~ubuntu-branches/ubuntu/wily/bluez/wily

« back to all changes in this revision

Viewing changes to src/plugin.c

ImportĀ upstreamĀ versionĀ 4.81

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 *
3
3
 *  BlueZ - Bluetooth protocol stack for Linux
4
4
 *
5
 
 *  Copyright (C) 2004-2009  Marcel Holtmann <marcel@holtmann.org>
 
5
 *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
6
6
 *
7
7
 *
8
8
 *  This program is free software; you can redistribute it and/or modify
35
35
#include <glib.h>
36
36
 
37
37
#include "plugin.h"
38
 
#include "logging.h"
 
38
#include "log.h"
39
39
#include "hcid.h"
40
40
#include "btio.h"
41
41
 
43
43
 
44
44
struct bluetooth_plugin {
45
45
        void *handle;
 
46
        gboolean active;
46
47
        struct bluetooth_plugin_desc *desc;
47
48
};
48
49
 
 
50
static gint compare_priority(gconstpointer a, gconstpointer b)
 
51
{
 
52
        const struct bluetooth_plugin *plugin1 = a;
 
53
        const struct bluetooth_plugin *plugin2 = b;
 
54
 
 
55
        return plugin2->desc->priority - plugin1->desc->priority;
 
56
}
 
57
 
49
58
static gboolean add_plugin(void *handle, struct bluetooth_plugin_desc *desc)
50
59
{
51
60
        struct bluetooth_plugin *plugin;
54
63
                return FALSE;
55
64
 
56
65
        if (g_str_equal(desc->version, VERSION) == FALSE) {
57
 
                DBG("version mismatch for %s", desc->name);
 
66
                error("Version mismatch for %s", desc->name);
58
67
                return FALSE;
59
68
        }
60
69
 
 
70
        DBG("Loading %s plugin", desc->name);
 
71
 
61
72
        plugin = g_try_new0(struct bluetooth_plugin, 1);
62
73
        if (plugin == NULL)
63
74
                return FALSE;
64
75
 
65
76
        plugin->handle = handle;
 
77
        plugin->active = FALSE;
66
78
        plugin->desc = desc;
67
79
 
68
 
        if (desc->init() < 0) {
69
 
                g_free(plugin);
70
 
                return FALSE;
71
 
        }
72
 
 
73
 
        plugins = g_slist_append(plugins, plugin);
74
 
 
75
 
        return TRUE;
76
 
}
77
 
 
78
 
static gboolean is_disabled(const char *name, char **list)
79
 
{
80
 
        int i;
81
 
 
82
 
        for (i = 0; list[i] != NULL; i++) {
83
 
                char *str;
84
 
                gboolean equal;
85
 
 
86
 
                str = g_strdup_printf("%s.so", list[i]);
87
 
 
88
 
                equal = g_str_equal(str, name);
89
 
 
90
 
                g_free(str);
91
 
 
92
 
                if (equal)
93
 
                        return TRUE;
94
 
        }
95
 
 
96
 
        return FALSE;
97
 
}
98
 
 
99
 
gboolean plugin_init(GKeyFile *config)
100
 
{
 
80
        plugins = g_slist_insert_sorted(plugins, plugin, compare_priority);
 
81
 
 
82
        return TRUE;
 
83
}
 
84
 
 
85
static gboolean enable_plugin(const char *name, char **conf_disable,
 
86
                                        char **cli_enable, char **cli_disable)
 
87
{
 
88
        if (conf_disable) {
 
89
                for (; *conf_disable; conf_disable++)
 
90
                        if (g_pattern_match_simple(*conf_disable, name))
 
91
                                break;
 
92
                if (*conf_disable) {
 
93
                        info("Excluding (conf) %s", name);
 
94
                        return FALSE;
 
95
                }
 
96
        }
 
97
 
 
98
        if (cli_disable) {
 
99
                for (; *cli_disable; cli_disable++)
 
100
                        if (g_pattern_match_simple(*cli_disable, name))
 
101
                                break;
 
102
                if (*cli_disable) {
 
103
                        info("Excluding (cli) %s", name);
 
104
                        return FALSE;
 
105
                }
 
106
        }
 
107
 
 
108
        if (cli_enable) {
 
109
                for (; *cli_enable; cli_enable++)
 
110
                        if (g_pattern_match_simple(*cli_enable, name))
 
111
                                break;
 
112
                if (!*cli_enable) {
 
113
                        info("Ignoring (cli) %s", name);
 
114
                        return FALSE;
 
115
                }
 
116
        }
 
117
 
 
118
        return TRUE;
 
119
}
 
120
 
 
121
#include "builtin.h"
 
122
 
 
123
gboolean plugin_init(GKeyFile *config, const char *enable, const char *disable)
 
