diff options
Diffstat (limited to 'common')
| -rw-r--r-- | common/cmd_mem.c | 71 | ||||
| -rw-r--r-- | common/cmd_pcmcia.c | 2 | ||||
| -rw-r--r-- | common/command.c | 153 | ||||
| -rw-r--r-- | common/hush.c | 85 | 
4 files changed, 303 insertions, 8 deletions
| diff --git a/common/cmd_mem.c b/common/cmd_mem.c index f18bfde3a..8430298a3 100644 --- a/common/cmd_mem.c +++ b/common/cmd_mem.c @@ -963,6 +963,8 @@ mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[])  	return 0;  } +#ifndef CONFIG_CRC32_VERIFY +  int do_mem_crc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])  {  	ulong addr, length; @@ -992,6 +994,62 @@ int do_mem_crc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])  	return 0;  } +#else	/* CONFIG_CRC32_VERIFY */ + +int do_mem_crc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ +	ulong addr, length; +	ulong crc; +	ulong *ptr; +	ulong vcrc;  +	int verify; +	int ac; +	char **av; + +	if (argc < 3) { +  usage: +		printf ("Usage:\n%s\n", cmdtp->usage); +		return 1; +	} + +	av = argv + 1; +	ac = argc - 1; +	if (strcmp(*av, "-v") == 0) { +		verify = 1; +		av++; +		ac--; +		if (ac < 3) +			goto usage; +	} else +		verify = 0; + +	addr = simple_strtoul(*av++, NULL, 16); +	addr += base_address; +	length = simple_strtoul(*av++, NULL, 16); + +	crc = crc32(0, (const uchar *) addr, length); + +	if (!verify) { +		printf ("CRC32 for %08lx ... %08lx ==> %08lx\n", +				addr, addr + length - 1, crc); +		if (ac > 2) { +			ptr = (ulong *) simple_strtoul (*av++, NULL, 16); +			*ptr = crc; +		} +	} else { +		vcrc = simple_strtoul(*av++, NULL, 16); +		if (vcrc != crc) { +			printf ("CRC32 for %08lx ... %08lx ==> %08lx != %08lx ** ERROR **\n", +					addr, addr + length - 1, crc, vcrc); +			return 1; +		} +	} + +	return 0; + +} +#endif	/* CONFIG_CRC32_VERIFY */ +  /**************************************************/  #if (CONFIG_COMMANDS & CFG_CMD_MEMORY)  U_BOOT_CMD( @@ -1032,12 +1090,25 @@ U_BOOT_CMD(  	"[.b, .w, .l] addr1 addr2 count\n    - compare memory\n"  ); +#ifndef CONFIG_CRC32_VERIFY +  U_BOOT_CMD(  	crc32,    4,    1,     do_mem_crc,  	"crc32   - checksum calculation\n",  	"address count [addr]\n    - compute CRC32 checksum [save at addr]\n"  ); +#else	/* CONFIG_CRC32_VERIFY */ + +U_BOOT_CMD( +	crc32,    5,    1,     do_mem_crc, +	"crc32   - checksum calculation\n", +	"address count [addr]\n    - compute CRC32 checksum [save at addr]\n" +	"-v address count crc\n    - verify crc of memory area\n" +); + +#endif	/* CONFIG_CRC32_VERIFY */ +  U_BOOT_CMD(  	base,    2,    1,     do_mem_base,  	"base    - print or set address offset\n", diff --git a/common/cmd_pcmcia.c b/common/cmd_pcmcia.c index 47632e755..7a2ca9e45 100644 --- a/common/cmd_pcmcia.c +++ b/common/cmd_pcmcia.c @@ -289,7 +289,7 @@ int pcmcia_on (void)  	return (rc);  } -#endif / CONFIG_PXA_PCMCIA */ +#endif /* CONFIG_PXA_PCMCIA */  #endif /* CONFIG_I82365 */ diff --git a/common/command.c b/common/command.c index df5d3e9bc..2b48a1c91 100644 --- a/common/command.c +++ b/common/command.c @@ -74,6 +74,159 @@ U_BOOT_CMD(  	"    - echo args to console; \\c suppresses newline\n"  ); +#ifdef CFG_HUSH_PARSER + +int +do_test (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ +	char **ap; +	int left, adv, expr, last_expr, neg, last_cmp; + +	/* args? */ +	if (argc < 3) +		return 1; + +#if 0 +	{ +		printf("test:"); +		left = 1;  +		while (argv[left]) +			printf(" %s", argv[left++]); +	} +#endif +	 +	last_expr = 0; +	left = argc - 1; ap = argv + 1; +	if (left > 0 && strcmp(ap[0], "!") == 0) { +		neg = 1; +		ap++; +		left--; +	} else +		neg = 0; + +	expr = -1; +	last_cmp = -1; +	last_expr = -1; +	while (left > 0) { + +		if (strcmp(ap[0], "-o") == 0 || strcmp(ap[0], "-a") == 0) +			adv = 1; +		else if (strcmp(ap[0], "-z") == 0 || strcmp(ap[0], "-n") == 0) +			adv = 2; +		else +			adv = 3; + +		if (left < adv) { +			expr = 1; +			break; +		} + +		if (adv == 1) { +			if (strcmp(ap[0], "-o") == 0) { +				last_expr = expr; +				last_cmp = 0; +			} else if (strcmp(ap[0], "-a") == 0) { +				last_expr = expr; +				last_cmp = 1; +			} else { +				expr = 1; +				break; +			} +		} + +		if (adv == 2) { +			if (strcmp(ap[0], "-z") == 0) +				expr = strlen(ap[1]) == 0 ? 0 : 1; +			else if (strcmp(ap[0], "-n") == 0) +				expr = strlen(ap[1]) == 0 ? 1 : 0; +			else { +				expr = 1; +				break; +			} + +			if (last_cmp == 0) +				expr = last_expr || expr; +			else if (last_cmp == 1) +				expr = last_expr && expr; +			last_cmp = -1; +		} + +		if (adv == 3) { +			if (strcmp(ap[1], "=") == 0) +				expr = strcmp(ap[0], ap[2]) == 0; +			else if (strcmp(ap[1], "!=") == 0) +				expr = strcmp(ap[0], ap[2]) != 0; +			else if (strcmp(ap[1], ">") == 0) +				expr = strcmp(ap[0], ap[2]) > 0; +			else if (strcmp(ap[1], "<") == 0) +				expr = strcmp(ap[0], ap[2]) < 0; +			else if (strcmp(ap[1], "-eq") == 0) +				expr = simple_strtol(ap[0], NULL, 10) == simple_strtol(ap[2], NULL, 10); +			else if (strcmp(ap[1], "-ne") == 0) +				expr = simple_strtol(ap[0], NULL, 10) != simple_strtol(ap[2], NULL, 10); +			else if (strcmp(ap[1], "-lt") == 0) +				expr = simple_strtol(ap[0], NULL, 10) < simple_strtol(ap[2], NULL, 10); +			else if (strcmp(ap[1], "-le") == 0) +				expr = simple_strtol(ap[0], NULL, 10) <= simple_strtol(ap[2], NULL, 10); +			else if (strcmp(ap[1], "-gt") == 0) +				expr = simple_strtol(ap[0], NULL, 10) > simple_strtol(ap[2], NULL, 10); +			else if (strcmp(ap[1], "-ge") == 0) +				expr = simple_strtol(ap[0], NULL, 10) >= simple_strtol(ap[2], NULL, 10); +			else { +				expr = 1; +				break; +			} + +			if (last_cmp == 0) +				expr = last_expr || expr; +			else if (last_cmp == 1) +				expr = last_expr && expr; +			last_cmp = -1; +		} + +		ap += adv; left -= adv; +	} + +	if (neg) +		expr = !expr; + +	expr = !expr; + +#if 0 +	printf(": returns %d\n", expr); +#endif + +	return expr; +} + +U_BOOT_CMD( +	test,	CFG_MAXARGS,	1,	do_test, + 	"test    - minimal test like /bin/sh\n", + 	"[args..]\n" +	"    - test functionality\n" +); + +int +do_exit (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ +	int r; + +	r = 0; +	if (argc > 1) +		r = simple_strtoul(argv[1], NULL, 10); + +	return -r - 2; +} + +U_BOOT_CMD( +	exit,	2,	1,	do_exit, + 	"exit    - exit script\n", +	"    - exit functionality\n" +); + + +#endif +  /*   * Use puts() instead of printf() to avoid printf buffer overflow   * for long help messages diff --git a/common/hush.c b/common/hush.c index eeb970cd5..47680edec 100644 --- a/common/hush.c +++ b/common/hush.c @@ -290,6 +290,7 @@ char **global_argv;  unsigned int global_argc;  #endif  unsigned int last_return_code; +int nesting_level;  #ifndef __U_BOOT__  extern char **environ; /* This is in <unistd.h>, but protected with __USE_GNU */  #endif @@ -416,7 +417,9 @@ static int b_check_space(o_string *o, int len);  static int b_addchr(o_string *o, int ch);  static void b_reset(o_string *o);  static int b_addqchr(o_string *o, int ch, int quote); +#ifndef __U_BOOT__  static int b_adduint(o_string *o, unsigned int i); +#endif  /*  in_str manipulations: */  static int static_get(struct in_str *i);  static int static_peek(struct in_str *i); @@ -936,6 +939,7 @@ char *simple_itoa(unsigned int i)  	return p + 1;  } +#ifndef __U_BOOT__  static int b_adduint(o_string *o, unsigned int i)  {  	int r; @@ -944,6 +948,7 @@ static int b_adduint(o_string *o, unsigned int i)  	do r=b_addchr(o, *p++); while (r==0 && *p);  	return r;  } +#endif  static int static_get(struct in_str *i)  { @@ -1921,6 +1926,10 @@ static int run_list_real(struct pipe *pi)  		}  		last_return_code=rcode;  #else +		if (rcode < -1) { +			last_return_code = -rcode - 2; +			return -2;	/* exit */ +		}  		last_return_code=(rcode == 0) ? 0 : 1;  #endif  #ifndef __U_BOOT__ @@ -2145,6 +2154,10 @@ static int xglob(o_string *dest, int flags, glob_t *pglob)  }  #endif +#ifdef __U_BOOT__ +static char *get_dollar_var(char ch); +#endif +  /* This is used to get/check local shell variables */  static char *get_local_var(const char *s)  { @@ -2152,6 +2165,12 @@ static char *get_local_var(const char *s)  	if (!s)  		return NULL; + +#ifdef __U_BOOT__ +	if (*s == '$') +		return get_dollar_var(s[1]); +#endif +  	for (cur = top_vars; cur; cur=cur->next)  		if(strcmp(cur->name, s)==0)  			return cur->value; @@ -2168,12 +2187,19 @@ static int set_local_var(const char *s, int flg_export)  	int result=0;  	struct variables *cur; +#ifdef __U_BOOT__ +	/* might be possible! */ +	if (!isalpha(*s)) +		return -1; +#endif +  	name=strdup(s);  #ifdef __U_BOOT__  	if (getenv(name) != NULL) {  		printf ("ERROR: "  				"There is a global environment variable with the same name.\n"); +		free(name);  		return -1;  	}  #endif @@ -2278,7 +2304,10 @@ static void unset_local_var(const char *name)  static int is_assignment(const char *s)  { -	if (s==NULL || !isalpha(*s)) return 0; +	if (s == NULL) +		return 0; + +	if (!isalpha(*s)) return 0;  	++s;  	while(isalnum(*s) || *s=='_') ++s;  	return *s=='='; @@ -2749,15 +2778,35 @@ static int parse_group(o_string *dest, struct p_context *ctx,   * see the bash man page under "Parameter Expansion" */  static char *lookup_param(char *src)  { -	char *p=NULL; -	if (src) { +	char *p; + +	if (!src) +		return NULL; +  		p = getenv(src);  		if (!p)  			p = get_local_var(src); -	} +  	return p;  } +#ifdef __U_BOOT__ +static char *get_dollar_var(char ch) +{ +	static char buf[40]; + +	buf[0] = '\0'; +	switch (ch) { +		case '?': +			sprintf(buf, "%u", (unsigned int)last_return_code); +			break; +		default: +			return NULL; +	} +	return buf; +} +#endif +  /* return code: 0 for OK, 1 for syntax error */  static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *input)  { @@ -2799,7 +2848,15 @@ static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *i  			break;  #endif  		case '?': +#ifndef __U_BOOT__  			b_adduint(dest,last_return_code); +#else +			ctx->child->sp++; +			b_addchr(dest, SPECIAL_VAR_SYMBOL); +			b_addchr(dest, '$'); +			b_addchr(dest, '?'); +			b_addchr(dest, SPECIAL_VAR_SYMBOL); +#endif  			advance = 1;  			break;  #ifndef __U_BOOT__ @@ -2885,8 +2942,11 @@ int parse_stream(o_string *dest, struct p_context *ctx,  		if (input->__promptme == 0) return 1;  #endif  		next = (ch == '\n') ? 0 : b_peek(input); -		debug_printf("parse_stream: ch=%c (%d) m=%d quote=%d\n", -			ch,ch,m,dest->quote); + +		debug_printf("parse_stream: ch=%c (%d) m=%d quote=%d - %c\n", +			ch >= ' ' ? ch : '.', ch, m, +			dest->quote, ctx->stack == NULL ? '*' : '.'); +  		if (m==0 || ((m==1 || m==2) && dest->quote)) {  			b_addqchr(dest, ch, dest->quote);  		} else { @@ -3107,7 +3167,18 @@ int parse_stream_outer(struct in_str *inp, int flag)  #ifndef __U_BOOT__  			run_list(ctx.list_head);  #else -			if (((code = run_list(ctx.list_head)) == -1)) +			code = run_list(ctx.list_head); +			if (code == -2) {	/* exit */ +				b_free(&temp); +				code = 0; +				/* XXX hackish way to not allow exit from main loop */ +				if (inp->peek == file_peek) { +					printf("exit not allowed from main input shell.\n"); +					continue; +				} +				break; +			} +			if (code == -1)  			    flag_repeat = 0;  #endif  		} else { |