Make modpython support different module types

This commit is contained in:
Kyle Fuller
2011-08-13 17:01:55 +01:00
parent 9e33e4bf59
commit 274d3eb2ec
6 changed files with 147 additions and 61 deletions
+96 -37
View File
@@ -562,11 +562,20 @@ void CClient::UserCommand(CString& sLine) {
}
return;
} else if (sCommand.Equals("LOADMOD") || sCommand.Equals("LOADMODULE")) {
CString sMod;
CString sArgs;
EModuleType eType;
CString sType = sLine.Token(1);
CString sMod = sLine.Token(2);
CString sArgs = sLine.Token(3, true);
sMod = sLine.Token(1);
sArgs = sLine.Token(2, 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.");
@@ -574,7 +583,7 @@ void CClient::UserCommand(CString& sLine) {
}
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,14 +712,19 @@ 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:
@@ -673,7 +732,7 @@ void CClient::UserCommand(CString& sLine) {
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()) {
+4 -4
View File
@@ -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);
}
}
+12 -6
View File
@@ -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,8 +195,16 @@ public:
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
@@ -204,7 +212,6 @@ public:
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 @@ 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 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;
+2 -2
View File
@@ -148,7 +148,7 @@ public:
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 @@ public:
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);
+4 -3
View File
@@ -135,10 +135,11 @@ public:
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 @@ public:
return;
}
Py_CLEAR(pyRes);
if (x && ModInfo.GetType() == eType) {
if (x && ModInfo.SupportsType(eType)) {
ssMods.insert(ModInfo);
ssAlready.insert(sName);
}
+29 -9
View File
@@ -150,7 +150,7 @@ class ModuleNV(collections.MutableMapping):
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