12ed917de64f468fd2e14c57381e2609baa50b59
[connman] / src / plugin.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2007-2008  Intel Corporation. All rights reserved.
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License version 2 as
9  *  published by the Free Software Foundation.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <dbus/dbus.h>
27
28 #include <glib.h>
29 #include <gmodule.h>
30
31 #include "connman.h"
32
33 static GSList *plugins = NULL;
34
35 struct connman_plugin {
36         GModule *module;
37         struct connman_plugin_desc *desc;
38 };
39
40 static gboolean add_plugin(GModule *module, struct connman_plugin_desc *desc)
41 {
42         struct connman_plugin *plugin;
43
44         plugin = g_try_new0(struct connman_plugin, 1);
45         if (plugin == NULL)
46                 return FALSE;
47
48         plugin->module = module;
49         plugin->desc = desc;
50
51         plugins = g_slist_append(plugins, plugin);
52
53         desc->init();
54
55         return TRUE;
56 }
57
58 static void load_plugins(const gchar *path)
59 {
60         GDir *dir;
61         const gchar *file;
62         gchar *filename;
63
64         dir = g_dir_open(path, 0, NULL);
65         if (dir != NULL) {
66                 while ((file = g_dir_read_name(dir)) != NULL) {
67                         GModule *module;
68                         struct connman_plugin_desc *desc;
69
70                         if (g_str_has_prefix(file, "lib") == TRUE ||
71                                         g_str_has_suffix(file, ".so") == FALSE)
72                                 continue;
73
74                         filename = g_build_filename(path, file, NULL);
75
76                         module = g_module_open(filename, 0);
77                         if (module == NULL) {
78                                 g_warning("Can't load %s: %s", filename,
79                                                         g_module_error());
80                                 continue;
81                         }
82
83                         g_free(filename);
84
85                         DBG("%s", g_module_name(module));
86
87                         if (g_module_symbol(module, "connman_plugin_desc",
88                                                 (gpointer) &desc) == FALSE) {
89                                 g_warning("Can't load symbol");
90                                 g_module_close(module);
91                                 continue;
92                         }
93
94                         if (desc == NULL || desc->init == NULL) {
95                                 g_module_close(module);
96                                 continue;
97                         }
98
99                         if (add_plugin(module, desc) == FALSE)
100                                 g_module_close(module);
101                 }
102
103                 g_dir_close(dir);
104         }
105 }
106
107 int __connman_plugin_init(void)
108 {
109         DBG("");
110
111         if (g_module_supported() == FALSE) {
112                 g_warning("Modules not supported: %s", g_module_error());
113                 return FALSE;
114         }
115
116         load_plugins(PLUGINDIR);
117
118         return 0;
119 }
120
121 void __connman_plugin_cleanup(void)
122 {
123         GSList *list;
124
125         DBG("");
126
127         for (list = plugins; list; list = list->next) {
128                 struct connman_plugin *plugin = list->data;
129
130                 DBG("%s", g_module_name(plugin->module));
131
132                 if (plugin->desc->exit)
133                         plugin->desc->exit();
134
135                 g_module_close(plugin->module);
136
137                 g_free(plugin);
138         }
139
140         g_slist_free(plugins);
141 }