From aaaafcc4b7f7ec582f7a39e1d93f61f218f406ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 9 Feb 2012 17:48:30 -0500 Subject: [PATCH] libfreerdp-utils: improve freerdp_load_plugin --- cmake/ConfigOptions.cmake | 2 +- config.h.in | 2 +- include/freerdp/utils/file.h | 2 ++ libfreerdp-channels/libchannels.c | 6 ++-- libfreerdp-utils/file.c | 54 +++++++++++++++++++++++++++++++ libfreerdp-utils/load_plugin.c | 39 ++++++++++++++-------- 6 files changed, 88 insertions(+), 17 deletions(-) diff --git a/cmake/ConfigOptions.cmake b/cmake/ConfigOptions.cmake index d59a04e9b..995d7a869 100644 --- a/cmake/ConfigOptions.cmake +++ b/cmake/ConfigOptions.cmake @@ -1,5 +1,5 @@ option(WITH_DEBUG_TRANSPORT "Print transport debug messages." OFF) -option(WITH_DEBUG_CHANMAN "Print channel manager debug messages." OFF) +option(WITH_DEBUG_CHANNELS "Print channel manager debug messages." OFF) option(WITH_DEBUG_SVC "Print static virtual channel debug messages." OFF) option(WITH_DEBUG_DVC "Print dynamic virtual channel debug messages." OFF) option(WITH_DEBUG_KBD "Print keyboard related debug messages." OFF) diff --git a/config.h.in b/config.h.in index bc5770ee4..742876440 100644 --- a/config.h.in +++ b/config.h.in @@ -23,7 +23,7 @@ /* Options */ #cmakedefine WITH_DEBUG_TRANSPORT -#cmakedefine WITH_DEBUG_CHANMAN +#cmakedefine WITH_DEBUG_CHANNELS #cmakedefine WITH_DEBUG_SVC #cmakedefine WITH_DEBUG_DVC #cmakedefine WITH_DEBUG_KBD diff --git a/include/freerdp/utils/file.h b/include/freerdp/utils/file.h index da74b81e2..7922a9d46 100644 --- a/include/freerdp/utils/file.h +++ b/include/freerdp/utils/file.h @@ -30,7 +30,9 @@ FREERDP_API char* freerdp_get_home_path(rdpSettings* settings); FREERDP_API char* freerdp_get_config_path(rdpSettings* settings); FREERDP_API char* freerdp_get_current_path(rdpSettings* settings); FREERDP_API char* freerdp_construct_path(char* base_path, char* relative_path); +FREERDP_API char* freerdp_append_shared_library_suffix(char* file_path); FREERDP_API char* freerdp_get_parent_path(char* base_path, int depth); +FREERDP_API boolean freerdp_path_contains_separator(char* path); FREERDP_API boolean freerdp_detect_development_mode(rdpSettings* settings); FREERDP_API void freerdp_detect_paths(rdpSettings* settings); diff --git a/libfreerdp-channels/libchannels.c b/libfreerdp-channels/libchannels.c index 13080833a..c16548bc1 100644 --- a/libfreerdp-channels/libchannels.c +++ b/libfreerdp-channels/libchannels.c @@ -683,7 +683,7 @@ int freerdp_channels_load_plugin(rdpChannels* channels, rdpSettings* settings, c } lib = channels->libs_data + channels->num_libs_data; - lib->entry = (PVIRTUALCHANNELENTRY)freerdp_load_plugin(name, CHANNEL_EXPORT_FUNC_NAME); + lib->entry = (PVIRTUALCHANNELENTRY) freerdp_load_plugin(name, CHANNEL_EXPORT_FUNC_NAME); if (lib->entry == NULL) { @@ -705,9 +705,11 @@ int freerdp_channels_load_plugin(rdpChannels* channels, rdpSettings* settings, c channels->settings = settings; freerdp_mutex_lock(g_mutex_init); + g_init_channels = channels; - ok = lib->entry((PCHANNEL_ENTRY_POINTS)&ep); + ok = lib->entry((PCHANNEL_ENTRY_POINTS) &ep); g_init_channels = NULL; + freerdp_mutex_unlock(g_mutex_init); /* disable MyVirtualChannelInit */ diff --git a/libfreerdp-utils/file.c b/libfreerdp-utils/file.c index 0f242c1f2..91746bbe8 100644 --- a/libfreerdp-utils/file.c +++ b/libfreerdp-utils/file.c @@ -47,6 +47,14 @@ #define HOME_ENV_VARIABLE "HOMEPATH" #endif +#ifdef _WIN32 +#define SHARED_LIB_SUFFIX ".dll" +#elif __APPLE__ +#define SHARED_LIB_SUFFIX ".dylib" +#else +#define SHARED_LIB_SUFFIX ".so" +#endif + #define FREERDP_CONFIG_DIR ".freerdp" #define PARENT_PATH ".." PATH_SEPARATOR_STR @@ -118,6 +126,41 @@ char* freerdp_construct_path(char* base_path, char* relative_path) return path; } +char* freerdp_append_shared_library_suffix(char* file_path) +{ + char* p; + char* path = NULL; + int file_path_length; + int shared_lib_suffix_length; + + if (file_path == NULL) + return NULL; + + file_path_length = strlen(file_path); + shared_lib_suffix_length = strlen(SHARED_LIB_SUFFIX); + + if (file_path_length >= shared_lib_suffix_length) + { + p = &file_path[file_path_length - shared_lib_suffix_length]; + + if (strcmp(p, SHARED_LIB_SUFFIX) != 0) + { + path = xmalloc(file_path_length + shared_lib_suffix_length + 1); + sprintf(path, "%s%s", file_path, SHARED_LIB_SUFFIX); + } + else + { + path = xstrdup(file_path); + } + } + else + { + path = xstrdup(file_path); + } + + return path; +} + char* freerdp_get_parent_path(char* base_path, int depth) { int i; @@ -154,6 +197,17 @@ char* freerdp_get_parent_path(char* base_path, int depth) return path; } +boolean freerdp_path_contains_separator(char* path) +{ + if (path == NULL) + return false; + + if (strchr(path, PATH_SEPARATOR_CHR) == NULL) + return false; + + return true; +} + /* detects if we are running from the source tree */ boolean freerdp_detect_development_mode(rdpSettings* settings) diff --git a/libfreerdp-utils/load_plugin.c b/libfreerdp-utils/load_plugin.c index 2247312d4..72a60722b 100644 --- a/libfreerdp-utils/load_plugin.c +++ b/libfreerdp-utils/load_plugin.c @@ -20,7 +20,9 @@ #include #include #include +#include #include +#include #include #ifdef _WIN32 @@ -30,8 +32,6 @@ #define DLSYM(f, n) GetProcAddress(f, n) #define DLCLOSE(f) FreeLibrary(f) #define DLERROR() "" -#define PATH_SEPARATOR '\\' -#define PLUGIN_EXT "dll" #else @@ -41,38 +41,51 @@ #define DLSYM(f, n) dlsym(f, n) #define DLCLOSE(f) dlclose(f) #define DLERROR() dlerror() -#define PATH_SEPARATOR '/' - -#ifdef __APPLE__ -#define PLUGIN_EXT "dylib" -#else -#define PLUGIN_EXT "so" -#endif #endif void* freerdp_load_plugin(const char* name, const char* entry_name) { - char path[255]; + char* path; void* module; void* entry; + char* suffixed_name; - if (strchr(name, PATH_SEPARATOR) == NULL) - snprintf(path, sizeof(path), PLUGIN_PATH "%c%s." PLUGIN_EXT, PATH_SEPARATOR, name); + suffixed_name = freerdp_append_shared_library_suffix((char*) name); + + if (!freerdp_path_contains_separator(suffixed_name)) + { + /* no explicit path given, use default path */ + path = freerdp_construct_path(PLUGIN_PATH, suffixed_name); + } else - strncpy(path, name, sizeof(path)); + { + /* explicit path given, use it instead of default path */ + path = xstrdup(suffixed_name); + } module = DLOPEN(path); + if (module == NULL) { printf("freerdp_load_plugin: failed to open %s: %s\n", path, DLERROR()); + xfree(suffixed_name); + xfree(path); return NULL; } + entry = DLSYM(module, entry_name); + if (entry == NULL) { printf("freerdp_load_plugin: failed to load %s: %s\n", path, DLERROR()); + xfree(suffixed_name); + xfree(path); return NULL; } + + xfree(suffixed_name); + xfree(path); + return entry; }