stop using __u32 etc. uint32_t is there for a reason
[oweals/busybox.git] / shell / ash.c
index 0d9fa7fe2e18e1cf23805563730f65e5dec420fc..6d96bce5aefb48288d9449017d6a36f83a07ffde 100644 (file)
@@ -42,6 +42,7 @@
  * When debugging is on, debugging info will be written to ./trace and
  * a quit signal will generate a core dump.
  */
+#define DEBUG 0
 
 
 #define IFS_BROKEN
@@ -50,7 +51,7 @@
 
 #include "busybox.h"
 
-#ifdef DEBUG
+#if DEBUG
 #define _GNU_SOURCE
 #endif
 
 #include <time.h>
 #include <fnmatch.h>
 
-#include "pwd_.h"
-
 #ifdef CONFIG_ASH_JOB_CONTROL
 #define JOBS 1
 #else
-#undef JOBS
+#define JOBS 0
 #endif
 
 #if JOBS || defined(CONFIG_ASH_READ_NCHARS)
@@ -106,7 +105,7 @@ static int *dash_errno;
 #error "Do not even bother, ash will not run on uClinux"
 #endif
 
-#ifdef DEBUG
+#if DEBUG
 #define _DIAGASSERT(assert_expr) assert(assert_expr)
 #else
 #define _DIAGASSERT(assert_expr)
@@ -584,7 +583,7 @@ static const char dolatstr[] = { CTLVAR, VSNORMAL|VSQUOTE, '@', '=', '\0' };
 static const char illnum[] = "Illegal number: %s";
 static const char homestr[] = "HOME";
 
-#ifdef DEBUG
+#if DEBUG
 #define TRACE(param)    trace param
 #define TRACEV(param)   tracev param
 #else
@@ -1382,15 +1381,7 @@ static const struct builtincmd builtincmd[] = {
        { BUILTIN_REGULAR       "wait", waitcmd },
 };
 
-#define NUMBUILTINS  (sizeof (builtincmd) / sizeof (struct builtincmd) )
-
-static const char *safe_applets[] = { 
-       "[", "test", "echo", "cat",
-       "ln", "cp", "touch", "mkdir", "rm",
-       "cut", "hexdump", "awk", "sort",
-       "find", "xargs", "ls", "dd",
-       "chown", "chmod"
-};
+#define NUMBUILTINS (sizeof(builtincmd) / sizeof(builtincmd[0]))
 
 
 struct cmdentry {
@@ -1496,7 +1487,6 @@ static void getoptsreset(const char *);
 #endif
 
 #ifdef CONFIG_LOCALE_SUPPORT
-#include <locale.h>
 static void change_lc_all(const char *value);
 static void change_lc_ctype(const char *value);
 #endif
@@ -1939,7 +1929,7 @@ struct shparam {
 #define uflag optlist[12]
 #define viflag optlist[13]
 
-#ifdef DEBUG
+#if DEBUG
 #define nolog optlist[14]
 #define debug optlist[15]
 #endif
@@ -1966,7 +1956,7 @@ static const char *const optletters_optnames[] = {
        "b"   "notify",
        "u"   "nounset",
        "\0"  "vi",
-#ifdef DEBUG
+#if DEBUG
        "\0"  "nolog",
        "\0"  "debug",
 #endif
@@ -2013,7 +2003,7 @@ static int redirectsafe(union node *, int);
 /*      show.h     */
 
 
-#ifdef DEBUG
+#if DEBUG
 static void showtree(union node *);
 static void trace(const char *, ...);
 static void tracev(const char *, va_list);
@@ -2044,7 +2034,30 @@ static void exitshell(void) ATTRIBUTE_NORETURN;
 
 static int is_safe_applet(char *name)
 {
-       int n = sizeof(safe_applets) / sizeof(char *);
+       /* It isn't a bug to have non-existent applet here... */
+       /* ...just a waste of space... */
+       static const char safe_applets[][8] = { 
+               "["
+               USE_AWK    (, "awk"    )
+               USE_CAT    (, "cat"    )
+               USE_CHMOD  (, "chmod"  )
+               USE_CHOWN  (, "chown"  )
+               USE_CP     (, "cp"     )
+               USE_CUT    (, "cut"    )
+               USE_DD     (, "dd"     )
+               USE_ECHO   (, "echo"   )
+               USE_FIND   (, "find"   )
+               USE_HEXDUMP(, "hexdump")
+               USE_LN     (, "ln"     )
+               USE_LS     (, "ls"     )
+               USE_MKDIR  (, "mkdir"  )
+               USE_RM     (, "rm"     )
+               USE_SORT   (, "sort"   )
+               USE_TEST   (, "test"   )
+               USE_TOUCH  (, "touch"  )
+               USE_XARGS  (, "xargs"  )
+       };
+       int n = sizeof(safe_applets) / sizeof(safe_applets[0]);
        int i;
        for (i = 0; i < n; i++)
                if (strcmp(safe_applets[i], name) == 0)
@@ -2131,10 +2144,10 @@ unalias(const char *name)
                INTOFF;
                *app = freealias(*app);
                INTON;
-               return (0);
+               return 0;
        }
 
-       return (1);
+       return 1;
 }
 
 static void
@@ -2162,8 +2175,8 @@ lookupalias(const char *name, int check)
        struct alias *ap = *__lookupalias(name);
 
        if (check && ap && (ap->flag & ALIASINUSE))
-               return (NULL);
-       return (ap);
+               return NULL;
+       return ap;
 }
 
 /*
@@ -2183,7 +2196,7 @@ aliascmd(int argc, char **argv)
                        for (ap = atab[i]; ap; ap = ap->next) {
                                printalias(ap);
                        }
-               return (0);
+               return 0;
        }
        while ((n = *++argv) != NULL) {
                if ((v = strchr(n+1, '=')) == NULL) { /* n+1: funny ksh stuff */
@@ -2198,7 +2211,7 @@ aliascmd(int argc, char **argv)
                }
        }
 
