~vanvugt/ubuntu/xenial/bluez/trunk

« back to all changes in this revision

Viewing changes to obexd/src/plugin.c

  • Committer: Daniel van Vugt
  • Date: 2017-05-24 07:16:52 UTC
  • Revision ID: daniel.van.vugt@canonical.com-20170524071652-8fnev589l3n104m1
Initial import from xenial

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *
 
3
 *  OBEX Server
 
4
 *
 
5
 *  Copyright (C) 2007-2010  Marcel Holtmann <marcel@holtmann.org>
 
6
 *
 
7
 *
 
8
 *  This program is free software; you can redistribute it and/or modify
 
9
 *  it under the terms of the GNU General Public License as published by
 
10
 *  the Free Software Foundation; either version 2 of the License, or
 
11
 *  (at your option) any later version.
 
12
 *
 
13
 *  This program is distributed in the hope that it will be useful,
 
14
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
 *  GNU General Public License for more details.
 
17
 *
 
18
 *  You should have received a copy of the GNU General Public License
 
19
 *  along with this program; if not, write to the Free Software
 
20
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
21
 *
 
22
 */
 
23
 
 
24
#ifdef HAVE_CONFIG_H
 
25
#include <config.h>
 
26
#endif
 
27
 
 
28
#include <errno.h>
 
29
#include <dlfcn.h>
 
30
#include <string.h>
 
31
#include <sys/stat.h>
 
32
 
 
33
#include <glib.h>
 
34
 
 
35
#include "obexd.h"
 
36
#include "plugin.h"
 
37
#include "log.h"
 
38
 
 
39
/*
 
40
 * Plugins that are using libraries with threads and their own mainloop
 
41
 * will crash on exit. This is a bug inside these libraries, but there is
 
42
 * nothing much that can be done about it. One bad example is libebook.
 
43
 */
 
44
#ifdef NEED_THREADS
 
45
#define PLUGINFLAG (RTLD_NOW | RTLD_NODELETE)
 
46
#else
 
47
#define PLUGINFLAG (RTLD_NOW)
 
48
#endif
 
49
 
 
50
static GSList *plugins = NULL;
 
51
 
 
52
struct obex_plugin {
 
53
        void *handle;
 
54
        struct obex_plugin_desc *desc;
 
55
};
 
56
 
 
57
static gboolean add_plugin(void *handle, struct obex_plugin_desc *desc)
 
58
{
 
59
        struct obex_plugin *plugin;
 
60
 
 
61
        if (desc->init == NULL)
 
62
                return FALSE;
 
63
 
 
64
        plugin = g_try_new0(struct obex_plugin, 1);
 
65
        if (plugin == NULL)
 
66
                return FALSE;
 
67
 
 
68
        plugin->handle = handle;
 
69
        plugin->desc = desc;
 
70
 
 
71
        if (desc->init() < 0) {
 
72
                g_free(plugin);
 
73
                return FALSE;
 
74
        }
 
75
 
 
76
        plugins = g_slist_append(plugins, plugin);
 
77
        DBG("Plugin %s loaded", desc->name);
 
78
 
 
79
        return TRUE;
 
80
}
 
81
 
 
82
static gboolean check_plugin(struct obex_plugin_desc *desc,
 
83
                                char **patterns, char **excludes)
 
84
{
 
85
        if (excludes) {
 
86
                for (; *excludes; excludes++)
 
87
                        if (g_pattern_match_simple(*excludes, desc->name))
 
88
                                break;
 
89
                if (*excludes) {
 
90
                        info("Excluding %s", desc->name);
 
91
                        return FALSE;
 
92
                }
 
93
        }
 
94
 
 
95
        if (patterns) {
 
96
                for (; *patterns; patterns++)
 
97
                        if (g_pattern_match_simple(*patterns, desc->name))
 
98
                                break;
 
99
                if (*patterns == NULL) {
 
100
                        info("Ignoring %s", desc->name);
 
101
                        return FALSE;
 
102
                }
 
103
        }
 
104
 
 
105
        return TRUE;
 
106
}
 
107
 
 
108
 
 
109
#include "builtin.h"
 
110
 
 
111
gboolean plugin_init(const char *pattern, const char *exclude)
 
112
{
 
113
        char **patterns = NULL;
 
114
        char **excludes = NULL;
 
115
        GDir *dir;
 
116
        const char *file;
 
117
        unsigned int i;
 
118
 
 
119
        if (strlen(PLUGINDIR) == 0)
 
120
                return FALSE;
 
121
 
 
122
        if (pattern)
 
123
                patterns = g_strsplit_set(pattern, ":, ", -1);
 
124
 
 
125
        if (exclude)
 
126
                excludes = g_strsplit_set(exclude, ":, ", -1);
 
127
 
 
128
        DBG("Loading builtin plugins");
 
129
 
 
130
        for (i = 0; __obex_builtin[i]; i++) {
 
131
                if (check_plugin(__obex_builtin[i],
 
132
                                        patterns, excludes) == FALSE)
 
133
                        continue;
 
134
 
 
135
                add_plugin(NULL,  __obex_builtin[i]);
 
136
        }
 
137
 
 
138
        DBG("Loading plugins %s", PLUGINDIR);
 
139
 
 
140
        dir = g_dir_open(PLUGINDIR, 0, NULL);
 
141
        if (!dir)
 
142
                return FALSE;
 
143
 
 
144
        while ((file = g_dir_read_name(dir)) != NULL) {
 
145
                struct obex_plugin_desc *desc;
 
146
                void *handle;
 
147
                char *filename;
 
148
 
 
149
                if (g_str_has_prefix(file, "lib") == TRUE ||
 
150
                                g_str_has_suffix(file, ".so") == FALSE)
 
151
                        continue;
 
152
 
 
153
                filename = g_build_filename(PLUGINDIR, file, NULL);
 
154
 
 
155
                handle = dlopen(filename, PLUGINFLAG);
 
156
                if (handle == NULL) {
 
157
                        error("Can't load plugin %s: %s", filename,
 
158
                                                                dlerror());
 
159
                        g_free(filename);
 
160
                        continue;
 
161
                }
 
162
 
 
163
                g_free(filename);
 
164
 
 
165
                desc = dlsym(handle, "obex_plugin_desc");
 
166
                if (desc == NULL) {
 
167
                        error("Can't load plugin description: %s", dlerror());
 
168
                        dlclose(handle);
 
169
                        continue;
 
170
                }
 
171
 
 
172
                if (check_plugin(desc, patterns, excludes) == FALSE) {
 
173
                        dlclose(handle);
 
174
                        continue;
 
175
                }
 
176
 
 
177
                if (add_plugin(handle, desc) == FALSE)
 
178
                        dlclose(handle);
 
179
        }
 
180
 
 
181
        g_dir_close(dir);
 
182
        g_strfreev(patterns);
 
183
        g_strfreev(excludes);
 
184
 
 
185
        return TRUE;
 
186
}
 
187
 
 
188
void plugin_cleanup(void)
 
189
{
 
190
        GSList *list;
 
191
 
 
192
        DBG("Cleanup plugins");
 
193
 
 
194
        for (list = plugins; list; list = list->next) {
 
195
                struct obex_plugin *plugin = list->data;
 
196
 
 
197
                if (plugin->desc->exit)
 
198
                        plugin->desc->exit();
 
199
 
 
200
                if (plugin->handle != NULL)
 
201
                        dlclose(plugin->handle);
 
202
 
 
203
                g_free(plugin);
 
204
        }
 
205
 
 
206
        g_slist_free(plugins);
 
207
}