Mercurial > pidgin
annotate src/plugin.c @ 5786:f8bee920b14e
[gaim-migrate @ 6211]
Matthew Hall (mthz) writes:
" In server.c, "plugin_event(event_buddy_idle, gc,
b->name);" gets fired to the plugins BEFORE the call to
"gaim_blist_update_buddy_idle(b, idle);" is made a few
lines later to update the the buddy struct's idle
member. So, if a plugin catches event_buddy_idle and
attempts to figure out the buddy's idle time, it will
not be correct (in some cases when one first signs on,
it will even be completely blank, as it is still
zeroed). As far as I can tell, there is nothing wrong
with reversing the order of the calls. Attached to
this is a patch for the latest CVS... as of 4-9-03 Noon."
because he put the patch in the bugs tracker, it took me this long to find
it. patches should be in the patch tracker.
committer: Tailor Script <tailor@pidgin.im>
| author | Luke Schierer <lschiere@pidgin.im> |
|---|---|
| date | Sat, 07 Jun 2003 03:42:16 +0000 |
| parents | 48c63ee49961 |
| children | 5e93fc46d1af |
| 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" | |
|
5638
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5573
diff
changeset
|
43 #include "accountopt.h" |
| 5205 | 44 #include "prpl.h" |
| 45 #include "event.h" | |
|
5436
ad445074d239
[gaim-migrate @ 5818]
Christian Hammond <chipx86@chipx86.com>
parents:
5357
diff
changeset
|
46 #include "notify.h" |
| 5205 | 47 |
| 48 #include <string.h> | |
| 49 | |
| 50 #include <sys/types.h> | |
| 51 #include <sys/stat.h> | |
| 52 | |
| 53 #include <unistd.h> | |
| 54 #include <stdio.h> | |
| 55 #include <stdlib.h> | |
| 56 | |
| 57 #ifdef _WIN32 | |
| 58 #include "win32dep.h" | |
| 59 #endif | |
| 60 | |
| 61 #ifdef _WIN32 | |
| 62 # define PLUGIN_EXT ".dll" | |
| 63 #else | |
| 64 # define PLUGIN_EXT ".so" | |
| 65 #endif | |
| 66 | |
| 67 static GList *loaded_plugins = NULL; | |
| 68 static GList *plugins = NULL; | |
| 69 static GList *plugin_loaders = NULL; | |
|
5573
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
70 static GList *protocol_plugins = NULL; |
| 5205 | 71 |
| 72 static size_t search_path_count = 0; | |
| 73 static char **search_paths = NULL; | |
| 74 | |
| 75 static void (*probe_cb)(void *) = NULL; | |
| 76 static void *probe_cb_data = NULL; | |
| 77 static void (*load_cb)(GaimPlugin *, void *) = NULL; | |
| 78 static void *load_cb_data = NULL; | |
| 79 static void (*unload_cb)(GaimPlugin *, void *) = NULL; | |
| 80 static void *unload_cb_data = NULL; | |
| 81 | |
| 82 #ifdef GAIM_PLUGINS | |
| 83 static int | |
| 84 is_so_file(const char *filename, const char *ext) | |
| 85 { | |
| 86 int len, extlen; | |
| 87 | |
| 88 if (filename == NULL || *filename == '\0' || ext == NULL) | |
| 89 return 0; | |
| 90 | |
| 91 extlen = strlen(ext); | |
| 92 len = strlen(filename) - extlen; | |
| 93 | |
| 94 if (len < 0) | |
| 95 return 0; | |
| 96 | |
| 97 return (!strncmp(filename + len, ext, extlen)); | |
| 98 } | |
| 99 | |
| 100 static gboolean | |
| 101 __loader_supports_file(GaimPlugin *loader, const char *filename) | |
| 102 { | |
| 103 GList *l, *exts; | |
| 104 GaimPlugin *plugin; | |
| 105 | |
| 106 for (l = plugin_loaders; l != NULL; l = l->next) { | |
| 107 plugin = l->data; | |
| 108 | |
| 109 for (exts = GAIM_PLUGIN_LOADER_INFO(plugin)->exts; | |
| 110 exts != NULL; | |
| 111 exts = exts->next) { | |
| 112 | |
| 113 if (is_so_file(filename, (char *)exts->data)) | |
| 114 return TRUE; | |
| 115 } | |
| 116 } | |
| 117 | |
| 118 return FALSE; | |
| 119 } | |
| 120 | |
| 121 static GaimPlugin * | |
| 122 __find_loader_for_plugin(const GaimPlugin *plugin) | |
| 123 { | |
| 124 GaimPlugin *loader; | |
| 125 GList *l; | |
| 126 | |
| 127 if (plugin->path == NULL) | |
| 128 return NULL; | |
| 129 | |
| 130 for (l = gaim_plugins_get_loaded(); l != NULL; l = l->next) { | |
| 131 loader = l->data; | |
| 132 | |
| 133 if (loader->info->type == GAIM_PLUGIN_LOADER && | |
| 134 __loader_supports_file(loader, plugin->path)) { | |
| 135 | |
| 136 return loader; | |
| 137 } | |
| 138 | |
| 139 loader = NULL; | |
| 140 } | |
| 141 | |
| 142 return NULL; | |
| 143 } | |
| 144 | |
| 5449 | 145 #endif /* GAIM_PLUGINS */ |
| 146 | |
| 5205 | 147 static gint |
| 148 compare_prpl(GaimPlugin *a, GaimPlugin *b) | |
| 149 { | |
| 150 /* neg if a before b, 0 if equal, pos if a after b */ | |
| 151 return ((GAIM_IS_PROTOCOL_PLUGIN(a) | |
| 152 ? GAIM_PLUGIN_PROTOCOL_INFO(a)->protocol : -1) - | |
| 153 ((GAIM_IS_PROTOCOL_PLUGIN(b) | |
| 154 ? GAIM_PLUGIN_PROTOCOL_INFO(b)->protocol : -1))); | |
| 155 } | |
| 156 | |
| 157 GaimPlugin * | |
| 158 gaim_plugin_new(gboolean native, const char *path) | |
| 159 { | |
| 160 GaimPlugin *plugin; | |
| 161 | |
| 162 plugin = g_new0(GaimPlugin, 1); | |
| 163 | |
| 164 plugin->native_plugin = native; | |
| 165 plugin->path = (path == NULL ? NULL : g_strdup(path)); | |
| 166 | |
| 167 return plugin; | |
| 168 } | |
| 169 | |
| 170 GaimPlugin * | |
| 171 gaim_plugin_probe(const char *filename) | |
| 172 { | |
| 173 #ifdef GAIM_PLUGINS | |
| 174 GaimPlugin *plugin = NULL; | |
| 175 GaimPlugin *loader; | |
| 176 gboolean (*gaim_init_plugin)(GaimPlugin *); | |
| 177 | |
| 178 g_return_val_if_fail(filename != NULL, NULL); | |
| 179 | |
| 180 plugin = gaim_plugins_find_with_filename(filename); | |
| 181 | |
| 182 if (plugin != NULL) | |
| 183 return plugin; | |
| 184 | |
| 185 plugin = gaim_plugin_new(is_so_file(filename, PLUGIN_EXT), filename); | |
| 186 | |
| 187 if (plugin->native_plugin) { | |
| 5450 | 188 const char *error; |
| 5205 | 189 plugin->handle = g_module_open(filename, 0); |
| 190 | |
| 191 if (plugin->handle == NULL) { | |
| 5443 | 192 error = g_module_error(); |
|
5269
cd7e4ba049f9
[gaim-migrate @ 5641]
Christian Hammond <chipx86@chipx86.com>
parents:
5268
diff
changeset
|
193 gaim_debug(GAIM_DEBUG_ERROR, "plugins", "%s is unloadable: %s\n", |
| 5443 | 194 plugin->path, error ? error : "Unknown error."); |
| 5205 | 195 |
|
5269
cd7e4ba049f9
[gaim-migrate @ 5641]
Christian Hammond <chipx86@chipx86.com>
parents:
5268
diff
changeset
|
196 gaim_plugin_destroy(plugin); |
|
cd7e4ba049f9
[gaim-migrate @ 5641]
Christian Hammond <chipx86@chipx86.com>
parents:
5268
diff
changeset
|
197 |
|
cd7e4ba049f9
[gaim-migrate @ 5641]
Christian Hammond <chipx86@chipx86.com>
parents:
5268
diff
changeset
|
198 return NULL; |
| 5205 | 199 } |
| 200 | |
| 201 if (!g_module_symbol(plugin->handle, "gaim_init_plugin", | |
| 202 (gpointer *)&gaim_init_plugin)) { | |
| 203 g_module_close(plugin->handle); | |
| 204 plugin->handle = NULL; | |
| 205 | |
| 5443 | 206 error = g_module_error(); |
|
5211
0241d6b6702d
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
207 gaim_debug(GAIM_DEBUG_ERROR, "plugins", "%s is unloadable: %s\n", |
| 5443 | 208 plugin->path, error ? error : "Unknown error."); |
| 5205 | 209 |
| 210 gaim_plugin_destroy(plugin); | |
| 211 | |
| 212 return NULL; | |
| 213 } | |
| 214 } | |
| 215 else { | |
| 216 loader = __find_loader_for_plugin(plugin); | |
| 217 | |
| 218 if (loader == NULL) { | |
| 219 gaim_plugin_destroy(plugin); | |
| 220 | |
| 221 return NULL; | |
| 222 } | |
| 223 | |
| 224 gaim_init_plugin = GAIM_PLUGIN_LOADER_INFO(loader)->probe; | |
| 225 } | |
| 226 | |
| 227 plugin->error = NULL; | |
| 228 | |
| 229 if (!gaim_init_plugin(plugin) || plugin->info == NULL) { | |
| 230 char buf[BUFSIZ]; | |
| 231 | |
| 232 g_snprintf(buf, sizeof(buf), | |
| 233 _("The plugin %s did not return any valid plugin " | |
| 234 "information"), | |
| 235 plugin->path); | |
| 236 | |
|
5436
ad445074d239
[gaim-migrate @ 5818]
Christian Hammond <chipx86@chipx86.com>
parents:
5357
diff
changeset
|
237 gaim_notify_error(NULL, NULL, |
|
ad445074d239
[gaim-migrate @ 5818]
Christian Hammond <chipx86@chipx86.com>
parents:
5357
diff
changeset
|
238 _("Gaim was unable to load your plugin."), buf); |
| 5205 | 239 |
| 240 gaim_plugin_destroy(plugin); | |
| 241 | |
| 242 return NULL; | |
| 243 } | |
| 244 | |
| 245 return plugin; | |
| 246 #else | |
| 247 return NULL; | |
| 248 #endif /* !GAIM_PLUGINS */ | |
| 249 } | |
| 250 | |
| 251 gboolean | |
| 252 gaim_plugin_load(GaimPlugin *plugin) | |
| 253 { | |
| 254 #ifdef GAIM_PLUGINS | |
| 255 g_return_val_if_fail(plugin != NULL, FALSE); | |
|
5270
d1fe8e320dab
[gaim-migrate @ 5642]
Christian Hammond <chipx86@chipx86.com>
parents:
5269
diff
changeset
|
256 g_return_val_if_fail(plugin->error == NULL, FALSE); |
| 5205 | 257 |
| 258 if (gaim_plugin_is_loaded(plugin)) | |
| 259 return TRUE; | |
| 260 | |
| 261 if (plugin->native_plugin) { | |
|
5357
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
262 if (plugin->info != NULL) { |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
263 if (plugin->info->load != NULL) |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
264 plugin->info->load(plugin); |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
265 |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
266 if (plugin->info->type == GAIM_PLUGIN_LOADER) { |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
267 GaimPluginLoaderInfo *loader_info; |
|
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 loader_info = GAIM_PLUGIN_LOADER_INFO(plugin); |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
270 |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
271 if (loader_info->broadcast != NULL) |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
272 gaim_signals_register_broadcast_func(loader_info->broadcast, |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
273 NULL); |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
274 } |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
275 } |
| 5205 | 276 } |
| 277 else { | |
| 278 GaimPlugin *loader; | |
| 279 GaimPluginLoaderInfo *loader_info; | |
| 280 | |
| 281 loader = __find_loader_for_plugin(plugin); | |
| 282 | |
| 283 if (loader == NULL) | |
| 284 return FALSE; | |
| 285 | |
| 286 loader_info = GAIM_PLUGIN_LOADER_INFO(loader); | |
| 287 | |
| 288 if (loader_info->load != NULL) | |
| 289 loader_info->load(plugin); | |
| 290 } | |
| 291 | |
| 292 loaded_plugins = g_list_append(loaded_plugins, plugin); | |
| 293 | |
| 294 plugin->loaded = TRUE; | |
| 295 | |
| 296 /* TODO */ | |
| 297 if (load_cb != NULL) | |
| 298 load_cb(plugin, load_cb_data); | |
| 299 | |
| 300 return TRUE; | |
| 301 | |
| 302 #else | |
| 5449 | 303 return TRUE; |
| 5205 | 304 #endif /* !GAIM_PLUGINS */ |
| 305 } | |
| 306 | |
| 307 gboolean | |
| 308 gaim_plugin_unload(GaimPlugin *plugin) | |
| 309 { | |
| 310 #ifdef GAIM_PLUGINS | |
| 311 g_return_val_if_fail(plugin != NULL, FALSE); | |
| 312 | |
| 313 loaded_plugins = g_list_remove(loaded_plugins, plugin); | |
| 314 | |
| 315 g_return_val_if_fail(gaim_plugin_is_loaded(plugin), FALSE); | |
| 316 | |
|
5211
0241d6b6702d
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
317 gaim_debug(GAIM_DEBUG_INFO, "plugins", "Unloading plugin %s\n", |
|
0241d6b6702d
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
318 plugin->info->name); |
| 5205 | 319 |
| 320 /* cancel any pending dialogs the plugin has */ | |
|
5498
cce2d7868c78
[gaim-migrate @ 5894]
Christian Hammond <chipx86@chipx86.com>
parents:
5450
diff
changeset
|
321 gaim_request_close_with_handle(plugin); |
|
cce2d7868c78
[gaim-migrate @ 5894]
Christian Hammond <chipx86@chipx86.com>
parents:
5450
diff
changeset
|
322 gaim_notify_close_with_handle(plugin); |
| 5205 | 323 |
| 324 plugin->loaded = FALSE; | |
| 325 | |
| 326 if (plugin->native_plugin) { | |
| 327 if (plugin->info->unload != NULL) | |
| 328 plugin->info->unload(plugin); | |
| 329 | |
| 330 if (plugin->info->type == GAIM_PLUGIN_PROTOCOL) { | |
| 331 GaimPluginProtocolInfo *prpl_info; | |
| 332 GList *l; | |
| 333 | |
| 334 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(plugin); | |
| 335 | |
|
5638
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5573
diff
changeset
|
336 for (l = prpl_info->user_splits; l != NULL; l = l->next) |
|
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5573
diff
changeset
|
337 gaim_account_user_split_destroy(l->data); |
| 5205 | 338 |
|
5638
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5573
diff
changeset
|
339 for (l = prpl_info->protocol_options; l != NULL; l = l->next) |
|
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5573
diff
changeset
|
340 gaim_account_option_destroy(l->data); |
| 5205 | 341 |
|
5646
48c63ee49961
[gaim-migrate @ 6060]
Christian Hammond <chipx86@chipx86.com>
parents:
5638
diff
changeset
|
342 if (prpl_info->user_splits != NULL) |
|
48c63ee49961
[gaim-migrate @ 6060]
Christian Hammond <chipx86@chipx86.com>
parents:
5638
diff
changeset
|
343 g_list_free(prpl_info->user_splits); |
|
48c63ee49961
[gaim-migrate @ 6060]
Christian Hammond <chipx86@chipx86.com>
parents:
5638
diff
changeset
|
344 |
|
48c63ee49961
[gaim-migrate @ 6060]
Christian Hammond <chipx86@chipx86.com>
parents:
5638
diff
changeset
|
345 if (prpl_info->protocol_options != NULL) |
|
48c63ee49961
[gaim-migrate @ 6060]
Christian Hammond <chipx86@chipx86.com>
parents:
5638
diff
changeset
|
346 g_list_free(prpl_info->protocol_options); |
| 5205 | 347 } |
|
5357
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
348 else if (plugin->info->type == GAIM_PLUGIN_LOADER) { |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
349 GaimPluginLoaderInfo *loader_info; |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
350 |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
351 loader_info = GAIM_PLUGIN_LOADER_INFO(plugin); |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
352 |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
353 if (loader_info->broadcast != NULL) |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
354 gaim_signals_unregister_broadcast_func(loader_info->broadcast); |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
355 } |
| 5205 | 356 } |
| 357 else { | |
| 358 GaimPlugin *loader; | |
| 359 GaimPluginLoaderInfo *loader_info; | |
| 360 | |
| 361 loader = __find_loader_for_plugin(plugin); | |
| 362 | |
| 363 if (loader == NULL) | |
| 364 return FALSE; | |
| 365 | |
| 366 loader_info = GAIM_PLUGIN_LOADER_INFO(loader); | |
| 367 | |
| 368 if (loader_info->load != NULL) | |
| 369 loader_info->unload(plugin); | |
| 370 } | |
| 371 | |
| 372 gaim_signals_disconnect_by_handle(plugin); | |
| 373 | |
| 374 /* TODO */ | |
| 375 if (unload_cb != NULL) | |
| 376 unload_cb(plugin, unload_cb_data); | |
| 377 | |
| 378 return TRUE; | |
| 5449 | 379 #else |
| 380 return TRUE; | |
| 5205 | 381 #endif /* GAIM_PLUGINS */ |
| 382 } | |
| 383 | |
| 384 gboolean | |
| 385 gaim_plugin_reload(GaimPlugin *plugin) | |
| 386 { | |
| 387 #ifdef GAIM_PLUGINS | |
| 388 g_return_val_if_fail(plugin != NULL, FALSE); | |
| 389 g_return_val_if_fail(gaim_plugin_is_loaded(plugin), FALSE); | |
| 390 | |
| 391 if (!gaim_plugin_unload(plugin)) | |
| 392 return FALSE; | |
| 393 | |
| 394 if (!gaim_plugin_load(plugin)) | |
| 395 return FALSE; | |
| 396 | |
| 397 return TRUE; | |
| 398 #else | |
| 5449 | 399 return TRUE; |
| 5205 | 400 #endif /* !GAIM_PLUGINS */ |
| 401 } | |
| 402 | |
| 403 void | |
| 404 gaim_plugin_destroy(GaimPlugin *plugin) | |
| 405 { | |
| 5449 | 406 #ifdef GAIM_PLUGINS |
| 5205 | 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); | |
| 5449 | 467 #endif /* !GAIM_PLUGINS */ |
| 5205 | 468 } |
| 469 | |
| 470 gboolean | |
| 471 gaim_plugin_is_loaded(const GaimPlugin *plugin) | |
| 472 { | |
| 473 g_return_val_if_fail(plugin != NULL, FALSE); | |
| 474 | |
| 475 return plugin->loaded; | |
| 476 } | |
| 477 | |
| 478 void | |
| 479 gaim_plugins_set_search_paths(size_t count, char **paths) | |
| 480 { | |
| 481 size_t s; | |
| 482 | |
| 483 g_return_if_fail(count > 0); | |
| 484 g_return_if_fail(paths != NULL); | |
| 485 | |
| 486 if (search_paths != NULL) { | |
| 487 for (s = 0; s < search_path_count; s++) | |
| 488 g_free(search_paths[s]); | |
| 489 | |
| 490 g_free(search_paths); | |
| 491 } | |
| 492 | |
| 493 search_paths = g_new0(char *, count); | |
| 494 | |
| 495 for (s = 0; s < count; s++) { | |
| 496 if (paths[s] == NULL) | |
| 497 search_paths[s] = NULL; | |
| 498 else | |
| 499 search_paths[s] = g_strdup(paths[s]); | |
| 500 } | |
| 501 | |
| 502 search_path_count = count; | |
| 503 } | |
| 504 | |
| 505 void | |
| 506 gaim_plugins_unload_all(void) | |
| 507 { | |
| 508 #ifdef GAIM_PLUGINS | |
| 509 | |
| 510 while (loaded_plugins != NULL) | |
| 511 gaim_plugin_unload(loaded_plugins->data); | |
| 512 | |
| 513 #endif /* GAIM_PLUGINS */ | |
| 514 } | |
| 515 | |
| 516 void | |
|
5242
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
517 gaim_plugins_destroy_all(void) |
|
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
518 { |
|
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
519 #ifdef GAIM_PLUGINS |
|
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
520 |
|
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
521 while (plugins != NULL) |
|
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
522 gaim_plugin_destroy(plugins->data); |
|
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
523 |
|
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
524 #endif /* GAIM_PLUGINS */ |
|
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
525 } |
|
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
526 void |
| 5205 | 527 gaim_plugins_probe(const char *ext) |
| 528 { | |
| 529 #ifdef GAIM_PLUGINS | |
| 530 GDir *dir; | |
| 531 const gchar *file; | |
| 532 gchar *path; | |
| 533 GaimPlugin *plugin; | |
| 534 size_t i; | |
| 535 | |
| 536 if (!g_module_supported()) | |
| 537 return; | |
| 538 | |
| 539 for (i = 0; i < search_path_count; i++) { | |
| 540 if (search_paths[i] == NULL) | |
| 541 continue; | |
| 542 | |
| 543 dir = g_dir_open(search_paths[i], 0, NULL); | |
| 544 | |
| 545 if (dir != NULL) { | |
| 546 while ((file = g_dir_read_name(dir)) != NULL) { | |
| 547 path = g_build_filename(search_paths[i], file, NULL); | |
| 548 | |
| 549 if (ext == NULL || is_so_file(file, ext)) | |
| 550 plugin = gaim_plugin_probe(path); | |
| 551 | |
| 552 g_free(path); | |
| 553 } | |
| 554 | |
| 555 g_dir_close(dir); | |
| 556 } | |
| 557 } | |
| 558 | |
| 559 if (probe_cb != NULL) | |
| 560 probe_cb(probe_cb_data); | |
| 561 | |
| 562 #endif /* GAIM_PLUGINS */ | |
| 563 } | |
| 564 | |
| 565 gboolean | |
| 566 gaim_plugin_register(GaimPlugin *plugin) | |
| 567 { | |
| 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 | |
|
5573
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
613 protocol_plugins = g_list_insert_sorted(protocol_plugins, plugin, |
|
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
614 (GCompareFunc)compare_prpl); |
| 5205 | 615 } |
| 616 | |
| 617 plugins = g_list_append(plugins, plugin); | |
| 618 | |
| 619 return TRUE; | |
| 620 } | |
| 621 | |
| 622 gboolean | |
| 623 gaim_plugins_enabled(void) | |
| 624 { | |
| 625 #ifdef GAIM_PLUGINS | |
| 626 return TRUE; | |
| 627 #else | |
| 628 return FALSE; | |
| 629 #endif | |
| 630 } | |
| 631 | |
| 632 void | |
| 633 gaim_plugins_register_probe_notify_cb(void (*func)(void *), void *data) | |
| 634 { | |
| 635 /* TODO */ | |
| 636 probe_cb = func; | |
| 637 probe_cb_data = data; | |
| 638 } | |
| 639 | |
| 640 void | |
| 641 gaim_plugins_unregister_probe_notify_cb(void (*func)(void *)) | |
| 642 { | |
| 643 /* TODO */ | |
| 644 probe_cb = NULL; | |
| 645 probe_cb_data = NULL; | |
| 646 } | |
| 647 | |
| 648 void | |
| 649 gaim_plugins_register_load_notify_cb(void (*func)(GaimPlugin *, void *), | |
| 650 void *data) | |
| 651 { | |
| 652 /* TODO */ | |
| 653 load_cb = func; | |
| 654 load_cb_data = data; | |
| 655 } | |
| 656 | |
| 657 void | |
| 658 gaim_plugins_unregister_load_notify_cb(void (*func)(GaimPlugin *, void *)) | |
| 659 { | |
| 660 /* TODO */ | |
| 661 load_cb = NULL; | |
| 662 load_cb_data = NULL; | |
| 663 } | |
| 664 | |
| 665 void | |
| 666 gaim_plugins_register_unload_notify_cb(void (*func)(GaimPlugin *, void *), | |
| 667 void *data) | |
| 668 { | |
| 669 /* TODO */ | |
| 670 unload_cb = func; | |
| 671 unload_cb_data = data; | |
| 672 } | |
| 673 | |
| 674 void | |
| 675 gaim_plugins_unregister_unload_notify_cb(void (*func)(GaimPlugin *, void *)) | |
| 676 { | |
| 677 /* TODO */ | |
| 678 unload_cb = NULL; | |
| 679 unload_cb_data = NULL; | |
| 680 } | |
| 681 | |
| 682 GaimPlugin * | |
| 683 gaim_plugins_find_with_name(const char *name) | |
| 684 { | |
| 685 GaimPlugin *plugin; | |
| 686 GList *l; | |
| 687 | |
| 688 for (l = plugins; l != NULL; l = l->next) { | |
| 689 plugin = l->data; | |
| 690 | |
| 691 if (!strcmp(plugin->info->name, name)) | |
| 692 return plugin; | |
| 693 } | |
| 694 | |
| 695 return NULL; | |
| 696 } | |
| 697 | |
| 698 GaimPlugin * | |
| 699 gaim_plugins_find_with_filename(const char *filename) | |
| 700 { | |
| 701 GaimPlugin *plugin; | |
| 702 GList *l; | |
| 703 | |
| 704 for (l = plugins; l != NULL; l = l->next) { | |
| 705 plugin = l->data; | |
| 706 | |
| 707 if (plugin->path != NULL && !strcmp(plugin->path, filename)) | |
| 708 return plugin; | |
| 709 } | |
| 710 | |
| 711 return NULL; | |
| 712 } | |
| 713 | |
| 714 GaimPlugin * | |
| 715 gaim_plugins_find_with_id(const char *id) | |
| 716 { | |
| 717 GaimPlugin *plugin; | |
| 718 GList *l; | |
| 719 | |
| 720 g_return_val_if_fail(id != NULL, NULL); | |
| 721 | |
| 722 for (l = plugins; l != NULL; l = l->next) { | |
| 723 plugin = l->data; | |
| 724 | |
| 725 if (!strcmp(plugin->info->id, id)) | |
| 726 return plugin; | |
| 727 } | |
| 728 | |
| 729 return NULL; | |
| 730 } | |
| 731 | |
| 732 GList * | |
| 733 gaim_plugins_get_loaded(void) | |
| 734 { | |
| 735 return loaded_plugins; | |
| 736 } | |
| 737 | |
| 738 GList * | |
|
5573
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
739 gaim_plugins_get_protocols(void) |
|
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
740 { |
|
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
741 return protocol_plugins; |
|
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
742 } |
|
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
743 |
|
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
744 GList * |
| 5205 | 745 gaim_plugins_get_all(void) |
| 746 { | |
| 747 return plugins; | |
| 748 } | |
| 749 |
