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