📄 cmd.c
字号:
/****************************************************************/
/* */
/* cmd.c */
/* */
/* command.com Top Level Driver */
/* */
/* August 9, 1991 */
/* */
/* Copyright (c) 1995, 1996 */
/* Pasquale J. Villani */
/* All Rights Reserved */
/* */
/* This file is part of DOS-C. */
/* */
/* DOS-C is free software; you can redistribute it and/or */
/* modify it under the terms of the GNU General Public License */
/* as published by the Free Software Foundation; either version */
/* 2, or (at your option) any later version. */
/* */
/* DOS-C is distributed in the hope that it will be useful, but */
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
/* the GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public */
/* License along with DOS-C; see the file COPYING. If not, */
/* write to the Free Software Foundation, 675 Mass Ave, */
/* Cambridge, MA 02139, USA. */
/****************************************************************/
/* $Logfile: C:/dos-c/src/command/cmd.c_v $ */
/* $Log: C:/dos-c/src/command/cmd.c_v $
*
* Rev 1.4 31 Jan 1998 8:12:30 patv
* Put preprocessor switch for version strings and changed log strings
*
* Rev 1.3 29 Aug 1996 13:07:04 patv
* Bug fixes for v0.91b
*
* Rev 1.2 19 Feb 1996 3:18:54 patv
* Added NLS, int2f and config.sys processing
*
* Rev 1.1 01 Sep 1995 18:04:34 patv
* First GPL release.
*
* Rev 1.0 02 Jul 1995 10:01:48 patv
* Initial revision.
*/
/* $EndLog$ */
#include <ctype.h>
#include "../../hdr/portab.h"
#define MAIN
#include "globals.h"
#include "proto.h"
#ifdef VERSION_STRINGS
static BYTE *RcsId = "$Header: C:/dos-c/src/command/cmd.c_v 1.4 31 Jan 1998 8:12:30 patv $";
#endif
#ifdef PROTO
struct table
{
BYTE *entry;
BOOL (*func)(COUNT, BYTE **);
};
#else
struct table
{
BYTE *entry;
BOOL (*func)();
};
#endif
#ifdef PROTO
struct table *lookup(struct table *, BYTE *);
VOID err_report(COUNT);
VOID put_prompt(BYTE *);
VOID Redirect(BYTE *, BYTE *, BYTE *, BOOL *);
VOID RestoreIO(COUNT, COUNT);
#else
struct table *lookup();
VOID err_report();
VOID put_prompt();
VOID Redirect();
VOID RestoreIO();
#endif
BOOL ExecCmd();
BOOL prompt();
BOOL cmd_path();
BOOL cmd_exit();
BOOL type();
BOOL cd();
BOOL copy();
BOOL del();
BOOL ren();
BOOL mkdir();
BOOL rmdir();
BOOL cmd_time();
BOOL cmd_date();
BOOL verify();
BOOL ver();
BOOL cmd_break();
BOOL batch();
BOOL label_bat();
BOOL pause_bat();
BOOL call_bat();
BOOL echo_bat();
BOOL echo_dot_bat();
BOOL for_bat();
BOOL if_bat();
BOOL rem_bat();
BOOL shift_bat();
BOOL goto_bat();
BOOL set_bat();
/* External cmmands */
struct table commands[] =
{
{"break", cmd_break},
{"copy", copy},
{"cd", cd},
{"chdir", cd},
{"date", cmd_date},
{"del", del},
{"dir", dir},
{"erase", del},
{"exit", cmd_exit},
{"mkdir", mkdir},
{"md", mkdir},
{"path", cmd_path},
{"prompt", prompt},
{"ren", ren},
{"rmdir", rmdir},
{"rd", rmdir},
{"time", cmd_time},
{"type", type},
{"verify", verify},
{"ver", ver},
{"if", if_bat},
{"label", label_bat},
{"pause", pause_bat},
{"call", call_bat},
{"echo", echo_bat},
{"echo.", echo_dot_bat},
{"echo+", echo_dot_bat},
{"echo\"", echo_dot_bat},
{"echo/", echo_dot_bat},
{"echo[", echo_dot_bat},
{"echo]", echo_dot_bat},
{"echo:", echo_dot_bat},
{"for", for_bat},
{"rem", rem_bat},
{"shift", shift_bat},
{"goto", goto_bat},
{"set", set_bat},
{"", ExecCmd}
};
static COUNT argc;
static BYTE *argv[NPARAMS];
static BOOL pflag, bootup = FALSE;
VOID main()
{
COUNT nread;
BOOL bool_FLAG = FALSE;
BOOL cflag;
BYTE FAR *cmd_tail;
BYTE *p_ptr;
extern UWORD _psp;
psp FAR *p;
COUNT driveno = -1;
BYTE pattern[MAX_CMDLINE] = "";
BYTE path[MAX_CMDLINE] = "", esize[MAX_CMDLINE] = "";
/* Initialize the interpreter */
p = MK_FP(_psp, 0);
switchchar = '/';
batch_FLAG = FALSE;
argv[0] = args[0];
argv[1] = (BYTE *)0;
args[0][0] = '\0';
*tail = '\0';
lpEnviron = (BYTE FAR *)MK_FP(p -> ps_environ, 0);
cmd_tail = MK_FP(_psp, 0x81);
fstrncpy((BYTE FAR *)tail, cmd_tail, 0x7f);
pflag = cflag = FALSE;
dosopt("$d$p*[e:pc]+", (BYTE FAR *)tail,
&driveno, path, pattern, esize, &pflag, &cflag);
/* Get the passed-in Environment size and make certain we */
/* allocate enough space */
EnvSize = EnvSizeUp();
if(EnvSize < ENV_DEFAULT)
EnvSize = ENV_DEFAULT;
if(*esize != '\0')
{
COUNT size = atoi(esize);
bool_FLAG = EnvAlloc(size);
EnvSize = size;
}
else
bool_FLAG = EnvAlloc(EnvSize);
if(!bool_FLAG)
error_message(OUT_ENV_SPACE);
/* Check what PROMPT is set in env to over ride default */
p_ptr = EnvLookup("PROMPT");
if(p_ptr != (BYTE *)0)
scopy(p_ptr, prompt_string);
else
scopy(dflt_pr_string, prompt_string);
/* Check what PATH is set in env to over ride default */
p_ptr = EnvLookup("PATH");
if(p_ptr != (BYTE *)0)
scopy(p_ptr, path);
else
scopy(dflt_path_string, path);
if(!cflag)
{
if(pflag)
{
/* Special MS-DOS compatability initialization, */
/* all command shells terminate onto */
/* themselves, but we always terminate at the */
/* root shell. If anyone complains, we'll */
/* change it. */
#ifndef DEBUG
p -> ps_parent = _psp;
#endif
/* Try to exec autoexec.bat */
bootup = TRUE;
*tail = '\0';
if(!batch(".\\autoexec.bat", tail))
{
*tail = '\0';
cmd_date(1, argv);
cmd_time(1, argv);
bootup = FALSE;
}
}
else
{
/* Announce our version */
printf(ANNOUNCE, copyright);
#ifdef SHWR
printf("**** Shareware version ****\nPlease register your copy.\n");
#else
printf("\n\n");
#endif
}
FOREVER
{
default_drive = DosGetDrive();
put_prompt(prompt_string);
if((nread = DosRead(STDIN, (BYTE FAR *)cmd_line, MAX_CMDLINE)) < 0)
continue;
do_command(nread);
}
}
else
{
BYTE FAR *p;
default_drive = DosGetDrive();
for(p = cmd_tail; *p != '\r'; p++)
{
if(*p == '/' && (*(p + 1) == 'c' || *(p + 1) == 'C'))
break;
}
p += 2;
fstrncpy((BYTE FAR *)cmd_line, p, 0x7f);
for(nread = 0; *p != '\r'; nread++, p++)
;
++nread;
do_command(nread);
}
}
VOID Redirect(cmd_line, Input, Output, AppendMode)
BYTE *cmd_line, *Input, *Output;
BOOL *AppendMode;
{
BYTE LocalBuffer[MAX_CMDLINE], *lp, *dp = cmd_line;
/* First - create an image, since we'll be copying back into */
/* the original buffer. */
strcpy(LocalBuffer, cmd_line);
/* Next, start looking for redirect symbols. */
lp = skipwh(LocalBuffer);
while(*lp != '\0')
{
switch(*lp)
{
case '<':
lp = scan(++lp, Input);
break;
case '>':
if(*(lp + 1) == '>')
{
++lp;
*AppendMode = TRUE;
}
lp = scan(++lp, Output);
break;
default:
*dp++ = *lp++;
break;
}
}
*dp = '\0';
}
VOID do_command(nread)
COUNT nread;
{
REG struct table *p;
REG BYTE *lp;
COUNT index = 0;
BYTE Input[MAX_CMDLINE], Output[MAX_CMDLINE];
BOOL AppendMode;
COUNT OldStdin = -1, OldStdout = -1, ErrorCode;
BOOL IORedirected = FALSE;
if(nread <= 0)
return;
cmd_line[nread] = '\0';
/* Pre-scan the command line and look for any re-directs */
*Input = *Output = '\0';
AppendMode = FALSE;
Redirect(cmd_line, Input, Output, &AppendMode);
IORedirected = (*Input != '\0' || *Output != '\0');
if(*Input != '\0')
{
COUNT Handle;
if(!DosDupHandle(STDIN, (COUNT FAR *)&OldStdin, (COUNT FAR *)&ErrorCode))
{
RestoreIO(OldStdin, -1);
error_message(INTERNAL_ERR);
return;
}
Handle = DosOpen((BYTE FAR *)Input, O_RDWR);
if((Handle < 0) || (!DosForceDupHandle(Handle, STDIN, (COUNT FAR *)&ErrorCode)))
{
RestoreIO(OldStdin, -1);
error_message(INTERNAL_ERR);
return;
}
DosClose(Handle);
}
if(*Output != '\0')
{
COUNT Handle;
if(!DosDupHandle(STDOUT, (COUNT FAR *)&OldStdout, (COUNT FAR *)&ErrorCode))
{
RestoreIO(-1, OldStdout);
error_message(INTERNAL_ERR);
return;
}
if(AppendMode)
{
if((Handle = DosOpen((BYTE FAR *)Output, O_RDWR)) < 0)
{
RestoreIO(-1, OldStdout);
error_message(INTERNAL_ERR);
return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -