aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2018-11-17 17:48:14 +0000
committerDenys Vlasenko <vda.linux@googlemail.com>2018-11-17 21:16:33 +0100
commit3778898f97a64e7b42b53194af7f3b93cc9c07a3 (patch)
tree9452b954be8861feff32a40072615ee95caaa4c6
parente6a63bf683f47027d36dc21b62b2f5cc3eb30a30 (diff)
downloadbusybox-w32-3778898f97a64e7b42b53194af7f3b93cc9c07a3.tar.gz
busybox-w32-3778898f97a64e7b42b53194af7f3b93cc9c07a3.tar.bz2
busybox-w32-3778898f97a64e7b42b53194af7f3b93cc9c07a3.zip
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>
-rw-r--r--.gitignore5
-rw-r--r--Makefile4
-rwxr-xr-xapplets/busybox.mkscripts16
-rw-r--r--applets_sh/README5
-rwxr-xr-xapplets_sh/dos2unix5
-rwxr-xr-xapplets_sh/nologin3
-rwxr-xr-xapplets_sh/tac7
-rwxr-xr-xapplets_sh/unix2dos5
-rwxr-xr-xembed/nologin4
-rw-r--r--include/applets.src.h21
-rw-r--r--include/libbb.h2
-rw-r--r--libbb/appletlib.c72
-rw-r--r--libbb/lineedit.c20
-rwxr-xr-xscripts/embedded_scripts107
-rwxr-xr-xscripts/gen_build_files.sh21
-rw-r--r--shell/ash.c19
-rw-r--r--util-linux/nologin.c27
17 files changed, 217 insertions, 126 deletions
diff --git a/.gitignore b/.gitignore
index c03c2e8a6..becd9bf6d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -56,3 +56,8 @@ cscope.po.out
56# 56#
57tags 57tags
58TAGS 58TAGS
59
60#
61# user-supplied scripts
62#
63/embed
diff --git a/Makefile b/Makefile
index 8a0dbdf49..c19280476 100644
--- a/Makefile
+++ b/Makefile
@@ -361,7 +361,7 @@ scripts/basic/%: scripts_basic ;
361 361
362# This target generates Kbuild's and Config.in's from *.c files 362# This target generates Kbuild's and Config.in's from *.c files
363PHONY += gen_build_files 363PHONY += gen_build_files
364gen_build_files: $(wildcard $(srctree)/*/*.c) $(wildcard $(srctree)/*/*/*.c) 364gen_build_files: $(wildcard $(srctree)/*/*.c) $(wildcard $(srctree)/*/*/*.c) $(wildcard embed/*)
365 $(Q)$(srctree)/scripts/gen_build_files.sh $(srctree) $(objtree) 365 $(Q)$(srctree)/scripts/gen_build_files.sh $(srctree) $(objtree)
366 366
367# bbox: we have helpers in applets/ 367# bbox: we have helpers in applets/
@@ -851,7 +851,7 @@ quiet_cmd_gen_common_bufsiz = GEN 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 853quiet_cmd_gen_embedded_scripts = GEN include/embedded_scripts.h
854 cmd_gen_embedded_scripts = scripts/embedded_scripts include/embedded_scripts.h embed 854 cmd_gen_embedded_scripts = $(srctree)/scripts/embedded_scripts include/embedded_scripts.h $(srctree)/embed $(srctree)/applets_sh
855#bbox# piggybacked generation of few .h files 855#bbox# piggybacked generation of few .h files
856include/config/MARKER: scripts/basic/split-include include/autoconf.h $(wildcard embed/*) scripts/embedded_scripts 856include/config/MARKER: scripts/basic/split-include include/autoconf.h $(wildcard embed/*) scripts/embedded_scripts
857 $(call cmd,split_autoconf) 857 $(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 @@
1#!/bin/sh
2# Make busybox scripted applet list file.
3
4# input $1: full path to Config.h
5# input $2: full path to applets.h
6# output (stdout): list of pathnames that should be linked to busybox
7
8export LC_ALL=POSIX
9export LC_CTYPE=POSIX
10
11CONFIG_H=${1:-include/autoconf.h}
12APPLETS_H=${2:-include/applets.h}
13$HOSTCC -E -DMAKE_SCRIPTS -include $CONFIG_H $APPLETS_H |
14 awk '/^[ \t]*SCRIPT/{
15 print $2
16 }'
diff --git a/applets_sh/README b/applets_sh/README
deleted file mode 100644
index 9dcd38ae3..000000000
--- a/applets_sh/README
+++ /dev/null
@@ -1,5 +0,0 @@
1This directory contains examples of applets implemented as shell scripts.
2
3So far these scripts are not hooked to the build system and are not
4installed by "make install". If you want to use them,
5you need to install them by hand.
diff --git a/applets_sh/dos2unix b/applets_sh/dos2unix
deleted file mode 100755
index 0fd5206f6..000000000
--- a/applets_sh/dos2unix
+++ /dev/null
@@ -1,5 +0,0 @@
1#!/bin/sh
2# TODO: use getopt to avoid parsing options as filenames,
3# and to support -- and --help
4[ $# -ne 0 ] && DASH_I=-i
5sed $DASH_I -e 's/\r$//' "$@"
diff --git a/applets_sh/nologin b/applets_sh/nologin
new file mode 100755
index 000000000..4ed5f6ca3
--- /dev/null
+++ b/applets_sh/nologin
@@ -0,0 +1,3 @@
1cat /etc/nologin.txt 2>/dev/null || echo This account is not available
2sleep 5
3exit 1
diff --git a/applets_sh/tac b/applets_sh/tac
deleted file mode 100755
index c5a8e39c1..000000000
--- a/applets_sh/tac
+++ /dev/null
@@ -1,7 +0,0 @@
1#!/bin/sh
2# TODO: use getopt to avoid parsing options as filenames,
3# and to support -- and --help
4for i in "$@"
5do
6sed -e '1!G;h;$!d' "$i"
7done
diff --git a/applets_sh/unix2dos b/applets_sh/unix2dos
deleted file mode 100755
index 70e042906..000000000
--- a/applets_sh/unix2dos
+++ /dev/null
@@ -1,5 +0,0 @@
1#!/bin/sh
2# TODO: use getopt to avoid parsing options as filenames,
3# and to support -- and --help
4[ $# -ne 0 ] && DASH_I=-i
5sed $DASH_I -e 's/$/\r/' "$@"
diff --git a/embed/nologin b/embed/nologin
deleted file mode 100755
index 3768eaaa7..000000000
--- a/embed/nologin
+++ /dev/null
@@ -1,4 +0,0 @@
1#!/bin/sh
2cat /etc/nologin.txt 2>/dev/null || echo "This account is not available"
3sleep 5
4exit 1
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:
22 BB_SUID_REQUIRE or BB_SUID_MAYBE applet. 22 BB_SUID_REQUIRE or BB_SUID_MAYBE applet.
23*/ 23*/
24 24
25#define NOUSAGE_STR "\b"
26
27#define dummy_trivial_usage NOUSAGE_STR \
28
29#define dummy_full_usage "" \
30
25#if defined(PROTOTYPES) 31#if defined(PROTOTYPES)
26# define APPLET(name,l,s) int name##_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 32# define APPLET(name,l,s) int name##_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
27# define APPLET_ODDNAME(name,main,l,s,help) int main##_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 33# define APPLET_ODDNAME(name,main,l,s,help) int main##_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
28# define APPLET_NOEXEC(name,main,l,s,help) int main##_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 34# define APPLET_NOEXEC(name,main,l,s,help) int main##_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
29# define APPLET_NOFORK(name,main,l,s,help) int main##_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 35# define APPLET_NOFORK(name,main,l,s,help) int main##_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
36# define APPLET_SCRIPTED(name,main,l,s,help)
30 37
31#elif defined(NAME_MAIN) 38#elif defined(NAME_MAIN)
32# define APPLET(name,l,s) name name##_main 39# define APPLET(name,l,s) name name##_main
33# define APPLET_ODDNAME(name,main,l,s,help) name main##_main 40# define APPLET_ODDNAME(name,main,l,s,help) name main##_main
34# define APPLET_NOEXEC(name,main,l,s,help) name main##_main 41# define APPLET_NOEXEC(name,main,l,s,help) name main##_main
35# define APPLET_NOFORK(name,main,l,s,help) name main##_main 42# define APPLET_NOFORK(name,main,l,s,help) name main##_main
43# define APPLET_SCRIPTED(name,main,l,s,help) name scripted_main
36 44
37#elif defined(MAKE_USAGE) && ENABLE_FEATURE_VERBOSE_USAGE 45#elif defined(MAKE_USAGE) && ENABLE_FEATURE_VERBOSE_USAGE
38# define APPLET(name,l,s) MAKE_USAGE(#name, name##_trivial_usage name##_full_usage) 46# define APPLET(name,l,s) MAKE_USAGE(#name, name##_trivial_usage name##_full_usage)
39# define APPLET_ODDNAME(name,main,l,s,help) MAKE_USAGE(#name, help##_trivial_usage help##_full_usage) 47# define APPLET_ODDNAME(name,main,l,s,help) MAKE_USAGE(#name, help##_trivial_usage help##_full_usage)
40# define APPLET_NOEXEC(name,main,l,s,help) MAKE_USAGE(#name, help##_trivial_usage help##_full_usage) 48# define APPLET_NOEXEC(name,main,l,s,help) MAKE_USAGE(#name, help##_trivial_usage help##_full_usage)
41# define APPLET_NOFORK(name,main,l,s,help) MAKE_USAGE(#name, help##_trivial_usage help##_full_usage) 49# define APPLET_NOFORK(name,main,l,s,help) MAKE_USAGE(#name, help##_trivial_usage help##_full_usage)
50# define APPLET_SCRIPTED(name,main,l,s,help) MAKE_USAGE(#name, help##_trivial_usage help##_full_usage)
42 51
43#elif defined(MAKE_USAGE) && !ENABLE_FEATURE_VERBOSE_USAGE 52#elif defined(MAKE_USAGE) && !ENABLE_FEATURE_VERBOSE_USAGE
44# define APPLET(name,l,s) MAKE_USAGE(#name, name##_trivial_usage) 53# define APPLET(name,l,s) MAKE_USAGE(#name, name##_trivial_usage)
45# define APPLET_ODDNAME(name,main,l,s,help) MAKE_USAGE(#name, help##_trivial_usage) 54# define APPLET_ODDNAME(name,main,l,s,help) MAKE_USAGE(#name, help##_trivial_usage)
46# define APPLET_NOEXEC(name,main,l,s,help) MAKE_USAGE(#name, help##_trivial_usage) 55# define APPLET_NOEXEC(name,main,l,s,help) MAKE_USAGE(#name, help##_trivial_usage)
47# define APPLET_NOFORK(name,main,l,s,help) MAKE_USAGE(#name, help##_trivial_usage) 56# define APPLET_NOFORK(name,main,l,s,help) MAKE_USAGE(#name, help##_trivial_usage)
57# define APPLET_SCRIPTED(name,main,l,s,help) MAKE_USAGE(#name, help##_trivial_usage)
48 58
49#elif defined(MAKE_LINKS) 59#elif defined(MAKE_LINKS)
50# define APPLET(name,l,c) LINK l name 60# define APPLET(name,l,c) LINK l name
51# define APPLET_ODDNAME(name,main,l,s,help) LINK l name 61# define APPLET_ODDNAME(name,main,l,s,help) LINK l name
52# define APPLET_NOEXEC(name,main,l,s,help) LINK l name 62# define APPLET_NOEXEC(name,main,l,s,help) LINK l name
53# define APPLET_NOFORK(name,main,l,s,help) LINK l name 63# define APPLET_NOFORK(name,main,l,s,help) LINK l name
64# define APPLET_SCRIPTED(name,main,l,s,help) LINK l name
54 65
55#elif defined(MAKE_SUID) 66#elif defined(MAKE_SUID)
56# define APPLET(name,l,s) SUID s l name 67# define APPLET(name,l,s) SUID s l name
57# define APPLET_ODDNAME(name,main,l,s,help) SUID s l name 68# define APPLET_ODDNAME(name,main,l,s,help) SUID s l name
58# define APPLET_NOEXEC(name,main,l,s,help) SUID s l name 69# define APPLET_NOEXEC(name,main,l,s,help) SUID s l name
59# define APPLET_NOFORK(name,main,l,s,help) SUID s l name 70# define APPLET_NOFORK(name,main,l,s,help) SUID s l name
71# define APPLET_SCRIPTED(name,main,l,s,help) SUID s l name
72
73#elif defined(MAKE_SCRIPTS)
74# define APPLET(name,l,s)
75# define APPLET_ODDNAME(name,main,l,s,help)
76# define APPLET_NOEXEC(name,main,l,s,help)
77# define APPLET_NOFORK(name,main,l,s,help)
78# define APPLET_SCRIPTED(name,main,l,s,help) SCRIPT name
60 79
61#else 80#else
62 static struct bb_applet applets[] = { /* name, main, location, need_suid */ 81 static struct bb_applet applets[] = { /* name, main, location, need_suid */
@@ -64,6 +83,7 @@ s - suid type:
64# define APPLET_ODDNAME(name,main,l,s,help) { #name, #main, l, s }, 83# define APPLET_ODDNAME(name,main,l,s,help) { #name, #main, l, s },
65# define APPLET_NOEXEC(name,main,l,s,help) { #name, #main, l, s, 1 }, 84# define APPLET_NOEXEC(name,main,l,s,help) { #name, #main, l, s, 1 },
66# define APPLET_NOFORK(name,main,l,s,help) { #name, #main, l, s, 1, 1 }, 85# define APPLET_NOFORK(name,main,l,s,help) { #name, #main, l, s, 1, 1 },
86# define APPLET_SCRIPTED(name,main,l,s,help) { #name, #main, l, s },
67#endif 87#endif
68 88
69#if ENABLE_INSTALL_NO_USR 89#if ENABLE_INSTALL_NO_USR
@@ -84,3 +104,4 @@ INSERT
84#undef APPLET_ODDNAME 104#undef APPLET_ODDNAME
85#undef APPLET_NOEXEC 105#undef APPLET_NOEXEC
86#undef APPLET_NOFORK 106#undef APPLET_NOFORK
107#undef APPLET_SCRIPTED
diff --git a/include/libbb.h b/include/libbb.h
index a32608ebd..aa9e9d019 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -1322,8 +1322,8 @@ void bb_logenv_override(void) FAST_FUNC;
1322#endif 1322#endif
1323 1323
1324/* Embedded script support */ 1324/* Embedded script support */
1325int find_script_by_name(const char *name) FAST_FUNC;
1326char *get_script_content(unsigned n) FAST_FUNC; 1325char *get_script_content(unsigned n) FAST_FUNC;
1326int scripted_main(int argc, char** argv);
1327 1327
1328/* Applets which are useful from another applets */ 1328/* Applets which are useful from another applets */
1329int bb_cat(char** argv) FAST_FUNC; 1329int bb_cat(char** argv) FAST_FUNC;
diff --git a/libbb/appletlib.c b/libbb/appletlib.c
index 6dfaf1f41..a0ebaca29 100644
--- a/libbb/appletlib.c
+++ b/libbb/appletlib.c
@@ -51,7 +51,7 @@
51#include "usage_compressed.h" 51#include "usage_compressed.h"
52 52
53#if ENABLE_ASH_EMBEDDED_SCRIPTS 53#if ENABLE_ASH_EMBEDDED_SCRIPTS
54# define DEFINE_script_names 1 54# define DEFINE_SCRIPT_DATA 1
55# include "embedded_scripts.h" 55# include "embedded_scripts.h"
56#else 56#else
57# define NUM_SCRIPTS 0 57# define NUM_SCRIPTS 0
@@ -818,27 +818,21 @@ int busybox_main(int argc UNUSED_PARAM, char **argv)
818 /* prevent last comma to be in the very last pos */ 818 /* prevent last comma to be in the very last pos */
819 output_width--; 819 output_width--;
820 a = applet_names; 820 a = applet_names;
821 { 821 while (*a) {
822# if NUM_SCRIPTS > 0 822 int len2 = strlen(a) + 2;
823 int i; 823 if (col >= (int)output_width - len2) {
824 for (i = 0; i < 2; i++, a = script_names) 824 full_write2_str(",\n");
825# endif 825 col = 0;
826 while (*a) { 826 }
827 int len2 = strlen(a) + 2; 827 if (col == 0) {
828 if (col >= (int)output_width - len2) { 828 col = 6;
829 full_write2_str(",\n"); 829 full_write2_str("\t");
830 col = 0; 830 } else {
831 } 831 full_write2_str(", ");
832 if (col == 0) {
833 col = 6;
834 full_write2_str("\t");
835 } else {
836 full_write2_str(", ");
837 }
838 full_write2_str(a);
839 col += len2;
840 a += len2 - 1;
841 } 832 }
833 full_write2_str(a);
834 col += len2;
835 a += len2 - 1;
842 } 836 }
843 full_write2_str("\n"); 837 full_write2_str("\n");
844 return 0; 838 return 0;
@@ -946,20 +940,25 @@ void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **ar
946# endif /* NUM_APPLETS > 0 */ 940# endif /* NUM_APPLETS > 0 */
947 941
948# if NUM_SCRIPTS > 0 942# if NUM_SCRIPTS > 0
949int FAST_FUNC 943static int find_script_by_name(const char *name)
950find_script_by_name(const char *name)
951{ 944{
952 const char *s = script_names; 945 int i;
953 int i = 0; 946 int applet = find_applet_by_name(name);
954 947
955 while (*s) { 948 if (applet >= 0) {
956 if (strcmp(name, s) == 0) 949 for (i = 0; i < NUM_SCRIPTS; ++i)
957 return i; 950 if (applet_numbers[i] == applet)
958 i++; 951 return i;
959 while (*s++ != '\0')
960 continue;
961 } 952 }
962 return -0x10000; /* make it so that NUM_APPLETS + <error> is still < 0 */ 953 return -1;
954}
955
956int scripted_main(int argc UNUSED_PARAM, char **argv)
957{
958 int script = find_script_by_name(applet_name);
959 if (script >= 0)
960 exit(ash_main(-script - 1, argv));
961 return 0;
963} 962}
964 963
965char* FAST_FUNC 964char* FAST_FUNC
@@ -978,7 +977,7 @@ get_script_content(unsigned n)
978} 977}
979# endif /* NUM_SCRIPTS > 0 */ 978# endif /* NUM_SCRIPTS > 0 */
980 979
981# if ENABLE_BUSYBOX || NUM_APPLETS > 0 || NUM_SCRIPTS > 0 980# if ENABLE_BUSYBOX || NUM_APPLETS > 0
982static NORETURN void run_applet_and_exit(const char *name, char **argv) 981static NORETURN void run_applet_and_exit(const char *name, char **argv)
983{ 982{
984# if ENABLE_BUSYBOX 983# if ENABLE_BUSYBOX
@@ -993,13 +992,6 @@ static NORETURN void run_applet_and_exit(const char *name, char **argv)
993 run_applet_no_and_exit(applet, name, argv); 992 run_applet_no_and_exit(applet, name, argv);
994 } 993 }
995# endif 994# endif
996# if NUM_SCRIPTS > 0
997 {
998 int script = find_script_by_name(name);
999 if (script >= 0)
1000 exit(ash_main(-script - 1, argv));
1001 }
1002# endif
1003 995
1004 /*bb_error_msg_and_die("applet not found"); - links in printf */ 996 /*bb_error_msg_and_die("applet not found"); - links in printf */
1005 full_write2_str(applet_name); 997 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 @@
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
50#ifndef _POSIX_VDISABLE 44#ifndef _POSIX_VDISABLE
51# define _POSIX_VDISABLE '\0' 45# define _POSIX_VDISABLE '\0'
52#endif 46#endif
@@ -812,20 +806,14 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type)
812 } 806 }
813 pf_len = strlen(pfind); 807 pf_len = strlen(pfind);
814 808
815# if ENABLE_FEATURE_SH_STANDALONE && (NUM_APPLETS != 1 || NUM_SCRIPTS > 0) 809# if ENABLE_FEATURE_SH_STANDALONE && NUM_APPLETS != 1
816 if (type == FIND_EXE_ONLY && !dirbuf) { 810 if (type == FIND_EXE_ONLY && !dirbuf) {
817 const char *p; 811 const char *p = applet_names;
818# if NUM_APPLETS != 1 && NUM_SCRIPTS > 0 812
819 for (i = 0, p = applet_names; i < 2; i++, p = script_names)
820# elif NUM_APPLETS != 1 /* and NUM_SCRIPTS == 0 */
821 p = applet_names;
822# else /* NUM_APPLETS == 1 && NUM_SCRIPTS > 0 */
823 p = script_names;
824# endif
825 while (*p) { 813 while (*p) {
826 if (strncmp(pfind, p, pf_len) == 0) 814 if (strncmp(pfind, p, pf_len) == 0)
827 add_match(xstrdup(p)); 815 add_match(xstrdup(p));
828 while (*p++) 816 while (*p++ != '\0')
829 continue; 817 continue;
830 } 818 }
831 } 819 }
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 @@
1#!/bin/sh 1#!/bin/sh
2 2
3target="$1" 3target="$1"
4loc="$2" 4custom_loc="$2"
5applet_loc="$3"
5 6
6test "$target" || exit 1 7test "$target" || exit 1
7test "$SED" || SED=sed 8test "$SED" || SED=sed
@@ -14,46 +15,102 @@ if test $? != 0; then
14 exit 1 15 exit 1
15fi 16fi
16 17
17exec >"$target.$$" 18custom_scripts=""
18 19if [ -d "$custom_loc" ]
19scripts=""
20if [ -d "$loc" ]
21then 20then
22 scripts=$(cd $loc; ls * 2>/dev/null) 21 custom_scripts=$(cd $custom_loc; ls * 2>/dev/null)
23fi 22fi
23all_scripts=$(applets/busybox.mkscripts)
24
25# all_scripts includes applet scripts and custom scripts, sort them out
26applet_scripts=""
27for i in $all_scripts
28do
29 found=0
30 for j in $custom_scripts
31 do
32 if [ "$i" = "$j" ]
33 then
34 found=1
35 break;
36 fi
37 done
38 if [ $found -eq 0 ]
39 then
40 # anything that isn't a custom script is an applet script
41 applet_scripts="$applet_scripts $i"
42 fi
43done
24 44
25n=$(echo $scripts | wc -w) 45# we know the custom scripts are present but applet scripts might have
46# become detached from their configuration
47for i in $applet_scripts
48do
49 #if [ ! -f "$applet_loc/$i" -a ! -f "$custom_loc/$i" ]
50 if [ ! -f "$applet_loc/$i" ]
51 then
52 echo "missing applet script $i"
53 exit 1
54 fi
55done
26 56
27if [ $n -ne 0 ] 57n=$(echo $custom_scripts $applet_scripts | wc -w)
58nall=$(echo $all_scripts | wc -w)
59
60if [ $n -ne $nall ]
28then 61then
29 printf '#ifdef DEFINE_script_names\n' 62 echo "script mismatch $n != $nall"
30 printf 'const char script_names[] ALIGN1 = ' 63 exit 1
31 for i in $scripts 64fi
65
66concatenate_scripts() {
67 for i in $custom_scripts
68 do
69 cat $custom_loc/$i
70 printf '\000'
71 done
72 for i in $applet_scripts
32 do 73 do
33 printf '"%s\\0"' $i 74 cat $applet_loc/$i
75 printf '\000'
34 done 76 done
35 printf ';\n' 77}
78
79exec >"$target.$$"
80
81if [ $n -ne 0 ]
82then
83 printf '#ifdef DEFINE_SCRIPT_DATA\n'
84 if [ $n -ne 0 ]
85 then
86 printf 'const uint16_t applet_numbers[] = {\n'
87 for i in $custom_scripts $applet_scripts
88 do
89 # TODO support applets with names including invalid characters
90 printf '\tAPPLET_NO_%s,\n' $i
91 done
92 printf '};\n'
93 fi
36 printf '#else\n' 94 printf '#else\n'
37 printf 'extern const char script_names[] ALIGN1;\n' 95 if [ $n -ne 0 ]
96 then
97 printf 'extern const uint16_t applet_numbers[];\n'
98 fi
38 printf '#endif\n' 99 printf '#endif\n'
39fi 100fi
40printf "#define NUM_SCRIPTS $n\n\n" 101
102printf "\n"
103printf '#define NUM_SCRIPTS %d\n' $n
104printf "\n"
41 105
42if [ $n -ne 0 ] 106if [ $n -ne 0 ]
43then 107then
44 printf '#define UNPACKED_SCRIPTS_LENGTH ' 108 printf '#define UNPACKED_SCRIPTS_LENGTH '
45 for i in $scripts 109 concatenate_scripts | wc -c
46 do
47 cat $loc/$i
48 printf '\000'
49 done | wc -c
50 110
51 printf '#define PACKED_SCRIPTS \\\n' 111 printf '#define PACKED_SCRIPTS \\\n'
52 for i in $scripts 112 concatenate_scripts | bzip2 -1 | $DD bs=2 skip=1 2>/dev/null | \
53 do 113 od -v -b \
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 '^ ' \ 114 | grep -v '^ ' \
58 | $SED -e 's/^[^ ]*//' \ 115 | $SED -e 's/^[^ ]*//' \
59 -e 's/ //g' \ 116 -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"; }
17gen() { status "GEN" "$@"; } 17gen() { status "GEN" "$@"; }
18chk() { status "CHK" "$@"; } 18chk() { status "CHK" "$@"; }
19 19
20# scripts in the 'embed' directory are treated as fake applets
21custom_scripts()
22{
23 custom_loc="$1"
24 if [ -d "$custom_loc" ]
25 then
26 for i in $(cd "$custom_loc"; ls *)
27 do
28 printf "APPLET_SCRIPTED(%s, scripted, BB_DIR_USR_BIN, BB_SUID_DROP, dummy)\n" $i;
29 done
30 fi
31}
32
20generate() 33generate()
21{ 34{
22 # NB: data to be inserted at INSERT line is coming on stdin 35 # NB: data to be inserted at INSERT line is coming on stdin
23 src="$1" 36 src="$1"
24 dst="$2" 37 dst="$2"
25 header="$3" 38 header="$3"
39 loc="$4"
26 #chk "${dst}" 40 #chk "${dst}"
27 { 41 {
28 # Need to use printf: different shells have inconsistent 42 # Need to use printf: different shells have inconsistent
@@ -32,6 +46,10 @@ generate()
32 sed -n '/^INSERT$/ q; p' "${src}" 46 sed -n '/^INSERT$/ q; p' "${src}"
33 # copy stdin to stdout 47 # copy stdin to stdout
34 cat 48 cat
49 if [ -n "$loc" ]
50 then
51 custom_scripts "$loc"
52 fi
35 # print everything after INSERT line 53 # print everything after INSERT line
36 sed -n '/^INSERT$/ { 54 sed -n '/^INSERT$/ {
37 :l 55 :l
@@ -53,7 +71,8 @@ sed -n 's@^//applet:@@p' "$srctree"/*/*.c "$srctree"/*/*/*.c \
53| generate \ 71| generate \
54 "$srctree/include/applets.src.h" \ 72 "$srctree/include/applets.src.h" \
55 "include/applets.h" \ 73 "include/applets.h" \
56 "/* DO NOT EDIT. This file is generated from applets.src.h */" 74 "/* DO NOT EDIT. This file is generated from applets.src.h */" \
75 "$srctree/embed"
57 76
58# (Re)generate include/usage.h 77# (Re)generate include/usage.h
59# We add line continuation backslash after each line, 78# 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 @@
158//config: at build time. Like applets, scripts can be run as 158//config: at build time. Like applets, scripts can be run as
159//config: 'busybox SCRIPT ...' or by linking their name to the binary. 159//config: 'busybox SCRIPT ...' or by linking their name to the binary.
160//config: 160//config:
161//config: This also allows applets to be implemented as scripts: place
162//config: the script in 'applets_sh' and a stub C file containing
163//config: configuration in the appropriate subsystem directory.
164//config:
161//config:endif # ash options 165//config:endif # ash options
162 166
163//applet:IF_ASH(APPLET(ash, BB_DIR_BIN, BB_SUID_DROP)) 167//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
8016{ 8020{
8017#if ENABLE_FEATURE_SH_STANDALONE 8021#if ENABLE_FEATURE_SH_STANDALONE
8018 if (applet_no >= 0) { 8022 if (applet_no >= 0) {
8019# if NUM_SCRIPTS > 0
8020 if (applet_no < NUM_APPLETS)
8021# endif
8022 if (APPLET_IS_NOEXEC(applet_no)) { 8023 if (APPLET_IS_NOEXEC(applet_no)) {
8023 clearenv(); 8024 clearenv();
8024 while (*envp) 8025 while (*envp)
@@ -8088,9 +8089,6 @@ static void shellexec(char *prog, char **argv, const char *path, int idx)
8088 if (strchr(prog, '/') != NULL 8089 if (strchr(prog, '/') != NULL
8089#if ENABLE_FEATURE_SH_STANDALONE 8090#if ENABLE_FEATURE_SH_STANDALONE
8090 || (applet_no = find_applet_by_name(prog)) >= 0 8091 || (applet_no = find_applet_by_name(prog)) >= 0
8091# if NUM_SCRIPTS > 0
8092 || (applet_no = NUM_APPLETS + find_script_by_name(prog)) >= 0
8093# endif
8094#endif 8092#endif
8095 ) { 8093 ) {
8096 tryexec(IF_FEATURE_SH_STANDALONE(applet_no,) prog, argv, envp); 8094 tryexec(IF_FEATURE_SH_STANDALONE(applet_no,) prog, argv, envp);
@@ -10192,10 +10190,6 @@ evalcommand(union node *cmd, int flags)
10192 */ 10190 */
10193 /* find_command() encodes applet_no as (-2 - applet_no) */ 10191 /* find_command() encodes applet_no as (-2 - applet_no) */
10194 int applet_no = (- cmdentry.u.index - 2); 10192 int applet_no = (- cmdentry.u.index - 2);
10195# if NUM_SCRIPTS > 0
10196 /* Applets are ok, but not embedded scripts */
10197 if (applet_no < NUM_APPLETS)
10198# endif
10199 if (applet_no >= 0 && APPLET_IS_NOFORK(applet_no)) { 10193 if (applet_no >= 0 && APPLET_IS_NOFORK(applet_no)) {
10200 char **sv_environ; 10194 char **sv_environ;
10201 10195
@@ -13378,11 +13372,6 @@ find_command(char *name, struct cmdentry *entry, int act, const char *path)
13378#if ENABLE_FEATURE_SH_STANDALONE 13372#if ENABLE_FEATURE_SH_STANDALONE
13379 { 13373 {
13380 int applet_no = find_applet_by_name(name); 13374 int applet_no = find_applet_by_name(name);
13381# if NUM_SCRIPTS > 0
13382 if (applet_no < 0)
13383 /* embedded script indices are offset by NUM_APPLETS */
13384 applet_no = NUM_APPLETS + find_script_by_name(name);
13385# endif
13386 if (applet_no >= 0) { 13375 if (applet_no >= 0) {
13387 entry->cmdtype = CMDNORMAL; 13376 entry->cmdtype = CMDNORMAL;
13388 entry->u.index = -2 - applet_no; 13377 entry->u.index = -2 - applet_no;
diff --git a/util-linux/nologin.c b/util-linux/nologin.c
new file mode 100644
index 000000000..cc619bf8a
--- /dev/null
+++ b/util-linux/nologin.c
@@ -0,0 +1,27 @@
1//config:config NOLOGIN
2//config: bool "nologin"
3//config: default y
4//config: depends on ASH_EMBEDDED_SCRIPTS
5//config: help
6//config: Politely refuse a login
7//config:
8//config:config NOLOGIN_DEPENDENCIES
9//config: bool "Dependencies for nologin"
10//config: default y
11//config: depends on NOLOGIN
12//config: select CAT
13//config: select ECHO
14//config: select SLEEP
15//config: help
16//config: nologin is implemented as a shell script. It requires the
17//config: following in the runtime environment:
18//config: cat echo sleep
19//config: If you know these will be available externally you can
20//config: disable this option.
21
22//applet:IF_NOLOGIN(APPLET_SCRIPTED(nologin, scripted, BB_DIR_USR_SBIN, BB_SUID_DROP, nologin))
23
24//usage:#define nologin_trivial_usage
25//usage: ""
26//usage:#define nologin_full_usage "\n\n"
27//usage: "Politely refuse a login"