aboutsummaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-11-28 06:49:03 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-11-28 06:49:03 +0000
commit1aa7e477b1b727db77cac2d717f0fcca40587f78 (patch)
tree247171517f0e01d32a71a5e96f4bef462cc0e9c6 /libbb
parent79c6904faff1ebd4bf4b7d9cd0c20ca70f4cec75 (diff)
downloadbusybox-w32-1aa7e477b1b727db77cac2d717f0fcca40587f78.tar.gz
busybox-w32-1aa7e477b1b727db77cac2d717f0fcca40587f78.tar.bz2
busybox-w32-1aa7e477b1b727db77cac2d717f0fcca40587f78.zip
reorganize applet table. Eliminates pointers to names.
Should be a big win for libbusybox. busybox wins too: text data bss dec hex filename 776524 929 9100 786553 c0079 busybox_old 775903 929 9100 785932 bfe0c busybox_unstripped
Diffstat (limited to 'libbb')
-rw-r--r--libbb/appletlib.c87
-rw-r--r--libbb/execable.c2
-rw-r--r--libbb/vfork_daemon_rexec.c22
3 files changed, 55 insertions, 56 deletions
diff --git a/libbb/appletlib.c b/libbb/appletlib.c
index 4bd60d049..dcf24f5a9 100644
--- a/libbb/appletlib.c
+++ b/libbb/appletlib.c
@@ -33,13 +33,9 @@ static const char usage_messages[] ALIGN1 = ""
33#define usage_messages 0 33#define usage_messages 0
34#endif /* SHOW_USAGE */ 34#endif /* SHOW_USAGE */
35 35
36/* Define struct bb_applet applets[] */
37#include "applets.h"
38 36
39#if ENABLE_FEATURE_SH_STANDALONE 37/* Include generated applet names, pointers to <apllet>_main, etc */
40/* -1 because last entry is NULL */ 38#include "applet_tables.h"
41const unsigned short NUM_APPLETS = ARRAY_SIZE(applets) - 1;
42#endif
43 39
44 40
45#if ENABLE_FEATURE_COMPRESS_USAGE 41#if ENABLE_FEATURE_COMPRESS_USAGE
@@ -84,16 +80,14 @@ void bb_show_usage(void)
84 const char *format_string; 80 const char *format_string;
85 const char *p; 81 const char *p;
86 const char *usage_string = p = unpack_usage_messages(); 82 const char *usage_string = p = unpack_usage_messages();
87 const struct bb_applet *ap = find_applet_by_name(applet_name); 83 int ap = find_applet_by_name(applet_name);
88 int i;
89 84
90 if (!ap) /* never happens, paranoia */ 85 if (ap < 0) /* never happens, paranoia */
91 xfunc_die(); 86 xfunc_die();
92 87
93 i = ap - applets; 88 while (ap) {
94 while (i) {
95 while (*p++) continue; 89 while (*p++) continue;
96 i--; 90 ap--;
97 } 91 }
98 92
99 fprintf(stderr, "%s multi-call binary\n", bb_banner); 93 fprintf(stderr, "%s multi-call binary\n", bb_banner);
@@ -107,18 +101,22 @@ void bb_show_usage(void)
107} 101}
108 102
109 103
110static int applet_name_compare(const void *name, const void *vapplet) 104static int applet_name_compare(const void *name, const void *v)
111{ 105{
112 const struct bb_applet *applet = vapplet; 106 int i = (const char *)v - applet_names;
113 107 return strcmp(name, APPLET_NAME(i));
114 return strcmp(name, applet->name);
115} 108}
116 109
117const struct bb_applet *find_applet_by_name(const char *name) 110int find_applet_by_name(const char *name)
118{ 111{
112 const char *p;
119 /* Do a binary search to find the applet entry given the name. */ 113 /* Do a binary search to find the applet entry given the name. */
120 return bsearch(name, applets, ARRAY_SIZE(applets)-1, sizeof(applets[0]), 114
121 applet_name_compare); 115 /* NB: any char pointer will work as well, not necessarily applet_names */
116 p = bsearch(name, applet_names, ARRAY_SIZE(applet_mains), 1, applet_name_compare);
117 if (!p)
118 return -1;
119 return p - applet_names;
122} 120}
123 121
124 122
@@ -166,7 +164,7 @@ USE_FEATURE_SUID(static uid_t ruid;) /* real uid */
166 164
167/* applets[] is const, so we have to define this "override" structure */ 165/* applets[] is const, so we have to define this "override" structure */
168static struct BB_suid_config { 166static struct BB_suid_config {
169 const struct bb_applet *m_applet; 167 int m_applet;
170 uid_t m_uid; 168 uid_t m_uid;
171 gid_t m_gid; 169 gid_t m_gid;
172 mode_t m_mode; 170 mode_t m_mode;
@@ -232,7 +230,7 @@ static void parse_config_file(void)
232{ 230{
233 struct BB_suid_config *sct_head; 231 struct BB_suid_config *sct_head;
234 struct BB_suid_config *sct; 232 struct BB_suid_config *sct;
235 const struct bb_applet *applet; 233 int applet_no;
236 FILE *f; 234 FILE *f;
237 const char *errmsg; 235 const char *errmsg;
238 char *s; 236 char *s;
@@ -343,14 +341,14 @@ static void parse_config_file(void)
343 * applet is currently built in and ignore it otherwise. 341 * applet is currently built in and ignore it otherwise.
344 * Note: this can hide config file bugs which only pop 342 * Note: this can hide config file bugs which only pop
345 * up when the busybox configuration is changed. */ 343 * up when the busybox configuration is changed. */
346 applet = find_applet_by_name(s); 344 applet_no = find_applet_by_name(s);
347 if (applet) { 345 if (applet_no >= 0) {
348 /* Note: We currently don't check for duplicates! 346 /* Note: We currently don't check for duplicates!
349 * The last config line for each applet will be the 347 * The last config line for each applet will be the
350 * one used since we insert at the head of the list. 348 * one used since we insert at the head of the list.
351 * I suppose this could be considered a feature. */ 349 * I suppose this could be considered a feature. */
352 sct = xmalloc(sizeof(struct BB_suid_config)); 350 sct = xmalloc(sizeof(struct BB_suid_config));
353 sct->m_applet = applet; 351 sct->m_applet = applet_no;
354 sct->m_mode = 0; 352 sct->m_mode = 0;
355 sct->m_next = sct_head; 353 sct->m_next = sct_head;
356 sct_head = sct; 354 sct_head = sct;
@@ -441,7 +439,7 @@ static inline void parse_config_file(void)
441 439
442 440
443#if ENABLE_FEATURE_SUID 441#if ENABLE_FEATURE_SUID
444static void check_suid(const struct bb_applet *applet) 442static void check_suid(int applet_no)
445{ 443{
446 gid_t rgid; /* real gid */ 444 gid_t rgid; /* real gid */
447 445
@@ -456,7 +454,7 @@ static void check_suid(const struct bb_applet *applet)
456 mode_t m; 454 mode_t m;
457 455
458 for (sct = suid_config; sct; sct = sct->m_next) { 456 for (sct = suid_config; sct; sct = sct->m_next) {
459 if (sct->m_applet == applet) 457 if (sct->m_applet == applet_no)
460 goto found; 458 goto found;
461 } 459 }
462 goto check_need_suid; 460 goto check_need_suid;
@@ -504,12 +502,12 @@ static void check_suid(const struct bb_applet *applet)
504#endif 502#endif
505 check_need_suid: 503 check_need_suid:
506#endif 504#endif
507 if (applet->need_suid == _BB_SUID_ALWAYS) { 505 if (APPLET_SUID(applet_no) == _BB_SUID_ALWAYS) {
508 /* Real uid is not 0. If euid isn't 0 too, suid bit 506 /* Real uid is not 0. If euid isn't 0 too, suid bit
509 * is most probably not set on our executable */ 507 * is most probably not set on our executable */
510 if (geteuid()) 508 if (geteuid())
511 bb_error_msg_and_die("must be suid to work properly"); 509 bb_error_msg_and_die("must be suid to work properly");
512 } else if (applet->need_suid == _BB_SUID_NEVER) { 510 } else if (APPLET_SUID(applet_no) == _BB_SUID_NEVER) {
513 xsetgid(rgid); /* drop all privileges */ 511 xsetgid(rgid); /* drop all privileges */
514 xsetuid(ruid); 512 xsetuid(ruid);
515 } 513 }
@@ -536,18 +534,19 @@ static void install_links(const char *busybox, int use_symbolic_links)
536 usr_sbin 534 usr_sbin
537 }; 535 };
538 536
539 int (*lf)(const char *, const char *) = link; 537 int (*lf)(const char *, const char *);
540 char *fpc; 538 char *fpc;
541 int i; 539 int i;
542 int rc; 540 int rc;
543 541
542 lf = link;
544 if (use_symbolic_links) 543 if (use_symbolic_links)
545 lf = symlink; 544 lf = symlink;
546 545
547 for (i = 0; applets[i].name != NULL; i++) { 546 for (i = 0; i < ARRAY_SIZE(applet_mains); i++) {
548 fpc = concat_path_file( 547 fpc = concat_path_file(
549 install_dir[applets[i].install_loc], 548 install_dir[APPLET_INSTALL_LOC(i)],
550 applets[i].name); 549 APPLET_NAME(i));
551 rc = lf(busybox, fpc); 550 rc = lf(busybox, fpc);
552 if (rc != 0 && errno != EEXIST) { 551 if (rc != 0 && errno != EEXIST) {
553 bb_simple_perror_msg(fpc); 552 bb_simple_perror_msg(fpc);
@@ -564,7 +563,7 @@ static int busybox_main(char **argv)
564{ 563{
565 if (!argv[1]) { 564 if (!argv[1]) {
566 /* Called without arguments */ 565 /* Called without arguments */
567 const struct bb_applet *a; 566 const char *a;
568 int col, output_width; 567 int col, output_width;
569 help: 568 help:
570 output_width = 80; 569 output_width = 80;
@@ -588,14 +587,14 @@ static int busybox_main(char **argv)
588 "\twill act like whatever it was invoked as!\n" 587 "\twill act like whatever it was invoked as!\n"
589 "\nCurrently defined functions:\n"); 588 "\nCurrently defined functions:\n");
590 col = 0; 589 col = 0;
591 a = applets; 590 a = applet_names;
592 while (a->name) { 591 while (*a) {
593 if (col > output_width) { 592 if (col > output_width) {
594 puts(","); 593 puts(",");
595 col = 0; 594 col = 0;
596 } 595 }
597 col += printf("%s%s", (col ? ", " : "\t"), a->name); 596 col += printf("%s%s", (col ? ", " : "\t"), a);
598 a++; 597 a += strlen(a) + 1;
599 } 598 }
600 puts("\n"); 599 puts("\n");
601 return 0; 600 return 0;
@@ -629,7 +628,7 @@ static int busybox_main(char **argv)
629 bb_error_msg_and_die("applet not found"); 628 bb_error_msg_and_die("applet not found");
630} 629}
631 630
632void run_appletstruct_and_exit(const struct bb_applet *applet, char **argv) 631void run_applet_no_and_exit(int applet_no, char **argv)
633{ 632{
634 int argc = 1; 633 int argc = 1;
635 634
@@ -640,19 +639,19 @@ void run_appletstruct_and_exit(const struct bb_applet *applet, char **argv)
640 optind = 1; 639 optind = 1;
641 xfunc_error_retval = EXIT_FAILURE; 640 xfunc_error_retval = EXIT_FAILURE;
642 641
643 applet_name = applet->name; 642 applet_name = APPLET_NAME(applet_no);
644 if (argc == 2 && !strcmp(argv[1], "--help")) 643 if (argc == 2 && !strcmp(argv[1], "--help"))
645 bb_show_usage(); 644 bb_show_usage();
646 if (ENABLE_FEATURE_SUID) 645 if (ENABLE_FEATURE_SUID)
647 check_suid(applet); 646 check_suid(applet_no);
648 exit(applet->main(argc, argv)); 647 exit(applet_mains[applet_no](argc, argv));
649} 648}
650 649
651void run_applet_and_exit(const char *name, char **argv) 650void run_applet_and_exit(const char *name, char **argv)
652{ 651{
653 const struct bb_applet *applet = find_applet_by_name(name); 652 int applet = find_applet_by_name(name);
654 if (applet) 653 if (applet >= 0)
655 run_appletstruct_and_exit(applet, argv); 654 run_applet_no_and_exit(applet, argv);
656 if (!strncmp(name, "busybox", 7)) 655 if (!strncmp(name, "busybox", 7))
657 exit(busybox_main(argv)); 656 exit(busybox_main(argv));
658} 657}
diff --git a/libbb/execable.c b/libbb/execable.c
index f679108be..2649a6cfe 100644
--- a/libbb/execable.c
+++ b/libbb/execable.c
@@ -65,7 +65,7 @@ int exists_execable(const char *filename)
65 */ 65 */
66int bb_execvp(const char *file, char *const argv[]) 66int bb_execvp(const char *file, char *const argv[])
67{ 67{
68 return execvp(find_applet_by_name(file) ? bb_busybox_exec_path : file, 68 return execvp(find_applet_by_name(file) >= 0 ? bb_busybox_exec_path : file,
69 argv); 69 argv);
70} 70}
71#endif 71#endif
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c
index a01065d69..1d6817ee6 100644
--- a/libbb/vfork_daemon_rexec.c
+++ b/libbb/vfork_daemon_rexec.c
@@ -16,7 +16,7 @@
16 */ 16 */
17 17
18#include <paths.h> 18#include <paths.h>
19#include "busybox.h" /* for struct bb_applet */ 19#include "busybox.h" /* uses applet tables */
20 20
21/* This does a fork/exec in one call, using vfork(). Returns PID of new child, 21/* This does a fork/exec in one call, using vfork(). Returns PID of new child,
22 * -1 for failure. Runs argv[0], searching path if that has no / in it. */ 22 * -1 for failure. Runs argv[0], searching path if that has no / in it. */
@@ -120,11 +120,11 @@ void restore_nofork_data(struct nofork_save_area *save)
120 die_sleep = save->die_sleep; 120 die_sleep = save->die_sleep;
121} 121}
122 122
123int run_nofork_applet_prime(struct nofork_save_area *old, const struct bb_applet *a, char **argv) 123int run_nofork_applet_prime(struct nofork_save_area *old, int applet_no, char **argv)
124{ 124{
125 int rc, argc; 125 int rc, argc;
126 126
127 applet_name = a->name; 127 applet_name = APPLET_NAME(applet_no);
128 xfunc_error_retval = EXIT_FAILURE; 128 xfunc_error_retval = EXIT_FAILURE;
129 /*option_mask32 = 0; - not needed */ 129 /*option_mask32 = 0; - not needed */
130 /* special flag for xfunc_die(). If xfunc will "die" 130 /* special flag for xfunc_die(). If xfunc will "die"
@@ -143,7 +143,7 @@ int run_nofork_applet_prime(struct nofork_save_area *old, const struct bb_applet
143 char *tmp_argv[argc+1]; 143 char *tmp_argv[argc+1];
144 memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0])); 144 memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0]));
145 /* Finally we can call NOFORK applet's main() */ 145 /* Finally we can call NOFORK applet's main() */
146 rc = a->main(argc, tmp_argv); 146 rc = applet_mains[applet_no](argc, tmp_argv);
147 } else { /* xfunc died in NOFORK applet */ 147 } else { /* xfunc died in NOFORK applet */
148 /* in case they meant to return 0... */ 148 /* in case they meant to return 0... */
149 if (rc == -2222) 149 if (rc == -2222)
@@ -155,13 +155,13 @@ int run_nofork_applet_prime(struct nofork_save_area *old, const struct bb_applet
155 return rc; 155 return rc;
156} 156}
157 157
158int run_nofork_applet(const struct bb_applet *a, char **argv) 158int run_nofork_applet(int applet_no, char **argv)
159{ 159{
160 struct nofork_save_area old; 160 struct nofork_save_area old;
161 161
162 /* Saving globals */ 162 /* Saving globals */
163 save_nofork_data(&old); 163 save_nofork_data(&old);
164 return run_nofork_applet_prime(&old, a, argv); 164 return run_nofork_applet_prime(&old, applet_no, argv);
165} 165}
166#endif /* FEATURE_PREFER_APPLETS */ 166#endif /* FEATURE_PREFER_APPLETS */
167 167
@@ -169,15 +169,15 @@ int spawn_and_wait(char **argv)
169{ 169{
170 int rc; 170 int rc;
171#if ENABLE_FEATURE_PREFER_APPLETS 171#if ENABLE_FEATURE_PREFER_APPLETS
172 const struct bb_applet *a = find_applet_by_name(argv[0]); 172 int a = find_applet_by_name(argv[0]);
173 173
174 if (a && (a->nofork 174 if (a >= 0 && (APPLET_IS_NOFORK(a)
175#if BB_MMU 175#if BB_MMU
176 || a->noexec /* NOEXEC trick needs fork() */ 176 || APPLET_IS_NOEXEC(a) /* NOEXEC trick needs fork() */
177#endif 177#endif
178 )) { 178 )) {
179#if BB_MMU 179#if BB_MMU
180 if (a->nofork) 180 if (APPLET_IS_NOFORK(a))
181#endif 181#endif
182 { 182 {
183 return run_nofork_applet(a, argv); 183 return run_nofork_applet(a, argv);
@@ -190,7 +190,7 @@ int spawn_and_wait(char **argv)
190 return wait4pid(rc); 190 return wait4pid(rc);
191 /* child */ 191 /* child */
192 xfunc_error_retval = EXIT_FAILURE; 192 xfunc_error_retval = EXIT_FAILURE;
193 run_appletstruct_and_exit(a, argv); 193 run_applet_no_and_exit(a, argv);
194#endif 194#endif
195 } 195 }
196#endif /* FEATURE_PREFER_APPLETS */ 196#endif /* FEATURE_PREFER_APPLETS */