mirror of
https://github.com/anope/anope.git
synced 2026-07-05 11:03:12 +02:00
Changed module callbacks to use new Timer API
git-svn-id: http://anope.svn.sourceforge.net/svnroot/anope/trunk@2338 5417fbe8-f217-4b02-8779-1006273d7864
This commit is contained in:
+21
-33
@@ -17,6 +17,7 @@
|
||||
#include <time.h>
|
||||
#include "services.h"
|
||||
#include <stdio.h>
|
||||
#include "timers.h"
|
||||
|
||||
/* Cross OS compatibility macros */
|
||||
#ifdef _WIN32
|
||||
@@ -194,7 +195,6 @@ typedef struct ModuleLang_ ModuleLang;
|
||||
typedef struct ModuleHash_ ModuleHash;
|
||||
typedef struct Message_ Message;
|
||||
typedef struct MessageHash_ MessageHash;
|
||||
typedef struct ModuleCallBack_ ModuleCallBack;
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
@@ -307,6 +307,10 @@ class CoreExport Module
|
||||
*/
|
||||
std::string filename;
|
||||
|
||||
/** Timers used in this module
|
||||
*/
|
||||
std::list<Timer *> CallBacks;
|
||||
|
||||
ano_module_t handle;
|
||||
time_t created;
|
||||
std::string version;
|
||||
@@ -448,23 +452,18 @@ class CoreExport Module
|
||||
int DelCommand(CommandHash * cmdTable[], const char *name);
|
||||
|
||||
/**
|
||||
* Adds a timed callback for the current module.
|
||||
* This allows modules to request that anope executes one of there functions at a time in the future, without an event to trigger it
|
||||
* @param name the name of the callback, this is used for refrence mostly, but is needed it you want to delete this particular callback later on
|
||||
* @param when when should the function be executed, this is a time in the future, seconds since 00:00:00 1970-01-01 UTC
|
||||
* @param func the function to be executed when the callback is ran, its format MUST be int func(int argc, char **argv);
|
||||
* @param argc the argument count for the argv paramter
|
||||
* @param atgv a argument list to be passed to the called function.
|
||||
* @return MOD_ERR_OK on success, anything else on fail.
|
||||
* @see moduleDelCallBack
|
||||
**/
|
||||
int AddCallback(const char *name, time_t when, int (*func) (int argc, char *argv[]), int argc, char **argv);
|
||||
* Adds a timer to the current module
|
||||
* The timer handling will take care of everything for this timer, this is only here
|
||||
* so we have a list of timers to destroy when this module is unloaded
|
||||
* @param t A timer derived class
|
||||
*/
|
||||
void AddCallBack(Timer *t);
|
||||
|
||||
/**
|
||||
* Allow modules to delete a timed callback by name.
|
||||
* @param name the name of the callback they wish to delete
|
||||
**/
|
||||
void DelCallback(const char *name);
|
||||
* Deletes a timer for the current module
|
||||
* @param t The timer
|
||||
*/
|
||||
bool DelCallBack(Timer *t);
|
||||
|
||||
/** Called when the ircd notifies that a user has been kicked from a channel.
|
||||
* @param c The channel the user has been kicked from.
|
||||
@@ -849,10 +848,6 @@ class CoreExport ModuleManager
|
||||
*/
|
||||
static int UnloadModule(Module *m, User * u);
|
||||
|
||||
/** Run all pending module timer callbacks.
|
||||
*/
|
||||
static void RunCallbacks();
|
||||
|
||||
/** 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
|
||||
* method (usually within void Module::Prioritize()) to set your events priority. You may use this call in other methods too, however, this is not supported behaviour
|
||||
@@ -904,6 +899,12 @@ class CoreExport ModuleManager
|
||||
* @param mod Module to attach events to
|
||||
*/
|
||||
static void Attach(Implementation* i, Module* mod, size_t sz);
|
||||
|
||||
/** Delete all timers attached to a module
|
||||
* @param m The module
|
||||
*/
|
||||
static void ClearTimers(Module *m);
|
||||
|
||||
private:
|
||||
/** Call the module_delete function to safely delete the module
|
||||
* @param m the module to delete
|
||||
@@ -938,25 +939,12 @@ struct MessageHash_ {
|
||||
MessageHash *next;
|
||||
};
|
||||
|
||||
struct ModuleCallBack_ {
|
||||
char *name;
|
||||
char *owner_name;
|
||||
time_t when;
|
||||
int (*func)(int argc, char *argv[]);
|
||||
int argc;
|
||||
char **argv;
|
||||
ModuleCallBack *next;
|
||||
};
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* Module Managment Functions */
|
||||
MDE Module *findModule(const char *name); /* Find a module */
|
||||
|
||||
int encryption_module_init(); /* Load the encryption module */
|
||||
int protocol_module_init(); /* Load the IRCD Protocol Module up*/
|
||||
void moduleCallBackPrepForUnload(const char *mod_name);
|
||||
MDE void moduleCallBackDeleteEntry(ModuleCallBack * prev);
|
||||
MDE void moduleDisplayHelp(const char *service, User *u);
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
@@ -475,8 +475,6 @@ int main(int ac, char **av, char **envp)
|
||||
if (delayed_quit)
|
||||
break;
|
||||
|
||||
ModuleManager::RunCallbacks();
|
||||
|
||||
if (t - last_check >= TimeoutCheck) {
|
||||
TimerManager::TickTimers(t);
|
||||
last_check = t;
|
||||
|
||||
+2
-2
@@ -66,8 +66,8 @@ Module::~Module()
|
||||
|
||||
Command *c;
|
||||
|
||||
/* Kill any active callbacks this module has */
|
||||
moduleCallBackPrepForUnload(this->name.c_str());
|
||||
/* Kill any active timers this module has */
|
||||
ModuleManager::ClearTimers(this);
|
||||
|
||||
/**
|
||||
* ok, im going to walk every hash looking for commands we own, now, not exactly elegant or efficiant :)
|
||||
|
||||
@@ -445,3 +445,21 @@ bool ModuleManager::SetPriority(Module* mod, Implementation i, Priority s, Modul
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Delete all timers attached to a module
|
||||
* @param m The module
|
||||
*/
|
||||
void ModuleManager::ClearTimers(Module *m)
|
||||
{
|
||||
std::list<Timer *>::iterator it;
|
||||
Timer *t2;
|
||||
|
||||
for (it = m->CallBacks.begin(); it != m->CallBacks.end(); ++it)
|
||||
{
|
||||
t2 = *it;
|
||||
|
||||
TimerManager::DelTimer(t2);
|
||||
}
|
||||
|
||||
m->CallBacks.clear();
|
||||
}
|
||||
|
||||
+24
-163
@@ -28,8 +28,6 @@ MessageHash *IRCD[MAX_CMD_HASH];
|
||||
ModuleHash *MODULE_HASH[MAX_CMD_HASH];
|
||||
|
||||
char *mod_current_buffer = NULL;
|
||||
ModuleCallBack *moduleCallBackHead = NULL;
|
||||
|
||||
|
||||
char *ModuleGetErrStr(int status)
|
||||
{
|
||||
@@ -621,159 +619,39 @@ int destroyMessage(Message * m)
|
||||
* Module Callback Functions
|
||||
*******************************************************************************/
|
||||
|
||||
int Module::AddCallback(const char *nname, time_t when,
|
||||
int (*func) (int argc, char *argv[]), int argc,
|
||||
char **argv)
|
||||
/**
|
||||
* Adds a timer to the current module
|
||||
* The timer handling will take care of everything for this timer, this is only here
|
||||
* so we have a list of timers to destroy when this module is unloaded
|
||||
* @param t A timer derived class
|
||||
*/
|
||||
void Module::AddCallBack(Timer *t)
|
||||
{
|
||||
ModuleCallBack *newcb, *tmp, *prev;
|
||||
int i;
|
||||
newcb = new ModuleCallBack;
|
||||
if (!newcb)
|
||||
return MOD_ERR_MEMORY;
|
||||
|
||||
if (nname)
|
||||
newcb->name = sstrdup(nname);
|
||||
else
|
||||
newcb->name = NULL;
|
||||
newcb->when = when;
|
||||
newcb->owner_name = sstrdup(this->name.c_str());
|
||||
newcb->func = func;
|
||||
newcb->argc = argc;
|
||||
newcb->argv = new char *[argc];
|
||||
for (i = 0; i < argc; i++) {
|
||||
newcb->argv[i] = sstrdup(argv[i]);
|
||||
}
|
||||
newcb->next = NULL;
|
||||
|
||||
if (moduleCallBackHead == NULL) {
|
||||
moduleCallBackHead = newcb;
|
||||
} else { /* find place in list */
|
||||
tmp = moduleCallBackHead;
|
||||
prev = tmp;
|
||||
if (newcb->when < tmp->when) {
|
||||
newcb->next = tmp;
|
||||
moduleCallBackHead = newcb;
|
||||
} else {
|
||||
while (tmp && newcb->when >= tmp->when) {
|
||||
prev = tmp;
|
||||
tmp = tmp->next;
|
||||
}
|
||||
prev->next = newcb;
|
||||
newcb->next = tmp;
|
||||
}
|
||||
}
|
||||
if (debug)
|
||||
alog("debug: added module CallBack: [%s] due to execute at %ld",
|
||||
newcb->name ? newcb->name : "?", static_cast<long>(newcb->when));
|
||||
return MOD_ERR_OK;
|
||||
this->CallBacks.push_back(t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a entry from the modules callback list
|
||||
* @param prev a pointer to the previous entry in the list, NULL for the head
|
||||
**/
|
||||
void moduleCallBackDeleteEntry(ModuleCallBack * prev)
|
||||
* Deletes a timer for the current module
|
||||
* @param t The timer
|
||||
*/
|
||||
bool Module::DelCallBack(Timer *t)
|
||||
{
|
||||
ModuleCallBack *tmp = NULL;
|
||||
int i;
|
||||
if (prev == NULL) {
|
||||
tmp = moduleCallBackHead;
|
||||
moduleCallBackHead = tmp->next;
|
||||
} else {
|
||||
tmp = prev->next;
|
||||
prev->next = tmp->next;
|
||||
}
|
||||
if (tmp->name)
|
||||
delete [] tmp->name;
|
||||
if (tmp->owner_name)
|
||||
delete [] tmp->owner_name;
|
||||
tmp->func = NULL;
|
||||
for (i = 0; i < tmp->argc; i++) {
|
||||
delete [] tmp->argv[i];
|
||||
}
|
||||
delete [] tmp->argv;
|
||||
tmp->argc = 0;
|
||||
tmp->next = NULL;
|
||||
delete tmp;
|
||||
}
|
||||
std::list<Timer *>::iterator it;
|
||||
Timer *t2;
|
||||
|
||||
/**
|
||||
* Search the module callback list for a given module
|
||||
* @param mod_name the name of the module were looking for
|
||||
* @param found have we found it?
|
||||
* @return a pointer to the ModuleCallBack struct or NULL - dont forget to check the found paramter!
|
||||
**/
|
||||
static ModuleCallBack *moduleCallBackFindEntry(const char *mod_name, bool * found)
|
||||
{
|
||||
ModuleCallBack *prev = NULL, *current = NULL;
|
||||
*found = false;
|
||||
current = moduleCallBackHead;
|
||||
while (current != NULL) {
|
||||
if (current->owner_name
|
||||
&& (strcmp(mod_name, current->owner_name) == 0)) {
|
||||
*found = true;
|
||||
break;
|
||||
} else {
|
||||
prev = current;
|
||||
current = current->next;
|
||||
for (it = this->CallBacks.begin(); it != this->CallBacks.end(); ++it)
|
||||
{
|
||||
t2 = *it;
|
||||
|
||||
if (t == t2)
|
||||
{
|
||||
TimerManager::DelTimer(t2);
|
||||
this->CallBacks.erase(it);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (current == moduleCallBackHead) {
|
||||
return NULL;
|
||||
} else {
|
||||
return prev;
|
||||
}
|
||||
}
|
||||
|
||||
void Module::DelCallback(const char *nname)
|
||||
{
|
||||
ModuleCallBack *current = NULL;
|
||||
ModuleCallBack *prev = NULL, *tmp = NULL;
|
||||
int del = 0;
|
||||
|
||||
current = moduleCallBackHead;
|
||||
|
||||
while (current) {
|
||||
if ((current->owner_name) && (current->name)) {
|
||||
if ((strcmp(this->name.c_str(), current->owner_name) == 0)
|
||||
&& (strcmp(current->name, nname) == 0)) {
|
||||
if (debug) {
|
||||
alog("debug: removing CallBack %s for module %s", nname, this->name.c_str());
|
||||
}
|
||||
tmp = current->next; /* get a pointer to the next record, as once we delete this record, we'll lose it :) */
|
||||
moduleCallBackDeleteEntry(prev); /* delete this record */
|
||||
del = 1; /* set the record deleted flag */
|
||||
}
|
||||
}
|
||||
if (del == 1) { /* if a record was deleted */
|
||||
current = tmp; /* use the value we stored in temp */
|
||||
tmp = NULL; /* clear it for next time */
|
||||
del = 0; /* reset the flag */
|
||||
} else {
|
||||
prev = current; /* just carry on as normal */
|
||||
current = current->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all outstanding module callbacks for the given module.
|
||||
* When a module is unloaded, any callbacks it had outstanding must be removed, else when they attempt to execute the func pointer will no longer be valid, and we'll seg.
|
||||
* @param mod_name the name of the module we are preping for unload
|
||||
**/
|
||||
void moduleCallBackPrepForUnload(const char *mod_name)
|
||||
{
|
||||
bool found = false;
|
||||
ModuleCallBack *tmp = NULL;
|
||||
|
||||
tmp = moduleCallBackFindEntry(mod_name, &found);
|
||||
while (found) {
|
||||
if (debug) {
|
||||
alog("debug: removing CallBack for module %s", mod_name);
|
||||
}
|
||||
moduleCallBackDeleteEntry(tmp);
|
||||
tmp = moduleCallBackFindEntry(mod_name, &found);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1059,21 +937,4 @@ void ModuleRunTimeDirCleanUp()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a stored call back
|
||||
**/
|
||||
void ModuleManager::RunCallbacks()
|
||||
{
|
||||
ModuleCallBack *tmp;
|
||||
|
||||
while ((tmp = moduleCallBackHead) && (tmp->when <= time(NULL))) {
|
||||
if (debug)
|
||||
alog("debug: executing callback: %s", tmp->name ? tmp->name : "<unknown>");
|
||||
if (tmp->func) {
|
||||
tmp->func(tmp->argc, tmp->argv);
|
||||
moduleCallBackDeleteEntry(NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
||||
+26
-19
@@ -24,7 +24,6 @@
|
||||
void mySendResponse(User *u, const char *channel, char *mask, const char *time);
|
||||
|
||||
void addBan(Channel *c, time_t timeout, char *banmask);
|
||||
int delBan(int argc, char **argv);
|
||||
int canBanUser(Channel *c, User *u, User *u2);
|
||||
|
||||
void mAddLanguages();
|
||||
@@ -167,6 +166,31 @@ void mySendResponse(User *u, const char *channel, char *mask, const char *time)
|
||||
me->NoticeLang(s_ChanServ, u, TBAN_RESPONSE, mask, channel, time);
|
||||
}
|
||||
|
||||
class TempBan : public Timer
|
||||
{
|
||||
private:
|
||||
std::string chan;
|
||||
std::string mask;
|
||||
|
||||
public:
|
||||
TempBan(time_t seconds, const std::string &channel, const std::string &banmask) : Timer(seconds), chan(channel), mask(banmask) { }
|
||||
|
||||
void Tick(time_t ctime)
|
||||
{
|
||||
const char *av[3];
|
||||
Channel *c;
|
||||
|
||||
av[0] = "-b";
|
||||
av[1] = mask.c_str();
|
||||
|
||||
if ((c = findchan(chan.c_str())) && c->ci)
|
||||
{
|
||||
ircdproto->SendMode(whosends(c->ci), c->name, "-b %s", av[1]);
|
||||
chan_set_modes(s_ChanServ, c, 2, av, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void addBan(Channel *c, time_t timeout, char *banmask)
|
||||
{
|
||||
const char *av[3];
|
||||
@@ -181,24 +205,7 @@ void addBan(Channel *c, time_t timeout, char *banmask)
|
||||
ircdproto->SendMode(whosends(c->ci), c->name, "+b %s", av[1]);
|
||||
chan_set_modes(s_ChanServ, c, 2, av, 1);
|
||||
|
||||
me->AddCallback("tban", time(NULL) + timeout, delBan, 2, cb);
|
||||
}
|
||||
|
||||
int delBan(int argc, char **argv)
|
||||
{
|
||||
const char *av[3];
|
||||
Channel *c;
|
||||
|
||||
av[0] = "-b";
|
||||
av[1] = argv[1];
|
||||
|
||||
if ((c = findchan(argv[0])) && c->ci)
|
||||
{
|
||||
ircdproto->SendMode(whosends(c->ci), c->name, "-b %s", av[1]);
|
||||
chan_set_modes(s_ChanServ, c, 2, av, 1);
|
||||
}
|
||||
|
||||
return MOD_CONT;
|
||||
me->AddCallBack(new TempBan(timeout, c->name, banmask));
|
||||
}
|
||||
|
||||
int canBanUser(Channel * c, User * u, User * u2)
|
||||
|
||||
Reference in New Issue
Block a user