|
|
1.1 ! root 1: /* Copyright (c) 1980 Regents of the University of California */ ! 2: static char *sccsid = "@(#)ex_temp.c 6.2 10/23/80"; ! 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: } ! 330: ! 331: TSYNC() ! 332: { ! 333: ! 334: if (dirtcnt > 12) { ! 335: #ifdef VMUNIX ! 336: if (stilinc) ! 337: tflush(); ! 338: #endif ! 339: dirtcnt = 0; ! 340: synctmp(); ! 341: } ! 342: } ! 343: ! 344: /* ! 345: * Named buffer routines. ! 346: * These are implemented differently than the main buffer. ! 347: * Each named buffer has a chain of blocks in the register file. ! 348: * Each block contains roughly 508 chars of text, ! 349: * and a previous and next block number. We also have information ! 350: * about which blocks came from deletes of multiple partial lines, ! 351: * e.g. deleting a sentence or a LISP object. ! 352: * ! 353: * We maintain a free map for the temp file. To free the blocks ! 354: * in a register we must read the blocks to find how they are chained ! 355: * together. ! 356: * ! 357: * BUG: The default savind of deleted lines in numbered ! 358: * buffers may be rather inefficient; it hasn't been profiled. ! 359: */ ! 360: struct strreg { ! 361: short rg_flags; ! 362: short rg_nleft; ! 363: short rg_first; ! 364: short rg_last; ! 365: } strregs[('z'-'a'+1) + ('9'-'0'+1)], *strp; ! 366: ! 367: struct rbuf { ! 368: short rb_prev; ! 369: short rb_next; ! 370: char rb_text[BUFSIZ - 2 * sizeof (short)]; ! 371: } *rbuf; ! 372: #ifdef VMUNIX ! 373: short rused[256]; ! 374: #else ! 375: short rused[32]; ! 376: #endif ! 377: short rnleft; ! 378: short rblock; ! 379: short rnext; ! 380: char *rbufcp; ! 381: ! 382: regio(b, iofcn) ! 383: short b; ! 384: int (*iofcn)(); ! 385: { ! 386: ! 387: if (rfile == -1) { ! 388: CP(rfname, tfname); ! 389: *(strend(rfname) - 7) = 'R'; ! 390: rfile = creat(rfname, 0600); ! 391: if (rfile < 0) ! 392: oops: ! 393: filioerr(rfname); ! 394: close(rfile); ! 395: rfile = open(rfname, 2); ! 396: if (rfile < 0) ! 397: goto oops; ! 398: } ! 399: lseek(rfile, (long) b * BUFSIZ, 0); ! 400: if ((*iofcn)(rfile, rbuf, BUFSIZ) != BUFSIZ) ! 401: goto oops; ! 402: rblock = b; ! 403: } ! 404: ! 405: REGblk() ! 406: { ! 407: register int i, j, m; ! 408: ! 409: for (i = 0; i < sizeof rused / sizeof rused[0]; i++) { ! 410: m = (rused[i] ^ 0177777) & 0177777; ! 411: if (i == 0) ! 412: m &= ~1; ! 413: if (m != 0) { ! 414: j = 0; ! 415: while ((m & 1) == 0) ! 416: j++, m >>= 1; ! 417: rused[i] |= (1 << j); ! 418: #ifdef RDEBUG ! 419: printf("allocating block %d\n", i * 16 + j); ! 420: #endif ! 421: return (i * 16 + j); ! 422: } ! 423: } ! 424: error("Out of register space (ugh)"); ! 425: /*NOTREACHED*/ ! 426: } ! 427: ! 428: struct strreg * ! 429: mapreg(c) ! 430: register int c; ! 431: { ! 432: ! 433: if (isupper(c)) ! 434: c = tolower(c); ! 435: return (isdigit(c) ? &strregs[('z'-'a'+1)+(c-'0')] : &strregs[c-'a']); ! 436: } ! 437: ! 438: int shread(); ! 439: ! 440: KILLreg(c) ! 441: register int c; ! 442: { ! 443: struct rbuf arbuf; ! 444: register struct strreg *sp; ! 445: ! 446: rbuf = &arbuf; ! 447: sp = mapreg(c); ! 448: rblock = sp->rg_first; ! 449: sp->rg_first = sp->rg_last = 0; ! 450: sp->rg_flags = sp->rg_nleft = 0; ! 451: while (rblock != 0) { ! 452: #ifdef RDEBUG ! 453: printf("freeing block %d\n", rblock); ! 454: #endif ! 455: rused[rblock / 16] &= ~(1 << (rblock % 16)); ! 456: regio(rblock, shread); ! 457: rblock = rbuf->rb_next; ! 458: } ! 459: } ! 460: ! 461: /*VARARGS*/ ! 462: shread() ! 463: { ! 464: struct front { short a; short b; }; ! 465: ! 466: if (read(rfile, (char *) rbuf, sizeof (struct front)) == sizeof (struct front)) ! 467: return (sizeof (struct rbuf)); ! 468: return (0); ! 469: } ! 470: ! 471: int getREG(); ! 472: ! 473: putreg(c) ! 474: char c; ! 475: { ! 476: struct rbuf arbuf; ! 477: register line *odot = dot; ! 478: register line *odol = dol; ! 479: register int cnt; ! 480: ! 481: deletenone(); ! 482: appendnone(); ! 483: rbuf = &arbuf; ! 484: rnleft = 0; ! 485: rblock = 0; ! 486: rnext = mapreg(c)->rg_first; ! 487: if (rnext == 0) { ! 488: if (inopen) { ! 489: splitw++; ! 490: vclean(); ! 491: vgoto(WECHO, 0); ! 492: } ! 493: vreg = -1; ! 494: error("Nothing in register %c", c); ! 495: } ! 496: if (inopen && partreg(c)) { ! 497: if (!FIXUNDO) { ! 498: splitw++; vclean(); vgoto(WECHO, 0); vreg = -1; ! 499: error("Can't put partial line inside macro"); ! 500: } ! 501: squish(); ! 502: addr1 = addr2 = dol; ! 503: } ! 504: cnt = append(getREG, addr2); ! 505: if (inopen && partreg(c)) { ! 506: unddol = dol; ! 507: dol = odol; ! 508: dot = odot; ! 509: pragged(0); ! 510: } ! 511: killcnt(cnt); ! 512: notecnt = cnt; ! 513: } ! 514: ! 515: partreg(c) ! 516: char c; ! 517: { ! 518: ! 519: return (mapreg(c)->rg_flags); ! 520: } ! 521: ! 522: notpart(c) ! 523: register int c; ! 524: { ! 525: ! 526: if (c) ! 527: mapreg(c)->rg_flags = 0; ! 528: } ! 529: ! 530: getREG() ! 531: { ! 532: register char *lp = linebuf; ! 533: register int c; ! 534: ! 535: for (;;) { ! 536: if (rnleft == 0) { ! 537: if (rnext == 0) ! 538: return (EOF); ! 539: regio(rnext, read); ! 540: rnext = rbuf->rb_next; ! 541: rbufcp = rbuf->rb_text; ! 542: rnleft = sizeof rbuf->rb_text; ! 543: } ! 544: c = *rbufcp; ! 545: if (c == 0) ! 546: return (EOF); ! 547: rbufcp++, --rnleft; ! 548: if (c == '\n') { ! 549: *lp++ = 0; ! 550: return (0); ! 551: } ! 552: *lp++ = c; ! 553: } ! 554: } ! 555: ! 556: YANKreg(c) ! 557: register int c; ! 558: { ! 559: struct rbuf arbuf; ! 560: register line *addr; ! 561: register struct strreg *sp; ! 562: char savelb[LBSIZE]; ! 563: ! 564: if (isdigit(c)) ! 565: kshift(); ! 566: if (islower(c)) ! 567: KILLreg(c); ! 568: strp = sp = mapreg(c); ! 569: sp->rg_flags = inopen && cursor && wcursor; ! 570: rbuf = &arbuf; ! 571: if (sp->rg_last) { ! 572: regio(sp->rg_last, read); ! 573: rnleft = sp->rg_nleft; ! 574: rbufcp = &rbuf->rb_text[sizeof rbuf->rb_text - rnleft]; ! 575: } else { ! 576: rblock = 0; ! 577: rnleft = 0; ! 578: } ! 579: CP(savelb,linebuf); ! 580: for (addr = addr1; addr <= addr2; addr++) { ! 581: getline(*addr); ! 582: if (sp->rg_flags) { ! 583: if (addr == addr2) ! 584: *wcursor = 0; ! 585: if (addr == addr1) ! 586: strcpy(linebuf, cursor); ! 587: } ! 588: YANKline(); ! 589: } ! 590: rbflush(); ! 591: killed(); ! 592: CP(linebuf,savelb); ! 593: } ! 594: ! 595: kshift() ! 596: { ! 597: register int i; ! 598: ! 599: KILLreg('9'); ! 600: for (i = '8'; i >= '0'; i--) ! 601: copy(mapreg(i+1), mapreg(i), sizeof (struct strreg)); ! 602: } ! 603: ! 604: YANKline() ! 605: { ! 606: register char *lp = linebuf; ! 607: register struct rbuf *rp = rbuf; ! 608: register int c; ! 609: ! 610: do { ! 611: c = *lp++; ! 612: if (c == 0) ! 613: c = '\n'; ! 614: if (rnleft == 0) { ! 615: rp->rb_next = REGblk(); ! 616: rbflush(); ! 617: rblock = rp->rb_next; ! 618: rp->rb_next = 0; ! 619: rp->rb_prev = rblock; ! 620: rnleft = sizeof rp->rb_text; ! 621: rbufcp = rp->rb_text; ! 622: } ! 623: *rbufcp++ = c; ! 624: --rnleft; ! 625: } while (c != '\n'); ! 626: if (rnleft) ! 627: *rbufcp = 0; ! 628: } ! 629: ! 630: rbflush() ! 631: { ! 632: register struct strreg *sp = strp; ! 633: ! 634: if (rblock == 0) ! 635: return; ! 636: regio(rblock, write); ! 637: if (sp->rg_first == 0) ! 638: sp->rg_first = rblock; ! 639: sp->rg_last = rblock; ! 640: sp->rg_nleft = rnleft; ! 641: } ! 642: ! 643: /* Register c to char buffer buf of size buflen */ ! 644: regbuf(c, buf, buflen) ! 645: char c; ! 646: char *buf; ! 647: int buflen; ! 648: { ! 649: struct rbuf arbuf; ! 650: register char *p, *lp; ! 651: ! 652: rbuf = &arbuf; ! 653: rnleft = 0; ! 654: rblock = 0; ! 655: rnext = mapreg(c)->rg_first; ! 656: if (rnext==0) { ! 657: *buf = 0; ! 658: error("Nothing in register %c",c); ! 659: } ! 660: p = buf; ! 661: while (getREG()==0) { ! 662: for (lp=linebuf; *lp;) { ! 663: if (p >= &buf[buflen]) ! 664: error("Register too long@to fit in memory"); ! 665: *p++ = *lp++; ! 666: } ! 667: *p++ = '\n'; ! 668: } ! 669: if (partreg(c)) p--; ! 670: *p = '\0'; ! 671: getDOT(); ! 672: } ! 673: ! 674: /* ! 675: * Encryption routines. These are essentially unmodified from ed. ! 676: */ ! 677: ! 678: #ifdef CRYPT ! 679: /* ! 680: * crblock: encrypt/decrypt a block of text. ! 681: * buf is the buffer through which the text is both input and ! 682: * output. nchar is the size of the buffer. permp is a work ! 683: * buffer, and startn is the beginning of a sequence. ! 684: */ ! 685: crblock(permp, buf, nchar, startn) ! 686: char *permp; ! 687: char *buf; ! 688: int nchar; ! 689: long startn; ! 690: { ! 691: register char *p1; ! 692: int n1; ! 693: int n2; ! 694: register char *t1, *t2, *t3; ! 695: ! 696: t1 = permp; ! 697: t2 = &permp[256]; ! 698: t3 = &permp[512]; ! 699: ! 700: n1 = startn&0377; ! 701: n2 = (startn>>8)&0377; ! 702: p1 = buf; ! 703: while(nchar--) { ! 704: *p1 = t2[(t3[(t1[(*p1+n1)&0377]+n2)&0377]-n2)&0377]-n1; ! 705: n1++; ! 706: if(n1==256){ ! 707: n1 = 0; ! 708: n2++; ! 709: if(n2==256) n2 = 0; ! 710: } ! 711: p1++; ! 712: } ! 713: } ! 714: ! 715: /* ! 716: * makekey: initialize buffers based on user key a. ! 717: */ ! 718: makekey(a, b) ! 719: char *a, *b; ! 720: { ! 721: register int i; ! 722: long t; ! 723: char temp[KSIZE + 1]; ! 724: ! 725: for(i = 0; i < KSIZE; i++) ! 726: temp[i] = *a++; ! 727: time(&t); ! 728: t += getpid(); ! 729: for(i = 0; i < 4; i++) ! 730: temp[i] ^= (t>>(8*i))&0377; ! 731: crinit(temp, b); ! 732: } ! 733: ! 734: /* ! 735: * crinit: besides initializing the encryption machine, this routine ! 736: * returns 0 if the key is null, and 1 if it is non-null. ! 737: */ ! 738: crinit(keyp, permp) ! 739: char *keyp, *permp; ! 740: { ! 741: register char *t1, *t2, *t3; ! 742: register i; ! 743: int ic, k, temp; ! 744: unsigned random; ! 745: char buf[13]; ! 746: long seed; ! 747: ! 748: t1 = permp; ! 749: t2 = &permp[256]; ! 750: t3 = &permp[512]; ! 751: if(*keyp == 0) ! 752: return(0); ! 753: strncpy(buf, keyp, 8); ! 754: while (*keyp) ! 755: *keyp++ = '\0'; ! 756: ! 757: buf[8] = buf[0]; ! 758: buf[9] = buf[1]; ! 759: domakekey(buf); ! 760: ! 761: seed = 123; ! 762: for (i=0; i<13; i++) ! 763: seed = seed*buf[i] + i; ! 764: for(i=0;i<256;i++){ ! 765: t1[i] = i; ! 766: t3[i] = 0; ! 767: } ! 768: for(i=0; i<256; i++) { ! 769: seed = 5*seed + buf[i%13]; ! 770: random = seed % 65521; ! 771: k = 256-1 - i; ! 772: ic = (random&0377) % (k+1); ! 773: random >>= 8; ! 774: temp = t1[k]; ! 775: t1[k] = t1[ic]; ! 776: t1[ic] = temp; ! 777: if(t3[k]!=0) continue; ! 778: ic = (random&0377) % k; ! 779: while(t3[ic]!=0) ic = (ic+1) % k; ! 780: t3[k] = ic; ! 781: t3[ic] = k; ! 782: } ! 783: for(i=0; i<256; i++) ! 784: t2[t1[i]&0377] = i; ! 785: return(1); ! 786: } ! 787: ! 788: /* ! 789: * domakekey: the following is the major nonportable part of the encryption ! 790: * mechanism. A 10 character key is supplied in buffer. ! 791: * This string is fed to makekey (an external program) which ! 792: * responds with a 13 character result. This result is placed ! 793: * in buffer. ! 794: */ ! 795: domakekey(buffer) ! 796: char *buffer; ! 797: { ! 798: int pf[2]; ! 799: ! 800: if (pipe(pf)<0) ! 801: pf[0] = pf[1] = -1; ! 802: if (fork()==0) { ! 803: close(0); ! 804: close(1); ! 805: dup(pf[0]); ! 806: dup(pf[1]); ! 807: execl("/usr/lib/makekey", "-", 0); ! 808: execl("/lib/makekey", "-", 0); ! 809: exit(1); ! 810: } ! 811: write(pf[1], buffer, 10); ! 812: if (wait((int *)NULL)==-1 || read(pf[0], buffer, 13)!=13) ! 813: error("crypt: cannot generate key"); ! 814: close(pf[0]); ! 815: close(pf[1]); ! 816: /* end of nonportable part */ ! 817: } ! 818: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.