file/src/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 #include <stdio.h>
00030 #include <stdlib.h>
00031 #include <string.h>
00032 
00033 
00034 #ifndef lint
00035 FILE_RCSID("@(#)$File: apptype.c,v 1.7 2007/01/12 17:38:27 christos Exp $")
00036 #endif /* lint */
00037 
00038 #ifdef __EMX__
00039 #include <io.h>
00040 #define INCL_DOSSESMGR
00041 #define INCL_DOSERRORS
00042 #define INCL_DOSFILEMGR
00043 #include <os2.h>
00044 typedef ULONG   APPTYPE;
00045 
00046 protected int
00047 file_os2_apptype(struct magic_set *ms, const char *fn, const void *buf,
00048     size_t nb)
00049 {
00050         APPTYPE         rc, type;
00051         char            path[_MAX_PATH], drive[_MAX_DRIVE], dir[_MAX_DIR],
00052                         fname[_MAX_FNAME], ext[_MAX_EXT];
00053         char           *filename;
00054         FILE           *fp;
00055 
00056         if (fn)
00057                 filename = strdup(fn);
00058         else if ((filename = tempnam("./", "tmp")) == NULL) {
00059                 file_error(ms, errno, "cannot create tempnam");
00060                 return -1;
00061         }
00062         /* qualify the filename to prevent extraneous searches */
00063         _splitpath(filename, drive, dir, fname, ext);
00064         (void)sprintf(path, "%s%s%s%s", drive,
00065                 (*dir == '\0') ? "./" : dir,
00066                 fname,
00067                 (*ext == '\0') ? "." : ext);
00068 
00069         if (fn == NULL) {
00070                 if ((fp = fopen(path, "wb")) == NULL) {
00071                         file_error(ms, errno, "cannot open tmp file `%s'", path);
00072                         return -1;
00073                 }
00074                 if (fwrite(buf, 1, nb, fp) != nb) {
00075                         file_error(ms, errno, "cannot write tmp file `%s'",
00076                             path);
00077                         return -1;
00078                 }
00079                 (void)fclose(fp);
00080         }
00081         rc = DosQueryAppType(path, &type);
00082 
00083         if (fn == NULL) {
00084                 unlink(path);
00085                 free(filename);
00086         }
00087 #if 0
00088         if (rc == ERROR_INVALID_EXE_SIGNATURE)
00089                 printf("%s: not an executable file\n", fname);
00090         else if (rc == ERROR_FILE_NOT_FOUND)
00091                 printf("%s: not found\n", fname);
00092         else if (rc == ERROR_ACCESS_DENIED)
00093                 printf("%s: access denied\n", fname);
00094         else if (rc != 0)
00095                 printf("%s: error code = %lu\n", fname, rc);
00096         else
00097 #else
00098 
00099         /*
00100          * for our purpose here it's sufficient to just ignore the error and
00101          * return w/o success (=0)
00102          */
00103 
00104         if (rc)
00105                 return (0);
00106 
00107 #endif
00108 
00109         if (type & FAPPTYP_32BIT)
00110                 if (file_printf(ms, "32-bit ") == -1)
00111                         return -1;
00112         if (type & FAPPTYP_PHYSDRV) {
00113                 if (file_printf(ms, "physical device driver") == -1)
00114                         return -1;
00115         } else if (type & FAPPTYP_VIRTDRV) {
00116                 if (file_printf(ms, "virtual device driver") == -1)
00117                         return -1;
00118         } else if (type & FAPPTYP_DLL) {
00119                 if (type & FAPPTYP_PROTDLL)
00120                         if (file_printf(ms, "protected ") == -1)
00121                                 return -1;
00122                 if (file_printf(ms, "DLL") == -1)
00123                         return -1;
00124         } else if (type & (FAPPTYP_WINDOWSREAL | FAPPTYP_WINDOWSPROT)) {
00125                 if (file_printf(ms, "Windows executable") == -1)
00126                         return -1;
00127         } else if (type & FAPPTYP_DOS) {
00128                 /*
00129                  * The API routine is partially broken on filenames ending
00130                  * ".com".
00131                  */
00132                 if (stricmp(ext, ".com") == 0)
00133                         if (strncmp((const char *)buf, "MZ", 2))
00134                                 return (0);
00135                 if (file_printf(ms, "DOS executable") == -1)
00136                         return -1;
00137                 /* ---------------------------------------- */
00138                 /* Might learn more from the magic(4) entry */
00139                 if (file_printf(ms, ", magic(4)-> ") == -1)
00140                         return -1;
00141                 return (0);
00142                 /* ---------------------------------------- */
00143         } else if (type & FAPPTYP_BOUND) {
00144                 if (file_printf(ms, "bound executable") == -1)
00145                         return -1;
00146         } else if ((type & 7) == FAPPTYP_WINDOWAPI) {
00147                 if (file_printf(ms, "PM executable") == -1)
00148                         return -1;
00149         } else if (file_printf(ms, "OS/2 executable") == -1)
00150                 return -1;
00151 
00152         switch (type & (FAPPTYP_NOTWINDOWCOMPAT |
00153                         FAPPTYP_WINDOWCOMPAT |
00154                         FAPPTYP_WINDOWAPI)) {
00155         case FAPPTYP_NOTWINDOWCOMPAT:
00156                 if (file_printf(ms, " [NOTWINDOWCOMPAT]") == -1)
00157                         return -1;
00158                 break;
00159         case FAPPTYP_WINDOWCOMPAT:
00160                 if (file_printf(ms, " [WINDOWCOMPAT]") == -1)
00161                         return -1;
00162                 break;
00163         case FAPPTYP_WINDOWAPI:
00164                 if (file_printf(ms, " [WINDOWAPI]") == -1)
00165                         return -1;
00166                 break;
00167         }
00168         return 1;
00169 }
00170 #endif

Generated on Fri Aug 31 11:02:21 2007 for rpm by  doxygen 1.5.1