📄 cmd.c
字号:
}
DosSeek(Handle, 2, 0l);
}
else
Handle = DosCreat((BYTE FAR *)Output, D_NORMAL | D_ARCHIVE);
if((Handle < 0) || (!DosForceDupHandle(Handle, STDOUT, (COUNT FAR *)&ErrorCode)))
{
RestoreIO(-1, OldStdout);
error_message(INTERNAL_ERR);
return;
}
DosClose(Handle);
}
for(argc = 0; argc < 16; argc++)
{
argv[argc] = (BYTE *)0;
args[argc][0] = '\0';
}
lp = scanspl(cmd_line, args[0], '/');
if(args[0][0] == '@')
{
at_FLAG = TRUE;
index++;
}
else
at_FLAG = FALSE;
/* If preceeded by a @, swallow it, it was taken care of */
/* elsewhere. Also, change case so that our command verb is */
/* case sensitive. */
while(args[0][index] != '\0')
{
if(at_FLAG)
args[0][index-1] = tolower(args[0][index]);
else
args[0][index] = tolower(args[0][index]);
index++;
}
if(at_FLAG)
args[0][index-1] = '\0';
argv[0] = args[0];
/* this kludge is for an MS-DOS wart emulation */
tail = skipwh(lp);
for(argc = 1; argc < NPARAMS; argc++)
{
lp = scan(lp, args[argc]);
if(*args[argc] == '\0')
break;
else
argv[argc] = args[argc];
}
if(*argv[0] != '\0')
{
/* Look for just a drive change command, and execute */
/* it if found. */
if(argv[0][1] == ':' && argv[0][2] == NULL)
{
BYTE c = argv[0][0];
if(c >= 'a' && c <= 'z')
c = c - 'a' + 'A';
if(c >= 'A' && c <= 'Z')
DosSetDrive(c - 'A');
}
/* It may be a help command request. */
else if((argv[1][0] == switchchar) &&
(argv[1][1] == '?'))
{
strcpy(tail, " ");
strcat(tail, argv[0]);
strcat(tail, "\r\n");
argc = 2;
argv[1] = argv[0];
argv[0] = "help";
argv[2] = 0;
ExecCmd(argc, argv);
if(IORedirected)
RestoreIO(OldStdin, OldStdout);
}
/* do a normal command execution */
else
{
p = lookup(commands, argv[0]);
(*(p -> func))(argc, argv);
if(IORedirected)
RestoreIO(OldStdin, OldStdout);
}
}
}
BOOL prompt(argc, argv)
WORD argc;
BYTE *argv[];
{
BYTE *p;
BYTE *cmd = "PROMPT";
if(argc == 1)
{
p = EnvLookup(cmd);
if(p != (BYTE *)0)
scopy(p, prompt_string);
else
{
scopy(dflt_pr_string, prompt_string);
EnvClearVar(cmd);
}
}
else
{
/* Trim trailing newline */
for(p = tail; (*p != '\r') && (*p != '\n'); p++)
;
*p = '\0';
/* should be scopy(argv[1], &pr_string[1]); but to */
/* emulate an MS-DOS wart, is */
scopy(tail, prompt_string);
/* Now set the environment variable for all children to */
/* see. */
EnvSetVar(cmd, prompt_string);
}
return TRUE;
}
struct table *lookup(p, token)
struct table *p;
BYTE *token;
{
while(*(p -> entry) != '\0')
{
if(strcmp(p -> entry, token) == 0)
break;
else
++p;
}
return p;
}
VOID RestoreIO(DupStdin, DupStdout)
{
COUNT ErrorCode;
if(DupStdin >= 0)
{
if(!DosForceDupHandle(DupStdin, STDIN, (COUNT FAR *)&ErrorCode))
error_message(INTERNAL_ERR);
DosClose(DupStdin);
}
if(DupStdout >= 0)
{
if(!DosForceDupHandle(DupStdout, STDOUT, (COUNT FAR *)&ErrorCode))
error_message(INTERNAL_ERR);
DosClose(DupStdout);
}
}
BOOL ExecCmd(argc, argv)
COUNT argc;
BYTE *argv[];
{
exec_blk exb;
COUNT err;
BYTE tmppath[64];
COUNT idx;
BOOL ext = FALSE;
BYTE *extp;
COUNT len;
BYTE *lp;
CommandTail CmdTail;
fcb fcb1, fcb2;
static BYTE *extns[2] =
{
".com",
".exe"
};
static BYTE *batfile = ".bat";
BYTE PathString[MAX_CMDLINE];
BYTE Path[MAX_CMDLINE], *pPath;
/* Build the path string and create the full string that */
/* includes ".\" so that the current directory is searched */
/* first. Note that Path is initialized outside the loop. */
strcpy(Path, ".\\");
strcpy(PathString, EnvLookup("PATH"));
pPath = PathString;
do
{
/* Build a path to the command. */
if(*pPath == ';')
++pPath;
strcpy(tmppath, Path);
if(*tmppath != '\0' && !((tmppath[strlen(tmppath) - 1] != '\\') == 0))
strcat(tmppath, "\\");
strcat(tmppath, argv[0]);
/* batch processing */
/* search for an extension in the specification */
for(idx = len = strlen(argv[0]) ; idx > 0 && idx > (len - FEXT_SIZE - 2); --idx)
{
if(argv[0][idx] == '.')
{
ext = TRUE;
extp = &argv[0][idx];
break;
}
}
/* If no extension was found, the entire path was */
/* specified and we do not append an extension. */
if(!ext)
{
strcat(tmppath, batfile);
extp = batfile;
}
/* if it ends with a '.bat' (either user supplied or */
/* previously added), try to run as a batch. */
if((strcmp(extp, batfile) == 0) && batch(tmppath, tail))
{
if(pflag && bootup)
bootup = FALSE;
return TRUE;
}
/* tail comes in as a string with trailing newline. */
/* Convert it to a return only and put it into CmdTail */
/* format */
CmdTail.ctCount = (argc > 1) ? strlen(tail) : 1;
strcpy(CmdTail.ctBuffer, " ");
strcpy(&CmdTail.ctBuffer[1], (argc > 1) ? tail : "");
CmdTail.ctBuffer[CmdTail.ctCount] = '\0';
if(CmdTail.ctCount < LINESIZE)
CmdTail.ctBuffer[CmdTail.ctCount] = '\0';
rtn_errlvl = 0;
exb.exec.env_seg = FP_SEG(lpEnviron);
exb.exec.cmd_line = (CommandTail FAR *)&CmdTail;
#if 0
if(argc > 1)
{
DosParseFilename((BYTE FAR *)argv[1], (fcb FAR *)&fcb1, 0);
exb.exec.fcb_1 = (fcb FAR *)&fcb1;
}
else
exb.exec.fcb_1 = (fcb FAR *)0;
if(argc > 2)
{
exb.exec.fcb_2 = (fcb FAR *)&fcb2;
DosParseFilename((BYTE FAR *)argv[2], (fcb FAR *)&fcb2, 0);
}
else
exb.exec.fcb_2 = (fcb FAR *)0;
#else
exb.exec.fcb_1 = (fcb FAR *)0;
exb.exec.fcb_2 = (fcb FAR *)0;
#endif
for(idx = 0; idx < 2; idx++)
{
strcpy(tmppath, Path);
if(*tmppath != '\0' && !((tmppath[strlen(tmppath) - 1] != '\\') == 0))
strcat(tmppath, "\\");
strcat(tmppath, argv[0]);
if(!ext)
{
strcat(tmppath, extns[idx]);
extp = extns[idx];
}
if(!(strcmp(extp, extns[idx]) == 0))
continue;
if((rtn_errlvl = err = DosExec((BYTE FAR *)tmppath, (exec_blk FAR *)&exb)) != SUCCESS)
{
switch(err)
{
case DE_FILENOTFND:
continue;
case DE_INVLDFUNC:
rtn_errlvl = INV_FUNCTION_PARAM;
goto errmsg;
case DE_PATHNOTFND:
rtn_errlvl = PATH_NOT_FOUND;
goto errmsg;
case DE_TOOMANY:
rtn_errlvl = TOO_FILES_OPEN;
goto errmsg;
case DE_ACCESS:
rtn_errlvl = ACCESS_DENIED;
goto errmsg;
case DE_NOMEM:
rtn_errlvl = INSUFF_MEM;
goto errmsg;
default:
rtn_errlvl = EXEC_ERR;
errmsg:
error_message(rtn_errlvl);
return FALSE;
}
}
else
{
rtn_errlvl = DosRtnValue() & 0xff;
return TRUE;
}
}
if(err < 0 || idx == 2)
{
if(!(err == DE_FILENOTFND || idx == 2))
{
error_message(EXEC_FAIL);
return FALSE;
}
continue;
}
}
while(*Path = '\0', pPath = scanspl(pPath, Path, ';'), *Path != '\0');
error_message(BAD_CMD_FILE_NAME);
return FALSE;
}
BOOL cmd_exit(argc, argv)
COUNT argc;
BYTE FAR *argv[];
{
#ifndef DEBUG
/* Don't exit from a permanent shell */
if(pflag)
return TRUE;
#endif
/* If no values passed, return errorvalue = 0 */
if(argc == 1)
DosExit(0);
/* otherwise return what the user asked for */
else
{
COUNT ret_val;
static BYTE nums[] = "0123456789";
BYTE FAR *p;
for(ret_val = 0, p = argv[1]; isdigit(*p); p++)
{
COUNT j;
for(j = 0; j < 10; j++)
if(nums[j] == *p)
break;
ret_val += j;
}
DosExit(ret_val);
}
return TRUE;
}
VOID sto(c)
COUNT c;
{
BYTE ch[1];
*ch = c;
DosWrite(STDOUT, (BYTE FAR *)ch, 1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -