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