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