These messages can be .rodata, so make them even more const.
[oweals/busybox.git] / lash.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * lash -- the BusyBox Lame-Ass SHell
4  *
5  * Copyright (C) 1999,2000,2001 by Lineo, inc.
6  * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
7  *
8  * Based in part on ladsh.c by Michael K. Johnson and Erik W. Troan, which is
9  * under the following liberal license: "We have placed this source code in the
10  * public domain. Use it in any project, free or commercial."
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or
15  * (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20  * General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25  *
26  */
27
28 /* The parsing engine of this program is officially at a dead-end.
29  * Future work in that direction should move to the work posted
30  * at http://doolittle.faludi.com/~larry/parser.html .
31  * A start on the integration of that work with the rest of sh.c
32  * is at http://codepoet.org/sh.c .
33  */
34 //
35 //This works pretty well now, and is now on by default.
36 #define BB_FEATURE_SH_ENVIRONMENT
37 //
38 //Backtick support has some problems, use at your own risk!
39 //#define BB_FEATURE_SH_BACKTICKS
40 //
41 //If, then, else, etc. support..  This should now behave basically
42 //like any other Bourne shell -- sortof...
43 #define BB_FEATURE_SH_IF_EXPRESSIONS
44 //
45 /* This is currently sortof broken, only for the brave... */
46 #undef HANDLE_CONTINUATION_CHARS
47 //
48 /* This would be great -- if wordexp wouldn't strip all quoting
49  * out from the target strings...  As is, a parser needs  */
50 #undef BB_FEATURE_SH_WORDEXP
51 //
52 //For debugging/development on the shell only...
53 //#define DEBUG_SHELL
54
55
56 #include <stdio.h>
57 #include <stdlib.h>
58 #include <ctype.h>
59 #include <errno.h>
60 #include <fcntl.h>
61 #include <signal.h>
62 #include <string.h>
63 #include <sys/ioctl.h>
64 #include <sys/wait.h>
65 #include <unistd.h>
66 #include <getopt.h>
67 #include "busybox.h"
68 #include "cmdedit.h"
69
70 #ifdef BB_LOCALE_SUPPORT
71 #include <locale.h>
72 #endif
73
74 //#define BB_FEATURE_SH_WORDEXP
75
76 #ifdef BB_FEATURE_SH_WORDEXP
77 #include <wordexp.h>
78 #define expand_t        wordexp_t
79 #undef BB_FEATURE_SH_BACKTICKS
80 #else
81 #include <glob.h>
82 #define expand_t        glob_t
83 #endif  
84
85
86 static const int MAX_READ = 128;        /* size of input buffer for `read' builtin */
87 #define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
88
89
90 enum redir_type { REDIRECT_INPUT, REDIRECT_OVERWRITE,
91         REDIRECT_APPEND
92 };
93
94 static const unsigned int DEFAULT_CONTEXT=0x1;
95 static const unsigned int IF_TRUE_CONTEXT=0x2;
96 static const unsigned int IF_FALSE_CONTEXT=0x4;
97 static const unsigned int THEN_EXP_CONTEXT=0x8;
98 static const unsigned int ELSE_EXP_CONTEXT=0x10;
99
100
101 struct jobset {
102         struct job *head;                       /* head of list of running jobs */
103         struct job *fg;                         /* current foreground job */
104 };
105
106 struct redir_struct {
107         enum redir_type type;   /* type of redirection */
108         int fd;                                         /* file descriptor being redirected */
109         char *filename;                         /* file to redirect fd to */
110 };
111
112 struct child_prog {
113         pid_t pid;                                      /* 0 if exited */
114         char **argv;                            /* program name and arguments */
115         int num_redirects;                      /* elements in redirection array */
116         struct redir_struct *redirects; /* I/O redirects */
117         int is_stopped;                         /* is the program currently running? */
118         struct job *family;                     /* pointer back to the child's parent job */
119 };
120
121 struct job {
122         int jobid;                                      /* job number */
123         int num_progs;                          /* total number of programs in job */
124         int running_progs;                      /* number of programs running */
125         char *text;                                     /* name of job */
126         char *cmdbuf;                           /* buffer various argv's point into */
127         pid_t pgrp;                                     /* process group ID for the job */
128         struct child_prog *progs;       /* array of programs in job */
129         struct job *next;                       /* to track background commands */
130         int stopped_progs;                      /* number of programs alive, but stopped */
131         unsigned int job_context;       /* bitmask defining current context */
132         struct jobset *job_list;
133 };
134
135 struct built_in_command {
136         char *cmd;                                      /* name */
137         char *descr;                            /* description */
138         int (*function) (struct child_prog *);  /* function ptr */
139 };
140
141 struct close_me {
142         int fd;
143         struct close_me *next;
144 };
145
146 /* function prototypes for builtins */
147 static int builtin_cd(struct child_prog *cmd);
148 static int builtin_exec(struct child_prog *cmd);
149 static int builtin_exit(struct child_prog *cmd);
150 static int builtin_fg_bg(struct child_prog *cmd);
151 static int builtin_help(struct child_prog *cmd);
152 static int builtin_jobs(struct child_prog *dummy);
153 static int builtin_pwd(struct child_prog *dummy);
154 static int builtin_export(struct child_prog *cmd);
155 static int builtin_source(struct child_prog *cmd);
156 static int builtin_unset(struct child_prog *cmd);
157 static int builtin_read(struct child_prog *cmd);
158 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
159 static int builtin_if(struct child_prog *cmd);
160 static int builtin_then(struct child_prog *cmd);
161 static int builtin_else(struct child_prog *cmd);
162 static int builtin_fi(struct child_prog *cmd);
163 /* function prototypes for shell stuff */
164 static int run_command_predicate(char *cmd);
165 #endif
166
167
168 /* function prototypes for shell stuff */
169 static void mark_open(int fd);
170 static void mark_closed(int fd);
171 static void close_all(void);
172 static void checkjobs(struct jobset *job_list);
173 static int get_command(FILE * source, char *command);
174 static int parse_command(char **command_ptr, struct job *job, int *inbg);
175 static int run_command(struct job *newjob, int inbg, int outpipe[2]);
176 static int pseudo_exec(struct child_prog *cmd) __attribute__ ((noreturn));
177 static int busy_loop(FILE * input);
178
179
180 /* Table of built-in functions (these are non-forking builtins, meaning they
181  * can change global variables in the parent shell process but they will not
182  * work with pipes and redirects; 'unset foo | whatever' will not work) */
183 static struct built_in_command bltins[] = {
184         {"bg", "Resume a job in the background", builtin_fg_bg},
185         {"cd", "Change working directory", builtin_cd},
186         {"exec", "Exec command, replacing this shell with the exec'd process", builtin_exec},
187         {"exit", "Exit from shell()", builtin_exit},
188         {"fg", "Bring job into the foreground", builtin_fg_bg},
189         {"jobs", "Lists the active jobs", builtin_jobs},
190         {"export", "Set environment variable", builtin_export},
191         {"unset", "Unset environment variable", builtin_unset},
192         {"read", "Input environment variable", builtin_read},
193         {".", "Source-in and run commands in a file", builtin_source},
194         /* to do: add ulimit */
195 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
196         {"if", NULL, builtin_if},
197         {"then", NULL, builtin_then},
198         {"else", NULL, builtin_else},
199         {"fi", NULL, builtin_fi},
200 #endif
201         {NULL, NULL, NULL}
202 };
203
204 /* Table of forking built-in functions (things that fork cannot change global
205  * variables in the parent process, such as the current working directory) */
206 static struct built_in_command bltins_forking[] = {
207         {"pwd", "Print current directory", builtin_pwd},
208         {"help", "List shell built-in commands", builtin_help},
209         {NULL, NULL, NULL}
210 };
211
212
213 /* Variables we export */
214 unsigned int shell_context;  /* Used in cmdedit.c to reset the
215                                                                 context when someone hits ^C */
216
217
218 /* Globals that are static to this file */
219 static char *cwd;
220 static char *local_pending_command = NULL;
221 static struct jobset job_list = { NULL, NULL };
222 static int argc;
223 static char **argv;
224 static struct close_me *close_me_head;
225 #ifdef BB_FEATURE_SH_ENVIRONMENT
226 static int last_bg_pid;
227 static int last_return_code;
228 static int show_x_trace;
229 #endif
230 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
231 static char syntax_err[]="syntax error near unexpected token";
232 #endif
233
234 static char *PS1;
235 static char *PS2 = "> ";
236
237
238 #ifdef DEBUG_SHELL
239 static inline void debug_printf(const char *format, ...)
240 {
241         va_list args;
242         va_start(args, format);
243         vfprintf(stderr, format, args);
244         va_end(args);
245 }
246 #else
247 static inline void debug_printf(const char *format, ...) { }
248 #endif
249
250 /*
251         Most builtins need access to the struct child_prog that has
252         their arguments, previously coded as cmd->progs[0].  That coding
253         can exhibit a bug, if the builtin is not the first command in
254         a pipeline: "echo foo | exec sort" will attempt to exec foo.
255
256 builtin   previous use      notes
257 ------ -----------------  ---------
258 cd      cmd->progs[0]
259 exec    cmd->progs[0]  squashed bug: didn't look for applets or forking builtins
260 exit    cmd->progs[0]
261 fg_bg   cmd->progs[0], job_list->head, job_list->fg
262 help    0
263 jobs    job_list->head
264 pwd     0
265 export  cmd->progs[0]
266 source  cmd->progs[0]
267 unset   cmd->progs[0]
268 read    cmd->progs[0]
269 if      cmd->job_context,  cmd->text
270 then    cmd->job_context,  cmd->text
271 else    cmd->job_context,  cmd->text
272 fi      cmd->job_context
273
274 The use of cmd->text by if/then/else/fi is hopelessly hacky.
275 Would it work to increment cmd->progs[0]->argv and recurse,
276 somewhat like builtin_exec does?
277
278 I added "struct job *family;" to struct child_prog,
279 and switched API to builtin_foo(struct child_prog *child);
280 So   cmd->text        becomes  child->family->text
281      cmd->job_context  becomes  child->family->job_context
282      cmd->progs[0]    becomes  *child
283      job_list          becomes  child->family->job_list
284  */
285
286 /* built-in 'cd <path>' handler */
287 static int builtin_cd(struct child_prog *child)
288 {
289         char *newdir;
290
291         if (child->argv[1] == NULL)
292                 newdir = getenv("HOME");
293         else
294                 newdir = child->argv[1];
295         if (chdir(newdir)) {
296                 printf("cd: %s: %m\n", newdir);
297                 return EXIT_FAILURE;
298         }
299         cwd = xgetcwd(cwd);
300
301         return EXIT_SUCCESS;
302 }
303
304 /* built-in 'exec' handler */
305 static int builtin_exec(struct child_prog *child)
306 {
307         if (child->argv[1] == NULL)
308                 return EXIT_SUCCESS;   /* Really? */
309         child->argv++;
310         close_all();
311         pseudo_exec(child);
312         /* never returns */
313 }
314
315 /* built-in 'exit' handler */
316 static int builtin_exit(struct child_prog *child)
317 {
318         if (child->argv[1] == NULL)
319                 exit(EXIT_SUCCESS);
320
321         exit (atoi(child->argv[1]));
322 }
323
324 /* built-in 'fg' and 'bg' handler */
325 static int builtin_fg_bg(struct child_prog *child)
326 {
327         int i, jobNum;
328         struct job *job=NULL;
329         
330         if (!child->argv[1] || child->argv[2]) {
331                 error_msg("%s: exactly one argument is expected",
332                                 child->argv[0]);
333                 return EXIT_FAILURE;
334         }
335
336         if (sscanf(child->argv[1], "%%%d", &jobNum) != 1) {
337                 error_msg("%s: bad argument '%s'",
338                                 child->argv[0], child->argv[1]);
339                 return EXIT_FAILURE;
340         }
341
342         for (job = child->family->job_list->head; job; job = job->next) {
343                 if (job->jobid == jobNum) {
344                         break;
345                 }
346         }
347
348         if (!job) {
349                 error_msg("%s: unknown job %d",
350                                 child->argv[0], jobNum);
351                 return EXIT_FAILURE;
352         }
353
354         if (*child->argv[0] == 'f') {
355                 /* Make this job the foreground job */
356                 /* suppress messages when run from /linuxrc mag@sysgo.de */
357                 if (tcsetpgrp(0, job->pgrp) && errno != ENOTTY)
358                         perror_msg("tcsetpgrp"); 
359                 child->family->job_list->fg = job;
360         }
361
362         /* Restart the processes in the job */
363         for (i = 0; i < job->num_progs; i++)
364                 job->progs[i].is_stopped = 0;
365
366         kill(-job->pgrp, SIGCONT);
367
368         job->stopped_progs = 0;
369
370         return EXIT_SUCCESS;
371 }
372
373 /* built-in 'help' handler */
374 static int builtin_help(struct child_prog *dummy)
375 {
376         struct built_in_command *x;
377
378         printf("\nBuilt-in commands:\n");
379         printf("-------------------\n");
380         for (x = bltins; x->cmd; x++) {
381                 if (x->descr==NULL)
382                         continue;
383                 printf("%s\t%s\n", x->cmd, x->descr);
384         }
385         for (x = bltins_forking; x->cmd; x++) {
386                 if (x->descr==NULL)
387                         continue;
388                 printf("%s\t%s\n", x->cmd, x->descr);
389         }
390         printf("\n\n");
391         return EXIT_SUCCESS;
392 }
393
394 /* built-in 'jobs' handler */
395 static int builtin_jobs(struct child_prog *child)
396 {
397         struct job *job;
398         char *status_string;
399
400         for (job = child->family->job_list->head; job; job = job->next) {
401                 if (job->running_progs == job->stopped_progs)
402                         status_string = "Stopped";
403                 else
404                         status_string = "Running";
405
406                 printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->text);
407         }
408         return EXIT_SUCCESS;
409 }
410
411
412 /* built-in 'pwd' handler */
413 static int builtin_pwd(struct child_prog *dummy)
414 {
415         printf( "%s\n", cwd);
416         return EXIT_SUCCESS;
417 }
418
419 /* built-in 'export VAR=value' handler */
420 static int builtin_export(struct child_prog *child)
421 {
422         int res;
423         char *v = child->argv[1];
424
425         if (v == NULL) {
426                 char **e;
427                 for (e = environ; *e; e++) {
428                         printf( "%s\n", *e);
429                 }
430                 return 0;
431         }
432         res = putenv(v);
433         if (res)
434                 fprintf(stderr, "export: %m\n");
435 #ifndef BB_FEATURE_SH_SIMPLE_PROMPT
436         if (strncmp(v, "PS1=", 4)==0)
437                 PS1 = getenv("PS1");
438 #endif
439
440 #ifdef BB_LOCALE_SUPPORT
441         if(strncmp(v, "LC_ALL=", 7)==0)
442                 setlocale(LC_ALL, getenv("LC_ALL"));
443         if(strncmp(v, "LC_CTYPE=", 9)==0)
444                 setlocale(LC_CTYPE, getenv("LC_CTYPE"));
445 #endif
446
447         return (res);
448 }
449
450 /* built-in 'read VAR' handler */
451 static int builtin_read(struct child_prog *child)
452 {
453         int res = 0, len, newlen;
454         char *s;
455         char string[MAX_READ];
456
457         if (child->argv[1]) {
458                 /* argument (VAR) given: put "VAR=" into buffer */
459                 strcpy(string, child->argv[1]);
460                 len = strlen(string);
461                 string[len++] = '=';
462                 string[len]   = '\0';
463                 fgets(&string[len], sizeof(string) - len, stdin);       /* read string */
464                 newlen = strlen(string);
465                 if(newlen > len)
466                         string[--newlen] = '\0';        /* chomp trailing newline */
467                 /*
468                 ** string should now contain "VAR=<value>"
469                 ** copy it (putenv() won't do that, so we must make sure
470                 ** the string resides in a static buffer!)
471                 */
472                 res = -1;
473                 if((s = strdup(string)))
474                         res = putenv(s);
475                 if (res)
476                         fprintf(stderr, "read: %m\n");
477         }
478         else
479                 fgets(string, sizeof(string), stdin);
480
481         return (res);
482 }
483
484 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
485 /* Built-in handler for 'if' commands */
486 static int builtin_if(struct child_prog *child)
487 {
488         struct job *cmd = child->family;
489         int status;
490         char* charptr1=cmd->text+3; /* skip over the leading 'if ' */
491
492         /* Now run the 'if' command */
493         debug_printf( "job=%p entering builtin_if ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
494         status = run_command_predicate(charptr1);
495         debug_printf( "if test returned ");
496         if (status == 0) {
497                 debug_printf( "TRUE\n");
498                 cmd->job_context |= IF_TRUE_CONTEXT;
499         } else {
500                 debug_printf( "FALSE\n");
501                 cmd->job_context |= IF_FALSE_CONTEXT;
502         }
503         debug_printf("job=%p builtin_if set job context to %x\n", cmd, cmd->job_context);
504         shell_context++;
505
506         return status;
507 }
508
509 /* Built-in handler for 'then' (part of the 'if' command) */
510 static int builtin_then(struct child_prog *child)
511 {
512         struct job *cmd = child->family;
513         char* charptr1=cmd->text+5; /* skip over the leading 'then ' */
514
515         debug_printf( "job=%p entering builtin_then ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
516         if (! (cmd->job_context & (IF_TRUE_CONTEXT|IF_FALSE_CONTEXT))) {
517                 shell_context = 0; /* Reset the shell's context on an error */
518                 error_msg("%s `then'", syntax_err);
519                 return EXIT_FAILURE;
520         }
521
522         cmd->job_context |= THEN_EXP_CONTEXT;
523         debug_printf("job=%p builtin_then set job context to %x\n", cmd, cmd->job_context);
524
525         /* If the if result was FALSE, skip the 'then' stuff */
526         if (cmd->job_context & IF_FALSE_CONTEXT) {
527                 return EXIT_SUCCESS;
528         }
529
530         /* Seems the if result was TRUE, so run the 'then' command */
531         debug_printf( "'then' now running '%s'\n", charptr1);
532
533         return(run_command_predicate(charptr1));
534 }
535
536 /* Built-in handler for 'else' (part of the 'if' command) */
537 static int builtin_else(struct child_prog *child)
538 {
539         struct job *cmd = child->family;
540         char* charptr1=cmd->text+5; /* skip over the leading 'else ' */
541
542         debug_printf( "job=%p entering builtin_else ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
543
544         if (! (cmd->job_context & THEN_EXP_CONTEXT)) {
545                 shell_context = 0; /* Reset the shell's context on an error */
546                 error_msg("%s `else'", syntax_err);
547                 return EXIT_FAILURE;
548         }
549         /* If the if result was TRUE, skip the 'else' stuff */
550         if (cmd->job_context & IF_TRUE_CONTEXT) {
551                 return EXIT_SUCCESS;
552         }
553
554         cmd->job_context |= ELSE_EXP_CONTEXT;
555         debug_printf("job=%p builtin_else set job context to %x\n", cmd, cmd->job_context);
556
557         /* Now run the 'else' command */
558         debug_printf( "'else' now running '%s'\n", charptr1);
559         return(run_command_predicate(charptr1));
560 }
561
562 /* Built-in handler for 'fi' (part of the 'if' command) */
563 static int builtin_fi(struct child_prog *child)
564 {
565         struct job *cmd = child->family;
566         debug_printf( "job=%p entering builtin_fi ('%s')-- context=%d\n", cmd, "", cmd->job_context);
567         if (! (cmd->job_context & (IF_TRUE_CONTEXT|IF_FALSE_CONTEXT))) {
568                 shell_context = 0; /* Reset the shell's context on an error */
569                 error_msg("%s `fi'", syntax_err);
570                 return EXIT_FAILURE;
571         }
572         /* Clear out the if and then context bits */
573         cmd->job_context &= ~(IF_TRUE_CONTEXT|IF_FALSE_CONTEXT|THEN_EXP_CONTEXT|ELSE_EXP_CONTEXT);
574         debug_printf("job=%p builtin_fi set job context to %x\n", cmd, cmd->job_context);
575         shell_context--;
576         return EXIT_SUCCESS;
577 }
578 #endif
579
580 /* Built-in '.' handler (read-in and execute commands from file) */
581 static int builtin_source(struct child_prog *child)
582 {
583         FILE *input;
584         int status;
585         int fd;
586
587         if (child->argv[1] == NULL)
588                 return EXIT_FAILURE;
589
590         input = fopen(child->argv[1], "r");
591         if (!input) {
592                 printf( "Couldn't open file '%s'\n", child->argv[1]);
593                 return EXIT_FAILURE;
594         }
595
596         fd=fileno(input);
597         mark_open(fd);
598         /* Now run the file */
599         status = busy_loop(input);
600         fclose(input);
601         mark_closed(fd);
602         return (status);
603 }
604
605 /* built-in 'unset VAR' handler */
606 static int builtin_unset(struct child_prog *child)
607 {
608         if (child->argv[1] == NULL) {
609                 printf( "unset: parameter required.\n");
610                 return EXIT_FAILURE;
611         }
612         unsetenv(child->argv[1]);
613         return EXIT_SUCCESS;
614 }
615
616 #ifdef BB_FEATURE_SH_IF_EXPRESSIONS
617 /* currently used by if/then/else.
618  *
619  * Reparsing the command line for this purpose is gross,
620  * incorrect, and fundamentally unfixable; in particular,
621  * think about what happens with command substitution.
622  * We really need to pull out the run, wait, return status
623  * functionality out of busy_loop so we can child->argv++
624  * and use that, without going back through parse_command.
625  */
626 static int run_command_predicate(char *cmd)
627 {
628         local_pending_command = xstrdup(cmd);
629         return( busy_loop(NULL));
630 }
631 #endif
632
633 static void mark_open(int fd)
634 {
635         struct close_me *new = xmalloc(sizeof(struct close_me));
636         new->fd = fd;
637         new->next = close_me_head;
638         close_me_head = new;
639 }
640
641 static void mark_closed(int fd)
642 {
643         struct close_me *tmp;
644         if (close_me_head == NULL || close_me_head->fd != fd)
645                 error_msg_and_die("corrupt close_me");
646         tmp = close_me_head;
647         close_me_head = close_me_head->next;
648         free(tmp);
649 }
650
651 static void close_all()
652 {
653         struct close_me *c, *tmp;
654         for (c=close_me_head; c; c=tmp) {
655                 close(c->fd);
656                 tmp=c->next;
657                 free(c);
658         }
659         close_me_head = NULL;
660 }
661
662
663 /* free up all memory from a job */
664 static void free_job(struct job *cmd)
665 {
666         int i;
667         struct jobset *keep;
668
669         for (i = 0; i < cmd->num_progs; i++) {
670                 free(cmd->progs[i].argv);
671                 if (cmd->progs[i].redirects)
672                         free(cmd->progs[i].redirects);
673         }
674         if (cmd->progs)
675                 free(cmd->progs);
676         if (cmd->text)
677                 free(cmd->text);
678         if (cmd->cmdbuf)
679                 free(cmd->cmdbuf);
680         keep = cmd->job_list;
681         memset(cmd, 0, sizeof(struct job));
682         cmd->job_list = keep;
683 }
684
685 /* remove a job from a jobset */
686 static void remove_job(struct jobset *j_list, struct job *job)
687 {
688         struct job *prevjob;
689
690         free_job(job);
691         if (job == j_list->head) {
692                 j_list->head = job->next;
693         } else {
694                 prevjob = j_list->head;
695                 while (prevjob->next != job)
696                         prevjob = prevjob->next;
697                 prevjob->next = job->next;
698         }
699
700         free(job);
701 }
702
703 /* Checks to see if any background processes have exited -- if they 
704    have, figure out why and see if a job has completed */
705 static void checkjobs(struct jobset *j_list)
706 {
707         struct job *job;
708         pid_t childpid;
709         int status;
710         int prognum = 0;
711
712         while ((childpid = waitpid(-1, &status, WNOHANG | WUNTRACED)) > 0) {
713                 for (job = j_list->head; job; job = job->next) {
714                         prognum = 0;
715                         while (prognum < job->num_progs &&
716                                    job->progs[prognum].pid != childpid) prognum++;
717                         if (prognum < job->num_progs)
718                                 break;
719                 }
720
721                 /* This happens on backticked commands */
722                 if(job==NULL)
723                         return;
724
725                 if (WIFEXITED(status) || WIFSIGNALED(status)) {
726                         /* child exited */
727                         job->running_progs--;
728                         job->progs[prognum].pid = 0;
729
730                         if (!job->running_progs) {
731                                 printf(JOB_STATUS_FORMAT, job->jobid, "Done", job->text);
732                                 remove_job(j_list, job);
733                         }
734                 } else {
735                         /* child stopped */
736                         job->stopped_progs++;
737                         job->progs[prognum].is_stopped = 1;
738
739                         if (job->stopped_progs == job->num_progs) {
740                                 printf(JOB_STATUS_FORMAT, job->jobid, "Stopped",
741                                            job->text);
742                         }
743                 }
744         }
745
746         if (childpid == -1 && errno != ECHILD)
747                 perror_msg("waitpid");
748 }
749
750 /* squirrel != NULL means we squirrel away copies of stdin, stdout,
751  * and stderr if they are redirected. */
752 static int setup_redirects(struct child_prog *prog, int squirrel[])
753 {
754         int i;
755         int openfd;
756         int mode = O_RDONLY;
757         struct redir_struct *redir = prog->redirects;
758
759         for (i = 0; i < prog->num_redirects; i++, redir++) {
760                 switch (redir->type) {
761                 case REDIRECT_INPUT:
762                         mode = O_RDONLY;
763                         break;
764                 case REDIRECT_OVERWRITE:
765                         mode = O_WRONLY | O_CREAT | O_TRUNC;
766                         break;
767                 case REDIRECT_APPEND:
768                         mode = O_WRONLY | O_CREAT | O_APPEND;
769                         break;
770                 }
771
772                 openfd = open(redir->filename, mode, 0666);
773                 if (openfd < 0) {
774                         /* this could get lost if stderr has been redirected, but
775                            bash and ash both lose it as well (though zsh doesn't!) */
776                         perror_msg("error opening %s", redir->filename);
777                         return 1;
778                 }
779
780                 if (openfd != redir->fd) {
781                         if (squirrel && redir->fd < 3) {
782                                 squirrel[redir->fd] = dup(redir->fd);
783                         }
784                         dup2(openfd, redir->fd);
785                         close(openfd);
786                 }
787         }
788
789         return 0;
790 }
791
792 static void restore_redirects(int squirrel[])
793 {
794         int i, fd;
795         for (i=0; i<3; i++) {
796                 fd = squirrel[i];
797                 if (fd != -1) {
798                         /* No error checking.  I sure wouldn't know what
799                          * to do with an error if I found one! */
800                         dup2(fd, i);
801                         close(fd);
802                 }
803         }
804 }
805
806 static inline void cmdedit_set_initial_prompt(void)
807 {
808 #ifdef BB_FEATURE_SH_SIMPLE_PROMPT
809         PS1 = NULL;
810 #else
811         PS1 = getenv("PS1");
812         if(PS1==0)
813                 PS1 = "\\w \\$ ";
814 #endif  
815 }
816
817 static inline void setup_prompt_string(char **prompt_str)
818 {
819 #ifdef BB_FEATURE_SH_SIMPLE_PROMPT
820         /* Set up the prompt */
821         if (shell_context == 0) {
822                 if (PS1)
823                         free(PS1);
824                 PS1=xmalloc(strlen(cwd)+4);
825                 sprintf(PS1, "%s %s", cwd, ( geteuid() != 0 ) ?  "$ ":"# ");
826                 *prompt_str = PS1;
827         } else {
828                 *prompt_str = PS2;
829         }
830 #else
831         *prompt_str = (shell_context==0)? PS1 : PS2;
832 #endif  
833 }
834
835 static int get_command(FILE * source, char *command)
836 {
837         char *prompt_str;
838
839         if (source == NULL) {
840                 if (local_pending_command) {
841                         /* a command specified (-c option): return it & mark it done */
842                         strcpy(command, local_pending_command);
843                         free(local_pending_command);
844                         local_pending_command = NULL;
845                         return 0;
846                 }
847                 return 1;
848         }
849
850         if (source == stdin) {
851                 setup_prompt_string(&prompt_str);
852
853 #ifdef BB_FEATURE_COMMAND_EDITING
854                 /*
855                 ** enable command line editing only while a command line
856                 ** is actually being read; otherwise, we'll end up bequeathing
857                 ** atexit() handlers and other unwanted stuff to our
858                 ** child processes (rob@sysgo.de)
859                 */
860                 cmdedit_read_input(prompt_str, command);
861                 cmdedit_terminate();
862                 return 0;
863 #else
864                 fputs(prompt_str, stdout);
865 #endif
866         }
867
868         if (!fgets(command, BUFSIZ - 2, source)) {
869                 if (source == stdin)
870                         printf("\n");
871                 return 1;
872         }
873
874         return 0;
875 }
876
877 #ifdef BB_FEATURE_SH_ENVIRONMENT
878 static char* itoa(register int i)
879 {
880         static char a[7]; /* Max 7 ints */
881         register char *b = a + sizeof(a) - 1;
882         int   sign = (i < 0);
883
884         if (sign)
885                 i = -i;
886         *b = 0;
887         do
888         {
889                 *--b = '0' + (i % 10);
890                 i /= 10;
891         }
892         while (i);
893         if (sign)
894                 *--b = '-';
895         return b;
896 }
897 #endif  
898
899 #if defined BB_FEATURE_SH_ENVIRONMENT && ! defined BB_FEATURE_SH_WORDEXP
900 char * strsep_space( char *string, int * ix)
901 {
902         char *token, *begin;
903
904         begin = string;
905
906         /* Short circuit the trivial case */
907         if ( !string || ! string[*ix])
908                 return NULL;
909
910         /* Find the end of the token. */
911         while( string && string[*ix] && !isspace(string[*ix]) ) {
912                 (*ix)++;
913         }
914
915         /* Find the end of any whitespace trailing behind 
916          * the token and let that be part of the token */
917         while( string && string[*ix] && isspace(string[*ix]) ) {
918                 (*ix)++;
919         }
920
921         if (! string && *ix==0) {
922                 /* Nothing useful was found */
923                 return NULL;
924         }
925
926         token = xmalloc(*ix+1);
927         token[*ix] = '\0';
928         strncpy(token, string,  *ix); 
929
930         return token;
931 }
932 #endif  
933
934
935 static int expand_arguments(char *command)
936 {
937 #ifdef BB_FEATURE_SH_ENVIRONMENT
938         expand_t expand_result;
939         char *src, *dst, *var;
940         int ix = 0;
941         int i=0, length, total_length=0, retval;
942         const char *out_of_space = "out of space during expansion"; 
943 #endif
944
945         /* get rid of the terminating \n */
946         chomp(command);
947         
948         /* Fix up escape sequences to be the Real Thing(tm) */
949         while( command && command[ix]) {
950                 if (command[ix] == '\\') {
951                         const char *tmp = command+ix+1;
952                         command[ix] = process_escape_sequence(  &tmp );
953                         memmove(command+ix + 1, tmp, strlen(tmp)+1);
954                 }
955                 ix++;
956         }
957
958 #ifdef BB_FEATURE_SH_ENVIRONMENT
959
960
961 #ifdef BB_FEATURE_SH_WORDEXP
962         /* This first part uses wordexp() which is a wonderful C lib 
963          * function which expands nearly everything.  */ 
964         retval = wordexp (command, &expand_result, WRDE_SHOWERR);
965         if (retval == WRDE_NOSPACE) {
966                 /* Mem may have been allocated... */
967                 wordfree (&expand_result);
968                 error_msg(out_of_space);
969                 return FALSE;
970         }
971         if (retval < 0) {
972                 /* Some other error.  */
973                 error_msg("syntax error");
974                 return FALSE;
975         }
976         
977         if (expand_result.we_wordc > 0) {
978                 /* Convert from char** (one word per string) to a simple char*,
979                  * but don't overflow command which is BUFSIZ in length */
980                 *command = '\0';
981                 while (i < expand_result.we_wordc && total_length < BUFSIZ) {
982                         length=strlen(expand_result.we_wordv[i])+1;
983                         if (BUFSIZ-total_length-length <= 0) {
984                                 error_msg(out_of_space);
985                                 return FALSE;
986                         }
987                         strcat(command+total_length, expand_result.we_wordv[i++]);
988                         strcat(command+total_length, " ");
989                         total_length+=length;
990                 }
991                 wordfree (&expand_result);
992         }
993 #else
994
995         /* Ok.  They don't have a recent glibc and they don't have uClibc.  Chances
996          * are about 100% they don't have wordexp(). So instead the best we can do
997          * is use glob and then fixup environment variables and such ourselves.
998          * This is better then nothing, but certainly not perfect */
999
1000         /* It turns out that glob is very stupid.  We have to feed it one word at a
1001          * time since it can't cope with a full string.  Here we convert command
1002          * (char*) into cmd (char**, one word per string) */
1003         {
1004         
1005                 int flags = GLOB_NOCHECK
1006 #ifdef GLOB_BRACE
1007                                 | GLOB_BRACE
1008 #endif  
1009 #ifdef GLOB_TILDE
1010                                 | GLOB_TILDE
1011 #endif  
1012                         ;
1013                 char *tmpcmd, *cmd, *cmd_copy;
1014                 /* We need a clean copy, so strsep can mess up the copy while
1015                  * we write stuff into the original (in a minute) */
1016                 cmd = cmd_copy = strdup(command);
1017                 *command = '\0';
1018                 for (ix = 0, tmpcmd = cmd; 
1019                                 (tmpcmd = strsep_space(cmd, &ix)) != NULL; cmd += ix, ix=0) {
1020                         if (*tmpcmd == '\0')
1021                                 break;
1022                         /* we need to trim() the result for glob! */
1023                         trim(tmpcmd);
1024                         retval = glob(tmpcmd, flags, NULL, &expand_result);
1025                         free(tmpcmd); /* Free mem allocated by strsep_space */
1026                         if (retval == GLOB_NOSPACE) {
1027                                 /* Mem may have been allocated... */
1028                                 globfree (&expand_result);
1029                                 error_msg(out_of_space);
1030                                 return FALSE;
1031                         } else if (retval != 0) {
1032                                 /* Some other error.  GLOB_NOMATCH shouldn't
1033                                  * happen because of the GLOB_NOCHECK flag in 
1034                                  * the glob call. */
1035                                 error_msg("syntax error");
1036                                 return FALSE;
1037                         } else {
1038                         /* Convert from char** (one word per string) to a simple char*,
1039                          * but don't overflow command which is BUFSIZ in length */
1040                                 for (i=0; i < expand_result.gl_pathc; i++) {
1041                                         length=strlen(expand_result.gl_pathv[i]);
1042                                         if (total_length+length+1 >= BUFSIZ) {
1043                                                 error_msg(out_of_space);
1044                                                 return FALSE;
1045                                         }
1046                                         strcat(command+total_length, " ");
1047                                         total_length+=1;
1048                                         strcat(command+total_length, expand_result.gl_pathv[i]);
1049                                         total_length+=length;
1050                                 }
1051                                 globfree (&expand_result);
1052                         }
1053                 }
1054                 free(cmd_copy);
1055                 trim(command);
1056         }
1057         
1058 #endif  
1059
1060         /* Now do the shell variable substitutions which 
1061          * wordexp can't do for us, namely $? and $! */
1062         src = command;
1063         while((dst = strchr(src,'$')) != NULL){
1064                 var = NULL;
1065                 switch(*(dst+1)) {
1066                         case '?':
1067                                 var = itoa(last_return_code);
1068                                 break;
1069                         case '!':
1070                                 if (last_bg_pid==-1)
1071                                         *(var)='\0';
1072                                 else
1073                                         var = itoa(last_bg_pid);
1074                                 break;
1075                                 /* Everything else like $$, $#, $[0-9], etc should all be
1076                                  * expanded by wordexp(), so we can in theory skip that stuff
1077                                  * here, but just to be on the safe side (i.e. since uClibc
1078                                  * wordexp doesn't do this stuff yet), lets leave it in for
1079                                  * now. */
1080                         case '$':
1081                                 var = itoa(getpid());
1082                                 break;
1083                         case '#':
1084                                 var = itoa(argc-1);
1085                                 break;
1086                         case '0':case '1':case '2':case '3':case '4':
1087                         case '5':case '6':case '7':case '8':case '9':
1088                                 {
1089                                         int ixx=*(dst + 1)-48;
1090                                         if (ixx >= argc) {
1091                                                 var='\0';
1092                                         } else {
1093                                                 var = argv[ixx];
1094                                         }
1095                                 }
1096                                 break;
1097
1098                 }
1099                 if (var) {
1100                         /* a single character construction was found, and 
1101                          * already handled in the case statement */
1102                         src=dst+2;
1103                 } else {
1104                         /* Looks like an environment variable */
1105                         char delim_hold;
1106                         int num_skip_chars=0;
1107                         int dstlen = strlen(dst);
1108                         /* Is this a ${foo} type variable? */
1109                         if (dstlen >=2 && *(dst+1) == '{') {
1110                                 src=strchr(dst+1, '}');
1111                                 num_skip_chars=1;
1112                         } else {
1113                                 src=dst+1;
1114                                 while(isalnum(*src) || *src=='_') src++;
1115                         }
1116                         if (src == NULL) {
1117                                 src = dst+dstlen;
1118                         }
1119                         delim_hold=*src;
1120                         *src='\0';  /* temporary */
1121                         var = getenv(dst + 1 + num_skip_chars);
1122                         *src=delim_hold;
1123                         src += num_skip_chars;
1124                 }
1125                 if (var == NULL) {
1126                         /* Seems we got an un-expandable variable.  So delete it. */
1127                         var = "";
1128                 }
1129                 {
1130                         int subst_len = strlen(var);
1131                         int trail_len = strlen(src);
1132                         if (dst+subst_len+trail_len >= command+BUFSIZ) {
1133                                 error_msg(out_of_space);
1134                                 return FALSE;
1135                         }
1136                         /* Move stuff to the end of the string to accommodate
1137                          * filling the created gap with the new stuff */
1138                         memmove(dst+subst_len, src, trail_len+1);
1139                         /* Now copy in the new stuff */
1140                         memcpy(dst, var, subst_len);
1141                         src = dst+subst_len;
1142                 }
1143         }
1144
1145 #endif  
1146         return TRUE;
1147 }
1148
1149 /* Return cmd->num_progs as 0 if no command is present (e.g. an empty
1150    line). If a valid command is found, command_ptr is set to point to
1151    the beginning of the next command (if the original command had more 
1152    then one job associated with it) or NULL if no more commands are 
1153    present. */
1154 static int parse_command(char **command_ptr, struct job *job, int *inbg)
1155 {
1156         char *command;
1157         char *return_command = NULL;
1158         char *src, *buf, *chptr;
1159         int argc_l = 0;
1160         int done = 0;
1161         int argv_alloced;
1162         int i, saw_quote = 0;
1163         char quote = '\0';
1164         int count;
1165         struct child_prog *prog;
1166
1167         /* skip leading white space */
1168         while (**command_ptr && isspace(**command_ptr))
1169                 (*command_ptr)++;
1170
1171         /* this handles empty lines or leading '#' characters */
1172         if (!**command_ptr || (**command_ptr == '#')) {
1173                 job->num_progs=0;
1174                 return 0;
1175         }
1176
1177         *inbg = 0;
1178         job->num_progs = 1;
1179         job->progs = xmalloc(sizeof(*job->progs));
1180
1181         /* We set the argv elements to point inside of this string. The 
1182            memory is freed by free_job(). Allocate twice the original
1183            length in case we need to quote every single character.
1184
1185            Getting clean memory relieves us of the task of NULL 
1186            terminating things and makes the rest of this look a bit 
1187            cleaner (though it is, admittedly, a tad less efficient) */
1188         job->cmdbuf = command = xcalloc(2*strlen(*command_ptr) + 1, sizeof(char));
1189         job->text = NULL;
1190
1191         prog = job->progs;
1192         prog->num_redirects = 0;
1193         prog->redirects = NULL;
1194         prog->is_stopped = 0;
1195         prog->family = job;
1196
1197         argv_alloced = 5;
1198         prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1199         prog->argv[0] = job->cmdbuf;
1200
1201         buf = command;
1202         src = *command_ptr;
1203         while (*src && !done) {
1204                 if (quote == *src) {
1205                         quote = '\0';
1206                 } else if (quote) {
1207                         if (*src == '\\') {
1208                                 src++;
1209                                 if (!*src) {
1210                                         error_msg("character expected after \\");
1211                                         free_job(job);
1212                                         return 1;
1213                                 }
1214
1215                                 /* in shell, "\'" should yield \' */
1216                                 if (*src != quote) {
1217                                         *buf++ = '\\';
1218                                         *buf++ = '\\';
1219                                 }
1220                         } else if (*src == '*' || *src == '?' || *src == '[' ||
1221                                            *src == ']') *buf++ = '\\';
1222                         *buf++ = *src;
1223                 } else if (isspace(*src)) {
1224                         if (*prog->argv[argc_l] || saw_quote) {
1225                                 buf++, argc_l++;
1226                                 /* +1 here leaves room for the NULL which ends argv */
1227                                 if ((argc_l + 1) == argv_alloced) {
1228                                         argv_alloced += 5;
1229                                         prog->argv = xrealloc(prog->argv,
1230                                                                                   sizeof(*prog->argv) *
1231                                                                                   argv_alloced);
1232                                 }
1233                                 prog->argv[argc_l] = buf;
1234                                 saw_quote = 0;
1235                         }
1236                 } else
1237                         switch (*src) {
1238                         case '"':
1239                         case '\'':
1240                                 quote = *src;
1241                                 saw_quote = 1;
1242                                 break;
1243
1244                         case '#':                       /* comment */
1245                                 if (*(src-1)== '$')
1246                                         *buf++ = *src;
1247                                 else
1248                                         done = 1;
1249                                 break;
1250
1251                         case '>':                       /* redirects */
1252                         case '<':
1253                                 i = prog->num_redirects++;
1254                                 prog->redirects = xrealloc(prog->redirects,
1255                                                                                           sizeof(*prog->redirects) *
1256                                                                                           (i + 1));
1257
1258                                 prog->redirects[i].fd = -1;
1259                                 if (buf != prog->argv[argc_l]) {
1260                                         /* the stuff before this character may be the file number 
1261                                            being redirected */
1262                                         prog->redirects[i].fd =
1263                                                 strtol(prog->argv[argc_l], &chptr, 10);
1264
1265                                         if (*chptr && *prog->argv[argc_l]) {
1266                                                 buf++, argc_l++;
1267                                                 prog->argv[argc_l] = buf;
1268                                         }
1269                                 }
1270
1271                                 if (prog->redirects[i].fd == -1) {
1272                                         if (*src == '>')
1273                                                 prog->redirects[i].fd = 1;
1274                                         else
1275                                                 prog->redirects[i].fd = 0;
1276                                 }
1277
1278                                 if (*src++ == '>') {
1279                                         if (*src == '>')
1280                                                 prog->redirects[i].type =
1281                                                         REDIRECT_APPEND, src++;
1282                                         else
1283                                                 prog->redirects[i].type = REDIRECT_OVERWRITE;
1284                                 } else {
1285                                         prog->redirects[i].type = REDIRECT_INPUT;
1286                                 }
1287
1288                                 /* This isn't POSIX sh compliant. Oh well. */
1289                                 chptr = src;
1290                                 while (isspace(*chptr))
1291                                         chptr++;
1292
1293                                 if (!*chptr) {
1294                                         error_msg("file name expected after %c", *(src-1));
1295                                         free_job(job);
1296                                         job->num_progs=0;
1297                                         return 1;
1298                                 }
1299
1300                                 prog->redirects[i].filename = buf;
1301                                 while (*chptr && !isspace(*chptr))
1302                                         *buf++ = *chptr++;
1303
1304                                 src = chptr - 1;        /* we src++ later */
1305                                 prog->argv[argc_l] = ++buf;
1306                                 break;
1307
1308                         case '|':                       /* pipe */
1309                                 /* finish this command */
1310                                 if (*prog->argv[argc_l] || saw_quote)
1311                                         argc_l++;
1312                                 if (!argc_l) {
1313                                         error_msg("empty command in pipe");
1314                                         free_job(job);
1315                                         job->num_progs=0;
1316                                         return 1;
1317                                 }
1318                                 prog->argv[argc_l] = NULL;
1319
1320                                 /* and start the next */
1321                                 job->num_progs++;
1322                                 job->progs = xrealloc(job->progs,
1323                                                                           sizeof(*job->progs) * job->num_progs);
1324                                 prog = job->progs + (job->num_progs - 1);
1325                                 prog->num_redirects = 0;
1326                                 prog->redirects = NULL;
1327                                 prog->is_stopped = 0;
1328                                 prog->family = job;
1329                                 argc_l = 0;
1330
1331                                 argv_alloced = 5;
1332                                 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1333                                 prog->argv[0] = ++buf;
1334
1335                                 src++;
1336                                 while (*src && isspace(*src))
1337                                         src++;
1338
1339                                 if (!*src) {
1340                                         error_msg("empty command in pipe");
1341                                         free_job(job);
1342                                         job->num_progs=0;
1343                                         return 1;
1344                                 }
1345                                 src--;                  /* we'll ++ it at the end of the loop */
1346
1347                                 break;
1348
1349                         case '&':                       /* background */
1350                                 *inbg = 1;
1351                         case ';':                       /* multiple commands */
1352                                 done = 1;
1353                                 return_command = *command_ptr + (src - *command_ptr) + 1;
1354                                 break;
1355
1356 #ifdef BB_FEATURE_SH_BACKTICKS
1357                         case '`':
1358                                 /* Exec a backtick-ed command */
1359                                 /* Besides any previous brokenness, I have not
1360                                  * updated backtick handling for close_me support.
1361                                  * I don't know if it needs it or not.  -- LRD */
1362                                 {
1363                                         char* charptr1=NULL, *charptr2;
1364                                         char* ptr=NULL;
1365                                         struct job *newjob;
1366                                         struct jobset njob_list = { NULL, NULL };
1367                                         int pipefd[2];
1368                                         int size;
1369
1370                                         ptr=strchr(++src, '`');
1371                                         if (ptr==NULL) {
1372                                                 fprintf(stderr, "Unmatched '`' in command\n");
1373                                                 free_job(job);
1374                                                 return 1;
1375                                         }
1376
1377                                         /* Make some space to hold just the backticked command */
1378                                         charptr1 = charptr2 = xmalloc(1+ptr-src);
1379                                         memcpy(charptr1, src, ptr-src);
1380                                         charptr1[ptr-src] = '\0';
1381                                         newjob = xmalloc(sizeof(struct job));
1382                                         newjob->job_list = &njob_list;
1383                                         /* Now parse and run the backticked command */
1384                                         if (!parse_command(&charptr1, newjob, inbg) 
1385                                                         && newjob->num_progs) {
1386                                                 pipe(pipefd);
1387                                                 run_command(newjob, 0, pipefd);
1388                                         }
1389                                         checkjobs(job->job_list);
1390                                         free_job(newjob);  /* doesn't actually free newjob,
1391                                                              looks like a memory leak */
1392                                         free(charptr2);
1393                                         
1394                                         /* Make a copy of any stuff left over in the command 
1395                                          * line after the second backtick */
1396                                         charptr2 = xmalloc(strlen(ptr)+1);
1397                                         memcpy(charptr2, ptr+1, strlen(ptr));
1398
1399
1400                                         /* Copy the output from the backtick-ed command into the
1401                                          * command line, making extra room as needed  */
1402                                         --src;
1403                                         charptr1 = xmalloc(BUFSIZ);
1404                                         while ( (size=full_read(pipefd[0], charptr1, BUFSIZ-1)) >0) {
1405                                                 int newsize=src - *command_ptr + size + 1 + strlen(charptr2);
1406                                                 if (newsize > BUFSIZ) {
1407                                                         *command_ptr=xrealloc(*command_ptr, newsize);
1408                                                 }
1409                                                 memcpy(src, charptr1, size); 
1410                                                 src+=size;
1411                                         }
1412                                         free(charptr1);
1413                                         close(pipefd[0]);
1414                                         if (*(src-1)=='\n')
1415                                                 --src;
1416
1417                                         /* Now paste into the *command_ptr all the stuff 
1418                                          * leftover after the second backtick */
1419                                         memcpy(src, charptr2, strlen(charptr2)+1);
1420                                         free(charptr2);
1421
1422                                         /* Now recursively call parse_command to deal with the new
1423                                          * and improved version of the command line with the backtick
1424                                          * results expanded in place... */
1425                                         {
1426                                                 struct jobset *jl=job->job_list;
1427                                                 free_job(job);
1428                                                 job->job_list = jl;
1429                                         }
1430                                         return(parse_command(command_ptr, job, inbg));
1431                                 }
1432                                 break;
1433 #endif // BB_FEATURE_SH_BACKTICKS
1434
1435                         case '\\':
1436                                 src++;
1437                                 if (!*src) {
1438 /* This is currently a little broken... */
1439 #ifdef HANDLE_CONTINUATION_CHARS
1440                                         /* They fed us a continuation char, so continue reading stuff
1441                                          * on the next line, then tack that onto the end of the current
1442                                          * command */
1443                                         char *command;
1444                                         int newsize;
1445                                         printf("erik: found a continue char at EOL...\n");
1446                                         command = (char *) xcalloc(BUFSIZ, sizeof(char));
1447                                         if (get_command(input, command)) {
1448                                                 error_msg("character expected after \\");
1449                                                 free(command);
1450                                                 free_job(job);
1451                                                 return 1;
1452                                         }
1453                                         newsize = strlen(*command_ptr) + strlen(command) + 2;
1454                                         if (newsize > BUFSIZ) {
1455                                                 printf("erik: doing realloc\n");
1456                                                 *command_ptr=xrealloc(*command_ptr, newsize);
1457                                         }
1458                                         printf("erik: A: *command_ptr='%s'\n", *command_ptr);
1459                                         memcpy(--src, command, strlen(command)); 
1460                                         printf("erik: B: *command_ptr='%s'\n", *command_ptr);
1461                                         free(command);
1462                                         break;
1463 #else
1464                                         error_msg("character expected after \\");
1465                                         free_job(job);
1466                                         return 1;
1467 #endif
1468                                 }
1469                                 if (*src == '*' || *src == '[' || *src == ']'
1470                                         || *src == '?') *buf++ = '\\';
1471                                 /* fallthrough */
1472                         default:
1473                                 *buf++ = *src;
1474                         }
1475
1476                 src++;
1477         }
1478
1479         if (*prog->argv[argc_l] || saw_quote) {
1480                 argc_l++;
1481         }
1482         if (!argc_l) {
1483                 free_job(job);
1484                 return 0;
1485         }
1486         prog->argv[argc_l] = NULL;
1487
1488         if (!return_command) {
1489                 job->text = xmalloc(strlen(*command_ptr) + 1);
1490                 strcpy(job->text, *command_ptr);
1491         } else {
1492                 /* This leaves any trailing spaces, which is a bit sloppy */
1493                 count = return_command - *command_ptr;
1494                 job->text = xmalloc(count + 1);
1495                 strncpy(job->text, *command_ptr, count);
1496                 job->text[count] = '\0';
1497         }
1498
1499         *command_ptr = return_command;
1500         
1501         return 0;
1502 }
1503
1504 /* Run the child_prog, no matter what kind of command it uses.
1505  */
1506 static int pseudo_exec(struct child_prog *child)
1507 {
1508         struct built_in_command *x;
1509 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
1510         char *name;
1511 #endif
1512
1513         /* Check if the command matches any of the non-forking builtins.
1514          * Depending on context, this might be redundant.  But it's
1515          * easier to waste a few CPU cycles than it is to figure out
1516          * if this is one of those cases.
1517          */
1518         for (x = bltins; x->cmd; x++) {
1519                 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1520                         exit(x->function(child));
1521                 }
1522         }
1523
1524         /* Check if the command matches any of the forking builtins. */
1525         for (x = bltins_forking; x->cmd; x++) {
1526                 if (strcmp(child->argv[0], x->cmd) == 0) {
1527                         applet_name=x->cmd;
1528                         exit (x->function(child));
1529                 }
1530         }
1531 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
1532         /* Check if the command matches any busybox internal
1533          * commands ("applets") here.  Following discussions from
1534          * November 2000 on busybox@opensource.lineo.com, don't use
1535          * get_last_path_component().  This way explicit (with
1536          * slashes) filenames will never be interpreted as an
1537          * applet, just like with builtins.  This way the user can
1538          * override an applet with an explicit filename reference.
1539          * The only downside to this change is that an explicit
1540          * /bin/foo invocation will fork and exec /bin/foo, even if
1541          * /bin/foo is a symlink to busybox.
1542          */
1543         name = child->argv[0];
1544
1545 #ifdef BB_FEATURE_SH_APPLETS_ALWAYS_WIN
1546         /* If you enable BB_FEATURE_SH_APPLETS_ALWAYS_WIN, then
1547          * if you run /bin/cat, it will use BusyBox cat even if 
1548          * /bin/cat exists on the filesystem and is _not_ busybox.
1549          * Some systems want this, others do not.  Choose wisely.  :-)
1550          */
1551         name = get_last_path_component(name);
1552 #endif
1553
1554         {
1555             char** argv_l=child->argv;
1556             int argc_l;
1557             for(argc_l=0;*argv_l!=NULL; argv_l++, argc_l++);
1558             optind = 1;
1559             run_applet_by_name(name, argc_l, child->argv);
1560         }
1561 #endif
1562
1563         execvp(child->argv[0], child->argv);
1564         perror_msg_and_die("%s", child->argv[0]);
1565 }
1566
1567 static void insert_job(struct job *newjob, int inbg)
1568 {
1569         struct job *thejob;
1570         struct jobset *j_list=newjob->job_list;
1571
1572         /* find the ID for thejob to use */
1573         newjob->jobid = 1;
1574         for (thejob = j_list->head; thejob; thejob = thejob->next)
1575                 if (thejob->jobid >= newjob->jobid)
1576                         newjob->jobid = thejob->jobid + 1;
1577
1578         /* add thejob to the list of running jobs */
1579         if (!j_list->head) {
1580                 thejob = j_list->head = xmalloc(sizeof(*thejob));
1581         } else {
1582                 for (thejob = j_list->head; thejob->next; thejob = thejob->next) /* nothing */;
1583                 thejob->next = xmalloc(sizeof(*thejob));
1584                 thejob = thejob->next;
1585         }
1586
1587         *thejob = *newjob;   /* physically copy the struct job */
1588         thejob->next = NULL;
1589         thejob->running_progs = thejob->num_progs;
1590         thejob->stopped_progs = 0;
1591
1592         if (inbg) {
1593                 /* we don't wait for background thejobs to return -- append it 
1594                    to the list of backgrounded thejobs and leave it alone */
1595                 printf("[%d] %d\n", thejob->jobid,
1596                            newjob->progs[newjob->num_progs - 1].pid);
1597 #ifdef BB_FEATURE_SH_ENVIRONMENT
1598                 last_bg_pid=newjob->progs[newjob->num_progs - 1].pid;
1599 #endif
1600         } else {
1601                 newjob->job_list->fg = thejob;
1602
1603                 /* move the new process group into the foreground */
1604                 /* suppress messages when run from /linuxrc mag@sysgo.de */
1605                 if (tcsetpgrp(0, newjob->pgrp) && errno != ENOTTY)
1606                         perror_msg("tcsetpgrp");
1607         }
1608 }
1609
1610 static int run_command(struct job *newjob, int inbg, int outpipe[2])
1611 {
1612         /* struct job *thejob; */
1613         int i;
1614         int nextin, nextout;
1615         int pipefds[2];                         /* pipefd[0] is for reading */
1616         struct built_in_command *x;
1617         struct child_prog *child;
1618
1619         nextin = 0, nextout = 1;
1620         for (i = 0; i < newjob->num_progs; i++) {
1621                 child = & (newjob->progs[i]);
1622
1623                 if ((i + 1) < newjob->num_progs) {
1624                         if (pipe(pipefds)<0) perror_msg_and_die("pipe");
1625                         nextout = pipefds[1];
1626                 } else {
1627                         if (outpipe[1]!=-1) {
1628                                 nextout = outpipe[1];
1629                         } else {
1630                                 nextout = 1;
1631                         }
1632                 }
1633
1634 #ifdef BB_FEATURE_SH_ENVIRONMENT
1635                 if (show_x_trace==TRUE) {
1636                         int j;
1637                         fputc('+', stderr);
1638                         for (j = 0; child->argv[j]; j++) {
1639                                 fputc(' ', stderr);
1640                                 fputs(child->argv[j], stderr);
1641                         }
1642                         fputc('\n', stderr);
1643                 }
1644 #endif
1645
1646                 /* Check if the command matches any non-forking builtins,
1647                  * but only if this is a simple command.
1648                  * Non-forking builtins within pipes have to fork anyway,
1649                  * and are handled in pseudo_exec.  "echo foo | read bar"
1650                  * is doomed to failure, and doesn't work on bash, either.
1651                  */
1652                 if (newjob->num_progs == 1) {
1653                         for (x = bltins; x->cmd; x++) {
1654                                 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1655                                         int squirrel[] = {-1, -1, -1};
1656                                         int rcode;
1657                                         setup_redirects(child, squirrel);
1658                                         rcode = x->function(child);
1659                                         restore_redirects(squirrel);
1660                                         return rcode;
1661                                 }
1662                         }
1663                 }
1664
1665                 if (!(child->pid = fork())) {
1666                         signal(SIGTTOU, SIG_DFL);
1667
1668                         close_all();
1669
1670                         if (outpipe[1]!=-1) {
1671                                 close(outpipe[0]);
1672                         }
1673                         if (nextin != 0) {
1674                                 dup2(nextin, 0);
1675                                 close(nextin);
1676                         }
1677
1678                         if (nextout != 1) {
1679                                 dup2(nextout, 1);
1680                                 dup2(nextout, 2);  /* Really? */
1681                                 close(nextout);
1682                                 close(pipefds[0]);
1683                         }
1684
1685                         /* explicit redirects override pipes */
1686                         setup_redirects(child,NULL);
1687
1688                         pseudo_exec(child);
1689                 }
1690                 if (outpipe[1]!=-1) {
1691                         close(outpipe[1]);
1692                 }
1693
1694                 /* put our child in the process group whose leader is the
1695                    first process in this pipe */
1696                 setpgid(child->pid, newjob->progs[0].pid);
1697                 if (nextin != 0)
1698                         close(nextin);
1699                 if (nextout != 1)
1700                         close(nextout);
1701
1702                 /* If there isn't another process, nextin is garbage 
1703                    but it doesn't matter */
1704                 nextin = pipefds[0];
1705         }
1706
1707         newjob->pgrp = newjob->progs[0].pid;
1708
1709         insert_job(newjob, inbg);
1710
1711         return 0;
1712 }
1713
1714 static int busy_loop(FILE * input)
1715 {
1716         char *command;
1717         char *next_command = NULL;
1718         struct job newjob;
1719         pid_t  parent_pgrp;
1720         int i;
1721         int inbg;
1722         int status;
1723         newjob.job_list = &job_list;
1724         newjob.job_context = DEFAULT_CONTEXT;
1725
1726         /* save current owner of TTY so we can restore it on exit */
1727         parent_pgrp = tcgetpgrp(0);
1728
1729         command = (char *) xcalloc(BUFSIZ, sizeof(char));
1730
1731         /* don't pay any attention to this signal; it just confuses 
1732            things and isn't really meant for shells anyway */
1733         signal(SIGTTOU, SIG_IGN);
1734
1735         while (1) {
1736                 if (!job_list.fg) {
1737                         /* no job is in the foreground */
1738
1739                         /* see if any background processes have exited */
1740                         checkjobs(&job_list);
1741
1742                         if (!next_command) {
1743                                 if (get_command(input, command))
1744                                         break;
1745                                 next_command = command;
1746                         }
1747
1748                         if (expand_arguments(next_command) == FALSE) {
1749                                 free(command);
1750                                 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1751                                 next_command = NULL;
1752                                 continue;
1753                         }
1754
1755                         if (!parse_command(&next_command, &newjob, &inbg) &&
1756                                 newjob.num_progs) {
1757                                 int pipefds[2] = {-1,-1};
1758                                 debug_printf( "job=%p fed to run_command by busy_loop()'\n", 
1759                                                 &newjob);
1760                                 run_command(&newjob, inbg, pipefds);
1761                         }
1762                         else {
1763                                 free(command);
1764                                 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1765                                 next_command = NULL;
1766                         }
1767                 } else {
1768                         /* a job is running in the foreground; wait for it */
1769                         i = 0;
1770                         while (!job_list.fg->progs[i].pid ||
1771                                    job_list.fg->progs[i].is_stopped == 1) i++;
1772
1773                         if (waitpid(job_list.fg->progs[i].pid, &status, WUNTRACED)<0)
1774                                 perror_msg_and_die("waitpid(%d)",job_list.fg->progs[i].pid);
1775
1776                         if (WIFEXITED(status) || WIFSIGNALED(status)) {
1777                                 /* the child exited */
1778                                 job_list.fg->running_progs--;
1779                                 job_list.fg->progs[i].pid = 0;
1780
1781 #ifdef BB_FEATURE_SH_ENVIRONMENT
1782                                 last_return_code=WEXITSTATUS(status);
1783                                 debug_printf("'%s' exited -- return code %d\n",
1784                                                 job_list.fg->text, last_return_code);
1785 #endif
1786                                 if (!job_list.fg->running_progs) {
1787                                         /* child exited */
1788                                         remove_job(&job_list, job_list.fg);
1789                                         job_list.fg = NULL;
1790                                 }
1791                         } else {
1792                                 /* the child was stopped */
1793                                 job_list.fg->stopped_progs++;
1794                                 job_list.fg->progs[i].is_stopped = 1;
1795
1796                                 if (job_list.fg->stopped_progs == job_list.fg->running_progs) {
1797                                         printf("\n" JOB_STATUS_FORMAT, job_list.fg->jobid,
1798                                                    "Stopped", job_list.fg->text);
1799                                         job_list.fg = NULL;
1800                                 }
1801                         }
1802
1803                         if (!job_list.fg) {
1804                                 /* move the shell to the foreground */
1805                                 /* suppress messages when run from /linuxrc mag@sysgo.de */
1806                                 if (tcsetpgrp(0, getpgrp()) && errno != ENOTTY)
1807                                         perror_msg("tcsetpgrp"); 
1808                         }
1809                 }
1810         }
1811         free(command);
1812
1813         /* return controlling TTY back to parent process group before exiting */
1814         if (tcsetpgrp(0, parent_pgrp))
1815                 perror_msg("tcsetpgrp");
1816
1817         /* return exit status if called with "-c" */
1818         if (input == NULL && WIFEXITED(status))
1819                 return WEXITSTATUS(status);
1820         
1821         return 0;
1822 }
1823
1824
1825 #ifdef BB_FEATURE_CLEAN_UP
1826 void free_memory(void)
1827 {
1828         if (cwd) {
1829                 free(cwd);
1830                 cwd = NULL;
1831         }
1832         if (local_pending_command)
1833                 free(local_pending_command);
1834
1835         if (job_list.fg && !job_list.fg->running_progs) {
1836                 remove_job(&job_list, job_list.fg);
1837         }
1838 }
1839 #endif
1840
1841
1842 int shell_main(int argc_l, char **argv_l)
1843 {
1844         int opt, interactive=FALSE;
1845         FILE *input = stdin;
1846         argc = argc_l;
1847         argv = argv_l;
1848
1849         /* These variables need re-initializing when recursing */
1850         shell_context = 0;
1851         local_pending_command = NULL;
1852         close_me_head = NULL;
1853         job_list.head = NULL;
1854         job_list.fg = NULL;
1855 #ifdef BB_FEATURE_SH_ENVIRONMENT
1856         last_bg_pid=1;
1857         last_return_code=1;
1858         show_x_trace=FALSE;
1859 #endif
1860
1861         if (argv[0] && argv[0][0] == '-') {
1862                 FILE *prof_input;
1863                 prof_input = fopen("/etc/profile", "r");
1864                 if (!prof_input) {
1865                         printf( "Couldn't open file '/etc/profile'\n");
1866                 } else {
1867                         int tmp_fd = fileno(prof_input);
1868                         mark_open(tmp_fd);      
1869                         /* Now run the file */
1870                         busy_loop(prof_input);
1871                         fclose(prof_input);
1872                         mark_closed(tmp_fd);
1873                 }
1874         }
1875
1876         while ((opt = getopt(argc_l, argv_l, "cxi")) > 0) {
1877                 switch (opt) {
1878                         case 'c':
1879                                 input = NULL;
1880                                 if (local_pending_command != 0)
1881                                         error_msg_and_die("multiple -c arguments");
1882                                 local_pending_command = xstrdup(argv[optind]);
1883                                 optind++;
1884                                 argv = argv+optind;
1885                                 break;
1886 #ifdef BB_FEATURE_SH_ENVIRONMENT
1887                         case 'x':
1888                                 show_x_trace = TRUE;
1889                                 break;
1890 #endif
1891                         case 'i':
1892                                 interactive = TRUE;
1893                                 break;
1894                         default:
1895                                 show_usage();
1896                 }
1897         }
1898         /* A shell is interactive if the `-i' flag was given, or if all of
1899          * the following conditions are met:
1900          *        no -c command
1901          *    no arguments remaining or the -s flag given
1902          *    standard input is a terminal
1903          *    standard output is a terminal
1904          *    Refer to Posix.2, the description of the `sh' utility. */
1905         if (argv[optind]==NULL && input==stdin &&
1906                         isatty(fileno(stdin)) && isatty(fileno(stdout))) {
1907                 interactive=TRUE;
1908         }
1909         if (interactive==TRUE) {
1910                 //printf( "optind=%d  argv[optind]='%s'\n", optind, argv[optind]);
1911                 /* Looks like they want an interactive shell */
1912                 printf( "\n\n" BB_BANNER " Built-in shell (lash)\n");
1913                 printf( "Enter 'help' for a list of built-in commands.\n\n");
1914         } else if (local_pending_command==NULL) {
1915                 //printf( "optind=%d  argv[optind]='%s'\n", optind, argv[optind]);
1916                 input = xfopen(argv[optind], "r");
1917                 mark_open(fileno(input));  /* be lazy, never mark this closed */
1918         }
1919
1920         /* initialize the cwd -- this is never freed...*/
1921         cwd = xgetcwd(0);
1922
1923 #ifdef BB_FEATURE_CLEAN_UP
1924         atexit(free_memory);
1925 #endif
1926
1927 #ifdef BB_FEATURE_COMMAND_EDITING
1928         cmdedit_set_initial_prompt();
1929 #else
1930         PS1 = NULL;
1931 #endif
1932         
1933         return (busy_loop(input));
1934 }
1935