aboutsummaryrefslogtreecommitdiff
path: root/plugin.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugin.c')
-rw-r--r--plugin.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/plugin.c b/plugin.c
new file mode 100644
index 0000000..14dce01
--- /dev/null
+++ b/plugin.c
@@ -0,0 +1,79 @@
+#include <stdio.h>
+#include <string.h>
+#include <dlfcn.h>
+#include "event.h"
+#include "global.h"
+#include "plugin.h"
+#include "plugin_client_header.h"
+
+
+struct plugin_data{
+ void *handle;
+ plugin_event_func_t *callback;
+};
+
+static i64 num_plugins=0;
+static i64 plugins_cap=8;
+static struct plugin_data *plugins_list=NULL;
+
+
+static void consume_event(const struct event_item *event){
+ struct plugin_event pe;
+ switch(event->type){
+ case EVENT_MESSAGE: pe.type=PLUGIN_EVENT_MESSAGE; break;
+ case EVENT_ONLINE: pe.type=PLUGIN_EVENT_ONLINE; break;
+ case EVENT_JOIN: pe.type=PLUGIN_EVENT_JOIN; break;
+ default:
+ die("Unknown event type %d in plugin.c:consume_event",event->type);
+ }
+ pe.timestamp=event->timestamp;
+ pe.message=event->message;
+ pe.user=event->user;
+ pe.room=event->room;
+ pe.num=event->num;
+
+ for(i64 i=0;i<num_plugins;i++){
+ plugins_list[i].callback(&pe);
+ }
+}
+
+
+void plugin_init(void){
+ if(plugins_list!=NULL)return;
+ plugins_list=malloc(plugins_cap,struct plugin_data);
+ memset(plugins_list,0,num_plugins*sizeof(struct plugin_data));
+
+ event_register(consume_event);
+}
+
+void plugin_register(const char *fname){
+ if(num_plugins==plugins_cap){
+ plugins_cap*=2;
+ plugins_list=realloc(plugins_list,plugins_cap,struct plugin_data);
+ }
+
+ struct plugin_data *data=plugins_list+num_plugins;
+ num_plugins++;
+ data->handle=dlopen(fname,RTLD_NOW|RTLD_LOCAL);
+ if(data->handle==NULL){
+ die("Error loading plugin '%s': %s",fname,dlerror());
+ }
+
+ plugin_event_func_t* (*init_func)(void)=NULL;
+ dlerror();
+ *(void**)&init_func=dlsym(data->handle,"plugin_init_func");
+ char *err=dlerror();
+ if(err!=NULL){
+ die("Error reading symbol 'plugin_init_func' from plugin '%s'",fname);
+ }
+ if(init_func==NULL){
+ die("Plugin '%s' exports NULL init function",fname);
+ }
+
+ data->callback=init_func();
+ if(data->callback==NULL){
+ die("Init function of plugin '%s' returned NULL",fname);
+ }
+
+ printf("Loaded plugin '%s'\n",fname);
+}