diff options
Diffstat (limited to 'common/main.c')
| -rw-r--r-- | common/main.c | 85 | 
1 files changed, 85 insertions, 0 deletions
| diff --git a/common/main.c b/common/main.c index a93335798..d96ba0a89 100644 --- a/common/main.c +++ b/common/main.c @@ -30,6 +30,7 @@  #include <common.h>  #include <watchdog.h>  #include <command.h> +#include <malloc.h>  #include <version.h>  #ifdef CONFIG_MODEM_SUPPORT  #include <malloc.h>		/* for free() prototype */ @@ -1373,6 +1374,90 @@ int run_command(const char *cmd, int flag)  #endif  } +#ifndef CONFIG_SYS_HUSH_PARSER +/** + * Execute a list of command separated by ; or \n using the built-in parser. + * + * This function cannot take a const char * for the command, since if it + * finds newlines in the string, it replaces them with \0. + * + * @param cmd	String containing list of commands + * @param flag	Execution flags (CMD_FLAG_...) + * @return 0 on success, or != 0 on error. + */ +static int builtin_run_command_list(char *cmd, int flag) +{ +	char *line, *next; +	int rcode = 0; + +	/* +	 * Break into individual lines, and execute each line; terminate on +	 * error. +	 */ +	line = next = cmd; +	while (*next) { +		if (*next == '\n') { +			*next = '\0'; +			/* run only non-empty commands */ +			if (*line) { +				debug("** exec: \"%s\"\n", line); +				if (builtin_run_command(line, 0) < 0) { +					rcode = 1; +					break; +				} +			} +			line = next + 1; +		} +		++next; +	} +	if (rcode == 0 && *line) +		rcode = (builtin_run_command(line, 0) >= 0); + +	return rcode; +} +#endif + +int run_command_list(const char *cmd, int len, int flag) +{ +	int need_buff = 1; +	char *buff = (char *)cmd;	/* cast away const */ +	int rcode = 0; + +	if (len == -1) { +		len = strlen(cmd); +#ifdef CONFIG_SYS_HUSH_PARSER +		/* hush will never change our string */ +		need_buff = 0; +#else +		/* the built-in parser will change our string if it sees \n */ +		need_buff = strchr(cmd, '\n') != NULL; +#endif +	} +	if (need_buff) { +		buff = malloc(len + 1); +		if (!buff) +			return 1; +		memcpy(buff, cmd, len); +		buff[len] = '\0'; +	} +#ifdef CONFIG_SYS_HUSH_PARSER +	rcode = parse_string_outer(buff, FLAG_PARSE_SEMICOLON); +#else +	/* +	 * This function will overwrite any \n it sees with a \0, which +	 * is why it can't work with a const char *. Here we are making +	 * using of internal knowledge of this function, to avoid always +	 * doing a malloc() which is actually required only in a case that +	 * is pretty rare. +	 */ +	rcode = builtin_run_command_list(buff, flag); +	if (need_buff) +		free(buff); +#endif + +	return rcode; +} +  /****************************************************************************/  #if defined(CONFIG_CMD_RUN) |