mirror of
https://github.com/anope/anope.git
synced 2026-07-08 23:43:13 +02:00
Move loadModule() and unloadModule() inside ModuleManager::
git-svn-id: http://anope.svn.sourceforge.net/svnroot/anope/trunk@1614 5417fbe8-f217-4b02-8779-1006273d7864
This commit is contained in:
+42
-25
@@ -132,27 +132,19 @@ struct ModuleLang_ {
|
||||
char **argv;
|
||||
};
|
||||
|
||||
/** Used to manage modules.
|
||||
*/
|
||||
CoreExport class ModuleManager
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Load up a list of modules.
|
||||
* @param total_modules The number of modules to load
|
||||
* @param module_list The list of modules to load
|
||||
**/
|
||||
static void LoadModuleList(int total_modules, char **module_list);
|
||||
};
|
||||
|
||||
/** Every module in Anope is actually a class.
|
||||
*/
|
||||
CoreExport class Module
|
||||
{
|
||||
public:
|
||||
// XXX :(
|
||||
/** The module name (e.g. os_modload)
|
||||
*/
|
||||
std::string name;
|
||||
char *filename;
|
||||
|
||||
/** The temporary path/filename
|
||||
*/
|
||||
std::string filename;
|
||||
|
||||
void *handle;
|
||||
time_t time;
|
||||
std::string version;
|
||||
@@ -250,6 +242,40 @@ CoreExport class Module
|
||||
int DelCommand(CommandHash * cmdTable[], const char *name);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/** Used to manage modules.
|
||||
*/
|
||||
CoreExport class ModuleManager
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Load up a list of modules.
|
||||
* @param total_modules The number of modules to load
|
||||
* @param module_list The list of modules to load
|
||||
**/
|
||||
static void LoadModuleList(int total_modules, char **module_list);
|
||||
|
||||
/**
|
||||
* Loads a given module.
|
||||
* @param m the module to load
|
||||
* @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 std::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);
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct ModuleHash_ {
|
||||
char *name;
|
||||
Module *m;
|
||||
@@ -354,17 +380,8 @@ int addModule(Module *m); /* Add a module to the module hash */
|
||||
int delModule(Module *m); /* Remove a module from the module hash */
|
||||
MDE Module *findModule(const char *name); /* Find a module */
|
||||
|
||||
/** Loads a given Anope module into the core, initialising relevant structures,
|
||||
* and calls the module's constructor.
|
||||
* @param modname The name of the module to load (e.g. os_modload)
|
||||
* @param u The user loading the module, or NULL for no user.
|
||||
* @return XXX, document me.
|
||||
*/
|
||||
int loadModule(const std::string &modname, User *u);
|
||||
|
||||
int encryption_module_init(void); /* Load the encryption module */
|
||||
int protocol_module_init(void); /* Load the IRCD Protocol Module up*/
|
||||
int unloadModule(Module *m, User *u); /* Unload the given module from the pro */
|
||||
void moduleCallBackPrepForUnload(const char *mod_name);
|
||||
MDE void moduleCallBackDeleteEntry(ModuleCallBack * prev);
|
||||
MDE char *moduleGetLastBuffer(void);
|
||||
@@ -424,7 +441,7 @@ int destroyEventHook(EvtHook * evh);
|
||||
|
||||
MDE void moduleInsertLanguage(int langNumber, int ac, const char **av);
|
||||
MDE void moduleNoticeLang(char *source, User *u, int number, ...);
|
||||
MDE char *moduleGetLangString(User * u, int number);
|
||||
MDE const char *moduleGetLangString(User * u, int number);
|
||||
MDE void moduleDeleteLanguage(int langNumber);
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
@@ -71,7 +71,7 @@ int do_modload(User * u)
|
||||
return MOD_CONT;
|
||||
}
|
||||
|
||||
int status = loadModule(name, u);
|
||||
int status = ModuleManager::LoadModule(name, u);
|
||||
if (status != MOD_ERR_OK)
|
||||
{
|
||||
notice_lang(s_OperServ, u, OPER_MODULE_LOAD_FAIL, m->name.c_str());
|
||||
|
||||
@@ -75,7 +75,7 @@ int do_modunload(User *u)
|
||||
|
||||
alog("Trying to unload module [%s]", name);
|
||||
|
||||
status = unloadModule(m, u);
|
||||
status = ModuleManager::UnloadModule(m, u);
|
||||
|
||||
if (!status)
|
||||
{
|
||||
|
||||
+1
-6
@@ -21,7 +21,6 @@
|
||||
Module::Module(const std::string &mname, const std::string &creator)
|
||||
{
|
||||
this->name = mname; /* Our name */
|
||||
this->filename = NULL;
|
||||
this->nickHelp = NULL;
|
||||
this->chanHelp = NULL;
|
||||
this->memoHelp = NULL;
|
||||
@@ -46,11 +45,7 @@ Module::~Module()
|
||||
for (i = 0; i < NUM_LANGS; i++)
|
||||
moduleDeleteLanguage(i);
|
||||
|
||||
if (this->filename)
|
||||
{
|
||||
remove(this->filename);
|
||||
free(this->filename);
|
||||
}
|
||||
remove(this->filename.c_str());
|
||||
|
||||
if (this->handle)
|
||||
{
|
||||
|
||||
+242
-1
@@ -12,6 +12,12 @@
|
||||
#include "language.h"
|
||||
#include "version.h"
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#include <dlfcn.h>
|
||||
#else
|
||||
const char *ano_moderr(void);
|
||||
#endif
|
||||
|
||||
void ModuleManager::LoadModuleList(int total_modules, char **module_list)
|
||||
{
|
||||
int idx;
|
||||
@@ -20,9 +26,244 @@ void ModuleManager::LoadModuleList(int total_modules, char **module_list)
|
||||
for (idx = 0; idx < total_modules; idx++) {
|
||||
m = findModule(module_list[idx]);
|
||||
if (!m) {
|
||||
status = loadModule(module_list[idx], NULL);
|
||||
status = ModuleManager::LoadModule(module_list[idx], NULL);
|
||||
mod_current_module = NULL;
|
||||
mod_current_user = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the module from the modules folder to the runtime folder.
|
||||
* This will prevent module updates while the modules is loaded from
|
||||
* triggering a segfault, as the actaul file in use will be in the
|
||||
* runtime folder.
|
||||
* @param name the name of the module to copy
|
||||
* @param output the destination to copy the module to
|
||||
* @return MOD_ERR_OK on success
|
||||
*/
|
||||
static int moduleCopyFile(const char *name, const char *output)
|
||||
{
|
||||
int ch;
|
||||
FILE *source, *target;
|
||||
int srcfp;
|
||||
char input[4096];
|
||||
int len;
|
||||
|
||||
strncpy(input, MODULE_PATH, 4095); /* Get full path with module extension */
|
||||
len = strlen(input);
|
||||
strncat(input, name, 4095 - len);
|
||||
len = strlen(output);
|
||||
strncat(input, MODULE_EXT, 4095 - len);
|
||||
|
||||
#ifndef _WIN32
|
||||
if ((srcfp = mkstemp((char *)output)) == -1)
|
||||
return MOD_ERR_FILE_IO;
|
||||
#else
|
||||
if (!mktemp(output))
|
||||
return MOD_ERR_FILE_IO;
|
||||
#endif
|
||||
|
||||
if (debug)
|
||||
alog("Runtime module location: %s", output);
|
||||
|
||||
/* Linux/UNIX should ignore the b param, why do we still have seperate
|
||||
* calls for it here? -GD
|
||||
*/
|
||||
#ifndef _WIN32
|
||||
if ((source = fopen(input, "r")) == NULL) {
|
||||
#else
|
||||
if ((source = fopen(input, "rb")) == NULL) {
|
||||
#endif
|
||||
return MOD_ERR_NOEXIST;
|
||||
}
|
||||
#ifndef _WIN32
|
||||
if ((target = fdopen(srcfp, "w")) == NULL) {
|
||||
#else
|
||||
if ((target = fopen(output, "wb")) == NULL) {
|
||||
#endif
|
||||
return MOD_ERR_FILE_IO;
|
||||
}
|
||||
while ((ch = fgetc(source)) != EOF) {
|
||||
fputc(ch, target);
|
||||
}
|
||||
fclose(source);
|
||||
if (fclose(target) != 0) {
|
||||
return MOD_ERR_FILE_IO;
|
||||
}
|
||||
return MOD_ERR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search all loaded modules looking for a protocol module.
|
||||
* @return 1 if one is found.
|
||||
**/
|
||||
static int protocolModuleLoaded()
|
||||
{
|
||||
int idx = 0;
|
||||
ModuleHash *current = NULL;
|
||||
|
||||
for (idx = 0; idx != MAX_CMD_HASH; idx++) {
|
||||
for (current = MODULE_HASH[idx]; current; current = current->next) {
|
||||
if (current->m->type == PROTOCOL) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search all loaded modules looking for an encryption module.
|
||||
* @ return 1 if one is loaded
|
||||
**/
|
||||
static int encryptionModuleLoaded()
|
||||
{
|
||||
int idx = 0;
|
||||
ModuleHash *current = NULL;
|
||||
|
||||
for (idx = 0; idx != MAX_CMD_HASH; idx++) {
|
||||
for (current = MODULE_HASH[idx]; current; current = current->next) {
|
||||
if (current->m->type == ENCRYPTION) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ModuleManager::LoadModule(const std::string &modname, User * u)
|
||||
{
|
||||
int len;
|
||||
const char *err;
|
||||
Module * (*func) (const std::string &);
|
||||
int ret = 0;
|
||||
|
||||
if (modname.empty())
|
||||
return MOD_ERR_PARAMS;
|
||||
|
||||
if (findModule(modname.c_str()) != NULL)
|
||||
return MOD_ERR_EXISTS;
|
||||
|
||||
if (debug)
|
||||
alog("trying to load [%s]", modname.c_str());
|
||||
|
||||
/* Generate the filename for the temporary copy of the module */
|
||||
std::string pbuf;
|
||||
pbuf = MODULE_PATH;
|
||||
#ifndef _WIN32
|
||||
pbuf += "runtime/";
|
||||
#else
|
||||
pbuf += "runtime\\";
|
||||
#endif
|
||||
pbuf += modname;
|
||||
pbuf += MODULE_EXT;
|
||||
pbuf += ".";
|
||||
pbuf += "XXXXXX";
|
||||
|
||||
/* Don't skip return value checking! -GD */
|
||||
if ((ret = moduleCopyFile(modname.c_str(), pbuf.c_str())) != MOD_ERR_OK)
|
||||
{
|
||||
/* XXX: This used to assign filename here, but I don't think that was correct..
|
||||
* even if it was, it makes life very fucking difficult, so.
|
||||
*/
|
||||
return ret;
|
||||
}
|
||||
|
||||
ano_modclearerr();
|
||||
|
||||
void *handle = ano_modopen(pbuf.c_str());
|
||||
if (handle == NULL && (err = ano_moderr()) != NULL)
|
||||
{
|
||||
alog("%s", err);
|
||||
return MOD_ERR_NOLOAD;
|
||||
}
|
||||
|
||||
ano_modclearerr();
|
||||
func = (Module *(*)(const std::string &))ano_modsym(handle, "init_module");
|
||||
if (func == NULL && (err = ano_moderr()) != NULL)
|
||||
{
|
||||
alog("No magical init function found, not an Anope module");
|
||||
ano_modclose(handle);
|
||||
return MOD_ERR_NOLOAD;
|
||||
}
|
||||
|
||||
if (!func)
|
||||
{
|
||||
throw CoreException("Couldn't find constructor, yet moderror wasn't set?");
|
||||
}
|
||||
|
||||
mod_current_module_name = modname.c_str();
|
||||
|
||||
/* Create module. */
|
||||
std::string nick;
|
||||
if (u)
|
||||
nick = u->nick;
|
||||
else
|
||||
nick = "";
|
||||
|
||||
Module *m;
|
||||
|
||||
try
|
||||
{
|
||||
m = func(nick);
|
||||
}
|
||||
catch (ModuleException &ex)
|
||||
{
|
||||
alog("Error while loading %s: %s", modname.c_str(), ex.GetReason());
|
||||
return MOD_STOP;
|
||||
}
|
||||
|
||||
mod_current_module = m;
|
||||
mod_current_user = u;
|
||||
m->filename = pbuf;
|
||||
m->handle = handle;
|
||||
|
||||
if (m->type == PROTOCOL && protocolModuleLoaded())
|
||||
{
|
||||
alog("You cannot load two protocol modules");
|
||||
ret = MOD_STOP;
|
||||
}
|
||||
else if (m->type == ENCRYPTION && encryptionModuleLoaded())
|
||||
{
|
||||
alog("You cannot load two encryption modules");
|
||||
ret = MOD_STOP;
|
||||
}
|
||||
|
||||
mod_current_module_name = NULL;
|
||||
|
||||
if (u)
|
||||
{
|
||||
ircdproto->SendGlobops(s_OperServ, "%s loaded module %s", u->nick, modname.c_str());
|
||||
notice_lang(s_OperServ, u, OPER_MODULE_LOADED, modname.c_str());
|
||||
}
|
||||
addModule(m);
|
||||
return MOD_ERR_OK;
|
||||
}
|
||||
|
||||
int ModuleManager::UnloadModule(Module * m, User * u)
|
||||
{
|
||||
if (!m || !m->handle)
|
||||
{
|
||||
if (u)
|
||||
notice_lang(s_OperServ, u, OPER_MODULE_REMOVE_FAIL, m->name.c_str());
|
||||
return MOD_ERR_PARAMS;
|
||||
}
|
||||
|
||||
if (m->type == PROTOCOL || m->type == ENCRYPTION)
|
||||
{
|
||||
if (u)
|
||||
notice_lang(s_OperServ, u, OPER_MODULE_NO_UNLOAD);
|
||||
return MOD_ERR_NOUNLOAD;
|
||||
}
|
||||
|
||||
if (u)
|
||||
{
|
||||
ircdproto->SendGlobops(s_OperServ, "%s unloaded module %s", u->nick, m->name.c_str());
|
||||
notice_lang(s_OperServ, u, OPER_MODULE_UNLOADED, m->name.c_str());
|
||||
}
|
||||
|
||||
delModule(m);
|
||||
return MOD_ERR_OK;
|
||||
}
|
||||
|
||||
|
||||
+7
-273
@@ -177,7 +177,7 @@ int encryption_module_init(void) {
|
||||
int ret = 0;
|
||||
|
||||
alog("Loading Encryption Module: [%s]", EncModule);
|
||||
ret = loadModule(EncModule, NULL);
|
||||
ret = ModuleManager::LoadModule(EncModule, NULL);
|
||||
if (ret == MOD_ERR_OK)
|
||||
findModule(EncModule)->SetType(ENCRYPTION);
|
||||
mod_current_module = NULL;
|
||||
@@ -192,7 +192,7 @@ int protocol_module_init(void)
|
||||
int ret = 0;
|
||||
|
||||
alog("Loading IRCD Protocol Module: [%s]", IRCDModule);
|
||||
ret = loadModule(IRCDModule, NULL);
|
||||
ret = ModuleManager::LoadModule(IRCDModule, NULL);
|
||||
|
||||
if (ret == MOD_ERR_OK)
|
||||
{
|
||||
@@ -368,272 +368,6 @@ Module *findModule(const char *name)
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Search all loaded modules looking for a protocol module.
|
||||
* @return 1 if one is found.
|
||||
**/
|
||||
int protocolModuleLoaded()
|
||||
{
|
||||
int idx = 0;
|
||||
ModuleHash *current = NULL;
|
||||
|
||||
for (idx = 0; idx != MAX_CMD_HASH; idx++) {
|
||||
for (current = MODULE_HASH[idx]; current; current = current->next) {
|
||||
if (current->m->type == PROTOCOL) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search all loaded modules looking for an encryption module.
|
||||
* @ return 1 if one is loaded
|
||||
**/
|
||||
int encryptionModuleLoaded()
|
||||
{
|
||||
int idx = 0;
|
||||
ModuleHash *current = NULL;
|
||||
|
||||
for (idx = 0; idx != MAX_CMD_HASH; idx++) {
|
||||
for (current = MODULE_HASH[idx]; current; current = current->next) {
|
||||
if (current->m->type == ENCRYPTION) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the module from the modules folder to the runtime folder.
|
||||
* This will prevent module updates while the modules is loaded from
|
||||
* triggering a segfault, as the actaul file in use will be in the
|
||||
* runtime folder.
|
||||
* @param name the name of the module to copy
|
||||
* @param output the destination to copy the module to
|
||||
* @return MOD_ERR_OK on success
|
||||
*/
|
||||
static int moduleCopyFile(const char *name, char *output)
|
||||
{
|
||||
int ch;
|
||||
FILE *source, *target;
|
||||
int srcfp;
|
||||
char input[4096];
|
||||
int len;
|
||||
|
||||
strncpy(input, MODULE_PATH, 4095); /* Get full path with module extension */
|
||||
len = strlen(input);
|
||||
strncat(input, name, 4095 - len);
|
||||
len = strlen(output);
|
||||
strncat(input, MODULE_EXT, 4095 - len);
|
||||
|
||||
#ifndef _WIN32
|
||||
if ((srcfp = mkstemp(output)) == -1)
|
||||
return MOD_ERR_FILE_IO;
|
||||
#else
|
||||
if (!mktemp(output))
|
||||
return MOD_ERR_FILE_IO;
|
||||
#endif
|
||||
|
||||
if (debug)
|
||||
alog("Runtime module location: %s", output);
|
||||
|
||||
/* Linux/UNIX should ignore the b param, why do we still have seperate
|
||||
* calls for it here? -GD
|
||||
*/
|
||||
#ifndef _WIN32
|
||||
if ((source = fopen(input, "r")) == NULL) {
|
||||
#else
|
||||
if ((source = fopen(input, "rb")) == NULL) {
|
||||
#endif
|
||||
return MOD_ERR_NOEXIST;
|
||||
}
|
||||
#ifndef _WIN32
|
||||
if ((target = fdopen(srcfp, "w")) == NULL) {
|
||||
#else
|
||||
if ((target = fopen(output, "wb")) == NULL) {
|
||||
#endif
|
||||
return MOD_ERR_FILE_IO;
|
||||
}
|
||||
while ((ch = fgetc(source)) != EOF) {
|
||||
fputc(ch, target);
|
||||
}
|
||||
fclose(source);
|
||||
if (fclose(target) != 0) {
|
||||
return MOD_ERR_FILE_IO;
|
||||
}
|
||||
return MOD_ERR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a given module.
|
||||
* @param m the module to load
|
||||
* @param u the user who loaded it, NULL for auto-load
|
||||
* @return MOD_ERR_OK on success, anything else on fail
|
||||
*/
|
||||
int loadModule(const std::string &modname, User * u)
|
||||
{
|
||||
char buf[4096];
|
||||
int len;
|
||||
const char *err;
|
||||
Module * (*func) (const std::string &);
|
||||
int ret = 0;
|
||||
|
||||
if (modname.empty())
|
||||
return MOD_ERR_PARAMS;
|
||||
|
||||
if (findModule(modname.c_str()) != NULL)
|
||||
return MOD_ERR_EXISTS;
|
||||
|
||||
if (debug)
|
||||
alog("trying to load [%s]", modname.c_str());
|
||||
|
||||
/* Generate the filename for the temporary copy of the module */
|
||||
strncpy(buf, MODULE_PATH, 4095); /* Get full path with module extension */
|
||||
len = strlen(buf);
|
||||
#ifndef _WIN32
|
||||
strncat(buf, "runtime/", 4095 - len);
|
||||
#else
|
||||
strncat(buf, "runtime\\", 4095 - len);
|
||||
#endif
|
||||
len = strlen(buf);
|
||||
strncat(buf, modname.c_str(), 4095 - len);
|
||||
len = strlen(buf);
|
||||
strncat(buf, MODULE_EXT, 4095 - len);
|
||||
len = strlen(buf);
|
||||
strncat(buf, ".", 4095 - len);
|
||||
len = strlen(buf);
|
||||
strncat(buf, "XXXXXX", 4095 - len);
|
||||
buf[4095] = '\0';
|
||||
/* Don't skip return value checking! -GD */
|
||||
if ((ret = moduleCopyFile(modname.c_str(), buf)) != MOD_ERR_OK)
|
||||
{
|
||||
/* XXX: This used to assign filename here, but I don't think that was correct..
|
||||
* even if it was, it makes life very fucking difficult, so.
|
||||
*/
|
||||
// m->filename = sstrdup(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ano_modclearerr();
|
||||
|
||||
void *handle = ano_modopen(buf);
|
||||
if (handle == NULL && (err = ano_moderr()) != NULL)
|
||||
{
|
||||
alog("%s", err);
|
||||
return MOD_ERR_NOLOAD;
|
||||
}
|
||||
|
||||
ano_modclearerr();
|
||||
func = (Module *(*)(const std::string &))ano_modsym(handle, "init_module");
|
||||
if (func == NULL && (err = ano_moderr()) != NULL)
|
||||
{
|
||||
alog("No magical init function found, not an Anope module, or a very old module(?)");
|
||||
ano_modclose(handle); /* If no AnopeInit - it isnt an Anope Module, close it */
|
||||
return MOD_ERR_NOLOAD;
|
||||
}
|
||||
|
||||
if (!func)
|
||||
{
|
||||
throw CoreException("Couldn't find constructor, yet moderror wasn't set?");
|
||||
}
|
||||
|
||||
mod_current_module_name = modname.c_str();
|
||||
|
||||
/* Create module. */
|
||||
std::string nick;
|
||||
if (u)
|
||||
nick = u->nick;
|
||||
else
|
||||
nick = "";
|
||||
|
||||
Module *m;
|
||||
|
||||
try
|
||||
{
|
||||
m = func(nick);
|
||||
}
|
||||
catch (ModuleException &ex)
|
||||
{
|
||||
alog("Error while loading %s: %s", modname.c_str(), ex.GetReason());
|
||||
return MOD_STOP;
|
||||
}
|
||||
|
||||
mod_current_module = m;
|
||||
mod_current_user = u;
|
||||
m->filename = sstrdup(buf);
|
||||
m->handle = handle;
|
||||
|
||||
/*
|
||||
if (ret == MOD_STOP) {
|
||||
alog("%s requested unload...", m->name);
|
||||
unloadModule(m, NULL);
|
||||
mod_current_module_name = NULL;
|
||||
return MOD_ERR_NOLOAD;
|
||||
}
|
||||
*/
|
||||
if (m->type == PROTOCOL && protocolModuleLoaded())
|
||||
{
|
||||
alog("You cannot load two protocol modules");
|
||||
ret = MOD_STOP;
|
||||
}
|
||||
else if (m->type == ENCRYPTION && encryptionModuleLoaded())
|
||||
{
|
||||
alog("You cannot load two encryption modules");
|
||||
ret = MOD_STOP;
|
||||
}
|
||||
|
||||
mod_current_module_name = NULL;
|
||||
|
||||
if (u)
|
||||
{
|
||||
ircdproto->SendGlobops(s_OperServ, "%s loaded module %s", u->nick, modname.c_str());
|
||||
notice_lang(s_OperServ, u, OPER_MODULE_LOADED, modname.c_str());
|
||||
}
|
||||
addModule(m);
|
||||
return MOD_ERR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
int unloadModule(Module * m, User * u)
|
||||
{
|
||||
void (*func) (void);
|
||||
|
||||
if (!m || !m->handle) {
|
||||
if (u) {
|
||||
notice_lang(s_OperServ, u, OPER_MODULE_REMOVE_FAIL, m->name.c_str());
|
||||
}
|
||||
return MOD_ERR_PARAMS;
|
||||
}
|
||||
|
||||
if (m->type == PROTOCOL) {
|
||||
if (u) {
|
||||
notice_lang(s_OperServ, u, OPER_MODULE_NO_UNLOAD);
|
||||
}
|
||||
return MOD_ERR_NOUNLOAD;
|
||||
} else if(m->type == ENCRYPTION) {
|
||||
if (u) {
|
||||
notice_lang(s_OperServ, u, OPER_MODULE_NO_UNLOAD);
|
||||
}
|
||||
return MOD_ERR_NOUNLOAD;
|
||||
}
|
||||
|
||||
if (u) {
|
||||
ircdproto->SendGlobops(s_OperServ, "%s unloaded module %s", u->nick,
|
||||
m->name.c_str());
|
||||
notice_lang(s_OperServ, u, OPER_MODULE_UNLOADED, m->name.c_str());
|
||||
}
|
||||
delModule(m);
|
||||
return MOD_ERR_OK;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Command Functions
|
||||
*******************************************************************************/
|
||||
@@ -949,13 +683,13 @@ static int internal_delCommand(CommandHash * cmdTable[], Command * c, const char
|
||||
* @param name the name of the command to delete from the service
|
||||
* @return returns MOD_ERR_OK on success
|
||||
*/
|
||||
int Module::DelCommand(CommandHash * cmdTable[], const char *name)
|
||||
int Module::DelCommand(CommandHash * cmdTable[], const char *dname)
|
||||
{
|
||||
Command *c = NULL;
|
||||
Command *cmd = NULL;
|
||||
int status = 0;
|
||||
|
||||
c = findCommand(cmdTable, name);
|
||||
c = findCommand(cmdTable, dname);
|
||||
if (!c) {
|
||||
return MOD_ERR_NOEXIST;
|
||||
}
|
||||
@@ -965,11 +699,11 @@ int Module::DelCommand(CommandHash * cmdTable[], const char *name)
|
||||
if (cmd->mod_name
|
||||
&& cmd->mod_name == this->name) {
|
||||
if (debug >= 2) {
|
||||
displayCommandFromHash(cmdTable, name);
|
||||
displayCommandFromHash(cmdTable, dname);
|
||||
}
|
||||
status = internal_delCommand(cmdTable, cmd, this->name.c_str());
|
||||
if (debug >= 2) {
|
||||
displayCommandFromHash(cmdTable, name);
|
||||
displayCommandFromHash(cmdTable, dname);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2176,7 +1910,7 @@ void moduleNoticeLang(char *source, User * u, int number, ...)
|
||||
* @param u The user to send the message to
|
||||
* @param number The message number
|
||||
**/
|
||||
char *moduleGetLangString(User * u, int number)
|
||||
const char *moduleGetLangString(User * u, int number)
|
||||
{
|
||||
int lang = NSDefLanguage;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user