From: Matthew Beeching Date: Sun, 11 Aug 2024 13:45:23 +0000 (+0100) Subject: Added new event hooks system and started migrating events to new system X-Git-Url: https://jfr.im/git/irc/evilnet/x3.git/commitdiff_plain/HEAD?hp=259fe757a4f80446fa436c0db5c55f1e5c04a963 Added new event hooks system and started migrating events to new system --- diff --git a/src/Makefile.am b/src/Makefile.am index 95aa04d..a256d47 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -56,6 +56,7 @@ x3_SOURCES = \ compat.c compat.h \ conf.c conf.h \ dict-splay.c dict.h \ + eventhooks.c eventhooks.h \ getopt.c getopt.h \ getopt1.c getopt.h \ gline.c gline.h \ diff --git a/src/Makefile.in b/src/Makefile.in index 337187f..b1d5855 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -63,7 +63,7 @@ am_slab_read_OBJECTS = slab-read.$(OBJEXT) slab_read_OBJECTS = $(am_slab_read_OBJECTS) slab_read_LDADD = $(LDADD) am_x3_OBJECTS = base64.$(OBJEXT) chanserv.$(OBJEXT) compat.$(OBJEXT) conf.$(OBJEXT) \ - dict-splay.$(OBJEXT) getopt.$(OBJEXT) getopt1.$(OBJEXT) \ + dict-splay.$(OBJEXT) eventhooks.$(OBJEXT) getopt.$(OBJEXT) getopt1.$(OBJEXT) \ gline.$(OBJEXT) global.$(OBJEXT) hash.$(OBJEXT) heap.$(OBJEXT) \ helpfile.$(OBJEXT) ioset.$(OBJEXT) \ log.$(OBJEXT) main.$(OBJEXT) math.$(OBJEXT) md5.$(OBJEXT) \ @@ -249,6 +249,7 @@ x3_SOURCES = \ compat.c compat.h \ conf.c conf.h \ dict-splay.c dict.h \ + eventhooks.c eventhooks.h \ getopt.c getopt.h \ getopt1.c getopt.h \ gline.c gline.h \ @@ -359,6 +360,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compat.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dict-splay.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eventhooks.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt1.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gline.Po@am__quote@ diff --git a/src/chanserv.c b/src/chanserv.c index 5931cd0..2303a76 100644 --- a/src/chanserv.c +++ b/src/chanserv.c @@ -8130,9 +8130,9 @@ static CHANSERV_FUNC(cmd_8ball) /*** COLOR *****/ if((word2) && strcasecmp(word1, "what") == 0 && ((strcasecmp(word2, "color") == 0) || (strcasecmp(word2, "colour") == 0))) eightball(eb, 1, accum); - else if((word3) && strcasecmp(word1, "what's") == 0 && strcasecmp(word2, "the") == 0 && ((strcasecmp(word2, "color") == 0) || (strcasecmp(word2, "colour") == 0))) + else if((word3) && strcasecmp(word1, "what's") == 0 && strcasecmp(word2, "the") == 0 && ((strcasecmp(word3, "color") == 0) || (strcasecmp(word3, "colour") == 0))) eightball(eb, 1, accum); - else if((word3) && strcasecmp(word1, "whats") == 0 && strcasecmp(word2, "the") == 0 && ((strcasecmp(word2, "color") == 0) || (strcasecmp(word2, "colour") == 0))) + else if((word3) && strcasecmp(word1, "whats") == 0 && strcasecmp(word2, "the") == 0 && ((strcasecmp(word3, "color") == 0) || (strcasecmp(word3, "colour") == 0))) eightball(eb, 1, accum); /*** LOCATION *****/ else if( diff --git a/src/eventhooks.c b/src/eventhooks.c new file mode 100644 index 0000000..da5c230 --- /dev/null +++ b/src/eventhooks.c @@ -0,0 +1,138 @@ +/* eventhooks.c - Event hooks + * Copyright 2000-2024 Evilnet Development + * + * This file is part of x3. + * + * x3 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 3 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 srvx; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include +#include +#include "eventhooks.h" + +struct eh_func_list *init_hook_func_list(struct eh_func_list *list, int defpos) { + if ((defpos != EH_ADD_TAIL) && (defpos != EH_ADD_HEAD)) + list->add_default = EH_ADD_TAIL; + else + list->add_default = defpos; + list->head = NULL; + list->tail = NULL; + list->count = 0; + list->clean = NULL; + + return list; +} + +void reg_hook_func_pos(struct eh_func_list *list, eh_func_t func, void *extra, int pos) { + struct eh_func *newehf = malloc(sizeof(struct eh_func)); + int addpos = pos; + + if ((addpos != EH_ADD_HEAD) && (addpos != EH_ADD_TAIL)) + addpos = list->add_default; + + if (newehf == NULL) + return; + + newehf->next = NULL; + newehf->func = func; + newehf->extra = extra; + + if (list->head == NULL) { + list->head = newehf; + list->tail = newehf; + } else if (addpos > 0) { + newehf->next = list->head; + list->head = newehf; + } else { + list->tail->next = newehf; + list->tail = newehf; + } + list->count++; +} + +void reg_hook_func(struct eh_func_list *list, eh_func_t func, void *extra) { + reg_hook_func_pos(list, func, extra, EH_ADD_DEFAULT); +} + +void unreg_hook_func(struct eh_func_list *list, eh_func_t func, void *extra) { + struct eh_func *ehfi = list->head; + struct eh_func *ehfr = NULL; + + if (ehfi != NULL) { + if ((ehfi->func == func) && (ehfi->extra == extra)) { + list->head = ehfi->next; + if (list->tail == ehfi) + list->tail = NULL; + if (list->clean != NULL) + list->clean(ehfi); + free(ehfi); + list->count--; + } else { + for (ehfi=list->head; ehfi!=NULL; ehfi=ehfi->next) { + if (ehfi->next != NULL) { + if ((ehfi->next->func == func) && (ehfi->next->extra == extra)) { + ehfr = ehfi->next; + ehfi->next = ehfi->next->next; + if (list->tail == ehfr) + list->tail = ehfi; + if (list->clean != NULL) + list->clean(ehfr); + free(ehfr); + list->count--; + break; + } + } + } + } + } +} + +void free_hook_func_list(struct eh_func_list *list) { + struct eh_func *ehfi = NULL; + struct eh_func *ehfn = NULL; + int i = 0; + + if (list->head == NULL) + return; + + for (ehfi=list->head; ehfi!=NULL; ehfi=ehfn) { + ehfn = ehfi->next; + + if (list->clean != NULL) + list->clean(ehfi); + + free(ehfi); + i++; + } + + assert(i==list->count); + + list->head = NULL; + list->tail = NULL; + list->count = 0; +} + +void call_hook_func_args(struct eh_func_list *list, void *callextra) { + struct eh_func *ehfi = NULL; + + for (ehfi=list->head; ehfi!=NULL; ehfi=ehfi->next) { + if (ehfi->func(ehfi->extra, callextra) != EH_CONT) + break; + } +} + +void call_hook_func_noargs(struct eh_func_list *list) { + call_hook_func_args(list, NULL); +} diff --git a/src/eventhooks.h b/src/eventhooks.h new file mode 100644 index 0000000..30e8f75 --- /dev/null +++ b/src/eventhooks.h @@ -0,0 +1,61 @@ +/* eventhooks.h - Event hooks + * Copyright 2000-2024 Evilnet Development + * + * This file is part of x3. + * + * x3 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 3 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 srvx; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifndef INCLUDED_eventhooks_h +#define INCLUDED_eventhooks_h + +#define EH_ADD_HEAD 1 +#define EH_ADD_TAIL -1 +#define EH_ADD_DEFAULT 0 + +#define DEFINE_EH_FUNC_LIST(l, d, cf) struct eh_func_list l = {NULL, NULL, d, 0, cf} +#define INIT_EH_FUNC_LIST(d) {NULL, NULL, d, 0} + +#define EH_CONT 0 +#define EH_STOP 1 + +struct eh_func; + +typedef int (*eh_func_t) (void *extra, void *callextra); +typedef void (*eh_clean_func_t) (struct eh_func *ehf); + +struct eh_func { + struct eh_func *next; + eh_func_t func; + void *extra; +}; + +struct eh_func_list { + struct eh_func *head; + struct eh_func *tail; + int add_default; + int count; + eh_clean_func_t clean; +}; + +struct eh_func_list *init_hook_func_list(struct eh_func_list *list, int defpos); +void reg_hook_func(struct eh_func_list *list, eh_func_t func, void *extra); +void reg_hook_func_pos(struct eh_func_list *list, eh_func_t func, void *extra, int pos); +void unreg_hook_func(struct eh_func_list *list, eh_func_t func, void *extra); +void free_hook_func_list(struct eh_func_list *list); +void call_hook_func_noargs(struct eh_func_list *list); +void call_hook_func_args(struct eh_func_list *list, void *callextra); + +#endif /* INCLUDED_eventhooks_h */ diff --git a/src/hash.c b/src/hash.c index 9775cfe..8f6a3df 100644 --- a/src/hash.c +++ b/src/hash.c @@ -149,37 +149,50 @@ unreg_sasl_input_func(sasl_input_func_t handler, void *extra) sif_used--; } -new_user_func_t *nuf_list; -void **nuf_list_extra; -unsigned int nuf_size = 0, nuf_used = 0; +void +nuf_free_ehf(struct eh_func *ehf) +{ + if (ehf->extra != NULL) + free(ehf->extra); +} + +DEFINE_EH_FUNC_LIST(nuf_list, EH_ADD_TAIL, nuf_free_ehf); + +int +nuf_wrapper(void *extra, void *callextra) +{ + struct funcargs *fa = (struct funcargs *)extra; + struct userNode *user = (struct userNode *)callextra; + + ((new_user_func_t)fa->func)(user, fa->extra); + + if (user->dead) + return EH_STOP; + + return EH_CONT; +} + +void +reg_new_user_func_pos(new_user_func_t handler, void *extra, int pos) +{ + struct funcargs *fa = malloc(sizeof(struct funcargs)); + + fa->func = (void *)handler; + fa->extra = extra; + + reg_hook_func_pos(&nuf_list, nuf_wrapper, (void *)fa, pos); +} void reg_new_user_func(new_user_func_t handler, void *extra) { - if (nuf_used == nuf_size) { - if (nuf_size) { - nuf_size <<= 1; - nuf_list = realloc(nuf_list, nuf_size*sizeof(new_user_func_t)); - nuf_list_extra = realloc(nuf_list_extra, nuf_size*sizeof(void*)); - } else { - nuf_size = 8; - nuf_list = malloc(nuf_size*sizeof(new_user_func_t)); - nuf_list_extra = malloc(nuf_size*sizeof(void*)); - } - } - nuf_list[nuf_used] = handler; - nuf_list_extra[nuf_used++] = extra; + reg_new_user_func_pos(handler, extra, EH_ADD_DEFAULT); } void call_new_user_funcs(struct userNode* user) { - unsigned int i; - - for (i = 0; i < nuf_used && !(user->dead); ++i) - { - nuf_list[i](user, nuf_list_extra[i]); - } + call_hook_func_args(&nuf_list, (void *)user); } static nick_change_func_t *ncf2_list; @@ -472,26 +485,51 @@ reg_new_channel_func(new_channel_func_t handler, void *extra) ncf_list_extra[ncf_used++] = extra; } -static join_func_t *jf_list; -static void **jf_list_extra; -static unsigned int jf_size = 0, jf_used = 0; +void +jf_free_ehf(struct eh_func *ehf) +{ + if (ehf->extra != NULL) + free(ehf->extra); +} + +DEFINE_EH_FUNC_LIST(jf_list, EH_ADD_TAIL, jf_free_ehf); + +int +jf_wrapper(void *extra, void *callextra) +{ + struct funcargs *fa = (struct funcargs *)extra; + struct modeNode *mNode = (struct modeNode *)callextra; + struct userNode *user = mNode->user; + + ((join_func_t)fa->func)(mNode, fa->extra); + + if (user->dead) + return EH_STOP; + + return EH_CONT; +} + +void +reg_join_func_pos(join_func_t handler, void *extra, int pos) +{ + struct funcargs *fa = malloc(sizeof(struct funcargs)); + + fa->func = (void *)handler; + fa->extra = extra; + + reg_hook_func_pos(&jf_list, jf_wrapper, (void *)fa, pos); +} void reg_join_func(join_func_t handler, void *extra) { - if (jf_used == jf_size) { - if (jf_size) { - jf_size <<= 1; - jf_list = realloc(jf_list, jf_size*sizeof(join_func_t)); - jf_list_extra = realloc(jf_list_extra, jf_size*sizeof(void*)); - } else { - jf_size = 8; - jf_list = malloc(jf_size*sizeof(join_func_t)); - jf_list_extra = malloc(jf_size*sizeof(void*)); - } - } - jf_list[jf_used] = handler; - jf_list_extra[jf_used++] = extra; + reg_join_func_pos(handler, extra, EH_ADD_DEFAULT); +} + +void +call_join_funcs(struct modeNode *mNode) +{ + call_hook_func_args(&jf_list, (void *)mNode); } int rel_age; @@ -705,7 +743,6 @@ struct modeNode * AddChannelUser(struct userNode *user, struct chanNode* channel) { struct modeNode *mNode; - unsigned int n; mNode = GetUserMode(channel, user); if (mNode) @@ -737,12 +774,7 @@ AddChannelUser(struct userNode *user, struct chanNode* channel) irc_join(user, channel); } - for (n=0; (ndead; n++) { - /* Callbacks return true if they kick or kill the user, - * and we can continue without removing mNode. */ - if (jf_list[n](mNode, jf_list_extra[n])) - return NULL; - } + call_join_funcs(mNode); return mNode; } @@ -1061,16 +1093,14 @@ hash_cleanup(UNUSED_ARG(void *extra)) free(slf_list); free(slf_list_extra); - free(nuf_list); - free(nuf_list_extra); + free_hook_func_list(&nuf_list); free(ncf2_list); free(ncf2_list_extra); free(duf_list); free(duf_list_extra); free(ncf_list); free(ncf_list_extra); - free(jf_list); - free(jf_list_extra); + free_hook_func_list(&jf_list); free(dcf_list); free(dcf_list_extra); free(pf_list); diff --git a/src/hash.h b/src/hash.h index 2e81f25..3c36823 100644 --- a/src/hash.h +++ b/src/hash.h @@ -23,6 +23,7 @@ #include "common.h" #include "dict.h" +#include "eventhooks.h" #include "policer.h" #include "recdb.h" @@ -383,6 +384,11 @@ struct route { struct routeList *servers; }; +/* generic hook function args */ +struct funcargs { + void *func; + void *extra; +}; extern struct server *self; extern dict_t channels; @@ -412,6 +418,7 @@ void unreg_sasl_input_func(sasl_input_func_t handler, void *extra); typedef int (*new_user_func_t) (struct userNode *user, void *extra); void reg_new_user_func(new_user_func_t handler, void *extra); +void reg_new_user_func_pos(new_user_func_t handler, void *extra, int pos); void call_new_user_funcs(struct userNode *user); typedef void (*del_user_func_t) (struct userNode *user, struct userNode *killer, const char *why, void *extra); void reg_del_user_func(del_user_func_t handler, void *extra); @@ -433,6 +440,7 @@ void set_geoip_info(struct userNode *user); typedef void (*new_channel_func_t) (struct chanNode *chan, void *extra); void reg_new_channel_func(new_channel_func_t handler, void *extra); typedef int (*join_func_t) (struct modeNode *mNode, void *extra); +void reg_join_func_pos(join_func_t handler, void *extra, int pos); void reg_join_func(join_func_t handler, void *extra); typedef void (*del_channel_func_t) (struct chanNode *chan, void *extra); void reg_del_channel_func(del_channel_func_t handler, void *extra); diff --git a/src/mod-snoop.c b/src/mod-snoop.c index c06135b..4eb3969 100644 --- a/src/mod-snoop.c +++ b/src/mod-snoop.c @@ -316,10 +316,10 @@ snoop_init(void) { reg_exit_func(snoop_cleanup, NULL); conf_register_reload(snoop_conf_read); reg_nick_change_func(snoop_nick_change, NULL); - reg_join_func(snoop_join, NULL); + reg_join_func_pos(snoop_join, NULL, EH_ADD_HEAD); reg_part_func(snoop_part, NULL); reg_kick_func(snoop_kick, NULL); - reg_new_user_func(snoop_new_user, NULL); + reg_new_user_func_pos(snoop_new_user, NULL, EH_ADD_HEAD); reg_del_user_func(snoop_del_user, NULL); reg_auth_func(snoop_auth, NULL); reg_channel_mode_func(snoop_channel_mode, NULL);