1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 23*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 24*7c478bd9Sstevel@tonic-gate 25*7c478bd9Sstevel@tonic-gate 26*7c478bd9Sstevel@tonic-gate /* 27*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 28*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 29*7c478bd9Sstevel@tonic-gate */ 30*7c478bd9Sstevel@tonic-gate 31*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 32*7c478bd9Sstevel@tonic-gate 33*7c478bd9Sstevel@tonic-gate /* 34*7c478bd9Sstevel@tonic-gate * Editor 35*7c478bd9Sstevel@tonic-gate */ 36*7c478bd9Sstevel@tonic-gate 37*7c478bd9Sstevel@tonic-gate #include <crypt.h> 38*7c478bd9Sstevel@tonic-gate #include <libgen.h> 39*7c478bd9Sstevel@tonic-gate #include <wait.h> 40*7c478bd9Sstevel@tonic-gate #include <string.h> 41*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 42*7c478bd9Sstevel@tonic-gate #include <locale.h> 43*7c478bd9Sstevel@tonic-gate #include <regexpr.h> 44*7c478bd9Sstevel@tonic-gate #include <regex.h> 45*7c478bd9Sstevel@tonic-gate #include <errno.h> 46*7c478bd9Sstevel@tonic-gate 47*7c478bd9Sstevel@tonic-gate static const char *msgtab[] = 48*7c478bd9Sstevel@tonic-gate { 49*7c478bd9Sstevel@tonic-gate "write or open on pipe failed", /* 0 */ 50*7c478bd9Sstevel@tonic-gate "warning: expecting `w'", /* 1 */ 51*7c478bd9Sstevel@tonic-gate "mark not lower case ascii", /* 2 */ 52*7c478bd9Sstevel@tonic-gate "Cannot open input file", /* 3 */ 53*7c478bd9Sstevel@tonic-gate "PWB spec problem", /* 4 */ 54*7c478bd9Sstevel@tonic-gate "nothing to undo", /* 5 */ 55*7c478bd9Sstevel@tonic-gate "restricted shell", /* 6 */ 56*7c478bd9Sstevel@tonic-gate "cannot create output file", /* 7 */ 57*7c478bd9Sstevel@tonic-gate "filesystem out of space!", /* 8 */ 58*7c478bd9Sstevel@tonic-gate "cannot open file", /* 9 */ 59*7c478bd9Sstevel@tonic-gate "cannot link", /* 10 */ 60*7c478bd9Sstevel@tonic-gate "Range endpoint too large", /* 11 */ 61*7c478bd9Sstevel@tonic-gate "unknown command", /* 12 */ 62*7c478bd9Sstevel@tonic-gate "search string not found", /* 13 */ 63*7c478bd9Sstevel@tonic-gate "-", /* 14 */ 64*7c478bd9Sstevel@tonic-gate "line out of range", /* 15 */ 65*7c478bd9Sstevel@tonic-gate "bad number", /* 16 */ 66*7c478bd9Sstevel@tonic-gate "bad range", /* 17 */ 67*7c478bd9Sstevel@tonic-gate "Illegal address count", /* 18 */ 68*7c478bd9Sstevel@tonic-gate "incomplete global expression", /* 19 */ 69*7c478bd9Sstevel@tonic-gate "illegal suffix", /* 20 */ 70*7c478bd9Sstevel@tonic-gate "illegal or missing filename", /* 21 */ 71*7c478bd9Sstevel@tonic-gate "no space after command", /* 22 */ 72*7c478bd9Sstevel@tonic-gate "fork failed - try again", /* 23 */ 73*7c478bd9Sstevel@tonic-gate "maximum of 64 characters in file names", /* 24 */ 74*7c478bd9Sstevel@tonic-gate "`\\digit' out of range", /* 25 */ 75*7c478bd9Sstevel@tonic-gate "interrupt", /* 26 */ 76*7c478bd9Sstevel@tonic-gate "line too long", /* 27 */ 77*7c478bd9Sstevel@tonic-gate "illegal character in input file", /* 28 */ 78*7c478bd9Sstevel@tonic-gate "write error", /* 29 */ 79*7c478bd9Sstevel@tonic-gate "out of memory for append", /* 30 */ 80*7c478bd9Sstevel@tonic-gate "temp file too big", /* 31 */ 81*7c478bd9Sstevel@tonic-gate "I/O error on temp file", /* 32 */ 82*7c478bd9Sstevel@tonic-gate "multiple globals not allowed", /* 33 */ 83*7c478bd9Sstevel@tonic-gate "global too long", /* 34 */ 84*7c478bd9Sstevel@tonic-gate "no match", /* 35 */ 85*7c478bd9Sstevel@tonic-gate "illegal or missing delimiter", /* 36 */ 86*7c478bd9Sstevel@tonic-gate "-", /* 37 */ 87*7c478bd9Sstevel@tonic-gate "replacement string too long", /* 38 */ 88*7c478bd9Sstevel@tonic-gate "illegal move destination", /* 39 */ 89*7c478bd9Sstevel@tonic-gate "-", /* 40 */ 90*7c478bd9Sstevel@tonic-gate "no remembered search string", /* 41 */ 91*7c478bd9Sstevel@tonic-gate "'\\( \\)' imbalance", /* 42 */ 92*7c478bd9Sstevel@tonic-gate "Too many `\\(' s", /* 43 */ 93*7c478bd9Sstevel@tonic-gate "more than 2 numbers given", /* 44 */ 94*7c478bd9Sstevel@tonic-gate "'\\}' expected", /* 45 */ 95*7c478bd9Sstevel@tonic-gate "first number exceeds second", /* 46 */ 96*7c478bd9Sstevel@tonic-gate "incomplete substitute", /* 47 */ 97*7c478bd9Sstevel@tonic-gate "newline unexpected", /* 48 */ 98*7c478bd9Sstevel@tonic-gate "'[ ]' imbalance", /* 49 */ 99*7c478bd9Sstevel@tonic-gate "regular expression overflow", /* 50 */ 100*7c478bd9Sstevel@tonic-gate "regular expression error", /* 51 */ 101*7c478bd9Sstevel@tonic-gate "command expected", /* 52 */ 102*7c478bd9Sstevel@tonic-gate "a, i, or c not allowed in G", /* 53 */ 103*7c478bd9Sstevel@tonic-gate "end of line expected", /* 54 */ 104*7c478bd9Sstevel@tonic-gate "no remembered replacement string", /* 55 */ 105*7c478bd9Sstevel@tonic-gate "no remembered command", /* 56 */ 106*7c478bd9Sstevel@tonic-gate "illegal redirection", /* 57 */ 107*7c478bd9Sstevel@tonic-gate "possible concurrent update", /* 58 */ 108*7c478bd9Sstevel@tonic-gate "-", /* 59 */ 109*7c478bd9Sstevel@tonic-gate "the x command has become X (upper case)", /* 60 */ 110*7c478bd9Sstevel@tonic-gate "Warning: 'w' may destroy input file " 111*7c478bd9Sstevel@tonic-gate "(due to `illegal char' read earlier)", 112*7c478bd9Sstevel@tonic-gate /* 61 */ 113*7c478bd9Sstevel@tonic-gate "Caution: 'q' may lose data in buffer;" 114*7c478bd9Sstevel@tonic-gate " 'w' may destroy input file", 115*7c478bd9Sstevel@tonic-gate /* 62 */ 116*7c478bd9Sstevel@tonic-gate "Encryption of string failed", /* 63 */ 117*7c478bd9Sstevel@tonic-gate "Encryption facility not available", /* 64 */ 118*7c478bd9Sstevel@tonic-gate "Cannot encrypt temporary file", /* 65 */ 119*7c478bd9Sstevel@tonic-gate "Enter key:", /* 66 */ 120*7c478bd9Sstevel@tonic-gate "Illegal byte sequence", /* 67 */ 121*7c478bd9Sstevel@tonic-gate "File does not exist", /* 68 */ 122*7c478bd9Sstevel@tonic-gate "tempnam failed", /* 69 */ 123*7c478bd9Sstevel@tonic-gate "Cannot open temporary file", /* 70 */ 124*7c478bd9Sstevel@tonic-gate 0 125*7c478bd9Sstevel@tonic-gate }; 126*7c478bd9Sstevel@tonic-gate 127*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 128*7c478bd9Sstevel@tonic-gate #include <limits.h> 129*7c478bd9Sstevel@tonic-gate #include <stdio.h> 130*7c478bd9Sstevel@tonic-gate #include <signal.h> 131*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 132*7c478bd9Sstevel@tonic-gate #include <sys/stat.h> 133*7c478bd9Sstevel@tonic-gate #include <sys/statvfs.h> 134*7c478bd9Sstevel@tonic-gate #include <unistd.h> 135*7c478bd9Sstevel@tonic-gate #include <termio.h> 136*7c478bd9Sstevel@tonic-gate #include <ctype.h> 137*7c478bd9Sstevel@tonic-gate #include <setjmp.h> 138*7c478bd9Sstevel@tonic-gate #include <fcntl.h> 139*7c478bd9Sstevel@tonic-gate #include <wchar.h> /* I18N */ 140*7c478bd9Sstevel@tonic-gate #include <wctype.h> /* I18N */ 141*7c478bd9Sstevel@tonic-gate #include <widec.h> /* I18N */ 142*7c478bd9Sstevel@tonic-gate 143*7c478bd9Sstevel@tonic-gate #define FTYPE(A) (A.st_mode) 144*7c478bd9Sstevel@tonic-gate #define FMODE(A) (A.st_mode) 145*7c478bd9Sstevel@tonic-gate #define IDENTICAL(A, B) (A.st_dev == B.st_dev && A.st_ino == B.st_ino) 146*7c478bd9Sstevel@tonic-gate #define ISBLK(A) ((A.st_mode & S_IFMT) == S_IFBLK) 147*7c478bd9Sstevel@tonic-gate #define ISCHR(A) ((A.st_mode & S_IFMT) == S_IFCHR) 148*7c478bd9Sstevel@tonic-gate #define ISDIR(A) ((A.st_mode & S_IFMT) == S_IFDIR) 149*7c478bd9Sstevel@tonic-gate #define ISFIFO(A) ((A.st_mode & S_IFMT) == S_IFIFO) 150*7c478bd9Sstevel@tonic-gate #define ISREG(A) ((A.st_mode & S_IFMT) == S_IFREG) 151*7c478bd9Sstevel@tonic-gate 152*7c478bd9Sstevel@tonic-gate #define PUTM() if (xcode >= 0) puts(gettext(msgtab[xcode])) 153*7c478bd9Sstevel@tonic-gate #define UNGETC(c) (peekc = c) 154*7c478bd9Sstevel@tonic-gate #define FNSIZE PATH_MAX 155*7c478bd9Sstevel@tonic-gate #define LBSIZE LINE_MAX 156*7c478bd9Sstevel@tonic-gate 157*7c478bd9Sstevel@tonic-gate /* size of substitution replacement pattern buffer */ 158*7c478bd9Sstevel@tonic-gate #define RHSIZE (LINE_MAX*2) 159*7c478bd9Sstevel@tonic-gate 160*7c478bd9Sstevel@tonic-gate #define KSIZE 8 161*7c478bd9Sstevel@tonic-gate 162*7c478bd9Sstevel@tonic-gate #define READ 0 163*7c478bd9Sstevel@tonic-gate #define WRITE 1 164*7c478bd9Sstevel@tonic-gate 165*7c478bd9Sstevel@tonic-gate extern char *optarg; /* Value of argument */ 166*7c478bd9Sstevel@tonic-gate extern int optind; /* Indicator of argument */ 167*7c478bd9Sstevel@tonic-gate extern int __xpg4; /* defined in xpg4.c; 0 if not xpg4-compiled program */ 168*7c478bd9Sstevel@tonic-gate 169*7c478bd9Sstevel@tonic-gate struct Fspec { 170*7c478bd9Sstevel@tonic-gate char Ftabs[22]; 171*7c478bd9Sstevel@tonic-gate char Fdel; 172*7c478bd9Sstevel@tonic-gate unsigned char Flim; 173*7c478bd9Sstevel@tonic-gate char Fmov; 174*7c478bd9Sstevel@tonic-gate char Ffill; 175*7c478bd9Sstevel@tonic-gate }; 176*7c478bd9Sstevel@tonic-gate static struct Fspec fss; 177*7c478bd9Sstevel@tonic-gate 178*7c478bd9Sstevel@tonic-gate static char *fsp; 179*7c478bd9Sstevel@tonic-gate static int fsprtn; 180*7c478bd9Sstevel@tonic-gate static char line[70]; 181*7c478bd9Sstevel@tonic-gate static char *linp = line; 182*7c478bd9Sstevel@tonic-gate static int sig; 183*7c478bd9Sstevel@tonic-gate static int Xqt = 0; 184*7c478bd9Sstevel@tonic-gate static int lastc; 185*7c478bd9Sstevel@tonic-gate static char savedfile[FNSIZE]; 186*7c478bd9Sstevel@tonic-gate static char file[FNSIZE]; 187*7c478bd9Sstevel@tonic-gate static char funny[FNSIZE]; 188*7c478bd9Sstevel@tonic-gate static int funlink = 0; 189*7c478bd9Sstevel@tonic-gate static char linebuf[LBSIZE]; 190*7c478bd9Sstevel@tonic-gate static char *tstring = linebuf; 191*7c478bd9Sstevel@tonic-gate 192*7c478bd9Sstevel@tonic-gate static char *expbuf; 193*7c478bd9Sstevel@tonic-gate 194*7c478bd9Sstevel@tonic-gate static char rhsbuf[RHSIZE]; 195*7c478bd9Sstevel@tonic-gate struct lin { 196*7c478bd9Sstevel@tonic-gate long cur; 197*7c478bd9Sstevel@tonic-gate long sav; 198*7c478bd9Sstevel@tonic-gate }; 199*7c478bd9Sstevel@tonic-gate typedef struct lin *LINE; 200*7c478bd9Sstevel@tonic-gate static LINE zero; 201*7c478bd9Sstevel@tonic-gate static LINE dot; 202*7c478bd9Sstevel@tonic-gate static LINE dol; 203*7c478bd9Sstevel@tonic-gate static LINE endcore; 204*7c478bd9Sstevel@tonic-gate static LINE fendcore; 205*7c478bd9Sstevel@tonic-gate static LINE addr1; 206*7c478bd9Sstevel@tonic-gate static LINE addr2; 207*7c478bd9Sstevel@tonic-gate static LINE savdol, savdot; 208*7c478bd9Sstevel@tonic-gate static int globflg; 209*7c478bd9Sstevel@tonic-gate static int initflg; 210*7c478bd9Sstevel@tonic-gate static char genbuf[LBSIZE]; 211*7c478bd9Sstevel@tonic-gate static long count; 212*7c478bd9Sstevel@tonic-gate static int numpass; /* Number of passes thru dosub(). */ 213*7c478bd9Sstevel@tonic-gate static int gsubf; /* Occurrence value. LBSIZE-1=all. */ 214*7c478bd9Sstevel@tonic-gate static int ocerr1; /* Allows lines NOT changed by dosub() to NOT be put */ 215*7c478bd9Sstevel@tonic-gate /* out. Retains last line changed as current line. */ 216*7c478bd9Sstevel@tonic-gate static int ocerr2; /* Flags if ANY line changed by substitute(). 0=nc. */ 217*7c478bd9Sstevel@tonic-gate static char *nextip; 218*7c478bd9Sstevel@tonic-gate static char *linebp; 219*7c478bd9Sstevel@tonic-gate static int ninbuf; 220*7c478bd9Sstevel@tonic-gate static int peekc; 221*7c478bd9Sstevel@tonic-gate static int io; 222*7c478bd9Sstevel@tonic-gate static void (*oldhup)(), (*oldintr)(); 223*7c478bd9Sstevel@tonic-gate static void (*oldquit)(), (*oldpipe)(); 224*7c478bd9Sstevel@tonic-gate static void quit(int); 225*7c478bd9Sstevel@tonic-gate static int vflag = 1; 226*7c478bd9Sstevel@tonic-gate static int xflag; 227*7c478bd9Sstevel@tonic-gate static int xtflag; 228*7c478bd9Sstevel@tonic-gate static int kflag; 229*7c478bd9Sstevel@tonic-gate static int crflag; 230*7c478bd9Sstevel@tonic-gate /* Flag for determining if file being read is encrypted */ 231*7c478bd9Sstevel@tonic-gate static int hflag; 232*7c478bd9Sstevel@tonic-gate static int xcode = -1; 233*7c478bd9Sstevel@tonic-gate static char crbuf[LBSIZE]; 234*7c478bd9Sstevel@tonic-gate static int perm[2]; 235*7c478bd9Sstevel@tonic-gate static int tperm[2]; 236*7c478bd9Sstevel@tonic-gate static int permflag; 237*7c478bd9Sstevel@tonic-gate static int tpermflag; 238*7c478bd9Sstevel@tonic-gate static int col; 239*7c478bd9Sstevel@tonic-gate static char *globp; 240*7c478bd9Sstevel@tonic-gate static int tfile = -1; 241*7c478bd9Sstevel@tonic-gate static int tline; 242*7c478bd9Sstevel@tonic-gate static char *tfname; 243*7c478bd9Sstevel@tonic-gate extern char *locs; 244*7c478bd9Sstevel@tonic-gate static char ibuff[LBSIZE]; 245*7c478bd9Sstevel@tonic-gate static int iblock = -1; 246*7c478bd9Sstevel@tonic-gate static char obuff[LBSIZE]; 247*7c478bd9Sstevel@tonic-gate static int oblock = -1; 248*7c478bd9Sstevel@tonic-gate static int ichanged; 249*7c478bd9Sstevel@tonic-gate static int nleft; 250*7c478bd9Sstevel@tonic-gate static long savnames[26], names[26]; 251*7c478bd9Sstevel@tonic-gate static int anymarks; 252*7c478bd9Sstevel@tonic-gate static long subnewa; 253*7c478bd9Sstevel@tonic-gate static int fchange; 254*7c478bd9Sstevel@tonic-gate static int nline; 255*7c478bd9Sstevel@tonic-gate static int fflg, shflg; 256*7c478bd9Sstevel@tonic-gate static char prompt[16] = "*"; 257*7c478bd9Sstevel@tonic-gate static int rflg; 258*7c478bd9Sstevel@tonic-gate static int readflg; 259*7c478bd9Sstevel@tonic-gate static int eflg; 260*7c478bd9Sstevel@tonic-gate static int qflg = 0; 261*7c478bd9Sstevel@tonic-gate static int ncflg; 262*7c478bd9Sstevel@tonic-gate static int listn; 263*7c478bd9Sstevel@tonic-gate static int listf; 264*7c478bd9Sstevel@tonic-gate static int pflag; 265*7c478bd9Sstevel@tonic-gate static int flag28 = 0; /* Prevents write after a partial read */ 266*7c478bd9Sstevel@tonic-gate static int save28 = 0; /* Flag whether buffer empty at start of read */ 267*7c478bd9Sstevel@tonic-gate static long savtime; 268*7c478bd9Sstevel@tonic-gate static char *name = "SHELL"; 269*7c478bd9Sstevel@tonic-gate static char *rshell = "/usr/lib/rsh"; 270*7c478bd9Sstevel@tonic-gate static char *shpath; /* pointer to correct shell for execution */ 271*7c478bd9Sstevel@tonic-gate /* of execlp() */ 272*7c478bd9Sstevel@tonic-gate static char *val; 273*7c478bd9Sstevel@tonic-gate static char *home; 274*7c478bd9Sstevel@tonic-gate static int nodelim; 275*7c478bd9Sstevel@tonic-gate 276*7c478bd9Sstevel@tonic-gate int makekey(int *); 277*7c478bd9Sstevel@tonic-gate int _mbftowc(char *, wchar_t *, int (*)(), int *); 278*7c478bd9Sstevel@tonic-gate static int error(int code); 279*7c478bd9Sstevel@tonic-gate static void tlist(struct Fspec *); 280*7c478bd9Sstevel@tonic-gate static void tstd(struct Fspec *); 281*7c478bd9Sstevel@tonic-gate static void gdelete(void); 282*7c478bd9Sstevel@tonic-gate static void delete(void); 283*7c478bd9Sstevel@tonic-gate static void exfile(void); 284*7c478bd9Sstevel@tonic-gate static void filename(int comm); 285*7c478bd9Sstevel@tonic-gate static void newline(void); 286*7c478bd9Sstevel@tonic-gate static int gettty(void); 287*7c478bd9Sstevel@tonic-gate static void commands(void); 288*7c478bd9Sstevel@tonic-gate static void undo(void); 289*7c478bd9Sstevel@tonic-gate static void save(void); 290*7c478bd9Sstevel@tonic-gate static void strcopy(char *source, char *dest); 291*7c478bd9Sstevel@tonic-gate static int strequal(char **scan1, char *str); 292*7c478bd9Sstevel@tonic-gate static int stdtab(char *, char *); 293*7c478bd9Sstevel@tonic-gate static int lenchk(char *, struct Fspec *); 294*7c478bd9Sstevel@tonic-gate static void clear(struct Fspec *); 295*7c478bd9Sstevel@tonic-gate static int expnd(char *, char *, int *, struct Fspec *); 296*7c478bd9Sstevel@tonic-gate static void tincr(int, struct Fspec *); 297*7c478bd9Sstevel@tonic-gate static void targ(struct Fspec *); 298*7c478bd9Sstevel@tonic-gate static int numb(void); 299*7c478bd9Sstevel@tonic-gate static int fspec(char *, struct Fspec *, int); 300*7c478bd9Sstevel@tonic-gate static void red(char *); 301*7c478bd9Sstevel@tonic-gate static void newtime(void); 302*7c478bd9Sstevel@tonic-gate static void chktime(void); 303*7c478bd9Sstevel@tonic-gate static void getime(void); 304*7c478bd9Sstevel@tonic-gate static void mkfunny(void); 305*7c478bd9Sstevel@tonic-gate static int eopen(char *, int); 306*7c478bd9Sstevel@tonic-gate static void eclose(int f); 307*7c478bd9Sstevel@tonic-gate static void globaln(int); 308*7c478bd9Sstevel@tonic-gate static char *getkey(const char *); 309*7c478bd9Sstevel@tonic-gate static int execute(int, LINE); 310*7c478bd9Sstevel@tonic-gate static void error1(int); 311*7c478bd9Sstevel@tonic-gate static int getcopy(void); 312*7c478bd9Sstevel@tonic-gate static void move(int); 313*7c478bd9Sstevel@tonic-gate static void dosub(void); 314*7c478bd9Sstevel@tonic-gate static int getsub(void); 315*7c478bd9Sstevel@tonic-gate static int compsub(void); 316*7c478bd9Sstevel@tonic-gate static void substitute(int); 317*7c478bd9Sstevel@tonic-gate static void join(void); 318*7c478bd9Sstevel@tonic-gate static void global(int); 319*7c478bd9Sstevel@tonic-gate static void init(void); 320*7c478bd9Sstevel@tonic-gate static void rdelete(LINE, LINE); 321*7c478bd9Sstevel@tonic-gate static void append(int (*)(void), LINE); 322*7c478bd9Sstevel@tonic-gate static int getfile(void); 323*7c478bd9Sstevel@tonic-gate static void putfile(void); 324*7c478bd9Sstevel@tonic-gate static void onpipe(int); 325*7c478bd9Sstevel@tonic-gate static void onhup(int); 326*7c478bd9Sstevel@tonic-gate static void onintr(int); 327*7c478bd9Sstevel@tonic-gate static void setdot(void); 328*7c478bd9Sstevel@tonic-gate static void setall(void); 329*7c478bd9Sstevel@tonic-gate static void setnoaddr(void); 330*7c478bd9Sstevel@tonic-gate static void nonzero(void); 331*7c478bd9Sstevel@tonic-gate static void setzeroasone(void); 332*7c478bd9Sstevel@tonic-gate static long putline(void); 333*7c478bd9Sstevel@tonic-gate static LINE address(void); 334*7c478bd9Sstevel@tonic-gate static char *getline(long); 335*7c478bd9Sstevel@tonic-gate static char *getblock(long, long); 336*7c478bd9Sstevel@tonic-gate static char *place(char *, char *, char *); 337*7c478bd9Sstevel@tonic-gate static void comple(wchar_t); 338*7c478bd9Sstevel@tonic-gate static void putchr(unsigned char); 339*7c478bd9Sstevel@tonic-gate static void putwchr(wchar_t); 340*7c478bd9Sstevel@tonic-gate static int getchr(void); 341*7c478bd9Sstevel@tonic-gate static void unixcom(void); 342*7c478bd9Sstevel@tonic-gate static void blkio(int, char *, ssize_t (*)()); 343*7c478bd9Sstevel@tonic-gate static void reverse(LINE, LINE); 344*7c478bd9Sstevel@tonic-gate static void putd(); 345*7c478bd9Sstevel@tonic-gate static wchar_t get_wchr(void); 346*7c478bd9Sstevel@tonic-gate 347*7c478bd9Sstevel@tonic-gate static struct stat Fl, Tf; 348*7c478bd9Sstevel@tonic-gate #ifndef RESEARCH 349*7c478bd9Sstevel@tonic-gate static struct statvfs U; 350*7c478bd9Sstevel@tonic-gate static int Short = 0; 351*7c478bd9Sstevel@tonic-gate static mode_t oldmask; /* No umask while writing */ 352*7c478bd9Sstevel@tonic-gate #endif 353*7c478bd9Sstevel@tonic-gate static jmp_buf savej; 354*7c478bd9Sstevel@tonic-gate 355*7c478bd9Sstevel@tonic-gate #ifdef NULLS 356*7c478bd9Sstevel@tonic-gate int nulls; /* Null count */ 357*7c478bd9Sstevel@tonic-gate #endif 358*7c478bd9Sstevel@tonic-gate static long ccount; 359*7c478bd9Sstevel@tonic-gate 360*7c478bd9Sstevel@tonic-gate static int errcnt = 0; 361*7c478bd9Sstevel@tonic-gate 362*7c478bd9Sstevel@tonic-gate 363*7c478bd9Sstevel@tonic-gate static void 364*7c478bd9Sstevel@tonic-gate onpipe(int sig) 365*7c478bd9Sstevel@tonic-gate { 366*7c478bd9Sstevel@tonic-gate (int)error(0); 367*7c478bd9Sstevel@tonic-gate } 368*7c478bd9Sstevel@tonic-gate 369*7c478bd9Sstevel@tonic-gate int 370*7c478bd9Sstevel@tonic-gate main(int argc, char **argv) 371*7c478bd9Sstevel@tonic-gate { 372*7c478bd9Sstevel@tonic-gate char *p1, *p2; 373*7c478bd9Sstevel@tonic-gate int c; 374*7c478bd9Sstevel@tonic-gate 375*7c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 376*7c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 377*7c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ 378*7c478bd9Sstevel@tonic-gate #endif 379*7c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 380*7c478bd9Sstevel@tonic-gate 381*7c478bd9Sstevel@tonic-gate oldquit = signal(SIGQUIT, SIG_IGN); 382*7c478bd9Sstevel@tonic-gate oldhup = signal(SIGHUP, SIG_IGN); 383*7c478bd9Sstevel@tonic-gate oldintr = signal(SIGINT, SIG_IGN); 384*7c478bd9Sstevel@tonic-gate oldpipe = signal(SIGPIPE, onpipe); 385*7c478bd9Sstevel@tonic-gate if (signal(SIGTERM, SIG_IGN) != SIG_IGN) 386*7c478bd9Sstevel@tonic-gate signal(SIGTERM, quit); 387*7c478bd9Sstevel@tonic-gate p1 = *argv; 388*7c478bd9Sstevel@tonic-gate while (*p1++); 389*7c478bd9Sstevel@tonic-gate while (--p1 >= *argv) 390*7c478bd9Sstevel@tonic-gate if (*p1 == '/') 391*7c478bd9Sstevel@tonic-gate break; 392*7c478bd9Sstevel@tonic-gate *argv = p1 + 1; 393*7c478bd9Sstevel@tonic-gate /* if SHELL set in environment and is /usr/lib/rsh, set rflg */ 394*7c478bd9Sstevel@tonic-gate if ((val = getenv(name)) != NULL) 395*7c478bd9Sstevel@tonic-gate if (strcmp(val, rshell) == 0) 396*7c478bd9Sstevel@tonic-gate rflg++; 397*7c478bd9Sstevel@tonic-gate if (**argv == 'r') 398*7c478bd9Sstevel@tonic-gate rflg++; 399*7c478bd9Sstevel@tonic-gate home = getenv("HOME"); 400*7c478bd9Sstevel@tonic-gate while (1) { 401*7c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, "sp:qxC")) != EOF) { 402*7c478bd9Sstevel@tonic-gate switch (c) { 403*7c478bd9Sstevel@tonic-gate 404*7c478bd9Sstevel@tonic-gate case 's': 405*7c478bd9Sstevel@tonic-gate vflag = 0; 406*7c478bd9Sstevel@tonic-gate break; 407*7c478bd9Sstevel@tonic-gate 408*7c478bd9Sstevel@tonic-gate case 'p': 409*7c478bd9Sstevel@tonic-gate strncpy(prompt, optarg, sizeof (prompt)-1); 410*7c478bd9Sstevel@tonic-gate shflg = 1; 411*7c478bd9Sstevel@tonic-gate break; 412*7c478bd9Sstevel@tonic-gate 413*7c478bd9Sstevel@tonic-gate case 'q': 414*7c478bd9Sstevel@tonic-gate signal(SIGQUIT, SIG_DFL); 415*7c478bd9Sstevel@tonic-gate vflag = 1; 416*7c478bd9Sstevel@tonic-gate break; 417*7c478bd9Sstevel@tonic-gate 418*7c478bd9Sstevel@tonic-gate case 'x': 419*7c478bd9Sstevel@tonic-gate crflag = -1; 420*7c478bd9Sstevel@tonic-gate xflag = 1; 421*7c478bd9Sstevel@tonic-gate break; 422*7c478bd9Sstevel@tonic-gate 423*7c478bd9Sstevel@tonic-gate case 'C': 424*7c478bd9Sstevel@tonic-gate crflag = 1; 425*7c478bd9Sstevel@tonic-gate xflag = 1; 426*7c478bd9Sstevel@tonic-gate break; 427*7c478bd9Sstevel@tonic-gate 428*7c478bd9Sstevel@tonic-gate case '?': 429*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 430*7c478bd9Sstevel@tonic-gate "Usage: ed [- | -s] [-p string] [-x] [-C] [file]\n" 431*7c478bd9Sstevel@tonic-gate " red [- | -s] [-p string] [-x] [-C] [file]\n")); 432*7c478bd9Sstevel@tonic-gate exit(2); 433*7c478bd9Sstevel@tonic-gate } 434*7c478bd9Sstevel@tonic-gate } 435*7c478bd9Sstevel@tonic-gate if (argv[optind] && strcmp(argv[optind], "-") == 0 && 436*7c478bd9Sstevel@tonic-gate strcmp(argv[optind-1], "--") != 0) { 437*7c478bd9Sstevel@tonic-gate vflag = 0; 438*7c478bd9Sstevel@tonic-gate optind++; 439*7c478bd9Sstevel@tonic-gate continue; 440*7c478bd9Sstevel@tonic-gate } 441*7c478bd9Sstevel@tonic-gate break; 442*7c478bd9Sstevel@tonic-gate } 443*7c478bd9Sstevel@tonic-gate argc = argc - optind; 444*7c478bd9Sstevel@tonic-gate argv = &argv[optind]; 445*7c478bd9Sstevel@tonic-gate 446*7c478bd9Sstevel@tonic-gate if (xflag) { 447*7c478bd9Sstevel@tonic-gate if (permflag) 448*7c478bd9Sstevel@tonic-gate crypt_close(perm); 449*7c478bd9Sstevel@tonic-gate permflag = 1; 450*7c478bd9Sstevel@tonic-gate if ((kflag = run_setkey(&perm[0], getkey(msgtab[66]))) 451*7c478bd9Sstevel@tonic-gate == -1) { 452*7c478bd9Sstevel@tonic-gate puts(gettext(msgtab[64])); 453*7c478bd9Sstevel@tonic-gate xflag = 0; 454*7c478bd9Sstevel@tonic-gate kflag = 0; 455*7c478bd9Sstevel@tonic-gate } 456*7c478bd9Sstevel@tonic-gate if (kflag == 0) 457*7c478bd9Sstevel@tonic-gate crflag = 0; 458*7c478bd9Sstevel@tonic-gate } 459*7c478bd9Sstevel@tonic-gate 460*7c478bd9Sstevel@tonic-gate if (argc > 0) { 461*7c478bd9Sstevel@tonic-gate p1 = *argv; 462*7c478bd9Sstevel@tonic-gate if (strlen(p1) >= (size_t)FNSIZE) { 463*7c478bd9Sstevel@tonic-gate puts(gettext("file name too long")); 464*7c478bd9Sstevel@tonic-gate if (kflag) 465*7c478bd9Sstevel@tonic-gate crypt_close(perm); 466*7c478bd9Sstevel@tonic-gate exit(2); 467*7c478bd9Sstevel@tonic-gate } 468*7c478bd9Sstevel@tonic-gate p2 = savedfile; 469*7c478bd9Sstevel@tonic-gate while (*p2++ = *p1++); 470*7c478bd9Sstevel@tonic-gate globp = "e"; 471*7c478bd9Sstevel@tonic-gate fflg++; 472*7c478bd9Sstevel@tonic-gate } else /* editing with no file so set savtime to 0 */ 473*7c478bd9Sstevel@tonic-gate savtime = 0; 474*7c478bd9Sstevel@tonic-gate eflg++; 475*7c478bd9Sstevel@tonic-gate if ((tfname = tempnam("", "ea")) == NULL) { 476*7c478bd9Sstevel@tonic-gate puts(gettext(msgtab[69])); 477*7c478bd9Sstevel@tonic-gate exit(2); 478*7c478bd9Sstevel@tonic-gate } 479*7c478bd9Sstevel@tonic-gate 480*7c478bd9Sstevel@tonic-gate fendcore = (LINE)sbrk(0); 481*7c478bd9Sstevel@tonic-gate init(); 482*7c478bd9Sstevel@tonic-gate if (oldintr != SIG_IGN) 483*7c478bd9Sstevel@tonic-gate signal(SIGINT, onintr); 484*7c478bd9Sstevel@tonic-gate if (oldhup != SIG_IGN) 485*7c478bd9Sstevel@tonic-gate signal(SIGHUP, onhup); 486*7c478bd9Sstevel@tonic-gate setjmp(savej); 487*7c478bd9Sstevel@tonic-gate commands(); 488*7c478bd9Sstevel@tonic-gate quit(sig); 489*7c478bd9Sstevel@tonic-gate return (0); 490*7c478bd9Sstevel@tonic-gate } 491*7c478bd9Sstevel@tonic-gate 492*7c478bd9Sstevel@tonic-gate static void 493*7c478bd9Sstevel@tonic-gate commands(void) 494*7c478bd9Sstevel@tonic-gate { 495*7c478bd9Sstevel@tonic-gate LINE a1; 496*7c478bd9Sstevel@tonic-gate int c; 497*7c478bd9Sstevel@tonic-gate char *p1, *p2; 498*7c478bd9Sstevel@tonic-gate int fsave, m, n; 499*7c478bd9Sstevel@tonic-gate 500*7c478bd9Sstevel@tonic-gate for (;;) { 501*7c478bd9Sstevel@tonic-gate nodelim = 0; 502*7c478bd9Sstevel@tonic-gate if (pflag) { 503*7c478bd9Sstevel@tonic-gate pflag = 0; 504*7c478bd9Sstevel@tonic-gate addr1 = addr2 = dot; 505*7c478bd9Sstevel@tonic-gate goto print; 506*7c478bd9Sstevel@tonic-gate } 507*7c478bd9Sstevel@tonic-gate if (shflg && globp == 0) 508*7c478bd9Sstevel@tonic-gate write(1, gettext(prompt), strlen(gettext(prompt))); 509*7c478bd9Sstevel@tonic-gate addr1 = 0; 510*7c478bd9Sstevel@tonic-gate addr2 = 0; 511*7c478bd9Sstevel@tonic-gate if ((c = getchr()) == ',') { 512*7c478bd9Sstevel@tonic-gate addr1 = zero + 1; 513*7c478bd9Sstevel@tonic-gate addr2 = dol; 514*7c478bd9Sstevel@tonic-gate #ifdef XPG6 515*7c478bd9Sstevel@tonic-gate /* XPG4 - it was an error if the second address was */ 516*7c478bd9Sstevel@tonic-gate /* input and the first address was ommitted */ 517*7c478bd9Sstevel@tonic-gate /* Parse second address */ 518*7c478bd9Sstevel@tonic-gate if ((a1 = address()) != 0) { 519*7c478bd9Sstevel@tonic-gate addr2 = a1; 520*7c478bd9Sstevel@tonic-gate } 521*7c478bd9Sstevel@tonic-gate #endif 522*7c478bd9Sstevel@tonic-gate c = getchr(); 523*7c478bd9Sstevel@tonic-gate goto swch; 524*7c478bd9Sstevel@tonic-gate } else if (c == ';') { 525*7c478bd9Sstevel@tonic-gate addr1 = dot; 526*7c478bd9Sstevel@tonic-gate addr2 = dol; 527*7c478bd9Sstevel@tonic-gate #ifdef XPG6 528*7c478bd9Sstevel@tonic-gate /* XPG4 - it was an error if the second address was */ 529*7c478bd9Sstevel@tonic-gate /* input and the first address was ommitted */ 530*7c478bd9Sstevel@tonic-gate /* Parse second address */ 531*7c478bd9Sstevel@tonic-gate if ((a1 = address()) != 0) { 532*7c478bd9Sstevel@tonic-gate addr2 = a1; 533*7c478bd9Sstevel@tonic-gate } 534*7c478bd9Sstevel@tonic-gate #endif 535*7c478bd9Sstevel@tonic-gate c = getchr(); 536*7c478bd9Sstevel@tonic-gate goto swch; 537*7c478bd9Sstevel@tonic-gate } else 538*7c478bd9Sstevel@tonic-gate peekc = c; 539*7c478bd9Sstevel@tonic-gate do { 540*7c478bd9Sstevel@tonic-gate addr1 = addr2; 541*7c478bd9Sstevel@tonic-gate if ((a1 = address()) == 0) { 542*7c478bd9Sstevel@tonic-gate c = getchr(); 543*7c478bd9Sstevel@tonic-gate break; 544*7c478bd9Sstevel@tonic-gate } 545*7c478bd9Sstevel@tonic-gate addr2 = a1; 546*7c478bd9Sstevel@tonic-gate if ((c = getchr()) == ';') { 547*7c478bd9Sstevel@tonic-gate c = ','; 548*7c478bd9Sstevel@tonic-gate dot = a1; 549*7c478bd9Sstevel@tonic-gate } 550*7c478bd9Sstevel@tonic-gate } while (c == ','); 551*7c478bd9Sstevel@tonic-gate if (addr1 == 0) 552*7c478bd9Sstevel@tonic-gate addr1 = addr2; 553*7c478bd9Sstevel@tonic-gate swch: 554*7c478bd9Sstevel@tonic-gate switch (c) { 555*7c478bd9Sstevel@tonic-gate 556*7c478bd9Sstevel@tonic-gate case 'a': 557*7c478bd9Sstevel@tonic-gate setdot(); 558*7c478bd9Sstevel@tonic-gate newline(); 559*7c478bd9Sstevel@tonic-gate if (!globflg) save(); 560*7c478bd9Sstevel@tonic-gate append(gettty, addr2); 561*7c478bd9Sstevel@tonic-gate continue; 562*7c478bd9Sstevel@tonic-gate 563*7c478bd9Sstevel@tonic-gate case 'c': 564*7c478bd9Sstevel@tonic-gate #ifdef XPG6 565*7c478bd9Sstevel@tonic-gate setzeroasone(); 566*7c478bd9Sstevel@tonic-gate #endif 567*7c478bd9Sstevel@tonic-gate delete(); 568*7c478bd9Sstevel@tonic-gate append(gettty, addr1-1); 569*7c478bd9Sstevel@tonic-gate 570*7c478bd9Sstevel@tonic-gate /* XPG4 - If no new lines are inserted, then the current */ 571*7c478bd9Sstevel@tonic-gate /* line becomes the line after the lines deleted. */ 572*7c478bd9Sstevel@tonic-gate 573*7c478bd9Sstevel@tonic-gate if (((linebuf[0] != '.') || (dot == (addr1-1))) && 574*7c478bd9Sstevel@tonic-gate (addr2 <= dol)) 575*7c478bd9Sstevel@tonic-gate dot = addr1; 576*7c478bd9Sstevel@tonic-gate continue; 577*7c478bd9Sstevel@tonic-gate 578*7c478bd9Sstevel@tonic-gate case 'd': 579*7c478bd9Sstevel@tonic-gate delete(); 580*7c478bd9Sstevel@tonic-gate continue; 581*7c478bd9Sstevel@tonic-gate 582*7c478bd9Sstevel@tonic-gate case 'E': 583*7c478bd9Sstevel@tonic-gate fchange = 0; 584*7c478bd9Sstevel@tonic-gate c = 'e'; 585*7c478bd9Sstevel@tonic-gate case 'e': 586*7c478bd9Sstevel@tonic-gate fflg++; 587*7c478bd9Sstevel@tonic-gate setnoaddr(); 588*7c478bd9Sstevel@tonic-gate if (vflag && fchange) { 589*7c478bd9Sstevel@tonic-gate fchange = 0; 590*7c478bd9Sstevel@tonic-gate (void) error(1); 591*7c478bd9Sstevel@tonic-gate } 592*7c478bd9Sstevel@tonic-gate filename(c); 593*7c478bd9Sstevel@tonic-gate eflg++; 594*7c478bd9Sstevel@tonic-gate init(); 595*7c478bd9Sstevel@tonic-gate addr2 = zero; 596*7c478bd9Sstevel@tonic-gate goto caseread; 597*7c478bd9Sstevel@tonic-gate 598*7c478bd9Sstevel@tonic-gate case 'f': 599*7c478bd9Sstevel@tonic-gate setnoaddr(); 600*7c478bd9Sstevel@tonic-gate filename(c); 601*7c478bd9Sstevel@tonic-gate if (!ncflg) /* there is a filename */ 602*7c478bd9Sstevel@tonic-gate getime(); 603*7c478bd9Sstevel@tonic-gate else 604*7c478bd9Sstevel@tonic-gate ncflg--; 605*7c478bd9Sstevel@tonic-gate puts(savedfile); 606*7c478bd9Sstevel@tonic-gate continue; 607*7c478bd9Sstevel@tonic-gate 608*7c478bd9Sstevel@tonic-gate case 'g': 609*7c478bd9Sstevel@tonic-gate global(1); 610*7c478bd9Sstevel@tonic-gate continue; 611*7c478bd9Sstevel@tonic-gate case 'G': 612*7c478bd9Sstevel@tonic-gate globaln(1); 613*7c478bd9Sstevel@tonic-gate continue; 614*7c478bd9Sstevel@tonic-gate 615*7c478bd9Sstevel@tonic-gate case 'h': 616*7c478bd9Sstevel@tonic-gate newline(); 617*7c478bd9Sstevel@tonic-gate setnoaddr(); 618*7c478bd9Sstevel@tonic-gate PUTM(); 619*7c478bd9Sstevel@tonic-gate continue; 620*7c478bd9Sstevel@tonic-gate 621*7c478bd9Sstevel@tonic-gate case 'H': 622*7c478bd9Sstevel@tonic-gate newline(); 623*7c478bd9Sstevel@tonic-gate setnoaddr(); 624*7c478bd9Sstevel@tonic-gate if (!hflag) { 625*7c478bd9Sstevel@tonic-gate hflag = 1; 626*7c478bd9Sstevel@tonic-gate PUTM(); 627*7c478bd9Sstevel@tonic-gate } 628*7c478bd9Sstevel@tonic-gate else 629*7c478bd9Sstevel@tonic-gate hflag = 0; 630*7c478bd9Sstevel@tonic-gate continue; 631*7c478bd9Sstevel@tonic-gate 632*7c478bd9Sstevel@tonic-gate case 'i': 633*7c478bd9Sstevel@tonic-gate #ifdef XPG6 634*7c478bd9Sstevel@tonic-gate setzeroasone(); 635*7c478bd9Sstevel@tonic-gate #endif 636*7c478bd9Sstevel@tonic-gate setdot(); 637*7c478bd9Sstevel@tonic-gate nonzero(); 638*7c478bd9Sstevel@tonic-gate newline(); 639*7c478bd9Sstevel@tonic-gate if (!globflg) save(); 640*7c478bd9Sstevel@tonic-gate append(gettty, addr2-1); 641*7c478bd9Sstevel@tonic-gate if (dot == addr2-1) 642*7c478bd9Sstevel@tonic-gate dot += 1; 643*7c478bd9Sstevel@tonic-gate continue; 644*7c478bd9Sstevel@tonic-gate 645*7c478bd9Sstevel@tonic-gate case 'j': 646*7c478bd9Sstevel@tonic-gate if (addr2 == 0) { 647*7c478bd9Sstevel@tonic-gate addr1 = dot; 648*7c478bd9Sstevel@tonic-gate addr2 = dot+1; 649*7c478bd9Sstevel@tonic-gate } 650*7c478bd9Sstevel@tonic-gate setdot(); 651*7c478bd9Sstevel@tonic-gate newline(); 652*7c478bd9Sstevel@tonic-gate nonzero(); 653*7c478bd9Sstevel@tonic-gate if (!globflg) save(); 654*7c478bd9Sstevel@tonic-gate join(); 655*7c478bd9Sstevel@tonic-gate continue; 656*7c478bd9Sstevel@tonic-gate 657*7c478bd9Sstevel@tonic-gate case 'k': 658*7c478bd9Sstevel@tonic-gate if ((c = getchr()) < 'a' || c > 'z') 659*7c478bd9Sstevel@tonic-gate (void) error(2); 660*7c478bd9Sstevel@tonic-gate newline(); 661*7c478bd9Sstevel@tonic-gate setdot(); 662*7c478bd9Sstevel@tonic-gate nonzero(); 663*7c478bd9Sstevel@tonic-gate names[c-'a'] = addr2->cur & ~01; 664*7c478bd9Sstevel@tonic-gate anymarks |= 01; 665*7c478bd9Sstevel@tonic-gate continue; 666*7c478bd9Sstevel@tonic-gate 667*7c478bd9Sstevel@tonic-gate case 'm': 668*7c478bd9Sstevel@tonic-gate move(0); 669*7c478bd9Sstevel@tonic-gate continue; 670*7c478bd9Sstevel@tonic-gate 671*7c478bd9Sstevel@tonic-gate case '\n': 672*7c478bd9Sstevel@tonic-gate if (addr2 == 0) 673*7c478bd9Sstevel@tonic-gate addr2 = dot+1; 674*7c478bd9Sstevel@tonic-gate addr1 = addr2; 675*7c478bd9Sstevel@tonic-gate goto print; 676*7c478bd9Sstevel@tonic-gate 677*7c478bd9Sstevel@tonic-gate case 'n': 678*7c478bd9Sstevel@tonic-gate listn++; 679*7c478bd9Sstevel@tonic-gate newline(); 680*7c478bd9Sstevel@tonic-gate goto print; 681*7c478bd9Sstevel@tonic-gate 682*7c478bd9Sstevel@tonic-gate case 'l': 683*7c478bd9Sstevel@tonic-gate listf++; 684*7c478bd9Sstevel@tonic-gate case 'p': 685*7c478bd9Sstevel@tonic-gate newline(); 686*7c478bd9Sstevel@tonic-gate print: 687*7c478bd9Sstevel@tonic-gate setdot(); 688*7c478bd9Sstevel@tonic-gate nonzero(); 689*7c478bd9Sstevel@tonic-gate a1 = addr1; 690*7c478bd9Sstevel@tonic-gate do { 691*7c478bd9Sstevel@tonic-gate if (listn) { 692*7c478bd9Sstevel@tonic-gate count = a1 - zero; 693*7c478bd9Sstevel@tonic-gate putd(); 694*7c478bd9Sstevel@tonic-gate putchr('\t'); 695*7c478bd9Sstevel@tonic-gate } 696*7c478bd9Sstevel@tonic-gate puts(getline((a1++)->cur)); 697*7c478bd9Sstevel@tonic-gate } 698*7c478bd9Sstevel@tonic-gate while (a1 <= addr2); 699*7c478bd9Sstevel@tonic-gate dot = addr2; 700*7c478bd9Sstevel@tonic-gate pflag = 0; 701*7c478bd9Sstevel@tonic-gate listn = 0; 702*7c478bd9Sstevel@tonic-gate listf = 0; 703*7c478bd9Sstevel@tonic-gate continue; 704*7c478bd9Sstevel@tonic-gate 705*7c478bd9Sstevel@tonic-gate case 'Q': 706*7c478bd9Sstevel@tonic-gate fchange = 0; 707*7c478bd9Sstevel@tonic-gate case 'q': 708*7c478bd9Sstevel@tonic-gate setnoaddr(); 709*7c478bd9Sstevel@tonic-gate newline(); 710*7c478bd9Sstevel@tonic-gate quit(sig); 711*7c478bd9Sstevel@tonic-gate 712*7c478bd9Sstevel@tonic-gate case 'r': 713*7c478bd9Sstevel@tonic-gate filename(c); 714*7c478bd9Sstevel@tonic-gate caseread: 715*7c478bd9Sstevel@tonic-gate readflg = 1; 716*7c478bd9Sstevel@tonic-gate save28 = (dol != fendcore); 717*7c478bd9Sstevel@tonic-gate if (crflag == 2 || crflag == -2) 718*7c478bd9Sstevel@tonic-gate crflag = -1; /* restore crflag for next file */ 719*7c478bd9Sstevel@tonic-gate errno = 0; 720*7c478bd9Sstevel@tonic-gate if ((io = eopen(file, O_RDONLY)) < 0) { 721*7c478bd9Sstevel@tonic-gate lastc = '\n'; 722*7c478bd9Sstevel@tonic-gate /* if first entering editor and file does not exist */ 723*7c478bd9Sstevel@tonic-gate /* set saved access time to 0 */ 724*7c478bd9Sstevel@tonic-gate if (eflg) { 725*7c478bd9Sstevel@tonic-gate savtime = 0; 726*7c478bd9Sstevel@tonic-gate eflg = 0; 727*7c478bd9Sstevel@tonic-gate if (c == 'e' && vflag == 0) 728*7c478bd9Sstevel@tonic-gate qflg = 1; 729*7c478bd9Sstevel@tonic-gate } 730*7c478bd9Sstevel@tonic-gate if (errno == ENOENT) { 731*7c478bd9Sstevel@tonic-gate (void) error(68); 732*7c478bd9Sstevel@tonic-gate } else { 733*7c478bd9Sstevel@tonic-gate (void) error(3); 734*7c478bd9Sstevel@tonic-gate } 735*7c478bd9Sstevel@tonic-gate } 736*7c478bd9Sstevel@tonic-gate /* get last mod time of file */ 737*7c478bd9Sstevel@tonic-gate /* eflg - entered editor with ed or e */ 738*7c478bd9Sstevel@tonic-gate if (eflg) { 739*7c478bd9Sstevel@tonic-gate eflg = 0; 740*7c478bd9Sstevel@tonic-gate getime(); 741*7c478bd9Sstevel@tonic-gate } 742*7c478bd9Sstevel@tonic-gate setall(); 743*7c478bd9Sstevel@tonic-gate ninbuf = 0; 744*7c478bd9Sstevel@tonic-gate n = zero != dol; 745*7c478bd9Sstevel@tonic-gate #ifdef NULLS 746*7c478bd9Sstevel@tonic-gate nulls = 0; 747*7c478bd9Sstevel@tonic-gate #endif 748*7c478bd9Sstevel@tonic-gate if (!globflg && (c == 'r')) save(); 749*7c478bd9Sstevel@tonic-gate append(getfile, addr2); 750*7c478bd9Sstevel@tonic-gate exfile(); 751*7c478bd9Sstevel@tonic-gate readflg = 0; 752*7c478bd9Sstevel@tonic-gate fchange = n; 753*7c478bd9Sstevel@tonic-gate continue; 754*7c478bd9Sstevel@tonic-gate 755*7c478bd9Sstevel@tonic-gate case 's': 756*7c478bd9Sstevel@tonic-gate setdot(); 757*7c478bd9Sstevel@tonic-gate nonzero(); 758*7c478bd9Sstevel@tonic-gate if (!globflg) save(); 759*7c478bd9Sstevel@tonic-gate substitute(globp != 0); 760*7c478bd9Sstevel@tonic-gate continue; 761*7c478bd9Sstevel@tonic-gate 762*7c478bd9Sstevel@tonic-gate case 't': 763*7c478bd9Sstevel@tonic-gate move(1); 764*7c478bd9Sstevel@tonic-gate continue; 765*7c478bd9Sstevel@tonic-gate 766*7c478bd9Sstevel@tonic-gate case 'u': 767*7c478bd9Sstevel@tonic-gate setdot(); 768*7c478bd9Sstevel@tonic-gate newline(); 769*7c478bd9Sstevel@tonic-gate if (!initflg) 770*7c478bd9Sstevel@tonic-gate undo(); 771*7c478bd9Sstevel@tonic-gate else 772*7c478bd9Sstevel@tonic-gate (void) error(5); 773*7c478bd9Sstevel@tonic-gate fchange = 1; 774*7c478bd9Sstevel@tonic-gate continue; 775*7c478bd9Sstevel@tonic-gate 776*7c478bd9Sstevel@tonic-gate case 'v': 777*7c478bd9Sstevel@tonic-gate global(0); 778*7c478bd9Sstevel@tonic-gate continue; 779*7c478bd9Sstevel@tonic-gate case 'V': 780*7c478bd9Sstevel@tonic-gate globaln(0); 781*7c478bd9Sstevel@tonic-gate continue; 782*7c478bd9Sstevel@tonic-gate 783*7c478bd9Sstevel@tonic-gate case 'W': 784*7c478bd9Sstevel@tonic-gate case 'w': 785*7c478bd9Sstevel@tonic-gate if (flag28) { 786*7c478bd9Sstevel@tonic-gate flag28 = 0; 787*7c478bd9Sstevel@tonic-gate fchange = 0; 788*7c478bd9Sstevel@tonic-gate (void) error(61); 789*7c478bd9Sstevel@tonic-gate } 790*7c478bd9Sstevel@tonic-gate setall(); 791*7c478bd9Sstevel@tonic-gate 792*7c478bd9Sstevel@tonic-gate /* on NULL-RE condition do not generate error */ 793*7c478bd9Sstevel@tonic-gate 794*7c478bd9Sstevel@tonic-gate if ((linebuf[0] != '.') && (zero != dol) && 795*7c478bd9Sstevel@tonic-gate (addr1 <= zero || addr2 > dol)) 796*7c478bd9Sstevel@tonic-gate (void) error(15); 797*7c478bd9Sstevel@tonic-gate filename(c); 798*7c478bd9Sstevel@tonic-gate if (Xqt) { 799*7c478bd9Sstevel@tonic-gate io = eopen(file, O_WRONLY); 800*7c478bd9Sstevel@tonic-gate n = 1; /* set n so newtime will not execute */ 801*7c478bd9Sstevel@tonic-gate } else { 802*7c478bd9Sstevel@tonic-gate struct stat lFl; 803*7c478bd9Sstevel@tonic-gate fstat(tfile, &Tf); 804*7c478bd9Sstevel@tonic-gate if (stat(file, &Fl) < 0) { 805*7c478bd9Sstevel@tonic-gate if ((io = creat(file, S_IRUSR|S_IWUSR|S_IRGRP 806*7c478bd9Sstevel@tonic-gate |S_IWGRP|S_IROTH|S_IWOTH)) < 0) 807*7c478bd9Sstevel@tonic-gate (void) error(7); 808*7c478bd9Sstevel@tonic-gate fstat(io, &Fl); 809*7c478bd9Sstevel@tonic-gate Fl.st_mtime = 0; 810*7c478bd9Sstevel@tonic-gate lFl = Fl; 811*7c478bd9Sstevel@tonic-gate close(io); 812*7c478bd9Sstevel@tonic-gate } else { 813*7c478bd9Sstevel@tonic-gate #ifndef RESEARCH 814*7c478bd9Sstevel@tonic-gate oldmask = umask(0); 815*7c478bd9Sstevel@tonic-gate /* 816*7c478bd9Sstevel@tonic-gate * Must determine if file is 817*7c478bd9Sstevel@tonic-gate * a symbolic link 818*7c478bd9Sstevel@tonic-gate */ 819*7c478bd9Sstevel@tonic-gate lstat(file, &lFl); 820*7c478bd9Sstevel@tonic-gate #endif 821*7c478bd9Sstevel@tonic-gate } 822*7c478bd9Sstevel@tonic-gate #ifndef RESEARCH 823*7c478bd9Sstevel@tonic-gate /* 824*7c478bd9Sstevel@tonic-gate * Determine if there are enough free blocks on system 825*7c478bd9Sstevel@tonic-gate */ 826*7c478bd9Sstevel@tonic-gate if (!Short && statvfs(file, &U) == 0 && 827*7c478bd9Sstevel@tonic-gate U.f_bfree < ((Tf.st_size/U.f_frsize) + 100)) { 828*7c478bd9Sstevel@tonic-gate Short = 1; 829*7c478bd9Sstevel@tonic-gate (void) error(8); 830*7c478bd9Sstevel@tonic-gate } 831*7c478bd9Sstevel@tonic-gate Short = 0; 832*7c478bd9Sstevel@tonic-gate #endif 833*7c478bd9Sstevel@tonic-gate p1 = savedfile; /* The current filename */ 834*7c478bd9Sstevel@tonic-gate p2 = file; 835*7c478bd9Sstevel@tonic-gate m = strcmp(p1, p2); 836*7c478bd9Sstevel@tonic-gate if (c == 'w' && Fl.st_nlink == 1 && ISREG(lFl)) { 837*7c478bd9Sstevel@tonic-gate if (close(open(file, O_WRONLY)) < 0) 838*7c478bd9Sstevel@tonic-gate (void) error(9); 839*7c478bd9Sstevel@tonic-gate if (!(n = m)) 840*7c478bd9Sstevel@tonic-gate chktime(); 841*7c478bd9Sstevel@tonic-gate mkfunny(); 842*7c478bd9Sstevel@tonic-gate /* 843*7c478bd9Sstevel@tonic-gate * If funlink equals one it means that 844*7c478bd9Sstevel@tonic-gate * funny points to a valid file which must 845*7c478bd9Sstevel@tonic-gate * be unlinked when interrupted. 846*7c478bd9Sstevel@tonic-gate */ 847*7c478bd9Sstevel@tonic-gate 848*7c478bd9Sstevel@tonic-gate funlink = 1; 849*7c478bd9Sstevel@tonic-gate if ((io = creat(funny, FMODE(Fl))) >= 0) { 850*7c478bd9Sstevel@tonic-gate chown(funny, Fl.st_uid, Fl.st_gid); 851*7c478bd9Sstevel@tonic-gate chmod(funny, FMODE(Fl)); 852*7c478bd9Sstevel@tonic-gate putfile(); 853*7c478bd9Sstevel@tonic-gate exfile(); 854*7c478bd9Sstevel@tonic-gate 855*7c478bd9Sstevel@tonic-gate if (rename(funny, file)) 856*7c478bd9Sstevel@tonic-gate (void) error(10); 857*7c478bd9Sstevel@tonic-gate funlink = 0; 858*7c478bd9Sstevel@tonic-gate /* if filenames are the same */ 859*7c478bd9Sstevel@tonic-gate if (!n) 860*7c478bd9Sstevel@tonic-gate newtime(); 861*7c478bd9Sstevel@tonic-gate /* check if entire buffer was written */ 862*7c478bd9Sstevel@tonic-gate fsave = fchange; 863*7c478bd9Sstevel@tonic-gate fchange = (((addr1 == zero) || (addr1 == (zero + 1))) && 864*7c478bd9Sstevel@tonic-gate (addr2 == dol)) ? 0 : 1; 865*7c478bd9Sstevel@tonic-gate if (fchange == 1 && m != 0) fchange = fsave; 866*7c478bd9Sstevel@tonic-gate continue; 867*7c478bd9Sstevel@tonic-gate } 868*7c478bd9Sstevel@tonic-gate } else 869*7c478bd9Sstevel@tonic-gate n = 1; /* set n so newtime will not execute */ 870*7c478bd9Sstevel@tonic-gate if ((io = open(file, 871*7c478bd9Sstevel@tonic-gate (c == 'w') ? O_WRONLY|O_CREAT|O_TRUNC 872*7c478bd9Sstevel@tonic-gate : O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR 873*7c478bd9Sstevel@tonic-gate |S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) < 0) 874*7c478bd9Sstevel@tonic-gate (void) error(7); 875*7c478bd9Sstevel@tonic-gate } 876*7c478bd9Sstevel@tonic-gate putfile(); 877*7c478bd9Sstevel@tonic-gate exfile(); 878*7c478bd9Sstevel@tonic-gate if (!n) newtime(); 879*7c478bd9Sstevel@tonic-gate fsave = fchange; 880*7c478bd9Sstevel@tonic-gate fchange = (((addr1 == zero) || (addr1 == (zero + 1))) && 881*7c478bd9Sstevel@tonic-gate (addr2 == dol)) ? 0 : 1; 882*7c478bd9Sstevel@tonic-gate /* Leave fchange alone if partial write was to another file */ 883*7c478bd9Sstevel@tonic-gate if (fchange == 1 && m != 0) fchange = fsave; 884*7c478bd9Sstevel@tonic-gate continue; 885*7c478bd9Sstevel@tonic-gate 886*7c478bd9Sstevel@tonic-gate case 'C': 887*7c478bd9Sstevel@tonic-gate crflag = 1; 888*7c478bd9Sstevel@tonic-gate /* 889*7c478bd9Sstevel@tonic-gate * C is same as X, but always assume input files are 890*7c478bd9Sstevel@tonic-gate * ciphertext 891*7c478bd9Sstevel@tonic-gate */ 892*7c478bd9Sstevel@tonic-gate goto encrypt; 893*7c478bd9Sstevel@tonic-gate 894*7c478bd9Sstevel@tonic-gate case 'X': 895*7c478bd9Sstevel@tonic-gate crflag = -1; 896*7c478bd9Sstevel@tonic-gate encrypt: 897*7c478bd9Sstevel@tonic-gate setnoaddr(); 898*7c478bd9Sstevel@tonic-gate newline(); 899*7c478bd9Sstevel@tonic-gate xflag = 1; 900*7c478bd9Sstevel@tonic-gate if (permflag) 901*7c478bd9Sstevel@tonic-gate (void) crypt_close(perm); 902*7c478bd9Sstevel@tonic-gate permflag = 1; 903*7c478bd9Sstevel@tonic-gate if ((kflag = run_setkey(&perm[0], getkey(msgtab[66]))) 904*7c478bd9Sstevel@tonic-gate == -1) { 905*7c478bd9Sstevel@tonic-gate xflag = 0; 906*7c478bd9Sstevel@tonic-gate kflag = 0; 907*7c478bd9Sstevel@tonic-gate crflag = 0; 908*7c478bd9Sstevel@tonic-gate (void) error(64); 909*7c478bd9Sstevel@tonic-gate } 910*7c478bd9Sstevel@tonic-gate if (kflag == 0) 911*7c478bd9Sstevel@tonic-gate crflag = 0; 912*7c478bd9Sstevel@tonic-gate continue; 913*7c478bd9Sstevel@tonic-gate 914*7c478bd9Sstevel@tonic-gate case '=': 915*7c478bd9Sstevel@tonic-gate setall(); 916*7c478bd9Sstevel@tonic-gate newline(); 917*7c478bd9Sstevel@tonic-gate count = (addr2-zero)&077777; 918*7c478bd9Sstevel@tonic-gate putd(); 919*7c478bd9Sstevel@tonic-gate putchr('\n'); 920*7c478bd9Sstevel@tonic-gate continue; 921*7c478bd9Sstevel@tonic-gate 922*7c478bd9Sstevel@tonic-gate case '!': 923*7c478bd9Sstevel@tonic-gate unixcom(); 924*7c478bd9Sstevel@tonic-gate continue; 925*7c478bd9Sstevel@tonic-gate 926*7c478bd9Sstevel@tonic-gate case EOF: 927*7c478bd9Sstevel@tonic-gate return; 928*7c478bd9Sstevel@tonic-gate 929*7c478bd9Sstevel@tonic-gate case 'P': 930*7c478bd9Sstevel@tonic-gate setnoaddr(); 931*7c478bd9Sstevel@tonic-gate newline(); 932*7c478bd9Sstevel@tonic-gate if (shflg) 933*7c478bd9Sstevel@tonic-gate shflg = 0; 934*7c478bd9Sstevel@tonic-gate else 935*7c478bd9Sstevel@tonic-gate shflg++; 936*7c478bd9Sstevel@tonic-gate continue; 937*7c478bd9Sstevel@tonic-gate } 938*7c478bd9Sstevel@tonic-gate if (c == 'x') 939*7c478bd9Sstevel@tonic-gate (void) error(60); 940*7c478bd9Sstevel@tonic-gate else 941*7c478bd9Sstevel@tonic-gate (void) error(12); 942*7c478bd9Sstevel@tonic-gate } 943*7c478bd9Sstevel@tonic-gate } 944*7c478bd9Sstevel@tonic-gate 945*7c478bd9Sstevel@tonic-gate LINE 946*7c478bd9Sstevel@tonic-gate address(void) 947*7c478bd9Sstevel@tonic-gate { 948*7c478bd9Sstevel@tonic-gate int minus, c; 949*7c478bd9Sstevel@tonic-gate LINE a1; 950*7c478bd9Sstevel@tonic-gate int n, relerr, retval; 951*7c478bd9Sstevel@tonic-gate 952*7c478bd9Sstevel@tonic-gate minus = 0; 953*7c478bd9Sstevel@tonic-gate a1 = 0; 954*7c478bd9Sstevel@tonic-gate for (;;) { 955*7c478bd9Sstevel@tonic-gate c = getchr(); 956*7c478bd9Sstevel@tonic-gate if ('0' <= c && c <= '9') { 957*7c478bd9Sstevel@tonic-gate n = 0; 958*7c478bd9Sstevel@tonic-gate do { 959*7c478bd9Sstevel@tonic-gate n *= 10; 960*7c478bd9Sstevel@tonic-gate n += c - '0'; 961*7c478bd9Sstevel@tonic-gate } while ((c = getchr()) >= '0' && c <= '9'); 962*7c478bd9Sstevel@tonic-gate peekc = c; 963*7c478bd9Sstevel@tonic-gate if (a1 == 0) 964*7c478bd9Sstevel@tonic-gate a1 = zero; 965*7c478bd9Sstevel@tonic-gate if (minus < 0) 966*7c478bd9Sstevel@tonic-gate n = -n; 967*7c478bd9Sstevel@tonic-gate a1 += n; 968*7c478bd9Sstevel@tonic-gate minus = 0; 969*7c478bd9Sstevel@tonic-gate continue; 970*7c478bd9Sstevel@tonic-gate } 971*7c478bd9Sstevel@tonic-gate relerr = 0; 972*7c478bd9Sstevel@tonic-gate if (a1 || minus) 973*7c478bd9Sstevel@tonic-gate relerr++; 974*7c478bd9Sstevel@tonic-gate switch (c) { 975*7c478bd9Sstevel@tonic-gate case ' ': 976*7c478bd9Sstevel@tonic-gate case '\t': 977*7c478bd9Sstevel@tonic-gate continue; 978*7c478bd9Sstevel@tonic-gate 979*7c478bd9Sstevel@tonic-gate case '+': 980*7c478bd9Sstevel@tonic-gate minus++; 981*7c478bd9Sstevel@tonic-gate if (a1 == 0) 982*7c478bd9Sstevel@tonic-gate a1 = dot; 983*7c478bd9Sstevel@tonic-gate continue; 984*7c478bd9Sstevel@tonic-gate 985*7c478bd9Sstevel@tonic-gate case '-': 986*7c478bd9Sstevel@tonic-gate case '^': 987*7c478bd9Sstevel@tonic-gate minus--; 988*7c478bd9Sstevel@tonic-gate if (a1 == 0) 989*7c478bd9Sstevel@tonic-gate a1 = dot; 990*7c478bd9Sstevel@tonic-gate continue; 991*7c478bd9Sstevel@tonic-gate 992*7c478bd9Sstevel@tonic-gate case '?': 993*7c478bd9Sstevel@tonic-gate case '/': 994*7c478bd9Sstevel@tonic-gate comple(c); 995*7c478bd9Sstevel@tonic-gate a1 = dot; 996*7c478bd9Sstevel@tonic-gate for (;;) { 997*7c478bd9Sstevel@tonic-gate if (c == '/') { 998*7c478bd9Sstevel@tonic-gate a1++; 999*7c478bd9Sstevel@tonic-gate if (a1 > dol) 1000*7c478bd9Sstevel@tonic-gate a1 = zero; 1001*7c478bd9Sstevel@tonic-gate } else { 1002*7c478bd9Sstevel@tonic-gate a1--; 1003*7c478bd9Sstevel@tonic-gate if (a1 < zero) 1004*7c478bd9Sstevel@tonic-gate a1 = dol; 1005*7c478bd9Sstevel@tonic-gate } 1006*7c478bd9Sstevel@tonic-gate 1007*7c478bd9Sstevel@tonic-gate if (execute(0, a1)) 1008*7c478bd9Sstevel@tonic-gate break; 1009*7c478bd9Sstevel@tonic-gate if (a1 == dot) 1010*7c478bd9Sstevel@tonic-gate (void) error(13); 1011*7c478bd9Sstevel@tonic-gate } 1012*7c478bd9Sstevel@tonic-gate break; 1013*7c478bd9Sstevel@tonic-gate 1014*7c478bd9Sstevel@tonic-gate case '$': 1015*7c478bd9Sstevel@tonic-gate a1 = dol; 1016*7c478bd9Sstevel@tonic-gate break; 1017*7c478bd9Sstevel@tonic-gate 1018*7c478bd9Sstevel@tonic-gate case '.': 1019*7c478bd9Sstevel@tonic-gate a1 = dot; 1020*7c478bd9Sstevel@tonic-gate break; 1021*7c478bd9Sstevel@tonic-gate 1022*7c478bd9Sstevel@tonic-gate case '\'': 1023*7c478bd9Sstevel@tonic-gate if ((c = getchr()) < 'a' || c > 'z') 1024*7c478bd9Sstevel@tonic-gate (void) error(2); 1025*7c478bd9Sstevel@tonic-gate for (a1 = zero; a1 <= dol; a1++) 1026*7c478bd9Sstevel@tonic-gate if (names[c-'a'] == (a1->cur & ~01)) 1027*7c478bd9Sstevel@tonic-gate break; 1028*7c478bd9Sstevel@tonic-gate break; 1029*7c478bd9Sstevel@tonic-gate 1030*7c478bd9Sstevel@tonic-gate default: 1031*7c478bd9Sstevel@tonic-gate peekc = c; 1032*7c478bd9Sstevel@tonic-gate if (a1 == 0) 1033*7c478bd9Sstevel@tonic-gate return (0); 1034*7c478bd9Sstevel@tonic-gate a1 += minus; 1035*7c478bd9Sstevel@tonic-gate 1036*7c478bd9Sstevel@tonic-gate /* on NULL-RE condition do not generate error */ 1037*7c478bd9Sstevel@tonic-gate 1038*7c478bd9Sstevel@tonic-gate if ((linebuf[0] != '.') && (a1 < zero || a1 > dol)) 1039*7c478bd9Sstevel@tonic-gate (void) error(15); 1040*7c478bd9Sstevel@tonic-gate return (a1); 1041*7c478bd9Sstevel@tonic-gate } 1042*7c478bd9Sstevel@tonic-gate if (relerr) 1043*7c478bd9Sstevel@tonic-gate (void) error(16); 1044*7c478bd9Sstevel@tonic-gate } 1045*7c478bd9Sstevel@tonic-gate } 1046*7c478bd9Sstevel@tonic-gate 1047*7c478bd9Sstevel@tonic-gate static void 1048*7c478bd9Sstevel@tonic-gate setdot(void) 1049*7c478bd9Sstevel@tonic-gate { 1050*7c478bd9Sstevel@tonic-gate if (addr2 == 0) 1051*7c478bd9Sstevel@tonic-gate addr1 = addr2 = dot; 1052*7c478bd9Sstevel@tonic-gate if (addr1 > addr2) 1053*7c478bd9Sstevel@tonic-gate (void) error(17); 1054*7c478bd9Sstevel@tonic-gate } 1055*7c478bd9Sstevel@tonic-gate 1056*7c478bd9Sstevel@tonic-gate static void 1057*7c478bd9Sstevel@tonic-gate setall(void) 1058*7c478bd9Sstevel@tonic-gate { 1059*7c478bd9Sstevel@tonic-gate if (addr2 == 0) { 1060*7c478bd9Sstevel@tonic-gate addr1 = zero+1; 1061*7c478bd9Sstevel@tonic-gate addr2 = dol; 1062*7c478bd9Sstevel@tonic-gate if (dol == zero) 1063*7c478bd9Sstevel@tonic-gate addr1 = zero; 1064*7c478bd9Sstevel@tonic-gate } 1065*7c478bd9Sstevel@tonic-gate setdot(); 1066*7c478bd9Sstevel@tonic-gate } 1067*7c478bd9Sstevel@tonic-gate 1068*7c478bd9Sstevel@tonic-gate static void 1069*7c478bd9Sstevel@tonic-gate setnoaddr(void) 1070*7c478bd9Sstevel@tonic-gate { 1071*7c478bd9Sstevel@tonic-gate if (addr2) 1072*7c478bd9Sstevel@tonic-gate (void) error(18); 1073*7c478bd9Sstevel@tonic-gate } 1074*7c478bd9Sstevel@tonic-gate 1075*7c478bd9Sstevel@tonic-gate static void 1076*7c478bd9Sstevel@tonic-gate nonzero(void) 1077*7c478bd9Sstevel@tonic-gate { 1078*7c478bd9Sstevel@tonic-gate /* on NULL-RE condition do not generate error */ 1079*7c478bd9Sstevel@tonic-gate 1080*7c478bd9Sstevel@tonic-gate if ((linebuf[0] != '.') && (addr1 <= zero || addr2 > dol)) 1081*7c478bd9Sstevel@tonic-gate (void) error(15); 1082*7c478bd9Sstevel@tonic-gate } 1083*7c478bd9Sstevel@tonic-gate 1084*7c478bd9Sstevel@tonic-gate static void 1085*7c478bd9Sstevel@tonic-gate setzeroasone(void) 1086*7c478bd9Sstevel@tonic-gate { 1087*7c478bd9Sstevel@tonic-gate /* for the c and i commands 0 equal to 1 address */ 1088*7c478bd9Sstevel@tonic-gate if (addr1 == zero) { 1089*7c478bd9Sstevel@tonic-gate addr1 = zero+1; 1090*7c478bd9Sstevel@tonic-gate } 1091*7c478bd9Sstevel@tonic-gate if (addr2 == zero) { 1092*7c478bd9Sstevel@tonic-gate addr2 = zero+1; 1093*7c478bd9Sstevel@tonic-gate } 1094*7c478bd9Sstevel@tonic-gate } 1095*7c478bd9Sstevel@tonic-gate 1096*7c478bd9Sstevel@tonic-gate 1097*7c478bd9Sstevel@tonic-gate static void 1098*7c478bd9Sstevel@tonic-gate newline(void) 1099*7c478bd9Sstevel@tonic-gate { 1100*7c478bd9Sstevel@tonic-gate int c; 1101*7c478bd9Sstevel@tonic-gate 1102*7c478bd9Sstevel@tonic-gate if ((c = getchr()) == '\n') 1103*7c478bd9Sstevel@tonic-gate return; 1104*7c478bd9Sstevel@tonic-gate if (c == 'p' || c == 'l' || c == 'n') { 1105*7c478bd9Sstevel@tonic-gate pflag++; 1106*7c478bd9Sstevel@tonic-gate if (c == 'l') listf++; 1107*7c478bd9Sstevel@tonic-gate if (c == 'n') listn++; 1108*7c478bd9Sstevel@tonic-gate if ((c = getchr()) == '\n') 1109*7c478bd9Sstevel@tonic-gate return; 1110*7c478bd9Sstevel@tonic-gate } 1111*7c478bd9Sstevel@tonic-gate (void) error(20); 1112*7c478bd9Sstevel@tonic-gate } 1113*7c478bd9Sstevel@tonic-gate 1114*7c478bd9Sstevel@tonic-gate static void 1115*7c478bd9Sstevel@tonic-gate filename(int comm) 1116*7c478bd9Sstevel@tonic-gate { 1117*7c478bd9Sstevel@tonic-gate char *p1, *p2; 1118*7c478bd9Sstevel@tonic-gate int c; 1119*7c478bd9Sstevel@tonic-gate int i = 0; 1120*7c478bd9Sstevel@tonic-gate 1121*7c478bd9Sstevel@tonic-gate count = 0; 1122*7c478bd9Sstevel@tonic-gate c = getchr(); 1123*7c478bd9Sstevel@tonic-gate if (c == '\n' || c == EOF) { 1124*7c478bd9Sstevel@tonic-gate p1 = savedfile; 1125*7c478bd9Sstevel@tonic-gate if (*p1 == 0 && comm != 'f') 1126*7c478bd9Sstevel@tonic-gate (void) error(21); 1127*7c478bd9Sstevel@tonic-gate /* ncflg set means do not get mod time of file */ 1128*7c478bd9Sstevel@tonic-gate /* since no filename followed f */ 1129*7c478bd9Sstevel@tonic-gate if (comm == 'f') 1130*7c478bd9Sstevel@tonic-gate ncflg++; 1131*7c478bd9Sstevel@tonic-gate p2 = file; 1132*7c478bd9Sstevel@tonic-gate while (*p2++ = *p1++); 1133*7c478bd9Sstevel@tonic-gate red(savedfile); 1134*7c478bd9Sstevel@tonic-gate return; 1135*7c478bd9Sstevel@tonic-gate } 1136*7c478bd9Sstevel@tonic-gate if (c != ' ') 1137*7c478bd9Sstevel@tonic-gate (void) error(22); 1138*7c478bd9Sstevel@tonic-gate while ((c = getchr()) == ' '); 1139*7c478bd9Sstevel@tonic-gate if (c == '!') 1140*7c478bd9Sstevel@tonic-gate ++Xqt, c = getchr(); 1141*7c478bd9Sstevel@tonic-gate if (c == '\n') 1142*7c478bd9Sstevel@tonic-gate (void) error(21); 1143*7c478bd9Sstevel@tonic-gate p1 = file; 1144*7c478bd9Sstevel@tonic-gate do { 1145*7c478bd9Sstevel@tonic-gate if (++i >= FNSIZE) 1146*7c478bd9Sstevel@tonic-gate (void) error(24); 1147*7c478bd9Sstevel@tonic-gate *p1++ = c; 1148*7c478bd9Sstevel@tonic-gate if (c == EOF || (c == ' ' && !Xqt)) 1149*7c478bd9Sstevel@tonic-gate (void) error(21); 1150*7c478bd9Sstevel@tonic-gate } while ((c = getchr()) != '\n'); 1151*7c478bd9Sstevel@tonic-gate *p1++ = 0; 1152*7c478bd9Sstevel@tonic-gate if (Xqt) 1153*7c478bd9Sstevel@tonic-gate if (comm == 'f') { 1154*7c478bd9Sstevel@tonic-gate --Xqt; 1155*7c478bd9Sstevel@tonic-gate (void) error(57); 1156*7c478bd9Sstevel@tonic-gate } 1157*7c478bd9Sstevel@tonic-gate else 1158*7c478bd9Sstevel@tonic-gate return; 1159*7c478bd9Sstevel@tonic-gate if (savedfile[0] == 0 || comm == 'e' || comm == 'f') { 1160*7c478bd9Sstevel@tonic-gate p1 = savedfile; 1161*7c478bd9Sstevel@tonic-gate p2 = file; 1162*7c478bd9Sstevel@tonic-gate while (*p1++ = *p2++); 1163*7c478bd9Sstevel@tonic-gate } 1164*7c478bd9Sstevel@tonic-gate red(file); 1165*7c478bd9Sstevel@tonic-gate } 1166*7c478bd9Sstevel@tonic-gate 1167*7c478bd9Sstevel@tonic-gate 1168*7c478bd9Sstevel@tonic-gate static void 1169*7c478bd9Sstevel@tonic-gate exfile(void) 1170*7c478bd9Sstevel@tonic-gate { 1171*7c478bd9Sstevel@tonic-gate #ifdef NULLS 1172*7c478bd9Sstevel@tonic-gate int c; 1173*7c478bd9Sstevel@tonic-gate #endif 1174*7c478bd9Sstevel@tonic-gate 1175*7c478bd9Sstevel@tonic-gate #ifndef RESEARCH 1176*7c478bd9Sstevel@tonic-gate if (oldmask) { 1177*7c478bd9Sstevel@tonic-gate umask(oldmask); 1178*7c478bd9Sstevel@tonic-gate oldmask = 0; 1179*7c478bd9Sstevel@tonic-gate } 1180*7c478bd9Sstevel@tonic-gate #endif 1181*7c478bd9Sstevel@tonic-gate eclose(io); 1182*7c478bd9Sstevel@tonic-gate io = -1; 1183*7c478bd9Sstevel@tonic-gate if (vflag) { 1184*7c478bd9Sstevel@tonic-gate putd(); 1185*7c478bd9Sstevel@tonic-gate putchr('\n'); 1186*7c478bd9Sstevel@tonic-gate #ifdef NULLS 1187*7c478bd9Sstevel@tonic-gate if (nulls) { 1188*7c478bd9Sstevel@tonic-gate c = count; 1189*7c478bd9Sstevel@tonic-gate count = nulls; 1190*7c478bd9Sstevel@tonic-gate nulls = 0; 1191*7c478bd9Sstevel@tonic-gate putd(); 1192*7c478bd9Sstevel@tonic-gate puts(gettext(" nulls replaced by '\\0'")); 1193*7c478bd9Sstevel@tonic-gate count = c; 1194*7c478bd9Sstevel@tonic-gate } 1195*7c478bd9Sstevel@tonic-gate #endif 1196*7c478bd9Sstevel@tonic-gate } 1197*7c478bd9Sstevel@tonic-gate } 1198*7c478bd9Sstevel@tonic-gate 1199*7c478bd9Sstevel@tonic-gate static void 1200*7c478bd9Sstevel@tonic-gate onintr(int sig) 1201*7c478bd9Sstevel@tonic-gate { 1202*7c478bd9Sstevel@tonic-gate signal(SIGINT, onintr); 1203*7c478bd9Sstevel@tonic-gate putchr('\n'); 1204*7c478bd9Sstevel@tonic-gate lastc = '\n'; 1205*7c478bd9Sstevel@tonic-gate globflg = 0; 1206*7c478bd9Sstevel@tonic-gate if (funlink) unlink(funny); /* remove tmp file */ 1207*7c478bd9Sstevel@tonic-gate /* if interrupted a read, only part of file may be in buffer */ 1208*7c478bd9Sstevel@tonic-gate if (readflg) { 1209*7c478bd9Sstevel@tonic-gate sprintf(tstring, "\007read may be incomplete - beware!\007"); 1210*7c478bd9Sstevel@tonic-gate puts(gettext(tstring)); 1211*7c478bd9Sstevel@tonic-gate fchange = 0; 1212*7c478bd9Sstevel@tonic-gate } 1213*7c478bd9Sstevel@tonic-gate (void) error(26); 1214*7c478bd9Sstevel@tonic-gate } 1215*7c478bd9Sstevel@tonic-gate 1216*7c478bd9Sstevel@tonic-gate static void 1217*7c478bd9Sstevel@tonic-gate onhup(int sig) 1218*7c478bd9Sstevel@tonic-gate { 1219*7c478bd9Sstevel@tonic-gate signal(SIGINT, SIG_IGN); 1220*7c478bd9Sstevel@tonic-gate signal(SIGHUP, SIG_IGN); 1221*7c478bd9Sstevel@tonic-gate /* 1222*7c478bd9Sstevel@tonic-gate * if there are lines in file and file was not written 1223*7c478bd9Sstevel@tonic-gate * since last update, save in ed.hup, or $HOME/ed.hup 1224*7c478bd9Sstevel@tonic-gate */ 1225*7c478bd9Sstevel@tonic-gate if (dol > zero && fchange == 1) { 1226*7c478bd9Sstevel@tonic-gate addr1 = zero+1; 1227*7c478bd9Sstevel@tonic-gate addr2 = dol; 1228*7c478bd9Sstevel@tonic-gate io = creat("ed.hup", 1229*7c478bd9Sstevel@tonic-gate S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH); 1230*7c478bd9Sstevel@tonic-gate if (io < 0 && home) { 1231*7c478bd9Sstevel@tonic-gate char *fn; 1232*7c478bd9Sstevel@tonic-gate 1233*7c478bd9Sstevel@tonic-gate fn = (char *)calloc(strlen(home) + 8, sizeof (char)); 1234*7c478bd9Sstevel@tonic-gate if (fn) { 1235*7c478bd9Sstevel@tonic-gate strcpy(fn, home); 1236*7c478bd9Sstevel@tonic-gate strcat(fn, "/ed.hup"); 1237*7c478bd9Sstevel@tonic-gate io = creat(fn, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP 1238*7c478bd9Sstevel@tonic-gate |S_IROTH|S_IWOTH); 1239*7c478bd9Sstevel@tonic-gate free(fn); 1240*7c478bd9Sstevel@tonic-gate } 1241*7c478bd9Sstevel@tonic-gate } 1242*7c478bd9Sstevel@tonic-gate if (io > 0) 1243*7c478bd9Sstevel@tonic-gate putfile(); 1244*7c478bd9Sstevel@tonic-gate } 1245*7c478bd9Sstevel@tonic-gate fchange = 0; 1246*7c478bd9Sstevel@tonic-gate ++errcnt; 1247*7c478bd9Sstevel@tonic-gate quit(sig); 1248*7c478bd9Sstevel@tonic-gate } 1249*7c478bd9Sstevel@tonic-gate 1250*7c478bd9Sstevel@tonic-gate static int 1251*7c478bd9Sstevel@tonic-gate error(int code) 1252*7c478bd9Sstevel@tonic-gate { 1253*7c478bd9Sstevel@tonic-gate int c; 1254*7c478bd9Sstevel@tonic-gate 1255*7c478bd9Sstevel@tonic-gate if (code == 28 && save28 == 0) { 1256*7c478bd9Sstevel@tonic-gate fchange = 0; 1257*7c478bd9Sstevel@tonic-gate flag28++; 1258*7c478bd9Sstevel@tonic-gate } 1259*7c478bd9Sstevel@tonic-gate readflg = 0; 1260*7c478bd9Sstevel@tonic-gate ++errcnt; 1261*7c478bd9Sstevel@tonic-gate listf = listn = 0; 1262*7c478bd9Sstevel@tonic-gate pflag = 0; 1263*7c478bd9Sstevel@tonic-gate #ifndef RESEARCH 1264*7c478bd9Sstevel@tonic-gate if (oldmask) { 1265*7c478bd9Sstevel@tonic-gate umask(oldmask); 1266*7c478bd9Sstevel@tonic-gate oldmask = 0; 1267*7c478bd9Sstevel@tonic-gate } 1268*7c478bd9Sstevel@tonic-gate #endif 1269*7c478bd9Sstevel@tonic-gate #ifdef NULLS /* Not really nulls, but close enough */ 1270*7c478bd9Sstevel@tonic-gate /* This is a bug because of buffering */ 1271*7c478bd9Sstevel@tonic-gate if (code == 28) /* illegal char. */ 1272*7c478bd9Sstevel@tonic-gate putd(); 1273*7c478bd9Sstevel@tonic-gate #endif 1274*7c478bd9Sstevel@tonic-gate /* Cant open file or file does not exist */ 1275*7c478bd9Sstevel@tonic-gate if ((code == 3) || (code == 68)) { 1276*7c478bd9Sstevel@tonic-gate if (qflg == 0) { 1277*7c478bd9Sstevel@tonic-gate putchr('?'); 1278*7c478bd9Sstevel@tonic-gate puts(file); 1279*7c478bd9Sstevel@tonic-gate } 1280*7c478bd9Sstevel@tonic-gate else 1281*7c478bd9Sstevel@tonic-gate qflg = 0; 1282*7c478bd9Sstevel@tonic-gate } 1283*7c478bd9Sstevel@tonic-gate else 1284*7c478bd9Sstevel@tonic-gate { 1285*7c478bd9Sstevel@tonic-gate putchr('?'); 1286*7c478bd9Sstevel@tonic-gate putchr('\n'); 1287*7c478bd9Sstevel@tonic-gate } 1288*7c478bd9Sstevel@tonic-gate count = 0; 1289*7c478bd9Sstevel@tonic-gate lseek(0, (long)0, 2); 1290*7c478bd9Sstevel@tonic-gate if (globp) 1291*7c478bd9Sstevel@tonic-gate lastc = '\n'; 1292*7c478bd9Sstevel@tonic-gate globp = 0; 1293*7c478bd9Sstevel@tonic-gate peekc = lastc; 1294*7c478bd9Sstevel@tonic-gate if (lastc) 1295*7c478bd9Sstevel@tonic-gate while ((c = getchr()) != '\n' && c != EOF); 1296*7c478bd9Sstevel@tonic-gate if (io) { 1297*7c478bd9Sstevel@tonic-gate eclose(io); 1298*7c478bd9Sstevel@tonic-gate io = -1; 1299*7c478bd9Sstevel@tonic-gate } 1300*7c478bd9Sstevel@tonic-gate xcode = code; 1301*7c478bd9Sstevel@tonic-gate if (hflag) 1302*7c478bd9Sstevel@tonic-gate PUTM(); 1303*7c478bd9Sstevel@tonic-gate if (code == 4) 1304*7c478bd9Sstevel@tonic-gate return (0); /* Non-fatal error. */ 1305*7c478bd9Sstevel@tonic-gate longjmp(savej, 1); 1306*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 1307*7c478bd9Sstevel@tonic-gate } 1308*7c478bd9Sstevel@tonic-gate 1309*7c478bd9Sstevel@tonic-gate static int 1310*7c478bd9Sstevel@tonic-gate getchr(void) 1311*7c478bd9Sstevel@tonic-gate { 1312*7c478bd9Sstevel@tonic-gate char c; 1313*7c478bd9Sstevel@tonic-gate if (lastc = peekc) { 1314*7c478bd9Sstevel@tonic-gate peekc = 0; 1315*7c478bd9Sstevel@tonic-gate return (lastc); 1316*7c478bd9Sstevel@tonic-gate } 1317*7c478bd9Sstevel@tonic-gate if (globp) { 1318*7c478bd9Sstevel@tonic-gate if ((lastc = (unsigned char)*globp++) != 0) 1319*7c478bd9Sstevel@tonic-gate return (lastc); 1320*7c478bd9Sstevel@tonic-gate globp = 0; 1321*7c478bd9Sstevel@tonic-gate return (EOF); 1322*7c478bd9Sstevel@tonic-gate } 1323*7c478bd9Sstevel@tonic-gate if (read(0, &c, 1) <= 0) 1324*7c478bd9Sstevel@tonic-gate return (lastc = EOF); 1325*7c478bd9Sstevel@tonic-gate lastc = (unsigned char)c; 1326*7c478bd9Sstevel@tonic-gate return (lastc); 1327*7c478bd9Sstevel@tonic-gate } 1328*7c478bd9Sstevel@tonic-gate 1329*7c478bd9Sstevel@tonic-gate static int 1330*7c478bd9Sstevel@tonic-gate gettty(void) 1331*7c478bd9Sstevel@tonic-gate { 1332*7c478bd9Sstevel@tonic-gate int c; 1333*7c478bd9Sstevel@tonic-gate char *gf; 1334*7c478bd9Sstevel@tonic-gate char *p; 1335*7c478bd9Sstevel@tonic-gate 1336*7c478bd9Sstevel@tonic-gate p = linebuf; 1337*7c478bd9Sstevel@tonic-gate gf = globp; 1338*7c478bd9Sstevel@tonic-gate while ((c = getchr()) != '\n') { 1339*7c478bd9Sstevel@tonic-gate if (c == EOF) { 1340*7c478bd9Sstevel@tonic-gate if (gf) 1341*7c478bd9Sstevel@tonic-gate peekc = c; 1342*7c478bd9Sstevel@tonic-gate return (c); 1343*7c478bd9Sstevel@tonic-gate } 1344*7c478bd9Sstevel@tonic-gate if (c == 0) 1345*7c478bd9Sstevel@tonic-gate continue; 1346*7c478bd9Sstevel@tonic-gate *p++ = c; 1347*7c478bd9Sstevel@tonic-gate 1348*7c478bd9Sstevel@tonic-gate if (p > &linebuf[LBSIZE-1]) 1349*7c478bd9Sstevel@tonic-gate (void) error(27); 1350*7c478bd9Sstevel@tonic-gate } 1351*7c478bd9Sstevel@tonic-gate *p++ = 0; 1352*7c478bd9Sstevel@tonic-gate if (linebuf[0] == '.' && linebuf[1] == 0) 1353*7c478bd9Sstevel@tonic-gate return (EOF); 1354*7c478bd9Sstevel@tonic-gate 1355*7c478bd9Sstevel@tonic-gate /* 1356*7c478bd9Sstevel@tonic-gate * POSIX.2/XPG4 explicitly says no to this: 1357*7c478bd9Sstevel@tonic-gate * 1358*7c478bd9Sstevel@tonic-gate * in Solaris backslash followed by special character "." is 1359*7c478bd9Sstevel@tonic-gate * special character "." itself; (so terminating input mode can be 1360*7c478bd9Sstevel@tonic-gate * "\.\n"). 1361*7c478bd9Sstevel@tonic-gate * 1362*7c478bd9Sstevel@tonic-gate * however, POSIX2/XPG4 says, input mode is terminated by 1363*7c478bd9Sstevel@tonic-gate * entering line consisting of only 2 characters: ".\n" 1364*7c478bd9Sstevel@tonic-gate * 1365*7c478bd9Sstevel@tonic-gate * if (linebuf[0]=='\\' && linebuf[1]=='.' && linebuf[2]==0) { 1366*7c478bd9Sstevel@tonic-gate * linebuf[0] = '.'; 1367*7c478bd9Sstevel@tonic-gate * linebuf[1] = 0; 1368*7c478bd9Sstevel@tonic-gate * } 1369*7c478bd9Sstevel@tonic-gate */ 1370*7c478bd9Sstevel@tonic-gate return (0); 1371*7c478bd9Sstevel@tonic-gate } 1372*7c478bd9Sstevel@tonic-gate 1373*7c478bd9Sstevel@tonic-gate static int 1374*7c478bd9Sstevel@tonic-gate getfile(void) 1375*7c478bd9Sstevel@tonic-gate { 1376*7c478bd9Sstevel@tonic-gate char c; 1377*7c478bd9Sstevel@tonic-gate char *lp, *fp; 1378*7c478bd9Sstevel@tonic-gate 1379*7c478bd9Sstevel@tonic-gate lp = linebuf; 1380*7c478bd9Sstevel@tonic-gate fp = nextip; 1381*7c478bd9Sstevel@tonic-gate do { 1382*7c478bd9Sstevel@tonic-gate if (--ninbuf < 0) { 1383*7c478bd9Sstevel@tonic-gate if ((ninbuf = read(io, genbuf, LBSIZE)-1) < 0) 1384*7c478bd9Sstevel@tonic-gate if (lp > linebuf) { 1385*7c478bd9Sstevel@tonic-gate puts(gettext("'\\n' appended")); 1386*7c478bd9Sstevel@tonic-gate *genbuf = '\n'; 1387*7c478bd9Sstevel@tonic-gate } 1388*7c478bd9Sstevel@tonic-gate else 1389*7c478bd9Sstevel@tonic-gate return (EOF); 1390*7c478bd9Sstevel@tonic-gate if (crflag == -1) { 1391*7c478bd9Sstevel@tonic-gate if (isencrypt(genbuf, ninbuf + 1)) 1392*7c478bd9Sstevel@tonic-gate crflag = 2; 1393*7c478bd9Sstevel@tonic-gate else 1394*7c478bd9Sstevel@tonic-gate crflag = -2; 1395*7c478bd9Sstevel@tonic-gate } 1396*7c478bd9Sstevel@tonic-gate fp = genbuf; 1397*7c478bd9Sstevel@tonic-gate if (crflag > 0) 1398*7c478bd9Sstevel@tonic-gate if (run_crypt(count, genbuf, ninbuf+1, perm) == -1) 1399*7c478bd9Sstevel@tonic-gate (void) error(63); 1400*7c478bd9Sstevel@tonic-gate } 1401*7c478bd9Sstevel@tonic-gate if (lp >= &linebuf[LBSIZE]) { 1402*7c478bd9Sstevel@tonic-gate lastc = '\n'; 1403*7c478bd9Sstevel@tonic-gate (void) error(27); 1404*7c478bd9Sstevel@tonic-gate } 1405*7c478bd9Sstevel@tonic-gate if ((*lp++ = c = *fp++) == 0) { 1406*7c478bd9Sstevel@tonic-gate #ifdef NULLS 1407*7c478bd9Sstevel@tonic-gate lp[-1] = '\\'; 1408*7c478bd9Sstevel@tonic-gate *lp++ = '0'; 1409*7c478bd9Sstevel@tonic-gate nulls++; 1410*7c478bd9Sstevel@tonic-gate #else 1411*7c478bd9Sstevel@tonic-gate lp--; 1412*7c478bd9Sstevel@tonic-gate continue; 1413*7c478bd9Sstevel@tonic-gate #endif 1414*7c478bd9Sstevel@tonic-gate } 1415*7c478bd9Sstevel@tonic-gate count++; 1416*7c478bd9Sstevel@tonic-gate } while (c != '\n'); 1417*7c478bd9Sstevel@tonic-gate *--lp = 0; 1418*7c478bd9Sstevel@tonic-gate nextip = fp; 1419*7c478bd9Sstevel@tonic-gate if (fss.Ffill && fss.Flim && lenchk(linebuf, &fss) < 0) { 1420*7c478bd9Sstevel@tonic-gate write(1, gettext("line too long: lno = "), 1421*7c478bd9Sstevel@tonic-gate strlen(gettext("line too long: lno = "))); 1422*7c478bd9Sstevel@tonic-gate ccount = count; 1423*7c478bd9Sstevel@tonic-gate count = (++dot-zero)&077777; 1424*7c478bd9Sstevel@tonic-gate dot--; 1425*7c478bd9Sstevel@tonic-gate putd(); 1426*7c478bd9Sstevel@tonic-gate count = ccount; 1427*7c478bd9Sstevel@tonic-gate putchr('\n'); 1428*7c478bd9Sstevel@tonic-gate } 1429*7c478bd9Sstevel@tonic-gate return (0); 1430*7c478bd9Sstevel@tonic-gate } 1431*7c478bd9Sstevel@tonic-gate 1432*7c478bd9Sstevel@tonic-gate static void 1433*7c478bd9Sstevel@tonic-gate putfile(void) 1434*7c478bd9Sstevel@tonic-gate { 1435*7c478bd9Sstevel@tonic-gate int n; 1436*7c478bd9Sstevel@tonic-gate LINE a1; 1437*7c478bd9Sstevel@tonic-gate char *fp, *lp; 1438*7c478bd9Sstevel@tonic-gate int nib; 1439*7c478bd9Sstevel@tonic-gate 1440*7c478bd9Sstevel@tonic-gate nib = LBSIZE; 1441*7c478bd9Sstevel@tonic-gate fp = genbuf; 1442*7c478bd9Sstevel@tonic-gate a1 = addr1; 1443*7c478bd9Sstevel@tonic-gate do { 1444*7c478bd9Sstevel@tonic-gate lp = getline(a1++->cur); 1445*7c478bd9Sstevel@tonic-gate if (fss.Ffill && fss.Flim && lenchk(linebuf, &fss) < 0) { 1446*7c478bd9Sstevel@tonic-gate write(1, gettext("line too long: lno = "), 1447*7c478bd9Sstevel@tonic-gate strlen(gettext("line too long: lno = "))); 1448*7c478bd9Sstevel@tonic-gate ccount = count; 1449*7c478bd9Sstevel@tonic-gate count = (a1-zero-1)&077777; 1450*7c478bd9Sstevel@tonic-gate putd(); 1451*7c478bd9Sstevel@tonic-gate count = ccount; 1452*7c478bd9Sstevel@tonic-gate putchr('\n'); 1453*7c478bd9Sstevel@tonic-gate } 1454*7c478bd9Sstevel@tonic-gate for (;;) { 1455*7c478bd9Sstevel@tonic-gate if (--nib < 0) { 1456*7c478bd9Sstevel@tonic-gate n = fp-genbuf; 1457*7c478bd9Sstevel@tonic-gate if (kflag) 1458*7c478bd9Sstevel@tonic-gate if (run_crypt(count-n, genbuf, n, perm) == -1) 1459*7c478bd9Sstevel@tonic-gate (void) error(63); 1460*7c478bd9Sstevel@tonic-gate if (write(io, genbuf, n) != n) 1461*7c478bd9Sstevel@tonic-gate (void) error(29); 1462*7c478bd9Sstevel@tonic-gate nib = LBSIZE - 1; 1463*7c478bd9Sstevel@tonic-gate fp = genbuf; 1464*7c478bd9Sstevel@tonic-gate } 1465*7c478bd9Sstevel@tonic-gate if (dol->cur == 0L)break; /* Allow write of null file */ 1466*7c478bd9Sstevel@tonic-gate count++; 1467*7c478bd9Sstevel@tonic-gate if ((*fp++ = *lp++) == 0) { 1468*7c478bd9Sstevel@tonic-gate fp[-1] = '\n'; 1469*7c478bd9Sstevel@tonic-gate break; 1470*7c478bd9Sstevel@tonic-gate } 1471*7c478bd9Sstevel@tonic-gate } 1472*7c478bd9Sstevel@tonic-gate } while (a1 <= addr2); 1473*7c478bd9Sstevel@tonic-gate n = fp-genbuf; 1474*7c478bd9Sstevel@tonic-gate if (kflag) 1475*7c478bd9Sstevel@tonic-gate if (run_crypt(count-n, genbuf, n, perm) == -1) 1476*7c478bd9Sstevel@tonic-gate (void) error(63); 1477*7c478bd9Sstevel@tonic-gate if (write(io, genbuf, n) != n) 1478*7c478bd9Sstevel@tonic-gate (void) error(29); 1479*7c478bd9Sstevel@tonic-gate } 1480*7c478bd9Sstevel@tonic-gate 1481*7c478bd9Sstevel@tonic-gate static void 1482*7c478bd9Sstevel@tonic-gate append(int (*f)(void), LINE a) 1483*7c478bd9Sstevel@tonic-gate { 1484*7c478bd9Sstevel@tonic-gate LINE a1, a2, rdot; 1485*7c478bd9Sstevel@tonic-gate long tl; 1486*7c478bd9Sstevel@tonic-gate 1487*7c478bd9Sstevel@tonic-gate nline = 0; 1488*7c478bd9Sstevel@tonic-gate dot = a; 1489*7c478bd9Sstevel@tonic-gate while ((*f)() == 0) { 1490*7c478bd9Sstevel@tonic-gate if (dol >= endcore) { 1491*7c478bd9Sstevel@tonic-gate if ((int)sbrk(512 * sizeof (struct lin)) == -1) { 1492*7c478bd9Sstevel@tonic-gate lastc = '\n'; 1493*7c478bd9Sstevel@tonic-gate (void) error(30); 1494*7c478bd9Sstevel@tonic-gate } 1495*7c478bd9Sstevel@tonic-gate endcore += 512; 1496*7c478bd9Sstevel@tonic-gate } 1497*7c478bd9Sstevel@tonic-gate tl = putline(); 1498*7c478bd9Sstevel@tonic-gate nline++; 1499*7c478bd9Sstevel@tonic-gate a1 = ++dol; 1500*7c478bd9Sstevel@tonic-gate a2 = a1+1; 1501*7c478bd9Sstevel@tonic-gate rdot = ++dot; 1502*7c478bd9Sstevel@tonic-gate while (a1 > rdot) 1503*7c478bd9Sstevel@tonic-gate (--a2)->cur = (--a1)->cur; 1504*7c478bd9Sstevel@tonic-gate rdot->cur = tl; 1505*7c478bd9Sstevel@tonic-gate } 1506*7c478bd9Sstevel@tonic-gate } 1507*7c478bd9Sstevel@tonic-gate 1508*7c478bd9Sstevel@tonic-gate static void 1509*7c478bd9Sstevel@tonic-gate unixcom(void) 1510*7c478bd9Sstevel@tonic-gate { 1511*7c478bd9Sstevel@tonic-gate void (*savint)(); 1512*7c478bd9Sstevel@tonic-gate pid_t pid, rpid; 1513*7c478bd9Sstevel@tonic-gate int retcode; 1514*7c478bd9Sstevel@tonic-gate static char savcmd[LBSIZE]; /* last command */ 1515*7c478bd9Sstevel@tonic-gate char curcmd[LBSIZE]; /* current command */ 1516*7c478bd9Sstevel@tonic-gate char *psavcmd, *pcurcmd, *psavedfile; 1517*7c478bd9Sstevel@tonic-gate int endflg = 1, shflg = 0; 1518*7c478bd9Sstevel@tonic-gate wchar_t c; 1519*7c478bd9Sstevel@tonic-gate int len; 1520*7c478bd9Sstevel@tonic-gate 1521*7c478bd9Sstevel@tonic-gate setnoaddr(); 1522*7c478bd9Sstevel@tonic-gate if (rflg) 1523*7c478bd9Sstevel@tonic-gate (void) error(6); 1524*7c478bd9Sstevel@tonic-gate pcurcmd = curcmd; 1525*7c478bd9Sstevel@tonic-gate /* read command til end */ 1526*7c478bd9Sstevel@tonic-gate 1527*7c478bd9Sstevel@tonic-gate /* 1528*7c478bd9Sstevel@tonic-gate * a '!' found in beginning of command is replaced with the saved 1529*7c478bd9Sstevel@tonic-gate * command. a '%' found in command is replaced with the current 1530*7c478bd9Sstevel@tonic-gate * filename 1531*7c478bd9Sstevel@tonic-gate */ 1532*7c478bd9Sstevel@tonic-gate 1533*7c478bd9Sstevel@tonic-gate c = getchr(); 1534*7c478bd9Sstevel@tonic-gate if (c == '!') { 1535*7c478bd9Sstevel@tonic-gate if (savcmd[0] == 0) 1536*7c478bd9Sstevel@tonic-gate (void) error(56); 1537*7c478bd9Sstevel@tonic-gate else { 1538*7c478bd9Sstevel@tonic-gate psavcmd = savcmd; 1539*7c478bd9Sstevel@tonic-gate while (*pcurcmd++ = *psavcmd++); 1540*7c478bd9Sstevel@tonic-gate --pcurcmd; 1541*7c478bd9Sstevel@tonic-gate shflg = 1; 1542*7c478bd9Sstevel@tonic-gate } 1543*7c478bd9Sstevel@tonic-gate } else 1544*7c478bd9Sstevel@tonic-gate UNGETC(c); /* put c back */ 1545*7c478bd9Sstevel@tonic-gate while (endflg == 1) { 1546*7c478bd9Sstevel@tonic-gate while ((c = get_wchr()) != '\n' && c != '%' && c != '\\') { 1547*7c478bd9Sstevel@tonic-gate if ((len = wctomb(pcurcmd, c)) <= 0) { 1548*7c478bd9Sstevel@tonic-gate *pcurcmd = (unsigned char)c; 1549*7c478bd9Sstevel@tonic-gate len = 1; 1550*7c478bd9Sstevel@tonic-gate } 1551*7c478bd9Sstevel@tonic-gate pcurcmd += len; 1552*7c478bd9Sstevel@tonic-gate } 1553*7c478bd9Sstevel@tonic-gate 1554*7c478bd9Sstevel@tonic-gate if (c == '%') { 1555*7c478bd9Sstevel@tonic-gate if (savedfile[0] == 0) 1556*7c478bd9Sstevel@tonic-gate (void) error(21); 1557*7c478bd9Sstevel@tonic-gate else { 1558*7c478bd9Sstevel@tonic-gate psavedfile = savedfile; 1559*7c478bd9Sstevel@tonic-gate while (pcurcmd < curcmd + LBSIZE && 1560*7c478bd9Sstevel@tonic-gate (*pcurcmd++ = *psavedfile++)); 1561*7c478bd9Sstevel@tonic-gate --pcurcmd; 1562*7c478bd9Sstevel@tonic-gate shflg = 1; 1563*7c478bd9Sstevel@tonic-gate } 1564*7c478bd9Sstevel@tonic-gate } else if (c == '\\') { 1565*7c478bd9Sstevel@tonic-gate c = get_wchr(); 1566*7c478bd9Sstevel@tonic-gate if (c != '%') 1567*7c478bd9Sstevel@tonic-gate *pcurcmd++ = '\\'; 1568*7c478bd9Sstevel@tonic-gate if ((len = wctomb(pcurcmd, c)) <= 0) { 1569*7c478bd9Sstevel@tonic-gate *pcurcmd = (unsigned char)c; 1570*7c478bd9Sstevel@tonic-gate len = 1; 1571*7c478bd9Sstevel@tonic-gate } 1572*7c478bd9Sstevel@tonic-gate pcurcmd += len; 1573*7c478bd9Sstevel@tonic-gate } 1574*7c478bd9Sstevel@tonic-gate else 1575*7c478bd9Sstevel@tonic-gate /* end of command hit */ 1576*7c478bd9Sstevel@tonic-gate endflg = 0; 1577*7c478bd9Sstevel@tonic-gate } 1578*7c478bd9Sstevel@tonic-gate *pcurcmd++ = 0; 1579*7c478bd9Sstevel@tonic-gate if (shflg == 1) 1580*7c478bd9Sstevel@tonic-gate puts(curcmd); 1581*7c478bd9Sstevel@tonic-gate /* save command */ 1582*7c478bd9Sstevel@tonic-gate strcpy(savcmd, curcmd); 1583*7c478bd9Sstevel@tonic-gate 1584*7c478bd9Sstevel@tonic-gate if ((pid = fork()) == 0) { 1585*7c478bd9Sstevel@tonic-gate signal(SIGHUP, oldhup); 1586*7c478bd9Sstevel@tonic-gate signal(SIGQUIT, oldquit); 1587*7c478bd9Sstevel@tonic-gate close(tfile); 1588*7c478bd9Sstevel@tonic-gate if (__xpg4 == 0) { /* not XPG4 */ 1589*7c478bd9Sstevel@tonic-gate shpath = "/usr/bin/sh"; 1590*7c478bd9Sstevel@tonic-gate } else { 1591*7c478bd9Sstevel@tonic-gate /* XPG4 */ 1592*7c478bd9Sstevel@tonic-gate shpath = "/usr/xpg4/bin/sh"; 1593*7c478bd9Sstevel@tonic-gate } 1594*7c478bd9Sstevel@tonic-gate execlp((const char *)shpath, "sh", "-c", curcmd, (char *)0); 1595*7c478bd9Sstevel@tonic-gate exit(0100); 1596*7c478bd9Sstevel@tonic-gate } 1597*7c478bd9Sstevel@tonic-gate savint = signal(SIGINT, SIG_IGN); 1598*7c478bd9Sstevel@tonic-gate while ((rpid = wait(&retcode)) != pid && rpid != (pid_t)-1); 1599*7c478bd9Sstevel@tonic-gate signal(SIGINT, savint); 1600*7c478bd9Sstevel@tonic-gate if (vflag) puts("!"); 1601*7c478bd9Sstevel@tonic-gate } 1602*7c478bd9Sstevel@tonic-gate 1603*7c478bd9Sstevel@tonic-gate static void 1604*7c478bd9Sstevel@tonic-gate quit(int sig) 1605*7c478bd9Sstevel@tonic-gate { 1606*7c478bd9Sstevel@tonic-gate if (vflag && fchange) { 1607*7c478bd9Sstevel@tonic-gate fchange = 0; 1608*7c478bd9Sstevel@tonic-gate if (flag28) { 1609*7c478bd9Sstevel@tonic-gate flag28 = 0; 1610*7c478bd9Sstevel@tonic-gate (void) error(62); 1611*7c478bd9Sstevel@tonic-gate } 1612*7c478bd9Sstevel@tonic-gate 1613*7c478bd9Sstevel@tonic-gate /* 1614*7c478bd9Sstevel@tonic-gate * For case where user reads in BOTH a good 1615*7c478bd9Sstevel@tonic-gate * file & a bad file 1616*7c478bd9Sstevel@tonic-gate */ 1617*7c478bd9Sstevel@tonic-gate (void) error(1); 1618*7c478bd9Sstevel@tonic-gate } 1619*7c478bd9Sstevel@tonic-gate unlink(tfname); 1620*7c478bd9Sstevel@tonic-gate if (kflag) 1621*7c478bd9Sstevel@tonic-gate crypt_close(perm); 1622*7c478bd9Sstevel@tonic-gate if (xtflag) 1623*7c478bd9Sstevel@tonic-gate crypt_close(tperm); 1624*7c478bd9Sstevel@tonic-gate exit(errcnt? 2: 0); 1625*7c478bd9Sstevel@tonic-gate } 1626*7c478bd9Sstevel@tonic-gate 1627*7c478bd9Sstevel@tonic-gate static void 1628*7c478bd9Sstevel@tonic-gate delete(void) 1629*7c478bd9Sstevel@tonic-gate { 1630*7c478bd9Sstevel@tonic-gate setdot(); 1631*7c478bd9Sstevel@tonic-gate newline(); 1632*7c478bd9Sstevel@tonic-gate nonzero(); 1633*7c478bd9Sstevel@tonic-gate if (!globflg) save(); 1634*7c478bd9Sstevel@tonic-gate rdelete(addr1, addr2); 1635*7c478bd9Sstevel@tonic-gate } 1636*7c478bd9Sstevel@tonic-gate 1637*7c478bd9Sstevel@tonic-gate static void 1638*7c478bd9Sstevel@tonic-gate rdelete(LINE ad1, LINE ad2) 1639*7c478bd9Sstevel@tonic-gate { 1640*7c478bd9Sstevel@tonic-gate LINE a1, a2, a3; 1641*7c478bd9Sstevel@tonic-gate 1642*7c478bd9Sstevel@tonic-gate a1 = ad1; 1643*7c478bd9Sstevel@tonic-gate a2 = ad2+1; 1644*7c478bd9Sstevel@tonic-gate a3 = dol; 1645*7c478bd9Sstevel@tonic-gate dol -= a2 - a1; 1646*7c478bd9Sstevel@tonic-gate do 1647*7c478bd9Sstevel@tonic-gate (a1++)->cur = (a2++)->cur; 1648*7c478bd9Sstevel@tonic-gate while (a2 <= a3); 1649*7c478bd9Sstevel@tonic-gate a1 = ad1; 1650*7c478bd9Sstevel@tonic-gate if (a1 > dol) 1651*7c478bd9Sstevel@tonic-gate a1 = dol; 1652*7c478bd9Sstevel@tonic-gate dot = a1; 1653*7c478bd9Sstevel@tonic-gate fchange = 1; 1654*7c478bd9Sstevel@tonic-gate } 1655*7c478bd9Sstevel@tonic-gate 1656*7c478bd9Sstevel@tonic-gate static void 1657*7c478bd9Sstevel@tonic-gate gdelete(void) 1658*7c478bd9Sstevel@tonic-gate { 1659*7c478bd9Sstevel@tonic-gate LINE a1, a2, a3; 1660*7c478bd9Sstevel@tonic-gate 1661*7c478bd9Sstevel@tonic-gate a3 = dol; 1662*7c478bd9Sstevel@tonic-gate for (a1 = zero+1; (a1->cur&01) == 0; a1++) 1663*7c478bd9Sstevel@tonic-gate if (a1 >= a3) 1664*7c478bd9Sstevel@tonic-gate return; 1665*7c478bd9Sstevel@tonic-gate for (a2 = a1 + 1; a2 <= a3; ) { 1666*7c478bd9Sstevel@tonic-gate if (a2->cur & 01) { 1667*7c478bd9Sstevel@tonic-gate a2++; 1668*7c478bd9Sstevel@tonic-gate dot = a1; 1669*7c478bd9Sstevel@tonic-gate } else 1670*7c478bd9Sstevel@tonic-gate (a1++)->cur = (a2++)->cur; 1671*7c478bd9Sstevel@tonic-gate } 1672*7c478bd9Sstevel@tonic-gate dol = a1-1; 1673*7c478bd9Sstevel@tonic-gate if (dot > dol) 1674*7c478bd9Sstevel@tonic-gate dot = dol; 1675*7c478bd9Sstevel@tonic-gate fchange = 1; 1676*7c478bd9Sstevel@tonic-gate } 1677*7c478bd9Sstevel@tonic-gate 1678*7c478bd9Sstevel@tonic-gate static char * 1679*7c478bd9Sstevel@tonic-gate getline(long tl) 1680*7c478bd9Sstevel@tonic-gate { 1681*7c478bd9Sstevel@tonic-gate char *bp, *lp; 1682*7c478bd9Sstevel@tonic-gate int nl; 1683*7c478bd9Sstevel@tonic-gate 1684*7c478bd9Sstevel@tonic-gate lp = linebuf; 1685*7c478bd9Sstevel@tonic-gate bp = getblock(tl, READ); 1686*7c478bd9Sstevel@tonic-gate nl = nleft; 1687*7c478bd9Sstevel@tonic-gate tl &= ~0377; 1688*7c478bd9Sstevel@tonic-gate while (*lp++ = *bp++) 1689*7c478bd9Sstevel@tonic-gate if (--nl == 0) { 1690*7c478bd9Sstevel@tonic-gate bp = getblock(tl += 0400, READ); 1691*7c478bd9Sstevel@tonic-gate nl = nleft; 1692*7c478bd9Sstevel@tonic-gate } 1693*7c478bd9Sstevel@tonic-gate return (linebuf); 1694*7c478bd9Sstevel@tonic-gate } 1695*7c478bd9Sstevel@tonic-gate 1696*7c478bd9Sstevel@tonic-gate static long 1697*7c478bd9Sstevel@tonic-gate putline(void) 1698*7c478bd9Sstevel@tonic-gate { 1699*7c478bd9Sstevel@tonic-gate char *bp, *lp; 1700*7c478bd9Sstevel@tonic-gate int nl; 1701*7c478bd9Sstevel@tonic-gate long tl; 1702*7c478bd9Sstevel@tonic-gate 1703*7c478bd9Sstevel@tonic-gate fchange = 1; 1704*7c478bd9Sstevel@tonic-gate lp = linebuf; 1705*7c478bd9Sstevel@tonic-gate tl = tline; 1706*7c478bd9Sstevel@tonic-gate bp = getblock(tl, WRITE); 1707*7c478bd9Sstevel@tonic-gate nl = nleft; 1708*7c478bd9Sstevel@tonic-gate tl &= ~0377; 1709*7c478bd9Sstevel@tonic-gate while (*bp = *lp++) { 1710*7c478bd9Sstevel@tonic-gate if (*bp++ == '\n') { 1711*7c478bd9Sstevel@tonic-gate *--bp = 0; 1712*7c478bd9Sstevel@tonic-gate linebp = lp; 1713*7c478bd9Sstevel@tonic-gate break; 1714*7c478bd9Sstevel@tonic-gate } 1715*7c478bd9Sstevel@tonic-gate if (--nl == 0) { 1716*7c478bd9Sstevel@tonic-gate bp = getblock(tl += 0400, WRITE); 1717*7c478bd9Sstevel@tonic-gate nl = nleft; 1718*7c478bd9Sstevel@tonic-gate } 1719*7c478bd9Sstevel@tonic-gate } 1720*7c478bd9Sstevel@tonic-gate nl = tline; 1721*7c478bd9Sstevel@tonic-gate tline += (((lp-linebuf)+03)>>1)&077776; 1722*7c478bd9Sstevel@tonic-gate return (nl); 1723*7c478bd9Sstevel@tonic-gate } 1724*7c478bd9Sstevel@tonic-gate 1725*7c478bd9Sstevel@tonic-gate static char * 1726*7c478bd9Sstevel@tonic-gate getblock(long atl, long iof) 1727*7c478bd9Sstevel@tonic-gate { 1728*7c478bd9Sstevel@tonic-gate int bno, off; 1729*7c478bd9Sstevel@tonic-gate char *p1, *p2; 1730*7c478bd9Sstevel@tonic-gate int n; 1731*7c478bd9Sstevel@tonic-gate 1732*7c478bd9Sstevel@tonic-gate bno = atl >> 8; 1733*7c478bd9Sstevel@tonic-gate off = (atl<<1)&0774; 1734*7c478bd9Sstevel@tonic-gate 1735*7c478bd9Sstevel@tonic-gate /* bno is limited to 16 bits */ 1736*7c478bd9Sstevel@tonic-gate if (bno >= 65535) { 1737*7c478bd9Sstevel@tonic-gate lastc = '\n'; 1738*7c478bd9Sstevel@tonic-gate (void) error(31); 1739*7c478bd9Sstevel@tonic-gate } 1740*7c478bd9Sstevel@tonic-gate nleft = 512 - off; 1741*7c478bd9Sstevel@tonic-gate if (bno == iblock) { 1742*7c478bd9Sstevel@tonic-gate ichanged |= iof; 1743*7c478bd9Sstevel@tonic-gate return (ibuff+off); 1744*7c478bd9Sstevel@tonic-gate } 1745*7c478bd9Sstevel@tonic-gate if (bno == oblock) 1746*7c478bd9Sstevel@tonic-gate return (obuff+off); 1747*7c478bd9Sstevel@tonic-gate if (iof == READ) { 1748*7c478bd9Sstevel@tonic-gate if (ichanged) { 1749*7c478bd9Sstevel@tonic-gate if (xtflag) 1750*7c478bd9Sstevel@tonic-gate if (run_crypt(0L, ibuff, 512, tperm) == -1) 1751*7c478bd9Sstevel@tonic-gate (void) error(63); 1752*7c478bd9Sstevel@tonic-gate blkio(iblock, ibuff, write); 1753*7c478bd9Sstevel@tonic-gate } 1754*7c478bd9Sstevel@tonic-gate ichanged = 0; 1755*7c478bd9Sstevel@tonic-gate iblock = bno; 1756*7c478bd9Sstevel@tonic-gate blkio(bno, ibuff, read); 1757*7c478bd9Sstevel@tonic-gate if (xtflag) 1758*7c478bd9Sstevel@tonic-gate if (run_crypt(0L, ibuff, 512, tperm) == -1) 1759*7c478bd9Sstevel@tonic-gate (void) error(63); 1760*7c478bd9Sstevel@tonic-gate return (ibuff+off); 1761*7c478bd9Sstevel@tonic-gate } 1762*7c478bd9Sstevel@tonic-gate if (oblock >= 0) { 1763*7c478bd9Sstevel@tonic-gate if (xtflag) { 1764*7c478bd9Sstevel@tonic-gate p1 = obuff; 1765*7c478bd9Sstevel@tonic-gate p2 = crbuf; 1766*7c478bd9Sstevel@tonic-gate n = 512; 1767*7c478bd9Sstevel@tonic-gate while (n--) 1768*7c478bd9Sstevel@tonic-gate *p2++ = *p1++; 1769*7c478bd9Sstevel@tonic-gate if (run_crypt(0L, crbuf, 512, tperm) == -1) 1770*7c478bd9Sstevel@tonic-gate (void) error(63); 1771*7c478bd9Sstevel@tonic-gate blkio(oblock, crbuf, write); 1772*7c478bd9Sstevel@tonic-gate } else 1773*7c478bd9Sstevel@tonic-gate blkio(oblock, obuff, write); 1774*7c478bd9Sstevel@tonic-gate } 1775*7c478bd9Sstevel@tonic-gate oblock = bno; 1776*7c478bd9Sstevel@tonic-gate return (obuff+off); 1777*7c478bd9Sstevel@tonic-gate } 1778*7c478bd9Sstevel@tonic-gate 1779*7c478bd9Sstevel@tonic-gate static void 1780*7c478bd9Sstevel@tonic-gate blkio(int b, char *buf, ssize_t (*iofcn)()) 1781*7c478bd9Sstevel@tonic-gate { 1782*7c478bd9Sstevel@tonic-gate lseek(tfile, (long)b<<9, 0); 1783*7c478bd9Sstevel@tonic-gate if ((*iofcn)(tfile, buf, 512) != 512) { 1784*7c478bd9Sstevel@tonic-gate if (dol != zero) 1785*7c478bd9Sstevel@tonic-gate (void) error(32); /* Bypass this if writing null file */ 1786*7c478bd9Sstevel@tonic-gate } 1787*7c478bd9Sstevel@tonic-gate } 1788*7c478bd9Sstevel@tonic-gate 1789*7c478bd9Sstevel@tonic-gate static void 1790*7c478bd9Sstevel@tonic-gate init(void) 1791*7c478bd9Sstevel@tonic-gate { 1792*7c478bd9Sstevel@tonic-gate long *markp; 1793*7c478bd9Sstevel@tonic-gate mode_t omask; 1794*7c478bd9Sstevel@tonic-gate 1795*7c478bd9Sstevel@tonic-gate if (tfile != -1) { 1796*7c478bd9Sstevel@tonic-gate (void) close(tfile); 1797*7c478bd9Sstevel@tonic-gate (void) unlink(tfname); 1798*7c478bd9Sstevel@tonic-gate } 1799*7c478bd9Sstevel@tonic-gate 1800*7c478bd9Sstevel@tonic-gate tline = 2; 1801*7c478bd9Sstevel@tonic-gate for (markp = names; markp < &names[26]; ) 1802*7c478bd9Sstevel@tonic-gate *markp++ = 0L; 1803*7c478bd9Sstevel@tonic-gate subnewa = 0L; 1804*7c478bd9Sstevel@tonic-gate anymarks = 0; 1805*7c478bd9Sstevel@tonic-gate iblock = -1; 1806*7c478bd9Sstevel@tonic-gate oblock = -1; 1807*7c478bd9Sstevel@tonic-gate ichanged = 0; 1808*7c478bd9Sstevel@tonic-gate initflg = 1; 1809*7c478bd9Sstevel@tonic-gate omask = umask(0); 1810*7c478bd9Sstevel@tonic-gate 1811*7c478bd9Sstevel@tonic-gate if ((tfile = open(tfname, O_CREAT|O_EXCL|O_RDWR, 1812*7c478bd9Sstevel@tonic-gate S_IRUSR|S_IWUSR)) < 0) { 1813*7c478bd9Sstevel@tonic-gate puts(gettext(msgtab[70])); 1814*7c478bd9Sstevel@tonic-gate exit(2); 1815*7c478bd9Sstevel@tonic-gate } 1816*7c478bd9Sstevel@tonic-gate 1817*7c478bd9Sstevel@tonic-gate umask(omask); 1818*7c478bd9Sstevel@tonic-gate if (xflag) { 1819*7c478bd9Sstevel@tonic-gate xtflag = 1; 1820*7c478bd9Sstevel@tonic-gate if (tpermflag) 1821*7c478bd9Sstevel@tonic-gate (void) crypt_close(tperm); 1822*7c478bd9Sstevel@tonic-gate tpermflag = 1; 1823*7c478bd9Sstevel@tonic-gate if (makekey(tperm)) { 1824*7c478bd9Sstevel@tonic-gate xtflag = 0; 1825*7c478bd9Sstevel@tonic-gate puts(gettext(msgtab[65])); 1826*7c478bd9Sstevel@tonic-gate } 1827*7c478bd9Sstevel@tonic-gate } 1828*7c478bd9Sstevel@tonic-gate brk((char *)fendcore); 1829*7c478bd9Sstevel@tonic-gate dot = zero = dol = savdot = savdol = fendcore; 1830*7c478bd9Sstevel@tonic-gate flag28 = save28 = 0; 1831*7c478bd9Sstevel@tonic-gate endcore = fendcore - sizeof (struct lin); 1832*7c478bd9Sstevel@tonic-gate } 1833*7c478bd9Sstevel@tonic-gate 1834*7c478bd9Sstevel@tonic-gate static void 1835*7c478bd9Sstevel@tonic-gate global(int k) 1836*7c478bd9Sstevel@tonic-gate { 1837*7c478bd9Sstevel@tonic-gate char *gp; 1838*7c478bd9Sstevel@tonic-gate wchar_t l; 1839*7c478bd9Sstevel@tonic-gate char multic[MB_LEN_MAX]; 1840*7c478bd9Sstevel@tonic-gate wchar_t c; 1841*7c478bd9Sstevel@tonic-gate LINE a1; 1842*7c478bd9Sstevel@tonic-gate char globuf[LBSIZE]; 1843*7c478bd9Sstevel@tonic-gate int n; 1844*7c478bd9Sstevel@tonic-gate int len; 1845*7c478bd9Sstevel@tonic-gate 1846*7c478bd9Sstevel@tonic-gate if (globp) 1847*7c478bd9Sstevel@tonic-gate (void) error(33); 1848*7c478bd9Sstevel@tonic-gate setall(); 1849*7c478bd9Sstevel@tonic-gate nonzero(); 1850*7c478bd9Sstevel@tonic-gate if ((n = _mbftowc(multic, &l, getchr, &peekc)) <= 0) 1851*7c478bd9Sstevel@tonic-gate (void) error(67); 1852*7c478bd9Sstevel@tonic-gate if (l == '\n') 1853*7c478bd9Sstevel@tonic-gate (void) error(19); 1854*7c478bd9Sstevel@tonic-gate save(); 1855*7c478bd9Sstevel@tonic-gate comple(l); 1856*7c478bd9Sstevel@tonic-gate gp = globuf; 1857*7c478bd9Sstevel@tonic-gate while ((c = get_wchr()) != '\n') { 1858*7c478bd9Sstevel@tonic-gate if (c == EOF) 1859*7c478bd9Sstevel@tonic-gate (void) error(19); 1860*7c478bd9Sstevel@tonic-gate 1861*7c478bd9Sstevel@tonic-gate /* '\\' has special meaning only if preceding a '\n' */ 1862*7c478bd9Sstevel@tonic-gate if (c == '\\') { 1863*7c478bd9Sstevel@tonic-gate c = get_wchr(); 1864*7c478bd9Sstevel@tonic-gate if (c != '\n') 1865*7c478bd9Sstevel@tonic-gate *gp++ = '\\'; 1866*7c478bd9Sstevel@tonic-gate } 1867*7c478bd9Sstevel@tonic-gate if ((gp + (unsigned int)MB_CUR_MAX) >= &globuf[LBSIZE-1]) 1868*7c478bd9Sstevel@tonic-gate (void) error(34); 1869*7c478bd9Sstevel@tonic-gate if ((len = wctomb(gp, c)) <= 0) { 1870*7c478bd9Sstevel@tonic-gate *gp = (unsigned char)c; 1871*7c478bd9Sstevel@tonic-gate len = 1; 1872*7c478bd9Sstevel@tonic-gate } 1873*7c478bd9Sstevel@tonic-gate gp += len; 1874*7c478bd9Sstevel@tonic-gate } 1875*7c478bd9Sstevel@tonic-gate if (gp == globuf) 1876*7c478bd9Sstevel@tonic-gate *gp++ = 'p'; 1877*7c478bd9Sstevel@tonic-gate *gp++ = '\n'; 1878*7c478bd9Sstevel@tonic-gate *gp++ = 0; 1879*7c478bd9Sstevel@tonic-gate for (a1 = zero; a1 <= dol; a1++) { 1880*7c478bd9Sstevel@tonic-gate a1->cur &= ~01; 1881*7c478bd9Sstevel@tonic-gate if (a1 >= addr1 && a1 <= addr2 && execute(0, a1) == k) 1882*7c478bd9Sstevel@tonic-gate a1->cur |= 01; 1883*7c478bd9Sstevel@tonic-gate } 1884*7c478bd9Sstevel@tonic-gate /* 1885*7c478bd9Sstevel@tonic-gate * Special case: g/.../d (avoid n^2 algorithm) 1886*7c478bd9Sstevel@tonic-gate */ 1887*7c478bd9Sstevel@tonic-gate if (globuf[0] == 'd' && globuf[1] == '\n' && globuf[2] == '\0') { 1888*7c478bd9Sstevel@tonic-gate gdelete(); 1889*7c478bd9Sstevel@tonic-gate return; 1890*7c478bd9Sstevel@tonic-gate } 1891*7c478bd9Sstevel@tonic-gate for (a1 = zero; a1 <= dol; a1++) { 1892*7c478bd9Sstevel@tonic-gate if (a1->cur & 01) { 1893*7c478bd9Sstevel@tonic-gate a1->cur &= ~01; 1894*7c478bd9Sstevel@tonic-gate dot = a1; 1895*7c478bd9Sstevel@tonic-gate globp = globuf; 1896*7c478bd9Sstevel@tonic-gate globflg = 1; 1897*7c478bd9Sstevel@tonic-gate commands(); 1898*7c478bd9Sstevel@tonic-gate globflg = 0; 1899*7c478bd9Sstevel@tonic-gate a1 = zero; 1900*7c478bd9Sstevel@tonic-gate } 1901*7c478bd9Sstevel@tonic-gate } 1902*7c478bd9Sstevel@tonic-gate } 1903*7c478bd9Sstevel@tonic-gate 1904*7c478bd9Sstevel@tonic-gate static void 1905*7c478bd9Sstevel@tonic-gate join(void) 1906*7c478bd9Sstevel@tonic-gate { 1907*7c478bd9Sstevel@tonic-gate char *gp, *lp; 1908*7c478bd9Sstevel@tonic-gate LINE a1; 1909*7c478bd9Sstevel@tonic-gate 1910*7c478bd9Sstevel@tonic-gate if (addr1 == addr2) 1911*7c478bd9Sstevel@tonic-gate return; 1912*7c478bd9Sstevel@tonic-gate gp = genbuf; 1913*7c478bd9Sstevel@tonic-gate for (a1 = addr1; a1 <= addr2; a1++) { 1914*7c478bd9Sstevel@tonic-gate lp = getline(a1->cur); 1915*7c478bd9Sstevel@tonic-gate while (*gp = *lp++) 1916*7c478bd9Sstevel@tonic-gate if (gp++ > &genbuf[LBSIZE-1]) 1917*7c478bd9Sstevel@tonic-gate (void) error(27); 1918*7c478bd9Sstevel@tonic-gate } 1919*7c478bd9Sstevel@tonic-gate lp = linebuf; 1920*7c478bd9Sstevel@tonic-gate gp = genbuf; 1921*7c478bd9Sstevel@tonic-gate while (*lp++ = *gp++); 1922*7c478bd9Sstevel@tonic-gate addr1->cur = putline(); 1923*7c478bd9Sstevel@tonic-gate if (addr1 < addr2) 1924*7c478bd9Sstevel@tonic-gate rdelete(addr1+1, addr2); 1925*7c478bd9Sstevel@tonic-gate dot = addr1; 1926*7c478bd9Sstevel@tonic-gate } 1927*7c478bd9Sstevel@tonic-gate 1928*7c478bd9Sstevel@tonic-gate static void 1929*7c478bd9Sstevel@tonic-gate substitute(int inglob) 1930*7c478bd9Sstevel@tonic-gate { 1931*7c478bd9Sstevel@tonic-gate int nl; 1932*7c478bd9Sstevel@tonic-gate LINE a1; 1933*7c478bd9Sstevel@tonic-gate long *markp; 1934*7c478bd9Sstevel@tonic-gate int ingsav; /* For saving arg. */ 1935*7c478bd9Sstevel@tonic-gate 1936*7c478bd9Sstevel@tonic-gate ingsav = inglob; 1937*7c478bd9Sstevel@tonic-gate ocerr2 = 0; 1938*7c478bd9Sstevel@tonic-gate gsubf = compsub(); 1939*7c478bd9Sstevel@tonic-gate for (a1 = addr1; a1 <= addr2; a1++) { 1940*7c478bd9Sstevel@tonic-gate if (execute(0, a1) == 0) 1941*7c478bd9Sstevel@tonic-gate continue; 1942*7c478bd9Sstevel@tonic-gate numpass = 0; 1943*7c478bd9Sstevel@tonic-gate ocerr1 = 0; 1944*7c478bd9Sstevel@tonic-gate inglob |= 01; 1945*7c478bd9Sstevel@tonic-gate dosub(); 1946*7c478bd9Sstevel@tonic-gate if (gsubf) { 1947*7c478bd9Sstevel@tonic-gate while (*loc2) { 1948*7c478bd9Sstevel@tonic-gate if (execute(1, (LINE)0) == 0) 1949*7c478bd9Sstevel@tonic-gate break; 1950*7c478bd9Sstevel@tonic-gate dosub(); 1951*7c478bd9Sstevel@tonic-gate } 1952*7c478bd9Sstevel@tonic-gate } 1953*7c478bd9Sstevel@tonic-gate if (ocerr1 == 0)continue; /* Don't put out-not changed. */ 1954*7c478bd9Sstevel@tonic-gate subnewa = putline(); 1955*7c478bd9Sstevel@tonic-gate a1->cur &= ~01; 1956*7c478bd9Sstevel@tonic-gate if (anymarks) { 1957*7c478bd9Sstevel@tonic-gate for (markp = names; markp < &names[26]; markp++) 1958*7c478bd9Sstevel@tonic-gate if (*markp == a1->cur) 1959*7c478bd9Sstevel@tonic-gate *markp = subnewa; 1960*7c478bd9Sstevel@tonic-gate } 1961*7c478bd9Sstevel@tonic-gate a1->cur = subnewa; 1962*7c478bd9Sstevel@tonic-gate append(getsub, a1); 1963*7c478bd9Sstevel@tonic-gate nl = nline; 1964*7c478bd9Sstevel@tonic-gate a1 += nl; 1965*7c478bd9Sstevel@tonic-gate addr2 += nl; 1966*7c478bd9Sstevel@tonic-gate } 1967*7c478bd9Sstevel@tonic-gate if (ingsav) 1968*7c478bd9Sstevel@tonic-gate return; /* Was in global-no error msg allowed. */ 1969*7c478bd9Sstevel@tonic-gate if (inglob == 0) 1970*7c478bd9Sstevel@tonic-gate (void) error(35); /* Not in global, but not found. */ 1971*7c478bd9Sstevel@tonic-gate if (ocerr2 == 0) 1972*7c478bd9Sstevel@tonic-gate (void) error(35); /* RE found, but occurrence match failed. */ 1973*7c478bd9Sstevel@tonic-gate } 1974*7c478bd9Sstevel@tonic-gate 1975*7c478bd9Sstevel@tonic-gate static int 1976*7c478bd9Sstevel@tonic-gate compsub(void) 1977*7c478bd9Sstevel@tonic-gate { 1978*7c478bd9Sstevel@tonic-gate int c; 1979*7c478bd9Sstevel@tonic-gate wchar_t seof; 1980*7c478bd9Sstevel@tonic-gate char *p; 1981*7c478bd9Sstevel@tonic-gate char multic[MB_LEN_MAX]; 1982*7c478bd9Sstevel@tonic-gate int n; 1983*7c478bd9Sstevel@tonic-gate static char remem[RHSIZE]; 1984*7c478bd9Sstevel@tonic-gate static int remflg = -1; 1985*7c478bd9Sstevel@tonic-gate int i; 1986*7c478bd9Sstevel@tonic-gate 1987*7c478bd9Sstevel@tonic-gate if ((n = _mbftowc(multic, &seof, getchr, &peekc)) <= 0) 1988*7c478bd9Sstevel@tonic-gate (void) error(67); 1989*7c478bd9Sstevel@tonic-gate if (seof == '\n' || seof == ' ') 1990*7c478bd9Sstevel@tonic-gate (void) error(36); 1991*7c478bd9Sstevel@tonic-gate comple(seof); 1992*7c478bd9Sstevel@tonic-gate p = rhsbuf; 1993*7c478bd9Sstevel@tonic-gate for (;;) { 1994*7c478bd9Sstevel@tonic-gate wchar_t cl; 1995*7c478bd9Sstevel@tonic-gate if ((n = _mbftowc(multic, &cl, getchr, &peekc)) <= 0) 1996*7c478bd9Sstevel@tonic-gate (void) error(67); 1997*7c478bd9Sstevel@tonic-gate if (cl == '\\') { 1998*7c478bd9Sstevel@tonic-gate *p++ = '\\'; 1999*7c478bd9Sstevel@tonic-gate if (p >= &rhsbuf[RHSIZE]) 2000*7c478bd9Sstevel@tonic-gate (void) error(38); 2001*7c478bd9Sstevel@tonic-gate if ((n = _mbftowc(multic, &cl, getchr, &peekc)) <= 0) 2002*7c478bd9Sstevel@tonic-gate (void) error(67); 2003*7c478bd9Sstevel@tonic-gate } else if (cl == '\n') { 2004*7c478bd9Sstevel@tonic-gate if (nodelim == 1) { 2005*7c478bd9Sstevel@tonic-gate nodelim = 0; 2006*7c478bd9Sstevel@tonic-gate (void) error(36); 2007*7c478bd9Sstevel@tonic-gate } 2008*7c478bd9Sstevel@tonic-gate if (!(globp && globp[0])) { 2009*7c478bd9Sstevel@tonic-gate UNGETC('\n'); 2010*7c478bd9Sstevel@tonic-gate pflag++; 2011*7c478bd9Sstevel@tonic-gate break; 2012*7c478bd9Sstevel@tonic-gate } 2013*7c478bd9Sstevel@tonic-gate } else if (cl == seof) 2014*7c478bd9Sstevel@tonic-gate break; 2015*7c478bd9Sstevel@tonic-gate if (p + n > &rhsbuf[RHSIZE]) 2016*7c478bd9Sstevel@tonic-gate (void) error(38); 2017*7c478bd9Sstevel@tonic-gate (void) strncpy(p, multic, n); 2018*7c478bd9Sstevel@tonic-gate p += n; 2019*7c478bd9Sstevel@tonic-gate } 2020*7c478bd9Sstevel@tonic-gate *p++ = 0; 2021*7c478bd9Sstevel@tonic-gate if (rhsbuf[0] == '%' && rhsbuf[1] == 0) 2022*7c478bd9Sstevel@tonic-gate /* 2023*7c478bd9Sstevel@tonic-gate * If there isn't a remembered string, it is an error; 2024*7c478bd9Sstevel@tonic-gate * otherwise the right hand side is the previous right 2025*7c478bd9Sstevel@tonic-gate * hand side. 2026*7c478bd9Sstevel@tonic-gate */ 2027*7c478bd9Sstevel@tonic-gate 2028*7c478bd9Sstevel@tonic-gate if (remflg == -1) 2029*7c478bd9Sstevel@tonic-gate (void) error(55); 2030*7c478bd9Sstevel@tonic-gate else 2031*7c478bd9Sstevel@tonic-gate strcpy(rhsbuf, remem); 2032*7c478bd9Sstevel@tonic-gate else { 2033*7c478bd9Sstevel@tonic-gate strcpy(remem, rhsbuf); 2034*7c478bd9Sstevel@tonic-gate remflg = 0; 2035*7c478bd9Sstevel@tonic-gate } 2036*7c478bd9Sstevel@tonic-gate c = 0; 2037*7c478bd9Sstevel@tonic-gate peekc = getchr(); /* Gets char after third delimiter. */ 2038*7c478bd9Sstevel@tonic-gate if (peekc == 'g') { 2039*7c478bd9Sstevel@tonic-gate c = LBSIZE; peekc = 0; 2040*7c478bd9Sstevel@tonic-gate } 2041*7c478bd9Sstevel@tonic-gate if (peekc >= '1' && peekc <= '9') { 2042*7c478bd9Sstevel@tonic-gate c = peekc-'0'; 2043*7c478bd9Sstevel@tonic-gate peekc = 0; /* Allows getchr() to get next char. */ 2044*7c478bd9Sstevel@tonic-gate while (1) { 2045*7c478bd9Sstevel@tonic-gate i = getchr(); 2046*7c478bd9Sstevel@tonic-gate if (i < '0' || i > '9') 2047*7c478bd9Sstevel@tonic-gate break; 2048*7c478bd9Sstevel@tonic-gate c = c*10 + i-'0'; 2049*7c478bd9Sstevel@tonic-gate if (c > LBSIZE-1) 2050*7c478bd9Sstevel@tonic-gate (void) error(20); /* "Illegal suffix" */ 2051*7c478bd9Sstevel@tonic-gate } 2052*7c478bd9Sstevel@tonic-gate peekc = i; /* Effectively an unget. */ 2053*7c478bd9Sstevel@tonic-gate } 2054*7c478bd9Sstevel@tonic-gate newline(); 2055*7c478bd9Sstevel@tonic-gate return (c); 2056*7c478bd9Sstevel@tonic-gate 2057*7c478bd9Sstevel@tonic-gate /* 2058*7c478bd9Sstevel@tonic-gate * Returns occurrence value. 0 & 1 both do first occurrence 2059*7c478bd9Sstevel@tonic-gate * only: c = 0 if ordinary substitute; c = 1 2060*7c478bd9Sstevel@tonic-gate * if use 1 in global sub(s/a/b/1). 0 in global form is illegal. 2061*7c478bd9Sstevel@tonic-gate */ 2062*7c478bd9Sstevel@tonic-gate } 2063*7c478bd9Sstevel@tonic-gate 2064*7c478bd9Sstevel@tonic-gate static int 2065*7c478bd9Sstevel@tonic-gate getsub(void) 2066*7c478bd9Sstevel@tonic-gate { 2067*7c478bd9Sstevel@tonic-gate char *p1, *p2; 2068*7c478bd9Sstevel@tonic-gate 2069*7c478bd9Sstevel@tonic-gate p1 = linebuf; 2070*7c478bd9Sstevel@tonic-gate if ((p2 = linebp) == 0) 2071*7c478bd9Sstevel@tonic-gate return (EOF); 2072*7c478bd9Sstevel@tonic-gate while (*p1++ = *p2++); 2073*7c478bd9Sstevel@tonic-gate linebp = 0; 2074*7c478bd9Sstevel@tonic-gate return (0); 2075*7c478bd9Sstevel@tonic-gate } 2076*7c478bd9Sstevel@tonic-gate 2077*7c478bd9Sstevel@tonic-gate static void 2078*7c478bd9Sstevel@tonic-gate dosub(void) 2079*7c478bd9Sstevel@tonic-gate { 2080*7c478bd9Sstevel@tonic-gate char *lp, *sp, *rp; 2081*7c478bd9Sstevel@tonic-gate int c; 2082*7c478bd9Sstevel@tonic-gate 2083*7c478bd9Sstevel@tonic-gate if (gsubf > 0 && gsubf < LBSIZE) { 2084*7c478bd9Sstevel@tonic-gate numpass++; 2085*7c478bd9Sstevel@tonic-gate if (gsubf != numpass) 2086*7c478bd9Sstevel@tonic-gate return; 2087*7c478bd9Sstevel@tonic-gate } 2088*7c478bd9Sstevel@tonic-gate ocerr1++; 2089*7c478bd9Sstevel@tonic-gate ocerr2++; 2090*7c478bd9Sstevel@tonic-gate lp = linebuf; 2091*7c478bd9Sstevel@tonic-gate sp = genbuf; 2092*7c478bd9Sstevel@tonic-gate rp = rhsbuf; 2093*7c478bd9Sstevel@tonic-gate while (lp < loc1) 2094*7c478bd9Sstevel@tonic-gate *sp++ = *lp++; 2095*7c478bd9Sstevel@tonic-gate while (c = *rp++) { 2096*7c478bd9Sstevel@tonic-gate if (c == '&') { 2097*7c478bd9Sstevel@tonic-gate sp = place(sp, loc1, loc2); 2098*7c478bd9Sstevel@tonic-gate continue; 2099*7c478bd9Sstevel@tonic-gate } else if (c == '\\') { 2100*7c478bd9Sstevel@tonic-gate c = *rp++; 2101*7c478bd9Sstevel@tonic-gate if (c >= '1' && c < nbra + '1') { 2102*7c478bd9Sstevel@tonic-gate sp = place(sp, braslist[c-'1'], braelist[c-'1']); 2103*7c478bd9Sstevel@tonic-gate continue; 2104*7c478bd9Sstevel@tonic-gate } 2105*7c478bd9Sstevel@tonic-gate } 2106*7c478bd9Sstevel@tonic-gate *sp++ = c; 2107*7c478bd9Sstevel@tonic-gate if (sp >= &genbuf[LBSIZE]) 2108*7c478bd9Sstevel@tonic-gate (void) error(27); 2109*7c478bd9Sstevel@tonic-gate } 2110*7c478bd9Sstevel@tonic-gate lp = loc2; 2111*7c478bd9Sstevel@tonic-gate loc2 = sp - genbuf + linebuf; 2112*7c478bd9Sstevel@tonic-gate while (*sp++ = *lp++) 2113*7c478bd9Sstevel@tonic-gate if (sp >= &genbuf[LBSIZE]) 2114*7c478bd9Sstevel@tonic-gate (void) error(27); 2115*7c478bd9Sstevel@tonic-gate lp = linebuf; 2116*7c478bd9Sstevel@tonic-gate sp = genbuf; 2117*7c478bd9Sstevel@tonic-gate while (*lp++ = *sp++); 2118*7c478bd9Sstevel@tonic-gate } 2119*7c478bd9Sstevel@tonic-gate 2120*7c478bd9Sstevel@tonic-gate static char * 2121*7c478bd9Sstevel@tonic-gate place(char *sp, char *l1, char *l2) 2122*7c478bd9Sstevel@tonic-gate { 2123*7c478bd9Sstevel@tonic-gate 2124*7c478bd9Sstevel@tonic-gate while (l1 < l2) { 2125*7c478bd9Sstevel@tonic-gate *sp++ = *l1++; 2126*7c478bd9Sstevel@tonic-gate if (sp >= &genbuf[LBSIZE]) 2127*7c478bd9Sstevel@tonic-gate (void) error(27); 2128*7c478bd9Sstevel@tonic-gate } 2129*7c478bd9Sstevel@tonic-gate return (sp); 2130*7c478bd9Sstevel@tonic-gate } 2131*7c478bd9Sstevel@tonic-gate 2132*7c478bd9Sstevel@tonic-gate static void 2133*7c478bd9Sstevel@tonic-gate comple(wchar_t seof) 2134*7c478bd9Sstevel@tonic-gate { 2135*7c478bd9Sstevel@tonic-gate int cclass = 0; 2136*7c478bd9Sstevel@tonic-gate wchar_t c; 2137*7c478bd9Sstevel@tonic-gate int n; 2138*7c478bd9Sstevel@tonic-gate char *cp = genbuf; 2139*7c478bd9Sstevel@tonic-gate char multic[MB_LEN_MAX]; 2140*7c478bd9Sstevel@tonic-gate 2141*7c478bd9Sstevel@tonic-gate while (1) { 2142*7c478bd9Sstevel@tonic-gate if ((n = _mbftowc(multic, &c, getchr, &peekc)) < 0) 2143*7c478bd9Sstevel@tonic-gate error1(67); 2144*7c478bd9Sstevel@tonic-gate if (n == 0 || c == '\n') { 2145*7c478bd9Sstevel@tonic-gate if (cclass) 2146*7c478bd9Sstevel@tonic-gate error1(49); 2147*7c478bd9Sstevel@tonic-gate else 2148*7c478bd9Sstevel@tonic-gate break; 2149*7c478bd9Sstevel@tonic-gate } 2150*7c478bd9Sstevel@tonic-gate if (c == seof && !cclass) 2151*7c478bd9Sstevel@tonic-gate break; 2152*7c478bd9Sstevel@tonic-gate if (cclass && c == ']') { 2153*7c478bd9Sstevel@tonic-gate cclass = 0; 2154*7c478bd9Sstevel@tonic-gate if (cp > &genbuf[LBSIZE-1]) 2155*7c478bd9Sstevel@tonic-gate error1(50); 2156*7c478bd9Sstevel@tonic-gate *cp++ = ']'; 2157*7c478bd9Sstevel@tonic-gate continue; 2158*7c478bd9Sstevel@tonic-gate } 2159*7c478bd9Sstevel@tonic-gate if (c == '[' && !cclass) { 2160*7c478bd9Sstevel@tonic-gate cclass = 1; 2161*7c478bd9Sstevel@tonic-gate if (cp > &genbuf[LBSIZE-1]) 2162*7c478bd9Sstevel@tonic-gate error1(50); 2163*7c478bd9Sstevel@tonic-gate *cp++ = '['; 2164*7c478bd9Sstevel@tonic-gate if ((n = _mbftowc(multic, &c, getchr, &peekc)) < 0) 2165*7c478bd9Sstevel@tonic-gate error1(67); 2166*7c478bd9Sstevel@tonic-gate if (n == 0 || c == '\n') 2167*7c478bd9Sstevel@tonic-gate error1(49); 2168*7c478bd9Sstevel@tonic-gate } 2169*7c478bd9Sstevel@tonic-gate if (c == '\\' && !cclass) { 2170*7c478bd9Sstevel@tonic-gate if (cp > &genbuf[LBSIZE-1]) 2171*7c478bd9Sstevel@tonic-gate error1(50); 2172*7c478bd9Sstevel@tonic-gate *cp++ = '\\'; 2173*7c478bd9Sstevel@tonic-gate if ((n = _mbftowc(multic, &c, getchr, &peekc)) < 0) 2174*7c478bd9Sstevel@tonic-gate error1(67); 2175*7c478bd9Sstevel@tonic-gate if (n == 0 || c == '\n') 2176*7c478bd9Sstevel@tonic-gate error1(36); 2177*7c478bd9Sstevel@tonic-gate } 2178*7c478bd9Sstevel@tonic-gate if (cp + n > &genbuf[LBSIZE-1]) 2179*7c478bd9Sstevel@tonic-gate error1(50); 2180*7c478bd9Sstevel@tonic-gate (void) strncpy(cp, multic, n); 2181*7c478bd9Sstevel@tonic-gate cp += n; 2182*7c478bd9Sstevel@tonic-gate } 2183*7c478bd9Sstevel@tonic-gate *cp = '\0'; 2184*7c478bd9Sstevel@tonic-gate if (n != 0 && c == '\n') 2185*7c478bd9Sstevel@tonic-gate UNGETC('\n'); 2186*7c478bd9Sstevel@tonic-gate if (n == 0 || c == '\n') 2187*7c478bd9Sstevel@tonic-gate nodelim = 1; 2188*7c478bd9Sstevel@tonic-gate 2189*7c478bd9Sstevel@tonic-gate /* 2190*7c478bd9Sstevel@tonic-gate * NULL RE: do not compile a null regular expression; but process 2191*7c478bd9Sstevel@tonic-gate * input with last regular expression encountered 2192*7c478bd9Sstevel@tonic-gate */ 2193*7c478bd9Sstevel@tonic-gate 2194*7c478bd9Sstevel@tonic-gate if (genbuf[0] != '\0') { 2195*7c478bd9Sstevel@tonic-gate if (expbuf) 2196*7c478bd9Sstevel@tonic-gate free(expbuf); 2197*7c478bd9Sstevel@tonic-gate expbuf = compile(genbuf, (char *)0, (char *)0); 2198*7c478bd9Sstevel@tonic-gate } 2199*7c478bd9Sstevel@tonic-gate if (regerrno) 2200*7c478bd9Sstevel@tonic-gate error1(regerrno); 2201*7c478bd9Sstevel@tonic-gate } 2202*7c478bd9Sstevel@tonic-gate 2203*7c478bd9Sstevel@tonic-gate static void 2204*7c478bd9Sstevel@tonic-gate move(int cflag) 2205*7c478bd9Sstevel@tonic-gate { 2206*7c478bd9Sstevel@tonic-gate LINE adt, ad1, ad2; 2207*7c478bd9Sstevel@tonic-gate 2208*7c478bd9Sstevel@tonic-gate setdot(); 2209*7c478bd9Sstevel@tonic-gate nonzero(); 2210*7c478bd9Sstevel@tonic-gate if ((adt = address()) == 0) 2211*7c478bd9Sstevel@tonic-gate (void) error(39); 2212*7c478bd9Sstevel@tonic-gate newline(); 2213*7c478bd9Sstevel@tonic-gate if (!globflg) save(); 2214*7c478bd9Sstevel@tonic-gate if (cflag) { 2215*7c478bd9Sstevel@tonic-gate ad1 = dol; 2216*7c478bd9Sstevel@tonic-gate append(getcopy, ad1++); 2217*7c478bd9Sstevel@tonic-gate ad2 = dol; 2218*7c478bd9Sstevel@tonic-gate } else { 2219*7c478bd9Sstevel@tonic-gate ad2 = addr2; 2220*7c478bd9Sstevel@tonic-gate for (ad1 = addr1; ad1 <= ad2; ) 2221*7c478bd9Sstevel@tonic-gate (ad1++)->cur &= ~01; 2222*7c478bd9Sstevel@tonic-gate ad1 = addr1; 2223*7c478bd9Sstevel@tonic-gate } 2224*7c478bd9Sstevel@tonic-gate ad2++; 2225*7c478bd9Sstevel@tonic-gate if (adt < ad1) { 2226*7c478bd9Sstevel@tonic-gate dot = adt + (ad2-ad1); 2227*7c478bd9Sstevel@tonic-gate if ((++adt) == ad1) 2228*7c478bd9Sstevel@tonic-gate return; 2229*7c478bd9Sstevel@tonic-gate reverse(adt, ad1); 2230*7c478bd9Sstevel@tonic-gate reverse(ad1, ad2); 2231*7c478bd9Sstevel@tonic-gate reverse(adt, ad2); 2232*7c478bd9Sstevel@tonic-gate } else if (adt >= ad2) { 2233*7c478bd9Sstevel@tonic-gate dot = adt++; 2234*7c478bd9Sstevel@tonic-gate reverse(ad1, ad2); 2235*7c478bd9Sstevel@tonic-gate reverse(ad2, adt); 2236*7c478bd9Sstevel@tonic-gate reverse(ad1, adt); 2237*7c478bd9Sstevel@tonic-gate } else 2238*7c478bd9Sstevel@tonic-gate (void) error(39); 2239*7c478bd9Sstevel@tonic-gate fchange = 1; 2240*7c478bd9Sstevel@tonic-gate } 2241*7c478bd9Sstevel@tonic-gate 2242*7c478bd9Sstevel@tonic-gate static void 2243*7c478bd9Sstevel@tonic-gate reverse(LINE a1, LINE a2) 2244*7c478bd9Sstevel@tonic-gate { 2245*7c478bd9Sstevel@tonic-gate long t; 2246*7c478bd9Sstevel@tonic-gate 2247*7c478bd9Sstevel@tonic-gate for (;;) { 2248*7c478bd9Sstevel@tonic-gate t = (--a2)->cur; 2249*7c478bd9Sstevel@tonic-gate if (a2 <= a1) 2250*7c478bd9Sstevel@tonic-gate return; 2251*7c478bd9Sstevel@tonic-gate a2->cur = a1->cur; 2252*7c478bd9Sstevel@tonic-gate (a1++)->cur = t; 2253*7c478bd9Sstevel@tonic-gate } 2254*7c478bd9Sstevel@tonic-gate } 2255*7c478bd9Sstevel@tonic-gate 2256*7c478bd9Sstevel@tonic-gate static int 2257*7c478bd9Sstevel@tonic-gate getcopy(void) 2258*7c478bd9Sstevel@tonic-gate { 2259*7c478bd9Sstevel@tonic-gate 2260*7c478bd9Sstevel@tonic-gate if (addr1 > addr2) 2261*7c478bd9Sstevel@tonic-gate return (EOF); 2262*7c478bd9Sstevel@tonic-gate (void) getline((addr1++)->cur); 2263*7c478bd9Sstevel@tonic-gate return (0); 2264*7c478bd9Sstevel@tonic-gate } 2265*7c478bd9Sstevel@tonic-gate 2266*7c478bd9Sstevel@tonic-gate 2267*7c478bd9Sstevel@tonic-gate /* 2268*7c478bd9Sstevel@tonic-gate * Handles error code returned from comple() routine: regular expression 2269*7c478bd9Sstevel@tonic-gate * compile and match routines 2270*7c478bd9Sstevel@tonic-gate */ 2271*7c478bd9Sstevel@tonic-gate 2272*7c478bd9Sstevel@tonic-gate static void 2273*7c478bd9Sstevel@tonic-gate error1(int code) 2274*7c478bd9Sstevel@tonic-gate { 2275*7c478bd9Sstevel@tonic-gate nbra = 0; 2276*7c478bd9Sstevel@tonic-gate (void) error(code); 2277*7c478bd9Sstevel@tonic-gate } 2278*7c478bd9Sstevel@tonic-gate 2279*7c478bd9Sstevel@tonic-gate 2280*7c478bd9Sstevel@tonic-gate static int 2281*7c478bd9Sstevel@tonic-gate execute(int gf, LINE addr) 2282*7c478bd9Sstevel@tonic-gate { 2283*7c478bd9Sstevel@tonic-gate char *p1; 2284*7c478bd9Sstevel@tonic-gate int c; 2285*7c478bd9Sstevel@tonic-gate 2286*7c478bd9Sstevel@tonic-gate for (c = 0; c < nbra; c++) { 2287*7c478bd9Sstevel@tonic-gate braslist[c] = 0; 2288*7c478bd9Sstevel@tonic-gate braelist[c] = 0; 2289*7c478bd9Sstevel@tonic-gate } 2290*7c478bd9Sstevel@tonic-gate if (gf) 2291*7c478bd9Sstevel@tonic-gate locs = p1 = loc2; 2292*7c478bd9Sstevel@tonic-gate else { 2293*7c478bd9Sstevel@tonic-gate if (addr == zero) 2294*7c478bd9Sstevel@tonic-gate return (0); 2295*7c478bd9Sstevel@tonic-gate p1 = getline(addr->cur); 2296*7c478bd9Sstevel@tonic-gate locs = 0; 2297*7c478bd9Sstevel@tonic-gate } 2298*7c478bd9Sstevel@tonic-gate return (step(p1, expbuf)); 2299*7c478bd9Sstevel@tonic-gate } 2300*7c478bd9Sstevel@tonic-gate 2301*7c478bd9Sstevel@tonic-gate 2302*7c478bd9Sstevel@tonic-gate static void 2303*7c478bd9Sstevel@tonic-gate putd() 2304*7c478bd9Sstevel@tonic-gate { 2305*7c478bd9Sstevel@tonic-gate int r; 2306*7c478bd9Sstevel@tonic-gate 2307*7c478bd9Sstevel@tonic-gate r = (int)(count%10); 2308*7c478bd9Sstevel@tonic-gate count /= 10; 2309*7c478bd9Sstevel@tonic-gate if (count) 2310*7c478bd9Sstevel@tonic-gate putd(); 2311*7c478bd9Sstevel@tonic-gate putchr(r + '0'); 2312*7c478bd9Sstevel@tonic-gate } 2313*7c478bd9Sstevel@tonic-gate 2314*7c478bd9Sstevel@tonic-gate 2315*7c478bd9Sstevel@tonic-gate int 2316*7c478bd9Sstevel@tonic-gate puts(const char *sp) 2317*7c478bd9Sstevel@tonic-gate { 2318*7c478bd9Sstevel@tonic-gate int n; 2319*7c478bd9Sstevel@tonic-gate wchar_t c; 2320*7c478bd9Sstevel@tonic-gate int sz, i; 2321*7c478bd9Sstevel@tonic-gate if (fss.Ffill && (listf == 0)) { 2322*7c478bd9Sstevel@tonic-gate 2323*7c478bd9Sstevel@tonic-gate /* deliberate attempt to remove constness of sp because */ 2324*7c478bd9Sstevel@tonic-gate /* it needs to be expanded */ 2325*7c478bd9Sstevel@tonic-gate 2326*7c478bd9Sstevel@tonic-gate if ((i = expnd((char *)sp, funny, &sz, &fss)) == -1) { 2327*7c478bd9Sstevel@tonic-gate write(1, funny, fss.Flim & 0377); 2328*7c478bd9Sstevel@tonic-gate putchr('\n'); 2329*7c478bd9Sstevel@tonic-gate write(1, gettext("too long"), 2330*7c478bd9Sstevel@tonic-gate strlen(gettext("too long"))); 2331*7c478bd9Sstevel@tonic-gate } 2332*7c478bd9Sstevel@tonic-gate else 2333*7c478bd9Sstevel@tonic-gate write(1, funny, sz); 2334*7c478bd9Sstevel@tonic-gate putchr('\n'); 2335*7c478bd9Sstevel@tonic-gate if (i == -2) 2336*7c478bd9Sstevel@tonic-gate write(1, gettext("tab count\n"), 2337*7c478bd9Sstevel@tonic-gate strlen(gettext("tab count\n"))); 2338*7c478bd9Sstevel@tonic-gate return (0); 2339*7c478bd9Sstevel@tonic-gate } 2340*7c478bd9Sstevel@tonic-gate col = 0; 2341*7c478bd9Sstevel@tonic-gate while (*sp) { 2342*7c478bd9Sstevel@tonic-gate n = mbtowc(&c, sp, MB_LEN_MAX); 2343*7c478bd9Sstevel@tonic-gate if (listf) { 2344*7c478bd9Sstevel@tonic-gate if (n < 1) 2345*7c478bd9Sstevel@tonic-gate (void) error(28); 2346*7c478bd9Sstevel@tonic-gate else if (n == 1) 2347*7c478bd9Sstevel@tonic-gate putchr((unsigned char)*sp++); 2348*7c478bd9Sstevel@tonic-gate else { 2349*7c478bd9Sstevel@tonic-gate sp += n; 2350*7c478bd9Sstevel@tonic-gate putwchr(c); 2351*7c478bd9Sstevel@tonic-gate } 2352*7c478bd9Sstevel@tonic-gate } else { 2353*7c478bd9Sstevel@tonic-gate putchr((unsigned char)*sp++); 2354*7c478bd9Sstevel@tonic-gate } 2355*7c478bd9Sstevel@tonic-gate } 2356*7c478bd9Sstevel@tonic-gate #ifndef XPG6 2357*7c478bd9Sstevel@tonic-gate if (listf) 2358*7c478bd9Sstevel@tonic-gate putchr('$'); /* end of line is marked with a $ */ 2359*7c478bd9Sstevel@tonic-gate #else 2360*7c478bd9Sstevel@tonic-gate if (listf) { 2361*7c478bd9Sstevel@tonic-gate /* xpg6 - ensure that the end of line $ is not preceeded with a "\" */ 2362*7c478bd9Sstevel@tonic-gate /* by doing a putchr() with listf=0, thereby avoiding the $ case */ 2363*7c478bd9Sstevel@tonic-gate /* statement in putchr() */ 2364*7c478bd9Sstevel@tonic-gate listf = 0; 2365*7c478bd9Sstevel@tonic-gate putchr('$'); /* end of line is marked with a $ */ 2366*7c478bd9Sstevel@tonic-gate listf++; 2367*7c478bd9Sstevel@tonic-gate } 2368*7c478bd9Sstevel@tonic-gate #endif 2369*7c478bd9Sstevel@tonic-gate putchr('\n'); 2370*7c478bd9Sstevel@tonic-gate return (1); 2371*7c478bd9Sstevel@tonic-gate } 2372*7c478bd9Sstevel@tonic-gate 2373*7c478bd9Sstevel@tonic-gate 2374*7c478bd9Sstevel@tonic-gate static void 2375*7c478bd9Sstevel@tonic-gate putwchr(wchar_t ac) 2376*7c478bd9Sstevel@tonic-gate { 2377*7c478bd9Sstevel@tonic-gate char buf[MB_LEN_MAX], *p; 2378*7c478bd9Sstevel@tonic-gate char *lp; 2379*7c478bd9Sstevel@tonic-gate wchar_t c; 2380*7c478bd9Sstevel@tonic-gate short len; 2381*7c478bd9Sstevel@tonic-gate 2382*7c478bd9Sstevel@tonic-gate lp = linp; 2383*7c478bd9Sstevel@tonic-gate c = ac; 2384*7c478bd9Sstevel@tonic-gate if (listf) { 2385*7c478bd9Sstevel@tonic-gate if (!iswprint(c)) { 2386*7c478bd9Sstevel@tonic-gate p = &buf[0]; 2387*7c478bd9Sstevel@tonic-gate if ((len = wctomb(p, c)) <= 0) { 2388*7c478bd9Sstevel@tonic-gate *p = (unsigned char)c; 2389*7c478bd9Sstevel@tonic-gate len = 1; 2390*7c478bd9Sstevel@tonic-gate }; 2391*7c478bd9Sstevel@tonic-gate while (len--) { 2392*7c478bd9Sstevel@tonic-gate if (col + 4 >= 72) { 2393*7c478bd9Sstevel@tonic-gate col = 0; 2394*7c478bd9Sstevel@tonic-gate *lp++ = '\\'; 2395*7c478bd9Sstevel@tonic-gate *lp++ = '\n'; 2396*7c478bd9Sstevel@tonic-gate } 2397*7c478bd9Sstevel@tonic-gate (void) sprintf(lp, "\\%03o", 2398*7c478bd9Sstevel@tonic-gate *(unsigned char *)p++); 2399*7c478bd9Sstevel@tonic-gate col += 4; 2400*7c478bd9Sstevel@tonic-gate lp += 4; 2401*7c478bd9Sstevel@tonic-gate } 2402*7c478bd9Sstevel@tonic-gate } else { 2403*7c478bd9Sstevel@tonic-gate if ((len = wcwidth(c)) <= 0) 2404*7c478bd9Sstevel@tonic-gate len = 0; 2405*7c478bd9Sstevel@tonic-gate if (col + len >= 72) { 2406*7c478bd9Sstevel@tonic-gate col = 0; 2407*7c478bd9Sstevel@tonic-gate *lp++ = '\\'; 2408*7c478bd9Sstevel@tonic-gate *lp++ = '\n'; 2409*7c478bd9Sstevel@tonic-gate } 2410*7c478bd9Sstevel@tonic-gate col += len; 2411*7c478bd9Sstevel@tonic-gate if ((len = wctomb(lp, c)) <= 0) { 2412*7c478bd9Sstevel@tonic-gate *lp = (unsigned char)c; 2413*7c478bd9Sstevel@tonic-gate len = 1; 2414*7c478bd9Sstevel@tonic-gate } 2415*7c478bd9Sstevel@tonic-gate lp += len; 2416*7c478bd9Sstevel@tonic-gate } 2417*7c478bd9Sstevel@tonic-gate } else { 2418*7c478bd9Sstevel@tonic-gate if ((len = wctomb(lp, c)) <= 0) { 2419*7c478bd9Sstevel@tonic-gate *lp = (unsigned char)c; 2420*7c478bd9Sstevel@tonic-gate len = 1; 2421*7c478bd9Sstevel@tonic-gate } 2422*7c478bd9Sstevel@tonic-gate lp += len; 2423*7c478bd9Sstevel@tonic-gate } 2424*7c478bd9Sstevel@tonic-gate if (c == '\n' || lp >= &line[64]) { 2425*7c478bd9Sstevel@tonic-gate linp = line; 2426*7c478bd9Sstevel@tonic-gate len = lp - line; 2427*7c478bd9Sstevel@tonic-gate write(1, line, len); 2428*7c478bd9Sstevel@tonic-gate return; 2429*7c478bd9Sstevel@tonic-gate } 2430*7c478bd9Sstevel@tonic-gate linp = lp; 2431*7c478bd9Sstevel@tonic-gate } 2432*7c478bd9Sstevel@tonic-gate 2433*7c478bd9Sstevel@tonic-gate 2434*7c478bd9Sstevel@tonic-gate static void 2435*7c478bd9Sstevel@tonic-gate putchr(unsigned char c) 2436*7c478bd9Sstevel@tonic-gate { 2437*7c478bd9Sstevel@tonic-gate char *lp; 2438*7c478bd9Sstevel@tonic-gate int len; 2439*7c478bd9Sstevel@tonic-gate 2440*7c478bd9Sstevel@tonic-gate lp = linp; 2441*7c478bd9Sstevel@tonic-gate if (listf && c != '\n') { 2442*7c478bd9Sstevel@tonic-gate switch (c) { 2443*7c478bd9Sstevel@tonic-gate case '\\' : 2444*7c478bd9Sstevel@tonic-gate *lp++ = '\\'; 2445*7c478bd9Sstevel@tonic-gate *lp++ = '\\'; 2446*7c478bd9Sstevel@tonic-gate col += 2; 2447*7c478bd9Sstevel@tonic-gate break; 2448*7c478bd9Sstevel@tonic-gate case '\007' : 2449*7c478bd9Sstevel@tonic-gate *lp++ = '\\'; 2450*7c478bd9Sstevel@tonic-gate *lp++ = 'a'; 2451*7c478bd9Sstevel@tonic-gate col += 2; 2452*7c478bd9Sstevel@tonic-gate break; 2453*7c478bd9Sstevel@tonic-gate case '\b' : 2454*7c478bd9Sstevel@tonic-gate *lp++ = '\\'; 2455*7c478bd9Sstevel@tonic-gate *lp++ = 'b'; 2456*7c478bd9Sstevel@tonic-gate col += 2; 2457*7c478bd9Sstevel@tonic-gate break; 2458*7c478bd9Sstevel@tonic-gate case '\f' : 2459*7c478bd9Sstevel@tonic-gate *lp++ = '\\'; 2460*7c478bd9Sstevel@tonic-gate *lp++ = 'f'; 2461*7c478bd9Sstevel@tonic-gate col += 2; 2462*7c478bd9Sstevel@tonic-gate break; 2463*7c478bd9Sstevel@tonic-gate case '\r' : 2464*7c478bd9Sstevel@tonic-gate *lp++ = '\\'; 2465*7c478bd9Sstevel@tonic-gate *lp++ = 'r'; 2466*7c478bd9Sstevel@tonic-gate col += 2; 2467*7c478bd9Sstevel@tonic-gate break; 2468*7c478bd9Sstevel@tonic-gate case '\t' : 2469*7c478bd9Sstevel@tonic-gate *lp++ = '\\'; 2470*7c478bd9Sstevel@tonic-gate *lp++ = 't'; 2471*7c478bd9Sstevel@tonic-gate col += 2; 2472*7c478bd9Sstevel@tonic-gate break; 2473*7c478bd9Sstevel@tonic-gate case '\v' : 2474*7c478bd9Sstevel@tonic-gate *lp++ = '\\'; 2475*7c478bd9Sstevel@tonic-gate *lp++ = 'v'; 2476*7c478bd9Sstevel@tonic-gate col += 2; 2477*7c478bd9Sstevel@tonic-gate break; 2478*7c478bd9Sstevel@tonic-gate #ifdef XPG6 2479*7c478bd9Sstevel@tonic-gate /* if $ characters are within the line preceed with \ */ 2480*7c478bd9Sstevel@tonic-gate case '$' : 2481*7c478bd9Sstevel@tonic-gate *lp++ = '\\'; 2482*7c478bd9Sstevel@tonic-gate *lp++ = '$'; 2483*7c478bd9Sstevel@tonic-gate col += 2; 2484*7c478bd9Sstevel@tonic-gate break; 2485*7c478bd9Sstevel@tonic-gate #endif 2486*7c478bd9Sstevel@tonic-gate default: 2487*7c478bd9Sstevel@tonic-gate if (isprint(c)) { 2488*7c478bd9Sstevel@tonic-gate *lp++ = c; 2489*7c478bd9Sstevel@tonic-gate col += 1; 2490*7c478bd9Sstevel@tonic-gate } else { 2491*7c478bd9Sstevel@tonic-gate (void) sprintf(lp, "\\%03o", c); 2492*7c478bd9Sstevel@tonic-gate col += 4; 2493*7c478bd9Sstevel@tonic-gate lp += 4; 2494*7c478bd9Sstevel@tonic-gate } 2495*7c478bd9Sstevel@tonic-gate break; 2496*7c478bd9Sstevel@tonic-gate } 2497*7c478bd9Sstevel@tonic-gate 2498*7c478bd9Sstevel@tonic-gate /* 2499*7c478bd9Sstevel@tonic-gate * long lines are folded w/ pt of folding indicated by writing 2500*7c478bd9Sstevel@tonic-gate * backslash/newline character 2501*7c478bd9Sstevel@tonic-gate */ 2502*7c478bd9Sstevel@tonic-gate 2503*7c478bd9Sstevel@tonic-gate if (col + 1 >= 72) { 2504*7c478bd9Sstevel@tonic-gate col = 0; 2505*7c478bd9Sstevel@tonic-gate *lp++ = '\\'; 2506*7c478bd9Sstevel@tonic-gate *lp++ = '\n'; 2507*7c478bd9Sstevel@tonic-gate } 2508*7c478bd9Sstevel@tonic-gate } else 2509*7c478bd9Sstevel@tonic-gate *lp++ = c; 2510*7c478bd9Sstevel@tonic-gate if (c == '\n' || lp >= &line[64]) { 2511*7c478bd9Sstevel@tonic-gate linp = line; 2512*7c478bd9Sstevel@tonic-gate len = lp - line; 2513*7c478bd9Sstevel@tonic-gate (void) write(1, line, len); 2514*7c478bd9Sstevel@tonic-gate return; 2515*7c478bd9Sstevel@tonic-gate } 2516*7c478bd9Sstevel@tonic-gate linp = lp; 2517*7c478bd9Sstevel@tonic-gate } 2518*7c478bd9Sstevel@tonic-gate 2519*7c478bd9Sstevel@tonic-gate 2520*7c478bd9Sstevel@tonic-gate static char * 2521*7c478bd9Sstevel@tonic-gate getkey(const char *prompt) 2522*7c478bd9Sstevel@tonic-gate { 2523*7c478bd9Sstevel@tonic-gate struct termio b; 2524*7c478bd9Sstevel@tonic-gate int save; 2525*7c478bd9Sstevel@tonic-gate void (*sig)(); 2526*7c478bd9Sstevel@tonic-gate static char key[KSIZE+1]; 2527*7c478bd9Sstevel@tonic-gate char *p; 2528*7c478bd9Sstevel@tonic-gate int c; 2529*7c478bd9Sstevel@tonic-gate 2530*7c478bd9Sstevel@tonic-gate sig = signal(SIGINT, SIG_IGN); 2531*7c478bd9Sstevel@tonic-gate ioctl(0, TCGETA, &b); 2532*7c478bd9Sstevel@tonic-gate save = b.c_lflag; 2533*7c478bd9Sstevel@tonic-gate b.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL); 2534*7c478bd9Sstevel@tonic-gate ioctl(0, TCSETAW, &b); 2535*7c478bd9Sstevel@tonic-gate write(1, gettext(prompt), strlen(gettext(prompt))); 2536*7c478bd9Sstevel@tonic-gate p = key; 2537*7c478bd9Sstevel@tonic-gate while (((c = getchr()) != EOF) && (c != '\n')) { 2538*7c478bd9Sstevel@tonic-gate if (p < &key[KSIZE]) 2539*7c478bd9Sstevel@tonic-gate *p++ = c; 2540*7c478bd9Sstevel@tonic-gate } 2541*7c478bd9Sstevel@tonic-gate *p = 0; 2542*7c478bd9Sstevel@tonic-gate write(1, "\n", 1); 2543*7c478bd9Sstevel@tonic-gate b.c_lflag = save; 2544*7c478bd9Sstevel@tonic-gate ioctl(0, TCSETAW, &b); 2545*7c478bd9Sstevel@tonic-gate signal(SIGINT, sig); 2546*7c478bd9Sstevel@tonic-gate return (key); 2547*7c478bd9Sstevel@tonic-gate } 2548*7c478bd9Sstevel@tonic-gate 2549*7c478bd9Sstevel@tonic-gate 2550*7c478bd9Sstevel@tonic-gate static void 2551*7c478bd9Sstevel@tonic-gate globaln(int k) 2552*7c478bd9Sstevel@tonic-gate { 2553*7c478bd9Sstevel@tonic-gate char *gp; 2554*7c478bd9Sstevel@tonic-gate int c; 2555*7c478bd9Sstevel@tonic-gate int n; 2556*7c478bd9Sstevel@tonic-gate wchar_t cl; 2557*7c478bd9Sstevel@tonic-gate LINE a1; 2558*7c478bd9Sstevel@tonic-gate int nfirst; 2559*7c478bd9Sstevel@tonic-gate char globuf[LBSIZE]; 2560*7c478bd9Sstevel@tonic-gate char multic[MB_LEN_MAX]; 2561*7c478bd9Sstevel@tonic-gate int len; 2562*7c478bd9Sstevel@tonic-gate int pflag_save = 0; 2563*7c478bd9Sstevel@tonic-gate int listf_save = 0; 2564*7c478bd9Sstevel@tonic-gate int listn_save = 0; 2565*7c478bd9Sstevel@tonic-gate 2566*7c478bd9Sstevel@tonic-gate if (globp) 2567*7c478bd9Sstevel@tonic-gate (void) error(33); 2568*7c478bd9Sstevel@tonic-gate setall(); 2569*7c478bd9Sstevel@tonic-gate nonzero(); 2570*7c478bd9Sstevel@tonic-gate if ((n = _mbftowc(multic, &cl, getchr, &peekc)) <= 0) 2571*7c478bd9Sstevel@tonic-gate (void) error(67); 2572*7c478bd9Sstevel@tonic-gate if (cl == '\n') 2573*7c478bd9Sstevel@tonic-gate (void) error(19); 2574*7c478bd9Sstevel@tonic-gate save(); 2575*7c478bd9Sstevel@tonic-gate comple(cl); 2576*7c478bd9Sstevel@tonic-gate for (a1 = zero; a1 <= dol; a1++) { 2577*7c478bd9Sstevel@tonic-gate a1->cur &= ~01; 2578*7c478bd9Sstevel@tonic-gate if (a1 >= addr1 && a1 <= addr2 && execute(0, a1) == k) 2579*7c478bd9Sstevel@tonic-gate a1->cur |= 01; 2580*7c478bd9Sstevel@tonic-gate } 2581*7c478bd9Sstevel@tonic-gate nfirst = 0; 2582*7c478bd9Sstevel@tonic-gate newline(); 2583*7c478bd9Sstevel@tonic-gate /* 2584*7c478bd9Sstevel@tonic-gate * preserve the p, l, and n suffix commands of the G and V 2585*7c478bd9Sstevel@tonic-gate * commands during the interactive section and restore 2586*7c478bd9Sstevel@tonic-gate * on completion of the G and V command. 2587*7c478bd9Sstevel@tonic-gate */ 2588*7c478bd9Sstevel@tonic-gate pflag_save = pflag; 2589*7c478bd9Sstevel@tonic-gate listf_save = listf; 2590*7c478bd9Sstevel@tonic-gate listn_save = listn; 2591*7c478bd9Sstevel@tonic-gate pflag = 0; 2592*7c478bd9Sstevel@tonic-gate listf = 0; 2593*7c478bd9Sstevel@tonic-gate listn = 0; 2594*7c478bd9Sstevel@tonic-gate for (a1 = zero; a1 <= dol; a1++) { 2595*7c478bd9Sstevel@tonic-gate if (a1->cur & 01) { 2596*7c478bd9Sstevel@tonic-gate a1->cur &= ~01; 2597*7c478bd9Sstevel@tonic-gate dot = a1; 2598*7c478bd9Sstevel@tonic-gate puts(getline(a1->cur)); 2599*7c478bd9Sstevel@tonic-gate if ((c = get_wchr()) == EOF) 2600*7c478bd9Sstevel@tonic-gate (void) error(52); 2601*7c478bd9Sstevel@tonic-gate if (c == 'a' || c == 'i' || c == 'c') 2602*7c478bd9Sstevel@tonic-gate (void) error(53); 2603*7c478bd9Sstevel@tonic-gate if (c == '\n') { 2604*7c478bd9Sstevel@tonic-gate a1 = zero; 2605*7c478bd9Sstevel@tonic-gate continue; 2606*7c478bd9Sstevel@tonic-gate } 2607*7c478bd9Sstevel@tonic-gate if (c != '&') { 2608*7c478bd9Sstevel@tonic-gate gp = globuf; 2609*7c478bd9Sstevel@tonic-gate if ((len = wctomb(gp, c)) <= 0) { 2610*7c478bd9Sstevel@tonic-gate *gp = (unsigned char)c; 2611*7c478bd9Sstevel@tonic-gate len = 1; 2612*7c478bd9Sstevel@tonic-gate } 2613*7c478bd9Sstevel@tonic-gate gp += len; 2614*7c478bd9Sstevel@tonic-gate while ((c = get_wchr()) != '\n') { 2615*7c478bd9Sstevel@tonic-gate 2616*7c478bd9Sstevel@tonic-gate /* '\\' has special meaning only if preceding a '\n' */ 2617*7c478bd9Sstevel@tonic-gate if (c == '\\') { 2618*7c478bd9Sstevel@tonic-gate c = get_wchr(); 2619*7c478bd9Sstevel@tonic-gate if (c != '\n') 2620*7c478bd9Sstevel@tonic-gate *gp++ = '\\'; 2621*7c478bd9Sstevel@tonic-gate } 2622*7c478bd9Sstevel@tonic-gate if ((gp + (unsigned int)MB_CUR_MAX) >= 2623*7c478bd9Sstevel@tonic-gate &globuf[LBSIZE-1]) 2624*7c478bd9Sstevel@tonic-gate (void) error(34); 2625*7c478bd9Sstevel@tonic-gate 2626*7c478bd9Sstevel@tonic-gate if ((len = wctomb(gp, c)) <= 0) { 2627*7c478bd9Sstevel@tonic-gate *gp = (unsigned char)c; 2628*7c478bd9Sstevel@tonic-gate len = 1; 2629*7c478bd9Sstevel@tonic-gate } 2630*7c478bd9Sstevel@tonic-gate gp += len; 2631*7c478bd9Sstevel@tonic-gate } 2632*7c478bd9Sstevel@tonic-gate *gp++ = '\n'; 2633*7c478bd9Sstevel@tonic-gate *gp++ = 0; 2634*7c478bd9Sstevel@tonic-gate nfirst = 1; 2635*7c478bd9Sstevel@tonic-gate } else if ((c = get_wchr()) != '\n') 2636*7c478bd9Sstevel@tonic-gate (void) error(54); 2637*7c478bd9Sstevel@tonic-gate globp = globuf; 2638*7c478bd9Sstevel@tonic-gate if (nfirst) { 2639*7c478bd9Sstevel@tonic-gate globflg = 1; 2640*7c478bd9Sstevel@tonic-gate commands(); 2641*7c478bd9Sstevel@tonic-gate globflg = 0; 2642*7c478bd9Sstevel@tonic-gate } else 2643*7c478bd9Sstevel@tonic-gate (void) error(56); 2644*7c478bd9Sstevel@tonic-gate globp = 0; 2645*7c478bd9Sstevel@tonic-gate a1 = zero; 2646*7c478bd9Sstevel@tonic-gate } 2647*7c478bd9Sstevel@tonic-gate } 2648*7c478bd9Sstevel@tonic-gate pflag = pflag_save; 2649*7c478bd9Sstevel@tonic-gate listf = listf_save; 2650*7c478bd9Sstevel@tonic-gate listn = listn_save; 2651*7c478bd9Sstevel@tonic-gate } 2652*7c478bd9Sstevel@tonic-gate 2653*7c478bd9Sstevel@tonic-gate 2654*7c478bd9Sstevel@tonic-gate static int 2655*7c478bd9Sstevel@tonic-gate eopen(char *string, int rw) 2656*7c478bd9Sstevel@tonic-gate { 2657*7c478bd9Sstevel@tonic-gate #define w_or_r(a, b) (rw ? a : b) 2658*7c478bd9Sstevel@tonic-gate int pf[2]; 2659*7c478bd9Sstevel@tonic-gate pid_t i; 2660*7c478bd9Sstevel@tonic-gate int io; 2661*7c478bd9Sstevel@tonic-gate int chcount; /* # of char read. */ 2662*7c478bd9Sstevel@tonic-gate 2663*7c478bd9Sstevel@tonic-gate if (rflg) { /* restricted shell */ 2664*7c478bd9Sstevel@tonic-gate if (Xqt) { 2665*7c478bd9Sstevel@tonic-gate Xqt = 0; 2666*7c478bd9Sstevel@tonic-gate (void) error(6); 2667*7c478bd9Sstevel@tonic-gate } 2668*7c478bd9Sstevel@tonic-gate } 2669*7c478bd9Sstevel@tonic-gate if (!Xqt) { 2670*7c478bd9Sstevel@tonic-gate if ((io = open(string, rw)) >= 0) { 2671*7c478bd9Sstevel@tonic-gate if (fflg) { 2672*7c478bd9Sstevel@tonic-gate chcount = read(io, crbuf, LBSIZE); 2673*7c478bd9Sstevel@tonic-gate if (crflag == -1) { 2674*7c478bd9Sstevel@tonic-gate if (isencrypt(crbuf, chcount)) 2675*7c478bd9Sstevel@tonic-gate crflag = 2; 2676*7c478bd9Sstevel@tonic-gate else 2677*7c478bd9Sstevel@tonic-gate crflag = -2; 2678*7c478bd9Sstevel@tonic-gate } 2679*7c478bd9Sstevel@tonic-gate if (crflag > 0) 2680*7c478bd9Sstevel@tonic-gate if (run_crypt(0L, crbuf, chcount, perm) == -1) 2681*7c478bd9Sstevel@tonic-gate (void) error(63); 2682*7c478bd9Sstevel@tonic-gate if (fspec(crbuf, &fss, 0) < 0) { 2683*7c478bd9Sstevel@tonic-gate fss.Ffill = 0; 2684*7c478bd9Sstevel@tonic-gate fflg = 0; 2685*7c478bd9Sstevel@tonic-gate (void) error(4); 2686*7c478bd9Sstevel@tonic-gate } 2687*7c478bd9Sstevel@tonic-gate lseek(io, 0L, 0); 2688*7c478bd9Sstevel@tonic-gate } 2689*7c478bd9Sstevel@tonic-gate } 2690*7c478bd9Sstevel@tonic-gate fflg = 0; 2691*7c478bd9Sstevel@tonic-gate return (io); 2692*7c478bd9Sstevel@tonic-gate } 2693*7c478bd9Sstevel@tonic-gate if (pipe(pf) < 0) 2694*7c478bd9Sstevel@tonic-gate xerr: (void) error(0); 2695*7c478bd9Sstevel@tonic-gate if ((i = fork()) == 0) { 2696*7c478bd9Sstevel@tonic-gate signal(SIGHUP, oldhup); 2697*7c478bd9Sstevel@tonic-gate signal(SIGQUIT, oldquit); 2698*7c478bd9Sstevel@tonic-gate signal(SIGPIPE, oldpipe); 2699*7c478bd9Sstevel@tonic-gate signal(SIGINT, (void (*)()) 0); 2700*7c478bd9Sstevel@tonic-gate close(w_or_r(pf[1], pf[0])); 2701*7c478bd9Sstevel@tonic-gate close(w_or_r(0, 1)); 2702*7c478bd9Sstevel@tonic-gate dup(w_or_r(pf[0], pf[1])); 2703*7c478bd9Sstevel@tonic-gate close(w_or_r(pf[0], pf[1])); 2704*7c478bd9Sstevel@tonic-gate if (__xpg4 == 0) { /* not XPG4 */ 2705*7c478bd9Sstevel@tonic-gate shpath = "/usr/bin/sh"; 2706*7c478bd9Sstevel@tonic-gate } else { 2707*7c478bd9Sstevel@tonic-gate /* XPG4 */ 2708*7c478bd9Sstevel@tonic-gate shpath = "/usr/xpg4/bin/sh"; 2709*7c478bd9Sstevel@tonic-gate } 2710*7c478bd9Sstevel@tonic-gate execlp((const char *)shpath, "sh", "-c", string, (char *)0); 2711*7c478bd9Sstevel@tonic-gate exit(1); 2712*7c478bd9Sstevel@tonic-gate } 2713*7c478bd9Sstevel@tonic-gate if (i == (pid_t)-1) 2714*7c478bd9Sstevel@tonic-gate goto xerr; 2715*7c478bd9Sstevel@tonic-gate close(w_or_r(pf[0], pf[1])); 2716*7c478bd9Sstevel@tonic-gate return (w_or_r(pf[1], pf[0])); 2717*7c478bd9Sstevel@tonic-gate } 2718*7c478bd9Sstevel@tonic-gate 2719*7c478bd9Sstevel@tonic-gate 2720*7c478bd9Sstevel@tonic-gate static void 2721*7c478bd9Sstevel@tonic-gate eclose(int f) 2722*7c478bd9Sstevel@tonic-gate { 2723*7c478bd9Sstevel@tonic-gate close(f); 2724*7c478bd9Sstevel@tonic-gate if (Xqt) 2725*7c478bd9Sstevel@tonic-gate Xqt = 0, wait((int *)0); 2726*7c478bd9Sstevel@tonic-gate } 2727*7c478bd9Sstevel@tonic-gate 2728*7c478bd9Sstevel@tonic-gate 2729*7c478bd9Sstevel@tonic-gate static void 2730*7c478bd9Sstevel@tonic-gate mkfunny(void) 2731*7c478bd9Sstevel@tonic-gate { 2732*7c478bd9Sstevel@tonic-gate char *p, *p1, *p2; 2733*7c478bd9Sstevel@tonic-gate 2734*7c478bd9Sstevel@tonic-gate p2 = p1 = funny; 2735*7c478bd9Sstevel@tonic-gate p = file; 2736*7c478bd9Sstevel@tonic-gate /* 2737*7c478bd9Sstevel@tonic-gate * Go to end of file name 2738*7c478bd9Sstevel@tonic-gate */ 2739*7c478bd9Sstevel@tonic-gate while (*p) 2740*7c478bd9Sstevel@tonic-gate p++; 2741*7c478bd9Sstevel@tonic-gate while (*--p == '/') /* delete trailing slashes */ 2742*7c478bd9Sstevel@tonic-gate *p = '\0'; 2743*7c478bd9Sstevel@tonic-gate /* 2744*7c478bd9Sstevel@tonic-gate * go back to beginning of file 2745*7c478bd9Sstevel@tonic-gate */ 2746*7c478bd9Sstevel@tonic-gate p = file; 2747*7c478bd9Sstevel@tonic-gate /* 2748*7c478bd9Sstevel@tonic-gate * Copy file name to funny setting p2 at 2749*7c478bd9Sstevel@tonic-gate * basename of file. 2750*7c478bd9Sstevel@tonic-gate */ 2751*7c478bd9Sstevel@tonic-gate while (*p1++ = *p) 2752*7c478bd9Sstevel@tonic-gate if (*p++ == '/') p2 = p1; 2753*7c478bd9Sstevel@tonic-gate /* 2754*7c478bd9Sstevel@tonic-gate * Set p1 to point to basename of tfname. 2755*7c478bd9Sstevel@tonic-gate */ 2756*7c478bd9Sstevel@tonic-gate p1 = strrchr(tfname, '/'); 2757*7c478bd9Sstevel@tonic-gate if (strlen(tfname) > (size_t)6) 2758*7c478bd9Sstevel@tonic-gate p1 = &tfname[strlen(tfname)-6]; 2759*7c478bd9Sstevel@tonic-gate p1++; 2760*7c478bd9Sstevel@tonic-gate *p2 = '\007'; /* add unprintable char for funny a unique name */ 2761*7c478bd9Sstevel@tonic-gate /* 2762*7c478bd9Sstevel@tonic-gate * Copy tfname to file. 2763*7c478bd9Sstevel@tonic-gate */ 2764*7c478bd9Sstevel@tonic-gate while (*++p2 = *p1++); 2765*7c478bd9Sstevel@tonic-gate } 2766*7c478bd9Sstevel@tonic-gate 2767*7c478bd9Sstevel@tonic-gate 2768*7c478bd9Sstevel@tonic-gate static void 2769*7c478bd9Sstevel@tonic-gate getime(void) /* get modified time of file and save */ 2770*7c478bd9Sstevel@tonic-gate { 2771*7c478bd9Sstevel@tonic-gate if (stat(file, &Fl) < 0) 2772*7c478bd9Sstevel@tonic-gate savtime = 0; 2773*7c478bd9Sstevel@tonic-gate else 2774*7c478bd9Sstevel@tonic-gate savtime = Fl.st_mtime; 2775*7c478bd9Sstevel@tonic-gate } 2776*7c478bd9Sstevel@tonic-gate 2777*7c478bd9Sstevel@tonic-gate 2778*7c478bd9Sstevel@tonic-gate static void 2779*7c478bd9Sstevel@tonic-gate chktime(void) /* check saved mod time against current mod time */ 2780*7c478bd9Sstevel@tonic-gate { 2781*7c478bd9Sstevel@tonic-gate if (savtime != 0 && Fl.st_mtime != 0) { 2782*7c478bd9Sstevel@tonic-gate if (savtime != Fl.st_mtime) 2783*7c478bd9Sstevel@tonic-gate (void) error(58); 2784*7c478bd9Sstevel@tonic-gate } 2785*7c478bd9Sstevel@tonic-gate } 2786*7c478bd9Sstevel@tonic-gate 2787*7c478bd9Sstevel@tonic-gate 2788*7c478bd9Sstevel@tonic-gate static void 2789*7c478bd9Sstevel@tonic-gate newtime(void) /* get new mod time and save */ 2790*7c478bd9Sstevel@tonic-gate { 2791*7c478bd9Sstevel@tonic-gate stat(file, &Fl); 2792*7c478bd9Sstevel@tonic-gate savtime = Fl.st_mtime; 2793*7c478bd9Sstevel@tonic-gate } 2794*7c478bd9Sstevel@tonic-gate 2795*7c478bd9Sstevel@tonic-gate 2796*7c478bd9Sstevel@tonic-gate static void 2797*7c478bd9Sstevel@tonic-gate red(char *op) /* restricted - check for '/' in name */ 2798*7c478bd9Sstevel@tonic-gate /* and delete trailing '/' */ 2799*7c478bd9Sstevel@tonic-gate { 2800*7c478bd9Sstevel@tonic-gate char *p; 2801*7c478bd9Sstevel@tonic-gate 2802*7c478bd9Sstevel@tonic-gate p = op; 2803*7c478bd9Sstevel@tonic-gate while (*p) 2804*7c478bd9Sstevel@tonic-gate if (*p++ == '/'&& rflg) { 2805*7c478bd9Sstevel@tonic-gate *op = 0; 2806*7c478bd9Sstevel@tonic-gate (void) error(6); 2807*7c478bd9Sstevel@tonic-gate } 2808*7c478bd9Sstevel@tonic-gate /* delete trailing '/' */ 2809*7c478bd9Sstevel@tonic-gate while (p > op) { 2810*7c478bd9Sstevel@tonic-gate if (*--p == '/') 2811*7c478bd9Sstevel@tonic-gate *p = '\0'; 2812*7c478bd9Sstevel@tonic-gate else break; 2813*7c478bd9Sstevel@tonic-gate } 2814*7c478bd9Sstevel@tonic-gate } 2815*7c478bd9Sstevel@tonic-gate 2816*7c478bd9Sstevel@tonic-gate 2817*7c478bd9Sstevel@tonic-gate /* 2818*7c478bd9Sstevel@tonic-gate * Searches thru beginning of file looking for a string of the form 2819*7c478bd9Sstevel@tonic-gate * <: values... :> 2820*7c478bd9Sstevel@tonic-gate * 2821*7c478bd9Sstevel@tonic-gate * where "values" are 2822*7c478bd9Sstevel@tonic-gate * 2823*7c478bd9Sstevel@tonic-gate * \b ignored 2824*7c478bd9Sstevel@tonic-gate * s<num> sets the Flim to <num> 2825*7c478bd9Sstevel@tonic-gate * t??? sets tab stop stuff 2826*7c478bd9Sstevel@tonic-gate * d ignored 2827*7c478bd9Sstevel@tonic-gate * m<num> ignored 2828*7c478bd9Sstevel@tonic-gate * e ignored 2829*7c478bd9Sstevel@tonic-gate */ 2830*7c478bd9Sstevel@tonic-gate 2831*7c478bd9Sstevel@tonic-gate static int 2832*7c478bd9Sstevel@tonic-gate fspec(char line[], struct Fspec *f, int up) 2833*7c478bd9Sstevel@tonic-gate { 2834*7c478bd9Sstevel@tonic-gate struct termio arg; 2835*7c478bd9Sstevel@tonic-gate int havespec, n; 2836*7c478bd9Sstevel@tonic-gate int len; 2837*7c478bd9Sstevel@tonic-gate 2838*7c478bd9Sstevel@tonic-gate if (!up) clear(f); 2839*7c478bd9Sstevel@tonic-gate 2840*7c478bd9Sstevel@tonic-gate havespec = fsprtn = 0; 2841*7c478bd9Sstevel@tonic-gate for (fsp = line; *fsp && *fsp != '\n'; fsp += len) { 2842*7c478bd9Sstevel@tonic-gate if ((len = mblen(fsp, MB_CUR_MAX)) <= 0) 2843*7c478bd9Sstevel@tonic-gate len = 1; 2844*7c478bd9Sstevel@tonic-gate switch (*fsp) { 2845*7c478bd9Sstevel@tonic-gate 2846*7c478bd9Sstevel@tonic-gate case '<': if (havespec) 2847*7c478bd9Sstevel@tonic-gate return (-1); 2848*7c478bd9Sstevel@tonic-gate if (*(fsp+1) == ':') { 2849*7c478bd9Sstevel@tonic-gate havespec = 1; 2850*7c478bd9Sstevel@tonic-gate clear(f); 2851*7c478bd9Sstevel@tonic-gate if (!ioctl(1, TCGETA, &arg) && 2852*7c478bd9Sstevel@tonic-gate ((arg.c_oflag&TAB3) == TAB3)) 2853*7c478bd9Sstevel@tonic-gate f->Ffill = 1; 2854*7c478bd9Sstevel@tonic-gate fsp++; 2855*7c478bd9Sstevel@tonic-gate continue; 2856*7c478bd9Sstevel@tonic-gate } 2857*7c478bd9Sstevel@tonic-gate 2858*7c478bd9Sstevel@tonic-gate case ' ': continue; 2859*7c478bd9Sstevel@tonic-gate 2860*7c478bd9Sstevel@tonic-gate case 's': if (havespec && (n = numb()) >= 0) 2861*7c478bd9Sstevel@tonic-gate f->Flim = n; 2862*7c478bd9Sstevel@tonic-gate continue; 2863*7c478bd9Sstevel@tonic-gate 2864*7c478bd9Sstevel@tonic-gate case 't': if (havespec) targ(f); 2865*7c478bd9Sstevel@tonic-gate continue; 2866*7c478bd9Sstevel@tonic-gate 2867*7c478bd9Sstevel@tonic-gate case 'd': continue; 2868*7c478bd9Sstevel@tonic-gate 2869*7c478bd9Sstevel@tonic-gate case 'm': if (havespec) n = numb(); 2870*7c478bd9Sstevel@tonic-gate continue; 2871*7c478bd9Sstevel@tonic-gate 2872*7c478bd9Sstevel@tonic-gate case 'e': continue; 2873*7c478bd9Sstevel@tonic-gate case ':': if (!havespec) continue; 2874*7c478bd9Sstevel@tonic-gate if (*(fsp+1) != '>') fsprtn = -1; 2875*7c478bd9Sstevel@tonic-gate return (fsprtn); 2876*7c478bd9Sstevel@tonic-gate 2877*7c478bd9Sstevel@tonic-gate default: if (!havespec) continue; 2878*7c478bd9Sstevel@tonic-gate return (-1); 2879*7c478bd9Sstevel@tonic-gate } 2880*7c478bd9Sstevel@tonic-gate } 2881*7c478bd9Sstevel@tonic-gate return (1); 2882*7c478bd9Sstevel@tonic-gate } 2883*7c478bd9Sstevel@tonic-gate 2884*7c478bd9Sstevel@tonic-gate 2885*7c478bd9Sstevel@tonic-gate static int 2886*7c478bd9Sstevel@tonic-gate numb(void) 2887*7c478bd9Sstevel@tonic-gate { 2888*7c478bd9Sstevel@tonic-gate int n; 2889*7c478bd9Sstevel@tonic-gate 2890*7c478bd9Sstevel@tonic-gate n = 0; 2891*7c478bd9Sstevel@tonic-gate while (*++fsp >= '0' && *fsp <= '9') 2892*7c478bd9Sstevel@tonic-gate n = 10*n + *fsp-'0'; 2893*7c478bd9Sstevel@tonic-gate fsp--; 2894*7c478bd9Sstevel@tonic-gate return (n); 2895*7c478bd9Sstevel@tonic-gate } 2896*7c478bd9Sstevel@tonic-gate 2897*7c478bd9Sstevel@tonic-gate 2898*7c478bd9Sstevel@tonic-gate static void 2899*7c478bd9Sstevel@tonic-gate targ(struct Fspec *f) 2900*7c478bd9Sstevel@tonic-gate { 2901*7c478bd9Sstevel@tonic-gate 2902*7c478bd9Sstevel@tonic-gate if (*++fsp == '-') { 2903*7c478bd9Sstevel@tonic-gate if (*(fsp + 1) >= '0' && *(fsp+1) <= '9') tincr(numb(), f); 2904*7c478bd9Sstevel@tonic-gate else tstd(f); 2905*7c478bd9Sstevel@tonic-gate return; 2906*7c478bd9Sstevel@tonic-gate } 2907*7c478bd9Sstevel@tonic-gate if (*fsp >= '0' && *fsp <= '9') { 2908*7c478bd9Sstevel@tonic-gate tlist(f); 2909*7c478bd9Sstevel@tonic-gate return; 2910*7c478bd9Sstevel@tonic-gate } 2911*7c478bd9Sstevel@tonic-gate fsprtn = -1; 2912*7c478bd9Sstevel@tonic-gate fsp--; 2913*7c478bd9Sstevel@tonic-gate } 2914*7c478bd9Sstevel@tonic-gate 2915*7c478bd9Sstevel@tonic-gate 2916*7c478bd9Sstevel@tonic-gate static void 2917*7c478bd9Sstevel@tonic-gate tincr(int n, struct Fspec *f) 2918*7c478bd9Sstevel@tonic-gate { 2919*7c478bd9Sstevel@tonic-gate int l, i; 2920*7c478bd9Sstevel@tonic-gate 2921*7c478bd9Sstevel@tonic-gate l = 1; 2922*7c478bd9Sstevel@tonic-gate for (i = 0; i < 20; i++) 2923*7c478bd9Sstevel@tonic-gate f->Ftabs[i] = l += n; 2924*7c478bd9Sstevel@tonic-gate f->Ftabs[i] = 0; 2925*7c478bd9Sstevel@tonic-gate } 2926*7c478bd9Sstevel@tonic-gate 2927*7c478bd9Sstevel@tonic-gate 2928*7c478bd9Sstevel@tonic-gate static void 2929*7c478bd9Sstevel@tonic-gate tstd(struct Fspec *f) 2930*7c478bd9Sstevel@tonic-gate { 2931*7c478bd9Sstevel@tonic-gate char std[3]; 2932*7c478bd9Sstevel@tonic-gate 2933*7c478bd9Sstevel@tonic-gate std[0] = *++fsp; 2934*7c478bd9Sstevel@tonic-gate if (*(fsp+1) >= '0' && *(fsp+1) <= '9') { 2935*7c478bd9Sstevel@tonic-gate std[1] = *++fsp; 2936*7c478bd9Sstevel@tonic-gate std[2] = '\0'; 2937*7c478bd9Sstevel@tonic-gate } else std[1] = '\0'; 2938*7c478bd9Sstevel@tonic-gate fsprtn = stdtab(std, f->Ftabs); 2939*7c478bd9Sstevel@tonic-gate } 2940*7c478bd9Sstevel@tonic-gate 2941*7c478bd9Sstevel@tonic-gate 2942*7c478bd9Sstevel@tonic-gate static void 2943*7c478bd9Sstevel@tonic-gate tlist(struct Fspec *f) 2944*7c478bd9Sstevel@tonic-gate { 2945*7c478bd9Sstevel@tonic-gate int n, last, i; 2946*7c478bd9Sstevel@tonic-gate 2947*7c478bd9Sstevel@tonic-gate fsp--; 2948*7c478bd9Sstevel@tonic-gate last = i = 0; 2949*7c478bd9Sstevel@tonic-gate 2950*7c478bd9Sstevel@tonic-gate do { 2951*7c478bd9Sstevel@tonic-gate if ((n = numb()) <= last || i >= 20) { 2952*7c478bd9Sstevel@tonic-gate fsprtn = -1; 2953*7c478bd9Sstevel@tonic-gate return; 2954*7c478bd9Sstevel@tonic-gate } 2955*7c478bd9Sstevel@tonic-gate f->Ftabs[i++] = last = n; 2956*7c478bd9Sstevel@tonic-gate } while (*++fsp == ','); 2957*7c478bd9Sstevel@tonic-gate 2958*7c478bd9Sstevel@tonic-gate f->Ftabs[i] = 0; 2959*7c478bd9Sstevel@tonic-gate fsp--; 2960*7c478bd9Sstevel@tonic-gate } 2961*7c478bd9Sstevel@tonic-gate 2962*7c478bd9Sstevel@tonic-gate 2963*7c478bd9Sstevel@tonic-gate static int 2964*7c478bd9Sstevel@tonic-gate expnd(char line[], char buf[], int *sz, struct Fspec *f) 2965*7c478bd9Sstevel@tonic-gate { 2966*7c478bd9Sstevel@tonic-gate char *l, *t; 2967*7c478bd9Sstevel@tonic-gate int b; 2968*7c478bd9Sstevel@tonic-gate 2969*7c478bd9Sstevel@tonic-gate l = line - 1; 2970*7c478bd9Sstevel@tonic-gate b = 1; 2971*7c478bd9Sstevel@tonic-gate t = f->Ftabs; 2972*7c478bd9Sstevel@tonic-gate fsprtn = 0; 2973*7c478bd9Sstevel@tonic-gate 2974*7c478bd9Sstevel@tonic-gate while (*++l && *l != '\n' && b < 511) { 2975*7c478bd9Sstevel@tonic-gate if (*l == '\t') { 2976*7c478bd9Sstevel@tonic-gate while (*t && b >= *t) t++; 2977*7c478bd9Sstevel@tonic-gate if (*t == 0) fsprtn = -2; 2978*7c478bd9Sstevel@tonic-gate do buf[b-1] = ' '; while (++b < *t); 2979*7c478bd9Sstevel@tonic-gate } else buf[b++ - 1] = *l; 2980*7c478bd9Sstevel@tonic-gate } 2981*7c478bd9Sstevel@tonic-gate 2982*7c478bd9Sstevel@tonic-gate buf[b] = '\0'; 2983*7c478bd9Sstevel@tonic-gate *sz = b; 2984*7c478bd9Sstevel@tonic-gate if (*l != '\0' && *l != '\n') { 2985*7c478bd9Sstevel@tonic-gate buf[b-1] = '\n'; 2986*7c478bd9Sstevel@tonic-gate return (-1); 2987*7c478bd9Sstevel@tonic-gate } 2988*7c478bd9Sstevel@tonic-gate buf[b-1] = *l; 2989*7c478bd9Sstevel@tonic-gate if (f->Flim && (b-1 > (int)f->Flim)) 2990*7c478bd9Sstevel@tonic-gate return (-1); 2991*7c478bd9Sstevel@tonic-gate return (fsprtn); 2992*7c478bd9Sstevel@tonic-gate } 2993*7c478bd9Sstevel@tonic-gate 2994*7c478bd9Sstevel@tonic-gate 2995*7c478bd9Sstevel@tonic-gate static void 2996*7c478bd9Sstevel@tonic-gate clear(struct Fspec *f) 2997*7c478bd9Sstevel@tonic-gate { 2998*7c478bd9Sstevel@tonic-gate f->Ftabs[0] = f->Fdel = f->Fmov = f->Ffill = 0; 2999*7c478bd9Sstevel@tonic-gate f->Flim = 0; 3000*7c478bd9Sstevel@tonic-gate } 3001*7c478bd9Sstevel@tonic-gate 3002*7c478bd9Sstevel@tonic-gate 3003*7c478bd9Sstevel@tonic-gate static int 3004*7c478bd9Sstevel@tonic-gate lenchk(char line[], struct Fspec *f) 3005*7c478bd9Sstevel@tonic-gate { 3006*7c478bd9Sstevel@tonic-gate char *l, *t; 3007*7c478bd9Sstevel@tonic-gate int b; 3008*7c478bd9Sstevel@tonic-gate 3009*7c478bd9Sstevel@tonic-gate l = line - 1; 3010*7c478bd9Sstevel@tonic-gate b = 1; 3011*7c478bd9Sstevel@tonic-gate t = f->Ftabs; 3012*7c478bd9Sstevel@tonic-gate 3013*7c478bd9Sstevel@tonic-gate while (*++l && *l != '\n' && b < 511) { 3014*7c478bd9Sstevel@tonic-gate if (*l == '\t') { 3015*7c478bd9Sstevel@tonic-gate while (*t && b >= *t) t++; 3016*7c478bd9Sstevel@tonic-gate while (++b < *t); 3017*7c478bd9Sstevel@tonic-gate } else b++; 3018*7c478bd9Sstevel@tonic-gate } 3019*7c478bd9Sstevel@tonic-gate 3020*7c478bd9Sstevel@tonic-gate if ((*l != '\0' && *l != '\n') || (f->Flim && (b-1 > (int)f->Flim))) 3021*7c478bd9Sstevel@tonic-gate return (-1); 3022*7c478bd9Sstevel@tonic-gate return (0); 3023*7c478bd9Sstevel@tonic-gate } 3024*7c478bd9Sstevel@tonic-gate #define NTABS 21 3025*7c478bd9Sstevel@tonic-gate 3026*7c478bd9Sstevel@tonic-gate 3027*7c478bd9Sstevel@tonic-gate /* 3028*7c478bd9Sstevel@tonic-gate * stdtabs: standard tabs table 3029*7c478bd9Sstevel@tonic-gate * format: option code letter(s), null, tabs, null 3030*7c478bd9Sstevel@tonic-gate */ 3031*7c478bd9Sstevel@tonic-gate 3032*7c478bd9Sstevel@tonic-gate static char stdtabs[] = { 3033*7c478bd9Sstevel@tonic-gate 'a', 0, 1, 10, 16, 36, 72, 0, /* IBM 370 Assembler */ 3034*7c478bd9Sstevel@tonic-gate 'a', '2', 0, 1, 10, 16, 40, 72, 0, /* IBM Assembler alternative */ 3035*7c478bd9Sstevel@tonic-gate 'c', 0, 1, 8, 12, 16, 20, 55, 0, /* COBOL, normal */ 3036*7c478bd9Sstevel@tonic-gate 'c', '2', 0, 1, 6, 10, 14, 49, 0, /* COBOL, crunched */ 3037*7c478bd9Sstevel@tonic-gate 'c', '3', 0, 1, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46, 50, 3038*7c478bd9Sstevel@tonic-gate 54, 58, 62, 67, 0, 3039*7c478bd9Sstevel@tonic-gate 'f', 0, 1, 7, 11, 15, 19, 23, 0, /* FORTRAN */ 3040*7c478bd9Sstevel@tonic-gate 'p', 0, 1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61, 0, 3041*7c478bd9Sstevel@tonic-gate /* PL/I */ 3042*7c478bd9Sstevel@tonic-gate 's', 0, 1, 10, 55, 0, /* SNOBOL */ 3043*7c478bd9Sstevel@tonic-gate 'u', 0, 1, 12, 20, 44, 0, /* UNIVAC ASM */ 3044*7c478bd9Sstevel@tonic-gate 0 }; 3045*7c478bd9Sstevel@tonic-gate 3046*7c478bd9Sstevel@tonic-gate 3047*7c478bd9Sstevel@tonic-gate /* 3048*7c478bd9Sstevel@tonic-gate * stdtab: return tab list for any "canned" tab option. 3049*7c478bd9Sstevel@tonic-gate * entry: option points to null-terminated option string 3050*7c478bd9Sstevel@tonic-gate * tabvect points to vector to be filled in 3051*7c478bd9Sstevel@tonic-gate * exit: return (0) if legal, tabvect filled, ending with zero 3052*7c478bd9Sstevel@tonic-gate * return (-1) if unknown option 3053*7c478bd9Sstevel@tonic-gate */ 3054*7c478bd9Sstevel@tonic-gate 3055*7c478bd9Sstevel@tonic-gate 3056*7c478bd9Sstevel@tonic-gate static int 3057*7c478bd9Sstevel@tonic-gate stdtab(char option[], char tabvect[NTABS]) 3058*7c478bd9Sstevel@tonic-gate { 3059*7c478bd9Sstevel@tonic-gate char *scan; 3060*7c478bd9Sstevel@tonic-gate tabvect[0] = 0; 3061*7c478bd9Sstevel@tonic-gate scan = stdtabs; 3062*7c478bd9Sstevel@tonic-gate while (*scan) { 3063*7c478bd9Sstevel@tonic-gate if (strequal(&scan, option)) { 3064*7c478bd9Sstevel@tonic-gate strcopy(scan, tabvect); 3065*7c478bd9Sstevel@tonic-gate break; 3066*7c478bd9Sstevel@tonic-gate } else 3067*7c478bd9Sstevel@tonic-gate while (*scan++); /* skip over tab specs */ 3068*7c478bd9Sstevel@tonic-gate } 3069*7c478bd9Sstevel@tonic-gate 3070*7c478bd9Sstevel@tonic-gate /* later: look up code in /etc/something */ 3071*7c478bd9Sstevel@tonic-gate return (tabvect[0] ? 0 : -1); 3072*7c478bd9Sstevel@tonic-gate } 3073*7c478bd9Sstevel@tonic-gate 3074*7c478bd9Sstevel@tonic-gate 3075*7c478bd9Sstevel@tonic-gate /* 3076*7c478bd9Sstevel@tonic-gate * strequal: checks strings for equality 3077*7c478bd9Sstevel@tonic-gate * entry: scan1 points to scan pointer, str points to string 3078*7c478bd9Sstevel@tonic-gate * exit: return (1) if equal, return (0) if not 3079*7c478bd9Sstevel@tonic-gate * *scan1 is advanced to next nonzero byte after null 3080*7c478bd9Sstevel@tonic-gate */ 3081*7c478bd9Sstevel@tonic-gate 3082*7c478bd9Sstevel@tonic-gate 3083*7c478bd9Sstevel@tonic-gate static int 3084*7c478bd9Sstevel@tonic-gate strequal(char **scan1, char *str) 3085*7c478bd9Sstevel@tonic-gate { 3086*7c478bd9Sstevel@tonic-gate char c, *scan; 3087*7c478bd9Sstevel@tonic-gate scan = *scan1; 3088*7c478bd9Sstevel@tonic-gate while ((c = *scan++) == *str && c) str++; 3089*7c478bd9Sstevel@tonic-gate *scan1 = scan; 3090*7c478bd9Sstevel@tonic-gate if (c == 0 && *str == 0) 3091*7c478bd9Sstevel@tonic-gate return (1); 3092*7c478bd9Sstevel@tonic-gate if (c) 3093*7c478bd9Sstevel@tonic-gate while (*scan++); 3094*7c478bd9Sstevel@tonic-gate *scan1 = scan; 3095*7c478bd9Sstevel@tonic-gate return (0); 3096*7c478bd9Sstevel@tonic-gate } 3097*7c478bd9Sstevel@tonic-gate 3098*7c478bd9Sstevel@tonic-gate 3099*7c478bd9Sstevel@tonic-gate /* strcopy: copy source to destination */ 3100*7c478bd9Sstevel@tonic-gate 3101*7c478bd9Sstevel@tonic-gate 3102*7c478bd9Sstevel@tonic-gate static void 3103*7c478bd9Sstevel@tonic-gate strcopy(char *source, char *dest) 3104*7c478bd9Sstevel@tonic-gate { 3105*7c478bd9Sstevel@tonic-gate while (*dest++ = *source++); 3106*7c478bd9Sstevel@tonic-gate } 3107*7c478bd9Sstevel@tonic-gate 3108*7c478bd9Sstevel@tonic-gate 3109*7c478bd9Sstevel@tonic-gate /* This is called before a buffer modifying command so that the */ 3110*7c478bd9Sstevel@tonic-gate /* current array of line ptrs is saved in sav and dot and dol are saved */ 3111*7c478bd9Sstevel@tonic-gate 3112*7c478bd9Sstevel@tonic-gate 3113*7c478bd9Sstevel@tonic-gate static void 3114*7c478bd9Sstevel@tonic-gate save(void) { 3115*7c478bd9Sstevel@tonic-gate LINE i; 3116*7c478bd9Sstevel@tonic-gate int j; 3117*7c478bd9Sstevel@tonic-gate 3118*7c478bd9Sstevel@tonic-gate savdot = dot; 3119*7c478bd9Sstevel@tonic-gate savdol = dol; 3120*7c478bd9Sstevel@tonic-gate for (j = 0; j <= 25; j++) 3121*7c478bd9Sstevel@tonic-gate savnames[j] = names[j]; 3122*7c478bd9Sstevel@tonic-gate 3123*7c478bd9Sstevel@tonic-gate for (i = zero + 1; i <= dol; i++) 3124*7c478bd9Sstevel@tonic-gate i->sav = i->cur; 3125*7c478bd9Sstevel@tonic-gate initflg = 0; 3126*7c478bd9Sstevel@tonic-gate } 3127*7c478bd9Sstevel@tonic-gate 3128*7c478bd9Sstevel@tonic-gate 3129*7c478bd9Sstevel@tonic-gate /* The undo command calls this to restore the previous ptr array sav */ 3130*7c478bd9Sstevel@tonic-gate /* and swap with cur - dot and dol are swapped also. This allows user to */ 3131*7c478bd9Sstevel@tonic-gate /* undo an undo */ 3132*7c478bd9Sstevel@tonic-gate 3133*7c478bd9Sstevel@tonic-gate 3134*7c478bd9Sstevel@tonic-gate static void 3135*7c478bd9Sstevel@tonic-gate undo(void) { 3136*7c478bd9Sstevel@tonic-gate int j; 3137*7c478bd9Sstevel@tonic-gate long tmp; 3138*7c478bd9Sstevel@tonic-gate LINE i, tmpdot, tmpdol; 3139*7c478bd9Sstevel@tonic-gate 3140*7c478bd9Sstevel@tonic-gate tmpdot = dot; dot = savdot; savdot = tmpdot; 3141*7c478bd9Sstevel@tonic-gate tmpdol = dol; dol = savdol; savdol = tmpdol; 3142*7c478bd9Sstevel@tonic-gate /* swap arrays using the greater of dol or savdol as upper limit */ 3143*7c478bd9Sstevel@tonic-gate for (i = zero + 1; i <= ((dol > savdol) ? dol : savdol); i++) { 3144*7c478bd9Sstevel@tonic-gate tmp = i->cur; 3145*7c478bd9Sstevel@tonic-gate i->cur = i->sav; 3146*7c478bd9Sstevel@tonic-gate i->sav = tmp; 3147*7c478bd9Sstevel@tonic-gate } 3148*7c478bd9Sstevel@tonic-gate /* 3149*7c478bd9Sstevel@tonic-gate * If the current text lines are swapped with the 3150*7c478bd9Sstevel@tonic-gate * text lines in the save buffer, then swap the current 3151*7c478bd9Sstevel@tonic-gate * marks with those in the save area. 3152*7c478bd9Sstevel@tonic-gate */ 3153*7c478bd9Sstevel@tonic-gate 3154*7c478bd9Sstevel@tonic-gate for (j = 0; j <= 25; j++) { 3155*7c478bd9Sstevel@tonic-gate tmp = names[j]; 3156*7c478bd9Sstevel@tonic-gate names[j] = savnames[j]; 3157*7c478bd9Sstevel@tonic-gate savnames[j] = tmp; 3158*7c478bd9Sstevel@tonic-gate } 3159*7c478bd9Sstevel@tonic-gate } 3160*7c478bd9Sstevel@tonic-gate 3161*7c478bd9Sstevel@tonic-gate static wchar_t 3162*7c478bd9Sstevel@tonic-gate get_wchr() 3163*7c478bd9Sstevel@tonic-gate { 3164*7c478bd9Sstevel@tonic-gate wchar_t wc; 3165*7c478bd9Sstevel@tonic-gate char multi[MB_LEN_MAX]; 3166*7c478bd9Sstevel@tonic-gate 3167*7c478bd9Sstevel@tonic-gate if (_mbftowc(multi, &wc, getchr, &peekc) <= 0) 3168*7c478bd9Sstevel@tonic-gate wc = getchr(); 3169*7c478bd9Sstevel@tonic-gate return (wc); 3170*7c478bd9Sstevel@tonic-gate } 3171