📄 docmd.c
字号:
showusage(cptr);
hp = &cptr->helptxt[2];
while(*hp)
printf("%s\n",*hp++);
printf("\nRequired user level: %d\n",lvltbl[index]);
}
else if (verbose == 1) {
printf(" %-12s %d %s\n", cptr->name, lvltbl[index],cptr->helptxt[0]);
}
else {
printf("%-12s",cptr->name);
}
return(1);
}
/* Command list headers can be defined in config.h or just
* omitted...
*/
#ifndef APP_CMDLIST_HEADER
#define APP_CMDLIST_HEADER "\nApplication-Installed Command Set:"
#endif
#ifndef MON_CMDLIST_HEADER
#define MON_CMDLIST_HEADER "\nMicro-Monitor Command Set:"
#endif
/* Help():
* This command displays each commands help text.
* The help text is assumed to be formatted as an array of strings
* where...
* the first string is the command description;
* the second string is command usage;
* and all remaining strings up to the NULL are just printable text.
*/
char *HelpHelp[] = {
"Display command set",
"-[di] [commandname]",
#if INCLUDE_VERBOSEHELP
"Options:",
" -d list commands and descriptions",
" -i configuration info",
#endif
0,
};
int
Help(int argc,char *argv[])
{
struct monCommand *cptr, *acptr;
char *cp;
int j, i, foundit, opt, descriptions;
descriptions = 0;
while((opt=getopt(argc,argv,"di")) != -1) {
switch(opt) {
case 'd':
descriptions = 1;
break;
case 'i':
monHeader(0);
mstatshowcom();
return(CMD_SUCCESS);
default:
return(CMD_PARAM_ERROR);
}
}
cptr = cmdlist;
if (argc == optind) {
foundit = 1;
if (descriptions) {
if (appCmdlist) {
printf("%s\n",APP_CMDLIST_HEADER);
acptr = appCmdlist;
for(i=0;acptr->name;acptr++,i++)
showhelp(appCmdlist,i,1);
}
printf("%s\n",MON_CMDLIST_HEADER);
while(cptr->name) {
showhelp(cmdlist,cptr-cmdlist,1);
cptr++;
}
putchar('\n');
}
else {
i = 0;
if (appCmdlist) {
acptr = appCmdlist;
printf("%s\n",APP_CMDLIST_HEADER);
for(j=0;acptr->name;acptr++,j++) {
if (showhelp(appCmdlist,j,0)) {
if ((++i%6) == 0)
putchar('\n');
}
}
putchar('\n');
i = 0;
}
printf("%s\n",MON_CMDLIST_HEADER);
while(cptr->name) {
if (showhelp(cmdlist,cptr-cmdlist,0)) {
if ((++i%6) == 0)
putchar('\n');
}
cptr++;
}
putchar('\n');
}
}
else {
foundit = 0;
cp = argv[1];
if (appCmdlist) {
acptr = appCmdlist;
for(i=0;acptr->name;acptr++,i++) {
if (strcmp(acptr->name,cp) == 0) {
foundit = showhelp(appCmdlist,i,2);
break;
}
}
}
if (!foundit) {
if (*cp == '_')
cp++;
while(cptr->name) {
if (strcmp(cptr->name,cp) == 0) {
foundit = showhelp(cmdlist,cptr-cmdlist,2);
break;
}
cptr++;
}
}
}
if (!foundit) {
printf("\"%s\" not found\n",argv[1]);
return(CMD_FAILURE);
}
return(CMD_SUCCESS);
}
#if INCLUDE_SHELLVARS
/* getPathEntry():
* Copy the next path entry pointed to by 'path' into 'entry'.
*/
char *
getPathEntry(char *path, char *entry, int entrysize)
{
int i;
char *base = entry;
entrysize--;
while(*path == ':')
path++;
for(i=0;(i < entrysize) && (*path != ':') && (*path != 0); i++)
*entry++ = *path++;
if (entry == base)
return(0);
*entry++ = 0;
return(path);
}
/* findPath():
* If PATH is set, then step through each colon-delimited entry looking
* for a valid executable.
*/
int
findPath(char *name,char *fpath,int pathsize)
{
int elen;
char *path;
char entry[TFSNAMESIZE+1];
if (tfsstat(name)) {
strcpy(fpath,name);
return(1);
}
if ((path = getenv("PATH")) == 0)
return(0);
while((path = getPathEntry(path,entry,sizeof(entry)))) {
elen = strlen(entry);
if ((elen + strlen(name)) < (pathsize-1)) {
if (entry[elen-1] != '/')
strcat(entry,"/");
strcat(entry,name);
if (tfsstat(entry)) {
strcpy(fpath,entry);
return(1);
}
}
}
return(0);
}
#else
int
findPath(char *name, char *fpath, int pathsize)
{
if (tfsstat(name)) {
strcpy(fpath,name);
return(1);
}
return(0);
}
#endif
/* 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.
* If verbose is non-zero, print the list of arguments after tokenization.
*/
int
docommand(char *cmdline,int verbose)
{
int ret, argc, i, err;
struct monCommand *cmdptr, *cmdptrbase;
char *ps, *argv[ARGCNT], cmdcpy[CMDLINESIZE], *ulvlptr;
char path[TFSNAMESIZE+1];
/* If the very first character is a poundsign, then just ignore
* the line and return success...
*/
if (cmdline[0] == '#')
return(CMD_SUCCESS);
/* 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);
}
/* Redirection check is done prior to shell variable expansion, so
* the code within RedirectionCheck() itself must deal with the '$'
* after the redirection arrow...
*/
if (RedirectionCheck(cmdcpy) == -1)
return(CMD_LINE_ERROR);
/* 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);
}
/* 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();
/* At this point all CLI processing has been done. We've tokenized
* and converted shell variables where necessary. Now its time to
* scan through the command table(s) looking for a match between
* the first token of the incoming command string and a command name
* in the table(s).
* The monitor allows the application to insert a set of commands
* that will be in addition to the commands that are in the monitor's
* command list, this is done with the API function mon_addcommand()
* which ultimately calls the function addcommand() in this file.
* That function is handed a pointer to two tables: a command structure
* table and a user level table.
* If the application-supplied command table is present, then we scan
* through it first. This is done so that when we scan the monitor-owned
* command table, we can strip off a leading underscore to support the
* ability to have a command in each table (applcation-supplied and
* monitor built-ins) with the same name.
*/
if (appCmdlist) {
cmdptrbase = appCmdlist;
ulvlptr = appcmdUlvl;
}
else {
cmdptrbase = cmdlist;
ulvlptr = cmdUlvl;
}
while(1) {
/* If we are processing the monitor-owned command table, then
* we want to eliminate the leading underscore of argv[0] (if
* there is one).
*/
if ((cmdptrbase == cmdlist) && (argv[0][0] == '_'))
strcpy(argv[0],&argv[0][1]);
for(cmdptr = cmdptrbase; cmdptr->name; cmdptr++) {
if (strcmp(argv[0],cmdptr->name) == 0)
break;
}
if (cmdptr->name) {
/* Make sure we are at or above the user level required
* to run this command...
*/
if (ulvlptr[cmdptr-cmdptrbase] > getUsrLvl()) {
printf("Command requires user level %d\n",
ulvlptr[cmdptr-cmdptrbase]);
return(CMD_ULVL_DENIED);
}
/* Do not run this command if monrc is active and the
* NOMONRC flag bit is set for this command...
*/
if ((cmdptr->flags & CMDFLAG_NOMONRC) && tfsRunningMonrc()) {
printf("%s: illegal within monrc.\n",cmdptr->name);
return(CMD_MONRC_DENIED);
}
/* Execute the command's function...
*/
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 (cmdptrbase == cmdlist)
break;
cmdptrbase = cmdlist;
ulvlptr = cmdUlvl;
}
/* 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 (findPath(argv[0],path,sizeof(path))) {
argv[0] = path;
err = tfsrun(argv,0);
if (err == TFS_OKAY)
ret = CMD_SUCCESS;
else
printf("%s: %s\n",path,(char *)tfsctrl(TFS_ERRMSG,err,0));
}
else {
printf("Command not found: %s\n",argv[0]);
printf("%s\r\n",argv[0]);
}
RedirectionCmdDone();
return(ret);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -