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
5*23a1cceaSRoger A. Faulkner * Common Development and Distribution License (the "License").
6*23a1cceaSRoger 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 */
21*23a1cceaSRoger A. Faulkner
22a1d23db4Sceastha /*
23*23a1cceaSRoger 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"
36f6db9f27Scf46844 #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
54f6db9f27Scf46844 void
fileinit(void)55f6db9f27Scf46844 fileinit(void)
567c478bd9Sstevel@tonic-gate {
57f6db9f27Scf46844 unsigned char *p;
58f6db9f27Scf46844 pid_t j;
59f6db9f27Scf46844 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 {
99f6db9f27Scf46844 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
107f6db9f27Scf46844 void
cleanup(bool all)108f6db9f27Scf46844 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);
116f6db9f27Scf46844 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)
145f6db9f27Scf46844 unlink((char *)tfname);
1467c478bd9Sstevel@tonic-gate havetmp = 0;
1477c478bd9Sstevel@tonic-gate if (all && rfile >= 0) {
148f6db9f27Scf46844 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
156f6db9f27Scf46844 void
getaline(line tl)157*23a1cceaSRoger A. Faulkner getaline(line tl)
1587c478bd9Sstevel@tonic-gate {
159f6db9f27Scf46844 unsigned char *bp, *lp;
160f6db9f27Scf46844 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++)) {
195f6db9f27Scf46844 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(atl,iof)2127c478bd9Sstevel@tonic-gate getblock(atl, iof)
2137c478bd9Sstevel@tonic-gate line atl;
2147c478bd9Sstevel@tonic-gate int iof;
2157c478bd9Sstevel@tonic-gate {
216f6db9f27Scf46844 int bno, off;
217f6db9f27Scf46844 unsigned char *p1, *p2;
218f6db9f27Scf46844 int n;
2197c478bd9Sstevel@tonic-gate line *tmpptr;
2207c478bd9Sstevel@tonic-gate
2217c478bd9Sstevel@tonic-gate bno = (atl >> OFFBTS) & BLKMSK;
2227c478bd9Sstevel@tonic-gate off = (atl << SHFT) & LBTMSK;
2237c478bd9Sstevel@tonic-gate if (bno >= NMBLKS) {
2247c478bd9Sstevel@tonic-gate /*
2257c478bd9Sstevel@tonic-gate * When we overflow tmpfile buffers,
2267c478bd9Sstevel@tonic-gate * throw away line which could not be
2277c478bd9Sstevel@tonic-gate * put into buffer.
2287c478bd9Sstevel@tonic-gate */
2297c478bd9Sstevel@tonic-gate for (tmpptr = dot; tmpptr < unddol; tmpptr++)
2307c478bd9Sstevel@tonic-gate *tmpptr = *(tmpptr+1);
2317c478bd9Sstevel@tonic-gate if (dot == dol)
2327c478bd9Sstevel@tonic-gate dot--;
2337c478bd9Sstevel@tonic-gate dol--;
2347c478bd9Sstevel@tonic-gate unddol--;
2357c478bd9Sstevel@tonic-gate error(gettext(" Tmp file too large"));
2367c478bd9Sstevel@tonic-gate }
2377c478bd9Sstevel@tonic-gate nleft = BUFSIZE - off;
2387c478bd9Sstevel@tonic-gate if (bno == iblock) {
2397c478bd9Sstevel@tonic-gate ichanged |= iof;
2407c478bd9Sstevel@tonic-gate hitin2 = 0;
2417c478bd9Sstevel@tonic-gate return (ibuff + off);
2427c478bd9Sstevel@tonic-gate }
2437c478bd9Sstevel@tonic-gate if (bno == iblock2) {
2447c478bd9Sstevel@tonic-gate ichang2 |= iof;
2457c478bd9Sstevel@tonic-gate hitin2 = 1;
2467c478bd9Sstevel@tonic-gate return (ibuff2 + off);
2477c478bd9Sstevel@tonic-gate }
2487c478bd9Sstevel@tonic-gate if (bno == oblock)
2497c478bd9Sstevel@tonic-gate return (obuff + off);
2507c478bd9Sstevel@tonic-gate if (iof == READ) {
2517c478bd9Sstevel@tonic-gate if (hitin2 == 0) {
2527c478bd9Sstevel@tonic-gate if (ichang2) {
2537c478bd9Sstevel@tonic-gate if (xtflag)
2547c478bd9Sstevel@tonic-gate if (run_crypt(0L, ibuff2,
2557c478bd9Sstevel@tonic-gate CRSIZE, tperm) == -1)
2567c478bd9Sstevel@tonic-gate filioerr(tfname);
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
311f6db9f27Scf46844 void
blkio(short b,unsigned char * buf,int (* iofcn)())312f6db9f27Scf46844 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
336f6db9f27Scf46844 void
tlaste(void)337f6db9f27Scf46844 tlaste(void)
3387c478bd9Sstevel@tonic-gate {
3397c478bd9Sstevel@tonic-gate
3407c478bd9Sstevel@tonic-gate if (stilinc)
3417c478bd9Sstevel@tonic-gate dirtcnt = 0;
3427c478bd9Sstevel@tonic-gate }
3437c478bd9Sstevel@tonic-gate
344f6db9f27Scf46844 void
tflush(void)345f6db9f27Scf46844 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 */
360f6db9f27Scf46844 void
synctmp(void)361f6db9f27Scf46844 synctmp(void)
3627c478bd9Sstevel@tonic-gate {
363f6db9f27Scf46844 int cnt;
364f6db9f27Scf46844 line *a;
365f6db9f27Scf46844 short *bp;
366f6db9f27Scf46844 unsigned char *p1, *p2;
367f6db9f27Scf46844 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++;
3987c478bd9Sstevel@tonic-gate if (run_crypt(0L, crbuf, CRSIZE, tperm) == -1)
3997c478bd9Sstevel@tonic-gate 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;
4117c478bd9Sstevel@tonic-gate a += BUFSIZE / sizeof (*a), bp++) {
4127c478bd9Sstevel@tonic-gate if (bp >= &H.Blocks[LBLKS-1])
4137c478bd9Sstevel@tonic-gate error(gettext(
4147c478bd9Sstevel@tonic-gate "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
441f6db9f27Scf46844 void
TSYNC(void)442f6db9f27Scf46844 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
493f6db9f27Scf46844 void
regio(short b,int (* iofcn)())494f6db9f27Scf46844 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
509f6db9f27Scf46844 int
REGblk(void)510f6db9f27Scf46844 REGblk(void)
5117c478bd9Sstevel@tonic-gate {
512f6db9f27Scf46844 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
524f6db9f27Scf46844 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*/
531f6db9f27Scf46844 return (0);
5327c478bd9Sstevel@tonic-gate }
5337c478bd9Sstevel@tonic-gate
5347c478bd9Sstevel@tonic-gate struct strreg *
mapreg(c)5357c478bd9Sstevel@tonic-gate mapreg(c)
536f6db9f27Scf46844 int c;
5377c478bd9Sstevel@tonic-gate {
5387c478bd9Sstevel@tonic-gate
5397c478bd9Sstevel@tonic-gate if (isupper(c))
5407c478bd9Sstevel@tonic-gate c = tolower(c);
5417c478bd9Sstevel@tonic-gate return (isdigit(c) ? &strregs[('z'-'a'+1)+(c-'0')] : &strregs[c-'a']);
5427c478bd9Sstevel@tonic-gate }
5437c478bd9Sstevel@tonic-gate
5447c478bd9Sstevel@tonic-gate int shread();
5457c478bd9Sstevel@tonic-gate
546f6db9f27Scf46844 void
KILLreg(int c)547f6db9f27Scf46844 KILLreg(int c)
5487c478bd9Sstevel@tonic-gate {
549f6db9f27Scf46844 struct strreg *sp;
5507c478bd9Sstevel@tonic-gate
5517c478bd9Sstevel@tonic-gate rbuf = &KILLrbuf;
5527c478bd9Sstevel@tonic-gate sp = mapreg(c);
5537c478bd9Sstevel@tonic-gate rblock = sp->rg_first;
5547c478bd9Sstevel@tonic-gate sp->rg_first = sp->rg_last = 0;
5557c478bd9Sstevel@tonic-gate sp->rg_flags = sp->rg_nleft = 0;
5567c478bd9Sstevel@tonic-gate while (rblock != 0) {
5577c478bd9Sstevel@tonic-gate #ifdef RDEBUG
558f6db9f27Scf46844 viprintf("freeing block %d\n", rblock);
5597c478bd9Sstevel@tonic-gate #endif
5607c478bd9Sstevel@tonic-gate rused[rblock / 16] &= ~(1 << (rblock % 16));
5617c478bd9Sstevel@tonic-gate regio(rblock, shread);
5627c478bd9Sstevel@tonic-gate rblock = rbuf->rb_next;
5637c478bd9Sstevel@tonic-gate }
5647c478bd9Sstevel@tonic-gate }
5657c478bd9Sstevel@tonic-gate
5667c478bd9Sstevel@tonic-gate /*VARARGS*/
567f6db9f27Scf46844 int
shread(void)568f6db9f27Scf46844 shread(void)
5697c478bd9Sstevel@tonic-gate {
5707c478bd9Sstevel@tonic-gate struct front { short a; short b; };
5717c478bd9Sstevel@tonic-gate
5727c478bd9Sstevel@tonic-gate if (read(rfile, (char *)rbuf, sizeof (struct front)) ==
5737c478bd9Sstevel@tonic-gate sizeof (struct front))
5747c478bd9Sstevel@tonic-gate return (sizeof (struct rbuf));
5757c478bd9Sstevel@tonic-gate return (0);
5767c478bd9Sstevel@tonic-gate }
5777c478bd9Sstevel@tonic-gate
5787c478bd9Sstevel@tonic-gate int getREG();
5797c478bd9Sstevel@tonic-gate
580f6db9f27Scf46844 int
putreg(unsigned char c)581f6db9f27Scf46844 putreg(unsigned char c)
5827c478bd9Sstevel@tonic-gate {
583f6db9f27Scf46844 line *odot = dot;
584f6db9f27Scf46844 line *odol = dol;
585f6db9f27Scf46844 int cnt;
5867c478bd9Sstevel@tonic-gate
5877c478bd9Sstevel@tonic-gate deletenone();
5887c478bd9Sstevel@tonic-gate appendnone();
5897c478bd9Sstevel@tonic-gate rbuf = &putrbuf;
5907c478bd9Sstevel@tonic-gate rnleft = 0;
5917c478bd9Sstevel@tonic-gate rblock = 0;
5927c478bd9Sstevel@tonic-gate rnext = mapreg(c)->rg_first;
5937c478bd9Sstevel@tonic-gate if (rnext == 0) {
5947c478bd9Sstevel@tonic-gate if (inopen) {
5957c478bd9Sstevel@tonic-gate splitw++;
5967c478bd9Sstevel@tonic-gate vclean();
5977c478bd9Sstevel@tonic-gate vgoto(WECHO, 0);
5987c478bd9Sstevel@tonic-gate }
5997c478bd9Sstevel@tonic-gate vreg = -1;
6007c478bd9Sstevel@tonic-gate error(gettext("Nothing in register %c"), c);
6017c478bd9Sstevel@tonic-gate }
6027c478bd9Sstevel@tonic-gate if (inopen && partreg(c)) {
6037c478bd9Sstevel@tonic-gate if (!FIXUNDO) {
6047c478bd9Sstevel@tonic-gate splitw++; vclean(); vgoto(WECHO, 0); vreg = -1;
6057c478bd9Sstevel@tonic-gate error(gettext("Can't put partial line inside macro"));
6067c478bd9Sstevel@tonic-gate }
6077c478bd9Sstevel@tonic-gate squish();
6087c478bd9Sstevel@tonic-gate addr1 = addr2 = dol;
6097c478bd9Sstevel@tonic-gate }
6107c478bd9Sstevel@tonic-gate cnt = append(getREG, addr2);
6117c478bd9Sstevel@tonic-gate if (inopen && partreg(c)) {
6127c478bd9Sstevel@tonic-gate unddol = dol;
6137c478bd9Sstevel@tonic-gate dol = odol;
6147c478bd9Sstevel@tonic-gate dot = odot;
6157c478bd9Sstevel@tonic-gate pragged(0);
6167c478bd9Sstevel@tonic-gate }
6177c478bd9Sstevel@tonic-gate killcnt(cnt);
6187c478bd9Sstevel@tonic-gate notecnt = cnt;
619f6db9f27Scf46844 return (0);
6207c478bd9Sstevel@tonic-gate }
6217c478bd9Sstevel@tonic-gate
622f6db9f27Scf46844 short
partreg(unsigned char c)623f6db9f27Scf46844 partreg(unsigned char c)
6247c478bd9Sstevel@tonic-gate {
6257c478bd9Sstevel@tonic-gate
6267c478bd9Sstevel@tonic-gate return (mapreg(c)->rg_flags);
6277c478bd9Sstevel@tonic-gate }
6287c478bd9Sstevel@tonic-gate
629f6db9f27Scf46844 void
notpart(int c)630f6db9f27Scf46844 notpart(int c)
6317c478bd9Sstevel@tonic-gate {
6327c478bd9Sstevel@tonic-gate
6337c478bd9Sstevel@tonic-gate if (c)
6347c478bd9Sstevel@tonic-gate mapreg(c)->rg_flags = 0;
6357c478bd9Sstevel@tonic-gate }
6367c478bd9Sstevel@tonic-gate
637f6db9f27Scf46844 int
getREG(void)638f6db9f27Scf46844 getREG(void)
6397c478bd9Sstevel@tonic-gate {
640f6db9f27Scf46844 unsigned char *lp = linebuf;
641f6db9f27Scf46844 int c;
6427c478bd9Sstevel@tonic-gate
6437c478bd9Sstevel@tonic-gate for (;;) {
6447c478bd9Sstevel@tonic-gate if (rnleft == 0) {
6457c478bd9Sstevel@tonic-gate if (rnext == 0)
6467c478bd9Sstevel@tonic-gate return (EOF);
6477c478bd9Sstevel@tonic-gate regio(rnext, read);
6487c478bd9Sstevel@tonic-gate rnext = rbuf->rb_next;
6497c478bd9Sstevel@tonic-gate rbufcp = rbuf->rb_text;
6507c478bd9Sstevel@tonic-gate rnleft = sizeof (rbuf->rb_text);
6517c478bd9Sstevel@tonic-gate }
6527c478bd9Sstevel@tonic-gate c = *rbufcp;
6537c478bd9Sstevel@tonic-gate if (c == 0)
6547c478bd9Sstevel@tonic-gate return (EOF);
6557c478bd9Sstevel@tonic-gate rbufcp++, --rnleft;
6567c478bd9Sstevel@tonic-gate if (c == '\n') {
6577c478bd9Sstevel@tonic-gate *lp++ = 0;
6587c478bd9Sstevel@tonic-gate return (0);
6597c478bd9Sstevel@tonic-gate }
6607c478bd9Sstevel@tonic-gate *lp++ = c;
6617c478bd9Sstevel@tonic-gate }
6627c478bd9Sstevel@tonic-gate }
6637c478bd9Sstevel@tonic-gate
664f6db9f27Scf46844 int
YANKreg(int c)665f6db9f27Scf46844 YANKreg(int c)
6667c478bd9Sstevel@tonic-gate {
667f6db9f27Scf46844 line *addr;
668f6db9f27Scf46844 struct strreg *sp;
6697c478bd9Sstevel@tonic-gate unsigned char savelb[LBSIZE];
6707c478bd9Sstevel@tonic-gate
6717c478bd9Sstevel@tonic-gate if (isdigit(c))
6727c478bd9Sstevel@tonic-gate kshift();
6737c478bd9Sstevel@tonic-gate if (islower(c))
6747c478bd9Sstevel@tonic-gate KILLreg(c);
6757c478bd9Sstevel@tonic-gate strp = sp = mapreg(c);
6767c478bd9Sstevel@tonic-gate sp->rg_flags = inopen && cursor && wcursor;
6777c478bd9Sstevel@tonic-gate rbuf = &YANKrbuf;
6787c478bd9Sstevel@tonic-gate if (sp->rg_last) {
6797c478bd9Sstevel@tonic-gate regio(sp->rg_last, read);
6807c478bd9Sstevel@tonic-gate rnleft = sp->rg_nleft;
6817c478bd9Sstevel@tonic-gate rbufcp = &rbuf->rb_text[sizeof (rbuf->rb_text) - rnleft];
6827c478bd9Sstevel@tonic-gate } else {
6837c478bd9Sstevel@tonic-gate rblock = 0;
6847c478bd9Sstevel@tonic-gate rnleft = 0;
6857c478bd9Sstevel@tonic-gate }
6867c478bd9Sstevel@tonic-gate CP(savelb, linebuf);
6877c478bd9Sstevel@tonic-gate for (addr = addr1; addr <= addr2; addr++) {
688*23a1cceaSRoger A. Faulkner getaline(*addr);
6897c478bd9Sstevel@tonic-gate if (sp->rg_flags) {
6907c478bd9Sstevel@tonic-gate if (addr == addr2)
6917c478bd9Sstevel@tonic-gate *wcursor = 0;
6927c478bd9Sstevel@tonic-gate if (addr == addr1)
6937c478bd9Sstevel@tonic-gate strcpy(linebuf, cursor);
6947c478bd9Sstevel@tonic-gate }
6957c478bd9Sstevel@tonic-gate YANKline();
6967c478bd9Sstevel@tonic-gate }
6977c478bd9Sstevel@tonic-gate rbflush();
6987c478bd9Sstevel@tonic-gate killed();
6997c478bd9Sstevel@tonic-gate CP(linebuf, savelb);
700f6db9f27Scf46844 return (0);
7017c478bd9Sstevel@tonic-gate }
7027c478bd9Sstevel@tonic-gate
703f6db9f27Scf46844 void
kshift(void)704f6db9f27Scf46844 kshift(void)
7057c478bd9Sstevel@tonic-gate {
706f6db9f27Scf46844 int i;
7077c478bd9Sstevel@tonic-gate
7087c478bd9Sstevel@tonic-gate KILLreg('9');
7097c478bd9Sstevel@tonic-gate for (i = '8'; i >= '0'; i--)
7107c478bd9Sstevel@tonic-gate copy(mapreg(i+1), mapreg(i), sizeof (struct strreg));
7117c478bd9Sstevel@tonic-gate }
7127c478bd9Sstevel@tonic-gate
713f6db9f27Scf46844 void
YANKline(void)714f6db9f27Scf46844 YANKline(void)
7157c478bd9Sstevel@tonic-gate {
716f6db9f27Scf46844 unsigned char *lp = linebuf;
717f6db9f27Scf46844 struct rbuf *rp = rbuf;
718f6db9f27Scf46844 int c;
7197c478bd9Sstevel@tonic-gate
7207c478bd9Sstevel@tonic-gate do {
7217c478bd9Sstevel@tonic-gate c = *lp++;
7227c478bd9Sstevel@tonic-gate if (c == 0)
7237c478bd9Sstevel@tonic-gate c = '\n';
7247c478bd9Sstevel@tonic-gate if (rnleft == 0) {
7257c478bd9Sstevel@tonic-gate rp->rb_next = REGblk();
7267c478bd9Sstevel@tonic-gate rbflush();
7277c478bd9Sstevel@tonic-gate rblock = rp->rb_next;
7287c478bd9Sstevel@tonic-gate rp->rb_next = 0;
7297c478bd9Sstevel@tonic-gate rp->rb_prev = rblock;
7307c478bd9Sstevel@tonic-gate rnleft = sizeof (rp->rb_text);
7317c478bd9Sstevel@tonic-gate rbufcp = rp->rb_text;
7327c478bd9Sstevel@tonic-gate }
7337c478bd9Sstevel@tonic-gate *rbufcp++ = c;
7347c478bd9Sstevel@tonic-gate --rnleft;
7357c478bd9Sstevel@tonic-gate } while (c != '\n');
7367c478bd9Sstevel@tonic-gate if (rnleft)
7377c478bd9Sstevel@tonic-gate *rbufcp = 0;
7387c478bd9Sstevel@tonic-gate }
7397c478bd9Sstevel@tonic-gate
740f6db9f27Scf46844 void
rbflush(void)741f6db9f27Scf46844 rbflush(void)
7427c478bd9Sstevel@tonic-gate {
743f6db9f27Scf46844 struct strreg *sp = strp;
7447c478bd9Sstevel@tonic-gate
7457c478bd9Sstevel@tonic-gate if (rblock == 0)
7467c478bd9Sstevel@tonic-gate return;
7477c478bd9Sstevel@tonic-gate regio(rblock, write);
7487c478bd9Sstevel@tonic-gate if (sp->rg_first == 0)
7497c478bd9Sstevel@tonic-gate sp->rg_first = rblock;
7507c478bd9Sstevel@tonic-gate sp->rg_last = rblock;
7517c478bd9Sstevel@tonic-gate sp->rg_nleft = rnleft;
7527c478bd9Sstevel@tonic-gate }
7537c478bd9Sstevel@tonic-gate
7547c478bd9Sstevel@tonic-gate /* Register c to char buffer buf of size buflen */
755f6db9f27Scf46844 void
regbuf(c,buf,buflen)7567c478bd9Sstevel@tonic-gate regbuf(c, buf, buflen)
7577c478bd9Sstevel@tonic-gate unsigned char c;
7587c478bd9Sstevel@tonic-gate unsigned char *buf;
7597c478bd9Sstevel@tonic-gate int buflen;
7607c478bd9Sstevel@tonic-gate {
761f6db9f27Scf46844 unsigned char *p, *lp;
7627c478bd9Sstevel@tonic-gate
7637c478bd9Sstevel@tonic-gate rbuf = ®rbuf;
7647c478bd9Sstevel@tonic-gate rnleft = 0;
7657c478bd9Sstevel@tonic-gate rblock = 0;
7667c478bd9Sstevel@tonic-gate rnext = mapreg(c)->rg_first;
7677c478bd9Sstevel@tonic-gate if (rnext == 0) {
7687c478bd9Sstevel@tonic-gate *buf = 0;
7697c478bd9Sstevel@tonic-gate error(gettext("Nothing in register %c"), c);
7707c478bd9Sstevel@tonic-gate }
7717c478bd9Sstevel@tonic-gate p = buf;
7727c478bd9Sstevel@tonic-gate while (getREG() == 0) {
7737c478bd9Sstevel@tonic-gate lp = linebuf;
7747c478bd9Sstevel@tonic-gate while (*lp) {
7757c478bd9Sstevel@tonic-gate if (p >= &buf[buflen])
7767c478bd9Sstevel@tonic-gate error(value(vi_TERSE) ?
7777c478bd9Sstevel@tonic-gate gettext("Register too long") : gettext("Register too long to fit in memory"));
7787c478bd9Sstevel@tonic-gate *p++ = *lp++;
7797c478bd9Sstevel@tonic-gate }
7807c478bd9Sstevel@tonic-gate *p++ = '\n';
7817c478bd9Sstevel@tonic-gate }
7827c478bd9Sstevel@tonic-gate if (partreg(c)) p--;
7837c478bd9Sstevel@tonic-gate *p = '\0';
7847c478bd9Sstevel@tonic-gate getDOT();
7857c478bd9Sstevel@tonic-gate }
7867c478bd9Sstevel@tonic-gate
7877c478bd9Sstevel@tonic-gate #ifdef TRACE
7887c478bd9Sstevel@tonic-gate
7897c478bd9Sstevel@tonic-gate /*
7907c478bd9Sstevel@tonic-gate * Test code for displaying named registers.
7917c478bd9Sstevel@tonic-gate */
7927c478bd9Sstevel@tonic-gate
shownam()7937c478bd9Sstevel@tonic-gate shownam()
7947c478bd9Sstevel@tonic-gate {
7957c478bd9Sstevel@tonic-gate int k;
7967c478bd9Sstevel@tonic-gate
797f6db9f27Scf46844 viprintf("\nRegister Contents\n");
798f6db9f27Scf46844 viprintf("======== ========\n");
7997c478bd9Sstevel@tonic-gate for (k = 'a'; k <= 'z'; k++) {
8007c478bd9Sstevel@tonic-gate rbuf = &putrbuf;
8017c478bd9Sstevel@tonic-gate rnleft = 0;
8027c478bd9Sstevel@tonic-gate rblock = 0;
8037c478bd9Sstevel@tonic-gate rnext = mapreg(k)->rg_first;
804f6db9f27Scf46844 viprintf(" %c:", k);
8057c478bd9Sstevel@tonic-gate if (rnext == 0)
806f6db9f27Scf46844 viprintf("\t\tNothing in register.\n");
8077c478bd9Sstevel@tonic-gate while (getREG() == 0) {
808f6db9f27Scf46844 viprintf("\t\t%s\n", linebuf);
8097c478bd9Sstevel@tonic-gate }
8107c478bd9Sstevel@tonic-gate }
8117c478bd9Sstevel@tonic-gate return (0);
8127c478bd9Sstevel@tonic-gate }
8137c478bd9Sstevel@tonic-gate
8147c478bd9Sstevel@tonic-gate /*
8157c478bd9Sstevel@tonic-gate * Test code for displaying numbered registers.
8167c478bd9Sstevel@tonic-gate */
8177c478bd9Sstevel@tonic-gate
shownbr()8187c478bd9Sstevel@tonic-gate shownbr()
8197c478bd9Sstevel@tonic-gate {
8207c478bd9Sstevel@tonic-gate int k;
8217c478bd9Sstevel@tonic-gate
822f6db9f27Scf46844 viprintf("\nRegister Contents\n");
823f6db9f27Scf46844 viprintf("======== ========\n");
8247c478bd9Sstevel@tonic-gate for (k = '1'; k <= '9'; k++) {
8257c478bd9Sstevel@tonic-gate rbuf = &putrbuf;
8267c478bd9Sstevel@tonic-gate rnleft = 0;
8277c478bd9Sstevel@tonic-gate rblock = 0;
8287c478bd9Sstevel@tonic-gate rnext = mapreg(k)->rg_first;
829f6db9f27Scf46844 viprintf(" %c:", k);
8307c478bd9Sstevel@tonic-gate if (rnext == 0)
831f6db9f27Scf46844 viprintf("\t\tNothing in register.\n");
8327c478bd9Sstevel@tonic-gate while (getREG() == 0) {
833f6db9f27Scf46844 viprintf("\t\t%s\n", linebuf);
8347c478bd9Sstevel@tonic-gate }
8357c478bd9Sstevel@tonic-gate }
8367c478bd9Sstevel@tonic-gate return (0);
8377c478bd9Sstevel@tonic-gate }
8387c478bd9Sstevel@tonic-gate #endif
839