aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--archival/ar.c9
-rw-r--r--archival/dpkg_deb.c2
-rw-r--r--archival/tar.c10
-rw-r--r--coreutils/cut.c2
-rw-r--r--coreutils/date.c2
-rw-r--r--coreutils/env.c12
-rw-r--r--coreutils/id.c7
-rw-r--r--coreutils/install.c2
-rw-r--r--debianutils/start_stop_daemon.c4
-rw-r--r--findutils/grep.c4
-rw-r--r--libbb/getopt_ulflags.c181
-rw-r--r--networking/traceroute.c2
-rw-r--r--networking/wget.c28
-rw-r--r--procps/pidof.c2
-rw-r--r--util-linux/hwclock.c2
15 files changed, 154 insertions, 115 deletions
diff --git a/archival/ar.c b/archival/ar.c
index de5bc9b84..983b5ae2c 100644
--- a/archival/ar.c
+++ b/archival/ar.c
@@ -68,16 +68,9 @@ extern int ar_main(int argc, char **argv)
68 archive_handle = init_handle(); 68 archive_handle = init_handle();
69 69
70 /* Prepend '-' to the first argument if required */ 70 /* Prepend '-' to the first argument if required */
71 if (argv[1][0] != '-') 71 bb_opt_complementally = "--:p:t:x:-1:?:p--tx:t--px:x--pt";
72 argv[1] = bb_xasprintf("-%s", argv[1]);
73
74 bb_opt_complementally = "?p~tx:t~px:x~pt";
75 opt = bb_getopt_ulflags(argc, argv, "ptxovcr"); 72 opt = bb_getopt_ulflags(argc, argv, "ptxovcr");
76 73
77 if ((opt == 0) || (optind == argc)) {
78 bb_show_usage();
79 }
80
81 if (opt & AR_CTX_PRINT) { 74 if (opt & AR_CTX_PRINT) {
82 archive_handle->action_data = data_extract_to_stdout; 75 archive_handle->action_data = data_extract_to_stdout;
83 } 76 }
diff --git a/archival/dpkg_deb.c b/archival/dpkg_deb.c
index f38fb6195..29e9719cb 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 32e9cbaa6..7cfb495e5 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -690,18 +690,16 @@ int tar_main(int argc, char **argv)
690 unsigned long opt; 690 unsigned long opt;
691 unsigned long ctx_flag = 0; 691 unsigned long ctx_flag = 0;
692 692
693 /* Prepend '-' to the first argument if required */ 693
694 if (argv[1][0] != '-')
695 argv[1] = bb_xasprintf("-%s", argv[1]);
696
697 /* Initialise default values */ 694 /* Initialise default values */
698 tar_handle = init_handle(); 695 tar_handle = init_handle();
699 tar_handle->flags = ARCHIVE_CREATE_LEADING_DIRS | ARCHIVE_PRESERVE_DATE | ARCHIVE_EXTRACT_UNCONDITIONAL; 696 tar_handle->flags = ARCHIVE_CREATE_LEADING_DIRS | ARCHIVE_PRESERVE_DATE | ARCHIVE_EXTRACT_UNCONDITIONAL;
700 697
698 /* Prepend '-' to the first argument if required */
701#ifdef CONFIG_FEATURE_TAR_CREATE 699#ifdef CONFIG_FEATURE_TAR_CREATE
702 bb_opt_complementally = "?:c?c:t?t:x?x:c~tx:t~cx:x~ct:X*:T*"; 700 bb_opt_complementally = "--:-1:X::T::c:t:x:?:c--tx:t--cx:x--ct";
703#else 701#else
704 bb_opt_complementally = "?:t?t:x?x:t~x:x~t:X*:T*"; 702 bb_opt_complementally = "--:-1:X::T::t:x:?:t--x:x--t";
705#endif 703#endif
706#ifdef CONFIG_FEATURE_TAR_LONG_OPTIONS 704#ifdef CONFIG_FEATURE_TAR_LONG_OPTIONS
707 bb_applet_long_options = tar_long_options; 705 bb_applet_long_options = tar_long_options;
diff --git a/coreutils/cut.c b/coreutils/cut.c
index f9c72ca81..839bab68e 100644
--- a/coreutils/cut.c
+++ b/coreutils/cut.c
@@ -294,7 +294,7 @@ extern int cut_main(int argc, char **argv)
294 unsigned long opt; 294 unsigned long opt;
295 char *sopt, *sdopt; 295 char *sopt, *sdopt;
296 296
297 bb_opt_complementally = "b~bcf:c~bcf:f~bcf"; 297 bb_opt_complementally = "b--bcf:c--bcf:f--bcf";
298 opt = bb_getopt_ulflags(argc, argv, optstring, &sopt, &sopt, &sopt, &sdopt); 298 opt = bb_getopt_ulflags(argc, argv, optstring, &sopt, &sopt, &sopt, &sdopt);
299 part = opt & (OPT_BYTE_FLGS|OPT_CHAR_FLGS|OPT_FIELDS_FLGS); 299 part = opt & (OPT_BYTE_FLGS|OPT_CHAR_FLGS|OPT_FIELDS_FLGS);
300 if(part == 0) 300 if(part == 0)
diff --git a/coreutils/date.c b/coreutils/date.c
index 43130f914..6593df970 100644
--- a/coreutils/date.c
+++ b/coreutils/date.c
@@ -149,7 +149,7 @@ int date_main(int argc, char **argv)
149#else 149#else
150# define GETOPT_ISOFMT 150# define GETOPT_ISOFMT
151#endif 151#endif
152 bb_opt_complementally = "?d~s:s~d"; 152 bb_opt_complementally = "?:d--s:s--d";
153 opt = bb_getopt_ulflags(argc, argv, "Rs:ud:r:" GETOPT_ISOFMT, 153 opt = bb_getopt_ulflags(argc, argv, "Rs:ud:r:" GETOPT_ISOFMT,
154 &date_str, &date_str, &filename 154 &date_str, &date_str, &filename
155#ifdef CONFIG_FEATURE_DATE_ISOFMT 155#ifdef CONFIG_FEATURE_DATE_ISOFMT
diff --git a/coreutils/env.c b/coreutils/env.c
index 1a8ad7c78..d59e738f1 100644
--- a/coreutils/env.c
+++ b/coreutils/env.c
@@ -38,7 +38,7 @@
38 * - correct "-" option usage 38 * - correct "-" option usage
39 * - multiple "-u unsetenv" support 39 * - multiple "-u unsetenv" support
40 * - GNU long option support 40 * - GNU long option support
41 * - save errno after exec failed before bb_perror_msg() 41 * - use bb_default_error_retval
42 */ 42 */
43 43
44 44
@@ -65,7 +65,7 @@ extern int env_main(int argc, char** argv)
65 llist_t *unset_env = NULL; 65 llist_t *unset_env = NULL;
66 extern char **environ; 66 extern char **environ;
67 67
68 bb_opt_complementally = "u*"; 68 bb_opt_complementally = "u::";
69 bb_applet_long_options = env_long_options; 69 bb_applet_long_options = env_long_options;
70 70
71 opt = bb_getopt_ulflags(argc, argv, "+iu:", &unset_env); 71 opt = bb_getopt_ulflags(argc, argv, "+iu:", &unset_env);
@@ -93,12 +93,10 @@ extern int env_main(int argc, char** argv)
93 } 93 }
94 94
95 if (*argv) { 95 if (*argv) {
96 int er;
97
98 execvp(*argv, argv); 96 execvp(*argv, argv);
99 er = errno; 97 /* SUSv3-mandated exit codes. */
100 bb_perror_msg("%s", *argv); /* Avoid multibyte problems. */ 98 bb_default_error_retval = (errno == ENOENT) ? 127 : 126;
101 return (er == ENOENT) ? 127 : 126; /* SUSv3-mandated exit codes. */ 99 bb_perror_msg_and_die("%s", *argv);
102 } 100 }
103 101
104 for (ep = environ; *ep; ep++) { 102 for (ep = environ; *ep; ep++) {
diff --git a/coreutils/id.c b/coreutils/id.c
index 14497b416..39a57c196 100644
--- a/coreutils/id.c
+++ b/coreutils/id.c
@@ -62,12 +62,9 @@ extern int id_main(int argc, char **argv)
62 short status; 62 short status;
63 63
64 /* Don't allow -n -r -nr -ug -rug -nug -rnug */ 64 /* Don't allow -n -r -nr -ug -rug -nug -rnug */
65 bb_opt_complementally = "?u~g:g~u:r?ug:n?ug";
66 flags = bb_getopt_ulflags(argc, argv, "rnug");
67
68 /* Don't allow more than one username */ 65 /* Don't allow more than one username */
69 if (argc > (optind + 1)) 66 bb_opt_complementally = "?1:?:u--g:g--u:r?ug:n?ug";
70 bb_show_usage(); 67 flags = bb_getopt_ulflags(argc, argv, "rnug");
71 68
72 /* This values could be overwritten later */ 69 /* This values could be overwritten later */
73 uid = geteuid(); 70 uid = geteuid();
diff --git a/coreutils/install.c b/coreutils/install.c
index 9e5eb6037..a4a96151d 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 b6c463556..2ace0cc8b 100644
--- a/debianutils/start_stop_daemon.c
+++ b/debianutils/start_stop_daemon.c
@@ -234,9 +234,9 @@ start_stop_daemon_main(int argc, char **argv)
234 bb_applet_long_options = ssd_long_options; 234 bb_applet_long_options = ssd_long_options;
235 235
236 /* Check required one context option was given */ 236 /* Check required one context option was given */
237 bb_opt_complementally = "?:K?K:S?S:K~S:S~K"; 237 bb_opt_complementally = "K:S:?:K--S:S--K";
238 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:",
239 &startas, &cmdname, &signame, &userspec, &execname, &pidfile); 239 &startas, &cmdname, &signame, &userspec, &execname, &pidfile);
240 240
241 241
242 quiet = opt & SSD_OPT_QUIET; 242 quiet = opt & SSD_OPT_QUIET;
diff --git a/findutils/grep.c b/findutils/grep.c
index 323e4afc6..3c5167e28 100644
--- a/findutils/grep.c
+++ b/findutils/grep.c
@@ -264,7 +264,7 @@ extern int grep_main(int argc, char **argv)
264 char *slines_before; 264 char *slines_before;
265 char *Copt; 265 char *Copt;
266 266
267 bb_opt_complementally = "H-h:e*:f*:C-AB"; 267 bb_opt_complementally = "H-h:e::f::C-AB";
268 opt = bb_getopt_ulflags(argc, argv, 268 opt = bb_getopt_ulflags(argc, argv,
269 GREP_OPTS GREP_OPT_CONTEXT OPT_EGREP, 269 GREP_OPTS GREP_OPT_CONTEXT OPT_EGREP,
270 &pattern_head, &fopt, 270 &pattern_head, &fopt,
@@ -299,7 +299,7 @@ extern int grep_main(int argc, char **argv)
299 } 299 }
300#else 300#else
301 /* with auto sanity checks */ 301 /* with auto sanity checks */
302 bb_opt_complementally = "H-h:e*:f*:c-n:q-n:l-n"; 302 bb_opt_complementally = "H-h:e::f::c-n:q-n:l-n";
303 opt = bb_getopt_ulflags(argc, argv, GREP_OPTS OPT_EGREP, 303 opt = bb_getopt_ulflags(argc, argv, GREP_OPTS OPT_EGREP,
304 &pattern_head, &fopt); 304 &pattern_head, &fopt);
305#endif 305#endif
diff --git a/libbb/getopt_ulflags.c b/libbb/getopt_ulflags.c
index 5f35c583c..47f65d6b2 100644
--- a/libbb/getopt_ulflags.c
+++ b/libbb/getopt_ulflags.c
@@ -66,7 +66,7 @@ bb_getopt_ulflags (int argc, char **argv, const char *applet_opts, ...)
66 &pointer_to_arg_for_c, &pointer_to_arg_for_d); 66 &pointer_to_arg_for_c, &pointer_to_arg_for_d);
67 67
68 The type of the pointer (char* or llist_t *) may be controlled 68 The type of the pointer (char* or llist_t *) may be controlled
69 by the "*" special character that is set in the external string 69 by the "::" special separator that is set in the external string
70 bb_opt_complementally (see below for more info). 70 bb_opt_complementally (see below for more info).
71 71
72static const struct option bb_default_long_options[] 72static const struct option bb_default_long_options[]
@@ -127,13 +127,13 @@ const char *bb_opt_complementally
127 127
128 w_counter is a pointer to an integer. It has to be passed to 128 w_counter is a pointer to an integer. It has to be passed to
129 bb_getopt_ulflags() after all other option argument sinks. 129 bb_getopt_ulflags() after all other option argument sinks.
130 For example: accept multiple -v to indicate the level of verbosity and 130 For example: accept multiple -v to indicate the level of verbosity
131 for each -b optarg, add optarg to my_b. Finally, if b is given, turn off 131 and for each -b optarg, add optarg to my_b. Finally, if b is given,
132 c and vice versa: 132 turn off c and vice versa:
133 133
134 llist_t *my_b = NULL; 134 llist_t *my_b = NULL;
135 int verbose_level = 0; 135 int verbose_level = 0;
136 bb_opt_complementally = "vv:b*:b-c:c-b"; 136 bb_opt_complementally = "vv:b::b-c:c-b";
137 f = bb_getopt_ulflags(argc, argv, "vb:c", &my_b, &verbose_level); 137 f = bb_getopt_ulflags(argc, argv, "vb:c", &my_b, &verbose_level);
138 if((f & 2)) // -c after -b unset this -b flag 138 if((f & 2)) // -c after -b unset this -b flag
139 while (my_b) { dosomething_with(my_b->data) ; my_b = my_b->link; } 139 while (my_b) { dosomething_with(my_b->data) ; my_b = my_b->link; }
@@ -164,15 +164,14 @@ Special characters:
164 opt = bb_getopt_ulflags(argc, argv, "sd:x", &smax_print_depth); 164 opt = bb_getopt_ulflags(argc, argv, "sd:x", &smax_print_depth);
165 165
166 if (opt & 2) { 166 if (opt & 2) {
167 max_print_depth = bb_xgetularg10_bnd(smax_print_depth, 167 max_print_depth = atoi(smax_print_depth);
168 0, INT_MAX);
169 } 168 }
170 if(opt & 4) 169 if(opt & 4)
171 printf("Detected odd -x usaging\n"); 170 printf("Detected odd -x usaging\n");
172 171
173 "-" A minus as the first char in a bb_opt_complementally group means to 172 "-" A dash as the first char in a bb_opt_complementally group means to
174 convert the arguments as option. 173 convert the arguments as option. Next char for this case can`t set
175 For example: 174 [0-9], recomended use ':' or end of line. For example:
176 175
177 bb_opt_complementally = "-:w-x:x-w"; 176 bb_opt_complementally = "-:w-x:x-w";
178 bb_getopt_ulflags(argc, argv, "wx"); 177 bb_getopt_ulflags(argc, argv, "wx");
@@ -180,7 +179,10 @@ Special characters:
180 Allows any arguments to be given without a dash (./program w x) 179 Allows any arguments to be given without a dash (./program w x)
181 as well as with a dash (./program -x). Why unset -w see above. 180 as well as with a dash (./program -x). Why unset -w see above.
182 181
183 "~" A tilde between two options, or between an option and a group 182 "-N" A dash as the first char in a bb_opt_complementally group with
183 number 0-9 as one char is means check minimal arguments required.
184
185 "--" A double dash between two options, or between an option and a group
184 of options, means that they are mutually exclusive. Unlike 186 of options, means that they are mutually exclusive. Unlike
185 the "-" case above, an error will be forced if the options 187 the "-" case above, an error will be forced if the options
186 are used together. 188 are used together.
@@ -189,7 +191,7 @@ Special characters:
189 The cut applet must have only one type of list specified, so 191 The cut applet must have only one type of list specified, so
190 -b, -c and -f are mutally exclusive and should raise an error 192 -b, -c and -f are mutally exclusive and should raise an error
191 if specified together. In this case you must set 193 if specified together. In this case you must set
192 bb_opt_complementally = "b~cf:c~bf:f~bc". If two of the 194 bb_opt_complementally = "b--cf:c--bf:f--bc". If two of the
193 mutually exclusive options are found, bb_getopt_ulflags's 195 mutually exclusive options are found, bb_getopt_ulflags's
194 return value will have the error flag set (BB_GETOPT_ERROR) so 196 return value will have the error flag set (BB_GETOPT_ERROR) so
195 that we can check for it: 197 that we can check for it:
@@ -199,9 +201,13 @@ Special characters:
199 201
200 "?" A "ask" as the first char in a bb_opt_complementally group give: 202 "?" A "ask" as the first char in a bb_opt_complementally group give:
201 if previous point set BB_GETOPT_ERROR, don`t return and 203 if previous point set BB_GETOPT_ERROR, don`t return and
202 call previous example internally 204 call previous example internally. Next char for this case can`t
205 set to [0-9], recomended use ':' or end of line.
206
207 "?N" A "ask" as the first char in a bb_opt_complementally group with
208 number 0-9 as one char is means check maximal arguments possible.
203 209
204 "*" A star after a char in bb_opt_complementally means that the 210 "::" A double colon after a char in bb_opt_complementally means that the
205 option can occur multiple times: 211 option can occur multiple times:
206 212
207 For example: 213 For example:
@@ -213,33 +219,45 @@ Special characters:
213 (this pointer must be initializated to NULL if the list is empty 219 (this pointer must be initializated to NULL if the list is empty
214 as required by *llist_add_to(llist_t *old_head, char *new_item).) 220 as required by *llist_add_to(llist_t *old_head, char *new_item).)
215 221
216 bb_opt_complementally = "e*"; 222 bb_opt_complementally = "e::";
217 223
218 bb_getopt_ulflags(argc, argv, "e:", &patterns); 224 bb_getopt_ulflags(argc, argv, "e:", &patterns);
219 $ grep -e user -e root /etc/passwd 225 $ grep -e user -e root /etc/passwd
220 root:x:0:0:root:/root:/bin/bash 226 root:x:0:0:root:/root:/bin/bash
221 user:x:500:500::/home/user:/bin/bash 227 user:x:500:500::/home/user:/bin/bash
222 228
229 "--" A double dash as the first char in a bb_opt_complementally group
230 means make first argv[1] as option always as may be added -, special
231 for "ar" and "tar" applets.
232
223 "?" A "ask" between main and group options causes the second of the two 233 "?" 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. 234 to be depending required as or if first is given on the command line.
225 For example from "id" applet: 235 For example from "id" applet:
226 236
227 // Don't allow -n -r -rn -ug -rug -nug -rnug 237 // Don't allow -n -r -rn -ug -rug -nug -rnug
228 bb_opt_complementally = "?u~g:g~u:r?ug:n?ug"; 238 bb_opt_complementally = "r?ug:n?ug:?u--g:g--u";
229 flags = bb_getopt_ulflags(argc, argv, "rnug"); 239 flags = bb_getopt_ulflags(argc, argv, "rnug");
230 240
231 This example allowed only: 241 This example allowed only:
232 $ id; id -u; id -g; id -ru; id -nu; id -rg; id -ng; id -rnu; id -rng 242 $ id; id -u; id -g; id -ru; id -nu; id -rg; id -ng; id -rnu; id -rng
233 243
234 "?" A "ask" between equivalent options in bb_opt_complementally means 244 "X" A one options in bb_opt_complementally group means
235 requires this option always, checked after switch off from 245 requires this option always with "or" logic if more one specified,
236 complementally logic 246 checked after switch off from complementally logic.
237 For example from "start-stop-daemon" applet: 247 For example from "start-stop-daemon" applet:
238 248
239 // Don't allow -KS -SK, but -S or -K required 249 // Don't allow -KS -SK, but -S or -K required
240 bb_opt_complementally = "?:K?K:S?S:K~S:S~K"; 250 bb_opt_complementally = "K:S:?K--S:S--K";
241 flags = bb_getopt_ulflags(argc, argv, "KS...); 251 flags = bb_getopt_ulflags(argc, argv, "KS...);
242 252
253
254 "x--x" give error if double or more used -x option
255
256 Don`t forget ':' store. For example "?322-22-23X-x-a" interpretet as
257 "?3:22:-2:2-2:2-3Xa:2--x": max args is 3, count -2 usaged, min args is 2,
258 -2 option triggered, unset -3 and -X and -a if -2 any usaged, give error if
259 after -2 the -x option usaged.
260
243*/ 261*/
244 262
245const char *bb_opt_complementally; 263const char *bb_opt_complementally;
@@ -277,22 +295,25 @@ bb_getopt_ulflags (int argc, char **argv, const char *applet_opts, ...)
277 const struct option *l_o; 295 const struct option *l_o;
278 unsigned long trigger; 296 unsigned long trigger;
279 char **pargv = NULL; 297 char **pargv = NULL;
298 int min_arg = 0;
299 int max_arg = -1;
280 300
281#define SHOW_USAGE_IF_ERROR 1 301#define SHOW_USAGE_IF_ERROR 1
282#define ARGV_IS_OPTS 2 302#define ALL_ARGV_IS_OPTS 2
303#define FIRST_ARGV_IS_OPT 4
304#define FREE_FIRST_ARGV_IS_OPT 8
283 int spec_flgs = 0; 305 int spec_flgs = 0;
284 306
285 va_start (p, applet_opts); 307 va_start (p, applet_opts);
286 308
287 /* skip GNU extension */
288 s = applet_opts;
289 if(*s == '+' || *s == '-')
290 s++;
291
292 c = 0; 309 c = 0;
293 on_off = complementally; 310 on_off = complementally;
294 memset(on_off, 0, sizeof(complementally)); 311 memset(on_off, 0, sizeof(complementally));
295 312
313 /* skip GNU extension */
314 s = applet_opts;
315 if(*s == '+' || *s == '-')
316 s++;
296 for (; *s; s++) { 317 for (; *s; s++) {
297 if(c >= (int)(sizeof(flags)*8)) 318 if(c >= (int)(sizeof(flags)*8))
298 break; 319 break;
@@ -324,68 +345,86 @@ bb_getopt_ulflags (int argc, char **argv, const char *applet_opts, ...)
324 c++; 345 c++;
325 } 346 }
326 } 347 }
327 c = 0;
328 for (s = bb_opt_complementally; s && *s; s++) { 348 for (s = bb_opt_complementally; s && *s; s++) {
329 t_complementally *pair; 349 t_complementally *pair;
350 unsigned long *pair_switch;
330 351
331 if (*s == ':') { 352 if (*s == ':')
332 c = 0;
333 continue;
334 }
335 if (c)
336 continue; 353 continue;
354 c = s[1];
337 if(*s == '?') { 355 if(*s == '?') {
338 spec_flgs |= SHOW_USAGE_IF_ERROR; 356 if(c < '0' || c > '9') {
357 spec_flgs |= SHOW_USAGE_IF_ERROR;
358 } else {
359 max_arg = c - '0';
360 s++;
361 }
339 continue; 362 continue;
340 } 363 }
341 if(*s == '-') { 364 if(*s == '-') {
342 spec_flgs |= ARGV_IS_OPTS; 365 if(c < '0' || c > '9') {
366 if(c == '-') {
367 spec_flgs |= FIRST_ARGV_IS_OPT;
368 s++;
369 } else
370 spec_flgs |= ALL_ARGV_IS_OPTS;
371 } else {
372 min_arg = c - '0';
373 s++;
374 }
343 continue; 375 continue;
344 } 376 }
345 for (on_off = complementally; on_off->opt; on_off++) 377 for (on_off = complementally; on_off->opt; on_off++)
346 if (on_off->opt == *s) 378 if (on_off->opt == *s)
347 break; 379 break;
380 if(c == ':' && s[2] == ':') {
381 on_off->list_flg++;
382 continue;
383 }
384 if(c == ':' || c == '\0') {
385 requires |= on_off->switch_on;
386 continue;
387 }
388 if(c == *s) {
389 on_off->counter = va_arg (p, int *);
390 s++;
391 }
348 pair = on_off; 392 pair = on_off;
393 pair_switch = &(pair->switch_on);
349 for(s++; *s && *s != ':'; s++) { 394 for(s++; *s && *s != ':'; s++) {
350 if (*s == '-' || *s == '~' || *s == '?') { 395 if(*s == '?') {
351 c = *s; 396 pair_switch = &(pair->requires);
352 } else if(*s == '*') { 397 } else if (*s == '-') {
353 pair->list_flg++; 398 if(pair_switch == &(pair->switch_off))
354 } else {
355 unsigned long *pair_switch;
356
357 switch(c) {
358 case '-':
359 pair_switch = &(pair->switch_off);
360 break;
361 case '~':
362 pair_switch = &(pair->incongruously); 399 pair_switch = &(pair->incongruously);
363 break; 400 else
364 case '?': 401 pair_switch = &(pair->switch_off);
365 pair_switch = &(pair->requires); 402 } else {
366 break;
367 default:
368 pair_switch = &(pair->switch_on);
369 }
370 for (on_off = complementally; on_off->opt; on_off++) 403 for (on_off = complementally; on_off->opt; on_off++)
371 if (on_off->opt == *s) { 404 if (on_off->opt == *s) {
372 if(pair_switch == &(on_off->switch_on)) 405 *pair_switch |= on_off->switch_on;
373 on_off->counter = va_arg (p, int *);
374 else if(pair_switch == &(on_off->requires))
375 requires |= on_off->switch_on;
376 else
377 *pair_switch |= on_off->switch_on;
378 break; 406 break;
379 } 407 }
380 } 408 }
381 } 409 }
382 s--; 410 s--;
383 } 411 }
384 412 va_end (p);
413
414#if defined(CONFIG_AR) || defined(CONFIG_TAR)
415 if((spec_flgs & FIRST_ARGV_IS_OPT)) {
416 if(argv[1] && argv[1][0] != '-' && argv[1][0] != '\0') {
417 argv[1] = bb_xasprintf("-%s", argv[1]);
418 if(ENABLE_FEATURE_CLEAN_UP)
419 spec_flgs |= FREE_FIRST_ARGV_IS_OPT;
420 }
421 }
422#endif
385 while ((c = getopt_long (argc, argv, applet_opts, 423 while ((c = getopt_long (argc, argv, applet_opts,
386 bb_applet_long_options, NULL)) >= 0) { 424 bb_applet_long_options, NULL)) >= 0) {
387 425#ifdef CONFIG_PS
388loop_arg_is_opt: 426loop_arg_is_opt:
427#endif
389 for (on_off = complementally; on_off->opt != c; on_off++) { 428 for (on_off = complementally; on_off->opt != c; on_off++) {
390 /* c==0 if long opt have non NULL flag */ 429 /* c==0 if long opt have non NULL flag */
391 if(on_off->opt == 0 && c != 0) 430 if(on_off->opt == 0 && c != 0)
@@ -408,10 +447,14 @@ loop_arg_is_opt:
408 } else if (on_off->optarg) { 447 } else if (on_off->optarg) {
409 *(char **)(on_off->optarg) = optarg; 448 *(char **)(on_off->optarg) = optarg;
410 } 449 }
450#ifdef CONFIG_PS
411 if(pargv != NULL) 451 if(pargv != NULL)
412 break; 452 break;
453#endif
413 } 454 }
414 if((spec_flgs & ARGV_IS_OPTS)) { 455
456#ifdef CONFIG_PS
457 if((spec_flgs & ALL_ARGV_IS_OPTS)) {
415 /* process argv is option, for example "ps" applet */ 458 /* process argv is option, for example "ps" applet */
416 if(pargv == NULL) 459 if(pargv == NULL)
417 pargv = argv + optind; 460 pargv = argv + optind;
@@ -425,6 +468,13 @@ loop_arg_is_opt:
425 } 468 }
426 } 469 }
427 } 470 }
471#endif
472
473#if (defined(CONFIG_AR) || defined(CONFIG_TAR)) && \
474 defined(CONFIG_FEATURE_CLEAN_UP)
475 if((spec_flgs & FREE_FIRST_ARGV_IS_OPT))
476 free(argv[1]);
477#endif
428 /* check depending requires for given options */ 478 /* check depending requires for given options */
429 for (on_off = complementally; on_off->opt; on_off++) { 479 for (on_off = complementally; on_off->opt; on_off++) {
430 if(on_off->requires && (flags & on_off->switch_on) && 480 if(on_off->requires && (flags & on_off->switch_on) &&
@@ -433,5 +483,8 @@ loop_arg_is_opt:
433 } 483 }
434 if(requires && (flags & requires) == 0) 484 if(requires && (flags & requires) == 0)
435 bb_show_usage (); 485 bb_show_usage ();
486 argc -= optind;
487 if(argc < min_arg || (max_arg >= 0 && argc > max_arg))
488 bb_show_usage ();
436 return flags; 489 return flags;
437} 490}
diff --git a/networking/traceroute.c b/networking/traceroute.c
index d716f2f73..690e21f82 100644
--- a/networking/traceroute.c
+++ b/networking/traceroute.c
@@ -965,7 +965,7 @@ traceroute_main(int argc, char *argv[])
965 965
966 opterr = 0; 966 opterr = 0;
967#ifdef CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE 967#ifdef CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE
968 bb_opt_complementally = "x-x:g*"; 968 bb_opt_complementally = "x-x:g::";
969#else 969#else
970 bb_opt_complementally = "x-x"; 970 bb_opt_complementally = "x-x";
971#endif 971#endif
diff --git a/networking/wget.c b/networking/wget.c
index 0a4ccaddd..165af9a58 100644
--- a/networking/wget.c
+++ b/networking/wget.c
@@ -177,23 +177,25 @@ int wget_main(int argc, char **argv)
177 struct sockaddr_in s_in; 177 struct sockaddr_in s_in;
178 llist_t *headers_llist = NULL; 178 llist_t *headers_llist = NULL;
179 179
180 FILE *sfp = NULL; /* socket to web/ftp server */ 180 FILE *sfp = NULL; /* socket to web/ftp server */
181 FILE *dfp = NULL; /* socket to ftp server (data) */ 181 FILE *dfp = NULL; /* socket to ftp server (data) */
182 char *fname_out = NULL; /* where to direct output (-O) */ 182 char *fname_out = NULL; /* where to direct output (-O) */
183 int do_continue = 0; /* continue a prev transfer (-c) */ 183 int do_continue = 0; /* continue a prev transfer (-c) */
184 long beg_range = 0L; /* range at which continue begins */ 184 long beg_range = 0L; /* range at which continue begins */
185 int got_clen = 0; /* got content-length: from server */ 185 int got_clen = 0; /* got content-length: from server */
186 FILE *output; /* socket to web server */ 186 FILE *output; /* socket to web server */
187 int quiet_flag = FALSE; /* Be verry, verry quiet... */ 187 int quiet_flag = FALSE; /* Be verry, verry quiet... */
188 int use_proxy = 1; /* Use proxies if env vars are set */ 188 int use_proxy = 1; /* Use proxies if env vars are set */
189 char *proxy_flag = "on"; /* Use proxies if env vars are set */ 189 char *proxy_flag = "on"; /* Use proxies if env vars are set */
190 190
191 /* 191 /*
192 * Crack command line. 192 * Crack command line.
193 */ 193 */
194 bb_opt_complementally = "\203*"; 194 bb_opt_complementally = "-1:\203::";
195 bb_applet_long_options = wget_long_options; 195 bb_applet_long_options = wget_long_options;
196 opt = bb_getopt_ulflags(argc, argv, "cq\213O:\203:P:Y:", &fname_out, &headers_llist, &dir_prefix, &proxy_flag); 196 opt = bb_getopt_ulflags(argc, argv, "cq\213O:\203:P:Y:",
197 &fname_out, &headers_llist,
198 &dir_prefix, &proxy_flag);
197 if (opt & WGET_OPT_CONTINUE) { 199 if (opt & WGET_OPT_CONTINUE) {
198 ++do_continue; 200 ++do_continue;
199 } 201 }
@@ -218,9 +220,7 @@ int wget_main(int argc, char **argv)
218 headers_llist = headers_llist->link; 220 headers_llist = headers_llist->link;
219 } 221 }
220 } 222 }
221 if (argc - optind != 1) 223
222 bb_show_usage();
223
224 parse_url(argv[optind], &target); 224 parse_url(argv[optind], &target);
225 server.host = target.host; 225 server.host = target.host;
226 server.port = target.port; 226 server.port = target.port;
diff --git a/procps/pidof.c b/procps/pidof.c
index 76c58df85..acd2d515f 100644
--- a/procps/pidof.c
+++ b/procps/pidof.c
@@ -49,7 +49,7 @@ extern int pidof_main(int argc, char **argv)
49 unsigned long int opt; 49 unsigned long int opt;
50#if ENABLE_FEATURE_PIDOF_OMIT 50#if ENABLE_FEATURE_PIDOF_OMIT
51 llist_t *omits = NULL; /* list of pids to omit */ 51 llist_t *omits = NULL; /* list of pids to omit */
52 bb_opt_complementally = _OMIT_COMPL("o*"); 52 bb_opt_complementally = _OMIT_COMPL("o::");
53#endif 53#endif
54 54
55 /* do unconditional option parsing */ 55 /* do unconditional option parsing */
diff --git a/util-linux/hwclock.c b/util-linux/hwclock.c
index 3021442b7..5b990df0c 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 */