예제 #1
0
파일: nvm-utils.c 프로젝트: Undrizzle/apps
void __do_env_get_parameter(env_t *nvm, const char *key, char *value)
{
	int oldval;
	unsigned char *env, *nxt = NULL;

	unsigned char *env_data = nvm->data;

	/*
	 * search if variable with this name already exists
	 */
	oldval = -1;
	for (env=env_data; *env; env=nxt+1)
	{
		for (nxt=env; *nxt; ++nxt)
			;
		if ((oldval = envmatch((unsigned char *)key, env-env_data, env_data)) >= 0)
			break;
	}
	
	if (oldval >= 0)
	{
		strcpy(value, env_data + oldval);
	}
	else
	{
		value[0] = '\0';
	}	
}
예제 #2
0
int getenv_r(char *name, char *buf, unsigned len){
	int i, nxt;

	for(i = 0; env_get_char(i) != '\0'; i = nxt + 1){
		int val, n;

		for(nxt = i; env_get_char(nxt) != '\0'; ++nxt){
			if(nxt >= CFG_ENV_SIZE){
				return(-1);
			}
		}
		if((val = envmatch((uchar *)name, i)) < 0){
			continue;
		}
		/* found; copy out */
		n = 0;
		while((len > n++) && (*buf++ = env_get_char(val++)) != '\0');

		if(len == n){
			*buf = '\0';
		}

		return(n);
	}

	return(-1);
}
        /* tear down ed*/

#ifdef DEBUGME
        printk(KERN_ERR\
            "%s: Tearing down data!\n",\
             __func__);
#endif /*DEBUGME*/
        ed.mtd = -1;
        kfree(ed.data);
        ed.data = NULL;
        put_mtd_device(ed.mtds[0]); ed.mtds[0] = NULL;
        put_mtd_device(ed.mtds[1]); ed.mtds[1] = NULL;
#ifdef DEBUGME
        printk(KERN_ERR\
            "%s: Tearing down complete!\n",\
             __func__);
#endif /*DEBUGME*/
        return (*buf) ? 0 : -1;
    } else {
        printk(KERN_ERR\
            "%s: Failed to read the env block!\n",\
            __func__);
        return -3;
    }
    return 0;
}
#else /*CONFIG_CIRRUS_DUAL_MTD_ENV*/
int rtcnvet_get_env(char *name, char **buf)
{
    int j, k, nxt;

    if (!env_valid) {
        *buf = NULL;
        return -1;
    }

    k = -1;

    for (j = 0; env_get_char(j) != '\0'; j = nxt+1) {

        for (nxt = j; env_get_char(nxt) != '\0'; ++nxt)
            ;
        k = envmatch((unsigned char *)name, j);
        if (k < 0)
            continue;

        break;
    }

    if (k < 0) {
        printk(KERN_ERR "## Error: \"%s\" not defined\n", name);
        *buf = NULL;
    } else
        *buf = &env_buf[k];

    return (*buf) ? 0 : -1;
}
예제 #4
0
파일: cmd_nvedit.c 프로젝트: aosp/uboot
/*
 * Look up variable from environment for restricted C runtime env.
 */
