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