124
{
 
125
        GSList *list;
101
126
        GDir *dir;
102
127
        const gchar *file;
103
 
        gchar **disabled;
104
 
 
105
 
        if (strlen(PLUGINDIR) == 0)
106
 
                return FALSE;
 
128
        char **conf_disabled, **cli_disabled, **cli_enabled;
 
129
        unsigned int i;
107
130
 
108
131
        /* Make a call to BtIO API so its symbols got resolved before the
109
132
         * plugins are loaded. */
110
133
        bt_io_error_quark();
111
134
 
112
135
        if (config)
113
 
                disabled = g_key_file_get_string_list(config, "General",
 
136
                conf_disabled = g_key_file_get_string_list(config, "General",
114
137
                                                        "DisablePlugins",
115
138
                                                        NULL, NULL);
116
139
        else
117
 
                disabled = NULL;
118
 
 
119
 
        debug("Loading plugins %s", PLUGINDIR);
 
140
                conf_disabled = NULL;
 
141
 
 
142
        if (enable)
 
143
                cli_enabled = g_strsplit_set(enable, ", ", -1);
 
144
        else
 
145
                cli_enabled = NULL;
 
146
 
 
147
        if (disable)
 
148
                cli_disabled = g_strsplit_set(disable, ", ", -1);
 
149
        else
 
150
                cli_disabled = NULL;
 
151
 
 
152
        DBG("Loading builtin plugins");
 
153
 
 
154
        for (i = 0; __bluetooth_builtin[i]; i++) {
 
155
                if (!enable_plugin(__bluetooth_builtin[i]->name, conf_disabled,
 
156
                                                cli_enabled, cli_disabled))
 
157
                        continue;
 
158
 
 
159
                add_plugin(NULL,  __bluetooth_builtin[i]);
 
160
        }
 
161
 
 
162
        if (strlen(PLUGINDIR) == 0)
 
163
                goto start;
 
164
 
 
165
        DBG("Loading plugins %s", PLUGINDIR);
120
166
 
121
167
        dir = g_dir_open(PLUGINDIR, 0, NULL);
122
 
        if (!dir) {
123
 
                g_strfreev(disabled);
124
 
                return FALSE;
125
 
        }
 
168
        if (!dir)
 
169
                goto start;
126
170
 
127
171
        while ((file = g_dir_read_name(dir)) != NULL) {
128
172
                struct bluetooth_plugin_desc *desc;
129
173
                void *handle;
130
174
                gchar *filename;
131
 
                struct stat st;
132
175
 
133
176
                if (g_str_has_prefix(file, "lib") == TRUE ||
134
177
                                g_str_has_suffix(file, ".so") == FALSE)
135
178
                        continue;
136
179
 
137
 
                if (disabled && is_disabled(file, disabled))
138
 
                        continue;
139
 
 
140
180
                filename = g_build_filename(PLUGINDIR, file, NULL);
141
181
 
142
 
                if (stat(filename, &st) < 0) {
143
 
                        error("Can't find plugin %s: %s", filename,
144
 
                                                        strerror(errno));
145
 
                        g_free(filename);
146
 
                        continue;
147
 
                }
148
 
 
149
182
                handle = dlopen(filename, RTLD_NOW);
150
183
                if (handle == NULL) {
151
184
                        error("Can't load plugin %s: %s", filename,
163
196
                        continue;
164
197
                }
165
198
 
 
199
                if (!enable_plugin(desc->name, conf_disabled,
 
200
                                                cli_enabled, cli_disabled)) {
 
201
                        dlclose(handle);
 
202
                        continue;
 
203
                }
 
204
 
166
205
                if (add_plugin(handle, desc) == FALSE)
167
206
                        dlclose(handle);
168
207
        }
169
208
 
170
209
        g_dir_close(dir);
171
210
 
172
 
        g_strfreev(disabled);
 
211
start:
 
212
        for (list = plugins; list; list = list->next) {
 
213
                struct bluetooth_plugin *plugin = list->data;
 
214
 
 
215
                if (plugin->desc->init() < 0) {
 
216
                        error("Failed to init %s plugin", plugin->desc->name);
 
217
                        continue;
 
218
                }
 
219
 
 
220
                plugin->active = TRUE;
 
221
        }
 
222
 
 
223
        g_strfreev(conf_disabled);
 
224
        g_strfreev(cli_enabled);
 
225
        g_strfreev(cli_disabled);
173
226
 
174
227
        return TRUE;
175
228
}
178
231
{
179
232
        GSList *list;
180
233
 
181
 
        debug("Cleanup plugins");
 
234
        DBG("Cleanup plugins");
182
235
 
183
236
        for (list = plugins; list; list = list->next) {
184
237
                struct bluetooth_plugin *plugin = list->data;
185
238
 
186
 
                if (plugin->desc->exit)
 
239
                if (plugin->active == TRUE && plugin->desc->exit)
187
240
                        plugin->desc->exit();
188
241
 
189
 
                dlclose(plugin->handle);
 
242
                if (plugin->handle != NULL)
 
243
                        dlclose(plugin->handle);
190
244
 
191
245
                g_free(plugin);
192
246
        }