Add simple 'true' command, useful for while loops
[oweals/u-boot_mod.git] / u-boot / common / hush.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * sh.c -- a prototype Bourne shell grammar parser
4  *      Intended to follow the original Thompson and Ritchie
5  *      "small and simple is beautiful" philosophy, which
6  *      incidentally is a good match to today's BusyBox.
7  *
8  * Copyright (C) 2000,2001  Larry Doolittle  <larry@doolittle.boa.org>
9  *
10  * Credits:
11  *      The parser routines proper are all original material, first
12  *      written Dec 2000 and Jan 2001 by Larry Doolittle.
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@lineo.com>, <andersee@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  *      simple_itoa() was lifted from boa-0.93.15
22  *      b_addchr() derived from similar w_addchar function in glibc-2.2
23  *      setup_redirect(), redirect_opt_num(), and big chunks of main()
24  *        and many builtins derived from contributions by Erik Andersen
25  *      miscellaneous bugfixes from Matt Kraai
26  *
27  * There are two big (and related) architecture differences between
28  * this parser and the lash parser.  One is that this version is
29  * actually designed from the ground up to understand nearly all
30  * of the Bourne grammar.  The second, consequential change is that
31  * the parser and input reader have been turned inside out.  Now,
32  * the parser is in control, and asks for input as needed.  The old
33  * way had the input reader in control, and it asked for parsing to
34  * take place as needed.  The new way makes it much easier to properly
35  * handle the recursion implicit in the various substitutions, especially
36  * across continuation lines.
37  *
38  * Bash grammar not implemented: (how many of these were in original sh?)
39  *      $@ (those sure look like weird quoting rules)
40  *      $_
41  *      ! negation operator for pipes
42  *      &> and >& redirection of stdout+stderr
43  *      Brace Expansion
44  *      Tilde Expansion
45  *      fancy forms of Parameter Expansion
46  *      aliases
47  *      Arithmetic Expansion
48  *      <(list) and >(list) Process Substitution
49  *      reserved words: case, esac, select, function
50  *      Here Documents ( << word )
51  *      Functions
52  * Major bugs:
53  *      job handling woefully incomplete and buggy
54  *      reserved word execution woefully incomplete and buggy
55  * to-do:
56  *      port selected bugfixes from post-0.49 busybox lash - done?
57  *      finish implementing reserved words: for, while, until, do, done
58  *      change { and } from special chars to reserved words
59  *      builtins: break, continue, eval, return, set, trap, ulimit
60  *      test magic exec
61  *      handle children going into background
62  *      clean up recognition of null pipes
63  *      check setting of global_argc and global_argv
64  *      control-C handling, probably with longjmp
65  *      follow IFS rules more precisely, including update semantics
66  *      figure out what to do with backslash-newline
67  *      explain why we use signal instead of sigaction
68  *      propagate syntax errors, die on resource errors?
69  *      continuation lines, both explicit and implicit - done?
70  *      memory leak finding and plugging - done?
71  *      more testing, especially quoting rules and redirection
72  *      document how quoting rules not precisely followed for variable assignments
73  *      maybe change map[] to use 2-bit entries
74  *      (eventually) remove all the printf's
75  *
76  * This program is free software; you can redistribute it and/or modify
77  * it under the terms of the GNU General Public License as published by
78  * the Free Software Foundation; either version 2 of the License, or
79  * (at your option) any later version.
80  *
81  * This program is distributed in the hope that it will be useful,
82  * but WITHOUT ANY WARRANTY; without even the implied warranty of
83  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
84  * General Public License for more details.
85  *
86  * You should have received a copy of the GNU General Public License
87  * along with this program; if not, write to the Free Software
88  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
89  */
90
91 #include <malloc.h>         /* malloc, free, realloc*/
92 #include <linux/ctype.h>    /* isalpha, isdigit */
93 #include <common.h>        /* readline */
94 #include <hush.h>
95 #include <command.h>        /* find_cmd */
96 /*cmd_boot.c*/
97 extern int do_bootd(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); /* do_bootd */
98
99 #ifdef CFG_HUSH_PARSER
100 #define SPECIAL_VAR_SYMBOL 03
101
102 DECLARE_GLOBAL_DATA_PTR;
103
104 #define EXIT_SUCCESS 0
105 #define EOF -1
106 #define syntax() syntax_err()
107 #define xstrdup strdup
108 #define error_msg printf
109
110 typedef enum {
111         PIPE_SEQ = 1, PIPE_AND = 2, PIPE_OR = 3, PIPE_BG = 4,
112 } pipe_style;
113
114 /* might eventually control execution */
115 typedef enum {
116         RES_NONE = 0,
117         RES_IF = 1,
118         RES_THEN = 2,
119         RES_ELIF = 3,
120         RES_ELSE = 4,
121         RES_FI = 5,
122         RES_FOR = 6,
123         RES_WHILE = 7,
124         RES_UNTIL = 8,
125         RES_DO = 9,
126         RES_DONE = 10,
127         RES_XXXX = 11,
128         RES_IN = 12,
129         RES_SNTX = 13
130 } reserved_style;
131 #define FLAG_END   (1<<RES_NONE)
132 #define FLAG_IF    (1<<RES_IF)
133 #define FLAG_THEN  (1<<RES_THEN)
134 #define FLAG_ELIF  (1<<RES_ELIF)
135 #define FLAG_ELSE  (1<<RES_ELSE)
136 #define FLAG_FI    (1<<RES_FI)
137 #define FLAG_FOR   (1<<RES_FOR)
138 #define FLAG_WHILE (1<<RES_WHILE)
139 #define FLAG_UNTIL (1<<RES_UNTIL)
140 #define FLAG_DO    (1<<RES_DO)
141 #define FLAG_DONE  (1<<RES_DONE)
142 #define FLAG_IN    (1<<RES_IN)
143 #define FLAG_START (1<<RES_XXXX)
144
145 /* This holds pointers to the various results of parsing */
146 struct p_context {
147         struct child_prog *child;
148         struct pipe *list_head;
149         struct pipe *pipe;
150         reserved_style w;
151         int old_flag; /* for figuring out valid reserved words */
152         struct p_context *stack;
153         int type; /* define type of parser : ";$" common or special symbol */
154 /* How about quoting status? */
155 };
156
157 struct child_prog {
158         char **argv; /* program name and arguments */
159         int argc; /* number of program arguments */
160         struct pipe *group; /* if non-NULL, first in group or subshell */
161         int sp; /* number of SPECIAL_VAR_SYMBOL */
162         int type;
163 };
164
165 struct pipe {
166         int num_progs; /* total number of programs in job */
167         struct child_prog *progs; /* array of commands in pipe */
168         struct pipe *next; /* to track background commands */
169         pipe_style followup; /* PIPE_BG, PIPE_SEQ, PIPE_OR, PIPE_AND */
170         reserved_style r_mode; /* supports if, for, while, until */
171 };
172
173 struct variables {
174         char *name;
175         char *value;
176         int flg_export;
177         int flg_read_only;
178         struct variables *next;
179 };
180
181 /* globals, connect us to the outside world
182  * the first three support $?, $#, and $1 */
183 unsigned int last_return_code;
184 int nesting_level;
185
186 /* "globals" within this file */
187 static uchar *ifs;
188 static char map[256];
189 static int flag_repeat = 0;
190 static int do_repeat = 0;
191 static struct variables *top_vars = NULL;
192
193 #define B_CHUNK (100)
194 #define B_NOSPAC 1
195
196 typedef struct {
197         char *data;
198         int length;
199         int maxlen;
200         int quote;
201         int nonnull;
202 } o_string;
203 #define NULL_O_STRING {NULL,0,0,0,0}
204 /* used for initialization:
205  o_string foo = NULL_O_STRING; */
206
207 /* I can almost use ordinary FILE *.  Is open_memstream() universally
208  * available?  Where is it documented? */
209 struct in_str {
210         const char *p;
211         int __promptme;
212         int promptmode;
213         int (*get)(struct in_str *);
214         int (*peek)(struct in_str *);
215 };
216 #define b_getch(input) ((input)->get(input))
217 #define b_peek(input) ((input)->peek(input))
218
219 /* This should be in utility.c */
220 #ifdef DEBUG_SHELL
221 #define debug_printf printf             /* U-Boot debug flag */
222 #else
223 static inline void debug_printf(const char *format, ...) {
224 }
225 #endif
226 #define final_printf debug_printf
227
228 static void syntax_err(void) {
229         printf_err("syntax error!\n");
230 }
231
232 static void *xmalloc(size_t size);
233 static void *xrealloc(void *ptr, size_t size);
234
235 /*   o_string manipulation: */
236 static int b_check_space(o_string *o, int len);
237 static int b_addchr(o_string *o, int ch);
238 static void b_reset(o_string *o);
239 static int b_addqchr(o_string *o, int ch, int quote);
240
241 /*  in_str manipulations: */
242 static int static_get(struct in_str *i);
243 static int static_peek(struct in_str *i);
244 static int file_get(struct in_str *i);
245 static int file_peek(struct in_str *i);
246 static void setup_file_in_str(struct in_str *i);
247 static void setup_string_in_str(struct in_str *i, const char *s);
248
249 /*  "run" the final data structures: */
250 static char *indenter(int i);
251 static int free_pipe_list(struct pipe *head, int indent);
252 static int free_pipe(struct pipe *pi, int indent);
253
254 /*  really run the final data structures: */
255 static int run_list_real(struct pipe *pi);
256 static int run_pipe_real(struct pipe *pi);
257
258 /*   variable assignment: */
259 static int is_assignment(const char *s);
260
261 /*   data structure manipulation: */
262 static void initialize_context(struct p_context *ctx);
263 static int done_word(o_string *dest, struct p_context *ctx);
264 static int done_command(struct p_context *ctx);
265 static int done_pipe(struct p_context *ctx, pipe_style type);
266
267 /*   primary string parsing: */
268 static char *lookup_param(char *src);
269 static char *make_string(char **inp);
270 static int handle_dollar(o_string *dest, struct p_context *ctx,
271                 struct in_str *input);
272 static int parse_stream(o_string *dest, struct p_context *ctx,
273                 struct in_str *input0, int end_trigger);
274
275 /*   setup: */
276 static int parse_stream_outer(struct in_str *inp, int flag);
277
278 /*     local variable support */
279 static char **make_list_in(char **inp, char *name);
280 static char *insert_var_value(char *inp);
281 static char *get_local_var(const char *var);
282 static int set_local_var(const char *s, int flg_export);
283
284 static int b_check_space(o_string *o, int len) {
285         /* It would be easy to drop a more restrictive policy
286          * in here, such as setting a maximum string length */
287         if (o->length + len > o->maxlen) {
288                 char *old_data = o->data;
289                 /* assert (data == NULL || o->maxlen != 0); */
290                 o->maxlen += max(2 * len, B_CHUNK);
291                 o->data = realloc(o->data, 1 + o->maxlen);
292                 if (o->data == NULL) {
293                         free(old_data);
294                 }
295         }
296         return o->data == NULL;
297 }
298
299 static int b_addchr(o_string *o, int ch) {
300         debug_printf("b_addchr: %c %d %p\n", ch, o->length, o);
301         if (b_check_space(o, 1))
302                 return B_NOSPAC;
303         o->data[o->length] = ch;
304         o->length++;
305         o->data[o->length] = '\0';
306         return 0;
307 }
308
309 static void b_reset(o_string *o) {
310         o->length = 0;
311         o->nonnull = 0;
312         if (o->data != NULL)
313                 *o->data = '\0';
314 }
315
316 static void b_free(o_string *o) {
317         b_reset(o);
318         free(o->data);
319         o->data = NULL;
320         o->maxlen = 0;
321 }
322
323 /* My analysis of quoting semantics tells me that state information
324  * is associated with a destination, not a source.
325  */
326 static int b_addqchr(o_string *o, int ch, int quote) {
327         if (quote && strchr("*?[\\", ch)) {
328                 int rc;
329                 rc = b_addchr(o, '\\');
330                 if (rc)
331                         return rc;
332         }
333         return b_addchr(o, ch);
334 }
335
336 /* belongs in utility.c */
337 char *simple_itoa(unsigned int i) {
338         /* 21 digits plus null terminator, good for 64-bit or smaller ints */
339         static char local[22];
340         char *p = &local[21];
341         *p-- = '\0';
342         do {
343                 *p-- = '0' + i % 10;
344                 i /= 10;
345         } while (i > 0);
346         return p + 1;
347 }
348
349 static int static_get(struct in_str *i) {
350         int ch = *i->p++;
351         if (ch == '\0')
352                 return EOF;
353         return ch;
354 }
355
356 static int static_peek(struct in_str *i) {
357         return *i->p;
358 }
359
360 static void get_user_input(struct in_str *i) {
361         extern char console_buffer[CFG_CBSIZE];
362         int n;
363         static char the_command[CFG_CBSIZE];
364
365 #ifdef CONFIG_BOOT_RETRY_TIME
366 #  ifdef CONFIG_RESET_TO_RETRY
367         extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
368 #  else
369 #       error "This currently only works with CONFIG_RESET_TO_RETRY enabled"
370 #  endif
371         reset_cmd_timeout();
372 #endif
373         i->__promptme = 1;
374         if (i->promptmode == 1) {
375                 n = readline(CFG_PROMPT);
376         } else {
377                 n = readline(CFG_PROMPT_HUSH_PS2);
378         }
379 #ifdef CONFIG_BOOT_RETRY_TIME
380         if (n == -2) {
381                 puts("\nTimeout waiting for command\n");
382 #  ifdef CONFIG_RESET_TO_RETRY
383                 do_reset(NULL, 0, 0, NULL);
384 #  else
385 #       error "This currently only works with CONFIG_RESET_TO_RETRY enabled"
386 #  endif
387         }
388 #endif
389         if (n == -1) {
390                 flag_repeat = 0;
391                 i->__promptme = 0;
392         }
393         n = strlen(console_buffer);
394         console_buffer[n] = '\n';
395         console_buffer[n + 1] = '\0';
396         if (had_ctrlc())
397                 flag_repeat = 0;
398         clear_ctrlc();
399         do_repeat = 0;
400         if (i->promptmode == 1) {
401                 if (console_buffer[0] == '\n' && flag_repeat == 0) {
402                         strcpy(the_command, console_buffer);
403                 } else {
404                         if (console_buffer[0] != '\n') {
405                                 strcpy(the_command, console_buffer);
406                                 flag_repeat = 1;
407                         } else {
408                                 do_repeat = 1;
409                         }
410                 }
411                 i->p = the_command;
412         } else {
413                 if (console_buffer[0] != '\n') {
414                         if (strlen(the_command) + strlen(console_buffer) < CFG_CBSIZE) {
415                                 n = strlen(the_command);
416                                 the_command[n - 1] = ' ';
417                                 strcpy(&the_command[n], console_buffer);
418                         } else {
419                                 the_command[0] = '\n';
420                                 the_command[1] = '\0';
421                                 flag_repeat = 0;
422                         }
423                 }
424                 if (i->__promptme == 0) {
425                         the_command[0] = '\n';
426                         the_command[1] = '\0';
427                 }
428                 i->p = console_buffer;
429         }
430 }
431
432 /* This is the magic location that prints prompts
433  * and gets data back from the user */
434 static int file_get(struct in_str *i) {
435         int ch;
436
437         ch = 0;
438         /* If there is data waiting, eat it up */
439         if (i->p && *i->p) {
440                 ch = *i->p++;
441         } else {
442                 /* need to double check i->file because we might be doing something
443                  * more complicated by now, like sourcing or substituting. */
444                 while (!i->p || strlen(i->p) == 0) {
445                         get_user_input(i);
446                 }
447
448                 i->promptmode = 2;
449
450                 if (i->p && *i->p) {
451                         ch = *i->p++;
452                 }
453                 debug_printf("b_getch: got a %d\n", ch);
454         }
455
456         return ch;
457 }
458
459 /* All the callers guarantee this routine will never be
460  * used right after a newline, so prompting is not needed.
461  */
462 static int file_peek(struct in_str *i) {
463         return *i->p;
464 }
465
466 static void setup_file_in_str(struct in_str *i) {
467         i->peek = file_peek;
468         i->get = file_get;
469         i->__promptme = 1;
470         i->promptmode = 1;
471         i->p = NULL;
472 }
473
474 static void setup_string_in_str(struct in_str *i, const char *s) {
475         i->peek = static_peek;
476         i->get = static_get;
477         i->__promptme = 1;
478         i->promptmode = 1;
479         i->p = s;
480 }
481
482 /* run_pipe_real() starts all the jobs, but doesn't wait for anything
483  * to finish.  See checkjobs().
484  *
485  * return code is normally -1, when the caller has to wait for children
486  * to finish to determine the exit status of the pipe.  If the pipe
487  * is a simple builtin command, however, the action is done by the
488  * time run_pipe_real returns, and the exit code is provided as the
489  * return value.
490  *
491  * The input of the pipe is always stdin, the output is always
492  * stdout.  The outpipe[] mechanism in BusyBox-0.48 lash is bogus,
493  * because it tries to avoid running the command substitution in
494  * subshell, when that is in fact necessary.  The subshell process
495  * now has its stdout directed to the input of the appropriate pipe,
496  * so this routine is noticeably simpler.
497  */
498 static int run_pipe_real(struct pipe *pi) {
499         int i;
500         int nextin;
501         int flag = do_repeat ? CMD_FLAG_REPEAT : 0;
502         struct child_prog *child;
503         cmd_tbl_t *cmdtp;
504         char *p;
505 # if __GNUC__
506         /* Avoid longjmp clobbering */
507         (void) &i;
508         (void) &nextin;
509         (void) &child;
510 # endif
511
512         nextin = 0;
513
514         /* Check if this is a simple builtin (not part of a pipe).
515          * Builtins within pipes have to fork anyway, and are handled in
516          * pseudo_exec.  "echo foo | read bar" doesn't work on bash, either.
517          */
518         if (pi->num_progs == 1)
519                 child = &(pi->progs[0]);
520         if (pi->num_progs == 1 && child->group) {
521                 int rcode;
522                 debug_printf("non-subshell grouping\n");
523                 rcode = run_list_real(child->group);
524                 return rcode;
525         } else if (pi->num_progs == 1 && pi->progs[0].argv != NULL) {
526                 for (i = 0; is_assignment(child->argv[i]); i++) { /* nothing */
527                 }
528                 if (i != 0 && child->argv[i] == NULL) {
529                         /* assignments, but no command: set the local environment */
530                         for (i = 0; child->argv[i] != NULL; i++) {
531
532                                 /* Ok, this case is tricky.  We have to decide if this is a
533                                  * local variable, or an already exported variable.  If it is
534                                  * already exported, we have to export the new value.  If it is
535                                  * not exported, we need only set this as a local variable.
536                                  * This junk is all to decide whether or not to export this
537                                  * variable. */
538                                 int export_me = 0;
539                                 char *name, *value;
540                                 name = xstrdup(child->argv[i]);
541                                 debug_printf("Local environment set: %s\n", name);
542                                 value = strchr(name, '=');
543                                 if (value)
544                                         *value = 0;
545                                 free(name);
546                                 p = insert_var_value(child->argv[i]);
547                                 set_local_var(p, export_me);
548                                 if (p != child->argv[i])
549                                         free(p);
550                         }
551                         return EXIT_SUCCESS; /* don't worry about errors in set_local_var() yet */
552                 }
553                 for (i = 0; is_assignment(child->argv[i]); i++) {
554                         p = insert_var_value(child->argv[i]);
555                         set_local_var(p, 0);
556                         if (p != child->argv[i]) {
557                                 child->sp--;
558                                 free(p);
559                         }
560                 }
561                 if (child->sp) {
562                         char * str = NULL;
563
564                         str = make_string((child->argv + i));
565                         parse_string_outer(str, FLAG_EXIT_FROM_LOOP | FLAG_REPARSING);
566                         free(str);
567                         return last_return_code;
568                 }
569
570                 /* check ";", because ,example , argv consist from
571                  * "help;flinfo" must not execute
572                  */
573                 if (strchr(child->argv[i], ';')) {
574                         printf_err("unknown command '%s' - try 'help' or use 'run' command\n", child->argv[i]);
575                         return -1;
576                 }
577
578                 /* Look up command in command table */
579                 if ((cmdtp = find_cmd(child->argv[i])) == NULL) {
580                         printf_err("unknown command '%s' - try 'help'\n", child->argv[i]);
581                         return -1; /* give up after bad command */
582                 } else {
583                         int rcode;
584 #if defined(CONFIG_CMD_BOOTD)
585                         extern int do_bootd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
586
587                         /* avoid "bootd" recursion */
588                         if (cmdtp->cmd == do_bootd) {
589                                 if (flag & CMD_FLAG_BOOTD) {
590                                         printf_err("'bootd' recursion detected!\n");
591                                         return -1;
592                                 } else {
593                                         flag |= CMD_FLAG_BOOTD;
594                                 }
595                         }
596 #endif /* CONFIG_CMD_BOOTD */
597                         /* found - check max args */
598                         if ((child->argc - i) > cmdtp->maxargs) {
599                                 print_cmd_help(cmdtp);
600                                 return -1;
601                         }
602                         child->argv += i; /* XXX horrible hack */
603                         /* OK - call function to do the command */
604                         rcode = (cmdtp->cmd)(cmdtp, flag, child->argc - i, &child->argv[i]);
605
606                         if (!cmdtp->repeatable)
607                                 flag_repeat = 0;
608
609                         child->argv -= i; /* XXX restore hack so free() can work right */
610
611                         return rcode;
612                 }
613         }
614         return -1;
615 }
616
617 static int run_list_real(struct pipe *pi) {
618         char *save_name = NULL;
619         char **list = NULL;
620         char **save_list = NULL;
621         struct pipe *rpipe;
622         int flag_rep = 0;
623         int rcode = 0, flag_skip = 1;
624         int flag_restore = 0;
625         int if_code = 0, next_if_code = 0; /* need double-buffer to handle elif */
626         reserved_style rmode, skip_more_in_this_rmode = RES_XXXX;
627         /* check syntax for "for" */
628         for (rpipe = pi; rpipe; rpipe = rpipe->next) {
629                 if ((rpipe->r_mode == RES_IN || rpipe->r_mode == RES_FOR)
630                                 && (rpipe->next == NULL)) {
631                         syntax();
632                         flag_repeat = 0;
633                         return 1;
634                 }
635                 if ((rpipe->r_mode == RES_IN
636                                 && (rpipe->next->r_mode == RES_IN
637                                                 && rpipe->next->progs->argv != NULL))
638                                 || (rpipe->r_mode == RES_FOR && rpipe->next->r_mode != RES_IN)) {
639                         syntax();
640                         flag_repeat = 0;
641                         return 1;
642                 }
643         }
644         for (; pi; pi = (flag_restore != 0) ? rpipe : pi->next) {
645                 if (pi->r_mode == RES_WHILE || pi->r_mode == RES_UNTIL
646                                 || pi->r_mode == RES_FOR) {
647                         /* check Ctrl-C */
648                         ctrlc();
649                         if ((had_ctrlc())) {
650                                 return 1;
651                         }
652                         flag_restore = 0;
653                         if (!rpipe) {
654                                 flag_rep = 0;
655                                 rpipe = pi;
656                         }
657                 }
658                 rmode = pi->r_mode;
659                 debug_printf("rmode=%d  if_code=%d  next_if_code=%d skip_more=%d\n",
660                                 rmode, if_code, next_if_code, skip_more_in_this_rmode);
661                 if (rmode == skip_more_in_this_rmode && flag_skip) {
662                         if (pi->followup == PIPE_SEQ)
663                                 flag_skip = 0;
664                         continue;
665                 }
666                 flag_skip = 1;
667                 skip_more_in_this_rmode = RES_XXXX;
668                 if (rmode == RES_THEN || rmode == RES_ELSE)
669                         if_code = next_if_code;
670                 if (rmode == RES_THEN && if_code)
671                         continue;
672                 if (rmode == RES_ELSE && !if_code)
673                         continue;
674                 if (rmode == RES_ELIF && !if_code)
675                         break;
676                 if (rmode == RES_FOR && pi->num_progs) {
677                         if (!list) {
678                                 /* if no variable values after "in" we skip "for" */
679                                 if (!pi->next->progs->argv)
680                                         continue;
681                                 /* create list of variable values */
682                                 list = make_list_in(pi->next->progs->argv, pi->progs->argv[0]);
683                                 save_list = list;
684                                 save_name = pi->progs->argv[0];
685                                 pi->progs->argv[0] = NULL;
686                                 flag_rep = 1;
687                         }
688                         if (!(*list)) {
689                                 free(pi->progs->argv[0]);
690                                 free(save_list);
691                                 list = NULL;
692                                 flag_rep = 0;
693                                 pi->progs->argv[0] = save_name;
694                                 continue;
695                         } else {
696                                 /* insert new value from list for variable */
697                                 if (pi->progs->argv[0])
698                                         free(pi->progs->argv[0]);
699                                 pi->progs->argv[0] = *list++;
700                         }
701                 }
702                 if (rmode == RES_IN)
703                         continue;
704                 if (rmode == RES_DO) {
705                         if (!flag_rep)
706                                 continue;
707                 }
708                 if ((rmode == RES_DONE)) {
709                         if (flag_rep) {
710                                 flag_restore = 1;
711                         } else {
712                                 rpipe = NULL;
713                         }
714                 }
715                 if (pi->num_progs == 0)
716                         continue;
717                 rcode = run_pipe_real(pi);
718                 debug_printf("run_pipe_real returned %d\n", rcode);
719                 if (rcode < -1) {
720                         last_return_code = -rcode - 2;
721                         return -2; /* exit */
722                 }
723                 last_return_code = (rcode == 0) ? 0 : 1;
724
725                 if (rmode == RES_IF || rmode == RES_ELIF)
726                         next_if_code = rcode; /* can be overwritten a number of times */
727                 if (rmode == RES_WHILE)
728                         flag_rep = !last_return_code;
729                 if (rmode == RES_UNTIL)
730                         flag_rep = last_return_code;
731                 if ((rcode == EXIT_SUCCESS && pi->followup == PIPE_OR)
732                                 || (rcode != EXIT_SUCCESS && pi->followup == PIPE_AND))
733                         skip_more_in_this_rmode = rmode;
734         }
735         return rcode;
736 }
737
738 /* broken, of course, but OK for testing */
739 static char *indenter(int i) {
740         static char blanks[] = "                                    ";
741         return &blanks[sizeof(blanks) - i - 1];
742 }
743
744 /* return code is the exit status of the pipe */
745 static int free_pipe(struct pipe *pi, int indent) {
746         char **p;
747         struct child_prog *child;
748         int a, i, ret_code = 0;
749         char *ind = indenter(indent);
750
751         for (i = 0; i < pi->num_progs; i++) {
752                 child = &pi->progs[i];
753                 final_printf("%s  command %d:\n", ind, i);
754                 if (child->argv) {
755                         for (a = 0, p = child->argv; *p; a++, p++) {
756                                 final_printf("%s   argv[%d] = %s\n", ind, a, *p);
757                         }
758                         for (a = child->argc; a >= 0; a--) {
759                                 free(child->argv[a]);
760                         }
761                         free(child->argv);
762                         child->argc = 0;
763                         child->argv = NULL;
764                 } else if (child->group) {
765                         ret_code = free_pipe_list(child->group, indent + 3);
766                         final_printf("%s   end group\n", ind);
767                 } else {
768                         final_printf("%s   (nil)\n", ind);
769                 }
770         }
771         free(pi->progs); /* children are an array, they get freed all at once */
772         pi->progs = NULL;
773         return ret_code;
774 }
775
776 static int free_pipe_list(struct pipe *head, int indent) {
777         int rcode = 0; /* if list has no members */
778         struct pipe *pi, *next;
779         char *ind = indenter(indent);
780         for (pi = head; pi; pi = next) {
781                 final_printf("%s pipe reserved mode %d\n", ind, pi->r_mode);
782                 rcode = free_pipe(pi, indent);
783                 final_printf("%s pipe followup code %d\n", ind, pi->followup);
784                 next = pi->next;
785                 pi->next = NULL;
786                 free(pi);
787         }
788         return rcode;
789 }
790
791 /* Select which version we will use */
792 static int run_list(struct pipe *pi) {
793         int rcode = run_list_real(pi);
794
795         /* free_pipe_list has the side effect of clearing memory
796          * In the long run that function can be merged with run_list_real,
797          * but doing that now would hobble the debugging effort. */
798         free_pipe_list(pi, 0);
799         return rcode;
800 }
801
802 static char *get_dollar_var(char ch);
803
804 /* This is used to get/check local shell variables */
805 static char *get_local_var(const char *s) {
806         struct variables *cur;
807
808         if (!s)
809                 return NULL;
810
811         if (*s == '$')
812                 return get_dollar_var(s[1]);
813
814         for (cur = top_vars; cur; cur = cur->next)
815                 if (strcmp(cur->name, s) == 0)
816                         return cur->value;
817         return NULL;
818 }
819
820 /* This is used to set local shell variables
821  flg_export==0 if only local (not exporting) variable
822  flg_export==1 if "new" exporting environ
823  flg_export>1  if current startup environ (not call putenv()) */
824 static int set_local_var(const char *s, int flg_export) {
825         char *name, *value;
826         int result = 0;
827         struct variables *cur;
828
829         /* might be possible! */
830         if (!isalpha(*s))
831                 return -1;
832
833         name = strdup(s);
834
835         if (getenv(name) != NULL) {
836                 printf_err("there is a global environment variable with the same name!\n");
837                 free(name);
838                 return -1;
839         }
840
841         /* Assume when we enter this function that we are already in
842          * NAME=VALUE format.  So the first order of business is to
843          * split 's' on the '=' into 'name' and 'value' */
844         value = strchr(name, '=');
845         if (value == 0 && ++value == 0) {
846                 free(name);
847                 return -1;
848         }
849         *value++ = 0;
850
851         for (cur = top_vars; cur; cur = cur->next) {
852                 if (strcmp(cur->name, name) == 0)
853                         break;
854         }
855
856         if (cur) {
857                 if (strcmp(cur->value, value) == 0) {
858                         if (flg_export > 0 && cur->flg_export == 0)
859                                 cur->flg_export = flg_export;
860                         else
861                                 result++;
862                 } else {
863                         if (cur->flg_read_only) {
864                                 printf_err("%s: readonly variable", name);
865                                 result = -1;
866                         } else {
867                                 if (flg_export > 0 || cur->flg_export > 1)
868                                         cur->flg_export = 1;
869                                 free(cur->value);
870
871                                 cur->value = strdup(value);
872                         }
873                 }
874         } else {
875                 cur = malloc(sizeof(struct variables));
876                 if (!cur) {
877                         result = -1;
878                 } else {
879                         cur->name = strdup(name);
880                         if (cur->name == 0) {
881                                 free(cur);
882                                 result = -1;
883                         } else {
884                                 struct variables *bottom = top_vars;
885                                 cur->value = strdup(value);
886                                 cur->next = 0;
887                                 cur->flg_export = flg_export;
888                                 cur->flg_read_only = 0;
889                                 while (bottom->next)
890                                         bottom = bottom->next;
891                                 bottom->next = cur;
892                         }
893                 }
894         }
895
896         free(name);
897
898         return result;
899 }
900
901 static int is_assignment(const char *s) {
902         if (s == NULL)
903                 return 0;
904
905         if (!isalpha(*s))
906                 return 0;
907         ++s;
908         while (isalnum(*s) || *s == '_')
909                 ++s;
910         return *s == '=';
911 }
912
913 struct pipe *new_pipe(void) {
914         struct pipe *pi;
915         pi = xmalloc(sizeof(struct pipe));
916         pi->num_progs = 0;
917         pi->progs = NULL;
918         pi->next = NULL;
919         pi->followup = 0; /* invalid */
920         pi->r_mode = RES_NONE;
921         return pi;
922 }
923
924 static void initialize_context(struct p_context *ctx) {
925         ctx->pipe = NULL;
926         ctx->child = NULL;
927         ctx->list_head = new_pipe();
928         ctx->pipe = ctx->list_head;
929         ctx->w = RES_NONE;
930         ctx->stack = NULL;
931         ctx->old_flag = 0;
932         done_command(ctx); /* creates the memory for working child */
933 }
934
935 /* normal return is 0
936  * if a reserved word is found, and processed, return 1
937  * should handle if, then, elif, else, fi, for, while, until, do, done.
938  * case, function, and select are obnoxious, save those for later.
939  */
940 struct reserved_combo {
941         char *literal;
942         int code;
943         long flag;
944 };
945 /* Mostly a list of accepted follow-up reserved words.
946  * FLAG_END means we are done with the sequence, and are ready
947  * to turn the compound list into a command.
948  * FLAG_START means the word must start a new compound list.
949  */
950 static struct reserved_combo reserved_list[] = { { "if", RES_IF, FLAG_THEN
951                 | FLAG_START }, { "then", RES_THEN, FLAG_ELIF | FLAG_ELSE | FLAG_FI }, {
952                 "elif", RES_ELIF, FLAG_THEN }, { "else", RES_ELSE, FLAG_FI }, { "fi",
953                 RES_FI, FLAG_END }, { "for", RES_FOR, FLAG_IN | FLAG_START }, { "while",
954                 RES_WHILE, FLAG_DO | FLAG_START }, { "until", RES_UNTIL, FLAG_DO
955                 | FLAG_START }, { "in", RES_IN, FLAG_DO }, { "do", RES_DO, FLAG_DONE },
956                 { "done", RES_DONE, FLAG_END } };
957 #define NRES (sizeof(reserved_list)/sizeof(struct reserved_combo))
958
959 int reserved_word(o_string *dest, struct p_context *ctx) {
960         struct reserved_combo *r;
961         for (r = reserved_list; r < reserved_list + NRES; r++) {
962                 if (strcmp(dest->data, r->literal) == 0) {
963                         debug_printf("found reserved word %s, code %d\n", r->literal,
964                                         r->code);
965                         if (r->flag & FLAG_START) {
966                                 struct p_context *new = xmalloc(sizeof(struct p_context));
967                                 debug_printf("push stack\n");
968                                 if (ctx->w == RES_IN || ctx->w == RES_FOR) {
969                                         syntax();
970                                         free(new);
971                                         ctx->w = RES_SNTX;
972                                         b_reset(dest);
973                                         return 1;
974                                 }
975                                 *new = *ctx; /* physical copy */
976                                 initialize_context(ctx);
977                                 ctx->stack = new;
978                         } else if (ctx->w == RES_NONE
979                                         || !(ctx->old_flag & (1 << r->code))) {
980                                 syntax();
981                                 ctx->w = RES_SNTX;
982                                 b_reset(dest);
983                                 return 1;
984                         }
985                         ctx->w = r->code;
986                         ctx->old_flag = r->flag;
987                         if (ctx->old_flag & FLAG_END) {
988                                 struct p_context *old;
989                                 debug_printf("pop stack\n");
990                                 done_pipe(ctx, PIPE_SEQ);
991                                 old = ctx->stack;
992                                 old->child->group = ctx->list_head;
993                                 *ctx = *old; /* physical copy */
994                                 free(old);
995                         }
996                         b_reset(dest);
997                         return 1;
998                 }
999         }
1000         return 0;
1001 }
1002
1003 /* normal return is 0.
1004  * Syntax or xglob errors return 1. */
1005 static int done_word(o_string *dest, struct p_context *ctx) {
1006         struct child_prog *child = ctx->child;
1007         char *str, *s;
1008         int argc, cnt;
1009
1010         debug_printf("done_word: %s %p\n", dest->data, child);
1011         if (dest->length == 0 && !dest->nonnull) {
1012                 debug_printf("  true null, ignored\n");
1013                 return 0;
1014         }
1015         if (child->group) {
1016                 syntax();
1017                 return 1; /* syntax error, groups and arglists don't mix */
1018         }
1019         if (!child->argv && (ctx->type & FLAG_PARSE_SEMICOLON)) {
1020                 debug_printf("checking %s for reserved-ness\n", dest->data);
1021                 if (reserved_word(dest, ctx))
1022                         return ctx->w == RES_SNTX;
1023         }
1024         for (cnt = 1, s = dest->data; s && *s; s++) {
1025                 if (*s == '\\')
1026                         s++;
1027                 cnt++;
1028         }
1029         str = malloc(cnt);
1030         if (!str)
1031                 return 1;
1032         if (child->argv == NULL) {
1033                 child->argc = 0;
1034         }
1035         argc = ++child->argc;
1036         child->argv = realloc(child->argv, (argc + 1) * sizeof(*child->argv));
1037         if (child->argv == NULL)
1038                 return 1;
1039         child->argv[argc - 1] = str;
1040         child->argv[argc] = NULL;
1041         for (s = dest->data; s && *s; s++, str++) {
1042                 if (*s == '\\')
1043                         s++;
1044                 *str = *s;
1045         }
1046
1047         *str = '\0';
1048
1049         b_reset(dest);
1050
1051         if (ctx->w == RES_FOR) {
1052                 done_word(dest, ctx);
1053                 done_pipe(ctx, PIPE_SEQ);
1054         }
1055         return 0;
1056 }
1057
1058 /* The only possible error here is out of memory, in which case
1059  * xmalloc exits. */
1060 static int done_command(struct p_context *ctx) {
1061         /* The child is really already in the pipe structure, so
1062          * advance the pipe counter and make a new, null child.
1063          * Only real trickiness here is that the uncommitted
1064          * child structure, to which ctx->child points, is not
1065          * counted in pi->num_progs. */
1066         struct pipe *pi = ctx->pipe;
1067         struct child_prog *prog = ctx->child;
1068
1069         if (prog && prog->group == NULL && prog->argv == NULL) {
1070                 debug_printf("done_command: skipping null command\n");
1071                 return 0;
1072         } else if (prog) {
1073                 pi->num_progs++;
1074                 debug_printf("done_command: num_progs incremented to %d\n",
1075                                 pi->num_progs);
1076         } else {
1077                 debug_printf("done_command: initializing\n");
1078         }
1079         pi->progs = xrealloc(pi->progs, sizeof(*pi->progs) * (pi->num_progs + 1));
1080
1081         prog = pi->progs + pi->num_progs;
1082         prog->argv = NULL;
1083         prog->group = NULL;
1084         prog->sp = 0;
1085         ctx->child = prog;
1086         prog->type = ctx->type;
1087
1088         /* but ctx->pipe and ctx->list_head remain unchanged */
1089         return 0;
1090 }
1091
1092 static int done_pipe(struct p_context *ctx, pipe_style type) {
1093         struct pipe *new_p;
1094         done_command(ctx); /* implicit closure of previous command */
1095         debug_printf("done_pipe, type %d\n", type);
1096         ctx->pipe->followup = type;
1097         ctx->pipe->r_mode = ctx->w;
1098         new_p = new_pipe();
1099         ctx->pipe->next = new_p;
1100         ctx->pipe = new_p;
1101         ctx->child = NULL;
1102         done_command(ctx); /* set up new pipe to accept commands */
1103         return 0;
1104 }
1105
1106 /* basically useful version until someone wants to get fancier,
1107  * see the bash man page under "Parameter Expansion" */
1108 static char *lookup_param(char *src) {
1109         char *p;
1110
1111         if (!src)
1112                 return NULL;
1113
1114         p = getenv(src);
1115         if (!p)
1116                 p = get_local_var(src);
1117
1118         return p;
1119 }
1120
1121 static char *get_dollar_var(char ch) {
1122         static char buf[40];
1123
1124         buf[0] = '\0';
1125         switch (ch) {
1126         case '?':
1127                 sprintf(buf, "%u", (unsigned int) last_return_code);
1128                 break;
1129         default:
1130                 return NULL;
1131         }
1132         return buf;
1133 }
1134
1135 /* return code: 0 for OK, 1 for syntax error */
1136 static int handle_dollar(o_string *dest, struct p_context *ctx,
1137                 struct in_str *input) {
1138         int advance = 0;
1139         int ch = input->peek(input); /* first character after the $ */
1140         debug_printf("handle_dollar: ch=%c\n", ch);
1141         if (isalpha(ch)) {
1142                 b_addchr(dest, SPECIAL_VAR_SYMBOL);
1143                 ctx->child->sp++;
1144                 while (ch = b_peek(input), isalnum(ch) || ch == '_') {
1145                         b_getch(input);
1146                         b_addchr(dest, ch);
1147                 }
1148                 b_addchr(dest, SPECIAL_VAR_SYMBOL);
1149         } else
1150                 switch (ch) {
1151                 case '?':
1152                         ctx->child->sp++;
1153                         b_addchr(dest, SPECIAL_VAR_SYMBOL);
1154                         b_addchr(dest, '$');
1155                         b_addchr(dest, '?');
1156                         b_addchr(dest, SPECIAL_VAR_SYMBOL);
1157                         advance = 1;
1158                         break;
1159                 case '{':
1160                         b_addchr(dest, SPECIAL_VAR_SYMBOL);
1161                         ctx->child->sp++;
1162                         b_getch(input);
1163                         /* XXX maybe someone will try to escape the '}' */
1164                         while (ch = b_getch(input), ch != EOF && ch != '}') {
1165                                 b_addchr(dest, ch);
1166                         }
1167                         if (ch != '}') {
1168                                 syntax();
1169                                 return 1;
1170                         }
1171                         b_addchr(dest, SPECIAL_VAR_SYMBOL);
1172                         break;
1173                 default:
1174                         b_addqchr(dest, '$', dest->quote);
1175                 }
1176         /* Eat the character if the flag was set.  If the compiler
1177          * is smart enough, we could substitute "b_getch(input);"
1178          * for all the "advance = 1;" above, and also end up with
1179          * a nice size-optimized program.  Hah!  That'll be the day.
1180          */
1181         if (advance)
1182                 b_getch(input);
1183         return 0;
1184 }
1185
1186 /* return code is 0 for normal exit, 1 for syntax error */
1187 int parse_stream(o_string *dest, struct p_context *ctx, struct in_str *input,
1188                 int end_trigger) {
1189         unsigned int ch, m;
1190         int next;
1191
1192         /* Only double-quote state is handled in the state variable dest->quote.
1193          * A single-quote triggers a bypass of the main loop until its mate is
1194          * found.  When recursing, quote state is passed in via dest->quote. */
1195
1196         debug_printf("parse_stream, end_trigger=%d\n", end_trigger);
1197         while ((ch = b_getch(input)) != EOF) {
1198                 m = map[ch];
1199                 if (input->__promptme == 0)
1200                         return 1;
1201
1202                 next = (ch == '\n') ? 0 : b_peek(input);
1203
1204                 debug_printf("parse_stream: ch=%c (%d) m=%d quote=%d - %c\n",
1205                                 ch >= ' ' ? ch : '.', ch, m, dest->quote,
1206                                 ctx->stack == NULL ? '*' : '.');
1207
1208                 if (m == 0 || ((m == 1 || m == 2) && dest->quote)) {
1209                         b_addqchr(dest, ch, dest->quote);
1210                 } else {
1211                         if (m == 2) { /* unquoted IFS */
1212                                 if (done_word(dest, ctx)) {
1213                                         return 1;
1214                                 }
1215                                 /* If we aren't performing a substitution, treat a newline as a
1216                                  * command separator.  */
1217                                 if (end_trigger != '\0' && ch == '\n')
1218                                         done_pipe(ctx, PIPE_SEQ);
1219                         }
1220                         if (ch == end_trigger && !dest->quote && ctx->w == RES_NONE) {
1221                                 debug_printf("leaving parse_stream (triggered)\n");
1222                                 return 0;
1223                         }
1224                         if (m != 2)
1225                                 switch (ch) {
1226                                 case '#':
1227                                         if (dest->length == 0 && !dest->quote) {
1228                                                 while (ch = b_peek(input), ch != EOF && ch != '\n') {
1229                                                         b_getch(input);
1230                                                 }
1231                                         } else {
1232                                                 b_addqchr(dest, ch, dest->quote);
1233                                         }
1234                                         break;
1235                                 case '\\':
1236                                         if (next == EOF) {
1237                                                 syntax();
1238                                                 return 1;
1239                                         }
1240                                         b_addqchr(dest, '\\', dest->quote);
1241                                         b_addqchr(dest, b_getch(input), dest->quote);
1242                                         break;
1243                                 case '$':
1244                                         if (handle_dollar(dest, ctx, input) != 0)
1245                                                 return 1;
1246                                         break;
1247                                 case '\'':
1248                                         dest->nonnull = 1;
1249                                         while (ch = b_getch(input), ch != EOF && ch != '\'') {
1250                                                 if (input->__promptme == 0)
1251                                                         return 1;
1252                                                 b_addchr(dest, ch);
1253                                         }
1254                                         if (ch == EOF) {
1255                                                 syntax();
1256                                                 return 1;
1257                                         }
1258                                         break;
1259                                 case '"':
1260                                         dest->nonnull = 1;
1261                                         dest->quote = !dest->quote;
1262                                         break;
1263                                 case ';':
1264                                         done_word(dest, ctx);
1265                                         done_pipe(ctx, PIPE_SEQ);
1266                                         break;
1267                                 case '&':
1268                                         done_word(dest, ctx);
1269                                         if (next == '&') {
1270                                                 b_getch(input);
1271                                                 done_pipe(ctx, PIPE_AND);
1272                                         } else {
1273                                                 syntax_err();
1274                                                 return 1;
1275                                         }
1276                                         break;
1277                                 case '|':
1278                                         done_word(dest, ctx);
1279                                         if (next == '|') {
1280                                                 b_getch(input);
1281                                                 done_pipe(ctx, PIPE_OR);
1282                                         } else {
1283                                                 /* we could pick up a file descriptor choice here
1284                                                  * with redirect_opt_num(), but bash doesn't do it.
1285                                                  * "echo foo 2| cat" yields "foo 2". */
1286                                                 syntax_err();
1287                                                 return 1;
1288                                         }
1289                                         break;
1290                                 default:
1291                                         syntax(); /* this is really an internal logic error */
1292                                         return 1;
1293                                 }
1294                 }
1295         }
1296         /* complain if quote?  No, maybe we just finished a command substitution
1297          * that was quoted.  Example:
1298          * $ echo "`cat foo` plus more"
1299          * and we just got the EOF generated by the subshell that ran "cat foo"
1300          * The only real complaint is if we got an EOF when end_trigger != '\0',
1301          * that is, we were really supposed to get end_trigger, and never got
1302          * one before the EOF.  Can't use the standard "syntax error" return code,
1303          * so that parse_stream_outer can distinguish the EOF and exit smoothly. */
1304         debug_printf("leaving parse_stream (EOF)\n");
1305         if (end_trigger != '\0')
1306                 return -1;
1307         return 0;
1308 }
1309
1310 void mapset(const unsigned char *set, int code) {
1311         const unsigned char *s;
1312         for (s = set; *s; s++)
1313                 map[*s] = code;
1314 }
1315
1316 void update_ifs_map(void) {
1317         /* char *ifs and char map[256] are both globals. */
1318         ifs = (uchar *) getenv("IFS");
1319         if (ifs == NULL)
1320                 ifs = (uchar *) " \t\n";
1321         /* Precompute a list of 'flow through' behavior so it can be treated
1322          * quickly up front.  Computation is necessary because of IFS.
1323          * Special case handling of IFS == " \t\n" is not implemented.
1324          * The map[] array only really needs two bits each, and on most machines
1325          * that would be faster because of the reduced L1 cache footprint.
1326          */
1327         memset(map, 0, sizeof(map)); /* most characters flow through always */
1328         mapset((uchar *) "\\$'\"", 3); /* never flow through */
1329         mapset((uchar *) ";&|#", 1); /* flow through if quoted */
1330         mapset(ifs, 2); /* also flow through if quoted */
1331 }
1332
1333 /* most recursion does not come through here, the exeception is
1334  * from builtin_source() */
1335 int parse_stream_outer(struct in_str *inp, int flag) {
1336
1337         struct p_context ctx;
1338         o_string temp = NULL_O_STRING;
1339         int rcode;
1340         int code = 0;
1341         do {
1342                 ctx.type = flag;
1343                 initialize_context(&ctx);
1344                 update_ifs_map();
1345                 if (!(flag & FLAG_PARSE_SEMICOLON) || (flag & FLAG_REPARSING))
1346                         mapset((uchar *) ";$&|", 0);
1347                 inp->promptmode = 1;
1348                 rcode = parse_stream(&temp, &ctx, inp, '\n');
1349                 if (rcode == 1)
1350                         flag_repeat = 0;
1351                 if (rcode != 1 && ctx.old_flag != 0) {
1352                         syntax();
1353                         flag_repeat = 0;
1354                 }
1355                 if (rcode != 1 && ctx.old_flag == 0) {
1356                         done_word(&temp, &ctx);
1357                         done_pipe(&ctx, PIPE_SEQ);
1358                         code = run_list(ctx.list_head);
1359                         if (code == -2) { /* exit */
1360                                 b_free(&temp);
1361                                 code = 0;
1362                                 /* XXX hackish way to not allow exit from main loop */
1363                                 if (inp->peek == file_peek) {
1364                                         printf_err("exit not allowed from main input shell!\n");
1365                                         continue;
1366                                 }
1367                                 break;
1368                         }
1369                         if (code == -1)
1370                                 flag_repeat = 0;
1371                 } else {
1372                         if (ctx.old_flag != 0) {
1373                                 free(ctx.stack);
1374                                 b_reset(&temp);
1375                         }
1376                         if (inp->__promptme == 0)
1377                                 printf("<INTERRUPT>\n");
1378                         inp->__promptme = 1;
1379                         temp.nonnull = 0;
1380                         temp.quote = 0;
1381                         inp->p = NULL;
1382                         free_pipe_list(ctx.list_head, 0);
1383                 }
1384                 b_free(&temp);
1385         } while (rcode != -1 && !(flag & FLAG_EXIT_FROM_LOOP)); /* loop on syntax errors, return on EOF */
1386
1387         return (code != 0) ? 1 : 0;
1388 }
1389
1390 int parse_string_outer(char *s, int flag) {
1391         struct in_str input;
1392         char *p = NULL;
1393         int rcode;
1394
1395         if (!s || !*s)
1396                 return 1;
1397
1398         if (!(p = strchr(s, '\n')) || *++p) {
1399                 p = xmalloc(strlen(s) + 2);
1400                 strcpy(p, s);
1401                 strcat(p, "\n");
1402                 setup_string_in_str(&input, p);
1403                 rcode = parse_stream_outer(&input, flag);
1404                 free(p);
1405                 return rcode;
1406         } else {
1407                 setup_string_in_str(&input, s);
1408                 return parse_stream_outer(&input, flag);
1409         }
1410 }
1411
1412 int parse_file_outer(void) {
1413         int rcode;
1414         struct in_str input;
1415         setup_file_in_str(&input);
1416         rcode = parse_stream_outer(&input, FLAG_PARSE_SEMICOLON);
1417         return rcode;
1418 }
1419
1420 static void u_boot_hush_reloc(void) {
1421         unsigned long addr;
1422         struct reserved_combo *r;
1423
1424         for (r = reserved_list; r < reserved_list + NRES; r++) {
1425                 addr = (ulong) (r->literal) + gd->reloc_off;
1426                 r->literal = (char *) addr;
1427         }
1428 }
1429
1430 int u_boot_hush_start(void) {
1431         if (top_vars == NULL) {
1432                 top_vars = malloc(sizeof(struct variables));
1433                 top_vars->name = "HUSH_VERSION";
1434                 top_vars->value = "0.01";
1435                 top_vars->next = 0;
1436                 top_vars->flg_export = 0;
1437                 top_vars->flg_read_only = 1;
1438                 u_boot_hush_reloc();
1439         }
1440         return 0;
1441 }
1442
1443 static void *xmalloc(size_t size) {
1444         void *p = NULL;
1445
1446         if (!(p = malloc(size))) {
1447                 printf_err("memory not allocated!\n");
1448                 for (;;)
1449                         ;
1450         }
1451         return p;
1452 }
1453
1454 static void *xrealloc(void *ptr, size_t size) {
1455         void *p = NULL;
1456
1457         if (!(p = realloc(ptr, size))) {
1458                 printf_err("memory not allocated!\n");
1459                 for (;;)
1460                         ;
1461         }
1462         return p;
1463 }
1464
1465 static char *insert_var_value(char *inp) {
1466         int res_str_len = 0;
1467         int len;
1468         int done = 0;
1469         char *p, *p1, *res_str = NULL;
1470
1471         while ((p = strchr(inp, SPECIAL_VAR_SYMBOL))) {
1472                 if (p != inp) {
1473                         len = p - inp;
1474                         res_str = xrealloc(res_str, (res_str_len + len));
1475                         strncpy((res_str + res_str_len), inp, len);
1476                         res_str_len += len;
1477                 }
1478                 inp = ++p;
1479                 p = strchr(inp, SPECIAL_VAR_SYMBOL);
1480                 *p = '\0';
1481                 if ((p1 = lookup_param(inp))) {
1482                         len = res_str_len + strlen(p1);
1483                         res_str = xrealloc(res_str, (1 + len));
1484                         strcpy((res_str + res_str_len), p1);
1485                         res_str_len = len;
1486                 }
1487                 *p = SPECIAL_VAR_SYMBOL;
1488                 inp = ++p;
1489                 done = 1;
1490         }
1491         if (done) {
1492                 res_str = xrealloc(res_str, (1 + res_str_len + strlen(inp)));
1493                 strcpy((res_str + res_str_len), inp);
1494                 while ((p = strchr(res_str, '\n'))) {
1495                         *p = ' ';
1496                 }
1497         }
1498         return (res_str == NULL) ? inp : res_str;
1499 }
1500
1501 static char **make_list_in(char **inp, char *name) {
1502         int len, i;
1503         int name_len = strlen(name);
1504         int n = 0;
1505         char **list;
1506         char *p1, *p2, *p3;
1507
1508         /* create list of variable values */
1509         list = xmalloc(sizeof(*list));
1510         for (i = 0; inp[i]; i++) {
1511                 p3 = insert_var_value(inp[i]);
1512                 p1 = p3;
1513                 while (*p1) {
1514                         if ((*p1 == ' ')) {
1515                                 p1++;
1516                                 continue;
1517                         }
1518                         if ((p2 = strchr(p1, ' '))) {
1519                                 len = p2 - p1;
1520                         } else {
1521                                 len = strlen(p1);
1522                                 p2 = p1 + len;
1523                         }
1524                         /* we use n + 2 in realloc for list,because we add
1525                          * new element and then we will add NULL element */
1526                         list = xrealloc(list, sizeof(*list) * (n + 2));
1527                         list[n] = xmalloc(2 + name_len + len);
1528                         strcpy(list[n], name);
1529                         strcat(list[n], "=");
1530                         strncat(list[n], p1, len);
1531                         list[n++][name_len + len + 1] = '\0';
1532                         p1 = p2;
1533                 }
1534                 if (p3 != inp[i])
1535                         free(p3);
1536         }
1537         list[n] = NULL;
1538         return list;
1539 }
1540
1541 /* Make new string for parser */
1542 static char * make_string(char ** inp) {
1543         char *p;
1544         char *str = NULL;
1545         int n;
1546         int len = 2;
1547
1548         for (n = 0; inp[n]; n++) {
1549                 p = insert_var_value(inp[n]);
1550                 str = xrealloc(str, (len + strlen(p)));
1551                 if (n) {
1552                         strcat(str, " ");
1553                 } else {
1554                         *str = '\0';
1555                 }
1556                 strcat(str, p);
1557                 len = strlen(str) + 3;
1558                 if (p != inp[n])
1559                         free(p);
1560         }
1561         len = strlen(str);
1562         *(str + len) = '\n';
1563         *(str + len + 1) = '\0';
1564         return str;
1565 }
1566
1567 int do_true(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
1568 {
1569         return 0;
1570 }
1571
1572 U_BOOT_CMD(true, 1, 1, do_true, "return true\n", NULL);
1573
1574 #endif /* CFG_HUSH_PARSER */
1575 /****************************************************************************/