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