bool CModules::LoadModule(const CString& sModule, const CString& sArgs, CUser* pUser, CString& sRetMsg, bool bFake) { sRetMsg = ""; if (FindModule(sModule) != NULL) { sRetMsg = "Module [" + sModule + "] already loaded."; return false; } if (bFake) { CModule* pModule = new CModule(NULL, sModule, ""); pModule->SetArgs(sArgs); pModule->SetDescription("<<Fake Module>>"); pModule->SetFake(true); push_back(pModule); sRetMsg = "Loaded fake module [" + sModule + "]"; return true; } 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); 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); 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, 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, 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; }