#define HOOK_INCREMENT 1000
+struct hook_entry
+{
+ rb_dlink_node node;
+ hookfn fn;
+ enum hook_priority priority;
+};
+
int num_hooks = 0;
int last_hook = 0;
int max_hooks = HOOK_INCREMENT;
int h_server_introduced;
int h_server_eob;
int h_client_exit;
+int h_after_client_exit;
int h_umode_changed;
int h_new_local_user;
int h_new_remote_user;
int h_conf_read_start;
int h_conf_read_end;
int h_outbound_msgbuf;
+int h_rehash;
+int h_priv_change;
+int h_cap_change;
void
init_hook(void)
h_server_introduced = register_hook("server_introduced");
h_server_eob = register_hook("server_eob");
h_client_exit = register_hook("client_exit");
+ h_after_client_exit = register_hook("after_client_exit");
h_umode_changed = register_hook("umode_changed");
h_new_local_user = register_hook("new_local_user");
h_new_remote_user = register_hook("new_remote_user");
h_conf_read_start = register_hook("conf_read_start");
h_conf_read_end = register_hook("conf_read_end");
h_outbound_msgbuf = register_hook("outbound_msgbuf");
+ h_rehash = register_hook("rehash");
+ h_priv_change = register_hook("priv_change");
+ h_cap_change = register_hook("cap_change");
}
/* grow_hooktable()
void
add_hook(const char *name, hookfn fn)
{
+ add_hook_prio(name, fn, HOOK_NORMAL);
+}
+
+/* add_hook_prio()
+ * Adds a hook with the specified priority
+ */
+void
+add_hook_prio(const char *name, hookfn fn, enum hook_priority priority)
+{
+ rb_dlink_node *ptr;
+ struct hook_entry *entry = rb_malloc(sizeof *entry);
int i;
i = register_hook(name);
+ entry->fn = fn;
+ entry->priority = priority;
+
+ RB_DLINK_FOREACH(ptr, hooks[i].hooks.head)
+ {
+ struct hook_entry *o = ptr->data;
+ if (entry->priority <= o->priority)
+ {
+ rb_dlinkAddBefore(ptr, entry, &entry->node, &hooks[i].hooks);
+ return;
+ }
+ }
- rb_dlinkAddAlloc(fn, &hooks[i].hooks);
+ rb_dlinkAddTail(entry, &entry->node, &hooks[i].hooks);
}
/* remove_hook()
void
remove_hook(const char *name, hookfn fn)
{
+ rb_dlink_node *ptr, *scratch;
int i;
if((i = find_hook(name)) < 0)
return;
- rb_dlinkFindDestroy(fn, &hooks[i].hooks);
+ RB_DLINK_FOREACH_SAFE(ptr, scratch, hooks[i].hooks.head)
+ {
+ struct hook_entry *entry = ptr->data;
+ if (entry->fn == fn)
+ {
+ rb_dlinkDelete(ptr, &hooks[i].hooks);
+ return;
+ }
+ }
}
/* call_hook()
void
call_hook(int id, void *arg)
{
- hookfn fn;
rb_dlink_node *ptr;
/* The ID we were passed is the position in the hook table of this
*/
RB_DLINK_FOREACH(ptr, hooks[id].hooks.head)
{
- fn = ptr->data;
- fn(arg);
+ struct hook_entry *entry = ptr->data;
+ entry->fn(arg);
}
}