From f680f242ff582f9b613d68ce63ca8306452f8508 Mon Sep 17 00:00:00 2001 From: psychon Date: Mon, 10 Aug 2009 18:58:55 +0000 Subject: [PATCH] Improve the error message from /msg *status loadmod Ever since r1505 our error messages when loading modules all were the same: "Unable to find modinfo" Improve this by giving the user all the information we offered before again. The most useful one here is most likely the result from dlerror(). This is done by adding a helper function CModules::OpenModule(). Most of its code is from CModules::LoadModule() and this function and CModules::GetModInfo() now both use this helper function for generating error messages. This commit adds a "#warning", don't worry I'm working on it. git-svn-id: https://znc.svn.sourceforge.net/svnroot/znc/trunk@1596 726aef4b-f618-498e-8847-2d620e286838 --- ClientCommand.cpp | 14 ++-- Modules.cpp | 191 +++++++++++++++++++++------------------------- Modules.h | 6 +- 3 files changed, 103 insertions(+), 108 deletions(-) diff --git a/ClientCommand.cpp b/ClientCommand.cpp index 0a558575..cfc64834 100644 --- a/ClientCommand.cpp +++ b/ClientCommand.cpp @@ -635,8 +635,9 @@ void CClient::UserCommand(CString& sLine) { #ifdef _MODULES CModInfo ModInfo; - if (!CZNC::Get().GetModules().GetModInfo(ModInfo, sMod)) { - PutStatus("Unable to find modinfo [" + sMod + "]"); + CString sRetMsg; + if (!CZNC::Get().GetModules().GetModInfo(ModInfo, sMod, sRetMsg)) { + PutStatus("Unable to find modinfo [" + sMod + "] [" + sRetMsg + "]"); return; } @@ -676,7 +677,9 @@ void CClient::UserCommand(CString& sLine) { } #ifdef _MODULES CModInfo ModInfo; - if (!CZNC::Get().GetModules().GetModInfo(ModInfo, sMod)) { + CString sRetMsg; +#warning If a module is removed while it is loaded, one can no longer unload it? + if (!CZNC::Get().GetModules().GetModInfo(ModInfo, sMod, sRetMsg)) { PutStatus("Unable to find modinfo for [" + sMod + "]"); return; } @@ -719,8 +722,9 @@ void CClient::UserCommand(CString& sLine) { } #ifdef _MODULES CModInfo ModInfo; - if (!CZNC::Get().GetModules().GetModInfo(ModInfo, sMod)) { - PutStatus("Unable to find modinfo for [" + sMod + "]"); + CString sRetMsg; + if (!CZNC::Get().GetModules().GetModInfo(ModInfo, sMod, sRetMsg)) { + PutStatus("Unable to find modinfo for [" + sMod + "] [" + sRetMsg + "]"); return; } diff --git a/Modules.cpp b/Modules.cpp index 1e3b6080..e90e2c39 100644 --- a/Modules.cpp +++ b/Modules.cpp @@ -715,79 +715,36 @@ CModule* CModules::FindModule(const CString& sModule) const { bool CModules::LoadModule(const CString& sModule, const CString& sArgs, CUser* pUser, CString& sRetMsg, bool bFake) { sRetMsg = ""; - for (unsigned int a = 0; a < sModule.length(); a++) { - if (((sModule[a] < '0') || (sModule[a] > '9')) && ((sModule[a] < 'a') || (sModule[a] > 'z')) && ((sModule[a] < 'A') || (sModule[a] > 'Z')) && (sModule[a] != '_')) { - sRetMsg = "Unable to load module [" + sModule + "] module names can only be letters, numbers, or underscores."; - return false; - } - } - if (FindModule(sModule) != NULL) { sRetMsg = "Module [" + sModule + "] already loaded."; return false; } - CString sModPath, sDataPath; - - if (!CZNC::Get().FindModPath(sModule, sModPath, sDataPath)) { - sRetMsg = "Unable to find module [" + sModule + "]"; - return false; - } - if (bFake) { - CModule* pModule = new CModule(NULL, sModule, sDataPath); + CModule* pModule = new CModule(NULL, sModule, ""); pModule->SetArgs(sArgs); pModule->SetDescription("<>"); pModule->SetFake(true); push_back(pModule); - sRetMsg = "Loaded fake module [" + sModule + "] [" + sModPath + "]"; + sRetMsg = "Loaded fake module [" + sModule + "]"; return true; } - unsigned int uDLFlags = RTLD_NOW; - uDLFlags |= (pUser) ? RTLD_LOCAL : RTLD_GLOBAL; + CString sModPath, sDataPath; + CString sDesc; + bool bVersionMismatch; + bool bIsGlobal; + ModHandle p = OpenModule(sModule, sModPath, sDataPath, bVersionMismatch, bIsGlobal, sDesc, sRetMsg); - ModHandle p = dlopen((sModPath).c_str(), uDLFlags); - - if (!p) { - sRetMsg = "Unable to load module [" + sModule + "] [" + dlerror() + "]"; + if (!p) return false; - } - typedef double (*dFP)(); - dFP Version = (dFP) dlsym(p, "ZNCModVersion"); - - if (!Version) { - dlclose(p); - sRetMsg = "Could not find ZNCModVersion() in module [" + sModule + "]"; - return false; - } - - if (CModule::GetCoreVersion() != Version()) { + if (bVersionMismatch) { dlclose(p); sRetMsg = "Version mismatch, recompile this module."; return false; } - typedef bool (*bFP)(); - bFP IsGlobal = (bFP) dlsym(p, "ZNCModGlobal"); - - if (!IsGlobal) { - dlclose(p); - sRetMsg = "Could not find ZNCModGlobal() in module [" + sModule + "]"; - return false; - } - - typedef CString (*sFP)(); - sFP GetDesc = (sFP) dlsym(p, "ZNCModDescription"); - - if (!GetDesc) { - dlclose(p); - sRetMsg = "Could not find ZNCModDescription() in module [" + sModule + "]"; - return false; - } - - bool bIsGlobal = IsGlobal(); if ((pUser == NULL) != bIsGlobal) { dlclose(p); sRetMsg = "Module [" + sModule + "] is "; @@ -824,7 +781,7 @@ bool CModules::LoadModule(const CString& sModule, const CString& sArgs, CUser* p pModule = Load(p, sModule, sDataPath); } - pModule->SetDescription(GetDesc()); + pModule->SetDescription(sDesc); pModule->SetGlobal(bIsGlobal); pModule->SetArgs(sArgs); push_back(pModule); @@ -927,59 +884,23 @@ bool CModules::ReloadModule(const CString& sModule, const CString& sArgs, CUser* return true; } -bool CModules::GetModInfo(CModInfo& ModInfo, const CString& sModule) { - for (unsigned int a = 0; a < sModule.length(); a++) { - const char& c = sModule[a]; - - if ((c < '0' || c > '9') && (c < 'a' || c > 'z') && (c < 'A' || c > 'Z') && c != '_') { - return false; - } - } - +bool CModules::GetModInfo(CModInfo& ModInfo, const CString& sModule, CString& sRetMsg) { CString sModPath, sTmp; + CString sDesc; + bool bVersionMismatch; + bool bIsGlobal; - if (!CZNC::Get().FindModPath(sModule, sModPath, sTmp)) { + ModHandle p = OpenModule(sModule, sModPath, sTmp, bVersionMismatch, bIsGlobal, sDesc, sRetMsg); + + if (!p) return false; - } - unsigned int uDLFlags = RTLD_LAZY | RTLD_LOCAL; - - ModHandle p = dlopen((sModPath).c_str(), uDLFlags); - - if (!p) { - return false; - } - - typedef double (*dFP)(); - dFP Version = (dFP) dlsym(p, "ZNCModVersion"); - - if (!Version) { - dlclose(p); - return false; - } - - typedef bool (*bFP)(); - bFP IsGlobal = (bFP) dlsym(p, "ZNCModGlobal"); - - if (!IsGlobal) { - dlclose(p); - return false; - } - - typedef CString (*sFP)(); - sFP GetDescription = (sFP) dlsym(p, "ZNCModDescription"); - - if (!GetDescription) { - dlclose(p); - return false; - } - - ModInfo.SetGlobal(IsGlobal()); - ModInfo.SetDescription(GetDescription()); + ModInfo.SetGlobal(bIsGlobal); + ModInfo.SetDescription(sDesc); ModInfo.SetName(sModule); ModInfo.SetPath(sModPath); - if (CModule::GetCoreVersion() != Version()) { + if (bVersionMismatch) { ModInfo.SetDescription("--- Version mismatch, recompile this module. ---"); } @@ -1001,7 +922,8 @@ void CModules::GetAvailableMods(set& ssMods, bool bGlobal) { CModInfo ModInfo; sName.RightChomp(3); - if (GetModInfo(ModInfo, sName)) { + CString sIgnoreRetMsg; + if (GetModInfo(ModInfo, sName, sIgnoreRetMsg)) { if (ModInfo.IsGlobal() == bGlobal) { ssMods.insert(ModInfo); } @@ -1015,7 +937,8 @@ void CModules::GetAvailableMods(set& ssMods, bool bGlobal) { CModInfo ModInfo; sName.RightChomp(3); - if (GetModInfo(ModInfo, sName)) { + CString sIgnoreRetMsg; + if (GetModInfo(ModInfo, sName, sIgnoreRetMsg)) { if (ModInfo.IsGlobal() == bGlobal) { ssMods.insert(ModInfo); } @@ -1029,7 +952,8 @@ void CModules::GetAvailableMods(set& ssMods, bool bGlobal) { CModInfo ModInfo; sName.RightChomp(3); - if (GetModInfo(ModInfo, sName)) { + CString sIgnoreRetMsg; + if (GetModInfo(ModInfo, sName, sIgnoreRetMsg)) { if (ModInfo.IsGlobal() == bGlobal) { ssMods.insert(ModInfo); } @@ -1037,4 +961,67 @@ void CModules::GetAvailableMods(set& ssMods, bool bGlobal) { } } +ModHandle CModules::OpenModule(const CString& sModule, CString& sModPath, CString& sDataPath, + bool &bVersionMismatch, bool &bIsGlobal, CString& sDesc, CString& sRetMsg) +{ + for (unsigned int a = 0; a < sModule.length(); a++) { + if (((sModule[a] < '0') || (sModule[a] > '9')) && ((sModule[a] < 'a') || (sModule[a] > 'z')) && ((sModule[a] < 'A') || (sModule[a] > 'Z')) && (sModule[a] != '_')) { + sRetMsg = "Module names can only contain letters, numbers and underscores, [" + sModule + "] is invalid."; + return NULL; + } + } + + if (!CZNC::Get().FindModPath(sModule, sModPath, sDataPath)) { + sRetMsg = "Unable to find module [" + sModule + "]"; + return NULL; + } + + ModHandle p = dlopen((sModPath).c_str(), RTLD_NOW | RTLD_LOCAL); + + if (!p) { + sRetMsg = "Unable to open module [" + sModule + "] [" + dlerror() + "]"; + return NULL; + } + + typedef double (*dFP)(); + dFP Version = (dFP) dlsym(p, "ZNCModVersion"); + + if (!Version) { + dlclose(p); + sRetMsg = "Could not find ZNCModVersion() in module [" + sModule + "]"; + return NULL; + } + + typedef bool (*bFP)(); + bFP IsGlobal = (bFP) dlsym(p, "ZNCModGlobal"); + + if (!IsGlobal) { + dlclose(p); + sRetMsg = "Could not find ZNCModGlobal() in module [" + sModule + "]"; + return NULL; + } + + typedef CString (*sFP)(); + sFP GetDesc = (sFP) dlsym(p, "ZNCModDescription"); + + if (!GetDesc) { + dlclose(p); + sRetMsg = "Could not find ZNCModDescription() in module [" + sModule + "]"; + return false; + } + + bIsGlobal = IsGlobal(); + sDesc = GetDesc(); + + if (CModule::GetCoreVersion() != Version()) { + bVersionMismatch = true; + sRetMsg = "Version mismatch, recompile this module."; + } else { + sRetMsg = ""; + bVersionMismatch = false; + } + + return p; +} + #endif // _MODULES diff --git a/Modules.h b/Modules.h index f16bdd66..f35889aa 100644 --- a/Modules.h +++ b/Modules.h @@ -460,9 +460,13 @@ public: bool UnloadModule(const CString& sModule, CString& sRetMsg); bool ReloadModule(const CString& sModule, const CString& sArgs, CUser* pUser, CString& sRetMsg); - bool GetModInfo(CModInfo& ModInfo, const CString& sModule); + bool GetModInfo(CModInfo& ModInfo, const CString& sModule, CString &sRetMsg); void GetAvailableMods(set& ssMods, bool bGlobal = false); +private: + ModHandle OpenModule(const CString& sModule, CString& sModPath, CString& sDataPath, + bool &bVersionMismatch, bool &bIsGlobal, CString& sDesc, CString& sRetMsg); + protected: CUser* m_pUser; CClient* m_pClient;