diff --git a/src/lib/arch/unix/ArchPluginUnix.cpp b/src/lib/arch/unix/ArchPluginUnix.cpp index a1f36411..caeaab48 100644 --- a/src/lib/arch/unix/ArchPluginUnix.cpp +++ b/src/lib/arch/unix/ArchPluginUnix.cpp @@ -73,32 +73,41 @@ ArchPluginUnix::load() std::vector::iterator it; for (it = plugins.begin(); it != plugins.end(); ++it) { - LOG((CLOG_DEBUG "loading plugin: %s", (*it).c_str())); - String path = String(getPluginsDir()).append("/").append(*it); - void* library = dlopen(path.c_str(), RTLD_LAZY); + String filename = *it; + String path = synergy::string::sprintf( + "%s/%s", pluginsDir.c_str(), filename.c_str()); + String name = synergy::string::removeFileExt(filename.substr(3)); - if (library == NULL) { - LOG((CLOG_ERR "failed to load plugin '%s', error: %s", (*it).c_str(), dlerror())); + LOG((CLOG_DEBUG "loading plugin: %s", filename.c_str())); + void* handle = dlopen(path.c_str(), RTLD_LAZY); + + if (handle == NULL) { + LOG((CLOG_ERR "failed to load plugin '%s', error: %s", + filename.c_str(), dlerror())); continue; } - String filename = synergy::string::removeFileExt(*it); - size_t pos = filename.find("lib"); - String pluginName = filename.substr(pos + 3); - char* version = (char*)invoke(filename.c_str(), "version", NULL, library); - String expectedVersion(pluginVersion(pluginName.c_str())); - if (version != NULL && expectedVersion.compare(version) == 0) { - LOG((CLOG_DEBUG "loaded plugin: %s (%s)", (*it).c_str(), version)); - m_pluginTable.insert(std::make_pair(filename, library)); - } - else { - LOG((CLOG_ERR "plugin version doesn't match")); - LOG((CLOG_DEBUG "expected plugin version: %s actual plugin version: %s", - expectedVersion.c_str(), version)); - LOG((CLOG_ERR "skip plugin: %s", (*it).c_str())); - dlclose(library); + String expectedVersion = getExpectedPluginVersion(name.c_str()); + String currentVersion = getCurrentVersion(name, handle); + + if (currentVersion.empty() || (expectedVersion != currentVersion)) { + LOG((CLOG_ERR + "failed to load plugin '%s', " + "expected version %s but was %s", + filename.c_str(), + expectedVersion.c_str(), + currentVersion.empty() ? "unknown" : currentVersion.c_str())); + + dlclose(handle); + continue; } + + LOG((CLOG_DEBUG "plugin loaded: %s (version %s)", + filename.c_str(), + currentVersion.c_str())); + + m_pluginTable.insert(std::make_pair(name, handle)); } } @@ -204,6 +213,17 @@ ArchPluginUnix::getPluginsDir() return ARCH->getPluginDirectory(); } +String +ArchPluginUnix::getCurrentVersion(const String& name, void* handle) +{ + char* version = (char*)invoke(name.c_str(), "version", NULL, handle); + if (version == NULL) { + return ""; + } + + return version; +} + void sendEvent(const char* eventName, void* data) { diff --git a/src/lib/arch/unix/ArchPluginUnix.h b/src/lib/arch/unix/ArchPluginUnix.h index 894c675b..eeb14691 100644 --- a/src/lib/arch/unix/ArchPluginUnix.h +++ b/src/lib/arch/unix/ArchPluginUnix.h @@ -41,8 +41,9 @@ public: void** args, void* library = NULL); - private: +private: String getPluginsDir(); + String getCurrentVersion(const String& name, void* handle); private: PluginTable m_pluginTable;