ADAPT / src / tool_plugin.c
tool_plugin.c
Raw
#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;
	    }
	}
    }
}