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