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