132626a91Sbostic /*-
2*ee3b4668Sbostic * Copyright (c) 1991
3*ee3b4668Sbostic * The Regents of the University of California. All rights reserved.
432626a91Sbostic *
532626a91Sbostic * %sccs.include.proprietary.c%
632626a91Sbostic */
732626a91Sbostic
8854cc826Ssam #ifndef lint
932626a91Sbostic char copyright[] =
10*ee3b4668Sbostic "@(#) Copyright (c) 1991\n\
11*ee3b4668Sbostic The Regents of the University of California. All rights reserved.\n";
1232626a91Sbostic #endif /* not lint */
1332626a91Sbostic
1432626a91Sbostic #ifndef lint
15*ee3b4668Sbostic static char sccsid[] = "@(#)ed.c 5.2 (Berkeley) 04/02/94";
1632626a91Sbostic #endif /* not lint */
1791c17a00Smckusick
1891c17a00Smckusick /*
1991c17a00Smckusick * Editor
2091c17a00Smckusick */
21*ee3b4668Sbostic #define CRYPT
22*ee3b4668Sbostic
23e6cf7962Sdonn #include <sys/param.h>
24dd8545c9Sbostic #include <sys/wait.h>
25dd8545c9Sbostic #include <signal.h>
2691c17a00Smckusick #include <sgtty.h>
2719f69de9Ssam #undef CEOF
28dd8545c9Sbostic #include <fcntl.h>
29dd8545c9Sbostic #include <time.h>
3091c17a00Smckusick #include <setjmp.h>
31dd8545c9Sbostic #include <stdlib.h>
32dd8545c9Sbostic #include <string.h>
33dd8545c9Sbostic #include <unistd.h>
3473bab485Sbostic #include "pathnames.h"
3573bab485Sbostic
3691c17a00Smckusick #define NULL 0
3791c17a00Smckusick #define LBSIZE 512
3891c17a00Smckusick #define ESIZE 128
3991c17a00Smckusick #define GBSIZE 256
4091c17a00Smckusick #define NBRA 5
4191c17a00Smckusick #define EOF -1
4291c17a00Smckusick
4391c17a00Smckusick #define CBRA 1
4491c17a00Smckusick #define CCHR 2
4591c17a00Smckusick #define CDOT 4
4691c17a00Smckusick #define CCL 6
4791c17a00Smckusick #define NCCL 8
4891c17a00Smckusick #define CDOL 10
4991c17a00Smckusick #define CEOF 11
5091c17a00Smckusick #define CKET 12
5191c17a00Smckusick #define CBACK 14
5291c17a00Smckusick
5391c17a00Smckusick #define STAR 01
5491c17a00Smckusick
5591c17a00Smckusick char Q[] = "";
5691c17a00Smckusick char T[] = "TMP";
5791c17a00Smckusick #define READ 0
5891c17a00Smckusick #define WRITE 1
5991c17a00Smckusick
6091c17a00Smckusick int peekc;
6191c17a00Smckusick int lastc;
629a892047Sbostic char savedfile[MAXPATHLEN];
639a892047Sbostic char file[MAXPATHLEN];
6491c17a00Smckusick char linebuf[LBSIZE];
6591c17a00Smckusick char rhsbuf[LBSIZE/2];
6691c17a00Smckusick char expbuf[ESIZE+4];
6791c17a00Smckusick int circfl;
6891c17a00Smckusick int *zero;
6991c17a00Smckusick int *dot;
7091c17a00Smckusick int *dol;
7191c17a00Smckusick int *addr1;
7291c17a00Smckusick int *addr2;
7391c17a00Smckusick char genbuf[LBSIZE];
7491c17a00Smckusick long count;
7591c17a00Smckusick char *nextip;
7691c17a00Smckusick char *linebp;
7791c17a00Smckusick int ninbuf;
7891c17a00Smckusick int io;
7991c17a00Smckusick int pflag;
80522670b9Sbostic sig_t oldhup;
81522670b9Sbostic sig_t oldquit;
8291c17a00Smckusick int vflag = 1;
83da1d502bSmckusick
84*ee3b4668Sbostic #ifdef CRYPT
85*ee3b4668Sbostic /*
86*ee3b4668Sbostic * Various flags and buffers needed by the encryption routines.
87*ee3b4668Sbostic */
88*ee3b4668Sbostic #define KSIZE 9
89*ee3b4668Sbostic int xflag;
90*ee3b4668Sbostic int xtflag;
91*ee3b4668Sbostic int kflag;
92*ee3b4668Sbostic char key[KSIZE + 1];
93*ee3b4668Sbostic char crbuf[512];
94*ee3b4668Sbostic char perm[768];
95*ee3b4668Sbostic char tperm[768];
96*ee3b4668Sbostic #endif CRYPT
97da1d502bSmckusick
9891c17a00Smckusick int listf;
9991c17a00Smckusick int col;
10091c17a00Smckusick char *globp;
10191c17a00Smckusick int tfile = -1;
10291c17a00Smckusick int tline;
103bad56901Sbostic char tfname[sizeof(_PATH_TMP) + 20];
10491c17a00Smckusick char *loc1;
10591c17a00Smckusick char *loc2;
10691c17a00Smckusick char *locs;
10791c17a00Smckusick char ibuff[512];
10891c17a00Smckusick int iblock = -1;
10991c17a00Smckusick char obuff[512];
11091c17a00Smckusick int oblock = -1;
11191c17a00Smckusick int ichanged;
11291c17a00Smckusick int nleft;
11391c17a00Smckusick char WRERR[] = "WRITE ERROR";
11491c17a00Smckusick int names[26];
11591c17a00Smckusick int anymarks;
11691c17a00Smckusick char *braslist[NBRA];
11791c17a00Smckusick char *braelist[NBRA];
11891c17a00Smckusick int nbra;
11991c17a00Smckusick int subnewa;
12091c17a00Smckusick int subolda;
12191c17a00Smckusick int fchange;
12291c17a00Smckusick int wrapp;
12391c17a00Smckusick unsigned nlall = 128;
12491c17a00Smckusick
12591c17a00Smckusick int *address();
12691c17a00Smckusick char *getline();
12791c17a00Smckusick char *getblock();
12891c17a00Smckusick char *place();
12991c17a00Smckusick jmp_buf savej;
13091c17a00Smckusick
131dd8545c9Sbostic void onintr(), quit(), onhup();
132dd8545c9Sbostic
main(argc,argv)13391c17a00Smckusick main(argc, argv)
134dd8545c9Sbostic int argc;
13591c17a00Smckusick char **argv;
13691c17a00Smckusick {
13791c17a00Smckusick register char *p1, *p2;
138522670b9Sbostic sig_t oldintr;
13991c17a00Smckusick
14091c17a00Smckusick oldquit = signal(SIGQUIT, SIG_IGN);
14191c17a00Smckusick oldhup = signal(SIGHUP, SIG_IGN);
14291c17a00Smckusick oldintr = signal(SIGINT, SIG_IGN);
14391c17a00Smckusick if ((int)signal(SIGTERM, SIG_IGN) == 0)
14491c17a00Smckusick signal(SIGTERM, quit);
14591c17a00Smckusick argv++;
14691c17a00Smckusick while (argc > 1 && **argv=='-') {
14791c17a00Smckusick switch((*argv)[1]) {
14891c17a00Smckusick
14991c17a00Smckusick case '\0':
15091c17a00Smckusick vflag = 0;
15191c17a00Smckusick break;
15291c17a00Smckusick
15391c17a00Smckusick case 'q':
15491c17a00Smckusick signal(SIGQUIT, SIG_DFL);
15591c17a00Smckusick vflag = 1;
15691c17a00Smckusick break;
15791c17a00Smckusick
158*ee3b4668Sbostic #ifdef CRYPT
159*ee3b4668Sbostic case 'x':
160*ee3b4668Sbostic xflag = 1;
161*ee3b4668Sbostic break;
162*ee3b4668Sbostic #endif CRYPT
16391c17a00Smckusick }
16491c17a00Smckusick argv++;
16591c17a00Smckusick argc--;
16691c17a00Smckusick }
167*ee3b4668Sbostic #ifdef CRYPT
168*ee3b4668Sbostic if(xflag){
169*ee3b4668Sbostic getkey();
170*ee3b4668Sbostic kflag = crinit(key, perm);
171*ee3b4668Sbostic }
172*ee3b4668Sbostic #endif CRYPT
17391c17a00Smckusick
17491c17a00Smckusick if (argc>1) {
17591c17a00Smckusick p1 = *argv;
17691c17a00Smckusick p2 = savedfile;
17791c17a00Smckusick while (*p2++ = *p1++)
17891c17a00Smckusick ;
17991c17a00Smckusick globp = "r";
18091c17a00Smckusick }
18191c17a00Smckusick zero = (int *)malloc(nlall*sizeof(int));
182bad56901Sbostic (void)strcpy(tfname, _PATH_TMP);
183bad56901Sbostic (void)strcat(tfname, "_edXXXXXX");
184bad56901Sbostic (void)mktemp(tfname);
18591c17a00Smckusick init();
18691c17a00Smckusick if (((int)oldintr&01) == 0)
18791c17a00Smckusick signal(SIGINT, onintr);
18891c17a00Smckusick if (((int)oldhup&01) == 0)
18991c17a00Smckusick signal(SIGHUP, onhup);
19091c17a00Smckusick setjmp(savej);
19191c17a00Smckusick commands();
19291c17a00Smckusick quit();
19391c17a00Smckusick }
19491c17a00Smckusick
commands()19591c17a00Smckusick commands()
19691c17a00Smckusick {
19791c17a00Smckusick int getfile(), gettty();
19891c17a00Smckusick register *a1, c;
19991c17a00Smckusick
20091c17a00Smckusick for (;;) {
20191c17a00Smckusick if (pflag) {
20291c17a00Smckusick pflag = 0;
20391c17a00Smckusick addr1 = addr2 = dot;
20491c17a00Smckusick goto print;
20591c17a00Smckusick }
20691c17a00Smckusick addr1 = 0;
20791c17a00Smckusick addr2 = 0;
20891c17a00Smckusick do {
20991c17a00Smckusick addr1 = addr2;
21091c17a00Smckusick if ((a1 = address())==0) {
21191c17a00Smckusick c = getchr();
21291c17a00Smckusick break;
21391c17a00Smckusick }
21491c17a00Smckusick addr2 = a1;
21591c17a00Smckusick if ((c=getchr()) == ';') {
21691c17a00Smckusick c = ',';
21791c17a00Smckusick dot = a1;
21891c17a00Smckusick }
21991c17a00Smckusick } while (c==',');
22091c17a00Smckusick if (addr1==0)
22191c17a00Smckusick addr1 = addr2;
22291c17a00Smckusick switch(c) {
22391c17a00Smckusick
22491c17a00Smckusick case 'a':
22591c17a00Smckusick setdot();
22691c17a00Smckusick newline();
22791c17a00Smckusick append(gettty, addr2);
22891c17a00Smckusick continue;
22991c17a00Smckusick
23091c17a00Smckusick case 'c':
23191c17a00Smckusick delete();
23291c17a00Smckusick append(gettty, addr1-1);
23391c17a00Smckusick continue;
23491c17a00Smckusick
23591c17a00Smckusick case 'd':
23691c17a00Smckusick delete();
23791c17a00Smckusick continue;
23891c17a00Smckusick
23991c17a00Smckusick case 'E':
24091c17a00Smckusick fchange = 0;
24191c17a00Smckusick c = 'e';
24291c17a00Smckusick case 'e':
24391c17a00Smckusick setnoaddr();
24491c17a00Smckusick if (vflag && fchange) {
24591c17a00Smckusick fchange = 0;
24691c17a00Smckusick error(Q);
24791c17a00Smckusick }
24891c17a00Smckusick filename(c);
24991c17a00Smckusick init();
25091c17a00Smckusick addr2 = zero;
25191c17a00Smckusick goto caseread;
25291c17a00Smckusick
25391c17a00Smckusick case 'f':
25491c17a00Smckusick setnoaddr();
25591c17a00Smckusick filename(c);
25691c17a00Smckusick puts(savedfile);
25791c17a00Smckusick continue;
25891c17a00Smckusick
25991c17a00Smckusick case 'g':
26091c17a00Smckusick global(1);
26191c17a00Smckusick continue;
26291c17a00Smckusick
26391c17a00Smckusick case 'i':
26491c17a00Smckusick setdot();
26591c17a00Smckusick nonzero();
26691c17a00Smckusick newline();
26791c17a00Smckusick append(gettty, addr2-1);
26891c17a00Smckusick continue;
26991c17a00Smckusick
27091c17a00Smckusick
27191c17a00Smckusick case 'j':
27291c17a00Smckusick if (addr2==0) {
27391c17a00Smckusick addr1 = dot;
27491c17a00Smckusick addr2 = dot+1;
27591c17a00Smckusick }
27691c17a00Smckusick setdot();
27791c17a00Smckusick newline();
27891c17a00Smckusick nonzero();
27991c17a00Smckusick join();
28091c17a00Smckusick continue;
28191c17a00Smckusick
28291c17a00Smckusick case 'k':
28391c17a00Smckusick if ((c = getchr()) < 'a' || c > 'z')
28491c17a00Smckusick error(Q);
28591c17a00Smckusick newline();
28691c17a00Smckusick setdot();
28791c17a00Smckusick nonzero();
28891c17a00Smckusick names[c-'a'] = *addr2 & ~01;
28991c17a00Smckusick anymarks |= 01;
29091c17a00Smckusick continue;
29191c17a00Smckusick
29291c17a00Smckusick case 'm':
29391c17a00Smckusick move(0);
29491c17a00Smckusick continue;
29591c17a00Smckusick
29691c17a00Smckusick case '\n':
29791c17a00Smckusick if (addr2==0)
29891c17a00Smckusick addr2 = dot+1;
29991c17a00Smckusick addr1 = addr2;
30091c17a00Smckusick goto print;
30191c17a00Smckusick
30291c17a00Smckusick case 'l':
30391c17a00Smckusick listf++;
30491c17a00Smckusick case 'p':
30591c17a00Smckusick case 'P':
30691c17a00Smckusick newline();
30791c17a00Smckusick print:
30891c17a00Smckusick setdot();
30991c17a00Smckusick nonzero();
31091c17a00Smckusick a1 = addr1;
31191c17a00Smckusick do {
31291c17a00Smckusick puts(getline(*a1++));
31391c17a00Smckusick } while (a1 <= addr2);
31491c17a00Smckusick dot = addr2;
31591c17a00Smckusick listf = 0;
31691c17a00Smckusick continue;
31791c17a00Smckusick
31891c17a00Smckusick case 'Q':
31991c17a00Smckusick fchange = 0;
32091c17a00Smckusick case 'q':
32191c17a00Smckusick setnoaddr();
32291c17a00Smckusick newline();
32391c17a00Smckusick quit();
32491c17a00Smckusick
32591c17a00Smckusick case 'r':
32691c17a00Smckusick filename(c);
32791c17a00Smckusick caseread:
32891c17a00Smckusick if ((io = open(file, 0)) < 0) {
32991c17a00Smckusick lastc = '\n';
33091c17a00Smckusick error(file);
33191c17a00Smckusick }
33291c17a00Smckusick setall();
33391c17a00Smckusick ninbuf = 0;
33491c17a00Smckusick c = zero != dol;
33591c17a00Smckusick append(getfile, addr2);
33691c17a00Smckusick exfile();
33791c17a00Smckusick fchange = c;
33891c17a00Smckusick continue;
33991c17a00Smckusick
34091c17a00Smckusick case 's':
34191c17a00Smckusick setdot();
34291c17a00Smckusick nonzero();
34391c17a00Smckusick substitute(globp!=0);
34491c17a00Smckusick continue;
34591c17a00Smckusick
34691c17a00Smckusick case 't':
34791c17a00Smckusick move(1);
34891c17a00Smckusick continue;
34991c17a00Smckusick
35091c17a00Smckusick case 'u':
35191c17a00Smckusick setdot();
35291c17a00Smckusick nonzero();
35391c17a00Smckusick newline();
35491c17a00Smckusick if ((*addr2&~01) != subnewa)
35591c17a00Smckusick error(Q);
35691c17a00Smckusick *addr2 = subolda;
35791c17a00Smckusick dot = addr2;
35891c17a00Smckusick continue;
35991c17a00Smckusick
36091c17a00Smckusick case 'v':
36191c17a00Smckusick global(0);
36291c17a00Smckusick continue;
36391c17a00Smckusick
36491c17a00Smckusick case 'W':
36591c17a00Smckusick wrapp++;
36691c17a00Smckusick case 'w':
36791c17a00Smckusick setall();
36891c17a00Smckusick nonzero();
36991c17a00Smckusick filename(c);
37091c17a00Smckusick if(!wrapp ||
37191c17a00Smckusick ((io = open(file,1)) == -1) ||
37291c17a00Smckusick ((lseek(io, 0L, 2)) == -1))
37391c17a00Smckusick if ((io = creat(file, 0666)) < 0)
37491c17a00Smckusick error(file);
37591c17a00Smckusick wrapp = 0;
37691c17a00Smckusick putfile();
37791c17a00Smckusick exfile();
37891c17a00Smckusick if (addr1==zero+1 && addr2==dol)
37991c17a00Smckusick fchange = 0;
38091c17a00Smckusick continue;
38191c17a00Smckusick
382*ee3b4668Sbostic #ifdef CRYPT
383*ee3b4668Sbostic case 'x':
384*ee3b4668Sbostic setnoaddr();
385*ee3b4668Sbostic newline();
386*ee3b4668Sbostic xflag = 1;
387*ee3b4668Sbostic puts("Entering encrypting mode!");
388*ee3b4668Sbostic getkey();
389*ee3b4668Sbostic kflag = crinit(key, perm);
390*ee3b4668Sbostic continue;
391*ee3b4668Sbostic #endif CRYPT
39291c17a00Smckusick
39391c17a00Smckusick
39491c17a00Smckusick case '=':
39591c17a00Smckusick setall();
39691c17a00Smckusick newline();
39791c17a00Smckusick count = (addr2-zero)&077777;
39891c17a00Smckusick putd();
39991c17a00Smckusick putchr('\n');
40091c17a00Smckusick continue;
40191c17a00Smckusick
40291c17a00Smckusick case '!':
40391c17a00Smckusick callunix();
40491c17a00Smckusick continue;
40591c17a00Smckusick
40691c17a00Smckusick case EOF:
40791c17a00Smckusick return;
40891c17a00Smckusick
40991c17a00Smckusick }
41091c17a00Smckusick error(Q);
41191c17a00Smckusick }
41291c17a00Smckusick }
41391c17a00Smckusick
41491c17a00Smckusick int *
address()41591c17a00Smckusick address()
41691c17a00Smckusick {
41791c17a00Smckusick register *a1, minus, c;
41891c17a00Smckusick int n, relerr;
41991c17a00Smckusick
42091c17a00Smckusick minus = 0;
42191c17a00Smckusick a1 = 0;
42291c17a00Smckusick for (;;) {
42391c17a00Smckusick c = getchr();
42491c17a00Smckusick if ('0'<=c && c<='9') {
42591c17a00Smckusick n = 0;
42691c17a00Smckusick do {
42791c17a00Smckusick n *= 10;
42891c17a00Smckusick n += c - '0';
42991c17a00Smckusick } while ((c = getchr())>='0' && c<='9');
43091c17a00Smckusick peekc = c;
43191c17a00Smckusick if (a1==0)
43291c17a00Smckusick a1 = zero;
43391c17a00Smckusick if (minus<0)
43491c17a00Smckusick n = -n;
43591c17a00Smckusick a1 += n;
43691c17a00Smckusick minus = 0;
43791c17a00Smckusick continue;
43891c17a00Smckusick }
43991c17a00Smckusick relerr = 0;
44091c17a00Smckusick if (a1 || minus)
44191c17a00Smckusick relerr++;
44291c17a00Smckusick switch(c) {
44391c17a00Smckusick case ' ':
44491c17a00Smckusick case '\t':
44591c17a00Smckusick continue;
44691c17a00Smckusick
44791c17a00Smckusick case '+':
44891c17a00Smckusick minus++;
44991c17a00Smckusick if (a1==0)
45091c17a00Smckusick a1 = dot;
45191c17a00Smckusick continue;
45291c17a00Smckusick
45391c17a00Smckusick case '-':
45491c17a00Smckusick case '^':
45591c17a00Smckusick minus--;
45691c17a00Smckusick if (a1==0)
45791c17a00Smckusick a1 = dot;
45891c17a00Smckusick continue;
45991c17a00Smckusick
46091c17a00Smckusick case '?':
46191c17a00Smckusick case '/':
46291c17a00Smckusick compile(c);
46391c17a00Smckusick a1 = dot;
46491c17a00Smckusick for (;;) {
46591c17a00Smckusick if (c=='/') {
46691c17a00Smckusick a1++;
46791c17a00Smckusick if (a1 > dol)
46891c17a00Smckusick a1 = zero;
46991c17a00Smckusick } else {
47091c17a00Smckusick a1--;
47191c17a00Smckusick if (a1 < zero)
47291c17a00Smckusick a1 = dol;
47391c17a00Smckusick }
47491c17a00Smckusick if (execute(0, a1))
47591c17a00Smckusick break;
47691c17a00Smckusick if (a1==dot)
47791c17a00Smckusick error(Q);
47891c17a00Smckusick }
47991c17a00Smckusick break;
48091c17a00Smckusick
48191c17a00Smckusick case '$':
48291c17a00Smckusick a1 = dol;
48391c17a00Smckusick break;
48491c17a00Smckusick
48591c17a00Smckusick case '.':
48691c17a00Smckusick a1 = dot;
48791c17a00Smckusick break;
48891c17a00Smckusick
48991c17a00Smckusick case '\'':
49091c17a00Smckusick if ((c = getchr()) < 'a' || c > 'z')
49191c17a00Smckusick error(Q);
49291c17a00Smckusick for (a1=zero; a1<=dol; a1++)
49391c17a00Smckusick if (names[c-'a'] == (*a1 & ~01))
49491c17a00Smckusick break;
49591c17a00Smckusick break;
49691c17a00Smckusick
49791c17a00Smckusick default:
49891c17a00Smckusick peekc = c;
49991c17a00Smckusick if (a1==0)
50091c17a00Smckusick return(0);
50191c17a00Smckusick a1 += minus;
50291c17a00Smckusick if (a1<zero || a1>dol)
50391c17a00Smckusick error(Q);
50491c17a00Smckusick return(a1);
50591c17a00Smckusick }
50691c17a00Smckusick if (relerr)
50791c17a00Smckusick error(Q);
50891c17a00Smckusick }
50991c17a00Smckusick }
51091c17a00Smckusick
setdot()51191c17a00Smckusick setdot()
51291c17a00Smckusick {
51391c17a00Smckusick if (addr2 == 0)
51491c17a00Smckusick addr1 = addr2 = dot;
51591c17a00Smckusick if (addr1 > addr2)
51691c17a00Smckusick error(Q);
51791c17a00Smckusick }
51891c17a00Smckusick
setall()51991c17a00Smckusick setall()
52091c17a00Smckusick {
52191c17a00Smckusick if (addr2==0) {
52291c17a00Smckusick addr1 = zero+1;
52391c17a00Smckusick addr2 = dol;
52491c17a00Smckusick if (dol==zero)
52591c17a00Smckusick addr1 = zero;
52691c17a00Smckusick }
52791c17a00Smckusick setdot();
52891c17a00Smckusick }
52991c17a00Smckusick
setnoaddr()53091c17a00Smckusick setnoaddr()
53191c17a00Smckusick {
53291c17a00Smckusick if (addr2)
53391c17a00Smckusick error(Q);
53491c17a00Smckusick }
53591c17a00Smckusick
nonzero()53691c17a00Smckusick nonzero()
53791c17a00Smckusick {
53891c17a00Smckusick if (addr1<=zero || addr2>dol)
53991c17a00Smckusick error(Q);
54091c17a00Smckusick }
54191c17a00Smckusick
newline()54291c17a00Smckusick newline()
54391c17a00Smckusick {
54491c17a00Smckusick register c;
54591c17a00Smckusick
54691c17a00Smckusick if ((c = getchr()) == '\n')
54791c17a00Smckusick return;
54891c17a00Smckusick if (c=='p' || c=='l') {
54991c17a00Smckusick pflag++;
55091c17a00Smckusick if (c=='l')
55191c17a00Smckusick listf++;
55291c17a00Smckusick if (getchr() == '\n')
55391c17a00Smckusick return;
55491c17a00Smckusick }
55591c17a00Smckusick error(Q);
55691c17a00Smckusick }
55791c17a00Smckusick
filename(comm)55891c17a00Smckusick filename(comm)
55991c17a00Smckusick {
56091c17a00Smckusick register char *p1, *p2;
56191c17a00Smckusick register c;
56291c17a00Smckusick
56391c17a00Smckusick count = 0;
56491c17a00Smckusick c = getchr();
56591c17a00Smckusick if (c=='\n' || c==EOF) {
56691c17a00Smckusick p1 = savedfile;
56791c17a00Smckusick if (*p1==0 && comm!='f')
56891c17a00Smckusick error(Q);
56991c17a00Smckusick p2 = file;
57091c17a00Smckusick while (*p2++ = *p1++)
57191c17a00Smckusick ;
57291c17a00Smckusick return;
57391c17a00Smckusick }
57491c17a00Smckusick if (c!=' ')
57591c17a00Smckusick error(Q);
57691c17a00Smckusick while ((c = getchr()) == ' ')
57791c17a00Smckusick ;
57891c17a00Smckusick if (c=='\n')
57991c17a00Smckusick error(Q);
58091c17a00Smckusick p1 = file;
58191c17a00Smckusick do {
58291c17a00Smckusick *p1++ = c;
58391c17a00Smckusick if (c==' ' || c==EOF)
58491c17a00Smckusick error(Q);
58591c17a00Smckusick } while ((c = getchr()) != '\n');
58691c17a00Smckusick *p1++ = 0;
58791c17a00Smckusick if (savedfile[0]==0 || comm=='e' || comm=='f') {
58891c17a00Smckusick p1 = savedfile;
58991c17a00Smckusick p2 = file;
59091c17a00Smckusick while (*p1++ = *p2++)
59191c17a00Smckusick ;
59291c17a00Smckusick }
59391c17a00Smckusick }
59491c17a00Smckusick
exfile()59591c17a00Smckusick exfile()
59691c17a00Smckusick {
59791c17a00Smckusick close(io);
59891c17a00Smckusick io = -1;
59991c17a00Smckusick if (vflag) {
60091c17a00Smckusick putd();
60191c17a00Smckusick putchr('\n');
60291c17a00Smckusick }
60391c17a00Smckusick }
60491c17a00Smckusick
605522670b9Sbostic void
onintr()60691c17a00Smckusick onintr()
60791c17a00Smckusick {
608522670b9Sbostic /* not necessary: (void)signal(SIGINT, onintr); */
60991c17a00Smckusick putchr('\n');
61091c17a00Smckusick lastc = '\n';
61191c17a00Smckusick error(Q);
61291c17a00Smckusick }
61391c17a00Smckusick
614522670b9Sbostic void
onhup()61591c17a00Smckusick onhup()
61691c17a00Smckusick {
617522670b9Sbostic /* not necessary: (void)signal(SIGINT, SIG_IGN); */
618522670b9Sbostic /* not necessary: (void)signal(SIGHUP, SIG_IGN); */
61991c17a00Smckusick if (dol > zero) {
62091c17a00Smckusick addr1 = zero+1;
62191c17a00Smckusick addr2 = dol;
62291c17a00Smckusick io = creat("ed.hup", 0666);
62391c17a00Smckusick if (io > 0)
62491c17a00Smckusick putfile();
62591c17a00Smckusick }
62691c17a00Smckusick fchange = 0;
62791c17a00Smckusick quit();
62891c17a00Smckusick }
62991c17a00Smckusick
error(s)63091c17a00Smckusick error(s)
63191c17a00Smckusick char *s;
63291c17a00Smckusick {
63391c17a00Smckusick register c;
63491c17a00Smckusick
63591c17a00Smckusick wrapp = 0;
63691c17a00Smckusick listf = 0;
63791c17a00Smckusick putchr('?');
63891c17a00Smckusick puts(s);
63991c17a00Smckusick count = 0;
64091c17a00Smckusick lseek(0, (long)0, 2);
64191c17a00Smckusick pflag = 0;
64291c17a00Smckusick if (globp)
64391c17a00Smckusick lastc = '\n';
64491c17a00Smckusick globp = 0;
64591c17a00Smckusick peekc = lastc;
64691c17a00Smckusick if(lastc)
64791c17a00Smckusick while ((c = getchr()) != '\n' && c != EOF)
64891c17a00Smckusick ;
64991c17a00Smckusick if (io > 0) {
65091c17a00Smckusick close(io);
65191c17a00Smckusick io = -1;
65291c17a00Smckusick }
65391c17a00Smckusick longjmp(savej, 1);
65491c17a00Smckusick }
65591c17a00Smckusick
getchr()65691c17a00Smckusick getchr()
65791c17a00Smckusick {
65891c17a00Smckusick char c;
65991c17a00Smckusick if (lastc=peekc) {
66091c17a00Smckusick peekc = 0;
66191c17a00Smckusick return(lastc);
66291c17a00Smckusick }
66391c17a00Smckusick if (globp) {
66491c17a00Smckusick if ((lastc = *globp++) != 0)
66591c17a00Smckusick return(lastc);
66691c17a00Smckusick globp = 0;
66791c17a00Smckusick return(EOF);
66891c17a00Smckusick }
66991c17a00Smckusick if (read(0, &c, 1) <= 0)
67091c17a00Smckusick return(lastc = EOF);
67191c17a00Smckusick lastc = c&0177;
67291c17a00Smckusick return(lastc);
67391c17a00Smckusick }
67491c17a00Smckusick
gettty()67591c17a00Smckusick gettty()
67691c17a00Smckusick {
67791c17a00Smckusick register c;
67891c17a00Smckusick register char *gf;
67991c17a00Smckusick register char *p;
68091c17a00Smckusick
68191c17a00Smckusick p = linebuf;
68291c17a00Smckusick gf = globp;
68391c17a00Smckusick while ((c = getchr()) != '\n') {
68491c17a00Smckusick if (c==EOF) {
68591c17a00Smckusick if (gf)
68691c17a00Smckusick peekc = c;
68791c17a00Smckusick return(c);
68891c17a00Smckusick }
68991c17a00Smckusick if ((c &= 0177) == 0)
69091c17a00Smckusick continue;
69191c17a00Smckusick *p++ = c;
69291c17a00Smckusick if (p >= &linebuf[LBSIZE-2])
69391c17a00Smckusick error(Q);
69491c17a00Smckusick }
69591c17a00Smckusick *p++ = 0;
69691c17a00Smckusick if (linebuf[0]=='.' && linebuf[1]==0)
69791c17a00Smckusick return(EOF);
69891c17a00Smckusick return(0);
69991c17a00Smckusick }
70091c17a00Smckusick
getfile()70191c17a00Smckusick getfile()
70291c17a00Smckusick {
70391c17a00Smckusick register c;
70491c17a00Smckusick register char *lp, *fp;
70591c17a00Smckusick
70691c17a00Smckusick lp = linebuf;
70791c17a00Smckusick fp = nextip;
70891c17a00Smckusick do {
70991c17a00Smckusick if (--ninbuf < 0) {
71091c17a00Smckusick if ((ninbuf = read(io, genbuf, LBSIZE)-1) < 0)
71191c17a00Smckusick return(EOF);
71291c17a00Smckusick fp = genbuf;
71391c17a00Smckusick while(fp < &genbuf[ninbuf]) {
71491c17a00Smckusick if (*fp++ & 0200) {
715*ee3b4668Sbostic #ifdef CRYPT
716*ee3b4668Sbostic if (kflag)
717*ee3b4668Sbostic crblock(perm, genbuf, ninbuf+1, count);
718*ee3b4668Sbostic #endif CRYPT
71991c17a00Smckusick break;
72091c17a00Smckusick }
72191c17a00Smckusick }
72291c17a00Smckusick fp = genbuf;
72391c17a00Smckusick }
72491c17a00Smckusick c = *fp++;
72591c17a00Smckusick if (c=='\0')
72691c17a00Smckusick continue;
72791c17a00Smckusick if (c&0200 || lp >= &linebuf[LBSIZE]) {
72891c17a00Smckusick lastc = '\n';
72991c17a00Smckusick error(Q);
73091c17a00Smckusick }
73191c17a00Smckusick *lp++ = c;
73291c17a00Smckusick count++;
73391c17a00Smckusick } while (c != '\n');
73491c17a00Smckusick *--lp = 0;
73591c17a00Smckusick nextip = fp;
73691c17a00Smckusick return(0);
73791c17a00Smckusick }
73891c17a00Smckusick
putfile()73991c17a00Smckusick putfile()
74091c17a00Smckusick {
74191c17a00Smckusick int *a1, n;
74291c17a00Smckusick register char *fp, *lp;
74391c17a00Smckusick register nib;
74491c17a00Smckusick
74591c17a00Smckusick nib = 512;
74691c17a00Smckusick fp = genbuf;
74791c17a00Smckusick a1 = addr1;
74891c17a00Smckusick do {
74991c17a00Smckusick lp = getline(*a1++);
75091c17a00Smckusick for (;;) {
75191c17a00Smckusick if (--nib < 0) {
75291c17a00Smckusick n = fp-genbuf;
753*ee3b4668Sbostic #ifdef CRYPT
754*ee3b4668Sbostic if(kflag)
755*ee3b4668Sbostic crblock(perm, genbuf, n, count-n);
756*ee3b4668Sbostic #endif CRYPT
75791c17a00Smckusick if(write(io, genbuf, n) != n) {
75891c17a00Smckusick puts(WRERR);
75991c17a00Smckusick error(Q);
76091c17a00Smckusick }
76191c17a00Smckusick nib = 511;
76291c17a00Smckusick fp = genbuf;
76391c17a00Smckusick }
76491c17a00Smckusick count++;
76591c17a00Smckusick if ((*fp++ = *lp++) == 0) {
76691c17a00Smckusick fp[-1] = '\n';
76791c17a00Smckusick break;
76891c17a00Smckusick }
76991c17a00Smckusick }
77091c17a00Smckusick } while (a1 <= addr2);
77191c17a00Smckusick n = fp-genbuf;
772*ee3b4668Sbostic #ifdef CRYPT
773*ee3b4668Sbostic if(kflag)
774*ee3b4668Sbostic crblock(perm, genbuf, n, count-n);
775*ee3b4668Sbostic #endif CRYPT
77691c17a00Smckusick if(write(io, genbuf, n) != n) {
77791c17a00Smckusick puts(WRERR);
77891c17a00Smckusick error(Q);
77991c17a00Smckusick }
78091c17a00Smckusick }
78191c17a00Smckusick
append(f,a)78291c17a00Smckusick append(f, a)
78391c17a00Smckusick int *a;
78491c17a00Smckusick int (*f)();
78591c17a00Smckusick {
78691c17a00Smckusick register *a1, *a2, *rdot;
78791c17a00Smckusick int nline, tl;
78891c17a00Smckusick
78991c17a00Smckusick nline = 0;
79091c17a00Smckusick dot = a;
79191c17a00Smckusick while ((*f)() == 0) {
79291c17a00Smckusick if ((dol-zero)+1 >= nlall) {
79391c17a00Smckusick int *ozero = zero;
79491c17a00Smckusick nlall += 512;
79591c17a00Smckusick if ((zero = (int *)realloc((char *)zero, nlall*sizeof(int)))==NULL) {
79691c17a00Smckusick lastc = '\n';
79791c17a00Smckusick zero = ozero;
79891c17a00Smckusick error("MEM?");
79991c17a00Smckusick }
80091c17a00Smckusick dot += zero - ozero;
80191c17a00Smckusick dol += zero - ozero;
80291c17a00Smckusick }
80391c17a00Smckusick tl = putline();
80491c17a00Smckusick nline++;
80591c17a00Smckusick a1 = ++dol;
80691c17a00Smckusick a2 = a1+1;
80791c17a00Smckusick rdot = ++dot;
80891c17a00Smckusick while (a1 > rdot)
80991c17a00Smckusick *--a2 = *--a1;
81091c17a00Smckusick *rdot = tl;
81191c17a00Smckusick }
81291c17a00Smckusick return(nline);
81391c17a00Smckusick }
81491c17a00Smckusick
callunix()81591c17a00Smckusick callunix()
81691c17a00Smckusick {
817522670b9Sbostic register sig_t savint;
818522670b9Sbostic register int pid, rpid;
81991c17a00Smckusick int retcode;
82091c17a00Smckusick
82191c17a00Smckusick setnoaddr();
82291c17a00Smckusick if ((pid = fork()) == 0) {
82391c17a00Smckusick signal(SIGHUP, oldhup);
82491c17a00Smckusick signal(SIGQUIT, oldquit);
82573bab485Sbostic execl(_PATH_BSHELL, "sh", "-t", 0);
82691c17a00Smckusick exit(0100);
82791c17a00Smckusick }
82891c17a00Smckusick savint = signal(SIGINT, SIG_IGN);
82991c17a00Smckusick while ((rpid = wait(&retcode)) != pid && rpid != -1)
83091c17a00Smckusick ;
83191c17a00Smckusick signal(SIGINT, savint);
83291c17a00Smckusick puts("!");
83391c17a00Smckusick }
83491c17a00Smckusick
835522670b9Sbostic void
quit()83691c17a00Smckusick quit()
83791c17a00Smckusick {
83891c17a00Smckusick if (vflag && fchange && dol!=zero) {
83991c17a00Smckusick fchange = 0;
84091c17a00Smckusick error(Q);
84191c17a00Smckusick }
84291c17a00Smckusick unlink(tfname);
84391c17a00Smckusick exit(0);
84491c17a00Smckusick }
84591c17a00Smckusick
delete()84691c17a00Smckusick delete()
84791c17a00Smckusick {
84891c17a00Smckusick setdot();
84991c17a00Smckusick newline();
85091c17a00Smckusick nonzero();
85191c17a00Smckusick rdelete(addr1, addr2);
85291c17a00Smckusick }
85391c17a00Smckusick
rdelete(ad1,ad2)85491c17a00Smckusick rdelete(ad1, ad2)
85591c17a00Smckusick int *ad1, *ad2;
85691c17a00Smckusick {
85791c17a00Smckusick register *a1, *a2, *a3;
85891c17a00Smckusick
85991c17a00Smckusick a1 = ad1;
86091c17a00Smckusick a2 = ad2+1;
86191c17a00Smckusick a3 = dol;
86291c17a00Smckusick dol -= a2 - a1;
86391c17a00Smckusick do {
86491c17a00Smckusick *a1++ = *a2++;
86591c17a00Smckusick } while (a2 <= a3);
86691c17a00Smckusick a1 = ad1;
86791c17a00Smckusick if (a1 > dol)
86891c17a00Smckusick a1 = dol;
86991c17a00Smckusick dot = a1;
87091c17a00Smckusick fchange = 1;
87191c17a00Smckusick }
87291c17a00Smckusick
gdelete()87391c17a00Smckusick gdelete()
87491c17a00Smckusick {
87591c17a00Smckusick register *a1, *a2, *a3;
87691c17a00Smckusick
87791c17a00Smckusick a3 = dol;
87891c17a00Smckusick for (a1=zero+1; (*a1&01)==0; a1++)
87991c17a00Smckusick if (a1>=a3)
88091c17a00Smckusick return;
88191c17a00Smckusick for (a2=a1+1; a2<=a3;) {
88291c17a00Smckusick if (*a2&01) {
88391c17a00Smckusick a2++;
88491c17a00Smckusick dot = a1;
88591c17a00Smckusick } else
88691c17a00Smckusick *a1++ = *a2++;
88791c17a00Smckusick }
88891c17a00Smckusick dol = a1-1;
88991c17a00Smckusick if (dot>dol)
89091c17a00Smckusick dot = dol;
89191c17a00Smckusick fchange = 1;
89291c17a00Smckusick }
89391c17a00Smckusick
89491c17a00Smckusick char *
getline(tl)89591c17a00Smckusick getline(tl)
89691c17a00Smckusick {
89791c17a00Smckusick register char *bp, *lp;
89891c17a00Smckusick register nl;
89991c17a00Smckusick
90091c17a00Smckusick lp = linebuf;
90191c17a00Smckusick bp = getblock(tl, READ);
90291c17a00Smckusick nl = nleft;
90391c17a00Smckusick tl &= ~0377;
90491c17a00Smckusick while (*lp++ = *bp++)
90591c17a00Smckusick if (--nl == 0) {
90691c17a00Smckusick bp = getblock(tl+=0400, READ);
90791c17a00Smckusick nl = nleft;
90891c17a00Smckusick }
90991c17a00Smckusick return(linebuf);
91091c17a00Smckusick }
91191c17a00Smckusick
putline()91291c17a00Smckusick putline()
91391c17a00Smckusick {
91491c17a00Smckusick register char *bp, *lp;
91591c17a00Smckusick register nl;
91691c17a00Smckusick int tl;
91791c17a00Smckusick
91891c17a00Smckusick fchange = 1;
91991c17a00Smckusick lp = linebuf;
92091c17a00Smckusick tl = tline;
92191c17a00Smckusick bp = getblock(tl, WRITE);
92291c17a00Smckusick nl = nleft;
92391c17a00Smckusick tl &= ~0377;
92491c17a00Smckusick while (*bp = *lp++) {
92591c17a00Smckusick if (*bp++ == '\n') {
92691c17a00Smckusick *--bp = 0;
92791c17a00Smckusick linebp = lp;
92891c17a00Smckusick break;
92991c17a00Smckusick }
93091c17a00Smckusick if (--nl == 0) {
93191c17a00Smckusick bp = getblock(tl+=0400, WRITE);
93291c17a00Smckusick nl = nleft;
93391c17a00Smckusick }
93491c17a00Smckusick }
93591c17a00Smckusick nl = tline;
93691c17a00Smckusick tline += (((lp-linebuf)+03)>>1)&077776;
93791c17a00Smckusick return(nl);
93891c17a00Smckusick }
93991c17a00Smckusick
94091c17a00Smckusick char *
getblock(atl,iof)94191c17a00Smckusick getblock(atl, iof)
94291c17a00Smckusick {
94391c17a00Smckusick extern read(), write();
94491c17a00Smckusick register bno, off;
94591c17a00Smckusick register char *p1, *p2;
94691c17a00Smckusick register int n;
94791c17a00Smckusick
94891c17a00Smckusick bno = (atl>>8)&0377;
94991c17a00Smckusick off = (atl<<1)&0774;
95091c17a00Smckusick if (bno >= 255) {
95191c17a00Smckusick lastc = '\n';
95291c17a00Smckusick error(T);
95391c17a00Smckusick }
95491c17a00Smckusick nleft = 512 - off;
95591c17a00Smckusick if (bno==iblock) {
95691c17a00Smckusick ichanged |= iof;
95791c17a00Smckusick return(ibuff+off);
95891c17a00Smckusick }
95991c17a00Smckusick if (bno==oblock)
96091c17a00Smckusick return(obuff+off);
96191c17a00Smckusick if (iof==READ) {
96291c17a00Smckusick if (ichanged) {
963*ee3b4668Sbostic #ifdef CRYPT
964*ee3b4668Sbostic if(xtflag)
965*ee3b4668Sbostic crblock(tperm, ibuff, 512, (long)0);
966*ee3b4668Sbostic #endif CRYPT
96791c17a00Smckusick blkio(iblock, ibuff, write);
96891c17a00Smckusick }
96991c17a00Smckusick ichanged = 0;
97091c17a00Smckusick iblock = bno;
97191c17a00Smckusick blkio(bno, ibuff, read);
972*ee3b4668Sbostic #ifdef CRYPT
973*ee3b4668Sbostic if(xtflag)
974*ee3b4668Sbostic crblock(tperm, ibuff, 512, (long)0);
975*ee3b4668Sbostic #endif CRYPT
97691c17a00Smckusick return(ibuff+off);
97791c17a00Smckusick }
97891c17a00Smckusick if (oblock>=0) {
979*ee3b4668Sbostic #ifdef CRYPT
980*ee3b4668Sbostic if(xtflag) {
981*ee3b4668Sbostic p1 = obuff;
982*ee3b4668Sbostic p2 = crbuf;
983*ee3b4668Sbostic n = 512;
984*ee3b4668Sbostic while(n--)
985*ee3b4668Sbostic *p2++ = *p1++;
986*ee3b4668Sbostic crblock(tperm, crbuf, 512, (long)0);
987*ee3b4668Sbostic blkio(oblock, crbuf, write);
988*ee3b4668Sbostic } else
989*ee3b4668Sbostic #endif CRYPT
99091c17a00Smckusick blkio(oblock, obuff, write);
99191c17a00Smckusick }
99291c17a00Smckusick oblock = bno;
99391c17a00Smckusick return(obuff+off);
99491c17a00Smckusick }
99591c17a00Smckusick
blkio(b,buf,iofcn)99691c17a00Smckusick blkio(b, buf, iofcn)
99791c17a00Smckusick char *buf;
99891c17a00Smckusick int (*iofcn)();
99991c17a00Smckusick {
100091c17a00Smckusick lseek(tfile, (long)b<<9, 0);
100191c17a00Smckusick if ((*iofcn)(tfile, buf, 512) != 512) {
100291c17a00Smckusick error(T);
100391c17a00Smckusick }
100491c17a00Smckusick }
100591c17a00Smckusick
init()100691c17a00Smckusick init()
100791c17a00Smckusick {
100891c17a00Smckusick register *markp;
100991c17a00Smckusick
101091c17a00Smckusick close(tfile);
101191c17a00Smckusick tline = 2;
101291c17a00Smckusick for (markp = names; markp < &names[26]; )
101391c17a00Smckusick *markp++ = 0;
101491c17a00Smckusick subnewa = 0;
101591c17a00Smckusick anymarks = 0;
101691c17a00Smckusick iblock = -1;
101791c17a00Smckusick oblock = -1;
101891c17a00Smckusick ichanged = 0;
101991c17a00Smckusick close(creat(tfname, 0600));
102091c17a00Smckusick tfile = open(tfname, 2);
1021*ee3b4668Sbostic #ifdef CRYPT
1022*ee3b4668Sbostic if(xflag) {
1023*ee3b4668Sbostic xtflag = 1;
1024*ee3b4668Sbostic makekey(key, tperm);
1025*ee3b4668Sbostic }
1026*ee3b4668Sbostic #endif CRYPT
102791c17a00Smckusick dot = dol = zero;
102891c17a00Smckusick }
102991c17a00Smckusick
global(k)103091c17a00Smckusick global(k)
103191c17a00Smckusick {
103291c17a00Smckusick register char *gp;
103391c17a00Smckusick register c;
103491c17a00Smckusick register int *a1;
103591c17a00Smckusick char globuf[GBSIZE];
103691c17a00Smckusick
103791c17a00Smckusick if (globp)
103891c17a00Smckusick error(Q);
103991c17a00Smckusick setall();
104091c17a00Smckusick nonzero();
104191c17a00Smckusick if ((c=getchr())=='\n')
104291c17a00Smckusick error(Q);
104391c17a00Smckusick compile(c);
104491c17a00Smckusick gp = globuf;
104591c17a00Smckusick while ((c = getchr()) != '\n') {
104691c17a00Smckusick if (c==EOF)
104791c17a00Smckusick error(Q);
104891c17a00Smckusick if (c=='\\') {
104991c17a00Smckusick c = getchr();
105091c17a00Smckusick if (c!='\n')
105191c17a00Smckusick *gp++ = '\\';
105291c17a00Smckusick }
105391c17a00Smckusick *gp++ = c;
105491c17a00Smckusick if (gp >= &globuf[GBSIZE-2])
105591c17a00Smckusick error(Q);
105691c17a00Smckusick }
105791c17a00Smckusick *gp++ = '\n';
105891c17a00Smckusick *gp++ = 0;
105991c17a00Smckusick for (a1=zero; a1<=dol; a1++) {
106091c17a00Smckusick *a1 &= ~01;
106191c17a00Smckusick if (a1>=addr1 && a1<=addr2 && execute(0, a1)==k)
106291c17a00Smckusick *a1 |= 01;
106391c17a00Smckusick }
106491c17a00Smckusick /*
106591c17a00Smckusick * Special case: g/.../d (avoid n^2 algorithm)
106691c17a00Smckusick */
106791c17a00Smckusick if (globuf[0]=='d' && globuf[1]=='\n' && globuf[2]=='\0') {
106891c17a00Smckusick gdelete();
106991c17a00Smckusick return;
107091c17a00Smckusick }
107191c17a00Smckusick for (a1=zero; a1<=dol; a1++) {
107291c17a00Smckusick if (*a1 & 01) {
107391c17a00Smckusick *a1 &= ~01;
107491c17a00Smckusick dot = a1;
107591c17a00Smckusick globp = globuf;
107691c17a00Smckusick commands();
107791c17a00Smckusick a1 = zero;
107891c17a00Smckusick }
107991c17a00Smckusick }
108091c17a00Smckusick }
108191c17a00Smckusick
join()108291c17a00Smckusick join()
108391c17a00Smckusick {
108491c17a00Smckusick register char *gp, *lp;
108591c17a00Smckusick register *a1;
108691c17a00Smckusick
108791c17a00Smckusick gp = genbuf;
108891c17a00Smckusick for (a1=addr1; a1<=addr2; a1++) {
108991c17a00Smckusick lp = getline(*a1);
109091c17a00Smckusick while (*gp = *lp++)
109191c17a00Smckusick if (gp++ >= &genbuf[LBSIZE-2])
109291c17a00Smckusick error(Q);
109391c17a00Smckusick }
109491c17a00Smckusick lp = linebuf;
109591c17a00Smckusick gp = genbuf;
109691c17a00Smckusick while (*lp++ = *gp++)
109791c17a00Smckusick ;
109891c17a00Smckusick *addr1 = putline();
109991c17a00Smckusick if (addr1<addr2)
110091c17a00Smckusick rdelete(addr1+1, addr2);
110191c17a00Smckusick dot = addr1;
110291c17a00Smckusick }
110391c17a00Smckusick
substitute(inglob)110491c17a00Smckusick substitute(inglob)
110591c17a00Smckusick {
110691c17a00Smckusick register *markp, *a1, nl;
110791c17a00Smckusick int gsubf;
110891c17a00Smckusick int getsub();
110991c17a00Smckusick
111091c17a00Smckusick gsubf = compsub();
111191c17a00Smckusick for (a1 = addr1; a1 <= addr2; a1++) {
111291c17a00Smckusick int *ozero;
111391c17a00Smckusick if (execute(0, a1)==0)
111491c17a00Smckusick continue;
111591c17a00Smckusick inglob |= 01;
111691c17a00Smckusick dosub();
111791c17a00Smckusick if (gsubf) {
111891c17a00Smckusick while (*loc2) {
111991c17a00Smckusick if (execute(1, (int *)0)==0)
112091c17a00Smckusick break;
112191c17a00Smckusick dosub();
112291c17a00Smckusick }
112391c17a00Smckusick }
112491c17a00Smckusick subnewa = putline();
112591c17a00Smckusick *a1 &= ~01;
112691c17a00Smckusick if (anymarks) {
112791c17a00Smckusick for (markp = names; markp < &names[26]; markp++)
112891c17a00Smckusick if (*markp == *a1)
112991c17a00Smckusick *markp = subnewa;
113091c17a00Smckusick }
113191c17a00Smckusick subolda = *a1;
113291c17a00Smckusick *a1 = subnewa;
113391c17a00Smckusick ozero = zero;
113491c17a00Smckusick nl = append(getsub, a1);
113591c17a00Smckusick nl += zero-ozero;
113691c17a00Smckusick a1 += nl;
113791c17a00Smckusick addr2 += nl;
113891c17a00Smckusick }
113991c17a00Smckusick if (inglob==0)
114091c17a00Smckusick error(Q);
114191c17a00Smckusick }
114291c17a00Smckusick
compsub()114391c17a00Smckusick compsub()
114491c17a00Smckusick {
114591c17a00Smckusick register seof, c;
114691c17a00Smckusick register char *p;
114791c17a00Smckusick
114891c17a00Smckusick if ((seof = getchr()) == '\n' || seof == ' ')
114991c17a00Smckusick error(Q);
115091c17a00Smckusick compile(seof);
115191c17a00Smckusick p = rhsbuf;
115291c17a00Smckusick for (;;) {
115391c17a00Smckusick c = getchr();
115491c17a00Smckusick if (c=='\\')
115591c17a00Smckusick c = getchr() | 0200;
115691c17a00Smckusick if (c=='\n') {
115791c17a00Smckusick if (globp)
115891c17a00Smckusick c |= 0200;
115991c17a00Smckusick else
116091c17a00Smckusick error(Q);
116191c17a00Smckusick }
116291c17a00Smckusick if (c==seof)
116391c17a00Smckusick break;
116491c17a00Smckusick *p++ = c;
116591c17a00Smckusick if (p >= &rhsbuf[LBSIZE/2])
116691c17a00Smckusick error(Q);
116791c17a00Smckusick }
116891c17a00Smckusick *p++ = 0;
116991c17a00Smckusick if ((peekc = getchr()) == 'g') {
117091c17a00Smckusick peekc = 0;
117191c17a00Smckusick newline();
117291c17a00Smckusick return(1);
117391c17a00Smckusick }
117491c17a00Smckusick newline();
117591c17a00Smckusick return(0);
117691c17a00Smckusick }
117791c17a00Smckusick
getsub()117891c17a00Smckusick getsub()
117991c17a00Smckusick {
118091c17a00Smckusick register char *p1, *p2;
118191c17a00Smckusick
118291c17a00Smckusick p1 = linebuf;
118391c17a00Smckusick if ((p2 = linebp) == 0)
118491c17a00Smckusick return(EOF);
118591c17a00Smckusick while (*p1++ = *p2++)
118691c17a00Smckusick ;
118791c17a00Smckusick linebp = 0;
118891c17a00Smckusick return(0);
118991c17a00Smckusick }
119091c17a00Smckusick
dosub()119191c17a00Smckusick dosub()
119291c17a00Smckusick {
119391c17a00Smckusick register char *lp, *sp, *rp;
119491c17a00Smckusick int c;
119591c17a00Smckusick
119691c17a00Smckusick lp = linebuf;
119791c17a00Smckusick sp = genbuf;
119891c17a00Smckusick rp = rhsbuf;
119991c17a00Smckusick while (lp < loc1)
120091c17a00Smckusick *sp++ = *lp++;
120191c17a00Smckusick while (c = *rp++&0377) {
120291c17a00Smckusick if (c=='&') {
120391c17a00Smckusick sp = place(sp, loc1, loc2);
120491c17a00Smckusick continue;
120591c17a00Smckusick } else if (c&0200 && (c &= 0177) >='1' && c < nbra+'1') {
120691c17a00Smckusick sp = place(sp, braslist[c-'1'], braelist[c-'1']);
120791c17a00Smckusick continue;
120891c17a00Smckusick }
120991c17a00Smckusick *sp++ = c&0177;
121091c17a00Smckusick if (sp >= &genbuf[LBSIZE])
121191c17a00Smckusick error(Q);
121291c17a00Smckusick }
121391c17a00Smckusick lp = loc2;
121491c17a00Smckusick loc2 = sp - genbuf + linebuf;
121591c17a00Smckusick while (*sp++ = *lp++)
121691c17a00Smckusick if (sp >= &genbuf[LBSIZE])
121791c17a00Smckusick error(Q);
121891c17a00Smckusick lp = linebuf;
121991c17a00Smckusick sp = genbuf;
122091c17a00Smckusick while (*lp++ = *sp++)
122191c17a00Smckusick ;
122291c17a00Smckusick }
122391c17a00Smckusick
122491c17a00Smckusick char *
place(sp,l1,l2)122591c17a00Smckusick place(sp, l1, l2)
122691c17a00Smckusick register char *sp, *l1, *l2;
122791c17a00Smckusick {
122891c17a00Smckusick
122991c17a00Smckusick while (l1 < l2) {
123091c17a00Smckusick *sp++ = *l1++;
123191c17a00Smckusick if (sp >= &genbuf[LBSIZE])
123291c17a00Smckusick error(Q);
123391c17a00Smckusick }
123491c17a00Smckusick return(sp);
123591c17a00Smckusick }
123691c17a00Smckusick
move(cflag)123791c17a00Smckusick move(cflag)
123891c17a00Smckusick {
123991c17a00Smckusick register int *adt, *ad1, *ad2;
124091c17a00Smckusick int getcopy();
124191c17a00Smckusick
124291c17a00Smckusick setdot();
124391c17a00Smckusick nonzero();
124491c17a00Smckusick if ((adt = address())==0)
124591c17a00Smckusick error(Q);
124691c17a00Smckusick newline();
124791c17a00Smckusick if (cflag) {
124891c17a00Smckusick int *ozero, delta;
124991c17a00Smckusick ad1 = dol;
125091c17a00Smckusick ozero = zero;
125191c17a00Smckusick append(getcopy, ad1++);
125291c17a00Smckusick ad2 = dol;
125391c17a00Smckusick delta = zero - ozero;
125491c17a00Smckusick ad1 += delta;
125591c17a00Smckusick adt += delta;
125691c17a00Smckusick } else {
125791c17a00Smckusick ad2 = addr2;
125891c17a00Smckusick for (ad1 = addr1; ad1 <= ad2;)
125991c17a00Smckusick *ad1++ &= ~01;
126091c17a00Smckusick ad1 = addr1;
126191c17a00Smckusick }
126291c17a00Smckusick ad2++;
126391c17a00Smckusick if (adt<ad1) {
126491c17a00Smckusick dot = adt + (ad2-ad1);
126591c17a00Smckusick if ((++adt)==ad1)
126691c17a00Smckusick return;
126791c17a00Smckusick reverse(adt, ad1);
126891c17a00Smckusick reverse(ad1, ad2);
126991c17a00Smckusick reverse(adt, ad2);
127091c17a00Smckusick } else if (adt >= ad2) {
127191c17a00Smckusick dot = adt++;
127291c17a00Smckusick reverse(ad1, ad2);
127391c17a00Smckusick reverse(ad2, adt);
127491c17a00Smckusick reverse(ad1, adt);
127591c17a00Smckusick } else
127691c17a00Smckusick error(Q);
127791c17a00Smckusick fchange = 1;
127891c17a00Smckusick }
127991c17a00Smckusick
reverse(a1,a2)128091c17a00Smckusick reverse(a1, a2)
128191c17a00Smckusick register int *a1, *a2;
128291c17a00Smckusick {
128391c17a00Smckusick register int t;
128491c17a00Smckusick
128591c17a00Smckusick for (;;) {
128691c17a00Smckusick t = *--a2;
128791c17a00Smckusick if (a2 <= a1)
128891c17a00Smckusick return;
128991c17a00Smckusick *a2 = *a1;
129091c17a00Smckusick *a1++ = t;
129191c17a00Smckusick }
129291c17a00Smckusick }
129391c17a00Smckusick
getcopy()129491c17a00Smckusick getcopy()
129591c17a00Smckusick {
129691c17a00Smckusick if (addr1 > addr2)
129791c17a00Smckusick return(EOF);
129891c17a00Smckusick getline(*addr1++);
129991c17a00Smckusick return(0);
130091c17a00Smckusick }
130191c17a00Smckusick
compile(aeof)130291c17a00Smckusick compile(aeof)
130391c17a00Smckusick {
130491c17a00Smckusick register eof, c;
130591c17a00Smckusick register char *ep;
130691c17a00Smckusick char *lastep;
130791c17a00Smckusick char bracket[NBRA], *bracketp;
130891c17a00Smckusick int cclcnt;
130991c17a00Smckusick
131091c17a00Smckusick ep = expbuf;
131191c17a00Smckusick eof = aeof;
131291c17a00Smckusick bracketp = bracket;
131391c17a00Smckusick if ((c = getchr()) == eof) {
131491c17a00Smckusick if (*ep==0)
131591c17a00Smckusick error(Q);
131691c17a00Smckusick return;
131791c17a00Smckusick }
131891c17a00Smckusick circfl = 0;
131991c17a00Smckusick nbra = 0;
132091c17a00Smckusick if (c=='^') {
132191c17a00Smckusick c = getchr();
132291c17a00Smckusick circfl++;
132391c17a00Smckusick }
132491c17a00Smckusick peekc = c;
132591c17a00Smckusick lastep = 0;
132691c17a00Smckusick for (;;) {
132791c17a00Smckusick if (ep >= &expbuf[ESIZE])
132891c17a00Smckusick goto cerror;
132991c17a00Smckusick c = getchr();
133091c17a00Smckusick if (c==eof) {
133191c17a00Smckusick if (bracketp != bracket)
133291c17a00Smckusick goto cerror;
133391c17a00Smckusick *ep++ = CEOF;
133491c17a00Smckusick return;
133591c17a00Smckusick }
133691c17a00Smckusick if (c!='*')
133791c17a00Smckusick lastep = ep;
133891c17a00Smckusick switch (c) {
133991c17a00Smckusick
134091c17a00Smckusick case '\\':
134191c17a00Smckusick if ((c = getchr())=='(') {
134291c17a00Smckusick if (nbra >= NBRA)
134391c17a00Smckusick goto cerror;
134491c17a00Smckusick *bracketp++ = nbra;
134591c17a00Smckusick *ep++ = CBRA;
134691c17a00Smckusick *ep++ = nbra++;
134791c17a00Smckusick continue;
134891c17a00Smckusick }
134991c17a00Smckusick if (c == ')') {
135091c17a00Smckusick if (bracketp <= bracket)
135191c17a00Smckusick goto cerror;
135291c17a00Smckusick *ep++ = CKET;
135391c17a00Smckusick *ep++ = *--bracketp;
135491c17a00Smckusick continue;
135591c17a00Smckusick }
135691c17a00Smckusick if (c>='1' && c<'1'+NBRA) {
135791c17a00Smckusick *ep++ = CBACK;
135891c17a00Smckusick *ep++ = c-'1';
135991c17a00Smckusick continue;
136091c17a00Smckusick }
136191c17a00Smckusick *ep++ = CCHR;
136291c17a00Smckusick if (c=='\n')
136391c17a00Smckusick goto cerror;
136491c17a00Smckusick *ep++ = c;
136591c17a00Smckusick continue;
136691c17a00Smckusick
136791c17a00Smckusick case '.':
136891c17a00Smckusick *ep++ = CDOT;
136991c17a00Smckusick continue;
137091c17a00Smckusick
137191c17a00Smckusick case '\n':
137291c17a00Smckusick goto cerror;
137391c17a00Smckusick
137491c17a00Smckusick case '*':
137591c17a00Smckusick if (lastep==0 || *lastep==CBRA || *lastep==CKET)
137691c17a00Smckusick goto defchar;
137791c17a00Smckusick *lastep |= STAR;
137891c17a00Smckusick continue;
137991c17a00Smckusick
138091c17a00Smckusick case '$':
138191c17a00Smckusick if ((peekc=getchr()) != eof)
138291c17a00Smckusick goto defchar;
138391c17a00Smckusick *ep++ = CDOL;
138491c17a00Smckusick continue;
138591c17a00Smckusick
138691c17a00Smckusick case '[':
138791c17a00Smckusick *ep++ = CCL;
138891c17a00Smckusick *ep++ = 0;
138991c17a00Smckusick cclcnt = 1;
139091c17a00Smckusick if ((c=getchr()) == '^') {
139191c17a00Smckusick c = getchr();
139291c17a00Smckusick ep[-2] = NCCL;
139391c17a00Smckusick }
139491c17a00Smckusick do {
139591c17a00Smckusick if (c=='\n')
139691c17a00Smckusick goto cerror;
139791c17a00Smckusick if (c=='-' && ep[-1]!=0) {
139891c17a00Smckusick if ((c=getchr())==']') {
139991c17a00Smckusick *ep++ = '-';
140091c17a00Smckusick cclcnt++;
140191c17a00Smckusick break;
140291c17a00Smckusick }
140391c17a00Smckusick while (ep[-1]<c) {
140491c17a00Smckusick *ep = ep[-1]+1;
140591c17a00Smckusick ep++;
140691c17a00Smckusick cclcnt++;
140791c17a00Smckusick if (ep>=&expbuf[ESIZE])
140891c17a00Smckusick goto cerror;
140991c17a00Smckusick }
141091c17a00Smckusick }
141191c17a00Smckusick *ep++ = c;
141291c17a00Smckusick cclcnt++;
141391c17a00Smckusick if (ep >= &expbuf[ESIZE])
141491c17a00Smckusick goto cerror;
141591c17a00Smckusick } while ((c = getchr()) != ']');
141691c17a00Smckusick lastep[1] = cclcnt;
141791c17a00Smckusick continue;
141891c17a00Smckusick
141991c17a00Smckusick defchar:
142091c17a00Smckusick default:
142191c17a00Smckusick *ep++ = CCHR;
142291c17a00Smckusick *ep++ = c;
142391c17a00Smckusick }
142491c17a00Smckusick }
142591c17a00Smckusick cerror:
142691c17a00Smckusick expbuf[0] = 0;
142791c17a00Smckusick nbra = 0;
142891c17a00Smckusick error(Q);
142991c17a00Smckusick }
143091c17a00Smckusick
execute(gf,addr)143191c17a00Smckusick execute(gf, addr)
143291c17a00Smckusick int *addr;
143391c17a00Smckusick {
143491c17a00Smckusick register char *p1, *p2, c;
143591c17a00Smckusick
143691c17a00Smckusick for (c=0; c<NBRA; c++) {
143791c17a00Smckusick braslist[c] = 0;
143891c17a00Smckusick braelist[c] = 0;
143991c17a00Smckusick }
144091c17a00Smckusick if (gf) {
144191c17a00Smckusick if (circfl)
144291c17a00Smckusick return(0);
144391c17a00Smckusick p1 = linebuf;
144491c17a00Smckusick p2 = genbuf;
144591c17a00Smckusick while (*p1++ = *p2++)
144691c17a00Smckusick ;
144791c17a00Smckusick locs = p1 = loc2;
144891c17a00Smckusick } else {
144991c17a00Smckusick if (addr==zero)
145091c17a00Smckusick return(0);
145191c17a00Smckusick p1 = getline(*addr);
145291c17a00Smckusick locs = 0;
145391c17a00Smckusick }
145491c17a00Smckusick p2 = expbuf;
145591c17a00Smckusick if (circfl) {
145691c17a00Smckusick loc1 = p1;
145791c17a00Smckusick return(advance(p1, p2));
145891c17a00Smckusick }
145991c17a00Smckusick /* fast check for first character */
146091c17a00Smckusick if (*p2==CCHR) {
146191c17a00Smckusick c = p2[1];
146291c17a00Smckusick do {
146391c17a00Smckusick if (*p1!=c)
146491c17a00Smckusick continue;
146591c17a00Smckusick if (advance(p1, p2)) {
146691c17a00Smckusick loc1 = p1;
146791c17a00Smckusick return(1);
146891c17a00Smckusick }
146991c17a00Smckusick } while (*p1++);
147091c17a00Smckusick return(0);
147191c17a00Smckusick }
147291c17a00Smckusick /* regular algorithm */
147391c17a00Smckusick do {
147491c17a00Smckusick if (advance(p1, p2)) {
147591c17a00Smckusick loc1 = p1;
147691c17a00Smckusick return(1);
147791c17a00Smckusick }
147891c17a00Smckusick } while (*p1++);
147991c17a00Smckusick return(0);
148091c17a00Smckusick }
148191c17a00Smckusick
advance(lp,ep)148291c17a00Smckusick advance(lp, ep)
148391c17a00Smckusick register char *ep, *lp;
148491c17a00Smckusick {
148591c17a00Smckusick register char *curlp;
148691c17a00Smckusick int i;
148791c17a00Smckusick
148891c17a00Smckusick for (;;) switch (*ep++) {
148991c17a00Smckusick
149091c17a00Smckusick case CCHR:
149191c17a00Smckusick if (*ep++ == *lp++)
149291c17a00Smckusick continue;
149391c17a00Smckusick return(0);
149491c17a00Smckusick
149591c17a00Smckusick case CDOT:
149691c17a00Smckusick if (*lp++)
149791c17a00Smckusick continue;
149891c17a00Smckusick return(0);
149991c17a00Smckusick
150091c17a00Smckusick case CDOL:
150191c17a00Smckusick if (*lp==0)
150291c17a00Smckusick continue;
150391c17a00Smckusick return(0);
150491c17a00Smckusick
150591c17a00Smckusick case CEOF:
150691c17a00Smckusick loc2 = lp;
150791c17a00Smckusick return(1);
150891c17a00Smckusick
150991c17a00Smckusick case CCL:
151091c17a00Smckusick if (cclass(ep, *lp++, 1)) {
151191c17a00Smckusick ep += *ep;
151291c17a00Smckusick continue;
151391c17a00Smckusick }
151491c17a00Smckusick return(0);
151591c17a00Smckusick
151691c17a00Smckusick case NCCL:
151791c17a00Smckusick if (cclass(ep, *lp++, 0)) {
151891c17a00Smckusick ep += *ep;
151991c17a00Smckusick continue;
152091c17a00Smckusick }
152191c17a00Smckusick return(0);
152291c17a00Smckusick
152391c17a00Smckusick case CBRA:
152491c17a00Smckusick braslist[*ep++] = lp;
152591c17a00Smckusick continue;
152691c17a00Smckusick
152791c17a00Smckusick case CKET:
152891c17a00Smckusick braelist[*ep++] = lp;
152991c17a00Smckusick continue;
153091c17a00Smckusick
153191c17a00Smckusick case CBACK:
153291c17a00Smckusick if (braelist[i = *ep++]==0)
153391c17a00Smckusick error(Q);
153491c17a00Smckusick if (backref(i, lp)) {
153591c17a00Smckusick lp += braelist[i] - braslist[i];
153691c17a00Smckusick continue;
153791c17a00Smckusick }
153891c17a00Smckusick return(0);
153991c17a00Smckusick
154091c17a00Smckusick case CBACK|STAR:
154191c17a00Smckusick if (braelist[i = *ep++] == 0)
154291c17a00Smckusick error(Q);
154391c17a00Smckusick curlp = lp;
154491c17a00Smckusick while (backref(i, lp))
154591c17a00Smckusick lp += braelist[i] - braslist[i];
154691c17a00Smckusick while (lp >= curlp) {
154791c17a00Smckusick if (advance(lp, ep))
154891c17a00Smckusick return(1);
154991c17a00Smckusick lp -= braelist[i] - braslist[i];
155091c17a00Smckusick }
155191c17a00Smckusick continue;
155291c17a00Smckusick
155391c17a00Smckusick case CDOT|STAR:
155491c17a00Smckusick curlp = lp;
155591c17a00Smckusick while (*lp++)
155691c17a00Smckusick ;
155791c17a00Smckusick goto star;
155891c17a00Smckusick
155991c17a00Smckusick case CCHR|STAR:
156091c17a00Smckusick curlp = lp;
156191c17a00Smckusick while (*lp++ == *ep)
156291c17a00Smckusick ;
156391c17a00Smckusick ep++;
156491c17a00Smckusick goto star;
156591c17a00Smckusick
156691c17a00Smckusick case CCL|STAR:
156791c17a00Smckusick case NCCL|STAR:
156891c17a00Smckusick curlp = lp;
156991c17a00Smckusick while (cclass(ep, *lp++, ep[-1]==(CCL|STAR)))
157091c17a00Smckusick ;
157191c17a00Smckusick ep += *ep;
157291c17a00Smckusick goto star;
157391c17a00Smckusick
157491c17a00Smckusick star:
157591c17a00Smckusick do {
157691c17a00Smckusick lp--;
157791c17a00Smckusick if (lp==locs)
157891c17a00Smckusick break;
157991c17a00Smckusick if (advance(lp, ep))
158091c17a00Smckusick return(1);
158191c17a00Smckusick } while (lp > curlp);
158291c17a00Smckusick return(0);
158391c17a00Smckusick
158491c17a00Smckusick default:
158591c17a00Smckusick error(Q);
158691c17a00Smckusick }
158791c17a00Smckusick }
158891c17a00Smckusick
backref(i,lp)158991c17a00Smckusick backref(i, lp)
159091c17a00Smckusick register i;
159191c17a00Smckusick register char *lp;
159291c17a00Smckusick {
159391c17a00Smckusick register char *bp;
159491c17a00Smckusick
159591c17a00Smckusick bp = braslist[i];
159691c17a00Smckusick while (*bp++ == *lp++)
159791c17a00Smckusick if (bp >= braelist[i])
159891c17a00Smckusick return(1);
159991c17a00Smckusick return(0);
160091c17a00Smckusick }
160191c17a00Smckusick
cclass(set,c,af)160291c17a00Smckusick cclass(set, c, af)
160391c17a00Smckusick register char *set, c;
160491c17a00Smckusick {
160591c17a00Smckusick register n;
160691c17a00Smckusick
160791c17a00Smckusick if (c==0)
160891c17a00Smckusick return(0);
160991c17a00Smckusick n = *set++;
161091c17a00Smckusick while (--n)
161191c17a00Smckusick if (*set++ == c)
161291c17a00Smckusick return(af);
161391c17a00Smckusick return(!af);
161491c17a00Smckusick }
161591c17a00Smckusick
putd()161691c17a00Smckusick putd()
161791c17a00Smckusick {
161891c17a00Smckusick register r;
161991c17a00Smckusick
162091c17a00Smckusick r = count%10;
162191c17a00Smckusick count /= 10;
162291c17a00Smckusick if (count)
162391c17a00Smckusick putd();
162491c17a00Smckusick putchr(r + '0');
162591c17a00Smckusick }
162691c17a00Smckusick
puts(sp)162791c17a00Smckusick puts(sp)
162891c17a00Smckusick register char *sp;
162991c17a00Smckusick {
163091c17a00Smckusick col = 0;
163191c17a00Smckusick while (*sp)
163291c17a00Smckusick putchr(*sp++);
163391c17a00Smckusick putchr('\n');
163491c17a00Smckusick }
163591c17a00Smckusick
163691c17a00Smckusick char line[70];
163791c17a00Smckusick char *linp = line;
163891c17a00Smckusick
putchr(ac)163991c17a00Smckusick putchr(ac)
164091c17a00Smckusick {
164191c17a00Smckusick register char *lp;
164291c17a00Smckusick register c;
164391c17a00Smckusick
164491c17a00Smckusick lp = linp;
164591c17a00Smckusick c = ac;
164691c17a00Smckusick if (listf) {
164791c17a00Smckusick col++;
164891c17a00Smckusick if (col >= 72) {
164991c17a00Smckusick col = 0;
165091c17a00Smckusick *lp++ = '\\';
165191c17a00Smckusick *lp++ = '\n';
165291c17a00Smckusick }
165391c17a00Smckusick if (c=='\t') {
165491c17a00Smckusick c = '>';
165591c17a00Smckusick goto esc;
165691c17a00Smckusick }
165791c17a00Smckusick if (c=='\b') {
165891c17a00Smckusick c = '<';
165991c17a00Smckusick esc:
166091c17a00Smckusick *lp++ = '-';
166191c17a00Smckusick *lp++ = '\b';
166291c17a00Smckusick *lp++ = c;
166391c17a00Smckusick goto out;
166491c17a00Smckusick }
166591c17a00Smckusick if (c<' ' && c!= '\n') {
166691c17a00Smckusick *lp++ = '\\';
166791c17a00Smckusick *lp++ = (c>>3)+'0';
166891c17a00Smckusick *lp++ = (c&07)+'0';
166991c17a00Smckusick col += 2;
167091c17a00Smckusick goto out;
167191c17a00Smckusick }
167291c17a00Smckusick }
167391c17a00Smckusick *lp++ = c;
167491c17a00Smckusick out:
167591c17a00Smckusick if(c == '\n' || lp >= &line[64]) {
167691c17a00Smckusick linp = line;
167791c17a00Smckusick write(1, line, lp-line);
167891c17a00Smckusick return;
167991c17a00Smckusick }
168091c17a00Smckusick linp = lp;
168191c17a00Smckusick }
1682da1d502bSmckusick
1683*ee3b4668Sbostic #ifdef CRYPT
1684*ee3b4668Sbostic /*
1685*ee3b4668Sbostic * Begin routines for doing encryption.
1686*ee3b4668Sbostic */
crblock(permp,buf,nchar,startn)1687*ee3b4668Sbostic crblock(permp, buf, nchar, startn)
1688*ee3b4668Sbostic char *permp;
1689*ee3b4668Sbostic char *buf;
1690*ee3b4668Sbostic long startn;
1691*ee3b4668Sbostic {
1692*ee3b4668Sbostic register char *p1;
1693*ee3b4668Sbostic int n1;
1694*ee3b4668Sbostic int n2;
1695*ee3b4668Sbostic register char *t1, *t2, *t3;
1696*ee3b4668Sbostic
1697*ee3b4668Sbostic t1 = permp;
1698*ee3b4668Sbostic t2 = &permp[256];
1699*ee3b4668Sbostic t3 = &permp[512];
1700*ee3b4668Sbostic
1701*ee3b4668Sbostic n1 = startn&0377;
1702*ee3b4668Sbostic n2 = (startn>>8)&0377;
1703*ee3b4668Sbostic p1 = buf;
1704*ee3b4668Sbostic while(nchar--) {
1705*ee3b4668Sbostic *p1 = t2[(t3[(t1[(*p1+n1)&0377]+n2)&0377]-n2)&0377]-n1;
1706*ee3b4668Sbostic n1++;
1707*ee3b4668Sbostic if(n1==256){
1708*ee3b4668Sbostic n1 = 0;
1709*ee3b4668Sbostic n2++;
1710*ee3b4668Sbostic if(n2==256) n2 = 0;
1711*ee3b4668Sbostic }
1712*ee3b4668Sbostic p1++;
1713*ee3b4668Sbostic }
1714*ee3b4668Sbostic }
1715*ee3b4668Sbostic
getkey()1716*ee3b4668Sbostic getkey()
1717*ee3b4668Sbostic {
1718*ee3b4668Sbostic struct sgttyb b;
1719*ee3b4668Sbostic int save;
1720*ee3b4668Sbostic sig_t sig;
1721*ee3b4668Sbostic register char *p;
1722*ee3b4668Sbostic register c;
1723*ee3b4668Sbostic
1724*ee3b4668Sbostic sig = signal(SIGINT, SIG_IGN);
1725*ee3b4668Sbostic if (ioctl(0, TIOCGETP, &b) == -1)
1726*ee3b4668Sbostic error("Input not tty");
1727*ee3b4668Sbostic save = b.sg_flags;
1728*ee3b4668Sbostic b.sg_flags &= ~ECHO;
1729*ee3b4668Sbostic (void)ioctl(0, TIOCSETP, &b);
1730*ee3b4668Sbostic puts("Key:");
1731*ee3b4668Sbostic p = key;
1732*ee3b4668Sbostic while(((c=getchr()) != EOF) && (c!='\n')) {
1733*ee3b4668Sbostic if(p < &key[KSIZE])
1734*ee3b4668Sbostic *p++ = c;
1735*ee3b4668Sbostic }
1736*ee3b4668Sbostic *p = 0;
1737*ee3b4668Sbostic b.sg_flags = save;
1738*ee3b4668Sbostic (void)ioctl(0, TIOCSETP, &b);
1739*ee3b4668Sbostic signal(SIGINT, sig);
1740*ee3b4668Sbostic return(key[0] != 0);
1741*ee3b4668Sbostic }
1742*ee3b4668Sbostic
1743*ee3b4668Sbostic /*
1744*ee3b4668Sbostic * Besides initializing the encryption machine, this routine
1745*ee3b4668Sbostic * returns 0 if the key is null, and 1 if it is non-null.
1746*ee3b4668Sbostic */
crinit(keyp,permp)1747*ee3b4668Sbostic crinit(keyp, permp)
1748*ee3b4668Sbostic char *keyp, *permp;
1749*ee3b4668Sbostic {
1750*ee3b4668Sbostic register char *t1, *t2, *t3;
1751*ee3b4668Sbostic register i;
1752*ee3b4668Sbostic int ic, k, temp, pf[2];
1753*ee3b4668Sbostic unsigned random;
1754*ee3b4668Sbostic char buf[13];
1755*ee3b4668Sbostic long seed;
1756*ee3b4668Sbostic
1757*ee3b4668Sbostic t1 = permp;
1758*ee3b4668Sbostic t2 = &permp[256];
1759*ee3b4668Sbostic t3 = &permp[512];
1760*ee3b4668Sbostic if(*keyp == 0)
1761*ee3b4668Sbostic return(0);
1762*ee3b4668Sbostic strncpy(buf, keyp, 8);
1763*ee3b4668Sbostic while (*keyp)
1764*ee3b4668Sbostic *keyp++ = '\0';
1765*ee3b4668Sbostic buf[8] = buf[0];
1766*ee3b4668Sbostic buf[9] = buf[1];
1767*ee3b4668Sbostic if (pipe(pf)<0)
1768*ee3b4668Sbostic pf[0] = pf[1] = -1;
1769*ee3b4668Sbostic if (fork()==0) {
1770*ee3b4668Sbostic close(0);
1771*ee3b4668Sbostic close(1);
1772*ee3b4668Sbostic dup(pf[0]);
1773*ee3b4668Sbostic dup(pf[1]);
1774*ee3b4668Sbostic execl(_PATH_MAKEKEY, "-", 0);
1775*ee3b4668Sbostic exit(1);
1776*ee3b4668Sbostic }
1777*ee3b4668Sbostic write(pf[1], buf, 10);
1778*ee3b4668Sbostic if (wait((int *)NULL)==-1 || read(pf[0], buf, 13)!=13)
1779*ee3b4668Sbostic error("crypt: cannot generate key");
1780*ee3b4668Sbostic close(pf[0]);
1781*ee3b4668Sbostic close(pf[1]);
1782*ee3b4668Sbostic seed = 123;
1783*ee3b4668Sbostic for (i=0; i<13; i++)
1784*ee3b4668Sbostic seed = seed*buf[i] + i;
1785*ee3b4668Sbostic for(i=0;i<256;i++){
1786*ee3b4668Sbostic t1[i] = i;
1787*ee3b4668Sbostic t3[i] = 0;
1788*ee3b4668Sbostic }
1789*ee3b4668Sbostic for(i=0; i<256; i++) {
1790*ee3b4668Sbostic seed = 5*seed + buf[i%13];
1791*ee3b4668Sbostic random = seed % 65521;
1792*ee3b4668Sbostic k = 256-1 - i;
1793*ee3b4668Sbostic ic = (random&0377) % (k+1);
1794*ee3b4668Sbostic random >>= 8;
1795*ee3b4668Sbostic temp = t1[k];
1796*ee3b4668Sbostic t1[k] = t1[ic];
1797*ee3b4668Sbostic t1[ic] = temp;
1798*ee3b4668Sbostic if(t3[k]!=0) continue;
1799*ee3b4668Sbostic ic = (random&0377) % k;
1800*ee3b4668Sbostic while(t3[ic]!=0) ic = (ic+1) % k;
1801*ee3b4668Sbostic t3[k] = ic;
1802*ee3b4668Sbostic t3[ic] = k;
1803*ee3b4668Sbostic }
1804*ee3b4668Sbostic for(i=0; i<256; i++)
1805*ee3b4668Sbostic t2[t1[i]&0377] = i;
1806*ee3b4668Sbostic return(1);
1807*ee3b4668Sbostic }
1808*ee3b4668Sbostic
makekey(a,b)1809*ee3b4668Sbostic makekey(a, b)
1810*ee3b4668Sbostic char *a, *b;
1811*ee3b4668Sbostic {
1812*ee3b4668Sbostic register int i;
1813*ee3b4668Sbostic long t;
1814*ee3b4668Sbostic char temp[KSIZE + 1];
1815*ee3b4668Sbostic
1816*ee3b4668Sbostic for(i = 0; i < KSIZE; i++)
1817*ee3b4668Sbostic temp[i] = *a++;
1818*ee3b4668Sbostic time(&t);
1819*ee3b4668Sbostic t += getpid();
1820*ee3b4668Sbostic for(i = 0; i < 4; i++)
1821*ee3b4668Sbostic temp[i] ^= (t>>(8*i))&0377;
1822*ee3b4668Sbostic crinit(temp, b);
1823*ee3b4668Sbostic }
1824*ee3b4668Sbostic #endif CRYPT
1825