source: MondoRescue/branches/stable/mindi-busybox/shell/hush.c @ 821

Last change on this file since 821 was 821, checked in by Bruno Cornec, 14 years ago

Addition of busybox 1.2.1 as a mindi-busybox new package
This should avoid delivering binary files in mindi not built there (Fedora and Debian are quite serious about that)

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