1: /*
   2:  * Copyright (c) 1980 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  */
   6: 
   7: #ifndef lint
   8: static char *sccsid = "@(#)ex_temp.c	7.5 (Berkeley) 6/7/85";
   9: #endif not lint
  10: 
  11: #include "ex.h"
  12: #include "ex_temp.h"
  13: #include "ex_vis.h"
  14: #include "ex_tty.h"
  15: 
  16: /*
  17:  * Editor temporary file routines.
  18:  * Very similar to those of ed, except uses 2 input buffers.
  19:  */
  20: #define READ    0
  21: #define WRITE   1
  22: 
  23: char    tfname[40];
  24: char    rfname[40];
  25: int havetmp;
  26: short   tfile = -1;
  27: short   rfile = -1;
  28: 
  29: fileinit()
  30: {
  31:     register char *p;
  32:     register int i, j;
  33:     struct stat stbuf;
  34: 
  35:     if (tline == INCRMT * (HBLKS+2))
  36:         return;
  37:     cleanup(0);
  38:     close(tfile);
  39:     tline = INCRMT * (HBLKS+2);
  40:     blocks[0] = HBLKS;
  41:     blocks[1] = HBLKS+1;
  42:     blocks[2] = -1;
  43:     dirtcnt = 0;
  44:     iblock = -1;
  45:     iblock2 = -1;
  46:     oblock = -1;
  47:     CP(tfname, svalue(DIRECTORY));
  48:     if (stat(tfname, &stbuf)) {
  49: dumbness:
  50:         if (setexit() == 0)
  51:             filioerr(tfname);
  52:         else
  53:             putNFL();
  54:         cleanup(1);
  55:         exit(1);
  56:     }
  57:     if ((stbuf.st_mode & S_IFMT) != S_IFDIR) {
  58:         errno = ENOTDIR;
  59:         goto dumbness;
  60:     }
  61:     ichanged = 0;
  62:     ichang2 = 0;
  63:     ignore(strcat(tfname, "/ExXXXXX"));
  64:     for (p = strend(tfname), i = 5, j = getpid(); i > 0; i--, j /= 10)
  65:         *--p = j % 10 | '0';
  66:     tfile = creat(tfname, 0600);
  67:     if (tfile < 0)
  68:         goto dumbness;
  69: #ifdef VMUNIX
  70:     {
  71:         extern stilinc;     /* see below */
  72:         stilinc = 0;
  73:     }
  74: #endif
  75:     havetmp = 1;
  76:     close(tfile);
  77:     tfile = open(tfname, 2);
  78:     if (tfile < 0)
  79:         goto dumbness;
  80: /* 	brk((char *)fendcore); */
  81: }
  82: 
  83: cleanup(all)
  84:     bool all;
  85: {
  86:     if (all) {
  87:         putpad(TE);
  88:         flush();
  89:     }
  90:     if (havetmp)
  91:         unlink(tfname);
  92:     havetmp = 0;
  93:     if (all && rfile >= 0) {
  94:         unlink(rfname);
  95:         close(rfile);
  96:         rfile = -1;
  97:     }
  98: }
  99: 
 100: getline(tl)
 101:     line tl;
 102: {
 103:     register char *bp, *lp;
 104:     register int nl;
 105: 
 106:     lp = linebuf;
 107:     bp = getblock(tl, READ);
 108:     nl = nleft;
 109:     tl &= ~OFFMSK;
 110:     while (*lp++ = *bp++)
 111:         if (--nl == 0) {
 112:             bp = getblock(tl += INCRMT, READ);
 113:             nl = nleft;
 114:         }
 115: }
 116: 
 117: putline()
 118: {
 119:     register char *bp, *lp;
 120:     register int nl;
 121:     line tl;
 122: 
 123:     dirtcnt++;
 124:     lp = linebuf;
 125:     change();
 126:     tl = tline;
 127:     bp = getblock(tl, WRITE);
 128:     nl = nleft;
 129:     tl &= ~OFFMSK;
 130:     while (*bp = *lp++) {
 131:         if (*bp++ == '\n') {
 132:             *--bp = 0;
 133:             linebp = lp;
 134:             break;
 135:         }
 136:         if (--nl == 0) {
 137:             bp = getblock(tl += INCRMT, WRITE);
 138:             nl = nleft;
 139:         }
 140:     }
 141:     tl = tline;
 142:     tline += (((lp - linebuf) + BNDRY - 1) >> SHFT) & 077776;
 143:     return (tl);
 144: }
 145: 
 146: int read();
 147: int write();
 148: 
 149: char *
 150: getblock(atl, iof)
 151:     line atl;
 152:     int iof;
 153: {
 154:     register int bno, off;
 155:         register char *p1, *p2;
 156:         register int n;
 157: 
 158:     bno = (atl >> OFFBTS) & BLKMSK;
 159:     off = (atl << SHFT) & LBTMSK;
 160:     if (bno >= NMBLKS)
 161:         error(" Tmp file too large");
 162:     nleft = BUFSIZ - off;
 163:     if (bno == iblock) {
 164:         ichanged |= iof;
 165:         hitin2 = 0;
 166:         return (ibuff + off);
 167:     }
 168:     if (bno == iblock2) {
 169:         ichang2 |= iof;
 170:         hitin2 = 1;
 171:         return (ibuff2 + off);
 172:     }
 173:     if (bno == oblock)
 174:         return (obuff + off);
 175:     if (iof == READ) {
 176:         if (hitin2 == 0) {
 177:             if (ichang2) {
 178: #ifdef CRYPT
 179:                 if(xtflag)
 180:                     crblock(tperm, ibuff2, CRSIZE, (long)0);
 181: #endif
 182:                 blkio(iblock2, ibuff2, write);
 183:             }
 184:             ichang2 = 0;
 185:             iblock2 = bno;
 186:             blkio(bno, ibuff2, read);
 187: #ifdef CRYPT
 188:             if(xtflag)
 189:                 crblock(tperm, ibuff2, CRSIZE, (long)0);
 190: #endif
 191:             hitin2 = 1;
 192:             return (ibuff2 + off);
 193:         }
 194:         hitin2 = 0;
 195:         if (ichanged) {
 196: #ifdef CRYPT
 197:             if(xtflag)
 198:                 crblock(tperm, ibuff, CRSIZE, (long)0);
 199: #endif
 200:             blkio(iblock, ibuff, write);
 201:         }
 202:         ichanged = 0;
 203:         iblock = bno;
 204:         blkio(bno, ibuff, read);
 205: #ifdef CRYPT
 206:         if(xtflag)
 207:             crblock(tperm, ibuff, CRSIZE, (long)0);
 208: #endif
 209:         return (ibuff + off);
 210:     }
 211:     if (oblock >= 0) {
 212: #ifdef CRYPT
 213:         if(xtflag) {
 214:             /*
 215: 			 * Encrypt block before writing, so some devious
 216: 			 * person can't look at temp file while editing.
 217: 			 */
 218:             p1 = obuff;
 219:             p2 = crbuf;
 220:             n = CRSIZE;
 221:             while(n--)
 222:                 *p2++ = *p1++;
 223:             crblock(tperm, crbuf, CRSIZE, (long)0);
 224:             blkio(oblock, crbuf, write);
 225:         } else
 226: #endif
 227:             blkio(oblock, obuff, write);
 228:     }
 229:     oblock = bno;
 230:     return (obuff + off);
 231: }
 232: 
 233: #ifdef  VMUNIX
 234: #define INCORB  64
 235: char    incorb[INCORB+1][BUFSIZ];
 236: #define pagrnd(a)   ((char *)(((int)a)&~(BUFSIZ-1)))
 237: int stilinc;    /* up to here not written yet */
 238: #endif
 239: 
 240: blkio(b, buf, iofcn)
 241:     short b;
 242:     char *buf;
 243:     int (*iofcn)();
 244: {
 245: 
 246: #ifdef VMUNIX
 247:     if (b < INCORB) {
 248:         if (iofcn == read) {
 249:             bcopy(pagrnd(incorb[b+1]), buf, BUFSIZ);
 250:             return;
 251:         }
 252:         bcopy(buf, pagrnd(incorb[b+1]), BUFSIZ);
 253:         if (laste) {
 254:             if (b >= stilinc)
 255:                 stilinc = b + 1;
 256:             return;
 257:         }
 258:     } else if (stilinc)
 259:         tflush();
 260: #endif
 261:     lseek(tfile, (long) (unsigned) b * BUFSIZ, 0);
 262:     if ((*iofcn)(tfile, buf, BUFSIZ) != BUFSIZ)
 263:         filioerr(tfname);
 264: }
 265: 
 266: #ifdef VMUNIX
 267: tlaste()
 268: {
 269: 
 270:     if (stilinc)
 271:         dirtcnt = 0;
 272: }
 273: 
 274: tflush()
 275: {
 276:     int i = stilinc;
 277: 
 278:     stilinc = 0;
 279:     lseek(tfile, (long) 0, 0);
 280:     if (write(tfile, pagrnd(incorb[1]), i * BUFSIZ) != (i * BUFSIZ))
 281:         filioerr(tfname);
 282: }
 283: #endif
 284: 
 285: /*
 286:  * Synchronize the state of the temporary file in case
 287:  * a crash occurs.
 288:  */
 289: synctmp()
 290: {
 291:     register int cnt;
 292:     register line *a;
 293:     register short *bp;
 294: 
 295: #ifdef VMUNIX
 296:     if (stilinc)
 297:         return;
 298: #endif
 299:     if (dol == zero)
 300:         return;
 301:     if (ichanged)
 302:         blkio(iblock, ibuff, write);
 303:     ichanged = 0;
 304:     if (ichang2)
 305:         blkio(iblock2, ibuff2, write);
 306:     ichang2 = 0;
 307:     if (oblock != -1)
 308:         blkio(oblock, obuff, write);
 309:     time(&H.Time);
 310:     uid = getuid();
 311:     *zero = (line) H.Time;
 312:     for (a = zero, bp = blocks; a <= dol; a += BUFSIZ / sizeof *a, bp++) {
 313:         if (*bp < 0) {
 314:             tline = (tline + OFFMSK) &~ OFFMSK;
 315:             *bp = ((tline >> OFFBTS) & BLKMSK);
 316:             if (*bp > NMBLKS)
 317:                 error(" Tmp file too large");
 318:             tline += INCRMT;
 319:             oblock = *bp + 1;
 320:             bp[1] = -1;
 321:         }
 322:         lseek(tfile, (long) (unsigned) *bp * BUFSIZ, 0);
 323:         cnt = ((dol - a) + 2) * sizeof (line);
 324:         if (cnt > BUFSIZ)
 325:             cnt = BUFSIZ;
 326:         if (write(tfile, (char *) a, cnt) != cnt) {
 327: oops:
 328:             *zero = 0;
 329:             filioerr(tfname);
 330:         }
 331:         *zero = 0;
 332:     }
 333:     flines = lineDOL();
 334:     lseek(tfile, 0l, 0);
 335:     if (write(tfile, (char *) &H, sizeof H) != sizeof H)
 336:         goto oops;
 337: #ifdef notdef
 338:     /*
 339: 	 * This will insure that exrecover gets as much
 340: 	 * back after a crash as is absolutely possible,
 341: 	 * but can result in pregnant pauses between commands
 342: 	 * when the TSYNC call is made, so...
 343: 	 */
 344:     (void) fsync(tfile);
 345: #endif
 346: }
 347: 
 348: TSYNC()
 349: {
 350: 
 351:     if (dirtcnt > MAXDIRT) {    /* mjm: 12 --> MAXDIRT */
 352: #ifdef VMUNIX
 353:         if (stilinc)
 354:             tflush();
 355: #endif
 356:         dirtcnt = 0;
 357:         synctmp();
 358:     }
 359: }
 360: 
 361: /*
 362:  * Named buffer routines.
 363:  * These are implemented differently than the main buffer.
 364:  * Each named buffer has a chain of blocks in the register file.
 365:  * Each block contains roughly 508 chars of text,
 366:  * and a previous and next block number.  We also have information
 367:  * about which blocks came from deletes of multiple partial lines,
 368:  * e.g. deleting a sentence or a LISP object.
 369:  *
 370:  * We maintain a free map for the temp file.  To free the blocks
 371:  * in a register we must read the blocks to find how they are chained
 372:  * together.
 373:  *
 374:  * BUG:		The default savind of deleted lines in numbered
 375:  *		buffers may be rather inefficient; it hasn't been profiled.
 376:  */
 377: struct  strreg {
 378:     short   rg_flags;
 379:     short   rg_nleft;
 380:     short   rg_first;
 381:     short   rg_last;
 382: } strregs[('z'-'a'+1) + ('9'-'0'+1)], *strp;
 383: 
 384: struct  rbuf {
 385:     short   rb_prev;
 386:     short   rb_next;
 387:     char    rb_text[BUFSIZ - 2 * sizeof (short)];
 388: } *rbuf, KILLrbuf, putrbuf, YANKrbuf, regrbuf;
 389: #ifdef VMUNIX
 390: short   rused[256];
 391: #else
 392: short   rused[32];
 393: #endif
 394: short   rnleft;
 395: short   rblock;
 396: short   rnext;
 397: char    *rbufcp;
 398: 
 399: regio(b, iofcn)
 400:     short b;
 401:     int (*iofcn)();
 402: {
 403: 
 404:     if (rfile == -1) {
 405:         CP(rfname, tfname);
 406:         *(strend(rfname) - 7) = 'R';
 407:         rfile = creat(rfname, 0600);
 408:         if (rfile < 0)
 409: oops:
 410:             filioerr(rfname);
 411:         close(rfile);
 412:         rfile = open(rfname, 2);
 413:         if (rfile < 0)
 414:             goto oops;
 415:     }
 416:     lseek(rfile, (long) b * BUFSIZ, 0);
 417:     if ((*iofcn)(rfile, rbuf, BUFSIZ) != BUFSIZ)
 418:         goto oops;
 419:     rblock = b;
 420: }
 421: 
 422: REGblk()
 423: {
 424:     register int i, j, m;
 425: 
 426:     for (i = 0; i < sizeof rused / sizeof rused[0]; i++) {
 427:         m = (rused[i] ^ 0177777) & 0177777;
 428:         if (i == 0)
 429:             m &= ~1;
 430:         if (m != 0) {
 431:             j = 0;
 432:             while ((m & 1) == 0)
 433:                 j++, m >>= 1;
 434:             rused[i] |= (1 << j);
 435: #ifdef RDEBUG
 436:             printf("allocating block %d\n", i * 16 + j);
 437: #endif
 438:             return (i * 16 + j);
 439:         }
 440:     }
 441:     error("Out of register space (ugh)");
 442:     /*NOTREACHED*/
 443: }
 444: 
 445: struct  strreg *
 446: mapreg(c)
 447:     register int c;
 448: {
 449: 
 450:     if (isupper(c))
 451:         c = tolower(c);
 452:     return (isdigit(c) ? &strregs[('z'-'a'+1)+(c-'0')] : &strregs[c-'a']);
 453: }
 454: 
 455: int shread();
 456: 
 457: KILLreg(c)
 458:     register int c;
 459: {
 460:     register struct strreg *sp;
 461: 
 462:     rbuf = &KILLrbuf;
 463:     sp = mapreg(c);
 464:     rblock = sp->rg_first;
 465:     sp->rg_first = sp->rg_last = 0;
 466:     sp->rg_flags = sp->rg_nleft = 0;
 467:     while (rblock != 0) {
 468: #ifdef RDEBUG
 469:         printf("freeing block %d\n", rblock);
 470: #endif
 471:         rused[rblock / 16] &= ~(1 << (rblock % 16));
 472:         regio(rblock, shread);
 473:         rblock = rbuf->rb_next;
 474:     }
 475: }
 476: 
 477: /*VARARGS*/
 478: shread()
 479: {
 480:     struct front { short a; short b; };
 481: 
 482:     if (read(rfile, (char *) rbuf, sizeof (struct front)) == sizeof (struct front))
 483:         return (sizeof (struct rbuf));
 484:     return (0);
 485: }
 486: 
 487: int getREG();
 488: 
 489: putreg(c)
 490:     char c;
 491: {
 492:     register line *odot = dot;
 493:     register line *odol = dol;
 494:     register int cnt;
 495: 
 496:     deletenone();
 497:     appendnone();
 498:     rbuf = &putrbuf;
 499:     rnleft = 0;
 500:     rblock = 0;
 501:     rnext = mapreg(c)->rg_first;
 502:     if (rnext == 0) {
 503:         if (inopen) {
 504:             splitw++;
 505:             vclean();
 506:             vgoto(WECHO, 0);
 507:         }
 508:         vreg = -1;
 509:         error("Nothing in register %c", c);
 510:     }
 511:     if (inopen && partreg(c)) {
 512:         if (!FIXUNDO) {
 513:             splitw++; vclean(); vgoto(WECHO, 0); vreg = -1;
 514:             error("Can't put partial line inside macro");
 515:         }
 516:         squish();
 517:         addr1 = addr2 = dol;
 518:     }
 519:     cnt = append(getREG, addr2);
 520:     if (inopen && partreg(c)) {
 521:         unddol = dol;
 522:         dol = odol;
 523:         dot = odot;
 524:         pragged(0);
 525:     }
 526:     killcnt(cnt);
 527:     notecnt = cnt;
 528: }
 529: 
 530: partreg(c)
 531:     char c;
 532: {
 533: 
 534:     return (mapreg(c)->rg_flags);
 535: }
 536: 
 537: notpart(c)
 538:     register int c;
 539: {
 540: 
 541:     if (c)
 542:         mapreg(c)->rg_flags = 0;
 543: }
 544: 
 545: getREG()
 546: {
 547:     register char *lp = linebuf;
 548:     register int c;
 549: 
 550:     for (;;) {
 551:         if (rnleft == 0) {
 552:             if (rnext == 0)
 553:                 return (EOF);
 554:             regio(rnext, read);
 555:             rnext = rbuf->rb_next;
 556:             rbufcp = rbuf->rb_text;
 557:             rnleft = sizeof rbuf->rb_text;
 558:         }
 559:         c = *rbufcp;
 560:         if (c == 0)
 561:             return (EOF);
 562:         rbufcp++, --rnleft;
 563:         if (c == '\n') {
 564:             *lp++ = 0;
 565:             return (0);
 566:         }
 567:         *lp++ = c;
 568:     }
 569: }
 570: 
 571: YANKreg(c)
 572:     register int c;
 573: {
 574:     register line *addr;
 575:     register struct strreg *sp;
 576:     char savelb[LBSIZE];
 577: 
 578:     if (isdigit(c))
 579:         kshift();
 580:     if (islower(c))
 581:         KILLreg(c);
 582:     strp = sp = mapreg(c);
 583:     sp->rg_flags = inopen && cursor && wcursor;
 584:     rbuf = &YANKrbuf;
 585:     if (sp->rg_last) {
 586:         regio(sp->rg_last, read);
 587:         rnleft = sp->rg_nleft;
 588:         rbufcp = &rbuf->rb_text[sizeof rbuf->rb_text - rnleft];
 589:     } else {
 590:         rblock = 0;
 591:         rnleft = 0;
 592:     }
 593:     CP(savelb,linebuf);
 594:     for (addr = addr1; addr <= addr2; addr++) {
 595:         getline(*addr);
 596:         if (sp->rg_flags) {
 597:             if (addr == addr2)
 598:                 *wcursor = 0;
 599:             if (addr == addr1)
 600:                 strcpy(linebuf, cursor);
 601:         }
 602:         YANKline();
 603:     }
 604:     rbflush();
 605:     killed();
 606:     CP(linebuf,savelb);
 607: }
 608: 
 609: kshift()
 610: {
 611:     register int i;
 612: 
 613:     KILLreg('9');
 614:     for (i = '8'; i >= '0'; i--)
 615:         copy(mapreg(i+1), mapreg(i), sizeof (struct strreg));
 616: }
 617: 
 618: YANKline()
 619: {
 620:     register char *lp = linebuf;
 621:     register struct rbuf *rp = rbuf;
 622:     register int c;
 623: 
 624:     do {
 625:         c = *lp++;
 626:         if (c == 0)
 627:             c = '\n';
 628:         if (rnleft == 0) {
 629:             rp->rb_next = REGblk();
 630:             rbflush();
 631:             rblock = rp->rb_next;
 632:             rp->rb_next = 0;
 633:             rp->rb_prev = rblock;
 634:             rnleft = sizeof rp->rb_text;
 635:             rbufcp = rp->rb_text;
 636:         }
 637:         *rbufcp++ = c;
 638:         --rnleft;
 639:     } while (c != '\n');
 640:     if (rnleft)
 641:         *rbufcp = 0;
 642: }
 643: 
 644: rbflush()
 645: {
 646:     register struct strreg *sp = strp;
 647: 
 648:     if (rblock == 0)
 649:         return;
 650:     regio(rblock, write);
 651:     if (sp->rg_first == 0)
 652:         sp->rg_first = rblock;
 653:     sp->rg_last = rblock;
 654:     sp->rg_nleft = rnleft;
 655: }
 656: 
 657: /* Register c to char buffer buf of size buflen */
 658: regbuf(c, buf, buflen)
 659: char c;
 660: char *buf;
 661: int buflen;
 662: {
 663:     register char *p, *lp;
 664: 
 665:     rbuf = &regrbuf;
 666:     rnleft = 0;
 667:     rblock = 0;
 668:     rnext = mapreg(c)->rg_first;
 669:     if (rnext==0) {
 670:         *buf = 0;
 671:         error("Nothing in register %c",c);
 672:     }
 673:     p = buf;
 674:     while (getREG()==0) {
 675:         for (lp=linebuf; *lp;) {
 676:             if (p >= &buf[buflen])
 677:                 error("Register too long@to fit in memory");
 678:             *p++ = *lp++;
 679:         }
 680:         *p++ = '\n';
 681:     }
 682:     if (partreg(c)) p--;
 683:     *p = '\0';
 684:     getDOT();
 685: }
 686: 
 687: /*
 688:  * Encryption routines.  These are essentially unmodified from ed.
 689:  */
 690: 
 691: #ifdef CRYPT
 692: /*
 693:  * crblock: encrypt/decrypt a block of text.
 694:  * buf is the buffer through which the text is both input and
 695:  * output. nchar is the size of the buffer. permp is a work
 696:  * buffer, and startn is the beginning of a sequence.
 697:  */
 698: crblock(permp, buf, nchar, startn)
 699: char *permp;
 700: char *buf;
 701: int nchar;
 702: long startn;
 703: {
 704:     register char *p1;
 705:     int n1;
 706:     int n2;
 707:     register char *t1, *t2, *t3;
 708: 
 709:     t1 = permp;
 710:     t2 = &permp[256];
 711:     t3 = &permp[512];
 712: 
 713:     n1 = startn&0377;
 714:     n2 = (startn>>8)&0377;
 715:     p1 = buf;
 716:     while(nchar--) {
 717:         *p1 = t2[(t3[(t1[(*p1+n1)&0377]+n2)&0377]-n2)&0377]-n1;
 718:         n1++;
 719:         if(n1==256){
 720:             n1 = 0;
 721:             n2++;
 722:             if(n2==256) n2 = 0;
 723:         }
 724:         p1++;
 725:     }
 726: }
 727: 
 728: /*
 729:  * makekey: initialize buffers based on user key a.
 730:  */
 731: makekey(a, b)
 732: char *a, *b;
 733: {
 734:        register int i;
 735:     long t;
 736:     char temp[KSIZE + 1];
 737: 
 738:     for(i = 0; i < KSIZE; i++)
 739:         temp[i] = *a++;
 740:     time(&t);
 741:     t += getpid();
 742:     for(i = 0; i < 4; i++)
 743:         temp[i] ^= (t>>(8*i))&0377;
 744:     crinit(temp, b);
 745: }
 746: 
 747: /*
 748:  * crinit: besides initializing the encryption machine, this routine
 749:  * returns 0 if the key is null, and 1 if it is non-null.
 750:  */
 751: crinit(keyp, permp)
 752: char    *keyp, *permp;
 753: {
 754:        register char *t1, *t2, *t3;
 755:     register i;
 756:     int ic, k, temp;
 757:     unsigned random;
 758:     char buf[13];
 759:     long seed;
 760: 
 761:     t1 = permp;
 762:     t2 = &permp[256];
 763:     t3 = &permp[512];
 764:     if(*keyp == 0)
 765:         return(0);
 766:     strncpy(buf, keyp, 8);
 767:     while (*keyp)
 768:         *keyp++ = '\0';
 769: 
 770:     buf[8] = buf[0];
 771:     buf[9] = buf[1];
 772:     domakekey(buf);
 773: 
 774:     seed = 123;
 775:     for (i=0; i<13; i++)
 776:         seed = seed*buf[i] + i;
 777:     for(i=0;i<256;i++){
 778:         t1[i] = i;
 779:         t3[i] = 0;
 780:     }
 781:     for(i=0; i<256; i++) {
 782:         seed = 5*seed + buf[i%13];
 783:         random = seed % 65521;
 784:         k = 256-1 - i;
 785:         ic = (random&0377) % (k+1);
 786:         random >>= 8;
 787:         temp = t1[k];
 788:         t1[k] = t1[ic];
 789:         t1[ic] = temp;
 790:         if(t3[k]!=0) continue;
 791:         ic = (random&0377) % k;
 792:         while(t3[ic]!=0) ic = (ic+1) % k;
 793:         t3[k] = ic;
 794:         t3[ic] = k;
 795:     }
 796:     for(i=0; i<256; i++)
 797:         t2[t1[i]&0377] = i;
 798:     return(1);
 799: }
 800: 
 801: /*
 802:  * domakekey: the following is the major nonportable part of the encryption
 803:  * mechanism. A 10 character key is supplied in buffer.
 804:  * This string is fed to makekey (an external program) which
 805:  * responds with a 13 character result. This result is placed
 806:  * in buffer.
 807:  */
 808: domakekey(buffer)
 809: char *buffer;
 810: {
 811:        int pf[2];
 812: 
 813:     if (pipe(pf)<0)
 814:         pf[0] = pf[1] = -1;
 815:     if (fork()==0) {
 816:         close(0);
 817:         close(1);
 818:         dup(pf[0]);
 819:         dup(pf[1]);
 820:         execl("/usr/lib/makekey", "-", 0);
 821:         execl("/lib/makekey", "-", 0);
 822:         exit(1);
 823:     }
 824:     write(pf[1], buffer, 10);
 825:     if (wait((int *)NULL)==-1 || read(pf[0], buffer, 13)!=13)
 826:         error("crypt: cannot generate key");
 827:     close(pf[0]);
 828:     close(pf[1]);
 829:     /* end of nonportable part */
 830: }
 831: #endif

