Browse files

Make modpython support different module types

  • Loading branch information...
1 parent 9e33e4b commit 274d3eb2ec540b400ba290106a71860c71f458fe @kylef kylef committed Aug 13, 2011
Showing with 148 additions and 62 deletions.
  1. +97 −38 ClientCommand.cpp
  2. +4 −4 Modules.cpp
  3. +12 −6 Modules.h
  4. +2 −2 modules/modperl.cpp
  5. +4 −3 modules/modpython.cpp
  6. +29 −9 modules/modpython/znc.py
View
135 ClientCommand.cpp
@@ -562,19 +562,28 @@ void CClient::UserCommand(CString& sLine) {
}
return;
} else if (sCommand.Equals("LOADMOD") || sCommand.Equals("LOADMODULE")) {
- CString sMod;
- CString sArgs;
-
- sMod = sLine.Token(1);
- sArgs = sLine.Token(2, true);
+ EModuleType eType;
+ CString sType = sLine.Token(1);
+ CString sMod = sLine.Token(2);
+ CString sArgs = sLine.Token(3, true);
+
+ if (sType.Equals("global")) {
+ eType = ModuleTypeGlobal;
+ } else if (sType.Equals("user")) {
+ eType = ModuleTypeUser;
+ } else {
+ sMod = sType;
+ sArgs = sLine.Token(2, true);
+ sType = "default";
+ }
if (m_pUser->DenyLoadMod()) {
PutStatus("Unable to load [" + sMod + "] Access Denied.");
return;
}
if (sMod.empty()) {
- PutStatus("Usage: LoadMod <module> [args]");
+ PutStatus("Usage: LoadMod [type] <module> [args]");
return;
}
@@ -585,23 +594,28 @@ void CClient::UserCommand(CString& sLine) {
return;
}
+ if (sType.Equals("default")) {
+ eType = ModInfo.DefaultType();
+ }
+
+ if (eType == ModuleTypeGlobal && !m_pUser->IsAdmin()) {
+ PutStatus("Unable to load global module [" + sMod + "] Access Denied.");
+ return;
+ }
+
CString sModRet;
bool b = false;
- switch (ModInfo.GetType()) {
+ switch (eType) {
case ModuleTypeGlobal:
- if (m_pUser->IsAdmin()) {
- b = CZNC::Get().GetModules().LoadModule(sMod, sArgs, ModuleTypeGlobal, NULL, sModRet);
- } else {
- sModRet = "Unable to load global module [" + sMod + "] Access Denied.";
- }
+ b = CZNC::Get().GetModules().LoadModule(sMod, sArgs, eType, NULL, sModRet);
break;
case ModuleTypeUser:
- b = m_pUser->GetModules().LoadModule(sMod, sArgs, ModuleTypeUser, m_pUser, sModRet);
+ b = m_pUser->GetModules().LoadModule(sMod, sArgs, eType, m_pUser, sModRet);
break;
default:
sModRet = "Unable to load module [" + sMod + "] Unknown module type";
- break;
+
}
if (b)
@@ -610,44 +624,84 @@ void CClient::UserCommand(CString& sLine) {
PutStatus(sModRet);
return;
} else if (sCommand.Equals("UNLOADMOD") || sCommand.Equals("UNLOADMODULE")) {
- CString sMod;
- sMod = sLine.Token(1);
+ EModuleType eType = ModuleTypeUser;
+ CString sType = sLine.Token(1);
+ CString sMod = sLine.Token(2);
+
+ if (sType.Equals("global")) {
+ eType = ModuleTypeGlobal;
+ } else if (sType.Equals("user")) {
+ eType = ModuleTypeUser;
+ } else {
+ sMod = sType;
+ sType = "default";
+ }
if (m_pUser->DenyLoadMod()) {
PutStatus("Unable to unload [" + sMod + "] Access Denied.");
return;
}
+
if (sMod.empty()) {
- PutStatus("Usage: UnloadMod <module>");
+ PutStatus("Usage: UnloadMod [type] <module>");
+ return;
+ }
+
+ CModInfo ModInfo;
+ CString sRetMsg;
+ if (!CZNC::Get().GetModules().GetModInfo(ModInfo, sMod, sRetMsg)) {
+ PutStatus("Unable to find modinfo [" + sMod + "] [" + sRetMsg + "]");
+ return;
+ }
+
+ if (sType.Equals("default")) {
+ eType = ModInfo.DefaultType();
+ }
+
+ if (eType == ModuleTypeGlobal && !m_pUser->IsAdmin()) {
+ PutStatus("Unable to unload global module [" + sMod + "] Access Denied.");
return;
}
CString sModRet;
- bool b;
- // First, try to unload the user module
- b = m_pUser->GetModules().UnloadModule(sMod, sModRet);
- if (!b && m_pUser->IsAdmin()) {
- // If that failed and the user is an admin, try to unload a global module
- b = CZNC::Get().GetModules().UnloadModule(sMod, sModRet);
+ switch (eType) {
+ case ModuleTypeGlobal:
+ CZNC::Get().GetModules().UnloadModule(sMod, sModRet);
+ break;
+ case ModuleTypeUser:
+ m_pUser->GetModules().UnloadModule(sMod, sModRet);
+ break;
+ default:
+ sModRet = "Unable to unload module [" + sMod + "] Unknown module type";
+
}
PutStatus(sModRet);
return;
} else if (sCommand.Equals("RELOADMOD") || sCommand.Equals("RELOADMODULE")) {
- CString sMod;
- CString sArgs;
-
- sMod = sLine.Token(1);
- sArgs = sLine.Token(2, true);
+ EModuleType eType;
+ CString sType = sLine.Token(1);
+ CString sMod = sLine.Token(2);
+ CString sArgs = sLine.Token(3, true);
if (m_pUser->DenyLoadMod()) {
PutStatus("Unable to reload modules. Access Denied.");
return;
}
+ if (sType.Equals("global")) {
+ eType = ModuleTypeGlobal;
+ } else if (sType.Equals("user")) {
+ eType = ModuleTypeUser;
+ } else {
+ sMod = sType;
+ sArgs = sLine.Token(2, true);
+ sType = "default";
+ }
+
if (sMod.empty()) {
- PutStatus("Usage: ReloadMod <module> [args]");
+ PutStatus("Usage: ReloadMod [type] <module> [args]");
return;
}
@@ -658,22 +712,27 @@ void CClient::UserCommand(CString& sLine) {
return;
}
+ if (sType.Equals("default")) {
+ eType = ModInfo.DefaultType();
+ }
+
+ if (eType == ModuleTypeGlobal && !m_pUser->IsAdmin()) {
+ PutStatus("Unable to reload global module [" + sMod + "] Access Denied.");
+ return;
+ }
+
CString sModRet;
- switch (ModInfo.GetType()) {
+ switch (eType) {
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);
@@ -1143,17 +1202,17 @@ void CClient::HelpUser() {
if (!m_pUser->DenyLoadMod()) {
Table.AddRow();
Table.SetCell("Command", "LoadMod");
- Table.SetCell("Arguments", "<module>");
+ Table.SetCell("Arguments", "[type] <module>");
Table.SetCell("Description", "Load a module");
Table.AddRow();
Table.SetCell("Command", "UnloadMod");
- Table.SetCell("Arguments", "<module>");
+ Table.SetCell("Arguments", "[type] <module>");
Table.SetCell("Description", "Unload a module");
Table.AddRow();
Table.SetCell("Command", "ReloadMod");
- Table.SetCell("Arguments", "<module>");
+ Table.SetCell("Arguments", "[type] <module>");
Table.SetCell("Description", "Reload a module");
if (m_pUser->IsAdmin()) {
View
8 Modules.cpp
@@ -830,9 +830,9 @@ bool CModules::LoadModule(const CString& sModule, const CString& sArgs, EModuleT
return false;
}
- if (!Info.SupportsModule(eType)) {
+ if (!Info.SupportsType(eType)) {
dlclose(p);
- sRetMsg = "Module [ + sModule + ] does not support module type.";
+ sRetMsg = "Module [" + sModule + "] does not support module type.";
return false;
}
@@ -858,7 +858,7 @@ bool CModules::LoadModule(const CString& sModule, const CString& sArgs, EModuleT
}
pModule->SetDescription(Info.GetDescription());
- pModule->SetType(Info.GetType());
+ pModule->SetType(eType);
pModule->SetArgs(sArgs);
pModule->SetModPath(CDir::ChangeDir(CZNC::Get().GetCurPath(), sModPath));
push_back(pModule);
@@ -1007,7 +1007,7 @@ void CModules::GetAvailableMods(set<CModInfo>& ssMods, EModuleType eType) {
CString sIgnoreRetMsg;
if (GetModPathInfo(ModInfo, sName, sPath, sIgnoreRetMsg)) {
- if (ModInfo.GetType() == eType) {
+ if (ModInfo.SupportsType(eType)) {
ssMods.insert(ModInfo);
}
}
View
18 Modules.h
@@ -70,7 +70,7 @@ template<class M> CModule* TModLoadGlobal(ModHandle p,
if (dCoreVersion != VERSION) \
return false; \
Info.SetDescription(DESCRIPTION); \
- Info.SetType(TYPE); \
+ Info.AddType(TYPE); \
LOADER; \
TModInfo<CLASS>(Info); \
return true; \
@@ -195,16 +195,23 @@ class CModInfo {
return (GetName() < Info.GetName());
}
- bool SupportsModule(EModuleType eType) {
- return eType == m_eType;
+ bool SupportsType(EModuleType eType) {
+ return m_seType.find(eType) != m_seType.end();
+ }
+
+ void AddType(EModuleType eType) {
+ m_seType.insert(eType);
+ }
+
+ EModuleType DefaultType() {
+ return *m_seType.begin();
}
// Getters
const CString& GetName() const { return m_sName; }
const CString& GetPath() const { return m_sPath; }
const CString& GetDescription() const { return m_sDescription; }
const CString& GetWikiPage() const { return m_sWikiPage; }
- EModuleType GetType() const { return m_eType; }
ModLoader GetLoader() const { return m_fLoader; }
GlobalModLoader GetGlobalLoader() const { return m_fGlobalLoader; }
// !Getters
@@ -214,13 +221,12 @@ class CModInfo {
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 SetType(EModuleType eType) { m_eType = eType; }
void SetLoader(ModLoader fLoader) { m_fLoader = fLoader; }
void SetGlobalLoader(GlobalModLoader fGlobalLoader) { m_fGlobalLoader = fGlobalLoader; }
// !Setters
private:
protected:
- EModuleType m_eType;
+ set<EModuleType> m_seType;
CString m_sName;
CString m_sPath;
CString m_sDescription;
View
4 modules/modperl.cpp
@@ -148,7 +148,7 @@ class CModPerl: public CModule {
case Perl_Loaded:
result = HALT;
if (4 == ret) {
- ModInfo.SetType(ModuleTypeUser);
+ ModInfo.AddType(ModuleTypeUser);
ModInfo.SetDescription(PString(ST(2)));
ModInfo.SetName(sModule);
ModInfo.SetPath(PString(ST(1)));
@@ -203,7 +203,7 @@ class CModPerl: public CModule {
PUSH_STR(sName);
PCALL("ZNC::Core::ModInfoByPath");
if (!SvTRUE(ERRSV) && ret == 2) {
- ModInfo.SetType(ModuleTypeUser);
+ ModInfo.AddType(ModuleTypeUser);
ModInfo.SetDescription(PString(ST(0)));
ModInfo.SetName(sName);
ModInfo.SetPath(sPath);
View
7 modules/modpython.cpp
@@ -135,10 +135,11 @@ class CModPython: public CModule {
bSuccess = false;
return HALT;
}
- PyObject* pyRes = PyObject_CallFunction(pyFunc, const_cast<char*>("ssNNN"),
+ PyObject* pyRes = PyObject_CallFunction(pyFunc, const_cast<char*>("ssiNNN"),
sModName.c_str(),
sArgs.c_str(),
- (eType == ModuleTypeUser ? SWIG_NewInstanceObj(GetUser(), SWIG_TypeQuery("CUser*"), 0) : NULL),
+ (int)eType,
+ (eType == ModuleTypeUser ? SWIG_NewInstanceObj(GetUser(), SWIG_TypeQuery("CUser*"), 0) : Py_None),
CPyRetString::wrap(sRetMsg),
SWIG_NewInstanceObj(reinterpret_cast<CModule*>(this), SWIG_TypeQuery("CModule*"), 0));
if (!pyRes) {
@@ -279,7 +280,7 @@ class CModPython: public CModule {
return;
}
Py_CLEAR(pyRes);
- if (x && ModInfo.GetType() == eType) {
+ if (x && ModInfo.SupportsType(eType)) {
ssMods.insert(ModInfo);
ssAlready.insert(sName);
}
View
38 modules/modpython/znc.py
@@ -150,7 +150,7 @@ def __len__(self):
class Module:
description = '< Placeholder for a description >'
- module_type = ModuleTypeUser
+ module_types = [ModuleTypeUser]
wiki_page = ''
@@ -423,7 +423,7 @@ def find_open(modname):
return (None, None)
-def load_module(modname, args, user, retmsg, modpython):
+def load_module(modname, args, module_type, user, retmsg, modpython):
'''Returns 0 if not found, 1 on loading error, 2 on success'''
if re.search(r'[^a-zA-Z0-9_]', modname) is not None:
retmsg.s = 'Module names can only contain letters, numbers and ' \
@@ -437,21 +437,38 @@ def load_module(modname, args, user, retmsg, modpython):
pymodule.__file__, modname)
return 1
cl = pymodule.__dict__[modname]
+
+ if module_type not in cl.module_types:
+ retmsg.s = "Module [{}] doesn't support type.".format(modname)
+ return 1
+
module = cl()
- if user:
+ if module_type == ModuleTypeUser:
module._cmod = CreateUserPyModule(user, modname, datapath, module, modpython)
- else:
+ elif module_type == ModuleTypeGlobal:
module._cmod = CreateGlobalPyModule(modname, datapath, module, modpython)
+ else:
+ retmsg.s = "Module [modpython] doesn't support module type."
+ return 1
+
module.nv = ModuleNV(module._cmod)
module.SetDescription(cl.description)
module.SetArgs(args)
module.SetModPath(pymodule.__file__)
- module.SetType(cl.module_type)
+ module.SetType(module_type)
- if user:
+ if module_type == ModuleTypeUser:
+ if not user:
+ retmsg.s = "Module [modpython] needs user for for ModuleTypeUser."
+ unload_module(module)
+ return 1
user.GetModules().push_back(module._cmod)
- else:
+ elif module_type == ModuleTypeGlobal:
CZNC.Get().GetModules().push_back(module._cmod)
+ else:
+ retmsg.s = "Module [modpython] doesn't support module type."
+ unload_module(module)
+ return 1
try:
loaded = True
@@ -511,7 +528,8 @@ def get_mod_info(modname, retmsg, modinfo):
pymodule.__file__, modname)
return 1
cl = pymodule.__dict__[modname]
- modinfo.SetType(cl.module_type)
+ for module_type in cl.module_types:
+ modinfo.AddType(module_type)
modinfo.SetDescription(cl.description)
modinfo.SetWikiPage(cl.wiki_page)
modinfo.SetName(modname)
@@ -539,11 +557,13 @@ def get_mod_info_path(path, modname, modinfo):
if modname not in pymodule.__dict__:
return 0
cl = pymodule.__dict__[modname]
- modinfo.SetType(cl.module_type)
modinfo.SetDescription(cl.description)
modinfo.SetWikiPage(cl.wiki_page)
modinfo.SetName(modname)
modinfo.SetPath(pymodule.__file__)
+ for module_type in cl.module_types:
+ modinfo.AddType(module_type)
+
return 1

0 comments on commit 274d3eb

Please sign in to comment.