From: Christos Zoulas Date: Mon, 24 Mar 2003 01:34:21 +0000 (+0000) Subject: add apptype.c for OS/2 X-Git-Tag: FILE4_00~7 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=64a3edc5fa0becd6ab58db1fb1e8f6072a1db3dc;p=file add apptype.c for OS/2 --- diff --git a/src/Makefile.am b/src/Makefile.am index 4b719eaa..afc7805d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -8,7 +8,7 @@ AM_CPPFLAGS = -DMAGIC='"$(MAGIC)"' libmagic_la_SOURCES = magic.c apprentice.c softmagic.c ascmagic.c \ compress.c is_tar.c readelf.c print.c fsmagic.c \ - funcs.c file.h names.h patchlevel.h readelf.h tar.h + funcs.c file.h names.h patchlevel.h readelf.h tar.h apptype.c libmagic_la_LDFLAGS = -version-info 1:0:0 file_SOURCES = file.c diff --git a/src/apptype.c b/src/apptype.c new file mode 100644 index 00000000..9a649d03 --- /dev/null +++ b/src/apptype.c @@ -0,0 +1,169 @@ +/* + * Adapted from: apptype.c, Written by Eberhard Mattes and put into the + * public domain + * + * Notes: 1. Qualify the filename so that DosQueryAppType does not do extraneous + * searches. + * + * 2. DosQueryAppType will return FAPPTYP_DOS on a file ending with ".com" + * (other than an OS/2 exe or Win exe with this name). Eberhard Mattes + * remarks Tue, 6 Apr 93: Moreover, it reports the type of the (new and very + * bug ridden) Win Emacs as "OS/2 executable". + * + * 3. apptype() uses the filename if given, otherwise a tmp file is created with + * the contents of buf. If buf is not the complete file, apptype can + * incorrectly identify the exe type. The "-z" option of "file" is the reason + * for this ugly code. + */ + +/* + * amai: Darrel Hankerson did the changes described here. + * + * It remains to check the validity of comments (2.) since it's referred to an + * "old" OS/2 version. + * + */ + +#ifdef __EMX__ +#include +#include +#include +#include +#define INCL_DOSSESMGR +#define INCL_DOSERRORS +#define INCL_DOSFILEMGR +#include +typedef ULONG APPTYPE; + +#include "file.h" + +#ifndef lint +FILE_RCSID("@(#)$Id: apptype.c,v 1.1 2003/03/24 01:34:21 christos Exp $") +#endif /* lint */ + +protected int +file_os2_apptype(struct magic_set *ms, const char *fn, const void *buf, + size_t nb) +{ + APPTYPE rc, type; + char path[_MAX_PATH], drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME], + ext[_MAX_EXT]; +#endif + char *filename; + FILE *fp; + + if (fn) + filename = strdup(fn); + else if ((filename = tempnam("./", "tmp")) == NULL) { + error("can't create tempnam (%s).\n", strerror(errno)); + } + /* qualify the filename to prevent extraneous searches */ + _splitpath(filename, drive, dir, fname, ext); + sprintf(path, "%s%s%s%s", drive, + (*dir == '\0') ? "./" : dir, + fname, + (*ext == '\0') ? "." : ext); + + if (fn == NULL) { + if ((fp = fopen(path, "wb")) == NULL) { + file_error("Can't open tmp file `%s' (%s)", path, + strerror(errno)); + return -1; + } + if (fwrite(buf, 1, nb, fp) != nb) { + file_error("Can't write tmp file `%s' (%s)", path, + strerror(errno)); + return -1; + } + (void)fclose(fp); + } + rc = DosQueryAppType(path, &type); + + if (fn == NULL) { + unlink(path); + free(filename); + } +#if 0 + if (rc == ERROR_INVALID_EXE_SIGNATURE) + printf("%s: not an executable file\n", fname); + else if (rc == ERROR_FILE_NOT_FOUND) + printf("%s: not found\n", fname); + else if (rc == ERROR_ACCESS_DENIED) + printf("%s: access denied\n", fname); + else if (rc != 0) + printf("%s: error code = %lu\n", fname, rc); + else +#else + + /* + * for our purpose here it's sufficient to just ignore the error and + * return w/o success (=0) + */ + + if (rc) + return (0); + +#endif + + if (type & FAPPTYP_32BIT) + if (file_printf(ms, "32-bit ") == -1) + return -1; + if (type & FAPPTYP_PHYSDRV) { + if (file_printf(ms, "physical device driver") == -1) + return -1; + } else if (type & FAPPTYP_VIRTDRV) { + if (file_printf(ms, "virtual device driver") == -1) + return -1; + } else if (type & FAPPTYP_DLL) { + if (type & FAPPTYP_PROTDLL) + if (file_printf(ms, "protected ") == -1) + return -1; + if (file_printf(ms, "DLL") == -1) + return -1; + } else if (type & (FAPPTYP_WINDOWSREAL | FAPPTYP_WINDOWSPROT)) { + if (file_printf(ms, "Windows executable") == -1) + return -1; + } else if (type & FAPPTYP_DOS) { + /* + * The API routine is partially broken on filenames ending + * ".com". + */ + if (stricmp(ext, ".com") == 0) + if (strncmp((const char *)buf, "MZ", 2)) + return (0); + if (file_printf(ms, "DOS executable") == -1) + return -1; + /* ---------------------------------------- */ + /* Might learn more from the magic(4) entry */ + if (file_printf(ms, ", magic(4)-> ") == -1) + return -1; + return (0); + /* ---------------------------------------- */ + } else if (type & FAPPTYP_BOUND) { + if (file_printf(ms, "bound executable") == -1) + return -1; + } else if ((type & 7) == FAPPTYP_WINDOWAPI) { + if (file_printf(ms, "PM executable") == -1) + return -1; + } else if (file_printf(ms, "OS/2 executable") == -1) + return -1; + + switch (type & (FAPPTYP_NOTWINDOWCOMPAT | + FAPPTYP_WINDOWCOMPAT | + FAPPTYP_WINDOWAPI)) { + case FAPPTYP_NOTWINDOWCOMPAT: + if (file_printf(ms, " [NOTWINDOWCOMPAT]") == -1) + return -1; + break; + case FAPPTYP_WINDOWCOMPAT: + if (file_printf(ms, " [WINDOWCOMPAT]") == -1) + return -1; + break; + case FAPPTYP_WINDOWAPI: + if (file_printf(ms, " [WINDOWAPI]") == -1) + return -1; + break; + } + return 1; +} +#endif diff --git a/src/file.c b/src/file.c index 22629fb5..94fad898 100644 --- a/src/file.c +++ b/src/file.c @@ -72,7 +72,7 @@ #include "patchlevel.h" #ifndef lint -FILE_RCSID("@(#)$Id: file.c,v 1.72 2003/03/24 01:16:28 christos Exp $") +FILE_RCSID("@(#)$Id: file.c,v 1.73 2003/03/24 01:34:21 christos Exp $") #endif /* lint */ @@ -82,11 +82,6 @@ FILE_RCSID("@(#)$Id: file.c,v 1.72 2003/03/24 01:16:28 christos Exp $") # define USAGE "Usage: %s [-bciknsvz] [-f namefile] [-m magicfiles] file...\n" #endif -#ifdef __EMX__ -private char *apptypeName = NULL; -int os2_apptype (const char *fn, char *buf, int nb); -#endif /* __EMX__ */ - #ifndef MAGIC # define MAGIC "/etc/magic" #endif diff --git a/src/funcs.c b/src/funcs.c index e95e7f1f..7f0722f2 100644 --- a/src/funcs.c +++ b/src/funcs.c @@ -31,6 +31,7 @@ #include #include #include + /* * Like printf, only we print to a buffer and advance it. */ diff --git a/src/magic.c b/src/magic.c index 3733120d..8a8106c6 100644 --- a/src/magic.c +++ b/src/magic.c @@ -36,9 +36,14 @@ #include "patchlevel.h" #ifndef lint -FILE_RCSID("@(#)$Id: magic.c,v 1.4 2003/03/24 01:16:28 christos Exp $") +FILE_RCSID("@(#)$Id: magic.c,v 1.5 2003/03/24 01:34:21 christos Exp $") #endif /* lint */ +#ifdef __EMX__ +private char *apptypeName = NULL; +protected int file_os2_apptype(struct magic_set *ms, const char *fn, + const void *buf, size_t nb); +#endif /* __EMX__ */ #ifndef MAGIC # define MAGIC "/etc/magic" @@ -190,12 +195,22 @@ magic_file(struct magic_set *ms, const char *inname) return NULL; } - if (nbytes == 0){ + if (nbytes == 0) { if (file_printf(ms, (ms->flags & MAGIC_MIME) ? "application/x-empty" : "empty") == -1) return NULL; } else { buf[nbytes++] = '\0'; /* null-terminate it */ +#ifdef __EMX__ + switch (file_os2_apptype(ms, inname, buf, nbytes)) { + case -1: + return NULL; + case 0: + break; + default: + return ms->o.buf; + } +#endif if (file_buffer(ms, buf, nbytes) == -1) return NULL; #ifdef BUILTIN_ELF