Thu, 17 Jul 2003 10:35:43 +0000
[gaim-migrate @ 6664]
Core/UI split the core initialization and shutdown. I think I got all the
bugs worked out. It's looking nice and stable here, but if it causes CVS to
go to hell for everyone.. er, try to fix it or let me know :) I don't have
this in patch form.
| 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
754c63f29b77
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5840
diff
changeset
|
37 | #include "internal.h" |
| 5205 | 38 | |
|
5638
53e752c88ea1
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5573
diff
changeset
|
39 | #include "accountopt.h" |
|
5872
754c63f29b77
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5840
diff
changeset
|
40 | #include "debug.h" |
| 5205 | 41 | #include "event.h" |
|
5436
a0e0bacaa196
[gaim-migrate @ 5818]
Christian Hammond <chipx86@chipx86.com>
parents:
5357
diff
changeset
|
42 | #include "notify.h" |
|
5872
754c63f29b77
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5840
diff
changeset
|
43 | #include "prefs.h" |
|
754c63f29b77
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5840
diff
changeset
|
44 | #include "prpl.h" |
|
754c63f29b77
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5840
diff
changeset
|
45 | #include "request.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
633880e3f137
[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
ebdbb7dc6658
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5646
diff
changeset
|
87 | loader_supports_file(GaimPlugin *loader, const char *filename) |
| 5205 | 88 | { |
| 89 | GList *l, *exts; | |
| 90 | GaimPlugin *plugin; | |
| 91 | ||
| 92 | for (l = plugin_loaders; l != NULL; l = l->next) { | |
| 93 | plugin = l->data; | |
| 94 | ||
| 95 | for (exts = GAIM_PLUGIN_LOADER_INFO(plugin)->exts; | |
| 96 | exts != NULL; | |
| 97 | exts = exts->next) { | |
| 98 | ||
| 99 | if (is_so_file(filename, (char *)exts->data)) | |
| 100 | return TRUE; | |
| 101 | } | |
| 102 | } | |
| 103 | ||
| 104 | return FALSE; | |
| 105 | } | |
| 106 | ||
| 107 | static GaimPlugin * | |
|
5794
ebdbb7dc6658
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5646
diff
changeset
|
108 | find_loader_for_plugin(const GaimPlugin *plugin) |
| 5205 | 109 | { |
| 110 | GaimPlugin *loader; | |
| 111 | GList *l; | |
| 112 | ||
| 113 | if (plugin->path == NULL) | |
| 114 | return NULL; | |
| 115 | ||
| 116 | for (l = gaim_plugins_get_loaded(); l != NULL; l = l->next) { | |
| 117 | loader = l->data; | |
| 118 | ||
| 119 | if (loader->info->type == GAIM_PLUGIN_LOADER && | |
|
5794
ebdbb7dc6658
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5646
diff
changeset
|
120 | loader_supports_file(loader, plugin->path)) { |
| 5205 | 121 | |
| 122 | return loader; | |
| 123 | } | |
| 124 | ||
| 125 | loader = NULL; | |
| 126 | } | |
| 127 | ||
| 128 | return NULL; | |
| 129 | } | |
| 130 | ||
|
5449
4c350eb7d4a0
[gaim-migrate @ 5836]
Decklin Foster <decklin@red-bean.com>
parents:
5443
diff
changeset
|
131 | #endif /* GAIM_PLUGINS */ |
|
4c350eb7d4a0
[gaim-migrate @ 5836]
Decklin Foster <decklin@red-bean.com>
parents:
5443
diff
changeset
|
132 | |
| 5205 | 133 | static gint |
| 134 | compare_prpl(GaimPlugin *a, GaimPlugin *b) | |
| 135 | { | |
| 136 | /* neg if a before b, 0 if equal, pos if a after b */ | |
| 137 | return ((GAIM_IS_PROTOCOL_PLUGIN(a) | |
| 138 | ? GAIM_PLUGIN_PROTOCOL_INFO(a)->protocol : -1) - | |
| 139 | ((GAIM_IS_PROTOCOL_PLUGIN(b) | |
| 140 | ? GAIM_PLUGIN_PROTOCOL_INFO(b)->protocol : -1))); | |
| 141 | } | |
| 142 | ||
| 143 | GaimPlugin * | |
| 144 | gaim_plugin_new(gboolean native, const char *path) | |
| 145 | { | |
| 146 | GaimPlugin *plugin; | |
| 147 | ||
| 148 | plugin = g_new0(GaimPlugin, 1); | |
| 149 | ||
| 150 | plugin->native_plugin = native; | |
| 151 | plugin->path = (path == NULL ? NULL : g_strdup(path)); | |
| 152 | ||
| 153 | return plugin; | |
| 154 | } | |
| 155 | ||
| 156 | GaimPlugin * | |
| 157 | gaim_plugin_probe(const char *filename) | |
| 158 | { | |
| 159 | #ifdef GAIM_PLUGINS | |
| 160 | GaimPlugin *plugin = NULL; | |
| 161 | GaimPlugin *loader; | |
| 162 | gboolean (*gaim_init_plugin)(GaimPlugin *); | |
| 163 | ||
| 164 | g_return_val_if_fail(filename != NULL, NULL); | |
| 165 | ||
|
5973
adc75f0fcaa3
[gaim-migrate @ 6420]
Mark Doliner <markdoliner@pidgin.im>
parents:
5949
diff
changeset
|
166 | if (!g_file_test(filename, G_FILE_TEST_EXISTS)) |
|
adc75f0fcaa3
[gaim-migrate @ 6420]
Mark Doliner <markdoliner@pidgin.im>
parents:
5949
diff
changeset
|
167 | return NULL; |
|
adc75f0fcaa3
[gaim-migrate @ 6420]
Mark Doliner <markdoliner@pidgin.im>
parents:
5949
diff
changeset
|
168 | |
| 5205 | 169 | plugin = gaim_plugins_find_with_filename(filename); |
| 170 | ||
| 171 | if (plugin != NULL) | |
| 172 | return plugin; | |
| 173 | ||
| 174 | plugin = gaim_plugin_new(is_so_file(filename, PLUGIN_EXT), filename); | |
| 175 | ||
| 176 | if (plugin->native_plugin) { | |
| 5450 | 177 | const char *error; |
| 5205 | 178 | plugin->handle = g_module_open(filename, 0); |
| 179 | ||
| 180 | if (plugin->handle == NULL) { | |
| 5443 | 181 | error = g_module_error(); |
|
5269
a318feccd844
[gaim-migrate @ 5641]
Christian Hammond <chipx86@chipx86.com>
parents:
5268
diff
changeset
|
182 | gaim_debug(GAIM_DEBUG_ERROR, "plugins", "%s is unloadable: %s\n", |
| 5443 | 183 | plugin->path, error ? error : "Unknown error."); |
| 5205 | 184 | |
|
5269
a318feccd844
[gaim-migrate @ 5641]
Christian Hammond <chipx86@chipx86.com>
parents:
5268
diff
changeset
|
185 | gaim_plugin_destroy(plugin); |
|
a318feccd844
[gaim-migrate @ 5641]
Christian Hammond <chipx86@chipx86.com>
parents:
5268
diff
changeset
|
186 | |
|
a318feccd844
[gaim-migrate @ 5641]
Christian Hammond <chipx86@chipx86.com>
parents:
5268
diff
changeset
|
187 | return NULL; |
| 5205 | 188 | } |
| 189 | ||
| 190 | if (!g_module_symbol(plugin->handle, "gaim_init_plugin", | |
| 191 | (gpointer *)&gaim_init_plugin)) { | |
| 192 | g_module_close(plugin->handle); | |
| 193 | plugin->handle = NULL; | |
| 194 | ||
| 5443 | 195 | error = g_module_error(); |
|
5211
94d9756c381f
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
196 | gaim_debug(GAIM_DEBUG_ERROR, "plugins", "%s is unloadable: %s\n", |
| 5443 | 197 | plugin->path, error ? error : "Unknown error."); |
| 5205 | 198 | |
| 199 | gaim_plugin_destroy(plugin); | |
| 200 | ||
| 201 | return NULL; | |
| 202 | } | |
| 203 | } | |
| 204 | else { | |
|
5794
ebdbb7dc6658
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5646
diff
changeset
|
205 | loader = find_loader_for_plugin(plugin); |
| 5205 | 206 | |
| 207 | if (loader == NULL) { | |
| 208 | gaim_plugin_destroy(plugin); | |
| 209 | ||
| 210 | return NULL; | |
| 211 | } | |
| 212 | ||
| 213 | gaim_init_plugin = GAIM_PLUGIN_LOADER_INFO(loader)->probe; | |
| 214 | } | |
| 215 | ||
| 216 | plugin->error = NULL; | |
| 217 | ||
| 218 | if (!gaim_init_plugin(plugin) || plugin->info == NULL) { | |
| 219 | char buf[BUFSIZ]; | |
| 220 | ||
| 221 | g_snprintf(buf, sizeof(buf), | |
| 222 | _("The plugin %s did not return any valid plugin " | |
| 223 | "information"), | |
| 224 | plugin->path); | |
| 225 | ||
|
5436
a0e0bacaa196
[gaim-migrate @ 5818]
Christian Hammond <chipx86@chipx86.com>
parents:
5357
diff
changeset
|
226 | gaim_notify_error(NULL, NULL, |
|
a0e0bacaa196
[gaim-migrate @ 5818]
Christian Hammond <chipx86@chipx86.com>
parents:
5357
diff
changeset
|
227 | _("Gaim was unable to load your plugin."), buf); |
| 5205 | 228 | |
| 229 | gaim_plugin_destroy(plugin); | |
| 230 | ||
| 231 | return NULL; | |
| 232 | } | |
| 233 | ||
| 234 | return plugin; | |
| 235 | #else | |
| 236 | return NULL; | |
| 237 | #endif /* !GAIM_PLUGINS */ | |
| 238 | } | |
| 239 | ||
| 240 | gboolean | |
| 241 | gaim_plugin_load(GaimPlugin *plugin) | |
| 242 | { | |
| 243 | #ifdef GAIM_PLUGINS | |
| 244 | g_return_val_if_fail(plugin != NULL, FALSE); | |
|
5270
74286f7fb991
[gaim-migrate @ 5642]
Christian Hammond <chipx86@chipx86.com>
parents:
5269
diff
changeset
|
245 | g_return_val_if_fail(plugin->error == NULL, FALSE); |
| 5205 | 246 | |
| 247 | if (gaim_plugin_is_loaded(plugin)) | |
| 248 | return TRUE; | |
| 249 | ||
| 250 | if (plugin->native_plugin) { | |
|
5357
1fa9e57df50c
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
251 | if (plugin->info != NULL) { |
|
1fa9e57df50c
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
252 | if (plugin->info->load != NULL) |
|
1fa9e57df50c
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
253 | plugin->info->load(plugin); |
|
1fa9e57df50c
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
254 | |
|
1fa9e57df50c
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
255 | if (plugin->info->type == GAIM_PLUGIN_LOADER) { |
|
1fa9e57df50c
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
256 | GaimPluginLoaderInfo *loader_info; |
|
1fa9e57df50c
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
257 | |
|
1fa9e57df50c
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
258 | loader_info = GAIM_PLUGIN_LOADER_INFO(plugin); |
|
1fa9e57df50c
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
259 | |
|
1fa9e57df50c
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
260 | if (loader_info->broadcast != NULL) |
|
1fa9e57df50c
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
261 | gaim_signals_register_broadcast_func(loader_info->broadcast, |
|
1fa9e57df50c
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
262 | NULL); |
|
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 | } |
| 5205 | 265 | } |
| 266 | else { | |
| 267 | GaimPlugin *loader; | |
| 268 | GaimPluginLoaderInfo *loader_info; | |
| 269 | ||
|
5794
ebdbb7dc6658
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5646
diff
changeset
|
270 | loader = find_loader_for_plugin(plugin); |
| 5205 | 271 | |
| 272 | if (loader == NULL) | |
| 273 | return FALSE; | |
| 274 | ||
| 275 | loader_info = GAIM_PLUGIN_LOADER_INFO(loader); | |
| 276 | ||
| 277 | if (loader_info->load != NULL) | |
| 278 | loader_info->load(plugin); | |
| 279 | } | |
| 280 | ||
| 281 | loaded_plugins = g_list_append(loaded_plugins, plugin); | |
| 282 | ||
| 283 | plugin->loaded = TRUE; | |
| 284 | ||
| 285 | /* TODO */ | |
| 286 | if (load_cb != NULL) | |
| 287 | load_cb(plugin, load_cb_data); | |
| 288 | ||
| 289 | return TRUE; | |
| 290 | ||
| 291 | #else | |
|
5449
4c350eb7d4a0
[gaim-migrate @ 5836]
Decklin Foster <decklin@red-bean.com>
parents:
5443
diff
changeset
|
292 | return TRUE; |
| 5205 | 293 | #endif /* !GAIM_PLUGINS */ |
| 294 | } | |
| 295 | ||
| 296 | gboolean | |
| 297 | gaim_plugin_unload(GaimPlugin *plugin) | |
| 298 | { | |
| 299 | #ifdef GAIM_PLUGINS | |
| 300 | g_return_val_if_fail(plugin != NULL, FALSE); | |
| 301 | ||
| 302 | loaded_plugins = g_list_remove(loaded_plugins, plugin); | |
| 303 | ||
| 304 | g_return_val_if_fail(gaim_plugin_is_loaded(plugin), FALSE); | |
| 305 | ||
|
5211
94d9756c381f
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
306 | gaim_debug(GAIM_DEBUG_INFO, "plugins", "Unloading plugin %s\n", |
|
94d9756c381f
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
307 | plugin->info->name); |
| 5205 | 308 | |
| 309 | /* cancel any pending dialogs the plugin has */ | |
|
5498
01eec144d71b
[gaim-migrate @ 5894]
Christian Hammond <chipx86@chipx86.com>
parents:
5450
diff
changeset
|
310 | gaim_request_close_with_handle(plugin); |
|
01eec144d71b
[gaim-migrate @ 5894]
Christian Hammond <chipx86@chipx86.com>
parents:
5450
diff
changeset
|
311 | gaim_notify_close_with_handle(plugin); |
| 5205 | 312 | |
| 313 | plugin->loaded = FALSE; | |
| 314 | ||
| 315 | if (plugin->native_plugin) { | |
| 316 | if (plugin->info->unload != NULL) | |
| 317 | plugin->info->unload(plugin); | |
| 318 | ||
| 319 | if (plugin->info->type == GAIM_PLUGIN_PROTOCOL) { | |
| 320 | GaimPluginProtocolInfo *prpl_info; | |
| 321 | GList *l; | |
| 322 | ||
| 323 | prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(plugin); | |
| 324 | ||
|
5638
53e752c88ea1
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5573
diff
changeset
|
325 | for (l = prpl_info->user_splits; l != NULL; l = l->next) |
|
53e752c88ea1
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5573
diff
changeset
|
326 | gaim_account_user_split_destroy(l->data); |
| 5205 | 327 | |
|
5638
53e752c88ea1
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5573
diff
changeset
|
328 | for (l = prpl_info->protocol_options; l != NULL; l = l->next) |
|
53e752c88ea1
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5573
diff
changeset
|
329 | gaim_account_option_destroy(l->data); |
| 5205 | 330 | |
|
5646
0aa637549d87
[gaim-migrate @ 6060]
Christian Hammond <chipx86@chipx86.com>
parents:
5638
diff
changeset
|
331 | if (prpl_info->user_splits != NULL) |
|
0aa637549d87
[gaim-migrate @ 6060]
Christian Hammond <chipx86@chipx86.com>
parents:
5638
diff
changeset
|
332 | g_list_free(prpl_info->user_splits); |
|
0aa637549d87
[gaim-migrate @ 6060]
Christian Hammond <chipx86@chipx86.com>
parents:
5638
diff
changeset
|
333 | |
|
0aa637549d87
[gaim-migrate @ 6060]
Christian Hammond <chipx86@chipx86.com>
parents:
5638
diff
changeset
|
334 | if (prpl_info->protocol_options != NULL) |
|
0aa637549d87
[gaim-migrate @ 6060]
Christian Hammond <chipx86@chipx86.com>
parents:
5638
diff
changeset
|
335 | g_list_free(prpl_info->protocol_options); |
| 5205 | 336 | } |
|
5357
1fa9e57df50c
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
337 | else if (plugin->info->type == GAIM_PLUGIN_LOADER) { |
|
1fa9e57df50c
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
338 | GaimPluginLoaderInfo *loader_info; |
|
1fa9e57df50c
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
339 | |
|
1fa9e57df50c
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
340 | loader_info = GAIM_PLUGIN_LOADER_INFO(plugin); |
|
1fa9e57df50c
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
341 | |
|
1fa9e57df50c
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
342 | if (loader_info->broadcast != NULL) |
|
1fa9e57df50c
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
343 | gaim_signals_unregister_broadcast_func(loader_info->broadcast); |
|
1fa9e57df50c
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
344 | } |
| 5205 | 345 | } |
| 346 | else { | |
| 347 | GaimPlugin *loader; | |
| 348 | GaimPluginLoaderInfo *loader_info; | |
| 349 | ||
|
5794
ebdbb7dc6658
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5646
diff
changeset
|
350 | loader = find_loader_for_plugin(plugin); |
| 5205 | 351 | |
| 352 | if (loader == NULL) | |
| 353 | return FALSE; | |
| 354 | ||
| 355 | loader_info = GAIM_PLUGIN_LOADER_INFO(loader); | |
| 356 | ||
| 357 | if (loader_info->load != NULL) | |
| 358 | loader_info->unload(plugin); | |
| 359 | } | |
| 360 | ||
| 361 | gaim_signals_disconnect_by_handle(plugin); | |
| 362 | ||
| 363 | /* TODO */ | |
| 364 | if (unload_cb != NULL) | |
| 365 | unload_cb(plugin, unload_cb_data); | |
| 366 | ||
| 367 | return TRUE; | |
|
5449
4c350eb7d4a0
[gaim-migrate @ 5836]
Decklin Foster <decklin@red-bean.com>
parents:
5443
diff
changeset
|
368 | #else |
|
4c350eb7d4a0
[gaim-migrate @ 5836]
Decklin Foster <decklin@red-bean.com>
parents:
5443
diff
changeset
|
369 | return TRUE; |
| 5205 | 370 | #endif /* GAIM_PLUGINS */ |
| 371 | } | |
| 372 | ||
| 373 | gboolean | |
| 374 | gaim_plugin_reload(GaimPlugin *plugin) | |
| 375 | { | |
| 376 | #ifdef GAIM_PLUGINS | |
| 377 | g_return_val_if_fail(plugin != NULL, FALSE); | |
| 378 | g_return_val_if_fail(gaim_plugin_is_loaded(plugin), FALSE); | |
| 379 | ||
| 380 | if (!gaim_plugin_unload(plugin)) | |
| 381 | return FALSE; | |
| 382 | ||
| 383 | if (!gaim_plugin_load(plugin)) | |
| 384 | return FALSE; | |
| 385 | ||
| 386 | return TRUE; | |
| 387 | #else | |
|
5449
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 | void | |
| 393 | gaim_plugin_destroy(GaimPlugin *plugin) | |
| 394 | { | |
|
5449
4c350eb7d4a0
[gaim-migrate @ 5836]
Decklin Foster <decklin@red-bean.com>
parents:
5443
diff
changeset
|
395 | #ifdef GAIM_PLUGINS |
| 5205 | 396 | g_return_if_fail(plugin != NULL); |
| 397 | ||
| 398 | if (gaim_plugin_is_loaded(plugin)) | |
| 399 | gaim_plugin_unload(plugin); | |
| 400 | ||
| 401 | plugins = g_list_remove(plugins, plugin); | |
| 402 | ||
|
5243
e8d35a430c6d
[gaim-migrate @ 5614]
Christian Hammond <chipx86@chipx86.com>
parents:
5242
diff
changeset
|
403 | if (plugin->info != NULL && plugin->info->dependencies != NULL) |
|
e8d35a430c6d
[gaim-migrate @ 5614]
Christian Hammond <chipx86@chipx86.com>
parents:
5242
diff
changeset
|
404 | g_list_free(plugin->info->dependencies); |
| 5205 | 405 | |
| 406 | if (plugin->native_plugin) { | |
| 407 | ||
| 408 | if (plugin->info != NULL && plugin->info->type == GAIM_PLUGIN_LOADER) { | |
| 409 | GList *exts, *l, *next_l; | |
| 410 | GaimPlugin *p2; | |
| 411 | ||
| 412 | for (exts = GAIM_PLUGIN_LOADER_INFO(plugin)->exts; | |
| 413 | exts != NULL; | |
| 414 | exts = exts->next) { | |
| 415 | ||
| 416 | for (l = gaim_plugins_get_all(); l != NULL; l = next_l) { | |
| 417 | next_l = l->next; | |
| 418 | ||
| 419 | p2 = l->data; | |
| 420 | ||
| 421 | if (p2->path != NULL && is_so_file(p2->path, exts->data)) | |
| 422 | gaim_plugin_destroy(p2); | |
| 423 | } | |
| 424 | } | |
| 425 | ||
| 426 | g_list_free(GAIM_PLUGIN_LOADER_INFO(plugin)->exts); | |
| 427 | ||
| 428 | plugin_loaders = g_list_remove(plugin_loaders, plugin); | |
| 429 | } | |
| 430 | ||
| 431 | if (plugin->info != NULL && plugin->info->destroy != NULL) | |
| 432 | plugin->info->destroy(plugin); | |
| 433 | ||
| 434 | if (plugin->handle != NULL) | |
| 435 | g_module_close(plugin->handle); | |
| 436 | } | |
| 437 | else { | |
| 438 | GaimPlugin *loader; | |
| 439 | GaimPluginLoaderInfo *loader_info; | |
| 440 | ||
|
5794
ebdbb7dc6658
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5646
diff
changeset
|
441 | loader = find_loader_for_plugin(plugin); |
| 5205 | 442 | |
|
5941
46e136a842b8
[gaim-migrate @ 6381]
Christian Hammond <chipx86@chipx86.com>
parents:
5872
diff
changeset
|
443 | if (loader != NULL) { |
|
46e136a842b8
[gaim-migrate @ 6381]
Christian Hammond <chipx86@chipx86.com>
parents:
5872
diff
changeset
|
444 | loader_info = GAIM_PLUGIN_LOADER_INFO(loader); |
| 5205 | 445 | |
|
5941
46e136a842b8
[gaim-migrate @ 6381]
Christian Hammond <chipx86@chipx86.com>
parents:
5872
diff
changeset
|
446 | if (loader_info->destroy != NULL) |
|
46e136a842b8
[gaim-migrate @ 6381]
Christian Hammond <chipx86@chipx86.com>
parents:
5872
diff
changeset
|
447 | loader_info->destroy(plugin); |
|
46e136a842b8
[gaim-migrate @ 6381]
Christian Hammond <chipx86@chipx86.com>
parents:
5872
diff
changeset
|
448 | } |
| 5205 | 449 | } |
| 450 | ||
| 451 | if (plugin->path != NULL) g_free(plugin->path); | |
| 452 | if (plugin->error != NULL) g_free(plugin->error); | |
| 453 | ||
| 454 | g_free(plugin); | |
|
5449
4c350eb7d4a0
[gaim-migrate @ 5836]
Decklin Foster <decklin@red-bean.com>
parents:
5443
diff
changeset
|
455 | #endif /* !GAIM_PLUGINS */ |
| 5205 | 456 | } |
| 457 | ||
| 458 | gboolean | |
| 459 | gaim_plugin_is_loaded(const GaimPlugin *plugin) | |
| 460 | { | |
| 461 | g_return_val_if_fail(plugin != NULL, FALSE); | |
| 462 | ||
| 463 | return plugin->loaded; | |
| 464 | } | |
| 465 | ||
| 466 | void | |
| 467 | gaim_plugins_set_search_paths(size_t count, char **paths) | |
| 468 | { | |
| 469 | size_t s; | |
| 470 | ||
| 471 | g_return_if_fail(count > 0); | |
| 472 | g_return_if_fail(paths != NULL); | |
| 473 | ||
| 474 | if (search_paths != NULL) { | |
| 475 | for (s = 0; s < search_path_count; s++) | |
| 476 | g_free(search_paths[s]); | |
| 477 | ||
| 478 | g_free(search_paths); | |
| 479 | } | |
| 480 | ||
| 481 | search_paths = g_new0(char *, count); | |
| 482 | ||
| 483 | for (s = 0; s < count; s++) { | |
| 484 | if (paths[s] == NULL) | |
| 485 | search_paths[s] = NULL; | |
| 486 | else | |
| 487 | search_paths[s] = g_strdup(paths[s]); | |
| 488 | } | |
| 489 | ||
| 490 | search_path_count = count; | |
| 491 | } | |
| 492 | ||
| 493 | void | |
| 494 | gaim_plugins_unload_all(void) | |
| 495 | { | |
| 496 | #ifdef GAIM_PLUGINS | |
| 497 | ||
| 498 | while (loaded_plugins != NULL) | |
| 499 | gaim_plugin_unload(loaded_plugins->data); | |
| 500 | ||
| 501 | #endif /* GAIM_PLUGINS */ | |
| 502 | } | |
| 503 | ||
| 504 | void | |
|
5242
155da5e9bbf0
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
505 | gaim_plugins_destroy_all(void) |
|
155da5e9bbf0
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
506 | { |
|
155da5e9bbf0
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
507 | #ifdef GAIM_PLUGINS |
|
155da5e9bbf0
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
508 | |
|
155da5e9bbf0
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
509 | while (plugins != NULL) |
|
155da5e9bbf0
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
510 | gaim_plugin_destroy(plugins->data); |
|
155da5e9bbf0
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
511 | |
|
155da5e9bbf0
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
512 | #endif /* GAIM_PLUGINS */ |
|
155da5e9bbf0
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
513 | } |
| 5838 | 514 | |
| 515 | void | |
|
5949
bb7cbf02dda9
[gaim-migrate @ 6393]
Christian Hammond <chipx86@chipx86.com>
parents:
5941
diff
changeset
|
516 | gaim_plugins_load_saved(const char *key) |
| 5838 | 517 | { |
| 518 | #ifdef GAIM_PLUGINS | |
|
5949
bb7cbf02dda9
[gaim-migrate @ 6393]
Christian Hammond <chipx86@chipx86.com>
parents:
5941
diff
changeset
|
519 | GList *f, *files; |
|
bb7cbf02dda9
[gaim-migrate @ 6393]
Christian Hammond <chipx86@chipx86.com>
parents:
5941
diff
changeset
|
520 | |
|
bb7cbf02dda9
[gaim-migrate @ 6393]
Christian Hammond <chipx86@chipx86.com>
parents:
5941
diff
changeset
|
521 | g_return_if_fail(key != NULL); |
| 5838 | 522 | |
|
5949
bb7cbf02dda9
[gaim-migrate @ 6393]
Christian Hammond <chipx86@chipx86.com>
parents:
5941
diff
changeset
|
523 | files = gaim_prefs_get_string_list(key); |
|
bb7cbf02dda9
[gaim-migrate @ 6393]
Christian Hammond <chipx86@chipx86.com>
parents:
5941
diff
changeset
|
524 | |
|
bb7cbf02dda9
[gaim-migrate @ 6393]
Christian Hammond <chipx86@chipx86.com>
parents:
5941
diff
changeset
|
525 | for (f = files; f; f = f->next) { |
| 5838 | 526 | gaim_plugin_load(gaim_plugin_probe(f->data)); |
| 527 | g_free(f->data); | |
| 528 | } | |
| 529 | ||
| 530 | g_list_free(files); | |
| 531 | #endif /* GAIM_PLUGINS */ | |
| 532 | } | |
| 533 | ||
| 534 | ||
|
5242
155da5e9bbf0
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
535 | void |
| 5205 | 536 | gaim_plugins_probe(const char *ext) |
| 537 | { | |
| 538 | #ifdef GAIM_PLUGINS | |
| 539 | GDir *dir; | |
| 540 | const gchar *file; | |
| 541 | gchar *path; | |
| 542 | GaimPlugin *plugin; | |
| 543 | size_t i; | |
| 544 | ||
| 545 | if (!g_module_supported()) | |
| 546 | return; | |
| 547 | ||
| 548 | for (i = 0; i < search_path_count; i++) { | |
| 549 | if (search_paths[i] == NULL) | |
| 550 | continue; | |
| 551 | ||
| 552 | dir = g_dir_open(search_paths[i], 0, NULL); | |
| 553 | ||
| 554 | if (dir != NULL) { | |
| 555 | while ((file = g_dir_read_name(dir)) != NULL) { | |
| 556 | path = g_build_filename(search_paths[i], file, NULL); | |
| 557 | ||
| 558 | if (ext == NULL || is_so_file(file, ext)) | |
| 559 | plugin = gaim_plugin_probe(path); | |
| 560 | ||
| 561 | g_free(path); | |
| 562 | } | |
| 563 | ||
| 564 | g_dir_close(dir); | |
| 565 | } | |
| 566 | } | |
| 567 | ||
| 568 | if (probe_cb != NULL) | |
| 569 | probe_cb(probe_cb_data); | |
| 570 | ||
| 571 | #endif /* GAIM_PLUGINS */ | |
| 572 | } | |
| 573 | ||
| 574 | gboolean | |
| 575 | gaim_plugin_register(GaimPlugin *plugin) | |
| 576 | { | |
| 577 | g_return_val_if_fail(plugin != NULL, FALSE); | |
| 578 | ||
| 579 | if (g_list_find(plugins, plugin)) | |
| 580 | return TRUE; | |
| 581 | ||
| 582 | /* Special exception for loader plugins. We want them loaded NOW! */ | |
| 583 | if (plugin->info->type == GAIM_PLUGIN_LOADER) { | |
| 584 | GList *exts; | |
| 585 | ||
| 586 | /* We'll just load this right now. */ | |
| 587 | if (!gaim_plugin_load(plugin)) { | |
| 588 | ||
| 589 | gaim_plugin_destroy(plugin); | |
| 590 | ||
| 591 | return FALSE; | |
| 592 | } | |
| 593 | ||
| 594 | plugin_loaders = g_list_append(plugin_loaders, plugin); | |
| 595 | ||
| 596 | for (exts = GAIM_PLUGIN_LOADER_INFO(plugin)->exts; | |
| 597 | exts != NULL; | |
| 598 | exts = exts->next) { | |
| 599 | ||
| 600 | gaim_plugins_probe(exts->data); | |
| 601 | } | |
| 602 | } | |
| 603 | else if (plugin->info->type == GAIM_PLUGIN_PROTOCOL) { | |
| 604 | ||
| 605 | /* We'll just load this right now. */ | |
| 606 | if (!gaim_plugin_load(plugin)) { | |
| 607 | ||
| 608 | gaim_plugin_destroy(plugin); | |
| 609 | ||
| 610 | return FALSE; | |
| 611 | } | |
| 612 | ||
| 613 | if (GAIM_PLUGIN_PROTOCOL_INFO(plugin)->protocol == GAIM_PROTO_ICQ || | |
| 614 | gaim_find_prpl(GAIM_PLUGIN_PROTOCOL_INFO(plugin)->protocol)) { | |
| 615 | ||
| 616 | /* Nothing to see here--move along, move along */ | |
| 617 | gaim_plugin_destroy(plugin); | |
| 618 | ||
| 619 | return FALSE; | |
| 620 | } | |
| 621 | ||
|
5573
633880e3f137
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
622 | protocol_plugins = g_list_insert_sorted(protocol_plugins, plugin, |
|
633880e3f137
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
623 | (GCompareFunc)compare_prpl); |
| 5205 | 624 | } |
| 625 | ||
| 626 | plugins = g_list_append(plugins, plugin); | |
| 627 | ||
| 628 | return TRUE; | |
| 629 | } | |
| 630 | ||
| 631 | gboolean | |
| 632 | gaim_plugins_enabled(void) | |
| 633 | { | |
| 634 | #ifdef GAIM_PLUGINS | |
| 635 | return TRUE; | |
| 636 | #else | |
| 637 | return FALSE; | |
| 638 | #endif | |
| 639 | } | |
| 640 | ||
| 641 | void | |
| 642 | gaim_plugins_register_probe_notify_cb(void (*func)(void *), void *data) | |
| 643 | { | |
| 644 | /* TODO */ | |
| 645 | probe_cb = func; | |
| 646 | probe_cb_data = data; | |
| 647 | } | |
| 648 | ||
| 649 | void | |
| 650 | gaim_plugins_unregister_probe_notify_cb(void (*func)(void *)) | |
| 651 | { | |
| 652 | /* TODO */ | |
| 653 | probe_cb = NULL; | |
| 654 | probe_cb_data = NULL; | |
| 655 | } | |
| 656 | ||
| 657 | void | |
| 658 | gaim_plugins_register_load_notify_cb(void (*func)(GaimPlugin *, void *), | |
| 659 | void *data) | |
| 660 | { | |
| 661 | /* TODO */ | |
| 662 | load_cb = func; | |
| 663 | load_cb_data = data; | |
| 664 | } | |
| 665 | ||
| 666 | void | |
| 667 | gaim_plugins_unregister_load_notify_cb(void (*func)(GaimPlugin *, void *)) | |
| 668 | { | |
| 669 | /* TODO */ | |
| 670 | load_cb = NULL; | |
| 671 | load_cb_data = NULL; | |
| 672 | } | |
| 673 | ||
| 674 | void | |
| 675 | gaim_plugins_register_unload_notify_cb(void (*func)(GaimPlugin *, void *), | |
| 676 | void *data) | |
| 677 | { | |
| 678 | /* TODO */ | |
| 679 | unload_cb = func; | |
| 680 | unload_cb_data = data; | |
| 681 | } | |
| 682 | ||
| 683 | void | |
| 684 | gaim_plugins_unregister_unload_notify_cb(void (*func)(GaimPlugin *, void *)) | |
| 685 | { | |
| 686 | /* TODO */ | |
| 687 | unload_cb = NULL; | |
| 688 | unload_cb_data = NULL; | |
| 689 | } | |
| 690 | ||
| 691 | GaimPlugin * | |
| 692 | gaim_plugins_find_with_name(const char *name) | |
| 693 | { | |
| 694 | GaimPlugin *plugin; | |
| 695 | GList *l; | |
| 696 | ||
| 697 | for (l = plugins; l != NULL; l = l->next) { | |
| 698 | plugin = l->data; | |
| 699 | ||
| 700 | if (!strcmp(plugin->info->name, name)) | |
| 701 | return plugin; | |
| 702 | } | |
| 703 | ||
| 704 | return NULL; | |
| 705 | } | |
| 706 | ||
| 707 | GaimPlugin * | |
| 708 | gaim_plugins_find_with_filename(const char *filename) | |
| 709 | { | |
| 710 | GaimPlugin *plugin; | |
| 711 | GList *l; | |
| 712 | ||
| 713 | for (l = plugins; l != NULL; l = l->next) { | |
| 714 | plugin = l->data; | |
| 715 | ||
| 716 | if (plugin->path != NULL && !strcmp(plugin->path, filename)) | |
| 717 | return plugin; | |
| 718 | } | |
| 719 | ||
| 720 | return NULL; | |
| 721 | } | |
| 722 | ||
| 723 | GaimPlugin * | |
| 724 | gaim_plugins_find_with_id(const char *id) | |
| 725 | { | |
| 726 | GaimPlugin *plugin; | |
| 727 | GList *l; | |
| 728 | ||
| 729 | g_return_val_if_fail(id != NULL, NULL); | |
| 730 | ||
| 731 | for (l = plugins; l != NULL; l = l->next) { | |
| 732 | plugin = l->data; | |
| 733 | ||
| 734 | if (!strcmp(plugin->info->id, id)) | |
| 735 | return plugin; | |
| 736 | } | |
| 737 | ||
| 738 | return NULL; | |
| 739 | } | |
| 740 | ||
| 741 | GList * | |
| 742 | gaim_plugins_get_loaded(void) | |
| 743 | { | |
| 744 | return loaded_plugins; | |
| 745 | } | |
| 746 | ||
| 747 | GList * | |
|
5573
633880e3f137
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
748 | gaim_plugins_get_protocols(void) |
|
633880e3f137
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
749 | { |
|
633880e3f137
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
750 | return protocol_plugins; |
|
633880e3f137
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
751 | } |
|
633880e3f137
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
752 | |
|
633880e3f137
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
753 | GList * |
| 5205 | 754 | gaim_plugins_get_all(void) |
| 755 | { | |
| 756 | return plugins; | |
| 757 | } | |
| 758 |