]> jfr.im git - irc/evilnet/x3.git/commitdiff
Added new event hooks system and started migrating events to new system master
authorMatthew Beeching <redacted>
Sun, 11 Aug 2024 13:45:23 +0000 (14:45 +0100)
committerMatthew Beeching <redacted>
Sun, 11 Aug 2024 13:45:23 +0000 (14:45 +0100)
src/Makefile.am
src/Makefile.in
src/chanserv.c
src/eventhooks.c [new file with mode: 0644]
src/eventhooks.h [new file with mode: 0644]
src/hash.c
src/hash.h
src/mod-snoop.c

index 95aa04df916a4a515b4fc9abd10006ee04a212ec..a256d471b949457d7c79d9e05780ba31e5ff1ab0 100644 (file)
@@ -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 \
index 337187fc959adb718fcf103dd7965c4097b6a516..b1d585529544efeeea62d91cb0a4f796638c99b9 100644 (file)
@@ -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@
index 5931cd0fc731b9654e409ba6bd5d5cdf5bb52b34..2303a76196450c8cc16ceeb9a9f462ec431aaf57 100644 (file)
@@ -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 (file)
index 0000000..da5c230
--- /dev/null
@@ -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 <assert.h>
+#include <stdlib.h>
+#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 (file)
index 0000000..30e8f75
--- /dev/null
@@ -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 */
index 9775cfedeb05f4356f1b411af20fbb63a734e83f..8f6a3dfe9edd41dacc8bdfc30de645e317a0abb2 100644 (file)
@@ -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; (n<jf_used) && !user->dead; 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);
index 2e81f256de35a66d1d5eb0806fedc4e7054ee550..3c36823367b9f7c7338dc3f59a7421bfe233dd0c 100644 (file)
@@ -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);
index c06135bdc7cd347f29f14f88d7d5f525043ea417..4eb39694e12e7a28158bc0da1b966aa573e7db6a 100644 (file)
@@ -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);