⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 env.c

📁 umon bootloader source code, support mips cpu.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* shell variable functions:
 *	Used to load or retrieve shell variable information from the
 *	shell variable table.
 *
 *	General notice:
 *	This code is part of a boot-monitor package developed as a generic base
 *	platform for embedded system designs.  As such, it is likely to be
 *	distributed to various projects beyond the control of the original
 *	author.  Please notify the author of any enhancements made or bugs found
 *	so that all may benefit from the changes.  In addition, notification back
 *	to the author will allow the new user to pick up changes that may have
 *	been made by other users after this version of the code was distributed.
 *
 *	Note1: the majority of this code was edited with 4-space tabs.
 *	Note2: as more and more contributions are accepted, the term "author"
 *		   is becoming a mis-representation of credit.
 *
 *	Original author:	Ed Sutter
 *	Email:				esutter@lucent.com
 *	Phone:				908-582-2351
 */
#include <stdarg.h>
#include "config.h"
#if INCLUDE_SHELLVARS
#include "tfs.h"
#include "tfsprivate.h"
#include "ether.h"
#include "genlib.h"
#include "stddefs.h"
#include "cli.h"
#include "version.h"
#include "boardinfo.h"
#include "ee.h"


#ifdef TARGET_ENV_SETUP
extern void TARGET_ENV_SETUP(void);
#endif

#ifndef PROMPT
#define PROMPT "uMON>"
#endif

int	shell_print(void);
int	envToExec(char *);
void clearenv(void);

/* Structure used for the shell variables: */
struct s_shell {
	char	*val;		/* Value stored in shell variable */
	char	*name;		/* Name of shell variable */
	int		vsize;		/* Size of storage allocated for value */
	struct	s_shell *next;
};

struct s_shell *shell_vars;

/* If no malloc, then use locally defined env_alloc() and env_free()...
 */
#if INCLUDE_MALLOC

#define env_alloc	malloc
#define env_free	free

#else

#define ENV_ALLOC_TOT	48
#define ENV_ALLOC_SIZE	(sizeof(struct s_shell)+8)

struct env_space {
	int inuse;
	char space[ENV_ALLOC_SIZE];
} envSpace[ENV_ALLOC_TOT];


char *
env_alloc(int size)
{
	int	 i;

	if (size > ENV_ALLOC_SIZE)
		return(0);

	for(i=0;i<ENV_ALLOC_TOT;i++) {
		if (envSpace[i].inuse == 0) {
			envSpace[i].inuse = 1;
			memset(envSpace[i].space,0,ENV_ALLOC_SIZE);
			return(envSpace[i].space);
		}
	}
	return(0);
}

void
env_free(char *space)
{
	int i;

	for(i=0;i<ENV_ALLOC_TOT;i++) {
		if (envSpace[i].space == space) {
			envSpace[i].inuse = 0;
			break;
		}
	}
	return;
}
#endif

/*
 *  Set()
 *
 *	Syntax:
 *		set var				clears the variable 'var'
 *		set var value		assign "value" to variable 'var'
 *		set -a var value	AND 'var' with 'value'
 *		set -o var value	OR 'var' with 'value'
 *		set -i var [value]	increment 'var' by 'value' (or 1 if no value)
 *		set -d var [value]	decrement 'var' by 'value' (or 1 if no value)
 *		set -x 				result of -i/-d is in hex
 */
char *SetHelp[] = {
	"Shell variable operations",
#if INCLUDE_EE
	"-[ab:cdef:iox] [varname[=expression]] [value]",
#else
	"-[ab:cdef:iox] [varname] [value]",
#endif
#if INCLUDE_VERBOSEHELP
	" -a        AND var with value",
	" -b        set console baudrate",
	" -c        clear the environment",
	" -d        decrease var by value (or 1)",
	" -e        build an environ string",
	" -f{file}  create script from environment",
	" -i        increase var by value (or 1)",
	" -o        OR var with value",
	" -x        result is hex (else decimal)",
#endif
	0,
};

#define SET_NOOP	0
#define SET_INCR	1
#define SET_DECR	2
#define SET_OR		3
#define SET_AND		4

