function old new delta busybox_main - 647 +647 applet_names 2536 2544 +8 run_applet_no_and_exit 451 458 +7 applet_main 1468 1472 +4 main 119 120 +1 .rodata 147032 147027 -5 packed_usage 30751 30738 -13 run_applet_and_exit 675 23 -652 ------------------------------------------------------------------------------ (add/remove: 2/0 grow/shrink: 4/3 up/down: 667/-670) Total: -3 bytes
Signed-off-by: Ron Yorston <[email protected]> --- Config.in | 21 +++-- applets/applet_tables.c | 18 ++-- include/busybox.h | 4 - libbb/appletlib.c | 199 ++----------------------------------------- libbb/busybox.c | 220 ++++++++++++++++++++++++++++++++++++++++++++++++ scripts/trylink | 20 ----- 6 files changed, 248 insertions(+), 234 deletions(-) create mode 100644 libbb/busybox.c diff --git a/Config.in b/Config.in index 0a0b5d7..eff733a 100644 --- a/Config.in +++ b/Config.in @@ -116,9 +116,21 @@ config FEATURE_COMPRESS_USAGE and have very little memory, this might not be a win. Otherwise, you probably want this. +config BUSYBOX + bool "Include busybox applet" + default y + help + The busybox applet provides general help regarding busybox and + allows the included applets to be listed. It's also required + if applet links are to be installed at runtime. + + If you can live without these features disabling this will save + some space. + config FEATURE_INSTALLER bool "Support --install [-s] to install applet links at runtime" default y + depends on BUSYBOX help Enable 'busybox --install [-s]' support. This will allow you to use busybox at runtime to create hard links or symlinks for all the @@ -577,15 +589,6 @@ config FEATURE_INDIVIDUAL You need to have a working dynamic linker. -config FEATURE_SHARED_BUSYBOX - bool "Produce additional busybox binary linked against libbusybox" - default y - depends on BUILD_LIBBUSYBOX - help - Build busybox, dynamically linked against libbusybox.so.N.N.N. - - You need to have a working dynamic linker. - ### config BUILD_AT_ONCE ### bool "Compile all sources at once" ### default n diff --git a/applets/applet_tables.c b/applets/applet_tables.c index 843f2ec..a2917cd 100644 --- a/applets/applet_tables.c +++ b/applets/applet_tables.c @@ -98,8 +98,15 @@ int main(int argc, char **argv) printf("#define SINGLE_APPLET_STR \"%s\"\n", applets[0].name); printf("#define SINGLE_APPLET_MAIN %s_main\n", applets[0].main); } - printf("#define KNOWN_APPNAME_OFFSETS %u\n\n", KNOWN_APPNAME_OFFSETS); + + for (i = 0; i < NUM_APPLETS; i++) { + if (str_isalnum_(applets[i].name)) + printf("#define APPLET_NO_%s %d\n", applets[i].name, i); + } + printf("\n\n"); + + printf("#ifndef SKIP_definitions\n"); if (KNOWN_APPNAME_OFFSETS > 0) { int ofs, offset[KNOWN_APPNAME_OFFSETS], index[KNOWN_APPNAME_OFFSETS]; for (i = 0; i < KNOWN_APPNAME_OFFSETS; i++) @@ -120,7 +127,6 @@ int main(int argc, char **argv) printf("};\n\n"); } - //printf("#ifndef SKIP_definitions\n"); printf("const char applet_names[] ALIGN1 = \"\"\n"); for (i = 0; i < NUM_APPLETS; i++) { printf("\"%s\" \"\\0\"\n", applets[i].name); @@ -129,12 +135,6 @@ int main(int argc, char **argv) } printf(";\n\n"); - for (i = 0; i < NUM_APPLETS; i++) { - if (str_isalnum_(applets[i].name)) - printf("#define APPLET_NO_%s %d\n", applets[i].name, i); - } - printf("\n"); - printf("#ifndef SKIP_applet_main\n"); printf("int (*const applet_main[])(int argc, char **argv) = {\n"); for (i = 0; i < NUM_APPLETS; i++) { @@ -189,7 +189,7 @@ int main(int argc, char **argv) } printf("};\n"); #endif - //printf("#endif /* SKIP_definitions */\n"); + printf("#endif /* SKIP_definitions */\n"); // printf("\n"); // printf("#define MAX_APPLET_NAME_LEN %u\n", MAX_APPLET_NAME_LEN); diff --git a/include/busybox.h b/include/busybox.h index 737627b..4af6a11 100644 --- a/include/busybox.h +++ b/include/busybox.h @@ -44,12 +44,8 @@ extern const uint8_t applet_install_loc[] ALIGN1; * and "individual" binaries. Keep them short. */ #if ENABLE_BUILD_LIBBUSYBOX -#if ENABLE_FEATURE_SHARED_BUSYBOX -int lbb_main(char **argv) EXTERNALLY_VISIBLE; -#else int lbb_main(char **argv); #endif -#endif POP_SAVED_FUNCTION_VISIBILITY diff --git a/libbb/appletlib.c b/libbb/appletlib.c index b682e6b..4a6ad25 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c @@ -655,195 +655,6 @@ static void check_suid(int applet_no) # define check_suid(x) ((void)0) # endif /* FEATURE_SUID */ - -# if ENABLE_FEATURE_INSTALLER -static const char usr_bin [] ALIGN1 = "/usr/bin/"; -static const char usr_sbin[] ALIGN1 = "/usr/sbin/"; -static const char *const install_dir[] = { - &usr_bin [8], /* "/" */ - &usr_bin [4], /* "/bin/" */ - &usr_sbin[4] /* "/sbin/" */ -# if !ENABLE_INSTALL_NO_USR - ,usr_bin - ,usr_sbin -# endif -}; - -/* create (sym)links for each applet */ -static void install_links(const char *busybox, int use_symbolic_links, - char *custom_install_dir) -{ - /* directory table - * this should be consistent w/ the enum, - * busybox.h::bb_install_loc_t, or else... */ - int (*lf)(const char *, const char *); - char *fpc; - const char *appname = applet_names; - unsigned i; - int rc; - - lf = link; - if (use_symbolic_links) - lf = symlink; - - for (i = 0; i < ARRAY_SIZE(applet_main); i++) { - fpc = concat_path_file( - custom_install_dir ? custom_install_dir : install_dir[APPLET_INSTALL_LOC(i)], - appname); - // debug: bb_error_msg("%slinking %s to busybox", - // use_symbolic_links ? "sym" : "", fpc); - rc = lf(busybox, fpc); - if (rc != 0 && errno != EEXIST) { - bb_simple_perror_msg(fpc); - } - free(fpc); - while (*appname++ != '\0') - continue; - } -} -# else -static void install_links(const char *busybox UNUSED_PARAM, - int use_symbolic_links UNUSED_PARAM, - char *custom_install_dir UNUSED_PARAM) -{ -} -# endif - -/* If we were called as "busybox..." */ -static int busybox_main(char **argv) -{ - if (!argv[1]) { - /* Called without arguments */ - const char *a; - int col; - unsigned output_width; - help: - output_width = 80; - if (ENABLE_FEATURE_AUTOWIDTH) { - /* Obtain the terminal width */ - output_width = get_terminal_width(2); - } - - dup2(1, 2); - full_write2_str(bb_banner); /* reuse const string */ - full_write2_str(" multi-call binary.\n"); /* reuse */ - full_write2_str( - "BusyBox is copyrighted by many authors between 1998-2015.\n" - "Licensed under GPLv2. See source distribution for detailed\n" - "copyright notices.\n" - "\n" - "Usage: busybox [function [arguments]...]\n" - " or: busybox --list"IF_FEATURE_INSTALLER("[-full]")"\n" - IF_FEATURE_INSTALLER( - " or: busybox --install [-s] [DIR]\n" - ) - " or: function [arguments]...\n" - "\n" - IF_NOT_FEATURE_SH_STANDALONE( - "\tBusyBox is a multi-call binary that combines many common Unix\n" - "\tutilities into a single executable. Most people will create a\n" - "\tlink to busybox for each function they wish to use and BusyBox\n" - "\twill act like whatever it was invoked as.\n" - ) - IF_FEATURE_SH_STANDALONE( - "\tBusyBox is a multi-call binary that combines many common Unix\n" - "\tutilities into a single executable. The shell in this build\n" - "\tis configured to run built-in utilities without $PATH search.\n" - "\tYou don't need to install a link to busybox for each utility.\n" - "\tTo run external program, use full path (/sbin/ip instead of ip).\n" - ) - "\n" - "Currently defined functions:\n" - ); - col = 0; - a = applet_names; - /* prevent last comma to be in the very last pos */ - output_width--; - while (*a) { - int len2 = strlen(a) + 2; - if (col >= (int)output_width - len2) { - full_write2_str(",\n"); - col = 0; - } - if (col == 0) { - col = 6; - full_write2_str("\t"); - } else { - full_write2_str(", "); - } - full_write2_str(a); - col += len2; - a += len2 - 1; - } - full_write2_str("\n\n"); - return 0; - } - - if (is_prefixed_with(argv[1], "--list")) { - unsigned i = 0; - const char *a = applet_names; - dup2(1, 2); - while (*a) { -# if ENABLE_FEATURE_INSTALLER - if (argv[1][6]) /* --list-full? */ - full_write2_str(install_dir[APPLET_INSTALL_LOC(i)] + 1); -# endif - full_write2_str(a); - full_write2_str("\n"); - i++; - while (*a++ != '\0') - continue; - } - return 0; - } - - if (ENABLE_FEATURE_INSTALLER && strcmp(argv[1], "--install") == 0) { - int use_symbolic_links; - const char *busybox; - - busybox = xmalloc_readlink(bb_busybox_exec_path); - if (!busybox) { - /* bb_busybox_exec_path is usually "/proc/self/exe". - * In chroot, readlink("/proc/self/exe") usually fails. - * In such case, better use argv[0] as symlink target - * if it is a full path name. - */ - if (argv[0][0] != '/') - bb_error_msg_and_die("'%s' is not an absolute path", argv[0]); - busybox = argv[0]; - } - /* busybox --install [-s] [DIR]: - * -s: make symlinks - * DIR: directory to install links to - */ - use_symbolic_links = (argv[2] && strcmp(argv[2], "-s") == 0 && ++argv); - install_links(busybox, use_symbolic_links, argv[2]); - return 0; - } - - if (strcmp(argv[1], "--help") == 0) { - /* "busybox --help [<applet>]" */ - if (!argv[2]) - goto help; - /* convert to "<applet> --help" */ - argv[0] = argv[2]; - argv[2] = NULL; - } else { - /* "busybox <applet> arg1 arg2 ..." */ - argv++; - } - /* We support "busybox /a/path/to/applet args..." too. Allows for - * "#!/bin/busybox"-style wrappers */ - applet_name = bb_get_last_path_component_nostrip(argv[0]); - run_applet_and_exit(applet_name, argv); - - /*bb_error_msg_and_die("applet not found"); - sucks in printf */ - full_write2_str(applet_name); - full_write2_str(": applet not found\n"); - /* POSIX: "If a command is not found, the exit status shall be 127" */ - exit(127); -} - void FAST_FUNC run_applet_no_and_exit(int applet_no, char **argv) { int argc = 1; @@ -870,6 +681,9 @@ void FAST_FUNC run_applet_no_and_exit(int applet_no, char **argv) #if defined APPLET_NO_false && applet_no != APPLET_NO_false #endif +#if defined APPLET_NO_busybox + && applet_no != APPLET_NO_busybox +#endif ) { if (argc == 2 && strcmp(argv[1], "--help") == 0) { /* Make "foo --help" exit with 0: */ @@ -886,9 +700,6 @@ void FAST_FUNC run_applet_and_exit(const char *name, char **argv) { int applet; - if (is_prefixed_with(name, "busybox")) - exit(busybox_main(argv)); - /* find_applet_by_name() search is more expensive, so goes second */ applet = find_applet_by_name(name); if (applet >= 0) run_applet_no_and_exit(applet, argv); @@ -952,6 +763,10 @@ int main(int argc UNUSED_PARAM, char **argv) #else lbb_prepare("busybox" IF_FEATURE_INDIVIDUAL(, argv)); +#if !defined(CONFIG_BUSYBOX) + if (argv[1] && is_prefixed_with(bb_basename(argv[0]), "busybox")) + argv++; +#endif applet_name = argv[0]; if (applet_name[0] == '-') applet_name++; diff --git a/libbb/busybox.c b/libbb/busybox.c new file mode 100644 index 0000000..368cd55 --- /dev/null +++ b/libbb/busybox.c @@ -0,0 +1,220 @@ +/* vi: set sw=4 ts=4: */ +/* + * busybox applet + * + * Copyright (C) tons of folks. Tracking down who wrote what + * isn't something I'm going to worry about... If you wrote something + * here, please feel free to acknowledge your work. + * + * Licensed under GPLv2 or later, see file LICENSE in this source tree. + */ + +#include "busybox.h" +#define SKIP_definitions +#include "applet_tables.h" + +//applet:IF_BUSYBOX(APPLET(busybox, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_BUSYBOX) += busybox.o + +//usage:#define busybox_trivial_usage +//usage: "" +//usage:#define busybox_full_usage +//usage: "" + +# if ENABLE_FEATURE_INSTALLER +static const char usr_bin [] ALIGN1 = "/usr/bin/"; +static const char usr_sbin[] ALIGN1 = "/usr/sbin/"; +static const char *const install_dir[] = { + &usr_bin [8], /* "/" */ + &usr_bin [4], /* "/bin/" */ + &usr_sbin[4] /* "/sbin/" */ +# if !ENABLE_INSTALL_NO_USR + ,usr_bin + ,usr_sbin +# endif +}; + +/* create (sym)links for each applet */ +static void install_links(const char *busybox, int use_symbolic_links, + char *custom_install_dir) +{ + /* directory table + * this should be consistent w/ the enum, + * busybox.h::bb_install_loc_t, or else... */ + int (*lf)(const char *, const char *); + char *fpc; + const char *appname = applet_names; + unsigned i; + int rc; + + lf = link; + if (use_symbolic_links) + lf = symlink; + + for (i = 0; i < NUM_APPLETS; i++) { +#if defined APPLET_NO_busybox + if (i == APPLET_NO_busybox) + goto skip_name; +#endif + fpc = concat_path_file( + custom_install_dir ? custom_install_dir : install_dir[APPLET_INSTALL_LOC(i)], + appname); + // debug: bb_error_msg("%slinking %s to busybox", + // use_symbolic_links ? "sym" : "", fpc); + rc = lf(busybox, fpc); + if (rc != 0 && errno != EEXIST) { + bb_simple_perror_msg(fpc); + } + free(fpc); + skip_name: + while (*appname++ != '\0') + continue; + } +} +# else +static void install_links(const char *busybox UNUSED_PARAM, + int use_symbolic_links UNUSED_PARAM, + char *custom_install_dir UNUSED_PARAM) +{ +} +# endif + +int busybox_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int busybox_main(int argc UNUSED_PARAM, char **argv) +{ + if (!argv[1]) { + /* Called without arguments */ + const char *a; + int col; + unsigned output_width; + help: + output_width = 80; + if (ENABLE_FEATURE_AUTOWIDTH) { + /* Obtain the terminal width */ + output_width = get_terminal_width(2); + } + + dup2(1, 2); + full_write2_str(bb_banner); /* reuse const string */ + full_write2_str(" multi-call binary.\n"); /* reuse */ + full_write2_str( + "BusyBox is copyrighted by many authors between 1998-2015.\n" + "Licensed under GPLv2. See source distribution for detailed\n" + "copyright notices.\n" + "\n" + "Usage: busybox [function [arguments]...]\n" + " or: busybox --list"IF_FEATURE_INSTALLER("[-full]")"\n" + IF_FEATURE_INSTALLER( + " or: busybox --install [-s] [DIR]\n" + ) + " or: function [arguments]...\n" + "\n" + IF_NOT_FEATURE_SH_STANDALONE( + "\tBusyBox is a multi-call binary that combines many common Unix\n" + "\tutilities into a single executable. Most people will create a\n" + "\tlink to busybox for each function they wish to use and BusyBox\n" + "\twill act like whatever it was invoked as.\n" + ) + IF_FEATURE_SH_STANDALONE( + "\tBusyBox is a multi-call binary that combines many common Unix\n" + "\tutilities into a single executable. The shell in this build\n" + "\tis configured to run built-in utilities without $PATH search.\n" + "\tYou don't need to install a link to busybox for each utility.\n" + "\tTo run external program, use full path (/sbin/ip instead of ip).\n" + ) + "\n" + "Currently defined functions:\n" + ); + col = 0; + a = applet_names; + /* prevent last comma to be in the very last pos */ + output_width--; + while (*a) { + int len2 = strlen(a) + 2; + if (col >= (int)output_width - len2) { + full_write2_str(",\n"); + col = 0; + } + if (col == 0) { + col = 6; + full_write2_str("\t"); + } else { + full_write2_str(", "); + } + full_write2_str(a); + col += len2; + a += len2 - 1; + } + full_write2_str("\n\n"); + return 0; + } + + if (is_prefixed_with(argv[1], "--list")) { + unsigned i = 0; + const char *a = applet_names; + dup2(1, 2); + while (*a) { + if (ENABLE_FEATURE_INSTALLER && argv[1][6]) { /* --list-full? */ +#if defined APPLET_NO_busybox + if (i == APPLET_NO_busybox) + goto skip_name; +#endif + full_write2_str(install_dir[APPLET_INSTALL_LOC(i)] + 1); + } + full_write2_str(a); + full_write2_str("\n"); + skip_name: + i++; + while (*a++ != '\0') + continue; + } + return 0; + } + + if (ENABLE_FEATURE_INSTALLER && strcmp(argv[1], "--install") == 0) { + int use_symbolic_links; + const char *busybox; + + busybox = xmalloc_readlink(bb_busybox_exec_path); + if (!busybox) { + /* bb_busybox_exec_path is usually "/proc/self/exe". + * In chroot, readlink("/proc/self/exe") usually fails. + * In such case, better use argv[0] as symlink target + * if it is a full path name. + */ + if (argv[0][0] != '/') + bb_error_msg_and_die("'%s' is not an absolute path", argv[0]); + busybox = argv[0]; + } + /* busybox --install [-s] [DIR]: + * -s: make symlinks + * DIR: directory to install links to + */ + use_symbolic_links = (argv[2] && strcmp(argv[2], "-s") == 0 && ++argv); + install_links(busybox, use_symbolic_links, argv[2]); + return 0; + } + + if (strcmp(argv[1], "--help") == 0) { + /* "busybox --help [<applet>]" */ + if (!argv[2]) + goto help; + /* convert to "<applet> --help" */ + argv[0] = argv[2]; + argv[2] = NULL; + } else { + /* "busybox <applet> arg1 arg2 ..." */ + argv++; + } + /* We support "busybox /a/path/to/applet args..." too. Allows for + * "#!/bin/busybox"-style wrappers */ + applet_name = bb_get_last_path_component_nostrip(argv[0]); + run_applet_and_exit(applet_name, argv); + + /*bb_error_msg_and_die("applet not found"); - sucks in printf */ + full_write2_str(applet_name); + full_write2_str(": applet not found\n"); + /* POSIX: "If a command is not found, the exit status shall be 127" */ + exit(127); +} diff --git a/scripts/trylink b/scripts/trylink index 129570a..daa8c1f 100755 --- a/scripts/trylink +++ b/scripts/trylink @@ -269,26 +269,6 @@ if test "$CONFIG_BUILD_LIBBUSYBOX" = y; then echo "libbusybox: $sharedlib_dir/libbusybox.so.$BB_VER" fi -if test "$CONFIG_FEATURE_SHARED_BUSYBOX" = y; then - EXE="$sharedlib_dir/busybox_unstripped" - try $CC $CFLAGS $LDFLAGS \ - -o $EXE \ - $SORT_COMMON \ - $SORT_SECTION \ - $GC_SECTIONS \ - $START_GROUP $O_FILES $END_GROUP \ - -L"$sharedlib_dir" -lbusybox \ - $l_list \ - $INFO_OPTS \ - || { - echo "Linking $EXE failed" - cat $EXE.out - exit 1 - } - $STRIP -s --remove-section=.note --remove-section=.comment $EXE -o "$sharedlib_dir/busybox" - echo "busybox linked against libbusybox: $sharedlib_dir/busybox" -fi - if test "$CONFIG_FEATURE_INDIVIDUAL" = y; then echo "Linking individual applets against libbusybox (see $sharedlib_dir/*)" gcc -DNAME_MAIN -E -include include/autoconf.h include/applets.h \ -- 2.5.5 _______________________________________________ busybox mailing list [email protected] http://lists.busybox.net/mailman/listinfo/busybox
