2.9BSD/usr/src/ucb/ex/updates/3.3-3.4

# 3.3-3.4
ed - ex.c << '-*-END-*-'
418a
#ifdef TIOCLGET
		if (dosusp)
			signal(SIGTSTP, onsusp);
#endif
	}
.
413c
	if (ruptible) {
.
362a
	/*
	 * USG tty driver can send multiple HUP's!!
	 */
	signal(SIGINT, SIG_IGN);
	signal(SIGHUP, SIG_IGN);
.
347a
        if(xflag) {
                xtflag = 1;
                makekey(key, tperm);
        }
.
344a
#ifdef USG
	signal (SIGHUP, SIG_IGN);
#endif
#ifdef USG3TTY
#ifndef USG
	signal (SIGHUP, SIG_IGN);
#endif
#endif
.
272,273c
		else {
			globp = 0;
			if ((cp = getenv("HOME")) != 0 && *cp)
				source(strcat(strcpy(genbuf, cp), "/.exrc"), 1);
		}
.
270c
		if ((globp = getenv("EXINIT")) && *globp)
.
265c
			if ((cp = getenv("TERM")) != 0 && *cp)
.
260a
		if (cp = getenv("SHELL"))
			CP(shell, cp);
.
225a
	if(xflag){
		key = getpass(KEYPROMPT);
		kflag = crinit(key, perm);
	}

.
214a
		case 'x':
			/* -x: encrypted mode */
			xflag = 1;
			break;

.
163a
		case 'R':
			value(READONLY) = 1;
			break;

.
139a
#ifdef TIOCLGET
	if (signal(SIGTSTP, SIG_IGN) == SIG_DFL)
		signal(SIGTSTP, onsusp), dosusp++;
#endif
.
118a
	 * For debugging take files out of . if name is a.out.
	 */
	if (av[0][0] == 'a')
		erpath = tailpath(erpath);
#endif
	/*
.
117a
#ifndef VMUNIX
.
104,112c
	ivis = any('v', av[0]);	/* "vi" */
	if (any('w', av[0]))	/* "view" */
		value(READONLY) = 1;
	if (any('d', av[0])) {	/* "edit" */
.
101,102c
	 * Figure out how we were invoked: ex, edit, vi, view.
.
98d
94c
	 * Defend against d's, v's, w's, and a's in directories of
.
91a
#else
	normf = tty;
#endif
.
90a
#ifndef USG3TTY
.
62,67c
 * in the routine commands.  We are entered as either "ex", "edit", "vi"
 * or "view" and the distinction is made here.  Actually, we are "vi" if
 * there is a 'v' in our name, "view" is there is a 'w', and "edit" if
 * there is a 'd' in our name.  For edit we just diddle options;
 * for vi we actually force an early visual command.
.
54a
 * ex_unix.c		Routines for the ! command and its variations.
 *
.
w
q
'-*-END-*-'
ed - ex.h << '-*-END-*-'
335a
int	onsusp();
.
279a
 * Various miscellaneous flags and buffers needed by the encryption routines.
 */
#define	KSIZE   9       /* key size for encryption */
#define	KEYPROMPT       "Key: "
int	xflag;		/* True if we are in encryption mode */
int	xtflag;		/* True if the temp file is being encrypted */
int	kflag;		/* True if the key has been accepted */
char	perm[768];
char	tperm[768];
char	*key;
char	crbuf[CRSIZE];
char	*getpass();

/*
.
175a
short	oprompt;		/* Saved during source */
.
156a
bool	inappend;		/* in ex command append mode */
.
144a
#ifdef TIOCLGET
bool	dosusp;			/* Do SIGTSTP in visual when ^Z typed */
#endif
.
50a
/*
 *	The following little dance copes with the new USG tty handling.
 *	This stuff has the advantage of considerable flexibility, and
 *	the disadvantage of being incompatible with anything else.
 *	The presence of the symbol USG3TTY will indicate the new code:
 *	in this case, we define CBREAK (because we can simulate it exactly),
 *	but we won't actually use it, so we set it to a value that will
 *	probably blow the compilation if we goof up.
 */
#ifdef USG3TTY
#include <termio.h>
#define CBREAK xxxxx
#else
#include <sgtty.h>
#endif

.
46d
39c
 * or to csvax.mark@berkeley on the ARPA-net.  I would particularly like to hear
.
32c
 *	Mark Horton
.
7c
 * Ex version 3 (see exact version in ex_cmds.c, search for /Version/)
.
w
q
'-*-END-*-'
ed - ex_addr.c << '-*-END-*-'
204a
						if (loc1 == loc2)
							loc2++;
.
197a
					}
.
195c
					while (loc1 <= inline) {
						if (loc1 == loc2)
							loc2++;
.
w
q
'-*-END-*-'
ed - ex_cmds.c << '-*-END-*-'
758a
			vmacchng(0);
.
747c
				vclrech(1);	/* vcontin(0); */
.
737a
				vmacchng(0);
.
716a
/* " */
		case '"':
			comment();
			continue;

.
651a
			vmacchng(0);
.
606a
				if (inopen) {
					c = 'e';
					goto editcmd;
				}
.
600c
				printf("Version 3.4, June 24, 1980");
.
579a
/* unabbreviate */
				case 'a':
					tail2of("unabbreviate");
					setnoaddr();
					mapcmd(1, 1);
					anyabbrs = 1;
					continue;
.
578c
					mapcmd(1, 0);
.
575c
				switch(peekchar()) {
/* unmap */
				case 'm':
.
573d
567a
			vmacchng(0);
.
551a
			vmacchng(0);
.
540a
#ifdef TIOCLGET
/* stop */
			case 't':
				tail("stop");
				if (!ldisc)
					error("Old tty driver|Not using new tty driver/shell");
				c = exclam();
				eol();
				if (!c)
					ckaw();
				eol();
				onsusp();
				continue;
#endif

.
491a
			vmacchng(0);
.
451a
					ckaw();
					ignore(quickly());
.
450d
433a
					*/
.
431a
					tostop();
					/* replaced by tostop
.
381a
				vmacchng(0);
.
343a
			vmacchng(0);
.
335c
					mapcmd(0, 0);
.
298a
			vmacchng(0);
.
286a
			inappend = 0;
.
285a
			inappend = 1;
.
283a
			vmacchng(0);
.
239a
editcmd:
.
229a
			vmacchng(0);
.
218a
			inappend = 0;
.
217a
			inappend = 1;
.
215a
			vmacchng(0);
.
167a
				vmacchng(0);
.
158a
			inappend = 0;
.
157a
			inappend = 1;
.
155a
			vmacchng(0);
.
140c
			switch(peekchar()) {
			case 'b':
/* abbreviate */
				tail("abbreviate");
				setnoaddr();
				mapcmd(0, 1);
				anyabbrs = 1;
				continue;
			case 'r':
.
w
q
'-*-END-*-'
ed - ex_cmds2.c << '-*-END-*-'
529a
		*/
.
527a
		tostop();
		/* replaced by the ostop above
.
509a
			*/
.
507a
			tostart();
			/* replaced by ostart.
.
506c
		if (Peekkey != ':') {
.
381c
	return (endcmd(peekchar()) && peekchar() != '"');
.
279a
		case '"':
			comment();
			setflav();
			return;

.
234a
	isalt = (strcmp(altfile, args)==0) + 1;
.
230a
	extern short isalt;	/* defined in ex_io.c */
.
161c
	inappend = inglobal = 0;
.
136a
		*/
.
134a
		/* ostop should be doing this
.
121,124d
104a
	if (laste) {
		laste = 0;
		sync();
	}
.
41a
	case '"':
.
w
q
'-*-END-*-'
ed - ex_cmdsub.c << '-*-END-*-'
1173c
			if (eq(src, mp[slot].cap) || eq(src, mp[slot].mapto))
.
1136a
#ifdef TRACE
	if (trace)
		fprintf(trace, "addmac(src='%s', dest='%s', dname='%s', mp=%x\n", src, dest, dname, mp);
#endif
.
1096c
		} else if (endcmd(c) && c!='"') {
.
1080a
				*p = 0;
.
1072,1077c
		} else if (!un && any(c, " \t")) {
			/* End of lhs */
			break;
		} else if (endcmd(c) && c!='"') {
.
1052a
		if (un)
			error("Missing lhs");
.
1046c
	mp = ab ? abbrevs : exclam() ? immacs : arrows;
.
1040c
	char lhs[100], rhs[100];	/* max sizes resp. */
.
1038a
	int ab;	/* true if this is abbr command */
.
1037c
mapcmd(un, ab)
.
988c
	/*
	 * Defensive programming - after a munged undadot.
	 * Also handle empty buffer case.
	 */
	if ((dot <= zero || dot > dol) && dot != dol)
.
585c
					extern char *ncols['z'-'a'+2];
.
562a
			/* Rest of tag if abbreviated */
			while (!iswhite(*cp))
				cp++;

.
544c
			if ((*lp || !iswhite(*cp)) && (value(TAGLENGTH)==0 || lp-lasttag < value(TAGLENGTH))) {
.
526a
		tfcount++;
.
216a
	if (FIXUNDO)
		vundkind = VMANY;
.
215a
	if (FIXUNDO)
		undap1 = undap2 = addr1;
.
14a
static	jnoop();
.
5a
#include "ex_vis.h"
.
w
q
'-*-END-*-'
ed - ex_data.c << '-*-END-*-'
69d
64a
	"taglength",	"tl",	NUMERIC,	0,	0,	0,
	"tags",		"tag",	STRING,		0,	0,	tags,
.
63d
53a
	"readonly",	"ro",	ONOFF,		0,	0,	0,
.
48a
	"mesg",		0,	ONOFF,		1,	1,	0,
.
w
q
'-*-END-*-'
ed - ex_io.c << '-*-END-*-'
973a
	if (slevel <= 0)
		ttyindes = saveinp;
.
968d
960c
short slevel;
short ttyindes;
.
936a
	if(kflag)
		crblock(perm, genbuf, nib, cntch);
.
922a
                		if(kflag)
                                        crblock(perm, genbuf, nib, cntch);
.
894d
876a
			while(fp < &genbuf[ninbuf]) {
				if (*fp++ & 0200) {
					if (kflag)
						crblock(perm, genbuf, ninbuf+1,
cntch);
					break;
				}
			}
			fp = genbuf;
			cntch += ninbuf+1;
.
870a
					lp++;
.
543,854d
484a
			if (value(READONLY))
				error(" File is read only");
.
483a
		case EDF:
			if (value(READONLY))
				error(" File is read only");
			break;

.
465c
		if (!exclam && (!value(WRITEANY) || value(READONLY)))
		switch (edfile()) {
.
324a
		if (xflag)
			break;
.
141c
			if (any(peekchar(), "#%|"))
.
86a
			if (value(READONLY))
				printf(" [Read only]");
.
46a
		if (c == 'e' || c == 'E')
			altdot = lineDOT();
.
45c
		wasalt = (isalt > 0) ? isalt-1 : 0;
		isalt = 0;
.
18a
short	isalt;
.
9c
 * File input/output, source, preserve and recover
.
w
q
'-*-END-*-'
ed - ex_put.c << '-*-END-*-'
902a
}

#ifdef TIOCLGET
/*
 * We have just gotten a susp.  Suspend and prepare to resume.
 */
onsusp()
{
	ttymode f;

	f = setty(normf);
	vnfl();
	putpad(TE);
	flush();

	signal(SIGTSTP, SIG_DFL);
	kill(0, SIGTSTP);

	/* the pc stops here */

	signal(SIGTSTP, onsusp);
	vcontin(0);
	setty(f);
	if (!inopen)
		error(0);
	else {
		if (vcnt < 0) {
			vcnt = -vcnt;
			if (state == VISUAL)
				vclear();
			else if (state == CRTOPEN)
				vcnt = 0;
		}
		vdirty(0, LINES);
		vrepaint(cursor);
	}
.
892a
# endif
# ifdef TIOCLGET
	ioctl(i, TIOCSLTC, &nlttyc);
# endif

#else
	/* USG 3 very simple: just set everything */
	ioctl(i, TCSETAW, &tty);
.
890,891c
# endif

# ifdef TIOCGETC
	/* Update the other random chars while we're at it. */
.
888c
# else
	/* We have to.  Too bad. */
.
879,886c
#ifndef USG3TTY
# ifdef USG
	/* Bug in USG tty driver, put out a DEL as a patch. */
	if (tty.sg_ospeed >= B1200)
		write(1, "\377", 1);
# endif

# ifdef TIOCSETN
	/* Don't flush typeahead if we don't have to */
.
874a
/*
 * sTTY: set the tty modes on file descriptor i to be what's
 * currently in global "tty".  (Also use nttyc if needed.)
 */
.
872a
	if ((tn=ttyname(0)) == NULL && (tn=ttyname(1)) == NULL && (tn=ttyname(2)) == NULL)
		tn = "/dev/tty";
	strcpy(ttynbuf, tn);
	stat(ttynbuf, &sbuf);
	ttymesg = sbuf.st_mode & 0777;
.
871a
# endif
# ifdef TIOCLGET
	ioctl(i, TIOCGLTC, &olttyc);
	nlttyc = olttyc;
# endif
#else
	ioctl(i, TCGETA, &tty);
.
869c
# ifdef TIOCGETC
.
867a
#ifndef USG3TTY
.
866a
	char *tn;
	struct stat sbuf;
.
859a
#else
	if (tty.c_lflag & ICANON)
		ttcharoff();
	tty = f;
#endif
.
856,858c
# ifdef TIOCLGET
		nlttyc = olttyc;
# endif
	} else
		ttcharoff();
.
853,854c
#ifndef USG3TTY
	if (f == normf) {
.
851a
#else
	ttymode ot;
	ot = tty;
#endif
.
850a
#ifndef USG3TTY
.
849c
	ttymode f;
.
847a
ttymode
.
836c
	ttymode f;
.
807a
	if (!value(MESG))
		chmod(ttynbuf, ttymesg);
.
805a
	tostop();
}

/* Actions associated with putting the terminal in the right mode. */
tostop()
{
.
803a
#else
	pfast = (f.c_oflag & OCRNL) == 0;
#endif
.
802a
#ifndef USG3TTY
.
800c
	ttymode f;
.
796a
 * Turn off start/stop chars if they aren't the default ^S/^Q.
 * This is so idiots who make esc their start/stop don't lose.
 * We always turn off quit since datamedias send ^\ for their
 * right arrow key.
 */
#ifdef TIOCGETC
ttcharoff()
{
	nttyc.t_quitc = '\377';
	if (nttyc.t_startc != CTRL(q))
		nttyc.t_startc = '\377';
	if (nttyc.t_stopc != CTRL(s))
		nttyc.t_stopc = '\377';
# ifdef TIOCLGET
	nlttyc.t_suspc = '\377';	/* ^Z */
	nlttyc.t_dsuspc = '\377';	/* ^Y */
	nlttyc.t_flushc = '\377';	/* ^O */
	nlttyc.t_lnextc = '\377';	/* ^V */
# endif
}
#endif

#ifdef USG3TTY
ttcharoff()
{
	tty.c_cc[VQUIT] = '\377';
# ifdef VSTART
	/*
	 * The following is sample code if USG ever lets people change
	 * their start/stop chars.  As long as they can't we can't get
	 * into trouble so we just leave them alone.
	 */
	if (tty.c_cc[VSTART] != CTRL(q))
		tty.c_cc[VSTART] = '\377';
	if (tty.c_cc[VSTOP] != CTRL(s))
		tty.c_cc[VSTOP] = '\377';
# endif
}
#endif

/*
.
795a
/* actions associated with putting the terminal in open mode */
tostart()
{
	putpad(VS);
	putpad(KS);
	if (!value(MESG))
		chmod(ttynbuf, 0611);	/* 11 = urgent only allowed */
}

.
790,791c
	tostart();
.
786,788d
784c
	f = tty;
	tty = normf;
	tty.c_iflag &= ~ICRNL;
	tty.c_lflag &= ~(ECHO|ICANON);
	tty.c_oflag &= ~TAB3;
	tty.c_cc[VMIN] = 1;
	tty.c_cc[VTIME] = 1;
	ttcharoff();
.
781,782c
	tty.sg_flags = (normf &~ (ECHO|XTABS|CRMOD)) |
# ifdef CBREAK
							CBREAK;
# else
							RAW;
# endif
# ifdef TIOCGETC
	ttcharoff();
# endif
.
779a
#ifndef USG3TTY
.
774c
	ttymode f;
.
771a
ttymode
.
750a
#else
	tty = normf;
	tty.c_oflag &= ~(ONLCR|TAB3);
	tty.c_lflag &= ~ECHO;
#endif
.
749a
#ifndef USG3TTY
.
681,690d
671c
	*obp++ = c & 0177;
.
565,568d
532c
		i = tabcol(outcol, value(HARDTABS));
.
499c
		if (xNL && pfast)
			tputs(xNL, 0, plodput);
		else
			plodput('\n');
.
491c
			if (xNL)
				tputs(xNL, 0, plodput);
			else
				plodput('\n');
.
489c
		/*
		 * BUG: this doesn't take the (possibly long) length
		 * of xCR into account.
		 */
		if (xCR)
			tputs(xCR, 0, plodput);
		else
			plodput('\r');
.
459c
		i = destcol % value(HARDTABS)
		    + destcol / value(HARDTABS);
.
457c
	} else
	/*
	 * No home and no up means it's impossible, so we return an
	 * incredibly big number to make cursor motion win out.
	 */
		if (!UP && destline < outline)
			return (500);
.
451c
			if (i + k + 2 < j && (k<=0 || UP)) {
.
449a
			/*
			 * Quickly consider homing down and moving from there.
			 * Assume cost of LL is 2.
			 */
.
446c

		/*
		 * Decision.  We may not have a choice if no UP.
		 */
		if (i + destline < j || (!UP && destline < outline)) {
			/*
			 * Cheaper to home.  Do it now and pretend it's a
			 * regular local motion.
			 */
.
441c
				j = i + 1; /* impossibly expensive */

		/* k is the absolute value of vertical distance */
.
439c
				i = j = outcol - destcol; /* cheaper to backspace */
.
437c
		} else
			/* leftward motion only works if we can backspace. */
.
431,434c
		/*
		 * j is cost to move locally without homing
		 */
		if (destcol >= outcol) {	/* if motion is to the right */
			j = destcol / value(HARDTABS) - outcol / value(HARDTABS);
			if (GT && j)
				j += destcol % value(HARDTABS);
.
428c
			i = (destcol / value(HARDTABS)) + (destcol % value(HARDTABS));
.
426a
		/*
		 * i is the cost to home and tab/space to the right to
		 * get to the proper column.  This assumes ND space costs
		 * 1 char.  So i+destcol is cost of motion with home.
		 */
.
425a
	/*
	 * Consider homing and moving down/right from there, vs moving
	 * directly with local motions to the right spot.
	 */
.
369c
			/*
			 * The following linefeed (or simulation thereof)
			 * is supposed to scroll up the screen, since we
			 * are on the bottom line.  We make the assumption
			 * that linefeed will scroll.  If ns is in the
			 * capability list this won't work.  We should
			 * probably have an sc capability but sf will
			 * generally take the place if it works.
			 *
			 * Superbee glitch:  in the middle of the screen we
			 * have to use esc B (down) because linefeed screws up
			 * in "Efficient Paging" (what a joke) mode (which is
			 * essential in some SB's because CRLF mode puts garbage
			 * in at end of memory), but you must use linefeed to
			 * scroll since down arrow won't go past memory end.
			 * I turned this off after recieving Paul Eggert's
			 * Superbee description which wins better.
			 */
			if (xNL /* && !XB */ && pfast)
				tputs(xNL, 0, putch);
			else
				putch('\n');
.
347,348c
					if (xCR)
						tputs(xCR, 0, putch);
					else
						putch('\r');
				if (xNL)
					tputs(xNL, 0, putch);
				else
					putch('\n');
.
197,202c
static	char linb[66];
static	char *linp = linb;
.
w
q
'-*-END-*-'
ed - ex_re.c << '-*-END-*-'
786c
	case CEOFC:
.
704,707d
650c
				*ep++ = CEOFC;
.
525c
			*ep++ = CEOFC;
.
310c
	if (cflag == 0)
.
198c
			cflag = !cflag;
.
186a
		if (subre.Expbuf[0] == 0)
			error("No previous substitute re|No previous substitute to repeat");
.
177c
		cflag = 0;
.
160c
		gsubf = cflag = 0;
.
148c
	if (stotal == 0 && !inglobal && !cflag)
.
107c
bool	cflag;
.
w
q
'-*-END-*-'
ed - ex_re.h << '-*-END-*-'
62c
#define	CEOFC	17
.
w
q
'-*-END-*-'
ed - ex_set.c << '-*-END-*-'
76a
			if (op == &options[PROMPT])
				oprompt = 1 - no;
.
w
q
'-*-END-*-'
ed - ex_subr.c << '-*-END-*-'
770d
686a
/*
 * Return the column number that results from being in column col and
 * hitting a tab, where tabs are set every ts columns.  Work right for
 * the case where col > COLUMNS, even if ts does not divide COLUMNS.
 */
tabcol(col, ts)
int col, ts;
{
	int offset, result;

	if (col >= COLUMNS) {
		offset = COLUMNS * (col/COLUMNS);
		col -= offset;
	} else
		offset = 0;
	result = col + ts - (col % ts) + offset;
	return (result);
}

.
446c
	*addr = n | oldglobmk;
.
440a
	oldglobmk = *addr & 1;
.
439a
	register oldglobmk;
.
181a
	else if (c=='"')
		comment();
.
58a
/*
 * Ignore a comment to the end of the line.
 * This routine eats the trailing newline so don't call newline().
 */
comment()
{
	register int c;

	do {
		c = getchar();
	} while (c != '\n' && c != EOF);
	if (c == EOF)
		ungetchar(c);
}

.
w
q
'-*-END-*-'
ed - ex_temp.c << '-*-END-*-'
574a
}

/*
 * Encryption routines.  These are essentially unmodified from ed.
 */

/*
 * crblock: encrypt/decrypt a block of text.
 * buf is the buffer through which the text is both input and
 * output. nchar is the size of the buffer. permp is a work
 * buffer, and startn is the beginning of a sequence.
 */
crblock(permp, buf, nchar, startn)
char *permp;
char *buf;
int nchar;
long startn;
{
	register char *p1;
	int n1;
	int n2;
	register char *t1, *t2, *t3;

	t1 = permp;
	t2 = &permp[256];
	t3 = &permp[512];

	n1 = startn&0377;
	n2 = (startn>>8)&0377;
	p1 = buf;
	while(nchar--) {
		*p1 = t2[(t3[(t1[(*p1+n1)&0377]+n2)&0377]-n2)&0377]-n1;
		n1++;
		if(n1==256){
			n1 = 0;
			n2++;
			if(n2==256) n2 = 0;
		}
		p1++;
	}
}

/*
 * makekey: initialize buffers based on user key a.
 */
makekey(a, b)
char *a, *b;
{
       register int i;
	long t;
	char temp[KSIZE + 1];

	for(i = 0; i < KSIZE; i++)
		temp[i] = *a++;
	time(&t);
	t += getpid();
	for(i = 0; i < 4; i++)
		temp[i] ^= (t>>(8*i))&0377;
	crinit(temp, b);
}

/*
 * crinit: besides initializing the encryption machine, this routine
 * returns 0 if the key is null, and 1 if it is non-null.
 */
crinit(keyp, permp)
char    *keyp, *permp;
{
       register char *t1, *t2, *t3;
	register i;
	int ic, k, temp;
	unsigned random;
	char buf[13];
	long seed;

	t1 = permp;
	t2 = &permp[256];
	t3 = &permp[512];
	if(*keyp == 0)
		return(0);
	strncpy(buf, keyp, 8);
	while (*keyp)
		*keyp++ = '\0';

	buf[8] = buf[0];
	buf[9] = buf[1];
	domakekey(buf);

	seed = 123;
	for (i=0; i<13; i++)
		seed = seed*buf[i] + i;
	for(i=0;i<256;i++){
		t1[i] = i;
		t3[i] = 0;
	}
	for(i=0; i<256; i++) {
		seed = 5*seed + buf[i%13];
		random = seed % 65521;
		k = 256-1 - i;
		ic = (random&0377) % (k+1);
		random >>= 8;
		temp = t1[k];
		t1[k] = t1[ic];
		t1[ic] = temp;
		if(t3[k]!=0) continue;
		ic = (random&0377) % k;
		while(t3[ic]!=0) ic = (ic+1) % k;
		t3[k] = ic;
		t3[ic] = k;
	}
	for(i=0; i<256; i++)
		t2[t1[i]&0377] = i;
	return(1);
}

/*
 * domakekey: the following is the major nonportable part of the encryption
 * mechanism. A 10 character key is supplied in buffer.
 * This string is fed to makekey (an external program) which
 * responds with a 13 character result. This result is placed
 * in buffer.
 */
domakekey(buffer)
char *buffer;
{
       int pf[2];

	if (pipe(pf)<0)
		pf[0] = pf[1] = -1;
	if (fork()==0) {
		close(0);
		close(1);
		dup(pf[0]);
		dup(pf[1]);
		execl("/usr/lib/makekey", "-", 0);
		execl("/lib/makekey", "-", 0);
		exit(1);
	}
	write(pf[1], buffer, 10);
	if (wait((int *)NULL)==-1 || read(pf[0], buffer, 13)!=13)
		error("crypt: cannot generate key");
	close(pf[0]);
	close(pf[1]);
	/* end of nonportable part */
.
219a
			if (*bp > NMBLKS)
				error(" Tmp file too large");
.
176,177c
	if (oblock >= 0) {
		if(xtflag) {
			/*
			 * Encrypt block before writing, so some devious
			 * person can't look at temp file while editing.
			 */
			p1 = obuff;
			p2 = crbuf;
			n = CRSIZE;
			while(n--)
				*p2++ = *p1++;
			crblock(tperm, crbuf, CRSIZE, (long)0);
			blkio(oblock, crbuf, write);
		} else
			blkio(oblock, obuff, write);
	}
.
173a
		if(xtflag)
			crblock(tperm, ibuff, CRSIZE, (long)0);
.
170a
		}
.
169c
		if (ichanged) {
			if(xtflag)
				crblock(tperm, ibuff, CRSIZE, (long)0);
.
164a
			if(xtflag)
				crblock(tperm, ibuff2, CRSIZE, (long)0);
.
161a
			}
.
160c
			if (ichang2) {
				if(xtflag)
					crblock(tperm, ibuff2, CRSIZE, (long)0);
.
139a
        register char *p1, *p2;
        register int n;
.
w
q
'-*-END-*-'
ed - ex_tty.c << '-*-END-*-'
117c
	namp = "albcbtcdceclcmcrdcdldmdoedeik0k1k2k3k4k5k6k7k8k9hoicimipkdkekhklkrkskullndnlpcsesfsosrtatetiupvbvsve";
.
111c
 	namp = "ambsdadbeohchzinmincnsosulxbxnxtxx";
.
92,96d
82c
	if (tgoto(CM, 2, 2)[0] == 'O')	/* OOPS */
.
80c
	if (COLUMNS <= 4)
.
75a
#ifdef TIOCLGET
	/*
	 * Now map users susp char to ^Z, being careful that the susp
	 * overrides any arrow key, but only for hackers (=new tty driver).
	 */
	{
		static char sc[2];
		int i, fnd;

		ioctl(0, TIOCGETD, &ldisc);
		if (ldisc == NTTYDISC) {
			sc[0] = olttyc.t_suspc;
			sc[1] = 0;
			if (olttyc.t_suspc == CTRL(z)) {
				for (i=0; i<=4; i++)
					if (arrows[i].cap[0] == CTRL(z))
						addmac(sc, NULL, NULL, arrows);
			} else
				addmac(sc, "\32", "susp", arrows);
		}
	}
#endif

.
42c
	char *tgoto();
.
34c
	&AM, &BS, &DA, &DB, &EO, &HC, &HZ, &IN, &MI, &NC, &NS, &OS, &UL,
	&XB, &XN, &XT, &XX
.
31c
	&ND, &xNL, &xPC, &SE, &SF, &SO, &SR, &TA, &TE, &TI, &UP, &VB, &VS, &VE
.
28c
	&AL, &BC, &BT, &CD, &CE, &CL, &CM, &xCR, &DC, &DL, &DM, &DO, &ED, &EI,
.
23a
#else
	if (ioctl(1, TCGETA, &tty) < 0)
		return;
	if (ospeed != tty.c_cflag & CBAUD)
		value(SLOWOPEN) = (tty.c_cflag & CBAUD) < B1200;
	ospeed = tty.c_cflag & CBAUD;
	normf = tty;
	UPPERCASE = (tty.c_iflag & IUCLC) != 0;
	GT = (tty.c_oflag & TABDLY) != TAB3 && !XT;
	NONL = (tty.c_oflag & OCRNL) == 0;
#endif
.
14a
#ifndef USG3TTY
.
w
q
'-*-END-*-'
ed - ex_tty.h << '-*-END-*-'
132a
int	maphopcnt;	/* check for infinite mapping loops */
bool	anyabbrs;	/* true if abbr or unabbr has been done */
char	ttynbuf[20];	/* result of ttyname() */
int	ttymesg;	/* original mode of users tty */
.
130a
struct maps abbrevs[MAXNOMACS];	/* for word abbreviations */
int	ldisc;			/* line discipline for ucb tty driver */
.
111a
ttymode	normf;			/* Restore tty flags to this (someday) */
bool	normtty;		/* Have to restore normal mode from normf */

ttymode ostart(), setty(), unixex();

.
108,110d
105,106c
/*
 * There are several kinds of tty drivers to contend with.  These include:
 * (1)	V6:		no CBREAK, no ioctl.  (Include PWB V1 here).
 * (2)	V7 research:	has CBREAK, has ioctl, and has the tchars (TIOCSETC)
 *			business to change start, stop, etc. chars.
 * (3)	USG V2:		Basically like V6 but RAW mode is like V7 RAW.
 *			(We treat it as V6.)
 * (4)	USG V3:		equivalent to V7 but totally incompatible.
 * (5)  Berkeley:	has ltchars in addition to all of V7.
 *
 * The following attempts to decide what we are on, and declare
 * some variables in the appropriate format.  The wierd looking one (ttymode)
 * is the thing we pass to sTTY and family to turn "RAW" mode on or off
 * when we go into or out of visual mode.  In V7/V6 it's just the flags word
 * to stty.  In USG V3 it's the whole tty structure.
 */
#ifdef	USG3TTY			/* USG V3 */
  struct	termio tty;	/* Use this one structure to change modes */
  typedef	struct termio ttymode;	/* Mode to contain tty flags */

#else				/* All others */
  struct	sgttyb tty;	/* Always stty/gtty using this one structure */
  typedef	int ttymode;	/* Mode to contain tty flags */
# ifdef 	TIOCSETC	/* V7 */
   struct	tchars ottyc, nttyc;	/* For V7 character masking */
# endif
# ifdef		TIOCLGET	/* Berkeley */
   struct	ltchars olttyc, nlttyc;	/* More of tchars style stuff */
# endif

.
86a
bool	XX;			/* Tektronix 4025 insert line */
.
84a
bool	XB;			/* Beehive (no escape key, simulate with f1) */
.
82a
bool	NS;			/* No scroll - linefeed at bottom won't scroll */
.
58a
char	*xNL;			/*    Line feed (new line) */
.
37a
char	*xCR;			/* P  Carriage return */
.
w
q
'-*-END-*-'
ed - ex_tune.h << '-*-END-*-'
109c
#define	ATTN	(-2)
.
40a
#define CRSIZE		512
.
37a
#define CRSIZE		1024
.
16c
#define	EXSTRINGS	libpath(ex3.4strings)
.
13,14c
#define	EXRECOVER	libpath(ex3.4recover)
#define	EXPRESERVE	libpath(ex3.4preserve)
.
w
q
'-*-END-*-'
cat > ex_unix.c << '-*-END-*-'
/* Copyright (c) 1979 Regents of the University of California */
#include "ex.h"
#include "ex_temp.h"
#include "ex_tty.h"
#include "ex_vis.h"

/*
 * Unix escapes, filtering
 */

/*
 * First part of a shell escape,
 * parse the line, expanding # and % and ! and printing if implied.
 */
unix0(warn)
	bool warn;
{
	register char *up, *fp;
	register short c;
	char printub, puxb[UXBSIZE + sizeof (int)];

	printub = 0;
	CP(puxb, uxb);
	c = getchar();
	if (c == '\n' || c == EOF)
		error("Incomplete shell escape command@- use 'shell' to get a shell");
	up = uxb;
	do {
		switch (c) {

		case '\\':
			if (any(peekchar(), "%#!"))
				c = getchar();
		default:
			if (up >= &uxb[UXBSIZE]) {
tunix:
				uxb[0] = 0;
				error("Command too long");
			}
			*up++ = c;
			break;

		case '!':
			fp = puxb;
			if (*fp == 0) {
				uxb[0] = 0;
				error("No previous command@to substitute for !");
			}
			printub++;
			while (*fp) {
				if (up >= &uxb[UXBSIZE])
					goto tunix;
				*up++ = *fp++;
			}
			break;

		case '#':
			fp = altfile;
			if (*fp == 0) {
				uxb[0] = 0;
				error("No alternate filename@to substitute for #");
			}
			goto uexp;

		case '%':
			fp = savedfile;
			if (*fp == 0) {
				uxb[0] = 0;
				error("No filename@to substitute for %%");
			}
uexp:
			printub++;
			while (*fp) {
				if (up >= &uxb[UXBSIZE])
					goto tunix;
				*up++ = *fp++ | QUOTE;
			}
			break;
		}
		c = getchar();
	} while (c == '"' || c == '|' || !endcmd(c));
	if (c == EOF)
		ungetchar(c);
	*up = 0;
	if (!inopen)
		resetflav();
	if (warn)
		ckaw();
	if (warn && hush == 0 && chng && xchng != chng && value(WARN) && dol > zero) {
		xchng = chng;
		vnfl();
		printf(mesg("[No write]|[No write since last change]"));
		noonl();
		flush();
	} else
		warn = 0;
	if (printub) {
		if (uxb[0] == 0)
			error("No previous command@to repeat");
		if (inopen) {
			splitw++;
			vclean();
			vgoto(WECHO, 0);
		}
		if (warn)
			vnfl();
		if (hush == 0)
			lprintf("!%s", uxb);
		if (inopen && Outchar != termchar) {
			vclreol();
			vgoto(WECHO, 0);
		} else
			putnl();
		flush();
	}
}

/*
 * Do the real work for execution of a shell escape.
 * Mode is like the number passed to open system calls
 * and indicates filtering.  If input is implied, newstdin
 * must have been setup already.
 */
ttymode
unixex(opt, up, newstdin, mode)
	char *opt, *up;
	int newstdin, mode;
{
	int pvec[2];
	ttymode f;

	signal(SIGINT, SIG_IGN);
#ifdef TIOCLGET
	if (dosusp)
		signal(SIGTSTP, SIG_DFL);
#endif
	if (inopen)
		f = setty(normf);
	if ((mode & 1) && pipe(pvec) < 0) {
		/* Newstdin should be io so it will be closed */
		if (inopen)
			setty(f);
		error("Can't make pipe for filter");
	}
#ifndef VFORK
	pid = fork();
#else
	pid = vfork();
#endif
	if (pid < 0) {
		if (mode & 1) {
			close(pvec[0]);
			close(pvec[1]);
		}
		setrupt();
		error("No more processes");
	}
	if (pid == 0) {
		if (mode & 2) {
			close(0);
			dup(newstdin);
			close(newstdin);
		}
		if (mode & 1) {
			close(pvec[0]);
			close(1);
			dup(pvec[1]);
			if (inopen) {
				close(2);
				dup(1);
			}
			close(pvec[1]);
		}
		if (io)
			close(io);
		if (tfile)
			close(tfile);
#ifndef VMUNIX
		close(erfile);
#endif
		signal(SIGHUP, oldhup);
		signal(SIGQUIT, oldquit);
		if (ruptible)
			signal(SIGINT, SIG_DFL);
		execl(svalue(SHELL), "sh", opt, up, (char *) 0);
		printf("No %s!\n", svalue(SHELL));
		error(NOSTR);
	}
	if (mode & 1) {
		io = pvec[0];
		close(pvec[1]);
	}
	if (newstdin)
		close(newstdin);
	return (f);
}

/*
 * Wait for the command to complete.
 * F is for restoration of tty mode if from open/visual.
 * C flags suppression of printing.
 */
unixwt(c, f)
	bool c;
	ttymode f;
{

	waitfor();
#ifdef TIOCLGET
	if (dosusp)
		signal(SIGTSTP, onsusp);
#endif
	if (inopen)
		setty(f);
	setrupt();
	if (!inopen && c && hush == 0) {
		printf("!\n");
		flush();
		termreset();
		gettmode();
	}
}

/*
 * Setup a pipeline for the filtration implied by mode
 * which is like a open number.  If input is required to
 * the filter, then a child editor is created to write it.
 * If output is catch it from io which is created by unixex.
 */
filter(mode)
	register int mode;
{
	static int pvec[2];
	register ttymode f;
	register int lines = lineDOL();

	mode++;
	if (mode & 2) {
		signal(SIGINT, SIG_IGN);
		if (pipe(pvec) < 0)
			error("Can't make pipe");
		pid = fork();
		io = pvec[0];
		if (pid < 0) {
			setrupt();
			close(pvec[1]);
			error("No more processes");
		}
		if (pid == 0) {
			setrupt();
			io = pvec[1];
			close(pvec[0]);
			putfile();
			exit(0);
		}
		close(pvec[1]);
		io = pvec[0];
		setrupt();
	}
	f = unixex("-c", uxb, (mode & 2) ? pvec[0] : 0, mode);
	if (mode == 3) {
		delete(0);
		addr2 = addr1 - 1;
	}
	if (mode & 1) {
		if(FIXUNDO)
			undap1 = undap2 = addr2+1;
		ignore(append(getfile, addr2));
	}
	close(io);
	io = -1;
	unixwt(!inopen, f);
	netchHAD(lines);
}

/*
 * Set up to do a recover, getting io to be a pipe from
 * the recover process.
 */
recover()
{
	static int pvec[2];

	if (pipe(pvec) < 0)
		error(" Can't make pipe for recovery");
	pid = fork();
	io = pvec[0];
	if (pid < 0) {
		close(pvec[1]);
		error(" Can't fork to execute recovery");
	}
	if (pid == 0) {
		close(2);
		dup(1);
		close(1);
		dup(pvec[1]);
	        close(pvec[1]);
		execl(EXRECOVER, "exrecover", svalue(DIRECTORY), file, (char *) 0);
		close(1);
		dup(2);
		error(" No recovery routine");
	}
	close(pvec[1]);
}

/*
 * Wait for the process (pid an external) to complete.
 */
waitfor()
{

	do
		rpid = wait(&status);
	while (rpid != pid && rpid != -1);
	status = (status >> 8) & 0377;
}

/*
 * The end of a recover operation.  If the process
 * exits non-zero, force not edited; otherwise force
 * a write.
 */
revocer()
{

	waitfor();
	if (pid == rpid && status != 0)
		edited = 0;
	else
		change();
}
'-*-END-*-'
ed - ex_v.c << '-*-END-*-'
260a
	if (undadot <= zero || undadot > dol)
		undadot = zero+1;
.
177a
	if (NS && !SF) {
		if (initev)
			goto toopen;
		error("Visual requires scrolling");
	}
.
156c
	register ttymode f;
.
131c
	ttymode f;
.
56c
	register ttymode f;
.
w
q
'-*-END-*-'
ed - ex_vadj.c << '-*-END-*-'
366a
	vscroll(cnt);
.
365d
118a
#ifdef TRACE
	if (trace)
		fprintf(trace, "after pline in vreopen\n");
#endif
.
117a
#ifdef TRACE
	if (trace)
		fprintf(trace, "before pline in vreopen\n");
#endif
.
w
q
'-*-END-*-'
ed - ex_vars.h << '-*-END-*-'
40c
#define	NOPTS	40
.
13,38c
#define MESG            12
#define NUMBER          13
#define OPEN            14
#define OPTIMIZE        15
#define PARAGRAPHS      16
#define PROMPT          17
#define READONLY        18
#define REDRAW          19
#define REMAP           20
#define REPORT          21
#define SCROLL          22
#define SECTIONS        23
#define SHELL           24
#define SHIFTWIDTH      25
#define SHOWMATCH       26
#define SLOWOPEN        27
#define TABSTOP         28
#define TAGLENGTH       29
#define TAGS            30
#define TERM            31
#define TERSE           32
#define TIMEOUT         33
#define TTYTYPE         34
#define WARN            35
#define WINDOW          36
#define WRAPSCAN        37
#define WRAPMARGIN      38
#define WRITEANY        39
.
w
q
'-*-END-*-'
ed - ex_vget.c << '-*-END-*-'
496,497c
	register line *p;

	if (!trace) return;

	fprintf(trace, "\n%s: undkind=%d, vundkind=%d, unddel=%d, undap1=%d, undap2=%d,\n",
		s, undkind, vundkind, lineno(unddel), lineno(undap1), lineno(undap2));
	fprintf(trace, "  undadot=%d, dot=%d, dol=%d, unddol=%d, truedol=%d\n",
		lineno(undadot), lineno(dot), lineno(dol), lineno(unddol), lineno(truedol));
	fprintf(trace, "  [");
	for (p=zero+1; p<=truedol; p++)
		fprintf(trace, "%o ", *p);
	fprintf(trace, "]\n");
.
492a
visdump(s)
char *s;
{
	register int i;

	if (!trace) return;

	fprintf(trace, "\n%s: basWTOP=%d, basWLINES=%d, WTOP=%d, WBOT=%d, WLINES=%d, WCOLS=%d, WECHO=%d\n",
		s, basWTOP, basWLINES, WTOP, WBOT, WLINES, WCOLS, WECHO);
	fprintf(trace, "   vcnt=%d, vcline=%d, cursor=%d, wcursor=%d, wdot=%d\n",
		vcnt, vcline, cursor-linebuf, wcursor-linebuf, wdot-zero);
	for (i=0; i<TUBELINES; i++)
		if (vtube[i] && *vtube[i])
			fprintf(trace, "%d: '%s'\n", i, vtube[i]);
	tvliny();
}

.
488a
#endif
		vch_mac = VC_NOCHANGE;
.
483a
#ifdef notdef
.
469c
		fprintf(trace, "macpush(%s), canundo=%d\n",st,canundo);
.
466a
#endif
.
464a
#ifdef notdef
.
442c
		fprintf(trace,"Fail: push(%s), return %c", &b[1], c);
.
433,434c
			if (trace)
				fprintf(trace,"Success: push(%s), return %c",maps[d].mapto, c);
.
430c
			macpush(maps[d].mapto,maps == arrows);
.
415a
						 * Nothing waiting.  Push back
						 * what we peeked at & return
						 * failure (c).
						 *
.
413c
							fprintf(trace,"fpk=0: return '%c'",c);
.
404a
					 * Is there another char waiting?
					 *
.
395c
			fprintf(trace,"\ntry '%s', ",maps[d].cap);
.
389a
	/*
	 * If c==0, the char came from getesc typing escape.  Pass it through
	 * unchanged.  0 messes up the following code anyway.
	 */
	if (c==0)
		return(0);

.
246c
	if (vglobp || vmacp)
.
220a
	if (Outchar == termchar)
		putchar('\n');
.
95a
#ifdef BEEHIVE
	if (XB && slevel==0 && c == ESCAPE) {
		if (read(0, &Peek2key, 1) != 1)
			goto getATTN;
		Peek2key &= TRIM;
		switch (Peek2key) {
		case 'C':	/* SPOW mode sometimes sends \EC for space */
			c = ' ';
			Peek2key = 0;
			break;
		case 'q':	/* f2 -> ^C */
			c = CTRL(c);
			Peek2key = 0;
			break;
		case 'p':	/* f1 -> esc */
			Peek2key = 0;
			break;
		}
	}
#endif
.
90c
	if (read(slevel == 0 ? 0 : ttyindes, &ch, 1) != 1) {
.
86a
		vch_mac = VC_NOTINMAC;
.
72a
#ifdef BEEHIVE
	if (Peek2key) {
		c = Peek2key;
		Peek2key = 0;
		return (c);
	}
#endif
.
65a
#define BEEHIVE
#ifdef BEEHIVE
	static char Peek2key;
#endif
	extern short slevel, ttyindes;
.
w
q
'-*-END-*-'
ed - ex_vis.h << '-*-END-*-'
135a

/*
 * State information for undoing of macros.  The basic idea is that
 * if the macro does only 1 change or even none, we don't treat it
 * specially.  If it does 2 or more changes we want to be able to
 * undo it as a unit.  We remember how many changes have been made
 * within the current macro.  (Remember macros can be nested.)
 */
#define VC_NOTINMAC	0	/* Not in a macro */
#define VC_NOCHANGE	1	/* In a macro, no changes so far */
#define VC_ONECHANCE	2	/* In a macro, one change so far */
#define VC_MANYCHANGE	3	/* In a macro, at least 2 changes so far */

short	vch_mac;	/* Change state - one of the above */
.
3c
 * Ex version 3
.
w
q
'-*-END-*-'
ed - ex_vmain.c << '-*-END-*-'
1040c
			vundo(1);
.
852a
			getDOT();
.
839a
		 * ^Z:	suspend editor session and temporarily return
		 * 	to shell.  Only works on Berkeley tty driver.
		 */
		case CTRL(z):
			forbid(dosusp == 0 || !ldisc);
			vsave();
			oglobp = globp;
			globp = "stop";
			goto gogo;
#endif

		/*
.
838a
#ifdef TIOCLGET
.
692a
			vmacchng(1);
.
691a
			/*
			 * If we just did a macro the whole buffer is in
			 * the undo save area.  We don't want to put THAT.
			 */
			forbid (vundkind == VMANY && undkind==UNDALL);
.
674a
#endif
.
673a
#ifdef notdef
.
646a
			/*
			 * If we are in the middle of a macro, throw away
			 * the rest and fix up undo.
			 * This code copied from getbr().
			 */
			if (vmacp) {
				vmacp = 0;
				if (inopen == -1)	/* don't screw up undo for esc esc */
					vundkind = VMANY;
				inopen = 1;	/* restore old setting now that macro done */
			}
.
576a
			vmacchng(1);
.
508a
				setLAST();
.
490a
			vmacchng(1);
.
455a
			vmacchng(1);
.
403c
				dot -= vcline - 2 + (cnt-1)*basWLINES;
.
400,401d
388c
				dot += (vcnt - vcline) - 2 + (cnt-1)*basWLINES;
.
385,386d
381c
		 *		Count repeats.
.
146a
			if (++maphopcnt > 256)
				error("Infinite macro loop");
.
123a
		maphopcnt = 0;
.
26a
	vch_mac = VC_NOTINMAC;

.
w
q
'-*-END-*-'
ed - ex_voperate.c << '-*-END-*-'
415a
		vmacchng(1);
.
113a
	vmacchng(1);
.
108a
		vmacchng(1);
.
w
q
'-*-END-*-'
ed - ex_vops.c << '-*-END-*-'
148a
		break;
	}
}

/*
 * Routine to handle a change inside a macro.
 * Fromvis is true if we were called from a visual command (as
 * opposed to an ex command).  This has nothing to do with being
 * in open/visual mode as :s/foo/bar is not fromvis.
 */
vmacchng(fromvis)
bool fromvis;
{
	line *savedot, *savedol;
	char *savecursor;
	int nlines, more;
	register line *a1, *a2;
	char ch;	/* DEBUG */
	int copyw(), copywR();

	if (!inopen)
		return;
	if (!vmacp)
		vch_mac = VC_NOTINMAC;
#ifdef TRACE
	if (trace)
		fprintf(trace, "vmacchng, vch_mac=%d, linebuf='%s', *dot=%o\n", vch_mac, linebuf, *dot);
#endif
	if (vmacp && fromvis)
		vsave();
#ifdef TRACE
	if (trace)
		fprintf(trace, "after vsave, linebuf='%s', *dot=%o\n", linebuf, *dot);
#endif
	switch(vch_mac) {
	case VC_NOCHANGE:
		vch_mac = VC_ONECHANGE;
		break;
	case VC_ONECHANGE:
		/* Save current state somewhere */
#ifdef TRACE
		vudump("before vmacchng hairy case");
#endif
		savedot = dot; savedol = dol; savecursor = cursor;
		nlines = dol - zero;
		while ((line *) endcore - truedol < nlines)
			morelines();
		copyw(truedol+1, zero+1, nlines);
		truedol += nlines;

#ifdef TRACE
		visdump("before vundo");
#endif
		/* Restore state as it was at beginning of macro */
		vundo(0);
#ifdef TRACE
		visdump("after vundo");
		vudump("after vundo");
#endif

		/* Do the saveall we should have done then */
		saveall();
#ifdef TRACE
		vudump("after saveall");
#endif

		/* Restore current state from where saved */
		more = savedol - dol; /* amount we shift everything by */
		if (more)
			(*(more>0 ? copywR : copyw))(savedol+1, dol+1, truedol-dol);
		unddol += more; truedol += more;

		truedol -= nlines;
		copyw(zero+1, truedol+1, nlines);
		dot = savedot; dol = savedol ; cursor = savecursor;
		vch_mac = VC_MANYCHANGE;

		/* Arrange that no further undo saving happens within macro */
		otchng = tchng;	/* Copied this line blindly - bug? */
		inopen = -1;	/* no need to save since it had to be 1 or -1 before */
		vundkind = VMANY;
#ifdef TRACE
		vudump("after vmacchng");
#endif
		break;
	case VC_NOTINMAC:
	case VC_MANYCHANGE:
		/* Nothing to do for various reasons. */
.
118a
		if (!show)
			break;
.
105,106c
		if (show) {
			vcline = cnt;
			vrepaint(vmcurs);
		}
.
100c
			if (show)
				vjumpto(dot, NOSTR, '.');
.
95c
		if (show && (vundkind != VMCHNG || addr != dot))
.
91,92c
		if (show)
			if (undkind == UNDMOVE)
				vdirty(0, LINES);
			else
				vreplace(undap1 - addr, undap2 - undap1,
				    undkind == UNDPUT ? 0 : unddol - dol);
.
56c
vundo(show)
bool show;	/* if true update the screen */
.
52a
	cursor = linebuf;
.
w
q
'-*-END-*-'
ed - ex_vops2.c << '-*-END-*-'
720c
	if (Outchar != termchar)
		Outchar = OO;
.
714d
710d
704a
			flush();
.
596a

		/*
		 * Word abbreviation mode.
		 */
		cstr[0] = c;
		if (anyabbrs && gcursor > ogcursor && !wordch(cstr) && wordch(gcursor-1)) {
				int wdtype, abno;

				cstr[1] = 0;
				wdkind = 1;
				cp = gcursor - 1;
				for (wdtype = wordch(cp - 1);
				    cp > ogcursor && wordof(wdtype, cp - 1); cp--)
					;
				*gcursor = 0;
				for (abno=0; abbrevs[abno].mapto; abno++) {
					if (eq(cp, abbrevs[abno].cap)) {
						macpush(cstr, 0);
						macpush(abbrevs[abno].mapto);
						goto vbackup;
					}
				}
		}

.
595a
		dontbreak:;
.
592,594c
			if (/* c <= ' ' && */ value(WRAPMARGIN) &&
				outcol >= OCOLUMNS - value(WRAPMARGIN)) {
				/*
				 * At end of word and hit wrapmargin.
				 * Move the word to next line and keep going.
				 */
				wdkind = 1;
				*gcursor++ = c;
				*gcursor = 0;
				/*
				 * Find end of previous word if we are past it.
				 */
				for (cp=gcursor; cp>ogcursor && isspace(cp[-1]); cp--)
					;
				if (outcol - (gcursor-cp) >= OCOLUMNS - value(WRAPMARGIN)) {
					/*
					 * Find beginning of previous word.
					 */
					for (; cp>ogcursor && !isspace(cp[-1]); cp--)
						;
					if (cp <= ogcursor) {
						/*
						 * There is a single word that
						 * is too long to fit.  Just
						 * let it pass, but beep for
						 * each new letter to warn
						 * the luser.
						 */
						c = *--gcursor;
						*gcursor = 0;
						beep();
						goto dontbreak;
					}
					/*
					 * Save it for next line.
					 */
					macpush(cp, 0);
					cp--;
				}
				macpush("\n", 0);
				/*
				 * Erase white space before the word.
				 */
				while (cp > ogcursor && isspace(cp[-1]))
					cp--;	/* skip blank */
				gobblebl = 3;
				goto vbackup;
.
587,588c
		if (c != NL && !splitw) {
			if (c == ' ' && gobblebl) {
.
547a
#else
				if (c == tty.c_cc[VERASE]
				    || c == tty.c_cc[VKILL]) {
#endif
.
546a
#ifndef USG3TTY
.
463a
#else
			if (c == tty.c_cc[VERASE])
				c = CTRL(h);
			else if (c == tty.c_cc[VKILL])
				c = -1;
#endif
.
459a
#ifndef USG3TTY
.
450a
				if (++maphopcnt > 256)
					error("Infinite macro loop");
.
445c
		c = getkey();
		if (c != ATTN)
			c &= (QUOTE|TRIM);
		ch = c;
		maphopcnt = 0;
.
409a
	char cstr[2];
.
w
q
'-*-END-*-'
ed - ex_vops3.c << '-*-END-*-'
459c
			if (lf == vmove && wcursor > linebuf)
.
372a
	else {
		strcLIN(sp);
		strcpy(scurs, genbuf);
		if (!lmatchp((line *) 0))
			beep();
	}
.
329c
	parens = any(*cp, "()") ? "()" : any(*cp, "[]") ? "[]" : "{}";
.
325c
	for (cp = cursor; !any(*cp, "({[)}]");)
.
w
q
'-*-END-*-'
ed - ex_vput.c << '-*-END-*-'
621c
		if (inssiz >= doomed + tabcol(tabstart, value(TABSTOP)) - tabstart) {
.
545c
		inssiz = tabcol(inscol, value(TABSTOP)) - inscol;
.
446c
	if (p < 0 || vtube[p] == cp)
.
406c
	while (--i);
.
402c
	register int i = tabcol(destcol, value(TABSTOP)) - destcol;
.
118,121c
		if (DB) {
			vgoto(WECHO, 0);
			vputp(CD ? CD : CE, 1);
		} else {
			if (XT) {
				/*
				 * This code basically handles the t1061
				 * where positioning at (0, 0) won't work
				 * because the terminal won't let you put
				 * the cursor on it's magic cookie.
				 *
				 * Should probably be XS above, or even a
				 * new X? glitch, but right now t1061 is the
				 * only terminal with XT.
				 */
				vgoto(WECHO, 0);
				vputp(DL, 1);
			} else {
				vigoto(WECHO, 0);
				vclreol();
			}
		}
.
w
q
'-*-END-*-'
ed - exrecover.c << '-*-END-*-'
179a
#else
	ioctl(2, TCGETA, &tty);
	if (tty.c_lflag & ICANON)
#endif
.
177a
#ifndef USG3TTY
.
w
q
'-*-END-*-'
ed - makefile << '-*-END-*-'
/rm -f.*NBINDIR/s/$/ ${DESTDIR}${NBINDIR}\/view/
/ln.*NBINDIR.*vi/a
	ln ${DESTDIR}${NBINDIR}/ex ${DESTDIR}${NBINDIR}/view
.
/rm -f.*{BINDIR}\/vi/a
	-rm -f ${DESTDIR}${BINDIR}/view
.
/ln.*{BINDIR}\/vi/a
	ln ${DESTDIR}${BINDIR}/ex ${DESTDIR}${BINDIR}/view
.
/ex_tty.o/s//& ex_unix.o/
1c
VERSION=3.4
.
w
q
'-*-END-*-'
ed - makeoptions << '-*-END-*-'
40c
rm /tmp/foo.c
.
35,37c
	$s/e[ 	].*[ 	]/e	NOPTS	/
	w! ex_vars.h
	q
.
11,32c
cc -E $* /tmp/$$.c >/tmp/foo.c
ex - /tmp/foo.c <<'X'
	" delete all preprocessor output (# line, etc)
	g/^# /d
	set sh=/bin/csh
	" delete junk (all but data lines)
	g/^[ 	]*$/d
	1,/options/d
	/}/-1,$d
	" get rid of all of line but option name
	1,$s/	"//
	1,$s/".*//
	1m$	" kludge since options start at 0 but num at 1
	%!num
	$t0	" unkludge
	1s/......../     0  /	" unkludge
	" make #define lines
	1,$s/\(......\)\(.*\)/#define	\U\2\L	\1/
	" get rid of extra blanks, turning into (single) tabs.
	1,$s/	 */	/g
	g/  */s//	/g
	" filter through expand to make it line up nice
	%!expand -8\,24
	" blank line and number of options.
	$i
.
4,9c
onintr ifintr
cp ex_data.c /tmp/$$.c
ex - /tmp/$$.c <<'%'
	g/^#include/d
	w
	q
.
w
q
'-*-END-*-'