Applied with some changes, please check current git. In particular:
static int find_script_by_name(const char *name) { int i; int applet = find_applet_by_name(name); if (applet >= 0) { for (i = 0; i < NUM_SCRIPTS; ++i) if (applet_numbers[i] == applet) return i; } 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; } Currently, scripted_main() can only be reached if the applet is indeed a script. Therefore, checking that it's in applet_numbers[] is pointless (it is there). Therefore, we don't NEED applet_numbers[] and find_script_by_name(), right? ( And if we'd need it later for "busybox --showscript", we can check it via applet_main[applet_no] == scripted_main ) On Sat, Nov 17, 2018 at 6:48 PM Ron Yorston <r...@pobox.com> wrote: > > 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 - 53 +53 > packed_usage 32951 32997 +46 > .rodata 168610 168655 +45 > applet_names 2695 2703 +8 > applet_main 3128 3136 +8 > script_names 9 - -9 > find_script_by_name 57 26 -31 > run_applet_and_exit 782 728 -54 > ------------------------------------------------------------------------------ > (add/remove: 1/1 grow/shrink: 4/2 up/down: 160/-94) Total: 66 bytes > > Signed-off-by: Ron Yorston <r...@pobox.com> > --- > .gitignore | 5 ++ > Makefile | 4 +- > applets/busybox.mkscripts | 16 +++++ > {embed => applets_sh}/nologin | 0 > include/applets.src.h | 21 +++++++ > include/libbb.h | 1 + > libbb/appletlib.c | 69 ++++++++++------------ > libbb/lineedit.c | 20 ++----- > scripts/embedded_scripts | 107 ++++++++++++++++++++++++++-------- > scripts/gen_build_files.sh | 21 ++++++- > shell/ash.c | 19 ++---- > util-linux/nologin.c | 27 +++++++++ > 12 files changed, 213 insertions(+), 97 deletions(-) > create mode 100755 applets/busybox.mkscripts > rename {embed => applets_sh}/nologin (100%) > create mode 100644 util-linux/nologin.c > > diff --git a/.gitignore b/.gitignore > index c03c2e8a6..becd9bf6d 100644 > --- a/.gitignore > +++ b/.gitignore > @@ -56,3 +56,8 @@ cscope.po.out > # > tags > TAGS > + > +# > +# user-supplied scripts > +# > +/embed > diff --git a/Makefile b/Makefile > index 8a0dbdf49..c19280476 100644 > --- a/Makefile > +++ b/Makefile > @@ -361,7 +361,7 @@ scripts/basic/%: scripts_basic ; > > # This target generates Kbuild's and Config.in's from *.c 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) > > # 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/* > cmd_split_autoconf = scripts/basic/split-include include/autoconf.h > include/config > 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 > include/config/MARKER: scripts/basic/split-include include/autoconf.h > $(wildcard embed/*) scripts/embedded_scripts > $(call cmd,split_autoconf) > diff --git a/applets/busybox.mkscripts b/applets/busybox.mkscripts > new file mode 100755 > index 000000000..935685cba > --- /dev/null > +++ b/applets/busybox.mkscripts > @@ -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 > + }' > diff --git a/embed/nologin b/applets_sh/nologin > similarity index 100% > rename from embed/nologin > rename to applets_sh/nologin > diff --git a/include/applets.src.h b/include/applets.src.h > index 2ddf120ad..a9db5d160 100644 > --- a/include/applets.src.h > +++ b/include/applets.src.h > @@ -22,41 +22,60 @@ s - suid type: > 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) > # 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_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_SCRIPTED(name,main,l,s,help) > > #elif defined(NAME_MAIN) > # define APPLET(name,l,s) name name##_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_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 > # 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_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_SCRIPTED(name,main,l,s,help) MAKE_USAGE(#name, > help##_trivial_usage help##_full_usage) > > #elif defined(MAKE_USAGE) && !ENABLE_FEATURE_VERBOSE_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_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_SCRIPTED(name,main,l,s,help) MAKE_USAGE(#name, > help##_trivial_usage) > > #elif defined(MAKE_LINKS) > # define APPLET(name,l,c) 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_NOFORK(name,main,l,s,help) LINK l name > +# define APPLET_SCRIPTED(name,main,l,s,help) LINK l name > > #elif defined(MAKE_SUID) > # define APPLET(name,l,s) 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_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 > 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_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_SCRIPTED(name,main,l,s,help) { #name, #main, l, s }, > #endif > > #if ENABLE_INSTALL_NO_USR > @@ -84,3 +104,4 @@ INSERT > #undef APPLET_ODDNAME > #undef APPLET_NOEXEC > #undef APPLET_NOFORK > +#undef APPLET_SCRIPTED > diff --git a/include/libbb.h b/include/libbb.h > index a32608ebd..3fcff421b 100644 > --- a/include/libbb.h > +++ b/include/libbb.h > @@ -1324,6 +1324,7 @@ void bb_logenv_override(void) FAST_FUNC; > /* Embedded script support */ > int find_script_by_name(const char *name) FAST_FUNC; > char *get_script_content(unsigned n) FAST_FUNC; > +int scripted_main(int argc UNUSED_PARAM, char** argv) FAST_FUNC; > > /* Applets which are useful from another applets */ > int bb_cat(char** argv) FAST_FUNC; > diff --git a/libbb/appletlib.c b/libbb/appletlib.c > index 6dfaf1f41..5e7114198 100644 > --- a/libbb/appletlib.c > +++ b/libbb/appletlib.c > @@ -51,7 +51,7 @@ > #include "usage_compressed.h" > > #if ENABLE_ASH_EMBEDDED_SCRIPTS > -# define DEFINE_script_names 1 > +# define DEFINE_SCRIPT_DATA 1 > # include "embedded_scripts.h" > #else > # define NUM_SCRIPTS 0 > @@ -754,6 +754,14 @@ static void install_links(const char *busybox > UNUSED_PARAM, > } > # endif > > +int FAST_FUNC 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; > +} > + > static void run_applet_and_exit(const char *name, char **argv) NORETURN; > > # if ENABLE_BUSYBOX > @@ -818,27 +826,21 @@ int busybox_main(int argc UNUSED_PARAM, char **argv) > /* prevent last comma to be in the very last pos */ > output_width--; > a = applet_names; > - { > -# if NUM_SCRIPTS > 0 > - int i; > - for (i = 0; i < 2; i++, a = script_names) > -# endif > - 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; > + 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; > } > full_write2_str("\n"); > return 0; > @@ -949,17 +951,15 @@ void FAST_FUNC run_applet_no_and_exit(int applet_no, > const char *name, char **ar > int FAST_FUNC > find_script_by_name(const char *name) > { > - const char *s = script_names; > - int i = 0; > + int i; > + int applet = find_applet_by_name(name); > > - while (*s) { > - if (strcmp(name, s) == 0) > - return i; > - i++; > - while (*s++ != '\0') > - continue; > + if (applet >= 0) { > + for (i=0; i<NUM_SCRIPTS; ++i) > + if (applet_numbers[i] == applet) > + return i; > } > - return -0x10000; /* make it so that NUM_APPLETS + <error> is still < > 0 */ > + return -1; > } > > char* FAST_FUNC > @@ -978,7 +978,7 @@ get_script_content(unsigned n) > } > # 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) > { > # if ENABLE_BUSYBOX > @@ -993,13 +993,6 @@ static NORETURN void run_applet_and_exit(const char > *name, char **argv) > run_applet_no_and_exit(applet, name, argv); > } > # 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 */ > full_write2_str(applet_name); > diff --git a/libbb/lineedit.c b/libbb/lineedit.c > index 618e7c221..b1e971f88 100644 > --- a/libbb/lineedit.c > +++ b/libbb/lineedit.c > @@ -41,12 +41,6 @@ > #include "busybox.h" > #include "NUM_APPLETS.h" > #include "unicode.h" > -#if ENABLE_ASH_EMBEDDED_SCRIPTS > -# include "embedded_scripts.h" > -#else > -# define NUM_SCRIPTS 0 > -#endif > - > #ifndef _POSIX_VDISABLE > # define _POSIX_VDISABLE '\0' > #endif > @@ -812,20 +806,14 @@ static NOINLINE unsigned complete_cmd_dir_file(const > char *command, int type) > } > 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) { > - const char *p; > -# 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 > + const char *p = applet_names; > + > while (*p) { > if (strncmp(pfind, p, pf_len) == 0) > add_match(xstrdup(p)); > - while (*p++) > + while (*p++ != '\0') > continue; > } > } > diff --git a/scripts/embedded_scripts b/scripts/embedded_scripts > index 7245ba6e0..b7a023ce0 100755 > --- a/scripts/embedded_scripts > +++ b/scripts/embedded_scripts > @@ -1,7 +1,8 @@ > #!/bin/sh > > target="$1" > -loc="$2" > +custom_loc="$2" > +applet_loc="$3" > > test "$target" || exit 1 > test "$SED" || SED=sed > @@ -14,46 +15,102 @@ if test $? != 0; then > exit 1 > fi > > -exec >"$target.$$" > - > -scripts="" > -if [ -d "$loc" ] > +custom_scripts="" > +if [ -d "$custom_loc" ] > 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 > > -n=$(echo $scripts | wc -w) > +# 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 > > -if [ $n -ne 0 ] > +n=$(echo $custom_scripts $applet_scripts | wc -w) > +nall=$(echo $all_scripts | wc -w) > + > +if [ $n -ne $nall ] > then > - printf '#ifdef DEFINE_script_names\n' > - printf 'const char script_names[] ALIGN1 = ' > - for i in $scripts > + echo "script mismatch $n != $nall" > + exit 1 > +fi > + > +concatenate_scripts() { > + for i in $custom_scripts > + do > + cat $custom_loc/$i > + printf '\000' > + done > + for i in $applet_scripts > do > - printf '"%s\\0"' $i > + cat $applet_loc/$i > + printf '\000' > done > - printf ';\n' > +} > + > +exec >"$target.$$" > + > +if [ $n -ne 0 ] > +then > + printf '#ifdef DEFINE_SCRIPT_DATA\n' > + if [ $n -ne 0 ] > + then > + printf 'const uint16_t applet_numbers[] = {\n' > + for i in $custom_scripts $applet_scripts > + do > + # TODO support applets with names including invalid > characters > + printf '\tAPPLET_NO_%s,\n' $i > + done > + printf '};\n' > + fi > 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' > fi > -printf "#define NUM_SCRIPTS $n\n\n" > + > +printf "\n" > +printf '#define NUM_SCRIPTS %d\n' $n > +printf "\n" > > if [ $n -ne 0 ] > then > printf '#define UNPACKED_SCRIPTS_LENGTH ' > - for i in $scripts > - do > - cat $loc/$i > - printf '\000' > - done | wc -c > + concatenate_scripts | wc -c > > printf '#define PACKED_SCRIPTS \\\n' > - for i in $scripts > - do > - cat $loc/$i > - printf '\000' > - done | bzip2 -1 | $DD bs=2 skip=1 2>/dev/null | od -v -b \ > + concatenate_scripts | bzip2 -1 | $DD bs=2 skip=1 2>/dev/null | \ > + od -v -b \ > | grep -v '^ ' \ > | $SED -e 's/^[^ ]*//' \ > -e 's/ //g' \ > diff --git a/scripts/gen_build_files.sh b/scripts/gen_build_files.sh > index f79fa2f83..64e4bffa9 100755 > --- a/scripts/gen_build_files.sh > +++ b/scripts/gen_build_files.sh > @@ -17,12 +17,26 @@ status() { printf ' %-8s%s\n' "$1" "$2"; } > gen() { status "GEN" "$@"; } > 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() > { > # NB: data to be inserted at INSERT line is coming on stdin > src="$1" > dst="$2" > header="$3" > + loc="$4" > #chk "${dst}" > { > # Need to use printf: different shells have inconsistent > @@ -32,6 +46,10 @@ generate() > sed -n '/^INSERT$/ q; p' "${src}" > # copy stdin to stdout > cat > + if [ -n "$loc" ] > + then > + custom_scripts "$loc" > + fi > # print everything after INSERT line > sed -n '/^INSERT$/ { > :l > @@ -53,7 +71,8 @@ sed -n 's@^//applet:@@p' "$srctree"/*/*.c > "$srctree"/*/*/*.c \ > | generate \ > "$srctree/include/applets.src.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 > # We add line continuation backslash after each line, > diff --git a/shell/ash.c b/shell/ash.c > index b1f8f15d2..44b3569dc 100644 > --- a/shell/ash.c > +++ b/shell/ash.c > @@ -158,6 +158,10 @@ > //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)) > @@ -8016,9 +8020,6 @@ tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) const > char *cmd, char **argv, c > { > #if ENABLE_FEATURE_SH_STANDALONE > if (applet_no >= 0) { > -# if NUM_SCRIPTS > 0 > - if (applet_no < NUM_APPLETS) > -# endif > if (APPLET_IS_NOEXEC(applet_no)) { > clearenv(); > while (*envp) > @@ -8088,9 +8089,6 @@ static void shellexec(char *prog, char **argv, const > char *path, int idx) > if (strchr(prog, '/') != NULL > #if ENABLE_FEATURE_SH_STANDALONE > || (applet_no = find_applet_by_name(prog)) >= 0 > -# if NUM_SCRIPTS > 0 > - || (applet_no = NUM_APPLETS + find_script_by_name(prog)) >= 0 > -# endif > #endif > ) { > 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) */ > 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)) { > char **sv_environ; > > @@ -13378,11 +13372,6 @@ find_command(char *name, struct cmdentry *entry, int > act, const char *path) > #if ENABLE_FEATURE_SH_STANDALONE > { > 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) { > entry->cmdtype = CMDNORMAL; > entry->u.index = -2 - applet_no; > diff --git a/util-linux/nologin.c b/util-linux/nologin.c > new file mode 100644 > index 000000000..52c640784 > --- /dev/null > +++ b/util-linux/nologin.c > @@ -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: "Display a message that an account is not available and exit > non-zero." > -- > 2.19.1 > _______________________________________________ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox