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