X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Futil%2Fplugin.c;h=4e0385a0984d65c1aa11cb0a7a2f073d65c53ce1;hb=f491ac4fab469421986f77df0bbf79fefc417786;hp=4e960b4fe83c778c1f5233f04fb591659bc2fd0d;hpb=2386d0b653cfabc856a8639504d6dcc82022cc1b;p=oweals%2Fgnunet.git diff --git a/src/util/plugin.c b/src/util/plugin.c index 4e960b4fe..4e0385a09 100644 --- a/src/util/plugin.c +++ b/src/util/plugin.c @@ -30,6 +30,8 @@ #include "gnunet_os_lib.h" #include "gnunet_plugin_lib.h" +#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) + /** * Linked list of active plugins. */ @@ -73,7 +75,7 @@ static struct PluginList *plugins; /** * Setup libtool paths. */ -static void +static void plugin_init () { int err; @@ -83,34 +85,30 @@ plugin_init () err = lt_dlinit (); if (err > 0) - { - fprintf (stderr, - _("Initialization of plugin mechanism failed: %s!\n"), - lt_dlerror ()); - return; - } + { + FPRINTF (stderr, _("Initialization of plugin mechanism failed: %s!\n"), + lt_dlerror ()); + return; + } opath = lt_dlgetsearchpath (); if (opath != NULL) old_dlsearchpath = GNUNET_strdup (opath); path = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_LIBDIR); if (path != NULL) + { + if (opath != NULL) + { + GNUNET_asprintf (&cpath, "%s:%s", opath, path); + lt_dlsetsearchpath (cpath); + GNUNET_free (path); + GNUNET_free (cpath); + } + else { - if (opath != NULL) - { - GNUNET_asprintf (&cpath, - "%s:%s", - opath, - path); - lt_dlsetsearchpath (cpath); - GNUNET_free (path); - GNUNET_free (cpath); - } - else - { - lt_dlsetsearchpath (path); - GNUNET_free (path); - } + lt_dlsetsearchpath (path); + GNUNET_free (path); } + } } @@ -122,10 +120,10 @@ plugin_fini () { lt_dlsetsearchpath (old_dlsearchpath); if (old_dlsearchpath != NULL) - { - GNUNET_free (old_dlsearchpath); - old_dlsearchpath = NULL; - } + { + GNUNET_free (old_dlsearchpath); + old_dlsearchpath = NULL; + } lt_dlexit (); } @@ -144,9 +142,9 @@ resolve_function (struct PluginList *plug, const char *name) if (mptr == NULL) mptr = lt_dlsym (plug->handle, initName); if (mptr == NULL) - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("`%s' failed to resolve method '%s' with error: %s\n"), - "lt_dlsym", &initName[1], lt_dlerror ()); + LOG (GNUNET_ERROR_TYPE_ERROR, + _("`%s' failed to resolve method '%s' with error: %s\n"), "lt_dlsym", + &initName[1], lt_dlerror ()); GNUNET_free (initName); return mptr; } @@ -155,7 +153,7 @@ resolve_function (struct PluginList *plug, const char *name) * Test if a plugin exists. * * Note that the library must export a symbol called - * "library_name_init" for the test to succeed. + * "library_name_init" for the test to succeed. * * @param library_name name of the plugin to test if it is installed * @return GNUNET_YES if the plugin exists, GNUNET_NO if not @@ -167,23 +165,23 @@ GNUNET_PLUGIN_test (const char *library_name) GNUNET_PLUGIN_Callback init; struct PluginList plug; - if (! initialized) - { - initialized = GNUNET_YES; - plugin_init (); - } + if (!initialized) + { + initialized = GNUNET_YES; + plugin_init (); + } libhandle = lt_dlopenext (library_name); if (libhandle == NULL) return GNUNET_NO; plug.handle = libhandle; - plug.name = (char*) library_name; + plug.name = (char *) library_name; init = resolve_function (&plug, "init"); if (init == NULL) - { - GNUNET_break (0); - lt_dlclose (libhandle); - return GNUNET_NO; - } + { + GNUNET_break (0); + lt_dlclose (libhandle); + return GNUNET_NO; + } lt_dlclose (libhandle); return GNUNET_YES; } @@ -209,19 +207,19 @@ GNUNET_PLUGIN_load (const char *library_name, void *arg) GNUNET_PLUGIN_Callback init; void *ret; - if (! initialized) - { - initialized = GNUNET_YES; - plugin_init (); - } + if (!initialized) + { + initialized = GNUNET_YES; + plugin_init (); + } libhandle = lt_dlopenext (library_name); if (libhandle == NULL) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("`%s' failed for library `%s' with error: %s\n"), - "lt_dlopenext", library_name, lt_dlerror ()); - return NULL; - } + { + LOG (GNUNET_ERROR_TYPE_ERROR, + _("`%s' failed for library `%s' with error: %s\n"), "lt_dlopenext", + library_name, lt_dlerror ()); + return NULL; + } plug = GNUNET_malloc (sizeof (struct PluginList)); plug->handle = libhandle; plug->name = GNUNET_strdup (library_name); @@ -229,13 +227,13 @@ GNUNET_PLUGIN_load (const char *library_name, void *arg) plugins = plug; init = resolve_function (plug, "init"); if ((init == NULL) || (NULL == (ret = init (arg)))) - { - lt_dlclose (libhandle); - GNUNET_free (plug->name); - plugins = plug->next; - GNUNET_free (plug); - return NULL; - } + { + lt_dlclose (libhandle); + GNUNET_free (plug->name); + plugins = plug->next; + GNUNET_free (plug); + return NULL; + } return ret; } @@ -259,10 +257,10 @@ GNUNET_PLUGIN_unload (const char *library_name, void *arg) prev = NULL; pos = plugins; while ((pos != NULL) && (0 != strcmp (pos->name, library_name))) - { - prev = pos; - pos = pos->next; - } + { + prev = pos; + pos = pos->next; + } if (pos == NULL) return NULL; @@ -278,13 +276,86 @@ GNUNET_PLUGIN_unload (const char *library_name, void *arg) GNUNET_free (pos->name); GNUNET_free (pos); if (plugins == NULL) - { - plugin_fini(); - initialized = GNUNET_NO; - } + { + plugin_fini (); + initialized = GNUNET_NO; + } return ret; } +struct LoadAllContext +{ + const char *basename; + void *arg; + GNUNET_PLUGIN_LoaderCallback cb; + void *cb_cls; +}; + + +static int +find_libraries (void *cls, const char *filename) +{ + struct LoadAllContext *lac = cls; + const char *slashpos; + const char *libname; + char *basename; + char *dot; + void *lib_ret; + size_t n; + + libname = filename; + while (NULL != (slashpos = strstr (libname, DIR_SEPARATOR_STR))) + libname = slashpos + 1; + n = strlen (libname); + if (0 != strncmp (lac->basename, libname, strlen (lac->basename))) + return GNUNET_OK; /* wrong name */ + if ((n > 3) && (0 == strcmp (&libname[n - 3], ".la"))) + return GNUNET_OK; /* .la file */ + basename = GNUNET_strdup (libname); + if (NULL != (dot = strstr (basename, "."))) + *dot = '\0'; + lib_ret = GNUNET_PLUGIN_load (basename, lac->arg); + if (NULL != lib_ret) + lac->cb (lac->cb_cls, basename, lib_ret); + GNUNET_free (basename); + return GNUNET_OK; +} + + +/** + * Load all compatible plugins with the given base name. + * + * Note that the library must export symbols called + * "basename_ANYTHING_init" and "basename_ANYTHING__done". These will + * be called when the library is loaded and unloaded respectively. + * + * @param basename basename of the plugins to load + * @param arg argument to the plugin initialization function + * @param cb function to call for each plugin found + * @param cb_cls closure for 'cb' + */ +void +GNUNET_PLUGIN_load_all (const char *basename, void *arg, + GNUNET_PLUGIN_LoaderCallback cb, void *cb_cls) +{ + struct LoadAllContext lac; + char *path; + + path = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_LIBDIR); + if (path == NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Could not determine plugin installation path.\n")); + return; + } + lac.basename = basename; + lac.arg = arg; + lac.cb = cb; + lac.cb_cls = cb_cls; + GNUNET_DISK_directory_scan (path, &find_libraries, &lac); + GNUNET_free (path); +} + /* end of plugin.c */