service_new: ready_confirm_fd
[oweals/gnunet.git] / src / util / plugin.c
index dffc8ecd614b6ad55cb82833dbdb84f5ba90d7ca..c7ac47a7c355fb96f0661e451abacb30f01a593a 100644 (file)
@@ -1,10 +1,10 @@
 /*
      This file is part of GNUnet
 /*
      This file is part of GNUnet
-     (C) 2002, 2003, 2004, 2005, 2006, 2009 Christian Grothoff (and other contributing authors)
+     Copyright (C) 2002-2013 GNUnet e.V.
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 2, or (at your
+     by the Free Software Foundation; either version 3, or (at your
      option) any later version.
 
      GNUnet is distributed in the hope that it will be useful, but
      option) any later version.
 
      GNUnet is distributed in the hope that it will be useful, but
@@ -14,8 +14,8 @@
 
      You should have received a copy of the GNU General Public License
      along with GNUnet; see the file COPYING.  If not, write to the
 
      You should have received a copy of the GNU General Public License
      along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-     Boston, MA 02111-1307, USA.
+     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+     Boston, MA 02110-1301, USA.
 */
 
 /**
 */
 
 /**
@@ -26,9 +26,7 @@
 
 #include "platform.h"
 #include <ltdl.h>
 
 #include "platform.h"
 #include <ltdl.h>
-#include "gnunet_common.h"
-#include "gnunet_os_lib.h"
-#include "gnunet_plugin_lib.h"
+#include "gnunet_util_lib.h"
 
 #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
 
 
 #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
 
@@ -59,13 +57,11 @@ struct PluginList
  */
 static int initialized;
 
  */
 static int initialized;
 
-
 /**
  * Libtool search path before we started.
  */
 static char *old_dlsearchpath;
 
 /**
  * Libtool search path before we started.
  */
 static char *old_dlsearchpath;
 
-
 /**
  * List of plugins we have loaded.
  */
 /**
  * List of plugins we have loaded.
  */
@@ -85,30 +81,31 @@ plugin_init ()
 
   err = lt_dlinit ();
   if (err > 0)
 
   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 ();
   opath = lt_dlgetsearchpath ();
-  if (opath != NULL)
+  if (NULL != opath)
     old_dlsearchpath = GNUNET_strdup (opath);
   path = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_LIBDIR);
     old_dlsearchpath = GNUNET_strdup (opath);
   path = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_LIBDIR);
-  if (path != NULL)
+  if (NULL != path)
+  {
+    if (NULL != opath)
     {
     {
-      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);
-       }
+      GNUNET_asprintf (&cpath, "%s:%s", opath, path);
+      lt_dlsetsearchpath (cpath);
+      GNUNET_free (path);
+      GNUNET_free (cpath);
     }
     }
+    else
+    {
+      lt_dlsetsearchpath (path);
+      GNUNET_free (path);
+    }
+  }
 }
 
 
 }
 
 
@@ -119,44 +116,54 @@ static void
 plugin_fini ()
 {
   lt_dlsetsearchpath (old_dlsearchpath);
 plugin_fini ()
 {
   lt_dlsetsearchpath (old_dlsearchpath);
-  if (old_dlsearchpath != NULL)
-    {
-      GNUNET_free (old_dlsearchpath);
-      old_dlsearchpath = NULL;
-    }
+  if (NULL != old_dlsearchpath)
+  {
+    GNUNET_free (old_dlsearchpath);
+    old_dlsearchpath = NULL;
+  }
   lt_dlexit ();
 }
 
 
 /**
  * Lookup a function in the plugin.
   lt_dlexit ();
 }
 
 
 /**
  * Lookup a function in the plugin.
+ *
+ * @param plug the plugin to check
+ * @param name name of the symbol to look for
+ * @return NULL if the symbol was not found
  */
 static GNUNET_PLUGIN_Callback
  */
 static GNUNET_PLUGIN_Callback
-resolve_function (struct PluginList *plug, const char *name)
+resolve_function (struct PluginList *plug,
+                  const char *name)
 {
   char *initName;
   void *mptr;
 
 {
   char *initName;
   void *mptr;
 
-  GNUNET_asprintf (&initName, "_%s_%s", plug->name, name);
+  GNUNET_asprintf (&initName,
+                   "_%s_%s",
+                   plug->name,
+                   name);
   mptr = lt_dlsym (plug->handle, &initName[1]);
   mptr = lt_dlsym (plug->handle, &initName[1]);
-  if (mptr == NULL)
+  if (NULL == mptr)
     mptr = lt_dlsym (plug->handle, initName);
     mptr = lt_dlsym (plug->handle, initName);
-  if (mptr == NULL)
+  if (NULL == mptr)
     LOG (GNUNET_ERROR_TYPE_ERROR,
     LOG (GNUNET_ERROR_TYPE_ERROR,
-        _("`%s' failed to resolve method '%s' with error: %s\n"),
-        "lt_dlsym", &initName[1], lt_dlerror ());
+         _("`%s' failed to resolve method '%s' with error: %s\n"),
+         "lt_dlsym",
+         &initName[1], lt_dlerror ());
   GNUNET_free (initName);
   return mptr;
 }
 
   GNUNET_free (initName);
   return mptr;
 }
 
+
 /**
  * Test if a plugin exists.
  *
  * Note that the library must export a symbol called
 /**
  * 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
  *
  * @param library_name name of the plugin to test if it is installed
- * @return GNUNET_YES if the plugin exists, GNUNET_NO if not
+ * @return #GNUNET_YES if the plugin exists, #GNUNET_NO if not
  */
 int
 GNUNET_PLUGIN_test (const char *library_name)
  */
 int
 GNUNET_PLUGIN_test (const char *library_name)
@@ -165,34 +172,34 @@ GNUNET_PLUGIN_test (const char *library_name)
   GNUNET_PLUGIN_Callback init;
   struct PluginList plug;
 
   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);
   libhandle = lt_dlopenext (library_name);
