#define _POSIX_C_SOURCE 200809L #include "tool_plugin.h" #include #include #include #include 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;inum_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;inum_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; } } } }