diff options
Diffstat (limited to 'src/hook.c')
-rw-r--r-- | src/hook.c | 214 |
1 files changed, 0 insertions, 214 deletions
diff --git a/src/hook.c b/src/hook.c deleted file mode 100644 index 86b2e86..0000000 --- a/src/hook.c +++ /dev/null @@ -1,214 +0,0 @@ -/* - * ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd) - * - * Copyright (c) 2003 Piotr Nizynski, Advanced IRC Services Project Team - * Copyright (c) 2005-2014 ircd-hybrid development team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -/*! \file hook.c - * \brief Provides a generic event hooking interface. - * \version $Id$ - */ - -#include "stdinc.h" -#include "list.h" -#include "hook.h" -#include "ircd.h" -#include "memory.h" -#include "numeric.h" -#include "irc_string.h" -#include "send.h" -#include "client.h" - - -static dlink_list callback_list; - - -/*! \brief Creates a new callback. - * \param name Name used to identify the callback - * (can be NULL for anonymous callbacks) - * \param func Initial function attached to the chain - * (can be NULL to create an empty chain) - * \return Pointer to Callback structure or NULL if already exists - * \note Once registered, a callback should never be freed! - * That's because there may be modules which depend on it - * (even if no functions are attached). That's also why - * we dynamically allocate the struct here -- we don't want - * to allow anyone to place it in module data, which can be - * unloaded at any time. - */ -struct Callback * -register_callback(const char *name, CBFUNC *func) -{ - struct Callback *cb = NULL; - - if (name != NULL) - { - if ((cb = find_callback(name)) != NULL) - { - if (func != NULL) - dlinkAddTail(func, MyMalloc(sizeof(dlink_node)), &cb->chain); - - return cb; - } - } - - cb = MyMalloc(sizeof(struct Callback)); - - if (func != NULL) - dlinkAdd(func, MyMalloc(sizeof(dlink_node)), &cb->chain); - - if (name != NULL) - { - cb->name = xstrdup(name); - dlinkAdd(cb, &cb->node, &callback_list); - } - - return cb; -} - -/*! \brief Passes control down the callback hook chain. - * \param cb Pointer to Callback structure - * \param ... Argument to pass - * \return function Return value - */ -void * -execute_callback(struct Callback *cb, ...) -{ - void *res = NULL; - va_list args; - - cb->called++; - cb->last = CurrentTime; - - if (!is_callback_present(cb)) - return NULL; - - va_start(args, cb); - res = ((CBFUNC *)cb->chain.head->data)(args); - va_end(args); - - return res; -} - -/*! \brief Called by a hook function to pass code flow further - * in the hook chain. - * \param this_hook Pointer to dlink_node of the current hook function - * \param ... (original or modified) arguments to be passed - * \return callback Return value - */ -void * -pass_callback(dlink_node *this_hook, ...) -{ - void *res = NULL; - va_list args; - - if (this_hook->next == NULL) - return NULL; /* Reached the last one */ - - va_start(args, this_hook); - res = ((CBFUNC *)this_hook->next->data)(args); - va_end(args); - - return res; -} - -/*! \brief Finds a named callback. - * \param name Name of the callback - * \return Pointer to Callback structure or NULL if not found - */ -struct Callback * -find_callback(const char *name) -{ - dlink_node *ptr = NULL; - - DLINK_FOREACH(ptr, callback_list.head) - { - struct Callback *cb = ptr->data; - - if (!irccmp(cb->name, name)) - return cb; - } - - return NULL; -} - -/*! \brief Installs a hook for the given callback. - * - * The new hook is installed at the beginning of the chain, - * so it has full control over functions installed earlier. - * - * \param cb Pointer to Callback structure - * \param hook Address of hook function - * \return Pointer to dlink_node of the hook (used when passing - * control to the next hook in the chain); - * valid till uninstall_hook() is called - */ -dlink_node * -install_hook(struct Callback *cb, CBFUNC *hook) -{ - dlink_node *node = MyMalloc(sizeof(dlink_node)); - - dlinkAdd(hook, node, &cb->chain); - return node; -} - -/*! \brief Removes a specific hook for the given callback. - * \param cb Pointer to Callback structure - * \param hook Address of hook function - */ -void -uninstall_hook(struct Callback *cb, CBFUNC *hook) -{ - /* Let it core if not found */ - dlink_node *ptr = dlinkFind(&cb->chain, hook); - - dlinkDelete(ptr, &cb->chain); - MyFree(ptr); -} - -/*! \brief Displays registered callbacks and lengths of their hook chains. - * (This is the handler of /stats h) - * \param source_p Pointer to struct Client - */ -void -stats_hooks(struct Client *source_p) -{ - char lastused[IRCD_BUFSIZE]; - const dlink_node *ptr = NULL; - - sendto_one(source_p, ":%s %d %s : %-20s %-20s Used Hooks", me.name, - RPL_STATSDEBUG, source_p->name, "Callback", "Last Execution"); - sendto_one(source_p, ":%s %d %s : ------------------------------------" - "--------------------", me.name, RPL_STATSDEBUG, source_p->name); - - DLINK_FOREACH(ptr, callback_list.head) - { - const struct Callback *cb = ptr->data; - - if (cb->last != 0) - snprintf(lastused, sizeof(lastused), "%d seconds ago", - (int) (CurrentTime - cb->last)); - else - strcpy(lastused, "NEVER"); - - sendto_one(source_p, ":%s %d %s : %-20s %-20s %-8u %d", me.name, - RPL_STATSDEBUG, source_p->name, cb->name, lastused, cb->called, - dlink_list_length(&cb->chain)); - } -} |