Tue, 27 May 2003 03:38:52 +0000
[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
| 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
a0e0bacaa196
[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
4c350eb7d4a0
[gaim-migrate @ 5836]
Decklin Foster <decklin@red-bean.com>
parents:
5443
diff
changeset
|
143 | #endif /* GAIM_PLUGINS */ |
|
4c350eb7d4a0
[gaim-migrate @ 5836]
Decklin Foster <decklin@red-bean.com>
parents:
5443
diff
changeset
|
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
a318feccd844
[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
a318feccd844
[gaim-migrate @ 5641]
Christian Hammond <chipx86@chipx86.com>
parents:
5268
diff
changeset
|
194 | gaim_plugin_destroy(plugin); |
|
a318feccd844
[gaim-migrate @ 5641]
Christian Hammond <chipx86@chipx86.com>
parents:
5268
diff
changeset
|
195 | |
|
a318feccd844
[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
94d9756c381f
[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
a0e0bacaa196
[gaim-migrate @ 5818]
Christian Hammond <chipx86@chipx86.com>
parents:
5357
diff
changeset
|
235 | gaim_notify_error(NULL, NULL, |
|
a0e0bacaa196
[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
74286f7fb991
[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
1fa9e57df50c
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
260 | if (plugin->info != NULL) { |
|
1fa9e57df50c
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
261 | if (plugin->info->load != NULL) |
|
1fa9e57df50c
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
262 | plugin->info->load(plugin); |
|
1fa9e57df50c
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
263 | |
|
1fa9e57df50c
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
264 | if (plugin->info->type == GAIM_PLUGIN_LOADER) { |
|
1fa9e57df50c
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
265 | GaimPluginLoaderInfo *loader_info; |
|
1fa9e57df50c
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
266 | |
|
1fa9e57df50c
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
267 | loader_info = GAIM_PLUGIN_LOADER_INFO(plugin); |
|
1fa9e57df50c
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
268 | |
|
1fa9e57df50c
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
269 | if (loader_info->broadcast != NULL) |
|
1fa9e57df50c
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
270 | gaim_signals_register_broadcast_func(loader_info->broadcast, |
|
1fa9e57df50c
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
271 | NULL); |
|
1fa9e57df50c
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
272 | } |
|
1fa9e57df50c
[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
4c350eb7d4a0
[gaim-migrate @ 5836]
Decklin Foster <decklin@red-bean.com>
parents:
5443
diff
changeset
|
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
94d9756c381f
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
315 | gaim_debug(GAIM_DEBUG_INFO, "plugins", "Unloading plugin %s\n", |
|
94d9756c381f
[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
01eec144d71b
[gaim-migrate @ 5894]
Christian Hammond <chipx86@chipx86.com>
parents:
5450
diff
changeset
|
319 | gaim_request_close_with_handle(plugin); |
|
01eec144d71b
[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
1fa9e57df50c
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
356 | else if (plugin->info->type == GAIM_PLUGIN_LOADER) { |
|
1fa9e57df50c
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
357 | GaimPluginLoaderInfo *loader_info; |
|
1fa9e57df50c
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
358 | |
|
1fa9e57df50c
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
359 | loader_info = GAIM_PLUGIN_LOADER_INFO(plugin); |
|
1fa9e57df50c
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
360 | |
|
1fa9e57df50c
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
361 | if (loader_info->broadcast != NULL) |
|
1fa9e57df50c
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
362 | gaim_signals_unregister_broadcast_func(loader_info->broadcast); |
|
1fa9e57df50c
[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
4c350eb7d4a0
[gaim-migrate @ 5836]
Decklin Foster <decklin@red-bean.com>
parents:
5443
diff
changeset
|
387 | #else |
|
4c350eb7d4a0
[gaim-migrate @ 5836]
Decklin Foster <decklin@red-bean.com>
parents:
5443
diff
changeset
|
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
4c350eb7d4a0
[gaim-migrate @ 5836]
Decklin Foster <decklin@red-bean.com>
parents:
5443
diff
changeset
|
407 | return TRUE; |
| 5205 | 408 | #endif /* !GAIM_PLUGINS */ |
| 409 | } | |
| 410 | ||
| 411 | void | |
| 412 | gaim_plugin_destroy(GaimPlugin *plugin) | |
| 413 | { | |
|
5449
4c350eb7d4a0
[gaim-migrate @ 5836]
Decklin Foster <decklin@red-bean.com>
parents:
5443
diff
changeset
|
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
e8d35a430c6d
[gaim-migrate @ 5614]
Christian Hammond <chipx86@chipx86.com>
parents:
5242
diff
changeset
|
422 | if (plugin->info != NULL && plugin->info->dependencies != NULL) |
|
e8d35a430c6d
[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
4c350eb7d4a0
[gaim-migrate @ 5836]
Decklin Foster <decklin@red-bean.com>
parents:
5443
diff
changeset
|
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
155da5e9bbf0
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
525 | gaim_plugins_destroy_all(void) |
|
155da5e9bbf0
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
526 | { |
|
155da5e9bbf0
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
527 | #ifdef GAIM_PLUGINS |
|
155da5e9bbf0
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
528 | |
|
155da5e9bbf0
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
529 | while (plugins != NULL) |
|
155da5e9bbf0
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
530 | gaim_plugin_destroy(plugins->data); |
|
155da5e9bbf0
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
531 | |
|
155da5e9bbf0
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
532 | #endif /* GAIM_PLUGINS */ |
|
155da5e9bbf0
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
533 | } |
|
155da5e9bbf0
[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 |