Treat custom and applet scripts as applets
BusyBox has support for embedded shell scripts. Two types can be distinguished: custom scripts and scripts implementing applets. Custom scripts should be placed in the 'embed' directory at build time. They are given a default applet configuration and appear as applets to the user but no further configuration is possible. Applet scripts are integrated with the BusyBox build system and are intended to be used to ship standard applets that just happen to be implemented as scripts. They can be configured at build time and appear just like native applets. Such scripts should be placed in the 'applets_sh' directory. A stub C program should be written to provide the usual applet configuration details and placed in a suitable subsystem directory. It may be helpful to have a configuration option to enable any dependencies the script requires: see the 'nologin' applet for an example. function old new delta scripted_main - 41 +41 applet_names 2773 2781 +8 applet_main 1600 1604 +4 i2cdetect_main 672 674 +2 applet_suid 100 101 +1 applet_install_loc 200 201 +1 applet_flags 100 101 +1 packed_usage 33180 33179 -1 tryexec 159 152 -7 evalcommand 1661 1653 -8 script_names 9 - -9 packed_scripts 123 114 -9 complete_cmd_dir_file 826 811 -15 shellexec 271 254 -17 find_command 1007 990 -17 busybox_main 642 624 -18 run_applet_and_exit 100 78 -22 find_script_by_name 51 - -51 ------------------------------------------------------------------------------ (add/remove: 1/2 grow/shrink: 6/9 up/down: 58/-174) Total: -116 bytes text data bss dec hex filename 950034 477 7296 957807 e9d6f busybox_old 949918 477 7296 957691 e9cfb busybox_unstripped Signed-off-by: Ron Yorston <rmy@pobox.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
e6a63bf683
commit
3778898f97
5
.gitignore
vendored
5
.gitignore
vendored
@ -56,3 +56,8 @@ cscope.po.out
|
|||||||
#
|
#
|
||||||
tags
|
tags
|
||||||
TAGS
|
TAGS
|
||||||
|
|
||||||
|
#
|
||||||
|
# user-supplied scripts
|
||||||
|
#
|
||||||
|
/embed
|
||||||
|
4
Makefile
4
Makefile
@ -361,7 +361,7 @@ scripts/basic/%: scripts_basic ;
|
|||||||
|
|
||||||
# This target generates Kbuild's and Config.in's from *.c files
|
# This target generates Kbuild's and Config.in's from *.c files
|
||||||
PHONY += gen_build_files
|
PHONY += gen_build_files
|
||||||
gen_build_files: $(wildcard $(srctree)/*/*.c) $(wildcard $(srctree)/*/*/*.c)
|
gen_build_files: $(wildcard $(srctree)/*/*.c) $(wildcard $(srctree)/*/*/*.c) $(wildcard embed/*)
|
||||||
$(Q)$(srctree)/scripts/gen_build_files.sh $(srctree) $(objtree)
|
$(Q)$(srctree)/scripts/gen_build_files.sh $(srctree) $(objtree)
|
||||||
|
|
||||||
# bbox: we have helpers in applets/
|
# bbox: we have helpers in applets/
|
||||||
@ -851,7 +851,7 @@ quiet_cmd_gen_common_bufsiz = GEN include/common_bufsiz.h
|
|||||||
quiet_cmd_split_autoconf = SPLIT include/autoconf.h -> include/config/*
|
quiet_cmd_split_autoconf = SPLIT include/autoconf.h -> include/config/*
|
||||||
cmd_split_autoconf = scripts/basic/split-include include/autoconf.h include/config
|
cmd_split_autoconf = scripts/basic/split-include include/autoconf.h include/config
|
||||||
quiet_cmd_gen_embedded_scripts = GEN include/embedded_scripts.h
|
quiet_cmd_gen_embedded_scripts = GEN include/embedded_scripts.h
|
||||||
cmd_gen_embedded_scripts = scripts/embedded_scripts include/embedded_scripts.h embed
|
cmd_gen_embedded_scripts = $(srctree)/scripts/embedded_scripts include/embedded_scripts.h $(srctree)/embed $(srctree)/applets_sh
|
||||||
#bbox# piggybacked generation of few .h files
|
#bbox# piggybacked generation of few .h files
|
||||||
include/config/MARKER: scripts/basic/split-include include/autoconf.h $(wildcard embed/*) scripts/embedded_scripts
|
include/config/MARKER: scripts/basic/split-include include/autoconf.h $(wildcard embed/*) scripts/embedded_scripts
|
||||||
$(call cmd,split_autoconf)
|
$(call cmd,split_autoconf)
|
||||||
|
16
applets/busybox.mkscripts
Executable file
16
applets/busybox.mkscripts
Executable file
@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Make busybox scripted applet list file.
|
||||||
|
|
||||||
|
# input $1: full path to Config.h
|
||||||
|
# input $2: full path to applets.h
|
||||||
|
# output (stdout): list of pathnames that should be linked to busybox
|
||||||
|
|
||||||
|
export LC_ALL=POSIX
|
||||||
|
export LC_CTYPE=POSIX
|
||||||
|
|
||||||
|
CONFIG_H=${1:-include/autoconf.h}
|
||||||
|
APPLETS_H=${2:-include/applets.h}
|
||||||
|
$HOSTCC -E -DMAKE_SCRIPTS -include $CONFIG_H $APPLETS_H |
|
||||||
|
awk '/^[ \t]*SCRIPT/{
|
||||||
|
print $2
|
||||||
|
}'
|
@ -1,5 +0,0 @@
|
|||||||
This directory contains examples of applets implemented as shell scripts.
|
|
||||||
|
|
||||||
So far these scripts are not hooked to the build system and are not
|
|
||||||
installed by "make install". If you want to use them,
|
|
||||||
you need to install them by hand.
|
|
@ -1,5 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
# TODO: use getopt to avoid parsing options as filenames,
|
|
||||||
# and to support -- and --help
|
|
||||||
[ $# -ne 0 ] && DASH_I=-i
|
|
||||||
sed $DASH_I -e 's/\r$//' "$@"
|
|
3
applets_sh/nologin
Executable file
3
applets_sh/nologin
Executable file
@ -0,0 +1,3 @@
|
|||||||
|
cat /etc/nologin.txt 2>/dev/null || echo This account is not available
|
||||||
|
sleep 5
|
||||||
|
exit 1
|
@ -1,7 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
# TODO: use getopt to avoid parsing options as filenames,
|
|
||||||
# and to support -- and --help
|
|
||||||
for i in "$@"
|
|
||||||
do
|
|
||||||
sed -e '1!G;h;$!d' "$i"
|
|
||||||
done
|
|
@ -1,5 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
# TODO: use getopt to avoid parsing options as filenames,
|
|
||||||
# and to support -- and --help
|
|
||||||
[ $# -ne 0 ] && DASH_I=-i
|
|
||||||
sed $DASH_I -e 's/$/\r/' "$@"
|
|
@ -1,4 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
cat /etc/nologin.txt 2>/dev/null || echo "This account is not available"
|
|
||||||
sleep 5
|
|
||||||
exit 1
|
|
@ -22,41 +22,60 @@ s - suid type:
|
|||||||
BB_SUID_REQUIRE or BB_SUID_MAYBE applet.
|
BB_SUID_REQUIRE or BB_SUID_MAYBE applet.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define NOUSAGE_STR "\b"
|
||||||
|
|
||||||
|
#define dummy_trivial_usage NOUSAGE_STR \
|
||||||
|
|
||||||
|
#define dummy_full_usage "" \
|
||||||
|
|
||||||
#if defined(PROTOTYPES)
|
#if defined(PROTOTYPES)
|
||||||
# define APPLET(name,l,s) int name##_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
# define APPLET(name,l,s) int name##_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
||||||
# define APPLET_ODDNAME(name,main,l,s,help) int main##_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
# define APPLET_ODDNAME(name,main,l,s,help) int main##_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
||||||
# define APPLET_NOEXEC(name,main,l,s,help) int main##_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
# define APPLET_NOEXEC(name,main,l,s,help) int main##_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
||||||
# define APPLET_NOFORK(name,main,l,s,help) int main##_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
# define APPLET_NOFORK(name,main,l,s,help) int main##_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
||||||
|
# define APPLET_SCRIPTED(name,main,l,s,help)
|
||||||
|
|
||||||
#elif defined(NAME_MAIN)
|
#elif defined(NAME_MAIN)
|
||||||
# define APPLET(name,l,s) name name##_main
|
# define APPLET(name,l,s) name name##_main
|
||||||
# define APPLET_ODDNAME(name,main,l,s,help) name main##_main
|
# define APPLET_ODDNAME(name,main,l,s,help) name main##_main
|
||||||
# define APPLET_NOEXEC(name,main,l,s,help) name main##_main
|
# define APPLET_NOEXEC(name,main,l,s,help) name main##_main
|
||||||
# define APPLET_NOFORK(name,main,l,s,help) name main##_main
|
# define APPLET_NOFORK(name,main,l,s,help) name main##_main
|
||||||
|
# define APPLET_SCRIPTED(name,main,l,s,help) name scripted_main
|
||||||
|
|
||||||
#elif defined(MAKE_USAGE) && ENABLE_FEATURE_VERBOSE_USAGE
|
#elif defined(MAKE_USAGE) && ENABLE_FEATURE_VERBOSE_USAGE
|
||||||
# define APPLET(name,l,s) MAKE_USAGE(#name, name##_trivial_usage name##_full_usage)
|
# define APPLET(name,l,s) MAKE_USAGE(#name, name##_trivial_usage name##_full_usage)
|
||||||
# define APPLET_ODDNAME(name,main,l,s,help) MAKE_USAGE(#name, help##_trivial_usage help##_full_usage)
|
# define APPLET_ODDNAME(name,main,l,s,help) MAKE_USAGE(#name, help##_trivial_usage help##_full_usage)
|
||||||
# define APPLET_NOEXEC(name,main,l,s,help) MAKE_USAGE(#name, help##_trivial_usage help##_full_usage)
|
# define APPLET_NOEXEC(name,main,l,s,help) MAKE_USAGE(#name, help##_trivial_usage help##_full_usage)
|
||||||
# define APPLET_NOFORK(name,main,l,s,help) MAKE_USAGE(#name, help##_trivial_usage help##_full_usage)
|
# define APPLET_NOFORK(name,main,l,s,help) MAKE_USAGE(#name, help##_trivial_usage help##_full_usage)
|
||||||
|
# define APPLET_SCRIPTED(name,main,l,s,help) MAKE_USAGE(#name, help##_trivial_usage help##_full_usage)
|
||||||
|
|
||||||
#elif defined(MAKE_USAGE) && !ENABLE_FEATURE_VERBOSE_USAGE
|
#elif defined(MAKE_USAGE) && !ENABLE_FEATURE_VERBOSE_USAGE
|
||||||
# define APPLET(name,l,s) MAKE_USAGE(#name, name##_trivial_usage)
|
# define APPLET(name,l,s) MAKE_USAGE(#name, name##_trivial_usage)
|
||||||
# define APPLET_ODDNAME(name,main,l,s,help) MAKE_USAGE(#name, help##_trivial_usage)
|
# define APPLET_ODDNAME(name,main,l,s,help) MAKE_USAGE(#name, help##_trivial_usage)
|
||||||
# define APPLET_NOEXEC(name,main,l,s,help) MAKE_USAGE(#name, help##_trivial_usage)
|
# define APPLET_NOEXEC(name,main,l,s,help) MAKE_USAGE(#name, help##_trivial_usage)
|
||||||
# define APPLET_NOFORK(name,main,l,s,help) MAKE_USAGE(#name, help##_trivial_usage)
|
# define APPLET_NOFORK(name,main,l,s,help) MAKE_USAGE(#name, help##_trivial_usage)
|
||||||
|
# define APPLET_SCRIPTED(name,main,l,s,help) MAKE_USAGE(#name, help##_trivial_usage)
|
||||||
|
|
||||||
#elif defined(MAKE_LINKS)
|
#elif defined(MAKE_LINKS)
|
||||||
# define APPLET(name,l,c) LINK l name
|
# define APPLET(name,l,c) LINK l name
|
||||||
# define APPLET_ODDNAME(name,main,l,s,help) LINK l name
|
# define APPLET_ODDNAME(name,main,l,s,help) LINK l name
|
||||||
# define APPLET_NOEXEC(name,main,l,s,help) LINK l name
|
# define APPLET_NOEXEC(name,main,l,s,help) LINK l name
|
||||||
# define APPLET_NOFORK(name,main,l,s,help) LINK l name
|
# define APPLET_NOFORK(name,main,l,s,help) LINK l name
|
||||||
|
# define APPLET_SCRIPTED(name,main,l,s,help) LINK l name
|
||||||
|
|
||||||
#elif defined(MAKE_SUID)
|
#elif defined(MAKE_SUID)
|
||||||
# define APPLET(name,l,s) SUID s l name
|
# define APPLET(name,l,s) SUID s l name
|
||||||
# define APPLET_ODDNAME(name,main,l,s,help) SUID s l name
|
# define APPLET_ODDNAME(name,main,l,s,help) SUID s l name
|
||||||
# define APPLET_NOEXEC(name,main,l,s,help) SUID s l name
|
# define APPLET_NOEXEC(name,main,l,s,help) SUID s l name
|
||||||
# define APPLET_NOFORK(name,main,l,s,help) SUID s l name
|
# define APPLET_NOFORK(name,main,l,s,help) SUID s l name
|
||||||
|
# define APPLET_SCRIPTED(name,main,l,s,help) SUID s l name
|
||||||
|
|
||||||
|
#elif defined(MAKE_SCRIPTS)
|
||||||
|
# define APPLET(name,l,s)
|
||||||
|
# define APPLET_ODDNAME(name,main,l,s,help)
|
||||||
|
# define APPLET_NOEXEC(name,main,l,s,help)
|
||||||
|
# define APPLET_NOFORK(name,main,l,s,help)
|
||||||
|
# define APPLET_SCRIPTED(name,main,l,s,help) SCRIPT name
|
||||||
|
|
||||||
#else
|
#else
|
||||||
static struct bb_applet applets[] = { /* name, main, location, need_suid */
|
static struct bb_applet applets[] = { /* name, main, location, need_suid */
|
||||||
@ -64,6 +83,7 @@ s - suid type:
|
|||||||
# define APPLET_ODDNAME(name,main,l,s,help) { #name, #main, l, s },
|
# define APPLET_ODDNAME(name,main,l,s,help) { #name, #main, l, s },
|
||||||
# define APPLET_NOEXEC(name,main,l,s,help) { #name, #main, l, s, 1 },
|
# define APPLET_NOEXEC(name,main,l,s,help) { #name, #main, l, s, 1 },
|
||||||
# define APPLET_NOFORK(name,main,l,s,help) { #name, #main, l, s, 1, 1 },
|
# define APPLET_NOFORK(name,main,l,s,help) { #name, #main, l, s, 1, 1 },
|
||||||
|
# define APPLET_SCRIPTED(name,main,l,s,help) { #name, #main, l, s },
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLE_INSTALL_NO_USR
|
#if ENABLE_INSTALL_NO_USR
|
||||||
@ -84,3 +104,4 @@ INSERT
|
|||||||
#undef APPLET_ODDNAME
|
#undef APPLET_ODDNAME
|
||||||
#undef APPLET_NOEXEC
|
#undef APPLET_NOEXEC
|
||||||
#undef APPLET_NOFORK
|
#undef APPLET_NOFORK
|
||||||
|
#undef APPLET_SCRIPTED
|
||||||
|
@ -1322,8 +1322,8 @@ void bb_logenv_override(void) FAST_FUNC;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Embedded script support */
|
/* Embedded script support */
|
||||||
int find_script_by_name(const char *name) FAST_FUNC;
|
|
||||||
char *get_script_content(unsigned n) FAST_FUNC;
|
char *get_script_content(unsigned n) FAST_FUNC;
|
||||||
|
int scripted_main(int argc, char** argv);
|
||||||
|
|
||||||
/* Applets which are useful from another applets */
|
/* Applets which are useful from another applets */
|
||||||
int bb_cat(char** argv) FAST_FUNC;
|
int bb_cat(char** argv) FAST_FUNC;
|
||||||
|
@ -51,7 +51,7 @@
|
|||||||
#include "usage_compressed.h"
|
#include "usage_compressed.h"
|
||||||
|
|
||||||
#if ENABLE_ASH_EMBEDDED_SCRIPTS
|
#if ENABLE_ASH_EMBEDDED_SCRIPTS
|
||||||
# define DEFINE_script_names 1
|
# define DEFINE_SCRIPT_DATA 1
|
||||||
# include "embedded_scripts.h"
|
# include "embedded_scripts.h"
|
||||||
#else
|
#else
|
||||||
# define NUM_SCRIPTS 0
|
# define NUM_SCRIPTS 0
|
||||||
@ -818,27 +818,21 @@ int busybox_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
/* prevent last comma to be in the very last pos */
|
/* prevent last comma to be in the very last pos */
|
||||||
output_width--;
|
output_width--;
|
||||||
a = applet_names;
|
a = applet_names;
|
||||||
{
|
while (*a) {
|
||||||
# if NUM_SCRIPTS > 0
|
int len2 = strlen(a) + 2;
|
||||||
int i;
|
if (col >= (int)output_width - len2) {
|
||||||
for (i = 0; i < 2; i++, a = script_names)
|
full_write2_str(",\n");
|
||||||
# endif
|
col = 0;
|
||||||
while (*a) {
|
|
||||||
int len2 = strlen(a) + 2;
|
|
||||||
if (col >= (int)output_width - len2) {
|
|
||||||
full_write2_str(",\n");
|
|
||||||
col = 0;
|
|
||||||
}
|
|
||||||
if (col == 0) {
|
|
||||||
col = 6;
|
|
||||||
full_write2_str("\t");
|
|
||||||
} else {
|
|
||||||
full_write2_str(", ");
|
|
||||||
}
|
|
||||||
full_write2_str(a);
|
|
||||||
col += len2;
|
|
||||||
a += len2 - 1;
|
|
||||||
}
|
}
|
||||||
|
if (col == 0) {
|
||||||
|
col = 6;
|
||||||
|
full_write2_str("\t");
|
||||||
|
} else {
|
||||||
|
full_write2_str(", ");
|
||||||
|
}
|
||||||
|
full_write2_str(a);
|
||||||
|
col += len2;
|
||||||
|
a += len2 - 1;
|
||||||
}
|
}
|
||||||
full_write2_str("\n");
|
full_write2_str("\n");
|
||||||
return 0;
|
return 0;
|
||||||
@ -946,20 +940,25 @@ void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **ar
|
|||||||
# endif /* NUM_APPLETS > 0 */
|
# endif /* NUM_APPLETS > 0 */
|
||||||
|
|
||||||
# if NUM_SCRIPTS > 0
|
# if NUM_SCRIPTS > 0
|
||||||
int FAST_FUNC
|
static int find_script_by_name(const char *name)
|
||||||
find_script_by_name(const char *name)
|
|
||||||
{
|
{
|
||||||
const char *s = script_names;
|
int i;
|
||||||
int i = 0;
|
int applet = find_applet_by_name(name);
|
||||||
|
|
||||||
while (*s) {
|
if (applet >= 0) {
|
||||||
if (strcmp(name, s) == 0)
|
for (i = 0; i < NUM_SCRIPTS; ++i)
|
||||||
return i;
|
if (applet_numbers[i] == applet)
|
||||||
i++;
|
return i;
|
||||||
while (*s++ != '\0')
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
return -0x10000; /* make it so that NUM_APPLETS + <error> is still < 0 */
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int scripted_main(int argc UNUSED_PARAM, char **argv)
|
||||||
|
{
|
||||||
|
int script = find_script_by_name(applet_name);
|
||||||
|
if (script >= 0)
|
||||||
|
exit(ash_main(-script - 1, argv));
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* FAST_FUNC
|
char* FAST_FUNC
|
||||||
@ -978,7 +977,7 @@ get_script_content(unsigned n)
|
|||||||
}
|
}
|
||||||
# endif /* NUM_SCRIPTS > 0 */
|
# endif /* NUM_SCRIPTS > 0 */
|
||||||
|
|
||||||
# if ENABLE_BUSYBOX || NUM_APPLETS > 0 || NUM_SCRIPTS > 0
|
# if ENABLE_BUSYBOX || NUM_APPLETS > 0
|
||||||
static NORETURN void run_applet_and_exit(const char *name, char **argv)
|
static NORETURN void run_applet_and_exit(const char *name, char **argv)
|
||||||
{
|
{
|
||||||
# if ENABLE_BUSYBOX
|
# if ENABLE_BUSYBOX
|
||||||
@ -993,13 +992,6 @@ static NORETURN void run_applet_and_exit(const char *name, char **argv)
|
|||||||
run_applet_no_and_exit(applet, name, argv);
|
run_applet_no_and_exit(applet, name, argv);
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
# if NUM_SCRIPTS > 0
|
|
||||||
{
|
|
||||||
int script = find_script_by_name(name);
|
|
||||||
if (script >= 0)
|
|
||||||
exit(ash_main(-script - 1, argv));
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
|
|
||||||
/*bb_error_msg_and_die("applet not found"); - links in printf */
|
/*bb_error_msg_and_die("applet not found"); - links in printf */
|
||||||
full_write2_str(applet_name);
|
full_write2_str(applet_name);
|
||||||
|
@ -41,12 +41,6 @@
|
|||||||
#include "busybox.h"
|
#include "busybox.h"
|
||||||
#include "NUM_APPLETS.h"
|
#include "NUM_APPLETS.h"
|
||||||
#include "unicode.h"
|
#include "unicode.h"
|
||||||
#if ENABLE_ASH_EMBEDDED_SCRIPTS
|
|
||||||
# include "embedded_scripts.h"
|
|
||||||
#else
|
|
||||||
# define NUM_SCRIPTS 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _POSIX_VDISABLE
|
#ifndef _POSIX_VDISABLE
|
||||||
# define _POSIX_VDISABLE '\0'
|
# define _POSIX_VDISABLE '\0'
|
||||||
#endif
|
#endif
|
||||||
@ -812,20 +806,14 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type)
|
|||||||
}
|
}
|
||||||
pf_len = strlen(pfind);
|
pf_len = strlen(pfind);
|
||||||
|
|
||||||
# if ENABLE_FEATURE_SH_STANDALONE && (NUM_APPLETS != 1 || NUM_SCRIPTS > 0)
|
# if ENABLE_FEATURE_SH_STANDALONE && NUM_APPLETS != 1
|
||||||
if (type == FIND_EXE_ONLY && !dirbuf) {
|
if (type == FIND_EXE_ONLY && !dirbuf) {
|
||||||
const char *p;
|
const char *p = applet_names;
|
||||||
# if NUM_APPLETS != 1 && NUM_SCRIPTS > 0
|
|
||||||
for (i = 0, p = applet_names; i < 2; i++, p = script_names)
|
|
||||||
# elif NUM_APPLETS != 1 /* and NUM_SCRIPTS == 0 */
|
|
||||||
p = applet_names;
|
|
||||||
# else /* NUM_APPLETS == 1 && NUM_SCRIPTS > 0 */
|
|
||||||
p = script_names;
|
|
||||||
# endif
|
|
||||||
while (*p) {
|
while (*p) {
|
||||||
if (strncmp(pfind, p, pf_len) == 0)
|
if (strncmp(pfind, p, pf_len) == 0)
|
||||||
add_match(xstrdup(p));
|
add_match(xstrdup(p));
|
||||||
while (*p++)
|
while (*p++ != '\0')
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
target="$1"
|
target="$1"
|
||||||
loc="$2"
|
custom_loc="$2"
|
||||||
|
applet_loc="$3"
|
||||||
|
|
||||||
test "$target" || exit 1
|
test "$target" || exit 1
|
||||||
test "$SED" || SED=sed
|
test "$SED" || SED=sed
|
||||||
@ -14,46 +15,102 @@ if test $? != 0; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
exec >"$target.$$"
|
custom_scripts=""
|
||||||
|
if [ -d "$custom_loc" ]
|
||||||
scripts=""
|
|
||||||
if [ -d "$loc" ]
|
|
||||||
then
|
then
|
||||||
scripts=$(cd $loc; ls * 2>/dev/null)
|
custom_scripts=$(cd $custom_loc; ls * 2>/dev/null)
|
||||||
|
fi
|
||||||
|
all_scripts=$(applets/busybox.mkscripts)
|
||||||
|
|
||||||
|
# all_scripts includes applet scripts and custom scripts, sort them out
|
||||||
|
applet_scripts=""
|
||||||
|
for i in $all_scripts
|
||||||
|
do
|
||||||
|
found=0
|
||||||
|
for j in $custom_scripts
|
||||||
|
do
|
||||||
|
if [ "$i" = "$j" ]
|
||||||
|
then
|
||||||
|
found=1
|
||||||
|
break;
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [ $found -eq 0 ]
|
||||||
|
then
|
||||||
|
# anything that isn't a custom script is an applet script
|
||||||
|
applet_scripts="$applet_scripts $i"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# we know the custom scripts are present but applet scripts might have
|
||||||
|
# become detached from their configuration
|
||||||
|
for i in $applet_scripts
|
||||||
|
do
|
||||||
|
#if [ ! -f "$applet_loc/$i" -a ! -f "$custom_loc/$i" ]
|
||||||
|
if [ ! -f "$applet_loc/$i" ]
|
||||||
|
then
|
||||||
|
echo "missing applet script $i"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
n=$(echo $custom_scripts $applet_scripts | wc -w)
|
||||||
|
nall=$(echo $all_scripts | wc -w)
|
||||||
|
|
||||||
|
if [ $n -ne $nall ]
|
||||||
|
then
|
||||||
|
echo "script mismatch $n != $nall"
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
n=$(echo $scripts | wc -w)
|
concatenate_scripts() {
|
||||||
|
for i in $custom_scripts
|
||||||
|
do
|
||||||
|
cat $custom_loc/$i
|
||||||
|
printf '\000'
|
||||||
|
done
|
||||||
|
for i in $applet_scripts
|
||||||
|
do
|
||||||
|
cat $applet_loc/$i
|
||||||
|
printf '\000'
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
exec >"$target.$$"
|
||||||
|
|
||||||
if [ $n -ne 0 ]
|
if [ $n -ne 0 ]
|
||||||
then
|
then
|
||||||
printf '#ifdef DEFINE_script_names\n'
|
printf '#ifdef DEFINE_SCRIPT_DATA\n'
|
||||||
printf 'const char script_names[] ALIGN1 = '
|
if [ $n -ne 0 ]
|
||||||
for i in $scripts
|
then
|
||||||
do
|
printf 'const uint16_t applet_numbers[] = {\n'
|
||||||
printf '"%s\\0"' $i
|
for i in $custom_scripts $applet_scripts
|
||||||
done
|
do
|
||||||
printf ';\n'
|
# TODO support applets with names including invalid characters
|
||||||
|
printf '\tAPPLET_NO_%s,\n' $i
|
||||||
|
done
|
||||||
|
printf '};\n'
|
||||||
|
fi
|
||||||
printf '#else\n'
|
printf '#else\n'
|
||||||
printf 'extern const char script_names[] ALIGN1;\n'
|
if [ $n -ne 0 ]
|
||||||
|
then
|
||||||
|
printf 'extern const uint16_t applet_numbers[];\n'
|
||||||
|
fi
|
||||||
printf '#endif\n'
|
printf '#endif\n'
|
||||||
fi
|
fi
|
||||||
printf "#define NUM_SCRIPTS $n\n\n"
|
|
||||||
|
printf "\n"
|
||||||
|
printf '#define NUM_SCRIPTS %d\n' $n
|
||||||
|
printf "\n"
|
||||||
|
|
||||||
if [ $n -ne 0 ]
|
if [ $n -ne 0 ]
|
||||||
then
|
then
|
||||||
printf '#define UNPACKED_SCRIPTS_LENGTH '
|
printf '#define UNPACKED_SCRIPTS_LENGTH '
|
||||||
for i in $scripts
|
concatenate_scripts | wc -c
|
||||||
do
|
|
||||||
cat $loc/$i
|
|
||||||
printf '\000'
|
|
||||||
done | wc -c
|
|
||||||
|
|
||||||
printf '#define PACKED_SCRIPTS \\\n'
|
printf '#define PACKED_SCRIPTS \\\n'
|
||||||
for i in $scripts
|
concatenate_scripts | bzip2 -1 | $DD bs=2 skip=1 2>/dev/null | \
|
||||||
do
|
od -v -b \
|
||||||
cat $loc/$i
|
|
||||||
printf '\000'
|
|
||||||
done | bzip2 -1 | $DD bs=2 skip=1 2>/dev/null | od -v -b \
|
|
||||||
| grep -v '^ ' \
|
| grep -v '^ ' \
|
||||||
| $SED -e 's/^[^ ]*//' \
|
| $SED -e 's/^[^ ]*//' \
|
||||||
-e 's/ //g' \
|
-e 's/ //g' \
|
||||||
|
@ -17,12 +17,26 @@ status() { printf ' %-8s%s\n' "$1" "$2"; }
|
|||||||
gen() { status "GEN" "$@"; }
|
gen() { status "GEN" "$@"; }
|
||||||
chk() { status "CHK" "$@"; }
|
chk() { status "CHK" "$@"; }
|
||||||
|
|
||||||
|
# scripts in the 'embed' directory are treated as fake applets
|
||||||
|
custom_scripts()
|
||||||
|
{
|
||||||
|
custom_loc="$1"
|
||||||
|
if [ -d "$custom_loc" ]
|
||||||
|
then
|
||||||
|
for i in $(cd "$custom_loc"; ls *)
|
||||||
|
do
|
||||||
|
printf "APPLET_SCRIPTED(%s, scripted, BB_DIR_USR_BIN, BB_SUID_DROP, dummy)\n" $i;
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
generate()
|
generate()
|
||||||
{
|
{
|
||||||
# NB: data to be inserted at INSERT line is coming on stdin
|
# NB: data to be inserted at INSERT line is coming on stdin
|
||||||
src="$1"
|
src="$1"
|
||||||
dst="$2"
|
dst="$2"
|
||||||
header="$3"
|
header="$3"
|
||||||
|
loc="$4"
|
||||||
#chk "${dst}"
|
#chk "${dst}"
|
||||||
{
|
{
|
||||||
# Need to use printf: different shells have inconsistent
|
# Need to use printf: different shells have inconsistent
|
||||||
@ -32,6 +46,10 @@ generate()
|
|||||||
sed -n '/^INSERT$/ q; p' "${src}"
|
sed -n '/^INSERT$/ q; p' "${src}"
|
||||||
# copy stdin to stdout
|
# copy stdin to stdout
|
||||||
cat
|
cat
|
||||||
|
if [ -n "$loc" ]
|
||||||
|
then
|
||||||
|
custom_scripts "$loc"
|
||||||
|
fi
|
||||||
# print everything after INSERT line
|
# print everything after INSERT line
|
||||||
sed -n '/^INSERT$/ {
|
sed -n '/^INSERT$/ {
|
||||||
:l
|
:l
|
||||||
@ -53,7 +71,8 @@ sed -n 's@^//applet:@@p' "$srctree"/*/*.c "$srctree"/*/*/*.c \
|
|||||||
| generate \
|
| generate \
|
||||||
"$srctree/include/applets.src.h" \
|
"$srctree/include/applets.src.h" \
|
||||||
"include/applets.h" \
|
"include/applets.h" \
|
||||||
"/* DO NOT EDIT. This file is generated from applets.src.h */"
|
"/* DO NOT EDIT. This file is generated from applets.src.h */" \
|
||||||
|
"$srctree/embed"
|
||||||
|
|
||||||
# (Re)generate include/usage.h
|
# (Re)generate include/usage.h
|
||||||
# We add line continuation backslash after each line,
|
# We add line continuation backslash after each line,
|
||||||
|
19
shell/ash.c
19
shell/ash.c
@ -158,6 +158,10 @@
|
|||||||
//config: at build time. Like applets, scripts can be run as
|
//config: at build time. Like applets, scripts can be run as
|
||||||
//config: 'busybox SCRIPT ...' or by linking their name to the binary.
|
//config: 'busybox SCRIPT ...' or by linking their name to the binary.
|
||||||
//config:
|
//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))
|
||||||
@ -8016,9 +8020,6 @@ tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) const char *cmd, char **argv, c
|
|||||||
{
|
{
|
||||||
#if ENABLE_FEATURE_SH_STANDALONE
|
#if ENABLE_FEATURE_SH_STANDALONE
|
||||||
if (applet_no >= 0) {
|
if (applet_no >= 0) {
|
||||||
# if NUM_SCRIPTS > 0
|
|
||||||
if (applet_no < NUM_APPLETS)
|
|
||||||
# endif
|
|
||||||
if (APPLET_IS_NOEXEC(applet_no)) {
|
if (APPLET_IS_NOEXEC(applet_no)) {
|
||||||
clearenv();
|
clearenv();
|
||||||
while (*envp)
|
while (*envp)
|
||||||
@ -8088,9 +8089,6 @@ static void shellexec(char *prog, char **argv, const char *path, int idx)
|
|||||||
if (strchr(prog, '/') != NULL
|
if (strchr(prog, '/') != NULL
|
||||||
#if ENABLE_FEATURE_SH_STANDALONE
|
#if ENABLE_FEATURE_SH_STANDALONE
|
||||||
|| (applet_no = find_applet_by_name(prog)) >= 0
|
|| (applet_no = find_applet_by_name(prog)) >= 0
|
||||||
# if NUM_SCRIPTS > 0
|
|
||||||
|| (applet_no = NUM_APPLETS + find_script_by_name(prog)) >= 0
|
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
) {
|
) {
|
||||||
tryexec(IF_FEATURE_SH_STANDALONE(applet_no,) prog, argv, envp);
|
tryexec(IF_FEATURE_SH_STANDALONE(applet_no,) prog, argv, envp);
|
||||||
@ -10192,10 +10190,6 @@ evalcommand(union node *cmd, int flags)
|
|||||||
*/
|
*/
|
||||||
/* find_command() encodes applet_no as (-2 - applet_no) */
|
/* find_command() encodes applet_no as (-2 - applet_no) */
|
||||||
int applet_no = (- cmdentry.u.index - 2);
|
int applet_no = (- cmdentry.u.index - 2);
|
||||||
# if NUM_SCRIPTS > 0
|
|
||||||
/* Applets are ok, but not embedded scripts */
|
|
||||||
if (applet_no < NUM_APPLETS)
|
|
||||||
# endif
|
|
||||||
if (applet_no >= 0 && APPLET_IS_NOFORK(applet_no)) {
|
if (applet_no >= 0 && APPLET_IS_NOFORK(applet_no)) {
|
||||||
char **sv_environ;
|
char **sv_environ;
|
||||||
|
|
||||||
@ -13378,11 +13372,6 @@ find_command(char *name, struct cmdentry *entry, int act, const char *path)
|
|||||||
#if ENABLE_FEATURE_SH_STANDALONE
|
#if ENABLE_FEATURE_SH_STANDALONE
|
||||||
{
|
{
|
||||||
int applet_no = find_applet_by_name(name);
|
int applet_no = find_applet_by_name(name);
|
||||||
# if NUM_SCRIPTS > 0
|
|
||||||
if (applet_no < 0)
|
|
||||||
/* embedded script indices are offset by NUM_APPLETS */
|
|
||||||
applet_no = NUM_APPLETS + find_script_by_name(name);
|
|
||||||
# endif
|
|
||||||
if (applet_no >= 0) {
|
if (applet_no >= 0) {
|
||||||
entry->cmdtype = CMDNORMAL;
|
entry->cmdtype = CMDNORMAL;
|
||||||
entry->u.index = -2 - applet_no;
|
entry->u.index = -2 - applet_no;
|
||||||
|
27
util-linux/nologin.c
Normal file
27
util-linux/nologin.c
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
//config:config NOLOGIN
|
||||||
|
//config: bool "nologin"
|
||||||
|
//config: default y
|
||||||
|
//config: depends on ASH_EMBEDDED_SCRIPTS
|
||||||
|
//config: help
|
||||||
|
//config: Politely refuse a login
|
||||||
|
//config:
|
||||||
|
//config:config NOLOGIN_DEPENDENCIES
|
||||||
|
//config: bool "Dependencies for nologin"
|
||||||
|
//config: default y
|
||||||
|
//config: depends on NOLOGIN
|
||||||
|
//config: select CAT
|
||||||
|
//config: select ECHO
|
||||||
|
//config: select SLEEP
|
||||||
|
//config: help
|
||||||
|
//config: nologin is implemented as a shell script. It requires the
|
||||||
|
//config: following in the runtime environment:
|
||||||
|
//config: cat echo sleep
|
||||||
|
//config: If you know these will be available externally you can
|
||||||
|
//config: disable this option.
|
||||||
|
|
||||||
|
//applet:IF_NOLOGIN(APPLET_SCRIPTED(nologin, scripted, BB_DIR_USR_SBIN, BB_SUID_DROP, nologin))
|
||||||
|
|
||||||
|
//usage:#define nologin_trivial_usage
|
||||||
|
//usage: ""
|
||||||
|
//usage:#define nologin_full_usage "\n\n"
|
||||||
|
//usage: "Politely refuse a login"
|
Loading…
Reference in New Issue
Block a user