int
Set(int argc,char *argv[])
{
	char	*file, *envp, buf[128];
	int		opt, decimal, setop, i;

	setop = SET_NOOP;
	file = (char *)0;
	envp = (char *)0;
	decimal = 1;
	while((opt=getopt(argc,argv,"ab:cde:f:iox")) != -1) {
		switch(opt) {
		case 'a':		/* logical and */
			setop = SET_AND;
			decimal = 0;
			break;
		case 'b':
			ChangeConsoleBaudrate(atoi(optarg));
			return(CMD_SUCCESS);
		case 'c':		/* clear environment */
			clearenv();
			break;
		case 'd':		/* decrement */
			setop = SET_DECR;
			break;
		case 'e':	
			envp = getenvp();
			break;
#if INCLUDE_TFS	
		case 'f':		/* build script from environment */
			envToExec(optarg);
			return(0);
#endif
		case 'i':		/* increment */
			setop = SET_INCR;
			break;
		case 'o':		/* logical or */
			setop = SET_OR;
			decimal = 0;
			break;
		case 'x':
			decimal = 0;
			break;
		default:
			return(CMD_PARAM_ERROR);
		}
	}

	if (!shell_vars) {
		printf("No memory allocated for environment.\n");
		return(CMD_FAILURE);
	}

	if (setop != SET_NOOP) {	/* Do some operation on a shell variable */
		char	*varval, buf[32];
		unsigned long	value, opval;

		/* For -i & -d, if value is not specified, then assume 1. */
		if (argc == optind+1) {
			if ((setop == SET_INCR) || (setop == SET_DECR))
				opval = 1;
			else
				return(CMD_PARAM_ERROR);
		}
		else if (argc == optind+2)
			opval = strtoul(argv[optind+1],0,0);
		else
			return(CMD_PARAM_ERROR);

		varval = getenv(argv[optind]);
		if (!varval) {
			printf("%s: not found\n", argv[optind]);
			return(CMD_FAILURE);
		}
			
		value = strtoul(varval,(char **)0,0);
		switch(setop) {
			case SET_INCR:
				value += opval;
				break;
			case SET_DECR:
				value -= opval;
				break;
			case SET_AND:
				value &= opval;
				break;
			case SET_OR:
				value |= opval;
				break;
		}
		if (decimal)
			sprintf(buf,"%ld",value);
		else
			sprintf(buf,"0x%lx",value);
		setenv(argv[optind],buf);
	}
	else if (argc == optind) {	/* display all variables */
		shell_print();
	}
	else if (argc == (optind+1)) {	/* run EE or clear one var or set envp */
#if INCLUDE_EE
		switch(setEE(argv[optind])) {
			case 1:
				return(CMD_SUCCESS);
			case -1:
				return(CMD_FAILURE);
		}
#endif
		if (envp) 
			shell_sprintf(argv[optind],"0x%lx",(ulong)envp);
		else
			setenv(argv[optind],0);
	}
	else if (argc >= (optind+2)) {	/* Set a specific variable */
		buf[0] = 0;
		for(i=optind+1;i<argc;i++) {
			if ((strlen(buf) + strlen(argv[i]) + 2) >= sizeof(buf)) {
				printf("String too large\n");
				break;
			}
			strcat(buf,argv[i]);
			if (i != (argc-1))
				strcat(buf," ");
		}
		setenv(argv[optind],buf);
	}
	else 
		return(CMD_PARAM_ERROR);

	//printf("Ethaddr=%s\n",getenv("ETHERADD"));
	return(CMD_SUCCESS);
}

/* Shell variable support routines...
 *	The basic scheme is to malloc in the space needed for the variable
 *	name and the value of that variable.  For each variable that 
 *	exists there is one s_shell structure that is in the linked list.
 *	As shell variables are removed, their corresonding s_shell structure
 *	is NOT removed, but the data pointed to within the structure is
 *	freed.  This keeps the linked list implementation extremely simple
 *	but maintains the versatility gained by using malloc for the 
 *	variables instead of some limted set of static arrays.
 */


/* shell_alloc():
 *	First scan through the entire list to see if the requested
 *	shell variable name already exists in the list; if it does,
 *	then just use the same s_shell entry but change the value.
 *	Also, if the new value fits in the same space as the older value,
 *	then just use the same memory space (don't do the free/malloc).
 *	If it doesn't, then scan through the list again.  If there
 *	is one that has no variable assigned to it (name = 0), then
 *	use it for the new allocation.  If all s_shell structures do 
 *	have valid entries, then malloc a new s_shell structure and then
 *	place the new shell variable data in that structure.
 */

static int
shell_alloc(char *name,char *value)
{
	int	namelen, valuelen;
	struct s_shell *sp;

	sp = shell_vars;
	namelen = strlen(name);
	valuelen = strlen(value);
	while(1) {
		if (sp->name == (char *)0) {
			if (sp->next != (struct s_shell *)0) {
				sp = sp->next;
				continue;
			}
			else
				break;
		}
		if (strcmp(sp->name,name) == 0) {
			if (sp->vsize < valuelen+1) {		/* If new value is smaller	*/
				env_free(sp->val);				/* than the old value, then */
				sp->val = env_alloc(valuelen+1);/* don't re-allocate any	*/
				if (!sp->val)					/* memory, just copy into	*/
					return(-1);					/* the space used by the	*/
				sp->vsize = valuelen+1;			/* previous value.			*/
			}
			strcpy(sp->val,value);
			return(0);
		}
		if (sp->next == (struct s_shell *)0) 
			break;
		sp = sp->next;
	}
	sp = shell_vars;
	while(1) {
		if (sp->name == (char *)0) {
			sp->name = env_alloc(namelen+1);
			if (!sp->name)
				return(-1);
			strcpy(sp->name,name);
			sp->val = env_alloc(valuelen+1);
			if (!sp->val)
				return(-1);
			sp->vsize = valuelen+1;
			strcpy(sp->val,value);
			return(0);
		}
		if (sp->next != (struct s_shell *)0)
			sp = sp->next;
		else {
			sp->next = (struct s_shell *)env_alloc(sizeof(struct s_shell));
			if (!sp->next)
				return(-1);
			sp = sp->next;
			sp->name = env_alloc(namelen+1);
			if (!sp->name)
				return(-1);
			strcpy(sp->name,name);
			sp->val = env_alloc(valuelen+1);
			if (!sp->val)
				return(-1);
			sp->vsize = valuelen+1;
			strcpy(sp->val,value);
			sp->next = (struct s_shell *)0;
			return(0);
		}
	}
}

/* shell_dealloc():
 *	Remove the requested shell variable from the list.  Return 0 if
 *	the variable was removed successfully, otherwise return -1.
 */
static int
shell_dealloc(char *name)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -