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