diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-11-28 06:49:03 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-11-28 06:49:03 +0000 |
commit | 1aa7e477b1b727db77cac2d717f0fcca40587f78 (patch) | |
tree | 247171517f0e01d32a71a5e96f4bef462cc0e9c6 /libbb/appletlib.c | |
parent | 79c6904faff1ebd4bf4b7d9cd0c20ca70f4cec75 (diff) | |
download | busybox-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/appletlib.c')
-rw-r--r-- | libbb/appletlib.c | 87 |
1 files changed, 43 insertions, 44 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" |
41 | const 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 | ||
110 | static int applet_name_compare(const void *name, const void *vapplet) | 104 | static 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 | ||
117 | const struct bb_applet *find_applet_by_name(const char *name) | 110 | int 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 */ |
168 | static struct BB_suid_config { | 166 | static 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 |
444 | static void check_suid(const struct bb_applet *applet) | 442 | static 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 | ||
632 | void run_appletstruct_and_exit(const struct bb_applet *applet, char **argv) | 631 | void 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 | ||
651 | void run_applet_and_exit(const char *name, char **argv) | 650 | void 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 | } |