172339Sabial#include <stdlib.h> 272339Sabial#include <string.h> 372339Sabial#include <unistd.h> 472339Sabial#include <fcntl.h> 572339Sabial 672339Sabial/* Need a way to have void used for ANSI, nothing for K&R. */ 772339Sabial#ifndef _ANSI 872339Sabial#undef _VOID 972339Sabial#define _VOID 1072339Sabial#endif 1172339Sabial 1272339Sabial/* -------- sh.h -------- */ 1372339Sabial/* 1472339Sabial * shell 1572339Sabial */ 1672339Sabial 1772339Sabial#define LINELIM 2100 1872339Sabial#define NPUSH 8 /* limit to input nesting */ 1972339Sabial 2072339Sabial#define NOFILE 20 /* Number of open files */ 2172339Sabial#define NUFILE 10 /* Number of user-accessible files */ 2272339Sabial#define FDBASE 10 /* First file usable by Shell */ 2372339Sabial 2472339Sabial/* 2572339Sabial * values returned by wait 2672339Sabial */ 2772339Sabial#define WAITSIG(s) ((s)&0177) 2872339Sabial#define WAITVAL(s) (((s)>>8)&0377) 2972339Sabial#define WAITCORE(s) (((s)&0200)!=0) 3072339Sabial 3172339Sabial/* 3272339Sabial * library and system defintions 3372339Sabial */ 3472339Sabial#ifdef __STDC__ 3572339Sabialtypedef void xint; /* base type of jmp_buf, for not broken compilers */ 3672339Sabial#else 3772339Sabialtypedef char * xint; /* base type of jmp_buf, for broken compilers */ 3872339Sabial#endif 3972339Sabial 4072339Sabial/* 4172339Sabial * shell components 4272339Sabial */ 4372339Sabial/* #include "area.h" */ 4472339Sabial/* #include "word.h" */ 4572339Sabial/* #include "io.h" */ 4672339Sabial/* #include "var.h" */ 4772339Sabial 4872339Sabial#define QUOTE 0200 4972339Sabial 5072339Sabial#define NOBLOCK ((struct op *)NULL) 5172339Sabial#define NOWORD ((char *)NULL) 5272339Sabial#define NOWORDS ((char **)NULL) 5372339Sabial#define NOPIPE ((int *)NULL) 5472339Sabial 5572339Sabial/* 5672339Sabial * Description of a command or an operation on commands. 5772339Sabial * Might eventually use a union. 5872339Sabial */ 5972339Sabialstruct op { 6072339Sabial int type; /* operation type, see below */ 6172339Sabial char **words; /* arguments to a command */ 6272339Sabial struct ioword **ioact; /* IO actions (eg, < > >>) */ 6372339Sabial struct op *left; 6472339Sabial struct op *right; 6572339Sabial char *str; /* identifier for case and for */ 6672339Sabial}; 6772339Sabial 6872339Sabial#define TCOM 1 /* command */ 6972339Sabial#define TPAREN 2 /* (c-list) */ 7072339Sabial#define TPIPE 3 /* a | b */ 7172339Sabial#define TLIST 4 /* a [&;] b */ 7272339Sabial#define TOR 5 /* || */ 7372339Sabial#define TAND 6 /* && */ 7472339Sabial#define TFOR 7 7572339Sabial#define TDO 8 7672339Sabial#define TCASE 9 7772339Sabial#define TIF 10 7872339Sabial#define TWHILE 11 7972339Sabial#define TUNTIL 12 8072339Sabial#define TELIF 13 8172339Sabial#define TPAT 14 /* pattern in case */ 8272339Sabial#define TBRACE 15 /* {c-list} */ 8372339Sabial#define TASYNC 16 /* c & */ 8472339Sabial 8572339Sabial/* 8672339Sabial * actions determining the environment of a process 8772339Sabial */ 8872339Sabial#define BIT(i) (1<<(i)) 8972339Sabial#define FEXEC BIT(0) /* execute without forking */ 9072339Sabial 9172339Sabial/* 9272339Sabial * flags to control evaluation of words 9372339Sabial */ 9472339Sabial#define DOSUB 1 /* interpret $, `, and quotes */ 9572339Sabial#define DOBLANK 2 /* perform blank interpretation */ 9672339Sabial#define DOGLOB 4 /* interpret [?* */ 9772339Sabial#define DOKEY 8 /* move words with `=' to 2nd arg. list */ 9872339Sabial#define DOTRIM 16 /* trim resulting string */ 9972339Sabial 10072339Sabial#define DOALL (DOSUB|DOBLANK|DOGLOB|DOKEY|DOTRIM) 10172339Sabial 10272339SabialExtern char **dolv; 10372339SabialExtern int dolc; 10472339SabialExtern int exstat; 10572339SabialExtern char gflg; 10672339SabialExtern int talking; /* interactive (talking-type wireless) */ 10772339SabialExtern int execflg; 10872339SabialExtern int multiline; /* \n changed to ; */ 10972339SabialExtern struct op *outtree; /* result from parser */ 11072339Sabial 11172339SabialExtern xint *failpt; 11272339SabialExtern xint *errpt; 11372339Sabial 11472339Sabialstruct brkcon { 11572339Sabial jmp_buf brkpt; 11672339Sabial struct brkcon *nextlev; 11772339Sabial} ; 11872339SabialExtern struct brkcon *brklist; 11972339SabialExtern int isbreak; 12072339Sabial 12172339Sabial/* 12272339Sabial * redirection 12372339Sabial */ 12472339Sabialstruct ioword { 12572339Sabial short io_unit; /* unit affected */ 12672339Sabial short io_flag; /* action (below) */ 12772339Sabial char *io_name; /* file name */ 12872339Sabial}; 12972339Sabial#define IOREAD 1 /* < */ 13072339Sabial#define IOHERE 2 /* << (here file) */ 13172339Sabial#define IOWRITE 4 /* > */ 13272339Sabial#define IOCAT 8 /* >> */ 13372339Sabial#define IOXHERE 16 /* ${}, ` in << */ 13472339Sabial#define IODUP 32 /* >&digit */ 13572339Sabial#define IOCLOSE 64 /* >&- */ 13672339Sabial 13772339Sabial#define IODEFAULT (-1) /* token for default IO unit */ 13872339Sabial 13972339SabialExtern struct wdblock *wdlist; 14072339SabialExtern struct wdblock *iolist; 14172339Sabial 14272339Sabial/* 14372339Sabial * parsing & execution environment 14472339Sabial */ 14572339Sabialextern struct env { 14672339Sabial char *linep; 14772339Sabial struct io *iobase; 14872339Sabial struct io *iop; 14972339Sabial xint *errpt; 15072339Sabial int iofd; 15172339Sabial struct env *oenv; 15272339Sabial} e; 15372339Sabial 15472339Sabial/* 15572339Sabial * flags: 15672339Sabial * -e: quit on error 15772339Sabial * -k: look for name=value everywhere on command line 15872339Sabial * -n: no execution 15972339Sabial * -t: exit after reading and executing one command 16072339Sabial * -v: echo as read 16172339Sabial * -x: trace 16272339Sabial * -u: unset variables net diagnostic 16372339Sabial */ 16472339Sabialextern char *flag; 16572339Sabial 16672339Sabialextern char *null; /* null value for variable */ 16772339Sabialextern int intr; /* interrupt pending */ 16872339Sabial 16972339SabialExtern char *trap[_NSIG+1]; 17072339SabialExtern char ourtrap[_NSIG+1]; 17172339SabialExtern int trapset; /* trap pending */ 17272339Sabial 17372339Sabialextern int heedint; /* heed interrupt signals */ 17472339Sabial 17572339SabialExtern int yynerrs; /* yacc */ 17672339Sabial 17772339SabialExtern char line[LINELIM]; 17872339Sabialextern char *elinep; 17972339Sabial 18072339Sabial/* 18172339Sabial * other functions 18272339Sabial */ 18372339Sabial#ifdef __STDC__ 18472339Sabialint (*inbuilt(char *s ))(void); 18572339Sabial#else 18672339Sabialint (*inbuilt())(); 18772339Sabial#endif 18872339Sabial 18972339Sabial#ifdef __FreeBSD__ 19072339Sabial#define _PROTOTYPE(x,y) x ## y 19172339Sabial#endif 19272339Sabial 19372339Sabial_PROTOTYPE(char *rexecve , (char *c , char **v , char **envp )); 19472339Sabial_PROTOTYPE(char *space , (int n )); 19572339Sabial_PROTOTYPE(char *strsave , (char *s , int a )); 19672339Sabial_PROTOTYPE(char *evalstr , (char *cp , int f )); 19772339Sabial_PROTOTYPE(char *putn , (int n )); 19872339Sabial_PROTOTYPE(char *itoa , (unsigned u , int n )); 19972339Sabial_PROTOTYPE(char *unquote , (char *as )); 20072339Sabial_PROTOTYPE(struct var *lookup , (char *n )); 20172339Sabial_PROTOTYPE(int rlookup , (char *n )); 20272339Sabial_PROTOTYPE(struct wdblock *glob , (char *cp , struct wdblock *wb )); 20372339Sabial_PROTOTYPE(int subgetc , (int ec , int quoted )); 20472339Sabial_PROTOTYPE(char **makenv , (void)); 20572339Sabial_PROTOTYPE(char **eval , (char **ap , int f )); 20672339Sabial_PROTOTYPE(int setstatus , (int s )); 20772339Sabial_PROTOTYPE(int waitfor , (int lastpid , int canintr )); 20872339Sabial 20972339Sabial_PROTOTYPE(void onintr , (int s )); /* SIGINT handler */ 21072339Sabial 21172339Sabial_PROTOTYPE(int newenv , (int f )); 21272339Sabial_PROTOTYPE(void quitenv , (void)); 21372339Sabial_PROTOTYPE(void err , (char *s )); 21472339Sabial_PROTOTYPE(int anys , (char *s1 , char *s2 )); 21572339Sabial_PROTOTYPE(int any , (int c , char *s )); 21672339Sabial_PROTOTYPE(void next , (int f )); 21772339Sabial_PROTOTYPE(void setdash , (void)); 21872339Sabial_PROTOTYPE(void onecommand , (void)); 21972339Sabial_PROTOTYPE(void runtrap , (int i )); 22072339Sabial_PROTOTYPE(void xfree , (char *s )); 22172339Sabial_PROTOTYPE(int letter , (int c )); 22272339Sabial_PROTOTYPE(int digit , (int c )); 22372339Sabial_PROTOTYPE(int letnum , (int c )); 22472339Sabial_PROTOTYPE(int gmatch , (char *s , char *p )); 22572339Sabial 22672339Sabial/* 22772339Sabial * error handling 22872339Sabial */ 22972339Sabial_PROTOTYPE(void leave , (void)); /* abort shell (or fail in subshell) */ 23072339Sabial_PROTOTYPE(void fail , (void)); /* fail but return to process next command */ 23172339Sabial_PROTOTYPE(void warn , (char *s )); 23272339Sabial_PROTOTYPE(void sig , (int i )); /* default signal handler */ 23372339Sabial 23472339Sabial/* -------- var.h -------- */ 23572339Sabial 23672339Sabialstruct var { 23772339Sabial char *value; 23872339Sabial char *name; 23972339Sabial struct var *next; 24072339Sabial char status; 24172339Sabial}; 24272339Sabial#define COPYV 1 /* flag to setval, suggesting copy */ 24372339Sabial#define RONLY 01 /* variable is read-only */ 24472339Sabial#define EXPORT 02 /* variable is to be exported */ 24572339Sabial#define GETCELL 04 /* name & value space was got with getcell */ 24672339Sabial 24772339SabialExtern struct var *vlist; /* dictionary */ 24872339Sabial 24972339SabialExtern struct var *homedir; /* home directory */ 25072339SabialExtern struct var *prompt; /* main prompt */ 25172339SabialExtern struct var *cprompt; /* continuation prompt */ 25272339SabialExtern struct var *path; /* search path for commands */ 25372339SabialExtern struct var *shell; /* shell to interpret command files */ 25472339SabialExtern struct var *ifs; /* field separators */ 25572339Sabial 25672339Sabial_PROTOTYPE(int yyparse , (void)); 25772339Sabial_PROTOTYPE(struct var *lookup , (char *n )); 25872339Sabial_PROTOTYPE(void setval , (struct var *vp , char *val )); 25972339Sabial_PROTOTYPE(void nameval , (struct var *vp , char *val , char *name )); 26072339Sabial_PROTOTYPE(void export , (struct var *vp )); 26172339Sabial_PROTOTYPE(void ronly , (struct var *vp )); 26272339Sabial_PROTOTYPE(int isassign , (char *s )); 26372339Sabial_PROTOTYPE(int checkname , (char *cp )); 26472339Sabial_PROTOTYPE(int assign , (char *s , int cf )); 26572339Sabial_PROTOTYPE(void putvlist , (int f , int out )); 26672339Sabial_PROTOTYPE(int eqname , (char *n1 , char *n2 )); 26772339Sabial 26872339Sabial_PROTOTYPE(int execute , (struct op *t , int *pin , int *pout , int act )); 26972339Sabial 27072339Sabial/* -------- io.h -------- */ 27172339Sabial/* io buffer */ 27272339Sabialstruct iobuf { 27372339Sabial unsigned id; /* buffer id */ 27472339Sabial char buf[512]; /* buffer */ 27572339Sabial char *bufp; /* pointer into buffer */ 27672339Sabial char *ebufp; /* pointer to end of buffer */ 27772339Sabial}; 27872339Sabial 27972339Sabial/* possible arguments to an IO function */ 28072339Sabialstruct ioarg { 28172339Sabial char *aword; 28272339Sabial char **awordlist; 28372339Sabial int afile; /* file descriptor */ 28472339Sabial unsigned afid; /* buffer id */ 28572339Sabial long afpos; /* file position */ 28672339Sabial struct iobuf *afbuf; /* buffer for this file */ 28772339Sabial}; 28872339SabialExtern struct ioarg ioargstack[NPUSH]; 28972339Sabial#define AFID_NOBUF (~0) 29072339Sabial#define AFID_ID 0 29172339Sabial 29272339Sabial/* an input generator's state */ 29372339Sabialstruct io { 29472339Sabial int (*iofn)(_VOID); 29572339Sabial struct ioarg *argp; 29672339Sabial int peekc; 29772339Sabial char prev; /* previous character read by readc() */ 29872339Sabial char nlcount; /* for `'s */ 29972339Sabial char xchar; /* for `'s */ 30072339Sabial char task; /* reason for pushed IO */ 30172339Sabial}; 30272339SabialExtern struct io iostack[NPUSH]; 30372339Sabial#define XOTHER 0 /* none of the below */ 30472339Sabial#define XDOLL 1 /* expanding ${} */ 30572339Sabial#define XGRAVE 2 /* expanding `'s */ 30672339Sabial#define XIO 3 /* file IO */ 30772339Sabial 30872339Sabial/* in substitution */ 30972339Sabial#define INSUB() (e.iop->task == XGRAVE || e.iop->task == XDOLL) 31072339Sabial 31172339Sabial/* 31272339Sabial * input generators for IO structure 31372339Sabial */ 31472339Sabial_PROTOTYPE(int nlchar , (struct ioarg *ap )); 31572339Sabial_PROTOTYPE(int strchar , (struct ioarg *ap )); 31672339Sabial_PROTOTYPE(int qstrchar , (struct ioarg *ap )); 31772339Sabial_PROTOTYPE(int filechar , (struct ioarg *ap )); 31872339Sabial_PROTOTYPE(int herechar , (struct ioarg *ap )); 31972339Sabial_PROTOTYPE(int linechar , (struct ioarg *ap )); 32072339Sabial_PROTOTYPE(int gravechar , (struct ioarg *ap , struct io *iop )); 32172339Sabial_PROTOTYPE(int qgravechar , (struct ioarg *ap , struct io *iop )); 32272339Sabial_PROTOTYPE(int dolchar , (struct ioarg *ap )); 32372339Sabial_PROTOTYPE(int wdchar , (struct ioarg *ap )); 32472339Sabial_PROTOTYPE(void scraphere , (void)); 32572339Sabial_PROTOTYPE(void freehere , (int area )); 32672339Sabial_PROTOTYPE(void gethere , (void)); 32772339Sabial_PROTOTYPE(void markhere , (char *s , struct ioword *iop )); 32872339Sabial_PROTOTYPE(int herein , (char *hname , int xdoll )); 32972339Sabial_PROTOTYPE(int run , (struct ioarg *argp , int (*f)(_VOID))); 33072339Sabial 33172339Sabial/* 33272339Sabial * IO functions 33372339Sabial */ 33472339Sabial_PROTOTYPE(int eofc , (void)); 33572339Sabial_PROTOTYPE(int getc , (int ec )); 33672339Sabial_PROTOTYPE(int readc , (void)); 33772339Sabial_PROTOTYPE(void unget , (int c )); 33872339Sabial_PROTOTYPE(void ioecho , (int c )); 33972339Sabial_PROTOTYPE(void prs , (char *s )); 34072339Sabial_PROTOTYPE(void putc , (int c )); 34172339Sabial_PROTOTYPE(void prn , (unsigned u )); 34272339Sabial_PROTOTYPE(void closef , (int i )); 34372339Sabial_PROTOTYPE(void closeall , (void)); 34472339Sabial 34572339Sabial/* 34672339Sabial * IO control 34772339Sabial */ 34872339Sabial_PROTOTYPE(void pushio , (struct ioarg *argp , int (*fn)(_VOID))); 34972339Sabial_PROTOTYPE(int remap , (int fd )); 35072339Sabial_PROTOTYPE(int openpipe , (int *pv )); 35172339Sabial_PROTOTYPE(void closepipe , (int *pv )); 35272339Sabial_PROTOTYPE(struct io *setbase , (struct io *ip )); 35372339Sabial 35472339Sabialextern struct ioarg temparg; /* temporary for PUSHIO */ 35572339Sabial#define PUSHIO(what,arg,gen) ((temparg.what = (arg)),pushio(&temparg,(gen))) 35672339Sabial#define RUN(what,arg,gen) ((temparg.what = (arg)), run(&temparg,(gen))) 35772339Sabial 35872339Sabial/* -------- word.h -------- */ 35972339Sabial#ifndef WORD_H 36072339Sabial#define WORD_H 1 36172339Sabialstruct wdblock { 36272339Sabial short w_bsize; 36372339Sabial short w_nword; 36472339Sabial /* bounds are arbitrary */ 36572339Sabial char *w_words[1]; 36672339Sabial}; 36772339Sabial 36872339Sabial_PROTOTYPE(struct wdblock *addword , (char *wd , struct wdblock *wb )); 36972339Sabial_PROTOTYPE(struct wdblock *newword , (int nw )); 37072339Sabial_PROTOTYPE(char **getwords , (struct wdblock *wb )); 37172339Sabial#endif 37272339Sabial 37372339Sabial/* -------- area.h -------- */ 37472339Sabial 37572339Sabial/* 37672339Sabial * storage allocation 37772339Sabial */ 37872339Sabial_PROTOTYPE(char *getcell , (unsigned nbytes )); 37972339Sabial_PROTOTYPE(void garbage , (void)); 38072339Sabial_PROTOTYPE(void setarea , (char *cp , int a )); 38172339Sabial_PROTOTYPE(int getarea , (char *cp )); 38272339Sabial_PROTOTYPE(void freearea , (int a )); 38372339Sabial_PROTOTYPE(void freecell , (char *cp )); 38472339Sabial 38572339SabialExtern int areanum; /* current allocation area */ 38672339Sabial 38772339Sabial#define NEW(type) (type *)getcell(sizeof(type)) 38872339Sabial#define DELETE(obj) freecell((char *)obj) 389