bool CModules::LoadModule(const CString& sModule, const CString& sArgs, CUser* pUser, CString& sRetMsg) { sRetMsg = ""; if (FindModule(sModule) != NULL) { sRetMsg = "Module [" + sModule + "] already loaded."; return false; } bool bSuccess; GLOBALMODULECALL(OnModuleLoading(sModule, sArgs, bSuccess, sRetMsg), pUser, NULL, return bSuccess); CString sModPath, sDataPath; bool bVersionMismatch; CModInfo Info; if (!FindModPath(sModule, sModPath, sDataPath)) { sRetMsg = "Unable to find module [" + sModule + "]"; return false; } ModHandle p = OpenModule(sModule, sModPath, bVersionMismatch, Info, sRetMsg); if (!p) return false; if (bVersionMismatch) { dlclose(p); sRetMsg = "Version mismatch, recompile this module."; return false; } if ((pUser == NULL) != Info.IsGlobal()) { dlclose(p); sRetMsg = "Module [" + sModule + "] is "; sRetMsg += Info.IsGlobal() ? "" : "not "; sRetMsg += "a global module."; return false; } CModule* pModule = NULL; if (pUser) { pModule = Info.GetLoader()(p, pUser, sModule, sDataPath); } else { pModule = Info.GetGlobalLoader()(p, sModule, sDataPath); } pModule->SetDescription(Info.GetDescription()); pModule->SetGlobal(Info.IsGlobal()); pModule->SetArgs(sArgs); pModule->SetModPath(CDir::ChangeDir(CZNC::Get().GetCurPath(), sModPath)); push_back(pModule); bool bLoaded; try { bLoaded = pModule->OnLoad(sArgs, sRetMsg); } catch (CModule::EModException) { bLoaded = false; sRetMsg = "Caught an exception"; } if (!bLoaded) { UnloadModule(sModule, sModPath); if (!sRetMsg.empty()) sRetMsg = "Module [" + sModule + "] aborted: " + sRetMsg; else sRetMsg = "Module [" + sModule + "] aborted."; return false; } if (!sRetMsg.empty()) { sRetMsg += "[" + sRetMsg + "] "; } sRetMsg += "[" + sModPath + "]"; return true; }
bool CModules::LoadModule(const CString& sModule, const CString& sArgs, CUser* pUser, CString& sRetMsg) { sRetMsg = ""; if (FindModule(sModule) != NULL) { sRetMsg = "Module [" + sModule + "] already loaded."; return false; } bool bSuccess; GLOBALMODULECALL(OnModuleLoading(sModule, sArgs, bSuccess, sRetMsg), pUser, NULL, return bSuccess); CString sModPath, sDataPath; CString sDesc; bool bVersionMismatch; bool bIsGlobal; if (!FindModPath(sModule, sModPath, sDataPath)) { sRetMsg = "Unable to find module [" + sModule + "]"; return false; } ModHandle p = OpenModule(sModule, sModPath, bVersionMismatch, bIsGlobal, sDesc, sRetMsg); if (!p) return false; if (bVersionMismatch) { dlclose(p); sRetMsg = "Version mismatch, recompile this module."; return false; } if ((pUser == NULL) != bIsGlobal) { dlclose(p); sRetMsg = "Module [" + sModule + "] is "; sRetMsg += (bIsGlobal) ? "" : "not "; sRetMsg += "a global module."; return false; } CModule* pModule = NULL; if (pUser) { typedef CModule* (*fp)(ModHandle, CUser* pUser, const CString& sModName, const CString& sDataPath); fp Load = (fp) dlsym(p, "ZNCModLoad"); if (!Load) { dlclose(p); sRetMsg = "Could not find ZNCModLoad() in module [" + sModule + "]"; return false; } pModule = Load(p, pUser, sModule, sDataPath); } else { typedef CModule* (*fp)(ModHandle, const CString& sModName, const CString& sDataPath); fp Load = (fp) dlsym(p, "ZNCModLoad"); if (!Load) { dlclose(p); sRetMsg = "Could not find ZNCModLoad() in module [" + sModule + "]"; return false; } pModule = Load(p, sModule, sDataPath); } pModule->SetDescription(sDesc); pModule->SetGlobal(bIsGlobal); pModule->SetArgs(sArgs); pModule->SetModPath(CDir::ChangeDir(CZNC::Get().GetCurPath(), sModPath)); push_back(pModule); bool bLoaded; try { bLoaded = pModule->OnLoad(sArgs, sRetMsg); } catch (CModule::EModException) { bLoaded = false; sRetMsg = "Caught an exception"; } if (!bLoaded) { UnloadModule(sModule, sModPath); if (!sRetMsg.empty()) sRetMsg = "Module [" + sModule + "] aborted: " + sRetMsg; else sRetMsg = "Module [" + sModule + "] aborted."; return false; } if (!sRetMsg.empty()) { sRetMsg = "Loaded module [" + sModule + "] [" + sRetMsg + "] [" + sModPath + "]"; } else { sRetMsg = "Loaded module [" + sModule + "] [" + sModPath + "]"; } return true; }
bool CModules::LoadModule(const CString& sModule, const CString& sArgs, CModInfo::EModuleType eType, CUser* pUser, CIRCNetwork *pNetwork, CString& sRetMsg) { sRetMsg = ""; if (FindModule(sModule) != NULL) { sRetMsg = "Module [" + sModule + "] already loaded."; return false; } bool bSuccess; bool bHandled = false; _GLOBALMODULECALL(OnModuleLoading(sModule, sArgs, eType, bSuccess, sRetMsg), pUser, pNetwork, NULL, &bHandled); if (bHandled) return bSuccess; CString sModPath, sDataPath; bool bVersionMismatch; CModInfo Info; if (!FindModPath(sModule, sModPath, sDataPath)) { sRetMsg = "Unable to find module [" + sModule + "]"; return false; } ModHandle p = OpenModule(sModule, sModPath, bVersionMismatch, Info, sRetMsg); if (!p) return false; if (bVersionMismatch) { dlclose(p); sRetMsg = "Version mismatch, recompile this module."; return false; } if (!Info.SupportsType(eType)) { dlclose(p); sRetMsg = "Module [" + sModule + "] does not support module type [" + CModInfo::ModuleTypeToString(eType) + "]."; return false; } if (!pUser && eType == CModInfo::UserModule) { dlclose(p); sRetMsg = "Module [" + sModule + "] requires a user."; return false; } if (!pNetwork && eType == CModInfo::NetworkModule) { dlclose(p); sRetMsg = "Module [" + sModule + "] requires a network."; return false; } CModule* pModule = Info.GetLoader()(p, pUser, pNetwork, sModule, sDataPath); pModule->SetDescription(Info.GetDescription()); pModule->SetType(eType); pModule->SetArgs(sArgs); pModule->SetModPath(CDir::ChangeDir(CZNC::Get().GetCurPath(), sModPath)); push_back(pModule); bool bLoaded; try { bLoaded = pModule->OnLoad(sArgs, sRetMsg); } catch (CModule::EModException) { bLoaded = false; sRetMsg = "Caught an exception"; } if (!bLoaded) { UnloadModule(sModule, sModPath); if (!sRetMsg.empty()) sRetMsg = "Module [" + sModule + "] aborted: " + sRetMsg; else sRetMsg = "Module [" + sModule + "] aborted."; return false; } if (!sRetMsg.empty()) { sRetMsg += "[" + sRetMsg + "] "; } sRetMsg += "[" + sModPath + "]"; return true; }