aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile6
-rw-r--r--archival/libarchive/Kbuild.src1
-rwxr-xr-xembed/nologin (renamed from applets_sh/nologin)0
-rw-r--r--include/.gitignore1
-rw-r--r--include/libbb.h8
-rw-r--r--libbb/appletlib.c83
-rw-r--r--libbb/lineedit.c6
-rwxr-xr-xscripts/embedded_scripts66
-rw-r--r--shell/ash.c33
9 files changed, 201 insertions, 3 deletions
diff --git a/Makefile b/Makefile
index 59ec83a6a..8a0dbdf49 100644
--- a/Makefile
+++ b/Makefile
@@ -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
851quiet_cmd_split_autoconf = SPLIT include/autoconf.h -> include/config/* 851quiet_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
853quiet_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
854include/config/MARKER: scripts/basic/split-include include/autoconf.h 856include/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.
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/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;
1326char *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 */
1326int bb_cat(char** argv) FAST_FUNC; 1329int bb_cat(char** argv) FAST_FUNC;
1330int 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 */
1328int echo_main(int argc, char** argv) IF_ECHO(MAIN_EXTERNALLY_VISIBLE); 1336int echo_main(int argc, char** argv) IF_ECHO(MAIN_EXTERNALLY_VISIBLE);
1329int printf_main(int argc, char **argv) IF_PRINTF(MAIN_EXTERNALLY_VISIBLE); 1337int 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"
61static 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
967static char *
968unpack_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 */
999static int
1000find_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
1015char* FAST_FUNC
1016get_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
957static NORETURN void run_applet_and_exit(const char *name, char **argv) 1031static 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
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 '#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'
39fi
40printf "#define NUM_SCRIPTS $n\n\n"
41
42if [ $n -ne 0 ]
43then
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'
64fi
65
66mv -- "$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 */
14131int ash_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 14155int ash_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
14132int ash_main(int argc UNUSED_PARAM, char **argv) 14156int 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: "));