aboutsummaryrefslogtreecommitdiff
path: root/src/util/plugin.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/plugin.c')
-rw-r--r--src/util/plugin.c246
1 files changed, 122 insertions, 124 deletions
diff --git a/src/util/plugin.c b/src/util/plugin.c
index 19169f070..2b11e5c3c 100644
--- a/src/util/plugin.c
+++ b/src/util/plugin.c
@@ -16,7 +16,7 @@
16 along with this program. If not, see <http://www.gnu.org/licenses/>. 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 17
18 SPDX-License-Identifier: AGPL3.0-or-later 18 SPDX-License-Identifier: AGPL3.0-or-later
19*/ 19 */
20 20
21/** 21/**
22 * @file util/plugin.c 22 * @file util/plugin.c
@@ -28,13 +28,12 @@
28#include <ltdl.h> 28#include <ltdl.h>
29#include "gnunet_util_lib.h" 29#include "gnunet_util_lib.h"
30 30
31#define LOG(kind, ...) GNUNET_log_from (kind, "util-plugin", __VA_ARGS__) 31#define LOG(kind, ...) GNUNET_log_from(kind, "util-plugin", __VA_ARGS__)
32 32
33/** 33/**
34 * Linked list of active plugins. 34 * Linked list of active plugins.
35 */ 35 */
36struct PluginList 36struct PluginList {
37{
38 /** 37 /**
39 * This is a linked list. 38 * This is a linked list.
40 */ 39 */
@@ -72,40 +71,40 @@ static struct PluginList *plugins;
72 * Setup libtool paths. 71 * Setup libtool paths.
73 */ 72 */
74static void 73static void
75plugin_init () 74plugin_init()
76{ 75{
77 int err; 76 int err;
78 const char *opath; 77 const char *opath;
79 char *path; 78 char *path;
80 char *cpath; 79 char *cpath;
81 80
82 err = lt_dlinit (); 81 err = lt_dlinit();
83 if (err > 0) 82 if (err > 0)
84 {
85 fprintf (stderr,
86 _ ("Initialization of plugin mechanism failed: %s!\n"),
87 lt_dlerror ());
88 return;
89 }
90 opath = lt_dlgetsearchpath ();
91 if (NULL != opath)
92 old_dlsearchpath = GNUNET_strdup (opath);
93 path = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_LIBDIR);
94 if (NULL != path)
95 {
96 if (NULL != opath)
97 { 83 {
98 GNUNET_asprintf (&cpath, "%s:%s", opath, path); 84 fprintf(stderr,
99 lt_dlsetsearchpath (cpath); 85 _("Initialization of plugin mechanism failed: %s!\n"),
100 GNUNET_free (path); 86 lt_dlerror());
101 GNUNET_free (cpath); 87 return;
102 } 88 }
103 else 89 opath = lt_dlgetsearchpath();
90 if (NULL != opath)
91 old_dlsearchpath = GNUNET_strdup(opath);
92 path = GNUNET_OS_installation_get_path(GNUNET_OS_IPK_LIBDIR);
93 if (NULL != path)
104 { 94 {
105 lt_dlsetsearchpath (path); 95 if (NULL != opath)
106 GNUNET_free (path); 96 {
97 GNUNET_asprintf(&cpath, "%s:%s", opath, path);
98 lt_dlsetsearchpath(cpath);
99 GNUNET_free(path);
100 GNUNET_free(cpath);
101 }
102 else
103 {
104 lt_dlsetsearchpath(path);
105 GNUNET_free(path);
106 }
107 } 107 }
108 }
109} 108}
110 109
111 110
@@ -113,15 +112,15 @@ plugin_init ()
113 * Shutdown libtool. 112 * Shutdown libtool.
114 */ 113 */
115static void 114static void
116plugin_fini () 115plugin_fini()
117{ 116{
118 lt_dlsetsearchpath (old_dlsearchpath); 117 lt_dlsetsearchpath(old_dlsearchpath);
119 if (NULL != old_dlsearchpath) 118 if (NULL != old_dlsearchpath)
120 { 119 {
121 GNUNET_free (old_dlsearchpath); 120 GNUNET_free(old_dlsearchpath);
122 old_dlsearchpath = NULL; 121 old_dlsearchpath = NULL;
123 } 122 }
124 lt_dlexit (); 123 lt_dlexit();
125} 124}
126 125
127 126
@@ -133,22 +132,22 @@ plugin_fini ()
133 * @return NULL if the symbol was not found 132 * @return NULL if the symbol was not found
134 */ 133 */
135static GNUNET_PLUGIN_Callback 134static GNUNET_PLUGIN_Callback
136resolve_function (struct PluginList *plug, const char *name) 135resolve_function(struct PluginList *plug, const char *name)
137{ 136{
138 char *initName; 137 char *initName;
139 void *mptr; 138 void *mptr;
140 139
141 GNUNET_asprintf (&initName, "_%s_%s", plug->name, name); 140 GNUNET_asprintf(&initName, "_%s_%s", plug->name, name);
142 mptr = lt_dlsym (plug->handle, &initName[1]); 141 mptr = lt_dlsym(plug->handle, &initName[1]);
143 if (NULL == mptr) 142 if (NULL == mptr)
144 mptr = lt_dlsym (plug->handle, initName); 143 mptr = lt_dlsym(plug->handle, initName);
145 if (NULL == mptr) 144 if (NULL == mptr)
146 LOG (GNUNET_ERROR_TYPE_ERROR, 145 LOG(GNUNET_ERROR_TYPE_ERROR,
147 _ ("`%s' failed to resolve method '%s' with error: %s\n"), 146 _("`%s' failed to resolve method '%s' with error: %s\n"),
148 "lt_dlsym", 147 "lt_dlsym",
149 &initName[1], 148 &initName[1],
150 lt_dlerror ()); 149 lt_dlerror());
151 GNUNET_free (initName); 150 GNUNET_free(initName);
152 return mptr; 151 return mptr;
153} 152}
154 153
@@ -163,30 +162,30 @@ resolve_function (struct PluginList *plug, const char *name)
163 * @return #GNUNET_YES if the plugin exists, #GNUNET_NO if not 162 * @return #GNUNET_YES if the plugin exists, #GNUNET_NO if not
164 */ 163 */
165int 164int
166GNUNET_PLUGIN_test (const char *library_name) 165GNUNET_PLUGIN_test(const char *library_name)
167{ 166{
168 void *libhandle; 167 void *libhandle;
169 GNUNET_PLUGIN_Callback init; 168 GNUNET_PLUGIN_Callback init;
170 struct PluginList plug; 169 struct PluginList plug;
171 170
172 if (! initialized) 171 if (!initialized)
173 { 172 {
174 initialized = GNUNET_YES; 173 initialized = GNUNET_YES;
175 plugin_init (); 174 plugin_init();
176 } 175 }
177 libhandle = lt_dlopenext (library_name); 176 libhandle = lt_dlopenext(library_name);
178 if (NULL == libhandle) 177 if (NULL == libhandle)
179 return GNUNET_NO; 178 return GNUNET_NO;
180 plug.handle = libhandle; 179 plug.handle = libhandle;
181 plug.name = (char *) library_name; 180 plug.name = (char *)library_name;
182 init = resolve_function (&plug, "init"); 181 init = resolve_function(&plug, "init");
183 if (NULL == init) 182 if (NULL == init)
184 { 183 {
185 GNUNET_break (0); 184 GNUNET_break(0);
186 lt_dlclose (libhandle); 185 lt_dlclose(libhandle);
187 return GNUNET_NO; 186 return GNUNET_NO;
188 } 187 }
189 lt_dlclose (libhandle); 188 lt_dlclose(libhandle);
190 return GNUNET_YES; 189 return GNUNET_YES;
191} 190}
192 191
@@ -204,42 +203,42 @@ GNUNET_PLUGIN_test (const char *library_name)
204 * @return whatever the initialization function returned 203 * @return whatever the initialization function returned
205 */ 204 */
206void * 205void *
207GNUNET_PLUGIN_load (const char *library_name, void *arg) 206GNUNET_PLUGIN_load(const char *library_name, void *arg)
208{ 207{
209 void *libhandle; 208 void *libhandle;
210 struct PluginList *plug; 209 struct PluginList *plug;
211 GNUNET_PLUGIN_Callback init; 210 GNUNET_PLUGIN_Callback init;
212 void *ret; 211 void *ret;
213 212
214 if (! initialized) 213 if (!initialized)
215 { 214 {
216 initialized = GNUNET_YES; 215 initialized = GNUNET_YES;
217 plugin_init (); 216 plugin_init();
218 } 217 }
219 libhandle = lt_dlopenext (library_name); 218 libhandle = lt_dlopenext(library_name);
220 if (libhandle == NULL) 219 if (libhandle == NULL)
221 { 220 {
222 LOG (GNUNET_ERROR_TYPE_ERROR, 221 LOG(GNUNET_ERROR_TYPE_ERROR,
223 _ ("`%s' failed for library `%s' with error: %s\n"), 222 _("`%s' failed for library `%s' with error: %s\n"),
224 "lt_dlopenext", 223 "lt_dlopenext",
225 library_name, 224 library_name,
226 lt_dlerror ()); 225 lt_dlerror());
227 return NULL; 226 return NULL;
228 } 227 }
229 plug = GNUNET_new (struct PluginList); 228 plug = GNUNET_new(struct PluginList);
230 plug->handle = libhandle; 229 plug->handle = libhandle;
231 plug->name = GNUNET_strdup (library_name); 230 plug->name = GNUNET_strdup(library_name);
232 plug->next = plugins; 231 plug->next = plugins;
233 plugins = plug; 232 plugins = plug;
234 init = resolve_function (plug, "init"); 233 init = resolve_function(plug, "init");
235 if ((init == NULL) || (NULL == (ret = init (arg)))) 234 if ((init == NULL) || (NULL == (ret = init(arg))))
236 { 235 {
237 lt_dlclose (libhandle); 236 lt_dlclose(libhandle);
238 GNUNET_free (plug->name); 237 GNUNET_free(plug->name);
239 plugins = plug->next; 238 plugins = plug->next;
240 GNUNET_free (plug); 239 GNUNET_free(plug);
241 return NULL; 240 return NULL;
242 } 241 }
243 return ret; 242 return ret;
244} 243}
245 244
@@ -253,7 +252,7 @@ GNUNET_PLUGIN_load (const char *library_name, void *arg)
253 * @return whatever the shutdown function returned 252 * @return whatever the shutdown function returned
254 */ 253 */
255void * 254void *
256GNUNET_PLUGIN_unload (const char *library_name, void *arg) 255GNUNET_PLUGIN_unload(const char *library_name, void *arg)
257{ 256{
258 struct PluginList *pos; 257 struct PluginList *pos;
259 struct PluginList *prev; 258 struct PluginList *prev;
@@ -262,30 +261,30 @@ GNUNET_PLUGIN_unload (const char *library_name, void *arg)
262 261
263 prev = NULL; 262 prev = NULL;
264 pos = plugins; 263 pos = plugins;
265 while ((NULL != pos) && (0 != strcmp (pos->name, library_name))) 264 while ((NULL != pos) && (0 != strcmp(pos->name, library_name)))
266 { 265 {
267 prev = pos; 266 prev = pos;
268 pos = pos->next; 267 pos = pos->next;
269 } 268 }
270 if (NULL == pos) 269 if (NULL == pos)
271 return NULL; 270 return NULL;
272 271
273 done = resolve_function (pos, "done"); 272 done = resolve_function(pos, "done");
274 ret = NULL; 273 ret = NULL;
275 if (NULL != done) 274 if (NULL != done)
276 ret = done (arg); 275 ret = done(arg);
277 if (NULL == prev) 276 if (NULL == prev)
278 plugins = pos->next; 277 plugins = pos->next;
279 else 278 else
280 prev->next = pos->next; 279 prev->next = pos->next;
281 lt_dlclose (pos->handle); 280 lt_dlclose(pos->handle);
282 GNUNET_free (pos->name); 281 GNUNET_free(pos->name);
283 GNUNET_free (pos); 282 GNUNET_free(pos);
284 if (NULL == plugins) 283 if (NULL == plugins)
285 { 284 {
286 plugin_fini (); 285 plugin_fini();
287 initialized = GNUNET_NO; 286 initialized = GNUNET_NO;
288 } 287 }
289 return ret; 288 return ret;
290} 289}
291 290
@@ -293,8 +292,7 @@ GNUNET_PLUGIN_unload (const char *library_name, void *arg)
293/** 292/**
294 * Closure for #find_libraries(). 293 * Closure for #find_libraries().
295 */ 294 */
296struct LoadAllContext 295struct LoadAllContext {
297{
298 /** 296 /**
299 * Prefix the plugin names we find have to match. 297 * Prefix the plugin names we find have to match.
300 */ 298 */
@@ -327,7 +325,7 @@ struct LoadAllContext
327 * @return #GNUNET_OK (continue loading) 325 * @return #GNUNET_OK (continue loading)
328 */ 326 */
329static int 327static int
330find_libraries (void *cls, const char *filename) 328find_libraries(void *cls, const char *filename)
331{ 329{
332 struct LoadAllContext *lac = cls; 330 struct LoadAllContext *lac = cls;
333 const char *slashpos; 331 const char *slashpos;
@@ -338,20 +336,20 @@ find_libraries (void *cls, const char *filename)
338 size_t n; 336 size_t n;
339 337
340 libname = filename; 338 libname = filename;
341 while (NULL != (slashpos = strstr (libname, DIR_SEPARATOR_STR))) 339 while (NULL != (slashpos = strstr(libname, DIR_SEPARATOR_STR)))
342 libname = slashpos + 1; 340 libname = slashpos + 1;
343 n = strlen (libname); 341 n = strlen(libname);
344 if (0 != strncmp (lac->basename, libname, strlen (lac->basename))) 342 if (0 != strncmp(lac->basename, libname, strlen(lac->basename)))
345 return GNUNET_OK; /* wrong name */ 343 return GNUNET_OK; /* wrong name */
346 if ((n > 3) && (0 == strcmp (&libname[n - 3], ".la"))) 344 if ((n > 3) && (0 == strcmp(&libname[n - 3], ".la")))
347 return GNUNET_OK; /* .la file */ 345 return GNUNET_OK; /* .la file */
348 basename = GNUNET_strdup (libname); 346 basename = GNUNET_strdup(libname);
349 if (NULL != (dot = strstr (basename, "."))) 347 if (NULL != (dot = strstr(basename, ".")))
350 *dot = '\0'; 348 *dot = '\0';
351 lib_ret = GNUNET_PLUGIN_load (basename, lac->arg); 349 lib_ret = GNUNET_PLUGIN_load(basename, lac->arg);
352 if (NULL != lib_ret) 350 if (NULL != lib_ret)
353 lac->cb (lac->cb_cls, basename, lib_ret); 351 lac->cb(lac->cb_cls, basename, lib_ret);
354 GNUNET_free (basename); 352 GNUNET_free(basename);
355 return GNUNET_OK; 353 return GNUNET_OK;
356} 354}
357 355
@@ -369,27 +367,27 @@ find_libraries (void *cls, const char *filename)
369 * @param cb_cls closure for @a cb 367 * @param cb_cls closure for @a cb
370 */ 368 */
371void 369void
372GNUNET_PLUGIN_load_all (const char *basename, 370GNUNET_PLUGIN_load_all(const char *basename,
373 void *arg, 371 void *arg,
374 GNUNET_PLUGIN_LoaderCallback cb, 372 GNUNET_PLUGIN_LoaderCallback cb,
375 void *cb_cls) 373 void *cb_cls)
376{ 374{
377 struct LoadAllContext lac; 375 struct LoadAllContext lac;
378 char *path; 376 char *path;
379 377
380 path = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_LIBDIR); 378 path = GNUNET_OS_installation_get_path(GNUNET_OS_IPK_LIBDIR);
381 if (NULL == path) 379 if (NULL == path)
382 { 380 {
383 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 381 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
384 _ ("Could not determine plugin installation path.\n")); 382 _("Could not determine plugin installation path.\n"));
385 return; 383 return;
386 } 384 }
387 lac.basename = basename; 385 lac.basename = basename;
388 lac.arg = arg; 386 lac.arg = arg;
389 lac.cb = cb; 387 lac.cb = cb;
390 lac.cb_cls = cb_cls; 388 lac.cb_cls = cb_cls;
391 GNUNET_DISK_directory_scan (path, &find_libraries, &lac); 389 GNUNET_DISK_directory_scan(path, &find_libraries, &lac);
392 GNUNET_free (path); 390 GNUNET_free(path);
393} 391}
394 392
395 393