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