Mercurial > pidgin
annotate src/plugin.c @ 6695:0c5637b5462e
[gaim-migrate @ 7221]
This is contact support. Really.
It has a few bugs left in it, like sorting not working, and stuff like that,
but it's pretty solid for the most part.
I'm not in the mood to do a whole lot of typing, so just use and enjoy.
committer: Tailor Script <tailor@pidgin.im>
author | Nathan Walp <nwalp@pidgin.im> |
---|---|
date | Tue, 02 Sep 2003 03:41:10 +0000 |
parents | 1b91cb6be4c3 |
children | 7dba3e17cb21 |
rev | line source |
---|---|
5205 | 1 /* |
2 * gaim | |
3 * | |
4 * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net> | |
5 * | |
6 * This program is free software; you can redistribute it and/or modify | |
7 * it under the terms of the GNU General Public License as published by | |
8 * the Free Software Foundation; either version 2 of the License, or | |
9 * (at your option) any later version. | |
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
19 */ | |
20 | |
21 /* | |
22 * ---------------- | |
23 * The Plug-in plugin | |
24 * | |
25 * Plugin support is currently being maintained by Mike Saraf | |
26 * msaraf@dwc.edu | |
27 * | |
28 * Well, I didn't see any work done on it for a while, so I'm going to try | |
29 * my hand at it. - Eric warmenhoven@yahoo.com | |
30 * | |
31 * Mike is my roomate. I can assure you that he's lazy :-P | |
32 * -- Rob rob@marko.net | |
33 * | |
34 * Yeah, well now I'm re-writing a good portion of it! The perl stuff was | |
35 * a hack. Tsk tsk! -- Christian <chipx86@gnupdate.org> | |
36 */ | |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5840
diff
changeset
|
37 #include "internal.h" |
5205 | 38 |
5638
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5573
diff
changeset
|
39 #include "accountopt.h" |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5840
diff
changeset
|
40 #include "debug.h" |
5436
ad445074d239
[gaim-migrate @ 5818]
Christian Hammond <chipx86@chipx86.com>
parents:
5357
diff
changeset
|
41 #include "notify.h" |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5840
diff
changeset
|
42 #include "prefs.h" |
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5840
diff
changeset
|
43 #include "prpl.h" |
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5840
diff
changeset
|
44 #include "request.h" |
6485
70d5122bc3ff
[gaim-migrate @ 6999]
Christian Hammond <chipx86@chipx86.com>
parents:
6432
diff
changeset
|
45 #include "signals.h" |
5205 | 46 |
47 #ifdef _WIN32 | |
48 # define PLUGIN_EXT ".dll" | |
49 #else | |
6639 | 50 #ifdef __hpux |
51 # define PLUGIN_EXT ".sl" | |
52 #else | |
5205 | 53 # define PLUGIN_EXT ".so" |
54 #endif | |
6639 | 55 #endif |
5205 | 56 |
57 static GList *loaded_plugins = NULL; | |
58 static GList *plugins = NULL; | |
59 static GList *plugin_loaders = NULL; | |
5573
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
60 static GList *protocol_plugins = NULL; |
5205 | 61 |
62 static size_t search_path_count = 0; | |
63 static char **search_paths = NULL; | |
64 | |
65 static void (*probe_cb)(void *) = NULL; | |
66 static void *probe_cb_data = NULL; | |
67 static void (*load_cb)(GaimPlugin *, void *) = NULL; | |
68 static void *load_cb_data = NULL; | |
69 static void (*unload_cb)(GaimPlugin *, void *) = NULL; | |
70 static void *unload_cb_data = NULL; | |
71 | |
72 #ifdef GAIM_PLUGINS | |
73 static int | |
74 is_so_file(const char *filename, const char *ext) | |
75 { | |
76 int len, extlen; | |
77 | |
78 if (filename == NULL || *filename == '\0' || ext == NULL) | |
79 return 0; | |
80 | |
81 extlen = strlen(ext); | |
82 len = strlen(filename) - extlen; | |
83 | |
84 if (len < 0) | |
85 return 0; | |
86 | |
87 return (!strncmp(filename + len, ext, extlen)); | |
88 } | |
89 | |
90 static gboolean | |
5794
5e93fc46d1af
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5646
diff
changeset
|
91 loader_supports_file(GaimPlugin *loader, const char *filename) |
5205 | 92 { |
6432 | 93 GList *exts; |
5205 | 94 |
6432 | 95 for (exts = GAIM_PLUGIN_LOADER_INFO(loader)->exts; exts != NULL; exts = exts->next) { |
96 if (is_so_file(filename, (char *)exts->data)) { | |
97 return TRUE; | |
5205 | 98 } |
99 } | |
100 | |
101 return FALSE; | |
102 } | |
103 | |
104 static GaimPlugin * | |
5794
5e93fc46d1af
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5646
diff
changeset
|
105 find_loader_for_plugin(const GaimPlugin *plugin) |
5205 | 106 { |
107 GaimPlugin *loader; | |
108 GList *l; | |
109 | |
110 if (plugin->path == NULL) | |
111 return NULL; | |
112 | |
113 for (l = gaim_plugins_get_loaded(); l != NULL; l = l->next) { | |
114 loader = l->data; | |
115 | |
116 if (loader->info->type == GAIM_PLUGIN_LOADER && | |
5794
5e93fc46d1af
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5646
diff
changeset
|
117 loader_supports_file(loader, plugin->path)) { |
5205 | 118 |
119 return loader; | |
120 } | |
121 | |
122 loader = NULL; | |
123 } | |
124 | |
125 return NULL; | |
126 } | |
127 | |
5449 | 128 #endif /* GAIM_PLUGINS */ |
129 | |
5205 | 130 static gint |
131 compare_prpl(GaimPlugin *a, GaimPlugin *b) | |
132 { | |
133 /* neg if a before b, 0 if equal, pos if a after b */ | |
134 return ((GAIM_IS_PROTOCOL_PLUGIN(a) | |
135 ? GAIM_PLUGIN_PROTOCOL_INFO(a)->protocol : -1) - | |
136 ((GAIM_IS_PROTOCOL_PLUGIN(b) | |
137 ? GAIM_PLUGIN_PROTOCOL_INFO(b)->protocol : -1))); | |
138 } | |
139 | |
140 GaimPlugin * | |
141 gaim_plugin_new(gboolean native, const char *path) | |
142 { | |
143 GaimPlugin *plugin; | |
144 | |
145 plugin = g_new0(GaimPlugin, 1); | |
146 | |
147 plugin->native_plugin = native; | |
148 plugin->path = (path == NULL ? NULL : g_strdup(path)); | |
149 | |
150 return plugin; | |
151 } | |
152 | |
153 GaimPlugin * | |
154 gaim_plugin_probe(const char *filename) | |
155 { | |
156 #ifdef GAIM_PLUGINS | |
157 GaimPlugin *plugin = NULL; | |
158 GaimPlugin *loader; | |
159 gboolean (*gaim_init_plugin)(GaimPlugin *); | |
160 | |
161 g_return_val_if_fail(filename != NULL, NULL); | |
162 | |
5973 | 163 if (!g_file_test(filename, G_FILE_TEST_EXISTS)) |
164 return NULL; | |
165 | |
5205 | 166 plugin = gaim_plugins_find_with_filename(filename); |
167 | |
168 if (plugin != NULL) | |
169 return plugin; | |
170 | |
171 plugin = gaim_plugin_new(is_so_file(filename, PLUGIN_EXT), filename); | |
172 | |
173 if (plugin->native_plugin) { | |
5450 | 174 const char *error; |
5205 | 175 plugin->handle = g_module_open(filename, 0); |
176 | |
177 if (plugin->handle == NULL) { | |
5443 | 178 error = g_module_error(); |
5269
cd7e4ba049f9
[gaim-migrate @ 5641]
Christian Hammond <chipx86@chipx86.com>
parents:
5268
diff
changeset
|
179 gaim_debug(GAIM_DEBUG_ERROR, "plugins", "%s is unloadable: %s\n", |
5443 | 180 plugin->path, error ? error : "Unknown error."); |
5205 | 181 |
5269
cd7e4ba049f9
[gaim-migrate @ 5641]
Christian Hammond <chipx86@chipx86.com>
parents:
5268
diff
changeset
|
182 gaim_plugin_destroy(plugin); |
cd7e4ba049f9
[gaim-migrate @ 5641]
Christian Hammond <chipx86@chipx86.com>
parents:
5268
diff
changeset
|
183 |
cd7e4ba049f9
[gaim-migrate @ 5641]
Christian Hammond <chipx86@chipx86.com>
parents:
5268
diff
changeset
|
184 return NULL; |
5205 | 185 } |
186 | |
187 if (!g_module_symbol(plugin->handle, "gaim_init_plugin", | |
188 (gpointer *)&gaim_init_plugin)) { | |
189 g_module_close(plugin->handle); | |
190 plugin->handle = NULL; | |
191 | |
5443 | 192 error = g_module_error(); |
5211
0241d6b6702d
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
193 gaim_debug(GAIM_DEBUG_ERROR, "plugins", "%s is unloadable: %s\n", |
5443 | 194 plugin->path, error ? error : "Unknown error."); |
5205 | 195 |
196 gaim_plugin_destroy(plugin); | |
197 | |
198 return NULL; | |
199 } | |
200 } | |
201 else { | |
5794
5e93fc46d1af
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5646
diff
changeset
|
202 loader = find_loader_for_plugin(plugin); |
5205 | 203 |
204 if (loader == NULL) { | |
205 gaim_plugin_destroy(plugin); | |
206 | |
207 return NULL; | |
208 } | |
209 | |
210 gaim_init_plugin = GAIM_PLUGIN_LOADER_INFO(loader)->probe; | |
211 } | |
212 | |
213 plugin->error = NULL; | |
214 | |
215 if (!gaim_init_plugin(plugin) || plugin->info == NULL) { | |
216 gaim_plugin_destroy(plugin); | |
217 | |
218 return NULL; | |
219 } | |
220 | |
221 return plugin; | |
222 #else | |
223 return NULL; | |
224 #endif /* !GAIM_PLUGINS */ | |
225 } | |
226 | |
227 gboolean | |
228 gaim_plugin_load(GaimPlugin *plugin) | |
229 { | |
230 #ifdef GAIM_PLUGINS | |
6486
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
231 GList *dep_list = NULL; |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
232 GList *l; |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
233 |
5205 | 234 g_return_val_if_fail(plugin != NULL, FALSE); |
5270
d1fe8e320dab
[gaim-migrate @ 5642]
Christian Hammond <chipx86@chipx86.com>
parents:
5269
diff
changeset
|
235 g_return_val_if_fail(plugin->error == NULL, FALSE); |
5205 | 236 |
237 if (gaim_plugin_is_loaded(plugin)) | |
238 return TRUE; | |
239 | |
6486
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
240 /* |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
241 * Go through the list of the plugin's dependencies. |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
242 * |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
243 * First pass: Make sure all the plugins needed are probed. |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
244 */ |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
245 for (l = plugin->info->dependencies; l != NULL; l = l->next) |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
246 { |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
247 const char *dep_name = (const char *)l->data; |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
248 GaimPlugin *dep_plugin; |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
249 |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
250 dep_plugin = gaim_plugins_find_with_id(dep_name); |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
251 |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
252 if (dep_plugin == NULL) |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
253 { |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
254 char buf[BUFSIZ]; |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
255 |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
256 g_snprintf(buf, sizeof(buf), |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
257 _("The required plugin %s was not found. " |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
258 "Please install this plugin and try again."), |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
259 dep_name); |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
260 |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
261 gaim_notify_error(NULL, NULL, |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
262 _("Gaim was unable to load your plugin."), |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
263 buf); |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
264 |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
265 if (dep_list != NULL) |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
266 g_list_free(dep_list); |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
267 |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
268 return FALSE; |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
269 } |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
270 |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
271 dep_list = g_list_append(dep_list, dep_plugin); |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
272 } |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
273 |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
274 /* Second pass: load all the required plugins. */ |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
275 for (l = dep_list; l != NULL; l = l->next) |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
276 { |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
277 GaimPlugin *dep_plugin = (GaimPlugin *)l->data; |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
278 |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
279 if (!gaim_plugin_is_loaded(dep_plugin)) |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
280 { |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
281 if (!gaim_plugin_load(dep_plugin)) |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
282 { |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
283 char buf[BUFSIZ]; |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
284 |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
285 g_snprintf(buf, sizeof(buf), |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
286 _("The required plugin %s was unable to load."), |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
287 plugin->info->name); |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
288 |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
289 gaim_notify_error(NULL, NULL, |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
290 _("Gaim was unable to load your plugin."), |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
291 buf); |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
292 |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
293 if (dep_list != NULL) |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
294 g_list_free(dep_list); |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
295 |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
296 return FALSE; |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
297 } |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
298 } |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
299 } |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
300 |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
301 if (dep_list != NULL) |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
302 g_list_free(dep_list); |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
303 |
5205 | 304 if (plugin->native_plugin) { |
5357
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
305 if (plugin->info != NULL) { |
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
306 if (plugin->info->load != NULL) |
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
307 plugin->info->load(plugin); |
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
308 } |
5205 | 309 } |
310 else { | |
311 GaimPlugin *loader; | |
312 GaimPluginLoaderInfo *loader_info; | |
313 | |
5794
5e93fc46d1af
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5646
diff
changeset
|
314 loader = find_loader_for_plugin(plugin); |
5205 | 315 |
316 if (loader == NULL) | |
317 return FALSE; | |
318 | |
319 loader_info = GAIM_PLUGIN_LOADER_INFO(loader); | |
320 | |
321 if (loader_info->load != NULL) | |
322 loader_info->load(plugin); | |
323 } | |
324 | |
325 loaded_plugins = g_list_append(loaded_plugins, plugin); | |
326 | |
327 plugin->loaded = TRUE; | |
328 | |
329 /* TODO */ | |
330 if (load_cb != NULL) | |
331 load_cb(plugin, load_cb_data); | |
332 | |
333 return TRUE; | |
334 | |
335 #else | |
5449 | 336 return TRUE; |
5205 | 337 #endif /* !GAIM_PLUGINS */ |
338 } | |
339 | |
340 gboolean | |
341 gaim_plugin_unload(GaimPlugin *plugin) | |
342 { | |
343 #ifdef GAIM_PLUGINS | |
344 g_return_val_if_fail(plugin != NULL, FALSE); | |
345 | |
346 loaded_plugins = g_list_remove(loaded_plugins, plugin); | |
347 | |
348 g_return_val_if_fail(gaim_plugin_is_loaded(plugin), FALSE); | |
349 | |
5211
0241d6b6702d
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
350 gaim_debug(GAIM_DEBUG_INFO, "plugins", "Unloading plugin %s\n", |
0241d6b6702d
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
351 plugin->info->name); |
5205 | 352 |
353 /* cancel any pending dialogs the plugin has */ | |
5498
cce2d7868c78
[gaim-migrate @ 5894]
Christian Hammond <chipx86@chipx86.com>
parents:
5450
diff
changeset
|
354 gaim_request_close_with_handle(plugin); |
cce2d7868c78
[gaim-migrate @ 5894]
Christian Hammond <chipx86@chipx86.com>
parents:
5450
diff
changeset
|
355 gaim_notify_close_with_handle(plugin); |
5205 | 356 |
357 plugin->loaded = FALSE; | |
358 | |
359 if (plugin->native_plugin) { | |
360 if (plugin->info->unload != NULL) | |
361 plugin->info->unload(plugin); | |
362 | |
363 if (plugin->info->type == GAIM_PLUGIN_PROTOCOL) { | |
364 GaimPluginProtocolInfo *prpl_info; | |
365 GList *l; | |
366 | |
367 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(plugin); | |
368 | |
5638
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5573
diff
changeset
|
369 for (l = prpl_info->user_splits; l != NULL; l = l->next) |
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5573
diff
changeset
|
370 gaim_account_user_split_destroy(l->data); |
5205 | 371 |
5638
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5573
diff
changeset
|
372 for (l = prpl_info->protocol_options; l != NULL; l = l->next) |
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5573
diff
changeset
|
373 gaim_account_option_destroy(l->data); |
5205 | 374 |
5646
48c63ee49961
[gaim-migrate @ 6060]
Christian Hammond <chipx86@chipx86.com>
parents:
5638
diff
changeset
|
375 if (prpl_info->user_splits != NULL) |
48c63ee49961
[gaim-migrate @ 6060]
Christian Hammond <chipx86@chipx86.com>
parents:
5638
diff
changeset
|
376 g_list_free(prpl_info->user_splits); |
48c63ee49961
[gaim-migrate @ 6060]
Christian Hammond <chipx86@chipx86.com>
parents:
5638
diff
changeset
|
377 |
48c63ee49961
[gaim-migrate @ 6060]
Christian Hammond <chipx86@chipx86.com>
parents:
5638
diff
changeset
|
378 if (prpl_info->protocol_options != NULL) |
48c63ee49961
[gaim-migrate @ 6060]
Christian Hammond <chipx86@chipx86.com>
parents:
5638
diff
changeset
|
379 g_list_free(prpl_info->protocol_options); |
5205 | 380 } |
381 } | |
382 else { | |
383 GaimPlugin *loader; | |
384 GaimPluginLoaderInfo *loader_info; | |
385 | |
5794
5e93fc46d1af
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5646
diff
changeset
|
386 loader = find_loader_for_plugin(plugin); |
5205 | 387 |
388 if (loader == NULL) | |
389 return FALSE; | |
390 | |
391 loader_info = GAIM_PLUGIN_LOADER_INFO(loader); | |
392 | |
393 if (loader_info->load != NULL) | |
394 loader_info->unload(plugin); | |
395 } | |
396 | |
397 gaim_signals_disconnect_by_handle(plugin); | |
398 | |
399 /* TODO */ | |
400 if (unload_cb != NULL) | |
401 unload_cb(plugin, unload_cb_data); | |
402 | |
403 return TRUE; | |
5449 | 404 #else |
405 return TRUE; | |
5205 | 406 #endif /* GAIM_PLUGINS */ |
407 } | |
408 | |
409 gboolean | |
410 gaim_plugin_reload(GaimPlugin *plugin) | |
411 { | |
412 #ifdef GAIM_PLUGINS | |
413 g_return_val_if_fail(plugin != NULL, FALSE); | |
414 g_return_val_if_fail(gaim_plugin_is_loaded(plugin), FALSE); | |
415 | |
416 if (!gaim_plugin_unload(plugin)) | |
417 return FALSE; | |
418 | |
419 if (!gaim_plugin_load(plugin)) | |
420 return FALSE; | |
421 | |
422 return TRUE; | |
423 #else | |
5449 | 424 return TRUE; |
5205 | 425 #endif /* !GAIM_PLUGINS */ |
426 } | |
427 | |
428 void | |
429 gaim_plugin_destroy(GaimPlugin *plugin) | |
430 { | |
5449 | 431 #ifdef GAIM_PLUGINS |
5205 | 432 g_return_if_fail(plugin != NULL); |
433 | |
434 if (gaim_plugin_is_loaded(plugin)) | |
435 gaim_plugin_unload(plugin); | |
436 | |
437 plugins = g_list_remove(plugins, plugin); | |
438 | |
5243
f6e0c689a88b
[gaim-migrate @ 5614]
Christian Hammond <chipx86@chipx86.com>
parents:
5242
diff
changeset
|
439 if (plugin->info != NULL && plugin->info->dependencies != NULL) |
f6e0c689a88b
[gaim-migrate @ 5614]
Christian Hammond <chipx86@chipx86.com>
parents:
5242
diff
changeset
|
440 g_list_free(plugin->info->dependencies); |
5205 | 441 |
442 if (plugin->native_plugin) { | |
443 | |
444 if (plugin->info != NULL && plugin->info->type == GAIM_PLUGIN_LOADER) { | |
445 GList *exts, *l, *next_l; | |
446 GaimPlugin *p2; | |
447 | |
448 for (exts = GAIM_PLUGIN_LOADER_INFO(plugin)->exts; | |
449 exts != NULL; | |
450 exts = exts->next) { | |
451 | |
452 for (l = gaim_plugins_get_all(); l != NULL; l = next_l) { | |
453 next_l = l->next; | |
454 | |
455 p2 = l->data; | |
456 | |
457 if (p2->path != NULL && is_so_file(p2->path, exts->data)) | |
458 gaim_plugin_destroy(p2); | |
459 } | |
460 } | |
461 | |
462 g_list_free(GAIM_PLUGIN_LOADER_INFO(plugin)->exts); | |
463 | |
464 plugin_loaders = g_list_remove(plugin_loaders, plugin); | |
465 } | |
466 | |
467 if (plugin->info != NULL && plugin->info->destroy != NULL) | |
468 plugin->info->destroy(plugin); | |
469 | |
470 if (plugin->handle != NULL) | |
471 g_module_close(plugin->handle); | |
472 } | |
473 else { | |
474 GaimPlugin *loader; | |
475 GaimPluginLoaderInfo *loader_info; | |
476 | |
5794
5e93fc46d1af
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5646
diff
changeset
|
477 loader = find_loader_for_plugin(plugin); |
5205 | 478 |
5941
a3e60ff95b7d
[gaim-migrate @ 6381]
Christian Hammond <chipx86@chipx86.com>
parents:
5872
diff
changeset
|
479 if (loader != NULL) { |
a3e60ff95b7d
[gaim-migrate @ 6381]
Christian Hammond <chipx86@chipx86.com>
parents:
5872
diff
changeset
|
480 loader_info = GAIM_PLUGIN_LOADER_INFO(loader); |
5205 | 481 |
5941
a3e60ff95b7d
[gaim-migrate @ 6381]
Christian Hammond <chipx86@chipx86.com>
parents:
5872
diff
changeset
|
482 if (loader_info->destroy != NULL) |
a3e60ff95b7d
[gaim-migrate @ 6381]
Christian Hammond <chipx86@chipx86.com>
parents:
5872
diff
changeset
|
483 loader_info->destroy(plugin); |
a3e60ff95b7d
[gaim-migrate @ 6381]
Christian Hammond <chipx86@chipx86.com>
parents:
5872
diff
changeset
|
484 } |
5205 | 485 } |
486 | |
487 if (plugin->path != NULL) g_free(plugin->path); | |
488 if (plugin->error != NULL) g_free(plugin->error); | |
489 | |
490 g_free(plugin); | |
5449 | 491 #endif /* !GAIM_PLUGINS */ |
5205 | 492 } |
493 | |
494 gboolean | |
495 gaim_plugin_is_loaded(const GaimPlugin *plugin) | |
496 { | |
497 g_return_val_if_fail(plugin != NULL, FALSE); | |
498 | |
499 return plugin->loaded; | |
500 } | |
501 | |
502 void | |
503 gaim_plugins_set_search_paths(size_t count, char **paths) | |
504 { | |
505 size_t s; | |
506 | |
507 g_return_if_fail(count > 0); | |
508 g_return_if_fail(paths != NULL); | |
509 | |
510 if (search_paths != NULL) { | |
511 for (s = 0; s < search_path_count; s++) | |
512 g_free(search_paths[s]); | |
513 | |
514 g_free(search_paths); | |
515 } | |
516 | |
517 search_paths = g_new0(char *, count); | |
518 | |
519 for (s = 0; s < count; s++) { | |
520 if (paths[s] == NULL) | |
521 search_paths[s] = NULL; | |
522 else | |
523 search_paths[s] = g_strdup(paths[s]); | |
524 } | |
525 | |
526 search_path_count = count; | |
527 } | |
528 | |
529 void | |
530 gaim_plugins_unload_all(void) | |
531 { | |
532 #ifdef GAIM_PLUGINS | |
533 | |
534 while (loaded_plugins != NULL) | |
535 gaim_plugin_unload(loaded_plugins->data); | |
536 | |
537 #endif /* GAIM_PLUGINS */ | |
538 } | |
539 | |
540 void | |
5242
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
541 gaim_plugins_destroy_all(void) |
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
542 { |
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
543 #ifdef GAIM_PLUGINS |
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
544 |
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
545 while (plugins != NULL) |
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
546 gaim_plugin_destroy(plugins->data); |
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
547 |
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
548 #endif /* GAIM_PLUGINS */ |
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
549 } |
5838 | 550 |
551 void | |
5949
90d0849abd3c
[gaim-migrate @ 6393]
Christian Hammond <chipx86@chipx86.com>
parents:
5941
diff
changeset
|
552 gaim_plugins_load_saved(const char *key) |
5838 | 553 { |
554 #ifdef GAIM_PLUGINS | |
5949
90d0849abd3c
[gaim-migrate @ 6393]
Christian Hammond <chipx86@chipx86.com>
parents:
5941
diff
changeset
|
555 GList *f, *files; |
90d0849abd3c
[gaim-migrate @ 6393]
Christian Hammond <chipx86@chipx86.com>
parents:
5941
diff
changeset
|
556 |
90d0849abd3c
[gaim-migrate @ 6393]
Christian Hammond <chipx86@chipx86.com>
parents:
5941
diff
changeset
|
557 g_return_if_fail(key != NULL); |
5838 | 558 |
5949
90d0849abd3c
[gaim-migrate @ 6393]
Christian Hammond <chipx86@chipx86.com>
parents:
5941
diff
changeset
|
559 files = gaim_prefs_get_string_list(key); |
90d0849abd3c
[gaim-migrate @ 6393]
Christian Hammond <chipx86@chipx86.com>
parents:
5941
diff
changeset
|
560 |
90d0849abd3c
[gaim-migrate @ 6393]
Christian Hammond <chipx86@chipx86.com>
parents:
5941
diff
changeset
|
561 for (f = files; f; f = f->next) { |
5838 | 562 gaim_plugin_load(gaim_plugin_probe(f->data)); |
563 g_free(f->data); | |
564 } | |
565 | |
566 g_list_free(files); | |
567 #endif /* GAIM_PLUGINS */ | |
568 } | |
569 | |
570 | |
5242
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
571 void |
5205 | 572 gaim_plugins_probe(const char *ext) |
573 { | |
574 #ifdef GAIM_PLUGINS | |
575 GDir *dir; | |
576 const gchar *file; | |
577 gchar *path; | |
578 GaimPlugin *plugin; | |
579 size_t i; | |
580 | |
581 if (!g_module_supported()) | |
582 return; | |
583 | |
584 for (i = 0; i < search_path_count; i++) { | |
585 if (search_paths[i] == NULL) | |
586 continue; | |
587 | |
588 dir = g_dir_open(search_paths[i], 0, NULL); | |
589 | |
590 if (dir != NULL) { | |
591 while ((file = g_dir_read_name(dir)) != NULL) { | |
592 path = g_build_filename(search_paths[i], file, NULL); | |
593 | |
594 if (ext == NULL || is_so_file(file, ext)) | |
595 plugin = gaim_plugin_probe(path); | |
596 | |
597 g_free(path); | |
598 } | |
599 | |
600 g_dir_close(dir); | |
601 } | |
602 } | |
603 | |
604 if (probe_cb != NULL) | |
605 probe_cb(probe_cb_data); | |
606 | |
607 #endif /* GAIM_PLUGINS */ | |
608 } | |
609 | |
610 gboolean | |
611 gaim_plugin_register(GaimPlugin *plugin) | |
612 { | |
613 g_return_val_if_fail(plugin != NULL, FALSE); | |
614 | |
615 if (g_list_find(plugins, plugin)) | |
616 return TRUE; | |
617 | |
618 /* Special exception for loader plugins. We want them loaded NOW! */ | |
619 if (plugin->info->type == GAIM_PLUGIN_LOADER) { | |
620 GList *exts; | |
621 | |
622 /* We'll just load this right now. */ | |
623 if (!gaim_plugin_load(plugin)) { | |
624 | |
625 gaim_plugin_destroy(plugin); | |
626 | |
627 return FALSE; | |
628 } | |
629 | |
630 plugin_loaders = g_list_append(plugin_loaders, plugin); | |
631 | |
632 for (exts = GAIM_PLUGIN_LOADER_INFO(plugin)->exts; | |
633 exts != NULL; | |
634 exts = exts->next) { | |
635 | |
636 gaim_plugins_probe(exts->data); | |
637 } | |
638 } | |
639 else if (plugin->info->type == GAIM_PLUGIN_PROTOCOL) { | |
640 | |
641 /* We'll just load this right now. */ | |
642 if (!gaim_plugin_load(plugin)) { | |
643 | |
644 gaim_plugin_destroy(plugin); | |
645 | |
646 return FALSE; | |
647 } | |
648 | |
649 if (GAIM_PLUGIN_PROTOCOL_INFO(plugin)->protocol == GAIM_PROTO_ICQ || | |
650 gaim_find_prpl(GAIM_PLUGIN_PROTOCOL_INFO(plugin)->protocol)) { | |
651 | |
652 /* Nothing to see here--move along, move along */ | |
653 gaim_plugin_destroy(plugin); | |
654 | |
655 return FALSE; | |
656 } | |
657 | |
5573
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
658 protocol_plugins = g_list_insert_sorted(protocol_plugins, plugin, |
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
659 (GCompareFunc)compare_prpl); |
5205 | 660 } |
661 | |
662 plugins = g_list_append(plugins, plugin); | |
663 | |
664 return TRUE; | |
665 } | |
666 | |
667 gboolean | |
668 gaim_plugins_enabled(void) | |
669 { | |
670 #ifdef GAIM_PLUGINS | |
671 return TRUE; | |
672 #else | |
673 return FALSE; | |
674 #endif | |
675 } | |
676 | |
677 void | |
678 gaim_plugins_register_probe_notify_cb(void (*func)(void *), void *data) | |
679 { | |
680 /* TODO */ | |
681 probe_cb = func; | |
682 probe_cb_data = data; | |
683 } | |
684 | |
685 void | |
686 gaim_plugins_unregister_probe_notify_cb(void (*func)(void *)) | |
687 { | |
688 /* TODO */ | |
689 probe_cb = NULL; | |
690 probe_cb_data = NULL; | |
691 } | |
692 | |
693 void | |
694 gaim_plugins_register_load_notify_cb(void (*func)(GaimPlugin *, void *), | |
695 void *data) | |
696 { | |
697 /* TODO */ | |
698 load_cb = func; | |
699 load_cb_data = data; | |
700 } | |
701 | |
702 void | |
703 gaim_plugins_unregister_load_notify_cb(void (*func)(GaimPlugin *, void *)) | |
704 { | |
705 /* TODO */ | |
706 load_cb = NULL; | |
707 load_cb_data = NULL; | |
708 } | |
709 | |
710 void | |
711 gaim_plugins_register_unload_notify_cb(void (*func)(GaimPlugin *, void *), | |
712 void *data) | |
713 { | |
714 /* TODO */ | |
715 unload_cb = func; | |
716 unload_cb_data = data; | |
717 } | |
718 | |
719 void | |
720 gaim_plugins_unregister_unload_notify_cb(void (*func)(GaimPlugin *, void *)) | |
721 { | |
722 /* TODO */ | |
723 unload_cb = NULL; | |
724 unload_cb_data = NULL; | |
725 } | |
726 | |
727 GaimPlugin * | |
728 gaim_plugins_find_with_name(const char *name) | |
729 { | |
730 GaimPlugin *plugin; | |
731 GList *l; | |
732 | |
733 for (l = plugins; l != NULL; l = l->next) { | |
734 plugin = l->data; | |
735 | |
736 if (!strcmp(plugin->info->name, name)) | |
737 return plugin; | |
738 } | |
739 | |
740 return NULL; | |
741 } | |
742 | |
743 GaimPlugin * | |
744 gaim_plugins_find_with_filename(const char *filename) | |
745 { | |
746 GaimPlugin *plugin; | |
747 GList *l; | |
748 | |
749 for (l = plugins; l != NULL; l = l->next) { | |
750 plugin = l->data; | |
751 | |
752 if (plugin->path != NULL && !strcmp(plugin->path, filename)) | |
753 return plugin; | |
754 } | |
755 | |
756 return NULL; | |
757 } | |
758 | |
759 GaimPlugin * | |
760 gaim_plugins_find_with_id(const char *id) | |
761 { | |
762 GaimPlugin *plugin; | |
763 GList *l; | |
764 | |
765 g_return_val_if_fail(id != NULL, NULL); | |
766 | |
6486
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
767 for (l = plugins; l != NULL; l = l->next) |
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
768 { |
5205 | 769 plugin = l->data; |
770 | |
6486
fab81e4b885c
[gaim-migrate @ 7000]
Christian Hammond <chipx86@chipx86.com>
parents:
6485
diff
changeset
|
771 if (plugin->info->id != NULL && !strcmp(plugin->info->id, id)) |
5205 | 772 return plugin; |
773 } | |
774 | |
775 return NULL; | |
776 } | |
777 | |
778 GList * | |
779 gaim_plugins_get_loaded(void) | |
780 { | |
781 return loaded_plugins; | |
782 } | |
783 | |
784 GList * | |
5573
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
785 gaim_plugins_get_protocols(void) |
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
786 { |
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
787 return protocol_plugins; |
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
788 } |
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
789 |
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
790 GList * |
5205 | 791 gaim_plugins_get_all(void) |
792 { | |
793 return plugins; | |
794 } | |
795 |