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