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