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