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