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