| From 80bde3fbfa74a884b71e6900b9b0be79fbbce35b Mon Sep 17 00:00:00 2001 |
| From: Johannes Schindelin <johannes.schindelin@gmx.de> |
| Date: Thu, 1 Oct 2015 14:59:12 +0200 |
| Subject: [PATCH] Make antiword.exe relocatable on Windows |
| |
| This change allows antiword to find its resource files relative to the |
| executable file: it is expected to live in `<prefix>/bin/antiword.exe` |
| and the resource files will be found in `<prefix>/share/antiword/`. |
| |
| Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> |
| --- |
| antiword.h | 1 + |
| fonts_u.c | 2 +- |
| misc.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| options.c | 17 +++-------------- |
| 4 files changed, 68 insertions(+), 15 deletions(-) |
| |
| diff --git a/antiword.h b/antiword.h |
| index 3f4aad5..d24b640 100644 |
| --- a/antiword.h |
| +++ b/antiword.h |
| @@ -454,6 +454,7 @@ extern BOOL bAllZero(const UCHAR *, size_t); |
| extern BOOL bGetNormalizedCodeset(char *, size_t, BOOL *); |
| extern const char *szGetDefaultMappingFile(void); |
| extern time_t tConvertDTTM(ULONG); |
| +extern FILE *fOpenResource(const char *szFilename, const char *szSuffix); |
| /* notes.c */ |
| extern void vDestroyNotesInfoLists(void); |
| extern void vGetNotesInfo(FILE *, const pps_info_type *, |
| diff --git a/fonts_u.c b/fonts_u.c |
| index a99f7d2..280a7f2 100644 |
| --- a/fonts_u.c |
| +++ b/fonts_u.c |
| @@ -78,7 +78,7 @@ pOpenFontTableFile(void) |
| szGlobalFile = GLOBAL_ANTIWORD_DIR FILE_SEPARATOR FONTNAMES_FILE; |
| DBG_MSG(szGlobalFile); |
| |
| - pFile = fopen(szGlobalFile, "r"); |
| + pFile = fOpenResource(FONTNAMES_FILE, "r"); |
| if (pFile != NULL) { |
| return pFile; |
| } |
| diff --git a/misc.c b/misc.c |
| index 609a2f0..a9610d0 100644 |
| --- a/misc.c |
| +++ b/misc.c |
| @@ -892,3 +892,66 @@ tConvertDTTM(ULONG ulDTTM) |
| NO_DBG_MSG(ctime(&tResult)); |
| return tResult; |
| } /* end of tConvertDTTM */ |
| + |
| +#ifdef __MINGW64_VERSION_MAJOR |
| +#define WIN32_LEAN_AND_MEAN |
| +#include <windows.h> |
| +#endif |
| + |
| +/* |
| + * Opens an Antiword resource file |
| + * |
| + * returns the handle for the file, or NULL |
| + */ |
| +FILE |
| +*fOpenResource(const char *szFilename, const char *szSuffix) |
| +{ |
| +#ifndef __MINGW64_VERSION_MAJOR |
| + static char szPath[PATH_MAX+1]; |
| + |
| + snprintf(szPath, sizeof(szPath), |
| + GLOBAL_ANTIWORD_DIR FILE_SEPARATOR "%s%s", |
| + szFilename, szSuffix ? szSuffix : ""); |
| +#else |
| + static char szPath[32768]; |
| + static size_t tPrefixLen = (size_t)-1; |
| + |
| + if (tPrefixLen == (size_t)-1) { |
| + tPrefixLen = (size_t) |
| + GetModuleFileName(NULL, szPath, sizeof(szPath)); |
| + if (tPrefixLen && tPrefixLen < sizeof(szPath)) { |
| + const char *dir = GLOBAL_ANTIWORD_DIR; |
| + |
| + /* Strip suffix `antiword.exe` */ |
| + while (tPrefixLen > 0 && szPath[tPrefixLen-1] != '\\') { |
| + tPrefixLen--; |
| + } |
| + /* Strip `bin/` directory */ |
| + if (tPrefixLen > 5 && !memcmp(szPath+(tPrefixLen-5), |
| + "\\bin\\",5)) { |
| + tPrefixLen -= 4; |
| + } |
| + /* Append GLOBAL_ANTIWORD_DIR, skipping /usr/ or / */ |
| + if (*dir && *dir == '/') { |
| + dir++; |
| + if (!memcmp(dir, "usr/", 4)) |
| + dir += 4; |
| + } |
| + while (*dir && tPrefixLen < sizeof(szPath)-1) { |
| + char c = *(dir++); |
| + szPath[tPrefixLen++] = c == '/' ? '\\' : c; |
| + } |
| + /* Make sure the prefix ends in a file separator */ |
| + if (tPrefixLen && tPrefixLen < sizeof(szPath)-1 && |
| + szPath[tPrefixLen-1] != '\\') { |
| + szPath[tPrefixLen++] = '\\'; |
| + } |
| + szPath[tPrefixLen]='\0'; |
| + } |
| + } |
| + |
| + snprintf(szPath + tPrefixLen, sizeof(szPath) - tPrefixLen, |
| + "%s%s", szFilename, szSuffix ? szSuffix : ""); |
| +#endif |
| + return fopen(szPath, "r"); |
| +} /* end of fOpenResource */ |
| diff --git a/options.c b/options.c |
| index 8379fef..dd6ced9 100644 |
| --- a/options.c |
| +++ b/options.c |
| @@ -236,20 +236,9 @@ pOpenCharacterMappingFile(const char *szLeafname) |
| } |
| |
| /* Try the global version of the mapping file */ |
| - if (tFilenameLen < |
| - sizeof(szMappingFile) - |
| - sizeof(GLOBAL_ANTIWORD_DIR) - |
| - sizeof(FILE_SEPARATOR)) { |
| - sprintf(szMappingFile, |
| - GLOBAL_ANTIWORD_DIR FILE_SEPARATOR "%s%s", |
| - szLeafname, szSuffix); |
| - DBG_MSG(szMappingFile); |
| - pFile = fopen(szMappingFile, "r"); |
| - if (pFile != NULL) { |
| - return pFile; |
| - } |
| - } else { |
| - werr(0, "Global mappingfilename too long, ignored"); |
| + pFile = fOpenResource(szLeafname, szSuffix); |
| + if (pFile != NULL) { |
| + return pFile; |
| } |
| werr(0, "I can't open your mapping file (%s%s)\n" |
| "It is not in '%s" FILE_SEPARATOR ANTIWORD_DIR "' nor in '" |
| -- |
| 2.5.3.windows.1 |
| |