Logo Search packages:      
Sourcecode: rageircd version File versions  Download package

hook.c

/*
 * RageIRCd: an advanced Internet Relay Chat daemon (ircd).
 * (C) 2000-2005 the RageIRCd Development Team, all rights reserved.
 *
 * This software is free, licensed under the General Public License.
 * Please refer to doc/LICENSE and doc/README for further details.
 *
 * $Id: hook.c,v 1.44.2.1 2004/12/07 03:05:11 pneumatus Exp $
 */

#include "struct.h"
#include "setup.h"
#include "common.h"
#include "sys.h"
#include "numeric.h"
#include "h.h"
#include "msg.h"
#include "channel.h"
#include "send.h"
#include "patchlevel.h"
#include "memory.h"
#include "hook.h"
#include "dlink.h"
#include "modules.h"
#include <sys/types.h>
#include <sys/stat.h>   
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

dlink_list hook_list = DLINK_LIST_INIT;

Hook *h_post_accept = NULL; /* s_bsd.c, add_connection() */
Hook *h_user_access = NULL; /* s_bsd.c, check_client() */
Hook *h_register_user_local = NULL; /* s_user.c, register_user() */
Hook *h_register_user_remote = NULL; /* s_user.c, register_user() */
Hook *h_post_register_user = NULL; /* s_user.c, register_user() */
Hook *h_conf_parse = NULL;
Hook *h_conf_test = NULL;
Hook *h_conf_verify = NULL;
Hook *h_conf_complete = NULL;
Hook *h_conf_rehash = NULL;
Hook *h_pre_netio = NULL;
Hook *h_post_netio = NULL;
Hook *h_exit_user_local = NULL;
Hook *h_exit_user_remote = NULL;
Hook *h_exit_server = NULL;
Hook *h_exit_unknown = NULL;
Hook *h_pre_connauth = NULL;

void hook_init()
{
      h_post_accept = hook_add("h_post_accept");
      h_user_access = hook_add("h_user_access");
      h_register_user_local = hook_add("h_register_user_local");
      h_register_user_remote = hook_add("h_register_user_remote");
      h_post_register_user = hook_add("h_post_register_user");
      h_conf_parse = hook_add("h_conf_parse");
      h_conf_test = hook_add("h_conf_test");
      h_conf_verify = hook_add("h_conf_verify");
      h_conf_complete = hook_add("h_conf_complete");
      h_conf_rehash = hook_add("h_conf_rehash");
      h_pre_netio = hook_add("h_pre_netio");
      h_post_netio = hook_add("h_post_netio");
      h_exit_user_local = hook_add("h_exit_user_local");
      h_exit_user_remote = hook_add("h_exit_user_remote");
      h_exit_server = hook_add("h_exit_server");
      h_exit_unknown = hook_add("h_exit_unknown");
      h_pre_connauth = hook_add("h_pre_connauth");
}

static void *hook_find_event(Hook *hook, int (*event)(), int want_node)
{
      dlink_node *node;
      HookEvent *hookevent;

      ASSERT(hook != NULL);

      DLINK_FOREACH_DATA(hook->events.head, node, hookevent, HookEvent) {
            if (hookevent->event == event) {
                  return (want_node) ? (void *)node : (void *)hookevent;
            }
      }

      return NULL;
}

Hook *hook_find(char *name)
{
      dlink_node *node;
      Hook *hook;

      DLINK_FOREACH_DATA(hook_list.head, node, hook, Hook) {
            if (!irccmp(hook->name, name)) {
                  return hook;
            }
      }

      return NULL;
}

HookEvent *hook_add_event(Hook *hook, int (*event)())
{
      HookEvent *hookevent;

      ASSERT(hook != NULL);

      if ((hookevent = (HookEvent *)hook_find_event(hook, event, 0)) != NULL) {
            ircdlog(LOG_ERROR, "Ignoring duplicate hook event in hook %s (already exists!)",
                  hook->name);
            return NULL;
      }

      hookevent = (HookEvent *)MyMalloc(sizeof(HookEvent));
      hookevent->hook = hook;
      hookevent->event = event;
      hookevent->owner = NULL;

      dlink_add(&hook->events, hookevent);
      return hookevent;
}

void hook_del_event(HookEvent *hookevent)
{
      ASSERT(hookevent != NULL);

      dlink_del(&hookevent->hook->events, hookevent, NULL);
      MyFree(hookevent);
}

Hook *hook_add(char *name)
{
      Hook *hook;

      if ((hook = hook_find(name)) != NULL) {
            ircdlog(LOG_ERROR, "Ignoring duplicate hook %s (already exists!)", name);
            return NULL;
      }

      hook = (Hook *)MyMalloc(sizeof(Hook));
      DupString(hook->name, name);
      dlink_add(&hook_list, hook);

      return hook;
}

static void hook_del_event_from_owner(HookEvent *hookevent)
{
      Module *owner;

      ASSERT(hookevent != NULL);
      owner = hookevent->owner;
      ASSERT(owner != NULL);

      dlink_del(&owner->hookevents, hookevent, NULL);
}

void hook_del_events(Hook *hook)
{
      dlink_node *node, *next = NULL;
      HookEvent *hookevent;

      ASSERT(hook != NULL);

      DLINK_FOREACH_SAFE_DATA(hook->events.head, node, next, hookevent, HookEvent) {
            if (hookevent->owner != NULL) {
                  ASSERT(hookevent->owner != hook->owner);
                  sendto_realops("Hook %s contained an event from %s. Please reload "
                        "this module.", hook->name, hookevent->owner->name);
                  hook_del_event_from_owner(hookevent);
            }
            dlink_del(&hook->events, NULL, node);
            MyFree(hookevent);
      }
}

void hook_del(Hook *hook)
{
      ASSERT(hook != NULL);

      dlink_del(&hook_list, hook, NULL);

      if (dlink_length(&hook->events)) {
            hook_del_events(hook);
      }

      MyFree(hook->name);
      MyFree(hook);
}

void hook_report(aClient *cptr)
{
      dlink_node *node, *enode;
      Hook *hook;
      HookEvent *hookevent;
      int s_ev, m_ev;

      send_me_debugNA(cptr, "H :Hook                    Static/Module Events");

      DLINK_FOREACH_DATA(hook_list.head, node, hook, Hook) {
             s_ev = m_ev = 0;

            DLINK_FOREACH_DATA(hook->events.head, enode, hookevent, HookEvent) {
                  if (hookevent->owner == NULL) {
                        s_ev++;
                  }
                  else {
                        m_ev++;
                  }
            }

            send_me_debug(cptr, "H :%-23s %d/%d", hook->name, s_ev, m_ev);
      }
}

Generated by  Doxygen 1.6.0   Back to index