change default configurations on systems with UNIX domain sockets to NOT specify...
[oweals/gnunet.git] / src / util / plugin.c
index 4e960b4fe83c778c1f5233f04fb591659bc2fd0d..4e0385a0984d65c1aa11cb0a7a2f073d65c53ce1 100644 (file)
@@ -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 */