From 02013228914a1d17e8df15d4e2b7950469395a5c Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Fri, 15 May 2015 10:23:51 +0200 Subject: ripe-atlas-fw: imported version 4520 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Bjørn Mork --- shell/ash.c | 20 ++++ shell/hush.c | 384 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 391 insertions(+), 13 deletions(-) (limited to 'shell') 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 +#include /* #include */ #if ENABLE_HUSH_CASE #include @@ -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; -- cgit v1.2.3