|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)ed.c 4.4 (Berkeley) 4/26/86";
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: if ((zero = (int *)realloc((char *)zero, nlall*sizeof(int)))==NULL) {
753: lastc = '\n';
754: zero = ozero;
755: error("MEM?");
756: }
757: dot += zero - ozero;
758: dol += zero - ozero;
759: }
760: tl = putline();
761: nline++;
762: a1 = ++dol;
763: a2 = a1+1;
764: rdot = ++dot;
765: while (a1 > rdot)
766: *--a2 = *--a1;
767: *rdot = tl;
768: }
769: return(nline);
770: }
771:
772: callunix()
773: {
774: register (*savint)(), pid, rpid;
775: int retcode;
776:
777: setnoaddr();
778: if ((pid = fork()) == 0) {
779: signal(SIGHUP, oldhup);
780: signal(SIGQUIT, oldquit);
781: execl("/bin/sh", "sh", "-t", 0);
782: exit(0100);
783: }
784: savint = signal(SIGINT, SIG_IGN);
785: while ((rpid = wait(&retcode)) != pid && rpid != -1)
786: ;
787: signal(SIGINT, savint);
788: puts("!");
789: }
790:
791: quit()
792: {
793: if (vflag && fchange && dol!=zero) {
794: fchange = 0;
795: error(Q);
796: }
797: unlink(tfname);
798: exit(0);
799: }
800:
801: delete()
802: {
803: setdot();
804: newline();
805: nonzero();
806: rdelete(addr1, addr2);
807: }
808:
809: rdelete(ad1, ad2)
810: int *ad1, *ad2;
811: {
812: register *a1, *a2, *a3;
813:
814: a1 = ad1;
815: a2 = ad2+1;
816: a3 = dol;
817: dol -= a2 - a1;
818: do {
819: *a1++ = *a2++;
820: } while (a2 <= a3);
821: a1 = ad1;
822: if (a1 > dol)
823: a1 = dol;
824: dot = a1;
825: fchange = 1;
826: }
827:
828: gdelete()
829: {
830: register *a1, *a2, *a3;
831:
832: a3 = dol;
833: for (a1=zero+1; (*a1&01)==0; a1++)
834: if (a1>=a3)
835: return;
836: for (a2=a1+1; a2<=a3;) {
837: if (*a2&01) {
838: a2++;
839: dot = a1;
840: } else
841: *a1++ = *a2++;
842: }
843: dol = a1-1;
844: if (dot>dol)
845: dot = dol;
846: fchange = 1;
847: }
848:
849: char *
850: getline(tl)
851: {
852: register char *bp, *lp;
853: register nl;
854:
855: lp = linebuf;
856: bp = getblock(tl, READ);
857: nl = nleft;
858: tl &= ~0377;
859: while (*lp++ = *bp++)
860: if (--nl == 0) {
861: bp = getblock(tl+=0400, READ);
862: nl = nleft;
863: }
864: return(linebuf);
865: }
866:
867: putline()
868: {
869: register char *bp, *lp;
870: register nl;
871: int tl;
872:
873: fchange = 1;
874: lp = linebuf;
875: tl = tline;
876: bp = getblock(tl, WRITE);
877: nl = nleft;
878: tl &= ~0377;
879: while (*bp = *lp++) {
880: if (*bp++ == '\n') {
881: *--bp = 0;
882: linebp = lp;
883: break;
884: }
885: if (--nl == 0) {
886: bp = getblock(tl+=0400, WRITE);
887: nl = nleft;
888: }
889: }
890: nl = tline;
891: tline += (((lp-linebuf)+03)>>1)&077776;
892: return(nl);
893: }
894:
895: char *
896: getblock(atl, iof)
897: {
898: extern read(), write();
899: register bno, off;
900: register char *p1, *p2;
901: register int n;
902:
903: bno = (atl>>8)&0377;
904: off = (atl<<1)&0774;
905: if (bno >= 255) {
906: lastc = '\n';
907: error(T);
908: }
909: nleft = 512 - off;
910: if (bno==iblock) {
911: ichanged |= iof;
912: return(ibuff+off);
913: }
914: if (bno==oblock)
915: return(obuff+off);
916: if (iof==READ) {
917: if (ichanged) {
918: if(xtflag)
919: crblock(tperm, ibuff, 512, (long)0);
920: blkio(iblock, ibuff, write);
921: }
922: ichanged = 0;
923: iblock = bno;
924: blkio(bno, ibuff, read);
925: if(xtflag)
926: crblock(tperm, ibuff, 512, (long)0);
927: return(ibuff+off);
928: }
929: if (oblock>=0) {
930: if(xtflag) {
931: p1 = obuff;
932: p2 = crbuf;
933: n = 512;
934: while(n--)
935: *p2++ = *p1++;
936: crblock(tperm, crbuf, 512, (long)0);
937: blkio(oblock, crbuf, write);
938: } else
939: blkio(oblock, obuff, write);
940: }
941: oblock = bno;
942: return(obuff+off);
943: }
944:
945: blkio(b, buf, iofcn)
946: char *buf;
947: int (*iofcn)();
948: {
949: lseek(tfile, (long)b<<9, 0);
950: if ((*iofcn)(tfile, buf, 512) != 512) {
951: error(T);
952: }
953: }
954:
955: init()
956: {
957: register *markp;
958:
959: close(tfile);
960: tline = 2;
961: for (markp = names; markp < &names[26]; )
962: *markp++ = 0;
963: subnewa = 0;
964: anymarks = 0;
965: iblock = -1;
966: oblock = -1;
967: ichanged = 0;
968: close(creat(tfname, 0600));
969: tfile = open(tfname, 2);
970: if(xflag) {
971: xtflag = 1;
972: makekey(key, tperm);
973: }
974: dot = dol = zero;
975: }
976:
977: global(k)
978: {
979: register char *gp;
980: register c;
981: register int *a1;
982: char globuf[GBSIZE];
983:
984: if (globp)
985: error(Q);
986: setall();
987: nonzero();
988: if ((c=getchr())=='\n')
989: error(Q);
990: compile(c);
991: gp = globuf;
992: while ((c = getchr()) != '\n') {
993: if (c==EOF)
994: error(Q);
995: if (c=='\\') {
996: c = getchr();
997: if (c!='\n')
998: *gp++ = '\\';
999: }
1000: *gp++ = c;
1001: if (gp >= &globuf[GBSIZE-2])
1002: error(Q);
1003: }
1004: *gp++ = '\n';
1005: *gp++ = 0;
1006: for (a1=zero; a1<=dol; a1++) {
1007: *a1 &= ~01;
1008: if (a1>=addr1 && a1<=addr2 && execute(0, a1)==k)
1009: *a1 |= 01;
1010: }
1011: /*
1012: * Special case: g/.../d (avoid n^2 algorithm)
1013: */
1014: if (globuf[0]=='d' && globuf[1]=='\n' && globuf[2]=='\0') {
1015: gdelete();
1016: return;
1017: }
1018: for (a1=zero; a1<=dol; a1++) {
1019: if (*a1 & 01) {
1020: *a1 &= ~01;
1021: dot = a1;
1022: globp = globuf;
1023: commands();
1024: a1 = zero;
1025: }
1026: }
1027: }
1028:
1029: join()
1030: {
1031: register char *gp, *lp;
1032: register *a1;
1033:
1034: gp = genbuf;
1035: for (a1=addr1; a1<=addr2; a1++) {
1036: lp = getline(*a1);
1037: while (*gp = *lp++)
1038: if (gp++ >= &genbuf[LBSIZE-2])
1039: error(Q);
1040: }
1041: lp = linebuf;
1042: gp = genbuf;
1043: while (*lp++ = *gp++)
1044: ;
1045: *addr1 = putline();
1046: if (addr1<addr2)
1047: rdelete(addr1+1, addr2);
1048: dot = addr1;
1049: }
1050:
1051: substitute(inglob)
1052: {
1053: register *markp, *a1, nl;
1054: int gsubf;
1055: int getsub();
1056:
1057: gsubf = compsub();
1058: for (a1 = addr1; a1 <= addr2; a1++) {
1059: int *ozero;
1060: if (execute(0, a1)==0)
1061: continue;
1062: inglob |= 01;
1063: dosub();
1064: if (gsubf) {
1065: while (*loc2) {
1066: if (execute(1, (int *)0)==0)
1067: break;
1068: dosub();
1069: }
1070: }
1071: subnewa = putline();
1072: *a1 &= ~01;
1073: if (anymarks) {
1074: for (markp = names; markp < &names[26]; markp++)
1075: if (*markp == *a1)
1076: *markp = subnewa;
1077: }
1078: subolda = *a1;
1079: *a1 = subnewa;
1080: ozero = zero;
1081: nl = append(getsub, a1);
1082: nl += zero-ozero;
1083: a1 += nl;
1084: addr2 += nl;
1085: }
1086: if (inglob==0)
1087: error(Q);
1088: }
1089:
1090: compsub()
1091: {
1092: register seof, c;
1093: register char *p;
1094:
1095: if ((seof = getchr()) == '\n' || seof == ' ')
1096: error(Q);
1097: compile(seof);
1098: p = rhsbuf;
1099: for (;;) {
1100: c = getchr();
1101: if (c=='\\')
1102: c = getchr() | 0200;
1103: if (c=='\n') {
1104: if (globp)
1105: c |= 0200;
1106: else
1107: error(Q);
1108: }
1109: if (c==seof)
1110: break;
1111: *p++ = c;
1112: if (p >= &rhsbuf[LBSIZE/2])
1113: error(Q);
1114: }
1115: *p++ = 0;
1116: if ((peekc = getchr()) == 'g') {
1117: peekc = 0;
1118: newline();
1119: return(1);
1120: }
1121: newline();
1122: return(0);
1123: }
1124:
1125: getsub()
1126: {
1127: register char *p1, *p2;
1128:
1129: p1 = linebuf;
1130: if ((p2 = linebp) == 0)
1131: return(EOF);
1132: while (*p1++ = *p2++)
1133: ;
1134: linebp = 0;
1135: return(0);
1136: }
1137:
1138: dosub()
1139: {
1140: register char *lp, *sp, *rp;
1141: int c;
1142:
1143: lp = linebuf;
1144: sp = genbuf;
1145: rp = rhsbuf;
1146: while (lp < loc1)
1147: *sp++ = *lp++;
1148: while (c = *rp++&0377) {
1149: if (c=='&') {
1150: sp = place(sp, loc1, loc2);
1151: continue;
1152: } else if (c&0200 && (c &= 0177) >='1' && c < nbra+'1') {
1153: sp = place(sp, braslist[c-'1'], braelist[c-'1']);
1154: continue;
1155: }
1156: *sp++ = c&0177;
1157: if (sp >= &genbuf[LBSIZE])
1158: error(Q);
1159: }
1160: lp = loc2;
1161: loc2 = sp - genbuf + linebuf;
1162: while (*sp++ = *lp++)
1163: if (sp >= &genbuf[LBSIZE])
1164: error(Q);
1165: lp = linebuf;
1166: sp = genbuf;
1167: while (*lp++ = *sp++)
1168: ;
1169: }
1170:
1171: char *
1172: place(sp, l1, l2)
1173: register char *sp, *l1, *l2;
1174: {
1175:
1176: while (l1 < l2) {
1177: *sp++ = *l1++;
1178: if (sp >= &genbuf[LBSIZE])
1179: error(Q);
1180: }
1181: return(sp);
1182: }
1183:
1184: move(cflag)
1185: {
1186: register int *adt, *ad1, *ad2;
1187: int getcopy();
1188:
1189: setdot();
1190: nonzero();
1191: if ((adt = address())==0)
1192: error(Q);
1193: newline();
1194: if (cflag) {
1195: int *ozero, delta;
1196: ad1 = dol;
1197: ozero = zero;
1198: append(getcopy, ad1++);
1199: ad2 = dol;
1200: delta = zero - ozero;
1201: ad1 += delta;
1202: adt += delta;
1203: } else {
1204: ad2 = addr2;
1205: for (ad1 = addr1; ad1 <= ad2;)
1206: *ad1++ &= ~01;
1207: ad1 = addr1;
1208: }
1209: ad2++;
1210: if (adt<ad1) {
1211: dot = adt + (ad2-ad1);
1212: if ((++adt)==ad1)
1213: return;
1214: reverse(adt, ad1);
1215: reverse(ad1, ad2);
1216: reverse(adt, ad2);
1217: } else if (adt >= ad2) {
1218: dot = adt++;
1219: reverse(ad1, ad2);
1220: reverse(ad2, adt);
1221: reverse(ad1, adt);
1222: } else
1223: error(Q);
1224: fchange = 1;
1225: }
1226:
1227: reverse(a1, a2)
1228: register int *a1, *a2;
1229: {
1230: register int t;
1231:
1232: for (;;) {
1233: t = *--a2;
1234: if (a2 <= a1)
1235: return;
1236: *a2 = *a1;
1237: *a1++ = t;
1238: }
1239: }
1240:
1241: getcopy()
1242: {
1243: if (addr1 > addr2)
1244: return(EOF);
1245: getline(*addr1++);
1246: return(0);
1247: }
1248:
1249: compile(aeof)
1250: {
1251: register eof, c;
1252: register char *ep;
1253: char *lastep;
1254: char bracket[NBRA], *bracketp;
1255: int cclcnt;
1256:
1257: ep = expbuf;
1258: eof = aeof;
1259: bracketp = bracket;
1260: if ((c = getchr()) == eof) {
1261: if (*ep==0)
1262: error(Q);
1263: return;
1264: }
1265: circfl = 0;
1266: nbra = 0;
1267: if (c=='^') {
1268: c = getchr();
1269: circfl++;
1270: }
1271: peekc = c;
1272: lastep = 0;
1273: for (;;) {
1274: if (ep >= &expbuf[ESIZE])
1275: goto cerror;
1276: c = getchr();
1277: if (c==eof) {
1278: if (bracketp != bracket)
1279: goto cerror;
1280: *ep++ = CEOF;
1281: return;
1282: }
1283: if (c!='*')
1284: lastep = ep;
1285: switch (c) {
1286:
1287: case '\\':
1288: if ((c = getchr())=='(') {
1289: if (nbra >= NBRA)
1290: goto cerror;
1291: *bracketp++ = nbra;
1292: *ep++ = CBRA;
1293: *ep++ = nbra++;
1294: continue;
1295: }
1296: if (c == ')') {
1297: if (bracketp <= bracket)
1298: goto cerror;
1299: *ep++ = CKET;
1300: *ep++ = *--bracketp;
1301: continue;
1302: }
1303: if (c>='1' && c<'1'+NBRA) {
1304: *ep++ = CBACK;
1305: *ep++ = c-'1';
1306: continue;
1307: }
1308: *ep++ = CCHR;
1309: if (c=='\n')
1310: goto cerror;
1311: *ep++ = c;
1312: continue;
1313:
1314: case '.':
1315: *ep++ = CDOT;
1316: continue;
1317:
1318: case '\n':
1319: goto cerror;
1320:
1321: case '*':
1322: if (lastep==0 || *lastep==CBRA || *lastep==CKET)
1323: goto defchar;
1324: *lastep |= STAR;
1325: continue;
1326:
1327: case '$':
1328: if ((peekc=getchr()) != eof)
1329: goto defchar;
1330: *ep++ = CDOL;
1331: continue;
1332:
1333: case '[':
1334: *ep++ = CCL;
1335: *ep++ = 0;
1336: cclcnt = 1;
1337: if ((c=getchr()) == '^') {
1338: c = getchr();
1339: ep[-2] = NCCL;
1340: }
1341: do {
1342: if (c=='\n')
1343: goto cerror;
1344: if (c=='-' && ep[-1]!=0) {
1345: if ((c=getchr())==']') {
1346: *ep++ = '-';
1347: cclcnt++;
1348: break;
1349: }
1350: while (ep[-1]<c) {
1351: *ep = ep[-1]+1;
1352: ep++;
1353: cclcnt++;
1354: if (ep>=&expbuf[ESIZE])
1355: goto cerror;
1356: }
1357: }
1358: *ep++ = c;
1359: cclcnt++;
1360: if (ep >= &expbuf[ESIZE])
1361: goto cerror;
1362: } while ((c = getchr()) != ']');
1363: lastep[1] = cclcnt;
1364: continue;
1365:
1366: defchar:
1367: default:
1368: *ep++ = CCHR;
1369: *ep++ = c;
1370: }
1371: }
1372: cerror:
1373: expbuf[0] = 0;
1374: nbra = 0;
1375: error(Q);
1376: }
1377:
1378: execute(gf, addr)
1379: int *addr;
1380: {
1381: register char *p1, *p2, c;
1382:
1383: for (c=0; c<NBRA; c++) {
1384: braslist[c] = 0;
1385: braelist[c] = 0;
1386: }
1387: if (gf) {
1388: if (circfl)
1389: return(0);
1390: p1 = linebuf;
1391: p2 = genbuf;
1392: while (*p1++ = *p2++)
1393: ;
1394: locs = p1 = loc2;
1395: } else {
1396: if (addr==zero)
1397: return(0);
1398: p1 = getline(*addr);
1399: locs = 0;
1400: }
1401: p2 = expbuf;
1402: if (circfl) {
1403: loc1 = p1;
1404: return(advance(p1, p2));
1405: }
1406: /* fast check for first character */
1407: if (*p2==CCHR) {
1408: c = p2[1];
1409: do {
1410: if (*p1!=c)
1411: continue;
1412: if (advance(p1, p2)) {
1413: loc1 = p1;
1414: return(1);
1415: }
1416: } while (*p1++);
1417: return(0);
1418: }
1419: /* regular algorithm */
1420: do {
1421: if (advance(p1, p2)) {
1422: loc1 = p1;
1423: return(1);
1424: }
1425: } while (*p1++);
1426: return(0);
1427: }
1428:
1429: advance(lp, ep)
1430: register char *ep, *lp;
1431: {
1432: register char *curlp;
1433: int i;
1434:
1435: for (;;) switch (*ep++) {
1436:
1437: case CCHR:
1438: if (*ep++ == *lp++)
1439: continue;
1440: return(0);
1441:
1442: case CDOT:
1443: if (*lp++)
1444: continue;
1445: return(0);
1446:
1447: case CDOL:
1448: if (*lp==0)
1449: continue;
1450: return(0);
1451:
1452: case CEOF:
1453: loc2 = lp;
1454: return(1);
1455:
1456: case CCL:
1457: if (cclass(ep, *lp++, 1)) {
1458: ep += *ep;
1459: continue;
1460: }
1461: return(0);
1462:
1463: case NCCL:
1464: if (cclass(ep, *lp++, 0)) {
1465: ep += *ep;
1466: continue;
1467: }
1468: return(0);
1469:
1470: case CBRA:
1471: braslist[*ep++] = lp;
1472: continue;
1473:
1474: case CKET:
1475: braelist[*ep++] = lp;
1476: continue;
1477:
1478: case CBACK:
1479: if (braelist[i = *ep++]==0)
1480: error(Q);
1481: if (backref(i, lp)) {
1482: lp += braelist[i] - braslist[i];
1483: continue;
1484: }
1485: return(0);
1486:
1487: case CBACK|STAR:
1488: if (braelist[i = *ep++] == 0)
1489: error(Q);
1490: curlp = lp;
1491: while (backref(i, lp))
1492: lp += braelist[i] - braslist[i];
1493: while (lp >= curlp) {
1494: if (advance(lp, ep))
1495: return(1);
1496: lp -= braelist[i] - braslist[i];
1497: }
1498: continue;
1499:
1500: case CDOT|STAR:
1501: curlp = lp;
1502: while (*lp++)
1503: ;
1504: goto star;
1505:
1506: case CCHR|STAR:
1507: curlp = lp;
1508: while (*lp++ == *ep)
1509: ;
1510: ep++;
1511: goto star;
1512:
1513: case CCL|STAR:
1514: case NCCL|STAR:
1515: curlp = lp;
1516: while (cclass(ep, *lp++, ep[-1]==(CCL|STAR)))
1517: ;
1518: ep += *ep;
1519: goto star;
1520:
1521: star:
1522: do {
1523: lp--;
1524: if (lp==locs)
1525: break;
1526: if (advance(lp, ep))
1527: return(1);
1528: } while (lp > curlp);
1529: return(0);
1530:
1531: default:
1532: error(Q);
1533: }
1534: }
1535:
1536: backref(i, lp)
1537: register i;
1538: register char *lp;
1539: {
1540: register char *bp;
1541:
1542: bp = braslist[i];
1543: while (*bp++ == *lp++)
1544: if (bp >= braelist[i])
1545: return(1);
1546: return(0);
1547: }
1548:
1549: cclass(set, c, af)
1550: register char *set, c;
1551: {
1552: register n;
1553:
1554: if (c==0)
1555: return(0);
1556: n = *set++;
1557: while (--n)
1558: if (*set++ == c)
1559: return(af);
1560: return(!af);
1561: }
1562:
1563: putd()
1564: {
1565: register r;
1566:
1567: r = count%10;
1568: count /= 10;
1569: if (count)
1570: putd();
1571: putchr(r + '0');
1572: }
1573:
1574: puts(sp)
1575: register char *sp;
1576: {
1577: col = 0;
1578: while (*sp)
1579: putchr(*sp++);
1580: putchr('\n');
1581: }
1582:
1583: char line[70];
1584: char *linp = line;
1585:
1586: putchr(ac)
1587: {
1588: register char *lp;
1589: register c;
1590:
1591: lp = linp;
1592: c = ac;
1593: if (listf) {
1594: col++;
1595: if (col >= 72) {
1596: col = 0;
1597: *lp++ = '\\';
1598: *lp++ = '\n';
1599: }
1600: if (c=='\t') {
1601: c = '>';
1602: goto esc;
1603: }
1604: if (c=='\b') {
1605: c = '<';
1606: esc:
1607: *lp++ = '-';
1608: *lp++ = '\b';
1609: *lp++ = c;
1610: goto out;
1611: }
1612: if (c<' ' && c!= '\n') {
1613: *lp++ = '\\';
1614: *lp++ = (c>>3)+'0';
1615: *lp++ = (c&07)+'0';
1616: col += 2;
1617: goto out;
1618: }
1619: }
1620: *lp++ = c;
1621: out:
1622: if(c == '\n' || lp >= &line[64]) {
1623: linp = line;
1624: write(1, line, lp-line);
1625: return;
1626: }
1627: linp = lp;
1628: }
1629: crblock(permp, buf, nchar, startn)
1630: char *permp;
1631: char *buf;
1632: long startn;
1633: {
1634: register char *p1;
1635: int n1;
1636: int n2;
1637: register char *t1, *t2, *t3;
1638:
1639: t1 = permp;
1640: t2 = &permp[256];
1641: t3 = &permp[512];
1642:
1643: n1 = startn&0377;
1644: n2 = (startn>>8)&0377;
1645: p1 = buf;
1646: while(nchar--) {
1647: *p1 = t2[(t3[(t1[(*p1+n1)&0377]+n2)&0377]-n2)&0377]-n1;
1648: n1++;
1649: if(n1==256){
1650: n1 = 0;
1651: n2++;
1652: if(n2==256) n2 = 0;
1653: }
1654: p1++;
1655: }
1656: }
1657:
1658: getkey()
1659: {
1660: struct sgttyb b;
1661: int save;
1662: int (*sig)();
1663: register char *p;
1664: register c;
1665:
1666: sig = signal(SIGINT, SIG_IGN);
1667: if (gtty(0, &b) == -1)
1668: error("Input not tty");
1669: save = b.sg_flags;
1670: b.sg_flags &= ~ECHO;
1671: stty(0, &b);
1672: puts("Key:");
1673: p = key;
1674: while(((c=getchr()) != EOF) && (c!='\n')) {
1675: if(p < &key[KSIZE])
1676: *p++ = c;
1677: }
1678: *p = 0;
1679: b.sg_flags = save;
1680: stty(0, &b);
1681: signal(SIGINT, sig);
1682: return(key[0] != 0);
1683: }
1684:
1685: /*
1686: * Besides initializing the encryption machine, this routine
1687: * returns 0 if the key is null, and 1 if it is non-null.
1688: */
1689: crinit(keyp, permp)
1690: char *keyp, *permp;
1691: {
1692: register char *t1, *t2, *t3;
1693: register i;
1694: int ic, k, temp, pf[2];
1695: unsigned random;
1696: char buf[13];
1697: long seed;
1698:
1699: t1 = permp;
1700: t2 = &permp[256];
1701: t3 = &permp[512];
1702: if(*keyp == 0)
1703: return(0);
1704: strncpy(buf, keyp, 8);
1705: while (*keyp)
1706: *keyp++ = '\0';
1707: buf[8] = buf[0];
1708: buf[9] = buf[1];
1709: if (pipe(pf)<0)
1710: pf[0] = pf[1] = -1;
1711: if (fork()==0) {
1712: close(0);
1713: close(1);
1714: dup(pf[0]);
1715: dup(pf[1]);
1716: execl("/usr/lib/makekey", "-", 0);
1717: execl("/lib/makekey", "-", 0);
1718: exit(1);
1719: }
1720: write(pf[1], buf, 10);
1721: if (wait((int *)NULL)==-1 || read(pf[0], buf, 13)!=13)
1722: error("crypt: cannot generate key");
1723: close(pf[0]);
1724: close(pf[1]);
1725: seed = 123;
1726: for (i=0; i<13; i++)
1727: seed = seed*buf[i] + i;
1728: for(i=0;i<256;i++){
1729: t1[i] = i;
1730: t3[i] = 0;
1731: }
1732: for(i=0; i<256; i++) {
1733: seed = 5*seed + buf[i%13];
1734: random = seed % 65521;
1735: k = 256-1 - i;
1736: ic = (random&0377) % (k+1);
1737: random >>= 8;
1738: temp = t1[k];
1739: t1[k] = t1[ic];
1740: t1[ic] = temp;
1741: if(t3[k]!=0) continue;
1742: ic = (random&0377) % k;
1743: while(t3[ic]!=0) ic = (ic+1) % k;
1744: t3[k] = ic;
1745: t3[ic] = k;
1746: }
1747: for(i=0; i<256; i++)
1748: t2[t1[i]&0377] = i;
1749: return(1);
1750: }
1751:
1752: makekey(a, b)
1753: char *a, *b;
1754: {
1755: register int i;
1756: long t;
1757: char temp[KSIZE + 1];
1758:
1759: for(i = 0; i < KSIZE; i++)
1760: temp[i] = *a++;
1761: time(&t);
1762: t += getpid();
1763: for(i = 0; i < 4; i++)
1764: temp[i] ^= (t>>(8*i))&0377;
1765: crinit(temp, b);
1766: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.