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