#include #include #include #include #include "plugin_manager.h" #include "plugin.h" #include "debug.h" #include "version.h" #include "utils.h" static char *exec_path; int init_plugin_manager(const char *_exec_path) { char *str = strdup(_exec_path); exec_path = strdup(dirname(str)); free(str); return 0; } int load_plugin(const char *path) { struct plugin_info *info; void *handle; int ret = -1; handle = dlopen(path, RTLD_NOW); if (!handle) { pr_err("Failed to load plugin %s: %s\n", path, dlerror()); return -1; } info = dlsym(handle, "plugin_info"); if (!info) { pr_err("Plugin %s does not contain plugin info\n", path); goto out; } if (!info->version) { pr_err("Plugin %s version info missing\n", path); ret = -1; goto out; } if (strcmp(RRDD_VERSION, info->version)) { pr_err("Plugin %s version mismatch, expected %s, got %s\n", path, RRDD_VERSION, info->version); ret = -1; goto out; } if (!info->init) { pr_err("Plugin info structure has NULL .init callback\n"); goto out; } ret = info->init(); pr_info("Loading plugin %s %s\n", path, ret ? "failed" : "succeeded"); out: if (ret) dlclose(handle); return ret; } /* * Try to load a parser plugin with file name matching some of the * following candidates (%s being the requested name): * * "%s_parser.so" * "./%s_parser.so" * "/%s_parser.so" */ int load_parser_plugin(const char *name) { char str[256], parser[] = "_parser.so"; int ret; strncpy(str, name, sizeof(str)); str[sizeof(str) - 1] = '\0'; _strlcat(str, parser, sizeof(str)); ret = load_plugin(str); if (!ret) return 0; strncpy(str, "./", sizeof(str)); str[sizeof(str) - 1] = '\0'; _strlcat(str, name, sizeof(str)); _strlcat(str, parser, sizeof(str)); ret = load_plugin(str); if (!ret) return 0; if (!exec_path) return 0; strncpy(str, exec_path, sizeof(str)); str[sizeof(str) - 1] = '\0'; _strlcat(str, "/", sizeof(str)); _strlcat(str, name, sizeof(str)); _strlcat(str, parser, sizeof(str)); return load_plugin(str); }