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