--- embedaddon/php/ext/fileinfo/libmagic/magic.c 2012/02/21 23:47:56 1.1.1.1 +++ embedaddon/php/ext/fileinfo/libmagic/magic.c 2012/05/29 12:34:39 1.1.1.2 @@ -28,7 +28,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: magic.c,v 1.62 2009/03/20 21:25:41 christos Exp $") +FILE_RCSID("@(#)$File: magic.c,v 1.74 2011/05/26 01:27:59 christos Exp $") #endif /* lint */ #include "magic.h" @@ -46,6 +46,10 @@ FILE_RCSID("@(#)$File: magic.c,v 1.62 2009/03/20 21:25 # include "php_config.h" #endif +#ifdef PHP_WIN32 +#include +#endif + #include /* for PIPE_BUF */ #if defined(HAVE_UTIMES) @@ -62,12 +66,6 @@ FILE_RCSID("@(#)$File: magic.c,v 1.62 2009/03/20 21:25 #include /* for read() */ #endif -#ifndef PHP_WIN32 -# include /* for byte swapping */ -#endif - -#include "patchlevel.h" - #ifndef PIPE_BUF /* Get the PIPE_BUF from pathconf */ #ifdef _PC_PIPE_BUF @@ -86,12 +84,140 @@ private void free_mlist(struct mlist *); private void close_and_restore(const struct magic_set *, const char *, int, const struct stat *); private int unreadable_info(struct magic_set *, mode_t, const char *); +private const char* get_default_magic(void); private const char *file_or_stream(struct magic_set *, const char *, php_stream *); #ifndef STDIN_FILENO #define STDIN_FILENO 0 #endif +/* XXX this functionality is excluded in php, enable it in apprentice.c:340 */ +#if 0 +private const char * +get_default_magic(void) +{ + static const char hmagic[] = "/.magic/magic.mgc"; + static char *default_magic; + char *home, *hmagicpath; + +#ifndef PHP_WIN32 + struct stat st; + + if (default_magic) { + free(default_magic); + default_magic = NULL; + } + if ((home = getenv("HOME")) == NULL) + return MAGIC; + + if (asprintf(&hmagicpath, "%s/.magic", home) < 0) + return MAGIC; + if (stat(hmagicpath, &st) == -1) + goto out; + if (S_ISDIR(st.st_mode)) { + free(hmagicpath); + if (asprintf(&hmagicpath, "%s/%s", home, hmagic) < 0) + return MAGIC; + if (access(hmagicpath, R_OK) == -1) + goto out; + } + + if (asprintf(&default_magic, "%s:%s", hmagicpath, MAGIC) < 0) + goto out; + free(hmagicpath); + return default_magic; +out: + default_magic = NULL; + free(hmagicpath); + return MAGIC; +#else + char *hmagicp = hmagicpath; + char *tmppath = NULL; + LPTSTR dllpath; + +#define APPENDPATH() \ + do { \ + if (tmppath && access(tmppath, R_OK) != -1) { \ + if (hmagicpath == NULL) \ + hmagicpath = tmppath; \ + else { \ + if (asprintf(&hmagicp, "%s%c%s", hmagicpath, \ + PATHSEP, tmppath) >= 0) { \ + free(hmagicpath); \ + hmagicpath = hmagicp; \ + } \ + free(tmppath); \ + } \ + tmppath = NULL; \ + } \ + } while (/*CONSTCOND*/0) + + if (default_magic) { + free(default_magic); + default_magic = NULL; + } + + /* First, try to get user-specific magic file */ + if ((home = getenv("LOCALAPPDATA")) == NULL) { + if ((home = getenv("USERPROFILE")) != NULL) + if (asprintf(&tmppath, + "%s/Local Settings/Application Data%s", home, + hmagic) < 0) + tmppath = NULL; + } else { + if (asprintf(&tmppath, "%s%s", home, hmagic) < 0) + tmppath = NULL; + } + + APPENDPATH(); + + /* Second, try to get a magic file from Common Files */ + if ((home = getenv("COMMONPROGRAMFILES")) != NULL) { + if (asprintf(&tmppath, "%s%s", home, hmagic) >= 0) + APPENDPATH(); + } + + /* Third, try to get magic file relative to dll location */ + dllpath = malloc(sizeof(*dllpath) * (MAX_PATH + 1)); + dllpath[MAX_PATH] = 0; /* just in case long path gets truncated and not null terminated */ + if (GetModuleFileNameA(NULL, dllpath, MAX_PATH)){ + PathRemoveFileSpecA(dllpath); + if (strlen(dllpath) > 3 && + stricmp(&dllpath[strlen(dllpath) - 3], "bin") == 0) { + if (asprintf(&tmppath, + "%s/../share/misc/magic.mgc", dllpath) >= 0) + APPENDPATH(); + } else { + if (asprintf(&tmppath, + "%s/share/misc/magic.mgc", dllpath) >= 0) + APPENDPATH(); + else if (asprintf(&tmppath, + "%s/magic.mgc", dllpath) >= 0) + APPENDPATH(); + } + } + + /* Don't put MAGIC constant - it likely points to a file within MSys + tree */ + default_magic = hmagicpath; + return default_magic; +#endif +} + +public const char * +magic_getpath(const char *magicfile, int action) +{ + if (magicfile != NULL) + return magicfile; + + magicfile = getenv("MAGIC"); + if (magicfile != NULL) + return magicfile; + + return action == FILE_LOAD ? get_default_magic() : MAGIC; +} +#endif + public struct magic_set * magic_open(int flags) { @@ -196,6 +322,15 @@ magic_compile(struct magic_set *ms, const char *magicf return ml ? 0 : -1; } + +public int +magic_list(struct magic_set *ms, const char *magicfile) +{ + struct mlist *ml = file_apprentice(ms, magicfile, FILE_LIST); + free_mlist(ml); + return ml ? 0 : -1; +} + private void close_and_restore(const struct magic_set *ms, const char *name, int fd, const struct stat *sb) @@ -272,18 +407,17 @@ file_or_stream(struct magic_set *ms, const char *innam #define SLOP (1 + sizeof(union VALUETYPE)) buf = emalloc(HOWMANY + SLOP); - if (file_reset(ms) == -1) { + if (file_reset(ms) == -1) goto done; - } switch (file_fsmagic(ms, inname, &sb, stream)) { - case -1: /* error */ - goto done; - case 0: /* nothing found */ - break; - default: /* matched it and printed type */ - rv = 0; - goto done; + case -1: /* error */ + goto done; + case 0: /* nothing found */ + break; + default: /* matched it and printed type */ + rv = 0; + goto done; } errno = 0; @@ -330,6 +464,7 @@ done: close_and_restore(ms, inname, 0, &sb); return rv == 0 ? file_getbuffer(ms) : NULL; } + public const char * magic_buffer(struct magic_set *ms, const void *buf, size_t nb)