From 6a79cc3e591e88bc38daa801f9d8269b3e0cfb25 Mon Sep 17 00:00:00 2001 From: def Date: Mon, 21 Sep 2020 00:07:31 +0200 Subject: [PATCH] Determine binary dir independently of data dir (fixes #2891) @Learath2 Could you check if this can be extended to also find the DDNet-Server executable on Mac? --- src/engine/shared/storage.cpp | 82 +++++++++++++++++++++++++++++------ 1 file changed, 68 insertions(+), 14 deletions(-) diff --git a/src/engine/shared/storage.cpp b/src/engine/shared/storage.cpp index 2f909d5d0..69c8fd511 100644 --- a/src/engine/shared/storage.cpp +++ b/src/engine/shared/storage.cpp @@ -3,6 +3,7 @@ #include "linereader.h" #include #include +#include #include class CStorage : public IStorage @@ -31,6 +32,9 @@ public: // get datadir FindDatadir(ppArguments[0]); + // get binarydir + FindBinarydir(ppArguments[0]); + // get currentdir if(!fs_getcwd(m_aCurrentdir, sizeof(m_aCurrentdir))) m_aCurrentdir[0] = 0; @@ -166,7 +170,6 @@ public: if(fs_is_dir("data/mapres")) { str_copy(m_aDatadir, "data", sizeof(m_aDatadir)); - str_copy(m_aBinarydir, "", sizeof(m_aBinarydir)); return; } @@ -175,11 +178,6 @@ public: if(fs_is_dir(DATA_DIR "/mapres")) { str_copy(m_aDatadir, DATA_DIR, sizeof(m_aDatadir)); -#if defined(BINARY_DIR) - str_copy(m_aBinarydir, BINARY_DIR, sizeof(m_aBinarydir)); -#else - str_copy(m_aBinarydir, DATA_DIR "/..", sizeof(m_aBinarydir)); -#endif return; } #endif @@ -194,15 +192,14 @@ public: if(Pos < MAX_PATH_LENGTH) { char aBuf[MAX_PATH_LENGTH]; - str_copy(m_aBinarydir, pArgv0, Pos + 1); - str_format(aBuf, sizeof(aBuf), "%s/data/mapres", m_aBinarydir); + char aDir[MAX_PATH_LENGTH]; + str_copy(aDir, pArgv0, Pos + 1); + str_format(aBuf, sizeof(aBuf), "%s/data/mapres", aDir); if(fs_is_dir(aBuf)) { - str_format(m_aDatadir, sizeof(m_aDatadir), "%s/data", m_aBinarydir); + str_format(m_aDatadir, sizeof(m_aDatadir), "%s/data", aDir); return; } - else - m_aBinarydir[0] = 0; } } @@ -226,7 +223,6 @@ public: str_format(aBuf, sizeof(aBuf), "%s/data/mapres", aDirs[i]); if(fs_is_dir(aBuf)) { - str_copy(m_aBinarydir, aDirs[i], sizeof(m_aDatadir)); str_format(m_aDatadir, sizeof(m_aDatadir), "%s/data", aDirs[i]); return; } @@ -234,8 +230,66 @@ public: } #endif - // no data-dir found - dbg_msg("storage", "warning no data directory found"); + dbg_msg("storage", "warning: no data directory found"); + } + + void FindBinarydir(const char *pArgv0) + { +#if defined(BINARY_DIR) + str_copy(m_aBinarydir, BINARY_DIR, sizeof(m_aBinarydir)); + return; +#endif + + // check for usable path in argv[0] + { + unsigned int Pos = ~0U; + for(unsigned i = 0; pArgv0[i]; i++) + if(pArgv0[i] == '/' || pArgv0[i] == '\\') + Pos = i; + + if(Pos < MAX_PATH_LENGTH) + { + char aBuf[MAX_PATH_LENGTH]; + str_copy(m_aBinarydir, pArgv0, Pos + 1); + str_format(aBuf, sizeof(aBuf), "%s/" PLAT_SERVER_EXEC, m_aBinarydir); + IOHANDLE File = io_open(aBuf, IOFLAG_READ); + if(File) + { + io_close(File); + return; + } + else + m_aBinarydir[0] = 0; + } + } + +#if defined(CONF_FAMILY_UNIX) + // check for all default locations + { + const char *aDirs[] = { + "/usr/bin", + "/usr/local/bin", + "/usr/pkg/bin", + "/opt/ddnet"}; + const int DirsCount = sizeof(aDirs) / sizeof(aDirs[0]); + + int i; + for(i = 0; i < DirsCount; i++) + { + char aBuf[128]; + str_format(aBuf, sizeof(aBuf), "%s/" PLAT_SERVER_EXEC, aDirs[i]); + IOHANDLE File = io_open(aBuf, IOFLAG_READ); + if(File) + { + io_close(File); + str_copy(m_aBinarydir, aDirs[i], sizeof(m_aDatadir)); + return; + } + } + } +#endif + + dbg_msg("storage", "warning: no binary directory found"); } virtual void ListDirectoryInfo(int Type, const char *pPath, FS_LISTDIR_INFO_CALLBACK pfnCallback, void *pUser)