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