-       return (ret);
+       return ret;
 }
 
 static int
@@ -2209,7 +2222,7 @@ unaliascmd(int argc, char **argv)
        while ((i = nextopt("a")) != '\0') {
                if (i == 'a') {
                        rmaliases();
-                       return (0);
+                       return 0;
                }
        }
        for (i = 0; *argptr; argptr++) {
@@ -2219,7 +2232,7 @@ unaliascmd(int argc, char **argv)
                }
        }
 
-       return (i);
+       return i;
 }
 
 static struct alias *
@@ -2317,7 +2330,7 @@ cdcmd(int argc, char **argv)
        dest = *argptr;
        if (!dest)
                dest = bltinlookup(homestr);
-       else if (dest[0] == '-' && dest[1] == '\0') {
+       else if (LONE_DASH(dest)) {
                dest = bltinlookup("OLDPWD");
                flags |= CD_PRINT;
        }
@@ -2404,7 +2417,7 @@ static const char * updatepwd(const char *dir)
        }
        p = strtok(cdcomppath, "/");
        while (p) {
-               switch(*p) {
+               switch (*p) {
                case '.':
                        if (p[1] == '.' && p[2] == '\0') {
                                while (new > lim) {
@@ -2538,7 +2551,7 @@ static void exverror(int, const char *, va_list)
 static void
 exraise(int e)
 {
-#ifdef DEBUG
+#if DEBUG
        if (handler == NULL)
                abort();
 #endif
@@ -2598,7 +2611,7 @@ exvwarning(const char *msg, va_list ap)
 static void
 exverror(int cond, const char *msg, va_list ap)
 {
-#ifdef DEBUG
+#if DEBUG
        if (msg) {
                TRACE(("exverror(%d, \"", cond));
                TRACEV((msg, ap));
@@ -2787,7 +2800,7 @@ evaltree(union node *n, int flags)
            getpid(), n, n->type, flags));
        switch (n->type) {
        default:
-#ifdef DEBUG
+#if DEBUG
                out1fmt("Node type = %d\n", n->type);
                fflush(stdout);
                break;
@@ -3044,6 +3057,7 @@ expredir(union node *n)
 
        for (redir = n ; redir ; redir = redir->nfile.next) {
                struct arglist fn;
+               memset(&fn, 0, sizeof(struct arglist));
                fn.lastp = &fn.list;
                switch (redir->type) {
                case NFROMTO:
@@ -3058,7 +3072,10 @@ expredir(union node *n)
                case NTOFD:
                        if (redir->ndup.vname) {
                                expandarg(redir->ndup.vname, &fn, EXP_FULL | EXP_TILDE);
-                               fixredir(redir, fn.list->text, 1);
+                               if (fn.list != NULL)
+                                       fixredir(redir, fn.list->text, 1);
+                               else
+                                       sh_error("redir error");
                        }
                        break;
                }
@@ -3700,12 +3717,11 @@ shellexec(char **argv, const char *path, int idx)
 
        clearredir(1);
        envp = environment();
-       if (strchr(argv[0], '/') != NULL
-               || is_safe_applet(argv[0])
+       if (strchr(argv[0], '/')
 #ifdef CONFIG_FEATURE_SH_STANDALONE_SHELL
-               || find_applet_by_name(argv[0])
+        || find_applet_by_name(argv[0])
 #endif
-                                               ) {
+       ) {
                tryexec(argv[0], argv, envp);
                e = errno;
        } else {
@@ -3748,7 +3764,10 @@ tryexec(char *cmd, char **argv, char **envp)
        int argc = 0;
        char **c;
        
-       if(strchr(cmd, '/') == NULL && is_safe_applet(cmd) && (a = find_applet_by_name(cmd)) != NULL) {
+       if (strchr(cmd, '/') == NULL
+        && (a = find_applet_by_name(cmd)) != NULL
+        && is_safe_applet(cmd)
+       ) {
                c = argv;
                while (*c != NULL) {
                        c++; argc++;
@@ -3757,7 +3776,7 @@ tryexec(char *cmd, char **argv, char **envp)
                exit(a->main(argc, argv));
        }
 #ifdef CONFIG_FEATURE_SH_STANDALONE_SHELL
-       if(find_applet_by_name(cmd) != NULL) {
+       if (find_applet_by_name(cmd) != NULL) {
                /* re-exec ourselves with the new arguments */
                execve(CONFIG_BUSYBOX_EXEC_PATH,argv,envp);
                /* If they called chroot or otherwise made the binary no longer
@@ -4479,7 +4498,7 @@ commandcmd(int argc, char **argv)
                        verify |= VERIFY_VERBOSE;
                else if (c == 'v')
                        verify |= VERIFY_BRIEF;
-#ifdef DEBUG
+#if DEBUG
                else if (c != 'p')
                        abort();
 #endif
@@ -4800,11 +4819,11 @@ exptilde(char *startp, char *p, int flag)
        name = p + 1;
 
        while ((c = *++p) != '\0') {
-               switch(c) {
+               switch (c) {
                case CTLESC:
-                       return (startp);
+                       return startp;
                case CTLQUOTEMARK:
-                       return (startp);
+                       return startp;
                case ':':
                        if (flag & EXP_VARTILDE)
                                goto done;
@@ -4829,10 +4848,10 @@ done:
        startloc = expdest - (char *)stackblock();
        strtodest(home, SQSYNTAX, quotes);
        recordregion(startloc, expdest - (char *)stackblock(), 0);
-       return (p);
+       return p;
 lose:
        *p = c;
-       return (startp);
+       return startp;
 }
 
 
@@ -4905,7 +4924,7 @@ expari(int quotes)
 
                while (*p != CTLARI) {
                        p--;
-#ifdef DEBUG
+#if DEBUG
                        if (p < start) {
                                sh_error("missing CTLARI (shouldn't happen)");
                        }
@@ -5098,7 +5117,7 @@ subevalvar(char *p, char *str, int strloc, int subtype, int startloc, int varfla
        }
 
        subtype -= VSTRIMRIGHT;
-#ifdef DEBUG
+#if DEBUG
        if (subtype < 0 || subtype > 3)
                abort();
 #endif
@@ -5221,7 +5240,7 @@ record:
                goto end;
        }
 
-#ifdef DEBUG
+#if DEBUG
        switch (subtype) {
        case VSTRIMLEFT:
        case VSTRIMLEFTMAX:
@@ -5849,7 +5868,7 @@ _rmescapes(char *str, int flag)
                }
                q = r;
                if (len > 0) {
-                       q = mempcpy(q, str, len);
+                       q = memcpy(q, str, len) + len;
                }
        }
        inquotes = (flag & RMESCAPE_QUOTED) ^ RMESCAPE_QUOTED;
@@ -6458,7 +6477,7 @@ set_curjob(struct job *jp, unsigned mode)
        jpp = curp;
        switch (mode) {
        default:
-#ifdef DEBUG
+#if DEBUG
                abort();
 #endif
        case CUR_DELETE:
@@ -6579,7 +6598,7 @@ usage:
                        while ((c = nextopt("ls:")) != '\0')
                                switch (c) {
                                default:
-#ifdef DEBUG
+#if DEBUG
                                        abort();
 #endif
                                case 'l':
@@ -6645,7 +6664,7 @@ usage:
 }
 #endif /* JOBS */
 
-#if defined(JOBS) || defined(DEBUG)
+#if JOBS || DEBUG
 static int
 jobno(const struct job *jp)
 {
@@ -7825,7 +7844,7 @@ chkmail(void)
                if (*p == '\0')
                        continue;
                for (q = p ; *q ; q++);
-#ifdef DEBUG
+#if DEBUG
                if (q[-1] != '/')
                        abort();
 #endif
@@ -7919,7 +7938,7 @@ ash_main(int argc, char **argv)
                        goto state4;
        }
        handler = &jmploc;
-#ifdef DEBUG
+#if DEBUG
        opentrace();
        trputs("Shell args:  ");  trargs(argv);
 #endif
@@ -7986,7 +8005,7 @@ state4: /* XXX ??? - why isn't this before the "if" statement */
 #if PROFILE
        monitor(0);
 #endif
-#if GPROF
+#ifdef GPROF
        {
                extern void _mcleanup(void);
                _mcleanup();
@@ -8170,7 +8189,7 @@ exitcmd(int argc, char **argv)
 static int
 echocmd(int argc, char **argv)
 {
-       return bb_echo(argc, argv);
+       return bb_echo(argv);
 }
 #endif
 
@@ -8264,7 +8283,7 @@ stalloc(size_t nbytes)
 void
 stunalloc(pointer p)
 {
-#ifdef DEBUG
+#if DEBUG
        if (!p || (stacknxt < (char *)p) || ((char *)p < stackp->space)) {
                write(2, "stunalloc\n", 10);
                abort();
@@ -8431,7 +8450,7 @@ char *
 stnputs(const char *s, size_t n, char *p)
 {
        p = makestrspace(n, p);
-       p = mempcpy(p, s, n);
+       p = memcpy(p, s, n) + n;
        return p;
 }
 
@@ -8515,7 +8534,7 @@ single_quote(const char *s) {
                q = p = makestrspace(len + 3, p);
 
                *q++ = '\'';
-               q = mempcpy(q, s, len);
+               q = memcpy(q, s, len) + len;
                *q++ = '\'';
                s += len;
 
@@ -8528,7 +8547,7 @@ single_quote(const char *s) {
                q = p = makestrspace(len + 3, p);
 
                *q++ = '"';
-               q = mempcpy(q, s, len);
+               q = memcpy(q, s, len) + len;
                *q++ = '"';
                s += len;
 
@@ -8752,11 +8771,12 @@ copynodelist(struct nodelist *lp)
 
 
 static char *
-nodesavestr(char   *s)
+nodesavestr(char *s)
 {
-       char   *rtn = funcstring;
+       char *rtn = funcstring;
 
-       funcstring = stpcpy(funcstring, s) + 1;
+       strcpy(funcstring, s);
+       funcstring += strlen(s) + 1;
        return rtn;
 }
 
@@ -8842,7 +8862,7 @@ setarg0:
 void
 optschanged(void)
 {
-#ifdef DEBUG
+#if DEBUG
        opentrace();
 #endif
        setinteractive(iflag);
@@ -8887,7 +8907,7 @@ options(int cmdline)
                argptr++;
                if ((c = *p++) == '-') {
                        val = 1;
-                       if (p[0] == '\0' || (p[0] == '-' && p[1] == '\0')) {
+                       if (p[0] == '\0' || LONE_DASH(p)) {
                                if (!cmdline) {
                                        /* "-" means turn off -x and -v */
                                        if (p[0] == '\0')
@@ -9112,7 +9132,7 @@ atend:
                        goto out;
                }
                optnext++;
-               if (p[0] == '-' && p[1] == '\0')        /* check for "--" */
+               if (LONE_DASH(p))        /* check for "--" */
                        goto atend;
        }
 
@@ -9230,7 +9250,7 @@ nextopt(const char *optstring)
                if (p == NULL || *p != '-' || *++p == '\0')
                        return '\0';
                argptr++;
-               if (p[0] == '-' && p[1] == '\0')        /* check for "--" */
+               if (LONE_DASH(p))        /* check for "--" */
                        return '\0';
        }
        c = *p++;
@@ -9823,7 +9843,7 @@ void fixredir(union node *n, const char *text, int err)
 
        if (is_digit(text[0]) && text[1] == '\0')
                n->ndup.dupfd = digit_val(text[0]);
-       else if (text[0] == '-' && text[1] == '\0')
+       else if (LONE_DASH(text))
                n->ndup.dupfd = -1;
        else {
 
@@ -9911,7 +9931,7 @@ static int
 readtoken(void)
 {
        int t;
-#ifdef DEBUG
+#if DEBUG
        int alreadyseen = tokpushback;
 #endif
 
@@ -9961,13 +9981,13 @@ top:
        }
 out:
        checkkwd = 0;
-#ifdef DEBUG
+#if DEBUG
        if (!alreadyseen)
            TRACE(("token %s %s\n", tokname(t), t == TWORD ? wordtext : ""));
        else
            TRACE(("reread token %s %s\n", tokname(t), t == TWORD ? wordtext : ""));
 #endif
-       return (t);
+       return t;
 }
 
 
@@ -10208,7 +10228,7 @@ readtoken1(int firstc, int syntax, char *eofmark, int striptabs)
                CHECKEND();     /* set c to PEOF if at end of here document */
                for (;;) {      /* until end of line or end of word */
                        CHECKSTRSPACE(4, out);  /* permit 4 calls to USTPUTC */
-                       switch(SIT(c, syntax)) {
+                       switch (SIT(c, syntax)) {
                        case CNL:       /* '\n' */
                                if (syntax == BASESYNTAX)
                                        goto endword;   /* exit outer loop */
@@ -11051,7 +11071,7 @@ openredirect(union node *redir)
                        goto ecreate;
                break;
        default:
-#ifdef DEBUG
+#if DEBUG
                abort();
 #endif
                /* Fall through to eliminate warning. */
@@ -11253,7 +11273,7 @@ redirectsafe(union node *redir, int flags)
 
 /*      show.c    */
 
-#ifdef DEBUG
+#if DEBUG
 static void shtree(union node *, int, char *, FILE*);
 static void shcmd(union node *, FILE *);
 static void sharg(union node *, FILE *);
@@ -11279,7 +11299,7 @@ shtree(union node *n, int ind, char *pfx, FILE *fp)
                return;
 
        indent(ind, pfx, fp);
-       switch(n->type) {
+       switch (n->type) {
        case NSEMI:
                s = "; ";
                goto binop;
@@ -11648,7 +11668,7 @@ trapcmd(int argc, char **argv)
                        sh_error("%s: bad trap", *ap);
                INTOFF;
                if (action) {
-                       if (action[0] == '-' && action[1] == '\0')
+                       if (LONE_DASH(action))
                                action = NULL;
                        else
                                action = savestr(action);
@@ -11712,7 +11732,7 @@ setsignal(int signo)
                                action = S_CATCH;
                        break;
                case SIGQUIT:
-#ifdef DEBUG
+#if DEBUG
                        if (debug)
                                break;
 #endif
@@ -11890,17 +11910,11 @@ static int helpcmd(int argc, char **argv)
                }
        }
 #ifdef CONFIG_FEATURE_SH_STANDALONE_SHELL
-       {
-               extern const struct BB_applet applets[];
-               extern const size_t NUM_APPLETS;
-
-               for (i = 0; i < NUM_APPLETS; i++) {
-
-                       col += out1fmt("%c%s", ((col == 0) ? '\t' : ' '), applets[i].name);
-                       if (col > 60) {
-                               out1fmt("\n");
-                               col = 0;
-                       }
+       for (i = 0; i < NUM_APPLETS; i++) {
+               col += out1fmt("%c%s", ((col == 0) ? '\t' : ' '), applets[i].name);
+               if (col > 60) {
+                       out1fmt("\n");
+                       col = 0;
                }
        }
 #endif
@@ -12011,10 +12025,11 @@ setvar(const char *name, const char *val, int flags)
                vallen = strlen(val);
        }
        INTOFF;
-       p = mempcpy(nameeq = ckmalloc(namelen + vallen + 2), name, namelen);
+       nameeq = ckmalloc(namelen + vallen + 2);
+       p = memcpy(nameeq, name, namelen) + namelen;
        if (val) {
                *p++ = '=';
-               p = mempcpy(p, val, vallen);
+               p = memcpy(p, val, vallen) + vallen;
        }
        *p = '\0';
        setvareq(nameeq, flags | VNOSAVE);
@@ -12255,7 +12270,7 @@ static void mklocal(char *name)
 
        INTOFF;
        lvp = ckmalloc(sizeof (struct localvar));
-       if (name[0] == '-' && name[1] == '\0') {
+       if (LONE_DASH(name)) {
                char *p;
                p = ckmalloc(sizeof(optlist));
                lvp->text = memcpy(p, optlist, sizeof(optlist));
@@ -12529,7 +12544,7 @@ dash_arith(const char *s)
        }
        INTON;
 
-       return (result);
+       return result;
 }
 
 
@@ -12544,7 +12559,7 @@ static int
 letcmd(int argc, char **argv)
 {
        char **ap;
-       arith_t i;
+       arith_t i = 0;
 
        ap = argv + 1;
        if(!*ap)
@@ -12553,7 +12568,7 @@ letcmd(int argc, char **argv)
                i = dash_arith(*ap);
        }
 
-       return (!i);
+       return !i;
 }
 #endif /* CONFIG_ASH_MATH_SUPPORT */
 
@@ -12565,11 +12580,9 @@ letcmd(int argc, char **argv)
 
 #undef rflag
 
-#ifdef __GLIBC__
-#if __GLIBC__ == 2 && __GLIBC_MINOR__ < 1
+#if defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 1
 typedef enum __rlimit_resource rlim_t;
 #endif
-#endif
 
 
 /*
@@ -12617,7 +12630,7 @@ readcmd(int argc, char **argv)
        while ((i = nextopt("p:r")) != '\0')
 #endif
        {
-               switch(i) {
+               switch (i) {
                case 'p':
                        prompt = optionarg;
                        break;
@@ -12691,7 +12704,7 @@ readcmd(int argc, char **argv)
                FD_ZERO (&set);
                FD_SET (0, &set);
 
-               i = select (FD_SETSIZE, &set, NULL, NULL, &ts);
+               i = select(FD_SETSIZE, &set, NULL, NULL, &ts);
                if (!i) {
 #if defined(CONFIG_ASH_READ_NCHARS)
                        if (nch_flag)
@@ -13418,7 +13431,8 @@ static int arith_apply(operator op, v_n_t *numstack, v_n_t **numstackptr)
        /* protect geting var value, is number now */
        numptr_m1->var = NULL;
        return 0;
-err: return(-1);
+ err:
+       return -1;
 }
 
 /* longest must first */
@@ -13582,7 +13596,7 @@ static arith_t arith (const char *expr, int *perrcode)
                 * a number, since it evaluates to one). Think about it.
                 * It makes sense. */
                if (lasttok != TOK_NUM) {
-                       switch(op) {
+                       switch (op) {
                                case TOK_ADD:
                                    op = TOK_UPLUS;
                                    break;
@@ -13657,7 +13671,7 @@ static arith_t arith (const char *expr, int *perrcode)
 #endif /* CONFIG_ASH_MATH_SUPPORT */
 
 
-#ifdef DEBUG
+#if DEBUG
 const char *applet_name = "debug stuff usage";
 int main(int argc, char **argv)
 {