diff options
author | "Vladimir N. Oleynik" <dzo@simtreas.ru> | 2005-10-11 14:38:01 +0000 |
---|---|---|
committer | "Vladimir N. Oleynik" <dzo@simtreas.ru> | 2005-10-11 14:38:01 +0000 |
commit | 064f04e7e2b1316f7c3de1ac7dd1fc4d4e108dd5 (patch) | |
tree | dcf88d0a287b1f154984bfc0acb292631df2f1f3 | |
parent | ff567f7943f50b88dea14cd27636168ba2d319b5 (diff) | |
download | busybox-w32-064f04e7e2b1316f7c3de1ac7dd1fc4d4e108dd5.tar.gz busybox-w32-064f04e7e2b1316f7c3de1ac7dd1fc4d4e108dd5.tar.bz2 busybox-w32-064f04e7e2b1316f7c3de1ac7dd1fc4d4e108dd5.zip |
- use complementally '!' to '?' - 'ask' is best 'free' char for this.
- more long opt compatibility, can set flag for long opt struct now
- more logic: check opt-depend requires and global requires, special for 'id' and 'start-stop-daemon' applets.
-rw-r--r-- | archival/ar.c | 2 | ||||
-rw-r--r-- | archival/dpkg_deb.c | 2 | ||||
-rw-r--r-- | archival/tar.c | 2 | ||||
-rw-r--r-- | coreutils/date.c | 2 | ||||
-rw-r--r-- | coreutils/id.c | 21 | ||||
-rw-r--r-- | coreutils/install.c | 2 | ||||
-rw-r--r-- | debianutils/start_stop_daemon.c | 28 | ||||
-rw-r--r-- | libbb/getopt_ulflags.c | 108 | ||||
-rw-r--r-- | util-linux/hwclock.c | 2 |
9 files changed, 100 insertions, 69 deletions
diff --git a/archival/ar.c b/archival/ar.c index 411a25e0a..70deb5cbb 100644 --- a/archival/ar.c +++ b/archival/ar.c | |||
@@ -66,7 +66,7 @@ extern int ar_main(int argc, char **argv) | |||
66 | 66 | ||
67 | archive_handle = init_handle(); | 67 | archive_handle = init_handle(); |
68 | 68 | ||
69 | bb_opt_complementally = "!p~tx:t~px:x~pt"; | 69 | bb_opt_complementally = "?p~tx:t~px:x~pt"; |
70 | opt = bb_getopt_ulflags(argc, argv, "ptxovcr"); | 70 | opt = bb_getopt_ulflags(argc, argv, "ptxovcr"); |
71 | 71 | ||
72 | if ((opt == 0) || (optind == argc)) { | 72 | if ((opt == 0) || (optind == argc)) { |
diff --git a/archival/dpkg_deb.c b/archival/dpkg_deb.c index 1ceaa60e0..f38fb6195 100644 --- a/archival/dpkg_deb.c +++ b/archival/dpkg_deb.c | |||
@@ -55,7 +55,7 @@ extern int dpkg_deb_main(int argc, char **argv) | |||
55 | control_tar_llist = llist_add_to(control_tar_llist, "control.tar.bz2"); | 55 | control_tar_llist = llist_add_to(control_tar_llist, "control.tar.bz2"); |
56 | #endif | 56 | #endif |
57 | 57 | ||
58 | bb_opt_complementally = "!c~efXx:e~cfXx:f~ceXx:X~cefx:x~cefX"; | 58 | bb_opt_complementally = "?c~efXx:e~cfXx:f~ceXx:X~cefx:x~cefX"; |
59 | opt = bb_getopt_ulflags(argc, argv, "cefXx"); | 59 | opt = bb_getopt_ulflags(argc, argv, "cefXx"); |
60 | 60 | ||
61 | if (opt & DPKG_DEB_OPT_CONTENTS) { | 61 | if (opt & DPKG_DEB_OPT_CONTENTS) { |
diff --git a/archival/tar.c b/archival/tar.c index f6750ae33..d98426748 100644 --- a/archival/tar.c +++ b/archival/tar.c | |||
@@ -702,7 +702,7 @@ int tar_main(int argc, char **argv) | |||
702 | tar_handle = init_handle(); | 702 | tar_handle = init_handle(); |
703 | tar_handle->flags = ARCHIVE_CREATE_LEADING_DIRS | ARCHIVE_PRESERVE_DATE | ARCHIVE_EXTRACT_UNCONDITIONAL; | 703 | tar_handle->flags = ARCHIVE_CREATE_LEADING_DIRS | ARCHIVE_PRESERVE_DATE | ARCHIVE_EXTRACT_UNCONDITIONAL; |
704 | 704 | ||
705 | bb_opt_complementally = "!c~tx:t~cx:x~ct:X*:T*"; | 705 | bb_opt_complementally = "?c~tx:t~cx:x~ct:X*:T*"; |
706 | #ifdef CONFIG_FEATURE_TAR_LONG_OPTIONS | 706 | #ifdef CONFIG_FEATURE_TAR_LONG_OPTIONS |
707 | bb_applet_long_options = tar_long_options; | 707 | bb_applet_long_options = tar_long_options; |
708 | #endif | 708 | #endif |
diff --git a/coreutils/date.c b/coreutils/date.c index 9583a0036..5ee2c74e8 100644 --- a/coreutils/date.c +++ b/coreutils/date.c | |||
@@ -151,7 +151,7 @@ int date_main(int argc, char **argv) | |||
151 | #else | 151 | #else |
152 | # define GETOPT_ISOFMT | 152 | # define GETOPT_ISOFMT |
153 | #endif | 153 | #endif |
154 | bb_opt_complementally = "!d~ds:s~ds"; | 154 | bb_opt_complementally = "?d~ds:s~ds"; |
155 | opt = bb_getopt_ulflags(argc, argv, "Rs:ud:r:" GETOPT_ISOFMT, | 155 | opt = bb_getopt_ulflags(argc, argv, "Rs:ud:r:" GETOPT_ISOFMT, |
156 | &date_str, &date_str, &filename | 156 | &date_str, &date_str, &filename |
157 | #ifdef CONFIG_FEATURE_DATE_ISOFMT | 157 | #ifdef CONFIG_FEATURE_DATE_ISOFMT |
diff --git a/coreutils/id.c b/coreutils/id.c index 28050ddf2..14497b416 100644 --- a/coreutils/id.c +++ b/coreutils/id.c | |||
@@ -22,7 +22,7 @@ | |||
22 | 22 | ||
23 | /* BB_AUDIT SUSv3 _NOT_ compliant -- option -G is not currently supported. */ | 23 | /* BB_AUDIT SUSv3 _NOT_ compliant -- option -G is not currently supported. */ |
24 | /* Hacked by Tito Ragusa (C) 2004 to handle usernames of whatever length and to | 24 | /* Hacked by Tito Ragusa (C) 2004 to handle usernames of whatever length and to |
25 | * be more similar to GNU id. | 25 | * be more similar to GNU id. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | #include "busybox.h" | 28 | #include "busybox.h" |
@@ -41,10 +41,10 @@ | |||
41 | #define JUST_GROUP 8 | 41 | #define JUST_GROUP 8 |
42 | 42 | ||
43 | static short printf_full(unsigned int id, const char *arg, const char prefix) | 43 | static short printf_full(unsigned int id, const char *arg, const char prefix) |
44 | { | 44 | { |
45 | const char *fmt = "%cid=%u"; | 45 | const char *fmt = "%cid=%u"; |
46 | short status=EXIT_FAILURE; | 46 | short status=EXIT_FAILURE; |
47 | 47 | ||
48 | if(arg) { | 48 | if(arg) { |
49 | fmt = "%cid=%u(%s)"; | 49 | fmt = "%cid=%u(%s)"; |
50 | status=EXIT_SUCCESS; | 50 | status=EXIT_SUCCESS; |
@@ -61,15 +61,14 @@ extern int id_main(int argc, char **argv) | |||
61 | unsigned long flags; | 61 | unsigned long flags; |
62 | short status; | 62 | short status; |
63 | 63 | ||
64 | bb_opt_complementally = "!u~g:g~u"; | 64 | /* Don't allow -n -r -nr -ug -rug -nug -rnug */ |
65 | bb_opt_complementally = "?u~g:g~u:r?ug:n?ug"; | ||
65 | flags = bb_getopt_ulflags(argc, argv, "rnug"); | 66 | flags = bb_getopt_ulflags(argc, argv, "rnug"); |
66 | 67 | ||
67 | /* Don't allow -n -r -nr */ | ||
68 | if ((flags <= 3 && flags > 0) | ||
69 | /* Don't allow more than one username */ | 68 | /* Don't allow more than one username */ |
70 | || (argc > optind + 1)) | 69 | if (argc > (optind + 1)) |
71 | bb_show_usage(); | 70 | bb_show_usage(); |
72 | 71 | ||
73 | /* This values could be overwritten later */ | 72 | /* This values could be overwritten later */ |
74 | uid = geteuid(); | 73 | uid = geteuid(); |
75 | gid = getegid(); | 74 | gid = getegid(); |
@@ -77,13 +76,13 @@ extern int id_main(int argc, char **argv) | |||
77 | uid = getuid(); | 76 | uid = getuid(); |
78 | gid = getgid(); | 77 | gid = getgid(); |
79 | } | 78 | } |
80 | 79 | ||
81 | if(argv[optind]) { | 80 | if(argv[optind]) { |
82 | p=getpwnam(argv[optind]); | 81 | p=getpwnam(argv[optind]); |
83 | /* bb_xgetpwnam is needed because it exits on failure */ | 82 | /* bb_xgetpwnam is needed because it exits on failure */ |
84 | uid = bb_xgetpwnam(argv[optind]); | 83 | uid = bb_xgetpwnam(argv[optind]); |
85 | gid = p->pw_gid; | 84 | gid = p->pw_gid; |
86 | /* in this case PRINT_REAL is the same */ | 85 | /* in this case PRINT_REAL is the same */ |
87 | } | 86 | } |
88 | 87 | ||
89 | if(flags & (JUST_GROUP | JUST_USER)) { | 88 | if(flags & (JUST_GROUP | JUST_USER)) { |
@@ -94,7 +93,7 @@ extern int id_main(int argc, char **argv) | |||
94 | } else { | 93 | } else { |
95 | bb_printf("%u\n",(flags & JUST_USER) ? uid : gid); | 94 | bb_printf("%u\n",(flags & JUST_USER) ? uid : gid); |
96 | } | 95 | } |
97 | /* exit */ | 96 | /* exit */ |
98 | bb_fflush_stdout_and_exit(EXIT_SUCCESS); | 97 | bb_fflush_stdout_and_exit(EXIT_SUCCESS); |
99 | } | 98 | } |
100 | 99 | ||
diff --git a/coreutils/install.c b/coreutils/install.c index 9fcb75405..9e5eb6037 100644 --- a/coreutils/install.c +++ b/coreutils/install.c | |||
@@ -61,7 +61,7 @@ extern int install_main(int argc, char **argv) | |||
61 | int ret = EXIT_SUCCESS, flags, i, isdir; | 61 | int ret = EXIT_SUCCESS, flags, i, isdir; |
62 | 62 | ||
63 | bb_applet_long_options = install_long_options; | 63 | bb_applet_long_options = install_long_options; |
64 | bb_opt_complementally = "!s~d:d~s"; | 64 | bb_opt_complementally = "?s~d:d~s"; |
65 | /* -c exists for backwards compatability, its needed */ | 65 | /* -c exists for backwards compatability, its needed */ |
66 | flags = bb_getopt_ulflags(argc, argv, "cdpsg:m:o:", &gid_str, &mode_str, &uid_str); /* 'a' must be 2nd */ | 66 | flags = bb_getopt_ulflags(argc, argv, "cdpsg:m:o:", &gid_str, &mode_str, &uid_str); /* 'a' must be 2nd */ |
67 | 67 | ||
diff --git a/debianutils/start_stop_daemon.c b/debianutils/start_stop_daemon.c index f9310af8d..b6c463556 100644 --- a/debianutils/start_stop_daemon.c +++ b/debianutils/start_stop_daemon.c | |||
@@ -204,18 +204,18 @@ do_stop(void) | |||
204 | 204 | ||
205 | 205 | ||
206 | static const struct option ssd_long_options[] = { | 206 | static const struct option ssd_long_options[] = { |
207 | { "stop", 0, NULL, 'K' }, | 207 | { "stop", 0, NULL, 'K' }, |
208 | { "start", 0, NULL, 'S' }, | 208 | { "start", 0, NULL, 'S' }, |
209 | { "background", 0, NULL, 'b' }, | 209 | { "background", 0, NULL, 'b' }, |
210 | { "quiet", 0, NULL, 'q' }, | 210 | { "quiet", 0, NULL, 'q' }, |
211 | { "make-pidfile", 0, NULL, 'm' }, | 211 | { "make-pidfile", 0, NULL, 'm' }, |
212 | { "startas", 1, NULL, 'a' }, | 212 | { "startas", 1, NULL, 'a' }, |
213 | { "name", 1, NULL, 'n' }, | 213 | { "name", 1, NULL, 'n' }, |
214 | { "signal", 1, NULL, 's' }, | 214 | { "signal", 1, NULL, 's' }, |
215 | { "user", 1, NULL, 'u' }, | 215 | { "user", 1, NULL, 'u' }, |
216 | { "exec", 1, NULL, 'x' }, | 216 | { "exec", 1, NULL, 'x' }, |
217 | { "pidfile", 1, NULL, 'p' }, | 217 | { "pidfile", 1, NULL, 'p' }, |
218 | { 0, 0, 0, 0 } | 218 | { 0, 0, 0, 0 } |
219 | }; | 219 | }; |
220 | 220 | ||
221 | #define SSD_CTX_STOP 1 | 221 | #define SSD_CTX_STOP 1 |
@@ -233,17 +233,13 @@ start_stop_daemon_main(int argc, char **argv) | |||
233 | 233 | ||
234 | bb_applet_long_options = ssd_long_options; | 234 | bb_applet_long_options = ssd_long_options; |
235 | 235 | ||
236 | bb_opt_complementally = "!K~S:S~K"; | 236 | /* Check required one context option was given */ |
237 | bb_opt_complementally = "?:K?K:S?S:K~S:S~K"; | ||
237 | opt = bb_getopt_ulflags(argc, argv, "KSbqma:n:s:u:x:p:", | 238 | opt = bb_getopt_ulflags(argc, argv, "KSbqma:n:s:u:x:p:", |
238 | &startas, &cmdname, &signame, &userspec, &execname, &pidfile); | 239 | &startas, &cmdname, &signame, &userspec, &execname, &pidfile); |
239 | 240 | ||
240 | /* Check required one context option was given */ | 241 | |
241 | if ((opt & (SSD_CTX_STOP | SSD_CTX_START)) == 0) { | 242 | quiet = opt & SSD_OPT_QUIET; |
242 | bb_show_usage(); | ||
243 | } | ||
244 | |||
245 | if (opt & SSD_OPT_QUIET) | ||
246 | quiet = 1; | ||
247 | 243 | ||
248 | if (signame) { | 244 | if (signame) { |
249 | signal_nr = bb_xgetlarg(signame, 10, 0, NSIG); | 245 | signal_nr = bb_xgetlarg(signame, 10, 0, NSIG); |
diff --git a/libbb/getopt_ulflags.c b/libbb/getopt_ulflags.c index 2e2ee0b6b..5f35c583c 100644 --- a/libbb/getopt_ulflags.c +++ b/libbb/getopt_ulflags.c | |||
@@ -197,8 +197,9 @@ Special characters: | |||
197 | if (flags & BB_GETOPT_ERROR) | 197 | if (flags & BB_GETOPT_ERROR) |
198 | bb_show_usage(); | 198 | bb_show_usage(); |
199 | 199 | ||
200 | "!" If previous point set BB_GETOPT_ERROR, don`t return and call | 200 | "?" A "ask" as the first char in a bb_opt_complementally group give: |
201 | previous example internally | 201 | if previous point set BB_GETOPT_ERROR, don`t return and |
202 | call previous example internally | ||
202 | 203 | ||
203 | "*" A star after a char in bb_opt_complementally means that the | 204 | "*" A star after a char in bb_opt_complementally means that the |
204 | option can occur multiple times: | 205 | option can occur multiple times: |
@@ -218,16 +219,38 @@ Special characters: | |||
218 | $ grep -e user -e root /etc/passwd | 219 | $ grep -e user -e root /etc/passwd |
219 | root:x:0:0:root:/root:/bin/bash | 220 | root:x:0:0:root:/root:/bin/bash |
220 | user:x:500:500::/home/user:/bin/bash | 221 | user:x:500:500::/home/user:/bin/bash |
222 | |||
223 | "?" A "ask" between main and group options causes the second of the two | ||
224 | to be depending required if first is given on the command line. | ||
225 | For example from "id" applet: | ||
226 | |||
227 | // Don't allow -n -r -rn -ug -rug -nug -rnug | ||
228 | bb_opt_complementally = "?u~g:g~u:r?ug:n?ug"; | ||
229 | flags = bb_getopt_ulflags(argc, argv, "rnug"); | ||
230 | |||
231 | This example allowed only: | ||
232 | $ id; id -u; id -g; id -ru; id -nu; id -rg; id -ng; id -rnu; id -rng | ||
233 | |||
234 | "?" A "ask" between equivalent options in bb_opt_complementally means | ||
235 | requires this option always, checked after switch off from | ||
236 | complementally logic | ||
237 | For example from "start-stop-daemon" applet: | ||
238 | |||
239 | // Don't allow -KS -SK, but -S or -K required | ||
240 | bb_opt_complementally = "?:K?K:S?S:K~S:S~K"; | ||
241 | flags = bb_getopt_ulflags(argc, argv, "KS...); | ||
242 | |||
221 | */ | 243 | */ |
222 | 244 | ||
223 | const char *bb_opt_complementally; | 245 | const char *bb_opt_complementally; |
224 | 246 | ||
225 | typedef struct { | 247 | typedef struct { |
226 | unsigned char opt; | 248 | int opt; |
227 | char list_flg; | 249 | int list_flg; |
228 | unsigned long switch_on; | 250 | unsigned long switch_on; |
229 | unsigned long switch_off; | 251 | unsigned long switch_off; |
230 | unsigned long incongruously; | 252 | unsigned long incongruously; |
253 | unsigned long requires; | ||
231 | void **optarg; /* char **optarg or llist_t **optarg */ | 254 | void **optarg; /* char **optarg or llist_t **optarg */ |
232 | int *counter; | 255 | int *counter; |
233 | } t_complementally; | 256 | } t_complementally; |
@@ -245,17 +268,20 @@ unsigned long | |||
245 | bb_getopt_ulflags (int argc, char **argv, const char *applet_opts, ...) | 268 | bb_getopt_ulflags (int argc, char **argv, const char *applet_opts, ...) |
246 | { | 269 | { |
247 | unsigned long flags = 0; | 270 | unsigned long flags = 0; |
271 | unsigned long requires = 0; | ||
248 | t_complementally complementally[sizeof(flags) * 8 + 1]; | 272 | t_complementally complementally[sizeof(flags) * 8 + 1]; |
249 | int c; | 273 | int c; |
250 | const unsigned char *s; | 274 | const unsigned char *s; |
251 | t_complementally *on_off; | 275 | t_complementally *on_off; |
252 | va_list p; | 276 | va_list p; |
253 | const struct option *l_o; | 277 | const struct option *l_o; |
254 | char flg_show_usage_if_error = 0; | ||
255 | char flg_argv_is_opts = 0; | ||
256 | unsigned long trigger; | 278 | unsigned long trigger; |
257 | char **pargv = NULL; | 279 | char **pargv = NULL; |
258 | 280 | ||
281 | #define SHOW_USAGE_IF_ERROR 1 | ||
282 | #define ARGV_IS_OPTS 2 | ||
283 | int spec_flgs = 0; | ||
284 | |||
259 | va_start (p, applet_opts); | 285 | va_start (p, applet_opts); |
260 | 286 | ||
261 | /* skip GNU extension */ | 287 | /* skip GNU extension */ |
@@ -265,16 +291,13 @@ bb_getopt_ulflags (int argc, char **argv, const char *applet_opts, ...) | |||
265 | 291 | ||
266 | c = 0; | 292 | c = 0; |
267 | on_off = complementally; | 293 | on_off = complementally; |
294 | memset(on_off, 0, sizeof(complementally)); | ||
295 | |||
268 | for (; *s; s++) { | 296 | for (; *s; s++) { |
269 | if(c >= (int)(sizeof(flags)*8)) | 297 | if(c >= (int)(sizeof(flags)*8)) |
270 | break; | 298 | break; |
271 | on_off->opt = *s; | 299 | on_off->opt = *s; |
272 | on_off->switch_on = (1 << c); | 300 | on_off->switch_on = (1 << c); |
273 | on_off->list_flg = 0; | ||
274 | on_off->switch_off = 0; | ||
275 | on_off->incongruously = 0; | ||
276 | on_off->optarg = NULL; | ||
277 | on_off->counter = NULL; | ||
278 | if (s[1] == ':') { | 301 | if (s[1] == ':') { |
279 | on_off->optarg = va_arg (p, void **); | 302 | on_off->optarg = va_arg (p, void **); |
280 | do | 303 | do |
@@ -284,9 +307,10 @@ bb_getopt_ulflags (int argc, char **argv, const char *applet_opts, ...) | |||
284 | on_off++; | 307 | on_off++; |
285 | c++; | 308 | c++; |
286 | } | 309 | } |
287 | on_off->opt = 0; | ||
288 | 310 | ||
289 | for(l_o = bb_applet_long_options; l_o->name; l_o++) { | 311 | for(l_o = bb_applet_long_options; l_o->name; l_o++) { |
312 | if(l_o->flag) | ||
313 | continue; | ||
290 | for(on_off = complementally; on_off->opt != 0; on_off++) | 314 | for(on_off = complementally; on_off->opt != 0; on_off++) |
291 | if(on_off->opt == l_o->val) | 315 | if(on_off->opt == l_o->val) |
292 | break; | 316 | break; |
@@ -295,16 +319,8 @@ bb_getopt_ulflags (int argc, char **argv, const char *applet_opts, ...) | |||
295 | break; | 319 | break; |
296 | on_off->opt = l_o->val; | 320 | on_off->opt = l_o->val; |
297 | on_off->switch_on = (1 << c); | 321 | on_off->switch_on = (1 << c); |
298 | on_off->list_flg = 0; | ||
299 | on_off->switch_off = 0; | ||
300 | on_off->incongruously = 0; | ||
301 | on_off->counter = NULL; | ||
302 | if(l_o->has_arg != no_argument) | 322 | if(l_o->has_arg != no_argument) |
303 | on_off->optarg = va_arg (p, void **); | 323 | on_off->optarg = va_arg (p, void **); |
304 | else | ||
305 | on_off->optarg = NULL; | ||
306 | on_off++; | ||
307 | on_off->opt = 0; | ||
308 | c++; | 324 | c++; |
309 | } | 325 | } |
310 | } | 326 | } |
@@ -318,12 +334,12 @@ bb_getopt_ulflags (int argc, char **argv, const char *applet_opts, ...) | |||
318 | } | 334 | } |
319 | if (c) | 335 | if (c) |
320 | continue; | 336 | continue; |
321 | if(*s == '!') { | 337 | if(*s == '?') { |
322 | flg_show_usage_if_error = '!'; | 338 | spec_flgs |= SHOW_USAGE_IF_ERROR; |
323 | continue; | 339 | continue; |
324 | } | 340 | } |
325 | if(*s == '-') { | 341 | if(*s == '-') { |
326 | flg_argv_is_opts = '-'; | 342 | spec_flgs |= ARGV_IS_OPTS; |
327 | continue; | 343 | continue; |
328 | } | 344 | } |
329 | for (on_off = complementally; on_off->opt; on_off++) | 345 | for (on_off = complementally; on_off->opt; on_off++) |
@@ -331,18 +347,32 @@ bb_getopt_ulflags (int argc, char **argv, const char *applet_opts, ...) | |||
331 | break; | 347 | break; |
332 | pair = on_off; | 348 | pair = on_off; |
333 | for(s++; *s && *s != ':'; s++) { | 349 | for(s++; *s && *s != ':'; s++) { |
334 | if (*s == '-' || *s == '~') { | 350 | if (*s == '-' || *s == '~' || *s == '?') { |
335 | c = *s; | 351 | c = *s; |
336 | } else if(*s == '*') { | 352 | } else if(*s == '*') { |
337 | pair->list_flg++; | 353 | pair->list_flg++; |
338 | } else { | 354 | } else { |
339 | unsigned long *pair_switch = &(pair->switch_on); | 355 | unsigned long *pair_switch; |
340 | if(c) | 356 | |
341 | pair_switch = c == '-' ? &(pair->switch_off) : &(pair->incongruously); | 357 | switch(c) { |
358 | case '-': | ||
359 | pair_switch = &(pair->switch_off); | ||
360 | break; | ||
361 | case '~': | ||
362 | pair_switch = &(pair->incongruously); | ||
363 | break; | ||
364 | case '?': | ||
365 | pair_switch = &(pair->requires); | ||
366 | break; | ||
367 | default: | ||
368 | pair_switch = &(pair->switch_on); | ||
369 | } | ||
342 | for (on_off = complementally; on_off->opt; on_off++) | 370 | for (on_off = complementally; on_off->opt; on_off++) |
343 | if (on_off->opt == *s) { | 371 | if (on_off->opt == *s) { |
344 | if(pair_switch == &(on_off->switch_on)) | 372 | if(pair_switch == &(on_off->switch_on)) |
345 | on_off->counter = va_arg (p, int *); | 373 | on_off->counter = va_arg (p, int *); |
374 | else if(pair_switch == &(on_off->requires)) | ||
375 | requires |= on_off->switch_on; | ||
346 | else | 376 | else |
347 | *pair_switch |= on_off->switch_on; | 377 | *pair_switch |= on_off->switch_on; |
348 | break; | 378 | break; |
@@ -353,15 +383,16 @@ bb_getopt_ulflags (int argc, char **argv, const char *applet_opts, ...) | |||
353 | } | 383 | } |
354 | 384 | ||
355 | while ((c = getopt_long (argc, argv, applet_opts, | 385 | while ((c = getopt_long (argc, argv, applet_opts, |
356 | bb_applet_long_options, NULL)) > 0) { | 386 | bb_applet_long_options, NULL)) >= 0) { |
357 | 387 | ||
358 | loop_arg_is_opt: | 388 | loop_arg_is_opt: |
359 | for (on_off = complementally; on_off->opt != c; on_off++) { | 389 | for (on_off = complementally; on_off->opt != c; on_off++) { |
360 | if(!on_off->opt) | 390 | /* c==0 if long opt have non NULL flag */ |
391 | if(on_off->opt == 0 && c != 0) | ||
361 | bb_show_usage (); | 392 | bb_show_usage (); |
362 | } | 393 | } |
363 | if(flags & on_off->incongruously) { | 394 | if(flags & on_off->incongruously) { |
364 | if(flg_show_usage_if_error) | 395 | if((spec_flgs & SHOW_USAGE_IF_ERROR)) |
365 | bb_show_usage (); | 396 | bb_show_usage (); |
366 | flags |= BB_GETOPT_ERROR; | 397 | flags |= BB_GETOPT_ERROR; |
367 | } | 398 | } |
@@ -377,15 +408,13 @@ loop_arg_is_opt: | |||
377 | } else if (on_off->optarg) { | 408 | } else if (on_off->optarg) { |
378 | *(char **)(on_off->optarg) = optarg; | 409 | *(char **)(on_off->optarg) = optarg; |
379 | } | 410 | } |
380 | if(flg_argv_is_opts == 'p') | 411 | if(pargv != NULL) |
381 | break; | 412 | break; |
382 | } | 413 | } |
383 | if(flg_argv_is_opts) { | 414 | if((spec_flgs & ARGV_IS_OPTS)) { |
384 | /* process argv is option, for example "ps" applet */ | 415 | /* process argv is option, for example "ps" applet */ |
385 | if(flg_argv_is_opts == '-') { | 416 | if(pargv == NULL) |
386 | flg_argv_is_opts = 'p'; | ||
387 | pargv = argv + optind; | 417 | pargv = argv + optind; |
388 | } | ||
389 | while(*pargv) { | 418 | while(*pargv) { |
390 | c = **pargv; | 419 | c = **pargv; |
391 | if(c == '\0') { | 420 | if(c == '\0') { |
@@ -396,6 +425,13 @@ loop_arg_is_opt: | |||
396 | } | 425 | } |
397 | } | 426 | } |
398 | } | 427 | } |
399 | 428 | /* check depending requires for given options */ | |
429 | for (on_off = complementally; on_off->opt; on_off++) { | ||
430 | if(on_off->requires && (flags & on_off->switch_on) && | ||
431 | (flags & on_off->requires) == 0) | ||
432 | bb_show_usage (); | ||
433 | } | ||
434 | if(requires && (flags & requires) == 0) | ||
435 | bb_show_usage (); | ||
400 | return flags; | 436 | return flags; |
401 | } | 437 | } |
diff --git a/util-linux/hwclock.c b/util-linux/hwclock.c index 45959e7a1..3021442b7 100644 --- a/util-linux/hwclock.c +++ b/util-linux/hwclock.c | |||
@@ -209,7 +209,7 @@ static const struct option hwclock_long_options[] = { | |||
209 | bb_applet_long_options = hwclock_long_options; | 209 | bb_applet_long_options = hwclock_long_options; |
210 | #endif | 210 | #endif |
211 | 211 | ||
212 | bb_opt_complementally = "!r~ws:w~rs:s~wr:l~u:u~l"; | 212 | bb_opt_complementally = "?r~ws:w~rs:s~wr:l~u:u~l"; |
213 | opt = bb_getopt_ulflags(argc, argv, "lursw"); | 213 | opt = bb_getopt_ulflags(argc, argv, "lursw"); |
214 | 214 | ||
215 | /* If -u or -l wasn't given check if we are using utc */ | 215 | /* If -u or -l wasn't given check if we are using utc */ |