#define _POSIX_C_SOURCE 200809L
#include "tool_plugin.h"
#include <dlfcn.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void tool_plugin_init(struct tool_plugin *t_plugin, char *tool_name, size_t num_caps)
{
t_plugin->name = tool_name;
t_plugin->num_caps = num_caps;
t_plugin->caps = malloc(t_plugin->num_caps*sizeof(struct tool_capability));
}
void tool_plugin_destroy(struct tool_plugin *t_plugin)
{
for(size_t i=0;i<t_plugin->num_caps;i++)
{
free(t_plugin->caps[i].name);
}
free(t_plugin->caps);
dlclose(t_plugin->handle);
}
void load_tool_plugin(struct tool_plugin *t_plugin, char *plugin_file)
{
void *handle;
tool_name_fn name_fn;
tool_interface_fn interface_fn;
char *tool_name = NULL;
size_t num_caps = 0;
dlerror();
handle = dlopen(plugin_file, RTLD_LAZY);
if (!handle )
{
fprintf(stderr, "[Err] Couldn't not dlopen %s\n", plugin_file);
printf("[dlerror] %s\n",dlerror());
return;
}
t_plugin->handle = handle;
name_fn = dlsym(handle, "tool_name");
if(!name_fn)
{
fprintf(stderr, "[Err] Couldn't not resolve tool_name symbol\n");
return;
}
tool_name = name_fn();
interface_fn = dlsym(handle, "tool_interface");
if (!interface_fn)
{
fprintf(stderr, "[Err] Couldn't not resolve tool_interface symbol\n");
return;
}
char **interface = interface_fn(&num_caps);
tool_plugin_init(t_plugin, tool_name, num_caps);
for(size_t i=0;i<t_plugin->num_caps;i++)
{
char *fn_name = strchr(interface[i],':');
if(fn_name && fn_name[1]!='\0')
{
t_plugin->caps[i].name = strndup(interface[i],fn_name-interface[i]);
t_plugin->caps[i].run = dlsym(handle,fn_name+1);
if(!t_plugin->caps[i].run)
{
fprintf(stderr,"[Err] Could not resolve function: %s\n",fn_name);
return;
}
int nbytes = snprintf(NULL,0,"%s_guard",fn_name+1);
char guard_fn_str[nbytes+1];
snprintf(guard_fn_str,nbytes+1,"%s_guard",fn_name+1);
t_plugin->caps[i].guard = dlsym(handle,guard_fn_str);
if(!t_plugin->caps[i].guard)
{
fprintf(stderr,"[Err] Could not resolve function: %s\n",guard_fn_str);
return;
}
}
}
}