Mercurial > pidgin
annotate src/plugin.c @ 6064:ed3c3c38e182
[gaim-migrate @ 6514]
clee|work (who I suppose is at work right now) points out that we allow the
Idle Maker plugin to set idle times of sizes up to an int, whereas OSCAR only
accepts them up to a short int.
Actually, he just complained that it wasn't working and I explained that it
was overflowing. I'm not quite sure he understands, but this is a nice fix,
regardless.
committer: Tailor Script <tailor@pidgin.im>
author | Sean Egan <seanegan@gmail.com> |
---|---|
date | Tue, 08 Jul 2003 23:07:13 +0000 |
parents | 81564bb4db68 |
children | f9428d38c03b |
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" |
5205 | 41 #include "event.h" |
5436
ad445074d239
[gaim-migrate @ 5818]
Christian Hammond <chipx86@chipx86.com>
parents:
5357
diff
changeset
|
42 #include "notify.h" |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5840
diff
changeset
|
43 #include "prefs.h" |
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5840
diff
changeset
|
44 #include "prpl.h" |
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5840
diff
changeset
|
45 #include "request.h" |
5205 | 46 |
47 #ifdef _WIN32 | |
48 # define PLUGIN_EXT ".dll" | |
49 #else | |
50 # define PLUGIN_EXT ".so" | |
51 #endif | |
52 | |
53 static GList *loaded_plugins = NULL; | |
54 static GList *plugins = NULL; | |
55 static GList *plugin_loaders = NULL; | |
5573
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
56 static GList *protocol_plugins = NULL; |
5205 | 57 |
58 static size_t search_path_count = 0; | |
59 static char **search_paths = NULL; | |
60 | |
61 static void (*probe_cb)(void *) = NULL; | |
62 static void *probe_cb_data = NULL; | |
63 static void (*load_cb)(GaimPlugin *, void *) = NULL; | |
64 static void *load_cb_data = NULL; | |
65 static void (*unload_cb)(GaimPlugin *, void *) = NULL; | |
66 static void *unload_cb_data = NULL; | |
67 | |
68 #ifdef GAIM_PLUGINS | |
69 static int | |
70 is_so_file(const char *filename, const char *ext) | |
71 { | |
72 int len, extlen; | |
73 | |
74 if (filename == NULL || *filename == '\0' || ext == NULL) | |
75 return 0; | |
76 | |
77 extlen = strlen(ext); | |
78 len = strlen(filename) - extlen; | |
79 | |
80 if (len < 0) | |
81 return 0; | |
82 | |
83 return (!strncmp(filename + len, ext, extlen)); | |
84 } | |
85 | |
86 static gboolean | |
5794
5e93fc46d1af
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5646
diff
changeset
|
87 loader_supports_file(GaimPlugin *loader, const char *filename) |
5205 | 88 { |
89 GList *l, *exts; | |
90 GaimPlugin *plugin; | |
91 | |
92 for (l = plugin_loaders; l != NULL; l = l->next) { | |
93 plugin = l->data; | |
94 | |
95 for (exts = GAIM_PLUGIN_LOADER_INFO(plugin)->exts; | |
96 exts != NULL; | |
97 exts = exts->next) { | |
98 | |
99 if (is_so_file(filename, (char *)exts->data)) | |
100 return TRUE; | |
101 } | |
102 } | |
103 | |
104 return FALSE; | |
105 } | |
106 | |
107 static GaimPlugin * | |
5794
5e93fc46d1af
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5646
diff
changeset
|
108 find_loader_for_plugin(const GaimPlugin *plugin) |
5205 | 109 { |
110 GaimPlugin *loader; | |
111 GList *l; | |
112 | |
113 if (plugin->path == NULL) | |
114 return NULL; | |
115 | |
116 for (l = gaim_plugins_get_loaded(); l != NULL; l = l->next) { | |
117 loader = l->data; | |
118 | |
119 if (loader->info->type == GAIM_PLUGIN_LOADER && | |
5794
5e93fc46d1af
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5646
diff
changeset
|
120 loader_supports_file(loader, plugin->path)) { |
5205 | 121 |
122 return loader; | |
123 } | |
124 | |
125 loader = NULL; | |
126 } | |
127 | |
128 return NULL; | |
129 } | |
130 | |
5449 | 131 #endif /* GAIM_PLUGINS */ |
132 | |
5205 | 133 static gint |
134 compare_prpl(GaimPlugin *a, GaimPlugin *b) | |
135 { | |
136 /* neg if a before b, 0 if equal, pos if a after b */ | |
137 return ((GAIM_IS_PROTOCOL_PLUGIN(a) | |
138 ? GAIM_PLUGIN_PROTOCOL_INFO(a)->protocol : -1) - | |
139 ((GAIM_IS_PROTOCOL_PLUGIN(b) | |
140 ? GAIM_PLUGIN_PROTOCOL_INFO(b)->protocol : -1))); | |
141 } | |
142 | |
143 GaimPlugin * | |
144 gaim_plugin_new(gboolean native, const char *path) | |
145 { | |
146 GaimPlugin *plugin; | |
147 | |
148 plugin = g_new0(GaimPlugin, 1); | |
149 | |
150 plugin->native_plugin = native; | |
151 plugin->path = (path == NULL ? NULL : g_strdup(path)); | |
152 | |
153 return plugin; | |
154 } | |
155 | |
156 GaimPlugin * | |
157 gaim_plugin_probe(const char *filename) | |
158 { | |
159 #ifdef GAIM_PLUGINS | |
160 GaimPlugin *plugin = NULL; | |
161 GaimPlugin *loader; | |
162 gboolean (*gaim_init_plugin)(GaimPlugin *); | |
163 | |
164 g_return_val_if_fail(filename != NULL, NULL); | |
165 | |
5973 | 166 if (!g_file_test(filename, G_FILE_TEST_EXISTS)) |
167 return NULL; | |
168 | |
5205 | 169 plugin = gaim_plugins_find_with_filename(filename); |
170 | |
171 if (plugin != NULL) | |
172 return plugin; | |
173 | |
174 plugin = gaim_plugin_new(is_so_file(filename, PLUGIN_EXT), filename); | |
175 | |
176 if (plugin->native_plugin) { | |
5450 | 177 const char *error; |
5205 | 178 plugin->handle = g_module_open(filename, 0); |
179 | |
180 if (plugin->handle == NULL) { | |
5443 | 181 error = g_module_error(); |
5269
cd7e4ba049f9
[gaim-migrate @ 5641]
Christian Hammond <chipx86@chipx86.com>
parents:
5268
diff
changeset
|
182 gaim_debug(GAIM_DEBUG_ERROR, "plugins", "%s is unloadable: %s\n", |
5443 | 183 plugin->path, error ? error : "Unknown error."); |
5205 | 184 |
5269
cd7e4ba049f9
[gaim-migrate @ 5641]
Christian Hammond <chipx86@chipx86.com>
parents:
5268
diff
changeset
|
185 gaim_plugin_destroy(plugin); |
cd7e4ba049f9
[gaim-migrate @ 5641]
Christian Hammond <chipx86@chipx86.com>
parents:
5268
diff
changeset
|
186 |
cd7e4ba049f9
[gaim-migrate @ 5641]
Christian Hammond <chipx86@chipx86.com>
parents:
5268
diff
changeset
|
187 return NULL; |
5205 | 188 } |
189 | |
190 if (!g_module_symbol(plugin->handle, "gaim_init_plugin", | |
191 (gpointer *)&gaim_init_plugin)) { | |
192 g_module_close(plugin->handle); | |
193 plugin->handle = NULL; | |
194 | |
5443 | 195 error = g_module_error(); |
5211
0241d6b6702d
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
196 gaim_debug(GAIM_DEBUG_ERROR, "plugins", "%s is unloadable: %s\n", |
5443 | 197 plugin->path, error ? error : "Unknown error."); |
5205 | 198 |
199 gaim_plugin_destroy(plugin); | |
200 | |
201 return NULL; | |
202 } | |
203 } | |
204 else { | |
5794
5e93fc46d1af
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5646
diff
changeset
|
205 loader = find_loader_for_plugin(plugin); |
5205 | 206 |
207 if (loader == NULL) { | |
208 gaim_plugin_destroy(plugin); | |
209 | |
210 return NULL; | |
211 } | |
212 | |
213 gaim_init_plugin = GAIM_PLUGIN_LOADER_INFO(loader)->probe; | |
214 } | |
215 | |
216 plugin->error = NULL; | |
217 | |
218 if (!gaim_init_plugin(plugin) || plugin->info == NULL) { | |
219 char buf[BUFSIZ]; | |
220 | |
221 g_snprintf(buf, sizeof(buf), | |
222 _("The plugin %s did not return any valid plugin " | |
223 "information"), | |
224 plugin->path); | |
225 | |
5436
ad445074d239
[gaim-migrate @ 5818]
Christian Hammond <chipx86@chipx86.com>
parents:
5357
diff
changeset
|
226 gaim_notify_error(NULL, NULL, |
ad445074d239
[gaim-migrate @ 5818]
Christian Hammond <chipx86@chipx86.com>
parents:
5357
diff
changeset
|
227 _("Gaim was unable to load your plugin."), buf); |
5205 | 228 |
229 gaim_plugin_destroy(plugin); | |
230 | |
231 return NULL; | |
232 } | |
233 | |
234 return plugin; | |
235 #else | |
236 return NULL; | |
237 #endif /* !GAIM_PLUGINS */ | |
238 } | |
239 | |
240 gboolean | |
241 gaim_plugin_load(GaimPlugin *plugin) | |
242 { | |
243 #ifdef GAIM_PLUGINS | |
244 g_return_val_if_fail(plugin != NULL, FALSE); | |
5270
d1fe8e320dab
[gaim-migrate @ 5642]
Christian Hammond <chipx86@chipx86.com>
parents:
5269
diff
changeset
|
245 g_return_val_if_fail(plugin->error == NULL, FALSE); |
5205 | 246 |
247 if (gaim_plugin_is_loaded(plugin)) | |
248 return TRUE; | |
249 | |
250 if (plugin->native_plugin) { | |
5357
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
251 if (plugin->info != NULL) { |
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
252 if (plugin->info->load != NULL) |
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
253 plugin->info->load(plugin); |
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
254 |
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
255 if (plugin->info->type == GAIM_PLUGIN_LOADER) { |
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
256 GaimPluginLoaderInfo *loader_info; |
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
257 |
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
258 loader_info = GAIM_PLUGIN_LOADER_INFO(plugin); |
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
259 |
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
260 if (loader_info->broadcast != NULL) |
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
261 gaim_signals_register_broadcast_func(loader_info->broadcast, |
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
262 NULL); |
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
263 } |
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
264 } |
5205 | 265 } |
266 else { | |
267 GaimPlugin *loader; | |
268 GaimPluginLoaderInfo *loader_info; | |
269 | |
5794
5e93fc46d1af
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5646
diff
changeset
|
270 loader = find_loader_for_plugin(plugin); |
5205 | 271 |
272 if (loader == NULL) | |
273 return FALSE; | |
274 | |
275 loader_info = GAIM_PLUGIN_LOADER_INFO(loader); | |
276 | |
277 if (loader_info->load != NULL) | |
278 loader_info->load(plugin); | |
279 } | |
280 | |
281 loaded_plugins = g_list_append(loaded_plugins, plugin); | |
282 | |
283 plugin->loaded = TRUE; | |
284 | |
285 /* TODO */ | |
286 if (load_cb != NULL) | |
287 load_cb(plugin, load_cb_data); | |
288 | |
289 return TRUE; | |
290 | |
291 #else | |
5449 | 292 return TRUE; |
5205 | 293 #endif /* !GAIM_PLUGINS */ |
294 } | |
295 | |
296 gboolean | |
297 gaim_plugin_unload(GaimPlugin *plugin) | |
298 { | |
299 #ifdef GAIM_PLUGINS | |
300 g_return_val_if_fail(plugin != NULL, FALSE); | |
301 | |
302 loaded_plugins = g_list_remove(loaded_plugins, plugin); | |
303 | |
304 g_return_val_if_fail(gaim_plugin_is_loaded(plugin), FALSE); | |
305 | |
5211
0241d6b6702d
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
306 gaim_debug(GAIM_DEBUG_INFO, "plugins", "Unloading plugin %s\n", |
0241d6b6702d
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
307 plugin->info->name); |
5205 | 308 |
309 /* cancel any pending dialogs the plugin has */ | |
5498
cce2d7868c78
[gaim-migrate @ 5894]
Christian Hammond <chipx86@chipx86.com>
parents:
5450
diff
changeset
|
310 gaim_request_close_with_handle(plugin); |
cce2d7868c78
[gaim-migrate @ 5894]
Christian Hammond <chipx86@chipx86.com>
parents:
5450
diff
changeset
|
311 gaim_notify_close_with_handle(plugin); |
5205 | 312 |
313 plugin->loaded = FALSE; | |
314 | |
315 if (plugin->native_plugin) { | |
316 if (plugin->info->unload != NULL) | |
317 plugin->info->unload(plugin); | |
318 | |
319 if (plugin->info->type == GAIM_PLUGIN_PROTOCOL) { | |
320 GaimPluginProtocolInfo *prpl_info; | |
321 GList *l; | |
322 | |
323 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(plugin); | |
324 | |
5638
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5573
diff
changeset
|
325 for (l = prpl_info->user_splits; l != NULL; l = l->next) |
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5573
diff
changeset
|
326 gaim_account_user_split_destroy(l->data); |
5205 | 327 |
5638
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5573
diff
changeset
|
328 for (l = prpl_info->protocol_options; l != NULL; l = l->next) |
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5573
diff
changeset
|
329 gaim_account_option_destroy(l->data); |
5205 | 330 |
5646
48c63ee49961
[gaim-migrate @ 6060]
Christian Hammond <chipx86@chipx86.com>
parents:
5638
diff
changeset
|
331 if (prpl_info->user_splits != NULL) |
48c63ee49961
[gaim-migrate @ 6060]
Christian Hammond <chipx86@chipx86.com>
parents:
5638
diff
changeset
|
332 g_list_free(prpl_info->user_splits); |
48c63ee49961
[gaim-migrate @ 6060]
Christian Hammond <chipx86@chipx86.com>
parents:
5638
diff
changeset
|
333 |
48c63ee49961
[gaim-migrate @ 6060]
Christian Hammond <chipx86@chipx86.com>
parents:
5638
diff
changeset
|
334 if (prpl_info->protocol_options != NULL) |
48c63ee49961
[gaim-migrate @ 6060]
Christian Hammond <chipx86@chipx86.com>
parents:
5638
diff
changeset
|
335 g_list_free(prpl_info->protocol_options); |
5205 | 336 } |
5357
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
337 else if (plugin->info->type == GAIM_PLUGIN_LOADER) { |
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
338 GaimPluginLoaderInfo *loader_info; |
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
339 |
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
340 loader_info = GAIM_PLUGIN_LOADER_INFO(plugin); |
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
341 |
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
342 if (loader_info->broadcast != NULL) |
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
343 gaim_signals_unregister_broadcast_func(loader_info->broadcast); |
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
344 } |
5205 | 345 } |
346 else { | |
347 GaimPlugin *loader; | |
348 GaimPluginLoaderInfo *loader_info; | |
349 | |
5794
5e93fc46d1af
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5646
diff
changeset
|
350 loader = find_loader_for_plugin(plugin); |
5205 | 351 |
352 if (loader == NULL) | |
353 return FALSE; | |
354 | |
355 loader_info = GAIM_PLUGIN_LOADER_INFO(loader); | |
356 | |
357 if (loader_info->load != NULL) | |
358 loader_info->unload(plugin); | |
359 } | |
360 | |
361 gaim_signals_disconnect_by_handle(plugin); | |
362 | |
363 /* TODO */ | |
364 if (unload_cb != NULL) | |
365 unload_cb(plugin, unload_cb_data); | |
366 | |
367 return TRUE; | |
5449 | 368 #else |
369 return TRUE; | |
5205 | 370 #endif /* GAIM_PLUGINS */ |
371 } | |
372 | |
373 gboolean | |
374 gaim_plugin_reload(GaimPlugin *plugin) | |
375 { | |
376 #ifdef GAIM_PLUGINS | |
377 g_return_val_if_fail(plugin != NULL, FALSE); | |
378 g_return_val_if_fail(gaim_plugin_is_loaded(plugin), FALSE); | |
379 | |
380 if (!gaim_plugin_unload(plugin)) | |
381 return FALSE; | |
382 | |
383 if (!gaim_plugin_load(plugin)) | |
384 return FALSE; | |
385 | |
386 return TRUE; | |
387 #else | |
5449 | 388 return TRUE; |
5205 | 389 #endif /* !GAIM_PLUGINS */ |
390 } | |
391 | |
392 void | |
393 gaim_plugin_destroy(GaimPlugin *plugin) | |
394 { | |
5449 | 395 #ifdef GAIM_PLUGINS |
5205 | 396 g_return_if_fail(plugin != NULL); |
397 | |
398 if (gaim_plugin_is_loaded(plugin)) | |
399 gaim_plugin_unload(plugin); | |
400 | |
401 plugins = g_list_remove(plugins, plugin); | |
402 | |
5243
f6e0c689a88b
[gaim-migrate @ 5614]
Christian Hammond <chipx86@chipx86.com>
parents:
5242
diff
changeset
|
403 if (plugin->info != NULL && plugin->info->dependencies != NULL) |
f6e0c689a88b
[gaim-migrate @ 5614]
Christian Hammond <chipx86@chipx86.com>
parents:
5242
diff
changeset
|
404 g_list_free(plugin->info->dependencies); |
5205 | 405 |
406 if (plugin->native_plugin) { | |
407 | |
408 if (plugin->info != NULL && plugin->info->type == GAIM_PLUGIN_LOADER) { | |
409 GList *exts, *l, *next_l; | |
410 GaimPlugin *p2; | |
411 | |
412 for (exts = GAIM_PLUGIN_LOADER_INFO(plugin)->exts; | |
413 exts != NULL; | |
414 exts = exts->next) { | |
415 | |
416 for (l = gaim_plugins_get_all(); l != NULL; l = next_l) { | |
417 next_l = l->next; | |
418 | |
419 p2 = l->data; | |
420 | |
421 if (p2->path != NULL && is_so_file(p2->path, exts->data)) | |
422 gaim_plugin_destroy(p2); | |
423 } | |
424 } | |
425 | |
426 g_list_free(GAIM_PLUGIN_LOADER_INFO(plugin)->exts); | |
427 | |
428 plugin_loaders = g_list_remove(plugin_loaders, plugin); | |
429 } | |
430 | |
431 if (plugin->info != NULL && plugin->info->destroy != NULL) | |
432 plugin->info->destroy(plugin); | |
433 | |
434 if (plugin->handle != NULL) | |
435 g_module_close(plugin->handle); | |
436 } | |
437 else { | |
438 GaimPlugin *loader; | |
439 GaimPluginLoaderInfo *loader_info; | |
440 | |
5794
5e93fc46d1af
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5646
diff
changeset
|
441 loader = find_loader_for_plugin(plugin); |
5205 | 442 |
5941
a3e60ff95b7d
[gaim-migrate @ 6381]
Christian Hammond <chipx86@chipx86.com>
parents:
5872
diff
changeset
|
443 if (loader != NULL) { |
a3e60ff95b7d
[gaim-migrate @ 6381]
Christian Hammond <chipx86@chipx86.com>
parents:
5872
diff
changeset
|
444 loader_info = GAIM_PLUGIN_LOADER_INFO(loader); |
5205 | 445 |
5941
a3e60ff95b7d
[gaim-migrate @ 6381]
Christian Hammond <chipx86@chipx86.com>
parents:
5872
diff
changeset
|
446 if (loader_info->destroy != NULL) |
a3e60ff95b7d
[gaim-migrate @ 6381]
Christian Hammond <chipx86@chipx86.com>
parents:
5872
diff
changeset
|
447 loader_info->destroy(plugin); |
a3e60ff95b7d
[gaim-migrate @ 6381]
Christian Hammond <chipx86@chipx86.com>
parents:
5872
diff
changeset
|
448 } |
5205 | 449 } |
450 | |
451 if (plugin->path != NULL) g_free(plugin->path); | |
452 if (plugin->error != NULL) g_free(plugin->error); | |
453 | |
454 g_free(plugin); | |
5449 | 455 #endif /* !GAIM_PLUGINS */ |
5205 | 456 } |
457 | |
458 gboolean | |
459 gaim_plugin_is_loaded(const GaimPlugin *plugin) | |
460 { | |
461 g_return_val_if_fail(plugin != NULL, FALSE); | |
462 | |
463 return plugin->loaded; | |
464 } | |
465 | |
466 void | |
467 gaim_plugins_set_search_paths(size_t count, char **paths) | |
468 { | |
469 size_t s; | |
470 | |
471 g_return_if_fail(count > 0); | |
472 g_return_if_fail(paths != NULL); | |
473 | |
474 if (search_paths != NULL) { | |
475 for (s = 0; s < search_path_count; s++) | |
476 g_free(search_paths[s]); | |
477 | |
478 g_free(search_paths); | |
479 } | |
480 | |
481 search_paths = g_new0(char *, count); | |
482 | |
483 for (s = 0; s < count; s++) { | |
484 if (paths[s] == NULL) | |
485 search_paths[s] = NULL; | |
486 else | |
487 search_paths[s] = g_strdup(paths[s]); | |
488 } | |
489 | |
490 search_path_count = count; | |
491 } | |
492 | |
493 void | |
494 gaim_plugins_unload_all(void) | |
495 { | |
496 #ifdef GAIM_PLUGINS | |
497 | |
498 while (loaded_plugins != NULL) | |
499 gaim_plugin_unload(loaded_plugins->data); | |
500 | |
501 #endif /* GAIM_PLUGINS */ | |
502 } | |
503 | |
504 void | |
5242
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
505 gaim_plugins_destroy_all(void) |
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
506 { |
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
507 #ifdef GAIM_PLUGINS |
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
508 |
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
509 while (plugins != NULL) |
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
510 gaim_plugin_destroy(plugins->data); |
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
511 |
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
512 #endif /* GAIM_PLUGINS */ |
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
513 } |
5838 | 514 |
515 void | |
5949
90d0849abd3c
[gaim-migrate @ 6393]
Christian Hammond <chipx86@chipx86.com>
parents:
5941
diff
changeset
|
516 gaim_plugins_load_saved(const char *key) |
5838 | 517 { |
518 #ifdef GAIM_PLUGINS | |
5949
90d0849abd3c
[gaim-migrate @ 6393]
Christian Hammond <chipx86@chipx86.com>
parents:
5941
diff
changeset
|
519 GList *f, *files; |
90d0849abd3c
[gaim-migrate @ 6393]
Christian Hammond <chipx86@chipx86.com>
parents:
5941
diff
changeset
|
520 |
90d0849abd3c
[gaim-migrate @ 6393]
Christian Hammond <chipx86@chipx86.com>
parents:
5941
diff
changeset
|
521 g_return_if_fail(key != NULL); |
5838 | 522 |
5949
90d0849abd3c
[gaim-migrate @ 6393]
Christian Hammond <chipx86@chipx86.com>
parents:
5941
diff
changeset
|
523 files = gaim_prefs_get_string_list(key); |
90d0849abd3c
[gaim-migrate @ 6393]
Christian Hammond <chipx86@chipx86.com>
parents:
5941
diff
changeset
|
524 |
90d0849abd3c
[gaim-migrate @ 6393]
Christian Hammond <chipx86@chipx86.com>
parents:
5941
diff
changeset
|
525 for (f = files; f; f = f->next) { |
5838 | 526 gaim_plugin_load(gaim_plugin_probe(f->data)); |
527 g_free(f->data); | |
528 } | |
529 | |
530 g_list_free(files); | |
531 #endif /* GAIM_PLUGINS */ | |
532 } | |
533 | |
534 | |
5242
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
535 void |
5205 | 536 gaim_plugins_probe(const char *ext) |
537 { | |
538 #ifdef GAIM_PLUGINS | |
539 GDir *dir; | |
540 const gchar *file; | |
541 gchar *path; | |
542 GaimPlugin *plugin; | |
543 size_t i; | |
544 | |
545 if (!g_module_supported()) | |
546 return; | |
547 | |
548 for (i = 0; i < search_path_count; i++) { | |
549 if (search_paths[i] == NULL) | |
550 continue; | |
551 | |
552 dir = g_dir_open(search_paths[i], 0, NULL); | |
553 | |
554 if (dir != NULL) { | |
555 while ((file = g_dir_read_name(dir)) != NULL) { | |
556 path = g_build_filename(search_paths[i], file, NULL); | |
557 | |
558 if (ext == NULL || is_so_file(file, ext)) | |
559 plugin = gaim_plugin_probe(path); | |
560 | |
561 g_free(path); | |
562 } | |
563 | |
564 g_dir_close(dir); | |
565 } | |
566 } | |
567 | |
568 if (probe_cb != NULL) | |
569 probe_cb(probe_cb_data); | |
570 | |
571 #endif /* GAIM_PLUGINS */ | |
572 } | |
573 | |
574 gboolean | |
575 gaim_plugin_register(GaimPlugin *plugin) | |
576 { | |
577 g_return_val_if_fail(plugin != NULL, FALSE); | |
578 | |
579 if (g_list_find(plugins, plugin)) | |
580 return TRUE; | |
581 | |
582 /* Special exception for loader plugins. We want them loaded NOW! */ | |
583 if (plugin->info->type == GAIM_PLUGIN_LOADER) { | |
584 GList *exts; | |
585 | |
586 /* We'll just load this right now. */ | |
587 if (!gaim_plugin_load(plugin)) { | |
588 | |
589 gaim_plugin_destroy(plugin); | |
590 | |
591 return FALSE; | |
592 } | |
593 | |
594 plugin_loaders = g_list_append(plugin_loaders, plugin); | |
595 | |
596 for (exts = GAIM_PLUGIN_LOADER_INFO(plugin)->exts; | |
597 exts != NULL; | |
598 exts = exts->next) { | |
599 | |
600 gaim_plugins_probe(exts->data); | |
601 } | |
602 } | |
603 else if (plugin->info->type == GAIM_PLUGIN_PROTOCOL) { | |
604 | |
605 /* We'll just load this right now. */ | |
606 if (!gaim_plugin_load(plugin)) { | |
607 | |
608 gaim_plugin_destroy(plugin); | |
609 | |
610 return FALSE; | |
611 } | |
612 | |
613 if (GAIM_PLUGIN_PROTOCOL_INFO(plugin)->protocol == GAIM_PROTO_ICQ || | |
614 gaim_find_prpl(GAIM_PLUGIN_PROTOCOL_INFO(plugin)->protocol)) { | |
615 | |
616 /* Nothing to see here--move along, move along */ | |
617 gaim_plugin_destroy(plugin); | |
618 | |
619 return FALSE; | |
620 } | |
621 | |
5573
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
622 protocol_plugins = g_list_insert_sorted(protocol_plugins, plugin, |
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
623 (GCompareFunc)compare_prpl); |
5205 | 624 } |
625 | |
626 plugins = g_list_append(plugins, plugin); | |
627 | |
628 return TRUE; | |
629 } | |
630 | |
631 gboolean | |
632 gaim_plugins_enabled(void) | |
633 { | |
634 #ifdef GAIM_PLUGINS | |
635 return TRUE; | |
636 #else | |
637 return FALSE; | |
638 #endif | |
639 } | |
640 | |
641 void | |
642 gaim_plugins_register_probe_notify_cb(void (*func)(void *), void *data) | |
643 { | |
644 /* TODO */ | |
645 probe_cb = func; | |
646 probe_cb_data = data; | |
647 } | |
648 | |
649 void | |
650 gaim_plugins_unregister_probe_notify_cb(void (*func)(void *)) | |
651 { | |
652 /* TODO */ | |
653 probe_cb = NULL; | |
654 probe_cb_data = NULL; | |
655 } | |
656 | |
657 void | |
658 gaim_plugins_register_load_notify_cb(void (*func)(GaimPlugin *, void *), | |
659 void *data) | |
660 { | |
661 /* TODO */ | |
662 load_cb = func; | |
663 load_cb_data = data; | |
664 } | |
665 | |
666 void | |
667 gaim_plugins_unregister_load_notify_cb(void (*func)(GaimPlugin *, void *)) | |
668 { | |
669 /* TODO */ | |
670 load_cb = NULL; | |
671 load_cb_data = NULL; | |
672 } | |
673 | |
674 void | |
675 gaim_plugins_register_unload_notify_cb(void (*func)(GaimPlugin *, void *), | |
676 void *data) | |
677 { | |
678 /* TODO */ | |
679 unload_cb = func; | |
680 unload_cb_data = data; | |
681 } | |
682 | |
683 void | |
684 gaim_plugins_unregister_unload_notify_cb(void (*func)(GaimPlugin *, void *)) | |
685 { | |
686 /* TODO */ | |
687 unload_cb = NULL; | |
688 unload_cb_data = NULL; | |
689 } | |
690 | |
691 GaimPlugin * | |
692 gaim_plugins_find_with_name(const char *name) | |
693 { | |
694 GaimPlugin *plugin; | |
695 GList *l; | |
696 | |
697 for (l = plugins; l != NULL; l = l->next) { | |
698 plugin = l->data; | |
699 | |
700 if (!strcmp(plugin->info->name, name)) | |
701 return plugin; | |
702 } | |
703 | |
704 return NULL; | |
705 } | |
706 | |
707 GaimPlugin * | |
708 gaim_plugins_find_with_filename(const char *filename) | |
709 { | |
710 GaimPlugin *plugin; | |
711 GList *l; | |
712 | |
713 for (l = plugins; l != NULL; l = l->next) { | |
714 plugin = l->data; | |
715 | |
716 if (plugin->path != NULL && !strcmp(plugin->path, filename)) | |
717 return plugin; | |
718 } | |
719 | |
720 return NULL; | |
721 } | |
722 | |
723 GaimPlugin * | |
724 gaim_plugins_find_with_id(const char *id) | |
725 { | |
726 GaimPlugin *plugin; | |
727 GList *l; | |
728 | |
729 g_return_val_if_fail(id != NULL, NULL); | |
730 | |
731 for (l = plugins; l != NULL; l = l->next) { | |
732 plugin = l->data; | |
733 | |
734 if (!strcmp(plugin->info->id, id)) | |
735 return plugin; | |
736 } | |
737 | |
738 return NULL; | |
739 } | |
740 | |
741 GList * | |
742 gaim_plugins_get_loaded(void) | |
743 { | |
744 return loaded_plugins; | |
745 } | |
746 | |
747 GList * | |
5573
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
748 gaim_plugins_get_protocols(void) |
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
749 { |
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
750 return protocol_plugins; |
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
751 } |
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
752 |
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
753 GList * |
5205 | 754 gaim_plugins_get_all(void) |
755 { | |
756 return plugins; | |
757 } | |
758 |