aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-07-24 15:54:42 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-07-24 15:54:42 +0000
commit990d0f63eeb502c8762076e5c5499196e09cba55 (patch)
tree30a2091a8159b1694d65f9952e2aba2667d7dc11
parentbcb66ec22e82f6b1ab93f3aec917269393a5b464 (diff)
downloadbusybox-w32-990d0f63eeb502c8762076e5c5499196e09cba55.tar.gz
busybox-w32-990d0f63eeb502c8762076e5c5499196e09cba55.tar.bz2
busybox-w32-990d0f63eeb502c8762076e5c5499196e09cba55.zip
Replace index_in_[sub]str_array with index_in_[sub]strings,
which scans thru "abc\0def\0123\0\0" type strings. Saves 250 bytes. text data bss dec hex filename 781266 1328 11844 794438 c1f46 busybox_old 781010 1328 11844 794182 c1e46 busybox_unstripped
-rw-r--r--archival/dpkg.c11
-rw-r--r--archival/tar.c2
-rw-r--r--console-tools/setconsole.c2
-rw-r--r--coreutils/dd.c23
-rw-r--r--coreutils/env.c2
-rw-r--r--coreutils/expr.c7
-rw-r--r--coreutils/install.c2
-rw-r--r--coreutils/ls.c2
-rw-r--r--coreutils/mkdir.c2
-rw-r--r--coreutils/mv.c2
-rw-r--r--coreutils/od_bloaty.c2
-rw-r--r--coreutils/stty.c22
-rw-r--r--coreutils/tr.c11
-rw-r--r--debianutils/run_parts.c2
-rw-r--r--debianutils/start_stop_daemon.c2
-rw-r--r--e2fsprogs/fsck.c40
-rw-r--r--findutils/find.c76
-rw-r--r--include/libbb.h6
-rw-r--r--libbb/compare_string_array.c33
-rw-r--r--libbb/dump.c2
-rw-r--r--libbb/getopt32.c2
-rw-r--r--loginutils/chpasswd.c2
-rw-r--r--miscutils/devfsd.c38
-rw-r--r--networking/arp.c24
-rw-r--r--networking/ftpgetput.c2
-rw-r--r--networking/ip.c19
-rw-r--r--networking/ipcalc.c2
-rw-r--r--networking/libiproute/ip_parse_common_args.c10
-rw-r--r--networking/libiproute/ipaddress.c30
-rw-r--r--networking/libiproute/iplink.c20
-rw-r--r--networking/libiproute/iproute.c93
-rw-r--r--networking/libiproute/iprule.c24
-rw-r--r--networking/libiproute/iptunnel.c41
-rw-r--r--networking/libiproute/rtm_map.c14
-rw-r--r--networking/slattach.c21
-rw-r--r--networking/udhcp/dhcpc.c2
-rw-r--r--networking/udhcp/dumpleases.c2
-rw-r--r--networking/wget.c11
-rw-r--r--selinux/chcon.c2
-rw-r--r--selinux/runcon.c2
-rw-r--r--util-linux/getopt.c2
-rw-r--r--util-linux/hwclock.c2
-rw-r--r--util-linux/mount.c76
43 files changed, 352 insertions, 340 deletions
diff --git a/archival/dpkg.c b/archival/dpkg.c
index 0c1f541e0..bd729a2a9 100644
--- a/archival/dpkg.c
+++ b/archival/dpkg.c
@@ -582,10 +582,9 @@ static int read_package_field(const char *package_buffer, char **field_name, cha
582 582
583static unsigned fill_package_struct(char *control_buffer) 583static unsigned fill_package_struct(char *control_buffer)
584{ 584{
585 static const char *const field_names[] = { "Package", "Version", 585 static const char field_names[] = "Package\0""Version\0"
586 "Pre-Depends", "Depends","Replaces", "Provides", 586 "Pre-Depends\0""Depends\0""Replaces\0""Provides\0"
587 "Conflicts", "Suggests", "Recommends", "Enhances", NULL 587 "Conflicts\0""Suggests\0""Recommends\0""Enhances\0";
588 };
589 588
590 common_node_t *new_node = xzalloc(sizeof(common_node_t)); 589 common_node_t *new_node = xzalloc(sizeof(common_node_t));
591 char *field_name; 590 char *field_name;
@@ -602,10 +601,10 @@ static unsigned fill_package_struct(char *control_buffer)
602 &field_name, &field_value); 601 &field_name, &field_value);
603 602
604 if (field_name == NULL) { 603 if (field_name == NULL) {
605 goto fill_package_struct_cleanup; /* Oh no, the dreaded goto statement ! */ 604 goto fill_package_struct_cleanup; /* Oh no, the dreaded goto statement! */
606 } 605 }
607 606
608 field_num = index_in_str_array(field_names, field_name); 607 field_num = index_in_strings(field_names, field_name);
609 switch (field_num) { 608 switch (field_num) {
610 case 0: /* Package */ 609 case 0: /* Package */
611 new_node->name = search_name_hashtable(field_value); 610 new_node->name = search_name_hashtable(field_value);
diff --git a/archival/tar.c b/archival/tar.c
index d03b18b9c..7d7bf79d6 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -752,7 +752,7 @@ static const char tar_longopts[] =
752# if ENABLE_FEATURE_TAR_FROM 752# if ENABLE_FEATURE_TAR_FROM
753 "exclude\0" Required_argument "\xff" 753 "exclude\0" Required_argument "\xff"
754# endif 754# endif
755 "\0"; 755 ;
756#endif 756#endif
757 757
758int tar_main(int argc, char **argv); 758int tar_main(int argc, char **argv);
diff --git a/console-tools/setconsole.c b/console-tools/setconsole.c
index 2e60c375e..5908dad48 100644
--- a/console-tools/setconsole.c
+++ b/console-tools/setconsole.c
@@ -13,7 +13,7 @@
13#if ENABLE_FEATURE_SETCONSOLE_LONG_OPTIONS 13#if ENABLE_FEATURE_SETCONSOLE_LONG_OPTIONS
14static const char setconsole_longopts[] = 14static const char setconsole_longopts[] =
15 "reset\0" No_argument "r" 15 "reset\0" No_argument "r"
16 "\0"; 16 ;
17#endif 17#endif
18 18
19#define OPT_SETCONS_RESET 1 19#define OPT_SETCONS_RESET 1
diff --git a/coreutils/dd.c b/coreutils/dd.c
index dd311d86a..22ad19287 100644
--- a/coreutils/dd.c
+++ b/coreutils/dd.c
@@ -51,7 +51,7 @@ static ssize_t full_write_or_warn(int fd, const void *buf, size_t len,
51} 51}
52 52
53static bool write_and_stats(int fd, const void *buf, size_t len, size_t obs, 53static bool write_and_stats(int fd, const void *buf, size_t len, size_t obs,
54 const char * const filename) 54 const char *filename)
55{ 55{
56 ssize_t n = full_write_or_warn(fd, buf, len, filename); 56 ssize_t n = full_write_or_warn(fd, buf, len, filename);
57 if (n < 0) 57 if (n < 0)
@@ -78,13 +78,12 @@ int dd_main(int argc, char **argv)
78 TRUNC_FLAG = 1 << 2, 78 TRUNC_FLAG = 1 << 2,
79 TWOBUFS_FLAG = 1 << 3, 79 TWOBUFS_FLAG = 1 << 3,
80 }; 80 };
81 static const char * const keywords[] = { 81 static const char keywords[] =
82 "bs=", "count=", "seek=", "skip=", "if=", "of=", 82 "bs=\0""count=\0""seek=\0""skip=\0""if=\0""of=\0"
83#if ENABLE_FEATURE_DD_IBS_OBS 83#if ENABLE_FEATURE_DD_IBS_OBS
84 "ibs=", "obs=", "conv=", "notrunc", "sync", "noerror", 84 "ibs=\0""obs=\0""conv=\0""notrunc\0""sync\0""noerror\0"
85#endif 85#endif
86 NULL 86 ;
87 };
88 enum { 87 enum {
89 OP_bs = 1, 88 OP_bs = 1,
90 OP_count, 89 OP_count,
@@ -134,7 +133,7 @@ int dd_main(int argc, char **argv)
134 bb_show_usage(); 133 bb_show_usage();
135 key_len = key - arg + 1; 134 key_len = key - arg + 1;
136 key = xstrndup(arg, key_len); 135 key = xstrndup(arg, key_len);
137 what = index_in_str_array(keywords, key) + 1; 136 what = index_in_strings(keywords, key) + 1;
138 if (ENABLE_FEATURE_CLEAN_UP) 137 if (ENABLE_FEATURE_CLEAN_UP)
139 free(key); 138 free(key);
140 if (what == 0) 139 if (what == 0)
@@ -153,13 +152,13 @@ int dd_main(int argc, char **argv)
153 if (what == OP_conv) { 152 if (what == OP_conv) {
154 while (1) { 153 while (1) {
155 /* find ',', replace them with nil so we can use arg for 154 /* find ',', replace them with nil so we can use arg for
156 * index_in_str_array without copying. 155 * index_in_strings() without copying.
157 * We rely on arg being non-null, else strchr would fault. 156 * We rely on arg being non-null, else strchr would fault.
158 */ 157 */
159 key = strchr(arg, ','); 158 key = strchr(arg, ',');
160 if (key) 159 if (key)
161 *key = '\0'; 160 *key = '\0';
162 what = index_in_str_array(keywords, arg) + 1; 161 what = index_in_strings(keywords, arg) + 1;
163 if (what < OP_conv_notrunc) 162 if (what < OP_conv_notrunc)
164 bb_error_msg_and_die(bb_msg_invalid_arg, arg, "conv"); 163 bb_error_msg_and_die(bb_msg_invalid_arg, arg, "conv");
165 if (what == OP_conv_notrunc) 164 if (what == OP_conv_notrunc)
@@ -298,15 +297,15 @@ int dd_main(int argc, char **argv)
298 G.out_part++; 297 G.out_part++;
299 } 298 }
300 if (close(ifd) < 0) { 299 if (close(ifd) < 0) {
301die_infile: 300 die_infile:
302 bb_perror_msg_and_die("%s", infile); 301 bb_perror_msg_and_die("%s", infile);
303 } 302 }
304 303
305 if (close(ofd) < 0) { 304 if (close(ofd) < 0) {
306die_outfile: 305 die_outfile:
307 bb_perror_msg_and_die("%s", outfile); 306 bb_perror_msg_and_die("%s", outfile);
308 } 307 }
309out_status: 308 out_status:
310 dd_output_status(0); 309 dd_output_status(0);
311 310
312 return EXIT_SUCCESS; 311 return EXIT_SUCCESS;
diff --git a/coreutils/env.c b/coreutils/env.c
index 8d20eac9c..31167d029 100644
--- a/coreutils/env.c
+++ b/coreutils/env.c
@@ -38,7 +38,7 @@ extern char **environ;
38static const char env_longopts[] = 38static const char env_longopts[] =
39 "ignore-environment\0" No_argument "i" 39 "ignore-environment\0" No_argument "i"
40 "unset\0" Required_argument "u" 40 "unset\0" Required_argument "u"
41 "\0"; 41 ;
42#endif 42#endif
43 43
44int env_main(int argc, char** argv); 44int env_main(int argc, char** argv);
diff --git a/coreutils/expr.c b/coreutils/expr.c
index ab182a804..6a4683d90 100644
--- a/coreutils/expr.c
+++ b/coreutils/expr.c
@@ -277,14 +277,13 @@ static VALUE *eval7(void)
277 277
278static VALUE *eval6(void) 278static VALUE *eval6(void)
279{ 279{
280 static const char * const keywords[] = { 280 static const char keywords[] =
281 "quote", "length", "match", "index", "substr", NULL 281 "quote\0""length\0""match\0""index\0""substr\0";
282 };
283 282
284 VALUE *r, *i1, *i2; 283 VALUE *r, *i1, *i2;
285 VALUE *l = l; /* silence gcc */ 284 VALUE *l = l; /* silence gcc */
286 VALUE *v = v; /* silence gcc */ 285 VALUE *v = v; /* silence gcc */
287 int key = *G.args ? index_in_str_array(keywords, *G.args) + 1 : 0; 286 int key = *G.args ? index_in_strings(keywords, *G.args) + 1 : 0;
288 287
289 if (key == 0) /* not a keyword */ 288 if (key == 0) /* not a keyword */
290 return eval7(); 289 return eval7();
diff --git a/coreutils/install.c b/coreutils/install.c
index 8d5494958..c2638f492 100644
--- a/coreutils/install.c
+++ b/coreutils/install.c
@@ -28,7 +28,7 @@ static const char install_longopts[] =
28 "preserve_context\0" No_argument "\xff" 28 "preserve_context\0" No_argument "\xff"
29 "preserve-context\0" No_argument "\xff" 29 "preserve-context\0" No_argument "\xff"
30#endif 30#endif
31 "\0"; 31 ;
32#endif 32#endif
33 33
34 34
diff --git a/coreutils/ls.c b/coreutils/ls.c
index 8545edda9..f47ec204c 100644
--- a/coreutils/ls.c
+++ b/coreutils/ls.c
@@ -122,7 +122,7 @@ static smallint show_color;
122 * equivalent */ 122 * equivalent */
123static const char ls_color_opt[] = 123static const char ls_color_opt[] =
124 "color\0" Optional_argument "\xff" /* no short equivalent */ 124 "color\0" Optional_argument "\xff" /* no short equivalent */
125 "\0"; 125 ;
126#else 126#else
127enum { show_color = 0 }; 127enum { show_color = 0 };
128#endif 128#endif
diff --git a/coreutils/mkdir.c b/coreutils/mkdir.c
index b0595b43f..a6eaa9612 100644
--- a/coreutils/mkdir.c
+++ b/coreutils/mkdir.c
@@ -31,7 +31,7 @@ static const char mkdir_longopts[] =
31#if ENABLE_SELINUX 31#if ENABLE_SELINUX
32 "context\0" Required_argument "Z" 32 "context\0" Required_argument "Z"
33#endif 33#endif
34 "\0"; 34 ;
35#endif 35#endif
36 36
37int mkdir_main(int argc, char **argv); 37int mkdir_main(int argc, char **argv);
diff --git a/coreutils/mv.c b/coreutils/mv.c
index bb96af8f6..064407838 100644
--- a/coreutils/mv.c
+++ b/coreutils/mv.c
@@ -24,7 +24,7 @@
24static const char mv_longopts[] = 24static const char mv_longopts[] =
25 "interactive\0" No_argument "i" 25 "interactive\0" No_argument "i"
26 "force\0" No_argument "f" 26 "force\0" No_argument "f"
27 "\0"; 27 ;
28#endif 28#endif
29 29
30#define OPT_FILEUTILS_FORCE 1 30#define OPT_FILEUTILS_FORCE 1
diff --git a/coreutils/od_bloaty.c b/coreutils/od_bloaty.c
index 0b77f8b94..803407224 100644
--- a/coreutils/od_bloaty.c
+++ b/coreutils/od_bloaty.c
@@ -1242,7 +1242,7 @@ int od_main(int argc, char **argv)
1242 "strings\0" Optional_argument "S" 1242 "strings\0" Optional_argument "S"
1243 "width\0" Optional_argument "w" 1243 "width\0" Optional_argument "w"
1244 "traditional\0" No_argument "\xff" 1244 "traditional\0" No_argument "\xff"
1245 "\0"; 1245 ;
1246#endif 1246#endif
1247 char *str_A, *str_N, *str_j, *str_S; 1247 char *str_A, *str_N, *str_j, *str_S;
1248 char *str_w = NULL; 1248 char *str_w = NULL;
diff --git a/coreutils/stty.c b/coreutils/stty.c
index 0983532cf..b73e2eace 100644
--- a/coreutils/stty.c
+++ b/coreutils/stty.c
@@ -562,18 +562,16 @@ enum {
562 562
563static int find_param(const char * const name) 563static int find_param(const char * const name)
564{ 564{
565 static const char * const params[] = { 565 static const char params[] =
566 "line", /* 1 */ 566 "line\0" /* 1 */
567 "rows", /* 2 */ 567 "rows\0" /* 2 */
568 "cols", /* 3 */ 568 "cols\0" /* 3 */
569 "columns", /* 4 */ 569 "columns\0" /* 4 */
570 "size", /* 5 */ 570 "size\0" /* 5 */
571 "ispeed"+1, /* 6 */ 571 "speed\0" /* 6 */
572 "ispeed", 572 "ispeed\0"
573 "ospeed", 573 "ospeed\0";
574 NULL 574 int i = index_in_strings(params, name) + 1;
575 };
576 int i = index_in_str_array(params, name) + 1;
577 if (i == 0) 575 if (i == 0)
578 return 0; 576 return 0;
579 if (i != 5 && i != 6) 577 if (i != 5 && i != 6)
diff --git a/coreutils/tr.c b/coreutils/tr.c
index c0d0dfacb..594571833 100644
--- a/coreutils/tr.c
+++ b/coreutils/tr.c
@@ -51,11 +51,10 @@ static unsigned int expand(const char *arg, char *buffer)
51 char *buffer_start = buffer; 51 char *buffer_start = buffer;
52 unsigned i; /* XXX: FIXME: use unsigned char? */ 52 unsigned i; /* XXX: FIXME: use unsigned char? */
53 unsigned char ac; 53 unsigned char ac;
54#define CLO ":]" 54#define CLO ":]\0"
55 static const char * const classes[] = { 55 static const char classes[] =
56 "alpha"CLO, "alnum"CLO, "digit"CLO, "lower"CLO, "upper"CLO, "space"CLO, 56 "alpha"CLO "alnum"CLO "digit"CLO "lower"CLO "upper"CLO "space"CLO
57 "blank"CLO, "punct"CLO, "cntrl"CLO, NULL 57 "blank"CLO "punct"CLO "cntrl"CLO;
58 };
59#define CLASS_invalid 0 /* we increment the retval */ 58#define CLASS_invalid 0 /* we increment the retval */
60#define CLASS_alpha 1 59#define CLASS_alpha 1
61#define CLASS_alnum 2 60#define CLASS_alnum 2
@@ -90,7 +89,7 @@ static unsigned int expand(const char *arg, char *buffer)
90 smalluint j; 89 smalluint j;
91 { /* not really pretty.. */ 90 { /* not really pretty.. */
92 char *tmp = xstrndup(arg, 7); // warning: xdigit needs 8, not 7 91 char *tmp = xstrndup(arg, 7); // warning: xdigit needs 8, not 7
93 j = index_in_str_array(classes, tmp) + 1; 92 j = index_in_strings(classes, tmp) + 1;
94 free(tmp); 93 free(tmp);
95 } 94 }
96 if (j == CLASS_alnum || j == CLASS_digit) { 95 if (j == CLASS_alnum || j == CLASS_digit) {
diff --git a/debianutils/run_parts.c b/debianutils/run_parts.c
index 4173987ab..8a1f38a1d 100644
--- a/debianutils/run_parts.c
+++ b/debianutils/run_parts.c
@@ -44,7 +44,7 @@ static const char runparts_longopts[] =
44//TODO: "reverse\0" No_argument "r" 44//TODO: "reverse\0" No_argument "r"
45//TODO: "verbose\0" No_argument "v" 45//TODO: "verbose\0" No_argument "v"
46#endif 46#endif
47 "\0"; 47 ;
48#endif 48#endif
49 49
50struct globals { 50struct globals {
diff --git a/debianutils/start_stop_daemon.c b/debianutils/start_stop_daemon.c
index 0c8dea760..1933e1cfc 100644
--- a/debianutils/start_stop_daemon.c
+++ b/debianutils/start_stop_daemon.c
@@ -215,7 +215,7 @@ static const char start_stop_daemon_longopts[] =
215#if ENABLE_FEATURE_START_STOP_DAEMON_FANCY 215#if ENABLE_FEATURE_START_STOP_DAEMON_FANCY
216 "retry\0" Required_argument "R" 216 "retry\0" Required_argument "R"
217#endif 217#endif
218 "\0"; 218 ;
219#endif 219#endif
220 220
221enum { 221enum {
diff --git a/e2fsprogs/fsck.c b/e2fsprogs/fsck.c
index 2954cabf3..eb1fa84c8 100644
--- a/e2fsprogs/fsck.c
+++ b/e2fsprogs/fsck.c
@@ -79,29 +79,25 @@ struct fsck_instance {
79 char *base_device; /* /dev/hda for /dev/hdaN etc */ 79 char *base_device; /* /dev/hda for /dev/hdaN etc */
80}; 80};
81 81
82static const char *const ignored_types[] = { 82static const char ignored_types[] =
83 "ignore", 83 "ignore\0"
84 "iso9660", 84 "iso9660\0"
85 "nfs", 85 "nfs\0"
86 "proc", 86 "proc\0"
87 "sw", 87 "sw\0"
88 "swap", 88 "swap\0"
89 "tmpfs", 89 "tmpfs\0"
90 "devpts", 90 "devpts\0";
91 NULL
92};
93 91
94#if 0 92#if 0
95static const char *const really_wanted[] = { 93static const char really_wanted[] =
96 "minix", 94 "minix\0"
97 "ext2", 95 "ext2\0"
98 "ext3", 96 "ext3\0"
99 "jfs", 97 "jfs\0"
100 "reiserfs", 98 "reiserfs\0"
101 "xiafs", 99 "xiafs\0"
102 "xfs", 100 "xfs\0";
103 NULL
104};
105#endif 101#endif
106 102
107#define BASE_MD "/dev/md" 103#define BASE_MD "/dev/md"
@@ -847,7 +843,7 @@ static int ignore(struct fs_info *fs)
847 return 1; 843 return 1;
848 844
849 /* Are we ignoring this type? */ 845 /* Are we ignoring this type? */
850 if (index_in_str_array(ignored_types, fs->type) >= 0) 846 if (index_in_strings(ignored_types, fs->type) >= 0)
851 return 1; 847 return 1;
852 848
853 /* We can and want to check this file system type. */ 849 /* We can and want to check this file system type. */
diff --git a/findutils/find.c b/findutils/find.c
index 6f2cbbc78..eaf1d5946 100644
--- a/findutils/find.c
+++ b/findutils/find.c
@@ -470,38 +470,37 @@ static action*** parse_params(char **argv)
470 USE_FEATURE_FIND_CONTEXT(PARM_context ,) 470 USE_FEATURE_FIND_CONTEXT(PARM_context ,)
471 }; 471 };
472 472
473 static const char *const params[] = { 473 static const char params[] =
474 "-a" , 474 "-a\0"
475 "-o" , 475 "-o\0"
476 USE_FEATURE_FIND_NOT( "!" ,) 476 USE_FEATURE_FIND_NOT( "!\0" )
477#if ENABLE_DESKTOP 477#if ENABLE_DESKTOP
478 "-and" , 478 "-and\0"
479 "-or" , 479 "-or\0"
480 USE_FEATURE_FIND_NOT( "-not" ,) 480 USE_FEATURE_FIND_NOT( "-not\0" )
481#endif 481#endif
482 "-print" , 482 "-print\0"
483 USE_FEATURE_FIND_PRINT0( "-print0" ,) 483 USE_FEATURE_FIND_PRINT0( "-print0\0" )
484 USE_FEATURE_FIND_DEPTH( "-depth" ,) 484 USE_FEATURE_FIND_DEPTH( "-depth\0" )
485 USE_FEATURE_FIND_PRUNE( "-prune" ,) 485 USE_FEATURE_FIND_PRUNE( "-prune\0" )
486 USE_FEATURE_FIND_DELETE( "-delete" ,) 486 USE_FEATURE_FIND_DELETE( "-delete\0" )
487 USE_FEATURE_FIND_EXEC( "-exec" ,) 487 USE_FEATURE_FIND_EXEC( "-exec\0" )
488 USE_FEATURE_FIND_PAREN( "(" ,) 488 USE_FEATURE_FIND_PAREN( "(\0" )
489 /* All options starting from here require argument */ 489 /* All options starting from here require argument */
490 "-name" , 490 "-name\0"
491 USE_FEATURE_FIND_PATH( "-path" ,) 491 USE_FEATURE_FIND_PATH( "-path\0" )
492 USE_FEATURE_FIND_REGEX( "-regex" ,) 492 USE_FEATURE_FIND_REGEX( "-regex\0" )
493 USE_FEATURE_FIND_TYPE( "-type" ,) 493 USE_FEATURE_FIND_TYPE( "-type\0" )
494 USE_FEATURE_FIND_PERM( "-perm" ,) 494 USE_FEATURE_FIND_PERM( "-perm\0" )
495 USE_FEATURE_FIND_MTIME( "-mtime" ,) 495 USE_FEATURE_FIND_MTIME( "-mtime\0" )
496 USE_FEATURE_FIND_MMIN( "-mmin" ,) 496 USE_FEATURE_FIND_MMIN( "-mmin\0" )
497 USE_FEATURE_FIND_NEWER( "-newer" ,) 497 USE_FEATURE_FIND_NEWER( "-newer\0" )
498 USE_FEATURE_FIND_INUM( "-inum" ,) 498 USE_FEATURE_FIND_INUM( "-inum\0" )
499 USE_FEATURE_FIND_USER( "-user" ,) 499 USE_FEATURE_FIND_USER( "-user\0" )
500 USE_FEATURE_FIND_GROUP( "-group" ,) 500 USE_FEATURE_FIND_GROUP( "-group\0" )
501 USE_FEATURE_FIND_SIZE( "-size" ,) 501 USE_FEATURE_FIND_SIZE( "-size\0" )
502 USE_FEATURE_FIND_CONTEXT("-context",) 502 USE_FEATURE_FIND_CONTEXT("-context\0")
503 NULL 503 ;
504 };
505 504
506 action*** appp; 505 action*** appp;
507 unsigned cur_group = 0; 506 unsigned cur_group = 0;
@@ -541,7 +540,7 @@ static action*** parse_params(char **argv)
541 */ 540 */
542 while (*argv) { 541 while (*argv) {
543 const char *arg = argv[0]; 542 const char *arg = argv[0];
544 int parm = index_in_str_array(params, arg); 543 int parm = index_in_strings(params, arg);
545 const char *arg1 = argv[1]; 544 const char *arg1 = argv[1];
546 545
547 if (parm >= PARM_name) { 546 if (parm >= PARM_name) {
@@ -795,14 +794,13 @@ static action*** parse_params(char **argv)
795int find_main(int argc, char **argv); 794int find_main(int argc, char **argv);
796int find_main(int argc, char **argv) 795int find_main(int argc, char **argv)
797{ 796{
798 static const char *const options[] = { 797 static const char options[] =
799 "-follow", 798 "-follow\0"
800USE_FEATURE_FIND_XDEV( "-xdev" ,) 799USE_FEATURE_FIND_XDEV( "-xdev\0" )
801USE_FEATURE_FIND_MAXDEPTH("-maxdepth",) 800USE_FEATURE_FIND_MAXDEPTH("-maxdepth\0")
802 NULL 801 ;
803 };
804 enum { 802 enum {
805 OPT_FOLLOW, 803 OPT_FOLLOW,
806USE_FEATURE_FIND_XDEV( OPT_XDEV ,) 804USE_FEATURE_FIND_XDEV( OPT_XDEV ,)
807USE_FEATURE_FIND_MAXDEPTH(OPT_MAXDEPTH,) 805USE_FEATURE_FIND_MAXDEPTH(OPT_MAXDEPTH,)
808 }; 806 };
@@ -839,7 +837,7 @@ USE_FEATURE_FIND_MAXDEPTH(OPT_MAXDEPTH,)
839 /* (-a will be ignored by recursive parser later) */ 837 /* (-a will be ignored by recursive parser later) */
840 argp = &argv[firstopt]; 838 argp = &argv[firstopt];
841 while ((arg = argp[0])) { 839 while ((arg = argp[0])) {
842 int opt = index_in_str_array(options, arg); 840 int opt = index_in_strings(options, arg);
843 if (opt == OPT_FOLLOW) { 841 if (opt == OPT_FOLLOW) {
844 recurse_flags |= ACTION_FOLLOWLINKS; 842 recurse_flags |= ACTION_FOLLOWLINKS;
845 argp[0] = (char*)"-a"; 843 argp[0] = (char*)"-a";
diff --git a/include/libbb.h b/include/libbb.h
index fe99e5eec..8fb5520eb 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -773,8 +773,10 @@ extern int correct_password(const struct passwd *pw);
773/* Returns a ptr to static storage */ 773/* Returns a ptr to static storage */
774extern char *pw_encrypt(const char *clear, const char *salt); 774extern char *pw_encrypt(const char *clear, const char *salt);
775extern int obscure(const char *old, const char *newval, const struct passwd *pwdp); 775extern int obscure(const char *old, const char *newval, const struct passwd *pwdp);
776extern int index_in_str_array(const char * const string_array[], const char *key); 776extern int index_in_str_array(const char *const string_array[], const char *key);
777extern int index_in_substr_array(const char * const string_array[], const char *key); 777extern int index_in_strings(const char *strings, const char *key);
778extern int index_in_substr_array(const char *const string_array[], const char *key);
779extern int index_in_substrings(const char *strings, const char *key);
778extern void print_login_issue(const char *issue_file, const char *tty); 780extern void print_login_issue(const char *issue_file, const char *tty);
779extern void print_login_prompt(void); 781extern void print_login_prompt(void);
780 782
diff --git a/libbb/compare_string_array.c b/libbb/compare_string_array.c
index 077a280a2..e873d7cc3 100644
--- a/libbb/compare_string_array.c
+++ b/libbb/compare_string_array.c
@@ -19,8 +19,23 @@ int index_in_str_array(const char * const string_array[], const char *key)
19 return -1; 19 return -1;
20} 20}
21 21
22int index_in_strings(const char *strings, const char *key)
23{
24 int idx = 0;
25
26 while (strings[0]) {
27 if (strcmp(strings, key) == 0) {
28 return idx;
29 }
30 strings += strlen(strings) + 1; /* skip NUL */
31 idx++;
32 }
33 return -1;
34}
35
22/* returns the array index of the string, even if it matches only a beginning */ 36/* returns the array index of the string, even if it matches only a beginning */
23/* (index of first match is returned, or -1) */ 37/* (index of first match is returned, or -1) */
38#ifdef UNUSED
24int index_in_substr_array(const char * const string_array[], const char *key) 39int index_in_substr_array(const char * const string_array[], const char *key)
25{ 40{
26 int i; 41 int i;
@@ -34,3 +49,21 @@ int index_in_substr_array(const char * const string_array[], const char *key)
34 } 49 }
35 return -1; 50 return -1;
36} 51}
52#endif
53
54int index_in_substrings(const char *strings, const char *key)
55{
56 int len = strlen(key);
57
58 if (len) {
59 int idx = 0;
60 while (strings[0]) {
61 if (strncmp(strings, key, len) == 0) {
62 return idx;
63 }
64 strings += strlen(strings) + 1; /* skip NUL */
65 idx++;
66 }
67 }
68 return -1;
69}
diff --git a/libbb/dump.c b/libbb/dump.c
index 6dbbd9f84..5ddbbaaf6 100644
--- a/libbb/dump.c
+++ b/libbb/dump.c
@@ -449,7 +449,7 @@ static const char conv_str[] =
449 "\r\\r\0" 449 "\r\\r\0"
450 "\t\\t\0" 450 "\t\\t\0"
451 "\v\\v\0" 451 "\v\\v\0"
452 "\0"; 452 ;
453 453
454 454
455static void conv_c(PR * pr, unsigned char * p) 455static void conv_c(PR * pr, unsigned char * p)
diff --git a/libbb/getopt32.c b/libbb/getopt32.c
index 25eb113df..107102329 100644
--- a/libbb/getopt32.c
+++ b/libbb/getopt32.c
@@ -79,7 +79,7 @@ const char *applet_long_options
79 static const char applet_longopts[] = 79 static const char applet_longopts[] =
80 //"name\0" has_arg val 80 //"name\0" has_arg val
81 "verbose\0" No_argument "v" 81 "verbose\0" No_argument "v"
82 "\0"; 82 ;
83 applet_long_options = applet_longopts; 83 applet_long_options = applet_longopts;
84 84
85 The last member of struct option (val) typically is set to 85 The last member of struct option (val) typically is set to
diff --git a/loginutils/chpasswd.c b/loginutils/chpasswd.c
index 3e3e8d3d3..3e02c8e7c 100644
--- a/loginutils/chpasswd.c
+++ b/loginutils/chpasswd.c
@@ -14,7 +14,7 @@
14static const char chpasswd_longopts[] = 14static const char chpasswd_longopts[] =
15 "encrypted\0" No_argument "e" 15 "encrypted\0" No_argument "e"
16 "md5\0" No_argument "m" 16 "md5\0" No_argument "m"
17 "\0"; 17 ;
18#endif 18#endif
19 19
20#define OPT_ENC 1 20#define OPT_ENC 1
diff --git a/miscutils/devfsd.c b/miscutils/devfsd.c
index 6db0c7b05..848f2b3ea 100644
--- a/miscutils/devfsd.c
+++ b/miscutils/devfsd.c
@@ -509,12 +509,11 @@ static void process_config_line(const char *line, unsigned long *event_mask)
509 int i; 509 int i;
510 510
511 /* !!!! Only Uppercase Keywords in devsfd.conf */ 511 /* !!!! Only Uppercase Keywords in devsfd.conf */
512 static const char *const options[] = { 512 static const char options[] =
513 "CLEAR_CONFIG", "INCLUDE", "OPTIONAL_INCLUDE", 513 "CLEAR_CONFIG\0""INCLUDE\0""OPTIONAL_INCLUDE\0"
514 "RESTORE", "PERMISSIONS", "MODLOAD", "EXECUTE", 514 "RESTORE\0""PERMISSIONS\0""MODLOAD\0""EXECUTE\0"
515 "COPY", "IGNORE", "MKOLDCOMPAT", "MKNEWCOMPAT", 515 "COPY\0""IGNORE\0""MKOLDCOMPAT\0""MKNEWCOMPAT\0"
516 "RMOLDCOMPAT", "RMNEWCOMPAT", 0 516 "RMOLDCOMPAT\0""RMNEWCOMPAT\0";
517 };
518 517
519 for (count = 0; count < MAX_ARGS; ++count) 518 for (count = 0; count < MAX_ARGS; ++count)
520 p[count][0] = '\0'; 519 p[count][0] = '\0';
@@ -522,9 +521,9 @@ static void process_config_line(const char *line, unsigned long *event_mask)
522 when, name, what, 521 when, name, what,
523 p[0], p[1], p[2], p[3], p[4], p[5], p[6]); 522 p[0], p[1], p[2], p[3], p[4], p[5], p[6]);
524 523
525 i = index_in_str_array(options, when); 524 i = index_in_strings(options, when);
526 525
527 /*"CLEAR_CONFIG"*/ 526 /* "CLEAR_CONFIG" */
528 if (i == 0) { 527 if (i == 0) {
529 free_config(); 528 free_config();
530 *event_mask = 0; 529 *event_mask = 0;
@@ -562,7 +561,7 @@ static void process_config_line(const char *line, unsigned long *event_mask)
562 goto process_config_line_err; 561 goto process_config_line_err;
563 } 562 }
564 563
565 i = index_in_str_array(options, what); 564 i = index_in_strings(options, what);
566 565
567 switch (i) { 566 switch (i) {
568 case 4: /* "PERMISSIONS" */ 567 case 4: /* "PERMISSIONS" */
@@ -1140,27 +1139,30 @@ static void signal_handler(int sig)
1140 1139
1141static const char *get_variable(const char *variable, void *info) 1140static const char *get_variable(const char *variable, void *info)
1142{ 1141{
1142 static char sbuf[sizeof(int)*3 + 2]; /* sign and NUL */
1143
1144 char hostname[STRING_LENGTH];
1143 struct get_variable_info *gv_info = info; 1145 struct get_variable_info *gv_info = info;
1144 static char hostname[STRING_LENGTH], sbuf[STRING_LENGTH]; 1146 const char *field_names[] = {
1145 const char *field_names[] = { "hostname", "mntpt", "devpath", "devname", 1147 "hostname", "mntpt", "devpath", "devname",
1146 "uid", "gid", "mode", hostname, mount_point, 1148 "uid", "gid", "mode", hostname, mount_point,
1147 gv_info->devpath, gv_info->devname, 0 }; 1149 gv_info->devpath, gv_info->devname, NULL
1150 };
1148 int i; 1151 int i;
1149 1152
1150 if (gethostname(hostname, STRING_LENGTH - 1) != 0) 1153 if (gethostname(hostname, STRING_LENGTH - 1) != 0)
1154 /* Here on error we should do exit(RV_SYS_ERROR), instead we do exit(EXIT_FAILURE) */
1151 error_logger_and_die(LOG_ERR, "gethostname"); 1155 error_logger_and_die(LOG_ERR, "gethostname");
1152 1156
1153 /* Here on error we should do exit(RV_SYS_ERROR), instead we do exit(EXIT_FAILURE) */ 1157 hostname[STRING_LENGTH - 1] = '\0';
1154 hostname[STRING_LENGTH - 1] = '\0';
1155 1158
1156 /* index_in_str_array returns i>=0 */ 1159 /* index_in_str_array returns i>=0 */
1157 i = index_in_str_array(field_names, variable); 1160 i = index_in_str_array(field_names, variable);
1158 1161
1159 if (i > 6 || i < 0 || (i > 1 && gv_info == NULL)) 1162 if (i > 6 || i < 0 || (i > 1 && gv_info == NULL))
1160 return NULL; 1163 return NULL;
1161 if (i >= 0 && i <= 3) { 1164 if (i >= 0 && i <= 3)
1162 return field_names[i + 7]; 1165 return field_names[i + 7];
1163 }
1164 1166
1165 if (i == 4) 1167 if (i == 4)
1166 sprintf(sbuf, "%u", gv_info->info->uid); 1168 sprintf(sbuf, "%u", gv_info->info->uid);
diff --git a/networking/arp.c b/networking/arp.c
index e529257a8..907433b4a 100644
--- a/networking/arp.c
+++ b/networking/arp.c
@@ -46,17 +46,15 @@ static int sockfd; /* active socket descriptor */
46static smallint hw_set; /* flag if hw-type was set (-H) */ 46static smallint hw_set; /* flag if hw-type was set (-H) */
47static const char *device = ""; /* current device */ 47static const char *device = ""; /* current device */
48 48
49static const char *const options[] = { 49static const char options[] =
50 "pub", 50 "pub\0"
51 "priv", 51 "priv\0"
52 "temp", 52 "temp\0"
53 "trail", 53 "trail\0"
54 "dontpub", 54 "dontpub\0"
55 "auto", 55 "auto\0"
56 "dev", 56 "dev\0"
57 "netmask", 57 "netmask\0";
58 NULL
59};
60 58
61/* Delete an entry from the ARP cache. */ 59/* Delete an entry from the ARP cache. */
62/* Called only from main, once */ 60/* Called only from main, once */
@@ -85,7 +83,7 @@ static int arp_del(char **args)
85 req.arp_flags = ATF_PERM; 83 req.arp_flags = ATF_PERM;
86 args++; 84 args++;
87 while (*args != NULL) { 85 while (*args != NULL) {
88 switch (index_in_str_array(options, *args)) { 86 switch (index_in_strings(options, *args)) {
89 case 0: /* "pub" */ 87 case 0: /* "pub" */
90 flags |= 1; 88 flags |= 1;
91 args++; 89 args++;
@@ -239,7 +237,7 @@ static int arp_set(char **args)
239 /* Check out any modifiers. */ 237 /* Check out any modifiers. */
240 flags = ATF_PERM | ATF_COM; 238 flags = ATF_PERM | ATF_COM;
241 while (*args != NULL) { 239 while (*args != NULL) {
242 switch (index_in_str_array(options, *args)) { 240 switch (index_in_strings(options, *args)) {
243 case 0: /* "pub" */ 241 case 0: /* "pub" */
244 flags |= ATF_PUBL; 242 flags |= ATF_PUBL;
245 args++; 243 args++;
diff --git a/networking/ftpgetput.c b/networking/ftpgetput.c
index 011fbac84..02e7c5270 100644
--- a/networking/ftpgetput.c
+++ b/networking/ftpgetput.c
@@ -293,7 +293,7 @@ static const char ftpgetput_longopts[] =
293 "username\0" Required_argument "u" 293 "username\0" Required_argument "u"
294 "password\0" Required_argument "p" 294 "password\0" Required_argument "p"
295 "port\0" Required_argument "P" 295 "port\0" Required_argument "P"
296 "\0"; 296 ;
297#endif 297#endif
298 298
299int ftpgetput_main(int argc, char **argv); 299int ftpgetput_main(int argc, char **argv);
diff --git a/networking/ip.c b/networking/ip.c
index 0105bd98b..bf7e84c53 100644
--- a/networking/ip.c
+++ b/networking/ip.c
@@ -82,14 +82,13 @@ int iptunnel_main(int argc, char **argv)
82int ip_main(int argc, char **argv); 82int ip_main(int argc, char **argv);
83int ip_main(int argc, char **argv) 83int ip_main(int argc, char **argv)
84{ 84{
85 const char * const keywords[] = { 85 static const char keywords[] =
86 USE_FEATURE_IP_ADDRESS("address",) 86 USE_FEATURE_IP_ADDRESS("address\0")
87 USE_FEATURE_IP_ROUTE("route",) 87 USE_FEATURE_IP_ROUTE("route\0")
88 USE_FEATURE_IP_LINK("link",) 88 USE_FEATURE_IP_LINK("link\0")
89 USE_FEATURE_IP_TUNNEL("tunnel", "tunl",) 89 USE_FEATURE_IP_TUNNEL("tunnel\0" "tunl\0")
90 USE_FEATURE_IP_RULE("rule",) 90 USE_FEATURE_IP_RULE("rule\0")
91 NULL 91 ;
92 };
93 enum { 92 enum {
94 USE_FEATURE_IP_ADDRESS(IP_addr,) 93 USE_FEATURE_IP_ADDRESS(IP_addr,)
95 USE_FEATURE_IP_ROUTE(IP_route,) 94 USE_FEATURE_IP_ROUTE(IP_route,)
@@ -101,7 +100,7 @@ int ip_main(int argc, char **argv)
101 100
102 ip_parse_common_args(&argc, &argv); 101 ip_parse_common_args(&argc, &argv);
103 if (argc > 1) { 102 if (argc > 1) {
104 int key = index_in_substr_array(keywords, argv[1]); 103 int key = index_in_substrings(keywords, argv[1]);
105 argc -= 2; 104 argc -= 2;
106 argv += 2; 105 argv += 2;
107#if ENABLE_FEATURE_IP_ADDRESS 106#if ENABLE_FEATURE_IP_ADDRESS
@@ -125,7 +124,7 @@ int ip_main(int argc, char **argv)
125 ip_func = do_iprule; 124 ip_func = do_iprule;
126#endif 125#endif
127 } 126 }
128 return (ip_func(argc, argv)); 127 return ip_func(argc, argv);
129} 128}
130 129
131#endif /* any of ENABLE_FEATURE_IP_xxx is 1 */ 130#endif /* any of ENABLE_FEATURE_IP_xxx is 1 */
diff --git a/networking/ipcalc.c b/networking/ipcalc.c
index 32b939f96..f3e3ad98f 100644
--- a/networking/ipcalc.c
+++ b/networking/ipcalc.c
@@ -72,7 +72,7 @@ int get_prefix(unsigned long netmask);
72 "hostname\0" No_argument "h" 72 "hostname\0" No_argument "h"
73 "silent\0" No_argument "s" 73 "silent\0" No_argument "s"
74# endif 74# endif
75 "\0"; 75 ;
76#endif 76#endif
77 77
78int ipcalc_main(int argc, char **argv); 78int ipcalc_main(int argc, char **argv);
diff --git a/networking/libiproute/ip_parse_common_args.c b/networking/libiproute/ip_parse_common_args.c
index 2d597ea3a..0e429a06f 100644
--- a/networking/libiproute/ip_parse_common_args.c
+++ b/networking/libiproute/ip_parse_common_args.c
@@ -26,9 +26,9 @@ void ip_parse_common_args(int *argcp, char ***argvp)
26{ 26{
27 int argc = *argcp; 27 int argc = *argcp;
28 char **argv = *argvp; 28 char **argv = *argvp;
29 static const char * const ip_common_commands[] = 29 static const char ip_common_commands[] =
30 {"-family", "inet", "inet6", "link", 30 "-family\0""inet\0""inet6\0""link\0"
31 "-4", "-6", "-0", "-oneline", 0}; 31 "-4\0""-6\0""-0\0""-oneline\0";
32 enum { 32 enum {
33 ARG_family = 1, 33 ARG_family = 1,
34 ARG_inet, 34 ARG_inet,
@@ -53,13 +53,13 @@ void ip_parse_common_args(int *argcp, char ***argvp)
53 break; 53 break;
54 if (opt[1] == '-') 54 if (opt[1] == '-')
55 opt++; 55 opt++;
56 arg = index_in_str_array(ip_common_commands, opt) + 1; 56 arg = index_in_strings(ip_common_commands, opt) + 1;
57 if (arg == ARG_family) { 57 if (arg == ARG_family) {
58 argc--; 58 argc--;
59 argv++; 59 argv++;
60 if (!argv[1]) 60 if (!argv[1])
61 bb_show_usage(); 61 bb_show_usage();
62 arg = index_in_str_array(ip_common_commands, argv[1]) + 1; 62 arg = index_in_strings(ip_common_commands, argv[1]) + 1;
63 if (arg == ARG_inet) 63 if (arg == ARG_inet)
64 preferred_family = AF_INET; 64 preferred_family = AF_INET;
65 else if (arg == ARG_inet6) 65 else if (arg == ARG_inet6)
diff --git a/networking/libiproute/ipaddress.c b/networking/libiproute/ipaddress.c
index 955a9d933..8874fdb0a 100644
--- a/networking/libiproute/ipaddress.c
+++ b/networking/libiproute/ipaddress.c
@@ -412,7 +412,7 @@ static void ipaddr_reset_filter(int _oneline)
412/* Return value becomes exitcode. It's okay to not return at all */ 412/* Return value becomes exitcode. It's okay to not return at all */
413int ipaddr_list_or_flush(int argc, char **argv, int flush) 413int ipaddr_list_or_flush(int argc, char **argv, int flush)
414{ 414{
415 static const char *const option[] = { "to", "scope", "up", "label", "dev", 0 }; 415 static const char option[] = "to\0""scope\0""up\0""label\0""dev\0";
416 416
417 struct nlmsg_list *linfo = NULL; 417 struct nlmsg_list *linfo = NULL;
418 struct nlmsg_list *ainfo = NULL; 418 struct nlmsg_list *ainfo = NULL;
@@ -437,7 +437,7 @@ int ipaddr_list_or_flush(int argc, char **argv, int flush)
437 } 437 }
438 438
439 while (argc > 0) { 439 while (argc > 0) {
440 const int option_num = index_in_str_array(option, *argv); 440 const int option_num = index_in_strings(option, *argv);
441 switch (option_num) { 441 switch (option_num) {
442 case 0: /* to */ 442 case 0: /* to */
443 NEXT_ARG(); 443 NEXT_ARG();
@@ -599,18 +599,17 @@ static int default_scope(inet_prefix *lcl)
599/* Return value becomes exitcode. It's okay to not return at all */ 599/* Return value becomes exitcode. It's okay to not return at all */
600static int ipaddr_modify(int cmd, int argc, char **argv) 600static int ipaddr_modify(int cmd, int argc, char **argv)
601{ 601{
602 static const char *const option[] = { 602 static const char option[] =
603 "peer", "remote", "broadcast", "brd", 603 "peer\0""remote\0""broadcast\0""brd\0"
604 "anycast", "scope", "dev", "label", "local", 0 604 "anycast\0""scope\0""dev\0""label\0""local\0";
605 };
606 struct rtnl_handle rth; 605 struct rtnl_handle rth;
607 struct { 606 struct {
608 struct nlmsghdr n; 607 struct nlmsghdr n;
609 struct ifaddrmsg ifa; 608 struct ifaddrmsg ifa;
610 char buf[256]; 609 char buf[256];
611 } req; 610 } req;
612 char *d = NULL; 611 char *d = NULL;
613 char *l = NULL; 612 char *l = NULL;
614 inet_prefix lcl; 613 inet_prefix lcl;
615 inet_prefix peer; 614 inet_prefix peer;
616 int local_len = 0; 615 int local_len = 0;
@@ -627,7 +626,7 @@ static int ipaddr_modify(int cmd, int argc, char **argv)
627 req.ifa.ifa_family = preferred_family; 626 req.ifa.ifa_family = preferred_family;
628 627
629 while (argc > 0) { 628 while (argc > 0) {
630 const int option_num = index_in_str_array(option, *argv); 629 const int option_num = index_in_strings(option, *argv);
631 switch (option_num) { 630 switch (option_num) {
632 case 0: /* peer */ 631 case 0: /* peer */
633 case 1: /* remote */ 632 case 1: /* remote */
@@ -769,14 +768,13 @@ static int ipaddr_modify(int cmd, int argc, char **argv)
769/* Return value becomes exitcode. It's okay to not return at all */ 768/* Return value becomes exitcode. It's okay to not return at all */
770int do_ipaddr(int argc, char **argv) 769int do_ipaddr(int argc, char **argv)
771{ 770{
772 static const char *const commands[] = { 771 static const char commands[] =
773 "add", "delete", "list", "show", "lst", "flush", 0 772 "add\0""delete\0""list\0""show\0""lst\0""flush\0";
774 };
775 773
776 int command_num = 2; /* default command is list */ 774 int command_num = 2; /* default command is list */
777 775
778 if (*argv) { 776 if (*argv) {
779 command_num = index_in_substr_array(commands, *argv); 777 command_num = index_in_substrings(commands, *argv);
780 } 778 }
781 if (command_num < 0 || command_num > 5) 779 if (command_num < 0 || command_num > 5)
782 bb_error_msg_and_die("unknown command %s", *argv); 780 bb_error_msg_and_die("unknown command %s", *argv);
diff --git a/networking/libiproute/iplink.c b/networking/libiproute/iplink.c
index 3d3ea2a23..69ce84e49 100644
--- a/networking/libiproute/iplink.c
+++ b/networking/libiproute/iplink.c
@@ -171,16 +171,15 @@ static int do_set(int argc, char **argv)
171 struct ifreq ifr0, ifr1; 171 struct ifreq ifr0, ifr1;
172 char *newname = NULL; 172 char *newname = NULL;
173 int htype, halen; 173 int htype, halen;
174 static const char * const keywords[] = { 174 static const char keywords[] =
175 "up", "down", "name", "mtu", "multicast", "arp", "addr", "dev", 175 "up\0""down\0""name\0""mtu\0""multicast\0""arp\0""addr\0""dev\0"
176 "on", "off", NULL 176 "on\0""off\0";
177 };
178 enum { ARG_up = 1, ARG_down, ARG_name, ARG_mtu, ARG_multicast, ARG_arp, 177 enum { ARG_up = 1, ARG_down, ARG_name, ARG_mtu, ARG_multicast, ARG_arp,
179 ARG_addr, ARG_dev, PARM_on, PARM_off }; 178 ARG_addr, ARG_dev, PARM_on, PARM_off };
180 smalluint key; 179 smalluint key;
181 180
182 while (argc > 0) { 181 while (argc > 0) {
183 key = index_in_str_array(keywords, *argv) + 1; 182 key = index_in_strings(keywords, *argv) + 1;
184 if (key == ARG_up) { 183 if (key == ARG_up) {
185 mask |= IFF_UP; 184 mask |= IFF_UP;
186 flags |= IFF_UP; 185 flags |= IFF_UP;
@@ -199,7 +198,7 @@ static int do_set(int argc, char **argv)
199 } else if (key == ARG_multicast) { 198 } else if (key == ARG_multicast) {
200 NEXT_ARG(); 199 NEXT_ARG();
201 mask |= IFF_MULTICAST; 200 mask |= IFF_MULTICAST;
202 key = index_in_str_array(keywords, *argv) + 1; 201 key = index_in_strings(keywords, *argv) + 1;
203 if (key == PARM_on) { 202 if (key == PARM_on) {
204 flags |= IFF_MULTICAST; 203 flags |= IFF_MULTICAST;
205 } else if (key == PARM_off) { 204 } else if (key == PARM_off) {
@@ -209,7 +208,7 @@ static int do_set(int argc, char **argv)
209 } else if (key == ARG_arp) { 208 } else if (key == ARG_arp) {
210 NEXT_ARG(); 209 NEXT_ARG();
211 mask |= IFF_NOARP; 210 mask |= IFF_NOARP;
212 key = index_in_str_array(keywords, *argv) + 1; 211 key = index_in_strings(keywords, *argv) + 1;
213 if (key == PARM_on) { 212 if (key == PARM_on) {
214 flags &= ~IFF_NOARP; 213 flags &= ~IFF_NOARP;
215 } else if (key == PARM_off) { 214 } else if (key == PARM_off) {
@@ -276,13 +275,12 @@ static int ipaddr_list_link(int argc, char **argv)
276/* Return value becomes exitcode. It's okay to not return at all */ 275/* Return value becomes exitcode. It's okay to not return at all */
277int do_iplink(int argc, char **argv) 276int do_iplink(int argc, char **argv)
278{ 277{
279 static const char * const keywords[] = { 278 static const char keywords[] =
280 "set", "show", "lst", "list", NULL 279 "set\0""show\0""lst\0""list\0";
281 };
282 smalluint key; 280 smalluint key;
283 if (argc <= 0) 281 if (argc <= 0)
284 return ipaddr_list_link(0, NULL); 282 return ipaddr_list_link(0, NULL);
285 key = index_in_substr_array(keywords, *argv) + 1; 283 key = index_in_substrings(keywords, *argv) + 1;
286 if (key == 0) 284 if (key == 0)
287 bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name); 285 bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name);
288 argc--; argv++; 286 argc--; argv++;
diff --git a/networking/libiproute/iproute.c b/networking/libiproute/iproute.c
index 75e52939c..0d171c785 100644
--- a/networking/libiproute/iproute.c
+++ b/networking/libiproute/iproute.c
@@ -294,6 +294,25 @@ static int print_route(struct sockaddr_nl *who ATTRIBUTE_UNUSED,
294/* Return value becomes exitcode. It's okay to not return at all */ 294/* Return value becomes exitcode. It's okay to not return at all */
295static int iproute_modify(int cmd, unsigned flags, int argc, char **argv) 295static int iproute_modify(int cmd, unsigned flags, int argc, char **argv)
296{ 296{
297 static const char keywords[] =
298 "src\0""via\0""mtu\0""lock\0""protocol\0"USE_FEATURE_IP_RULE("table\0")
299 "dev\0""oif\0""to\0";
300 enum {
301 ARG_src,
302 ARG_via,
303 ARG_mtu, PARM_lock,
304 ARG_protocol,
305USE_FEATURE_IP_RULE(ARG_table,)
306 ARG_dev,
307 ARG_oif,
308 ARG_to
309 };
310 enum {
311 gw_ok = 1 << 0,
312 dst_ok = 1 << 1,
313 proto_ok = 1 << 2,
314 type_ok = 1 << 3
315 };
297 struct rtnl_handle rth; 316 struct rtnl_handle rth;
298 struct { 317 struct {
299 struct nlmsghdr n; 318 struct nlmsghdr n;
@@ -304,22 +323,7 @@ static int iproute_modify(int cmd, unsigned flags, int argc, char **argv)
304 struct rtattr * mxrta = (void*)mxbuf; 323 struct rtattr * mxrta = (void*)mxbuf;
305 unsigned mxlock = 0; 324 unsigned mxlock = 0;
306 char *d = NULL; 325 char *d = NULL;
307 enum { gw_ok = 1<<0, dst_ok = 1<<1, proto_ok = 1<<2, type_ok = 1<<3};
308 smalluint ok = 0; 326 smalluint ok = 0;
309 static const char * const keywords[] = {
310 "src", "via", "mtu", "lock", "protocol", USE_FEATURE_IP_RULE("table",)
311 "dev", "oif", "to", NULL
312 };
313 enum {
314 ARG_src,
315 ARG_via,
316 ARG_mtu, PARM_lock,
317 ARG_protocol,
318USE_FEATURE_IP_RULE(ARG_table,)
319 ARG_dev,
320 ARG_oif,
321 ARG_to
322 };
323 int arg; 327 int arg;
324 328
325 memset(&req, 0, sizeof(req)); 329 memset(&req, 0, sizeof(req));
@@ -341,7 +345,7 @@ USE_FEATURE_IP_RULE(ARG_table,)
341 mxrta->rta_len = RTA_LENGTH(0); 345 mxrta->rta_len = RTA_LENGTH(0);
342 346
343 while (argc > 0) { 347 while (argc > 0) {
344 arg = index_in_substr_array(keywords, *argv); 348 arg = index_in_substrings(keywords, *argv);
345 if (arg == ARG_src) { 349 if (arg == ARG_src) {
346 inet_prefix addr; 350 inet_prefix addr;
347 NEXT_ARG(); 351 NEXT_ARG();
@@ -361,7 +365,7 @@ USE_FEATURE_IP_RULE(ARG_table,)
361 } else if (arg == ARG_mtu) { 365 } else if (arg == ARG_mtu) {
362 unsigned mtu; 366 unsigned mtu;
363 NEXT_ARG(); 367 NEXT_ARG();
364 if (index_in_str_array(keywords, *argv) == PARM_lock) { 368 if (index_in_strings(keywords, *argv) == PARM_lock) {
365 mxlock |= (1<<RTAX_MTU); 369 mxlock |= (1<<RTAX_MTU);
366 NEXT_ARG(); 370 NEXT_ARG();
367 } 371 }
@@ -513,10 +517,9 @@ static int iproute_list_or_flush(int argc, char **argv, int flush)
513 struct rtnl_handle rth; 517 struct rtnl_handle rth;
514 char *id = NULL; 518 char *id = NULL;
515 char *od = NULL; 519 char *od = NULL;
516 static const char * const keywords[] = { 520 static const char keywords[] =
517 "protocol", "all", "dev", "oif", "iif", "via", "table", "cache",/*all,*/ 521 "protocol\0""all\0""dev\0""oif\0""iif\0""via\0""table\0""cache\0" /*all*/
518 "from", "root", "match", "exact", "to", /*root,match,exact*/ NULL 522 "from\0""root\0""match\0""exact\0""to\0"/*root match exact*/;
519 };
520 enum { 523 enum {
521 ARG_proto, PARM_all, 524 ARG_proto, PARM_all,
522 ARG_dev, 525 ARG_dev,
@@ -535,13 +538,13 @@ static int iproute_list_or_flush(int argc, char **argv, int flush)
535 bb_error_msg_and_die(bb_msg_requires_arg, "\"ip route flush\""); 538 bb_error_msg_and_die(bb_msg_requires_arg, "\"ip route flush\"");
536 539
537 while (argc > 0) { 540 while (argc > 0) {
538 arg = index_in_substr_array(keywords, *argv); 541 arg = index_in_substrings(keywords, *argv);
539 if (arg == ARG_proto) { 542 if (arg == ARG_proto) {
540 uint32_t prot = 0; 543 uint32_t prot = 0;
541 NEXT_ARG(); 544 NEXT_ARG();
542 filter.protocolmask = -1; 545 filter.protocolmask = -1;
543 if (rtnl_rtprot_a2n(&prot, *argv)) { 546 if (rtnl_rtprot_a2n(&prot, *argv)) {
544 if (index_in_str_array(keywords, *argv) != PARM_all) 547 if (index_in_strings(keywords, *argv) != PARM_all)
545 invarg(*argv, "protocol"); 548 invarg(*argv, "protocol");
546 prot = 0; 549 prot = 0;
547 filter.protocolmask = 0; 550 filter.protocolmask = 0;
@@ -558,7 +561,7 @@ static int iproute_list_or_flush(int argc, char **argv, int flush)
558 get_prefix(&filter.rvia, *argv, do_ipv6); 561 get_prefix(&filter.rvia, *argv, do_ipv6);
559 } else if (arg == ARG_table) { 562 } else if (arg == ARG_table) {
560 NEXT_ARG(); 563 NEXT_ARG();
561 parm = index_in_substr_array(keywords, *argv); 564 parm = index_in_substrings(keywords, *argv);
562 if (parm == PARM_cache) 565 if (parm == PARM_cache)
563 filter.tb = -1; 566 filter.tb = -1;
564 else if (parm == PARM_all) 567 else if (parm == PARM_all)
@@ -567,7 +570,7 @@ static int iproute_list_or_flush(int argc, char **argv, int flush)
567 invarg(*argv, "table"); 570 invarg(*argv, "table");
568 } else if (arg == ARG_from) { 571 } else if (arg == ARG_from) {
569 NEXT_ARG(); 572 NEXT_ARG();
570 parm = index_in_substr_array(keywords, *argv); 573 parm = index_in_substrings(keywords, *argv);
571 if (parm == PARM_root) { 574 if (parm == PARM_root) {
572 NEXT_ARG(); 575 NEXT_ARG();
573 get_prefix(&filter.rsrc, *argv, do_ipv6); 576 get_prefix(&filter.rsrc, *argv, do_ipv6);
@@ -584,7 +587,7 @@ static int iproute_list_or_flush(int argc, char **argv, int flush)
584 /* parm = arg; // would be more plausible, we reuse arg here */ 587 /* parm = arg; // would be more plausible, we reuse arg here */
585 if (arg == ARG_to) { 588 if (arg == ARG_to) {
586 NEXT_ARG(); 589 NEXT_ARG();
587 arg = index_in_substr_array(keywords, *argv); 590 arg = index_in_substrings(keywords, *argv);
588 } 591 }
589 if (arg == PARM_root) { 592 if (arg == PARM_root) {
590 NEXT_ARG(); 593 NEXT_ARG();
@@ -645,9 +648,8 @@ static int iproute_list_or_flush(int argc, char **argv, int flush)
645 xrtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE); 648 xrtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE);
646 filter.flushed = 0; 649 filter.flushed = 0;
647 xrtnl_dump_filter(&rth, print_route, stdout); 650 xrtnl_dump_filter(&rth, print_route, stdout);
648 if (filter.flushed == 0) { 651 if (filter.flushed == 0)
649 return 0; 652 return 0;
650 }
651 if (flush_update()) 653 if (flush_update())
652 return 1; 654 return 1;
653 } 655 }
@@ -655,10 +657,8 @@ static int iproute_list_or_flush(int argc, char **argv, int flush)
655 657
656 if (filter.tb != -1) { 658 if (filter.tb != -1) {
657 xrtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE); 659 xrtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE);
658 } else { 660 } else if (rtnl_rtcache_request(&rth, do_ipv6) < 0) {
659 if (rtnl_rtcache_request(&rth, do_ipv6) < 0) { 661 bb_perror_msg_and_die("cannot send dump request");
660 bb_perror_msg_and_die("cannot send dump request");
661 }
662 } 662 }
663 xrtnl_dump_filter(&rth, print_route, stdout); 663 xrtnl_dump_filter(&rth, print_route, stdout);
664 664
@@ -671,16 +671,16 @@ static int iproute_get(int argc, char **argv)
671{ 671{
672 struct rtnl_handle rth; 672 struct rtnl_handle rth;
673 struct { 673 struct {
674 struct nlmsghdr n; 674 struct nlmsghdr n;
675 struct rtmsg r; 675 struct rtmsg r;
676 char buf[1024]; 676 char buf[1024];
677 } req; 677 } req;
678 char *idev = NULL; 678 char *idev = NULL;
679 char *odev = NULL; 679 char *odev = NULL;
680 bool connected = 0; 680 bool connected = 0;
681 bool from_ok = 0; 681 bool from_ok = 0;
682 static const char * const options[] = 682 static const char options[] =
683 { "from", "iif", "oif", "dev", "notify", "connected", "to", 0 }; 683 "from\0""iif\0""oif\0""dev\0""notify\0""connected\0""to\0";
684 684
685 memset(&req, 0, sizeof(req)); 685 memset(&req, 0, sizeof(req));
686 686
@@ -699,7 +699,7 @@ static int iproute_get(int argc, char **argv)
699 req.r.rtm_tos = 0; 699 req.r.rtm_tos = 0;
700 700
701 while (argc > 0) { 701 while (argc > 0) {
702 switch (index_in_str_array(options, *argv)) { 702 switch (index_in_strings(options, *argv)) {
703 case 0: /* from */ 703 case 0: /* from */
704 { 704 {
705 inet_prefix addr; 705 inet_prefix addr;
@@ -824,19 +824,18 @@ static int iproute_get(int argc, char **argv)
824/* Return value becomes exitcode. It's okay to not return at all */ 824/* Return value becomes exitcode. It's okay to not return at all */
825int do_iproute(int argc, char **argv) 825int do_iproute(int argc, char **argv)
826{ 826{
827 static const char * const ip_route_commands[] = { 827 static const char ip_route_commands[] =
828 /*0-3*/ "add", "append", "change", "chg", 828 /*0-3*/ "add\0""append\0""change\0""chg\0"
829 /*4-7*/ "delete", "get", "list", "show", 829 /*4-7*/ "delete\0""get\0""list\0""show\0"
830 /*8..*/ "prepend", "replace", "test", "flush", 0 830 /*8..*/ "prepend\0""replace\0""test\0""flush\0";
831 };
832 int command_num = 6; 831 int command_num = 6;
833 unsigned int flags = 0; 832 unsigned flags = 0;
834 int cmd = RTM_NEWROUTE; 833 int cmd = RTM_NEWROUTE;
835 834
836 /* "Standard" 'ip r a' treats 'a' as 'add', not 'append' */ 835 /* "Standard" 'ip r a' treats 'a' as 'add', not 'append' */
837 /* It probably means that it is using "first match" rule */ 836 /* It probably means that it is using "first match" rule */
838 if (*argv) { 837 if (*argv) {
839 command_num = index_in_substr_array(ip_route_commands, *argv); 838 command_num = index_in_substrings(ip_route_commands, *argv);
840 } 839 }
841 switch (command_num) { 840 switch (command_num) {
842 case 0: /* add */ 841 case 0: /* add */
diff --git a/networking/libiproute/iprule.c b/networking/libiproute/iprule.c
index a62eae1fe..8e2a06f4f 100644
--- a/networking/libiproute/iprule.c
+++ b/networking/libiproute/iprule.c
@@ -187,6 +187,15 @@ static int iprule_list(int argc, char **argv)
187/* Return value becomes exitcode. It's okay to not return at all */ 187/* Return value becomes exitcode. It's okay to not return at all */
188static int iprule_modify(int cmd, int argc, char **argv) 188static int iprule_modify(int cmd, int argc, char **argv)
189{ 189{
190 static const char keywords[] =
191 "from\0""to\0""preference\0""order\0""priority\0"
192 "tos\0""fwmark\0""realms\0""table\0""lookup\0""dev\0"
193 "iif\0""nat\0""map-to\0""type\0""help\0";
194 enum {
195 ARG_from = 1, ARG_to, ARG_preference, ARG_order, ARG_priority,
196 ARG_tos, ARG_fwmark, ARG_realms, ARG_table, ARG_lookup, ARG_dev,
197 ARG_iif, ARG_nat, ARG_map_to, ARG_type, ARG_help
198 };
190 bool table_ok = 0; 199 bool table_ok = 0;
191 struct rtnl_handle rth; 200 struct rtnl_handle rth;
192 struct { 201 struct {
@@ -194,13 +203,6 @@ static int iprule_modify(int cmd, int argc, char **argv)
194 struct rtmsg r; 203 struct rtmsg r;
195 char buf[1024]; 204 char buf[1024];
196 } req; 205 } req;
197 static const char * const keywords[] =
198 { "from", "to", "preference", "order", "priority", "tos", "fwmark",
199 "realms", "table", "lookup", "dev", "iif", "nat", "map-to", "type",
200 "help", NULL};
201 enum { ARG_from = 1, ARG_to, ARG_preference, ARG_order, ARG_priority,
202 ARG_tos, ARG_fwmark, ARG_realms, ARG_table, ARG_lookup, ARG_dev,
203 ARG_iif, ARG_nat, ARG_map_to, ARG_type, ARG_help };
204 smalluint key; 206 smalluint key;
205 207
206 memset(&req, 0, sizeof(req)); 208 memset(&req, 0, sizeof(req));
@@ -220,7 +222,7 @@ static int iprule_modify(int cmd, int argc, char **argv)
220 } 222 }
221 223
222 while (argc > 0) { 224 while (argc > 0) {
223 key = index_in_substr_array(keywords, *argv) + 1; 225 key = index_in_substrings(keywords, *argv) + 1;
224 if (key == 0) /* no match found in keywords array, bail out. */ 226 if (key == 0) /* no match found in keywords array, bail out. */
225 bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name); 227 bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name);
226 if (key == ARG_from) { 228 if (key == ARG_from) {
@@ -311,14 +313,14 @@ static int iprule_modify(int cmd, int argc, char **argv)
311/* Return value becomes exitcode. It's okay to not return at all */ 313/* Return value becomes exitcode. It's okay to not return at all */
312int do_iprule(int argc, char **argv) 314int do_iprule(int argc, char **argv)
313{ 315{
314 static const char * const ip_rule_commands[] = 316 static const char ip_rule_commands[] =
315 {"add", "delete", "list", "show", 0}; 317 "add\0""delete\0""list\0""show\0";
316 int cmd = 2; /* list */ 318 int cmd = 2; /* list */
317 319
318 if (argc < 1) 320 if (argc < 1)
319 return iprule_list(0, NULL); 321 return iprule_list(0, NULL);
320 if (*argv) 322 if (*argv)
321 cmd = index_in_substr_array(ip_rule_commands, *argv); 323 cmd = index_in_substrings(ip_rule_commands, *argv);
322 324
323 switch (cmd) { 325 switch (cmd) {
324 case 0: /* add */ 326 case 0: /* add */
diff --git a/networking/libiproute/iptunnel.c b/networking/libiproute/iptunnel.c
index 90d0e1186..a2933879c 100644
--- a/networking/libiproute/iptunnel.c
+++ b/networking/libiproute/iptunnel.c
@@ -128,16 +128,13 @@ static int do_del_ioctl(const char *basedev, struct ip_tunnel_parm *p)
128/* Dies on error */ 128/* Dies on error */
129static void parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p) 129static void parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p)
130{ 130{
131 int count = 0; 131 static const char keywords[] =
132 char medium[IFNAMSIZ]; 132 "mode\0""ipip\0""ip/ip\0""gre\0""gre/ip\0""sit\0""ipv6/ip\0"
133 static const char * const keywords[] = { 133 "key\0""ikey\0""okey\0""seq\0""iseq\0""oseq\0"
134 "mode", "ipip", "ip/ip", "gre", "gre/ip", "sit", "ipv6/ip", 134 "csum\0""icsum\0""ocsum\0""nopmtudisc\0""pmtudisc\0"
135 "key", "ikey", "okey", "seq", "iseq", "oseq", 135 "remote\0""any\0""local\0""dev\0"
136 "csum", "icsum", "ocsum", "nopmtudisc", "pmtudisc", 136 "ttl\0""inherit\0""tos\0""dsfield\0"
137 "remote", "any", "local", "dev", 137 "name\0";
138 "ttl", "inherit", "tos", "dsfield",
139 "name", NULL
140 };
141 enum { 138 enum {
142 ARG_mode, ARG_ipip, ARG_ip_ip, ARG_gre, ARG_gre_ip, ARG_sit, ARG_ip6_ip, 139 ARG_mode, ARG_ipip, ARG_ip_ip, ARG_gre, ARG_gre_ip, ARG_sit, ARG_ip6_ip,
143 ARG_key, ARG_ikey, ARG_okey, ARG_seq, ARG_iseq, ARG_oseq, 140 ARG_key, ARG_ikey, ARG_okey, ARG_seq, ARG_iseq, ARG_oseq,
@@ -146,22 +143,25 @@ static void parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p)
146 ARG_ttl, ARG_inherit, ARG_tos, ARG_dsfield, 143 ARG_ttl, ARG_inherit, ARG_tos, ARG_dsfield,
147 ARG_name 144 ARG_name
148 }; 145 };
146 int count = 0;
147 char medium[IFNAMSIZ];
149 int key; 148 int key;
149
150 memset(p, 0, sizeof(*p)); 150 memset(p, 0, sizeof(*p));
151 memset(&medium, 0, sizeof(medium)); 151 memset(&medium, 0, sizeof(medium));
152 152
153 p->iph.version = 4; 153 p->iph.version = 4;
154 p->iph.ihl = 5; 154 p->iph.ihl = 5;
155#ifndef IP_DF 155#ifndef IP_DF
156#define IP_DF 0x4000 /* Flag: "Don't Fragment" */ 156#define IP_DF 0x4000 /* Flag: "Don't Fragment" */
157#endif 157#endif
158 p->iph.frag_off = htons(IP_DF); 158 p->iph.frag_off = htons(IP_DF);
159 159
160 while (argc > 0) { 160 while (argc > 0) {
161 key = index_in_str_array(keywords, *argv); 161 key = index_in_strings(keywords, *argv);
162 if (key == ARG_mode) { 162 if (key == ARG_mode) {
163 NEXT_ARG(); 163 NEXT_ARG();
164 key = index_in_str_array(keywords, *argv); 164 key = index_in_strings(keywords, *argv);
165 if (key == ARG_ipip || 165 if (key == ARG_ipip ||
166 key == ARG_ip_ip) { 166 key == ARG_ip_ip) {
167 if (p->iph.protocol && p->iph.protocol != IPPROTO_IPIP) { 167 if (p->iph.protocol && p->iph.protocol != IPPROTO_IPIP) {
@@ -240,12 +240,12 @@ static void parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p)
240 p->iph.frag_off = htons(IP_DF); 240 p->iph.frag_off = htons(IP_DF);
241 } else if (key == ARG_remote) { 241 } else if (key == ARG_remote) {
242 NEXT_ARG(); 242 NEXT_ARG();
243 key = index_in_str_array(keywords, *argv); 243 key = index_in_strings(keywords, *argv);
244 if (key == ARG_any) 244 if (key == ARG_any)
245 p->iph.daddr = get_addr32(*argv); 245 p->iph.daddr = get_addr32(*argv);
246 } else if (key == ARG_local) { 246 } else if (key == ARG_local) {
247 NEXT_ARG(); 247 NEXT_ARG();
248 key = index_in_str_array(keywords, *argv); 248 key = index_in_strings(keywords, *argv);
249 if (key == ARG_any) 249 if (key == ARG_any)
250 p->iph.saddr = get_addr32(*argv); 250 p->iph.saddr = get_addr32(*argv);
251 } else if (key == ARG_dev) { 251 } else if (key == ARG_dev) {
@@ -254,7 +254,7 @@ static void parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p)
254 } else if (key == ARG_ttl) { 254 } else if (key == ARG_ttl) {
255 unsigned uval; 255 unsigned uval;
256 NEXT_ARG(); 256 NEXT_ARG();
257 key = index_in_str_array(keywords, *argv); 257 key = index_in_strings(keywords, *argv);
258 if (key != ARG_inherit) { 258 if (key != ARG_inherit) {
259 if (get_unsigned(&uval, *argv, 0)) 259 if (get_unsigned(&uval, *argv, 0))
260 invarg(*argv, "TTL"); 260 invarg(*argv, "TTL");
@@ -266,7 +266,7 @@ static void parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p)
266 key == ARG_dsfield) { 266 key == ARG_dsfield) {
267 uint32_t uval; 267 uint32_t uval;
268 NEXT_ARG(); 268 NEXT_ARG();
269 key = index_in_str_array(keywords, *argv); 269 key = index_in_strings(keywords, *argv);
270 if (key != ARG_inherit) { 270 if (key != ARG_inherit) {
271 if (rtnl_dsfield_a2n(&uval, *argv)) 271 if (rtnl_dsfield_a2n(&uval, *argv))
272 invarg(*argv, "TOS"); 272 invarg(*argv, "TOS");
@@ -519,14 +519,13 @@ static int do_show(int argc, char **argv)
519/* Return value becomes exitcode. It's okay to not return at all */ 519/* Return value becomes exitcode. It's okay to not return at all */
520int do_iptunnel(int argc, char **argv) 520int do_iptunnel(int argc, char **argv)
521{ 521{
522 static const char *const keywords[] = { 522 static const char keywords[] =
523 "add", "change", "delete", "show", "list", "lst", NULL 523 "add\0""change\0""delete\0""show\0""list\0""lst\0";
524 };
525 enum { ARG_add = 0, ARG_change, ARG_del, ARG_show, ARG_list, ARG_lst }; 524 enum { ARG_add = 0, ARG_change, ARG_del, ARG_show, ARG_list, ARG_lst };
526 int key; 525 int key;
527 526
528 if (argc) { 527 if (argc) {
529 key = index_in_substr_array(keywords, *argv); 528 key = index_in_substrings(keywords, *argv);
530 if (key < 0) 529 if (key < 0)
531 bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name); 530 bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name);
532 --argc; 531 --argc;
diff --git a/networking/libiproute/rtm_map.c b/networking/libiproute/rtm_map.c
index 593017bf1..96b2d1791 100644
--- a/networking/libiproute/rtm_map.c
+++ b/networking/libiproute/rtm_map.c
@@ -51,16 +51,16 @@ const char *rtnl_rtntype_n2a(int id, char *buf, int len)
51 51
52int rtnl_rtntype_a2n(int *id, char *arg) 52int rtnl_rtntype_a2n(int *id, char *arg)
53{ 53{
54 static const char * const keywords[] = { 54 static const char keywords[] =
55 "local", "nat", "broadcast", "brd", "anycast", 55 "local\0""nat\0""broadcast\0""brd\0""anycast\0"
56 "multicast", "prohibit", "unreachable", "blackhole", 56 "multicast\0""prohibit\0""unreachable\0""blackhole\0"
57 "xresolve", "unicast", "throw", NULL 57 "xresolve\0""unicast\0""throw\0";
58 }; 58 enum {
59 enum { ARG_local = 1, ARG_nat, ARG_broadcast, ARG_brd, ARG_anycast, 59 ARG_local = 1, ARG_nat, ARG_broadcast, ARG_brd, ARG_anycast,
60 ARG_multicast, ARG_prohibit, ARG_unreachable, ARG_blackhole, 60 ARG_multicast, ARG_prohibit, ARG_unreachable, ARG_blackhole,
61 ARG_xresolve, ARG_unicast, ARG_throw 61 ARG_xresolve, ARG_unicast, ARG_throw
62 }; 62 };
63 const smalluint key = index_in_substr_array(keywords, arg) + 1; 63 const smalluint key = index_in_substrings(keywords, arg) + 1;
64 char *end; 64 char *end;
65 unsigned long res; 65 unsigned long res;
66 66
diff --git a/networking/slattach.c b/networking/slattach.c
index 1a4423b72..4bac879d2 100644
--- a/networking/slattach.c
+++ b/networking/slattach.c
@@ -16,16 +16,6 @@
16#include "libbb.h" 16#include "libbb.h"
17#include "libiproute/utils.h" /* invarg() */ 17#include "libiproute/utils.h" /* invarg() */
18 18
19/* Line discipline code table */
20static const char *const proto_names[] = {
21 "cslip"+1, /* 0 */
22 "cslip", /* 1 */
23 "cslip6"+1, /* 2 */
24 "cslip6", /* 3 */
25 "adaptive", /* 8 */
26 NULL
27};
28
29struct globals { 19struct globals {
30 int handle; 20 int handle;
31 int saved_disc; 21 int saved_disc;
@@ -132,6 +122,15 @@ static void sig_handler(int signo)
132int slattach_main(int argc, char **argv); 122int slattach_main(int argc, char **argv);
133int slattach_main(int argc, char **argv) 123int slattach_main(int argc, char **argv)
134{ 124{
125 /* Line discipline code table */
126 static const char proto_names[] =
127 "slip\0" /* 0 */
128 "cslip\0" /* 1 */
129 "slip6\0" /* 2 */
130 "cslip6\0" /* 3 */
131 "adaptive\0" /* 8 */
132 ;
133
135 int i, encap, opt; 134 int i, encap, opt;
136 struct termios state; 135 struct termios state;
137 const char *proto = "cslip"; 136 const char *proto = "cslip";
@@ -160,7 +159,7 @@ int slattach_main(int argc, char **argv)
160 if (!*argv) 159 if (!*argv)
161 bb_show_usage(); 160 bb_show_usage();
162 161
163 encap = index_in_str_array(proto_names, proto); 162 encap = index_in_strings(proto_names, proto);
164 163
165 if (encap < 0) 164 if (encap < 0)
166 invarg(proto, "protocol"); 165 invarg(proto, "protocol");
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c
index 2b95c3250..b84a6785a 100644
--- a/networking/udhcp/dhcpc.c
+++ b/networking/udhcp/dhcpc.c
@@ -200,7 +200,7 @@ int udhcpc_main(int argc, char **argv)
200 "timeout\0" Required_argument "T" 200 "timeout\0" Required_argument "T"
201 "version\0" No_argument "v" 201 "version\0" No_argument "v"
202 "retries\0" Required_argument "t" 202 "retries\0" Required_argument "t"
203 "\0"; 203 ;
204#endif 204#endif
205 /* Default options. */ 205 /* Default options. */
206 client_config.interface = "eth0"; 206 client_config.interface = "eth0";
diff --git a/networking/udhcp/dumpleases.c b/networking/udhcp/dumpleases.c
index fb50d6888..f9f923124 100644
--- a/networking/udhcp/dumpleases.c
+++ b/networking/udhcp/dumpleases.c
@@ -28,7 +28,7 @@ int dumpleases_main(int argc, char **argv)
28 "absolute\0" No_argument "a" 28 "absolute\0" No_argument "a"
29 "remaining\0" No_argument "r" 29 "remaining\0" No_argument "r"
30 "file\0" Required_argument "f" 30 "file\0" Required_argument "f"
31 "\0"; 31 ;
32 32
33 applet_long_options = dumpleases_longopts; 33 applet_long_options = dumpleases_longopts;
34#endif 34#endif
diff --git a/networking/wget.c b/networking/wget.c
index ad09091d3..d944f0173 100644
--- a/networking/wget.c
+++ b/networking/wget.c
@@ -114,9 +114,8 @@ int wget_main(int argc, char **argv)
114 bool use_proxy = 1; /* Use proxies if env vars are set */ 114 bool use_proxy = 1; /* Use proxies if env vars are set */
115 const char *proxy_flag = "on"; /* Use proxies if env vars are set */ 115 const char *proxy_flag = "on"; /* Use proxies if env vars are set */
116 const char *user_agent = "Wget";/* "User-Agent" header field */ 116 const char *user_agent = "Wget";/* "User-Agent" header field */
117 static const char * const keywords[] = { 117 static const char keywords[] =
118 "content-length", "transfer-encoding", "chunked", "location", NULL 118 "content-length\0""transfer-encoding\0""chunked\0""location\0";
119 };
120 enum { 119 enum {
121 KEY_content_length = 1, KEY_transfer_encoding, KEY_chunked, KEY_location 120 KEY_content_length = 1, KEY_transfer_encoding, KEY_chunked, KEY_location
122 }; 121 };
@@ -143,7 +142,7 @@ int wget_main(int argc, char **argv)
143 "user-agent\0" Required_argument "U" 142 "user-agent\0" Required_argument "U"
144 "passive-ftp\0" No_argument "\xff" 143 "passive-ftp\0" No_argument "\xff"
145 "header\0" Required_argument "\xfe" 144 "header\0" Required_argument "\xfe"
146 "\0"; 145 ;
147 applet_long_options = wget_longopts; 146 applet_long_options = wget_longopts;
148#endif 147#endif
149 /* server.allocated = target.allocated = NULL; */ 148 /* server.allocated = target.allocated = NULL; */
@@ -327,7 +326,7 @@ int wget_main(int argc, char **argv)
327 */ 326 */
328 while ((str = gethdr(buf, sizeof(buf), sfp, &n)) != NULL) { 327 while ((str = gethdr(buf, sizeof(buf), sfp, &n)) != NULL) {
329 /* gethdr did already convert the "FOO:" string to lowercase */ 328 /* gethdr did already convert the "FOO:" string to lowercase */
330 smalluint key = index_in_str_array(keywords, *&buf) + 1; 329 smalluint key = index_in_strings(keywords, *&buf) + 1;
331 if (key == KEY_content_length) { 330 if (key == KEY_content_length) {
332 content_len = BB_STRTOOFF(str, NULL, 10); 331 content_len = BB_STRTOOFF(str, NULL, 10);
333 if (errno || content_len < 0) { 332 if (errno || content_len < 0) {
@@ -337,7 +336,7 @@ int wget_main(int argc, char **argv)
337 continue; 336 continue;
338 } 337 }
339 if (key == KEY_transfer_encoding) { 338 if (key == KEY_transfer_encoding) {
340 if (index_in_str_array(keywords, str_tolower(str)) + 1 != KEY_chunked) 339 if (index_in_strings(keywords, str_tolower(str)) + 1 != KEY_chunked)
341 bb_error_msg_and_die("server wants to do %s transfer encoding", str); 340 bb_error_msg_and_die("server wants to do %s transfer encoding", str);
342 chunked = got_clen = 1; 341 chunked = got_clen = 1;
343 } 342 }
diff --git a/selinux/chcon.c b/selinux/chcon.c
index 689ec8c8c..6e98c4ab9 100644
--- a/selinux/chcon.c
+++ b/selinux/chcon.c
@@ -117,7 +117,7 @@ static const char chcon_longopts[] =
117 "range\0" Required_argument "l" 117 "range\0" Required_argument "l"
118 "verbose\0" No_argument "v" 118 "verbose\0" No_argument "v"
119 "reference\0" Required_argument "\xff" /* no short option */ 119 "reference\0" Required_argument "\xff" /* no short option */
120 "\0"; 120 ;
121#endif 121#endif
122 122
123int chcon_main(int argc, char **argv); 123int chcon_main(int argc, char **argv);
diff --git a/selinux/runcon.c b/selinux/runcon.c
index 3502dcd3a..5f9e3fd12 100644
--- a/selinux/runcon.c
+++ b/selinux/runcon.c
@@ -76,7 +76,7 @@ static const char runcon_options[] =
76 "range\0" Required_argument "l" 76 "range\0" Required_argument "l"
77 "compute\0" No_argument "c" 77 "compute\0" No_argument "c"
78 "help\0" No_argument "h" 78 "help\0" No_argument "h"
79 "\0"; 79 ;
80#endif 80#endif
81 81
82#define OPTS_ROLE (1<<0) /* r */ 82#define OPTS_ROLE (1<<0) /* r */
diff --git a/util-linux/getopt.c b/util-linux/getopt.c
index 5ee13ec8b..41299d2c3 100644
--- a/util-linux/getopt.c
+++ b/util-linux/getopt.c
@@ -276,7 +276,7 @@ static const char getopt_longopts[] =
276 "unquoted\0" No_argument "u" 276 "unquoted\0" No_argument "u"
277 "alternative\0" No_argument "a" 277 "alternative\0" No_argument "a"
278 "name\0" Required_argument "n" 278 "name\0" Required_argument "n"
279 "\0"; 279 ;
280#endif 280#endif
281 281
282int getopt_main(int argc, char *argv[]); 282int getopt_main(int argc, char *argv[]);
diff --git a/util-linux/hwclock.c b/util-linux/hwclock.c
index ff696a3d7..ede95ecaa 100644
--- a/util-linux/hwclock.c
+++ b/util-linux/hwclock.c
@@ -185,7 +185,7 @@ int hwclock_main(int argc, char **argv)
185 "hctosys\0" No_argument "s" 185 "hctosys\0" No_argument "s"
186 "systohc\0" No_argument "w" 186 "systohc\0" No_argument "w"
187 "file\0" Required_argument "f" 187 "file\0" Required_argument "f"
188 "\0"; 188 ;
189 applet_long_options = hwclock_longopts; 189 applet_long_options = hwclock_longopts;
190#endif 190#endif
191 opt_complementary = "r--ws:w--rs:s--wr:l--u:u--l"; 191 opt_complementary = "r--ws:w--rs:s--wr:l--u:u--l";
diff --git a/util-linux/mount.c b/util-linux/mount.c
index 4dd1a85a2..7ee24ca14 100644
--- a/util-linux/mount.c
+++ b/util-linux/mount.c
@@ -888,33 +888,31 @@ static int nfsmount(struct mntent *mp, int vfsflags, char *filteropts)
888 if (filteropts) for (opt = strtok(filteropts, ","); opt; opt = strtok(NULL, ",")) { 888 if (filteropts) for (opt = strtok(filteropts, ","); opt; opt = strtok(NULL, ",")) {
889 char *opteq = strchr(opt, '='); 889 char *opteq = strchr(opt, '=');
890 if (opteq) { 890 if (opteq) {
891 static const char *const options[] = { 891 static const char options[] =
892 /* 0 */ "rsize", 892 /* 0 */ "rsize\0"
893 /* 1 */ "wsize", 893 /* 1 */ "wsize\0"
894 /* 2 */ "timeo", 894 /* 2 */ "timeo\0"
895 /* 3 */ "retrans", 895 /* 3 */ "retrans\0"
896 /* 4 */ "acregmin", 896 /* 4 */ "acregmin\0"
897 /* 5 */ "acregmax", 897 /* 5 */ "acregmax\0"
898 /* 6 */ "acdirmin", 898 /* 6 */ "acdirmin\0"
899 /* 7 */ "acdirmax", 899 /* 7 */ "acdirmax\0"
900 /* 8 */ "actimeo", 900 /* 8 */ "actimeo\0"
901 /* 9 */ "retry", 901 /* 9 */ "retry\0"
902 /* 10 */ "port", 902 /* 10 */ "port\0"
903 /* 11 */ "mountport", 903 /* 11 */ "mountport\0"
904 /* 12 */ "mounthost", 904 /* 12 */ "mounthost\0"
905 /* 13 */ "mountprog", 905 /* 13 */ "mountprog\0"
906 /* 14 */ "mountvers", 906 /* 14 */ "mountvers\0"
907 /* 15 */ "nfsprog", 907 /* 15 */ "nfsprog\0"
908 /* 16 */ "nfsvers", 908 /* 16 */ "nfsvers\0"
909 /* 17 */ "vers", 909 /* 17 */ "vers\0"
910 /* 18 */ "proto", 910 /* 18 */ "proto\0"
911 /* 19 */ "namlen", 911 /* 19 */ "namlen\0"
912 /* 20 */ "addr", 912 /* 20 */ "addr\0";
913 NULL
914 };
915 int val = xatoi_u(opteq + 1); 913 int val = xatoi_u(opteq + 1);
916 *opteq = '\0'; 914 *opteq = '\0';
917 switch (index_in_str_array(options, opt)) { 915 switch (index_in_strings(options, opt)) {
918 case 0: // "rsize" 916 case 0: // "rsize"
919 data.rsize = val; 917 data.rsize = val;
920 break; 918 break;
@@ -993,26 +991,24 @@ static int nfsmount(struct mntent *mp, int vfsflags, char *filteropts)
993 } 991 }
994 } 992 }
995 else { 993 else {
996 static const char *const options[] = { 994 static const char options[] =
997 "bg", 995 "bg\0"
998 "fg", 996 "fg\0"
999 "soft", 997 "soft\0"
1000 "hard", 998 "hard\0"
1001 "intr", 999 "intr\0"
1002 "posix", 1000 "posix\0"
1003 "cto", 1001 "cto\0"
1004 "ac", 1002 "ac\0"
1005 "tcp", 1003 "tcp\0"
1006 "udp", 1004 "udp\0"
1007 "lock", 1005 "lock\0";
1008 NULL
1009 };
1010 int val = 1; 1006 int val = 1;
1011 if (!strncmp(opt, "no", 2)) { 1007 if (!strncmp(opt, "no", 2)) {
1012 val = 0; 1008 val = 0;
1013 opt += 2; 1009 opt += 2;
1014 } 1010 }
1015 switch (index_in_str_array(options, opt)) { 1011 switch (index_in_strings(options, opt)) {
1016 case 0: // "bg" 1012 case 0: // "bg"
1017 bg = val; 1013 bg = val;
1018 break; 1014 break;