1
0
mirror of https://github.com/anope/anope.git synced 2026-07-02 23:43:12 +02:00

Added os_modreload. Also allow unloading database and encryption modules since there isn't a reason we cant allow reloading them. Soon os_modreload will allow reloading the protocol modules.

This commit is contained in:
Adam
2010-10-02 21:09:11 -04:00
parent 0d684191e9
commit 90f0a7c92a
9 changed files with 173 additions and 49 deletions
+1 -1
View File
@@ -1339,7 +1339,7 @@ operserv
* The core modules to load for OperServ. This is a space separated list that corresponds
* to the base names of the modules for OperServ. This directive is optional, but highly recommended.
*/
modules = "os_help os_global os_stats os_staff os_mode os_kick os_clearmodes os_akill os_snline os_sqline os_szline os_chanlist os_userlist os_news os_session os_noop os_jupe os_ignore os_set os_reload os_update os_restart os_quit os_shutdown os_defcon os_chankill os_svsnick os_oline os_umode os_modload os_modunload os_modlist os_modinfo"
modules = "os_help os_global os_stats os_staff os_mode os_kick os_clearmodes os_akill os_snline os_sqline os_szline os_chanlist os_userlist os_news os_session os_noop os_jupe os_ignore os_set os_reload os_update os_restart os_quit os_shutdown os_defcon os_chankill os_svsnick os_oline os_umode os_modload os_modunload os_modreload os_modlist os_modinfo"
/*
* If set, Services Admins will be able to use SUPERADMIN [ON|OFF] which will temporarily grant
+1
View File
@@ -18,6 +18,7 @@ m_dnsbl added
** MODIFIED CONFIGURATION DIRECTIVES **
opertype:commands changed operserv/sgline to opserv/snline
operserv:modules changed os_sgline to os_snline
operserv:modules added os_modreload
operserv:sglineexpiry changed to operserv:snlineexpiry
operserv:killonsgline changed to operserv:killonsnline
operserv:notifications ossgline changed ossnline
+4
View File
@@ -1121,6 +1121,7 @@ enum LanguageString
DEFCON_GLOBAL,
OPER_MODULE_LOADED,
OPER_MODULE_UNLOADED,
OPER_MODULE_RELOADED,
OPER_MODULE_LOAD_FAIL,
OPER_MODULE_REMOVE_FAIL,
OPER_MODULE_NO_UNLOAD,
@@ -1128,6 +1129,7 @@ enum LanguageString
OPER_MODULE_ISNT_LOADED,
OPER_MODULE_LOAD_SYNTAX,
OPER_MODULE_UNLOAD_SYNTAX,
OPER_MODULE_RELOAD_SYNTAX,
OPER_MODULE_LIST_HEADER,
OPER_MODULE_LIST,
OPER_MODULE_LIST_FOOTER,
@@ -1514,6 +1516,7 @@ enum LanguageString
OPER_HELP_CMD_SVSNICK,
OPER_HELP_CMD_MODLOAD,
OPER_HELP_CMD_MODUNLOAD,
OPER_HELP_CMD_MODRELOAD,
OPER_HELP_CMD_MODINFO,
OPER_HELP_CMD_MODLIST,
OPER_HELP,
@@ -1550,6 +1553,7 @@ enum LanguageString
OPER_HELP_USERLIST,
OPER_HELP_MODLOAD,
OPER_HELP_MODUNLOAD,
OPER_HELP_MODRELOAD,
OPER_HELP_MODINFO,
OPER_HELP_MODLIST,
BOT_HELP_CMD_BOTLIST,
+5 -3
View File
@@ -148,7 +148,9 @@ enum ModuleReturn
MOD_ERR_UNKNOWN,
MOD_ERR_FILE_IO,
MOD_ERR_NOSERVICE,
MOD_ERR_NO_MOD_NAME
MOD_ERR_NO_MOD_NAME,
MOD_ERR_EXCEPTION,
MOD_ERR_VERSION
};
/** Priority types which can be returned from Module::Prioritize()
@@ -1106,14 +1108,14 @@ class CoreExport ModuleManager
* @param u the user who loaded it, NULL for auto-load
* @return MOD_ERR_OK on success, anything else on fail
*/
static int LoadModule(const Anope::string &modname, User *u);
static ModuleReturn LoadModule(const Anope::string &modname, User *u);
/** Unload the given module.
* @param m the module to unload
* @param u the user who unloaded it
* @return MOD_ERR_OK on success, anything else on fail
*/
static int UnloadModule(Module *m, User * u);
static ModuleReturn UnloadModule(Module *m, User * u);
/** Change the priority of one event in a module.
* Each module event has a list of modules which are attached to that event type. If you wish to be called before or after other specific modules, you may use this
+13 -3
View File
@@ -31,11 +31,21 @@ class CommandOSModLoad : public Command
return MOD_CONT;
}
int status = ModuleManager::LoadModule(mname, u);
if (status != MOD_ERR_OK)
ModuleReturn status = ModuleManager::LoadModule(mname, u);
if (status == MOD_ERR_OK)
{
u->SendMessage(OperServ, OPER_MODULE_LOAD_FAIL, mname.c_str());
ircdproto->SendGlobops(OperServ, "%s loaded module %s", u->nick.c_str(), mname.c_str());
u->SendMessage(OperServ, OPER_MODULE_LOADED, mname.c_str());
/* If a user is loading this module, then the core databases have already been loaded
* so trigger the event manually
*/
m = FindModule(mname);
if (m)
m->OnPostLoadDatabases();
}
else
u->SendMessage(OperServ, OPER_MODULE_LOAD_FAIL, mname.c_str());
return MOD_CONT;
}
+112
View File
@@ -0,0 +1,112 @@
/* OperServ core functions
*
* (C) 2003-2010 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
*
* Based on the original code of Epona by Lara.
* Based on the original code of Services by Andy Church.
*/
/*************************************************************************/
#include "module.h"
class CommandOSModReLoad : public Command
{
public:
CommandOSModReLoad() : Command("MODRELOAD", 1, 1, "operserv/modload")
{
}
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
{
Anope::string mname = params[0];
Module *m = FindModule(mname);
if (!m)
{
u->SendMessage(OperServ, OPER_MODULE_ISNT_LOADED, mname.c_str());
return MOD_CONT;
}
if (!m->handle)
{
u->SendMessage(OperServ, OPER_MODULE_REMOVE_FAIL, m->name.c_str());
return MOD_CONT;
}
if (m->GetPermanent() || m->type == PROTOCOL) // TODO: make protocol modules reloadable
{
u->SendMessage(OperServ, OPER_MODULE_NO_UNLOAD);
return MOD_CONT;
}
/* Unrecoverable */
bool fatal = m->type == PROTOCOL;
ModuleReturn status = ModuleManager::UnloadModule(m, u);
if (status != MOD_ERR_OK)
{
u->SendMessage(OperServ, OPER_MODULE_REMOVE_FAIL, mname.c_str());
return MOD_CONT;
}
status = ModuleManager::LoadModule(mname, u);
if (status == MOD_ERR_OK)
{
ircdproto->SendGlobops(OperServ, "%s reloaded module %s", u->nick.c_str(), mname.c_str());
u->SendMessage(OperServ, OPER_MODULE_RELOADED, mname.c_str());
/* If a user is loading this module, then the core databases have already been loaded
* so trigger the event manually
*/
m = FindModule(mname);
if (m)
m->OnPostLoadDatabases();
}
else
{
if (fatal)
throw FatalException("Unable to reload module " + mname);
else
u->SendMessage(OperServ, OPER_MODULE_LOAD_FAIL, mname.c_str());
}
return MOD_CONT;
}
bool OnHelp(User *u, const Anope::string &subcommand)
{
u->SendMessage(OperServ, OPER_HELP_MODRELOAD);
return true;
}
void OnSyntaxError(User *u, const Anope::string &subcommand)
{
SyntaxError(OperServ, u, "MODLOAD", OPER_MODULE_RELOAD_SYNTAX);
}
void OnServHelp(User *u)
{
u->SendMessage(OperServ, OPER_HELP_CMD_MODRELOAD);
}
};
class OSModReLoad : public Module
{
CommandOSModReLoad commandosmodreload;
public:
OSModReLoad(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
{
this->SetAuthor("Anope");
this->SetType(CORE);
this->SetPermanent(true);
this->AddCommand(OperServ, &commandosmodreload);
}
};
MODULE_INIT(OSModReLoad)
+19 -3
View File
@@ -23,7 +23,6 @@ class CommandOSModUnLoad : public Command
CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
{
Anope::string mname = params[0];
int status;
Module *m = FindModule(mname);
if (!m)
@@ -31,12 +30,29 @@ class CommandOSModUnLoad : public Command
u->SendMessage(OperServ, OPER_MODULE_ISNT_LOADED, mname.c_str());
return MOD_CONT;
}
if (!m->handle)
{
u->SendMessage(OperServ, OPER_MODULE_REMOVE_FAIL, m->name.c_str());
return MOD_CONT;
}
if (m->GetPermanent() || m->type == PROTOCOL)
{
u->SendMessage(OperServ, OPER_MODULE_NO_UNLOAD);
return MOD_CONT;
}
Log() << "Trying to unload module [" << mname << "]";
status = ModuleManager::UnloadModule(m, u);
ModuleReturn status = ModuleManager::UnloadModule(m, u);
if (status != MOD_ERR_OK)
if (status == MOD_ERR_OK)
{
u->SendMessage(OperServ, OPER_MODULE_UNLOADED, mname.c_str());
ircdproto->SendGlobops(OperServ, "%s unloaded module %s", u->nick.c_str(), mname.c_str());
}
else
u->SendMessage(OperServ, OPER_MODULE_REMOVE_FAIL, mname.c_str());
return MOD_CONT;
+10
View File
@@ -2430,6 +2430,8 @@ Anope::string language_strings[LANG_STRING_COUNT] = {
_("Module %s loaded"),
/* OPER_MODULE_UNLOADED */
_("Module %s unloaded"),
/* OPER_MODULE_RELOADED */
_("Module \002%s\002 reloaded"),
/* OPER_MODULE_LOAD_FAIL */
_("Unable to load module %s"),
/* OPER_MODULE_REMOVE_FAIL */
@@ -2444,6 +2446,8 @@ Anope::string language_strings[LANG_STRING_COUNT] = {
_("MODLOAD FileName"),
/* OPER_MODULE_UNLOAD_SYNTAX */
_("MODUNLOAD FileName"),
/* OPER_MODULE_RELOAD_SYNTAX */
_("MODRELOAD \037FileName\037"),
/* OPER_MODULE_LIST_HEADER */
_("Current Module list:"),
/* OPER_MODULE_LIST */
@@ -4570,6 +4574,8 @@ Anope::string language_strings[LANG_STRING_COUNT] = {
_(" MODLOAD Load a module"),
/* OPER_HELP_CMD_MODUNLOAD */
_(" MODUNLOAD Un-Load a module"),
/* OPER_HELP_CMD_MODRELOAD */
_(" MODRELOAD Reload a module"),
/* OPER_HELP_CMD_MODINFO */
_(" MODINFO Info about a loaded module"),
/* OPER_HELP_CMD_MODLIST */
@@ -4977,6 +4983,10 @@ Anope::string language_strings[LANG_STRING_COUNT] = {
" \n"
"This command unloads the module named FileName from the modules\n"
"directory."),
/* OPER_HELP_MODRELOAD */
_("Syntax: \002MODRELOAD\002 \002FileName\002\n"
" \n"
"This command reloads the module named FileName."),
/* OPER_HELP_MODINFO */
_("Syntax: MODINFO FileName\n"
" \n"
+8 -39
View File
@@ -28,7 +28,7 @@ void ModuleManager::LoadModuleList(std::list<Anope::string> &ModuleList)
* @param output the destination to copy the module to
* @return MOD_ERR_OK on success
*/
static int moduleCopyFile(const Anope::string &name, Anope::string &output)
static ModuleReturn moduleCopyFile(const Anope::string &name, Anope::string &output)
{
Anope::string input = services_dir + "/modules/" + name + ".so";
FILE *source = fopen(input.c_str(), "rb");
@@ -107,7 +107,7 @@ template <class TYPE> TYPE function_cast(ano_module_t symbol)
return cast.function;
}
int ModuleManager::LoadModule(const Anope::string &modname, User *u)
ModuleReturn ModuleManager::LoadModule(const Anope::string &modname, User *u)
{
if (modname.empty())
return MOD_ERR_PARAMS;
@@ -121,7 +121,7 @@ int ModuleManager::LoadModule(const Anope::string &modname, User *u)
Anope::string pbuf = services_dir + "/modules/runtime/" + modname + ".so.XXXXXX";
/* Don't skip return value checking! -GD */
int ret = moduleCopyFile(modname, pbuf);
ModuleReturn ret = moduleCopyFile(modname, pbuf);
if (ret != MOD_ERR_OK)
{
/* XXX: This used to assign filename here, but I don't think that was correct..
@@ -167,7 +167,7 @@ int ModuleManager::LoadModule(const Anope::string &modname, User *u)
catch (const ModuleException &ex)
{
Log() << "Error while loading " << modname << ": " << ex.GetReason();
return MOD_STOP;
return MOD_ERR_EXCEPTION;
}
m->filename = pbuf;
@@ -178,13 +178,13 @@ int ModuleManager::LoadModule(const Anope::string &modname, User *u)
{
Log() << "Module " << modname << " is compiled against an older version of Anope " << v.GetMajor() << "." << v.GetMinor() << ", this is " << VERSION_MAJOR << "." << VERSION_MINOR;
DeleteModule(m);
return MOD_STOP;
return MOD_ERR_VERSION;
}
else if (v.GetMajor() > VERSION_MAJOR || (v.GetMajor() == VERSION_MAJOR && v.GetMinor() > VERSION_MINOR))
{
Log() << "Module " << modname << " is compiled against a newer version of Anope " << v.GetMajor() << "." << v.GetMinor() << ", this is " << VERSION_MAJOR << "." << VERSION_MINOR;
DeleteModule(m);
return MOD_STOP;
return MOD_ERR_VERSION;
}
else if (v.GetBuild() < VERSION_BUILD)
Log() << "Module " << modname << " is compiled against an older revision of Anope " << v.GetBuild() << ", this is " << VERSION_BUILD;
@@ -197,18 +197,7 @@ int ModuleManager::LoadModule(const Anope::string &modname, User *u)
{
DeleteModule(m);
Log() << "You cannot load two protocol modules";
return MOD_STOP;
}
if (u)
{
ircdproto->SendGlobops(OperServ, "%s loaded module %s", u->nick.c_str(), modname.c_str());
u->SendMessage(OperServ, OPER_MODULE_LOADED, modname.c_str());
/* If a user is loading this module, then the core databases have already been loaded
* so trigger the event manually
*/
m->OnPostLoadDatabases();
return MOD_ERR_UNKNOWN;
}
FOREACH_MOD(I_OnModuleLoad, OnModuleLoad(u, m));
@@ -216,28 +205,8 @@ int ModuleManager::LoadModule(const Anope::string &modname, User *u)
return MOD_ERR_OK;
}
int ModuleManager::UnloadModule(Module *m, User *u)
ModuleReturn ModuleManager::UnloadModule(Module *m, User *u)
{
if (!m || !m->handle)
{
if (u)
u->SendMessage(OperServ, OPER_MODULE_REMOVE_FAIL, m->name.c_str());
return MOD_ERR_PARAMS;
}
if (m->GetPermanent() || m->type == PROTOCOL || m->type == ENCRYPTION || m->type == DATABASE)
{
if (u)
u->SendMessage(OperServ, OPER_MODULE_NO_UNLOAD);
return MOD_ERR_NOUNLOAD;
}
if (u)
{
ircdproto->SendGlobops(OperServ, "%s unloaded module %s", u->nick.c_str(), m->name.c_str());
u->SendMessage(OperServ, OPER_MODULE_UNLOADED, m->name.c_str());
}
FOREACH_MOD(I_OnModuleUnload, OnModuleUnload(u, m));
if (DNSEngine)