Skip to content

Commit

Permalink
Treat custom and applet scripts as applets
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Denys Vlasenko <[email protected]>
  • Loading branch information
rmyorston authored and Denys Vlasenko committed Nov 17, 2018
1 parent e6a63bf commit 3778898
Show file tree
Hide file tree
Showing 17 changed files with 217 additions and 126 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,8 @@ cscope.po.out
#
tags
TAGS

#
# user-supplied scripts
#
/embed
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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/
Expand Down Expand Up @@ -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)
Expand Down
16 changes: 16 additions & 0 deletions applets/busybox.mkscripts
Original file line number Diff line number Diff line change
@@ -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
}'
5 changes: 0 additions & 5 deletions applets_sh/README

This file was deleted.

5 changes: 0 additions & 5 deletions applets_sh/dos2unix

This file was deleted.

3 changes: 3 additions & 0 deletions applets_sh/nologin
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
cat /etc/nologin.txt 2>/dev/null || echo This account is not available
sleep 5
exit 1
7 changes: 0 additions & 7 deletions applets_sh/tac

This file was deleted.

5 changes: 0 additions & 5 deletions applets_sh/unix2dos

This file was deleted.

4 changes: 0 additions & 4 deletions embed/nologin

This file was deleted.

21 changes: 21 additions & 0 deletions include/applets.src.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,48 +22,68 @@ 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 */
# define APPLET(name,l,s) { #name, #name, 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_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
Expand All @@ -84,3 +104,4 @@ INSERT
#undef APPLET_ODDNAME
#undef APPLET_NOEXEC
#undef APPLET_NOFORK
#undef APPLET_SCRIPTED
2 changes: 1 addition & 1 deletion include/libbb.h
Original file line number Diff line number Diff line change
Expand Up @@ -1322,8 +1322,8 @@ void bb_logenv_override(void) FAST_FUNC;
#endif

/* 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, char** argv);

/* Applets which are useful from another applets */
int bb_cat(char** argv) FAST_FUNC;
Expand Down
72 changes: 32 additions & 40 deletions libbb/appletlib.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -818,27 +818,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;
Expand Down Expand Up @@ -946,20 +940,25 @@ void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **ar
# endif /* NUM_APPLETS > 0 */

# if NUM_SCRIPTS > 0
int FAST_FUNC
find_script_by_name(const char *name)
static int 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;
}

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
Expand All @@ -978,7 +977,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
Expand All @@ -993,13 +992,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);
Expand Down
20 changes: 4 additions & 16 deletions libbb/lineedit.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}
}
Expand Down
Loading

0 comments on commit 3778898

Please sign in to comment.