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

📄 env.c

📁 完整的Bell实验室的嵌入式文件系统TFS
💻 C
字号:
/* 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 "config.h"#include "tfs.h"#include "tfsprivate.h"#include "ether.h"#include "genlib.h"#include "stddefs.h"#include "cli.h"#ifndef PROMPT#define PROMPT "uMON>"#endifint shell_print(void);int envToExec(char *);/* 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;/* *  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",    "-[adF:iox] [varname] [value]",    " -a        AND var with value",    " -d        decrease var by value (or 1)",    " -i        increase var by value (or 1)",    " -o        OR var with value",    " -x        result is hex (else decimal)",    0,};#define SET_NOOP    0#define SET_INCR    1#define SET_DECR    2#define SET_OR      3#define SET_AND     4intSet(int argc,char *argv[]){    char    *buf, *file;    int     i, opt, decimal, setop;    setop = SET_NOOP;    file = (char *)0;    decimal = 1;    while((opt=getopt(argc,argv,"adiox")) != -1) {        switch(opt) {        case 'a':       /* logical and */            setop = SET_AND;            decimal = 0;            break;        case 'd':       /* decrement */            setop = SET_DECR;            break;        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) {    /* clear one variable */        setenv(argv[optind],0);    }    else if (argc == optind + 2) {  /* Set a specific variable */        setenv(argv[optind],argv[optind+1]);    }    else if (argc >= optind + 2) {  /* Concatenate multiple args into one. */        int len = 0;        for(i=optind+1;i<argc;i++)            len += strlen(argv[i]);        buf = malloc(len+argc+8);        *buf = 0;        for(i=optind+1;i<argc;i++) {            strcat(buf,argv[i]);            if (i+1 != argc)                strcat(buf," ");        }        setenv(argv[optind],buf);        free(buf);    }    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. */intshell_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  */                free(sp->val);                  /* than the old value, then */                sp->val = malloc(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 = malloc(namelen+1);            if (!sp->name)                return(-1);            strcpy(sp->name,name);            sp->val = malloc(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 *)malloc(sizeof(struct s_shell));            if (!sp->next)                return(-1);            sp = sp->next;            sp->name = malloc(namelen+1);            if (!sp->name)                return(-1);            strcpy(sp->name,name);            sp->val = malloc(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. */intshell_dealloc(name)char    *name;{    struct  s_shell *sp;    sp = shell_vars;    while(1) {        if (sp->name == (char *)0) {            if (sp->next == (struct s_shell *)0)                return(-1);            else {                sp = sp->next;                continue;            }        }        if (strcmp(name,sp->name) == 0) {            free(sp->name);            free(sp->val);            sp->name = (char *)0;            sp->val = (char *)0;            return(0);        }                if (sp->next == (struct s_shell *)0)            return(-1);        else            sp = sp->next;    }}/* ConsoleBaudEnvSet(): *  Called by ShellVarInit() and mstat() to load/reload the CONSOLEBAUD *  shell variable based on the content of the global variable *  "ConsoleBaudRate". */voidConsoleBaudEnvSet(void){    char    buf[16];    sprintf(buf,"%d",ConsoleBaudRate);    setenv("CONSOLEBAUD",buf);}/* ShellVarInit(); *  Setup the shell_vars pointer appropriately for additional *  shell variable assignments that will be made through shell_alloc(). */intShellVarInit(){    char    buf[16];    shell_vars = (struct s_shell *)malloc(sizeof(struct s_shell));    if (!shell_vars) {        printf("No memory for environment initialization\n");        return(-1);    }    shell_vars->next = (struct s_shell *)0;    shell_vars->name = (char *)0;    setenv("PROMPT",PROMPT);    sprintf(buf,"0x%lx",APPLICATION_RAMSTART);    setenv("APPRAMBASE",buf);    sprintf(buf,"0x%lx",BOOTROM_BASE);    setenv("BOOTROMBASE",buf);    setenv("PLATFORM",PLATFORM_NAME);    ConsoleBaudEnvSet();    MonitorBuiltEnvSet();    return(0);}/* shell_get: *  Return the pointer to the value entry if the shell variable *  name is currently set; otherwise, return a null pointer. */char *getenv(char *name){    register struct s_shell *sp;    sp = shell_vars;    while(sp) {        if (sp->name != (char *)0) {            if (strcmp(sp->name,name) == 0)                return(sp->val);        }        sp = sp->next;    }    return((char *)0);}/* setenv: *  Interface to shell_dealloc() and shell_alloc(). */intsetenv(char *name,char *value){    if (!shell_vars)        return(-1);    if ((value == (char *)0) || (*value == 0))        return(shell_dealloc(name));    else        return(shell_alloc(name,value));}/* shell_print(): *  Print out all of the current shell variables and their values. */intshell_print(void){    register struct s_shell *sp;    sp = shell_vars;    while(1) {        if (sp->name != (char *)0) {            printf("%16s = ", sp->name);            puts(sp->val);      /* sp->val may overflow printf, so use puts */            putchar('\n');        }        if (sp->next != (struct s_shell *)0)            sp = sp->next;        else            break;    }    return(0);}/* shell_sprintf(): *  Simple way to turn a printf-like formatted string into a shell variable. */intshell_sprintf(char *varname,char *format,long arg1,long arg2,long arg3,    long arg4,long arg5,long arg6,long arg7,long arg8,long arg9,    long arg10,long arg11,long arg12){    int len;    char buf[80];    len = sprintf(buf,format,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,        arg10,arg11,arg12);    setenv(varname,buf);    return(len);}

⌨️ 快捷键说明

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