diff --git a/ClientCommand.cpp b/ClientCommand.cpp index 2554de5a..80decb72 100644 --- a/ClientCommand.cpp +++ b/ClientCommand.cpp @@ -517,7 +517,7 @@ void CClient::UserCommand(CString& sLine) { if (m_pUser->IsAdmin()) { set ssGlobalMods; - CZNC::Get().GetModules().GetAvailableMods(ssGlobalMods, true); + CZNC::Get().GetModules().GetAvailableMods(ssGlobalMods, ModuleTypeGlobal); if (ssGlobalMods.empty()) { PutStatus("No global modules available."); @@ -585,20 +585,23 @@ void CClient::UserCommand(CString& sLine) { return; } - bool bGlobal = ModInfo.IsGlobal(); - - if (bGlobal && !m_pUser->IsAdmin()) { - PutStatus("Unable to load global module [" + sMod + "] Access Denied."); - return; - } - CString sModRet; - bool b; + bool b = false; - if (bGlobal) { - b = CZNC::Get().GetModules().LoadModule(sMod, sArgs, NULL, sModRet); - } else { - b = m_pUser->GetModules().LoadModule(sMod, sArgs, m_pUser, sModRet); + switch (ModInfo.GetType()) { + case ModuleTypeGlobal: + if (m_pUser->IsAdmin()) { + b = CZNC::Get().GetModules().LoadModule(sMod, sArgs, NULL, sModRet); + } else { + sModRet = "Unable to load global module [" + sMod + "] Access Denied."; + } + break; + case ModuleTypeUser: + b = m_pUser->GetModules().LoadModule(sMod, sArgs, m_pUser, sModRet); + break; + default: + sModRet = "Unable to load module [" + sMod + "] Unknown module type"; + break; } if (b) @@ -655,19 +658,22 @@ void CClient::UserCommand(CString& sLine) { return; } - bool bGlobal = ModInfo.IsGlobal(); - - if (bGlobal && !m_pUser->IsAdmin()) { - PutStatus("Unable to reload global module [" + sMod + "] Access Denied."); - return; - } - CString sModRet; - if (bGlobal) { - CZNC::Get().GetModules().ReloadModule(sMod, sArgs, NULL, sModRet); - } else { - m_pUser->GetModules().ReloadModule(sMod, sArgs, m_pUser, sModRet); + switch (ModInfo.GetType()) { + case ModuleTypeGlobal: + if (!m_pUser->IsAdmin()) { + PutStatus("Unable to reload modules. Access Denied."); + return; + } + CZNC::Get().GetModules().ReloadModule(sMod, sArgs, NULL, sModRet); + break; + case ModuleTypeUser: + m_pUser->GetModules().ReloadModule(sMod, sArgs, m_pUser, sModRet); + break; + default: + sModRet = "Unable to reload module [" + sMod + "] Unknown module type"; + break; } PutStatus(sModRet); diff --git a/Modules.cpp b/Modules.cpp index 234ca8d7..57872645 100644 --- a/Modules.cpp +++ b/Modules.cpp @@ -105,7 +105,7 @@ const CString& CTimer::GetDescription() const { return m_sDescription; } CModule::CModule(ModHandle pDLL, CUser* pUser, const CString& sModName, const CString& sDataDir) { - m_bGlobal = false; + m_eType = ModuleTypeUser; m_pDLL = pDLL; m_pManager = &(CZNC::Get().GetManager());; m_pUser = pUser; @@ -588,7 +588,7 @@ CModule::EModRet CGlobalModule::OnModuleUnloading(CModule* pModule, bool& bSucce } CModule::EModRet CGlobalModule::OnGetModInfo(CModInfo& ModInfo, const CString& sModule, bool& bSuccess, CString& sRetMsg) { return CONTINUE; } -void CGlobalModule::OnGetAvailableMods(set& ssMods, bool bGlobal) {} +void CGlobalModule::OnGetAvailableMods(set& ssMods, EModuleType eType) {} CModules::CModules() { @@ -788,8 +788,8 @@ bool CGlobalModules::OnGetModInfo(CModInfo& ModInfo, const CString& sModule, GLOBALMODHALTCHK(OnGetModInfo(ModInfo, sModule, bSuccess, sRetMsg)); } -bool CGlobalModules::OnGetAvailableMods(set& ssMods, bool bGlobal) { - GLOBALMODCALL(OnGetAvailableMods(ssMods, bGlobal)); +bool CGlobalModules::OnGetAvailableMods(set& ssMods, EModuleType eType) { + GLOBALMODCALL(OnGetAvailableMods(ssMods, eType)); return false; } @@ -835,10 +835,10 @@ bool CModules::LoadModule(const CString& sModule, const CString& sArgs, CUser* p return false; } - if ((pUser == NULL) != Info.IsGlobal()) { + if ((pUser == NULL) != (Info.GetType() == ModuleTypeGlobal)) { dlclose(p); sRetMsg = "Module [" + sModule + "] is "; - sRetMsg += Info.IsGlobal() ? "" : "not "; + sRetMsg += (Info.GetType() == ModuleTypeGlobal) ? "" : "not "; sRetMsg += "a global module."; return false; } @@ -852,7 +852,7 @@ bool CModules::LoadModule(const CString& sModule, const CString& sArgs, CUser* p } pModule->SetDescription(Info.GetDescription()); - pModule->SetGlobal(Info.IsGlobal()); + pModule->SetType(Info.GetType()); pModule->SetArgs(sArgs); pModule->SetModPath(CDir::ChangeDir(CZNC::Get().GetCurPath(), sModPath)); push_back(pModule); @@ -970,7 +970,7 @@ bool CModules::GetModPathInfo(CModInfo& ModInfo, const CString& sModule, const C return true; } -void CModules::GetAvailableMods(set& ssMods, bool bGlobal) { +void CModules::GetAvailableMods(set& ssMods, EModuleType eType) { ssMods.clear(); unsigned int a = 0; @@ -991,14 +991,14 @@ void CModules::GetAvailableMods(set& ssMods, bool bGlobal) { CString sIgnoreRetMsg; if (GetModPathInfo(ModInfo, sName, sPath, sIgnoreRetMsg)) { - if (ModInfo.IsGlobal() == bGlobal) { + if (ModInfo.GetType() == eType) { ssMods.insert(ModInfo); } } } } - GLOBALMODULECALL(OnGetAvailableMods(ssMods, bGlobal), NULL, NULL, NOTHING); + GLOBALMODULECALL(OnGetAvailableMods(ssMods, eType), NULL, NULL, NOTHING); } bool CModules::FindModPath(const CString& sModule, CString& sModPath, diff --git a/Modules.h b/Modules.h index ac8709b1..e92b4e49 100644 --- a/Modules.h +++ b/Modules.h @@ -40,6 +40,11 @@ class CModInfo; #endif #endif +typedef enum { + ModuleTypeGlobal, + ModuleTypeUser +} EModuleType; + typedef void* ModHandle; template void TModInfo(CModInfo& Info) {} @@ -59,14 +64,14 @@ template CGlobalModule* TModLoadGlobal(ModHandle p, # define MODULE_EXPORT #endif -#define MODCOMMONDEFS(CLASS, DESCRIPTION, GLOBAL, LOADER) \ +#define MODCOMMONDEFS(CLASS, DESCRIPTION, TYPE, LOADER) \ extern "C" { \ MODULE_EXPORT bool ZNCModInfo(double dCoreVersion, CModInfo& Info); \ bool ZNCModInfo(double dCoreVersion, CModInfo& Info) { \ if (dCoreVersion != VERSION) \ return false; \ Info.SetDescription(DESCRIPTION); \ - Info.SetGlobal(GLOBAL); \ + Info.SetType(TYPE); \ LOADER; \ TModInfo(Info); \ return true; \ @@ -101,7 +106,7 @@ template CGlobalModule* TModLoadGlobal(ModHandle p, * @see For global modules you need GLOBALMODULEDEFS. */ #define MODULEDEFS(CLASS, DESCRIPTION) \ - MODCOMMONDEFS(CLASS, DESCRIPTION, false, Info.SetLoader(TModLoad)) + MODCOMMONDEFS(CLASS, DESCRIPTION, ModuleTypeUser, Info.SetLoader(TModLoad)) // !User Module Macros // Global Module Macros @@ -112,7 +117,7 @@ template CGlobalModule* TModLoadGlobal(ModHandle p, /** This works exactly like MODULEDEFS, but for global modules. */ #define GLOBALMODULEDEFS(CLASS, DESCRIPTION) \ - MODCOMMONDEFS(CLASS, DESCRIPTION, true, Info.SetGlobalLoader(TModLoadGlobal)) + MODCOMMONDEFS(CLASS, DESCRIPTION, ModuleTypeGlobal, Info.SetGlobalLoader(TModLoadGlobal)) // !Global Module Macros // Forward Declarations @@ -179,8 +184,7 @@ public: m_fGlobalLoader = NULL; m_fLoader = NULL; } - CModInfo(const CString& sName, const CString& sPath, bool bGlobal) { - m_bGlobal = bGlobal; + CModInfo(const CString& sName, const CString& sPath, EModuleType eType) { m_sName = sName; m_sPath = sPath; m_fGlobalLoader = NULL; @@ -197,7 +201,7 @@ public: const CString& GetPath() const { return m_sPath; } const CString& GetDescription() const { return m_sDescription; } const CString& GetWikiPage() const { return m_sWikiPage; } - bool IsGlobal() const { return m_bGlobal; } + EModuleType GetType() const { return m_eType; } ModLoader GetLoader() const { return m_fLoader; } GlobalModLoader GetGlobalLoader() const { return m_fGlobalLoader; } // !Getters @@ -207,13 +211,13 @@ public: void SetPath(const CString& s) { m_sPath = s; } void SetDescription(const CString& s) { m_sDescription = s; } void SetWikiPage(const CString& s) { m_sWikiPage = s; } - void SetGlobal(bool b) { m_bGlobal = b; } + void SetType(EModuleType eType) { m_eType = eType; } void SetLoader(ModLoader fLoader) { m_fLoader = fLoader; } void SetGlobalLoader(GlobalModLoader fGlobalLoader) { m_fGlobalLoader = fGlobalLoader; } // !Setters private: protected: - bool m_bGlobal; + EModuleType m_eType; CString m_sName; CString m_sPath; CString m_sDescription; @@ -845,14 +849,14 @@ public: const CString& GetSavePath() const; // Setters - void SetGlobal(bool b) { m_bGlobal = b; } + void SetType(EModuleType eType) { m_eType = eType; } void SetDescription(const CString& s) { m_sDescription = s; } void SetModPath(const CString& s) { m_sModPath = s; } void SetArgs(const CString& s) { m_sArgs = s; } // !Setters // Getters - bool IsGlobal() const { return m_bGlobal; } + EModuleType GetType() const { return m_eType; } const CString& GetDescription() const { return m_sDescription; } const CString& GetArgs() const { return m_sArgs; } const CString& GetModPath() const { return m_sModPath; } @@ -871,7 +875,7 @@ public: // !Getters protected: - bool m_bGlobal; + EModuleType m_eType; CString m_sDescription; set m_sTimers; set m_sSockets; @@ -974,7 +978,7 @@ public: static bool GetModInfo(CModInfo& ModInfo, const CString& sModule, CString &sRetMsg); static bool GetModPathInfo(CModInfo& ModInfo, const CString& sModule, const CString& sModPath, CString &sRetMsg); - static void GetAvailableMods(set& ssMods, bool bGlobal = false); + static void GetAvailableMods(set& ssMods, EModuleType eType = ModuleTypeUser); // This returns the path to the .so and to the data dir // which is where static data (webadmin skins) are saved @@ -1097,7 +1101,7 @@ public: * @param ssMods put new modules here. * @param bGlobal true if global modules are needed. */ - virtual void OnGetAvailableMods(set& ssMods, bool bGlobal); + virtual void OnGetAvailableMods(set& ssMods, EModuleType eType); private: }; @@ -1120,7 +1124,7 @@ public: bool OnModuleUnloading(CModule* pModule, bool& bSuccess, CString& sRetMsg); bool OnGetModInfo(CModInfo& ModInfo, const CString& sModule, bool& bSuccess, CString& sRetMsg); - bool OnGetAvailableMods(set& ssMods, bool bGlobal); + bool OnGetAvailableMods(set& ssMods, EModuleType eType); private: }; diff --git a/Socket.cpp b/Socket.cpp index e4c2ef74..edf2e49a 100644 --- a/Socket.cpp +++ b/Socket.cpp @@ -59,7 +59,7 @@ CSocket::~CSocket() { m_pModule->UnlinkSocket(this); } - if (pUser && m_pModule && !m_pModule->IsGlobal()) { + if (pUser && m_pModule && (m_pModule->GetType() != ModuleTypeGlobal)) { pUser->AddBytesWritten(GetBytesWritten()); pUser->AddBytesRead(GetBytesRead()); } else { diff --git a/WebModules.cpp b/WebModules.cpp index 572cf0d4..c2404c8b 100644 --- a/WebModules.cpp +++ b/WebModules.cpp @@ -639,7 +639,7 @@ CWebSock::EPageReqResult CWebSock::OnPageRequestInternal(const CString& sURI, CS } else if (pModule->WebRequiresAdmin() && !GetSession()->IsAdmin()) { PrintErrorPage(403, "Forbidden", "You need to be an admin to access this module"); return PAGE_DONE; - } else if (!pModule->IsGlobal() && pModule->GetUser() != GetSession()->GetUser()) { + } else if (pModule->GetType() != ModuleTypeGlobal && pModule->GetUser() != GetSession()->GetUser()) { PrintErrorPage(403, "Forbidden", "You must login as " + pModule->GetUser()->GetUserName() + " in order to view this page"); return PAGE_DONE; } else if (pModule->OnWebPreRequest(*this, m_sPage)) { @@ -659,7 +659,7 @@ CWebSock::EPageReqResult CWebSock::OnPageRequestInternal(const CString& sURI, CS } } - if (pModule && !pModule->IsGlobal() && (!IsLoggedIn() || pModule->GetUser() != GetSession()->GetUser())) { + if (pModule && pModule->GetType() != ModuleTypeGlobal && (!IsLoggedIn() || pModule->GetUser() != GetSession()->GetUser())) { AddModLoop("UserModLoop", *pModule); } diff --git a/modules/modperl.cpp b/modules/modperl.cpp index 2fdf7800..24560b16 100644 --- a/modules/modperl.cpp +++ b/modules/modperl.cpp @@ -148,7 +148,7 @@ public: case Perl_Loaded: result = HALT; if (4 == ret) { - ModInfo.SetGlobal(false); + ModInfo.SetType(ModuleTypeUser); ModInfo.SetDescription(PString(ST(2))); ModInfo.SetName(sModule); ModInfo.SetPath(PString(ST(1))); @@ -178,8 +178,8 @@ public: return result; } - virtual void OnGetAvailableMods(set& ssMods, bool bGlobal) { - if (bGlobal) { + virtual void OnGetAvailableMods(set& ssMods, EModuleType eType) { + if (eType != ModuleTypeUser) { return; } @@ -203,7 +203,7 @@ public: PUSH_STR(sName); PCALL("ZNC::Core::ModInfoByPath"); if (!SvTRUE(ERRSV) && ret == 2) { - ModInfo.SetGlobal(false); + ModInfo.SetType(ModuleTypeUser); ModInfo.SetDescription(PString(ST(0))); ModInfo.SetName(sName); ModInfo.SetPath(sPath); diff --git a/modules/modpython.cpp b/modules/modpython.cpp index 3b12de54..d8fb83b3 100644 --- a/modules/modpython.cpp +++ b/modules/modpython.cpp @@ -128,9 +128,6 @@ public: virtual EModRet OnModuleLoading(const CString& sModName, const CString& sArgs, bool& bSuccess, CString& sRetMsg) { - if (!GetUser()) { - return CONTINUE; - } PyObject* pyFunc = PyObject_GetAttrString(m_PyZNCModule, "load_module"); if (!pyFunc) { sRetMsg = GetPyExceptionStr(); @@ -252,7 +249,7 @@ public: return HALT; } - void TryAddModInfo(const CString& sPath, const CString& sName, set& ssMods, set& ssAlready) { + void TryAddModInfo(const CString& sPath, const CString& sName, set& ssMods, set& ssAlready, EModuleType eType) { if (ssAlready.count(sName)) { return; } @@ -282,17 +279,13 @@ public: return; } Py_CLEAR(pyRes); - if (x) { + if (x && ModInfo.GetType() == eType) { ssMods.insert(ModInfo); ssAlready.insert(sName); } } - virtual void OnGetAvailableMods(set& ssMods, bool bGlobal) { - if (bGlobal) { - return; - } - + virtual void OnGetAvailableMods(set& ssMods, EModuleType eType) { CDir Dir; CModules::ModDirList dirs = CModules::GetModDirs(); @@ -306,7 +299,7 @@ public: CString sPath = File.GetLongName(); sPath.TrimSuffix(sName); sName.RightChomp(3); - TryAddModInfo(sPath, sName, ssMods, already); + TryAddModInfo(sPath, sName, ssMods, already, eType); } Dir.FillByWildcard(dirs.front().first, "*.pyc"); @@ -316,7 +309,7 @@ public: CString sPath = File.GetLongName(); sPath.TrimSuffix(sName); sName.RightChomp(4); - TryAddModInfo(sPath, sName, ssMods, already); + TryAddModInfo(sPath, sName, ssMods, already, eType); } Dir.FillByWildcard(dirs.front().first, "*.so"); @@ -326,7 +319,7 @@ public: CString sPath = File.GetLongName(); sPath.TrimSuffix(sName); sName.RightChomp(3); - TryAddModInfo(sPath, sName, ssMods, already); + TryAddModInfo(sPath, sName, ssMods, already, eType); } dirs.pop(); diff --git a/modules/modpython/znc.py b/modules/modpython/znc.py index 3cc89b61..61a55919 100644 --- a/modules/modpython/znc.py +++ b/modules/modpython/znc.py @@ -150,6 +150,7 @@ class ModuleNV(collections.MutableMapping): class Module: description = '< Placeholder for a description >' + module_type = ModuleTypeUser wiki_page = '' @@ -498,7 +499,7 @@ def get_mod_info(modname, retmsg, modinfo): pymodule.__file__, modname) return 1 cl = pymodule.__dict__[modname] - modinfo.SetGlobal(False) + modinfo.SetType(cl.module_type) modinfo.SetDescription(cl.description) modinfo.SetWikiPage(cl.wiki_page) modinfo.SetName(modname) @@ -526,7 +527,7 @@ def get_mod_info_path(path, modname, modinfo): if modname not in pymodule.__dict__: return 0 cl = pymodule.__dict__[modname] - modinfo.SetGlobal(False) + modinfo.SetType(cl.module_type) modinfo.SetDescription(cl.description) modinfo.SetWikiPage(cl.wiki_page) modinfo.SetName(modname) diff --git a/modules/webadmin.cpp b/modules/webadmin.cpp index eb103c96..59c228f0 100644 --- a/modules/webadmin.cpp +++ b/modules/webadmin.cpp @@ -143,24 +143,6 @@ public: return true; } - CString GetModArgs(CUser* pUser, const CString& sModName, bool bGlobal = false) { - if (!bGlobal && !pUser) { - return ""; - } - - CModules& Modules = (bGlobal) ? CZNC::Get().GetModules() : pUser->GetModules(); - - for (unsigned int a = 0; a < Modules.size(); a++) { - CModule* pModule = Modules[a]; - - if (pModule->GetModName() == sModName) { - return pModule->GetArgs(); - } - } - - return ""; - } - CUser* GetNewUser(CWebSock& WebSock, CUser* pUser) { CSmartPtr spSession = WebSock.GetSession(); CString sUsername = WebSock.GetParam("newuser"); @@ -744,11 +726,14 @@ public: l["Name"] = Info.GetName(); l["Description"] = Info.GetDescription(); - l["Args"] = GetModArgs(pUser, Info.GetName()); l["Wiki"] = Info.GetWikiPage(); if (pUser && pUser->GetModules().FindModule(Info.GetName())) { - l["Checked"] = "true"; + CModule *pModule = pUser->GetModules().FindModule(Info.GetName()); + if (pModule) { + l["Checked"] = "true"; + l["Args"] = pModule->GetArgs(); + } } if (!spSession->IsAdmin() && pUser && pUser->DenyLoadMod()) { @@ -1023,14 +1008,16 @@ public: } set ssGlobalMods; - CZNC::Get().GetModules().GetAvailableMods(ssGlobalMods, true); + CZNC::Get().GetModules().GetAvailableMods(ssGlobalMods, ModuleTypeGlobal); for (set::iterator it = ssGlobalMods.begin(); it != ssGlobalMods.end(); ++it) { const CModInfo& Info = *it; CTemplate& l = Tmpl.AddRow("ModuleLoop"); - if (CZNC::Get().GetModules().FindModule(Info.GetName())) { + CModule *pModule = CZNC::Get().GetModules().FindModule(Info.GetName()); + if (pModule) { l["Checked"] = "true"; + l["Args"] = pModule->GetArgs(); } if (Info.GetName() == GetModName()) { @@ -1039,7 +1026,6 @@ public: l["Name"] = Info.GetName(); l["Description"] = Info.GetDescription(); - l["Args"] = GetModArgs(NULL, Info.GetName(), true); l["Wiki"] = Info.GetWikiPage(); } diff --git a/znc.cpp b/znc.cpp index 9da44d11..a3a1d4cc 100644 --- a/znc.cpp +++ b/znc.cpp @@ -632,7 +632,7 @@ bool CZNC::WriteNewConfig(const CString& sConfigFile) { // !Listen set ssGlobalMods; - GetModules().GetAvailableMods(ssGlobalMods, true); + GetModules().GetAvailableMods(ssGlobalMods, ModuleTypeGlobal); size_t uNrOtherGlobalMods = FilterUncommonModules(ssGlobalMods); if (!ssGlobalMods.empty()) {