added unloadmod command

This commit is contained in:
Aaron Blakely 2024-02-17 00:03:20 -06:00
parent 2ee7d7d1fb
commit eec33fc573
6 changed files with 88 additions and 17 deletions

View File

@ -1,6 +1,6 @@
# xbot
Xbot is a modular C IRC bot.
xbot is a modular IRC bot in C for Linux and Windows
## Building
@ -17,5 +17,6 @@ Afterwords, just edit xbot.cfg and execute the xbot binary.
These are commands which allow the bot's admin to control it once it's connected to the IRC server.
* LOADMOD <module>
* UNLOADMOD <module>
* JOIN <channel>

View File

@ -34,6 +34,6 @@ struct mods {
void init_mods();
void load_module(struct irc_conn *bot, char *where, char *stype, char *file);
void unload_module(struct irc_conn *bot, char *where, char *file);
#endif

View File

@ -7,8 +7,6 @@
#include <stdlib.h>
#include <string.h>
int HANDLER = 0;
MY_API void hello(struct irc_conn *bot, char *user, char *host, char *chan, const char *text)
{
char *buf = (char *)malloc(sizeof(char *) * 500);
@ -24,12 +22,21 @@ MY_API void hello(struct irc_conn *bot, char *user, char *host, char *chan, cons
free(buf);
}
MY_API void hello_join(struct irc_conn *bot, char *user, char *host, char *chan)
{
printf("%s!%s joined %s\n", user, host, chan);
irc_privmsg(bot, chan, "Hi %s! Welcome to %s", user, chan);
}
MY_API void mod_init()
{
HANDLER = add_handler(PRIVMSG_CHAN, hello);
add_handler(PRIVMSG_CHAN, hello);
add_handler(JOIN, hello_join);
}
MY_API void mod_unload()
{
del_handler(PRIVMSG_CHAN, hello);
del_handler(JOIN, hello_join);
}

View File

@ -9,10 +9,6 @@
#ifdef _WIN32
#include <ctype.h>
#define SPF sprintf_s
#else
#define SPF sprintf
#endif
struct handler *privmsg_self;
@ -162,11 +158,12 @@ void fire_handler(struct irc_conn *bot, char *type, ...)
{
if (!strcmp(bot->admin, usr))
{
irc_notice(bot, usr, "Loading module: mods/%s.so", arg);
#ifdef _WIN32
SPF(modpath, "./mods/%s.dll", arg);
irc_notice(bot, usr, "Loading module: mods/%s.dll", arg);
sprintf(modpath, "./mods/%s.dll", arg);
#else
SPF(modpath, "./mods/%s.so", arg);
irc_notice(bot, usr, "Loading module: mods/%s.so", arg);
sprintf(modpath, "./mods/%s.so", arg);
#endif
load_module(bot, usr, PRIVMSG_SELF, modpath);
}
@ -175,6 +172,24 @@ void fire_handler(struct irc_conn *bot, char *type, ...)
irc_notice(bot, usr, "You are unauthorized to use this command.");
}
}
else if (!strcmp("UNLOADMOD", cmd))
{
if (!strcmp(bot->admin, usr))
{
#ifdef _WIN32
irc_notice(bot, usr, "Unloading module: mods/%s.dll", arg);
sprintf(modpath, "./mods/%s.dll", arg);
#else
irc_notice(bot, usr, "Unloading module: mods/%s.so", arg);
sprintf(modpath, "./mods/%s.so", arg);
#endif
unload_module(bot, usr, modpath);
}
else
{
irc_notice(bot, usr, "You are unauthorized to use this command.");
}
}
}
for (i = 0; i < handlers_count; i++)

View File

@ -276,7 +276,7 @@ void irc_parse_raw(struct irc_conn *bot, char *raw)
{
add_channel(text);
add_user_to_channel(user, host, text);
fire_handler(bot, JOIN, user, host, par);
fire_handler(bot, JOIN, user, host, text);
}
}
else if (!strcmp("PART", raw))

View File

@ -75,7 +75,29 @@ void load_module(struct irc_conn *bot, char *where, char *stype, char *file)
((void(*)(void))mods->modules[mods->count].init)();
//FreeLibrary(libHandle);
mods->modules[mods->count].unload = GetProcAddress(mods->modules[mods->count].handle, "mod_unload");
if (mods->modules[mods->count].unload == NULL)
{
DWORD err = GetLastError();
sprintf(error, "Error loading mod_unload() pointer for %s: %lu", file, err);
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);
}
return;
}
if (strcmp("runtime", stype))
{
@ -136,9 +158,6 @@ void load_module(struct irc_conn *bot, char *where, char *stype, char *file)
(*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)
{
@ -192,3 +211,32 @@ void load_module(struct irc_conn *bot, char *where, char *stype, char *file)
mods->count++;
}
void unload_module(struct irc_conn *bot, char *where, char *file)
{
int i;
for (i = 0; i < mods->count; i++)
{
(*mods->modules[i].unload)();
if (strcmp(mods->modules[i].fname, file) == 0)
{
#ifdef _WIN32
FreeLibrary(mods->modules[i].handle);
#else
dlclose(mods->modules[i].handle);
#endif
if (strcmp(PRIVMSG_CHAN, where))
{
irc_privmsg(bot, where, "Module '%s' unloaded.", file);
}
else
{
printf("Module '%s' unloaded.\n", file);
}
return;
}
}
}