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