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

📄 docmd.c

📁 完整的Bell实验室的嵌入式文件系统TFS
💻 C
📖 第 1 页 / 共 2 页
字号:
/* docmd: *  This code supports the command line interface (CLI) portion of the *  monitor.  It is a table-driven CLI that uses the table in cmdtbl.c. *  A limited amount of "shell-like" capabilities are supported... *      shell variables, symbol-table lookup, command history, *      command line editiing, command output redirection, etc... * *  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 "genlib.h"#include "tfs.h"#include "tfsprivate.h"#include "cli.h"/* appCmdlist: *  This is a pointer to a list of commands that can be added to the  *  monitor's list by the application using addcommand(). */struct  monCommand *appCmdlist;void    paramerr(struct monCommand *);void    showusage(struct monCommand *);int     showhelp(struct monCommand *,int,int);void    shownextarg(struct monCommand *,char *,int,char **);int     expandshellvars(char *);int     tokenize(char *,char **);extern  struct monCommand cmdlist[];extern  char cmdUlvl[];/*  docommand(): *  Assume the incoming string is a null terminated character string *  that is made up of whitespace delimited tokens that will be parsed *  into command line arguments.  The first argument is the command name *  and all following arguments (if any) are specific to that command. *  Three levels of verbosity are supported: *  verbose == 0        no verbosity; *  verbose == 1        print the list of arguments after tokenization *  verbose == 2        print the incoming string prior to processing AND *                      print the list of arguments after tokenization;  *                      the print of the unprocessed string is prefixed by *                      a "+ " string. *  The verbosity level is 0 by default, to change the level, the script *  should be run with "tfs -v run script" for verbose = 1 or *  "tfs -v -v run script" for verbose = 2. */intdocommand(char *cmdline,int verbose){    int ret, argc, i;    struct  monCommand  *cmdptr;    char    *ps, *argv[ARGCNT], cmdcpy[CMDLINESIZE];    if (verbose == 2)       /* Print command line prior to processing */        printf("+ %s\n",cmdline);        /* Just in case an upper-level interpreter has the same command as     * this monitor, if the first character of the incoming command     * string is an underscore, just throw it away.  This allows the     * user to get to the monitor command that is duplicated in an     * upper level interpreter by preceding it with an underscore.     */    if (cmdline[0] == '_')        cmdline++;    /* Copy the incoming command line to a local buffer so that we can      * be sure that the line is writeable; plus we do not alter the      * incoming buffer.     */    strcpy(cmdcpy,cmdline);    /* Scan through the string, if '#' is found, terminate line if     * it is not preceded by a backslash.  If it is preceded by a     * backslash, then remove the backslash from the line and leave     * the rest of the line as is.     */    ps = strchr(cmdcpy,'#');    if (ps) {        if (*(ps-1) != '\\')            *ps = 0;        else            strcpy(ps-1,ps);    }    /* If there are any instances if a dollar or percent sign within the      * command line, then expand any shell variables (or symbols) that may     * be present.     */    if (strpbrk(cmdcpy,"$%")) {        if (expandshellvars(cmdcpy) < 0)            return(CMD_LINE_ERROR);    }    /* Do a redirection check after shell variable expansion.     * This must be done after the shell variable expansion so that we     * can do things like..     *     *   echo hi >$APPRAMBASE,100     */    if (RedirectionCheck(cmdcpy) == -1)        return(CMD_LINE_ERROR);    /* Build argc/argv structure based on incoming command line. */    argc = tokenize(cmdcpy,argv);    if (argc == 0)        return(CMD_LINE_ERROR);    if (argc < 0) {        printf("Command line error\n");        return(CMD_LINE_ERROR);    }    /* If verbosity is enabled, print the processed command line. */    if (verbose) {          for(i=0;i<argc;i++)            printf("%s ",argv[i]);        printf("\n");    }    /* Initialize static data used by getopt(). */    getoptinit();    /* Step through the command table looking for a match between     * the first token of the command line and a command name.     */    cmdptr = cmdlist;    while(cmdptr->name) {        if (strcmp(argv[0],cmdptr->name) == 0)            break;        cmdptr++;    }    if (cmdptr->name) {        if (cmdUlvl[cmdptr-cmdlist] > getUsrLvl()) {            return(CMD_ULVL_DENIED);        }        if ((argc > 1) && (strcmp(argv[argc-1],"?") == 0)) {            shownextarg(cmdptr,cmdline,argc,argv);            return(CMD_PREFILL);        }        ret = cmdptr->func(argc,argv);        /* If command returns parameter error, then print the second         * string in that commands help text as the usage text.  If         * the second string is a null pointer, then print a generic         * "no arguments" string as the usage message.         */        if (ret == CMD_PARAM_ERROR)            paramerr(cmdptr);                RedirectionCmdDone();        return(ret);    }    /* If we get here, then the first token does not match on any of     * the command names in the standard command table.  Next we try     * the optional application-provided command table.     */    if (appCmdlist) {        cmdptr = appCmdlist;        while(cmdptr->name) {            if (strcmp(argv[0],cmdptr->name) == 0)                break;            cmdptr++;        }        if (cmdptr->name) {            ret = cmdptr->func(argc,argv);            if (ret == CMD_PARAM_ERROR)                paramerr(cmdptr);            RedirectionCmdDone();            return(ret);        }    }    /* If we get here, then the first token does not match on any of     * the command names in ether of the command tables.  As a last     * resort, we look to see if the first token matches an executable     * file name in TFS.     */    ret = CMD_NOT_FOUND;    if (tfsstat(argv[0])) {        int err;        err = tfsrun(argv,verbose);        if (err == TFS_OKAY) {            ret = CMD_SUCCESS;        }        else {            printf("%s: %s\n",argv[0],(char *)tfsctrl(TFS_ERRMSG,err,0));        }    }    else {        printf("Command not found: %s\n",argv[0]);    }    RedirectionCmdDone();    return(ret);}/* shownextarg(): */voidshownextarg(struct monCommand *cmdptr, char *cmdline, int argc, char **argv){    char *eol;    /* Remove the question mark: */    eol = cmdline + strlen(cmdline);    while(eol > cmdline) {        if (*eol == '?') {            *eol = 0;            break;        }        else            *eol = 0;        eol--;    }    if (cmdptr->clix) {        if (cmdptr->clix->nextarg(cmdline,argc,argv) == -1)            showusage(cmdptr);    }    else        showusage(cmdptr);}voidshowusage(struct monCommand *cmdptr){    char    *usage;    usage = cmdptr->helptxt[1];    printf("Usage: %s %s\n",        cmdptr->name,*usage ? usage : "(no args/opts)");}voidparamerr(struct monCommand *cmdptr){    printf("Command line error...\n");    showusage(cmdptr);}intaddcommand(struct monCommand *cmd){    if (appCmdlist)        printf("Overwriting appCmdlist pointer.\n");    appCmdlist = cmd;    return(0);}static char *shellsym_chk(char type, char *string,int *size,char *buf,int bufsize){    char    *p1, *p2, varname[CMDLINESIZE], *val;    p1 = string;    p2 = varname;    while(1) {        if (((*p1 >= '0') && (*p1 <= '9')) ||            ((*p1 >= 'a') && (*p1 <= 'z')) ||            ((*p1 >= 'A') && (*p1 <= 'Z')) ||            (*p1 == '_')) {            *p2++ = *p1++;        }        else            break;    }    *p2 = '\0';    if (type == '%')        val = getsym(varname,buf,bufsize);    else        val = getenv(varname);    if (val) {        *size = strlen(varname);        return(val);    }    else        return((char *)0);}/* braceimbalance(): *  Return non-zero (the index into the src string at the point of the  *  imbalance) if the incoming string does not have a balanced set *  of braces; else return 0. */static intbraceimbalance(char *src, int *idx, int *ndp){    int     bnest;    char    *base;    bnest = 0;    base = src;    while((*src) && (bnest >= 0)) {        if (((*src == '$') || (*src == '%')) && (*(src+1) == '{')) {            bnest++;            src++;        }        else if (*src == '}')            bnest--;        else if (*src == '{') {            *ndp += 1;  /* Indicate that there is a brace with no '$' prefix */        }        else if (*src == '\\') {            if ((*(src+1) == '$') || (*(src+1) == '%') ||                (*(src+1) == '\\') ||                (*(src+1) == '{') || (*(src+1) == '}')) {                src++;            }        }        src++;    }    /* If there is a '{}' mismatch, bnest will be non-zero... */    *idx = src - base - 1;    return(bnest);}/* processprefixes(): *  Process the '$' for shell variables and '%' for symbols. *  Look for the last '$' (or '%') in the incoming string and attempt to *  make a shell variable (or symbol) substitution.  Return 0 if no '$' *  (or '%') is found.  Note that '$' and '%' are processed interchangeably *  to support symbols and shell variables in the same way. */static intprocessprefixes(char *src){    int     namesize, srclen;    char    *base, *varname, *value;    char    buf[CMDLINESIZE], buf1[CMDLINESIZE];    base = src;

⌨️ 快捷键说明

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