int getenv_f(const char *name, char *buf, unsigned len)
{
	int i, nxt;

	for (i = 0; env_get_char(i) != '\0'; i = nxt+1) {
		int val, n;

		for (nxt = i; env_get_char(nxt) != '\0'; ++nxt) {
			if (nxt >= CONFIG_ENV_SIZE)
				return -1;
		}

		val = envmatch((uchar *)name, i);
		if (val < 0)
			continue;

		/* found; copy out */
		for (n = 0; n < len; ++n, ++buf) {
			if ((*buf = env_get_char(val++)) == '\0')
				return n;
		}

		if (n)
			*--buf = '\0';

		printf("env_buf [%d bytes] too small for value of \"%s\"\n",
			len, name);

		return n;
	}
	return -1;
}
예제 #5
0
void do_printenv (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
{
	uchar *env, *nxt;
	int i;

#if defined(CFG_FLASH_ENV_ADDR)
	uchar *environment = env_init();
#else
	env_init();
#endif	/* CFG_FLASH_ENV_ADDR */

	if (argc == 1) {		/* Print all env variables	*/
		uchar *start = environment;
		for (env=environment; *env; env=nxt+1) {
			for (nxt=env; *nxt; ++nxt)
				;
			puts (env);
			putc  ('\n');

			if (tstc()) {
				getc ();
				printf ("\n ** Abort\n");
				return;
			}
		}

		printf("\nEnvironment size: %d bytes\n", env-start);

		return;
	}

	for (i=1; i<argc; ++i) {	/* print single env variables	*/
		char *name = argv[i];
		char *val = NULL;

		for (env=environment; *env; env=nxt+1) {

			for (nxt=env; *nxt; ++nxt)
				;
			val=envmatch(name, env);
			if (val) {
				puts (name);
				putc ('=');
				puts (val);
				putc ('\n');
				break;
			}
		}
		if (!val)
			printf ("## Error: \"%s\" not defined\n", name);
	}
}
예제 #6
0
int do_printenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	int i, j, k, nxt;
	int rcode = 0;

	if (argc == 1) {		/* Print all env variables	*/
		for (i=0; env_get_char(i) != '\0'; i=nxt+1) {
			for (nxt=i; env_get_char(nxt) != '\0'; ++nxt)
				;
			for (k=i; k<nxt; ++k)
				putc(env_get_char(k));
			putc  ('\n');

			if (ctrlc()) {
				puts ("\n ** Abort\n");
				return 1;
			}
		}

		printf("\nEnvironment size: %d/%ld bytes\n",
			i, (ulong)ENV_SIZE);

		return 0;
	}

	for (i=1; i<argc; ++i) {	/* print single env variables	*/
		char *name = argv[i];

		k = -1;

		for (j=0; env_get_char(j) != '\0'; j=nxt+1) {

			for (nxt=j; env_get_char(nxt) != '\0'; ++nxt)
				;
			k = envmatch((uchar *)name, j);
			if (k < 0) {
				continue;
			}
			puts (name);
			putc ('=');
			while (k < nxt)
				putc(env_get_char(k++));
			putc ('\n');
			break;
		}
		if (k < 0) {
			printf ("## Error: \"%s\" not defined\n", name);
			rcode ++;
		}
	}
	return rcode;
}
예제 #7
0
파일: cmd_nvedit.c 프로젝트: qgp/armboot
int do_printenv (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
{
    int i, j, k, nxt;
    
    if (argc == 1) {		/* Print all env variables	*/
	for (i=0; get_env_char(bd, i) != '\0'; i=nxt+1) {
	    for (nxt=i; get_env_char(bd, nxt) != '\0'; ++nxt)
	      ;
	    for (k=i; k<nxt; ++k)
	      putc(get_env_char(bd, k));
	    putc  ('\n');
	    
	    if (ctrlc()) {
		printf ("\n ** Abort\n");
		return 1;
	    }
	}
	
	printf("\nEnvironment size: %d/%d bytes\n", i, sizeof(bd->bi_env_data));
	
	return 0;
    }
    
    for (i=1; i<argc; ++i) {	/* print single env variables	*/
	char *name = argv[i];
	
	k = -1;
	
	for (j=0; get_env_char(bd, j) != '\0'; j=nxt+1) {
	    
	    for (nxt=j; get_env_char(bd, nxt) != '\0'; ++nxt)
	      ;
	    k = envmatch(bd, name, j);
	    if (k < 0) {
		continue;
	    }
	    puts (name);
	    putc ('=');
	    while (k < nxt)
	      putc(get_env_char(bd, k++));
	    putc ('\n');
	    break;
	}
	if (k < 0)
	{
	  printf ("## Error: \"%s\" not defined\n", name);
	  return 1;
	}
    }
    return 0;
}
예제 #8
0
파일: env.c 프로젝트: John677/Kernal_k3note
static char *findenv(const char *name)
{
	int i, nxt, val;
	for (i = 0; env_get_char(i) != '\0'; i = nxt + 1) {
		for (nxt = i; env_get_char(nxt) != '\0'; ++nxt) {
			if (nxt >= CFG_ENV_SIZE)
				return NULL;
		}
		val = envmatch((char *)name, i);
		if (val < 0)
			continue;
		return (char *)env_get_addr(val);
	}
	return NULL;
}
예제 #9
0
static char *findenv(const char *name)
{
	int i, nxt, val;
	for (i = 0; env_get_char(i) != '\0'; i = nxt+1) {
		for (nxt=i; env_get_char(nxt) != '\0'; ++nxt) {
			if (nxt >= CFG_ENV_SIZE) {
				return (NULL);
			}
		}
		if ((val=envmatch((char *)name, i)) < 0) {
			continue;
		}
		return ((char *)env_get_addr(val));
	}
	return (NULL);
}
예제 #10
0
파일: cmd_nvedit.c 프로젝트: qgp/armboot
char *getenv (bd_t * bd, uchar *name)
{
    int i, nxt;
    
    for (i=0; get_env_char(bd, i) != '\0'; i=nxt+1) {
	int val;
	
	for (nxt=i; get_env_char(bd, nxt) != '\0'; ++nxt) {
	    if (nxt >= sizeof(bd->bi_env_data)) {
		return (NULL);
	    }
	}
	if ((val=envmatch(bd, name, i)) < 0)
	  continue;
	return (get_env_addr(bd, val));
    }
    
    return (NULL);
}
예제 #11
0
/*
 * pseudo signature:
 *
 * int API_env_enum(const char *last, char **next)
 *
 * last: ptr to name of env var found in last iteration
 */
static int API_env_enum(va_list ap)
{
	int i, n;
	char *last, **next;

	last = (char *)va_arg(ap, u_int32_t);

	if ((next = (char **)va_arg(ap, u_int32_t)) == NULL)
		return API_EINVAL;

	if (last == NULL)
		/* start over */
		*next = ((char *)env_get_addr(0));
	else {
		*next = last;

		for (i = 0; env_get_char(i) != '\0'; i = n + 1) {
			for (n = i; env_get_char(n) != '\0'; ++n) {
				if (n >= CONFIG_ENV_SIZE) {
					/* XXX shouldn't we set *next = NULL?? */
					return 0;
				}
			}

			if (envmatch((uchar *)last, i) < 0)
				continue;

			/* try to get next name */
			i = n + 1;
			if (env_get_char(i) == '\0') {
				/* no more left */
				*next = NULL;
				return 0;
			}

			*next = ((char *)env_get_addr(i));
			return 0;
		}
	}

	return 0;
}
예제 #12
0
char *getenv (char *name)
{
	int i, nxt;

	WATCHDOG_RESET();

	for (i=0; env_get_char(i) != '\0'; i=nxt+1) {
		int val;

		for (nxt=i; env_get_char(nxt) != '\0'; ++nxt) {
			if (nxt >= CONFIG_ENV_SIZE) {
				return (NULL);
			}
		}
		if ((val=envmatch((uchar *)name, i)) < 0)
			continue;
		return ((char *)env_get_addr(val));
	}

	return (NULL);
}
int rtcnvet_do_printenv(char *name)
{
    int i, j, k, nxt;
    const uint8_t *b;

    if (name == NULL) {
        /* Print all env variables  */
        for (i = 0; env_get_char(i) != '\0'; i = nxt+1) {
            for (nxt = i; env_get_char(nxt) != '\0'; ++nxt)
                ;
            b = (const uint8_t *)&env_buf[i];
            dump_hex_f(b, (nxt-i), DUMP_ASCII);
        }

        printk(KERN_INFO "\nEnvironment size: %d/%d bytes\n",
        i, env_size);

        return 0;
    } else {
        k = -1;

        for (j = 0; env_get_char(j) != '\0'; j = nxt+1) {

            for (nxt = j; env_get_char(nxt) != '\0'; ++nxt)
                ;
            k = envmatch((unsigned char *)name, j);
            if (k < 0)
                continue;

            printk(KERN_INFO "%s=", name);
            b = (const uint8_t *)&env_buf[k];
            dump_hex_f(b, (nxt-k), DUMP_ASCII);
            break;
        }
        if (k < 0)
            printk(KERN_ERR "## Error: \"%s\" not defined\n", name);

        return 0;
    }
}
예제 #14
0
char *get_env(char *name)
{
	int i, nxt;
	printk("[%s]get_env %s\n",MODULE_NAME,name);
	if(!env_valid)
		return NULL;

	for (i=0; env_get_char(i) != '\0'; i=nxt+1) {
		int val;

		for (nxt=i; env_get_char(nxt) != '\0'; ++nxt) {
			if (nxt >= CFG_ENV_SIZE) {
				return (NULL);
			}
		}
		if ((val=envmatch((char *)name, i)) < 0)
			continue;
		return ((char *)env_get_addr(val));
	}

	return (NULL);
}
예제 #15
0
char *getenv (uchar *name)
{
	uchar *env, *nxt;

#if defined(CFG_FLASH_ENV_ADDR)
	uchar *environment = env_init();
#else
	env_init();
#endif	/* CFG_FLASH_ENV_ADDR */

	for (env=environment; *env; env=nxt+1) {
		char *val;

		for (nxt=env; *nxt; ++nxt)
			;
		val=envmatch(name, env);
		if (!val)
			continue;
		return (val);
	}

	return (NULL);
}
/*
 * state 0: finish printing this string and return (matched!)
 * state 1: no matching to be done; print everything
 * state 2: continue searching for matched name
 */
static int printenv(char *name, int state)
{
	int i, j;
	char c, buf[17];

	i = 0;
	buf[16] = '\0';

	while (state && env_get_char(i) != '\0') {
		if (state == 2 && envmatch((uchar *)name, i) >= 0)
			state = 0;

		j = 0;
		do {
			buf[j++] = c = env_get_char(i++);
			if (j == sizeof(buf) - 1) {
				if (state <= 1)
					puts(buf);
				j = 0;
			}
		} while (c != '\0');

		if (state <= 1) {
			if (j)
				puts(buf);
			putc('\n');
		}

		if (ctrlc())
			return -1;
	}

	if (state == 0)
		i = 0;
	return i;
}
예제 #17
0
/*
 * Search the environment for a variable.
 * Return the value, if found, or NULL, if not found.
 */
unsigned char *fw_getenv (unsigned char *name)
{
	uchar *env, *nxt;

	if (env_init ())
		return (NULL);

	for (env = environment.data; *env; env = nxt + 1) {
		uchar *val;

		for (nxt = env; *nxt; ++nxt) {
			if (nxt >= &environment.data[ENV_SIZE]) {
				fprintf (stderr, "## Error: "
					"environment not terminated\n");
				return (NULL);
			}
		}
		val = envmatch (name, env);
		if (!val)
			continue;
		return (val);
	}
	return (NULL);
}
예제 #18
0
/*
 * Deletes or sets environment variables. Returns errno style error codes:
 * 0	  - OK
 * EINVAL - need at least 1 argument
 * EROFS  - certain variables ("ethaddr", "serial#") cannot be
 *	    modified or deleted
 *
 */
int fw_setenv (int argc, char *argv[])
{
	int i, len;
	uchar *env, *nxt;
	uchar *oldval = NULL;
	char *name;

	if (argc < 2) {
		return (EINVAL);
	}

	if (env_init ())
		return (errno);

	name = argv[1];

	/*
	 * search if variable with this name already exists
	 */
	for (nxt = env = environment.data; *env; env = nxt + 1) {
		for (nxt = env; *nxt; ++nxt) {
			if (nxt >= &environment.data[ENV_SIZE]) {
				fprintf (stderr, "## Error: "
					"environment not terminated\n");
				return (EINVAL);
			}
		}
		if ((oldval = envmatch ((uchar *)name, env)) != NULL)
			break;
	}

	/*
	 * Delete any existing definition
	 */
	if (oldval) {
		/*
		 * Ethernet Address and serial# can be set only once
		 */
		if ((strcmp (name, "ethaddr") == 0) ||
			(strcmp (name, "serial#") == 0)) {
			fprintf (stderr, "Can't overwrite \"%s\"\n", name);
			return (EROFS);
		}

		if (*++nxt == '\0') {
			*env = '\0';
		} else {
			for (;;) {
				*env = *nxt++;
				if ((*env == '\0') && (*nxt == '\0'))
					break;
				++env;
			}
		}
		*++env = '\0';
	}

	/* Delete only ? */
	if (argc < 3)
		goto WRITE_FLASH;

	/*
	 * Append new definition at the end
	 */
	for (env = environment.data; *env || *(env + 1); ++env);
	if (env > environment.data)
		++env;
	/*
	 * Overflow when:
	 * "name" + "=" + "val" +"\0\0"  > CFG_ENV_SIZE - (env-environment)
	 */
	len = strlen (name) + 2;
	/* add '=' for first arg, ' ' for all others */
	for (i = 2; i < argc; ++i) {
		len += strlen (argv[i]) + 1;
	}
	if (len > (&environment.data[ENV_SIZE] - env)) {
		fprintf (stderr,
			"Error: environment overflow, \"%s\" deleted\n",
			name);
		return (-1);
	}
	while ((*env = *name++) != '\0')
		env++;
	for (i = 2; i < argc; ++i) {
		char *val = argv[i];

		*env = (i == 2) ? '=' : ' ';
		while ((*++env = *val++) != '\0');
	}

	/* end is marked with double '\0' */
	*++env = '\0';

  WRITE_FLASH:

	/* Update CRC */
	environment.crc = crc32 (0, environment.data, ENV_SIZE);

	/* write environment back to flash */
	if (flash_io (O_RDWR)) {
		fprintf (stderr, "Error: can't write fw_env to flash\n");
		return (-1);
	}

	return (0);
}
        /* ed is not valid anymore! */
        return 0;
    } else {
        printk(KERN_ERR\
            "%s: Cannot find a valid env!\n",\
            __func__);
        return -1;
    }
