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