#include <libc/stubs.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <dpmi.h>
#include <go32.h>
#include <io.h>
#include <libc/farptrgs.h>
#include <libc/dosio.h>
extern unsigned short _djstat_flags;
unsigned short _get_magic(const char *, int);
int _is_executable(const char *, int, const char *);
#define _STAT_EXEC_EXT 2
#define _STAT_EXEC_MAGIC 4
unsigned short
_get_magic(const char *s, int fh)
{
__dpmi_regs regs;
unsigned short retval;
unsigned short fpos_high = 0, fpos_low = 0;
int read_fail = 0;
if (s)
{
int handle;
if((handle = _open(s,0)) == -1)
return 0;
regs.x.bx = handle;
}
else
{
regs.x.ax = 0x4201;
regs.x.bx = fh;
regs.x.cx = regs.x.dx = 0;
__dpmi_int(0x21, ®s);
if (regs.x.flags & 1)
{
errno = __doserr_to_errno(regs.x.ax);
return 0;
}
fpos_high = regs.x.dx;
fpos_low = regs.x.ax;
regs.x.ax = 0x4200;
regs.x.cx = regs.x.dx = 0;
__dpmi_int(0x21, ®s);
if (regs.x.flags & 1)
{
errno = __doserr_to_errno(regs.x.ax);
return 0;
}
}
regs.x.ds = __tb_segment;
regs.x.dx = __tb_offset;
regs.x.ax = 0x3f00;
regs.x.cx = 2;
__dpmi_int(0x21, ®s);
if (regs.x.ax != 2)
read_fail = (regs.x.flags & 1) ? regs.x.ax : -1;
if (s)
{
regs.x.ax = 0x3e00;
__dpmi_int(0x21, ®s);
if (regs.x.flags & 1)
errno = __doserr_to_errno(regs.x.ax);
}
else
{
regs.x.ax = 0x4200;
regs.x.bx = fh;
regs.x.cx = fpos_high;
regs.x.dx = fpos_low;
__dpmi_int(0x21, ®s);
if (regs.x.flags & 1)
{
errno = __doserr_to_errno(regs.x.ax);
return 0;
}
}
if (read_fail == 0)
retval = _farpeekw(_dos_ds, __tb);
else
{
retval = 0;
if (read_fail != -1)
errno = __doserr_to_errno(read_fail);
}
return retval;
}
static char executables[] = "|EXE|COM|BAT|BTM|DLL|VXD|";
static char non_executables[] = "\
|A|A01|A02|A03|A04|A05|ADL|ARC|ARJ|ASC|ASM|AUX|AWK\
|BAS|BIB|BGI|BMP\
|C|CC|CFG|CGZ|CH3|CHR|CI|CLP|CMF|CPI|CPP|CXX\
|DAT|DBF|DIZ|DOC|DVI\
|E|EL|ELC\
|F77|FN3\
|GIF|GZ\
|H|HLP|HPP|HXX\
|ICO|IN|INC|INF|INI\
|JPG\
|L|LEX|LF|LIB|LOG|LST|LZH\
|M|MAK|MAP|MF|MID|MPG\
|O|OBJ\
|PAK|PAS|PBM|PCD|PCX|PDS|PIC|PIF|PN3|PRJ|PS\
|RAS|RGB|RLE\
|S|SND|SY3\
|TAR|TAZ|TEX|TGA|TGZ|TIF|TXH|TXI|TXT\
|VOC\
|WAV|WK1|WK3|WKB|WQ1|WQ3|WQ4|WQ5|WQ6|WQ!\
|XBM\
|Y\
|ZIP|ZOO|";
int
_is_executable(const char *filename, int fhandle, const char *extension)
{
if (!extension && filename)
{
const char *cp, *ep=0;
for (cp=filename; *cp; cp++)
{
if (*cp == '.')
ep = cp;
if (*cp == '/' || *cp == '\\' || *cp == ':')
ep = 0;
}
extension = ep;
}
if ((_djstat_flags & _STAT_EXEC_EXT) == 0
&& extension
&& *extension
&& strlen(extension) <= ((extension[0]=='.') ? 4 : 3))
{
char tmp_buf[6], *tp = tmp_buf;
*tp++ = '|';
if (*extension == '.')
extension++;
while (*extension)
*tp++ = toupper (*extension++);
*tp++ = '|';
*tp = '\0';
if (strstr(non_executables, tmp_buf))
return 0;
else if (strstr(executables, tmp_buf))
return 1;
}
if ( (_djstat_flags & _STAT_EXEC_MAGIC) == 0 )
{
switch (_get_magic(filename, fhandle))
{
case 0x5a4d:
case 0x010b:
case 0x014c:
case 0x2123:
return 1;
}
}
return 0;
}