#ifdef DEBUGME
    printk(KERN_ERR\
        "%s: All done, exiting!\n",\
        __func__);
#endif /*DEBUGME*/
    return 0;
}
#else /*CONFIG_CIRRUS_DUAL_MTD_ENV*/
int rtcnvet_do_setenv(char *name, char *val)
{
    int len, oldval;
    unsigned char *env, *nxt = NULL;
    unsigned char *env_data = NULL;

    rtcnvet_reload_env();
    env_data = (unsigned char *)&env_buf[0];

    if (!env_valid)
        return -1;

    if (strchr(name, '=')) {
        printk(KERN_ERR \
        "Illegal character '=' in variable name \"%s\"\n", name);
        return -2;
    }

    /*
     * search if variable with this name already exists
     */
    oldval = -1;
    for (env = env_data; *env; env = nxt+1) {
        for (nxt = env; *nxt; ++nxt)
            ;
        oldval = envmatch((unsigned char *)name, env-env_data);
        if (oldval >= 0)
            break;
    }


    /*
     * Delete any existing definition
     */
    if (oldval >= 0) {
        if (*++nxt == '\0')
            if (env > env_data) {
                env--;
            } else {
                *env = '\0';
        } else {
            for (;;) {
                *env = *nxt++;
                if ((*env == '\0') && (*nxt == '\0'))
                    break;
                ++env;
            }
        }
        *++env = '\0';
    }

    /*
     * Append new definition at the end
     */
    for (env = env_data; *env || *(env+1); ++env)
        ;
    if (env > env_data)
        ++env;
    /*
     * Overflow when:
     * "name" + "=" + "val" +"\0\0"  > ENV_SIZE - (env-env_data)
     */
    len = strlen(name) + 2;
    /* add '=' for first arg, ' ' for all others */
    len += strlen(val) + 1;
    if (len > (&env_data[env_size]-env)) {
        printk(KERN_ERR \
        "Environment overflow, \"%s\" deleted\n", name);
        return 1;
    }
    while ((*env = *name++) != '\0')
        env++;

    *env = '=';
    while ((*++env = *val++) != '\0')
        ;

    /* end is marked with double '\0' */
    *++env = '\0';

    /* Update CRC */
    env_crc_update();

    /* save every time */
    env_save();

    return 0;
}
예제 #20
0
int _do_setenv (int flag, int argc, char *argv[])
{
	int   i, len, oldval;
	int   console = -1;
	uchar *env, *nxt = NULL;
	char *name;
	bd_t *bd = gd->bd;

	uchar *env_data = env_get_addr(0);

	if (!env_data)	/* need copy in RAM */
		return 1;

	name = argv[1];

	if (strchr(name, '=')) {
		printf ("## Error: illegal character '=' in variable name \"%s\"\n", name);
		return 1;
	}

	/*
	 * search if variable with this name already exists
	 */
	oldval = -1;
	for (env=env_data; *env; env=nxt+1) {
		for (nxt=env; *nxt; ++nxt)
			;
		if ((oldval = envmatch((uchar *)name, env-env_data)) >= 0)
			break;
	}

	/*
	 * Delete any existing definition
	 */
	if (oldval >= 0) {
#ifndef CONFIG_ENV_OVERWRITE

		/*
		 * Ethernet Address and serial# can be set only once,
		 * ver is readonly.
		 */
		if (
#ifdef CONFIG_HAS_UID
		/* Allow serial# forced overwrite with 0xdeaf4add flag */
		    ((strcmp (name, "serial#") == 0) && (flag != 0xdeaf4add)) ||
#else
		    (strcmp (name, "serial#") == 0) ||
#endif
		    ((strcmp (name, "ethaddr") == 0)
#if defined(CONFIG_OVERWRITE_ETHADDR_ONCE) && defined(CONFIG_ETHADDR)
		     && (strcmp ((char *)env_get_addr(oldval),MK_STR(CONFIG_ETHADDR)) != 0)
#endif	/* CONFIG_OVERWRITE_ETHADDR_ONCE && CONFIG_ETHADDR */
		    ) ) {
			printf ("Can't overwrite \"%s\"\n", name);
			return 1;
		}
#endif

		/* Check for console redirection */
		if (strcmp(name,"stdin") == 0) {
			console = stdin;
		} else if (strcmp(name,"stdout") == 0) {
			console = stdout;
		} else if (strcmp(name,"stderr") == 0) {
			console = stderr;
		}

		if (console != -1) {
			if (argc < 3) {		/* Cannot delete it! */
				printf("Can't delete \"%s\"\n", name);
				return 1;
			}

#ifdef CONFIG_CONSOLE_MUX
			i = iomux_doenv(console, argv[2]);
			if (i)
				return i;
#else
			/* Try assigning specified device */
			if (console_assign (console, argv[2]) < 0)
				return 1;

#ifdef CONFIG_SERIAL_MULTI
			if (serial_assign (argv[2]) < 0)
				return 1;
#endif
#endif /* CONFIG_CONSOLE_MUX */
		}

		/*
		 * Switch to new baudrate if new baudrate is supported
		 */
		if (strcmp(argv[1],"baudrate") == 0) {
			int baudrate = simple_strtoul(argv[2], NULL, 10);
			int i;
			for (i=0; i<N_BAUDRATES; ++i) {
				if (baudrate == baudrate_table[i])
					break;
			}
			if (i == N_BAUDRATES) {
				printf ("## Baudrate %d bps not supported\n",
					baudrate);
				return 1;
			}
			printf ("## Switch baudrate to %d bps and press ENTER ...\n",
				baudrate);
			udelay(50000);
			gd->baudrate = baudrate;
#if defined(CONFIG_PPC) || defined(CONFIG_MCF52x2)
			gd->bd->bi_baudrate = baudrate;
#endif

			serial_setbrg ();
			udelay(50000);
			for (;;) {
				if (getc() == '\r')
				      break;
			}
		}

		if (*++nxt == '\0') {
			if (env > env_data) {
				env--;
			} else {
				*env = '\0';
			}
		} else {
			for (;;) {
				*env = *nxt++;
				if ((*env == '\0') && (*nxt == '\0'))
					break;
				++env;
			}
		}
		*++env = '\0';
	}

#ifdef CONFIG_NET_MULTI
	if (strncmp(name, "eth", 3) == 0) {
		char *end;
		int   num = simple_strtoul(name+3, &end, 10);

		if (strcmp(end, "addr") == 0) {
			eth_set_enetaddr(num, argv[2]);
		}
	}
#endif


	/* Delete only ? */
	if ((argc < 3) || argv[2] == NULL) {
		env_crc_update ();
		return 0;
	}

	/*
	 * Append new definition at the end
	 */
	for (env=env_data; *env || *(env+1); ++env)
		;
	if (env > env_data)
		++env;
	/*
	 * Overflow when:
	 * "name" + "=" + "val" +"\0\0"  > ENV_SIZE - (env-env_data)
	 */
	len = strlen(name) + 2;
	/* add '=' for first arg, ' ' for all others */
	for (i=2; i<argc; ++i) {
		len += strlen(argv[i]) + 1;
	}
	if (len > (&env_data[ENV_SIZE]-env)) {
		printf ("## Error: environment overflow, \"%s\" deleted\n", name);
		return 1;
	}
	while ((*env = *name++) != '\0')
		env++;
	for (i=2; i<argc; ++i) {
		char *val = argv[i];

		*env = (i==2) ? '=' : ' ';
		while ((*++env = *val++) != '\0')
			;
	}

	/* end is marked with double '\0' */
	*++env = '\0';

	/* Update CRC */
	env_crc_update ();

	/*
	 * Some variables should be updated when the corresponding
	 * entry in the enviornment is changed
	 */

	if (strcmp(argv[1],"ethaddr") == 0) {
		char *s = argv[2];	/* always use only one arg */
		char *e;
		for (i=0; i<6; ++i) {
			bd->bi_enetaddr[i] = s ? simple_strtoul(s, &e, 16) : 0;
			if (s) s = (*e) ? e+1 : e;
		}
#ifdef CONFIG_NET_MULTI
		eth_set_enetaddr(0, argv[2]);
#endif
		return 0;
	}

	if (strcmp(argv[1],"ipaddr") == 0) {
		char *s = argv[2];	/* always use only one arg */
		char *e;
		unsigned long addr;
		bd->bi_ip_addr = 0;
		for (addr=0, i=0; i<4; ++i) {
			ulong val = s ? simple_strtoul(s, &e, 10) : 0;
			addr <<= 8;
			addr  |= (val & 0xFF);
			if (s) s = (*e) ? e+1 : e;
		}
		bd->bi_ip_addr = htonl(addr);
		return 0;
	}
	if (strcmp(argv[1],"loadaddr") == 0) {
		load_addr = simple_strtoul(argv[2], NULL, 16);
		return 0;
	}
#if defined(CONFIG_CMD_NET)
	if (strcmp(argv[1],"bootfile") == 0) {
		copy_filename (BootFile, argv[2], sizeof(BootFile));
		return 0;
	}
#endif

#ifdef CONFIG_AMIGAONEG3SE
	if (strcmp(argv[1], "vga_fg_color") == 0 ||
	    strcmp(argv[1], "vga_bg_color") == 0 ) {
		extern void video_set_color(unsigned char attr);
		extern unsigned char video_get_attr(void);

		video_set_color(video_get_attr());
		return 0;
	}
#endif	/* CONFIG_AMIGAONEG3SE */

	return 0;
}
예제 #21
0
int set_env(char *name,char *value)
{
	int  len;
	int  oldval = -1;
	char *env, *nxt = NULL;
	int ret = 0;
	char *env_data = NULL;
	pr_notice("[%s]set env, name=%s,value=%s\n", 
		  MODULE_NAME, name, value);
	
	env_init();

	env_data = g_env.env_data;
	if (!env_buffer) {
		return (-1);
	}
	if (!env_valid) {
		env = env_data;
		goto add;
	}
/* find match name and return the val header pointer*/
	for (env = env_data; *env; env = nxt + 1) {
		for (nxt=env; *nxt; ++nxt) {
			;
		}
		if ((oldval = envmatch((char *)name, env-env_data)) >= 0)
			break;
	}/* end find */
	if (oldval>0) {
		if (*++nxt == '\0') {
			if (env > env_data) {
				env--;
			} else {
				*env = '\0';
			}
		} else {
			for (;;) {
				*env = *nxt++;
				if ((*env == '\0') && (*nxt == '\0'))
					break;
				++env;
			}
		}
		*++env = '\0';
	}

	for (env=env_data; *env || *(env+1); ++env) {
		;
	}
	if (env > env_data) {
		++env;
	}
add:
	if (*value == '\0') {
		pr_notice("[%s]clear env name=%s\n", 
			  MODULE_NAME, name);
		goto write_env;
	}

	len = strlen(name) + 2;
	len += strlen(value) + 1;
	if (len > (&env_data[CFG_ENV_DATA_SIZE] - env)) {
		pr_err("[%s]env data overflow, %s deleted\n", 
			MODULE_NAME, name);
		return -1;
	}
	while ((*env = *name++) != '\0') {
		env++;
	}
	*env = '=';
	while ((*++env = *value++) != '\0') {
		;
	}
write_env:
/* end is marked with double '\0' */
	*++env = '\0';
	memset(env, 0x00, CFG_ENV_DATA_SIZE - (env - env_data));

	ret = write_env_area(env_buffer);
	if (ret < 0) {
		pr_err("[%s]%s error: write env area fail\n", 
			MODULE_NAME, __FUNCTION__);
		memset(env_buffer, 0x00, CFG_ENV_SIZE);
		return -1;
	}
	env_valid = 1;
	return 0;
}
예제 #22
0
int set_env(char *name,char *value)
{
	int  len, oldval;
	char *env, *nxt = NULL;
	
	int ret;

	char *env_data = g_env.env_data;

	printk("[%s]set_env %s %s\n",MODULE_NAME,name,value);

	oldval = -1;
	if(!env_buffer){
		return -1;
	}
	if(!env_valid){
		env = env_data;
		goto add;
	}
	
	for (env=env_data; *env; env=nxt+1) {
		for (nxt=env; *nxt; ++nxt)
			;
		if ((oldval = envmatch((char *)name, env-env_data)) >= 0)
			break;
	}

	if(oldval>0){
		if (*++nxt == '\0') {
			if (env > env_data) {
				env--;
			} else {
				*env = '\0';
			}
		} else {
			for (;;) {
				*env = *nxt++;
				if ((*env == '\0') && (*nxt == '\0'))
					break;
				++env;
			}
		}
		*++env = '\0';
	}

	for (env=env_data; *env || *(env+1); ++env)
		;
	if (env > env_data)
		++env;

add:
	if(*value == '\0'){
		printk("[LK_ENV]clear %s\n",name);
		goto write_env;
	}
		/*
	 * Overflow when:
	 * "name" + "=" + "val" +"\0\0"  > ENV_SIZE - (env-env_data)
	 */
	len = strlen(name) + 2;
	/* add '=' for first arg, ' ' for all others */
	len += strlen(value) + 1;

	if (len > (&env_data[CFG_ENV_DATA_SIZE]-env)) {
		printk ("## Error: environment overflow, \"%s\" deleted\n", name);
		return -1;
	}
	while ((*env = *name++) != '\0')
		env++;
	
	*env = '=';
	
	while ((*++env = *value++) != '\0')
			;

write_env:
	/* end is marked with double '\0' */
	*++env = '\0';
	memset(env,0x00,CFG_ENV_DATA_SIZE-(env-env_data));

	ret = write_env_area(env_buffer);
	if(ret < 0){
		printk("[%s]write env fail\n",MODULE_NAME);
		memset(env_buffer,0x00,CFG_ENV_SIZE);
		return -1;
	}
	env_valid = 1;
	return 0;

}
예제 #23
0
/************************************************************************
 * Command interface: print one or all environment variables
 */
