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