Defined functions

KILLreg defined in line 457; used 2 times
REGblk defined in line 422; used 1 times
TSYNC defined in line 348; used 3 times
YANKline defined in line 618; used 1 times
YANKreg defined in line 571; used 6 times
blkio defined in line 240; used 9 times
cleanup defined in line 83; used 6 times
crblock defined in line 698; used 8 times
crinit defined in line 751; used 2 times
domakekey defined in line 808; used 1 times
fileinit defined in line 29; used 1 times
getREG defined in line 545; used 3 times
getblock defined in line 149; used 5 times
kshift defined in line 609; used 1 times
makekey defined in line 731; used 1 times
mapreg defined in line 445; used 8 times
notpart defined in line 537; used 2 times
partreg defined in line 530; used 4 times
putline defined in line 117; used 1 times
putreg defined in line 489; used 2 times
rbflush defined in line 644; used 2 times
regbuf defined in line 658; used 2 times
regio defined in line 399; used 4 times
shread defined in line 478; used 2 times
synctmp defined in line 289; used 2 times
tflush defined in line 274; used 3 times
tlaste defined in line 267; used 2 times

Defined variables

KILLrbuf defined in line 388; used 1 times
YANKrbuf defined in line 388; used 1 times
havetmp defined in line 25; used 3 times
incorb defined in line 235; used 3 times
putrbuf defined in line 388; used 1 times
rblock defined in line 395; used 17 times
rbuf defined in line 388; used 13 times
rbufcp defined in line 397; used 7 times
regrbuf defined in line 388; used 1 times
rfile defined in line 27; used 12 times
rfname defined in line 24; used 6 times
rnext defined in line 396; used 7 times
rnleft defined in line 394; used 13 times
rused defined in line 392; used 5 times
sccsid defined in line 8; never used
stilinc defined in line 237; used 10 times
strp defined in line 382; used 2 times
strregs defined in line 382; used 2 times
  • in line 452(2)
tfile defined in line 26; used 51 times
tfname defined in line 23; used 12 times

Defined struct's

front defined in line 480; used 4 times
  • in line 482(4)
rbuf defined in line 384; used 4 times
strreg defined in line 377; used 10 times

Defined macros

INCORB defined in line 234; used 2 times
READ defined in line 20; used 3 times
WRITE defined in line 21; used 2 times
pagrnd defined in line 236; used 3 times
Last modified: 1985-06-08
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2812
Valid CSS Valid XHTML 1.0 Strict