📄 com.c
字号:
BYTE sppath[MAX_PATHLEN]; /* Buffer for the optional */
/* load path. */
BYTE fname[8+1+3+1+8+1]; /* Buffer for the filename */
/* optional extension and */
/* password */
BYTE *path; /* Environment Load path */
BYTE *ftype; /* Optional file type */
BYTE *pwd; /* Optional Password */
BYTE *envpath; /* current PATH= in env */
WORD i, ret;
#if !STACK
BYTE pathbuf[MAX_ENVLEN]; /* temporary path buffer */
#endif
strip_path(loadpath, sppath); /* isolate the optional path*/
ftype = loadpath+strlen(sppath); /* get the Filename Address */
if(strlen(ftype) < sizeof(fname)) /* If the filename is not */
strcpy(fname, ftype); /* too long then copy to an */
else /* internal buffer otherwise*/
longjmp(break_env, IA_FILENAME); /* break with FILENAME error*/
if((ftype = strchr(fname, '.')) != 0) { /* then extract the optional*/
*ftype++ = '\0'; /* file type from the name */
pwd = ftype;
}
else { /* If no type has been */
ftype = NULLPTR; /* specified then make it */
pwd = fname; /* file type a NULL pointer */
}
if ((ret = ms_x_open (fname, 0)) > 0) { /* don't exec a device in */
i = isdev (ret); /* any shape or form */
ms_x_close (ret);
if (i)
return (ED_FILE);
}
#if defined(PASSWORD)
if((pwd = strchr(pwd, *pwdchar)) != 0) /* Finally extract the */
*pwd++ = '\0'; /* optional password if none*/
else /* exists then default to a */
pwd = NULLPTR; /* NULL pointer. */
#endif
if(ftype) { /* If a file type has been */
for(i=0; ftypes[i]; i++) /* specified then check that*/
if(!strcmp(ftype, ftypes[i])) /* is legal and return an */
break; /* error if not. */
if(!ftypes[i]) /* If an illegal filetype */
return ED_FILE; /* has been given then */
} /* return FAILURE */
*loadtype = i; /* Save the Load File Type */
/*
* Check if a path is currently defined if YES then get
* a copy of the path and save locally on the heap. Protecting
* it against being overwritten.
*/
if(!env_scan(msg_patheq, heap())) {
envpath = heap();
while (*envpath) { /* process path in env */
if(dbcs_lead(*envpath)) /* so delimiters are the */
envpath++; /* pathchar we expect */
else
if((*envpath == '/') || (*envpath == '\\'))
*envpath = *pathchar;
envpath++;
}
#if STACK
envpath = stack(strlen(heap()) + 1);
#else
envpath = &pathbuf[0];
#endif
strcpy(envpath, heap());
}
else
envpath = "";
/*
* First attempt to load the file from the default/specified
* path and then if no path was specified attempt to load the
* file from all the entries in the search path defined in the
* environment.
*/
if(*sppath)
path = sppath;
else
path = "";
do {
i = checkfile(loadpath, loadtype, path, fname, ftype, pwd);
switch (i)
{
case SUCCESS:
strupr(loadpath);
return SUCCESS;
case ED_FAIL:
case ED_DRIVE: /* if bad drive in search */
if ((!*sppath) && (*path)) /* path, print msg & carry on*/
{
eprintf(MSG_PATHDRV);
i = ED_FILE;
break;
}
default:
break; /* get next search path */
}
path = envpath; /* Set PATH to the next */
if((s=strchr(envpath, ';')) != 0) { /* element in the search path*/
while (*s == ';') { /* Skip over extra semicolons*/
*s = 0;
s++;
}
envpath = s;
}
else
envpath = ""; /* path exhausted, -> null */
/* If you type FILENAME.EXE, it will search the current drive then */
/* the path. If you type C:\DIR\FILENAME.EXE, it will search */
/* C:\DIR. Now, if you type C:FILENAME.EXE, it will search the */
/* current directory on C:, then path. This is done by resetting */
/* sppath after the first run through, if it is just D: */
if((strlen(sppath) == 2) && (sppath[1] == ':'))
sppath[0] = '\0';
} while(!*sppath && *path);
return i;
}
/*
* CHECKFILE generates the full path of the load file and
* attempts to open the file. If the file is located and
* can successfully be opened return SUCCESS with the full
* path in LOADPATH and the LOADTYPE initialised.
*
* If no file extension has been specified then use the standard
* search order.
*
* ATTR_SEARCH specifies the attributes used to locate the file
* to be loaded.
*/
#define ATTR_SEARCH ATTR_STD + ATTR_HID
MLOCAL WORD checkfile(loadpath, loadtype, path, fname, ftype, pwd)
BYTE *loadpath;
UWORD *loadtype;
BYTE *path, *fname, *ftype, *pwd;
{
UWORD type;
WORD ret;
DTA search;
BYTE curpath[MAX_PATHLEN+1];
if((path = d_check(path)) == NULL) /* Remove the drive specifier*/
return ED_DRIVE; /* and return on Error. */
/* get path starting from root. n.b. don't use ms_x_expand (func 60h) */
/* as it upsets Novell */
if (ddrive != -1)
{
sprintf(loadpath, "%c:%c", ddrive + 'A', *pathchar);
if((*path == '\\') || (*path == '/')) /* If path is absolute then */
strcpy(loadpath+2, path); /* just append to drive */
else { /* Otherwise append the */
ms_x_curdir(ddrive+1, loadpath+3); /* path to the drive and */
if(*fptr(loadpath)) /* current subdirectory. */
append_slash(loadpath);
strcat(loadpath, path);
}
}
else
ms_x_expand(loadpath,path);
if(*fptr(loadpath))
append_slash(loadpath);
strcat(loadpath, fname); /* Add the FileName */
strcat(loadpath, ".");
path = loadpath + strlen(loadpath); /* Save the Extension Offset */
#if defined(PCDOS)
/*
* If running under PCDOS the check if any extension has been specified
* if not then search first for filename.* and return if no match occurs
* This will be quicker than opening each file in turn.
*/
if(!ftype) {
strcat(path, "*");
if((ret = ms_x_first(loadpath, ATTR_SEARCH, &search)) < 0) {
if( ret == ED_FILE || /* Abort if an error occurs */
ret == ED_ROOM || /* but ignore File not Found */
ret == ED_PATH) /* and invalid path errors */
return ED_FILE;
else
return e_check(ret);
}
}
#endif
if (ftype == 0)
type = COM_FILETYPE; /* Initialize the Type Index */
else /* correctly depending on the */
type = *loadtype; /* initial file type. */
do {
strcpy(path, ftypes[type]); /* Add the first file type */
#if defined(PASSWORD)
if(pwd) { /* followed by the optional */
strcat(path, pwdchar); /* password and attempt to */
strcat(path, pwd); /* open the file. */
}
#endif
if((ret = ms_x_first(loadpath, ATTR_SEARCH, &search)) < 0) {
if(ret == ED_PATH) /* Stop scanning this */
return ED_FILE; /* element of the path if */
/* it is invalid. */
#if 0
if(ret != ED_FILE && ret != ED_ROOM)
return ret;
#endif
}
else {
*loadtype = type; /* Set the correct loadtype */
return SUCCESS; /* and return SUCCESS */
}
if (++type > BAT_FILETYPE)
#if defined(DOSPLUS) || defined(NETWARE)
type = COM_FILETYPE;
#else
type = CMD_FILETYPE;
#endif
} while(!ftype && (type != COM_FILETYPE));
return ED_FILE;
}
#endif
MLOCAL BOOLEAN doexec(argv0, loadpath, loadtype, tail)
BYTE *argv0; /* Invoking Command */
BYTE *loadpath; /* Fully expanded filename */
UWORD loadtype; /* File Type .BAT, .EXE etc. */
BYTE *tail; /* Command line options */
{
WORD ret;
WORD i;
BYTE *s;
#if !STACK
BYTE tailbuf[128];
#endif
#if 0
printf("DOEXEC Load File \"%s\" Command Line \"%s\"\n",
loadpath, (tail ? tail : ""));
#endif
if(loadtype == BAT_FILETYPE) { /* if Batch file then:- */
if (batchflg == 0) echoflg_save2 = echoflg;
ret = echoflg; /* Save the Current ECHO State */
batch_end(); /* Close any Existing Batch file */
echoflg = ret; /* restore the ECHO status */
batch_start(argv0, loadpath, tail); /* and initialize the new batch */
return YES; /* use "CALL" to nest batches. */
}
/* if CMD, COM or EXE */
if(batchflg) /* close the BATCH file if OPEN cos */
batch_close(); /* some programs update the running */
/* batch file. */
s = deblank(tail); /* No SPACE before options */
if(!*s) /* if this is a blank line */
tail = s;
#if defined(CDOSTMP)
ret = exec(loadpath, loadtype, tail, back_flag);
#else
ms_set_break(break_flag);
#if STACK
s = stack(strlen(tail)+2)+1;
#else
s = &tailbuf[1];
#endif
tail = strcpy(s, tail) - 1;
*tail = (UBYTE) strlen(tail+1);
strcat(tail+1, "\r");
#if !defined(FINAL)
save_psp();
#endif
ret = exec(loadpath, loadtype, tail, back_flag);
#if !defined(FINAL)
check_psp();
#endif
init_switchar(); /* switch character may have changed */
break_flag = ms_set_break(YES);
#endif
/*
* Novell use the MS_DRV_GET function to detect abnormal
* program termination. They assume this function is only
* called by the command processor when a child has terminated.
* They close all Remote Handles when the parent command
* processor calls this function.
*/
drive = ms_drv_get(); /* get default drive. */
for (i=5;i<20;i++) ms_x_close(i); /* Close all handles */
if(ret < 0) { /* Get the returned Error Code */
#if defined(CDOS) || defined(CDOSTMP)
if(ret == ED_ENVIRON) /* Check for an Environment */
ret = (-255); /* error this is really */
#endif /* a resource unavailable. */
/* Print a message if the exec */
e_check(ret); /* went wrong otherwise get the */
/* completion status and return */
return FAILURE;
}
err_ret = ms_x_wait();
return YES;
}
#if !defined(CDOSTMP)
VOID FAR CDECL int2e_handler (cmd)
BYTE *cmd;
{
BYTE *p;
jmp_buf save_jmpbuf;
/* save the normal setjmp environment and reset it to ourselves */
/* so that the int2e caller does not get aborted on criterr or */
/* Control break */
memmove (&save_jmpbuf, &break_env, sizeof (jmp_buf));
if (setjmp (break_env) == 0) {
if ((p = strchr (cmd, 0xd)) != NULL)
*p = '\0';
int2e_start();
docmd (deblank (cmd), TRUE);
/* if int2e is executing a batch file, do not return until all */
/* batch file commands have been processed. Loop round as in main */
/* loop */
while (batchflg > 0)
{
cmd_loop (cmd);
}
int2e_finish();
}
memmove (&break_env, &save_jmpbuf, sizeof (jmp_buf));
}
MLOCAL VOID init_switchar()
{
*switchar = ms_switchar(); /* get switch character */
if (*switchar == '/') /* if not UNIX path char */
*pathchar = '\\'; /* then be compatible */
else
*pathchar = '/';
}
#endif
#if defined(DOSPLUS)
GLOBAL VOID process_config_env()
{
BYTE FAR *config_env;
WORD i;
BYTE buff[128];
BYTE *s;
config_env = get_config_env();
if (config_env) {
FOREVER {
i = 0;
while ((*config_env) && (*config_env!=0x1A) &&
(i < 127)) {
buff[i++] = *config_env++;
}
if (i == 0) {
while (*config_env != 0x1A) config_env++;
config_env++;
boot_key_scan_code = * ((UWORD far *) config_env);
break;
}
buff[i] = 0;
cmd_set(buff);
while (*config_env) config_env++;
config_env++;
}
#if 0
s = heap();
if (!env_scan("HOMEDIR=",s)) {
if (s[1] == ':') ms_drv_set(toupper(*s)-'A');
ms_x_chdir(s);
}
#endif
}
}
#endif
#if !defined(FINAL)
void save_psp()
{
BYTE far *fp;
WORD i;
fp = MK_FP(_psp,0);
psp_xsum = 0;
for (i=64;i<128;i++) psp_xsum += fp[i];
}
void check_psp()
{
BYTE far *fp;
WORD xsum;
WORD i;
fp = MK_FP(_psp,0);
xsum = 0;
for (i=64;i<128;i++) xsum += fp[i];
if (xsum != psp_xsum) {
printf("BETA DEBUG ERROR: Need more stack!\n");
printf("Press a key to continue.\n");
getch();
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -