aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore5
-rw-r--r--archival/libarchive/Kbuild.src1
-rw-r--r--include/.gitignore1
-rw-r--r--shell/Kbuild.src10
-rw-r--r--shell/ash.c140
-rwxr-xr-xshell/embedded_scripts62
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#
59tags 59tags
60TAGS 60TAGS
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.
91lib-$(CONFIG_FEATURE_SEAMLESS_XZ) += open_transformer.o decompress_unxz.o 91lib-$(CONFIG_FEATURE_SEAMLESS_XZ) += open_transformer.o decompress_unxz.o
92lib-$(CONFIG_FEATURE_COMPRESS_USAGE) += open_transformer.o decompress_bunzip2.o 92lib-$(CONFIG_FEATURE_COMPRESS_USAGE) += open_transformer.o decompress_bunzip2.o
93lib-$(CONFIG_FEATURE_COMPRESS_BBCONFIG) += open_transformer.o decompress_bunzip2.o 93lib-$(CONFIG_FEATURE_COMPRESS_BBCONFIG) += open_transformer.o decompress_bunzip2.o
94lib-$(CONFIG_ASH_EMBEDDED_SCRIPTS) += open_transformer.o decompress_bunzip2.o
94 95
95ifneq ($(lib-y),) 96ifneq ($(lib-y),)
96lib-y += $(COMMON_FILES) 97lib-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
11lib-$(CONFIG_FEATURE_SH_MATH) += math.o 11lib-$(CONFIG_FEATURE_SH_MATH) += math.o
12lib-$(CONFIG_FEATURE_PRNG_SHELL) += random.o 12lib-$(CONFIG_FEATURE_PRNG_SHELL) += random.o
13
14quiet_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
17ifdef CONFIG_ASH_EMBEDDED_SCRIPTS
18shell/ash.o: include/embedded_scripts.h
19endif
20
21include/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
238static 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"
11525static 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
11554static char *
11555check_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
11581static void
11582alias_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
3target="$1"
4loc="$2"
5
6test "$target" || exit 1
7test "$SED" || SED=sed
8test "$DD" || DD=dd
9
10# Some people were bitten by their system lacking a (proper) od
11od -v -b </dev/null >/dev/null
12if test $? != 0; then
13 echo 'od tool is not installed or cannot accept "-v -b" options'
14 exit 1
15fi
16
17exec >"$target.$$"
18
19scripts=""
20if [ -d "$loc" ]
21then
22 scripts=$(cd $loc; ls * 2>/dev/null)
23fi
24
25n=$(echo $scripts | wc -w)
26
27if [ $n -ne 0 ]
28then
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'
35fi
36printf "#define NUM_SCRIPTS $n\n\n"
37
38if [ $n -ne 0 ]
39then
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'
60fi
61
62mv -- "$target.$$" "$target"