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