hush: allow hush to run embedded scripts
Embedded scripts require a shell to be present in the BusyBox binary. Allow either ash or hush to be used for this purpose. If both are enabled ash takes precedence. The size of the binary is unchanged in the default configuration: both ash and hush are present but support for embedded scripts isn't compiled into hush. Signed-off-by: Ron Yorston <rmy@pobox.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
f4709d78cb
commit
71df2d3589
@ -91,7 +91,7 @@ lib-$(CONFIG_FEATURE_SEAMLESS_LZMA) += open_transformer.o decompress_unlzma.
|
|||||||
lib-$(CONFIG_FEATURE_SEAMLESS_XZ) += open_transformer.o decompress_unxz.o
|
lib-$(CONFIG_FEATURE_SEAMLESS_XZ) += open_transformer.o decompress_unxz.o
|
||||||
lib-$(CONFIG_FEATURE_COMPRESS_USAGE) += open_transformer.o decompress_bunzip2.o
|
lib-$(CONFIG_FEATURE_COMPRESS_USAGE) += open_transformer.o decompress_bunzip2.o
|
||||||
lib-$(CONFIG_FEATURE_COMPRESS_BBCONFIG) += open_transformer.o decompress_bunzip2.o
|
lib-$(CONFIG_FEATURE_COMPRESS_BBCONFIG) += open_transformer.o decompress_bunzip2.o
|
||||||
lib-$(CONFIG_ASH_EMBEDDED_SCRIPTS) += open_transformer.o decompress_bunzip2.o
|
lib-$(CONFIG_FEATURE_SH_EMBEDDED_SCRIPTS) += open_transformer.o decompress_bunzip2.o
|
||||||
|
|
||||||
ifneq ($(lib-y),)
|
ifneq ($(lib-y),)
|
||||||
lib-y += $(COMMON_FILES)
|
lib-y += $(COMMON_FILES)
|
||||||
|
@ -3,13 +3,9 @@ Embedded Shell Scripts in BusyBox
|
|||||||
|
|
||||||
BusyBox allows applets to be implemented as shell scripts. Since
|
BusyBox allows applets to be implemented as shell scripts. Since
|
||||||
this obviously requires a shell to interpret the scripts the feature
|
this obviously requires a shell to interpret the scripts the feature
|
||||||
depends on having a shell (specifically, ash) built into the binary.
|
depends on having a shell built into the binary. Either ash or hush
|
||||||
Support for embedded scripts also has to be enabled.
|
will do. If both are present ash will be used. Support for embedded
|
||||||
|
scripts also has to be enabled.
|
||||||
To embed scripts in BusyBox you must enable these configuration options:
|
|
||||||
|
|
||||||
ASH
|
|
||||||
ASH_EMBEDDED_SCRIPTS
|
|
||||||
|
|
||||||
It's unlikely that your applet will be implemented as a pure shell
|
It's unlikely that your applet will be implemented as a pure shell
|
||||||
script: it will probably need some external commands. If these are
|
script: it will probably need some external commands. If these are
|
||||||
@ -75,10 +71,9 @@ code for the native applet:
|
|||||||
|
|
||||||
The only difference is that the applet is specified as being of type
|
The only difference is that the applet is specified as being of type
|
||||||
APPLET_SCRIPTED. It would also be useful to include details of any
|
APPLET_SCRIPTED. It would also be useful to include details of any
|
||||||
dependencies the script has. We can assume that ash is available.
|
dependencies the script has. No external commands are used by our mu
|
||||||
No external commands are used by our mu script, but it does depend on
|
script, but it does depend on optional shell features. We can ensure
|
||||||
optional shell features. We can ensure these are selected by adding
|
these are selected by adding this to the configuration:
|
||||||
this to the configuration:
|
|
||||||
|
|
||||||
//config:config MU_DEPENDENCIES
|
//config:config MU_DEPENDENCIES
|
||||||
//config: bool "Enable dependencies for mu"
|
//config: bool "Enable dependencies for mu"
|
||||||
@ -87,8 +82,8 @@ this to the configuration:
|
|||||||
//config: select ASH_RANDOM_SUPPORT
|
//config: select ASH_RANDOM_SUPPORT
|
||||||
//config: select FEATURE_SH_MATH
|
//config: select FEATURE_SH_MATH
|
||||||
//config: help
|
//config: help
|
||||||
//config: mu is implemented as a shell script. It requires ash
|
//config: mu is implemented as a shell script. It requires support
|
||||||
//config: support for $RANDOM and arithmetic.
|
//config: for $RANDOM and arithmetic.
|
||||||
|
|
||||||
The configuration data should be placed in a C file in an appropriate
|
The configuration data should be placed in a C file in an appropriate
|
||||||
subdirectory. There isn't any C code, though! In this case the file
|
subdirectory. There isn't any C code, though! In this case the file
|
||||||
|
@ -1348,6 +1348,11 @@ int ash_main(int argc, char** argv)
|
|||||||
MAIN_EXTERNALLY_VISIBLE
|
MAIN_EXTERNALLY_VISIBLE
|
||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
|
int hush_main(int argc, char** argv)
|
||||||
|
#if ENABLE_HUSH || ENABLE_SH_IS_HUSH || ENABLE_BASH_IS_HUSH
|
||||||
|
MAIN_EXTERNALLY_VISIBLE
|
||||||
|
#endif
|
||||||
|
;
|
||||||
/* If shell needs them, they exist even if not enabled as applets */
|
/* If shell needs them, they exist even if not enabled as applets */
|
||||||
int echo_main(int argc, char** argv) IF_ECHO(MAIN_EXTERNALLY_VISIBLE);
|
int echo_main(int argc, char** argv) IF_ECHO(MAIN_EXTERNALLY_VISIBLE);
|
||||||
int printf_main(int argc, char **argv) IF_PRINTF(MAIN_EXTERNALLY_VISIBLE);
|
int printf_main(int argc, char **argv) IF_PRINTF(MAIN_EXTERNALLY_VISIBLE);
|
||||||
|
@ -50,7 +50,7 @@
|
|||||||
|
|
||||||
#include "usage_compressed.h"
|
#include "usage_compressed.h"
|
||||||
|
|
||||||
#if ENABLE_ASH_EMBEDDED_SCRIPTS
|
#if ENABLE_FEATURE_SH_EMBEDDED_SCRIPTS
|
||||||
# define DEFINE_SCRIPT_DATA 1
|
# define DEFINE_SCRIPT_DATA 1
|
||||||
# include "embedded_scripts.h"
|
# include "embedded_scripts.h"
|
||||||
#else
|
#else
|
||||||
@ -774,7 +774,13 @@ int scripted_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
{
|
{
|
||||||
int script = find_script_by_name(applet_name);
|
int script = find_script_by_name(applet_name);
|
||||||
if (script >= 0)
|
if (script >= 0)
|
||||||
|
#if ENABLE_ASH || ENABLE_SH_IS_ASH || ENABLE_BASH_IS_ASH
|
||||||
exit(ash_main(-script - 1, argv));
|
exit(ash_main(-script - 1, argv));
|
||||||
|
#elif ENABLE_HUSH || ENABLE_SH_IS_HUSH || ENABLE_BASH_IS_HUSH
|
||||||
|
exit(hush_main(-script - 1, argv));
|
||||||
|
#else
|
||||||
|
return 1;
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
|
. ./.config || exit 1
|
||||||
|
|
||||||
target="$1"
|
target="$1"
|
||||||
custom_loc="$2"
|
custom_loc="$2"
|
||||||
applet_loc="$3"
|
applet_loc="$3"
|
||||||
@ -8,6 +10,12 @@ test "$target" || exit 1
|
|||||||
test "$SED" || SED=sed
|
test "$SED" || SED=sed
|
||||||
test "$DD" || DD=dd
|
test "$DD" || DD=dd
|
||||||
|
|
||||||
|
if [ x"$CONFIG_FEATURE_SH_EMBEDDED_SCRIPTS" != x"y" ]
|
||||||
|
then
|
||||||
|
printf '#define NUM_SCRIPTS 0\n' >"$target"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
# Some people were bitten by their system lacking a (proper) od
|
# Some people were bitten by their system lacking a (proper) od
|
||||||
od -v -b </dev/null >/dev/null
|
od -v -b </dev/null >/dev/null
|
||||||
if test $? != 0; then
|
if test $? != 0; then
|
||||||
|
@ -25,7 +25,7 @@ custom_scripts()
|
|||||||
then
|
then
|
||||||
for i in $(cd "$custom_loc"; ls * 2>/dev/null)
|
for i in $(cd "$custom_loc"; ls * 2>/dev/null)
|
||||||
do
|
do
|
||||||
printf "APPLET_SCRIPTED(%s, scripted, BB_DIR_USR_BIN, BB_SUID_DROP, scripted)\n" $i;
|
printf "IF_FEATURE_SH_EMBEDDED_SCRIPTS(APPLET_SCRIPTED(%s, scripted, BB_DIR_USR_BIN, BB_SUID_DROP, scripted))\n" $i;
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
@ -161,6 +161,20 @@ config FEATURE_SH_HISTFILESIZE
|
|||||||
to set shell history size. Note that its max value is capped
|
to set shell history size. Note that its max value is capped
|
||||||
by "History size" setting in library tuning section.
|
by "History size" setting in library tuning section.
|
||||||
|
|
||||||
|
config FEATURE_SH_EMBEDDED_SCRIPTS
|
||||||
|
bool "Embed scripts in the binary"
|
||||||
|
default y
|
||||||
|
depends on ASH || HUSH || SH_IS_ASH || BASH_IS_ASH || SH_IS_HUSH || BASH_IS_HUSH
|
||||||
|
help
|
||||||
|
Allow scripts to be compressed and embedded in the busybox
|
||||||
|
binary. The scripts should be placed in the 'embed' directory
|
||||||
|
at build time. Like applets, scripts can be run as
|
||||||
|
'busybox SCRIPT ...' or by linking their name to the binary.
|
||||||
|
|
||||||
|
This also allows applets to be implemented as scripts: place
|
||||||
|
the script in 'applets_sh' and a stub C file containing
|
||||||
|
configuration in the appropriate subsystem directory.
|
||||||
|
|
||||||
endif # Options common to all shells
|
endif # Options common to all shells
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
16
shell/ash.c
16
shell/ash.c
@ -148,20 +148,6 @@
|
|||||||
//config: you to run the specified command or builtin,
|
//config: you to run the specified command or builtin,
|
||||||
//config: even when there is a function with the same name.
|
//config: even when there is a function with the same name.
|
||||||
//config:
|
//config:
|
||||||
//config:config ASH_EMBEDDED_SCRIPTS
|
|
||||||
//config: bool "Embed scripts in the binary"
|
|
||||||
//config: default y
|
|
||||||
//config: depends on ASH || SH_IS_ASH || BASH_IS_ASH
|
|
||||||
//config: help
|
|
||||||
//config: Allow scripts to be compressed and embedded in the busybox
|
|
||||||
//config: binary. The scripts should be placed in the 'embed' directory
|
|
||||||
//config: at build time. Like applets, scripts can be run as
|
|
||||||
//config: 'busybox SCRIPT ...' or by linking their name to the binary.
|
|
||||||
//config:
|
|
||||||
//config: This also allows applets to be implemented as scripts: place
|
|
||||||
//config: the script in 'applets_sh' and a stub C file containing
|
|
||||||
//config: configuration in the appropriate subsystem directory.
|
|
||||||
//config:
|
|
||||||
//config:endif # ash options
|
//config:endif # ash options
|
||||||
|
|
||||||
//applet:IF_ASH(APPLET(ash, BB_DIR_BIN, BB_SUID_DROP))
|
//applet:IF_ASH(APPLET(ash, BB_DIR_BIN, BB_SUID_DROP))
|
||||||
@ -195,7 +181,7 @@
|
|||||||
#include <sys/times.h>
|
#include <sys/times.h>
|
||||||
#include <sys/utsname.h> /* for setting $HOSTNAME */
|
#include <sys/utsname.h> /* for setting $HOSTNAME */
|
||||||
#include "busybox.h" /* for applet_names */
|
#include "busybox.h" /* for applet_names */
|
||||||
#if ENABLE_ASH_EMBEDDED_SCRIPTS
|
#if ENABLE_FEATURE_SH_EMBEDDED_SCRIPTS
|
||||||
# include "embedded_scripts.h"
|
# include "embedded_scripts.h"
|
||||||
#else
|
#else
|
||||||
# define NUM_SCRIPTS 0
|
# define NUM_SCRIPTS 0
|
||||||
|
16
shell/hush.c
16
shell/hush.c
@ -367,6 +367,11 @@
|
|||||||
# define PIPE_BUF 4096 /* amount of buffering in a pipe */
|
# define PIPE_BUF 4096 /* amount of buffering in a pipe */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if ENABLE_FEATURE_SH_EMBEDDED_SCRIPTS && !(ENABLE_ASH || ENABLE_SH_IS_ASH || ENABLE_BASH_IS_ASH)
|
||||||
|
# include "embedded_scripts.h"
|
||||||
|
#else
|
||||||
|
# define NUM_SCRIPTS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
/* So far, all bash compat is controlled by one config option */
|
/* So far, all bash compat is controlled by one config option */
|
||||||
/* Separate defines document which part of code implements what */
|
/* Separate defines document which part of code implements what */
|
||||||
@ -9951,6 +9956,14 @@ int hush_main(int argc, char **argv)
|
|||||||
/* http://www.opengroup.org/onlinepubs/9699919799/utilities/sh.html */
|
/* http://www.opengroup.org/onlinepubs/9699919799/utilities/sh.html */
|
||||||
flags = (argv[0] && argv[0][0] == '-') ? OPT_login : 0;
|
flags = (argv[0] && argv[0][0] == '-') ? OPT_login : 0;
|
||||||
builtin_argc = 0;
|
builtin_argc = 0;
|
||||||
|
#if NUM_SCRIPTS > 0
|
||||||
|
if (argc < 0) {
|
||||||
|
optarg = get_script_content(-argc - 1);
|
||||||
|
optind = 0;
|
||||||
|
argc = string_array_len(argv);
|
||||||
|
goto run_script;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
while (1) {
|
while (1) {
|
||||||
int opt = getopt(argc, argv, "+c:exinsl"
|
int opt = getopt(argc, argv, "+c:exinsl"
|
||||||
#if !BB_MMU
|
#if !BB_MMU
|
||||||
@ -9974,6 +9987,9 @@ int hush_main(int argc, char **argv)
|
|||||||
* Note: the form without ARG0 never happens:
|
* Note: the form without ARG0 never happens:
|
||||||
* sh ... -c 'builtin' BARGV... ""
|
* sh ... -c 'builtin' BARGV... ""
|
||||||
*/
|
*/
|
||||||
|
#if NUM_SCRIPTS > 0
|
||||||
|
run_script:
|
||||||
|
#endif
|
||||||
if (!G.root_pid) {
|
if (!G.root_pid) {
|
||||||
G.root_pid = getpid();
|
G.root_pid = getpid();
|
||||||
G.root_ppid = getppid();
|
G.root_ppid = getppid();
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//config:config NOLOGIN
|
//config:config NOLOGIN
|
||||||
//config: bool "nologin"
|
//config: bool "nologin"
|
||||||
//config: default y
|
//config: default y
|
||||||
//config: depends on ASH_EMBEDDED_SCRIPTS
|
//config: depends on FEATURE_SH_EMBEDDED_SCRIPTS
|
||||||
//config: help
|
//config: help
|
||||||
//config: Politely refuse a login
|
//config: Politely refuse a login
|
||||||
//config:
|
//config:
|
||||||
|
Loading…
Reference in New Issue
Block a user