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