diff options
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/env/Makefile | 46 | ||||
| -rw-r--r-- | tools/env/README | 29 | ||||
| -rw-r--r-- | tools/env/fw_env.c | 662 | ||||
| -rw-r--r-- | tools/env/fw_env.h | 44 | ||||
| -rw-r--r-- | tools/env/fw_env_main.c | 78 | 
5 files changed, 859 insertions, 0 deletions
| diff --git a/tools/env/Makefile b/tools/env/Makefile new file mode 100644 index 000000000..7da1d2b7b --- /dev/null +++ b/tools/env/Makefile @@ -0,0 +1,46 @@ +# +# (C) Copyright 2002 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +SOURCES := crc32.c  fw_env.c  fw_env_main.c +HEADERS := fw_env.h + +all:	fw_printenv + +fw_printenv:	$(SOURCES) $(HEADERS) +	$(CROSS_COMPILE)gcc -Wall -DUSE_HOSTCC $(SOURCES) -o fw_printenv + +clean: +	rm -f fw_printenv crc32.c + +crc32.c: +	ln -s ../../lib_generic/crc32.c crc32.c + +######################################################################### + +.depend:	Makefile $(SOURCES) +		$(CC) -M $(HOST_CFLAGS) $(CPPFLAGS) -DUSE_HOSTCC $(SOURCES) > $@ + +sinclude .depend + +######################################################################### + diff --git a/tools/env/README b/tools/env/README new file mode 100644 index 000000000..2b54adf76 --- /dev/null +++ b/tools/env/README @@ -0,0 +1,29 @@ + +This is a demo implementation of a Linux command line tool to access +the U-Boot's environment variables. + +Configuration is done via #defines in the fw_env.h file. The +following lines are relevant: + +#define HAVE_REDUND	/* For systems with 2 env sectors */ +#define DEVICE1_NAME	"/dev/mtd1" +#define DEVICE2_NAME	"/dev/mtd2" +#define ENV1_SIZE	0x4000 +#define DEVICE1_ESIZE	0x4000 +#define ENV2_SIZE	0x4000 +#define DEVICE2_ESIZE	0x4000 + +Current configuration matches the environment layout of the TRAB +board. + +Un-define HAVE_REDUND, if you want to use the utlities on a system +that does not have support for redundant environment enabled. The +DEVICEx_NAME constants define which MTD character device(s) is (are) +to be used to access the environment. If HAVE_REDUND is undefined, +DEVICE2_NAME is ignored, as is ENV2_SIZE and DEVICE2_ESIZE. ENVx_SIZE +defines the size in bytes taken by the environment, which may be less +then flash sector size, if the environment takes less then 1 sector. +DEVICEx_ESIZE defines the size of the first sector in the flash +partition where the environment resides. It is assumed that the +environment is located in the first ENVx_SIZE bytes of the device +DEVICEx_NAME. diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c new file mode 100644 index 000000000..5bf75ac2c --- /dev/null +++ b/tools/env/fw_env.c @@ -0,0 +1,662 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <stddef.h> +#include <string.h> +#include <sys/types.h> +#include <sys/ioctl.h> +#include <sys/stat.h> +#include <unistd.h> +#include <linux/mtd/mtd.h> +#include "fw_env.h" + +typedef	unsigned char	uchar; + +#define	CMD_GETENV	"fw_printenv" +#define	CMD_SETENV	"fw_setenv" + +typedef struct envdev_s { +	uchar devname[16]; /* Device name */ +	ulong env_size;    /* environment size */ +	ulong erase_size;  /* device erase size */ +} envdev_t; + +static envdev_t envdevices[2]; +static int curdev; + +#define DEVNAME(i)    envdevices[(i)].devname +#define ENVSIZE(i)    envdevices[(i)].env_size +#define DEVESIZE(i)   envdevices[(i)].erase_size + +#define CFG_ENV_SIZE ENVSIZE(curdev) + +#ifdef HAVE_REDUND +#define ENV_SIZE (CFG_ENV_SIZE - sizeof(long) - 1) +#else +#define ENV_SIZE (CFG_ENV_SIZE - sizeof(long)) +#endif + +typedef struct environment_s { +	ulong	crc;		/* CRC32 over data bytes	*/ +	uchar   flags;      /* active or obsolete */ +	uchar *data; +} env_t; + +static env_t environment; +static int valid = 0; + +#ifdef HAVE_REDUND +static uchar active_flag = 1; +static uchar obsolete_flag = 0; +#endif + +#define XMK_STR(x)	#x +#define MK_STR(x)	XMK_STR(x) + +static uchar default_environment[] = { +#ifdef	CONFIG_BOOTARGS +	"bootargs="	CONFIG_BOOTARGS			"\0" +#endif +#ifdef	CONFIG_BOOTCOMMAND +	"bootcmd="	CONFIG_BOOTCOMMAND		"\0" +#endif +#if (CONFIG_BOOTDELAY >= 0) +	"bootdelay="	MK_STR(CONFIG_BOOTDELAY)	"\0" +#endif +#if (CONFIG_BAUDRATE >= 0) +	"baudrate="	MK_STR(CONFIG_BAUDRATE)		"\0" +#endif +#ifdef	CONFIG_ETHADDR +	"ethaddr="	MK_STR(CONFIG_ETHADDR)		"\0" +#endif +#ifdef	CONFIG_IPADDR +	"ipaddr="	MK_STR(CONFIG_IPADDR)		"\0" +#endif +#ifdef	CONFIG_SERVERIP +	"serverip="	MK_STR(CONFIG_SERVERIP)		"\0" +#endif +	"\0" +}; + +static int  flash_io (int mode); +static uchar *envmatch(uchar *s1, uchar *s2); +static int env_init(void); +static int parse_config(void); + + +/* + * 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); +} + +/* + * Print the current definition of one, or more, or all + * environment variables + */ +void fw_printenv(int argc, char *argv[]) +{ +	uchar *env, *nxt; +	int i, n_flag; + +	if (env_init()) +		return; + +	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"); +					return; +				} +			} + +			printf("%s\n", env); +		} +		return; +	} + +	if (strcmp(argv[1], "-n") == 0) { +		n_flag = 1; +		++argv; +		--argc; +		if (argc != 2) { +			fprintf (stderr, "## Error: " +				"`-n' option requires exactly one argument\n"); +			return; +		} +	} else { +		n_flag = 0; +	} + +	for (i=1; i<argc; ++i) {	/* print single env variables	*/ +		uchar *name = argv[i]; +		uchar *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"); +					return; +				} +			} +			val=envmatch(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); +	} +} + +/* + * 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; +	uchar *name; + +	if (argc < 2) { +		return (EINVAL); +	} + +	if (env_init()) +		return (errno); + +	name = argv[1]; + +	/* +	 * search if variable with this name already exists +	 */ +	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"); +				return (EINVAL); +			} +		} +		if ((oldval=envmatch(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) { +		uchar *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); +} + +static int flash_io (int mode) +{ +	int fd, fdr, rc, otherdev, len, resid; +	erase_info_t erase; +	char *data; + +	if ((fd = open(DEVNAME(curdev), mode)) < 0) { +		fprintf (stderr,  +				 "Can't open %s: %s\n",  +				 DEVNAME(curdev), strerror(errno)); +		return (-1); +	} + +	len = sizeof(environment.crc) + sizeof(environment.flags); + +	if (mode == O_RDWR) { +#ifdef HAVE_REDUND +		/* switch to next partition for writing */ +		otherdev = !curdev; +		if ((fdr = open(DEVNAME(otherdev), mode)) < 0) { +			fprintf (stderr,  +					 "Can't open %s: %s\n",  +					 DEVNAME(otherdev), strerror(errno)); +			return (-1); +		} +#else +		otherdev = curdev; +		fdr = fd; +		len = sizeof(environment.crc); +#endif +		printf("Unlocking flash...\n"); +		erase.length = DEVESIZE(otherdev); +		erase.start = 0; +		ioctl (fdr, MEMUNLOCK, &erase); + +#ifdef HAVE_REDUND +		erase.length = DEVESIZE(curdev); +		erase.start = 0; +		ioctl (fd, MEMUNLOCK, &erase); +		environment.flags = active_flag; +#endif +		printf("Done\n"); +		resid = DEVESIZE(otherdev) - CFG_ENV_SIZE; +		if (resid) { +			if ((data = malloc(resid)) == NULL) { +				fprintf(stderr,  +				  "Cannot malloc %d bytes: %s\n", +				  resid, strerror(errno)); +				return (-1); +			} +			if (lseek (fdr, CFG_ENV_SIZE, SEEK_SET) == -1) { +				fprintf (stderr, +				  "seek error on %s: %s\n",  +				   DEVNAME(curdev), strerror(errno)); +				return (-1); +			} +			if ((rc = read (fdr, data, resid)) != resid) { +				fprintf (stderr, +				  "read error on %s: %s\n",  +				  DEVNAME(curdev), strerror(errno)); +				return (-1); +			} +			if (lseek (fdr, 0, SEEK_SET) == -1) { +				fprintf (stderr, +				  "seek error on %s: %s\n",  +				  DEVNAME(curdev), strerror(errno)); +				return (-1); +			} +		} + +		printf("Erasing old environment...\n"); + +		erase.length = DEVESIZE(otherdev); +		if (ioctl (fdr, MEMERASE, &erase) != 0) { +			fprintf (stderr, "MTD erase error on %s: %s\n", +			  DEVNAME(otherdev), strerror(errno)); +			return (-1); +		} + +		printf("Done\n"); + +		printf("Writing environment to %s...\n",DEVNAME(otherdev)); +		if (write(fdr, &environment, len) != len) { +			fprintf (stderr, +			  "CRC write error on %s: %s\n",  +			  DEVNAME(otherdev), strerror(errno)); +			return (-1); +		} +		if (write(fdr, environment.data, ENV_SIZE) != ENV_SIZE) { +			fprintf (stderr, +			  "Write error on %s: %s\n",  +			  DEVNAME(otherdev), strerror(errno)); +			return (-1); +		} +		if (resid) { +			if (write (fdr, data, resid) != resid) { +				fprintf (stderr, +				 "write error on %s: %s\n",  +				  DEVNAME(curdev), strerror(errno)); +				return (-1); +			} +			free(data); +		} +#ifdef HAVE_REDUND +		/* change flag on current active env partition */ +		if (lseek (fd, sizeof(ulong), SEEK_SET) == -1) { +			fprintf (stderr, +			  "seek error on %s: %s\n",  +			  DEVNAME(curdev), strerror(errno)); +			return (-1); +		} +		if (write (fd, &obsolete_flag, sizeof(obsolete_flag)) !=  +			sizeof(obsolete_flag)) { +			fprintf (stderr, +			 "Write error on %s: %s\n",  +			 DEVNAME(curdev), strerror(errno)); +			return (-1); +		} +#endif +		printf("Done\n"); +		printf("Locking ...\n"); +		erase.length = DEVESIZE(otherdev); +		erase.start = 0; +		ioctl (fdr, MEMLOCK, &erase); +#ifdef HAVE_REDUND +		erase.length = DEVESIZE(curdev); +		erase.start = 0; +		ioctl (fd, MEMLOCK, &erase); +		if (close(fdr)) { +			fprintf (stderr, +			 "I/O error on %s: %s\n",  +			 DEVNAME(otherdev), strerror(errno)); +			return (-1); +		} +#endif +		printf("Done\n"); +	} else { +#ifndef HAVE_REDUND +		len = sizeof(environment.crc); +#endif +		if (read (fd, &environment, len) != len) { +			fprintf (stderr, +			 "CRC read error on %s: %s\n",  +			 DEVNAME(curdev), strerror(errno)); +			return (-1); +		} +		if ((rc = read (fd, environment.data, ENV_SIZE)) != ENV_SIZE) { +			fprintf (stderr, +			 "Read error on %s: %s\n",  +			  DEVNAME(curdev), strerror(errno)); +			return (-1); +		} +	} + +	if (close(fd)) { +		fprintf (stderr, +		  "I/O error on %s: %s\n",  +		  DEVNAME(curdev), strerror(errno)); +		return (-1); +	} + +	/* everything ok */ +	return (0); +} + +/* + * s1 is either a simple 'name', or a 'name=value' pair. + * s2 is a 'name=value' pair. + * If the names match, return the value of s2, else NULL. + */ + +static uchar * +envmatch (uchar *s1, uchar *s2) +{ + +	while (*s1 == *s2++) +		if (*s1++ == '=') +			return(s2); +	if (*s1 == '\0' && *(s2-1) == '=') +		return(s2); +	return(NULL); +} + +/* + * Prevent confusion if running from erased flash memory + */ +static int env_init(void) +{ +	int crc1, crc1_ok; +	uchar *addr1; +#ifdef HAVE_REDUND +	int crc2, crc2_ok; +	uchar flag1, flag2, *addr2; +#endif + +	 +	if (!valid) { + +		if (parse_config()) /* should fill envdevices */ +			return 1; + +		if ((addr1 = calloc (1, ENV_SIZE)) == NULL) { +			fprintf (stderr,  +			 "Not enough memory for environment (%ld bytes)\n", +			 ENV_SIZE); +			return (errno); +		} + +		/* read environment from FLASH to local buffer */ +		environment.data = addr1; +		curdev = 0; +		if (flash_io (O_RDONLY)) { +			return (errno); +		} + +		crc1_ok = ((crc1 = crc32(0, environment.data, ENV_SIZE))  +			 == environment.crc); +#ifndef HAVE_REDUND +		if (!crc1_ok) { +			fprintf (stderr,  +			 "Warning: Bad CRC, using default environment\n"); +			environment.data = default_environment; +			free(addr1); +		} +#else +		flag1 = environment.flags; +		 +		curdev = 1; +		if ((addr2 = calloc (1, ENV_SIZE)) == NULL) { +			fprintf (stderr,  +			 "Not enough memory for environment (%ld bytes)\n", +			 ENV_SIZE); +			return (errno); +		}		 +		environment.data = addr2; + +		if (flash_io (O_RDONLY)) { +			return (errno); +		} + +		crc2_ok = ((crc2 = crc32(0, environment.data, ENV_SIZE))  +				   == environment.crc); +		flag2 = environment.flags; +		 +		if (crc1_ok && ! crc2_ok) { +			environment.data  = addr1; +			environment.flags = flag1; +			environment.crc = crc1; +			curdev = 0; +			free(addr2); +		} +		else if (! crc1_ok && crc2_ok) { +			environment.data  = addr2; +			environment.flags = flag2; +			environment.crc = crc2; +			curdev = 1; +			free(addr1); +		} +		else if (! crc1_ok && ! crc2_ok) { +			fprintf (stderr,  +			 "Warning: Bad CRC, using default environment\n"); +			environment.data = default_environment; +			curdev = 0; +			free(addr2); +			free(addr1); +		} +		else if (flag1 == active_flag && flag2 == obsolete_flag) { +			environment.data  = addr1; +			environment.flags = flag1; +			environment.crc = crc1; +			curdev = 0; +			free(addr2); +		} +		else if (flag1 == obsolete_flag && flag2 == active_flag) { +			environment.data  = addr2; +			environment.flags = flag2; +			environment.crc = crc2; +			curdev = 1; +			free(addr1); +		} +		else if (flag1 == flag2) { +			environment.data  = addr1; +			environment.flags = flag1; +			environment.crc = crc1; +			curdev = 0; +			free(addr2); +		} +		else if (flag1 == 0xFF)	{ +			environment.data  = addr1; +			environment.flags = flag1; +			environment.crc = crc1; +			curdev = 0; +			free(addr2); +		} +		else if (flag2 == 0xFF) { +			environment.data  = addr2; +			environment.flags = flag2; +			environment.crc = crc2; +			curdev = 1; +			free(addr1); +		} +#endif		 +		valid = 1; +	} +	return (0); +} + + +static int parse_config() +{ +	struct stat st; + +	if (stat (DEVICE1_NAME, &st)) { +		fprintf (stderr,  +		 "Cannot access MTD device %s: %s\n",  +		 DEVICE1_NAME, strerror(errno)); +		return 1; +	} + +	strcpy(DEVNAME(0), DEVICE1_NAME); +	ENVSIZE(0) = ENV1_SIZE; +	DEVESIZE(0) = DEVICE1_ESIZE; +#ifdef HAVE_REDUND +	if (stat (DEVICE2_NAME, &st)) { +		fprintf (stderr,  +		 "Cannot access MTD device %s: %s\n",  +		 DEVICE2_NAME, strerror(errno)); +		return 1; +	} +	strcpy(DEVNAME(1), DEVICE2_NAME); +	ENVSIZE(1) = ENV2_SIZE; +	DEVESIZE(1) = DEVICE2_ESIZE; +#endif +	return 0; +} diff --git a/tools/env/fw_env.h b/tools/env/fw_env.h new file mode 100644 index 000000000..d98edc997 --- /dev/null +++ b/tools/env/fw_env.h @@ -0,0 +1,44 @@ +/* + * (C) Copyright 2002 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#define HAVE_REDUND /* For systems with 2 env sectors */ +#define DEVICE1_NAME      "/dev/mtd1" +#define DEVICE2_NAME      "/dev/mtd2" +#define ENV1_SIZE         0x4000 +#define DEVICE1_ESIZE     0x4000 +#define ENV2_SIZE         0x4000 +#define DEVICE2_ESIZE     0x4000 + +#define CONFIG_BAUDRATE		115200 +#define CONFIG_BOOTDELAY	5	/* autoboot after 5 seconds	*/ +#define CONFIG_BOOTCOMMAND							\ +	"bootp; " 								\ +	"setenv bootargs root=/dev/nfs nfsroot=$(serverip):$(rootpath) " 	\ +	"ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname)::off; " 	\ +	"bootm" + +extern		void  fw_printenv(int argc, char *argv[]); +extern unsigned char *fw_getenv  (unsigned char *name); +extern		int   fw_setenv  (int argc, char *argv[]); + +extern unsigned	long  crc32	 (unsigned long, const unsigned char *, unsigned); diff --git a/tools/env/fw_env_main.c b/tools/env/fw_env_main.c new file mode 100644 index 000000000..1c22e7143 --- /dev/null +++ b/tools/env/fw_env_main.c @@ -0,0 +1,78 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * Command line user interface to firmware (=PPCBoot) environment. + * + * Implements: + *	fw_printenv [ name ... ] + *		- prints the values of the environment variables + *		  "name", or the whole environment if no names are + *		  specified + *	fw_setenv name [ value ... ] + *		- If a name without any values is given, the variable + *		  with this name is deleted from the environment; + *		  otherwise, all "value" arguments are concatenated, + *		  separated by sinlge blank characters, and the + *		  resulting string is assigned to the environment + *		  variable "name" + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include "fw_env.h" + +#define	CMD_PRINTENV	"fw_printenv" +#define CMD_SETENV	"fw_setenv" + +int +main(int argc, char *argv[]) +{ +	char *p; +	char *cmdname = *argv; + +	if ((p = strrchr (cmdname, '/')) != NULL) { +		cmdname = p + 1; +	} + +	if (strcmp(cmdname, CMD_PRINTENV) == 0) { + +			fw_printenv (argc, argv); + +			return (EXIT_SUCCESS); + +	} else if (strcmp(cmdname, CMD_SETENV) == 0) { + +			if (fw_setenv (argc, argv) != 0) +				return (EXIT_FAILURE); + +			return (EXIT_SUCCESS); +	} + +	fprintf (stderr, +		"Identity crisis - may be called as `" CMD_PRINTENV +		"' or as `" CMD_SETENV "' but not as `%s'\n", +		cmdname); +	return (EXIT_FAILURE); +} |