Mercurial > pidgin.yaz
annotate src/plugin.c @ 6485:70d5122bc3ff
[gaim-migrate @ 6999]
Removed the old event system and replaced it with a much better signal
system. There will most likely be some bugs in this, but it seems to be
working for now. Plugins can now generate their own signals, and other
plugins can find those plugins and connect to them. This could give
plugins a form of IPC. It's also useful for other things. It's rather
flexible, except for the damn marshalling, but there's no way around that
that I or the glib people can see.
committer: Tailor Script <tailor@pidgin.im>
| author | Christian Hammond <chipx86@chipx86.com> |
|---|---|
| date | Mon, 18 Aug 2003 01:03:43 +0000 |
| parents | f9428d38c03b |
| children | fab81e4b885c |
| rev | line source |
|---|---|
| 5205 | 1 /* |
| 2 * gaim | |
| 3 * | |
| 4 * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net> | |
| 5 * | |
| 6 * This program is free software; you can redistribute it and/or modify | |
| 7 * it under the terms of the GNU General Public License as published by | |
| 8 * the Free Software Foundation; either version 2 of the License, or | |
| 9 * (at your option) any later version. | |
| 10 * | |
| 11 * This program is distributed in the hope that it will be useful, | |
| 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 14 * GNU General Public License for more details. | |
| 15 * | |
| 16 * You should have received a copy of the GNU General Public License | |
| 17 * along with this program; if not, write to the Free Software | |
| 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
| 19 */ | |
| 20 | |
| 21 /* | |
| 22 * ---------------- | |
| 23 * The Plug-in plugin | |
| 24 * | |
| 25 * Plugin support is currently being maintained by Mike Saraf | |
| 26 * msaraf@dwc.edu | |
| 27 * | |
| 28 * Well, I didn't see any work done on it for a while, so I'm going to try | |
| 29 * my hand at it. - Eric warmenhoven@yahoo.com | |
| 30 * | |
| 31 * Mike is my roomate. I can assure you that he's lazy :-P | |
| 32 * -- Rob rob@marko.net | |
| 33 * | |
| 34 * Yeah, well now I'm re-writing a good portion of it! The perl stuff was | |
| 35 * a hack. Tsk tsk! -- Christian <chipx86@gnupdate.org> | |
| 36 */ | |
|
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5840
diff
changeset
|
37 #include "internal.h" |
| 5205 | 38 |
|
5638
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5573
diff
changeset
|
39 #include "accountopt.h" |
|
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5840
diff
changeset
|
40 #include "debug.h" |
|
5436
ad445074d239
[gaim-migrate @ 5818]
Christian Hammond <chipx86@chipx86.com>
parents:
5357
diff
changeset
|
41 #include "notify.h" |
|
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5840
diff
changeset
|
42 #include "prefs.h" |
|
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5840
diff
changeset
|
43 #include "prpl.h" |
|
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5840
diff
changeset
|
44 #include "request.h" |
|
6485
70d5122bc3ff
[gaim-migrate @ 6999]
Christian Hammond <chipx86@chipx86.com>
parents:
6432
diff
changeset
|
45 #include "signals.h" |
| 5205 | 46 |
| 47 #ifdef _WIN32 | |
| 48 # define PLUGIN_EXT ".dll" | |
| 49 #else | |
| 50 # define PLUGIN_EXT ".so" | |
| 51 #endif | |
| 52 | |
| 53 static GList *loaded_plugins = NULL; | |
| 54 static GList *plugins = NULL; | |
| 55 static GList *plugin_loaders = NULL; | |
|
5573
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
56 static GList *protocol_plugins = NULL; |
| 5205 | 57 |
| 58 static size_t search_path_count = 0; | |
| 59 static char **search_paths = NULL; | |
| 60 | |
| 61 static void (*probe_cb)(void *) = NULL; | |
| 62 static void *probe_cb_data = NULL; | |
| 63 static void (*load_cb)(GaimPlugin *, void *) = NULL; | |
| 64 static void *load_cb_data = NULL; | |
| 65 static void (*unload_cb)(GaimPlugin *, void *) = NULL; | |
| 66 static void *unload_cb_data = NULL; | |
| 67 | |
| 68 #ifdef GAIM_PLUGINS | |
| 69 static int | |
| 70 is_so_file(const char *filename, const char *ext) | |
| 71 { | |
| 72 int len, extlen; | |
| 73 | |
| 74 if (filename == NULL || *filename == '\0' || ext == NULL) | |
| 75 return 0; | |
| 76 | |
| 77 extlen = strlen(ext); | |
| 78 len = strlen(filename) - extlen; | |
| 79 | |
| 80 if (len < 0) | |
| 81 return 0; | |
| 82 | |
| 83 return (!strncmp(filename + len, ext, extlen)); | |
| 84 } | |
| 85 | |
| 86 static gboolean | |
|
5794
5e93fc46d1af
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5646
diff
changeset
|
87 loader_supports_file(GaimPlugin *loader, const char *filename) |
| 5205 | 88 { |
| 6432 | 89 GList *exts; |
| 5205 | 90 |
| 6432 | 91 for (exts = GAIM_PLUGIN_LOADER_INFO(loader)->exts; exts != NULL; exts = exts->next) { |
| 92 if (is_so_file(filename, (char *)exts->data)) { | |
| 93 return TRUE; | |
| 5205 | 94 } |
| 95 } | |
| 96 | |
| 97 return FALSE; | |
| 98 } | |
| 99 | |
| 100 static GaimPlugin * | |
|
5794
5e93fc46d1af
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5646
diff
changeset
|
101 find_loader_for_plugin(const GaimPlugin *plugin) |
| 5205 | 102 { |
| 103 GaimPlugin *loader; | |
| 104 GList *l; | |
| 105 | |
| 106 if (plugin->path == NULL) | |
| 107 return NULL; | |
| 108 | |
| 109 for (l = gaim_plugins_get_loaded(); l != NULL; l = l->next) { | |
| 110 loader = l->data; | |
| 111 | |
| 112 if (loader->info->type == GAIM_PLUGIN_LOADER && | |
|
5794
5e93fc46d1af
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5646
diff
changeset
|
113 loader_supports_file(loader, plugin->path)) { |
| 5205 | 114 |
| 115 return loader; | |
| 116 } | |
| 117 | |
| 118 loader = NULL; | |
| 119 } | |
| 120 | |
| 121 return NULL; | |
| 122 } | |
| 123 | |
| 5449 | 124 #endif /* GAIM_PLUGINS */ |
| 125 | |
| 5205 | 126 static gint |
| 127 compare_prpl(GaimPlugin *a, GaimPlugin *b) | |
| 128 { | |
| 129 /* neg if a before b, 0 if equal, pos if a after b */ | |
| 130 return ((GAIM_IS_PROTOCOL_PLUGIN(a) | |
| 131 ? GAIM_PLUGIN_PROTOCOL_INFO(a)->protocol : -1) - | |
| 132 ((GAIM_IS_PROTOCOL_PLUGIN(b) | |
| 133 ? GAIM_PLUGIN_PROTOCOL_INFO(b)->protocol : -1))); | |
| 134 } | |
| 135 | |
| 136 GaimPlugin * | |
| 137 gaim_plugin_new(gboolean native, const char *path) | |
| 138 { | |
| 139 GaimPlugin *plugin; | |
| 140 | |
| 141 plugin = g_new0(GaimPlugin, 1); | |
| 142 | |
| 143 plugin->native_plugin = native; | |
| 144 plugin->path = (path == NULL ? NULL : g_strdup(path)); | |
| 145 | |
| 146 return plugin; | |
| 147 } | |
| 148 | |
| 149 GaimPlugin * | |
| 150 gaim_plugin_probe(const char *filename) | |
| 151 { | |
| 152 #ifdef GAIM_PLUGINS | |
| 153 GaimPlugin *plugin = NULL; | |
| 154 GaimPlugin *loader; | |
| 155 gboolean (*gaim_init_plugin)(GaimPlugin *); | |
| 156 | |
| 157 g_return_val_if_fail(filename != NULL, NULL); | |
| 158 | |
| 5973 | 159 if (!g_file_test(filename, G_FILE_TEST_EXISTS)) |
| 160 return NULL; | |
| 161 | |
| 5205 | 162 plugin = gaim_plugins_find_with_filename(filename); |
| 163 | |
| 164 if (plugin != NULL) | |
| 165 return plugin; | |
| 166 | |
| 167 plugin = gaim_plugin_new(is_so_file(filename, PLUGIN_EXT), filename); | |
| 168 | |
| 169 if (plugin->native_plugin) { | |
| 5450 | 170 const char *error; |
| 5205 | 171 plugin->handle = g_module_open(filename, 0); |
| 172 | |
| 173 if (plugin->handle == NULL) { | |
| 5443 | 174 error = g_module_error(); |
|
5269
cd7e4ba049f9
[gaim-migrate @ 5641]
Christian Hammond <chipx86@chipx86.com>
parents:
5268
diff
changeset
|
175 gaim_debug(GAIM_DEBUG_ERROR, "plugins", "%s is unloadable: %s\n", |
| 5443 | 176 plugin->path, error ? error : "Unknown error."); |
| 5205 | 177 |
|
5269
cd7e4ba049f9
[gaim-migrate @ 5641]
Christian Hammond <chipx86@chipx86.com>
parents:
5268
diff
changeset
|
178 gaim_plugin_destroy(plugin); |
|
cd7e4ba049f9
[gaim-migrate @ 5641]
Christian Hammond <chipx86@chipx86.com>
parents:
5268
diff
changeset
|
179 |
|
cd7e4ba049f9
[gaim-migrate @ 5641]
Christian Hammond <chipx86@chipx86.com>
parents:
5268
diff
changeset
|
180 return NULL; |
| 5205 | 181 } |
| 182 | |
| 183 if (!g_module_symbol(plugin->handle, "gaim_init_plugin", | |
| 184 (gpointer *)&gaim_init_plugin)) { | |
| 185 g_module_close(plugin->handle); | |
| 186 plugin->handle = NULL; | |
| 187 | |
| 5443 | 188 error = g_module_error(); |
|
5211
0241d6b6702d
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
189 gaim_debug(GAIM_DEBUG_ERROR, "plugins", "%s is unloadable: %s\n", |
| 5443 | 190 plugin->path, error ? error : "Unknown error."); |
| 5205 | 191 |
| 192 gaim_plugin_destroy(plugin); | |
| 193 | |
| 194 return NULL; | |
| 195 } | |
| 196 } | |
| 197 else { | |
|
5794
5e93fc46d1af
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5646
diff
changeset
|
198 loader = find_loader_for_plugin(plugin); |
| 5205 | 199 |
| 200 if (loader == NULL) { | |
| 201 gaim_plugin_destroy(plugin); | |
| 202 | |
| 203 return NULL; | |
| 204 } | |
| 205 | |
| 206 gaim_init_plugin = GAIM_PLUGIN_LOADER_INFO(loader)->probe; | |
| 207 } | |
| 208 | |
| 209 plugin->error = NULL; | |
| 210 | |
| 211 if (!gaim_init_plugin(plugin) || plugin->info == NULL) { | |
| 212 char buf[BUFSIZ]; | |
| 213 | |
| 214 g_snprintf(buf, sizeof(buf), | |
| 215 _("The plugin %s did not return any valid plugin " | |
| 216 "information"), | |
| 217 plugin->path); | |
| 218 | |
|
5436
ad445074d239
[gaim-migrate @ 5818]
Christian Hammond <chipx86@chipx86.com>
parents:
5357
diff
changeset
|
219 gaim_notify_error(NULL, NULL, |
|
ad445074d239
[gaim-migrate @ 5818]
Christian Hammond <chipx86@chipx86.com>
parents:
5357
diff
changeset
|
220 _("Gaim was unable to load your plugin."), buf); |
| 5205 | 221 |
| 222 gaim_plugin_destroy(plugin); | |
| 223 | |
| 224 return NULL; | |
| 225 } | |
| 226 | |
| 227 return plugin; | |
| 228 #else | |
| 229 return NULL; | |
| 230 #endif /* !GAIM_PLUGINS */ | |
| 231 } | |
| 232 | |
| 233 gboolean | |
| 234 gaim_plugin_load(GaimPlugin *plugin) | |
| 235 { | |
| 236 #ifdef GAIM_PLUGINS | |
| 237 g_return_val_if_fail(plugin != NULL, FALSE); | |
|
5270
d1fe8e320dab
[gaim-migrate @ 5642]
Christian Hammond <chipx86@chipx86.com>
parents:
5269
diff
changeset
|
238 g_return_val_if_fail(plugin->error == NULL, FALSE); |
| 5205 | 239 |
| 240 if (gaim_plugin_is_loaded(plugin)) | |
| 241 return TRUE; | |
| 242 | |
| 243 if (plugin->native_plugin) { | |
|
5357
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
244 if (plugin->info != NULL) { |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
245 if (plugin->info->load != NULL) |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
246 plugin->info->load(plugin); |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
247 } |
| 5205 | 248 } |
| 249 else { | |
| 250 GaimPlugin *loader; | |
| 251 GaimPluginLoaderInfo *loader_info; | |
| 252 | |
|
5794
5e93fc46d1af
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5646
diff
changeset
|
253 loader = find_loader_for_plugin(plugin); |
| 5205 | 254 |
| 255 if (loader == NULL) | |
| 256 return FALSE; | |
| 257 | |
| 258 loader_info = GAIM_PLUGIN_LOADER_INFO(loader); | |
| 259 | |
| 260 if (loader_info->load != NULL) | |
| 261 loader_info->load(plugin); | |
| 262 } | |
| 263 | |
| 264 loaded_plugins = g_list_append(loaded_plugins, plugin); | |
| 265 | |
| 266 plugin->loaded = TRUE; | |
| 267 | |
| 268 /* TODO */ | |
| 269 if (load_cb != NULL) | |
| 270 load_cb(plugin, load_cb_data); | |
| 271 | |
| 272 return TRUE; | |
| 273 | |
| 274 #else | |
| 5449 | 275 return TRUE; |
| 5205 | 276 #endif /* !GAIM_PLUGINS */ |
| 277 } | |
| 278 | |
| 279 gboolean | |
| 280 gaim_plugin_unload(GaimPlugin *plugin) | |
| 281 { | |
| 282 #ifdef GAIM_PLUGINS | |
| 283 g_return_val_if_fail(plugin != NULL, FALSE); | |
| 284 | |
| 285 loaded_plugins = g_list_remove(loaded_plugins, plugin); | |
| 286 | |
| 287 g_return_val_if_fail(gaim_plugin_is_loaded(plugin), FALSE); | |
| 288 | |
|
5211
0241d6b6702d
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
289 gaim_debug(GAIM_DEBUG_INFO, "plugins", "Unloading plugin %s\n", |
|
0241d6b6702d
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
290 plugin->info->name); |
| 5205 | 291 |
| 292 /* cancel any pending dialogs the plugin has */ | |
|
5498
cce2d7868c78
[gaim-migrate @ 5894]
Christian Hammond <chipx86@chipx86.com>
parents:
5450
diff
changeset
|
293 gaim_request_close_with_handle(plugin); |
|
cce2d7868c78
[gaim-migrate @ 5894]
Christian Hammond <chipx86@chipx86.com>
parents:
5450
diff
changeset
|
294 gaim_notify_close_with_handle(plugin); |
| 5205 | 295 |
| 296 plugin->loaded = FALSE; | |
| 297 | |
| 298 if (plugin->native_plugin) { | |
| 299 if (plugin->info->unload != NULL) | |
| 300 plugin->info->unload(plugin); | |
| 301 | |
| 302 if (plugin->info->type == GAIM_PLUGIN_PROTOCOL) { | |
| 303 GaimPluginProtocolInfo *prpl_info; | |
| 304 GList *l; | |
| 305 | |
| 306 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(plugin); | |
| 307 | |
|
5638
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5573
diff
changeset
|
308 for (l = prpl_info->user_splits; l != NULL; l = l->next) |
|
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5573
diff
changeset
|
309 gaim_account_user_split_destroy(l->data); |
| 5205 | 310 |
|
5638
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5573
diff
changeset
|
311 for (l = prpl_info->protocol_options; l != NULL; l = l->next) |
|
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5573
diff
changeset
|
312 gaim_account_option_destroy(l->data); |
| 5205 | 313 |
|
5646
48c63ee49961
[gaim-migrate @ 6060]
Christian Hammond <chipx86@chipx86.com>
parents:
5638
diff
changeset
|
314 if (prpl_info->user_splits != NULL) |
|
48c63ee49961
[gaim-migrate @ 6060]
Christian Hammond <chipx86@chipx86.com>
parents:
5638
diff
changeset
|
315 g_list_free(prpl_info->user_splits); |
|
48c63ee49961
[gaim-migrate @ 6060]
Christian Hammond <chipx86@chipx86.com>
parents:
5638
diff
changeset
|
316 |
|
48c63ee49961
[gaim-migrate @ 6060]
Christian Hammond <chipx86@chipx86.com>
parents:
5638
diff
changeset
|
317 if (prpl_info->protocol_options != NULL) |
|
48c63ee49961
[gaim-migrate @ 6060]
Christian Hammond <chipx86@chipx86.com>
parents:
5638
diff
changeset
|
318 g_list_free(prpl_info->protocol_options); |
| 5205 | 319 } |
| 320 } | |
| 321 else { | |
| 322 GaimPlugin *loader; | |
| 323 GaimPluginLoaderInfo *loader_info; | |
| 324 | |
|
5794
5e93fc46d1af
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5646
diff
changeset
|
325 loader = find_loader_for_plugin(plugin); |
| 5205 | 326 |
| 327 if (loader == NULL) | |
| 328 return FALSE; | |
| 329 | |
| 330 loader_info = GAIM_PLUGIN_LOADER_INFO(loader); | |
| 331 | |
| 332 if (loader_info->load != NULL) | |
| 333 loader_info->unload(plugin); | |
| 334 } | |
| 335 | |
| 336 gaim_signals_disconnect_by_handle(plugin); | |
| 337 | |
| 338 /* TODO */ | |
| 339 if (unload_cb != NULL) | |
| 340 unload_cb(plugin, unload_cb_data); | |
| 341 | |
| 342 return TRUE; | |
| 5449 | 343 #else |
| 344 return TRUE; | |
| 5205 | 345 #endif /* GAIM_PLUGINS */ |
| 346 } | |
| 347 | |
| 348 gboolean | |
| 349 gaim_plugin_reload(GaimPlugin *plugin) | |
| 350 { | |
| 351 #ifdef GAIM_PLUGINS | |
| 352 g_return_val_if_fail(plugin != NULL, FALSE); | |
| 353 g_return_val_if_fail(gaim_plugin_is_loaded(plugin), FALSE); | |
| 354 | |
| 355 if (!gaim_plugin_unload(plugin)) | |
| 356 return FALSE; | |
| 357 | |
| 358 if (!gaim_plugin_load(plugin)) | |
| 359 return FALSE; | |
| 360 | |
| 361 return TRUE; | |
| 362 #else | |
| 5449 | 363 return TRUE; |
| 5205 | 364 #endif /* !GAIM_PLUGINS */ |
| 365 } | |
| 366 | |
| 367 void | |
| 368 gaim_plugin_destroy(GaimPlugin *plugin) | |
| 369 { | |
| 5449 | 370 #ifdef GAIM_PLUGINS |
| 5205 | 371 g_return_if_fail(plugin != NULL); |
| 372 | |
| 373 if (gaim_plugin_is_loaded(plugin)) | |
| 374 gaim_plugin_unload(plugin); | |
| 375 | |
| 376 plugins = g_list_remove(plugins, plugin); | |
| 377 | |
|
5243
f6e0c689a88b
[gaim-migrate @ 5614]
Christian Hammond <chipx86@chipx86.com>
parents:
5242
diff
changeset
|
378 if (plugin->info != NULL && plugin->info->dependencies != NULL) |
|
f6e0c689a88b
[gaim-migrate @ 5614]
Christian Hammond <chipx86@chipx86.com>
parents:
5242
diff
changeset
|
379 g_list_free(plugin->info->dependencies); |
| 5205 | 380 |
| 381 if (plugin->native_plugin) { | |
| 382 | |
| 383 if (plugin->info != NULL && plugin->info->type == GAIM_PLUGIN_LOADER) { | |
| 384 GList *exts, *l, *next_l; | |
| 385 GaimPlugin *p2; | |
| 386 | |
| 387 for (exts = GAIM_PLUGIN_LOADER_INFO(plugin)->exts; | |
| 388 exts != NULL; | |
| 389 exts = exts->next) { | |
| 390 | |
| 391 for (l = gaim_plugins_get_all(); l != NULL; l = next_l) { | |
| 392 next_l = l->next; | |
| 393 | |
| 394 p2 = l->data; | |
| 395 | |
| 396 if (p2->path != NULL && is_so_file(p2->path, exts->data)) | |
| 397 gaim_plugin_destroy(p2); | |
| 398 } | |
| 399 } | |
| 400 | |
| 401 g_list_free(GAIM_PLUGIN_LOADER_INFO(plugin)->exts); | |
| 402 | |
| 403 plugin_loaders = g_list_remove(plugin_loaders, plugin); | |
| 404 } | |
| 405 | |
| 406 if (plugin->info != NULL && plugin->info->destroy != NULL) | |
| 407 plugin->info->destroy(plugin); | |
| 408 | |
| 409 if (plugin->handle != NULL) | |
| 410 g_module_close(plugin->handle); | |
| 411 } | |
| 412 else { | |
| 413 GaimPlugin *loader; | |
| 414 GaimPluginLoaderInfo *loader_info; | |
| 415 | |
|
5794
5e93fc46d1af
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5646
diff
changeset
|
416 loader = find_loader_for_plugin(plugin); |
| 5205 | 417 |
|
5941
a3e60ff95b7d
[gaim-migrate @ 6381]
Christian Hammond <chipx86@chipx86.com>
parents:
5872
diff
changeset
|
418 if (loader != NULL) { |
|
a3e60ff95b7d
[gaim-migrate @ 6381]
Christian Hammond <chipx86@chipx86.com>
parents:
5872
diff
changeset
|
419 loader_info = GAIM_PLUGIN_LOADER_INFO(loader); |
| 5205 | 420 |
|
5941
a3e60ff95b7d
[gaim-migrate @ 6381]
Christian Hammond <chipx86@chipx86.com>
parents:
5872
diff
changeset
|
421 if (loader_info->destroy != NULL) |
|
a3e60ff95b7d
[gaim-migrate @ 6381]
Christian Hammond <chipx86@chipx86.com>
parents:
5872
diff
changeset
|
422 loader_info->destroy(plugin); |
|
a3e60ff95b7d
[gaim-migrate @ 6381]
Christian Hammond <chipx86@chipx86.com>
parents:
5872
diff
changeset
|
423 } |
| 5205 | 424 } |
| 425 | |
| 426 if (plugin->path != NULL) g_free(plugin->path); | |
| 427 if (plugin->error != NULL) g_free(plugin->error); | |
| 428 | |
| 429 g_free(plugin); | |
| 5449 | 430 #endif /* !GAIM_PLUGINS */ |
| 5205 | 431 } |
| 432 | |
| 433 gboolean | |
| 434 gaim_plugin_is_loaded(const GaimPlugin *plugin) | |
| 435 { | |
| 436 g_return_val_if_fail(plugin != NULL, FALSE); | |
| 437 | |
| 438 return plugin->loaded; | |
| 439 } | |
| 440 | |
| 441 void | |
| 442 gaim_plugins_set_search_paths(size_t count, char **paths) | |
| 443 { | |
| 444 size_t s; | |
| 445 | |
| 446 g_return_if_fail(count > 0); | |
| 447 g_return_if_fail(paths != NULL); | |
| 448 | |
| 449 if (search_paths != NULL) { | |
| 450 for (s = 0; s < search_path_count; s++) | |
| 451 g_free(search_paths[s]); | |
| 452 | |
| 453 g_free(search_paths); | |
| 454 } | |
| 455 | |
| 456 search_paths = g_new0(char *, count); | |
| 457 | |
| 458 for (s = 0; s < count; s++) { | |
| 459 if (paths[s] == NULL) | |
| 460 search_paths[s] = NULL; | |
| 461 else | |
| 462 search_paths[s] = g_strdup(paths[s]); | |
| 463 } | |
| 464 | |
| 465 search_path_count = count; | |
| 466 } | |
| 467 | |
| 468 void | |
| 469 gaim_plugins_unload_all(void) | |
| 470 { | |
| 471 #ifdef GAIM_PLUGINS | |
| 472 | |
| 473 while (loaded_plugins != NULL) | |
| 474 gaim_plugin_unload(loaded_plugins->data); | |
| 475 | |
| 476 #endif /* GAIM_PLUGINS */ | |
| 477 } | |
| 478 | |
| 479 void | |
|
5242
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
480 gaim_plugins_destroy_all(void) |
|
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
481 { |
|
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
482 #ifdef GAIM_PLUGINS |
|
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
483 |
|
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
484 while (plugins != NULL) |
|
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
485 gaim_plugin_destroy(plugins->data); |
|
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
486 |
|
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
487 #endif /* GAIM_PLUGINS */ |
|
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
488 } |
| 5838 | 489 |
| 490 void | |
|
5949
90d0849abd3c
[gaim-migrate @ 6393]
Christian Hammond <chipx86@chipx86.com>
parents:
5941
diff
changeset
|
491 gaim_plugins_load_saved(const char *key) |
| 5838 | 492 { |
| 493 #ifdef GAIM_PLUGINS | |
|
5949
90d0849abd3c
[gaim-migrate @ 6393]
Christian Hammond <chipx86@chipx86.com>
parents:
5941
diff
changeset
|
494 GList *f, *files; |
|
90d0849abd3c
[gaim-migrate @ 6393]
Christian Hammond <chipx86@chipx86.com>
parents:
5941
diff
changeset
|
495 |
|
90d0849abd3c
[gaim-migrate @ 6393]
Christian Hammond <chipx86@chipx86.com>
parents:
5941
diff
changeset
|
496 g_return_if_fail(key != NULL); |
| 5838 | 497 |
|
5949
90d0849abd3c
[gaim-migrate @ 6393]
Christian Hammond <chipx86@chipx86.com>
parents:
5941
diff
changeset
|
498 files = gaim_prefs_get_string_list(key); |
|
90d0849abd3c
[gaim-migrate @ 6393]
Christian Hammond <chipx86@chipx86.com>
parents:
5941
diff
changeset
|
499 |
|
90d0849abd3c
[gaim-migrate @ 6393]
Christian Hammond <chipx86@chipx86.com>
parents:
5941
diff
changeset
|
500 for (f = files; f; f = f->next) { |
| 5838 | 501 gaim_plugin_load(gaim_plugin_probe(f->data)); |
| 502 g_free(f->data); | |
| 503 } | |
| 504 | |
| 505 g_list_free(files); | |
| 506 #endif /* GAIM_PLUGINS */ | |
| 507 } | |
| 508 | |
| 509 | |
|
5242
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
510 void |
| 5205 | 511 gaim_plugins_probe(const char *ext) |
| 512 { | |
| 513 #ifdef GAIM_PLUGINS | |
| 514 GDir *dir; | |
| 515 const gchar *file; | |
| 516 gchar *path; | |
| 517 GaimPlugin *plugin; | |
| 518 size_t i; | |
| 519 | |
| 520 if (!g_module_supported()) | |
| 521 return; | |
| 522 | |
| 523 for (i = 0; i < search_path_count; i++) { | |
| 524 if (search_paths[i] == NULL) | |
| 525 continue; | |
| 526 | |
| 527 dir = g_dir_open(search_paths[i], 0, NULL); | |
| 528 | |
| 529 if (dir != NULL) { | |
| 530 while ((file = g_dir_read_name(dir)) != NULL) { | |
| 531 path = g_build_filename(search_paths[i], file, NULL); | |
| 532 | |
| 533 if (ext == NULL || is_so_file(file, ext)) | |
| 534 plugin = gaim_plugin_probe(path); | |
| 535 | |
| 536 g_free(path); | |
| 537 } | |
| 538 | |
| 539 g_dir_close(dir); | |
| 540 } | |
| 541 } | |
| 542 | |
| 543 if (probe_cb != NULL) | |
| 544 probe_cb(probe_cb_data); | |
| 545 | |
| 546 #endif /* GAIM_PLUGINS */ | |
| 547 } | |
| 548 | |
| 549 gboolean | |
| 550 gaim_plugin_register(GaimPlugin *plugin) | |
| 551 { | |
| 552 g_return_val_if_fail(plugin != NULL, FALSE); | |
| 553 | |
| 554 if (g_list_find(plugins, plugin)) | |
| 555 return TRUE; | |
| 556 | |
| 557 /* Special exception for loader plugins. We want them loaded NOW! */ | |
| 558 if (plugin->info->type == GAIM_PLUGIN_LOADER) { | |
| 559 GList *exts; | |
| 560 | |
| 561 /* We'll just load this right now. */ | |
| 562 if (!gaim_plugin_load(plugin)) { | |
| 563 | |
| 564 gaim_plugin_destroy(plugin); | |
| 565 | |
| 566 return FALSE; | |
| 567 } | |
| 568 | |
| 569 plugin_loaders = g_list_append(plugin_loaders, plugin); | |
| 570 | |
| 571 for (exts = GAIM_PLUGIN_LOADER_INFO(plugin)->exts; | |
| 572 exts != NULL; | |
| 573 exts = exts->next) { | |
| 574 | |
| 575 gaim_plugins_probe(exts->data); | |
| 576 } | |
| 577 } | |
| 578 else if (plugin->info->type == GAIM_PLUGIN_PROTOCOL) { | |
| 579 | |
| 580 /* We'll just load this right now. */ | |
| 581 if (!gaim_plugin_load(plugin)) { | |
| 582 | |
| 583 gaim_plugin_destroy(plugin); | |
| 584 | |
| 585 return FALSE; | |
| 586 } | |
| 587 | |
| 588 if (GAIM_PLUGIN_PROTOCOL_INFO(plugin)->protocol == GAIM_PROTO_ICQ || | |
| 589 gaim_find_prpl(GAIM_PLUGIN_PROTOCOL_INFO(plugin)->protocol)) { | |
| 590 | |
| 591 /* Nothing to see here--move along, move along */ | |
| 592 gaim_plugin_destroy(plugin); | |
| 593 | |
| 594 return FALSE; | |
| 595 } | |
| 596 | |
|
5573
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
597 protocol_plugins = g_list_insert_sorted(protocol_plugins, plugin, |
|
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
598 (GCompareFunc)compare_prpl); |
| 5205 | 599 } |
| 600 | |
| 601 plugins = g_list_append(plugins, plugin); | |
| 602 | |
| 603 return TRUE; | |
| 604 } | |
| 605 | |
| 606 gboolean | |
| 607 gaim_plugins_enabled(void) | |
| 608 { | |
| 609 #ifdef GAIM_PLUGINS | |
| 610 return TRUE; | |
| 611 #else | |
| 612 return FALSE; | |
| 613 #endif | |
| 614 } | |
| 615 | |
| 616 void | |
| 617 gaim_plugins_register_probe_notify_cb(void (*func)(void *), void *data) | |
| 618 { | |
| 619 /* TODO */ | |
| 620 probe_cb = func; | |
| 621 probe_cb_data = data; | |
| 622 } | |
| 623 | |
| 624 void | |
| 625 gaim_plugins_unregister_probe_notify_cb(void (*func)(void *)) | |
| 626 { | |
| 627 /* TODO */ | |
| 628 probe_cb = NULL; | |
| 629 probe_cb_data = NULL; | |
| 630 } | |
| 631 | |
| 632 void | |
| 633 gaim_plugins_register_load_notify_cb(void (*func)(GaimPlugin *, void *), | |
| 634 void *data) | |
| 635 { | |
| 636 /* TODO */ | |
| 637 load_cb = func; | |
| 638 load_cb_data = data; | |
| 639 } | |
| 640 | |
| 641 void | |
| 642 gaim_plugins_unregister_load_notify_cb(void (*func)(GaimPlugin *, void *)) | |
| 643 { | |
| 644 /* TODO */ | |
| 645 load_cb = NULL; | |
| 646 load_cb_data = NULL; | |
| 647 } | |
| 648 | |
| 649 void | |
| 650 gaim_plugins_register_unload_notify_cb(void (*func)(GaimPlugin *, void *), | |
| 651 void *data) | |
| 652 { | |
| 653 /* TODO */ | |
| 654 unload_cb = func; | |
| 655 unload_cb_data = data; | |
| 656 } | |
| 657 | |
| 658 void | |
| 659 gaim_plugins_unregister_unload_notify_cb(void (*func)(GaimPlugin *, void *)) | |
| 660 { | |
| 661 /* TODO */ | |
| 662 unload_cb = NULL; | |
| 663 unload_cb_data = NULL; | |
| 664 } | |
| 665 | |
| 666 GaimPlugin * | |
| 667 gaim_plugins_find_with_name(const char *name) | |
| 668 { | |
| 669 GaimPlugin *plugin; | |
| 670 GList *l; | |
| 671 | |
| 672 for (l = plugins; l != NULL; l = l->next) { | |
| 673 plugin = l->data; | |
| 674 | |
| 675 if (!strcmp(plugin->info->name, name)) | |
| 676 return plugin; | |
| 677 } | |
| 678 | |
| 679 return NULL; | |
| 680 } | |
| 681 | |
| 682 GaimPlugin * | |
| 683 gaim_plugins_find_with_filename(const char *filename) | |
| 684 { | |
| 685 GaimPlugin *plugin; | |
| 686 GList *l; | |
| 687 | |
| 688 for (l = plugins; l != NULL; l = l->next) { | |
| 689 plugin = l->data; | |
| 690 | |
| 691 if (plugin->path != NULL && !strcmp(plugin->path, filename)) | |
| 692 return plugin; | |
| 693 } | |
| 694 | |
| 695 return NULL; | |
| 696 } | |
| 697 | |
| 698 GaimPlugin * | |
| 699 gaim_plugins_find_with_id(const char *id) | |
| 700 { | |
| 701 GaimPlugin *plugin; | |
| 702 GList *l; | |
| 703 | |
| 704 g_return_val_if_fail(id != NULL, NULL); | |
| 705 | |
| 706 for (l = plugins; l != NULL; l = l->next) { | |
| 707 plugin = l->data; | |
| 708 | |
| 709 if (!strcmp(plugin->info->id, id)) | |
| 710 return plugin; | |
| 711 } | |
| 712 | |
| 713 return NULL; | |
| 714 } | |
| 715 | |
| 716 GList * | |
| 717 gaim_plugins_get_loaded(void) | |
| 718 { | |
| 719 return loaded_plugins; | |
| 720 } | |
| 721 | |
| 722 GList * | |
|
5573
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
723 gaim_plugins_get_protocols(void) |
|
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
724 { |
|
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
725 return protocol_plugins; |
|
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
726 } |
|
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
727 |
|
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
728 GList * |
| 5205 | 729 gaim_plugins_get_all(void) |
| 730 { | |
| 731 return plugins; | |
| 732 } | |
| 733 |
