|
|
1.1 ! root 1: /* Copyright (c) 1981 Regents of the University of California */ ! 2: static char *sccsid = "@(#)ex_temp.c 7.3 9/3/81"; ! 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 > MAXDIRT) { /* mjm: 12 --> MAXDIRT */ ! 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, KILLrbuf, putrbuf, YANKrbuf, regrbuf; ! 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: register struct strreg *sp; ! 444: ! 445: rbuf = &KILLrbuf; ! 446: sp = mapreg(c); ! 447: rblock = sp->rg_first; ! 448: sp->rg_first = sp->rg_last = 0; ! 449: sp->rg_flags = sp->rg_nleft = 0; ! 450: while (rblock != 0) { ! 451: #ifdef RDEBUG ! 452: printf("freeing block %d\n", rblock); ! 453: #endif ! 454: rused[rblock / 16] &= ~(1 << (rblock % 16)); ! 455: regio(rblock, shread); ! 456: rblock = rbuf->rb_next; ! 457: } ! 458: } ! 459: ! 460: /*VARARGS*/ ! 461: shread() ! 462: { ! 463: struct front { short a; short b; }; ! 464: ! 465: if (read(rfile, (char *) rbuf, sizeof (struct front)) == sizeof (struct front)) ! 466: return (sizeof (struct rbuf)); ! 467: return (0); ! 468: } ! 469: ! 470: int getREG(); ! 471: ! 472: putreg(c) ! 473: char c; ! 474: { ! 475: register line *odot = dot; ! 476: register line *odol = dol; ! 477: register int cnt; ! 478: ! 479: deletenone(); ! 480: appendnone(); ! 481: rbuf = &putrbuf; ! 482: rnleft = 0; ! 483: rblock = 0; ! 484: rnext = mapreg(c)->rg_first; ! 485: if (rnext == 0) { ! 486: if (inopen) { ! 487: splitw++; ! 488: vclean(); ! 489: vgoto(WECHO, 0); ! 490: } ! 491: vreg = -1; ! 492: error("Nothing in register %c", c); ! 493: } ! 494: if (inopen && partreg(c)) { ! 495: if (!FIXUNDO) { ! 496: splitw++; vclean(); vgoto(WECHO, 0); vreg = -1; ! 497: error("Can't put partial line inside macro"); ! 498: } ! 499: squish(); ! 500: addr1 = addr2 = dol; ! 501: } ! 502: cnt = append(getREG, addr2); ! 503: if (inopen && partreg(c)) { ! 504: unddol = dol; ! 505: dol = odol; ! 506: dot = odot; ! 507: pragged(0); ! 508: } ! 509: killcnt(cnt); ! 510: notecnt = cnt; ! 511: } ! 512: ! 513: partreg(c) ! 514: char c; ! 515: { ! 516: ! 517: return (mapreg(c)->rg_flags); ! 518: } ! 519: ! 520: notpart(c) ! 521: register int c; ! 522: { ! 523: ! 524: if (c) ! 525: mapreg(c)->rg_flags = 0; ! 526: } ! 527: ! 528: getREG() ! 529: { ! 530: register char *lp = linebuf; ! 531: register int c; ! 532: ! 533: for (;;) { ! 534: if (rnleft == 0) { ! 535: if (rnext == 0) ! 536: return (EOF); ! 537: regio(rnext, read); ! 538: rnext = rbuf->rb_next; ! 539: rbufcp = rbuf->rb_text; ! 540: rnleft = sizeof rbuf->rb_text; ! 541: } ! 542: c = *rbufcp; ! 543: if (c == 0) ! 544: return (EOF); ! 545: rbufcp++, --rnleft; ! 546: if (c == '\n') { ! 547: *lp++ = 0; ! 548: return (0); ! 549: } ! 550: *lp++ = c; ! 551: } ! 552: } ! 553: ! 554: YANKreg(c) ! 555: register int c; ! 556: { ! 557: register line *addr; ! 558: register struct strreg *sp; ! 559: char savelb[LBSIZE]; ! 560: ! 561: if (isdigit(c)) ! 562: kshift(); ! 563: if (islower(c)) ! 564: KILLreg(c); ! 565: strp = sp = mapreg(c); ! 566: sp->rg_flags = inopen && cursor && wcursor; ! 567: rbuf = &YANKrbuf; ! 568: if (sp->rg_last) { ! 569: regio(sp->rg_last, read); ! 570: rnleft = sp->rg_nleft; ! 571: rbufcp = &rbuf->rb_text[sizeof rbuf->rb_text - rnleft]; ! 572: } else { ! 573: rblock = 0; ! 574: rnleft = 0; ! 575: } ! 576: CP(savelb,linebuf); ! 577: for (addr = addr1; addr <= addr2; addr++) { ! 578: getline(*addr); ! 579: if (sp->rg_flags) { ! 580: if (addr == addr2) ! 581: *wcursor = 0; ! 582: if (addr == addr1) ! 583: strcpy(linebuf, cursor); ! 584: } ! 585: YANKline(); ! 586: } ! 587: rbflush(); ! 588: killed(); ! 589: CP(linebuf,savelb); ! 590: } ! 591: ! 592: kshift() ! 593: { ! 594: register int i; ! 595: ! 596: KILLreg('9'); ! 597: for (i = '8'; i >= '0'; i--) ! 598: copy(mapreg(i+1), mapreg(i), sizeof (struct strreg)); ! 599: } ! 600: ! 601: YANKline() ! 602: { ! 603: register char *lp = linebuf; ! 604: register struct rbuf *rp = rbuf; ! 605: register int c; ! 606: ! 607: do { ! 608: c = *lp++; ! 609: if (c == 0) ! 610: c = '\n'; ! 611: if (rnleft == 0) { ! 612: rp->rb_next = REGblk(); ! 613: rbflush(); ! 614: rblock = rp->rb_next; ! 615: rp->rb_next = 0; ! 616: rp->rb_prev = rblock; ! 617: rnleft = sizeof rp->rb_text; ! 618: rbufcp = rp->rb_text; ! 619: } ! 620: *rbufcp++ = c; ! 621: --rnleft; ! 622: } while (c != '\n'); ! 623: if (rnleft) ! 624: *rbufcp = 0; ! 625: } ! 626: ! 627: rbflush() ! 628: { ! 629: register struct strreg *sp = strp; ! 630: ! 631: if (rblock == 0) ! 632: return; ! 633: regio(rblock, write); ! 634: if (sp->rg_first == 0) ! 635: sp->rg_first = rblock; ! 636: sp->rg_last = rblock; ! 637: sp->rg_nleft = rnleft; ! 638: } ! 639: ! 640: /* Register c to char buffer buf of size buflen */ ! 641: regbuf(c, buf, buflen) ! 642: char c; ! 643: char *buf; ! 644: int buflen; ! 645: { ! 646: register char *p, *lp; ! 647: ! 648: rbuf = ®rbuf; ! 649: rnleft = 0; ! 650: rblock = 0; ! 651: rnext = mapreg(c)->rg_first; ! 652: if (rnext==0) { ! 653: *buf = 0; ! 654: error("Nothing in register %c",c); ! 655: } ! 656: p = buf; ! 657: while (getREG()==0) { ! 658: for (lp=linebuf; *lp;) { ! 659: if (p >= &buf[buflen]) ! 660: error("Register too long@to fit in memory"); ! 661: *p++ = *lp++; ! 662: } ! 663: *p++ = '\n'; ! 664: } ! 665: if (partreg(c)) p--; ! 666: *p = '\0'; ! 667: getDOT(); ! 668: } ! 669: ! 670: /* ! 671: * Encryption routines. These are essentially unmodified from ed. ! 672: */ ! 673: ! 674: #ifdef CRYPT ! 675: /* ! 676: * crblock: encrypt/decrypt a block of text. ! 677: * buf is the buffer through which the text is both input and ! 678: * output. nchar is the size of the buffer. permp is a work ! 679: * buffer, and startn is the beginning of a sequence. ! 680: */ ! 681: crblock(permp, buf, nchar, startn) ! 682: char *permp; ! 683: char *buf; ! 684: int nchar; ! 685: long startn; ! 686: { ! 687: register char *p1; ! 688: int n1; ! 689: int n2; ! 690: int n3; ! 691: register char *t1, *t2, *t3; ! 692: char *t4; ! 693: ! 694: t1 = permp; ! 695: t2 = &permp[256]; ! 696: t3 = &permp[512]; ! 697: t4 = &permp[768]; ! 698: ! 699: n1 = startn&0377; ! 700: n2 = (startn>>8)&0377; ! 701: p1 = buf; ! 702: while(nchar--) { ! 703: n3 = t4[n1]; ! 704: *p1 = t2[(t3[(t1[(*p1+n3)&0377]+n2)&0377]-n2)&0377]-n3; ! 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: char *t4; ! 743: register i; ! 744: int ic, k, temp; ! 745: unsigned random; ! 746: char buf[13]; ! 747: long seed; ! 748: ! 749: t1 = permp; ! 750: t2 = &permp[256]; ! 751: t3 = &permp[512]; ! 752: t4 = &permp[768]; ! 753: if(*keyp == 0) ! 754: return(0); ! 755: strncpy(buf, keyp, 8); ! 756: while (*keyp) ! 757: *keyp++ = '\0'; ! 758: ! 759: buf[8] = buf[0]; ! 760: buf[9] = buf[1]; ! 761: domakekey(buf); ! 762: ! 763: seed = 123; ! 764: for (i=0; i<13; i++) ! 765: seed = seed*buf[i] + i; ! 766: for(i=0;i<256;i++){ ! 767: t1[i] = i; ! 768: t3[i] = 0; ! 769: } ! 770: for(i=0; i<256; i++) { ! 771: seed = 5*seed + buf[i%13]; ! 772: random = seed % 65521; ! 773: k = 256-1 - i; ! 774: ic = (random&0377) % (k+1); ! 775: random >>= 8; ! 776: temp = t1[k]; ! 777: t1[k] = t1[ic]; ! 778: t1[ic] = temp; ! 779: if(t3[k]!=0) continue; ! 780: ic = (random&0377) % k; ! 781: while(t3[ic]!=0) ic = (ic+1) % k; ! 782: t3[k] = ic; ! 783: t3[ic] = k; ! 784: } ! 785: for(i=0; i<256; i++){ ! 786: t2[t1[i]&0377] = i; ! 787: t4[i] = (t1[i] + t3[i]) & 0377; ! 788: } ! 789: return(1); ! 790: } ! 791: ! 792: /* ! 793: * domakekey: the following is the major nonportable part of the encryption ! 794: * mechanism. A 10 character key is supplied in buffer. ! 795: * This string is fed to makekey (an external program) which ! 796: * responds with a 13 character result. This result is placed ! 797: * in buffer. ! 798: */ ! 799: domakekey(buffer) ! 800: char *buffer; ! 801: { ! 802: int pf[2]; ! 803: ! 804: if (pipe(pf)<0) ! 805: pf[0] = pf[1] = -1; ! 806: if (fork()==0) { ! 807: close(0); ! 808: close(1); ! 809: dup(pf[0]); ! 810: dup(pf[1]); ! 811: execl("/usr/lib/makekey", "-", 0); ! 812: execl("/lib/makekey", "-", 0); ! 813: exit(1); ! 814: } ! 815: write(pf[1], buffer, 10); ! 816: if (wait((int *)NULL)==-1 || read(pf[0], buffer, 13)!=13) ! 817: error("crypt: cannot generate key"); ! 818: close(pf[0]); ! 819: close(pf[1]); ! 820: /* end of nonportable part */ ! 821: } ! 822: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.