int do_printenv(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){
	int i, j, k, nxt;
	int rcode = 0;

	if(argc == 1){ /* Print all env variables	*/
		for(i = 0; env_get_char(i) != '\0'; i = nxt + 1){

			for(nxt = i; env_get_char(nxt) != '\0'; ++nxt);

			for(k = i; k < nxt; ++k){
				putc(env_get_char(k));
			}

			putc('\n');

			if(ctrlc()){
				puts("\nAbort\n");
				return(1);
			}
		}

#if defined(CFG_ENV_IS_IN_NVRAM) || \
	defined(CFG_ENV_IS_IN_EEPROM) || \
	((CONFIG_COMMANDS & (CFG_CMD_ENV|CFG_CMD_FLASH)) == (CFG_CMD_ENV|CFG_CMD_FLASH)) || \
    ((CONFIG_COMMANDS & (CFG_CMD_ENV|CFG_CMD_NAND)) == (CFG_CMD_ENV|CFG_CMD_NAND))
		printf("\nEnvironment size: %d/%d bytes\n\n", i, ENV_SIZE);
#else
		printf("\nEnvironment size: %d bytes\n\n", i);
#endif
		return(0);
	}

	for(i = 1; i < argc; ++i){ /* print single env variables	*/
		char *name = argv[i];

		k = -1;

		for(j = 0; env_get_char(j) != '\0'; j = nxt + 1){

			for(nxt = j; env_get_char(nxt) != '\0'; ++nxt);

			k = envmatch((uchar *)name, j);

			if(k < 0){
				continue;
			}

			puts(name);
			putc('=');

			while(k < nxt){
				putc(env_get_char(k++));
			}

			putc('\n');
			break;
		}
		if(k < 0){
			printf("## Error: \"%s\" not defined\n", name);
			rcode++;
		}
	}
	return(rcode);
}
예제 #24
0
void _do_setenv (bd_t *bd, int flag, int argc, char *argv[])
{
	int   i, len;
	int   console = -1;
	uchar *env, *nxt;
	uchar *oldval = NULL;
	uchar *name;

#if defined(CFG_FLASH_ENV_ADDR)
	uchar *environment = env_init();
	ulong real_env_size = env_size;
	ulong env_size = real_env_size - sizeof (ulong);
#else
	env_init();
#endif	/* CFG_FLASH_ENV_ADDR */

	name = argv[1];

	/*
	 * search if variable with this name already exists
	 */
	for (env=environment; *env; env=nxt+1) {
		for (nxt=env; *nxt; ++nxt)
			;
		if ((oldval=envmatch(name, env)) != NULL)
			break;
	}

	/*
	 * Delete any existing definition
	 */
	if (oldval) {
#ifndef CONFIG_ENV_OVERWRITE
		/*
		 * Ethernet Address and serial# can be set only once
		 */
		if ((strcmp (name, "ethaddr") == 0) ||
		    (strcmp (name, "serial#") == 0) ) {
			printf ("Can't overwrite \"%s\"\n", name);
			return;
		}
#endif

		/* Check for console redirection */
		if (strcmp(name,"stdin") == 0) {
			console = stdin;
		} else if (strcmp(name,"stdout") == 0) {
			console = stdout;
		} else if (strcmp(name,"stderr") == 0) {
			console = stderr;
		}

		if (console != -1) {
			if (argc < 3)		/* Cannot delete it! */
				return;

			/* Try assigning specified device */
			if (console_assign (console, argv[2]) < 0)
				return;
		}

		if (*++nxt == '\0') {
			*env = '\0';
		} else {
			for (;;) {
				*env = *nxt++;
				if ((*env == '\0') && (*nxt == '\0'))
					break;
				++env;
			}
		}
		*++env = '\0';
	}

#if defined(CFG_FLASH_ENV_ADDR)
	MAKEVALID(environment, real_env_size);
#endif	/* CFG_FLASH_ENV_ADDR */

	/* Delete only ? */
	if (argc < 3)
		return;

	/*
	 * Append new definition at the end
	 */
	for (env=environment; *env || *(env+1); ++env)
		;
	if (env > environment)
		++env;
	/*
	 * Overflow when:
	 * "name" + "=" + "val" +"\0\0"  > env_size - (env-environment)
	 */
	len = strlen(name) + 2;
	/* add '=' for first arg, ' ' for all others */
	for (i=2; i<argc; ++i) {
		len += strlen(argv[i]) + 1;
	}
	if (len > (&environment[env_size]-env)) {
		printf ("## Error: environment overflow, \"%s\" deleted\n", name);
		return;
	}
	while ((*env = *name++) != '\0')
		env++;
	for (i=2; i<argc; ++i) {
		char *val = argv[i];

		*env = (i==2) ? '=' : ' ';
		while ((*++env = *val++) != '\0')
			;
	}

	/* end is marked with double '\0' */
	*++env = '\0';

#ifdef CONFIG_NVRAM_ENV
	*(ulong *)CFG_NVRAM_VAR_CRC_ADDR = crc32(0, (char *)environment, env_size);
#endif
#if defined(CFG_FLASH_ENV_ADDR)
	MAKEVALID(environment, real_env_size);
#endif	/* CFG_FLASH_ENV_ADDR */

        /* Changes of the Ethernet or IP address should be reflected
         * in the board info structure.
	 */

	if (strcmp(argv[1],"ethaddr") == 0) {
		char *s = argv[2];	/* always use only one arg */
		char *e;
		for (i=0; i<6; ++i) {
			bd->bi_enetaddr[i] = s ? simple_strtoul(s, &e, 16) : 0;
			if (s) s = (*e) ? e+1 : e;
		}
		return;
	}

	if (strcmp(argv[1],"ipaddr") == 0) {
		char *s = argv[2];	/* always use only one arg */
		char *e;
		bd->bi_ip_addr = 0;
		for (i=0; i<4; ++i) {
			ulong val = s ? simple_strtoul(s, &e, 10) : 0;
			bd->bi_ip_addr <<= 8;
			bd->bi_ip_addr  |= (val & 0xFF);
			if (s) s = (*e) ? e+1 : e;
		}
	}
}
예제 #25
0
/*
 * Print the current definition of one, or more, or all
 * environment variables
 */
