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