aboutsummaryrefslogtreecommitdiff
path: root/libbb/getopt32.c
diff options
context:
space:
mode:
Diffstat (limited to 'libbb/getopt32.c')
-rw-r--r--libbb/getopt32.c22
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;
}