|
|
1.1 ! root 1: /* ! 2: * Editor ! 3: */ ! 4: ! 5: #include <signal.h> ! 6: #include <sgtty.h> ! 7: #include <setjmp.h> ! 8: #define NULL 0 ! 9: #define FNSIZE 128 ! 10: #define LBSIZE 512 ! 11: #define ESIZE 256 ! 12: #define GBSIZE 256 ! 13: #define NBRA 5 ! 14: #define EOF -1 ! 15: #define KSIZE 9 ! 16: ! 17: #define CBRA 1 ! 18: #define CCHR 2 ! 19: #define CDOT 4 ! 20: #define CCL 6 ! 21: #define NCCL 8 ! 22: #define CDOL 10 ! 23: #define CEOF 11 ! 24: #define CKET 12 ! 25: #define CBACK 14 ! 26: ! 27: #define STAR 01 ! 28: ! 29: char Q[] = ""; ! 30: char T[] = "TMP"; ! 31: #define READ 0 ! 32: #define WRITE 1 ! 33: ! 34: int peekc; ! 35: int lastc; ! 36: char savedfile[FNSIZE]; ! 37: char file[FNSIZE]; ! 38: char linebuf[LBSIZE]; ! 39: char rhsbuf[LBSIZE/2]; ! 40: char expbuf[ESIZE+4]; ! 41: int circfl; ! 42: int *zero; ! 43: int *dot; ! 44: int *dol; ! 45: int given; ! 46: int *addr1; ! 47: int *addr2; ! 48: char genbuf[LBSIZE]; ! 49: long count; ! 50: char *nextip; ! 51: char *linebp; ! 52: int ninbuf; ! 53: int io; ! 54: int pflag; ! 55: long lseek(); ! 56: int (*oldhup)(); ! 57: int (*oldquit)(); ! 58: int vflag = 1; ! 59: int xflag; ! 60: int xtflag; ! 61: int kflag; ! 62: int oflag; ! 63: char key[KSIZE + 1]; ! 64: char crbuf[512]; ! 65: char perm[768]; ! 66: char tperm[768]; ! 67: int listf; ! 68: int listn; ! 69: int col; ! 70: char *globp; ! 71: int tfile = -1; ! 72: int tline; ! 73: char *tfname; ! 74: char *loc1; ! 75: char *loc2; ! 76: char *locs; ! 77: char ibuff[512]; ! 78: int iblock = -1; ! 79: char obuff[512]; ! 80: int oblock = -1; ! 81: int ichanged; ! 82: int nleft; ! 83: char WRERR[] = "WRITE ERROR"; ! 84: int names[26]; ! 85: int anymarks; ! 86: char *braslist[NBRA]; ! 87: char *braelist[NBRA]; ! 88: int nbra; ! 89: int subnewa; ! 90: int subolda; ! 91: int fchange; ! 92: int wrapp; ! 93: int bpagesize = 20; ! 94: unsigned nlall = 128; ! 95: ! 96: int *address(); ! 97: char *getline(); ! 98: char *getblock(); ! 99: char *place(); ! 100: char *mktemp(); ! 101: char *malloc(); ! 102: char *realloc(); ! 103: jmp_buf savej; ! 104: ! 105: main(argc, argv) ! 106: char **argv; ! 107: { ! 108: register char *p1, *p2; ! 109: extern int onintr(), quit(), onhup(); ! 110: int (*oldintr)(); ! 111: ! 112: oldquit = signal(SIGQUIT, SIG_IGN); ! 113: oldhup = signal(SIGHUP, SIG_IGN); ! 114: oldintr = signal(SIGINT, SIG_IGN); ! 115: if ((int)signal(SIGTERM, SIG_IGN) == 0) ! 116: signal(SIGTERM, quit); ! 117: argv++; ! 118: while (argc > 1 && **argv=='-') { ! 119: switch((*argv)[1]) { ! 120: ! 121: case '\0': ! 122: vflag = 0; ! 123: break; ! 124: ! 125: case 'q': ! 126: signal(SIGQUIT, SIG_DFL); ! 127: vflag = 1; ! 128: break; ! 129: ! 130: case 'X': ! 131: xflag = 1; ! 132: break; ! 133: ! 134: case 'o': ! 135: oflag = 1; ! 136: vflag = 0; ! 137: break; ! 138: } ! 139: argv++; ! 140: argc--; ! 141: } ! 142: if(xflag){ ! 143: getkey(); ! 144: kflag = crinit(key, perm); ! 145: } ! 146: ! 147: if (oflag) { ! 148: p1 = "/dev/stdout"; ! 149: p2 = savedfile; ! 150: while (*p2++ = *p1++) ! 151: ; ! 152: globp = "a"; ! 153: } else if (argc>1) { ! 154: p1 = *argv; ! 155: p2 = savedfile; ! 156: while (*p2++ = *p1++) ! 157: if (p2 >= &savedfile[sizeof(savedfile)]) ! 158: p2--; ! 159: globp = "r"; ! 160: } ! 161: zero = (int *)malloc(nlall*sizeof(int)); ! 162: tfname = mktemp("/tmp/eXXXXX"); ! 163: init(); ! 164: if (((int)oldintr&01) == 0) ! 165: signal(SIGINT, onintr); ! 166: if (((int)oldhup&01) == 0) ! 167: signal(SIGHUP, onhup); ! 168: setjmp(savej); ! 169: commands(); ! 170: quit(); ! 171: } ! 172: ! 173: commands() ! 174: { ! 175: int getfile(), gettty(); ! 176: register *a1, c; ! 177: register int temp; ! 178: char lastsep; ! 179: ! 180: for (;;) { ! 181: if (pflag) { ! 182: pflag = 0; ! 183: addr1 = addr2 = dot; ! 184: print(); ! 185: } ! 186: c = '\n'; ! 187: for (addr1 = 0;;) { ! 188: lastsep = c; ! 189: a1 = address(); ! 190: c = getchr(); ! 191: if (c!=',' && c!=';') ! 192: break; ! 193: if (lastsep==',') ! 194: error(Q); ! 195: if (a1==0) { ! 196: a1 = zero+1; ! 197: if (a1>dol) ! 198: a1--; ! 199: } ! 200: addr1 = a1; ! 201: if (c==';') ! 202: dot = a1; ! 203: } ! 204: if (lastsep!='\n' && a1==0) ! 205: a1 = dol; ! 206: if ((addr2=a1)==0) { ! 207: given = 0; ! 208: addr2 = dot; ! 209: } ! 210: else ! 211: given = 1; ! 212: if (addr1==0) ! 213: addr1 = addr2; ! 214: switch(c) { ! 215: ! 216: case 'a': ! 217: add(0); ! 218: continue; ! 219: ! 220: case 'b': ! 221: nonzero(); ! 222: browse(); ! 223: continue; ! 224: ! 225: case 'c': ! 226: nonzero(); ! 227: newline(); ! 228: rdelete(addr1, addr2); ! 229: append(gettty, addr1-1); ! 230: continue; ! 231: ! 232: case 'd': ! 233: nonzero(); ! 234: newline(); ! 235: rdelete(addr1, addr2); ! 236: continue; ! 237: ! 238: case 'E': ! 239: fchange = 0; ! 240: c = 'e'; ! 241: case 'e': ! 242: setnoaddr(); ! 243: if (vflag && fchange) { ! 244: fchange = 0; ! 245: error(Q); ! 246: } ! 247: filename(c); ! 248: init(); ! 249: addr2 = zero; ! 250: goto caseread; ! 251: ! 252: case 'f': ! 253: setnoaddr(); ! 254: filename(c); ! 255: puts(savedfile); ! 256: continue; ! 257: ! 258: case 'g': ! 259: global(1); ! 260: continue; ! 261: ! 262: case 'i': ! 263: add(-1); ! 264: continue; ! 265: ! 266: ! 267: case 'j': ! 268: if (!given) ! 269: addr2++; ! 270: newline(); ! 271: join(); ! 272: continue; ! 273: ! 274: case 'k': ! 275: nonzero(); ! 276: if ((c = getchr()) < 'a' || c > 'z') ! 277: error(Q); ! 278: newline(); ! 279: names[c-'a'] = *addr2 & ~01; ! 280: anymarks |= 01; ! 281: continue; ! 282: ! 283: case 'm': ! 284: move(0); ! 285: continue; ! 286: ! 287: case 'n': ! 288: listn++; ! 289: newline(); ! 290: print(); ! 291: continue; ! 292: ! 293: case '\n': ! 294: if (a1==0) { ! 295: a1 = dot+1; ! 296: addr2 = a1; ! 297: addr1 = a1; ! 298: } ! 299: if (lastsep==';') ! 300: addr1 = a1; ! 301: print(); ! 302: continue; ! 303: ! 304: case 'l': ! 305: listf++; ! 306: case 'p': ! 307: case 'P': ! 308: newline(); ! 309: print(); ! 310: continue; ! 311: ! 312: case 'Q': ! 313: fchange = 0; ! 314: case 'q': ! 315: setnoaddr(); ! 316: newline(); ! 317: quit(); ! 318: ! 319: case 'r': ! 320: filename(c); ! 321: caseread: ! 322: if ((io = open(file, 0)) < 0) { ! 323: lastc = '\n'; ! 324: error(file); ! 325: } ! 326: setwide(); ! 327: squeeze(0); ! 328: ninbuf = 0; ! 329: c = zero != dol; ! 330: append(getfile, addr2); ! 331: exfile(); ! 332: fchange = c; ! 333: continue; ! 334: ! 335: case 's': ! 336: nonzero(); ! 337: substitute(globp!=0); ! 338: continue; ! 339: ! 340: case 't': ! 341: move(1); ! 342: continue; ! 343: ! 344: case 'u': ! 345: nonzero(); ! 346: newline(); ! 347: if ((*addr2&~01) != subnewa) ! 348: error(Q); ! 349: *addr2 = subolda; ! 350: dot = addr2; ! 351: continue; ! 352: ! 353: case 'v': ! 354: global(0); ! 355: continue; ! 356: ! 357: case 'W': ! 358: wrapp++; ! 359: case 'w': ! 360: setwide(); ! 361: squeeze(dol>zero); ! 362: if ((temp = getchr()) != 'q' && temp != 'Q') { ! 363: peekc = temp; ! 364: temp = 0; ! 365: } ! 366: filename(c); ! 367: if(!wrapp || ! 368: ((io = open(file,1)) == -1) || ! 369: ((lseek(io, 0L, 2)) == -1)) ! 370: if ((io = creat(file, 0666)) < 0) ! 371: error(file); ! 372: wrapp = 0; ! 373: if (dol > zero) ! 374: putfile(); ! 375: exfile(); ! 376: if (addr1<=zero+1 && addr2==dol) ! 377: fchange = 0; ! 378: if (temp == 'Q') ! 379: fchange = 0; ! 380: if (temp) ! 381: quit(); ! 382: continue; ! 383: ! 384: case 'X': ! 385: setnoaddr(); ! 386: newline(); ! 387: xflag = 1; ! 388: puts("Entering encrypting mode!"); ! 389: getkey(); ! 390: kflag = crinit(key, perm); ! 391: continue; ! 392: ! 393: ! 394: case '=': ! 395: setwide(); ! 396: squeeze(0); ! 397: newline(); ! 398: count = addr2 - zero; ! 399: putd(); ! 400: putchr('\n'); ! 401: continue; ! 402: ! 403: case '!': ! 404: callunix(); ! 405: continue; ! 406: ! 407: case EOF: ! 408: return; ! 409: ! 410: } ! 411: error(Q); ! 412: } ! 413: } ! 414: ! 415: print(){ ! 416: register int *a1; ! 417: nonzero(); ! 418: a1 = addr1; ! 419: do { ! 420: if (listn) { ! 421: count = a1-zero; ! 422: putd(); ! 423: putchr('\t'); ! 424: } ! 425: puts(getline(*a1++)); ! 426: } while (a1 <= addr2); ! 427: dot = addr2; ! 428: listf = 0; ! 429: listn = 0; ! 430: pflag = 0; ! 431: } ! 432: ! 433: int * ! 434: address() ! 435: { ! 436: register int sign, *a; ! 437: int opcnt, nextopand, *b; ! 438: register int c; ! 439: ! 440: nextopand = -1; ! 441: sign = 1; ! 442: opcnt = 0; ! 443: a = dot; ! 444: do { ! 445: do c = getchr(); while (c==' ' || c=='\t'); ! 446: if ('0'<=c && c<='9') { ! 447: peekc = c; ! 448: if (!opcnt) ! 449: a = zero; ! 450: a += sign*getnum(); ! 451: } else switch (c) { ! 452: case '$': ! 453: a = dol; ! 454: /* fall through */ ! 455: case '.': ! 456: if (opcnt) ! 457: error(Q); ! 458: break; ! 459: case '\'': ! 460: c = getchr(); ! 461: if (opcnt || c<'a' || 'z'<c) ! 462: error(Q); ! 463: a = zero; ! 464: do a++; while (a<=dol && names[c-'a']!=(*a&~01)); ! 465: break; ! 466: case '?': ! 467: sign = -sign; ! 468: /* fall through */ ! 469: case '/': ! 470: compile(c); ! 471: b = a; ! 472: for (;;) { ! 473: a += sign; ! 474: if (a<zero) ! 475: a = dol; ! 476: if (a>dol) ! 477: a = zero; ! 478: if (execute(a)) ! 479: break; ! 480: if (a==b) ! 481: error(Q); ! 482: } ! 483: break; ! 484: default: ! 485: if (nextopand == opcnt) { ! 486: a += sign; ! 487: if (a<zero || dol<a) ! 488: continue; /* error(Q); */ ! 489: } ! 490: if (c!='+' && c!='-' && c!='^') { ! 491: peekc = c; ! 492: if (opcnt==0) ! 493: a = 0; ! 494: return (a); ! 495: } ! 496: sign = 1; ! 497: if (c!='+') ! 498: sign = -sign; ! 499: nextopand = ++opcnt; ! 500: continue; ! 501: } ! 502: sign = 1; ! 503: opcnt++; ! 504: } while (zero<=a && a<=dol); ! 505: error(Q); ! 506: /*NOTREACHED*/ ! 507: } ! 508: int getnum() ! 509: { ! 510: register int r, c; ! 511: ! 512: r = 0; ! 513: while ((c=getchr())>='0' && c<='9') ! 514: r = r*10 + c - '0'; ! 515: peekc = c; ! 516: return (r); ! 517: } ! 518: ! 519: setwide() ! 520: { ! 521: if (!given) { ! 522: addr1 = zero + (dol>zero); ! 523: addr2 = dol; ! 524: } ! 525: } ! 526: ! 527: setnoaddr() ! 528: { ! 529: if (given) ! 530: error(Q); ! 531: } ! 532: ! 533: nonzero() ! 534: { ! 535: squeeze(1); ! 536: } ! 537: ! 538: squeeze(i) ! 539: int i; ! 540: { ! 541: if (addr1<zero+i || addr2>dol || addr1>addr2) ! 542: error(Q); ! 543: } ! 544: ! 545: newline() ! 546: { ! 547: register c; ! 548: ! 549: if ((c = getchr()) == '\n' || c == EOF) ! 550: return; ! 551: if (c=='p' || c=='l' || c=='n') { ! 552: pflag++; ! 553: if (c=='l') ! 554: listf++; ! 555: else if (c=='n') ! 556: listn++; ! 557: if ((c=getchr())=='\n') ! 558: return; ! 559: } ! 560: error(Q); ! 561: } ! 562: ! 563: filename(comm) ! 564: { ! 565: register char *p1, *p2; ! 566: register c; ! 567: ! 568: count = 0; ! 569: c = getchr(); ! 570: if (c=='\n' || c==EOF) { ! 571: p1 = savedfile; ! 572: if (*p1==0 && comm!='f') ! 573: error(Q); ! 574: p2 = file; ! 575: while (*p2++ = *p1++) ! 576: ; ! 577: return; ! 578: } ! 579: if (c!=' ') ! 580: error(Q); ! 581: while ((c = getchr()) == ' ') ! 582: ; ! 583: if (c=='\n') ! 584: error(Q); ! 585: p1 = file; ! 586: do { ! 587: if (p1 >= &file[sizeof(file)-1] || c==' ' || c==EOF) ! 588: error(Q); ! 589: *p1++ = c; ! 590: } while ((c = getchr()) != '\n'); ! 591: *p1++ = 0; ! 592: if (savedfile[0]==0 || comm=='e' || comm=='f') { ! 593: p1 = savedfile; ! 594: p2 = file; ! 595: while (*p1++ = *p2++) ! 596: ; ! 597: } ! 598: } ! 599: ! 600: exfile() ! 601: { ! 602: close(io); ! 603: io = -1; ! 604: if (vflag) { ! 605: putd(); ! 606: putchr('\n'); ! 607: } ! 608: } ! 609: ! 610: onintr() ! 611: { ! 612: signal(SIGINT, onintr); ! 613: putchr('\n'); ! 614: lastc = '\n'; ! 615: error(Q); ! 616: } ! 617: ! 618: onhup() ! 619: { ! 620: signal(SIGINT, SIG_IGN); ! 621: signal(SIGHUP, SIG_IGN); ! 622: if (dol > zero) { ! 623: addr1 = zero+1; ! 624: addr2 = dol; ! 625: io = creat("ed.hup", 0666); ! 626: if (io > 0) ! 627: putfile(); ! 628: } ! 629: fchange = 0; ! 630: quit(); ! 631: } ! 632: ! 633: error(s) ! 634: char *s; ! 635: { ! 636: register c; ! 637: ! 638: wrapp = 0; ! 639: listf = 0; ! 640: listn = 0; ! 641: putchr('?'); ! 642: puts(s); ! 643: count = 0; ! 644: lseek(0, (long)0, 2); ! 645: pflag = 0; ! 646: if (globp) ! 647: lastc = '\n'; ! 648: globp = 0; ! 649: peekc = lastc; ! 650: if(lastc) ! 651: while ((c = getchr()) != '\n' && c != EOF) ! 652: ; ! 653: if (io > 0) { ! 654: close(io); ! 655: io = -1; ! 656: } ! 657: longjmp(savej, 1); ! 658: } ! 659: ! 660: getchr() ! 661: { ! 662: char c; ! 663: if (lastc=peekc) { ! 664: peekc = 0; ! 665: return(lastc); ! 666: } ! 667: if (globp) { ! 668: if ((lastc = *globp++) != 0) ! 669: return(lastc); ! 670: globp = 0; ! 671: return(EOF); ! 672: } ! 673: if (read(0, &c, 1) <= 0) ! 674: return(lastc = EOF); ! 675: lastc = c&0177; ! 676: return(lastc); ! 677: } ! 678: ! 679: gettty() ! 680: { ! 681: register int rc; ! 682: ! 683: if (rc = gety()) ! 684: return(rc); ! 685: if (linebuf[0]=='.' && linebuf[1]==0) ! 686: return(EOF); ! 687: return(0); ! 688: } ! 689: ! 690: gety() ! 691: { ! 692: register int c; ! 693: register char *gf; ! 694: register char *p; ! 695: ! 696: p = linebuf; ! 697: gf = globp; ! 698: while ((c = getchr()) != '\n') { ! 699: if (c==EOF) { ! 700: if (gf) ! 701: peekc = c; ! 702: return(c); ! 703: } ! 704: if ((c &= 0177) == 0) ! 705: continue; ! 706: *p++ = c; ! 707: if (p >= &linebuf[LBSIZE-2]) ! 708: error(Q); ! 709: } ! 710: ! 711: *p++ = 0; ! 712: return(0); ! 713: } ! 714: ! 715: getfile() ! 716: { ! 717: register c; ! 718: register char *lp, *fp; ! 719: ! 720: lp = linebuf; ! 721: fp = nextip; ! 722: do { ! 723: if (--ninbuf < 0) { ! 724: if ((ninbuf = read(io, genbuf, LBSIZE)-1) < 0) ! 725: if (lp>linebuf) { ! 726: puts("'\\n' appended"); ! 727: *genbuf = '\n'; ! 728: } ! 729: else return(EOF); ! 730: fp = genbuf; ! 731: while(fp < &genbuf[ninbuf]) { ! 732: if (*fp++ & 0200) { ! 733: if (kflag) ! 734: crblock(perm, genbuf, ninbuf+1, count); ! 735: break; ! 736: } ! 737: } ! 738: fp = genbuf; ! 739: } ! 740: c = *fp++; ! 741: if (c=='\0') ! 742: continue; ! 743: if (c&0200 || lp >= &linebuf[LBSIZE]) { ! 744: lastc = '\n'; ! 745: error(Q); ! 746: } ! 747: *lp++ = c; ! 748: count++; ! 749: } while (c != '\n'); ! 750: *--lp = 0; ! 751: nextip = fp; ! 752: return(0); ! 753: } ! 754: ! 755: putfile() ! 756: { ! 757: int *a1, n; ! 758: register char *fp, *lp; ! 759: register nib; ! 760: ! 761: nib = 512; ! 762: fp = genbuf; ! 763: a1 = addr1; ! 764: do { ! 765: lp = getline(*a1++); ! 766: for (;;) { ! 767: if (--nib < 0) { ! 768: n = fp-genbuf; ! 769: if(kflag) ! 770: crblock(perm, genbuf, n, count-n); ! 771: if(write(io, genbuf, n) != n) { ! 772: puts(WRERR); ! 773: error(Q); ! 774: } ! 775: nib = 511; ! 776: fp = genbuf; ! 777: } ! 778: count++; ! 779: if ((*fp++ = *lp++) == 0) { ! 780: fp[-1] = '\n'; ! 781: break; ! 782: } ! 783: } ! 784: } while (a1 <= addr2); ! 785: n = fp-genbuf; ! 786: if(kflag) ! 787: crblock(perm, genbuf, n, count-n); ! 788: if(write(io, genbuf, n) != n) { ! 789: puts(WRERR); ! 790: error(Q); ! 791: } ! 792: } ! 793: ! 794: append(f, a) ! 795: int *a; ! 796: int (*f)(); ! 797: { ! 798: register *a1, *a2, *rdot; ! 799: int nline, tl; ! 800: ! 801: nline = 0; ! 802: dot = a; ! 803: while ((*f)() == 0) { ! 804: if ((dol-zero)+1 >= nlall) { ! 805: int *ozero = zero; ! 806: nlall += 512; ! 807: if ((zero = (int *)realloc((char *)zero, nlall*sizeof(int)))==NULL) { ! 808: error("MEM?"); ! 809: onhup(); ! 810: } ! 811: dot += zero - ozero; ! 812: dol += zero - ozero; ! 813: } ! 814: tl = putline(); ! 815: nline++; ! 816: a1 = ++dol; ! 817: a2 = a1+1; ! 818: rdot = ++dot; ! 819: while (a1 > rdot) ! 820: *--a2 = *--a1; ! 821: *rdot = tl; ! 822: } ! 823: return(nline); ! 824: } ! 825: ! 826: add(i) ! 827: int i; ! 828: { ! 829: if (i && (given || dol>zero)) { ! 830: addr1--; ! 831: addr2--; ! 832: } ! 833: squeeze(0); ! 834: newline(); ! 835: append(gettty, addr2); ! 836: } ! 837: ! 838: browse() ! 839: { ! 840: register forward, n; ! 841: static bformat; /*0*/ ! 842: static bnum; /*0*/ ! 843: forward=1; ! 844: if((peekc=getchr())!='\n'){ ! 845: if (peekc=='-' || peekc=='+') { ! 846: if(peekc=='-') ! 847: forward=0; ! 848: getchr(); ! 849: } ! 850: if((n=getnum())>0) ! 851: bpagesize=n; ! 852: } ! 853: newline(); ! 854: if (pflag) { ! 855: bformat=listf; ! 856: bnum=listn; ! 857: } else { ! 858: listf=bformat; ! 859: listn=bnum; ! 860: } ! 861: if (forward) { ! 862: addr1=addr2; ! 863: if((addr2+=bpagesize)>dol) ! 864: addr2=dol; ! 865: } else { ! 866: if((addr1=addr2-bpagesize)<=zero) ! 867: addr1=zero+1; ! 868: } ! 869: print(); ! 870: } ! 871: ! 872: callunix() ! 873: { ! 874: register (*savint)(), pid, rpid; ! 875: int retcode; ! 876: ! 877: setnoaddr(); ! 878: if ((pid = fork()) == 0) { ! 879: signal(SIGHUP, oldhup); ! 880: signal(SIGQUIT, oldquit); ! 881: execl("/bin/sh", "sh", "-t", 0); ! 882: exit(0100); ! 883: } ! 884: savint = signal(SIGINT, SIG_IGN); ! 885: while ((rpid = wait(&retcode)) != pid && rpid != -1) ! 886: ; ! 887: signal(SIGINT, savint); ! 888: if (vflag) { ! 889: puts("!"); ! 890: } ! 891: } ! 892: ! 893: quit() ! 894: { ! 895: if (vflag && fchange && dol!=zero) { ! 896: fchange = 0; ! 897: error(Q); ! 898: } ! 899: unlink(tfname); ! 900: exit(0); ! 901: } ! 902: ! 903: rdelete(ad1, ad2) ! 904: int *ad1, *ad2; ! 905: { ! 906: register *a1, *a2, *a3; ! 907: ! 908: a1 = ad1; ! 909: a2 = ad2+1; ! 910: a3 = dol; ! 911: dol -= a2 - a1; ! 912: do { ! 913: *a1++ = *a2++; ! 914: } while (a2 <= a3); ! 915: a1 = ad1; ! 916: if (a1 > dol) ! 917: a1 = dol; ! 918: dot = a1; ! 919: fchange = 1; ! 920: } ! 921: ! 922: gdelete() ! 923: { ! 924: register *a1, *a2, *a3; ! 925: ! 926: a3 = dol; ! 927: for (a1=zero; (*a1&01)==0; a1++) ! 928: if (a1>=a3) ! 929: return; ! 930: for (a2=a1+1; a2<=a3;) { ! 931: if (*a2&01) { ! 932: a2++; ! 933: dot = a1; ! 934: } else ! 935: *a1++ = *a2++; ! 936: } ! 937: dol = a1-1; ! 938: if (dot>dol) ! 939: dot = dol; ! 940: fchange = 1; ! 941: } ! 942: ! 943: char * ! 944: getline(tl) ! 945: { ! 946: register char *bp, *lp; ! 947: register nl; ! 948: ! 949: lp = linebuf; ! 950: bp = getblock(tl, READ); ! 951: nl = nleft; ! 952: tl &= ~0377; ! 953: while (*lp++ = *bp++) ! 954: if (--nl == 0) { ! 955: bp = getblock(tl+=0400, READ); ! 956: nl = nleft; ! 957: } ! 958: return(linebuf); ! 959: } ! 960: ! 961: putline() ! 962: { ! 963: register char *bp, *lp; ! 964: register nl; ! 965: int tl; ! 966: ! 967: fchange = 1; ! 968: lp = linebuf; ! 969: tl = tline; ! 970: bp = getblock(tl, WRITE); ! 971: nl = nleft; ! 972: tl &= ~0377; ! 973: while (*bp = *lp++) { ! 974: if (*bp++ == '\n') { ! 975: *--bp = 0; ! 976: linebp = lp; ! 977: break; ! 978: } ! 979: if (--nl == 0) { ! 980: bp = getblock(tl+=0400, WRITE); ! 981: nl = nleft; ! 982: } ! 983: } ! 984: nl = tline; ! 985: tline += (((lp-linebuf)+03)>>1)&077776; ! 986: return(nl); ! 987: } ! 988: ! 989: char * ! 990: getblock(atl, iof) ! 991: { ! 992: extern read(), write(); ! 993: register bno, off; ! 994: register char *p1, *p2; ! 995: register int n; ! 996: ! 997: bno = (atl>>8)&0377; ! 998: off = (atl<<1)&0774; ! 999: if (bno >= 255) { ! 1000: lastc = '\n'; ! 1001: error(T); ! 1002: } ! 1003: nleft = 512 - off; ! 1004: if (bno==iblock) { ! 1005: ichanged |= iof; ! 1006: return(ibuff+off); ! 1007: } ! 1008: if (bno==oblock) ! 1009: return(obuff+off); ! 1010: if (iof==READ) { ! 1011: if (ichanged) { ! 1012: if(xtflag) ! 1013: crblock(tperm, ibuff, 512, (long)0); ! 1014: blkio(iblock, ibuff, write); ! 1015: } ! 1016: ichanged = 0; ! 1017: iblock = bno; ! 1018: blkio(bno, ibuff, read); ! 1019: if(xtflag) ! 1020: crblock(tperm, ibuff, 512, (long)0); ! 1021: return(ibuff+off); ! 1022: } ! 1023: if (oblock>=0) { ! 1024: if(xtflag) { ! 1025: p1 = obuff; ! 1026: p2 = crbuf; ! 1027: n = 512; ! 1028: while(n--) ! 1029: *p2++ = *p1++; ! 1030: crblock(tperm, crbuf, 512, (long)0); ! 1031: blkio(oblock, crbuf, write); ! 1032: } else ! 1033: blkio(oblock, obuff, write); ! 1034: } ! 1035: oblock = bno; ! 1036: return(obuff+off); ! 1037: } ! 1038: ! 1039: blkio(b, buf, iofcn) ! 1040: char *buf; ! 1041: int (*iofcn)(); ! 1042: { ! 1043: lseek(tfile, (long)b<<9, 0); ! 1044: if ((*iofcn)(tfile, buf, 512) != 512) { ! 1045: error(T); ! 1046: } ! 1047: } ! 1048: ! 1049: init() ! 1050: { ! 1051: register *markp; ! 1052: ! 1053: close(tfile); ! 1054: tline = 2; ! 1055: for (markp = names; markp < &names[26]; ) ! 1056: *markp++ = 0; ! 1057: subnewa = 0; ! 1058: anymarks = 0; ! 1059: iblock = -1; ! 1060: oblock = -1; ! 1061: ichanged = 0; ! 1062: close(creat(tfname, 0600)); ! 1063: tfile = open(tfname, 2); ! 1064: if(xflag) { ! 1065: xtflag = 1; ! 1066: makekey(key, tperm); ! 1067: } ! 1068: dot = dol = zero; ! 1069: } ! 1070: ! 1071: global(k) ! 1072: { ! 1073: register char *gp; ! 1074: register c; ! 1075: register int *a1; ! 1076: char globuf[GBSIZE]; ! 1077: ! 1078: if (globp) ! 1079: error(Q); ! 1080: setwide(); ! 1081: squeeze(dol>zero); ! 1082: if ((c=getchr())=='\n') ! 1083: error(Q); ! 1084: compile(c); ! 1085: gp = globuf; ! 1086: while ((c = getchr()) != '\n') { ! 1087: if (c==EOF) ! 1088: error(Q); ! 1089: if (c=='\\') { ! 1090: c = getchr(); ! 1091: if (c!='\n') ! 1092: *gp++ = '\\'; ! 1093: } ! 1094: *gp++ = c; ! 1095: if (gp >= &globuf[GBSIZE-2]) ! 1096: error(Q); ! 1097: } ! 1098: if (gp == globuf) ! 1099: *gp++ = 'p'; ! 1100: *gp++ = '\n'; ! 1101: *gp++ = 0; ! 1102: for (a1=zero; a1<=dol; a1++) { ! 1103: *a1 &= ~01; ! 1104: if (a1>=addr1 && a1<=addr2 && execute(a1)==k) ! 1105: *a1 |= 01; ! 1106: } ! 1107: /* ! 1108: * Special case: g/.../d (avoid n^2 algorithm) ! 1109: */ ! 1110: if (globuf[0]=='d' && globuf[1]=='\n' && globuf[2]=='\0') { ! 1111: gdelete(); ! 1112: return; ! 1113: } ! 1114: for (a1=zero; a1<=dol; a1++) { ! 1115: if (*a1 & 01) { ! 1116: *a1 &= ~01; ! 1117: dot = a1; ! 1118: globp = globuf; ! 1119: commands(); ! 1120: a1 = zero; ! 1121: } ! 1122: } ! 1123: } ! 1124: ! 1125: join() ! 1126: { ! 1127: register char *gp, *lp; ! 1128: register *a1; ! 1129: ! 1130: nonzero(); ! 1131: gp = genbuf; ! 1132: for (a1=addr1; a1<=addr2; a1++) { ! 1133: lp = getline(*a1); ! 1134: while (*gp = *lp++) ! 1135: if (gp++ >= &genbuf[LBSIZE-2]) ! 1136: error(Q); ! 1137: } ! 1138: lp = linebuf; ! 1139: gp = genbuf; ! 1140: while (*lp++ = *gp++) ! 1141: ; ! 1142: *addr1 = putline(); ! 1143: if (addr1<addr2) ! 1144: rdelete(addr1+1, addr2); ! 1145: dot = addr1; ! 1146: } ! 1147: ! 1148: substitute(inglob) ! 1149: { ! 1150: register *markp, *a1, nl; ! 1151: int gsubf; ! 1152: int getsub(); ! 1153: int n, m; ! 1154: ! 1155: n = getnum(); /* OK even if n==0 */ ! 1156: gsubf = compsub(); ! 1157: for (a1 = addr1; a1 <= addr2; a1++) { ! 1158: if (execute(a1)){ ! 1159: int *ozero; ! 1160: m = n; ! 1161: do { ! 1162: if (--m <= 0) { ! 1163: dosub(); ! 1164: if (!gsubf) ! 1165: break; ! 1166: } ! 1167: } while (execute((int *)0)); ! 1168: if (m <= 0) { ! 1169: inglob |= 01; ! 1170: subnewa = putline(); ! 1171: *a1 &= ~01; ! 1172: if (anymarks) { ! 1173: for (markp = names; markp < &names[26]; markp++) ! 1174: if (*markp == *a1) ! 1175: *markp = subnewa; ! 1176: } ! 1177: subolda = *a1; ! 1178: *a1 = subnewa; ! 1179: ozero = zero; ! 1180: nl = append(getsub, a1); ! 1181: nl += zero-ozero; ! 1182: a1 += nl; ! 1183: addr2 += nl; ! 1184: } ! 1185: } ! 1186: } ! 1187: if (inglob==0) ! 1188: error(Q); ! 1189: } ! 1190: ! 1191: compsub() ! 1192: { ! 1193: register seof, c; ! 1194: register char *p; ! 1195: ! 1196: if ((seof = getchr()) == '\n' || seof == ' ') ! 1197: error(Q); ! 1198: compile(seof); ! 1199: p = rhsbuf; ! 1200: for (;;) { ! 1201: c = getchr(); ! 1202: if (c=='\\') ! 1203: c = getchr() | 0200; ! 1204: if (c=='\n') { ! 1205: if (globp && globp[0]) /* last '\n' does not count */ ! 1206: c |= 0200; ! 1207: else { ! 1208: peekc = c; ! 1209: pflag++; ! 1210: break; ! 1211: } ! 1212: } ! 1213: if (c==seof) ! 1214: break; ! 1215: *p++ = c; ! 1216: if (p >= &rhsbuf[LBSIZE/2]) ! 1217: error(Q); ! 1218: } ! 1219: *p++ = 0; ! 1220: if ((peekc = getchr()) == 'g') { ! 1221: peekc = 0; ! 1222: newline(); ! 1223: return(1); ! 1224: } ! 1225: newline(); ! 1226: return(0); ! 1227: } ! 1228: ! 1229: getsub() ! 1230: { ! 1231: register char *p1, *p2; ! 1232: ! 1233: p1 = linebuf; ! 1234: if ((p2 = linebp) == 0) ! 1235: return(EOF); ! 1236: while (*p1++ = *p2++) ! 1237: ; ! 1238: linebp = 0; ! 1239: return(0); ! 1240: } ! 1241: ! 1242: dosub() ! 1243: { ! 1244: register char *lp, *sp, *rp; ! 1245: int c; ! 1246: ! 1247: lp = linebuf; ! 1248: sp = genbuf; ! 1249: rp = rhsbuf; ! 1250: while (lp < loc1) ! 1251: *sp++ = *lp++; ! 1252: while (c = *rp++&0377) { ! 1253: if (c=='&') { ! 1254: sp = place(sp, loc1, loc2); ! 1255: continue; ! 1256: } else if (c&0200 && (c &= 0177) >='1' && c < nbra+'1') { ! 1257: sp = place(sp, braslist[c-'1'], braelist[c-'1']); ! 1258: continue; ! 1259: } ! 1260: *sp++ = c&0177; ! 1261: if (sp >= &genbuf[LBSIZE]) ! 1262: error(Q); ! 1263: } ! 1264: lp = loc2; ! 1265: loc2 = sp - genbuf + linebuf; ! 1266: while (*sp++ = *lp++) ! 1267: if (sp >= &genbuf[LBSIZE]) ! 1268: error(Q); ! 1269: lp = linebuf; ! 1270: sp = genbuf; ! 1271: while (*lp++ = *sp++) ! 1272: ; ! 1273: } ! 1274: ! 1275: char * ! 1276: place(sp, l1, l2) ! 1277: register char *sp, *l1, *l2; ! 1278: { ! 1279: ! 1280: while (l1 < l2) { ! 1281: *sp++ = *l1++; ! 1282: if (sp >= &genbuf[LBSIZE]) ! 1283: error(Q); ! 1284: } ! 1285: return(sp); ! 1286: } ! 1287: ! 1288: move(cflag) ! 1289: { ! 1290: register int *adt, *ad1, *ad2; ! 1291: int getcopy(); ! 1292: ! 1293: nonzero(); ! 1294: if ((adt = address())==0) /* address() guarantees addr is in range */ ! 1295: error(Q); ! 1296: newline(); ! 1297: if (cflag) { ! 1298: int *ozero, delta; ! 1299: ad1 = dol; ! 1300: ozero = zero; ! 1301: append(getcopy, ad1++); ! 1302: ad2 = dol; ! 1303: delta = zero - ozero; ! 1304: ad1 += delta; ! 1305: adt += delta; ! 1306: } else { ! 1307: ad2 = addr2; ! 1308: for (ad1 = addr1; ad1 <= ad2;) ! 1309: *ad1++ &= ~01; ! 1310: ad1 = addr1; ! 1311: } ! 1312: ad2++; ! 1313: if (adt<ad1) { ! 1314: dot = adt + (ad2-ad1); ! 1315: if ((++adt)==ad1) ! 1316: return; ! 1317: reverse(adt, ad1); ! 1318: reverse(ad1, ad2); ! 1319: reverse(adt, ad2); ! 1320: } else if (adt >= ad2) { ! 1321: dot = adt++; ! 1322: reverse(ad1, ad2); ! 1323: reverse(ad2, adt); ! 1324: reverse(ad1, adt); ! 1325: } else ! 1326: error(Q); ! 1327: fchange = 1; ! 1328: } ! 1329: ! 1330: reverse(a1, a2) ! 1331: register int *a1, *a2; ! 1332: { ! 1333: register int t; ! 1334: ! 1335: for (;;) { ! 1336: t = *--a2; ! 1337: if (a2 <= a1) ! 1338: return; ! 1339: *a2 = *a1; ! 1340: *a1++ = t; ! 1341: } ! 1342: } ! 1343: ! 1344: getcopy() ! 1345: { ! 1346: if (addr1 > addr2) ! 1347: return(EOF); ! 1348: getline(*addr1++); ! 1349: return(0); ! 1350: } ! 1351: ! 1352: compile(aeof) ! 1353: { ! 1354: register eof, c; ! 1355: register char *ep; ! 1356: char *lastep; ! 1357: char bracket[NBRA], *bracketp; ! 1358: int cclcnt; ! 1359: ! 1360: ep = expbuf; ! 1361: eof = aeof; ! 1362: bracketp = bracket; ! 1363: if ((c = getchr()) == '\n') { ! 1364: peekc = c; ! 1365: c = eof; ! 1366: } ! 1367: if (c == eof) { ! 1368: if (*ep==0) ! 1369: error(Q); ! 1370: return; ! 1371: } ! 1372: circfl = 0; ! 1373: nbra = 0; ! 1374: if (c=='^') { ! 1375: c = getchr(); ! 1376: circfl++; ! 1377: } ! 1378: peekc = c; ! 1379: lastep = 0; ! 1380: for (;;) { ! 1381: if (ep >= &expbuf[ESIZE]) ! 1382: goto cerror; ! 1383: c = getchr(); ! 1384: if (c == '\n') { ! 1385: peekc = c; ! 1386: c = eof; ! 1387: } ! 1388: if (c==eof) { ! 1389: if (bracketp != bracket) ! 1390: goto cerror; ! 1391: *ep++ = CEOF; ! 1392: return; ! 1393: } ! 1394: if (c!='*') ! 1395: lastep = ep; ! 1396: switch (c) { ! 1397: ! 1398: case '\\': ! 1399: if ((c = getchr())=='(') { ! 1400: if (nbra >= NBRA) ! 1401: goto cerror; ! 1402: *bracketp++ = nbra; ! 1403: *ep++ = CBRA; ! 1404: *ep++ = nbra++; ! 1405: continue; ! 1406: } ! 1407: if (c == ')') { ! 1408: if (bracketp <= bracket) ! 1409: goto cerror; ! 1410: *ep++ = CKET; ! 1411: *ep++ = *--bracketp; ! 1412: continue; ! 1413: } ! 1414: if (c>='1' && c<'1'+NBRA) { ! 1415: *ep++ = CBACK; ! 1416: *ep++ = c-'1'; ! 1417: continue; ! 1418: } ! 1419: *ep++ = CCHR; ! 1420: if (c=='\n') ! 1421: goto cerror; ! 1422: *ep++ = c; ! 1423: continue; ! 1424: ! 1425: case '.': ! 1426: *ep++ = CDOT; ! 1427: continue; ! 1428: ! 1429: case '\n': ! 1430: goto cerror; ! 1431: ! 1432: case '*': ! 1433: if (lastep==0 || *lastep==CBRA || *lastep==CKET) ! 1434: goto defchar; ! 1435: *lastep |= STAR; ! 1436: continue; ! 1437: ! 1438: case '$': ! 1439: if ((peekc=getchr()) != eof && peekc!='\n') ! 1440: goto defchar; ! 1441: *ep++ = CDOL; ! 1442: continue; ! 1443: ! 1444: case '[': ! 1445: *ep++ = CCL; ! 1446: *ep++ = 0; ! 1447: cclcnt = 1; ! 1448: if ((c=getchr()) == '^') { ! 1449: c = getchr(); ! 1450: ep[-2] = NCCL; ! 1451: } ! 1452: do { ! 1453: if (c=='\n') ! 1454: goto cerror; ! 1455: if (c=='-' && ep[-1]!=0) { ! 1456: if ((c=getchr())==']') { ! 1457: *ep++ = '-'; ! 1458: cclcnt++; ! 1459: break; ! 1460: } ! 1461: while (ep[-1]<c) { ! 1462: *ep = ep[-1]+1; ! 1463: ep++; ! 1464: cclcnt++; ! 1465: if (ep>=&expbuf[ESIZE]) ! 1466: goto cerror; ! 1467: } ! 1468: } ! 1469: *ep++ = c; ! 1470: cclcnt++; ! 1471: if (ep >= &expbuf[ESIZE]) ! 1472: goto cerror; ! 1473: } while ((c = getchr()) != ']'); ! 1474: lastep[1] = cclcnt; ! 1475: continue; ! 1476: ! 1477: defchar: ! 1478: default: ! 1479: *ep++ = CCHR; ! 1480: *ep++ = c; ! 1481: } ! 1482: } ! 1483: cerror: ! 1484: expbuf[0] = 0; ! 1485: nbra = 0; ! 1486: error(Q); ! 1487: } ! 1488: ! 1489: execute(addr) ! 1490: int *addr; ! 1491: { ! 1492: register char *p1, *p2; ! 1493: register c; ! 1494: ! 1495: for (c=0; c<NBRA; c++) { ! 1496: braslist[c] = 0; ! 1497: braelist[c] = 0; ! 1498: } ! 1499: if (addr == (int *)0) { ! 1500: if (circfl) ! 1501: return(0); ! 1502: locs = p1 = loc2; ! 1503: } else { ! 1504: if (addr==zero) ! 1505: return(0); ! 1506: p1 = getline(*addr); ! 1507: locs = 0; ! 1508: } ! 1509: p2 = expbuf; ! 1510: if (circfl) { ! 1511: loc1 = p1; ! 1512: return(advance(p1, p2)); ! 1513: } ! 1514: /* fast check for first character */ ! 1515: if (*p2==CCHR) { ! 1516: c = p2[1]; ! 1517: do { ! 1518: if (*p1!=c) ! 1519: continue; ! 1520: if (advance(p1, p2)) { ! 1521: loc1 = p1; ! 1522: return(1); ! 1523: } ! 1524: } while (*p1++); ! 1525: return(0); ! 1526: } ! 1527: /* regular algorithm */ ! 1528: do { ! 1529: if (advance(p1, p2)) { ! 1530: loc1 = p1; ! 1531: return(1); ! 1532: } ! 1533: } while (*p1++); ! 1534: return(0); ! 1535: } ! 1536: ! 1537: advance(lp, ep) ! 1538: register char *ep, *lp; ! 1539: { ! 1540: register char *curlp; ! 1541: int i; ! 1542: ! 1543: for (;;) switch (*ep++) { ! 1544: ! 1545: case CCHR: ! 1546: if (*ep++ == *lp++) ! 1547: continue; ! 1548: return(0); ! 1549: ! 1550: case CDOT: ! 1551: if (*lp++) ! 1552: continue; ! 1553: return(0); ! 1554: ! 1555: case CDOL: ! 1556: if (*lp==0) ! 1557: continue; ! 1558: return(0); ! 1559: ! 1560: case CEOF: ! 1561: loc2 = lp; ! 1562: return(1); ! 1563: ! 1564: case CCL: ! 1565: if (cclass(ep, *lp++, 1)) { ! 1566: ep += *ep; ! 1567: continue; ! 1568: } ! 1569: return(0); ! 1570: ! 1571: case NCCL: ! 1572: if (cclass(ep, *lp++, 0)) { ! 1573: ep += *ep; ! 1574: continue; ! 1575: } ! 1576: return(0); ! 1577: ! 1578: case CBRA: ! 1579: braslist[*ep++] = lp; ! 1580: continue; ! 1581: ! 1582: case CKET: ! 1583: braelist[*ep++] = lp; ! 1584: continue; ! 1585: ! 1586: case CBACK: ! 1587: if (braelist[i = *ep++]==0) ! 1588: error(Q); ! 1589: if (backref(i, lp)) { ! 1590: lp += braelist[i] - braslist[i]; ! 1591: continue; ! 1592: } ! 1593: return(0); ! 1594: ! 1595: case CBACK|STAR: ! 1596: if (braelist[i = *ep++] == 0) ! 1597: error(Q); ! 1598: curlp = lp; ! 1599: while (backref(i, lp)) ! 1600: lp += braelist[i] - braslist[i]; ! 1601: while (lp >= curlp) { ! 1602: if (advance(lp, ep)) ! 1603: return(1); ! 1604: lp -= braelist[i] - braslist[i]; ! 1605: } ! 1606: continue; ! 1607: ! 1608: case CDOT|STAR: ! 1609: curlp = lp; ! 1610: while (*lp++) ! 1611: ; ! 1612: goto star; ! 1613: ! 1614: case CCHR|STAR: ! 1615: curlp = lp; ! 1616: while (*lp++ == *ep) ! 1617: ; ! 1618: ep++; ! 1619: goto star; ! 1620: ! 1621: case CCL|STAR: ! 1622: case NCCL|STAR: ! 1623: curlp = lp; ! 1624: while (cclass(ep, *lp++, ep[-1]==(CCL|STAR))) ! 1625: ; ! 1626: ep += *ep; ! 1627: goto star; ! 1628: ! 1629: star: ! 1630: do { ! 1631: lp--; ! 1632: if (lp==locs) ! 1633: break; ! 1634: if (advance(lp, ep)) ! 1635: return(1); ! 1636: } while (lp > curlp); ! 1637: return(0); ! 1638: ! 1639: default: ! 1640: error(Q); ! 1641: } ! 1642: } ! 1643: ! 1644: backref(i, lp) ! 1645: register i; ! 1646: register char *lp; ! 1647: { ! 1648: register char *bp; ! 1649: ! 1650: bp = braslist[i]; ! 1651: while (*bp++ == *lp++) ! 1652: if (bp >= braelist[i]) ! 1653: return(1); ! 1654: return(0); ! 1655: } ! 1656: ! 1657: cclass(set, c, af) ! 1658: register char *set; ! 1659: register c; ! 1660: { ! 1661: register n; ! 1662: ! 1663: if (c==0) ! 1664: return(0); ! 1665: n = *set++; ! 1666: while (--n) ! 1667: if (*set++ == c) ! 1668: return(af); ! 1669: return(!af); ! 1670: } ! 1671: ! 1672: putd() ! 1673: { ! 1674: register r; ! 1675: ! 1676: r = count%10; ! 1677: count /= 10; ! 1678: if (count) ! 1679: putd(); ! 1680: putchr(r + '0'); ! 1681: } ! 1682: ! 1683: puts(sp) ! 1684: register char *sp; ! 1685: { ! 1686: col = 0; ! 1687: while (*sp) ! 1688: putchr(*sp++); ! 1689: putchr('\n'); ! 1690: } ! 1691: ! 1692: char line[70]; ! 1693: char *linp = line; ! 1694: ! 1695: putchr(ac) ! 1696: { ! 1697: register char *lp; ! 1698: register c; ! 1699: ! 1700: lp = linp; ! 1701: c = ac; ! 1702: if (listf) { ! 1703: if (c=='\n') { ! 1704: if (linp!=line && linp[-1]==' ') { ! 1705: *lp++ = '\\'; ! 1706: *lp++ = 'n'; ! 1707: } ! 1708: } else { ! 1709: if (col > (72-4-2)) { ! 1710: col = 8; ! 1711: *lp++ = '\\'; ! 1712: *lp++ = '\n'; ! 1713: *lp++ = '\t'; ! 1714: } ! 1715: col++; ! 1716: if (c=='\b' || c=='\t' || c=='\\') { ! 1717: *lp++ = '\\'; ! 1718: if (c=='\b') ! 1719: c = 'b'; ! 1720: else if (c=='\t') ! 1721: c = 't'; ! 1722: col++; ! 1723: } else if (c<' ' || c=='\177') { ! 1724: *lp++ = '\\'; ! 1725: *lp++ = (c>>6) +'0'; ! 1726: *lp++ = ((c>>3)&07)+'0'; ! 1727: c = ( c &07)+'0'; ! 1728: col += 3; ! 1729: } ! 1730: } ! 1731: } ! 1732: *lp++ = c; ! 1733: if(c == '\n' || lp >= &line[64]) { ! 1734: linp = line; ! 1735: write(oflag?2:1, line, lp-line); ! 1736: return; ! 1737: } ! 1738: linp = lp; ! 1739: } ! 1740: crblock(permp, buf, nchar, startn) ! 1741: char *permp; ! 1742: char *buf; ! 1743: long startn; ! 1744: { ! 1745: register char *p1; ! 1746: int n1; ! 1747: int n2; ! 1748: register char *t1, *t2, *t3; ! 1749: ! 1750: t1 = permp; ! 1751: t2 = &permp[256]; ! 1752: t3 = &permp[512]; ! 1753: ! 1754: n1 = startn&0377; ! 1755: n2 = (startn>>8)&0377; ! 1756: p1 = buf; ! 1757: while(nchar--) { ! 1758: *p1 = t2[(t3[(t1[(*p1+n1)&0377]+n2)&0377]-n2)&0377]-n1; ! 1759: n1++; ! 1760: if(n1==256){ ! 1761: n1 = 0; ! 1762: n2++; ! 1763: if(n2==256) n2 = 0; ! 1764: } ! 1765: p1++; ! 1766: } ! 1767: } ! 1768: ! 1769: getkey() ! 1770: { ! 1771: struct sgttyb b; ! 1772: int save; ! 1773: int (*sig)(); ! 1774: register char *p; ! 1775: register c; ! 1776: ! 1777: sig = signal(SIGINT, SIG_IGN); ! 1778: if (gtty(0, &b) == -1) ! 1779: error("Input not tty"); ! 1780: save = b.sg_flags; ! 1781: b.sg_flags &= ~ECHO; ! 1782: stty(0, &b); ! 1783: puts("Key:"); ! 1784: p = key; ! 1785: while(((c=getchr()) != EOF) && (c!='\n')) { ! 1786: if(p < &key[KSIZE]) ! 1787: *p++ = c; ! 1788: } ! 1789: *p = 0; ! 1790: b.sg_flags = save; ! 1791: stty(0, &b); ! 1792: signal(SIGINT, sig); ! 1793: return(key[0] != 0); ! 1794: } ! 1795: ! 1796: /* ! 1797: * Besides initializing the encryption machine, this routine ! 1798: * returns 0 if the key is null, and 1 if it is non-null. ! 1799: */ ! 1800: crinit(keyp, permp) ! 1801: char *keyp, *permp; ! 1802: { ! 1803: register char *t1, *t2, *t3; ! 1804: register i; ! 1805: int ic, k, temp, pf[2]; ! 1806: unsigned random; ! 1807: char buf[13]; ! 1808: long seed; ! 1809: ! 1810: t1 = permp; ! 1811: t2 = &permp[256]; ! 1812: t3 = &permp[512]; ! 1813: if(*keyp == 0) ! 1814: return(0); ! 1815: strncpy(buf, keyp, 8); ! 1816: while (*keyp) ! 1817: *keyp++ = '\0'; ! 1818: buf[8] = buf[0]; ! 1819: buf[9] = buf[1]; ! 1820: if (pipe(pf)<0) ! 1821: pf[0] = pf[1] = -1; ! 1822: if (fork()==0) { ! 1823: close(0); ! 1824: close(1); ! 1825: dup(pf[0]); ! 1826: dup(pf[1]); ! 1827: execl("/usr/lib/makekey", "-", 0); ! 1828: execl("/lib/makekey", "-", 0); ! 1829: exit(1); ! 1830: } ! 1831: write(pf[1], buf, 10); ! 1832: if (wait((int *)NULL)==-1 || read(pf[0], buf, 13)!=13) ! 1833: error("crypt: cannot generate key"); ! 1834: close(pf[0]); ! 1835: close(pf[1]); ! 1836: seed = 123; ! 1837: for (i=0; i<13; i++) ! 1838: seed = seed*buf[i] + i; ! 1839: for(i=0;i<256;i++){ ! 1840: t1[i] = i; ! 1841: t3[i] = 0; ! 1842: } ! 1843: for(i=0; i<256; i++) { ! 1844: seed = 5*seed + buf[i%13]; ! 1845: random = seed % 65521; ! 1846: k = 256-1 - i; ! 1847: ic = (random&0377) % (k+1); ! 1848: random >>= 8; ! 1849: temp = t1[k]; ! 1850: t1[k] = t1[ic]; ! 1851: t1[ic] = temp; ! 1852: if(t3[k]!=0) continue; ! 1853: ic = (random&0377) % k; ! 1854: while(t3[ic]!=0) ic = (ic+1) % k; ! 1855: t3[k] = ic; ! 1856: t3[ic] = k; ! 1857: } ! 1858: for(i=0; i<256; i++) ! 1859: t2[t1[i]&0377] = i; ! 1860: return(1); ! 1861: } ! 1862: ! 1863: makekey(a, b) ! 1864: char *a, *b; ! 1865: { ! 1866: register int i; ! 1867: long t; ! 1868: char temp[KSIZE + 1]; ! 1869: ! 1870: for(i = 0; i < KSIZE; i++) ! 1871: temp[i] = *a++; ! 1872: time(&t); ! 1873: t += getpid(); ! 1874: for(i = 0; i < 4; i++) ! 1875: temp[i] ^= (t>>(8*i))&0377; ! 1876: crinit(temp, b); ! 1877: ! 1878: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.