xref: /csrg-svn/bin/ed/ed.c (revision 66633)
147839Sbostic /*-
2*66633Sbostic  * Copyright (c) 1991
3*66633Sbostic  *	The Regents of the University of California.  All rights reserved.
447839Sbostic  *
547839Sbostic  * %sccs.include.proprietary.c%
647839Sbostic  */
747839Sbostic 
814463Ssam #ifndef lint
947839Sbostic char copyright[] =
10*66633Sbostic "@(#) Copyright (c) 1991\n\
11*66633Sbostic 	The Regents of the University of California.  All rights reserved.\n";
1247839Sbostic #endif /* not lint */
136644Smckusick 
1447839Sbostic #ifndef lint
15*66633Sbostic static char sccsid[] = "@(#)ed.c	5.2 (Berkeley) 04/02/94";
1647839Sbostic #endif /* not lint */
1747839Sbostic 
186644Smckusick /*
196644Smckusick  * Editor
206644Smckusick  */
21*66633Sbostic #define CRYPT
22*66633Sbostic 
2340179Sdonn #include <sys/param.h>
2446653Sbostic #include <sys/wait.h>
2546653Sbostic #include <signal.h>
266644Smckusick #include <sgtty.h>
279909Ssam #undef CEOF
2846653Sbostic #include <fcntl.h>
2946653Sbostic #include <time.h>
306644Smckusick #include <setjmp.h>
3146653Sbostic #include <stdlib.h>
3246653Sbostic #include <string.h>
3346653Sbostic #include <unistd.h>
3437029Sbostic #include "pathnames.h"
3537029Sbostic 
366644Smckusick #define	NULL	0
376644Smckusick #define	LBSIZE	512
386644Smckusick #define	ESIZE	128
396644Smckusick #define	GBSIZE	256
406644Smckusick #define	NBRA	5
416644Smckusick #define	EOF	-1
426644Smckusick 
436644Smckusick #define	CBRA	1
446644Smckusick #define	CCHR	2
456644Smckusick #define	CDOT	4
466644Smckusick #define	CCL	6
476644Smckusick #define	NCCL	8
486644Smckusick #define	CDOL	10
496644Smckusick #define	CEOF	11
506644Smckusick #define	CKET	12
516644Smckusick #define	CBACK	14
526644Smckusick 
536644Smckusick #define	STAR	01
546644Smckusick 
556644Smckusick char	Q[]	= "";
566644Smckusick char	T[]	= "TMP";
576644Smckusick #define	READ	0
586644Smckusick #define	WRITE	1
596644Smckusick 
606644Smckusick int	peekc;
616644Smckusick int	lastc;
6240154Sbostic char	savedfile[MAXPATHLEN];
6340154Sbostic char	file[MAXPATHLEN];
646644Smckusick char	linebuf[LBSIZE];
656644Smckusick char	rhsbuf[LBSIZE/2];
666644Smckusick char	expbuf[ESIZE+4];
676644Smckusick int	circfl;
686644Smckusick int	*zero;
696644Smckusick int	*dot;
706644Smckusick int	*dol;
716644Smckusick int	*addr1;
726644Smckusick int	*addr2;
736644Smckusick char	genbuf[LBSIZE];
746644Smckusick long	count;
756644Smckusick char	*nextip;
766644Smckusick char	*linebp;
776644Smckusick int	ninbuf;
786644Smckusick int	io;
796644Smckusick int	pflag;
8039154Sbostic sig_t	oldhup;
8139154Sbostic sig_t	oldquit;
826644Smckusick int	vflag	= 1;
8329769Smckusick 
84*66633Sbostic #ifdef CRYPT
85*66633Sbostic /*
86*66633Sbostic  * Various flags and buffers needed by the encryption routines.
87*66633Sbostic  */
88*66633Sbostic #define	KSIZE	9
89*66633Sbostic int	xflag;
90*66633Sbostic int	xtflag;
91*66633Sbostic int	kflag;
92*66633Sbostic char	key[KSIZE + 1];
93*66633Sbostic char	crbuf[512];
94*66633Sbostic char	perm[768];
95*66633Sbostic char	tperm[768];
96*66633Sbostic #endif CRYPT
9729769Smckusick 
986644Smckusick int	listf;
996644Smckusick int	col;
1006644Smckusick char	*globp;
1016644Smckusick int	tfile	= -1;
1026644Smckusick int	tline;
10337686Sbostic char	tfname[sizeof(_PATH_TMP) + 20];
1046644Smckusick char	*loc1;
1056644Smckusick char	*loc2;
1066644Smckusick char	*locs;
1076644Smckusick char	ibuff[512];
1086644Smckusick int	iblock	= -1;
1096644Smckusick char	obuff[512];
1106644Smckusick int	oblock	= -1;
1116644Smckusick int	ichanged;
1126644Smckusick int	nleft;
1136644Smckusick char	WRERR[]	= "WRITE ERROR";
1146644Smckusick int	names[26];
1156644Smckusick int	anymarks;
1166644Smckusick char	*braslist[NBRA];
1176644Smckusick char	*braelist[NBRA];
1186644Smckusick int	nbra;
1196644Smckusick int	subnewa;
1206644Smckusick int	subolda;
1216644Smckusick int	fchange;
1226644Smckusick int	wrapp;
1236644Smckusick unsigned nlall = 128;
1246644Smckusick 
1256644Smckusick int	*address();
1266644Smckusick char	*getline();
1276644Smckusick char	*getblock();
1286644Smckusick char	*place();
1296644Smckusick jmp_buf	savej;
1306644Smckusick 
13146653Sbostic void onintr(), quit(), onhup();
13246653Sbostic 
main(argc,argv)1336644Smckusick main(argc, argv)
13446653Sbostic 	int argc;
13546653Sbostic 	char **argv;
1366644Smckusick {
1376644Smckusick 	register char *p1, *p2;
13839154Sbostic 	sig_t oldintr;
1396644Smckusick 
1406644Smckusick 	oldquit = signal(SIGQUIT, SIG_IGN);
1416644Smckusick 	oldhup = signal(SIGHUP, SIG_IGN);
1426644Smckusick 	oldintr = signal(SIGINT, SIG_IGN);
1436644Smckusick 	if ((int)signal(SIGTERM, SIG_IGN) == 0)
1446644Smckusick 		signal(SIGTERM, quit);
1456644Smckusick 	argv++;
1466644Smckusick 	while (argc > 1 && **argv=='-') {
1476644Smckusick 		switch((*argv)[1]) {
1486644Smckusick 
1496644Smckusick 		case '\0':
1506644Smckusick 			vflag = 0;
1516644Smckusick 			break;
1526644Smckusick 
1536644Smckusick 		case 'q':
1546644Smckusick 			signal(SIGQUIT, SIG_DFL);
1556644Smckusick 			vflag = 1;
1566644Smckusick 			break;
1576644Smckusick 
158*66633Sbostic #ifdef CRYPT
159*66633Sbostic 		case 'x':
160*66633Sbostic 			xflag = 1;
161*66633Sbostic 			break;
162*66633Sbostic #endif CRYPT
1636644Smckusick 		}
1646644Smckusick 		argv++;
1656644Smckusick 		argc--;
1666644Smckusick 	}
167*66633Sbostic #ifdef CRYPT
168*66633Sbostic 	if(xflag){
169*66633Sbostic 		getkey();
170*66633Sbostic 		kflag = crinit(key, perm);
171*66633Sbostic 	}
172*66633Sbostic #endif CRYPT
1736644Smckusick 
1746644Smckusick 	if (argc>1) {
1756644Smckusick 		p1 = *argv;
1766644Smckusick 		p2 = savedfile;
1776644Smckusick 		while (*p2++ = *p1++)
1786644Smckusick 			;
1796644Smckusick 		globp = "r";
1806644Smckusick 	}
1816644Smckusick 	zero = (int *)malloc(nlall*sizeof(int));
18237686Sbostic 	(void)strcpy(tfname, _PATH_TMP);
18337686Sbostic 	(void)strcat(tfname, "_edXXXXXX");
18437686Sbostic 	(void)mktemp(tfname);
1856644Smckusick 	init();
1866644Smckusick 	if (((int)oldintr&01) == 0)
1876644Smckusick 		signal(SIGINT, onintr);
1886644Smckusick 	if (((int)oldhup&01) == 0)
1896644Smckusick 		signal(SIGHUP, onhup);
1906644Smckusick 	setjmp(savej);
1916644Smckusick 	commands();
1926644Smckusick 	quit();
1936644Smckusick }
1946644Smckusick 
commands()1956644Smckusick commands()
1966644Smckusick {
1976644Smckusick 	int getfile(), gettty();
1986644Smckusick 	register *a1, c;
1996644Smckusick 
2006644Smckusick 	for (;;) {
2016644Smckusick 	if (pflag) {
2026644Smckusick 		pflag = 0;
2036644Smckusick 		addr1 = addr2 = dot;
2046644Smckusick 		goto print;
2056644Smckusick 	}
2066644Smckusick 	addr1 = 0;
2076644Smckusick 	addr2 = 0;
2086644Smckusick 	do {
2096644Smckusick 		addr1 = addr2;
2106644Smckusick 		if ((a1 = address())==0) {
2116644Smckusick 			c = getchr();
2126644Smckusick 			break;
2136644Smckusick 		}
2146644Smckusick 		addr2 = a1;
2156644Smckusick 		if ((c=getchr()) == ';') {
2166644Smckusick 			c = ',';
2176644Smckusick 			dot = a1;
2186644Smckusick 		}
2196644Smckusick 	} while (c==',');
2206644Smckusick 	if (addr1==0)
2216644Smckusick 		addr1 = addr2;
2226644Smckusick 	switch(c) {
2236644Smckusick 
2246644Smckusick 	case 'a':
2256644Smckusick 		setdot();
2266644Smckusick 		newline();
2276644Smckusick 		append(gettty, addr2);
2286644Smckusick 		continue;
2296644Smckusick 
2306644Smckusick 	case 'c':
2316644Smckusick 		delete();
2326644Smckusick 		append(gettty, addr1-1);
2336644Smckusick 		continue;
2346644Smckusick 
2356644Smckusick 	case 'd':
2366644Smckusick 		delete();
2376644Smckusick 		continue;
2386644Smckusick 
2396644Smckusick 	case 'E':
2406644Smckusick 		fchange = 0;
2416644Smckusick 		c = 'e';
2426644Smckusick 	case 'e':
2436644Smckusick 		setnoaddr();
2446644Smckusick 		if (vflag && fchange) {
2456644Smckusick 			fchange = 0;
2466644Smckusick 			error(Q);
2476644Smckusick 		}
2486644Smckusick 		filename(c);
2496644Smckusick 		init();
2506644Smckusick 		addr2 = zero;
2516644Smckusick 		goto caseread;
2526644Smckusick 
2536644Smckusick 	case 'f':
2546644Smckusick 		setnoaddr();
2556644Smckusick 		filename(c);
2566644Smckusick 		puts(savedfile);
2576644Smckusick 		continue;
2586644Smckusick 
2596644Smckusick 	case 'g':
2606644Smckusick 		global(1);
2616644Smckusick 		continue;
2626644Smckusick 
2636644Smckusick 	case 'i':
2646644Smckusick 		setdot();
2656644Smckusick 		nonzero();
2666644Smckusick 		newline();
2676644Smckusick 		append(gettty, addr2-1);
2686644Smckusick 		continue;
2696644Smckusick 
2706644Smckusick 
2716644Smckusick 	case 'j':
2726644Smckusick 		if (addr2==0) {
2736644Smckusick 			addr1 = dot;
2746644Smckusick 			addr2 = dot+1;
2756644Smckusick 		}
2766644Smckusick 		setdot();
2776644Smckusick 		newline();
2786644Smckusick 		nonzero();
2796644Smckusick 		join();
2806644Smckusick 		continue;
2816644Smckusick 
2826644Smckusick 	case 'k':
2836644Smckusick 		if ((c = getchr()) < 'a' || c > 'z')
2846644Smckusick 			error(Q);
2856644Smckusick 		newline();
2866644Smckusick 		setdot();
2876644Smckusick 		nonzero();
2886644Smckusick 		names[c-'a'] = *addr2 & ~01;
2896644Smckusick 		anymarks |= 01;
2906644Smckusick 		continue;
2916644Smckusick 
2926644Smckusick 	case 'm':
2936644Smckusick 		move(0);
2946644Smckusick 		continue;
2956644Smckusick 
2966644Smckusick 	case '\n':
2976644Smckusick 		if (addr2==0)
2986644Smckusick 			addr2 = dot+1;
2996644Smckusick 		addr1 = addr2;
3006644Smckusick 		goto print;
3016644Smckusick 
3026644Smckusick 	case 'l':
3036644Smckusick 		listf++;
3046644Smckusick 	case 'p':
3056644Smckusick 	case 'P':
3066644Smckusick 		newline();
3076644Smckusick 	print:
3086644Smckusick 		setdot();
3096644Smckusick 		nonzero();
3106644Smckusick 		a1 = addr1;
3116644Smckusick 		do {
3126644Smckusick 			puts(getline(*a1++));
3136644Smckusick 		} while (a1 <= addr2);
3146644Smckusick 		dot = addr2;
3156644Smckusick 		listf = 0;
3166644Smckusick 		continue;
3176644Smckusick 
3186644Smckusick 	case 'Q':
3196644Smckusick 		fchange = 0;
3206644Smckusick 	case 'q':
3216644Smckusick 		setnoaddr();
3226644Smckusick 		newline();
3236644Smckusick 		quit();
3246644Smckusick 
3256644Smckusick 	case 'r':
3266644Smckusick 		filename(c);
3276644Smckusick 	caseread:
3286644Smckusick 		if ((io = open(file, 0)) < 0) {
3296644Smckusick 			lastc = '\n';
3306644Smckusick 			error(file);
3316644Smckusick 		}
3326644Smckusick 		setall();
3336644Smckusick 		ninbuf = 0;
3346644Smckusick 		c = zero != dol;
3356644Smckusick 		append(getfile, addr2);
3366644Smckusick 		exfile();
3376644Smckusick 		fchange = c;
3386644Smckusick 		continue;
3396644Smckusick 
3406644Smckusick 	case 's':
3416644Smckusick 		setdot();
3426644Smckusick 		nonzero();
3436644Smckusick 		substitute(globp!=0);
3446644Smckusick 		continue;
3456644Smckusick 
3466644Smckusick 	case 't':
3476644Smckusick 		move(1);
3486644Smckusick 		continue;
3496644Smckusick 
3506644Smckusick 	case 'u':
3516644Smckusick 		setdot();
3526644Smckusick 		nonzero();
3536644Smckusick 		newline();
3546644Smckusick 		if ((*addr2&~01) != subnewa)
3556644Smckusick 			error(Q);
3566644Smckusick 		*addr2 = subolda;
3576644Smckusick 		dot = addr2;
3586644Smckusick 		continue;
3596644Smckusick 
3606644Smckusick 	case 'v':
3616644Smckusick 		global(0);
3626644Smckusick 		continue;
3636644Smckusick 
3646644Smckusick 	case 'W':
3656644Smckusick 		wrapp++;
3666644Smckusick 	case 'w':
3676644Smckusick 		setall();
3686644Smckusick 		nonzero();
3696644Smckusick 		filename(c);
3706644Smckusick 		if(!wrapp ||
3716644Smckusick 		  ((io = open(file,1)) == -1) ||
3726644Smckusick 		  ((lseek(io, 0L, 2)) == -1))
3736644Smckusick 			if ((io = creat(file, 0666)) < 0)
3746644Smckusick 				error(file);
3756644Smckusick 		wrapp = 0;
3766644Smckusick 		putfile();
3776644Smckusick 		exfile();
3786644Smckusick 		if (addr1==zero+1 && addr2==dol)
3796644Smckusick 			fchange = 0;
3806644Smckusick 		continue;
3816644Smckusick 
382*66633Sbostic #ifdef CRYPT
383*66633Sbostic 	case 'x':
384*66633Sbostic 		setnoaddr();
385*66633Sbostic 		newline();
386*66633Sbostic 		xflag = 1;
387*66633Sbostic 		puts("Entering encrypting mode!");
388*66633Sbostic 		getkey();
389*66633Sbostic 		kflag = crinit(key, perm);
390*66633Sbostic 		continue;
391*66633Sbostic #endif CRYPT
3926644Smckusick 
3936644Smckusick 
3946644Smckusick 	case '=':
3956644Smckusick 		setall();
3966644Smckusick 		newline();
3976644Smckusick 		count = (addr2-zero)&077777;
3986644Smckusick 		putd();
3996644Smckusick 		putchr('\n');
4006644Smckusick 		continue;
4016644Smckusick 
4026644Smckusick 	case '!':
4036644Smckusick 		callunix();
4046644Smckusick 		continue;
4056644Smckusick 
4066644Smckusick 	case EOF:
4076644Smckusick 		return;
4086644Smckusick 
4096644Smckusick 	}
4106644Smckusick 	error(Q);
4116644Smckusick 	}
4126644Smckusick }
4136644Smckusick 
4146644Smckusick int *
address()4156644Smckusick address()
4166644Smckusick {
4176644Smckusick 	register *a1, minus, c;
4186644Smckusick 	int n, relerr;
4196644Smckusick 
4206644Smckusick 	minus = 0;
4216644Smckusick 	a1 = 0;
4226644Smckusick 	for (;;) {
4236644Smckusick 		c = getchr();
4246644Smckusick 		if ('0'<=c && c<='9') {
4256644Smckusick 			n = 0;
4266644Smckusick 			do {
4276644Smckusick 				n *= 10;
4286644Smckusick 				n += c - '0';
4296644Smckusick 			} while ((c = getchr())>='0' && c<='9');
4306644Smckusick 			peekc = c;
4316644Smckusick 			if (a1==0)
4326644Smckusick 				a1 = zero;
4336644Smckusick 			if (minus<0)
4346644Smckusick 				n = -n;
4356644Smckusick 			a1 += n;
4366644Smckusick 			minus = 0;
4376644Smckusick 			continue;
4386644Smckusick 		}
4396644Smckusick 		relerr = 0;
4406644Smckusick 		if (a1 || minus)
4416644Smckusick 			relerr++;
4426644Smckusick 		switch(c) {
4436644Smckusick 		case ' ':
4446644Smckusick 		case '\t':
4456644Smckusick 			continue;
4466644Smckusick 
4476644Smckusick 		case '+':
4486644Smckusick 			minus++;
4496644Smckusick 			if (a1==0)
4506644Smckusick 				a1 = dot;
4516644Smckusick 			continue;
4526644Smckusick 
4536644Smckusick 		case '-':
4546644Smckusick 		case '^':
4556644Smckusick 			minus--;
4566644Smckusick 			if (a1==0)
4576644Smckusick 				a1 = dot;
4586644Smckusick 			continue;
4596644Smckusick 
4606644Smckusick 		case '?':
4616644Smckusick 		case '/':
4626644Smckusick 			compile(c);
4636644Smckusick 			a1 = dot;
4646644Smckusick 			for (;;) {
4656644Smckusick 				if (c=='/') {
4666644Smckusick 					a1++;
4676644Smckusick 					if (a1 > dol)
4686644Smckusick 						a1 = zero;
4696644Smckusick 				} else {
4706644Smckusick 					a1--;
4716644Smckusick 					if (a1 < zero)
4726644Smckusick 						a1 = dol;
4736644Smckusick 				}
4746644Smckusick 				if (execute(0, a1))
4756644Smckusick 					break;
4766644Smckusick 				if (a1==dot)
4776644Smckusick 					error(Q);
4786644Smckusick 			}
4796644Smckusick 			break;
4806644Smckusick 
4816644Smckusick 		case '$':
4826644Smckusick 			a1 = dol;
4836644Smckusick 			break;
4846644Smckusick 
4856644Smckusick 		case '.':
4866644Smckusick 			a1 = dot;
4876644Smckusick 			break;
4886644Smckusick 
4896644Smckusick 		case '\'':
4906644Smckusick 			if ((c = getchr()) < 'a' || c > 'z')
4916644Smckusick 				error(Q);
4926644Smckusick 			for (a1=zero; a1<=dol; a1++)
4936644Smckusick 				if (names[c-'a'] == (*a1 & ~01))
4946644Smckusick 					break;
4956644Smckusick 			break;
4966644Smckusick 
4976644Smckusick 		default:
4986644Smckusick 			peekc = c;
4996644Smckusick 			if (a1==0)
5006644Smckusick 				return(0);
5016644Smckusick 			a1 += minus;
5026644Smckusick 			if (a1<zero || a1>dol)
5036644Smckusick 				error(Q);
5046644Smckusick 			return(a1);
5056644Smckusick 		}
5066644Smckusick 		if (relerr)
5076644Smckusick 			error(Q);
5086644Smckusick 	}
5096644Smckusick }
5106644Smckusick 
setdot()5116644Smckusick setdot()
5126644Smckusick {
5136644Smckusick 	if (addr2 == 0)
5146644Smckusick 		addr1 = addr2 = dot;
5156644Smckusick 	if (addr1 > addr2)
5166644Smckusick 		error(Q);
5176644Smckusick }
5186644Smckusick 
setall()5196644Smckusick setall()
5206644Smckusick {
5216644Smckusick 	if (addr2==0) {
5226644Smckusick 		addr1 = zero+1;
5236644Smckusick 		addr2 = dol;
5246644Smckusick 		if (dol==zero)
5256644Smckusick 			addr1 = zero;
5266644Smckusick 	}
5276644Smckusick 	setdot();
5286644Smckusick }
5296644Smckusick 
setnoaddr()5306644Smckusick setnoaddr()
5316644Smckusick {
5326644Smckusick 	if (addr2)
5336644Smckusick 		error(Q);
5346644Smckusick }
5356644Smckusick 
nonzero()5366644Smckusick nonzero()
5376644Smckusick {
5386644Smckusick 	if (addr1<=zero || addr2>dol)
5396644Smckusick 		error(Q);
5406644Smckusick }
5416644Smckusick 
newline()5426644Smckusick newline()
5436644Smckusick {
5446644Smckusick 	register c;
5456644Smckusick 
5466644Smckusick 	if ((c = getchr()) == '\n')
5476644Smckusick 		return;
5486644Smckusick 	if (c=='p' || c=='l') {
5496644Smckusick 		pflag++;
5506644Smckusick 		if (c=='l')
5516644Smckusick 			listf++;
5526644Smckusick 		if (getchr() == '\n')
5536644Smckusick 			return;
5546644Smckusick 	}
5556644Smckusick 	error(Q);
5566644Smckusick }
5576644Smckusick 
filename(comm)5586644Smckusick filename(comm)
5596644Smckusick {
5606644Smckusick 	register char *p1, *p2;
5616644Smckusick 	register c;
5626644Smckusick 
5636644Smckusick 	count = 0;
5646644Smckusick 	c = getchr();
5656644Smckusick 	if (c=='\n' || c==EOF) {
5666644Smckusick 		p1 = savedfile;
5676644Smckusick 		if (*p1==0 && comm!='f')
5686644Smckusick 			error(Q);
5696644Smckusick 		p2 = file;
5706644Smckusick 		while (*p2++ = *p1++)
5716644Smckusick 			;
5726644Smckusick 		return;
5736644Smckusick 	}
5746644Smckusick 	if (c!=' ')
5756644Smckusick 		error(Q);
5766644Smckusick 	while ((c = getchr()) == ' ')
5776644Smckusick 		;
5786644Smckusick 	if (c=='\n')
5796644Smckusick 		error(Q);
5806644Smckusick 	p1 = file;
5816644Smckusick 	do {
5826644Smckusick 		*p1++ = c;
5836644Smckusick 		if (c==' ' || c==EOF)
5846644Smckusick 			error(Q);
5856644Smckusick 	} while ((c = getchr()) != '\n');
5866644Smckusick 	*p1++ = 0;
5876644Smckusick 	if (savedfile[0]==0 || comm=='e' || comm=='f') {
5886644Smckusick 		p1 = savedfile;
5896644Smckusick 		p2 = file;
5906644Smckusick 		while (*p1++ = *p2++)
5916644Smckusick 			;
5926644Smckusick 	}
5936644Smckusick }
5946644Smckusick 
exfile()5956644Smckusick exfile()
5966644Smckusick {
5976644Smckusick 	close(io);
5986644Smckusick 	io = -1;
5996644Smckusick 	if (vflag) {
6006644Smckusick 		putd();
6016644Smckusick 		putchr('\n');
6026644Smckusick 	}
6036644Smckusick }
6046644Smckusick 
60539154Sbostic void
onintr()6066644Smckusick onintr()
6076644Smckusick {
60839154Sbostic 	/* not necessary: (void)signal(SIGINT, onintr); */
6096644Smckusick 	putchr('\n');
6106644Smckusick 	lastc = '\n';
6116644Smckusick 	error(Q);
6126644Smckusick }
6136644Smckusick 
61439154Sbostic void
onhup()6156644Smckusick onhup()
6166644Smckusick {
61739154Sbostic 	/* not necessary: (void)signal(SIGINT, SIG_IGN); */
61839154Sbostic 	/* not necessary: (void)signal(SIGHUP, SIG_IGN); */
6196644Smckusick 	if (dol > zero) {
6206644Smckusick 		addr1 = zero+1;
6216644Smckusick 		addr2 = dol;
6226644Smckusick 		io = creat("ed.hup", 0666);
6236644Smckusick 		if (io > 0)
6246644Smckusick 			putfile();
6256644Smckusick 	}
6266644Smckusick 	fchange = 0;
6276644Smckusick 	quit();
6286644Smckusick }
6296644Smckusick 
error(s)6306644Smckusick error(s)
6316644Smckusick char *s;
6326644Smckusick {
6336644Smckusick 	register c;
6346644Smckusick 
6356644Smckusick 	wrapp = 0;
6366644Smckusick 	listf = 0;
6376644Smckusick 	putchr('?');
6386644Smckusick 	puts(s);
6396644Smckusick 	count = 0;
6406644Smckusick 	lseek(0, (long)0, 2);
6416644Smckusick 	pflag = 0;
6426644Smckusick 	if (globp)
6436644Smckusick 		lastc = '\n';
6446644Smckusick 	globp = 0;
6456644Smckusick 	peekc = lastc;
6466644Smckusick 	if(lastc)
6476644Smckusick 		while ((c = getchr()) != '\n' && c != EOF)
6486644Smckusick 			;
6496644Smckusick 	if (io > 0) {
6506644Smckusick 		close(io);
6516644Smckusick 		io = -1;
6526644Smckusick 	}
6536644Smckusick 	longjmp(savej, 1);
6546644Smckusick }
6556644Smckusick 
getchr()6566644Smckusick getchr()
6576644Smckusick {
6586644Smckusick 	char c;
6596644Smckusick 	if (lastc=peekc) {
6606644Smckusick 		peekc = 0;
6616644Smckusick 		return(lastc);
6626644Smckusick 	}
6636644Smckusick 	if (globp) {
6646644Smckusick 		if ((lastc = *globp++) != 0)
6656644Smckusick 			return(lastc);
6666644Smckusick 		globp = 0;
6676644Smckusick 		return(EOF);
6686644Smckusick 	}
6696644Smckusick 	if (read(0, &c, 1) <= 0)
6706644Smckusick 		return(lastc = EOF);
6716644Smckusick 	lastc = c&0177;
6726644Smckusick 	return(lastc);
6736644Smckusick }
6746644Smckusick 
gettty()6756644Smckusick gettty()
6766644Smckusick {
6776644Smckusick 	register c;
6786644Smckusick 	register char *gf;
6796644Smckusick 	register char *p;
6806644Smckusick 
6816644Smckusick 	p = linebuf;
6826644Smckusick 	gf = globp;
6836644Smckusick 	while ((c = getchr()) != '\n') {
6846644Smckusick 		if (c==EOF) {
6856644Smckusick 			if (gf)
6866644Smckusick 				peekc = c;
6876644Smckusick 			return(c);
6886644Smckusick 		}
6896644Smckusick 		if ((c &= 0177) == 0)
6906644Smckusick 			continue;
6916644Smckusick 		*p++ = c;
6926644Smckusick 		if (p >= &linebuf[LBSIZE-2])
6936644Smckusick 			error(Q);
6946644Smckusick 	}
6956644Smckusick 	*p++ = 0;
6966644Smckusick 	if (linebuf[0]=='.' && linebuf[1]==0)
6976644Smckusick 		return(EOF);
6986644Smckusick 	return(0);
6996644Smckusick }
7006644Smckusick 
getfile()7016644Smckusick getfile()
7026644Smckusick {
7036644Smckusick 	register c;
7046644Smckusick 	register char *lp, *fp;
7056644Smckusick 
7066644Smckusick 	lp = linebuf;
7076644Smckusick 	fp = nextip;
7086644Smckusick 	do {
7096644Smckusick 		if (--ninbuf < 0) {
7106644Smckusick 			if ((ninbuf = read(io, genbuf, LBSIZE)-1) < 0)
7116644Smckusick 				return(EOF);
7126644Smckusick 			fp = genbuf;
7136644Smckusick 			while(fp < &genbuf[ninbuf]) {
7146644Smckusick 				if (*fp++ & 0200) {
715*66633Sbostic #ifdef CRYPT
716*66633Sbostic 					if (kflag)
717*66633Sbostic 						crblock(perm, genbuf, ninbuf+1, count);
718*66633Sbostic #endif CRYPT
7196644Smckusick 					break;
7206644Smckusick 				}
7216644Smckusick 			}
7226644Smckusick 			fp = genbuf;
7236644Smckusick 		}
7246644Smckusick 		c = *fp++;
7256644Smckusick 		if (c=='\0')
7266644Smckusick 			continue;
7276644Smckusick 		if (c&0200 || lp >= &linebuf[LBSIZE]) {
7286644Smckusick 			lastc = '\n';
7296644Smckusick 			error(Q);
7306644Smckusick 		}
7316644Smckusick 		*lp++ = c;
7326644Smckusick 		count++;
7336644Smckusick 	} while (c != '\n');
7346644Smckusick 	*--lp = 0;
7356644Smckusick 	nextip = fp;
7366644Smckusick 	return(0);
7376644Smckusick }
7386644Smckusick 
putfile()7396644Smckusick putfile()
7406644Smckusick {
7416644Smckusick 	int *a1, n;
7426644Smckusick 	register char *fp, *lp;
7436644Smckusick 	register nib;
7446644Smckusick 
7456644Smckusick 	nib = 512;
7466644Smckusick 	fp = genbuf;
7476644Smckusick 	a1 = addr1;
7486644Smckusick 	do {
7496644Smckusick 		lp = getline(*a1++);
7506644Smckusick 		for (;;) {
7516644Smckusick 			if (--nib < 0) {
7526644Smckusick 				n = fp-genbuf;
753*66633Sbostic #ifdef CRYPT
754*66633Sbostic 				if(kflag)
755*66633Sbostic 					crblock(perm, genbuf, n, count-n);
756*66633Sbostic #endif CRYPT
7576644Smckusick 				if(write(io, genbuf, n) != n) {
7586644Smckusick 					puts(WRERR);
7596644Smckusick 					error(Q);
7606644Smckusick 				}
7616644Smckusick 				nib = 511;
7626644Smckusick 				fp = genbuf;
7636644Smckusick 			}
7646644Smckusick 			count++;
7656644Smckusick 			if ((*fp++ = *lp++) == 0) {
7666644Smckusick 				fp[-1] = '\n';
7676644Smckusick 				break;
7686644Smckusick 			}
7696644Smckusick 		}
7706644Smckusick 	} while (a1 <= addr2);
7716644Smckusick 	n = fp-genbuf;
772*66633Sbostic #ifdef CRYPT
773*66633Sbostic 	if(kflag)
774*66633Sbostic 		crblock(perm, genbuf, n, count-n);
775*66633Sbostic #endif CRYPT
7766644Smckusick 	if(write(io, genbuf, n) != n) {
7776644Smckusick 		puts(WRERR);
7786644Smckusick 		error(Q);
7796644Smckusick 	}
7806644Smckusick }
7816644Smckusick 
append(f,a)7826644Smckusick append(f, a)
7836644Smckusick int *a;
7846644Smckusick int (*f)();
7856644Smckusick {
7866644Smckusick 	register *a1, *a2, *rdot;
7876644Smckusick 	int nline, tl;
7886644Smckusick 
7896644Smckusick 	nline = 0;
7906644Smckusick 	dot = a;
7916644Smckusick 	while ((*f)() == 0) {
7926644Smckusick 		if ((dol-zero)+1 >= nlall) {
7936644Smckusick 			int *ozero = zero;
7946644Smckusick 			nlall += 512;
7956644Smckusick 			if ((zero = (int *)realloc((char *)zero, nlall*sizeof(int)))==NULL) {
7966644Smckusick 				lastc = '\n';
7976644Smckusick 				zero = ozero;
7986644Smckusick 				error("MEM?");
7996644Smckusick 			}
8006644Smckusick 			dot += zero - ozero;
8016644Smckusick 			dol += zero - ozero;
8026644Smckusick 		}
8036644Smckusick 		tl = putline();
8046644Smckusick 		nline++;
8056644Smckusick 		a1 = ++dol;
8066644Smckusick 		a2 = a1+1;
8076644Smckusick 		rdot = ++dot;
8086644Smckusick 		while (a1 > rdot)
8096644Smckusick 			*--a2 = *--a1;
8106644Smckusick 		*rdot = tl;
8116644Smckusick 	}
8126644Smckusick 	return(nline);
8136644Smckusick }
8146644Smckusick 
callunix()8156644Smckusick callunix()
8166644Smckusick {
81739154Sbostic 	register sig_t savint;
81839154Sbostic 	register int pid, rpid;
8196644Smckusick 	int retcode;
8206644Smckusick 
8216644Smckusick 	setnoaddr();
8226644Smckusick 	if ((pid = fork()) == 0) {
8236644Smckusick 		signal(SIGHUP, oldhup);
8246644Smckusick 		signal(SIGQUIT, oldquit);
82537029Sbostic 		execl(_PATH_BSHELL, "sh", "-t", 0);
8266644Smckusick 		exit(0100);
8276644Smckusick 	}
8286644Smckusick 	savint = signal(SIGINT, SIG_IGN);
8296644Smckusick 	while ((rpid = wait(&retcode)) != pid && rpid != -1)
8306644Smckusick 		;
8316644Smckusick 	signal(SIGINT, savint);
8326644Smckusick 	puts("!");
8336644Smckusick }
8346644Smckusick 
83539154Sbostic void
quit()8366644Smckusick quit()
8376644Smckusick {
8386644Smckusick 	if (vflag && fchange && dol!=zero) {
8396644Smckusick 		fchange = 0;
8406644Smckusick 		error(Q);
8416644Smckusick 	}
8426644Smckusick 	unlink(tfname);
8436644Smckusick 	exit(0);
8446644Smckusick }
8456644Smckusick 
delete()8466644Smckusick delete()
8476644Smckusick {
8486644Smckusick 	setdot();
8496644Smckusick 	newline();
8506644Smckusick 	nonzero();
8516644Smckusick 	rdelete(addr1, addr2);
8526644Smckusick }
8536644Smckusick 
rdelete(ad1,ad2)8546644Smckusick rdelete(ad1, ad2)
8556644Smckusick int *ad1, *ad2;
8566644Smckusick {
8576644Smckusick 	register *a1, *a2, *a3;
8586644Smckusick 
8596644Smckusick 	a1 = ad1;
8606644Smckusick 	a2 = ad2+1;
8616644Smckusick 	a3 = dol;
8626644Smckusick 	dol -= a2 - a1;
8636644Smckusick 	do {
8646644Smckusick 		*a1++ = *a2++;
8656644Smckusick 	} while (a2 <= a3);
8666644Smckusick 	a1 = ad1;
8676644Smckusick 	if (a1 > dol)
8686644Smckusick 		a1 = dol;
8696644Smckusick 	dot = a1;
8706644Smckusick 	fchange = 1;
8716644Smckusick }
8726644Smckusick 
gdelete()8736644Smckusick gdelete()
8746644Smckusick {
8756644Smckusick 	register *a1, *a2, *a3;
8766644Smckusick 
8776644Smckusick 	a3 = dol;
8786644Smckusick 	for (a1=zero+1; (*a1&01)==0; a1++)
8796644Smckusick 		if (a1>=a3)
8806644Smckusick 			return;
8816644Smckusick 	for (a2=a1+1; a2<=a3;) {
8826644Smckusick 		if (*a2&01) {
8836644Smckusick 			a2++;
8846644Smckusick 			dot = a1;
8856644Smckusick 		} else
8866644Smckusick 			*a1++ = *a2++;
8876644Smckusick 	}
8886644Smckusick 	dol = a1-1;
8896644Smckusick 	if (dot>dol)
8906644Smckusick 		dot = dol;
8916644Smckusick 	fchange = 1;
8926644Smckusick }
8936644Smckusick 
8946644Smckusick char *
getline(tl)8956644Smckusick getline(tl)
8966644Smckusick {
8976644Smckusick 	register char *bp, *lp;
8986644Smckusick 	register nl;
8996644Smckusick 
9006644Smckusick 	lp = linebuf;
9016644Smckusick 	bp = getblock(tl, READ);
9026644Smckusick 	nl = nleft;
9036644Smckusick 	tl &= ~0377;
9046644Smckusick 	while (*lp++ = *bp++)
9056644Smckusick 		if (--nl == 0) {
9066644Smckusick 			bp = getblock(tl+=0400, READ);
9076644Smckusick 			nl = nleft;
9086644Smckusick 		}
9096644Smckusick 	return(linebuf);
9106644Smckusick }
9116644Smckusick 
putline()9126644Smckusick putline()
9136644Smckusick {
9146644Smckusick 	register char *bp, *lp;
9156644Smckusick 	register nl;
9166644Smckusick 	int tl;
9176644Smckusick 
9186644Smckusick 	fchange = 1;
9196644Smckusick 	lp = linebuf;
9206644Smckusick 	tl = tline;
9216644Smckusick 	bp = getblock(tl, WRITE);
9226644Smckusick 	nl = nleft;
9236644Smckusick 	tl &= ~0377;
9246644Smckusick 	while (*bp = *lp++) {
9256644Smckusick 		if (*bp++ == '\n') {
9266644Smckusick 			*--bp = 0;
9276644Smckusick 			linebp = lp;
9286644Smckusick 			break;
9296644Smckusick 		}
9306644Smckusick 		if (--nl == 0) {
9316644Smckusick 			bp = getblock(tl+=0400, WRITE);
9326644Smckusick 			nl = nleft;
9336644Smckusick 		}
9346644Smckusick 	}
9356644Smckusick 	nl = tline;
9366644Smckusick 	tline += (((lp-linebuf)+03)>>1)&077776;
9376644Smckusick 	return(nl);
9386644Smckusick }
9396644Smckusick 
9406644Smckusick char *
getblock(atl,iof)9416644Smckusick getblock(atl, iof)
9426644Smckusick {
9436644Smckusick 	extern read(), write();
9446644Smckusick 	register bno, off;
9456644Smckusick 	register char *p1, *p2;
9466644Smckusick 	register int n;
9476644Smckusick 
9486644Smckusick 	bno = (atl>>8)&0377;
9496644Smckusick 	off = (atl<<1)&0774;
9506644Smckusick 	if (bno >= 255) {
9516644Smckusick 		lastc = '\n';
9526644Smckusick 		error(T);
9536644Smckusick 	}
9546644Smckusick 	nleft = 512 - off;
9556644Smckusick 	if (bno==iblock) {
9566644Smckusick 		ichanged |= iof;
9576644Smckusick 		return(ibuff+off);
9586644Smckusick 	}
9596644Smckusick 	if (bno==oblock)
9606644Smckusick 		return(obuff+off);
9616644Smckusick 	if (iof==READ) {
9626644Smckusick 		if (ichanged) {
963*66633Sbostic #ifdef CRYPT
964*66633Sbostic 			if(xtflag)
965*66633Sbostic 				crblock(tperm, ibuff, 512, (long)0);
966*66633Sbostic #endif CRYPT
9676644Smckusick 			blkio(iblock, ibuff, write);
9686644Smckusick 		}
9696644Smckusick 		ichanged = 0;
9706644Smckusick 		iblock = bno;
9716644Smckusick 		blkio(bno, ibuff, read);
972*66633Sbostic #ifdef CRYPT
973*66633Sbostic 		if(xtflag)
974*66633Sbostic 			crblock(tperm, ibuff, 512, (long)0);
975*66633Sbostic #endif CRYPT
9766644Smckusick 		return(ibuff+off);
9776644Smckusick 	}
9786644Smckusick 	if (oblock>=0) {
979*66633Sbostic #ifdef CRYPT
980*66633Sbostic 		if(xtflag) {
981*66633Sbostic 			p1 = obuff;
982*66633Sbostic 			p2 = crbuf;
983*66633Sbostic 			n = 512;
984*66633Sbostic 			while(n--)
985*66633Sbostic 				*p2++ = *p1++;
986*66633Sbostic 			crblock(tperm, crbuf, 512, (long)0);
987*66633Sbostic 			blkio(oblock, crbuf, write);
988*66633Sbostic 		} else
989*66633Sbostic #endif CRYPT
9906644Smckusick 			blkio(oblock, obuff, write);
9916644Smckusick 	}
9926644Smckusick 	oblock = bno;
9936644Smckusick 	return(obuff+off);
9946644Smckusick }
9956644Smckusick 
blkio(b,buf,iofcn)9966644Smckusick blkio(b, buf, iofcn)
9976644Smckusick char *buf;
9986644Smckusick int (*iofcn)();
9996644Smckusick {
10006644Smckusick 	lseek(tfile, (long)b<<9, 0);
10016644Smckusick 	if ((*iofcn)(tfile, buf, 512) != 512) {
10026644Smckusick 		error(T);
10036644Smckusick 	}
10046644Smckusick }
10056644Smckusick 
init()10066644Smckusick init()
10076644Smckusick {
10086644Smckusick 	register *markp;
10096644Smckusick 
10106644Smckusick 	close(tfile);
10116644Smckusick 	tline = 2;
10126644Smckusick 	for (markp = names; markp < &names[26]; )
10136644Smckusick 		*markp++ = 0;
10146644Smckusick 	subnewa = 0;
10156644Smckusick 	anymarks = 0;
10166644Smckusick 	iblock = -1;
10176644Smckusick 	oblock = -1;
10186644Smckusick 	ichanged = 0;
10196644Smckusick 	close(creat(tfname, 0600));
10206644Smckusick 	tfile = open(tfname, 2);
1021*66633Sbostic #ifdef CRYPT
1022*66633Sbostic 	if(xflag) {
1023*66633Sbostic 		xtflag = 1;
1024*66633Sbostic 		makekey(key, tperm);
1025*66633Sbostic 	}
1026*66633Sbostic #endif CRYPT
10276644Smckusick 	dot = dol = zero;
10286644Smckusick }
10296644Smckusick 
global(k)10306644Smckusick global(k)
10316644Smckusick {
10326644Smckusick 	register char *gp;
10336644Smckusick 	register c;
10346644Smckusick 	register int *a1;
10356644Smckusick 	char globuf[GBSIZE];
10366644Smckusick 
10376644Smckusick 	if (globp)
10386644Smckusick 		error(Q);
10396644Smckusick 	setall();
10406644Smckusick 	nonzero();
10416644Smckusick 	if ((c=getchr())=='\n')
10426644Smckusick 		error(Q);
10436644Smckusick 	compile(c);
10446644Smckusick 	gp = globuf;
10456644Smckusick 	while ((c = getchr()) != '\n') {
10466644Smckusick 		if (c==EOF)
10476644Smckusick 			error(Q);
10486644Smckusick 		if (c=='\\') {
10496644Smckusick 			c = getchr();
10506644Smckusick 			if (c!='\n')
10516644Smckusick 				*gp++ = '\\';
10526644Smckusick 		}
10536644Smckusick 		*gp++ = c;
10546644Smckusick 		if (gp >= &globuf[GBSIZE-2])
10556644Smckusick 			error(Q);
10566644Smckusick 	}
10576644Smckusick 	*gp++ = '\n';
10586644Smckusick 	*gp++ = 0;
10596644Smckusick 	for (a1=zero; a1<=dol; a1++) {
10606644Smckusick 		*a1 &= ~01;
10616644Smckusick 		if (a1>=addr1 && a1<=addr2 && execute(0, a1)==k)
10626644Smckusick 			*a1 |= 01;
10636644Smckusick 	}
10646644Smckusick 	/*
10656644Smckusick 	 * Special case: g/.../d (avoid n^2 algorithm)
10666644Smckusick 	 */
10676644Smckusick 	if (globuf[0]=='d' && globuf[1]=='\n' && globuf[2]=='\0') {
10686644Smckusick 		gdelete();
10696644Smckusick 		return;
10706644Smckusick 	}
10716644Smckusick 	for (a1=zero; a1<=dol; a1++) {
10726644Smckusick 		if (*a1 & 01) {
10736644Smckusick 			*a1 &= ~01;
10746644Smckusick 			dot = a1;
10756644Smckusick 			globp = globuf;
10766644Smckusick 			commands();
10776644Smckusick 			a1 = zero;
10786644Smckusick 		}
10796644Smckusick 	}
10806644Smckusick }
10816644Smckusick 
join()10826644Smckusick join()
10836644Smckusick {
10846644Smckusick 	register char *gp, *lp;
10856644Smckusick 	register *a1;
10866644Smckusick 
10876644Smckusick 	gp = genbuf;
10886644Smckusick 	for (a1=addr1; a1<=addr2; a1++) {
10896644Smckusick 		lp = getline(*a1);
10906644Smckusick 		while (*gp = *lp++)
10916644Smckusick 			if (gp++ >= &genbuf[LBSIZE-2])
10926644Smckusick 				error(Q);
10936644Smckusick 	}
10946644Smckusick 	lp = linebuf;
10956644Smckusick 	gp = genbuf;
10966644Smckusick 	while (*lp++ = *gp++)
10976644Smckusick 		;
10986644Smckusick 	*addr1 = putline();
10996644Smckusick 	if (addr1<addr2)
11006644Smckusick 		rdelete(addr1+1, addr2);
11016644Smckusick 	dot = addr1;
11026644Smckusick }
11036644Smckusick 
substitute(inglob)11046644Smckusick substitute(inglob)
11056644Smckusick {
11066644Smckusick 	register *markp, *a1, nl;
11076644Smckusick 	int gsubf;
11086644Smckusick 	int getsub();
11096644Smckusick 
11106644Smckusick 	gsubf = compsub();
11116644Smckusick 	for (a1 = addr1; a1 <= addr2; a1++) {
11126644Smckusick 		int *ozero;
11136644Smckusick 		if (execute(0, a1)==0)
11146644Smckusick 			continue;
11156644Smckusick 		inglob |= 01;
11166644Smckusick 		dosub();
11176644Smckusick 		if (gsubf) {
11186644Smckusick 			while (*loc2) {
11196644Smckusick 				if (execute(1, (int *)0)==0)
11206644Smckusick 					break;
11216644Smckusick 				dosub();
11226644Smckusick 			}
11236644Smckusick 		}
11246644Smckusick 		subnewa = putline();
11256644Smckusick 		*a1 &= ~01;
11266644Smckusick 		if (anymarks) {
11276644Smckusick 			for (markp = names; markp < &names[26]; markp++)
11286644Smckusick 				if (*markp == *a1)
11296644Smckusick 					*markp = subnewa;
11306644Smckusick 		}
11316644Smckusick 		subolda = *a1;
11326644Smckusick 		*a1 = subnewa;
11336644Smckusick 		ozero = zero;
11346644Smckusick 		nl = append(getsub, a1);
11356644Smckusick 		nl += zero-ozero;
11366644Smckusick 		a1 += nl;
11376644Smckusick 		addr2 += nl;
11386644Smckusick 	}
11396644Smckusick 	if (inglob==0)
11406644Smckusick 		error(Q);
11416644Smckusick }
11426644Smckusick 
compsub()11436644Smckusick compsub()
11446644Smckusick {
11456644Smckusick 	register seof, c;
11466644Smckusick 	register char *p;
11476644Smckusick 
11486644Smckusick 	if ((seof = getchr()) == '\n' || seof == ' ')
11496644Smckusick 		error(Q);
11506644Smckusick 	compile(seof);
11516644Smckusick 	p = rhsbuf;
11526644Smckusick 	for (;;) {
11536644Smckusick 		c = getchr();
11546644Smckusick 		if (c=='\\')
11556644Smckusick 			c = getchr() | 0200;
11566644Smckusick 		if (c=='\n') {
11576644Smckusick 			if (globp)
11586644Smckusick 				c |= 0200;
11596644Smckusick 			else
11606644Smckusick 				error(Q);
11616644Smckusick 		}
11626644Smckusick 		if (c==seof)
11636644Smckusick 			break;
11646644Smckusick 		*p++ = c;
11656644Smckusick 		if (p >= &rhsbuf[LBSIZE/2])
11666644Smckusick 			error(Q);
11676644Smckusick 	}
11686644Smckusick 	*p++ = 0;
11696644Smckusick 	if ((peekc = getchr()) == 'g') {
11706644Smckusick 		peekc = 0;
11716644Smckusick 		newline();
11726644Smckusick 		return(1);
11736644Smckusick 	}
11746644Smckusick 	newline();
11756644Smckusick 	return(0);
11766644Smckusick }
11776644Smckusick 
getsub()11786644Smckusick getsub()
11796644Smckusick {
11806644Smckusick 	register char *p1, *p2;
11816644Smckusick 
11826644Smckusick 	p1 = linebuf;
11836644Smckusick 	if ((p2 = linebp) == 0)
11846644Smckusick 		return(EOF);
11856644Smckusick 	while (*p1++ = *p2++)
11866644Smckusick 		;
11876644Smckusick 	linebp = 0;
11886644Smckusick 	return(0);
11896644Smckusick }
11906644Smckusick 
dosub()11916644Smckusick dosub()
11926644Smckusick {
11936644Smckusick 	register char *lp, *sp, *rp;
11946644Smckusick 	int c;
11956644Smckusick 
11966644Smckusick 	lp = linebuf;
11976644Smckusick 	sp = genbuf;
11986644Smckusick 	rp = rhsbuf;
11996644Smckusick 	while (lp < loc1)
12006644Smckusick 		*sp++ = *lp++;
12016644Smckusick 	while (c = *rp++&0377) {
12026644Smckusick 		if (c=='&') {
12036644Smckusick 			sp = place(sp, loc1, loc2);
12046644Smckusick 			continue;
12056644Smckusick 		} else if (c&0200 && (c &= 0177) >='1' && c < nbra+'1') {
12066644Smckusick 			sp = place(sp, braslist[c-'1'], braelist[c-'1']);
12076644Smckusick 			continue;
12086644Smckusick 		}
12096644Smckusick 		*sp++ = c&0177;
12106644Smckusick 		if (sp >= &genbuf[LBSIZE])
12116644Smckusick 			error(Q);
12126644Smckusick 	}
12136644Smckusick 	lp = loc2;
12146644Smckusick 	loc2 = sp - genbuf + linebuf;
12156644Smckusick 	while (*sp++ = *lp++)
12166644Smckusick 		if (sp >= &genbuf[LBSIZE])
12176644Smckusick 			error(Q);
12186644Smckusick 	lp = linebuf;
12196644Smckusick 	sp = genbuf;
12206644Smckusick 	while (*lp++ = *sp++)
12216644Smckusick 		;
12226644Smckusick }
12236644Smckusick 
12246644Smckusick char *
place(sp,l1,l2)12256644Smckusick place(sp, l1, l2)
12266644Smckusick register char *sp, *l1, *l2;
12276644Smckusick {
12286644Smckusick 
12296644Smckusick 	while (l1 < l2) {
12306644Smckusick 		*sp++ = *l1++;
12316644Smckusick 		if (sp >= &genbuf[LBSIZE])
12326644Smckusick 			error(Q);
12336644Smckusick 	}
12346644Smckusick 	return(sp);
12356644Smckusick }
12366644Smckusick 
move(cflag)12376644Smckusick move(cflag)
12386644Smckusick {
12396644Smckusick 	register int *adt, *ad1, *ad2;
12406644Smckusick 	int getcopy();
12416644Smckusick 
12426644Smckusick 	setdot();
12436644Smckusick 	nonzero();
12446644Smckusick 	if ((adt = address())==0)
12456644Smckusick 		error(Q);
12466644Smckusick 	newline();
12476644Smckusick 	if (cflag) {
12486644Smckusick 		int *ozero, delta;
12496644Smckusick 		ad1 = dol;
12506644Smckusick 		ozero = zero;
12516644Smckusick 		append(getcopy, ad1++);
12526644Smckusick 		ad2 = dol;
12536644Smckusick 		delta = zero - ozero;
12546644Smckusick 		ad1 += delta;
12556644Smckusick 		adt += delta;
12566644Smckusick 	} else {
12576644Smckusick 		ad2 = addr2;
12586644Smckusick 		for (ad1 = addr1; ad1 <= ad2;)
12596644Smckusick 			*ad1++ &= ~01;
12606644Smckusick 		ad1 = addr1;
12616644Smckusick 	}
12626644Smckusick 	ad2++;
12636644Smckusick 	if (adt<ad1) {
12646644Smckusick 		dot = adt + (ad2-ad1);
12656644Smckusick 		if ((++adt)==ad1)
12666644Smckusick 			return;
12676644Smckusick 		reverse(adt, ad1);
12686644Smckusick 		reverse(ad1, ad2);
12696644Smckusick 		reverse(adt, ad2);
12706644Smckusick 	} else if (adt >= ad2) {
12716644Smckusick 		dot = adt++;
12726644Smckusick 		reverse(ad1, ad2);
12736644Smckusick 		reverse(ad2, adt);
12746644Smckusick 		reverse(ad1, adt);
12756644Smckusick 	} else
12766644Smckusick 		error(Q);
12776644Smckusick 	fchange = 1;
12786644Smckusick }
12796644Smckusick 
reverse(a1,a2)12806644Smckusick reverse(a1, a2)
12816644Smckusick register int *a1, *a2;
12826644Smckusick {
12836644Smckusick 	register int t;
12846644Smckusick 
12856644Smckusick 	for (;;) {
12866644Smckusick 		t = *--a2;
12876644Smckusick 		if (a2 <= a1)
12886644Smckusick 			return;
12896644Smckusick 		*a2 = *a1;
12906644Smckusick 		*a1++ = t;
12916644Smckusick 	}
12926644Smckusick }
12936644Smckusick 
getcopy()12946644Smckusick getcopy()
12956644Smckusick {
12966644Smckusick 	if (addr1 > addr2)
12976644Smckusick 		return(EOF);
12986644Smckusick 	getline(*addr1++);
12996644Smckusick 	return(0);
13006644Smckusick }
13016644Smckusick 
compile(aeof)13026644Smckusick compile(aeof)
13036644Smckusick {
13046644Smckusick 	register eof, c;
13056644Smckusick 	register char *ep;
13066644Smckusick 	char *lastep;
13076644Smckusick 	char bracket[NBRA], *bracketp;
13086644Smckusick 	int cclcnt;
13096644Smckusick 
13106644Smckusick 	ep = expbuf;
13116644Smckusick 	eof = aeof;
13126644Smckusick 	bracketp = bracket;
13136644Smckusick 	if ((c = getchr()) == eof) {
13146644Smckusick 		if (*ep==0)
13156644Smckusick 			error(Q);
13166644Smckusick 		return;
13176644Smckusick 	}
13186644Smckusick 	circfl = 0;
13196644Smckusick 	nbra = 0;
13206644Smckusick 	if (c=='^') {
13216644Smckusick 		c = getchr();
13226644Smckusick 		circfl++;
13236644Smckusick 	}
13246644Smckusick 	peekc = c;
13256644Smckusick 	lastep = 0;
13266644Smckusick 	for (;;) {
13276644Smckusick 		if (ep >= &expbuf[ESIZE])
13286644Smckusick 			goto cerror;
13296644Smckusick 		c = getchr();
13306644Smckusick 		if (c==eof) {
13316644Smckusick 			if (bracketp != bracket)
13326644Smckusick 				goto cerror;
13336644Smckusick 			*ep++ = CEOF;
13346644Smckusick 			return;
13356644Smckusick 		}
13366644Smckusick 		if (c!='*')
13376644Smckusick 			lastep = ep;
13386644Smckusick 		switch (c) {
13396644Smckusick 
13406644Smckusick 		case '\\':
13416644Smckusick 			if ((c = getchr())=='(') {
13426644Smckusick 				if (nbra >= NBRA)
13436644Smckusick 					goto cerror;
13446644Smckusick 				*bracketp++ = nbra;
13456644Smckusick 				*ep++ = CBRA;
13466644Smckusick 				*ep++ = nbra++;
13476644Smckusick 				continue;
13486644Smckusick 			}
13496644Smckusick 			if (c == ')') {
13506644Smckusick 				if (bracketp <= bracket)
13516644Smckusick 					goto cerror;
13526644Smckusick 				*ep++ = CKET;
13536644Smckusick 				*ep++ = *--bracketp;
13546644Smckusick 				continue;
13556644Smckusick 			}
13566644Smckusick 			if (c>='1' && c<'1'+NBRA) {
13576644Smckusick 				*ep++ = CBACK;
13586644Smckusick 				*ep++ = c-'1';
13596644Smckusick 				continue;
13606644Smckusick 			}
13616644Smckusick 			*ep++ = CCHR;
13626644Smckusick 			if (c=='\n')
13636644Smckusick 				goto cerror;
13646644Smckusick 			*ep++ = c;
13656644Smckusick 			continue;
13666644Smckusick 
13676644Smckusick 		case '.':
13686644Smckusick 			*ep++ = CDOT;
13696644Smckusick 			continue;
13706644Smckusick 
13716644Smckusick 		case '\n':
13726644Smckusick 			goto cerror;
13736644Smckusick 
13746644Smckusick 		case '*':
13756644Smckusick 			if (lastep==0 || *lastep==CBRA || *lastep==CKET)
13766644Smckusick 				goto defchar;
13776644Smckusick 			*lastep |= STAR;
13786644Smckusick 			continue;
13796644Smckusick 
13806644Smckusick 		case '$':
13816644Smckusick 			if ((peekc=getchr()) != eof)
13826644Smckusick 				goto defchar;
13836644Smckusick 			*ep++ = CDOL;
13846644Smckusick 			continue;
13856644Smckusick 
13866644Smckusick 		case '[':
13876644Smckusick 			*ep++ = CCL;
13886644Smckusick 			*ep++ = 0;
13896644Smckusick 			cclcnt = 1;
13906644Smckusick 			if ((c=getchr()) == '^') {
13916644Smckusick 				c = getchr();
13926644Smckusick 				ep[-2] = NCCL;
13936644Smckusick 			}
13946644Smckusick 			do {
13956644Smckusick 				if (c=='\n')
13966644Smckusick 					goto cerror;
13976644Smckusick 				if (c=='-' && ep[-1]!=0) {
13986644Smckusick 					if ((c=getchr())==']') {
13996644Smckusick 						*ep++ = '-';
14006644Smckusick 						cclcnt++;
14016644Smckusick 						break;
14026644Smckusick 					}
14036644Smckusick 					while (ep[-1]<c) {
14046644Smckusick 						*ep = ep[-1]+1;
14056644Smckusick 						ep++;
14066644Smckusick 						cclcnt++;
14076644Smckusick 						if (ep>=&expbuf[ESIZE])
14086644Smckusick 							goto cerror;
14096644Smckusick 					}
14106644Smckusick 				}
14116644Smckusick 				*ep++ = c;
14126644Smckusick 				cclcnt++;
14136644Smckusick 				if (ep >= &expbuf[ESIZE])
14146644Smckusick 					goto cerror;
14156644Smckusick 			} while ((c = getchr()) != ']');
14166644Smckusick 			lastep[1] = cclcnt;
14176644Smckusick 			continue;
14186644Smckusick 
14196644Smckusick 		defchar:
14206644Smckusick 		default:
14216644Smckusick 			*ep++ = CCHR;
14226644Smckusick 			*ep++ = c;
14236644Smckusick 		}
14246644Smckusick 	}
14256644Smckusick    cerror:
14266644Smckusick 	expbuf[0] = 0;
14276644Smckusick 	nbra = 0;
14286644Smckusick 	error(Q);
14296644Smckusick }
14306644Smckusick 
execute(gf,addr)14316644Smckusick execute(gf, addr)
14326644Smckusick int *addr;
14336644Smckusick {
14346644Smckusick 	register char *p1, *p2, c;
14356644Smckusick 
14366644Smckusick 	for (c=0; c<NBRA; c++) {
14376644Smckusick 		braslist[c] = 0;
14386644Smckusick 		braelist[c] = 0;
14396644Smckusick 	}
14406644Smckusick 	if (gf) {
14416644Smckusick 		if (circfl)
14426644Smckusick 			return(0);
14436644Smckusick 		p1 = linebuf;
14446644Smckusick 		p2 = genbuf;
14456644Smckusick 		while (*p1++ = *p2++)
14466644Smckusick 			;
14476644Smckusick 		locs = p1 = loc2;
14486644Smckusick 	} else {
14496644Smckusick 		if (addr==zero)
14506644Smckusick 			return(0);
14516644Smckusick 		p1 = getline(*addr);
14526644Smckusick 		locs = 0;
14536644Smckusick 	}
14546644Smckusick 	p2 = expbuf;
14556644Smckusick 	if (circfl) {
14566644Smckusick 		loc1 = p1;
14576644Smckusick 		return(advance(p1, p2));
14586644Smckusick 	}
14596644Smckusick 	/* fast check for first character */
14606644Smckusick 	if (*p2==CCHR) {
14616644Smckusick 		c = p2[1];
14626644Smckusick 		do {
14636644Smckusick 			if (*p1!=c)
14646644Smckusick 				continue;
14656644Smckusick 			if (advance(p1, p2)) {
14666644Smckusick 				loc1 = p1;
14676644Smckusick 				return(1);
14686644Smckusick 			}
14696644Smckusick 		} while (*p1++);
14706644Smckusick 		return(0);
14716644Smckusick 	}
14726644Smckusick 	/* regular algorithm */
14736644Smckusick 	do {
14746644Smckusick 		if (advance(p1, p2)) {
14756644Smckusick 			loc1 = p1;
14766644Smckusick 			return(1);
14776644Smckusick 		}
14786644Smckusick 	} while (*p1++);
14796644Smckusick 	return(0);
14806644Smckusick }
14816644Smckusick 
advance(lp,ep)14826644Smckusick advance(lp, ep)
14836644Smckusick register char *ep, *lp;
14846644Smckusick {
14856644Smckusick 	register char *curlp;
14866644Smckusick 	int i;
14876644Smckusick 
14886644Smckusick 	for (;;) switch (*ep++) {
14896644Smckusick 
14906644Smckusick 	case CCHR:
14916644Smckusick 		if (*ep++ == *lp++)
14926644Smckusick 			continue;
14936644Smckusick 		return(0);
14946644Smckusick 
14956644Smckusick 	case CDOT:
14966644Smckusick 		if (*lp++)
14976644Smckusick 			continue;
14986644Smckusick 		return(0);
14996644Smckusick 
15006644Smckusick 	case CDOL:
15016644Smckusick 		if (*lp==0)
15026644Smckusick 			continue;
15036644Smckusick 		return(0);
15046644Smckusick 
15056644Smckusick 	case CEOF:
15066644Smckusick 		loc2 = lp;
15076644Smckusick 		return(1);
15086644Smckusick 
15096644Smckusick 	case CCL:
15106644Smckusick 		if (cclass(ep, *lp++, 1)) {
15116644Smckusick 			ep += *ep;
15126644Smckusick 			continue;
15136644Smckusick 		}
15146644Smckusick 		return(0);
15156644Smckusick 
15166644Smckusick 	case NCCL:
15176644Smckusick 		if (cclass(ep, *lp++, 0)) {
15186644Smckusick 			ep += *ep;
15196644Smckusick 			continue;
15206644Smckusick 		}
15216644Smckusick 		return(0);
15226644Smckusick 
15236644Smckusick 	case CBRA:
15246644Smckusick 		braslist[*ep++] = lp;
15256644Smckusick 		continue;
15266644Smckusick 
15276644Smckusick 	case CKET:
15286644Smckusick 		braelist[*ep++] = lp;
15296644Smckusick 		continue;
15306644Smckusick 
15316644Smckusick 	case CBACK:
15326644Smckusick 		if (braelist[i = *ep++]==0)
15336644Smckusick 			error(Q);
15346644Smckusick 		if (backref(i, lp)) {
15356644Smckusick 			lp += braelist[i] - braslist[i];
15366644Smckusick 			continue;
15376644Smckusick 		}
15386644Smckusick 		return(0);
15396644Smckusick 
15406644Smckusick 	case CBACK|STAR:
15416644Smckusick 		if (braelist[i = *ep++] == 0)
15426644Smckusick 			error(Q);
15436644Smckusick 		curlp = lp;
15446644Smckusick 		while (backref(i, lp))
15456644Smckusick 			lp += braelist[i] - braslist[i];
15466644Smckusick 		while (lp >= curlp) {
15476644Smckusick 			if (advance(lp, ep))
15486644Smckusick 				return(1);
15496644Smckusick 			lp -= braelist[i] - braslist[i];
15506644Smckusick 		}
15516644Smckusick 		continue;
15526644Smckusick 
15536644Smckusick 	case CDOT|STAR:
15546644Smckusick 		curlp = lp;
15556644Smckusick 		while (*lp++)
15566644Smckusick 			;
15576644Smckusick 		goto star;
15586644Smckusick 
15596644Smckusick 	case CCHR|STAR:
15606644Smckusick 		curlp = lp;
15616644Smckusick 		while (*lp++ == *ep)
15626644Smckusick 			;
15636644Smckusick 		ep++;
15646644Smckusick 		goto star;
15656644Smckusick 
15666644Smckusick 	case CCL|STAR:
15676644Smckusick 	case NCCL|STAR:
15686644Smckusick 		curlp = lp;
15696644Smckusick 		while (cclass(ep, *lp++, ep[-1]==(CCL|STAR)))
15706644Smckusick 			;
15716644Smckusick 		ep += *ep;
15726644Smckusick 		goto star;
15736644Smckusick 
15746644Smckusick 	star:
15756644Smckusick 		do {
15766644Smckusick 			lp--;
15776644Smckusick 			if (lp==locs)
15786644Smckusick 				break;
15796644Smckusick 			if (advance(lp, ep))
15806644Smckusick 				return(1);
15816644Smckusick 		} while (lp > curlp);
15826644Smckusick 		return(0);
15836644Smckusick 
15846644Smckusick 	default:
15856644Smckusick 		error(Q);
15866644Smckusick 	}
15876644Smckusick }
15886644Smckusick 
backref(i,lp)15896644Smckusick backref(i, lp)
15906644Smckusick register i;
15916644Smckusick register char *lp;
15926644Smckusick {
15936644Smckusick 	register char *bp;
15946644Smckusick 
15956644Smckusick 	bp = braslist[i];
15966644Smckusick 	while (*bp++ == *lp++)
15976644Smckusick 		if (bp >= braelist[i])
15986644Smckusick 			return(1);
15996644Smckusick 	return(0);
16006644Smckusick }
16016644Smckusick 
cclass(set,c,af)16026644Smckusick cclass(set, c, af)
16036644Smckusick register char *set, c;
16046644Smckusick {
16056644Smckusick 	register n;
16066644Smckusick 
16076644Smckusick 	if (c==0)
16086644Smckusick 		return(0);
16096644Smckusick 	n = *set++;
16106644Smckusick 	while (--n)
16116644Smckusick 		if (*set++ == c)
16126644Smckusick 			return(af);
16136644Smckusick 	return(!af);
16146644Smckusick }
16156644Smckusick 
putd()16166644Smckusick putd()
16176644Smckusick {
16186644Smckusick 	register r;
16196644Smckusick 
16206644Smckusick 	r = count%10;
16216644Smckusick 	count /= 10;
16226644Smckusick 	if (count)
16236644Smckusick 		putd();
16246644Smckusick 	putchr(r + '0');
16256644Smckusick }
16266644Smckusick 
puts(sp)16276644Smckusick puts(sp)
16286644Smckusick register char *sp;
16296644Smckusick {
16306644Smckusick 	col = 0;
16316644Smckusick 	while (*sp)
16326644Smckusick 		putchr(*sp++);
16336644Smckusick 	putchr('\n');
16346644Smckusick }
16356644Smckusick 
16366644Smckusick char	line[70];
16376644Smckusick char	*linp	= line;
16386644Smckusick 
putchr(ac)16396644Smckusick putchr(ac)
16406644Smckusick {
16416644Smckusick 	register char *lp;
16426644Smckusick 	register c;
16436644Smckusick 
16446644Smckusick 	lp = linp;
16456644Smckusick 	c = ac;
16466644Smckusick 	if (listf) {
16476644Smckusick 		col++;
16486644Smckusick 		if (col >= 72) {
16496644Smckusick 			col = 0;
16506644Smckusick 			*lp++ = '\\';
16516644Smckusick 			*lp++ = '\n';
16526644Smckusick 		}
16536644Smckusick 		if (c=='\t') {
16546644Smckusick 			c = '>';
16556644Smckusick 			goto esc;
16566644Smckusick 		}
16576644Smckusick 		if (c=='\b') {
16586644Smckusick 			c = '<';
16596644Smckusick 		esc:
16606644Smckusick 			*lp++ = '-';
16616644Smckusick 			*lp++ = '\b';
16626644Smckusick 			*lp++ = c;
16636644Smckusick 			goto out;
16646644Smckusick 		}
16656644Smckusick 		if (c<' ' && c!= '\n') {
16666644Smckusick 			*lp++ = '\\';
16676644Smckusick 			*lp++ = (c>>3)+'0';
16686644Smckusick 			*lp++ = (c&07)+'0';
16696644Smckusick 			col += 2;
16706644Smckusick 			goto out;
16716644Smckusick 		}
16726644Smckusick 	}
16736644Smckusick 	*lp++ = c;
16746644Smckusick out:
16756644Smckusick 	if(c == '\n' || lp >= &line[64]) {
16766644Smckusick 		linp = line;
16776644Smckusick 		write(1, line, lp-line);
16786644Smckusick 		return;
16796644Smckusick 	}
16806644Smckusick 	linp = lp;
16816644Smckusick }
168229769Smckusick 
1683*66633Sbostic #ifdef CRYPT
1684*66633Sbostic /*
1685*66633Sbostic  * Begin routines for doing encryption.
1686*66633Sbostic  */
crblock(permp,buf,nchar,startn)1687*66633Sbostic crblock(permp, buf, nchar, startn)
1688*66633Sbostic char *permp;
1689*66633Sbostic char *buf;
1690*66633Sbostic long startn;
1691*66633Sbostic {
1692*66633Sbostic 	register char *p1;
1693*66633Sbostic 	int n1;
1694*66633Sbostic 	int n2;
1695*66633Sbostic 	register char *t1, *t2, *t3;
1696*66633Sbostic 
1697*66633Sbostic 	t1 = permp;
1698*66633Sbostic 	t2 = &permp[256];
1699*66633Sbostic 	t3 = &permp[512];
1700*66633Sbostic 
1701*66633Sbostic 	n1 = startn&0377;
1702*66633Sbostic 	n2 = (startn>>8)&0377;
1703*66633Sbostic 	p1 = buf;
1704*66633Sbostic 	while(nchar--) {
1705*66633Sbostic 		*p1 = t2[(t3[(t1[(*p1+n1)&0377]+n2)&0377]-n2)&0377]-n1;
1706*66633Sbostic 		n1++;
1707*66633Sbostic 		if(n1==256){
1708*66633Sbostic 			n1 = 0;
1709*66633Sbostic 			n2++;
1710*66633Sbostic 			if(n2==256) n2 = 0;
1711*66633Sbostic 		}
1712*66633Sbostic 		p1++;
1713*66633Sbostic 	}
1714*66633Sbostic }
1715*66633Sbostic 
getkey()1716*66633Sbostic getkey()
1717*66633Sbostic {
1718*66633Sbostic 	struct sgttyb b;
1719*66633Sbostic 	int save;
1720*66633Sbostic 	sig_t sig;
1721*66633Sbostic 	register char *p;
1722*66633Sbostic 	register c;
1723*66633Sbostic 
1724*66633Sbostic 	sig = signal(SIGINT, SIG_IGN);
1725*66633Sbostic 	if (ioctl(0, TIOCGETP, &b) == -1)
1726*66633Sbostic 		error("Input not tty");
1727*66633Sbostic 	save = b.sg_flags;
1728*66633Sbostic 	b.sg_flags &= ~ECHO;
1729*66633Sbostic 	(void)ioctl(0, TIOCSETP, &b);
1730*66633Sbostic 	puts("Key:");
1731*66633Sbostic 	p = key;
1732*66633Sbostic 	while(((c=getchr()) != EOF) && (c!='\n')) {
1733*66633Sbostic 		if(p < &key[KSIZE])
1734*66633Sbostic 			*p++ = c;
1735*66633Sbostic 	}
1736*66633Sbostic 	*p = 0;
1737*66633Sbostic 	b.sg_flags = save;
1738*66633Sbostic 	(void)ioctl(0, TIOCSETP, &b);
1739*66633Sbostic 	signal(SIGINT, sig);
1740*66633Sbostic 	return(key[0] != 0);
1741*66633Sbostic }
1742*66633Sbostic 
1743*66633Sbostic /*
1744*66633Sbostic  * Besides initializing the encryption machine, this routine
1745*66633Sbostic  * returns 0 if the key is null, and 1 if it is non-null.
1746*66633Sbostic  */
crinit(keyp,permp)1747*66633Sbostic crinit(keyp, permp)
1748*66633Sbostic char	*keyp, *permp;
1749*66633Sbostic {
1750*66633Sbostic 	register char *t1, *t2, *t3;
1751*66633Sbostic 	register i;
1752*66633Sbostic 	int ic, k, temp, pf[2];
1753*66633Sbostic 	unsigned random;
1754*66633Sbostic 	char buf[13];
1755*66633Sbostic 	long seed;
1756*66633Sbostic 
1757*66633Sbostic 	t1 = permp;
1758*66633Sbostic 	t2 = &permp[256];
1759*66633Sbostic 	t3 = &permp[512];
1760*66633Sbostic 	if(*keyp == 0)
1761*66633Sbostic 		return(0);
1762*66633Sbostic 	strncpy(buf, keyp, 8);
1763*66633Sbostic 	while (*keyp)
1764*66633Sbostic 		*keyp++ = '\0';
1765*66633Sbostic 	buf[8] = buf[0];
1766*66633Sbostic 	buf[9] = buf[1];
1767*66633Sbostic 	if (pipe(pf)<0)
1768*66633Sbostic 		pf[0] = pf[1] = -1;
1769*66633Sbostic 	if (fork()==0) {
1770*66633Sbostic 		close(0);
1771*66633Sbostic 		close(1);
1772*66633Sbostic 		dup(pf[0]);
1773*66633Sbostic 		dup(pf[1]);
1774*66633Sbostic 		execl(_PATH_MAKEKEY, "-", 0);
1775*66633Sbostic 		exit(1);
1776*66633Sbostic 	}
1777*66633Sbostic 	write(pf[1], buf, 10);
1778*66633Sbostic 	if (wait((int *)NULL)==-1 || read(pf[0], buf, 13)!=13)
1779*66633Sbostic 		error("crypt: cannot generate key");
1780*66633Sbostic 	close(pf[0]);
1781*66633Sbostic 	close(pf[1]);
1782*66633Sbostic 	seed = 123;
1783*66633Sbostic 	for (i=0; i<13; i++)
1784*66633Sbostic 		seed = seed*buf[i] + i;
1785*66633Sbostic 	for(i=0;i<256;i++){
1786*66633Sbostic 		t1[i] = i;
1787*66633Sbostic 		t3[i] = 0;
1788*66633Sbostic 	}
1789*66633Sbostic 	for(i=0; i<256; i++) {
1790*66633Sbostic 		seed = 5*seed + buf[i%13];
1791*66633Sbostic 		random = seed % 65521;
1792*66633Sbostic 		k = 256-1 - i;
1793*66633Sbostic 		ic = (random&0377) % (k+1);
1794*66633Sbostic 		random >>= 8;
1795*66633Sbostic 		temp = t1[k];
1796*66633Sbostic 		t1[k] = t1[ic];
1797*66633Sbostic 		t1[ic] = temp;
1798*66633Sbostic 		if(t3[k]!=0) continue;
1799*66633Sbostic 		ic = (random&0377) % k;
1800*66633Sbostic 		while(t3[ic]!=0) ic = (ic+1) % k;
1801*66633Sbostic 		t3[k] = ic;
1802*66633Sbostic 		t3[ic] = k;
1803*66633Sbostic 	}
1804*66633Sbostic 	for(i=0; i<256; i++)
1805*66633Sbostic 		t2[t1[i]&0377] = i;
1806*66633Sbostic 	return(1);
1807*66633Sbostic }
1808*66633Sbostic 
makekey(a,b)1809*66633Sbostic makekey(a, b)
1810*66633Sbostic char *a, *b;
1811*66633Sbostic {
1812*66633Sbostic 	register int i;
1813*66633Sbostic 	long t;
1814*66633Sbostic 	char temp[KSIZE + 1];
1815*66633Sbostic 
1816*66633Sbostic 	for(i = 0; i < KSIZE; i++)
1817*66633Sbostic 		temp[i] = *a++;
1818*66633Sbostic 	time(&t);
1819*66633Sbostic 	t += getpid();
1820*66633Sbostic 	for(i = 0; i < 4; i++)
1821*66633Sbostic 		temp[i] ^= (t>>(8*i))&0377;
1822*66633Sbostic 	crinit(temp, b);
1823*66633Sbostic }
1824*66633Sbostic #endif CRYPT
1825