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