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