First steps into providing API documentation
[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", filename);
79                                 continue;
80                         }
81
82                         g_free(filename);
83
84                         DBG("%s", g_module_name(module));
85
86                         if (g_module_symbol(module, "connman_plugin_desc",
87                                                 (gpointer) &desc) == FALSE) {
88                                 g_warning("Can't load symbol");
89                                 g_module_close(module);
90                                 continue;
91                         }
92
93                         if (desc == NULL || desc->init == NULL) {
94                                 g_module_close(module);
95                                 continue;
96                         }
97
98                         if (add_plugin(module, desc) == FALSE)
99                                 g_module_close(module);
100                 }
101
102                 g_dir_close(dir);
103         }
104 }
105
106 int __connman_plugin_init(void)
107 {
108         DBG("");
109
110         if (g_module_supported() == FALSE) {
111                 g_warning("Modules not supported: %s", g_module_error());
112                 return FALSE;
113         }
114
115         load_plugins(PLUGINDIR);
116
117         return 0;
118 }
119
120 void __connman_plugin_cleanup(void)
121 {
122         GSList *list;
123
124         DBG("");
125
126         for (list = plugins; list; list = list->next) {
127                 struct connman_plugin *plugin = list->data;
128
129                 DBG("%s", g_module_name(plugin->module));
130
131                 if (plugin->desc->exit)
132                         plugin->desc->exit();
133
134                 g_module_close(plugin->module);
135
136                 g_free(plugin);
137         }
138
139         g_slist_free(plugins);
140 }