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