1#include <stdlib.h> 2#include <string.h> 3#include <unistd.h> 4#include <fcntl.h> 5 6/* Need a way to have void used for ANSI, nothing for K&R. */ 7#ifndef _ANSI 8#undef _VOID 9#define _VOID 10#endif 11 12/* -------- sh.h -------- */ 13/* 14 * shell 15 */ 16 17#define LINELIM 2100 18#define NPUSH 8 /* limit to input nesting */ 19 20#define NOFILE 20 /* Number of open files */ 21#define NUFILE 10 /* Number of user-accessible files */ 22#define FDBASE 10 /* First file usable by Shell */ 23 24/* 25 * values returned by wait 26 */ 27#define WAITSIG(s) ((s)&0177) 28#define WAITVAL(s) (((s)>>8)&0377) 29#define WAITCORE(s) (((s)&0200)!=0) 30 31/* 32 * library and system defintions 33 */ 34#ifdef __STDC__ 35typedef void xint; /* base type of jmp_buf, for not broken compilers */ 36#else 37typedef char * xint; /* base type of jmp_buf, for broken compilers */ 38#endif 39 40/* 41 * shell components 42 */ 43/* #include "area.h" */ 44/* #include "word.h" */ 45/* #include "io.h" */ 46/* #include "var.h" */ 47 48#define QUOTE 0200 49 50#define NOBLOCK ((struct op *)NULL) 51#define NOWORD ((char *)NULL) 52#define NOWORDS ((char **)NULL) 53#define NOPIPE ((int *)NULL) 54 55/* 56 * Description of a command or an operation on commands. 57 * Might eventually use a union. 58 */ 59struct op { 60 int type; /* operation type, see below */ 61 char **words; /* arguments to a command */ 62 struct ioword **ioact; /* IO actions (eg, < > >>) */ 63 struct op *left; 64 struct op *right; 65 char *str; /* identifier for case and for */ 66}; 67 68#define TCOM 1 /* command */ 69#define TPAREN 2 /* (c-list) */ 70#define TPIPE 3 /* a | b */ 71#define TLIST 4 /* a [&;] b */ 72#define TOR 5 /* || */ 73#define TAND 6 /* && */ 74#define TFOR 7 75#define TDO 8 76#define TCASE 9 77#define TIF 10 78#define TWHILE 11 79#define TUNTIL 12 80#define TELIF 13 81#define TPAT 14 /* pattern in case */ 82#define TBRACE 15 /* {c-list} */ 83#define TASYNC 16 /* c & */ 84 85/* 86 * actions determining the environment of a process 87 */ 88#define BIT(i) (1<<(i)) 89#define FEXEC BIT(0) /* execute without forking */ 90 91/* 92 * flags to control evaluation of words 93 */ 94#define DOSUB 1 /* interpret $, `, and quotes */ 95#define DOBLANK 2 /* perform blank interpretation */ 96#define DOGLOB 4 /* interpret [?* */ 97#define DOKEY 8 /* move words with `=' to 2nd arg. list */ 98#define DOTRIM 16 /* trim resulting string */ 99 100#define DOALL (DOSUB|DOBLANK|DOGLOB|DOKEY|DOTRIM) 101 102Extern char **dolv; 103Extern int dolc; 104Extern int exstat; 105Extern char gflg; 106Extern int talking; /* interactive (talking-type wireless) */ 107Extern int execflg; 108Extern int multiline; /* \n changed to ; */ 109Extern struct op *outtree; /* result from parser */ 110 111Extern xint *failpt; 112Extern xint *errpt; 113 114struct brkcon { 115 jmp_buf brkpt; 116 struct brkcon *nextlev; 117} ; 118Extern struct brkcon *brklist; 119Extern int isbreak; 120 121/* 122 * redirection 123 */ 124struct ioword { 125 short io_unit; /* unit affected */ 126 short io_flag; /* action (below) */ 127 char *io_name; /* file name */ 128}; 129#define IOREAD 1 /* < */ 130#define IOHERE 2 /* << (here file) */ 131#define IOWRITE 4 /* > */ 132#define IOCAT 8 /* >> */ 133#define IOXHERE 16 /* ${}, ` in << */ 134#define IODUP 32 /* >&digit */ 135#define IOCLOSE 64 /* >&- */ 136 137#define IODEFAULT (-1) /* token for default IO unit */ 138 139Extern struct wdblock *wdlist; 140Extern struct wdblock *iolist; 141 142/* 143 * parsing & execution environment 144 */ 145extern struct env { 146 char *linep; 147 struct io *iobase; 148 struct io *iop; 149 xint *errpt; 150 int iofd; 151 struct env *oenv; 152} e; 153 154/* 155 * flags: 156 * -e: quit on error 157 * -k: look for name=value everywhere on command line 158 * -n: no execution 159 * -t: exit after reading and executing one command 160 * -v: echo as read 161 * -x: trace 162 * -u: unset variables net diagnostic 163 */ 164extern char *flag; 165 166extern char *null; /* null value for variable */ 167extern int intr; /* interrupt pending */ 168 169Extern char *trap[_NSIG+1]; 170Extern char ourtrap[_NSIG+1]; 171Extern int trapset; /* trap pending */ 172 173extern int heedint; /* heed interrupt signals */ 174 175Extern int yynerrs; /* yacc */ 176 177Extern char line[LINELIM]; 178extern char *elinep; 179 180/* 181 * other functions 182 */ 183#ifdef __STDC__ 184int (*inbuilt(char *s ))(void); 185#else 186int (*inbuilt())(); 187#endif 188 189#ifdef __FreeBSD__ 190#define _PROTOTYPE(x,y) x ## y 191#endif 192 193_PROTOTYPE(char *rexecve , (char *c , char **v , char **envp )); 194_PROTOTYPE(char *space , (int n )); 195_PROTOTYPE(char *strsave , (char *s , int a )); 196_PROTOTYPE(char *evalstr , (char *cp , int f )); 197_PROTOTYPE(char *putn , (int n )); 198_PROTOTYPE(char *itoa , (unsigned u , int n )); 199_PROTOTYPE(char *unquote , (char *as )); 200_PROTOTYPE(struct var *lookup , (char *n )); 201_PROTOTYPE(int rlookup , (char *n )); 202_PROTOTYPE(struct wdblock *glob , (char *cp , struct wdblock *wb )); 203_PROTOTYPE(int subgetc , (int ec , int quoted )); 204_PROTOTYPE(char **makenv , (void)); 205_PROTOTYPE(char **eval , (char **ap , int f )); 206_PROTOTYPE(int setstatus , (int s )); 207_PROTOTYPE(int waitfor , (int lastpid , int canintr )); 208 209_PROTOTYPE(void onintr , (int s )); /* SIGINT handler */ 210 211_PROTOTYPE(int newenv , (int f )); 212_PROTOTYPE(void quitenv , (void)); 213_PROTOTYPE(void err , (char *s )); 214_PROTOTYPE(int anys , (char *s1 , char *s2 )); 215_PROTOTYPE(int any , (int c , char *s )); 216_PROTOTYPE(void next , (int f )); 217_PROTOTYPE(void setdash , (void)); 218_PROTOTYPE(void onecommand , (void)); 219_PROTOTYPE(void runtrap , (int i )); 220_PROTOTYPE(void xfree , (char *s )); 221_PROTOTYPE(int letter , (int c )); 222_PROTOTYPE(int digit , (int c )); 223_PROTOTYPE(int letnum , (int c )); 224_PROTOTYPE(int gmatch , (char *s , char *p )); 225 226/* 227 * error handling 228 */ 229_PROTOTYPE(void leave , (void)); /* abort shell (or fail in subshell) */ 230_PROTOTYPE(void fail , (void)); /* fail but return to process next command */ 231_PROTOTYPE(void warn , (char *s )); 232_PROTOTYPE(void sig , (int i )); /* default signal handler */ 233 234/* -------- var.h -------- */ 235 236struct var { 237 char *value; 238 char *name; 239 struct var *next; 240 char status; 241}; 242#define COPYV 1 /* flag to setval, suggesting copy */ 243#define RONLY 01 /* variable is read-only */ 244#define EXPORT 02 /* variable is to be exported */ 245#define GETCELL 04 /* name & value space was got with getcell */ 246 247Extern struct var *vlist; /* dictionary */ 248 249Extern struct var *homedir; /* home directory */ 250Extern struct var *prompt; /* main prompt */ 251Extern struct var *cprompt; /* continuation prompt */ 252Extern struct var *path; /* search path for commands */ 253Extern struct var *shell; /* shell to interpret command files */ 254Extern struct var *ifs; /* field separators */ 255 256_PROTOTYPE(int yyparse , (void)); 257_PROTOTYPE(struct var *lookup , (char *n )); 258_PROTOTYPE(void setval , (struct var *vp , char *val )); 259_PROTOTYPE(void nameval , (struct var *vp , char *val , char *name )); 260_PROTOTYPE(void export , (struct var *vp )); 261_PROTOTYPE(void ronly , (struct var *vp )); 262_PROTOTYPE(int isassign , (char *s )); 263_PROTOTYPE(int checkname , (char *cp )); 264_PROTOTYPE(int assign , (char *s , int cf )); 265_PROTOTYPE(void putvlist , (int f , int out )); 266_PROTOTYPE(int eqname , (char *n1 , char *n2 )); 267 268_PROTOTYPE(int execute , (struct op *t , int *pin , int *pout , int act )); 269 270/* -------- io.h -------- */ 271/* io buffer */ 272struct iobuf { 273 unsigned id; /* buffer id */ 274 char buf[512]; /* buffer */ 275 char *bufp; /* pointer into buffer */ 276 char *ebufp; /* pointer to end of buffer */ 277}; 278 279/* possible arguments to an IO function */ 280struct ioarg { 281 char *aword; 282 char **awordlist; 283 int afile; /* file descriptor */ 284 unsigned afid; /* buffer id */ 285 long afpos; /* file position */ 286 struct iobuf *afbuf; /* buffer for this file */ 287}; 288Extern struct ioarg ioargstack[NPUSH]; 289#define AFID_NOBUF (~0) 290#define AFID_ID 0 291 292/* an input generator's state */ 293struct io { 294 int (*iofn)(_VOID); 295 struct ioarg *argp; 296 int peekc; 297 char prev; /* previous character read by readc() */ 298 char nlcount; /* for `'s */ 299 char xchar; /* for `'s */ 300 char task; /* reason for pushed IO */ 301}; 302Extern struct io iostack[NPUSH]; 303#define XOTHER 0 /* none of the below */ 304#define XDOLL 1 /* expanding ${} */ 305#define XGRAVE 2 /* expanding `'s */ 306#define XIO 3 /* file IO */ 307 308/* in substitution */ 309#define INSUB() (e.iop->task == XGRAVE || e.iop->task == XDOLL) 310 311/* 312 * input generators for IO structure 313 */ 314_PROTOTYPE(int nlchar , (struct ioarg *ap )); 315_PROTOTYPE(int strchar , (struct ioarg *ap )); 316_PROTOTYPE(int qstrchar , (struct ioarg *ap )); 317_PROTOTYPE(int filechar , (struct ioarg *ap )); 318_PROTOTYPE(int herechar , (struct ioarg *ap )); 319_PROTOTYPE(int linechar , (struct ioarg *ap )); 320_PROTOTYPE(int gravechar , (struct ioarg *ap , struct io *iop )); 321_PROTOTYPE(int qgravechar , (struct ioarg *ap , struct io *iop )); 322_PROTOTYPE(int dolchar , (struct ioarg *ap )); 323_PROTOTYPE(int wdchar , (struct ioarg *ap )); 324_PROTOTYPE(void scraphere , (void)); 325_PROTOTYPE(void freehere , (int area )); 326_PROTOTYPE(void gethere , (void)); 327_PROTOTYPE(void markhere , (char *s , struct ioword *iop )); 328_PROTOTYPE(int herein , (char *hname , int xdoll )); 329_PROTOTYPE(int run , (struct ioarg *argp , int (*f)(_VOID))); 330 331/* 332 * IO functions 333 */ 334_PROTOTYPE(int eofc , (void)); 335_PROTOTYPE(int getc , (int ec )); 336_PROTOTYPE(int readc , (void)); 337_PROTOTYPE(void unget , (int c )); 338_PROTOTYPE(void ioecho , (int c )); 339_PROTOTYPE(void prs , (char *s )); 340_PROTOTYPE(void putc , (int c )); 341_PROTOTYPE(void prn , (unsigned u )); 342_PROTOTYPE(void closef , (int i )); 343_PROTOTYPE(void closeall , (void)); 344 345/* 346 * IO control 347 */ 348_PROTOTYPE(void pushio , (struct ioarg *argp , int (*fn)(_VOID))); 349_PROTOTYPE(int remap , (int fd )); 350_PROTOTYPE(int openpipe , (int *pv )); 351_PROTOTYPE(void closepipe , (int *pv )); 352_PROTOTYPE(struct io *setbase , (struct io *ip )); 353 354extern struct ioarg temparg; /* temporary for PUSHIO */ 355#define PUSHIO(what,arg,gen) ((temparg.what = (arg)),pushio(&temparg,(gen))) 356#define RUN(what,arg,gen) ((temparg.what = (arg)), run(&temparg,(gen))) 357 358/* -------- word.h -------- */ 359#ifndef WORD_H 360#define WORD_H 1 361struct wdblock { 362 short w_bsize; 363 short w_nword; 364 /* bounds are arbitrary */ 365 char *w_words[1]; 366}; 367 368_PROTOTYPE(struct wdblock *addword , (char *wd , struct wdblock *wb )); 369_PROTOTYPE(struct wdblock *newword , (int nw )); 370_PROTOTYPE(char **getwords , (struct wdblock *wb )); 371#endif 372 373/* -------- area.h -------- */ 374 375/* 376 * storage allocation 377 */ 378_PROTOTYPE(char *getcell , (unsigned nbytes )); 379_PROTOTYPE(void garbage , (void)); 380_PROTOTYPE(void setarea , (char *cp , int a )); 381_PROTOTYPE(int getarea , (char *cp )); 382_PROTOTYPE(void freearea , (int a )); 383_PROTOTYPE(void freecell , (char *cp )); 384 385Extern int areanum; /* current allocation area */ 386 387#define NEW(type) (type *)getcell(sizeof(type)) 388#define DELETE(obj) freecell((char *)obj) 389