98550734130976a0456a9d1de261f6242e6ee7a0
[people/mcb30/busybox.git] / ash.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * ash shell port for busybox
4  *
5  * Copyright (c) 1989, 1991, 1993, 1994
6  *      The Regents of the University of California.  All rights reserved.
7  *
8  * This code is derived from software contributed to Berkeley by
9  * Kenneth Almquist.
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  * General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24  *
25  * This version of ash is adapted from the source in Debian's ash 0.3.8-5
26  * package.
27  *
28  * Modified by Erik Andersen <andersee@debian.org> and
29  * Vladimir Oleynik <vodz@usa.net> to be used in busybox
30  *
31  *
32  * Original copyright notice is retained at the end of this file.
33  */
34
35
36 /* These defines allow you to adjust the feature set to be compiled
37  * into the ash shell.   As a rule, enabling these options will make
38  * ash get bigger...   With all of these options off, ash adds about
39  * 60k to busybox on an x86 system.*/
40
41
42 /* Enable job control.  This allows you to run jobs in the background,
43  * which is great when ash is being  used as an interactive shell, but
44  * it completely useless for is all you are doing is running scripts.
45  * This adds about 2.5k on an x86 system. */
46 #undef JOBS
47
48 /* This enables alias support in ash.  If you want to support things
49  * like "alias ls='ls -l'" with ash, enable this.  This is only useful
50  * when ash is used as an intractive shell.   This adds about 1.5k */
51 #define ASH_ALIAS
52
53 /* If you need ash to act as a full Posix shell, with full math
54  * support, enable this.   This option needs some work, since it
55  * doesn't compile right now... */
56 #undef ASH_MATH_SUPPORT
57
58 /* Getopts is used by shell procedures to parse positional parameters.
59  * You probably want to leave this disabled, and use the busybox getopt
60  * applet if you want to do this sort of thing.  There are some scripts
61  * out there that use it, so it you need it, enable.  Most people will
62  * leave this disabled.  This adds 1k on an x86 system. */
63 #undef ASH_GETOPTS
64
65 /* This allows you to override shell builtins and use whatever is on
66  * the filesystem.  This is most useful when ash is acting as a
67  * standalone shell.   Adds about 272 bytes. */
68 #undef ASH_CMDCMD
69
70
71 /* Optimize size vs speed as size */
72 #define ASH_OPTIMIZE_FOR_SIZE
73
74 /* Enable this to compile in extra debugging noise.  When debugging is
75  * on, debugging info will be written to $HOME/trace and a quit signal
76  * will generate a core dump. */
77 #undef DEBUG
78
79 /* These are here to work with glibc -- Don't change these... */
80 #undef FNMATCH_BROKEN
81 #undef GLOB_BROKEN
82 #undef _GNU_SOURCE
83
84 #include <assert.h>
85 #include <ctype.h>
86 #include <dirent.h>
87 #include <errno.h>
88 #include <fcntl.h>
89 #include <limits.h>
90 #include <paths.h>
91 #include <pwd.h>
92 #include <setjmp.h>
93 #include <signal.h>
94 #include <stdarg.h>
95 #include <stdio.h>
96 #include <stdlib.h>
97 #include <string.h>
98 #include <sysexits.h>
99 #include <unistd.h>
100 #include <sys/stat.h>
101 #include <sys/cdefs.h>
102 #include <sys/ioctl.h>
103 #include <sys/param.h>
104 #include <sys/resource.h>
105 #include <sys/time.h>
106 #include <sys/times.h>
107 #include <sys/types.h>
108 #include <sys/wait.h>
109
110
111 #if !defined(FNMATCH_BROKEN)
112 #include <fnmatch.h>
113 #endif
114 #if !defined(GLOB_BROKEN)
115 #include <glob.h>
116 #endif
117
118 #ifdef JOBS
119 #include <termios.h>
120 #endif
121
122 #include "busybox.h"
123 #include "cmdedit.h"
124
125 /*
126  * This file was generated by the mksyntax program.
127  */
128
129 /* Syntax classes */
130 #define CWORD 0                 /* character is nothing special */
131 #define CNL 1                   /* newline character */
132 #define CBACK 2                 /* a backslash character */
133 #define CSQUOTE 3               /* single quote */
134 #define CDQUOTE 4               /* double quote */
135 #define CENDQUOTE 5             /* a terminating quote */
136 #define CBQUOTE 6               /* backwards single quote */
137 #define CVAR 7                  /* a dollar sign */
138 #define CENDVAR 8               /* a '}' character */
139 #define CLP 9                   /* a left paren in arithmetic */
140 #define CRP 10                  /* a right paren in arithmetic */
141 #define CENDFILE 11             /* end of file */
142 #define CCTL 12                 /* like CWORD, except it must be escaped */
143 #define CSPCL 13                /* these terminate a word */
144 #define CIGN 14                 /* character should be ignored */
145
146 /* Syntax classes for is_ functions */
147 #define ISDIGIT 01              /* a digit */
148 #define ISUPPER 02              /* an upper case letter */
149 #define ISLOWER 04              /* a lower case letter */
150 #define ISUNDER 010             /* an underscore */
151 #define ISSPECL 020             /* the name of a special parameter */
152
153 #define SYNBASE 130
154 #define PEOF -130
155
156 #define PEOA -129
157
158 #define TEOF 0
159 #define TNL 1
160 #define TSEMI 2
161 #define TBACKGND 3
162 #define TAND 4
163 #define TOR 5
164 #define TPIPE 6
165 #define TLP 7
166 #define TRP 8
167 #define TENDCASE 9
168 #define TENDBQUOTE 10
169 #define TREDIR 11
170 #define TWORD 12
171 #define TASSIGN 13
172 #define TNOT 14
173 #define TCASE 15
174 #define TDO 16
175 #define TDONE 17
176 #define TELIF 18
177 #define TELSE 19
178 #define TESAC 20
179 #define TFI 21
180 #define TFOR 22
181 #define TIF 23
182 #define TIN 24
183 #define TTHEN 25
184 #define TUNTIL 26
185 #define TWHILE 27
186 #define TBEGIN 28
187 #define TEND 29
188
189
190 #define BASESYNTAX (basesyntax + SYNBASE)
191 #define DQSYNTAX (dqsyntax + SYNBASE)
192 #define SQSYNTAX (sqsyntax + SYNBASE)
193 #define ARISYNTAX (arisyntax + SYNBASE)
194
195 /* control characters in argument strings */
196 #define CTLESC '\201'
197 #define CTLVAR '\202'
198 #define CTLENDVAR '\203'
199 #define CTLBACKQ '\204'
200 #define CTLQUOTE 01             /* ored with CTLBACKQ code if in quotes */
201 /*      CTLBACKQ | CTLQUOTE == '\205' */
202 #define CTLARI  '\206'
203 #define CTLENDARI '\207'
204 #define CTLQUOTEMARK '\210'
205
206 #define is_digit(c)     ((c)>='0' && (c)<='9')
207 #define is_alpha(c)     (((c) < CTLESC || (c) > CTLENDARI) && isalpha((unsigned char) (c)))
208 #define is_name(c)      (((c) < CTLESC || (c) > CTLENDARI) && ((c) == '_' || isalpha((unsigned char) (c))))
209 #define is_in_name(c)   (((c) < CTLESC || (c) > CTLENDARI) && ((c) == '_' || isalnum((unsigned char) (c))))
210 #define is_special(c)   ((is_type+SYNBASE)[c] & (ISSPECL|ISDIGIT))
211 #define digit_val(c)    ((c) - '0')
212
213
214 #define _DIAGASSERT(x)
215
216
217
218 #define S_DFL 1                 /* default signal handling (SIG_DFL) */
219 #define S_CATCH 2               /* signal is caught */
220 #define S_IGN 3                 /* signal is ignored (SIG_IGN) */
221 #define S_HARD_IGN 4            /* signal is ignored permenantly */
222 #define S_RESET 5               /* temporary - to reset a hard ignored sig */
223
224
225 /* variable substitution byte (follows CTLVAR) */
226 #define VSTYPE  0x0f            /* type of variable substitution */
227 #define VSNUL   0x10            /* colon--treat the empty string as unset */
228 #define VSQUOTE 0x80            /* inside double quotes--suppress splitting */
229
230 /* values of VSTYPE field */
231 #define VSNORMAL        0x1             /* normal variable:  $var or ${var} */
232 #define VSMINUS         0x2             /* ${var-text} */
233 #define VSPLUS          0x3             /* ${var+text} */
234 #define VSQUESTION      0x4             /* ${var?message} */
235 #define VSASSIGN        0x5             /* ${var=text} */
236 #define VSTRIMLEFT      0x6             /* ${var#pattern} */
237 #define VSTRIMLEFTMAX   0x7             /* ${var##pattern} */
238 #define VSTRIMRIGHT     0x8             /* ${var%pattern} */
239 #define VSTRIMRIGHTMAX  0x9             /* ${var%%pattern} */
240 #define VSLENGTH        0xa             /* ${#var} */
241
242 /* flags passed to redirect */
243 #define REDIR_PUSH 01           /* save previous values of file descriptors */
244 #define REDIR_BACKQ 02          /* save the command output to pipe */
245
246 /*
247  * BSD setjmp saves the signal mask, which violates ANSI C and takes time,
248  * so we use _setjmp instead.
249  */
250
251 #if defined(BSD)
252 #define setjmp(jmploc)  _setjmp(jmploc)
253 #define longjmp(jmploc, val)    _longjmp(jmploc, val)
254 #endif
255
256 /*
257  * Most machines require the value returned from malloc to be aligned
258  * in some way.  The following macro will get this right on many machines.
259  */
260
261 #ifndef ALIGN
262 union align {
263         int i;
264         char *cp;
265 };
266
267 #define ALIGN(nbytes)   (((nbytes) + sizeof(union align) - 1) & ~(sizeof(union align) - 1))
268 #endif
269
270 #ifdef BB_LOCALE_SUPPORT
271 #include <locale.h>
272 static void change_lc_all(const char *value);
273 static void change_lc_ctype(const char *value);
274 #endif
275
276 /*
277  * These macros allow the user to suspend the handling of interrupt signals
278  * over a period of time.  This is similar to SIGHOLD to or sigblock, but
279  * much more efficient and portable.  (But hacking the kernel is so much
280  * more fun than worrying about efficiency and portability. :-))
281  */
282
283 static void onint (void);
284 static volatile int suppressint;
285 static volatile int intpending;
286
287 #define INTOFF suppressint++
288 #ifndef ASH_OPTIMIZE_FOR_SIZE
289 #define INTON { if (--suppressint == 0 && intpending) onint(); }
290 #define FORCEINTON {suppressint = 0; if (intpending) onint();}
291 #else
292 static void __inton (void);
293 static void forceinton (void);
294 #define INTON __inton()
295 #define FORCEINTON forceinton()
296 #endif
297
298 #define CLEAR_PENDING_INT intpending = 0
299 #define int_pending() intpending
300
301
302 typedef void *pointer;
303 #ifndef NULL
304 #define NULL (void *)0
305 #endif
306
307 static inline pointer  ckmalloc (int sz)          { return xmalloc(sz);     }
308 static inline pointer  ckrealloc(void *p, int sz) { return xrealloc(p, sz); }
309 static inline char *   savestr  (const char *s)   { return xstrdup(s);      }
310
311 static pointer stalloc (int);
312 static void stunalloc (pointer);
313 static void ungrabstackstr (char *, char *);
314 static char * growstackstr(void);
315 static char * makestrspace(size_t newlen);
316 static char *sstrdup (const char *);
317
318 /*
319  * Parse trees for commands are allocated in lifo order, so we use a stack
320  * to make this more efficient, and also to avoid all sorts of exception
321  * handling code to handle interrupts in the middle of a parse.
322  *
323  * The size 504 was chosen because the Ultrix malloc handles that size
324  * well.
325  */
326
327 #define MINSIZE 504             /* minimum size of a block */
328
329
330 struct stack_block {
331         struct stack_block *prev;
332         char space[MINSIZE];
333 };
334
335 static struct stack_block stackbase;
336 static struct stack_block *stackp = &stackbase;
337 static struct stackmark *markp;
338 static char *stacknxt = stackbase.space;
339 static int stacknleft = MINSIZE;
340
341
342 #define equal(s1, s2)   (strcmp(s1, s2) == 0)
343
344 #define stackblock() stacknxt
345 #define stackblocksize() stacknleft
346 #define STARTSTACKSTR(p)        p = stackblock(), sstrnleft = stackblocksize()
347
348 #define STPUTC(c, p)    (--sstrnleft >= 0? (*p++ = (c)) : (p = growstackstr(), *p++ = (c)))
349 #define CHECKSTRSPACE(n, p)     { if (sstrnleft < n) p = makestrspace(n); }
350 #define STACKSTRNUL(p)  (sstrnleft == 0? (p = growstackstr(), *p = '\0') : (*p = '\0'))
351
352
353 #define USTPUTC(c, p)   (--sstrnleft, *p++ = (c))
354 #define STUNPUTC(p)     (++sstrnleft, --p)
355 #define STTOPC(p)       p[-1]
356 #define STADJUST(amount, p)     (p += (amount), sstrnleft -= (amount))
357 #define grabstackstr(p) stalloc(stackblocksize() - sstrnleft)
358
359 #define ckfree(p)       free((pointer)(p))
360
361
362 #ifdef DEBUG
363 #define TRACE(param)    trace param
364 static void trace (const char *, ...);
365 static void trargs (char **);
366 static void showtree (union node *);
367 static void trputc (int);
368 static void trputs (const char *);
369 static void opentrace (void);
370 #else
371 #define TRACE(param)
372 #endif
373
374 #define NSEMI 0
375 #define NCMD 1
376 #define NPIPE 2
377 #define NREDIR 3
378 #define NBACKGND 4
379 #define NSUBSHELL 5
380 #define NAND 6
381 #define NOR 7
382 #define NIF 8
383 #define NWHILE 9
384 #define NUNTIL 10
385 #define NFOR 11
386 #define NCASE 12
387 #define NCLIST 13
388 #define NDEFUN 14
389 #define NARG 15
390 #define NTO 16
391 #define NFROM 17
392 #define NFROMTO 18
393 #define NAPPEND 19
394 #define NTOOV 20
395 #define NTOFD 21
396 #define NFROMFD 22
397 #define NHERE 23
398 #define NXHERE 24
399 #define NNOT 25
400
401 /*
402  * expandarg() flags
403  */
404 #define EXP_FULL        0x1     /* perform word splitting & file globbing */
405 #define EXP_TILDE       0x2     /* do normal tilde expansion */
406 #define EXP_VARTILDE    0x4     /* expand tildes in an assignment */
407 #define EXP_REDIR       0x8     /* file glob for a redirection (1 match only) */
408 #define EXP_CASE        0x10    /* keeps quotes around for CASE pattern */
409 #define EXP_RECORD      0x20    /* need to record arguments for ifs breakup */
410
411
412 #define NOPTS   16
413
414 static char optet_vals[NOPTS];
415
416 static const char * const optlist[NOPTS] = {
417         "e" "errexit",
418         "f" "noglob",
419         "I" "ignoreeof",
420         "i" "interactive",
421         "m" "monitor",
422         "n" "noexec",
423         "s" "stdin",
424         "x" "xtrace",
425         "v" "verbose",
426         "V" "vi",
427         "E" "emacs",
428         "C" "noclobber",
429         "a" "allexport",
430         "b" "notify",
431         "u" "nounset",
432         "q" "quietprofile"
433 };
434
435 #define optent_name(optent) (optent+1)
436 #define optent_letter(optent) optent[0]
437 #define optent_val(optent) optet_vals[optent]
438
439 #define eflag optent_val(0)
440 #define fflag optent_val(1)
441 #define Iflag optent_val(2)
442 #define iflag optent_val(3)
443 #define mflag optent_val(4)
444 #define nflag optent_val(5)
445 #define sflag optent_val(6)
446 #define xflag optent_val(7)
447 #define vflag optent_val(8)
448 #define Vflag optent_val(9)
449 #define Eflag optent_val(10)
450 #define Cflag optent_val(11)
451 #define aflag optent_val(12)
452 #define bflag optent_val(13)
453 #define uflag optent_val(14)
454 #define qflag optent_val(15)
455
456
457 /* Mode argument to forkshell.  Don't change FORK_FG or FORK_BG. */
458 #define FORK_FG 0
459 #define FORK_BG 1
460 #define FORK_NOJOB 2
461
462
463 struct nbinary {
464       int type;
465       union node *ch1;
466       union node *ch2;
467 };
468
469
470 struct ncmd {
471       int type;
472       int backgnd;
473       union node *assign;
474       union node *args;
475       union node *redirect;
476 };
477
478
479 struct npipe {
480       int type;
481       int backgnd;
482       struct nodelist *cmdlist;
483 };
484
485
486 struct nredir {
487       int type;
488       union node *n;
489       union node *redirect;
490 };
491
492
493 struct nif {
494       int type;
495       union node *test;
496       union node *ifpart;
497       union node *elsepart;
498 };
499
500
501 struct nfor {
502       int type;
503       union node *args;
504       union node *body;
505       char *var;
506 };
507
508
509 struct ncase {
510       int type;
511       union node *expr;
512       union node *cases;
513 };
514
515
516 struct nclist {
517       int type;
518       union node *next;
519       union node *pattern;
520       union node *body;
521 };
522
523
524 struct narg {
525       int type;
526       union node *next;
527       char *text;
528       struct nodelist *backquote;
529 };
530
531
532 struct nfile {
533       int type;
534       union node *next;
535       int fd;
536       union node *fname;
537       char *expfname;
538 };
539
540
541 struct ndup {
542       int type;
543       union node *next;
544       int fd;
545       int dupfd;
546       union node *vname;
547 };
548
549
550 struct nhere {
551       int type;
552       union node *next;
553       int fd;
554       union node *doc;
555 };
556
557
558 struct nnot {
559       int type;
560       union node *com;
561 };
562
563
564 union node {
565       int type;
566       struct nbinary nbinary;
567       struct ncmd ncmd;
568       struct npipe npipe;
569       struct nredir nredir;
570       struct nif nif;
571       struct nfor nfor;
572       struct ncase ncase;
573       struct nclist nclist;
574       struct narg narg;
575       struct nfile nfile;
576       struct ndup ndup;
577       struct nhere nhere;
578       struct nnot nnot;
579 };
580
581
582 struct nodelist {
583         struct nodelist *next;
584         union node *n;
585 };
586
587 struct backcmd {                /* result of evalbackcmd */
588         int fd;                 /* file descriptor to read from */
589         char *buf;              /* buffer */
590         int nleft;              /* number of chars in buffer */
591         struct job *jp;         /* job structure for command */
592 };
593
594 struct cmdentry {
595         int cmdtype;
596         union param {
597                 int index;
598                 union node *func;
599                 const struct builtincmd *cmd;
600         } u;
601 };
602
603 struct strlist {
604         struct strlist *next;
605         char *text;
606 };
607
608
609 struct arglist {
610         struct strlist *list;
611         struct strlist **lastp;
612 };
613
614 struct strpush {
615         struct strpush *prev;   /* preceding string on stack */
616         char *prevstring;
617         int prevnleft;
618 #ifdef ASH_ALIAS
619         struct alias *ap;       /* if push was associated with an alias */
620 #endif
621         char *string;           /* remember the string since it may change */
622 };
623
624 struct parsefile {
625         struct parsefile *prev; /* preceding file on stack */
626         int linno;              /* current line */
627         int fd;                 /* file descriptor (or -1 if string) */
628         int nleft;              /* number of chars left in this line */
629         int lleft;              /* number of chars left in this buffer */
630         char *nextc;            /* next char in buffer */
631         char *buf;              /* input buffer */
632         struct strpush *strpush; /* for pushing strings at this level */
633         struct strpush basestrpush; /* so pushing one is fast */
634 };
635
636 struct stackmark {
637         struct stack_block *stackp;
638         char *stacknxt;
639         int stacknleft;
640         struct stackmark *marknext;
641 };
642
643 struct shparam {
644         int nparam;             /* # of positional parameters (without $0) */
645         unsigned char malloc;   /* if parameter list dynamically allocated */
646         char **p;               /* parameter list */
647         int optind;             /* next parameter to be processed by getopts */
648         int optoff;             /* used by getopts */
649 };
650
651 /*
652  * When commands are first encountered, they are entered in a hash table.
653  * This ensures that a full path search will not have to be done for them
654  * on each invocation.
655  *
656  * We should investigate converting to a linear search, even though that
657  * would make the command name "hash" a misnomer.
658  */
659 #define CMDTABLESIZE 31         /* should be prime */
660 #define ARB 1                   /* actual size determined at run time */
661
662
663
664 struct tblentry {
665         struct tblentry *next;  /* next entry in hash chain */
666         union param param;      /* definition of builtin function */
667         short cmdtype;          /* index identifying command */
668         char rehash;            /* if set, cd done since entry created */
669         char cmdname[ARB];      /* name of command */
670 };
671
672
673 static struct tblentry *cmdtable[CMDTABLESIZE];
674 static int builtinloc = -1;             /* index in path of %builtin, or -1 */
675 static int exerrno = 0;                 /* Last exec error */
676
677
678 static void tryexec (char *, char **, char **);
679 static void printentry (struct tblentry *, int);
680 static void clearcmdentry (int);
681 static struct tblentry *cmdlookup (const char *, int);
682 static void delete_cmd_entry (void);
683 static int path_change (const char *, int *);
684
685
686 static void flushall (void);
687 static void out2fmt (const char *, ...)
688     __attribute__((__format__(__printf__,1,2)));
689 static int xwrite (int, const char *, int);
690
691 static void outstr (const char *p, FILE *file) { fputs(p, file); }
692 static void out1str(const char *p) { outstr(p, stdout); }
693 static void out2str(const char *p) { outstr(p, stderr); }
694
695 #ifndef ASH_OPTIMIZE_FOR_SIZE
696 #define out2c(c)        putc((c), stderr)
697 #else
698 static void out2c(int c)           { putc(c, stderr); }
699 #endif
700
701 /* syntax table used when not in quotes */
702 static const char basesyntax[257] = {
703       CENDFILE,   CSPCL,   CWORD,   CCTL,
704       CCTL,    CCTL,    CCTL,    CCTL,
705       CCTL,    CCTL,    CCTL,    CWORD,
706       CWORD,   CWORD,   CWORD,   CWORD,
707       CWORD,   CWORD,   CWORD,   CWORD,
708       CWORD,   CWORD,   CWORD,   CWORD,
709       CWORD,   CWORD,   CWORD,   CWORD,
710       CWORD,   CWORD,   CWORD,   CWORD,
711       CWORD,   CWORD,   CWORD,   CWORD,
712       CWORD,   CWORD,   CWORD,   CWORD,
713       CWORD,   CWORD,   CWORD,   CWORD,
714       CWORD,   CWORD,   CWORD,   CWORD,
715       CWORD,   CWORD,   CWORD,   CWORD,
716       CWORD,   CWORD,   CWORD,   CWORD,
717       CWORD,   CWORD,   CWORD,   CWORD,
718       CWORD,   CWORD,   CWORD,   CWORD,
719       CWORD,   CWORD,   CWORD,   CWORD,
720       CWORD,   CWORD,   CWORD,   CWORD,
721       CWORD,   CWORD,   CWORD,   CWORD,
722       CWORD,   CWORD,   CWORD,   CWORD,
723       CWORD,   CWORD,   CWORD,   CWORD,
724       CWORD,   CWORD,   CWORD,   CWORD,
725       CWORD,   CWORD,   CWORD,   CWORD,
726       CWORD,   CWORD,   CWORD,   CWORD,
727       CWORD,   CWORD,   CWORD,   CWORD,
728       CWORD,   CWORD,   CWORD,   CWORD,
729       CWORD,   CWORD,   CWORD,   CWORD,
730       CWORD,   CWORD,   CWORD,   CWORD,
731       CWORD,   CWORD,   CWORD,   CWORD,
732       CWORD,   CWORD,   CWORD,   CWORD,
733       CWORD,   CWORD,   CWORD,   CWORD,
734       CWORD,   CWORD,   CWORD,   CWORD,
735       CWORD,   CWORD,   CWORD,   CWORD,
736       CWORD,   CWORD,   CWORD,   CWORD,
737       CWORD,   CWORD,   CWORD,   CSPCL,
738       CNL,     CWORD,   CWORD,   CWORD,
739       CWORD,   CWORD,   CWORD,   CWORD,
740       CWORD,   CWORD,   CWORD,   CWORD,
741       CWORD,   CWORD,   CWORD,   CWORD,
742       CWORD,   CWORD,   CWORD,   CWORD,
743       CWORD,   CWORD,   CSPCL,   CWORD,
744       CDQUOTE, CWORD,   CVAR,    CWORD,
745       CSPCL,   CSQUOTE, CSPCL,   CSPCL,
746       CWORD,   CWORD,   CWORD,   CWORD,
747       CWORD,   CWORD,   CWORD,   CWORD,
748       CWORD,   CWORD,   CWORD,   CWORD,
749       CWORD,   CWORD,   CWORD,   CWORD,
750       CWORD,   CSPCL,   CSPCL,   CWORD,
751       CSPCL,   CWORD,   CWORD,   CWORD,
752       CWORD,   CWORD,   CWORD,   CWORD,
753       CWORD,   CWORD,   CWORD,   CWORD,
754       CWORD,   CWORD,   CWORD,   CWORD,
755       CWORD,   CWORD,   CWORD,   CWORD,
756       CWORD,   CWORD,   CWORD,   CWORD,
757       CWORD,   CWORD,   CWORD,   CWORD,
758       CWORD,   CWORD,   CBACK,   CWORD,
759       CWORD,   CWORD,   CBQUOTE, CWORD,
760       CWORD,   CWORD,   CWORD,   CWORD,
761       CWORD,   CWORD,   CWORD,   CWORD,
762       CWORD,   CWORD,   CWORD,   CWORD,
763       CWORD,   CWORD,   CWORD,   CWORD,
764       CWORD,   CWORD,   CWORD,   CWORD,
765       CWORD,   CWORD,   CWORD,   CWORD,
766       CWORD,   CWORD,   CSPCL,   CENDVAR,
767       CWORD
768 };
769
770 /* syntax table used when in double quotes */
771 static const char dqsyntax[257] = {
772       CENDFILE,   CIGN,    CWORD,   CCTL,
773       CCTL,    CCTL,    CCTL,    CCTL,
774       CCTL,    CCTL,    CCTL,    CWORD,
775       CWORD,   CWORD,   CWORD,   CWORD,
776       CWORD,   CWORD,   CWORD,   CWORD,
777       CWORD,   CWORD,   CWORD,   CWORD,
778       CWORD,   CWORD,   CWORD,   CWORD,
779       CWORD,   CWORD,   CWORD,   CWORD,
780       CWORD,   CWORD,   CWORD,   CWORD,
781       CWORD,   CWORD,   CWORD,   CWORD,
782       CWORD,   CWORD,   CWORD,   CWORD,
783       CWORD,   CWORD,   CWORD,   CWORD,
784       CWORD,   CWORD,   CWORD,   CWORD,
785       CWORD,   CWORD,   CWORD,   CWORD,
786       CWORD,   CWORD,   CWORD,   CWORD,
787       CWORD,   CWORD,   CWORD,   CWORD,
788       CWORD,   CWORD,   CWORD,   CWORD,
789       CWORD,   CWORD,   CWORD,   CWORD,
790       CWORD,   CWORD,   CWORD,   CWORD,
791       CWORD,   CWORD,   CWORD,   CWORD,
792       CWORD,   CWORD,   CWORD,   CWORD,
793       CWORD,   CWORD,   CWORD,   CWORD,
794       CWORD,   CWORD,   CWORD,   CWORD,
795       CWORD,   CWORD,   CWORD,   CWORD,
796       CWORD,   CWORD,   CWORD,   CWORD,
797       CWORD,   CWORD,   CWORD,   CWORD,
798       CWORD,   CWORD,   CWORD,   CWORD,
799       CWORD,   CWORD,   CWORD,   CWORD,
800       CWORD,   CWORD,   CWORD,   CWORD,
801       CWORD,   CWORD,   CWORD,   CWORD,
802       CWORD,   CWORD,   CWORD,   CWORD,
803       CWORD,   CWORD,   CWORD,   CWORD,
804       CWORD,   CWORD,   CWORD,   CWORD,
805       CWORD,   CWORD,   CWORD,   CWORD,
806       CWORD,   CWORD,   CWORD,   CWORD,
807       CNL,     CWORD,   CWORD,   CWORD,
808       CWORD,   CWORD,   CWORD,   CWORD,
809       CWORD,   CWORD,   CWORD,   CWORD,
810       CWORD,   CWORD,   CWORD,   CWORD,
811       CWORD,   CWORD,   CWORD,   CWORD,
812       CWORD,   CWORD,   CWORD,   CCTL,
813       CENDQUOTE,CWORD,  CVAR,    CWORD,
814       CWORD,   CWORD,   CWORD,   CWORD,
815       CCTL,    CWORD,   CWORD,   CCTL,
816       CWORD,   CCTL,    CWORD,   CWORD,
817       CWORD,   CWORD,   CWORD,   CWORD,
818       CWORD,   CWORD,   CWORD,   CWORD,
819       CCTL,    CWORD,   CWORD,   CCTL,
820       CWORD,   CCTL,    CWORD,   CWORD,
821       CWORD,   CWORD,   CWORD,   CWORD,
822       CWORD,   CWORD,   CWORD,   CWORD,
823       CWORD,   CWORD,   CWORD,   CWORD,
824       CWORD,   CWORD,   CWORD,   CWORD,
825       CWORD,   CWORD,   CWORD,   CWORD,
826       CWORD,   CWORD,   CWORD,   CWORD,
827       CWORD,   CCTL,    CBACK,   CCTL,
828       CWORD,   CWORD,   CBQUOTE, CWORD,
829       CWORD,   CWORD,   CWORD,   CWORD,
830       CWORD,   CWORD,   CWORD,   CWORD,
831       CWORD,   CWORD,   CWORD,   CWORD,
832       CWORD,   CWORD,   CWORD,   CWORD,
833       CWORD,   CWORD,   CWORD,   CWORD,
834       CWORD,   CWORD,   CWORD,   CWORD,
835       CWORD,   CWORD,   CWORD,   CENDVAR,
836       CCTL
837 };
838
839 /* syntax table used when in single quotes */
840 static const char sqsyntax[257] = {
841       CENDFILE,   CIGN,    CWORD,   CCTL,
842       CCTL,    CCTL,    CCTL,    CCTL,
843       CCTL,    CCTL,    CCTL,    CWORD,
844       CWORD,   CWORD,   CWORD,   CWORD,
845       CWORD,   CWORD,   CWORD,   CWORD,
846       CWORD,   CWORD,   CWORD,   CWORD,
847       CWORD,   CWORD,   CWORD,   CWORD,
848       CWORD,   CWORD,   CWORD,   CWORD,
849       CWORD,   CWORD,   CWORD,   CWORD,
850       CWORD,   CWORD,   CWORD,   CWORD,
851       CWORD,   CWORD,   CWORD,   CWORD,
852       CWORD,   CWORD,   CWORD,   CWORD,
853       CWORD,   CWORD,   CWORD,   CWORD,
854       CWORD,   CWORD,   CWORD,   CWORD,
855       CWORD,   CWORD,   CWORD,   CWORD,
856       CWORD,   CWORD,   CWORD,   CWORD,
857       CWORD,   CWORD,   CWORD,   CWORD,
858       CWORD,   CWORD,   CWORD,   CWORD,
859       CWORD,   CWORD,   CWORD,   CWORD,
860       CWORD,   CWORD,   CWORD,   CWORD,
861       CWORD,   CWORD,   CWORD,   CWORD,
862       CWORD,   CWORD,   CWORD,   CWORD,
863       CWORD,   CWORD,   CWORD,   CWORD,
864       CWORD,   CWORD,   CWORD,   CWORD,
865       CWORD,   CWORD,   CWORD,   CWORD,
866       CWORD,   CWORD,   CWORD,   CWORD,
867       CWORD,   CWORD,   CWORD,   CWORD,
868       CWORD,   CWORD,   CWORD,   CWORD,
869       CWORD,   CWORD,   CWORD,   CWORD,
870       CWORD,   CWORD,   CWORD,   CWORD,
871       CWORD,   CWORD,   CWORD,   CWORD,
872       CWORD,   CWORD,   CWORD,   CWORD,
873       CWORD,   CWORD,   CWORD,   CWORD,
874       CWORD,   CWORD,   CWORD,   CWORD,
875       CWORD,   CWORD,   CWORD,   CWORD,
876       CNL,     CWORD,   CWORD,   CWORD,
877       CWORD,   CWORD,   CWORD,   CWORD,
878       CWORD,   CWORD,   CWORD,   CWORD,
879       CWORD,   CWORD,   CWORD,   CWORD,
880       CWORD,   CWORD,   CWORD,   CWORD,
881       CWORD,   CWORD,   CWORD,   CCTL,
882       CWORD,   CWORD,   CWORD,   CWORD,
883       CWORD,   CENDQUOTE,CWORD,  CWORD,
884       CCTL,    CWORD,   CWORD,   CCTL,
885       CWORD,   CCTL,    CWORD,   CWORD,
886       CWORD,   CWORD,   CWORD,   CWORD,
887       CWORD,   CWORD,   CWORD,   CWORD,
888       CCTL,    CWORD,   CWORD,   CCTL,
889       CWORD,   CCTL,    CWORD,   CWORD,
890       CWORD,   CWORD,   CWORD,   CWORD,
891       CWORD,   CWORD,   CWORD,   CWORD,
892       CWORD,   CWORD,   CWORD,   CWORD,
893       CWORD,   CWORD,   CWORD,   CWORD,
894       CWORD,   CWORD,   CWORD,   CWORD,
895       CWORD,   CWORD,   CWORD,   CWORD,
896       CWORD,   CCTL,    CCTL,    CCTL,
897       CWORD,   CWORD,   CWORD,   CWORD,
898       CWORD,   CWORD,   CWORD,   CWORD,
899       CWORD,   CWORD,   CWORD,   CWORD,
900       CWORD,   CWORD,   CWORD,   CWORD,
901       CWORD,   CWORD,   CWORD,   CWORD,
902       CWORD,   CWORD,   CWORD,   CWORD,
903       CWORD,   CWORD,   CWORD,   CWORD,
904       CWORD,   CWORD,   CWORD,   CWORD,
905       CCTL
906 };
907
908 /* syntax table used when in arithmetic */
909 static const char arisyntax[257] = {
910       CENDFILE,   CIGN,    CWORD,   CCTL,
911       CCTL,    CCTL,    CCTL,    CCTL,
912       CCTL,    CCTL,    CCTL,    CWORD,
913       CWORD,   CWORD,   CWORD,   CWORD,
914       CWORD,   CWORD,   CWORD,   CWORD,
915       CWORD,   CWORD,   CWORD,   CWORD,
916       CWORD,   CWORD,   CWORD,   CWORD,
917       CWORD,   CWORD,   CWORD,   CWORD,
918       CWORD,   CWORD,   CWORD,   CWORD,
919       CWORD,   CWORD,   CWORD,   CWORD,
920       CWORD,   CWORD,   CWORD,   CWORD,
921       CWORD,   CWORD,   CWORD,   CWORD,
922       CWORD,   CWORD,   CWORD,   CWORD,
923       CWORD,   CWORD,   CWORD,   CWORD,
924       CWORD,   CWORD,   CWORD,   CWORD,
925       CWORD,   CWORD,   CWORD,   CWORD,
926       CWORD,   CWORD,   CWORD,   CWORD,
927       CWORD,   CWORD,   CWORD,   CWORD,
928       CWORD,   CWORD,   CWORD,   CWORD,
929       CWORD,   CWORD,   CWORD,   CWORD,
930       CWORD,   CWORD,   CWORD,   CWORD,
931       CWORD,   CWORD,   CWORD,   CWORD,
932       CWORD,   CWORD,   CWORD,   CWORD,
933       CWORD,   CWORD,   CWORD,   CWORD,
934       CWORD,   CWORD,   CWORD,   CWORD,
935       CWORD,   CWORD,   CWORD,   CWORD,
936       CWORD,   CWORD,   CWORD,   CWORD,
937       CWORD,   CWORD,   CWORD,   CWORD,
938       CWORD,   CWORD,   CWORD,   CWORD,
939       CWORD,   CWORD,   CWORD,   CWORD,
940       CWORD,   CWORD,   CWORD,   CWORD,
941       CWORD,   CWORD,   CWORD,   CWORD,
942       CWORD,   CWORD,   CWORD,   CWORD,
943       CWORD,   CWORD,   CWORD,   CWORD,
944       CWORD,   CWORD,   CWORD,   CWORD,
945       CNL,     CWORD,   CWORD,   CWORD,
946       CWORD,   CWORD,   CWORD,   CWORD,
947       CWORD,   CWORD,   CWORD,   CWORD,
948       CWORD,   CWORD,   CWORD,   CWORD,
949       CWORD,   CWORD,   CWORD,   CWORD,
950       CWORD,   CWORD,   CWORD,   CWORD,
951       CDQUOTE, CWORD,   CVAR,    CWORD,
952       CWORD,   CSQUOTE, CLP,     CRP,
953       CWORD,   CWORD,   CWORD,   CWORD,
954       CWORD,   CWORD,   CWORD,   CWORD,
955       CWORD,   CWORD,   CWORD,   CWORD,
956       CWORD,   CWORD,   CWORD,   CWORD,
957       CWORD,   CWORD,   CWORD,   CWORD,
958       CWORD,   CWORD,   CWORD,   CWORD,
959       CWORD,   CWORD,   CWORD,   CWORD,
960       CWORD,   CWORD,   CWORD,   CWORD,
961       CWORD,   CWORD,   CWORD,   CWORD,
962       CWORD,   CWORD,   CWORD,   CWORD,
963       CWORD,   CWORD,   CWORD,   CWORD,
964       CWORD,   CWORD,   CWORD,   CWORD,
965       CWORD,   CWORD,   CBACK,   CWORD,
966       CWORD,   CWORD,   CBQUOTE, CWORD,
967       CWORD,   CWORD,   CWORD,   CWORD,
968       CWORD,   CWORD,   CWORD,   CWORD,
969       CWORD,   CWORD,   CWORD,   CWORD,
970       CWORD,   CWORD,   CWORD,   CWORD,
971       CWORD,   CWORD,   CWORD,   CWORD,
972       CWORD,   CWORD,   CWORD,   CWORD,
973       CWORD,   CWORD,   CWORD,   CENDVAR,
974       CWORD
975 };
976
977 /* character classification table */
978 static const char is_type[257] = {
979       0,       0,       0,       0,
980       0,       0,       0,       0,
981       0,       0,       0,       0,
982       0,       0,       0,       0,
983       0,       0,       0,       0,
984       0,       0,       0,       0,
985       0,       0,       0,       0,
986       0,       0,       0,       0,
987       0,       0,       0,       0,
988       0,       0,       0,       0,
989       0,       0,       0,       0,
990       0,       0,       0,       0,
991       0,       0,       0,       0,
992       0,       0,       0,       0,
993       0,       0,       0,       0,
994       0,       0,       0,       0,
995       0,       0,       0,       0,
996       0,       0,       0,       0,
997       0,       0,       0,       0,
998       0,       0,       0,       0,
999       0,       0,       0,       0,
1000       0,       0,       0,       0,
1001       0,       0,       0,       0,
1002       0,       0,       0,       0,
1003       0,       0,       0,       0,
1004       0,       0,       0,       0,
1005       0,       0,       0,       0,
1006       0,       0,       0,       0,
1007       0,       0,       0,       0,
1008       0,       0,       0,       0,
1009       0,       0,       0,       0,
1010       0,       0,       0,       0,
1011       0,       0,       0,       0,
1012       0,       0,       0,       0,
1013       0,       0,       0,       0,
1014       0,       0,       0,       0,
1015       0,       0,       0,       0,
1016       0,       0,       0,       0,
1017       0,       0,       0,       0,
1018       0,       0,       0,       0,
1019       0,       0,       0,       ISSPECL,
1020       0,       ISSPECL, ISSPECL, 0,
1021       0,       0,       0,       0,
1022       ISSPECL, 0,       0,       ISSPECL,
1023       0,       0,       ISDIGIT, ISDIGIT,
1024       ISDIGIT, ISDIGIT, ISDIGIT, ISDIGIT,
1025       ISDIGIT, ISDIGIT, ISDIGIT, ISDIGIT,
1026       0,       0,       0,       0,
1027       0,       ISSPECL, ISSPECL, ISUPPER,
1028       ISUPPER, ISUPPER, ISUPPER, ISUPPER,
1029       ISUPPER, ISUPPER, ISUPPER, ISUPPER,
1030       ISUPPER, ISUPPER, ISUPPER, ISUPPER,
1031       ISUPPER, ISUPPER, ISUPPER, ISUPPER,
1032       ISUPPER, ISUPPER, ISUPPER, ISUPPER,
1033       ISUPPER, ISUPPER, ISUPPER, ISUPPER,
1034       ISUPPER, 0,       0,       0,
1035       0,       ISUNDER, 0,       ISLOWER,
1036       ISLOWER, ISLOWER, ISLOWER, ISLOWER,
1037       ISLOWER, ISLOWER, ISLOWER, ISLOWER,
1038       ISLOWER, ISLOWER, ISLOWER, ISLOWER,
1039       ISLOWER, ISLOWER, ISLOWER, ISLOWER,
1040       ISLOWER, ISLOWER, ISLOWER, ISLOWER,
1041       ISLOWER, ISLOWER, ISLOWER, ISLOWER,
1042       ISLOWER, 0,       0,       0,
1043       0
1044 };
1045
1046 /* Array indicating which tokens mark the end of a list */
1047 static const char tokendlist[] = {
1048         1,
1049         0,
1050         0,
1051         0,
1052         0,
1053         0,
1054         0,
1055         0,
1056         1,
1057         1,
1058         1,
1059         0,
1060         0,
1061         0,
1062         0,
1063         0,
1064         1,
1065         1,
1066         1,
1067         1,
1068         1,
1069         1,
1070         0,
1071         0,
1072         0,
1073         1,
1074         0,
1075         0,
1076         0,
1077         1,
1078 };
1079
1080 static const char *const tokname[] = {
1081         "end of file",
1082         "newline",
1083         "\";\"",
1084         "\"&\"",
1085         "\"&&\"",
1086         "\"||\"",
1087         "\"|\"",
1088         "\"(\"",
1089         "\")\"",
1090         "\";;\"",
1091         "\"`\"",
1092         "redirection",
1093         "word",
1094         "assignment",
1095         "\"!\"",
1096         "\"case\"",
1097         "\"do\"",
1098         "\"done\"",
1099         "\"elif\"",
1100         "\"else\"",
1101         "\"esac\"",
1102         "\"fi\"",
1103         "\"for\"",
1104         "\"if\"",
1105         "\"in\"",
1106         "\"then\"",
1107         "\"until\"",
1108         "\"while\"",
1109         "\"{\"",
1110         "\"}\"",
1111 };
1112
1113 #define KWDOFFSET 14
1114
1115 static const char *const parsekwd[] = {
1116         "!",
1117         "case",
1118         "do",
1119         "done",
1120         "elif",
1121         "else",
1122         "esac",
1123         "fi",
1124         "for",
1125         "if",
1126         "in",
1127         "then",
1128         "until",
1129         "while",
1130         "{",
1131         "}"
1132 };
1133
1134
1135 static int plinno = 1;          /* input line number */
1136
1137 static int parselleft;          /* copy of parsefile->lleft */
1138
1139 static struct parsefile basepf; /* top level input file */
1140 static char basebuf[BUFSIZ];    /* buffer for top level input file */
1141 static struct parsefile *parsefile = &basepf;  /* current input file */
1142
1143 /*
1144  * NEOF is returned by parsecmd when it encounters an end of file.  It
1145  * must be distinct from NULL, so we use the address of a variable that
1146  * happens to be handy.
1147  */
1148
1149 static int tokpushback;         /* last token pushed back */
1150 #define NEOF ((union node *)&tokpushback)
1151 static int checkkwd;            /* 1 == check for kwds, 2 == also eat newlines */
1152
1153
1154 static void error (const char *, ...) __attribute__((__noreturn__));
1155 static void exerror (int, const char *, ...) __attribute__((__noreturn__));
1156 static void shellexec (char **, char **, const char *, int)
1157     __attribute__((noreturn));
1158 static void exitshell (int) __attribute__((noreturn));
1159
1160 static int  goodname(const char *);
1161 static void ignoresig (int);
1162 static void onsig (int);
1163 static void dotrap (void);
1164 static int  decode_signal (const char *, int);
1165
1166 static void shprocvar(void);
1167 static void deletefuncs(void);
1168 static void setparam (char **);
1169 static void freeparam (volatile struct shparam *);
1170
1171 /* reasons for skipping commands (see comment on breakcmd routine) */
1172 #define SKIPBREAK       1
1173 #define SKIPCONT        2
1174 #define SKIPFUNC        3
1175 #define SKIPFILE        4
1176
1177 /* values of cmdtype */
1178 #define CMDUNKNOWN -1           /* no entry in table for command */
1179 #define CMDNORMAL 0             /* command is an executable program */
1180 #define CMDBUILTIN 1            /* command is a shell builtin */
1181 #define CMDFUNCTION 2           /* command is a shell function */
1182
1183 #define DO_ERR  1               /* find_command prints errors */
1184 #define DO_ABS  2               /* find_command checks absolute paths */
1185 #define DO_NOFUN        4       /* find_command ignores functions */
1186 #define DO_BRUTE        8       /* find_command ignores hash table */
1187
1188 /*
1189  * Shell variables.
1190  */
1191
1192 /* flags */
1193 #define VEXPORT         0x01    /* variable is exported */
1194 #define VREADONLY       0x02    /* variable cannot be modified */
1195 #define VSTRFIXED       0x04    /* variable struct is staticly allocated */
1196 #define VTEXTFIXED      0x08    /* text is staticly allocated */
1197 #define VSTACK          0x10    /* text is allocated on the stack */
1198 #define VUNSET          0x20    /* the variable is not set */
1199 #define VNOFUNC         0x40    /* don't call the callback function */
1200
1201
1202 struct var {
1203         struct var *next;               /* next entry in hash list */
1204         int flags;                      /* flags are defined above */
1205         char *text;                     /* name=value */
1206         void (*func) (const char *);
1207                                         /* function to be called when  */
1208                                         /* the variable gets set/unset */
1209 };
1210
1211 struct localvar {
1212         struct localvar *next;          /* next local variable in list */
1213         struct var *vp;                 /* the variable that was made local */
1214         int flags;                      /* saved flags */
1215         char *text;                     /* saved text */
1216 };
1217
1218
1219 #if defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(FNMATCH_BROKEN)
1220 #define rmescapes(p) _rmescapes((p), 0)
1221 static char *_rmescapes (char *, int);
1222 #else
1223 static void rmescapes (char *);
1224 #endif
1225
1226 static int  casematch (union node *, const char *);
1227 static void clearredir(void);
1228 static void popstring(void);
1229 static void readcmdfile (const char *);
1230
1231 static int number (const char *);
1232 static int is_number (const char *, int *num);
1233 static char *single_quote (const char *);
1234 static int nextopt (const char *);
1235
1236 static void redirect (union node *, int);
1237 static void popredir (void);
1238 static int dup_as_newfd (int, int);
1239
1240 static void changepath(const char *newval);
1241 static void getoptsreset(const char *value);
1242
1243
1244 static int parsenleft;                  /* copy of parsefile->nleft */
1245 static char *parsenextc;                /* copy of parsefile->nextc */
1246 static int rootpid;     /* pid of main shell */
1247 static int rootshell;   /* true if we aren't a child of the main shell */
1248
1249 static const char spcstr[] = " ";
1250 static const char snlfmt[] = "%s\n";
1251
1252 static int sstrnleft;
1253 static int herefd = -1;
1254
1255 static struct localvar *localvars;
1256
1257 static struct var vifs;
1258 static struct var vmail;
1259 static struct var vmpath;
1260 static struct var vpath;
1261 static struct var vps1;
1262 static struct var vps2;
1263 static struct var voptind;
1264 #ifdef BB_LOCALE_SUPPORT
1265 static struct var vlc_all;
1266 static struct var vlc_ctype;
1267 #endif
1268
1269 struct varinit {
1270         struct var *var;
1271         int flags;
1272         const char *text;
1273         void (*func) (const char *);
1274 };
1275
1276 static const char defpathvar[] =
1277         "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin";
1278 #define defpath (defpathvar + 5)
1279
1280 #ifdef IFS_BROKEN
1281 static const char defifsvar[] = "IFS= \t\n";
1282 #define defifs (defifsvar + 4)
1283 #else
1284 static const char defifs[] = " \t\n";
1285 #endif
1286
1287 static const struct varinit varinit[] = {
1288 #ifdef IFS_BROKEN
1289         { &vifs,        VSTRFIXED|VTEXTFIXED,           defifsvar,
1290 #else
1291         { &vifs,        VSTRFIXED|VTEXTFIXED|VUNSET,    "IFS=",
1292 #endif
1293           NULL },
1294         { &vmail,       VSTRFIXED|VTEXTFIXED|VUNSET,    "MAIL=",
1295           NULL },
1296         { &vmpath,      VSTRFIXED|VTEXTFIXED|VUNSET,    "MAILPATH=",
1297           NULL },
1298         { &vpath,       VSTRFIXED|VTEXTFIXED,           defpathvar,
1299           changepath },
1300         /*
1301          * vps1 depends on uid
1302          */
1303         { &vps2,        VSTRFIXED|VTEXTFIXED,           "PS2=> ",
1304           NULL },
1305         { &voptind,     VSTRFIXED|VTEXTFIXED,           "OPTIND=1",
1306           getoptsreset },
1307 #ifdef BB_LOCALE_SUPPORT
1308         { &vlc_all,     VSTRFIXED|VTEXTFIXED|VUNSET,    "LC_ALL=",
1309           change_lc_all },
1310         { &vlc_ctype,   VSTRFIXED|VTEXTFIXED|VUNSET,    "LC_CTYPE=",
1311           change_lc_ctype },
1312 #endif
1313         { NULL, 0,                              NULL,
1314           NULL }
1315 };
1316
1317 #define VTABSIZE 39
1318
1319 static struct var *vartab[VTABSIZE];
1320
1321 /*
1322  * The following macros access the values of the above variables.
1323  * They have to skip over the name.  They return the null string
1324  * for unset variables.
1325  */
1326
1327 #define ifsval()        (vifs.text + 4)
1328 #define ifsset()        ((vifs.flags & VUNSET) == 0)
1329 #define mailval()       (vmail.text + 5)
1330 #define mpathval()      (vmpath.text + 9)
1331 #define pathval()       (vpath.text + 5)
1332 #define ps1val()        (vps1.text + 4)
1333 #define ps2val()        (vps2.text + 4)
1334 #define optindval()     (voptind.text + 7)
1335
1336 #define mpathset()      ((vmpath.flags & VUNSET) == 0)
1337
1338 static void initvar (void);
1339 static void setvar (const char *, const char *, int);
1340 static void setvareq (char *, int);
1341 static void listsetvar (struct strlist *);
1342 static const char *lookupvar (const char *);
1343 static const char *bltinlookup (const char *);
1344 static char **environment (void);
1345 static int showvarscmd (int, char **);
1346 static void mklocal (char *);
1347 static void poplocalvars (void);
1348 static int unsetvar (const char *);
1349 static int varequal (const char *, const char *);
1350
1351
1352 static char *arg0;                      /* value of $0 */
1353 static struct shparam shellparam;       /* current positional parameters */
1354 static char **argptr;                   /* argument list for builtin commands */
1355 static char *optionarg;                 /* set by nextopt (like getopt) */
1356 static char *optptr;                    /* used by nextopt */
1357 static char *minusc;                    /* argument to -c option */
1358
1359
1360 #ifdef ASH_ALIAS
1361
1362 #define ALIASINUSE      1
1363 #define ALIASDEAD       2
1364
1365 #define ATABSIZE 39
1366
1367 struct alias {
1368         struct alias *next;
1369         char *name;
1370         char *val;
1371         int flag;
1372 };
1373
1374 static struct alias *atab[ATABSIZE];
1375
1376 static void setalias (char *, char *);
1377 static struct alias **hashalias (const char *);
1378 static struct alias *freealias (struct alias *);
1379 static struct alias **__lookupalias (const char *);
1380
1381 static void
1382 setalias(name, val)
1383         char *name, *val;
1384 {
1385         struct alias *ap, **app;
1386
1387         app = __lookupalias(name);
1388         ap = *app;
1389         INTOFF;
1390         if (ap) {
1391                 if (!(ap->flag & ALIASINUSE)) {
1392                         ckfree(ap->val);
1393                 }
1394                 ap->val = savestr(val);
1395                 ap->flag &= ~ALIASDEAD;
1396         } else {
1397                 /* not found */
1398                 ap = ckmalloc(sizeof (struct alias));
1399                 ap->name = savestr(name);
1400                 ap->val = savestr(val);
1401                 ap->flag = 0;
1402                 ap->next = 0;
1403                 *app = ap;
1404         }
1405         INTON;
1406 }
1407
1408 static int
1409 unalias(char *name)
1410 {
1411         struct alias **app;
1412
1413         app = __lookupalias(name);
1414
1415         if (*app) {
1416                 INTOFF;
1417                 *app = freealias(*app);
1418                 INTON;
1419                 return (0);
1420         }
1421
1422         return (1);
1423 }
1424
1425 static void
1426 rmaliases(void)
1427 {
1428         struct alias *ap, **app;
1429         int i;
1430
1431         INTOFF;
1432         for (i = 0; i < ATABSIZE; i++) {
1433                 app = &atab[i];
1434                 for (ap = *app; ap; ap = *app) {
1435                         *app = freealias(*app);
1436                         if (ap == *app) {
1437                                 app = &ap->next;
1438                         }
1439                 }
1440         }
1441         INTON;
1442 }
1443
1444 static struct alias *
1445 lookupalias(const char *name, int check)
1446 {
1447         struct alias *ap = *__lookupalias(name);
1448
1449         if (check && ap && (ap->flag & ALIASINUSE))
1450                 return (NULL);
1451         return (ap);
1452 }
1453
1454 static void
1455 printalias(const struct alias *ap) {
1456         char *p;
1457
1458         p = single_quote(ap->val);
1459         printf("alias %s=%s\n", ap->name, p);
1460         stunalloc(p);
1461 }
1462
1463
1464 /*
1465  * TODO - sort output
1466  */
1467 static int
1468 aliascmd(int argc, char **argv)
1469 {
1470         char *n, *v;
1471         int ret = 0;
1472         struct alias *ap;
1473
1474         if (argc == 1) {
1475                 int i;
1476
1477                 for (i = 0; i < ATABSIZE; i++)
1478                         for (ap = atab[i]; ap; ap = ap->next) {
1479                                 printalias(ap);
1480                         }
1481                 return (0);
1482         }
1483         while ((n = *++argv) != NULL) {
1484                 if ((v = strchr(n+1, '=')) == NULL) { /* n+1: funny ksh stuff */
1485                         if ((ap = *__lookupalias(n)) == NULL) {
1486                                 out2fmt("%s: %s not found\n", "alias", n);
1487                                 ret = 1;
1488                         } else
1489                                 printalias(ap);
1490                 }
1491                 else {
1492                         *v++ = '\0';
1493                         setalias(n, v);
1494                 }
1495         }
1496
1497         return (ret);
1498 }
1499
1500 static int
1501 unaliascmd(int argc, char **argv)
1502 {
1503         int i;
1504
1505         while ((i = nextopt("a")) != '\0') {
1506                 if (i == 'a') {
1507                         rmaliases();
1508                         return (0);
1509                 }
1510         }
1511         for (i = 0; *argptr; argptr++) {
1512                 if (unalias(*argptr)) {
1513                         out2fmt("%s: %s not found\n", "unalias", *argptr);
1514                         i = 1;
1515                 }
1516         }
1517
1518         return (i);
1519 }
1520
1521 static struct alias **
1522 hashalias(p)
1523         const char *p;
1524         {
1525         unsigned int hashval;
1526
1527         hashval = *p << 4;
1528         while (*p)
1529                 hashval+= *p++;
1530         return &atab[hashval % ATABSIZE];
1531 }
1532
1533 static struct alias *
1534 freealias(struct alias *ap) {
1535         struct alias *next;
1536
1537         if (ap->flag & ALIASINUSE) {
1538                 ap->flag |= ALIASDEAD;
1539                 return ap;
1540         }
1541
1542         next = ap->next;
1543         ckfree(ap->name);
1544         ckfree(ap->val);
1545         ckfree(ap);
1546         return next;
1547 }
1548
1549
1550 static struct alias **
1551 __lookupalias(const char *name) {
1552         struct alias **app = hashalias(name);
1553
1554         for (; *app; app = &(*app)->next) {
1555                 if (equal(name, (*app)->name)) {
1556                         break;
1557                 }
1558         }
1559
1560         return app;
1561 }
1562 #endif
1563
1564 #ifdef ASH_MATH_SUPPORT
1565 /* The generated file arith.c has been snipped.  If you want this
1566  * stuff back in, feel free to add it to your own copy.  */
1567 #define ARITH_NUM 257
1568 #define ARITH_LPAREN 258
1569 #define ARITH_RPAREN 259
1570 #define ARITH_OR 260
1571 #define ARITH_AND 261
1572 #define ARITH_BOR 262
1573 #define ARITH_BXOR 263
1574 #define ARITH_BAND 264
1575 #define ARITH_EQ 265
1576 #define ARITH_NE 266
1577 #define ARITH_LT 267
1578 #define ARITH_GT 268
1579 #define ARITH_GE 269
1580 #define ARITH_LE 270
1581 #define ARITH_LSHIFT 271
1582 #define ARITH_RSHIFT 272
1583 #define ARITH_ADD 273
1584 #define ARITH_SUB 274
1585 #define ARITH_MUL 275
1586 #define ARITH_DIV 276
1587 #define ARITH_REM 277
1588 #define ARITH_UNARYMINUS 278
1589 #define ARITH_UNARYPLUS 279
1590 #define ARITH_NOT 280
1591 #define ARITH_BNOT 281
1592
1593 static void expari (int);
1594 /* From arith.y */
1595 static int arith (const char *);
1596 static int expcmd (int , char **);
1597 static void arith_lex_reset (void);
1598 static int yylex (void);
1599
1600 #endif
1601
1602 static char *trap[NSIG];                /* trap handler commands */
1603 static char sigmode[NSIG - 1];  /* current value of signal */
1604 static char gotsig[NSIG - 1];           /* indicates specified signal received */
1605 static int pendingsigs;                 /* indicates some signal received */
1606
1607 /*
1608  * This file was generated by the mkbuiltins program.
1609  */
1610
1611 #ifdef JOBS
1612 static int bgcmd (int, char **);
1613 static int fgcmd (int, char **);
1614 static int killcmd (int, char **);
1615 #endif
1616 static int bltincmd (int, char **);
1617 static int cdcmd (int, char **);
1618 static int breakcmd (int, char **);
1619 #ifdef ASH_CMDCMD
1620 static int commandcmd (int, char **);
1621 #endif
1622 static int dotcmd (int, char **);
1623 static int evalcmd (int, char **);
1624 static int execcmd (int, char **);
1625 static int exitcmd (int, char **);
1626 static int exportcmd (int, char **);
1627 static int histcmd (int, char **);
1628 static int hashcmd (int, char **);
1629 static int helpcmd (int, char **);
1630 static int jobscmd (int, char **);
1631 static int localcmd (int, char **);
1632 #ifndef BB_PWD
1633 static int pwdcmd (int, char **);
1634 #endif
1635 static int readcmd (int, char **);
1636 static int returncmd (int, char **);
1637 static int setcmd (int, char **);
1638 static int setvarcmd (int, char **);
1639 static int shiftcmd (int, char **);
1640 static int trapcmd (int, char **);
1641 static int umaskcmd (int, char **);
1642 #ifdef ASH_ALIAS
1643 static int aliascmd (int, char **);
1644 static int unaliascmd (int, char **);
1645 #endif
1646 static int unsetcmd (int, char **);
1647 static int waitcmd (int, char **);
1648 static int ulimitcmd (int, char **);
1649 static int timescmd (int, char **);
1650 #ifdef ASH_MATH_SUPPORT
1651 static int expcmd (int, char **);
1652 #endif
1653 static int typecmd (int, char **);
1654 #ifdef ASH_GETOPTS
1655 static int getoptscmd (int, char **);
1656 #endif
1657
1658 #ifndef BB_TRUE_FALSE
1659 static int true_main (int, char **);
1660 static int false_main (int, char **);
1661 #endif
1662
1663 static void     setpwd (const char *, int);
1664
1665
1666 #define BUILTIN_NOSPEC  "0"
1667 #define BUILTIN_SPECIAL "1"
1668 #define BUILTIN_REGULAR "2"
1669 #define BUILTIN_ASSIGN  "4"
1670 #define BUILTIN_SPEC_ASSG  "5"
1671 #define BUILTIN_REG_ASSG   "6"
1672
1673 #define IS_BUILTIN_SPECIAL(builtincmd) ((builtincmd)->name[0] & 1)
1674 #define IS_BUILTIN_REGULAR(builtincmd) ((builtincmd)->name[0] & 2)
1675 #define IS_BUILTIN_ASSIGN(builtincmd) ((builtincmd)->name[0] & 4)
1676
1677 struct builtincmd {
1678         const char *name;
1679         int (*const builtinfunc) (int, char **);
1680         //unsigned flags;
1681 };
1682
1683
1684 /* It is CRUCIAL that this listing be kept in ascii order, otherwise
1685  * the binary search in find_builtin() will stop working. If you value
1686  * your kneecaps, you'll be sure to *make sure* that any changes made
1687  * to this array result in the listing remaining in ascii order. You
1688  * have been warned.
1689  */
1690 static const struct builtincmd builtincmds[] = {
1691         { BUILTIN_SPECIAL   ".", dotcmd },    /* first, see declare DOTCMD */
1692         { BUILTIN_SPECIAL   ":", true_main },
1693 #ifdef ASH_ALIAS
1694         { BUILTIN_REG_ASSG  "alias", aliascmd },
1695 #endif
1696 #ifdef JOBS
1697         { BUILTIN_REGULAR   "bg", bgcmd },
1698 #endif
1699         { BUILTIN_SPECIAL   "break", breakcmd },
1700         { BUILTIN_SPECIAL   "builtin", bltincmd },
1701         { BUILTIN_REGULAR   "cd", cdcmd },
1702         { BUILTIN_NOSPEC    "chdir", cdcmd },
1703 #ifdef ASH_CMDCMD
1704         { BUILTIN_REGULAR   "command", commandcmd },
1705 #endif
1706         { BUILTIN_SPECIAL   "continue", breakcmd },
1707         { BUILTIN_SPECIAL   "eval", evalcmd },
1708         { BUILTIN_SPECIAL   "exec", execcmd },
1709         { BUILTIN_SPECIAL   "exit", exitcmd },
1710 #ifdef ASH_MATH_SUPPORT
1711         { BUILTIN_NOSPEC    "exp", expcmd },
1712 #endif
1713         { BUILTIN_SPEC_ASSG "export", exportcmd },
1714         { BUILTIN_REGULAR   "false", false_main },
1715         { BUILTIN_REGULAR   "fc", histcmd },
1716 #ifdef JOBS
1717         { BUILTIN_REGULAR   "fg", fgcmd },
1718 #endif
1719 #ifdef ASH_GETOPTS
1720         { BUILTIN_REGULAR   "getopts", getoptscmd },
1721 #endif
1722         { BUILTIN_NOSPEC    "hash", hashcmd },
1723         { BUILTIN_NOSPEC    "help", helpcmd },
1724         { BUILTIN_REGULAR   "jobs", jobscmd },
1725 #ifdef JOBS
1726         { BUILTIN_REGULAR   "kill", killcmd },
1727 #endif
1728 #ifdef ASH_MATH_SUPPORT
1729         { BUILTIN_NOSPEC    "let", expcmd },
1730 #endif
1731         { BUILTIN_ASSIGN    "local", localcmd },
1732 #ifndef BB_PWD
1733         { BUILTIN_NOSPEC    "pwd", pwdcmd },
1734 #endif
1735         { BUILTIN_REGULAR   "read", readcmd },
1736         { BUILTIN_SPEC_ASSG "readonly", exportcmd },
1737         { BUILTIN_SPECIAL   "return", returncmd },
1738         { BUILTIN_SPECIAL   "set", setcmd },
1739         { BUILTIN_NOSPEC    "setvar", setvarcmd },
1740         { BUILTIN_SPECIAL   "shift", shiftcmd },
1741         { BUILTIN_SPECIAL   "times", timescmd },
1742         { BUILTIN_SPECIAL   "trap", trapcmd },
1743         { BUILTIN_REGULAR   "true", true_main },
1744         { BUILTIN_NOSPEC    "type", typecmd },
1745         { BUILTIN_NOSPEC    "ulimit", ulimitcmd },
1746         { BUILTIN_REGULAR   "umask", umaskcmd },
1747 #ifdef ASH_ALIAS
1748         { BUILTIN_REGULAR   "unalias", unaliascmd },
1749 #endif
1750         { BUILTIN_SPECIAL   "unset", unsetcmd },
1751         { BUILTIN_REGULAR   "wait", waitcmd },
1752 };
1753 #define NUMBUILTINS  (sizeof (builtincmds) / sizeof (struct builtincmd) )
1754
1755 static const struct builtincmd *DOTCMD = &builtincmds[0];
1756 static struct builtincmd *BLTINCMD;
1757 static struct builtincmd *EXECCMD;
1758 static struct builtincmd *EVALCMD;
1759
1760 /* states */
1761 #define JOBSTOPPED 1            /* all procs are stopped */
1762 #define JOBDONE 2               /* all procs are completed */
1763
1764 /*
1765  * A job structure contains information about a job.  A job is either a
1766  * single process or a set of processes contained in a pipeline.  In the
1767  * latter case, pidlist will be non-NULL, and will point to a -1 terminated
1768  * array of pids.
1769  */
1770
1771 struct procstat {
1772         pid_t pid;              /* process id */
1773         int status;             /* status flags (defined above) */
1774         char *cmd;              /* text of command being run */
1775 };
1776
1777
1778 static int job_warning;         /* user was warned about stopped jobs */
1779
1780 #ifdef JOBS
1781 static void setjobctl(int enable);
1782 #else
1783 #define setjobctl(on)   /* do nothing */
1784 #endif
1785
1786
1787 struct job {
1788         struct procstat ps0;    /* status of process */
1789         struct procstat *ps;    /* status or processes when more than one */
1790         short nprocs;           /* number of processes */
1791         short pgrp;             /* process group of this job */
1792         char state;             /* true if job is finished */
1793         char used;              /* true if this entry is in used */
1794         char changed;           /* true if status has changed */
1795 #ifdef JOBS
1796         char jobctl;            /* job running under job control */
1797 #endif
1798 };
1799
1800 static struct job *jobtab;      /* array of jobs */
1801 static int njobs;               /* size of array */
1802 static int backgndpid = -1;     /* pid of last background process */
1803 #ifdef JOBS
1804 static int initialpgrp;         /* pgrp of shell on invocation */
1805 static int curjob;              /* current job */
1806 static int jobctl;
1807 #endif
1808 static int intreceived;
1809
1810 static struct job *makejob (const union node *, int);
1811 static int forkshell (struct job *, const union node *, int);
1812 static int waitforjob (struct job *);
1813
1814 static int docd (char *, int);
1815 static char *getcomponent (void);
1816 static void updatepwd (const char *);
1817 static void getpwd (void);
1818
1819 static char *padvance (const char **, const char *);
1820
1821 static char nullstr[1];         /* zero length string */
1822 static char *curdir = nullstr;          /* current working directory */
1823 static char *cdcomppath;
1824
1825 static int
1826 cdcmd(argc, argv)
1827         int argc;
1828         char **argv;
1829 {
1830         const char *dest;
1831         const char *path;
1832         char *p;
1833         struct stat statb;
1834         int print = 0;
1835
1836         nextopt(nullstr);
1837         if ((dest = *argptr) == NULL && (dest = bltinlookup("HOME")) == NULL)
1838                 error("HOME not set");
1839         if (*dest == '\0')
1840                 dest = ".";
1841         if (dest[0] == '-' && dest[1] == '\0') {
1842                 dest = bltinlookup("OLDPWD");
1843                 if (!dest || !*dest) {
1844                         dest = curdir;
1845                 }
1846                 print = 1;
1847                 if (dest)
1848                         print = 1;
1849                 else
1850                         dest = ".";
1851         }
1852         if (*dest == '/' || (path = bltinlookup("CDPATH")) == NULL)
1853                 path = nullstr;
1854         while ((p = padvance(&path, dest)) != NULL) {
1855                 if (stat(p, &statb) >= 0 && S_ISDIR(statb.st_mode)) {
1856                         if (!print) {
1857                                 /*
1858                                  * XXX - rethink
1859                                  */
1860                                 if (p[0] == '.' && p[1] == '/' && p[2] != '\0')
1861                                         p += 2;
1862                                 print = strcmp(p, dest);
1863                         }
1864                         if (docd(p, print) >= 0)
1865                                 return 0;
1866
1867                 }
1868         }
1869         error("can't cd to %s", dest);
1870         /* NOTREACHED */
1871 }
1872
1873
1874 /*
1875  * Actually do the chdir.  In an interactive shell, print the
1876  * directory name if "print" is nonzero.
1877  */
1878
1879 static int
1880 docd(dest, print)
1881         char *dest;
1882         int print;
1883 {
1884         char *p;
1885         char *q;
1886         char *component;
1887         struct stat statb;
1888         int first;
1889         int badstat;
1890
1891         TRACE(("docd(\"%s\", %d) called\n", dest, print));
1892
1893         /*
1894          *  Check each component of the path. If we find a symlink or
1895          *  something we can't stat, clear curdir to force a getcwd()
1896          *  next time we get the value of the current directory.
1897          */
1898         badstat = 0;
1899         cdcomppath = sstrdup(dest);
1900         STARTSTACKSTR(p);
1901         if (*dest == '/') {
1902                 STPUTC('/', p);
1903                 cdcomppath++;
1904         }
1905         first = 1;
1906         while ((q = getcomponent()) != NULL) {
1907                 if (q[0] == '\0' || (q[0] == '.' && q[1] == '\0'))
1908                         continue;
1909                 if (! first)
1910                         STPUTC('/', p);
1911                 first = 0;
1912                 component = q;
1913                 while (*q)
1914                         STPUTC(*q++, p);
1915                 if (equal(component, ".."))
1916                         continue;
1917                 STACKSTRNUL(p);
1918                 if ((lstat(stackblock(), &statb) < 0)
1919                     || (S_ISLNK(statb.st_mode)))  {
1920                         /* print = 1; */
1921                         badstat = 1;
1922                         break;
1923                 }
1924         }
1925
1926         INTOFF;
1927         if (chdir(dest) < 0) {
1928                 INTON;
1929                 return -1;
1930         }
1931         updatepwd(badstat ? NULL : dest);
1932         INTON;
1933         if (print && iflag)
1934                 printf(snlfmt, curdir);
1935         return 0;
1936 }
1937
1938
1939 /*
1940  * Get the next component of the path name pointed to by cdcomppath.
1941  * This routine overwrites the string pointed to by cdcomppath.
1942  */
1943
1944 static char *
1945 getcomponent() {
1946         char *p;
1947         char *start;
1948
1949         if ((p = cdcomppath) == NULL)
1950                 return NULL;
1951         start = cdcomppath;
1952         while (*p != '/' && *p != '\0')
1953                 p++;
1954         if (*p == '\0') {
1955                 cdcomppath = NULL;
1956         } else {
1957                 *p++ = '\0';
1958                 cdcomppath = p;
1959         }
1960         return start;
1961 }
1962
1963
1964
1965 /*
1966  * Update curdir (the name of the current directory) in response to a
1967  * cd command.  We also call hashcd to let the routines in exec.c know
1968  * that the current directory has changed.
1969  */
1970
1971 static void hashcd (void);
1972
1973 static void
1974 updatepwd(const char *dir)
1975 {
1976         char *new;
1977         char *p;
1978         size_t len;
1979
1980         hashcd();                               /* update command hash table */
1981
1982         /*
1983          * If our argument is NULL, we don't know the current directory
1984          * any more because we traversed a symbolic link or something
1985          * we couldn't stat().
1986          */
1987         if (dir == NULL || curdir == nullstr)  {
1988                 setpwd(0, 1);
1989                 return;
1990         }
1991         len = strlen(dir);
1992         cdcomppath = sstrdup(dir);
1993         STARTSTACKSTR(new);
1994         if (*dir != '/') {
1995                 p = curdir;
1996                 while (*p)
1997                         STPUTC(*p++, new);
1998                 if (p[-1] == '/')
1999                         STUNPUTC(new);
2000         }
2001         while ((p = getcomponent()) != NULL) {
2002                 if (equal(p, "..")) {
2003                         while (new > stackblock() && (STUNPUTC(new), *new) != '/');
2004                 } else if (*p != '\0' && ! equal(p, ".")) {
2005                         STPUTC('/', new);
2006                         while (*p)
2007                                 STPUTC(*p++, new);
2008                 }
2009         }
2010         if (new == stackblock())
2011                 STPUTC('/', new);
2012         STACKSTRNUL(new);
2013         setpwd(stackblock(), 1);
2014 }
2015
2016
2017 #ifndef BB_PWD
2018 static int
2019 pwdcmd(argc, argv)
2020         int argc;
2021         char **argv;
2022 {
2023         printf(snlfmt, curdir);
2024         return 0;
2025 }
2026 #endif
2027
2028 /*
2029  * Find out what the current directory is. If we already know the current
2030  * directory, this routine returns immediately.
2031  */
2032 static void
2033 getpwd(void)
2034 {
2035         curdir = xgetcwd(0);
2036         if(curdir==0)
2037                 curdir = nullstr;
2038 }
2039
2040 static void
2041 setpwd(const char *val, int setold)
2042 {
2043         if (setold) {
2044                 setvar("OLDPWD", curdir, VEXPORT);
2045         }
2046         INTOFF;
2047         if (curdir != nullstr) {
2048                 free(curdir);
2049                 curdir = nullstr;
2050         }
2051         if (!val) {
2052                 getpwd();
2053         } else {
2054                 curdir = savestr(val);
2055         }
2056         INTON;
2057         setvar("PWD", curdir, VEXPORT);
2058 }
2059
2060 /*
2061  * Errors and exceptions.
2062  */
2063
2064 /*
2065  * Code to handle exceptions in C.
2066  */
2067
2068 /*
2069  * We enclose jmp_buf in a structure so that we can declare pointers to
2070  * jump locations.  The global variable handler contains the location to
2071  * jump to when an exception occurs, and the global variable exception
2072  * contains a code identifying the exeception.  To implement nested
2073  * exception handlers, the user should save the value of handler on entry
2074  * to an inner scope, set handler to point to a jmploc structure for the
2075  * inner scope, and restore handler on exit from the scope.
2076  */
2077
2078 struct jmploc {
2079         jmp_buf loc;
2080 };
2081
2082 /* exceptions */
2083 #define EXINT 0         /* SIGINT received */
2084 #define EXERROR 1       /* a generic error */
2085 #define EXSHELLPROC 2   /* execute a shell procedure */
2086 #define EXEXEC 3        /* command execution failed */
2087
2088 static struct jmploc *handler;
2089 static int exception;
2090
2091 static void exverror (int, const char *, va_list)
2092     __attribute__((__noreturn__));
2093
2094 /*
2095  * Called to raise an exception.  Since C doesn't include exceptions, we
2096  * just do a longjmp to the exception handler.  The type of exception is
2097  * stored in the global variable "exception".
2098  */
2099
2100 static void exraise (int) __attribute__((__noreturn__));
2101
2102 static void
2103 exraise(int e)
2104 {
2105 #ifdef DEBUG
2106         if (handler == NULL)
2107                 abort();
2108 #endif
2109         flushall();
2110         exception = e;
2111         longjmp(handler->loc, 1);
2112 }
2113
2114
2115 /*
2116  * Called from trap.c when a SIGINT is received.  (If the user specifies
2117  * that SIGINT is to be trapped or ignored using the trap builtin, then
2118  * this routine is not called.)  Suppressint is nonzero when interrupts
2119  * are held using the INTOFF macro.  The call to _exit is necessary because
2120  * there is a short period after a fork before the signal handlers are
2121  * set to the appropriate value for the child.  (The test for iflag is
2122  * just defensive programming.)
2123  */
2124
2125 static void
2126 onint(void) {
2127         sigset_t mysigset;
2128
2129         if (suppressint) {
2130                 intpending++;
2131                 return;
2132         }
2133         intpending = 0;
2134         sigemptyset(&mysigset);
2135         sigprocmask(SIG_SETMASK, &mysigset, NULL);
2136         if (rootshell && iflag)
2137                 exraise(EXINT);
2138         else {
2139                 signal(SIGINT, SIG_DFL);
2140                 raise(SIGINT);
2141         }
2142         /* NOTREACHED */
2143 }
2144
2145
2146 static char *commandname;       /* currently executing command */
2147
2148 /*
2149  * Exverror is called to raise the error exception.  If the first argument
2150  * is not NULL then error prints an error message using printf style
2151  * formatting.  It then raises the error exception.
2152  */
2153 static void
2154 exverror(int cond, const char *msg, va_list ap)
2155 {
2156         CLEAR_PENDING_INT;
2157         INTOFF;
2158
2159 #ifdef DEBUG
2160         if (msg)
2161                 TRACE(("exverror(%d, \"%s\") pid=%d\n", cond, msg, getpid()));
2162         else
2163                 TRACE(("exverror(%d, NULL) pid=%d\n", cond, getpid()));
2164 #endif
2165         if (msg) {
2166                 if (commandname)
2167                         out2fmt("%s: ", commandname);
2168                 vfprintf(stderr, msg, ap);
2169                 out2c('\n');
2170         }
2171         exraise(cond);
2172         /* NOTREACHED */
2173 }
2174
2175
2176 #ifdef __STDC__
2177 static void
2178 error(const char *msg, ...)
2179 #else
2180 static void
2181 error(va_alist)
2182         va_dcl
2183 #endif
2184 {
2185 #ifndef __STDC__
2186         const char *msg;
2187 #endif
2188         va_list ap;
2189 #ifdef __STDC__
2190         va_start(ap, msg);
2191 #else
2192         va_start(ap);
2193         msg = va_arg(ap, const char *);
2194 #endif
2195         exverror(EXERROR, msg, ap);
2196         /* NOTREACHED */
2197         va_end(ap);
2198 }
2199
2200
2201 #ifdef __STDC__
2202 static void
2203 exerror(int cond, const char *msg, ...)
2204 #else
2205 static void
2206 exerror(va_alist)
2207         va_dcl
2208 #endif
2209 {
2210 #ifndef __STDC__
2211         int cond;
2212         const char *msg;
2213 #endif
2214         va_list ap;
2215 #ifdef __STDC__
2216         va_start(ap, msg);
2217 #else
2218         va_start(ap);
2219         cond = va_arg(ap, int);
2220         msg = va_arg(ap, const char *);
2221 #endif
2222         exverror(cond, msg, ap);
2223         /* NOTREACHED */
2224         va_end(ap);
2225 }
2226
2227
2228
2229 /*
2230  * Table of error messages.
2231  */
2232
2233 struct errname {
2234         short errcode;          /* error number */
2235         char  action;           /* operation which encountered the error */
2236 };
2237
2238 /*
2239  * Types of operations (passed to the errmsg routine).
2240  */
2241
2242 #define E_OPEN 01       /* opening a file */
2243 #define E_CREAT 02      /* creating a file */
2244 #define E_EXEC 04       /* executing a program */
2245
2246 #define ALL (E_OPEN|E_CREAT|E_EXEC)
2247
2248 static const struct errname errormsg[] = {
2249         { EINTR,        ALL     },
2250         { EACCES,       ALL     },
2251         { EIO,          ALL     },
2252         { ENOENT,       E_OPEN  },
2253         { ENOENT,       E_CREAT },
2254         { ENOENT,       E_EXEC  },
2255         { ENOTDIR,      E_OPEN  },
2256         { ENOTDIR,      E_CREAT },
2257         { ENOTDIR,      E_EXEC  },
2258         { EISDIR,       ALL     },
2259         { EEXIST,       E_CREAT },
2260 #ifdef EMFILE
2261         { EMFILE,       ALL     },
2262 #endif
2263         { ENFILE,       ALL     },
2264         { ENOSPC,       ALL     },
2265 #ifdef EDQUOT
2266         { EDQUOT,       ALL     },
2267 #endif
2268 #ifdef ENOSR
2269         { ENOSR,        ALL     },
2270 #endif
2271         { ENXIO,        ALL     },
2272         { EROFS,        ALL     },
2273         { ETXTBSY,      ALL     },
2274 #ifdef EAGAIN
2275         { EAGAIN,       E_EXEC  },
2276 #endif
2277         { ENOMEM,       ALL     },
2278 #ifdef ENOLINK
2279         { ENOLINK,      ALL     },
2280 #endif
2281 #ifdef EMULTIHOP
2282         { EMULTIHOP,    ALL     },
2283 #endif
2284 #ifdef ECOMM
2285         { ECOMM,        ALL     },
2286 #endif
2287 #ifdef ESTALE
2288         { ESTALE,       ALL     },
2289 #endif
2290 #ifdef ETIMEDOUT
2291         { ETIMEDOUT,    ALL     },
2292 #endif
2293 #ifdef ELOOP
2294         { ELOOP,        ALL     },
2295 #endif
2296         { E2BIG,        E_EXEC  },
2297 #ifdef ELIBACC
2298         { ELIBACC,      E_EXEC  },
2299 #endif
2300 };
2301
2302 #define ERRNAME_SIZE (sizeof(errormsg)/sizeof(struct errname))
2303
2304 /*
2305  * Return a string describing an error.  The returned string may be a
2306  * pointer to a static buffer that will be overwritten on the next call.
2307  * Action describes the operation that got the error.
2308  */
2309
2310 static const char *
2311 errmsg(int e, int action)
2312 {
2313         struct errname const *ep;
2314         static char buf[12];
2315
2316         for (ep = errormsg ; ep < errormsg+ERRNAME_SIZE; ep++) {
2317                 if (ep->errcode == e && (ep->action & action) != 0)
2318                         return strerror(e);
2319         }
2320
2321         snprintf(buf, sizeof buf, "error %d", e);
2322         return buf;
2323 }
2324
2325
2326 #ifdef ASH_OPTIMIZE_FOR_SIZE
2327 static void
2328 __inton() {
2329         if (--suppressint == 0 && intpending) {
2330                 onint();
2331         }
2332 }
2333 static void forceinton (void) {
2334         suppressint = 0;
2335         if (intpending)
2336                 onint();
2337 }
2338 #endif
2339
2340 /* flags in argument to evaltree */
2341 #define EV_EXIT 01              /* exit after evaluating tree */
2342 #define EV_TESTED 02            /* exit status is checked; ignore -e flag */
2343 #define EV_BACKCMD 04           /* command executing within back quotes */
2344
2345 static int evalskip;                    /* set if we are skipping commands */
2346 static int skipcount;           /* number of levels to skip */
2347 static int loopnest;            /* current loop nesting level */
2348 static int funcnest;                    /* depth of function calls */
2349
2350
2351 static struct strlist *cmdenviron;      /* environment for builtin command */
2352 static int exitstatus;                  /* exit status of last command */
2353 static int oexitstatus;         /* saved exit status */
2354
2355 static void evalsubshell (const union node *, int);
2356 static void expredir (union node *);
2357 static void prehash (union node *);
2358 static void eprintlist (struct strlist *);
2359
2360 static union node *parsecmd(int);
2361 /*
2362  * Called to reset things after an exception.
2363  */
2364
2365 /*
2366  * The eval commmand.
2367  */
2368 static void evalstring (char *, int);
2369
2370 static int
2371 evalcmd(argc, argv)
2372         int argc;
2373         char **argv;
2374 {
2375         char *p;
2376         char *concat;
2377         char **ap;
2378
2379         if (argc > 1) {
2380                 p = argv[1];
2381                 if (argc > 2) {
2382                         STARTSTACKSTR(concat);
2383                         ap = argv + 2;
2384                         for (;;) {
2385                                 while (*p)
2386                                         STPUTC(*p++, concat);
2387                                 if ((p = *ap++) == NULL)
2388                                         break;
2389                                 STPUTC(' ', concat);
2390                         }
2391                         STPUTC('\0', concat);
2392                         p = grabstackstr(concat);
2393                 }
2394                 evalstring(p, EV_TESTED);
2395         }
2396         return exitstatus;
2397 }
2398
2399 /*
2400  * Execute a command or commands contained in a string.
2401  */
2402
2403 static void evaltree (union node *, int);
2404 static void setinputstring (char *);
2405 static void popfile (void);
2406 static void setstackmark(struct stackmark *mark);
2407 static void popstackmark(struct stackmark *mark);
2408
2409
2410 static void
2411 evalstring(char *s, int flag)
2412 {
2413         union node *n;
2414         struct stackmark smark;
2415
2416         setstackmark(&smark);
2417         setinputstring(s);
2418         while ((n = parsecmd(0)) != NEOF) {
2419                 evaltree(n, flag);
2420                 popstackmark(&smark);
2421         }
2422         popfile();
2423         popstackmark(&smark);
2424 }
2425
2426 static struct builtincmd *find_builtin (const char *);
2427 static void expandarg (union node *, struct arglist *, int);
2428 static void calcsize (const union node *);
2429 static union node *copynode (const union node *);
2430
2431 /*
2432  * Make a copy of a parse tree.
2433  */
2434
2435 static int     funcblocksize;           /* size of structures in function */
2436 static int     funcstringsize;          /* size of strings in node */
2437 static pointer funcblock;              /* block to allocate function from */
2438 static char   *funcstring;              /* block to allocate strings from */
2439
2440
2441 static inline union node *
2442 copyfunc(union node *n)
2443 {
2444         if (n == NULL)
2445                 return NULL;
2446         funcblocksize = 0;
2447         funcstringsize = 0;
2448         calcsize(n);
2449         funcblock = ckmalloc(funcblocksize + funcstringsize);
2450         funcstring = (char *) funcblock + funcblocksize;
2451         return copynode(n);
2452 }
2453
2454 /*
2455  * Free a parse tree.
2456  */
2457
2458 static void
2459 freefunc(union node *n)
2460 {
2461         if (n)
2462                 ckfree(n);
2463 }
2464
2465
2466 /*
2467  * Add a new command entry, replacing any existing command entry for
2468  * the same name.
2469  */
2470
2471 static inline void
2472 addcmdentry(char *name, struct cmdentry *entry)
2473 {
2474         struct tblentry *cmdp;
2475
2476         INTOFF;
2477         cmdp = cmdlookup(name, 1);
2478         if (cmdp->cmdtype == CMDFUNCTION) {
2479                 freefunc(cmdp->param.func);
2480         }
2481         cmdp->cmdtype = entry->cmdtype;
2482         cmdp->param = entry->u;
2483         INTON;
2484 }
2485
2486 static inline void
2487 evalloop(const union node *n, int flags)
2488 {
2489         int status;
2490
2491         loopnest++;
2492         status = 0;
2493         for (;;) {
2494                 evaltree(n->nbinary.ch1, EV_TESTED);
2495                 if (evalskip) {
2496 skipping:         if (evalskip == SKIPCONT && --skipcount <= 0) {
2497                                 evalskip = 0;
2498                                 continue;
2499                         }
2500                         if (evalskip == SKIPBREAK && --skipcount <= 0)
2501                                 evalskip = 0;
2502                         break;
2503                 }
2504                 if (n->type == NWHILE) {
2505                         if (exitstatus != 0)
2506                                 break;
2507                 } else {
2508                         if (exitstatus == 0)
2509                                 break;
2510                 }
2511                 evaltree(n->nbinary.ch2, flags & EV_TESTED);
2512                 status = exitstatus;
2513                 if (evalskip)
2514                         goto skipping;
2515         }
2516         loopnest--;
2517         exitstatus = status;
2518 }
2519
2520 static void
2521 evalfor(const union node *n, int flags)
2522 {
2523         struct arglist arglist;
2524         union node *argp;
2525         struct strlist *sp;
2526         struct stackmark smark;
2527
2528         setstackmark(&smark);
2529         arglist.lastp = &arglist.list;
2530         for (argp = n->nfor.args ; argp ; argp = argp->narg.next) {
2531                 oexitstatus = exitstatus;
2532                 expandarg(argp, &arglist, EXP_FULL | EXP_TILDE | EXP_RECORD);
2533                 if (evalskip)
2534                         goto out;
2535         }
2536         *arglist.lastp = NULL;
2537
2538         exitstatus = 0;
2539         loopnest++;
2540         for (sp = arglist.list ; sp ; sp = sp->next) {
2541                 setvar(n->nfor.var, sp->text, 0);
2542                 evaltree(n->nfor.body, flags & EV_TESTED);
2543                 if (evalskip) {
2544                         if (evalskip == SKIPCONT && --skipcount <= 0) {
2545                                 evalskip = 0;
2546                                 continue;
2547                         }
2548                         if (evalskip == SKIPBREAK && --skipcount <= 0)
2549                                 evalskip = 0;
2550                         break;
2551                 }
2552         }
2553         loopnest--;
2554 out:
2555         popstackmark(&smark);
2556 }
2557
2558 static inline void
2559 evalcase(const union node *n, int flags)
2560 {
2561         union node *cp;
2562         union node *patp;
2563         struct arglist arglist;
2564         struct stackmark smark;
2565
2566         setstackmark(&smark);
2567         arglist.lastp = &arglist.list;
2568         oexitstatus = exitstatus;
2569         expandarg(n->ncase.expr, &arglist, EXP_TILDE);
2570         for (cp = n->ncase.cases ; cp && evalskip == 0 ; cp = cp->nclist.next) {
2571                 for (patp = cp->nclist.pattern ; patp ; patp = patp->narg.next) {
2572                         if (casematch(patp, arglist.list->text)) {
2573                                 if (evalskip == 0) {
2574                                         evaltree(cp->nclist.body, flags);
2575                                 }
2576                                 goto out;
2577                         }
2578                 }
2579         }
2580 out:
2581         popstackmark(&smark);
2582 }
2583
2584 /*
2585  * Evaluate a pipeline.  All the processes in the pipeline are children
2586  * of the process creating the pipeline.  (This differs from some versions
2587  * of the shell, which make the last process in a pipeline the parent
2588  * of all the rest.)
2589  */
2590
2591 static inline void
2592 evalpipe(n)
2593         union node *n;
2594 {
2595         struct job *jp;
2596         struct nodelist *lp;
2597         int pipelen;
2598         int prevfd;
2599         int pip[2];
2600
2601         TRACE(("evalpipe(0x%lx) called\n", (long)n));
2602         pipelen = 0;
2603         for (lp = n->npipe.cmdlist ; lp ; lp = lp->next)
2604                 pipelen++;
2605         INTOFF;
2606         jp = makejob(n, pipelen);
2607         prevfd = -1;
2608         for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
2609                 prehash(lp->n);
2610                 pip[1] = -1;
2611                 if (lp->next) {
2612                         if (pipe(pip) < 0) {
2613                                 close(prevfd);
2614                                 error("Pipe call failed");
2615                         }
2616                 }
2617                 if (forkshell(jp, lp->n, n->npipe.backgnd) == 0) {
2618                         INTON;
2619                         if (prevfd > 0) {
2620                                 close(0);
2621                                 dup_as_newfd(prevfd, 0);
2622                                 close(prevfd);
2623                                 if (pip[0] == 0) {
2624                                         pip[0] = -1;
2625                                 }
2626                         }
2627                         if (pip[1] >= 0) {
2628                                 if (pip[0] >= 0) {
2629                                         close(pip[0]);
2630                                 }
2631                                 if (pip[1] != 1) {
2632                                         close(1);
2633                                         dup_as_newfd(pip[1], 1);
2634                                         close(pip[1]);
2635                                 }
2636                         }
2637                         evaltree(lp->n, EV_EXIT);
2638                 }
2639                 if (prevfd >= 0)
2640                         close(prevfd);
2641                 prevfd = pip[0];
2642                 close(pip[1]);
2643         }
2644         INTON;
2645         if (n->npipe.backgnd == 0) {
2646                 INTOFF;
2647                 exitstatus = waitforjob(jp);
2648                 TRACE(("evalpipe:  job done exit status %d\n", exitstatus));
2649                 INTON;
2650         }
2651 }
2652
2653 static void find_command (const char *, struct cmdentry *, int, const char *);
2654
2655 static int
2656 isassignment(const char *word) {
2657         if (!is_name(*word)) {
2658                 return 0;
2659         }
2660         do {
2661                 word++;
2662         } while (is_in_name(*word));
2663         return *word == '=';
2664 }
2665
2666
2667 static void
2668 evalcommand(union node *cmd, int flags)
2669 {
2670         struct stackmark smark;
2671         union node *argp;
2672         struct arglist arglist;
2673         struct arglist varlist;
2674         char **argv;
2675         int argc;
2676         char **envp;
2677         struct strlist *sp;
2678         int mode;
2679         struct cmdentry cmdentry;
2680         struct job *jp;
2681         char *volatile savecmdname;
2682         volatile struct shparam saveparam;
2683         struct localvar *volatile savelocalvars;
2684         volatile int e;
2685         char *lastarg;
2686         const char *path;
2687         const struct builtincmd *firstbltin;
2688         struct jmploc *volatile savehandler;
2689         struct jmploc jmploc;
2690 #if __GNUC__
2691         /* Avoid longjmp clobbering */
2692         (void) &argv;
2693         (void) &argc;
2694         (void) &lastarg;
2695         (void) &flags;
2696 #endif
2697
2698         /* First expand the arguments. */
2699         TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags));
2700         setstackmark(&smark);
2701         arglist.lastp = &arglist.list;
2702         varlist.lastp = &varlist.list;
2703         arglist.list = 0;
2704         oexitstatus = exitstatus;
2705         exitstatus = 0;
2706         path = pathval();
2707         for (argp = cmd->ncmd.assign; argp; argp = argp->narg.next) {
2708                 expandarg(argp, &varlist, EXP_VARTILDE);
2709         }
2710         for (
2711                 argp = cmd->ncmd.args; argp && !arglist.list;
2712                 argp = argp->narg.next
2713         ) {
2714                 expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
2715         }
2716         if (argp) {
2717                 struct builtincmd *bcmd;
2718                 int pseudovarflag;
2719                 bcmd = find_builtin(arglist.list->text);
2720                 pseudovarflag = bcmd && IS_BUILTIN_ASSIGN(bcmd);
2721                 for (; argp; argp = argp->narg.next) {
2722                         if (pseudovarflag && isassignment(argp->narg.text)) {
2723                                 expandarg(argp, &arglist, EXP_VARTILDE);
2724                                 continue;
2725                         }
2726                         expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
2727                 }
2728         }
2729         *arglist.lastp = NULL;
2730         *varlist.lastp = NULL;
2731         expredir(cmd->ncmd.redirect);
2732         argc = 0;
2733         for (sp = arglist.list ; sp ; sp = sp->next)
2734                 argc++;
2735         argv = stalloc(sizeof (char *) * (argc + 1));
2736
2737         for (sp = arglist.list ; sp ; sp = sp->next) {
2738                 TRACE(("evalcommand arg: %s\n", sp->text));
2739                 *argv++ = sp->text;
2740         }
2741         *argv = NULL;
2742         lastarg = NULL;
2743         if (iflag && funcnest == 0 && argc > 0)
2744                 lastarg = argv[-1];
2745         argv -= argc;
2746
2747         /* Print the command if xflag is set. */
2748         if (xflag) {
2749                 out2c('+');
2750                 eprintlist(varlist.list);
2751                 eprintlist(arglist.list);
2752                 out2c('\n');
2753         }
2754
2755         /* Now locate the command. */
2756         if (argc == 0) {
2757                 cmdentry.cmdtype = CMDBUILTIN;
2758                 firstbltin = cmdentry.u.cmd = BLTINCMD;
2759         } else {
2760                 const char *oldpath;
2761                 int findflag = DO_ERR;
2762                 int oldfindflag;
2763
2764                 /*
2765                  * Modify the command lookup path, if a PATH= assignment
2766                  * is present
2767                  */
2768                 for (sp = varlist.list ; sp ; sp = sp->next)
2769                         if (varequal(sp->text, defpathvar)) {
2770                                 path = sp->text + 5;
2771                                 findflag |= DO_BRUTE;
2772                         }
2773                 oldpath = path;
2774                 oldfindflag = findflag;
2775                 firstbltin = 0;
2776                 for(;;) {
2777                         find_command(argv[0], &cmdentry, findflag, path);
2778                         if (cmdentry.cmdtype == CMDUNKNOWN) {   /* command not found */
2779                                 exitstatus = 127;
2780                                 goto out;
2781                         }
2782                         /* implement bltin and command here */
2783                         if (cmdentry.cmdtype != CMDBUILTIN) {
2784                                 break;
2785                         }
2786                         if (!firstbltin) {
2787                                 firstbltin = cmdentry.u.cmd;
2788                         }
2789                         if (cmdentry.u.cmd == BLTINCMD) {
2790                                 for(;;) {
2791                                         struct builtincmd *bcmd;
2792
2793                                         argv++;
2794                                         if (--argc == 0)
2795                                                 goto found;
2796                                         if (!(bcmd = find_builtin(*argv))) {
2797                                                 out2fmt("%s: not found\n", *argv);
2798                                                 exitstatus = 127;
2799                                                 goto out;
2800                                         }
2801                                         cmdentry.u.cmd = bcmd;
2802                                         if (bcmd != BLTINCMD)
2803                                                 break;
2804                                 }
2805                         }
2806                         if (cmdentry.u.cmd == find_builtin("command")) {
2807                                 argv++;
2808                                 if (--argc == 0) {
2809                                         goto found;
2810                                 }
2811                                 if (*argv[0] == '-') {
2812                                         if (!equal(argv[0], "-p")) {
2813                                                 argv--;
2814                                                 argc++;
2815                                                 break;
2816                                         }
2817                                         argv++;
2818                                         if (--argc == 0) {
2819                                                 goto found;
2820                                         }
2821                                         path = defpath;
2822                                         findflag |= DO_BRUTE;
2823                                 } else {
2824                                         path = oldpath;
2825                                         findflag = oldfindflag;
2826                                 }
2827                                 findflag |= DO_NOFUN;
2828                                 continue;
2829                         }
2830 found:
2831                         break;
2832                 }
2833         }
2834
2835         /* Fork off a child process if necessary. */
2836         if (cmd->ncmd.backgnd
2837          || (cmdentry.cmdtype == CMDNORMAL && (flags & EV_EXIT) == 0)
2838         ) {
2839                 jp = makejob(cmd, 1);
2840                 mode = cmd->ncmd.backgnd;
2841                 if (forkshell(jp, cmd, mode) != 0)
2842                         goto parent;    /* at end of routine */
2843                 flags |= EV_EXIT;
2844         }
2845
2846         /* This is the child process if a fork occurred. */
2847         /* Execute the command. */
2848         if (cmdentry.cmdtype == CMDFUNCTION) {
2849 #ifdef DEBUG
2850                 trputs("Shell function:  ");  trargs(argv);
2851 #endif
2852                 exitstatus = oexitstatus;
2853                 redirect(cmd->ncmd.redirect, REDIR_PUSH);
2854                 saveparam = shellparam;
2855                 shellparam.malloc = 0;
2856                 shellparam.nparam = argc - 1;
2857                 shellparam.p = argv + 1;
2858                 INTOFF;
2859                 savelocalvars = localvars;
2860                 localvars = NULL;
2861                 INTON;
2862                 if (setjmp(jmploc.loc)) {
2863                         if (exception == EXSHELLPROC) {
2864                                 freeparam((volatile struct shparam *)
2865                                     &saveparam);
2866                         } else {
2867                                 saveparam.optind = shellparam.optind;
2868                                 saveparam.optoff = shellparam.optoff;
2869                                 freeparam(&shellparam);
2870                                 shellparam = saveparam;
2871                         }
2872                         poplocalvars();
2873                         localvars = savelocalvars;
2874                         handler = savehandler;
2875                         longjmp(handler->loc, 1);
2876                 }
2877                 savehandler = handler;
2878                 handler = &jmploc;
2879                 for (sp = varlist.list ; sp ; sp = sp->next)
2880                         mklocal(sp->text);
2881                 funcnest++;
2882                 evaltree(cmdentry.u.func, flags & EV_TESTED);
2883                 funcnest--;
2884                 INTOFF;
2885                 poplocalvars();
2886                 localvars = savelocalvars;
2887                 saveparam.optind = shellparam.optind;
2888                 saveparam.optoff = shellparam.optoff;
2889                 freeparam(&shellparam);
2890                 shellparam = saveparam;
2891                 handler = savehandler;
2892                 popredir();
2893                 INTON;
2894                 if (evalskip == SKIPFUNC) {
2895                         evalskip = 0;
2896                         skipcount = 0;
2897                 }
2898                 if (flags & EV_EXIT)
2899                         exitshell(exitstatus);
2900         } else if (cmdentry.cmdtype == CMDBUILTIN) {
2901 #ifdef DEBUG
2902                 trputs("builtin command:  ");  trargs(argv);
2903 #endif
2904                 mode = (cmdentry.u.cmd == EXECCMD)? 0 : REDIR_PUSH;
2905                 redirect(cmd->ncmd.redirect, mode);
2906                 savecmdname = commandname;
2907                 if (IS_BUILTIN_SPECIAL(firstbltin)) {
2908                         listsetvar(varlist.list);
2909                 } else {
2910                         cmdenviron = varlist.list;
2911                 }
2912                 e = -1;
2913                 if (setjmp(jmploc.loc)) {
2914                         e = exception;
2915                         exitstatus = (e == EXINT)? SIGINT+128 : 2;
2916                         goto cmddone;
2917                 }
2918                 savehandler = handler;
2919                 handler = &jmploc;
2920                 commandname = argv[0];
2921                 argptr = argv + 1;
2922                 optptr = NULL;                  /* initialize nextopt */
2923                 exitstatus = (*cmdentry.u.cmd->builtinfunc)(argc, argv);
2924                 flushall();
2925 cmddone:
2926                 cmdenviron = NULL;
2927                 if (e != EXSHELLPROC) {
2928                         commandname = savecmdname;
2929                         if (flags & EV_EXIT)
2930                                 exitshell(exitstatus);
2931                 }
2932                 handler = savehandler;
2933                 if (e != -1) {
2934                         if ((e != EXERROR && e != EXEXEC)
2935                            || cmdentry.u.cmd == BLTINCMD
2936                            || cmdentry.u.cmd == DOTCMD
2937                            || cmdentry.u.cmd == EVALCMD
2938                            || cmdentry.u.cmd == EXECCMD)
2939                                 exraise(e);
2940                         FORCEINTON;
2941                 }
2942                 if (cmdentry.u.cmd != EXECCMD)
2943                         popredir();
2944         } else {
2945 #ifdef DEBUG
2946                 trputs("normal command:  ");  trargs(argv);
2947 #endif
2948                 redirect(cmd->ncmd.redirect, 0);
2949                 clearredir();
2950                 for (sp = varlist.list ; sp ; sp = sp->next)
2951                         setvareq(sp->text, VEXPORT|VSTACK);
2952                 envp = environment();
2953                 shellexec(argv, envp, path, cmdentry.u.index);
2954         }
2955         goto out;
2956
2957 parent: /* parent process gets here (if we forked) */
2958         if (mode == 0) {        /* argument to fork */
2959                 INTOFF;
2960                 exitstatus = waitforjob(jp);
2961                 INTON;
2962         }
2963
2964 out:
2965         if (lastarg)
2966                 setvar("_", lastarg, 0);
2967         popstackmark(&smark);
2968 }
2969
2970 /*
2971  * Evaluate a parse tree.  The value is left in the global variable
2972  * exitstatus.
2973  */
2974 static void
2975 evaltree(n, flags)
2976         union node *n;
2977         int flags;
2978 {
2979         int checkexit = 0;
2980         if (n == NULL) {
2981                 TRACE(("evaltree(NULL) called\n"));
2982                 goto out;
2983         }
2984         TRACE(("evaltree(0x%lx: %d) called\n", (long)n, n->type));
2985         switch (n->type) {
2986         case NSEMI:
2987                 evaltree(n->nbinary.ch1, flags & EV_TESTED);
2988                 if (evalskip)
2989                         goto out;
2990                 evaltree(n->nbinary.ch2, flags);
2991                 break;
2992         case NAND:
2993                 evaltree(n->nbinary.ch1, EV_TESTED);
2994                 if (evalskip || exitstatus != 0)
2995                         goto out;
2996                 evaltree(n->nbinary.ch2, flags);
2997                 break;
2998         case NOR:
2999                 evaltree(n->nbinary.ch1, EV_TESTED);
3000                 if (evalskip || exitstatus == 0)
3001                         goto out;
3002                 evaltree(n->nbinary.ch2, flags);
3003                 break;
3004         case NREDIR:
3005                 expredir(n->nredir.redirect);
3006                 redirect(n->nredir.redirect, REDIR_PUSH);
3007                 evaltree(n->nredir.n, flags);
3008                 popredir();
3009                 break;
3010         case NSUBSHELL:
3011                 evalsubshell(n, flags);
3012                 break;
3013         case NBACKGND:
3014                 evalsubshell(n, flags);
3015                 break;
3016         case NIF: {
3017                 evaltree(n->nif.test, EV_TESTED);
3018                 if (evalskip)
3019                         goto out;
3020                 if (exitstatus == 0)
3021                         evaltree(n->nif.ifpart, flags);
3022                 else if (n->nif.elsepart)
3023                         evaltree(n->nif.elsepart, flags);
3024                 else
3025                         exitstatus = 0;
3026                 break;
3027         }
3028         case NWHILE:
3029         case NUNTIL:
3030                 evalloop(n, flags);
3031                 break;
3032         case NFOR:
3033                 evalfor(n, flags);
3034                 break;
3035         case NCASE:
3036                 evalcase(n, flags);
3037                 break;
3038         case NDEFUN: {
3039                 struct builtincmd *bcmd;
3040                 struct cmdentry entry;
3041                 if (
3042                         (bcmd = find_builtin(n->narg.text)) &&
3043                         IS_BUILTIN_SPECIAL(bcmd)
3044                 ) {
3045                         out2fmt("%s is a special built-in\n", n->narg.text);
3046                         exitstatus = 1;
3047                         break;
3048                 }
3049                 entry.cmdtype = CMDFUNCTION;
3050                 entry.u.func = copyfunc(n->narg.next);
3051                 addcmdentry(n->narg.text, &entry);
3052                 exitstatus = 0;
3053                 break;
3054         }
3055         case NNOT:
3056                 evaltree(n->nnot.com, EV_TESTED);
3057                 exitstatus = !exitstatus;
3058                 break;
3059
3060         case NPIPE:
3061                 evalpipe(n);
3062                 checkexit = 1;
3063                 break;
3064         case NCMD:
3065                 evalcommand(n, flags);
3066                 checkexit = 1;
3067                 break;
3068 #ifdef DEBUG
3069         default:
3070                 printf("Node type = %d\n", n->type);
3071                 break;
3072 #endif
3073         }
3074 out:
3075         if (pendingsigs)
3076                 dotrap();
3077         if (
3078                 flags & EV_EXIT ||
3079                 (checkexit && eflag && exitstatus && !(flags & EV_TESTED))
3080         )
3081                 exitshell(exitstatus);
3082 }
3083
3084 /*
3085  * Kick off a subshell to evaluate a tree.
3086  */
3087
3088 static void
3089 evalsubshell(const union node *n, int flags)
3090 {
3091         struct job *jp;
3092         int backgnd = (n->type == NBACKGND);
3093
3094         expredir(n->nredir.redirect);
3095         jp = makejob(n, 1);
3096         if (forkshell(jp, n, backgnd) == 0) {
3097                 if (backgnd)
3098                         flags &=~ EV_TESTED;
3099                 redirect(n->nredir.redirect, 0);
3100                 evaltree(n->nredir.n, flags | EV_EXIT); /* never returns */
3101         }
3102         if (! backgnd) {
3103                 INTOFF;
3104                 exitstatus = waitforjob(jp);
3105                 INTON;
3106         }
3107 }
3108
3109 /*
3110  * Compute the names of the files in a redirection list.
3111  */
3112
3113 static void fixredir(union node *n, const char *text, int err);
3114
3115 static void
3116 expredir(union node *n)
3117 {
3118         union node *redir;
3119
3120         for (redir = n ; redir ; redir = redir->nfile.next) {
3121                 struct arglist fn;
3122                 fn.lastp = &fn.list;
3123                 oexitstatus = exitstatus;
3124                 switch (redir->type) {
3125                 case NFROMTO:
3126                 case NFROM:
3127                 case NTO:
3128                 case NAPPEND:
3129                 case NTOOV:
3130                         expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR);
3131                         redir->nfile.expfname = fn.list->text;
3132                         break;
3133                 case NFROMFD:
3134                 case NTOFD:
3135                         if (redir->ndup.vname) {
3136                                 expandarg(redir->ndup.vname, &fn, EXP_FULL | EXP_TILDE);
3137                                 fixredir(redir, fn.list->text, 1);
3138                         }
3139                         break;
3140                 }
3141         }
3142 }
3143
3144
3145 /*
3146  * Execute a command inside back quotes.  If it's a builtin command, we
3147  * want to save its output in a block obtained from malloc.  Otherwise
3148  * we fork off a subprocess and get the output of the command via a pipe.
3149  * Should be called with interrupts off.
3150  */
3151
3152 static void
3153 evalbackcmd(union node *n, struct backcmd *result)
3154 {
3155         int pip[2];
3156         struct job *jp;
3157         struct stackmark smark;         /* unnecessary */
3158
3159         setstackmark(&smark);
3160         result->fd = -1;
3161         result->buf = NULL;
3162         result->nleft = 0;
3163         result->jp = NULL;
3164         if (n == NULL) {
3165                 exitstatus = 0;
3166                 goto out;
3167         }
3168         exitstatus = 0;
3169         if (pipe(pip) < 0)
3170                 error("Pipe call failed");
3171         jp = makejob(n, 1);
3172         if (forkshell(jp, n, FORK_NOJOB) == 0) {
3173                 FORCEINTON;
3174                 close(pip[0]);
3175                 if (pip[1] != 1) {
3176                         close(1);
3177                         dup_as_newfd(pip[1], 1);
3178                         close(pip[1]);
3179                 }
3180                 eflag = 0;
3181                 evaltree(n, EV_EXIT);
3182         }
3183         close(pip[1]);
3184         result->fd = pip[0];
3185         result->jp = jp;
3186 out:
3187         popstackmark(&smark);
3188         TRACE(("evalbackcmd done: fd=%d buf=0x%x nleft=%d jp=0x%x\n",
3189                 result->fd, result->buf, result->nleft, result->jp));
3190 }
3191
3192
3193 /*
3194  * Execute a simple command.
3195  */
3196
3197 /*
3198  * Search for a command.  This is called before we fork so that the
3199  * location of the command will be available in the parent as well as
3200  * the child.  The check for "goodname" is an overly conservative
3201  * check that the name will not be subject to expansion.
3202  */
3203
3204 static void
3205 prehash(n)
3206         union node *n;
3207 {
3208         struct cmdentry entry;
3209
3210         if (n->type == NCMD && n->ncmd.args)
3211                 if (goodname(n->ncmd.args->narg.text))
3212                         find_command(n->ncmd.args->narg.text, &entry, 0,
3213                                      pathval());
3214 }
3215
3216
3217 /*
3218  * Builtin commands.  Builtin commands whose functions are closely
3219  * tied to evaluation are implemented here.
3220  */
3221
3222 /*
3223  * No command given, or a bltin command with no arguments.  Set the
3224  * specified variables.
3225  */
3226
3227 int
3228 bltincmd(argc, argv)
3229         int argc;
3230         char **argv;
3231 {
3232         /*
3233          * Preserve exitstatus of a previous possible redirection
3234          * as POSIX mandates
3235          */
3236         return exitstatus;
3237 }
3238
3239
3240 /*
3241  * Handle break and continue commands.  Break, continue, and return are
3242  * all handled by setting the evalskip flag.  The evaluation routines
3243  * above all check this flag, and if it is set they start skipping
3244  * commands rather than executing them.  The variable skipcount is
3245  * the number of loops to break/continue, or the number of function
3246  * levels to return.  (The latter is always 1.)  It should probably
3247  * be an error to break out of more loops than exist, but it isn't
3248  * in the standard shell so we don't make it one here.
3249  */
3250
3251 static int
3252 breakcmd(argc, argv)
3253         int argc;
3254         char **argv;
3255 {
3256         int n = argc > 1 ? number(argv[1]) : 1;
3257
3258         if (n > loopnest)
3259                 n = loopnest;
3260         if (n > 0) {
3261                 evalskip = (**argv == 'c')? SKIPCONT : SKIPBREAK;
3262                 skipcount = n;
3263         }
3264         return 0;
3265 }
3266
3267
3268 /*
3269  * The return command.
3270  */
3271
3272 static int
3273 returncmd(argc, argv)
3274         int argc;
3275         char **argv;
3276 {
3277         int ret = argc > 1 ? number(argv[1]) : oexitstatus;
3278
3279         if (funcnest) {
3280                 evalskip = SKIPFUNC;
3281                 skipcount = 1;
3282                 return ret;
3283         }
3284         else {
3285                 /* Do what ksh does; skip the rest of the file */
3286                 evalskip = SKIPFILE;
3287                 skipcount = 1;
3288                 return ret;
3289         }
3290 }
3291
3292
3293 #ifndef BB_TRUE_FALSE
3294 static int
3295 false_main(argc, argv)
3296         int argc;
3297         char **argv;
3298 {
3299         return 1;
3300 }
3301
3302
3303 static int
3304 true_main(argc, argv)
3305         int argc;
3306         char **argv;
3307 {
3308         return 0;
3309 }
3310 #endif
3311
3312 /*
3313  * Controls whether the shell is interactive or not.
3314  */
3315
3316 static void setsignal(int signo);
3317 static void chkmail(int silent);
3318
3319
3320 static void
3321 setinteractive(int on)
3322 {
3323         static int is_interactive;
3324         static int do_banner=0;
3325
3326         if (on == is_interactive)
3327                 return;
3328         setsignal(SIGINT);
3329         setsignal(SIGQUIT);
3330         setsignal(SIGTERM);
3331         chkmail(1);
3332         is_interactive = on;
3333         if (do_banner==0 && is_interactive) {
3334                 /* Looks like they want an interactive shell */
3335                 printf( "\n\n" BB_BANNER " Built-in shell (ash)\n");
3336                 printf( "Enter 'help' for a list of built-in commands.\n\n");
3337                 do_banner=1;
3338         }
3339 }
3340
3341 static void
3342 optschanged(void)
3343 {
3344         setinteractive(iflag);
3345         setjobctl(mflag);
3346 }
3347
3348
3349 static int
3350 execcmd(argc, argv)
3351         int argc;
3352         char **argv;
3353 {
3354         if (argc > 1) {
3355                 struct strlist *sp;
3356
3357                 iflag = 0;              /* exit on error */
3358                 mflag = 0;
3359                 optschanged();
3360                 for (sp = cmdenviron; sp ; sp = sp->next)
3361                         setvareq(sp->text, VEXPORT|VSTACK);
3362                 shellexec(argv + 1, environment(), pathval(), 0);
3363         }
3364         return 0;
3365 }
3366
3367 static void
3368 eprintlist(struct strlist *sp)
3369 {
3370         for (; sp; sp = sp->next) {
3371                 out2fmt(" %s",sp->text);
3372         }
3373 }
3374
3375 /*
3376  * Exec a program.  Never returns.  If you change this routine, you may
3377  * have to change the find_command routine as well.
3378  */
3379
3380 static const char *pathopt;     /* set by padvance */
3381
3382 static void
3383 shellexec(argv, envp, path, idx)
3384         char **argv, **envp;
3385         const char *path;
3386         int idx;
3387 {
3388         char *cmdname;
3389         int e;
3390
3391         if (strchr(argv[0], '/') != NULL) {
3392                 tryexec(argv[0], argv, envp);
3393                 e = errno;
3394         } else {
3395                 e = ENOENT;
3396                 while ((cmdname = padvance(&path, argv[0])) != NULL) {
3397                         if (--idx < 0 && pathopt == NULL) {
3398                                 tryexec(cmdname, argv, envp);
3399                                 if (errno != ENOENT && errno != ENOTDIR)
3400                                         e = errno;
3401                         }
3402                         stunalloc(cmdname);
3403                 }
3404         }
3405
3406         /* Map to POSIX errors */
3407         switch (e) {
3408         case EACCES:
3409                 exerrno = 126;
3410                 break;
3411         case ENOENT:
3412                 exerrno = 127;
3413                 break;
3414         default:
3415                 exerrno = 2;
3416                 break;
3417         }
3418         exerror(EXEXEC, "%s: %s", argv[0], errmsg(e, E_EXEC));
3419         /* NOTREACHED */
3420 }
3421
3422 /*
3423  * Clear traps on a fork.
3424  */
3425 static void
3426 clear_traps(void) {
3427         char **tp;
3428
3429         for (tp = trap ; tp < &trap[NSIG] ; tp++) {
3430                 if (*tp && **tp) {      /* trap not NULL or SIG_IGN */
3431                         INTOFF;
3432                         ckfree(*tp);
3433                         *tp = NULL;
3434                         if (tp != &trap[0])
3435                                 setsignal(tp - trap);
3436                         INTON;
3437                 }
3438         }
3439 }
3440
3441
3442 static void
3443 initshellproc(void) {
3444
3445 #ifdef ASH_ALIAS
3446       /* from alias.c: */
3447       {
3448               rmaliases();
3449       }
3450 #endif
3451       /* from eval.c: */
3452       {
3453               exitstatus = 0;
3454       }
3455
3456       /* from exec.c: */
3457       {
3458               deletefuncs();
3459       }
3460
3461       /* from jobs.c: */
3462       {
3463               backgndpid = -1;
3464 #ifdef JOBS
3465               jobctl = 0;
3466 #endif
3467       }
3468
3469       /* from options.c: */
3470       {
3471               int i;
3472
3473               for (i = 0; i < NOPTS; i++)
3474                       optent_val(i) = 0;
3475               optschanged();
3476
3477       }
3478
3479       /* from redir.c: */
3480       {
3481               clearredir();
3482       }
3483
3484       /* from trap.c: */
3485       {
3486               char *sm;
3487
3488               clear_traps();
3489               for (sm = sigmode ; sm < sigmode + NSIG - 1; sm++) {
3490                       if (*sm == S_IGN)
3491                               *sm = S_HARD_IGN;
3492               }
3493       }
3494
3495       /* from var.c: */
3496       {
3497               shprocvar();
3498       }
3499 }
3500
3501 static int preadbuffer(void);
3502 static void pushfile (void);
3503
3504 /*
3505  * Read a character from the script, returning PEOF on end of file.
3506  * Nul characters in the input are silently discarded.
3507  */
3508
3509 #ifndef ASH_OPTIMIZE_FOR_SIZE
3510 #define pgetc_macro()   (--parsenleft >= 0? *parsenextc++ : preadbuffer())
3511 static int
3512 pgetc(void)
3513 {
3514         return pgetc_macro();
3515 }
3516 #else
3517 static int
3518 pgetc_macro(void)
3519 {
3520         return --parsenleft >= 0? *parsenextc++ : preadbuffer();
3521 }
3522
3523 static inline int
3524 pgetc(void)
3525 {
3526         return pgetc_macro();
3527 }
3528 #endif
3529
3530
3531 /*
3532  * Undo the last call to pgetc.  Only one character may be pushed back.
3533  * PEOF may be pushed back.
3534  */
3535
3536 static void
3537 pungetc() {
3538         parsenleft++;
3539         parsenextc--;
3540 }
3541
3542
3543 static void
3544 popfile(void) {
3545         struct parsefile *pf = parsefile;
3546
3547         INTOFF;
3548         if (pf->fd >= 0)
3549                 close(pf->fd);
3550         if (pf->buf)
3551                 ckfree(pf->buf);
3552         while (pf->strpush)
3553                 popstring();
3554         parsefile = pf->prev;
3555         ckfree(pf);
3556         parsenleft = parsefile->nleft;
3557         parselleft = parsefile->lleft;
3558         parsenextc = parsefile->nextc;
3559         plinno = parsefile->linno;
3560         INTON;
3561 }
3562
3563
3564 /*
3565  * Return to top level.
3566  */
3567
3568 static void
3569 popallfiles(void) {
3570         while (parsefile != &basepf)
3571                 popfile();
3572 }
3573
3574 /*
3575  * Close the file(s) that the shell is reading commands from.  Called
3576  * after a fork is done.
3577  */
3578
3579 static void
3580 closescript() {
3581         popallfiles();
3582         if (parsefile->fd > 0) {
3583                 close(parsefile->fd);
3584                 parsefile->fd = 0;
3585         }
3586 }
3587
3588
3589 /*
3590  * Like setinputfile, but takes an open file descriptor.  Call this with
3591  * interrupts off.
3592  */
3593
3594 static void
3595 setinputfd(fd, push)
3596         int fd, push;
3597 {
3598         (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
3599         if (push) {
3600                 pushfile();
3601                 parsefile->buf = 0;
3602         } else {
3603                 closescript();
3604                 while (parsefile->strpush)
3605                         popstring();
3606         }
3607         parsefile->fd = fd;
3608         if (parsefile->buf == NULL)
3609                 parsefile->buf = ckmalloc(BUFSIZ);
3610         parselleft = parsenleft = 0;
3611         plinno = 1;
3612 }
3613
3614
3615 /*
3616  * Set the input to take input from a file.  If push is set, push the
3617  * old input onto the stack first.
3618  */
3619
3620 static void
3621 setinputfile(const char *fname, int push)
3622 {
3623         int fd;
3624         int myfileno2;
3625
3626         INTOFF;
3627         if ((fd = open(fname, O_RDONLY)) < 0)
3628                 error("Can't open %s", fname);
3629         if (fd < 10) {
3630                 myfileno2 = dup_as_newfd(fd, 10);
3631                 close(fd);
3632                 if (myfileno2 < 0)
3633                         error("Out of file descriptors");
3634                 fd = myfileno2;
3635         }
3636         setinputfd(fd, push);
3637         INTON;
3638 }
3639
3640
3641 static void
3642 tryexec(char *cmd, char **argv, char **envp)
3643 {
3644         int e;
3645
3646 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
3647         char *name = cmd;
3648         char** argv_l=argv;
3649         int argc_l;
3650 #ifdef BB_FEATURE_SH_APPLETS_ALWAYS_WIN
3651         name = get_last_path_component(name);
3652 #endif
3653         argv_l=envp;
3654         for(argc_l=0;*argv_l!=NULL; argv_l++, argc_l++)
3655                 putenv(*argv_l);
3656         argv_l=argv;
3657         for(argc_l=0;*argv_l!=NULL; argv_l++, argc_l++)
3658         optind = 1;
3659         run_applet_by_name(name, argc_l, argv);
3660 #endif
3661         execve(cmd, argv, envp);
3662         e = errno;
3663         if (e == ENOEXEC) {
3664                 INTOFF;
3665                 initshellproc();
3666                 setinputfile(cmd, 0);
3667                 commandname = arg0 = savestr(argv[0]);
3668                 setparam(argv + 1);
3669                 exraise(EXSHELLPROC);
3670         }
3671         errno = e;
3672 }
3673
3674 static char *commandtext (const union node *);
3675
3676 /*
3677  * Do a path search.  The variable path (passed by reference) should be
3678  * set to the start of the path before the first call; padvance will update
3679  * this value as it proceeds.  Successive calls to padvance will return
3680  * the possible path expansions in sequence.  If an option (indicated by
3681  * a percent sign) appears in the path entry then the global variable
3682  * pathopt will be set to point to it; otherwise pathopt will be set to
3683  * NULL.
3684  */
3685
3686 static const char *pathopt;
3687
3688 static void growstackblock(void);
3689
3690
3691 static char *
3692 padvance(const char **path, const char *name)
3693 {
3694         const char *p;
3695         char *q;
3696         const char *start;
3697         int len;
3698
3699         if (*path == NULL)
3700                 return NULL;
3701         start = *path;
3702         for (p = start ; *p && *p != ':' && *p != '%' ; p++);
3703         len = p - start + strlen(name) + 2;     /* "2" is for '/' and '\0' */
3704         while (stackblocksize() < len)
3705                 growstackblock();
3706         q = stackblock();
3707         if (p != start) {
3708                 memcpy(q, start, p - start);
3709                 q += p - start;
3710                 *q++ = '/';
3711         }
3712         strcpy(q, name);
3713         pathopt = NULL;
3714         if (*p == '%') {
3715                 pathopt = ++p;
3716                 while (*p && *p != ':')  p++;
3717         }
3718         if (*p == ':')
3719                 *path = p + 1;
3720         else
3721                 *path = NULL;
3722         return stalloc(len);
3723 }
3724
3725 /*
3726  * Wrapper around strcmp for qsort/bsearch/...
3727  */
3728 static int
3729 pstrcmp(const void *a, const void *b)
3730 {
3731         return strcmp((const char *) a, *(const char *const *) b);
3732 }
3733
3734 /*
3735  * Find a keyword is in a sorted array.
3736  */
3737
3738 static const char *const *
3739 findkwd(const char *s)
3740 {
3741         return  bsearch(s, parsekwd, sizeof(parsekwd) / sizeof(const char *),
3742                         sizeof(const char *), pstrcmp);
3743 }
3744
3745
3746 /*** Command hashing code ***/
3747
3748
3749 static int
3750 hashcmd(argc, argv)
3751         int argc;
3752         char **argv;
3753 {
3754         struct tblentry **pp;
3755         struct tblentry *cmdp;
3756         int c;
3757         int verbose;
3758         struct cmdentry entry;
3759         char *name;
3760 #ifdef ASH_ALIAS
3761         const struct alias *ap;
3762 #endif
3763
3764         verbose = 0;
3765         while ((c = nextopt("rvV")) != '\0') {
3766                 if (c == 'r') {
3767                         clearcmdentry(0);
3768                         return 0;
3769                 } else if (c == 'v' || c == 'V') {
3770                         verbose = c;
3771                 }
3772         }
3773         if (*argptr == NULL) {
3774                 for (pp = cmdtable ; pp < &cmdtable[CMDTABLESIZE] ; pp++) {
3775                         for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) {
3776                                 if (cmdp->cmdtype != CMDBUILTIN) {
3777                                         printentry(cmdp, verbose);
3778                                 }
3779                         }
3780                 }
3781                 return 0;
3782         }
3783         c = 0;
3784         while ((name = *argptr++) != NULL) {
3785                 if ((cmdp = cmdlookup(name, 0)) != NULL
3786                  && (cmdp->cmdtype == CMDNORMAL
3787                      || (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0)))
3788                         delete_cmd_entry();
3789 #ifdef ASH_ALIAS
3790         /* Then look at the aliases */
3791                 if ((ap = lookupalias(name, 0)) != NULL) {
3792                         if (verbose=='v')
3793                                 printf("%s is an alias for %s\n", name, ap->val);
3794                         else
3795                                 printalias(ap);
3796                         continue;
3797                 }
3798 #endif
3799                         /* First look at the keywords */
3800                 if (findkwd(name)!=0) {
3801                         if (verbose=='v')
3802                                 printf("%s is a shell keyword\n", name);
3803                         else
3804                                 printf(snlfmt, name);
3805                         continue;
3806                 }
3807
3808                 find_command(name, &entry, DO_ERR, pathval());
3809                 if (entry.cmdtype == CMDUNKNOWN) c = 1;
3810                 else if (verbose) {
3811                         cmdp = cmdlookup(name, 0);
3812                         if (cmdp) printentry(cmdp, verbose=='v');
3813                         flushall();
3814                 }
3815         }
3816         return c;
3817 }
3818
3819 static void
3820 printentry(cmdp, verbose)
3821         struct tblentry *cmdp;
3822         int verbose;
3823         {
3824         int idx;
3825         const char *path;
3826         char *name;
3827
3828         printf("%s%s", cmdp->cmdname, (verbose ? " is " : ""));
3829         if (cmdp->cmdtype == CMDNORMAL) {
3830                 idx = cmdp->param.index;
3831                 path = pathval();
3832                 do {
3833                         name = padvance(&path, cmdp->cmdname);
3834                         stunalloc(name);
3835                 } while (--idx >= 0);
3836                 if(verbose)
3837                         out1str(name);
3838         } else if (cmdp->cmdtype == CMDBUILTIN) {
3839                 if(verbose)
3840                         out1str("a shell builtin");
3841         } else if (cmdp->cmdtype == CMDFUNCTION) {
3842                 if (verbose) {
3843                         INTOFF;
3844                         out1str("a function\n");
3845                         name = commandtext(cmdp->param.func);
3846                         printf("%s() {\n %s\n}", cmdp->cmdname, name);
3847                         ckfree(name);
3848                         INTON;
3849                 }
3850 #ifdef DEBUG
3851         } else {
3852                 error("internal error: cmdtype %d", cmdp->cmdtype);
3853 #endif
3854         }
3855         printf(snlfmt, cmdp->rehash ? "*" : nullstr);
3856 }
3857
3858
3859
3860 /*** List the available builtins ***/
3861
3862
3863 static int helpcmd(int argc, char** argv)
3864 {
3865         int col, i;
3866
3867         printf("\nBuilt-in commands:\n-------------------\n");
3868         for (col=0, i=0; i < NUMBUILTINS; i++) {
3869                 col += printf("%c%s", ((col == 0) ? '\t' : ' '),
3870                                 builtincmds[i].name+1);
3871                 if (col > 60) {
3872                         printf("\n");
3873                         col = 0;
3874                 }
3875         }
3876 #ifdef BB_FEATURE_SH_STANDALONE_SHELL
3877         {
3878                 extern const struct BB_applet applets[];
3879                 extern const size_t NUM_APPLETS;
3880
3881                 for (i=0; i < NUM_APPLETS; i++) {
3882
3883                         col += printf("%c%s", ((col == 0) ? '\t' : ' '),
3884                                         applets[i].name);
3885                         if (col > 60) {
3886                                 printf("\n");
3887                                 col = 0;
3888                         }
3889                 }
3890         }
3891 #endif
3892         printf("\n\n");
3893         return EXIT_SUCCESS;
3894 }
3895
3896 /*
3897  * Resolve a command name.  If you change this routine, you may have to
3898  * change the shellexec routine as well.
3899  */
3900
3901 static int prefix (const char *, const char *);
3902
3903 static void
3904 find_command(const char *name, struct cmdentry *entry, int act, const char *path)
3905 {
3906         struct tblentry *cmdp;
3907         int idx;
3908         int prev;
3909         char *fullname;
3910         struct stat statb;
3911         int e;
3912         int bltin;
3913         int firstchange;
3914         int updatetbl;
3915         int regular;
3916         struct builtincmd *bcmd;
3917
3918         /* If name contains a slash, don't use the hash table */
3919         if (strchr(name, '/') != NULL) {
3920                 if (act & DO_ABS) {
3921                         while (stat(name, &statb) < 0) {
3922                                 if (errno != ENOENT && errno != ENOTDIR)
3923                                         e = errno;
3924                                 entry->cmdtype = CMDUNKNOWN;
3925                                 entry->u.index = -1;
3926                                 return;
3927                         }
3928                         entry->cmdtype = CMDNORMAL;
3929                         entry->u.index = -1;
3930                         return;
3931                 }
3932                 entry->cmdtype = CMDNORMAL;
3933                 entry->u.index = 0;
3934                 return;
3935         }
3936
3937         updatetbl = 1;
3938         if (act & DO_BRUTE) {
3939                 firstchange = path_change(path, &bltin);
3940         } else {
3941                 bltin = builtinloc;
3942                 firstchange = 9999;
3943         }
3944
3945         /* If name is in the table, and not invalidated by cd, we're done */
3946         if ((cmdp = cmdlookup(name, 0)) != NULL && cmdp->rehash == 0) {
3947                 if (cmdp->cmdtype == CMDFUNCTION) {
3948                         if (act & DO_NOFUN) {
3949                                 updatetbl = 0;
3950                         } else {
3951                                 goto success;
3952                         }
3953                 } else if (act & DO_BRUTE) {
3954                         if ((cmdp->cmdtype == CMDNORMAL &&
3955                              cmdp->param.index >= firstchange) ||
3956                             (cmdp->cmdtype == CMDBUILTIN &&
3957                              ((builtinloc < 0 && bltin >= 0) ?
3958                               bltin : builtinloc) >= firstchange)) {
3959                                 /* need to recompute the entry */
3960                         } else {
3961                                 goto success;
3962                         }
3963                 } else {
3964                         goto success;
3965                 }
3966         }
3967
3968         bcmd = find_builtin(name);
3969         regular = bcmd && IS_BUILTIN_REGULAR(bcmd);
3970
3971         if (regular) {
3972                 if (cmdp && (cmdp->cmdtype == CMDBUILTIN)) {
3973                         goto success;
3974                 }
3975         } else if (act & DO_BRUTE) {
3976                 if (firstchange == 0) {
3977                         updatetbl = 0;
3978                 }
3979         }
3980
3981         /* If %builtin not in path, check for builtin next */
3982         if (regular || (bltin < 0 && bcmd)) {
3983 builtin:
3984                 if (!updatetbl) {
3985                         entry->cmdtype = CMDBUILTIN;
3986                         entry->u.cmd = bcmd;
3987                         return;
3988                 }
3989                 INTOFF;
3990                 cmdp = cmdlookup(name, 1);
3991                 cmdp->cmdtype = CMDBUILTIN;
3992                 cmdp->param.cmd = bcmd;
3993                 INTON;
3994                 goto success;
3995         }
3996
3997         /* We have to search path. */
3998         prev = -1;              /* where to start */
3999         if (cmdp && cmdp->rehash) {     /* doing a rehash */
4000                 if (cmdp->cmdtype == CMDBUILTIN)
4001                         prev = builtinloc;
4002                 else
4003                         prev = cmdp->param.index;
4004         }
4005
4006         e = ENOENT;
4007         idx = -1;
4008 loop:
4009         while ((fullname = padvance(&path, name)) != NULL) {
4010                 stunalloc(fullname);
4011                 idx++;
4012                 if (idx >= firstchange) {
4013                         updatetbl = 0;
4014                 }
4015                 if (pathopt) {
4016                         if (prefix("builtin", pathopt)) {
4017                                 if ((bcmd = find_builtin(name))) {
4018                                         goto builtin;
4019                                 }
4020                                 continue;