template<> void TModInfo<CLogMod>(CModInfo& Info) { Info.AddType(CModInfo::NetworkModule); Info.AddType(CModInfo::GlobalModule); Info.SetHasArgs(true); Info.SetArgsHelpText("[-sanitize] Optional path where to store logs."); Info.SetWikiPage("log"); }
void TryAddModInfo(const CString& sPath, const CString& sName, set<CModInfo>& ssMods, set<CString>& ssAlready, CModInfo::EModuleType eType) { if (ssAlready.count(sName)) { return; } PyObject* pyFunc = PyObject_GetAttrString(m_PyZNCModule, "get_mod_info_path"); if (!pyFunc) { CString sRetMsg = GetPyExceptionStr(); DEBUG("modpython tried to get info about [" << sPath << "] (1) but: " << sRetMsg); return; } CModInfo ModInfo; PyObject* pyRes = PyObject_CallFunction(pyFunc, const_cast<char*>("ssN"), sPath.c_str(), sName.c_str(), SWIG_NewInstanceObj(&ModInfo, SWIG_TypeQuery("CModInfo*"), 0)); if (!pyRes) { CString sRetMsg = GetPyExceptionStr(); DEBUG("modpython tried to get info about [" << sPath << "] (2) but: " << sRetMsg); Py_CLEAR(pyFunc); return; } Py_CLEAR(pyFunc); long int x = PyLong_AsLong(pyRes); if (PyErr_Occurred()) { CString sRetMsg = GetPyExceptionStr(); DEBUG("modpython tried to get info about [" << sPath << "] (3) but: " << sRetMsg); Py_CLEAR(pyRes); return; } Py_CLEAR(pyRes); if (x && ModInfo.SupportsType(eType)) { ssMods.insert(ModInfo); ssAlready.insert(sName); } }
void CModules::GetAvailableMods(set<CModInfo>& ssMods, bool bGlobal) { ssMods.clear(); unsigned int a = 0; CDir Dir; ModDirList dirs = GetModDirs(); while (!dirs.empty()) { Dir.FillByWildcard(dirs.front().first, "*.so"); dirs.pop(); for (a = 0; a < Dir.size(); a++) { CFile& File = *Dir[a]; CString sName = File.GetShortName(); CString sPath = File.GetLongName(); CModInfo ModInfo; sName.RightChomp(3); CString sIgnoreRetMsg; if (GetModPathInfo(ModInfo, sName, sPath, sIgnoreRetMsg)) { if (ModInfo.IsGlobal() == bGlobal) { ssMods.insert(ModInfo); } } } } GLOBALMODULECALL(OnGetAvailableMods(ssMods, bGlobal), NULL, NULL, ); }
void TModInfo<CNotesMod>(CModInfo& Info) { Info.SetWikiPage("notes"); Info.SetHasArgs(true); Info.SetArgsHelpText( "This user module takes up to one arguments. It can be " "-disableNotesOnLogin not to show notes upon client login"); }
void TModInfo<CFloodDetachMod>(CModInfo& Info) { Info.SetWikiPage("flooddetach"); Info.SetHasArgs(true); Info.SetArgsHelpText( Info.t_s("This user module takes up to two arguments. Arguments are " "numbers of messages and seconds.")); }
virtual void OnGetAvailableMods(set<CModInfo>& ssMods, CModInfo::EModuleType eType) override { unsigned int a = 0; CDir Dir; CModules::ModDirList dirs = CModules::GetModDirs(); while (!dirs.empty()) { Dir.FillByWildcard(dirs.front().first, "*.pm"); dirs.pop(); for (a = 0; a < Dir.size(); a++) { CFile& File = *Dir[a]; CString sName = File.GetShortName(); CString sPath = File.GetLongName(); CModInfo ModInfo; sName.RightChomp(3); PSTART; PUSH_STR(sPath); PUSH_STR(sName); PUSH_PTR(CModInfo*, &ModInfo); PCALL("ZNC::Core::ModInfoByPath"); if (SvTRUE(ERRSV)) { DEBUG(__PRETTY_FUNCTION__ << ": " << sPath << ": " << PString(ERRSV)); } else if (ModInfo.SupportsType(eType)) { ssMods.insert(ModInfo); } PEND; } } }
virtual void OnGetAvailableMods(set<CModInfo>& ssMods, bool bGlobal) { if (bGlobal) { return; } unsigned int a = 0; CDir Dir; CModules::ModDirList dirs = CModules::GetModDirs(); while (!dirs.empty()) { Dir.FillByWildcard(dirs.front().first, "*.pm"); dirs.pop(); for (a = 0; a < Dir.size(); a++) { CFile& File = *Dir[a]; CString sName = File.GetShortName(); CString sPath = File.GetLongName(); CModInfo ModInfo; sName.RightChomp(3); PSTART; PUSH_STR(sPath); PUSH_STR(sName); PCALL("ZNC::Core::ModInfoByPath"); if (!SvTRUE(ERRSV) && ret == 1) { ModInfo.SetGlobal(false); ModInfo.SetDescription(PString(ST(0))); ModInfo.SetName(sName); ModInfo.SetPath(sPath); ssMods.insert(ModInfo); } PEND; } } }
void TModInfo<CFloodDetachMod>(CModInfo& Info) { Info.SetWikiPage("flooddetach"); Info.SetHasArgs(true); Info.SetArgsHelpText( "This user module takes up to two arguments. Arguments are msgs and " "secs numbers."); }
void TModInfo<CChanAttach>(CModInfo& Info) { Info.AddType(CModInfo::UserModule); Info.SetWikiPage("autoattach"); Info.SetHasArgs(true); Info.SetArgsHelpText( "List of channel masks and channel masks with ! before them."); }
void TModInfo<CSimpleAway>(CModInfo& Info) { Info.SetWikiPage("simple_away"); Info.SetHasArgs(true); Info.SetArgsHelpText( Info.t_s("You might enter up to 3 arguments, like -notimer awaymessage " "or -timer 5 awaymessage.")); }
template<> void TModInfo<CCharsetMod>(CModInfo& Info) { Info.SetWikiPage("charset"); Info.SetHasArgs(true); Info.SetArgsHelpText("Two charset lists: [-force] " "<client_charset1[,client_charset2[,...]]> " "<server_charset1[,server_charset2[,...]]>"); }
void TModInfo<CCtcpFloodMod>(CModInfo& Info) { Info.SetWikiPage("ctcpflood"); Info.SetHasArgs(true); Info.SetArgsHelpText(Info.t_s( "This user module takes none to two arguments. The first argument is " "the number of lines after which the flood-protection is triggered. " "The second argument is the time (sec) to in which the number of lines " "is reached. The default setting is 4 CTCPs in 2 seconds")); }
bool CUser::LoadModule(const CString& sModName, const CString& sArgs, const CString& sNotice, CString& sError) { bool bModRet = true; CString sModRet; CModInfo ModInfo; if (!CZNC::Get().GetModules().GetModInfo(ModInfo, sModName, sModRet)) { sError = "Unable to find modinfo [" + sModName + "] [" + sModRet + "]"; return false; } CUtils::PrintAction(sNotice); if (!ModInfo.SupportsType(CModInfo::UserModule) && ModInfo.SupportsType(CModInfo::NetworkModule)) { CUtils::PrintMessage( "NOTICE: Module [" + sModName + "] is a network module, loading module for all networks in user."); // Do they have old NV? CFile fNVFile = CFile(GetUserPath() + "/moddata/" + sModName + "/.registry"); for (CIRCNetwork* pNetwork : m_vIRCNetworks) { // Check whether the network already has this module loaded (#954) if (pNetwork->GetModules().FindModule(sModName)) { continue; } if (fNVFile.Exists()) { CString sNetworkModPath = pNetwork->GetNetworkPath() + "/moddata/" + sModName; if (!CFile::Exists(sNetworkModPath)) { CDir::MakeDir(sNetworkModPath); } fNVFile.Copy(sNetworkModPath + "/.registry"); } bModRet = pNetwork->GetModules().LoadModule( sModName, sArgs, CModInfo::NetworkModule, this, pNetwork, sModRet); if (!bModRet) { break; } } } else { bModRet = GetModules().LoadModule(sModName, sArgs, CModInfo::UserModule, this, nullptr, sModRet); } if (!bModRet) { sError = sModRet; } return bModRet; }
virtual EModRet OnGetModInfo(CModInfo& ModInfo, const CString& sModule, bool& bSuccess, CString& sRetMsg) { PSTART; PUSH_STR(sModule); PCALL("ZNC::Core::GetModInfo"); EModRet result = CONTINUE; if (SvTRUE(ERRSV)) { bSuccess = false; sRetMsg = PString(ERRSV); } else if (0 < ret) { switch(static_cast<ELoadPerlMod>(SvUV(ST(0)))) { case Perl_NotFound: result = CONTINUE; break; case Perl_Loaded: result = HALT; if (3 == ret) { ModInfo.SetGlobal(false); ModInfo.SetDescription(PString(ST(2))); ModInfo.SetName(sModule); ModInfo.SetPath(PString(ST(1))); bSuccess = true; } else { bSuccess = false; sRetMsg = "Something weird happened"; } break; case Perl_LoadError: result = HALT; bSuccess = false; if (2 == ret) { sRetMsg = PString(ST(1)); } else { sRetMsg = "Something weird happened"; } } } else { result = HALT; bSuccess = false; sRetMsg = "Something weird happened"; } PEND; DEBUG(__PRETTY_FUNCTION__ << " " << sRetMsg); return result; }
bool CModules::GetModPathInfo(CModInfo& ModInfo, const CString& sModule, const CString& sModPath, CString& sRetMsg) { bool bVersionMismatch; ModHandle p = OpenModule(sModule, sModPath, bVersionMismatch, ModInfo, sRetMsg); if (!p) return false; ModInfo.SetName(sModule); ModInfo.SetPath(sModPath); if (bVersionMismatch) { ModInfo.SetDescription("--- Version mismatch, recompile this module. ---"); } dlclose(p); return true; }
template<> void TModInfo<CModTcl>(CModInfo& Info) { Info.SetWikiPage("modtcl"); Info.SetHasArgs(true); Info.SetArgsHelpText("Absolute path to modtcl.tcl file"); }
template<> void TModInfo<CFailToBanMod>(CModInfo& Info) { Info.SetWikiPage("fail2ban"); Info.SetHasArgs(true); Info.SetArgsHelpText("You might enter the time in minutes for the IP banning and the number of failed logins before any action is taken."); }
template<> void TModInfo<CAdminLogMod>(CModInfo& Info) { Info.SetWikiPage("adminlog"); }
template<> void TModInfo<CMultiAwayMod>(CModInfo& Info) { Info.SetWikiPage("multi_away"); Info.AddType(CModInfo::NetworkModule); }
void TModInfo<CRouteRepliesMod>(CModInfo& Info) { Info.SetWikiPage("route_replies"); }
void TModInfo<CKeepNickMod>(CModInfo& Info) { Info.SetWikiPage("keepnick"); }
template<> void TModInfo<CModPython>(CModInfo& Info) { Info.SetWikiPage("modpython"); }
template<> void TModInfo<CIMAPAuthMod>(CModInfo& Info) { Info.SetWikiPage("imapauth"); Info.SetHasArgs(true); Info.SetArgsHelpText("[ server [+]port [ UserFormatString ] ]"); }
template<> void TModInfo<CRawMod>(CModInfo& Info) { Info.SetWikiPage("raw"); Info.AddType(CModInfo::UserModule); }
template<> void TModInfo<CAutoCycleMod>(CModInfo& Info) { Info.SetWikiPage("autocycle"); }
void TModInfo<CBlockUser>(CModInfo& Info) { Info.SetWikiPage("blockuser"); Info.SetHasArgs(true); Info.SetArgsHelpText( "Enter one or more user names. Separate them by spaces."); }
void TModInfo<CListSockets>(CModInfo& Info) { Info.SetWikiPage("listsockets"); }
template<> void TModInfo<CIdentFileModule>(CModInfo& Info) { Info.SetWikiPage("identfile"); }
void TModInfo<CSASLMod>(CModInfo& Info) { Info.SetWikiPage("sasl"); }
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; }