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