[PATCH] ash: allow a profile script to be embedded in the binary
Ron Yorston
rmy at pobox.com
Sun Nov 18 10:57:17 UTC 2018
If the file embed/.profile exists at build time it is placed at the
start of the block of compressed scripts. Its name isn't included
in the list of scripts so it can't be run directly by the user.
Instead it is executed when a login shell is started, before
/etc/profile.
With no embed/.profile the binary is unchanged; with an empty script:
function old new delta
scripted_main 55 57 +2
ash_main 1346 1301 -45
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/1 up/down: 2/-45) Total: -43 bytes
Signed-off-by: Ron Yorston <rmy at pobox.com>
---
Makefile | 2 +-
libbb/appletlib.c | 9 ++++++---
scripts/embedded_scripts | 10 +++++++++-
shell/ash.c | 20 ++++++++++++++++++++
4 files changed, 36 insertions(+), 5 deletions(-)
diff --git a/Makefile b/Makefile
index f0b4da234..a9c3c3996 100644
--- a/Makefile
+++ b/Makefile
@@ -853,7 +853,7 @@ quiet_cmd_split_autoconf = SPLIT include/autoconf.h -> include/config/*
quiet_cmd_gen_embedded_scripts = GEN include/embedded_scripts.h
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 $(srctree)/embed/*) $(wildcard $(srctree)/applets_sh/*) $(srctree)/scripts/embedded_scripts
+include/config/MARKER: scripts/basic/split-include include/autoconf.h $(wildcard $(srctree)/embed/*) $(if $(wildcard $(srctree)/embed/.profile),$(srctree)/embed/.profile,) $(wildcard $(srctree)/applets_sh/*) $(srctree)/scripts/embedded_scripts
$(call cmd,split_autoconf)
$(call cmd,gen_bbconfigopts)
$(call cmd,gen_common_bufsiz)
diff --git a/libbb/appletlib.c b/libbb/appletlib.c
index a0ebaca29..e0a402031 100644
--- a/libbb/appletlib.c
+++ b/libbb/appletlib.c
@@ -55,8 +55,9 @@
# include "embedded_scripts.h"
#else
# define NUM_SCRIPTS 0
+# define HAS_PROFILE 0
#endif
-#if NUM_SCRIPTS > 0
+#if NUM_SCRIPTS > 0 || HAS_PROFILE
# include "bb_archive.h"
static const char packed_scripts[] ALIGN1 = { PACKED_SCRIPTS };
#endif
@@ -948,7 +949,7 @@ static int find_script_by_name(const char *name)
if (applet >= 0) {
for (i = 0; i < NUM_SCRIPTS; ++i)
if (applet_numbers[i] == applet)
- return i;
+ return i + HAS_PROFILE;
}
return -1;
}
@@ -960,7 +961,9 @@ int scripted_main(int argc UNUSED_PARAM, char **argv)
exit(ash_main(-script - 1, argv));
return 0;
}
+# endif /* NUM_SCRIPTS > 0 */
+# if NUM_SCRIPTS > 0 || HAS_PROFILE
char* FAST_FUNC
get_script_content(unsigned n)
{
@@ -975,7 +978,7 @@ get_script_content(unsigned n)
}
return t;
}
-# endif /* NUM_SCRIPTS > 0 */
+# endif /* NUM_SCRIPTS > 0 || HAS_PROFILE */
# if ENABLE_BUSYBOX || NUM_APPLETS > 0
static NORETURN void run_applet_and_exit(const char *name, char **argv)
diff --git a/scripts/embedded_scripts b/scripts/embedded_scripts
index b419bcb1f..9e137ca1d 100755
--- a/scripts/embedded_scripts
+++ b/scripts/embedded_scripts
@@ -86,7 +86,7 @@ concatenate_scripts() {
exec >"$target.$$"
-if [ $n -ne 0 ]
+if [ $n -ne 0 -o -f $custom_loc/.profile ]
then
printf '#ifdef DEFINE_SCRIPT_DATA\n'
if [ $n -ne 0 ]
@@ -109,6 +109,14 @@ fi
printf "\n"
printf '#define NUM_SCRIPTS %d\n' $n
+if [ -f $custom_loc/.profile ]
+then
+ # order is important: .profile must be first
+ custom_scripts=".profile $custom_scripts"
+ printf "#define HAS_PROFILE 1\n"
+else
+ printf "#define HAS_PROFILE 0\n"
+fi
printf "\n"
if [ $n -ne 0 ]
diff --git a/shell/ash.c b/shell/ash.c
index 44b3569dc..8233efb04 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -199,6 +199,7 @@
# include "embedded_scripts.h"
#else
# define NUM_SCRIPTS 0
+# define HAS_PROFILE 0
#endif
/* So far, all bash compat is controlled by one config option */
@@ -14163,6 +14164,9 @@ int ash_main(int argc UNUSED_PARAM, char **argv)
struct jmploc jmploc;
struct stackmark smark;
int login_sh;
+#if HAS_PROFILE
+ char *profile;
+#endif
/* Initialize global data */
INIT_G_misc();
@@ -14198,6 +14202,10 @@ int ash_main(int argc UNUSED_PARAM, char **argv)
popstackmark(&smark);
FORCE_INT_ON; /* enable interrupts */
+#if HAS_PROFILE
+ if (s == 0x1a)
+ goto state1a;
+#endif
if (s == 1)
goto state1;
if (s == 2)
@@ -14226,6 +14234,18 @@ int ash_main(int argc UNUSED_PARAM, char **argv)
if (login_sh) {
const char *hp;
+#if HAS_PROFILE
+ state = 0x1a;
+ profile = get_script_content(0);
+ if (profile) {
+ setinputstring(profile);
+ cmdloop(0);
+ popfile();
+ }
+ state1a:
+ free(profile);
+#endif
+
state = 1;
read_profile("/etc/profile");
state1:
--
2.19.1
More information about the busybox
mailing list