1/* vi: set sw=4 ts=4: */
2/*
3 * sh.c -- a prototype Bourne shell grammar parser
4 *      Intended to follow the original Thompson and Ritchie
5 *      "small and simple is beautiful" philosophy, which
6 *      incidentally is a good match to today's BusyBox.
7 *
8 * Copyright (C) 2000,2001  Larry Doolittle  <larry@doolittle.boa.org>
9 *
10 * Credits:
11 *      The parser routines proper are all original material, first
12 *      written Dec 2000 and Jan 2001 by Larry Doolittle.  The
13 *      execution engine, the builtins, and much of the underlying
14 *      support has been adapted from busybox-0.49pre's lash, which is
15 *      Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
16 *      written by Erik Andersen <andersen@codepoet.org>.  That, in turn,
17 *      is based in part on ladsh.c, by Michael K. Johnson and Erik W.
18 *      Troan, which they placed in the public domain.  I don't know
19 *      how much of the Johnson/Troan code has survived the repeated
20 *      rewrites.
21 *
22 * Other credits:
23 *      b_addchr() derived from similar w_addchar function in glibc-2.2
24 *      setup_redirect(), redirect_opt_num(), and big chunks of main()
25 *      and many builtins derived from contributions by Erik Andersen
26 *      miscellaneous bugfixes from Matt Kraai
27 *
28 * There are two big (and related) architecture differences between
29 * this parser and the lash parser.  One is that this version is
30 * actually designed from the ground up to understand nearly all
31 * of the Bourne grammar.  The second, consequential change is that
32 * the parser and input reader have been turned inside out.  Now,
33 * the parser is in control, and asks for input as needed.  The old
34 * way had the input reader in control, and it asked for parsing to
35 * take place as needed.  The new way makes it much easier to properly
36 * handle the recursion implicit in the various substitutions, especially
37 * across continuation lines.
38 *
39 * Bash grammar not implemented: (how many of these were in original sh?)
40 *      $_
41 *      ! negation operator for pipes
42 *      &> and >& redirection of stdout+stderr
43 *      Brace Expansion
44 *      Tilde Expansion
45 *      fancy forms of Parameter Expansion
46 *      aliases
47 *      Arithmetic Expansion
48 *      <(list) and >(list) Process Substitution
49 *      reserved words: case, esac, select, function
50 *      Here Documents ( << word )
51 *      Functions
52 * Major bugs:
53 *      job handling woefully incomplete and buggy (improved --vda)
54 *      reserved word execution woefully incomplete and buggy
55 * to-do:
56 *      port selected bugfixes from post-0.49 busybox lash - done?
57 *      finish implementing reserved words: for, while, until, do, done
58 *      change { and } from special chars to reserved words
59 *      builtins: break, continue, eval, return, set, trap, ulimit
60 *      test magic exec
61 *      handle children going into background
62 *      clean up recognition of null pipes
63 *      check setting of global_argc and global_argv
64 *      control-C handling, probably with longjmp
65 *      follow IFS rules more precisely, including update semantics
66 *      figure out what to do with backslash-newline
67 *      explain why we use signal instead of sigaction
68 *      propagate syntax errors, die on resource errors?
69 *      continuation lines, both explicit and implicit - done?
70 *      memory leak finding and plugging - done?
71 *      more testing, especially quoting rules and redirection
72 *      document how quoting rules not precisely followed for variable assignments
73 *      maybe change charmap[] to use 2-bit entries
74 *      (eventually) remove all the printf's
75 *
76 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
77 */
78
79
80#include <glob.h>      /* glob, of course */
81#include <getopt.h>    /* should be pretty obvious */
82/* #include <dmalloc.h> */
83
84extern char **environ; /* This is in <unistd.h>, but protected with __USE_GNU */
85
86#include "busybox.h" /* for struct bb_applet */
87
88
89/* If you comment out one of these below, it will be #defined later
90 * to perform debug printfs to stderr: */
91#define debug_printf(...)        do {} while (0)
92/* Finer-grained debug switches */
93#define debug_printf_parse(...)  do {} while (0)
94#define debug_print_tree(a, b)   do {} while (0)
95#define debug_printf_exec(...)   do {} while (0)
96#define debug_printf_jobs(...)   do {} while (0)
97#define debug_printf_expand(...) do {} while (0)
98#define debug_printf_clean(...)  do {} while (0)
99
100#ifndef debug_printf
101#define debug_printf(...) fprintf(stderr, __VA_ARGS__)
102#endif
103
104#ifndef debug_printf_parse
105#define debug_printf_parse(...) fprintf(stderr, __VA_ARGS__)
106#endif
107
108#ifndef debug_printf_exec
109#define debug_printf_exec(...) fprintf(stderr, __VA_ARGS__)
110#endif
111
112#ifndef debug_printf_jobs
113#define debug_printf_jobs(...) fprintf(stderr, __VA_ARGS__)
114#define DEBUG_SHELL_JOBS 1
115#endif
116
117#ifndef debug_printf_expand
118#define debug_printf_expand(...) fprintf(stderr, __VA_ARGS__)
119#define DEBUG_EXPAND 1
120#endif
121
122/* Keep unconditionally on for now */
123#define ENABLE_HUSH_DEBUG 1
124
125#ifndef debug_printf_clean
126/* broken, of course, but OK for testing */
127static const char *indenter(int i)
128{
129	static const char blanks[] ALIGN1 =
130		"                                    ";
131	return &blanks[sizeof(blanks) - i - 1];
132}
133#define debug_printf_clean(...) fprintf(stderr, __VA_ARGS__)
134#define DEBUG_CLEAN 1
135#endif
136
137
138#if !ENABLE_HUSH_INTERACTIVE
139#undef ENABLE_FEATURE_EDITING
140#define ENABLE_FEATURE_EDITING 0
141#undef ENABLE_FEATURE_EDITING_FANCY_PROMPT
142#define ENABLE_FEATURE_EDITING_FANCY_PROMPT 0
143#endif
144
145#define SPECIAL_VAR_SYMBOL   3
146
147#define PARSEFLAG_EXIT_FROM_LOOP 1
148#define PARSEFLAG_SEMICOLON      (1 << 1)  /* symbol ';' is special for parser */
149#define PARSEFLAG_REPARSING      (1 << 2)  /* >= 2nd pass */
150
151typedef enum {
152	REDIRECT_INPUT     = 1,
153	REDIRECT_OVERWRITE = 2,
154	REDIRECT_APPEND    = 3,
155	REDIRECT_HEREIS    = 4,
156	REDIRECT_IO        = 5
157} redir_type;
158
159/* The descrip member of this structure is only used to make debugging
160 * output pretty */
161static const struct {
162	int mode;
163	signed char default_fd;
164	char descrip[3];
165} redir_table[] = {
166	{ 0,                         0, "()" },
167	{ O_RDONLY,                  0, "<"  },
168	{ O_CREAT|O_TRUNC|O_WRONLY,  1, ">"  },
169	{ O_CREAT|O_APPEND|O_WRONLY, 1, ">>" },
170	{ O_RDONLY,                 -1, "<<" },
171	{ O_RDWR,                    1, "<>" }
172};
173
174typedef enum {
175	PIPE_SEQ = 1,
176	PIPE_AND = 2,
177	PIPE_OR  = 3,
178	PIPE_BG  = 4,
179} pipe_style;
180
181/* might eventually control execution */
182typedef enum {
183	RES_NONE  = 0,
184#if ENABLE_HUSH_IF
185	RES_IF    = 1,
186	RES_THEN  = 2,
187	RES_ELIF  = 3,
188	RES_ELSE  = 4,
189	RES_FI    = 5,
190#endif
191#if ENABLE_HUSH_LOOPS
192	RES_FOR   = 6,
193	RES_WHILE = 7,
194	RES_UNTIL = 8,
195	RES_DO    = 9,
196	RES_DONE  = 10,
197	RES_IN    = 11,
198#endif
199	RES_XXXX  = 12,
200	RES_SNTX  = 13
201} reserved_style;
202enum {
203	FLAG_END   = (1 << RES_NONE ),
204#if ENABLE_HUSH_IF
205	FLAG_IF    = (1 << RES_IF   ),
206	FLAG_THEN  = (1 << RES_THEN ),
207	FLAG_ELIF  = (1 << RES_ELIF ),
208	FLAG_ELSE  = (1 << RES_ELSE ),
209	FLAG_FI    = (1 << RES_FI   ),
210#endif
211#if ENABLE_HUSH_LOOPS
212	FLAG_FOR   = (1 << RES_FOR  ),
213	FLAG_WHILE = (1 << RES_WHILE),
214	FLAG_UNTIL = (1 << RES_UNTIL),
215	FLAG_DO    = (1 << RES_DO   ),
216	FLAG_DONE  = (1 << RES_DONE ),
217	FLAG_IN    = (1 << RES_IN   ),
218#endif
219	FLAG_START = (1 << RES_XXXX ),
220};
221
222/* This holds pointers to the various results of parsing */
223struct p_context {
224	struct child_prog *child;
225	struct pipe *list_head;
226	struct pipe *pipe;
227	struct redir_struct *pending_redirect;
228	smallint res_w;
229	smallint parse_type;        /* bitmask of PARSEFLAG_xxx, defines type of parser : ";$" common or special symbol */
230	int old_flag;               /* bitmask of FLAG_xxx, for figuring out valid reserved words */
231	struct p_context *stack;
232	/* How about quoting status? */
233};
234
235struct redir_struct {
236	struct redir_struct *next;  /* pointer to the next redirect in the list */
237	redir_type type;            /* type of redirection */
238	int fd;                     /* file descriptor being redirected */
239	int dup;                    /* -1, or file descriptor being duplicated */
240	glob_t word;                /* *word.gl_pathv is the filename */
241};
242
243struct child_prog {
244	pid_t pid;                  /* 0 if exited */
245	char **argv;                /* program name and arguments */
246	struct pipe *group;         /* if non-NULL, first in group or subshell */
247	smallint subshell;          /* flag, non-zero if group must be forked */
248	smallint is_stopped;        /* is the program currently running? */
249	struct redir_struct *redirects; /* I/O redirections */
250	glob_t glob_result;         /* result of parameter globbing */
251	struct pipe *family;        /* pointer back to the child's parent pipe */
252	//sp counting seems to be broken... so commented out, grep for '//sp:'
253	//sp: int sp;               /* number of SPECIAL_VAR_SYMBOL */
254	//seems to be unused, grep for '//pt:'
255	//pt: int parse_type;
256};
257/* argv vector may contain variable references (^Cvar^C, ^C0^C etc)
258 * and on execution these are substituted with their values.
259 * Substitution can make _several_ words out of one argv[n]!
260 * Example: argv[0]=='.^C*^C.' here: echo .$*.
261 */
262
263struct pipe {
264	struct pipe *next;
265	int num_progs;              /* total number of programs in job */
266	int running_progs;          /* number of programs running (not exited) */
267	int stopped_progs;          /* number of programs alive, but stopped */
268#if ENABLE_HUSH_JOB
269	int jobid;                  /* job number */
270	pid_t pgrp;                 /* process group ID for the job */
271	char *cmdtext;              /* name of job */
272#endif
273	char *cmdbuf;               /* buffer various argv's point into */
274	struct child_prog *progs;   /* array of commands in pipe */
275	int job_context;            /* bitmask defining current context */
276	smallint followup;          /* PIPE_BG, PIPE_SEQ, PIPE_OR, PIPE_AND */
277	smallint res_word;          /* needed for if, for, while, until... */
278};
279
280struct close_me {
281	struct close_me *next;
282	int fd;
283};
284
285/* On program start, environ points to initial environment.
286 * putenv adds new pointers into it, unsetenv removes them.
287 * Neither of these (de)allocates the strings.
288 * setenv allocates new strings in malloc space and does putenv,
289 * and thus setenv is unusable (leaky) for shell's purposes */
290#define setenv(...) setenv_is_leaky_dont_use()
291struct variable {
292	struct variable *next;
293	char *varstr;        /* points to "name=" portion */
294	int max_len;         /* if > 0, name is part of initial env; else name is malloced */
295	smallint flg_export; /* putenv should be done on this var */
296	smallint flg_read_only;
297};
298
299typedef struct {
300	char *data;
301	int length;
302	int maxlen;
303	int quote;
304	int nonnull;
305} o_string;
306#define NULL_O_STRING {NULL,0,0,0,0}
307/* used for initialization: o_string foo = NULL_O_STRING; */
308
309/* I can almost use ordinary FILE *.  Is open_memstream() universally
310 * available?  Where is it documented? */
311struct in_str {
312	const char *p;
313	/* eof_flag=1: last char in ->p is really an EOF */
314	char eof_flag; /* meaningless if ->p == NULL */
315	char peek_buf[2];
316#if ENABLE_HUSH_INTERACTIVE
317	smallint promptme;
318	smallint promptmode; /* 0: PS1, 1: PS2 */
319#endif
320	FILE *file;
321	int (*get) (struct in_str *);
322	int (*peek) (struct in_str *);
323};
324#define b_getch(input) ((input)->get(input))
325#define b_peek(input) ((input)->peek(input))
326
327enum {
328	CHAR_ORDINARY           = 0,
329	CHAR_ORDINARY_IF_QUOTED = 1, /* example: *, # */
330	CHAR_IFS                = 2, /* treated as ordinary if quoted */
331	CHAR_SPECIAL            = 3, /* example: $ */
332};
333
334#define HUSH_VER_STR "0.02"
335
336/* "Globals" within this file */
337
338/* Sorted roughly by size (smaller offsets == smaller code) */
339struct globals {
340#if ENABLE_HUSH_INTERACTIVE
341	/* 'interactive_fd' is a fd# open to ctty, if we have one
342	 * _AND_ if we decided to act interactively */
343	int interactive_fd;
344	const char *PS1;
345	const char *PS2;
346#endif
347#if ENABLE_FEATURE_EDITING
348	line_input_t *line_input_state;
349#endif
350#if ENABLE_HUSH_JOB
351	int run_list_level;
352	pid_t saved_task_pgrp;
353	pid_t saved_tty_pgrp;
354	int last_jobid;
355	struct pipe *job_list;
356	struct pipe *toplevel_list;
357	smallint ctrl_z_flag;
358#endif
359	smallint fake_mode;
360	/* these three support $?, $#, and $1 */
361	char **global_argv;
362	int global_argc;
363	int last_return_code;
364	const char *ifs;
365	struct close_me *close_me_head;
366	const char *cwd;
367	unsigned last_bg_pid;
368	struct variable *top_var; /* = &shell_ver (set in main()) */
369	struct variable shell_ver;
370#if ENABLE_FEATURE_SH_STANDALONE
371	struct nofork_save_area nofork_save;
372#endif
373#if ENABLE_HUSH_JOB
374	sigjmp_buf toplevel_jb;
375#endif
376	unsigned char charmap[256];
377	char user_input_buf[ENABLE_FEATURE_EDITING ? BUFSIZ : 2];
378};
379
380#define G (*ptr_to_globals)
381
382#if !ENABLE_HUSH_INTERACTIVE
383enum { interactive_fd = 0 };
384#endif
385#if !ENABLE_HUSH_JOB
386enum { run_list_level = 0 };
387#endif
388
389#if ENABLE_HUSH_INTERACTIVE
390#define interactive_fd   (G.interactive_fd  )
391#define PS1              (G.PS1             )
392#define PS2              (G.PS2             )
393#endif
394#if ENABLE_FEATURE_EDITING
395#define line_input_state (G.line_input_state)
396#endif
397#if ENABLE_HUSH_JOB
398#define run_list_level   (G.run_list_level  )
399#define saved_task_pgrp  (G.saved_task_pgrp )
400#define saved_tty_pgrp   (G.saved_tty_pgrp  )
401#define last_jobid       (G.last_jobid      )
402#define job_list         (G.job_list        )
403#define toplevel_list    (G.toplevel_list   )
404#define toplevel_jb      (G.toplevel_jb     )
405#define ctrl_z_flag      (G.ctrl_z_flag     )
406#endif /* JOB */
407#define global_argv      (G.global_argv     )
408#define global_argc      (G.global_argc     )
409#define last_return_code (G.last_return_code)
410#define ifs              (G.ifs             )
411#define fake_mode        (G.fake_mode       )
412#define close_me_head    (G.close_me_head   )
413#define cwd              (G.cwd             )
414#define last_bg_pid      (G.last_bg_pid     )
415#define top_var          (G.top_var         )
416#define shell_ver        (G.shell_ver       )
417#if ENABLE_FEATURE_SH_STANDALONE
418#define nofork_save      (G.nofork_save     )
419#endif
420#if ENABLE_HUSH_JOB
421#define toplevel_jb      (G.toplevel_jb     )
422#endif
423#define charmap          (G.charmap         )
424#define user_input_buf   (G.user_input_buf  )
425
426
427#define B_CHUNK  100
428#define B_NOSPAC 1
429#define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
430
431/* Normal */
432static void syntax(const char *msg)
433{
434	/* Was using fancy stuff:
435	 * (interactive_fd ? bb_error_msg : bb_error_msg_and_die)(...params...)
436	 * but it SEGVs. ?! Oh well... explicit temp ptr works around that */
437	void (*fp)(const char *s, ...);
438
439	fp = (interactive_fd ? bb_error_msg : bb_error_msg_and_die);
440	fp(msg ? "%s: %s" : "syntax error", "syntax error", msg);
441}
442
443
444/* Index of subroutines: */
445/*   function prototypes for builtins */
446static int builtin_cd(char **argv);
447static int builtin_eval(char **argv);
448static int builtin_exec(char **argv);
449static int builtin_exit(char **argv);
450static int builtin_export(char **argv);
451#if ENABLE_HUSH_JOB
452static int builtin_fg_bg(char **argv);
453static int builtin_jobs(char **argv);
454#endif
455#if ENABLE_HUSH_HELP
456static int builtin_help(char **argv);
457#endif
458static int builtin_pwd(char **argv);
459static int builtin_read(char **argv);
460static int builtin_set(char **argv);
461static int builtin_shift(char **argv);
462static int builtin_source(char **argv);
463static int builtin_umask(char **argv);
464static int builtin_unset(char **argv);
465//static int builtin_not_written(char **argv);
466/*   o_string manipulation: */
467static int b_check_space(o_string *o, int len);
468static int b_addchr(o_string *o, int ch);
469static void b_reset(o_string *o);
470static int b_addqchr(o_string *o, int ch, int quote);
471/*  in_str manipulations: */
472static int static_get(struct in_str *i);
473static int static_peek(struct in_str *i);
474static int file_get(struct in_str *i);
475static int file_peek(struct in_str *i);
476static void setup_file_in_str(struct in_str *i, FILE *f);
477static void setup_string_in_str(struct in_str *i, const char *s);
478/*  close_me manipulations: */
479static void mark_open(int fd);
480static void mark_closed(int fd);
481static void close_all(void);
482/*  "run" the final data structures: */
483#if !defined(DEBUG_CLEAN)
484#define free_pipe_list(head, indent) free_pipe_list(head)
485#define free_pipe(pi, indent)        free_pipe(pi)
486#endif
487static int free_pipe_list(struct pipe *head, int indent);
488static int free_pipe(struct pipe *pi, int indent);
489/*  really run the final data structures: */
490static int setup_redirects(struct child_prog *prog, int squirrel[]);
491static int run_list_real(struct pipe *pi);
492static void pseudo_exec_argv(char **argv) ATTRIBUTE_NORETURN;
493static void pseudo_exec(struct child_prog *child) ATTRIBUTE_NORETURN;
494static int run_pipe_real(struct pipe *pi);
495/*   extended glob support: */
496static int globhack(const char *src, int flags, glob_t *pglob);
497static int glob_needed(const char *s);
498static int xglob(o_string *dest, int flags, glob_t *pglob);
499/*   variable assignment: */
500static int is_assignment(const char *s);
501/*   data structure manipulation: */
502static int setup_redirect(struct p_context *ctx, int fd, redir_type style, struct in_str *input);
503static void initialize_context(struct p_context *ctx);
504static int done_word(o_string *dest, struct p_context *ctx);
505static int done_command(struct p_context *ctx);
506static int done_pipe(struct p_context *ctx, pipe_style type);
507/*   primary string parsing: */
508static int redirect_dup_num(struct in_str *input);
509static int redirect_opt_num(o_string *o);
510#if ENABLE_HUSH_TICK
511static int process_command_subs(o_string *dest, struct p_context *ctx, struct in_str *input, const char *subst_end);
512#endif
513static int parse_group(o_string *dest, struct p_context *ctx, struct in_str *input, int ch);
514static const char *lookup_param(const char *src);
515static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *input);
516static int parse_stream(o_string *dest, struct p_context *ctx, struct in_str *input0, const char *end_trigger);
517/*   setup: */
518static int parse_and_run_stream(struct in_str *inp, int parse_flag);
519static int parse_and_run_string(const char *s, int parse_flag);
520static int parse_and_run_file(FILE *f);
521/*   job management: */
522static int checkjobs(struct pipe* fg_pipe);
523#if ENABLE_HUSH_JOB
524static int checkjobs_and_fg_shell(struct pipe* fg_pipe);
525static void insert_bg_job(struct pipe *pi);
526static void remove_bg_job(struct pipe *pi);
527static void delete_finished_bg_job(struct pipe *pi);
528#else
529int checkjobs_and_fg_shell(struct pipe* fg_pipe); /* never called */
530#endif
531/*     local variable support */
532static char **expand_strvec_to_strvec(char **argv);
533/* used for eval */
534static char *expand_strvec_to_string(char **argv);
535/* used for expansion of right hand of assignments */
536static char *expand_string_to_string(const char *str);
537static struct variable *get_local_var(const char *name);
538static int set_local_var(char *str, int flg_export);
539static void unset_local_var(const char *name);
540
541/* Table of built-in functions.  They can be forked or not, depending on
542 * context: within pipes, they fork.  As simple commands, they do not.
543 * When used in non-forking context, they can change global variables
544 * in the parent shell process.  If forked, of course they cannot.
545 * For example, 'unset foo | whatever' will parse and run, but foo will
546 * still be set at the end. */
547struct built_in_command {
548	const char *cmd;                /* name */
549	int (*function) (char **argv);  /* function ptr */
550#if ENABLE_HUSH_HELP
551	const char *descr;              /* description */
552#define BLTIN(cmd, func, help) { cmd, func, help }
553#else
554#define BLTIN(cmd, func, help) { cmd, func }
555#endif
556};
557
558static const struct built_in_command bltins[] = {
559#if ENABLE_HUSH_JOB
560	BLTIN("bg"    , builtin_fg_bg, "Resume a job in the background"),
561#endif
562//	BLTIN("break" , builtin_not_written, "Exit for, while or until loop"),
563	BLTIN("cd"    , builtin_cd, "Change working directory"),
564//	BLTIN("continue", builtin_not_written, "Continue for, while or until loop"),
565	BLTIN("eval"  , builtin_eval, "Construct and run shell command"),
566	BLTIN("exec"  , builtin_exec, "Exec command, replacing this shell with the exec'd process"),
567	BLTIN("exit"  , builtin_exit, "Exit from shell"),
568	BLTIN("export", builtin_export, "Set environment variable"),
569#if ENABLE_HUSH_JOB
570	BLTIN("fg"    , builtin_fg_bg, "Bring job into the foreground"),
571	BLTIN("jobs"  , builtin_jobs, "Lists the active jobs"),
572#endif
573// TODO: remove pwd? we have it as an applet...
574	BLTIN("pwd"   , builtin_pwd, "Print current directory"),
575	BLTIN("read"  , builtin_read, "Input environment variable"),
576//	BLTIN("return", builtin_not_written, "Return from a function"),
577	BLTIN("set"   , builtin_set, "Set/unset shell local variables"),
578	BLTIN("shift" , builtin_shift, "Shift positional parameters"),
579//	BLTIN("trap"  , builtin_not_written, "Trap signals"),
580//	BLTIN("ulimit", builtin_not_written, "Controls resource limits"),
581	BLTIN("umask" , builtin_umask, "Sets file creation mask"),
582	BLTIN("unset" , builtin_unset, "Unset environment variable"),
583	BLTIN("."     , builtin_source, "Source-in and run commands in a file"),
584#if ENABLE_HUSH_HELP
585	BLTIN("help"  , builtin_help, "List shell built-in commands"),
586#endif
587	BLTIN(NULL, NULL, NULL)
588};
589
590#if ENABLE_HUSH_JOB
591
592/* move to libbb? */
593static void signal_SA_RESTART(int sig, void (*handler)(int))
594{
595	struct sigaction sa;
596	sa.sa_handler = handler;
597	sa.sa_flags = SA_RESTART;
598	sigemptyset(&sa.sa_mask);
599	sigaction(sig, &sa, NULL);
600}
601
602/* Signals are grouped, we handle them in batches */
603static void set_fatal_sighandler(void (*handler)(int))
604{
605	signal(SIGILL , handler);
606	signal(SIGTRAP, handler);
607	signal(SIGABRT, handler);
608	signal(SIGFPE , handler);
609	signal(SIGBUS , handler);
610	signal(SIGSEGV, handler);
611	/* bash 3.2 seems to handle these just like 'fatal' ones */
612	signal(SIGHUP , handler);
613	signal(SIGPIPE, handler);
614	signal(SIGALRM, handler);
615}
616static void set_jobctrl_sighandler(void (*handler)(int))
617{
618	signal(SIGTSTP, handler);
619	signal(SIGTTIN, handler);
620	signal(SIGTTOU, handler);
621}
622static void set_misc_sighandler(void (*handler)(int))
623{
624	signal(SIGINT , handler);
625	signal(SIGQUIT, handler);
626	signal(SIGTERM, handler);
627}
628/* SIGCHLD is special and handled separately */
629
630static void set_every_sighandler(void (*handler)(int))
631{
632	set_fatal_sighandler(handler);
633	set_jobctrl_sighandler(handler);
634	set_misc_sighandler(handler);
635	signal(SIGCHLD, handler);
636}
637
638static void handler_ctrl_c(int sig)
639{
640	debug_printf_jobs("got sig %d\n", sig);
641// as usual we can have all kinds of nasty problems with leaked malloc data here
642	siglongjmp(toplevel_jb, 1);
643}
644
645static void handler_ctrl_z(int sig)
646{
647	pid_t pid;
648
649	debug_printf_jobs("got tty sig %d in pid %d\n", sig, getpid());
650	pid = fork();
651	if (pid < 0) /* can't fork. Pretend there was no ctrl-Z */
652		return;
653	ctrl_z_flag = 1;
654	if (!pid) { /* child */
655		setpgrp();
656		debug_printf_jobs("set pgrp for child %d ok\n", getpid());
657		set_every_sighandler(SIG_DFL);
658		raise(SIGTSTP); /* resend TSTP so that child will be stopped */
659		debug_printf_jobs("returning in child\n");
660		/* return to nofork, it will eventually exit now,
661		 * not return back to shell */
662		return;
663	}
664	/* parent */
665	/* finish filling up pipe info */
666	toplevel_list->pgrp = pid; /* child is in its own pgrp */
667	toplevel_list->progs[0].pid = pid;
668	/* parent needs to longjmp out of running nofork.
669	 * we will "return" exitcode 0, with child put in background */
670// as usual we can have all kinds of nasty problems with leaked malloc data here
671	debug_printf_jobs("siglongjmp in parent\n");
672	siglongjmp(toplevel_jb, 1);
673}
674
675/* Restores tty foreground process group, and exits.
676 * May be called as signal handler for fatal signal
677 * (will faithfully resend signal to itself, producing correct exit state)
678 * or called directly with -EXITCODE.
679 * We also call it if xfunc is exiting. */
680static void sigexit(int sig) ATTRIBUTE_NORETURN;
681static void sigexit(int sig)
682{
683	sigset_t block_all;
684
685	/* Disable all signals: job control, SIGPIPE, etc. */
686	sigfillset(&block_all);
687	sigprocmask(SIG_SETMASK, &block_all, NULL);
688
689	if (interactive_fd)
690		tcsetpgrp(interactive_fd, saved_tty_pgrp);
691
692	/* Not a signal, just exit */
693	if (sig <= 0)
694		_exit(- sig);
695
696	/* Enable only this sig and kill ourself with it */
697	signal(sig, SIG_DFL);
698	sigdelset(&block_all, sig);
699	sigprocmask(SIG_SETMASK, &block_all, NULL);
700	raise(sig);
701	_exit(1); /* Should not reach it */
702}
703
704/* Restores tty foreground process group, and exits. */
705static void hush_exit(int exitcode) ATTRIBUTE_NORETURN;
706static void hush_exit(int exitcode)
707{
708	fflush(NULL); /* flush all streams */
709	sigexit(- (exitcode & 0xff));
710}
711
712#else /* !JOB */
713
714#define set_fatal_sighandler(handler)   ((void)0)
715#define set_jobctrl_sighandler(handler) ((void)0)
716#define set_misc_sighandler(handler)    ((void)0)
717#define hush_exit(e)                    exit(e)
718
719#endif /* JOB */
720
721
722static const char *set_cwd(void)
723{
724	if (cwd == bb_msg_unknown)
725		cwd = NULL;     /* xrealloc_getcwd_or_warn(arg) calls free(arg)! */
726	cwd = xrealloc_getcwd_or_warn((char *)cwd);
727	if (!cwd)
728		cwd = bb_msg_unknown;
729	return cwd;
730}
731
732/* built-in 'eval' handler */
733static int builtin_eval(char **argv)
734{
735	int rcode = EXIT_SUCCESS;
736
737	if (argv[1]) {
738		char *str = expand_strvec_to_string(argv + 1);
739		parse_and_run_string(str, PARSEFLAG_EXIT_FROM_LOOP |
740					PARSEFLAG_SEMICOLON);
741		free(str);
742		rcode = last_return_code;
743	}
744	return rcode;
745}
746
747/* built-in 'cd <path>' handler */
748static int builtin_cd(char **argv)
749{
750	const char *newdir;
751	if (argv[1] == NULL)
752		newdir = getenv("HOME") ? : "/";
753	else
754		newdir = argv[1];
755	if (chdir(newdir)) {
756		printf("cd: %s: %s\n", newdir, strerror(errno));
757		return EXIT_FAILURE;
758	}
759	set_cwd();
760	return EXIT_SUCCESS;
761}
762
763/* built-in 'exec' handler */
764static int builtin_exec(char **argv)
765{
766	if (argv[1] == NULL)
767		return EXIT_SUCCESS;   /* Really? */
768	pseudo_exec_argv(argv + 1);
769	/* never returns */
770}
771
772/* built-in 'exit' handler */
773static int builtin_exit(char **argv)
774{
775// TODO: bash does it ONLY on top-level sh exit (+interacive only?)
776	//puts("exit"); /* bash does it */
777// TODO: warn if we have background jobs: "There are stopped jobs"
778// On second consecutive 'exit', exit anyway.
779
780	if (argv[1] == NULL)
781		hush_exit(last_return_code);
782	/* mimic bash: exit 123abc == exit 255 + error msg */
783	xfunc_error_retval = 255;
784	/* bash: exit -2 == exit 254, no error msg */
785	hush_exit(xatoi(argv[1]) & 0xff);
786}
787
788/* built-in 'export VAR=value' handler */
789static int builtin_export(char **argv)
790{
791	const char *value;
792	char *name = argv[1];
793
794	if (name == NULL) {
795		// TODO:
796		// ash emits: export VAR='VAL'
797		// bash: declare -x VAR="VAL"
798		// (both also escape as needed (quotes, $, etc))
799		char **e = environ;
800		if (e)
801			while (*e)
802				puts(*e++);
803		return EXIT_SUCCESS;
804	}
805
806	value = strchr(name, '=');
807	if (!value) {
808		/* They are exporting something without a =VALUE */
809		struct variable *var;
810
811		var = get_local_var(name);
812		if (var) {
813			var->flg_export = 1;
814			putenv(var->varstr);
815		}
816		/* bash does not return an error when trying to export
817		 * an undefined variable.  Do likewise. */
818		return EXIT_SUCCESS;
819	}
820
821	set_local_var(xstrdup(name), 1);
822	return EXIT_SUCCESS;
823}
824
825#if ENABLE_HUSH_JOB
826/* built-in 'fg' and 'bg' handler */
827static int builtin_fg_bg(char **argv)
828{
829	int i, jobnum;
830	struct pipe *pi;
831
832	if (!interactive_fd)
833		return EXIT_FAILURE;
834	/* If they gave us no args, assume they want the last backgrounded task */
835	if (!argv[1]) {
836		for (pi = job_list; pi; pi = pi->next) {
837			if (pi->jobid == last_jobid) {
838				goto found;
839			}
840		}
841		bb_error_msg("%s: no current job", argv[0]);
842		return EXIT_FAILURE;
843	}
844	if (sscanf(argv[1], "%%%d", &jobnum) != 1) {
845		bb_error_msg("%s: bad argument '%s'", argv[0], argv[1]);
846		return EXIT_FAILURE;
847	}
848	for (pi = job_list; pi; pi = pi->next) {
849		if (pi->jobid == jobnum) {
850			goto found;
851		}
852	}
853	bb_error_msg("%s: %d: no such job", argv[0], jobnum);
854	return EXIT_FAILURE;
855 found:
856	// TODO: bash prints a string representation
857	// of job being foregrounded (like "sleep 1 | cat")
858	if (*argv[0] == 'f') {
859		/* Put the job into the foreground.  */
860		tcsetpgrp(interactive_fd, pi->pgrp);
861	}
862
863	/* Restart the processes in the job */
864	debug_printf_jobs("reviving %d procs, pgrp %d\n", pi->num_progs, pi->pgrp);
865	for (i = 0; i < pi->num_progs; i++) {
866		debug_printf_jobs("reviving pid %d\n", pi->progs[i].pid);
867		pi->progs[i].is_stopped = 0;
868	}
869	pi->stopped_progs = 0;
870
871	i = kill(- pi->pgrp, SIGCONT);
872	if (i < 0) {
873		if (errno == ESRCH) {
874			delete_finished_bg_job(pi);
875			return EXIT_SUCCESS;
876		} else {
877			bb_perror_msg("kill (SIGCONT)");
878		}
879	}
880
881	if (*argv[0] == 'f') {
882		remove_bg_job(pi);
883		return checkjobs_and_fg_shell(pi);
884	}
885	return EXIT_SUCCESS;
886}
887#endif
888
889/* built-in 'help' handler */
890#if ENABLE_HUSH_HELP
891static int builtin_help(char **argv ATTRIBUTE_UNUSED)
892{
893	const struct built_in_command *x;
894
895	printf("\nBuilt-in commands:\n");
896	printf("-------------------\n");
897	for (x = bltins; x->cmd; x++) {
898		printf("%s\t%s\n", x->cmd, x->descr);
899	}
900	printf("\n\n");
901	return EXIT_SUCCESS;
902}
903#endif
904
905#if ENABLE_HUSH_JOB
906/* built-in 'jobs' handler */
907static int builtin_jobs(char **argv ATTRIBUTE_UNUSED)
908{
909	struct pipe *job;
910	const char *status_string;
911
912	for (job = job_list; job; job = job->next) {
913		if (job->running_progs == job->stopped_progs)
914			status_string = "Stopped";
915		else
916			status_string = "Running";
917
918		printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->cmdtext);
919	}
920	return EXIT_SUCCESS;
921}
922#endif
923
924/* built-in 'pwd' handler */
925static int builtin_pwd(char **argv ATTRIBUTE_UNUSED)
926{
927	puts(set_cwd());
928	return EXIT_SUCCESS;
929}
930
931/* built-in 'read VAR' handler */
932static int builtin_read(char **argv)
933{
934	char *string;
935	const char *name = argv[1] ? argv[1] : "REPLY";
936
937	string = xmalloc_reads(STDIN_FILENO, xasprintf("%s=", name));
938	return set_local_var(string, 0);
939}
940
941/* built-in 'set [VAR=value]' handler */
942static int builtin_set(char **argv)
943{
944	char *temp = argv[1];
945	struct variable *e;
946
947	if (temp == NULL)
948		for (e = top_var; e; e = e->next)
949			puts(e->varstr);
950	else
951		set_local_var(xstrdup(temp), 0);
952
953	return EXIT_SUCCESS;
954}
955
956
957/* Built-in 'shift' handler */
958static int builtin_shift(char **argv)
959{
960	int n = 1;
961	if (argv[1]) {
962		n = atoi(argv[1]);
963	}
964	if (n >= 0 && n < global_argc) {
965		global_argv[n] = global_argv[0];
966		global_argc -= n;
967		global_argv += n;
968		return EXIT_SUCCESS;
969	}
970	return EXIT_FAILURE;
971}
972
973/* Built-in '.' handler (read-in and execute commands from file) */
974static int builtin_source(char **argv)
975{
976	FILE *input;
977	int status;
978
979	if (argv[1] == NULL)
980		return EXIT_FAILURE;
981
982	input = fopen(argv[1], "r");
983	if (!input) {
984		bb_error_msg("cannot open '%s'", argv[1]);
985		return EXIT_FAILURE;
986	}
987
988	/* Now run the file */
989	mark_open(fileno(input));
990	status = parse_and_run_file(input);
991	mark_closed(fileno(input));
992	fclose(input);
993	return status;
994}
995
996static int builtin_umask(char **argv)
997{
998	mode_t new_umask;
999	const char *arg = argv[1];
1000	char *end;
1001	if (arg) {
1002		new_umask = strtoul(arg, &end, 8);
1003		if (*end != '\0' || end == arg) {
1004			return EXIT_FAILURE;
1005		}
1006	} else {
1007		new_umask = umask(0);
1008		printf("%.3o\n", (unsigned) new_umask);
1009	}
1010	umask(new_umask);
1011	return EXIT_SUCCESS;
1012}
1013
1014/* built-in 'unset VAR' handler */
1015static int builtin_unset(char **argv)
1016{
1017	/* bash always returns true */
1018	unset_local_var(argv[1]);
1019	return EXIT_SUCCESS;
1020}
1021
1022//static int builtin_not_written(char **argv)
1023//{
1024//	printf("builtin_%s not written\n", argv[0]);
1025//	return EXIT_FAILURE;
1026//}
1027
1028static int b_check_space(o_string *o, int len)
1029{
1030	/* It would be easy to drop a more restrictive policy
1031	 * in here, such as setting a maximum string length */
1032	if (o->length + len > o->maxlen) {
1033		/* assert(data == NULL || o->maxlen != 0); */
1034		o->maxlen += (2*len > B_CHUNK ? 2*len : B_CHUNK);
1035		o->data = xrealloc(o->data, 1 + o->maxlen);
1036	}
1037	return o->data == NULL;
1038}
1039
1040static int b_addchr(o_string *o, int ch)
1041{
1042	debug_printf("b_addchr: '%c' o->length=%d o=%p\n", ch, o->length, o);
1043	if (b_check_space(o, 1))
1044		return B_NOSPAC;
1045	o->data[o->length] = ch;
1046	o->length++;
1047	o->data[o->length] = '\0';
1048	return 0;
1049}
1050
1051static void b_reset(o_string *o)
1052{
1053	o->length = 0;
1054	o->nonnull = 0;
1055	if (o->data != NULL)
1056		*o->data = '\0';
1057}
1058
1059static void b_free(o_string *o)
1060{
1061	b_reset(o);
1062	free(o->data);
1063	o->data = NULL;
1064	o->maxlen = 0;
1065}
1066
1067/* My analysis of quoting semantics tells me that state information
1068 * is associated with a destination, not a source.
1069 */
1070static int b_addqchr(o_string *o, int ch, int quote)
1071{
1072	if (quote && strchr("*?[\\", ch)) {
1073		int rc;
1074		rc = b_addchr(o, '\\');
1075		if (rc)
1076			return rc;
1077	}
1078	return b_addchr(o, ch);
1079}
1080
1081static int static_get(struct in_str *i)
1082{
1083	int ch = *i->p++;
1084	if (ch == '\0') return EOF;
1085	return ch;
1086}
1087
1088static int static_peek(struct in_str *i)
1089{
1090	return *i->p;
1091}
1092
1093#if ENABLE_HUSH_INTERACTIVE
1094#if ENABLE_FEATURE_EDITING
1095static void cmdedit_set_initial_prompt(void)
1096{
1097#if !ENABLE_FEATURE_EDITING_FANCY_PROMPT
1098	PS1 = NULL;
1099#else
1100	PS1 = getenv("PS1");
1101	if (PS1 == NULL)
1102		PS1 = "\\w \\$ ";
1103#endif
1104}
1105#endif /* EDITING */
1106
1107static const char* setup_prompt_string(int promptmode)
1108{
1109	const char *prompt_str;
1110	debug_printf("setup_prompt_string %d ", promptmode);
1111#if !ENABLE_FEATURE_EDITING_FANCY_PROMPT
1112	/* Set up the prompt */
1113	if (promptmode == 0) { /* PS1 */
1114		free((char*)PS1);
1115		PS1 = xasprintf("%s %c ", cwd, (geteuid() != 0) ? '$' : '#');
1116		prompt_str = PS1;
1117	} else {
1118		prompt_str = PS2;
1119	}
1120#else
1121	prompt_str = (promptmode == 0) ? PS1 : PS2;
1122#endif
1123	debug_printf("result '%s'\n", prompt_str);
1124	return prompt_str;
1125}
1126
1127static void get_user_input(struct in_str *i)
1128{
1129	int r;
1130	const char *prompt_str;
1131
1132	prompt_str = setup_prompt_string(i->promptmode);
1133#if ENABLE_FEATURE_EDITING
1134	/* Enable command line editing only while a command line
1135	 * is actually being read; otherwise, we'll end up bequeathing
1136	 * atexit() handlers and other unwanted stuff to our
1137	 * child processes (rob@sysgo.de) */
1138	r = read_line_input(prompt_str, user_input_buf, BUFSIZ-1, line_input_state);
1139	i->eof_flag = (r < 0);
1140	if (i->eof_flag) { /* EOF/error detected */
1141		user_input_buf[0] = EOF; /* yes, it will be truncated, it's ok */
1142		user_input_buf[1] = '\0';
1143	}
1144#else
1145	fputs(prompt_str, stdout);
1146	fflush(stdout);
1147	user_input_buf[0] = r = fgetc(i->file);
1148	/*user_input_buf[1] = '\0'; - already is and never changed */
1149	i->eof_flag = (r == EOF);
1150#endif
1151	i->p = user_input_buf;
1152}
1153#endif  /* INTERACTIVE */
1154
1155/* This is the magic location that prints prompts
1156 * and gets data back from the user */
1157static int file_get(struct in_str *i)
1158{
1159	int ch;
1160
1161	/* If there is data waiting, eat it up */
1162	if (i->p && *i->p) {
1163#if ENABLE_HUSH_INTERACTIVE
1164 take_cached:
1165#endif
1166		ch = *i->p++;
1167		if (i->eof_flag && !*i->p)
1168			ch = EOF;
1169	} else {
1170		/* need to double check i->file because we might be doing something
1171		 * more complicated by now, like sourcing or substituting. */
1172#if ENABLE_HUSH_INTERACTIVE
1173		if (interactive_fd && i->promptme && i->file == stdin) {
1174			do {
1175				get_user_input(i);
1176			} while (!*i->p); /* need non-empty line */
1177			i->promptmode = 1; /* PS2 */
1178			i->promptme = 0;
1179			goto take_cached;
1180		}
1181#endif
1182		ch = fgetc(i->file);
1183	}
1184	debug_printf("file_get: got a '%c' %d\n", ch, ch);
1185#if ENABLE_HUSH_INTERACTIVE
1186	if (ch == '\n')
1187		i->promptme = 1;
1188#endif
1189	return ch;
1190}
1191
1192/* All the callers guarantee this routine will never be
1193 * used right after a newline, so prompting is not needed.
1194 */
1195static int file_peek(struct in_str *i)
1196{
1197	int ch;
1198	if (i->p && *i->p) {
1199		if (i->eof_flag && !i->p[1])
1200			return EOF;
1201		return *i->p;
1202	}
1203	ch = fgetc(i->file);
1204	i->eof_flag = (ch == EOF);
1205	i->peek_buf[0] = ch;
1206	i->peek_buf[1] = '\0';
1207	i->p = i->peek_buf;
1208	debug_printf("file_peek: got a '%c' %d\n", *i->p, *i->p);
1209	return ch;
1210}
1211
1212static void setup_file_in_str(struct in_str *i, FILE *f)
1213{
1214	i->peek = file_peek;
1215	i->get = file_get;
1216#if ENABLE_HUSH_INTERACTIVE
1217	i->promptme = 1;
1218	i->promptmode = 0; /* PS1 */
1219#endif
1220	i->file = f;
1221	i->p = NULL;
1222}
1223
1224static void setup_string_in_str(struct in_str *i, const char *s)
1225{
1226	i->peek = static_peek;
1227	i->get = static_get;
1228#if ENABLE_HUSH_INTERACTIVE
1229	i->promptme = 1;
1230	i->promptmode = 0; /* PS1 */
1231#endif
1232	i->p = s;
1233	i->eof_flag = 0;
1234}
1235
1236static void mark_open(int fd)
1237{
1238	struct close_me *new = xmalloc(sizeof(struct close_me));
1239	new->fd = fd;
1240	new->next = close_me_head;
1241	close_me_head = new;
1242}
1243
1244static void mark_closed(int fd)
1245{
1246	struct close_me *tmp;
1247	if (close_me_head == NULL || close_me_head->fd != fd)
1248		bb_error_msg_and_die("corrupt close_me");
1249	tmp = close_me_head;
1250	close_me_head = close_me_head->next;
1251	free(tmp);
1252}
1253
1254static void close_all(void)
1255{
1256	struct close_me *c;
1257	for (c = close_me_head; c; c = c->next) {
1258		close(c->fd);
1259	}
1260	close_me_head = NULL;
1261}
1262
1263/* squirrel != NULL means we squirrel away copies of stdin, stdout,
1264 * and stderr if they are redirected. */
1265static int setup_redirects(struct child_prog *prog, int squirrel[])
1266{
1267	int openfd, mode;
1268	struct redir_struct *redir;
1269
1270	for (redir = prog->redirects; redir; redir = redir->next) {
1271		if (redir->dup == -1 && redir->word.gl_pathv == NULL) {
1272			/* something went wrong in the parse.  Pretend it didn't happen */
1273			continue;
1274		}
1275		if (redir->dup == -1) {
1276			mode = redir_table[redir->type].mode;
1277			openfd = open_or_warn(redir->word.gl_pathv[0], mode);
1278			if (openfd < 0) {
1279			/* this could get lost if stderr has been redirected, but
1280			   bash and ash both lose it as well (though zsh doesn't!) */
1281				return 1;
1282			}
1283		} else {
1284			openfd = redir->dup;
1285		}
1286
1287		if (openfd != redir->fd) {
1288			if (squirrel && redir->fd < 3) {
1289				squirrel[redir->fd] = dup(redir->fd);
1290			}
1291			if (openfd == -3) {
1292				close(openfd);
1293			} else {
1294				dup2(openfd, redir->fd);
1295				if (redir->dup == -1)
1296					close(openfd);
1297			}
1298		}
1299	}
1300	return 0;
1301}
1302
1303static void restore_redirects(int squirrel[])
1304{
1305	int i, fd;
1306	for (i = 0; i < 3; i++) {
1307		fd = squirrel[i];
1308		if (fd != -1) {
1309			/* We simply die on error */
1310			xmove_fd(fd, i);
1311		}
1312	}
1313}
1314
1315/* never returns */
1316static void pseudo_exec_argv(char **argv)
1317{
1318	int i, rcode;
1319	char *p;
1320	const struct built_in_command *x;
1321
1322	for (i = 0; is_assignment(argv[i]); i++) {
1323		debug_printf_exec("pid %d environment modification: %s\n",
1324				getpid(), argv[i]);
1325		p = expand_string_to_string(argv[i]);
1326		putenv(p);
1327	}
1328	argv += i;
1329	/* If a variable is assigned in a forest, and nobody listens,
1330	 * was it ever really set?
1331	 */
1332	if (argv[0] == NULL) {
1333		_exit(EXIT_SUCCESS);
1334	}
1335
1336	argv = expand_strvec_to_strvec(argv);
1337
1338	/*
1339	 * Check if the command matches any of the builtins.
1340	 * Depending on context, this might be redundant.  But it's
1341	 * easier to waste a few CPU cycles than it is to figure out
1342	 * if this is one of those cases.
1343	 */
1344	for (x = bltins; x->cmd; x++) {
1345		if (strcmp(argv[0], x->cmd) == 0) {
1346			debug_printf_exec("running builtin '%s'\n", argv[0]);
1347			rcode = x->function(argv);
1348			fflush(stdout);
1349			_exit(rcode);
1350		}
1351	}
1352
1353	/* Check if the command matches any busybox applets */
1354#if ENABLE_FEATURE_SH_STANDALONE
1355	if (strchr(argv[0], '/') == NULL) {
1356		const struct bb_applet *a = find_applet_by_name(argv[0]);
1357		if (a) {
1358			if (a->noexec) {
1359				current_applet = a;
1360				debug_printf_exec("running applet '%s'\n", argv[0]);
1361// is it ok that run_current_applet_and_exit() does exit(), not _exit()?
1362				run_current_applet_and_exit(argv);
1363			}
1364			/* re-exec ourselves with the new arguments */
1365			debug_printf_exec("re-execing applet '%s'\n", argv[0]);
1366			execvp(bb_busybox_exec_path, argv);
1367			/* If they called chroot or otherwise made the binary no longer
1368			 * executable, fall through */
1369		}
1370	}
1371#endif
1372
1373	debug_printf_exec("execing '%s'\n", argv[0]);
1374	execvp(argv[0], argv);
1375	bb_perror_msg("cannot exec '%s'", argv[0]);
1376	_exit(1);
1377}
1378
1379static void pseudo_exec(struct child_prog *child)
1380{
1381// until it does exec/_exit, but currently it does.
1382	int rcode;
1383
1384	if (child->argv) {
1385		pseudo_exec_argv(child->argv);
1386	}
1387
1388	if (child->group) {
1389#if ENABLE_HUSH_INTERACTIVE
1390		debug_printf_exec("pseudo_exec: setting interactive_fd=0\n");
1391		interactive_fd = 0;    /* crucial!!!! */
1392#endif
1393		debug_printf_exec("pseudo_exec: run_list_real\n");
1394		rcode = run_list_real(child->group);
1395		/* OK to leak memory by not calling free_pipe_list,
1396		 * since this process is about to exit */
1397		_exit(rcode);
1398	}
1399
1400	/* Can happen.  See what bash does with ">foo" by itself. */
1401	debug_printf("trying to pseudo_exec null command\n");
1402	_exit(EXIT_SUCCESS);
1403}
1404
1405#if ENABLE_HUSH_JOB
1406static const char *get_cmdtext(struct pipe *pi)
1407{
1408	char **argv;
1409	char *p;
1410	int len;
1411
1412	/* This is subtle. ->cmdtext is created only on first backgrounding.
1413	 * (Think "cat, <ctrl-z>, fg, <ctrl-z>, fg, <ctrl-z>...." here...)
1414	 * On subsequent bg argv is trashed, but we won't use it */
1415	if (pi->cmdtext)
1416		return pi->cmdtext;
1417	argv = pi->progs[0].argv;
1418	if (!argv || !argv[0])
1419		return (pi->cmdtext = xzalloc(1));
1420
1421	len = 0;
1422	do len += strlen(*argv) + 1; while (*++argv);
1423	pi->cmdtext = p = xmalloc(len);
1424	argv = pi->progs[0].argv;
1425	do {
1426		len = strlen(*argv);
1427		memcpy(p, *argv, len);
1428		p += len;
1429		*p++ = ' ';
1430	} while (*++argv);
1431	p[-1] = '\0';
1432	return pi->cmdtext;
1433}
1434
1435static void insert_bg_job(struct pipe *pi)
1436{
1437	struct pipe *thejob;
1438	int i;
1439
1440	/* Linear search for the ID of the job to use */
1441	pi->jobid = 1;
1442	for (thejob = job_list; thejob; thejob = thejob->next)
1443		if (thejob->jobid >= pi->jobid)
1444			pi->jobid = thejob->jobid + 1;
1445
1446	/* Add thejob to the list of running jobs */
1447	if (!job_list) {
1448		thejob = job_list = xmalloc(sizeof(*thejob));
1449	} else {
1450		for (thejob = job_list; thejob->next; thejob = thejob->next)
1451			continue;
1452		thejob->next = xmalloc(sizeof(*thejob));
1453		thejob = thejob->next;
1454	}
1455
1456	/* Physically copy the struct job */
1457	memcpy(thejob, pi, sizeof(struct pipe));
1458	thejob->progs = xzalloc(sizeof(pi->progs[0]) * pi->num_progs);
1459	/* We cannot copy entire pi->progs[] vector! Double free()s will happen */
1460	for (i = 0; i < pi->num_progs; i++) {
1461// TODO: do we really need to have so many fields which are just dead weight
1462// at execution stage?
1463		thejob->progs[i].pid = pi->progs[i].pid;
1464		/* all other fields are not used and stay zero */
1465	}
1466	thejob->next = NULL;
1467	thejob->cmdtext = xstrdup(get_cmdtext(pi));
1468
1469	/* We don't wait for background thejobs to return -- append it
1470	   to the list of backgrounded thejobs and leave it alone */
1471	printf("[%d] %d %s\n", thejob->jobid, thejob->progs[0].pid, thejob->cmdtext);
1472	last_bg_pid = thejob->progs[0].pid;
1473	last_jobid = thejob->jobid;
1474}
1475
1476static void remove_bg_job(struct pipe *pi)
1477{
1478	struct pipe *prev_pipe;
1479
1480	if (pi == job_list) {
1481		job_list = pi->next;
1482	} else {
1483		prev_pipe = job_list;
1484		while (prev_pipe->next != pi)
1485			prev_pipe = prev_pipe->next;
1486		prev_pipe->next = pi->next;
1487	}
1488	if (job_list)
1489		last_jobid = job_list->jobid;
1490	else
1491		last_jobid = 0;
1492}
1493
1494/* remove a backgrounded job */
1495static void delete_finished_bg_job(struct pipe *pi)
1496{
1497	remove_bg_job(pi);
1498	pi->stopped_progs = 0;
1499	free_pipe(pi, 0);
1500	free(pi);
1501}
1502#endif /* JOB */
1503
1504/* Checks to see if any processes have exited -- if they
1505   have, figure out why and see if a job has completed */
1506static int checkjobs(struct pipe* fg_pipe)
1507{
1508	int attributes;
1509	int status;
1510#if ENABLE_HUSH_JOB
1511	int prognum = 0;
1512	struct pipe *pi;
1513#endif
1514	pid_t childpid;
1515	int rcode = 0;
1516
1517	attributes = WUNTRACED;
1518	if (fg_pipe == NULL) {
1519		attributes |= WNOHANG;
1520	}
1521
1522/* Do we do this right?
1523 * bash-3.00# sleep 20 | false
1524 * <ctrl-Z pressed>
1525 * [3]+  Stopped          sleep 20 | false
1526 * bash-3.00# echo $?
1527 * 1   <========== bg pipe is not fully done, but exitcode is already known!
1528 */
1529
1530//are stopped. Testcase: "cat | cat" in a script (not on command line)
1531// + killall -STOP cat
1532
1533 wait_more:
1534	while ((childpid = waitpid(-1, &status, attributes)) > 0) {
1535		const int dead = WIFEXITED(status) || WIFSIGNALED(status);
1536
1537#ifdef DEBUG_SHELL_JOBS
1538		if (WIFSTOPPED(status))
1539			debug_printf_jobs("pid %d stopped by sig %d (exitcode %d)\n",
1540					childpid, WSTOPSIG(status), WEXITSTATUS(status));
1541		if (WIFSIGNALED(status))
1542			debug_printf_jobs("pid %d killed by sig %d (exitcode %d)\n",
1543					childpid, WTERMSIG(status), WEXITSTATUS(status));
1544		if (WIFEXITED(status))
1545			debug_printf_jobs("pid %d exited, exitcode %d\n",
1546					childpid, WEXITSTATUS(status));
1547#endif
1548		/* Were we asked to wait for fg pipe? */
1549		if (fg_pipe) {
1550			int i;
1551			for (i = 0; i < fg_pipe->num_progs; i++) {
1552				debug_printf_jobs("check pid %d\n", fg_pipe->progs[i].pid);
1553				if (fg_pipe->progs[i].pid == childpid) {
1554					/* printf("process %d exit %d\n", i, WEXITSTATUS(status)); */
1555					if (dead) {
1556						fg_pipe->progs[i].pid = 0;
1557						fg_pipe->running_progs--;
1558						if (i == fg_pipe->num_progs-1)
1559							/* last process gives overall exitstatus */
1560							rcode = WEXITSTATUS(status);
1561					} else {
1562						fg_pipe->progs[i].is_stopped = 1;
1563						fg_pipe->stopped_progs++;
1564					}
1565					debug_printf_jobs("fg_pipe: running_progs %d stopped_progs %d\n",
1566							fg_pipe->running_progs, fg_pipe->stopped_progs);
1567					if (fg_pipe->running_progs - fg_pipe->stopped_progs <= 0) {
1568						/* All processes in fg pipe have exited/stopped */
1569#if ENABLE_HUSH_JOB
1570						if (fg_pipe->running_progs)
1571							insert_bg_job(fg_pipe);
1572#endif
1573						return rcode;
1574					}
1575					/* There are still running processes in the fg pipe */
1576					goto wait_more;
1577				}
1578			}
1579			/* fall through to searching process in bg pipes */
1580		}
1581
1582#if ENABLE_HUSH_JOB
1583		/* We asked to wait for bg or orphaned children */
1584		/* No need to remember exitcode in this case */
1585		for (pi = job_list; pi; pi = pi->next) {
1586			prognum = 0;
1587			while (prognum < pi->num_progs) {
1588				if (pi->progs[prognum].pid == childpid)
1589					goto found_pi_and_prognum;
1590				prognum++;
1591			}
1592		}
1593#endif
1594
1595		/* Happens when shell is used as init process (init=/bin/sh) */
1596		debug_printf("checkjobs: pid %d was not in our list!\n", childpid);
1597		goto wait_more;
1598
1599#if ENABLE_HUSH_JOB
1600 found_pi_and_prognum:
1601		if (dead) {
1602			/* child exited */
1603			pi->progs[prognum].pid = 0;
1604			pi->running_progs--;
1605			if (!pi->running_progs) {
1606				printf(JOB_STATUS_FORMAT, pi->jobid,
1607							"Done", pi->cmdtext);
1608				delete_finished_bg_job(pi);
1609			}
1610		} else {
1611			/* child stopped */
1612			pi->stopped_progs++;
1613			pi->progs[prognum].is_stopped = 1;
1614		}
1615#endif
1616	}
1617
1618	/* wait found no children or failed */
1619
1620	if (childpid && errno != ECHILD)
1621		bb_perror_msg("waitpid");
1622	return rcode;
1623}
1624
1625#if ENABLE_HUSH_JOB
1626static int checkjobs_and_fg_shell(struct pipe* fg_pipe)
1627{
1628	pid_t p;
1629	int rcode = checkjobs(fg_pipe);
1630	/* Job finished, move the shell to the foreground */
1631	p = getpgid(0); /* pgid of our process */
1632	debug_printf_jobs("fg'ing ourself: getpgid(0)=%d\n", (int)p);
1633	if (tcsetpgrp(interactive_fd, p) && errno != ENOTTY)
1634		bb_perror_msg("tcsetpgrp-4a");
1635	return rcode;
1636}
1637#endif
1638
1639/* run_pipe_real() starts all the jobs, but doesn't wait for anything
1640 * to finish.  See checkjobs().
1641 *
1642 * return code is normally -1, when the caller has to wait for children
1643 * to finish to determine the exit status of the pipe.  If the pipe
1644 * is a simple builtin command, however, the action is done by the
1645 * time run_pipe_real returns, and the exit code is provided as the
1646 * return value.
1647 *
1648 * The input of the pipe is always stdin, the output is always
1649 * stdout.  The outpipe[] mechanism in BusyBox-0.48 lash is bogus,
1650 * because it tries to avoid running the command substitution in
1651 * subshell, when that is in fact necessary.  The subshell process
1652 * now has its stdout directed to the input of the appropriate pipe,
1653 * so this routine is noticeably simpler.
1654 *
1655 * Returns -1 only if started some children. IOW: we have to
1656 * mask out retvals of builtins etc with 0xff!
1657 */
1658static int run_pipe_real(struct pipe *pi)
1659{
1660	int i;
1661	int nextin, nextout;
1662	int pipefds[2];				/* pipefds[0] is for reading */
1663	struct child_prog *child;
1664	const struct built_in_command *x;
1665	char *p;
1666	/* it is not always needed, but we aim to smaller code */
1667	int squirrel[] = { -1, -1, -1 };
1668	int rcode;
1669	const int single_fg = (pi->num_progs == 1 && pi->followup != PIPE_BG);
1670
1671	debug_printf_exec("run_pipe_real start: single_fg=%d\n", single_fg);
1672
1673	nextin = 0;
1674#if ENABLE_HUSH_JOB
1675	pi->pgrp = -1;
1676#endif
1677	pi->running_progs = 1;
1678	pi->stopped_progs = 0;
1679
1680	/* Check if this is a simple builtin (not part of a pipe).
1681	 * Builtins within pipes have to fork anyway, and are handled in
1682	 * pseudo_exec.  "echo foo | read bar" doesn't work on bash, either.
1683	 */
1684	child = &(pi->progs[0]);
1685	if (single_fg && child->group && child->subshell == 0) {
1686		debug_printf("non-subshell grouping\n");
1687		setup_redirects(child, squirrel);
1688		debug_printf_exec(": run_list_real\n");
1689		rcode = run_list_real(child->group);
1690		restore_redirects(squirrel);
1691		debug_printf_exec("run_pipe_real return %d\n", rcode);
1692		return rcode; // do we need to add '... & 0xff' ?
1693	}
1694
1695	if (single_fg && child->argv != NULL) {
1696		char **argv_expanded;
1697		char **argv = child->argv;
1698
1699		for (i = 0; is_assignment(argv[i]); i++)
1700			continue;
1701		if (i != 0 && argv[i] == NULL) {
1702			/* assignments, but no command: set the local environment */
1703			for (i = 0; argv[i] != NULL; i++) {
1704				debug_printf("local environment set: %s\n", argv[i]);
1705				p = expand_string_to_string(argv[i]);
1706				set_local_var(p, 0);
1707			}
1708			return EXIT_SUCCESS;   /* don't worry about errors in set_local_var() yet */
1709		}
1710		for (i = 0; is_assignment(argv[i]); i++) {
1711			p = expand_string_to_string(argv[i]);
1712			//sp: child->sp--;
1713			putenv(p);
1714		}
1715		for (x = bltins; x->cmd; x++) {
1716			if (strcmp(argv[i], x->cmd) == 0) {
1717				if (x->function == builtin_exec && argv[i+1] == NULL) {
1718					debug_printf("magic exec\n");
1719					setup_redirects(child, NULL);
1720					return EXIT_SUCCESS;
1721				}
1722				debug_printf("builtin inline %s\n", argv[0]);
1723				setup_redirects(child, squirrel);
1724				debug_printf_exec(": builtin '%s' '%s'...\n", x->cmd, argv[i+1]);
1725				//sp: if (child->sp) /* btw we can do it unconditionally... */
1726				argv_expanded = expand_strvec_to_strvec(argv + i);
1727				rcode = x->function(argv_expanded) & 0xff;
1728				free(argv_expanded);
1729				restore_redirects(squirrel);
1730				debug_printf_exec("run_pipe_real return %d\n", rcode);
1731				return rcode;
1732			}
1733		}
1734#if ENABLE_FEATURE_SH_STANDALONE
1735		{
1736			const struct bb_applet *a = find_applet_by_name(argv[i]);
1737			if (a && a->nofork) {
1738				setup_redirects(child, squirrel);
1739				save_nofork_data(&nofork_save);
1740				argv_expanded = argv + i;
1741				//sp: if (child->sp)
1742				argv_expanded = expand_strvec_to_strvec(argv + i);
1743				debug_printf_exec(": run_nofork_applet '%s' '%s'...\n", argv_expanded[0], argv_expanded[1]);
1744				rcode = run_nofork_applet_prime(&nofork_save, a, argv_expanded) & 0xff;
1745				free(argv_expanded);
1746				restore_redirects(squirrel);
1747				debug_printf_exec("run_pipe_real return %d\n", rcode);
1748				return rcode;
1749			}
1750		}
1751#endif
1752	}
1753
1754	/* Going to fork a child per each pipe member */
1755	pi->running_progs = 0;
1756
1757	/* Disable job control signals for shell (parent) and
1758	 * for initial child code after fork */
1759	set_jobctrl_sighandler(SIG_IGN);
1760
1761	for (i = 0; i < pi->num_progs; i++) {
1762		child = &(pi->progs[i]);
1763		if (child->argv)
1764			debug_printf_exec(": pipe member '%s' '%s'...\n", child->argv[0], child->argv[1]);
1765		else
1766			debug_printf_exec(": pipe member with no argv\n");
1767
1768		/* pipes are inserted between pairs of commands */
1769		if ((i + 1) < pi->num_progs) {
1770			pipe(pipefds);
1771			nextout = pipefds[1];
1772		} else {
1773			nextout = 1;
1774			pipefds[0] = -1;
1775		}
1776
1777#if BB_MMU
1778		child->pid = fork();
1779#else
1780		child->pid = vfork();
1781#endif
1782		if (!child->pid) { /* child */
1783			/* Every child adds itself to new process group
1784			 * with pgid == pid of first child in pipe */
1785#if ENABLE_HUSH_JOB
1786			if (run_list_level == 1 && interactive_fd) {
1787				/* Don't do pgrp restore anymore on fatal signals */
1788				set_fatal_sighandler(SIG_DFL);
1789				if (pi->pgrp < 0) /* true for 1st process only */
1790					pi->pgrp = getpid();
1791				if (setpgid(0, pi->pgrp) == 0 && pi->followup != PIPE_BG) {
1792					/* We do it in *every* child, not just first,
1793					 * to avoid races */
1794					tcsetpgrp(interactive_fd, pi->pgrp);
1795				}
1796			}
1797#endif
1798			/* in non-interactive case fatal sigs are already SIG_DFL */
1799			close_all();
1800			if (nextin != 0) {
1801				dup2(nextin, 0);
1802				close(nextin);
1803			}
1804			if (nextout != 1) {
1805				dup2(nextout, 1);
1806				close(nextout);
1807			}
1808			if (pipefds[0] != -1) {
1809				close(pipefds[0]);  /* opposite end of our output pipe */
1810			}
1811			/* Like bash, explicit redirects override pipes,
1812			 * and the pipe fd is available for dup'ing. */
1813			setup_redirects(child, NULL);
1814
1815			/* Restore default handlers just prior to exec */
1816			set_jobctrl_sighandler(SIG_DFL);
1817			set_misc_sighandler(SIG_DFL);
1818			signal(SIGCHLD, SIG_DFL);
1819			pseudo_exec(child);
1820		}
1821
1822		pi->running_progs++;
1823
1824#if ENABLE_HUSH_JOB
1825		/* Second and next children need to know pid of first one */
1826		if (pi->pgrp < 0)
1827			pi->pgrp = child->pid;
1828#endif
1829		if (nextin != 0)
1830			close(nextin);
1831		if (nextout != 1)
1832			close(nextout);
1833
1834		/* If there isn't another process, nextin is garbage
1835		   but it doesn't matter */
1836		nextin = pipefds[0];
1837	}
1838	debug_printf_exec("run_pipe_real return -1\n");
1839	return -1;
1840}
1841
1842#ifndef debug_print_tree
1843static void debug_print_tree(struct pipe *pi, int lvl)
1844{
1845	static const char *PIPE[] = {
1846		[PIPE_SEQ] = "SEQ",
1847		[PIPE_AND] = "AND",
1848		[PIPE_OR ] = "OR" ,
1849		[PIPE_BG ] = "BG" ,
1850	};
1851	static const char *RES[] = {
1852		[RES_NONE ] = "NONE" ,
1853#if ENABLE_HUSH_IF
1854		[RES_IF   ] = "IF"   ,
1855		[RES_THEN ] = "THEN" ,
1856		[RES_ELIF ] = "ELIF" ,
1857		[RES_ELSE ] = "ELSE" ,
1858		[RES_FI   ] = "FI"   ,
1859#endif
1860#if ENABLE_HUSH_LOOPS
1861		[RES_FOR  ] = "FOR"  ,
1862		[RES_WHILE] = "WHILE",
1863		[RES_UNTIL] = "UNTIL",
1864		[RES_DO   ] = "DO"   ,
1865		[RES_DONE ] = "DONE" ,
1866		[RES_IN   ] = "IN"   ,
1867#endif
1868		[RES_XXXX ] = "XXXX" ,
1869		[RES_SNTX ] = "SNTX" ,
1870	};
1871
1872	int pin, prn;
1873
1874	pin = 0;
1875	while (pi) {
1876		fprintf(stderr, "%*spipe %d res_word=%s followup=%d %s\n", lvl*2, "",
1877				pin, RES[pi->res_word], pi->followup, PIPE[pi->followup]);
1878		prn = 0;
1879		while (prn < pi->num_progs) {
1880			struct child_prog *child = &pi->progs[prn];
1881			char **argv = child->argv;
1882
1883			fprintf(stderr, "%*s prog %d", lvl*2, "", prn);
1884			if (child->group) {
1885				fprintf(stderr, " group %s: (argv=%p)\n",
1886						(child->subshell ? "()" : "{}"),
1887						argv);
1888				debug_print_tree(child->group, lvl+1);
1889				prn++;
1890				continue;
1891			}
1892			if (argv) while (*argv) {
1893				fprintf(stderr, " '%s'", *argv);
1894				argv++;
1895			}
1896			fprintf(stderr, "\n");
1897			prn++;
1898		}
1899		pi = pi->next;
1900		pin++;
1901	}
1902}
1903#endif
1904
1905/* NB: called by pseudo_exec, and therefore must not modify any
1906 * global data until exec/_exit (we can be a child after vfork!) */
1907static int run_list_real(struct pipe *pi)
1908{
1909	struct pipe *rpipe;
1910#if ENABLE_HUSH_LOOPS
1911	char *for_varname = NULL;
1912	char **for_lcur = NULL;
1913	char **for_list = NULL;
1914	int flag_rep = 0;
1915#endif
1916	int save_num_progs;
1917	int flag_skip = 1;
1918	int rcode = 0; /* probably for gcc only */
1919	int flag_restore = 0;
1920#if ENABLE_HUSH_IF
1921	int if_code = 0, next_if_code = 0;  /* need double-buffer to handle elif */
1922#else
1923	enum { if_code = 0, next_if_code = 0 };
1924#endif
1925	reserved_style rword;
1926	reserved_style skip_more_for_this_rword = RES_XXXX;
1927
1928	debug_printf_exec("run_list_real start lvl %d\n", run_list_level + 1);
1929
1930#if ENABLE_HUSH_LOOPS
1931	/* check syntax for "for" */
1932	for (rpipe = pi; rpipe; rpipe = rpipe->next) {
1933		if ((rpipe->res_word == RES_IN || rpipe->res_word == RES_FOR)
1934		 && (rpipe->next == NULL)
1935		) {
1936			syntax("malformed for"); /* no IN or no commands after IN */
1937			debug_printf_exec("run_list_real lvl %d return 1\n", run_list_level);
1938			return 1;
1939		}
1940		if ((rpipe->res_word == RES_IN && rpipe->next->res_word == RES_IN && rpipe->next->progs[0].argv != NULL)
1941		 || (rpipe->res_word == RES_FOR && rpipe->next->res_word != RES_IN)
1942		) {
1943			/* TODO: what is tested in the first condition? */
1944			syntax("malformed for"); /* 2nd condition: not followed by IN */
1945			debug_printf_exec("run_list_real lvl %d return 1\n", run_list_level);
1946			return 1;
1947		}
1948	}
1949#else
1950	rpipe = NULL;
1951#endif
1952
1953#if ENABLE_HUSH_JOB
1954	/* Example of nested list: "while true; do { sleep 1 | exit 2; } done".
1955	 * We are saving state before entering outermost list ("while...done")
1956	 * so that ctrl-Z will correctly background _entire_ outermost list,
1957	 * not just a part of it (like "sleep 1 | exit 2") */
1958	if (++run_list_level == 1 && interactive_fd) {
1959		if (sigsetjmp(toplevel_jb, 1)) {
1960			/* ctrl-Z forked and we are parent; or ctrl-C.
1961			 * Sighandler has longjmped us here */
1962			signal(SIGINT, SIG_IGN);
1963			signal(SIGTSTP, SIG_IGN);
1964			/* Restore level (we can be coming from deep inside
1965			 * nested levels) */
1966			run_list_level = 1;
1967#if ENABLE_FEATURE_SH_STANDALONE
1968			if (nofork_save.saved) { /* if save area is valid */
1969				debug_printf_jobs("exiting nofork early\n");
1970				restore_nofork_data(&nofork_save);
1971			}
1972#endif
1973			if (ctrl_z_flag) {
1974				/* ctrl-Z has forked and stored pid of the child in pi->pid.
1975				 * Remember this child as background job */
1976				insert_bg_job(pi);
1977			} else {
1978				/* ctrl-C. We just stop doing whatever we were doing */
1979				putchar('\n');
1980			}
1981			rcode = 0;
1982			goto ret;
1983		}
1984		/* ctrl-Z handler will store pid etc in pi */
1985		toplevel_list = pi;
1986		ctrl_z_flag = 0;
1987#if ENABLE_FEATURE_SH_STANDALONE
1988		nofork_save.saved = 0; /* in case we will run a nofork later */
1989#endif
1990		signal_SA_RESTART(SIGTSTP, handler_ctrl_z);
1991		signal(SIGINT, handler_ctrl_c);
1992	}
1993#endif
1994
1995	for (; pi; pi = flag_restore ? rpipe : pi->next) {
1996		rword = pi->res_word;
1997#if ENABLE_HUSH_LOOPS
1998		if (rword == RES_WHILE || rword == RES_UNTIL || rword == RES_FOR) {
1999			flag_restore = 0;
2000			if (!rpipe) {
2001				flag_rep = 0;
2002				rpipe = pi;
2003			}
2004		}
2005#endif
2006		debug_printf_exec(": rword=%d if_code=%d next_if_code=%d skip_more=%d\n",
2007				rword, if_code, next_if_code, skip_more_for_this_rword);
2008		if (rword == skip_more_for_this_rword && flag_skip) {
2009			if (pi->followup == PIPE_SEQ)
2010				flag_skip = 0;
2011			continue;
2012		}
2013		flag_skip = 1;
2014		skip_more_for_this_rword = RES_XXXX;
2015#if ENABLE_HUSH_IF
2016		if (rword == RES_THEN || rword == RES_ELSE)
2017			if_code = next_if_code;
2018		if (rword == RES_THEN && if_code)
2019			continue;
2020		if (rword == RES_ELSE && !if_code)
2021			continue;
2022		if (rword == RES_ELIF && !if_code)
2023			break;
2024#endif
2025#if ENABLE_HUSH_LOOPS
2026		if (rword == RES_FOR && pi->num_progs) {
2027			if (!for_lcur) {
2028				/* if no variable values after "in" we skip "for" */
2029				if (!pi->next->progs->argv)
2030					continue;
2031				/* create list of variable values */
2032				for_list = expand_strvec_to_strvec(pi->next->progs->argv);
2033				for_lcur = for_list;
2034				for_varname = pi->progs->argv[0];
2035				pi->progs->argv[0] = NULL;
2036				flag_rep = 1;
2037			}
2038			free(pi->progs->argv[0]);
2039			if (!*for_lcur) {
2040				free(for_list);
2041				for_lcur = NULL;
2042				flag_rep = 0;
2043				pi->progs->argv[0] = for_varname;
2044				pi->progs->glob_result.gl_pathv[0] = pi->progs->argv[0];
2045				continue;
2046			}
2047			/* insert next value from for_lcur */
2048			/* vda: does it need escaping? */
2049			pi->progs->argv[0] = xasprintf("%s=%s", for_varname, *for_lcur++);
2050			pi->progs->glob_result.gl_pathv[0] = pi->progs->argv[0];
2051		}
2052		if (rword == RES_IN)
2053			continue;
2054		if (rword == RES_DO) {
2055			if (!flag_rep)
2056				continue;
2057		}
2058		if (rword == RES_DONE) {
2059			if (flag_rep) {
2060				flag_restore = 1;
2061			} else {
2062				rpipe = NULL;
2063			}
2064		}
2065#endif
2066		if (pi->num_progs == 0)
2067			continue;
2068		save_num_progs = pi->num_progs; /* save number of programs */
2069		debug_printf_exec(": run_pipe_real with %d members\n", pi->num_progs);
2070		rcode = run_pipe_real(pi);
2071		if (rcode != -1) {
2072			/* We only ran a builtin: rcode was set by the return value
2073			 * of run_pipe_real(), and we don't need to wait for anything. */
2074		} else if (pi->followup == PIPE_BG) {
2075			/* What does bash do with attempts to background builtins? */
2076			/* Even bash 3.2 doesn't do that well with nested bg:
2077			 * try "{ { sleep 10; echo DEEP; } & echo HERE; } &".
2078			 * I'm NOT treating inner &'s as jobs */
2079#if ENABLE_HUSH_JOB
2080			if (run_list_level == 1)
2081				insert_bg_job(pi);
2082#endif
2083			rcode = EXIT_SUCCESS;
2084		} else {
2085#if ENABLE_HUSH_JOB
2086			/* Paranoia, just "interactive_fd" should be enough? */
2087			if (run_list_level == 1 && interactive_fd) {
2088				/* waits for completion, then fg's main shell */
2089				rcode = checkjobs_and_fg_shell(pi);
2090			} else
2091#endif
2092			{
2093				/* this one just waits for completion */
2094				rcode = checkjobs(pi);
2095			}
2096			debug_printf_exec(": checkjobs returned %d\n", rcode);
2097		}
2098		debug_printf_exec(": setting last_return_code=%d\n", rcode);
2099		last_return_code = rcode;
2100		pi->num_progs = save_num_progs; /* restore number of programs */
2101#if ENABLE_HUSH_IF
2102		if (rword == RES_IF || rword == RES_ELIF)
2103			next_if_code = rcode;  /* can be overwritten a number of times */
2104#endif
2105#if ENABLE_HUSH_LOOPS
2106		if (rword == RES_WHILE)
2107			flag_rep = !last_return_code;
2108		if (rword == RES_UNTIL)
2109			flag_rep = last_return_code;
2110#endif
2111		if ((rcode == EXIT_SUCCESS && pi->followup == PIPE_OR)
2112		 || (rcode != EXIT_SUCCESS && pi->followup == PIPE_AND)
2113		) {
2114			skip_more_for_this_rword = rword;
2115		}
2116		checkjobs(NULL);
2117	}
2118
2119#if ENABLE_HUSH_JOB
2120	if (ctrl_z_flag) {
2121		/* ctrl-Z forked somewhere in the past, we are the child,
2122		 * and now we completed running the list. Exit. */
2123		exit(rcode);
2124	}
2125 ret:
2126	if (!--run_list_level && interactive_fd) {
2127		signal(SIGTSTP, SIG_IGN);
2128		signal(SIGINT, SIG_IGN);
2129	}
2130#endif
2131	debug_printf_exec("run_list_real lvl %d return %d\n", run_list_level + 1, rcode);
2132	return rcode;
2133}
2134
2135/* return code is the exit status of the pipe */
2136static int free_pipe(struct pipe *pi, int indent)
2137{
2138	char **p;
2139	struct child_prog *child;
2140	struct redir_struct *r, *rnext;
2141	int a, i, ret_code = 0;
2142
2143	if (pi->stopped_progs > 0)
2144		return ret_code;
2145	debug_printf_clean("%s run pipe: (pid %d)\n", indenter(indent), getpid());
2146	for (i = 0; i < pi->num_progs; i++) {
2147		child = &pi->progs[i];
2148		debug_printf_clean("%s  command %d:\n", indenter(indent), i);
2149		if (child->argv) {
2150			for (a = 0, p = child->argv; *p; a++, p++) {
2151				debug_printf_clean("%s   argv[%d] = %s\n", indenter(indent), a, *p);
2152			}
2153			globfree(&child->glob_result);
2154			child->argv = NULL;
2155		} else if (child->group) {
2156			debug_printf_clean("%s   begin group (subshell:%d)\n", indenter(indent), child->subshell);
2157			ret_code = free_pipe_list(child->group, indent+3);
2158			debug_printf_clean("%s   end group\n", indenter(indent));
2159		} else {
2160			debug_printf_clean("%s   (nil)\n", indenter(indent));
2161		}
2162		for (r = child->redirects; r; r = rnext) {
2163			debug_printf_clean("%s   redirect %d%s", indenter(indent), r->fd, redir_table[r->type].descrip);
2164			if (r->dup == -1) {
2165				/* guard against the case >$FOO, where foo is unset or blank */
2166				if (r->word.gl_pathv) {
2167					debug_printf_clean(" %s\n", *r->word.gl_pathv);
2168					globfree(&r->word);
2169				}
2170			} else {
2171				debug_printf_clean("&%d\n", r->dup);
2172			}
2173			rnext = r->next;
2174			free(r);
2175		}
2176		child->redirects = NULL;
2177	}
2178	free(pi->progs);   /* children are an array, they get freed all at once */
2179	pi->progs = NULL;
2180#if ENABLE_HUSH_JOB
2181	free(pi->cmdtext);
2182	pi->cmdtext = NULL;
2183#endif
2184	return ret_code;
2185}
2186
2187static int free_pipe_list(struct pipe *head, int indent)
2188{
2189	int rcode = 0;   /* if list has no members */
2190	struct pipe *pi, *next;
2191
2192	for (pi = head; pi; pi = next) {
2193		debug_printf_clean("%s pipe reserved mode %d\n", indenter(indent), pi->res_word);
2194		rcode = free_pipe(pi, indent);
2195		debug_printf_clean("%s pipe followup code %d\n", indenter(indent), pi->followup);
2196		next = pi->next;
2197		/*pi->next = NULL;*/
2198		free(pi);
2199	}
2200	return rcode;
2201}
2202
2203/* Select which version we will use */
2204static int run_list(struct pipe *pi)
2205{
2206	int rcode = 0;
2207	debug_printf_exec("run_list entered\n");
2208	if (fake_mode == 0) {
2209		debug_printf_exec(": run_list_real with %d members\n", pi->num_progs);
2210		rcode = run_list_real(pi);
2211	}
2212	/* free_pipe_list has the side effect of clearing memory.
2213	 * In the long run that function can be merged with run_list_real,
2214	 * but doing that now would hobble the debugging effort. */
2215	free_pipe_list(pi, 0);
2216	debug_printf_exec("run_list return %d\n", rcode);
2217	return rcode;
2218}
2219
2220static int globhack(const char *src, int flags, glob_t *pglob)
2221{
2222	int cnt = 0, pathc;
2223	const char *s;
2224	char *dest;
2225	for (cnt = 1, s = src; s && *s; s++) {
2226		if (*s == '\\') s++;
2227		cnt++;
2228	}
2229	dest = xmalloc(cnt);
2230	if (!(flags & GLOB_APPEND)) {
2231		pglob->gl_pathv = NULL;
2232		pglob->gl_pathc = 0;
2233		pglob->gl_offs = 0;
2234		pglob->gl_offs = 0;
2235	}
2236	pathc = ++pglob->gl_pathc;
2237	pglob->gl_pathv = xrealloc(pglob->gl_pathv, (pathc+1) * sizeof(*pglob->gl_pathv));
2238	pglob->gl_pathv[pathc-1] = dest;
2239	pglob->gl_pathv[pathc] = NULL;
2240	for (s = src; s && *s; s++, dest++) {
2241		if (*s == '\\') s++;
2242		*dest = *s;
2243	}
2244	*dest = '\0';
2245	return 0;
2246}
2247
2248static int glob_needed(const char *s)
2249{
2250	for (; *s; s++) {
2251		if (*s == '\\') s++;
2252		if (strchr("*[?", *s)) return 1;
2253	}
2254	return 0;
2255}
2256
2257static int xglob(o_string *dest, int flags, glob_t *pglob)
2258{
2259	int gr;
2260
2261	/* short-circuit for null word */
2262	/* we can code this better when the debug_printf's are gone */
2263	if (dest->length == 0) {
2264		if (dest->nonnull) {
2265			/* bash man page calls this an "explicit" null */
2266			gr = globhack(dest->data, flags, pglob);
2267			debug_printf("globhack returned %d\n", gr);
2268		} else {
2269			return 0;
2270		}
2271	} else if (glob_needed(dest->data)) {
2272		gr = glob(dest->data, flags, NULL, pglob);
2273		debug_printf("glob returned %d\n", gr);
2274		if (gr == GLOB_NOMATCH) {
2275			/* quote removal, or more accurately, backslash removal */
2276			gr = globhack(dest->data, flags, pglob);
2277			debug_printf("globhack returned %d\n", gr);
2278		}
2279	} else {
2280		gr = globhack(dest->data, flags, pglob);
2281		debug_printf("globhack returned %d\n", gr);
2282	}
2283	if (gr == GLOB_NOSPACE)
2284		bb_error_msg_and_die("out of memory during glob");
2285	if (gr != 0) { /* GLOB_ABORTED ? */
2286		bb_error_msg("glob(3) error %d", gr);
2287	}
2288	/* globprint(glob_target); */
2289	return gr;
2290}
2291
2292/* expand_strvec_to_strvec() takes a list of strings, expands
2293 * all variable references within and returns a pointer to
2294 * a list of expanded strings, possibly with larger number
2295 * of strings. (Think VAR="a b"; echo $VAR).
2296 * This new list is allocated as a single malloc block.
2297 * NULL-terminated list of char* pointers is at the beginning of it,
2298 * followed by strings themself.
2299 * Caller can deallocate entire list by single free(list). */
2300
2301/* Helpers first:
2302 * count_XXX estimates size of the block we need. It's okay
2303 * to over-estimate sizes a bit, if it makes code simpler */
2304static int count_ifs(const char *str)
2305{
2306	int cnt = 0;
2307	debug_printf_expand("count_ifs('%s') ifs='%s'", str, ifs);
2308	while (1) {
2309		str += strcspn(str, ifs);
2310		if (!*str) break;
2311		str++; /* str += strspn(str, ifs); */
2312		cnt++; /* cnt += strspn(str, ifs); - but this code is larger */
2313	}
2314	debug_printf_expand(" return %d\n", cnt);
2315	return cnt;
2316}
2317
2318static void count_var_expansion_space(int *countp, int *lenp, char *arg)
2319{
2320	char first_ch;
2321	int i;
2322	int len = *lenp;
2323	int count = *countp;
2324	const char *val;
2325	char *p;
2326
2327	while ((p = strchr(arg, SPECIAL_VAR_SYMBOL))) {
2328		len += p - arg;
2329		arg = ++p;
2330		p = strchr(p, SPECIAL_VAR_SYMBOL);
2331		first_ch = arg[0];
2332
2333		switch (first_ch & 0x7f) {
2334		/* high bit in 1st_ch indicates that var is double-quoted */
2335		case '$': /* pid */
2336		case '!': /* bg pid */
2337		case '?': /* exitcode */
2338		case '#': /* argc */
2339			len += sizeof(int)*3 + 1; /* enough for int */
2340			break;
2341		case '*':
2342		case '@':
2343			for (i = 1; i < global_argc; i++) {
2344				len += strlen(global_argv[i]) + 1;
2345				count++;
2346				if (!(first_ch & 0x80))
2347					count += count_ifs(global_argv[i]);
2348			}
2349			break;
2350		default:
2351			*p = '\0';
2352			arg[0] = first_ch & 0x7f;
2353			if (isdigit(arg[0])) {
2354				i = xatoi_u(arg);
2355				val = NULL;
2356				if (i < global_argc)
2357					val = global_argv[i];
2358			} else
2359				val = lookup_param(arg);
2360			arg[0] = first_ch;
2361			*p = SPECIAL_VAR_SYMBOL;
2362
2363			if (val) {
2364				len += strlen(val) + 1;
2365				if (!(first_ch & 0x80))
2366					count += count_ifs(val);
2367			}
2368		}
2369		arg = ++p;
2370	}
2371
2372	len += strlen(arg) + 1;
2373	count++;
2374	*lenp = len;
2375	*countp = count;
2376}
2377
2378/* Store given string, finalizing the word and starting new one whenever
2379 * we encounter ifs char(s). This is used for expanding variable values.
2380 * End-of-string does NOT finalize word: think about 'echo -$VAR-' */
2381static int expand_on_ifs(char **list, int n, char **posp, const char *str)
2382{
2383	char *pos = *posp;
2384	while (1) {
2385		int word_len = strcspn(str, ifs);
2386		if (word_len) {
2387			memcpy(pos, str, word_len); /* store non-ifs chars */
2388			pos += word_len;
2389			str += word_len;
2390		}
2391		if (!*str)  /* EOL - do not finalize word */
2392			break;
2393		*pos++ = '\0';
2394		if (n) debug_printf_expand("expand_on_ifs finalized list[%d]=%p '%s' "
2395			"strlen=%d next=%p pos=%p\n", n-1, list[n-1], list[n-1],
2396			strlen(list[n-1]), list[n-1] + strlen(list[n-1]) + 1, pos);
2397		list[n++] = pos;
2398		str += strspn(str, ifs); /* skip ifs chars */
2399	}
2400	*posp = pos;
2401	return n;
2402}
2403
2404/* Expand all variable references in given string, adding words to list[]
2405 * at n, n+1,... positions. Return updated n (so that list[n] is next one
2406 * to be filled). This routine is extremely tricky: has to deal with
2407 * variables/parameters with whitespace, $* and $@, and constructs like
2408 * 'echo -$*-'. If you play here, you must run testsuite afterwards! */
2409/* NB: another bug is that we cannot detect empty strings yet:
2410 * "" or $empty"" expands to zero words, has to expand to empty word */
2411static int expand_vars_to_list(char **list, int n, char **posp, char *arg, char or_mask)
2412{
2413	/* or_mask is either 0 (normal case) or 0x80
2414	 * (expansion of right-hand side of assignment == 1-element expand) */
2415
2416	char first_ch, ored_ch;
2417	int i;
2418	const char *val;
2419	char *p;
2420	char *pos = *posp;
2421
2422	ored_ch = 0;
2423
2424	if (n) debug_printf_expand("expand_vars_to_list finalized list[%d]=%p '%s' "
2425		"strlen=%d next=%p pos=%p\n", n-1, list[n-1], list[n-1],
2426		strlen(list[n-1]), list[n-1] + strlen(list[n-1]) + 1, pos);
2427	list[n++] = pos;
2428
2429	while ((p = strchr(arg, SPECIAL_VAR_SYMBOL))) {
2430		memcpy(pos, arg, p - arg);
2431		pos += (p - arg);
2432		arg = ++p;
2433		p = strchr(p, SPECIAL_VAR_SYMBOL);
2434
2435		first_ch = arg[0] | or_mask; /* forced to "quoted" if or_mask = 0x80 */
2436		ored_ch |= first_ch;
2437		val = NULL;
2438		switch (first_ch & 0x7f) {
2439		/* Highest bit in first_ch indicates that var is double-quoted */
2440		case '$': /* pid */
2441			val = utoa(getpid());
2442			break;
2443		case '!': /* bg pid */
2444			val = last_bg_pid ? utoa(last_bg_pid) : (char*)"";
2445			break;
2446		case '?': /* exitcode */
2447			val = utoa(last_return_code);
2448			break;
2449		case '#': /* argc */
2450			val = utoa(global_argc ? global_argc-1 : 0);
2451			break;
2452		case '*':
2453		case '@':
2454			i = 1;
2455			if (!(first_ch & 0x80)) { /* unquoted $* or $@ */
2456				while (i < global_argc) {
2457					n = expand_on_ifs(list, n, &pos, global_argv[i]);
2458					debug_printf_expand("expand_vars_to_list: argv %d (last %d)\n", i, global_argc-1);
2459					if (global_argv[i++][0] && i < global_argc) {
2460						/* this argv[] is not empty and not last:
2461						 * put terminating NUL, start new word */
2462						*pos++ = '\0';
2463						if (n) debug_printf_expand("expand_vars_to_list 2 finalized list[%d]=%p '%s' "
2464							"strlen=%d next=%p pos=%p\n", n-1, list[n-1], list[n-1],
2465							strlen(list[n-1]), list[n-1] + strlen(list[n-1]) + 1, pos);
2466						list[n++] = pos;
2467					}
2468				}
2469			} else
2470			/* If or_mask is nonzero, we handle assignment 'a=....$@.....'
2471			 * and in this case should theat it like '$*' */
2472			if (first_ch == ('@'|0x80) && !or_mask) { /* quoted $@ */
2473				while (1) {
2474					strcpy(pos, global_argv[i]);
2475					pos += strlen(global_argv[i]);
2476					if (++i >= global_argc)
2477						break;
2478					*pos++ = '\0';
2479					if (n) debug_printf_expand("expand_vars_to_list 3 finalized list[%d]=%p '%s' "
2480						"strlen=%d next=%p pos=%p\n", n-1, list[n-1], list[n-1],
2481							strlen(list[n-1]), list[n-1] + strlen(list[n-1]) + 1, pos);
2482					list[n++] = pos;
2483				}
2484			} else { /* quoted $*: add as one word */
2485				while (1) {
2486					strcpy(pos, global_argv[i]);
2487					pos += strlen(global_argv[i]);
2488					if (++i >= global_argc)
2489						break;
2490					if (ifs[0])
2491						*pos++ = ifs[0];
2492				}
2493			}
2494			break;
2495		default:
2496			*p = '\0';
2497			arg[0] = first_ch & 0x7f;
2498			if (isdigit(arg[0])) {
2499				i = xatoi_u(arg);
2500				val = NULL;
2501				if (i < global_argc)
2502					val = global_argv[i];
2503			} else
2504				val = lookup_param(arg);
2505			arg[0] = first_ch;
2506			*p = SPECIAL_VAR_SYMBOL;
2507			if (!(first_ch & 0x80)) { /* unquoted $VAR */
2508				if (val) {
2509					n = expand_on_ifs(list, n, &pos, val);
2510					val = NULL;
2511				}
2512			} /* else: quoted $VAR, val will be appended at pos */
2513		}
2514		if (val) {
2515			strcpy(pos, val);
2516			pos += strlen(val);
2517		}
2518		arg = ++p;
2519	}
2520	debug_printf_expand("expand_vars_to_list adding tail '%s' at %p\n", arg, pos);
2521	strcpy(pos, arg);
2522	pos += strlen(arg) + 1;
2523	if (pos == list[n-1] + 1) { /* expansion is empty */
2524		if (!(ored_ch & 0x80)) { /* all vars were not quoted... */
2525			debug_printf_expand("expand_vars_to_list list[%d] empty, going back\n", n);
2526			pos--;
2527			n--;
2528		}
2529	}
2530
2531	*posp = pos;
2532	return n;
2533}
2534
2535static char **expand_variables(char **argv, char or_mask)
2536{
2537	int n;
2538	int count = 1;
2539	int len = 0;
2540	char *pos, **v, **list;
2541
2542	v = argv;
2543	if (!*v) debug_printf_expand("count_var_expansion_space: "
2544			"argv[0]=NULL count=%d len=%d alloc_space=%d\n",
2545			count, len, sizeof(char*) * count + len);
2546	while (*v) {
2547		count_var_expansion_space(&count, &len, *v);
2548		debug_printf_expand("count_var_expansion_space: "
2549			"'%s' count=%d len=%d alloc_space=%d\n",
2550			*v, count, len, sizeof(char*) * count + len);
2551		v++;
2552	}
2553	len += sizeof(char*) * count; /* total to alloc */
2554	list = xmalloc(len);
2555	pos = (char*)(list + count);
2556	debug_printf_expand("list=%p, list[0] should be %p\n", list, pos);
2557	n = 0;
2558	v = argv;
2559	while (*v)
2560		n = expand_vars_to_list(list, n, &pos, *v++, or_mask);
2561
2562	if (n) debug_printf_expand("finalized list[%d]=%p '%s' "
2563		"strlen=%d next=%p pos=%p\n", n-1, list[n-1], list[n-1],
2564		strlen(list[n-1]), list[n-1] + strlen(list[n-1]) + 1, pos);
2565	list[n] = NULL;
2566
2567#ifdef DEBUG_EXPAND
2568	{
2569		int m = 0;
2570		while (m <= n) {
2571			debug_printf_expand("list[%d]=%p '%s'\n", m, list[m], list[m]);
2572			m++;
2573		}
2574		debug_printf_expand("used_space=%d\n", pos - (char*)list);
2575	}
2576#endif
2577	if (ENABLE_HUSH_DEBUG)
2578		if (pos - (char*)list > len)
2579			bb_error_msg_and_die("BUG in varexp");
2580	return list;
2581}
2582
2583static char **expand_strvec_to_strvec(char **argv)
2584{
2585	return expand_variables(argv, 0);
2586}
2587
2588static char *expand_string_to_string(const char *str)
2589{
2590	char *argv[2], **list;
2591
2592	argv[0] = (char*)str;
2593	argv[1] = NULL;
2594	list = expand_variables(argv, 0x80); /* 0x80: make one-element expansion */
2595	if (ENABLE_HUSH_DEBUG)
2596		if (!list[0] || list[1])
2597			bb_error_msg_and_die("BUG in varexp2");
2598	/* actually, just move string 2*sizeof(char*) bytes back */
2599	strcpy((char*)list, list[0]);
2600	debug_printf_expand("string_to_string='%s'\n", (char*)list);
2601	return (char*)list;
2602}
2603
2604static char* expand_strvec_to_string(char **argv)
2605{
2606	char **list;
2607
2608	list = expand_variables(argv, 0x80);
2609	/* Convert all NULs to spaces */
2610	if (list[0]) {
2611		int n = 1;
2612		while (list[n]) {
2613			if (ENABLE_HUSH_DEBUG)
2614				if (list[n-1] + strlen(list[n-1]) + 1 != list[n])
2615					bb_error_msg_and_die("BUG in varexp3");
2616			list[n][-1] = ' '; /* TODO: or to ifs[0]? */
2617			n++;
2618		}
2619	}
2620	strcpy((char*)list, list[0]);
2621	debug_printf_expand("strvec_to_string='%s'\n", (char*)list);
2622	return (char*)list;
2623}
2624
2625/* This is used to get/check local shell variables */
2626static struct variable *get_local_var(const char *name)
2627{
2628	struct variable *cur;
2629	int len;
2630
2631	if (!name)
2632		return NULL;
2633	len = strlen(name);
2634	for (cur = top_var; cur; cur = cur->next) {
2635		if (strncmp(cur->varstr, name, len) == 0 && cur->varstr[len] == '=')
2636			return cur;
2637	}
2638	return NULL;
2639}
2640
2641/* str holds "NAME=VAL" and is expected to be malloced.
2642 * We take ownership of it. */
2643static int set_local_var(char *str, int flg_export)
2644{
2645	struct variable *cur;
2646	char *value;
2647	int name_len;
2648
2649	value = strchr(str, '=');
2650	if (!value) { /* not expected to ever happen? */
2651		free(str);
2652		return -1;
2653	}
2654
2655	name_len = value - str + 1; /* including '=' */
2656	cur = top_var; /* cannot be NULL (we have HUSH_VERSION and it's RO) */
2657	while (1) {
2658		if (strncmp(cur->varstr, str, name_len) != 0) {
2659			if (!cur->next) {
2660				/* Bail out. Note that now cur points
2661				 * to last var in linked list */
2662				break;
2663			}
2664			cur = cur->next;
2665			continue;
2666		}
2667		/* We found an existing var with this name */
2668		*value = '\0';
2669		if (cur->flg_read_only) {
2670			bb_error_msg("%s: readonly variable", str);
2671			free(str);
2672			return -1;
2673		}
2674		unsetenv(str); /* just in case */
2675		*value = '=';
2676		if (strcmp(cur->varstr, str) == 0) {
2677 free_and_exp:
2678			free(str);
2679			goto exp;
2680		}
2681		if (cur->max_len >= strlen(str)) {
2682			/* This one is from startup env, reuse space */
2683			strcpy(cur->varstr, str);
2684			goto free_and_exp;
2685		}
2686		/* max_len == 0 signifies "malloced" var, which we can
2687		 * (and has to) free */
2688		if (!cur->max_len)
2689			free(cur->varstr);
2690		cur->max_len = 0;
2691		goto set_str_and_exp;
2692	}
2693
2694	/* Not found - create next variable struct */
2695	cur->next = xzalloc(sizeof(*cur));
2696	cur = cur->next;
2697
2698 set_str_and_exp:
2699	cur->varstr = str;
2700 exp:
2701	if (flg_export)
2702		cur->flg_export = 1;
2703	if (cur->flg_export)
2704		return putenv(cur->varstr);
2705	return 0;
2706}
2707
2708static void unset_local_var(const char *name)
2709{
2710	struct variable *cur;
2711	struct variable *prev = prev; /* for gcc */
2712	int name_len;
2713
2714	if (!name)
2715		return;
2716	name_len = strlen(name);
2717	cur = top_var;
2718	while (cur) {
2719		if (strncmp(cur->varstr, name, name_len) == 0 && cur->varstr[name_len] == '=') {
2720			if (cur->flg_read_only) {
2721				bb_error_msg("%s: readonly variable", name);
2722				return;
2723			}
2724		/* prev is ok to use here because 1st variable, HUSH_VERSION,
2725		 * is ro, and we cannot reach this code on the 1st pass */
2726			prev->next = cur->next;
2727			unsetenv(cur->varstr);
2728			if (!cur->max_len)
2729				free(cur->varstr);
2730			free(cur);
2731			return;
2732		}
2733		prev = cur;
2734		cur = cur->next;
2735	}
2736}
2737
2738static int is_assignment(const char *s)
2739{
2740	if (!s || !isalpha(*s))
2741		return 0;
2742	s++;
2743	while (isalnum(*s) || *s == '_')
2744		s++;
2745	return *s == '=';
2746}
2747
2748/* the src parameter allows us to peek forward to a possible &n syntax
2749 * for file descriptor duplication, e.g., "2>&1".
2750 * Return code is 0 normally, 1 if a syntax error is detected in src.
2751 * Resource errors (in xmalloc) cause the process to exit */
2752static int setup_redirect(struct p_context *ctx, int fd, redir_type style,
2753	struct in_str *input)
2754{
2755	struct child_prog *child = ctx->child;
2756	struct redir_struct *redir = child->redirects;
2757	struct redir_struct *last_redir = NULL;
2758
2759	/* Create a new redir_struct and drop it onto the end of the linked list */
2760	while (redir) {
2761		last_redir = redir;
2762		redir = redir->next;
2763	}
2764	redir = xmalloc(sizeof(struct redir_struct));
2765	redir->next = NULL;
2766	redir->word.gl_pathv = NULL;
2767	if (last_redir) {
2768		last_redir->next = redir;
2769	} else {
2770		child->redirects = redir;
2771	}
2772
2773	redir->type = style;
2774	redir->fd = (fd == -1) ? redir_table[style].default_fd : fd;
2775
2776	debug_printf("Redirect type %d%s\n", redir->fd, redir_table[style].descrip);
2777
2778	/* Check for a '2>&1' type redirect */
2779	redir->dup = redirect_dup_num(input);
2780	if (redir->dup == -2) return 1;  /* syntax error */
2781	if (redir->dup != -1) {
2782		/* Erik had a check here that the file descriptor in question
2783		 * is legit; I postpone that to "run time"
2784		 * A "-" representation of "close me" shows up as a -3 here */
2785		debug_printf("Duplicating redirect '%d>&%d'\n", redir->fd, redir->dup);
2786	} else {
2787		/* We do _not_ try to open the file that src points to,
2788		 * since we need to return and let src be expanded first.
2789		 * Set ctx->pending_redirect, so we know what to do at the
2790		 * end of the next parsed word. */
2791		ctx->pending_redirect = redir;
2792	}
2793	return 0;
2794}
2795
2796static struct pipe *new_pipe(void)
2797{
2798	struct pipe *pi;
2799	pi = xzalloc(sizeof(struct pipe));
2800	/*pi->num_progs = 0;*/
2801	/*pi->progs = NULL;*/
2802	/*pi->next = NULL;*/
2803	/*pi->followup = 0;  invalid */
2804	if (RES_NONE)
2805		pi->res_word = RES_NONE;
2806	return pi;
2807}
2808
2809static void initialize_context(struct p_context *ctx)
2810{
2811	ctx->child = NULL;
2812	ctx->pipe = ctx->list_head = new_pipe();
2813	ctx->pending_redirect = NULL;
2814	ctx->res_w = RES_NONE;
2815	//only ctx->parse_type is not touched... is this intentional?
2816	ctx->old_flag = 0;
2817	ctx->stack = NULL;
2818	done_command(ctx);   /* creates the memory for working child */
2819}
2820
2821/* normal return is 0
2822 * if a reserved word is found, and processed, return 1
2823 * should handle if, then, elif, else, fi, for, while, until, do, done.
2824 * case, function, and select are obnoxious, save those for later.
2825 */
2826#if ENABLE_HUSH_IF || ENABLE_HUSH_LOOPS
2827static int reserved_word(o_string *dest, struct p_context *ctx)
2828{
2829	struct reserved_combo {
2830		char literal[7];
2831		unsigned char code;
2832		int flag;
2833	};
2834	/* Mostly a list of accepted follow-up reserved words.
2835	 * FLAG_END means we are done with the sequence, and are ready
2836	 * to turn the compound list into a command.
2837	 * FLAG_START means the word must start a new compound list.
2838	 */
2839	static const struct reserved_combo reserved_list[] = {
2840#if ENABLE_HUSH_IF
2841		{ "if",    RES_IF,    FLAG_THEN | FLAG_START },
2842		{ "then",  RES_THEN,  FLAG_ELIF | FLAG_ELSE | FLAG_FI },
2843		{ "elif",  RES_ELIF,  FLAG_THEN },
2844		{ "else",  RES_ELSE,  FLAG_FI   },
2845		{ "fi",    RES_FI,    FLAG_END  },
2846#endif
2847#if ENABLE_HUSH_LOOPS
2848		{ "for",   RES_FOR,   FLAG_IN   | FLAG_START },
2849		{ "while", RES_WHILE, FLAG_DO   | FLAG_START },
2850		{ "until", RES_UNTIL, FLAG_DO   | FLAG_START },
2851		{ "in",    RES_IN,    FLAG_DO   },
2852		{ "do",    RES_DO,    FLAG_DONE },
2853		{ "done",  RES_DONE,  FLAG_END  }
2854#endif
2855	};
2856
2857	const struct reserved_combo *r;
2858
2859	for (r = reserved_list;	r < reserved_list + ARRAY_SIZE(reserved_list); r++) {
2860		if (strcmp(dest->data, r->literal) != 0)
2861			continue;
2862		debug_printf("found reserved word %s, code %d\n", r->literal, r->code);
2863		if (r->flag & FLAG_START) {
2864			struct p_context *new;
2865			debug_printf("push stack\n");
2866#if ENABLE_HUSH_LOOPS
2867			if (ctx->res_w == RES_IN || ctx->res_w == RES_FOR) {
2868				syntax("malformed for"); /* example: 'for if' */
2869				ctx->res_w = RES_SNTX;
2870				b_reset(dest);
2871				return 1;
2872			}
2873#endif
2874			new = xmalloc(sizeof(*new));
2875			*new = *ctx;   /* physical copy */
2876			initialize_context(ctx);
2877			ctx->stack = new;
2878		} else if (ctx->res_w == RES_NONE || !(ctx->old_flag & (1 << r->code))) {
2879			syntax(NULL);
2880			ctx->res_w = RES_SNTX;
2881			b_reset(dest);
2882			return 1;
2883		}
2884		ctx->res_w = r->code;
2885		ctx->old_flag = r->flag;
2886		if (ctx->old_flag & FLAG_END) {
2887			struct p_context *old;
2888			debug_printf("pop stack\n");
2889			done_pipe(ctx, PIPE_SEQ);
2890			old = ctx->stack;
2891			old->child->group = ctx->list_head;
2892			old->child->subshell = 0;
2893			*ctx = *old;   /* physical copy */
2894			free(old);
2895		}
2896		b_reset(dest);
2897		return 1;
2898	}
2899	return 0;
2900}
2901#else
2902#define reserved_word(dest, ctx) ((int)0)
2903#endif
2904
2905/* Normal return is 0.
2906 * Syntax or xglob errors return 1. */
2907static int done_word(o_string *dest, struct p_context *ctx)
2908{
2909	struct child_prog *child = ctx->child;
2910	glob_t *glob_target;
2911	int gr, flags = 0;
2912
2913	debug_printf_parse("done_word entered: '%s' %p\n", dest->data, child);
2914	if (dest->length == 0 && !dest->nonnull) {
2915		debug_printf_parse("done_word return 0: true null, ignored\n");
2916		return 0;
2917	}
2918	if (ctx->pending_redirect) {
2919		glob_target = &ctx->pending_redirect->word;
2920	} else {
2921		if (child->group) {
2922			syntax(NULL);
2923			debug_printf_parse("done_word return 1: syntax error, groups and arglists don't mix\n");
2924			return 1;
2925		}
2926		if (!child->argv && (ctx->parse_type & PARSEFLAG_SEMICOLON)) {
2927			debug_printf_parse(": checking '%s' for reserved-ness\n", dest->data);
2928			if (reserved_word(dest, ctx)) {
2929				debug_printf_parse("done_word return %d\n", (ctx->res_w == RES_SNTX));
2930				return (ctx->res_w == RES_SNTX);
2931			}
2932		}
2933		glob_target = &child->glob_result;
2934		if (child->argv)
2935			flags |= GLOB_APPEND;
2936	}
2937	gr = xglob(dest, flags, glob_target);
2938	if (gr != 0) {
2939		debug_printf_parse("done_word return 1: xglob returned %d\n", gr);
2940		return 1;
2941	}
2942
2943	b_reset(dest);
2944	if (ctx->pending_redirect) {
2945		ctx->pending_redirect = NULL;
2946		if (glob_target->gl_pathc != 1) {
2947			bb_error_msg("ambiguous redirect");
2948			debug_printf_parse("done_word return 1: ambiguous redirect\n");
2949			return 1;
2950		}
2951	} else {
2952		child->argv = glob_target->gl_pathv;
2953	}
2954#if ENABLE_HUSH_LOOPS
2955	if (ctx->res_w == RES_FOR) {
2956		done_word(dest, ctx);
2957		done_pipe(ctx, PIPE_SEQ);
2958	}
2959#endif
2960	debug_printf_parse("done_word return 0\n");
2961	return 0;
2962}
2963
2964/* The only possible error here is out of memory, in which case
2965 * xmalloc exits. */
2966static int done_command(struct p_context *ctx)
2967{
2968	/* The child is really already in the pipe structure, so
2969	 * advance the pipe counter and make a new, null child. */
2970	struct pipe *pi = ctx->pipe;
2971	struct child_prog *child = ctx->child;
2972
2973	if (child) {
2974		if (child->group == NULL
2975		 && child->argv == NULL
2976		 && child->redirects == NULL
2977		) {
2978			debug_printf_parse("done_command: skipping null cmd, num_progs=%d\n", pi->num_progs);
2979			return pi->num_progs;
2980		}
2981		pi->num_progs++;
2982		debug_printf_parse("done_command: ++num_progs=%d\n", pi->num_progs);
2983	} else {
2984		debug_printf_parse("done_command: initializing, num_progs=%d\n", pi->num_progs);
2985	}
2986
2987	/* Only real trickiness here is that the uncommitted
2988	 * child structure is not counted in pi->num_progs. */
2989	pi->progs = xrealloc(pi->progs, sizeof(*pi->progs) * (pi->num_progs+1));
2990	child = &pi->progs[pi->num_progs];
2991
2992	memset(child, 0, sizeof(*child));
2993	/*child->redirects = NULL;*/
2994	/*child->argv = NULL;*/
2995	/*child->is_stopped = 0;*/
2996	/*child->group = NULL;*/
2997	/*child->glob_result.gl_pathv = NULL;*/
2998	child->family = pi;
2999	//sp: /*child->sp = 0;*/
3000	//pt: child->parse_type = ctx->parse_type;
3001
3002	ctx->child = child;
3003	/* but ctx->pipe and ctx->list_head remain unchanged */
3004
3005	return pi->num_progs; /* used only for 0/nonzero check */
3006}
3007
3008static int done_pipe(struct p_context *ctx, pipe_style type)
3009{
3010	struct pipe *new_p;
3011	int not_null;
3012
3013	debug_printf_parse("done_pipe entered, followup %d\n", type);
3014	not_null = done_command(ctx);  /* implicit closure of previous command */
3015	ctx->pipe->followup = type;
3016	ctx->pipe->res_word = ctx->res_w;
3017	/* Without this check, even just <enter> on command line generates
3018	 * tree of three NOPs (!). Which is harmless but annoying.
3019	 * IOW: it is safe to do it unconditionally. */
3020	if (not_null) {
3021		new_p = new_pipe();
3022		ctx->pipe->next = new_p;
3023		ctx->pipe = new_p;
3024		ctx->child = NULL;
3025		done_command(ctx);  /* set up new pipe to accept commands */
3026	}
3027	debug_printf_parse("done_pipe return 0\n");
3028	return 0;
3029}
3030
3031/* peek ahead in the in_str to find out if we have a "&n" construct,
3032 * as in "2>&1", that represents duplicating a file descriptor.
3033 * returns either -2 (syntax error), -1 (no &), or the number found.
3034 */
3035static int redirect_dup_num(struct in_str *input)
3036{
3037	int ch, d = 0, ok = 0;
3038	ch = b_peek(input);
3039	if (ch != '&') return -1;
3040
3041	b_getch(input);  /* get the & */
3042	ch = b_peek(input);
3043	if (ch == '-') {
3044		b_getch(input);
3045		return -3;  /* "-" represents "close me" */
3046	}
3047	while (isdigit(ch)) {
3048		d = d*10 + (ch-'0');
3049		ok = 1;
3050		b_getch(input);
3051		ch = b_peek(input);
3052	}
3053	if (ok) return d;
3054
3055	bb_error_msg("ambiguous redirect");
3056	return -2;
3057}
3058
3059/* If a redirect is immediately preceded by a number, that number is
3060 * supposed to tell which file descriptor to redirect.  This routine
3061 * looks for such preceding numbers.  In an ideal world this routine
3062 * needs to handle all the following classes of redirects...
3063 *     echo 2>foo     # redirects fd  2 to file "foo", nothing passed to echo
3064 *     echo 49>foo    # redirects fd 49 to file "foo", nothing passed to echo
3065 *     echo -2>foo    # redirects fd  1 to file "foo",    "-2" passed to echo
3066 *     echo 49x>foo   # redirects fd  1 to file "foo",   "49x" passed to echo
3067 * A -1 output from this program means no valid number was found, so the
3068 * caller should use the appropriate default for this redirection.
3069 */
3070static int redirect_opt_num(o_string *o)
3071{
3072	int num;
3073
3074	if (o->length == 0)
3075		return -1;
3076	for (num = 0; num < o->length; num++) {
3077		if (!isdigit(*(o->data + num))) {
3078			return -1;
3079		}
3080	}
3081	/* reuse num (and save an int) */
3082	num = atoi(o->data);
3083	b_reset(o);
3084	return num;
3085}
3086
3087#if ENABLE_HUSH_TICK
3088static FILE *generate_stream_from_list(struct pipe *head)
3089{
3090	FILE *pf;
3091	int pid, channel[2];
3092
3093	xpipe(channel);
3094#if BB_MMU
3095	pid = fork();
3096#else
3097	pid = vfork();
3098#endif
3099	if (pid < 0) {
3100		bb_perror_msg_and_die("fork");
3101	} else if (pid == 0) {
3102		close(channel[0]);
3103		if (channel[1] != 1) {
3104			dup2(channel[1], 1);
3105			close(channel[1]);
3106		}
3107		/* Prevent it from trying to handle ctrl-z etc */
3108#if ENABLE_HUSH_JOB
3109		run_list_level = 1;
3110#endif
3111		/* Process substitution is not considered to be usual
3112		 * 'command execution'.
3113		 * SUSv3 says ctrl-Z should be ignored, ctrl-C should not. */
3114		/* Not needed, we are relying on it being disabled
3115		 * everywhere outside actual command execution. */
3116		/*set_jobctrl_sighandler(SIG_IGN);*/
3117		set_misc_sighandler(SIG_DFL);
3118		_exit(run_list_real(head));   /* leaks memory */
3119	}
3120	close(channel[1]);
3121	pf = fdopen(channel[0], "r");
3122	return pf;
3123}
3124
3125/* Return code is exit status of the process that is run. */
3126static int process_command_subs(o_string *dest, struct p_context *ctx,
3127	struct in_str *input, const char *subst_end)
3128{
3129	int retcode, ch, eol_cnt;
3130	o_string result = NULL_O_STRING;
3131	struct p_context inner;
3132	FILE *p;
3133	struct in_str pipe_str;
3134
3135	initialize_context(&inner);
3136
3137	/* recursion to generate command */
3138	retcode = parse_stream(&result, &inner, input, subst_end);
3139	if (retcode != 0)
3140		return retcode;  /* syntax error or EOF */
3141	done_word(&result, &inner);
3142	done_pipe(&inner, PIPE_SEQ);
3143	b_free(&result);
3144
3145	p = generate_stream_from_list(inner.list_head);
3146	if (p == NULL) return 1;
3147	mark_open(fileno(p));
3148	setup_file_in_str(&pipe_str, p);
3149
3150	/* now send results of command back into original context */
3151	eol_cnt = 0;
3152	while ((ch = b_getch(&pipe_str)) != EOF) {
3153		if (ch == '\n') {
3154			eol_cnt++;
3155			continue;
3156		}
3157		while (eol_cnt) {
3158			b_addqchr(dest, '\n', dest->quote);
3159			eol_cnt--;
3160		}
3161		b_addqchr(dest, ch, dest->quote);
3162	}
3163
3164	debug_printf("done reading from pipe, pclose()ing\n");
3165	/* This is the step that wait()s for the child.  Should be pretty
3166	 * safe, since we just read an EOF from its stdout.  We could try
3167	 * to do better, by using wait(), and keeping track of background jobs
3168	 * at the same time.  That would be a lot of work, and contrary
3169	 * to the KISS philosophy of this program. */
3170	mark_closed(fileno(p));
3171	retcode = fclose(p);
3172	free_pipe_list(inner.list_head, 0);
3173	debug_printf("closed FILE from child, retcode=%d\n", retcode);
3174	return retcode;
3175}
3176#endif
3177
3178static int parse_group(o_string *dest, struct p_context *ctx,
3179	struct in_str *input, int ch)
3180{
3181	int rcode;
3182	const char *endch = NULL;
3183	struct p_context sub;
3184	struct child_prog *child = ctx->child;
3185
3186	debug_printf_parse("parse_group entered\n");
3187	if (child->argv) {
3188		syntax(NULL);
3189		debug_printf_parse("parse_group return 1: syntax error, groups and arglists don't mix\n");
3190		return 1;
3191	}
3192	initialize_context(&sub);
3193	endch = "}";
3194	if (ch == '(') {
3195		endch = ")";
3196		child->subshell = 1;
3197	}
3198	rcode = parse_stream(dest, &sub, input, endch);
3199//vda: err chk?
3200	done_word(dest, &sub); /* finish off the final word in the subcontext */
3201	done_pipe(&sub, PIPE_SEQ);  /* and the final command there, too */
3202	child->group = sub.list_head;
3203
3204	debug_printf_parse("parse_group return %d\n", rcode);
3205	return rcode;
3206	/* child remains "open", available for possible redirects */
3207}
3208
3209/* Basically useful version until someone wants to get fancier,
3210 * see the bash man page under "Parameter Expansion" */
3211static const char *lookup_param(const char *src)
3212{
3213	struct variable *var = get_local_var(src);
3214	if (var)
3215		return strchr(var->varstr, '=') + 1;
3216	return NULL;
3217}
3218
3219/* return code: 0 for OK, 1 for syntax error */
3220static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *input)
3221{
3222	int ch = b_peek(input);  /* first character after the $ */
3223	unsigned char quote_mask = dest->quote ? 0x80 : 0;
3224
3225	debug_printf_parse("handle_dollar entered: ch='%c'\n", ch);
3226	if (isalpha(ch)) {
3227		b_addchr(dest, SPECIAL_VAR_SYMBOL);
3228		//sp: ctx->child->sp++;
3229		while (1) {
3230			debug_printf_parse(": '%c'\n", ch);
3231			b_getch(input);
3232			b_addchr(dest, ch | quote_mask);
3233			quote_mask = 0;
3234			ch = b_peek(input);
3235			if (!isalnum(ch) && ch != '_')
3236				break;
3237		}
3238		b_addchr(dest, SPECIAL_VAR_SYMBOL);
3239	} else if (isdigit(ch)) {
3240 make_one_char_var:
3241		b_addchr(dest, SPECIAL_VAR_SYMBOL);
3242		//sp: ctx->child->sp++;
3243		debug_printf_parse(": '%c'\n", ch);
3244		b_getch(input);
3245		b_addchr(dest, ch | quote_mask);
3246		b_addchr(dest, SPECIAL_VAR_SYMBOL);
3247	} else switch (ch) {
3248		case '$': /* pid */
3249		case '!': /* last bg pid */
3250		case '?': /* last exit code */
3251		case '#': /* number of args */
3252		case '*': /* args */
3253		case '@': /* args */
3254			goto make_one_char_var;
3255		case '{':
3256			b_addchr(dest, SPECIAL_VAR_SYMBOL);
3257			//sp: ctx->child->sp++;
3258			b_getch(input);
3259			while (1) {
3260				ch = b_getch(input);
3261				if (ch == '}')
3262					break;
3263				if (!isalnum(ch) && ch != '_') {
3264					syntax("unterminated ${name}");
3265					debug_printf_parse("handle_dollar return 1: unterminated ${name}\n");
3266					return 1;
3267				}
3268				debug_printf_parse(": '%c'\n", ch);
3269				b_addchr(dest, ch | quote_mask);
3270				quote_mask = 0;
3271			}
3272			b_addchr(dest, SPECIAL_VAR_SYMBOL);
3273			break;
3274#if ENABLE_HUSH_TICK
3275		case '(':
3276			b_getch(input);
3277			process_command_subs(dest, ctx, input, ")");
3278			break;
3279#endif
3280		case '-':
3281		case '_':
3282			/* still unhandled, but should be eventually */
3283			bb_error_msg("unhandled syntax: $%c", ch);
3284			return 1;
3285			break;
3286		default:
3287			b_addqchr(dest, '$', dest->quote);
3288	}
3289	debug_printf_parse("handle_dollar return 0\n");
3290	return 0;
3291}
3292
3293/* return code is 0 for normal exit, 1 for syntax error */
3294static int parse_stream(o_string *dest, struct p_context *ctx,
3295	struct in_str *input, const char *end_trigger)
3296{
3297	int ch, m;
3298	int redir_fd;
3299	redir_type redir_style;
3300	int next;
3301
3302	/* Only double-quote state is handled in the state variable dest->quote.
3303	 * A single-quote triggers a bypass of the main loop until its mate is
3304	 * found.  When recursing, quote state is passed in via dest->quote. */
3305
3306	debug_printf_parse("parse_stream entered, end_trigger='%s'\n", end_trigger);
3307
3308	while (1) {
3309		m = CHAR_IFS;
3310		next = '\0';
3311		ch = b_getch(input);
3312		if (ch != EOF) {
3313			m = charmap[ch];
3314			if (ch != '\n')
3315				next = b_peek(input);
3316		}
3317		debug_printf_parse(": ch=%c (%d) m=%d quote=%d\n",
3318						ch, ch, m, dest->quote);
3319		if (m == CHAR_ORDINARY
3320		 || (m != CHAR_SPECIAL && dest->quote)
3321		) {
3322			if (ch == EOF) {
3323				syntax("unterminated \"");
3324				debug_printf_parse("parse_stream return 1: unterminated \"\n");
3325				return 1;
3326			}
3327			b_addqchr(dest, ch, dest->quote);
3328			continue;
3329		}
3330		if (m == CHAR_IFS) {
3331			if (done_word(dest, ctx)) {
3332				debug_printf_parse("parse_stream return 1: done_word!=0\n");
3333				return 1;
3334			}
3335			if (ch == EOF)
3336				break;
3337			/* If we aren't performing a substitution, treat
3338			 * a newline as a command separator.
3339			 * [why we don't handle it exactly like ';'? --vda] */
3340			if (end_trigger && ch == '\n') {
3341				done_pipe(ctx, PIPE_SEQ);
3342			}
3343		}
3344		if ((end_trigger && strchr(end_trigger, ch))
3345		 && !dest->quote && ctx->res_w == RES_NONE
3346		) {
3347			debug_printf_parse("parse_stream return 0: end_trigger char found\n");
3348			return 0;
3349		}
3350		if (m == CHAR_IFS)
3351			continue;
3352		switch (ch) {
3353		case '#':
3354			if (dest->length == 0 && !dest->quote) {
3355				while (1) {
3356					ch = b_peek(input);
3357					if (ch == EOF || ch == '\n')
3358						break;
3359					b_getch(input);
3360				}
3361			} else {
3362				b_addqchr(dest, ch, dest->quote);
3363			}
3364			break;
3365		case '\\':
3366			if (next == EOF) {
3367				syntax("\\<eof>");
3368				debug_printf_parse("parse_stream return 1: \\<eof>\n");
3369				return 1;
3370			}
3371			b_addqchr(dest, '\\', dest->quote);
3372			b_addqchr(dest, b_getch(input), dest->quote);
3373			break;
3374		case '$':
3375			if (handle_dollar(dest, ctx, input) != 0) {
3376				debug_printf_parse("parse_stream return 1: handle_dollar returned non-0\n");
3377				return 1;
3378			}
3379			break;
3380		case '\'':
3381			dest->nonnull = 1;
3382			while (1) {
3383				ch = b_getch(input);
3384				if (ch == EOF || ch == '\'')
3385					break;
3386				b_addchr(dest, ch);
3387			}
3388			if (ch == EOF) {
3389				syntax("unterminated '");
3390				debug_printf_parse("parse_stream return 1: unterminated '\n");
3391				return 1;
3392			}
3393			break;
3394		case '"':
3395			dest->nonnull = 1;
3396			dest->quote = !dest->quote;
3397			break;
3398#if ENABLE_HUSH_TICK
3399		case '`':
3400			process_command_subs(dest, ctx, input, "`");
3401			break;
3402#endif
3403		case '>':
3404			redir_fd = redirect_opt_num(dest);
3405			done_word(dest, ctx);
3406			redir_style = REDIRECT_OVERWRITE;
3407			if (next == '>') {
3408				redir_style = REDIRECT_APPEND;
3409				b_getch(input);
3410			}
3411			setup_redirect(ctx, redir_fd, redir_style, input);
3412			break;
3413		case '<':
3414			redir_fd = redirect_opt_num(dest);
3415			done_word(dest, ctx);
3416			redir_style = REDIRECT_INPUT;
3417			if (next == '<') {
3418				redir_style = REDIRECT_HEREIS;
3419				b_getch(input);
3420			} else if (next == '>') {
3421				redir_style = REDIRECT_IO;
3422				b_getch(input);
3423			}
3424			setup_redirect(ctx, redir_fd, redir_style, input);
3425			break;
3426		case ';':
3427			done_word(dest, ctx);
3428			done_pipe(ctx, PIPE_SEQ);
3429			break;
3430		case '&':
3431			done_word(dest, ctx);
3432			if (next == '&') {
3433				b_getch(input);
3434				done_pipe(ctx, PIPE_AND);
3435			} else {
3436				done_pipe(ctx, PIPE_BG);
3437			}
3438			break;
3439		case '|':
3440			done_word(dest, ctx);
3441			if (next == '|') {
3442				b_getch(input);
3443				done_pipe(ctx, PIPE_OR);
3444			} else {
3445				/* we could pick up a file descriptor choice here
3446				 * with redirect_opt_num(), but bash doesn't do it.
3447				 * "echo foo 2| cat" yields "foo 2". */
3448				done_command(ctx);
3449			}
3450			break;
3451		case '(':
3452		case '{':
3453			if (parse_group(dest, ctx, input, ch) != 0) {
3454				debug_printf_parse("parse_stream return 1: parse_group returned non-0\n");
3455				return 1;
3456			}
3457			break;
3458		case ')':
3459		case '}':
3460			syntax("unexpected }");   /* Proper use of this character is caught by end_trigger */
3461			debug_printf_parse("parse_stream return 1: unexpected '}'\n");
3462			return 1;
3463		default:
3464			if (ENABLE_HUSH_DEBUG)
3465				bb_error_msg_and_die("BUG: unexpected %c\n", ch);
3466		}
3467	}
3468	/* Complain if quote?  No, maybe we just finished a command substitution
3469	 * that was quoted.  Example:
3470	 * $ echo "`cat foo` plus more"
3471	 * and we just got the EOF generated by the subshell that ran "cat foo"
3472	 * The only real complaint is if we got an EOF when end_trigger != NULL,
3473	 * that is, we were really supposed to get end_trigger, and never got
3474	 * one before the EOF.  Can't use the standard "syntax error" return code,
3475	 * so that parse_stream_outer can distinguish the EOF and exit smoothly. */
3476	debug_printf_parse("parse_stream return %d\n", -(end_trigger != NULL));
3477	if (end_trigger)
3478		return -1;
3479	return 0;
3480}
3481
3482static void set_in_charmap(const char *set, int code)
3483{
3484	while (*set)
3485		charmap[(unsigned char)*set++] = code;
3486}
3487
3488static void update_charmap(void)
3489{
3490	/* char *ifs and char charmap[256] are both globals. */
3491	ifs = getenv("IFS");
3492	if (ifs == NULL)
3493		ifs = " \t\n";
3494	/* Precompute a list of 'flow through' behavior so it can be treated
3495	 * quickly up front.  Computation is necessary because of IFS.
3496	 * Special case handling of IFS == " \t\n" is not implemented.
3497	 * The charmap[] array only really needs two bits each,
3498	 * and on most machines that would be faster (reduced L1 cache use).
3499	 */
3500	memset(charmap, CHAR_ORDINARY, sizeof(charmap));
3501#if ENABLE_HUSH_TICK
3502	set_in_charmap("\\$\"`", CHAR_SPECIAL);
3503#else
3504	set_in_charmap("\\$\"", CHAR_SPECIAL);
3505#endif
3506	set_in_charmap("<>;&|(){}#'", CHAR_ORDINARY_IF_QUOTED);
3507	set_in_charmap(ifs, CHAR_IFS);  /* are ordinary if quoted */
3508}
3509
3510/* most recursion does not come through here, the exception is
3511 * from builtin_source() and builtin_eval() */
3512static int parse_and_run_stream(struct in_str *inp, int parse_flag)
3513{
3514	struct p_context ctx;
3515	o_string temp = NULL_O_STRING;
3516	int rcode;
3517	do {
3518		ctx.parse_type = parse_flag;
3519		initialize_context(&ctx);
3520		update_charmap();
3521		if (!(parse_flag & PARSEFLAG_SEMICOLON) || (parse_flag & PARSEFLAG_REPARSING))
3522			set_in_charmap(";$&|", CHAR_ORDINARY);
3523#if ENABLE_HUSH_INTERACTIVE
3524		inp->promptmode = 0; /* PS1 */
3525#endif
3526		/* We will stop & execute after each ';' or '\n'.
3527		 * Example: "sleep 9999; echo TEST" + ctrl-C:
3528		 * TEST should be printed */
3529		rcode = parse_stream(&temp, &ctx, inp, ";\n");
3530		if (rcode != 1 && ctx.old_flag != 0) {
3531			syntax(NULL);
3532		}
3533		if (rcode != 1 && ctx.old_flag == 0) {
3534			done_word(&temp, &ctx);
3535			done_pipe(&ctx, PIPE_SEQ);
3536			debug_print_tree(ctx.list_head, 0);
3537			debug_printf_exec("parse_stream_outer: run_list\n");
3538			run_list(ctx.list_head);
3539		} else {
3540			if (ctx.old_flag != 0) {
3541				free(ctx.stack);
3542				b_reset(&temp);
3543			}
3544			temp.nonnull = 0;
3545			temp.quote = 0;
3546			inp->p = NULL;
3547			free_pipe_list(ctx.list_head, 0);
3548		}
3549		b_free(&temp);
3550	} while (rcode != -1 && !(parse_flag & PARSEFLAG_EXIT_FROM_LOOP));   /* loop on syntax errors, return on EOF */
3551	return 0;
3552}
3553
3554static int parse_and_run_string(const char *s, int parse_flag)
3555{
3556	struct in_str input;
3557	setup_string_in_str(&input, s);
3558	return parse_and_run_stream(&input, parse_flag);
3559}
3560
3561static int parse_and_run_file(FILE *f)
3562{
3563	int rcode;
3564	struct in_str input;
3565	setup_file_in_str(&input, f);
3566	rcode = parse_and_run_stream(&input, PARSEFLAG_SEMICOLON);
3567	return rcode;
3568}
3569
3570#if ENABLE_HUSH_JOB
3571/* Make sure we have a controlling tty.  If we get started under a job
3572 * aware app (like bash for example), make sure we are now in charge so
3573 * we don't fight over who gets the foreground */
3574static void setup_job_control(void)
3575{
3576	pid_t shell_pgrp;
3577
3578	saved_task_pgrp = shell_pgrp = getpgrp();
3579	debug_printf_jobs("saved_task_pgrp=%d\n", saved_task_pgrp);
3580	fcntl(interactive_fd, F_SETFD, FD_CLOEXEC);
3581
3582	/* If we were ran as 'hush &',
3583	 * sleep until we are in the foreground.  */
3584	while (tcgetpgrp(interactive_fd) != shell_pgrp) {
3585		/* Send TTIN to ourself (should stop us) */
3586		kill(- shell_pgrp, SIGTTIN);
3587		shell_pgrp = getpgrp();
3588	}
3589
3590	/* Ignore job-control and misc signals.  */
3591	set_jobctrl_sighandler(SIG_IGN);
3592	set_misc_sighandler(SIG_IGN);
3593//huh?	signal(SIGCHLD, SIG_IGN);
3594
3595	/* We _must_ restore tty pgrp on fatal signals */
3596	set_fatal_sighandler(sigexit);
3597
3598	/* Put ourselves in our own process group.  */
3599	setpgrp(); /* is the same as setpgid(our_pid, our_pid); */
3600	/* Grab control of the terminal.  */
3601	tcsetpgrp(interactive_fd, getpid());
3602}
3603#endif
3604
3605int hush_main(int argc, char **argv);
3606int hush_main(int argc, char **argv)
3607{
3608	static const char version_str[] ALIGN1 = "HUSH_VERSION="HUSH_VER_STR;
3609	static const struct variable const_shell_ver = {
3610		.next = NULL,
3611		.varstr = (char*)version_str,
3612		.max_len = 1, /* 0 can provoke free(name) */
3613		.flg_export = 1,
3614		.flg_read_only = 1,
3615	};
3616
3617	int opt;
3618	FILE *input;
3619	char **e;
3620	struct variable *cur_var;
3621
3622	PTR_TO_GLOBALS = xzalloc(sizeof(G));
3623
3624	/* Deal with HUSH_VERSION */
3625	shell_ver = const_shell_ver; /* copying struct here */
3626	top_var = &shell_ver;
3627	unsetenv("HUSH_VERSION"); /* in case it exists in initial env */
3628	/* Initialize our shell local variables with the values
3629	 * currently living in the environment */
3630	cur_var = top_var;
3631	e = environ;
3632	if (e) while (*e) {
3633		char *value = strchr(*e, '=');
3634		if (value) { /* paranoia */
3635			cur_var->next = xzalloc(sizeof(*cur_var));
3636			cur_var = cur_var->next;
3637			cur_var->varstr = *e;
3638			cur_var->max_len = strlen(*e);
3639			cur_var->flg_export = 1;
3640		}
3641		e++;
3642	}
3643	putenv((char *)version_str); /* reinstate HUSH_VERSION */
3644
3645#if ENABLE_FEATURE_EDITING
3646	line_input_state = new_line_input_t(FOR_SHELL);
3647#endif
3648	global_argc = argc;
3649	global_argv = argv;
3650	/* Initialize some more globals to non-zero values */
3651	set_cwd();
3652#if ENABLE_HUSH_INTERACTIVE
3653#if ENABLE_FEATURE_EDITING
3654	cmdedit_set_initial_prompt();
3655#endif
3656	PS2 = "> ";
3657#endif
3658
3659	if (EXIT_SUCCESS) /* otherwise is already done */
3660		last_return_code = EXIT_SUCCESS;
3661
3662	if (argv[0] && argv[0][0] == '-') {
3663		debug_printf("sourcing /etc/profile\n");
3664		input = fopen("/etc/profile", "r");
3665		if (input != NULL) {
3666			mark_open(fileno(input));
3667			parse_and_run_file(input);
3668			mark_closed(fileno(input));
3669			fclose(input);
3670		}
3671	}
3672	input = stdin;
3673
3674	while ((opt = getopt(argc, argv, "c:xif")) > 0) {
3675		switch (opt) {
3676		case 'c':
3677			global_argv = argv + optind;
3678			global_argc = argc - optind;
3679			opt = parse_and_run_string(optarg, PARSEFLAG_SEMICOLON);
3680			goto final_return;
3681		case 'i':
3682			/* Well, we cannot just declare interactiveness,
3683			 * we have to have some stuff (ctty, etc) */
3684			/* interactive_fd++; */
3685			break;
3686		case 'f':
3687			fake_mode = 1;
3688			break;
3689		default:
3690#ifndef BB_VER
3691			fprintf(stderr, "Usage: sh [FILE]...\n"
3692					"   or: sh -c command [args]...\n\n");
3693			exit(EXIT_FAILURE);
3694#else
3695			bb_show_usage();
3696#endif
3697		}
3698	}
3699#if ENABLE_HUSH_JOB
3700	/* A shell is interactive if the '-i' flag was given, or if all of
3701	 * the following conditions are met:
3702	 *    no -c command
3703	 *    no arguments remaining or the -s flag given
3704	 *    standard input is a terminal
3705	 *    standard output is a terminal
3706	 *    Refer to Posix.2, the description of the 'sh' utility. */
3707	if (argv[optind] == NULL && input == stdin
3708	 && isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)
3709	) {
3710		saved_tty_pgrp = tcgetpgrp(STDIN_FILENO);
3711		debug_printf("saved_tty_pgrp=%d\n", saved_tty_pgrp);
3712		if (saved_tty_pgrp >= 0) {
3713			/* try to dup to high fd#, >= 255 */
3714			interactive_fd = fcntl(STDIN_FILENO, F_DUPFD, 255);
3715			if (interactive_fd < 0) {
3716				/* try to dup to any fd */
3717				interactive_fd = dup(STDIN_FILENO);
3718				if (interactive_fd < 0)
3719					/* give up */
3720					interactive_fd = 0;
3721			}
3722			// TODO: track & disallow any attempts of user
3723			// to (inadvertently) close/redirect it
3724		}
3725	}
3726	debug_printf("interactive_fd=%d\n", interactive_fd);
3727	if (interactive_fd) {
3728		/* Looks like they want an interactive shell */
3729		setup_job_control();
3730		/* Make xfuncs do cleanup on exit */
3731		die_sleep = -1; /* flag */
3732		if (setjmp(die_jmp)) {
3733			/* xfunc has failed! die die die */
3734			hush_exit(xfunc_error_retval);
3735		}
3736#if !ENABLE_FEATURE_SH_EXTRA_QUIET
3737		printf("\n\n%s hush - the humble shell v"HUSH_VER_STR"\n", bb_banner);
3738		printf("Enter 'help' for a list of built-in commands.\n\n");
3739#endif
3740	}
3741#elif ENABLE_HUSH_INTERACTIVE
3742/* no job control compiled, only prompt/line editing */
3743	if (argv[optind] == NULL && input == stdin
3744	 && isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)
3745	) {
3746		interactive_fd = fcntl(STDIN_FILENO, F_DUPFD, 255);
3747		if (interactive_fd < 0) {
3748			/* try to dup to any fd */
3749			interactive_fd = dup(STDIN_FILENO);
3750			if (interactive_fd < 0)
3751				/* give up */
3752				interactive_fd = 0;
3753		}
3754	}
3755
3756#endif
3757
3758	if (argv[optind] == NULL) {
3759		opt = parse_and_run_file(stdin);
3760		goto final_return;
3761	}
3762
3763	debug_printf("\nrunning script '%s'\n", argv[optind]);
3764	global_argv = argv + optind;
3765	global_argc = argc - optind;
3766	input = xfopen(argv[optind], "r");
3767	opt = parse_and_run_file(input);
3768
3769 final_return:
3770
3771#if ENABLE_FEATURE_CLEAN_UP
3772	fclose(input);
3773	if (cwd != bb_msg_unknown)
3774		free((char*)cwd);
3775	cur_var = top_var->next;
3776	while (cur_var) {
3777		struct variable *tmp = cur_var;
3778		if (!cur_var->max_len)
3779			free(cur_var->varstr);
3780		cur_var = cur_var->next;
3781		free(tmp);
3782	}
3783#endif
3784	hush_exit(opt ? opt : last_return_code);
3785}
3786