aboutsummaryrefslogtreecommitdiff
path: root/shell/ash.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--shell/ash.c140
1 files changed, 139 insertions, 1 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 7131609e4..9d7ef032c 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -175,6 +175,25 @@
175//config: from a GUI application. Disable this if your platform doesn't 175//config: from a GUI application. Disable this if your platform doesn't
176//config: support the required APIs. 176//config: support the required APIs.
177//config: 177//config:
178//config:config ASH_EMBEDDED_SCRIPTS
179//config: bool "Embed scripts in the binary"
180//config: default n
181//config: depends on ASH || SH_IS_ASH || BASH_IS_ASH
182//config: help
183//config: Allow scripts to be compressed and embedded in the BusyBox
184//config: binary. The scripts should be placed in the 'embed' directory.
185//config: Such scripts can only be run by giving their name as an
186//config: argument to the shell, though aliases are set up to do this.
187//config: The names of the scripts are listed by the '-L' shell argument.
188//config:
189//config:config ASH_LIST_EMBEDDED_SCRIPTS
190//config: bool "Allow the contents of embedded scripts to be listed"
191//config: default n
192//config: depends on ASH_EMBEDDED_SCRIPTS
193//config: help
194//config: Allow the contents of embedded script to be listed using
195//config: the '-L name' shell argument.
196//config:
178//config:endif # ash options 197//config:endif # ash options
179 198
180//applet:IF_ASH(APPLET(ash, BB_DIR_BIN, BB_SUID_DROP)) 199//applet:IF_ASH(APPLET(ash, BB_DIR_BIN, BB_SUID_DROP))
@@ -209,6 +228,16 @@
209#include <sys/utsname.h> /* for setting $HOSTNAME */ 228#include <sys/utsname.h> /* for setting $HOSTNAME */
210#include "busybox.h" /* for applet_names */ 229#include "busybox.h" /* for applet_names */
211 230
231#if ENABLE_ASH_EMBEDDED_SCRIPTS
232#include "embedded_scripts.h"
233#else
234#define NUM_SCRIPTS 0
235#endif
236
237#if NUM_SCRIPTS
238static const char packed_scripts[] ALIGN1 = { PACKED_SCRIPTS };
239#endif
240
212/* So far, all bash compat is controlled by one config option */ 241/* So far, all bash compat is controlled by one config option */
213/* Separate defines document which part of code implements what */ 242/* Separate defines document which part of code implements what */
214/* function keyword */ 243/* function keyword */
@@ -11490,6 +11519,76 @@ setparam(char **argv)
11490#endif 11519#endif
11491} 11520}
11492 11521
11522#if NUM_SCRIPTS
11523#define BB_ARCHIVE_PUBLIC
11524# include "bb_archive.h"
11525static char *unpack_scripts(void)
11526{
11527 char *outbuf = NULL;
11528 bunzip_data *bd;
11529 int i;
11530 jmp_buf jmpbuf;
11531
11532 /* Setup for I/O error handling via longjmp */
11533 i = setjmp(jmpbuf);
11534 if (i == 0) {
11535 i = start_bunzip(&jmpbuf,
11536 &bd,
11537 /* src_fd: */ -1,
11538 /* inbuf: */ packed_scripts,
11539 /* len: */ sizeof(packed_scripts)
11540 );
11541 }
11542 /* read_bunzip can longjmp and end up here with i != 0
11543 * on read data errors! Not trivial */
11544 if (i == 0) {
11545 /* Cannot use xmalloc: will leak bd in NOFORK case! */
11546 outbuf = malloc_or_warn(UNPACKED_SCRIPTS_LENGTH);
11547 if (outbuf)
11548 read_bunzip(bd, outbuf, UNPACKED_SCRIPTS_LENGTH);
11549 }
11550 dealloc_bunzip(bd);
11551 return outbuf;
11552}
11553
11554static char *
11555check_embedded(const char *arg)
11556{
11557 int i;
11558 char *scripts;
11559 const char *s;
11560
11561 i = 0;
11562 for (s=script_names; *s; s+=strlen(s)+1) {
11563 if (strcmp(arg, s) == 0) {
11564 break;
11565 }
11566 ++i;
11567 }
11568
11569 if (i != NUM_SCRIPTS && (scripts=unpack_scripts()) != NULL) {
11570 char *t = scripts;
11571 while (i != 0) {
11572 t += strlen(t) + 1;
11573 --i;
11574 }
11575 return t;
11576 }
11577
11578 return NULL;
11579}
11580
11581static void
11582alias_embedded(void)
11583{
11584 const char *s;
11585
11586 for (s=script_names; *s; s+=strlen(s)+1) {
11587 setalias(s, auto_string(xasprintf("sh %s", s)));
11588 }
11589}
11590#endif
11591
11493/* 11592/*
11494 * Process shell options. The global variable argptr contains a pointer 11593 * Process shell options. The global variable argptr contains a pointer
11495 * to the argument list; we advance it past the options. 11594 * to the argument list; we advance it past the options.
@@ -11600,6 +11699,26 @@ options(int cmdline, int *login_sh)
11600 *login_sh = 1; 11699 *login_sh = 1;
11601 } 11700 }
11602 break; 11701 break;
11702#if NUM_SCRIPTS
11703 } else if (cmdline && (c == 'L')) {
11704#if ENABLE_ASH_LIST_EMBEDDED_SCRIPTS
11705 if (*argptr) {
11706 char *script;
11707
11708 if ((script=check_embedded(*argptr)) != NULL) {
11709 printf(script);
11710 }
11711 } else
11712#endif
11713 {
11714 const char *s;
11715
11716 for (s=script_names; *s; s+=strlen(s)+1) {
11717 printf("%s\n", s);
11718 }
11719 }
11720 exit(0);
11721#endif
11603 } else { 11722 } else {
11604 setoption(c, val); 11723 setoption(c, val);
11605 } 11724 }
@@ -14643,9 +14762,17 @@ init(void)
14643 } 14762 }
14644} 14763}
14645 14764
14646
14647//usage:#define ash_trivial_usage 14765//usage:#define ash_trivial_usage
14648//usage: "[-/+OPTIONS] [-/+o OPT]... [-c 'SCRIPT' [ARG0 [ARGS]] / FILE [ARGS] / -s [ARGS]]" 14766//usage: "[-/+OPTIONS] [-/+o OPT]... [-c 'SCRIPT' [ARG0 [ARGS]] / FILE [ARGS] / -s [ARGS]]"
14767//usage: IF_ASH_EMBEDDED_SCRIPTS(
14768//usage: " [-L"
14769//usage: )
14770//usage: IF_ASH_LIST_EMBEDDED_SCRIPTS(
14771//usage: " [name]"
14772//usage: )
14773//usage: IF_ASH_EMBEDDED_SCRIPTS(
14774//usage: "]"
14775//usage: )
14649//usage:#define ash_full_usage "\n\n" 14776//usage:#define ash_full_usage "\n\n"
14650//usage: "Unix shell interpreter" 14777//usage: "Unix shell interpreter"
14651 14778
@@ -14689,12 +14816,23 @@ procargs(char **argv)
14689#if DEBUG == 2 14816#if DEBUG == 2
14690 debug = 1; 14817 debug = 1;
14691#endif 14818#endif
14819#if NUM_SCRIPTS
14820 alias_embedded();
14821#endif
14692 /* POSIX 1003.2: first arg after "-c CMD" is $0, remainder $1... */ 14822 /* POSIX 1003.2: first arg after "-c CMD" is $0, remainder $1... */
14693 if (xminusc) { 14823 if (xminusc) {
14694 minusc = *xargv++; 14824 minusc = *xargv++;
14695 if (*xargv) 14825 if (*xargv)
14696 goto setarg0; 14826 goto setarg0;
14697 } else if (!sflag) { 14827 } else if (!sflag) {
14828#if NUM_SCRIPTS
14829 char *script;
14830 if ((script=check_embedded(*xargv)) != NULL) {
14831 setinputstring(script);
14832 xflag = 0;
14833 goto setarg0;
14834 }
14835#endif
14698 setinputfile(*xargv, 0); 14836 setinputfile(*xargv, 0);
14699#if ENABLE_PLATFORM_MINGW32 14837#if ENABLE_PLATFORM_MINGW32
14700 convert_slashes(*xargv); 14838 convert_slashes(*xargv);