aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorBjørn Mork <bjorn@mork.no>2015-05-15 10:23:51 +0200
committerBjørn Mork <bjorn@mork.no>2015-05-15 10:23:51 +0200
commit02013228914a1d17e8df15d4e2b7950469395a5c (patch)
tree48d2fbe2f5a5adb60cbeabc26fadaec8e0fa82ed /shell
parent9b3dbb454e8f8a463d5fe4541ee2001585527bc6 (diff)
ripe-atlas-fw: imported version 45204520
Signed-off-by: Bjørn Mork <bjorn@mork.no>
Diffstat (limited to 'shell')
-rw-r--r--shell/ash.c20
-rw-r--r--shell/hush.c384
2 files changed, 391 insertions, 13 deletions
diff --git a/shell/ash.c b/shell/ash.c
index d6fd388..6f843a9 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -244,6 +244,7 @@ extern struct globals_misc *const ash_ptr_to_globals_misc;
physdir = nullstr; \
} while (0)
+static int testadd_main(char **argv);
/* ============ Utility functions */
static int isdigit_str9(const char *str)
@@ -8601,11 +8602,14 @@ static int ulimitcmd(int, char **);
#define echocmd echo_main
#define printfcmd printf_main
#define testcmd test_main
+#define testadd testadd_main
/* Keep these in proper order since it is searched via bsearch() */
static const struct builtincmd builtintab[] = {
{ BUILTIN_SPEC_REG ".", dotcmd },
{ BUILTIN_SPEC_REG ":", truecmd },
+ { BUILTIN_REGULAR "[", testadd },
+ { BUILTIN_REGULAR "[[", testadd },
#if ENABLE_ASH_BUILTIN_TEST
{ BUILTIN_REGULAR "[", testcmd },
#if ENABLE_ASH_BASH_COMPAT
@@ -8661,6 +8665,7 @@ static const struct builtincmd builtintab[] = {
{ BUILTIN_SPEC_REG "set", setcmd },
{ BUILTIN_SPEC_REG "shift", shiftcmd },
{ BUILTIN_SPEC_REG "source", dotcmd },
+ { BUILTIN_REGULAR "test", testadd },
#if ENABLE_ASH_BUILTIN_TEST
{ BUILTIN_REGULAR "test", testcmd },
#endif
@@ -13760,3 +13765,18 @@ int main(int argc, char **argv)
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
+
+
+static int testadd_main(char **argv)
+{
+ char *p;
+ int r1;
+ int r2;
+ char * opnd1;
+ char * opnd2;
+ opnd1 = argv[1];
+ opnd2 = argv[2];
+ r1 = strtol(opnd1, &p, 10);
+ r2 = strtol(opnd2, &p, 10);
+ return ((r1+r2));
+}
diff --git a/shell/hush.c b/shell/hush.c
index 4212729..9b0d850 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -68,6 +68,7 @@
#include "busybox.h" /* for APPLET_IS_NOFORK/NOEXEC */
#include <glob.h>
+#include <stdlib.h>
/* #include <dmalloc.h> */
#if ENABLE_HUSH_CASE
#include <fnmatch.h>
@@ -458,8 +459,11 @@ struct globals {
smallint fake_mode;
/* these three support $?, $#, and $1 */
smalluint last_return_code;
- char **global_argv;
+ /* is global_argv and global_argv[1..n] malloced? (note: not [0]) */
+ smalluint global_args_malloced;
+ /* how many non-NULL argv's we have. NB: $# + 1 */
int global_argc;
+ char **global_argv;
#if ENABLE_HUSH_LOOPS
unsigned depth_break_continue;
unsigned depth_of_loop;
@@ -633,7 +637,7 @@ static char *unbackslash(char *src)
return dst;
}
-static char **add_strings_to_strings(char **strings, char **add)
+static char **add_strings_to_strings(char **strings, char **add, int need_to_dup)
{
int i;
unsigned count1;
@@ -658,7 +662,7 @@ static char **add_strings_to_strings(char **strings, char **add)
v[count1 + count2] = NULL;
i = count2;
while (--i >= 0)
- v[count1 + i] = add[i];
+ v[count1 + i] = (need_to_dup ? xstrdup(add[i]) : add[i]);
return v;
}
@@ -667,7 +671,7 @@ static char **add_string_to_strings(char **strings, char *add)
char *v[2];
v[0] = add;
v[1] = NULL;
- return add_strings_to_strings(strings, v);
+ return add_strings_to_strings(strings, v, /*dup:*/ 0);
}
static void putenv_all(char **strings)
@@ -756,6 +760,16 @@ static int builtin_help(char **argv);
static int builtin_pwd(char **argv);
static int builtin_read(char **argv);
static int builtin_test(char **argv);
+static int builtin_add(char **argv);
+static int builtin_sub(char **argv);
+static int builtin_rchoose(char **argv);
+static int builtin_findpid(char **argv);
+static int builtin_sleepkick(char **argv);
+static int builtin_buddyinfo(char **argv);
+static int builtin_epoch(char **argv);
+static int builtin_condmv(char **argv);
+static int builtin_dfrm(char **argv);
+static int builtin_rxtxrpt(char **argv);
static int builtin_true(char **argv);
static int builtin_set(char **argv);
static int builtin_shift(char **argv);
@@ -792,6 +806,11 @@ static const struct built_in_command bltins[] = {
BLTIN(":" , builtin_true, "No-op"),
BLTIN("[" , builtin_test, "Test condition"),
BLTIN("[[" , builtin_test, "Test condition"),
+ BLTIN("[" , builtin_add, "Add two integers"),
+ BLTIN("[[" , builtin_add, "Add two integers"),
+ BLTIN("[" , builtin_sub, "Substract two integers"),
+ BLTIN("[[" , builtin_sub, "Substract two integers"),
+
#if ENABLE_HUSH_JOB
BLTIN("bg" , builtin_fg_bg, "Resume a job in the background"),
#endif
@@ -802,6 +821,14 @@ static const struct built_in_command bltins[] = {
#if ENABLE_HUSH_LOOPS
BLTIN("continue", builtin_continue, "Start new loop iteration"),
#endif
+ BLTIN("rchoose" , builtin_rchoose, "return a random one from the args"),
+ BLTIN("findpid" , builtin_findpid, "find process /proc/"),
+ BLTIN("buddyinfo" , builtin_buddyinfo, "print /proc/buddyinfo"),
+ BLTIN("sleepkick" , builtin_sleepkick, "sleep and kick the watchdog"),
+ BLTIN("epoch" , builtin_epoch, "UNIX epoch"),
+ BLTIN("condmv" , builtin_condmv, "conditional move"),
+ BLTIN("dfrm" , builtin_dfrm, "cleanup if free space gets too low"),
+ BLTIN("rxtxrpt" , builtin_rxtxrpt, "report RX and TX"),
BLTIN("echo" , builtin_echo, "Write to stdout"),
BLTIN("eval" , builtin_eval, "Construct and run shell command"),
BLTIN("exec" , builtin_exec, "Execute command, don't return to shell"),
@@ -818,6 +845,8 @@ static const struct built_in_command bltins[] = {
BLTIN("shift" , builtin_shift, "Shift positional parameters"),
// BLTIN("trap" , builtin_not_written, "Trap signals"),
BLTIN("test" , builtin_test, "Test condition"),
+ BLTIN("add" , builtin_add, "Add two integers."),
+ BLTIN("sub" , builtin_sub, "Subtract two integers."),
// BLTIN("ulimit", builtin_not_written, "Control resource limits"),
BLTIN("umask" , builtin_umask, "Set file creation mask"),
BLTIN("unset" , builtin_unset, "Unset environment variable"),
@@ -1213,8 +1242,13 @@ static int o_glob(o_string *o, int n)
* Otherwise, just finish current list[] and start new */
static int o_save_ptr(o_string *o, int n)
{
- if (o->o_glob)
- return o_glob(o, n); /* o_save_ptr_helper is inside */
+ if (o->o_glob) { /* if globbing is requested */
+ /* If o->has_empty_slot, list[n] was already globbed
+ * (if it was requested back then when it was filled)
+ * so don't do that again! */
+ if (!o->has_empty_slot)
+ return o_glob(o, n); /* o_save_ptr_helper is inside */
+ }
return o_save_ptr_helper(o, n);
}
@@ -4279,6 +4313,11 @@ int hush_main(int argc, char **argv)
switch (opt) {
case 'c':
G.global_argv = argv + optind;
+ if (!argv[optind]) {
+ /* -c 'script' (no params): prevent empty $0 */
+ *--G.global_argv = argv[0];
+ optind--;
+ } /* else -c 'script' PAR0 PAR1: $0 is PAR0 */
G.global_argc = argc - optind;
opt = parse_and_run_string(optarg, 0 /* parse_flag */);
goto final_return;
@@ -4412,6 +4451,269 @@ static int builtin_true(char **argv UNUSED_PARAM)
return 0;
}
+static int builtin_sleepkick (char **argv)
+{
+#define WATCHDOGDEV "/dev/watchdog"
+ unsigned duration;
+ unsigned watchdog;
+ int modDuration = 0;
+ if (argv[1] == NULL)
+ return (1);
+
+ duration = xatou(argv[1]);
+
+ if(argv[2])
+ {
+ int fd; /* File handler for watchdog */
+ int i = 0;
+ int iMax = 0;
+
+ watchdog = xatou(argv[2]);
+ iMax = (int) (duration / watchdog);
+
+ if( duration >= watchdog)
+ {
+ modDuration = duration % watchdog;
+ }
+ else {
+ modDuration = duration;
+ }
+
+ fd = open(WATCHDOGDEV, O_RDWR);
+ for( i = 0; i < iMax; i++)
+ {
+ write(fd, "1", 1);
+ sleep(watchdog);
+ }
+ if(modDuration)
+ {
+ write(fd, "1", 1);
+ sleep(modDuration);
+ write(fd, "1", 1);
+ }
+ close(fd);
+ }
+ else
+ {
+ sleep(duration);
+ }
+ return 0;
+}
+
+static int builtin_add(char **argv)
+{
+ char *p;
+ int r1;
+ int r2;
+ char * opnd1;
+ char * opnd2;
+ opnd1 = argv[1];
+ opnd2 = argv[2];
+ r1 = strtol(opnd1, &p, 10);
+ r2 = strtol(opnd2, &p, 10);
+ return ((r1+r2));
+}
+
+static int builtin_epoch (char **argv)
+{
+ char *p;
+ int r1 = 0;
+ char * opnd1;
+ opnd1 = argv[1];
+ if(argv[1])
+ r1 = strtol(opnd1, &p, 10);
+ if(r1 > 0 )
+ {
+ int r2 = time(0) - r1;
+ printf("%d\n", r2);
+ return EXIT_SUCCESS;
+ }
+ printf ("%ld\n", (time(0)));
+ return EXIT_SUCCESS;
+}
+
+static int builtin_buddyinfo(char **argv)
+{
+ char *lowmemChar;
+ unsigned lowmem = 0;
+ FILE *fp = xfopen_for_read("/proc/buddyinfo");
+ FILE *fp1 = xfopen_for_read("/proc/buddyinfo");
+ char aa[10];
+ char *my_mac ;
+ int i = 0;
+ int j = 0;
+ int memBlock = 4;
+ int fReboot = 1; // don't reboot
+ int freeMem = 0;
+ int jMax = 64; // enough
+ struct sysinfo info;
+
+ lowmemChar = argv[1];
+
+ if(lowmemChar)
+ lowmem = xatou(lowmemChar);
+ fscanf(fp, "%s", aa);
+ fscanf(fp, "%s", aa);
+ fscanf(fp, "%s", aa);
+ fscanf(fp, "%s", aa);
+
+ my_mac = getenv("ETHER_SCANNED");
+
+ if (lowmem >= 4 )
+ {
+ fReboot = 0; // env variable is set sow we check for low thershhold
+ }
+ printf ("RESULT 9001 ongoing %d ", (int)time(0));
+ if (my_mac != NULL)
+ printf("%s ", my_mac);
+ else
+ printf( "AAAAAABBBBBB ");
+ /* get uptime and print it */
+ sysinfo(&info);
+ printf ("%-7ld", info.uptime );
+
+ for (j=0; j < jMax; j++)
+ {
+ if (fscanf(fp, "%d", &i) != 1)
+ break;
+ freeMem += ( memBlock * i);
+ if ( lowmem >= 4)
+ {
+ if( memBlock >= lowmem)
+ {
+ if(fReboot == 0)
+ {
+ if (i > 0 )
+ {
+ fReboot = 1;
+
+ }
+ }
+ }
+ }
+ memBlock *= 2;
+ }
+
+ /* now print it */
+
+ printf (" %-5d " , freeMem);
+
+ fclose (fp);
+ fscanf(fp1, "%s", aa);
+ fscanf(fp1, "%s", aa);
+ fscanf(fp1, "%s", aa);
+ fscanf(fp1, "%s", aa);
+
+
+ for (j=0; j < jMax ; j++)
+ {
+ if (fscanf(fp1, "%d", &i) != 1)
+ break;
+ printf("%-3d ", i);
+ }
+
+ printf ("\n");
+ fclose(fp1);
+ if(fReboot == 0 )
+ {
+ fprintf(stderr, "buddy info returned 1 for block %d\n", lowmem);
+ return (EXIT_FAILURE);
+ }
+ return 0;
+}
+
+static int builtin_findpid(char **argv)
+{
+ procps_status_t* p = NULL;
+ int found = 0;
+
+ if (argv[1])
+ {
+ while ((p = procps_scan(p, PSSCAN_PID|PSSCAN_COMM|PSSCAN_ARGVN)))
+ {
+ if (comm_match(p, argv[1])
+ /* or we require argv0 to match (essential for matching reexeced
+ /proc/self/exe)*/
+ || (p->argv0 && strcmp(bb_basename(p->argv0), *argv) == 0)
+ /* TODO: we can also try /proc/NUM/exe link, do we want that? */
+ )
+ {
+ found = 1; /* found the match but return at the end */
+ /* otherwise free_procps won't be called
+ d will remain open */
+ }
+ }
+ }
+ return !found; /* exit 0 is success */
+}
+
+int condmv_main(int argc, char *argv[]);
+
+static int builtin_condmv(char **argv)
+{
+ int argc;
+
+ for (argc= 0; argv[argc] != 0; argc++)
+ ;
+ return condmv_main(argc, argv);
+}
+
+int dfrm_main(int argc, char *argv[]);
+
+static int builtin_dfrm(char **argv)
+{
+ int argc;
+
+ for (argc= 0; argv[argc] != 0; argc++)
+ ;
+ return dfrm_main(argc, argv);
+}
+
+int rxtxrpt_main(int argc, char *argv[]);
+
+static int builtin_rxtxrpt(char **argv)
+{
+ int argc;
+
+ for (argc= 0; argv[argc] != 0; argc++)
+ ;
+ return rxtxrpt_main(argc, argv);
+}
+
+
+static int builtin_rchoose(char **argv)
+{
+ int argc = 0;
+ int r;
+
+ srandom (time (0));
+ r = random();
+ while (*argv) {
+ argc++;
+ argv++;
+ }
+ argv -= argc;
+ argv++;
+ r %= (argc - 1);
+ printf ("%s\n", argv[r]);
+ return fflush(stdout);
+}
+
+static int builtin_sub(char **argv)
+{
+ char *p;
+ int r1;
+ int r2;
+ char * opnd1;
+ char * opnd2;
+ opnd1 = argv[1];
+ opnd2 = argv[2];
+ r1 = strtol(opnd1, &p, 10);
+ r2 = strtol(opnd2, &p, 10);
+ printf ("%d\n", (r1-r2));
+ return (fflush(stdout));
+}
+
static int builtin_test(char **argv)
{
int argc = 0;
@@ -4639,17 +4941,68 @@ static int builtin_read(char **argv)
return set_local_var(string, 0);
}
-/* built-in 'set [VAR=value]' handler */
+/* built-in 'set' handler
+ * SUSv3 says:
+ * set [-abCefmnuvx] [-h] [-o option] [argument...]
+ * set [+abCefmnuvx] [+h] [+o option] [argument...]
+ * set -- [argument...]
+ * set -o
+ * set +o
+ * Implementations shall support the options in both their hyphen and
+ * plus-sign forms. These options can also be specified as options to sh.
+ * Examples:
+ * Write out all variables and their values: set
+ * Set $1, $2, and $3 and set "$#" to 3: set c a b
+ * Turn on the -x and -v options: set -xv
+ * Unset all positional parameters: set --
+ * Set $1 to the value of x, even if it begins with '-' or '+': set -- "$x"
+ * Set the positional parameters to the expansion of x, even if x expands
+ * with a leading '-' or '+': set -- $x
+ *
+ * So far, we only support "set -- [argument...]" by ignoring all options
+ * (also, "-o option" will be mishandled by taking "option" as parameter #1).
+ */
static int builtin_set(char **argv)
{
- char *temp = argv[1];
struct variable *e;
+ char **pp;
+ char *arg = *++argv;
- if (temp == NULL)
+ if (arg == NULL) {
for (e = G.top_var; e; e = e->next)
puts(e->varstr);
- else
- set_local_var(xstrdup(temp), 0);
+ } else {
+ /* NB: G.global_argv[0] ($0) is never freed/changed */
+
+ if (G.global_args_malloced) {
+ pp = G.global_argv;
+ while (*++pp)
+ free(*pp);
+ G.global_argv[1] = NULL;
+ } else {
+ G.global_args_malloced = 1;
+ pp = xzalloc(sizeof(pp[0]) * 2);
+ pp[0] = G.global_argv[0]; /* retain $0 */
+ G.global_argv = pp;
+ }
+ do {
+ if (arg[0] == '+')
+ continue;
+ if (arg[0] != '-')
+ break;
+ if (arg[1] == '-' && arg[2] == '\0') {
+ argv++;
+ break;
+ }
+ } while ((arg = *++argv) != NULL);
+ /* Now argv[0] is 1st argument */
+
+ /* This realloc's G.global_argv */
+ G.global_argv = pp = add_strings_to_strings(G.global_argv, argv, /*dup:*/ 1);
+ G.global_argc = 1;
+ while (*++pp)
+ G.global_argc++;
+ }
return EXIT_SUCCESS;
}
@@ -4661,9 +5014,14 @@ static int builtin_shift(char **argv)
n = atoi(argv[1]);
}
if (n >= 0 && n < G.global_argc) {
- G.global_argv[n] = G.global_argv[0];
+ if (G.global_args_malloced) {
+ int m = 1;
+ while (m <= n)
+ free(G.global_argv[m++]);
+ }
G.global_argc -= n;
- G.global_argv += n;
+ memmove(&G.global_argv[1], &G.global_argv[n+1],
+ G.global_argc * sizeof(G.global_argv[0]));
return EXIT_SUCCESS;
}
return EXIT_FAILURE;