int fw_printenv (int argc, char *argv[])
{
	uchar *env, *nxt;
	int i, n_flag, ret = EXIT_SUCCESS;

	if (env_init ())
		return ret;

	if (argc == 1) {		/* Print all env variables  */
		for (env = environment.data; *env; env = nxt + 1) {
			for (nxt = env; *nxt; ++nxt) {
				if (nxt >= &environment.data[ENV_SIZE]) {
					fprintf (stderr, "## Error: environment not terminated\n");
						ret = EXIT_FAILURE;
					return ret;
				}
			}

			printf ("%s\n", env);
		}
		return ret;
	}

	if (strcmp (argv[1], "-n") == 0) {
		n_flag = 1;
		++argv;
		--argc;
		if (argc != 2) {
			fprintf (stderr, "## Error: `-n' option requires exactly one argument\n");
			ret = EXIT_FAILURE;
			return ret;
		}
	} else {
		n_flag = 0;
	}

	for (i = 1; i < argc; ++i) {	/* print single env variables   */
		char *name = argv[i];
		char *val = NULL;

		for (env = environment.data; *env; env = nxt + 1) {

			for (nxt = env; *nxt; ++nxt) {
				if (nxt >= &environment.data[ENV_SIZE]) {
					fprintf (stderr, "## Error: environment not terminated\n");
					ret = EXIT_FAILURE;
					return ret;
				}
			}
			val = (char *)envmatch ((uchar *)name, env);
			if (val) {
				if (!n_flag) {
					fputs (name, stdout);
					putc ('=', stdout);
				}
				puts (val);
				break;
			}
		}
		if (!val) {
			fprintf (stderr, "## Error: \"%s\" not defined\n", name);
			ret = EXIT_FAILURE;
		}
	}
	
	return ret;
}
예제 #26
0
파일: nvm-utils.c 프로젝트: Undrizzle/apps
void __do_env_set_parameter(env_t *nvm, const char *key, const char *value)
{
	int   i, len, oldval;
	unsigned char *env, *nxt = NULL;
	//char *name = "ethaddr";

	unsigned char *env_data = nvm->data;

	/*
	 * search if variable with this name already exists
	 */
	oldval = -1;
	for (env=env_data; *env; env=nxt+1)
	{
		for (nxt=env; *nxt; ++nxt)
			;
		if ((oldval = envmatch((unsigned char *)key, env-env_data, env_data)) >= 0)
			break;
	}
	/*
	 * Delete any existing definition
	 */
	if (oldval >= 0)
	{
		if (*++nxt == '\0')
		{
			if (env > env_data) {
				env--;
			}
			else
			{
				*env = '\0';
			}
		}
		else
		{
			for (;;)
			{
				*env = *nxt++;
				if ((*env == '\0') && (*nxt == '\0'))
					break;
				++env;
			}
		}
		*++env = '\0';
	}

	/*
	 * Append new definition at the end
	 */
	for (env=env_data; *env || *(env+1); ++env)
		;
	if (env > env_data)
		++env;
	/*
	 * Overflow when:
	 * "name" + "=" + "val" +"\0\0"  > ENV_SIZE - (env-env_data)
	 */
	len = strlen(key) + 2;
	len += strlen(value) + 1;
	
	if (len > (&env_data[ENV_SIZE]-env)) {
		printf ("## Error: environment overflow, \"%s\" deleted\n", key);
		return;
	}
	while ((*env = *key++) != '\0')
		env++;
	*env = '=';
	while ((*++env = *value++) != '\0')
			;

	/* end is marked with double '\0' */
	*++env = '\0';
}
예제 #27
0
파일: cmd_nvedit.c 프로젝트: qgp/armboot
int _do_setenv (bd_t *bd, int flag, int argc, char *argv[])
{
    int   i, len, oldval;
    uchar *env, *nxt = 0;
    uchar *name;
    
    /* need writable copy in RAM */
    if (!bd->bi_env_data)
      return 1;

    name = argv[1];
    
    /*
     * search if variable with this name already exists
     */
    oldval = -1;
    for (env = bd->bi_env_data; *env; env = nxt+1) {
	for (nxt = env; *nxt; ++nxt)
	  ;
	if ((oldval = envmatch(bd, name, (ulong)env - (ulong)bd->bi_env_data)) >= 0)
	  break;
    }
    
    /*
     * Delete any existing definition
     */
    if (oldval >= 0) {
#ifndef CONFIG_ENV_OVERWRITE
	
	/*
	 * Ethernet Address and serial# can be set only once
	 */
	if ( (strcmp (name, "serial#") == 0) ||
	    ((strcmp (name, "ethaddr") == 0)
# if defined(CONFIG_OVERWRITE_ETHADDR_ONCE) && defined(CONFIG_ETHADDR)
	     && (strcmp (get_env_addr(bd, oldval),MK_STR(CONFIG_ETHADDR)) != 0)
# endif	/* CONFIG_OVERWRITE_ETHADDR_ONCE && CONFIG_ETHADDR */
	     ) ) {
	    printf ("Can't overwrite \"%s\"\n", name);
	    return 1;
	}
#endif
	
	/*
	 * Switch to new baudrate if new baudrate is supported
	 */
	if (strcmp(argv[1],"baudrate") == 0) {
	    int baudrate = simple_strtoul(argv[2], NULL, 10);
	    int i;
	    for (i=0; i<N_BAUDRATES; ++i) {
		if (baudrate == baudrate_table[i])
		  break;
	    }
	    if (i == N_BAUDRATES) {
		printf ("## Baudrate %d bps not supported\n",
			baudrate);
		return 1;
	    }
	    printf ("## Switch baudrate to %d bps and press ENTER ...\n",
		    baudrate);
	    udelay(50000);
	    serial_setbrg (bd, baudrate);
	    udelay(50000);
	    for (;;) {
		if (getc() == '\r')
		  break;
	    }
	    bd->bi_baudrate = baudrate;
	}
	
	if (*++nxt == '\0') {
	    if ((ulong)env > (ulong)bd->bi_env_data) {
		env--;
	    } else {
		*env = '\0';
	    }
	} else {
	    for (;;) {
		*env = *nxt++;
		if ((*env == '\0') && (*nxt == '\0'))
		  break;
		++env;
	    }
	}
	*++env = '\0';
    }
    /* Delete only ? */
    if ((argc < 3) || argv[2] == NULL) {    
	/* Update CRC */
	bd->bi_env_crc = crc32(0, bd->bi_env_data, sizeof(bd->bi_env_data));
	return 0;
    }

    /*
     * Append new definition at the end
     */
    for (env = bd->bi_env_data; *env || *(env+1); ++env)
      ;
    if ((ulong)env > (ulong)bd->bi_env_data)
      ++env;
    /*
     * Overflow when:
     * "name" + "=" + "val" +"\0\0"  > 
     *      sizeof(bd->bi_env_data) - (env-bd->bi_env_data)
     */
    len = strlen(name) + 2;
    /* add '=' for first arg, ' ' for all others */
    for (i=2; i<argc; ++i) {
	len += strlen(argv[i]) + 1;
    }
    if (len > sizeof(bd->bi_env_data)) {
	printf ("## Error: environment overflow, \"%s\" deleted\n", name);
	return 1;
    }
    while ((*env = *name++) != '\0')
      env++;
    for (i=2; i<argc; ++i) {
	char *val = argv[i];
	
	*env = (i==2) ? '=' : ' ';
	while ((*++env = *val++) != '\0')
	  ;
    }
    
    /* end is marked with double '\0' */
    *++env = '\0';
    
    /* Update CRC */
    bd->bi_env_crc = crc32(0, bd->bi_env_data, sizeof(bd->bi_env_data));

    /*
     * Some variables should be updated when the corresponding
     * entry in the enviornment is changed
     */
    
    if (strcmp(argv[1],"ethaddr") == 0) {
	char *s = argv[2];	/* always use only one arg */
	char *e;
	for (i=0; i<6; ++i) {
	    bd->bi_enetaddr[i] = s ? simple_strtoul(s, &e, 16) : 0;
	    if (s) s = (*e) ? e+1 : e;
	}
	return 0;
    }

#if (CONFIG_COMMANDS & CFG_CMD_NET)
    if (strcmp(argv[1],"ipaddr") == 0) {
	char *s = argv[2];	/* always use only one arg */
	bd->bi_ip_addr = string_to_ip(s);
	return 0;
    }
#endif

    if (strcmp(argv[1],"loadaddr") == 0) {
	load_addr = simple_strtoul(argv[2], NULL, 16);
	return 0;
    }

    if (strcmp(argv[1],"pagelength") == 0) {
	pagelength = simple_strtoul(argv[2], NULL, 10);
	return 0;
    }

#if (CONFIG_COMMANDS & CFG_CMD_NET)
    if (strcmp(argv[1],"bootfile") == 0) {
	copy_filename (BootFile, argv[2], sizeof(BootFile));
	return 0;
    }
#endif	/* CFG_CMD_NET */

#ifdef CONFIG_KEYBOARD
    if (strcmp(argv[1],"keymap") == 0) {
	kbd_mapping (argv[2]);
	return 0;
    }
#endif	/* CONFIG_KEYBOARD */

#ifdef CONFIG_ADJUST_LCD
    if (strcmp(argv[1],"contrast") == 0) {
	lcd_contrast(simple_strtoul(argv[2], NULL, 10));
	return 0;
	}
    if (strcmp(argv[1],"brightness") == 0) {
	lcd_brightness(simple_strtoul(argv[2], NULL, 10));
	return 0;
	}
#endif	/* CONFIG_ADJUST_LCD */

    return 0;
}
예제 #28
0
/************************************************************************
 * Set a new environment variable,
 * or replace or delete an existing one.
 *
 * This function will ONLY work with a in-RAM copy of the environment
 */
