xbot/src/module.c

328 lines
7.0 KiB
C
Raw Normal View History

#include "irc.h"
#include "util.h"
#include "events.h"
#include "module.h"
#include <stdio.h>
#include <stdlib.h>
2015-04-08 11:56:32 -07:00
#include <string.h>
2024-02-12 23:22:10 -08:00
#ifdef _WIN32
#include <windows.h>
#else
#include <dlfcn.h>
2024-02-12 23:22:10 -08:00
#endif
struct mods *mods;
2024-02-25 09:09:24 -08:00
struct irc_conn *instance;
struct db_table *dbinstance;
void init_mods()
{
mods = calloc(1, sizeof(struct mods));
mods->count = 0;
mods->modules = calloc(512, sizeof(struct module));
}
2015-04-08 11:56:32 -07:00
void load_module(struct irc_conn *bot, char *where, char *stype, char *file)
{
2024-02-21 06:24:49 -08:00
char *error = (char *)malloc(sizeof(char *)*1024);
#ifdef _WIN32
2024-02-21 06:24:49 -08:00
DWORD err;
2024-02-21 06:24:49 -08:00
strlcpy(mods->modules[mods->count].fname, file, 256);
mods->modules[mods->count].handle = LoadLibrary(file);
if (mods->modules[mods->count].handle == NULL)
{
2024-02-21 06:24:49 -08:00
err = GetLastError();
sprintf(error, "Error loading %s: %lu", file, err);
2015-04-08 11:56:32 -07:00
if (strcmp("runtime", stype))
2015-04-07 11:18:24 -07:00
{
eprint("%s\n", error);
return;
}
2024-02-12 23:22:10 -08:00
else if (strcmp(PRIVMSG_CHAN, stype))
{
2024-02-21 06:24:49 -08:00
irc_notice(bot, where, error);
2024-02-12 23:22:10 -08:00
}
else
{
irc_notice(bot, where, error);
}
2024-02-12 23:22:10 -08:00
return;
}
mods->modules[mods->count].init = GetProcAddress(mods->modules[mods->count].handle, "mod_init");
if (mods->modules[mods->count].init == NULL)
{
2024-02-12 23:22:10 -08:00
DWORD err = GetLastError();
sprintf(error, "Error loading mod_init() pointer for %s: %lu", file, err);
eprint("Error: %s\n", error);
2015-04-07 11:18:24 -07:00
2024-02-12 23:22:10 -08:00
if (strcmp("runtime", stype))
{
return;
}
else if (strcmp(PRIVMSG_CHAN, stype))
{
2024-02-21 06:24:49 -08:00
irc_notice(bot, where, error);
2024-02-12 23:22:10 -08:00
}
else
{
irc_notice(bot, where, error);
}
return;
}
((void(*)(void))mods->modules[mods->count].init)();
2024-02-16 22:03:20 -08:00
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))
{
2024-02-21 06:24:49 -08:00
irc_notice(bot, where, error);
2024-02-16 22:03:20 -08:00
}
else
{
irc_notice(bot, where, error);
}
return;
}
2015-04-08 11:56:32 -07:00
if (strcmp("runtime", stype))
2024-02-12 23:22:10 -08:00
{
2024-02-21 06:24:49 -08:00
irc_notice(bot, where, "Module '%s' loaded.", file);
2024-02-12 23:22:10 -08:00
}
2024-03-09 01:38:58 -08:00
xlog("[module] Module '%s' loaded.\n", file);
2024-02-12 23:22:10 -08:00
free(error);
#else
void (*mod_init)();
2024-02-21 06:24:49 -08:00
strlcpy(mods->modules[mods->count].fname, file, 256);
mods->modules[mods->count].handle = dlopen(file, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
if (!mods->modules[mods->count].handle)
2024-02-12 23:22:10 -08:00
{
2024-03-09 01:38:58 -08:00
sprintf(error, "[module] Error loading %s: %s", file, dlerror());
2024-02-12 23:22:10 -08:00
if (strcmp("runtime", stype))
{
eprint("%s\n", error);
return;
}
else if (strcmp(PRIVMSG_CHAN, stype))
{
2024-02-21 06:24:49 -08:00
irc_notice(bot, where, error);
2024-02-12 23:22:10 -08:00
}
else
{
irc_notice(bot, where, error);
}
2024-03-09 01:38:58 -08:00
xlog("[module] %s", error);
2024-02-12 23:22:10 -08:00
return;
}
dlerror();
*(void **)(&mods->modules[mods->count].init) = dlsym(mods->modules[mods->count].handle , "mod_init");
if ((error = dlerror()) != NULL)
{
if (strcmp("runtime", stype))
{
2024-03-09 01:38:58 -08:00
eprint("Error: %s\n", error);
return;
}
else if (strcmp(PRIVMSG_CHAN, stype))
{
2024-02-21 06:24:49 -08:00
irc_notice(bot, where, error);
}
else
{
irc_notice(bot, where, error);
}
2024-03-09 01:38:58 -08:00
xlog("[module] Error: %s", error);
}
(*mods->modules[mods->count].init)();
2024-02-12 23:22:10 -08:00
*(void **)(&mods->modules[mods->count].unload) = dlsym(mods->modules[mods->count].handle , "mod_unload");
2024-02-12 23:22:10 -08:00
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))
{
2024-02-21 06:24:49 -08:00
irc_notice(bot, where, error);
2024-02-12 23:22:10 -08:00
}
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))
{
2024-02-21 06:24:49 -08:00
irc_notice(bot, where, error);
}
else
{
irc_notice(bot, where, error);
}
}
2024-02-12 23:22:10 -08:00
if (strcmp("runtime", stype))
{
2024-02-21 06:24:49 -08:00
irc_notice(bot, where, "Module '%s' loaded.", file);
2024-02-12 23:22:10 -08:00
}
else
{
2024-03-09 01:38:58 -08:00
xlog("[module] Module '%s' loaded.\n", file);
2024-02-12 23:22:10 -08:00
}
free(error);
#endif
mods->count++;
2024-02-12 23:22:10 -08:00
}
2024-02-16 22:03:20 -08:00
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))
{
2024-02-21 06:24:49 -08:00
irc_notice(bot, where, "Module '%s' unloaded.", file);
2024-02-16 22:03:20 -08:00
}
else
{
2024-03-09 01:38:58 -08:00
xlog("[module] Module '%s' unloaded.\n", file);
2024-02-16 22:03:20 -08:00
}
2024-02-17 00:21:22 -08:00
while (i < mods->count)
{
mods->modules[i] = mods->modules[i+1];
i++;
}
2024-02-21 06:24:49 -08:00
mods->count--;
2024-02-17 00:21:22 -08:00
return;
}
}
}
void list_modules(struct irc_conn *bot, char *where)
{
int i;
char *msg = malloc(512);
char *tmp = malloc(512);
for (i = 0; i < mods->count; i++)
{
sprintf(tmp, "%s (%s) by %s - %s", mods->modules[i].name, mods->modules[i].version, mods->modules[i].author, mods->modules[i].description);
irc_notice(bot, where, tmp);
}
free(msg);
free(tmp);
}
MY_API void register_module(char *name, char *author, char *version, char *description)
{
if (mods->count >= 512)
{
eprint("Error: Too many modules loaded.\n");
return;
}
strlcpy(mods->modules[mods->count].name, name, 25);
strlcpy(mods->modules[mods->count].author, author, 50);
strlcpy(mods->modules[mods->count].version, version, 10);
strlcpy(mods->modules[mods->count].description, description, 256);
}
MY_API void unregister_module(char *name)
{
int i;
for (i = 0; i < mods->count; i++)
{
if (strcmp(mods->modules[i].fname, name) == 0)
{
while (i < mods->count)
{
mods->modules[i] = mods->modules[i+1];
i++;
}
2024-02-16 22:03:20 -08:00
return;
}
}
}
2024-02-17 00:21:22 -08:00
MY_API struct mods *get_mods()
{
return mods;
}
2024-02-25 09:09:24 -08:00
MY_API struct irc_conn *get_bot()
{
return instance;
}
2024-02-29 18:49:33 -08:00
void set_bot(struct irc_conn *b)
2024-02-25 09:09:24 -08:00
{
instance = b;
}
void set_bot_db(struct db_table *db)
{
dbinstance = db;
}
MY_API struct db_table *get_bot_db()
{
return dbinstance;
}