Back to index

php5  5.3.10
apptype.c
Go to the documentation of this file.
00001 /*
00002  * Adapted from: apptype.c, Written by Eberhard Mattes and put into the
00003  * public domain
00004  * 
00005  * Notes: 1. Qualify the filename so that DosQueryAppType does not do extraneous
00006  * searches.
00007  * 
00008  * 2. DosQueryAppType will return FAPPTYP_DOS on a file ending with ".com"
00009  * (other than an OS/2 exe or Win exe with this name). Eberhard Mattes
00010  * remarks Tue, 6 Apr 93: Moreover, it reports the type of the (new and very
00011  * bug ridden) Win Emacs as "OS/2 executable".
00012  * 
00013  * 3. apptype() uses the filename if given, otherwise a tmp file is created with
00014  * the contents of buf. If buf is not the complete file, apptype can
00015  * incorrectly identify the exe type. The "-z" option of "file" is the reason
00016  * for this ugly code.
00017  */
00018 
00019 /*
00020  * amai: Darrel Hankerson did the changes described here.
00021  * 
00022  * It remains to check the validity of comments (2.) since it's referred to an
00023  * "old" OS/2 version.
00024  * 
00025  */
00026 
00027 #include "file.h"
00028 
00029 #ifndef       lint
00030 FILE_RCSID("@(#)$File: apptype.c,v 1.11 2009/02/04 18:24:32 christos Exp $")
00031 #endif /* lint */
00032 
00033 #include <stdlib.h>
00034 #include <string.h>
00035 
00036 #ifdef __EMX__
00037 #include <io.h>
00038 #define INCL_DOSSESMGR
00039 #define INCL_DOSERRORS
00040 #define INCL_DOSFILEMGR
00041 #include <os2.h>
00042 typedef ULONG   APPTYPE;
00043 
00044 protected int
00045 file_os2_apptype(struct magic_set *ms, const char *fn, const void *buf,
00046     size_t nb)
00047 {
00048        APPTYPE         rc, type;
00049        char            path[_MAX_PATH], drive[_MAX_DRIVE], dir[_MAX_DIR],
00050                      fname[_MAX_FNAME], ext[_MAX_EXT];
00051        char           *filename;
00052        FILE           *fp;
00053 
00054        if (fn)
00055               filename = strdup(fn);
00056        else if ((filename = tempnam("./", "tmp")) == NULL) {
00057               file_error(ms, errno, "cannot create tempnam");
00058               return -1;
00059        }
00060        /* qualify the filename to prevent extraneous searches */
00061        _splitpath(filename, drive, dir, fname, ext);
00062        (void)sprintf(path, "%s%s%s%s", drive,
00063               (*dir == '\0') ? "./" : dir,
00064               fname,
00065               (*ext == '\0') ? "." : ext);
00066 
00067        if (fn == NULL) {
00068               if ((fp = fopen(path, "wb")) == NULL) {
00069                      file_error(ms, errno, "cannot open tmp file `%s'", path);
00070                      return -1;
00071               }
00072               if (fwrite(buf, 1, nb, fp) != nb) {
00073                      file_error(ms, errno, "cannot write tmp file `%s'",
00074                          path);
00075                      return -1;
00076               }
00077               (void)fclose(fp);
00078        }
00079        rc = DosQueryAppType((unsigned char *)path, &type);
00080 
00081        if (fn == NULL) {
00082               unlink(path);
00083               free(filename);
00084        }
00085 #if 0
00086        if (rc == ERROR_INVALID_EXE_SIGNATURE)
00087               printf("%s: not an executable file\n", fname);
00088        else if (rc == ERROR_FILE_NOT_FOUND)
00089               printf("%s: not found\n", fname);
00090        else if (rc == ERROR_ACCESS_DENIED)
00091               printf("%s: access denied\n", fname);
00092        else if (rc != 0)
00093               printf("%s: error code = %lu\n", fname, rc);
00094        else
00095 #else
00096 
00097        /*
00098         * for our purpose here it's sufficient to just ignore the error and
00099         * return w/o success (=0)
00100         */
00101 
00102        if (rc)
00103               return (0);
00104 
00105 #endif
00106 
00107        if (type & FAPPTYP_32BIT)
00108               if (file_printf(ms, "32-bit ") == -1)
00109                      return -1;
00110        if (type & FAPPTYP_PHYSDRV) {
00111               if (file_printf(ms, "physical device driver") == -1)
00112                      return -1;
00113        } else if (type & FAPPTYP_VIRTDRV) {
00114               if (file_printf(ms, "virtual device driver") == -1)
00115                      return -1;
00116        } else if (type & FAPPTYP_DLL) {
00117               if (type & FAPPTYP_PROTDLL)
00118                      if (file_printf(ms, "protected ") == -1)
00119                             return -1;
00120               if (file_printf(ms, "DLL") == -1)
00121                      return -1;
00122        } else if (type & (FAPPTYP_WINDOWSREAL | FAPPTYP_WINDOWSPROT)) {
00123               if (file_printf(ms, "Windows executable") == -1)
00124                      return -1;
00125        } else if (type & FAPPTYP_DOS) {
00126               /*
00127                * The API routine is partially broken on filenames ending
00128                * ".com".
00129                */
00130               if (stricmp(ext, ".com") == 0)
00131                      if (strncmp((const char *)buf, "MZ", 2))
00132                             return (0);
00133               if (file_printf(ms, "DOS executable") == -1)
00134                      return -1;
00135               /* ---------------------------------------- */
00136               /* Might learn more from the magic(4) entry */
00137               if (file_printf(ms, ", magic(4)-> ") == -1)
00138                      return -1;
00139               return (0);
00140               /* ---------------------------------------- */
00141        } else if (type & FAPPTYP_BOUND) {
00142               if (file_printf(ms, "bound executable") == -1)
00143                      return -1;
00144        } else if ((type & 7) == FAPPTYP_WINDOWAPI) {
00145               if (file_printf(ms, "PM executable") == -1)
00146                      return -1;
00147        } else if (file_printf(ms, "OS/2 executable") == -1)
00148               return -1;
00149 
00150        switch (type & (FAPPTYP_NOTWINDOWCOMPAT |
00151                      FAPPTYP_WINDOWCOMPAT |
00152                      FAPPTYP_WINDOWAPI)) {
00153        case FAPPTYP_NOTWINDOWCOMPAT:
00154               if (file_printf(ms, " [NOTWINDOWCOMPAT]") == -1)
00155                      return -1;
00156               break;
00157        case FAPPTYP_WINDOWCOMPAT:
00158               if (file_printf(ms, " [WINDOWCOMPAT]") == -1)
00159                      return -1;
00160               break;
00161        case FAPPTYP_WINDOWAPI:
00162               if (file_printf(ms, " [WINDOWAPI]") == -1)
00163                      return -1;
00164               break;
00165        }
00166        return 1;
00167 }
00168 #endif