From 3f6a978a0dabe08e9df15b3f9ee2bd3cf8e3c441 Mon Sep 17 00:00:00 2001 From: Rostislav Skudnov Date: Mon, 15 Oct 2018 10:26:15 +0000 Subject: dd: add 'oflag=seek_bytes' Allow specifying position in the output file in bytes instead of obs-sized blocks, improve compatibility with GNU dd. function old new delta dd_main 1632 1693 +61 packed_usage 33130 33150 +20 static.oflag_words - 12 +12 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 2/0 up/down: 93/0) Total: 93 bytes Signed-off-by: Rostislav Skudnov Signed-off-by: Denys Vlasenko --- docs/posix_conformance.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'docs') diff --git a/docs/posix_conformance.txt b/docs/posix_conformance.txt index cdf89b744..0e6f4a317 100644 --- a/docs/posix_conformance.txt +++ b/docs/posix_conformance.txt @@ -182,6 +182,7 @@ dd compatibility options: conv=fsync | yes | | iflag=skip_bytes| yes | | iflag=fullblock | yes | | + oflag=seek_bytes| yes | | df POSIX options option | exists | compliant | remarks -- cgit v1.2.3-55-g6feb From 31a04d91c24f6ee180de45e1508dc03dea9f9c11 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Tue, 27 Nov 2018 10:45:30 +0000 Subject: docs: add embedded-scripts.txt Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- docs/embedded-scripts.txt | 116 ++++++++++++++++++++++++++++++++++++++++++++++ util-linux/nologin.c | 2 +- 2 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 docs/embedded-scripts.txt (limited to 'docs') diff --git a/docs/embedded-scripts.txt b/docs/embedded-scripts.txt new file mode 100644 index 000000000..1b0c5b591 --- /dev/null +++ b/docs/embedded-scripts.txt @@ -0,0 +1,116 @@ +Embedded Shell Scripts in BusyBox +================================= + +BusyBox allows applets to be implemented as shell scripts. Since +this obviously requires a shell to interpret the scripts the feature +depends on having a shell (specifically, ash) built into the binary. +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 +script: it will probably need some external commands. If these are +to be provided by BusyBox you'll need to ensure they're enabled too. + +There are two ways to include scripts in BusyBox: the quick-and-dirty +custom script and the full-featured scripted applet. + +Custom Scripts +-------------- + +When embedded script support is enabled the BusyBox build process +assumes that any files in the directory 'embed' at the top level of +the source tree are scripts to be embedded. + +The embed directory isn't present in the BusyBox source tree and +BusyBox itself will never put anything there: it's entirely for the +use of third parties. + +Adding a custom script is as simple as running the following sequence +of commands in the BusyBox source directory: + + mkdir embed + echo 'echo foo' >embed/foo + make defconfig + make + +The resulting binary includes the new applet foo! + +Custom scripts have limited opportunities for configuration: the only +control developers have is to put them in the embed directory, or not. +Everything else takes default values. For more control you need the +additional features provided by scripted applets. + +Scripted Applets +---------------- + +Suppose we want to make a shell script version of the sample applet +from the New Applet HOWTO. First we'd have to write a script (vaguely) +equivalent to the C code: + + return $(($RANDOM%256)) + +This should be placed in the file applets_sh/mu in the source tree. + +Next we need the configuration data. This is very similar to the example +code for the native applet: + +//config:config MU +//config: bool "MU" +//config: default y +//config: help +//config: Returns an indeterminate value. + +//applet:IF_MU(APPLET_SCRIPTED(mu, scripted, BB_DIR_USR_BIN, BB_SUID_DROP, mu)) + +//usage:#define mu_trivial_usage +//usage: "[-abcde] FILE..." +//usage:#define mu_full_usage +//usage: "Returns an indeterminate value\n" +//usage: "\n -a First function" +//usage: "\n -b Second function" + +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 +dependencies the script has. We can assume that ash is available. +No external commands are used by our mu script, but it does depend on +optional shell features. We can ensure these are selected by adding +this to the configuration: + +//config:config MU_DEPENDENCIES +//config: bool "Enable dependencies for mu" +//config: default y +//config: depends on MU +//config: select ASH_RANDOM_SUPPORT +//config: select FEATURE_SH_MATH +//config: help +//config: mu is implemented as a shell script. It requires ash +//config: support for $RANDOM and arithmetic. + +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 +could be miscutils/mu.c. + +Scripted applets are just as configurable as applets written in C. +They can be enabled or disabled using the configuration menu; their +install directory can be specified and their usage messages are stored +along with those of all other applets. + +Additional Notes +---------------- + +The source for embedded scripts can be displayed by running: + + busybox --show SCRIPT + +This can be disabled by turning off FEATURE_SHOW_SCRIPT in the +configuration, though it won't prevent a determined user from +extracting the source code. + +It can be argued that embedded scripts are linked into the BusyBox +binary and are therefore not subject to the 'mere aggregation' +exception in the GPL. If this is the case embedded scripts should +have a licence compatible with BusyBox's GPL v2-only licence. diff --git a/util-linux/nologin.c b/util-linux/nologin.c index cc619bf8a..0982fff3d 100644 --- a/util-linux/nologin.c +++ b/util-linux/nologin.c @@ -6,7 +6,7 @@ //config: Politely refuse a login //config: //config:config NOLOGIN_DEPENDENCIES -//config: bool "Dependencies for nologin" +//config: bool "Enable dependencies for nologin" //config: default y //config: depends on NOLOGIN //config: select CAT -- cgit v1.2.3-55-g6feb From 71df2d3589e3e682cd6770f41f0b184841b78702 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Tue, 27 Nov 2018 14:34:25 +0000 Subject: 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 Signed-off-by: Denys Vlasenko --- archival/libarchive/Kbuild.src | 2 +- docs/embedded-scripts.txt | 21 ++++++++------------- include/libbb.h | 5 +++++ libbb/appletlib.c | 8 +++++++- scripts/embedded_scripts | 8 ++++++++ scripts/gen_build_files.sh | 2 +- shell/Config.src | 14 ++++++++++++++ shell/ash.c | 16 +--------------- shell/hush.c | 16 ++++++++++++++++ util-linux/nologin.c | 2 +- 10 files changed, 62 insertions(+), 32 deletions(-) (limited to 'docs') diff --git a/archival/libarchive/Kbuild.src b/archival/libarchive/Kbuild.src index 12e66a88b..d2f284b08 100644 --- a/archival/libarchive/Kbuild.src +++ b/archival/libarchive/Kbuild.src @@ -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_COMPRESS_USAGE) += 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),) lib-y += $(COMMON_FILES) diff --git a/docs/embedded-scripts.txt b/docs/embedded-scripts.txt index 1b0c5b591..7a273d698 100644 --- a/docs/embedded-scripts.txt +++ b/docs/embedded-scripts.txt @@ -3,13 +3,9 @@ Embedded Shell Scripts in BusyBox BusyBox allows applets to be implemented as shell scripts. Since this obviously requires a shell to interpret the scripts the feature -depends on having a shell (specifically, ash) built into the binary. -Support for embedded scripts also has to be enabled. - -To embed scripts in BusyBox you must enable these configuration options: - - ASH - ASH_EMBEDDED_SCRIPTS +depends on having a shell built into the binary. Either ash or hush +will do. If both are present ash will be used. Support for embedded +scripts also has to be enabled. It's unlikely that your applet will be implemented as a pure shell 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 APPLET_SCRIPTED. It would also be useful to include details of any -dependencies the script has. We can assume that ash is available. -No external commands are used by our mu script, but it does depend on -optional shell features. We can ensure these are selected by adding -this to the configuration: +dependencies the script has. No external commands are used by our mu +script, but it does depend on optional shell features. We can ensure +these are selected by adding this to the configuration: //config:config MU_DEPENDENCIES //config: bool "Enable dependencies for mu" @@ -87,8 +82,8 @@ this to the configuration: //config: select ASH_RANDOM_SUPPORT //config: select FEATURE_SH_MATH //config: help -//config: mu is implemented as a shell script. It requires ash -//config: support for $RANDOM and arithmetic. +//config: mu is implemented as a shell script. It requires support +//config: for $RANDOM and arithmetic. 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 diff --git a/include/libbb.h b/include/libbb.h index ebd090e18..b560cc2eb 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1348,6 +1348,11 @@ int ash_main(int argc, char** argv) MAIN_EXTERNALLY_VISIBLE #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 */ int echo_main(int argc, char** argv) IF_ECHO(MAIN_EXTERNALLY_VISIBLE); int printf_main(int argc, char **argv) IF_PRINTF(MAIN_EXTERNALLY_VISIBLE); diff --git a/libbb/appletlib.c b/libbb/appletlib.c index a79a37efb..cd09b620c 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c @@ -50,7 +50,7 @@ #include "usage_compressed.h" -#if ENABLE_ASH_EMBEDDED_SCRIPTS +#if ENABLE_FEATURE_SH_EMBEDDED_SCRIPTS # define DEFINE_SCRIPT_DATA 1 # include "embedded_scripts.h" #else @@ -774,7 +774,13 @@ int scripted_main(int argc UNUSED_PARAM, char **argv) { int script = find_script_by_name(applet_name); if (script >= 0) +#if ENABLE_ASH || ENABLE_SH_IS_ASH || ENABLE_BASH_IS_ASH 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; } diff --git a/scripts/embedded_scripts b/scripts/embedded_scripts index 86ad44d1d..aa7bf3e8a 100755 --- a/scripts/embedded_scripts +++ b/scripts/embedded_scripts @@ -1,5 +1,7 @@ #!/bin/sh +. ./.config || exit 1 + target="$1" custom_loc="$2" applet_loc="$3" @@ -8,6 +10,12 @@ test "$target" || exit 1 test "$SED" || SED=sed 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 od -v -b /dev/null if test $? != 0; then diff --git a/scripts/gen_build_files.sh b/scripts/gen_build_files.sh index 362632df3..92de681ac 100755 --- a/scripts/gen_build_files.sh +++ b/scripts/gen_build_files.sh @@ -25,7 +25,7 @@ custom_scripts() then for i in $(cd "$custom_loc"; ls * 2>/dev/null) 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 fi } diff --git a/shell/Config.src b/shell/Config.src index 959d3cb42..bc7218fe5 100644 --- a/shell/Config.src +++ b/shell/Config.src @@ -161,6 +161,20 @@ config FEATURE_SH_HISTFILESIZE to set shell history size. Note that its max value is capped 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 endmenu diff --git a/shell/ash.c b/shell/ash.c index 04e4006c8..9ce1d1a76 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -148,20 +148,6 @@ //config: you to run the specified command or builtin, //config: even when there is a function with the same name. //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 //applet:IF_ASH(APPLET(ash, BB_DIR_BIN, BB_SUID_DROP)) @@ -195,7 +181,7 @@ #include #include /* for setting $HOSTNAME */ #include "busybox.h" /* for applet_names */ -#if ENABLE_ASH_EMBEDDED_SCRIPTS +#if ENABLE_FEATURE_SH_EMBEDDED_SCRIPTS # include "embedded_scripts.h" #else # define NUM_SCRIPTS 0 diff --git a/shell/hush.c b/shell/hush.c index 431010f09..90191408d 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -367,6 +367,11 @@ # define PIPE_BUF 4096 /* amount of buffering in a pipe */ #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 */ /* 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 */ flags = (argv[0] && argv[0][0] == '-') ? OPT_login : 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) { int opt = getopt(argc, argv, "+c:exinsl" #if !BB_MMU @@ -9974,6 +9987,9 @@ int hush_main(int argc, char **argv) * Note: the form without ARG0 never happens: * sh ... -c 'builtin' BARGV... "" */ +#if NUM_SCRIPTS > 0 + run_script: +#endif if (!G.root_pid) { G.root_pid = getpid(); G.root_ppid = getppid(); diff --git a/util-linux/nologin.c b/util-linux/nologin.c index 0982fff3d..5e5e42305 100644 --- a/util-linux/nologin.c +++ b/util-linux/nologin.c @@ -1,7 +1,7 @@ //config:config NOLOGIN //config: bool "nologin" //config: default y -//config: depends on ASH_EMBEDDED_SCRIPTS +//config: depends on FEATURE_SH_EMBEDDED_SCRIPTS //config: help //config: Politely refuse a login //config: -- cgit v1.2.3-55-g6feb