X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=shell%2Fash.c;h=6d96bce5aefb48288d9449017d6a36f83a07ffde;hb=98ee06d3d46aa7f89c204681c7075b53300a6a6e;hp=0d9fa7fe2e18e1cf23805563730f65e5dec420fc;hpb=8f8f268cfdecb4cabeb2e649a73afc7a485aeff5;p=oweals%2Fbusybox.git diff --git a/shell/ash.c b/shell/ash.c index 0d9fa7fe2..6d96bce5a 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -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 @@ -81,12 +82,10 @@ #include #include -#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 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) {