2 * Copyright (C) 2007 Martin Willi
3 * Hochschule fuer Technik Rapperswil
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>.
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
17 #include "plugin_loader.h"
26 #include <integrity_checker.h>
27 #include <utils/linked_list.h>
28 #include <plugins/plugin.h>
30 typedef struct private_plugin_loader_t private_plugin_loader_t
;
33 * private data of plugin_loader
35 struct private_plugin_loader_t
{
40 plugin_loader_t
public;
43 * list of loaded plugins
45 linked_list_t
*plugins
;
48 * names of loaded plugins
54 * load a single plugin
56 static plugin_t
* load_plugin(private_plugin_loader_t
*this,
57 char *path
, char *name
)
62 plugin_constructor_t constructor
;
64 snprintf(file
, sizeof(file
), "%s/libstrongswan-%s.so", path
, name
);
67 !lib
->integrity
->check_file(lib
->integrity
, name
, file
))
69 DBG1("file integrity test of plugin '%s' failed", name
);
72 handle
= dlopen(file
, RTLD_LAZY
);
75 DBG1("loading plugin '%s' failed: %s", name
, dlerror());
78 constructor
= dlsym(handle
, "plugin_create");
79 if (constructor
== NULL
)
81 DBG1("loading plugin '%s' failed: no plugin_create() function", name
);
86 !lib
->integrity
->check_segment(lib
->integrity
, name
, constructor
))
88 DBG1("segment integrity test of plugin '%s' failed", name
);
92 plugin
= constructor();
95 DBG1("loading plugin '%s' failed: plugin_create() returned NULL", name
);
99 DBG2("plugin '%s' loaded successfully", name
);
101 /* we do not store or free dlopen() handles, leak_detective requires
102 * the modules to keep loaded until leak report */
107 * Implementation of plugin_loader_t.load_plugins.
109 static int load(private_plugin_loader_t
*this, char *path
, char *list
)
112 enumerator_t
*enumerator
;
116 enumerator
= enumerator_create_token(list
, " ", " ");
117 while (enumerator
->enumerate(enumerator
, &token
))
119 plugin
= load_plugin(this, path
, token
);
121 { /* insert in front to destroy them in reverse order */
122 this->plugins
->insert_last(this->plugins
, plugin
);
123 this->names
->insert_last(this->names
, strdup(token
));
127 enumerator
->destroy(enumerator
);
132 * Implementation of plugin_loader_t.unload
134 static void unload(private_plugin_loader_t
*this)
139 while (this->plugins
->remove_first(this->plugins
,
140 (void**)&plugin
) == SUCCESS
)
142 plugin
->destroy(plugin
);
144 while (this->names
->remove_first(this->names
, (void**)&name
) == SUCCESS
)
151 * Implementation of plugin_loader_t.create_plugin_enumerator
153 static enumerator_t
* create_plugin_enumerator(private_plugin_loader_t
*this)
155 return this->names
->create_enumerator(this->names
);
159 * Implementation of plugin_loader_t.destroy
161 static void destroy(private_plugin_loader_t
*this)
163 this->plugins
->destroy_offset(this->plugins
, offsetof(plugin_t
, destroy
));
164 this->names
->destroy_function(this->names
, free
);
171 plugin_loader_t
*plugin_loader_create()
173 private_plugin_loader_t
*this = malloc_thing(private_plugin_loader_t
);
175 this->public.load
= (int(*)(plugin_loader_t
*, char *path
, char *prefix
))load
;
176 this->public.unload
= (void(*)(plugin_loader_t
*))unload
;
177 this->public.create_plugin_enumerator
= (enumerator_t
*(*)(plugin_loader_t
*))create_plugin_enumerator
;
178 this->public.destroy
= (void(*)(plugin_loader_t
*))destroy
;
180 this->plugins
= linked_list_create();
181 this->names
= linked_list_create();
183 return &this->public;