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); +} | 
