]> granicus.if.org Git - file/commitdiff
add apptype.c for OS/2
authorChristos Zoulas <christos@zoulas.com>
Mon, 24 Mar 2003 01:34:21 +0000 (01:34 +0000)
committerChristos Zoulas <christos@zoulas.com>
Mon, 24 Mar 2003 01:34:21 +0000 (01:34 +0000)
src/Makefile.am
src/apptype.c [new file with mode: 0644]
src/file.c
src/funcs.c
src/magic.c

index 4b719eaaf179e2713d894eb81fc69fa77f510195..afc7805ddbdd9d63e3f7a3b45a237db1b57079e1 100644 (file)
@@ -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 (file)
index 0000000..9a649d0
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <io.h>
+#define INCL_DOSSESMGR
+#define INCL_DOSERRORS
+#define INCL_DOSFILEMGR
+#include <os2.h>
+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
index 22629fb5d19770f6271c8249d347b553e2c7895e..94fad898106c819ee9ec254c6af628eeb286407e 100644 (file)
@@ -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
index e95e7f1fa442f392f97da456e9202777ac5875ab..7f0722f2ce5466557d9d22307729209cab813f54 100644 (file)
@@ -31,6 +31,7 @@
 #include <stdarg.h>
 #include <stdlib.h>
 #include <string.h>
+
 /*
  * Like printf, only we print to a buffer and advance it.
  */
index 3733120d59c0d2306aaab5c621cf70265bcc1945..8a8106c61b19e472d4d35a3d63ab03a9fcf02635 100644 (file)
 #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