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