diff options
Diffstat (limited to '')
-rw-r--r-- | shell/ash.c | 140 |
1 files changed, 139 insertions, 1 deletions
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); |