diff options
-rw-r--r-- | .gitignore | 5 | ||||
-rw-r--r-- | archival/libarchive/Kbuild.src | 1 | ||||
-rw-r--r-- | include/.gitignore | 1 | ||||
-rw-r--r-- | shell/Kbuild.src | 10 | ||||
-rw-r--r-- | shell/ash.c | 140 | ||||
-rwxr-xr-x | shell/embedded_scripts | 62 |
6 files changed, 218 insertions, 1 deletions
diff --git a/.gitignore b/.gitignore index 517e750c1..cc485189e 100644 --- a/.gitignore +++ b/.gitignore | |||
@@ -58,3 +58,8 @@ cscope.po.out | |||
58 | # | 58 | # |
59 | tags | 59 | tags |
60 | TAGS | 60 | TAGS |
61 | |||
62 | # | ||
63 | # user-supplied scripts | ||
64 | # | ||
65 | /embed | ||
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/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/shell/Kbuild.src b/shell/Kbuild.src index a287fce4e..34dd93d48 100644 --- a/shell/Kbuild.src +++ b/shell/Kbuild.src | |||
@@ -10,3 +10,13 @@ INSERT | |||
10 | 10 | ||
11 | lib-$(CONFIG_FEATURE_SH_MATH) += math.o | 11 | lib-$(CONFIG_FEATURE_SH_MATH) += math.o |
12 | lib-$(CONFIG_FEATURE_PRNG_SHELL) += random.o | 12 | lib-$(CONFIG_FEATURE_PRNG_SHELL) += random.o |
13 | |||
14 | quiet_cmd_gen_embedded_scripts = GEN include/embedded_scripts.h | ||
15 | cmd_gen_embedded_scripts = $(srctree_slash)shell/embedded_scripts include/embedded_scripts.h embed | ||
16 | |||
17 | ifdef CONFIG_ASH_EMBEDDED_SCRIPTS | ||
18 | shell/ash.o: include/embedded_scripts.h | ||
19 | endif | ||
20 | |||
21 | include/embedded_scripts.h: $(wildcard embed/*) shell/embedded_scripts | ||
22 | $(call cmd,gen_embedded_scripts) | ||
diff --git a/shell/ash.c b/shell/ash.c index 7131609e4..9d7ef032c 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -175,6 +175,25 @@ | |||
175 | //config: from a GUI application. Disable this if your platform doesn't | 175 | //config: from a GUI application. Disable this if your platform doesn't |
176 | //config: support the required APIs. | 176 | //config: support the required APIs. |
177 | //config: | 177 | //config: |
178 | //config:config ASH_EMBEDDED_SCRIPTS | ||
179 | //config: bool "Embed scripts in the binary" | ||
180 | //config: default n | ||
181 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH | ||
182 | //config: help | ||
183 | //config: Allow scripts to be compressed and embedded in the BusyBox | ||
184 | //config: binary. The scripts should be placed in the 'embed' directory. | ||
185 | //config: Such scripts can only be run by giving their name as an | ||
186 | //config: argument to the shell, though aliases are set up to do this. | ||
187 | //config: The names of the scripts are listed by the '-L' shell argument. | ||
188 | //config: | ||
189 | //config:config ASH_LIST_EMBEDDED_SCRIPTS | ||
190 | //config: bool "Allow the contents of embedded scripts to be listed" | ||
191 | //config: default n | ||
192 | //config: depends on ASH_EMBEDDED_SCRIPTS | ||
193 | //config: help | ||
194 | //config: Allow the contents of embedded script to be listed using | ||
195 | //config: the '-L name' shell argument. | ||
196 | //config: | ||
178 | //config:endif # ash options | 197 | //config:endif # ash options |
179 | 198 | ||
180 | //applet:IF_ASH(APPLET(ash, BB_DIR_BIN, BB_SUID_DROP)) | 199 | //applet:IF_ASH(APPLET(ash, BB_DIR_BIN, BB_SUID_DROP)) |
@@ -209,6 +228,16 @@ | |||
209 | #include <sys/utsname.h> /* for setting $HOSTNAME */ | 228 | #include <sys/utsname.h> /* for setting $HOSTNAME */ |
210 | #include "busybox.h" /* for applet_names */ | 229 | #include "busybox.h" /* for applet_names */ |
211 | 230 | ||
231 | #if ENABLE_ASH_EMBEDDED_SCRIPTS | ||
232 | #include "embedded_scripts.h" | ||
233 | #else | ||
234 | #define NUM_SCRIPTS 0 | ||
235 | #endif | ||
236 | |||
237 | #if NUM_SCRIPTS | ||
238 | static const char packed_scripts[] ALIGN1 = { PACKED_SCRIPTS }; | ||
239 | #endif | ||
240 | |||
212 | /* So far, all bash compat is controlled by one config option */ | 241 | /* So far, all bash compat is controlled by one config option */ |
213 | /* Separate defines document which part of code implements what */ | 242 | /* Separate defines document which part of code implements what */ |
214 | /* function keyword */ | 243 | /* function keyword */ |
@@ -11490,6 +11519,76 @@ setparam(char **argv) | |||
11490 | #endif | 11519 | #endif |
11491 | } | 11520 | } |
11492 | 11521 | ||
11522 | #if NUM_SCRIPTS | ||
11523 | #define BB_ARCHIVE_PUBLIC | ||
11524 | # include "bb_archive.h" | ||
11525 | static char *unpack_scripts(void) | ||
11526 | { | ||
11527 | char *outbuf = NULL; | ||
11528 | bunzip_data *bd; | ||
11529 | int i; | ||
11530 | jmp_buf jmpbuf; | ||
11531 | |||
11532 | /* Setup for I/O error handling via longjmp */ | ||
11533 | i = setjmp(jmpbuf); | ||
11534 | if (i == 0) { | ||
11535 | i = start_bunzip(&jmpbuf, | ||
11536 | &bd, | ||
11537 | /* src_fd: */ -1, | ||
11538 | /* inbuf: */ packed_scripts, | ||
11539 | /* len: */ sizeof(packed_scripts) | ||
11540 | ); | ||
11541 | } | ||
11542 | /* read_bunzip can longjmp and end up here with i != 0 | ||
11543 | * on read data errors! Not trivial */ | ||
11544 | if (i == 0) { | ||
11545 | /* Cannot use xmalloc: will leak bd in NOFORK case! */ | ||
11546 | outbuf = malloc_or_warn(UNPACKED_SCRIPTS_LENGTH); | ||
11547 | if (outbuf) | ||
11548 | read_bunzip(bd, outbuf, UNPACKED_SCRIPTS_LENGTH); | ||
11549 | } | ||
11550 | dealloc_bunzip(bd); | ||
11551 | return outbuf; | ||
11552 | } | ||
11553 | |||
11554 | static char * | ||
11555 | check_embedded(const char *arg) | ||
11556 | { | ||
11557 | int i; | ||
11558 | char *scripts; | ||
11559 | const char *s; | ||
11560 | |||
11561 | i = 0; | ||
11562 | for (s=script_names; *s; s+=strlen(s)+1) { | ||
11563 | if (strcmp(arg, s) == 0) { | ||
11564 | break; | ||
11565 | } | ||
11566 | ++i; | ||
11567 | } | ||
11568 | |||
11569 | if (i != NUM_SCRIPTS && (scripts=unpack_scripts()) != NULL) { | ||
11570 | char *t = scripts; | ||
11571 | while (i != 0) { | ||
11572 | t += strlen(t) + 1; | ||
11573 | --i; | ||
11574 | } | ||
11575 | return t; | ||
11576 | } | ||
11577 | |||
11578 | return NULL; | ||
11579 | } | ||
11580 | |||
11581 | static void | ||
11582 | alias_embedded(void) | ||
11583 | { | ||
11584 | const char *s; | ||
11585 | |||
11586 | for (s=script_names; *s; s+=strlen(s)+1) { | ||
11587 | setalias(s, auto_string(xasprintf("sh %s", s))); | ||
11588 | } | ||
11589 | } | ||
11590 | #endif | ||
11591 | |||
11493 | /* | 11592 | /* |
11494 | * Process shell options. The global variable argptr contains a pointer | 11593 | * Process shell options. The global variable argptr contains a pointer |
11495 | * to the argument list; we advance it past the options. | 11594 | * to the argument list; we advance it past the options. |
@@ -11600,6 +11699,26 @@ options(int cmdline, int *login_sh) | |||
11600 | *login_sh = 1; | 11699 | *login_sh = 1; |
11601 | } | 11700 | } |
11602 | break; | 11701 | break; |
11702 | #if NUM_SCRIPTS | ||
11703 | } else if (cmdline && (c == 'L')) { | ||
11704 | #if ENABLE_ASH_LIST_EMBEDDED_SCRIPTS | ||
11705 | if (*argptr) { | ||
11706 | char *script; | ||
11707 | |||
11708 | if ((script=check_embedded(*argptr)) != NULL) { | ||
11709 | printf(script); | ||
11710 | } | ||
11711 | } else | ||
11712 | #endif | ||
11713 | { | ||
11714 | const char *s; | ||
11715 | |||
11716 | for (s=script_names; *s; s+=strlen(s)+1) { | ||
11717 | printf("%s\n", s); | ||
11718 | } | ||
11719 | } | ||
11720 | exit(0); | ||
11721 | #endif | ||
11603 | } else { | 11722 | } else { |
11604 | setoption(c, val); | 11723 | setoption(c, val); |
11605 | } | 11724 | } |
@@ -14643,9 +14762,17 @@ init(void) | |||
14643 | } | 14762 | } |
14644 | } | 14763 | } |
14645 | 14764 | ||
14646 | |||
14647 | //usage:#define ash_trivial_usage | 14765 | //usage:#define ash_trivial_usage |
14648 | //usage: "[-/+OPTIONS] [-/+o OPT]... [-c 'SCRIPT' [ARG0 [ARGS]] / FILE [ARGS] / -s [ARGS]]" | 14766 | //usage: "[-/+OPTIONS] [-/+o OPT]... [-c 'SCRIPT' [ARG0 [ARGS]] / FILE [ARGS] / -s [ARGS]]" |
14767 | //usage: IF_ASH_EMBEDDED_SCRIPTS( | ||
14768 | //usage: " [-L" | ||
14769 | //usage: ) | ||
14770 | //usage: IF_ASH_LIST_EMBEDDED_SCRIPTS( | ||
14771 | //usage: " [name]" | ||
14772 | //usage: ) | ||
14773 | //usage: IF_ASH_EMBEDDED_SCRIPTS( | ||
14774 | //usage: "]" | ||
14775 | //usage: ) | ||
14649 | //usage:#define ash_full_usage "\n\n" | 14776 | //usage:#define ash_full_usage "\n\n" |
14650 | //usage: "Unix shell interpreter" | 14777 | //usage: "Unix shell interpreter" |
14651 | 14778 | ||
@@ -14689,12 +14816,23 @@ procargs(char **argv) | |||
14689 | #if DEBUG == 2 | 14816 | #if DEBUG == 2 |
14690 | debug = 1; | 14817 | debug = 1; |
14691 | #endif | 14818 | #endif |
14819 | #if NUM_SCRIPTS | ||
14820 | alias_embedded(); | ||
14821 | #endif | ||
14692 | /* POSIX 1003.2: first arg after "-c CMD" is $0, remainder $1... */ | 14822 | /* POSIX 1003.2: first arg after "-c CMD" is $0, remainder $1... */ |
14693 | if (xminusc) { | 14823 | if (xminusc) { |
14694 | minusc = *xargv++; | 14824 | minusc = *xargv++; |
14695 | if (*xargv) | 14825 | if (*xargv) |
14696 | goto setarg0; | 14826 | goto setarg0; |
14697 | } else if (!sflag) { | 14827 | } else if (!sflag) { |
14828 | #if NUM_SCRIPTS | ||
14829 | char *script; | ||
14830 | if ((script=check_embedded(*xargv)) != NULL) { | ||
14831 | setinputstring(script); | ||
14832 | xflag = 0; | ||
14833 | goto setarg0; | ||
14834 | } | ||
14835 | #endif | ||
14698 | setinputfile(*xargv, 0); | 14836 | setinputfile(*xargv, 0); |
14699 | #if ENABLE_PLATFORM_MINGW32 | 14837 | #if ENABLE_PLATFORM_MINGW32 |
14700 | convert_slashes(*xargv); | 14838 | convert_slashes(*xargv); |
diff --git a/shell/embedded_scripts b/shell/embedded_scripts new file mode 100755 index 000000000..0ca89b91e --- /dev/null +++ b/shell/embedded_scripts | |||
@@ -0,0 +1,62 @@ | |||
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 'static const char script_names[] ALIGN1 = ' | ||
30 | for i in $scripts | ||
31 | do | ||
32 | printf '"%s\\0"' $i | ||
33 | done | ||
34 | printf '"\\0";\n' | ||
35 | fi | ||
36 | printf "#define NUM_SCRIPTS $n\n\n" | ||
37 | |||
38 | if [ $n -ne 0 ] | ||
39 | then | ||
40 | printf '#define UNPACKED_SCRIPTS_LENGTH ' | ||
41 | for i in $scripts | ||
42 | do | ||
43 | cat $loc/$i | ||
44 | printf '\000' | ||
45 | done | wc -c | ||
46 | |||
47 | printf '#define PACKED_SCRIPTS \\\n' | ||
48 | for i in $scripts | ||
49 | do | ||
50 | cat $loc/$i | ||
51 | printf '\000' | ||
52 | done | bzip2 -1 | $DD bs=2 skip=1 2>/dev/null | od -v -b \ | ||
53 | | grep -v '^ ' \ | ||
54 | | $SED -e 's/^[^ ]*//' \ | ||
55 | -e 's/ //g' \ | ||
56 | -e '/^$/d' \ | ||
57 | -e 's/\(...\)/0\1,/g' \ | ||
58 | -e 's/$/ \\/' | ||
59 | printf '\n' | ||
60 | fi | ||
61 | |||
62 | mv -- "$target.$$" "$target" | ||