void cve_plugin_manager_init() { DIR *dir = NULL; struct dirent *ent = NULL; autofree(char) *mod_path =NULL; if (_plugins) { return; } _plugins = cve_hashmap_new_full(string_hash, string_compare, NULL, (hash_free_func)destroy_plugin); mod_path = get_plugins_path(); if (!mod_path) { fprintf(stderr, "Unable to determine module path\n"); return; } if (!(dir = opendir(mod_path))) { fprintf(stderr, "Unable to list modules: %s\n", strerror(errno)); return; } while ((ent = readdir(dir))) { if (g_str_has_suffix(ent->d_name, ".so")) { load_module(ent->d_name); } } if (dir) { closedir(dir); } }
static void load_module(const char *name) { void *handle, *cast; autofree(char) *path = NULL; char *error = NULL; cve_plugin_init init_func; CvePlugin *plugin = NULL; #ifdef TEST_SUITE_BUILD if (!asprintf(&path, TOP_BUILD_DIR"/tests/dummy_install/%s", name)) { #else if (!asprintf(&path, "%s/%s", MODULE_DIR, name)) { #endif fprintf(stderr, "No memory\n"); return; } handle = dlopen(path, RTLD_LAZY); if (!handle) { fprintf(stderr, "Unable to load module: %s\n", dlerror()); return; } dlerror(); cast = dlsym(handle, "cve_plugin_module_init"); if (!cast || (error = dlerror()) != NULL) { fprintf(stderr, "Cannot load module: %s\n", error); abort(); } dlerror(); memcpy(&init_func, &cast, sizeof(init_func)); plugin = calloc(1, sizeof(struct CvePlugin)); if (!plugin) { fprintf(stderr, "Unable to allocate memory\n"); abort(); } if (!init_func(plugin)) { fprintf(stderr, "Plugin initialisation failed\n"); abort(); } if (!plugin->name) { fprintf(stderr, "Plugin %s does not set a name - aborting\n", name); abort(); } plugin->handle = handle; cve_hashmap_put(_plugins, (char*)plugin->name, plugin); } static void destroy_plugin(CvePlugin *plugin) { if (plugin->destroy) { plugin->destroy(plugin); } if (plugin->handle) { dlclose(plugin->handle); } free(plugin); } void cve_plugin_manager_init() { DIR *dir = NULL; struct dirent *ent = NULL; if (_plugins) { return; } _plugins = cve_hashmap_new_full(string_hash, string_compare, NULL, (hash_free_func)destroy_plugin); #ifdef TEST_SUITE_BUILD if (!(dir = opendir(TOP_BUILD_DIR "/tests/dummy_install"))) { #else if (!(dir = opendir(MODULE_DIR))) { #endif fprintf(stderr, "Unable to list modules: %s\n", strerror(errno)); return; } while ((ent = readdir(dir))) { if (g_str_has_suffix(ent->d_name, ".so")) { load_module(ent->d_name); } } if (dir) { closedir(dir); } } void cve_plugin_manager_destroy() { if (!_plugins) { return; } cve_hashmap_free(_plugins); _plugins = NULL; } CvePlugin *cve_plugin_get_by_name(const char *name) { CvePlugin *ret = NULL; if (!_plugins) { return NULL; } ret = cve_hashmap_get(_plugins, name); return ret; }