decreased plugin load verbosity
[strongswan.git] / src / libstrongswan / plugins / plugin_loader.c
1 /*
2 * Copyright (C) 2007 Martin Willi
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 *
15 * $Id$
16 */
17
18 #include "plugin_loader.h"
19
20 #include <dlfcn.h>
21
22 #include <debug.h>
23 #include <utils/linked_list.h>
24 #include <plugins/plugin.h>
25
26 typedef struct private_plugin_loader_t private_plugin_loader_t;
27
28 /**
29 * private data of plugin_loader
30 */
31 struct private_plugin_loader_t {
32
33 /**
34 * public functions
35 */
36 plugin_loader_t public;
37
38 /**
39 * list of loaded plugins
40 */
41 linked_list_t *plugins;
42 };
43
44 /**
45 * Implementation of plugin_loader_t.load_plugins.
46 */
47 static int load(private_plugin_loader_t *this, char *path, char *prefix)
48 {
49 enumerator_t *enumerator;
50 char *file, *ending, *rel;
51 void *handle;
52 int count = 0;
53
54 enumerator = enumerator_create_directory(path);
55 if (!enumerator)
56 {
57 DBG1("opening plugin directory %s failed", path);
58 return 0;
59 }
60 DBG2("loading plugins from %s", path);
61 while (enumerator->enumerate(enumerator, &rel, &file, NULL))
62 {
63 plugin_t *plugin;
64 plugin_constructor_t constructor;
65
66 ending = file + strlen(file) - 3;
67 if (ending <= file || !streq(ending, ".so"))
68 { /* only process .so libraries */
69 continue;
70 }
71 if (!strneq(prefix, rel, strlen(prefix)))
72 {
73 continue;
74 }
75 handle = dlopen(file, RTLD_LAZY);
76 if (handle == NULL)
77 {
78 DBG1("loading plugin %s failed: %s", rel, dlerror());
79 continue;
80 }
81 constructor = dlsym(handle, "plugin_create");
82 if (constructor == NULL)
83 {
84 DBG1("plugin %s has no plugin_create() function, skipped", rel);
85 dlclose(handle);
86 continue;
87 }
88 plugin = constructor();
89 if (plugin == NULL)
90 {
91 DBG1("plugin %s constructor failed, skipping", rel);
92 dlclose(handle);
93 continue;
94 }
95 DBG2("plugin %s loaded successfully", rel);
96 /* insert in front to destroy them in reverse order */
97 this->plugins->insert_last(this->plugins, plugin);
98 /* we do not store or free dlopen() handles, leak_detective requires
99 * the modules to keep loaded until leak report */
100 count++;
101 }
102 enumerator->destroy(enumerator);
103 return count;
104 }
105
106 /**
107 * Implementation of plugin_loader_t.destroy
108 */
109 static void destroy(private_plugin_loader_t *this)
110 {
111 this->plugins->destroy_offset(this->plugins, offsetof(plugin_t, destroy));
112 free(this);
113 }
114
115 /*
116 * see header file
117 */
118 plugin_loader_t *plugin_loader_create()
119 {
120 private_plugin_loader_t *this = malloc_thing(private_plugin_loader_t);
121
122 this->public.load = (int(*)(plugin_loader_t*, char *path, char *prefix))load;
123 this->public.destroy = (void(*)(plugin_loader_t*))destroy;
124
125 this->plugins = linked_list_create();
126
127 return &this->public;
128 }
129