diff options
Diffstat (limited to 'src/util/plugin.c')
-rw-r--r-- | src/util/plugin.c | 246 |
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 | */ |
36 | struct PluginList | 36 | struct 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 | */ |
74 | static void | 73 | static void |
75 | plugin_init () | 74 | plugin_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 | */ |
115 | static void | 114 | static void |
116 | plugin_fini () | 115 | plugin_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 | */ |
135 | static GNUNET_PLUGIN_Callback | 134 | static GNUNET_PLUGIN_Callback |
136 | resolve_function (struct PluginList *plug, const char *name) | 135 | resolve_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 | */ |
165 | int | 164 | int |
166 | GNUNET_PLUGIN_test (const char *library_name) | 165 | GNUNET_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 | */ |
206 | void * | 205 | void * |
207 | GNUNET_PLUGIN_load (const char *library_name, void *arg) | 206 | GNUNET_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 | */ |
255 | void * | 254 | void * |
256 | GNUNET_PLUGIN_unload (const char *library_name, void *arg) | 255 | GNUNET_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 | */ |
296 | struct LoadAllContext | 295 | struct 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 | */ |
329 | static int | 327 | static int |
330 | find_libraries (void *cls, const char *filename) | 328 | find_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 | */ |
371 | void | 369 | void |
372 | GNUNET_PLUGIN_load_all (const char *basename, | 370 | GNUNET_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 | ||