From 0e215f112a122b1eeabae42e73417f98ad228266 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Mon, 2 Apr 2012 13:09:33 +0200 Subject: [PATCH] Fixed search path problems. --- base/application.cpp | 93 +++++++++++++++++++++++++++++++++++- base/application.h | 6 +++ base/base.vcxproj | 4 +- base/unix.h | 6 +++ base/win32.h | 3 ++ icinga/icingaapplication.cpp | 17 ++++++- icinga/icingaapplication.h | 2 + 7 files changed, 126 insertions(+), 5 deletions(-) diff --git a/base/application.cpp b/base/application.cpp index 9c1c5e364..37c226728 100644 --- a/base/application.cpp +++ b/base/application.cpp @@ -188,7 +188,7 @@ Component::RefType Application::LoadComponent(string path, ConfigObject::RefType lt_dlhandle hModule = 0; lt_dladvise advise; - if (!lt_dladvise_init(&advise) && !lt_dladvise_global(&advise)) { + if (!lt_dladvise_init(&advise) && !lt_dladvise_local(&advise)) { hModule = lt_dlopenadvise(path.c_str(), advise); } @@ -199,7 +199,7 @@ Component::RefType Application::LoadComponent(string path, ConfigObject::RefType throw exception(/*"Could not load module"*/); #ifdef _WIN32 - pCreateComponent = (Component *(*)())GetProcAddress(hModule, ); + pCreateComponent = (Component *(*)())GetProcAddress(hModule, "CreateComponent"); #else /* _WIN32 */ pCreateComponent = (Component *(*)())lt_dlsym(hModule, "CreateComponent"); #endif /* _WIN32 */ @@ -256,3 +256,92 @@ void Application::Log(const char *format, ...) fprintf(stderr, "%s\n", message); } +vector& Application::GetArguments(void) +{ + return m_Arguments; +} + +string Application::GetExeDirectory(void) +{ + static string ExePath; + + if (ExePath.length() != 0) + return ExePath; + +#ifndef _WIN32 + char Buf[MAXPATHLEN], Cwd[MAXPATHLEN]; + char *PathEnv, *Directory, PathTest[MAXPATHLEN], FullExePath[MAXPATHLEN]; + bool FoundPath; + + const char *argv0 = m_Arguments[0].c_str(); + + if (getcwd(Cwd, sizeof(Cwd)) == NULL) + throw exception(/*"getcwd() failed"*/); + + if (argv0[0] != '/') + snprintf(FullExePath, sizeof(FullExePath), "%s/%s", Cwd, argv0); + else + strncpy(FullExePath, argv0, sizeof(FullExePath)); + + if (strchr(argv0, '/') == NULL) { + PathEnv = getenv("PATH"); + + if (PathEnv != NULL) { + PathEnv = strdup(PathEnv); + + if (PathEnv == NULL) + throw exception(/*"strdup() failed"*/); + + FoundPath = false; + + for (Directory = strtok(PathEnv, ":"); Directory != NULL; Directory = strtok(NULL, ":")) { + if (snprintf(PathTest, sizeof(PathTest), "%s/%s", Directory, argv0) < 0) + throw exception(/*"snprintf() failed"*/); + + if (access(PathTest, X_OK) == 0) { + strncpy(FullExePath, PathTest, sizeof(FullExePath)); + + FoundPath = true; + + break; + } + } + + free(PathEnv); + + if (!FoundPath) + throw exception(/*"Could not determine executable path."*/); + } + } + + if (realpath(FullExePath, Buf) == NULL) + throw exception(/*"realpath() failed"*/); + + // remove filename + char *LastSlash = strrchr(Buf, '/'); + + if (LastSlash != NULL) + *LastSlash = '\0'; + + ExePath = string(Buf); +#else /* _WIN32 */ + char FullExePath[MAXPATHLEN]; + + GetModuleFileName(NULL, FullExePath, MAXPATHLEN); + + PathRemoveFileSpec(FullExePath); + + ExePath = string(FullExePath); +#endif /* _WIN32 */ + + return ExePath; +} + +void Application::AddComponentSearchDir(string componentDirectory) +{ +#ifdef _WIN32 + SetDllDirectory(componentDirectory.c_str()); +#else /* _WIN32 */ + lt_dladdsearchdir(componentDirectory.c_str()); +#endif /* _WIN32 */ +} diff --git a/base/application.h b/base/application.h index 59dfda905..212730b65 100644 --- a/base/application.h +++ b/base/application.h @@ -10,6 +10,7 @@ private: bool m_ShuttingDown; ConfigHive::RefType m_ConfigHive; map< string, shared_ptr > m_Components; + vector m_Arguments; public: typedef shared_ptr RefType; @@ -22,6 +23,8 @@ public: virtual int Main(const vector& args) = 0; + vector& GetArguments(void); + void RunEventLoop(void); bool Daemonize(void); void Shutdown(void); @@ -33,6 +36,9 @@ public: shared_ptr LoadComponent(string path, ConfigObject::RefType componentConfig); void UnloadComponent(string name); shared_ptr GetComponent(string name); + void AddComponentSearchDir(string componentDirectory); + + string GetExeDirectory(void); }; template diff --git a/base/base.vcxproj b/base/base.vcxproj index 389883f45..3802c4fa3 100644 --- a/base/base.vcxproj +++ b/base/base.vcxproj @@ -94,7 +94,7 @@ ws2_32.lib;imagehlp.lib;%(AdditionalDependencies) - ws2_32.lib + ws2_32.lib;shlwapi.lib @@ -114,7 +114,7 @@ ws2_32.lib;imagehlp.lib;%(AdditionalDependencies) - ws2_32.lib + ws2_32.lib;shlwapi.lib diff --git a/base/unix.h b/base/unix.h index de9892be3..9876ab5cf 100644 --- a/base/unix.h +++ b/base/unix.h @@ -19,6 +19,12 @@ void closesocket(SOCKET fd); #define ioctlsocket ioctl +#ifndef PATH_MAX +# define PATH_MAX 1024 +#endif /* PATH_MAX */ + +#define MAXPATHLEN PATH_MAX + /* default visibility takes care of exported symbols */ #define I2_EXPORT #define I2_IMPORT diff --git a/base/win32.h b/base/win32.h index 44b9fc86f..fe6d5ba6f 100644 --- a/base/win32.h +++ b/base/win32.h @@ -4,9 +4,12 @@ #define NOGDI #include #include +#include typedef int socklen_t; +#define MAXPATHLEN MAX_PATH + #define I2_EXPORT __declspec(dllexport) #define I2_IMPORT __declspec(dllimport) diff --git a/icinga/icingaapplication.cpp b/icinga/icingaapplication.cpp index b7144ca10..cdeefa930 100644 --- a/icinga/icingaapplication.cpp +++ b/icinga/icingaapplication.cpp @@ -22,6 +22,16 @@ int IcingaApplication::Main(const vector& args) cout << "Icinga component loader (version: " << ICINGA_VERSION << ")" << endl; #endif /* _WIN32 */ + if (args.size() < 2) { + PrintUsage(args[0]); + return EXIT_FAILURE; + } + +#ifndef _WIN32 + string componentDirectory = GetExeDirectory() + "../lib/icinga"; + AddComponentSearchDir(componentDirectory); +#endif /* _WIN32 */ + GetConfigHive()->OnObjectCreated.bind(bind_weak(&IcingaApplication::ConfigObjectCreatedHandler, shared_from_this())); GetConfigHive()->OnObjectRemoved.bind(bind_weak(&IcingaApplication::ConfigObjectRemovedHandler, shared_from_this())); @@ -33,7 +43,12 @@ int IcingaApplication::Main(const vector& args) RunEventLoop(); - return 0; + return EXIT_SUCCESS; +} + +void IcingaApplication::PrintUsage(const string& programPath) +{ + cout << "Syntax: " << programPath << " " << endl; } ConnectionManager::RefType IcingaApplication::GetConnectionManager(void) diff --git a/icinga/icingaapplication.h b/icinga/icingaapplication.h index f7f92d0a4..3c51bcfee 100644 --- a/icinga/icingaapplication.h +++ b/icinga/icingaapplication.h @@ -20,6 +20,8 @@ public: virtual int Main(const vector& args); + void PrintUsage(const string& programPath); + virtual ConnectionManager::RefType GetConnectionManager(void); };