diff --git a/Makefile b/Makefile index 667beeb..bdf71a5 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ CC=gcc -CFLAGS=-g -std=gnu99 -c -lconfig -I./lib -BINFLAGS=-g -lconfig +CFLAGS=-g -std=gnu99 -c -lconfig -ldl -I./lib +BINFLAGS=-g -rdynamic -ldl -lconfig SRC=./src OBJ=./build OBJECTS=$(OBJ)/*.o @@ -13,6 +13,7 @@ main: $(CC) $(CFLAGS) $(SRC)/irc.c -o $(OBJ)/irc.o $(CC) $(CFLAGS) $(SRC)/util.c -o $(OBJ)/util.o $(CC) $(CFLAGS) $(SRC)/events.c -o $(OBJ)/events.o + $(CC) $(CFLAGS) $(SRC)/module.c -o $(OBJ)/module.o $(CC) -o $(EXEC) $(OBJECTS) $(BINFLAGS) @echo "All Done!" diff --git a/exported.txt b/exported.txt new file mode 100644 index 0000000..f1d161f --- /dev/null +++ b/exported.txt @@ -0,0 +1,8 @@ +{ + extern "C" + { + add_handler; + irc_privmsg; + irc_notice; + }; +} diff --git a/lib/irc.h b/lib/irc.h index 13876c5..28f2d36 100644 --- a/lib/irc.h +++ b/lib/irc.h @@ -28,6 +28,7 @@ struct irc_conn void irc_connect(struct irc_conn *bot); void irc_auth(struct irc_conn *bot); void irc_notice(struct irc_conn *bot, char *to, char *fmt, ...); +void irc_privmsg(struct irc_conn *bot, char *to, char *fmt, ...); void irc_raw(struct irc_conn *bot, char *fmt, ...); void irc_parse_raw(struct irc_conn *bot, char *raw); diff --git a/lib/module.h b/lib/module.h index e69de29..3b130c0 100644 --- a/lib/module.h +++ b/lib/module.h @@ -0,0 +1,8 @@ +#ifndef MODULE_H +#define MODULE_H + +#include "irc.h" + +void load_module(struct irc_conn *bot, char *where, int stype, char *file); + +#endif \ No newline at end of file diff --git a/mods/test.so b/mods/test.so new file mode 100755 index 0000000..75064ab Binary files /dev/null and b/mods/test.so differ diff --git a/mods/test/Makefile b/mods/test/Makefile new file mode 100644 index 0000000..c83dea2 --- /dev/null +++ b/mods/test/Makefile @@ -0,0 +1,4 @@ +gcc -c -fPIC -I../../lib test.c -o test.o +gcc test.o -shared test.so +mv test.so .. +rm test.o \ No newline at end of file diff --git a/mods/test/build.sh b/mods/test/build.sh new file mode 100755 index 0000000..e69de29 diff --git a/mods/test/test.c b/mods/test/test.c new file mode 100644 index 0000000..1184ad1 --- /dev/null +++ b/mods/test/test.c @@ -0,0 +1,26 @@ +#include "irc.h" +#include "events.h" +#include +#include + +void hello(struct irc_conn *bot, char *user, char *chan, char *text) +{ + printf("hi\n"); + + char *buf = (char *)malloc(sizeof(char *) * 500); + sprintf(buf, "hi %s", bot->nick); + + printf("trigger: %s\n", buf); + + if (!strcmp(text, buf)) + { + irc_privmsg(bot, chan, "hi %s", user); + } + + free(buf); +} + +void mod_init(struct irc_conn *b, char *where) +{ + add_handler(PRIVMSG_CHAN, hello); +} \ No newline at end of file diff --git a/mods/test/test.o b/mods/test/test.o new file mode 100644 index 0000000..8e109a7 Binary files /dev/null and b/mods/test/test.o differ diff --git a/mods/test/test.so b/mods/test/test.so new file mode 100755 index 0000000..43f242d Binary files /dev/null and b/mods/test/test.so differ diff --git a/src/events.c b/src/events.c index d6c268c..2547201 100644 --- a/src/events.c +++ b/src/events.c @@ -1,6 +1,7 @@ #include "irc.h" #include "util.h" #include "events.h" +#include "module.h" #include #include #include @@ -29,6 +30,7 @@ void init_events() void add_handler(int type, void *handler) { + printf("Installing handler @ %p [type: %i]\n", handler, type); int handler_count; if (type == PRIVMSG_SELF) @@ -63,10 +65,12 @@ void handle_chan_privmsg(struct irc_conn *bot, char *user, char *chan, char *tex void handle_self_privmsg(struct irc_conn *bot, char *user, char *text) { void (*handler)(); - char *cmd, *arg; + char *cmd, *arg, *modpath; cmd = text; arg = skip(cmd, ' '); + modpath = (char *)malloc(sizeof(char)*500); + for (int i = 0; i < privmsg_self.count; i++) { handler = privmsg_self.handlers[i]; @@ -90,12 +94,16 @@ void handle_self_privmsg(struct irc_conn *bot, char *user, char *text) if (strcmp(bot->admin, user)) { irc_notice(bot, user, "Loading module: mods/%s.so", arg); + sprintf(modpath, "./mods/%s.so", arg); + load_module(bot, user, PRIVMSG_SELF, modpath); } else { irc_notice(bot, user, "You are unauthorized to use this command."); } } + + free(modpath); } void handle_join(struct irc_conn *bot, char *user, char *chan) diff --git a/src/irc.c b/src/irc.c index 766948e..8a6cfa9 100644 --- a/src/irc.c +++ b/src/irc.c @@ -75,6 +75,18 @@ void irc_notice(struct irc_conn *bot, char *to, char *fmt, ...) irc_raw(bot, "NOTICE %s :%s", to, msg_); } +void irc_privmsg(struct irc_conn *bot, char *to, char *fmt, ...) +{ + char msg_[4096]; + va_list ap; + + va_start(ap, fmt); + vsnprintf(msg_, sizeof msg_, fmt, ap); + va_end(ap); + + irc_raw(bot, "PRIVMSG %s :%s", to, msg_); +} + void irc_raw(struct irc_conn *bot, char *fmt, ...) { va_list ap; @@ -122,7 +134,7 @@ void irc_parse_raw(struct irc_conn *bot, char *raw) if (!strcmp("PRIVMSG", raw)) { - if (strcmp(user, bot->nick)) + if (!strcmp(par, bot->nick)) { handle_self_privmsg(bot, user, text); } diff --git a/src/main.c b/src/main.c index 77aa9c2..c1a73c6 100644 --- a/src/main.c +++ b/src/main.c @@ -64,8 +64,6 @@ int main() // Free the config before entering the main loop config_destroy(cf); - add_handler(PRIVMSG_SELF, hello_cmd); - add_handler(PRIVMSG_SELF, hello_cmd); for (;;) { diff --git a/src/module.c b/src/module.c index e69de29..99dd6e2 100644 --- a/src/module.c +++ b/src/module.c @@ -0,0 +1,57 @@ +#include "irc.h" +#include "util.h" +#include "events.h" +#include +#include +#include + +void load_module(struct irc_conn *bot, char *where, int stype, char *file) +{ + void *handle; + void (*mod_init)(struct irc_conn *bot, char *where, void (*ah)()); + char *error = (char *)malloc(sizeof(char *)*1024); + + + handle = dlopen(file, RTLD_NOW | RTLD_GLOBAL); + if (!handle) + { + sprintf(error, "Error: %s", dlerror()); + + if (stype == PRIVMSG_CHAN) + { + irc_privmsg(bot, where, error); + } + else + { + irc_notice(bot, where, error); + } + + return; + } + + dlerror(); + + *(void **)(&mod_init) = dlsym(handle, "mod_init"); + + if ((error = dlerror()) != NULL) + { + //sprintf(error, "Error: %s", error); + eprint("Error: %s\n", error); + if (stype == PRIVMSG_CHAN) + { + irc_privmsg(bot, where, error); + } + else + { + irc_notice(bot, where, error); + } + } + + (*mod_init)(bot, where); + + dlclose(handle); + + irc_privmsg(bot, where, "Module '%s' loaded.", file); + + free(error); +} \ No newline at end of file diff --git a/src/util.c b/src/util.c index 08e9249..a4a997b 100644 --- a/src/util.c +++ b/src/util.c @@ -25,8 +25,6 @@ void eprint(char *fmt, ...) { fprintf(stderr, "%s\n", strerror(errno)); } - - exit(1); } void strlcpy(char *to, const char *from, int len)