ash: handle "A=1 A=2 B=$A; echo $B". closes bug 947.
[oweals/busybox.git] / shell / 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  * Copyright (c) 1997-2005 Herbert Xu <herbert@gondor.apana.org.au>
9  * was re-ported from NetBSD and debianized.
10  *
11  *
12  * This code is derived from software contributed to Berkeley by
13  * Kenneth Almquist.
14  *
15  * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
16  *
17  * Original BSD copyright notice is retained at the end of this file.
18  */
19
20 /*
21  * rewrite arith.y to micro stack based cryptic algorithm by
22  * Copyright (c) 2001 Aaron Lehmann <aaronl@vitelus.com>
23  *
24  * Modified by Paul Mundt <lethal@linux-sh.org> (c) 2004 to support
25  * dynamic variables.
26  *
27  * Modified by Vladimir Oleynik <dzo@simtreas.ru> (c) 2001-2005 to be
28  * used in busybox and size optimizations,
29  * rewrote arith (see notes to this), added locale support,
30  * rewrote dynamic variables.
31  *
32  */
33
34 /*
35  * The follow should be set to reflect the type of system you have:
36  *      JOBS -> 1 if you have Berkeley job control, 0 otherwise.
37  *      define SYSV if you are running under System V.
38  *      define DEBUG=1 to compile in debugging ('set -o debug' to turn on)
39  *      define DEBUG=2 to compile in and turn on debugging.
40  *
41  * When debugging is on, debugging info will be written to ./trace and
42  * a quit signal will generate a core dump.
43  */
44 #define DEBUG 0
45 #define PROFILE 0
46
47 #define IFS_BROKEN
48
49 #define JOBS ENABLE_ASH_JOB_CONTROL
50
51 #if DEBUG
52 #ifndef _GNU_SOURCE
53 #define _GNU_SOURCE
54 #endif
55 #endif
56
57 #include "busybox.h" /* for applet_names */
58 #include <paths.h>
59 #include <setjmp.h>
60 #include <fnmatch.h>
61 #if JOBS || ENABLE_ASH_READ_NCHARS
62 #include <termios.h>
63 #endif
64
65 #if defined(__uClinux__)
66 #error "Do not even bother, ash will not run on uClinux"
67 #endif
68
69
70 /* ============ Hash table sizes. Configurable. */
71
72 #define VTABSIZE 39
73 #define ATABSIZE 39
74 #define CMDTABLESIZE 31         /* should be prime */
75
76
77 /* ============ Misc helpers */
78
79 #define xbarrier() do { __asm__ __volatile__ ("": : :"memory"); } while (0)
80
81 /* C99 say: "char" declaration may be signed or unsigned default */
82 #define signed_char2int(sc) ((int)((signed char)sc))
83
84
85 /* ============ Shell options */
86
87 static const char *const optletters_optnames[] = {
88         "e"   "errexit",
89         "f"   "noglob",
90         "I"   "ignoreeof",
91         "i"   "interactive",
92         "m"   "monitor",
93         "n"   "noexec",
94         "s"   "stdin",
95         "x"   "xtrace",
96         "v"   "verbose",
97         "C"   "noclobber",
98         "a"   "allexport",
99         "b"   "notify",
100         "u"   "nounset",
101         "\0"  "vi"
102 #if DEBUG
103         ,"\0"  "nolog"
104         ,"\0"  "debug"
105 #endif
106 };
107
108 #define optletters(n) optletters_optnames[(n)][0]
109 #define optnames(n) (&optletters_optnames[(n)][1])
110
111 enum { NOPTS = ARRAY_SIZE(optletters_optnames) };
112
113 static char optlist[NOPTS] ALIGN1;
114
115 #define eflag optlist[0]
116 #define fflag optlist[1]
117 #define Iflag optlist[2]
118 #define iflag optlist[3]
119 #define mflag optlist[4]
120 #define nflag optlist[5]
121 #define sflag optlist[6]
122 #define xflag optlist[7]
123 #define vflag optlist[8]
124 #define Cflag optlist[9]
125 #define aflag optlist[10]
126 #define bflag optlist[11]
127 #define uflag optlist[12]
128 #define viflag optlist[13]
129 #if DEBUG
130 #define nolog optlist[14]
131 #define debug optlist[15]
132 #endif
133
134
135 /* ============ Misc data */
136
137 static const char homestr[] ALIGN1 = "HOME";
138 static const char snlfmt[] ALIGN1 = "%s\n";
139 static const char illnum[] ALIGN1 = "Illegal number: %s";
140
141 /*
142  * We enclose jmp_buf in a structure so that we can declare pointers to
143  * jump locations.  The global variable handler contains the location to
144  * jump to when an exception occurs, and the global variable exception
145  * contains a code identifying the exception.  To implement nested
146  * exception handlers, the user should save the value of handler on entry
147  * to an inner scope, set handler to point to a jmploc structure for the
148  * inner scope, and restore handler on exit from the scope.
149  */
150 struct jmploc {
151         jmp_buf loc;
152 };
153
154 struct globals_misc {
155         /* pid of main shell */
156         int rootpid;
157         /* shell level: 0 for the main shell, 1 for its children, and so on */
158         int shlvl;
159 #define rootshell (!shlvl)
160         char *minusc;  /* argument to -c option */
161
162         char *curdir; // = nullstr;     /* current working directory */
163         char *physdir; // = nullstr;    /* physical working directory */
164
165         char *arg0; /* value of $0 */
166
167         struct jmploc *exception_handler;
168
169 // disabled by vda: cannot understand how it was supposed to work -
170 // cannot fix bugs. That's why you have to explain your non-trivial designs!
171 //      /* do we generate EXSIG events */
172 //      int exsig; /* counter */
173         volatile int suppressint; /* counter */
174         volatile /*sig_atomic_t*/ smallint intpending; /* 1 = got SIGINT */
175         /* last pending signal */
176         volatile /*sig_atomic_t*/ smallint pendingsig;
177         smallint exception; /* kind of exception (0..5) */
178         /* exceptions */
179 #define EXINT 0         /* SIGINT received */
180 #define EXERROR 1       /* a generic error */
181 #define EXSHELLPROC 2   /* execute a shell procedure */
182 #define EXEXEC 3        /* command execution failed */
183 #define EXEXIT 4        /* exit the shell */
184 #define EXSIG 5         /* trapped signal in wait(1) */
185
186         /* trap handler commands */
187         char *trap[NSIG];
188         smallint isloginsh;
189         char nullstr[1];                /* zero length string */
190         /*
191          * Sigmode records the current value of the signal handlers for the various
192          * modes.  A value of zero means that the current handler is not known.
193          * S_HARD_IGN indicates that the signal was ignored on entry to the shell,
194          */
195         char sigmode[NSIG - 1];
196 #define S_DFL 1                 /* default signal handling (SIG_DFL) */
197 #define S_CATCH 2               /* signal is caught */
198 #define S_IGN 3                 /* signal is ignored (SIG_IGN) */
199 #define S_HARD_IGN 4            /* signal is ignored permenantly */
200 #define S_RESET 5               /* temporary - to reset a hard ignored sig */
201
202         /* indicates specified signal received */
203         char gotsig[NSIG - 1];
204 };
205 /* Make it reside in writable memory, yet make compiler understand that it is not going to change. */
206 static struct globals_misc *const ptr_to_globals_misc __attribute__ ((section (".data")));
207 #define G_misc (*ptr_to_globals_misc)
208 #define rootpid   (G_misc.rootpid  )
209 #define shlvl     (G_misc.shlvl    )
210 #define minusc    (G_misc.minusc   )
211 #define curdir    (G_misc.curdir   )
212 #define physdir   (G_misc.physdir  )
213 #define arg0      (G_misc.arg0     )
214 #define exception_handler (G_misc.exception_handler)
215 #define exception         (G_misc.exception        )
216 #define suppressint       (G_misc.suppressint      )
217 #define intpending        (G_misc.intpending       )
218 //#define exsig             (G_misc.exsig            )
219 #define pendingsig        (G_misc.pendingsig       )
220 #define trap      (G_misc.trap     )
221 #define isloginsh (G_misc.isloginsh)
222 #define nullstr   (G_misc.nullstr  )
223 #define sigmode   (G_misc.sigmode  )
224 #define gotsig    (G_misc.gotsig   )
225 #define INIT_G_misc() do { \
226         (*(struct globals_misc**)&ptr_to_globals_misc) = xzalloc(sizeof(G_misc)); \
227         curdir = nullstr; \
228         physdir = nullstr; \
229 } while (0)
230
231
232 /* ============ Interrupts / exceptions */
233
234 /*
235  * These macros allow the user to suspend the handling of interrupt signals
236  * over a period of time.  This is similar to SIGHOLD or to sigblock, but
237  * much more efficient and portable.  (But hacking the kernel is so much
238  * more fun than worrying about efficiency and portability. :-))
239  */
240 #define INT_OFF \
241         do { \
242                 suppressint++; \
243                 xbarrier(); \
244         } while (0)
245
246 /*
247  * Called to raise an exception.  Since C doesn't include exceptions, we
248  * just do a longjmp to the exception handler.  The type of exception is
249  * stored in the global variable "exception".
250  */
251 static void raise_exception(int) ATTRIBUTE_NORETURN;
252 static void
253 raise_exception(int e)
254 {
255 #if DEBUG
256         if (exception_handler == NULL)
257                 abort();
258 #endif
259         INT_OFF;
260         exception = e;
261         longjmp(exception_handler->loc, 1);
262 }
263
264 /*
265  * Called from trap.c when a SIGINT is received.  (If the user specifies
266  * that SIGINT is to be trapped or ignored using the trap builtin, then
267  * this routine is not called.)  Suppressint is nonzero when interrupts
268  * are held using the INT_OFF macro.  (The test for iflag is just
269  * defensive programming.)
270  */
271 static void raise_interrupt(void) ATTRIBUTE_NORETURN;
272 static void
273 raise_interrupt(void)
274 {
275         int i;
276         sigset_t mask;
277
278         intpending = 0;
279         /* Signal is not automatically unmasked after it is raised,
280          * do it ourself - unmask all signals */
281         sigemptyset(&mask);
282         sigprocmask(SIG_SETMASK, &mask, NULL);
283         /* pendingsig = 0; - now done in onsig() */
284
285         i = EXSIG;
286         if (gotsig[SIGINT - 1] && !trap[SIGINT]) {
287                 if (!(rootshell && iflag)) {
288                         /* Kill ourself with SIGINT */
289                         signal(SIGINT, SIG_DFL);
290                         raise(SIGINT);
291                 }
292                 i = EXINT;
293         }
294         raise_exception(i);
295         /* NOTREACHED */
296 }
297
298 #if ENABLE_ASH_OPTIMIZE_FOR_SIZE
299 static void
300 int_on(void)
301 {
302         if (--suppressint == 0 && intpending) {
303                 raise_interrupt();
304         }
305 }
306 #define INT_ON int_on()
307 static void
308 force_int_on(void)
309 {
310         suppressint = 0;
311         if (intpending)
312                 raise_interrupt();
313 }
314 #define FORCE_INT_ON force_int_on()
315 #else
316 #define INT_ON \
317         do { \
318                 xbarrier(); \
319                 if (--suppressint == 0 && intpending) \
320                         raise_interrupt(); \
321         } while (0)
322 #define FORCE_INT_ON \
323         do { \
324                 xbarrier(); \
325                 suppressint = 0; \
326                 if (intpending) \
327                         raise_interrupt(); \
328         } while (0)
329 #endif /* ASH_OPTIMIZE_FOR_SIZE */
330
331 #define SAVE_INT(v) ((v) = suppressint)
332
333 #define RESTORE_INT(v) \
334         do { \
335                 xbarrier(); \
336                 suppressint = (v); \
337                 if (suppressint == 0 && intpending) \
338                         raise_interrupt(); \
339         } while (0)
340
341 /*
342  * Ignore a signal. Only one usage site - in forkchild()
343  */
344 static void
345 ignoresig(int signo)
346 {
347         if (sigmode[signo - 1] != S_IGN && sigmode[signo - 1] != S_HARD_IGN) {
348                 signal(signo, SIG_IGN);
349         }
350         sigmode[signo - 1] = S_HARD_IGN;
351 }
352
353 /*
354  * Signal handler. Only one usage site - in setsignal()
355  */
356 static void
357 onsig(int signo)
358 {
359         gotsig[signo - 1] = 1;
360         pendingsig = signo;
361
362         if ( /* exsig || */ (signo == SIGINT && !trap[SIGINT])) {
363                 if (!suppressint) {
364                         pendingsig = 0;
365                         raise_interrupt(); /* does not return */
366                 }
367                 intpending = 1;
368         }
369 }
370
371
372 /* ============ Stdout/stderr output */
373
374 static void
375 outstr(const char *p, FILE *file)
376 {
377         INT_OFF;
378         fputs(p, file);
379         INT_ON;
380 }
381
382 static void
383 flush_stdout_stderr(void)
384 {
385         INT_OFF;
386         fflush(stdout);
387         fflush(stderr);
388         INT_ON;
389 }
390
391 static void
392 flush_stderr(void)
393 {
394         INT_OFF;
395         fflush(stderr);
396         INT_ON;
397 }
398
399 static void
400 outcslow(int c, FILE *dest)
401 {
402         INT_OFF;
403         putc(c, dest);
404         fflush(dest);
405         INT_ON;
406 }
407
408 static int out1fmt(const char *, ...) __attribute__((__format__(__printf__,1,2)));
409 static int
410 out1fmt(const char *fmt, ...)
411 {
412         va_list ap;
413         int r;
414
415         INT_OFF;
416         va_start(ap, fmt);
417         r = vprintf(fmt, ap);
418         va_end(ap);
419         INT_ON;
420         return r;
421 }
422
423 static int fmtstr(char *, size_t, const char *, ...) __attribute__((__format__(__printf__,3,4)));
424 static int
425 fmtstr(char *outbuf, size_t length, const char *fmt, ...)
426 {
427         va_list ap;
428         int ret;
429
430         va_start(ap, fmt);
431         INT_OFF;
432         ret = vsnprintf(outbuf, length, fmt, ap);
433         va_end(ap);
434         INT_ON;
435         return ret;
436 }
437
438 static void
439 out1str(const char *p)
440 {
441         outstr(p, stdout);
442 }
443
444 static void
445 out2str(const char *p)
446 {
447         outstr(p, stderr);
448         flush_stderr();
449 }
450
451
452 /* ============ Parser structures */
453
454 /* control characters in argument strings */
455 #define CTLESC '\201'           /* escape next character */
456 #define CTLVAR '\202'           /* variable defn */
457 #define CTLENDVAR '\203'
458 #define CTLBACKQ '\204'
459 #define CTLQUOTE 01             /* ored with CTLBACKQ code if in quotes */
460 /*      CTLBACKQ | CTLQUOTE == '\205' */
461 #define CTLARI  '\206'          /* arithmetic expression */
462 #define CTLENDARI '\207'
463 #define CTLQUOTEMARK '\210'
464
465 /* variable substitution byte (follows CTLVAR) */
466 #define VSTYPE  0x0f            /* type of variable substitution */
467 #define VSNUL   0x10            /* colon--treat the empty string as unset */
468 #define VSQUOTE 0x80            /* inside double quotes--suppress splitting */
469
470 /* values of VSTYPE field */
471 #define VSNORMAL        0x1             /* normal variable:  $var or ${var} */
472 #define VSMINUS         0x2             /* ${var-text} */
473 #define VSPLUS          0x3             /* ${var+text} */
474 #define VSQUESTION      0x4             /* ${var?message} */
475 #define VSASSIGN        0x5             /* ${var=text} */
476 #define VSTRIMRIGHT     0x6             /* ${var%pattern} */
477 #define VSTRIMRIGHTMAX  0x7             /* ${var%%pattern} */
478 #define VSTRIMLEFT      0x8             /* ${var#pattern} */
479 #define VSTRIMLEFTMAX   0x9             /* ${var##pattern} */
480 #define VSLENGTH        0xa             /* ${#var} */
481
482 static const char dolatstr[] ALIGN1 = {
483         CTLVAR, VSNORMAL|VSQUOTE, '@', '=', '\0'
484 };
485
486 #define NCMD 0
487 #define NPIPE 1
488 #define NREDIR 2
489 #define NBACKGND 3
490 #define NSUBSHELL 4
491 #define NAND 5
492 #define NOR 6
493 #define NSEMI 7
494 #define NIF 8
495 #define NWHILE 9
496 #define NUNTIL 10
497 #define NFOR 11
498 #define NCASE 12
499 #define NCLIST 13
500 #define NDEFUN 14
501 #define NARG 15
502 #define NTO 16
503 #define NCLOBBER 17
504 #define NFROM 18
505 #define NFROMTO 19
506 #define NAPPEND 20
507 #define NTOFD 21
508 #define NFROMFD 22
509 #define NHERE 23
510 #define NXHERE 24
511 #define NNOT 25
512
513 union node;
514
515 struct ncmd {
516         int type;
517         union node *assign;
518         union node *args;
519         union node *redirect;
520 };
521
522 struct npipe {
523         int type;
524         int backgnd;
525         struct nodelist *cmdlist;
526 };
527
528 struct nredir {
529         int type;
530         union node *n;
531         union node *redirect;
532 };
533
534 struct nbinary {
535         int type;
536         union node *ch1;
537         union node *ch2;
538 };
539
540 struct nif {
541         int type;
542         union node *test;
543         union node *ifpart;
544         union node *elsepart;
545 };
546
547 struct nfor {
548         int type;
549         union node *args;
550         union node *body;
551         char *var;
552 };
553
554 struct ncase {
555         int type;
556         union node *expr;
557         union node *cases;
558 };
559
560 struct nclist {
561         int type;
562         union node *next;
563         union node *pattern;
564         union node *body;
565 };
566
567 struct narg {
568         int type;
569         union node *next;
570         char *text;
571         struct nodelist *backquote;
572 };
573
574 struct nfile {
575         int type;
576         union node *next;
577         int fd;
578         union node *fname;
579         char *expfname;
580 };
581
582 struct ndup {
583         int type;
584         union node *next;
585         int fd;
586         int dupfd;
587         union node *vname;
588 };
589
590 struct nhere {
591         int type;
592         union node *next;
593         int fd;
594         union node *doc;
595 };
596
597 struct nnot {
598         int type;
599         union node *com;
600 };
601
602 union node {
603         int type;
604         struct ncmd ncmd;
605         struct npipe npipe;
606         struct nredir nredir;
607         struct nbinary nbinary;
608         struct nif nif;
609         struct nfor nfor;
610         struct ncase ncase;
611         struct nclist nclist;
612         struct narg narg;
613         struct nfile nfile;
614         struct ndup ndup;
615         struct nhere nhere;
616         struct nnot nnot;
617 };
618
619 struct nodelist {
620         struct nodelist *next;
621         union node *n;
622 };
623
624 struct funcnode {
625         int count;
626         union node n;
627 };
628
629 /*
630  * Free a parse tree.
631  */
632 static void
633 freefunc(struct funcnode *f)
634 {
635         if (f && --f->count < 0)
636                 free(f);
637 }
638
639
640 /* ============ Debugging output */
641
642 #if DEBUG
643
644 static FILE *tracefile;
645
646 static void
647 trace_printf(const char *fmt, ...)
648 {
649         va_list va;
650
651         if (debug != 1)
652                 return;
653         va_start(va, fmt);
654         vfprintf(tracefile, fmt, va);
655         va_end(va);
656 }
657
658 static void
659 trace_vprintf(const char *fmt, va_list va)
660 {
661         if (debug != 1)
662                 return;
663         vfprintf(tracefile, fmt, va);
664 }
665
666 static void
667 trace_puts(const char *s)
668 {
669         if (debug != 1)
670                 return;
671         fputs(s, tracefile);
672 }
673
674 static void
675 trace_puts_quoted(char *s)
676 {
677         char *p;
678         char c;
679
680         if (debug != 1)
681                 return;
682         putc('"', tracefile);
683         for (p = s; *p; p++) {
684                 switch (*p) {
685                 case '\n':  c = 'n';  goto backslash;
686                 case '\t':  c = 't';  goto backslash;
687                 case '\r':  c = 'r';  goto backslash;
688                 case '"':  c = '"';  goto backslash;
689                 case '\\':  c = '\\';  goto backslash;
690                 case CTLESC:  c = 'e';  goto backslash;
691                 case CTLVAR:  c = 'v';  goto backslash;
692                 case CTLVAR+CTLQUOTE:  c = 'V'; goto backslash;
693                 case CTLBACKQ:  c = 'q';  goto backslash;
694                 case CTLBACKQ+CTLQUOTE:  c = 'Q'; goto backslash;
695  backslash:
696                         putc('\\', tracefile);
697                         putc(c, tracefile);
698                         break;
699                 default:
700                         if (*p >= ' ' && *p <= '~')
701                                 putc(*p, tracefile);
702                         else {
703                                 putc('\\', tracefile);
704                                 putc(*p >> 6 & 03, tracefile);
705                                 putc(*p >> 3 & 07, tracefile);
706                                 putc(*p & 07, tracefile);
707                         }
708                         break;
709                 }
710         }
711         putc('"', tracefile);
712 }
713
714 static void
715 trace_puts_args(char **ap)
716 {
717         if (debug != 1)
718                 return;
719         if (!*ap)
720                 return;
721         while (1) {
722                 trace_puts_quoted(*ap);
723                 if (!*++ap) {
724                         putc('\n', tracefile);
725                         break;
726                 }
727                 putc(' ', tracefile);
728         }
729 }
730
731 static void
732 opentrace(void)
733 {
734         char s[100];
735 #ifdef O_APPEND
736         int flags;
737 #endif
738
739         if (debug != 1) {
740                 if (tracefile)
741                         fflush(tracefile);
742                 /* leave open because libedit might be using it */
743                 return;
744         }
745         strcpy(s, "./trace");
746         if (tracefile) {
747                 if (!freopen(s, "a", tracefile)) {
748                         fprintf(stderr, "Can't re-open %s\n", s);
749                         debug = 0;
750                         return;
751                 }
752         } else {
753                 tracefile = fopen(s, "a");
754                 if (tracefile == NULL) {
755                         fprintf(stderr, "Can't open %s\n", s);
756                         debug = 0;
757                         return;
758                 }
759         }
760 #ifdef O_APPEND
761         flags = fcntl(fileno(tracefile), F_GETFL);
762         if (flags >= 0)
763                 fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND);
764 #endif
765         setlinebuf(tracefile);
766         fputs("\nTracing started.\n", tracefile);
767 }
768
769 static void
770 indent(int amount, char *pfx, FILE *fp)
771 {
772         int i;
773
774         for (i = 0; i < amount; i++) {
775                 if (pfx && i == amount - 1)
776                         fputs(pfx, fp);
777                 putc('\t', fp);
778         }
779 }
780
781 /* little circular references here... */
782 static void shtree(union node *n, int ind, char *pfx, FILE *fp);
783
784 static void
785 sharg(union node *arg, FILE *fp)
786 {
787         char *p;
788         struct nodelist *bqlist;
789         int subtype;
790
791         if (arg->type != NARG) {
792                 out1fmt("<node type %d>\n", arg->type);
793                 abort();
794         }
795         bqlist = arg->narg.backquote;
796         for (p = arg->narg.text; *p; p++) {
797                 switch (*p) {
798                 case CTLESC:
799                         putc(*++p, fp);
800                         break;
801                 case CTLVAR:
802                         putc('$', fp);
803                         putc('{', fp);
804                         subtype = *++p;
805                         if (subtype == VSLENGTH)
806                                 putc('#', fp);
807
808                         while (*p != '=')
809                                 putc(*p++, fp);
810
811                         if (subtype & VSNUL)
812                                 putc(':', fp);
813
814                         switch (subtype & VSTYPE) {
815                         case VSNORMAL:
816                                 putc('}', fp);
817                                 break;
818                         case VSMINUS:
819                                 putc('-', fp);
820                                 break;
821                         case VSPLUS:
822                                 putc('+', fp);
823                                 break;
824                         case VSQUESTION:
825                                 putc('?', fp);
826                                 break;
827                         case VSASSIGN:
828                                 putc('=', fp);
829                                 break;
830                         case VSTRIMLEFT:
831                                 putc('#', fp);
832                                 break;
833                         case VSTRIMLEFTMAX:
834                                 putc('#', fp);
835                                 putc('#', fp);
836                                 break;
837                         case VSTRIMRIGHT:
838                                 putc('%', fp);
839                                 break;
840                         case VSTRIMRIGHTMAX:
841                                 putc('%', fp);
842                                 putc('%', fp);
843                                 break;
844                         case VSLENGTH:
845                                 break;
846                         default:
847                                 out1fmt("<subtype %d>", subtype);
848                         }
849                         break;
850                 case CTLENDVAR:
851                         putc('}', fp);
852                         break;
853                 case CTLBACKQ:
854                 case CTLBACKQ|CTLQUOTE:
855                         putc('$', fp);
856                         putc('(', fp);
857                         shtree(bqlist->n, -1, NULL, fp);
858                         putc(')', fp);
859                         break;
860                 default:
861                         putc(*p, fp);
862                         break;
863                 }
864         }
865 }
866
867 static void
868 shcmd(union node *cmd, FILE *fp)
869 {
870         union node *np;
871         int first;
872         const char *s;
873         int dftfd;
874
875         first = 1;
876         for (np = cmd->ncmd.args; np; np = np->narg.next) {
877                 if (!first)
878                         putc(' ', fp);
879                 sharg(np, fp);
880                 first = 0;
881         }
882         for (np = cmd->ncmd.redirect; np; np = np->nfile.next) {
883                 if (!first)
884                         putc(' ', fp);
885                 dftfd = 0;
886                 switch (np->nfile.type) {
887                 case NTO:      s = ">>"+1; dftfd = 1; break;
888                 case NCLOBBER: s = ">|"; dftfd = 1; break;
889                 case NAPPEND:  s = ">>"; dftfd = 1; break;
890                 case NTOFD:    s = ">&"; dftfd = 1; break;
891                 case NFROM:    s = "<";  break;
892                 case NFROMFD:  s = "<&"; break;
893                 case NFROMTO:  s = "<>"; break;
894                 default:       s = "*error*"; break;
895                 }
896                 if (np->nfile.fd != dftfd)
897                         fprintf(fp, "%d", np->nfile.fd);
898                 fputs(s, fp);
899                 if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) {
900                         fprintf(fp, "%d", np->ndup.dupfd);
901                 } else {
902                         sharg(np->nfile.fname, fp);
903                 }
904                 first = 0;
905         }
906 }
907
908 static void
909 shtree(union node *n, int ind, char *pfx, FILE *fp)
910 {
911         struct nodelist *lp;
912         const char *s;
913
914         if (n == NULL)
915                 return;
916
917         indent(ind, pfx, fp);
918         switch (n->type) {
919         case NSEMI:
920                 s = "; ";
921                 goto binop;
922         case NAND:
923                 s = " && ";
924                 goto binop;
925         case NOR:
926                 s = " || ";
927  binop:
928                 shtree(n->nbinary.ch1, ind, NULL, fp);
929                 /* if (ind < 0) */
930                         fputs(s, fp);
931                 shtree(n->nbinary.ch2, ind, NULL, fp);
932                 break;
933         case NCMD:
934                 shcmd(n, fp);
935                 if (ind >= 0)
936                         putc('\n', fp);
937                 break;
938         case NPIPE:
939                 for (lp = n->npipe.cmdlist; lp; lp = lp->next) {
940                         shcmd(lp->n, fp);
941                         if (lp->next)
942                                 fputs(" | ", fp);
943                 }
944                 if (n->npipe.backgnd)
945                         fputs(" &", fp);
946                 if (ind >= 0)
947                         putc('\n', fp);
948                 break;
949         default:
950                 fprintf(fp, "<node type %d>", n->type);
951                 if (ind >= 0)
952                         putc('\n', fp);
953                 break;
954         }
955 }
956
957 static void
958 showtree(union node *n)
959 {
960         trace_puts("showtree called\n");
961         shtree(n, 1, NULL, stdout);
962 }
963
964 #define TRACE(param)    trace_printf param
965 #define TRACEV(param)   trace_vprintf param
966
967 #else
968
969 #define TRACE(param)
970 #define TRACEV(param)
971
972 #endif /* DEBUG */
973
974
975 /* ============ Parser data */
976
977 /*
978  * ash_vmsg() needs parsefile->fd, hence parsefile definition is moved up.
979  */
980 struct strlist {
981         struct strlist *next;
982         char *text;
983 };
984
985 #if ENABLE_ASH_ALIAS
986 struct alias;
987 #endif
988
989 struct strpush {
990         struct strpush *prev;   /* preceding string on stack */
991         char *prevstring;
992         int prevnleft;
993 #if ENABLE_ASH_ALIAS
994         struct alias *ap;       /* if push was associated with an alias */
995 #endif
996         char *string;           /* remember the string since it may change */
997 };
998
999 struct parsefile {
1000         struct parsefile *prev; /* preceding file on stack */
1001         int linno;              /* current line */
1002         int fd;                 /* file descriptor (or -1 if string) */
1003         int nleft;              /* number of chars left in this line */
1004         int lleft;              /* number of chars left in this buffer */
1005         char *nextc;            /* next char in buffer */
1006         char *buf;              /* input buffer */
1007         struct strpush *strpush; /* for pushing strings at this level */
1008         struct strpush basestrpush; /* so pushing one is fast */
1009 };
1010
1011 static struct parsefile basepf;         /* top level input file */
1012 static struct parsefile *parsefile = &basepf;  /* current input file */
1013 static int startlinno;                 /* line # where last token started */
1014 static char *commandname;              /* currently executing command */
1015 static struct strlist *cmdenviron;     /* environment for builtin command */
1016 static int exitstatus;                 /* exit status of last command */
1017
1018
1019 /* ============ Message printing */
1020
1021 static void
1022 ash_vmsg(const char *msg, va_list ap)
1023 {
1024         fprintf(stderr, "%s: ", arg0);
1025         if (commandname) {
1026                 if (strcmp(arg0, commandname))
1027                         fprintf(stderr, "%s: ", commandname);
1028                 if (!iflag || parsefile->fd)
1029                         fprintf(stderr, "line %d: ", startlinno);
1030         }
1031         vfprintf(stderr, msg, ap);
1032         outcslow('\n', stderr);
1033 }
1034
1035 /*
1036  * Exverror is called to raise the error exception.  If the second argument
1037  * is not NULL then error prints an error message using printf style
1038  * formatting.  It then raises the error exception.
1039  */
1040 static void ash_vmsg_and_raise(int, const char *, va_list) ATTRIBUTE_NORETURN;
1041 static void
1042 ash_vmsg_and_raise(int cond, const char *msg, va_list ap)
1043 {
1044 #if DEBUG
1045         if (msg) {
1046                 TRACE(("ash_vmsg_and_raise(%d, \"", cond));
1047                 TRACEV((msg, ap));
1048                 TRACE(("\") pid=%d\n", getpid()));
1049         } else
1050                 TRACE(("ash_vmsg_and_raise(%d, NULL) pid=%d\n", cond, getpid()));
1051         if (msg)
1052 #endif
1053                 ash_vmsg(msg, ap);
1054
1055         flush_stdout_stderr();
1056         raise_exception(cond);
1057         /* NOTREACHED */
1058 }
1059
1060 static void ash_msg_and_raise_error(const char *, ...) ATTRIBUTE_NORETURN;
1061 static void
1062 ash_msg_and_raise_error(const char *msg, ...)
1063 {
1064         va_list ap;
1065
1066         va_start(ap, msg);
1067         ash_vmsg_and_raise(EXERROR, msg, ap);
1068         /* NOTREACHED */
1069         va_end(ap);
1070 }
1071
1072 static void ash_msg_and_raise(int, const char *, ...) ATTRIBUTE_NORETURN;
1073 static void
1074 ash_msg_and_raise(int cond, const char *msg, ...)
1075 {
1076         va_list ap;
1077
1078         va_start(ap, msg);
1079         ash_vmsg_and_raise(cond, msg, ap);
1080         /* NOTREACHED */
1081         va_end(ap);
1082 }
1083
1084 /*
1085  * error/warning routines for external builtins
1086  */
1087 static void
1088 ash_msg(const char *fmt, ...)
1089 {
1090         va_list ap;
1091
1092         va_start(ap, fmt);
1093         ash_vmsg(fmt, ap);
1094         va_end(ap);
1095 }
1096
1097 /*
1098  * Return a string describing an error.  The returned string may be a
1099  * pointer to a static buffer that will be overwritten on the next call.
1100  * Action describes the operation that got the error.
1101  */
1102 static const char *
1103 errmsg(int e, const char *em)
1104 {
1105         if (e == ENOENT || e == ENOTDIR) {
1106                 return em;
1107         }
1108         return strerror(e);
1109 }
1110
1111
1112 /* ============ Memory allocation */
1113
1114 /*
1115  * It appears that grabstackstr() will barf with such alignments
1116  * because stalloc() will return a string allocated in a new stackblock.
1117  */
1118 #define SHELL_ALIGN(nbytes) (((nbytes) + SHELL_SIZE) & ~SHELL_SIZE)
1119 enum {
1120         /* Most machines require the value returned from malloc to be aligned
1121          * in some way.  The following macro will get this right
1122          * on many machines.  */
1123         SHELL_SIZE = sizeof(union {int i; char *cp; double d; }) - 1,
1124         /* Minimum size of a block */
1125         MINSIZE = SHELL_ALIGN(504),
1126 };
1127
1128 struct stack_block {
1129         struct stack_block *prev;
1130         char space[MINSIZE];
1131 };
1132
1133 struct stackmark {
1134         struct stack_block *stackp;
1135         char *stacknxt;
1136         size_t stacknleft;
1137         struct stackmark *marknext;
1138 };
1139
1140
1141 struct globals_memstack {
1142         struct stack_block *g_stackp; // = &stackbase;
1143         struct stackmark *markp;
1144         char *g_stacknxt; // = stackbase.space;
1145         char *sstrend; // = stackbase.space + MINSIZE;
1146         size_t g_stacknleft; // = MINSIZE;
1147         int    herefd; // = -1;
1148         struct stack_block stackbase;
1149 };
1150 /* Make it reside in writable memory, yet make compiler understand that it is not going to change. */
1151 static struct globals_memstack *const ptr_to_globals_memstack __attribute__ ((section (".data")));
1152 #define G_memstack (*ptr_to_globals_memstack)
1153 #define g_stackp     (G_memstack.g_stackp    )
1154 #define markp        (G_memstack.markp       )
1155 #define g_stacknxt   (G_memstack.g_stacknxt  )
1156 #define sstrend      (G_memstack.sstrend     )
1157 #define g_stacknleft (G_memstack.g_stacknleft)
1158 #define herefd       (G_memstack.herefd      )
1159 #define stackbase    (G_memstack.stackbase   )
1160 #define INIT_G_memstack() do { \
1161         (*(struct globals_memstack**)&ptr_to_globals_memstack) = xzalloc(sizeof(G_memstack)); \
1162         g_stackp = &stackbase; \
1163         g_stacknxt = stackbase.space; \
1164         g_stacknleft = MINSIZE; \
1165         sstrend = stackbase.space + MINSIZE; \
1166         herefd = -1; \
1167 } while (0)
1168
1169 #define stackblock()     ((void *)g_stacknxt)
1170 #define stackblocksize() g_stacknleft
1171
1172
1173 static void *
1174 ckrealloc(void * p, size_t nbytes)
1175 {
1176         p = realloc(p, nbytes);
1177         if (!p)
1178                 ash_msg_and_raise_error(bb_msg_memory_exhausted);
1179         return p;
1180 }
1181
1182 static void *
1183 ckmalloc(size_t nbytes)
1184 {
1185         return ckrealloc(NULL, nbytes);
1186 }
1187
1188 /*
1189  * Make a copy of a string in safe storage.
1190  */
1191 static char *
1192 ckstrdup(const char *s)
1193 {
1194         char *p = strdup(s);
1195         if (!p)
1196                 ash_msg_and_raise_error(bb_msg_memory_exhausted);
1197         return p;
1198 }
1199
1200 /*
1201  * Parse trees for commands are allocated in lifo order, so we use a stack
1202  * to make this more efficient, and also to avoid all sorts of exception
1203  * handling code to handle interrupts in the middle of a parse.
1204  *
1205  * The size 504 was chosen because the Ultrix malloc handles that size
1206  * well.
1207  */
1208 static void *
1209 stalloc(size_t nbytes)
1210 {
1211         char *p;
1212         size_t aligned;
1213
1214         aligned = SHELL_ALIGN(nbytes);
1215         if (aligned > g_stacknleft) {
1216                 size_t len;
1217                 size_t blocksize;
1218                 struct stack_block *sp;
1219
1220                 blocksize = aligned;
1221                 if (blocksize < MINSIZE)
1222                         blocksize = MINSIZE;
1223                 len = sizeof(struct stack_block) - MINSIZE + blocksize;
1224                 if (len < blocksize)
1225                         ash_msg_and_raise_error(bb_msg_memory_exhausted);
1226                 INT_OFF;
1227                 sp = ckmalloc(len);
1228                 sp->prev = g_stackp;
1229                 g_stacknxt = sp->space;
1230                 g_stacknleft = blocksize;
1231                 sstrend = g_stacknxt + blocksize;
1232                 g_stackp = sp;
1233                 INT_ON;
1234         }
1235         p = g_stacknxt;
1236         g_stacknxt += aligned;
1237         g_stacknleft -= aligned;
1238         return p;
1239 }
1240
1241 static void
1242 stunalloc(void *p)
1243 {
1244 #if DEBUG
1245         if (!p || (g_stacknxt < (char *)p) || ((char *)p < g_stackp->space)) {
1246                 write(2, "stunalloc\n", 10);
1247                 abort();
1248         }
1249 #endif
1250         g_stacknleft += g_stacknxt - (char *)p;
1251         g_stacknxt = p;
1252 }
1253
1254 /*
1255  * Like strdup but works with the ash stack.
1256  */
1257 static char *
1258 ststrdup(const char *p)
1259 {
1260         size_t len = strlen(p) + 1;
1261         return memcpy(stalloc(len), p, len);
1262 }
1263
1264 static void
1265 setstackmark(struct stackmark *mark)
1266 {
1267         mark->stackp = g_stackp;
1268         mark->stacknxt = g_stacknxt;
1269         mark->stacknleft = g_stacknleft;
1270         mark->marknext = markp;
1271         markp = mark;
1272 }
1273
1274 static void
1275 popstackmark(struct stackmark *mark)
1276 {
1277         struct stack_block *sp;
1278
1279         if (!mark->stackp)
1280                 return;
1281
1282         INT_OFF;
1283         markp = mark->marknext;
1284         while (g_stackp != mark->stackp) {
1285                 sp = g_stackp;
1286                 g_stackp = sp->prev;
1287                 free(sp);
1288         }
1289         g_stacknxt = mark->stacknxt;
1290         g_stacknleft = mark->stacknleft;
1291         sstrend = mark->stacknxt + mark->stacknleft;
1292         INT_ON;
1293 }
1294
1295 /*
1296  * When the parser reads in a string, it wants to stick the string on the
1297  * stack and only adjust the stack pointer when it knows how big the
1298  * string is.  Stackblock (defined in stack.h) returns a pointer to a block
1299  * of space on top of the stack and stackblocklen returns the length of
1300  * this block.  Growstackblock will grow this space by at least one byte,
1301  * possibly moving it (like realloc).  Grabstackblock actually allocates the
1302  * part of the block that has been used.
1303  */
1304 static void
1305 growstackblock(void)
1306 {
1307         size_t newlen;
1308
1309         newlen = g_stacknleft * 2;
1310         if (newlen < g_stacknleft)
1311                 ash_msg_and_raise_error(bb_msg_memory_exhausted);
1312         if (newlen < 128)
1313                 newlen += 128;
1314
1315         if (g_stacknxt == g_stackp->space && g_stackp != &stackbase) {
1316                 struct stack_block *oldstackp;
1317                 struct stackmark *xmark;
1318                 struct stack_block *sp;
1319                 struct stack_block *prevstackp;
1320                 size_t grosslen;
1321
1322                 INT_OFF;
1323                 oldstackp = g_stackp;
1324                 sp = g_stackp;
1325                 prevstackp = sp->prev;
1326                 grosslen = newlen + sizeof(struct stack_block) - MINSIZE;
1327                 sp = ckrealloc(sp, grosslen);
1328                 sp->prev = prevstackp;
1329                 g_stackp = sp;
1330                 g_stacknxt = sp->space;
1331                 g_stacknleft = newlen;
1332                 sstrend = sp->space + newlen;
1333
1334                 /*
1335                  * Stack marks pointing to the start of the old block
1336                  * must be relocated to point to the new block
1337                  */
1338                 xmark = markp;
1339                 while (xmark != NULL && xmark->stackp == oldstackp) {
1340                         xmark->stackp = g_stackp;
1341                         xmark->stacknxt = g_stacknxt;
1342                         xmark->stacknleft = g_stacknleft;
1343                         xmark = xmark->marknext;
1344                 }
1345                 INT_ON;
1346         } else {
1347                 char *oldspace = g_stacknxt;
1348                 int oldlen = g_stacknleft;
1349                 char *p = stalloc(newlen);
1350
1351                 /* free the space we just allocated */
1352                 g_stacknxt = memcpy(p, oldspace, oldlen);
1353                 g_stacknleft += newlen;
1354         }
1355 }
1356
1357 static void
1358 grabstackblock(size_t len)
1359 {
1360         len = SHELL_ALIGN(len);
1361         g_stacknxt += len;
1362         g_stacknleft -= len;
1363 }
1364
1365 /*
1366  * The following routines are somewhat easier to use than the above.
1367  * The user declares a variable of type STACKSTR, which may be declared
1368  * to be a register.  The macro STARTSTACKSTR initializes things.  Then
1369  * the user uses the macro STPUTC to add characters to the string.  In
1370  * effect, STPUTC(c, p) is the same as *p++ = c except that the stack is
1371  * grown as necessary.  When the user is done, she can just leave the
1372  * string there and refer to it using stackblock().  Or she can allocate
1373  * the space for it using grabstackstr().  If it is necessary to allow
1374  * someone else to use the stack temporarily and then continue to grow
1375  * the string, the user should use grabstack to allocate the space, and
1376  * then call ungrabstr(p) to return to the previous mode of operation.
1377  *
1378  * USTPUTC is like STPUTC except that it doesn't check for overflow.
1379  * CHECKSTACKSPACE can be called before USTPUTC to ensure that there
1380  * is space for at least one character.
1381  */
1382 static void *
1383 growstackstr(void)
1384 {
1385         size_t len = stackblocksize();
1386         if (herefd >= 0 && len >= 1024) {
1387                 full_write(herefd, stackblock(), len);
1388                 return stackblock();
1389         }
1390         growstackblock();
1391         return stackblock() + len;
1392 }
1393
1394 /*
1395  * Called from CHECKSTRSPACE.
1396  */
1397 static char *
1398 makestrspace(size_t newlen, char *p)
1399 {
1400         size_t len = p - g_stacknxt;
1401         size_t size = stackblocksize();
1402
1403         for (;;) {
1404                 size_t nleft;
1405
1406                 size = stackblocksize();
1407                 nleft = size - len;
1408                 if (nleft >= newlen)
1409                         break;
1410                 growstackblock();
1411         }
1412         return stackblock() + len;
1413 }
1414
1415 static char *
1416 stack_nputstr(const char *s, size_t n, char *p)
1417 {
1418         p = makestrspace(n, p);
1419         p = memcpy(p, s, n) + n;
1420         return p;
1421 }
1422
1423 static char *
1424 stack_putstr(const char *s, char *p)
1425 {
1426         return stack_nputstr(s, strlen(s), p);
1427 }
1428
1429 static char *
1430 _STPUTC(int c, char *p)
1431 {
1432         if (p == sstrend)
1433                 p = growstackstr();
1434         *p++ = c;
1435         return p;
1436 }
1437
1438 #define STARTSTACKSTR(p)        ((p) = stackblock())
1439 #define STPUTC(c, p)            ((p) = _STPUTC((c), (p)))
1440 #define CHECKSTRSPACE(n, p) \
1441         do { \
1442                 char *q = (p); \
1443                 size_t l = (n); \
1444                 size_t m = sstrend - q; \
1445                 if (l > m) \
1446                         (p) = makestrspace(l, q); \
1447         } while (0)
1448 #define USTPUTC(c, p)           (*p++ = (c))
1449 #define STACKSTRNUL(p) \
1450         do { \
1451                 if ((p) == sstrend) \
1452                         p = growstackstr(); \
1453                 *p = '\0'; \
1454         } while (0)
1455 #define STUNPUTC(p)             (--p)
1456 #define STTOPC(p)               (p[-1])
1457 #define STADJUST(amount, p)     (p += (amount))
1458
1459 #define grabstackstr(p)         stalloc((char *)(p) - (char *)stackblock())
1460 #define ungrabstackstr(s, p)    stunalloc((s))
1461 #define stackstrend()           ((void *)sstrend)
1462
1463
1464 /* ============ String helpers */
1465
1466 /*
1467  * prefix -- see if pfx is a prefix of string.
1468  */
1469 static char *
1470 prefix(const char *string, const char *pfx)
1471 {
1472         while (*pfx) {
1473                 if (*pfx++ != *string++)
1474                         return NULL;
1475         }
1476         return (char *) string;
1477 }
1478
1479 /*
1480  * Check for a valid number.  This should be elsewhere.
1481  */
1482 static int
1483 is_number(const char *p)
1484 {
1485         do {
1486                 if (!isdigit(*p))
1487                         return 0;
1488         } while (*++p != '\0');
1489         return 1;
1490 }
1491
1492 /*
1493  * Convert a string of digits to an integer, printing an error message on
1494  * failure.
1495  */
1496 static int
1497 number(const char *s)
1498 {
1499         if (!is_number(s))
1500                 ash_msg_and_raise_error(illnum, s);
1501         return atoi(s);
1502 }
1503
1504 /*
1505  * Produce a possibly single quoted string suitable as input to the shell.
1506  * The return string is allocated on the stack.
1507  */
1508 static char *
1509 single_quote(const char *s)
1510 {
1511         char *p;
1512
1513         STARTSTACKSTR(p);
1514
1515         do {
1516                 char *q;
1517                 size_t len;
1518
1519                 len = strchrnul(s, '\'') - s;
1520
1521                 q = p = makestrspace(len + 3, p);
1522
1523                 *q++ = '\'';
1524                 q = memcpy(q, s, len) + len;
1525                 *q++ = '\'';
1526                 s += len;
1527
1528                 STADJUST(q - p, p);
1529
1530                 len = strspn(s, "'");
1531                 if (!len)
1532                         break;
1533
1534                 q = p = makestrspace(len + 3, p);
1535
1536                 *q++ = '"';
1537                 q = memcpy(q, s, len) + len;
1538                 *q++ = '"';
1539                 s += len;
1540
1541                 STADJUST(q - p, p);
1542         } while (*s);
1543
1544         USTPUTC(0, p);
1545
1546         return stackblock();
1547 }
1548
1549
1550 /* ============ nextopt */
1551
1552 static char **argptr;                  /* argument list for builtin commands */
1553 static char *optionarg;                /* set by nextopt (like getopt) */
1554 static char *optptr;                   /* used by nextopt */
1555
1556 /*
1557  * XXX - should get rid of.  have all builtins use getopt(3).  the
1558  * library getopt must have the BSD extension static variable "optreset"
1559  * otherwise it can't be used within the shell safely.
1560  *
1561  * Standard option processing (a la getopt) for builtin routines.  The
1562  * only argument that is passed to nextopt is the option string; the
1563  * other arguments are unnecessary.  It return the character, or '\0' on
1564  * end of input.
1565  */
1566 static int
1567 nextopt(const char *optstring)
1568 {
1569         char *p;
1570         const char *q;
1571         char c;
1572
1573         p = optptr;
1574         if (p == NULL || *p == '\0') {
1575                 p = *argptr;
1576                 if (p == NULL || *p != '-' || *++p == '\0')
1577                         return '\0';
1578                 argptr++;
1579                 if (LONE_DASH(p))        /* check for "--" */
1580                         return '\0';
1581         }
1582         c = *p++;
1583         for (q = optstring; *q != c; ) {
1584                 if (*q == '\0')
1585                         ash_msg_and_raise_error("illegal option -%c", c);
1586                 if (*++q == ':')
1587                         q++;
1588         }
1589         if (*++q == ':') {
1590                 if (*p == '\0' && (p = *argptr++) == NULL)
1591                         ash_msg_and_raise_error("no arg for -%c option", c);
1592                 optionarg = p;
1593                 p = NULL;
1594         }
1595         optptr = p;
1596         return c;
1597 }
1598
1599
1600 /* ============ Math support definitions */
1601
1602 #if ENABLE_ASH_MATH_SUPPORT_64
1603 typedef int64_t arith_t;
1604 #define arith_t_type long long
1605 #else
1606 typedef long arith_t;
1607 #define arith_t_type long
1608 #endif
1609
1610 #if ENABLE_ASH_MATH_SUPPORT
1611 static arith_t dash_arith(const char *);
1612 static arith_t arith(const char *expr, int *perrcode);
1613 #endif
1614
1615 #if ENABLE_ASH_RANDOM_SUPPORT
1616 static unsigned long rseed;
1617 #ifndef DYNAMIC_VAR
1618 #define DYNAMIC_VAR
1619 #endif
1620 #endif
1621
1622
1623 /* ============ Shell variables */
1624
1625 /*
1626  * The parsefile structure pointed to by the global variable parsefile
1627  * contains information about the current file being read.
1628  */
1629 struct redirtab {
1630         struct redirtab *next;
1631         int renamed[10];
1632         int nullredirs;
1633 };
1634
1635 struct shparam {
1636         int nparam;             /* # of positional parameters (without $0) */
1637 #if ENABLE_ASH_GETOPTS
1638         int optind;             /* next parameter to be processed by getopts */
1639         int optoff;             /* used by getopts */
1640 #endif
1641         unsigned char malloced; /* if parameter list dynamically allocated */
1642         char **p;               /* parameter list */
1643 };
1644
1645 /*
1646  * Free the list of positional parameters.
1647  */
1648 static void
1649 freeparam(volatile struct shparam *param)
1650 {
1651         char **ap;
1652
1653         if (param->malloced) {
1654                 for (ap = param->p; *ap; ap++)
1655                         free(*ap);
1656                 free(param->p);
1657         }
1658 }
1659
1660 #if ENABLE_ASH_GETOPTS
1661 static void getoptsreset(const char *value);
1662 #endif
1663
1664 struct var {
1665         struct var *next;               /* next entry in hash list */
1666         int flags;                      /* flags are defined above */
1667         const char *text;               /* name=value */
1668         void (*func)(const char *);     /* function to be called when  */
1669                                         /* the variable gets set/unset */
1670 };
1671
1672 struct localvar {
1673         struct localvar *next;          /* next local variable in list */
1674         struct var *vp;                 /* the variable that was made local */
1675         int flags;                      /* saved flags */
1676         const char *text;               /* saved text */
1677 };
1678
1679 /* flags */
1680 #define VEXPORT         0x01    /* variable is exported */
1681 #define VREADONLY       0x02    /* variable cannot be modified */
1682 #define VSTRFIXED       0x04    /* variable struct is statically allocated */
1683 #define VTEXTFIXED      0x08    /* text is statically allocated */
1684 #define VSTACK          0x10    /* text is allocated on the stack */
1685 #define VUNSET          0x20    /* the variable is not set */
1686 #define VNOFUNC         0x40    /* don't call the callback function */
1687 #define VNOSET          0x80    /* do not set variable - just readonly test */
1688 #define VNOSAVE         0x100   /* when text is on the heap before setvareq */
1689 #ifdef DYNAMIC_VAR
1690 # define VDYNAMIC       0x200   /* dynamic variable */
1691 #else
1692 # define VDYNAMIC       0
1693 #endif
1694
1695 #ifdef IFS_BROKEN
1696 static const char defifsvar[] ALIGN1 = "IFS= \t\n";
1697 #define defifs (defifsvar + 4)
1698 #else
1699 static const char defifs[] ALIGN1 = " \t\n";
1700 #endif
1701
1702
1703 /* Need to be before varinit_data[] */
1704 #if ENABLE_LOCALE_SUPPORT
1705 static void
1706 change_lc_all(const char *value)
1707 {
1708         if (value && *value != '\0')
1709                 setlocale(LC_ALL, value);
1710 }
1711 static void
1712 change_lc_ctype(const char *value)
1713 {
1714         if (value && *value != '\0')
1715                 setlocale(LC_CTYPE, value);
1716 }
1717 #endif
1718 #if ENABLE_ASH_MAIL
1719 static void chkmail(void);
1720 static void changemail(const char *);
1721 #endif
1722 static void changepath(const char *);
1723 #if ENABLE_ASH_RANDOM_SUPPORT
1724 static void change_random(const char *);
1725 #endif
1726
1727 static const struct {
1728         int flags;
1729         const char *text;
1730         void (*func)(const char *);
1731 } varinit_data[] = {
1732 #ifdef IFS_BROKEN
1733         { VSTRFIXED|VTEXTFIXED       , defifsvar   , NULL            },
1734 #else
1735         { VSTRFIXED|VTEXTFIXED|VUNSET, "IFS\0"     , NULL            },
1736 #endif
1737 #if ENABLE_ASH_MAIL
1738         { VSTRFIXED|VTEXTFIXED|VUNSET, "MAIL\0"    , changemail      },
1739         { VSTRFIXED|VTEXTFIXED|VUNSET, "MAILPATH\0", changemail      },
1740 #endif
1741         { VSTRFIXED|VTEXTFIXED       , bb_PATH_root_path, changepath },
1742         { VSTRFIXED|VTEXTFIXED       , "PS1=$ "    , NULL            },
1743         { VSTRFIXED|VTEXTFIXED       , "PS2=> "    , NULL            },
1744         { VSTRFIXED|VTEXTFIXED       , "PS4=+ "    , NULL            },
1745 #if ENABLE_ASH_GETOPTS
1746         { VSTRFIXED|VTEXTFIXED       , "OPTIND=1"  , getoptsreset    },
1747 #endif
1748 #if ENABLE_ASH_RANDOM_SUPPORT
1749         { VSTRFIXED|VTEXTFIXED|VUNSET|VDYNAMIC, "RANDOM\0", change_random },
1750 #endif
1751 #if ENABLE_LOCALE_SUPPORT
1752         { VSTRFIXED|VTEXTFIXED|VUNSET, "LC_ALL\0"  , change_lc_all   },
1753         { VSTRFIXED|VTEXTFIXED|VUNSET, "LC_CTYPE\0", change_lc_ctype },
1754 #endif
1755 #if ENABLE_FEATURE_EDITING_SAVEHISTORY
1756         { VSTRFIXED|VTEXTFIXED|VUNSET, "HISTFILE\0", NULL            },
1757 #endif
1758 };
1759
1760
1761 struct globals_var {
1762         struct shparam shellparam;      /* $@ current positional parameters */
1763         struct redirtab *redirlist;
1764         int g_nullredirs;
1765         int preverrout_fd;   /* save fd2 before print debug if xflag is set. */
1766         struct var *vartab[VTABSIZE];
1767         struct var varinit[ARRAY_SIZE(varinit_data)];
1768 };
1769 /* Make it reside in writable memory, yet make compiler understand that it is not going to change. */
1770 static struct globals_var *const ptr_to_globals_var __attribute__ ((section (".data")));
1771 #define G_var (*ptr_to_globals_var)
1772 #define shellparam    (G_var.shellparam   )
1773 #define redirlist     (G_var.redirlist    )
1774 #define g_nullredirs  (G_var.g_nullredirs )
1775 #define preverrout_fd (G_var.preverrout_fd)
1776 #define vartab        (G_var.vartab       )
1777 #define varinit       (G_var.varinit      )
1778 #define INIT_G_var() do { \
1779         int i; \
1780         (*(struct globals_var**)&ptr_to_globals_var) = xzalloc(sizeof(G_var)); \
1781         for (i = 0; i < ARRAY_SIZE(varinit_data); i++) { \
1782                 varinit[i].flags = varinit_data[i].flags; \
1783                 varinit[i].text  = varinit_data[i].text; \
1784                 varinit[i].func  = varinit_data[i].func; \
1785         } \
1786 } while (0)
1787
1788 #define vifs    varinit[0]
1789 #if ENABLE_ASH_MAIL
1790 #define vmail   (&vifs)[1]
1791 #define vmpath  (&vmail)[1]
1792 #else
1793 #define vmpath  vifs
1794 #endif
1795 #define vpath   (&vmpath)[1]
1796 #define vps1    (&vpath)[1]
1797 #define vps2    (&vps1)[1]
1798 #define vps4    (&vps2)[1]
1799 #define voptind (&vps4)[1]
1800 #if ENABLE_ASH_GETOPTS
1801 #define vrandom (&voptind)[1]
1802 #else
1803 #define vrandom (&vps4)[1]
1804 #endif
1805
1806 /*
1807  * The following macros access the values of the above variables.
1808  * They have to skip over the name.  They return the null string
1809  * for unset variables.
1810  */
1811 #define ifsval()        (vifs.text + 4)
1812 #define ifsset()        ((vifs.flags & VUNSET) == 0)
1813 #define mailval()       (vmail.text + 5)
1814 #define mpathval()      (vmpath.text + 9)
1815 #define pathval()       (vpath.text + 5)
1816 #define ps1val()        (vps1.text + 4)
1817 #define ps2val()        (vps2.text + 4)
1818 #define ps4val()        (vps4.text + 4)
1819 #define optindval()     (voptind.text + 7)
1820
1821 #define mpathset()      ((vmpath.flags & VUNSET) == 0)
1822
1823
1824 #define is_name(c)      ((c) == '_' || isalpha((unsigned char)(c)))
1825 #define is_in_name(c)   ((c) == '_' || isalnum((unsigned char)(c)))
1826
1827 #if ENABLE_ASH_GETOPTS
1828 static void
1829 getoptsreset(const char *value)
1830 {
1831         shellparam.optind = number(value);
1832         shellparam.optoff = -1;
1833 }
1834 #endif
1835
1836 /*
1837  * Return of a legal variable name (a letter or underscore followed by zero or
1838  * more letters, underscores, and digits).
1839  */
1840 static char *
1841 endofname(const char *name)
1842 {
1843         char *p;
1844
1845         p = (char *) name;
1846         if (!is_name(*p))
1847                 return p;
1848         while (*++p) {
1849                 if (!is_in_name(*p))
1850                         break;
1851         }
1852         return p;
1853 }
1854
1855 /*
1856  * Compares two strings up to the first = or '\0'.  The first
1857  * string must be terminated by '='; the second may be terminated by
1858  * either '=' or '\0'.
1859  */
1860 static int
1861 varcmp(const char *p, const char *q)
1862 {
1863         int c, d;
1864
1865         while ((c = *p) == (d = *q)) {
1866                 if (!c || c == '=')
1867                         goto out;
1868                 p++;
1869                 q++;
1870         }
1871         if (c == '=')
1872                 c = '\0';
1873         if (d == '=')
1874                 d = '\0';
1875  out:
1876         return c - d;
1877 }
1878
1879 static int
1880 varequal(const char *a, const char *b)
1881 {
1882         return !varcmp(a, b);
1883 }
1884
1885 /*
1886  * Find the appropriate entry in the hash table from the name.
1887  */
1888 static struct var **
1889 hashvar(const char *p)
1890 {
1891         unsigned hashval;
1892
1893         hashval = ((unsigned char) *p) << 4;
1894         while (*p && *p != '=')
1895                 hashval += (unsigned char) *p++;
1896         return &vartab[hashval % VTABSIZE];
1897 }
1898
1899 static int
1900 vpcmp(const void *a, const void *b)
1901 {
1902         return varcmp(*(const char **)a, *(const char **)b);
1903 }
1904
1905 /*
1906  * This routine initializes the builtin variables.
1907  */
1908 static void
1909 initvar(void)
1910 {
1911         struct var *vp;
1912         struct var *end;
1913         struct var **vpp;
1914
1915         /*
1916          * PS1 depends on uid
1917          */
1918 #if ENABLE_FEATURE_EDITING && ENABLE_FEATURE_EDITING_FANCY_PROMPT
1919         vps1.text = "PS1=\\w \\$ ";
1920 #else
1921         if (!geteuid())
1922                 vps1.text = "PS1=# ";
1923 #endif
1924         vp = varinit;
1925         end = vp + ARRAY_SIZE(varinit);
1926         do {
1927                 vpp = hashvar(vp->text);
1928                 vp->next = *vpp;
1929                 *vpp = vp;
1930         } while (++vp < end);
1931 }
1932
1933 static struct var **
1934 findvar(struct var **vpp, const char *name)
1935 {
1936         for (; *vpp; vpp = &(*vpp)->next) {
1937                 if (varequal((*vpp)->text, name)) {
1938                         break;
1939                 }
1940         }
1941         return vpp;
1942 }
1943
1944 /*
1945  * Find the value of a variable.  Returns NULL if not set.
1946  */
1947 static char *
1948 lookupvar(const char *name)
1949 {
1950         struct var *v;
1951
1952         v = *findvar(hashvar(name), name);
1953         if (v) {
1954 #ifdef DYNAMIC_VAR
1955         /*
1956          * Dynamic variables are implemented roughly the same way they are
1957          * in bash. Namely, they're "special" so long as they aren't unset.
1958          * As soon as they're unset, they're no longer dynamic, and dynamic
1959          * lookup will no longer happen at that point. -- PFM.
1960          */
1961                 if ((v->flags & VDYNAMIC))
1962                         (*v->func)(NULL);
1963 #endif
1964                 if (!(v->flags & VUNSET))
1965                         return strchrnul(v->text, '=') + 1;
1966         }
1967         return NULL;
1968 }
1969
1970 /*
1971  * Search the environment of a builtin command.
1972  */
1973 static char *
1974 bltinlookup(const char *name)
1975 {
1976         struct strlist *sp;
1977
1978         for (sp = cmdenviron; sp; sp = sp->next) {
1979                 if (varequal(sp->text, name))
1980                         return strchrnul(sp->text, '=') + 1;
1981         }
1982         return lookupvar(name);
1983 }
1984
1985 /*
1986  * Same as setvar except that the variable and value are passed in
1987  * the first argument as name=value.  Since the first argument will
1988  * be actually stored in the table, it should not be a string that
1989  * will go away.
1990  * Called with interrupts off.
1991  */
1992 static void
1993 setvareq(char *s, int flags)
1994 {
1995         struct var *vp, **vpp;
1996
1997         vpp = hashvar(s);
1998         flags |= (VEXPORT & (((unsigned) (1 - aflag)) - 1));
1999         vp = *findvar(vpp, s);
2000         if (vp) {
2001                 if ((vp->flags & (VREADONLY|VDYNAMIC)) == VREADONLY) {
2002                         const char *n;
2003
2004                         if (flags & VNOSAVE)
2005                                 free(s);
2006                         n = vp->text;
2007                         ash_msg_and_raise_error("%.*s: is read only", strchrnul(n, '=') - n, n);
2008                 }
2009
2010                 if (flags & VNOSET)
2011                         return;
2012
2013                 if (vp->func && (flags & VNOFUNC) == 0)
2014                         (*vp->func)(strchrnul(s, '=') + 1);
2015
2016                 if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0)
2017                         free((char*)vp->text);
2018
2019                 flags |= vp->flags & ~(VTEXTFIXED|VSTACK|VNOSAVE|VUNSET);
2020         } else {
2021                 if (flags & VNOSET)
2022                         return;
2023                 /* not found */
2024                 vp = ckmalloc(sizeof(*vp));
2025                 vp->next = *vpp;
2026                 vp->func = NULL;
2027                 *vpp = vp;
2028         }
2029         if (!(flags & (VTEXTFIXED|VSTACK|VNOSAVE)))
2030                 s = ckstrdup(s);
2031         vp->text = s;
2032         vp->flags = flags;
2033 }
2034
2035 /*
2036  * Set the value of a variable.  The flags argument is ored with the
2037  * flags of the variable.  If val is NULL, the variable is unset.
2038  */
2039 static void
2040 setvar(const char *name, const char *val, int flags)
2041 {
2042         char *p, *q;
2043         size_t namelen;
2044         char *nameeq;
2045         size_t vallen;
2046
2047         q = endofname(name);
2048         p = strchrnul(q, '=');
2049         namelen = p - name;
2050         if (!namelen || p != q)
2051                 ash_msg_and_raise_error("%.*s: bad variable name", namelen, name);
2052         vallen = 0;
2053         if (val == NULL) {
2054                 flags |= VUNSET;
2055         } else {
2056                 vallen = strlen(val);
2057         }
2058         INT_OFF;
2059         nameeq = ckmalloc(namelen + vallen + 2);
2060         p = memcpy(nameeq, name, namelen) + namelen;
2061         if (val) {
2062                 *p++ = '=';
2063                 p = memcpy(p, val, vallen) + vallen;
2064         }
2065         *p = '\0';
2066         setvareq(nameeq, flags | VNOSAVE);
2067         INT_ON;
2068 }
2069
2070 #if ENABLE_ASH_GETOPTS
2071 /*
2072  * Safe version of setvar, returns 1 on success 0 on failure.
2073  */
2074 static int
2075 setvarsafe(const char *name, const char *val, int flags)
2076 {
2077         int err;
2078         volatile int saveint;
2079         struct jmploc *volatile savehandler = exception_handler;
2080         struct jmploc jmploc;
2081
2082         SAVE_INT(saveint);
2083         if (setjmp(jmploc.loc))
2084                 err = 1;
2085         else {
2086                 exception_handler = &jmploc;
2087                 setvar(name, val, flags);
2088                 err = 0;
2089         }
2090         exception_handler = savehandler;
2091         RESTORE_INT(saveint);
2092         return err;
2093 }
2094 #endif
2095
2096 /*
2097  * Unset the specified variable.
2098  */
2099 static int
2100 unsetvar(const char *s)
2101 {
2102         struct var **vpp;
2103         struct var *vp;
2104         int retval;
2105
2106         vpp = findvar(hashvar(s), s);
2107         vp = *vpp;
2108         retval = 2;
2109         if (vp) {
2110                 int flags = vp->flags;
2111
2112                 retval = 1;
2113                 if (flags & VREADONLY)
2114                         goto out;
2115 #ifdef DYNAMIC_VAR
2116                 vp->flags &= ~VDYNAMIC;
2117 #endif
2118                 if (flags & VUNSET)
2119                         goto ok;
2120                 if ((flags & VSTRFIXED) == 0) {
2121                         INT_OFF;
2122                         if ((flags & (VTEXTFIXED|VSTACK)) == 0)
2123                                 free((char*)vp->text);
2124                         *vpp = vp->next;
2125                         free(vp);
2126                         INT_ON;
2127                 } else {
2128                         setvar(s, 0, 0);
2129                         vp->flags &= ~VEXPORT;
2130                 }
2131  ok:
2132                 retval = 0;
2133         }
2134  out:
2135         return retval;
2136 }
2137
2138 /*
2139  * Process a linked list of variable assignments.
2140  */
2141 static void
2142 listsetvar(struct strlist *list_set_var, int flags)
2143 {
2144         struct strlist *lp = list_set_var;
2145
2146         if (!lp)
2147                 return;
2148         INT_OFF;
2149         do {
2150                 setvareq(lp->text, flags);
2151                 lp = lp->next;
2152         } while (lp);
2153         INT_ON;
2154 }
2155
2156 /*
2157  * Generate a list of variables satisfying the given conditions.
2158  */
2159 static char **
2160 listvars(int on, int off, char ***end)
2161 {
2162         struct var **vpp;
2163         struct var *vp;
2164         char **ep;
2165         int mask;
2166
2167         STARTSTACKSTR(ep);
2168         vpp = vartab;
2169         mask = on | off;
2170         do {
2171                 for (vp = *vpp; vp; vp = vp->next) {
2172                         if ((vp->flags & mask) == on) {
2173                                 if (ep == stackstrend())
2174                                         ep = growstackstr();
2175                                 *ep++ = (char *) vp->text;
2176                         }
2177                 }
2178         } while (++vpp < vartab + VTABSIZE);
2179         if (ep == stackstrend())
2180                 ep = growstackstr();
2181         if (end)
2182                 *end = ep;
2183         *ep++ = NULL;
2184         return grabstackstr(ep);
2185 }
2186
2187
2188 /* ============ Path search helper
2189  *
2190  * The variable path (passed by reference) should be set to the start
2191  * of the path before the first call; padvance will update
2192  * this value as it proceeds.  Successive calls to padvance will return
2193  * the possible path expansions in sequence.  If an option (indicated by
2194  * a percent sign) appears in the path entry then the global variable
2195  * pathopt will be set to point to it; otherwise pathopt will be set to
2196  * NULL.
2197  */
2198 static const char *pathopt;     /* set by padvance */
2199
2200 static char *
2201 padvance(const char **path, const char *name)
2202 {
2203         const char *p;
2204         char *q;
2205         const char *start;
2206         size_t len;
2207
2208         if (*path == NULL)
2209                 return NULL;
2210         start = *path;
2211         for (p = start; *p && *p != ':' && *p != '%'; p++);
2212         len = p - start + strlen(name) + 2;     /* "2" is for '/' and '\0' */
2213         while (stackblocksize() < len)
2214                 growstackblock();
2215         q = stackblock();
2216         if (p != start) {
2217                 memcpy(q, start, p - start);
2218                 q += p - start;
2219                 *q++ = '/';
2220         }
2221         strcpy(q, name);
2222         pathopt = NULL;
2223         if (*p == '%') {
2224                 pathopt = ++p;
2225                 while (*p && *p != ':') p++;
2226         }
2227         if (*p == ':')
2228                 *path = p + 1;
2229         else
2230                 *path = NULL;
2231         return stalloc(len);
2232 }
2233
2234
2235 /* ============ Prompt */
2236
2237 static smallint doprompt;                   /* if set, prompt the user */
2238 static smallint needprompt;                 /* true if interactive and at start of line */
2239
2240 #if ENABLE_FEATURE_EDITING
2241 static line_input_t *line_input_state;
2242 static const char *cmdedit_prompt;
2243 static void
2244 putprompt(const char *s)
2245 {
2246         if (ENABLE_ASH_EXPAND_PRMT) {
2247                 free((char*)cmdedit_prompt);
2248                 cmdedit_prompt = ckstrdup(s);
2249                 return;
2250         }
2251         cmdedit_prompt = s;
2252 }
2253 #else
2254 static void
2255 putprompt(const char *s)
2256 {
2257         out2str(s);
2258 }
2259 #endif
2260
2261 #if ENABLE_ASH_EXPAND_PRMT
2262 /* expandstr() needs parsing machinery, so it is far away ahead... */
2263 static const char *expandstr(const char *ps);
2264 #else
2265 #define expandstr(s) s
2266 #endif
2267
2268 static void
2269 setprompt(int whichprompt)
2270 {
2271         const char *prompt;
2272 #if ENABLE_ASH_EXPAND_PRMT
2273         struct stackmark smark;
2274 #endif
2275
2276         needprompt = 0;
2277
2278         switch (whichprompt) {
2279         case 1:
2280                 prompt = ps1val();
2281                 break;
2282         case 2:
2283                 prompt = ps2val();
2284                 break;
2285         default:                        /* 0 */
2286                 prompt = nullstr;
2287         }
2288 #if ENABLE_ASH_EXPAND_PRMT
2289         setstackmark(&smark);
2290         stalloc(stackblocksize());
2291 #endif
2292         putprompt(expandstr(prompt));
2293 #if ENABLE_ASH_EXPAND_PRMT
2294         popstackmark(&smark);
2295 #endif
2296 }
2297
2298
2299 /* ============ The cd and pwd commands */
2300
2301 #define CD_PHYSICAL 1
2302 #define CD_PRINT 2
2303
2304 static int docd(const char *, int);
2305
2306 static int
2307 cdopt(void)
2308 {
2309         int flags = 0;
2310         int i, j;
2311
2312         j = 'L';
2313         while ((i = nextopt("LP"))) {
2314                 if (i != j) {
2315                         flags ^= CD_PHYSICAL;
2316                         j = i;
2317                 }
2318         }
2319
2320         return flags;
2321 }
2322
2323 /*
2324  * Update curdir (the name of the current directory) in response to a
2325  * cd command.
2326  */
2327 static const char *
2328 updatepwd(const char *dir)
2329 {
2330         char *new;
2331         char *p;
2332         char *cdcomppath;
2333         const char *lim;
2334
2335         cdcomppath = ststrdup(dir);
2336         STARTSTACKSTR(new);
2337         if (*dir != '/') {
2338                 if (curdir == nullstr)
2339                         return 0;
2340                 new = stack_putstr(curdir, new);
2341         }
2342         new = makestrspace(strlen(dir) + 2, new);
2343         lim = stackblock() + 1;
2344         if (*dir != '/') {
2345                 if (new[-1] != '/')
2346                         USTPUTC('/', new);
2347                 if (new > lim && *lim == '/')
2348                         lim++;
2349         } else {
2350                 USTPUTC('/', new);
2351                 cdcomppath++;
2352                 if (dir[1] == '/' && dir[2] != '/') {
2353                         USTPUTC('/', new);
2354                         cdcomppath++;
2355                         lim++;
2356                 }
2357         }
2358         p = strtok(cdcomppath, "/");
2359         while (p) {
2360                 switch (*p) {
2361                 case '.':
2362                         if (p[1] == '.' && p[2] == '\0') {
2363                                 while (new > lim) {
2364                                         STUNPUTC(new);
2365                                         if (new[-1] == '/')
2366                                                 break;
2367                                 }
2368                                 break;
2369                         }
2370                         if (p[1] == '\0')
2371                                 break;
2372                         /* fall through */
2373                 default:
2374                         new = stack_putstr(p, new);
2375                         USTPUTC('/', new);
2376                 }
2377                 p = strtok(0, "/");
2378         }
2379         if (new > lim)
2380                 STUNPUTC(new);
2381         *new = 0;
2382         return stackblock();
2383 }
2384
2385 /*
2386  * Find out what the current directory is. If we already know the current
2387  * directory, this routine returns immediately.
2388  */
2389 static char *
2390 getpwd(void)
2391 {
2392         char *dir = getcwd(NULL, 0); /* huh, using glibc extension? */
2393         return dir ? dir : nullstr;
2394 }
2395
2396 static void
2397 setpwd(const char *val, int setold)
2398 {
2399         char *oldcur, *dir;
2400
2401         oldcur = dir = curdir;
2402
2403         if (setold) {
2404                 setvar("OLDPWD", oldcur, VEXPORT);
2405         }
2406         INT_OFF;
2407         if (physdir != nullstr) {
2408                 if (physdir != oldcur)
2409                         free(physdir);
2410                 physdir = nullstr;
2411         }
2412         if (oldcur == val || !val) {
2413                 char *s = getpwd();
2414                 physdir = s;
2415                 if (!val)
2416                         dir = s;
2417         } else
2418                 dir = ckstrdup(val);
2419         if (oldcur != dir && oldcur != nullstr) {
2420                 free(oldcur);
2421         }
2422         curdir = dir;
2423         INT_ON;
2424         setvar("PWD", dir, VEXPORT);
2425 }
2426
2427 static void hashcd(void);
2428
2429 /*
2430  * Actually do the chdir.  We also call hashcd to let the routines in exec.c
2431  * know that the current directory has changed.
2432  */
2433 static int
2434 docd(const char *dest, int flags)
2435 {
2436         const char *dir = 0;
2437         int err;
2438
2439         TRACE(("docd(\"%s\", %d) called\n", dest, flags));
2440
2441         INT_OFF;
2442         if (!(flags & CD_PHYSICAL)) {
2443                 dir = updatepwd(dest);
2444                 if (dir)
2445                         dest = dir;
2446         }
2447         err = chdir(dest);
2448         if (err)
2449                 goto out;
2450         setpwd(dir, 1);
2451         hashcd();
2452  out:
2453         INT_ON;
2454         return err;
2455 }
2456
2457 static int
2458 cdcmd(int argc, char **argv)
2459 {
2460         const char *dest;
2461         const char *path;
2462         const char *p;
2463         char c;
2464         struct stat statb;
2465         int flags;
2466
2467         flags = cdopt();
2468         dest = *argptr;
2469         if (!dest)
2470                 dest = bltinlookup(homestr);
2471         else if (LONE_DASH(dest)) {
2472                 dest = bltinlookup("OLDPWD");
2473                 flags |= CD_PRINT;
2474         }
2475         if (!dest)
2476                 dest = nullstr;
2477         if (*dest == '/')
2478                 goto step7;
2479         if (*dest == '.') {
2480                 c = dest[1];
2481  dotdot:
2482                 switch (c) {
2483                 case '\0':
2484                 case '/':
2485                         goto step6;
2486                 case '.':
2487                         c = dest[2];
2488                         if (c != '.')
2489                                 goto dotdot;
2490                 }
2491         }
2492         if (!*dest)
2493                 dest = ".";
2494         path = bltinlookup("CDPATH");
2495         if (!path) {
2496  step6:
2497  step7:
2498                 p = dest;
2499                 goto docd;
2500         }
2501         do {
2502                 c = *path;
2503                 p = padvance(&path, dest);
2504                 if (stat(p, &statb) >= 0 && S_ISDIR(statb.st_mode)) {
2505                         if (c && c != ':')
2506                                 flags |= CD_PRINT;
2507  docd:
2508                         if (!docd(p, flags))
2509                                 goto out;
2510                         break;
2511                 }
2512         } while (path);
2513         ash_msg_and_raise_error("can't cd to %s", dest);
2514         /* NOTREACHED */
2515  out:
2516         if (flags & CD_PRINT)
2517                 out1fmt(snlfmt, curdir);
2518         return 0;
2519 }
2520
2521 static int
2522 pwdcmd(int argc, char **argv)
2523 {
2524         int flags;
2525         const char *dir = curdir;
2526
2527         flags = cdopt();
2528         if (flags) {
2529                 if (physdir == nullstr)
2530                         setpwd(dir, 0);
2531                 dir = physdir;
2532         }
2533         out1fmt(snlfmt, dir);
2534         return 0;
2535 }
2536
2537
2538 /* ============ ... */
2539
2540 #define IBUFSIZ COMMON_BUFSIZE
2541 #define basebuf bb_common_bufsiz1       /* buffer for top level input file */
2542
2543 /* Syntax classes */
2544 #define CWORD 0                 /* character is nothing special */
2545 #define CNL 1                   /* newline character */
2546 #define CBACK 2                 /* a backslash character */
2547 #define CSQUOTE 3               /* single quote */
2548 #define CDQUOTE 4               /* double quote */
2549 #define CENDQUOTE 5             /* a terminating quote */
2550 #define CBQUOTE 6               /* backwards single quote */
2551 #define CVAR 7                  /* a dollar sign */
2552 #define CENDVAR 8               /* a '}' character */
2553 #define CLP 9                   /* a left paren in arithmetic */
2554 #define CRP 10                  /* a right paren in arithmetic */
2555 #define CENDFILE 11             /* end of file */
2556 #define CCTL 12                 /* like CWORD, except it must be escaped */
2557 #define CSPCL 13                /* these terminate a word */
2558 #define CIGN 14                 /* character should be ignored */
2559
2560 #if ENABLE_ASH_ALIAS
2561 #define SYNBASE 130
2562 #define PEOF -130
2563 #define PEOA -129
2564 #define PEOA_OR_PEOF PEOA
2565 #else
2566 #define SYNBASE 129
2567 #define PEOF -129
2568 #define PEOA_OR_PEOF PEOF
2569 #endif
2570
2571 /* number syntax index */
2572 #define BASESYNTAX 0    /* not in quotes */
2573 #define DQSYNTAX   1    /* in double quotes */
2574 #define SQSYNTAX   2    /* in single quotes */
2575 #define ARISYNTAX  3    /* in arithmetic */
2576 #define PSSYNTAX   4    /* prompt */
2577
2578 #if ENABLE_ASH_OPTIMIZE_FOR_SIZE
2579 #define USE_SIT_FUNCTION
2580 #endif
2581
2582 #if ENABLE_ASH_MATH_SUPPORT
2583 static const char S_I_T[][4] = {
2584 #if ENABLE_ASH_ALIAS
2585         { CSPCL, CIGN, CIGN, CIGN },            /* 0, PEOA */
2586 #endif
2587         { CSPCL, CWORD, CWORD, CWORD },         /* 1, ' ' */
2588         { CNL, CNL, CNL, CNL },                 /* 2, \n */
2589         { CWORD, CCTL, CCTL, CWORD },           /* 3, !*-/:=?[]~ */
2590         { CDQUOTE, CENDQUOTE, CWORD, CWORD },   /* 4, '"' */
2591         { CVAR, CVAR, CWORD, CVAR },            /* 5, $ */
2592         { CSQUOTE, CWORD, CENDQUOTE, CWORD },   /* 6, "'" */
2593         { CSPCL, CWORD, CWORD, CLP },           /* 7, ( */
2594         { CSPCL, CWORD, CWORD, CRP },           /* 8, ) */
2595         { CBACK, CBACK, CCTL, CBACK },          /* 9, \ */
2596         { CBQUOTE, CBQUOTE, CWORD, CBQUOTE },   /* 10, ` */
2597         { CENDVAR, CENDVAR, CWORD, CENDVAR },   /* 11, } */
2598 #ifndef USE_SIT_FUNCTION
2599         { CENDFILE, CENDFILE, CENDFILE, CENDFILE }, /* 12, PEOF */
2600         { CWORD, CWORD, CWORD, CWORD },         /* 13, 0-9A-Za-z */
2601         { CCTL, CCTL, CCTL, CCTL }              /* 14, CTLESC ... */
2602 #endif
2603 };
2604 #else
2605 static const char S_I_T[][3] = {
2606 #if ENABLE_ASH_ALIAS
2607         { CSPCL, CIGN, CIGN },                  /* 0, PEOA */
2608 #endif
2609         { CSPCL, CWORD, CWORD },                /* 1, ' ' */
2610         { CNL, CNL, CNL },                      /* 2, \n */
2611         { CWORD, CCTL, CCTL },                  /* 3, !*-/:=?[]~ */
2612         { CDQUOTE, CENDQUOTE, CWORD },          /* 4, '"' */
2613         { CVAR, CVAR, CWORD },                  /* 5, $ */
2614         { CSQUOTE, CWORD, CENDQUOTE },          /* 6, "'" */
2615         { CSPCL, CWORD, CWORD },                /* 7, ( */
2616         { CSPCL, CWORD, CWORD },                /* 8, ) */
2617         { CBACK, CBACK, CCTL },                 /* 9, \ */
2618         { CBQUOTE, CBQUOTE, CWORD },            /* 10, ` */
2619         { CENDVAR, CENDVAR, CWORD },            /* 11, } */
2620 #ifndef USE_SIT_FUNCTION
2621         { CENDFILE, CENDFILE, CENDFILE },       /* 12, PEOF */
2622         { CWORD, CWORD, CWORD },                /* 13, 0-9A-Za-z */
2623         { CCTL, CCTL, CCTL }                    /* 14, CTLESC ... */
2624 #endif
2625 };
2626 #endif /* ASH_MATH_SUPPORT */
2627
2628 #ifdef USE_SIT_FUNCTION
2629
2630 static int
2631 SIT(int c, int syntax)
2632 {
2633         static const char spec_symbls[] ALIGN1 = "\t\n !\"$&'()*-/:;<=>?[\\]`|}~";
2634 #if ENABLE_ASH_ALIAS
2635         static const char syntax_index_table[] ALIGN1 = {
2636                 1, 2, 1, 3, 4, 5, 1, 6,         /* "\t\n !\"$&'" */
2637                 7, 8, 3, 3, 3, 3, 1, 1,         /* "()*-/:;<" */
2638                 3, 1, 3, 3, 9, 3, 10, 1,        /* "=>?[\\]`|" */
2639                 11, 3                           /* "}~" */
2640         };
2641 #else
2642         static const char syntax_index_table[] ALIGN1 = {
2643                 0, 1, 0, 2, 3, 4, 0, 5,         /* "\t\n !\"$&'" */
2644                 6, 7, 2, 2, 2, 2, 0, 0,         /* "()*-/:;<" */
2645                 2, 0, 2, 2, 8, 2, 9, 0,         /* "=>?[\\]`|" */
2646                 10, 2                           /* "}~" */
2647         };
2648 #endif
2649         const char *s;
2650         int indx;
2651
2652         if (c == PEOF)          /* 2^8+2 */
2653                 return CENDFILE;
2654 #if ENABLE_ASH_ALIAS
2655         if (c == PEOA)          /* 2^8+1 */
2656                 indx = 0;
2657         else
2658 #endif
2659 #define U_C(c) ((unsigned char)(c))
2660
2661         if ((unsigned char)c >= (unsigned char)(CTLESC)
2662          && (unsigned char)c <= (unsigned char)(CTLQUOTEMARK)
2663         ) {
2664                 return CCTL;
2665         } else {
2666                 s = strchr(spec_symbls, c);
2667                 if (s == NULL || *s == '\0')
2668                         return CWORD;
2669                 indx = syntax_index_table[(s - spec_symbls)];
2670         }
2671         return S_I_T[indx][syntax];
2672 }
2673
2674 #else   /* !USE_SIT_FUNCTION */
2675
2676 #if ENABLE_ASH_ALIAS
2677 #define CSPCL_CIGN_CIGN_CIGN                     0
2678 #define CSPCL_CWORD_CWORD_CWORD                  1
2679 #define CNL_CNL_CNL_CNL                          2
2680 #define CWORD_CCTL_CCTL_CWORD                    3
2681 #define CDQUOTE_CENDQUOTE_CWORD_CWORD            4
2682 #define CVAR_CVAR_CWORD_CVAR                     5
2683 #define CSQUOTE_CWORD_CENDQUOTE_CWORD            6
2684 #define CSPCL_CWORD_CWORD_CLP                    7
2685 #define CSPCL_CWORD_CWORD_CRP                    8
2686 #define CBACK_CBACK_CCTL_CBACK                   9
2687 #define CBQUOTE_CBQUOTE_CWORD_CBQUOTE           10
2688 #define CENDVAR_CENDVAR_CWORD_CENDVAR           11
2689 #define CENDFILE_CENDFILE_CENDFILE_CENDFILE     12
2690 #define CWORD_CWORD_CWORD_CWORD                 13
2691 #define CCTL_CCTL_CCTL_CCTL                     14
2692 #else
2693 #define CSPCL_CWORD_CWORD_CWORD                  0
2694 #define CNL_CNL_CNL_CNL                          1
2695 #define CWORD_CCTL_CCTL_CWORD                    2
2696 #define CDQUOTE_CENDQUOTE_CWORD_CWORD            3
2697 #define CVAR_CVAR_CWORD_CVAR                     4
2698 #define CSQUOTE_CWORD_CENDQUOTE_CWORD            5
2699 #define CSPCL_CWORD_CWORD_CLP                    6
2700 #define CSPCL_CWORD_CWORD_CRP                    7
2701 #define CBACK_CBACK_CCTL_CBACK                   8
2702 #define CBQUOTE_CBQUOTE_CWORD_CBQUOTE            9
2703 #define CENDVAR_CENDVAR_CWORD_CENDVAR           10
2704 #define CENDFILE_CENDFILE_CENDFILE_CENDFILE     11
2705 #define CWORD_CWORD_CWORD_CWORD                 12
2706 #define CCTL_CCTL_CCTL_CCTL                     13
2707 #endif
2708
2709 static const char syntax_index_table[258] = {
2710         /* BASESYNTAX_DQSYNTAX_SQSYNTAX_ARISYNTAX */
2711         /*   0  PEOF */      CENDFILE_CENDFILE_CENDFILE_CENDFILE,
2712 #if ENABLE_ASH_ALIAS
2713         /*   1  PEOA */      CSPCL_CIGN_CIGN_CIGN,
2714 #endif
2715         /*   2  -128 0x80 */ CWORD_CWORD_CWORD_CWORD,
2716         /*   3  -127 CTLESC       */ CCTL_CCTL_CCTL_CCTL,
2717         /*   4  -126 CTLVAR       */ CCTL_CCTL_CCTL_CCTL,
2718         /*   5  -125 CTLENDVAR    */ CCTL_CCTL_CCTL_CCTL,
2719         /*   6  -124 CTLBACKQ     */ CCTL_CCTL_CCTL_CCTL,
2720         /*   7  -123 CTLQUOTE     */ CCTL_CCTL_CCTL_CCTL,
2721         /*   8  -122 CTLARI       */ CCTL_CCTL_CCTL_CCTL,
2722         /*   9  -121 CTLENDARI    */ CCTL_CCTL_CCTL_CCTL,
2723         /*  10  -120 CTLQUOTEMARK */ CCTL_CCTL_CCTL_CCTL,
2724         /*  11  -119      */ CWORD_CWORD_CWORD_CWORD,
2725         /*  12  -118      */ CWORD_CWORD_CWORD_CWORD,
2726         /*  13  -117      */ CWORD_CWORD_CWORD_CWORD,
2727         /*  14  -116      */ CWORD_CWORD_CWORD_CWORD,
2728         /*  15  -115      */ CWORD_CWORD_CWORD_CWORD,
2729         /*  16  -114      */ CWORD_CWORD_CWORD_CWORD,
2730         /*  17  -113      */ CWORD_CWORD_CWORD_CWORD,
2731         /*  18  -112      */ CWORD_CWORD_CWORD_CWORD,
2732         /*  19  -111      */ CWORD_CWORD_CWORD_CWORD,
2733         /*  20  -110      */ CWORD_CWORD_CWORD_CWORD,
2734         /*  21  -109      */ CWORD_CWORD_CWORD_CWORD,
2735         /*  22  -108      */ CWORD_CWORD_CWORD_CWORD,
2736         /*  23  -107      */ CWORD_CWORD_CWORD_CWORD,
2737         /*  24  -106      */ CWORD_CWORD_CWORD_CWORD,
2738         /*  25  -105      */ CWORD_CWORD_CWORD_CWORD,
2739         /*  26  -104      */ CWORD_CWORD_CWORD_CWORD,
2740         /*  27  -103      */ CWORD_CWORD_CWORD_CWORD,
2741         /*  28  -102      */ CWORD_CWORD_CWORD_CWORD,
2742         /*  29  -101      */ CWORD_CWORD_CWORD_CWORD,
2743         /*  30  -100      */ CWORD_CWORD_CWORD_CWORD,
2744         /*  31   -99      */ CWORD_CWORD_CWORD_CWORD,
2745         /*  32   -98      */ CWORD_CWORD_CWORD_CWORD,
2746         /*  33   -97      */ CWORD_CWORD_CWORD_CWORD,
2747         /*  34   -96      */ CWORD_CWORD_CWORD_CWORD,
2748         /*  35   -95      */ CWORD_CWORD_CWORD_CWORD,
2749         /*  36   -94      */ CWORD_CWORD_CWORD_CWORD,
2750         /*  37   -93      */ CWORD_CWORD_CWORD_CWORD,
2751         /*  38   -92      */ CWORD_CWORD_CWORD_CWORD,
2752         /*  39   -91      */ CWORD_CWORD_CWORD_CWORD,
2753         /*  40   -90      */ CWORD_CWORD_CWORD_CWORD,
2754         /*  41   -89      */ CWORD_CWORD_CWORD_CWORD,
2755         /*  42   -88      */ CWORD_CWORD_CWORD_CWORD,
2756         /*  43   -87      */ CWORD_CWORD_CWORD_CWORD,
2757         /*  44   -86      */ CWORD_CWORD_CWORD_CWORD,
2758         /*  45   -85      */ CWORD_CWORD_CWORD_CWORD,
2759         /*  46   -84      */ CWORD_CWORD_CWORD_CWORD,
2760         /*  47   -83      */ CWORD_CWORD_CWORD_CWORD,
2761         /*  48   -82      */ CWORD_CWORD_CWORD_CWORD,
2762         /*  49   -81      */ CWORD_CWORD_CWORD_CWORD,
2763         /*  50   -80      */ CWORD_CWORD_CWORD_CWORD,
2764         /*  51   -79      */ CWORD_CWORD_CWORD_CWORD,
2765         /*  52   -78      */ CWORD_CWORD_CWORD_CWORD,
2766         /*  53   -77      */ CWORD_CWORD_CWORD_CWORD,
2767         /*  54   -76      */ CWORD_CWORD_CWORD_CWORD,
2768         /*  55   -75      */ CWORD_CWORD_CWORD_CWORD,
2769         /*  56   -74      */ CWORD_CWORD_CWORD_CWORD,
2770         /*  57   -73      */ CWORD_CWORD_CWORD_CWORD,
2771         /*  58   -72      */ CWORD_CWORD_CWORD_CWORD,
2772         /*  59   -71      */ CWORD_CWORD_CWORD_CWORD,
2773         /*  60   -70      */ CWORD_CWORD_CWORD_CWORD,
2774         /*  61   -69      */ CWORD_CWORD_CWORD_CWORD,
2775         /*  62   -68      */ CWORD_CWORD_CWORD_CWORD,
2776         /*  63   -67      */ CWORD_CWORD_CWORD_CWORD,
2777         /*  64   -66      */ CWORD_CWORD_CWORD_CWORD,
2778         /*  65   -65      */ CWORD_CWORD_CWORD_CWORD,
2779         /*  66   -64      */ CWORD_CWORD_CWORD_CWORD,
2780         /*  67   -63      */ CWORD_CWORD_CWORD_CWORD,
2781         /*  68   -62      */ CWORD_CWORD_CWORD_CWORD,
2782         /*  69   -61      */ CWORD_CWORD_CWORD_CWORD,
2783         /*  70   -60      */ CWORD_CWORD_CWORD_CWORD,
2784         /*  71   -59      */ CWORD_CWORD_CWORD_CWORD,
2785         /*  72   -58      */ CWORD_CWORD_CWORD_CWORD,
2786         /*  73   -57      */ CWORD_CWORD_CWORD_CWORD,
2787         /*  74   -56      */ CWORD_CWORD_CWORD_CWORD,
2788         /*  75   -55      */ CWORD_CWORD_CWORD_CWORD,
2789         /*  76   -54      */ CWORD_CWORD_CWORD_CWORD,
2790         /*  77   -53      */ CWORD_CWORD_CWORD_CWORD,
2791         /*  78   -52      */ CWORD_CWORD_CWORD_CWORD,
2792         /*  79   -51      */ CWORD_CWORD_CWORD_CWORD,
2793         /*  80   -50      */ CWORD_CWORD_CWORD_CWORD,
2794         /*  81   -49      */ CWORD_CWORD_CWORD_CWORD,
2795         /*  82   -48      */ CWORD_CWORD_CWORD_CWORD,
2796         /*  83   -47      */ CWORD_CWORD_CWORD_CWORD,
2797         /*  84   -46      */ CWORD_CWORD_CWORD_CWORD,
2798         /*  85   -45      */ CWORD_CWORD_CWORD_CWORD,
2799         /*  86   -44      */ CWORD_CWORD_CWORD_CWORD,
2800         /*  87   -43      */ CWORD_CWORD_CWORD_CWORD,
2801         /*  88   -42      */ CWORD_CWORD_CWORD_CWORD,
2802         /*  89   -41      */ CWORD_CWORD_CWORD_CWORD,
2803         /*  90   -40      */ CWORD_CWORD_CWORD_CWORD,
2804         /*  91   -39      */ CWORD_CWORD_CWORD_CWORD,
2805         /*  92   -38      */ CWORD_CWORD_CWORD_CWORD,
2806         /*  93   -37      */ CWORD_CWORD_CWORD_CWORD,
2807         /*  94   -36      */ CWORD_CWORD_CWORD_CWORD,
2808         /*  95   -35      */ CWORD_CWORD_CWORD_CWORD,
2809         /*  96   -34      */ CWORD_CWORD_CWORD_CWORD,
2810         /*  97   -33      */ CWORD_CWORD_CWORD_CWORD,
2811         /*  98   -32      */ CWORD_CWORD_CWORD_CWORD,
2812         /*  99   -31      */ CWORD_CWORD_CWORD_CWORD,
2813         /* 100   -30      */ CWORD_CWORD_CWORD_CWORD,
2814         /* 101   -29      */ CWORD_CWORD_CWORD_CWORD,
2815         /* 102   -28      */ CWORD_CWORD_CWORD_CWORD,
2816         /* 103   -27      */ CWORD_CWORD_CWORD_CWORD,
2817         /* 104   -26      */ CWORD_CWORD_CWORD_CWORD,
2818         /* 105   -25      */ CWORD_CWORD_CWORD_CWORD,
2819         /* 106   -24      */ CWORD_CWORD_CWORD_CWORD,
2820         /* 107   -23      */ CWORD_CWORD_CWORD_CWORD,
2821         /* 108   -22      */ CWORD_CWORD_CWORD_CWORD,
2822         /* 109   -21      */ CWORD_CWORD_CWORD_CWORD,
2823         /* 110   -20      */ CWORD_CWORD_CWORD_CWORD,
2824         /* 111   -19      */ CWORD_CWORD_CWORD_CWORD,
2825         /* 112   -18      */ CWORD_CWORD_CWORD_CWORD,
2826         /* 113   -17      */ CWORD_CWORD_CWORD_CWORD,
2827         /* 114   -16      */ CWORD_CWORD_CWORD_CWORD,
2828         /* 115   -15      */ CWORD_CWORD_CWORD_CWORD,
2829         /* 116   -14      */ CWORD_CWORD_CWORD_CWORD,
2830         /* 117   -13      */ CWORD_CWORD_CWORD_CWORD,
2831         /* 118   -12      */ CWORD_CWORD_CWORD_CWORD,
2832         /* 119   -11      */ CWORD_CWORD_CWORD_CWORD,
2833         /* 120   -10      */ CWORD_CWORD_CWORD_CWORD,
2834         /* 121    -9      */ CWORD_CWORD_CWORD_CWORD,
2835         /* 122    -8      */ CWORD_CWORD_CWORD_CWORD,
2836         /* 123    -7      */ CWORD_CWORD_CWORD_CWORD,
2837         /* 124    -6      */ CWORD_CWORD_CWORD_CWORD,
2838         /* 125    -5      */ CWORD_CWORD_CWORD_CWORD,
2839         /* 126    -4      */ CWORD_CWORD_CWORD_CWORD,
2840         /* 127    -3      */ CWORD_CWORD_CWORD_CWORD,
2841         /* 128    -2      */ CWORD_CWORD_CWORD_CWORD,
2842         /* 129    -1      */ CWORD_CWORD_CWORD_CWORD,
2843         /* 130     0      */ CWORD_CWORD_CWORD_CWORD,
2844         /* 131     1      */ CWORD_CWORD_CWORD_CWORD,
2845         /* 132     2      */ CWORD_CWORD_CWORD_CWORD,
2846         /* 133     3      */ CWORD_CWORD_CWORD_CWORD,
2847         /* 134     4      */ CWORD_CWORD_CWORD_CWORD,
2848         /* 135     5      */ CWORD_CWORD_CWORD_CWORD,
2849         /* 136     6      */ CWORD_CWORD_CWORD_CWORD,
2850         /* 137     7      */ CWORD_CWORD_CWORD_CWORD,
2851         /* 138     8      */ CWORD_CWORD_CWORD_CWORD,
2852         /* 139     9 "\t" */ CSPCL_CWORD_CWORD_CWORD,
2853         /* 140    10 "\n" */ CNL_CNL_CNL_CNL,
2854         /* 141    11      */ CWORD_CWORD_CWORD_CWORD,
2855         /* 142    12      */ CWORD_CWORD_CWORD_CWORD,
2856         /* 143    13      */ CWORD_CWORD_CWORD_CWORD,
2857         /* 144    14      */ CWORD_CWORD_CWORD_CWORD,
2858         /* 145    15      */ CWORD_CWORD_CWORD_CWORD,
2859         /* 146    16      */ CWORD_CWORD_CWORD_CWORD,
2860         /* 147    17      */ CWORD_CWORD_CWORD_CWORD,
2861         /* 148    18      */ CWORD_CWORD_CWORD_CWORD,
2862         /* 149    19      */ CWORD_CWORD_CWORD_CWORD,
2863         /* 150    20      */ CWORD_CWORD_CWORD_CWORD,
2864         /* 151    21      */ CWORD_CWORD_CWORD_CWORD,
2865         /* 152    22      */ CWORD_CWORD_CWORD_CWORD,
2866         /* 153    23      */ CWORD_CWORD_CWORD_CWORD,
2867         /* 154    24      */ CWORD_CWORD_CWORD_CWORD,
2868         /* 155    25      */ CWORD_CWORD_CWORD_CWORD,
2869         /* 156    26      */ CWORD_CWORD_CWORD_CWORD,
2870         /* 157    27      */ CWORD_CWORD_CWORD_CWORD,
2871         /* 158    28      */ CWORD_CWORD_CWORD_CWORD,
2872         /* 159    29      */ CWORD_CWORD_CWORD_CWORD,
2873         /* 160    30      */ CWORD_CWORD_CWORD_CWORD,
2874         /* 161    31      */ CWORD_CWORD_CWORD_CWORD,
2875         /* 162    32  " " */ CSPCL_CWORD_CWORD_CWORD,
2876         /* 163    33  "!" */ CWORD_CCTL_CCTL_CWORD,
2877         /* 164    34  """ */ CDQUOTE_CENDQUOTE_CWORD_CWORD,
2878         /* 165    35  "#" */ CWORD_CWORD_CWORD_CWORD,
2879         /* 166    36  "$" */ CVAR_CVAR_CWORD_CVAR,
2880         /* 167    37  "%" */ CWORD_CWORD_CWORD_CWORD,
2881         /* 168    38  "&" */ CSPCL_CWORD_CWORD_CWORD,
2882         /* 169    39  "'" */ CSQUOTE_CWORD_CENDQUOTE_CWORD,
2883         /* 170    40  "(" */ CSPCL_CWORD_CWORD_CLP,
2884         /* 171    41  ")" */ CSPCL_CWORD_CWORD_CRP,
2885         /* 172    42  "*" */ CWORD_CCTL_CCTL_CWORD,
2886         /* 173    43  "+" */ CWORD_CWORD_CWORD_CWORD,
2887         /* 174    44  "," */ CWORD_CWORD_CWORD_CWORD,
2888         /* 175    45  "-" */ CWORD_CCTL_CCTL_CWORD,
2889         /* 176    46  "." */ CWORD_CWORD_CWORD_CWORD,
2890         /* 177    47  "/" */ CWORD_CCTL_CCTL_CWORD,
2891         /* 178    48  "0" */ CWORD_CWORD_CWORD_CWORD,
2892         /* 179    49  "1" */ CWORD_CWORD_CWORD_CWORD,
2893         /* 180    50  "2" */ CWORD_CWORD_CWORD_CWORD,
2894         /* 181    51  "3" */ CWORD_CWORD_CWORD_CWORD,
2895         /* 182    52  "4" */ CWORD_CWORD_CWORD_CWORD,
2896         /* 183    53  "5" */ CWORD_CWORD_CWORD_CWORD,
2897         /* 184    54  "6" */ CWORD_CWORD_CWORD_CWORD,
2898         /* 185    55  "7" */ CWORD_CWORD_CWORD_CWORD,
2899         /* 186    56  "8" */ CWORD_CWORD_CWORD_CWORD,
2900         /* 187    57  "9" */ CWORD_CWORD_CWORD_CWORD,
2901         /* 188    58  ":" */ CWORD_CCTL_CCTL_CWORD,
2902         /* 189    59  ";" */ CSPCL_CWORD_CWORD_CWORD,
2903         /* 190    60  "<" */ CSPCL_CWORD_CWORD_CWORD,
2904         /* 191    61  "=" */ CWORD_CCTL_CCTL_CWORD,
2905         /* 192    62  ">" */ CSPCL_CWORD_CWORD_CWORD,
2906         /* 193    63  "?" */ CWORD_CCTL_CCTL_CWORD,
2907         /* 194    64  "@" */ CWORD_CWORD_CWORD_CWORD,
2908         /* 195    65  "A" */ CWORD_CWORD_CWORD_CWORD,
2909         /* 196    66  "B" */ CWORD_CWORD_CWORD_CWORD,
2910         /* 197    67  "C" */ CWORD_CWORD_CWORD_CWORD,
2911         /* 198    68  "D" */ CWORD_CWORD_CWORD_CWORD,
2912         /* 199    69  "E" */ CWORD_CWORD_CWORD_CWORD,
2913         /* 200    70  "F" */ CWORD_CWORD_CWORD_CWORD,
2914         /* 201    71  "G" */ CWORD_CWORD_CWORD_CWORD,
2915         /* 202    72  "H" */ CWORD_CWORD_CWORD_CWORD,
2916         /* 203    73  "I" */ CWORD_CWORD_CWORD_CWORD,
2917         /* 204    74  "J" */ CWORD_CWORD_CWORD_CWORD,
2918         /* 205    75  "K" */ CWORD_CWORD_CWORD_CWORD,
2919         /* 206    76  "L" */ CWORD_CWORD_CWORD_CWORD,
2920         /* 207    77  "M" */ CWORD_CWORD_CWORD_CWORD,
2921         /* 208    78  "N" */ CWORD_CWORD_CWORD_CWORD,
2922         /* 209    79  "O" */ CWORD_CWORD_CWORD_CWORD,
2923         /* 210    80  "P" */ CWORD_CWORD_CWORD_CWORD,
2924         /* 211    81  "Q" */ CWORD_CWORD_CWORD_CWORD,
2925         /* 212    82  "R" */ CWORD_CWORD_CWORD_CWORD,
2926         /* 213    83  "S" */ CWORD_CWORD_CWORD_CWORD,
2927         /* 214    84  "T" */ CWORD_CWORD_CWORD_CWORD,
2928         /* 215    85  "U" */ CWORD_CWORD_CWORD_CWORD,
2929         /* 216    86  "V" */ CWORD_CWORD_CWORD_CWORD,
2930         /* 217    87  "W" */ CWORD_CWORD_CWORD_CWORD,
2931         /* 218    88  "X" */ CWORD_CWORD_CWORD_CWORD,
2932         /* 219    89  "Y" */ CWORD_CWORD_CWORD_CWORD,
2933         /* 220    90  "Z" */ CWORD_CWORD_CWORD_CWORD,
2934         /* 221    91  "[" */ CWORD_CCTL_CCTL_CWORD,
2935         /* 222    92  "\" */ CBACK_CBACK_CCTL_CBACK,
2936         /* 223    93  "]" */ CWORD_CCTL_CCTL_CWORD,
2937         /* 224    94  "^" */ CWORD_CWORD_CWORD_CWORD,
2938         /* 225    95  "_" */ CWORD_CWORD_CWORD_CWORD,
2939         /* 226    96  "`" */ CBQUOTE_CBQUOTE_CWORD_CBQUOTE,
2940         /* 227    97  "a" */ CWORD_CWORD_CWORD_CWORD,
2941         /* 228    98  "b" */ CWORD_CWORD_CWORD_CWORD,
2942         /* 229    99  "c" */ CWORD_CWORD_CWORD_CWORD,
2943         /* 230   100  "d" */ CWORD_CWORD_CWORD_CWORD,
2944         /* 231   101  "e" */ CWORD_CWORD_CWORD_CWORD,
2945         /* 232   102  "f" */ CWORD_CWORD_CWORD_CWORD,
2946         /* 233   103  "g" */ CWORD_CWORD_CWORD_CWORD,
2947         /* 234   104  "h" */ CWORD_CWORD_CWORD_CWORD,
2948         /* 235   105  "i" */ CWORD_CWORD_CWORD_CWORD,
2949         /* 236   106  "j" */ CWORD_CWORD_CWORD_CWORD,
2950         /* 237   107  "k" */ CWORD_CWORD_CWORD_CWORD,
2951         /* 238   108  "l" */ CWORD_CWORD_CWORD_CWORD,
2952         /* 239   109  "m" */ CWORD_CWORD_CWORD_CWORD,
2953         /* 240   110  "n" */ CWORD_CWORD_CWORD_CWORD,
2954         /* 241   111  "o" */ CWORD_CWORD_CWORD_CWORD,
2955         /* 242   112  "p" */ CWORD_CWORD_CWORD_CWORD,
2956         /* 243   113  "q" */ CWORD_CWORD_CWORD_CWORD,
2957         /* 244   114  "r" */ CWORD_CWORD_CWORD_CWORD,
2958         /* 245   115  "s" */ CWORD_CWORD_CWORD_CWORD,
2959         /* 246   116  "t" */ CWORD_CWORD_CWORD_CWORD,
2960         /* 247   117  "u" */ CWORD_CWORD_CWORD_CWORD,
2961         /* 248   118  "v" */ CWORD_CWORD_CWORD_CWORD,
2962         /* 249   119  "w" */ CWORD_CWORD_CWORD_CWORD,
2963         /* 250   120  "x" */ CWORD_CWORD_CWORD_CWORD,
2964         /* 251   121  "y" */ CWORD_CWORD_CWORD_CWORD,
2965         /* 252   122  "z" */ CWORD_CWORD_CWORD_CWORD,
2966         /* 253   123  "{" */ CWORD_CWORD_CWORD_CWORD,
2967         /* 254   124  "|" */ CSPCL_CWORD_CWORD_CWORD,
2968         /* 255   125  "}" */ CENDVAR_CENDVAR_CWORD_CENDVAR,
2969         /* 256   126  "~" */ CWORD_CCTL_CCTL_CWORD,
2970         /* 257   127      */ CWORD_CWORD_CWORD_CWORD,
2971 };
2972
2973 #define SIT(c, syntax) (S_I_T[(int)syntax_index_table[((int)c)+SYNBASE]][syntax])
2974
2975 #endif  /* USE_SIT_FUNCTION */
2976
2977
2978 /* ============ Alias handling */
2979
2980 #if ENABLE_ASH_ALIAS
2981
2982 #define ALIASINUSE 1
2983 #define ALIASDEAD  2
2984
2985 struct alias {
2986         struct alias *next;
2987         char *name;
2988         char *val;
2989         int flag;
2990 };
2991
2992
2993 static struct alias **atab; // [ATABSIZE];
2994 #define INIT_G_alias() do { \
2995         atab = xzalloc(ATABSIZE * sizeof(atab[0])); \
2996 } while (0)
2997
2998
2999 static struct alias **
3000 __lookupalias(const char *name) {
3001         unsigned int hashval;
3002         struct alias **app;
3003         const char *p;
3004         unsigned int ch;
3005
3006         p = name;
3007
3008         ch = (unsigned char)*p;
3009         hashval = ch << 4;
3010         while (ch) {
3011                 hashval += ch;
3012                 ch = (unsigned char)*++p;
3013         }
3014         app = &atab[hashval % ATABSIZE];
3015
3016         for (; *app; app = &(*app)->next) {
3017                 if (strcmp(name, (*app)->name) == 0) {
3018                         break;
3019                 }
3020         }
3021
3022         return app;
3023 }
3024
3025 static struct alias *
3026 lookupalias(const char *name, int check)
3027 {
3028         struct alias *ap = *__lookupalias(name);
3029
3030         if (check && ap && (ap->flag & ALIASINUSE))
3031                 return NULL;
3032         return ap;
3033 }
3034
3035 static struct alias *
3036 freealias(struct alias *ap)
3037 {
3038         struct alias *next;
3039
3040         if (ap->flag & ALIASINUSE) {
3041                 ap->flag |= ALIASDEAD;
3042                 return ap;
3043         }
3044
3045         next = ap->next;
3046         free(ap->name);
3047         free(ap->val);
3048         free(ap);
3049         return next;
3050 }
3051
3052 static void
3053 setalias(const char *name, const char *val)
3054 {
3055         struct alias *ap, **app;
3056
3057         app = __lookupalias(name);
3058         ap = *app;
3059         INT_OFF;
3060         if (ap) {
3061                 if (!(ap->flag & ALIASINUSE)) {
3062                         free(ap->val);
3063                 }
3064                 ap->val = ckstrdup(val);
3065                 ap->flag &= ~ALIASDEAD;
3066         } else {
3067                 /* not found */
3068                 ap = ckmalloc(sizeof(struct alias));
3069                 ap->name = ckstrdup(name);
3070                 ap->val = ckstrdup(val);
3071                 ap->flag = 0;
3072                 ap->next = 0;
3073                 *app = ap;
3074         }
3075         INT_ON;
3076 }
3077
3078 static int
3079 unalias(const char *name)
3080 {
3081         struct alias **app;
3082
3083         app = __lookupalias(name);
3084
3085         if (*app) {
3086                 INT_OFF;
3087                 *app = freealias(*app);
3088                 INT_ON;
3089                 return 0;
3090         }
3091
3092         return 1;
3093 }
3094
3095 static void
3096 rmaliases(void)
3097 {
3098         struct alias *ap, **app;
3099         int i;
3100
3101         INT_OFF;
3102         for (i = 0; i < ATABSIZE; i++) {
3103                 app = &atab[i];
3104                 for (ap = *app; ap; ap = *app) {
3105                         *app = freealias(*app);
3106                         if (ap == *app) {
3107                                 app = &ap->next;
3108                         }
3109                 }
3110         }
3111         INT_ON;
3112 }
3113
3114 static void
3115 printalias(const struct alias *ap)
3116 {
3117         out1fmt("%s=%s\n", ap->name, single_quote(ap->val));
3118 }
3119
3120 /*
3121  * TODO - sort output
3122  */
3123 static int
3124 aliascmd(int argc, char **argv)
3125 {
3126         char *n, *v;
3127         int ret = 0;
3128         struct alias *ap;
3129
3130         if (argc == 1) {
3131                 int i;
3132
3133                 for (i = 0; i < ATABSIZE; i++)
3134                         for (ap = atab[i]; ap; ap = ap->next) {
3135                                 printalias(ap);
3136                         }
3137                 return 0;
3138         }
3139         while ((n = *++argv) != NULL) {
3140                 v = strchr(n+1, '=');
3141                 if (v == NULL) { /* n+1: funny ksh stuff */
3142                         ap = *__lookupalias(n);
3143                         if (ap == NULL) {
3144                                 fprintf(stderr, "%s: %s not found\n", "alias", n);
3145                                 ret = 1;
3146                         } else
3147                                 printalias(ap);
3148                 } else {
3149                         *v++ = '\0';
3150                         setalias(n, v);
3151                 }
3152         }
3153
3154         return ret;
3155 }
3156
3157 static int
3158 unaliascmd(int argc, char **argv)
3159 {
3160         int i;
3161
3162         while ((i = nextopt("a")) != '\0') {
3163                 if (i == 'a') {
3164                         rmaliases();
3165                         return 0;
3166                 }
3167         }
3168         for (i = 0; *argptr; argptr++) {
3169                 if (unalias(*argptr)) {
3170                         fprintf(stderr, "%s: %s not found\n", "unalias", *argptr);
3171                         i = 1;
3172                 }
3173         }
3174
3175         return i;
3176 }
3177
3178 #endif /* ASH_ALIAS */
3179
3180
3181 /* ============ jobs.c */
3182
3183 /* Mode argument to forkshell.  Don't change FORK_FG or FORK_BG. */
3184 #define FORK_FG 0
3185 #define FORK_BG 1
3186 #define FORK_NOJOB 2
3187
3188 /* mode flags for showjob(s) */
3189 #define SHOW_PGID       0x01    /* only show pgid - for jobs -p */
3190 #define SHOW_PID        0x04    /* include process pid */
3191 #define SHOW_CHANGED    0x08    /* only jobs whose state has changed */
3192
3193 /*
3194  * A job structure contains information about a job.  A job is either a
3195  * single process or a set of processes contained in a pipeline.  In the
3196  * latter case, pidlist will be non-NULL, and will point to a -1 terminated
3197  * array of pids.
3198  */
3199
3200 struct procstat {
3201         pid_t   pid;            /* process id */
3202         int     status;         /* last process status from wait() */
3203         char    *cmd;           /* text of command being run */
3204 };
3205
3206 struct job {
3207         struct procstat ps0;    /* status of process */
3208         struct procstat *ps;    /* status or processes when more than one */
3209 #if JOBS
3210         int stopstatus;         /* status of a stopped job */
3211 #endif
3212         uint32_t
3213                 nprocs: 16,     /* number of processes */
3214                 state: 8,
3215 #define JOBRUNNING      0       /* at least one proc running */
3216 #define JOBSTOPPED      1       /* all procs are stopped */
3217 #define JOBDONE         2       /* all procs are completed */
3218 #if JOBS
3219                 sigint: 1,      /* job was killed by SIGINT */
3220                 jobctl: 1,      /* job running under job control */
3221 #endif
3222                 waited: 1,      /* true if this entry has been waited for */
3223                 used: 1,        /* true if this entry is in used */
3224                 changed: 1;     /* true if status has changed */
3225         struct job *prev_job;   /* previous job */
3226 };
3227
3228 static pid_t backgndpid;        /* pid of last background process */
3229 static smallint job_warning;    /* user was warned about stopped jobs (can be 2, 1 or 0). */
3230
3231 static struct job *makejob(union node *, int);
3232 static int forkshell(struct job *, union node *, int);
3233 static int waitforjob(struct job *);
3234
3235 #if !JOBS
3236 enum { jobctl = 0 };
3237 #define setjobctl(on) do {} while (0)
3238 #else
3239 static smallint jobctl;              /* true if doing job control */
3240 static void setjobctl(int);
3241 #endif
3242
3243 /*
3244  * Set the signal handler for the specified signal.  The routine figures
3245  * out what it should be set to.
3246  */
3247 static void
3248 setsignal(int signo)
3249 {
3250         int action;
3251         char *t, tsig;
3252         struct sigaction act;
3253
3254         t = trap[signo];
3255         action = S_IGN;
3256         if (t == NULL)
3257                 action = S_DFL;
3258         else if (*t != '\0')
3259                 action = S_CATCH;
3260         if (rootshell && action == S_DFL) {
3261                 switch (signo) {
3262                 case SIGINT:
3263                         if (iflag || minusc || sflag == 0)
3264                                 action = S_CATCH;
3265                         break;
3266                 case SIGQUIT:
3267 #if DEBUG
3268                         if (debug)
3269                                 break;
3270 #endif
3271                         /* FALLTHROUGH */
3272                 case SIGTERM:
3273                         if (iflag)
3274                                 action = S_IGN;
3275                         break;
3276 #if JOBS
3277                 case SIGTSTP:
3278                 case SIGTTOU:
3279                         if (mflag)
3280                                 action = S_IGN;
3281                         break;
3282 #endif
3283                 }
3284         }
3285
3286         t = &sigmode[signo - 1];
3287         tsig = *t;
3288         if (tsig == 0) {
3289                 /*
3290                  * current setting unknown
3291                  */
3292                 if (sigaction(signo, NULL, &act) == -1) {
3293                         /*
3294                          * Pretend it worked; maybe we should give a warning
3295                          * here, but other shells don't. We don't alter
3296                          * sigmode, so that we retry every time.
3297                          */
3298                         return;
3299                 }
3300                 tsig = S_RESET; /* force to be set */
3301                 if (act.sa_handler == SIG_IGN) {
3302                         tsig = S_HARD_IGN;
3303                         if (mflag
3304                          && (signo == SIGTSTP || signo == SIGTTIN || signo == SIGTTOU)
3305                         ) {
3306                                 tsig = S_IGN;   /* don't hard ignore these */
3307                         }
3308                 }
3309         }
3310         if (tsig == S_HARD_IGN || tsig == action)
3311                 return;
3312         act.sa_handler = SIG_DFL;
3313         switch (action) {
3314         case S_CATCH:
3315                 act.sa_handler = onsig;
3316                 break;
3317         case S_IGN:
3318                 act.sa_handler = SIG_IGN;
3319                 break;
3320         }
3321         *t = action;
3322         act.sa_flags = 0;
3323         sigfillset(&act.sa_mask);
3324         sigaction(signo, &act, NULL);
3325 }
3326
3327 /* mode flags for set_curjob */
3328 #define CUR_DELETE 2
3329 #define CUR_RUNNING 1
3330 #define CUR_STOPPED 0
3331
3332 /* mode flags for dowait */
3333 #define DOWAIT_NONBLOCK WNOHANG
3334 #define DOWAIT_BLOCK    0
3335
3336 #if JOBS
3337 /* pgrp of shell on invocation */
3338 static int initialpgrp;
3339 static int ttyfd = -1;
3340 #endif
3341 /* array of jobs */
3342 static struct job *jobtab;
3343 /* size of array */
3344 static unsigned njobs;
3345 /* current job */
3346 static struct job *curjob;
3347 /* number of presumed living untracked jobs */
3348 static int jobless;
3349
3350 static void
3351 set_curjob(struct job *jp, unsigned mode)
3352 {
3353         struct job *jp1;
3354         struct job **jpp, **curp;
3355
3356         /* first remove from list */
3357         jpp = curp = &curjob;
3358         do {
3359                 jp1 = *jpp;
3360                 if (jp1 == jp)
3361                         break;
3362                 jpp = &jp1->prev_job;
3363         } while (1);
3364         *jpp = jp1->prev_job;
3365
3366         /* Then re-insert in correct position */
3367         jpp = curp;
3368         switch (mode) {
3369         default:
3370 #if DEBUG
3371                 abort();
3372 #endif
3373         case CUR_DELETE:
3374                 /* job being deleted */
3375                 break;
3376         case CUR_RUNNING:
3377                 /* newly created job or backgrounded job,
3378                    put after all stopped jobs. */
3379                 do {
3380                         jp1 = *jpp;
3381 #if JOBS
3382                         if (!jp1 || jp1->state != JOBSTOPPED)
3383 #endif
3384                                 break;
3385                         jpp = &jp1->prev_job;
3386                 } while (1);
3387                 /* FALLTHROUGH */
3388 #if JOBS
3389         case CUR_STOPPED:
3390 #endif
3391                 /* newly stopped job - becomes curjob */
3392                 jp->prev_job = *jpp;
3393                 *jpp = jp;
3394                 break;
3395         }
3396 }
3397
3398 #if JOBS || DEBUG
3399 static int
3400 jobno(const struct job *jp)
3401 {
3402         return jp - jobtab + 1;
3403 }
3404 #endif
3405
3406 /*
3407  * Convert a job name to a job structure.
3408  */
3409 static struct job *
3410 getjob(const char *name, int getctl)
3411 {
3412         struct job *jp;
3413         struct job *found;
3414         const char *err_msg = "No such job: %s";
3415         unsigned num;
3416         int c;
3417         const char *p;
3418         char *(*match)(const char *, const char *);
3419
3420         jp = curjob;
3421         p = name;
3422         if (!p)
3423                 goto currentjob;
3424
3425         if (*p != '%')
3426                 goto err;
3427
3428         c = *++p;
3429         if (!c)
3430                 goto currentjob;
3431
3432         if (!p[1]) {
3433                 if (c == '+' || c == '%') {
3434  currentjob:
3435                         err_msg = "No current job";
3436                         goto check;
3437                 }
3438                 if (c == '-') {
3439                         if (jp)
3440                                 jp = jp->prev_job;
3441                         err_msg = "No previous job";
3442  check:
3443                         if (!jp)
3444                                 goto err;
3445                         goto gotit;
3446                 }
3447         }
3448
3449         if (is_number(p)) {
3450                 num = atoi(p);
3451                 if (num < njobs) {
3452                         jp = jobtab + num - 1;
3453                         if (jp->used)
3454                                 goto gotit;
3455                         goto err;
3456                 }
3457         }
3458
3459         match = prefix;
3460         if (*p == '?') {
3461                 match = strstr;
3462                 p++;
3463         }
3464
3465         found = 0;
3466         while (1) {
3467                 if (!jp)
3468                         goto err;
3469                 if (match(jp->ps[0].cmd, p)) {
3470                         if (found)
3471                                 goto err;
3472                         found = jp;
3473                         err_msg = "%s: ambiguous";
3474                 }
3475                 jp = jp->prev_job;
3476         }
3477
3478  gotit:
3479 #if JOBS
3480         err_msg = "job %s not created under job control";
3481         if (getctl && jp->jobctl == 0)
3482                 goto err;
3483 #endif
3484         return jp;
3485  err:
3486         ash_msg_and_raise_error(err_msg, name);
3487 }
3488
3489 /*
3490  * Mark a job structure as unused.
3491  */
3492 static void
3493 freejob(struct job *jp)
3494 {
3495         struct procstat *ps;
3496         int i;
3497
3498         INT_OFF;
3499         for (i = jp->nprocs, ps = jp->ps; --i >= 0; ps++) {
3500                 if (ps->cmd != nullstr)
3501                         free(ps->cmd);
3502         }
3503         if (jp->ps != &jp->ps0)
3504                 free(jp->ps);
3505         jp->used = 0;
3506         set_curjob(jp, CUR_DELETE);
3507         INT_ON;
3508 }
3509
3510 #if JOBS
3511 static void
3512 xtcsetpgrp(int fd, pid_t pgrp)
3513 {
3514         if (tcsetpgrp(fd, pgrp))
3515                 ash_msg_and_raise_error("cannot set tty process group (%m)");
3516 }
3517
3518 /*
3519  * Turn job control on and off.
3520  *
3521  * Note:  This code assumes that the third arg to ioctl is a character
3522  * pointer, which is true on Berkeley systems but not System V.  Since
3523  * System V doesn't have job control yet, this isn't a problem now.
3524  *
3525  * Called with interrupts off.
3526  */
3527 static void
3528 setjobctl(int on)
3529 {
3530         int fd;
3531         int pgrp;
3532
3533         if (on == jobctl || rootshell == 0)
3534                 return;
3535         if (on) {
3536                 int ofd;
3537                 ofd = fd = open(_PATH_TTY, O_RDWR);
3538                 if (fd < 0) {
3539         /* BTW, bash will try to open(ttyname(0)) if open("/dev/tty") fails.
3540          * That sometimes helps to acquire controlling tty.
3541          * Obviously, a workaround for bugs when someone
3542          * failed to provide a controlling tty to bash! :) */
3543                         fd = 2;
3544                         while (!isatty(fd))
3545                                 if (--fd < 0)
3546                                         goto out;
3547                 }
3548                 fd = fcntl(fd, F_DUPFD, 10);
3549                 if (ofd >= 0)
3550                         close(ofd);
3551                 if (fd < 0)
3552                         goto out;
3553                 /* fd is a tty at this point */
3554                 close_on_exec_on(fd);
3555                 do { /* while we are in the background */
3556                         pgrp = tcgetpgrp(fd);
3557                         if (pgrp < 0) {
3558  out:
3559                                 ash_msg("can't access tty; job control turned off");
3560                                 mflag = on = 0;
3561                                 goto close;
3562                         }
3563                         if (pgrp == getpgrp())
3564                                 break;
3565                         killpg(0, SIGTTIN);
3566                 } while (1);
3567                 initialpgrp = pgrp;
3568
3569                 setsignal(SIGTSTP);
3570                 setsignal(SIGTTOU);
3571                 setsignal(SIGTTIN);
3572                 pgrp = rootpid;
3573                 setpgid(0, pgrp);
3574                 xtcsetpgrp(fd, pgrp);
3575         } else {
3576                 /* turning job control off */
3577                 fd = ttyfd;
3578                 pgrp = initialpgrp;
3579                 /* was xtcsetpgrp, but this can make exiting ash
3580                  * loop forever if pty is already deleted */
3581                 tcsetpgrp(fd, pgrp);
3582                 setpgid(0, pgrp);
3583                 setsignal(SIGTSTP);
3584                 setsignal(SIGTTOU);
3585                 setsignal(SIGTTIN);
3586  close:
3587                 if (fd >= 0)
3588                         close(fd);
3589                 fd = -1;
3590         }
3591         ttyfd = fd;
3592         jobctl = on;
3593 }
3594
3595 static int
3596 killcmd(int argc, char **argv)
3597 {
3598         if (argv[1] && strcmp(argv[1], "-l") != 0) {
3599                 int i = 1;
3600                 do {
3601                         if (argv[i][0] == '%') {
3602                                 struct job *jp = getjob(argv[i], 0);
3603                                 unsigned pid = jp->ps[0].pid;
3604                                 /* Enough space for ' -NNN<nul>' */
3605                                 argv[i] = alloca(sizeof(int)*3 + 3);
3606                                 /* kill_main has matching code to expect
3607                                  * leading space. Needed to not confuse
3608                                  * negative pids with "kill -SIGNAL_NO" syntax */
3609                                 sprintf(argv[i], " -%u", pid);
3610                         }
3611                 } while (argv[++i]);
3612         }
3613         return kill_main(argc, argv);
3614 }
3615
3616 static void
3617 showpipe(struct job *jp, FILE *out)
3618 {
3619         struct procstat *sp;
3620         struct procstat *spend;
3621
3622         spend = jp->ps + jp->nprocs;
3623         for (sp = jp->ps + 1; sp < spend; sp++)
3624                 fprintf(out, " | %s", sp->cmd);
3625         outcslow('\n', out);
3626         flush_stdout_stderr();
3627 }
3628
3629
3630 static int
3631 restartjob(struct job *jp, int mode)
3632 {
3633         struct procstat *ps;
3634         int i;
3635         int status;
3636         pid_t pgid;
3637
3638         INT_OFF;
3639         if (jp->state == JOBDONE)
3640                 goto out;
3641         jp->state = JOBRUNNING;
3642         pgid = jp->ps->pid;
3643         if (mode == FORK_FG)
3644                 xtcsetpgrp(ttyfd, pgid);
3645         killpg(pgid, SIGCONT);
3646         ps = jp->ps;
3647         i = jp->nprocs;
3648         do {
3649                 if (WIFSTOPPED(ps->status)) {
3650                         ps->status = -1;
3651                 }
3652                 ps++;
3653         } while (--i);
3654  out:
3655         status = (mode == FORK_FG) ? waitforjob(jp) : 0;
3656         INT_ON;
3657         return status;
3658 }
3659
3660 static int
3661 fg_bgcmd(int argc, char **argv)
3662 {
3663         struct job *jp;
3664         FILE *out;
3665         int mode;
3666         int retval;
3667
3668         mode = (**argv == 'f') ? FORK_FG : FORK_BG;
3669         nextopt(nullstr);
3670         argv = argptr;
3671         out = stdout;
3672         do {
3673                 jp = getjob(*argv, 1);
3674                 if (mode == FORK_BG) {
3675                         set_curjob(jp, CUR_RUNNING);
3676                         fprintf(out, "[%d] ", jobno(jp));
3677                 }
3678                 outstr(jp->ps->cmd, out);
3679                 showpipe(jp, out);
3680                 retval = restartjob(jp, mode);
3681         } while (*argv && *++argv);
3682         return retval;
3683 }
3684 #endif
3685
3686 static int
3687 sprint_status(char *s, int status, int sigonly)
3688 {
3689         int col;
3690         int st;
3691
3692         col = 0;
3693         if (!WIFEXITED(status)) {
3694 #if JOBS
3695                 if (WIFSTOPPED(status))
3696                         st = WSTOPSIG(status);
3697                 else
3698 #endif
3699                         st = WTERMSIG(status);
3700                 if (sigonly) {
3701                         if (st == SIGINT || st == SIGPIPE)
3702                                 goto out;
3703 #if JOBS
3704                         if (WIFSTOPPED(status))
3705                                 goto out;
3706 #endif
3707                 }
3708                 st &= 0x7f;
3709                 col = fmtstr(s, 32, strsignal(st));
3710                 if (WCOREDUMP(status)) {
3711                         col += fmtstr(s + col, 16, " (core dumped)");
3712                 }
3713         } else if (!sigonly) {
3714                 st = WEXITSTATUS(status);
3715                 if (st)
3716                         col = fmtstr(s, 16, "Done(%d)", st);
3717                 else
3718                         col = fmtstr(s, 16, "Done");
3719         }
3720  out:
3721         return col;
3722 }
3723
3724 /*
3725  * Do a wait system call.  If job control is compiled in, we accept
3726  * stopped processes.  If block is zero, we return a value of zero
3727  * rather than blocking.
3728  *
3729  * System V doesn't have a non-blocking wait system call.  It does
3730  * have a SIGCLD signal that is sent to a process when one of it's
3731  * children dies.  The obvious way to use SIGCLD would be to install
3732  * a handler for SIGCLD which simply bumped a counter when a SIGCLD
3733  * was received, and have waitproc bump another counter when it got
3734  * the status of a process.  Waitproc would then know that a wait
3735  * system call would not block if the two counters were different.
3736  * This approach doesn't work because if a process has children that
3737  * have not been waited for, System V will send it a SIGCLD when it
3738  * installs a signal handler for SIGCLD.  What this means is that when
3739  * a child exits, the shell will be sent SIGCLD signals continuously
3740  * until is runs out of stack space, unless it does a wait call before
3741  * restoring the signal handler.  The code below takes advantage of
3742  * this (mis)feature by installing a signal handler for SIGCLD and
3743  * then checking to see whether it was called.  If there are any
3744  * children to be waited for, it will be.
3745  *
3746  * If neither SYSV nor BSD is defined, we don't implement nonblocking
3747  * waits at all.  In this case, the user will not be informed when
3748  * a background process until the next time she runs a real program
3749  * (as opposed to running a builtin command or just typing return),
3750  * and the jobs command may give out of date information.
3751  */
3752 static int
3753 waitproc(int wait_flags, int *status)
3754 {
3755 #if JOBS
3756         if (jobctl)
3757                 wait_flags |= WUNTRACED;
3758 #endif
3759         /* NB: _not_ safe_waitpid, we need to detect EINTR */
3760         return waitpid(-1, status, wait_flags);
3761 }
3762
3763 /*
3764  * Wait for a process to terminate.
3765  */
3766 static int
3767 dowait(int wait_flags, struct job *job)
3768 {
3769         int pid;
3770         int status;
3771         struct job *jp;
3772         struct job *thisjob;
3773         int state;
3774
3775         TRACE(("dowait(%d) called\n", wait_flags));
3776         pid = waitproc(wait_flags, &status);
3777         TRACE(("wait returns pid=%d, status=%d\n", pid, status));
3778         if (pid <= 0) {
3779                 /* If we were doing blocking wait and (probably) got EINTR,
3780                  * check for pending sigs received while waiting.
3781                  * (NB: can be moved into callers if needed) */
3782                 if (wait_flags == DOWAIT_BLOCK && pendingsig)
3783                         raise_exception(EXSIG);
3784                 return pid;
3785         }
3786         INT_OFF;
3787         thisjob = NULL;
3788         for (jp = curjob; jp; jp = jp->prev_job) {
3789                 struct procstat *sp;
3790                 struct procstat *spend;
3791                 if (jp->state == JOBDONE)
3792                         continue;
3793                 state = JOBDONE;
3794                 spend = jp->ps + jp->nprocs;
3795                 sp = jp->ps;
3796                 do {
3797                         if (sp->pid == pid) {
3798                                 TRACE(("Job %d: changing status of proc %d "
3799                                         "from 0x%x to 0x%x\n",
3800                                         jobno(jp), pid, sp->status, status));
3801                                 sp->status = status;
3802                                 thisjob = jp;
3803                         }
3804                         if (sp->status == -1)
3805                                 state = JOBRUNNING;
3806 #if JOBS
3807                         if (state == JOBRUNNING)
3808                                 continue;
3809                         if (WIFSTOPPED(sp->status)) {
3810                                 jp->stopstatus = sp->status;
3811                                 state = JOBSTOPPED;
3812                         }
3813 #endif
3814                 } while (++sp < spend);
3815                 if (thisjob)
3816                         goto gotjob;
3817         }
3818 #if JOBS
3819         if (!WIFSTOPPED(status))
3820 #endif
3821                 jobless--;
3822         goto out;
3823
3824  gotjob:
3825         if (state != JOBRUNNING) {
3826                 thisjob->changed = 1;
3827
3828                 if (thisjob->state != state) {
3829                         TRACE(("Job %d: changing state from %d to %d\n",
3830                                 jobno(thisjob), thisjob->state, state));
3831                         thisjob->state = state;
3832 #if JOBS
3833                         if (state == JOBSTOPPED) {
3834                                 set_curjob(thisjob, CUR_STOPPED);
3835                         }
3836 #endif
3837                 }
3838         }
3839
3840  out:
3841         INT_ON;
3842
3843         if (thisjob && thisjob == job) {
3844                 char s[48 + 1];
3845                 int len;
3846
3847                 len = sprint_status(s, status, 1);
3848                 if (len) {
3849                         s[len] = '\n';
3850                         s[len + 1] = '\0';
3851                         out2str(s);
3852                 }
3853         }
3854         return pid;
3855 }
3856
3857 #if JOBS
3858 static void
3859 showjob(FILE *out, struct job *jp, int mode)
3860 {
3861         struct procstat *ps;
3862         struct procstat *psend;
3863         int col;
3864         int indent_col;
3865         char s[80];
3866
3867         ps = jp->ps;
3868
3869         if (mode & SHOW_PGID) {
3870                 /* just output process (group) id of pipeline */
3871                 fprintf(out, "%d\n", ps->pid);
3872                 return;
3873         }
3874
3875         col = fmtstr(s, 16, "[%d]   ", jobno(jp));
3876         indent_col = col;
3877
3878         if (jp == curjob)
3879                 s[col - 2] = '+';
3880         else if (curjob && jp == curjob->prev_job)
3881                 s[col - 2] = '-';
3882
3883         if (mode & SHOW_PID)
3884                 col += fmtstr(s + col, 16, "%d ", ps->pid);
3885
3886         psend = ps + jp->nprocs;
3887
3888         if (jp->state == JOBRUNNING) {
3889                 strcpy(s + col, "Running");
3890                 col += sizeof("Running") - 1;
3891         } else {
3892                 int status = psend[-1].status;
3893                 if (jp->state == JOBSTOPPED)
3894                         status = jp->stopstatus;
3895                 col += sprint_status(s + col, status, 0);
3896         }
3897
3898         goto start;
3899
3900         do {
3901                 /* for each process */
3902                 col = fmtstr(s, 48, " |\n%*c%d ", indent_col, ' ', ps->pid) - 3;
3903  start:
3904                 fprintf(out, "%s%*c%s",
3905                         s, 33 - col >= 0 ? 33 - col : 0, ' ', ps->cmd
3906                 );
3907                 if (!(mode & SHOW_PID)) {
3908                         showpipe(jp, out);
3909                         break;
3910                 }
3911                 if (++ps == psend) {
3912                         outcslow('\n', out);
3913                         break;
3914                 }
3915         } while (1);
3916
3917         jp->changed = 0;
3918
3919         if (jp->state == JOBDONE) {
3920                 TRACE(("showjob: freeing job %d\n", jobno(jp)));
3921                 freejob(jp);
3922         }
3923 }
3924
3925 /*
3926  * Print a list of jobs.  If "change" is nonzero, only print jobs whose
3927  * statuses have changed since the last call to showjobs.
3928  */
3929 static void
3930 showjobs(FILE *out, int mode)
3931 {
3932         struct job *jp;
3933
3934         TRACE(("showjobs(%x) called\n", mode));
3935
3936         /* If not even one job changed, there is nothing to do */
3937         while (dowait(DOWAIT_NONBLOCK, NULL) > 0)
3938                 continue;
3939
3940         for (jp = curjob; jp; jp = jp->prev_job) {
3941                 if (!(mode & SHOW_CHANGED) || jp->changed) {
3942                         showjob(out, jp, mode);
3943                 }
3944         }
3945 }
3946
3947 static int
3948 jobscmd(int argc, char **argv)
3949 {
3950         int mode, m;
3951
3952         mode = 0;
3953         while ((m = nextopt("lp"))) {
3954                 if (m == 'l')
3955                         mode = SHOW_PID;
3956                 else
3957                         mode = SHOW_PGID;
3958         }
3959
3960         argv = argptr;
3961         if (*argv) {
3962                 do
3963                         showjob(stdout, getjob(*argv,0), mode);
3964                 while (*++argv);
3965         } else
3966                 showjobs(stdout, mode);
3967
3968         return 0;
3969 }
3970 #endif /* JOBS */
3971
3972 static int
3973 getstatus(struct job *job)
3974 {
3975         int status;
3976         int retval;
3977
3978         status = job->ps[job->nprocs - 1].status;
3979         retval = WEXITSTATUS(status);
3980         if (!WIFEXITED(status)) {
3981 #if JOBS
3982                 retval = WSTOPSIG(status);
3983                 if (!WIFSTOPPED(status))
3984 #endif
3985                 {
3986                         /* XXX: limits number of signals */
3987                         retval = WTERMSIG(status);
3988 #if JOBS
3989                         if (retval == SIGINT)
3990                                 job->sigint = 1;
3991 #endif
3992                 }
3993                 retval += 128;
3994         }
3995         TRACE(("getstatus: job %d, nproc %d, status %x, retval %x\n",
3996                 jobno(job), job->nprocs, status, retval));
3997         return retval;
3998 }
3999
4000 static int
4001 waitcmd(int argc, char **argv)
4002 {
4003         struct job *job;
4004         int retval;
4005         struct job *jp;
4006
4007 //      exsig++;
4008 //      xbarrier();
4009         if (pendingsig)
4010                 raise_exception(EXSIG);
4011
4012         nextopt(nullstr);
4013         retval = 0;
4014
4015         argv = argptr;
4016         if (!*argv) {
4017                 /* wait for all jobs */
4018                 for (;;) {
4019                         jp = curjob;
4020                         while (1) {
4021                                 if (!jp) /* no running procs */
4022                                         goto ret;
4023                                 if (jp->state == JOBRUNNING)
4024                                         break;
4025                                 jp->waited = 1;
4026                                 jp = jp->prev_job;
4027                         }
4028                         dowait(DOWAIT_BLOCK, NULL);
4029                 }
4030         }
4031
4032         retval = 127;
4033         do {
4034                 if (**argv != '%') {
4035                         pid_t pid = number(*argv);
4036                         job = curjob;
4037                         while (1) {
4038                                 if (!job)
4039                                         goto repeat;
4040                                 if (job->ps[job->nprocs - 1].pid == pid)
4041                                         break;
4042                                 job = job->prev_job;
4043                         }
4044                 } else
4045                         job = getjob(*argv, 0);
4046                 /* loop until process terminated or stopped */
4047                 while (job->state == JOBRUNNING)
4048                         dowait(DOWAIT_BLOCK, NULL);
4049                 job->waited = 1;
4050                 retval = getstatus(job);
4051  repeat:
4052                 ;
4053         } while (*++argv);
4054
4055  ret:
4056         return retval;
4057 }
4058
4059 static struct job *
4060 growjobtab(void)
4061 {
4062         size_t len;
4063         ptrdiff_t offset;
4064         struct job *jp, *jq;
4065
4066         len = njobs * sizeof(*jp);
4067         jq = jobtab;
4068         jp = ckrealloc(jq, len + 4 * sizeof(*jp));
4069
4070         offset = (char *)jp - (char *)jq;
4071         if (offset) {
4072                 /* Relocate pointers */
4073                 size_t l = len;
4074
4075                 jq = (struct job *)((char *)jq + l);
4076                 while (l) {
4077                         l -= sizeof(*jp);
4078                         jq--;
4079 #define joff(p) ((struct job *)((char *)(p) + l))
4080 #define jmove(p) (p) = (void *)((char *)(p) + offset)
4081                         if (joff(jp)->ps == &jq->ps0)
4082                                 jmove(joff(jp)->ps);
4083                         if (joff(jp)->prev_job)
4084                                 jmove(joff(jp)->prev_job);
4085                 }
4086                 if (curjob)
4087                         jmove(curjob);
4088 #undef joff
4089 #undef jmove
4090         }
4091
4092         njobs += 4;
4093         jobtab = jp;
4094         jp = (struct job *)((char *)jp + len);
4095         jq = jp + 3;
4096         do {
4097                 jq->used = 0;
4098         } while (--jq >= jp);
4099         return jp;
4100 }
4101
4102 /*
4103  * Return a new job structure.
4104  * Called with interrupts off.
4105  */
4106 static struct job *
4107 makejob(union node *node, int nprocs)
4108 {
4109         int i;
4110         struct job *jp;
4111
4112         for (i = njobs, jp = jobtab; ; jp++) {
4113                 if (--i < 0) {
4114                         jp = growjobtab();
4115                         break;
4116                 }
4117                 if (jp->used == 0)
4118                         break;
4119                 if (jp->state != JOBDONE || !jp->waited)
4120                         continue;
4121 #if JOBS
4122                 if (jobctl)
4123                         continue;
4124 #endif
4125                 freejob(jp);
4126                 break;
4127         }
4128         memset(jp, 0, sizeof(*jp));
4129 #if JOBS
4130         /* jp->jobctl is a bitfield.
4131          * "jp->jobctl |= jobctl" likely to give awful code */
4132         if (jobctl)
4133                 jp->jobctl = 1;
4134 #endif
4135         jp->prev_job = curjob;
4136         curjob = jp;
4137         jp->used = 1;
4138         jp->ps = &jp->ps0;
4139         if (nprocs > 1) {
4140                 jp->ps = ckmalloc(nprocs * sizeof(struct procstat));
4141         }
4142         TRACE(("makejob(0x%lx, %d) returns %%%d\n", (long)node, nprocs,
4143                                 jobno(jp)));
4144         return jp;
4145 }
4146
4147 #if JOBS
4148 /*
4149  * Return a string identifying a command (to be printed by the
4150  * jobs command).
4151  */
4152 static char *cmdnextc;
4153
4154 static void
4155 cmdputs(const char *s)
4156 {
4157         const char *p, *str;
4158         char c, cc[2] = " ";
4159         char *nextc;
4160         int subtype = 0;
4161         int quoted = 0;
4162         static const char vstype[VSTYPE + 1][4] = {
4163                 "", "}", "-", "+", "?", "=",
4164                 "%", "%%", "#", "##"
4165         };
4166
4167         nextc = makestrspace((strlen(s) + 1) * 8, cmdnextc);
4168         p = s;
4169         while ((c = *p++) != 0) {
4170                 str = 0;
4171                 switch (c) {
4172                 case CTLESC:
4173                         c = *p++;
4174                         break;
4175                 case CTLVAR:
4176                         subtype = *p++;
4177                         if ((subtype & VSTYPE) == VSLENGTH)
4178                                 str = "${#";
4179                         else
4180                                 str = "${";
4181                         if (!(subtype & VSQUOTE) == !(quoted & 1))
4182                                 goto dostr;
4183                         quoted ^= 1;
4184                         c = '"';
4185                         break;
4186                 case CTLENDVAR:
4187                         str = "\"}" + !(quoted & 1);
4188                         quoted >>= 1;
4189                         subtype = 0;
4190                         goto dostr;
4191                 case CTLBACKQ:
4192                         str = "$(...)";
4193                         goto dostr;
4194                 case CTLBACKQ+CTLQUOTE:
4195                         str = "\"$(...)\"";
4196                         goto dostr;
4197 #if ENABLE_ASH_MATH_SUPPORT
4198                 case CTLARI:
4199                         str = "$((";
4200                         goto dostr;
4201                 case CTLENDARI:
4202                         str = "))";
4203                         goto dostr;
4204 #endif
4205                 case CTLQUOTEMARK:
4206                         quoted ^= 1;
4207                         c = '"';
4208                         break;
4209                 case '=':
4210                         if (subtype == 0)
4211                                 break;
4212                         if ((subtype & VSTYPE) != VSNORMAL)
4213                                 quoted <<= 1;
4214                         str = vstype[subtype & VSTYPE];
4215                         if (subtype & VSNUL)
4216                                 c = ':';
4217                         else
4218                                 goto checkstr;
4219                         break;
4220                 case '\'':
4221                 case '\\':
4222                 case '"':
4223                 case '$':
4224                         /* These can only happen inside quotes */
4225                         cc[0] = c;
4226                         str = cc;
4227                         c = '\\';
4228                         break;
4229                 default:
4230                         break;
4231                 }
4232                 USTPUTC(c, nextc);
4233  checkstr:
4234                 if (!str)
4235                         continue;
4236  dostr:
4237                 while ((c = *str++)) {
4238                         USTPUTC(c, nextc);
4239                 }
4240         }
4241         if (quoted & 1) {
4242                 USTPUTC('"', nextc);
4243         }
4244         *nextc = 0;
4245         cmdnextc = nextc;
4246 }
4247
4248 /* cmdtxt() and cmdlist() call each other */
4249 static void cmdtxt(union node *n);
4250
4251 static void
4252 cmdlist(union node *np, int sep)
4253 {
4254         for (; np; np = np->narg.next) {
4255                 if (!sep)
4256                         cmdputs(" ");
4257                 cmdtxt(np);
4258                 if (sep && np->narg.next)
4259                         cmdputs(" ");
4260         }
4261 }
4262
4263 static void
4264 cmdtxt(union node *n)
4265 {
4266         union node *np;
4267         struct nodelist *lp;
4268         const char *p;
4269         char s[2];
4270
4271         if (!n)
4272                 return;
4273         switch (n->type) {
4274         default:
4275 #if DEBUG
4276                 abort();
4277 #endif
4278         case NPIPE:
4279                 lp = n->npipe.cmdlist;
4280                 for (;;) {
4281                         cmdtxt(lp->n);
4282                         lp = lp->next;
4283                         if (!lp)
4284                                 break;
4285                         cmdputs(" | ");
4286                 }
4287                 break;
4288         case NSEMI:
4289                 p = "; ";
4290                 goto binop;
4291         case NAND:
4292                 p = " && ";
4293                 goto binop;
4294         case NOR:
4295                 p = " || ";
4296  binop:
4297                 cmdtxt(n->nbinary.ch1);
4298                 cmdputs(p);
4299                 n = n->nbinary.ch2;
4300                 goto donode;
4301         case NREDIR:
4302         case NBACKGND:
4303                 n = n->nredir.n;
4304                 goto donode;
4305         case NNOT:
4306                 cmdputs("!");
4307                 n = n->nnot.com;
4308  donode:
4309                 cmdtxt(n);
4310                 break;
4311         case NIF:
4312                 cmdputs("if ");
4313                 cmdtxt(n->nif.test);
4314                 cmdputs("; then ");
4315                 n = n->nif.ifpart;
4316                 if (n->nif.elsepart) {
4317                         cmdtxt(n);
4318                         cmdputs("; else ");
4319                         n = n->nif.elsepart;
4320                 }
4321                 p = "; fi";
4322                 goto dotail;
4323         case NSUBSHELL:
4324                 cmdputs("(");
4325                 n = n->nredir.n;
4326                 p = ")";
4327                 goto dotail;
4328         case NWHILE:
4329                 p = "while ";
4330                 goto until;
4331         case NUNTIL:
4332                 p = "until ";
4333  until:
4334                 cmdputs(p);
4335                 cmdtxt(n->nbinary.ch1);
4336                 n = n->nbinary.ch2;
4337                 p = "; done";
4338  dodo:
4339                 cmdputs("; do ");
4340  dotail:
4341                 cmdtxt(n);
4342                 goto dotail2;
4343         case NFOR:
4344                 cmdputs("for ");
4345                 cmdputs(n->nfor.var);
4346                 cmdputs(" in ");
4347                 cmdlist(n->nfor.args, 1);
4348                 n = n->nfor.body;
4349                 p = "; done";
4350                 goto dodo;
4351         case NDEFUN:
4352                 cmdputs(n->narg.text);
4353                 p = "() { ... }";
4354                 goto dotail2;
4355         case NCMD:
4356                 cmdlist(n->ncmd.args, 1);
4357                 cmdlist(n->ncmd.redirect, 0);
4358                 break;
4359         case NARG:
4360                 p = n->narg.text;
4361  dotail2:
4362                 cmdputs(p);
4363                 break;
4364         case NHERE:
4365         case NXHERE:
4366                 p = "<<...";
4367                 goto dotail2;
4368         case NCASE:
4369                 cmdputs("case ");
4370                 cmdputs(n->ncase.expr->narg.text);
4371                 cmdputs(" in ");
4372                 for (np = n->ncase.cases; np; np = np->nclist.next) {
4373                         cmdtxt(np->nclist.pattern);
4374                         cmdputs(") ");
4375                         cmdtxt(np->nclist.body);
4376                         cmdputs(";; ");
4377                 }
4378                 p = "esac";
4379                 goto dotail2;
4380         case NTO:
4381                 p = ">";
4382                 goto redir;
4383         case NCLOBBER:
4384                 p = ">|";
4385                 goto redir;
4386         case NAPPEND:
4387                 p = ">>";
4388                 goto redir;
4389         case NTOFD:
4390                 p = ">&";
4391                 goto redir;
4392         case NFROM:
4393                 p = "<";
4394                 goto redir;
4395         case NFROMFD:
4396                 p = "<&";
4397                 goto redir;
4398         case NFROMTO:
4399                 p = "<>";
4400  redir:
4401                 s[0] = n->nfile.fd + '0';
4402                 s[1] = '\0';
4403                 cmdputs(s);
4404                 cmdputs(p);
4405                 if (n->type == NTOFD || n->type == NFROMFD) {
4406                         s[0] = n->ndup.dupfd + '0';
4407                         p = s;
4408                         goto dotail2;
4409                 }
4410                 n = n->nfile.fname;
4411                 goto donode;
4412         }
4413 }
4414
4415 static char *
4416 commandtext(union node *n)
4417 {
4418         char *name;
4419
4420         STARTSTACKSTR(cmdnextc);
4421         cmdtxt(n);
4422         name = stackblock();
4423         TRACE(("commandtext: name %p, end %p\n\t\"%s\"\n",
4424                         name, cmdnextc, cmdnextc));
4425         return ckstrdup(name);
4426 }
4427 #endif /* JOBS */
4428
4429 /*
4430  * Fork off a subshell.  If we are doing job control, give the subshell its
4431  * own process group.  Jp is a job structure that the job is to be added to.
4432  * N is the command that will be evaluated by the child.  Both jp and n may
4433  * be NULL.  The mode parameter can be one of the following:
4434  *      FORK_FG - Fork off a foreground process.
4435  *      FORK_BG - Fork off a background process.
4436  *      FORK_NOJOB - Like FORK_FG, but don't give the process its own
4437  *                   process group even if job control is on.
4438  *
4439  * When job control is turned off, background processes have their standard
4440  * input redirected to /dev/null (except for the second and later processes
4441  * in a pipeline).
4442  *
4443  * Called with interrupts off.
4444  */
4445 /*
4446  * Clear traps on a fork.
4447  */
4448 static void
4449 clear_traps(void)
4450 {
4451         char **tp;
4452
4453         for (tp = trap; tp < &trap[NSIG]; tp++) {
4454                 if (*tp && **tp) {      /* trap not NULL or "" (SIG_IGN) */
4455                         INT_OFF;
4456                         free(*tp);
4457                         *tp = NULL;
4458                         if (tp != &trap[0])
4459                                 setsignal(tp - trap);
4460                         INT_ON;
4461                 }
4462         }
4463 }
4464
4465 /* Lives far away from here, needed for forkchild */
4466 static void closescript(void);
4467
4468 /* Called after fork(), in child */
4469 static void
4470 forkchild(struct job *jp, union node *n, int mode)
4471 {
4472         int oldlvl;
4473
4474         TRACE(("Child shell %d\n", getpid()));
4475         oldlvl = shlvl;
4476         shlvl++;
4477
4478         closescript();
4479         clear_traps();
4480 #if JOBS
4481         /* do job control only in root shell */
4482         jobctl = 0;
4483         if (mode != FORK_NOJOB && jp->jobctl && !oldlvl) {
4484                 pid_t pgrp;
4485
4486                 if (jp->nprocs == 0)
4487                         pgrp = getpid();
4488                 else
4489                         pgrp = jp->ps[0].pid;
4490                 /* This can fail because we are doing it in the parent also */
4491                 (void)setpgid(0, pgrp);
4492                 if (mode == FORK_FG)
4493                         xtcsetpgrp(ttyfd, pgrp);
4494                 setsignal(SIGTSTP);
4495                 setsignal(SIGTTOU);
4496         } else
4497 #endif
4498         if (mode == FORK_BG) {
4499                 ignoresig(SIGINT);
4500                 ignoresig(SIGQUIT);
4501                 if (jp->nprocs == 0) {
4502                         close(0);
4503                         if (open(bb_dev_null, O_RDONLY) != 0)
4504                                 ash_msg_and_raise_error("can't open %s", bb_dev_null);
4505                 }
4506         }
4507         if (!oldlvl && iflag) {
4508                 setsignal(SIGINT);
4509                 setsignal(SIGQUIT);
4510                 setsignal(SIGTERM);
4511         }
4512         for (jp = curjob; jp; jp = jp->prev_job)
4513                 freejob(jp);
4514         jobless = 0;
4515 }
4516
4517 /* Called after fork(), in parent */
4518 static void
4519 forkparent(struct job *jp, union node *n, int mode, pid_t pid)
4520 {
4521         TRACE(("In parent shell: child = %d\n", pid));
4522         if (!jp) {
4523                 while (jobless && dowait(DOWAIT_NONBLOCK, NULL) > 0)
4524                         continue;
4525                 jobless++;
4526                 return;
4527         }
4528 #if JOBS
4529         if (mode != FORK_NOJOB && jp->jobctl) {
4530                 int pgrp;
4531
4532                 if (jp->nprocs == 0)
4533                         pgrp = pid;
4534                 else
4535                         pgrp = jp->ps[0].pid;
4536                 /* This can fail because we are doing it in the child also */
4537                 setpgid(pid, pgrp);
4538         }
4539 #endif
4540         if (mode == FORK_BG) {
4541                 backgndpid = pid;               /* set $! */
4542                 set_curjob(jp, CUR_RUNNING);
4543         }
4544         if (jp) {
4545                 struct procstat *ps = &jp->ps[jp->nprocs++];
4546                 ps->pid = pid;
4547                 ps->status = -1;
4548                 ps->cmd = nullstr;
4549 #if JOBS
4550                 if (jobctl && n)
4551                         ps->cmd = commandtext(n);
4552 #endif
4553         }
4554 }
4555
4556 static int
4557 forkshell(struct job *jp, union node *n, int mode)
4558 {
4559         int pid;
4560
4561         TRACE(("forkshell(%%%d, %p, %d) called\n", jobno(jp), n, mode));
4562         pid = fork();
4563         if (pid < 0) {
4564                 TRACE(("Fork failed, errno=%d", errno));
4565                 if (jp)
4566                         freejob(jp);
4567                 ash_msg_and_raise_error("cannot fork");
4568         }
4569         if (pid == 0)
4570                 forkchild(jp, n, mode);
4571         else
4572                 forkparent(jp, n, mode, pid);
4573         return pid;
4574 }
4575
4576 /*
4577  * Wait for job to finish.
4578  *
4579  * Under job control we have the problem that while a child process is
4580  * running interrupts generated by the user are sent to the child but not
4581  * to the shell.  This means that an infinite loop started by an inter-
4582  * active user may be hard to kill.  With job control turned off, an
4583  * interactive user may place an interactive program inside a loop.  If
4584  * the interactive program catches interrupts, the user doesn't want
4585  * these interrupts to also abort the loop.  The approach we take here
4586  * is to have the shell ignore interrupt signals while waiting for a
4587  * foreground process to terminate, and then send itself an interrupt
4588  * signal if the child process was terminated by an interrupt signal.
4589  * Unfortunately, some programs want to do a bit of cleanup and then
4590  * exit on interrupt; unless these processes terminate themselves by
4591  * sending a signal to themselves (instead of calling exit) they will
4592  * confuse this approach.
4593  *
4594  * Called with interrupts off.
4595  */
4596 static int
4597 waitforjob(struct job *jp)
4598 {
4599         int st;
4600
4601         TRACE(("waitforjob(%%%d) called\n", jobno(jp)));
4602         while (jp->state == JOBRUNNING) {
4603                 dowait(DOWAIT_BLOCK, jp);
4604         }
4605         st = getstatus(jp);
4606 #if JOBS
4607         if (jp->jobctl) {
4608                 xtcsetpgrp(ttyfd, rootpid);
4609                 /*
4610                  * This is truly gross.
4611                  * If we're doing job control, then we did a TIOCSPGRP which
4612                  * caused us (the shell) to no longer be in the controlling
4613                  * session -- so we wouldn't have seen any ^C/SIGINT.  So, we
4614                  * intuit from the subprocess exit status whether a SIGINT
4615                  * occurred, and if so interrupt ourselves.  Yuck.  - mycroft
4616                  */
4617                 if (jp->sigint) /* TODO: do the same with all signals */
4618                         raise(SIGINT); /* ... by raise(jp->sig) instead? */
4619         }
4620         if (jp->state == JOBDONE)
4621 #endif
4622                 freejob(jp);
4623         return st;
4624 }
4625
4626 /*
4627  * return 1 if there are stopped jobs, otherwise 0
4628  */
4629 static int
4630 stoppedjobs(void)
4631 {
4632         struct job *jp;
4633         int retval;
4634
4635         retval = 0;
4636         if (job_warning)
4637                 goto out;
4638         jp = curjob;
4639         if (jp && jp->state == JOBSTOPPED) {
4640                 out2str("You have stopped jobs.\n");
4641                 job_warning = 2;
4642                 retval++;
4643         }
4644  out:
4645         return retval;
4646 }
4647
4648
4649 /* ============ redir.c
4650  *
4651  * Code for dealing with input/output redirection.
4652  */
4653
4654 #define EMPTY -2                /* marks an unused slot in redirtab */
4655 #define CLOSED -3               /* marks a slot of previously-closed fd */
4656 #ifndef PIPE_BUF
4657 # define PIPESIZE 4096          /* amount of buffering in a pipe */
4658 #else
4659 # define PIPESIZE PIPE_BUF
4660 #endif
4661
4662 /*
4663  * Open a file in noclobber mode.
4664  * The code was copied from bash.
4665  */
4666 static int
4667 noclobberopen(const char *fname)
4668 {
4669         int r, fd;
4670         struct stat finfo, finfo2;
4671
4672         /*
4673          * If the file exists and is a regular file, return an error
4674          * immediately.
4675          */
4676         r = stat(fname, &finfo);
4677         if (r == 0 && S_ISREG(finfo.st_mode)) {
4678                 errno = EEXIST;
4679                 return -1;
4680         }
4681
4682         /*
4683          * If the file was not present (r != 0), make sure we open it
4684          * exclusively so that if it is created before we open it, our open
4685          * will fail.  Make sure that we do not truncate an existing file.
4686          * Note that we don't turn on O_EXCL unless the stat failed -- if the
4687          * file was not a regular file, we leave O_EXCL off.
4688          */
4689         if (r != 0)
4690                 return open(fname, O_WRONLY|O_CREAT|O_EXCL, 0666);
4691         fd = open(fname, O_WRONLY|O_CREAT, 0666);
4692
4693         /* If the open failed, return the file descriptor right away. */
4694         if (fd < 0)
4695                 return fd;
4696
4697         /*
4698          * OK, the open succeeded, but the file may have been changed from a
4699          * non-regular file to a regular file between the stat and the open.
4700          * We are assuming that the O_EXCL open handles the case where FILENAME
4701          * did not exist and is symlinked to an existing file between the stat
4702          * and open.
4703          */
4704
4705         /*
4706          * If we can open it and fstat the file descriptor, and neither check
4707          * revealed that it was a regular file, and the file has not been
4708          * replaced, return the file descriptor.
4709          */
4710         if (fstat(fd, &finfo2) == 0 && !S_ISREG(finfo2.st_mode)
4711          && finfo.st_dev == finfo2.st_dev && finfo.st_ino == finfo2.st_ino)
4712                 return fd;
4713
4714         /* The file has been replaced.  badness. */
4715         close(fd);
4716         errno = EEXIST;
4717         return -1;
4718 }
4719
4720 /*
4721  * Handle here documents.  Normally we fork off a process to write the
4722  * data to a pipe.  If the document is short, we can stuff the data in
4723  * the pipe without forking.
4724  */
4725 /* openhere needs this forward reference */
4726 static void expandhere(union node *arg, int fd);
4727 static int
4728 openhere(union node *redir)
4729 {
4730         int pip[2];
4731         size_t len = 0;
4732
4733         if (pipe(pip) < 0)
4734                 ash_msg_and_raise_error("pipe call failed");
4735         if (redir->type == NHERE) {
4736                 len = strlen(redir->nhere.doc->narg.text);
4737                 if (len <= PIPESIZE) {
4738                         full_write(pip[1], redir->nhere.doc->narg.text, len);
4739                         goto out;
4740                 }
4741         }
4742         if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) {
4743                 close(pip[0]);
4744                 signal(SIGINT, SIG_IGN);
4745                 signal(SIGQUIT, SIG_IGN);
4746                 signal(SIGHUP, SIG_IGN);
4747 #ifdef SIGTSTP
4748                 signal(SIGTSTP, SIG_IGN);
4749 #endif
4750                 signal(SIGPIPE, SIG_DFL);
4751                 if (redir->type == NHERE)
4752                         full_write(pip[1], redir->nhere.doc->narg.text, len);
4753                 else
4754                         expandhere(redir->nhere.doc, pip[1]);
4755                 _exit(0);
4756         }
4757  out:
4758         close(pip[1]);
4759         return pip[0];
4760 }
4761
4762 static int
4763 openredirect(union node *redir)
4764 {
4765         char *fname;
4766         int f;
4767
4768         switch (redir->nfile.type) {
4769         case NFROM:
4770                 fname = redir->nfile.expfname;
4771                 f = open(fname, O_RDONLY);
4772                 if (f < 0)
4773                         goto eopen;
4774                 break;
4775         case NFROMTO:
4776                 fname = redir->nfile.expfname;
4777                 f = open(fname, O_RDWR|O_CREAT|O_TRUNC, 0666);
4778                 if (f < 0)
4779                         goto ecreate;
4780                 break;
4781         case NTO:
4782                 /* Take care of noclobber mode. */
4783                 if (Cflag) {
4784                         fname = redir->nfile.expfname;
4785                         f = noclobberopen(fname);
4786                         if (f < 0)
4787                                 goto ecreate;
4788                         break;
4789                 }
4790                 /* FALLTHROUGH */
4791         case NCLOBBER:
4792                 fname = redir->nfile.expfname;
4793                 f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666);
4794                 if (f < 0)
4795                         goto ecreate;
4796                 break;
4797         case NAPPEND:
4798                 fname = redir->nfile.expfname;
4799                 f = open(fname, O_WRONLY|O_CREAT|O_APPEND, 0666);
4800                 if (f < 0)
4801                         goto ecreate;
4802                 break;
4803         default:
4804 #if DEBUG
4805                 abort();
4806 #endif
4807                 /* Fall through to eliminate warning. */
4808         case NTOFD:
4809         case NFROMFD:
4810                 f = -1;
4811                 break;
4812         case NHERE:
4813         case NXHERE:
4814                 f = openhere(redir);
4815                 break;
4816         }
4817
4818         return f;
4819  ecreate:
4820         ash_msg_and_raise_error("cannot create %s: %s", fname, errmsg(errno, "nonexistent directory"));
4821  eopen:
4822         ash_msg_and_raise_error("cannot open %s: %s", fname, errmsg(errno, "no such file"));
4823 }
4824
4825 /*
4826  * Copy a file descriptor to be >= to.  Returns -1
4827  * if the source file descriptor is closed, EMPTY if there are no unused
4828  * file descriptors left.
4829  */
4830 static int
4831 copyfd(int from, int to)
4832 {
4833         int newfd;
4834
4835         newfd = fcntl(from, F_DUPFD, to);
4836         if (newfd < 0) {
4837                 if (errno == EMFILE)
4838                         return EMPTY;
4839                 ash_msg_and_raise_error("%d: %m", from);
4840         }
4841         return newfd;
4842 }
4843
4844 static void
4845 dupredirect(union node *redir, int f)
4846 {
4847         int fd = redir->nfile.fd;
4848
4849         if (redir->nfile.type == NTOFD || redir->nfile.type == NFROMFD) {
4850                 if (redir->ndup.dupfd >= 0) {   /* if not ">&-" */
4851                         copyfd(redir->ndup.dupfd, fd);
4852                 }
4853                 return;
4854         }
4855
4856         if (f != fd) {
4857                 copyfd(f, fd);
4858                 close(f);
4859         }
4860 }
4861
4862 /*
4863  * Process a list of redirection commands.  If the REDIR_PUSH flag is set,
4864  * old file descriptors are stashed away so that the redirection can be
4865  * undone by calling popredir.  If the REDIR_BACKQ flag is set, then the
4866  * standard output, and the standard error if it becomes a duplicate of
4867  * stdout, is saved in memory.
4868  */
4869 /* flags passed to redirect */
4870 #define REDIR_PUSH    01        /* save previous values of file descriptors */
4871 #define REDIR_SAVEFD2 03        /* set preverrout */
4872 static void
4873 redirect(union node *redir, int flags)
4874 {
4875         union node *n;
4876         struct redirtab *sv;
4877         int i;
4878         int fd;
4879         int newfd;
4880
4881         g_nullredirs++;
4882         if (!redir) {
4883                 return;
4884         }
4885         sv = NULL;
4886         INT_OFF;
4887         if (flags & REDIR_PUSH) {
4888                 sv = ckmalloc(sizeof(*sv));
4889                 sv->next = redirlist;
4890                 redirlist = sv;
4891                 sv->nullredirs = g_nullredirs - 1;
4892                 for (i = 0; i < 10; i++)
4893                         sv->renamed[i] = EMPTY;
4894                 g_nullredirs = 0;
4895         }
4896         n = redir;
4897         do {
4898                 fd = n->nfile.fd;
4899                 if ((n->nfile.type == NTOFD || n->nfile.type == NFROMFD)
4900                  && n->ndup.dupfd == fd)
4901                         continue; /* redirect from/to same file descriptor */
4902
4903                 newfd = openredirect(n);
4904                 if (fd == newfd) {
4905                         /* Descriptor wasn't open before redirect.
4906                          * Mark it for close in the future */
4907                         if (sv && sv->renamed[fd] == EMPTY)
4908                                 sv->renamed[fd] = CLOSED;
4909                         continue;
4910                 }
4911                 if (sv && sv->renamed[fd] == EMPTY) {
4912                         i = fcntl(fd, F_DUPFD, 10);
4913
4914                         if (i == -1) {
4915                                 i = errno;
4916                                 if (i != EBADF) {
4917                                         close(newfd);
4918                                         errno = i;
4919                                         ash_msg_and_raise_error("%d: %m", fd);
4920                                         /* NOTREACHED */
4921                                 }
4922                         } else {
4923                                 sv->renamed[fd] = i;
4924                                 close(fd);
4925                         }
4926                 } else {
4927                         close(fd);
4928                 }
4929                 dupredirect(n, newfd);
4930         } while ((n = n->nfile.next));
4931         INT_ON;
4932         if ((flags & REDIR_SAVEFD2) && sv && sv->renamed[2] >= 0)
4933                 preverrout_fd = sv->renamed[2];
4934 }
4935
4936 /*
4937  * Undo the effects of the last redirection.
4938  */
4939 static void
4940 popredir(int drop)
4941 {
4942         struct redirtab *rp;
4943         int i;
4944
4945         if (--g_nullredirs >= 0)
4946                 return;
4947         INT_OFF;
4948         rp = redirlist;
4949         for (i = 0; i < 10; i++) {
4950                 if (rp->renamed[i] == CLOSED) {
4951                         if (!drop)
4952                                 close(i);
4953                         continue;
4954                 }
4955                 if (rp->renamed[i] != EMPTY) {
4956                         if (!drop) {
4957                                 close(i);
4958                                 copyfd(rp->renamed[i], i);
4959                         }
4960                         close(rp->renamed[i]);
4961                 }
4962         }
4963         redirlist = rp->next;
4964         g_nullredirs = rp->nullredirs;
4965         free(rp);
4966         INT_ON;
4967 }
4968
4969 /*
4970  * Undo all redirections.  Called on error or interrupt.
4971  */
4972
4973 /*
4974  * Discard all saved file descriptors.
4975  */
4976 static void
4977 clearredir(int drop)
4978 {
4979         for (;;) {
4980                 g_nullredirs = 0;
4981                 if (!redirlist)
4982                         break;
4983                 popredir(drop);
4984         }
4985 }
4986
4987 static int
4988 redirectsafe(union node *redir, int flags)
4989 {
4990         int err;
4991         volatile int saveint;
4992         struct jmploc *volatile savehandler = exception_handler;
4993         struct jmploc jmploc;
4994
4995         SAVE_INT(saveint);
4996         err = setjmp(jmploc.loc) * 2;
4997         if (!err) {
4998                 exception_handler = &jmploc;
4999                 redirect(redir, flags);
5000         }
5001         exception_handler = savehandler;
5002         if (err && exception != EXERROR)
5003                 longjmp(exception_handler->loc, 1);
5004         RESTORE_INT(saveint);
5005         return err;
5006 }
5007
5008
5009 /* ============ Routines to expand arguments to commands
5010  *
5011  * We have to deal with backquotes, shell variables, and file metacharacters.
5012  */
5013
5014 /*
5015  * expandarg flags
5016  */
5017 #define EXP_FULL        0x1     /* perform word splitting & file globbing */
5018 #define EXP_TILDE       0x2     /* do normal tilde expansion */
5019 #define EXP_VARTILDE    0x4     /* expand tildes in an assignment */
5020 #define EXP_REDIR       0x8     /* file glob for a redirection (1 match only) */
5021 #define EXP_CASE        0x10    /* keeps quotes around for CASE pattern */
5022 #define EXP_RECORD      0x20    /* need to record arguments for ifs breakup */
5023 #define EXP_VARTILDE2   0x40    /* expand tildes after colons only */
5024 #define EXP_WORD        0x80    /* expand word in parameter expansion */
5025 #define EXP_QWORD       0x100   /* expand word in quoted parameter expansion */
5026 /*
5027  * _rmescape() flags
5028  */
5029 #define RMESCAPE_ALLOC  0x1     /* Allocate a new string */
5030 #define RMESCAPE_GLOB   0x2     /* Add backslashes for glob */
5031 #define RMESCAPE_QUOTED 0x4     /* Remove CTLESC unless in quotes */
5032 #define RMESCAPE_GROW   0x8     /* Grow strings instead of stalloc */
5033 #define RMESCAPE_HEAP   0x10    /* Malloc strings instead of stalloc */
5034
5035 /*
5036  * Structure specifying which parts of the string should be searched
5037  * for IFS characters.
5038  */
5039 struct ifsregion {
5040         struct ifsregion *next; /* next region in list */
5041         int begoff;             /* offset of start of region */
5042         int endoff;             /* offset of end of region */
5043         int nulonly;            /* search for nul bytes only */
5044 };
5045
5046 struct arglist {
5047         struct strlist *list;
5048         struct strlist **lastp;
5049 };
5050
5051 /* output of current string */
5052 static char *expdest;
5053 /* list of back quote expressions */
5054 static struct nodelist *argbackq;
5055 /* first struct in list of ifs regions */
5056 static struct ifsregion ifsfirst;
5057 /* last struct in list */
5058 static struct ifsregion *ifslastp;
5059 /* holds expanded arg list */
5060 static struct arglist exparg;
5061
5062 /*
5063  * Our own itoa().
5064  */
5065 static int
5066 cvtnum(arith_t num)
5067 {
5068         int len;
5069
5070         expdest = makestrspace(32, expdest);
5071 #if ENABLE_ASH_MATH_SUPPORT_64
5072         len = fmtstr(expdest, 32, "%lld", (long long) num);
5073 #else
5074         len = fmtstr(expdest, 32, "%ld", num);
5075 #endif
5076         STADJUST(len, expdest);
5077         return len;
5078 }
5079
5080 static size_t
5081 esclen(const char *start, const char *p)
5082 {
5083         size_t esc = 0;
5084
5085         while (p > start && *--p == CTLESC) {
5086                 esc++;
5087         }
5088         return esc;
5089 }
5090
5091 /*
5092  * Remove any CTLESC characters from a string.
5093  */
5094 static char *
5095 _rmescapes(char *str, int flag)
5096 {
5097         static const char qchars[] ALIGN1 = { CTLESC, CTLQUOTEMARK, '\0' };
5098
5099         char *p, *q, *r;
5100         unsigned inquotes;
5101         int notescaped;
5102         int globbing;
5103
5104         p = strpbrk(str, qchars);
5105         if (!p) {
5106                 return str;
5107         }
5108         q = p;
5109         r = str;
5110         if (flag & RMESCAPE_ALLOC) {
5111                 size_t len = p - str;
5112                 size_t fulllen = len + strlen(p) + 1;
5113
5114                 if (flag & RMESCAPE_GROW) {
5115                         r = makestrspace(fulllen, expdest);
5116                 } else if (flag & RMESCAPE_HEAP) {
5117                         r = ckmalloc(fulllen);
5118                 } else {
5119                         r = stalloc(fulllen);
5120                 }
5121                 q = r;
5122                 if (len > 0) {
5123                         q = memcpy(q, str, len) + len;
5124                 }
5125         }
5126         inquotes = (flag & RMESCAPE_QUOTED) ^ RMESCAPE_QUOTED;
5127         globbing = flag & RMESCAPE_GLOB;
5128         notescaped = globbing;
5129         while (*p) {
5130                 if (*p == CTLQUOTEMARK) {
5131                         inquotes = ~inquotes;
5132                         p++;
5133                         notescaped = globbing;
5134                         continue;
5135                 }
5136                 if (*p == '\\') {
5137                         /* naked back slash */
5138                         notescaped = 0;
5139                         goto copy;
5140                 }
5141                 if (*p == CTLESC) {
5142                         p++;
5143                         if (notescaped && inquotes && *p != '/') {
5144                                 *q++ = '\\';
5145                         }
5146                 }
5147                 notescaped = globbing;
5148  copy:
5149                 *q++ = *p++;
5150         }
5151         *q = '\0';
5152         if (flag & RMESCAPE_GROW) {
5153                 expdest = r;
5154                 STADJUST(q - r + 1, expdest);
5155         }
5156         return r;
5157 }
5158 #define rmescapes(p) _rmescapes((p), 0)
5159
5160 #define pmatch(a, b) !fnmatch((a), (b), 0)
5161
5162 /*
5163  * Prepare a pattern for a expmeta (internal glob(3)) call.
5164  *
5165  * Returns an stalloced string.
5166  */
5167 static char *
5168 preglob(const char *pattern, int quoted, int flag)
5169 {
5170         flag |= RMESCAPE_GLOB;
5171         if (quoted) {
5172                 flag |= RMESCAPE_QUOTED;
5173         }
5174         return _rmescapes((char *)pattern, flag);
5175 }
5176
5177 /*
5178  * Put a string on the stack.
5179  */
5180 static void
5181 memtodest(const char *p, size_t len, int syntax, int quotes)
5182 {
5183         char *q = expdest;
5184
5185         q = makestrspace(len * 2, q);
5186
5187         while (len--) {
5188                 int c = signed_char2int(*p++);
5189                 if (!c)
5190                         continue;
5191                 if (quotes && (SIT(c, syntax) == CCTL || SIT(c, syntax) == CBACK))
5192                         USTPUTC(CTLESC, q);
5193                 USTPUTC(c, q);
5194         }
5195
5196         expdest = q;
5197 }
5198
5199 static void
5200 strtodest(const char *p, int syntax, int quotes)
5201 {
5202         memtodest(p, strlen(p), syntax, quotes);
5203 }
5204
5205 /*
5206  * Record the fact that we have to scan this region of the
5207  * string for IFS characters.
5208  */
5209 static void
5210 recordregion(int start, int end, int nulonly)
5211 {
5212         struct ifsregion *ifsp;
5213
5214         if (ifslastp == NULL) {
5215                 ifsp = &ifsfirst;
5216         } else {
5217                 INT_OFF;
5218                 ifsp = ckmalloc(sizeof(*ifsp));
5219                 ifsp->next = NULL;
5220                 ifslastp->next = ifsp;
5221                 INT_ON;
5222         }
5223         ifslastp = ifsp;
5224         ifslastp->begoff = start;
5225         ifslastp->endoff = end;
5226         ifslastp->nulonly = nulonly;
5227 }
5228
5229 static void
5230 removerecordregions(int endoff)
5231 {
5232         if (ifslastp == NULL)
5233                 return;
5234
5235         if (ifsfirst.endoff > endoff) {
5236                 while (ifsfirst.next != NULL) {
5237                         struct ifsregion *ifsp;
5238                         INT_OFF;
5239                         ifsp = ifsfirst.next->next;
5240                         free(ifsfirst.next);
5241                         ifsfirst.next = ifsp;
5242                         INT_ON;
5243                 }
5244                 if (ifsfirst.begoff > endoff)
5245                         ifslastp = NULL;
5246                 else {
5247                         ifslastp = &ifsfirst;
5248                         ifsfirst.endoff = endoff;
5249                 }
5250                 return;
5251         }
5252
5253         ifslastp = &ifsfirst;
5254         while (ifslastp->next && ifslastp->next->begoff < endoff)
5255                 ifslastp=ifslastp->next;
5256         while (ifslastp->next != NULL) {
5257                 struct ifsregion *ifsp;
5258                 INT_OFF;
5259                 ifsp = ifslastp->next->next;
5260                 free(ifslastp->next);
5261                 ifslastp->next = ifsp;
5262                 INT_ON;
5263         }
5264         if (ifslastp->endoff > endoff)
5265                 ifslastp->endoff = endoff;
5266 }
5267
5268 static char *
5269 exptilde(char *startp, char *p, int flag)
5270 {
5271         char c;
5272         char *name;
5273         struct passwd *pw;
5274         const char *home;
5275         int quotes = flag & (EXP_FULL | EXP_CASE);
5276         int startloc;
5277
5278         name = p + 1;
5279
5280         while ((c = *++p) != '\0') {
5281                 switch (c) {
5282                 case CTLESC:
5283                         return startp;
5284                 case CTLQUOTEMARK:
5285                         return startp;
5286                 case ':':
5287                         if (flag & EXP_VARTILDE)
5288                                 goto done;
5289                         break;
5290                 case '/':
5291                 case CTLENDVAR:
5292                         goto done;
5293                 }
5294         }
5295  done:
5296         *p = '\0';
5297         if (*name == '\0') {
5298                 home = lookupvar(homestr);
5299         } else {
5300                 pw = getpwnam(name);
5301                 if (pw == NULL)
5302                         goto lose;
5303                 home = pw->pw_dir;
5304         }
5305         if (!home || !*home)
5306                 goto lose;
5307         *p = c;
5308         startloc = expdest - (char *)stackblock();
5309         strtodest(home, SQSYNTAX, quotes);
5310         recordregion(startloc, expdest - (char *)stackblock(), 0);
5311         return p;
5312  lose:
5313         *p = c;
5314         return startp;
5315 }
5316
5317 /*
5318  * Execute a command inside back quotes.  If it's a builtin command, we
5319  * want to save its output in a block obtained from malloc.  Otherwise
5320  * we fork off a subprocess and get the output of the command via a pipe.
5321  * Should be called with interrupts off.
5322  */
5323 struct backcmd {                /* result of evalbackcmd */
5324         int fd;                 /* file descriptor to read from */
5325         char *buf;              /* buffer */
5326         int nleft;              /* number of chars in buffer */
5327         struct job *jp;         /* job structure for command */
5328 };
5329
5330 /* These forward decls are needed to use "eval" code for backticks handling: */
5331 static int back_exitstatus; /* exit status of backquoted command */
5332 #define EV_EXIT 01              /* exit after evaluating tree */
5333 static void evaltree(union node *, int);
5334
5335 static void
5336 evalbackcmd(union node *n, struct backcmd *result)
5337 {
5338         int saveherefd;
5339
5340         result->fd = -1;
5341         result->buf = NULL;
5342         result->nleft = 0;
5343         result->jp = NULL;
5344         if (n == NULL) {
5345                 goto out;
5346         }
5347
5348         saveherefd = herefd;
5349         herefd = -1;
5350
5351         {
5352                 int pip[2];
5353                 struct job *jp;
5354
5355                 if (pipe(pip) < 0)
5356                         ash_msg_and_raise_error("pipe call failed");
5357                 jp = makejob(n, 1);
5358                 if (forkshell(jp, n, FORK_NOJOB) == 0) {
5359                         FORCE_INT_ON;
5360                         close(pip[0]);
5361                         if (pip[1] != 1) {
5362                                 close(1);
5363                                 copyfd(pip[1], 1);
5364                                 close(pip[1]);
5365                         }
5366                         eflag = 0;
5367                         evaltree(n, EV_EXIT); /* actually evaltreenr... */
5368                         /* NOTREACHED */
5369                 }
5370                 close(pip[1]);
5371                 result->fd = pip[0];
5372                 result->jp = jp;
5373         }
5374         herefd = saveherefd;
5375  out:
5376         TRACE(("evalbackcmd done: fd=%d buf=0x%x nleft=%d jp=0x%x\n",
5377                 result->fd, result->buf, result->nleft, result->jp));
5378 }
5379
5380 /*
5381  * Expand stuff in backwards quotes.
5382  */
5383 static void
5384 expbackq(union node *cmd, int quoted, int quotes)
5385 {
5386         struct backcmd in;
5387         int i;
5388         char buf[128];
5389         char *p;
5390         char *dest;
5391         int startloc;
5392         int syntax = quoted? DQSYNTAX : BASESYNTAX;
5393         struct stackmark smark;
5394
5395         INT_OFF;
5396         setstackmark(&smark);
5397         dest = expdest;
5398         startloc = dest - (char *)stackblock();
5399         grabstackstr(dest);
5400         evalbackcmd(cmd, &in);
5401         popstackmark(&smark);
5402
5403         p = in.buf;
5404         i = in.nleft;
5405         if (i == 0)
5406                 goto read;
5407         for (;;) {
5408                 memtodest(p, i, syntax, quotes);
5409  read:
5410                 if (in.fd < 0)
5411                         break;
5412                 i = safe_read(in.fd, buf, sizeof(buf));
5413                 TRACE(("expbackq: read returns %d\n", i));
5414                 if (i <= 0)
5415                         break;
5416                 p = buf;
5417         }
5418
5419         free(in.buf);
5420         if (in.fd >= 0) {
5421                 close(in.fd);
5422                 back_exitstatus = waitforjob(in.jp);
5423         }
5424         INT_ON;
5425
5426         /* Eat all trailing newlines */
5427         dest = expdest;
5428         for (; dest > (char *)stackblock() && dest[-1] == '\n';)
5429                 STUNPUTC(dest);
5430         expdest = dest;
5431
5432         if (quoted == 0)
5433                 recordregion(startloc, dest - (char *)stackblock(), 0);
5434         TRACE(("evalbackq: size=%d: \"%.*s\"\n",
5435                 (dest - (char *)stackblock()) - startloc,
5436                 (dest - (char *)stackblock()) - startloc,
5437                 stackblock() + startloc));
5438 }
5439
5440 #if ENABLE_ASH_MATH_SUPPORT
5441 /*
5442  * Expand arithmetic expression.  Backup to start of expression,
5443  * evaluate, place result in (backed up) result, adjust string position.
5444  */
5445 static void
5446 expari(int quotes)
5447 {
5448         char *p, *start;
5449         int begoff;
5450         int flag;
5451         int len;
5452
5453         /*      ifsfree(); */
5454
5455         /*
5456          * This routine is slightly over-complicated for
5457          * efficiency.  Next we scan backwards looking for the
5458          * start of arithmetic.
5459          */
5460         start = stackblock();
5461         p = expdest - 1;
5462         *p = '\0';
5463         p--;
5464         do {
5465                 int esc;
5466
5467                 while (*p != CTLARI) {
5468                         p--;
5469 #if DEBUG
5470                         if (p < start) {
5471                                 ash_msg_and_raise_error("missing CTLARI (shouldn't happen)");
5472                         }
5473 #endif
5474                 }
5475
5476                 esc = esclen(start, p);
5477                 if (!(esc % 2)) {
5478                         break;
5479                 }
5480
5481                 p -= esc + 1;
5482         } while (1);
5483
5484         begoff = p - start;
5485
5486         removerecordregions(begoff);
5487
5488         flag = p[1];
5489
5490         expdest = p;
5491
5492         if (quotes)
5493                 rmescapes(p + 2);
5494
5495         len = cvtnum(dash_arith(p + 2));
5496
5497         if (flag != '"')
5498                 recordregion(begoff, begoff + len, 0);
5499 }
5500 #endif
5501
5502 /* argstr needs it */
5503 static char *evalvar(char *p, int flag, struct strlist *var_str_list);
5504
5505 /*
5506  * Perform variable and command substitution.  If EXP_FULL is set, output CTLESC
5507  * characters to allow for further processing.  Otherwise treat
5508  * $@ like $* since no splitting will be performed.
5509  *
5510  * var_str_list (can be NULL) is a list of "VAR=val" strings which take precedence
5511  * over shell varables. Needed for "A=a B=$A; echo $B" case - we use it
5512  * for correct expansion of "B=$A" word.
5513  */
5514 static void
5515 argstr(char *p, int flag, struct strlist *var_str_list)
5516 {
5517         static const char spclchars[] ALIGN1 = {
5518                 '=',
5519                 ':',
5520                 CTLQUOTEMARK,
5521                 CTLENDVAR,
5522                 CTLESC,
5523                 CTLVAR,
5524                 CTLBACKQ,
5525                 CTLBACKQ | CTLQUOTE,
5526 #if ENABLE_ASH_MATH_SUPPORT
5527                 CTLENDARI,
5528 #endif
5529                 0
5530         };
5531         const char *reject = spclchars;
5532         int c;
5533         int quotes = flag & (EXP_FULL | EXP_CASE);      /* do CTLESC */
5534         int breakall = flag & EXP_WORD;
5535         int inquotes;
5536         size_t length;
5537         int startloc;
5538
5539         if (!(flag & EXP_VARTILDE)) {
5540                 reject += 2;
5541         } else if (flag & EXP_VARTILDE2) {
5542                 reject++;
5543         }
5544         inquotes = 0;
5545         length = 0;
5546         if (flag & EXP_TILDE) {
5547                 char *q;
5548
5549                 flag &= ~EXP_TILDE;
5550  tilde:
5551                 q = p;
5552                 if (*q == CTLESC && (flag & EXP_QWORD))
5553                         q++;
5554                 if (*q == '~')
5555                         p = exptilde(p, q, flag);
5556         }
5557  start:
5558         startloc = expdest - (char *)stackblock();
5559         for (;;) {
5560                 length += strcspn(p + length, reject);
5561                 c = p[length];
5562                 if (c && (!(c & 0x80)
5563 #if ENABLE_ASH_MATH_SUPPORT
5564                                         || c == CTLENDARI
5565 #endif
5566                    )) {
5567                         /* c == '=' || c == ':' || c == CTLENDARI */
5568                         length++;
5569                 }
5570                 if (length > 0) {
5571                         int newloc;
5572                         expdest = stack_nputstr(p, length, expdest);
5573                         newloc = expdest - (char *)stackblock();
5574                         if (breakall && !inquotes && newloc > startloc) {
5575                                 recordregion(startloc, newloc, 0);
5576                         }
5577                         startloc = newloc;
5578                 }
5579                 p += length + 1;
5580                 length = 0;
5581
5582                 switch (c) {
5583                 case '\0':
5584                         goto breakloop;
5585                 case '=':
5586                         if (flag & EXP_VARTILDE2) {
5587                                 p--;
5588                                 continue;
5589                         }
5590                         flag |= EXP_VARTILDE2;
5591                         reject++;
5592                         /* fall through */
5593                 case ':':
5594                         /*
5595                          * sort of a hack - expand tildes in variable
5596                          * assignments (after the first '=' and after ':'s).
5597                          */
5598                         if (*--p == '~') {
5599                                 goto tilde;
5600                         }
5601                         continue;
5602                 }
5603
5604                 switch (c) {
5605                 case CTLENDVAR: /* ??? */
5606                         goto breakloop;
5607                 case CTLQUOTEMARK:
5608                         /* "$@" syntax adherence hack */
5609                         if (
5610                                 !inquotes &&
5611                                 !memcmp(p, dolatstr, 4) &&
5612                                 (p[4] == CTLQUOTEMARK || (
5613                                         p[4] == CTLENDVAR &&
5614                                         p[5] == CTLQUOTEMARK
5615                                 ))
5616                         ) {
5617                                 p = evalvar(p + 1, flag, /* var_str_list: */ NULL) + 1;
5618                                 goto start;
5619                         }
5620                         inquotes = !inquotes;
5621  addquote:
5622                         if (quotes) {
5623                                 p--;
5624                                 length++;
5625                                 startloc++;
5626                         }
5627                         break;
5628                 case CTLESC:
5629                         startloc++;
5630                         length++;
5631                         goto addquote;
5632                 case CTLVAR:
5633                         p = evalvar(p, flag, var_str_list);
5634                         goto start;
5635                 case CTLBACKQ:
5636                         c = 0;
5637                 case CTLBACKQ|CTLQUOTE:
5638                         expbackq(argbackq->n, c, quotes);
5639                         argbackq = argbackq->next;
5640                         goto start;
5641 #if ENABLE_ASH_MATH_SUPPORT
5642                 case CTLENDARI:
5643                         p--;
5644                         expari(quotes);
5645                         goto start;
5646 #endif
5647                 }
5648         }
5649  breakloop:
5650         ;
5651 }
5652
5653 static char *
5654 scanleft(char *startp, char *rmesc, char *rmescend, char *str, int quotes,
5655         int zero)
5656 {
5657         char *loc;
5658         char *loc2;
5659         char c;
5660
5661         loc = startp;
5662         loc2 = rmesc;
5663         do {
5664                 int match;
5665                 const char *s = loc2;
5666                 c = *loc2;
5667                 if (zero) {
5668                         *loc2 = '\0';
5669                         s = rmesc;
5670                 }
5671                 match = pmatch(str, s);
5672                 *loc2 = c;
5673                 if (match)
5674                         return loc;
5675                 if (quotes && *loc == CTLESC)
5676                         loc++;
5677                 loc++;
5678                 loc2++;
5679         } while (c);
5680         return 0;
5681 }
5682
5683 static char *
5684 scanright(char *startp, char *rmesc, char *rmescend, char *str, int quotes,
5685         int zero)
5686 {
5687         int esc = 0;
5688         char *loc;
5689         char *loc2;
5690
5691         for (loc = str - 1, loc2 = rmescend; loc >= startp; loc2--) {
5692                 int match;
5693                 char c = *loc2;
5694                 const char *s = loc2;
5695                 if (zero) {
5696                         *loc2 = '\0';
5697                         s = rmesc;
5698                 }
5699                 match = pmatch(str, s);
5700                 *loc2 = c;
5701                 if (match)
5702                         return loc;
5703                 loc--;
5704                 if (quotes) {
5705                         if (--esc < 0) {
5706                                 esc = esclen(startp, loc);
5707                         }
5708                         if (esc % 2) {
5709                                 esc--;
5710                                 loc--;
5711                         }
5712                 }
5713         }
5714         return 0;
5715 }
5716
5717 static void varunset(const char *, const char *, const char *, int) ATTRIBUTE_NORETURN;
5718 static void
5719 varunset(const char *end, const char *var, const char *umsg, int varflags)
5720 {
5721         const char *msg;
5722         const char *tail;
5723
5724         tail = nullstr;
5725         msg = "parameter not set";
5726         if (umsg) {
5727                 if (*end == CTLENDVAR) {
5728                         if (varflags & VSNUL)
5729                                 tail = " or null";
5730                 } else
5731                         msg = umsg;
5732         }
5733         ash_msg_and_raise_error("%.*s: %s%s", end - var - 1, var, msg, tail);
5734 }
5735
5736 static const char *
5737 subevalvar(char *p, char *str, int strloc, int subtype,
5738                 int startloc, int varflags, int quotes, struct strlist *var_str_list)
5739 {
5740         char *startp;
5741         char *loc;
5742         int saveherefd = herefd;
5743         struct nodelist *saveargbackq = argbackq;
5744         int amount;
5745         char *rmesc, *rmescend;
5746         int zero;
5747         char *(*scan)(char *, char *, char *, char *, int , int);
5748
5749         herefd = -1;
5750         argstr(p, (subtype != VSASSIGN && subtype != VSQUESTION) ? EXP_CASE : 0,
5751                         var_str_list);
5752         STPUTC('\0', expdest);
5753         herefd = saveherefd;
5754         argbackq = saveargbackq;
5755         startp = stackblock() + startloc;
5756
5757         switch (subtype) {
5758         case VSASSIGN:
5759                 setvar(str, startp, 0);
5760                 amount = startp - expdest;
5761                 STADJUST(amount, expdest);
5762                 return startp;
5763
5764         case VSQUESTION:
5765                 varunset(p, str, startp, varflags);
5766                 /* NOTREACHED */
5767         }
5768
5769         subtype -= VSTRIMRIGHT;
5770 #if DEBUG
5771         if (subtype < 0 || subtype > 3)
5772                 abort();
5773 #endif
5774
5775         rmesc = startp;
5776         rmescend = stackblock() + strloc;
5777         if (quotes) {
5778                 rmesc = _rmescapes(startp, RMESCAPE_ALLOC | RMESCAPE_GROW);
5779                 if (rmesc != startp) {
5780                         rmescend = expdest;
5781                         startp = stackblock() + startloc;
5782                 }
5783         }
5784         rmescend--;
5785         str = stackblock() + strloc;
5786         preglob(str, varflags & VSQUOTE, 0);
5787
5788         /* zero = subtype == VSTRIMLEFT || subtype == VSTRIMLEFTMAX */
5789         zero = subtype >> 1;
5790         /* VSTRIMLEFT/VSTRIMRIGHTMAX -> scanleft */
5791         scan = (subtype & 1) ^ zero ? scanleft : scanright;
5792
5793         loc = scan(startp, rmesc, rmescend, str, quotes, zero);
5794         if (loc) {
5795                 if (zero) {
5796                         memmove(startp, loc, str - loc);
5797                         loc = startp + (str - loc) - 1;
5798                 }
5799                 *loc = '\0';
5800                 amount = loc - expdest;
5801                 STADJUST(amount, expdest);
5802         }
5803         return loc;
5804 }
5805
5806 /*
5807  * Add the value of a specialized variable to the stack string.
5808  */
5809 static ssize_t
5810 varvalue(char *name, int varflags, int flags, struct strlist *var_str_list)
5811 {
5812         int num;
5813         char *p;
5814         int i;
5815         int sep = 0;
5816         int sepq = 0;
5817         ssize_t len = 0;
5818         char **ap;
5819         int syntax;
5820         int quoted = varflags & VSQUOTE;
5821         int subtype = varflags & VSTYPE;
5822         int quotes = flags & (EXP_FULL | EXP_CASE);
5823
5824         if (quoted && (flags & EXP_FULL))
5825                 sep = 1 << CHAR_BIT;
5826
5827         syntax = quoted ? DQSYNTAX : BASESYNTAX;
5828         switch (*name) {
5829         case '$':
5830                 num = rootpid;
5831                 goto numvar;
5832         case '?':
5833                 num = exitstatus;
5834                 goto numvar;
5835         case '#':
5836                 num = shellparam.nparam;
5837                 goto numvar;
5838         case '!':
5839                 num = backgndpid;
5840                 if (num == 0)
5841                         return -1;
5842  numvar:
5843                 len = cvtnum(num);
5844                 break;
5845         case '-':
5846                 p = makestrspace(NOPTS, expdest);
5847                 for (i = NOPTS - 1; i >= 0; i--) {
5848                         if (optlist[i]) {
5849                                 USTPUTC(optletters(i), p);
5850                                 len++;
5851                         }
5852                 }
5853                 expdest = p;
5854                 break;
5855         case '@':
5856                 if (sep)
5857                         goto param;
5858                 /* fall through */
5859         case '*':
5860                 sep = ifsset() ? signed_char2int(ifsval()[0]) : ' ';
5861                 if (quotes && (SIT(sep, syntax) == CCTL || SIT(sep, syntax) == CBACK))
5862                         sepq = 1;
5863  param:
5864                 ap = shellparam.p;
5865                 if (!ap)
5866                         return -1;
5867                 while ((p = *ap++)) {
5868                         size_t partlen;
5869
5870                         partlen = strlen(p);
5871                         len += partlen;
5872
5873                         if (!(subtype == VSPLUS || subtype == VSLENGTH))
5874                                 memtodest(p, partlen, syntax, quotes);
5875
5876                         if (*ap && sep) {
5877                                 char *q;
5878
5879                                 len++;
5880                                 if (subtype == VSPLUS || subtype == VSLENGTH) {
5881                                         continue;
5882                                 }
5883                                 q = expdest;
5884                                 if (sepq)
5885                                         STPUTC(CTLESC, q);
5886                                 STPUTC(sep, q);
5887                                 expdest = q;
5888                         }
5889                 }
5890                 return len;
5891         case '0':
5892         case '1':
5893         case '2':
5894         case '3':
5895         case '4':
5896         case '5':
5897         case '6':
5898         case '7':
5899         case '8':
5900         case '9':
5901                 num = atoi(name);
5902                 if (num < 0 || num > shellparam.nparam)
5903                         return -1;
5904                 p = num ? shellparam.p[num - 1] : arg0;
5905                 goto value;
5906         default:
5907                 /* NB: name has form "VAR=..." */
5908
5909                 /* "A=a B=$A" case: var_str_list is a list of "A=a" strings
5910                  * which should be considered before we check variables. */
5911                 if (var_str_list) {
5912                         unsigned name_len = (strchrnul(name, '=') - name) + 1;
5913                         p = NULL;
5914                         do {
5915                                 char *str = var_str_list->text;
5916                                 char *eq = strchr(str, '=');
5917                                 if (!eq) /* stop at first non-assignment */
5918                                         break;
5919                                 eq++;
5920                                 if (name_len == (eq - str)
5921                                  && strncmp(str, name, name_len) == 0) {
5922                                         p = eq;
5923                                         /* goto value; - WRONG! */
5924                                         /* think "A=1 A=2 B=$A" */
5925                                 }
5926                                 var_str_list = var_str_list->next;
5927                         } while (var_str_list);
5928                         if (p)
5929                                 goto value;
5930                 }
5931                 p = lookupvar(name);
5932  value:
5933                 if (!p)
5934                         return -1;
5935
5936                 len = strlen(p);
5937                 if (!(subtype == VSPLUS || subtype == VSLENGTH))
5938                         memtodest(p, len, syntax, quotes);
5939                 return len;
5940         }
5941
5942         if (subtype == VSPLUS || subtype == VSLENGTH)
5943                 STADJUST(-len, expdest);
5944         return len;
5945 }
5946
5947 /*
5948  * Expand a variable, and return a pointer to the next character in the
5949  * input string.
5950  */
5951 static char *
5952 evalvar(char *p, int flag, struct strlist *var_str_list)
5953 {
5954         char varflags;
5955         char subtype;
5956         char quoted;
5957         char easy;
5958         char *var;
5959         int patloc;
5960         int startloc;
5961         ssize_t varlen;
5962
5963         varflags = *p++;
5964         subtype = varflags & VSTYPE;
5965         quoted = varflags & VSQUOTE;
5966         var = p;
5967         easy = (!quoted || (*var == '@' && shellparam.nparam));
5968         startloc = expdest - (char *)stackblock();
5969         p = strchr(p, '=') + 1;
5970
5971  again:
5972         varlen = varvalue(var, varflags, flag, var_str_list);
5973         if (varflags & VSNUL)
5974                 varlen--;
5975
5976         if (subtype == VSPLUS) {
5977                 varlen = -1 - varlen;
5978                 goto vsplus;
5979         }
5980
5981         if (subtype == VSMINUS) {
5982  vsplus:
5983                 if (varlen < 0) {
5984                         argstr(
5985                                 p, flag | EXP_TILDE |
5986                                         (quoted ?  EXP_QWORD : EXP_WORD),
5987                                 var_str_list
5988                         );
5989                         goto end;
5990                 }
5991                 if (easy)
5992                         goto record;
5993                 goto end;
5994         }
5995
5996         if (subtype == VSASSIGN || subtype == VSQUESTION) {
5997                 if (varlen < 0) {
5998                         if (subevalvar(p, var, /* strloc: */ 0,
5999                                         subtype, startloc, varflags,
6000                                         /* quotes: */ 0,
6001                                         var_str_list)
6002                         ) {
6003                                 varflags &= ~VSNUL;
6004                                 /*
6005                                  * Remove any recorded regions beyond
6006                                  * start of variable
6007                                  */
6008                                 removerecordregions(startloc);
6009                                 goto again;
6010                         }
6011                         goto end;
6012                 }
6013                 if (easy)
6014                         goto record;
6015                 goto end;
6016         }
6017
6018         if (varlen < 0 && uflag)
6019                 varunset(p, var, 0, 0);
6020
6021         if (subtype == VSLENGTH) {
6022                 cvtnum(varlen > 0 ? varlen : 0);
6023                 goto record;
6024         }
6025
6026         if (subtype == VSNORMAL) {
6027                 if (easy)
6028                         goto record;
6029                 goto end;
6030         }
6031
6032 #if DEBUG
6033         switch (subtype) {
6034         case VSTRIMLEFT:
6035         case VSTRIMLEFTMAX:
6036         case VSTRIMRIGHT:
6037         case VSTRIMRIGHTMAX:
6038                 break;
6039         default:
6040                 abort();
6041         }
6042 #endif
6043
6044         if (varlen >= 0) {
6045                 /*
6046                  * Terminate the string and start recording the pattern
6047                  * right after it
6048                  */
6049                 STPUTC('\0', expdest);
6050                 patloc = expdest - (char *)stackblock();
6051                 if (0 == subevalvar(p, /* str: */ NULL, patloc, subtype,
6052                                 startloc, varflags,
6053                                 /* quotes: */ flag & (EXP_FULL | EXP_CASE),
6054                                 var_str_list)
6055                 ) {
6056                         int amount = expdest - (
6057                                 (char *)stackblock() + patloc - 1
6058                         );
6059                         STADJUST(-amount, expdest);
6060                 }
6061                 /* Remove any recorded regions beyond start of variable */
6062                 removerecordregions(startloc);
6063  record:
6064                 recordregion(startloc, expdest - (char *)stackblock(), quoted);
6065         }
6066
6067  end:
6068         if (subtype != VSNORMAL) {      /* skip to end of alternative */
6069                 int nesting = 1;
6070                 for (;;) {
6071                         char c = *p++;
6072                         if (c == CTLESC)
6073                                 p++;
6074                         else if (c == CTLBACKQ || c == (CTLBACKQ|CTLQUOTE)) {
6075                                 if (varlen >= 0)
6076                                         argbackq = argbackq->next;
6077                         } else if (c == CTLVAR) {
6078                                 if ((*p++ & VSTYPE) != VSNORMAL)
6079                                         nesting++;
6080                         } else if (c == CTLENDVAR) {
6081                                 if (--nesting == 0)
6082                                         break;
6083                         }
6084                 }
6085         }
6086         return p;
6087 }
6088
6089 /*
6090  * Break the argument string into pieces based upon IFS and add the
6091  * strings to the argument list.  The regions of the string to be
6092  * searched for IFS characters have been stored by recordregion.
6093  */
6094 static void
6095 ifsbreakup(char *string, struct arglist *arglist)
6096 {
6097         struct ifsregion *ifsp;
6098         struct strlist *sp;
6099         char *start;
6100         char *p;
6101         char *q;
6102         const char *ifs, *realifs;
6103         int ifsspc;
6104         int nulonly;
6105
6106         start = string;
6107         if (ifslastp != NULL) {
6108                 ifsspc = 0;
6109                 nulonly = 0;
6110                 realifs = ifsset() ? ifsval() : defifs;
6111                 ifsp = &ifsfirst;
6112                 do {
6113                         p = string + ifsp->begoff;
6114                         nulonly = ifsp->nulonly;
6115                         ifs = nulonly ? nullstr : realifs;
6116                         ifsspc = 0;
6117                         while (p < string + ifsp->endoff) {
6118                                 q = p;
6119                                 if (*p == CTLESC)
6120                                         p++;
6121                                 if (!strchr(ifs, *p)) {
6122                                         p++;
6123                                         continue;
6124                                 }
6125                                 if (!nulonly)
6126                                         ifsspc = (strchr(defifs, *p) != NULL);
6127                                 /* Ignore IFS whitespace at start */
6128                                 if (q == start && ifsspc) {
6129                                         p++;
6130                                         start = p;
6131                                         continue;
6132                                 }
6133                                 *q = '\0';
6134                                 sp = stalloc(sizeof(*sp));
6135                                 sp->text = start;
6136                                 *arglist->lastp = sp;
6137                                 arglist->lastp = &sp->next;
6138                                 p++;
6139                                 if (!nulonly) {
6140                                         for (;;) {
6141                                                 if (p >= string + ifsp->endoff) {
6142                                                         break;
6143                                                 }
6144                                                 q = p;
6145                                                 if (*p == CTLESC)
6146                                                         p++;
6147                                                 if (strchr(ifs, *p) == NULL ) {
6148                                                         p = q;
6149                                                         break;
6150                                                 } else if (strchr(defifs, *p) == NULL) {
6151                                                         if (ifsspc) {
6152                                                                 p++;
6153                                                                 ifsspc = 0;
6154                                                         } else {
6155                                                                 p = q;
6156                                                                 break;
6157                                                         }
6158                                                 } else
6159                                                         p++;
6160                                         }
6161                                 }
6162                                 start = p;
6163                         } /* while */
6164                         ifsp = ifsp->next;
6165                 } while (ifsp != NULL);
6166                 if (nulonly)
6167                         goto add;
6168         }
6169
6170         if (!*start)
6171                 return;
6172
6173  add:
6174         sp = stalloc(sizeof(*sp));
6175         sp->text = start;
6176         *arglist->lastp = sp;
6177         arglist->lastp = &sp->next;
6178 }
6179
6180 static void
6181 ifsfree(void)
6182 {
6183         struct ifsregion *p;
6184
6185         INT_OFF;
6186         p = ifsfirst.next;
6187         do {
6188                 struct ifsregion *ifsp;
6189                 ifsp = p->next;
6190                 free(p);
6191                 p = ifsp;
6192         } while (p);
6193         ifslastp = NULL;
6194         ifsfirst.next = NULL;
6195         INT_ON;
6196 }
6197
6198 /*
6199  * Add a file name to the list.
6200  */
6201 static void
6202 addfname(const char *name)
6203 {
6204         struct strlist *sp;
6205
6206         sp = stalloc(sizeof(*sp));
6207         sp->text = ststrdup(name);
6208         *exparg.lastp = sp;
6209         exparg.lastp = &sp->next;
6210 }
6211
6212 static char *expdir;
6213
6214 /*
6215  * Do metacharacter (i.e. *, ?, [...]) expansion.
6216  */
6217 static void
6218 expmeta(char *enddir, char *name)
6219 {
6220         char *p;
6221         const char *cp;
6222         char *start;
6223         char *endname;
6224         int metaflag;
6225         struct stat statb;
6226         DIR *dirp;
6227         struct dirent *dp;
6228         int atend;
6229         int matchdot;
6230
6231         metaflag = 0;
6232         start = name;
6233         for (p = name; *p; p++) {
6234                 if (*p == '*' || *p == '?')
6235                         metaflag = 1;
6236                 else if (*p == '[') {
6237                         char *q = p + 1;
6238                         if (*q == '!')
6239                                 q++;
6240                         for (;;) {
6241                                 if (*q == '\\')
6242                                         q++;
6243                                 if (*q == '/' || *q == '\0')
6244                                         break;
6245                                 if (*++q == ']') {
6246                                         metaflag = 1;
6247                                         break;
6248                                 }
6249                         }
6250                 } else if (*p == '\\')
6251                         p++;
6252                 else if (*p == '/') {
6253                         if (metaflag)
6254                                 goto out;
6255                         start = p + 1;
6256                 }
6257         }
6258  out:
6259         if (metaflag == 0) {    /* we've reached the end of the file name */
6260                 if (enddir != expdir)
6261                         metaflag++;
6262                 p = name;
6263                 do {
6264                         if (*p == '\\')
6265                                 p++;
6266                         *enddir++ = *p;
6267                 } while (*p++);
6268                 if (metaflag == 0 || lstat(expdir, &statb) >= 0)
6269                         addfname(expdir);
6270                 return;
6271         }
6272         endname = p;
6273         if (name < start) {
6274                 p = name;
6275                 do {
6276                         if (*p == '\\')
6277                                 p++;
6278                         *enddir++ = *p++;
6279                 } while (p < start);
6280         }
6281         if (enddir == expdir) {
6282                 cp = ".";
6283         } else if (enddir == expdir + 1 && *expdir == '/') {
6284                 cp = "/";
6285         } else {
6286                 cp = expdir;
6287                 enddir[-1] = '\0';
6288         }
6289         dirp = opendir(cp);
6290         if (dirp == NULL)
6291                 return;
6292         if (enddir != expdir)
6293                 enddir[-1] = '/';
6294         if (*endname == 0) {
6295                 atend = 1;
6296         } else {
6297                 atend = 0;
6298                 *endname++ = '\0';
6299         }
6300         matchdot = 0;
6301         p = start;
6302         if (*p == '\\')
6303                 p++;
6304         if (*p == '.')
6305                 matchdot++;
6306         while (!intpending && (dp = readdir(dirp)) != NULL) {
6307                 if (dp->d_name[0] == '.' && ! matchdot)
6308                         continue;
6309                 if (pmatch(start, dp->d_name)) {
6310                         if (atend) {
6311                                 strcpy(enddir, dp->d_name);
6312                                 addfname(expdir);
6313                         } else {
6314                                 for (p = enddir, cp = dp->d_name; (*p++ = *cp++) != '\0';)
6315                                         continue;
6316                                 p[-1] = '/';
6317                                 expmeta(p, endname);
6318                         }
6319                 }
6320         }
6321         closedir(dirp);
6322         if (! atend)
6323                 endname[-1] = '/';
6324 }
6325
6326 static struct strlist *
6327 msort(struct strlist *list, int len)
6328 {
6329         struct strlist *p, *q = NULL;
6330         struct strlist **lpp;
6331         int half;
6332         int n;
6333
6334         if (len <= 1)
6335                 return list;
6336         half = len >> 1;
6337         p = list;
6338         for (n = half; --n >= 0; ) {
6339                 q = p;
6340                 p = p->next;
6341         }
6342         q->next = NULL;                 /* terminate first half of list */
6343         q = msort(list, half);          /* sort first half of list */
6344         p = msort(p, len - half);               /* sort second half */
6345         lpp = &list;
6346         for (;;) {
6347 #if ENABLE_LOCALE_SUPPORT
6348                 if (strcoll(p->text, q->text) < 0)
6349 #else
6350                 if (strcmp(p->text, q->text) < 0)
6351 #endif
6352                                                 {
6353                         *lpp = p;
6354                         lpp = &p->next;
6355                         p = *lpp;
6356                         if (p == NULL) {
6357                                 *lpp = q;
6358                                 break;
6359                         }
6360                 } else {
6361                         *lpp = q;
6362                         lpp = &q->next;
6363                         q = *lpp;
6364                         if (q == NULL) {
6365                                 *lpp = p;
6366                                 break;
6367                         }
6368                 }
6369         }
6370         return list;
6371 }
6372
6373 /*
6374  * Sort the results of file name expansion.  It calculates the number of
6375  * strings to sort and then calls msort (short for merge sort) to do the
6376  * work.
6377  */
6378 static struct strlist *
6379 expsort(struct strlist *str)
6380 {
6381         int len;
6382         struct strlist *sp;
6383
6384         len = 0;
6385         for (sp = str; sp; sp = sp->next)
6386                 len++;
6387         return msort(str, len);
6388 }
6389
6390 static void
6391 expandmeta(struct strlist *str, int flag)
6392 {
6393         static const char metachars[] ALIGN1 = {
6394                 '*', '?', '[', 0
6395         };
6396         /* TODO - EXP_REDIR */
6397
6398         while (str) {
6399                 struct strlist **savelastp;
6400                 struct strlist *sp;
6401                 char *p;
6402
6403                 if (fflag)
6404                         goto nometa;
6405                 if (!strpbrk(str->text, metachars))
6406                         goto nometa;
6407                 savelastp = exparg.lastp;
6408
6409                 INT_OFF;
6410                 p = preglob(str->text, 0, RMESCAPE_ALLOC | RMESCAPE_HEAP);
6411                 {
6412                         int i = strlen(str->text);
6413                         expdir = ckmalloc(i < 2048 ? 2048 : i); /* XXX */
6414                 }
6415
6416                 expmeta(expdir, p);
6417                 free(expdir);
6418                 if (p != str->text)
6419                         free(p);
6420                 INT_ON;
6421                 if (exparg.lastp == savelastp) {
6422                         /*
6423                          * no matches
6424                          */
6425  nometa:
6426                         *exparg.lastp = str;
6427                         rmescapes(str->text);
6428                         exparg.lastp = &str->next;
6429                 } else {
6430                         *exparg.lastp = NULL;
6431                         *savelastp = sp = expsort(*savelastp);
6432                         while (sp->next != NULL)
6433                                 sp = sp->next;
6434                         exparg.lastp = &sp->next;
6435                 }
6436                 str = str->next;
6437         }
6438 }
6439
6440 /*
6441  * Perform variable substitution and command substitution on an argument,
6442  * placing the resulting list of arguments in arglist.  If EXP_FULL is true,
6443  * perform splitting and file name expansion.  When arglist is NULL, perform
6444  * here document expansion.
6445  */
6446 static void
6447 expandarg(union node *arg, struct arglist *arglist, int flag)
6448 {
6449         struct strlist *sp;
6450         char *p;
6451
6452         argbackq = arg->narg.backquote;
6453         STARTSTACKSTR(expdest);
6454         ifsfirst.next = NULL;
6455         ifslastp = NULL;
6456         argstr(arg->narg.text, flag,
6457                         /* var_str_list: */ arglist ? arglist->list : NULL);
6458         p = _STPUTC('\0', expdest);
6459         expdest = p - 1;
6460         if (arglist == NULL) {
6461                 return;                 /* here document expanded */
6462         }
6463         p = grabstackstr(p);
6464         exparg.lastp = &exparg.list;
6465         /*
6466          * TODO - EXP_REDIR
6467          */
6468         if (flag & EXP_FULL) {
6469                 ifsbreakup(p, &exparg);
6470                 *exparg.lastp = NULL;
6471                 exparg.lastp = &exparg.list;
6472                 expandmeta(exparg.list, flag);
6473         } else {
6474                 if (flag & EXP_REDIR) /*XXX - for now, just remove escapes */
6475                         rmescapes(p);
6476                 sp = stalloc(sizeof(*sp));
6477                 sp->text = p;
6478                 *exparg.lastp = sp;
6479                 exparg.lastp = &sp->next;
6480         }
6481         if (ifsfirst.next)
6482                 ifsfree();
6483         *exparg.lastp = NULL;
6484         if (exparg.list) {
6485                 *arglist->lastp = exparg.list;
6486                 arglist->lastp = exparg.lastp;
6487         }
6488 }
6489
6490 /*
6491  * Expand shell variables and backquotes inside a here document.
6492  */
6493 static void
6494 expandhere(union node *arg, int fd)
6495 {
6496         herefd = fd;
6497         expandarg(arg, (struct arglist *)NULL, 0);
6498         full_write(fd, stackblock(), expdest - (char *)stackblock());
6499 }
6500
6501 /*
6502  * Returns true if the pattern matches the string.
6503  */
6504 static int
6505 patmatch(char *pattern, const char *string)
6506 {
6507         return pmatch(preglob(pattern, 0, 0), string);
6508 }
6509
6510 /*
6511  * See if a pattern matches in a case statement.
6512  */
6513 static int
6514 casematch(union node *pattern, char *val)
6515 {
6516         struct stackmark smark;
6517         int result;
6518
6519         setstackmark(&smark);
6520         argbackq = pattern->narg.backquote;
6521         STARTSTACKSTR(expdest);
6522         ifslastp = NULL;
6523         argstr(pattern->narg.text, EXP_TILDE | EXP_CASE,
6524                         /* var_str_list: */ NULL);
6525         STACKSTRNUL(expdest);
6526         result = patmatch(stackblock(), val);
6527         popstackmark(&smark);
6528         return result;
6529 }
6530
6531
6532 /* ============ find_command */
6533
6534 struct builtincmd {
6535         const char *name;
6536         int (*builtin)(int, char **);
6537         /* unsigned flags; */
6538 };
6539 #define IS_BUILTIN_SPECIAL(b) ((b)->name[0] & 1)
6540 /* "regular" builtins always take precedence over commands,
6541  * regardless of PATH=....%builtin... position */
6542 #define IS_BUILTIN_REGULAR(b) ((b)->name[0] & 2)
6543 #define IS_BUILTIN_ASSIGN(b)  ((b)->name[0] & 4)
6544
6545 struct cmdentry {
6546         int cmdtype;
6547         union param {
6548                 int index;
6549                 const struct builtincmd *cmd;
6550                 struct funcnode *func;
6551         } u;
6552 };
6553 /* values of cmdtype */
6554 #define CMDUNKNOWN      -1      /* no entry in table for command */
6555 #define CMDNORMAL       0       /* command is an executable program */
6556 #define CMDFUNCTION     1       /* command is a shell function */
6557 #define CMDBUILTIN      2       /* command is a shell builtin */
6558
6559 /* action to find_command() */
6560 #define DO_ERR          0x01    /* prints errors */
6561 #define DO_ABS          0x02    /* checks absolute paths */
6562 #define DO_NOFUNC       0x04    /* don't return shell functions, for command */
6563 #define DO_ALTPATH      0x08    /* using alternate path */
6564 #define DO_ALTBLTIN     0x20    /* %builtin in alt. path */
6565
6566 static void find_command(char *, struct cmdentry *, int, const char *);
6567
6568
6569 /* ============ Hashing commands */
6570
6571 /*
6572  * When commands are first encountered, they are entered in a hash table.
6573  * This ensures that a full path search will not have to be done for them
6574  * on each invocation.
6575  *
6576  * We should investigate converting to a linear search, even though that
6577  * would make the command name "hash" a misnomer.
6578  */
6579
6580 #define ARB 1                   /* actual size determined at run time */
6581
6582 struct tblentry {
6583         struct tblentry *next;  /* next entry in hash chain */
6584         union param param;      /* definition of builtin function */
6585         short cmdtype;          /* index identifying command */
6586         char rehash;            /* if set, cd done since entry created */
6587         char cmdname[ARB];      /* name of command */
6588 };
6589
6590 static struct tblentry **cmdtable;
6591 #define INIT_G_cmdtable() do { \
6592         cmdtable = xzalloc(CMDTABLESIZE * sizeof(cmdtable[0])); \
6593 } while (0)
6594
6595 static int builtinloc = -1;     /* index in path of %builtin, or -1 */
6596
6597
6598 static void
6599 tryexec(char *cmd, char **argv, char **envp)
6600 {
6601         int repeated = 0;
6602
6603 #if ENABLE_FEATURE_SH_STANDALONE
6604         if (strchr(cmd, '/') == NULL) {
6605                 int a = find_applet_by_name(cmd);
6606                 if (a >= 0) {
6607                         if (APPLET_IS_NOEXEC(a))
6608                                 run_applet_no_and_exit(a, argv);
6609                         /* re-exec ourselves with the new arguments */
6610                         execve(bb_busybox_exec_path, argv, envp);
6611                         /* If they called chroot or otherwise made the binary no longer
6612                          * executable, fall through */
6613                 }
6614         }
6615 #endif
6616
6617  repeat:
6618 #ifdef SYSV
6619         do {
6620                 execve(cmd, argv, envp);
6621         } while (errno == EINTR);
6622 #else
6623         execve(cmd, argv, envp);
6624 #endif
6625         if (repeated++) {
6626                 free(argv);
6627         } else if (errno == ENOEXEC) {
6628                 char **ap;
6629                 char **new;
6630
6631                 for (ap = argv; *ap; ap++)
6632                         ;
6633                 ap = new = ckmalloc((ap - argv + 2) * sizeof(char *));
6634                 ap[1] = cmd;
6635                 ap[0] = cmd = (char *)DEFAULT_SHELL;
6636                 ap += 2;
6637                 argv++;
6638                 while ((*ap++ = *argv++))
6639                         ;
6640                 argv = new;
6641                 goto repeat;
6642         }
6643 }
6644
6645 /*
6646  * Exec a program.  Never returns.  If you change this routine, you may
6647  * have to change the find_command routine as well.
6648  */
6649 #define environment() listvars(VEXPORT, VUNSET, 0)
6650 static void shellexec(char **, const char *, int) ATTRIBUTE_NORETURN;
6651 static void
6652 shellexec(char **argv, const char *path, int idx)
6653 {
6654         char *cmdname;
6655         int e;
6656         char **envp;
6657         int exerrno;
6658
6659         clearredir(1);
6660         envp = environment();
6661         if (strchr(argv[0], '/')
6662 #if ENABLE_FEATURE_SH_STANDALONE
6663          || find_applet_by_name(argv[0]) >= 0
6664 #endif
6665         ) {
6666                 tryexec(argv[0], argv, envp);
6667                 e = errno;
6668         } else {
6669                 e = ENOENT;
6670                 while ((cmdname = padvance(&path, argv[0])) != NULL) {
6671                         if (--idx < 0 && pathopt == NULL) {
6672                                 tryexec(cmdname, argv, envp);
6673                                 if (errno != ENOENT && errno != ENOTDIR)
6674                                         e = errno;
6675                         }
6676                         stunalloc(cmdname);
6677                 }
6678         }
6679
6680         /* Map to POSIX errors */
6681         switch (e) {
6682         case EACCES:
6683                 exerrno = 126;
6684                 break;
6685         case ENOENT:
6686                 exerrno = 127;
6687                 break;
6688         default:
6689                 exerrno = 2;
6690                 break;
6691         }
6692         exitstatus = exerrno;
6693         TRACE(("shellexec failed for %s, errno %d, suppressint %d\n",
6694                 argv[0], e, suppressint ));
6695         ash_msg_and_raise(EXEXEC, "%s: %s", argv[0], errmsg(e, "not found"));
6696         /* NOTREACHED */
6697 }
6698
6699 static void
6700 printentry(struct tblentry *cmdp)
6701 {
6702         int idx;
6703         const char *path;
6704         char *name;
6705
6706         idx = cmdp->param.index;
6707         path = pathval();
6708         do {
6709                 name = padvance(&path, cmdp->cmdname);
6710                 stunalloc(name);
6711         } while (--idx >= 0);
6712         out1fmt("%s%s\n", name, (cmdp->rehash ? "*" : nullstr));
6713 }
6714
6715 /*
6716  * Clear out command entries.  The argument specifies the first entry in
6717  * PATH which has changed.
6718  */
6719 static void
6720 clearcmdentry(int firstchange)
6721 {
6722         struct tblentry **tblp;
6723         struct tblentry **pp;
6724         struct tblentry *cmdp;
6725
6726         INT_OFF;
6727         for (tblp = cmdtable; tblp < &cmdtable[CMDTABLESIZE]; tblp++) {
6728                 pp = tblp;
6729                 while ((cmdp = *pp) != NULL) {
6730                         if ((cmdp->cmdtype == CMDNORMAL &&
6731                              cmdp->param.index >= firstchange)
6732                          || (cmdp->cmdtype == CMDBUILTIN &&
6733                              builtinloc >= firstchange)
6734                         ) {
6735                                 *pp = cmdp->next;
6736                                 free(cmdp);
6737                         } else {
6738                                 pp = &cmdp->next;
6739                         }
6740                 }
6741         }
6742         INT_ON;
6743 }
6744
6745 /*
6746  * Locate a command in the command hash table.  If "add" is nonzero,
6747  * add the command to the table if it is not already present.  The
6748  * variable "lastcmdentry" is set to point to the address of the link
6749  * pointing to the entry, so that delete_cmd_entry can delete the
6750  * entry.
6751  *
6752  * Interrupts must be off if called with add != 0.
6753  */
6754 static struct tblentry **lastcmdentry;
6755
6756 static struct tblentry *
6757 cmdlookup(const char *name, int add)
6758 {
6759         unsigned int hashval;
6760         const char *p;
6761         struct tblentry *cmdp;
6762         struct tblentry **pp;
6763
6764         p = name;
6765         hashval = (unsigned char)*p << 4;
6766         while (*p)
6767                 hashval += (unsigned char)*p++;
6768         hashval &= 0x7FFF;
6769         pp = &cmdtable[hashval % CMDTABLESIZE];
6770         for (cmdp = *pp; cmdp; cmdp = cmdp->next) {
6771                 if (strcmp(cmdp->cmdname, name) == 0)
6772                         break;
6773                 pp = &cmdp->next;
6774         }
6775         if (add && cmdp == NULL) {
6776                 cmdp = *pp = ckmalloc(sizeof(struct tblentry) - ARB
6777                                         + strlen(name) + 1);
6778                 cmdp->next = NULL;
6779                 cmdp->cmdtype = CMDUNKNOWN;
6780                 strcpy(cmdp->cmdname, name);
6781         }
6782         lastcmdentry = pp;
6783         return cmdp;
6784 }
6785
6786 /*
6787  * Delete the command entry returned on the last lookup.
6788  */
6789 static void
6790 delete_cmd_entry(void)
6791 {
6792         struct tblentry *cmdp;
6793
6794         INT_OFF;
6795         cmdp = *lastcmdentry;
6796         *lastcmdentry = cmdp->next;
6797         if (cmdp->cmdtype == CMDFUNCTION)
6798                 freefunc(cmdp->param.func);
6799         free(cmdp);
6800         INT_ON;
6801 }
6802
6803 /*
6804  * Add a new command entry, replacing any existing command entry for
6805  * the same name - except special builtins.
6806  */
6807 static void
6808 addcmdentry(char *name, struct cmdentry *entry)
6809 {
6810         struct tblentry *cmdp;
6811
6812         cmdp = cmdlookup(name, 1);
6813         if (cmdp->cmdtype == CMDFUNCTION) {
6814                 freefunc(cmdp->param.func);
6815         }
6816         cmdp->cmdtype = entry->cmdtype;
6817         cmdp->param = entry->u;
6818         cmdp->rehash = 0;
6819 }
6820
6821 static int
6822 hashcmd(int argc, char **argv)
6823 {
6824         struct tblentry **pp;
6825         struct tblentry *cmdp;
6826         int c;
6827         struct cmdentry entry;
6828         char *name;
6829
6830         if (nextopt("r") != '\0') {
6831                 clearcmdentry(0);
6832                 return 0;
6833         }
6834
6835         if (*argptr == NULL) {
6836                 for (pp = cmdtable; pp < &cmdtable[CMDTABLESIZE]; pp++) {
6837                         for (cmdp = *pp; cmdp; cmdp = cmdp->next) {
6838                                 if (cmdp->cmdtype == CMDNORMAL)
6839                                         printentry(cmdp);
6840                         }
6841                 }
6842                 return 0;
6843         }
6844
6845         c = 0;
6846         while ((name = *argptr) != NULL) {
6847                 cmdp = cmdlookup(name, 0);
6848                 if (cmdp != NULL
6849                  && (cmdp->cmdtype == CMDNORMAL
6850                      || (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0))
6851                 ) {
6852                         delete_cmd_entry();
6853                 }
6854                 find_command(name, &entry, DO_ERR, pathval());
6855                 if (entry.cmdtype == CMDUNKNOWN)
6856                         c = 1;
6857                 argptr++;
6858         }
6859         return c;
6860 }
6861
6862 /*
6863  * Called when a cd is done.  Marks all commands so the next time they
6864  * are executed they will be rehashed.
6865  */
6866 static void
6867 hashcd(void)
6868 {
6869         struct tblentry **pp;
6870         struct tblentry *cmdp;
6871
6872         for (pp = cmdtable; pp < &cmdtable[CMDTABLESIZE]; pp++) {
6873                 for (cmdp = *pp; cmdp; cmdp = cmdp->next) {
6874                         if (cmdp->cmdtype == CMDNORMAL
6875                          || (cmdp->cmdtype == CMDBUILTIN
6876                              && !IS_BUILTIN_REGULAR(cmdp->param.cmd)
6877                              && builtinloc > 0)
6878                         ) {
6879                                 cmdp->rehash = 1;
6880                         }
6881                 }
6882         }
6883 }
6884
6885 /*
6886  * Fix command hash table when PATH changed.
6887  * Called before PATH is changed.  The argument is the new value of PATH;
6888  * pathval() still returns the old value at this point.
6889  * Called with interrupts off.
6890  */
6891 static void
6892 changepath(const char *new)
6893 {
6894         const char *old;
6895         int firstchange;
6896         int idx;
6897         int idx_bltin;
6898
6899         old = pathval();
6900         firstchange = 9999;     /* assume no change */
6901         idx = 0;
6902         idx_bltin = -1;
6903         for (;;) {
6904                 if (*old != *new) {
6905                         firstchange = idx;
6906                         if ((*old == '\0' && *new == ':')
6907                          || (*old == ':' && *new == '\0'))
6908                                 firstchange++;
6909                         old = new;      /* ignore subsequent differences */
6910                 }
6911                 if (*new == '\0')
6912                         break;
6913                 if (*new == '%' && idx_bltin < 0 && prefix(new + 1, "builtin"))
6914                         idx_bltin = idx;
6915                 if (*new == ':')
6916                         idx++;
6917                 new++, old++;
6918         }
6919         if (builtinloc < 0 && idx_bltin >= 0)
6920                 builtinloc = idx_bltin;             /* zap builtins */
6921         if (builtinloc >= 0 && idx_bltin < 0)
6922                 firstchange = 0;
6923         clearcmdentry(firstchange);
6924         builtinloc = idx_bltin;
6925 }
6926
6927 #define TEOF 0
6928 #define TNL 1
6929 #define TREDIR 2
6930 #define TWORD 3
6931 #define TSEMI 4
6932 #define TBACKGND 5
6933 #define TAND 6
6934 #define TOR 7
6935 #define TPIPE 8
6936 #define TLP 9
6937 #define TRP 10
6938 #define TENDCASE 11
6939 #define TENDBQUOTE 12
6940 #define TNOT 13
6941 #define TCASE 14
6942 #define TDO 15
6943 #define TDONE 16
6944 #define TELIF 17
6945 #define TELSE 18
6946 #define TESAC 19
6947 #define TFI 20
6948 #define TFOR 21
6949 #define TIF 22
6950 #define TIN 23
6951 #define TTHEN 24
6952 #define TUNTIL 25
6953 #define TWHILE 26
6954 #define TBEGIN 27
6955 #define TEND 28
6956
6957 /* first char is indicating which tokens mark the end of a list */
6958 static const char *const tokname_array[] = {
6959         "\1end of file",
6960         "\0newline",
6961         "\0redirection",
6962         "\0word",
6963         "\0;",
6964         "\0&",
6965         "\0&&",
6966         "\0||",
6967         "\0|",
6968         "\0(",
6969         "\1)",
6970         "\1;;",
6971         "\1`",
6972 #define KWDOFFSET 13
6973         /* the following are keywords */
6974         "\0!",
6975         "\0case",
6976         "\1do",
6977         "\1done",
6978         "\1elif",
6979         "\1else",
6980         "\1esac",
6981         "\1fi",
6982         "\0for",
6983         "\0if",
6984         "\0in",
6985         "\1then",
6986         "\0until",
6987         "\0while",
6988         "\0{",
6989         "\1}",
6990 };
6991
6992 static const char *
6993 tokname(int tok)
6994 {
6995         static char buf[16];
6996
6997 //try this:
6998 //if (tok < TSEMI) return tokname_array[tok] + 1;
6999 //sprintf(buf, "\"%s\"", tokname_array[tok] + 1);
7000 //return buf;
7001
7002         if (tok >= TSEMI)
7003                 buf[0] = '"';
7004         sprintf(buf + (tok >= TSEMI), "%s%c",
7005                         tokname_array[tok] + 1, (tok >= TSEMI ? '"' : 0));
7006         return buf;
7007 }
7008
7009 /* Wrapper around strcmp for qsort/bsearch/... */
7010 static int
7011 pstrcmp(const void *a, const void *b)
7012 {
7013         return strcmp((char*) a, (*(char**) b) + 1);
7014 }
7015
7016 static const char *const *
7017 findkwd(const char *s)
7018 {
7019         return bsearch(s, tokname_array + KWDOFFSET,
7020                         ARRAY_SIZE(tokname_array) - KWDOFFSET,
7021                         sizeof(tokname_array[0]), pstrcmp);
7022 }
7023
7024 /*
7025  * Locate and print what a word is...
7026  */
7027 static int
7028 describe_command(char *command, int describe_command_verbose)
7029 {
7030         struct cmdentry entry;
7031         struct tblentry *cmdp;
7032 #if ENABLE_ASH_ALIAS
7033         const struct alias *ap;
7034 #endif
7035         const char *path = pathval();
7036
7037         if (describe_command_verbose) {
7038                 out1str(command);
7039         }
7040
7041         /* First look at the keywords */
7042         if (findkwd(command)) {
7043                 out1str(describe_command_verbose ? " is a shell keyword" : command);
7044                 goto out;
7045         }
7046
7047 #if ENABLE_ASH_ALIAS
7048         /* Then look at the aliases */
7049         ap = lookupalias(command, 0);
7050         if (ap != NULL) {
7051                 if (!describe_command_verbose) {
7052                         out1str("alias ");
7053                         printalias(ap);
7054                         return 0;
7055                 }
7056                 out1fmt(" is an alias for %s", ap->val);
7057                 goto out;
7058         }
7059 #endif
7060         /* Then check if it is a tracked alias */
7061         cmdp = cmdlookup(command, 0);
7062         if (cmdp != NULL) {
7063                 entry.cmdtype = cmdp->cmdtype;
7064                 entry.u = cmdp->param;
7065         } else {
7066                 /* Finally use brute force */
7067                 find_command(command, &entry, DO_ABS, path);
7068         }
7069
7070         switch (entry.cmdtype) {
7071         case CMDNORMAL: {
7072                 int j = entry.u.index;
7073                 char *p;
7074                 if (j == -1) {
7075                         p = command;
7076                 } else {
7077                         do {
7078                                 p = padvance(&path, command);
7079                                 stunalloc(p);
7080                         } while (--j >= 0);
7081                 }
7082                 if (describe_command_verbose) {
7083                         out1fmt(" is%s %s",
7084                                 (cmdp ? " a tracked alias for" : nullstr), p
7085                         );
7086                 } else {
7087                         out1str(p);
7088                 }
7089                 break;
7090         }
7091
7092         case CMDFUNCTION:
7093                 if (describe_command_verbose) {
7094                         out1str(" is a shell function");
7095                 } else {
7096                         out1str(command);
7097                 }
7098                 break;
7099
7100         case CMDBUILTIN:
7101                 if (describe_command_verbose) {
7102                         out1fmt(" is a %sshell builtin",
7103                                 IS_BUILTIN_SPECIAL(entry.u.cmd) ?
7104                                         "special " : nullstr
7105                         );
7106                 } else {
7107                         out1str(command);
7108                 }
7109                 break;
7110
7111         default:
7112                 if (describe_command_verbose) {
7113                         out1str(": not found\n");
7114                 }
7115                 return 127;
7116         }
7117  out:
7118         outstr("\n", stdout);
7119         return 0;
7120 }
7121
7122 static int
7123 typecmd(int argc, char **argv)
7124 {
7125         int i = 1;
7126         int err = 0;
7127         int verbose = 1;
7128
7129         /* type -p ... ? (we don't bother checking for 'p') */
7130         if (argv[1] && argv[1][0] == '-') {
7131                 i++;
7132                 verbose = 0;
7133         }
7134         while (i < argc) {
7135                 err |= describe_command(argv[i++], verbose);
7136         }
7137         return err;
7138 }
7139
7140 #if ENABLE_ASH_CMDCMD
7141 static int
7142 commandcmd(int argc, char **argv)
7143 {
7144         int c;
7145         enum {
7146                 VERIFY_BRIEF = 1,
7147                 VERIFY_VERBOSE = 2,
7148         } verify = 0;
7149
7150         while ((c = nextopt("pvV")) != '\0')
7151                 if (c == 'V')
7152                         verify |= VERIFY_VERBOSE;
7153                 else if (c == 'v')
7154                         verify |= VERIFY_BRIEF;
7155 #if DEBUG
7156                 else if (c != 'p')
7157                         abort();
7158 #endif
7159         if (verify)
7160                 return describe_command(*argptr, verify - VERIFY_BRIEF);
7161
7162         return 0;
7163 }
7164 #endif
7165
7166
7167 /* ============ eval.c */
7168
7169 static int funcblocksize;          /* size of structures in function */
7170 static int funcstringsize;         /* size of strings in node */
7171 static void *funcblock;            /* block to allocate function from */
7172 static char *funcstring;           /* block to allocate strings from */
7173
7174 /* flags in argument to evaltree */
7175 #define EV_EXIT 01              /* exit after evaluating tree */
7176 #define EV_TESTED 02            /* exit status is checked; ignore -e flag */
7177 #define EV_BACKCMD 04           /* command executing within back quotes */
7178
7179 static const short nodesize[26] = {
7180         SHELL_ALIGN(sizeof(struct ncmd)),
7181         SHELL_ALIGN(sizeof(struct npipe)),
7182         SHELL_ALIGN(sizeof(struct nredir)),
7183         SHELL_ALIGN(sizeof(struct nredir)),
7184         SHELL_ALIGN(sizeof(struct nredir)),
7185         SHELL_ALIGN(sizeof(struct nbinary)),
7186         SHELL_ALIGN(sizeof(struct nbinary)),
7187         SHELL_ALIGN(sizeof(struct nbinary)),
7188         SHELL_ALIGN(sizeof(struct nif)),
7189         SHELL_ALIGN(sizeof(struct nbinary)),
7190         SHELL_ALIGN(sizeof(struct nbinary)),
7191         SHELL_ALIGN(sizeof(struct nfor)),
7192         SHELL_ALIGN(sizeof(struct ncase)),
7193         SHELL_ALIGN(sizeof(struct nclist)),
7194         SHELL_ALIGN(sizeof(struct narg)),
7195         SHELL_ALIGN(sizeof(struct narg)),
7196         SHELL_ALIGN(sizeof(struct nfile)),
7197         SHELL_ALIGN(sizeof(struct nfile)),
7198         SHELL_ALIGN(sizeof(struct nfile)),
7199         SHELL_ALIGN(sizeof(struct nfile)),
7200         SHELL_ALIGN(sizeof(struct nfile)),
7201         SHELL_ALIGN(sizeof(struct ndup)),
7202         SHELL_ALIGN(sizeof(struct ndup)),
7203         SHELL_ALIGN(sizeof(struct nhere)),
7204         SHELL_ALIGN(sizeof(struct nhere)),
7205         SHELL_ALIGN(sizeof(struct nnot)),
7206 };
7207
7208 static void calcsize(union node *n);
7209
7210 static void
7211 sizenodelist(struct nodelist *lp)
7212 {
7213         while (lp) {
7214                 funcblocksize += SHELL_ALIGN(sizeof(struct nodelist));
7215                 calcsize(lp->n);
7216                 lp = lp->next;
7217         }
7218 }
7219
7220 static void
7221 calcsize(union node *n)
7222 {
7223         if (n == NULL)
7224                 return;
7225         funcblocksize += nodesize[n->type];
7226         switch (n->type) {
7227         case NCMD:
7228                 calcsize(n->ncmd.redirect);
7229                 calcsize(n->ncmd.args);
7230                 calcsize(n->ncmd.assign);
7231                 break;
7232         case NPIPE:
7233                 sizenodelist(n->npipe.cmdlist);
7234                 break;
7235         case NREDIR:
7236         case NBACKGND:
7237         case NSUBSHELL:
7238                 calcsize(n->nredir.redirect);
7239                 calcsize(n->nredir.n);
7240                 break;
7241         case NAND:
7242         case NOR:
7243         case NSEMI:
7244         case NWHILE:
7245         case NUNTIL:
7246                 calcsize(n->nbinary.ch2);
7247                 calcsize(n->nbinary.ch1);
7248                 break;
7249         case NIF:
7250                 calcsize(n->nif.elsepart);
7251                 calcsize(n->nif.ifpart);
7252                 calcsize(n->nif.test);
7253                 break;
7254         case NFOR:
7255                 funcstringsize += strlen(n->nfor.var) + 1;
7256                 calcsize(n->nfor.body);
7257                 calcsize(n->nfor.args);
7258                 break;
7259         case NCASE:
7260                 calcsize(n->ncase.cases);
7261                 calcsize(n->ncase.expr);
7262                 break;
7263         case NCLIST:
7264                 calcsize(n->nclist.body);
7265                 calcsize(n->nclist.pattern);
7266                 calcsize(n->nclist.next);
7267                 break;
7268         case NDEFUN:
7269         case NARG:
7270                 sizenodelist(n->narg.backquote);
7271                 funcstringsize += strlen(n->narg.text) + 1;
7272                 calcsize(n->narg.next);
7273                 break;
7274         case NTO:
7275         case NCLOBBER:
7276         case NFROM:
7277         case NFROMTO:
7278         case NAPPEND:
7279                 calcsize(n->nfile.fname);
7280                 calcsize(n->nfile.next);
7281                 break;
7282         case NTOFD:
7283         case NFROMFD:
7284                 calcsize(n->ndup.vname);
7285                 calcsize(n->ndup.next);
7286         break;
7287         case NHERE:
7288         case NXHERE:
7289                 calcsize(n->nhere.doc);
7290                 calcsize(n->nhere.next);
7291                 break;
7292         case NNOT:
7293                 calcsize(n->nnot.com);
7294                 break;
7295         };
7296 }
7297
7298 static char *
7299 nodeckstrdup(char *s)
7300 {
7301         char *rtn = funcstring;
7302
7303         strcpy(funcstring, s);
7304         funcstring += strlen(s) + 1;
7305         return rtn;
7306 }
7307
7308 static union node *copynode(union node *);
7309
7310 static struct nodelist *
7311 copynodelist(struct nodelist *lp)
7312 {
7313         struct nodelist *start;
7314         struct nodelist **lpp;
7315
7316         lpp = &start;
7317         while (lp) {
7318                 *lpp = funcblock;
7319                 funcblock = (char *) funcblock + SHELL_ALIGN(sizeof(struct nodelist));
7320                 (*lpp)->n = copynode(lp->n);
7321                 lp = lp->next;
7322                 lpp = &(*lpp)->next;
7323         }
7324         *lpp = NULL;
7325         return start;
7326 }
7327
7328 static union node *
7329 copynode(union node *n)
7330 {
7331         union node *new;
7332
7333         if (n == NULL)
7334                 return NULL;
7335         new = funcblock;
7336         funcblock = (char *) funcblock + nodesize[n->type];
7337
7338         switch (n->type) {
7339         case NCMD:
7340                 new->ncmd.redirect = copynode(n->ncmd.redirect);
7341                 new->ncmd.args = copynode(n->ncmd.args);
7342                 new->ncmd.assign = copynode(n->ncmd.assign);
7343                 break;
7344         case NPIPE:
7345                 new->npipe.cmdlist = copynodelist(n->npipe.cmdlist);
7346                 new->npipe.backgnd = n->npipe.backgnd;
7347                 break;
7348         case NREDIR:
7349         case NBACKGND:
7350         case NSUBSHELL:
7351                 new->nredir.redirect = copynode(n->nredir.redirect);
7352                 new->nredir.n = copynode(n->nredir.n);
7353                 break;
7354         case NAND:
7355         case NOR:
7356         case NSEMI:
7357         case NWHILE:
7358         case NUNTIL:
7359                 new->nbinary.ch2 = copynode(n->nbinary.ch2);
7360                 new->nbinary.ch1 = copynode(n->nbinary.ch1);
7361                 break;
7362         case NIF:
7363                 new->nif.elsepart = copynode(n->nif.elsepart);
7364                 new->nif.ifpart = copynode(n->nif.ifpart);
7365                 new->nif.test = copynode(n->nif.test);
7366                 break;
7367         case NFOR:
7368                 new->nfor.var = nodeckstrdup(n->nfor.var);
7369                 new->nfor.body = copynode(n->nfor.body);
7370                 new->nfor.args = copynode(n->nfor.args);
7371                 break;
7372         case NCASE:
7373                 new->ncase.cases = copynode(n->ncase.cases);
7374                 new->ncase.expr = copynode(n->ncase.expr);
7375                 break;
7376         case NCLIST:
7377                 new->nclist.body = copynode(n->nclist.body);
7378                 new->nclist.pattern = copynode(n->nclist.pattern);
7379                 new->nclist.next = copynode(n->nclist.next);
7380                 break;
7381         case NDEFUN:
7382         case NARG:
7383                 new->narg.backquote = copynodelist(n->narg.backquote);
7384                 new->narg.text = nodeckstrdup(n->narg.text);
7385                 new->narg.next = copynode(n->narg.next);
7386                 break;
7387         case NTO:
7388         case NCLOBBER:
7389         case NFROM:
7390         case NFROMTO:
7391         case NAPPEND:
7392                 new->nfile.fname = copynode(n->nfile.fname);
7393                 new->nfile.fd = n->nfile.fd;
7394                 new->nfile.next = copynode(n->nfile.next);
7395                 break;
7396         case NTOFD:
7397         case NFROMFD:
7398                 new->ndup.vname = copynode(n->ndup.vname);
7399                 new->ndup.dupfd = n->ndup.dupfd;
7400                 new->ndup.fd = n->ndup.fd;
7401                 new->ndup.next = copynode(n->ndup.next);
7402                 break;
7403         case NHERE:
7404         case NXHERE:
7405                 new->nhere.doc = copynode(n->nhere.doc);
7406                 new->nhere.fd = n->nhere.fd;
7407                 new->nhere.next = copynode(n->nhere.next);
7408                 break;
7409         case NNOT:
7410                 new->nnot.com = copynode(n->nnot.com);
7411                 break;
7412         };
7413         new->type = n->type;
7414         return new;
7415 }
7416
7417 /*
7418  * Make a copy of a parse tree.
7419  */
7420 static struct funcnode *
7421 copyfunc(union node *n)
7422 {
7423         struct funcnode *f;
7424         size_t blocksize;
7425
7426         funcblocksize = offsetof(struct funcnode, n);
7427         funcstringsize = 0;
7428         calcsize(n);
7429         blocksize = funcblocksize;
7430         f = ckmalloc(blocksize + funcstringsize);
7431         funcblock = (char *) f + offsetof(struct funcnode, n);
7432         funcstring = (char *) f + blocksize;
7433         copynode(n);
7434         f->count = 0;
7435         return f;
7436 }
7437
7438 /*
7439  * Define a shell function.
7440  */
7441 static void
7442 defun(char *name, union node *func)
7443 {
7444         struct cmdentry entry;
7445
7446         INT_OFF;
7447         entry.cmdtype = CMDFUNCTION;
7448         entry.u.func = copyfunc(func);
7449         addcmdentry(name, &entry);
7450         INT_ON;
7451 }
7452
7453 static int evalskip;            /* set if we are skipping commands */
7454 /* reasons for skipping commands (see comment on breakcmd routine) */
7455 #define SKIPBREAK      (1 << 0)
7456 #define SKIPCONT       (1 << 1)
7457 #define SKIPFUNC       (1 << 2)
7458 #define SKIPFILE       (1 << 3)
7459 #define SKIPEVAL       (1 << 4)
7460 static int skipcount;           /* number of levels to skip */
7461 static int funcnest;            /* depth of function calls */
7462
7463 /* forward decl way out to parsing code - dotrap needs it */
7464 static int evalstring(char *s, int mask);
7465
7466 /*
7467  * Called to execute a trap.  Perhaps we should avoid entering new trap
7468  * handlers while we are executing a trap handler.
7469  */
7470 static int
7471 dotrap(void)
7472 {
7473         char *p;
7474         char *q;
7475         int i;
7476         int savestatus;
7477         int skip;
7478
7479         savestatus = exitstatus;
7480         pendingsig = 0;
7481         xbarrier();
7482
7483         for (i = 0, q = gotsig; i < NSIG - 1; i++, q++) {
7484                 if (!*q)
7485                         continue;
7486                 *q = '\0';
7487
7488                 p = trap[i + 1];
7489                 if (!p)
7490                         continue;
7491                 skip = evalstring(p, SKIPEVAL);
7492                 exitstatus = savestatus;
7493                 if (skip)
7494                         return skip;
7495         }
7496
7497         return 0;
7498 }
7499
7500 /* forward declarations - evaluation is fairly recursive business... */
7501 static void evalloop(union node *, int);
7502 static void evalfor(union node *, int);
7503 static void evalcase(union node *, int);
7504 static void evalsubshell(union node *, int);
7505 static void expredir(union node *);
7506 static void evalpipe(union node *, int);
7507 static void evalcommand(union node *, int);
7508 static int evalbltin(const struct builtincmd *, int, char **);
7509 static void prehash(union node *);
7510
7511 /*
7512  * Evaluate a parse tree.  The value is left in the global variable
7513  * exitstatus.
7514  */
7515 static void
7516 evaltree(union node *n, int flags)
7517 {
7518         int checkexit = 0;
7519         void (*evalfn)(union node *, int);
7520         unsigned isor;
7521         int status;
7522         if (n == NULL) {
7523                 TRACE(("evaltree(NULL) called\n"));
7524                 goto out;
7525         }
7526         TRACE(("pid %d, evaltree(%p: %d, %d) called\n",
7527                         getpid(), n, n->type, flags));
7528         switch (n->type) {
7529         default:
7530 #if DEBUG
7531                 out1fmt("Node type = %d\n", n->type);
7532                 fflush(stdout);
7533                 break;
7534 #endif
7535         case NNOT:
7536                 evaltree(n->nnot.com, EV_TESTED);
7537                 status = !exitstatus;
7538                 goto setstatus;
7539         case NREDIR:
7540                 expredir(n->nredir.redirect);
7541                 status = redirectsafe(n->nredir.redirect, REDIR_PUSH);
7542                 if (!status) {
7543                         evaltree(n->nredir.n, flags & EV_TESTED);
7544                         status = exitstatus;
7545                 }
7546                 popredir(0);
7547                 goto setstatus;
7548         case NCMD:
7549                 evalfn = evalcommand;
7550  checkexit:
7551                 if (eflag && !(flags & EV_TESTED))
7552                         checkexit = ~0;
7553                 goto calleval;
7554         case NFOR:
7555                 evalfn = evalfor;
7556                 goto calleval;
7557         case NWHILE:
7558         case NUNTIL:
7559                 evalfn = evalloop;
7560                 goto calleval;
7561         case NSUBSHELL:
7562         case NBACKGND:
7563                 evalfn = evalsubshell;
7564                 goto calleval;
7565         case NPIPE:
7566                 evalfn = evalpipe;
7567                 goto checkexit;
7568         case NCASE:
7569                 evalfn = evalcase;
7570                 goto calleval;
7571         case NAND:
7572         case NOR:
7573         case NSEMI:
7574 #if NAND + 1 != NOR
7575 #error NAND + 1 != NOR
7576 #endif
7577 #if NOR + 1 != NSEMI
7578 #error NOR + 1 != NSEMI
7579 #endif
7580                 isor = n->type - NAND;
7581                 evaltree(
7582                         n->nbinary.ch1,
7583                         (flags | ((isor >> 1) - 1)) & EV_TESTED
7584                 );
7585                 if (!exitstatus == isor)
7586                         break;
7587                 if (!evalskip) {
7588                         n = n->nbinary.ch2;
7589  evaln:
7590                         evalfn = evaltree;
7591  calleval:
7592                         evalfn(n, flags);
7593                         break;
7594                 }
7595                 break;
7596         case NIF:
7597                 evaltree(n->nif.test, EV_TESTED);
7598                 if (evalskip)
7599                         break;
7600                 if (exitstatus == 0) {
7601                         n = n->nif.ifpart;
7602                         goto evaln;
7603                 } else if (n->nif.elsepart) {
7604                         n = n->nif.elsepart;
7605                         goto evaln;
7606                 }
7607                 goto success;
7608         case NDEFUN:
7609                 defun(n->narg.text, n->narg.next);
7610  success:
7611                 status = 0;
7612  setstatus:
7613                 exitstatus = status;
7614                 break;
7615         }
7616  out:
7617         if ((checkexit & exitstatus))
7618                 evalskip |= SKIPEVAL;
7619         else if (pendingsig && dotrap())
7620                 goto exexit;
7621
7622         if (flags & EV_EXIT) {
7623  exexit:
7624                 raise_exception(EXEXIT);
7625         }
7626 }
7627
7628 #if !defined(__alpha__) || (defined(__GNUC__) && __GNUC__ >= 3)
7629 static
7630 #endif
7631 void evaltreenr(union node *, int) __attribute__ ((alias("evaltree"),__noreturn__));
7632
7633 static int loopnest;            /* current loop nesting level */
7634
7635 static void
7636 evalloop(union node *n, int flags)
7637 {
7638         int status;
7639
7640         loopnest++;
7641         status = 0;
7642         flags &= EV_TESTED;
7643         for (;;) {
7644                 int i;
7645
7646                 evaltree(n->nbinary.ch1, EV_TESTED);
7647                 if (evalskip) {
7648  skipping:
7649                         if (evalskip == SKIPCONT && --skipcount <= 0) {
7650                                 evalskip = 0;
7651                                 continue;
7652                         }
7653                         if (evalskip == SKIPBREAK && --skipcount <= 0)
7654                                 evalskip = 0;
7655                         break;
7656                 }
7657                 i = exitstatus;
7658                 if (n->type != NWHILE)
7659                         i = !i;
7660                 if (i != 0)
7661                         break;
7662                 evaltree(n->nbinary.ch2, flags);
7663                 status = exitstatus;
7664                 if (evalskip)
7665                         goto skipping;
7666         }
7667         loopnest--;
7668         exitstatus = status;
7669 }
7670
7671 static void
7672 evalfor(union node *n, int flags)
7673 {
7674         struct arglist arglist;
7675         union node *argp;
7676         struct strlist *sp;
7677         struct stackmark smark;
7678
7679         setstackmark(&smark);
7680         arglist.lastp = &arglist.list;
7681         for (argp = n->nfor.args; argp; argp = argp->narg.next) {
7682                 expandarg(argp, &arglist, EXP_FULL | EXP_TILDE | EXP_RECORD);
7683                 /* XXX */
7684                 if (evalskip)
7685                         goto out;
7686         }
7687         *arglist.lastp = NULL;
7688
7689         exitstatus = 0;
7690         loopnest++;
7691         flags &= EV_TESTED;
7692         for (sp = arglist.list; sp; sp = sp->next) {
7693                 setvar(n->nfor.var, sp->text, 0);
7694                 evaltree(n->nfor.body, flags);
7695                 if (evalskip) {
7696                         if (evalskip == SKIPCONT && --skipcount <= 0) {
7697                                 evalskip = 0;
7698                                 continue;
7699                         }
7700                         if (evalskip == SKIPBREAK && --skipcount <= 0)
7701                                 evalskip = 0;
7702                         break;
7703                 }
7704         }
7705         loopnest--;
7706  out:
7707         popstackmark(&smark);
7708 }
7709
7710 static void
7711 evalcase(union node *n, int flags)
7712 {
7713         union node *cp;
7714         union node *patp;
7715         struct arglist arglist;
7716         struct stackmark smark;
7717
7718         setstackmark(&smark);
7719         arglist.lastp = &arglist.list;
7720         expandarg(n->ncase.expr, &arglist, EXP_TILDE);
7721         exitstatus = 0;
7722         for (cp = n->ncase.cases; cp && evalskip == 0; cp = cp->nclist.next) {
7723                 for (patp = cp->nclist.pattern; patp; patp = patp->narg.next) {
7724                         if (casematch(patp, arglist.list->text)) {
7725                                 if (evalskip == 0) {
7726                                         evaltree(cp->nclist.body, flags);
7727                                 }
7728                                 goto out;
7729                         }
7730                 }
7731         }
7732  out:
7733         popstackmark(&smark);
7734 }
7735
7736 /*
7737  * Kick off a subshell to evaluate a tree.
7738  */
7739 static void
7740 evalsubshell(union node *n, int flags)
7741 {
7742         struct job *jp;
7743         int backgnd = (n->type == NBACKGND);
7744         int status;
7745
7746         expredir(n->nredir.redirect);
7747         if (!backgnd && flags & EV_EXIT && !trap[0])
7748                 goto nofork;
7749         INT_OFF;
7750         jp = makejob(n, 1);
7751         if (forkshell(jp, n, backgnd) == 0) {
7752                 INT_ON;
7753                 flags |= EV_EXIT;
7754                 if (backgnd)
7755                         flags &=~ EV_TESTED;
7756  nofork:
7757                 redirect(n->nredir.redirect, 0);
7758                 evaltreenr(n->nredir.n, flags);
7759                 /* never returns */
7760         }
7761         status = 0;
7762         if (! backgnd)
7763                 status = waitforjob(jp);
7764         exitstatus = status;
7765         INT_ON;
7766 }
7767
7768 /*
7769  * Compute the names of the files in a redirection list.
7770  */
7771 static void fixredir(union node *, const char *, int);
7772 static void
7773 expredir(union node *n)
7774 {
7775         union node *redir;
7776
7777         for (redir = n; redir; redir = redir->nfile.next) {
7778                 struct arglist fn;
7779
7780                 memset(&fn, 0, sizeof(fn));
7781                 fn.lastp = &fn.list;
7782                 switch (redir->type) {
7783                 case NFROMTO:
7784                 case NFROM:
7785                 case NTO:
7786                 case NCLOBBER:
7787                 case NAPPEND:
7788                         expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR);
7789                         redir->nfile.expfname = fn.list->text;
7790                         break;
7791                 case NFROMFD:
7792                 case NTOFD:
7793                         if (redir->ndup.vname) {
7794                                 expandarg(redir->ndup.vname, &fn, EXP_FULL | EXP_TILDE);
7795                                 if (fn.list == NULL)
7796                                         ash_msg_and_raise_error("redir error");
7797                                 fixredir(redir, fn.list->text, 1);
7798                         }
7799                         break;
7800                 }
7801         }
7802 }
7803
7804 /*
7805  * Evaluate a pipeline.  All the processes in the pipeline are children
7806  * of the process creating the pipeline.  (This differs from some versions
7807  * of the shell, which make the last process in a pipeline the parent
7808  * of all the rest.)
7809  */
7810 static void
7811 evalpipe(union node *n, int flags)
7812 {
7813         struct job *jp;
7814         struct nodelist *lp;
7815         int pipelen;
7816         int prevfd;
7817         int pip[2];
7818
7819         TRACE(("evalpipe(0x%lx) called\n", (long)n));
7820         pipelen = 0;
7821         for (lp = n->npipe.cmdlist; lp; lp = lp->next)
7822                 pipelen++;
7823         flags |= EV_EXIT;
7824         INT_OFF;
7825         jp = makejob(n, pipelen);
7826         prevfd = -1;
7827         for (lp = n->npipe.cmdlist; lp; lp = lp->next) {
7828                 prehash(lp->n);
7829                 pip[1] = -1;
7830                 if (lp->next) {
7831                         if (pipe(pip) < 0) {
7832                                 close(prevfd);
7833                                 ash_msg_and_raise_error("pipe call failed");
7834                         }
7835                 }
7836                 if (forkshell(jp, lp->n, n->npipe.backgnd) == 0) {
7837                         INT_ON;
7838                         if (pip[1] >= 0) {
7839                                 close(pip[0]);
7840                         }
7841                         if (prevfd > 0) {
7842                                 dup2(prevfd, 0);
7843                                 close(prevfd);
7844                         }
7845                         if (pip[1] > 1) {
7846                                 dup2(pip[1], 1);
7847                                 close(pip[1]);
7848                         }
7849                         evaltreenr(lp->n, flags);
7850                         /* never returns */
7851                 }
7852                 if (prevfd >= 0)
7853                         close(prevfd);
7854                 prevfd = pip[0];
7855                 close(pip[1]);
7856         }
7857         if (n->npipe.backgnd == 0) {
7858                 exitstatus = waitforjob(jp);
7859                 TRACE(("evalpipe:  job done exit status %d\n", exitstatus));
7860         }
7861         INT_ON;
7862 }
7863
7864 /*
7865  * Controls whether the shell is interactive or not.
7866  */
7867 static void
7868 setinteractive(int on)
7869 {
7870         static int is_interactive;
7871
7872         if (++on == is_interactive)
7873                 return;
7874         is_interactive = on;
7875         setsignal(SIGINT);
7876         setsignal(SIGQUIT);
7877         setsignal(SIGTERM);
7878 #if !ENABLE_FEATURE_SH_EXTRA_QUIET
7879         if (is_interactive > 1) {
7880                 /* Looks like they want an interactive shell */
7881                 static smallint did_banner;
7882
7883                 if (!did_banner) {
7884                         out1fmt(
7885                                 "\n\n"
7886                                 "%s built-in shell (ash)\n"
7887                                 "Enter 'help' for a list of built-in commands."
7888                                 "\n\n",
7889                                 bb_banner);
7890                         did_banner = 1;
7891                 }
7892         }
7893 #endif
7894 }
7895
7896 #if ENABLE_FEATURE_EDITING_VI
7897 #define setvimode(on) do { \
7898         if (on) line_input_state->flags |= VI_MODE; \
7899         else line_input_state->flags &= ~VI_MODE; \
7900 } while (0)
7901 #else
7902 #define setvimode(on) viflag = 0   /* forcibly keep the option off */
7903 #endif
7904
7905 static void
7906 optschanged(void)
7907 {
7908 #if DEBUG
7909         opentrace();
7910 #endif
7911         setinteractive(iflag);
7912         setjobctl(mflag);
7913         setvimode(viflag);
7914 }
7915
7916 static struct localvar *localvars;
7917
7918 /*
7919  * Called after a function returns.
7920  * Interrupts must be off.
7921  */
7922 static void
7923 poplocalvars(void)
7924 {
7925         struct localvar *lvp;
7926         struct var *vp;
7927
7928         while ((lvp = localvars) != NULL) {
7929                 localvars = lvp->next;
7930                 vp = lvp->vp;
7931                 TRACE(("poplocalvar %s", vp ? vp->text : "-"));
7932                 if (vp == NULL) {       /* $- saved */
7933                         memcpy(optlist, lvp->text, sizeof(optlist));
7934                         free((char*)lvp->text);
7935                         optschanged();
7936                 } else if ((lvp->flags & (VUNSET|VSTRFIXED)) == VUNSET) {
7937                         unsetvar(vp->text);
7938                 } else {
7939                         if (vp->func)
7940                                 (*vp->func)(strchrnul(lvp->text, '=') + 1);
7941                         if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0)
7942                                 free((char*)vp->text);
7943                         vp->flags = lvp->flags;
7944                         vp->text = lvp->text;
7945                 }
7946                 free(lvp);
7947         }
7948 }
7949
7950 static int
7951 evalfun(struct funcnode *func, int argc, char **argv, int flags)
7952 {
7953         volatile struct shparam saveparam;
7954         struct localvar *volatile savelocalvars;
7955         struct jmploc *volatile savehandler;
7956         struct jmploc jmploc;
7957         int e;
7958
7959         saveparam = shellparam;
7960         savelocalvars = localvars;
7961         e = setjmp(jmploc.loc);
7962         if (e) {
7963                 goto funcdone;
7964         }
7965         INT_OFF;
7966         savehandler = exception_handler;
7967         exception_handler = &jmploc;
7968         localvars = NULL;
7969         shellparam.malloced = 0;
7970         func->count++;
7971         funcnest++;
7972         INT_ON;
7973         shellparam.nparam = argc - 1;
7974         shellparam.p = argv + 1;
7975 #if ENABLE_ASH_GETOPTS
7976         shellparam.optind = 1;
7977         shellparam.optoff = -1;
7978 #endif
7979         evaltree(&func->n, flags & EV_TESTED);
7980  funcdone:
7981         INT_OFF;
7982         funcnest--;
7983         freefunc(func);
7984         poplocalvars();
7985         localvars = savelocalvars;
7986         freeparam(&shellparam);
7987         shellparam = saveparam;
7988         exception_handler = savehandler;
7989         INT_ON;
7990         evalskip &= ~SKIPFUNC;
7991         return e;
7992 }
7993
7994 #if ENABLE_ASH_CMDCMD
7995 static char **
7996 parse_command_args(char **argv, const char **path)
7997 {
7998         char *cp, c;
7999
8000         for (;;) {
8001                 cp = *++argv;
8002                 if (!cp)
8003                         return 0;
8004                 if (*cp++ != '-')
8005                         break;
8006                 c = *cp++;
8007                 if (!c)
8008                         break;
8009                 if (c == '-' && !*cp) {
8010                         argv++;
8011                         break;
8012                 }
8013                 do {
8014                         switch (c) {
8015                         case 'p':
8016                                 *path = bb_default_path;
8017                                 break;
8018                         default:
8019                                 /* run 'typecmd' for other options */
8020                                 return 0;
8021                         }
8022                         c = *cp++;
8023                 } while (c);
8024         }
8025         return argv;
8026 }
8027 #endif
8028
8029 /*
8030  * Make a variable a local variable.  When a variable is made local, it's
8031  * value and flags are saved in a localvar structure.  The saved values
8032  * will be restored when the shell function returns.  We handle the name
8033  * "-" as a special case.
8034  */
8035 static void
8036 mklocal(char *name)
8037 {
8038         struct localvar *lvp;
8039         struct var **vpp;
8040         struct var *vp;
8041
8042         INT_OFF;
8043         lvp = ckmalloc(sizeof(struct localvar));
8044         if (LONE_DASH(name)) {
8045                 char *p;
8046                 p = ckmalloc(sizeof(optlist));
8047                 lvp->text = memcpy(p, optlist, sizeof(optlist));
8048                 vp = NULL;
8049         } else {
8050                 char *eq;
8051
8052                 vpp = hashvar(name);
8053                 vp = *findvar(vpp, name);
8054                 eq = strchr(name, '=');
8055                 if (vp == NULL) {
8056                         if (eq)
8057                                 setvareq(name, VSTRFIXED);
8058                         else
8059                                 setvar(name, NULL, VSTRFIXED);
8060                         vp = *vpp;      /* the new variable */
8061                         lvp->flags = VUNSET;
8062                 } else {
8063                         lvp->text = vp->text;
8064                         lvp->flags = vp->flags;
8065                         vp->flags |= VSTRFIXED|VTEXTFIXED;
8066                         if (eq)
8067                                 setvareq(name, 0);
8068                 }
8069         }
8070         lvp->vp = vp;
8071         lvp->next = localvars;
8072         localvars = lvp;
8073         INT_ON;
8074 }
8075
8076 /*
8077  * The "local" command.
8078  */
8079 static int
8080 localcmd(int argc, char **argv)
8081 {
8082         char *name;
8083
8084         argv = argptr;
8085         while ((name = *argv++) != NULL) {
8086                 mklocal(name);
8087         }
8088         return 0;
8089 }
8090
8091 static int
8092 falsecmd(int argc, char **argv)
8093 {
8094         return 1;
8095 }
8096
8097 static int
8098 truecmd(int argc, char **argv)
8099 {
8100         return 0;
8101 }
8102
8103 static int
8104 execcmd(int argc, char **argv)
8105 {
8106         if (argc > 1) {
8107                 iflag = 0;              /* exit on error */
8108                 mflag = 0;
8109                 optschanged();
8110                 shellexec(argv + 1, pathval(), 0);
8111         }
8112         return 0;
8113 }
8114
8115 /*
8116  * The return command.
8117  */
8118 static int
8119 returncmd(int argc, char **argv)
8120 {
8121         /*
8122          * If called outside a function, do what ksh does;
8123          * skip the rest of the file.
8124          */
8125         evalskip = funcnest ? SKIPFUNC : SKIPFILE;
8126         return argv[1] ? number(argv[1]) : exitstatus;
8127 }
8128
8129 /* Forward declarations for builtintab[] */
8130 static int breakcmd(int, char **);
8131 static int dotcmd(int, char **);
8132 static int evalcmd(int, char **);
8133 #if ENABLE_ASH_BUILTIN_ECHO
8134 static int echocmd(int, char **);
8135 #endif
8136 #if ENABLE_ASH_BUILTIN_TEST
8137 static int testcmd(int, char **);
8138 #endif
8139 static int exitcmd(int, char **);
8140 static int exportcmd(int, char **);
8141 #if ENABLE_ASH_GETOPTS
8142 static int getoptscmd(int, char **);
8143 #endif
8144 #if !ENABLE_FEATURE_SH_EXTRA_QUIET
8145 static int helpcmd(int argc, char **argv);
8146 #endif
8147 #if ENABLE_ASH_MATH_SUPPORT
8148 static int letcmd(int, char **);
8149 #endif
8150 static int readcmd(int, char **);
8151 static int setcmd(int, char **);
8152 static int shiftcmd(int, char **);
8153 static int timescmd(int, char **);
8154 static int trapcmd(int, char **);
8155 static int umaskcmd(int, char **);
8156 static int unsetcmd(int, char **);
8157 static int ulimitcmd(int, char **);
8158
8159 #define BUILTIN_NOSPEC          "0"
8160 #define BUILTIN_SPECIAL         "1"
8161 #define BUILTIN_REGULAR         "2"
8162 #define BUILTIN_SPEC_REG        "3"
8163 #define BUILTIN_ASSIGN          "4"
8164 #define BUILTIN_SPEC_ASSG       "5"
8165 #define BUILTIN_REG_ASSG        "6"
8166 #define BUILTIN_SPEC_REG_ASSG   "7"
8167
8168 /* make sure to keep these in proper order since it is searched via bsearch() */
8169 static const struct builtincmd builtintab[] = {
8170         { BUILTIN_SPEC_REG      ".", dotcmd },
8171         { BUILTIN_SPEC_REG      ":", truecmd },
8172 #if ENABLE_ASH_BUILTIN_TEST
8173         { BUILTIN_REGULAR       "[", testcmd },
8174         { BUILTIN_REGULAR       "[[", testcmd },
8175 #endif
8176 #if ENABLE_ASH_ALIAS
8177         { BUILTIN_REG_ASSG      "alias", aliascmd },
8178 #endif
8179 #if JOBS
8180         { BUILTIN_REGULAR       "bg", fg_bgcmd },
8181 #endif
8182         { BUILTIN_SPEC_REG      "break", breakcmd },
8183         { BUILTIN_REGULAR       "cd", cdcmd },
8184         { BUILTIN_NOSPEC        "chdir", cdcmd },
8185 #if ENABLE_ASH_CMDCMD
8186         { BUILTIN_REGULAR       "command", commandcmd },
8187 #endif
8188         { BUILTIN_SPEC_REG      "continue", breakcmd },
8189 #if ENABLE_ASH_BUILTIN_ECHO
8190         { BUILTIN_REGULAR       "echo", echocmd },
8191 #endif
8192         { BUILTIN_SPEC_REG      "eval", evalcmd },
8193         { BUILTIN_SPEC_REG      "exec", execcmd },
8194         { BUILTIN_SPEC_REG      "exit", exitcmd },
8195         { BUILTIN_SPEC_REG_ASSG "export", exportcmd },
8196         { BUILTIN_REGULAR       "false", falsecmd },
8197 #if JOBS
8198         { BUILTIN_REGULAR       "fg", fg_bgcmd },
8199 #endif
8200 #if ENABLE_ASH_GETOPTS
8201         { BUILTIN_REGULAR       "getopts", getoptscmd },
8202 #endif
8203         { BUILTIN_NOSPEC        "hash", hashcmd },
8204 #if !ENABLE_FEATURE_SH_EXTRA_QUIET
8205         { BUILTIN_NOSPEC        "help", helpcmd },
8206 #endif
8207 #if JOBS
8208         { BUILTIN_REGULAR       "jobs", jobscmd },
8209         { BUILTIN_REGULAR       "kill", killcmd },
8210 #endif
8211 #if ENABLE_ASH_MATH_SUPPORT
8212         { BUILTIN_NOSPEC        "let", letcmd },
8213 #endif
8214         { BUILTIN_ASSIGN        "local", localcmd },
8215         { BUILTIN_NOSPEC        "pwd", pwdcmd },
8216         { BUILTIN_REGULAR       "read", readcmd },
8217         { BUILTIN_SPEC_REG_ASSG "readonly", exportcmd },
8218         { BUILTIN_SPEC_REG      "return", returncmd },
8219         { BUILTIN_SPEC_REG      "set", setcmd },
8220         { BUILTIN_SPEC_REG      "shift", shiftcmd },
8221         { BUILTIN_SPEC_REG      "source", dotcmd },
8222 #if ENABLE_ASH_BUILTIN_TEST
8223         { BUILTIN_REGULAR       "test", testcmd },
8224 #endif
8225         { BUILTIN_SPEC_REG      "times", timescmd },
8226         { BUILTIN_SPEC_REG      "trap", trapcmd },
8227         { BUILTIN_REGULAR       "true", truecmd },
8228         { BUILTIN_NOSPEC        "type", typecmd },
8229         { BUILTIN_NOSPEC        "ulimit", ulimitcmd },
8230         { BUILTIN_REGULAR       "umask", umaskcmd },
8231 #if ENABLE_ASH_ALIAS
8232         { BUILTIN_REGULAR       "unalias", unaliascmd },
8233 #endif
8234         { BUILTIN_SPEC_REG      "unset", unsetcmd },
8235         { BUILTIN_REGULAR       "wait", waitcmd },
8236 };
8237
8238
8239 #define COMMANDCMD (builtintab + 5 + \
8240         2 * ENABLE_ASH_BUILTIN_TEST + \
8241         ENABLE_ASH_ALIAS + \
8242         ENABLE_ASH_JOB_CONTROL)
8243 #define EXECCMD (builtintab + 7 + \
8244         2 * ENABLE_ASH_BUILTIN_TEST + \
8245         ENABLE_ASH_ALIAS + \
8246         ENABLE_ASH_JOB_CONTROL + \
8247         ENABLE_ASH_CMDCMD + \
8248         ENABLE_ASH_BUILTIN_ECHO)
8249
8250 /*
8251  * Search the table of builtin commands.
8252  */
8253 static struct builtincmd *
8254 find_builtin(const char *name)
8255 {
8256         struct builtincmd *bp;
8257
8258         bp = bsearch(
8259                 name, builtintab, ARRAY_SIZE(builtintab), sizeof(builtintab[0]),
8260                 pstrcmp
8261         );
8262         return bp;
8263 }
8264
8265 /*
8266  * Execute a simple command.
8267  */
8268 static int back_exitstatus; /* exit status of backquoted command */
8269 static int
8270 isassignment(const char *p)
8271 {
8272         const char *q = endofname(p);
8273         if (p == q)
8274                 return 0;
8275         return *q == '=';
8276 }
8277 static int
8278 bltincmd(int argc, char **argv)
8279 {
8280         /* Preserve exitstatus of a previous possible redirection
8281          * as POSIX mandates */
8282         return back_exitstatus;
8283 }
8284 static void
8285 evalcommand(union node *cmd, int flags)
8286 {
8287         static const struct builtincmd null_bltin = {
8288                 "\0\0", bltincmd /* why three NULs? */
8289         };
8290         struct stackmark smark;
8291         union node *argp;
8292         struct arglist arglist;
8293         struct arglist varlist;
8294         char **argv;
8295         int argc;
8296         const struct strlist *sp;
8297         struct cmdentry cmdentry;
8298         struct job *jp;
8299         char *lastarg;
8300         const char *path;
8301         int spclbltin;
8302         int cmd_is_exec;
8303         int status;
8304         char **nargv;
8305         struct builtincmd *bcmd;
8306         int pseudovarflag = 0;
8307
8308         /* First expand the arguments. */
8309         TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags));
8310         setstackmark(&smark);
8311         back_exitstatus = 0;
8312
8313         cmdentry.cmdtype = CMDBUILTIN;
8314         cmdentry.u.cmd = &null_bltin;
8315         varlist.lastp = &varlist.list;
8316         *varlist.lastp = NULL;
8317         arglist.lastp = &arglist.list;
8318         *arglist.lastp = NULL;
8319
8320         argc = 0;
8321         if (cmd->ncmd.args) {
8322                 bcmd = find_builtin(cmd->ncmd.args->narg.text);
8323                 pseudovarflag = bcmd && IS_BUILTIN_ASSIGN(bcmd);
8324         }
8325
8326         for (argp = cmd->ncmd.args; argp; argp = argp->narg.next) {
8327                 struct strlist **spp;
8328
8329                 spp = arglist.lastp;
8330                 if (pseudovarflag && isassignment(argp->narg.text))
8331                         expandarg(argp, &arglist, EXP_VARTILDE);
8332                 else
8333                         expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
8334
8335                 for (sp = *spp; sp; sp = sp->next)
8336                         argc++;
8337         }
8338
8339         argv = nargv = stalloc(sizeof(char *) * (argc + 1));
8340         for (sp = arglist.list; sp; sp = sp->next) {
8341                 TRACE(("evalcommand arg: %s\n", sp->text));
8342                 *nargv++ = sp->text;
8343         }
8344         *nargv = NULL;
8345
8346         lastarg = NULL;
8347         if (iflag && funcnest == 0 && argc > 0)
8348                 lastarg = nargv[-1];
8349
8350         preverrout_fd = 2;
8351         expredir(cmd->ncmd.redirect);
8352         status = redirectsafe(cmd->ncmd.redirect, REDIR_PUSH | REDIR_SAVEFD2);
8353
8354         path = vpath.text;
8355         for (argp = cmd->ncmd.assign; argp; argp = argp->narg.next) {
8356                 struct strlist **spp;
8357                 char *p;
8358
8359                 spp = varlist.lastp;
8360                 expandarg(argp, &varlist, EXP_VARTILDE);
8361
8362                 /*
8363                  * Modify the command lookup path, if a PATH= assignment
8364                  * is present
8365                  */
8366                 p = (*spp)->text;
8367                 if (varequal(p, path))
8368                         path = p;
8369         }
8370
8371         /* Print the command if xflag is set. */
8372         if (xflag) {
8373                 int n;
8374                 const char *p = " %s";
8375
8376                 p++;
8377                 fdprintf(preverrout_fd, p, expandstr(ps4val()));
8378
8379                 sp = varlist.list;
8380                 for (n = 0; n < 2; n++) {
8381                         while (sp) {
8382                                 fdprintf(preverrout_fd, p, sp->text);
8383                                 sp = sp->next;
8384                                 if (*p == '%') {
8385                                         p--;
8386                                 }
8387                         }
8388                         sp = arglist.list;
8389                 }
8390                 safe_write(preverrout_fd, "\n", 1);
8391         }
8392
8393         cmd_is_exec = 0;
8394         spclbltin = -1;
8395
8396         /* Now locate the command. */
8397         if (argc) {
8398                 const char *oldpath;
8399                 int cmd_flag = DO_ERR;
8400
8401                 path += 5;
8402                 oldpath = path;
8403                 for (;;) {
8404                         find_command(argv[0], &cmdentry, cmd_flag, path);
8405                         if (cmdentry.cmdtype == CMDUNKNOWN) {
8406                                 status = 127;
8407                                 flush_stderr();
8408                                 goto bail;
8409                         }
8410
8411                         /* implement bltin and command here */
8412                         if (cmdentry.cmdtype != CMDBUILTIN)
8413                                 break;
8414                         if (spclbltin < 0)
8415                                 spclbltin = IS_BUILTIN_SPECIAL(cmdentry.u.cmd);
8416                         if (cmdentry.u.cmd == EXECCMD)
8417                                 cmd_is_exec++;
8418 #if ENABLE_ASH_CMDCMD
8419                         if (cmdentry.u.cmd == COMMANDCMD) {
8420                                 path = oldpath;
8421                                 nargv = parse_command_args(argv, &path);
8422                                 if (!nargv)
8423                                         break;
8424                                 argc -= nargv - argv;
8425                                 argv = nargv;
8426                                 cmd_flag |= DO_NOFUNC;
8427                         } else
8428 #endif
8429                                 break;
8430                 }
8431         }
8432
8433         if (status) {
8434                 /* We have a redirection error. */
8435                 if (spclbltin > 0)
8436                         raise_exception(EXERROR);
8437  bail:
8438                 exitstatus = status;
8439                 goto out;
8440         }
8441
8442         /* Execute the command. */
8443         switch (cmdentry.cmdtype) {
8444         default:
8445                 /* Fork off a child process if necessary. */
8446                 if (!(flags & EV_EXIT) || trap[0]) {
8447                         INT_OFF;
8448                         jp = makejob(cmd, 1);
8449                         if (forkshell(jp, cmd, FORK_FG) != 0) {
8450                                 exitstatus = waitforjob(jp);
8451                                 INT_ON;
8452                                 break;
8453                         }
8454                         FORCE_INT_ON;
8455                 }
8456                 listsetvar(varlist.list, VEXPORT|VSTACK);
8457                 shellexec(argv, path, cmdentry.u.index);
8458                 /* NOTREACHED */
8459
8460         case CMDBUILTIN:
8461                 cmdenviron = varlist.list;
8462                 if (cmdenviron) {
8463                         struct strlist *list = cmdenviron;
8464                         int i = VNOSET;
8465                         if (spclbltin > 0 || argc == 0) {
8466                                 i = 0;
8467                                 if (cmd_is_exec && argc > 1)
8468                                         i = VEXPORT;
8469                         }
8470                         listsetvar(list, i);
8471                 }
8472                 if (evalbltin(cmdentry.u.cmd, argc, argv)) {
8473                         int exit_status;
8474                         int i = exception;
8475                         if (i == EXEXIT)
8476                                 goto raise;
8477                         exit_status = 2;
8478                         if (i == EXINT)
8479                                 exit_status = 128 + SIGINT;
8480                         if (i == EXSIG)
8481                                 exit_status = 128 + pendingsig;
8482                         exitstatus = exit_status;
8483                         if (i == EXINT || spclbltin > 0) {
8484  raise:
8485                                 longjmp(exception_handler->loc, 1);
8486                         }
8487                         FORCE_INT_ON;
8488                 }
8489                 break;
8490
8491         case CMDFUNCTION:
8492                 listsetvar(varlist.list, 0);
8493                 if (evalfun(cmdentry.u.func, argc, argv, flags))
8494                         goto raise;
8495                 break;
8496         }
8497
8498  out:
8499         popredir(cmd_is_exec);
8500         if (lastarg)
8501                 /* dsl: I think this is intended to be used to support
8502                  * '_' in 'vi' command mode during line editing...
8503                  * However I implemented that within libedit itself.
8504                  */
8505                 setvar("_", lastarg, 0);
8506         popstackmark(&smark);
8507 }
8508
8509 static int
8510 evalbltin(const struct builtincmd *cmd, int argc, char **argv)
8511 {
8512         char *volatile savecmdname;
8513         struct jmploc *volatile savehandler;
8514         struct jmploc jmploc;
8515         int i;
8516
8517         savecmdname = commandname;
8518         i = setjmp(jmploc.loc);
8519         if (i)
8520                 goto cmddone;
8521         savehandler = exception_handler;
8522         exception_handler = &jmploc;
8523         commandname = argv[0];
8524         argptr = argv + 1;
8525         optptr = NULL;                  /* initialize nextopt */
8526         exitstatus = (*cmd->builtin)(argc, argv);
8527         flush_stdout_stderr();
8528  cmddone:
8529         exitstatus |= ferror(stdout);
8530         clearerr(stdout);
8531         commandname = savecmdname;
8532 //      exsig = 0;
8533         exception_handler = savehandler;
8534
8535         return i;
8536 }
8537
8538 static int
8539 goodname(const char *p)
8540 {
8541         return !*endofname(p);
8542 }
8543
8544
8545 /*
8546  * Search for a command.  This is called before we fork so that the
8547  * location of the command will be available in the parent as well as
8548  * the child.  The check for "goodname" is an overly conservative
8549  * check that the name will not be subject to expansion.
8550  */
8551 static void
8552 prehash(union node *n)
8553 {
8554         struct cmdentry entry;
8555
8556         if (n->type == NCMD && n->ncmd.args && goodname(n->ncmd.args->narg.text))
8557                 find_command(n->ncmd.args->narg.text, &entry, 0, pathval());
8558 }
8559
8560
8561 /* ============ Builtin commands
8562  *
8563  * Builtin commands whose functions are closely tied to evaluation
8564  * are implemented here.
8565  */
8566
8567 /*
8568  * Handle break and continue commands.  Break, continue, and return are
8569  * all handled by setting the evalskip flag.  The evaluation routines
8570  * above all check this flag, and if it is set they start skipping
8571  * commands rather than executing them.  The variable skipcount is
8572  * the number of loops to break/continue, or the number of function
8573  * levels to return.  (The latter is always 1.)  It should probably
8574  * be an error to break out of more loops than exist, but it isn't
8575  * in the standard shell so we don't make it one here.
8576  */
8577 static int
8578 breakcmd(int argc, char **argv)
8579 {
8580         int n = argc > 1 ? number(argv[1]) : 1;
8581
8582         if (n <= 0)
8583                 ash_msg_and_raise_error(illnum, argv[1]);
8584         if (n > loopnest)
8585                 n = loopnest;
8586         if (n > 0) {
8587                 evalskip = (**argv == 'c') ? SKIPCONT : SKIPBREAK;
8588                 skipcount = n;
8589         }
8590         return 0;
8591 }
8592
8593
8594 /* ============ input.c
8595  *
8596  * This implements the input routines used by the parser.
8597  */
8598
8599 #define EOF_NLEFT -99           /* value of parsenleft when EOF pushed back */
8600
8601 enum {
8602         INPUT_PUSH_FILE = 1,
8603         INPUT_NOFILE_OK = 2,
8604 };
8605
8606 static int plinno = 1;                  /* input line number */
8607 /* number of characters left in input buffer */
8608 static int parsenleft;                  /* copy of parsefile->nleft */
8609 static int parselleft;                  /* copy of parsefile->lleft */
8610 /* next character in input buffer */
8611 static char *parsenextc;                /* copy of parsefile->nextc */
8612
8613 static int checkkwd;
8614 /* values of checkkwd variable */
8615 #define CHKALIAS        0x1
8616 #define CHKKWD          0x2
8617 #define CHKNL           0x4
8618
8619 static void
8620 popstring(void)
8621 {
8622         struct strpush *sp = parsefile->strpush;
8623
8624         INT_OFF;
8625 #if ENABLE_ASH_ALIAS
8626         if (sp->ap) {
8627                 if (parsenextc[-1] == ' ' || parsenextc[-1] == '\t') {
8628                         checkkwd |= CHKALIAS;
8629                 }
8630                 if (sp->string != sp->ap->val) {
8631                         free(sp->string);
8632                 }
8633                 sp->ap->flag &= ~ALIASINUSE;
8634                 if (sp->ap->flag & ALIASDEAD) {
8635                         unalias(sp->ap->name);
8636                 }
8637         }
8638 #endif
8639         parsenextc = sp->prevstring;
8640         parsenleft = sp->prevnleft;
8641 /*dprintf("*** calling popstring: restoring to '%s'\n", parsenextc);*/
8642         parsefile->strpush = sp->prev;
8643         if (sp != &(parsefile->basestrpush))
8644                 free(sp);
8645         INT_ON;
8646 }
8647
8648 static int
8649 preadfd(void)
8650 {
8651         int nr;
8652         char *buf =  parsefile->buf;
8653         parsenextc = buf;
8654
8655  retry:
8656 #if ENABLE_FEATURE_EDITING
8657         if (!iflag || parsefile->fd)
8658                 nr = safe_read(parsefile->fd, buf, BUFSIZ - 1);
8659         else {
8660 #if ENABLE_FEATURE_TAB_COMPLETION
8661                 line_input_state->path_lookup = pathval();
8662 #endif
8663                 nr = read_line_input(cmdedit_prompt, buf, BUFSIZ, line_input_state);
8664                 if (nr == 0) {
8665                         /* Ctrl+C pressed */
8666                         if (trap[SIGINT]) {
8667                                 buf[0] = '\n';
8668                                 buf[1] = '\0';
8669                                 raise(SIGINT);
8670                                 return 1;
8671                         }
8672                         goto retry;
8673                 }
8674                 if (nr < 0 && errno == 0) {
8675                         /* Ctrl+D pressed */
8676                         nr = 0;
8677                 }
8678         }
8679 #else
8680         nr = safe_read(parsefile->fd, buf, BUFSIZ - 1);
8681 #endif
8682
8683         if (nr < 0) {
8684                 if (parsefile->fd == 0 && errno == EWOULDBLOCK) {
8685                         int flags = fcntl(0, F_GETFL);
8686                         if (flags >= 0 && (flags & O_NONBLOCK)) {
8687                                 flags &= ~O_NONBLOCK;
8688                                 if (fcntl(0, F_SETFL, flags) >= 0) {
8689                                         out2str("sh: turning off NDELAY mode\n");
8690                                         goto retry;
8691                                 }
8692                         }
8693                 }
8694         }
8695         return nr;
8696 }
8697
8698 /*
8699  * Refill the input buffer and return the next input character:
8700  *
8701  * 1) If a string was pushed back on the input, pop it;
8702  * 2) If an EOF was pushed back (parsenleft == EOF_NLEFT) or we are reading
8703  *    from a string so we can't refill the buffer, return EOF.
8704  * 3) If the is more stuff in this buffer, use it else call read to fill it.
8705  * 4) Process input up to the next newline, deleting nul characters.
8706  */
8707 static int
8708 preadbuffer(void)
8709 {
8710         char *q;
8711         int more;
8712         char savec;
8713
8714         while (parsefile->strpush) {
8715 #if ENABLE_ASH_ALIAS
8716                 if (parsenleft == -1 && parsefile->strpush->ap &&
8717                         parsenextc[-1] != ' ' && parsenextc[-1] != '\t') {
8718                         return PEOA;
8719                 }
8720 #endif
8721                 popstring();
8722                 if (--parsenleft >= 0)
8723                         return signed_char2int(*parsenextc++);
8724         }
8725         if (parsenleft == EOF_NLEFT || parsefile->buf == NULL)
8726                 return PEOF;
8727         flush_stdout_stderr();
8728
8729         more = parselleft;
8730         if (more <= 0) {
8731  again:
8732                 more = preadfd();
8733                 if (more <= 0) {
8734                         parselleft = parsenleft = EOF_NLEFT;
8735                         return PEOF;
8736                 }
8737         }
8738
8739         q = parsenextc;
8740
8741         /* delete nul characters */
8742         for (;;) {
8743                 int c;
8744
8745                 more--;
8746                 c = *q;
8747
8748                 if (!c)
8749                         memmove(q, q + 1, more);
8750                 else {
8751                         q++;
8752                         if (c == '\n') {
8753                                 parsenleft = q - parsenextc - 1;
8754                                 break;
8755                         }
8756                 }
8757
8758                 if (more <= 0) {
8759                         parsenleft = q - parsenextc - 1;
8760                         if (parsenleft < 0)
8761                                 goto again;
8762                         break;
8763                 }
8764         }
8765         parselleft = more;
8766
8767         savec = *q;
8768         *q = '\0';
8769
8770         if (vflag) {
8771                 out2str(parsenextc);
8772         }
8773
8774         *q = savec;
8775
8776         return signed_char2int(*parsenextc++);
8777 }
8778
8779 #define pgetc_as_macro() (--parsenleft >= 0? signed_char2int(*parsenextc++) : preadbuffer())
8780 static int
8781 pgetc(void)
8782 {
8783         return pgetc_as_macro();
8784 }
8785
8786 #if ENABLE_ASH_OPTIMIZE_FOR_SIZE
8787 #define pgetc_macro() pgetc()
8788 #else
8789 #define pgetc_macro() pgetc_as_macro()
8790 #endif
8791
8792 /*
8793  * Same as pgetc(), but ignores PEOA.
8794  */
8795 #if ENABLE_ASH_ALIAS
8796 static int
8797 pgetc2(void)
8798 {
8799         int c;
8800
8801         do {
8802                 c = pgetc_macro();
8803         } while (c == PEOA);
8804         return c;
8805 }
8806 #else
8807 static int
8808 pgetc2(void)
8809 {
8810         return pgetc_macro();
8811 }
8812 #endif
8813
8814 /*
8815  * Read a line from the script.
8816  */
8817 static char *
8818 pfgets(char *line, int len)
8819 {
8820         char *p = line;
8821         int nleft = len;
8822         int c;
8823
8824         while (--nleft > 0) {
8825                 c = pgetc2();
8826                 if (c == PEOF) {
8827                         if (p == line)
8828                                 return NULL;
8829                         break;
8830                 }
8831                 *p++ = c;
8832                 if (c == '\n')
8833                         break;
8834         }
8835         *p = '\0';
8836         return line;
8837 }
8838
8839 /*
8840  * Undo the last call to pgetc.  Only one character may be pushed back.
8841  * PEOF may be pushed back.
8842  */
8843 static void
8844 pungetc(void)
8845 {
8846         parsenleft++;
8847         parsenextc--;
8848 }
8849
8850 /*
8851  * Push a string back onto the input at this current parsefile level.
8852  * We handle aliases this way.
8853  */
8854 static void
8855 pushstring(char *s, void *ap)
8856 {
8857         struct strpush *sp;
8858         size_t len;
8859
8860         len = strlen(s);
8861         INT_OFF;
8862 /*dprintf("*** calling pushstring: %s, %d\n", s, len);*/
8863         if (parsefile->strpush) {
8864                 sp = ckmalloc(sizeof(struct strpush));
8865                 sp->prev = parsefile->strpush;
8866                 parsefile->strpush = sp;
8867         } else
8868                 sp = parsefile->strpush = &(parsefile->basestrpush);
8869         sp->prevstring = parsenextc;
8870         sp->prevnleft = parsenleft;
8871 #if ENABLE_ASH_ALIAS
8872         sp->ap = (struct alias *)ap;
8873         if (ap) {
8874                 ((struct alias *)ap)->flag |= ALIASINUSE;
8875                 sp->string = s;
8876         }
8877 #endif
8878         parsenextc = s;
8879         parsenleft = len;
8880         INT_ON;
8881 }
8882
8883 /*
8884  * To handle the "." command, a stack of input files is used.  Pushfile
8885  * adds a new entry to the stack and popfile restores the previous level.
8886  */
8887 static void
8888 pushfile(void)
8889 {
8890         struct parsefile *pf;
8891
8892         parsefile->nleft = parsenleft;
8893         parsefile->lleft = parselleft;
8894         parsefile->nextc = parsenextc;
8895         parsefile->linno = plinno;
8896         pf = ckmalloc(sizeof(*pf));
8897         pf->prev = parsefile;
8898         pf->fd = -1;
8899         pf->strpush = NULL;
8900         pf->basestrpush.prev = NULL;
8901         parsefile = pf;
8902 }
8903
8904 static void
8905 popfile(void)
8906 {
8907         struct parsefile *pf = parsefile;
8908
8909         INT_OFF;
8910         if (pf->fd >= 0)
8911                 close(pf->fd);
8912         free(pf->buf);
8913         while (pf->strpush)
8914                 popstring();
8915         parsefile = pf->prev;
8916         free(pf);
8917         parsenleft = parsefile->nleft;
8918         parselleft = parsefile->lleft;
8919         parsenextc = parsefile->nextc;
8920         plinno = parsefile->linno;
8921         INT_ON;
8922 }
8923
8924 /*
8925  * Return to top level.
8926  */
8927 static void
8928 popallfiles(void)
8929 {
8930         while (parsefile != &basepf)
8931                 popfile();
8932 }
8933
8934 /*
8935  * Close the file(s) that the shell is reading commands from.  Called
8936  * after a fork is done.
8937  */
8938 static void
8939 closescript(void)
8940 {
8941         popallfiles();
8942         if (parsefile->fd > 0) {
8943                 close(parsefile->fd);
8944                 parsefile->fd = 0;
8945         }
8946 }
8947
8948 /*
8949  * Like setinputfile, but takes an open file descriptor.  Call this with
8950  * interrupts off.
8951  */
8952 static void
8953 setinputfd(int fd, int push)
8954 {
8955         close_on_exec_on(fd);
8956         if (push) {
8957                 pushfile();
8958                 parsefile->buf = 0;
8959         }
8960         parsefile->fd = fd;
8961         if (parsefile->buf == NULL)
8962                 parsefile->buf = ckmalloc(IBUFSIZ);
8963         parselleft = parsenleft = 0;
8964         plinno = 1;
8965 }
8966
8967 /*
8968  * Set the input to take input from a file.  If push is set, push the
8969  * old input onto the stack first.
8970  */
8971 static int
8972 setinputfile(const char *fname, int flags)
8973 {
8974         int fd;
8975         int fd2;
8976
8977         INT_OFF;
8978         fd = open(fname, O_RDONLY);
8979         if (fd < 0) {
8980                 if (flags & INPUT_NOFILE_OK)
8981                         goto out;
8982                 ash_msg_and_raise_error("can't open %s", fname);
8983         }
8984         if (fd < 10) {
8985                 fd2 = copyfd(fd, 10);
8986                 close(fd);
8987                 if (fd2 < 0)
8988                         ash_msg_and_raise_error("out of file descriptors");
8989                 fd = fd2;
8990         }
8991         setinputfd(fd, flags & INPUT_PUSH_FILE);
8992  out:
8993         INT_ON;
8994         return fd;
8995 }
8996
8997 /*
8998  * Like setinputfile, but takes input from a string.
8999  */
9000 static void
9001 setinputstring(char *string)
9002 {
9003         INT_OFF;
9004         pushfile();
9005         parsenextc = string;
9006         parsenleft = strlen(string);
9007         parsefile->buf = NULL;
9008         plinno = 1;
9009         INT_ON;
9010 }
9011
9012
9013 /* ============ mail.c
9014  *
9015  * Routines to check for mail.
9016  */
9017
9018 #if ENABLE_ASH_MAIL
9019
9020 #define MAXMBOXES 10
9021
9022 /* times of mailboxes */
9023 static time_t mailtime[MAXMBOXES];
9024 /* Set if MAIL or MAILPATH is changed. */
9025 static smallint mail_var_path_changed;
9026
9027 /*
9028  * Print appropriate message(s) if mail has arrived.
9029  * If mail_var_path_changed is set,
9030  * then the value of MAIL has mail_var_path_changed,
9031  * so we just update the values.
9032  */
9033 static void
9034 chkmail(void)
9035 {
9036         const char *mpath;
9037         char *p;
9038         char *q;
9039         time_t *mtp;
9040         struct stackmark smark;
9041         struct stat statb;
9042
9043         setstackmark(&smark);
9044         mpath = mpathset() ? mpathval() : mailval();
9045         for (mtp = mailtime; mtp < mailtime + MAXMBOXES; mtp++) {
9046                 p = padvance(&mpath, nullstr);
9047                 if (p == NULL)
9048                         break;
9049                 if (*p == '\0')
9050                         continue;
9051                 for (q = p; *q; q++);
9052 #if DEBUG
9053                 if (q[-1] != '/')
9054                         abort();
9055 #endif
9056                 q[-1] = '\0';                   /* delete trailing '/' */
9057                 if (stat(p, &statb) < 0) {
9058                         *mtp = 0;
9059                         continue;
9060                 }
9061                 if (!mail_var_path_changed && statb.st_mtime != *mtp) {
9062                         fprintf(
9063                                 stderr, snlfmt,
9064                                 pathopt ? pathopt : "you have mail"
9065                         );
9066                 }
9067                 *mtp = statb.st_mtime;
9068         }
9069         mail_var_path_changed = 0;
9070         popstackmark(&smark);
9071 }
9072
9073 static void
9074 changemail(const char *val)
9075 {
9076         mail_var_path_changed = 1;
9077 }
9078
9079 #endif /* ASH_MAIL */
9080
9081
9082 /* ============ ??? */
9083
9084 /*
9085  * Set the shell parameters.
9086  */
9087 static void
9088 setparam(char **argv)
9089 {
9090         char **newparam;
9091         char **ap;
9092         int nparam;
9093
9094         for (nparam = 0; argv[nparam]; nparam++);
9095         ap = newparam = ckmalloc((nparam + 1) * sizeof(*ap));
9096         while (*argv) {
9097                 *ap++ = ckstrdup(*argv++);
9098         }
9099         *ap = NULL;
9100         freeparam(&shellparam);
9101         shellparam.malloced = 1;
9102         shellparam.nparam = nparam;
9103         shellparam.p = newparam;
9104 #if ENABLE_ASH_GETOPTS
9105         shellparam.optind = 1;
9106         shellparam.optoff = -1;
9107 #endif
9108 }
9109
9110 /*
9111  * Process shell options.  The global variable argptr contains a pointer
9112  * to the argument list; we advance it past the options.
9113  *
9114  * SUSv3 section 2.8.1 "Consequences of Shell Errors" says:
9115  * For a non-interactive shell, an error condition encountered
9116  * by a special built-in ... shall cause the shell to write a diagnostic message
9117  * to standard error and exit as shown in the following table:
9118  * Error                                           Special Built-In 
9119  * ...
9120  * Utility syntax error (option or operand error)  Shall exit
9121  * ...
9122  * However, in bug 1142 (http://busybox.net/bugs/view.php?id=1142)
9123  * we see that bash does not do that (set "finishes" with error code 1 instead,
9124  * and shell continues), and people rely on this behavior!
9125  * Testcase:
9126  * set -o barfoo 2>/dev/null
9127  * echo $?
9128  *
9129  * Oh well. Let's mimic that.
9130  */
9131 static int
9132 minus_o(char *name, int val)
9133 {
9134         int i;
9135
9136         if (name) {
9137                 for (i = 0; i < NOPTS; i++) {
9138                         if (strcmp(name, optnames(i)) == 0) {
9139                                 optlist[i] = val;
9140                                 return 0;
9141                         }
9142                 }
9143                 ash_msg("illegal option -o %s", name);
9144                 return 1;
9145         }
9146         out1str("Current option settings\n");
9147         for (i = 0; i < NOPTS; i++)
9148                 out1fmt("%-16s%s\n", optnames(i),
9149                                 optlist[i] ? "on" : "off");
9150         return 0;
9151 }
9152 static void
9153 setoption(int flag, int val)
9154 {
9155         int i;
9156
9157         for (i = 0; i < NOPTS; i++) {
9158                 if (optletters(i) == flag) {
9159                         optlist[i] = val;
9160                         return;
9161                 }
9162         }
9163         ash_msg_and_raise_error("illegal option -%c", flag);
9164         /* NOTREACHED */
9165 }
9166 static int
9167 options(int cmdline)
9168 {
9169         char *p;
9170         int val;
9171         int c;
9172
9173         if (cmdline)
9174                 minusc = NULL;
9175         while ((p = *argptr) != NULL) {
9176                 c = *p++;
9177                 if (c != '-' && c != '+')
9178                         break;
9179                 argptr++;
9180                 val = 0; /* val = 0 if c == '+' */
9181                 if (c == '-') {
9182                         val = 1;
9183                         if (p[0] == '\0' || LONE_DASH(p)) {
9184                                 if (!cmdline) {
9185                                         /* "-" means turn off -x and -v */
9186                                         if (p[0] == '\0')
9187                                                 xflag = vflag = 0;
9188                                         /* "--" means reset params */
9189                                         else if (*argptr == NULL)
9190                                                 setparam(argptr);
9191                                 }
9192                                 break;    /* "-" or  "--" terminates options */
9193                         }
9194                 }
9195                 /* first char was + or - */
9196                 while ((c = *p++) != '\0') {
9197                         /* bash 3.2 indeed handles -c CMD and +c CMD the same */
9198                         if (c == 'c' && cmdline) {
9199                                 minusc = p;     /* command is after shell args */
9200                         } else if (c == 'o') {
9201                                 if (minus_o(*argptr, val)) {
9202                                         /* it already printed err message */
9203                                         return 1; /* error */
9204                                 }
9205                                 if (*argptr)
9206                                         argptr++;
9207                         } else if (cmdline && (c == 'l')) { /* -l or +l == --login */
9208                                 isloginsh = 1;
9209                         /* bash does not accept +-login, we also won't */
9210                         } else if (cmdline && val && (c == '-')) { /* long options */
9211                                 if (strcmp(p, "login") == 0)
9212                                         isloginsh = 1;
9213                                 break;
9214                         } else {
9215                                 setoption(c, val);
9216                         }
9217                 }
9218         }
9219         return 0;
9220 }
9221
9222 /*
9223  * The shift builtin command.
9224  */
9225 static int
9226 shiftcmd(int argc, char **argv)
9227 {
9228         int n;
9229         char **ap1, **ap2;
9230
9231         n = 1;
9232         if (argc > 1)
9233                 n = number(argv[1]);
9234         if (n > shellparam.nparam)
9235                 ash_msg_and_raise_error("can't shift that many");
9236         INT_OFF;
9237         shellparam.nparam -= n;
9238         for (ap1 = shellparam.p; --n >= 0; ap1++) {
9239                 if (shellparam.malloced)
9240                         free(*ap1);
9241         }
9242         ap2 = shellparam.p;
9243         while ((*ap2++ = *ap1++) != NULL);
9244 #if ENABLE_ASH_GETOPTS
9245         shellparam.optind = 1;
9246         shellparam.optoff = -1;
9247 #endif
9248         INT_ON;
9249         return 0;
9250 }
9251
9252 /*
9253  * POSIX requires that 'set' (but not export or readonly) output the
9254  * variables in lexicographic order - by the locale's collating order (sigh).
9255  * Maybe we could keep them in an ordered balanced binary tree
9256  * instead of hashed lists.
9257  * For now just roll 'em through qsort for printing...
9258  */
9259 static int
9260 showvars(const char *sep_prefix, int on, int off)
9261 {
9262         const char *sep;
9263         char **ep, **epend;
9264
9265         ep = listvars(on, off, &epend);
9266         qsort(ep, epend - ep, sizeof(char *), vpcmp);
9267
9268         sep = *sep_prefix ? " " : sep_prefix;
9269
9270         for (; ep < epend; ep++) {
9271                 const char *p;
9272                 const char *q;
9273
9274                 p = strchrnul(*ep, '=');
9275                 q = nullstr;
9276                 if (*p)
9277                         q = single_quote(++p);
9278                 out1fmt("%s%s%.*s%s\n", sep_prefix, sep, (int)(p - *ep), *ep, q);
9279         }
9280         return 0;
9281 }
9282
9283 /*
9284  * The set command builtin.
9285  */
9286 static int
9287 setcmd(int argc, char **argv)
9288 {
9289         int retval;
9290
9291         if (argc == 1)
9292                 return showvars(nullstr, 0, VUNSET);
9293         INT_OFF;
9294         retval = 1;
9295         if (!options(0)) { /* if no parse error... */
9296                 retval = 0;
9297                 optschanged();
9298                 if (*argptr != NULL) {
9299                         setparam(argptr);
9300                 }
9301         }
9302         INT_ON;
9303         return retval;
9304 }
9305
9306 #if ENABLE_ASH_RANDOM_SUPPORT
9307 /* Roughly copied from bash.. */
9308 static void
9309 change_random(const char *value)
9310 {
9311         if (value == NULL) {
9312                 /* "get", generate */
9313                 char buf[16];
9314
9315                 rseed = rseed * 1103515245 + 12345;
9316                 sprintf(buf, "%d", (unsigned int)((rseed & 32767)));
9317                 /* set without recursion */
9318                 setvar(vrandom.text, buf, VNOFUNC);
9319                 vrandom.flags &= ~VNOFUNC;
9320         } else {
9321                 /* set/reset */
9322                 rseed = strtoul(value, (char **)NULL, 10);
9323         }
9324 }
9325 #endif
9326
9327 #if ENABLE_ASH_GETOPTS
9328 static int
9329 getopts(char *optstr, char *optvar, char **optfirst, int *param_optind, int *optoff)
9330 {
9331         char *p, *q;
9332         char c = '?';
9333         int done = 0;
9334         int err = 0;
9335         char s[12];
9336         char **optnext;
9337
9338         if (*param_optind < 1)
9339                 return 1;
9340         optnext = optfirst + *param_optind - 1;
9341
9342         if (*param_optind <= 1 || *optoff < 0 || strlen(optnext[-1]) < *optoff)
9343                 p = NULL;
9344         else
9345                 p = optnext[-1] + *optoff;
9346         if (p == NULL || *p == '\0') {
9347                 /* Current word is done, advance */
9348                 p = *optnext;
9349                 if (p == NULL || *p != '-' || *++p == '\0') {
9350  atend:
9351                         p = NULL;
9352                         done = 1;
9353                         goto out;
9354                 }
9355                 optnext++;
9356                 if (LONE_DASH(p))        /* check for "--" */
9357                         goto atend;
9358         }
9359
9360         c = *p++;
9361         for (q = optstr; *q != c; ) {
9362                 if (*q == '\0') {
9363                         if (optstr[0] == ':') {
9364                                 s[0] = c;
9365                                 s[1] = '\0';
9366                                 err |= setvarsafe("OPTARG", s, 0);
9367                         } else {
9368                                 fprintf(stderr, "Illegal option -%c\n", c);
9369                                 unsetvar("OPTARG");
9370                         }
9371                         c = '?';
9372                         goto out;
9373                 }
9374                 if (*++q == ':')
9375                         q++;
9376         }
9377
9378         if (*++q == ':') {
9379                 if (*p == '\0' && (p = *optnext) == NULL) {
9380                         if (optstr[0] == ':') {
9381                                 s[0] = c;
9382                                 s[1] = '\0';
9383                                 err |= setvarsafe("OPTARG", s, 0);
9384                                 c = ':';
9385                         } else {
9386                                 fprintf(stderr, "No arg for -%c option\n", c);
9387                                 unsetvar("OPTARG");
9388                                 c = '?';
9389                         }
9390                         goto out;
9391                 }
9392
9393                 if (p == *optnext)
9394                         optnext++;
9395                 err |= setvarsafe("OPTARG", p, 0);
9396                 p = NULL;
9397         } else
9398                 err |= setvarsafe("OPTARG", nullstr, 0);
9399  out:
9400         *optoff = p ? p - *(optnext - 1) : -1;
9401         *param_optind = optnext - optfirst + 1;
9402         fmtstr(s, sizeof(s), "%d", *param_optind);
9403         err |= setvarsafe("OPTIND", s, VNOFUNC);
9404         s[0] = c;
9405         s[1] = '\0';
9406         err |= setvarsafe(optvar, s, 0);
9407         if (err) {
9408                 *param_optind = 1;
9409                 *optoff = -1;
9410                 flush_stdout_stderr();
9411                 raise_exception(EXERROR);
9412         }
9413         return done;
9414 }
9415
9416 /*
9417  * The getopts builtin.  Shellparam.optnext points to the next argument
9418  * to be processed.  Shellparam.optptr points to the next character to
9419  * be processed in the current argument.  If shellparam.optnext is NULL,
9420  * then it's the first time getopts has been called.
9421  */
9422 static int
9423 getoptscmd(int argc, char **argv)
9424 {
9425         char **optbase;
9426
9427         if (argc < 3)
9428                 ash_msg_and_raise_error("usage: getopts optstring var [arg]");
9429         if (argc == 3) {
9430                 optbase = shellparam.p;
9431                 if (shellparam.optind > shellparam.nparam + 1) {
9432                         shellparam.optind = 1;
9433                         shellparam.optoff = -1;
9434                 }
9435         } else {
9436                 optbase = &argv[3];
9437                 if (shellparam.optind > argc - 2) {
9438                         shellparam.optind = 1;
9439                         shellparam.optoff = -1;
9440                 }
9441         }
9442
9443         return getopts(argv[1], argv[2], optbase, &shellparam.optind,
9444                         &shellparam.optoff);
9445 }
9446 #endif /* ASH_GETOPTS */
9447
9448
9449 /* ============ Shell parser */
9450
9451 /*
9452  * NEOF is returned by parsecmd when it encounters an end of file.  It
9453  * must be distinct from NULL, so we use the address of a variable that
9454  * happens to be handy.
9455  */
9456 static smallint tokpushback;           /* last token pushed back */
9457 #define NEOF ((union node *)&tokpushback)
9458 static smallint parsebackquote;        /* nonzero if we are inside backquotes */
9459 static int lasttoken;                  /* last token read */
9460 static char *wordtext;                 /* text of last word returned by readtoken */
9461 static struct nodelist *backquotelist;
9462 static union node *redirnode;
9463 static struct heredoc *heredoc;
9464 static smallint quoteflag;             /* set if (part of) last token was quoted */
9465
9466 static void raise_error_syntax(const char *) ATTRIBUTE_NORETURN;
9467 static void
9468 raise_error_syntax(const char *msg)
9469 {
9470         ash_msg_and_raise_error("syntax error: %s", msg);
9471         /* NOTREACHED */
9472 }
9473
9474 /*
9475  * Called when an unexpected token is read during the parse.  The argument
9476  * is the token that is expected, or -1 if more than one type of token can
9477  * occur at this point.
9478  */
9479 static void raise_error_unexpected_syntax(int) ATTRIBUTE_NORETURN;
9480 static void
9481 raise_error_unexpected_syntax(int token)
9482 {
9483         char msg[64];
9484         int l;
9485
9486         l = sprintf(msg, "%s unexpected", tokname(lasttoken));
9487         if (token >= 0)
9488                 sprintf(msg + l, " (expecting %s)", tokname(token));
9489         raise_error_syntax(msg);
9490         /* NOTREACHED */
9491 }
9492
9493 #define EOFMARKLEN 79
9494
9495 struct heredoc {
9496         struct heredoc *next;   /* next here document in list */
9497         union node *here;               /* redirection node */
9498         char *eofmark;          /* string indicating end of input */
9499         int striptabs;          /* if set, strip leading tabs */
9500 };
9501
9502 static struct heredoc *heredoclist;    /* list of here documents to read */
9503
9504 /* parsing is heavily cross-recursive, need these forward decls */
9505 static union node *andor(void);
9506 static union node *pipeline(void);
9507 static union node *parse_command(void);
9508 static void parseheredoc(void);
9509 static char peektoken(void);
9510 static int readtoken(void);
9511
9512 static union node *
9513 list(int nlflag)
9514 {
9515         union node *n1, *n2, *n3;
9516         int tok;
9517
9518         checkkwd = CHKNL | CHKKWD | CHKALIAS;
9519         if (nlflag == 2 && peektoken())
9520                 return NULL;
9521         n1 = NULL;
9522         for (;;) {
9523                 n2 = andor();
9524                 tok = readtoken();
9525                 if (tok == TBACKGND) {
9526                         if (n2->type == NPIPE) {
9527                                 n2->npipe.backgnd = 1;
9528                         } else {
9529                                 if (n2->type != NREDIR) {
9530                                         n3 = stalloc(sizeof(struct nredir));
9531                                         n3->nredir.n = n2;
9532                                         n3->nredir.redirect = NULL;
9533                                         n2 = n3;
9534                                 }
9535                                 n2->type = NBACKGND;
9536                         }
9537                 }
9538                 if (n1 == NULL) {
9539                         n1 = n2;
9540                 } else {
9541                         n3 = stalloc(sizeof(struct nbinary));
9542                         n3->type = NSEMI;
9543                         n3->nbinary.ch1 = n1;
9544                         n3->nbinary.ch2 = n2;
9545                         n1 = n3;
9546                 }
9547                 switch (tok) {
9548                 case TBACKGND:
9549                 case TSEMI:
9550                         tok = readtoken();
9551                         /* fall through */
9552                 case TNL:
9553                         if (tok == TNL) {
9554                                 parseheredoc();
9555                                 if (nlflag == 1)
9556                                         return n1;
9557                         } else {
9558                                 tokpushback = 1;
9559                         }
9560                         checkkwd = CHKNL | CHKKWD | CHKALIAS;
9561                         if (peektoken())
9562                                 return n1;
9563                         break;
9564                 case TEOF:
9565                         if (heredoclist)
9566                                 parseheredoc();
9567                         else
9568                                 pungetc();              /* push back EOF on input */
9569                         return n1;
9570                 default:
9571                         if (nlflag == 1)
9572                                 raise_error_unexpected_syntax(-1);
9573                         tokpushback = 1;
9574                         return n1;
9575                 }
9576         }
9577 }
9578
9579 static union node *
9580 andor(void)
9581 {
9582         union node *n1, *n2, *n3;
9583         int t;
9584
9585         n1 = pipeline();
9586         for (;;) {
9587                 t = readtoken();
9588                 if (t == TAND) {
9589                         t = NAND;
9590                 } else if (t == TOR) {
9591                         t = NOR;
9592                 } else {
9593                         tokpushback = 1;
9594                         return n1;
9595                 }
9596                 checkkwd = CHKNL | CHKKWD | CHKALIAS;
9597                 n2 = pipeline();
9598                 n3 = stalloc(sizeof(struct nbinary));
9599                 n3->type = t;
9600                 n3->nbinary.ch1 = n1;
9601                 n3->nbinary.ch2 = n2;
9602                 n1 = n3;
9603         }
9604 }
9605
9606 static union node *
9607 pipeline(void)
9608 {
9609         union node *n1, *n2, *pipenode;
9610         struct nodelist *lp, *prev;
9611         int negate;
9612
9613         negate = 0;
9614         TRACE(("pipeline: entered\n"));
9615         if (readtoken() == TNOT) {
9616                 negate = !negate;
9617                 checkkwd = CHKKWD | CHKALIAS;
9618         } else
9619                 tokpushback = 1;
9620         n1 = parse_command();
9621         if (readtoken() == TPIPE) {
9622                 pipenode = stalloc(sizeof(struct npipe));
9623                 pipenode->type = NPIPE;
9624                 pipenode->npipe.backgnd = 0;
9625                 lp = stalloc(sizeof(struct nodelist));
9626                 pipenode->npipe.cmdlist = lp;
9627                 lp->n = n1;
9628                 do {
9629                         prev = lp;
9630                         lp = stalloc(sizeof(struct nodelist));
9631                         checkkwd = CHKNL | CHKKWD | CHKALIAS;
9632                         lp->n = parse_command();
9633                         prev->next = lp;
9634                 } while (readtoken() == TPIPE);
9635                 lp->next = NULL;
9636                 n1 = pipenode;
9637         }
9638         tokpushback = 1;
9639         if (negate) {
9640                 n2 = stalloc(sizeof(struct nnot));
9641                 n2->type = NNOT;
9642                 n2->nnot.com = n1;
9643                 return n2;
9644         }
9645         return n1;
9646 }
9647
9648 static union node *
9649 makename(void)
9650 {
9651         union node *n;
9652
9653         n = stalloc(sizeof(struct narg));
9654         n->type = NARG;
9655         n->narg.next = NULL;
9656         n->narg.text = wordtext;
9657         n->narg.backquote = backquotelist;
9658         return n;
9659 }
9660
9661 static void
9662 fixredir(union node *n, const char *text, int err)
9663 {
9664         TRACE(("Fix redir %s %d\n", text, err));
9665         if (!err)
9666                 n->ndup.vname = NULL;
9667
9668         if (isdigit(text[0]) && text[1] == '\0')
9669                 n->ndup.dupfd = text[0] - '0';
9670         else if (LONE_DASH(text))
9671                 n->ndup.dupfd = -1;
9672         else {
9673                 if (err)
9674                         raise_error_syntax("Bad fd number");
9675                 n->ndup.vname = makename();
9676         }
9677 }
9678
9679 /*
9680  * Returns true if the text contains nothing to expand (no dollar signs
9681  * or backquotes).
9682  */
9683 static int
9684 noexpand(char *text)
9685 {
9686         char *p;
9687         char c;
9688
9689         p = text;
9690         while ((c = *p++) != '\0') {
9691                 if (c == CTLQUOTEMARK)
9692                         continue;
9693                 if (c == CTLESC)
9694                         p++;
9695                 else if (SIT(c, BASESYNTAX) == CCTL)
9696                         return 0;
9697         }
9698         return 1;
9699 }
9700
9701 static void
9702 parsefname(void)
9703 {
9704         union node *n = redirnode;
9705
9706         if (readtoken() != TWORD)
9707                 raise_error_unexpected_syntax(-1);
9708         if (n->type == NHERE) {
9709                 struct heredoc *here = heredoc;
9710                 struct heredoc *p;
9711                 int i;
9712
9713                 if (quoteflag == 0)
9714                         n->type = NXHERE;
9715                 TRACE(("Here document %d\n", n->type));
9716                 if (!noexpand(wordtext) || (i = strlen(wordtext)) == 0 || i > EOFMARKLEN)
9717                         raise_error_syntax("Illegal eof marker for << redirection");
9718                 rmescapes(wordtext);
9719                 here->eofmark = wordtext;
9720                 here->next = NULL;
9721                 if (heredoclist == NULL)
9722                         heredoclist = here;
9723                 else {
9724                         for (p = heredoclist; p->next; p = p->next);
9725                         p->next = here;
9726                 }
9727         } else if (n->type == NTOFD || n->type == NFROMFD) {
9728                 fixredir(n, wordtext, 0);
9729         } else {
9730                 n->nfile.fname = makename();
9731         }
9732 }
9733
9734 static union node *
9735 simplecmd(void)
9736 {
9737         union node *args, **app;
9738         union node *n = NULL;
9739         union node *vars, **vpp;
9740         union node **rpp, *redir;
9741         int savecheckkwd;
9742
9743         args = NULL;
9744         app = &args;
9745         vars = NULL;
9746         vpp = &vars;
9747         redir = NULL;
9748         rpp = &redir;
9749
9750         savecheckkwd = CHKALIAS;
9751         for (;;) {
9752                 checkkwd = savecheckkwd;
9753                 switch (readtoken()) {
9754                 case TWORD:
9755                         n = stalloc(sizeof(struct narg));
9756                         n->type = NARG;
9757                         n->narg.text = wordtext;
9758                         n->narg.backquote = backquotelist;
9759                         if (savecheckkwd && isassignment(wordtext)) {
9760                                 *vpp = n;
9761                                 vpp = &n->narg.next;
9762                         } else {
9763                                 *app = n;
9764                                 app = &n->narg.next;
9765                                 savecheckkwd = 0;
9766                         }
9767                         break;
9768                 case TREDIR:
9769                         *rpp = n = redirnode;
9770                         rpp = &n->nfile.next;
9771                         parsefname();   /* read name of redirection file */
9772                         break;
9773                 case TLP:
9774                         if (args && app == &args->narg.next
9775                          && !vars && !redir
9776                         ) {
9777                                 struct builtincmd *bcmd;
9778                                 const char *name;
9779
9780                                 /* We have a function */
9781                                 if (readtoken() != TRP)
9782                                         raise_error_unexpected_syntax(TRP);
9783                                 name = n->narg.text;
9784                                 if (!goodname(name)
9785                                  || ((bcmd = find_builtin(name)) && IS_BUILTIN_SPECIAL(bcmd))
9786                                 ) {
9787                                         raise_error_syntax("Bad function name");
9788                                 }
9789                                 n->type = NDEFUN;
9790                                 checkkwd = CHKNL | CHKKWD | CHKALIAS;
9791                                 n->narg.next = parse_command();
9792                                 return n;
9793                         }
9794                         /* fall through */
9795                 default:
9796                         tokpushback = 1;
9797                         goto out;
9798                 }
9799         }
9800  out:
9801         *app = NULL;
9802         *vpp = NULL;
9803         *rpp = NULL;
9804         n = stalloc(sizeof(struct ncmd));
9805         n->type = NCMD;
9806         n->ncmd.args = args;
9807         n->ncmd.assign = vars;
9808         n->ncmd.redirect = redir;
9809         return n;
9810 }
9811
9812 static union node *
9813 parse_command(void)
9814 {
9815         union node *n1, *n2;
9816         union node *ap, **app;
9817         union node *cp, **cpp;
9818         union node *redir, **rpp;
9819         union node **rpp2;
9820         int t;
9821
9822         redir = NULL;
9823         rpp2 = &redir;
9824
9825         switch (readtoken()) {
9826         default:
9827                 raise_error_unexpected_syntax(-1);
9828                 /* NOTREACHED */
9829         case TIF:
9830                 n1 = stalloc(sizeof(struct nif));
9831                 n1->type = NIF;
9832                 n1->nif.test = list(0);
9833                 if (readtoken() != TTHEN)
9834                         raise_error_unexpected_syntax(TTHEN);
9835                 n1->nif.ifpart = list(0);
9836                 n2 = n1;
9837                 while (readtoken() == TELIF) {
9838                         n2->nif.elsepart = stalloc(sizeof(struct nif));
9839                         n2 = n2->nif.elsepart;
9840                         n2->type = NIF;
9841                         n2->nif.test = list(0);
9842                         if (readtoken() != TTHEN)
9843                                 raise_error_unexpected_syntax(TTHEN);
9844                         n2->nif.ifpart = list(0);
9845                 }
9846                 if (lasttoken == TELSE)
9847                         n2->nif.elsepart = list(0);
9848                 else {
9849                         n2->nif.elsepart = NULL;
9850                         tokpushback = 1;
9851                 }
9852                 t = TFI;
9853                 break;
9854         case TWHILE:
9855         case TUNTIL: {
9856                 int got;
9857                 n1 = stalloc(sizeof(struct nbinary));
9858                 n1->type = (lasttoken == TWHILE) ? NWHILE : NUNTIL;
9859                 n1->nbinary.ch1 = list(0);
9860                 got = readtoken();
9861                 if (got != TDO) {
9862                         TRACE(("expecting DO got %s %s\n", tokname(got),
9863                                         got == TWORD ? wordtext : ""));
9864                         raise_error_unexpected_syntax(TDO);
9865                 }
9866                 n1->nbinary.ch2 = list(0);
9867                 t = TDONE;
9868                 break;
9869         }
9870         case TFOR:
9871                 if (readtoken() != TWORD || quoteflag || ! goodname(wordtext))
9872                         raise_error_syntax("Bad for loop variable");
9873                 n1 = stalloc(sizeof(struct nfor));
9874                 n1->type = NFOR;
9875                 n1->nfor.var = wordtext;
9876                 checkkwd = CHKKWD | CHKALIAS;
9877                 if (readtoken() == TIN) {
9878                         app = &ap;
9879                         while (readtoken() == TWORD) {
9880                                 n2 = stalloc(sizeof(struct narg));
9881                                 n2->type = NARG;
9882                                 n2->narg.text = wordtext;
9883                                 n2->narg.backquote = backquotelist;
9884                                 *app = n2;
9885                                 app = &n2->narg.next;
9886                         }
9887                         *app = NULL;
9888                         n1->nfor.args = ap;
9889                         if (lasttoken != TNL && lasttoken != TSEMI)
9890                                 raise_error_unexpected_syntax(-1);
9891                 } else {
9892                         n2 = stalloc(sizeof(struct narg));
9893                         n2->type = NARG;
9894                         n2->narg.text = (char *)dolatstr;
9895                         n2->narg.backquote = NULL;
9896                         n2->narg.next = NULL;
9897                         n1->nfor.args = n2;
9898                         /*
9899                          * Newline or semicolon here is optional (but note
9900                          * that the original Bourne shell only allowed NL).
9901                          */
9902                         if (lasttoken != TNL && lasttoken != TSEMI)
9903                                 tokpushback = 1;
9904                 }
9905                 checkkwd = CHKNL | CHKKWD | CHKALIAS;
9906                 if (readtoken() != TDO)
9907                         raise_error_unexpected_syntax(TDO);
9908                 n1->nfor.body = list(0);
9909                 t = TDONE;
9910                 break;
9911         case TCASE:
9912                 n1 = stalloc(sizeof(struct ncase));
9913                 n1->type = NCASE;
9914                 if (readtoken() != TWORD)
9915                         raise_error_unexpected_syntax(TWORD);
9916                 n1->ncase.expr = n2 = stalloc(sizeof(struct narg));
9917                 n2->type = NARG;
9918                 n2->narg.text = wordtext;
9919                 n2->narg.backquote = backquotelist;
9920                 n2->narg.next = NULL;
9921                 do {
9922                         checkkwd = CHKKWD | CHKALIAS;
9923                 } while (readtoken() == TNL);
9924                 if (lasttoken != TIN)
9925                         raise_error_unexpected_syntax(TIN);
9926                 cpp = &n1->ncase.cases;
9927  next_case:
9928                 checkkwd = CHKNL | CHKKWD;
9929                 t = readtoken();
9930                 while (t != TESAC) {
9931                         if (lasttoken == TLP)
9932                                 readtoken();
9933                         *cpp = cp = stalloc(sizeof(struct nclist));
9934                         cp->type = NCLIST;
9935                         app = &cp->nclist.pattern;
9936                         for (;;) {
9937                                 *app = ap = stalloc(sizeof(struct narg));
9938                                 ap->type = NARG;
9939                                 ap->narg.text = wordtext;
9940                                 ap->narg.backquote = backquotelist;
9941                                 if (readtoken() != TPIPE)
9942                                         break;
9943                                 app = &ap->narg.next;
9944                                 readtoken();
9945                         }
9946                         ap->narg.next = NULL;
9947                         if (lasttoken != TRP)
9948                                 raise_error_unexpected_syntax(TRP);
9949                         cp->nclist.body = list(2);
9950
9951                         cpp = &cp->nclist.next;
9952
9953                         checkkwd = CHKNL | CHKKWD;
9954                         t = readtoken();
9955                         if (t != TESAC) {
9956                                 if (t != TENDCASE)
9957                                         raise_error_unexpected_syntax(TENDCASE);
9958                                 goto next_case;
9959                         }
9960                 }
9961                 *cpp = NULL;
9962                 goto redir;
9963         case TLP:
9964                 n1 = stalloc(sizeof(struct nredir));
9965                 n1->type = NSUBSHELL;
9966                 n1->nredir.n = list(0);
9967                 n1->nredir.redirect = NULL;
9968                 t = TRP;
9969                 break;
9970         case TBEGIN:
9971                 n1 = list(0);
9972                 t = TEND;
9973                 break;
9974         case TWORD:
9975         case TREDIR:
9976                 tokpushback = 1;
9977                 return simplecmd();
9978         }
9979
9980         if (readtoken() != t)
9981                 raise_error_unexpected_syntax(t);
9982
9983  redir:
9984         /* Now check for redirection which may follow command */
9985         checkkwd = CHKKWD | CHKALIAS;
9986         rpp = rpp2;
9987         while (readtoken() == TREDIR) {
9988                 *rpp = n2 = redirnode;
9989                 rpp = &n2->nfile.next;
9990                 parsefname();
9991         }
9992         tokpushback = 1;
9993         *rpp = NULL;
9994         if (redir) {
9995                 if (n1->type != NSUBSHELL) {
9996                         n2 = stalloc(sizeof(struct nredir));
9997                         n2->type = NREDIR;
9998                         n2->nredir.n = n1;
9999                         n1 = n2;
10000                 }
10001                 n1->nredir.redirect = redir;
10002         }
10003         return n1;
10004 }
10005
10006 /*
10007  * If eofmark is NULL, read a word or a redirection symbol.  If eofmark
10008  * is not NULL, read a here document.  In the latter case, eofmark is the
10009  * word which marks the end of the document and striptabs is true if
10010  * leading tabs should be stripped from the document.  The argument firstc
10011  * is the first character of the input token or document.
10012  *
10013  * Because C does not have internal subroutines, I have simulated them
10014  * using goto's to implement the subroutine linkage.  The following macros
10015  * will run code that appears at the end of readtoken1.
10016  */
10017
10018 #define CHECKEND()      {goto checkend; checkend_return:;}
10019 #define PARSEREDIR()    {goto parseredir; parseredir_return:;}
10020 #define PARSESUB()      {goto parsesub; parsesub_return:;}
10021 #define PARSEBACKQOLD() {oldstyle = 1; goto parsebackq; parsebackq_oldreturn:;}
10022 #define PARSEBACKQNEW() {oldstyle = 0; goto parsebackq; parsebackq_newreturn:;}
10023 #define PARSEARITH()    {goto parsearith; parsearith_return:;}
10024
10025 static int
10026 readtoken1(int firstc, int syntax, char *eofmark, int striptabs)
10027 {
10028         /* NB: syntax parameter fits into smallint */
10029         int c = firstc;
10030         char *out;
10031         int len;
10032         char line[EOFMARKLEN + 1];
10033         struct nodelist *bqlist;
10034         smallint quotef;
10035         smallint dblquote;
10036         smallint oldstyle;
10037         smallint prevsyntax; /* syntax before arithmetic */
10038 #if ENABLE_ASH_EXPAND_PRMT
10039         smallint pssyntax;   /* we are expanding a prompt string */
10040 #endif
10041         int varnest;         /* levels of variables expansion */
10042         int arinest;         /* levels of arithmetic expansion */
10043         int parenlevel;      /* levels of parens in arithmetic */
10044         int dqvarnest;       /* levels of variables expansion within double quotes */
10045
10046 #if __GNUC__
10047         /* Avoid longjmp clobbering */
10048         (void) &out;
10049         (void) &quotef;
10050         (void) &dblquote;
10051         (void) &varnest;
10052         (void) &arinest;
10053         (void) &parenlevel;
10054         (void) &dqvarnest;
10055         (void) &oldstyle;
10056         (void) &prevsyntax;
10057         (void) &syntax;
10058 #endif
10059         startlinno = plinno;
10060         bqlist = NULL;
10061         quotef = 0;
10062         oldstyle = 0;
10063         prevsyntax = 0;
10064 #if ENABLE_ASH_EXPAND_PRMT
10065         pssyntax = (syntax == PSSYNTAX);
10066         if (pssyntax)
10067                 syntax = DQSYNTAX;
10068 #endif
10069         dblquote = (syntax == DQSYNTAX);
10070         varnest = 0;
10071         arinest = 0;
10072         parenlevel = 0;
10073         dqvarnest = 0;
10074
10075         STARTSTACKSTR(out);
10076         loop: { /* for each line, until end of word */
10077                 CHECKEND();     /* set c to PEOF if at end of here document */
10078                 for (;;) {      /* until end of line or end of word */
10079                         CHECKSTRSPACE(4, out);  /* permit 4 calls to USTPUTC */
10080                         switch (SIT(c, syntax)) {
10081                         case CNL:       /* '\n' */
10082                                 if (syntax == BASESYNTAX)
10083                                         goto endword;   /* exit outer loop */
10084                                 USTPUTC(c, out);
10085                                 plinno++;
10086                                 if (doprompt)
10087                                         setprompt(2);
10088                                 c = pgetc();
10089                                 goto loop;              /* continue outer loop */
10090                         case CWORD:
10091                                 USTPUTC(c, out);
10092                                 break;
10093                         case CCTL:
10094                                 if (eofmark == NULL || dblquote)
10095                                         USTPUTC(CTLESC, out);
10096                                 USTPUTC(c, out);
10097                                 break;
10098                         case CBACK:     /* backslash */
10099                                 c = pgetc2();
10100                                 if (c == PEOF) {
10101                                         USTPUTC(CTLESC, out);
10102                                         USTPUTC('\\', out);
10103                                         pungetc();
10104                                 } else if (c == '\n') {
10105                                         if (doprompt)
10106                                                 setprompt(2);
10107                                 } else {
10108 #if ENABLE_ASH_EXPAND_PRMT
10109                                         if (c == '$' && pssyntax) {
10110                                                 USTPUTC(CTLESC, out);
10111                                                 USTPUTC('\\', out);
10112                                         }
10113 #endif
10114                                         if (dblquote &&
10115                                                 c != '\\' && c != '`' &&
10116                                                 c != '$' && (
10117                                                         c != '"' ||
10118                                                         eofmark != NULL)
10119                                         ) {
10120                                                 USTPUTC(CTLESC, out);
10121                                                 USTPUTC('\\', out);
10122                                         }
10123                                         if (SIT(c, SQSYNTAX) == CCTL)
10124                                                 USTPUTC(CTLESC, out);
10125                                         USTPUTC(c, out);
10126                                         quotef = 1;
10127                                 }
10128                                 break;
10129                         case CSQUOTE:
10130                                 syntax = SQSYNTAX;
10131  quotemark:
10132                                 if (eofmark == NULL) {
10133                                         USTPUTC(CTLQUOTEMARK, out);
10134                                 }
10135                                 break;
10136                         case CDQUOTE:
10137                                 syntax = DQSYNTAX;
10138                                 dblquote = 1;
10139                                 goto quotemark;
10140                         case CENDQUOTE:
10141                                 if (eofmark != NULL && arinest == 0
10142                                  && varnest == 0
10143                                 ) {
10144                                         USTPUTC(c, out);
10145                                 } else {
10146                                         if (dqvarnest == 0) {
10147                                                 syntax = BASESYNTAX;
10148                                                 dblquote = 0;
10149                                         }
10150                                         quotef = 1;
10151                                         goto quotemark;
10152                                 }
10153                                 break;
10154                         case CVAR:      /* '$' */
10155                                 PARSESUB();             /* parse substitution */
10156                                 break;
10157                         case CENDVAR:   /* '}' */
10158                                 if (varnest > 0) {
10159                                         varnest--;
10160                                         if (dqvarnest > 0) {
10161                                                 dqvarnest--;
10162                                         }
10163                                         USTPUTC(CTLENDVAR, out);
10164                                 } else {
10165                                         USTPUTC(c, out);
10166                                 }
10167                                 break;
10168 #if ENABLE_ASH_MATH_SUPPORT
10169                         case CLP:       /* '(' in arithmetic */
10170                                 parenlevel++;
10171                                 USTPUTC(c, out);
10172                                 break;
10173                         case CRP:       /* ')' in arithmetic */
10174                                 if (parenlevel > 0) {
10175                                         USTPUTC(c, out);
10176                                         --parenlevel;
10177                                 } else {
10178                                         if (pgetc() == ')') {
10179                                                 if (--arinest == 0) {
10180                                                         USTPUTC(CTLENDARI, out);
10181                                                         syntax = prevsyntax;
10182                                                         dblquote = (syntax == DQSYNTAX);
10183                                                 } else
10184                                                         USTPUTC(')', out);
10185                                         } else {
10186                                                 /*
10187                                                  * unbalanced parens
10188                                                  *  (don't 2nd guess - no error)
10189                                                  */
10190                                                 pungetc();
10191                                                 USTPUTC(')', out);
10192                                         }
10193                                 }
10194                                 break;
10195 #endif
10196                         case CBQUOTE:   /* '`' */
10197                                 PARSEBACKQOLD();
10198                                 break;
10199                         case CENDFILE:
10200                                 goto endword;           /* exit outer loop */
10201                         case CIGN:
10202                                 break;
10203                         default:
10204                                 if (varnest == 0)
10205                                         goto endword;   /* exit outer loop */
10206 #if ENABLE_ASH_ALIAS
10207                                 if (c != PEOA)
10208 #endif
10209                                         USTPUTC(c, out);
10210
10211                         }
10212                         c = pgetc_macro();
10213                 }
10214         }
10215  endword:
10216 #if ENABLE_ASH_MATH_SUPPORT
10217         if (syntax == ARISYNTAX)
10218                 raise_error_syntax("Missing '))'");
10219 #endif
10220         if (syntax != BASESYNTAX && !parsebackquote && eofmark == NULL)
10221                 raise_error_syntax("Unterminated quoted string");
10222         if (varnest != 0) {
10223                 startlinno = plinno;
10224                 /* { */
10225                 raise_error_syntax("Missing '}'");
10226         }
10227         USTPUTC('\0', out);
10228         len = out - (char *)stackblock();
10229         out = stackblock();
10230         if (eofmark == NULL) {
10231                 if ((c == '>' || c == '<')
10232                  && quotef == 0
10233                  && len <= 2
10234                  && (*out == '\0' || isdigit(*out))) {
10235                         PARSEREDIR();
10236                         return lasttoken = TREDIR;
10237                 } else {
10238                         pungetc();
10239                 }
10240         }
10241         quoteflag = quotef;
10242         backquotelist = bqlist;
10243         grabstackblock(len);
10244         wordtext = out;
10245         lasttoken = TWORD;
10246         return lasttoken;
10247 /* end of readtoken routine */
10248
10249 /*
10250  * Check to see whether we are at the end of the here document.  When this
10251  * is called, c is set to the first character of the next input line.  If
10252  * we are at the end of the here document, this routine sets the c to PEOF.
10253  */
10254 checkend: {
10255         if (eofmark) {
10256 #if ENABLE_ASH_ALIAS
10257                 if (c == PEOA) {
10258                         c = pgetc2();
10259                 }
10260 #endif
10261                 if (striptabs) {
10262                         while (c == '\t') {
10263                                 c = pgetc2();
10264                         }
10265                 }
10266                 if (c == *eofmark) {
10267                         if (pfgets(line, sizeof(line)) != NULL) {
10268                                 char *p, *q;
10269
10270                                 p = line;
10271                                 for (q = eofmark + 1; *q && *p == *q; p++, q++);
10272                                 if (*p == '\n' && *q == '\0') {
10273                                         c = PEOF;
10274                                         plinno++;
10275                                         needprompt = doprompt;
10276                                 } else {
10277                                         pushstring(line, NULL);
10278                                 }
10279                         }
10280                 }
10281         }
10282         goto checkend_return;
10283 }
10284
10285 /*
10286  * Parse a redirection operator.  The variable "out" points to a string
10287  * specifying the fd to be redirected.  The variable "c" contains the
10288  * first character of the redirection operator.
10289  */
10290 parseredir: {
10291         char fd = *out;
10292         union node *np;
10293
10294         np = stalloc(sizeof(struct nfile));
10295         if (c == '>') {
10296                 np->nfile.fd = 1;
10297                 c = pgetc();
10298                 if (c == '>')
10299                         np->type = NAPPEND;
10300                 else if (c == '|')
10301                         np->type = NCLOBBER;
10302                 else if (c == '&')
10303                         np->type = NTOFD;
10304                 else {
10305                         np->type = NTO;
10306                         pungetc();
10307                 }
10308         } else {        /* c == '<' */
10309                 np->nfile.fd = 0;
10310                 c = pgetc();
10311                 switch (c) {
10312                 case '<':
10313                         if (sizeof(struct nfile) != sizeof(struct nhere)) {
10314                                 np = stalloc(sizeof(struct nhere));
10315                                 np->nfile.fd = 0;
10316                         }
10317                         np->type = NHERE;
10318                         heredoc = stalloc(sizeof(struct heredoc));
10319                         heredoc->here = np;
10320                         c = pgetc();
10321                         if (c == '-') {
10322                                 heredoc->striptabs = 1;
10323                         } else {
10324                                 heredoc->striptabs = 0;
10325                                 pungetc();
10326                         }
10327                         break;
10328
10329                 case '&':
10330                         np->type = NFROMFD;
10331                         break;
10332
10333                 case '>':
10334                         np->type = NFROMTO;
10335                         break;
10336
10337                 default:
10338                         np->type = NFROM;
10339                         pungetc();
10340                         break;
10341                 }
10342         }
10343         if (fd != '\0')
10344                 np->nfile.fd = fd - '0';
10345         redirnode = np;
10346         goto parseredir_return;
10347 }
10348
10349 /*
10350  * Parse a substitution.  At this point, we have read the dollar sign
10351  * and nothing else.
10352  */
10353
10354 /* is_special(c) evaluates to 1 for c in "!#$*-0123456789?@"; 0 otherwise
10355  * (assuming ascii char codes, as the original implementation did) */
10356 #define is_special(c) \
10357         ((((unsigned int)c) - 33 < 32) \
10358                         && ((0xc1ff920dUL >> (((unsigned int)c) - 33)) & 1))
10359 parsesub: {
10360         int subtype;
10361         int typeloc;
10362         int flags;
10363         char *p;
10364         static const char types[] ALIGN1 = "}-+?=";
10365
10366         c = pgetc();
10367         if (
10368                 c <= PEOA_OR_PEOF  ||
10369                 (c != '(' && c != '{' && !is_name(c) && !is_special(c))
10370         ) {
10371                 USTPUTC('$', out);
10372                 pungetc();
10373         } else if (c == '(') {  /* $(command) or $((arith)) */
10374                 if (pgetc() == '(') {
10375 #if ENABLE_ASH_MATH_SUPPORT
10376                         PARSEARITH();
10377 #else
10378                         raise_error_syntax("We unsupport $((arith))");
10379 #endif
10380                 } else {
10381                         pungetc();
10382                         PARSEBACKQNEW();
10383                 }
10384         } else {
10385                 USTPUTC(CTLVAR, out);
10386                 typeloc = out - (char *)stackblock();
10387                 USTPUTC(VSNORMAL, out);
10388                 subtype = VSNORMAL;
10389                 if (c == '{') {
10390                         c = pgetc();
10391                         if (c == '#') {
10392                                 c = pgetc();
10393                                 if (c == '}')
10394                                         c = '#';
10395                                 else
10396                                         subtype = VSLENGTH;
10397                         } else
10398                                 subtype = 0;
10399                 }
10400                 if (c > PEOA_OR_PEOF && is_name(c)) {
10401                         do {
10402                                 STPUTC(c, out);
10403                                 c = pgetc();
10404                         } while (c > PEOA_OR_PEOF && is_in_name(c));
10405                 } else if (isdigit(c)) {
10406                         do {
10407                                 STPUTC(c, out);
10408                                 c = pgetc();
10409                         } while (isdigit(c));
10410                 } else if (is_special(c)) {
10411                         USTPUTC(c, out);
10412                         c = pgetc();
10413                 } else
10414  badsub:                raise_error_syntax("Bad substitution");
10415
10416                 STPUTC('=', out);
10417                 flags = 0;
10418                 if (subtype == 0) {
10419                         switch (c) {
10420                         case ':':
10421                                 flags = VSNUL;
10422                                 c = pgetc();
10423                                 /*FALLTHROUGH*/
10424                         default:
10425                                 p = strchr(types, c);
10426                                 if (p == NULL)
10427                                         goto badsub;
10428                                 subtype = p - types + VSNORMAL;
10429                                 break;
10430                         case '%':
10431                         case '#':
10432                                 {
10433                                         int cc = c;
10434                                         subtype = c == '#' ? VSTRIMLEFT :
10435                                                              VSTRIMRIGHT;
10436                                         c = pgetc();
10437                                         if (c == cc)
10438                                                 subtype++;
10439                                         else
10440                                                 pungetc();
10441                                         break;
10442                                 }
10443                         }
10444                 } else {
10445                         pungetc();
10446                 }
10447                 if (dblquote || arinest)
10448                         flags |= VSQUOTE;
10449                 *((char *)stackblock() + typeloc) = subtype | flags;
10450                 if (subtype != VSNORMAL) {
10451                         varnest++;
10452                         if (dblquote || arinest) {
10453                                 dqvarnest++;
10454                         }
10455                 }
10456         }
10457         goto parsesub_return;
10458 }
10459
10460 /*
10461  * Called to parse command substitutions.  Newstyle is set if the command
10462  * is enclosed inside $(...); nlpp is a pointer to the head of the linked
10463  * list of commands (passed by reference), and savelen is the number of
10464  * characters on the top of the stack which must be preserved.
10465  */
10466 parsebackq: {
10467         struct nodelist **nlpp;
10468         smallint savepbq;
10469         union node *n;
10470         char *volatile str;
10471         struct jmploc jmploc;
10472         struct jmploc *volatile savehandler;
10473         size_t savelen;
10474         smallint saveprompt = 0;
10475
10476 #ifdef __GNUC__
10477         (void) &saveprompt;
10478 #endif
10479         savepbq = parsebackquote;
10480         if (setjmp(jmploc.loc)) {
10481                 free(str);
10482                 parsebackquote = 0;
10483                 exception_handler = savehandler;
10484                 longjmp(exception_handler->loc, 1);
10485         }
10486         INT_OFF;
10487         str = NULL;
10488         savelen = out - (char *)stackblock();
10489         if (savelen > 0) {
10490                 str = ckmalloc(savelen);
10491                 memcpy(str, stackblock(), savelen);
10492         }
10493         savehandler = exception_handler;
10494         exception_handler = &jmploc;
10495         INT_ON;
10496         if (oldstyle) {
10497                 /* We must read until the closing backquote, giving special
10498                    treatment to some slashes, and then push the string and
10499                    reread it as input, interpreting it normally.  */
10500                 char *pout;
10501                 int pc;
10502                 size_t psavelen;
10503                 char *pstr;
10504
10505
10506                 STARTSTACKSTR(pout);
10507                 for (;;) {
10508                         if (needprompt) {
10509                                 setprompt(2);
10510                         }
10511                         pc = pgetc();
10512                         switch (pc) {
10513                         case '`':
10514                                 goto done;
10515
10516                         case '\\':
10517                                 pc = pgetc();
10518                                 if (pc == '\n') {
10519                                         plinno++;
10520                                         if (doprompt)
10521                                                 setprompt(2);
10522                                         /*
10523                                          * If eating a newline, avoid putting
10524                                          * the newline into the new character
10525                                          * stream (via the STPUTC after the
10526                                          * switch).
10527                                          */
10528                                         continue;
10529                                 }
10530                                 if (pc != '\\' && pc != '`' && pc != '$'
10531                                  && (!dblquote || pc != '"'))
10532                                         STPUTC('\\', pout);
10533                                 if (pc > PEOA_OR_PEOF) {
10534                                         break;
10535                                 }
10536                                 /* fall through */
10537
10538                         case PEOF:
10539 #if ENABLE_ASH_ALIAS
10540                         case PEOA:
10541 #endif
10542                                 startlinno = plinno;
10543                                 raise_error_syntax("EOF in backquote substitution");
10544
10545                         case '\n':
10546                                 plinno++;
10547                                 needprompt = doprompt;
10548                                 break;
10549
10550                         default:
10551                                 break;
10552                         }
10553                         STPUTC(pc, pout);
10554                 }
10555  done:
10556                 STPUTC('\0', pout);
10557                 psavelen = pout - (char *)stackblock();
10558                 if (psavelen > 0) {
10559                         pstr = grabstackstr(pout);
10560                         setinputstring(pstr);
10561                 }
10562         }
10563         nlpp = &bqlist;
10564         while (*nlpp)
10565                 nlpp = &(*nlpp)->next;
10566         *nlpp = stalloc(sizeof(**nlpp));
10567         (*nlpp)->next = NULL;
10568         parsebackquote = oldstyle;
10569
10570         if (oldstyle) {
10571                 saveprompt = doprompt;
10572                 doprompt = 0;
10573         }
10574
10575         n = list(2);
10576
10577         if (oldstyle)
10578                 doprompt = saveprompt;
10579         else if (readtoken() != TRP)
10580                 raise_error_unexpected_syntax(TRP);
10581
10582         (*nlpp)->n = n;
10583         if (oldstyle) {
10584                 /*
10585                  * Start reading from old file again, ignoring any pushed back
10586                  * tokens left from the backquote parsing
10587                  */
10588                 popfile();
10589                 tokpushback = 0;
10590         }
10591         while (stackblocksize() <= savelen)
10592                 growstackblock();
10593         STARTSTACKSTR(out);
10594         if (str) {
10595                 memcpy(out, str, savelen);
10596                 STADJUST(savelen, out);
10597                 INT_OFF;
10598                 free(str);
10599                 str = NULL;
10600                 INT_ON;
10601         }
10602         parsebackquote = savepbq;
10603         exception_handler = savehandler;
10604         if (arinest || dblquote)
10605                 USTPUTC(CTLBACKQ | CTLQUOTE, out);
10606         else
10607                 USTPUTC(CTLBACKQ, out);
10608         if (oldstyle)
10609                 goto parsebackq_oldreturn;
10610         goto parsebackq_newreturn;
10611 }
10612
10613 #if ENABLE_ASH_MATH_SUPPORT
10614 /*
10615  * Parse an arithmetic expansion (indicate start of one and set state)
10616  */
10617 parsearith: {
10618         if (++arinest == 1) {
10619                 prevsyntax = syntax;
10620                 syntax = ARISYNTAX;
10621                 USTPUTC(CTLARI, out);
10622                 if (dblquote)
10623                         USTPUTC('"', out);
10624                 else
10625                         USTPUTC(' ', out);
10626         } else {
10627                 /*
10628                  * we collapse embedded arithmetic expansion to
10629                  * parenthesis, which should be equivalent
10630                  */
10631                 USTPUTC('(', out);
10632         }
10633         goto parsearith_return;
10634 }
10635 #endif
10636
10637 } /* end of readtoken */
10638
10639 /*
10640  * Read the next input token.
10641  * If the token is a word, we set backquotelist to the list of cmds in
10642  *      backquotes.  We set quoteflag to true if any part of the word was
10643  *      quoted.
10644  * If the token is TREDIR, then we set redirnode to a structure containing
10645  *      the redirection.
10646  * In all cases, the variable startlinno is set to the number of the line
10647  *      on which the token starts.
10648  *
10649  * [Change comment:  here documents and internal procedures]
10650  * [Readtoken shouldn't have any arguments.  Perhaps we should make the
10651  *  word parsing code into a separate routine.  In this case, readtoken
10652  *  doesn't need to have any internal procedures, but parseword does.
10653  *  We could also make parseoperator in essence the main routine, and
10654  *  have parseword (readtoken1?) handle both words and redirection.]
10655  */
10656 #define NEW_xxreadtoken
10657 #ifdef NEW_xxreadtoken
10658 /* singles must be first! */
10659 static const char xxreadtoken_chars[7] ALIGN1 = {
10660         '\n', '(', ')', '&', '|', ';', 0
10661 };
10662
10663 static const char xxreadtoken_tokens[] ALIGN1 = {
10664         TNL, TLP, TRP,          /* only single occurrence allowed */
10665         TBACKGND, TPIPE, TSEMI, /* if single occurrence */
10666         TEOF,                   /* corresponds to trailing nul */
10667         TAND, TOR, TENDCASE     /* if double occurrence */
10668 };
10669
10670 #define xxreadtoken_doubles \
10671         (sizeof(xxreadtoken_tokens) - sizeof(xxreadtoken_chars))
10672 #define xxreadtoken_singles \
10673         (sizeof(xxreadtoken_chars) - xxreadtoken_doubles - 1)
10674
10675 static int
10676 xxreadtoken(void)
10677 {
10678         int c;
10679
10680         if (tokpushback) {
10681                 tokpushback = 0;
10682                 return lasttoken;
10683         }
10684         if (needprompt) {
10685                 setprompt(2);
10686         }
10687         startlinno = plinno;
10688         for (;;) {                      /* until token or start of word found */
10689                 c = pgetc_macro();
10690
10691                 if ((c != ' ') && (c != '\t')
10692 #if ENABLE_ASH_ALIAS
10693                  && (c != PEOA)
10694 #endif
10695                 ) {
10696                         if (c == '#') {
10697                                 while ((c = pgetc()) != '\n' && c != PEOF);
10698                                 pungetc();
10699                         } else if (c == '\\') {
10700                                 if (pgetc() != '\n') {
10701                                         pungetc();
10702                                         goto READTOKEN1;
10703                                 }
10704                                 startlinno = ++plinno;
10705                                 if (doprompt)
10706                                         setprompt(2);
10707                         } else {
10708                                 const char *p
10709                                         = xxreadtoken_chars + sizeof(xxreadtoken_chars) - 1;
10710
10711                                 if (c != PEOF) {
10712                                         if (c == '\n') {
10713                                                 plinno++;
10714                                                 needprompt = doprompt;
10715                                         }
10716
10717                                         p = strchr(xxreadtoken_chars, c);
10718                                         if (p == NULL) {
10719  READTOKEN1:
10720                                                 return readtoken1(c, BASESYNTAX, (char *) NULL, 0);
10721                                         }
10722
10723                                         if (p - xxreadtoken_chars >= xxreadtoken_singles) {
10724                                                 if (pgetc() == *p) {    /* double occurrence? */
10725                                                         p += xxreadtoken_doubles + 1;
10726                                                 } else {
10727                                                         pungetc();
10728                                                 }
10729                                         }
10730                                 }
10731                                 return lasttoken = xxreadtoken_tokens[p - xxreadtoken_chars];
10732                         }
10733                 }
10734         } /* for */
10735 }
10736 #else
10737 #define RETURN(token)   return lasttoken = token
10738 static int
10739 xxreadtoken(void)
10740 {
10741         int c;
10742
10743         if (tokpushback) {
10744                 tokpushback = 0;
10745                 return lasttoken;
10746         }
10747         if (needprompt) {
10748                 setprompt(2);
10749         }
10750         startlinno = plinno;
10751         for (;;) {      /* until token or start of word found */
10752                 c = pgetc_macro();
10753                 switch (c) {
10754                 case ' ': case '\t':
10755 #if ENABLE_ASH_ALIAS
10756                 case PEOA:
10757 #endif
10758                         continue;
10759                 case '#':
10760                         while ((c = pgetc()) != '\n' && c != PEOF);
10761                         pungetc();
10762                         continue;
10763                 case '\\':
10764                         if (pgetc() == '\n') {
10765                                 startlinno = ++plinno;
10766                                 if (doprompt)
10767                                         setprompt(2);
10768                                 continue;
10769                         }
10770                         pungetc();
10771                         goto breakloop;
10772                 case '\n':
10773                         plinno++;
10774                         needprompt = doprompt;
10775                         RETURN(TNL);
10776                 case PEOF:
10777                         RETURN(TEOF);
10778                 case '&':
10779                         if (pgetc() == '&')
10780                                 RETURN(TAND);
10781                         pungetc();
10782                         RETURN(TBACKGND);
10783                 case '|':
10784                         if (pgetc() == '|')
10785                                 RETURN(TOR);
10786                         pungetc();
10787                         RETURN(TPIPE);
10788                 case ';':
10789                         if (pgetc() == ';')
10790                                 RETURN(TENDCASE);
10791                         pungetc();
10792                         RETURN(TSEMI);
10793                 case '(':
10794                         RETURN(TLP);
10795                 case ')':
10796                         RETURN(TRP);
10797                 default:
10798                         goto breakloop;
10799                 }
10800         }
10801  breakloop:
10802         return readtoken1(c, BASESYNTAX, (char *)NULL, 0);
10803 #undef RETURN
10804 }
10805 #endif /* NEW_xxreadtoken */
10806
10807 static int
10808 readtoken(void)
10809 {
10810         int t;
10811 #if DEBUG
10812         smallint alreadyseen = tokpushback;
10813 #endif
10814
10815 #if ENABLE_ASH_ALIAS
10816  top:
10817 #endif
10818
10819         t = xxreadtoken();
10820
10821         /*
10822          * eat newlines
10823          */
10824         if (checkkwd & CHKNL) {
10825                 while (t == TNL) {
10826                         parseheredoc();
10827                         t = xxreadtoken();
10828                 }
10829         }
10830
10831         if (t != TWORD || quoteflag) {
10832                 goto out;
10833         }
10834
10835         /*
10836          * check for keywords
10837          */
10838         if (checkkwd & CHKKWD) {
10839                 const char *const *pp;
10840
10841                 pp = findkwd(wordtext);
10842                 if (pp) {
10843                         lasttoken = t = pp - tokname_array;
10844                         TRACE(("keyword %s recognized\n", tokname(t)));
10845                         goto out;
10846                 }
10847         }
10848
10849         if (checkkwd & CHKALIAS) {
10850 #if ENABLE_ASH_ALIAS
10851                 struct alias *ap;
10852                 ap = lookupalias(wordtext, 1);
10853                 if (ap != NULL) {
10854                         if (*ap->val) {
10855                                 pushstring(ap->val, ap);
10856                         }
10857                         goto top;
10858                 }
10859 #endif
10860         }
10861  out:
10862         checkkwd = 0;
10863 #if DEBUG
10864         if (!alreadyseen)
10865                 TRACE(("token %s %s\n", tokname(t), t == TWORD ? wordtext : ""));
10866         else
10867                 TRACE(("reread token %s %s\n", tokname(t), t == TWORD ? wordtext : ""));
10868 #endif
10869         return t;
10870 }
10871
10872 static char
10873 peektoken(void)
10874 {
10875         int t;
10876
10877         t = readtoken();
10878         tokpushback = 1;
10879         return tokname_array[t][0];
10880 }
10881
10882 /*
10883  * Read and parse a command.  Returns NEOF on end of file.  (NULL is a
10884  * valid parse tree indicating a blank line.)
10885  */
10886 static union node *
10887 parsecmd(int interact)
10888 {
10889         int t;
10890
10891         tokpushback = 0;
10892         doprompt = interact;
10893         if (doprompt)
10894                 setprompt(doprompt);
10895         needprompt = 0;
10896         t = readtoken();
10897         if (t == TEOF)
10898                 return NEOF;
10899         if (t == TNL)
10900                 return NULL;
10901         tokpushback = 1;
10902         return list(1);
10903 }
10904
10905 /*
10906  * Input any here documents.
10907  */
10908 static void
10909 parseheredoc(void)
10910 {
10911         struct heredoc *here;
10912         union node *n;
10913
10914         here = heredoclist;
10915         heredoclist = 0;
10916
10917         while (here) {
10918                 if (needprompt) {
10919                         setprompt(2);
10920                 }
10921                 readtoken1(pgetc(), here->here->type == NHERE? SQSYNTAX : DQSYNTAX,
10922                                 here->eofmark, here->striptabs);
10923                 n = stalloc(sizeof(struct narg));
10924                 n->narg.type = NARG;
10925                 n->narg.next = NULL;
10926                 n->narg.text = wordtext;
10927                 n->narg.backquote = backquotelist;
10928                 here->here->nhere.doc = n;
10929                 here = here->next;
10930         }
10931 }
10932
10933
10934 /*
10935  * called by editline -- any expansions to the prompt should be added here.
10936  */
10937 #if ENABLE_ASH_EXPAND_PRMT
10938 static const char *
10939 expandstr(const char *ps)
10940 {
10941         union node n;
10942
10943         /* XXX Fix (char *) cast. */
10944         setinputstring((char *)ps);
10945         readtoken1(pgetc(), PSSYNTAX, nullstr, 0);
10946         popfile();
10947
10948         n.narg.type = NARG;
10949         n.narg.next = NULL;
10950         n.narg.text = wordtext;
10951         n.narg.backquote = backquotelist;
10952
10953         expandarg(&n, NULL, 0);
10954         return stackblock();
10955 }
10956 #endif
10957
10958 /*
10959  * Execute a command or commands contained in a string.
10960  */
10961 static int
10962 evalstring(char *s, int mask)
10963 {
10964         union node *n;
10965         struct stackmark smark;
10966         int skip;
10967
10968         setinputstring(s);
10969         setstackmark(&smark);
10970
10971         skip = 0;
10972         while ((n = parsecmd(0)) != NEOF) {
10973                 evaltree(n, 0);
10974                 popstackmark(&smark);
10975                 skip = evalskip;
10976                 if (skip)
10977                         break;
10978         }
10979         popfile();
10980
10981         skip &= mask;
10982         evalskip = skip;
10983         return skip;
10984 }
10985
10986 /*
10987  * The eval command.
10988  */
10989 static int
10990 evalcmd(int argc, char **argv)
10991 {
10992         char *p;
10993         char *concat;
10994         char **ap;
10995
10996         if (argc > 1) {
10997                 p = argv[1];
10998                 if (argc > 2) {
10999                         STARTSTACKSTR(concat);
11000                         ap = argv + 2;
11001                         for (;;) {
11002                                 concat = stack_putstr(p, concat);
11003                                 p = *ap++;
11004                                 if (p == NULL)
11005                                         break;
11006                                 STPUTC(' ', concat);
11007                         }
11008                         STPUTC('\0', concat);
11009                         p = grabstackstr(concat);
11010                 }
11011                 evalstring(p, ~SKIPEVAL);
11012
11013         }
11014         return exitstatus;
11015 }
11016
11017 /*
11018  * Read and execute commands.  "Top" is nonzero for the top level command
11019  * loop; it turns on prompting if the shell is interactive.
11020  */
11021 static int
11022 cmdloop(int top)
11023 {
11024         union node *n;
11025         struct stackmark smark;
11026         int inter;
11027         int numeof = 0;
11028
11029         TRACE(("cmdloop(%d) called\n", top));
11030         for (;;) {
11031                 int skip;
11032
11033                 setstackmark(&smark);
11034 #if JOBS
11035                 if (jobctl)
11036                         showjobs(stderr, SHOW_CHANGED);
11037 #endif
11038                 inter = 0;
11039                 if (iflag && top) {
11040                         inter++;
11041 #if ENABLE_ASH_MAIL
11042                         chkmail();
11043 #endif
11044                 }
11045                 n = parsecmd(inter);
11046                 /* showtree(n); DEBUG */
11047                 if (n == NEOF) {
11048                         if (!top || numeof >= 50)
11049                                 break;
11050                         if (!stoppedjobs()) {
11051                                 if (!Iflag)
11052                                         break;
11053                                 out2str("\nUse \"exit\" to leave shell.\n");
11054                         }
11055                         numeof++;
11056                 } else if (nflag == 0) {
11057                         /* job_warning can only be 2,1,0. Here 2->1, 1/0->0 */
11058                         job_warning >>= 1;
11059                         numeof = 0;
11060                         evaltree(n, 0);
11061                 }
11062                 popstackmark(&smark);
11063                 skip = evalskip;
11064
11065                 if (skip) {
11066                         evalskip = 0;
11067                         return skip & SKIPEVAL;
11068                 }
11069         }
11070         return 0;
11071 }
11072
11073 /*
11074  * Take commands from a file.  To be compatible we should do a path
11075  * search for the file, which is necessary to find sub-commands.
11076  */
11077 static char *
11078 find_dot_file(char *name)
11079 {
11080         char *fullname;
11081         const char *path = pathval();
11082         struct stat statb;
11083
11084         /* don't try this for absolute or relative paths */
11085         if (strchr(name, '/'))
11086                 return name;
11087
11088         while ((fullname = padvance(&path, name)) != NULL) {
11089                 if ((stat(fullname, &statb) == 0) && S_ISREG(statb.st_mode)) {
11090                         /*
11091                          * Don't bother freeing here, since it will
11092                          * be freed by the caller.
11093                          */
11094                         return fullname;
11095                 }
11096                 stunalloc(fullname);
11097         }
11098
11099         /* not found in the PATH */
11100         ash_msg_and_raise_error("%s: not found", name);
11101         /* NOTREACHED */
11102 }
11103
11104 static int
11105 dotcmd(int argc, char **argv)
11106 {
11107         struct strlist *sp;
11108         volatile struct shparam saveparam;
11109         int status = 0;
11110
11111         for (sp = cmdenviron; sp; sp = sp->next)
11112                 setvareq(ckstrdup(sp->text), VSTRFIXED | VTEXTFIXED);
11113
11114         if (argc >= 2) {        /* That's what SVR2 does */
11115                 char *fullname;
11116
11117                 fullname = find_dot_file(argv[1]);
11118
11119                 if (argc > 2) {
11120                         saveparam = shellparam;
11121                         shellparam.malloced = 0;
11122                         shellparam.nparam = argc - 2;
11123                         shellparam.p = argv + 2;
11124                 };
11125
11126                 setinputfile(fullname, INPUT_PUSH_FILE);
11127                 commandname = fullname;
11128                 cmdloop(0);
11129                 popfile();
11130
11131                 if (argc > 2) {
11132                         freeparam(&shellparam);
11133                         shellparam = saveparam;
11134                 };
11135                 status = exitstatus;
11136         }
11137         return status;
11138 }
11139
11140 static int
11141 exitcmd(int argc, char **argv)
11142 {
11143         if (stoppedjobs())
11144                 return 0;
11145         if (argc > 1)
11146                 exitstatus = number(argv[1]);
11147         raise_exception(EXEXIT);
11148         /* NOTREACHED */
11149 }
11150
11151 #if ENABLE_ASH_BUILTIN_ECHO
11152 static int
11153 echocmd(int argc, char **argv)
11154 {
11155         return echo_main(argc, argv);
11156 }
11157 #endif
11158
11159 #if ENABLE_ASH_BUILTIN_TEST
11160 static int
11161 testcmd(int argc, char **argv)
11162 {
11163         return test_main(argc, argv);
11164 }
11165 #endif
11166
11167 /*
11168  * Read a file containing shell functions.
11169  */
11170 static void
11171 readcmdfile(char *name)
11172 {
11173         setinputfile(name, INPUT_PUSH_FILE);
11174         cmdloop(0);
11175         popfile();
11176 }
11177
11178
11179 /* ============ find_command inplementation */
11180
11181 /*
11182  * Resolve a command name.  If you change this routine, you may have to
11183  * change the shellexec routine as well.
11184  */
11185 static void
11186 find_command(char *name, struct cmdentry *entry, int act, const char *path)
11187 {
11188         struct tblentry *cmdp;
11189         int idx;
11190         int prev;
11191         char *fullname;
11192         struct stat statb;
11193         int e;
11194         int updatetbl;
11195         struct builtincmd *bcmd;
11196
11197         /* If name contains a slash, don't use PATH or hash table */
11198         if (strchr(name, '/') != NULL) {
11199                 entry->u.index = -1;
11200                 if (act & DO_ABS) {
11201                         while (stat(name, &statb) < 0) {
11202 #ifdef SYSV
11203                                 if (errno == EINTR)
11204                                         continue;
11205 #endif
11206                                 entry->cmdtype = CMDUNKNOWN;
11207                                 return;
11208                         }
11209                 }
11210                 entry->cmdtype = CMDNORMAL;
11211                 return;
11212         }
11213
11214 /* #if ENABLE_FEATURE_SH_STANDALONE... moved after builtin check */
11215
11216         updatetbl = (path == pathval());
11217         if (!updatetbl) {
11218                 act |= DO_ALTPATH;
11219                 if (strstr(path, "%builtin") != NULL)
11220                         act |= DO_ALTBLTIN;
11221         }
11222
11223         /* If name is in the table, check answer will be ok */
11224         cmdp = cmdlookup(name, 0);
11225         if (cmdp != NULL) {
11226                 int bit;
11227
11228                 switch (cmdp->cmdtype) {
11229                 default:
11230 #if DEBUG
11231                         abort();
11232 #endif
11233                 case CMDNORMAL:
11234                         bit = DO_ALTPATH;
11235                         break;
11236                 case CMDFUNCTION:
11237                         bit = DO_NOFUNC;
11238                         break;
11239                 case CMDBUILTIN:
11240                         bit = DO_ALTBLTIN;
11241                         break;
11242                 }
11243                 if (act & bit) {
11244                         updatetbl = 0;
11245                         cmdp = NULL;
11246                 } else if (cmdp->rehash == 0)
11247                         /* if not invalidated by cd, we're done */
11248                         goto success;
11249         }
11250
11251         /* If %builtin not in path, check for builtin next */
11252         bcmd = find_builtin(name);
11253         if (bcmd) {
11254                 if (IS_BUILTIN_REGULAR(bcmd))
11255                         goto builtin_success;
11256                 if (act & DO_ALTPATH) {
11257                         if (!(act & DO_ALTBLTIN))
11258                                 goto builtin_success;
11259                 } else if (builtinloc <= 0) {
11260                         goto builtin_success;
11261                 }
11262         }
11263
11264 #if ENABLE_FEATURE_SH_STANDALONE
11265         if (find_applet_by_name(name) >= 0) {
11266                 entry->cmdtype = CMDNORMAL;
11267                 entry->u.index = -1;
11268                 return;
11269         }
11270 #endif
11271
11272         /* We have to search path. */
11273         prev = -1;              /* where to start */
11274         if (cmdp && cmdp->rehash) {     /* doing a rehash */
11275                 if (cmdp->cmdtype == CMDBUILTIN)
11276                         prev = builtinloc;
11277                 else
11278                         prev = cmdp->param.index;
11279         }
11280
11281         e = ENOENT;
11282         idx = -1;
11283  loop:
11284         while ((fullname = padvance(&path, name)) != NULL) {
11285                 stunalloc(fullname);
11286                 /* NB: code below will still use fullname
11287                  * despite it being "unallocated" */
11288                 idx++;
11289                 if (pathopt) {
11290                         if (prefix(pathopt, "builtin")) {
11291                                 if (bcmd)
11292                                         goto builtin_success;
11293                                 continue;
11294                         } else if (!(act & DO_NOFUNC)
11295                          && prefix(pathopt, "func")) {
11296                                 /* handled below */
11297                         } else {
11298                                 /* ignore unimplemented options */
11299                                 continue;
11300                         }
11301                 }
11302                 /* if rehash, don't redo absolute path names */
11303                 if (fullname[0] == '/' && idx <= prev) {
11304                         if (idx < prev)
11305                                 continue;
11306                         TRACE(("searchexec \"%s\": no change\n", name));
11307                         goto success;
11308                 }
11309                 while (stat(fullname, &statb) < 0) {
11310 #ifdef SYSV
11311                         if (errno == EINTR)
11312                                 continue;
11313 #endif
11314                         if (errno != ENOENT && errno != ENOTDIR)
11315                                 e = errno;
11316                         goto loop;
11317                 }
11318                 e = EACCES;     /* if we fail, this will be the error */
11319                 if (!S_ISREG(statb.st_mode))
11320                         continue;
11321                 if (pathopt) {          /* this is a %func directory */
11322                         stalloc(strlen(fullname) + 1);
11323                         /* NB: stalloc will return space pointed by fullname
11324                          * (because we don't have any intervening allocations
11325                          * between stunalloc above and this stalloc) */
11326                         readcmdfile(fullname);
11327                         cmdp = cmdlookup(name, 0);
11328                         if (cmdp == NULL || cmdp->cmdtype != CMDFUNCTION)
11329                                 ash_msg_and_raise_error("%s not defined in %s", name, fullname);
11330                         stunalloc(fullname);
11331                         goto success;
11332                 }
11333                 TRACE(("searchexec \"%s\" returns \"%s\"\n", name, fullname));
11334                 if (!updatetbl) {
11335                         entry->cmdtype = CMDNORMAL;
11336                         entry->u.index = idx;
11337                         return;
11338                 }
11339                 INT_OFF;
11340                 cmdp = cmdlookup(name, 1);
11341                 cmdp->cmdtype = CMDNORMAL;
11342                 cmdp->param.index = idx;
11343                 INT_ON;
11344                 goto success;
11345         }
11346
11347         /* We failed.  If there was an entry for this command, delete it */
11348         if (cmdp && updatetbl)
11349                 delete_cmd_entry();
11350         if (act & DO_ERR)
11351                 ash_msg("%s: %s", name, errmsg(e, "not found"));
11352         entry->cmdtype = CMDUNKNOWN;
11353         return;
11354
11355  builtin_success:
11356         if (!updatetbl) {
11357                 entry->cmdtype = CMDBUILTIN;
11358                 entry->u.cmd = bcmd;
11359                 return;
11360         }
11361         INT_OFF;
11362         cmdp = cmdlookup(name, 1);
11363         cmdp->cmdtype = CMDBUILTIN;
11364         cmdp->param.cmd = bcmd;
11365         INT_ON;
11366  success:
11367         cmdp->rehash = 0;
11368         entry->cmdtype = cmdp->cmdtype;
11369         entry->u = cmdp->param;
11370 }
11371
11372
11373 /* ============ trap.c */
11374
11375 /*
11376  * The trap builtin.
11377  */
11378 static int
11379 trapcmd(int argc, char **argv)
11380 {
11381         char *action;
11382         char **ap;
11383         int signo;
11384
11385         nextopt(nullstr);
11386         ap = argptr;
11387         if (!*ap) {
11388                 for (signo = 0; signo < NSIG; signo++) {
11389                         if (trap[signo] != NULL) {
11390                                 const char *sn;
11391
11392                                 sn = get_signame(signo);
11393                                 out1fmt("trap -- %s %s\n",
11394                                         single_quote(trap[signo]), sn);
11395                         }
11396                 }
11397                 return 0;
11398         }
11399         if (!ap[1])
11400                 action = NULL;
11401         else
11402                 action = *ap++;
11403         while (*ap) {
11404                 signo = get_signum(*ap);
11405                 if (signo < 0)
11406                         ash_msg_and_raise_error("%s: bad trap", *ap);
11407                 INT_OFF;
11408                 if (action) {
11409                         if (LONE_DASH(action))
11410                                 action = NULL;
11411                         else
11412                                 action = ckstrdup(action);
11413                 }
11414                 free(trap[signo]);
11415                 trap[signo] = action;
11416                 if (signo != 0)
11417                         setsignal(signo);
11418                 INT_ON;
11419                 ap++;
11420         }
11421         return 0;
11422 }
11423
11424
11425 /* ============ Builtins */
11426
11427 #if !ENABLE_FEATURE_SH_EXTRA_QUIET
11428 /*
11429  * Lists available builtins
11430  */
11431 static int
11432 helpcmd(int argc, char **argv)
11433 {
11434         int col, i;
11435
11436         out1fmt("\nBuilt-in commands:\n-------------------\n");
11437         for (col = 0, i = 0; i < ARRAY_SIZE(builtintab); i++) {
11438                 col += out1fmt("%c%s", ((col == 0) ? '\t' : ' '),
11439                                         builtintab[i].name + 1);
11440                 if (col > 60) {
11441                         out1fmt("\n");
11442                         col = 0;
11443                 }
11444         }
11445 #if ENABLE_FEATURE_SH_STANDALONE
11446         {
11447                 const char *a = applet_names;
11448                 while (*a) {
11449                         col += out1fmt("%c%s", ((col == 0) ? '\t' : ' '), a);
11450                         if (col > 60) {
11451                                 out1fmt("\n");
11452                                 col = 0;
11453                         }
11454                         a += strlen(a) + 1;
11455                 }
11456         }
11457 #endif
11458         out1fmt("\n\n");
11459         return EXIT_SUCCESS;
11460 }
11461 #endif /* FEATURE_SH_EXTRA_QUIET */
11462
11463 /*
11464  * The export and readonly commands.
11465  */
11466 static int
11467 exportcmd(int argc, char **argv)
11468 {
11469         struct var *vp;
11470         char *name;
11471         const char *p;
11472         char **aptr;
11473         int flag = argv[0][0] == 'r'? VREADONLY : VEXPORT;
11474
11475         if (nextopt("p") != 'p') {
11476                 aptr = argptr;
11477                 name = *aptr;
11478                 if (name) {
11479                         do {
11480                                 p = strchr(name, '=');
11481                                 if (p != NULL) {
11482                                         p++;
11483                                 } else {
11484                                         vp = *findvar(hashvar(name), name);
11485                                         if (vp) {
11486                                                 vp->flags |= flag;
11487                                                 continue;
11488                                         }
11489                                 }
11490                                 setvar(name, p, flag);
11491                         } while ((name = *++aptr) != NULL);
11492                         return 0;
11493                 }
11494         }
11495         showvars(argv[0], flag, 0);
11496         return 0;
11497 }
11498
11499 /*
11500  * Delete a function if it exists.
11501  */
11502 static void
11503 unsetfunc(const char *name)
11504 {
11505         struct tblentry *cmdp;
11506
11507         cmdp = cmdlookup(name, 0);
11508         if (cmdp!= NULL && cmdp->cmdtype == CMDFUNCTION)
11509                 delete_cmd_entry();
11510 }
11511
11512 /*
11513  * The unset builtin command.  We unset the function before we unset the
11514  * variable to allow a function to be unset when there is a readonly variable
11515  * with the same name.
11516  */
11517 static int
11518 unsetcmd(int argc, char **argv)
11519 {
11520         char **ap;
11521         int i;
11522         int flag = 0;
11523         int ret = 0;
11524
11525         while ((i = nextopt("vf")) != '\0') {
11526                 flag = i;
11527         }
11528
11529         for (ap = argptr; *ap; ap++) {
11530                 if (flag != 'f') {
11531                         i = unsetvar(*ap);
11532                         ret |= i;
11533                         if (!(i & 2))
11534                                 continue;
11535                 }
11536                 if (flag != 'v')
11537                         unsetfunc(*ap);
11538         }
11539         return ret & 1;
11540 }
11541
11542
11543 /*      setmode.c      */
11544
11545 #include <sys/times.h>
11546
11547 static const unsigned char timescmd_str[] ALIGN1 = {
11548         ' ',  offsetof(struct tms, tms_utime),
11549         '\n', offsetof(struct tms, tms_stime),
11550         ' ',  offsetof(struct tms, tms_cutime),
11551         '\n', offsetof(struct tms, tms_cstime),
11552         0
11553 };
11554
11555 static int
11556 timescmd(int ac, char **av)
11557 {
11558         long clk_tck, s, t;
11559         const unsigned char *p;
11560         struct tms buf;
11561
11562         clk_tck = sysconf(_SC_CLK_TCK);
11563         times(&buf);
11564
11565         p = timescmd_str;
11566         do {
11567                 t = *(clock_t *)(((char *) &buf) + p[1]);
11568                 s = t / clk_tck;
11569                 out1fmt("%ldm%ld.%.3lds%c",
11570                         s/60, s%60,
11571                         ((t - s * clk_tck) * 1000) / clk_tck,
11572                         p[0]);
11573         } while (*(p += 2));
11574
11575         return 0;
11576 }
11577
11578 #if ENABLE_ASH_MATH_SUPPORT
11579 static arith_t
11580 dash_arith(const char *s)
11581 {
11582         arith_t result;
11583         int errcode = 0;
11584
11585         INT_OFF;
11586         result = arith(s, &errcode);
11587         if (errcode < 0) {
11588                 if (errcode == -3)
11589                         ash_msg_and_raise_error("exponent less than 0");
11590                 if (errcode == -2)
11591                         ash_msg_and_raise_error("divide by zero");
11592                 if (errcode == -5)
11593                         ash_msg_and_raise_error("expression recursion loop detected");
11594                 raise_error_syntax(s);
11595         }
11596         INT_ON;
11597
11598         return result;
11599 }
11600
11601 /*
11602  *  The let builtin. partial stolen from GNU Bash, the Bourne Again SHell.
11603  *  Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
11604  *
11605  *  Copyright (C) 2003 Vladimir Oleynik <dzo@simtreas.ru>
11606  */
11607 static int
11608 letcmd(int argc, char **argv)
11609 {
11610         char **ap;
11611         arith_t i = 0;
11612
11613         ap = argv + 1;
11614         if (!*ap)
11615                 ash_msg_and_raise_error("expression expected");
11616         for (ap = argv + 1; *ap; ap++) {
11617                 i = dash_arith(*ap);
11618         }
11619
11620         return !i;
11621 }
11622 #endif /* ASH_MATH_SUPPORT */
11623
11624
11625 /* ============ miscbltin.c
11626  *
11627  * Miscellaneous builtins.
11628  */
11629
11630 #undef rflag
11631
11632 #if defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 1
11633 typedef enum __rlimit_resource rlim_t;
11634 #endif
11635
11636 /*
11637  * The read builtin.  The -e option causes backslashes to escape the
11638  * following character.
11639  *
11640  * This uses unbuffered input, which may be avoidable in some cases.
11641  */
11642 static int
11643 readcmd(int argc, char **argv)
11644 {
11645         char **ap;
11646         int backslash;
11647         char c;
11648         int rflag;
11649         char *prompt;
11650         const char *ifs;
11651         char *p;
11652         int startword;
11653         int status;
11654         int i;
11655 #if ENABLE_ASH_READ_NCHARS
11656         int n_flag = 0;
11657         int nchars = 0;
11658         int silent = 0;
11659         struct termios tty, old_tty;
11660 #endif
11661 #if ENABLE_ASH_READ_TIMEOUT
11662         fd_set set;
11663         struct timeval ts;
11664
11665         ts.tv_sec = ts.tv_usec = 0;
11666 #endif
11667
11668         rflag = 0;
11669         prompt = NULL;
11670 #if ENABLE_ASH_READ_NCHARS && ENABLE_ASH_READ_TIMEOUT
11671         while ((i = nextopt("p:rt:n:s")) != '\0')
11672 #elif ENABLE_ASH_READ_NCHARS
11673         while ((i = nextopt("p:rn:s")) != '\0')
11674 #elif ENABLE_ASH_READ_TIMEOUT
11675         while ((i = nextopt("p:rt:")) != '\0')
11676 #else
11677         while ((i = nextopt("p:r")) != '\0')
11678 #endif
11679         {
11680                 switch (i) {
11681                 case 'p':
11682                         prompt = optionarg;
11683                         break;
11684 #if ENABLE_ASH_READ_NCHARS
11685                 case 'n':
11686                         nchars = bb_strtou(optionarg, NULL, 10);
11687                         if (nchars < 0 || errno)
11688                                 ash_msg_and_raise_error("invalid count");
11689                         n_flag = nchars; /* just a flag "nchars is nonzero" */
11690                         break;
11691                 case 's':
11692                         silent = 1;
11693                         break;
11694 #endif
11695 #if ENABLE_ASH_READ_TIMEOUT
11696                 case 't':
11697                         ts.tv_sec = bb_strtou(optionarg, &p, 10);
11698                         ts.tv_usec = 0;
11699                         /* EINVAL means number is ok, but not terminated by NUL */
11700                         if (*p == '.' && errno == EINVAL) {
11701                                 char *p2;
11702                                 if (*++p) {
11703                                         int scale;
11704                                         ts.tv_usec = bb_strtou(p, &p2, 10);
11705                                         if (errno)
11706                                                 ash_msg_and_raise_error("invalid timeout");
11707                                         scale = p2 - p;
11708                                         /* normalize to usec */
11709                                         if (scale > 6)
11710                                                 ash_msg_and_raise_error("invalid timeout");
11711                                         while (scale++ < 6)
11712                                                 ts.tv_usec *= 10;
11713                                 }
11714                         } else if (ts.tv_sec < 0 || errno) {
11715                                 ash_msg_and_raise_error("invalid timeout");
11716                         }
11717                         if (!(ts.tv_sec | ts.tv_usec)) { /* both are 0? */
11718                                 ash_msg_and_raise_error("invalid timeout");
11719                         }
11720                         break;
11721 #endif
11722                 case 'r':
11723                         rflag = 1;
11724                         break;
11725                 default:
11726                         break;
11727                 }
11728         }
11729         if (prompt && isatty(0)) {
11730                 out2str(prompt);
11731         }
11732         ap = argptr;
11733         if (*ap == NULL)
11734                 ash_msg_and_raise_error("arg count");
11735         ifs = bltinlookup("IFS");
11736         if (ifs == NULL)
11737                 ifs = defifs;
11738 #if ENABLE_ASH_READ_NCHARS
11739         if (n_flag || silent) {
11740                 if (tcgetattr(0, &tty) != 0) {
11741                         /* Not a tty */
11742                         n_flag = 0;
11743                         silent = 0;
11744                 } else {
11745                         old_tty = tty;
11746                         if (n_flag) {
11747                                 tty.c_lflag &= ~ICANON;
11748                                 tty.c_cc[VMIN] = nchars < 256 ? nchars : 255;
11749                         }
11750                         if (silent) {
11751                                 tty.c_lflag &= ~(ECHO | ECHOK | ECHONL);
11752                         }
11753                         tcsetattr(0, TCSANOW, &tty);
11754                 }
11755         }
11756 #endif
11757 #if ENABLE_ASH_READ_TIMEOUT
11758         if (ts.tv_sec || ts.tv_usec) {
11759                 FD_ZERO(&set);
11760                 FD_SET(0, &set);
11761
11762                 /* poll-based wait produces bigger code, using select */
11763                 i = select(1, &set, NULL, NULL, &ts);
11764                 if (!i) { /* timed out! */
11765 #if ENABLE_ASH_READ_NCHARS
11766                         if (n_flag)
11767                                 tcsetattr(0, TCSANOW, &old_tty);
11768 #endif
11769                         return 1;
11770                 }
11771         }
11772 #endif
11773         status = 0;
11774         startword = 1;
11775         backslash = 0;
11776         STARTSTACKSTR(p);
11777         do {
11778                 if (read(0, &c, 1) != 1) {
11779                         status = 1;
11780                         break;
11781                 }
11782                 if (c == '\0')
11783                         continue;
11784                 if (backslash) {
11785                         backslash = 0;
11786                         if (c != '\n')
11787                                 goto put;
11788                         continue;
11789                 }
11790                 if (!rflag && c == '\\') {
11791                         backslash++;
11792                         continue;
11793                 }
11794                 if (c == '\n')
11795                         break;
11796                 if (startword && *ifs == ' ' && strchr(ifs, c)) {
11797                         continue;
11798                 }
11799                 startword = 0;
11800                 if (ap[1] != NULL && strchr(ifs, c) != NULL) {
11801                         STACKSTRNUL(p);
11802                         setvar(*ap, stackblock(), 0);
11803                         ap++;
11804                         startword = 1;
11805                         STARTSTACKSTR(p);
11806                 } else {
11807  put:
11808                         STPUTC(c, p);
11809                 }
11810         }
11811 /* end of do {} while: */
11812 #if ENABLE_ASH_READ_NCHARS
11813         while (!n_flag || --nchars);
11814 #else
11815         while (1);
11816 #endif
11817
11818 #if ENABLE_ASH_READ_NCHARS
11819         if (n_flag || silent)
11820                 tcsetattr(0, TCSANOW, &old_tty);
11821 #endif
11822
11823         STACKSTRNUL(p);
11824         /* Remove trailing blanks */
11825         while ((char *)stackblock() <= --p && strchr(ifs, *p) != NULL)
11826                 *p = '\0';
11827         setvar(*ap, stackblock(), 0);
11828         while (*++ap != NULL)
11829                 setvar(*ap, nullstr, 0);
11830         return status;
11831 }
11832
11833 static int
11834 umaskcmd(int argc, char **argv)
11835 {
11836         static const char permuser[3] ALIGN1 = "ugo";
11837         static const char permmode[3] ALIGN1 = "rwx";
11838         static const short permmask[] ALIGN2 = {
11839                 S_IRUSR, S_IWUSR, S_IXUSR,
11840                 S_IRGRP, S_IWGRP, S_IXGRP,
11841                 S_IROTH, S_IWOTH, S_IXOTH
11842         };
11843
11844         char *ap;
11845         mode_t mask;
11846         int i;
11847         int symbolic_mode = 0;
11848
11849         while (nextopt("S") != '\0') {
11850                 symbolic_mode = 1;
11851         }
11852
11853         INT_OFF;
11854         mask = umask(0);
11855         umask(mask);
11856         INT_ON;
11857
11858         ap = *argptr;
11859         if (ap == NULL) {
11860                 if (symbolic_mode) {
11861                         char buf[18];
11862                         char *p = buf;
11863
11864                         for (i = 0; i < 3; i++) {
11865                                 int j;
11866
11867                                 *p++ = permuser[i];
11868                                 *p++ = '=';
11869                                 for (j = 0; j < 3; j++) {
11870                                         if ((mask & permmask[3 * i + j]) == 0) {
11871                                                 *p++ = permmode[j];
11872                                         }
11873                                 }
11874                                 *p++ = ',';
11875                         }
11876                         *--p = 0;
11877                         puts(buf);
11878                 } else {
11879                         out1fmt("%.4o\n", mask);
11880                 }
11881         } else {
11882                 if (isdigit((unsigned char) *ap)) {
11883                         mask = 0;
11884                         do {
11885                                 if (*ap >= '8' || *ap < '0')
11886                                         ash_msg_and_raise_error(illnum, argv[1]);
11887                                 mask = (mask << 3) + (*ap - '0');
11888                         } while (*++ap != '\0');
11889                         umask(mask);
11890                 } else {
11891                         mask = ~mask & 0777;
11892                         if (!bb_parse_mode(ap, &mask)) {
11893                                 ash_msg_and_raise_error("illegal mode: %s", ap);
11894                         }
11895                         umask(~mask & 0777);
11896                 }
11897         }
11898         return 0;
11899 }
11900
11901 /*
11902  * ulimit builtin
11903  *
11904  * This code, originally by Doug Gwyn, Doug Kingston, Eric Gisin, and
11905  * Michael Rendell was ripped from pdksh 5.0.8 and hacked for use with
11906  * ash by J.T. Conklin.
11907  *
11908  * Public domain.
11909  */
11910
11911 struct limits {
11912         uint8_t cmd;          /* RLIMIT_xxx fit into it */
11913         uint8_t factor_shift; /* shift by to get rlim_{cur,max} values */
11914         char    option;
11915 };
11916
11917 static const struct limits limits_tbl[] = {
11918 #ifdef RLIMIT_CPU
11919         { RLIMIT_CPU,        0, 't' },
11920 #endif
11921 #ifdef RLIMIT_FSIZE
11922         { RLIMIT_FSIZE,      9, 'f' },
11923 #endif
11924 #ifdef RLIMIT_DATA
11925         { RLIMIT_DATA,      10, 'd' },
11926 #endif
11927 #ifdef RLIMIT_STACK
11928         { RLIMIT_STACK,     10, 's' },
11929 #endif
11930 #ifdef RLIMIT_CORE
11931         { RLIMIT_CORE,       9, 'c' },
11932 #endif
11933 #ifdef RLIMIT_RSS
11934         { RLIMIT_RSS,       10, 'm' },
11935 #endif
11936 #ifdef RLIMIT_MEMLOCK
11937         { RLIMIT_MEMLOCK,   10, 'l' },
11938 #endif
11939 #ifdef RLIMIT_NPROC
11940         { RLIMIT_NPROC,      0, 'p' },
11941 #endif
11942 #ifdef RLIMIT_NOFILE
11943         { RLIMIT_NOFILE,     0, 'n' },
11944 #endif
11945 #ifdef RLIMIT_AS
11946         { RLIMIT_AS,        10, 'v' },
11947 #endif
11948 #ifdef RLIMIT_LOCKS
11949         { RLIMIT_LOCKS,      0, 'w' },
11950 #endif
11951 };
11952 static const char limits_name[] =
11953 #ifdef RLIMIT_CPU
11954         "time(seconds)" "\0"
11955 #endif
11956 #ifdef RLIMIT_FSIZE
11957         "file(blocks)" "\0"
11958 #endif
11959 #ifdef RLIMIT_DATA
11960         "data(kb)" "\0"
11961 #endif
11962 #ifdef RLIMIT_STACK
11963         "stack(kb)" "\0"
11964 #endif
11965 #ifdef RLIMIT_CORE
11966         "coredump(blocks)" "\0"
11967 #endif
11968 #ifdef RLIMIT_RSS
11969         "memory(kb)" "\0"
11970 #endif
11971 #ifdef RLIMIT_MEMLOCK
11972         "locked memory(kb)" "\0"
11973 #endif
11974 #ifdef RLIMIT_NPROC
11975         "process" "\0"
11976 #endif
11977 #ifdef RLIMIT_NOFILE
11978         "nofiles" "\0"
11979 #endif
11980 #ifdef RLIMIT_AS
11981         "vmemory(kb)" "\0"
11982 #endif
11983 #ifdef RLIMIT_LOCKS
11984         "locks" "\0"
11985 #endif
11986 ;
11987
11988 enum limtype { SOFT = 0x1, HARD = 0x2 };
11989
11990 static void
11991 printlim(enum limtype how, const struct rlimit *limit,
11992                         const struct limits *l)
11993 {
11994         rlim_t val;
11995
11996         val = limit->rlim_max;
11997         if (how & SOFT)
11998                 val = limit->rlim_cur;
11999
12000         if (val == RLIM_INFINITY)
12001                 out1fmt("unlimited\n");
12002         else {
12003                 val >>= l->factor_shift;
12004                 out1fmt("%lld\n", (long long) val);
12005         }
12006 }
12007
12008 static int
12009 ulimitcmd(int argc, char **argv)
12010 {
12011         int c;
12012         rlim_t val = 0;
12013         enum limtype how = SOFT | HARD;
12014         const struct limits *l;
12015         int set, all = 0;
12016         int optc, what;
12017         struct rlimit limit;
12018
12019         what = 'f';
12020         while ((optc = nextopt("HSa"
12021 #ifdef RLIMIT_CPU
12022                                 "t"
12023 #endif
12024 #ifdef RLIMIT_FSIZE
12025                                 "f"
12026 #endif
12027 #ifdef RLIMIT_DATA
12028                                 "d"
12029 #endif
12030 #ifdef RLIMIT_STACK
12031                                 "s"
12032 #endif
12033 #ifdef RLIMIT_CORE
12034                                 "c"
12035 #endif
12036 #ifdef RLIMIT_RSS
12037                                 "m"
12038 #endif
12039 #ifdef RLIMIT_MEMLOCK
12040                                 "l"
12041 #endif
12042 #ifdef RLIMIT_NPROC
12043                                 "p"
12044 #endif
12045 #ifdef RLIMIT_NOFILE
12046                                 "n"
12047 #endif
12048 #ifdef RLIMIT_AS
12049                                 "v"
12050 #endif
12051 #ifdef RLIMIT_LOCKS
12052                                 "w"
12053 #endif
12054                                         )) != '\0')
12055                 switch (optc) {
12056                 case 'H':
12057                         how = HARD;
12058                         break;
12059                 case 'S':
12060                         how = SOFT;
12061                         break;
12062                 case 'a':
12063                         all = 1;
12064                         break;
12065                 default:
12066                         what = optc;
12067                 }
12068
12069         for (l = limits_tbl; l->option != what; l++)
12070                 continue;
12071
12072         set = *argptr ? 1 : 0;
12073         if (set) {
12074                 char *p = *argptr;
12075
12076                 if (all || argptr[1])
12077                         ash_msg_and_raise_error("too many arguments");
12078                 if (strncmp(p, "unlimited\n", 9) == 0)
12079                         val = RLIM_INFINITY;
12080                 else {
12081                         val = (rlim_t) 0;
12082
12083                         while ((c = *p++) >= '0' && c <= '9') {
12084                                 val = (val * 10) + (long)(c - '0');
12085                                 if (val < (rlim_t) 0)
12086                                         break;
12087                         }
12088                         if (c)
12089                                 ash_msg_and_raise_error("bad number");
12090                         val <<= l->factor_shift;
12091                 }
12092         }
12093         if (all) {
12094                 const char *lname = limits_name;
12095                 for (l = limits_tbl; l != &limits_tbl[ARRAY_SIZE(limits_tbl)]; l++) {
12096                         getrlimit(l->cmd, &limit);
12097                         out1fmt("%-20s ", lname);
12098                         lname += strlen(lname) + 1;
12099                         printlim(how, &limit, l);
12100                 }
12101                 return 0;
12102         }
12103
12104         getrlimit(l->cmd, &limit);
12105         if (set) {
12106                 if (how & HARD)
12107                         limit.rlim_max = val;
12108                 if (how & SOFT)
12109                         limit.rlim_cur = val;
12110                 if (setrlimit(l->cmd, &limit) < 0)
12111                         ash_msg_and_raise_error("error setting limit (%m)");
12112         } else {
12113                 printlim(how, &limit, l);
12114         }
12115         return 0;
12116 }
12117
12118
12119 /* ============ Math support */
12120
12121 #if ENABLE_ASH_MATH_SUPPORT
12122
12123 /* Copyright (c) 2001 Aaron Lehmann <aaronl@vitelus.com>
12124
12125    Permission is hereby granted, free of charge, to any person obtaining
12126    a copy of this software and associated documentation files (the
12127    "Software"), to deal in the Software without restriction, including
12128    without limitation the rights to use, copy, modify, merge, publish,
12129    distribute, sublicense, and/or sell copies of the Software, and to
12130    permit persons to whom the Software is furnished to do so, subject to
12131    the following conditions:
12132
12133    The above copyright notice and this permission notice shall be
12134    included in all copies or substantial portions of the Software.
12135
12136    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
12137    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
12138    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
12139    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
12140    CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
12141    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
12142    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
12143 */
12144
12145 /* This is my infix parser/evaluator. It is optimized for size, intended
12146  * as a replacement for yacc-based parsers. However, it may well be faster
12147  * than a comparable parser written in yacc. The supported operators are
12148  * listed in #defines below. Parens, order of operations, and error handling
12149  * are supported. This code is thread safe. The exact expression format should
12150  * be that which POSIX specifies for shells. */
12151
12152 /* The code uses a simple two-stack algorithm. See
12153  * http://www.onthenet.com.au/~grahamis/int2008/week02/lect02.html
12154  * for a detailed explanation of the infix-to-postfix algorithm on which
12155  * this is based (this code differs in that it applies operators immediately
12156  * to the stack instead of adding them to a queue to end up with an
12157  * expression). */
12158
12159 /* To use the routine, call it with an expression string and error return
12160  * pointer */
12161
12162 /*
12163  * Aug 24, 2001              Manuel Novoa III
12164  *
12165  * Reduced the generated code size by about 30% (i386) and fixed several bugs.
12166  *
12167  * 1) In arith_apply():
12168  *    a) Cached values of *numptr and &(numptr[-1]).
12169  *    b) Removed redundant test for zero denominator.
12170  *
12171  * 2) In arith():
12172  *    a) Eliminated redundant code for processing operator tokens by moving
12173  *       to a table-based implementation.  Also folded handling of parens
12174  *       into the table.
12175  *    b) Combined all 3 loops which called arith_apply to reduce generated
12176  *       code size at the cost of speed.
12177  *
12178  * 3) The following expressions were treated as valid by the original code:
12179  *       1()  ,    0!  ,    1 ( *3 )   .
12180  *    These bugs have been fixed by internally enclosing the expression in
12181  *    parens and then checking that all binary ops and right parens are
12182  *    preceded by a valid expression (NUM_TOKEN).
12183  *
12184  * Note: It may be desirable to replace Aaron's test for whitespace with
12185  * ctype's isspace() if it is used by another busybox applet or if additional
12186  * whitespace chars should be considered.  Look below the "#include"s for a
12187  * precompiler test.
12188  */
12189
12190 /*
12191  * Aug 26, 2001              Manuel Novoa III
12192  *
12193  * Return 0 for null expressions.  Pointed out by Vladimir Oleynik.
12194  *
12195  * Merge in Aaron's comments previously posted to the busybox list,
12196  * modified slightly to take account of my changes to the code.
12197  *
12198  */
12199
12200 /*
12201  *  (C) 2003 Vladimir Oleynik <dzo@simtreas.ru>
12202  *
12203  * - allow access to variable,
12204  *   used recursive find value indirection (c=2*2; a="c"; $((a+=2)) produce 6)
12205  * - realize assign syntax (VAR=expr, +=, *= etc)
12206  * - realize exponentiation (** operator)
12207  * - realize comma separated - expr, expr
12208  * - realise ++expr --expr expr++ expr--
12209  * - realise expr ? expr : expr (but, second expr calculate always)
12210  * - allow hexadecimal and octal numbers
12211  * - was restored loses XOR operator
12212  * - remove one goto label, added three ;-)
12213  * - protect $((num num)) as true zero expr (Manuel`s error)
12214  * - always use special isspace(), see comment from bash ;-)
12215  */
12216
12217 #define arith_isspace(arithval) \
12218         (arithval == ' ' || arithval == '\n' || arithval == '\t')
12219
12220 typedef unsigned char operator;
12221
12222 /* An operator's token id is a bit of a bitfield. The lower 5 bits are the
12223  * precedence, and 3 high bits are an ID unique across operators of that
12224  * precedence. The ID portion is so that multiple operators can have the
12225  * same precedence, ensuring that the leftmost one is evaluated first.
12226  * Consider * and /. */
12227
12228 #define tok_decl(prec,id) (((id)<<5)|(prec))
12229 #define PREC(op) ((op) & 0x1F)
12230
12231 #define TOK_LPAREN tok_decl(0,0)
12232
12233 #define TOK_COMMA tok_decl(1,0)
12234
12235 #define TOK_ASSIGN tok_decl(2,0)
12236 #define TOK_AND_ASSIGN tok_decl(2,1)
12237 #define TOK_OR_ASSIGN tok_decl(2,2)
12238 #define TOK_XOR_ASSIGN tok_decl(2,3)
12239 #define TOK_PLUS_ASSIGN tok_decl(2,4)
12240 #define TOK_MINUS_ASSIGN tok_decl(2,5)
12241 #define TOK_LSHIFT_ASSIGN tok_decl(2,6)
12242 #define TOK_RSHIFT_ASSIGN tok_decl(2,7)
12243
12244 #define TOK_MUL_ASSIGN tok_decl(3,0)
12245 #define TOK_DIV_ASSIGN tok_decl(3,1)
12246 #define TOK_REM_ASSIGN tok_decl(3,2)
12247
12248 /* all assign is right associativity and precedence eq, but (7+3)<<5 > 256 */
12249 #define convert_prec_is_assing(prec) do { if (prec == 3) prec = 2; } while (0)
12250
12251 /* conditional is right associativity too */
12252 #define TOK_CONDITIONAL tok_decl(4,0)
12253 #define TOK_CONDITIONAL_SEP tok_decl(4,1)
12254
12255 #define TOK_OR tok_decl(5,0)
12256
12257 #define TOK_AND tok_decl(6,0)
12258
12259 #define TOK_BOR tok_decl(7,0)
12260
12261 #define TOK_BXOR tok_decl(8,0)
12262
12263 #define TOK_BAND tok_decl(9,0)
12264
12265 #define TOK_EQ tok_decl(10,0)
12266 #define TOK_NE tok_decl(10,1)
12267
12268 #define TOK_LT tok_decl(11,0)
12269 #define TOK_GT tok_decl(11,1)
12270 #define TOK_GE tok_decl(11,2)
12271 #define TOK_LE tok_decl(11,3)
12272
12273 #define TOK_LSHIFT tok_decl(12,0)
12274 #define TOK_RSHIFT tok_decl(12,1)
12275
12276 #define TOK_ADD tok_decl(13,0)
12277 #define TOK_SUB tok_decl(13,1)
12278
12279 #define TOK_MUL tok_decl(14,0)
12280 #define TOK_DIV tok_decl(14,1)
12281 #define TOK_REM tok_decl(14,2)
12282
12283 /* exponent is right associativity */
12284 #define TOK_EXPONENT tok_decl(15,1)
12285
12286 /* For now unary operators. */
12287 #define UNARYPREC 16
12288 #define TOK_BNOT tok_decl(UNARYPREC,0)
12289 #define TOK_NOT tok_decl(UNARYPREC,1)
12290
12291 #define TOK_UMINUS tok_decl(UNARYPREC+1,0)
12292 #define TOK_UPLUS tok_decl(UNARYPREC+1,1)
12293
12294 #define PREC_PRE (UNARYPREC+2)
12295
12296 #define TOK_PRE_INC tok_decl(PREC_PRE, 0)
12297 #define TOK_PRE_DEC tok_decl(PREC_PRE, 1)
12298
12299 #define PREC_POST (UNARYPREC+3)
12300
12301 #define TOK_POST_INC tok_decl(PREC_POST, 0)
12302 #define TOK_POST_DEC tok_decl(PREC_POST, 1)
12303
12304 #define SPEC_PREC (UNARYPREC+4)
12305
12306 #define TOK_NUM tok_decl(SPEC_PREC, 0)
12307 #define TOK_RPAREN tok_decl(SPEC_PREC, 1)
12308
12309 #define NUMPTR (*numstackptr)
12310
12311 static int
12312 tok_have_assign(operator op)
12313 {
12314         operator prec = PREC(op);
12315
12316         convert_prec_is_assing(prec);
12317         return (prec == PREC(TOK_ASSIGN) ||
12318                         prec == PREC_PRE || prec == PREC_POST);
12319 }
12320
12321 static int
12322 is_right_associativity(operator prec)
12323 {
12324         return (prec == PREC(TOK_ASSIGN) || prec == PREC(TOK_EXPONENT)
12325                 || prec == PREC(TOK_CONDITIONAL));
12326 }
12327
12328 typedef struct ARITCH_VAR_NUM {
12329         arith_t val;
12330         arith_t contidional_second_val;
12331         char contidional_second_val_initialized;
12332         char *var;      /* if NULL then is regular number,
12333                            else is variable name */
12334 } v_n_t;
12335
12336 typedef struct CHK_VAR_RECURSIVE_LOOPED {
12337         const char *var;
12338         struct CHK_VAR_RECURSIVE_LOOPED *next;
12339 } chk_var_recursive_looped_t;
12340
12341 static chk_var_recursive_looped_t *prev_chk_var_recursive;
12342
12343 static int
12344 arith_lookup_val(v_n_t *t)
12345 {
12346         if (t->var) {
12347                 const char * p = lookupvar(t->var);
12348
12349                 if (p) {
12350                         int errcode;
12351
12352                         /* recursive try as expression */
12353                         chk_var_recursive_looped_t *cur;
12354                         chk_var_recursive_looped_t cur_save;
12355
12356                         for (cur = prev_chk_var_recursive; cur; cur = cur->next) {
12357                                 if (strcmp(cur->var, t->var) == 0) {
12358                                         /* expression recursion loop detected */
12359                                         return -5;
12360                                 }
12361                         }
12362                         /* save current lookuped var name */
12363                         cur = prev_chk_var_recursive;
12364                         cur_save.var = t->var;
12365                         cur_save.next = cur;
12366                         prev_chk_var_recursive = &cur_save;
12367
12368                         t->val = arith (p, &errcode);
12369                         /* restore previous ptr after recursiving */
12370                         prev_chk_var_recursive = cur;
12371                         return errcode;
12372                 }
12373                 /* allow undefined var as 0 */
12374                 t->val = 0;
12375         }
12376         return 0;
12377 }
12378
12379 /* "applying" a token means performing it on the top elements on the integer
12380  * stack. For a unary operator it will only change the top element, but a
12381  * binary operator will pop two arguments and push a result */
12382 static int
12383 arith_apply(operator op, v_n_t *numstack, v_n_t **numstackptr)
12384 {
12385         v_n_t *numptr_m1;
12386         arith_t numptr_val, rez;
12387         int ret_arith_lookup_val;
12388
12389         /* There is no operator that can work without arguments */
12390         if (NUMPTR == numstack) goto err;
12391         numptr_m1 = NUMPTR - 1;
12392
12393         /* check operand is var with noninteger value */
12394         ret_arith_lookup_val = arith_lookup_val(numptr_m1);
12395         if (ret_arith_lookup_val)
12396                 return ret_arith_lookup_val;
12397
12398         rez = numptr_m1->val;
12399         if (op == TOK_UMINUS)
12400                 rez *= -1;
12401         else if (op == TOK_NOT)
12402                 rez = !rez;
12403         else if (op == TOK_BNOT)
12404                 rez = ~rez;
12405         else if (op == TOK_POST_INC || op == TOK_PRE_INC)
12406                 rez++;
12407         else if (op == TOK_POST_DEC || op == TOK_PRE_DEC)
12408                 rez--;
12409         else if (op != TOK_UPLUS) {
12410                 /* Binary operators */
12411
12412                 /* check and binary operators need two arguments */
12413                 if (numptr_m1 == numstack) goto err;
12414
12415                 /* ... and they pop one */
12416                 --NUMPTR;
12417                 numptr_val = rez;
12418                 if (op == TOK_CONDITIONAL) {
12419                         if (! numptr_m1->contidional_second_val_initialized) {
12420                                 /* protect $((expr1 ? expr2)) without ": expr" */
12421                                 goto err;
12422                         }
12423                         rez = numptr_m1->contidional_second_val;
12424                 } else if (numptr_m1->contidional_second_val_initialized) {
12425                         /* protect $((expr1 : expr2)) without "expr ? " */
12426                         goto err;
12427                 }
12428                 numptr_m1 = NUMPTR - 1;
12429                 if (op != TOK_ASSIGN) {
12430                         /* check operand is var with noninteger value for not '=' */
12431                         ret_arith_lookup_val = arith_lookup_val(numptr_m1);
12432                         if (ret_arith_lookup_val)
12433                                 return ret_arith_lookup_val;
12434                 }
12435                 if (op == TOK_CONDITIONAL) {
12436                         numptr_m1->contidional_second_val = rez;
12437                 }
12438                 rez = numptr_m1->val;
12439                 if (op == TOK_BOR || op == TOK_OR_ASSIGN)
12440                         rez |= numptr_val;
12441                 else if (op == TOK_OR)
12442                         rez = numptr_val || rez;
12443                 else if (op == TOK_BAND || op == TOK_AND_ASSIGN)
12444                         rez &= numptr_val;
12445                 else if (op == TOK_BXOR || op == TOK_XOR_ASSIGN)
12446                         rez ^= numptr_val;
12447                 else if (op == TOK_AND)
12448                         rez = rez && numptr_val;
12449                 else if (op == TOK_EQ)
12450                         rez = (rez == numptr_val);
12451                 else if (op == TOK_NE)
12452                         rez = (rez != numptr_val);
12453                 else if (op == TOK_GE)
12454                         rez = (rez >= numptr_val);
12455                 else if (op == TOK_RSHIFT || op == TOK_RSHIFT_ASSIGN)
12456                         rez >>= numptr_val;
12457                 else if (op == TOK_LSHIFT || op == TOK_LSHIFT_ASSIGN)
12458                         rez <<= numptr_val;
12459                 else if (op == TOK_GT)
12460                         rez = (rez > numptr_val);
12461                 else if (op == TOK_LT)
12462                         rez = (rez < numptr_val);
12463                 else if (op == TOK_LE)
12464                         rez = (rez <= numptr_val);
12465                 else if (op == TOK_MUL || op == TOK_MUL_ASSIGN)
12466                         rez *= numptr_val;
12467                 else if (op == TOK_ADD || op == TOK_PLUS_ASSIGN)
12468                         rez += numptr_val;
12469                 else if (op == TOK_SUB || op == TOK_MINUS_ASSIGN)
12470                         rez -= numptr_val;
12471                 else if (op == TOK_ASSIGN || op == TOK_COMMA)
12472                         rez = numptr_val;
12473                 else if (op == TOK_CONDITIONAL_SEP) {
12474                         if (numptr_m1 == numstack) {
12475                                 /* protect $((expr : expr)) without "expr ? " */
12476                                 goto err;
12477                         }
12478                         numptr_m1->contidional_second_val_initialized = op;
12479                         numptr_m1->contidional_second_val = numptr_val;
12480                 } else if (op == TOK_CONDITIONAL) {
12481                         rez = rez ?
12482                                 numptr_val : numptr_m1->contidional_second_val;
12483                 } else if (op == TOK_EXPONENT) {
12484                         if (numptr_val < 0)
12485                                 return -3;      /* exponent less than 0 */
12486                         else {
12487                                 arith_t c = 1;
12488
12489                                 if (numptr_val)
12490                                         while (numptr_val--)
12491                                                 c *= rez;
12492                                 rez = c;
12493                         }
12494                 } else if (numptr_val==0)          /* zero divisor check */
12495                         return -2;
12496                 else if (op == TOK_DIV || op == TOK_DIV_ASSIGN)
12497                         rez /= numptr_val;
12498                 else if (op == TOK_REM || op == TOK_REM_ASSIGN)
12499                         rez %= numptr_val;
12500         }
12501         if (tok_have_assign(op)) {
12502                 char buf[sizeof(arith_t_type)*3 + 2];
12503
12504                 if (numptr_m1->var == NULL) {
12505                         /* Hmm, 1=2 ? */
12506                         goto err;
12507                 }
12508                 /* save to shell variable */
12509 #if ENABLE_ASH_MATH_SUPPORT_64
12510                 snprintf(buf, sizeof(buf), "%lld", (arith_t_type) rez);
12511 #else
12512                 snprintf(buf, sizeof(buf), "%ld", (arith_t_type) rez);
12513 #endif
12514                 setvar(numptr_m1->var, buf, 0);
12515                 /* after saving, make previous value for v++ or v-- */
12516                 if (op == TOK_POST_INC)
12517                         rez--;
12518                 else if (op == TOK_POST_DEC)
12519                         rez++;
12520         }
12521         numptr_m1->val = rez;
12522         /* protect geting var value, is number now */
12523         numptr_m1->var = NULL;
12524         return 0;
12525  err:
12526         return -1;
12527 }
12528
12529 /* longest must be first */
12530 static const char op_tokens[] ALIGN1 = {
12531         '<','<','=',0, TOK_LSHIFT_ASSIGN,
12532         '>','>','=',0, TOK_RSHIFT_ASSIGN,
12533         '<','<',    0, TOK_LSHIFT,
12534         '>','>',    0, TOK_RSHIFT,
12535         '|','|',    0, TOK_OR,
12536         '&','&',    0, TOK_AND,
12537         '!','=',    0, TOK_NE,
12538         '<','=',    0, TOK_LE,
12539         '>','=',    0, TOK_GE,
12540         '=','=',    0, TOK_EQ,
12541         '|','=',    0, TOK_OR_ASSIGN,
12542         '&','=',    0, TOK_AND_ASSIGN,
12543         '*','=',    0, TOK_MUL_ASSIGN,
12544         '/','=',    0, TOK_DIV_ASSIGN,
12545         '%','=',    0, TOK_REM_ASSIGN,
12546         '+','=',    0, TOK_PLUS_ASSIGN,
12547         '-','=',    0, TOK_MINUS_ASSIGN,
12548         '-','-',    0, TOK_POST_DEC,
12549         '^','=',    0, TOK_XOR_ASSIGN,
12550         '+','+',    0, TOK_POST_INC,
12551         '*','*',    0, TOK_EXPONENT,
12552         '!',        0, TOK_NOT,
12553         '<',        0, TOK_LT,
12554         '>',        0, TOK_GT,
12555         '=',        0, TOK_ASSIGN,
12556         '|',        0, TOK_BOR,
12557         '&',        0, TOK_BAND,
12558         '*',        0, TOK_MUL,
12559         '/',        0, TOK_DIV,
12560         '%',        0, TOK_REM,
12561         '+',        0, TOK_ADD,
12562         '-',        0, TOK_SUB,
12563         '^',        0, TOK_BXOR,
12564         /* uniq */
12565         '~',        0, TOK_BNOT,
12566         ',',        0, TOK_COMMA,
12567         '?',        0, TOK_CONDITIONAL,
12568         ':',        0, TOK_CONDITIONAL_SEP,
12569         ')',        0, TOK_RPAREN,
12570         '(',        0, TOK_LPAREN,
12571         0
12572 };
12573 /* ptr to ")" */
12574 #define endexpression &op_tokens[sizeof(op_tokens)-7]
12575
12576 static arith_t
12577 arith(const char *expr, int *perrcode)
12578 {
12579         char arithval; /* Current character under analysis */
12580         operator lasttok, op;
12581         operator prec;
12582
12583         const char *p = endexpression;
12584         int errcode;
12585
12586         size_t datasizes = strlen(expr) + 2;
12587
12588         /* Stack of integers */
12589         /* The proof that there can be no more than strlen(startbuf)/2+1 integers
12590          * in any given correct or incorrect expression is left as an exercise to
12591          * the reader. */
12592         v_n_t *numstack = alloca(((datasizes)/2)*sizeof(v_n_t)),
12593                                 *numstackptr = numstack;
12594         /* Stack of operator tokens */
12595         operator *stack = alloca((datasizes) * sizeof(operator)),
12596                                 *stackptr = stack;
12597
12598         *stackptr++ = lasttok = TOK_LPAREN;     /* start off with a left paren */
12599         *perrcode = errcode = 0;
12600
12601         while (1) {
12602                 arithval = *expr;
12603                 if (arithval == 0) {
12604                         if (p == endexpression) {
12605                                 /* Null expression. */
12606                                 return 0;
12607                         }
12608
12609                         /* This is only reached after all tokens have been extracted from the
12610                          * input stream. If there are still tokens on the operator stack, they
12611                          * are to be applied in order. At the end, there should be a final
12612                          * result on the integer stack */
12613
12614                         if (expr != endexpression + 1) {
12615                                 /* If we haven't done so already, */
12616                                 /* append a closing right paren */
12617                                 expr = endexpression;
12618                                 /* and let the loop process it. */
12619                                 continue;
12620                         }
12621                         /* At this point, we're done with the expression. */
12622                         if (numstackptr != numstack+1) {
12623                                 /* ... but if there isn't, it's bad */
12624  err:
12625                                 return (*perrcode = -1);
12626                         }
12627                         if (numstack->var) {
12628                                 /* expression is $((var)) only, lookup now */
12629                                 errcode = arith_lookup_val(numstack);
12630                         }
12631  ret:
12632                         *perrcode = errcode;
12633                         return numstack->val;
12634                 }
12635
12636                 /* Continue processing the expression. */
12637                 if (arith_isspace(arithval)) {
12638                         /* Skip whitespace */
12639                         goto prologue;
12640                 }
12641                 p = endofname(expr);
12642                 if (p != expr) {
12643                         size_t var_name_size = (p-expr) + 1;  /* trailing zero */
12644
12645                         numstackptr->var = alloca(var_name_size);
12646                         safe_strncpy(numstackptr->var, expr, var_name_size);
12647                         expr = p;
12648  num:
12649                         numstackptr->contidional_second_val_initialized = 0;
12650                         numstackptr++;
12651                         lasttok = TOK_NUM;
12652                         continue;
12653                 }
12654                 if (isdigit(arithval)) {
12655                         numstackptr->var = NULL;
12656 #if ENABLE_ASH_MATH_SUPPORT_64
12657                         numstackptr->val = strtoll(expr, (char **) &expr, 0);
12658 #else
12659                         numstackptr->val = strtol(expr, (char **) &expr, 0);
12660 #endif
12661                         goto num;
12662                 }
12663                 for (p = op_tokens; ; p++) {
12664                         const char *o;
12665
12666                         if (*p == 0) {
12667                                 /* strange operator not found */
12668                                 goto err;
12669                         }
12670                         for (o = expr; *p && *o == *p; p++)
12671                                 o++;
12672                         if (! *p) {
12673                                 /* found */
12674                                 expr = o - 1;
12675                                 break;
12676                         }
12677                         /* skip tail uncompared token */
12678                         while (*p)
12679                                 p++;
12680                         /* skip zero delim */
12681                         p++;
12682                 }
12683                 op = p[1];
12684
12685                 /* post grammar: a++ reduce to num */
12686                 if (lasttok == TOK_POST_INC || lasttok == TOK_POST_DEC)
12687                         lasttok = TOK_NUM;
12688
12689                 /* Plus and minus are binary (not unary) _only_ if the last
12690                  * token was as number, or a right paren (which pretends to be
12691                  * a number, since it evaluates to one). Think about it.
12692                  * It makes sense. */
12693                 if (lasttok != TOK_NUM) {
12694                         switch (op) {
12695                         case TOK_ADD:
12696                                 op = TOK_UPLUS;
12697                                 break;
12698                         case TOK_SUB:
12699                                 op = TOK_UMINUS;
12700                                 break;
12701                         case TOK_POST_INC:
12702                                 op = TOK_PRE_INC;
12703                                 break;
12704                         case TOK_POST_DEC:
12705                                 op = TOK_PRE_DEC;
12706                                 break;
12707                         }
12708                 }
12709                 /* We don't want a unary operator to cause recursive descent on the
12710                  * stack, because there can be many in a row and it could cause an
12711                  * operator to be evaluated before its argument is pushed onto the
12712                  * integer stack. */
12713                 /* But for binary operators, "apply" everything on the operator
12714                  * stack until we find an operator with a lesser priority than the
12715                  * one we have just extracted. */
12716                 /* Left paren is given the lowest priority so it will never be
12717                  * "applied" in this way.
12718                  * if associativity is right and priority eq, applied also skip
12719                  */
12720                 prec = PREC(op);
12721                 if ((prec > 0 && prec < UNARYPREC) || prec == SPEC_PREC) {
12722                         /* not left paren or unary */
12723                         if (lasttok != TOK_NUM) {
12724                                 /* binary op must be preceded by a num */
12725                                 goto err;
12726                         }
12727                         while (stackptr != stack) {
12728                                 if (op == TOK_RPAREN) {
12729                                         /* The algorithm employed here is simple: while we don't
12730                                          * hit an open paren nor the bottom of the stack, pop
12731                                          * tokens and apply them */
12732                                         if (stackptr[-1] == TOK_LPAREN) {
12733                                                 --stackptr;
12734                                                 /* Any operator directly after a */
12735                                                 lasttok = TOK_NUM;
12736                                                 /* close paren should consider itself binary */
12737                                                 goto prologue;
12738                                         }
12739                                 } else {
12740                                         operator prev_prec = PREC(stackptr[-1]);
12741
12742                                         convert_prec_is_assing(prec);
12743                                         convert_prec_is_assing(prev_prec);
12744                                         if (prev_prec < prec)
12745                                                 break;
12746                                         /* check right assoc */
12747                                         if (prev_prec == prec && is_right_associativity(prec))
12748                                                 break;
12749                                 }
12750                                 errcode = arith_apply(*--stackptr, numstack, &numstackptr);
12751                                 if (errcode) goto ret;
12752                         }
12753                         if (op == TOK_RPAREN) {
12754                                 goto err;
12755                         }
12756                 }
12757
12758                 /* Push this operator to the stack and remember it. */
12759                 *stackptr++ = lasttok = op;
12760  prologue:
12761                 ++expr;
12762         } /* while */
12763 }
12764 #endif /* ASH_MATH_SUPPORT */
12765
12766
12767 /* ============ main() and helpers */
12768
12769 /*
12770  * Called to exit the shell.
12771  */
12772 static void exitshell(void) ATTRIBUTE_NORETURN;
12773 static void
12774 exitshell(void)
12775 {
12776         struct jmploc loc;
12777         char *p;
12778         int status;
12779
12780         status = exitstatus;
12781         TRACE(("pid %d, exitshell(%d)\n", getpid(), status));
12782         if (setjmp(loc.loc)) {
12783                 if (exception == EXEXIT)
12784 /* dash bug: it just does _exit(exitstatus) here
12785  * but we have to do setjobctl(0) first!
12786  * (bug is still not fixed in dash-0.5.3 - if you run dash
12787  * under Midnight Commander, on exit from dash MC is backgrounded) */
12788                         status = exitstatus;
12789                 goto out;
12790         }
12791         exception_handler = &loc;
12792         p = trap[0];
12793         if (p) {
12794                 trap[0] = NULL;
12795                 evalstring(p, 0);
12796         }
12797         flush_stdout_stderr();
12798  out:
12799         setjobctl(0);
12800         _exit(status);
12801         /* NOTREACHED */
12802 }
12803
12804 static void
12805 init(void)
12806 {
12807         /* from input.c: */
12808         basepf.nextc = basepf.buf = basebuf;
12809
12810         /* from trap.c: */
12811         signal(SIGCHLD, SIG_DFL);
12812
12813         /* from var.c: */
12814         {
12815                 char **envp;
12816                 char ppid[sizeof(int)*3 + 1];
12817                 const char *p;
12818                 struct stat st1, st2;
12819
12820                 initvar();
12821                 for (envp = environ; envp && *envp; envp++) {
12822                         if (strchr(*envp, '=')) {
12823                                 setvareq(*envp, VEXPORT|VTEXTFIXED);
12824                         }
12825                 }
12826
12827                 snprintf(ppid, sizeof(ppid), "%u", (unsigned) getppid());
12828                 setvar("PPID", ppid, 0);
12829
12830                 p = lookupvar("PWD");
12831                 if (p)
12832                         if (*p != '/' || stat(p, &st1) || stat(".", &st2)
12833                          || st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino)
12834                                 p = '\0';
12835                 setpwd(p, 0);
12836         }
12837 }
12838
12839 /*
12840  * Process the shell command line arguments.
12841  */
12842 static void
12843 procargs(int argc, char **argv)
12844 {
12845         int i;
12846         const char *xminusc;
12847         char **xargv;
12848
12849         xargv = argv;
12850         arg0 = xargv[0];
12851         if (argc > 0)
12852                 xargv++;
12853         for (i = 0; i < NOPTS; i++)
12854                 optlist[i] = 2;
12855         argptr = xargv;
12856         if (options(1)) {
12857                 /* it already printed err message */
12858                 raise_exception(EXERROR);
12859         }
12860         xargv = argptr;
12861         xminusc = minusc;
12862         if (*xargv == NULL) {
12863                 if (xminusc)
12864                         ash_msg_and_raise_error(bb_msg_requires_arg, "-c");
12865                 sflag = 1;
12866         }
12867         if (iflag == 2 && sflag == 1 && isatty(0) && isatty(1))
12868                 iflag = 1;
12869         if (mflag == 2)
12870                 mflag = iflag;
12871         for (i = 0; i < NOPTS; i++)
12872                 if (optlist[i] == 2)
12873                         optlist[i] = 0;
12874 #if DEBUG == 2
12875         debug = 1;
12876 #endif
12877         /* POSIX 1003.2: first arg after -c cmd is $0, remainder $1... */
12878         if (xminusc) {
12879                 minusc = *xargv++;
12880                 if (*xargv)
12881                         goto setarg0;
12882         } else if (!sflag) {
12883                 setinputfile(*xargv, 0);
12884  setarg0:
12885                 arg0 = *xargv++;
12886                 commandname = arg0;
12887         }
12888
12889         shellparam.p = xargv;
12890 #if ENABLE_ASH_GETOPTS
12891         shellparam.optind = 1;
12892         shellparam.optoff = -1;
12893 #endif
12894         /* assert(shellparam.malloced == 0 && shellparam.nparam == 0); */
12895         while (*xargv) {
12896                 shellparam.nparam++;
12897                 xargv++;
12898         }
12899         optschanged();
12900 }
12901
12902 /*
12903  * Read /etc/profile or .profile.
12904  */
12905 static void
12906 read_profile(const char *name)
12907 {
12908         int skip;
12909
12910         if (setinputfile(name, INPUT_PUSH_FILE | INPUT_NOFILE_OK) < 0)
12911                 return;
12912         skip = cmdloop(0);
12913         popfile();
12914         if (skip)
12915                 exitshell();
12916 }
12917
12918 /*
12919  * This routine is called when an error or an interrupt occurs in an
12920  * interactive shell and control is returned to the main command loop.
12921  */
12922 static void
12923 reset(void)
12924 {
12925         /* from eval.c: */
12926         evalskip = 0;
12927         loopnest = 0;
12928         /* from input.c: */
12929         parselleft = parsenleft = 0;      /* clear input buffer */
12930         popallfiles();
12931         /* from parser.c: */
12932         tokpushback = 0;
12933         checkkwd = 0;
12934         /* from redir.c: */
12935         clearredir(0);
12936 }
12937
12938 #if PROFILE
12939 static short profile_buf[16384];
12940 extern int etext();
12941 #endif
12942
12943 /*
12944  * Main routine.  We initialize things, parse the arguments, execute
12945  * profiles if we're a login shell, and then call cmdloop to execute
12946  * commands.  The setjmp call sets up the location to jump to when an
12947  * exception occurs.  When an exception occurs the variable "state"
12948  * is used to figure out how far we had gotten.
12949  */
12950 int ash_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
12951 int ash_main(int argc, char **argv)
12952 {
12953         char *shinit;
12954         volatile int state;
12955         struct jmploc jmploc;
12956         struct stackmark smark;
12957
12958         /* Initialize global data */
12959         INIT_G_misc();
12960         INIT_G_memstack();
12961         INIT_G_var();
12962 #if ENABLE_ASH_ALIAS
12963         INIT_G_alias();
12964 #endif
12965         INIT_G_cmdtable();
12966
12967 #if PROFILE
12968         monitor(4, etext, profile_buf, sizeof(profile_buf), 50);
12969 #endif
12970
12971 #if ENABLE_FEATURE_EDITING
12972         line_input_state = new_line_input_t(FOR_SHELL | WITH_PATH_LOOKUP);
12973 #endif
12974         state = 0;
12975         if (setjmp(jmploc.loc)) {
12976                 int e;
12977                 int s;
12978
12979                 reset();
12980
12981                 e = exception;
12982                 if (e == EXERROR)
12983                         exitstatus = 2;
12984                 s = state;
12985                 if (e == EXEXIT || s == 0 || iflag == 0 || shlvl)
12986                         exitshell();
12987
12988                 if (e == EXINT) {
12989                         outcslow('\n', stderr);
12990                 }
12991                 popstackmark(&smark);
12992                 FORCE_INT_ON; /* enable interrupts */
12993                 if (s == 1)
12994                         goto state1;
12995                 if (s == 2)
12996                         goto state2;
12997                 if (s == 3)
12998                         goto state3;
12999                 goto state4;
13000         }
13001         exception_handler = &jmploc;
13002 #if DEBUG
13003         opentrace();
13004         trace_puts("Shell args: ");
13005         trace_puts_args(argv);
13006 #endif
13007         rootpid = getpid();
13008
13009 #if ENABLE_ASH_RANDOM_SUPPORT
13010         rseed = rootpid + time(NULL);
13011 #endif
13012         init();
13013         setstackmark(&smark);
13014         procargs(argc, argv);
13015 #if ENABLE_FEATURE_EDITING_SAVEHISTORY
13016         if (iflag) {
13017                 const char *hp = lookupvar("HISTFILE");
13018
13019                 if (hp == NULL) {
13020                         hp = lookupvar("HOME");
13021                         if (hp != NULL) {
13022                                 char *defhp = concat_path_file(hp, ".ash_history");
13023                                 setvar("HISTFILE", defhp, 0);
13024                                 free(defhp);
13025                         }
13026                 }
13027         }
13028 #endif
13029         if (argv[0] && argv[0][0] == '-')
13030                 isloginsh = 1;
13031         if (isloginsh) {
13032                 state = 1;
13033                 read_profile("/etc/profile");
13034  state1:
13035                 state = 2;
13036                 read_profile(".profile");
13037         }
13038  state2:
13039         state = 3;
13040         if (
13041 #ifndef linux
13042          getuid() == geteuid() && getgid() == getegid() &&
13043 #endif
13044          iflag
13045         ) {
13046                 shinit = lookupvar("ENV");
13047                 if (shinit != NULL && *shinit != '\0') {
13048                         read_profile(shinit);
13049                 }
13050         }
13051  state3:
13052         state = 4;
13053         if (minusc)
13054                 evalstring(minusc, 0);
13055
13056         if (sflag || minusc == NULL) {
13057 #if ENABLE_FEATURE_EDITING_SAVEHISTORY
13058                 if ( iflag ) {
13059                         const char *hp = lookupvar("HISTFILE");
13060
13061                         if (hp != NULL)
13062                                 line_input_state->hist_file = hp;
13063                 }
13064 #endif
13065  state4: /* XXX ??? - why isn't this before the "if" statement */
13066                 cmdloop(1);
13067         }
13068 #if PROFILE
13069         monitor(0);
13070 #endif
13071 #ifdef GPROF
13072         {
13073                 extern void _mcleanup(void);
13074                 _mcleanup();
13075         }
13076 #endif
13077         exitshell();
13078         /* NOTREACHED */
13079 }
13080
13081 #if DEBUG
13082 const char *applet_name = "debug stuff usage";
13083 int main(int argc, char **argv)
13084 {
13085         return ash_main(argc, argv);
13086 }
13087 #endif
13088
13089
13090 /*-
13091  * Copyright (c) 1989, 1991, 1993, 1994
13092  *      The Regents of the University of California.  All rights reserved.
13093  *
13094  * This code is derived from software contributed to Berkeley by
13095  * Kenneth Almquist.
13096  *
13097  * Redistribution and use in source and binary forms, with or without
13098  * modification, are permitted provided that the following conditions
13099  * are met:
13100  * 1. Redistributions of source code must retain the above copyright
13101  *    notice, this list of conditions and the following disclaimer.
13102  * 2. Redistributions in binary form must reproduce the above copyright
13103  *    notice, this list of conditions and the following disclaimer in the
13104  *    documentation and/or other materials provided with the distribution.
13105  * 3. Neither the name of the University nor the names of its contributors
13106  *    may be used to endorse or promote products derived from this software
13107  *    without specific prior written permission.
13108  *
13109  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
13110  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
13111  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
13112  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
13113  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
13114  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
13115  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
13116  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
13117  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
13118  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
13119  * SUCH DAMAGE.
13120  */