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