1133359Sobrien/* 2133359Sobrien * Adapted from: apptype.c, Written by Eberhard Mattes and put into the 3133359Sobrien * public domain 4133359Sobrien * 5133359Sobrien * Notes: 1. Qualify the filename so that DosQueryAppType does not do extraneous 6133359Sobrien * searches. 7133359Sobrien * 8133359Sobrien * 2. DosQueryAppType will return FAPPTYP_DOS on a file ending with ".com" 9133359Sobrien * (other than an OS/2 exe or Win exe with this name). Eberhard Mattes 10133359Sobrien * remarks Tue, 6 Apr 93: Moreover, it reports the type of the (new and very 11133359Sobrien * bug ridden) Win Emacs as "OS/2 executable". 12133359Sobrien * 13133359Sobrien * 3. apptype() uses the filename if given, otherwise a tmp file is created with 14133359Sobrien * the contents of buf. If buf is not the complete file, apptype can 15133359Sobrien * incorrectly identify the exe type. The "-z" option of "file" is the reason 16133359Sobrien * for this ugly code. 17133359Sobrien */ 18133359Sobrien 19133359Sobrien/* 20133359Sobrien * amai: Darrel Hankerson did the changes described here. 21133359Sobrien * 22133359Sobrien * It remains to check the validity of comments (2.) since it's referred to an 23133359Sobrien * "old" OS/2 version. 24133359Sobrien * 25133359Sobrien */ 26133359Sobrien 27133359Sobrien#include "file.h" 28133359Sobrien 29191736Sobrien#ifndef lint 30226048SobrienFILE_RCSID("@(#)$File: apptype.c,v 1.13 2011/09/07 21:57:15 christos Exp $") 31191736Sobrien#endif /* lint */ 32191736Sobrien 33133359Sobrien#include <stdlib.h> 34133359Sobrien#include <string.h> 35133359Sobrien 36133359Sobrien#ifdef __EMX__ 37133359Sobrien#include <io.h> 38133359Sobrien#define INCL_DOSSESMGR 39133359Sobrien#define INCL_DOSERRORS 40133359Sobrien#define INCL_DOSFILEMGR 41133359Sobrien#include <os2.h> 42133359Sobrientypedef ULONG APPTYPE; 43133359Sobrien 44133359Sobrienprotected int 45133359Sobrienfile_os2_apptype(struct magic_set *ms, const char *fn, const void *buf, 46133359Sobrien size_t nb) 47133359Sobrien{ 48133359Sobrien APPTYPE rc, type; 49133359Sobrien char path[_MAX_PATH], drive[_MAX_DRIVE], dir[_MAX_DIR], 50133359Sobrien fname[_MAX_FNAME], ext[_MAX_EXT]; 51133359Sobrien char *filename; 52133359Sobrien FILE *fp; 53133359Sobrien 54133359Sobrien if (fn) 55133359Sobrien filename = strdup(fn); 56133359Sobrien else if ((filename = tempnam("./", "tmp")) == NULL) { 57133359Sobrien file_error(ms, errno, "cannot create tempnam"); 58133359Sobrien return -1; 59133359Sobrien } 60133359Sobrien /* qualify the filename to prevent extraneous searches */ 61133359Sobrien _splitpath(filename, drive, dir, fname, ext); 62133359Sobrien (void)sprintf(path, "%s%s%s%s", drive, 63133359Sobrien (*dir == '\0') ? "./" : dir, 64133359Sobrien fname, 65133359Sobrien (*ext == '\0') ? "." : ext); 66133359Sobrien 67133359Sobrien if (fn == NULL) { 68133359Sobrien if ((fp = fopen(path, "wb")) == NULL) { 69133359Sobrien file_error(ms, errno, "cannot open tmp file `%s'", path); 70133359Sobrien return -1; 71133359Sobrien } 72133359Sobrien if (fwrite(buf, 1, nb, fp) != nb) { 73133359Sobrien file_error(ms, errno, "cannot write tmp file `%s'", 74133359Sobrien path); 75226048Sobrien (void)fclose(fp); 76133359Sobrien return -1; 77133359Sobrien } 78133359Sobrien (void)fclose(fp); 79133359Sobrien } 80192348Sdelphij rc = DosQueryAppType((unsigned char *)path, &type); 81133359Sobrien 82133359Sobrien if (fn == NULL) { 83133359Sobrien unlink(path); 84133359Sobrien free(filename); 85133359Sobrien } 86133359Sobrien#if 0 87133359Sobrien if (rc == ERROR_INVALID_EXE_SIGNATURE) 88133359Sobrien printf("%s: not an executable file\n", fname); 89133359Sobrien else if (rc == ERROR_FILE_NOT_FOUND) 90133359Sobrien printf("%s: not found\n", fname); 91133359Sobrien else if (rc == ERROR_ACCESS_DENIED) 92133359Sobrien printf("%s: access denied\n", fname); 93133359Sobrien else if (rc != 0) 94133359Sobrien printf("%s: error code = %lu\n", fname, rc); 95133359Sobrien else 96133359Sobrien#else 97133359Sobrien 98133359Sobrien /* 99133359Sobrien * for our purpose here it's sufficient to just ignore the error and 100133359Sobrien * return w/o success (=0) 101133359Sobrien */ 102133359Sobrien 103133359Sobrien if (rc) 104133359Sobrien return (0); 105133359Sobrien 106133359Sobrien#endif 107133359Sobrien 108133359Sobrien if (type & FAPPTYP_32BIT) 109133359Sobrien if (file_printf(ms, "32-bit ") == -1) 110133359Sobrien return -1; 111133359Sobrien if (type & FAPPTYP_PHYSDRV) { 112133359Sobrien if (file_printf(ms, "physical device driver") == -1) 113133359Sobrien return -1; 114133359Sobrien } else if (type & FAPPTYP_VIRTDRV) { 115133359Sobrien if (file_printf(ms, "virtual device driver") == -1) 116133359Sobrien return -1; 117133359Sobrien } else if (type & FAPPTYP_DLL) { 118133359Sobrien if (type & FAPPTYP_PROTDLL) 119133359Sobrien if (file_printf(ms, "protected ") == -1) 120133359Sobrien return -1; 121133359Sobrien if (file_printf(ms, "DLL") == -1) 122133359Sobrien return -1; 123133359Sobrien } else if (type & (FAPPTYP_WINDOWSREAL | FAPPTYP_WINDOWSPROT)) { 124133359Sobrien if (file_printf(ms, "Windows executable") == -1) 125133359Sobrien return -1; 126133359Sobrien } else if (type & FAPPTYP_DOS) { 127133359Sobrien /* 128133359Sobrien * The API routine is partially broken on filenames ending 129133359Sobrien * ".com". 130133359Sobrien */ 131133359Sobrien if (stricmp(ext, ".com") == 0) 132133359Sobrien if (strncmp((const char *)buf, "MZ", 2)) 133133359Sobrien return (0); 134133359Sobrien if (file_printf(ms, "DOS executable") == -1) 135133359Sobrien return -1; 136133359Sobrien /* ---------------------------------------- */ 137133359Sobrien /* Might learn more from the magic(4) entry */ 138133359Sobrien if (file_printf(ms, ", magic(4)-> ") == -1) 139133359Sobrien return -1; 140133359Sobrien return (0); 141133359Sobrien /* ---------------------------------------- */ 142133359Sobrien } else if (type & FAPPTYP_BOUND) { 143133359Sobrien if (file_printf(ms, "bound executable") == -1) 144133359Sobrien return -1; 145133359Sobrien } else if ((type & 7) == FAPPTYP_WINDOWAPI) { 146133359Sobrien if (file_printf(ms, "PM executable") == -1) 147133359Sobrien return -1; 148133359Sobrien } else if (file_printf(ms, "OS/2 executable") == -1) 149133359Sobrien return -1; 150133359Sobrien 151133359Sobrien switch (type & (FAPPTYP_NOTWINDOWCOMPAT | 152133359Sobrien FAPPTYP_WINDOWCOMPAT | 153133359Sobrien FAPPTYP_WINDOWAPI)) { 154133359Sobrien case FAPPTYP_NOTWINDOWCOMPAT: 155133359Sobrien if (file_printf(ms, " [NOTWINDOWCOMPAT]") == -1) 156133359Sobrien return -1; 157133359Sobrien break; 158133359Sobrien case FAPPTYP_WINDOWCOMPAT: 159133359Sobrien if (file_printf(ms, " [WINDOWCOMPAT]") == -1) 160133359Sobrien return -1; 161133359Sobrien break; 162133359Sobrien case FAPPTYP_WINDOWAPI: 163133359Sobrien if (file_printf(ms, " [WINDOWAPI]") == -1) 164133359Sobrien return -1; 165133359Sobrien break; 166133359Sobrien } 167133359Sobrien return 1; 168133359Sobrien} 169133359Sobrien#endif 170