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