xref: /illumos-gate/usr/src/cmd/vi/port/ex_temp.c (revision d33da75d)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
523a1cceaSRoger A. Faulkner  * Common Development and Distribution License (the "License").
623a1cceaSRoger A. Faulkner  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
2123a1cceaSRoger A. Faulkner 
22a1d23db4Sceastha /*
2323a1cceaSRoger A. Faulkner  * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
24a1d23db4Sceastha  */
25a1d23db4Sceastha 
267c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
277c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate /* Copyright (c) 1981 Regents of the University of California */
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate #include "ex.h"
337c478bd9Sstevel@tonic-gate #include "ex_temp.h"
347c478bd9Sstevel@tonic-gate #include "ex_vis.h"
357c478bd9Sstevel@tonic-gate #include "ex_tty.h"
36f6db9f27Scf #include <unistd.h>
377c478bd9Sstevel@tonic-gate 
387c478bd9Sstevel@tonic-gate /*
397c478bd9Sstevel@tonic-gate  * Editor temporary file routines.
407c478bd9Sstevel@tonic-gate  * Very similar to those of ed, except uses 2 input buffers.
417c478bd9Sstevel@tonic-gate  */
427c478bd9Sstevel@tonic-gate #define	READ	0
437c478bd9Sstevel@tonic-gate #define	WRITE	1
447c478bd9Sstevel@tonic-gate 
457c478bd9Sstevel@tonic-gate unsigned char	tfname[PATH_MAX+1];
467c478bd9Sstevel@tonic-gate static unsigned char	rfname[PATH_MAX+1];
477c478bd9Sstevel@tonic-gate static unsigned char	tempname[PATH_MAX+1];
487c478bd9Sstevel@tonic-gate int	havetmp;
497c478bd9Sstevel@tonic-gate short	tfile = -1;
507c478bd9Sstevel@tonic-gate static short	rfile = -1;
517c478bd9Sstevel@tonic-gate 
52a1d23db4Sceastha extern int junk();
53a1d23db4Sceastha 
54f6db9f27Scf void
fileinit(void)55f6db9f27Scf fileinit(void)
567c478bd9Sstevel@tonic-gate {
57f6db9f27Scf 	unsigned char *p;
58f6db9f27Scf 	pid_t j;
59f6db9f27Scf 	int i;
607c478bd9Sstevel@tonic-gate 	struct stat64 stbuf;
617c478bd9Sstevel@tonic-gate 
627c478bd9Sstevel@tonic-gate 	if (tline == INCRMT * (HBLKS+2))
637c478bd9Sstevel@tonic-gate 		return;
647c478bd9Sstevel@tonic-gate 	cleanup(0);
657c478bd9Sstevel@tonic-gate 	if (tfile != -1)
667c478bd9Sstevel@tonic-gate 		close(tfile);
677c478bd9Sstevel@tonic-gate 	tline = INCRMT * (HBLKS+2);
687c478bd9Sstevel@tonic-gate 	blocks[0] = HBLKS;
697c478bd9Sstevel@tonic-gate 	blocks[1] = HBLKS+1;
707c478bd9Sstevel@tonic-gate 	blocks[2] = -1;
717c478bd9Sstevel@tonic-gate 	dirtcnt = 0;
727c478bd9Sstevel@tonic-gate 	iblock = -1;
737c478bd9Sstevel@tonic-gate 	iblock2 = -1;
747c478bd9Sstevel@tonic-gate 	oblock = -1;
757c478bd9Sstevel@tonic-gate 	if (strlen(svalue(vi_DIRECTORY)) > (PATH_MAX -13))
767c478bd9Sstevel@tonic-gate 		error(gettext("User set directory too long"));
777c478bd9Sstevel@tonic-gate 	CP(tfname, svalue(vi_DIRECTORY));
787c478bd9Sstevel@tonic-gate 	if (stat64((char *)tfname, &stbuf)) {
797c478bd9Sstevel@tonic-gate dumbness:
807c478bd9Sstevel@tonic-gate 		if (setexit() == 0)
817c478bd9Sstevel@tonic-gate 			filioerr(tfname);
827c478bd9Sstevel@tonic-gate 		else
837c478bd9Sstevel@tonic-gate 			putNFL();
847c478bd9Sstevel@tonic-gate 		cleanup(1);
857c478bd9Sstevel@tonic-gate 		exit(++errcnt);
867c478bd9Sstevel@tonic-gate 	}
877c478bd9Sstevel@tonic-gate 	if (!ISDIR(stbuf)) {
887c478bd9Sstevel@tonic-gate 		errno = ENOTDIR;
897c478bd9Sstevel@tonic-gate 		goto dumbness;
907c478bd9Sstevel@tonic-gate 	}
917c478bd9Sstevel@tonic-gate 	CP(tempname, tfname);
927c478bd9Sstevel@tonic-gate 	ichanged = 0;
937c478bd9Sstevel@tonic-gate 	ichang2 = 0;
947c478bd9Sstevel@tonic-gate 	(void) strcat(tfname, "/ExXXXXXX");
957c478bd9Sstevel@tonic-gate 	if ((tfile = mkstemp((char *)tfname)) < 0)
967c478bd9Sstevel@tonic-gate 		goto dumbness;
977c478bd9Sstevel@tonic-gate #ifdef VMUNIX
987c478bd9Sstevel@tonic-gate 	{
99f6db9f27Scf 		extern int stilinc;		/* see below */
1007c478bd9Sstevel@tonic-gate 		stilinc = 0;
1017c478bd9Sstevel@tonic-gate 	}
1027c478bd9Sstevel@tonic-gate #endif
1037c478bd9Sstevel@tonic-gate 	havetmp = 1;
1047c478bd9Sstevel@tonic-gate /* 	brk((unsigned char *)fendcore); */
1057c478bd9Sstevel@tonic-gate }
1067c478bd9Sstevel@tonic-gate 
107f6db9f27Scf void
cleanup(bool all)108f6db9f27Scf cleanup(bool all)
1097c478bd9Sstevel@tonic-gate {
1107c478bd9Sstevel@tonic-gate 	pid_t pgrp;
1117c478bd9Sstevel@tonic-gate 	if (all) {
1127c478bd9Sstevel@tonic-gate 		if (kflag)
1137c478bd9Sstevel@tonic-gate 			crypt_close(perm);
1147c478bd9Sstevel@tonic-gate 		if (xtflag)
1157c478bd9Sstevel@tonic-gate 			crypt_close(tperm);
116f6db9f27Scf 		putpad((unsigned char *)exit_ca_mode);
1177c478bd9Sstevel@tonic-gate 		flush();
1187c478bd9Sstevel@tonic-gate 		if (ioctl(2, TIOCGPGRP, &pgrp) == 0) {
1197c478bd9Sstevel@tonic-gate 			if (pgrp == getpgid(0)) {
1207c478bd9Sstevel@tonic-gate #ifdef XPG4
1217c478bd9Sstevel@tonic-gate 				if (envlines != -1 || envcolumns != -1) {
1227c478bd9Sstevel@tonic-gate 					struct winsize jwin;
1237c478bd9Sstevel@tonic-gate 					jwin.ws_row = oldlines;
1247c478bd9Sstevel@tonic-gate 					jwin.ws_col = oldcolumns;
1257c478bd9Sstevel@tonic-gate 					ioctl(0, TIOCSWINSZ, &jwin);
1267c478bd9Sstevel@tonic-gate 				}
1277c478bd9Sstevel@tonic-gate #endif /* XPG4 */
1287c478bd9Sstevel@tonic-gate 				resetterm();
1297c478bd9Sstevel@tonic-gate 				normtty--;
1307c478bd9Sstevel@tonic-gate 			}
1317c478bd9Sstevel@tonic-gate 		} else {
1327c478bd9Sstevel@tonic-gate #ifdef XPG4
1337c478bd9Sstevel@tonic-gate 			if (envlines != -1 || envcolumns != -1) {
1347c478bd9Sstevel@tonic-gate 				struct winsize jwin;
1357c478bd9Sstevel@tonic-gate 				jwin.ws_row = oldlines;
1367c478bd9Sstevel@tonic-gate 				jwin.ws_col = oldcolumns;
1377c478bd9Sstevel@tonic-gate 				ioctl(0, TIOCSWINSZ, &jwin);
1387c478bd9Sstevel@tonic-gate 			}
1397c478bd9Sstevel@tonic-gate #endif /* XPG4 */
1407c478bd9Sstevel@tonic-gate 			resetterm();
1417c478bd9Sstevel@tonic-gate 			normtty--;
1427c478bd9Sstevel@tonic-gate 		}
1437c478bd9Sstevel@tonic-gate 	}
1447c478bd9Sstevel@tonic-gate 	if (havetmp)
145f6db9f27Scf 		unlink((char *)tfname);
1467c478bd9Sstevel@tonic-gate 	havetmp = 0;
1477c478bd9Sstevel@tonic-gate 	if (all && rfile >= 0) {
148f6db9f27Scf 		unlink((char *)rfname);
1497c478bd9Sstevel@tonic-gate 		close(rfile);
1507c478bd9Sstevel@tonic-gate 		rfile = -1;
1517c478bd9Sstevel@tonic-gate 	}
1527c478bd9Sstevel@tonic-gate 	if (all == 1)
1537c478bd9Sstevel@tonic-gate 		exit(errcnt);
1547c478bd9Sstevel@tonic-gate }
1557c478bd9Sstevel@tonic-gate 
156f6db9f27Scf void
getaline(line tl)15723a1cceaSRoger A. Faulkner getaline(line tl)
1587c478bd9Sstevel@tonic-gate {
159f6db9f27Scf 	unsigned char *bp, *lp;
160f6db9f27Scf 	int nl;
1617c478bd9Sstevel@tonic-gate 
1627c478bd9Sstevel@tonic-gate 	lp = linebuf;
1637c478bd9Sstevel@tonic-gate 	bp = getblock(tl, READ);
1647c478bd9Sstevel@tonic-gate 	nl = nleft;
1657c478bd9Sstevel@tonic-gate 	tl &= ~OFFMSK;
1667c478bd9Sstevel@tonic-gate 	while (*lp++ = *bp++)
1677c478bd9Sstevel@tonic-gate 		if (--nl == 0) {
1687c478bd9Sstevel@tonic-gate 			bp = getblock(tl += INCRMT, READ);
1697c478bd9Sstevel@tonic-gate 			nl = nleft;
1707c478bd9Sstevel@tonic-gate 		}
1717c478bd9Sstevel@tonic-gate }
1727c478bd9Sstevel@tonic-gate 
173a1d23db4Sceastha int
putline(void)174a1d23db4Sceastha putline(void)
1757c478bd9Sstevel@tonic-gate {
176a1d23db4Sceastha 	unsigned char *bp, *lp;
177a1d23db4Sceastha 	unsigned char tmpbp;
178a1d23db4Sceastha 	int nl;
1797c478bd9Sstevel@tonic-gate 	line tl;
1807c478bd9Sstevel@tonic-gate 
1817c478bd9Sstevel@tonic-gate 	dirtcnt++;
1827c478bd9Sstevel@tonic-gate 	lp = linebuf;
1837c478bd9Sstevel@tonic-gate 	change();
1847c478bd9Sstevel@tonic-gate 	tl = tline;
1857c478bd9Sstevel@tonic-gate 	bp = getblock(tl, WRITE);
1867c478bd9Sstevel@tonic-gate 	nl = nleft;
1877c478bd9Sstevel@tonic-gate 	tl &= ~OFFMSK;
1887c478bd9Sstevel@tonic-gate 	while (*bp = *lp++) {
189a1d23db4Sceastha 		tmpbp = *bp;
190a1d23db4Sceastha 		if (tmpbp == '\n') {
191a1d23db4Sceastha 			*bp = 0;
1927c478bd9Sstevel@tonic-gate 			linebp = lp;
1937c478bd9Sstevel@tonic-gate 			break;
194a1d23db4Sceastha 		} else if (junk(*bp++)) {
195f6db9f27Scf 			checkjunk(tmpbp);
196a1d23db4Sceastha 			*--bp;
1977c478bd9Sstevel@tonic-gate 		}
1987c478bd9Sstevel@tonic-gate 		if (--nl == 0) {
1997c478bd9Sstevel@tonic-gate 			bp = getblock(tl += INCRMT, WRITE);
2007c478bd9Sstevel@tonic-gate 			nl = nleft;
2017c478bd9Sstevel@tonic-gate 		}
2027c478bd9Sstevel@tonic-gate 	}
2037c478bd9Sstevel@tonic-gate 	tl = tline;
2047c478bd9Sstevel@tonic-gate 	tline += (((lp - linebuf) + BNDRY - 1) >> SHFT) & 077776;
2057c478bd9Sstevel@tonic-gate 	return (tl);
2067c478bd9Sstevel@tonic-gate }
2077c478bd9Sstevel@tonic-gate 
2087c478bd9Sstevel@tonic-gate int	read();
2097c478bd9Sstevel@tonic-gate int	write();
2107c478bd9Sstevel@tonic-gate 
2117c478bd9Sstevel@tonic-gate unsigned char *
getblock(line atl,int iof)212*d33da75dSToomas Soome getblock(line atl, int iof)
2137c478bd9Sstevel@tonic-gate {
214f6db9f27Scf 	int bno, off;
215f6db9f27Scf 	unsigned char *p1, *p2;
216f6db9f27Scf 	int n;
2177c478bd9Sstevel@tonic-gate 	line *tmpptr;
2187c478bd9Sstevel@tonic-gate 
2197c478bd9Sstevel@tonic-gate 	bno = (atl >> OFFBTS) & BLKMSK;
2207c478bd9Sstevel@tonic-gate 	off = (atl << SHFT) & LBTMSK;
2217c478bd9Sstevel@tonic-gate 	if (bno >= NMBLKS) {
2227c478bd9Sstevel@tonic-gate 		/*
2237c478bd9Sstevel@tonic-gate 		 * When we overflow tmpfile buffers,
2247c478bd9Sstevel@tonic-gate 		 * throw away line which could not be
2257c478bd9Sstevel@tonic-gate 		 * put into buffer.
2267c478bd9Sstevel@tonic-gate 		 */
2277c478bd9Sstevel@tonic-gate 		for (tmpptr = dot; tmpptr < unddol; tmpptr++)
2287c478bd9Sstevel@tonic-gate 			*tmpptr = *(tmpptr+1);
2297c478bd9Sstevel@tonic-gate 		if (dot == dol)
2307c478bd9Sstevel@tonic-gate 			dot--;
2317c478bd9Sstevel@tonic-gate 		dol--;
2327c478bd9Sstevel@tonic-gate 		unddol--;
2337c478bd9Sstevel@tonic-gate 		error(gettext(" Tmp file too large"));
2347c478bd9Sstevel@tonic-gate 	}
2357c478bd9Sstevel@tonic-gate 	nleft = BUFSIZE - off;
2367c478bd9Sstevel@tonic-gate 	if (bno == iblock) {
2377c478bd9Sstevel@tonic-gate 		ichanged |= iof;
2387c478bd9Sstevel@tonic-gate 		hitin2 = 0;
2397c478bd9Sstevel@tonic-gate 		return (ibuff + off);
2407c478bd9Sstevel@tonic-gate 	}
2417c478bd9Sstevel@tonic-gate 	if (bno == iblock2) {
2427c478bd9Sstevel@tonic-gate 		ichang2 |= iof;
2437c478bd9Sstevel@tonic-gate 		hitin2 = 1;
2447c478bd9Sstevel@tonic-gate 		return (ibuff2 + off);
2457c478bd9Sstevel@tonic-gate 	}
2467c478bd9Sstevel@tonic-gate 	if (bno == oblock)
2477c478bd9Sstevel@tonic-gate 		return (obuff + off);
2487c478bd9Sstevel@tonic-gate 	if (iof == READ) {
2497c478bd9Sstevel@tonic-gate 		if (hitin2 == 0) {
2507c478bd9Sstevel@tonic-gate 			if (ichang2) {
251*d33da75dSToomas Soome 				if (xtflag) {
2527c478bd9Sstevel@tonic-gate 					if (run_crypt(0L, ibuff2,
253*d33da75dSToomas Soome 					    CRSIZE, tperm) == -1) {
2547c478bd9Sstevel@tonic-gate 						filioerr(tfname);
255*d33da75dSToomas Soome 					}
256*d33da75dSToomas Soome 				}
2577c478bd9Sstevel@tonic-gate 				blkio(iblock2, ibuff2, write);
2587c478bd9Sstevel@tonic-gate 			}
2597c478bd9Sstevel@tonic-gate 			ichang2 = 0;
2607c478bd9Sstevel@tonic-gate 			iblock2 = bno;
2617c478bd9Sstevel@tonic-gate 			blkio(bno, ibuff2, read);
2627c478bd9Sstevel@tonic-gate 			if (xtflag)
2637c478bd9Sstevel@tonic-gate 				if (run_crypt(0L, ibuff2, CRSIZE, tperm) == -1)
2647c478bd9Sstevel@tonic-gate 					filioerr(tfname);
2657c478bd9Sstevel@tonic-gate 			hitin2 = 1;
2667c478bd9Sstevel@tonic-gate 			return (ibuff2 + off);
2677c478bd9Sstevel@tonic-gate 		}
2687c478bd9Sstevel@tonic-gate 		hitin2 = 0;
2697c478bd9Sstevel@tonic-gate 		if (ichanged) {
2707c478bd9Sstevel@tonic-gate 			if (xtflag)
2717c478bd9Sstevel@tonic-gate 				if (run_crypt(0L, ibuff, CRSIZE, tperm) == -1)
2727c478bd9Sstevel@tonic-gate 					filioerr(tfname);
2737c478bd9Sstevel@tonic-gate 			blkio(iblock, ibuff, write);
2747c478bd9Sstevel@tonic-gate 		}
2757c478bd9Sstevel@tonic-gate 		ichanged = 0;
2767c478bd9Sstevel@tonic-gate 		iblock = bno;
2777c478bd9Sstevel@tonic-gate 		blkio(bno, ibuff, read);
2787c478bd9Sstevel@tonic-gate 		if (xtflag)
2797c478bd9Sstevel@tonic-gate 			if (run_crypt(0L, ibuff, CRSIZE, tperm) == -1)
2807c478bd9Sstevel@tonic-gate 				filioerr(tfname);
2817c478bd9Sstevel@tonic-gate 		return (ibuff + off);
2827c478bd9Sstevel@tonic-gate 	}
2837c478bd9Sstevel@tonic-gate 	if (oblock >= 0) {
2847c478bd9Sstevel@tonic-gate 		if (xtflag) {
2857c478bd9Sstevel@tonic-gate 			/*
2867c478bd9Sstevel@tonic-gate 			 * Encrypt block before writing, so some devious
2877c478bd9Sstevel@tonic-gate 			 * person can't look at temp file while editing.
2887c478bd9Sstevel@tonic-gate 			 */
2897c478bd9Sstevel@tonic-gate 			p1 = obuff;
2907c478bd9Sstevel@tonic-gate 			p2 = crbuf;
2917c478bd9Sstevel@tonic-gate 			n = CRSIZE;
2927c478bd9Sstevel@tonic-gate 			while (n--)
2937c478bd9Sstevel@tonic-gate 				*p2++ = *p1++;
2947c478bd9Sstevel@tonic-gate 			if (run_crypt(0L, crbuf, CRSIZE, tperm) == -1)
2957c478bd9Sstevel@tonic-gate 				filioerr(tfname);
2967c478bd9Sstevel@tonic-gate 			blkio(oblock, crbuf, write);
2977c478bd9Sstevel@tonic-gate 		} else
2987c478bd9Sstevel@tonic-gate 			blkio(oblock, obuff, write);
2997c478bd9Sstevel@tonic-gate 	}
3007c478bd9Sstevel@tonic-gate 	oblock = bno;
3017c478bd9Sstevel@tonic-gate 	return (obuff + off);
3027c478bd9Sstevel@tonic-gate }
3037c478bd9Sstevel@tonic-gate 
3047c478bd9Sstevel@tonic-gate #ifdef	VMUNIX
3057c478bd9Sstevel@tonic-gate #define	INCORB	64
3067c478bd9Sstevel@tonic-gate unsigned char	incorb[INCORB+1][BUFSIZE];
3077c478bd9Sstevel@tonic-gate #define	pagrnd(a)	((unsigned char *)(((int)a)&~(BUFSIZE-1)))
3087c478bd9Sstevel@tonic-gate int	stilinc;	/* up to here not written yet */
3097c478bd9Sstevel@tonic-gate #endif
3107c478bd9Sstevel@tonic-gate 
311f6db9f27Scf void
blkio(short b,unsigned char * buf,int (* iofcn)())312f6db9f27Scf blkio(short b, unsigned char *buf, int (*iofcn)())
3137c478bd9Sstevel@tonic-gate {
3147c478bd9Sstevel@tonic-gate 
3157c478bd9Sstevel@tonic-gate #ifdef VMUNIX
3167c478bd9Sstevel@tonic-gate 	if (b < INCORB) {
3177c478bd9Sstevel@tonic-gate 		if (iofcn == read) {
3187c478bd9Sstevel@tonic-gate 			bcopy(pagrnd(incorb[b+1]), buf, BUFSIZE);
3197c478bd9Sstevel@tonic-gate 			return;
3207c478bd9Sstevel@tonic-gate 		}
3217c478bd9Sstevel@tonic-gate 		bcopy(buf, pagrnd(incorb[b+1]), BUFSIZE);
3227c478bd9Sstevel@tonic-gate 		if (laste) {
3237c478bd9Sstevel@tonic-gate 			if (b >= stilinc)
3247c478bd9Sstevel@tonic-gate 				stilinc = b + 1;
3257c478bd9Sstevel@tonic-gate 			return;
3267c478bd9Sstevel@tonic-gate 		}
3277c478bd9Sstevel@tonic-gate 	} else if (stilinc)
3287c478bd9Sstevel@tonic-gate 		tflush();
3297c478bd9Sstevel@tonic-gate #endif
3307c478bd9Sstevel@tonic-gate 	lseek(tfile, (long)(unsigned)b * BUFSIZE, 0);
3317c478bd9Sstevel@tonic-gate 	if ((*iofcn)(tfile, buf, BUFSIZE) != BUFSIZE)
3327c478bd9Sstevel@tonic-gate 		filioerr(tfname);
3337c478bd9Sstevel@tonic-gate }
3347c478bd9Sstevel@tonic-gate 
3357c478bd9Sstevel@tonic-gate #ifdef VMUNIX
336f6db9f27Scf void
tlaste(void)337f6db9f27Scf tlaste(void)
3387c478bd9Sstevel@tonic-gate {
3397c478bd9Sstevel@tonic-gate 
3407c478bd9Sstevel@tonic-gate 	if (stilinc)
3417c478bd9Sstevel@tonic-gate 		dirtcnt = 0;
3427c478bd9Sstevel@tonic-gate }
3437c478bd9Sstevel@tonic-gate 
344f6db9f27Scf void
tflush(void)345f6db9f27Scf tflush(void)
3467c478bd9Sstevel@tonic-gate {
3477c478bd9Sstevel@tonic-gate 	int i = stilinc;
3487c478bd9Sstevel@tonic-gate 
3497c478bd9Sstevel@tonic-gate 	stilinc = 0;
3507c478bd9Sstevel@tonic-gate 	lseek(tfile, (long)0, 0);
3517c478bd9Sstevel@tonic-gate 	if (write(tfile, pagrnd(incorb[1]), i * BUFSIZE) != (i * BUFSIZE))
3527c478bd9Sstevel@tonic-gate 		filioerr(tfname);
3537c478bd9Sstevel@tonic-gate }
3547c478bd9Sstevel@tonic-gate #endif
3557c478bd9Sstevel@tonic-gate 
3567c478bd9Sstevel@tonic-gate /*
3577c478bd9Sstevel@tonic-gate  * Synchronize the state of the temporary file in case
3587c478bd9Sstevel@tonic-gate  * a crash occurs.
3597c478bd9Sstevel@tonic-gate  */
360f6db9f27Scf void
synctmp(void)361f6db9f27Scf synctmp(void)
3627c478bd9Sstevel@tonic-gate {
363f6db9f27Scf 	int cnt;
364f6db9f27Scf 	line *a;
365f6db9f27Scf 	short *bp;
366f6db9f27Scf 	unsigned char *p1, *p2;
367f6db9f27Scf 	int n;
3687c478bd9Sstevel@tonic-gate 
3697c478bd9Sstevel@tonic-gate #ifdef VMUNIX
3707c478bd9Sstevel@tonic-gate 	if (stilinc)
3717c478bd9Sstevel@tonic-gate 		return;
3727c478bd9Sstevel@tonic-gate #endif
3737c478bd9Sstevel@tonic-gate 	if (dol == zero)
3747c478bd9Sstevel@tonic-gate 		return;
3757c478bd9Sstevel@tonic-gate 	/*
3767c478bd9Sstevel@tonic-gate 	 * In theory, we need to encrypt iblock and iblock2 before writing
3777c478bd9Sstevel@tonic-gate 	 * them out, as well as oblock, but in practice ichanged and ichang2
3787c478bd9Sstevel@tonic-gate 	 * can never be set, so this isn't really needed.  Likewise, the
3797c478bd9Sstevel@tonic-gate 	 * code in getblock above for iblock+iblock2 isn't needed.
3807c478bd9Sstevel@tonic-gate 	 */
3817c478bd9Sstevel@tonic-gate 	if (ichanged)
3827c478bd9Sstevel@tonic-gate 		blkio(iblock, ibuff, write);
3837c478bd9Sstevel@tonic-gate 	ichanged = 0;
3847c478bd9Sstevel@tonic-gate 	if (ichang2)
3857c478bd9Sstevel@tonic-gate 		blkio(iblock2, ibuff2, write);
3867c478bd9Sstevel@tonic-gate 	ichang2 = 0;
3877c478bd9Sstevel@tonic-gate 	if (oblock != -1)
3887c478bd9Sstevel@tonic-gate 	if (xtflag) {
3897c478bd9Sstevel@tonic-gate 		/*
3907c478bd9Sstevel@tonic-gate 		 * Encrypt block before writing, so some devious
3917c478bd9Sstevel@tonic-gate 		 * person can't look at temp file while editing.
3927c478bd9Sstevel@tonic-gate 		 */
3937c478bd9Sstevel@tonic-gate 		p1 = obuff;
3947c478bd9Sstevel@tonic-gate 		p2 = crbuf;
3957c478bd9Sstevel@tonic-gate 		n = CRSIZE;
3967c478bd9Sstevel@tonic-gate 		while (n--)
3977c478bd9Sstevel@tonic-gate 			*p2++ = *p1++;
398*d33da75dSToomas Soome 		if (run_crypt(0L, crbuf, CRSIZE, tperm) == -1)
399*d33da75dSToomas Soome 			filioerr(tfname);
4007c478bd9Sstevel@tonic-gate 		blkio(oblock, crbuf, write);
4017c478bd9Sstevel@tonic-gate 	} else
4027c478bd9Sstevel@tonic-gate 		blkio(oblock, obuff, write);
4037c478bd9Sstevel@tonic-gate 	time(&H.Time);
4047c478bd9Sstevel@tonic-gate 	uid = getuid();
4057c478bd9Sstevel@tonic-gate 	if (xtflag)
4067c478bd9Sstevel@tonic-gate 		H.encrypted = 1;
4077c478bd9Sstevel@tonic-gate 	else
4087c478bd9Sstevel@tonic-gate 		H.encrypted = 0;
4097c478bd9Sstevel@tonic-gate 	*zero = (line) H.Time;
4107c478bd9Sstevel@tonic-gate 	for (a = zero, bp = blocks; a <= dol;
411a1d23db4Sceastha 	    a += BUFSIZE / sizeof (*a), bp++) {
4127c478bd9Sstevel@tonic-gate 		if (bp >= &H.Blocks[LBLKS-1])
4137c478bd9Sstevel@tonic-gate 			error(gettext(
414a1d23db4Sceastha 			    "file too large to recover with -r option"));
4157c478bd9Sstevel@tonic-gate 		if (*bp < 0) {
4167c478bd9Sstevel@tonic-gate 			tline = (tline + OFFMSK) &~ OFFMSK;
4177c478bd9Sstevel@tonic-gate 			*bp = ((tline >> OFFBTS) & BLKMSK);
4187c478bd9Sstevel@tonic-gate 			if (*bp > NMBLKS)
4197c478bd9Sstevel@tonic-gate 				error(gettext(" Tmp file too large"));
4207c478bd9Sstevel@tonic-gate 			tline += INCRMT;
4217c478bd9Sstevel@tonic-gate 			oblock = *bp + 1;
4227c478bd9Sstevel@tonic-gate 			bp[1] = -1;
4237c478bd9Sstevel@tonic-gate 		}
4247c478bd9Sstevel@tonic-gate 		lseek(tfile, (long)(unsigned)*bp * BUFSIZE, 0);
4257c478bd9Sstevel@tonic-gate 		cnt = ((dol - a) + 2) * sizeof (line);
4267c478bd9Sstevel@tonic-gate 		if (cnt > BUFSIZE)
4277c478bd9Sstevel@tonic-gate 			cnt = BUFSIZE;
4287c478bd9Sstevel@tonic-gate 		if (write(tfile, (char *)a, cnt) != cnt) {
4297c478bd9Sstevel@tonic-gate oops:
4307c478bd9Sstevel@tonic-gate 			*zero = 0;
4317c478bd9Sstevel@tonic-gate 			filioerr(tfname);
4327c478bd9Sstevel@tonic-gate 		}
4337c478bd9Sstevel@tonic-gate 		*zero = 0;
4347c478bd9Sstevel@tonic-gate 	}
4357c478bd9Sstevel@tonic-gate 	flines = lineDOL();
4367c478bd9Sstevel@tonic-gate 	lseek(tfile, 0l, 0);
4377c478bd9Sstevel@tonic-gate 	if (write(tfile, (char *)&H, sizeof (H)) != sizeof (H))
4387c478bd9Sstevel@tonic-gate 		goto oops;
4397c478bd9Sstevel@tonic-gate }
4407c478bd9Sstevel@tonic-gate 
441f6db9f27Scf void
TSYNC(void)442f6db9f27Scf TSYNC(void)
4437c478bd9Sstevel@tonic-gate {
4447c478bd9Sstevel@tonic-gate 
4457c478bd9Sstevel@tonic-gate 	if (dirtcnt > MAXDIRT) {
4467c478bd9Sstevel@tonic-gate #ifdef VMUNIX
4477c478bd9Sstevel@tonic-gate 		if (stilinc)
4487c478bd9Sstevel@tonic-gate 			tflush();
4497c478bd9Sstevel@tonic-gate #endif
4507c478bd9Sstevel@tonic-gate 		dirtcnt = 0;
4517c478bd9Sstevel@tonic-gate 		synctmp();
4527c478bd9Sstevel@tonic-gate 	}
4537c478bd9Sstevel@tonic-gate }
4547c478bd9Sstevel@tonic-gate 
4557c478bd9Sstevel@tonic-gate /*
4567c478bd9Sstevel@tonic-gate  * Named buffer routines.
4577c478bd9Sstevel@tonic-gate  * These are implemented differently than the main buffer.
4587c478bd9Sstevel@tonic-gate  * Each named buffer has a chain of blocks in the register file.
4597c478bd9Sstevel@tonic-gate  * Each block contains roughly 508 chars of text,
4607c478bd9Sstevel@tonic-gate  * and a previous and next block number.  We also have information
4617c478bd9Sstevel@tonic-gate  * about which blocks came from deletes of multiple partial lines,
4627c478bd9Sstevel@tonic-gate  * e.g. deleting a sentence or a LISP object.
4637c478bd9Sstevel@tonic-gate  *
4647c478bd9Sstevel@tonic-gate  * We maintain a free map for the temp file.  To free the blocks
4657c478bd9Sstevel@tonic-gate  * in a register we must read the blocks to find how they are chained
4667c478bd9Sstevel@tonic-gate  * together.
4677c478bd9Sstevel@tonic-gate  *
4687c478bd9Sstevel@tonic-gate  * BUG:		The default savind of deleted lines in numbered
4697c478bd9Sstevel@tonic-gate  *		buffers may be rather inefficient; it hasn't been profiled.
4707c478bd9Sstevel@tonic-gate  */
4717c478bd9Sstevel@tonic-gate struct	strreg {
4727c478bd9Sstevel@tonic-gate 	short	rg_flags;
4737c478bd9Sstevel@tonic-gate 	short	rg_nleft;
4747c478bd9Sstevel@tonic-gate 	short	rg_first;
4757c478bd9Sstevel@tonic-gate 	short	rg_last;
4767c478bd9Sstevel@tonic-gate } strregs[('z'-'a'+1) + ('9'-'0'+1)], *strp;
4777c478bd9Sstevel@tonic-gate 
4787c478bd9Sstevel@tonic-gate struct	rbuf {
4797c478bd9Sstevel@tonic-gate 	short	rb_prev;
4807c478bd9Sstevel@tonic-gate 	short	rb_next;
4817c478bd9Sstevel@tonic-gate 	unsigned char	rb_text[BUFSIZE - 2 * sizeof (short)];
4827c478bd9Sstevel@tonic-gate } *rbuf, KILLrbuf, putrbuf, YANKrbuf, regrbuf;
4837c478bd9Sstevel@tonic-gate #ifdef VMUNIX
4847c478bd9Sstevel@tonic-gate short	rused[256];
4857c478bd9Sstevel@tonic-gate #else
4867c478bd9Sstevel@tonic-gate short	rused[32];
4877c478bd9Sstevel@tonic-gate #endif
4887c478bd9Sstevel@tonic-gate short	rnleft;
4897c478bd9Sstevel@tonic-gate short	rblock;
4907c478bd9Sstevel@tonic-gate short	rnext;
4917c478bd9Sstevel@tonic-gate unsigned char	*rbufcp;
4927c478bd9Sstevel@tonic-gate 
493f6db9f27Scf void
regio(short b,int (* iofcn)())494f6db9f27Scf regio(short b, int (*iofcn)())
4957c478bd9Sstevel@tonic-gate {
4967c478bd9Sstevel@tonic-gate 
4977c478bd9Sstevel@tonic-gate 	if (rfile == -1) {
4987c478bd9Sstevel@tonic-gate 		CP(rfname, tempname);
4997c478bd9Sstevel@tonic-gate 		(void) strcat(rfname, "/RxXXXXXX");
5007c478bd9Sstevel@tonic-gate 		if ((rfile = mkstemp((char *)rfname)) < 0)
5017c478bd9Sstevel@tonic-gate 			filioerr(rfname);
5027c478bd9Sstevel@tonic-gate 	}
5037c478bd9Sstevel@tonic-gate 	lseek(rfile, (long)b * BUFSIZE, 0);
5047c478bd9Sstevel@tonic-gate 	if ((*iofcn)(rfile, rbuf, BUFSIZE) != BUFSIZE)
5057c478bd9Sstevel@tonic-gate 		filioerr(rfname);
5067c478bd9Sstevel@tonic-gate 	rblock = b;
5077c478bd9Sstevel@tonic-gate }
5087c478bd9Sstevel@tonic-gate 
509f6db9f27Scf int
REGblk(void)510f6db9f27Scf REGblk(void)
5117c478bd9Sstevel@tonic-gate {
512f6db9f27Scf 	int i, j, m;
5137c478bd9Sstevel@tonic-gate 
5147c478bd9Sstevel@tonic-gate 	for (i = 0; i < sizeof (rused) / sizeof (rused[0]); i++) {
5157c478bd9Sstevel@tonic-gate 		m = (rused[i] ^ 0177777) & 0177777;
5167c478bd9Sstevel@tonic-gate 		if (i == 0)
5177c478bd9Sstevel@tonic-gate 			m &= ~1;
5187c478bd9Sstevel@tonic-gate 		if (m != 0) {
5197c478bd9Sstevel@tonic-gate 			j = 0;
5207c478bd9Sstevel@tonic-gate 			while ((m & 1) == 0)
5217c478bd9Sstevel@tonic-gate 				j++, m >>= 1;
5227c478bd9Sstevel@tonic-gate 			rused[i] |= (1 << j);
5237c478bd9Sstevel@tonic-gate #ifdef RDEBUG
524f6db9f27Scf 			viprintf("allocating block %d\n", i * 16 + j);
5257c478bd9Sstevel@tonic-gate #endif
5267c478bd9Sstevel@tonic-gate 			return (i * 16 + j);
5277c478bd9Sstevel@tonic-gate 		}
5287c478bd9Sstevel@tonic-gate 	}
5297c478bd9Sstevel@tonic-gate 	error(gettext("Out of register space (ugh)"));
5307c478bd9Sstevel@tonic-gate 	/*NOTREACHED*/
531f6db9f27Scf 	return (0);
5327c478bd9Sstevel@tonic-gate }
5337c478bd9Sstevel@tonic-gate 
534*d33da75dSToomas Soome struct strreg *
mapreg(int c)535*d33da75dSToomas Soome mapreg(int c)
5367c478bd9Sstevel@tonic-gate {
5377c478bd9Sstevel@tonic-gate 
5387c478bd9Sstevel@tonic-gate 	if (isupper(c))
5397c478bd9Sstevel@tonic-gate 		c = tolower(c);
5407c478bd9Sstevel@tonic-gate 	return (isdigit(c) ? &strregs[('z'-'a'+1)+(c-'0')] : &strregs[c-'a']);
5417c478bd9Sstevel@tonic-gate }
5427c478bd9Sstevel@tonic-gate 
5437c478bd9Sstevel@tonic-gate int	shread();
5447c478bd9Sstevel@tonic-gate 
545f6db9f27Scf void
KILLreg(int c)546f6db9f27Scf KILLreg(int c)
5477c478bd9Sstevel@tonic-gate {
548f6db9f27Scf 	struct strreg *sp;
5497c478bd9Sstevel@tonic-gate 
5507c478bd9Sstevel@tonic-gate 	rbuf = &KILLrbuf;
5517c478bd9Sstevel@tonic-gate 	sp = mapreg(c);
5527c478bd9Sstevel@tonic-gate 	rblock = sp->rg_first;
5537c478bd9Sstevel@tonic-gate 	sp->rg_first = sp->rg_last = 0;
5547c478bd9Sstevel@tonic-gate 	sp->rg_flags = sp->rg_nleft = 0;
5557c478bd9Sstevel@tonic-gate 	while (rblock != 0) {
5567c478bd9Sstevel@tonic-gate #ifdef RDEBUG
557f6db9f27Scf 		viprintf("freeing block %d\n", rblock);
5587c478bd9Sstevel@tonic-gate #endif
5597c478bd9Sstevel@tonic-gate 		rused[rblock / 16] &= ~(1 << (rblock % 16));
5607c478bd9Sstevel@tonic-gate 		regio(rblock, shread);
5617c478bd9Sstevel@tonic-gate 		rblock = rbuf->rb_next;
5627c478bd9Sstevel@tonic-gate 	}
5637c478bd9Sstevel@tonic-gate }
5647c478bd9Sstevel@tonic-gate 
5657c478bd9Sstevel@tonic-gate /*VARARGS*/
566f6db9f27Scf int
shread(void)567f6db9f27Scf shread(void)
5687c478bd9Sstevel@tonic-gate {
5697c478bd9Sstevel@tonic-gate 	struct front { short a; short b; };
5707c478bd9Sstevel@tonic-gate 
5717c478bd9Sstevel@tonic-gate 	if (read(rfile, (char *)rbuf, sizeof (struct front)) ==
572a1d23db4Sceastha 	    sizeof (struct front))
5737c478bd9Sstevel@tonic-gate 		return (sizeof (struct rbuf));
5747c478bd9Sstevel@tonic-gate 	return (0);
5757c478bd9Sstevel@tonic-gate }
5767c478bd9Sstevel@tonic-gate 
5777c478bd9Sstevel@tonic-gate int	getREG();
5787c478bd9Sstevel@tonic-gate 
579f6db9f27Scf int
putreg(unsigned char c)580f6db9f27Scf putreg(unsigned char c)
5817c478bd9Sstevel@tonic-gate {
582f6db9f27Scf 	line *odot = dot;
583f6db9f27Scf 	line *odol = dol;
584f6db9f27Scf 	int cnt;
5857c478bd9Sstevel@tonic-gate 
5867c478bd9Sstevel@tonic-gate 	deletenone();
5877c478bd9Sstevel@tonic-gate 	appendnone();
5887c478bd9Sstevel@tonic-gate 	rbuf = &putrbuf;
5897c478bd9Sstevel@tonic-gate 	rnleft = 0;
5907c478bd9Sstevel@tonic-gate 	rblock = 0;
5917c478bd9Sstevel@tonic-gate 	rnext = mapreg(c)->rg_first;
5927c478bd9Sstevel@tonic-gate 	if (rnext == 0) {
5937c478bd9Sstevel@tonic-gate 		if (inopen) {
5947c478bd9Sstevel@tonic-gate 			splitw++;
5957c478bd9Sstevel@tonic-gate 			vclean();
5967c478bd9Sstevel@tonic-gate 			vgoto(WECHO, 0);
5977c478bd9Sstevel@tonic-gate 		}
5987c478bd9Sstevel@tonic-gate 		vreg = -1;
5997c478bd9Sstevel@tonic-gate 		error(gettext("Nothing in register %c"), c);
6007c478bd9Sstevel@tonic-gate 	}
6017c478bd9Sstevel@tonic-gate 	if (inopen && partreg(c)) {
6027c478bd9Sstevel@tonic-gate 		if (!FIXUNDO) {
6037c478bd9Sstevel@tonic-gate 			splitw++; vclean(); vgoto(WECHO, 0); vreg = -1;
6047c478bd9Sstevel@tonic-gate 			error(gettext("Can't put partial line inside macro"));
6057c478bd9Sstevel@tonic-gate 		}
6067c478bd9Sstevel@tonic-gate 		squish();
6077c478bd9Sstevel@tonic-gate 		addr1 = addr2 = dol;
6087c478bd9Sstevel@tonic-gate 	}
6097c478bd9Sstevel@tonic-gate 	cnt = append(getREG, addr2);
6107c478bd9Sstevel@tonic-gate 	if (inopen && partreg(c)) {
6117c478bd9Sstevel@tonic-gate 		unddol = dol;
6127c478bd9Sstevel@tonic-gate 		dol = odol;
6137c478bd9Sstevel@tonic-gate 		dot = odot;
6147c478bd9Sstevel@tonic-gate 		pragged(0);
6157c478bd9Sstevel@tonic-gate 	}
6167c478bd9Sstevel@tonic-gate 	killcnt(cnt);
6177c478bd9Sstevel@tonic-gate 	notecnt = cnt;
618f6db9f27Scf 	return (0);
6197c478bd9Sstevel@tonic-gate }
6207c478bd9Sstevel@tonic-gate 
621f6db9f27Scf short
partreg(unsigned char c)622f6db9f27Scf partreg(unsigned char c)
6237c478bd9Sstevel@tonic-gate {
6247c478bd9Sstevel@tonic-gate 
6257c478bd9Sstevel@tonic-gate 	return (mapreg(c)->rg_flags);
6267c478bd9Sstevel@tonic-gate }
6277c478bd9Sstevel@tonic-gate 
628f6db9f27Scf void
notpart(int c)629f6db9f27Scf notpart(int c)
6307c478bd9Sstevel@tonic-gate {
6317c478bd9Sstevel@tonic-gate 
6327c478bd9Sstevel@tonic-gate 	if (c)
6337c478bd9Sstevel@tonic-gate 		mapreg(c)->rg_flags = 0;
6347c478bd9Sstevel@tonic-gate }
6357c478bd9Sstevel@tonic-gate 
636f6db9f27Scf int
getREG(void)637f6db9f27Scf getREG(void)
6387c478bd9Sstevel@tonic-gate {
639f6db9f27Scf 	unsigned char *lp = linebuf;
640f6db9f27Scf 	int c;
6417c478bd9Sstevel@tonic-gate 
6427c478bd9Sstevel@tonic-gate 	for (;;) {
6437c478bd9Sstevel@tonic-gate 		if (rnleft == 0) {
6447c478bd9Sstevel@tonic-gate 			if (rnext == 0)
6457c478bd9Sstevel@tonic-gate 				return (EOF);
6467c478bd9Sstevel@tonic-gate 			regio(rnext, read);
6477c478bd9Sstevel@tonic-gate 			rnext = rbuf->rb_next;
6487c478bd9Sstevel@tonic-gate 			rbufcp = rbuf->rb_text;
6497c478bd9Sstevel@tonic-gate 			rnleft = sizeof (rbuf->rb_text);
6507c478bd9Sstevel@tonic-gate 		}
6517c478bd9Sstevel@tonic-gate 		c = *rbufcp;
6527c478bd9Sstevel@tonic-gate 		if (c == 0)
6537c478bd9Sstevel@tonic-gate 			return (EOF);
6547c478bd9Sstevel@tonic-gate 		rbufcp++, --rnleft;
6557c478bd9Sstevel@tonic-gate 		if (c == '\n') {
6567c478bd9Sstevel@tonic-gate 			*lp++ = 0;
6577c478bd9Sstevel@tonic-gate 			return (0);
6587c478bd9Sstevel@tonic-gate 		}
6597c478bd9Sstevel@tonic-gate 		*lp++ = c;
6607c478bd9Sstevel@tonic-gate 	}
6617c478bd9Sstevel@tonic-gate }
6627c478bd9Sstevel@tonic-gate 
663f6db9f27Scf int
YANKreg(int c)664f6db9f27Scf YANKreg(int c)
6657c478bd9Sstevel@tonic-gate {
666f6db9f27Scf 	line *addr;
667f6db9f27Scf 	struct strreg *sp;
6687c478bd9Sstevel@tonic-gate 	unsigned char savelb[LBSIZE];
6697c478bd9Sstevel@tonic-gate 
6707c478bd9Sstevel@tonic-gate 	if (isdigit(c))
6717c478bd9Sstevel@tonic-gate 		kshift();
6727c478bd9Sstevel@tonic-gate 	if (islower(c))
6737c478bd9Sstevel@tonic-gate 		KILLreg(c);
6747c478bd9Sstevel@tonic-gate 	strp = sp = mapreg(c);
6757c478bd9Sstevel@tonic-gate 	sp->rg_flags = inopen && cursor && wcursor;
6767c478bd9Sstevel@tonic-gate 	rbuf = &YANKrbuf;
6777c478bd9Sstevel@tonic-gate 	if (sp->rg_last) {
6787c478bd9Sstevel@tonic-gate 		regio(sp->rg_last, read);
6797c478bd9Sstevel@tonic-gate 		rnleft = sp->rg_nleft;
6807c478bd9Sstevel@tonic-gate 		rbufcp = &rbuf->rb_text[sizeof (rbuf->rb_text) - rnleft];
6817c478bd9Sstevel@tonic-gate 	} else {
6827c478bd9Sstevel@tonic-gate 		rblock = 0;
6837c478bd9Sstevel@tonic-gate 		rnleft = 0;
6847c478bd9Sstevel@tonic-gate 	}
6857c478bd9Sstevel@tonic-gate 	CP(savelb, linebuf);
6867c478bd9Sstevel@tonic-gate 	for (addr = addr1; addr <= addr2; addr++) {
68723a1cceaSRoger A. Faulkner 		getaline(*addr);
6887c478bd9Sstevel@tonic-gate 		if (sp->rg_flags) {
6897c478bd9Sstevel@tonic-gate 			if (addr == addr2)
6907c478bd9Sstevel@tonic-gate 				*wcursor = 0;
6917c478bd9Sstevel@tonic-gate 			if (addr == addr1)
6927c478bd9Sstevel@tonic-gate 				strcpy(linebuf, cursor);
6937c478bd9Sstevel@tonic-gate 		}
6947c478bd9Sstevel@tonic-gate 		YANKline();
6957c478bd9Sstevel@tonic-gate 	}
6967c478bd9Sstevel@tonic-gate 	rbflush();
6977c478bd9Sstevel@tonic-gate 	killed();
6987c478bd9Sstevel@tonic-gate 	CP(linebuf, savelb);
699f6db9f27Scf 	return (0);
7007c478bd9Sstevel@tonic-gate }
7017c478bd9Sstevel@tonic-gate 
702f6db9f27Scf void
kshift(void)703f6db9f27Scf kshift(void)
7047c478bd9Sstevel@tonic-gate {
705f6db9f27Scf 	int i;
7067c478bd9Sstevel@tonic-gate 
7077c478bd9Sstevel@tonic-gate 	KILLreg('9');
7087c478bd9Sstevel@tonic-gate 	for (i = '8'; i >= '0'; i--)
7097c478bd9Sstevel@tonic-gate 		copy(mapreg(i+1), mapreg(i), sizeof (struct strreg));
7107c478bd9Sstevel@tonic-gate }
7117c478bd9Sstevel@tonic-gate 
712f6db9f27Scf void
YANKline(void)713f6db9f27Scf YANKline(void)
7147c478bd9Sstevel@tonic-gate {
715f6db9f27Scf 	unsigned char *lp = linebuf;
716f6db9f27Scf 	struct rbuf *rp = rbuf;
717f6db9f27Scf 	int c;
7187c478bd9Sstevel@tonic-gate 
7197c478bd9Sstevel@tonic-gate 	do {
7207c478bd9Sstevel@tonic-gate 		c = *lp++;
7217c478bd9Sstevel@tonic-gate 		if (c == 0)
7227c478bd9Sstevel@tonic-gate 			c = '\n';
7237c478bd9Sstevel@tonic-gate 		if (rnleft == 0) {
7247c478bd9Sstevel@tonic-gate 			rp->rb_next = REGblk();
7257c478bd9Sstevel@tonic-gate 			rbflush();
7267c478bd9Sstevel@tonic-gate 			rblock = rp->rb_next;
7277c478bd9Sstevel@tonic-gate 			rp->rb_next = 0;
7287c478bd9Sstevel@tonic-gate 			rp->rb_prev = rblock;
7297c478bd9Sstevel@tonic-gate 			rnleft = sizeof (rp->rb_text);
7307c478bd9Sstevel@tonic-gate 			rbufcp = rp->rb_text;
7317c478bd9Sstevel@tonic-gate 		}
7327c478bd9Sstevel@tonic-gate 		*rbufcp++ = c;
7337c478bd9Sstevel@tonic-gate 		--rnleft;
7347c478bd9Sstevel@tonic-gate 	} while (c != '\n');
7357c478bd9Sstevel@tonic-gate 	if (rnleft)
7367c478bd9Sstevel@tonic-gate 		*rbufcp = 0;
7377c478bd9Sstevel@tonic-gate }
7387c478bd9Sstevel@tonic-gate 
739f6db9f27Scf void
rbflush(void)740f6db9f27Scf rbflush(void)
7417c478bd9Sstevel@tonic-gate {
742f6db9f27Scf 	struct strreg *sp = strp;
7437c478bd9Sstevel@tonic-gate 
7447c478bd9Sstevel@tonic-gate 	if (rblock == 0)
7457c478bd9Sstevel@tonic-gate 		return;
7467c478bd9Sstevel@tonic-gate 	regio(rblock, write);
7477c478bd9Sstevel@tonic-gate 	if (sp->rg_first == 0)
7487c478bd9Sstevel@tonic-gate 		sp->rg_first = rblock;
7497c478bd9Sstevel@tonic-gate 	sp->rg_last = rblock;
7507c478bd9Sstevel@tonic-gate 	sp->rg_nleft = rnleft;
7517c478bd9Sstevel@tonic-gate }
7527c478bd9Sstevel@tonic-gate 
7537c478bd9Sstevel@tonic-gate /* Register c to char buffer buf of size buflen */
754f6db9f27Scf void
regbuf(unsigned char c,unsigned char * buf,int buflen)755*d33da75dSToomas Soome regbuf(unsigned char c, unsigned char *buf, int buflen)
7567c478bd9Sstevel@tonic-gate {
757f6db9f27Scf 	unsigned char *p, *lp;
7587c478bd9Sstevel@tonic-gate 
7597c478bd9Sstevel@tonic-gate 	rbuf = &regrbuf;
7607c478bd9Sstevel@tonic-gate 	rnleft = 0;
7617c478bd9Sstevel@tonic-gate 	rblock = 0;
7627c478bd9Sstevel@tonic-gate 	rnext = mapreg(c)->rg_first;
7637c478bd9Sstevel@tonic-gate 	if (rnext == 0) {
7647c478bd9Sstevel@tonic-gate 		*buf = 0;
7657c478bd9Sstevel@tonic-gate 		error(gettext("Nothing in register %c"), c);
7667c478bd9Sstevel@tonic-gate 	}
7677c478bd9Sstevel@tonic-gate 	p = buf;
7687c478bd9Sstevel@tonic-gate 	while (getREG() == 0) {
7697c478bd9Sstevel@tonic-gate 		lp = linebuf;
7707c478bd9Sstevel@tonic-gate 		while (*lp) {
7717c478bd9Sstevel@tonic-gate 			if (p >= &buf[buflen])
7727c478bd9Sstevel@tonic-gate 				error(value(vi_TERSE) ?
7737c478bd9Sstevel@tonic-gate gettext("Register too long") : gettext("Register too long to fit in memory"));
7747c478bd9Sstevel@tonic-gate 			*p++ = *lp++;
7757c478bd9Sstevel@tonic-gate 		}
7767c478bd9Sstevel@tonic-gate 		*p++ = '\n';
7777c478bd9Sstevel@tonic-gate 	}
7787c478bd9Sstevel@tonic-gate 	if (partreg(c)) p--;
7797c478bd9Sstevel@tonic-gate 	*p = '\0';
7807c478bd9Sstevel@tonic-gate 	getDOT();
7817c478bd9Sstevel@tonic-gate }
7827c478bd9Sstevel@tonic-gate 
7837c478bd9Sstevel@tonic-gate #ifdef TRACE
7847c478bd9Sstevel@tonic-gate 
7857c478bd9Sstevel@tonic-gate /*
7867c478bd9Sstevel@tonic-gate  * Test code for displaying named registers.
7877c478bd9Sstevel@tonic-gate  */
7887c478bd9Sstevel@tonic-gate 
shownam()7897c478bd9Sstevel@tonic-gate shownam()
7907c478bd9Sstevel@tonic-gate {
7917c478bd9Sstevel@tonic-gate 	int k;
7927c478bd9Sstevel@tonic-gate 
793f6db9f27Scf 	viprintf("\nRegister   Contents\n");
794f6db9f27Scf 	viprintf("========   ========\n");
7957c478bd9Sstevel@tonic-gate 	for (k = 'a'; k <= 'z'; k++) {
7967c478bd9Sstevel@tonic-gate 		rbuf = &putrbuf;
7977c478bd9Sstevel@tonic-gate 		rnleft = 0;
7987c478bd9Sstevel@tonic-gate 		rblock = 0;
7997c478bd9Sstevel@tonic-gate 		rnext = mapreg(k)->rg_first;
800f6db9f27Scf 		viprintf(" %c:", k);
8017c478bd9Sstevel@tonic-gate 		if (rnext == 0)
802f6db9f27Scf 			viprintf("\t\tNothing in register.\n");
8037c478bd9Sstevel@tonic-gate 		while (getREG() == 0) {
804f6db9f27Scf 			viprintf("\t\t%s\n", linebuf);
8057c478bd9Sstevel@tonic-gate 		}
8067c478bd9Sstevel@tonic-gate 	}
8077c478bd9Sstevel@tonic-gate 	return (0);
8087c478bd9Sstevel@tonic-gate }
8097c478bd9Sstevel@tonic-gate 
8107c478bd9Sstevel@tonic-gate /*
8117c478bd9Sstevel@tonic-gate  * Test code for displaying numbered registers.
8127c478bd9Sstevel@tonic-gate  */
8137c478bd9Sstevel@tonic-gate 
shownbr()8147c478bd9Sstevel@tonic-gate shownbr()
8157c478bd9Sstevel@tonic-gate {
8167c478bd9Sstevel@tonic-gate 	int k;
8177c478bd9Sstevel@tonic-gate 
818f6db9f27Scf 	viprintf("\nRegister   Contents\n");
819f6db9f27Scf 	viprintf("========   ========\n");
8207c478bd9Sstevel@tonic-gate 	for (k = '1'; k <= '9'; k++) {
8217c478bd9Sstevel@tonic-gate 		rbuf = &putrbuf;
8227c478bd9Sstevel@tonic-gate 		rnleft = 0;
8237c478bd9Sstevel@tonic-gate 		rblock = 0;
8247c478bd9Sstevel@tonic-gate 		rnext = mapreg(k)->rg_first;
825f6db9f27Scf 		viprintf(" %c:", k);
8267c478bd9Sstevel@tonic-gate 		if (rnext == 0)
827f6db9f27Scf 			viprintf("\t\tNothing in register.\n");
8287c478bd9Sstevel@tonic-gate 		while (getREG() == 0) {
829f6db9f27Scf 			viprintf("\t\t%s\n", linebuf);
8307c478bd9Sstevel@tonic-gate 		}
8317c478bd9Sstevel@tonic-gate 	}
8327c478bd9Sstevel@tonic-gate 	return (0);
8337c478bd9Sstevel@tonic-gate }
8347c478bd9Sstevel@tonic-gate #endif
835