Mercurial > pidgin
annotate src/plugin.c @ 5411:2c4188300aba
[gaim-migrate @ 5787]
This fixes an i18n thing, I think.
I changed some stuff in oscar.c to use _() instead of calling gettext
directly. That's ok, right? I like the macro better.
I also fixed a compile warning or two. If that function declaration
isn't supposed to be there, feel free to move it, or remove it, or
lemme know and I'll do it.
Viva 0.63!
committer: Tailor Script <tailor@pidgin.im>
| author | Mark Doliner <mark@kingant.net> |
|---|---|
| date | Sat, 17 May 2003 05:41:18 +0000 |
| parents | 2a1c92df7024 |
| children | ad445074d239 |
| 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) { | |
|
5357
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
256 if (plugin->info != NULL) { |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
257 if (plugin->info->load != NULL) |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
258 plugin->info->load(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 (plugin->info->type == GAIM_PLUGIN_LOADER) { |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
261 GaimPluginLoaderInfo *loader_info; |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
262 |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
263 loader_info = GAIM_PLUGIN_LOADER_INFO(plugin); |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
264 |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
265 if (loader_info->broadcast != NULL) |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
266 gaim_signals_register_broadcast_func(loader_info->broadcast, |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
267 NULL); |
|
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 } |
| 5205 | 270 } |
| 271 else { | |
| 272 GaimPlugin *loader; | |
| 273 GaimPluginLoaderInfo *loader_info; | |
| 274 | |
| 275 loader = __find_loader_for_plugin(plugin); | |
| 276 | |
| 277 if (loader == NULL) | |
| 278 return FALSE; | |
| 279 | |
| 280 loader_info = GAIM_PLUGIN_LOADER_INFO(loader); | |
| 281 | |
| 282 if (loader_info->load != NULL) | |
| 283 loader_info->load(plugin); | |
| 284 } | |
| 285 | |
| 286 loaded_plugins = g_list_append(loaded_plugins, plugin); | |
| 287 | |
| 288 plugin->loaded = TRUE; | |
| 289 | |
| 290 /* TODO */ | |
| 291 if (load_cb != NULL) | |
| 292 load_cb(plugin, load_cb_data); | |
| 293 | |
| 294 return TRUE; | |
| 295 | |
| 296 #else | |
| 297 return FALSE; | |
| 298 #endif /* !GAIM_PLUGINS */ | |
| 299 } | |
| 300 | |
| 301 gboolean | |
| 302 gaim_plugin_unload(GaimPlugin *plugin) | |
| 303 { | |
| 304 #ifdef GAIM_PLUGINS | |
| 305 g_return_val_if_fail(plugin != NULL, FALSE); | |
| 306 | |
| 307 loaded_plugins = g_list_remove(loaded_plugins, plugin); | |
| 308 | |
| 309 g_return_val_if_fail(gaim_plugin_is_loaded(plugin), FALSE); | |
| 310 | |
|
5211
0241d6b6702d
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
311 gaim_debug(GAIM_DEBUG_INFO, "plugins", "Unloading plugin %s\n", |
|
0241d6b6702d
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
312 plugin->info->name); |
| 5205 | 313 |
| 314 /* cancel any pending dialogs the plugin has */ | |
| 315 do_ask_cancel_by_handle(plugin); | |
| 316 | |
| 317 plugin->loaded = FALSE; | |
| 318 | |
| 319 if (plugin->native_plugin) { | |
| 320 if (plugin->info->unload != NULL) | |
| 321 plugin->info->unload(plugin); | |
| 322 | |
| 323 if (plugin->info->type == GAIM_PLUGIN_PROTOCOL) { | |
| 324 GaimPluginProtocolInfo *prpl_info; | |
| 325 GList *l; | |
| 326 struct proto_user_split *pus; | |
| 327 struct proto_user_opt *puo; | |
| 328 | |
| 329 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(plugin); | |
| 330 | |
| 331 for (l = prpl_info->user_splits; l != NULL; l = l->next) { | |
| 332 pus = l->data; | |
| 333 | |
| 334 g_free(pus->label); | |
| 335 g_free(pus->def); | |
| 336 g_free(pus); | |
| 337 } | |
| 338 | |
| 339 g_list_free(prpl_info->user_splits); | |
| 340 | |
| 341 for (l = prpl_info->user_opts; l != NULL; l = l->next) { | |
| 342 puo = l->data; | |
| 343 | |
| 344 g_free(puo->label); | |
| 345 g_free(puo->def); | |
| 346 g_free(puo); | |
| 347 } | |
| 348 | |
| 349 g_list_free(prpl_info->user_opts); | |
| 350 } | |
|
5357
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
351 else if (plugin->info->type == GAIM_PLUGIN_LOADER) { |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
352 GaimPluginLoaderInfo *loader_info; |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
353 |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
354 loader_info = GAIM_PLUGIN_LOADER_INFO(plugin); |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
355 |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
356 if (loader_info->broadcast != NULL) |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
357 gaim_signals_unregister_broadcast_func(loader_info->broadcast); |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
358 } |
| 5205 | 359 } |
| 360 else { | |
| 361 GaimPlugin *loader; | |
| 362 GaimPluginLoaderInfo *loader_info; | |
| 363 | |
| 364 loader = __find_loader_for_plugin(plugin); | |
| 365 | |
| 366 if (loader == NULL) | |
| 367 return FALSE; | |
| 368 | |
| 369 loader_info = GAIM_PLUGIN_LOADER_INFO(loader); | |
| 370 | |
| 371 if (loader_info->load != NULL) | |
| 372 loader_info->unload(plugin); | |
| 373 } | |
| 374 | |
| 375 gaim_signals_disconnect_by_handle(plugin); | |
| 376 | |
| 377 /* TODO */ | |
| 378 if (unload_cb != NULL) | |
| 379 unload_cb(plugin, unload_cb_data); | |
| 380 | |
| 381 return TRUE; | |
| 382 #endif /* GAIM_PLUGINS */ | |
| 383 } | |
| 384 | |
| 385 gboolean | |
| 386 gaim_plugin_reload(GaimPlugin *plugin) | |
| 387 { | |
| 388 #ifdef GAIM_PLUGINS | |
| 389 g_return_val_if_fail(plugin != NULL, FALSE); | |
| 390 g_return_val_if_fail(gaim_plugin_is_loaded(plugin), FALSE); | |
| 391 | |
| 392 if (!gaim_plugin_unload(plugin)) | |
| 393 return FALSE; | |
| 394 | |
| 395 if (!gaim_plugin_load(plugin)) | |
| 396 return FALSE; | |
| 397 | |
| 398 return TRUE; | |
| 399 #else | |
| 400 return NULL; | |
| 401 #endif /* !GAIM_PLUGINS */ | |
| 402 } | |
| 403 | |
| 404 void | |
| 405 gaim_plugin_destroy(GaimPlugin *plugin) | |
| 406 { | |
| 407 g_return_if_fail(plugin != NULL); | |
| 408 | |
| 409 if (gaim_plugin_is_loaded(plugin)) | |
| 410 gaim_plugin_unload(plugin); | |
| 411 | |
| 412 plugins = g_list_remove(plugins, plugin); | |
| 413 | |
|
5243
f6e0c689a88b
[gaim-migrate @ 5614]
Christian Hammond <chipx86@chipx86.com>
parents:
5242
diff
changeset
|
414 if (plugin->info != NULL && plugin->info->dependencies != NULL) |
|
f6e0c689a88b
[gaim-migrate @ 5614]
Christian Hammond <chipx86@chipx86.com>
parents:
5242
diff
changeset
|
415 g_list_free(plugin->info->dependencies); |
| 5205 | 416 |
| 417 if (plugin->native_plugin) { | |
| 418 | |
| 419 if (plugin->info != NULL && plugin->info->type == GAIM_PLUGIN_LOADER) { | |
| 420 GList *exts, *l, *next_l; | |
| 421 GaimPlugin *p2; | |
| 422 | |
| 423 for (exts = GAIM_PLUGIN_LOADER_INFO(plugin)->exts; | |
| 424 exts != NULL; | |
| 425 exts = exts->next) { | |
| 426 | |
| 427 for (l = gaim_plugins_get_all(); l != NULL; l = next_l) { | |
| 428 next_l = l->next; | |
| 429 | |
| 430 p2 = l->data; | |
| 431 | |
| 432 if (p2->path != NULL && is_so_file(p2->path, exts->data)) | |
| 433 gaim_plugin_destroy(p2); | |
| 434 } | |
| 435 } | |
| 436 | |
| 437 g_list_free(GAIM_PLUGIN_LOADER_INFO(plugin)->exts); | |
| 438 | |
| 439 plugin_loaders = g_list_remove(plugin_loaders, plugin); | |
| 440 } | |
| 441 | |
| 442 if (plugin->info != NULL && plugin->info->destroy != NULL) | |
| 443 plugin->info->destroy(plugin); | |
| 444 | |
| 445 if (plugin->handle != NULL) | |
| 446 g_module_close(plugin->handle); | |
| 447 } | |
| 448 else { | |
| 449 GaimPlugin *loader; | |
| 450 GaimPluginLoaderInfo *loader_info; | |
| 451 | |
| 452 loader = __find_loader_for_plugin(plugin); | |
| 453 | |
| 454 if (loader == NULL) | |
| 455 return; | |
| 456 | |
| 457 loader_info = GAIM_PLUGIN_LOADER_INFO(loader); | |
| 458 | |
| 459 if (loader_info->destroy != NULL) | |
| 460 loader_info->destroy(plugin); | |
| 461 } | |
| 462 | |
| 463 if (plugin->path != NULL) g_free(plugin->path); | |
| 464 if (plugin->error != NULL) g_free(plugin->error); | |
| 465 | |
| 466 g_free(plugin); | |
| 467 } | |
| 468 | |
| 469 gboolean | |
| 470 gaim_plugin_is_loaded(const GaimPlugin *plugin) | |
| 471 { | |
| 472 g_return_val_if_fail(plugin != NULL, FALSE); | |
| 473 | |
| 474 return plugin->loaded; | |
| 475 } | |
| 476 | |
| 477 void | |
| 478 gaim_plugins_set_search_paths(size_t count, char **paths) | |
| 479 { | |
| 480 size_t s; | |
| 481 | |
| 482 g_return_if_fail(count > 0); | |
| 483 g_return_if_fail(paths != NULL); | |
| 484 | |
| 485 if (search_paths != NULL) { | |
| 486 for (s = 0; s < search_path_count; s++) | |
| 487 g_free(search_paths[s]); | |
| 488 | |
| 489 g_free(search_paths); | |
| 490 } | |
| 491 | |
| 492 search_paths = g_new0(char *, count); | |
| 493 | |
| 494 for (s = 0; s < count; s++) { | |
| 495 if (paths[s] == NULL) | |
| 496 search_paths[s] = NULL; | |
| 497 else | |
| 498 search_paths[s] = g_strdup(paths[s]); | |
| 499 } | |
| 500 | |
| 501 search_path_count = count; | |
| 502 } | |
| 503 | |
| 504 void | |
| 505 gaim_plugins_unload_all(void) | |
| 506 { | |
| 507 #ifdef GAIM_PLUGINS | |
| 508 | |
| 509 while (loaded_plugins != NULL) | |
| 510 gaim_plugin_unload(loaded_plugins->data); | |
| 511 | |
| 512 #endif /* GAIM_PLUGINS */ | |
| 513 } | |
| 514 | |
| 515 void | |
|
5242
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
516 gaim_plugins_destroy_all(void) |
|
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 #ifdef GAIM_PLUGINS |
|
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
519 |
|
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
520 while (plugins != NULL) |
|
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
521 gaim_plugin_destroy(plugins->data); |
|
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 #endif /* GAIM_PLUGINS */ |
|
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
524 } |
|
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
525 void |
| 5205 | 526 gaim_plugins_probe(const char *ext) |
| 527 { | |
| 528 #ifdef GAIM_PLUGINS | |
| 529 GDir *dir; | |
| 530 const gchar *file; | |
| 531 gchar *path; | |
| 532 GaimPlugin *plugin; | |
| 533 size_t i; | |
| 534 | |
| 535 if (!g_module_supported()) | |
| 536 return; | |
| 537 | |
| 538 for (i = 0; i < search_path_count; i++) { | |
| 539 if (search_paths[i] == NULL) | |
| 540 continue; | |
| 541 | |
| 542 dir = g_dir_open(search_paths[i], 0, NULL); | |
| 543 | |
| 544 if (dir != NULL) { | |
| 545 while ((file = g_dir_read_name(dir)) != NULL) { | |
| 546 path = g_build_filename(search_paths[i], file, NULL); | |
| 547 | |
| 548 if (ext == NULL || is_so_file(file, ext)) | |
| 549 plugin = gaim_plugin_probe(path); | |
| 550 | |
| 551 g_free(path); | |
| 552 } | |
| 553 | |
| 554 g_dir_close(dir); | |
| 555 } | |
| 556 } | |
| 557 | |
| 558 if (probe_cb != NULL) | |
| 559 probe_cb(probe_cb_data); | |
| 560 | |
| 561 #endif /* GAIM_PLUGINS */ | |
| 562 } | |
| 563 | |
| 564 gboolean | |
| 565 gaim_plugin_register(GaimPlugin *plugin) | |
| 566 { | |
| 567 #ifdef GAIM_PLUGINS | |
| 568 g_return_val_if_fail(plugin != NULL, FALSE); | |
| 569 | |
| 570 if (g_list_find(plugins, plugin)) | |
| 571 return TRUE; | |
| 572 | |
| 573 /* Special exception for loader plugins. We want them loaded NOW! */ | |
| 574 if (plugin->info->type == GAIM_PLUGIN_LOADER) { | |
| 575 GList *exts; | |
| 576 | |
| 577 /* We'll just load this right now. */ | |
| 578 if (!gaim_plugin_load(plugin)) { | |
| 579 | |
| 580 gaim_plugin_destroy(plugin); | |
| 581 | |
| 582 return FALSE; | |
| 583 } | |
| 584 | |
| 585 plugin_loaders = g_list_append(plugin_loaders, plugin); | |
| 586 | |
| 587 for (exts = GAIM_PLUGIN_LOADER_INFO(plugin)->exts; | |
| 588 exts != NULL; | |
| 589 exts = exts->next) { | |
| 590 | |
| 591 gaim_plugins_probe(exts->data); | |
| 592 } | |
| 593 } | |
| 594 else if (plugin->info->type == GAIM_PLUGIN_PROTOCOL) { | |
| 595 | |
| 596 /* We'll just load this right now. */ | |
| 597 if (!gaim_plugin_load(plugin)) { | |
| 598 | |
| 599 gaim_plugin_destroy(plugin); | |
| 600 | |
| 601 return FALSE; | |
| 602 } | |
| 603 | |
| 604 if (GAIM_PLUGIN_PROTOCOL_INFO(plugin)->protocol == GAIM_PROTO_ICQ || | |
| 605 gaim_find_prpl(GAIM_PLUGIN_PROTOCOL_INFO(plugin)->protocol)) { | |
| 606 | |
| 607 /* Nothing to see here--move along, move along */ | |
| 608 gaim_plugin_destroy(plugin); | |
| 609 | |
| 610 return FALSE; | |
| 611 } | |
| 612 | |
| 613 protocols = g_slist_insert_sorted(protocols, plugin, | |
| 614 (GCompareFunc)compare_prpl); | |
| 615 } | |
| 616 | |
| 617 plugins = g_list_append(plugins, plugin); | |
| 618 | |
| 619 return TRUE; | |
| 620 #else | |
| 621 return FALSE; | |
| 622 #endif /* !GAIM_PLUGINS */ | |
| 623 } | |
| 624 | |
| 625 gboolean | |
| 626 gaim_plugins_enabled(void) | |
| 627 { | |
| 628 #ifdef GAIM_PLUGINS | |
| 629 return TRUE; | |
| 630 #else | |
| 631 return FALSE; | |
| 632 #endif | |
| 633 } | |
| 634 | |
| 635 void | |
| 636 gaim_plugins_register_probe_notify_cb(void (*func)(void *), void *data) | |
| 637 { | |
| 638 /* TODO */ | |
| 639 probe_cb = func; | |
| 640 probe_cb_data = data; | |
| 641 } | |
| 642 | |
| 643 void | |
| 644 gaim_plugins_unregister_probe_notify_cb(void (*func)(void *)) | |
| 645 { | |
| 646 /* TODO */ | |
| 647 probe_cb = NULL; | |
| 648 probe_cb_data = NULL; | |
| 649 } | |
| 650 | |
| 651 void | |
| 652 gaim_plugins_register_load_notify_cb(void (*func)(GaimPlugin *, void *), | |
| 653 void *data) | |
| 654 { | |
| 655 /* TODO */ | |
| 656 load_cb = func; | |
| 657 load_cb_data = data; | |
| 658 } | |
| 659 | |
| 660 void | |
| 661 gaim_plugins_unregister_load_notify_cb(void (*func)(GaimPlugin *, void *)) | |
| 662 { | |
| 663 /* TODO */ | |
| 664 load_cb = NULL; | |
| 665 load_cb_data = NULL; | |
| 666 } | |
| 667 | |
| 668 void | |
| 669 gaim_plugins_register_unload_notify_cb(void (*func)(GaimPlugin *, void *), | |
| 670 void *data) | |
| 671 { | |
| 672 /* TODO */ | |
| 673 unload_cb = func; | |
| 674 unload_cb_data = data; | |
| 675 } | |
| 676 | |
| 677 void | |
| 678 gaim_plugins_unregister_unload_notify_cb(void (*func)(GaimPlugin *, void *)) | |
| 679 { | |
| 680 /* TODO */ | |
| 681 unload_cb = NULL; | |
| 682 unload_cb_data = NULL; | |
| 683 } | |
| 684 | |
| 685 GaimPlugin * | |
| 686 gaim_plugins_find_with_name(const char *name) | |
| 687 { | |
| 688 GaimPlugin *plugin; | |
| 689 GList *l; | |
| 690 | |
| 691 for (l = plugins; l != NULL; l = l->next) { | |
| 692 plugin = l->data; | |
| 693 | |
| 694 if (!strcmp(plugin->info->name, name)) | |
| 695 return plugin; | |
| 696 } | |
| 697 | |
| 698 return NULL; | |
| 699 } | |
| 700 | |
| 701 GaimPlugin * | |
| 702 gaim_plugins_find_with_filename(const char *filename) | |
| 703 { | |
| 704 GaimPlugin *plugin; | |
| 705 GList *l; | |
| 706 | |
| 707 for (l = plugins; l != NULL; l = l->next) { | |
| 708 plugin = l->data; | |
| 709 | |
| 710 if (plugin->path != NULL && !strcmp(plugin->path, filename)) | |
| 711 return plugin; | |
| 712 } | |
| 713 | |
| 714 return NULL; | |
| 715 } | |
| 716 | |
| 717 GaimPlugin * | |
| 718 gaim_plugins_find_with_id(const char *id) | |
| 719 { | |
| 720 GaimPlugin *plugin; | |
| 721 GList *l; | |
| 722 | |
| 723 g_return_val_if_fail(id != NULL, NULL); | |
| 724 | |
| 725 for (l = plugins; l != NULL; l = l->next) { | |
| 726 plugin = l->data; | |
| 727 | |
| 728 if (!strcmp(plugin->info->id, id)) | |
| 729 return plugin; | |
| 730 } | |
| 731 | |
| 732 return NULL; | |
| 733 } | |
| 734 | |
| 735 GList * | |
| 736 gaim_plugins_get_loaded(void) | |
| 737 { | |
| 738 return loaded_plugins; | |
| 739 } | |
| 740 | |
| 741 GList * | |
| 742 gaim_plugins_get_all(void) | |
| 743 { | |
| 744 return plugins; | |
| 745 } | |
| 746 |
