aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2001-04-26 23:22:31 +0000
committerEric Andersen <andersen@codepoet.org>2001-04-26 23:22:31 +0000
commit25f2703015bede1d6b5b919b01f3df5848597bdb (patch)
tree00abde694cd250f56ed422db18db7cb2fdc4d296
parenta1dbc2246954a288f0749fed97c35ff907bf9a23 (diff)
downloadbusybox-w32-25f2703015bede1d6b5b919b01f3df5848597bdb.tar.gz
busybox-w32-25f2703015bede1d6b5b919b01f3df5848597bdb.tar.bz2
busybox-w32-25f2703015bede1d6b5b919b01f3df5848597bdb.zip
This is the initial checkin of Larry Doolittle's hush.c, using his
April 25, 2001 snapshot, adjusted a bit by me so it has cmdedit support. This checkin also removes sh.c. In the future sh.c will be a symlink to your shell of choice. For now, this symlink will default to pointing to lash.c (as in the past). If you change the symlink to point to hush.c, then thats what you will get. This symlink business is a temporary situation, which will be cleaned up Real Soon Now(tm). -Erik
-rw-r--r--Makefile1
-rw-r--r--hush.c2191
-rw-r--r--sh.c1935
-rw-r--r--shell/hush.c2191
4 files changed, 4383 insertions, 1935 deletions
diff --git a/Makefile b/Makefile
index dcf6bd641..5a62cb0ef 100644
--- a/Makefile
+++ b/Makefile
@@ -271,6 +271,7 @@ CFLAGS += $(CFLAGS_EXTRA)
271all: applet_source_list busybox busybox.links doc 271all: applet_source_list busybox busybox.links doc
272 272
273applet_source_list: busybox.sh Config.h 273applet_source_list: busybox.sh Config.h
274 if [ ! -L sh.c ] ; then ln -s lash.c sh.c ; fi
274 (echo -n "APPLET_SOURCES := "; $(SHELL) $^ $(BB_SRC_DIR)) > $@ 275 (echo -n "APPLET_SOURCES := "; $(SHELL) $^ $(BB_SRC_DIR)) > $@
275 276
276doc: olddoc 277doc: olddoc
diff --git a/hush.c b/hush.c
new file mode 100644
index 000000000..f2a4ea410
--- /dev/null
+++ b/hush.c
@@ -0,0 +1,2191 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * sh.c -- a prototype Bourne shell grammar parser
4 * Intended to follow the original Thompson and Ritchie
5 * "small and simple is beautiful" philosophy, which
6 * incidentally is a good match to today's BusyBox.
7 *
8 * Copyright (C) 2000,2001 Larry Doolittle <larry@doolittle.boa.org>
9 *
10 * Credits:
11 * The parser routines proper are all original material, first
12 * written Dec 2000 and Jan 2001 by Larry Doolittle.
13 * The execution engine, the builtins, and much of the underlying
14 * support has been adapted from busybox-0.49pre's lash,
15 * which is Copyright (C) 2000 by Lineo, Inc., and
16 * written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>.
17 * That, in turn, is based in part on ladsh.c, by Michael K. Johnson and
18 * Erik W. Troan, which they placed in the public domain. I don't know
19 * how much of the Johnson/Troan code has survived the repeated rewrites.
20 * Other credits:
21 * simple_itoa() was lifted from boa-0.93.15
22 * b_addchr() derived from similar w_addchar function in glibc-2.2
23 * setup_redirect(), redirect_opt_num(), and big chunks of main()
24 * and many builtins derived from contributions by Erik Andersen
25 * miscellaneous bugfixes from Matt Kraai
26 *
27 * There are two big (and related) architecture differences between
28 * this parser and the lash parser. One is that this version is
29 * actually designed from the ground up to understand nearly all
30 * of the Bourne grammar. The second, consequential change is that
31 * the parser and input reader have been turned inside out. Now,
32 * the parser is in control, and asks for input as needed. The old
33 * way had the input reader in control, and it asked for parsing to
34 * take place as needed. The new way makes it much easier to properly
35 * handle the recursion implicit in the various substitutions, especially
36 * across continuation lines.
37 *
38 * Bash grammar not implemented: (how many of these were in original sh?)
39 * $@ (those sure look like weird quoting rules)
40 * $_
41 * ! negation operator for pipes
42 * &> and >& redirection of stdout+stderr
43 * Brace Expansion
44 * Tilde Expansion
45 * fancy forms of Parameter Expansion
46 * Arithmetic Expansion
47 * <(list) and >(list) Process Substitution
48 * reserved words: if, then, elif, else, fi, while, until, for,
49 * do, done, case
50 * Here Documents ( << word )
51 * Functions
52 * Major bugs:
53 * job handling woefully incomplete and buggy
54 * reserved word execution woefully incomplete and buggy
55 * incomplete reserved word sequence doesn't request more lines of input
56 * to-do:
57 * port selected bugfixes from post-0.49 busybox lash
58 * finish implementing reserved words
59 * handle children going into background
60 * clean up recognition of null pipes
61 * have builtin_exec set flag to avoid restore_redirects
62 * figure out if "echo foo}" is fixable
63 * check setting of global_argc and global_argv
64 * control-C handling, probably with longjmp
65 * VAR=value prefix for simple commands
66 * follow IFS rules more precisely, including update semantics
67 * write builtin_eval, builtin_ulimit, builtin_umask
68 * figure out what to do with backslash-newline
69 * explain why we use signal instead of sigaction
70 * propagate syntax errors, die on resource errors?
71 * continuation lines, both explicit and implicit - done?
72 * memory leak finding and plugging - done?
73 * more testing, especially quoting rules and redirection
74 * maybe change map[] to use 2-bit entries
75 * (eventually) remove all the printf's
76 * more integration with BusyBox: prompts, cmdedit, applets
77 *
78 * This program is free software; you can redistribute it and/or modify
79 * it under the terms of the GNU General Public License as published by
80 * the Free Software Foundation; either version 2 of the License, or
81 * (at your option) any later version.
82 *
83 * This program is distributed in the hope that it will be useful,
84 * but WITHOUT ANY WARRANTY; without even the implied warranty of
85 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
86 * General Public License for more details.
87 *
88 * You should have received a copy of the GNU General Public License
89 * along with this program; if not, write to the Free Software
90 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
91 */
92#include <ctype.h> /* isalpha, isdigit */
93#include <unistd.h> /* getpid */
94#include <stdlib.h> /* getenv, atoi */
95#include <string.h> /* strchr */
96#include <stdio.h> /* popen etc. */
97#include <glob.h> /* glob, of course */
98#include <stdarg.h> /* va_list */
99#include <errno.h>
100#include <fcntl.h>
101#include <getopt.h> /* should be pretty obvious */
102
103#include <sys/types.h>
104#include <sys/wait.h>
105#include <signal.h>
106
107/* #include <dmalloc.h> */
108/* #define DEBUG_SHELL */
109
110#ifdef BB_VER
111#include "busybox.h"
112#include "cmdedit.h"
113#else
114/* in place of #include "busybox.h"; much of this is indeed
115 * pasted in from the copy of busybox.h in busybox-0.49pre */
116
117#define xrealloc realloc
118#define applet_name "hush"
119#define shell_main main
120
121extern void *xmalloc(size_t size)
122{
123 void *ptr = malloc(size);
124
125 if (!ptr) {
126 fprintf(stderr, "memory_exhausted\n");
127 exit (EXIT_FAILURE);
128 }
129 return ptr;
130}
131
132extern void usage(const char *usage)
133{
134 fprintf(stderr, "Usage: %s\n", usage);
135 exit(EXIT_FAILURE);
136}
137
138static void verror_msg(const char *s, va_list p)
139{
140 fflush(stdout);
141 fprintf(stderr, "%s: ", applet_name);
142 vfprintf(stderr, s, p);
143 fflush(stderr);
144}
145
146extern void error_msg(const char *s, ...)
147{
148 va_list p;
149
150 va_start(p, s);
151 verror_msg(s, p);
152 va_end(p);
153}
154
155extern void error_msg_and_die(const char *s, ...)
156{
157 va_list p;
158
159 va_start(p, s);
160 verror_msg(s, p);
161 va_end(p);
162 exit(EXIT_FAILURE);
163}
164
165static void vperror_msg(const char *s, va_list p)
166{
167 fflush(stdout);
168 fprintf(stderr, "%s: ", applet_name);
169 if (s && *s) {
170 vfprintf(stderr, s, p);
171 fputs(": ", stderr);
172 }
173 fprintf(stderr, "%s\n", strerror(errno));
174 fflush(stderr);
175}
176
177extern void perror_msg(const char *s, ...)
178{
179 va_list p;
180
181 va_start(p, s);
182 vperror_msg(s, p);
183 va_end(p);
184}
185
186extern void perror_msg_and_die(const char *s, ...)
187{
188 va_list p;
189
190 va_start(p, s);
191 vperror_msg(s, p);
192 va_end(p);
193 exit(EXIT_FAILURE);
194}
195
196FILE *xfopen(const char *path, const char *mode)
197{
198 FILE *fp;
199 if ((fp = fopen(path, mode)) == NULL)
200 perror_msg_and_die(path);
201 return fp;
202}
203#endif /* of busybox.h replacement */
204
205typedef enum {
206 REDIRECT_INPUT = 1,
207 REDIRECT_OVERWRITE = 2,
208 REDIRECT_APPEND = 3,
209 REDIRECT_HEREIS = 4,
210 REDIRECT_IO = 5
211} redir_type;
212
213/* The descrip member of this structure is only used to make debugging
214 * output pretty */
215struct {int mode; int default_fd; char *descrip;} redir_table[] = {
216 { 0, 0, "()" },
217 { O_RDONLY, 0, "<" },
218 { O_CREAT|O_TRUNC|O_WRONLY, 1, ">" },
219 { O_CREAT|O_APPEND|O_WRONLY, 1, ">>" },
220 { O_RDONLY, -1, "<<" },
221 { O_RDWR, 1, "<>" }
222};
223
224typedef enum {
225 PIPE_SEQ = 1,
226 PIPE_AND = 2,
227 PIPE_OR = 3,
228 PIPE_BG = 4,
229} pipe_style;
230
231/* might eventually control execution */
232typedef enum {
233 RES_NONE = 0,
234 RES_IF = 1,
235 RES_THEN = 2,
236 RES_ELIF = 3,
237 RES_ELSE = 4,
238 RES_FI = 5,
239 RES_FOR = 6,
240 RES_WHILE = 7,
241 RES_UNTIL = 8,
242 RES_DO = 9,
243 RES_DONE = 10,
244 RES_XXXX = 11
245} reserved_style;
246#define FLAG_END (1<<RES_NONE)
247#define FLAG_IF (1<<RES_IF)
248#define FLAG_THEN (1<<RES_THEN)
249#define FLAG_ELIF (1<<RES_ELIF)
250#define FLAG_ELSE (1<<RES_ELSE)
251#define FLAG_FI (1<<RES_FI)
252#define FLAG_FOR (1<<RES_FOR)
253#define FLAG_WHILE (1<<RES_WHILE)
254#define FLAG_UNTIL (1<<RES_UNTIL)
255#define FLAG_DO (1<<RES_DO)
256#define FLAG_DONE (1<<RES_DONE)
257#define FLAG_START (1<<RES_XXXX)
258
259/* This holds pointers to the various results of parsing */
260struct p_context {
261 struct child_prog *child;
262 struct pipe *list_head;
263 struct pipe *pipe;
264 struct redir_struct *pending_redirect;
265 reserved_style w;
266 int old_flag; /* for figuring out valid reserved words */
267 struct p_context *stack;
268 /* How about quoting status? */
269};
270
271struct redir_struct {
272 redir_type type; /* type of redirection */
273 int fd; /* file descriptor being redirected */
274 int dup; /* -1, or file descriptor being duplicated */
275 struct redir_struct *next; /* pointer to the next redirect in the list */
276 glob_t word; /* *word.gl_pathv is the filename */
277};
278
279struct child_prog {
280 pid_t pid; /* 0 if exited */
281 char **argv; /* program name and arguments */
282 struct pipe *group; /* if non-NULL, first in group or subshell */
283 int subshell; /* flag, non-zero if group must be forked */
284 struct redir_struct *redirects; /* I/O redirections */
285 glob_t glob_result; /* result of parameter globbing */
286 int is_stopped; /* is the program currently running? */
287 struct pipe *family; /* pointer back to the child's parent pipe */
288};
289
290struct pipe {
291 int jobid; /* job number */
292 int num_progs; /* total number of programs in job */
293 int running_progs; /* number of programs running */
294 char *text; /* name of job */
295 char *cmdbuf; /* buffer various argv's point into */
296 pid_t pgrp; /* process group ID for the job */
297 struct child_prog *progs; /* array of commands in pipe */
298 struct pipe *next; /* to track background commands */
299 int stopped_progs; /* number of programs alive, but stopped */
300 int job_context; /* bitmask defining current context */
301 pipe_style followup; /* PIPE_BG, PIPE_SEQ, PIPE_OR, PIPE_AND */
302 reserved_style r_mode; /* supports if, for, while, until */
303 struct jobset *job_list;
304};
305
306struct jobset {
307 struct pipe *head; /* head of list of running jobs */
308 struct pipe *fg; /* current foreground job */
309};
310
311struct close_me {
312 int fd;
313 struct close_me *next;
314};
315
316/* globals, connect us to the outside world
317 * the first three support $?, $#, and $1 */
318char **global_argv;
319unsigned int global_argc;
320unsigned int last_return_code;
321extern char **environ; /* This is in <unistd.h>, but protected with __USE_GNU */
322
323/* Variables we export */
324unsigned int shell_context; /* Used in cmdedit.c to reset the
325 * context when someone hits ^C */
326
327/* "globals" within this file */
328static char *ifs=NULL;
329static char map[256];
330static int fake_mode=0;
331static int interactive=0;
332static struct close_me *close_me_head = NULL;
333static char *cwd;
334static struct jobset job_list = { NULL, NULL };
335static unsigned int last_bg_pid=0;
336static char *PS1;
337static char *PS2 = "> ";
338
339#define B_CHUNK (100)
340#define B_NOSPAC 1
341#define MAX_LINE 256 /* for cwd */
342#define MAX_READ 256 /* for builtin_read */
343
344typedef struct {
345 char *data;
346 int length;
347 int maxlen;
348 int quote;
349 int nonnull;
350} o_string;
351#define NULL_O_STRING {NULL,0,0,0,0}
352/* used for initialization:
353 o_string foo = NULL_O_STRING; */
354
355/* I can almost use ordinary FILE *. Is open_memstream() universally
356 * available? Where is it documented? */
357struct in_str {
358 const char *p;
359 int __promptme;
360 int promptmode;
361 FILE *file;
362 int (*get) (struct in_str *);
363 int (*peek) (struct in_str *);
364};
365#define b_getch(input) ((input)->get(input))
366#define b_peek(input) ((input)->peek(input))
367
368#define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
369
370struct built_in_command {
371 char *cmd; /* name */
372 char *descr; /* description */
373 int (*function) (struct child_prog *); /* function ptr */
374};
375
376/* belongs in busybox.h */
377static inline int max(int a, int b) {
378 return (a>b)?a:b;
379}
380
381/* This should be in utility.c */
382#ifdef DEBUG_SHELL
383static void debug_printf(const char *format, ...)
384{
385 va_list args;
386 va_start(args, format);
387 vfprintf(stderr, format, args);
388 va_end(args);
389}
390#else
391static void debug_printf(const char *format, ...) { }
392#endif
393#define final_printf debug_printf
394
395void __syntax(char *file, int line) {
396 fprintf(stderr,"syntax error %s:%d\n",file,line);
397}
398#define syntax() __syntax(__FILE__, __LINE__)
399
400/* Index of subroutines: */
401/* function prototypes for builtins */
402static int builtin_cd(struct child_prog *child);
403static int builtin_env(struct child_prog *child);
404static int builtin_exec(struct child_prog *child);
405static int builtin_exit(struct child_prog *child);
406static int builtin_export(struct child_prog *child);
407static int builtin_fg_bg(struct child_prog *child);
408static int builtin_help(struct child_prog *child);
409static int builtin_jobs(struct child_prog *child);
410static int builtin_pwd(struct child_prog *child);
411static int builtin_read(struct child_prog *child);
412static int builtin_shift(struct child_prog *child);
413static int builtin_source(struct child_prog *child);
414static int builtin_ulimit(struct child_prog *child);
415static int builtin_umask(struct child_prog *child);
416static int builtin_unset(struct child_prog *child);
417/* o_string manipulation: */
418static int b_check_space(o_string *o, int len);
419static int b_addchr(o_string *o, int ch);
420static void b_reset(o_string *o);
421static int b_addqchr(o_string *o, int ch, int quote);
422static int b_adduint(o_string *o, unsigned int i);
423/* in_str manipulations: */
424static int static_get(struct in_str *i);
425static int static_peek(struct in_str *i);
426static int file_get(struct in_str *i);
427static int file_peek(struct in_str *i);
428static void setup_file_in_str(struct in_str *i, FILE *f);
429static void setup_string_in_str(struct in_str *i, const char *s);
430/* close_me manipulations: */
431static void mark_open(int fd);
432static void mark_closed(int fd);
433static void close_all();
434/* "run" the final data structures: */
435static char *indenter(int i);
436static int run_list_test(struct pipe *head, int indent);
437static int run_pipe_test(struct pipe *pi, int indent);
438/* really run the final data structures: */
439static int setup_redirects(struct child_prog *prog, int squirrel[]);
440static int pipe_wait(struct pipe *pi);
441static int run_list_real(struct pipe *pi);
442static void pseudo_exec(struct child_prog *child) __attribute__ ((noreturn));
443static int run_pipe_real(struct pipe *pi);
444/* extended glob support: */
445static int globhack(const char *src, int flags, glob_t *pglob);
446static int glob_needed(const char *s);
447static int xglob(o_string *dest, int flags, glob_t *pglob);
448/* data structure manipulation: */
449static int setup_redirect(struct p_context *ctx, int fd, redir_type style, struct in_str *input);
450static void initialize_context(struct p_context *ctx);
451static int done_word(o_string *dest, struct p_context *ctx);
452static int done_command(struct p_context *ctx);
453static int done_pipe(struct p_context *ctx, pipe_style type);
454/* primary string parsing: */
455static int redirect_dup_num(struct in_str *input);
456static int redirect_opt_num(o_string *o);
457static int process_command_subs(o_string *dest, struct p_context *ctx, struct in_str *input, int subst_end);
458static int parse_group(o_string *dest, struct p_context *ctx, struct in_str *input, int ch);
459static void lookup_param(o_string *dest, struct p_context *ctx, o_string *src);
460static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *input);
461static int parse_string(o_string *dest, struct p_context *ctx, const char *src);
462static int parse_stream(o_string *dest, struct p_context *ctx, struct in_str *input0, int end_trigger);
463/* setup: */
464static int parse_stream_outer(struct in_str *inp);
465static int parse_string_outer(const char *s);
466static int parse_file_outer(FILE *f);
467
468/* Table of built-in functions. They can be forked or not, depending on
469 * context: within pipes, they fork. As simple commands, they do not.
470 * When used in non-forking context, they can change global variables
471 * in the parent shell process. If forked, of course they can not.
472 * For example, 'unset foo | whatever' will parse and run, but foo will
473 * still be set at the end. */
474static struct built_in_command bltins[] = {
475 {"bg", "Resume a job in the background", builtin_fg_bg},
476 {"cd", "Change working directory", builtin_cd},
477 {"env", "Print all environment variables", builtin_env},
478 {"exec", "Exec command, replacing this shell with the exec'd process", builtin_exec},
479 {"exit", "Exit from shell()", builtin_exit},
480 {"export", "Set environment variable", builtin_export},
481 {"fg", "Bring job into the foreground", builtin_fg_bg},
482 {"jobs", "Lists the active jobs", builtin_jobs},
483 {"pwd", "Print current directory", builtin_pwd},
484 {"read", "Input environment variable", builtin_read},
485 {"shift", "Shift positional parameters", builtin_shift},
486 {"ulimit","Controls resource limits", builtin_ulimit},
487 {"umask","Sets file creation mask", builtin_umask},
488 {"unset", "Unset environment variable", builtin_unset},
489 {".", "Source-in and run commands in a file", builtin_source},
490 {"help", "List shell built-in commands", builtin_help},
491 {NULL, NULL, NULL}
492};
493
494/* built-in 'cd <path>' handler */
495static int builtin_cd(struct child_prog *child)
496{
497 char *newdir;
498 if (child->argv[1] == NULL)
499 newdir = getenv("HOME");
500 else
501 newdir = child->argv[1];
502 if (chdir(newdir)) {
503 printf("cd: %s: %s\n", newdir, strerror(errno));
504 return EXIT_FAILURE;
505 }
506 getcwd(cwd, sizeof(char)*MAX_LINE);
507 return EXIT_SUCCESS;
508}
509
510/* built-in 'env' handler */
511static int builtin_env(struct child_prog *dummy)
512{
513 char **e = environ;
514 if (e == NULL) return EXIT_FAILURE;
515 for (; *e; e++) {
516 puts(*e);
517 }
518 return EXIT_SUCCESS;
519}
520
521/* built-in 'exec' handler */
522static int builtin_exec(struct child_prog *child)
523{
524 if (child->argv[1] == NULL)
525 return EXIT_SUCCESS; /* Really? */
526 child->argv++;
527 pseudo_exec(child);
528 /* never returns */
529}
530
531/* built-in 'exit' handler */
532static int builtin_exit(struct child_prog *child)
533{
534 if (child->argv[1] == NULL)
535 exit(EXIT_SUCCESS);
536 exit (atoi(child->argv[1]));
537}
538
539/* built-in 'export VAR=value' handler */
540static int builtin_export(struct child_prog *child)
541{
542 int res;
543
544 if (child->argv[1] == NULL) {
545 return (builtin_env(child));
546 }
547 res = putenv(child->argv[1]);
548 if (res)
549 fprintf(stderr, "export: %s\n", strerror(errno));
550 return (res);
551}
552
553/* built-in 'fg' and 'bg' handler */
554static int builtin_fg_bg(struct child_prog *child)
555{
556 int i, jobNum;
557 struct pipe *job=NULL;
558
559 if (!child->argv[1] || child->argv[2]) {
560 error_msg("%s: exactly one argument is expected\n",
561 child->argv[0]);
562 return EXIT_FAILURE;
563 }
564
565 if (sscanf(child->argv[1], "%%%d", &jobNum) != 1) {
566 error_msg("%s: bad argument '%s'\n",
567 child->argv[0], child->argv[1]);
568 return EXIT_FAILURE;
569 }
570
571 for (job = child->family->job_list->head; job; job = job->next) {
572 if (job->jobid == jobNum) {
573 break;
574 }
575 }
576
577 if (!job) {
578 error_msg("%s: unknown job %d\n",
579 child->argv[0], jobNum);
580 return EXIT_FAILURE;
581 }
582
583 if (*child->argv[0] == 'f') {
584 /* Make this job the foreground job */
585 /* suppress messages when run from /linuxrc mag@sysgo.de */
586 if (tcsetpgrp(0, job->pgrp) && errno != ENOTTY)
587 perror_msg("tcsetpgrp");
588 child->family->job_list->fg = job;
589 }
590
591 /* Restart the processes in the job */
592 for (i = 0; i < job->num_progs; i++)
593 job->progs[i].is_stopped = 0;
594
595 kill(-job->pgrp, SIGCONT);
596
597 job->stopped_progs = 0;
598 return EXIT_SUCCESS;
599}
600
601/* built-in 'help' handler */
602static int builtin_help(struct child_prog *dummy)
603{
604 struct built_in_command *x;
605
606 printf("\nBuilt-in commands:\n");
607 printf("-------------------\n");
608 for (x = bltins; x->cmd; x++) {
609 if (x->descr==NULL)
610 continue;
611 printf("%s\t%s\n", x->cmd, x->descr);
612 }
613 printf("\n\n");
614 return EXIT_SUCCESS;
615}
616
617/* built-in 'jobs' handler */
618static int builtin_jobs(struct child_prog *child)
619{
620 struct pipe *job;
621 char *status_string;
622
623 for (job = child->family->job_list->head; job; job = job->next) {
624 if (job->running_progs == job->stopped_progs)
625 status_string = "Stopped";
626 else
627 status_string = "Running";
628 printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->text);
629 }
630 return EXIT_SUCCESS;
631}
632
633
634/* built-in 'pwd' handler */
635static int builtin_pwd(struct child_prog *dummy)
636{
637 getcwd(cwd, MAX_LINE);
638 puts(cwd);
639 return EXIT_SUCCESS;
640}
641
642/* built-in 'read VAR' handler */
643static int builtin_read(struct child_prog *child)
644{
645 int res = 0, len, newlen;
646 char *s;
647 char string[MAX_READ];
648
649 if (child->argv[1]) {
650 /* argument (VAR) given: put "VAR=" into buffer */
651 strcpy(string, child->argv[1]);
652 len = strlen(string);
653 string[len++] = '=';
654 string[len] = '\0';
655 /* XXX would it be better to go through in_str? */
656 fgets(&string[len], sizeof(string) - len, stdin); /* read string */
657 newlen = strlen(string);
658 if(newlen > len)
659 string[--newlen] = '\0'; /* chomp trailing newline */
660 /*
661 ** string should now contain "VAR=<value>"
662 ** copy it (putenv() won't do that, so we must make sure
663 ** the string resides in a static buffer!)
664 */
665 res = -1;
666 if((s = strdup(string)))
667 res = putenv(s);
668 if (res)
669 fprintf(stderr, "read: %s\n", strerror(errno));
670 }
671 else
672 fgets(string, sizeof(string), stdin);
673
674 return (res);
675}
676
677/* Built-in 'shift' handler */
678static int builtin_shift(struct child_prog *child)
679{
680 int n=1;
681 if (child->argv[1]) {
682 n=atoi(child->argv[1]);
683 }
684 if (n>=0 && n<global_argc) {
685 /* XXX This probably breaks $0 */
686 global_argc -= n;
687 global_argv += n;
688 return EXIT_SUCCESS;
689 } else {
690 return EXIT_FAILURE;
691 }
692}
693
694/* Built-in '.' handler (read-in and execute commands from file) */
695static int builtin_source(struct child_prog *child)
696{
697 FILE *input;
698 int status;
699
700 if (child->argv[1] == NULL)
701 return EXIT_FAILURE;
702
703 /* XXX search through $PATH is missing */
704 input = fopen(child->argv[1], "r");
705 if (!input) {
706 fprintf(stderr, "Couldn't open file '%s'\n", child->argv[1]);
707 return EXIT_FAILURE;
708 }
709
710 /* Now run the file */
711 /* XXX argv and argc are broken; need to save old global_argv
712 * (pointer only is OK!) on this stack frame,
713 * set global_argv=child->argv+1, recurse, and restore. */
714 mark_open(fileno(input));
715 status = parse_file_outer(input);
716 mark_closed(fileno(input));
717 fclose(input);
718 return (status);
719}
720
721static int builtin_ulimit(struct child_prog *child)
722{
723 printf("builtin_ulimit not written\n");
724 return EXIT_FAILURE;
725}
726
727static int builtin_umask(struct child_prog *child)
728{
729 printf("builtin_umask not written\n");
730 return EXIT_FAILURE;
731}
732
733/* built-in 'unset VAR' handler */
734static int builtin_unset(struct child_prog *child)
735{
736 if (child->argv[1] == NULL) {
737 fprintf(stderr, "unset: parameter required.\n");
738 return EXIT_FAILURE;
739 }
740 unsetenv(child->argv[1]);
741 return EXIT_SUCCESS;
742}
743
744static int b_check_space(o_string *o, int len)
745{
746 /* It would be easy to drop a more restrictive policy
747 * in here, such as setting a maximum string length */
748 if (o->length + len > o->maxlen) {
749 char *old_data = o->data;
750 /* assert (data == NULL || o->maxlen != 0); */
751 o->maxlen += max(2*len, B_CHUNK);
752 o->data = realloc(o->data, 1 + o->maxlen);
753 if (o->data == NULL) {
754 free(old_data);
755 }
756 }
757 return o->data == NULL;
758}
759
760static int b_addchr(o_string *o, int ch)
761{
762 debug_printf("b_addchr: %c %d %p\n", ch, o->length, o);
763 if (b_check_space(o, 1)) return B_NOSPAC;
764 o->data[o->length] = ch;
765 o->length++;
766 o->data[o->length] = '\0';
767 return 0;
768}
769
770static void b_reset(o_string *o)
771{
772 o->length = 0;
773 o->nonnull = 0;
774 if (o->data != NULL) *o->data = '\0';
775}
776
777static void b_free(o_string *o)
778{
779 b_reset(o);
780 if (o->data != NULL) free(o->data);
781 o->data = NULL;
782 o->maxlen = 0;
783}
784
785/* My analysis of quoting semantics tells me that state information
786 * is associated with a destination, not a source.
787 */
788static int b_addqchr(o_string *o, int ch, int quote)
789{
790 if (quote && strchr("*?[\\",ch)) {
791 int rc;
792 rc = b_addchr(o, '\\');
793 if (rc) return rc;
794 }
795 return b_addchr(o, ch);
796}
797
798/* belongs in utility.c */
799char *simple_itoa(unsigned int i)
800{
801 /* 21 digits plus null terminator, good for 64-bit or smaller ints */
802 static char local[22];
803 char *p = &local[21];
804 *p-- = '\0';
805 do {
806 *p-- = '0' + i % 10;
807 i /= 10;
808 } while (i > 0);
809 return p + 1;
810}
811
812static int b_adduint(o_string *o, unsigned int i)
813{
814 int r;
815 char *p = simple_itoa(i);
816 /* no escape checking necessary */
817 do r=b_addchr(o, *p++); while (r==0 && *p);
818 return r;
819}
820
821static int static_get(struct in_str *i)
822{
823 int ch=*i->p++;
824 if (ch=='\0') return EOF;
825 return ch;
826}
827
828static int static_peek(struct in_str *i)
829{
830 return *i->p;
831}
832
833static inline void cmdedit_set_initial_prompt(void)
834{
835#ifdef BB_FEATURE_SH_SIMPLE_PROMPT
836 PS1 = NULL;
837#else
838 PS1 = getenv("PS1");
839 if(PS1==0)
840 PS1 = "\\w \\$ ";
841#endif
842}
843
844static inline void setup_prompt_string(int promptmode, char **prompt_str)
845{
846#ifdef BB_FEATURE_SH_SIMPLE_PROMPT
847 /* Set up the prompt */
848 if (promptmode == 1) {
849 if (PS1)
850 free(PS1);
851 PS1=xmalloc(strlen(cwd)+4);
852 sprintf(PS1, "%s %s", cwd, ( geteuid() != 0 ) ? "$ ":"# ");
853 *prompt_str = PS1;
854 } else {
855 *prompt_str = PS2;
856 }
857#else
858 *prompt_str = (promptmode==0)? PS1 : PS2;
859#endif
860}
861
862static void get_user_input(struct in_str *i)
863{
864 char *prompt_str;
865 static char the_command[MAX_LINE];
866
867 setup_prompt_string(i->promptmode, &prompt_str);
868#ifdef BB_FEATURE_COMMAND_EDITING
869 /*
870 ** enable command line editing only while a command line
871 ** is actually being read; otherwise, we'll end up bequeathing
872 ** atexit() handlers and other unwanted stuff to our
873 ** child processes (rob@sysgo.de)
874 */
875 cmdedit_read_input(prompt_str, the_command);
876 cmdedit_terminate();
877#else
878 fputs(prompt_str, stdout);
879 fflush(stdout);
880 the_command[0]=fgetc(i->file);
881 the_command[1]='\0';
882#endif
883 i->p = the_command;
884}
885
886/* This is the magic location that prints prompts
887 * and gets data back from the user */
888static int file_get(struct in_str *i)
889{
890 int ch;
891
892 ch = 0;
893 /* If there is data waiting, eat it up */
894 if (i->p && *i->p) {
895 ch=*i->p++;
896 } else {
897 /* need to double check i->file because we might be doing something
898 * more complicated by now, like sourcing or substituting. */
899 if (i->__promptme && interactive && i->file == stdin) {
900 get_user_input(i);
901 i->promptmode=2;
902 }
903 i->__promptme = 0;
904
905 if (i->p && *i->p) {
906 ch=*i->p++;
907 }
908 debug_printf("b_getch: got a %d\n", ch);
909 }
910 if (ch == '\n') i->__promptme=1;
911 return ch;
912}
913
914/* All the callers guarantee this routine will never be
915 * used right after a newline, so prompting is not needed.
916 */
917static int file_peek(struct in_str *i)
918{
919 if (i->p && *i->p) {
920 return *i->p;
921 } else {
922 static char buffer;
923 buffer = fgetc(i->file);
924 i->p = &buffer;
925 debug_printf("b_peek: got a %d\n", *i->p);
926 return *i->p;
927 }
928}
929
930static void setup_file_in_str(struct in_str *i, FILE *f)
931{
932 i->peek = file_peek;
933 i->get = file_get;
934 i->__promptme=1;
935 i->promptmode=1;
936 i->file = f;
937 i->p = NULL;
938}
939
940static void setup_string_in_str(struct in_str *i, const char *s)
941{
942 i->peek = static_peek;
943 i->get = static_get;
944 i->__promptme=1;
945 i->promptmode=1;
946 i->p = s;
947}
948
949static void mark_open(int fd)
950{
951 struct close_me *new = xmalloc(sizeof(struct close_me));
952 new->fd = fd;
953 new->next = close_me_head;
954 close_me_head = new;
955}
956
957static void mark_closed(int fd)
958{
959 struct close_me *tmp;
960 if (close_me_head == NULL || close_me_head->fd != fd)
961 error_msg_and_die("corrupt close_me");
962 tmp = close_me_head;
963 close_me_head = close_me_head->next;
964 free(tmp);
965}
966
967static void close_all()
968{
969 struct close_me *c;
970 for (c=close_me_head; c; c=c->next) {
971 close(c->fd);
972 }
973 close_me_head = NULL;
974}
975
976/* squirrel != NULL means we squirrel away copies of stdin, stdout,
977 * and stderr if they are redirected. */
978static int setup_redirects(struct child_prog *prog, int squirrel[])
979{
980 int openfd, mode;
981 struct redir_struct *redir;
982
983 for (redir=prog->redirects; redir; redir=redir->next) {
984 if (redir->dup == -1) {
985 mode=redir_table[redir->type].mode;
986 openfd = open(redir->word.gl_pathv[0], mode, 0666);
987 if (openfd < 0) {
988 /* this could get lost if stderr has been redirected, but
989 bash and ash both lose it as well (though zsh doesn't!) */
990 fprintf(stderr,"error opening %s: %s\n", redir->word.gl_pathv[0],
991 strerror(errno));
992 return 1;
993 }
994 } else {
995 openfd = redir->dup;
996 }
997
998 if (openfd != redir->fd) {
999 if (squirrel && redir->fd < 3) {
1000 squirrel[redir->fd] = dup(redir->fd);
1001 }
1002 dup2(openfd, redir->fd);
1003 close(openfd);
1004 }
1005 }
1006 return 0;
1007}
1008
1009static void restore_redirects(int squirrel[])
1010{
1011 int i, fd;
1012 for (i=0; i<3; i++) {
1013 fd = squirrel[i];
1014 if (fd != -1) {
1015 /* No error checking. I sure wouldn't know what
1016 * to do with an error if I found one! */
1017 dup2(fd, i);
1018 close(fd);
1019 }
1020 }
1021}
1022
1023/* XXX this definitely needs some more thought, work, and
1024 * cribbing from other shells */
1025static int pipe_wait(struct pipe *pi)
1026{
1027 int rcode=0, i, pid, running, status;
1028 running = pi->num_progs;
1029 while (running) {
1030 pid=waitpid(-1, &status, 0);
1031 if (pid < 0) perror_msg_and_die("waitpid");
1032 for (i=0; i < pi->num_progs; i++) {
1033 if (pi->progs[i].pid == pid) {
1034 if (i==pi->num_progs-1) rcode=WEXITSTATUS(status);
1035 pi->progs[i].pid = 0;
1036 running--;
1037 break;
1038 }
1039 }
1040 }
1041 return rcode;
1042}
1043
1044/* very simple version for testing */
1045static void pseudo_exec(struct child_prog *child)
1046{
1047 int rcode;
1048 struct built_in_command *x;
1049 if (child->argv) {
1050 /*
1051 * Check if the command matches any of the builtins.
1052 * Depending on context, this might be redundant. But it's
1053 * easier to waste a few CPU cycles than it is to figure out
1054 * if this is one of those cases.
1055 */
1056 for (x = bltins; x->cmd; x++) {
1057 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1058 debug_printf("builtin exec %s\n", child->argv[0]);
1059 exit(x->function(child));
1060 }
1061 }
1062 debug_printf("exec of %s\n",child->argv[0]);
1063 execvp(child->argv[0],child->argv);
1064 perror("execvp");
1065 exit(1);
1066 } else if (child->group) {
1067 debug_printf("runtime nesting to group\n");
1068 interactive=0; /* crucial!!!! */
1069 rcode = run_list_real(child->group);
1070 /* OK to leak memory by not calling run_list_test,
1071 * since this process is about to exit */
1072 exit(rcode);
1073 } else {
1074 /* Can happen. See what bash does with ">foo" by itself. */
1075 debug_printf("trying to pseudo_exec null command\n");
1076 exit(EXIT_SUCCESS);
1077 }
1078}
1079
1080/* run_pipe_real() starts all the jobs, but doesn't wait for anything
1081 * to finish. See pipe_wait().
1082 *
1083 * return code is normally -1, when the caller has to wait for children
1084 * to finish to determine the exit status of the pipe. If the pipe
1085 * is a simple builtin command, however, the action is done by the
1086 * time run_pipe_real returns, and the exit code is provided as the
1087 * return value.
1088 *
1089 * The input of the pipe is always stdin, the output is always
1090 * stdout. The outpipe[] mechanism in BusyBox-0.48 lash is bogus,
1091 * because it tries to avoid running the command substitution in
1092 * subshell, when that is in fact necessary. The subshell process
1093 * now has its stdout directed to the input of the appropriate pipe,
1094 * so this routine is noticeably simpler.
1095 */
1096static int run_pipe_real(struct pipe *pi)
1097{
1098 int i;
1099 int nextin, nextout;
1100 int pipefds[2]; /* pipefds[0] is for reading */
1101 struct child_prog *child;
1102 struct built_in_command *x;
1103
1104 nextin = 0;
1105 pi->pgrp = 0;
1106
1107 /* Check if this is a simple builtin (not part of a pipe).
1108 * Builtins within pipes have to fork anyway, and are handled in
1109 * pseudo_exec. "echo foo | read bar" doesn't work on bash, either.
1110 */
1111 if (pi->num_progs == 1 && pi->progs[0].argv != NULL) {
1112 child = & (pi->progs[0]);
1113 if (child->group && ! child->subshell) {
1114 int squirrel[] = {-1, -1, -1};
1115 int rcode;
1116 debug_printf("non-subshell grouping\n");
1117 setup_redirects(child, squirrel);
1118 /* XXX could we merge code with following builtin case,
1119 * by creating a pseudo builtin that calls run_list_real? */
1120 rcode = run_list_real(child->group);
1121 restore_redirects(squirrel);
1122 return rcode;
1123 }
1124 for (x = bltins; x->cmd; x++) {
1125 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1126 int squirrel[] = {-1, -1, -1};
1127 int rcode;
1128 debug_printf("builtin inline %s\n", child->argv[0]);
1129 /* XXX setup_redirects acts on file descriptors, not FILEs.
1130 * This is perfect for work that comes after exec().
1131 * Is it really safe for inline use? Experimentally,
1132 * things seem to work with glibc. */
1133 setup_redirects(child, squirrel);
1134 rcode = x->function(child);
1135 restore_redirects(squirrel);
1136 return rcode;
1137 }
1138 }
1139 }
1140
1141 for (i = 0; i < pi->num_progs; i++) {
1142 child = & (pi->progs[i]);
1143
1144 /* pipes are inserted between pairs of commands */
1145 if ((i + 1) < pi->num_progs) {
1146 if (pipe(pipefds)<0) perror_msg_and_die("pipe");
1147 nextout = pipefds[1];
1148 } else {
1149 nextout=1;
1150 pipefds[0] = -1;
1151 }
1152
1153 /* XXX test for failed fork()? */
1154 if (!(child->pid = fork())) {
1155 close_all();
1156
1157 if (nextin != 0) {
1158 dup2(nextin, 0);
1159 close(nextin);
1160 }
1161 if (nextout != 1) {
1162 dup2(nextout, 1);
1163 close(nextout);
1164 }
1165 if (pipefds[0]!=-1) {
1166 close(pipefds[0]); /* opposite end of our output pipe */
1167 }
1168
1169 /* Like bash, explicit redirects override pipes,
1170 * and the pipe fd is available for dup'ing. */
1171 setup_redirects(child,NULL);
1172
1173 pseudo_exec(child);
1174 }
1175 if (interactive) {
1176 /* Put our child in the process group whose leader is the
1177 * first process in this pipe. */
1178 if (pi->pgrp==0) {
1179 pi->pgrp = child->pid;
1180 }
1181 /* Don't check for errors. The child may be dead already,
1182 * in which case setpgid returns error code EACCES. */
1183 setpgid(child->pid, pi->pgrp);
1184 }
1185 /* In the non-interactive case, do nothing. Leave the children
1186 * with the process group that they inherited from us. */
1187
1188 if (nextin != 0)
1189 close(nextin);
1190 if (nextout != 1)
1191 close(nextout);
1192
1193 /* If there isn't another process, nextin is garbage
1194 but it doesn't matter */
1195 nextin = pipefds[0];
1196 }
1197 return -1;
1198}
1199
1200static int run_list_real(struct pipe *pi)
1201{
1202 int rcode=0;
1203 int if_code=0, next_if_code=0; /* need double-buffer to handle elif */
1204 reserved_style rmode=RES_NONE;
1205 for (;pi;pi=pi->next) {
1206 rmode = pi->r_mode;
1207 debug_printf("rmode=%d if_code=%d next_if_code=%d\n", rmode, if_code, next_if_code);
1208 if (rmode == RES_THEN || rmode == RES_ELSE) if_code = next_if_code;
1209 if (rmode == RES_THEN && if_code) continue;
1210 if (rmode == RES_ELSE && !if_code) continue;
1211 if (rmode == RES_ELIF && !if_code) continue;
1212 if (pi->num_progs == 0) break;
1213 rcode = run_pipe_real(pi);
1214 if (rcode!=-1) {
1215 /* We only ran a builtin: rcode was set by the return value
1216 * of run_pipe_real(), and we don't need to wait for anything. */
1217 } else if (pi->followup==PIPE_BG) {
1218 /* XXX check bash's behavior with nontrivial pipes */
1219 /* XXX compute jobid */
1220 /* XXX what does bash do with attempts to background builtins? */
1221 printf("[%d] %d\n", pi->jobid, pi->pgrp);
1222 last_bg_pid = pi->pgrp;
1223 rcode = EXIT_SUCCESS;
1224 } else {
1225 if (interactive) {
1226 /* move the new process group into the foreground */
1227 /* suppress messages when run from /linuxrc mag@sysgo.de */
1228 signal(SIGTTIN, SIG_IGN);
1229 signal(SIGTTOU, SIG_IGN);
1230 if (tcsetpgrp(0, pi->pgrp) && errno != ENOTTY)
1231 perror_msg("tcsetpgrp");
1232 rcode = pipe_wait(pi);
1233 if (tcsetpgrp(0, getpid()) && errno != ENOTTY)
1234 perror_msg("tcsetpgrp");
1235 signal(SIGTTIN, SIG_DFL);
1236 signal(SIGTTOU, SIG_DFL);
1237 } else {
1238 rcode = pipe_wait(pi);
1239 }
1240 }
1241 last_return_code=rcode;
1242 if ( rmode == RES_IF || rmode == RES_ELIF )
1243 next_if_code=rcode; /* can be overwritten a number of times */
1244 if ( (rcode==EXIT_SUCCESS && pi->followup==PIPE_OR) ||
1245 (rcode!=EXIT_SUCCESS && pi->followup==PIPE_AND) )
1246 return rcode; /* XXX broken if list is part of if/then/else */
1247 }
1248 return rcode;
1249}
1250
1251/* broken, of course, but OK for testing */
1252static char *indenter(int i)
1253{
1254 static char blanks[]=" ";
1255 return &blanks[sizeof(blanks)-i-1];
1256}
1257
1258/* return code is the exit status of the pipe */
1259static int run_pipe_test(struct pipe *pi, int indent)
1260{
1261 char **p;
1262 struct child_prog *child;
1263 struct redir_struct *r, *rnext;
1264 int a, i, ret_code=0;
1265 char *ind = indenter(indent);
1266 final_printf("%s run pipe: (pid %d)\n",ind,getpid());
1267 for (i=0; i<pi->num_progs; i++) {
1268 child = &pi->progs[i];
1269 final_printf("%s command %d:\n",ind,i);
1270 if (child->argv) {
1271 for (a=0,p=child->argv; *p; a++,p++) {
1272 final_printf("%s argv[%d] = %s\n",ind,a,*p);
1273 }
1274 globfree(&child->glob_result);
1275 child->argv=NULL;
1276 } else if (child->group) {
1277 final_printf("%s begin group (subshell:%d)\n",ind, child->subshell);
1278 ret_code = run_list_test(child->group,indent+3);
1279 final_printf("%s end group\n",ind);
1280 } else {
1281 final_printf("%s (nil)\n",ind);
1282 }
1283 for (r=child->redirects; r; r=rnext) {
1284 final_printf("%s redirect %d%s", ind, r->fd, redir_table[r->type].descrip);
1285 if (r->dup == -1) {
1286 final_printf(" %s\n", *r->word.gl_pathv);
1287 globfree(&r->word);
1288 } else {
1289 final_printf("&%d\n", r->dup);
1290 }
1291 rnext=r->next;
1292 free(r);
1293 }
1294 child->redirects=NULL;
1295 }
1296 free(pi->progs); /* children are an array, they get freed all at once */
1297 pi->progs=NULL;
1298 return ret_code;
1299}
1300
1301static int run_list_test(struct pipe *head, int indent)
1302{
1303 int rcode=0; /* if list has no members */
1304 struct pipe *pi, *next;
1305 char *ind = indenter(indent);
1306 for (pi=head; pi; pi=next) {
1307 if (pi->num_progs == 0) break;
1308 final_printf("%s pipe reserved mode %d\n", ind, pi->r_mode);
1309 rcode = run_pipe_test(pi, indent);
1310 final_printf("%s pipe followup code %d\n", ind, pi->followup);
1311 next=pi->next;
1312 pi->next=NULL;
1313 free(pi);
1314 }
1315 return rcode;
1316}
1317
1318/* Select which version we will use */
1319static int run_list(struct pipe *pi)
1320{
1321 int rcode=0;
1322 if (fake_mode==0) {
1323 rcode = run_list_real(pi);
1324 }
1325 /* run_list_test has the side effect of clearing memory
1326 * In the long run that function can be merged with run_list_real,
1327 * but doing that now would hobble the debugging effort. */
1328 run_list_test(pi,0);
1329 return rcode;
1330}
1331
1332/* The API for glob is arguably broken. This routine pushes a non-matching
1333 * string into the output structure, removing non-backslashed backslashes.
1334 * If someone can prove me wrong, by performing this function within the
1335 * original glob(3) api, feel free to rewrite this routine into oblivion.
1336 * Return code (0 vs. GLOB_NOSPACE) matches glob(3).
1337 * XXX broken if the last character is '\\', check that before calling.
1338 */
1339static int globhack(const char *src, int flags, glob_t *pglob)
1340{
1341 int cnt, pathc;
1342 const char *s;
1343 char *dest;
1344 for (cnt=1, s=src; *s; s++) {
1345 if (*s == '\\') s++;
1346 cnt++;
1347 }
1348 dest = malloc(cnt);
1349 if (!dest) return GLOB_NOSPACE;
1350 if (!(flags & GLOB_APPEND)) {
1351 pglob->gl_pathv=NULL;
1352 pglob->gl_pathc=0;
1353 pglob->gl_offs=0;
1354 pglob->gl_offs=0;
1355 }
1356 pathc = ++pglob->gl_pathc;
1357 pglob->gl_pathv = realloc(pglob->gl_pathv, (pathc+1)*sizeof(*pglob->gl_pathv));
1358 if (pglob->gl_pathv == NULL) return GLOB_NOSPACE;
1359 pglob->gl_pathv[pathc-1]=dest;
1360 pglob->gl_pathv[pathc]=NULL;
1361 for (s=src; *s; s++, dest++) {
1362 if (*s == '\\') s++;
1363 *dest = *s;
1364 }
1365 *dest='\0';
1366 return 0;
1367}
1368
1369/* XXX broken if the last character is '\\', check that before calling */
1370static int glob_needed(const char *s)
1371{
1372 for (; *s; s++) {
1373 if (*s == '\\') s++;
1374 if (strchr("*[?",*s)) return 1;
1375 }
1376 return 0;
1377}
1378
1379#if 0
1380static void globprint(glob_t *pglob)
1381{
1382 int i;
1383 debug_printf("glob_t at %p:\n", pglob);
1384 debug_printf(" gl_pathc=%d gl_pathv=%p gl_offs=%d gl_flags=%d\n",
1385 pglob->gl_pathc, pglob->gl_pathv, pglob->gl_offs, pglob->gl_flags);
1386 for (i=0; i<pglob->gl_pathc; i++)
1387 debug_printf("pglob->gl_pathv[%d] = %p = %s\n", i,
1388 pglob->gl_pathv[i], pglob->gl_pathv[i]);
1389}
1390#endif
1391
1392static int xglob(o_string *dest, int flags, glob_t *pglob)
1393{
1394 int gr;
1395
1396 /* short-circuit for null word */
1397 /* we can code this better when the debug_printf's are gone */
1398 if (dest->length == 0) {
1399 if (dest->nonnull) {
1400 /* bash man page calls this an "explicit" null */
1401 gr = globhack(dest->data, flags, pglob);
1402 debug_printf("globhack returned %d\n",gr);
1403 } else {
1404 return 0;
1405 }
1406 } else if (glob_needed(dest->data)) {
1407 gr = glob(dest->data, flags, NULL, pglob);
1408 debug_printf("glob returned %d\n",gr);
1409 if (gr == GLOB_NOMATCH) {
1410 /* quote removal, or more accurately, backslash removal */
1411 gr = globhack(dest->data, flags, pglob);
1412 debug_printf("globhack returned %d\n",gr);
1413 }
1414 } else {
1415 gr = globhack(dest->data, flags, pglob);
1416 debug_printf("globhack returned %d\n",gr);
1417 }
1418 if (gr == GLOB_NOSPACE) {
1419 fprintf(stderr,"out of memory during glob\n");
1420 exit(1);
1421 }
1422 if (gr != 0) { /* GLOB_ABORTED ? */
1423 fprintf(stderr,"glob(3) error %d\n",gr);
1424 }
1425 /* globprint(glob_target); */
1426 return gr;
1427}
1428
1429/* the src parameter allows us to peek forward to a possible &n syntax
1430 * for file descriptor duplication, e.g., "2>&1".
1431 * Return code is 0 normally, 1 if a syntax error is detected in src.
1432 * Resource errors (in xmalloc) cause the process to exit */
1433static int setup_redirect(struct p_context *ctx, int fd, redir_type style,
1434 struct in_str *input)
1435{
1436 struct child_prog *child=ctx->child;
1437 struct redir_struct *redir = child->redirects;
1438 struct redir_struct *last_redir=NULL;
1439
1440 /* Create a new redir_struct and drop it onto the end of the linked list */
1441 while(redir) {
1442 last_redir=redir;
1443 redir=redir->next;
1444 }
1445 redir = xmalloc(sizeof(struct redir_struct));
1446 redir->next=NULL;
1447 if (last_redir) {
1448 last_redir->next=redir;
1449 } else {
1450 child->redirects=redir;
1451 }
1452
1453 redir->type=style;
1454 redir->fd= (fd==-1) ? redir_table[style].default_fd : fd ;
1455
1456 debug_printf("Redirect type %d%s\n", redir->fd, redir_table[style].descrip);
1457
1458 /* Check for a '2>&1' type redirect */
1459 redir->dup = redirect_dup_num(input);
1460 if (redir->dup == -2) return 1; /* syntax error */
1461 if (redir->dup != -1) {
1462 /* Erik had a check here that the file descriptor in question
1463 * is legit; I postpone that to "run time" */
1464 debug_printf("Duplicating redirect '%d>&%d'\n", redir->fd, redir->dup);
1465 } else {
1466 /* We do _not_ try to open the file that src points to,
1467 * since we need to return and let src be expanded first.
1468 * Set ctx->pending_redirect, so we know what to do at the
1469 * end of the next parsed word.
1470 */
1471 ctx->pending_redirect = redir;
1472 }
1473 return 0;
1474}
1475
1476struct pipe *new_pipe(void) {
1477 struct pipe *pi;
1478 pi = xmalloc(sizeof(struct pipe));
1479 pi->num_progs = 0;
1480 pi->progs = NULL;
1481 pi->next = NULL;
1482 pi->followup = 0; /* invalid */
1483 return pi;
1484}
1485
1486static void initialize_context(struct p_context *ctx)
1487{
1488 ctx->pipe=NULL;
1489 ctx->pending_redirect=NULL;
1490 ctx->child=NULL;
1491 ctx->list_head=new_pipe();
1492 ctx->pipe=ctx->list_head;
1493 ctx->w=RES_NONE;
1494 ctx->stack=NULL;
1495 done_command(ctx); /* creates the memory for working child */
1496}
1497
1498/* normal return is 0
1499 * if a reserved word is found, and processed, return 1
1500 * should handle if, then, elif, else, fi, for, while, until, do, done.
1501 * case, function, and select are obnoxious, save those for later.
1502 */
1503int reserved_word(o_string *dest, struct p_context *ctx)
1504{
1505 struct reserved_combo {
1506 char *literal;
1507 int code;
1508 long flag;
1509 };
1510 /* Mostly a list of accepted follow-up reserved words.
1511 * FLAG_END means we are done with the sequence, and are ready
1512 * to turn the compound list into a command.
1513 * FLAG_START means the word must start a new compound list.
1514 */
1515 static struct reserved_combo reserved_list[] = {
1516 { "if", RES_IF, FLAG_THEN | FLAG_START },
1517 { "then", RES_THEN, FLAG_ELIF | FLAG_ELSE | FLAG_FI },
1518 { "elif", RES_ELIF, FLAG_THEN },
1519 { "else", RES_ELSE, FLAG_FI },
1520 { "fi", RES_FI, FLAG_END },
1521 { "for", RES_FOR, FLAG_DO | FLAG_START },
1522 { "while", RES_WHILE, FLAG_DO | FLAG_START },
1523 { "until", RES_UNTIL, FLAG_DO | FLAG_START },
1524 { "do", RES_DO, FLAG_DONE },
1525 { "done", RES_DONE, FLAG_END }
1526 };
1527 struct reserved_combo *r;
1528 for (r=reserved_list;
1529#define NRES sizeof(reserved_list)/sizeof(struct reserved_combo)
1530 r<reserved_list+NRES; r++) {
1531 if (strcmp(dest->data, r->literal) == 0) {
1532 debug_printf("found reserved word %s, code %d\n",r->literal,r->code);
1533 if (r->flag & FLAG_START) {
1534 struct p_context *new = xmalloc(sizeof(struct p_context));
1535 debug_printf("push stack\n");
1536 *new = *ctx; /* physical copy */
1537 initialize_context(ctx);
1538 ctx->stack=new;
1539 } else if ( ctx->w == RES_NONE || ! (ctx->old_flag & (1<<r->code))) {
1540 syntax(); /* XXX how do we get out? */
1541 }
1542 ctx->w=r->code;
1543 ctx->old_flag = r->flag;
1544 if (ctx->old_flag & FLAG_END) {
1545 struct p_context *old;
1546 debug_printf("pop stack\n");
1547 old = ctx->stack;
1548 old->child->group = ctx->list_head;
1549 *ctx = *old; /* physical copy */
1550 free(old);
1551 ctx->w=RES_NONE;
1552 }
1553 b_reset (dest);
1554 return 1;
1555 }
1556 }
1557 return 0;
1558}
1559
1560/* normal return is 0.
1561 * Syntax or xglob errors return 1. */
1562static int done_word(o_string *dest, struct p_context *ctx)
1563{
1564 struct child_prog *child=ctx->child;
1565 glob_t *glob_target;
1566 int gr, flags = 0;
1567
1568 debug_printf("done_word: %s %p\n", dest->data, child);
1569 if (dest->length == 0 && !dest->nonnull) {
1570 debug_printf(" true null, ignored\n");
1571 return 0;
1572 }
1573 if (ctx->pending_redirect) {
1574 glob_target = &ctx->pending_redirect->word;
1575 } else {
1576 if (child->group) {
1577 syntax();
1578 return 1; /* syntax error, groups and arglists don't mix */
1579 }
1580 if (!child->argv) {
1581 debug_printf("checking %s for reserved-ness\n",dest->data);
1582 if (reserved_word(dest,ctx)) return 0;
1583 }
1584 glob_target = &child->glob_result;
1585 if (child->argv) flags |= GLOB_APPEND;
1586 }
1587 gr = xglob(dest, flags, glob_target);
1588 if (gr != 0) return 1;
1589
1590 b_reset(dest);
1591 if (ctx->pending_redirect) {
1592 ctx->pending_redirect=NULL;
1593 if (glob_target->gl_pathc != 1) {
1594 fprintf(stderr, "ambiguous redirect\n");
1595 return 1;
1596 }
1597 } else {
1598 child->argv = glob_target->gl_pathv;
1599 }
1600 return 0;
1601}
1602
1603/* The only possible error here is out of memory, in which case
1604 * xmalloc exits. */
1605static int done_command(struct p_context *ctx)
1606{
1607 /* The child is really already in the pipe structure, so
1608 * advance the pipe counter and make a new, null child.
1609 * Only real trickiness here is that the uncommitted
1610 * child structure, to which ctx->child points, is not
1611 * counted in pi->num_progs. */
1612 struct pipe *pi=ctx->pipe;
1613 struct child_prog *prog=ctx->child;
1614
1615 if (prog && prog->group == NULL
1616 && prog->argv == NULL
1617 && prog->redirects == NULL) {
1618 debug_printf("done_command: skipping null command\n");
1619 return 0;
1620 } else if (prog) {
1621 pi->num_progs++;
1622 debug_printf("done_command: num_progs incremented to %d\n",pi->num_progs);
1623 } else {
1624 debug_printf("done_command: initializing\n");
1625 }
1626 pi->progs = xrealloc(pi->progs, sizeof(*pi->progs) * (pi->num_progs+1));
1627
1628 prog = pi->progs + pi->num_progs;
1629 prog->redirects = NULL;
1630 prog->argv = NULL;
1631 prog->is_stopped = 0;
1632 prog->group = NULL;
1633 prog->glob_result.gl_pathv = NULL;
1634 prog->family = pi;
1635
1636 ctx->child=prog;
1637 /* but ctx->pipe and ctx->list_head remain unchanged */
1638 return 0;
1639}
1640
1641static int done_pipe(struct p_context *ctx, pipe_style type)
1642{
1643 struct pipe *new_p;
1644 done_command(ctx); /* implicit closure of previous command */
1645 debug_printf("done_pipe, type %d\n", type);
1646 ctx->pipe->followup = type;
1647 ctx->pipe->r_mode = ctx->w;
1648 new_p=new_pipe();
1649 ctx->pipe->next = new_p;
1650 ctx->pipe = new_p;
1651 ctx->child = NULL;
1652 done_command(ctx); /* set up new pipe to accept commands */
1653 return 0;
1654}
1655
1656/* peek ahead in the in_str to find out if we have a "&n" construct,
1657 * as in "2>&1", that represents duplicating a file descriptor.
1658 * returns either -2 (syntax error), -1 (no &), or the number found.
1659 */
1660static int redirect_dup_num(struct in_str *input)
1661{
1662 int ch, d=0, ok=0;
1663 ch = b_peek(input);
1664 if (ch != '&') return -1;
1665
1666 b_getch(input); /* get the & */
1667 while (ch=b_peek(input),isdigit(ch)) {
1668 d = d*10+(ch-'0');
1669 ok=1;
1670 b_getch(input);
1671 }
1672 if (ok) return d;
1673
1674 fprintf(stderr, "ambiguous redirect\n");
1675 return -2;
1676}
1677
1678/* If a redirect is immediately preceded by a number, that number is
1679 * supposed to tell which file descriptor to redirect. This routine
1680 * looks for such preceding numbers. In an ideal world this routine
1681 * needs to handle all the following classes of redirects...
1682 * echo 2>foo # redirects fd 2 to file "foo", nothing passed to echo
1683 * echo 49>foo # redirects fd 49 to file "foo", nothing passed to echo
1684 * echo -2>foo # redirects fd 1 to file "foo", "-2" passed to echo
1685 * echo 49x>foo # redirects fd 1 to file "foo", "49x" passed to echo
1686 * A -1 output from this program means no valid number was found, so the
1687 * caller should use the appropriate default for this redirection.
1688 */
1689static int redirect_opt_num(o_string *o)
1690{
1691 int num;
1692
1693 if (o->length==0) return -1;
1694 for(num=0; num<o->length; num++) {
1695 if (!isdigit(*(o->data+num))) {
1696 return -1;
1697 }
1698 }
1699 /* reuse num (and save an int) */
1700 num=atoi(o->data);
1701 b_reset(o);
1702 return num;
1703}
1704
1705FILE *generate_stream_from_list(struct pipe *head)
1706{
1707 FILE *pf;
1708#if 1
1709 int pid, channel[2];
1710 if (pipe(channel)<0) perror_msg_and_die("pipe");
1711 pid=fork();
1712 if (pid<0) {
1713 perror_msg_and_die("fork");
1714 } else if (pid==0) {
1715 close(channel[0]);
1716 if (channel[1] != 1) {
1717 dup2(channel[1],1);
1718 close(channel[1]);
1719 }
1720#if 0
1721#define SURROGATE "surrogate response"
1722 write(1,SURROGATE,sizeof(SURROGATE));
1723 exit(run_list(head));
1724#else
1725 exit(run_list_real(head)); /* leaks memory */
1726#endif
1727 }
1728 debug_printf("forked child %d\n",pid);
1729 close(channel[1]);
1730 pf = fdopen(channel[0],"r");
1731 debug_printf("pipe on FILE *%p\n",pf);
1732#else
1733 run_list_test(head,0);
1734 pf=popen("echo surrogate response","r");
1735 debug_printf("started fake pipe on FILE *%p\n",pf);
1736#endif
1737 return pf;
1738}
1739
1740/* this version hacked for testing purposes */
1741/* return code is exit status of the process that is run. */
1742static int process_command_subs(o_string *dest, struct p_context *ctx, struct in_str *input, int subst_end)
1743{
1744 int retcode;
1745 o_string result=NULL_O_STRING;
1746 struct p_context inner;
1747 FILE *p;
1748 struct in_str pipe_str;
1749 initialize_context(&inner);
1750
1751 /* recursion to generate command */
1752 retcode = parse_stream(&result, &inner, input, subst_end);
1753 if (retcode != 0) return retcode; /* syntax error or EOF */
1754 done_word(&result, &inner);
1755 done_pipe(&inner, PIPE_SEQ);
1756 b_free(&result);
1757
1758 p=generate_stream_from_list(inner.list_head);
1759 if (p==NULL) return 1;
1760 mark_open(fileno(p));
1761 setup_file_in_str(&pipe_str, p);
1762
1763 /* now send results of command back into original context */
1764 retcode = parse_stream(dest, ctx, &pipe_str, '\0');
1765 /* XXX In case of a syntax error, should we try to kill the child?
1766 * That would be tough to do right, so just read until EOF. */
1767 if (retcode == 1) {
1768 while (b_getch(&pipe_str)!=EOF) { /* discard */ };
1769 }
1770
1771 debug_printf("done reading from pipe, pclose()ing\n");
1772 /* This is the step that wait()s for the child. Should be pretty
1773 * safe, since we just read an EOF from its stdout. We could try
1774 * to better, by using wait(), and keeping track of background jobs
1775 * at the same time. That would be a lot of work, and contrary
1776 * to the KISS philosophy of this program. */
1777 mark_closed(fileno(p));
1778 retcode=pclose(p);
1779 debug_printf("pclosed, retcode=%d\n",retcode);
1780 /* XXX this process fails to trim a single trailing newline */
1781 return retcode;
1782}
1783
1784static int parse_group(o_string *dest, struct p_context *ctx,
1785 struct in_str *input, int ch)
1786{
1787 int rcode, endch=0;
1788 struct p_context sub;
1789 struct child_prog *child = ctx->child;
1790 if (child->argv) {
1791 syntax();
1792 return 1; /* syntax error, groups and arglists don't mix */
1793 }
1794 initialize_context(&sub);
1795 switch(ch) {
1796 case '(': endch=')'; child->subshell=1; break;
1797 case '{': endch='}'; break;
1798 default: syntax(); /* really logic error */
1799 }
1800 rcode=parse_stream(dest,&sub,input,endch);
1801 done_word(dest,&sub); /* finish off the final word in the subcontext */
1802 done_pipe(&sub, PIPE_SEQ); /* and the final command there, too */
1803 child->group = sub.list_head;
1804 return rcode;
1805 /* child remains "open", available for possible redirects */
1806}
1807
1808/* basically useful version until someone wants to get fancier,
1809 * see the bash man page under "Parameter Expansion" */
1810static void lookup_param(o_string *dest, struct p_context *ctx, o_string *src)
1811{
1812 const char *p=NULL;
1813 if (src->data) p = getenv(src->data);
1814 if (p) parse_string(dest, ctx, p); /* recursion */
1815 b_free(src);
1816}
1817
1818/* return code: 0 for OK, 1 for syntax error */
1819static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *input)
1820{
1821 int i, advance=0;
1822 o_string alt=NULL_O_STRING;
1823 char sep[]=" ";
1824 int ch = input->peek(input); /* first character after the $ */
1825 debug_printf("handle_dollar: ch=%c\n",ch);
1826 if (isalpha(ch)) {
1827 while(ch=b_peek(input),isalnum(ch) || ch=='_') {
1828 b_getch(input);
1829 b_addchr(&alt,ch);
1830 }
1831 lookup_param(dest, ctx, &alt);
1832 } else if (isdigit(ch)) {
1833 i = ch-'0'; /* XXX is $0 special? */
1834 if (i<global_argc) {
1835 parse_string(dest, ctx, global_argv[i]); /* recursion */
1836 }
1837 advance = 1;
1838 } else switch (ch) {
1839 case '$':
1840 b_adduint(dest,getpid());
1841 advance = 1;
1842 break;
1843 case '!':
1844 if (last_bg_pid > 0) b_adduint(dest, last_bg_pid);
1845 advance = 1;
1846 break;
1847 case '?':
1848 b_adduint(dest,last_return_code);
1849 advance = 1;
1850 break;
1851 case '#':
1852 b_adduint(dest,global_argc ? global_argc-1 : 0);
1853 advance = 1;
1854 break;
1855 case '{':
1856 b_getch(input);
1857 /* XXX maybe someone will try to escape the '}' */
1858 while(ch=b_getch(input),ch!=EOF && ch!='}') {
1859 b_addchr(&alt,ch);
1860 }
1861 if (ch != '}') {
1862 syntax();
1863 return 1;
1864 }
1865 lookup_param(dest, ctx, &alt);
1866 break;
1867 case '(':
1868 process_command_subs(dest, ctx, input, ')');
1869 break;
1870 case '*':
1871 sep[0]=ifs[0];
1872 for (i=1; i<global_argc; i++) {
1873 parse_string(dest, ctx, global_argv[i]);
1874 if (i+1 < global_argc) parse_string(dest, ctx, sep);
1875 }
1876 break;
1877 case '@':
1878 case '-':
1879 case '_':
1880 /* still unhandled, but should be eventually */
1881 fprintf(stderr,"unhandled syntax: $%c\n",ch);
1882 return 1;
1883 break;
1884 default:
1885 b_addqchr(dest,'$',dest->quote);
1886 }
1887 /* Eat the character if the flag was set. If the compiler
1888 * is smart enough, we could substitute "b_getch(input);"
1889 * for all the "advance = 1;" above, and also end up with
1890 * a nice size-optimized program. Hah! That'll be the day.
1891 */
1892 if (advance) b_getch(input);
1893 return 0;
1894}
1895
1896int parse_string(o_string *dest, struct p_context *ctx, const char *src)
1897{
1898 struct in_str foo;
1899 setup_string_in_str(&foo, src);
1900 return parse_stream(dest, ctx, &foo, '\0');
1901}
1902
1903/* return code is 0 for normal exit, 1 for syntax error */
1904int parse_stream(o_string *dest, struct p_context *ctx,
1905 struct in_str *input, int end_trigger)
1906{
1907 unsigned int ch, m;
1908 int redir_fd;
1909 redir_type redir_style;
1910 int next;
1911
1912 /* Only double-quote state is handled in the state variable dest->quote.
1913 * A single-quote triggers a bypass of the main loop until its mate is
1914 * found. When recursing, quote state is passed in via dest->quote. */
1915
1916 debug_printf("parse_stream, end_trigger=%d\n",end_trigger);
1917 while ((ch=b_getch(input))!=EOF) {
1918 m = map[ch];
1919 next = (ch == '\n') ? 0 : b_peek(input);
1920 debug_printf("parse_stream: ch=%c (%d) m=%d quote=%d\n",
1921 ch,ch,m,dest->quote);
1922 if (m==0 || ((m==1 || m==2) && dest->quote)) {
1923 b_addqchr(dest, ch, dest->quote);
1924 } else if (ch == end_trigger && !dest->quote) {
1925 debug_printf("leaving parse_stream\n");
1926 return 0;
1927 } else if (m==2 && !dest->quote) { /* IFS */
1928 done_word(dest, ctx);
1929#if 0
1930 if (ch=='\n') {
1931 /* Yahoo! Time to run with it! */
1932 done_pipe(ctx,PIPE_SEQ);
1933 run_list(ctx->list_head);
1934 initialize_context(ctx);
1935 }
1936#endif
1937 } else switch (ch) {
1938 case '#':
1939 if (dest->length == 0 && !dest->quote) {
1940 while(ch=b_peek(input),ch!=EOF && ch!='\n') { b_getch(input); }
1941 } else {
1942 b_addqchr(dest, ch, dest->quote);
1943 }
1944 break;
1945 case '\\':
1946 if (next == EOF) {
1947 syntax();
1948 return 1;
1949 }
1950 b_addqchr(dest, '\\', dest->quote);
1951 b_addqchr(dest, b_getch(input), dest->quote);
1952 break;
1953 case '$':
1954 if (handle_dollar(dest, ctx, input)!=0) return 1;
1955 break;
1956 case '\'':
1957 dest->nonnull = 1;
1958 while(ch=b_getch(input),ch!=EOF && ch!='\'') {
1959 b_addchr(dest,ch);
1960 }
1961 if (ch==EOF) {
1962 syntax();
1963 return 1;
1964 }
1965 break;
1966 case '"':
1967 dest->nonnull = 1;
1968 dest->quote = !dest->quote;
1969 break;
1970 case '`':
1971 process_command_subs(dest, ctx, input, '`');
1972 break;
1973 case '>':
1974 redir_fd = redirect_opt_num(dest);
1975 done_word(dest, ctx);
1976 redir_style=REDIRECT_OVERWRITE;
1977 if (next == '>') {
1978 redir_style=REDIRECT_APPEND;
1979 b_getch(input);
1980 } else if (next == '(') {
1981 syntax(); /* until we support >(list) Process Substitution */
1982 return 1;
1983 }
1984 setup_redirect(ctx, redir_fd, redir_style, input);
1985 break;
1986 case '<':
1987 redir_fd = redirect_opt_num(dest);
1988 done_word(dest, ctx);
1989 redir_style=REDIRECT_INPUT;
1990 if (next == '<') {
1991 redir_style=REDIRECT_HEREIS;
1992 b_getch(input);
1993 } else if (next == '>') {
1994 redir_style=REDIRECT_IO;
1995 b_getch(input);
1996 } else if (next == '(') {
1997 syntax(); /* until we support <(list) Process Substitution */
1998 return 1;
1999 }
2000 setup_redirect(ctx, redir_fd, redir_style, input);
2001 break;
2002 case ';':
2003 done_word(dest, ctx);
2004 done_pipe(ctx,PIPE_SEQ);
2005 break;
2006 case '&':
2007 done_word(dest, ctx);
2008 if (next=='&') {
2009 b_getch(input);
2010 done_pipe(ctx,PIPE_AND);
2011 } else {
2012 done_pipe(ctx,PIPE_BG);
2013 }
2014 break;
2015 case '|':
2016 done_word(dest, ctx);
2017 if (next=='|') {
2018 b_getch(input);
2019 done_pipe(ctx,PIPE_OR);
2020 } else {
2021 /* we could pick up a file descriptor choice here
2022 * with redirect_opt_num(), but bash doesn't do it.
2023 * "echo foo 2| cat" yields "foo 2". */
2024 done_command(ctx);
2025 }
2026 break;
2027 case '(':
2028 case '{':
2029 if (parse_group(dest, ctx, input, ch)!=0) return 1;
2030 break;
2031 case ')':
2032 case '}':
2033 syntax(); /* Proper use of this character caught by end_trigger */
2034 return 1;
2035 break;
2036 default:
2037 syntax(); /* this is really an internal logic error */
2038 return 1;
2039 }
2040 }
2041 /* complain if quote? No, maybe we just finished a command substitution
2042 * that was quoted. Example:
2043 * $ echo "`cat foo` plus more"
2044 * and we just got the EOF generated by the subshell that ran "cat foo"
2045 * The only real complaint is if we got an EOF when end_trigger != '\0',
2046 * that is, we were really supposed to get end_trigger, and never got
2047 * one before the EOF. Can't use the standard "syntax error" return code,
2048 * so that parse_stream_outer can distinguish the EOF and exit smoothly. */
2049 if (end_trigger != '\0') return -1;
2050 return 0;
2051}
2052
2053void mapset(const unsigned char *set, int code)
2054{
2055 const unsigned char *s;
2056 for (s=set; *s; s++) map[*s] = code;
2057}
2058
2059void update_ifs_map(void)
2060{
2061 /* char *ifs and char map[256] are both globals. */
2062 ifs = getenv("IFS");
2063 if (ifs == NULL) ifs=" \t\n";
2064 /* Precompute a list of 'flow through' behavior so it can be treated
2065 * quickly up front. Computation is necessary because of IFS.
2066 * Special case handling of IFS == " \t\n" is not implemented.
2067 * The map[] array only really needs two bits each, and on most machines
2068 * that would be faster because of the reduced L1 cache footprint.
2069 */
2070 memset(map,0,256); /* most characters flow through always */
2071 mapset("\\$'\"`", 3); /* never flow through */
2072 mapset("<>;&|(){}#", 1); /* flow through if quoted */
2073 mapset(ifs, 2); /* also flow through if quoted */
2074}
2075
2076/* most recursion does not come through here, the exeception is
2077 * from builtin_source() */
2078int parse_stream_outer(struct in_str *inp)
2079{
2080
2081 struct p_context ctx;
2082 o_string temp=NULL_O_STRING;
2083 int rcode;
2084 do {
2085 initialize_context(&ctx);
2086 update_ifs_map();
2087 inp->promptmode=1;
2088 rcode = parse_stream(&temp, &ctx, inp, '\n');
2089 done_word(&temp, &ctx);
2090 done_pipe(&ctx,PIPE_SEQ);
2091 run_list(ctx.list_head);
2092 } while (rcode != -1); /* loop on syntax errors, return on EOF */
2093 return 0;
2094}
2095
2096static int parse_string_outer(const char *s)
2097{
2098 struct in_str input;
2099 setup_string_in_str(&input, s);
2100 return parse_stream_outer(&input);
2101}
2102
2103static int parse_file_outer(FILE *f)
2104{
2105 int rcode;
2106 struct in_str input;
2107 setup_file_in_str(&input, f);
2108 rcode = parse_stream_outer(&input);
2109 return rcode;
2110}
2111
2112int shell_main(int argc, char **argv)
2113{
2114 int opt;
2115 FILE *input;
2116
2117 /* XXX what should these be while sourcing /etc/profile? */
2118 global_argc = argc;
2119 global_argv = argv;
2120
2121 if (argv[0] && argv[0][0] == '-') {
2122 debug_printf("\nsourcing /etc/profile\n");
2123 input = xfopen("/etc/profile", "r");
2124 mark_open(fileno(input));
2125 parse_file_outer(input);
2126 mark_closed(fileno(input));
2127 fclose(input);
2128 }
2129 input=stdin;
2130
2131 /* initialize the cwd -- this is never freed...*/
2132 cwd = xgetcwd(0);
2133#ifdef BB_FEATURE_COMMAND_EDITING
2134 cmdedit_set_initial_prompt();
2135#else
2136 PS1 = NULL;
2137#endif
2138
2139 while ((opt = getopt(argc, argv, "c:xif")) > 0) {
2140 switch (opt) {
2141 case 'c':
2142 {
2143 global_argv = argv+optind;
2144 global_argc = argc-optind;
2145 opt = parse_string_outer(optarg);
2146 exit(opt);
2147 }
2148 break;
2149 case 'i':
2150 interactive++;
2151 break;
2152 case 'f':
2153 fake_mode++;
2154 break;
2155 default:
2156 fprintf(stderr, "Usage: sh [FILE]...\n"
2157 " or: sh -c command [args]...\n\n");
2158 exit(EXIT_FAILURE);
2159 }
2160 }
2161 /* A shell is interactive if the `-i' flag was given, or if all of
2162 * the following conditions are met:
2163 * no -c command
2164 * no arguments remaining or the -s flag given
2165 * standard input is a terminal
2166 * standard output is a terminal
2167 * Refer to Posix.2, the description of the `sh' utility. */
2168 if (argv[optind]==NULL && input==stdin &&
2169 isatty(fileno(stdin)) && isatty(fileno(stdout))) {
2170 interactive++;
2171 }
2172
2173 if (interactive) {
2174 /* Looks like they want an interactive shell */
2175 fprintf(stdout, "\nhush -- the humble shell v0.01 (testing)\n\n");
2176 exit(parse_file_outer(stdin));
2177 }
2178 debug_printf("\ninteractive=%d\n", interactive);
2179
2180 debug_printf("\nrunning script '%s'\n", argv[optind]);
2181 global_argv = argv+optind;
2182 global_argc = argc-optind;
2183 input = xfopen(argv[optind], "r");
2184 opt = parse_file_outer(input);
2185
2186#ifdef BB_FEATURE_CLEAN_UP
2187 fclose(input.file);
2188#endif
2189
2190 return(opt);
2191}
diff --git a/sh.c b/sh.c
deleted file mode 100644
index 1d128355c..000000000
--- a/sh.c
+++ /dev/null
@@ -1,1935 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * lash -- the BusyBox Lame-Ass SHell
4 *
5 * Copyright (C) 1999,2000,2001 by Lineo, inc.
6 * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
7 *
8 * Based in part on ladsh.c by Michael K. Johnson and Erik W. Troan, which is
9 * under the following liberal license: "We have placed this source code in the
10 * public domain. Use it in any project, free or commercial."
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 *
26 */
27
28/* The parsing engine of this program is officially at a dead-end.
29 * Future work in that direction should move to the work posted
30 * at http://doolittle.faludi.com/~larry/parser.html .
31 * A start on the integration of that work with the rest of sh.c
32 * is at http://codepoet.org/sh.c .
33 */
34//
35//This works pretty well now, and is now on by default.
36#define BB_FEATURE_SH_ENVIRONMENT
37//
38//Backtick support has some problems, use at your own risk!
39//#define BB_FEATURE_SH_BACKTICKS
40//
41//If, then, else, etc. support.. This should now behave basically
42//like any other Bourne shell -- sortof...
43#define BB_FEATURE_SH_IF_EXPRESSIONS
44//
45/* This is currently sortof broken, only for the brave... */
46#undef HANDLE_CONTINUATION_CHARS
47//
48/* This would be great -- if wordexp wouldn't strip all quoting
49 * out from the target strings... As is, a parser needs */
50#undef BB_FEATURE_SH_WORDEXP
51//
52//For debugging/development on the shell only...
53//#define DEBUG_SHELL
54
55
56#include <stdio.h>
57#include <stdlib.h>
58#include <ctype.h>
59#include <errno.h>
60#include <fcntl.h>
61#include <signal.h>
62#include <string.h>
63#include <sys/ioctl.h>
64#include <sys/wait.h>
65#include <unistd.h>
66#include <getopt.h>
67#include "busybox.h"
68#include "cmdedit.h"
69
70#ifdef BB_LOCALE_SUPPORT
71#include <locale.h>
72#endif
73
74//#define BB_FEATURE_SH_WORDEXP
75
76#ifdef BB_FEATURE_SH_WORDEXP
77#include <wordexp.h>
78#define expand_t wordexp_t
79#undef BB_FEATURE_SH_BACKTICKS
80#else
81#include <glob.h>
82#define expand_t glob_t
83#endif
84
85
86static const int MAX_READ = 128; /* size of input buffer for `read' builtin */
87#define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
88
89
90enum redir_type { REDIRECT_INPUT, REDIRECT_OVERWRITE,
91 REDIRECT_APPEND
92};
93
94static const unsigned int DEFAULT_CONTEXT=0x1;
95static const unsigned int IF_TRUE_CONTEXT=0x2;
96static const unsigned int IF_FALSE_CONTEXT=0x4;
97static const unsigned int THEN_EXP_CONTEXT=0x8;
98static const unsigned int ELSE_EXP_CONTEXT=0x10;
99
100
101struct jobset {
102 struct job *head; /* head of list of running jobs */
103 struct job *fg; /* current foreground job */
104};
105
106struct redir_struct {
107 enum redir_type type; /* type of redirection */
108 int fd; /* file descriptor being redirected */
109 char *filename; /* file to redirect fd to */
110};
111
112struct child_prog {
113 pid_t pid; /* 0 if exited */
114 char **argv; /* program name and arguments */
115 int num_redirects; /* elements in redirection array */
116 struct redir_struct *redirects; /* I/O redirects */
117 int is_stopped; /* is the program currently running? */
118 struct job *family; /* pointer back to the child's parent job */
119};
120
121struct job {
122 int jobid; /* job number */
123 int num_progs; /* total number of programs in job */
124 int running_progs; /* number of programs running */
125 char *text; /* name of job */
126 char *cmdbuf; /* buffer various argv's point into */
127 pid_t pgrp; /* process group ID for the job */
128 struct child_prog *progs; /* array of programs in job */
129 struct job *next; /* to track background commands */
130 int stopped_progs; /* number of programs alive, but stopped */
131 unsigned int job_context; /* bitmask defining current context */
132 struct jobset *job_list;
133};
134
135struct built_in_command {
136 char *cmd; /* name */
137 char *descr; /* description */
138 int (*function) (struct child_prog *); /* function ptr */
139};
140
141struct close_me {
142 int fd;
143 struct close_me *next;
144};
145
146/* function prototypes for builtins */
147static int builtin_cd(struct child_prog *cmd);
148static int builtin_exec(struct child_prog *cmd);
149static int builtin_exit(struct child_prog *cmd);
150static int builtin_fg_bg(struct child_prog *cmd);
151static int builtin_help(struct child_prog *cmd);
152static int builtin_jobs(struct child_prog *dummy);
153static int builtin_pwd(struct child_prog *dummy);
154static int builtin_export(struct child_prog *cmd);
155static int builtin_source(struct child_prog *cmd);
156static int builtin_unset(struct child_prog *cmd);
157static int builtin_read(struct child_prog *cmd);
158#ifdef BB_FEATURE_SH_IF_EXPRESSIONS
159static int builtin_if(struct child_prog *cmd);
160static int builtin_then(struct child_prog *cmd);
161static int builtin_else(struct child_prog *cmd);
162static int builtin_fi(struct child_prog *cmd);
163/* function prototypes for shell stuff */
164static int run_command_predicate(char *cmd);
165#endif
166
167
168/* function prototypes for shell stuff */
169static void mark_open(int fd);
170static void mark_closed(int fd);
171static void close_all(void);
172static void checkjobs(struct jobset *job_list);
173static int get_command(FILE * source, char *command);
174static int parse_command(char **command_ptr, struct job *job, int *inbg);
175static int run_command(struct job *newjob, int inbg, int outpipe[2]);
176static int pseudo_exec(struct child_prog *cmd) __attribute__ ((noreturn));
177static int busy_loop(FILE * input);
178
179
180/* Table of built-in functions (these are non-forking builtins, meaning they
181 * can change global variables in the parent shell process but they will not
182 * work with pipes and redirects; 'unset foo | whatever' will not work) */
183static struct built_in_command bltins[] = {
184 {"bg", "Resume a job in the background", builtin_fg_bg},
185 {"cd", "Change working directory", builtin_cd},
186 {"exec", "Exec command, replacing this shell with the exec'd process", builtin_exec},
187 {"exit", "Exit from shell()", builtin_exit},
188 {"fg", "Bring job into the foreground", builtin_fg_bg},
189 {"jobs", "Lists the active jobs", builtin_jobs},
190 {"export", "Set environment variable", builtin_export},
191 {"unset", "Unset environment variable", builtin_unset},
192 {"read", "Input environment variable", builtin_read},
193 {".", "Source-in and run commands in a file", builtin_source},
194 /* to do: add ulimit */
195#ifdef BB_FEATURE_SH_IF_EXPRESSIONS
196 {"if", NULL, builtin_if},
197 {"then", NULL, builtin_then},
198 {"else", NULL, builtin_else},
199 {"fi", NULL, builtin_fi},
200#endif
201 {NULL, NULL, NULL}
202};
203
204/* Table of forking built-in functions (things that fork cannot change global
205 * variables in the parent process, such as the current working directory) */
206static struct built_in_command bltins_forking[] = {
207 {"pwd", "Print current directory", builtin_pwd},
208 {"help", "List shell built-in commands", builtin_help},
209 {NULL, NULL, NULL}
210};
211
212
213/* Variables we export */
214unsigned int shell_context; /* Used in cmdedit.c to reset the
215 context when someone hits ^C */
216
217
218/* Globals that are static to this file */
219static char *cwd;
220static char *local_pending_command = NULL;
221static struct jobset job_list = { NULL, NULL };
222static int argc;
223static char **argv;
224static struct close_me *close_me_head;
225#ifdef BB_FEATURE_SH_ENVIRONMENT
226static int last_bg_pid;
227static int last_return_code;
228static int show_x_trace;
229#endif
230#ifdef BB_FEATURE_SH_IF_EXPRESSIONS
231static char syntax_err[]="syntax error near unexpected token";
232#endif
233
234static char *PS1;
235static char *PS2 = "> ";
236
237
238#ifdef DEBUG_SHELL
239static inline void debug_printf(const char *format, ...)
240{
241 va_list args;
242 va_start(args, format);
243 vfprintf(stderr, format, args);
244 va_end(args);
245}
246#else
247static inline void debug_printf(const char *format, ...) { }
248#endif
249
250/*
251 Most builtins need access to the struct child_prog that has
252 their arguments, previously coded as cmd->progs[0]. That coding
253 can exhibit a bug, if the builtin is not the first command in
254 a pipeline: "echo foo | exec sort" will attempt to exec foo.
255
256builtin previous use notes
257------ ----------------- ---------
258cd cmd->progs[0]
259exec cmd->progs[0] squashed bug: didn't look for applets or forking builtins
260exit cmd->progs[0]
261fg_bg cmd->progs[0], job_list->head, job_list->fg
262help 0
263jobs job_list->head
264pwd 0
265export cmd->progs[0]
266source cmd->progs[0]
267unset cmd->progs[0]
268read cmd->progs[0]
269if cmd->job_context, cmd->text
270then cmd->job_context, cmd->text
271else cmd->job_context, cmd->text
272fi cmd->job_context
273
274The use of cmd->text by if/then/else/fi is hopelessly hacky.
275Would it work to increment cmd->progs[0]->argv and recurse,
276somewhat like builtin_exec does?
277
278I added "struct job *family;" to struct child_prog,
279and switched API to builtin_foo(struct child_prog *child);
280So cmd->text becomes child->family->text
281 cmd->job_context becomes child->family->job_context
282 cmd->progs[0] becomes *child
283 job_list becomes child->family->job_list
284 */
285
286/* built-in 'cd <path>' handler */
287static int builtin_cd(struct child_prog *child)
288{
289 char *newdir;
290
291 if (child->argv[1] == NULL)
292 newdir = getenv("HOME");
293 else
294 newdir = child->argv[1];
295 if (chdir(newdir)) {
296 printf("cd: %s: %m\n", newdir);
297 return EXIT_FAILURE;
298 }
299 cwd = xgetcwd(cwd);
300
301 return EXIT_SUCCESS;
302}
303
304/* built-in 'exec' handler */
305static int builtin_exec(struct child_prog *child)
306{
307 if (child->argv[1] == NULL)
308 return EXIT_SUCCESS; /* Really? */
309 child->argv++;
310 close_all();
311 pseudo_exec(child);
312 /* never returns */
313}
314
315/* built-in 'exit' handler */
316static int builtin_exit(struct child_prog *child)
317{
318 if (child->argv[1] == NULL)
319 exit(EXIT_SUCCESS);
320
321 exit (atoi(child->argv[1]));
322}
323
324/* built-in 'fg' and 'bg' handler */
325static int builtin_fg_bg(struct child_prog *child)
326{
327 int i, jobNum;
328 struct job *job=NULL;
329
330 if (!child->argv[1] || child->argv[2]) {
331 error_msg("%s: exactly one argument is expected",
332 child->argv[0]);
333 return EXIT_FAILURE;
334 }
335
336 if (sscanf(child->argv[1], "%%%d", &jobNum) != 1) {
337 error_msg("%s: bad argument '%s'",
338 child->argv[0], child->argv[1]);
339 return EXIT_FAILURE;
340 }
341
342 for (job = child->family->job_list->head; job; job = job->next) {
343 if (job->jobid == jobNum) {
344 break;
345 }
346 }
347
348 if (!job) {
349 error_msg("%s: unknown job %d",
350 child->argv[0], jobNum);
351 return EXIT_FAILURE;
352 }
353
354 if (*child->argv[0] == 'f') {
355 /* Make this job the foreground job */
356 /* suppress messages when run from /linuxrc mag@sysgo.de */
357 if (tcsetpgrp(0, job->pgrp) && errno != ENOTTY)
358 perror_msg("tcsetpgrp");
359 child->family->job_list->fg = job;
360 }
361
362 /* Restart the processes in the job */
363 for (i = 0; i < job->num_progs; i++)
364 job->progs[i].is_stopped = 0;
365
366 kill(-job->pgrp, SIGCONT);
367
368 job->stopped_progs = 0;
369
370 return EXIT_SUCCESS;
371}
372
373/* built-in 'help' handler */
374static int builtin_help(struct child_prog *dummy)
375{
376 struct built_in_command *x;
377
378 printf("\nBuilt-in commands:\n");
379 printf("-------------------\n");
380 for (x = bltins; x->cmd; x++) {
381 if (x->descr==NULL)
382 continue;
383 printf("%s\t%s\n", x->cmd, x->descr);
384 }
385 for (x = bltins_forking; x->cmd; x++) {
386 if (x->descr==NULL)
387 continue;
388 printf("%s\t%s\n", x->cmd, x->descr);
389 }
390 printf("\n\n");
391 return EXIT_SUCCESS;
392}
393
394/* built-in 'jobs' handler */
395static int builtin_jobs(struct child_prog *child)
396{
397 struct job *job;
398 char *status_string;
399
400 for (job = child->family->job_list->head; job; job = job->next) {
401 if (job->running_progs == job->stopped_progs)
402 status_string = "Stopped";
403 else
404 status_string = "Running";
405
406 printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->text);
407 }
408 return EXIT_SUCCESS;
409}
410
411
412/* built-in 'pwd' handler */
413static int builtin_pwd(struct child_prog *dummy)
414{
415 printf( "%s\n", cwd);
416 return EXIT_SUCCESS;
417}
418
419/* built-in 'export VAR=value' handler */
420static int builtin_export(struct child_prog *child)
421{
422 int res;
423 char *v = child->argv[1];
424
425 if (v == NULL) {
426 char **e;
427 for (e = environ; *e; e++) {
428 printf( "%s\n", *e);
429 }
430 return 0;
431 }
432 res = putenv(v);
433 if (res)
434 fprintf(stderr, "export: %m\n");
435#ifndef BB_FEATURE_SH_SIMPLE_PROMPT
436 if (strncmp(v, "PS1=", 4)==0)
437 PS1 = getenv("PS1");
438#endif
439
440#ifdef BB_LOCALE_SUPPORT
441 if(strncmp(v, "LC_ALL=", 7)==0)
442 setlocale(LC_ALL, getenv("LC_ALL"));
443 if(strncmp(v, "LC_CTYPE=", 9)==0)
444 setlocale(LC_CTYPE, getenv("LC_CTYPE"));
445#endif
446
447 return (res);
448}
449
450/* built-in 'read VAR' handler */
451static int builtin_read(struct child_prog *child)
452{
453 int res = 0, len, newlen;
454 char *s;
455 char string[MAX_READ];
456
457 if (child->argv[1]) {
458 /* argument (VAR) given: put "VAR=" into buffer */
459 strcpy(string, child->argv[1]);
460 len = strlen(string);
461 string[len++] = '=';
462 string[len] = '\0';
463 fgets(&string[len], sizeof(string) - len, stdin); /* read string */
464 newlen = strlen(string);
465 if(newlen > len)
466 string[--newlen] = '\0'; /* chomp trailing newline */
467 /*
468 ** string should now contain "VAR=<value>"
469 ** copy it (putenv() won't do that, so we must make sure
470 ** the string resides in a static buffer!)
471 */
472 res = -1;
473 if((s = strdup(string)))
474 res = putenv(s);
475 if (res)
476 fprintf(stderr, "read: %m\n");
477 }
478 else
479 fgets(string, sizeof(string), stdin);
480
481 return (res);
482}
483
484#ifdef BB_FEATURE_SH_IF_EXPRESSIONS
485/* Built-in handler for 'if' commands */
486static int builtin_if(struct child_prog *child)
487{
488 struct job *cmd = child->family;
489 int status;
490 char* charptr1=cmd->text+3; /* skip over the leading 'if ' */
491
492 /* Now run the 'if' command */
493 debug_printf( "job=%p entering builtin_if ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
494 status = run_command_predicate(charptr1);
495 debug_printf( "if test returned ");
496 if (status == 0) {
497 debug_printf( "TRUE\n");
498 cmd->job_context |= IF_TRUE_CONTEXT;
499 } else {
500 debug_printf( "FALSE\n");
501 cmd->job_context |= IF_FALSE_CONTEXT;
502 }
503 debug_printf("job=%p builtin_if set job context to %x\n", cmd, cmd->job_context);
504 shell_context++;
505
506 return status;
507}
508
509/* Built-in handler for 'then' (part of the 'if' command) */
510static int builtin_then(struct child_prog *child)
511{
512 struct job *cmd = child->family;
513 char* charptr1=cmd->text+5; /* skip over the leading 'then ' */
514
515 debug_printf( "job=%p entering builtin_then ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
516 if (! (cmd->job_context & (IF_TRUE_CONTEXT|IF_FALSE_CONTEXT))) {
517 shell_context = 0; /* Reset the shell's context on an error */
518 error_msg("%s `then'", syntax_err);
519 return EXIT_FAILURE;
520 }
521
522 cmd->job_context |= THEN_EXP_CONTEXT;
523 debug_printf("job=%p builtin_then set job context to %x\n", cmd, cmd->job_context);
524
525 /* If the if result was FALSE, skip the 'then' stuff */
526 if (cmd->job_context & IF_FALSE_CONTEXT) {
527 return EXIT_SUCCESS;
528 }
529
530 /* Seems the if result was TRUE, so run the 'then' command */
531 debug_printf( "'then' now running '%s'\n", charptr1);
532
533 return(run_command_predicate(charptr1));
534}
535
536/* Built-in handler for 'else' (part of the 'if' command) */
537static int builtin_else(struct child_prog *child)
538{
539 struct job *cmd = child->family;
540 char* charptr1=cmd->text+5; /* skip over the leading 'else ' */
541
542 debug_printf( "job=%p entering builtin_else ('%s')-- context=%d\n", cmd, charptr1, cmd->job_context);
543
544 if (! (cmd->job_context & THEN_EXP_CONTEXT)) {
545 shell_context = 0; /* Reset the shell's context on an error */
546 error_msg("%s `else'", syntax_err);
547 return EXIT_FAILURE;
548 }
549 /* If the if result was TRUE, skip the 'else' stuff */
550 if (cmd->job_context & IF_TRUE_CONTEXT) {
551 return EXIT_SUCCESS;
552 }
553
554 cmd->job_context |= ELSE_EXP_CONTEXT;
555 debug_printf("job=%p builtin_else set job context to %x\n", cmd, cmd->job_context);
556
557 /* Now run the 'else' command */
558 debug_printf( "'else' now running '%s'\n", charptr1);
559 return(run_command_predicate(charptr1));
560}
561
562/* Built-in handler for 'fi' (part of the 'if' command) */
563static int builtin_fi(struct child_prog *child)
564{
565 struct job *cmd = child->family;
566 debug_printf( "job=%p entering builtin_fi ('%s')-- context=%d\n", cmd, "", cmd->job_context);
567 if (! (cmd->job_context & (IF_TRUE_CONTEXT|IF_FALSE_CONTEXT))) {
568 shell_context = 0; /* Reset the shell's context on an error */
569 error_msg("%s `fi'", syntax_err);
570 return EXIT_FAILURE;
571 }
572 /* Clear out the if and then context bits */
573 cmd->job_context &= ~(IF_TRUE_CONTEXT|IF_FALSE_CONTEXT|THEN_EXP_CONTEXT|ELSE_EXP_CONTEXT);
574 debug_printf("job=%p builtin_fi set job context to %x\n", cmd, cmd->job_context);
575 shell_context--;
576 return EXIT_SUCCESS;
577}
578#endif
579
580/* Built-in '.' handler (read-in and execute commands from file) */
581static int builtin_source(struct child_prog *child)
582{
583 FILE *input;
584 int status;
585 int fd;
586
587 if (child->argv[1] == NULL)
588 return EXIT_FAILURE;
589
590 input = fopen(child->argv[1], "r");
591 if (!input) {
592 printf( "Couldn't open file '%s'\n", child->argv[1]);
593 return EXIT_FAILURE;
594 }
595
596 fd=fileno(input);
597 mark_open(fd);
598 /* Now run the file */
599 status = busy_loop(input);
600 fclose(input);
601 mark_closed(fd);
602 return (status);
603}
604
605/* built-in 'unset VAR' handler */
606static int builtin_unset(struct child_prog *child)
607{
608 if (child->argv[1] == NULL) {
609 printf( "unset: parameter required.\n");
610 return EXIT_FAILURE;
611 }
612 unsetenv(child->argv[1]);
613 return EXIT_SUCCESS;
614}
615
616#ifdef BB_FEATURE_SH_IF_EXPRESSIONS
617/* currently used by if/then/else.
618 *
619 * Reparsing the command line for this purpose is gross,
620 * incorrect, and fundamentally unfixable; in particular,
621 * think about what happens with command substitution.
622 * We really need to pull out the run, wait, return status
623 * functionality out of busy_loop so we can child->argv++
624 * and use that, without going back through parse_command.
625 */
626static int run_command_predicate(char *cmd)
627{
628 local_pending_command = xstrdup(cmd);
629 return( busy_loop(NULL));
630}
631#endif
632
633static void mark_open(int fd)
634{
635 struct close_me *new = xmalloc(sizeof(struct close_me));
636 new->fd = fd;
637 new->next = close_me_head;
638 close_me_head = new;
639}
640
641static void mark_closed(int fd)
642{
643 struct close_me *tmp;
644 if (close_me_head == NULL || close_me_head->fd != fd)
645 error_msg_and_die("corrupt close_me");
646 tmp = close_me_head;
647 close_me_head = close_me_head->next;
648 free(tmp);
649}
650
651static void close_all()
652{
653 struct close_me *c, *tmp;
654 for (c=close_me_head; c; c=tmp) {
655 close(c->fd);
656 tmp=c->next;
657 free(c);
658 }
659 close_me_head = NULL;
660}
661
662
663/* free up all memory from a job */
664static void free_job(struct job *cmd)
665{
666 int i;
667 struct jobset *keep;
668
669 for (i = 0; i < cmd->num_progs; i++) {
670 free(cmd->progs[i].argv);
671 if (cmd->progs[i].redirects)
672 free(cmd->progs[i].redirects);
673 }
674 if (cmd->progs)
675 free(cmd->progs);
676 if (cmd->text)
677 free(cmd->text);
678 if (cmd->cmdbuf)
679 free(cmd->cmdbuf);
680 keep = cmd->job_list;
681 memset(cmd, 0, sizeof(struct job));
682 cmd->job_list = keep;
683}
684
685/* remove a job from a jobset */
686static void remove_job(struct jobset *j_list, struct job *job)
687{
688 struct job *prevjob;
689
690 free_job(job);
691 if (job == j_list->head) {
692 j_list->head = job->next;
693 } else {
694 prevjob = j_list->head;
695 while (prevjob->next != job)
696 prevjob = prevjob->next;
697 prevjob->next = job->next;
698 }
699
700 free(job);
701}
702
703/* Checks to see if any background processes have exited -- if they
704 have, figure out why and see if a job has completed */
705static void checkjobs(struct jobset *j_list)
706{
707 struct job *job;
708 pid_t childpid;
709 int status;
710 int prognum = 0;
711
712 while ((childpid = waitpid(-1, &status, WNOHANG | WUNTRACED)) > 0) {
713 for (job = j_list->head; job; job = job->next) {
714 prognum = 0;
715 while (prognum < job->num_progs &&
716 job->progs[prognum].pid != childpid) prognum++;
717 if (prognum < job->num_progs)
718 break;
719 }
720
721 /* This happens on backticked commands */
722 if(job==NULL)
723 return;
724
725 if (WIFEXITED(status) || WIFSIGNALED(status)) {
726 /* child exited */
727 job->running_progs--;
728 job->progs[prognum].pid = 0;
729
730 if (!job->running_progs) {
731 printf(JOB_STATUS_FORMAT, job->jobid, "Done", job->text);
732 remove_job(j_list, job);
733 }
734 } else {
735 /* child stopped */
736 job->stopped_progs++;
737 job->progs[prognum].is_stopped = 1;
738
739 if (job->stopped_progs == job->num_progs) {
740 printf(JOB_STATUS_FORMAT, job->jobid, "Stopped",
741 job->text);
742 }
743 }
744 }
745
746 if (childpid == -1 && errno != ECHILD)
747 perror_msg("waitpid");
748}
749
750/* squirrel != NULL means we squirrel away copies of stdin, stdout,
751 * and stderr if they are redirected. */
752static int setup_redirects(struct child_prog *prog, int squirrel[])
753{
754 int i;
755 int openfd;
756 int mode = O_RDONLY;
757 struct redir_struct *redir = prog->redirects;
758
759 for (i = 0; i < prog->num_redirects; i++, redir++) {
760 switch (redir->type) {
761 case REDIRECT_INPUT:
762 mode = O_RDONLY;
763 break;
764 case REDIRECT_OVERWRITE:
765 mode = O_WRONLY | O_CREAT | O_TRUNC;
766 break;
767 case REDIRECT_APPEND:
768 mode = O_WRONLY | O_CREAT | O_APPEND;
769 break;
770 }
771
772 openfd = open(redir->filename, mode, 0666);
773 if (openfd < 0) {
774 /* this could get lost if stderr has been redirected, but
775 bash and ash both lose it as well (though zsh doesn't!) */
776 perror_msg("error opening %s", redir->filename);
777 return 1;
778 }
779
780 if (openfd != redir->fd) {
781 if (squirrel && redir->fd < 3) {
782 squirrel[redir->fd] = dup(redir->fd);
783 }
784 dup2(openfd, redir->fd);
785 close(openfd);
786 }
787 }
788
789 return 0;
790}
791
792static void restore_redirects(int squirrel[])
793{
794 int i, fd;
795 for (i=0; i<3; i++) {
796 fd = squirrel[i];
797 if (fd != -1) {
798 /* No error checking. I sure wouldn't know what
799 * to do with an error if I found one! */
800 dup2(fd, i);
801 close(fd);
802 }
803 }
804}
805
806static inline void cmdedit_set_initial_prompt(void)
807{
808#ifdef BB_FEATURE_SH_SIMPLE_PROMPT
809 PS1 = NULL;
810#else
811 PS1 = getenv("PS1");
812 if(PS1==0)
813 PS1 = "\\w \\$ ";
814#endif
815}
816
817static inline void setup_prompt_string(char **prompt_str)
818{
819#ifdef BB_FEATURE_SH_SIMPLE_PROMPT
820 /* Set up the prompt */
821 if (shell_context == 0) {
822 if (PS1)
823 free(PS1);
824 PS1=xmalloc(strlen(cwd)+4);
825 sprintf(PS1, "%s %s", cwd, ( geteuid() != 0 ) ? "$ ":"# ");
826 *prompt_str = PS1;
827 } else {
828 *prompt_str = PS2;
829 }
830#else
831 *prompt_str = (shell_context==0)? PS1 : PS2;
832#endif
833}
834
835static int get_command(FILE * source, char *command)
836{
837 char *prompt_str;
838
839 if (source == NULL) {
840 if (local_pending_command) {
841 /* a command specified (-c option): return it & mark it done */
842 strcpy(command, local_pending_command);
843 free(local_pending_command);
844 local_pending_command = NULL;
845 return 0;
846 }
847 return 1;
848 }
849
850 if (source == stdin) {
851 setup_prompt_string(&prompt_str);
852
853#ifdef BB_FEATURE_COMMAND_EDITING
854 /*
855 ** enable command line editing only while a command line
856 ** is actually being read; otherwise, we'll end up bequeathing
857 ** atexit() handlers and other unwanted stuff to our
858 ** child processes (rob@sysgo.de)
859 */
860 cmdedit_read_input(prompt_str, command);
861 cmdedit_terminate();
862 return 0;
863#else
864 fputs(prompt_str, stdout);
865#endif
866 }
867
868 if (!fgets(command, BUFSIZ - 2, source)) {
869 if (source == stdin)
870 printf("\n");
871 return 1;
872 }
873
874 return 0;
875}
876
877#ifdef BB_FEATURE_SH_ENVIRONMENT
878static char* itoa(register int i)
879{
880 static char a[7]; /* Max 7 ints */
881 register char *b = a + sizeof(a) - 1;
882 int sign = (i < 0);
883
884 if (sign)
885 i = -i;
886 *b = 0;
887 do
888 {
889 *--b = '0' + (i % 10);
890 i /= 10;
891 }
892 while (i);
893 if (sign)
894 *--b = '-';
895 return b;
896}
897#endif
898
899#if defined BB_FEATURE_SH_ENVIRONMENT && ! defined BB_FEATURE_SH_WORDEXP
900char * strsep_space( char *string, int * ix)
901{
902 char *token, *begin;
903
904 begin = string;
905
906 /* Short circuit the trivial case */
907 if ( !string || ! string[*ix])
908 return NULL;
909
910 /* Find the end of the token. */
911 while( string && string[*ix] && !isspace(string[*ix]) ) {
912 (*ix)++;
913 }
914
915 /* Find the end of any whitespace trailing behind
916 * the token and let that be part of the token */
917 while( string && string[*ix] && isspace(string[*ix]) ) {
918 (*ix)++;
919 }
920
921 if (! string && *ix==0) {
922 /* Nothing useful was found */
923 return NULL;
924 }
925
926 token = xmalloc(*ix+1);
927 token[*ix] = '\0';
928 strncpy(token, string, *ix);
929
930 return token;
931}
932#endif
933
934
935static int expand_arguments(char *command)
936{
937#ifdef BB_FEATURE_SH_ENVIRONMENT
938 expand_t expand_result;
939 char *src, *dst, *var;
940 int ix = 0;
941 int i=0, length, total_length=0, retval;
942 const char *out_of_space = "out of space during expansion";
943#endif
944
945 /* get rid of the terminating \n */
946 chomp(command);
947
948 /* Fix up escape sequences to be the Real Thing(tm) */
949 while( command && command[ix]) {
950 if (command[ix] == '\\') {
951 const char *tmp = command+ix+1;
952 command[ix] = process_escape_sequence( &tmp );
953 memmove(command+ix + 1, tmp, strlen(tmp)+1);
954 }
955 ix++;
956 }
957
958#ifdef BB_FEATURE_SH_ENVIRONMENT
959
960
961#ifdef BB_FEATURE_SH_WORDEXP
962 /* This first part uses wordexp() which is a wonderful C lib
963 * function which expands nearly everything. */
964 retval = wordexp (command, &expand_result, WRDE_SHOWERR);
965 if (retval == WRDE_NOSPACE) {
966 /* Mem may have been allocated... */
967 wordfree (&expand_result);
968 error_msg(out_of_space);
969 return FALSE;
970 }
971 if (retval < 0) {
972 /* Some other error. */
973 error_msg("syntax error");
974 return FALSE;
975 }
976
977 if (expand_result.we_wordc > 0) {
978 /* Convert from char** (one word per string) to a simple char*,
979 * but don't overflow command which is BUFSIZ in length */
980 *command = '\0';
981 while (i < expand_result.we_wordc && total_length < BUFSIZ) {
982 length=strlen(expand_result.we_wordv[i])+1;
983 if (BUFSIZ-total_length-length <= 0) {
984 error_msg(out_of_space);
985 return FALSE;
986 }
987 strcat(command+total_length, expand_result.we_wordv[i++]);
988 strcat(command+total_length, " ");
989 total_length+=length;
990 }
991 wordfree (&expand_result);
992 }
993#else
994
995 /* Ok. They don't have a recent glibc and they don't have uClibc. Chances
996 * are about 100% they don't have wordexp(). So instead the best we can do
997 * is use glob and then fixup environment variables and such ourselves.
998 * This is better then nothing, but certainly not perfect */
999
1000 /* It turns out that glob is very stupid. We have to feed it one word at a
1001 * time since it can't cope with a full string. Here we convert command
1002 * (char*) into cmd (char**, one word per string) */
1003 {
1004
1005 int flags = GLOB_NOCHECK
1006#ifdef GLOB_BRACE
1007 | GLOB_BRACE
1008#endif
1009#ifdef GLOB_TILDE
1010 | GLOB_TILDE
1011#endif
1012 ;
1013 char *tmpcmd, *cmd, *cmd_copy;
1014 /* We need a clean copy, so strsep can mess up the copy while
1015 * we write stuff into the original (in a minute) */
1016 cmd = cmd_copy = strdup(command);
1017 *command = '\0';
1018 for (ix = 0, tmpcmd = cmd;
1019 (tmpcmd = strsep_space(cmd, &ix)) != NULL; cmd += ix, ix=0) {
1020 if (*tmpcmd == '\0')
1021 break;
1022 /* we need to trim() the result for glob! */
1023 trim(tmpcmd);
1024 retval = glob(tmpcmd, flags, NULL, &expand_result);
1025 free(tmpcmd); /* Free mem allocated by strsep_space */
1026 if (retval == GLOB_NOSPACE) {
1027 /* Mem may have been allocated... */
1028 globfree (&expand_result);
1029 error_msg(out_of_space);
1030 return FALSE;
1031 } else if (retval != 0) {
1032 /* Some other error. GLOB_NOMATCH shouldn't
1033 * happen because of the GLOB_NOCHECK flag in
1034 * the glob call. */
1035 error_msg("syntax error");
1036 return FALSE;
1037 } else {
1038 /* Convert from char** (one word per string) to a simple char*,
1039 * but don't overflow command which is BUFSIZ in length */
1040 for (i=0; i < expand_result.gl_pathc; i++) {
1041 length=strlen(expand_result.gl_pathv[i]);
1042 if (total_length+length+1 >= BUFSIZ) {
1043 error_msg(out_of_space);
1044 return FALSE;
1045 }
1046 strcat(command+total_length, " ");
1047 total_length+=1;
1048 strcat(command+total_length, expand_result.gl_pathv[i]);
1049 total_length+=length;
1050 }
1051 globfree (&expand_result);
1052 }
1053 }
1054 free(cmd_copy);
1055 trim(command);
1056 }
1057
1058#endif
1059
1060 /* Now do the shell variable substitutions which
1061 * wordexp can't do for us, namely $? and $! */
1062 src = command;
1063 while((dst = strchr(src,'$')) != NULL){
1064 var = NULL;
1065 switch(*(dst+1)) {
1066 case '?':
1067 var = itoa(last_return_code);
1068 break;
1069 case '!':
1070 if (last_bg_pid==-1)
1071 *(var)='\0';
1072 else
1073 var = itoa(last_bg_pid);
1074 break;
1075 /* Everything else like $$, $#, $[0-9], etc should all be
1076 * expanded by wordexp(), so we can in theory skip that stuff
1077 * here, but just to be on the safe side (i.e. since uClibc
1078 * wordexp doesn't do this stuff yet), lets leave it in for
1079 * now. */
1080 case '$':
1081 var = itoa(getpid());
1082 break;
1083 case '#':
1084 var = itoa(argc-1);
1085 break;
1086 case '0':case '1':case '2':case '3':case '4':
1087 case '5':case '6':case '7':case '8':case '9':
1088 {
1089 int ixx=*(dst + 1)-48;
1090 if (ixx >= argc) {
1091 var='\0';
1092 } else {
1093 var = argv[ixx];
1094 }
1095 }
1096 break;
1097
1098 }
1099 if (var) {
1100 /* a single character construction was found, and
1101 * already handled in the case statement */
1102 src=dst+2;
1103 } else {
1104 /* Looks like an environment variable */
1105 char delim_hold;
1106 int num_skip_chars=0;
1107 int dstlen = strlen(dst);
1108 /* Is this a ${foo} type variable? */
1109 if (dstlen >=2 && *(dst+1) == '{') {
1110 src=strchr(dst+1, '}');
1111 num_skip_chars=1;
1112 } else {
1113 src=dst+1;
1114 while(isalnum(*src) || *src=='_') src++;
1115 }
1116 if (src == NULL) {
1117 src = dst+dstlen;
1118 }
1119 delim_hold=*src;
1120 *src='\0'; /* temporary */
1121 var = getenv(dst + 1 + num_skip_chars);
1122 *src=delim_hold;
1123 src += num_skip_chars;
1124 }
1125 if (var == NULL) {
1126 /* Seems we got an un-expandable variable. So delete it. */
1127 var = "";
1128 }
1129 {
1130 int subst_len = strlen(var);
1131 int trail_len = strlen(src);
1132 if (dst+subst_len+trail_len >= command+BUFSIZ) {
1133 error_msg(out_of_space);
1134 return FALSE;
1135 }
1136 /* Move stuff to the end of the string to accommodate
1137 * filling the created gap with the new stuff */
1138 memmove(dst+subst_len, src, trail_len+1);
1139 /* Now copy in the new stuff */
1140 memcpy(dst, var, subst_len);
1141 src = dst+subst_len;
1142 }
1143 }
1144
1145#endif
1146 return TRUE;
1147}
1148
1149/* Return cmd->num_progs as 0 if no command is present (e.g. an empty
1150 line). If a valid command is found, command_ptr is set to point to
1151 the beginning of the next command (if the original command had more
1152 then one job associated with it) or NULL if no more commands are
1153 present. */
1154static int parse_command(char **command_ptr, struct job *job, int *inbg)
1155{
1156 char *command;
1157 char *return_command = NULL;
1158 char *src, *buf, *chptr;
1159 int argc_l = 0;
1160 int done = 0;
1161 int argv_alloced;
1162 int i, saw_quote = 0;
1163 char quote = '\0';
1164 int count;
1165 struct child_prog *prog;
1166
1167 /* skip leading white space */
1168 while (**command_ptr && isspace(**command_ptr))
1169 (*command_ptr)++;
1170
1171 /* this handles empty lines or leading '#' characters */
1172 if (!**command_ptr || (**command_ptr == '#')) {
1173 job->num_progs=0;
1174 return 0;
1175 }
1176
1177 *inbg = 0;
1178 job->num_progs = 1;
1179 job->progs = xmalloc(sizeof(*job->progs));
1180
1181 /* We set the argv elements to point inside of this string. The
1182 memory is freed by free_job(). Allocate twice the original
1183 length in case we need to quote every single character.
1184
1185 Getting clean memory relieves us of the task of NULL
1186 terminating things and makes the rest of this look a bit
1187 cleaner (though it is, admittedly, a tad less efficient) */
1188 job->cmdbuf = command = xcalloc(2*strlen(*command_ptr) + 1, sizeof(char));
1189 job->text = NULL;
1190
1191 prog = job->progs;
1192 prog->num_redirects = 0;
1193 prog->redirects = NULL;
1194 prog->is_stopped = 0;
1195 prog->family = job;
1196
1197 argv_alloced = 5;
1198 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1199 prog->argv[0] = job->cmdbuf;
1200
1201 buf = command;
1202 src = *command_ptr;
1203 while (*src && !done) {
1204 if (quote == *src) {
1205 quote = '\0';
1206 } else if (quote) {
1207 if (*src == '\\') {
1208 src++;
1209 if (!*src) {
1210 error_msg("character expected after \\");
1211 free_job(job);
1212 return 1;
1213 }
1214
1215 /* in shell, "\'" should yield \' */
1216 if (*src != quote) {
1217 *buf++ = '\\';
1218 *buf++ = '\\';
1219 }
1220 } else if (*src == '*' || *src == '?' || *src == '[' ||
1221 *src == ']') *buf++ = '\\';
1222 *buf++ = *src;
1223 } else if (isspace(*src)) {
1224 if (*prog->argv[argc_l] || saw_quote) {
1225 buf++, argc_l++;
1226 /* +1 here leaves room for the NULL which ends argv */
1227 if ((argc_l + 1) == argv_alloced) {
1228 argv_alloced += 5;
1229 prog->argv = xrealloc(prog->argv,
1230 sizeof(*prog->argv) *
1231 argv_alloced);
1232 }
1233 prog->argv[argc_l] = buf;
1234 saw_quote = 0;
1235 }
1236 } else
1237 switch (*src) {
1238 case '"':
1239 case '\'':
1240 quote = *src;
1241 saw_quote = 1;
1242 break;
1243
1244 case '#': /* comment */
1245 if (*(src-1)== '$')
1246 *buf++ = *src;
1247 else
1248 done = 1;
1249 break;
1250
1251 case '>': /* redirects */
1252 case '<':
1253 i = prog->num_redirects++;
1254 prog->redirects = xrealloc(prog->redirects,
1255 sizeof(*prog->redirects) *
1256 (i + 1));
1257
1258 prog->redirects[i].fd = -1;
1259 if (buf != prog->argv[argc_l]) {
1260 /* the stuff before this character may be the file number
1261 being redirected */
1262 prog->redirects[i].fd =
1263 strtol(prog->argv[argc_l], &chptr, 10);
1264
1265 if (*chptr && *prog->argv[argc_l]) {
1266 buf++, argc_l++;
1267 prog->argv[argc_l] = buf;
1268 }
1269 }
1270
1271 if (prog->redirects[i].fd == -1) {
1272 if (*src == '>')
1273 prog->redirects[i].fd = 1;
1274 else
1275 prog->redirects[i].fd = 0;
1276 }
1277
1278 if (*src++ == '>') {
1279 if (*src == '>')
1280 prog->redirects[i].type =
1281 REDIRECT_APPEND, src++;
1282 else
1283 prog->redirects[i].type = REDIRECT_OVERWRITE;
1284 } else {
1285 prog->redirects[i].type = REDIRECT_INPUT;
1286 }
1287
1288 /* This isn't POSIX sh compliant. Oh well. */
1289 chptr = src;
1290 while (isspace(*chptr))
1291 chptr++;
1292
1293 if (!*chptr) {
1294 error_msg("file name expected after %c", *(src-1));
1295 free_job(job);
1296 job->num_progs=0;
1297 return 1;
1298 }
1299
1300 prog->redirects[i].filename = buf;
1301 while (*chptr && !isspace(*chptr))
1302 *buf++ = *chptr++;
1303
1304 src = chptr - 1; /* we src++ later */
1305 prog->argv[argc_l] = ++buf;
1306 break;
1307
1308 case '|': /* pipe */
1309 /* finish this command */
1310 if (*prog->argv[argc_l] || saw_quote)
1311 argc_l++;
1312 if (!argc_l) {
1313 error_msg("empty command in pipe");
1314 free_job(job);
1315 job->num_progs=0;
1316 return 1;
1317 }
1318 prog->argv[argc_l] = NULL;
1319
1320 /* and start the next */
1321 job->num_progs++;
1322 job->progs = xrealloc(job->progs,
1323 sizeof(*job->progs) * job->num_progs);
1324 prog = job->progs + (job->num_progs - 1);
1325 prog->num_redirects = 0;
1326 prog->redirects = NULL;
1327 prog->is_stopped = 0;
1328 prog->family = job;
1329 argc_l = 0;
1330
1331 argv_alloced = 5;
1332 prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced);
1333 prog->argv[0] = ++buf;
1334
1335 src++;
1336 while (*src && isspace(*src))
1337 src++;
1338
1339 if (!*src) {
1340 error_msg("empty command in pipe");
1341 free_job(job);
1342 job->num_progs=0;
1343 return 1;
1344 }
1345 src--; /* we'll ++ it at the end of the loop */
1346
1347 break;
1348
1349 case '&': /* background */
1350 *inbg = 1;
1351 case ';': /* multiple commands */
1352 done = 1;
1353 return_command = *command_ptr + (src - *command_ptr) + 1;
1354 break;
1355
1356#ifdef BB_FEATURE_SH_BACKTICKS
1357 case '`':
1358 /* Exec a backtick-ed command */
1359 /* Besides any previous brokenness, I have not
1360 * updated backtick handling for close_me support.
1361 * I don't know if it needs it or not. -- LRD */
1362 {
1363 char* charptr1=NULL, *charptr2;
1364 char* ptr=NULL;
1365 struct job *newjob;
1366 struct jobset njob_list = { NULL, NULL };
1367 int pipefd[2];
1368 int size;
1369
1370 ptr=strchr(++src, '`');
1371 if (ptr==NULL) {
1372 fprintf(stderr, "Unmatched '`' in command\n");
1373 free_job(job);
1374 return 1;
1375 }
1376
1377 /* Make some space to hold just the backticked command */
1378 charptr1 = charptr2 = xmalloc(1+ptr-src);
1379 memcpy(charptr1, src, ptr-src);
1380 charptr1[ptr-src] = '\0';
1381 newjob = xmalloc(sizeof(struct job));
1382 newjob->job_list = &njob_list;
1383 /* Now parse and run the backticked command */
1384 if (!parse_command(&charptr1, newjob, inbg)
1385 && newjob->num_progs) {
1386 pipe(pipefd);
1387 run_command(newjob, 0, pipefd);
1388 }
1389 checkjobs(job->job_list);
1390 free_job(newjob); /* doesn't actually free newjob,
1391 looks like a memory leak */
1392 free(charptr2);
1393
1394 /* Make a copy of any stuff left over in the command
1395 * line after the second backtick */
1396 charptr2 = xmalloc(strlen(ptr)+1);
1397 memcpy(charptr2, ptr+1, strlen(ptr));
1398
1399
1400 /* Copy the output from the backtick-ed command into the
1401 * command line, making extra room as needed */
1402 --src;
1403 charptr1 = xmalloc(BUFSIZ);
1404 while ( (size=full_read(pipefd[0], charptr1, BUFSIZ-1)) >0) {
1405 int newsize=src - *command_ptr + size + 1 + strlen(charptr2);
1406 if (newsize > BUFSIZ) {
1407 *command_ptr=xrealloc(*command_ptr, newsize);
1408 }
1409 memcpy(src, charptr1, size);
1410 src+=size;
1411 }
1412 free(charptr1);
1413 close(pipefd[0]);
1414 if (*(src-1)=='\n')
1415 --src;
1416
1417 /* Now paste into the *command_ptr all the stuff
1418 * leftover after the second backtick */
1419 memcpy(src, charptr2, strlen(charptr2)+1);
1420 free(charptr2);
1421
1422 /* Now recursively call parse_command to deal with the new
1423 * and improved version of the command line with the backtick
1424 * results expanded in place... */
1425 {
1426 struct jobset *jl=job->job_list;
1427 free_job(job);
1428 job->job_list = jl;
1429 }
1430 return(parse_command(command_ptr, job, inbg));
1431 }
1432 break;
1433#endif // BB_FEATURE_SH_BACKTICKS
1434
1435 case '\\':
1436 src++;
1437 if (!*src) {
1438/* This is currently a little broken... */
1439#ifdef HANDLE_CONTINUATION_CHARS
1440 /* They fed us a continuation char, so continue reading stuff
1441 * on the next line, then tack that onto the end of the current
1442 * command */
1443 char *command;
1444 int newsize;
1445 printf("erik: found a continue char at EOL...\n");
1446 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1447 if (get_command(input, command)) {
1448 error_msg("character expected after \\");
1449 free(command);
1450 free_job(job);
1451 return 1;
1452 }
1453 newsize = strlen(*command_ptr) + strlen(command) + 2;
1454 if (newsize > BUFSIZ) {
1455 printf("erik: doing realloc\n");
1456 *command_ptr=xrealloc(*command_ptr, newsize);
1457 }
1458 printf("erik: A: *command_ptr='%s'\n", *command_ptr);
1459 memcpy(--src, command, strlen(command));
1460 printf("erik: B: *command_ptr='%s'\n", *command_ptr);
1461 free(command);
1462 break;
1463#else
1464 error_msg("character expected after \\");
1465 free_job(job);
1466 return 1;
1467#endif
1468 }
1469 if (*src == '*' || *src == '[' || *src == ']'
1470 || *src == '?') *buf++ = '\\';
1471 /* fallthrough */
1472 default:
1473 *buf++ = *src;
1474 }
1475
1476 src++;
1477 }
1478
1479 if (*prog->argv[argc_l] || saw_quote) {
1480 argc_l++;
1481 }
1482 if (!argc_l) {
1483 free_job(job);
1484 return 0;
1485 }
1486 prog->argv[argc_l] = NULL;
1487
1488 if (!return_command) {
1489 job->text = xmalloc(strlen(*command_ptr) + 1);
1490 strcpy(job->text, *command_ptr);
1491 } else {
1492 /* This leaves any trailing spaces, which is a bit sloppy */
1493 count = return_command - *command_ptr;
1494 job->text = xmalloc(count + 1);
1495 strncpy(job->text, *command_ptr, count);
1496 job->text[count] = '\0';
1497 }
1498
1499 *command_ptr = return_command;
1500
1501 return 0;
1502}
1503
1504/* Run the child_prog, no matter what kind of command it uses.
1505 */
1506static int pseudo_exec(struct child_prog *child)
1507{
1508 struct built_in_command *x;
1509#ifdef BB_FEATURE_SH_STANDALONE_SHELL
1510 char *name;
1511#endif
1512
1513 /* Check if the command matches any of the non-forking builtins.
1514 * Depending on context, this might be redundant. But it's
1515 * easier to waste a few CPU cycles than it is to figure out
1516 * if this is one of those cases.
1517 */
1518 for (x = bltins; x->cmd; x++) {
1519 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1520 exit(x->function(child));
1521 }
1522 }
1523
1524 /* Check if the command matches any of the forking builtins. */
1525 for (x = bltins_forking; x->cmd; x++) {
1526 if (strcmp(child->argv[0], x->cmd) == 0) {
1527 applet_name=x->cmd;
1528 exit (x->function(child));
1529 }
1530 }
1531#ifdef BB_FEATURE_SH_STANDALONE_SHELL
1532 /* Check if the command matches any busybox internal
1533 * commands ("applets") here. Following discussions from
1534 * November 2000 on busybox@opensource.lineo.com, don't use
1535 * get_last_path_component(). This way explicit (with
1536 * slashes) filenames will never be interpreted as an
1537 * applet, just like with builtins. This way the user can
1538 * override an applet with an explicit filename reference.
1539 * The only downside to this change is that an explicit
1540 * /bin/foo invocation will fork and exec /bin/foo, even if
1541 * /bin/foo is a symlink to busybox.
1542 */
1543 name = child->argv[0];
1544
1545#ifdef BB_FEATURE_SH_APPLETS_ALWAYS_WIN
1546 /* If you enable BB_FEATURE_SH_APPLETS_ALWAYS_WIN, then
1547 * if you run /bin/cat, it will use BusyBox cat even if
1548 * /bin/cat exists on the filesystem and is _not_ busybox.
1549 * Some systems want this, others do not. Choose wisely. :-)
1550 */
1551 name = get_last_path_component(name);
1552#endif
1553
1554 {
1555 char** argv_l=child->argv;
1556 int argc_l;
1557 for(argc_l=0;*argv_l!=NULL; argv_l++, argc_l++);
1558 optind = 1;
1559 run_applet_by_name(name, argc_l, child->argv);
1560 }
1561#endif
1562
1563 execvp(child->argv[0], child->argv);
1564 perror_msg_and_die("%s", child->argv[0]);
1565}
1566
1567static void insert_job(struct job *newjob, int inbg)
1568{
1569 struct job *thejob;
1570 struct jobset *j_list=newjob->job_list;
1571
1572 /* find the ID for thejob to use */
1573 newjob->jobid = 1;
1574 for (thejob = j_list->head; thejob; thejob = thejob->next)
1575 if (thejob->jobid >= newjob->jobid)
1576 newjob->jobid = thejob->jobid + 1;
1577
1578 /* add thejob to the list of running jobs */
1579 if (!j_list->head) {
1580 thejob = j_list->head = xmalloc(sizeof(*thejob));
1581 } else {
1582 for (thejob = j_list->head; thejob->next; thejob = thejob->next) /* nothing */;
1583 thejob->next = xmalloc(sizeof(*thejob));
1584 thejob = thejob->next;
1585 }
1586
1587 *thejob = *newjob; /* physically copy the struct job */
1588 thejob->next = NULL;
1589 thejob->running_progs = thejob->num_progs;
1590 thejob->stopped_progs = 0;
1591
1592 if (inbg) {
1593 /* we don't wait for background thejobs to return -- append it
1594 to the list of backgrounded thejobs and leave it alone */
1595 printf("[%d] %d\n", thejob->jobid,
1596 newjob->progs[newjob->num_progs - 1].pid);
1597#ifdef BB_FEATURE_SH_ENVIRONMENT
1598 last_bg_pid=newjob->progs[newjob->num_progs - 1].pid;
1599#endif
1600 } else {
1601 newjob->job_list->fg = thejob;
1602
1603 /* move the new process group into the foreground */
1604 /* suppress messages when run from /linuxrc mag@sysgo.de */
1605 if (tcsetpgrp(0, newjob->pgrp) && errno != ENOTTY)
1606 perror_msg("tcsetpgrp");
1607 }
1608}
1609
1610static int run_command(struct job *newjob, int inbg, int outpipe[2])
1611{
1612 /* struct job *thejob; */
1613 int i;
1614 int nextin, nextout;
1615 int pipefds[2]; /* pipefd[0] is for reading */
1616 struct built_in_command *x;
1617 struct child_prog *child;
1618
1619 nextin = 0, nextout = 1;
1620 for (i = 0; i < newjob->num_progs; i++) {
1621 child = & (newjob->progs[i]);
1622
1623 if ((i + 1) < newjob->num_progs) {
1624 if (pipe(pipefds)<0) perror_msg_and_die("pipe");
1625 nextout = pipefds[1];
1626 } else {
1627 if (outpipe[1]!=-1) {
1628 nextout = outpipe[1];
1629 } else {
1630 nextout = 1;
1631 }
1632 }
1633
1634#ifdef BB_FEATURE_SH_ENVIRONMENT
1635 if (show_x_trace==TRUE) {
1636 int j;
1637 fputc('+', stderr);
1638 for (j = 0; child->argv[j]; j++) {
1639 fputc(' ', stderr);
1640 fputs(child->argv[j], stderr);
1641 }
1642 fputc('\n', stderr);
1643 }
1644#endif
1645
1646 /* Check if the command matches any non-forking builtins,
1647 * but only if this is a simple command.
1648 * Non-forking builtins within pipes have to fork anyway,
1649 * and are handled in pseudo_exec. "echo foo | read bar"
1650 * is doomed to failure, and doesn't work on bash, either.
1651 */
1652 if (newjob->num_progs == 1) {
1653 for (x = bltins; x->cmd; x++) {
1654 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1655 int squirrel[] = {-1, -1, -1};
1656 int rcode;
1657 setup_redirects(child, squirrel);
1658 rcode = x->function(child);
1659 restore_redirects(squirrel);
1660 return rcode;
1661 }
1662 }
1663 }
1664
1665 if (!(child->pid = fork())) {
1666 signal(SIGTTOU, SIG_DFL);
1667
1668 close_all();
1669
1670 if (outpipe[1]!=-1) {
1671 close(outpipe[0]);
1672 }
1673 if (nextin != 0) {
1674 dup2(nextin, 0);
1675 close(nextin);
1676 }
1677
1678 if (nextout != 1) {
1679 dup2(nextout, 1);
1680 dup2(nextout, 2); /* Really? */
1681 close(nextout);
1682 close(pipefds[0]);
1683 }
1684
1685 /* explicit redirects override pipes */
1686 setup_redirects(child,NULL);
1687
1688 pseudo_exec(child);
1689 }
1690 if (outpipe[1]!=-1) {
1691 close(outpipe[1]);
1692 }
1693
1694 /* put our child in the process group whose leader is the
1695 first process in this pipe */
1696 setpgid(child->pid, newjob->progs[0].pid);
1697 if (nextin != 0)
1698 close(nextin);
1699 if (nextout != 1)
1700 close(nextout);
1701
1702 /* If there isn't another process, nextin is garbage
1703 but it doesn't matter */
1704 nextin = pipefds[0];
1705 }
1706
1707 newjob->pgrp = newjob->progs[0].pid;
1708
1709 insert_job(newjob, inbg);
1710
1711 return 0;
1712}
1713
1714static int busy_loop(FILE * input)
1715{
1716 char *command;
1717 char *next_command = NULL;
1718 struct job newjob;
1719 pid_t parent_pgrp;
1720 int i;
1721 int inbg;
1722 int status;
1723 newjob.job_list = &job_list;
1724 newjob.job_context = DEFAULT_CONTEXT;
1725
1726 /* save current owner of TTY so we can restore it on exit */
1727 parent_pgrp = tcgetpgrp(0);
1728
1729 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1730
1731 /* don't pay any attention to this signal; it just confuses
1732 things and isn't really meant for shells anyway */
1733 signal(SIGTTOU, SIG_IGN);
1734
1735 while (1) {
1736 if (!job_list.fg) {
1737 /* no job is in the foreground */
1738
1739 /* see if any background processes have exited */
1740 checkjobs(&job_list);
1741
1742 if (!next_command) {
1743 if (get_command(input, command))
1744 break;
1745 next_command = command;
1746 }
1747
1748 if (expand_arguments(next_command) == FALSE) {
1749 free(command);
1750 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1751 next_command = NULL;
1752 continue;
1753 }
1754
1755 if (!parse_command(&next_command, &newjob, &inbg) &&
1756 newjob.num_progs) {
1757 int pipefds[2] = {-1,-1};
1758 debug_printf( "job=%p fed to run_command by busy_loop()'\n",
1759 &newjob);
1760 run_command(&newjob, inbg, pipefds);
1761 }
1762 else {
1763 free(command);
1764 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1765 next_command = NULL;
1766 }
1767 } else {
1768 /* a job is running in the foreground; wait for it */
1769 i = 0;
1770 while (!job_list.fg->progs[i].pid ||
1771 job_list.fg->progs[i].is_stopped == 1) i++;
1772
1773 if (waitpid(job_list.fg->progs[i].pid, &status, WUNTRACED)<0)
1774 perror_msg_and_die("waitpid(%d)",job_list.fg->progs[i].pid);
1775
1776 if (WIFEXITED(status) || WIFSIGNALED(status)) {
1777 /* the child exited */
1778 job_list.fg->running_progs--;
1779 job_list.fg->progs[i].pid = 0;
1780
1781#ifdef BB_FEATURE_SH_ENVIRONMENT
1782 last_return_code=WEXITSTATUS(status);
1783 debug_printf("'%s' exited -- return code %d\n",
1784 job_list.fg->text, last_return_code);
1785#endif
1786 if (!job_list.fg->running_progs) {
1787 /* child exited */
1788 remove_job(&job_list, job_list.fg);
1789 job_list.fg = NULL;
1790 }
1791 } else {
1792 /* the child was stopped */
1793 job_list.fg->stopped_progs++;
1794 job_list.fg->progs[i].is_stopped = 1;
1795
1796 if (job_list.fg->stopped_progs == job_list.fg->running_progs) {
1797 printf("\n" JOB_STATUS_FORMAT, job_list.fg->jobid,
1798 "Stopped", job_list.fg->text);
1799 job_list.fg = NULL;
1800 }
1801 }
1802
1803 if (!job_list.fg) {
1804 /* move the shell to the foreground */
1805 /* suppress messages when run from /linuxrc mag@sysgo.de */
1806 if (tcsetpgrp(0, getpgrp()) && errno != ENOTTY)
1807 perror_msg("tcsetpgrp");
1808 }
1809 }
1810 }
1811 free(command);
1812
1813 /* return controlling TTY back to parent process group before exiting */
1814 if (tcsetpgrp(0, parent_pgrp))
1815 perror_msg("tcsetpgrp");
1816
1817 /* return exit status if called with "-c" */
1818 if (input == NULL && WIFEXITED(status))
1819 return WEXITSTATUS(status);
1820
1821 return 0;
1822}
1823
1824
1825#ifdef BB_FEATURE_CLEAN_UP
1826void free_memory(void)
1827{
1828 if (cwd) {
1829 free(cwd);
1830 cwd = NULL;
1831 }
1832 if (local_pending_command)
1833 free(local_pending_command);
1834
1835 if (job_list.fg && !job_list.fg->running_progs) {
1836 remove_job(&job_list, job_list.fg);
1837 }
1838}
1839#endif
1840
1841
1842int shell_main(int argc_l, char **argv_l)
1843{
1844 int opt, interactive=FALSE;
1845 FILE *input = stdin;
1846 argc = argc_l;
1847 argv = argv_l;
1848
1849 /* These variables need re-initializing when recursing */
1850 shell_context = 0;
1851 local_pending_command = NULL;
1852 close_me_head = NULL;
1853 job_list.head = NULL;
1854 job_list.fg = NULL;
1855#ifdef BB_FEATURE_SH_ENVIRONMENT
1856 last_bg_pid=1;
1857 last_return_code=1;
1858 show_x_trace=FALSE;
1859#endif
1860
1861 if (argv[0] && argv[0][0] == '-') {
1862 FILE *prof_input;
1863 prof_input = fopen("/etc/profile", "r");
1864 if (!prof_input) {
1865 printf( "Couldn't open file '/etc/profile'\n");
1866 } else {
1867 int tmp_fd = fileno(prof_input);
1868 mark_open(tmp_fd);
1869 /* Now run the file */
1870 busy_loop(prof_input);
1871 fclose(prof_input);
1872 mark_closed(tmp_fd);
1873 }
1874 }
1875
1876 while ((opt = getopt(argc_l, argv_l, "cxi")) > 0) {
1877 switch (opt) {
1878 case 'c':
1879 input = NULL;
1880 if (local_pending_command != 0)
1881 error_msg_and_die("multiple -c arguments");
1882 local_pending_command = xstrdup(argv[optind]);
1883 optind++;
1884 argv = argv+optind;
1885 break;
1886#ifdef BB_FEATURE_SH_ENVIRONMENT
1887 case 'x':
1888 show_x_trace = TRUE;
1889 break;
1890#endif
1891 case 'i':
1892 interactive = TRUE;
1893 break;
1894 default:
1895 show_usage();
1896 }
1897 }
1898 /* A shell is interactive if the `-i' flag was given, or if all of
1899 * the following conditions are met:
1900 * no -c command
1901 * no arguments remaining or the -s flag given
1902 * standard input is a terminal
1903 * standard output is a terminal
1904 * Refer to Posix.2, the description of the `sh' utility. */
1905 if (argv[optind]==NULL && input==stdin &&
1906 isatty(fileno(stdin)) && isatty(fileno(stdout))) {
1907 interactive=TRUE;
1908 }
1909 if (interactive==TRUE) {
1910 //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
1911 /* Looks like they want an interactive shell */
1912 printf( "\n\n" BB_BANNER " Built-in shell (lash)\n");
1913 printf( "Enter 'help' for a list of built-in commands.\n\n");
1914 } else if (local_pending_command==NULL) {
1915 //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
1916 input = xfopen(argv[optind], "r");
1917 mark_open(fileno(input)); /* be lazy, never mark this closed */
1918 }
1919
1920 /* initialize the cwd -- this is never freed...*/
1921 cwd = xgetcwd(0);
1922
1923#ifdef BB_FEATURE_CLEAN_UP
1924 atexit(free_memory);
1925#endif
1926
1927#ifdef BB_FEATURE_COMMAND_EDITING
1928 cmdedit_set_initial_prompt();
1929#else
1930 PS1 = NULL;
1931#endif
1932
1933 return (busy_loop(input));
1934}
1935
diff --git a/shell/hush.c b/shell/hush.c
new file mode 100644
index 000000000..f2a4ea410
--- /dev/null
+++ b/shell/hush.c
@@ -0,0 +1,2191 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * sh.c -- a prototype Bourne shell grammar parser
4 * Intended to follow the original Thompson and Ritchie
5 * "small and simple is beautiful" philosophy, which
6 * incidentally is a good match to today's BusyBox.
7 *
8 * Copyright (C) 2000,2001 Larry Doolittle <larry@doolittle.boa.org>
9 *
10 * Credits:
11 * The parser routines proper are all original material, first
12 * written Dec 2000 and Jan 2001 by Larry Doolittle.
13 * The execution engine, the builtins, and much of the underlying
14 * support has been adapted from busybox-0.49pre's lash,
15 * which is Copyright (C) 2000 by Lineo, Inc., and
16 * written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>.
17 * That, in turn, is based in part on ladsh.c, by Michael K. Johnson and
18 * Erik W. Troan, which they placed in the public domain. I don't know
19 * how much of the Johnson/Troan code has survived the repeated rewrites.
20 * Other credits:
21 * simple_itoa() was lifted from boa-0.93.15
22 * b_addchr() derived from similar w_addchar function in glibc-2.2
23 * setup_redirect(), redirect_opt_num(), and big chunks of main()
24 * and many builtins derived from contributions by Erik Andersen
25 * miscellaneous bugfixes from Matt Kraai
26 *
27 * There are two big (and related) architecture differences between
28 * this parser and the lash parser. One is that this version is
29 * actually designed from the ground up to understand nearly all
30 * of the Bourne grammar. The second, consequential change is that
31 * the parser and input reader have been turned inside out. Now,
32 * the parser is in control, and asks for input as needed. The old
33 * way had the input reader in control, and it asked for parsing to
34 * take place as needed. The new way makes it much easier to properly
35 * handle the recursion implicit in the various substitutions, especially
36 * across continuation lines.
37 *
38 * Bash grammar not implemented: (how many of these were in original sh?)
39 * $@ (those sure look like weird quoting rules)
40 * $_
41 * ! negation operator for pipes
42 * &> and >& redirection of stdout+stderr
43 * Brace Expansion
44 * Tilde Expansion
45 * fancy forms of Parameter Expansion
46 * Arithmetic Expansion
47 * <(list) and >(list) Process Substitution
48 * reserved words: if, then, elif, else, fi, while, until, for,
49 * do, done, case
50 * Here Documents ( << word )
51 * Functions
52 * Major bugs:
53 * job handling woefully incomplete and buggy
54 * reserved word execution woefully incomplete and buggy
55 * incomplete reserved word sequence doesn't request more lines of input
56 * to-do:
57 * port selected bugfixes from post-0.49 busybox lash
58 * finish implementing reserved words
59 * handle children going into background
60 * clean up recognition of null pipes
61 * have builtin_exec set flag to avoid restore_redirects
62 * figure out if "echo foo}" is fixable
63 * check setting of global_argc and global_argv
64 * control-C handling, probably with longjmp
65 * VAR=value prefix for simple commands
66 * follow IFS rules more precisely, including update semantics
67 * write builtin_eval, builtin_ulimit, builtin_umask
68 * figure out what to do with backslash-newline
69 * explain why we use signal instead of sigaction
70 * propagate syntax errors, die on resource errors?
71 * continuation lines, both explicit and implicit - done?
72 * memory leak finding and plugging - done?
73 * more testing, especially quoting rules and redirection
74 * maybe change map[] to use 2-bit entries
75 * (eventually) remove all the printf's
76 * more integration with BusyBox: prompts, cmdedit, applets
77 *
78 * This program is free software; you can redistribute it and/or modify
79 * it under the terms of the GNU General Public License as published by
80 * the Free Software Foundation; either version 2 of the License, or
81 * (at your option) any later version.
82 *
83 * This program is distributed in the hope that it will be useful,
84 * but WITHOUT ANY WARRANTY; without even the implied warranty of
85 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
86 * General Public License for more details.
87 *
88 * You should have received a copy of the GNU General Public License
89 * along with this program; if not, write to the Free Software
90 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
91 */
92#include <ctype.h> /* isalpha, isdigit */
93#include <unistd.h> /* getpid */
94#include <stdlib.h> /* getenv, atoi */
95#include <string.h> /* strchr */
96#include <stdio.h> /* popen etc. */
97#include <glob.h> /* glob, of course */
98#include <stdarg.h> /* va_list */
99#include <errno.h>
100#include <fcntl.h>
101#include <getopt.h> /* should be pretty obvious */
102
103#include <sys/types.h>
104#include <sys/wait.h>
105#include <signal.h>
106
107/* #include <dmalloc.h> */
108/* #define DEBUG_SHELL */
109
110#ifdef BB_VER
111#include "busybox.h"
112#include "cmdedit.h"
113#else
114/* in place of #include "busybox.h"; much of this is indeed
115 * pasted in from the copy of busybox.h in busybox-0.49pre */
116
117#define xrealloc realloc
118#define applet_name "hush"
119#define shell_main main
120
121extern void *xmalloc(size_t size)
122{
123 void *ptr = malloc(size);
124
125 if (!ptr) {
126 fprintf(stderr, "memory_exhausted\n");
127 exit (EXIT_FAILURE);
128 }
129 return ptr;
130}
131
132extern void usage(const char *usage)
133{
134 fprintf(stderr, "Usage: %s\n", usage);
135 exit(EXIT_FAILURE);
136}
137
138static void verror_msg(const char *s, va_list p)
139{
140 fflush(stdout);
141 fprintf(stderr, "%s: ", applet_name);
142 vfprintf(stderr, s, p);
143 fflush(stderr);
144}
145
146extern void error_msg(const char *s, ...)
147{
148 va_list p;
149
150 va_start(p, s);
151 verror_msg(s, p);
152 va_end(p);
153}
154
155extern void error_msg_and_die(const char *s, ...)
156{
157 va_list p;
158
159 va_start(p, s);
160 verror_msg(s, p);
161 va_end(p);
162 exit(EXIT_FAILURE);
163}
164
165static void vperror_msg(const char *s, va_list p)
166{
167 fflush(stdout);
168 fprintf(stderr, "%s: ", applet_name);
169 if (s && *s) {
170 vfprintf(stderr, s, p);
171 fputs(": ", stderr);
172 }
173 fprintf(stderr, "%s\n", strerror(errno));
174 fflush(stderr);
175}
176
177extern void perror_msg(const char *s, ...)
178{
179 va_list p;
180
181 va_start(p, s);
182 vperror_msg(s, p);
183 va_end(p);
184}
185
186extern void perror_msg_and_die(const char *s, ...)
187{
188 va_list p;
189
190 va_start(p, s);
191 vperror_msg(s, p);
192 va_end(p);
193 exit(EXIT_FAILURE);
194}
195
196FILE *xfopen(const char *path, const char *mode)
197{
198 FILE *fp;
199 if ((fp = fopen(path, mode)) == NULL)
200 perror_msg_and_die(path);
201 return fp;
202}
203#endif /* of busybox.h replacement */
204
205typedef enum {
206 REDIRECT_INPUT = 1,
207 REDIRECT_OVERWRITE = 2,
208 REDIRECT_APPEND = 3,
209 REDIRECT_HEREIS = 4,
210 REDIRECT_IO = 5
211} redir_type;
212
213/* The descrip member of this structure is only used to make debugging
214 * output pretty */
215struct {int mode; int default_fd; char *descrip;} redir_table[] = {
216 { 0, 0, "()" },
217 { O_RDONLY, 0, "<" },
218 { O_CREAT|O_TRUNC|O_WRONLY, 1, ">" },
219 { O_CREAT|O_APPEND|O_WRONLY, 1, ">>" },
220 { O_RDONLY, -1, "<<" },
221 { O_RDWR, 1, "<>" }
222};
223
224typedef enum {
225 PIPE_SEQ = 1,
226 PIPE_AND = 2,
227 PIPE_OR = 3,
228 PIPE_BG = 4,
229} pipe_style;
230
231/* might eventually control execution */
232typedef enum {
233 RES_NONE = 0,
234 RES_IF = 1,
235 RES_THEN = 2,
236 RES_ELIF = 3,
237 RES_ELSE = 4,
238 RES_FI = 5,
239 RES_FOR = 6,
240 RES_WHILE = 7,
241 RES_UNTIL = 8,
242 RES_DO = 9,
243 RES_DONE = 10,
244 RES_XXXX = 11
245} reserved_style;
246#define FLAG_END (1<<RES_NONE)
247#define FLAG_IF (1<<RES_IF)
248#define FLAG_THEN (1<<RES_THEN)
249#define FLAG_ELIF (1<<RES_ELIF)
250#define FLAG_ELSE (1<<RES_ELSE)
251#define FLAG_FI (1<<RES_FI)
252#define FLAG_FOR (1<<RES_FOR)
253#define FLAG_WHILE (1<<RES_WHILE)
254#define FLAG_UNTIL (1<<RES_UNTIL)
255#define FLAG_DO (1<<RES_DO)
256#define FLAG_DONE (1<<RES_DONE)
257#define FLAG_START (1<<RES_XXXX)
258
259/* This holds pointers to the various results of parsing */
260struct p_context {
261 struct child_prog *child;
262 struct pipe *list_head;
263 struct pipe *pipe;
264 struct redir_struct *pending_redirect;
265 reserved_style w;
266 int old_flag; /* for figuring out valid reserved words */
267 struct p_context *stack;
268 /* How about quoting status? */
269};
270
271struct redir_struct {
272 redir_type type; /* type of redirection */
273 int fd; /* file descriptor being redirected */
274 int dup; /* -1, or file descriptor being duplicated */
275 struct redir_struct *next; /* pointer to the next redirect in the list */
276 glob_t word; /* *word.gl_pathv is the filename */
277};
278
279struct child_prog {
280 pid_t pid; /* 0 if exited */
281 char **argv; /* program name and arguments */
282 struct pipe *group; /* if non-NULL, first in group or subshell */
283 int subshell; /* flag, non-zero if group must be forked */
284 struct redir_struct *redirects; /* I/O redirections */
285 glob_t glob_result; /* result of parameter globbing */
286 int is_stopped; /* is the program currently running? */
287 struct pipe *family; /* pointer back to the child's parent pipe */
288};
289
290struct pipe {
291 int jobid; /* job number */
292 int num_progs; /* total number of programs in job */
293 int running_progs; /* number of programs running */
294 char *text; /* name of job */
295 char *cmdbuf; /* buffer various argv's point into */
296 pid_t pgrp; /* process group ID for the job */
297 struct child_prog *progs; /* array of commands in pipe */
298 struct pipe *next; /* to track background commands */
299 int stopped_progs; /* number of programs alive, but stopped */
300 int job_context; /* bitmask defining current context */
301 pipe_style followup; /* PIPE_BG, PIPE_SEQ, PIPE_OR, PIPE_AND */
302 reserved_style r_mode; /* supports if, for, while, until */
303 struct jobset *job_list;
304};
305
306struct jobset {
307 struct pipe *head; /* head of list of running jobs */
308 struct pipe *fg; /* current foreground job */
309};
310
311struct close_me {
312 int fd;
313 struct close_me *next;
314};
315
316/* globals, connect us to the outside world
317 * the first three support $?, $#, and $1 */
318char **global_argv;
319unsigned int global_argc;
320unsigned int last_return_code;
321extern char **environ; /* This is in <unistd.h>, but protected with __USE_GNU */
322
323/* Variables we export */
324unsigned int shell_context; /* Used in cmdedit.c to reset the
325 * context when someone hits ^C */
326
327/* "globals" within this file */
328static char *ifs=NULL;
329static char map[256];
330static int fake_mode=0;
331static int interactive=0;
332static struct close_me *close_me_head = NULL;
333static char *cwd;
334static struct jobset job_list = { NULL, NULL };
335static unsigned int last_bg_pid=0;
336static char *PS1;
337static char *PS2 = "> ";
338
339#define B_CHUNK (100)
340#define B_NOSPAC 1
341#define MAX_LINE 256 /* for cwd */
342#define MAX_READ 256 /* for builtin_read */
343
344typedef struct {
345 char *data;
346 int length;
347 int maxlen;
348 int quote;
349 int nonnull;
350} o_string;
351#define NULL_O_STRING {NULL,0,0,0,0}
352/* used for initialization:
353 o_string foo = NULL_O_STRING; */
354
355/* I can almost use ordinary FILE *. Is open_memstream() universally
356 * available? Where is it documented? */
357struct in_str {
358 const char *p;
359 int __promptme;
360 int promptmode;
361 FILE *file;
362 int (*get) (struct in_str *);
363 int (*peek) (struct in_str *);
364};
365#define b_getch(input) ((input)->get(input))
366#define b_peek(input) ((input)->peek(input))
367
368#define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
369
370struct built_in_command {
371 char *cmd; /* name */
372 char *descr; /* description */
373 int (*function) (struct child_prog *); /* function ptr */
374};
375
376/* belongs in busybox.h */
377static inline int max(int a, int b) {
378 return (a>b)?a:b;
379}
380
381/* This should be in utility.c */
382#ifdef DEBUG_SHELL
383static void debug_printf(const char *format, ...)
384{
385 va_list args;
386 va_start(args, format);
387 vfprintf(stderr, format, args);
388 va_end(args);
389}
390#else
391static void debug_printf(const char *format, ...) { }
392#endif
393#define final_printf debug_printf
394
395void __syntax(char *file, int line) {
396 fprintf(stderr,"syntax error %s:%d\n",file,line);
397}
398#define syntax() __syntax(__FILE__, __LINE__)
399
400/* Index of subroutines: */
401/* function prototypes for builtins */
402static int builtin_cd(struct child_prog *child);
403static int builtin_env(struct child_prog *child);
404static int builtin_exec(struct child_prog *child);
405static int builtin_exit(struct child_prog *child);
406static int builtin_export(struct child_prog *child);
407static int builtin_fg_bg(struct child_prog *child);
408static int builtin_help(struct child_prog *child);
409static int builtin_jobs(struct child_prog *child);
410static int builtin_pwd(struct child_prog *child);
411static int builtin_read(struct child_prog *child);
412static int builtin_shift(struct child_prog *child);
413static int builtin_source(struct child_prog *child);
414static int builtin_ulimit(struct child_prog *child);
415static int builtin_umask(struct child_prog *child);
416static int builtin_unset(struct child_prog *child);
417/* o_string manipulation: */
418static int b_check_space(o_string *o, int len);
419static int b_addchr(o_string *o, int ch);
420static void b_reset(o_string *o);
421static int b_addqchr(o_string *o, int ch, int quote);
422static int b_adduint(o_string *o, unsigned int i);
423/* in_str manipulations: */
424static int static_get(struct in_str *i);
425static int static_peek(struct in_str *i);
426static int file_get(struct in_str *i);
427static int file_peek(struct in_str *i);
428static void setup_file_in_str(struct in_str *i, FILE *f);
429static void setup_string_in_str(struct in_str *i, const char *s);
430/* close_me manipulations: */
431static void mark_open(int fd);
432static void mark_closed(int fd);
433static void close_all();
434/* "run" the final data structures: */
435static char *indenter(int i);
436static int run_list_test(struct pipe *head, int indent);
437static int run_pipe_test(struct pipe *pi, int indent);
438/* really run the final data structures: */
439static int setup_redirects(struct child_prog *prog, int squirrel[]);
440static int pipe_wait(struct pipe *pi);
441static int run_list_real(struct pipe *pi);
442static void pseudo_exec(struct child_prog *child) __attribute__ ((noreturn));
443static int run_pipe_real(struct pipe *pi);
444/* extended glob support: */
445static int globhack(const char *src, int flags, glob_t *pglob);
446static int glob_needed(const char *s);
447static int xglob(o_string *dest, int flags, glob_t *pglob);
448/* data structure manipulation: */
449static int setup_redirect(struct p_context *ctx, int fd, redir_type style, struct in_str *input);
450static void initialize_context(struct p_context *ctx);
451static int done_word(o_string *dest, struct p_context *ctx);
452static int done_command(struct p_context *ctx);
453static int done_pipe(struct p_context *ctx, pipe_style type);
454/* primary string parsing: */
455static int redirect_dup_num(struct in_str *input);
456static int redirect_opt_num(o_string *o);
457static int process_command_subs(o_string *dest, struct p_context *ctx, struct in_str *input, int subst_end);
458static int parse_group(o_string *dest, struct p_context *ctx, struct in_str *input, int ch);
459static void lookup_param(o_string *dest, struct p_context *ctx, o_string *src);
460static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *input);
461static int parse_string(o_string *dest, struct p_context *ctx, const char *src);
462static int parse_stream(o_string *dest, struct p_context *ctx, struct in_str *input0, int end_trigger);
463/* setup: */
464static int parse_stream_outer(struct in_str *inp);
465static int parse_string_outer(const char *s);
466static int parse_file_outer(FILE *f);
467
468/* Table of built-in functions. They can be forked or not, depending on
469 * context: within pipes, they fork. As simple commands, they do not.
470 * When used in non-forking context, they can change global variables
471 * in the parent shell process. If forked, of course they can not.
472 * For example, 'unset foo | whatever' will parse and run, but foo will
473 * still be set at the end. */
474static struct built_in_command bltins[] = {
475 {"bg", "Resume a job in the background", builtin_fg_bg},
476 {"cd", "Change working directory", builtin_cd},
477 {"env", "Print all environment variables", builtin_env},
478 {"exec", "Exec command, replacing this shell with the exec'd process", builtin_exec},
479 {"exit", "Exit from shell()", builtin_exit},
480 {"export", "Set environment variable", builtin_export},
481 {"fg", "Bring job into the foreground", builtin_fg_bg},
482 {"jobs", "Lists the active jobs", builtin_jobs},
483 {"pwd", "Print current directory", builtin_pwd},
484 {"read", "Input environment variable", builtin_read},
485 {"shift", "Shift positional parameters", builtin_shift},
486 {"ulimit","Controls resource limits", builtin_ulimit},
487 {"umask","Sets file creation mask", builtin_umask},
488 {"unset", "Unset environment variable", builtin_unset},
489 {".", "Source-in and run commands in a file", builtin_source},
490 {"help", "List shell built-in commands", builtin_help},
491 {NULL, NULL, NULL}
492};
493
494/* built-in 'cd <path>' handler */
495static int builtin_cd(struct child_prog *child)
496{
497 char *newdir;
498 if (child->argv[1] == NULL)
499 newdir = getenv("HOME");
500 else
501 newdir = child->argv[1];
502 if (chdir(newdir)) {
503 printf("cd: %s: %s\n", newdir, strerror(errno));
504 return EXIT_FAILURE;
505 }
506 getcwd(cwd, sizeof(char)*MAX_LINE);
507 return EXIT_SUCCESS;
508}
509
510/* built-in 'env' handler */
511static int builtin_env(struct child_prog *dummy)
512{
513 char **e = environ;
514 if (e == NULL) return EXIT_FAILURE;
515 for (; *e; e++) {
516 puts(*e);
517 }
518 return EXIT_SUCCESS;
519}
520
521/* built-in 'exec' handler */
522static int builtin_exec(struct child_prog *child)
523{
524 if (child->argv[1] == NULL)
525 return EXIT_SUCCESS; /* Really? */
526 child->argv++;
527 pseudo_exec(child);
528 /* never returns */
529}
530
531/* built-in 'exit' handler */
532static int builtin_exit(struct child_prog *child)
533{
534 if (child->argv[1] == NULL)
535 exit(EXIT_SUCCESS);
536 exit (atoi(child->argv[1]));
537}
538
539/* built-in 'export VAR=value' handler */
540static int builtin_export(struct child_prog *child)
541{
542 int res;
543
544 if (child->argv[1] == NULL) {
545 return (builtin_env(child));
546 }
547 res = putenv(child->argv[1]);
548 if (res)
549 fprintf(stderr, "export: %s\n", strerror(errno));
550 return (res);
551}
552
553/* built-in 'fg' and 'bg' handler */
554static int builtin_fg_bg(struct child_prog *child)
555{
556 int i, jobNum;
557 struct pipe *job=NULL;
558
559 if (!child->argv[1] || child->argv[2]) {
560 error_msg("%s: exactly one argument is expected\n",
561 child->argv[0]);
562 return EXIT_FAILURE;
563 }
564
565 if (sscanf(child->argv[1], "%%%d", &jobNum) != 1) {
566 error_msg("%s: bad argument '%s'\n",
567 child->argv[0], child->argv[1]);
568 return EXIT_FAILURE;
569 }
570
571 for (job = child->family->job_list->head; job; job = job->next) {
572 if (job->jobid == jobNum) {
573 break;
574 }
575 }
576
577 if (!job) {
578 error_msg("%s: unknown job %d\n",
579 child->argv[0], jobNum);
580 return EXIT_FAILURE;
581 }
582
583 if (*child->argv[0] == 'f') {
584 /* Make this job the foreground job */
585 /* suppress messages when run from /linuxrc mag@sysgo.de */
586 if (tcsetpgrp(0, job->pgrp) && errno != ENOTTY)
587 perror_msg("tcsetpgrp");
588 child->family->job_list->fg = job;
589 }
590
591 /* Restart the processes in the job */
592 for (i = 0; i < job->num_progs; i++)
593 job->progs[i].is_stopped = 0;
594
595 kill(-job->pgrp, SIGCONT);
596
597 job->stopped_progs = 0;
598 return EXIT_SUCCESS;
599}
600
601/* built-in 'help' handler */
602static int builtin_help(struct child_prog *dummy)
603{
604 struct built_in_command *x;
605
606 printf("\nBuilt-in commands:\n");
607 printf("-------------------\n");
608 for (x = bltins; x->cmd; x++) {
609 if (x->descr==NULL)
610 continue;
611 printf("%s\t%s\n", x->cmd, x->descr);
612 }
613 printf("\n\n");
614 return EXIT_SUCCESS;
615}
616
617/* built-in 'jobs' handler */
618static int builtin_jobs(struct child_prog *child)
619{
620 struct pipe *job;
621 char *status_string;
622
623 for (job = child->family->job_list->head; job; job = job->next) {
624 if (job->running_progs == job->stopped_progs)
625 status_string = "Stopped";
626 else
627 status_string = "Running";
628 printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->text);
629 }
630 return EXIT_SUCCESS;
631}
632
633
634/* built-in 'pwd' handler */
635static int builtin_pwd(struct child_prog *dummy)
636{
637 getcwd(cwd, MAX_LINE);
638 puts(cwd);
639 return EXIT_SUCCESS;
640}
641
642/* built-in 'read VAR' handler */
643static int builtin_read(struct child_prog *child)
644{
645 int res = 0, len, newlen;
646 char *s;
647 char string[MAX_READ];
648
649 if (child->argv[1]) {
650 /* argument (VAR) given: put "VAR=" into buffer */
651 strcpy(string, child->argv[1]);
652 len = strlen(string);
653 string[len++] = '=';
654 string[len] = '\0';
655 /* XXX would it be better to go through in_str? */
656 fgets(&string[len], sizeof(string) - len, stdin); /* read string */
657 newlen = strlen(string);
658 if(newlen > len)
659 string[--newlen] = '\0'; /* chomp trailing newline */
660 /*
661 ** string should now contain "VAR=<value>"
662 ** copy it (putenv() won't do that, so we must make sure
663 ** the string resides in a static buffer!)
664 */
665 res = -1;
666 if((s = strdup(string)))
667 res = putenv(s);
668 if (res)
669 fprintf(stderr, "read: %s\n", strerror(errno));
670 }
671 else
672 fgets(string, sizeof(string), stdin);
673
674 return (res);
675}
676
677/* Built-in 'shift' handler */
678static int builtin_shift(struct child_prog *child)
679{
680 int n=1;
681 if (child->argv[1]) {
682 n=atoi(child->argv[1]);
683 }
684 if (n>=0 && n<global_argc) {
685 /* XXX This probably breaks $0 */
686 global_argc -= n;
687 global_argv += n;
688 return EXIT_SUCCESS;
689 } else {
690 return EXIT_FAILURE;
691 }
692}
693
694/* Built-in '.' handler (read-in and execute commands from file) */
695static int builtin_source(struct child_prog *child)
696{
697 FILE *input;
698 int status;
699
700 if (child->argv[1] == NULL)
701 return EXIT_FAILURE;
702
703 /* XXX search through $PATH is missing */
704 input = fopen(child->argv[1], "r");
705 if (!input) {
706 fprintf(stderr, "Couldn't open file '%s'\n", child->argv[1]);
707 return EXIT_FAILURE;
708 }
709
710 /* Now run the file */
711 /* XXX argv and argc are broken; need to save old global_argv
712 * (pointer only is OK!) on this stack frame,
713 * set global_argv=child->argv+1, recurse, and restore. */
714 mark_open(fileno(input));
715 status = parse_file_outer(input);
716 mark_closed(fileno(input));
717 fclose(input);
718 return (status);
719}
720
721static int builtin_ulimit(struct child_prog *child)
722{
723 printf("builtin_ulimit not written\n");
724 return EXIT_FAILURE;
725}
726
727static int builtin_umask(struct child_prog *child)
728{
729 printf("builtin_umask not written\n");
730 return EXIT_FAILURE;
731}
732
733/* built-in 'unset VAR' handler */
734static int builtin_unset(struct child_prog *child)
735{
736 if (child->argv[1] == NULL) {
737 fprintf(stderr, "unset: parameter required.\n");
738 return EXIT_FAILURE;
739 }
740 unsetenv(child->argv[1]);
741 return EXIT_SUCCESS;
742}
743
744static int b_check_space(o_string *o, int len)
745{
746 /* It would be easy to drop a more restrictive policy
747 * in here, such as setting a maximum string length */
748 if (o->length + len > o->maxlen) {
749 char *old_data = o->data;
750 /* assert (data == NULL || o->maxlen != 0); */
751 o->maxlen += max(2*len, B_CHUNK);
752 o->data = realloc(o->data, 1 + o->maxlen);
753 if (o->data == NULL) {
754 free(old_data);
755 }
756 }
757 return o->data == NULL;
758}
759
760static int b_addchr(o_string *o, int ch)
761{
762 debug_printf("b_addchr: %c %d %p\n", ch, o->length, o);
763 if (b_check_space(o, 1)) return B_NOSPAC;
764 o->data[o->length] = ch;
765 o->length++;
766 o->data[o->length] = '\0';
767 return 0;
768}
769
770static void b_reset(o_string *o)
771{
772 o->length = 0;
773 o->nonnull = 0;
774 if (o->data != NULL) *o->data = '\0';
775}
776
777static void b_free(o_string *o)
778{
779 b_reset(o);
780 if (o->data != NULL) free(o->data);
781 o->data = NULL;
782 o->maxlen = 0;
783}
784
785/* My analysis of quoting semantics tells me that state information
786 * is associated with a destination, not a source.
787 */
788static int b_addqchr(o_string *o, int ch, int quote)
789{
790 if (quote && strchr("*?[\\",ch)) {
791 int rc;
792 rc = b_addchr(o, '\\');
793 if (rc) return rc;
794 }
795 return b_addchr(o, ch);
796}
797
798/* belongs in utility.c */
799char *simple_itoa(unsigned int i)
800{
801 /* 21 digits plus null terminator, good for 64-bit or smaller ints */
802 static char local[22];
803 char *p = &local[21];
804 *p-- = '\0';
805 do {
806 *p-- = '0' + i % 10;
807 i /= 10;
808 } while (i > 0);
809 return p + 1;
810}
811
812static int b_adduint(o_string *o, unsigned int i)
813{
814 int r;
815 char *p = simple_itoa(i);
816 /* no escape checking necessary */
817 do r=b_addchr(o, *p++); while (r==0 && *p);
818 return r;
819}
820
821static int static_get(struct in_str *i)
822{
823 int ch=*i->p++;
824 if (ch=='\0') return EOF;
825 return ch;
826}
827
828static int static_peek(struct in_str *i)
829{
830 return *i->p;
831}
832
833static inline void cmdedit_set_initial_prompt(void)
834{
835#ifdef BB_FEATURE_SH_SIMPLE_PROMPT
836 PS1 = NULL;
837#else
838 PS1 = getenv("PS1");
839 if(PS1==0)
840 PS1 = "\\w \\$ ";
841#endif
842}
843
844static inline void setup_prompt_string(int promptmode, char **prompt_str)
845{
846#ifdef BB_FEATURE_SH_SIMPLE_PROMPT
847 /* Set up the prompt */
848 if (promptmode == 1) {
849 if (PS1)
850 free(PS1);
851 PS1=xmalloc(strlen(cwd)+4);
852 sprintf(PS1, "%s %s", cwd, ( geteuid() != 0 ) ? "$ ":"# ");
853 *prompt_str = PS1;
854 } else {
855 *prompt_str = PS2;
856 }
857#else
858 *prompt_str = (promptmode==0)? PS1 : PS2;
859#endif
860}
861
862static void get_user_input(struct in_str *i)
863{
864 char *prompt_str;
865 static char the_command[MAX_LINE];
866
867 setup_prompt_string(i->promptmode, &prompt_str);
868#ifdef BB_FEATURE_COMMAND_EDITING
869 /*
870 ** enable command line editing only while a command line
871 ** is actually being read; otherwise, we'll end up bequeathing
872 ** atexit() handlers and other unwanted stuff to our
873 ** child processes (rob@sysgo.de)
874 */
875 cmdedit_read_input(prompt_str, the_command);
876 cmdedit_terminate();
877#else
878 fputs(prompt_str, stdout);
879 fflush(stdout);
880 the_command[0]=fgetc(i->file);
881 the_command[1]='\0';
882#endif
883 i->p = the_command;
884}
885
886/* This is the magic location that prints prompts
887 * and gets data back from the user */
888static int file_get(struct in_str *i)
889{
890 int ch;
891
892 ch = 0;
893 /* If there is data waiting, eat it up */
894 if (i->p && *i->p) {
895 ch=*i->p++;
896 } else {
897 /* need to double check i->file because we might be doing something
898 * more complicated by now, like sourcing or substituting. */
899 if (i->__promptme && interactive && i->file == stdin) {
900 get_user_input(i);
901 i->promptmode=2;
902 }
903 i->__promptme = 0;
904
905 if (i->p && *i->p) {
906 ch=*i->p++;
907 }
908 debug_printf("b_getch: got a %d\n", ch);
909 }
910 if (ch == '\n') i->__promptme=1;
911 return ch;
912}
913
914/* All the callers guarantee this routine will never be
915 * used right after a newline, so prompting is not needed.
916 */
917static int file_peek(struct in_str *i)
918{
919 if (i->p && *i->p) {
920 return *i->p;
921 } else {
922 static char buffer;
923 buffer = fgetc(i->file);
924 i->p = &buffer;
925 debug_printf("b_peek: got a %d\n", *i->p);
926 return *i->p;
927 }
928}
929
930static void setup_file_in_str(struct in_str *i, FILE *f)
931{
932 i->peek = file_peek;
933 i->get = file_get;
934 i->__promptme=1;
935 i->promptmode=1;
936 i->file = f;
937 i->p = NULL;
938}
939
940static void setup_string_in_str(struct in_str *i, const char *s)
941{
942 i->peek = static_peek;
943 i->get = static_get;
944 i->__promptme=1;
945 i->promptmode=1;
946 i->p = s;
947}
948
949static void mark_open(int fd)
950{
951 struct close_me *new = xmalloc(sizeof(struct close_me));
952 new->fd = fd;
953 new->next = close_me_head;
954 close_me_head = new;
955}
956
957static void mark_closed(int fd)
958{
959 struct close_me *tmp;
960 if (close_me_head == NULL || close_me_head->fd != fd)
961 error_msg_and_die("corrupt close_me");
962 tmp = close_me_head;
963 close_me_head = close_me_head->next;
964 free(tmp);
965}
966
967static void close_all()
968{
969 struct close_me *c;
970 for (c=close_me_head; c; c=c->next) {
971 close(c->fd);
972 }
973 close_me_head = NULL;
974}
975
976/* squirrel != NULL means we squirrel away copies of stdin, stdout,
977 * and stderr if they are redirected. */
978static int setup_redirects(struct child_prog *prog, int squirrel[])
979{
980 int openfd, mode;
981 struct redir_struct *redir;
982
983 for (redir=prog->redirects; redir; redir=redir->next) {
984 if (redir->dup == -1) {
985 mode=redir_table[redir->type].mode;
986 openfd = open(redir->word.gl_pathv[0], mode, 0666);
987 if (openfd < 0) {
988 /* this could get lost if stderr has been redirected, but
989 bash and ash both lose it as well (though zsh doesn't!) */
990 fprintf(stderr,"error opening %s: %s\n", redir->word.gl_pathv[0],
991 strerror(errno));
992 return 1;
993 }
994 } else {
995 openfd = redir->dup;
996 }
997
998 if (openfd != redir->fd) {
999 if (squirrel && redir->fd < 3) {
1000 squirrel[redir->fd] = dup(redir->fd);
1001 }
1002 dup2(openfd, redir->fd);
1003 close(openfd);
1004 }
1005 }
1006 return 0;
1007}
1008
1009static void restore_redirects(int squirrel[])
1010{
1011 int i, fd;
1012 for (i=0; i<3; i++) {
1013 fd = squirrel[i];
1014 if (fd != -1) {
1015 /* No error checking. I sure wouldn't know what
1016 * to do with an error if I found one! */
1017 dup2(fd, i);
1018 close(fd);
1019 }
1020 }
1021}
1022
1023/* XXX this definitely needs some more thought, work, and
1024 * cribbing from other shells */
1025static int pipe_wait(struct pipe *pi)
1026{
1027 int rcode=0, i, pid, running, status;
1028 running = pi->num_progs;
1029 while (running) {
1030 pid=waitpid(-1, &status, 0);
1031 if (pid < 0) perror_msg_and_die("waitpid");
1032 for (i=0; i < pi->num_progs; i++) {
1033 if (pi->progs[i].pid == pid) {
1034 if (i==pi->num_progs-1) rcode=WEXITSTATUS(status);
1035 pi->progs[i].pid = 0;
1036 running--;
1037 break;
1038 }
1039 }
1040 }
1041 return rcode;
1042}
1043
1044/* very simple version for testing */
1045static void pseudo_exec(struct child_prog *child)
1046{
1047 int rcode;
1048 struct built_in_command *x;
1049 if (child->argv) {
1050 /*
1051 * Check if the command matches any of the builtins.
1052 * Depending on context, this might be redundant. But it's
1053 * easier to waste a few CPU cycles than it is to figure out
1054 * if this is one of those cases.
1055 */
1056 for (x = bltins; x->cmd; x++) {
1057 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1058 debug_printf("builtin exec %s\n", child->argv[0]);
1059 exit(x->function(child));
1060 }
1061 }
1062 debug_printf("exec of %s\n",child->argv[0]);
1063 execvp(child->argv[0],child->argv);
1064 perror("execvp");
1065 exit(1);
1066 } else if (child->group) {
1067 debug_printf("runtime nesting to group\n");
1068 interactive=0; /* crucial!!!! */
1069 rcode = run_list_real(child->group);
1070 /* OK to leak memory by not calling run_list_test,
1071 * since this process is about to exit */
1072 exit(rcode);
1073 } else {
1074 /* Can happen. See what bash does with ">foo" by itself. */
1075 debug_printf("trying to pseudo_exec null command\n");
1076 exit(EXIT_SUCCESS);
1077 }
1078}
1079
1080/* run_pipe_real() starts all the jobs, but doesn't wait for anything
1081 * to finish. See pipe_wait().
1082 *
1083 * return code is normally -1, when the caller has to wait for children
1084 * to finish to determine the exit status of the pipe. If the pipe
1085 * is a simple builtin command, however, the action is done by the
1086 * time run_pipe_real returns, and the exit code is provided as the
1087 * return value.
1088 *
1089 * The input of the pipe is always stdin, the output is always
1090 * stdout. The outpipe[] mechanism in BusyBox-0.48 lash is bogus,
1091 * because it tries to avoid running the command substitution in
1092 * subshell, when that is in fact necessary. The subshell process
1093 * now has its stdout directed to the input of the appropriate pipe,
1094 * so this routine is noticeably simpler.
1095 */
1096static int run_pipe_real(struct pipe *pi)
1097{
1098 int i;
1099 int nextin, nextout;
1100 int pipefds[2]; /* pipefds[0] is for reading */
1101 struct child_prog *child;
1102 struct built_in_command *x;
1103
1104 nextin = 0;
1105 pi->pgrp = 0;
1106
1107 /* Check if this is a simple builtin (not part of a pipe).
1108 * Builtins within pipes have to fork anyway, and are handled in
1109 * pseudo_exec. "echo foo | read bar" doesn't work on bash, either.
1110 */
1111 if (pi->num_progs == 1 && pi->progs[0].argv != NULL) {
1112 child = & (pi->progs[0]);
1113 if (child->group && ! child->subshell) {
1114 int squirrel[] = {-1, -1, -1};
1115 int rcode;
1116 debug_printf("non-subshell grouping\n");
1117 setup_redirects(child, squirrel);
1118 /* XXX could we merge code with following builtin case,
1119 * by creating a pseudo builtin that calls run_list_real? */
1120 rcode = run_list_real(child->group);
1121 restore_redirects(squirrel);
1122 return rcode;
1123 }
1124 for (x = bltins; x->cmd; x++) {
1125 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1126 int squirrel[] = {-1, -1, -1};
1127 int rcode;
1128 debug_printf("builtin inline %s\n", child->argv[0]);
1129 /* XXX setup_redirects acts on file descriptors, not FILEs.
1130 * This is perfect for work that comes after exec().
1131 * Is it really safe for inline use? Experimentally,
1132 * things seem to work with glibc. */
1133 setup_redirects(child, squirrel);
1134 rcode = x->function(child);
1135 restore_redirects(squirrel);
1136 return rcode;
1137 }
1138 }
1139 }
1140
1141 for (i = 0; i < pi->num_progs; i++) {
1142 child = & (pi->progs[i]);
1143
1144 /* pipes are inserted between pairs of commands */
1145 if ((i + 1) < pi->num_progs) {
1146 if (pipe(pipefds)<0) perror_msg_and_die("pipe");
1147 nextout = pipefds[1];
1148 } else {
1149 nextout=1;
1150 pipefds[0] = -1;
1151 }
1152
1153 /* XXX test for failed fork()? */
1154 if (!(child->pid = fork())) {
1155 close_all();
1156
1157 if (nextin != 0) {
1158 dup2(nextin, 0);
1159 close(nextin);
1160 }
1161 if (nextout != 1) {
1162 dup2(nextout, 1);
1163 close(nextout);
1164 }
1165 if (pipefds[0]!=-1) {
1166 close(pipefds[0]); /* opposite end of our output pipe */
1167 }
1168
1169 /* Like bash, explicit redirects override pipes,
1170 * and the pipe fd is available for dup'ing. */
1171 setup_redirects(child,NULL);
1172
1173 pseudo_exec(child);
1174 }
1175 if (interactive) {
1176 /* Put our child in the process group whose leader is the
1177 * first process in this pipe. */
1178 if (pi->pgrp==0) {
1179 pi->pgrp = child->pid;
1180 }
1181 /* Don't check for errors. The child may be dead already,
1182 * in which case setpgid returns error code EACCES. */
1183 setpgid(child->pid, pi->pgrp);
1184 }
1185 /* In the non-interactive case, do nothing. Leave the children
1186 * with the process group that they inherited from us. */
1187
1188 if (nextin != 0)
1189 close(nextin);
1190 if (nextout != 1)
1191 close(nextout);
1192
1193 /* If there isn't another process, nextin is garbage
1194 but it doesn't matter */
1195 nextin = pipefds[0];
1196 }
1197 return -1;
1198}
1199
1200static int run_list_real(struct pipe *pi)
1201{
1202 int rcode=0;
1203 int if_code=0, next_if_code=0; /* need double-buffer to handle elif */
1204 reserved_style rmode=RES_NONE;
1205 for (;pi;pi=pi->next) {
1206 rmode = pi->r_mode;
1207 debug_printf("rmode=%d if_code=%d next_if_code=%d\n", rmode, if_code, next_if_code);
1208 if (rmode == RES_THEN || rmode == RES_ELSE) if_code = next_if_code;
1209 if (rmode == RES_THEN && if_code) continue;
1210 if (rmode == RES_ELSE && !if_code) continue;
1211 if (rmode == RES_ELIF && !if_code) continue;
1212 if (pi->num_progs == 0) break;
1213 rcode = run_pipe_real(pi);
1214 if (rcode!=-1) {
1215 /* We only ran a builtin: rcode was set by the return value
1216 * of run_pipe_real(), and we don't need to wait for anything. */
1217 } else if (pi->followup==PIPE_BG) {
1218 /* XXX check bash's behavior with nontrivial pipes */
1219 /* XXX compute jobid */
1220 /* XXX what does bash do with attempts to background builtins? */
1221 printf("[%d] %d\n", pi->jobid, pi->pgrp);
1222 last_bg_pid = pi->pgrp;
1223 rcode = EXIT_SUCCESS;
1224 } else {
1225 if (interactive) {
1226 /* move the new process group into the foreground */
1227 /* suppress messages when run from /linuxrc mag@sysgo.de */
1228 signal(SIGTTIN, SIG_IGN);
1229 signal(SIGTTOU, SIG_IGN);
1230 if (tcsetpgrp(0, pi->pgrp) && errno != ENOTTY)
1231 perror_msg("tcsetpgrp");
1232 rcode = pipe_wait(pi);
1233 if (tcsetpgrp(0, getpid()) && errno != ENOTTY)
1234 perror_msg("tcsetpgrp");
1235 signal(SIGTTIN, SIG_DFL);
1236 signal(SIGTTOU, SIG_DFL);
1237 } else {
1238 rcode = pipe_wait(pi);
1239 }
1240 }
1241 last_return_code=rcode;
1242 if ( rmode == RES_IF || rmode == RES_ELIF )
1243 next_if_code=rcode; /* can be overwritten a number of times */
1244 if ( (rcode==EXIT_SUCCESS && pi->followup==PIPE_OR) ||
1245 (rcode!=EXIT_SUCCESS && pi->followup==PIPE_AND) )
1246 return rcode; /* XXX broken if list is part of if/then/else */
1247 }
1248 return rcode;
1249}
1250
1251/* broken, of course, but OK for testing */
1252static char *indenter(int i)
1253{
1254 static char blanks[]=" ";
1255 return &blanks[sizeof(blanks)-i-1];
1256}
1257
1258/* return code is the exit status of the pipe */
1259static int run_pipe_test(struct pipe *pi, int indent)
1260{
1261 char **p;
1262 struct child_prog *child;
1263 struct redir_struct *r, *rnext;
1264 int a, i, ret_code=0;
1265 char *ind = indenter(indent);
1266 final_printf("%s run pipe: (pid %d)\n",ind,getpid());
1267 for (i=0; i<pi->num_progs; i++) {
1268 child = &pi->progs[i];
1269 final_printf("%s command %d:\n",ind,i);
1270 if (child->argv) {
1271 for (a=0,p=child->argv; *p; a++,p++) {
1272 final_printf("%s argv[%d] = %s\n",ind,a,*p);
1273 }
1274 globfree(&child->glob_result);
1275 child->argv=NULL;
1276 } else if (child->group) {
1277 final_printf("%s begin group (subshell:%d)\n",ind, child->subshell);
1278 ret_code = run_list_test(child->group,indent+3);
1279 final_printf("%s end group\n",ind);
1280 } else {
1281 final_printf("%s (nil)\n",ind);
1282 }
1283 for (r=child->redirects; r; r=rnext) {
1284 final_printf("%s redirect %d%s", ind, r->fd, redir_table[r->type].descrip);
1285 if (r->dup == -1) {
1286 final_printf(" %s\n", *r->word.gl_pathv);
1287 globfree(&r->word);
1288 } else {
1289 final_printf("&%d\n", r->dup);
1290 }
1291 rnext=r->next;
1292 free(r);
1293 }
1294 child->redirects=NULL;
1295 }
1296 free(pi->progs); /* children are an array, they get freed all at once */
1297 pi->progs=NULL;
1298 return ret_code;
1299}
1300
1301static int run_list_test(struct pipe *head, int indent)
1302{
1303 int rcode=0; /* if list has no members */
1304 struct pipe *pi, *next;
1305 char *ind = indenter(indent);
1306 for (pi=head; pi; pi=next) {
1307 if (pi->num_progs == 0) break;
1308 final_printf("%s pipe reserved mode %d\n", ind, pi->r_mode);
1309 rcode = run_pipe_test(pi, indent);
1310 final_printf("%s pipe followup code %d\n", ind, pi->followup);
1311 next=pi->next;
1312 pi->next=NULL;
1313 free(pi);
1314 }
1315 return rcode;
1316}
1317
1318/* Select which version we will use */
1319static int run_list(struct pipe *pi)
1320{
1321 int rcode=0;
1322 if (fake_mode==0) {
1323 rcode = run_list_real(pi);
1324 }
1325 /* run_list_test has the side effect of clearing memory
1326 * In the long run that function can be merged with run_list_real,
1327 * but doing that now would hobble the debugging effort. */
1328 run_list_test(pi,0);
1329 return rcode;
1330}
1331
1332/* The API for glob is arguably broken. This routine pushes a non-matching
1333 * string into the output structure, removing non-backslashed backslashes.
1334 * If someone can prove me wrong, by performing this function within the
1335 * original glob(3) api, feel free to rewrite this routine into oblivion.
1336 * Return code (0 vs. GLOB_NOSPACE) matches glob(3).
1337 * XXX broken if the last character is '\\', check that before calling.
1338 */
1339static int globhack(const char *src, int flags, glob_t *pglob)
1340{
1341 int cnt, pathc;
1342 const char *s;
1343 char *dest;
1344 for (cnt=1, s=src; *s; s++) {
1345 if (*s == '\\') s++;
1346 cnt++;
1347 }
1348 dest = malloc(cnt);
1349 if (!dest) return GLOB_NOSPACE;
1350 if (!(flags & GLOB_APPEND)) {
1351 pglob->gl_pathv=NULL;
1352 pglob->gl_pathc=0;
1353 pglob->gl_offs=0;
1354 pglob->gl_offs=0;
1355 }
1356 pathc = ++pglob->gl_pathc;
1357 pglob->gl_pathv = realloc(pglob->gl_pathv, (pathc+1)*sizeof(*pglob->gl_pathv));
1358 if (pglob->gl_pathv == NULL) return GLOB_NOSPACE;
1359 pglob->gl_pathv[pathc-1]=dest;
1360 pglob->gl_pathv[pathc]=NULL;
1361 for (s=src; *s; s++, dest++) {
1362 if (*s == '\\') s++;
1363 *dest = *s;
1364 }
1365 *dest='\0';
1366 return 0;
1367}
1368
1369/* XXX broken if the last character is '\\', check that before calling */
1370static int glob_needed(const char *s)
1371{
1372 for (; *s; s++) {
1373 if (*s == '\\') s++;
1374 if (strchr("*[?",*s)) return 1;
1375 }
1376 return 0;
1377}
1378
1379#if 0
1380static void globprint(glob_t *pglob)
1381{
1382 int i;
1383 debug_printf("glob_t at %p:\n", pglob);
1384 debug_printf(" gl_pathc=%d gl_pathv=%p gl_offs=%d gl_flags=%d\n",
1385 pglob->gl_pathc, pglob->gl_pathv, pglob->gl_offs, pglob->gl_flags);
1386 for (i=0; i<pglob->gl_pathc; i++)
1387 debug_printf("pglob->gl_pathv[%d] = %p = %s\n", i,
1388 pglob->gl_pathv[i], pglob->gl_pathv[i]);
1389}
1390#endif
1391
1392static int xglob(o_string *dest, int flags, glob_t *pglob)
1393{
1394 int gr;
1395
1396 /* short-circuit for null word */
1397 /* we can code this better when the debug_printf's are gone */
1398 if (dest->length == 0) {
1399 if (dest->nonnull) {
1400 /* bash man page calls this an "explicit" null */
1401 gr = globhack(dest->data, flags, pglob);
1402 debug_printf("globhack returned %d\n",gr);
1403 } else {
1404 return 0;
1405 }
1406 } else if (glob_needed(dest->data)) {
1407 gr = glob(dest->data, flags, NULL, pglob);
1408 debug_printf("glob returned %d\n",gr);
1409 if (gr == GLOB_NOMATCH) {
1410 /* quote removal, or more accurately, backslash removal */
1411 gr = globhack(dest->data, flags, pglob);
1412 debug_printf("globhack returned %d\n",gr);
1413 }
1414 } else {
1415 gr = globhack(dest->data, flags, pglob);
1416 debug_printf("globhack returned %d\n",gr);
1417 }
1418 if (gr == GLOB_NOSPACE) {
1419 fprintf(stderr,"out of memory during glob\n");
1420 exit(1);
1421 }
1422 if (gr != 0) { /* GLOB_ABORTED ? */
1423 fprintf(stderr,"glob(3) error %d\n",gr);
1424 }
1425 /* globprint(glob_target); */
1426 return gr;
1427}
1428
1429/* the src parameter allows us to peek forward to a possible &n syntax
1430 * for file descriptor duplication, e.g., "2>&1".
1431 * Return code is 0 normally, 1 if a syntax error is detected in src.
1432 * Resource errors (in xmalloc) cause the process to exit */
1433static int setup_redirect(struct p_context *ctx, int fd, redir_type style,
1434 struct in_str *input)
1435{
1436 struct child_prog *child=ctx->child;
1437 struct redir_struct *redir = child->redirects;
1438 struct redir_struct *last_redir=NULL;
1439
1440 /* Create a new redir_struct and drop it onto the end of the linked list */
1441 while(redir) {
1442 last_redir=redir;
1443 redir=redir->next;
1444 }
1445 redir = xmalloc(sizeof(struct redir_struct));
1446 redir->next=NULL;
1447 if (last_redir) {
1448 last_redir->next=redir;
1449 } else {
1450 child->redirects=redir;
1451 }
1452
1453 redir->type=style;
1454 redir->fd= (fd==-1) ? redir_table[style].default_fd : fd ;
1455
1456 debug_printf("Redirect type %d%s\n", redir->fd, redir_table[style].descrip);
1457
1458 /* Check for a '2>&1' type redirect */
1459 redir->dup = redirect_dup_num(input);
1460 if (redir->dup == -2) return 1; /* syntax error */
1461 if (redir->dup != -1) {
1462 /* Erik had a check here that the file descriptor in question
1463 * is legit; I postpone that to "run time" */
1464 debug_printf("Duplicating redirect '%d>&%d'\n", redir->fd, redir->dup);
1465 } else {
1466 /* We do _not_ try to open the file that src points to,
1467 * since we need to return and let src be expanded first.
1468 * Set ctx->pending_redirect, so we know what to do at the
1469 * end of the next parsed word.
1470 */
1471 ctx->pending_redirect = redir;
1472 }
1473 return 0;
1474}
1475
1476struct pipe *new_pipe(void) {
1477 struct pipe *pi;
1478 pi = xmalloc(sizeof(struct pipe));
1479 pi->num_progs = 0;
1480 pi->progs = NULL;
1481 pi->next = NULL;
1482 pi->followup = 0; /* invalid */
1483 return pi;
1484}
1485
1486static void initialize_context(struct p_context *ctx)
1487{
1488 ctx->pipe=NULL;
1489 ctx->pending_redirect=NULL;
1490 ctx->child=NULL;
1491 ctx->list_head=new_pipe();
1492 ctx->pipe=ctx->list_head;
1493 ctx->w=RES_NONE;
1494 ctx->stack=NULL;
1495 done_command(ctx); /* creates the memory for working child */
1496}
1497
1498/* normal return is 0
1499 * if a reserved word is found, and processed, return 1
1500 * should handle if, then, elif, else, fi, for, while, until, do, done.
1501 * case, function, and select are obnoxious, save those for later.
1502 */
1503int reserved_word(o_string *dest, struct p_context *ctx)
1504{
1505 struct reserved_combo {
1506 char *literal;
1507 int code;
1508 long flag;
1509 };
1510 /* Mostly a list of accepted follow-up reserved words.
1511 * FLAG_END means we are done with the sequence, and are ready
1512 * to turn the compound list into a command.
1513 * FLAG_START means the word must start a new compound list.
1514 */
1515 static struct reserved_combo reserved_list[] = {
1516 { "if", RES_IF, FLAG_THEN | FLAG_START },
1517 { "then", RES_THEN, FLAG_ELIF | FLAG_ELSE | FLAG_FI },
1518 { "elif", RES_ELIF, FLAG_THEN },
1519 { "else", RES_ELSE, FLAG_FI },
1520 { "fi", RES_FI, FLAG_END },
1521 { "for", RES_FOR, FLAG_DO | FLAG_START },
1522 { "while", RES_WHILE, FLAG_DO | FLAG_START },
1523 { "until", RES_UNTIL, FLAG_DO | FLAG_START },
1524 { "do", RES_DO, FLAG_DONE },
1525 { "done", RES_DONE, FLAG_END }
1526 };
1527 struct reserved_combo *r;
1528 for (r=reserved_list;
1529#define NRES sizeof(reserved_list)/sizeof(struct reserved_combo)
1530 r<reserved_list+NRES; r++) {
1531 if (strcmp(dest->data, r->literal) == 0) {
1532 debug_printf("found reserved word %s, code %d\n",r->literal,r->code);
1533 if (r->flag & FLAG_START) {
1534 struct p_context *new = xmalloc(sizeof(struct p_context));
1535 debug_printf("push stack\n");
1536 *new = *ctx; /* physical copy */
1537 initialize_context(ctx);
1538 ctx->stack=new;
1539 } else if ( ctx->w == RES_NONE || ! (ctx->old_flag & (1<<r->code))) {
1540 syntax(); /* XXX how do we get out? */
1541 }
1542 ctx->w=r->code;
1543 ctx->old_flag = r->flag;
1544 if (ctx->old_flag & FLAG_END) {
1545 struct p_context *old;
1546 debug_printf("pop stack\n");
1547 old = ctx->stack;
1548 old->child->group = ctx->list_head;
1549 *ctx = *old; /* physical copy */
1550 free(old);
1551 ctx->w=RES_NONE;
1552 }
1553 b_reset (dest);
1554 return 1;
1555 }
1556 }
1557 return 0;
1558}
1559
1560/* normal return is 0.
1561 * Syntax or xglob errors return 1. */
1562static int done_word(o_string *dest, struct p_context *ctx)
1563{
1564 struct child_prog *child=ctx->child;
1565 glob_t *glob_target;
1566 int gr, flags = 0;
1567
1568 debug_printf("done_word: %s %p\n", dest->data, child);
1569 if (dest->length == 0 && !dest->nonnull) {
1570 debug_printf(" true null, ignored\n");
1571 return 0;
1572 }
1573 if (ctx->pending_redirect) {
1574 glob_target = &ctx->pending_redirect->word;
1575 } else {
1576 if (child->group) {
1577 syntax();
1578 return 1; /* syntax error, groups and arglists don't mix */
1579 }
1580 if (!child->argv) {
1581 debug_printf("checking %s for reserved-ness\n",dest->data);
1582 if (reserved_word(dest,ctx)) return 0;
1583 }
1584 glob_target = &child->glob_result;
1585 if (child->argv) flags |= GLOB_APPEND;
1586 }
1587 gr = xglob(dest, flags, glob_target);
1588 if (gr != 0) return 1;
1589
1590 b_reset(dest);
1591 if (ctx->pending_redirect) {
1592 ctx->pending_redirect=NULL;
1593 if (glob_target->gl_pathc != 1) {
1594 fprintf(stderr, "ambiguous redirect\n");
1595 return 1;
1596 }
1597 } else {
1598 child->argv = glob_target->gl_pathv;
1599 }
1600 return 0;
1601}
1602
1603/* The only possible error here is out of memory, in which case
1604 * xmalloc exits. */
1605static int done_command(struct p_context *ctx)
1606{
1607 /* The child is really already in the pipe structure, so
1608 * advance the pipe counter and make a new, null child.
1609 * Only real trickiness here is that the uncommitted
1610 * child structure, to which ctx->child points, is not
1611 * counted in pi->num_progs. */
1612 struct pipe *pi=ctx->pipe;
1613 struct child_prog *prog=ctx->child;
1614
1615 if (prog && prog->group == NULL
1616 && prog->argv == NULL
1617 && prog->redirects == NULL) {
1618 debug_printf("done_command: skipping null command\n");
1619 return 0;
1620 } else if (prog) {
1621 pi->num_progs++;
1622 debug_printf("done_command: num_progs incremented to %d\n",pi->num_progs);
1623 } else {
1624 debug_printf("done_command: initializing\n");
1625 }
1626 pi->progs = xrealloc(pi->progs, sizeof(*pi->progs) * (pi->num_progs+1));
1627
1628 prog = pi->progs + pi->num_progs;
1629 prog->redirects = NULL;
1630 prog->argv = NULL;
1631 prog->is_stopped = 0;
1632 prog->group = NULL;
1633 prog->glob_result.gl_pathv = NULL;
1634 prog->family = pi;
1635
1636 ctx->child=prog;
1637 /* but ctx->pipe and ctx->list_head remain unchanged */
1638 return 0;
1639}
1640
1641static int done_pipe(struct p_context *ctx, pipe_style type)
1642{
1643 struct pipe *new_p;
1644 done_command(ctx); /* implicit closure of previous command */
1645 debug_printf("done_pipe, type %d\n", type);
1646 ctx->pipe->followup = type;
1647 ctx->pipe->r_mode = ctx->w;
1648 new_p=new_pipe();
1649 ctx->pipe->next = new_p;
1650 ctx->pipe = new_p;
1651 ctx->child = NULL;
1652 done_command(ctx); /* set up new pipe to accept commands */
1653 return 0;
1654}
1655
1656/* peek ahead in the in_str to find out if we have a "&n" construct,
1657 * as in "2>&1", that represents duplicating a file descriptor.
1658 * returns either -2 (syntax error), -1 (no &), or the number found.
1659 */
1660static int redirect_dup_num(struct in_str *input)
1661{
1662 int ch, d=0, ok=0;
1663 ch = b_peek(input);
1664 if (ch != '&') return -1;
1665
1666 b_getch(input); /* get the & */
1667 while (ch=b_peek(input),isdigit(ch)) {
1668 d = d*10+(ch-'0');
1669 ok=1;
1670 b_getch(input);
1671 }
1672 if (ok) return d;
1673
1674 fprintf(stderr, "ambiguous redirect\n");
1675 return -2;
1676}
1677
1678/* If a redirect is immediately preceded by a number, that number is
1679 * supposed to tell which file descriptor to redirect. This routine
1680 * looks for such preceding numbers. In an ideal world this routine
1681 * needs to handle all the following classes of redirects...
1682 * echo 2>foo # redirects fd 2 to file "foo", nothing passed to echo
1683 * echo 49>foo # redirects fd 49 to file "foo", nothing passed to echo
1684 * echo -2>foo # redirects fd 1 to file "foo", "-2" passed to echo
1685 * echo 49x>foo # redirects fd 1 to file "foo", "49x" passed to echo
1686 * A -1 output from this program means no valid number was found, so the
1687 * caller should use the appropriate default for this redirection.
1688 */
1689static int redirect_opt_num(o_string *o)
1690{
1691 int num;
1692
1693 if (o->length==0) return -1;
1694 for(num=0; num<o->length; num++) {
1695 if (!isdigit(*(o->data+num))) {
1696 return -1;
1697 }
1698 }
1699 /* reuse num (and save an int) */
1700 num=atoi(o->data);
1701 b_reset(o);
1702 return num;
1703}
1704
1705FILE *generate_stream_from_list(struct pipe *head)
1706{
1707 FILE *pf;
1708#if 1
1709 int pid, channel[2];
1710 if (pipe(channel)<0) perror_msg_and_die("pipe");
1711 pid=fork();
1712 if (pid<0) {
1713 perror_msg_and_die("fork");
1714 } else if (pid==0) {
1715 close(channel[0]);
1716 if (channel[1] != 1) {
1717 dup2(channel[1],1);
1718 close(channel[1]);
1719 }
1720#if 0
1721#define SURROGATE "surrogate response"
1722 write(1,SURROGATE,sizeof(SURROGATE));
1723 exit(run_list(head));
1724#else
1725 exit(run_list_real(head)); /* leaks memory */
1726#endif
1727 }
1728 debug_printf("forked child %d\n",pid);
1729 close(channel[1]);
1730 pf = fdopen(channel[0],"r");
1731 debug_printf("pipe on FILE *%p\n",pf);
1732#else
1733 run_list_test(head,0);
1734 pf=popen("echo surrogate response","r");
1735 debug_printf("started fake pipe on FILE *%p\n",pf);
1736#endif
1737 return pf;
1738}
1739
1740/* this version hacked for testing purposes */
1741/* return code is exit status of the process that is run. */
1742static int process_command_subs(o_string *dest, struct p_context *ctx, struct in_str *input, int subst_end)
1743{
1744 int retcode;
1745 o_string result=NULL_O_STRING;
1746 struct p_context inner;
1747 FILE *p;
1748 struct in_str pipe_str;
1749 initialize_context(&inner);
1750
1751 /* recursion to generate command */
1752 retcode = parse_stream(&result, &inner, input, subst_end);
1753 if (retcode != 0) return retcode; /* syntax error or EOF */
1754 done_word(&result, &inner);
1755 done_pipe(&inner, PIPE_SEQ);
1756 b_free(&result);
1757
1758 p=generate_stream_from_list(inner.list_head);
1759 if (p==NULL) return 1;
1760 mark_open(fileno(p));
1761 setup_file_in_str(&pipe_str, p);
1762
1763 /* now send results of command back into original context */
1764 retcode = parse_stream(dest, ctx, &pipe_str, '\0');
1765 /* XXX In case of a syntax error, should we try to kill the child?
1766 * That would be tough to do right, so just read until EOF. */
1767 if (retcode == 1) {
1768 while (b_getch(&pipe_str)!=EOF) { /* discard */ };
1769 }
1770
1771 debug_printf("done reading from pipe, pclose()ing\n");
1772 /* This is the step that wait()s for the child. Should be pretty
1773 * safe, since we just read an EOF from its stdout. We could try
1774 * to better, by using wait(), and keeping track of background jobs
1775 * at the same time. That would be a lot of work, and contrary
1776 * to the KISS philosophy of this program. */
1777 mark_closed(fileno(p));
1778 retcode=pclose(p);
1779 debug_printf("pclosed, retcode=%d\n",retcode);
1780 /* XXX this process fails to trim a single trailing newline */
1781 return retcode;
1782}
1783
1784static int parse_group(o_string *dest, struct p_context *ctx,
1785 struct in_str *input, int ch)
1786{
1787 int rcode, endch=0;
1788 struct p_context sub;
1789 struct child_prog *child = ctx->child;
1790 if (child->argv) {
1791 syntax();
1792 return 1; /* syntax error, groups and arglists don't mix */
1793 }
1794 initialize_context(&sub);
1795 switch(ch) {
1796 case '(': endch=')'; child->subshell=1; break;
1797 case '{': endch='}'; break;
1798 default: syntax(); /* really logic error */
1799 }
1800 rcode=parse_stream(dest,&sub,input,endch);
1801 done_word(dest,&sub); /* finish off the final word in the subcontext */
1802 done_pipe(&sub, PIPE_SEQ); /* and the final command there, too */
1803 child->group = sub.list_head;
1804 return rcode;
1805 /* child remains "open", available for possible redirects */
1806}
1807
1808/* basically useful version until someone wants to get fancier,
1809 * see the bash man page under "Parameter Expansion" */
1810static void lookup_param(o_string *dest, struct p_context *ctx, o_string *src)
1811{
1812 const char *p=NULL;
1813 if (src->data) p = getenv(src->data);
1814 if (p) parse_string(dest, ctx, p); /* recursion */
1815 b_free(src);
1816}
1817
1818/* return code: 0 for OK, 1 for syntax error */
1819static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *input)
1820{
1821 int i, advance=0;
1822 o_string alt=NULL_O_STRING;
1823 char sep[]=" ";
1824 int ch = input->peek(input); /* first character after the $ */
1825 debug_printf("handle_dollar: ch=%c\n",ch);
1826 if (isalpha(ch)) {
1827 while(ch=b_peek(input),isalnum(ch) || ch=='_') {
1828 b_getch(input);
1829 b_addchr(&alt,ch);
1830 }
1831 lookup_param(dest, ctx, &alt);
1832 } else if (isdigit(ch)) {
1833 i = ch-'0'; /* XXX is $0 special? */
1834 if (i<global_argc) {
1835 parse_string(dest, ctx, global_argv[i]); /* recursion */
1836 }
1837 advance = 1;
1838 } else switch (ch) {
1839 case '$':
1840 b_adduint(dest,getpid());
1841 advance = 1;
1842 break;
1843 case '!':
1844 if (last_bg_pid > 0) b_adduint(dest, last_bg_pid);
1845 advance = 1;
1846 break;
1847 case '?':
1848 b_adduint(dest,last_return_code);
1849 advance = 1;
1850 break;
1851 case '#':
1852 b_adduint(dest,global_argc ? global_argc-1 : 0);
1853 advance = 1;
1854 break;
1855 case '{':
1856 b_getch(input);
1857 /* XXX maybe someone will try to escape the '}' */
1858 while(ch=b_getch(input),ch!=EOF && ch!='}') {
1859 b_addchr(&alt,ch);
1860 }
1861 if (ch != '}') {
1862 syntax();
1863 return 1;
1864 }
1865 lookup_param(dest, ctx, &alt);
1866 break;
1867 case '(':
1868 process_command_subs(dest, ctx, input, ')');
1869 break;
1870 case '*':
1871 sep[0]=ifs[0];
1872 for (i=1; i<global_argc; i++) {
1873 parse_string(dest, ctx, global_argv[i]);
1874 if (i+1 < global_argc) parse_string(dest, ctx, sep);
1875 }
1876 break;
1877 case '@':
1878 case '-':
1879 case '_':
1880 /* still unhandled, but should be eventually */
1881 fprintf(stderr,"unhandled syntax: $%c\n",ch);
1882 return 1;
1883 break;
1884 default:
1885 b_addqchr(dest,'$',dest->quote);
1886 }
1887 /* Eat the character if the flag was set. If the compiler
1888 * is smart enough, we could substitute "b_getch(input);"
1889 * for all the "advance = 1;" above, and also end up with
1890 * a nice size-optimized program. Hah! That'll be the day.
1891 */
1892 if (advance) b_getch(input);
1893 return 0;
1894}
1895
1896int parse_string(o_string *dest, struct p_context *ctx, const char *src)
1897{
1898 struct in_str foo;
1899 setup_string_in_str(&foo, src);
1900 return parse_stream(dest, ctx, &foo, '\0');
1901}
1902
1903/* return code is 0 for normal exit, 1 for syntax error */
1904int parse_stream(o_string *dest, struct p_context *ctx,
1905 struct in_str *input, int end_trigger)
1906{
1907 unsigned int ch, m;
1908 int redir_fd;
1909 redir_type redir_style;
1910 int next;
1911
1912 /* Only double-quote state is handled in the state variable dest->quote.
1913 * A single-quote triggers a bypass of the main loop until its mate is
1914 * found. When recursing, quote state is passed in via dest->quote. */
1915
1916 debug_printf("parse_stream, end_trigger=%d\n",end_trigger);
1917 while ((ch=b_getch(input))!=EOF) {
1918 m = map[ch];
1919 next = (ch == '\n') ? 0 : b_peek(input);
1920 debug_printf("parse_stream: ch=%c (%d) m=%d quote=%d\n",
1921 ch,ch,m,dest->quote);
1922 if (m==0 || ((m==1 || m==2) && dest->quote)) {
1923 b_addqchr(dest, ch, dest->quote);
1924 } else if (ch == end_trigger && !dest->quote) {
1925 debug_printf("leaving parse_stream\n");
1926 return 0;
1927 } else if (m==2 && !dest->quote) { /* IFS */
1928 done_word(dest, ctx);
1929#if 0
1930 if (ch=='\n') {
1931 /* Yahoo! Time to run with it! */
1932 done_pipe(ctx,PIPE_SEQ);
1933 run_list(ctx->list_head);
1934 initialize_context(ctx);
1935 }
1936#endif
1937 } else switch (ch) {
1938 case '#':
1939 if (dest->length == 0 && !dest->quote) {
1940 while(ch=b_peek(input),ch!=EOF && ch!='\n') { b_getch(input); }
1941 } else {
1942 b_addqchr(dest, ch, dest->quote);
1943 }
1944 break;
1945 case '\\':
1946 if (next == EOF) {
1947 syntax();
1948 return 1;
1949 }
1950 b_addqchr(dest, '\\', dest->quote);
1951 b_addqchr(dest, b_getch(input), dest->quote);
1952 break;
1953 case '$':
1954 if (handle_dollar(dest, ctx, input)!=0) return 1;
1955 break;
1956 case '\'':
1957 dest->nonnull = 1;
1958 while(ch=b_getch(input),ch!=EOF && ch!='\'') {
1959 b_addchr(dest,ch);
1960 }
1961 if (ch==EOF) {
1962 syntax();
1963 return 1;
1964 }
1965 break;
1966 case '"':
1967 dest->nonnull = 1;
1968 dest->quote = !dest->quote;
1969 break;
1970 case '`':
1971 process_command_subs(dest, ctx, input, '`');
1972 break;
1973 case '>':
1974 redir_fd = redirect_opt_num(dest);
1975 done_word(dest, ctx);
1976 redir_style=REDIRECT_OVERWRITE;
1977 if (next == '>') {
1978 redir_style=REDIRECT_APPEND;
1979 b_getch(input);
1980 } else if (next == '(') {
1981 syntax(); /* until we support >(list) Process Substitution */
1982 return 1;
1983 }
1984 setup_redirect(ctx, redir_fd, redir_style, input);
1985 break;
1986 case '<':
1987 redir_fd = redirect_opt_num(dest);
1988 done_word(dest, ctx);
1989 redir_style=REDIRECT_INPUT;
1990 if (next == '<') {
1991 redir_style=REDIRECT_HEREIS;
1992 b_getch(input);
1993 } else if (next == '>') {
1994 redir_style=REDIRECT_IO;
1995 b_getch(input);
1996 } else if (next == '(') {
1997 syntax(); /* until we support <(list) Process Substitution */
1998 return 1;
1999 }
2000 setup_redirect(ctx, redir_fd, redir_style, input);
2001 break;
2002 case ';':
2003 done_word(dest, ctx);
2004 done_pipe(ctx,PIPE_SEQ);
2005 break;
2006 case '&':
2007 done_word(dest, ctx);
2008 if (next=='&') {
2009 b_getch(input);
2010 done_pipe(ctx,PIPE_AND);
2011 } else {
2012 done_pipe(ctx,PIPE_BG);
2013 }
2014 break;
2015 case '|':
2016 done_word(dest, ctx);
2017 if (next=='|') {
2018 b_getch(input);
2019 done_pipe(ctx,PIPE_OR);
2020 } else {
2021 /* we could pick up a file descriptor choice here
2022 * with redirect_opt_num(), but bash doesn't do it.
2023 * "echo foo 2| cat" yields "foo 2". */
2024 done_command(ctx);
2025 }
2026 break;
2027 case '(':
2028 case '{':
2029 if (parse_group(dest, ctx, input, ch)!=0) return 1;
2030 break;
2031 case ')':
2032 case '}':
2033 syntax(); /* Proper use of this character caught by end_trigger */
2034 return 1;
2035 break;
2036 default:
2037 syntax(); /* this is really an internal logic error */
2038 return 1;
2039 }
2040 }
2041 /* complain if quote? No, maybe we just finished a command substitution
2042 * that was quoted. Example:
2043 * $ echo "`cat foo` plus more"
2044 * and we just got the EOF generated by the subshell that ran "cat foo"
2045 * The only real complaint is if we got an EOF when end_trigger != '\0',
2046 * that is, we were really supposed to get end_trigger, and never got
2047 * one before the EOF. Can't use the standard "syntax error" return code,
2048 * so that parse_stream_outer can distinguish the EOF and exit smoothly. */
2049 if (end_trigger != '\0') return -1;
2050 return 0;
2051}
2052
2053void mapset(const unsigned char *set, int code)
2054{
2055 const unsigned char *s;
2056 for (s=set; *s; s++) map[*s] = code;
2057}
2058
2059void update_ifs_map(void)
2060{
2061 /* char *ifs and char map[256] are both globals. */
2062 ifs = getenv("IFS");
2063 if (ifs == NULL) ifs=" \t\n";
2064 /* Precompute a list of 'flow through' behavior so it can be treated
2065 * quickly up front. Computation is necessary because of IFS.
2066 * Special case handling of IFS == " \t\n" is not implemented.
2067 * The map[] array only really needs two bits each, and on most machines
2068 * that would be faster because of the reduced L1 cache footprint.
2069 */
2070 memset(map,0,256); /* most characters flow through always */
2071 mapset("\\$'\"`", 3); /* never flow through */
2072 mapset("<>;&|(){}#", 1); /* flow through if quoted */
2073 mapset(ifs, 2); /* also flow through if quoted */
2074}
2075
2076/* most recursion does not come through here, the exeception is
2077 * from builtin_source() */
2078int parse_stream_outer(struct in_str *inp)
2079{
2080
2081 struct p_context ctx;
2082 o_string temp=NULL_O_STRING;
2083 int rcode;
2084 do {
2085 initialize_context(&ctx);
2086 update_ifs_map();
2087 inp->promptmode=1;
2088 rcode = parse_stream(&temp, &ctx, inp, '\n');
2089 done_word(&temp, &ctx);
2090 done_pipe(&ctx,PIPE_SEQ);
2091 run_list(ctx.list_head);
2092 } while (rcode != -1); /* loop on syntax errors, return on EOF */
2093 return 0;
2094}
2095
2096static int parse_string_outer(const char *s)
2097{
2098 struct in_str input;
2099 setup_string_in_str(&input, s);
2100 return parse_stream_outer(&input);
2101}
2102
2103static int parse_file_outer(FILE *f)
2104{
2105 int rcode;
2106 struct in_str input;
2107 setup_file_in_str(&input, f);
2108 rcode = parse_stream_outer(&input);
2109 return rcode;
2110}
2111
2112int shell_main(int argc, char **argv)
2113{
2114 int opt;
2115 FILE *input;
2116
2117 /* XXX what should these be while sourcing /etc/profile? */
2118 global_argc = argc;
2119 global_argv = argv;
2120
2121 if (argv[0] && argv[0][0] == '-') {
2122 debug_printf("\nsourcing /etc/profile\n");
2123 input = xfopen("/etc/profile", "r");
2124 mark_open(fileno(input));
2125 parse_file_outer(input);
2126 mark_closed(fileno(input));
2127 fclose(input);
2128 }
2129 input=stdin;
2130
2131 /* initialize the cwd -- this is never freed...*/
2132 cwd = xgetcwd(0);
2133#ifdef BB_FEATURE_COMMAND_EDITING
2134 cmdedit_set_initial_prompt();
2135#else
2136 PS1 = NULL;
2137#endif
2138
2139 while ((opt = getopt(argc, argv, "c:xif")) > 0) {
2140 switch (opt) {
2141 case 'c':
2142 {
2143 global_argv = argv+optind;
2144 global_argc = argc-optind;
2145 opt = parse_string_outer(optarg);
2146 exit(opt);
2147 }
2148 break;
2149 case 'i':
2150 interactive++;
2151 break;
2152 case 'f':
2153 fake_mode++;
2154 break;
2155 default:
2156 fprintf(stderr, "Usage: sh [FILE]...\n"
2157 " or: sh -c command [args]...\n\n");
2158 exit(EXIT_FAILURE);
2159 }
2160 }
2161 /* A shell is interactive if the `-i' flag was given, or if all of
2162 * the following conditions are met:
2163 * no -c command
2164 * no arguments remaining or the -s flag given
2165 * standard input is a terminal
2166 * standard output is a terminal
2167 * Refer to Posix.2, the description of the `sh' utility. */
2168 if (argv[optind]==NULL && input==stdin &&
2169 isatty(fileno(stdin)) && isatty(fileno(stdout))) {
2170 interactive++;
2171 }
2172
2173 if (interactive) {
2174 /* Looks like they want an interactive shell */
2175 fprintf(stdout, "\nhush -- the humble shell v0.01 (testing)\n\n");
2176 exit(parse_file_outer(stdin));
2177 }
2178 debug_printf("\ninteractive=%d\n", interactive);
2179
2180 debug_printf("\nrunning script '%s'\n", argv[optind]);
2181 global_argv = argv+optind;
2182 global_argc = argc-optind;
2183 input = xfopen(argv[optind], "r");
2184 opt = parse_file_outer(input);
2185
2186#ifdef BB_FEATURE_CLEAN_UP
2187 fclose(input.file);
2188#endif
2189
2190 return(opt);
2191}