diff options
author | Christian Grothoff <christian@grothoff.org> | 2011-11-03 15:24:08 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2011-11-03 15:24:08 +0000 |
commit | 84a70da19fdf98b028b98e23a228e32f591535fe (patch) | |
tree | 3fde202b9a1d16c4594c25f5a64dea15e989a160 /src/util | |
parent | 7ae7229d2de6a6ef842634265847a46ac46f8c5c (diff) | |
download | gnunet-84a70da19fdf98b028b98e23a228e32f591535fe.tar.gz gnunet-84a70da19fdf98b028b98e23a228e32f591535fe.zip |
implementing plugin directory scanner for #1746
Diffstat (limited to 'src/util')
-rw-r--r-- | src/util/plugin.c | 82 | ||||
-rw-r--r-- | src/util/test_plugin.c | 13 |
2 files changed, 95 insertions, 0 deletions
diff --git a/src/util/plugin.c b/src/util/plugin.c index 77631410c..dffc8ecd6 100644 --- a/src/util/plugin.c +++ b/src/util/plugin.c | |||
@@ -284,5 +284,87 @@ GNUNET_PLUGIN_unload (const char *library_name, void *arg) | |||
284 | } | 284 | } |
285 | 285 | ||
286 | 286 | ||
287 | struct LoadAllContext | ||
288 | { | ||
289 | const char *basename; | ||
290 | void *arg; | ||
291 | GNUNET_PLUGIN_LoaderCallback cb; | ||
292 | void *cb_cls; | ||
293 | }; | ||
294 | |||
295 | |||
296 | static int | ||
297 | find_libraries (void *cls, | ||
298 | const char *filename) | ||
299 | { | ||
300 | struct LoadAllContext *lac = cls; | ||
301 | const char *slashpos; | ||
302 | const char *libname; | ||
303 | char *basename; | ||
304 | char *dot; | ||
305 | void *lib_ret; | ||
306 | size_t n; | ||
307 | |||
308 | libname = filename; | ||
309 | while (NULL != (slashpos = strstr (libname, DIR_SEPARATOR_STR))) | ||
310 | libname = slashpos + 1; | ||
311 | n = strlen (libname); | ||
312 | if (0 != strncmp (lac->basename, | ||
313 | libname, | ||
314 | strlen (lac->basename))) | ||
315 | return GNUNET_OK; /* wrong name */ | ||
316 | if ( (n > 3) && | ||
317 | (0 == strcmp (&libname[n-3], | ||
318 | ".la")) ) | ||
319 | return GNUNET_OK; /* .la file */ | ||
320 | basename = GNUNET_strdup (libname); | ||
321 | if (NULL != (dot = strstr (basename, "."))) | ||
322 | *dot = '\0'; | ||
323 | lib_ret = GNUNET_PLUGIN_load (basename, lac->arg); | ||
324 | if (NULL != lib_ret) | ||
325 | lac->cb (lac->cb_cls, basename, lib_ret); | ||
326 | GNUNET_free (basename); | ||
327 | return GNUNET_OK; | ||
328 | } | ||
329 | |||
330 | |||
331 | /** | ||
332 | * Load all compatible plugins with the given base name. | ||
333 | * | ||
334 | * Note that the library must export symbols called | ||
335 | * "basename_ANYTHING_init" and "basename_ANYTHING__done". These will | ||
336 | * be called when the library is loaded and unloaded respectively. | ||
337 | * | ||
338 | * @param basename basename of the plugins to load | ||
339 | * @param arg argument to the plugin initialization function | ||
340 | * @param cb function to call for each plugin found | ||
341 | * @param cb_cls closure for 'cb' | ||
342 | */ | ||
343 | void | ||
344 | GNUNET_PLUGIN_load_all (const char *basename, | ||
345 | void *arg, | ||
346 | GNUNET_PLUGIN_LoaderCallback cb, | ||
347 | void *cb_cls) | ||
348 | { | ||
349 | struct LoadAllContext lac; | ||
350 | char *path; | ||
351 | |||
352 | path = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_LIBDIR); | ||
353 | if (path == NULL) | ||
354 | { | ||
355 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
356 | _("Could not determine plugin installation path.\n")); | ||
357 | return; | ||
358 | } | ||
359 | lac.basename = basename; | ||
360 | lac.arg = arg; | ||
361 | lac.cb = cb; | ||
362 | lac.cb_cls = cb_cls; | ||
363 | GNUNET_DISK_directory_scan (path, | ||
364 | &find_libraries, | ||
365 | &lac); | ||
366 | GNUNET_free (path); | ||
367 | } | ||
368 | |||
287 | 369 | ||
288 | /* end of plugin.c */ | 370 | /* end of plugin.c */ |
diff --git a/src/util/test_plugin.c b/src/util/test_plugin.c index 479edb3cb..dc34841f5 100644 --- a/src/util/test_plugin.c +++ b/src/util/test_plugin.c | |||
@@ -26,6 +26,17 @@ | |||
26 | 26 | ||
27 | #define VERBOSE GNUNET_EXTRA_LOGGING | 27 | #define VERBOSE GNUNET_EXTRA_LOGGING |
28 | 28 | ||
29 | static void | ||
30 | test_cb (void *cls, | ||
31 | const char *libname, | ||
32 | void *lib_ret) | ||
33 | { | ||
34 | GNUNET_assert (0 == strcmp (cls, "test")); | ||
35 | GNUNET_assert (0 == strcmp (lib_ret, "Hello")); | ||
36 | GNUNET_assert (0 == strcmp (GNUNET_PLUGIN_unload (libname, "out"), "World")); | ||
37 | } | ||
38 | |||
39 | |||
29 | static int | 40 | static int |
30 | check () | 41 | check () |
31 | { | 42 | { |
@@ -47,6 +58,8 @@ check () | |||
47 | if (0 != strcmp (ret, "World")) | 58 | if (0 != strcmp (ret, "World")) |
48 | return 4; | 59 | return 4; |
49 | free (ret); | 60 | free (ret); |
61 | |||
62 | GNUNET_PLUGIN_load_all ("libgnunet_plugin_tes", "in", &test_cb, "test"); | ||
50 | return 0; | 63 | return 0; |
51 | } | 64 | } |
52 | 65 | ||