/*! Load the plugins. \param server The server object to use. */ int PluginsManager::load (Server *server) { list<string*> toRemove; HashMap<string, list<string>*> dependsOn; HashMap<string, PluginInfo*>::Iterator it = pluginsInfos.begin (); HashMap<string, bool> remove; while (it != pluginsInfos.end ()) { string name (it.getKey ()); PluginInfo* pinfo = *it; HashMap<string, pair<int, int>* >::Iterator depIt = pinfo->begin (); string msversion (MYSERVER_VERSION); size_t i = msversion.find ("-", 0); if (i != string::npos) msversion = msversion.substr (0, i); int msVersion = PluginInfo::convertVersion (msversion); if (msVersion < pinfo->getMyServerMinVersion () || msVersion > pinfo->getMyServerMaxVersion ()) server->log (MYSERVER_LOG_MSG_WARNING, _("Plugin `%s' not compatible with this version"), name.c_str ()); else remove.put (name, false); for (; depIt != pinfo->end (); depIt++) { string dname = depIt.getKey (); list<string>* deps = dependsOn.get (dname); if (!deps) { deps = new list<string > (); dependsOn.put (dname, deps); } deps->push_front (name); } it++; } list<string*>::iterator tRIt = toRemove.begin (); for (; tRIt != toRemove.end (); tRIt++) removePlugin (**tRIt); toRemove.clear (); HashMap<string, list<string>*>::Iterator dIt = dependsOn.begin (); for (; dIt != dependsOn.end (); dIt++) { string logBuf; string dname = dIt.getKey (); PluginInfo* pinfo = getPluginInfo (dname); if (!pinfo || pinfo->getVersion () == 0) remove.put (dname, true); list<string>* dependsList = (*dIt); if (!dependsList) continue; if (dependsList->empty ()) continue; bool rem = remove.get (dname); if (rem) { recursiveDependencesFallDown (server, dname, remove, dependsOn); continue; } HashMap<string, pair<int, int>* >::Iterator lit = pinfo->begin (); for (; lit != pinfo->end (); lit++) { string depN = lit.getKey (); PluginInfo* dep = getPluginInfo (depN); if (!dep || remove.get (depN)) { server->log (MYSERVER_LOG_MSG_WARNING, _("Missing plugin dependence `%s' --> `%s'"), dname.c_str (), depN.c_str ()); recursiveDependencesFallDown (server, dname, remove, dependsOn); break; } pair<int, int>* pdep = *lit; if (dep->getVersion () < pdep->first || dep->getVersion () > pdep->second) { recursiveDependencesFallDown (server, dname, remove, dependsOn); server->log (MYSERVER_LOG_MSG_WARNING, _("Plugin `%s' not compatible with this version"), dname.c_str ()); break; } } } HashMap<string, bool>::Iterator rIt = remove.begin (); for (; rIt != remove.end (); rIt++) { string name (rIt.getKey ()); if (*rIt) removePlugin (name); } for (it = pluginsInfos.begin (); it != pluginsInfos.end (); it++) (*it)->getPlugin ()->load (server); return 0; }
bool PluginInfo::pluginSignInfoIsEqual(const PluginInfo& pluginInfo) { return pluginName == pluginInfo.getName() && pluginAuthor == pluginInfo.getAuthor() && pluginVersion == pluginInfo.getVersion(); }
/*! Loads the plugin info. \param name The plugin name. \param path the plugin xml descriptor path. */ PluginInfo* PluginsManager::loadInfo (Server* server, string &name, string &path) { PluginInfo* pinfo = getPluginInfo (name); auto_ptr<PluginInfo> pinfoAutoPtr (NULL); if (!pinfo) pinfoAutoPtr.reset (pinfo = new PluginInfo (name)); else if (pinfo->getVersion () != 0) return NULL; XmlParser xml; if (xml.open (path, true)) { server->log (MYSERVER_LOG_MSG_ERROR, _("Error loading plugin `%s'"), name.c_str ()); return NULL; } auto_ptr<XmlXPathResult> xpathResPlugin = auto_ptr<XmlXPathResult> (xml.evaluateXpath ("/PLUGIN")); xmlNodeSetPtr nodes = xpathResPlugin->getNodeSet (); int size = (nodes) ? nodes->nodeNr : 0; if (size != 1) { server->log (MYSERVER_LOG_MSG_ERROR, _("Error loading plugin `%s': invalid plugin.xml"), name.c_str ()); return NULL; } if (xmlHasProp (nodes->nodeTab[0], (const xmlChar*) "min-version")) { xmlChar *minVersion = xmlGetProp (nodes->nodeTab[0], (const xmlChar*) "min-version"); string sMinVer ((char*) minVersion); pinfo->setMyServerMinVersion (PluginInfo::convertVersion (sMinVer)); } else { server->log (MYSERVER_LOG_MSG_ERROR, _("Error loading plugin `%s': invalid plugin.xml"), name.c_str ()); return NULL; } if (xmlHasProp (nodes->nodeTab[0], (const xmlChar*) "max-version")) { xmlChar* maxVersion = xmlGetProp (nodes->nodeTab[0], (const xmlChar*) "max-version"); string sMaxVer ((char*)maxVersion); pinfo->setMyServerMaxVersion (PluginInfo::convertVersion (sMaxVer)); } else { server->log (MYSERVER_LOG_MSG_ERROR, _("Error loading plugin `%s': invalid plugin.xml"), name.c_str ()); return NULL; } auto_ptr<XmlXPathResult> xpathResPluginName = auto_ptr<XmlXPathResult> (xml.evaluateXpath ("/PLUGIN/NAME/text ()")); nodes = xpathResPluginName->getNodeSet (); size = (nodes) ? nodes->nodeNr : 0; if (size != 1) { server->log (MYSERVER_LOG_MSG_ERROR, _("Error loading plugin `%s': invalid plugin.xml"), name.c_str ()); return NULL; } const char* cname = (const char*) nodes->nodeTab[0]->content; if (strcmp (name.c_str (), cname)) return NULL; auto_ptr<XmlXPathResult> xpathResPluginVersion = auto_ptr<XmlXPathResult> (xml.evaluateXpath ("/PLUGIN/VERSION/text ()")); nodes = xpathResPluginVersion->getNodeSet (); size = (nodes) ? nodes->nodeNr : 0; if (size != 1) { server->log (MYSERVER_LOG_MSG_ERROR, _("Error loading plugin `%s': invalid plugin.xml"), name.c_str ()); return NULL; } string verStr ((char*) nodes->nodeTab[0]->content); int version = PluginInfo::convertVersion (verStr); if (version != -1) pinfo->setVersion (version); else { server->log (MYSERVER_LOG_MSG_ERROR, _("Error loading plugin `%s': invalid plugin.xml"), name.c_str ()); return NULL; } auto_ptr<XmlXPathResult> xpathResDeps = auto_ptr<XmlXPathResult> (xml.evaluateXpath ("/PLUGIN/DEPENDS")); nodes = xpathResDeps->getNodeSet (); size = (nodes) ? nodes->nodeNr : 0; for (int i = 0; i < size; i++) { const char* depends = (const char*) nodes->nodeTab[i]->children->content; string nameDep (depends); if (!xmlHasProp (nodes->nodeTab[i], (const xmlChar*) "min-version") || !xmlHasProp (nodes->nodeTab[i], (const xmlChar*) "max-version")) { server->log (MYSERVER_LOG_MSG_ERROR, _("Error loading plugin `%s': invalid plugin.xml"), name.c_str ()); return NULL; } string minVerStr = ((char*) xmlGetProp (nodes->nodeTab[i], (const xmlChar*) "min-version")); string maxVerStr = ((char*) xmlGetProp (nodes->nodeTab[i], (const xmlChar*) "max-version")); int minVersion = PluginInfo::convertVersion (minVerStr); int maxVersion = PluginInfo::convertVersion (maxVerStr); if (minVersion == -1 || maxVersion == -1) { server->log (MYSERVER_LOG_MSG_ERROR, _("Error loading plugin `%s': invalid plugin.xml"), name.c_str ()); return NULL; } pinfo->addDependence (nameDep, minVersion, maxVersion); } pinfoAutoPtr.release (); return pinfo; }