diff --git a/README.md b/README.md index 96a7d17..c7efd4c 100755 --- a/README.md +++ b/README.md @@ -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 +* UNLOADMOD * JOIN diff --git a/lib/module.h b/lib/module.h index a3270eb..7bc39ab 100755 --- a/lib/module.h +++ b/lib/module.h @@ -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 diff --git a/mods/hello/hello.c b/mods/hello/hello.c index bdccf8e..f943fd8 100755 --- a/mods/hello/hello.c +++ b/mods/hello/hello.c @@ -7,8 +7,6 @@ #include #include -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); } diff --git a/src/events.c b/src/events.c index c7d1509..03b9b70 100755 --- a/src/events.c +++ b/src/events.c @@ -9,10 +9,6 @@ #ifdef _WIN32 #include - -#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++) diff --git a/src/irc.c b/src/irc.c index ceade8c..83f3429 100755 --- a/src/irc.c +++ b/src/irc.c @@ -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)) diff --git a/src/module.c b/src/module.c index e7bd2c8..61eccae 100755 --- a/src/module.c +++ b/src/module.c @@ -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; + } + } +}