-  if (libhandle == NULL)
+  if (NULL == libhandle)
     return GNUNET_NO;
   plug.handle = libhandle;
   plug.name = (char *) library_name;
   init = resolve_function (&plug, "init");
     return GNUNET_NO;
   plug.handle = libhandle;
   plug.name = (char *) library_name;
   init = resolve_function (&plug, "init");
-  if (init == NULL)
-    {
-      GNUNET_break (0);
-      lt_dlclose (libhandle);
-      return GNUNET_NO;
-    }
+  if (NULL == init)
+  {
+    GNUNET_break (0);
+    lt_dlclose (libhandle);
+    return GNUNET_NO;
+  }
   lt_dlclose (libhandle);
   return GNUNET_YES;
 }
 
 
 /**
   lt_dlclose (libhandle);
   return GNUNET_YES;
 }
 
 
 /**
- * Setup plugin (runs the "init" callback and returns whatever "init"
- * returned).  If "init" returns NULL, the plugin is unloaded.
+ * Setup plugin (runs the `init` callback and returns whatever `init`
+ * returned).  If `init` returns NULL, the plugin is unloaded.
  *
  * Note that the library must export symbols called
  *
  * Note that the library must export symbols called
- * "library_name_init" and "library_name_done".  These will be called
+ * `library_name_init` and `library_name_done`.  These will be called
  * when the library is loaded and unloaded respectively.
  *
  * @param library_name name of the plugin to load
  * when the library is loaded and unloaded respectively.
  *
  * @param library_name name of the plugin to load
@@ -208,38 +215,39 @@ GNUNET_PLUGIN_load (const char *library_name, void *arg)
   void *ret;
 
   if (!initialized)
   void *ret;
 
   if (!initialized)
-    {
-      initialized = GNUNET_YES;
-      plugin_init ();
-    }
+  {
+    initialized = GNUNET_YES;
+    plugin_init ();
+  }
   libhandle = lt_dlopenext (library_name);
   if (libhandle == NULL)
   libhandle = lt_dlopenext (library_name);
   if (libhandle == 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));
+  {
+    LOG (GNUNET_ERROR_TYPE_ERROR,
+         _("`%s' failed for library `%s' with error: %s\n"),
+         "lt_dlopenext",
+         library_name, lt_dlerror ());
+    return NULL;
+  }
+  plug = GNUNET_new (struct PluginList);
   plug->handle = libhandle;
   plug->name = GNUNET_strdup (library_name);
   plug->next = plugins;
   plugins = plug;
   init = resolve_function (plug, "init");
   if ((init == NULL) || (NULL == (ret = init (arg))))
   plug->handle = libhandle;
   plug->name = GNUNET_strdup (library_name);
   plug->next = plugins;
   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;
 }
 
 
 /**
   return ret;
 }
 
 
 /**
- * Unload plugin (runs the "done" callback and returns whatever "done"
+ * Unload plugin (runs the `done` callback and returns whatever `done`
  * returned).  The plugin is then unloaded.
  *
  * @param library_name name of the plugin to unload
  * returned).  The plugin is then unloaded.
  *
  * @param library_name name of the plugin to unload
@@ -247,7 +255,8 @@ GNUNET_PLUGIN_load (const char *library_name, void *arg)
  * @return whatever the shutdown function returned
  */
 void *
  * @return whatever the shutdown function returned
  */
 void *
