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