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