diff options
Diffstat (limited to 'libbb/getopt32.c')
-rw-r--r-- | libbb/getopt32.c | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/libbb/getopt32.c b/libbb/getopt32.c index 17babcd..198149d 100644 --- a/libbb/getopt32.c +++ b/libbb/getopt32.c @@ -3,6 +3,7 @@ * universal getopt32 implementation for busybox * * Copyright (C) 2003-2005 Vladimir Oleynik <dzo@simtreas.ru> + * Copyright (c) 2013 RIPE NCC <atlas@ripe.net> * * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. */ @@ -327,6 +328,7 @@ getopt32(char **argv, const char *applet_opts, ...) unsigned flags = 0; unsigned requires = 0; t_complementary complementary[33]; /* last stays zero-filled */ + char first_char; int c; const unsigned char *s; t_complementary *on_off; @@ -357,6 +359,11 @@ getopt32(char **argv, const char *applet_opts, ...) on_off = complementary; memset(on_off, 0, sizeof(complementary)); + /* skip bbox extension */ + first_char = applet_opts[0]; + if (first_char == '!') + applet_opts++; + /* skip GNU extension */ s = (const unsigned char *)applet_opts; if (*s == '+' || *s == '-') @@ -549,11 +556,11 @@ getopt32(char **argv, const char *applet_opts, ...) * is always NULL (see above) */ if (on_off->opt_char == '\0' /* && c != '\0' */) { /* c is probably '?' - "bad option" */ - bb_show_usage(); + goto error; } } if (flags & on_off->incongruously) - bb_show_usage(); + goto error; trigger = on_off->switch_on & on_off->switch_off; flags &= ~(on_off->switch_off ^ trigger); flags |= on_off->switch_on ^ trigger; @@ -579,14 +586,19 @@ getopt32(char **argv, const char *applet_opts, ...) for (on_off = complementary; on_off->opt_char; on_off++) { if (on_off->requires && (flags & on_off->switch_on) && (flags & on_off->requires) == 0) - bb_show_usage(); + goto error; } if (requires && (flags & requires) == 0) - bb_show_usage(); + goto error; argc -= optind; if (argc < min_arg || (max_arg >= 0 && argc > max_arg)) - bb_show_usage(); + goto error; option_mask32 = flags; return flags; + + error: + if (first_char != '!') + bb_show_usage(); + return (int32_t)-1; } |