|
|
1.1 ! root 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 = ®rbuf; ! 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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.