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