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