diff options
Diffstat (limited to 'plugin.c')
-rw-r--r-- | plugin.c | 79 |
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); +} |