gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r17967 - in gnunet/src: include util


From: gnunet
Subject: [GNUnet-SVN] r17967 - in gnunet/src: include util
Date: Thu, 3 Nov 2011 16:24:08 +0100

Author: grothoff
Date: 2011-11-03 16:24:08 +0100 (Thu, 03 Nov 2011)
New Revision: 17967

Modified:
   gnunet/src/include/gnunet_plugin_lib.h
   gnunet/src/util/plugin.c
   gnunet/src/util/test_plugin.c
Log:
implementing plugin directory scanner for #1746

Modified: gnunet/src/include/gnunet_plugin_lib.h
===================================================================
--- gnunet/src/include/gnunet_plugin_lib.h      2011-11-03 15:00:26 UTC (rev 
17966)
+++ gnunet/src/include/gnunet_plugin_lib.h      2011-11-03 15:24:08 UTC (rev 
17967)
@@ -62,6 +62,7 @@
 int
 GNUNET_PLUGIN_test (const char *library_name);
 
+
 /**
  * Setup plugin (runs the "init" callback and returns whatever "init"
  * returned).  If "init" returns NULL, the plugin is unloaded.
@@ -79,6 +80,40 @@
 
 
 /**
+ * Signature of a function called by 'GNUNET_PLUGIN_load_all'.
+ *
+ * @param cls closure
+ * @param library_name full name of the library (to be used with
+ *        'GNUNET_PLUGIN_unload')
+ * @param lib_ret return value from the initialization function
+ *        of the library (same as what 'GNUNET_PLUGIN_load' would
+ *        have returned for the given library name)
+ */
+typedef void (*GNUNET_PLUGIN_LoaderCallback)(void *cls,
+                                            const char *library_name,
+                                            void *lib_ret);
+
+
+/**
+ * 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);
+
+
+/**
  * Unload plugin (runs the "done" callback and returns whatever "done"
  * returned).  The plugin is then unloaded.
  *

Modified: gnunet/src/util/plugin.c
===================================================================
--- gnunet/src/util/plugin.c    2011-11-03 15:00:26 UTC (rev 17966)
+++ gnunet/src/util/plugin.c    2011-11-03 15:24:08 UTC (rev 17967)
@@ -284,5 +284,87 @@
 }
 
 
+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 */

Modified: gnunet/src/util/test_plugin.c
===================================================================
--- gnunet/src/util/test_plugin.c       2011-11-03 15:00:26 UTC (rev 17966)
+++ gnunet/src/util/test_plugin.c       2011-11-03 15:24:08 UTC (rev 17967)
@@ -26,6 +26,17 @@
 
 #define VERBOSE GNUNET_EXTRA_LOGGING
 
+static void
+test_cb (void *cls,
+        const char *libname,
+        void *lib_ret)
+{
+  GNUNET_assert (0 == strcmp (cls, "test"));
+  GNUNET_assert (0 == strcmp (lib_ret, "Hello"));
+  GNUNET_assert (0 == strcmp (GNUNET_PLUGIN_unload (libname, "out"), "World"));
+}
+        
+
 static int
 check ()
 {
@@ -47,6 +58,8 @@
   if (0 != strcmp (ret, "World"))
     return 4;
   free (ret);
+
+  GNUNET_PLUGIN_load_all ("libgnunet_plugin_tes", "in", &test_cb, "test");
   return 0;
 }
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]