From 78ae7430a066b58c211877a5b5fb500216f1b6f0 Mon Sep 17 00:00:00 2001 From: Aaron Blakely Date: Tue, 13 Feb 2024 17:47:20 -0600 Subject: [PATCH] rewriting modules system to use structs --- lib/events.h | 2 +- lib/module.h | 29 ++++++++++++-- mods/autojoin/autojoin.c | 7 +++- mods/hello/hello.c | 5 +++ mods/uptime/uptime.c | 6 +++ src/events.c | 27 +++++++++----- src/main.c | 7 ++++ src/module.c | 81 ++++++++++++++++++++++++++++++++-------- xbot.cfg | 2 +- 9 files changed, 135 insertions(+), 31 deletions(-) diff --git a/lib/events.h b/lib/events.h index 7e7b0e6..2aa183d 100755 --- a/lib/events.h +++ b/lib/events.h @@ -29,7 +29,7 @@ struct handler void init_events(); MY_API int add_handler(char *type, void *handler); -void del_handler(int num, char *type); +MY_API void del_handler(char *type, void *handler); void fire_handler(struct irc_conn *bot, char *type, ...); #endif diff --git a/lib/module.h b/lib/module.h index 59dffbc..a3270eb 100755 --- a/lib/module.h +++ b/lib/module.h @@ -4,13 +4,36 @@ #include "irc.h" #include "events.h" +#ifdef _WIN32 +#include +#endif + struct module { char *name; - char file[256]; - struct ev_handler *handlers; + char *author; + char *version; + char *description; + + char *fname; + +#ifdef _WIN32 + HMODULE handle; + FARPROC init; + FARPROC unload; +#else + void *handle; + void (*init)(); + void (*unload)(); +#endif }; -MY_API void load_module(struct irc_conn *bot, char *where, char *stype, char *file); +struct mods { + int count; + struct module *modules; +}; + +void init_mods(); +void load_module(struct irc_conn *bot, char *where, char *stype, char *file); #endif diff --git a/mods/autojoin/autojoin.c b/mods/autojoin/autojoin.c index e0c0ff4..c996c8c 100755 --- a/mods/autojoin/autojoin.c +++ b/mods/autojoin/autojoin.c @@ -47,4 +47,9 @@ MY_API void aj(struct irc_conn *bot, char *text) MY_API void mod_init() { add_handler(IRC_CONNECTED, aj); -} \ No newline at end of file +} + +MY_API void mod_unload() +{ + del_handler(IRC_CONNECTED, aj); +} diff --git a/mods/hello/hello.c b/mods/hello/hello.c index 8642a06..2059e37 100755 --- a/mods/hello/hello.c +++ b/mods/hello/hello.c @@ -28,3 +28,8 @@ MY_API void mod_init() { HANDLER = add_handler(PRIVMSG_CHAN, hello); } + +MY_API void mod_unload() +{ + del_handler(PRIVMSG_CHAN, hello); +} diff --git a/mods/uptime/uptime.c b/mods/uptime/uptime.c index 40ecf04..28b34ba 100755 --- a/mods/uptime/uptime.c +++ b/mods/uptime/uptime.c @@ -28,3 +28,9 @@ MY_API void mod_init() printf("installing up handler\n"); add_handler(PRIVMSG_CHAN, up); } + +MY_API void mod_unload() +{ + printf("unloading up handler\n"); + del_handler(PRIVMSG_CHAN, up); +} diff --git a/src/events.c b/src/events.c index 0b41634..5f750d4 100755 --- a/src/events.c +++ b/src/events.c @@ -23,9 +23,6 @@ struct handler *irc_connected; int handlers_count = 0; struct handler *handlers[512]; -// TODO: -// redo this module, unified api - void init_event_type(char *type) { handlers[handlers_count] = calloc(1, sizeof(struct handler)); @@ -73,8 +70,22 @@ MY_API int add_handler(char *type, void *handler) } } -void del_handler(int num, char *type) +MY_API void del_handler(char *type, void *handler) { + int i, j; + for (i = 0; i < handlers_count; i++) + { + if (!strcmp(handlers[i]->type, type)) + { + for (j = 0; j < handlers[i]->count; j++) + { + if (handlers[i]->evhands[j].handler == handler) + { + handlers[i]->evhands[j].handler = NULL; + } + } + } + } } void fire_handler(struct irc_conn *bot, char *type, ...) @@ -90,15 +101,13 @@ void fire_handler(struct irc_conn *bot, char *type, ...) { if (!strcmp(handlers[i]->type, type)) { - printf("handlers[%d]->count: %d\n", i, handlers[i]->count); - printf("type: %s\n", type); - for (j = 0; j < handlers[i]->count; j++) { - printf("j: %d i: %d\n", j, i); - handler = handlers[i]->evhands[j].handler; + if (handler == NULL) + continue; + if (!strcmp(type, PRIVMSG_SELF)) { va_start(args, type); diff --git a/src/main.c b/src/main.c index 11e34eb..d6f522e 100755 --- a/src/main.c +++ b/src/main.c @@ -33,6 +33,7 @@ int main() int bytesRecv; init_events(); + init_mods(); // Read the config bot = read_config(bot, "xbot.cfg"); @@ -103,6 +104,12 @@ int main() return -1; } + if (bytesRecv == 0) + { + eprint("xbot: remote host closed connection\n"); + return 0; + } + bot.in[bytesRecv] = '\0'; #else if (FD_ISSET(fileno(bot.srv_fd), &rd)) diff --git a/src/module.c b/src/module.c index e0de15c..e7bd2c8 100755 --- a/src/module.c +++ b/src/module.c @@ -1,6 +1,7 @@ #include "irc.h" #include "util.h" #include "events.h" +#include "module.h" #include #include #include @@ -11,15 +12,23 @@ #include #endif +struct mods *mods; + +void init_mods() +{ + mods = calloc(1, sizeof(struct mods)); + mods->count = 0; + mods->modules = calloc(512, sizeof(struct module)); +} + void load_module(struct irc_conn *bot, char *where, char *stype, char *file) { -#ifdef _WIN32 - HMODULE libHandle; - FARPROC funcPtr; char *error = (char *)malloc(sizeof(char *)*1024); + mods->modules[mods->count].fname = file; +#ifdef _WIN32 - libHandle = LoadLibrary(file); - if (libHandle == NULL) + mods->modules[mods->count].handle = LoadLibrary(file); + if (mods->modules[mods->count].handle == NULL) { sprintf(error, "Error loading %s\n", file); @@ -40,8 +49,8 @@ void load_module(struct irc_conn *bot, char *where, char *stype, char *file) return; } - funcPtr = GetProcAddress(libHandle, "mod_init"); - if (funcPtr == NULL) + mods->modules[mods->count].init = GetProcAddress(mods->modules[mods->count].handle, "mod_init"); + if (mods->modules[mods->count].init == NULL) { DWORD err = GetLastError(); @@ -64,7 +73,7 @@ void load_module(struct irc_conn *bot, char *where, char *stype, char *file) return; } - ((void(*)(void))funcPtr)(); + ((void(*)(void))mods->modules[mods->count].init)(); //FreeLibrary(libHandle); @@ -78,13 +87,10 @@ void load_module(struct irc_conn *bot, char *where, char *stype, char *file) } free(error); #else - void *handle; void (*mod_init)(); - char *error = (char *)malloc(sizeof(char *)*1024); - - handle = dlopen(file, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE); - if (!handle) + mods->modules[mods->count].handle = dlopen(file, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE); + if (!mods->modules[mods->count].handle) { sprintf(error, "Error: %s", dlerror()); @@ -107,7 +113,7 @@ void load_module(struct irc_conn *bot, char *where, char *stype, char *file) dlerror(); - *(void **)(&mod_init) = dlsym(handle, "mod_init"); + *(void **)(&mods->modules[mods->count].init) = dlsym(mods->modules[mods->count].handle , "mod_init"); if ((error = dlerror()) != NULL) { @@ -128,9 +134,50 @@ void load_module(struct irc_conn *bot, char *where, char *stype, char *file) } } - (*mod_init)(); + (*mods->modules[mods->count].init)(); + + //dlclose(handle); + + + *(void **)(&mods->modules[mods->count].unload) = dlsym(mods->modules[mods->count].handle , "mod_unload"); + if ((error = dlerror()) != NULL) + { + //sprintf(error, "Error: %s", error); + eprint("Error: %s\n", error); + + if (strcmp("runtime", stype)) + { + return; + } + else if (strcmp(PRIVMSG_CHAN, stype)) + { + irc_privmsg(bot, where, error); + } + else + { + irc_notice(bot, where, error); + } + } + + if ((error = dlerror()) != NULL) + { + //sprintf(error, "Error: %s", error); + eprint("Error: %s\n", error); + + if (strcmp("runtime", stype)) + { + return; + } + else if (strcmp(PRIVMSG_CHAN, stype)) + { + irc_privmsg(bot, where, error); + } + else + { + irc_notice(bot, where, error); + } + } - dlclose(handle); if (strcmp("runtime", stype)) { @@ -142,4 +189,6 @@ void load_module(struct irc_conn *bot, char *where, char *stype, char *file) } free(error); #endif + + mods->count++; } diff --git a/xbot.cfg b/xbot.cfg index 2206cbe..dc74edc 100755 --- a/xbot.cfg +++ b/xbot.cfg @@ -3,7 +3,7 @@ bot: { verbose = 1; - nick = "Win"; + nick = "Lin"; user = "xbot"; admin = "ab3800"; };