diff options
-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | archival/libarchive/Kbuild.src | 1 | ||||
-rwxr-xr-x | embed/nologin (renamed from applets_sh/nologin) | 0 | ||||
-rw-r--r-- | include/.gitignore | 1 | ||||
-rw-r--r-- | include/libbb.h | 8 | ||||
-rw-r--r-- | libbb/appletlib.c | 83 | ||||
-rw-r--r-- | libbb/lineedit.c | 6 | ||||
-rwxr-xr-x | scripts/embedded_scripts | 66 | ||||
-rw-r--r-- | shell/ash.c | 33 |
9 files changed, 201 insertions, 3 deletions
@@ -850,11 +850,14 @@ quiet_cmd_gen_common_bufsiz = GEN include/common_bufsiz.h | |||
850 | cmd_gen_common_bufsiz = $(srctree)/scripts/generate_BUFSIZ.sh include/common_bufsiz.h | 850 | cmd_gen_common_bufsiz = $(srctree)/scripts/generate_BUFSIZ.sh include/common_bufsiz.h |
851 | quiet_cmd_split_autoconf = SPLIT include/autoconf.h -> include/config/* | 851 | quiet_cmd_split_autoconf = SPLIT include/autoconf.h -> include/config/* |
852 | cmd_split_autoconf = scripts/basic/split-include include/autoconf.h include/config | 852 | cmd_split_autoconf = scripts/basic/split-include include/autoconf.h include/config |
853 | quiet_cmd_gen_embedded_scripts = GEN include/embedded_scripts.h | ||
854 | cmd_gen_embedded_scripts = scripts/embedded_scripts include/embedded_scripts.h embed | ||
853 | #bbox# piggybacked generation of few .h files | 855 | #bbox# piggybacked generation of few .h files |
854 | include/config/MARKER: scripts/basic/split-include include/autoconf.h | 856 | include/config/MARKER: scripts/basic/split-include include/autoconf.h $(wildcard embed/*) scripts/embedded_scripts |
855 | $(call cmd,split_autoconf) | 857 | $(call cmd,split_autoconf) |
856 | $(call cmd,gen_bbconfigopts) | 858 | $(call cmd,gen_bbconfigopts) |
857 | $(call cmd,gen_common_bufsiz) | 859 | $(call cmd,gen_common_bufsiz) |
860 | $(call cmd,gen_embedded_scripts) | ||
858 | @touch $@ | 861 | @touch $@ |
859 | 862 | ||
860 | # Generate some files | 863 | # Generate some files |
@@ -974,6 +977,7 @@ MRPROPER_FILES += .config .config.old include/asm .version .old_version \ | |||
974 | include/autoconf.h \ | 977 | include/autoconf.h \ |
975 | include/bbconfigopts.h \ | 978 | include/bbconfigopts.h \ |
976 | include/bbconfigopts_bz2.h \ | 979 | include/bbconfigopts_bz2.h \ |
980 | include/embedded_scripts.h \ | ||
977 | include/usage_compressed.h \ | 981 | include/usage_compressed.h \ |
978 | include/applet_tables.h \ | 982 | include/applet_tables.h \ |
979 | include/applets.h \ | 983 | include/applets.h \ |
diff --git a/archival/libarchive/Kbuild.src b/archival/libarchive/Kbuild.src index e1a8a7529..12e66a88b 100644 --- a/archival/libarchive/Kbuild.src +++ b/archival/libarchive/Kbuild.src | |||
@@ -91,6 +91,7 @@ lib-$(CONFIG_FEATURE_SEAMLESS_LZMA) += open_transformer.o decompress_unlzma. | |||
91 | lib-$(CONFIG_FEATURE_SEAMLESS_XZ) += open_transformer.o decompress_unxz.o | 91 | lib-$(CONFIG_FEATURE_SEAMLESS_XZ) += open_transformer.o decompress_unxz.o |
92 | lib-$(CONFIG_FEATURE_COMPRESS_USAGE) += open_transformer.o decompress_bunzip2.o | 92 | lib-$(CONFIG_FEATURE_COMPRESS_USAGE) += open_transformer.o decompress_bunzip2.o |
93 | lib-$(CONFIG_FEATURE_COMPRESS_BBCONFIG) += open_transformer.o decompress_bunzip2.o | 93 | lib-$(CONFIG_FEATURE_COMPRESS_BBCONFIG) += open_transformer.o decompress_bunzip2.o |
94 | lib-$(CONFIG_ASH_EMBEDDED_SCRIPTS) += open_transformer.o decompress_bunzip2.o | ||
94 | 95 | ||
95 | ifneq ($(lib-y),) | 96 | ifneq ($(lib-y),) |
96 | lib-y += $(COMMON_FILES) | 97 | lib-y += $(COMMON_FILES) |
diff --git a/applets_sh/nologin b/embed/nologin index 3768eaaa7..3768eaaa7 100755 --- a/applets_sh/nologin +++ b/embed/nologin | |||
diff --git a/include/.gitignore b/include/.gitignore index 75afff9ca..13a96e018 100644 --- a/include/.gitignore +++ b/include/.gitignore | |||
@@ -5,6 +5,7 @@ | |||
5 | /autoconf.h | 5 | /autoconf.h |
6 | /bbconfigopts_bz2.h | 6 | /bbconfigopts_bz2.h |
7 | /bbconfigopts.h | 7 | /bbconfigopts.h |
8 | /embedded_scripts.h | ||
8 | /NUM_APPLETS.h | 9 | /NUM_APPLETS.h |
9 | /usage_compressed.h | 10 | /usage_compressed.h |
10 | /usage.h | 11 | /usage.h |
diff --git a/include/libbb.h b/include/libbb.h index 140404ff5..affff5874 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -1321,9 +1321,17 @@ void bb_logenv_override(void) FAST_FUNC; | |||
1321 | #define MAIN_EXTERNALLY_VISIBLE | 1321 | #define MAIN_EXTERNALLY_VISIBLE |
1322 | #endif | 1322 | #endif |
1323 | 1323 | ||
1324 | /* Embedded script support */ | ||
1325 | //int find_script_by_name(const char *arg IF_FEATURE_SH_STANDALONE(, int offset)) FAST_FUNC; | ||
1326 | char *get_script_content(unsigned n) FAST_FUNC; | ||
1324 | 1327 | ||
1325 | /* Applets which are useful from another applets */ | 1328 | /* Applets which are useful from another applets */ |
1326 | int bb_cat(char** argv) FAST_FUNC; | 1329 | int bb_cat(char** argv) FAST_FUNC; |
1330 | int ash_main(int argc, char** argv) | ||
1331 | #if ENABLE_ASH || ENABLE_SH_IS_ASH || ENABLE_BASH_IS_ASH | ||
1332 | MAIN_EXTERNALLY_VISIBLE | ||
1333 | #endif | ||
1334 | ; | ||
1327 | /* If shell needs them, they exist even if not enabled as applets */ | 1335 | /* If shell needs them, they exist even if not enabled as applets */ |
1328 | int echo_main(int argc, char** argv) IF_ECHO(MAIN_EXTERNALLY_VISIBLE); | 1336 | int echo_main(int argc, char** argv) IF_ECHO(MAIN_EXTERNALLY_VISIBLE); |
1329 | int printf_main(int argc, char **argv) IF_PRINTF(MAIN_EXTERNALLY_VISIBLE); | 1337 | int printf_main(int argc, char **argv) IF_PRINTF(MAIN_EXTERNALLY_VISIBLE); |
diff --git a/libbb/appletlib.c b/libbb/appletlib.c index 319bcc263..08720082e 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c | |||
@@ -50,6 +50,16 @@ | |||
50 | 50 | ||
51 | #include "usage_compressed.h" | 51 | #include "usage_compressed.h" |
52 | 52 | ||
53 | #if ENABLE_ASH_EMBEDDED_SCRIPTS | ||
54 | # define DEFINE_script_names 1 | ||
55 | # include "embedded_scripts.h" | ||
56 | #else | ||
57 | # define NUM_SCRIPTS 0 | ||
58 | #endif | ||
59 | #if NUM_SCRIPTS > 0 | ||
60 | # include "bb_archive.h" | ||
61 | static const char packed_scripts[] ALIGN1 = { PACKED_SCRIPTS }; | ||
62 | #endif | ||
53 | 63 | ||
54 | /* "Do not compress usage text if uncompressed text is small | 64 | /* "Do not compress usage text if uncompressed text is small |
55 | * and we don't include bunzip2 code for other reasons" | 65 | * and we don't include bunzip2 code for other reasons" |
@@ -953,7 +963,71 @@ void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **ar | |||
953 | } | 963 | } |
954 | # endif /* NUM_APPLETS > 0 */ | 964 | # endif /* NUM_APPLETS > 0 */ |
955 | 965 | ||
956 | # if ENABLE_BUSYBOX || NUM_APPLETS > 0 | 966 | # if NUM_SCRIPTS > 0 |
967 | static char * | ||
968 | unpack_scripts(void) | ||
969 | { | ||
970 | char *outbuf = NULL; | ||
971 | bunzip_data *bd; | ||
972 | int i; | ||
973 | jmp_buf jmpbuf; | ||
974 | |||
975 | /* Setup for I/O error handling via longjmp */ | ||
976 | i = setjmp(jmpbuf); | ||
977 | if (i == 0) { | ||
978 | i = start_bunzip(&jmpbuf, | ||
979 | &bd, | ||
980 | /* src_fd: */ -1, | ||
981 | /* inbuf: */ packed_scripts, | ||
982 | /* len: */ sizeof(packed_scripts) | ||
983 | ); | ||
984 | } | ||
985 | /* read_bunzip can longjmp and end up here with i != 0 | ||
986 | * on read data errors! Not trivial */ | ||
987 | if (i == 0) { | ||
988 | outbuf = xmalloc(UNPACKED_SCRIPTS_LENGTH); | ||
989 | read_bunzip(bd, outbuf, UNPACKED_SCRIPTS_LENGTH); | ||
990 | } | ||
991 | dealloc_bunzip(bd); | ||
992 | return outbuf; | ||
993 | } | ||
994 | |||
995 | /* | ||
996 | * In standalone shell mode we sometimes want the index of the script | ||
997 | * and sometimes the index offset by NUM_APPLETS. | ||
998 | */ | ||
999 | static int | ||
1000 | find_script_by_name(const char *arg) | ||
1001 | { | ||
1002 | const char *s = script_names; | ||
1003 | int i = 0; | ||
1004 | |||
1005 | while (*s) { | ||
1006 | if (strcmp(arg, s) == 0) | ||
1007 | return i; | ||
1008 | i++; | ||
1009 | while (*s++ != '\0') | ||
1010 | continue; | ||
1011 | } | ||
1012 | return -1; | ||
1013 | } | ||
1014 | |||
1015 | char* FAST_FUNC | ||
1016 | get_script_content(unsigned n) | ||
1017 | { | ||
1018 | char *t = unpack_scripts(); | ||
1019 | if (t) { | ||
1020 | while (n != 0) { | ||
1021 | while (*t++ != '\0') | ||
1022 | continue; | ||
1023 | n--; | ||
1024 | } | ||
1025 | } | ||
1026 | return t; | ||
1027 | } | ||
1028 | # endif /* NUM_SCRIPTS > 0 */ | ||
1029 | |||
1030 | # if ENABLE_BUSYBOX || NUM_APPLETS > 0 || NUM_SCRIPTS > 0 | ||
957 | static NORETURN void run_applet_and_exit(const char *name, char **argv) | 1031 | static NORETURN void run_applet_and_exit(const char *name, char **argv) |
958 | { | 1032 | { |
959 | # if ENABLE_BUSYBOX | 1033 | # if ENABLE_BUSYBOX |
@@ -968,6 +1042,13 @@ static NORETURN void run_applet_and_exit(const char *name, char **argv) | |||
968 | run_applet_no_and_exit(applet, name, argv); | 1042 | run_applet_no_and_exit(applet, name, argv); |
969 | } | 1043 | } |
970 | # endif | 1044 | # endif |
1045 | # if NUM_SCRIPTS > 0 | ||
1046 | { | ||
1047 | int script = find_script_by_name(name); | ||
1048 | if (script >= 0) | ||
1049 | exit(ash_main(-script - 1, argv)); | ||
1050 | } | ||
1051 | # endif | ||
971 | 1052 | ||
972 | /*bb_error_msg_and_die("applet not found"); - links in printf */ | 1053 | /*bb_error_msg_and_die("applet not found"); - links in printf */ |
973 | full_write2_str(applet_name); | 1054 | full_write2_str(applet_name); |
diff --git a/libbb/lineedit.c b/libbb/lineedit.c index b1e971f88..aef1911d9 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c | |||
@@ -41,6 +41,12 @@ | |||
41 | #include "busybox.h" | 41 | #include "busybox.h" |
42 | #include "NUM_APPLETS.h" | 42 | #include "NUM_APPLETS.h" |
43 | #include "unicode.h" | 43 | #include "unicode.h" |
44 | #if ENABLE_ASH_EMBEDDED_SCRIPTS | ||
45 | # include "embedded_scripts.h" | ||
46 | #else | ||
47 | # define NUM_SCRIPTS 0 | ||
48 | #endif | ||
49 | |||
44 | #ifndef _POSIX_VDISABLE | 50 | #ifndef _POSIX_VDISABLE |
45 | # define _POSIX_VDISABLE '\0' | 51 | # define _POSIX_VDISABLE '\0' |
46 | #endif | 52 | #endif |
diff --git a/scripts/embedded_scripts b/scripts/embedded_scripts new file mode 100755 index 000000000..986e85160 --- /dev/null +++ b/scripts/embedded_scripts | |||
@@ -0,0 +1,66 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | target="$1" | ||
4 | loc="$2" | ||
5 | |||
6 | test "$target" || exit 1 | ||
7 | test "$SED" || SED=sed | ||
8 | test "$DD" || DD=dd | ||
9 | |||
10 | # Some people were bitten by their system lacking a (proper) od | ||
11 | od -v -b </dev/null >/dev/null | ||
12 | if test $? != 0; then | ||
13 | echo 'od tool is not installed or cannot accept "-v -b" options' | ||
14 | exit 1 | ||
15 | fi | ||
16 | |||
17 | exec >"$target.$$" | ||
18 | |||
19 | scripts="" | ||
20 | if [ -d "$loc" ] | ||
21 | then | ||
22 | scripts=$(cd $loc; ls * 2>/dev/null) | ||
23 | fi | ||
24 | |||
25 | n=$(echo $scripts | wc -w) | ||
26 | |||
27 | if [ $n -ne 0 ] | ||
28 | then | ||
29 | printf '#ifdef DEFINE_script_names\n' | ||
30 | printf 'const char script_names[] ALIGN1 = ' | ||
31 | for i in $scripts | ||
32 | do | ||
33 | printf '"%s\\0"' $i | ||
34 | done | ||
35 | printf '"\\0";\n' | ||
36 | printf '#else\n' | ||
37 | printf 'extern const char script_names[] ALIGN1;\n' | ||
38 | printf '#endif\n' | ||
39 | fi | ||
40 | printf "#define NUM_SCRIPTS $n\n\n" | ||
41 | |||
42 | if [ $n -ne 0 ] | ||
43 | then | ||
44 | printf '#define UNPACKED_SCRIPTS_LENGTH ' | ||
45 | for i in $scripts | ||
46 | do | ||
47 | cat $loc/$i | ||
48 | printf '\000' | ||
49 | done | wc -c | ||
50 | |||
51 | printf '#define PACKED_SCRIPTS \\\n' | ||
52 | for i in $scripts | ||
53 | do | ||
54 | cat $loc/$i | ||
55 | printf '\000' | ||
56 | done | bzip2 -1 | $DD bs=2 skip=1 2>/dev/null | od -v -b \ | ||
57 | | grep -v '^ ' \ | ||
58 | | $SED -e 's/^[^ ]*//' \ | ||
59 | -e 's/ //g' \ | ||
60 | -e '/^$/d' \ | ||
61 | -e 's/\(...\)/0\1,/g' \ | ||
62 | -e 's/$/ \\/' | ||
63 | printf '\n' | ||
64 | fi | ||
65 | |||
66 | mv -- "$target.$$" "$target" | ||
diff --git a/shell/ash.c b/shell/ash.c index dc1a55a6b..25468d796 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -148,6 +148,21 @@ | |||
148 | //config: you to run the specified command or builtin, | 148 | //config: you to run the specified command or builtin, |
149 | //config: even when there is a function with the same name. | 149 | //config: even when there is a function with the same name. |
150 | //config: | 150 | //config: |
151 | //config:config ASH_EMBEDDED_SCRIPTS | ||
152 | //config: bool "Embed scripts in the binary" | ||
153 | //config: default y | ||
154 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH | ||
155 | //config: help | ||
156 | //config: Allow scripts to be compressed and embedded in the BusyBox | ||
157 | //config: binary. The scripts should be placed in the 'embed' directory | ||
158 | //config: at build time. In standalone shell mode such scripts can be | ||
159 | //config: run directly and are subject to tab completion; otherwise they | ||
160 | //config: can be run by giving their name as an argument to the shell. | ||
161 | //config: For convenience shell aliases are created. The '-L' shell | ||
162 | //config: argument lists the names of the scripts. Like applets scripts | ||
163 | //config: can be run as 'busybox name ...' or by linking their name to | ||
164 | //config: the binary. | ||
165 | //config: | ||
151 | //config:endif # ash options | 166 | //config:endif # ash options |
152 | 167 | ||
153 | //applet:IF_ASH(APPLET(ash, BB_DIR_BIN, BB_SUID_DROP)) | 168 | //applet:IF_ASH(APPLET(ash, BB_DIR_BIN, BB_SUID_DROP)) |
@@ -181,6 +196,11 @@ | |||
181 | #include <sys/times.h> | 196 | #include <sys/times.h> |
182 | #include <sys/utsname.h> /* for setting $HOSTNAME */ | 197 | #include <sys/utsname.h> /* for setting $HOSTNAME */ |
183 | #include "busybox.h" /* for applet_names */ | 198 | #include "busybox.h" /* for applet_names */ |
199 | #if ENABLE_ASH_EMBEDDED_SCRIPTS | ||
200 | # include "embedded_scripts.h" | ||
201 | #else | ||
202 | # define NUM_SCRIPTS 0 | ||
203 | #endif | ||
184 | 204 | ||
185 | /* So far, all bash compat is controlled by one config option */ | 205 | /* So far, all bash compat is controlled by one config option */ |
186 | /* Separate defines document which part of code implements what */ | 206 | /* Separate defines document which part of code implements what */ |
@@ -14021,13 +14041,17 @@ procargs(char **argv) | |||
14021 | int login_sh; | 14041 | int login_sh; |
14022 | 14042 | ||
14023 | xargv = argv; | 14043 | xargv = argv; |
14044 | #if NUM_SCRIPTS > 0 | ||
14045 | if (minusc) | ||
14046 | goto setarg0; | ||
14047 | #endif | ||
14024 | login_sh = xargv[0] && xargv[0][0] == '-'; | 14048 | login_sh = xargv[0] && xargv[0][0] == '-'; |
14025 | arg0 = xargv[0]; | 14049 | arg0 = xargv[0]; |
14026 | /* if (xargv[0]) - mmm, this is always true! */ | 14050 | /* if (xargv[0]) - mmm, this is always true! */ |
14027 | xargv++; | 14051 | xargv++; |
14052 | argptr = xargv; | ||
14028 | for (i = 0; i < NOPTS; i++) | 14053 | for (i = 0; i < NOPTS; i++) |
14029 | optlist[i] = 2; | 14054 | optlist[i] = 2; |
14030 | argptr = xargv; | ||
14031 | if (options(/*cmdline:*/ 1, &login_sh)) { | 14055 | if (options(/*cmdline:*/ 1, &login_sh)) { |
14032 | /* it already printed err message */ | 14056 | /* it already printed err message */ |
14033 | raise_exception(EXERROR); | 14057 | raise_exception(EXERROR); |
@@ -14130,6 +14154,7 @@ extern int etext(); | |||
14130 | */ | 14154 | */ |
14131 | int ash_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 14155 | int ash_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
14132 | int ash_main(int argc UNUSED_PARAM, char **argv) | 14156 | int ash_main(int argc UNUSED_PARAM, char **argv) |
14157 | /* note: 'argc' is used only if embedded scripts are enabled */ | ||
14133 | { | 14158 | { |
14134 | volatile smallint state; | 14159 | volatile smallint state; |
14135 | struct jmploc jmploc; | 14160 | struct jmploc jmploc; |
@@ -14183,6 +14208,12 @@ int ash_main(int argc UNUSED_PARAM, char **argv) | |||
14183 | 14208 | ||
14184 | init(); | 14209 | init(); |
14185 | setstackmark(&smark); | 14210 | setstackmark(&smark); |
14211 | |||
14212 | #if NUM_SCRIPTS > 0 | ||
14213 | if (argc < 0) | ||
14214 | /* Non-NULL minusc tells procargs that an embedded script is being run */ | ||
14215 | minusc = get_script_content(-argc - 1); | ||
14216 | #endif | ||
14186 | login_sh = procargs(argv); | 14217 | login_sh = procargs(argv); |
14187 | #if DEBUG | 14218 | #if DEBUG |
14188 | TRACE(("Shell args: ")); | 14219 | TRACE(("Shell args: ")); |