int _do_setenv(int flag, int argc, char *argv[]){
	int i, len, oldval;
	int console = -1;
	uchar *env, *nxt = NULL;
	char *name;
	bd_t *bd = gd->bd;

	uchar *env_data = env_get_addr(0);

	if(!env_data){ /* need copy in RAM */
		return(1);
	}

	name = argv[1];

	/*
	 * search if variable with this name already exists
	 */
	oldval = -1;

	for(env = env_data; *env; env = nxt + 1){
		for(nxt = env; *nxt; ++nxt);

		if((oldval = envmatch((uchar *)name, env - env_data)) >= 0){
			break;
		}
	}

	/*
	 * Delete any existing definition
	 */
	if(oldval >= 0){
		/* Check for console redirection */
		if(strcmp(name, "stdin") == 0){
			console = stdin;
		} else if(strcmp(name, "stdout") == 0){
			console = stdout;
		} else if(strcmp(name, "stderr") == 0){
			console = stderr;
		}

		if(console != -1){
			if(argc < 3){ /* Cannot delete it! */
				printf("## Error: can't delete \"%s\"\n", name);
				return(1);
			}

			/* Try assigning specified device */
			if(console_assign(console, argv[2]) < 0){
				return(1);
			}

#ifdef CONFIG_SERIAL_MULTI
			if(serial_assign(argv[2]) < 0){
				return(1);
			}
#endif
		}

		/*
		 * Switch to new baudrate if new baudrate is supported
		 */
		if(strcmp(argv[1], "baudrate") == 0){
			int baudrate = simple_strtoul(argv[2], NULL, 10);
			int i;

			for(i = 0; i < N_BAUDRATES; ++i){
				if(baudrate == baudrate_table[i]){
					break;
				}
			}

			if(i == N_BAUDRATES){
				printf("## Error: baudrate %d bps is not supported,\n", baudrate);
				printf("          choose one from the list:\n\n");
				for(i = 0; i < N_BAUDRATES; ++i){
					printf("- %7d bps%s\n", baudrate_table[i], baudrate_table[i] == gd->baudrate ? " [current]" : "");
				}
				printf("\n");
				return(1);
			}

			printf("Switch baudrate to %d bps and press ENTER...\n", baudrate);
			udelay(50000);

			gd->baudrate = baudrate;

			serial_setbrg();

			udelay(50000);

			for(;;){
				if(getc() == '\r'){
					break;
				}
			}
		}

		if(*++nxt == '\0'){
			if(env > env_data){
				env--;
			} else {
				*env = '\0';
			}
		} else {
			for(;;){
				*env = *nxt++;

				if((*env == '\0') && (*nxt == '\0')){
					break;
				}

				++env;
			}
		}
		*++env = '\0';
	}

#ifdef CONFIG_NET_MULTI
	if(strncmp(name, "eth", 3) == 0){
		char *end;
		int num = simple_strtoul(name + 3, &end, 10);

		if(strcmp(end, "addr") == 0){
			eth_set_enetaddr(num, argv[2]);
		}
	}
#endif

	/* Delete only ? */
	if((argc < 3) || argv[2] == NULL){
		env_crc_update();
		return(0);
	}

	/*
	 * Append new definition at the end
	 */
	for(env = env_data; *env || *(env + 1); ++env);

	if(env > env_data){
		++env;
	}
	/*
	 * Overflow when:
	 * "name" + "=" + "val" +"\0\0"  > ENV_SIZE - (env-env_data)
	 */
	len = strlen(name) + 2;

	/* add '=' for first arg, ' ' for all others */
	for(i = 2; i < argc; ++i){
		len += strlen(argv[i]) + 1;
	}

	if(len > (&env_data[ENV_SIZE] - env)){
		printf("## Error: environment overflow, \"%s\" deleted\n", name);
		return(1);
	}

	while((*env = *name++) != '\0'){
		env++;
	}

	for(i = 2; i < argc; ++i){
		char *val = argv[i];

		*env = (i == 2) ? '=' : ' ';
		while((*++env = *val++) != '\0');
	}

	/* end is marked with double '\0' */
	*++env = '\0';

	/* Update CRC */
	env_crc_update();

	/*
	 * Some variables should be updated when the corresponding
	 * entry in the enviornment is changed
	 */
	if(strcmp(argv[1], "ethaddr") == 0){
		char *s = argv[2]; /* always use only one arg */
		char *e;

		for(i = 0; i < 6; ++i){
			bd->bi_enetaddr[i] = s ? simple_strtoul(s, &e, 16) : 0;
			if(s){
				s = (*e) ? e + 1 : e;
			}
		}
#ifdef CONFIG_NET_MULTI
		eth_set_enetaddr(0, argv[2]);
#endif
		return(0);
	}

	if(strcmp(argv[1], "ipaddr") == 0){
		char *s = argv[2]; /* always use only one arg */
		char *e;
		unsigned long addr;

		bd->bi_ip_addr = 0;

		for(addr = 0, i = 0; i < 4; ++i){
			ulong val = s ? simple_strtoul(s, &e, 10) : 0;
			addr <<= 8;
			addr |= (val & 0xFF);
			if(s){
				s = (*e) ? e + 1 : e;
			}
		}

		bd->bi_ip_addr = htonl(addr);
		return(0);
	}

	if(strcmp(argv[1], "loadaddr") == 0){
		load_addr = simple_strtoul(argv[2], NULL, 16);
		return(0);
	}

#if (CONFIG_COMMANDS & CFG_CMD_NET)
	if(strcmp(argv[1], "bootfile") == 0){
		copy_filename(BootFile, argv[2], sizeof(BootFile));
		return(0);
	}
#endif	/* CFG_CMD_NET */

	return(0);
}