gboolean plugin_load_module(const gchar *module_name, GlobalConfig *cfg, CfgArgs *args) { GModule *mod; static GModule *main_module_handle; gboolean (*init_func)(GlobalConfig *cfg, CfgArgs *args); gchar *module_init_func; const gchar *mp; gchar *p; if (!main_module_handle) main_module_handle = g_module_open(NULL, 0); module_init_func = g_strdup_printf("%s_module_init", module_name); for (p = module_init_func; *p; p++) { if ((*p) == '-') *p = '_'; } if (g_module_symbol(main_module_handle, module_init_func, (gpointer *) &init_func)) { /* already linked in, no need to load explicitly */ goto call_init; } if (cfg->lexer) mp = cfg_args_get(cfg->lexer->globals, "module-path"); else mp = NULL; if (!mp) mp = module_path; mod = plugin_dlopen_module(module_name, mp); if (!mod) { g_free(module_init_func); return FALSE; } g_module_make_resident(mod); if (!g_module_symbol(mod, module_init_func, (gpointer *) &init_func)) { msg_error("Error finding init function in module", evt_tag_str("module", module_name), evt_tag_str("symbol", module_init_func), evt_tag_str("error", g_module_error()), NULL); g_free(module_init_func); return FALSE; } call_init: g_free(module_init_func); return (*init_func)(cfg, args); }
gboolean plugin_load_module(const gchar *module_name, GlobalConfig *cfg, CfgArgs *args) { GModule *mod; static GModule *main_module_handle; gboolean (*init_func)(GlobalConfig *cfg, CfgArgs *args); gchar *module_init_func; const gchar *mp; gboolean result; ModuleInfo *module_info; /* lookup in the main executable */ if (!main_module_handle) main_module_handle = g_module_open(NULL, 0); module_init_func = plugin_get_module_init_name(module_name); if (g_module_symbol(main_module_handle, module_init_func, (gpointer *) &init_func)) { /* already linked in, no need to load explicitly */ goto call_init; } /* try to load it from external .so */ if (cfg->lexer) mp = cfg_args_get(cfg->lexer->globals, "module-path"); else mp = NULL; if (!mp) mp = resolvedConfigurablePaths.initial_module_path; mod = plugin_dlopen_module(module_name, mp); if (!mod) { g_free(module_init_func); return FALSE; } g_module_make_resident(mod); module_info = plugin_get_module_info(mod); if (module_info->canonical_name) { g_free(module_init_func); module_init_func = plugin_get_module_init_name(module_info->canonical_name ? : module_name); }
void plugin_list_modules(FILE *out, gboolean verbose) { GlobalConfig *cfg; GModule *mod; gchar **mod_paths; gint i, j, k; gboolean first = TRUE; cfg = cfg_new(CFG_CURRENT_VERSION); mod_paths = g_strsplit(module_path, ":", 0); for (i = 0; mod_paths[i]; i++) { GDir *dir; const gchar *fname; dir = g_dir_open(mod_paths[i], 0, NULL); if (!dir) continue; while ((fname = g_dir_read_name(dir))) { if (g_str_has_suffix(fname, G_MODULE_SUFFIX)) { gchar *module_name; ModuleInfo *module_info; gboolean success; if (g_str_has_prefix(fname, "lib")) fname += 3; module_name = g_strndup(fname, (gint) (strlen(fname) - strlen(G_MODULE_SUFFIX) - 1)); mod = plugin_dlopen_module(module_name, module_path); if (mod) success = g_module_symbol(mod, "module_info", (gpointer *) &module_info); else success = FALSE; if (verbose) { fprintf(out, "Module: %s\n", module_name); if (mod) { if (!success || !module_info) { fprintf(out, "Status: Unable to resolve module_info variable, probably not a syslog-ng module\n"); } else { if (strcmp(module_info->canonical_name, module_name) != 0) { fprintf(out, "Status: This module is to be loaded under the name %s instead of %s\n", module_info->canonical_name, module_name); } else { gchar **lines; fprintf(out, "Status: ok\n" "Version: %s\n" "Core-Revision: %s\n" "Description:\n", module_info->version, module_info->core_revision); lines = g_strsplit(module_info->description, "\n", 0); for (k = 0; lines[k]; k++) fprintf(out, " %s\n", lines[k][0] ? lines[k] : "."); g_strfreev(lines); fprintf(out, "Plugins:\n"); for (j = 0; j < module_info->plugins_len; j++) { Plugin *plugin = &module_info->plugins[j]; fprintf(out, " %-15s %s\n", cfg_lexer_lookup_context_name_by_type(plugin->type), plugin->name); } } } g_module_close(mod); } else { fprintf(out, "Status: Unable to dlopen shared object, probably not a syslog-ng module\n"); } fprintf(out, "\n"); } else if (success && module_info) { fprintf(out, "%s%s", first ? "" : ",", module_name); first = FALSE; } g_free(module_name); } } g_dir_close(dir); } g_strfreev(mod_paths); if (!verbose) fprintf(out, "\n"); }
void plugin_load_candidate_modules(GlobalConfig *cfg) { GModule *mod; gchar **mod_paths; gint i, j; mod_paths = g_strsplit(module_path, ":", 0); for (i = 0; mod_paths[i]; i++) { GDir *dir; const gchar *fname; dir = g_dir_open(mod_paths[i], 0, NULL); if (!dir) continue; while ((fname = g_dir_read_name(dir))) { if (g_str_has_suffix(fname, G_MODULE_SUFFIX)) { gchar *module_name; ModuleInfo *module_info; gboolean success; if (g_str_has_prefix(fname, "lib")) fname += 3; module_name = g_strndup(fname, (gint) (strlen(fname) - strlen(G_MODULE_SUFFIX) - 1)); mod = plugin_dlopen_module(module_name, module_path); if (mod) success = g_module_symbol(mod, "module_info", (gpointer *) &module_info); else success = FALSE; if (success && module_info) { for (j = 0; j < module_info->plugins_len; j++) { Plugin *plugin = &module_info->plugins[j]; PluginCandidate *candidate_plugin; candidate_plugin = (PluginCandidate *) plugin_find_in_list(cfg, cfg->candidate_plugins, plugin->type, plugin->name); if (candidate_plugin) { if (candidate_plugin->preference < module_info->preference) { plugin_candidate_set_module_name(candidate_plugin, module_info->canonical_name); plugin_candidate_set_preference(candidate_plugin, module_info->preference); } } else { cfg->candidate_plugins = g_list_prepend(cfg->candidate_plugins, plugin_candidate_new(plugin->type, plugin->name, module_info->canonical_name, module_info->preference)); } } } g_free(module_name); if (mod) g_module_close(mod); else mod = NULL; } } g_dir_close(dir); } g_strfreev(mod_paths); }