diff options
Diffstat (limited to 'board/hymod/env.c')
| -rw-r--r-- | board/hymod/env.c | 236 | 
1 files changed, 236 insertions, 0 deletions
| diff --git a/board/hymod/env.c b/board/hymod/env.c new file mode 100644 index 000000000..f58aec257 --- /dev/null +++ b/board/hymod/env.c @@ -0,0 +1,236 @@ +/* + * (C) Copyright 2003 + * Murray Jensen, CSIRO-MIT, <Murray.Jensen@csiro.au> + * + * 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 <common.h> + +/* imports from fetch.c */ +extern int fetch_and_parse (char *, ulong, int (*)(uchar *, uchar *)); + +/* this is relative to the root of the server's tftp directory */ +static char *def_global_env_path = "/hymod/global_env"; + +static int +env_callback (uchar *name, uchar *value) +{ +	DECLARE_GLOBAL_DATA_PTR; + +	hymod_conf_t *cp = &gd->bd->bi_hymod_conf; +	char ov[CFG_CBSIZE], nv[CFG_CBSIZE], *p, *q, *nn, c, *curver, *newver; +	int override = 1, append = 0, remove = 0, nnl, ovl, nvl; + +	nn = name; + +	if (*nn == '-') { +		override = 0; +		nn++; +	} + +	while (*nn == ' ' || *nn == '\t') +		nn++; + +	if ((nnl = strlen (nn)) == 0) { +		printf ("Empty name in global env file\n"); +		return (0); +	} + +	if ((c = nn[nnl - 1]) == '+' || c == '-') { +		if (c == '+') +			append = 1; +		else +			remove = 1; +		nn[--nnl] = '\0'; +	} + +	while (nnl > 0 && ((c = nn[nnl - 1]) == ' ' || c == '\t')) +		nn[--nnl] = '\0'; +	if (nnl == 0) { +		printf ("Empty name in global env file\n"); +		return (0); +	} + +	p = value; +	q = nv; + +	while ((c = *p) == ' ' || c == '\t') +		p++; + +	nvl = strlen (p); +	while (nvl > 0 && ((c = p[nvl - 1]) == ' ' || c == '\t')) +		p[--nvl] = '\0'; + +	while ((*q = *p++) != '\0') { +		if (*q == '%') { +			switch (*p++) { + +			case '\0':	/* whoops - back up */ +				p--; +				break; + +			case '%':	/* a single percent character */ +				q++; +				break; + +			case 's':	/* main board serial number as string */ +				q += sprintf (q, "%010lu", +					cp->main.eeprom.serno); +				break; + +			case 'S':	/* main board serial number as number */ +				q += sprintf (q, "%lu", cp->main.eeprom.serno); +				break; + +			default:	/* ignore any others */ +				break; +			} +		} +		else +			q++; +	} + +	if ((nvl = q - nv) == 0) { +		setenv (nn, NULL); +		return (1); +	} + +	if ((curver = getenv ("global_env_version")) == NULL) +		curver = "unknown"; + +	if ((newver = getenv ("new_genv_version")) == NULL || \ +	    strcmp (curver, newver) == 0) { +		if (strcmp (nn, "version") == 0) +			setenv ("new_genv_version", nv); +		return (1); +	} + +	if ((p = getenv (nn)) != NULL) { + +		strcpy (ov, p); +		ovl = strlen (ov); + +		if (append) { + +			if (strstr (ov, nv) == NULL) { + +				printf ("Appending '%s' to env var '%s'\n", +					nv, nn); + +				while (nvl >= 0) { +					nv[ovl + 1 + nvl] = nv[nvl]; +					nvl--; +				} + +				nv[ovl] = ' '; + +				while (--ovl >= 0) +					nv[ovl] = ov[ovl]; + +				setenv (nn, nv); +			} + +			return (1); +		} + +		if (remove) { + +			if (strstr (ov, nv) != NULL) { + +				printf ("Removing '%s' from env var '%s'\n", +					nv, nn); + +				while ((p = strstr (ov, nv)) != NULL) { +					q = p + nvl; +					if (*q == ' ') +						q++; +					strcpy(p, q); +				} + +				setenv (nn, ov); +			} + +			return (1); +		} + +		if (!override || strcmp (ov, nv) == 0) +			return (1); + +		printf ("Re-setting env cmd '%s' from '%s' to '%s'\n", +			nn, ov, nv); +	} +	else +		printf ("Setting env cmd '%s' to '%s'\n", nn, nv); + +	setenv (nn, nv); +	return (1); +} + +void +hymod_check_env (void) +{ +	char *p, *path, *curver, *newver; +	int firsttime = 0, needsave = 0; + +	if (getenv ("global_env_loaded") == NULL) { +		puts ("*** global environment has never been loaded\n"); +		puts ("*** fetching from server"); +		firsttime = 1; +	} +	else if ((p = getenv ("always_check_env")) != NULL && +	    strcmp (p, "yes") == 0) +		puts ("*** checking for updated global environment"); +	else +		return; + +	puts (" (Control-C to Abort)\n"); + +	if ((path = getenv ("global_env_path")) == NULL || *path == '\0') +		path = def_global_env_path; + +	if (fetch_and_parse (path, CFG_LOAD_ADDR, env_callback) == 0) { +		puts ("*** Fetch of global environment failed!\n"); +		return; +	} + +	if ((newver = getenv ("new_genv_version")) == NULL) { +		puts ("*** Version number not set - contents ignored!\n"); +		return; +	} + +	if ((curver = getenv ("global_env_version")) == NULL || \ +	    strcmp (curver, newver) != 0) { +		setenv ("global_env_version", newver); +		needsave = 1; +	} +	else +		printf ("*** Global environment up-to-date (ver %s)\n", curver); + +	setenv ("new_genv_version", NULL); + +	if (firsttime) { +		setenv ("global_env_loaded", "yes"); +		needsave = 1; +	} + +	if (needsave) +		puts ("\n*** Remember to run the 'saveenv' " +			"command to save the changes\n\n"); +} |