📄 if.c
字号:
#if INCLUDE_VERBOSEHELP
"Note: idx=1 retrieves item1",
#endif
0,
};
int
Item(int argc, char *argv[])
{
int idx;
char *varname;
if (argc < 3)
return(CMD_PARAM_ERROR);
idx = atoi(argv[1]);
varname = argv[2];
if ((idx < 1) || (idx > (argc-3))) {
setenv(varname,0);
return(CMD_SUCCESS);
}
idx += 2;
setenv(varname,argv[idx]);
return(CMD_SUCCESS);
}
/* Read():
* Simple interactive shell variable entry.
* Syntax:
* read [options] [var1] [var2] [...]
* Options:
* -twww timeout after 'www' milliseconds (approximate) of
* waiting for input.
*
*/
char *ReadHelp[] = {
"Interactive shellvar entry",
#if INCLUDE_VERBOSEHELP
"-[ft:] [var1] [var2] ... ",
" -f flush console input",
" -t ### msec timeout per char",
" -T ### msec timeout cumulative",
"Notes:",
" This command waits for console input terminated by ENTER.",
" Input tokens are whitespace delimited.",
"Examples:",
" * read name # wait forever",
" If user responds with ENTER, shell var 'name' is cleared;",
" else it is loaded with the first input token.",
" * read -t2000 name # timeout after 2 seconds",
" If timeout, shell var 'name' is untouched; else if timeout",
" doesn't occur, but user only types ENTER 'var' is cleared;",
" else 'var' will contain token.",
#endif
0,
};
int
Read(int argc,char *argv[])
{
int i, reached_eol, opt, waitfor;
char buf[64], *space, *bp;
waitfor = 0;
while((opt=getopt(argc,argv,"ft:T:")) != -1) {
switch(opt) {
case 'f':
flush_console_in();
return(CMD_SUCCESS);
case 't':
waitfor = strtol(optarg,(char **)0,0);
break;
case 'T':
waitfor = strtol(optarg,(char **)0,0);
waitfor = -waitfor;
break;
default:
return(CMD_PARAM_ERROR);
}
}
#if INCLUDE_ETHERNET
/* Since this command blocks waiting for user input on the console,
* check to see if we are running under the context of MONCMD, and,
* if yes, return CMD_FAILURE to avoid a lockup...
*/
if (IPMonCmdActive) {
printf("Invalid under moncmd context.\n");
return(CMD_FAILURE);
}
#endif
/* If -t, then restart the timeout for each character.
* If -T, then the timeout accumulates over all characters.
* If a timeout does occur, then do nothing to the shell variables
* that may be specified as arguments. This allows the script
* writer to distinguish between a timeout, and an empty line...
* Timeout has no affect, empty line will NULL out the variable.
*/
if (getline_t(buf,sizeof(buf)-1,waitfor) == -1) {
return(CMD_SUCCESS);
}
/* If there were no args after the option, then there is no need to
* consider populating a shell variable, so just return here.
*/
if (argc == optind) {
return(CMD_SUCCESS);
}
bp = buf;
reached_eol = 0;
for(i=optind;i<argc;i++) {
space=strpbrk(bp," \t");
if (space) {
*space = 0;
setenv(argv[i],bp);
bp = space+1;
}
else {
if ((reached_eol) || (*bp == 0)) {
setenv(argv[i],0);
}
else {
setenv(argv[i],bp);
reached_eol = 1;
}
}
}
return(CMD_SUCCESS);
}
int
currentScriptfd(void)
{
return(CurrentScriptfdTbl[ScriptIsRunning]);
}
/* gototag():
* Used with tfsscript to allow a command to adjust the pointer into the
* script that is currently being executed. It simply populates the
* "ScriptGotoTag" pointer with the tag that should be branched to next.
*/
void
gototag(char *tag)
{
if (InAScript()) {
if (ScriptGotoTag)
free(ScriptGotoTag);
ScriptGotoTag = malloc(strlen(tag)+8);
sprintf(ScriptGotoTag,"# %s",tag);
}
}
/* gosubtag():
* Similar in basic use to gototag(), except that we keep a copy of the
* current position in the active script file so that it can be returned
* to later.
*/
void
gosubtag(char *tag)
{
if (InAScript()) {
if (ReturnToDepth >= MAXGOSUBDEPTH) {
printf("Max return-to depth reached\n");
return;
}
ReturnToTellTbl[ReturnToDepth++] = tfstell(currentScriptfd());
gototag(tag);
}
}
void
gosubret(char *ignored)
{
int offset, err;
if (InAScript()) {
err = 0;
if (ReturnToDepth <= 0) {
printf("Nothing to return to\n");
err = 1;
}
else {
ReturnToDepth--;
offset = tfsseek(currentScriptfd(),
ReturnToTellTbl[ReturnToDepth],TFS_BEGIN);
if (offset <= 0) {
err = 1;
printf("return error: %s\n",tfserrmsg(offset));
}
}
if (err)
printf("Possible gosub/return imbalance.\n");
}
}
/* tfsscript():
* Treat the file as a list of commands that should be executed
* as monitor commands. Step through each line and execute it.
* The tfsDocommand() function pointer is used so that the application
* can assign a different command interpreter to the script capbilities
* of the monitor. To really take advantage of this, the command interpreter
* that is reassigned, should allow monitor commands to run if the command
* does not exist in the application's command list.
*
* Scripts can call other scripts that call other scripts (etc...) and
* that works fine because tfsscript() will just use more stack space but
* it eventually returns through the same function call tree. A script can
* also call a COFF, ELF or AOUT file and expect it to return as long as
* the executable returns through the same point into which it was started
* (the entrypoint). If the executable uses mon_appexit() to terminate,
* then the calling script will not regain control.
*/
int
tfsscript(TFILE *fp,int verbose)
{
char lcpy[CMDLINESIZE], *sv;
int tfd, lnsize, lno, verbosity, ignoreerror, cmdstat;
tfd = tfsopen(fp->name,TFS_RDONLY,0);
if (tfd < 0)
return(tfd);
lno = 0;
/* If ScriptIsRunning is zero, then we know that this is the top-level
* script, so we can initialize state here...
*/
if (ScriptIsRunning == 0)
ReturnToDepth = 0;
CurrentScriptfdTbl[++ScriptIsRunning] = tfd;
while(1) {
lno++;
lnsize = tfsgetline(tfd,lcpy,CMDLINESIZE);
if (lnsize == 0) /* end of file? */
break;
if (lnsize < 0) {
printf("tfsscript(): %s\n",tfserrmsg(lnsize));
break;
}
if ((lcpy[0] == '\r') || (lcpy[0] == '\n')) /* empty line? */
continue;
lcpy[lnsize-1] = 0; /* Remove the newline */
/* Just in case the goto tag was set outside a script, */
/* clear it now. */
if (ScriptGotoTag) {
free(ScriptGotoTag);
ScriptGotoTag = (char *)0;
}
ScriptExitFlag = 0;
/* Execute the command line.
* If the shell variable "SCRIPTVERBOSE" is set, then enable
* verbosity for this command; else use what was passed in
* the parameter list of the function. Note that the variable
* is tested for each command so that verbosity can be enabled
* or disabled within a script.
* If the command returns a status that indicates that there was
* some parameter error, then exit the script.
*/
sv = getenv("SCRIPTVERBOSE");
if (sv)
verbosity = atoi(sv);
else
verbosity = verbose;
if ((lcpy[0] == '-') || (getenv("SCRIPT_IGNORE_ERROR")))
ignoreerror = 1;
else
ignoreerror = 0;
if (verbosity)
printf("[%02d]: %s\n",lno,lcpy);
cmdstat = tfsDocommand(lcpy[0] == '-' ? lcpy+1 : lcpy, 0);
if (cmdstat != CMD_SUCCESS) {
setenv("CMDSTAT","FAIL");
if (ignoreerror == 0) {
printf("Terminating script '%s' at line %d\n",
TFS_NAME(fp),lno);
ScriptExitFlag = 1;
break;
}
}
else {
setenv("CMDSTAT","PASS");
}
/* Check for exit flag. If set, then in addition to terminating the
* script, clear the return depth here so that the "missing return"
* warning is not printed. This is done because there is likely
* to be a subroutine with an exit in it and this should not
* cause a warning.
*/
if (ScriptExitFlag) {
ReturnToDepth = 0;
break;
}
/* If ScriptGotoTag is set, then attempt to reposition the line
* pointer to the line that contains the tag.
*/
if (ScriptGotoTag) {
int tlen;
tlen = strlen(ScriptGotoTag);
lno = 0;
tfsseek(tfd,0,TFS_BEGIN);
while(1) {
lnsize = tfsgetline(tfd,lcpy,CMDLINESIZE);
if (lnsize == 0) {
printf("Tag '%s' not found\n",ScriptGotoTag+2);
free(ScriptGotoTag);
ScriptGotoTag = (char *)0;
tfsclose(tfd,0);
return(TFS_OKAY);
}
lno++;
if (!strncmp(lcpy,ScriptGotoTag,tlen)) {
free(ScriptGotoTag);
ScriptGotoTag = (char *)0;
break;
}
}
}
/* After each line, poll ethernet interface. */
pollethernet();
}
tfsclose(tfd,0);
if (ScriptExitFlag & REMOVE_SCRIPT)
tfsunlink(fp->name);
if (ScriptIsRunning > 0) {
ScriptIsRunning--;
if ((ScriptIsRunning == 0) && (ReturnToDepth != 0)) {
printf("Error: script is done, but return-to-depth != 0\n");
printf("(possible gosub/return imbalance)\n");
}
}
else {
printf("Script run-depth error\n");
}
/* Upon completion of a script, clear the ScriptExitFlag variable so
* that it is not accidentally applied to another script that may have
* called this script.
*/
ScriptExitFlag = 0;
return(TFS_OKAY);
}
#else /* INCLUDE_TFSSCRIPT */
int
tfsscript(TFILE *fp,int verbose)
{
return(TFSERR_NOTAVAILABLE);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -