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