68f67353967a265491bd2ca7ddba845c7fb0057e
[oweals/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 /* This shell's parsing engine is officially at a dead-end.
29  * Future work shell work should be done using hush.c
30  */
31
32 //For debugging/development on the shell only...
33 //#define DEBUG_SHELL
34
35
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <ctype.h>
39 #include <errno.h>
40 #include <fcntl.h>
41 #include <signal.h>
42 #include <string.h>
43 #include <sys/ioctl.h>
44 #include <sys/wait.h>
45 #include <unistd.h>
46 #include <getopt.h>
47 #include <termios.h>
48 #include "busybox.h"
49 #include "cmdedit.h"
50
51 #ifdef BB_LOCALE_SUPPORT
52 #include <locale.h>
53 #endif
54
55 #include <glob.h>
56 #define expand_t        glob_t
57
58
59 static const int MAX_READ = 128;        /* size of input buffer for `read' builtin */
60 #define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
61
62
63 enum redir_type { REDIRECT_INPUT, REDIRECT_OVERWRITE,
64         REDIRECT_APPEND
65 };
66
67 static const unsigned int DEFAULT_CONTEXT=0x1;
68 static const unsigned int IF_TRUE_CONTEXT=0x2;
69 static const unsigned int IF_FALSE_CONTEXT=0x4;
70 static const unsigned int THEN_EXP_CONTEXT=0x8;
71 static const unsigned int ELSE_EXP_CONTEXT=0x10;
72
73
74 struct jobset {
75         struct job *head;                       /* head of list of running jobs */
76         struct job *fg;                         /* current foreground job */
77 };
78
79 struct redir_struct {
80         enum redir_type type;   /* type of redirection */
81         int fd;                                         /* file descriptor being redirected */
82         char *filename;                         /* file to redirect fd to */
83 };
84
85 struct child_prog {
86         pid_t pid;                                      /* 0 if exited */
87         char **argv;                            /* program name and arguments */
88         int num_redirects;                      /* elements in redirection array */
89         struct redir_struct *redirects; /* I/O redirects */
90         int is_stopped;                         /* is the program currently running? */
91         struct job *family;                     /* pointer back to the child's parent job */
92 };
93
94 struct job {
95         int jobid;                                      /* job number */
96         int num_progs;                          /* total number of programs in job */
97         int running_progs;                      /* number of programs running */
98         char *text;                                     /* name of job */
99         char *cmdbuf;                           /* buffer various argv's point into */
100         pid_t pgrp;                                     /* process group ID for the job */
101         struct child_prog *progs;       /* array of programs in job */
102         struct job *next;                       /* to track background commands */
103         int stopped_progs;                      /* number of programs alive, but stopped */
104         unsigned int job_context;       /* bitmask defining current context */
105         struct jobset *job_list;
106 };
107
108 struct built_in_command {
109         char *cmd;                                      /* name */
110         char *descr;                            /* description */
111         int (*function) (struct child_prog *);  /* function ptr */
112 };
113
114 struct close_me {
115         int fd;
116         struct close_me *next;
117 };
118
119 /* function prototypes for builtins */
120 static int builtin_cd(struct child_prog *cmd);
121 static int builtin_exec(struct child_prog *cmd);
122 static int builtin_exit(struct child_prog *cmd);
123 static int builtin_fg_bg(struct child_prog *cmd);
124 static int builtin_help(struct child_prog *cmd);
125 static int builtin_jobs(struct child_prog *dummy);
126 static int builtin_pwd(struct child_prog *dummy);
127 static int builtin_export(struct child_prog *cmd);
128 static int builtin_source(struct child_prog *cmd);
129 static int builtin_unset(struct child_prog *cmd);
130 static int builtin_read(struct child_prog *cmd);
131
132
133 /* function prototypes for shell stuff */
134 static void mark_open(int fd);
135 static void mark_closed(int fd);
136 static void close_all(void);
137 static void checkjobs(struct jobset *job_list);
138 static int get_command(FILE * source, char *command);
139 static int parse_command(char **command_ptr, struct job *job, int *inbg);
140 static int run_command(struct job *newjob, int inbg, int outpipe[2]);
141 static int pseudo_exec(struct child_prog *cmd) __attribute__ ((noreturn));
142 static int busy_loop(FILE * input);
143
144
145 /* Table of built-in functions (these are non-forking builtins, meaning they
146  * can change global variables in the parent shell process but they will not
147  * work with pipes and redirects; 'unset foo | whatever' will not work) */
148 static struct built_in_command bltins[] = {
149         {"bg", "Resume a job in the background", builtin_fg_bg},
150         {"cd", "Change working directory", builtin_cd},
151         {"exec", "Exec command, replacing this shell with the exec'd process", builtin_exec},
152         {"exit", "Exit from shell()", builtin_exit},
153         {"fg", "Bring job into the foreground", builtin_fg_bg},
154         {"jobs", "Lists the active jobs", builtin_jobs},
155         {"export", "Set environment variable", builtin_export},
156         {"unset", "Unset environment variable", builtin_unset},
157         {"read", "Input environment variable", builtin_read},
158         {".", "Source-in and run commands in a file", builtin_source},
159         /* to do: add ulimit */
160         {NULL, NULL, NULL}
161 };
162
163 /* Table of forking built-in functions (things that fork cannot change global
164  * variables in the parent process, such as the current working directory) */
165 static struct built_in_command bltins_forking[] = {
166         {"pwd", "Print current directory", builtin_pwd},
167         {"help", "List shell built-in commands", builtin_help},
168         {NULL, NULL, NULL}
169 };
170
171
172 /* Variables we export */
173 unsigned int shell_context;  /* Used in cmdedit.c to reset the
174                                                                 context when someone hits ^C */
175
176
177 /* Globals that are static to this file */
178 static const char *cwd;
179 static char *local_pending_command = NULL;
180 static struct jobset job_list = { NULL, NULL };
181 static int argc;
182 static char **argv;
183 static struct close_me *close_me_head;
184 static unsigned int last_jobid;
185 static int shell_terminal;
186 static pid_t shell_pgrp;
187 static char *PS1;
188 static char *PS2 = "> ";
189
190
191 #ifdef DEBUG_SHELL
192 static inline void debug_printf(const char *format, ...)
193 {
194         va_list args;
195         va_start(args, format);
196         vfprintf(stderr, format, args);
197         va_end(args);
198 }
199 #else
200 static inline void debug_printf(const char *format, ...) { }
201 #endif
202
203 /*
204         Most builtins need access to the struct child_prog that has
205         their arguments, previously coded as cmd->progs[0].  That coding
206         can exhibit a bug, if the builtin is not the first command in
207         a pipeline: "echo foo | exec sort" will attempt to exec foo.
208
209 builtin   previous use      notes
210 ------ -----------------  ---------
211 cd      cmd->progs[0]
212 exec    cmd->progs[0]  squashed bug: didn't look for applets or forking builtins
213 exit    cmd->progs[0]
214 fg_bg   cmd->progs[0], job_list->head, job_list->fg
215 help    0
216 jobs    job_list->head
217 pwd     0
218 export  cmd->progs[0]
219 source  cmd->progs[0]
220 unset   cmd->progs[0]
221 read    cmd->progs[0]
222
223 I added "struct job *family;" to struct child_prog,
224 and switched API to builtin_foo(struct child_prog *child);
225 So   cmd->text        becomes  child->family->text
226      cmd->job_context  becomes  child->family->job_context
227      cmd->progs[0]    becomes  *child
228      job_list          becomes  child->family->job_list
229  */
230
231 /* built-in 'cd <path>' handler */
232 static int builtin_cd(struct child_prog *child)
233 {
234         char *newdir;
235
236         if (child->argv[1] == NULL)
237                 newdir = getenv("HOME");
238         else
239                 newdir = child->argv[1];
240         if (chdir(newdir)) {
241                 printf("cd: %s: %m\n", newdir);
242                 return EXIT_FAILURE;
243         }
244         cwd = xgetcwd((char *)cwd);
245         if (!cwd)
246                 cwd = unknown;
247         return EXIT_SUCCESS;
248 }
249
250 /* built-in 'exec' handler */
251 static int builtin_exec(struct child_prog *child)
252 {
253         if (child->argv[1] == NULL)
254                 return EXIT_SUCCESS;   /* Really? */
255         child->argv++;
256         close_all();
257         pseudo_exec(child);
258         /* never returns */
259 }
260
261 /* built-in 'exit' handler */
262 static int builtin_exit(struct child_prog *child)
263 {
264         if (child->argv[1] == NULL)
265                 exit(EXIT_SUCCESS);
266
267         exit (atoi(child->argv[1]));
268 }
269
270 /* built-in 'fg' and 'bg' handler */
271 static int builtin_fg_bg(struct child_prog *child)
272 {
273         int i, jobnum;
274         struct job *job=NULL;
275
276         /* If they gave us no args, assume they want the last backgrounded task */
277         if (!child->argv[1]) {
278                 for (job = child->family->job_list->head; job; job = job->next) {
279                         if (job->jobid == last_jobid) {
280                                 break;
281                         }
282                 }
283                 if (!job) {
284                         error_msg("%s: no current job", child->argv[0]);
285                         return EXIT_FAILURE;
286                 }
287         } else {
288                 if (sscanf(child->argv[1], "%%%d", &jobnum) != 1) {
289                         error_msg("%s: bad argument '%s'", child->argv[0], child->argv[1]);
290                         return EXIT_FAILURE;
291                 }
292                 for (job = child->family->job_list->head; job; job = job->next) {
293                         if (job->jobid == jobnum) {
294                                 break;
295                         }
296                 }
297                 if (!job) {
298                         error_msg("%s: %d: no such job", child->argv[0], jobnum);
299                         return EXIT_FAILURE;
300                 }
301         }
302
303         if (*child->argv[0] == 'f') {
304                 /* Put the job into the foreground.  */
305                 tcsetpgrp(shell_terminal, job->pgrp);
306
307                 child->family->job_list->fg = job;
308         }
309
310         /* Restart the processes in the job */
311         for (i = 0; i < job->num_progs; i++)
312                 job->progs[i].is_stopped = 0;
313
314         job->stopped_progs = 0;
315
316         if (kill(- job->pgrp, SIGCONT) < 0)
317                 perror_msg("kill (SIGCONT)");
318
319         return EXIT_SUCCESS;
320 }
321
322 /* built-in 'help' handler */
323 static int builtin_help(struct child_prog *dummy)
324 {
325         struct built_in_command *x;
326
327         printf("\nBuilt-in commands:\n");
328         printf("-------------------\n");
329         for (x = bltins; x->cmd; x++) {
330                 if (x->descr==NULL)
331                         continue;
332                 printf("%s\t%s\n", x->cmd, x->descr);
333         }
334         for (x = bltins_forking; x->cmd; x++) {
335                 if (x->descr==NULL)
336                         continue;
337                 printf("%s\t%s\n", x->cmd, x->descr);
338         }
339         printf("\n\n");
340         return EXIT_SUCCESS;
341 }
342
343 /* built-in 'jobs' handler */
344 static int builtin_jobs(struct child_prog *child)
345 {
346         struct job *job;
347         char *status_string;
348
349         for (job = child->family->job_list->head; job; job = job->next) {
350                 if (job->running_progs == job->stopped_progs)
351                         status_string = "Stopped";
352                 else
353                         status_string = "Running";
354
355                 printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->text);
356         }
357         return EXIT_SUCCESS;
358 }
359
360
361 /* built-in 'pwd' handler */
362 static int builtin_pwd(struct child_prog *dummy)
363 {
364         cwd = xgetcwd((char *)cwd);
365         if (!cwd)
366                 cwd = unknown;
367         puts(cwd);
368         return EXIT_SUCCESS;
369 }
370
371 /* built-in 'export VAR=value' handler */
372 static int builtin_export(struct child_prog *child)
373 {
374         int res;
375         char *v = child->argv[1];
376
377         if (v == NULL) {
378                 char **e;
379                 for (e = environ; *e; e++) {
380                         puts(*e);
381                 }
382                 return 0;
383         }
384         res = putenv(v);
385         if (res)
386                 fprintf(stderr, "export: %m\n");
387 #ifdef BB_FEATURE_SH_FANCY_PROMPT
388         if (strncmp(v, "PS1=", 4)==0)
389                 PS1 = getenv("PS1");
390 #endif
391
392 #ifdef BB_LOCALE_SUPPORT
393         if(strncmp(v, "LC_ALL=", 7)==0)
394                 setlocale(LC_ALL, getenv("LC_ALL"));
395         if(strncmp(v, "LC_CTYPE=", 9)==0)
396                 setlocale(LC_CTYPE, getenv("LC_CTYPE"));
397 #endif
398
399         return (res);
400 }
401
402 /* built-in 'read VAR' handler */
403 static int builtin_read(struct child_prog *child)
404 {
405         int res = 0, len, newlen;
406         char *s;
407         char string[MAX_READ];
408
409         if (child->argv[1]) {
410                 /* argument (VAR) given: put "VAR=" into buffer */
411                 strcpy(string, child->argv[1]);
412                 len = strlen(string);
413                 string[len++] = '=';
414                 string[len]   = '\0';
415                 fgets(&string[len], sizeof(string) - len, stdin);       /* read string */
416                 newlen = strlen(string);
417                 if(newlen > len)
418                         string[--newlen] = '\0';        /* chomp trailing newline */
419                 /*
420                 ** string should now contain "VAR=<value>"
421                 ** copy it (putenv() won't do that, so we must make sure
422                 ** the string resides in a static buffer!)
423                 */
424                 res = -1;
425                 if((s = strdup(string)))
426                         res = putenv(s);
427                 if (res)
428                         fprintf(stderr, "read: %m\n");
429         }
430         else
431                 fgets(string, sizeof(string), stdin);
432
433         return (res);
434 }
435
436 /* Built-in '.' handler (read-in and execute commands from file) */
437 static int builtin_source(struct child_prog *child)
438 {
439         FILE *input;
440         int status;
441         int fd;
442
443         if (child->argv[1] == NULL)
444                 return EXIT_FAILURE;
445
446         input = fopen(child->argv[1], "r");
447         if (!input) {
448                 printf( "Couldn't open file '%s'\n", child->argv[1]);
449                 return EXIT_FAILURE;
450         }
451
452         fd=fileno(input);
453         mark_open(fd);
454         /* Now run the file */
455         status = busy_loop(input);
456         fclose(input);
457         mark_closed(fd);
458         return (status);
459 }
460
461 /* built-in 'unset VAR' handler */
462 static int builtin_unset(struct child_prog *child)
463 {
464         if (child->argv[1] == NULL) {
465                 printf( "unset: parameter required.\n");
466                 return EXIT_FAILURE;
467         }
468         unsetenv(child->argv[1]);
469         return EXIT_SUCCESS;
470 }
471
472 static void mark_open(int fd)
473 {
474         struct close_me *new = xmalloc(sizeof(struct close_me));
475         new->fd = fd;
476         new->next = close_me_head;
477         close_me_head = new;
478 }
479
480 static void mark_closed(int fd)
481 {
482         struct close_me *tmp;
483         if (close_me_head == NULL || close_me_head->fd != fd)
484                 error_msg_and_die("corrupt close_me");
485         tmp = close_me_head;
486         close_me_head = close_me_head->next;
487         free(tmp);
488 }
489
490 static void close_all()
491 {
492         struct close_me *c, *tmp;
493         for (c=close_me_head; c; c=tmp) {
494                 close(c->fd);
495                 tmp=c->next;
496                 free(c);
497         }
498         close_me_head = NULL;
499 }
500
501
502 /* free up all memory from a job */
503 static void free_job(struct job *cmd)
504 {
505         int i;
506         struct jobset *keep;
507
508         for (i = 0; i < cmd->num_progs; i++) {
509                 free(cmd->progs[i].argv);
510                 if (cmd->progs[i].redirects)
511                         free(cmd->progs[i].redirects);
512         }
513         if (cmd->progs)
514                 free(cmd->progs);
515         if (cmd->text)
516                 free(cmd->text);
517         if (cmd->cmdbuf)
518                 free(cmd->cmdbuf);
519         keep = cmd->job_list;
520         memset(cmd, 0, sizeof(struct job));
521         cmd->job_list = keep;
522 }
523
524 /* remove a job from a jobset */
525 static void remove_job(struct jobset *j_list, struct job *job)
526 {
527         struct job *prevjob;
528
529         free_job(job);
530         if (job == j_list->head) {
531                 j_list->head = job->next;
532         } else {
533                 prevjob = j_list->head;
534                 while (prevjob->next != job)
535                         prevjob = prevjob->next;
536                 prevjob->next = job->next;
537         }
538
539         free(job);
540 }
541
542 /* Checks to see if any background processes have exited -- if they 
543    have, figure out why and see if a job has completed */
544 static void checkjobs(struct jobset *j_list)
545 {
546         struct job *job;
547         pid_t childpid;
548         int status;
549         int prognum = 0;
550
551         while ((childpid = waitpid(-1, &status, WNOHANG | WUNTRACED)) > 0) {
552                 for (job = j_list->head; job; job = job->next) {
553                         prognum = 0;
554                         while (prognum < job->num_progs &&
555                                    job->progs[prognum].pid != childpid) prognum++;
556                         if (prognum < job->num_progs)
557                                 break;
558                 }
559
560                 /* This happens on backticked commands */
561                 if(job==NULL)
562                         return;
563
564                 if (WIFEXITED(status) || WIFSIGNALED(status)) {
565                         /* child exited */
566                         job->running_progs--;
567                         job->progs[prognum].pid = 0;
568
569                         if (!job->running_progs) {
570                                 printf(JOB_STATUS_FORMAT, job->jobid, "Done", job->text);
571                                 last_jobid=0;
572                                 remove_job(j_list, job);
573                         }
574                 } else {
575                         /* child stopped */
576                         job->stopped_progs++;
577                         job->progs[prognum].is_stopped = 1;
578
579                         if (job->stopped_progs == job->num_progs) {
580                                 printf(JOB_STATUS_FORMAT, job->jobid, "Stopped",
581                                            job->text);
582                         }
583                 }
584         }
585
586         if (childpid == -1 && errno != ECHILD)
587                 perror_msg("waitpid");
588 }
589
590 /* squirrel != NULL means we squirrel away copies of stdin, stdout,
591  * and stderr if they are redirected. */
592 static int setup_redirects(struct child_prog *prog, int squirrel[])
593 {
594         int i;
595         int openfd;
596         int mode = O_RDONLY;
597         struct redir_struct *redir = prog->redirects;
598
599         for (i = 0; i < prog->num_redirects; i++, redir++) {
600                 switch (redir->type) {
601                 case REDIRECT_INPUT:
602                         mode = O_RDONLY;
603                         break;
604                 case REDIRECT_OVERWRITE:
605                         mode = O_WRONLY | O_CREAT | O_TRUNC;
606                         break;
607                 case REDIRECT_APPEND:
608                         mode = O_WRONLY | O_CREAT | O_APPEND;
609                         break;
610                 }
611
612                 openfd = open(redir->filename, mode, 0666);
613                 if (openfd < 0) {
614                         /* this could get lost if stderr has been redirected, but
615                            bash and ash both lose it as well (though zsh doesn't!) */
616                         perror_msg("error opening %s", redir->filename);
617                         return 1;
618                 }
619
620                 if (openfd != redir->fd) {
621                         if (squirrel && redir->fd < 3) {
622                                 squirrel[redir->fd] = dup(redir->fd);
623                         }
624                         dup2(openfd, redir->fd);
625                         close(openfd);
626                 }
627         }
628
629         return 0;
630 }
631
632 static void restore_redirects(int squirrel[])
633 {
634         int i, fd;
635         for (i=0; i<3; i++) {
636                 fd = squirrel[i];
637                 if (fd != -1) {
638                         /* No error checking.  I sure wouldn't know what
639                          * to do with an error if I found one! */
640                         dup2(fd, i);
641                         close(fd);
642                 }
643         }
644 }
645
646 static inline void cmdedit_set_initial_prompt(void)
647 {
648 #ifndef BB_FEATURE_SH_FANCY_PROMPT
649         PS1 = NULL;
650 #else
651         PS1 = getenv("PS1");
652         if(PS1==0)
653                 PS1 = "\\w \\$ ";
654 #endif  
655 }
656
657 static inline void setup_prompt_string(char **prompt_str)
658 {
659 #ifndef BB_FEATURE_SH_FANCY_PROMPT
660         /* Set up the prompt */
661         if (shell_context == 0) {
662                 if (PS1)
663                         free(PS1);
664                 PS1=xmalloc(strlen(cwd)+4);
665                 sprintf(PS1, "%s %s", cwd, ( geteuid() != 0 ) ?  "$ ":"# ");
666                 *prompt_str = PS1;
667         } else {
668                 *prompt_str = PS2;
669         }
670 #else
671         *prompt_str = (shell_context==0)? PS1 : PS2;
672 #endif  
673 }
674
675 static int get_command(FILE * source, char *command)
676 {
677         char *prompt_str;
678
679         if (source == NULL) {
680                 if (local_pending_command) {
681                         /* a command specified (-c option): return it & mark it done */
682                         strcpy(command, local_pending_command);
683                         free(local_pending_command);
684                         local_pending_command = NULL;
685                         return 0;
686                 }
687                 return 1;
688         }
689
690         if (source == stdin) {
691                 setup_prompt_string(&prompt_str);
692
693 #ifdef BB_FEATURE_COMMAND_EDITING
694                 /*
695                 ** enable command line editing only while a command line
696                 ** is actually being read; otherwise, we'll end up bequeathing
697                 ** atexit() handlers and other unwanted stuff to our
698                 ** child processes (rob@sysgo.de)
699                 */
700                 cmdedit_read_input(prompt_str, command);
701                 cmdedit_terminate();
702                 return 0;
703 #else
704                 fputs(prompt_str, stdout);
705 #endif
706         }
707
708         if (!fgets(command, BUFSIZ - 2, source)) {
709                 if (source == stdin)
710                         printf("\n");
711                 return 1;
712         }
713
714         return 0;
715 }
716
717
718 static int expand_arguments(char *command)
719 {
720         int ix = 0;
721
722         /* get rid of the terminating \n */
723         chomp(command);
724         
725         /* Fix up escape sequences to be the Real Thing(tm) */
726         while( command && command[ix]) {
727                 if (command[ix] == '\\') {
728                         const char *tmp = command+ix+1;
729                         command[ix] = process_escape_sequence(  &tmp );
730                         memmove(command+ix + 1, tmp, strlen(tmp)+1);
731                 }
732                 ix++;
733         }
734
735         return TRUE;
736 }
737
738 /* Return cmd->num_progs as 0 if no command is present (e.g. an empty
739    line). If a valid command is found, command_ptr is set to point to
740    the beginning of the next command (if the original command had more 
741    then one job associated with it) or NULL if no more commands are 
742    present. */
743 static int parse_command(char **command_ptr, struct job *job, int *inbg)
744 {
745         char *command;
746         char *return_command = NULL;
747         char *src, *buf, *chptr;
748         int argc_l = 0;
749         int done = 0;
750         int argv_alloced;
751         int i, saw_quote = 0;
752         char quote = '\0';
753         int count;
754         struct child_prog *prog;
755
756         /* skip leading white space */
757         while (**command_ptr && isspace(**command_ptr))
758                 (*command_ptr)++;
759
760         /* this handles empty lines or leading '#' characters */
761         if (!**command_ptr || (**command_ptr == '#')) {
762                 job->num_progs=0;
763                 return 0;
764         }
765
766         *inbg = 0;
767         job->num_progs = 1;
768         job->progs = xmalloc(sizeof(*job->progs));
769
770         /* We set the argv elements to point inside of this string. The 
771            memory is freed by free_job(). Allocate twice the original
772            length in case we need to quote every single character.
773
774            Getting clean memory relieves us of the task of NULL 
775            terminating things and makes the rest of this look a bit 
776            cleaner (though it is, admittedly, a tad less efficient) */
777         job->cmdbuf = command = xcalloc(2*strlen(*command_ptr) + 1, sizeof(char));
778         job->text = NULL;
779
780         prog = job->progs;
781         prog->num_redirects = 0;
782         prog->redirects = NULL;
783         prog->is_stopped = 0;
784         prog->family = job;
785
786         argv_alloced = 5;
787         prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
788         prog->argv[0] = job->cmdbuf;
789
790         buf = command;
791         src = *command_ptr;
792         while (*src && !done) {
793                 if (quote == *src) {
794                         quote = '\0';
795                 } else if (quote) {
796                         if (*src == '\\') {
797                                 src++;
798                                 if (!*src) {
799                                         error_msg("character expected after \\");
800                                         free_job(job);
801                                         return 1;
802                                 }
803
804                                 /* in shell, "\'" should yield \' */
805                                 if (*src != quote) {
806                                         *buf++ = '\\';
807                                         *buf++ = '\\';
808                                 }
809                         } else if (*src == '*' || *src == '?' || *src == '[' ||
810                                            *src == ']') *buf++ = '\\';
811                         *buf++ = *src;
812                 } else if (isspace(*src)) {
813                         if (*prog->argv[argc_l] || saw_quote) {
814                                 buf++, argc_l++;
815                                 /* +1 here leaves room for the NULL which ends argv */
816                                 if ((argc_l + 1) == argv_alloced) {
817                                         argv_alloced += 5;
818                                         prog->argv = xrealloc(prog->argv,
819                                                                                   sizeof(*prog->argv) *
820                                                                                   argv_alloced);
821                                 }
822                                 prog->argv[argc_l] = buf;
823                                 saw_quote = 0;
824                         }
825                 } else
826                         switch (*src) {
827                         case '"':
828                         case '\'':
829                                 quote = *src;
830                                 saw_quote = 1;
831                                 break;
832
833                         case '#':                       /* comment */
834                                 if (*(src-1)== '$')
835                                         *buf++ = *src;
836                                 else
837                                         done = 1;
838                                 break;
839
840                         case '>':                       /* redirects */
841                         case '<':
842                                 i = prog->num_redirects++;
843                                 prog->redirects = xrealloc(prog->redirects,
844                                                                                           sizeof(*prog->redirects) *
845                                                                                           (i + 1));
846
847                                 prog->redirects[i].fd = -1;
848                                 if (buf != prog->argv[argc_l]) {
849                                         /* the stuff before this character may be the file number 
850                                            being redirected */
851                                         prog->redirects[i].fd =
852                                                 strtol(prog->argv[argc_l], &chptr, 10);
853
854                                         if (*chptr && *prog->argv[argc_l]) {
855                                                 buf++, argc_l++;
856                                                 prog->argv[argc_l] = buf;
857                                         }
858                                 }
859
860                                 if (prog->redirects[i].fd == -1) {
861                                         if (*src == '>')
862                                                 prog->redirects[i].fd = 1;
863                                         else
864                                                 prog->redirects[i].fd = 0;
865                                 }
866
867                                 if (*src++ == '>') {
868                                         if (*src == '>')
869                                                 prog->redirects[i].type =
870                                                         REDIRECT_APPEND, src++;
871                                         else
872                                                 prog->redirects[i].type = REDIRECT_OVERWRITE;
873                                 } else {
874                                         prog->redirects[i].type = REDIRECT_INPUT;
875                                 }
876
877                                 /* This isn't POSIX sh compliant. Oh well. */
878                                 chptr = src;
879                                 while (isspace(*chptr))
880                                         chptr++;
881
882                                 if (!*chptr) {
883                                         error_msg("file name expected after %c", *(src-1));
884                                         free_job(job);
885                                         job->num_progs=0;
886                                         return 1;
887                                 }
888
889                                 prog->redirects[i].filename = buf;
890                                 while (*chptr && !isspace(*chptr))
891                                         *buf++ = *chptr++;
892
893                                 src = chptr - 1;        /* we src++ later */
894                                 prog->argv[argc_l] = ++buf;
895                                 break;
896
897                         case '|':                       /* pipe */
898                                 /* finish this command */
899                                 if (*prog->argv[argc_l] || saw_quote)
900                                         argc_l++;
901                                 if (!argc_l) {
902                                         error_msg("empty command in pipe");
903                                         free_job(job);
904                                         job->num_progs=0;
905                                         return 1;
906                                 }
907                                 prog->argv[argc_l] = NULL;
908
909                                 /* and start the next */
910                                 job->num_progs++;
911                                 job->progs = xrealloc(job->progs,
912                                                                           sizeof(*job->progs) * job->num_progs);
913                                 prog = job->progs + (job->num_progs - 1);
914                                 prog->num_redirects = 0;
915                                 prog->redirects = NULL;
916                                 prog->is_stopped = 0;
917                                 prog->family = job;
918                                 argc_l = 0;
919
920                                 argv_alloced = 5;
921                                 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
922                                 prog->argv[0] = ++buf;
923
924                                 src++;
925                                 while (*src && isspace(*src))
926                                         src++;
927
928                                 if (!*src) {
929                                         error_msg("empty command in pipe");
930                                         free_job(job);
931                                         job->num_progs=0;
932                                         return 1;
933                                 }
934                                 src--;                  /* we'll ++ it at the end of the loop */
935
936                                 break;
937
938                         case '&':                       /* background */
939                                 *inbg = 1;
940                         case ';':                       /* multiple commands */
941                                 done = 1;
942                                 return_command = *command_ptr + (src - *command_ptr) + 1;
943                                 break;
944
945                         case '\\':
946                                 src++;
947                                 if (!*src) {
948                                         error_msg("character expected after \\");
949                                         free_job(job);
950                                         return 1;
951                                 }
952                                 if (*src == '*' || *src == '[' || *src == ']'
953                                         || *src == '?') *buf++ = '\\';
954                                 /* fallthrough */
955                         default:
956                                 *buf++ = *src;
957                         }
958
959                 src++;
960         }
961
962         if (*prog->argv[argc_l] || saw_quote) {
963                 argc_l++;
964         }
965         if (!argc_l) {
966                 free_job(job);
967                 return 0;
968         }
969         prog->argv[argc_l] = NULL;
970
971         if (!return_command) {
972                 job->text = xmalloc(strlen(*command_ptr) + 1);
973                 strcpy(job->text, *command_ptr);
974         } else {
975                 /* This leaves any trailing spaces, which is a bit sloppy */
976                 count = return_command - *command_ptr;
977                 job->text = xmalloc(count + 1);
978                 strncpy(job->text, *command_ptr, count);
979                 job->text[count] = '\0';
980         }
981
982         *command_ptr = return_command;
983         
984         return 0;
985 }
986
987 /* Run the child_prog, no matter what kind of command it uses.
988  */
989 static int pseudo_exec(struct child_prog *child)
990 {
991         struct built_in_command *x;
992 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
993         char *name;
994 #endif
995
996         /* Check if the command matches any of the non-forking builtins.
997          * Depending on context, this might be redundant.  But it's
998          * easier to waste a few CPU cycles than it is to figure out
999          * if this is one of those cases.
1000          */
1001         for (x = bltins; x->cmd; x++) {
1002                 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1003                         exit(x->function(child));
1004                 }
1005         }
1006
1007         /* Check if the command matches any of the forking builtins. */
1008         for (x = bltins_forking; x->cmd; x++) {
1009                 if (strcmp(child->argv[0], x->cmd) == 0) {
1010                         applet_name=x->cmd;
1011                         exit (x->function(child));
1012                 }
1013         }
1014 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
1015         /* Check if the command matches any busybox internal
1016          * commands ("applets") here.  Following discussions from
1017          * November 2000 on busybox@opensource.lineo.com, don't use
1018          * get_last_path_component().  This way explicit (with
1019          * slashes) filenames will never be interpreted as an
1020          * applet, just like with builtins.  This way the user can
1021          * override an applet with an explicit filename reference.
1022          * The only downside to this change is that an explicit
1023          * /bin/foo invocation will fork and exec /bin/foo, even if
1024          * /bin/foo is a symlink to busybox.
1025          */
1026         name = child->argv[0];
1027
1028 #ifdef BB_FEATURE_SH_APPLETS_ALWAYS_WIN
1029         /* If you enable BB_FEATURE_SH_APPLETS_ALWAYS_WIN, then
1030          * if you run /bin/cat, it will use BusyBox cat even if 
1031          * /bin/cat exists on the filesystem and is _not_ busybox.
1032          * Some systems want this, others do not.  Choose wisely.  :-)
1033          */
1034         name = get_last_path_component(name);
1035 #endif
1036
1037         {
1038             char** argv_l=child->argv;
1039             int argc_l;
1040             for(argc_l=0;*argv_l!=NULL; argv_l++, argc_l++);
1041             optind = 1;
1042             run_applet_by_name(name, argc_l, child->argv);
1043         }
1044 #endif
1045
1046         execvp(child->argv[0], child->argv);
1047         perror_msg_and_die("%s", child->argv[0]);
1048 }
1049
1050 static void insert_job(struct job *newjob, int inbg)
1051 {
1052         struct job *thejob;
1053         struct jobset *j_list=newjob->job_list;
1054
1055         /* find the ID for thejob to use */
1056         newjob->jobid = 1;
1057         for (thejob = j_list->head; thejob; thejob = thejob->next)
1058                 if (thejob->jobid >= newjob->jobid)
1059                         newjob->jobid = thejob->jobid + 1;
1060
1061         /* add thejob to the list of running jobs */
1062         if (!j_list->head) {
1063                 thejob = j_list->head = xmalloc(sizeof(*thejob));
1064         } else {
1065                 for (thejob = j_list->head; thejob->next; thejob = thejob->next) /* nothing */;
1066                 thejob->next = xmalloc(sizeof(*thejob));
1067                 thejob = thejob->next;
1068         }
1069
1070         *thejob = *newjob;   /* physically copy the struct job */
1071         thejob->next = NULL;
1072         thejob->running_progs = thejob->num_progs;
1073         thejob->stopped_progs = 0;
1074
1075         if (inbg) {
1076                 /* we don't wait for background thejobs to return -- append it 
1077                    to the list of backgrounded thejobs and leave it alone */
1078                 printf("[%d] %d\n", thejob->jobid,
1079                            newjob->progs[newjob->num_progs - 1].pid);
1080                 last_jobid = newjob->jobid;
1081         } else {
1082                 newjob->job_list->fg = thejob;
1083
1084                 /* move the new process group into the foreground */
1085                 /* suppress messages when run from /linuxrc mag@sysgo.de */
1086                 if (tcsetpgrp(shell_terminal, newjob->pgrp) && errno != ENOTTY)
1087                         perror_msg("tcsetpgrp");
1088         }
1089 }
1090
1091 static int run_command(struct job *newjob, int inbg, int outpipe[2])
1092 {
1093         /* struct job *thejob; */
1094         int i;
1095         int nextin, nextout;
1096         int pipefds[2];                         /* pipefd[0] is for reading */
1097         struct built_in_command *x;
1098         struct child_prog *child;
1099
1100         nextin = 0, nextout = 1;
1101         for (i = 0; i < newjob->num_progs; i++) {
1102                 child = & (newjob->progs[i]);
1103
1104                 if ((i + 1) < newjob->num_progs) {
1105                         if (pipe(pipefds)<0) perror_msg_and_die("pipe");
1106                         nextout = pipefds[1];
1107                 } else {
1108                         if (outpipe[1]!=-1) {
1109                                 nextout = outpipe[1];
1110                         } else {
1111                                 nextout = 1;
1112                         }
1113                 }
1114
1115
1116                 /* Check if the command matches any non-forking builtins,
1117                  * but only if this is a simple command.
1118                  * Non-forking builtins within pipes have to fork anyway,
1119                  * and are handled in pseudo_exec.  "echo foo | read bar"
1120                  * is doomed to failure, and doesn't work on bash, either.
1121                  */
1122                 if (newjob->num_progs == 1) {
1123                         for (x = bltins; x->cmd; x++) {
1124                                 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1125                                         int squirrel[] = {-1, -1, -1};
1126                                         int rcode;
1127                                         setup_redirects(child, squirrel);
1128                                         rcode = x->function(child);
1129                                         restore_redirects(squirrel);
1130                                         return rcode;
1131                                 }
1132                         }
1133                 }
1134
1135                 if (!(child->pid = fork())) {
1136                         /* Set the handling for job control signals back to the default.  */
1137                         signal(SIGINT, SIG_DFL);
1138                         signal(SIGQUIT, SIG_DFL);
1139                         signal(SIGTSTP, SIG_DFL);
1140                         signal(SIGTTIN, SIG_DFL);
1141                         signal(SIGTTOU, SIG_DFL);
1142                         signal(SIGCHLD, SIG_DFL);
1143
1144                         close_all();
1145
1146                         if (outpipe[1]!=-1) {
1147                                 close(outpipe[0]);
1148                         }
1149                         if (nextin != 0) {
1150                                 dup2(nextin, 0);
1151                                 close(nextin);
1152                         }
1153
1154                         if (nextout != 1) {
1155                                 dup2(nextout, 1);
1156                                 dup2(nextout, 2);  /* Really? */
1157                                 close(nextout);
1158                                 close(pipefds[0]);
1159                         }
1160
1161                         /* explicit redirects override pipes */
1162                         setup_redirects(child,NULL);
1163
1164                         pseudo_exec(child);
1165                 }
1166                 if (outpipe[1]!=-1) {
1167                         close(outpipe[1]);
1168                 }
1169
1170                 /* put our child in the process group whose leader is the
1171                    first process in this pipe */
1172                 setpgid(child->pid, newjob->progs[0].pid);
1173                 if (nextin != 0)
1174                         close(nextin);
1175                 if (nextout != 1)
1176                         close(nextout);
1177
1178                 /* If there isn't another process, nextin is garbage 
1179                    but it doesn't matter */
1180                 nextin = pipefds[0];
1181         }
1182
1183         newjob->pgrp = newjob->progs[0].pid;
1184
1185         insert_job(newjob, inbg);
1186
1187         return 0;
1188 }
1189
1190 static int busy_loop(FILE * input)
1191 {
1192         char *command;
1193         char *next_command = NULL;
1194         struct job newjob;
1195         pid_t  parent_pgrp;
1196         int i;
1197         int inbg;
1198         int status;
1199         newjob.job_list = &job_list;
1200         newjob.job_context = DEFAULT_CONTEXT;
1201
1202         /* save current owner of TTY so we can restore it on exit */
1203         parent_pgrp = tcgetpgrp(shell_terminal);
1204
1205         command = (char *) xcalloc(BUFSIZ, sizeof(char));
1206
1207         while (1) {
1208                 if (!job_list.fg) {
1209                         /* no job is in the foreground */
1210
1211                         /* see if any background processes have exited */
1212                         checkjobs(&job_list);
1213
1214                         if (!next_command) {
1215                                 if (get_command(input, command))
1216                                         break;
1217                                 next_command = command;
1218                         }
1219
1220                         if (expand_arguments(next_command) == FALSE) {
1221                                 free(command);
1222                                 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1223                                 next_command = NULL;
1224                                 continue;
1225                         }
1226
1227                         if (!parse_command(&next_command, &newjob, &inbg) &&
1228                                 newjob.num_progs) {
1229                                 int pipefds[2] = {-1,-1};
1230                                 debug_printf( "job=%p fed to run_command by busy_loop()'\n", 
1231                                                 &newjob);
1232                                 run_command(&newjob, inbg, pipefds);
1233                         }
1234                         else {
1235                                 free(command);
1236                                 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1237                                 next_command = NULL;
1238                         }
1239                 } else {
1240                         /* a job is running in the foreground; wait for it */
1241                         i = 0;
1242                         while (!job_list.fg->progs[i].pid ||
1243                                    job_list.fg->progs[i].is_stopped == 1) i++;
1244
1245                         if (waitpid(job_list.fg->progs[i].pid, &status, WUNTRACED)<0)
1246                                 perror_msg_and_die("waitpid(%d)",job_list.fg->progs[i].pid);
1247
1248                         if (WIFEXITED(status) || WIFSIGNALED(status)) {
1249                                 /* the child exited */
1250                                 job_list.fg->running_progs--;
1251                                 job_list.fg->progs[i].pid = 0;
1252
1253                                 if (!job_list.fg->running_progs) {
1254                                         /* child exited */
1255                                         remove_job(&job_list, job_list.fg);
1256                                         job_list.fg = NULL;
1257                                 }
1258                         } else {
1259                                 /* the child was stopped */
1260                                 job_list.fg->stopped_progs++;
1261                                 job_list.fg->progs[i].is_stopped = 1;
1262
1263                                 if (job_list.fg->stopped_progs == job_list.fg->running_progs) {
1264                                         printf("\n" JOB_STATUS_FORMAT, job_list.fg->jobid,
1265                                                    "Stopped", job_list.fg->text);
1266                                         job_list.fg = NULL;
1267                                 }
1268                         }
1269
1270                         if (!job_list.fg) {
1271                                 /* move the shell to the foreground */
1272                                 /* suppress messages when run from /linuxrc mag@sysgo.de */
1273                                 if (tcsetpgrp(shell_terminal, getpgrp()) && errno != ENOTTY)
1274                                         perror_msg("tcsetpgrp"); 
1275                         }
1276                 }
1277         }
1278         free(command);
1279
1280         /* return controlling TTY back to parent process group before exiting */
1281         if (tcsetpgrp(shell_terminal, parent_pgrp))
1282                 perror_msg("tcsetpgrp");
1283
1284         /* return exit status if called with "-c" */
1285         if (input == NULL && WIFEXITED(status))
1286                 return WEXITSTATUS(status);
1287         
1288         return 0;
1289 }
1290
1291
1292 #ifdef BB_FEATURE_CLEAN_UP
1293 void free_memory(void)
1294 {
1295         if (cwd) {
1296                 free(cwd);
1297         }
1298         if (local_pending_command)
1299                 free(local_pending_command);
1300
1301         if (job_list.fg && !job_list.fg->running_progs) {
1302                 remove_job(&job_list, job_list.fg);
1303         }
1304 }
1305 #endif
1306
1307 /* Make sure we have a controlling tty.  If we get started under a job
1308  * aware app (like bash for example), make sure we are now in charge so
1309  * we don't fight over who gets the foreground */
1310 static void setup_job_control()
1311 {
1312         /* Loop until we are in the foreground.  */
1313         while (tcgetpgrp (shell_terminal) != (shell_pgrp = getpgrp ()))
1314                 kill (- shell_pgrp, SIGTTIN);
1315
1316         /* Ignore interactive and job-control signals.  */
1317         signal(SIGINT, SIG_IGN);
1318         signal(SIGQUIT, SIG_IGN);
1319         signal(SIGTSTP, SIG_IGN);
1320         signal(SIGTTIN, SIG_IGN);
1321         signal(SIGTTOU, SIG_IGN);
1322         signal(SIGCHLD, SIG_IGN);
1323
1324         /* Put ourselves in our own process group.  */
1325         shell_pgrp = getpid ();
1326         if (setpgid (shell_pgrp, shell_pgrp) < 0) {
1327                 perror_msg_and_die("Couldn't put the shell in its own process group");
1328         }
1329
1330         /* Grab control of the terminal.  */
1331         tcsetpgrp(shell_terminal, shell_pgrp);
1332 }
1333
1334 int shell_main(int argc_l, char **argv_l)
1335 {
1336         int opt, interactive=FALSE;
1337         FILE *input = stdin;
1338         argc = argc_l;
1339         argv = argv_l;
1340
1341         /* These variables need re-initializing when recursing */
1342         last_jobid = 0;
1343         shell_context = 0;
1344         local_pending_command = NULL;
1345         close_me_head = NULL;
1346         job_list.head = NULL;
1347         job_list.fg = NULL;
1348
1349         if (argv[0] && argv[0][0] == '-') {
1350                 FILE *prof_input;
1351                 prof_input = fopen("/etc/profile", "r");
1352                 if (!prof_input) {
1353                         printf( "Couldn't open file '/etc/profile'\n");
1354                 } else {
1355                         int tmp_fd = fileno(prof_input);
1356                         mark_open(tmp_fd);      
1357                         /* Now run the file */
1358                         busy_loop(prof_input);
1359                         fclose(prof_input);
1360                         mark_closed(tmp_fd);
1361                 }
1362         }
1363
1364         while ((opt = getopt(argc_l, argv_l, "cxi")) > 0) {
1365                 switch (opt) {
1366                         case 'c':
1367                                 input = NULL;
1368                                 if (local_pending_command != 0)
1369                                         error_msg_and_die("multiple -c arguments");
1370                                 local_pending_command = xstrdup(argv[optind]);
1371                                 optind++;
1372                                 argv = argv+optind;
1373                                 break;
1374                         case 'i':
1375                                 interactive = TRUE;
1376                                 break;
1377                         default:
1378                                 show_usage();
1379                 }
1380         }
1381         /* A shell is interactive if the `-i' flag was given, or if all of
1382          * the following conditions are met:
1383          *        no -c command
1384          *    no arguments remaining or the -s flag given
1385          *    standard input is a terminal
1386          *    standard output is a terminal
1387          *    Refer to Posix.2, the description of the `sh' utility. */
1388         if (argv[optind]==NULL && input==stdin &&
1389                         isatty(fileno(stdin)) && isatty(fileno(stdout))) {
1390                 interactive=TRUE;
1391         }
1392         setup_job_control();
1393         if (interactive==TRUE) {
1394                 //printf( "optind=%d  argv[optind]='%s'\n", optind, argv[optind]);
1395                 /* Looks like they want an interactive shell */
1396                 printf( "\n\n" BB_BANNER " Built-in shell (lash)\n");
1397                 printf( "Enter 'help' for a list of built-in commands.\n\n");
1398         } else if (local_pending_command==NULL) {
1399                 //printf( "optind=%d  argv[optind]='%s'\n", optind, argv[optind]);
1400                 input = xfopen(argv[optind], "r");
1401                 mark_open(fileno(input));  /* be lazy, never mark this closed */
1402         }
1403
1404         /* initialize the cwd -- this is never freed...*/
1405         cwd = xgetcwd(0);
1406         if (!cwd)
1407                 cwd = unknown;
1408
1409 #ifdef BB_FEATURE_CLEAN_UP
1410         atexit(free_memory);
1411 #endif
1412
1413 #ifdef BB_FEATURE_COMMAND_EDITING
1414         cmdedit_set_initial_prompt();
1415 #else
1416         PS1 = NULL;
1417 #endif
1418         
1419         return (busy_loop(input));
1420 }
1421