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