📄 msexec.c
字号:
/*
EXEC.C: EXEC function with memory swap - Prepare parameters.
Public domain software by
Thomas Wagner
Ferrari electronic GmbH
Beusselstrasse 27
D-1000 Berlin 21
Germany
*/
//#include "compat.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <dos.h>
#include <malloc.h>
#include <direct.h>
#include <sys\types.h>
#include <sys\stat.h>
#define MK_FP(seg,ofs) ((void far *)(((unsigned long)(seg) << 16) | \
(unsigned short)(ofs)))
#include <ctype.h>
#include <tools.h>
#define SWAP_FILENAME "$$AAAAAA.AAA"
/* internal flags for prep_swap */
#define CREAT_TEMP 0x0080
#define DONT_SWAP_ENV 0x4000
/* local variables */
static char l_drive [_MAX_DRIVE], dir [_MAX_DIR];
static char name [_MAX_FNAME], ext [_MAX_EXT];
#ifdef __cplusplus
extern "C" int
#else
extern int _cdecl
#endif
do_spawn (int swapping, /* swap if non-0 */
char *xeqfn, /* file to execute */
char *cmdtail, /* command tail string */
unsigned envlen, /* environment length */
char *envp); /* environment pointer */
#ifdef __cplusplus
extern "C" int
#else
extern int _cdecl
#endif
prep_swap (int method, /* swap method */
char *swapfn); /* swap file name and/or path */
/* Returns TRUE if a file with name 'fn' exists. */
static int exists (char *fn)
{
struct find_t fb;
return !_dos_findfirst (fn, _A_RDONLY|_A_HIDDEN|_A_SYSTEM|_A_ARCH, &fb);
}
/* Try '.COM' and '.EXE' on current filename, modify filename if found. */
static int tryext (char *fn)
{
int i;
i = strlen (fn);
strcat (fn, ".COM");
if (exists (fn))
return 1;
fn [i] = 0;
strcat (fn, ".EXE");
if (exists (fn))
return 1;
fn [i] = 0;
return 0;
}
/* Try to find the file 'fn' in the current path. Modifies the filename
accordingly. */
static int findfile (char *fn)
{
char *path, *penv;
char *prfx;
int found;
if (!fn [0])
strcpy (fn, getenv ("COMSPEC"));
_splitpath (fn, l_drive, dir, name, ext);
if (ext [0])
found = exists (fn);
else
found = tryext (fn);
if (!found && !dir [0] && !l_drive [0])
{
penv = getenv ("PATH");
if (!penv)
return 0;
path = (char *)malloc (strlen (penv) + 1);
if (path == NULL)
return 0;
strcpy (path, penv);
prfx = strtok (path, ";");
while (!found && prfx != NULL)
{
_makepath (fn, l_drive, prfx, name, ext);
if (ext [0])
found = exists (fn);
else
found = tryext (fn);
prfx = strtok (NULL, ";");
}
free (path);
}
return found;
}
/*
tempdir: Set temporary file path.
Read "TMP/TEMP" environment. If empty or invalid, clear path.
If TEMP is l_drive or l_drive+backslash only, return TEMP.
Otherwise check if given path is a valid directory.
If so, add a backslash, else clear path.
*/
static void tempdir (char *outfn)
{
int l;
char *s;
struct stat ff;
union REGS regs;
struct SREGS segregs;
*outfn = 0;
if ((s = getenv ("TMP")) == NULL)
if ((s = getenv ("TEMP")) == NULL)
return;
strcpy (outfn, s);
l = strlen (outfn);
if (!l)
return;
if (outfn [l - 1] == '\\' || outfn [l - 1] == '/')
outfn [--l] = 0;
_splitpath (outfn, l_drive, dir, name, ext);
if (l_drive [0])
{
regs.h.dl = (unsigned char)(toupper (l_drive [0]) - 'A' + 1);
regs.h.ah = 0x1c;
intdosx (®s, ®s, &segregs);
if (regs.h.al == 0xff)
{
*outfn = 0;
return;
}
}
if (!name [0]) /* No dir name */
{
if (dir [0])
*outfn = 0;
else
{
outfn [l++] = '\\';
outfn [l] = 0;
}
return;
}
if (stat (outfn, &ff))
*outfn = 0;
/* the following won't work with TC/BC - directories never have the
write attribute set (don't ask me why). So only check for dir.
*/
#if (0)
else if (!(ff.st_mode & S_IFDIR) || !(ff.st_mode & S_IWRITE))
#else
else if (!(ff.st_mode & S_IFDIR))
#endif
*outfn = 0;
else
{
outfn [l++] = '\\';
outfn [l] = 0;
}
}
int do_exec (char *exfn, char *epars, int spwn, unsigned needed, char **envp)
{
static char swapfn [82];
static char execfn [82];
unsigned avail;
union REGS regs;
unsigned envlen;
int rc;
int idx;
char **env;
char *ep, *envptr, *envbuf;
int swapping;
strcpy (execfn, exfn);
/* First, check if the file to execute exists. */
if (!findfile (execfn))
return RC_NOFILE;
/* Now create a copy of the environment if the user wants it. */
envlen = 0;
envptr = NULL;
if (envp != NULL)
for (env = envp; *env != NULL; env++)
envlen += strlen (*env) + 1;
if (envlen)
{
/* round up to paragraph, and alloc another paragraph leeway */
envlen = (envlen + 32) & 0xfff0;
envbuf = (char *)malloc (envlen);
if (envbuf == NULL)
return RC_ENVERR;
/* align to paragraph */
envptr = envbuf;
if (FP_OFF (envptr) & 0x0f)
envptr += 16 - (FP_OFF (envptr) & 0x0f);
ep = envptr;
for (env = envp; *env != NULL; env++)
{
ep = (strcpy (ep, *env), ep + strlen (*env)) + 1;
}
*ep = 0;
}
if (!spwn)
swapping = -1;
else
{
/* Determine amount of free memory */
regs.x.ax = 0x4800;
regs.x.bx = 0xffff;
intdos (®s, ®s);
avail = regs.x.bx;
/* No swapping if available memory > needed */
if (needed < avail)
swapping = 0;
else
{
/* Swapping necessary, use 'TMP' or 'TEMP' environment variable
to determine swap file path if defined. */
swapping = spwn;
if (spwn & USE_FILE)
{
tempdir (swapfn);
if (_osmajor >= 3)
swapping |= CREAT_TEMP;
else
{
strcat (swapfn, SWAP_FILENAME);
idx = strlen (swapfn) - 1;
while (exists (swapfn))
{
if (swapfn [idx] == 'Z')
idx--;
if (swapfn [idx] == '.')
idx--;
swapfn [idx]++;
}
}
}
}
}
/* All set up, ready to go. */
if (swapping > 0)
{
if (!envlen)
swapping |= DONT_SWAP_ENV;
rc = prep_swap (swapping, swapfn);
if (rc < 0)
return RC_PREPERR | -rc;
}
rc = do_spawn (swapping, execfn, epars, envlen, envptr);
/* Free the environment buffer if it was allocated. */
if (envlen)
free (envbuf);
return rc;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -