1/***********************************************************************
2*                                                                      *
3*               This software is part of the ast package               *
4*          Copyright (c) 1982-2011 AT&T Intellectual Property          *
5*                      and is licensed under the                       *
6*                  Common Public License, Version 1.0                  *
7*                    by AT&T Intellectual Property                     *
8*                                                                      *
9*                A copy of the License is available at                 *
10*            http://www.opensource.org/licenses/cpl1.0.txt             *
11*         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
12*                                                                      *
13*              Information and Software Systems Research               *
14*                            AT&T Research                             *
15*                           Florham Park NJ                            *
16*                                                                      *
17*                  David Korn <dgk@research.att.com>                   *
18*                                                                      *
19***********************************************************************/
20#pragma prototyped
21/*
22 * David Korn
23 * AT&T Labs
24 *
25 * Shell interface private definitions
26 *
27 */
28#ifndef defs_h_defined
29#define defs_h_defined
30
31#include	<ast.h>
32#include	<sfio.h>
33#include	<error.h>
34#include	"FEATURE/externs"
35#include	"FEATURE/options"
36#include	<cdt.h>
37#include	<history.h>
38#include	"fault.h"
39#include	"argnod.h"
40#include	"name.h"
41#include	<ctype.h>
42#define _SH_PRIVATE
43#include	<shcmd.h>
44#undef _SH_PRIVATE
45
46#ifndef pointerof
47#define pointerof(x)		((void*)((char*)0+(x)))
48#endif
49
50#define Empty			((char*)(e_sptbnl+3))
51
52#define	env_change()		(++ast.env_serial)
53#if SHOPT_ENV
54#   include	<env.h>
55#else
56#   define Env_t		void
57#   define sh_envput(e,p)	env_change()
58#   define env_delete(e,p)	env_change()
59#endif
60
61extern char*	sh_getenv(const char*);
62extern char*	sh_setenviron(const char*);
63
64/*
65 * note that the first few fields have to be the same as for
66 * Shscoped_t in <shell.h>
67 */
68
69
70struct sh_scoped
71{
72	struct sh_scoped *prevst;	/* pointer to previous state */
73	int		dolc;
74	char		**dolv;
75	char		*cmdname;
76	char		*filename;
77	char		*funname;
78	int		lineno;
79	Dt_t		*save_tree;	/* var_tree for calling function */
80	struct sh_scoped *self;		/* pointer to copy of this scope*/
81	Dt_t		*var_local;	/* local level variables for name() */
82	struct slnod	*staklist;	/* link list of function stacks */
83	int		states;
84	int		breakcnt;
85	int		execbrk;
86	int		loopcnt;
87	int		firstline;
88	int32_t		optindex;
89	int32_t		optnum;
90	int32_t		tmout;		/* value for TMOUT */
91	short		optchar;
92	short		opterror;
93	int		ioset;
94	unsigned short	trapmax;
95	char		*trap[SH_DEBUGTRAP+1];
96	char		**trapcom;
97	char		**otrapcom;
98	void		*timetrap;
99	struct Ufunction *real_fun;	/* current 'function name' function */
100};
101
102struct limits
103{
104	long		arg_max;	/* max arg+env exec() size */
105	int		open_max;	/* maximum number of file descriptors */
106	int		clk_tck;	/* number of ticks per second */
107	int		child_max;	/* maxumum number of children */
108	int		ngroups_max;	/* maximum number of process groups */
109	unsigned char	posix_version;	/* posix version number */
110	unsigned char	posix_jobcontrol;/* non-zero for job control systems */
111	unsigned char	fs3d;		/* non-zero for 3-d file system */
112};
113
114#ifndef SH_wait_f_defined
115    typedef int (*Shwait_f)(int, long, int);
116    #define     SH_wait_f_defined
117#endif
118
119
120struct shared
121{
122	struct limits	lim;
123	uid_t		userid;
124	uid_t		euserid;
125	gid_t		groupid;
126	gid_t		egroupid;
127	pid_t		pid;
128	int32_t		ppid;
129	unsigned char	sigruntime[2];
130	Namval_t	*bltin_nodes;
131	Namval_t	*bltin_cmds;
132	History_t	*hist_ptr;
133	char		*shpath;
134	char		*user;
135	char		**sigmsg;
136	char		*rcfile;
137	char		**login_files;
138	void		*ed_context;
139	void		*init_context;
140	void		*job_context;
141	int		*stats;
142	int		bltin_nnodes;	/* number of bltins nodes */
143	int		sigmax;
144	int		nforks;
145	Shwait_f	waitevent;
146};
147
148#define _SH_PRIVATE \
149	struct shared	*gd;		/* global data */ \
150	struct sh_scoped st;		/* scoped information */ \
151	Stk_t		*stk;		/* stack poiter */ \
152	Sfio_t		*heredocs;	/* current here-doc temp file */ \
153	Sfio_t		*funlog;	/* for logging function definitions */ \
154	int		**fdptrs;	/* pointer to file numbers */ \
155	int		savexit; \
156	char		*lastarg; \
157	char		*lastpath;	/* last alsolute path found */ \
158	int		path_err;	/* last error on path search */ \
159	Dt_t		*track_tree;	/* for tracked aliases*/ \
160	Dt_t		*var_base;	/* global level variables */ \
161	Namval_t	*namespace;	/* current active namespace*/ \
162	Namval_t	*last_table;	/* last table used in last nv_open  */ \
163	Namval_t	*prev_table;	/* previous table used in nv_open  */ \
164	Sfio_t		*outpool;	/* ouput stream pool */ \
165	long		timeout;	/* read timeout */ \
166	short		curenv;		/* current subshell number */ \
167	short		jobenv;		/* subshell number for jobs */ \
168	int		infd;		/* input file descriptor */ \
169	short		nextprompt;	/* next prompt is PS<nextprompt> */ \
170	short		poolfiles; \
171	Namval_t	*posix_fun;	/* points to last name() function */ \
172	char		*outbuff;	/* pointer to output buffer */ \
173	char		*errbuff;	/* pointer to stderr buffer */ \
174	char		*prompt;	/* pointer to prompt string */ \
175	char		*shname;	/* shell name */ \
176	char		*comdiv;	/* points to sh -c argument */ \
177	char		*prefix;	/* prefix for compound assignment */ \
178	sigjmp_buf	*jmplist;	/* longjmp return stack */ \
179	int		oldexit; \
180	pid_t		bckpid;		/* background process id */ \
181	pid_t		cpid; \
182	pid_t		spid; 		/* subshell process id */ \
183	pid_t		pipepid; \
184	pid_t		outpipepid; \
185	int		topfd; \
186	int		savesig; \
187	unsigned char	*sigflag;	/* pointer to signal states */ \
188	char		intrap; \
189	char		login_sh; \
190	char		lastbase; \
191	char		forked;	\
192	char		binscript; \
193	char		deftype; \
194	char		funload; \
195	char		used_pos;	/* used postional parameter */\
196	char		universe; \
197	char		winch; \
198	char		indebug; 	/* set when in debug trap */ \
199	unsigned char	ignsig;		/* ignored signal in subshell */ \
200	unsigned char	lastsig;	/* last signal received */ \
201	char		comsub;		/* set when in $() comsub */ \
202	char		subshare;	/* set when in ${..} comsub */ \
203	char		toomany;	/* set when out of fd's */ \
204	char		instance;	/* in set_instance */ \
205	char		decomma;	/* decimal_point=',' */ \
206	char		*readscript;	/* set before reading a script */ \
207	int		subdup;		/* bitmask for dups of 1 */ \
208	int		*inpipe;	/* input pipe pointer */ \
209	int		*outpipe;	/* output pipe pointer */ \
210	int		cpipe[3]; \
211	int		coutpipe; \
212	int		inuse_bits; \
213	struct argnod	*envlist; \
214	struct dolnod	*arglist; \
215	int		fn_depth; \
216	int		fn_reset; \
217	int		dot_depth; \
218	int		hist_depth; \
219	int		xargmin; \
220	int		xargmax; \
221	int		xargexit; \
222	int		nenv; \
223	mode_t		mask; \
224	Env_t		*env; \
225	void		*init_context; \
226	void		*mac_context; \
227	void		*lex_context; \
228	void		*arg_context; \
229	void		*job_context; \
230	void		*pathlist; \
231	void		*defpathlist; \
232	void		*cdpathlist; \
233	char		**argaddr; \
234	void		*optlist; \
235	struct sh_scoped global; \
236	struct checkpt	checkbase; \
237	Shinit_f	userinit; \
238	Shbltin_f	bltinfun; \
239	Shbltin_t	bltindata; \
240	char		*cur_line; \
241	int		offsets[10]; \
242	Sfio_t		**sftable; \
243	unsigned char	*fdstatus; \
244	const char	*pwd; \
245	void		*jmpbuffer; \
246	void		*mktype; \
247	Sfio_t		*strbuf; \
248	Sfio_t		*strbuf2; \
249	Dt_t		*last_root; \
250	Dt_t		*prev_root; \
251	Dt_t		*fpathdict; \
252	Dt_t		*typedict; \
253	Dt_t		*inpool; \
254	Dt_t		*transdict; \
255	char		ifstable[256]; \
256	unsigned long	test; \
257	Shopt_t		offoptions; \
258	Shopt_t		glob_options; \
259	Namval_t	*typeinit; \
260	Namfun_t	nvfun; \
261	char		*mathnodes; \
262	void		*coshell; \
263	struct Regress_s*regress;
264
265#include	<shell.h>
266
267#include	"regress.h"
268
269/* error exits from various parts of shell */
270#define	NIL(type)	((type)0)
271
272#define new_of(type,x)	((type*)malloc((unsigned)sizeof(type)+(x)))
273
274#define exitset()	(sh.savexit=sh.exitval)
275
276#ifndef SH_DICT
277#define SH_DICT		(void*)e_dict
278#endif
279
280#ifndef SH_CMDLIB_DIR
281#define SH_CMDLIB_DIR	"/opt/ast/bin"
282#endif
283
284/* states */
285/* low numbered states are same as options */
286#define SH_NOFORK	0	/* set when fork not necessary */
287#define	SH_FORKED	7	/* set when process has been forked */
288#define	SH_PROFILE	8	/* set when processing profiles */
289#define SH_NOALIAS	9	/* do not expand non-exported aliases */
290#define SH_NOTRACK	10	/* set to disable sftrack() function */
291#define SH_STOPOK	11	/* set for stopable builtins */
292#define SH_GRACE	12	/* set for timeout grace period */
293#define SH_TIMING	13	/* set while timing pipelines */
294#define SH_DEFPATH	14	/* set when using default path */
295#define SH_INIT		15	/* set when initializing the shell */
296#define SH_TTYWAIT	16	/* waiting for keyboard input */
297#define	SH_FCOMPLETE	17	/* set for filename completion */
298#define	SH_PREINIT	18	/* set with SH_INIT before parsing options */
299#define SH_COMPLETE	19	/* set for command completion */
300
301#define SH_BASH			41
302#define SH_BRACEEXPAND		42
303#define SH_POSIX		46
304#define SH_MULTILINE    	47
305
306#define SH_NOPROFILE		78
307#define SH_NOUSRPROFILE		79
308#define SH_LOGIN_SHELL		67
309#define SH_COMMANDLINE		0x100
310#define SH_BASHEXTRA		0x200
311#define SH_BASHOPT		0x400
312
313#define SH_ID			"ksh"	/* ksh id */
314#define SH_STD			"sh"	/* standard sh id */
315
316/* defines for sh_type() */
317
318#define SH_TYPE_SH		001
319#define SH_TYPE_KSH		002
320#define SH_TYPE_BASH		004
321#define SH_TYPE_LOGIN		010
322#define SH_TYPE_PROFILE		020
323#define SH_TYPE_RESTRICTED	040
324
325#if SHOPT_BASH
326#   ifndef SHOPT_HISTEXPAND
327#	define SHOPT_HISTEXPAND	1
328#   endif
329/*
330 *  define for all the bash options
331 */
332#   define SH_CDABLE_VARS	51
333#   define SH_CDSPELL		52
334#   define SH_CHECKHASH		53
335#   define SH_CHECKWINSIZE	54
336#   define SH_CMDHIST		55
337#   define SH_DOTGLOB		56
338#   define SH_EXECFAIL		57
339#   define SH_EXPAND_ALIASES	58
340#   define SH_EXTGLOB		59
341#   define SH_HOSTCOMPLETE	63
342#   define SH_HUPONEXIT		64
343#   define SH_INTERACTIVE_COMM	65
344#   define SH_LITHIST		66
345#   define SH_MAILWARN		68
346#   define SH_NOEMPTYCMDCOMPL	69
347#   define SH_NOCASEGLOB	70
348#   define SH_NULLGLOB		71
349#   define SH_PHYSICAL		45
350#   define SH_PROGCOMP		72
351#   define SH_PROMPTVARS	73
352#   define SH_RESTRICTED2	74
353#   define SH_SHIFT_VERBOSE	75
354#   define SH_SOURCEPATH	76
355#   define SH_XPG_ECHO		77
356#endif
357
358#if SHOPT_HISTEXPAND
359#   define SH_HISTAPPEND	60
360#   define SH_HISTEXPAND	43
361#   define SH_HISTORY2		44
362#   define SH_HISTREEDIT	61
363#   define SH_HISTVERIFY	62
364#endif
365
366#ifndef PIPE_BUF
367#   define PIPE_BUF		512
368#endif
369
370#if SHOPT_PFSH && ( !_lib_getexecuser || !_lib_free_execattr )
371#   undef SHOPT_PFSH
372#endif
373
374#define MATCH_MAX		64
375
376#define SH_READEVAL		0x4000	/* for sh_eval */
377#define SH_FUNEVAL		0x10000	/* for sh_eval for function load */
378
379extern struct shared	*shgd;
380extern Shell_t		*nv_shell(Namval_t*);
381extern int		sh_addlib(Shell_t*,void*);
382extern void		sh_applyopts(Shell_t*,Shopt_t);
383extern char 		**sh_argbuild(Shell_t*,int*,const struct comnod*,int);
384extern struct dolnod	*sh_argfree(Shell_t *, struct dolnod*,int);
385extern struct dolnod	*sh_argnew(Shell_t*,char*[],struct dolnod**);
386extern void 		*sh_argopen(Shell_t*);
387extern struct argnod	*sh_argprocsub(Shell_t*,struct argnod*);
388extern void 		sh_argreset(Shell_t*,struct dolnod*,struct dolnod*);
389extern Namval_t		*sh_assignok(Namval_t*,int);
390extern struct dolnod	*sh_arguse(Shell_t*);
391extern char		*sh_checkid(char*,char*);
392extern void		sh_chktrap(Shell_t*);
393extern void		sh_deparse(Sfio_t*,const Shnode_t*,int);
394extern int		sh_debug(Shell_t *shp,const char*,const char*,const char*,char *const[],int);
395extern int 		sh_echolist(Shell_t*,Sfio_t*, int, char**);
396extern struct argnod	*sh_endword(Shell_t*,int);
397extern char 		**sh_envgen(void);
398#if SHOPT_ENV
399extern void 		sh_envput(Env_t*, Namval_t*);
400#endif
401extern void 		sh_envnolocal(Namval_t*,void*);
402extern Sfdouble_t	sh_arith(Shell_t*,const char*);
403extern void		*sh_arithcomp(Shell_t *,char*);
404extern pid_t 		sh_fork(Shell_t*,int,int*);
405extern pid_t		_sh_fork(Shell_t*,pid_t, int ,int*);
406extern char 		*sh_mactrim(Shell_t*,char*,int);
407extern int 		sh_macexpand(Shell_t*,struct argnod*,struct argnod**,int);
408extern int		sh_macfun(Shell_t*,const char*,int);
409extern void 		sh_machere(Shell_t*,Sfio_t*, Sfio_t*, char*);
410extern void 		*sh_macopen(Shell_t*);
411extern char 		*sh_macpat(Shell_t*,struct argnod*,int);
412extern Sfdouble_t	sh_mathfun(Shell_t*, void*, int, Sfdouble_t*);
413extern int		sh_outtype(Shell_t*, Sfio_t*);
414extern char 		*sh_mactry(Shell_t*,char*);
415extern void		sh_printopts(Shopt_t,int,Shopt_t*);
416extern int 		sh_readline(Shell_t*,char**,int,int,long);
417extern Sfio_t		*sh_sfeval(char*[]);
418extern void		sh_setmatch(const char*,int,int,int[]);
419extern Dt_t		*sh_subaliastree(int);
420extern void             sh_scope(Shell_t*, struct argnod*, int);
421extern Namval_t		*sh_scoped(Shell_t*, Namval_t*);
422extern Dt_t		*sh_subfuntree(int);
423extern void		sh_subjobcheck(pid_t);
424extern int		sh_subsavefd(int);
425extern void		sh_subtmpfile(Shell_t*);
426extern char 		*sh_substitute(const char*,const char*,char*);
427extern void		sh_timetraps(Shell_t*);
428extern const char	*_sh_translate(const char*);
429extern int		sh_trace(Shell_t*,char*[],int);
430extern void		sh_trim(char*);
431extern int		sh_type(const char*);
432extern void             sh_unscope(Shell_t*);
433extern void		sh_utol(const char*, char*);
434extern int 		sh_whence(char**,int);
435#if SHOPT_COSHELL
436   extern int		sh_coaddfile(Shell_t*,char*);
437   extern int		sh_copipe(Shell_t*, int[], int);
438   extern int		sh_coaccept(Shell_t*,int[],int);
439#endif /* SHOPT_COSHELL */
440#if SHOPT_NAMESPACE
441    extern Namval_t	*sh_fsearch(Shell_t*,const char *,int);
442#endif /* SHOPT_NAMESPACE */
443
444#ifndef ERROR_dictionary
445#   define ERROR_dictionary(s)	(s)
446#endif
447#define sh_translate(s)	_sh_translate(ERROR_dictionary(s))
448
449#define WBITS		(sizeof(long)*8)
450#define WMASK		(0xff)
451
452#define is_option(s,x)	((s)->v[((x)&WMASK)/WBITS] & (1L << ((x) % WBITS)))
453#define on_option(s,x)	((s)->v[((x)&WMASK)/WBITS] |= (1L << ((x) % WBITS)))
454#define off_option(s,x)	((s)->v[((x)&WMASK)/WBITS] &= ~(1L << ((x) % WBITS)))
455#define sh_isoption(x)	is_option(&sh.options,x)
456#define sh_onoption(x)	on_option(&sh.options,x)
457#define sh_offoption(x)	off_option(&sh.options,x)
458
459
460#define sh_state(x)	( 1<<(x))
461#define	sh_isstate(x)	(sh.st.states&sh_state(x))
462#define	sh_onstate(x)	(sh.st.states |= sh_state(x))
463#define	sh_offstate(x)	(sh.st.states &= ~sh_state(x))
464#define	sh_getstate()	(sh.st.states)
465#define	sh_setstate(x)	(sh.st.states = (x))
466
467#define sh_sigcheck(shp) do{if(shp->trapnote&SH_SIGSET)sh_exit(SH_EXITSIG);} while(0)
468
469extern int32_t		sh_mailchk;
470extern const char	e_dict[];
471
472/* sh_printopts() mode flags -- set --[no]option by default */
473
474#define PRINT_VERBOSE	0x01	/* option on|off list		*/
475#define PRINT_ALL	0x02	/* list unset options too	*/
476#define PRINT_NO_HEADER	0x04	/* omit listing header		*/
477#define PRINT_SHOPT	0x08	/* shopt -s|-u			*/
478#define PRINT_TABLE	0x10	/* table of all options		*/
479
480#ifdef SHOPT_STATS
481    /* performance statistics */
482#   define	STAT_ARGHITS	0
483#   define	STAT_ARGEXPAND	1
484#   define	STAT_COMSUB	2
485#   define	STAT_FORKS	3
486#   define	STAT_FUNCT	4
487#   define	STAT_GLOBS	5
488#   define	STAT_READS	6
489#   define	STAT_NVHITS	7
490#   define	STAT_NVOPEN	8
491#   define	STAT_PATHS	9
492#   define	STAT_SVFUNCT	10
493#   define	STAT_SCMDS	11
494#   define	STAT_SPAWN	12
495#   define	STAT_SUBSHELL	13
496    extern const Shtable_t shtab_stats[];
497#   define sh_stats(x)	(shgd->stats[(x)]++)
498#else
499#   define sh_stats(x)
500#endif /* SHOPT_STATS */
501
502
503#endif
504