home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
-
- #include "global.h"
- #include "cmdparse.h"
- #include "misc.h"
- #include "var.h"
-
- varlist global_vars = NULL;
-
- static int command_tokenise(char *line, char *argv[]);
- static char *skipspace(char *p);
- static int unescape(char *s);
-
- void cmdparse_init(void)
- {
- global_vars = varlist_create(NULL);
- var_init_osvars(global_vars, vart_string, "TCPIP$String$*" );
- var_init_osvars(global_vars, vart_osvar, "TCPIP$OSVar$*" );
- }
-
- int dosetvar(int argc, char **argv)
- {
- var_create_string(global_vars, argv[1], 0, argv[2]);
- return 0;
- }
-
- int dosetosvar(int argc, char **argv)
- {
- var_create_osvar(global_vars, argv[1], 0, argv[2]);
- return 0;
- }
-
- int doshowvar(int argc, char **argv)
- {
- char buf[256];
- var vp;
-
- if (argc<2)
- {
- for (vp = global_vars->head; vp!=NULL; vp = vp->link)
- {
- var_output(vp, buf, 256);
- if (vp->type==vart_osvar)
- cwprintf(NULL, " %-16s: <%s> = \"%s\"\r\n", vp->name+1, vp->value.string, buf);
- else
- cwprintf(NULL, " %-16s: \"%s\"\r\n", vp->name+1, buf);
- }
- }
- else
- {
- if (vp = var_lookup(global_vars, argv[1], 0), vp!=NULL)
- {
- var_output(vp, buf, 256);
- if (vp->type==vart_osvar)
- cwprintf(NULL, " %-16s: <%s> = \"%s\"\r\n", vp->name+1, vp->value.string, buf);
- else
- cwprintf(NULL, " %-16s: \"%s\"\r\n", vp->name+1, buf);
- }
- else
- {
- cwprintf(NULL, "Variable not known\r\n");
- return 1;
- }
- }
- return 0;
- }
-
- /* Call a subcommand based on the first token in an already-parsed line */
- int subcmd(struct cmds *cmdtable, int argc, char **argv)
- {
- int loop, rslt;
-
- /* Strip off first token and pass rest of line to subcommand */
- if (argc < 2 || argv[1][0] == '?' || strnicmp(argv[1], "help", strlen(argv[1])) == NULL)
- {
- if (argc < 1)
- {
- cwprintf(NULL, "SUBCMD - Don't know what to do?\r\n");
- }
- else
- {
- cwprintf(NULL, "\"%s\" - takes at least one argument\r\n",argv[0]);
- for (loop = 0; cmdtable[loop].name != NULLCHAR; loop++)
- {
- cwprintf(NULL, "%20s", cmdtable[loop].name);
- if (cmdtable[loop].argc_errmsg != NULLCHAR)
- cwprintf(NULL, " - %s\r\n", cmdtable[loop].argc_errmsg);
- else
- cwprintf(NULL, "\r\n");
- }
- }
- return -1;
- }
- argc--;
- argv++;
- for (loop = 0; cmdtable[loop].name != NULLCHAR; loop++)
- {
- if (strnicmp(argv[0], cmdtable[loop].name, strlen(argv[0])) == 0)
- {
- if (argc < cmdtable[loop].argcmin)
- {
- if (cmdtable[loop].argc_errmsg != NULLCHAR)
- cwprintf(NULL, "Usage: %s\r\n", cmdtable[loop].argc_errmsg);
- return -1;
- }
- else
- {
- rslt = (cmdtable[loop].func)(argc, argv); /* Shouldn't call (*func) should we? */
- if ((rslt < 0) && (cmdtable[loop].exec_errmsg != NULLCHAR))
- cwprintf(NULL, "%s\r\n", cmdtable[loop].exec_errmsg);
- return(rslt);
- }
- }
- }
- if (cmdtable[loop].argc_errmsg != NULLCHAR)
- cwprintf(NULL, "%s\r\n", cmdtable[loop].argc_errmsg);
-
- return -1;
- }
-
- extern Terminal *MWin;
-
- int cmdparse(struct cmds *cmdtable, register char *line, Terminal *Window)
- {
- char *argv[NARG];
- int argc, loop, rslt;
- char xcmd[1024];
- Terminal *temp;
-
- /* Remove cr/lf */
- rip(line);
-
- var_translate(global_vars, line, 0, xcmd, 1024);
- line = xcmd;
-
- for (argc = 0; argc < NARG; argc++)
- argv[argc] = NULLCHAR;
-
- temp = Window;
- if (Window == NULL)
- Window = MWin;
-
- if (command_tokenise(xcmd, NULL)>NARG)
- {
- /*
- * Too many arguments for this poxy CLI to deal with...
- */
- cwprintf(Window, "Too many tokens for CLI\r\n");
- return 1;
- }
- else
- {
- argc = command_tokenise(xcmd, argv);
- if (argc==0)
- return 0;
- }
-
- /* Look up command in table; prefix matches are OK */
- for (loop = 0; cmdtable[loop].name != NULLCHAR; loop++)
- {
- if (strncmp(argv[0], cmdtable[loop].name, strlen(argv[0])) == 0)
- break;
- }
- if (cmdtable[loop].name == NULLCHAR)
- {
- if (cmdtable[loop].argc_errmsg != NULLCHAR)
- {
- cwprintf(Window, "%s\r\n", cmdtable[loop].argc_errmsg);
- }
- return -1;
- }
- else
- {
- if (argc < cmdtable[loop].argcmin)
- {
- /* Insufficient arguments */
- if (cmdtable[loop].argc_errmsg != NULLCHAR)
- cwprintf(Window, "Usage: %s\r\n", cmdtable[loop].argc_errmsg);
- return(-1);
- }
- else
- {
- rslt = (cmdtable[loop].func)(argc, argv); /* Shouldn't call (*func) should we? */
- if ((rslt < 0) && (cmdtable[loop].exec_errmsg != NULLCHAR))
- {
- cwprintf(Window, "%s\r\n", cmdtable[loop].exec_errmsg);
- }
- return(rslt);
- }
- }
- }
-
-
- static char *skipspace(char *p)
- {
- while (isspace(*p))
- p++;
- return p;
- }
-
- /*
- * Escape sequence stripper to get rid of sequences
- * added to keep command interpreter happy
- *
- * Stripping done in place
- *
- * Returns length of resulting string.
- */
- static int unescape(char *s)
- {
- int i, j;
-
- for (i=0, j=0; s[i]!='\0'; i++)
- {
- if (s[i] == '\\')
- {
- i++;
- switch (s[i])
- {
- case '\\':
- s[j++] = '\\';
- break;
- case '\"':
- s[j++] = '\"';
- break;
- case '{':
- s[j++] = '{';
- break;
- case '}':
- s[j++] = '}';
- break;
- default:
- s[j++] = s[--i];
- break;
- }
- }
- else
- s[j++] = s[i];
- }
- s[j] = '\0';
-
- return j;
- }
-
- /* Command args extraction function
- * can be used in two ways:
- * 1. Entered with argv==NULL to count the args only
- * for eg to determin size of array needed for
- * arg pointers.
- * 2. Entered with argv pointing to an array of char*
- * with sufficient entries for number of args present
- * cmd is the command line being processed.
- *
- * Returns number of args present, ignoring tail comments
- * or <0 if a parse error occurs (eg missing quote)
- *
- * No escape sequence processing is done, other than to not count
- * '\"' as a '"', as may need to be handled differently according to
- * usage
- */
- static int command_tokenise(char *line, char *argv[])
- {
- int n = 0;
- char *p = line;
-
- while (*p!='\0')
- {
- p = skipspace(p);
-
- /* Non escaped quote? (ie start of token) */
- if (*p=='\"')
- {
- ++p;
-
- if (argv!=NULL)
- argv[n] = p;
-
- /* scan forward for another non escaped quote */
- while ( !(*p=='\"' && *(p-1)!='\\') && *p!='\0')
- ++p;
-
- /* Test for missing closing quote,
- and return a parse error if missing
- */
- if (*p=='\0')
- return -1;
-
- if (argv!=NULL) /* Terminate arg if extracting */
- *p = '\0';
-
- ++p;
-
- if (argv!=NULL)
- unescape(argv[n]);
- ++n;
- }
- else if (*p!='\0')
- {
- /* Added to allow comments on end of script command to be ignored
- Tail comments may be either C++ style "// ..."
- or the style commonly used in scripts "# ..." and "; ..."
- */
- if (!strncmp("#", p, 1) || !strncmp(";", p, 1) || !strncmp("//", p, 2))
- break;
-
- if (argv!=NULL)
- argv[n] = p;
-
- while (!isspace(*p) && *p!='\0')
- ++p;
-
- if (argv!=NULL && *p!='\0') /* Terminate arg if extracting */
- *p++ = '\0';
-
- if (argv!=NULL)
- unescape(argv[n]);
- ++n;
- }
- }
- return n; /* Number of args found */
- }
-
- /* Examine a strings for flags. The presence of flags
- * is indicated by the 1st char being a '-'.
- *
- * If it is a flags string, for each character in the flags
- * string, set a or clear a bit in the flag word according
- * the the position of the char in the flags list string.
- * Prefixing any flag with '!' or '~' clear the flag.
- *
- * opts is the current options flags
- * the updated options flags are returned.
- * flags is a pointer to a flag characters string.
- *
- */
-
- unsigned int command_flags(unsigned int opts, char *cmd, char *flags)
- {
- int i;
- char *n;
-
- if (*cmd=='-')
- {
- opts = 1<<31; /* Top bit set for flags present */
- while(++cmd!='\0')
- {
- i = (*cmd == '!' || *cmd=='~');
- n = strchr(flags, *cmd);
- if (n)
- {
- if (i)
- opts &= ~( 1 << (n-flags) );
- else
- opts |= ( 1 << (n-flags) );
- }
- }
- } else
- opts = 0;
- return opts;
- }
-