-GNUNET_PLUGIN_unload (const char *library_name, void *arg)
+GNUNET_PLUGIN_unload (const char *library_name,
+                      void *arg)
 {
   struct PluginList *pos;
   struct PluginList *prev;
 {
   struct PluginList *pos;
   struct PluginList *prev;
@@ -256,46 +265,72 @@ GNUNET_PLUGIN_unload (const char *library_name, void *arg)
 
   prev = NULL;
   pos = plugins;
 
   prev = NULL;
   pos = plugins;
-  while ((pos != NULL) && (0 != strcmp (pos->name, library_name)))
-    {
-      prev = pos;
-      pos = pos->next;
-    }
-  if (pos == NULL)
+  while ((NULL != pos) && (0 != strcmp (pos->name, library_name)))
+  {
+    prev = pos;
+    pos = pos->next;
+  }
+  if (NULL == pos)
     return NULL;
 
   done = resolve_function (pos, "done");
   ret = NULL;
     return NULL;
 
   done = resolve_function (pos, "done");
   ret = NULL;
-  if (done != NULL)
+  if (NULL != done)
     ret = done (arg);
     ret = done (arg);
-  if (prev == NULL)
+  if (NULL == prev)
     plugins = pos->next;
   else
     prev->next = pos->next;
   lt_dlclose (pos->handle);
   GNUNET_free (pos->name);
   GNUNET_free (pos);
     plugins = pos->next;
   else
     prev->next = pos->next;
   lt_dlclose (pos->handle);
   GNUNET_free (pos->name);
   GNUNET_free (pos);
-  if (plugins == NULL)
-    {
-      plugin_fini ();
-      initialized = GNUNET_NO;
-    }
+  if (NULL == plugins)
+  {
+    plugin_fini ();
+    initialized = GNUNET_NO;
+  }
   return ret;
 }
 
 
   return ret;
 }
 
 
+/**
+ * Closure for #find_libraries().
+ */
 struct LoadAllContext
 {
 struct LoadAllContext
 {
+  /**
+   * Prefix the plugin names we find have to match.
+   */
   const char *basename;
   const char *basename;
+
+  /**
+   * Argument to give to 'init' when loading the plugin.
+   */
   void *arg;
   void *arg;
+
+  /**
+   * Function to call for each plugin.
+   */
   GNUNET_PLUGIN_LoaderCallback cb;
   GNUNET_PLUGIN_LoaderCallback cb;
+
+  /**
+   * Closure for @e cb
+   */
   void *cb_cls;
 };
 
 
   void *cb_cls;
 };
 
 
+/**
+ * Function called on each plugin in the directory.  Loads
+ * the plugins that match the given basename.
+ *
+ * @param cls the `struct LoadAllContext` describing which
+ *            plugins to load and what to do with them
+ * @param filename name of a plugin library to check
+ * @return #GNUNET_OK (continue loading)
+ */
 static int
 static int
-find_libraries (void *cls,
-               const char *filename)
+find_libraries (void *cls, const char *filename)
 {
   struct LoadAllContext *lac = cls;
   const char *slashpos;
 {
   struct LoadAllContext *lac = cls;
   const char *slashpos;
@@ -309,14 +344,10 @@ find_libraries (void *cls,
   while (NULL != (slashpos = strstr (libname, DIR_SEPARATOR_STR)))
     libname = slashpos + 1;
   n = strlen (libname);
   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 */
+  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';
   basename = GNUNET_strdup (libname);
   if (NULL != (dot = strstr (basename, ".")))
     *dot = '\0';
@@ -332,37 +363,33 @@ find_libraries (void *cls,
  * Load all compatible plugins with the given base name.
  *
  * Note that the library must export symbols called
  * 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
+ * `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
  * 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'
+ * @param cb_cls closure for @a cb
  */
  */
-void 
-GNUNET_PLUGIN_load_all (const char *basename, 
-                       void *arg,
-                       GNUNET_PLUGIN_LoaderCallback cb,
-                       void *cb_cls)
+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);
 {
   struct LoadAllContext lac;
   char *path;
 
   path = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_LIBDIR);
-  if (path == NULL)
+  if (NULL == path)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-               _("Could not determine plugin installation path.\n"));
+                _("Could not determine plugin installation path.\n"));
     return;
   }
   lac.basename = basename;
   lac.arg = arg;
   lac.cb = cb;
   lac.cb_cls = cb_cls;
     return;
   }
   lac.basename = basename;
   lac.arg = arg;
   lac.cb = cb;
   lac.cb_cls = cb_cls;
-  GNUNET_DISK_directory_scan (path,
-                             &find_libraries,
-                             &lac);
+  GNUNET_DISK_directory_scan (path, &find_libraries, &lac);
   GNUNET_free (path);
 }
 
   GNUNET_free (path);
 }