10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*13093SRoger.Faulkner@Oracle.COM * Common Development and Distribution License (the "License").
6*13093SRoger.Faulkner@Oracle.COM * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate
220Sstevel@tonic-gate /*
23*13093SRoger.Faulkner@Oracle.COM * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
240Sstevel@tonic-gate */
250Sstevel@tonic-gate
26*13093SRoger.Faulkner@Oracle.COM /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
27*13093SRoger.Faulkner@Oracle.COM /* All Rights Reserved */
280Sstevel@tonic-gate
290Sstevel@tonic-gate /*
300Sstevel@tonic-gate * Editor
310Sstevel@tonic-gate */
320Sstevel@tonic-gate
330Sstevel@tonic-gate #include <crypt.h>
340Sstevel@tonic-gate #include <libgen.h>
350Sstevel@tonic-gate #include <wait.h>
360Sstevel@tonic-gate #include <string.h>
370Sstevel@tonic-gate #include <sys/types.h>
380Sstevel@tonic-gate #include <locale.h>
390Sstevel@tonic-gate #include <regexpr.h>
400Sstevel@tonic-gate #include <regex.h>
410Sstevel@tonic-gate #include <errno.h>
420Sstevel@tonic-gate
430Sstevel@tonic-gate static const char *msgtab[] =
440Sstevel@tonic-gate {
450Sstevel@tonic-gate "write or open on pipe failed", /* 0 */
460Sstevel@tonic-gate "warning: expecting `w'", /* 1 */
470Sstevel@tonic-gate "mark not lower case ascii", /* 2 */
480Sstevel@tonic-gate "Cannot open input file", /* 3 */
490Sstevel@tonic-gate "PWB spec problem", /* 4 */
500Sstevel@tonic-gate "nothing to undo", /* 5 */
510Sstevel@tonic-gate "restricted shell", /* 6 */
520Sstevel@tonic-gate "cannot create output file", /* 7 */
530Sstevel@tonic-gate "filesystem out of space!", /* 8 */
540Sstevel@tonic-gate "cannot open file", /* 9 */
550Sstevel@tonic-gate "cannot link", /* 10 */
560Sstevel@tonic-gate "Range endpoint too large", /* 11 */
570Sstevel@tonic-gate "unknown command", /* 12 */
580Sstevel@tonic-gate "search string not found", /* 13 */
590Sstevel@tonic-gate "-", /* 14 */
600Sstevel@tonic-gate "line out of range", /* 15 */
610Sstevel@tonic-gate "bad number", /* 16 */
620Sstevel@tonic-gate "bad range", /* 17 */
630Sstevel@tonic-gate "Illegal address count", /* 18 */
640Sstevel@tonic-gate "incomplete global expression", /* 19 */
650Sstevel@tonic-gate "illegal suffix", /* 20 */
660Sstevel@tonic-gate "illegal or missing filename", /* 21 */
670Sstevel@tonic-gate "no space after command", /* 22 */
680Sstevel@tonic-gate "fork failed - try again", /* 23 */
690Sstevel@tonic-gate "maximum of 64 characters in file names", /* 24 */
700Sstevel@tonic-gate "`\\digit' out of range", /* 25 */
710Sstevel@tonic-gate "interrupt", /* 26 */
720Sstevel@tonic-gate "line too long", /* 27 */
730Sstevel@tonic-gate "illegal character in input file", /* 28 */
740Sstevel@tonic-gate "write error", /* 29 */
750Sstevel@tonic-gate "out of memory for append", /* 30 */
760Sstevel@tonic-gate "temp file too big", /* 31 */
770Sstevel@tonic-gate "I/O error on temp file", /* 32 */
780Sstevel@tonic-gate "multiple globals not allowed", /* 33 */
790Sstevel@tonic-gate "global too long", /* 34 */
800Sstevel@tonic-gate "no match", /* 35 */
810Sstevel@tonic-gate "illegal or missing delimiter", /* 36 */
820Sstevel@tonic-gate "-", /* 37 */
830Sstevel@tonic-gate "replacement string too long", /* 38 */
840Sstevel@tonic-gate "illegal move destination", /* 39 */
850Sstevel@tonic-gate "-", /* 40 */
860Sstevel@tonic-gate "no remembered search string", /* 41 */
870Sstevel@tonic-gate "'\\( \\)' imbalance", /* 42 */
880Sstevel@tonic-gate "Too many `\\(' s", /* 43 */
890Sstevel@tonic-gate "more than 2 numbers given", /* 44 */
900Sstevel@tonic-gate "'\\}' expected", /* 45 */
910Sstevel@tonic-gate "first number exceeds second", /* 46 */
920Sstevel@tonic-gate "incomplete substitute", /* 47 */
930Sstevel@tonic-gate "newline unexpected", /* 48 */
940Sstevel@tonic-gate "'[ ]' imbalance", /* 49 */
950Sstevel@tonic-gate "regular expression overflow", /* 50 */
960Sstevel@tonic-gate "regular expression error", /* 51 */
970Sstevel@tonic-gate "command expected", /* 52 */
980Sstevel@tonic-gate "a, i, or c not allowed in G", /* 53 */
990Sstevel@tonic-gate "end of line expected", /* 54 */
1000Sstevel@tonic-gate "no remembered replacement string", /* 55 */
1010Sstevel@tonic-gate "no remembered command", /* 56 */
1020Sstevel@tonic-gate "illegal redirection", /* 57 */
1030Sstevel@tonic-gate "possible concurrent update", /* 58 */
1040Sstevel@tonic-gate "-", /* 59 */
1050Sstevel@tonic-gate "the x command has become X (upper case)", /* 60 */
1060Sstevel@tonic-gate "Warning: 'w' may destroy input file "
1070Sstevel@tonic-gate "(due to `illegal char' read earlier)",
1080Sstevel@tonic-gate /* 61 */
1090Sstevel@tonic-gate "Caution: 'q' may lose data in buffer;"
1100Sstevel@tonic-gate " 'w' may destroy input file",
1110Sstevel@tonic-gate /* 62 */
1120Sstevel@tonic-gate "Encryption of string failed", /* 63 */
1130Sstevel@tonic-gate "Encryption facility not available", /* 64 */
1140Sstevel@tonic-gate "Cannot encrypt temporary file", /* 65 */
1150Sstevel@tonic-gate "Enter key:", /* 66 */
1160Sstevel@tonic-gate "Illegal byte sequence", /* 67 */
1170Sstevel@tonic-gate "File does not exist", /* 68 */
1180Sstevel@tonic-gate "tempnam failed", /* 69 */
1190Sstevel@tonic-gate "Cannot open temporary file", /* 70 */
1200Sstevel@tonic-gate 0
1210Sstevel@tonic-gate };
1220Sstevel@tonic-gate
1230Sstevel@tonic-gate #include <stdlib.h>
1240Sstevel@tonic-gate #include <limits.h>
1250Sstevel@tonic-gate #include <stdio.h>
1260Sstevel@tonic-gate #include <signal.h>
1270Sstevel@tonic-gate #include <sys/types.h>
1280Sstevel@tonic-gate #include <sys/stat.h>
1290Sstevel@tonic-gate #include <sys/statvfs.h>
1300Sstevel@tonic-gate #include <unistd.h>
1310Sstevel@tonic-gate #include <termio.h>
1320Sstevel@tonic-gate #include <ctype.h>
1330Sstevel@tonic-gate #include <setjmp.h>
1340Sstevel@tonic-gate #include <fcntl.h>
1350Sstevel@tonic-gate #include <wchar.h> /* I18N */
1360Sstevel@tonic-gate #include <wctype.h> /* I18N */
1370Sstevel@tonic-gate #include <widec.h> /* I18N */
1380Sstevel@tonic-gate
1390Sstevel@tonic-gate #define FTYPE(A) (A.st_mode)
1400Sstevel@tonic-gate #define FMODE(A) (A.st_mode)
1410Sstevel@tonic-gate #define IDENTICAL(A, B) (A.st_dev == B.st_dev && A.st_ino == B.st_ino)
1420Sstevel@tonic-gate #define ISBLK(A) ((A.st_mode & S_IFMT) == S_IFBLK)
1430Sstevel@tonic-gate #define ISCHR(A) ((A.st_mode & S_IFMT) == S_IFCHR)
1440Sstevel@tonic-gate #define ISDIR(A) ((A.st_mode & S_IFMT) == S_IFDIR)
1450Sstevel@tonic-gate #define ISFIFO(A) ((A.st_mode & S_IFMT) == S_IFIFO)
1460Sstevel@tonic-gate #define ISREG(A) ((A.st_mode & S_IFMT) == S_IFREG)
1470Sstevel@tonic-gate
1480Sstevel@tonic-gate #define PUTM() if (xcode >= 0) puts(gettext(msgtab[xcode]))
1490Sstevel@tonic-gate #define UNGETC(c) (peekc = c)
1500Sstevel@tonic-gate #define FNSIZE PATH_MAX
1510Sstevel@tonic-gate #define LBSIZE LINE_MAX
1520Sstevel@tonic-gate
1530Sstevel@tonic-gate /* size of substitution replacement pattern buffer */
1540Sstevel@tonic-gate #define RHSIZE (LINE_MAX*2)
1550Sstevel@tonic-gate
1560Sstevel@tonic-gate #define KSIZE 8
1570Sstevel@tonic-gate
1580Sstevel@tonic-gate #define READ 0
1590Sstevel@tonic-gate #define WRITE 1
1600Sstevel@tonic-gate
1610Sstevel@tonic-gate extern char *optarg; /* Value of argument */
1620Sstevel@tonic-gate extern int optind; /* Indicator of argument */
1630Sstevel@tonic-gate extern int __xpg4; /* defined in xpg4.c; 0 if not xpg4-compiled program */
1640Sstevel@tonic-gate
1650Sstevel@tonic-gate struct Fspec {
1660Sstevel@tonic-gate char Ftabs[22];
1670Sstevel@tonic-gate char Fdel;
1680Sstevel@tonic-gate unsigned char Flim;
1690Sstevel@tonic-gate char Fmov;
1700Sstevel@tonic-gate char Ffill;
1710Sstevel@tonic-gate };
1720Sstevel@tonic-gate static struct Fspec fss;
1730Sstevel@tonic-gate
1740Sstevel@tonic-gate static char *fsp;
1750Sstevel@tonic-gate static int fsprtn;
1760Sstevel@tonic-gate static char line[70];
1770Sstevel@tonic-gate static char *linp = line;
1780Sstevel@tonic-gate static int sig;
1790Sstevel@tonic-gate static int Xqt = 0;
1800Sstevel@tonic-gate static int lastc;
1810Sstevel@tonic-gate static char savedfile[FNSIZE];
1820Sstevel@tonic-gate static char file[FNSIZE];
1830Sstevel@tonic-gate static char funny[FNSIZE];
1840Sstevel@tonic-gate static int funlink = 0;
1850Sstevel@tonic-gate static char linebuf[LBSIZE];
1860Sstevel@tonic-gate static char *tstring = linebuf;
1870Sstevel@tonic-gate
1880Sstevel@tonic-gate static char *expbuf;
1890Sstevel@tonic-gate
1900Sstevel@tonic-gate static char rhsbuf[RHSIZE];
1910Sstevel@tonic-gate struct lin {
1920Sstevel@tonic-gate long cur;
1930Sstevel@tonic-gate long sav;
1940Sstevel@tonic-gate };
1950Sstevel@tonic-gate typedef struct lin *LINE;
1960Sstevel@tonic-gate static LINE zero;
1970Sstevel@tonic-gate static LINE dot;
1980Sstevel@tonic-gate static LINE dol;
1990Sstevel@tonic-gate static LINE endcore;
2000Sstevel@tonic-gate static LINE fendcore;
2010Sstevel@tonic-gate static LINE addr1;
2020Sstevel@tonic-gate static LINE addr2;
2030Sstevel@tonic-gate static LINE savdol, savdot;
2040Sstevel@tonic-gate static int globflg;
2050Sstevel@tonic-gate static int initflg;
2060Sstevel@tonic-gate static char genbuf[LBSIZE];
2070Sstevel@tonic-gate static long count;
2080Sstevel@tonic-gate static int numpass; /* Number of passes thru dosub(). */
2090Sstevel@tonic-gate static int gsubf; /* Occurrence value. LBSIZE-1=all. */
2100Sstevel@tonic-gate static int ocerr1; /* Allows lines NOT changed by dosub() to NOT be put */
2110Sstevel@tonic-gate /* out. Retains last line changed as current line. */
2120Sstevel@tonic-gate static int ocerr2; /* Flags if ANY line changed by substitute(). 0=nc. */
2130Sstevel@tonic-gate static char *nextip;
2140Sstevel@tonic-gate static char *linebp;
2150Sstevel@tonic-gate static int ninbuf;
2160Sstevel@tonic-gate static int peekc;
2170Sstevel@tonic-gate static int io;
2180Sstevel@tonic-gate static void (*oldhup)(), (*oldintr)();
2190Sstevel@tonic-gate static void (*oldquit)(), (*oldpipe)();
2200Sstevel@tonic-gate static void quit(int);
2210Sstevel@tonic-gate static int vflag = 1;
2220Sstevel@tonic-gate static int xflag;
2230Sstevel@tonic-gate static int xtflag;
2240Sstevel@tonic-gate static int kflag;
2250Sstevel@tonic-gate static int crflag;
2260Sstevel@tonic-gate /* Flag for determining if file being read is encrypted */
2270Sstevel@tonic-gate static int hflag;
2280Sstevel@tonic-gate static int xcode = -1;
2290Sstevel@tonic-gate static char crbuf[LBSIZE];
2300Sstevel@tonic-gate static int perm[2];
2310Sstevel@tonic-gate static int tperm[2];
2320Sstevel@tonic-gate static int permflag;
2330Sstevel@tonic-gate static int tpermflag;
2340Sstevel@tonic-gate static int col;
2350Sstevel@tonic-gate static char *globp;
2360Sstevel@tonic-gate static int tfile = -1;
2370Sstevel@tonic-gate static int tline;
2380Sstevel@tonic-gate static char *tfname;
2390Sstevel@tonic-gate extern char *locs;
2400Sstevel@tonic-gate static char ibuff[LBSIZE];
2410Sstevel@tonic-gate static int iblock = -1;
2420Sstevel@tonic-gate static char obuff[LBSIZE];
2430Sstevel@tonic-gate static int oblock = -1;
2440Sstevel@tonic-gate static int ichanged;
2450Sstevel@tonic-gate static int nleft;
2460Sstevel@tonic-gate static long savnames[26], names[26];
2470Sstevel@tonic-gate static int anymarks;
2480Sstevel@tonic-gate static long subnewa;
2490Sstevel@tonic-gate static int fchange;
2500Sstevel@tonic-gate static int nline;
2510Sstevel@tonic-gate static int fflg, shflg;
2520Sstevel@tonic-gate static char prompt[16] = "*";
2530Sstevel@tonic-gate static int rflg;
2540Sstevel@tonic-gate static int readflg;
2550Sstevel@tonic-gate static int eflg;
2560Sstevel@tonic-gate static int qflg = 0;
2570Sstevel@tonic-gate static int ncflg;
2580Sstevel@tonic-gate static int listn;
2590Sstevel@tonic-gate static int listf;
2600Sstevel@tonic-gate static int pflag;
2610Sstevel@tonic-gate static int flag28 = 0; /* Prevents write after a partial read */
2620Sstevel@tonic-gate static int save28 = 0; /* Flag whether buffer empty at start of read */
2630Sstevel@tonic-gate static long savtime;
2640Sstevel@tonic-gate static char *name = "SHELL";
2650Sstevel@tonic-gate static char *rshell = "/usr/lib/rsh";
2660Sstevel@tonic-gate static char *shpath; /* pointer to correct shell for execution */
2670Sstevel@tonic-gate /* of execlp() */
2680Sstevel@tonic-gate static char *val;
2690Sstevel@tonic-gate static char *home;
2700Sstevel@tonic-gate static int nodelim;
2710Sstevel@tonic-gate
2720Sstevel@tonic-gate int makekey(int *);
2730Sstevel@tonic-gate int _mbftowc(char *, wchar_t *, int (*)(), int *);
2740Sstevel@tonic-gate static int error(int code);
2750Sstevel@tonic-gate static void tlist(struct Fspec *);
2760Sstevel@tonic-gate static void tstd(struct Fspec *);
2770Sstevel@tonic-gate static void gdelete(void);
2780Sstevel@tonic-gate static void delete(void);
2790Sstevel@tonic-gate static void exfile(void);
2800Sstevel@tonic-gate static void filename(int comm);
2810Sstevel@tonic-gate static void newline(void);
2820Sstevel@tonic-gate static int gettty(void);
2830Sstevel@tonic-gate static void commands(void);
2840Sstevel@tonic-gate static void undo(void);
2850Sstevel@tonic-gate static void save(void);
2860Sstevel@tonic-gate static void strcopy(char *source, char *dest);
2870Sstevel@tonic-gate static int strequal(char **scan1, char *str);
2880Sstevel@tonic-gate static int stdtab(char *, char *);
2890Sstevel@tonic-gate static int lenchk(char *, struct Fspec *);
2900Sstevel@tonic-gate static void clear(struct Fspec *);
2910Sstevel@tonic-gate static int expnd(char *, char *, int *, struct Fspec *);
2920Sstevel@tonic-gate static void tincr(int, struct Fspec *);
2930Sstevel@tonic-gate static void targ(struct Fspec *);
2940Sstevel@tonic-gate static int numb(void);
2950Sstevel@tonic-gate static int fspec(char *, struct Fspec *, int);
2960Sstevel@tonic-gate static void red(char *);
2970Sstevel@tonic-gate static void newtime(void);
2980Sstevel@tonic-gate static void chktime(void);
2990Sstevel@tonic-gate static void getime(void);
3000Sstevel@tonic-gate static void mkfunny(void);
3010Sstevel@tonic-gate static int eopen(char *, int);
3020Sstevel@tonic-gate static void eclose(int f);
3030Sstevel@tonic-gate static void globaln(int);
3040Sstevel@tonic-gate static char *getkey(const char *);
3050Sstevel@tonic-gate static int execute(int, LINE);
3060Sstevel@tonic-gate static void error1(int);
3070Sstevel@tonic-gate static int getcopy(void);
3080Sstevel@tonic-gate static void move(int);
3090Sstevel@tonic-gate static void dosub(void);
3100Sstevel@tonic-gate static int getsub(void);
3110Sstevel@tonic-gate static int compsub(void);
3120Sstevel@tonic-gate static void substitute(int);
3130Sstevel@tonic-gate static void join(void);
3140Sstevel@tonic-gate static void global(int);
3150Sstevel@tonic-gate static void init(void);
3160Sstevel@tonic-gate static void rdelete(LINE, LINE);
3170Sstevel@tonic-gate static void append(int (*)(void), LINE);
3180Sstevel@tonic-gate static int getfile(void);
3190Sstevel@tonic-gate static void putfile(void);
3200Sstevel@tonic-gate static void onpipe(int);
3210Sstevel@tonic-gate static void onhup(int);
3220Sstevel@tonic-gate static void onintr(int);
3230Sstevel@tonic-gate static void setdot(void);
3240Sstevel@tonic-gate static void setall(void);
3250Sstevel@tonic-gate static void setnoaddr(void);
3260Sstevel@tonic-gate static void nonzero(void);
3270Sstevel@tonic-gate static void setzeroasone(void);
3280Sstevel@tonic-gate static long putline(void);
3290Sstevel@tonic-gate static LINE address(void);
330*13093SRoger.Faulkner@Oracle.COM static char *getaline(long);
3310Sstevel@tonic-gate static char *getblock(long, long);
3320Sstevel@tonic-gate static char *place(char *, char *, char *);
3330Sstevel@tonic-gate static void comple(wchar_t);
3340Sstevel@tonic-gate static void putchr(unsigned char);
3350Sstevel@tonic-gate static void putwchr(wchar_t);
3360Sstevel@tonic-gate static int getchr(void);
3370Sstevel@tonic-gate static void unixcom(void);
3380Sstevel@tonic-gate static void blkio(int, char *, ssize_t (*)());
3390Sstevel@tonic-gate static void reverse(LINE, LINE);
3400Sstevel@tonic-gate static void putd();
3410Sstevel@tonic-gate static wchar_t get_wchr(void);
3420Sstevel@tonic-gate
3430Sstevel@tonic-gate static struct stat Fl, Tf;
3440Sstevel@tonic-gate #ifndef RESEARCH
3450Sstevel@tonic-gate static struct statvfs U;
3460Sstevel@tonic-gate static int Short = 0;
3470Sstevel@tonic-gate static mode_t oldmask; /* No umask while writing */
3480Sstevel@tonic-gate #endif
3490Sstevel@tonic-gate static jmp_buf savej;
3500Sstevel@tonic-gate
3510Sstevel@tonic-gate #ifdef NULLS
3520Sstevel@tonic-gate int nulls; /* Null count */
3530Sstevel@tonic-gate #endif
3540Sstevel@tonic-gate static long ccount;
3550Sstevel@tonic-gate
3560Sstevel@tonic-gate static int errcnt = 0;
3570Sstevel@tonic-gate
3580Sstevel@tonic-gate
3590Sstevel@tonic-gate static void
onpipe(int sig)3600Sstevel@tonic-gate onpipe(int sig)
3610Sstevel@tonic-gate {
3620Sstevel@tonic-gate (int)error(0);
3630Sstevel@tonic-gate }
3640Sstevel@tonic-gate
3650Sstevel@tonic-gate int
main(int argc,char ** argv)3660Sstevel@tonic-gate main(int argc, char **argv)
3670Sstevel@tonic-gate {
3680Sstevel@tonic-gate char *p1, *p2;
3690Sstevel@tonic-gate int c;
3700Sstevel@tonic-gate
3710Sstevel@tonic-gate (void) setlocale(LC_ALL, "");
3720Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
3730Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
3740Sstevel@tonic-gate #endif
3750Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN);
3760Sstevel@tonic-gate
3770Sstevel@tonic-gate oldquit = signal(SIGQUIT, SIG_IGN);
3780Sstevel@tonic-gate oldhup = signal(SIGHUP, SIG_IGN);
3790Sstevel@tonic-gate oldintr = signal(SIGINT, SIG_IGN);
3800Sstevel@tonic-gate oldpipe = signal(SIGPIPE, onpipe);
3810Sstevel@tonic-gate if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
3820Sstevel@tonic-gate signal(SIGTERM, quit);
3830Sstevel@tonic-gate p1 = *argv;
3840Sstevel@tonic-gate while (*p1++);
3850Sstevel@tonic-gate while (--p1 >= *argv)
3860Sstevel@tonic-gate if (*p1 == '/')
3870Sstevel@tonic-gate break;
3880Sstevel@tonic-gate *argv = p1 + 1;
3890Sstevel@tonic-gate /* if SHELL set in environment and is /usr/lib/rsh, set rflg */
3900Sstevel@tonic-gate if ((val = getenv(name)) != NULL)
3910Sstevel@tonic-gate if (strcmp(val, rshell) == 0)
3920Sstevel@tonic-gate rflg++;
3930Sstevel@tonic-gate if (**argv == 'r')
3940Sstevel@tonic-gate rflg++;
3950Sstevel@tonic-gate home = getenv("HOME");
3960Sstevel@tonic-gate while (1) {
3970Sstevel@tonic-gate while ((c = getopt(argc, argv, "sp:qxC")) != EOF) {
3980Sstevel@tonic-gate switch (c) {
3990Sstevel@tonic-gate
4000Sstevel@tonic-gate case 's':
4010Sstevel@tonic-gate vflag = 0;
4020Sstevel@tonic-gate break;
4030Sstevel@tonic-gate
4040Sstevel@tonic-gate case 'p':
4050Sstevel@tonic-gate strncpy(prompt, optarg, sizeof (prompt)-1);
4060Sstevel@tonic-gate shflg = 1;
4070Sstevel@tonic-gate break;
4080Sstevel@tonic-gate
4090Sstevel@tonic-gate case 'q':
4100Sstevel@tonic-gate signal(SIGQUIT, SIG_DFL);
4110Sstevel@tonic-gate vflag = 1;
4120Sstevel@tonic-gate break;
4130Sstevel@tonic-gate
4140Sstevel@tonic-gate case 'x':
4150Sstevel@tonic-gate crflag = -1;
4160Sstevel@tonic-gate xflag = 1;
4170Sstevel@tonic-gate break;
4180Sstevel@tonic-gate
4190Sstevel@tonic-gate case 'C':
4200Sstevel@tonic-gate crflag = 1;
4210Sstevel@tonic-gate xflag = 1;
4220Sstevel@tonic-gate break;
4230Sstevel@tonic-gate
4240Sstevel@tonic-gate case '?':
4250Sstevel@tonic-gate (void) fprintf(stderr, gettext(
4260Sstevel@tonic-gate "Usage: ed [- | -s] [-p string] [-x] [-C] [file]\n"
4270Sstevel@tonic-gate " red [- | -s] [-p string] [-x] [-C] [file]\n"));
4280Sstevel@tonic-gate exit(2);
4290Sstevel@tonic-gate }
4300Sstevel@tonic-gate }
4310Sstevel@tonic-gate if (argv[optind] && strcmp(argv[optind], "-") == 0 &&
4320Sstevel@tonic-gate strcmp(argv[optind-1], "--") != 0) {
4330Sstevel@tonic-gate vflag = 0;
4340Sstevel@tonic-gate optind++;
4350Sstevel@tonic-gate continue;
4360Sstevel@tonic-gate }
4370Sstevel@tonic-gate break;
4380Sstevel@tonic-gate }
4390Sstevel@tonic-gate argc = argc - optind;
4400Sstevel@tonic-gate argv = &argv[optind];
4410Sstevel@tonic-gate
4420Sstevel@tonic-gate if (xflag) {
4430Sstevel@tonic-gate if (permflag)
4440Sstevel@tonic-gate crypt_close(perm);
4450Sstevel@tonic-gate permflag = 1;
4460Sstevel@tonic-gate if ((kflag = run_setkey(&perm[0], getkey(msgtab[66])))
4470Sstevel@tonic-gate == -1) {
4480Sstevel@tonic-gate puts(gettext(msgtab[64]));
4490Sstevel@tonic-gate xflag = 0;
4500Sstevel@tonic-gate kflag = 0;
4510Sstevel@tonic-gate }
4520Sstevel@tonic-gate if (kflag == 0)
4530Sstevel@tonic-gate crflag = 0;
4540Sstevel@tonic-gate }
4550Sstevel@tonic-gate
4560Sstevel@tonic-gate if (argc > 0) {
4570Sstevel@tonic-gate p1 = *argv;
4580Sstevel@tonic-gate if (strlen(p1) >= (size_t)FNSIZE) {
4590Sstevel@tonic-gate puts(gettext("file name too long"));
4600Sstevel@tonic-gate if (kflag)
4610Sstevel@tonic-gate crypt_close(perm);
4620Sstevel@tonic-gate exit(2);
4630Sstevel@tonic-gate }
4640Sstevel@tonic-gate p2 = savedfile;
4650Sstevel@tonic-gate while (*p2++ = *p1++);
4660Sstevel@tonic-gate globp = "e";
4670Sstevel@tonic-gate fflg++;
4680Sstevel@tonic-gate } else /* editing with no file so set savtime to 0 */
4690Sstevel@tonic-gate savtime = 0;
4700Sstevel@tonic-gate eflg++;
4710Sstevel@tonic-gate if ((tfname = tempnam("", "ea")) == NULL) {
4720Sstevel@tonic-gate puts(gettext(msgtab[69]));
4730Sstevel@tonic-gate exit(2);
4740Sstevel@tonic-gate }
4750Sstevel@tonic-gate
4760Sstevel@tonic-gate fendcore = (LINE)sbrk(0);
4770Sstevel@tonic-gate init();
4780Sstevel@tonic-gate if (oldintr != SIG_IGN)
4790Sstevel@tonic-gate signal(SIGINT, onintr);
4800Sstevel@tonic-gate if (oldhup != SIG_IGN)
4810Sstevel@tonic-gate signal(SIGHUP, onhup);
4820Sstevel@tonic-gate setjmp(savej);
4830Sstevel@tonic-gate commands();
4840Sstevel@tonic-gate quit(sig);
4850Sstevel@tonic-gate return (0);
4860Sstevel@tonic-gate }
4870Sstevel@tonic-gate
4880Sstevel@tonic-gate static void
commands(void)4890Sstevel@tonic-gate commands(void)
4900Sstevel@tonic-gate {
4910Sstevel@tonic-gate LINE a1;
4920Sstevel@tonic-gate int c;
4930Sstevel@tonic-gate char *p1, *p2;
4940Sstevel@tonic-gate int fsave, m, n;
4950Sstevel@tonic-gate
4960Sstevel@tonic-gate for (;;) {
4970Sstevel@tonic-gate nodelim = 0;
4980Sstevel@tonic-gate if (pflag) {
4990Sstevel@tonic-gate pflag = 0;
5000Sstevel@tonic-gate addr1 = addr2 = dot;
5010Sstevel@tonic-gate goto print;
5020Sstevel@tonic-gate }
5030Sstevel@tonic-gate if (shflg && globp == 0)
5040Sstevel@tonic-gate write(1, gettext(prompt), strlen(gettext(prompt)));
5050Sstevel@tonic-gate addr1 = 0;
5060Sstevel@tonic-gate addr2 = 0;
5070Sstevel@tonic-gate if ((c = getchr()) == ',') {
5080Sstevel@tonic-gate addr1 = zero + 1;
5090Sstevel@tonic-gate addr2 = dol;
5100Sstevel@tonic-gate #ifdef XPG6
5110Sstevel@tonic-gate /* XPG4 - it was an error if the second address was */
5120Sstevel@tonic-gate /* input and the first address was ommitted */
5130Sstevel@tonic-gate /* Parse second address */
5140Sstevel@tonic-gate if ((a1 = address()) != 0) {
5150Sstevel@tonic-gate addr2 = a1;
5160Sstevel@tonic-gate }
5170Sstevel@tonic-gate #endif
5180Sstevel@tonic-gate c = getchr();
5190Sstevel@tonic-gate goto swch;
5200Sstevel@tonic-gate } else if (c == ';') {
5210Sstevel@tonic-gate addr1 = dot;
5220Sstevel@tonic-gate addr2 = dol;
5230Sstevel@tonic-gate #ifdef XPG6
5240Sstevel@tonic-gate /* XPG4 - it was an error if the second address was */
5250Sstevel@tonic-gate /* input and the first address was ommitted */
5260Sstevel@tonic-gate /* Parse second address */
5270Sstevel@tonic-gate if ((a1 = address()) != 0) {
5280Sstevel@tonic-gate addr2 = a1;
5290Sstevel@tonic-gate }
5300Sstevel@tonic-gate #endif
5310Sstevel@tonic-gate c = getchr();
5320Sstevel@tonic-gate goto swch;
5330Sstevel@tonic-gate } else
5340Sstevel@tonic-gate peekc = c;
5350Sstevel@tonic-gate do {
5360Sstevel@tonic-gate addr1 = addr2;
5370Sstevel@tonic-gate if ((a1 = address()) == 0) {
5380Sstevel@tonic-gate c = getchr();
5390Sstevel@tonic-gate break;
5400Sstevel@tonic-gate }
5410Sstevel@tonic-gate addr2 = a1;
5420Sstevel@tonic-gate if ((c = getchr()) == ';') {
5430Sstevel@tonic-gate c = ',';
5440Sstevel@tonic-gate dot = a1;
5450Sstevel@tonic-gate }
5460Sstevel@tonic-gate } while (c == ',');
5470Sstevel@tonic-gate if (addr1 == 0)
5480Sstevel@tonic-gate addr1 = addr2;
5490Sstevel@tonic-gate swch:
5500Sstevel@tonic-gate switch (c) {
5510Sstevel@tonic-gate
5520Sstevel@tonic-gate case 'a':
5530Sstevel@tonic-gate setdot();
5540Sstevel@tonic-gate newline();
5550Sstevel@tonic-gate if (!globflg) save();
5560Sstevel@tonic-gate append(gettty, addr2);
5570Sstevel@tonic-gate continue;
5580Sstevel@tonic-gate
5590Sstevel@tonic-gate case 'c':
5600Sstevel@tonic-gate #ifdef XPG6
5610Sstevel@tonic-gate setzeroasone();
5620Sstevel@tonic-gate #endif
5630Sstevel@tonic-gate delete();
5640Sstevel@tonic-gate append(gettty, addr1-1);
5650Sstevel@tonic-gate
5660Sstevel@tonic-gate /* XPG4 - If no new lines are inserted, then the current */
5670Sstevel@tonic-gate /* line becomes the line after the lines deleted. */
5680Sstevel@tonic-gate
5690Sstevel@tonic-gate if (((linebuf[0] != '.') || (dot == (addr1-1))) &&
5700Sstevel@tonic-gate (addr2 <= dol))
5710Sstevel@tonic-gate dot = addr1;
5720Sstevel@tonic-gate continue;
5730Sstevel@tonic-gate
5740Sstevel@tonic-gate case 'd':
5750Sstevel@tonic-gate delete();
5760Sstevel@tonic-gate continue;
5770Sstevel@tonic-gate
5780Sstevel@tonic-gate case 'E':
5790Sstevel@tonic-gate fchange = 0;
5800Sstevel@tonic-gate c = 'e';
5810Sstevel@tonic-gate case 'e':
5820Sstevel@tonic-gate fflg++;
5830Sstevel@tonic-gate setnoaddr();
5840Sstevel@tonic-gate if (vflag && fchange) {
5850Sstevel@tonic-gate fchange = 0;
5860Sstevel@tonic-gate (void) error(1);
5870Sstevel@tonic-gate }
5880Sstevel@tonic-gate filename(c);
5890Sstevel@tonic-gate eflg++;
5900Sstevel@tonic-gate init();
5910Sstevel@tonic-gate addr2 = zero;
5920Sstevel@tonic-gate goto caseread;
5930Sstevel@tonic-gate
5940Sstevel@tonic-gate case 'f':
5950Sstevel@tonic-gate setnoaddr();
5960Sstevel@tonic-gate filename(c);
5970Sstevel@tonic-gate if (!ncflg) /* there is a filename */
5980Sstevel@tonic-gate getime();
5990Sstevel@tonic-gate else
6000Sstevel@tonic-gate ncflg--;
6010Sstevel@tonic-gate puts(savedfile);
6020Sstevel@tonic-gate continue;
6030Sstevel@tonic-gate
6040Sstevel@tonic-gate case 'g':
6050Sstevel@tonic-gate global(1);
6060Sstevel@tonic-gate continue;
6070Sstevel@tonic-gate case 'G':
6080Sstevel@tonic-gate globaln(1);
6090Sstevel@tonic-gate continue;
6100Sstevel@tonic-gate
6110Sstevel@tonic-gate case 'h':
6120Sstevel@tonic-gate newline();
6130Sstevel@tonic-gate setnoaddr();
6140Sstevel@tonic-gate PUTM();
6150Sstevel@tonic-gate continue;
6160Sstevel@tonic-gate
6170Sstevel@tonic-gate case 'H':
6180Sstevel@tonic-gate newline();
6190Sstevel@tonic-gate setnoaddr();
6200Sstevel@tonic-gate if (!hflag) {
6210Sstevel@tonic-gate hflag = 1;
6220Sstevel@tonic-gate PUTM();
6230Sstevel@tonic-gate }
6240Sstevel@tonic-gate else
6250Sstevel@tonic-gate hflag = 0;
6260Sstevel@tonic-gate continue;
6270Sstevel@tonic-gate
6280Sstevel@tonic-gate case 'i':
6290Sstevel@tonic-gate #ifdef XPG6
6300Sstevel@tonic-gate setzeroasone();
6310Sstevel@tonic-gate #endif
6320Sstevel@tonic-gate setdot();
6330Sstevel@tonic-gate nonzero();
6340Sstevel@tonic-gate newline();
6350Sstevel@tonic-gate if (!globflg) save();
6360Sstevel@tonic-gate append(gettty, addr2-1);
6370Sstevel@tonic-gate if (dot == addr2-1)
6380Sstevel@tonic-gate dot += 1;
6390Sstevel@tonic-gate continue;
6400Sstevel@tonic-gate
6410Sstevel@tonic-gate case 'j':
6420Sstevel@tonic-gate if (addr2 == 0) {
6430Sstevel@tonic-gate addr1 = dot;
6440Sstevel@tonic-gate addr2 = dot+1;
6450Sstevel@tonic-gate }
6460Sstevel@tonic-gate setdot();
6470Sstevel@tonic-gate newline();
6480Sstevel@tonic-gate nonzero();
6490Sstevel@tonic-gate if (!globflg) save();
6500Sstevel@tonic-gate join();
6510Sstevel@tonic-gate continue;
6520Sstevel@tonic-gate
6530Sstevel@tonic-gate case 'k':
6540Sstevel@tonic-gate if ((c = getchr()) < 'a' || c > 'z')
6550Sstevel@tonic-gate (void) error(2);
6560Sstevel@tonic-gate newline();
6570Sstevel@tonic-gate setdot();
6580Sstevel@tonic-gate nonzero();
6590Sstevel@tonic-gate names[c-'a'] = addr2->cur & ~01;
6600Sstevel@tonic-gate anymarks |= 01;
6610Sstevel@tonic-gate continue;
6620Sstevel@tonic-gate
6630Sstevel@tonic-gate case 'm':
6640Sstevel@tonic-gate move(0);
6650Sstevel@tonic-gate continue;
6660Sstevel@tonic-gate
6670Sstevel@tonic-gate case '\n':
6680Sstevel@tonic-gate if (addr2 == 0)
6690Sstevel@tonic-gate addr2 = dot+1;
6700Sstevel@tonic-gate addr1 = addr2;
6710Sstevel@tonic-gate goto print;
6720Sstevel@tonic-gate
6730Sstevel@tonic-gate case 'n':
6740Sstevel@tonic-gate listn++;
6750Sstevel@tonic-gate newline();
6760Sstevel@tonic-gate goto print;
6770Sstevel@tonic-gate
6780Sstevel@tonic-gate case 'l':
6790Sstevel@tonic-gate listf++;
6800Sstevel@tonic-gate case 'p':
6810Sstevel@tonic-gate newline();
6820Sstevel@tonic-gate print:
6830Sstevel@tonic-gate setdot();
6840Sstevel@tonic-gate nonzero();
6850Sstevel@tonic-gate a1 = addr1;
6860Sstevel@tonic-gate do {
6870Sstevel@tonic-gate if (listn) {
6880Sstevel@tonic-gate count = a1 - zero;
6890Sstevel@tonic-gate putd();
6900Sstevel@tonic-gate putchr('\t');
6910Sstevel@tonic-gate }
692*13093SRoger.Faulkner@Oracle.COM puts(getaline((a1++)->cur));
6930Sstevel@tonic-gate }
6940Sstevel@tonic-gate while (a1 <= addr2);
6950Sstevel@tonic-gate dot = addr2;
6960Sstevel@tonic-gate pflag = 0;
6970Sstevel@tonic-gate listn = 0;
6980Sstevel@tonic-gate listf = 0;
6990Sstevel@tonic-gate continue;
7000Sstevel@tonic-gate
7010Sstevel@tonic-gate case 'Q':
7020Sstevel@tonic-gate fchange = 0;
7030Sstevel@tonic-gate case 'q':
7040Sstevel@tonic-gate setnoaddr();
7050Sstevel@tonic-gate newline();
7060Sstevel@tonic-gate quit(sig);
7070Sstevel@tonic-gate
7080Sstevel@tonic-gate case 'r':
7090Sstevel@tonic-gate filename(c);
7100Sstevel@tonic-gate caseread:
7110Sstevel@tonic-gate readflg = 1;
7120Sstevel@tonic-gate save28 = (dol != fendcore);
7130Sstevel@tonic-gate if (crflag == 2 || crflag == -2)
7140Sstevel@tonic-gate crflag = -1; /* restore crflag for next file */
7150Sstevel@tonic-gate errno = 0;
7160Sstevel@tonic-gate if ((io = eopen(file, O_RDONLY)) < 0) {
7170Sstevel@tonic-gate lastc = '\n';
7180Sstevel@tonic-gate /* if first entering editor and file does not exist */
7190Sstevel@tonic-gate /* set saved access time to 0 */
7200Sstevel@tonic-gate if (eflg) {
7210Sstevel@tonic-gate savtime = 0;
7220Sstevel@tonic-gate eflg = 0;
7230Sstevel@tonic-gate if (c == 'e' && vflag == 0)
7240Sstevel@tonic-gate qflg = 1;
7250Sstevel@tonic-gate }
7260Sstevel@tonic-gate if (errno == ENOENT) {
7270Sstevel@tonic-gate (void) error(68);
7280Sstevel@tonic-gate } else {
7290Sstevel@tonic-gate (void) error(3);
7300Sstevel@tonic-gate }
7310Sstevel@tonic-gate }
7320Sstevel@tonic-gate /* get last mod time of file */
7330Sstevel@tonic-gate /* eflg - entered editor with ed or e */
7340Sstevel@tonic-gate if (eflg) {
7350Sstevel@tonic-gate eflg = 0;
7360Sstevel@tonic-gate getime();
7370Sstevel@tonic-gate }
7380Sstevel@tonic-gate setall();
7390Sstevel@tonic-gate ninbuf = 0;
7400Sstevel@tonic-gate n = zero != dol;
7410Sstevel@tonic-gate #ifdef NULLS
7420Sstevel@tonic-gate nulls = 0;
7430Sstevel@tonic-gate #endif
7440Sstevel@tonic-gate if (!globflg && (c == 'r')) save();
7450Sstevel@tonic-gate append(getfile, addr2);
7460Sstevel@tonic-gate exfile();
7470Sstevel@tonic-gate readflg = 0;
7480Sstevel@tonic-gate fchange = n;
7490Sstevel@tonic-gate continue;
7500Sstevel@tonic-gate
7510Sstevel@tonic-gate case 's':
7520Sstevel@tonic-gate setdot();
7530Sstevel@tonic-gate nonzero();
7540Sstevel@tonic-gate if (!globflg) save();
7550Sstevel@tonic-gate substitute(globp != 0);
7560Sstevel@tonic-gate continue;
7570Sstevel@tonic-gate
7580Sstevel@tonic-gate case 't':
7590Sstevel@tonic-gate move(1);
7600Sstevel@tonic-gate continue;
7610Sstevel@tonic-gate
7620Sstevel@tonic-gate case 'u':
7630Sstevel@tonic-gate setdot();
7640Sstevel@tonic-gate newline();
7650Sstevel@tonic-gate if (!initflg)
7660Sstevel@tonic-gate undo();
7670Sstevel@tonic-gate else
7680Sstevel@tonic-gate (void) error(5);
7690Sstevel@tonic-gate fchange = 1;
7700Sstevel@tonic-gate continue;
7710Sstevel@tonic-gate
7720Sstevel@tonic-gate case 'v':
7730Sstevel@tonic-gate global(0);
7740Sstevel@tonic-gate continue;
7750Sstevel@tonic-gate case 'V':
7760Sstevel@tonic-gate globaln(0);
7770Sstevel@tonic-gate continue;
7780Sstevel@tonic-gate
7790Sstevel@tonic-gate case 'W':
7800Sstevel@tonic-gate case 'w':
7810Sstevel@tonic-gate if (flag28) {
7820Sstevel@tonic-gate flag28 = 0;
7830Sstevel@tonic-gate fchange = 0;
7840Sstevel@tonic-gate (void) error(61);
7850Sstevel@tonic-gate }
7860Sstevel@tonic-gate setall();
7870Sstevel@tonic-gate
7880Sstevel@tonic-gate /* on NULL-RE condition do not generate error */
7890Sstevel@tonic-gate
7900Sstevel@tonic-gate if ((linebuf[0] != '.') && (zero != dol) &&
7910Sstevel@tonic-gate (addr1 <= zero || addr2 > dol))
7920Sstevel@tonic-gate (void) error(15);
7930Sstevel@tonic-gate filename(c);
7940Sstevel@tonic-gate if (Xqt) {
7950Sstevel@tonic-gate io = eopen(file, O_WRONLY);
7960Sstevel@tonic-gate n = 1; /* set n so newtime will not execute */
7970Sstevel@tonic-gate } else {
7980Sstevel@tonic-gate struct stat lFl;
7990Sstevel@tonic-gate fstat(tfile, &Tf);
8000Sstevel@tonic-gate if (stat(file, &Fl) < 0) {
8010Sstevel@tonic-gate if ((io = creat(file, S_IRUSR|S_IWUSR|S_IRGRP
8020Sstevel@tonic-gate |S_IWGRP|S_IROTH|S_IWOTH)) < 0)
8030Sstevel@tonic-gate (void) error(7);
8040Sstevel@tonic-gate fstat(io, &Fl);
8050Sstevel@tonic-gate Fl.st_mtime = 0;
8060Sstevel@tonic-gate lFl = Fl;
8070Sstevel@tonic-gate close(io);
8080Sstevel@tonic-gate } else {
8090Sstevel@tonic-gate #ifndef RESEARCH
8100Sstevel@tonic-gate oldmask = umask(0);
8110Sstevel@tonic-gate /*
8120Sstevel@tonic-gate * Must determine if file is
8130Sstevel@tonic-gate * a symbolic link
8140Sstevel@tonic-gate */
8150Sstevel@tonic-gate lstat(file, &lFl);
8160Sstevel@tonic-gate #endif
8170Sstevel@tonic-gate }
8180Sstevel@tonic-gate #ifndef RESEARCH
8190Sstevel@tonic-gate /*
8200Sstevel@tonic-gate * Determine if there are enough free blocks on system
8210Sstevel@tonic-gate */
8220Sstevel@tonic-gate if (!Short && statvfs(file, &U) == 0 &&
8230Sstevel@tonic-gate U.f_bfree < ((Tf.st_size/U.f_frsize) + 100)) {
8240Sstevel@tonic-gate Short = 1;
8250Sstevel@tonic-gate (void) error(8);
8260Sstevel@tonic-gate }
8270Sstevel@tonic-gate Short = 0;
8280Sstevel@tonic-gate #endif
8290Sstevel@tonic-gate p1 = savedfile; /* The current filename */
8300Sstevel@tonic-gate p2 = file;
8310Sstevel@tonic-gate m = strcmp(p1, p2);
8320Sstevel@tonic-gate if (c == 'w' && Fl.st_nlink == 1 && ISREG(lFl)) {
8330Sstevel@tonic-gate if (close(open(file, O_WRONLY)) < 0)
8340Sstevel@tonic-gate (void) error(9);
8350Sstevel@tonic-gate if (!(n = m))
8360Sstevel@tonic-gate chktime();
8370Sstevel@tonic-gate mkfunny();
8380Sstevel@tonic-gate /*
8390Sstevel@tonic-gate * If funlink equals one it means that
8400Sstevel@tonic-gate * funny points to a valid file which must
8410Sstevel@tonic-gate * be unlinked when interrupted.
8420Sstevel@tonic-gate */
8430Sstevel@tonic-gate
8440Sstevel@tonic-gate funlink = 1;
8450Sstevel@tonic-gate if ((io = creat(funny, FMODE(Fl))) >= 0) {
8460Sstevel@tonic-gate chown(funny, Fl.st_uid, Fl.st_gid);
8470Sstevel@tonic-gate chmod(funny, FMODE(Fl));
8480Sstevel@tonic-gate putfile();
8490Sstevel@tonic-gate exfile();
8500Sstevel@tonic-gate
8510Sstevel@tonic-gate if (rename(funny, file))
8520Sstevel@tonic-gate (void) error(10);
8530Sstevel@tonic-gate funlink = 0;
8540Sstevel@tonic-gate /* if filenames are the same */
8550Sstevel@tonic-gate if (!n)
8560Sstevel@tonic-gate newtime();
8570Sstevel@tonic-gate /* check if entire buffer was written */
8580Sstevel@tonic-gate fsave = fchange;
8590Sstevel@tonic-gate fchange = (((addr1 == zero) || (addr1 == (zero + 1))) &&
8600Sstevel@tonic-gate (addr2 == dol)) ? 0 : 1;
8610Sstevel@tonic-gate if (fchange == 1 && m != 0) fchange = fsave;
8620Sstevel@tonic-gate continue;
8630Sstevel@tonic-gate }
8640Sstevel@tonic-gate } else
8650Sstevel@tonic-gate n = 1; /* set n so newtime will not execute */
8660Sstevel@tonic-gate if ((io = open(file,
8670Sstevel@tonic-gate (c == 'w') ? O_WRONLY|O_CREAT|O_TRUNC
8680Sstevel@tonic-gate : O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR
8690Sstevel@tonic-gate |S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) < 0)
8700Sstevel@tonic-gate (void) error(7);
8710Sstevel@tonic-gate }
8720Sstevel@tonic-gate putfile();
8730Sstevel@tonic-gate exfile();
8740Sstevel@tonic-gate if (!n) newtime();
8750Sstevel@tonic-gate fsave = fchange;
8760Sstevel@tonic-gate fchange = (((addr1 == zero) || (addr1 == (zero + 1))) &&
8770Sstevel@tonic-gate (addr2 == dol)) ? 0 : 1;
8780Sstevel@tonic-gate /* Leave fchange alone if partial write was to another file */
8790Sstevel@tonic-gate if (fchange == 1 && m != 0) fchange = fsave;
8800Sstevel@tonic-gate continue;
8810Sstevel@tonic-gate
8820Sstevel@tonic-gate case 'C':
8830Sstevel@tonic-gate crflag = 1;
8840Sstevel@tonic-gate /*
8850Sstevel@tonic-gate * C is same as X, but always assume input files are
8860Sstevel@tonic-gate * ciphertext
8870Sstevel@tonic-gate */
8880Sstevel@tonic-gate goto encrypt;
8890Sstevel@tonic-gate
8900Sstevel@tonic-gate case 'X':
8910Sstevel@tonic-gate crflag = -1;
8920Sstevel@tonic-gate encrypt:
8930Sstevel@tonic-gate setnoaddr();
8940Sstevel@tonic-gate newline();
8950Sstevel@tonic-gate xflag = 1;
8960Sstevel@tonic-gate if (permflag)
8970Sstevel@tonic-gate (void) crypt_close(perm);
8980Sstevel@tonic-gate permflag = 1;
8990Sstevel@tonic-gate if ((kflag = run_setkey(&perm[0], getkey(msgtab[66])))
9000Sstevel@tonic-gate == -1) {
9010Sstevel@tonic-gate xflag = 0;
9020Sstevel@tonic-gate kflag = 0;
9030Sstevel@tonic-gate crflag = 0;
9040Sstevel@tonic-gate (void) error(64);
9050Sstevel@tonic-gate }
9060Sstevel@tonic-gate if (kflag == 0)
9070Sstevel@tonic-gate crflag = 0;
9080Sstevel@tonic-gate continue;
9090Sstevel@tonic-gate
9100Sstevel@tonic-gate case '=':
9110Sstevel@tonic-gate setall();
9120Sstevel@tonic-gate newline();
9130Sstevel@tonic-gate count = (addr2-zero)&077777;
9140Sstevel@tonic-gate putd();
9150Sstevel@tonic-gate putchr('\n');
9160Sstevel@tonic-gate continue;
9170Sstevel@tonic-gate
9180Sstevel@tonic-gate case '!':
9190Sstevel@tonic-gate unixcom();
9200Sstevel@tonic-gate continue;
9210Sstevel@tonic-gate
9220Sstevel@tonic-gate case EOF:
9230Sstevel@tonic-gate return;
9240Sstevel@tonic-gate
9250Sstevel@tonic-gate case 'P':
9260Sstevel@tonic-gate setnoaddr();
9270Sstevel@tonic-gate newline();
9280Sstevel@tonic-gate if (shflg)
9290Sstevel@tonic-gate shflg = 0;
9300Sstevel@tonic-gate else
9310Sstevel@tonic-gate shflg++;
9320Sstevel@tonic-gate continue;
9330Sstevel@tonic-gate }
9340Sstevel@tonic-gate if (c == 'x')
9350Sstevel@tonic-gate (void) error(60);
9360Sstevel@tonic-gate else
9370Sstevel@tonic-gate (void) error(12);
9380Sstevel@tonic-gate }
9390Sstevel@tonic-gate }
9400Sstevel@tonic-gate
9410Sstevel@tonic-gate LINE
address(void)9420Sstevel@tonic-gate address(void)
9430Sstevel@tonic-gate {
9440Sstevel@tonic-gate int minus, c;
9450Sstevel@tonic-gate LINE a1;
9460Sstevel@tonic-gate int n, relerr, retval;
9470Sstevel@tonic-gate
9480Sstevel@tonic-gate minus = 0;
9490Sstevel@tonic-gate a1 = 0;
9500Sstevel@tonic-gate for (;;) {
9510Sstevel@tonic-gate c = getchr();
9520Sstevel@tonic-gate if ('0' <= c && c <= '9') {
9530Sstevel@tonic-gate n = 0;
9540Sstevel@tonic-gate do {
9550Sstevel@tonic-gate n *= 10;
9560Sstevel@tonic-gate n += c - '0';
9570Sstevel@tonic-gate } while ((c = getchr()) >= '0' && c <= '9');
9580Sstevel@tonic-gate peekc = c;
9590Sstevel@tonic-gate if (a1 == 0)
9600Sstevel@tonic-gate a1 = zero;
9610Sstevel@tonic-gate if (minus < 0)
9620Sstevel@tonic-gate n = -n;
9630Sstevel@tonic-gate a1 += n;
9640Sstevel@tonic-gate minus = 0;
9650Sstevel@tonic-gate continue;
9660Sstevel@tonic-gate }
9670Sstevel@tonic-gate relerr = 0;
9680Sstevel@tonic-gate if (a1 || minus)
9690Sstevel@tonic-gate relerr++;
9700Sstevel@tonic-gate switch (c) {
9710Sstevel@tonic-gate case ' ':
9720Sstevel@tonic-gate case '\t':
9730Sstevel@tonic-gate continue;
9740Sstevel@tonic-gate
9750Sstevel@tonic-gate case '+':
9760Sstevel@tonic-gate minus++;
9770Sstevel@tonic-gate if (a1 == 0)
9780Sstevel@tonic-gate a1 = dot;
9790Sstevel@tonic-gate continue;
9800Sstevel@tonic-gate
9810Sstevel@tonic-gate case '-':
9820Sstevel@tonic-gate case '^':
9830Sstevel@tonic-gate minus--;
9840Sstevel@tonic-gate if (a1 == 0)
9850Sstevel@tonic-gate a1 = dot;
9860Sstevel@tonic-gate continue;
9870Sstevel@tonic-gate
9880Sstevel@tonic-gate case '?':
9890Sstevel@tonic-gate case '/':
9900Sstevel@tonic-gate comple(c);
9910Sstevel@tonic-gate a1 = dot;
9920Sstevel@tonic-gate for (;;) {
9930Sstevel@tonic-gate if (c == '/') {
9940Sstevel@tonic-gate a1++;
9950Sstevel@tonic-gate if (a1 > dol)
9960Sstevel@tonic-gate a1 = zero;
9970Sstevel@tonic-gate } else {
9980Sstevel@tonic-gate a1--;
9990Sstevel@tonic-gate if (a1 < zero)
10000Sstevel@tonic-gate a1 = dol;
10010Sstevel@tonic-gate }
10020Sstevel@tonic-gate
10030Sstevel@tonic-gate if (execute(0, a1))
10040Sstevel@tonic-gate break;
10050Sstevel@tonic-gate if (a1 == dot)
10060Sstevel@tonic-gate (void) error(13);
10070Sstevel@tonic-gate }
10080Sstevel@tonic-gate break;
10090Sstevel@tonic-gate
10100Sstevel@tonic-gate case '$':
10110Sstevel@tonic-gate a1 = dol;
10120Sstevel@tonic-gate break;
10130Sstevel@tonic-gate
10140Sstevel@tonic-gate case '.':
10150Sstevel@tonic-gate a1 = dot;
10160Sstevel@tonic-gate break;
10170Sstevel@tonic-gate
10180Sstevel@tonic-gate case '\'':
10190Sstevel@tonic-gate if ((c = getchr()) < 'a' || c > 'z')
10200Sstevel@tonic-gate (void) error(2);
10210Sstevel@tonic-gate for (a1 = zero; a1 <= dol; a1++)
10220Sstevel@tonic-gate if (names[c-'a'] == (a1->cur & ~01))
10230Sstevel@tonic-gate break;
10240Sstevel@tonic-gate break;
10250Sstevel@tonic-gate
10260Sstevel@tonic-gate default:
10270Sstevel@tonic-gate peekc = c;
10280Sstevel@tonic-gate if (a1 == 0)
10290Sstevel@tonic-gate return (0);
10300Sstevel@tonic-gate a1 += minus;
10310Sstevel@tonic-gate
10320Sstevel@tonic-gate /* on NULL-RE condition do not generate error */
10330Sstevel@tonic-gate
10340Sstevel@tonic-gate if ((linebuf[0] != '.') && (a1 < zero || a1 > dol))
10350Sstevel@tonic-gate (void) error(15);
10360Sstevel@tonic-gate return (a1);
10370Sstevel@tonic-gate }
10380Sstevel@tonic-gate if (relerr)
10390Sstevel@tonic-gate (void) error(16);
10400Sstevel@tonic-gate }
10410Sstevel@tonic-gate }
10420Sstevel@tonic-gate
10430Sstevel@tonic-gate static void
setdot(void)10440Sstevel@tonic-gate setdot(void)
10450Sstevel@tonic-gate {
10460Sstevel@tonic-gate if (addr2 == 0)
10470Sstevel@tonic-gate addr1 = addr2 = dot;
10480Sstevel@tonic-gate if (addr1 > addr2)
10490Sstevel@tonic-gate (void) error(17);
10500Sstevel@tonic-gate }
10510Sstevel@tonic-gate
10520Sstevel@tonic-gate static void
setall(void)10530Sstevel@tonic-gate setall(void)
10540Sstevel@tonic-gate {
10550Sstevel@tonic-gate if (addr2 == 0) {
10560Sstevel@tonic-gate addr1 = zero+1;
10570Sstevel@tonic-gate addr2 = dol;
10580Sstevel@tonic-gate if (dol == zero)
10590Sstevel@tonic-gate addr1 = zero;
10600Sstevel@tonic-gate }
10610Sstevel@tonic-gate setdot();
10620Sstevel@tonic-gate }
10630Sstevel@tonic-gate
10640Sstevel@tonic-gate static void
setnoaddr(void)10650Sstevel@tonic-gate setnoaddr(void)
10660Sstevel@tonic-gate {
10670Sstevel@tonic-gate if (addr2)
10680Sstevel@tonic-gate (void) error(18);
10690Sstevel@tonic-gate }
10700Sstevel@tonic-gate
10710Sstevel@tonic-gate static void
nonzero(void)10720Sstevel@tonic-gate nonzero(void)
10730Sstevel@tonic-gate {
10740Sstevel@tonic-gate /* on NULL-RE condition do not generate error */
10750Sstevel@tonic-gate
10760Sstevel@tonic-gate if ((linebuf[0] != '.') && (addr1 <= zero || addr2 > dol))
10770Sstevel@tonic-gate (void) error(15);
10780Sstevel@tonic-gate }
10790Sstevel@tonic-gate
10800Sstevel@tonic-gate static void
setzeroasone(void)10810Sstevel@tonic-gate setzeroasone(void)
10820Sstevel@tonic-gate {
10830Sstevel@tonic-gate /* for the c and i commands 0 equal to 1 address */
10840Sstevel@tonic-gate if (addr1 == zero) {
10850Sstevel@tonic-gate addr1 = zero+1;
10860Sstevel@tonic-gate }
10870Sstevel@tonic-gate if (addr2 == zero) {
10880Sstevel@tonic-gate addr2 = zero+1;
10890Sstevel@tonic-gate }
10900Sstevel@tonic-gate }
10910Sstevel@tonic-gate
10920Sstevel@tonic-gate
10930Sstevel@tonic-gate static void
newline(void)10940Sstevel@tonic-gate newline(void)
10950Sstevel@tonic-gate {
10960Sstevel@tonic-gate int c;
10970Sstevel@tonic-gate
10980Sstevel@tonic-gate if ((c = getchr()) == '\n')
10990Sstevel@tonic-gate return;
11000Sstevel@tonic-gate if (c == 'p' || c == 'l' || c == 'n') {
11010Sstevel@tonic-gate pflag++;
11020Sstevel@tonic-gate if (c == 'l') listf++;
11030Sstevel@tonic-gate if (c == 'n') listn++;
11040Sstevel@tonic-gate if ((c = getchr()) == '\n')
11050Sstevel@tonic-gate return;
11060Sstevel@tonic-gate }
11070Sstevel@tonic-gate (void) error(20);
11080Sstevel@tonic-gate }
11090Sstevel@tonic-gate
11100Sstevel@tonic-gate static void
filename(int comm)11110Sstevel@tonic-gate filename(int comm)
11120Sstevel@tonic-gate {
11130Sstevel@tonic-gate char *p1, *p2;
11140Sstevel@tonic-gate int c;
11150Sstevel@tonic-gate int i = 0;
11160Sstevel@tonic-gate
11170Sstevel@tonic-gate count = 0;
11180Sstevel@tonic-gate c = getchr();
11190Sstevel@tonic-gate if (c == '\n' || c == EOF) {
11200Sstevel@tonic-gate p1 = savedfile;
11210Sstevel@tonic-gate if (*p1 == 0 && comm != 'f')
11220Sstevel@tonic-gate (void) error(21);
11230Sstevel@tonic-gate /* ncflg set means do not get mod time of file */
11240Sstevel@tonic-gate /* since no filename followed f */
11250Sstevel@tonic-gate if (comm == 'f')
11260Sstevel@tonic-gate ncflg++;
11270Sstevel@tonic-gate p2 = file;
11280Sstevel@tonic-gate while (*p2++ = *p1++);
11290Sstevel@tonic-gate red(savedfile);
11300Sstevel@tonic-gate return;
11310Sstevel@tonic-gate }
11320Sstevel@tonic-gate if (c != ' ')
11330Sstevel@tonic-gate (void) error(22);
11340Sstevel@tonic-gate while ((c = getchr()) == ' ');
11350Sstevel@tonic-gate if (c == '!')
11360Sstevel@tonic-gate ++Xqt, c = getchr();
11370Sstevel@tonic-gate if (c == '\n')
11380Sstevel@tonic-gate (void) error(21);
11390Sstevel@tonic-gate p1 = file;
11400Sstevel@tonic-gate do {
11410Sstevel@tonic-gate if (++i >= FNSIZE)
11420Sstevel@tonic-gate (void) error(24);
11430Sstevel@tonic-gate *p1++ = c;
11440Sstevel@tonic-gate if (c == EOF || (c == ' ' && !Xqt))
11450Sstevel@tonic-gate (void) error(21);
11460Sstevel@tonic-gate } while ((c = getchr()) != '\n');
11470Sstevel@tonic-gate *p1++ = 0;
11480Sstevel@tonic-gate if (Xqt)
11490Sstevel@tonic-gate if (comm == 'f') {
11500Sstevel@tonic-gate --Xqt;
11510Sstevel@tonic-gate (void) error(57);
11520Sstevel@tonic-gate }
11530Sstevel@tonic-gate else
11540Sstevel@tonic-gate return;
11550Sstevel@tonic-gate if (savedfile[0] == 0 || comm == 'e' || comm == 'f') {
11560Sstevel@tonic-gate p1 = savedfile;
11570Sstevel@tonic-gate p2 = file;
11580Sstevel@tonic-gate while (*p1++ = *p2++);
11590Sstevel@tonic-gate }
11600Sstevel@tonic-gate red(file);
11610Sstevel@tonic-gate }
11620Sstevel@tonic-gate
11630Sstevel@tonic-gate
11640Sstevel@tonic-gate static void
exfile(void)11650Sstevel@tonic-gate exfile(void)
11660Sstevel@tonic-gate {
11670Sstevel@tonic-gate #ifdef NULLS
11680Sstevel@tonic-gate int c;
11690Sstevel@tonic-gate #endif
11700Sstevel@tonic-gate
11710Sstevel@tonic-gate #ifndef RESEARCH
11720Sstevel@tonic-gate if (oldmask) {
11730Sstevel@tonic-gate umask(oldmask);
11740Sstevel@tonic-gate oldmask = 0;
11750Sstevel@tonic-gate }
11760Sstevel@tonic-gate #endif
11770Sstevel@tonic-gate eclose(io);
11780Sstevel@tonic-gate io = -1;
11790Sstevel@tonic-gate if (vflag) {
11800Sstevel@tonic-gate putd();
11810Sstevel@tonic-gate putchr('\n');
11820Sstevel@tonic-gate #ifdef NULLS
11830Sstevel@tonic-gate if (nulls) {
11840Sstevel@tonic-gate c = count;
11850Sstevel@tonic-gate count = nulls;
11860Sstevel@tonic-gate nulls = 0;
11870Sstevel@tonic-gate putd();
11880Sstevel@tonic-gate puts(gettext(" nulls replaced by '\\0'"));
11890Sstevel@tonic-gate count = c;
11900Sstevel@tonic-gate }
11910Sstevel@tonic-gate #endif
11920Sstevel@tonic-gate }
11930Sstevel@tonic-gate }
11940Sstevel@tonic-gate
11950Sstevel@tonic-gate static void
onintr(int sig)11960Sstevel@tonic-gate onintr(int sig)
11970Sstevel@tonic-gate {
11980Sstevel@tonic-gate signal(SIGINT, onintr);
11990Sstevel@tonic-gate putchr('\n');
12000Sstevel@tonic-gate lastc = '\n';
12010Sstevel@tonic-gate globflg = 0;
12020Sstevel@tonic-gate if (funlink) unlink(funny); /* remove tmp file */
12030Sstevel@tonic-gate /* if interrupted a read, only part of file may be in buffer */
12040Sstevel@tonic-gate if (readflg) {
12050Sstevel@tonic-gate sprintf(tstring, "\007read may be incomplete - beware!\007");
12060Sstevel@tonic-gate puts(gettext(tstring));
12070Sstevel@tonic-gate fchange = 0;
12080Sstevel@tonic-gate }
12090Sstevel@tonic-gate (void) error(26);
12100Sstevel@tonic-gate }
12110Sstevel@tonic-gate
12120Sstevel@tonic-gate static void
onhup(int sig)12130Sstevel@tonic-gate onhup(int sig)
12140Sstevel@tonic-gate {
12150Sstevel@tonic-gate signal(SIGINT, SIG_IGN);
12160Sstevel@tonic-gate signal(SIGHUP, SIG_IGN);
12170Sstevel@tonic-gate /*
12180Sstevel@tonic-gate * if there are lines in file and file was not written
12190Sstevel@tonic-gate * since last update, save in ed.hup, or $HOME/ed.hup
12200Sstevel@tonic-gate */
12210Sstevel@tonic-gate if (dol > zero && fchange == 1) {
12220Sstevel@tonic-gate addr1 = zero+1;
12230Sstevel@tonic-gate addr2 = dol;
12240Sstevel@tonic-gate io = creat("ed.hup",
12250Sstevel@tonic-gate S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
12260Sstevel@tonic-gate if (io < 0 && home) {
12270Sstevel@tonic-gate char *fn;
12280Sstevel@tonic-gate
12290Sstevel@tonic-gate fn = (char *)calloc(strlen(home) + 8, sizeof (char));
12300Sstevel@tonic-gate if (fn) {
12310Sstevel@tonic-gate strcpy(fn, home);
12320Sstevel@tonic-gate strcat(fn, "/ed.hup");
12330Sstevel@tonic-gate io = creat(fn, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP
12340Sstevel@tonic-gate |S_IROTH|S_IWOTH);
12350Sstevel@tonic-gate free(fn);
12360Sstevel@tonic-gate }
12370Sstevel@tonic-gate }
12380Sstevel@tonic-gate if (io > 0)
12390Sstevel@tonic-gate putfile();
12400Sstevel@tonic-gate }
12410Sstevel@tonic-gate fchange = 0;
12420Sstevel@tonic-gate ++errcnt;
12430Sstevel@tonic-gate quit(sig);
12440Sstevel@tonic-gate }
12450Sstevel@tonic-gate
12460Sstevel@tonic-gate static int
error(int code)12470Sstevel@tonic-gate error(int code)
12480Sstevel@tonic-gate {
12490Sstevel@tonic-gate int c;
12500Sstevel@tonic-gate
12510Sstevel@tonic-gate if (code == 28 && save28 == 0) {
12520Sstevel@tonic-gate fchange = 0;
12530Sstevel@tonic-gate flag28++;
12540Sstevel@tonic-gate }
12550Sstevel@tonic-gate readflg = 0;
12560Sstevel@tonic-gate ++errcnt;
12570Sstevel@tonic-gate listf = listn = 0;
12580Sstevel@tonic-gate pflag = 0;
12590Sstevel@tonic-gate #ifndef RESEARCH
12600Sstevel@tonic-gate if (oldmask) {
12610Sstevel@tonic-gate umask(oldmask);
12620Sstevel@tonic-gate oldmask = 0;
12630Sstevel@tonic-gate }
12640Sstevel@tonic-gate #endif
12650Sstevel@tonic-gate #ifdef NULLS /* Not really nulls, but close enough */
12660Sstevel@tonic-gate /* This is a bug because of buffering */
12670Sstevel@tonic-gate if (code == 28) /* illegal char. */
12680Sstevel@tonic-gate putd();
12690Sstevel@tonic-gate #endif
12700Sstevel@tonic-gate /* Cant open file or file does not exist */
12710Sstevel@tonic-gate if ((code == 3) || (code == 68)) {
12720Sstevel@tonic-gate if (qflg == 0) {
12730Sstevel@tonic-gate putchr('?');
12740Sstevel@tonic-gate puts(file);
12750Sstevel@tonic-gate }
12760Sstevel@tonic-gate else
12770Sstevel@tonic-gate qflg = 0;
12780Sstevel@tonic-gate }
12790Sstevel@tonic-gate else
12800Sstevel@tonic-gate {
12810Sstevel@tonic-gate putchr('?');
12820Sstevel@tonic-gate putchr('\n');
12830Sstevel@tonic-gate }
12840Sstevel@tonic-gate count = 0;
12850Sstevel@tonic-gate lseek(0, (long)0, 2);
12860Sstevel@tonic-gate if (globp)
12870Sstevel@tonic-gate lastc = '\n';
12880Sstevel@tonic-gate globp = 0;
12890Sstevel@tonic-gate peekc = lastc;
12900Sstevel@tonic-gate if (lastc)
12910Sstevel@tonic-gate while ((c = getchr()) != '\n' && c != EOF);
12920Sstevel@tonic-gate if (io) {
12930Sstevel@tonic-gate eclose(io);
12940Sstevel@tonic-gate io = -1;
12950Sstevel@tonic-gate }
12960Sstevel@tonic-gate xcode = code;
12970Sstevel@tonic-gate if (hflag)
12980Sstevel@tonic-gate PUTM();
12990Sstevel@tonic-gate if (code == 4)
13000Sstevel@tonic-gate return (0); /* Non-fatal error. */
13010Sstevel@tonic-gate longjmp(savej, 1);
13020Sstevel@tonic-gate /* NOTREACHED */
13030Sstevel@tonic-gate }
13040Sstevel@tonic-gate
13050Sstevel@tonic-gate static int
getchr(void)13060Sstevel@tonic-gate getchr(void)
13070Sstevel@tonic-gate {
13080Sstevel@tonic-gate char c;
13090Sstevel@tonic-gate if (lastc = peekc) {
13100Sstevel@tonic-gate peekc = 0;
13110Sstevel@tonic-gate return (lastc);
13120Sstevel@tonic-gate }
13130Sstevel@tonic-gate if (globp) {
13140Sstevel@tonic-gate if ((lastc = (unsigned char)*globp++) != 0)
13150Sstevel@tonic-gate return (lastc);
13160Sstevel@tonic-gate globp = 0;
13170Sstevel@tonic-gate return (EOF);
13180Sstevel@tonic-gate }
13190Sstevel@tonic-gate if (read(0, &c, 1) <= 0)
13200Sstevel@tonic-gate return (lastc = EOF);
13210Sstevel@tonic-gate lastc = (unsigned char)c;
13220Sstevel@tonic-gate return (lastc);
13230Sstevel@tonic-gate }
13240Sstevel@tonic-gate
13250Sstevel@tonic-gate static int
gettty(void)13260Sstevel@tonic-gate gettty(void)
13270Sstevel@tonic-gate {
13280Sstevel@tonic-gate int c;
13290Sstevel@tonic-gate char *gf;
13300Sstevel@tonic-gate char *p;
13310Sstevel@tonic-gate
13320Sstevel@tonic-gate p = linebuf;
13330Sstevel@tonic-gate gf = globp;
13340Sstevel@tonic-gate while ((c = getchr()) != '\n') {
13350Sstevel@tonic-gate if (c == EOF) {
13360Sstevel@tonic-gate if (gf)
13370Sstevel@tonic-gate peekc = c;
13380Sstevel@tonic-gate return (c);
13390Sstevel@tonic-gate }
13400Sstevel@tonic-gate if (c == 0)
13410Sstevel@tonic-gate continue;
13420Sstevel@tonic-gate *p++ = c;
13430Sstevel@tonic-gate
13440Sstevel@tonic-gate if (p > &linebuf[LBSIZE-1])
13450Sstevel@tonic-gate (void) error(27);
13460Sstevel@tonic-gate }
13470Sstevel@tonic-gate *p++ = 0;
13480Sstevel@tonic-gate if (linebuf[0] == '.' && linebuf[1] == 0)
13490Sstevel@tonic-gate return (EOF);
13500Sstevel@tonic-gate
13510Sstevel@tonic-gate /*
13520Sstevel@tonic-gate * POSIX.2/XPG4 explicitly says no to this:
13530Sstevel@tonic-gate *
13540Sstevel@tonic-gate * in Solaris backslash followed by special character "." is
13550Sstevel@tonic-gate * special character "." itself; (so terminating input mode can be
13560Sstevel@tonic-gate * "\.\n").
13570Sstevel@tonic-gate *
13580Sstevel@tonic-gate * however, POSIX2/XPG4 says, input mode is terminated by
13590Sstevel@tonic-gate * entering line consisting of only 2 characters: ".\n"
13600Sstevel@tonic-gate *
13610Sstevel@tonic-gate * if (linebuf[0]=='\\' && linebuf[1]=='.' && linebuf[2]==0) {
13620Sstevel@tonic-gate * linebuf[0] = '.';
13630Sstevel@tonic-gate * linebuf[1] = 0;
13640Sstevel@tonic-gate * }
13650Sstevel@tonic-gate */
13660Sstevel@tonic-gate return (0);
13670Sstevel@tonic-gate }
13680Sstevel@tonic-gate
13690Sstevel@tonic-gate static int
getfile(void)13700Sstevel@tonic-gate getfile(void)
13710Sstevel@tonic-gate {
13720Sstevel@tonic-gate char c;
13730Sstevel@tonic-gate char *lp, *fp;
13740Sstevel@tonic-gate
13750Sstevel@tonic-gate lp = linebuf;
13760Sstevel@tonic-gate fp = nextip;
13770Sstevel@tonic-gate do {
13780Sstevel@tonic-gate if (--ninbuf < 0) {
13790Sstevel@tonic-gate if ((ninbuf = read(io, genbuf, LBSIZE)-1) < 0)
13800Sstevel@tonic-gate if (lp > linebuf) {
13810Sstevel@tonic-gate puts(gettext("'\\n' appended"));
13820Sstevel@tonic-gate *genbuf = '\n';
13830Sstevel@tonic-gate }
13840Sstevel@tonic-gate else
13850Sstevel@tonic-gate return (EOF);
13860Sstevel@tonic-gate if (crflag == -1) {
13870Sstevel@tonic-gate if (isencrypt(genbuf, ninbuf + 1))
13880Sstevel@tonic-gate crflag = 2;
13890Sstevel@tonic-gate else
13900Sstevel@tonic-gate crflag = -2;
13910Sstevel@tonic-gate }
13920Sstevel@tonic-gate fp = genbuf;
13930Sstevel@tonic-gate if (crflag > 0)
13940Sstevel@tonic-gate if (run_crypt(count, genbuf, ninbuf+1, perm) == -1)
13950Sstevel@tonic-gate (void) error(63);
13960Sstevel@tonic-gate }
13970Sstevel@tonic-gate if (lp >= &linebuf[LBSIZE]) {
13980Sstevel@tonic-gate lastc = '\n';
13990Sstevel@tonic-gate (void) error(27);
14000Sstevel@tonic-gate }
14010Sstevel@tonic-gate if ((*lp++ = c = *fp++) == 0) {
14020Sstevel@tonic-gate #ifdef NULLS
14030Sstevel@tonic-gate lp[-1] = '\\';
14040Sstevel@tonic-gate *lp++ = '0';
14050Sstevel@tonic-gate nulls++;
14060Sstevel@tonic-gate #else
14070Sstevel@tonic-gate lp--;
14080Sstevel@tonic-gate continue;
14090Sstevel@tonic-gate #endif
14100Sstevel@tonic-gate }
14110Sstevel@tonic-gate count++;
14120Sstevel@tonic-gate } while (c != '\n');
14130Sstevel@tonic-gate *--lp = 0;
14140Sstevel@tonic-gate nextip = fp;
14150Sstevel@tonic-gate if (fss.Ffill && fss.Flim && lenchk(linebuf, &fss) < 0) {
14160Sstevel@tonic-gate write(1, gettext("line too long: lno = "),
14170Sstevel@tonic-gate strlen(gettext("line too long: lno = ")));
14180Sstevel@tonic-gate ccount = count;
14190Sstevel@tonic-gate count = (++dot-zero)&077777;
14200Sstevel@tonic-gate dot--;
14210Sstevel@tonic-gate putd();
14220Sstevel@tonic-gate count = ccount;
14230Sstevel@tonic-gate putchr('\n');
14240Sstevel@tonic-gate }
14250Sstevel@tonic-gate return (0);
14260Sstevel@tonic-gate }
14270Sstevel@tonic-gate
14280Sstevel@tonic-gate static void
putfile(void)14290Sstevel@tonic-gate putfile(void)
14300Sstevel@tonic-gate {
14310Sstevel@tonic-gate int n;
14320Sstevel@tonic-gate LINE a1;
14330Sstevel@tonic-gate char *fp, *lp;
14340Sstevel@tonic-gate int nib;
14350Sstevel@tonic-gate
14360Sstevel@tonic-gate nib = LBSIZE;
14370Sstevel@tonic-gate fp = genbuf;
14380Sstevel@tonic-gate a1 = addr1;
14390Sstevel@tonic-gate do {
1440*13093SRoger.Faulkner@Oracle.COM lp = getaline(a1++->cur);
14410Sstevel@tonic-gate if (fss.Ffill && fss.Flim && lenchk(linebuf, &fss) < 0) {
14420Sstevel@tonic-gate write(1, gettext("line too long: lno = "),
14430Sstevel@tonic-gate strlen(gettext("line too long: lno = ")));
14440Sstevel@tonic-gate ccount = count;
14450Sstevel@tonic-gate count = (a1-zero-1)&077777;
14460Sstevel@tonic-gate putd();
14470Sstevel@tonic-gate count = ccount;
14480Sstevel@tonic-gate putchr('\n');
14490Sstevel@tonic-gate }
14500Sstevel@tonic-gate for (;;) {
14510Sstevel@tonic-gate if (--nib < 0) {
14520Sstevel@tonic-gate n = fp-genbuf;
14530Sstevel@tonic-gate if (kflag)
14540Sstevel@tonic-gate if (run_crypt(count-n, genbuf, n, perm) == -1)
14550Sstevel@tonic-gate (void) error(63);
14560Sstevel@tonic-gate if (write(io, genbuf, n) != n)
14570Sstevel@tonic-gate (void) error(29);
14580Sstevel@tonic-gate nib = LBSIZE - 1;
14590Sstevel@tonic-gate fp = genbuf;
14600Sstevel@tonic-gate }
14610Sstevel@tonic-gate if (dol->cur == 0L)break; /* Allow write of null file */
14620Sstevel@tonic-gate count++;
14630Sstevel@tonic-gate if ((*fp++ = *lp++) == 0) {
14640Sstevel@tonic-gate fp[-1] = '\n';
14650Sstevel@tonic-gate break;
14660Sstevel@tonic-gate }
14670Sstevel@tonic-gate }
14680Sstevel@tonic-gate } while (a1 <= addr2);
14690Sstevel@tonic-gate n = fp-genbuf;
14700Sstevel@tonic-gate if (kflag)
14710Sstevel@tonic-gate if (run_crypt(count-n, genbuf, n, perm) == -1)
14720Sstevel@tonic-gate (void) error(63);
14730Sstevel@tonic-gate if (write(io, genbuf, n) != n)
14740Sstevel@tonic-gate (void) error(29);
14750Sstevel@tonic-gate }
14760Sstevel@tonic-gate
14770Sstevel@tonic-gate static void
append(int (* f)(void),LINE a)14780Sstevel@tonic-gate append(int (*f)(void), LINE a)
14790Sstevel@tonic-gate {
14800Sstevel@tonic-gate LINE a1, a2, rdot;
14810Sstevel@tonic-gate long tl;
14820Sstevel@tonic-gate
14830Sstevel@tonic-gate nline = 0;
14840Sstevel@tonic-gate dot = a;
14850Sstevel@tonic-gate while ((*f)() == 0) {
14860Sstevel@tonic-gate if (dol >= endcore) {
14870Sstevel@tonic-gate if ((int)sbrk(512 * sizeof (struct lin)) == -1) {
14880Sstevel@tonic-gate lastc = '\n';
14890Sstevel@tonic-gate (void) error(30);
14900Sstevel@tonic-gate }
14910Sstevel@tonic-gate endcore += 512;
14920Sstevel@tonic-gate }
14930Sstevel@tonic-gate tl = putline();
14940Sstevel@tonic-gate nline++;
14950Sstevel@tonic-gate a1 = ++dol;
14960Sstevel@tonic-gate a2 = a1+1;
14970Sstevel@tonic-gate rdot = ++dot;
14980Sstevel@tonic-gate while (a1 > rdot)
14990Sstevel@tonic-gate (--a2)->cur = (--a1)->cur;
15000Sstevel@tonic-gate rdot->cur = tl;
15010Sstevel@tonic-gate }
15020Sstevel@tonic-gate }
15030Sstevel@tonic-gate
15040Sstevel@tonic-gate static void
unixcom(void)15050Sstevel@tonic-gate unixcom(void)
15060Sstevel@tonic-gate {
15070Sstevel@tonic-gate void (*savint)();
15080Sstevel@tonic-gate pid_t pid, rpid;
15090Sstevel@tonic-gate int retcode;
15100Sstevel@tonic-gate static char savcmd[LBSIZE]; /* last command */
15110Sstevel@tonic-gate char curcmd[LBSIZE]; /* current command */
15120Sstevel@tonic-gate char *psavcmd, *pcurcmd, *psavedfile;
15130Sstevel@tonic-gate int endflg = 1, shflg = 0;
15140Sstevel@tonic-gate wchar_t c;
15150Sstevel@tonic-gate int len;
15160Sstevel@tonic-gate
15170Sstevel@tonic-gate setnoaddr();
15180Sstevel@tonic-gate if (rflg)
15190Sstevel@tonic-gate (void) error(6);
15200Sstevel@tonic-gate pcurcmd = curcmd;
15210Sstevel@tonic-gate /* read command til end */
15220Sstevel@tonic-gate
15230Sstevel@tonic-gate /*
15240Sstevel@tonic-gate * a '!' found in beginning of command is replaced with the saved
15250Sstevel@tonic-gate * command. a '%' found in command is replaced with the current
15260Sstevel@tonic-gate * filename
15270Sstevel@tonic-gate */
15280Sstevel@tonic-gate
15290Sstevel@tonic-gate c = getchr();
15300Sstevel@tonic-gate if (c == '!') {
15310Sstevel@tonic-gate if (savcmd[0] == 0)
15320Sstevel@tonic-gate (void) error(56);
15330Sstevel@tonic-gate else {
15340Sstevel@tonic-gate psavcmd = savcmd;
15350Sstevel@tonic-gate while (*pcurcmd++ = *psavcmd++);
15360Sstevel@tonic-gate --pcurcmd;
15370Sstevel@tonic-gate shflg = 1;
15380Sstevel@tonic-gate }
15390Sstevel@tonic-gate } else
15400Sstevel@tonic-gate UNGETC(c); /* put c back */
15410Sstevel@tonic-gate while (endflg == 1) {
15420Sstevel@tonic-gate while ((c = get_wchr()) != '\n' && c != '%' && c != '\\') {
15430Sstevel@tonic-gate if ((len = wctomb(pcurcmd, c)) <= 0) {
15440Sstevel@tonic-gate *pcurcmd = (unsigned char)c;
15450Sstevel@tonic-gate len = 1;
15460Sstevel@tonic-gate }
15470Sstevel@tonic-gate pcurcmd += len;
15480Sstevel@tonic-gate }
15490Sstevel@tonic-gate
15500Sstevel@tonic-gate if (c == '%') {
15510Sstevel@tonic-gate if (savedfile[0] == 0)
15520Sstevel@tonic-gate (void) error(21);
15530Sstevel@tonic-gate else {
15540Sstevel@tonic-gate psavedfile = savedfile;
15550Sstevel@tonic-gate while (pcurcmd < curcmd + LBSIZE &&
15560Sstevel@tonic-gate (*pcurcmd++ = *psavedfile++));
15570Sstevel@tonic-gate --pcurcmd;
15580Sstevel@tonic-gate shflg = 1;
15590Sstevel@tonic-gate }
15600Sstevel@tonic-gate } else if (c == '\\') {
15610Sstevel@tonic-gate c = get_wchr();
15620Sstevel@tonic-gate if (c != '%')
15630Sstevel@tonic-gate *pcurcmd++ = '\\';
15640Sstevel@tonic-gate if ((len = wctomb(pcurcmd, c)) <= 0) {
15650Sstevel@tonic-gate *pcurcmd = (unsigned char)c;
15660Sstevel@tonic-gate len = 1;
15670Sstevel@tonic-gate }
15680Sstevel@tonic-gate pcurcmd += len;
15690Sstevel@tonic-gate }
15700Sstevel@tonic-gate else
15710Sstevel@tonic-gate /* end of command hit */
15720Sstevel@tonic-gate endflg = 0;
15730Sstevel@tonic-gate }
15740Sstevel@tonic-gate *pcurcmd++ = 0;
15750Sstevel@tonic-gate if (shflg == 1)
15760Sstevel@tonic-gate puts(curcmd);
15770Sstevel@tonic-gate /* save command */
15780Sstevel@tonic-gate strcpy(savcmd, curcmd);
15790Sstevel@tonic-gate
15800Sstevel@tonic-gate if ((pid = fork()) == 0) {
15810Sstevel@tonic-gate signal(SIGHUP, oldhup);
15820Sstevel@tonic-gate signal(SIGQUIT, oldquit);
15830Sstevel@tonic-gate close(tfile);
15840Sstevel@tonic-gate if (__xpg4 == 0) { /* not XPG4 */
15850Sstevel@tonic-gate shpath = "/usr/bin/sh";
15860Sstevel@tonic-gate } else {
15870Sstevel@tonic-gate /* XPG4 */
15880Sstevel@tonic-gate shpath = "/usr/xpg4/bin/sh";
15890Sstevel@tonic-gate }
15900Sstevel@tonic-gate execlp((const char *)shpath, "sh", "-c", curcmd, (char *)0);
15910Sstevel@tonic-gate exit(0100);
15920Sstevel@tonic-gate }
15930Sstevel@tonic-gate savint = signal(SIGINT, SIG_IGN);
15940Sstevel@tonic-gate while ((rpid = wait(&retcode)) != pid && rpid != (pid_t)-1);
15950Sstevel@tonic-gate signal(SIGINT, savint);
15960Sstevel@tonic-gate if (vflag) puts("!");
15970Sstevel@tonic-gate }
15980Sstevel@tonic-gate
15990Sstevel@tonic-gate static void
quit(int sig)16000Sstevel@tonic-gate quit(int sig)
16010Sstevel@tonic-gate {
16020Sstevel@tonic-gate if (vflag && fchange) {
16030Sstevel@tonic-gate fchange = 0;
16040Sstevel@tonic-gate if (flag28) {
16050Sstevel@tonic-gate flag28 = 0;
16060Sstevel@tonic-gate (void) error(62);
16070Sstevel@tonic-gate }
16080Sstevel@tonic-gate
16090Sstevel@tonic-gate /*
16100Sstevel@tonic-gate * For case where user reads in BOTH a good
16110Sstevel@tonic-gate * file & a bad file
16120Sstevel@tonic-gate */
16130Sstevel@tonic-gate (void) error(1);
16140Sstevel@tonic-gate }
16150Sstevel@tonic-gate unlink(tfname);
16160Sstevel@tonic-gate if (kflag)
16170Sstevel@tonic-gate crypt_close(perm);
16180Sstevel@tonic-gate if (xtflag)
16190Sstevel@tonic-gate crypt_close(tperm);
16200Sstevel@tonic-gate exit(errcnt? 2: 0);
16210Sstevel@tonic-gate }
16220Sstevel@tonic-gate
16230Sstevel@tonic-gate static void
delete(void)16240Sstevel@tonic-gate delete(void)
16250Sstevel@tonic-gate {
16260Sstevel@tonic-gate setdot();
16270Sstevel@tonic-gate newline();
16280Sstevel@tonic-gate nonzero();
16290Sstevel@tonic-gate if (!globflg) save();
16300Sstevel@tonic-gate rdelete(addr1, addr2);
16310Sstevel@tonic-gate }
16320Sstevel@tonic-gate
16330Sstevel@tonic-gate static void
rdelete(LINE ad1,LINE ad2)16340Sstevel@tonic-gate rdelete(LINE ad1, LINE ad2)
16350Sstevel@tonic-gate {
16360Sstevel@tonic-gate LINE a1, a2, a3;
16370Sstevel@tonic-gate
16380Sstevel@tonic-gate a1 = ad1;
16390Sstevel@tonic-gate a2 = ad2+1;
16400Sstevel@tonic-gate a3 = dol;
16410Sstevel@tonic-gate dol -= a2 - a1;
16420Sstevel@tonic-gate do
16430Sstevel@tonic-gate (a1++)->cur = (a2++)->cur;
16440Sstevel@tonic-gate while (a2 <= a3);
16450Sstevel@tonic-gate a1 = ad1;
16460Sstevel@tonic-gate if (a1 > dol)
16470Sstevel@tonic-gate a1 = dol;
16480Sstevel@tonic-gate dot = a1;
16490Sstevel@tonic-gate fchange = 1;
16500Sstevel@tonic-gate }
16510Sstevel@tonic-gate
16520Sstevel@tonic-gate static void
gdelete(void)16530Sstevel@tonic-gate gdelete(void)
16540Sstevel@tonic-gate {
16550Sstevel@tonic-gate LINE a1, a2, a3;
16560Sstevel@tonic-gate
16570Sstevel@tonic-gate a3 = dol;
16580Sstevel@tonic-gate for (a1 = zero+1; (a1->cur&01) == 0; a1++)
16590Sstevel@tonic-gate if (a1 >= a3)
16600Sstevel@tonic-gate return;
16610Sstevel@tonic-gate for (a2 = a1 + 1; a2 <= a3; ) {
16620Sstevel@tonic-gate if (a2->cur & 01) {
16630Sstevel@tonic-gate a2++;
16640Sstevel@tonic-gate dot = a1;
16650Sstevel@tonic-gate } else
16660Sstevel@tonic-gate (a1++)->cur = (a2++)->cur;
16670Sstevel@tonic-gate }
16680Sstevel@tonic-gate dol = a1-1;
16690Sstevel@tonic-gate if (dot > dol)
16700Sstevel@tonic-gate dot = dol;
16710Sstevel@tonic-gate fchange = 1;
16720Sstevel@tonic-gate }
16730Sstevel@tonic-gate
16740Sstevel@tonic-gate static char *
getaline(long tl)1675*13093SRoger.Faulkner@Oracle.COM getaline(long tl)
16760Sstevel@tonic-gate {
16770Sstevel@tonic-gate char *bp, *lp;
16780Sstevel@tonic-gate int nl;
16790Sstevel@tonic-gate
16800Sstevel@tonic-gate lp = linebuf;
16810Sstevel@tonic-gate bp = getblock(tl, READ);
16820Sstevel@tonic-gate nl = nleft;
16830Sstevel@tonic-gate tl &= ~0377;
16840Sstevel@tonic-gate while (*lp++ = *bp++)
16850Sstevel@tonic-gate if (--nl == 0) {
16860Sstevel@tonic-gate bp = getblock(tl += 0400, READ);
16870Sstevel@tonic-gate nl = nleft;
16880Sstevel@tonic-gate }
16890Sstevel@tonic-gate return (linebuf);
16900Sstevel@tonic-gate }
16910Sstevel@tonic-gate
16920Sstevel@tonic-gate static long
putline(void)16930Sstevel@tonic-gate putline(void)
16940Sstevel@tonic-gate {
16950Sstevel@tonic-gate char *bp, *lp;
16960Sstevel@tonic-gate int nl;
16970Sstevel@tonic-gate long tl;
16980Sstevel@tonic-gate
16990Sstevel@tonic-gate fchange = 1;
17000Sstevel@tonic-gate lp = linebuf;
17010Sstevel@tonic-gate tl = tline;
17020Sstevel@tonic-gate bp = getblock(tl, WRITE);
17030Sstevel@tonic-gate nl = nleft;
17040Sstevel@tonic-gate tl &= ~0377;
17050Sstevel@tonic-gate while (*bp = *lp++) {
17060Sstevel@tonic-gate if (*bp++ == '\n') {
17070Sstevel@tonic-gate *--bp = 0;
17080Sstevel@tonic-gate linebp = lp;
17090Sstevel@tonic-gate break;
17100Sstevel@tonic-gate }
17110Sstevel@tonic-gate if (--nl == 0) {
17120Sstevel@tonic-gate bp = getblock(tl += 0400, WRITE);
17130Sstevel@tonic-gate nl = nleft;
17140Sstevel@tonic-gate }
17150Sstevel@tonic-gate }
17160Sstevel@tonic-gate nl = tline;
17170Sstevel@tonic-gate tline += (((lp-linebuf)+03)>>1)&077776;
17180Sstevel@tonic-gate return (nl);
17190Sstevel@tonic-gate }
17200Sstevel@tonic-gate
17210Sstevel@tonic-gate static char *
getblock(long atl,long iof)17220Sstevel@tonic-gate getblock(long atl, long iof)
17230Sstevel@tonic-gate {
17240Sstevel@tonic-gate int bno, off;
17250Sstevel@tonic-gate char *p1, *p2;
17260Sstevel@tonic-gate int n;
17270Sstevel@tonic-gate
17280Sstevel@tonic-gate bno = atl >> 8;
17290Sstevel@tonic-gate off = (atl<<1)&0774;
17300Sstevel@tonic-gate
17310Sstevel@tonic-gate /* bno is limited to 16 bits */
17320Sstevel@tonic-gate if (bno >= 65535) {
17330Sstevel@tonic-gate lastc = '\n';
17340Sstevel@tonic-gate (void) error(31);
17350Sstevel@tonic-gate }
17360Sstevel@tonic-gate nleft = 512 - off;
17370Sstevel@tonic-gate if (bno == iblock) {
17380Sstevel@tonic-gate ichanged |= iof;
17390Sstevel@tonic-gate return (ibuff+off);
17400Sstevel@tonic-gate }
17410Sstevel@tonic-gate if (bno == oblock)
17420Sstevel@tonic-gate return (obuff+off);
17430Sstevel@tonic-gate if (iof == READ) {
17440Sstevel@tonic-gate if (ichanged) {
17450Sstevel@tonic-gate if (xtflag)
17460Sstevel@tonic-gate if (run_crypt(0L, ibuff, 512, tperm) == -1)
17470Sstevel@tonic-gate (void) error(63);
17480Sstevel@tonic-gate blkio(iblock, ibuff, write);
17490Sstevel@tonic-gate }
17500Sstevel@tonic-gate ichanged = 0;
17510Sstevel@tonic-gate iblock = bno;
17520Sstevel@tonic-gate blkio(bno, ibuff, read);
17530Sstevel@tonic-gate if (xtflag)
17540Sstevel@tonic-gate if (run_crypt(0L, ibuff, 512, tperm) == -1)
17550Sstevel@tonic-gate (void) error(63);
17560Sstevel@tonic-gate return (ibuff+off);
17570Sstevel@tonic-gate }
17580Sstevel@tonic-gate if (oblock >= 0) {
17590Sstevel@tonic-gate if (xtflag) {
17600Sstevel@tonic-gate p1 = obuff;
17610Sstevel@tonic-gate p2 = crbuf;
17620Sstevel@tonic-gate n = 512;
17630Sstevel@tonic-gate while (n--)
17640Sstevel@tonic-gate *p2++ = *p1++;
17650Sstevel@tonic-gate if (run_crypt(0L, crbuf, 512, tperm) == -1)
17660Sstevel@tonic-gate (void) error(63);
17670Sstevel@tonic-gate blkio(oblock, crbuf, write);
17680Sstevel@tonic-gate } else
17690Sstevel@tonic-gate blkio(oblock, obuff, write);
17700Sstevel@tonic-gate }
17710Sstevel@tonic-gate oblock = bno;
17720Sstevel@tonic-gate return (obuff+off);
17730Sstevel@tonic-gate }
17740Sstevel@tonic-gate
17750Sstevel@tonic-gate static void
blkio(int b,char * buf,ssize_t (* iofcn)())17760Sstevel@tonic-gate blkio(int b, char *buf, ssize_t (*iofcn)())
17770Sstevel@tonic-gate {
17780Sstevel@tonic-gate lseek(tfile, (long)b<<9, 0);
17790Sstevel@tonic-gate if ((*iofcn)(tfile, buf, 512) != 512) {
17800Sstevel@tonic-gate if (dol != zero)
17810Sstevel@tonic-gate (void) error(32); /* Bypass this if writing null file */
17820Sstevel@tonic-gate }
17830Sstevel@tonic-gate }
17840Sstevel@tonic-gate
17850Sstevel@tonic-gate static void
init(void)17860Sstevel@tonic-gate init(void)
17870Sstevel@tonic-gate {
17880Sstevel@tonic-gate long *markp;
17890Sstevel@tonic-gate mode_t omask;
17900Sstevel@tonic-gate
17910Sstevel@tonic-gate if (tfile != -1) {
17920Sstevel@tonic-gate (void) close(tfile);
17930Sstevel@tonic-gate (void) unlink(tfname);
17940Sstevel@tonic-gate }
17950Sstevel@tonic-gate
17960Sstevel@tonic-gate tline = 2;
17970Sstevel@tonic-gate for (markp = names; markp < &names[26]; )
17980Sstevel@tonic-gate *markp++ = 0L;
17990Sstevel@tonic-gate subnewa = 0L;
18000Sstevel@tonic-gate anymarks = 0;
18010Sstevel@tonic-gate iblock = -1;
18020Sstevel@tonic-gate oblock = -1;
18030Sstevel@tonic-gate ichanged = 0;
18040Sstevel@tonic-gate initflg = 1;
18050Sstevel@tonic-gate omask = umask(0);
18060Sstevel@tonic-gate
18070Sstevel@tonic-gate if ((tfile = open(tfname, O_CREAT|O_EXCL|O_RDWR,
18080Sstevel@tonic-gate S_IRUSR|S_IWUSR)) < 0) {
18090Sstevel@tonic-gate puts(gettext(msgtab[70]));
18100Sstevel@tonic-gate exit(2);
18110Sstevel@tonic-gate }
18120Sstevel@tonic-gate
18130Sstevel@tonic-gate umask(omask);
18140Sstevel@tonic-gate if (xflag) {
18150Sstevel@tonic-gate xtflag = 1;
18160Sstevel@tonic-gate if (tpermflag)
18170Sstevel@tonic-gate (void) crypt_close(tperm);
18180Sstevel@tonic-gate tpermflag = 1;
18190Sstevel@tonic-gate if (makekey(tperm)) {
18200Sstevel@tonic-gate xtflag = 0;
18210Sstevel@tonic-gate puts(gettext(msgtab[65]));
18220Sstevel@tonic-gate }
18230Sstevel@tonic-gate }
18240Sstevel@tonic-gate brk((char *)fendcore);
18250Sstevel@tonic-gate dot = zero = dol = savdot = savdol = fendcore;
18260Sstevel@tonic-gate flag28 = save28 = 0;
18270Sstevel@tonic-gate endcore = fendcore - sizeof (struct lin);
18280Sstevel@tonic-gate }
18290Sstevel@tonic-gate
18300Sstevel@tonic-gate static void
global(int k)18310Sstevel@tonic-gate global(int k)
18320Sstevel@tonic-gate {
18330Sstevel@tonic-gate char *gp;
18340Sstevel@tonic-gate wchar_t l;
18350Sstevel@tonic-gate char multic[MB_LEN_MAX];
18360Sstevel@tonic-gate wchar_t c;
18370Sstevel@tonic-gate LINE a1;
18380Sstevel@tonic-gate char globuf[LBSIZE];
18390Sstevel@tonic-gate int n;
18400Sstevel@tonic-gate int len;
18410Sstevel@tonic-gate
18420Sstevel@tonic-gate if (globp)
18430Sstevel@tonic-gate (void) error(33);
18440Sstevel@tonic-gate setall();
18450Sstevel@tonic-gate nonzero();
18460Sstevel@tonic-gate if ((n = _mbftowc(multic, &l, getchr, &peekc)) <= 0)
18470Sstevel@tonic-gate (void) error(67);
18480Sstevel@tonic-gate if (l == '\n')
18490Sstevel@tonic-gate (void) error(19);
18500Sstevel@tonic-gate save();
18510Sstevel@tonic-gate comple(l);
18520Sstevel@tonic-gate gp = globuf;
18530Sstevel@tonic-gate while ((c = get_wchr()) != '\n') {
18540Sstevel@tonic-gate if (c == EOF)
18550Sstevel@tonic-gate (void) error(19);
18560Sstevel@tonic-gate
18570Sstevel@tonic-gate /* '\\' has special meaning only if preceding a '\n' */
18580Sstevel@tonic-gate if (c == '\\') {
18590Sstevel@tonic-gate c = get_wchr();
18600Sstevel@tonic-gate if (c != '\n')
18610Sstevel@tonic-gate *gp++ = '\\';
18620Sstevel@tonic-gate }
18630Sstevel@tonic-gate if ((gp + (unsigned int)MB_CUR_MAX) >= &globuf[LBSIZE-1])
18640Sstevel@tonic-gate (void) error(34);
18650Sstevel@tonic-gate if ((len = wctomb(gp, c)) <= 0) {
18660Sstevel@tonic-gate *gp = (unsigned char)c;
18670Sstevel@tonic-gate len = 1;
18680Sstevel@tonic-gate }
18690Sstevel@tonic-gate gp += len;
18700Sstevel@tonic-gate }
18710Sstevel@tonic-gate if (gp == globuf)
18720Sstevel@tonic-gate *gp++ = 'p';
18730Sstevel@tonic-gate *gp++ = '\n';
18740Sstevel@tonic-gate *gp++ = 0;
18750Sstevel@tonic-gate for (a1 = zero; a1 <= dol; a1++) {
18760Sstevel@tonic-gate a1->cur &= ~01;
18770Sstevel@tonic-gate if (a1 >= addr1 && a1 <= addr2 && execute(0, a1) == k)
18780Sstevel@tonic-gate a1->cur |= 01;
18790Sstevel@tonic-gate }
18800Sstevel@tonic-gate /*
18810Sstevel@tonic-gate * Special case: g/.../d (avoid n^2 algorithm)
18820Sstevel@tonic-gate */
18830Sstevel@tonic-gate if (globuf[0] == 'd' && globuf[1] == '\n' && globuf[2] == '\0') {
18840Sstevel@tonic-gate gdelete();
18850Sstevel@tonic-gate return;
18860Sstevel@tonic-gate }
18870Sstevel@tonic-gate for (a1 = zero; a1 <= dol; a1++) {
18880Sstevel@tonic-gate if (a1->cur & 01) {
18890Sstevel@tonic-gate a1->cur &= ~01;
18900Sstevel@tonic-gate dot = a1;
18910Sstevel@tonic-gate globp = globuf;
18920Sstevel@tonic-gate globflg = 1;
18930Sstevel@tonic-gate commands();
18940Sstevel@tonic-gate globflg = 0;
18950Sstevel@tonic-gate a1 = zero;
18960Sstevel@tonic-gate }
18970Sstevel@tonic-gate }
18980Sstevel@tonic-gate }
18990Sstevel@tonic-gate
19000Sstevel@tonic-gate static void
join(void)19010Sstevel@tonic-gate join(void)
19020Sstevel@tonic-gate {
19030Sstevel@tonic-gate char *gp, *lp;
19040Sstevel@tonic-gate LINE a1;
19050Sstevel@tonic-gate
19060Sstevel@tonic-gate if (addr1 == addr2)
19070Sstevel@tonic-gate return;
19080Sstevel@tonic-gate gp = genbuf;
19090Sstevel@tonic-gate for (a1 = addr1; a1 <= addr2; a1++) {
1910*13093SRoger.Faulkner@Oracle.COM lp = getaline(a1->cur);
19110Sstevel@tonic-gate while (*gp = *lp++)
19120Sstevel@tonic-gate if (gp++ > &genbuf[LBSIZE-1])
19130Sstevel@tonic-gate (void) error(27);
19140Sstevel@tonic-gate }
19150Sstevel@tonic-gate lp = linebuf;
19160Sstevel@tonic-gate gp = genbuf;
19170Sstevel@tonic-gate while (*lp++ = *gp++);
19180Sstevel@tonic-gate addr1->cur = putline();
19190Sstevel@tonic-gate if (addr1 < addr2)
19200Sstevel@tonic-gate rdelete(addr1+1, addr2);
19210Sstevel@tonic-gate dot = addr1;
19220Sstevel@tonic-gate }
19230Sstevel@tonic-gate
19240Sstevel@tonic-gate static void
substitute(int inglob)19250Sstevel@tonic-gate substitute(int inglob)
19260Sstevel@tonic-gate {
19270Sstevel@tonic-gate int nl;
19280Sstevel@tonic-gate LINE a1;
19290Sstevel@tonic-gate long *markp;
19300Sstevel@tonic-gate int ingsav; /* For saving arg. */
19310Sstevel@tonic-gate
19320Sstevel@tonic-gate ingsav = inglob;
19330Sstevel@tonic-gate ocerr2 = 0;
19340Sstevel@tonic-gate gsubf = compsub();
19350Sstevel@tonic-gate for (a1 = addr1; a1 <= addr2; a1++) {
19360Sstevel@tonic-gate if (execute(0, a1) == 0)
19370Sstevel@tonic-gate continue;
19380Sstevel@tonic-gate numpass = 0;
19390Sstevel@tonic-gate ocerr1 = 0;
19400Sstevel@tonic-gate inglob |= 01;
19410Sstevel@tonic-gate dosub();
19420Sstevel@tonic-gate if (gsubf) {
19430Sstevel@tonic-gate while (*loc2) {
19440Sstevel@tonic-gate if (execute(1, (LINE)0) == 0)
19450Sstevel@tonic-gate break;
19460Sstevel@tonic-gate dosub();
19470Sstevel@tonic-gate }
19480Sstevel@tonic-gate }
19490Sstevel@tonic-gate if (ocerr1 == 0)continue; /* Don't put out-not changed. */
19500Sstevel@tonic-gate subnewa = putline();
19510Sstevel@tonic-gate a1->cur &= ~01;
19520Sstevel@tonic-gate if (anymarks) {
19530Sstevel@tonic-gate for (markp = names; markp < &names[26]; markp++)
19540Sstevel@tonic-gate if (*markp == a1->cur)
19550Sstevel@tonic-gate *markp = subnewa;
19560Sstevel@tonic-gate }
19570Sstevel@tonic-gate a1->cur = subnewa;
19580Sstevel@tonic-gate append(getsub, a1);
19590Sstevel@tonic-gate nl = nline;
19600Sstevel@tonic-gate a1 += nl;
19610Sstevel@tonic-gate addr2 += nl;
19620Sstevel@tonic-gate }
19630Sstevel@tonic-gate if (ingsav)
19640Sstevel@tonic-gate return; /* Was in global-no error msg allowed. */
19650Sstevel@tonic-gate if (inglob == 0)
19660Sstevel@tonic-gate (void) error(35); /* Not in global, but not found. */
19670Sstevel@tonic-gate if (ocerr2 == 0)
19680Sstevel@tonic-gate (void) error(35); /* RE found, but occurrence match failed. */
19690Sstevel@tonic-gate }
19700Sstevel@tonic-gate
19710Sstevel@tonic-gate static int
compsub(void)19720Sstevel@tonic-gate compsub(void)
19730Sstevel@tonic-gate {
19740Sstevel@tonic-gate int c;
19750Sstevel@tonic-gate wchar_t seof;
19760Sstevel@tonic-gate char *p;
19770Sstevel@tonic-gate char multic[MB_LEN_MAX];
19780Sstevel@tonic-gate int n;
19790Sstevel@tonic-gate static char remem[RHSIZE];
19800Sstevel@tonic-gate static int remflg = -1;
19810Sstevel@tonic-gate int i;
19820Sstevel@tonic-gate
19830Sstevel@tonic-gate if ((n = _mbftowc(multic, &seof, getchr, &peekc)) <= 0)
19840Sstevel@tonic-gate (void) error(67);
19850Sstevel@tonic-gate if (seof == '\n' || seof == ' ')
19860Sstevel@tonic-gate (void) error(36);
19870Sstevel@tonic-gate comple(seof);
19880Sstevel@tonic-gate p = rhsbuf;
19890Sstevel@tonic-gate for (;;) {
19900Sstevel@tonic-gate wchar_t cl;
19910Sstevel@tonic-gate if ((n = _mbftowc(multic, &cl, getchr, &peekc)) <= 0)
19920Sstevel@tonic-gate (void) error(67);
19930Sstevel@tonic-gate if (cl == '\\') {
19940Sstevel@tonic-gate *p++ = '\\';
19950Sstevel@tonic-gate if (p >= &rhsbuf[RHSIZE])
19960Sstevel@tonic-gate (void) error(38);
19970Sstevel@tonic-gate if ((n = _mbftowc(multic, &cl, getchr, &peekc)) <= 0)
19980Sstevel@tonic-gate (void) error(67);
19990Sstevel@tonic-gate } else if (cl == '\n') {
20000Sstevel@tonic-gate if (nodelim == 1) {
20010Sstevel@tonic-gate nodelim = 0;
20020Sstevel@tonic-gate (void) error(36);
20030Sstevel@tonic-gate }
20040Sstevel@tonic-gate if (!(globp && globp[0])) {
20050Sstevel@tonic-gate UNGETC('\n');
20060Sstevel@tonic-gate pflag++;
20070Sstevel@tonic-gate break;
20080Sstevel@tonic-gate }
20090Sstevel@tonic-gate } else if (cl == seof)
20100Sstevel@tonic-gate break;
20110Sstevel@tonic-gate if (p + n > &rhsbuf[RHSIZE])
20120Sstevel@tonic-gate (void) error(38);
20130Sstevel@tonic-gate (void) strncpy(p, multic, n);
20140Sstevel@tonic-gate p += n;
20150Sstevel@tonic-gate }
20160Sstevel@tonic-gate *p++ = 0;
20170Sstevel@tonic-gate if (rhsbuf[0] == '%' && rhsbuf[1] == 0)
20180Sstevel@tonic-gate /*
20190Sstevel@tonic-gate * If there isn't a remembered string, it is an error;
20200Sstevel@tonic-gate * otherwise the right hand side is the previous right
20210Sstevel@tonic-gate * hand side.
20220Sstevel@tonic-gate */
20230Sstevel@tonic-gate
20240Sstevel@tonic-gate if (remflg == -1)
20250Sstevel@tonic-gate (void) error(55);
20260Sstevel@tonic-gate else
20270Sstevel@tonic-gate strcpy(rhsbuf, remem);
20280Sstevel@tonic-gate else {
20290Sstevel@tonic-gate strcpy(remem, rhsbuf);
20300Sstevel@tonic-gate remflg = 0;
20310Sstevel@tonic-gate }
20320Sstevel@tonic-gate c = 0;
20330Sstevel@tonic-gate peekc = getchr(); /* Gets char after third delimiter. */
20340Sstevel@tonic-gate if (peekc == 'g') {
20350Sstevel@tonic-gate c = LBSIZE; peekc = 0;
20360Sstevel@tonic-gate }
20370Sstevel@tonic-gate if (peekc >= '1' && peekc <= '9') {
20380Sstevel@tonic-gate c = peekc-'0';
20390Sstevel@tonic-gate peekc = 0; /* Allows getchr() to get next char. */
20400Sstevel@tonic-gate while (1) {
20410Sstevel@tonic-gate i = getchr();
20420Sstevel@tonic-gate if (i < '0' || i > '9')
20430Sstevel@tonic-gate break;
20440Sstevel@tonic-gate c = c*10 + i-'0';
20450Sstevel@tonic-gate if (c > LBSIZE-1)
20460Sstevel@tonic-gate (void) error(20); /* "Illegal suffix" */
20470Sstevel@tonic-gate }
20480Sstevel@tonic-gate peekc = i; /* Effectively an unget. */
20490Sstevel@tonic-gate }
20500Sstevel@tonic-gate newline();
20510Sstevel@tonic-gate return (c);
20520Sstevel@tonic-gate
20530Sstevel@tonic-gate /*
20540Sstevel@tonic-gate * Returns occurrence value. 0 & 1 both do first occurrence
20550Sstevel@tonic-gate * only: c = 0 if ordinary substitute; c = 1
20560Sstevel@tonic-gate * if use 1 in global sub(s/a/b/1). 0 in global form is illegal.
20570Sstevel@tonic-gate */
20580Sstevel@tonic-gate }
20590Sstevel@tonic-gate
20600Sstevel@tonic-gate static int
getsub(void)20610Sstevel@tonic-gate getsub(void)
20620Sstevel@tonic-gate {
20630Sstevel@tonic-gate char *p1, *p2;
20640Sstevel@tonic-gate
20650Sstevel@tonic-gate p1 = linebuf;
20660Sstevel@tonic-gate if ((p2 = linebp) == 0)
20670Sstevel@tonic-gate return (EOF);
20680Sstevel@tonic-gate while (*p1++ = *p2++);
20690Sstevel@tonic-gate linebp = 0;
20700Sstevel@tonic-gate return (0);
20710Sstevel@tonic-gate }
20720Sstevel@tonic-gate
20730Sstevel@tonic-gate static void
dosub(void)20740Sstevel@tonic-gate dosub(void)
20750Sstevel@tonic-gate {
20760Sstevel@tonic-gate char *lp, *sp, *rp;
20770Sstevel@tonic-gate int c;
20780Sstevel@tonic-gate
20790Sstevel@tonic-gate if (gsubf > 0 && gsubf < LBSIZE) {
20800Sstevel@tonic-gate numpass++;
20810Sstevel@tonic-gate if (gsubf != numpass)
20820Sstevel@tonic-gate return;
20830Sstevel@tonic-gate }
20840Sstevel@tonic-gate ocerr1++;
20850Sstevel@tonic-gate ocerr2++;
20860Sstevel@tonic-gate lp = linebuf;
20870Sstevel@tonic-gate sp = genbuf;
20880Sstevel@tonic-gate rp = rhsbuf;
20890Sstevel@tonic-gate while (lp < loc1)
20900Sstevel@tonic-gate *sp++ = *lp++;
20910Sstevel@tonic-gate while (c = *rp++) {
20920Sstevel@tonic-gate if (c == '&') {
20930Sstevel@tonic-gate sp = place(sp, loc1, loc2);
20940Sstevel@tonic-gate continue;
20950Sstevel@tonic-gate } else if (c == '\\') {
20960Sstevel@tonic-gate c = *rp++;
20970Sstevel@tonic-gate if (c >= '1' && c < nbra + '1') {
20980Sstevel@tonic-gate sp = place(sp, braslist[c-'1'], braelist[c-'1']);
20990Sstevel@tonic-gate continue;
21000Sstevel@tonic-gate }
21010Sstevel@tonic-gate }
21020Sstevel@tonic-gate *sp++ = c;
21030Sstevel@tonic-gate if (sp >= &genbuf[LBSIZE])
21040Sstevel@tonic-gate (void) error(27);
21050Sstevel@tonic-gate }
21060Sstevel@tonic-gate lp = loc2;
21070Sstevel@tonic-gate loc2 = sp - genbuf + linebuf;
21080Sstevel@tonic-gate while (*sp++ = *lp++)
21090Sstevel@tonic-gate if (sp >= &genbuf[LBSIZE])
21100Sstevel@tonic-gate (void) error(27);
21110Sstevel@tonic-gate lp = linebuf;
21120Sstevel@tonic-gate sp = genbuf;
21130Sstevel@tonic-gate while (*lp++ = *sp++);
21140Sstevel@tonic-gate }
21150Sstevel@tonic-gate
21160Sstevel@tonic-gate static char *
place(char * sp,char * l1,char * l2)21170Sstevel@tonic-gate place(char *sp, char *l1, char *l2)
21180Sstevel@tonic-gate {
21190Sstevel@tonic-gate
21200Sstevel@tonic-gate while (l1 < l2) {
21210Sstevel@tonic-gate *sp++ = *l1++;
21220Sstevel@tonic-gate if (sp >= &genbuf[LBSIZE])
21230Sstevel@tonic-gate (void) error(27);
21240Sstevel@tonic-gate }
21250Sstevel@tonic-gate return (sp);
21260Sstevel@tonic-gate }
21270Sstevel@tonic-gate
21280Sstevel@tonic-gate static void
comple(wchar_t seof)21290Sstevel@tonic-gate comple(wchar_t seof)
21300Sstevel@tonic-gate {
21310Sstevel@tonic-gate int cclass = 0;
21320Sstevel@tonic-gate wchar_t c;
21330Sstevel@tonic-gate int n;
21340Sstevel@tonic-gate char *cp = genbuf;
21350Sstevel@tonic-gate char multic[MB_LEN_MAX];
21360Sstevel@tonic-gate
21370Sstevel@tonic-gate while (1) {
21380Sstevel@tonic-gate if ((n = _mbftowc(multic, &c, getchr, &peekc)) < 0)
21390Sstevel@tonic-gate error1(67);
21400Sstevel@tonic-gate if (n == 0 || c == '\n') {
21410Sstevel@tonic-gate if (cclass)
21420Sstevel@tonic-gate error1(49);
21430Sstevel@tonic-gate else
21440Sstevel@tonic-gate break;
21450Sstevel@tonic-gate }
21460Sstevel@tonic-gate if (c == seof && !cclass)
21470Sstevel@tonic-gate break;
21480Sstevel@tonic-gate if (cclass && c == ']') {
21490Sstevel@tonic-gate cclass = 0;
21500Sstevel@tonic-gate if (cp > &genbuf[LBSIZE-1])
21510Sstevel@tonic-gate error1(50);
21520Sstevel@tonic-gate *cp++ = ']';
21530Sstevel@tonic-gate continue;
21540Sstevel@tonic-gate }
21550Sstevel@tonic-gate if (c == '[' && !cclass) {
21560Sstevel@tonic-gate cclass = 1;
21570Sstevel@tonic-gate if (cp > &genbuf[LBSIZE-1])
21580Sstevel@tonic-gate error1(50);
21590Sstevel@tonic-gate *cp++ = '[';
21600Sstevel@tonic-gate if ((n = _mbftowc(multic, &c, getchr, &peekc)) < 0)
21610Sstevel@tonic-gate error1(67);
21620Sstevel@tonic-gate if (n == 0 || c == '\n')
21630Sstevel@tonic-gate error1(49);
21640Sstevel@tonic-gate }
21650Sstevel@tonic-gate if (c == '\\' && !cclass) {
21660Sstevel@tonic-gate if (cp > &genbuf[LBSIZE-1])
21670Sstevel@tonic-gate error1(50);
21680Sstevel@tonic-gate *cp++ = '\\';
21690Sstevel@tonic-gate if ((n = _mbftowc(multic, &c, getchr, &peekc)) < 0)
21700Sstevel@tonic-gate error1(67);
21710Sstevel@tonic-gate if (n == 0 || c == '\n')
21720Sstevel@tonic-gate error1(36);
21730Sstevel@tonic-gate }
21740Sstevel@tonic-gate if (cp + n > &genbuf[LBSIZE-1])
21750Sstevel@tonic-gate error1(50);
21760Sstevel@tonic-gate (void) strncpy(cp, multic, n);
21770Sstevel@tonic-gate cp += n;
21780Sstevel@tonic-gate }
21790Sstevel@tonic-gate *cp = '\0';
21800Sstevel@tonic-gate if (n != 0 && c == '\n')
21810Sstevel@tonic-gate UNGETC('\n');
21820Sstevel@tonic-gate if (n == 0 || c == '\n')
21830Sstevel@tonic-gate nodelim = 1;
21840Sstevel@tonic-gate
21850Sstevel@tonic-gate /*
21860Sstevel@tonic-gate * NULL RE: do not compile a null regular expression; but process
21870Sstevel@tonic-gate * input with last regular expression encountered
21880Sstevel@tonic-gate */
21890Sstevel@tonic-gate
21900Sstevel@tonic-gate if (genbuf[0] != '\0') {
21910Sstevel@tonic-gate if (expbuf)
21920Sstevel@tonic-gate free(expbuf);
21930Sstevel@tonic-gate expbuf = compile(genbuf, (char *)0, (char *)0);
21940Sstevel@tonic-gate }
21950Sstevel@tonic-gate if (regerrno)
21960Sstevel@tonic-gate error1(regerrno);
21970Sstevel@tonic-gate }
21980Sstevel@tonic-gate
21990Sstevel@tonic-gate static void
move(int cflag)22000Sstevel@tonic-gate move(int cflag)
22010Sstevel@tonic-gate {
22020Sstevel@tonic-gate LINE adt, ad1, ad2;
22030Sstevel@tonic-gate
22040Sstevel@tonic-gate setdot();
22050Sstevel@tonic-gate nonzero();
22060Sstevel@tonic-gate if ((adt = address()) == 0)
22070Sstevel@tonic-gate (void) error(39);
22080Sstevel@tonic-gate newline();
22090Sstevel@tonic-gate if (!globflg) save();
22100Sstevel@tonic-gate if (cflag) {
22110Sstevel@tonic-gate ad1 = dol;
22120Sstevel@tonic-gate append(getcopy, ad1++);
22130Sstevel@tonic-gate ad2 = dol;
22140Sstevel@tonic-gate } else {
22150Sstevel@tonic-gate ad2 = addr2;
22160Sstevel@tonic-gate for (ad1 = addr1; ad1 <= ad2; )
22170Sstevel@tonic-gate (ad1++)->cur &= ~01;
22180Sstevel@tonic-gate ad1 = addr1;
22190Sstevel@tonic-gate }
22200Sstevel@tonic-gate ad2++;
22210Sstevel@tonic-gate if (adt < ad1) {
22220Sstevel@tonic-gate dot = adt + (ad2-ad1);
22230Sstevel@tonic-gate if ((++adt) == ad1)
22240Sstevel@tonic-gate return;
22250Sstevel@tonic-gate reverse(adt, ad1);
22260Sstevel@tonic-gate reverse(ad1, ad2);
22270Sstevel@tonic-gate reverse(adt, ad2);
22280Sstevel@tonic-gate } else if (adt >= ad2) {
22290Sstevel@tonic-gate dot = adt++;
22300Sstevel@tonic-gate reverse(ad1, ad2);
22310Sstevel@tonic-gate reverse(ad2, adt);
22320Sstevel@tonic-gate reverse(ad1, adt);
22330Sstevel@tonic-gate } else
22340Sstevel@tonic-gate (void) error(39);
22350Sstevel@tonic-gate fchange = 1;
22360Sstevel@tonic-gate }
22370Sstevel@tonic-gate
22380Sstevel@tonic-gate static void
reverse(LINE a1,LINE a2)22390Sstevel@tonic-gate reverse(LINE a1, LINE a2)
22400Sstevel@tonic-gate {
22410Sstevel@tonic-gate long t;
22420Sstevel@tonic-gate
22430Sstevel@tonic-gate for (;;) {
22440Sstevel@tonic-gate t = (--a2)->cur;
22450Sstevel@tonic-gate if (a2 <= a1)
22460Sstevel@tonic-gate return;
22470Sstevel@tonic-gate a2->cur = a1->cur;
22480Sstevel@tonic-gate (a1++)->cur = t;
22490Sstevel@tonic-gate }
22500Sstevel@tonic-gate }
22510Sstevel@tonic-gate
22520Sstevel@tonic-gate static int
getcopy(void)22530Sstevel@tonic-gate getcopy(void)
22540Sstevel@tonic-gate {
22550Sstevel@tonic-gate
22560Sstevel@tonic-gate if (addr1 > addr2)
22570Sstevel@tonic-gate return (EOF);
2258*13093SRoger.Faulkner@Oracle.COM (void) getaline((addr1++)->cur);
22590Sstevel@tonic-gate return (0);
22600Sstevel@tonic-gate }
22610Sstevel@tonic-gate
22620Sstevel@tonic-gate
22630Sstevel@tonic-gate /*
22640Sstevel@tonic-gate * Handles error code returned from comple() routine: regular expression
22650Sstevel@tonic-gate * compile and match routines
22660Sstevel@tonic-gate */
22670Sstevel@tonic-gate
22680Sstevel@tonic-gate static void
error1(int code)22690Sstevel@tonic-gate error1(int code)
22700Sstevel@tonic-gate {
22710Sstevel@tonic-gate nbra = 0;
22720Sstevel@tonic-gate (void) error(code);
22730Sstevel@tonic-gate }
22740Sstevel@tonic-gate
22750Sstevel@tonic-gate
22760Sstevel@tonic-gate static int
execute(int gf,LINE addr)22770Sstevel@tonic-gate execute(int gf, LINE addr)
22780Sstevel@tonic-gate {
22790Sstevel@tonic-gate char *p1;
22800Sstevel@tonic-gate int c;
22810Sstevel@tonic-gate
22820Sstevel@tonic-gate for (c = 0; c < nbra; c++) {
22830Sstevel@tonic-gate braslist[c] = 0;
22840Sstevel@tonic-gate braelist[c] = 0;
22850Sstevel@tonic-gate }
22860Sstevel@tonic-gate if (gf)
22870Sstevel@tonic-gate locs = p1 = loc2;
22880Sstevel@tonic-gate else {
22890Sstevel@tonic-gate if (addr == zero)
22900Sstevel@tonic-gate return (0);
2291*13093SRoger.Faulkner@Oracle.COM p1 = getaline(addr->cur);
22920Sstevel@tonic-gate locs = 0;
22930Sstevel@tonic-gate }
22940Sstevel@tonic-gate return (step(p1, expbuf));
22950Sstevel@tonic-gate }
22960Sstevel@tonic-gate
22970Sstevel@tonic-gate
22980Sstevel@tonic-gate static void
putd()22990Sstevel@tonic-gate putd()
23000Sstevel@tonic-gate {
23010Sstevel@tonic-gate int r;
23020Sstevel@tonic-gate
23030Sstevel@tonic-gate r = (int)(count%10);
23040Sstevel@tonic-gate count /= 10;
23050Sstevel@tonic-gate if (count)
23060Sstevel@tonic-gate putd();
23070Sstevel@tonic-gate putchr(r + '0');
23080Sstevel@tonic-gate }
23090Sstevel@tonic-gate
23100Sstevel@tonic-gate
23110Sstevel@tonic-gate int
puts(const char * sp)23120Sstevel@tonic-gate puts(const char *sp)
23130Sstevel@tonic-gate {
23140Sstevel@tonic-gate int n;
23150Sstevel@tonic-gate wchar_t c;
23160Sstevel@tonic-gate int sz, i;
23170Sstevel@tonic-gate if (fss.Ffill && (listf == 0)) {
23180Sstevel@tonic-gate
23190Sstevel@tonic-gate /* deliberate attempt to remove constness of sp because */
23200Sstevel@tonic-gate /* it needs to be expanded */
23210Sstevel@tonic-gate
23220Sstevel@tonic-gate if ((i = expnd((char *)sp, funny, &sz, &fss)) == -1) {
23230Sstevel@tonic-gate write(1, funny, fss.Flim & 0377);
23240Sstevel@tonic-gate putchr('\n');
23250Sstevel@tonic-gate write(1, gettext("too long"),
23260Sstevel@tonic-gate strlen(gettext("too long")));
23270Sstevel@tonic-gate }
23280Sstevel@tonic-gate else
23290Sstevel@tonic-gate write(1, funny, sz);
23300Sstevel@tonic-gate putchr('\n');
23310Sstevel@tonic-gate if (i == -2)
23320Sstevel@tonic-gate write(1, gettext("tab count\n"),
23330Sstevel@tonic-gate strlen(gettext("tab count\n")));
23340Sstevel@tonic-gate return (0);
23350Sstevel@tonic-gate }
23360Sstevel@tonic-gate col = 0;
23370Sstevel@tonic-gate while (*sp) {
23380Sstevel@tonic-gate n = mbtowc(&c, sp, MB_LEN_MAX);
23390Sstevel@tonic-gate if (listf) {
23400Sstevel@tonic-gate if (n < 1)
23410Sstevel@tonic-gate (void) error(28);
23420Sstevel@tonic-gate else if (n == 1)
23430Sstevel@tonic-gate putchr((unsigned char)*sp++);
23440Sstevel@tonic-gate else {
23450Sstevel@tonic-gate sp += n;
23460Sstevel@tonic-gate putwchr(c);
23470Sstevel@tonic-gate }
23480Sstevel@tonic-gate } else {
23490Sstevel@tonic-gate putchr((unsigned char)*sp++);
23500Sstevel@tonic-gate }
23510Sstevel@tonic-gate }
23520Sstevel@tonic-gate #ifndef XPG6
23530Sstevel@tonic-gate if (listf)
23540Sstevel@tonic-gate putchr('$'); /* end of line is marked with a $ */
23550Sstevel@tonic-gate #else
23560Sstevel@tonic-gate if (listf) {
23570Sstevel@tonic-gate /* xpg6 - ensure that the end of line $ is not preceeded with a "\" */
23580Sstevel@tonic-gate /* by doing a putchr() with listf=0, thereby avoiding the $ case */
23590Sstevel@tonic-gate /* statement in putchr() */
23600Sstevel@tonic-gate listf = 0;
23610Sstevel@tonic-gate putchr('$'); /* end of line is marked with a $ */
23620Sstevel@tonic-gate listf++;
23630Sstevel@tonic-gate }
23640Sstevel@tonic-gate #endif
23650Sstevel@tonic-gate putchr('\n');
23660Sstevel@tonic-gate return (1);
23670Sstevel@tonic-gate }
23680Sstevel@tonic-gate
23690Sstevel@tonic-gate
23700Sstevel@tonic-gate static void
putwchr(wchar_t ac)23710Sstevel@tonic-gate putwchr(wchar_t ac)
23720Sstevel@tonic-gate {
23730Sstevel@tonic-gate char buf[MB_LEN_MAX], *p;
23740Sstevel@tonic-gate char *lp;
23750Sstevel@tonic-gate wchar_t c;
23760Sstevel@tonic-gate short len;
23770Sstevel@tonic-gate
23780Sstevel@tonic-gate lp = linp;
23790Sstevel@tonic-gate c = ac;
23800Sstevel@tonic-gate if (listf) {
23810Sstevel@tonic-gate if (!iswprint(c)) {
23820Sstevel@tonic-gate p = &buf[0];
23830Sstevel@tonic-gate if ((len = wctomb(p, c)) <= 0) {
23840Sstevel@tonic-gate *p = (unsigned char)c;
23850Sstevel@tonic-gate len = 1;
23860Sstevel@tonic-gate };
23870Sstevel@tonic-gate while (len--) {
23880Sstevel@tonic-gate if (col + 4 >= 72) {
23890Sstevel@tonic-gate col = 0;
23900Sstevel@tonic-gate *lp++ = '\\';
23910Sstevel@tonic-gate *lp++ = '\n';
23920Sstevel@tonic-gate }
23930Sstevel@tonic-gate (void) sprintf(lp, "\\%03o",
23940Sstevel@tonic-gate *(unsigned char *)p++);
23950Sstevel@tonic-gate col += 4;
23960Sstevel@tonic-gate lp += 4;
23970Sstevel@tonic-gate }
23980Sstevel@tonic-gate } else {
23990Sstevel@tonic-gate if ((len = wcwidth(c)) <= 0)
24000Sstevel@tonic-gate len = 0;
24010Sstevel@tonic-gate if (col + len >= 72) {
24020Sstevel@tonic-gate col = 0;
24030Sstevel@tonic-gate *lp++ = '\\';
24040Sstevel@tonic-gate *lp++ = '\n';
24050Sstevel@tonic-gate }
24060Sstevel@tonic-gate col += len;
24070Sstevel@tonic-gate if ((len = wctomb(lp, c)) <= 0) {
24080Sstevel@tonic-gate *lp = (unsigned char)c;
24090Sstevel@tonic-gate len = 1;
24100Sstevel@tonic-gate }
24110Sstevel@tonic-gate lp += len;
24120Sstevel@tonic-gate }
24130Sstevel@tonic-gate } else {
24140Sstevel@tonic-gate if ((len = wctomb(lp, c)) <= 0) {
24150Sstevel@tonic-gate *lp = (unsigned char)c;
24160Sstevel@tonic-gate len = 1;
24170Sstevel@tonic-gate }
24180Sstevel@tonic-gate lp += len;
24190Sstevel@tonic-gate }
24200Sstevel@tonic-gate if (c == '\n' || lp >= &line[64]) {
24210Sstevel@tonic-gate linp = line;
24220Sstevel@tonic-gate len = lp - line;
24230Sstevel@tonic-gate write(1, line, len);
24240Sstevel@tonic-gate return;
24250Sstevel@tonic-gate }
24260Sstevel@tonic-gate linp = lp;
24270Sstevel@tonic-gate }
24280Sstevel@tonic-gate
24290Sstevel@tonic-gate
24300Sstevel@tonic-gate static void
putchr(unsigned char c)24310Sstevel@tonic-gate putchr(unsigned char c)
24320Sstevel@tonic-gate {
24330Sstevel@tonic-gate char *lp;
24340Sstevel@tonic-gate int len;
24350Sstevel@tonic-gate
24360Sstevel@tonic-gate lp = linp;
24370Sstevel@tonic-gate if (listf && c != '\n') {
24380Sstevel@tonic-gate switch (c) {
24390Sstevel@tonic-gate case '\\' :
24400Sstevel@tonic-gate *lp++ = '\\';
24410Sstevel@tonic-gate *lp++ = '\\';
24420Sstevel@tonic-gate col += 2;
24430Sstevel@tonic-gate break;
24440Sstevel@tonic-gate case '\007' :
24450Sstevel@tonic-gate *lp++ = '\\';
24460Sstevel@tonic-gate *lp++ = 'a';
24470Sstevel@tonic-gate col += 2;
24480Sstevel@tonic-gate break;
24490Sstevel@tonic-gate case '\b' :
24500Sstevel@tonic-gate *lp++ = '\\';
24510Sstevel@tonic-gate *lp++ = 'b';
24520Sstevel@tonic-gate col += 2;
24530Sstevel@tonic-gate break;
24540Sstevel@tonic-gate case '\f' :
24550Sstevel@tonic-gate *lp++ = '\\';
24560Sstevel@tonic-gate *lp++ = 'f';
24570Sstevel@tonic-gate col += 2;
24580Sstevel@tonic-gate break;
24590Sstevel@tonic-gate case '\r' :
24600Sstevel@tonic-gate *lp++ = '\\';
24610Sstevel@tonic-gate *lp++ = 'r';
24620Sstevel@tonic-gate col += 2;
24630Sstevel@tonic-gate break;
24640Sstevel@tonic-gate case '\t' :
24650Sstevel@tonic-gate *lp++ = '\\';
24660Sstevel@tonic-gate *lp++ = 't';
24670Sstevel@tonic-gate col += 2;
24680Sstevel@tonic-gate break;
24690Sstevel@tonic-gate case '\v' :
24700Sstevel@tonic-gate *lp++ = '\\';
24710Sstevel@tonic-gate *lp++ = 'v';
24720Sstevel@tonic-gate col += 2;
24730Sstevel@tonic-gate break;
24740Sstevel@tonic-gate #ifdef XPG6
24750Sstevel@tonic-gate /* if $ characters are within the line preceed with \ */
24760Sstevel@tonic-gate case '$' :
24770Sstevel@tonic-gate *lp++ = '\\';
24780Sstevel@tonic-gate *lp++ = '$';
24790Sstevel@tonic-gate col += 2;
24800Sstevel@tonic-gate break;
24810Sstevel@tonic-gate #endif
24820Sstevel@tonic-gate default:
24830Sstevel@tonic-gate if (isprint(c)) {
24840Sstevel@tonic-gate *lp++ = c;
24850Sstevel@tonic-gate col += 1;
24860Sstevel@tonic-gate } else {
24870Sstevel@tonic-gate (void) sprintf(lp, "\\%03o", c);
24880Sstevel@tonic-gate col += 4;
24890Sstevel@tonic-gate lp += 4;
24900Sstevel@tonic-gate }
24910Sstevel@tonic-gate break;
24920Sstevel@tonic-gate }
24930Sstevel@tonic-gate
24940Sstevel@tonic-gate /*
24950Sstevel@tonic-gate * long lines are folded w/ pt of folding indicated by writing
24960Sstevel@tonic-gate * backslash/newline character
24970Sstevel@tonic-gate */
24980Sstevel@tonic-gate
24990Sstevel@tonic-gate if (col + 1 >= 72) {
25000Sstevel@tonic-gate col = 0;
25010Sstevel@tonic-gate *lp++ = '\\';
25020Sstevel@tonic-gate *lp++ = '\n';
25030Sstevel@tonic-gate }
25040Sstevel@tonic-gate } else
25050Sstevel@tonic-gate *lp++ = c;
25060Sstevel@tonic-gate if (c == '\n' || lp >= &line[64]) {
25070Sstevel@tonic-gate linp = line;
25080Sstevel@tonic-gate len = lp - line;
25090Sstevel@tonic-gate (void) write(1, line, len);
25100Sstevel@tonic-gate return;
25110Sstevel@tonic-gate }
25120Sstevel@tonic-gate linp = lp;
25130Sstevel@tonic-gate }
25140Sstevel@tonic-gate
25150Sstevel@tonic-gate
25160Sstevel@tonic-gate static char *
getkey(const char * prompt)25170Sstevel@tonic-gate getkey(const char *prompt)
25180Sstevel@tonic-gate {
25190Sstevel@tonic-gate struct termio b;
25200Sstevel@tonic-gate int save;
25210Sstevel@tonic-gate void (*sig)();
25220Sstevel@tonic-gate static char key[KSIZE+1];
25230Sstevel@tonic-gate char *p;
25240Sstevel@tonic-gate int c;
25250Sstevel@tonic-gate
25260Sstevel@tonic-gate sig = signal(SIGINT, SIG_IGN);
25270Sstevel@tonic-gate ioctl(0, TCGETA, &b);
25280Sstevel@tonic-gate save = b.c_lflag;
25290Sstevel@tonic-gate b.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
25300Sstevel@tonic-gate ioctl(0, TCSETAW, &b);
25310Sstevel@tonic-gate write(1, gettext(prompt), strlen(gettext(prompt)));
25320Sstevel@tonic-gate p = key;
25330Sstevel@tonic-gate while (((c = getchr()) != EOF) && (c != '\n')) {
25340Sstevel@tonic-gate if (p < &key[KSIZE])
25350Sstevel@tonic-gate *p++ = c;
25360Sstevel@tonic-gate }
25370Sstevel@tonic-gate *p = 0;
25380Sstevel@tonic-gate write(1, "\n", 1);
25390Sstevel@tonic-gate b.c_lflag = save;
25400Sstevel@tonic-gate ioctl(0, TCSETAW, &b);
25410Sstevel@tonic-gate signal(SIGINT, sig);
25420Sstevel@tonic-gate return (key);
25430Sstevel@tonic-gate }
25440Sstevel@tonic-gate
25450Sstevel@tonic-gate
25460Sstevel@tonic-gate static void
globaln(int k)25470Sstevel@tonic-gate globaln(int k)
25480Sstevel@tonic-gate {
25490Sstevel@tonic-gate char *gp;
25500Sstevel@tonic-gate int c;
25510Sstevel@tonic-gate int n;
25520Sstevel@tonic-gate wchar_t cl;
25530Sstevel@tonic-gate LINE a1;
25540Sstevel@tonic-gate int nfirst;
25550Sstevel@tonic-gate char globuf[LBSIZE];
25560Sstevel@tonic-gate char multic[MB_LEN_MAX];
25570Sstevel@tonic-gate int len;
25580Sstevel@tonic-gate int pflag_save = 0;
25590Sstevel@tonic-gate int listf_save = 0;
25600Sstevel@tonic-gate int listn_save = 0;
25610Sstevel@tonic-gate
25620Sstevel@tonic-gate if (globp)
25630Sstevel@tonic-gate (void) error(33);
25640Sstevel@tonic-gate setall();
25650Sstevel@tonic-gate nonzero();
25660Sstevel@tonic-gate if ((n = _mbftowc(multic, &cl, getchr, &peekc)) <= 0)
25670Sstevel@tonic-gate (void) error(67);
25680Sstevel@tonic-gate if (cl == '\n')
25690Sstevel@tonic-gate (void) error(19);
25700Sstevel@tonic-gate save();
25710Sstevel@tonic-gate comple(cl);
25720Sstevel@tonic-gate for (a1 = zero; a1 <= dol; a1++) {
25730Sstevel@tonic-gate a1->cur &= ~01;
25740Sstevel@tonic-gate if (a1 >= addr1 && a1 <= addr2 && execute(0, a1) == k)
25750Sstevel@tonic-gate a1->cur |= 01;
25760Sstevel@tonic-gate }
25770Sstevel@tonic-gate nfirst = 0;
25780Sstevel@tonic-gate newline();
25790Sstevel@tonic-gate /*
25800Sstevel@tonic-gate * preserve the p, l, and n suffix commands of the G and V
25810Sstevel@tonic-gate * commands during the interactive section and restore
25820Sstevel@tonic-gate * on completion of the G and V command.
25830Sstevel@tonic-gate */
25840Sstevel@tonic-gate pflag_save = pflag;
25850Sstevel@tonic-gate listf_save = listf;
25860Sstevel@tonic-gate listn_save = listn;
25870Sstevel@tonic-gate pflag = 0;
25880Sstevel@tonic-gate listf = 0;
25890Sstevel@tonic-gate listn = 0;
25900Sstevel@tonic-gate for (a1 = zero; a1 <= dol; a1++) {
25910Sstevel@tonic-gate if (a1->cur & 01) {
25920Sstevel@tonic-gate a1->cur &= ~01;
25930Sstevel@tonic-gate dot = a1;
2594*13093SRoger.Faulkner@Oracle.COM puts(getaline(a1->cur));
25950Sstevel@tonic-gate if ((c = get_wchr()) == EOF)
25960Sstevel@tonic-gate (void) error(52);
25970Sstevel@tonic-gate if (c == 'a' || c == 'i' || c == 'c')
25980Sstevel@tonic-gate (void) error(53);
25990Sstevel@tonic-gate if (c == '\n') {
26000Sstevel@tonic-gate a1 = zero;
26010Sstevel@tonic-gate continue;
26020Sstevel@tonic-gate }
26030Sstevel@tonic-gate if (c != '&') {
26040Sstevel@tonic-gate gp = globuf;
26050Sstevel@tonic-gate if ((len = wctomb(gp, c)) <= 0) {
26060Sstevel@tonic-gate *gp = (unsigned char)c;
26070Sstevel@tonic-gate len = 1;
26080Sstevel@tonic-gate }
26090Sstevel@tonic-gate gp += len;
26100Sstevel@tonic-gate while ((c = get_wchr()) != '\n') {
26110Sstevel@tonic-gate
26120Sstevel@tonic-gate /* '\\' has special meaning only if preceding a '\n' */
26130Sstevel@tonic-gate if (c == '\\') {
26140Sstevel@tonic-gate c = get_wchr();
26150Sstevel@tonic-gate if (c != '\n')
26160Sstevel@tonic-gate *gp++ = '\\';
26170Sstevel@tonic-gate }
26180Sstevel@tonic-gate if ((gp + (unsigned int)MB_CUR_MAX) >=
26190Sstevel@tonic-gate &globuf[LBSIZE-1])
26200Sstevel@tonic-gate (void) error(34);
26210Sstevel@tonic-gate
26220Sstevel@tonic-gate if ((len = wctomb(gp, c)) <= 0) {
26230Sstevel@tonic-gate *gp = (unsigned char)c;
26240Sstevel@tonic-gate len = 1;
26250Sstevel@tonic-gate }
26260Sstevel@tonic-gate gp += len;
26270Sstevel@tonic-gate }
26280Sstevel@tonic-gate *gp++ = '\n';
26290Sstevel@tonic-gate *gp++ = 0;
26300Sstevel@tonic-gate nfirst = 1;
26310Sstevel@tonic-gate } else if ((c = get_wchr()) != '\n')
26320Sstevel@tonic-gate (void) error(54);
26330Sstevel@tonic-gate globp = globuf;
26340Sstevel@tonic-gate if (nfirst) {
26350Sstevel@tonic-gate globflg = 1;
26360Sstevel@tonic-gate commands();
26370Sstevel@tonic-gate globflg = 0;
26380Sstevel@tonic-gate } else
26390Sstevel@tonic-gate (void) error(56);
26400Sstevel@tonic-gate globp = 0;
26410Sstevel@tonic-gate a1 = zero;
26420Sstevel@tonic-gate }
26430Sstevel@tonic-gate }
26440Sstevel@tonic-gate pflag = pflag_save;
26450Sstevel@tonic-gate listf = listf_save;
26460Sstevel@tonic-gate listn = listn_save;
26470Sstevel@tonic-gate }
26480Sstevel@tonic-gate
26490Sstevel@tonic-gate
26500Sstevel@tonic-gate static int
eopen(char * string,int rw)26510Sstevel@tonic-gate eopen(char *string, int rw)
26520Sstevel@tonic-gate {
26530Sstevel@tonic-gate #define w_or_r(a, b) (rw ? a : b)
26540Sstevel@tonic-gate int pf[2];
26550Sstevel@tonic-gate pid_t i;
26560Sstevel@tonic-gate int io;
26570Sstevel@tonic-gate int chcount; /* # of char read. */
26580Sstevel@tonic-gate
26590Sstevel@tonic-gate if (rflg) { /* restricted shell */
26600Sstevel@tonic-gate if (Xqt) {
26610Sstevel@tonic-gate Xqt = 0;
26620Sstevel@tonic-gate (void) error(6);
26630Sstevel@tonic-gate }
26640Sstevel@tonic-gate }
26650Sstevel@tonic-gate if (!Xqt) {
26660Sstevel@tonic-gate if ((io = open(string, rw)) >= 0) {
26670Sstevel@tonic-gate if (fflg) {
26680Sstevel@tonic-gate chcount = read(io, crbuf, LBSIZE);
26690Sstevel@tonic-gate if (crflag == -1) {
26700Sstevel@tonic-gate if (isencrypt(crbuf, chcount))
26710Sstevel@tonic-gate crflag = 2;
26720Sstevel@tonic-gate else
26730Sstevel@tonic-gate crflag = -2;
26740Sstevel@tonic-gate }
26750Sstevel@tonic-gate if (crflag > 0)
26760Sstevel@tonic-gate if (run_crypt(0L, crbuf, chcount, perm) == -1)
26770Sstevel@tonic-gate (void) error(63);
26780Sstevel@tonic-gate if (fspec(crbuf, &fss, 0) < 0) {
26790Sstevel@tonic-gate fss.Ffill = 0;
26800Sstevel@tonic-gate fflg = 0;
26810Sstevel@tonic-gate (void) error(4);
26820Sstevel@tonic-gate }
26830Sstevel@tonic-gate lseek(io, 0L, 0);
26840Sstevel@tonic-gate }
26850Sstevel@tonic-gate }
26860Sstevel@tonic-gate fflg = 0;
26870Sstevel@tonic-gate return (io);
26880Sstevel@tonic-gate }
26890Sstevel@tonic-gate if (pipe(pf) < 0)
26900Sstevel@tonic-gate xerr: (void) error(0);
26910Sstevel@tonic-gate if ((i = fork()) == 0) {
26920Sstevel@tonic-gate signal(SIGHUP, oldhup);
26930Sstevel@tonic-gate signal(SIGQUIT, oldquit);
26940Sstevel@tonic-gate signal(SIGPIPE, oldpipe);
26950Sstevel@tonic-gate signal(SIGINT, (void (*)()) 0);
26960Sstevel@tonic-gate close(w_or_r(pf[1], pf[0]));
26970Sstevel@tonic-gate close(w_or_r(0, 1));
26980Sstevel@tonic-gate dup(w_or_r(pf[0], pf[1]));
26990Sstevel@tonic-gate close(w_or_r(pf[0], pf[1]));
27000Sstevel@tonic-gate if (__xpg4 == 0) { /* not XPG4 */
27010Sstevel@tonic-gate shpath = "/usr/bin/sh";
27020Sstevel@tonic-gate } else {
27030Sstevel@tonic-gate /* XPG4 */
27040Sstevel@tonic-gate shpath = "/usr/xpg4/bin/sh";
27050Sstevel@tonic-gate }
27060Sstevel@tonic-gate execlp((const char *)shpath, "sh", "-c", string, (char *)0);
27070Sstevel@tonic-gate exit(1);
27080Sstevel@tonic-gate }
27090Sstevel@tonic-gate if (i == (pid_t)-1)
27100Sstevel@tonic-gate goto xerr;
27110Sstevel@tonic-gate close(w_or_r(pf[0], pf[1]));
27120Sstevel@tonic-gate return (w_or_r(pf[1], pf[0]));
27130Sstevel@tonic-gate }
27140Sstevel@tonic-gate
27150Sstevel@tonic-gate
27160Sstevel@tonic-gate static void
eclose(int f)27170Sstevel@tonic-gate eclose(int f)
27180Sstevel@tonic-gate {
27190Sstevel@tonic-gate close(f);
27200Sstevel@tonic-gate if (Xqt)
27210Sstevel@tonic-gate Xqt = 0, wait((int *)0);
27220Sstevel@tonic-gate }
27230Sstevel@tonic-gate
27240Sstevel@tonic-gate
27250Sstevel@tonic-gate static void
mkfunny(void)27260Sstevel@tonic-gate mkfunny(void)
27270Sstevel@tonic-gate {
27280Sstevel@tonic-gate char *p, *p1, *p2;
27290Sstevel@tonic-gate
27300Sstevel@tonic-gate p2 = p1 = funny;
27310Sstevel@tonic-gate p = file;
27320Sstevel@tonic-gate /*
27330Sstevel@tonic-gate * Go to end of file name
27340Sstevel@tonic-gate */
27350Sstevel@tonic-gate while (*p)
27360Sstevel@tonic-gate p++;
27370Sstevel@tonic-gate while (*--p == '/') /* delete trailing slashes */
27380Sstevel@tonic-gate *p = '\0';
27390Sstevel@tonic-gate /*
27400Sstevel@tonic-gate * go back to beginning of file
27410Sstevel@tonic-gate */
27420Sstevel@tonic-gate p = file;
27430Sstevel@tonic-gate /*
27440Sstevel@tonic-gate * Copy file name to funny setting p2 at
27450Sstevel@tonic-gate * basename of file.
27460Sstevel@tonic-gate */
27470Sstevel@tonic-gate while (*p1++ = *p)
27480Sstevel@tonic-gate if (*p++ == '/') p2 = p1;
27490Sstevel@tonic-gate /*
27500Sstevel@tonic-gate * Set p1 to point to basename of tfname.
27510Sstevel@tonic-gate */
27520Sstevel@tonic-gate p1 = strrchr(tfname, '/');
27530Sstevel@tonic-gate if (strlen(tfname) > (size_t)6)
27540Sstevel@tonic-gate p1 = &tfname[strlen(tfname)-6];
27550Sstevel@tonic-gate p1++;
27560Sstevel@tonic-gate *p2 = '\007'; /* add unprintable char for funny a unique name */
27570Sstevel@tonic-gate /*
27580Sstevel@tonic-gate * Copy tfname to file.
27590Sstevel@tonic-gate */
27600Sstevel@tonic-gate while (*++p2 = *p1++);
27610Sstevel@tonic-gate }
27620Sstevel@tonic-gate
27630Sstevel@tonic-gate
27640Sstevel@tonic-gate static void
getime(void)27650Sstevel@tonic-gate getime(void) /* get modified time of file and save */
27660Sstevel@tonic-gate {
27670Sstevel@tonic-gate if (stat(file, &Fl) < 0)
27680Sstevel@tonic-gate savtime = 0;
27690Sstevel@tonic-gate else
27700Sstevel@tonic-gate savtime = Fl.st_mtime;
27710Sstevel@tonic-gate }
27720Sstevel@tonic-gate
27730Sstevel@tonic-gate
27740Sstevel@tonic-gate static void
chktime(void)27750Sstevel@tonic-gate chktime(void) /* check saved mod time against current mod time */
27760Sstevel@tonic-gate {
27770Sstevel@tonic-gate if (savtime != 0 && Fl.st_mtime != 0) {
27780Sstevel@tonic-gate if (savtime != Fl.st_mtime)
27790Sstevel@tonic-gate (void) error(58);
27800Sstevel@tonic-gate }
27810Sstevel@tonic-gate }
27820Sstevel@tonic-gate
27830Sstevel@tonic-gate
27840Sstevel@tonic-gate static void
newtime(void)27850Sstevel@tonic-gate newtime(void) /* get new mod time and save */
27860Sstevel@tonic-gate {
27870Sstevel@tonic-gate stat(file, &Fl);
27880Sstevel@tonic-gate savtime = Fl.st_mtime;
27890Sstevel@tonic-gate }
27900Sstevel@tonic-gate
27910Sstevel@tonic-gate
27920Sstevel@tonic-gate static void
red(char * op)27930Sstevel@tonic-gate red(char *op) /* restricted - check for '/' in name */
27940Sstevel@tonic-gate /* and delete trailing '/' */
27950Sstevel@tonic-gate {
27960Sstevel@tonic-gate char *p;
27970Sstevel@tonic-gate
27980Sstevel@tonic-gate p = op;
27990Sstevel@tonic-gate while (*p)
28000Sstevel@tonic-gate if (*p++ == '/'&& rflg) {
28010Sstevel@tonic-gate *op = 0;
28020Sstevel@tonic-gate (void) error(6);
28030Sstevel@tonic-gate }
28040Sstevel@tonic-gate /* delete trailing '/' */
28050Sstevel@tonic-gate while (p > op) {
28060Sstevel@tonic-gate if (*--p == '/')
28070Sstevel@tonic-gate *p = '\0';
28080Sstevel@tonic-gate else break;
28090Sstevel@tonic-gate }
28100Sstevel@tonic-gate }
28110Sstevel@tonic-gate
28120Sstevel@tonic-gate
28130Sstevel@tonic-gate /*
28140Sstevel@tonic-gate * Searches thru beginning of file looking for a string of the form
28150Sstevel@tonic-gate * <: values... :>
28160Sstevel@tonic-gate *
28170Sstevel@tonic-gate * where "values" are
28180Sstevel@tonic-gate *
28190Sstevel@tonic-gate * \b ignored
28200Sstevel@tonic-gate * s<num> sets the Flim to <num>
28210Sstevel@tonic-gate * t??? sets tab stop stuff
28220Sstevel@tonic-gate * d ignored
28230Sstevel@tonic-gate * m<num> ignored
28240Sstevel@tonic-gate * e ignored
28250Sstevel@tonic-gate */
28260Sstevel@tonic-gate
28270Sstevel@tonic-gate static int
fspec(char line[],struct Fspec * f,int up)28280Sstevel@tonic-gate fspec(char line[], struct Fspec *f, int up)
28290Sstevel@tonic-gate {
28300Sstevel@tonic-gate struct termio arg;
28310Sstevel@tonic-gate int havespec, n;
28320Sstevel@tonic-gate int len;
28330Sstevel@tonic-gate
28340Sstevel@tonic-gate if (!up) clear(f);
28350Sstevel@tonic-gate
28360Sstevel@tonic-gate havespec = fsprtn = 0;
28370Sstevel@tonic-gate for (fsp = line; *fsp && *fsp != '\n'; fsp += len) {
28380Sstevel@tonic-gate if ((len = mblen(fsp, MB_CUR_MAX)) <= 0)
28390Sstevel@tonic-gate len = 1;
28400Sstevel@tonic-gate switch (*fsp) {
28410Sstevel@tonic-gate
28420Sstevel@tonic-gate case '<': if (havespec)
28430Sstevel@tonic-gate return (-1);
28440Sstevel@tonic-gate if (*(fsp+1) == ':') {
28450Sstevel@tonic-gate havespec = 1;
28460Sstevel@tonic-gate clear(f);
28470Sstevel@tonic-gate if (!ioctl(1, TCGETA, &arg) &&
28480Sstevel@tonic-gate ((arg.c_oflag&TAB3) == TAB3))
28490Sstevel@tonic-gate f->Ffill = 1;
28500Sstevel@tonic-gate fsp++;
28510Sstevel@tonic-gate continue;
28520Sstevel@tonic-gate }
28530Sstevel@tonic-gate
28540Sstevel@tonic-gate case ' ': continue;
28550Sstevel@tonic-gate
28560Sstevel@tonic-gate case 's': if (havespec && (n = numb()) >= 0)
28570Sstevel@tonic-gate f->Flim = n;
28580Sstevel@tonic-gate continue;
28590Sstevel@tonic-gate
28600Sstevel@tonic-gate case 't': if (havespec) targ(f);
28610Sstevel@tonic-gate continue;
28620Sstevel@tonic-gate
28630Sstevel@tonic-gate case 'd': continue;
28640Sstevel@tonic-gate
28650Sstevel@tonic-gate case 'm': if (havespec) n = numb();
28660Sstevel@tonic-gate continue;
28670Sstevel@tonic-gate
28680Sstevel@tonic-gate case 'e': continue;
28690Sstevel@tonic-gate case ':': if (!havespec) continue;
28700Sstevel@tonic-gate if (*(fsp+1) != '>') fsprtn = -1;
28710Sstevel@tonic-gate return (fsprtn);
28720Sstevel@tonic-gate
28730Sstevel@tonic-gate default: if (!havespec) continue;
28740Sstevel@tonic-gate return (-1);
28750Sstevel@tonic-gate }
28760Sstevel@tonic-gate }
28770Sstevel@tonic-gate return (1);
28780Sstevel@tonic-gate }
28790Sstevel@tonic-gate
28800Sstevel@tonic-gate
28810Sstevel@tonic-gate static int
numb(void)28820Sstevel@tonic-gate numb(void)
28830Sstevel@tonic-gate {
28840Sstevel@tonic-gate int n;
28850Sstevel@tonic-gate
28860Sstevel@tonic-gate n = 0;
28870Sstevel@tonic-gate while (*++fsp >= '0' && *fsp <= '9')
28880Sstevel@tonic-gate n = 10*n + *fsp-'0';
28890Sstevel@tonic-gate fsp--;
28900Sstevel@tonic-gate return (n);
28910Sstevel@tonic-gate }
28920Sstevel@tonic-gate
28930Sstevel@tonic-gate
28940Sstevel@tonic-gate static void
targ(struct Fspec * f)28950Sstevel@tonic-gate targ(struct Fspec *f)
28960Sstevel@tonic-gate {
28970Sstevel@tonic-gate
28980Sstevel@tonic-gate if (*++fsp == '-') {
28990Sstevel@tonic-gate if (*(fsp + 1) >= '0' && *(fsp+1) <= '9') tincr(numb(), f);
29000Sstevel@tonic-gate else tstd(f);
29010Sstevel@tonic-gate return;
29020Sstevel@tonic-gate }
29030Sstevel@tonic-gate if (*fsp >= '0' && *fsp <= '9') {
29040Sstevel@tonic-gate tlist(f);
29050Sstevel@tonic-gate return;
29060Sstevel@tonic-gate }
29070Sstevel@tonic-gate fsprtn = -1;
29080Sstevel@tonic-gate fsp--;
29090Sstevel@tonic-gate }
29100Sstevel@tonic-gate
29110Sstevel@tonic-gate
29120Sstevel@tonic-gate static void
tincr(int n,struct Fspec * f)29130Sstevel@tonic-gate tincr(int n, struct Fspec *f)
29140Sstevel@tonic-gate {
29150Sstevel@tonic-gate int l, i;
29160Sstevel@tonic-gate
29170Sstevel@tonic-gate l = 1;
29180Sstevel@tonic-gate for (i = 0; i < 20; i++)
29190Sstevel@tonic-gate f->Ftabs[i] = l += n;
29200Sstevel@tonic-gate f->Ftabs[i] = 0;
29210Sstevel@tonic-gate }
29220Sstevel@tonic-gate
29230Sstevel@tonic-gate
29240Sstevel@tonic-gate static void
tstd(struct Fspec * f)29250Sstevel@tonic-gate tstd(struct Fspec *f)
29260Sstevel@tonic-gate {
29270Sstevel@tonic-gate char std[3];
29280Sstevel@tonic-gate
29290Sstevel@tonic-gate std[0] = *++fsp;
29300Sstevel@tonic-gate if (*(fsp+1) >= '0' && *(fsp+1) <= '9') {
29310Sstevel@tonic-gate std[1] = *++fsp;
29320Sstevel@tonic-gate std[2] = '\0';
29330Sstevel@tonic-gate } else std[1] = '\0';
29340Sstevel@tonic-gate fsprtn = stdtab(std, f->Ftabs);
29350Sstevel@tonic-gate }
29360Sstevel@tonic-gate
29370Sstevel@tonic-gate
29380Sstevel@tonic-gate static void
tlist(struct Fspec * f)29390Sstevel@tonic-gate tlist(struct Fspec *f)
29400Sstevel@tonic-gate {
29410Sstevel@tonic-gate int n, last, i;
29420Sstevel@tonic-gate
29430Sstevel@tonic-gate fsp--;
29440Sstevel@tonic-gate last = i = 0;
29450Sstevel@tonic-gate
29460Sstevel@tonic-gate do {
29470Sstevel@tonic-gate if ((n = numb()) <= last || i >= 20) {
29480Sstevel@tonic-gate fsprtn = -1;
29490Sstevel@tonic-gate return;
29500Sstevel@tonic-gate }
29510Sstevel@tonic-gate f->Ftabs[i++] = last = n;
29520Sstevel@tonic-gate } while (*++fsp == ',');
29530Sstevel@tonic-gate
29540Sstevel@tonic-gate f->Ftabs[i] = 0;
29550Sstevel@tonic-gate fsp--;
29560Sstevel@tonic-gate }
29570Sstevel@tonic-gate
29580Sstevel@tonic-gate
29590Sstevel@tonic-gate static int
expnd(char line[],char buf[],int * sz,struct Fspec * f)29600Sstevel@tonic-gate expnd(char line[], char buf[], int *sz, struct Fspec *f)
29610Sstevel@tonic-gate {
29620Sstevel@tonic-gate char *l, *t;
29630Sstevel@tonic-gate int b;
29640Sstevel@tonic-gate
29650Sstevel@tonic-gate l = line - 1;
29660Sstevel@tonic-gate b = 1;
29670Sstevel@tonic-gate t = f->Ftabs;
29680Sstevel@tonic-gate fsprtn = 0;
29690Sstevel@tonic-gate
29700Sstevel@tonic-gate while (*++l && *l != '\n' && b < 511) {
29710Sstevel@tonic-gate if (*l == '\t') {
29720Sstevel@tonic-gate while (*t && b >= *t) t++;
29730Sstevel@tonic-gate if (*t == 0) fsprtn = -2;
29740Sstevel@tonic-gate do buf[b-1] = ' '; while (++b < *t);
29750Sstevel@tonic-gate } else buf[b++ - 1] = *l;
29760Sstevel@tonic-gate }
29770Sstevel@tonic-gate
29780Sstevel@tonic-gate buf[b] = '\0';
29790Sstevel@tonic-gate *sz = b;
29800Sstevel@tonic-gate if (*l != '\0' && *l != '\n') {
29810Sstevel@tonic-gate buf[b-1] = '\n';
29820Sstevel@tonic-gate return (-1);
29830Sstevel@tonic-gate }
29840Sstevel@tonic-gate buf[b-1] = *l;
29850Sstevel@tonic-gate if (f->Flim && (b-1 > (int)f->Flim))
29860Sstevel@tonic-gate return (-1);
29870Sstevel@tonic-gate return (fsprtn);
29880Sstevel@tonic-gate }
29890Sstevel@tonic-gate
29900Sstevel@tonic-gate
29910Sstevel@tonic-gate static void
clear(struct Fspec * f)29920Sstevel@tonic-gate clear(struct Fspec *f)
29930Sstevel@tonic-gate {
29940Sstevel@tonic-gate f->Ftabs[0] = f->Fdel = f->Fmov = f->Ffill = 0;
29950Sstevel@tonic-gate f->Flim = 0;
29960Sstevel@tonic-gate }
29970Sstevel@tonic-gate
29980Sstevel@tonic-gate
29990Sstevel@tonic-gate static int
lenchk(char line[],struct Fspec * f)30000Sstevel@tonic-gate lenchk(char line[], struct Fspec *f)
30010Sstevel@tonic-gate {
30020Sstevel@tonic-gate char *l, *t;
30030Sstevel@tonic-gate int b;
30040Sstevel@tonic-gate
30050Sstevel@tonic-gate l = line - 1;
30060Sstevel@tonic-gate b = 1;
30070Sstevel@tonic-gate t = f->Ftabs;
30080Sstevel@tonic-gate
30090Sstevel@tonic-gate while (*++l && *l != '\n' && b < 511) {
30100Sstevel@tonic-gate if (*l == '\t') {
30110Sstevel@tonic-gate while (*t && b >= *t) t++;
30120Sstevel@tonic-gate while (++b < *t);
30130Sstevel@tonic-gate } else b++;
30140Sstevel@tonic-gate }
30150Sstevel@tonic-gate
30160Sstevel@tonic-gate if ((*l != '\0' && *l != '\n') || (f->Flim && (b-1 > (int)f->Flim)))
30170Sstevel@tonic-gate return (-1);
30180Sstevel@tonic-gate return (0);
30190Sstevel@tonic-gate }
30200Sstevel@tonic-gate #define NTABS 21
30210Sstevel@tonic-gate
30220Sstevel@tonic-gate
30230Sstevel@tonic-gate /*
30240Sstevel@tonic-gate * stdtabs: standard tabs table
30250Sstevel@tonic-gate * format: option code letter(s), null, tabs, null
30260Sstevel@tonic-gate */
30270Sstevel@tonic-gate
30280Sstevel@tonic-gate static char stdtabs[] = {
30290Sstevel@tonic-gate 'a', 0, 1, 10, 16, 36, 72, 0, /* IBM 370 Assembler */
30300Sstevel@tonic-gate 'a', '2', 0, 1, 10, 16, 40, 72, 0, /* IBM Assembler alternative */
30310Sstevel@tonic-gate 'c', 0, 1, 8, 12, 16, 20, 55, 0, /* COBOL, normal */
30320Sstevel@tonic-gate 'c', '2', 0, 1, 6, 10, 14, 49, 0, /* COBOL, crunched */
30330Sstevel@tonic-gate 'c', '3', 0, 1, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46, 50,
30340Sstevel@tonic-gate 54, 58, 62, 67, 0,
30350Sstevel@tonic-gate 'f', 0, 1, 7, 11, 15, 19, 23, 0, /* FORTRAN */
30360Sstevel@tonic-gate 'p', 0, 1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61, 0,
30370Sstevel@tonic-gate /* PL/I */
30380Sstevel@tonic-gate 's', 0, 1, 10, 55, 0, /* SNOBOL */
30390Sstevel@tonic-gate 'u', 0, 1, 12, 20, 44, 0, /* UNIVAC ASM */
30400Sstevel@tonic-gate 0 };
30410Sstevel@tonic-gate
30420Sstevel@tonic-gate
30430Sstevel@tonic-gate /*
30440Sstevel@tonic-gate * stdtab: return tab list for any "canned" tab option.
30450Sstevel@tonic-gate * entry: option points to null-terminated option string
30460Sstevel@tonic-gate * tabvect points to vector to be filled in
30470Sstevel@tonic-gate * exit: return (0) if legal, tabvect filled, ending with zero
30480Sstevel@tonic-gate * return (-1) if unknown option
30490Sstevel@tonic-gate */
30500Sstevel@tonic-gate
30510Sstevel@tonic-gate
30520Sstevel@tonic-gate static int
stdtab(char option[],char tabvect[NTABS])30530Sstevel@tonic-gate stdtab(char option[], char tabvect[NTABS])
30540Sstevel@tonic-gate {
30550Sstevel@tonic-gate char *scan;
30560Sstevel@tonic-gate tabvect[0] = 0;
30570Sstevel@tonic-gate scan = stdtabs;
30580Sstevel@tonic-gate while (*scan) {
30590Sstevel@tonic-gate if (strequal(&scan, option)) {
30600Sstevel@tonic-gate strcopy(scan, tabvect);
30610Sstevel@tonic-gate break;
30620Sstevel@tonic-gate } else
30630Sstevel@tonic-gate while (*scan++); /* skip over tab specs */
30640Sstevel@tonic-gate }
30650Sstevel@tonic-gate
30660Sstevel@tonic-gate /* later: look up code in /etc/something */
30670Sstevel@tonic-gate return (tabvect[0] ? 0 : -1);
30680Sstevel@tonic-gate }
30690Sstevel@tonic-gate
30700Sstevel@tonic-gate
30710Sstevel@tonic-gate /*
30720Sstevel@tonic-gate * strequal: checks strings for equality
30730Sstevel@tonic-gate * entry: scan1 points to scan pointer, str points to string
30740Sstevel@tonic-gate * exit: return (1) if equal, return (0) if not
30750Sstevel@tonic-gate * *scan1 is advanced to next nonzero byte after null
30760Sstevel@tonic-gate */
30770Sstevel@tonic-gate
30780Sstevel@tonic-gate
30790Sstevel@tonic-gate static int
strequal(char ** scan1,char * str)30800Sstevel@tonic-gate strequal(char **scan1, char *str)
30810Sstevel@tonic-gate {
30820Sstevel@tonic-gate char c, *scan;
30830Sstevel@tonic-gate scan = *scan1;
30840Sstevel@tonic-gate while ((c = *scan++) == *str && c) str++;
30850Sstevel@tonic-gate *scan1 = scan;
30860Sstevel@tonic-gate if (c == 0 && *str == 0)
30870Sstevel@tonic-gate return (1);
30880Sstevel@tonic-gate if (c)
30890Sstevel@tonic-gate while (*scan++);
30900Sstevel@tonic-gate *scan1 = scan;
30910Sstevel@tonic-gate return (0);
30920Sstevel@tonic-gate }
30930Sstevel@tonic-gate
30940Sstevel@tonic-gate
30950Sstevel@tonic-gate /* strcopy: copy source to destination */
30960Sstevel@tonic-gate
30970Sstevel@tonic-gate
30980Sstevel@tonic-gate static void
strcopy(char * source,char * dest)30990Sstevel@tonic-gate strcopy(char *source, char *dest)
31000Sstevel@tonic-gate {
31010Sstevel@tonic-gate while (*dest++ = *source++);
31020Sstevel@tonic-gate }
31030Sstevel@tonic-gate
31040Sstevel@tonic-gate
31050Sstevel@tonic-gate /* This is called before a buffer modifying command so that the */
31060Sstevel@tonic-gate /* current array of line ptrs is saved in sav and dot and dol are saved */
31070Sstevel@tonic-gate
31080Sstevel@tonic-gate
31090Sstevel@tonic-gate static void
save(void)31100Sstevel@tonic-gate save(void) {
31110Sstevel@tonic-gate LINE i;
31120Sstevel@tonic-gate int j;
31130Sstevel@tonic-gate
31140Sstevel@tonic-gate savdot = dot;
31150Sstevel@tonic-gate savdol = dol;
31160Sstevel@tonic-gate for (j = 0; j <= 25; j++)
31170Sstevel@tonic-gate savnames[j] = names[j];
31180Sstevel@tonic-gate
31190Sstevel@tonic-gate for (i = zero + 1; i <= dol; i++)
31200Sstevel@tonic-gate i->sav = i->cur;
31210Sstevel@tonic-gate initflg = 0;
31220Sstevel@tonic-gate }
31230Sstevel@tonic-gate
31240Sstevel@tonic-gate
31250Sstevel@tonic-gate /* The undo command calls this to restore the previous ptr array sav */
31260Sstevel@tonic-gate /* and swap with cur - dot and dol are swapped also. This allows user to */
31270Sstevel@tonic-gate /* undo an undo */
31280Sstevel@tonic-gate
31290Sstevel@tonic-gate
31300Sstevel@tonic-gate static void
undo(void)31310Sstevel@tonic-gate undo(void) {
31320Sstevel@tonic-gate int j;
31330Sstevel@tonic-gate long tmp;
31340Sstevel@tonic-gate LINE i, tmpdot, tmpdol;
31350Sstevel@tonic-gate
31360Sstevel@tonic-gate tmpdot = dot; dot = savdot; savdot = tmpdot;
31370Sstevel@tonic-gate tmpdol = dol; dol = savdol; savdol = tmpdol;
31380Sstevel@tonic-gate /* swap arrays using the greater of dol or savdol as upper limit */
31390Sstevel@tonic-gate for (i = zero + 1; i <= ((dol > savdol) ? dol : savdol); i++) {
31400Sstevel@tonic-gate tmp = i->cur;
31410Sstevel@tonic-gate i->cur = i->sav;
31420Sstevel@tonic-gate i->sav = tmp;
31430Sstevel@tonic-gate }
31440Sstevel@tonic-gate /*
31450Sstevel@tonic-gate * If the current text lines are swapped with the
31460Sstevel@tonic-gate * text lines in the save buffer, then swap the current
31470Sstevel@tonic-gate * marks with those in the save area.
31480Sstevel@tonic-gate */
31490Sstevel@tonic-gate
31500Sstevel@tonic-gate for (j = 0; j <= 25; j++) {
31510Sstevel@tonic-gate tmp = names[j];
31520Sstevel@tonic-gate names[j] = savnames[j];
31530Sstevel@tonic-gate savnames[j] = tmp;
31540Sstevel@tonic-gate }
31550Sstevel@tonic-gate }
31560Sstevel@tonic-gate
31570Sstevel@tonic-gate static wchar_t
get_wchr()31580Sstevel@tonic-gate get_wchr()
31590Sstevel@tonic-gate {
31600Sstevel@tonic-gate wchar_t wc;
31610Sstevel@tonic-gate char multi[MB_LEN_MAX];
31620Sstevel@tonic-gate
31630Sstevel@tonic-gate if (_mbftowc(multi, &wc, getchr, &peekc) <= 0)
31640Sstevel@tonic-gate wc = getchr();
31650Sstevel@tonic-gate return (wc);
31660Sstevel@tonic-gate }
3167