Mercurial > pidgin.yaz
annotate src/plugin.c @ 5943:a4f2aba0848d
[gaim-migrate @ 6384]
This should fix corruption in the blist, accounts, and pounces when some
protocol plugins cannot load. Some parts of gaim now use the new unique
Plugin or Protocol Plugin IDs, while some still use the old protocol
numbers. Accounts kind of used both, and when prpls were missing, it had
trouble finding accounts. It would find the names, even without mapping the
protocol numbers to IDs, and any duplicate accounts would get nuked. That
would then affect pounce saving. Anyhow, long story short (well, it's
already long, too late for that), this should fix all that mess. And
introduce new mess, but hopefully temporary mess.
committer: Tailor Script <tailor@pidgin.im>
| author | Christian Hammond <chipx86@chipx86.com> |
|---|---|
| date | Mon, 23 Jun 2003 02:00:15 +0000 |
| parents | a3e60ff95b7d |
| children | 90d0849abd3c |
| rev | line source |
|---|---|
| 5205 | 1 /* |
| 2 * gaim | |
| 3 * | |
| 4 * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net> | |
| 5 * | |
| 6 * This program is free software; you can redistribute it and/or modify | |
| 7 * it under the terms of the GNU General Public License as published by | |
| 8 * the Free Software Foundation; either version 2 of the License, or | |
| 9 * (at your option) any later version. | |
| 10 * | |
| 11 * This program is distributed in the hope that it will be useful, | |
| 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 14 * GNU General Public License for more details. | |
| 15 * | |
| 16 * You should have received a copy of the GNU General Public License | |
| 17 * along with this program; if not, write to the Free Software | |
| 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
| 19 */ | |
| 20 | |
| 21 /* | |
| 22 * ---------------- | |
| 23 * The Plug-in plugin | |
| 24 * | |
| 25 * Plugin support is currently being maintained by Mike Saraf | |
| 26 * msaraf@dwc.edu | |
| 27 * | |
| 28 * Well, I didn't see any work done on it for a while, so I'm going to try | |
| 29 * my hand at it. - Eric warmenhoven@yahoo.com | |
| 30 * | |
| 31 * Mike is my roomate. I can assure you that he's lazy :-P | |
| 32 * -- Rob rob@marko.net | |
| 33 * | |
| 34 * Yeah, well now I'm re-writing a good portion of it! The perl stuff was | |
| 35 * a hack. Tsk tsk! -- Christian <chipx86@gnupdate.org> | |
| 36 */ | |
|
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5840
diff
changeset
|
37 #include "internal.h" |
| 5205 | 38 |
|
5638
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5573
diff
changeset
|
39 #include "accountopt.h" |
|
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5840
diff
changeset
|
40 #include "debug.h" |
| 5205 | 41 #include "event.h" |
|
5436
ad445074d239
[gaim-migrate @ 5818]
Christian Hammond <chipx86@chipx86.com>
parents:
5357
diff
changeset
|
42 #include "notify.h" |
|
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5840
diff
changeset
|
43 #include "prefs.h" |
|
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5840
diff
changeset
|
44 #include "prpl.h" |
|
059d95c67cda
[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
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
56 static GList *protocol_plugins = NULL; |
| 5205 | 57 |
| 58 static size_t search_path_count = 0; | |
| 59 static char **search_paths = NULL; | |
| 60 | |
| 61 static void (*probe_cb)(void *) = NULL; | |
| 62 static void *probe_cb_data = NULL; | |
| 63 static void (*load_cb)(GaimPlugin *, void *) = NULL; | |
| 64 static void *load_cb_data = NULL; | |
| 65 static void (*unload_cb)(GaimPlugin *, void *) = NULL; | |
| 66 static void *unload_cb_data = NULL; | |
| 67 | |
| 68 #ifdef GAIM_PLUGINS | |
| 69 static int | |
| 70 is_so_file(const char *filename, const char *ext) | |
| 71 { | |
| 72 int len, extlen; | |
| 73 | |
| 74 if (filename == NULL || *filename == '\0' || ext == NULL) | |
| 75 return 0; | |
| 76 | |
| 77 extlen = strlen(ext); | |
| 78 len = strlen(filename) - extlen; | |
| 79 | |
| 80 if (len < 0) | |
| 81 return 0; | |
| 82 | |
| 83 return (!strncmp(filename + len, ext, extlen)); | |
| 84 } | |
| 85 | |
| 86 static gboolean | |
|
5794
5e93fc46d1af
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5646
diff
changeset
|
87 loader_supports_file(GaimPlugin *loader, const char *filename) |
| 5205 | 88 { |
| 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
5e93fc46d1af
[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
5e93fc46d1af
[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 | 131 #endif /* GAIM_PLUGINS */ |
| 132 | |
| 5838 | 133 static void |
| 134 update_plugin_prefs(void) | |
| 135 { | |
| 136 GList *pl; | |
| 137 GList *files = NULL; | |
| 138 GaimPlugin *p; | |
| 139 | |
| 140 for (pl = gaim_plugins_get_loaded(); pl != NULL; pl = pl->next) { | |
| 141 p = pl->data; | |
| 142 | |
| 143 if(p->info->type != GAIM_PLUGIN_PROTOCOL && | |
| 144 p->info->type != GAIM_PLUGIN_LOADER) { | |
| 145 files = g_list_append(files, p->path); | |
| 146 } | |
| 147 } | |
| 148 | |
| 149 gaim_prefs_set_string_list("/plugins/loaded", files); | |
| 150 g_list_free(files); | |
| 151 } | |
| 152 | |
| 5205 | 153 static gint |
| 154 compare_prpl(GaimPlugin *a, GaimPlugin *b) | |
| 155 { | |
| 156 /* neg if a before b, 0 if equal, pos if a after b */ | |
| 157 return ((GAIM_IS_PROTOCOL_PLUGIN(a) | |
| 158 ? GAIM_PLUGIN_PROTOCOL_INFO(a)->protocol : -1) - | |
| 159 ((GAIM_IS_PROTOCOL_PLUGIN(b) | |
| 160 ? GAIM_PLUGIN_PROTOCOL_INFO(b)->protocol : -1))); | |
| 161 } | |
| 162 | |
| 163 GaimPlugin * | |
| 164 gaim_plugin_new(gboolean native, const char *path) | |
| 165 { | |
| 166 GaimPlugin *plugin; | |
| 167 | |
| 168 plugin = g_new0(GaimPlugin, 1); | |
| 169 | |
| 170 plugin->native_plugin = native; | |
| 171 plugin->path = (path == NULL ? NULL : g_strdup(path)); | |
| 172 | |
| 173 return plugin; | |
| 174 } | |
| 175 | |
| 176 GaimPlugin * | |
| 177 gaim_plugin_probe(const char *filename) | |
| 178 { | |
| 179 #ifdef GAIM_PLUGINS | |
| 180 GaimPlugin *plugin = NULL; | |
| 181 GaimPlugin *loader; | |
| 182 gboolean (*gaim_init_plugin)(GaimPlugin *); | |
| 183 | |
| 184 g_return_val_if_fail(filename != NULL, NULL); | |
| 185 | |
| 186 plugin = gaim_plugins_find_with_filename(filename); | |
| 187 | |
| 188 if (plugin != NULL) | |
| 189 return plugin; | |
| 190 | |
| 191 plugin = gaim_plugin_new(is_so_file(filename, PLUGIN_EXT), filename); | |
| 192 | |
| 193 if (plugin->native_plugin) { | |
| 5450 | 194 const char *error; |
| 5205 | 195 plugin->handle = g_module_open(filename, 0); |
| 196 | |
| 197 if (plugin->handle == NULL) { | |
| 5443 | 198 error = g_module_error(); |
|
5269
cd7e4ba049f9
[gaim-migrate @ 5641]
Christian Hammond <chipx86@chipx86.com>
parents:
5268
diff
changeset
|
199 gaim_debug(GAIM_DEBUG_ERROR, "plugins", "%s is unloadable: %s\n", |
| 5443 | 200 plugin->path, error ? error : "Unknown error."); |
| 5205 | 201 |
|
5269
cd7e4ba049f9
[gaim-migrate @ 5641]
Christian Hammond <chipx86@chipx86.com>
parents:
5268
diff
changeset
|
202 gaim_plugin_destroy(plugin); |
|
cd7e4ba049f9
[gaim-migrate @ 5641]
Christian Hammond <chipx86@chipx86.com>
parents:
5268
diff
changeset
|
203 |
|
cd7e4ba049f9
[gaim-migrate @ 5641]
Christian Hammond <chipx86@chipx86.com>
parents:
5268
diff
changeset
|
204 return NULL; |
| 5205 | 205 } |
| 206 | |
| 207 if (!g_module_symbol(plugin->handle, "gaim_init_plugin", | |
| 208 (gpointer *)&gaim_init_plugin)) { | |
| 209 g_module_close(plugin->handle); | |
| 210 plugin->handle = NULL; | |
| 211 | |
| 5443 | 212 error = g_module_error(); |
|
5211
0241d6b6702d
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
213 gaim_debug(GAIM_DEBUG_ERROR, "plugins", "%s is unloadable: %s\n", |
| 5443 | 214 plugin->path, error ? error : "Unknown error."); |
| 5205 | 215 |
| 216 gaim_plugin_destroy(plugin); | |
| 217 | |
| 218 return NULL; | |
| 219 } | |
| 220 } | |
| 221 else { | |
|
5794
5e93fc46d1af
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5646
diff
changeset
|
222 loader = find_loader_for_plugin(plugin); |
| 5205 | 223 |
| 224 if (loader == NULL) { | |
| 225 gaim_plugin_destroy(plugin); | |
| 226 | |
| 227 return NULL; | |
| 228 } | |
| 229 | |
| 230 gaim_init_plugin = GAIM_PLUGIN_LOADER_INFO(loader)->probe; | |
| 231 } | |
| 232 | |
| 233 plugin->error = NULL; | |
| 234 | |
| 235 if (!gaim_init_plugin(plugin) || plugin->info == NULL) { | |
| 236 char buf[BUFSIZ]; | |
| 237 | |
| 238 g_snprintf(buf, sizeof(buf), | |
| 239 _("The plugin %s did not return any valid plugin " | |
| 240 "information"), | |
| 241 plugin->path); | |
| 242 | |
|
5436
ad445074d239
[gaim-migrate @ 5818]
Christian Hammond <chipx86@chipx86.com>
parents:
5357
diff
changeset
|
243 gaim_notify_error(NULL, NULL, |
|
ad445074d239
[gaim-migrate @ 5818]
Christian Hammond <chipx86@chipx86.com>
parents:
5357
diff
changeset
|
244 _("Gaim was unable to load your plugin."), buf); |
| 5205 | 245 |
| 246 gaim_plugin_destroy(plugin); | |
| 247 | |
| 248 return NULL; | |
| 249 } | |
| 250 | |
| 251 return plugin; | |
| 252 #else | |
| 253 return NULL; | |
| 254 #endif /* !GAIM_PLUGINS */ | |
| 255 } | |
| 256 | |
| 257 gboolean | |
| 258 gaim_plugin_load(GaimPlugin *plugin) | |
| 259 { | |
| 260 #ifdef GAIM_PLUGINS | |
| 261 g_return_val_if_fail(plugin != NULL, FALSE); | |
|
5270
d1fe8e320dab
[gaim-migrate @ 5642]
Christian Hammond <chipx86@chipx86.com>
parents:
5269
diff
changeset
|
262 g_return_val_if_fail(plugin->error == NULL, FALSE); |
| 5205 | 263 |
| 264 if (gaim_plugin_is_loaded(plugin)) | |
| 265 return TRUE; | |
| 266 | |
| 267 if (plugin->native_plugin) { | |
|
5357
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
268 if (plugin->info != NULL) { |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
269 if (plugin->info->load != NULL) |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
270 plugin->info->load(plugin); |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
271 |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
272 if (plugin->info->type == GAIM_PLUGIN_LOADER) { |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
273 GaimPluginLoaderInfo *loader_info; |
|
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 loader_info = GAIM_PLUGIN_LOADER_INFO(plugin); |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
276 |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
277 if (loader_info->broadcast != NULL) |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
278 gaim_signals_register_broadcast_func(loader_info->broadcast, |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
279 NULL); |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
280 } |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
281 } |
| 5205 | 282 } |
| 283 else { | |
| 284 GaimPlugin *loader; | |
| 285 GaimPluginLoaderInfo *loader_info; | |
| 286 | |
|
5794
5e93fc46d1af
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5646
diff
changeset
|
287 loader = find_loader_for_plugin(plugin); |
| 5205 | 288 |
| 289 if (loader == NULL) | |
| 290 return FALSE; | |
| 291 | |
| 292 loader_info = GAIM_PLUGIN_LOADER_INFO(loader); | |
| 293 | |
| 294 if (loader_info->load != NULL) | |
| 295 loader_info->load(plugin); | |
| 296 } | |
| 297 | |
| 298 loaded_plugins = g_list_append(loaded_plugins, plugin); | |
| 5838 | 299 update_plugin_prefs(); |
| 5205 | 300 |
| 301 plugin->loaded = TRUE; | |
| 302 | |
| 303 /* TODO */ | |
| 304 if (load_cb != NULL) | |
| 305 load_cb(plugin, load_cb_data); | |
| 306 | |
| 307 return TRUE; | |
| 308 | |
| 309 #else | |
| 5449 | 310 return TRUE; |
| 5205 | 311 #endif /* !GAIM_PLUGINS */ |
| 312 } | |
| 313 | |
| 314 gboolean | |
| 315 gaim_plugin_unload(GaimPlugin *plugin) | |
| 316 { | |
| 317 #ifdef GAIM_PLUGINS | |
| 318 g_return_val_if_fail(plugin != NULL, FALSE); | |
| 319 | |
| 320 loaded_plugins = g_list_remove(loaded_plugins, plugin); | |
| 5838 | 321 update_plugin_prefs(); |
| 5205 | 322 |
| 323 g_return_val_if_fail(gaim_plugin_is_loaded(plugin), FALSE); | |
| 324 | |
|
5211
0241d6b6702d
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
325 gaim_debug(GAIM_DEBUG_INFO, "plugins", "Unloading plugin %s\n", |
|
0241d6b6702d
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
326 plugin->info->name); |
| 5205 | 327 |
| 328 /* cancel any pending dialogs the plugin has */ | |
|
5498
cce2d7868c78
[gaim-migrate @ 5894]
Christian Hammond <chipx86@chipx86.com>
parents:
5450
diff
changeset
|
329 gaim_request_close_with_handle(plugin); |
|
cce2d7868c78
[gaim-migrate @ 5894]
Christian Hammond <chipx86@chipx86.com>
parents:
5450
diff
changeset
|
330 gaim_notify_close_with_handle(plugin); |
| 5205 | 331 |
| 332 plugin->loaded = FALSE; | |
| 333 | |
| 334 if (plugin->native_plugin) { | |
| 335 if (plugin->info->unload != NULL) | |
| 336 plugin->info->unload(plugin); | |
| 337 | |
| 338 if (plugin->info->type == GAIM_PLUGIN_PROTOCOL) { | |
| 339 GaimPluginProtocolInfo *prpl_info; | |
| 340 GList *l; | |
| 341 | |
| 342 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(plugin); | |
| 343 | |
|
5638
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5573
diff
changeset
|
344 for (l = prpl_info->user_splits; l != NULL; l = l->next) |
|
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5573
diff
changeset
|
345 gaim_account_user_split_destroy(l->data); |
| 5205 | 346 |
|
5638
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5573
diff
changeset
|
347 for (l = prpl_info->protocol_options; l != NULL; l = l->next) |
|
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5573
diff
changeset
|
348 gaim_account_option_destroy(l->data); |
| 5205 | 349 |
|
5646
48c63ee49961
[gaim-migrate @ 6060]
Christian Hammond <chipx86@chipx86.com>
parents:
5638
diff
changeset
|
350 if (prpl_info->user_splits != NULL) |
|
48c63ee49961
[gaim-migrate @ 6060]
Christian Hammond <chipx86@chipx86.com>
parents:
5638
diff
changeset
|
351 g_list_free(prpl_info->user_splits); |
|
48c63ee49961
[gaim-migrate @ 6060]
Christian Hammond <chipx86@chipx86.com>
parents:
5638
diff
changeset
|
352 |
|
48c63ee49961
[gaim-migrate @ 6060]
Christian Hammond <chipx86@chipx86.com>
parents:
5638
diff
changeset
|
353 if (prpl_info->protocol_options != NULL) |
|
48c63ee49961
[gaim-migrate @ 6060]
Christian Hammond <chipx86@chipx86.com>
parents:
5638
diff
changeset
|
354 g_list_free(prpl_info->protocol_options); |
| 5205 | 355 } |
|
5357
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
356 else if (plugin->info->type == GAIM_PLUGIN_LOADER) { |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
357 GaimPluginLoaderInfo *loader_info; |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
358 |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
359 loader_info = GAIM_PLUGIN_LOADER_INFO(plugin); |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
360 |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
361 if (loader_info->broadcast != NULL) |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
362 gaim_signals_unregister_broadcast_func(loader_info->broadcast); |
|
2a1c92df7024
[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 | |
|
5794
5e93fc46d1af
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5646
diff
changeset
|
369 loader = find_loader_for_plugin(plugin); |
| 5205 | 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 | 387 #else |
| 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 | 407 return TRUE; |
| 5205 | 408 #endif /* !GAIM_PLUGINS */ |
| 409 } | |
| 410 | |
| 411 void | |
| 412 gaim_plugin_destroy(GaimPlugin *plugin) | |
| 413 { | |
| 5449 | 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
f6e0c689a88b
[gaim-migrate @ 5614]
Christian Hammond <chipx86@chipx86.com>
parents:
5242
diff
changeset
|
422 if (plugin->info != NULL && plugin->info->dependencies != NULL) |
|
f6e0c689a88b
[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 | |
|
5794
5e93fc46d1af
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5646
diff
changeset
|
460 loader = find_loader_for_plugin(plugin); |
| 5205 | 461 |
|
5941
a3e60ff95b7d
[gaim-migrate @ 6381]
Christian Hammond <chipx86@chipx86.com>
parents:
5872
diff
changeset
|
462 if (loader != NULL) { |
|
a3e60ff95b7d
[gaim-migrate @ 6381]
Christian Hammond <chipx86@chipx86.com>
parents:
5872
diff
changeset
|
463 loader_info = GAIM_PLUGIN_LOADER_INFO(loader); |
| 5205 | 464 |
|
5941
a3e60ff95b7d
[gaim-migrate @ 6381]
Christian Hammond <chipx86@chipx86.com>
parents:
5872
diff
changeset
|
465 if (loader_info->destroy != NULL) |
|
a3e60ff95b7d
[gaim-migrate @ 6381]
Christian Hammond <chipx86@chipx86.com>
parents:
5872
diff
changeset
|
466 loader_info->destroy(plugin); |
|
a3e60ff95b7d
[gaim-migrate @ 6381]
Christian Hammond <chipx86@chipx86.com>
parents:
5872
diff
changeset
|
467 } |
| 5205 | 468 } |
| 469 | |
| 470 if (plugin->path != NULL) g_free(plugin->path); | |
| 471 if (plugin->error != NULL) g_free(plugin->error); | |
| 472 | |
| 473 g_free(plugin); | |
| 5449 | 474 #endif /* !GAIM_PLUGINS */ |
| 5205 | 475 } |
| 476 | |
| 477 gboolean | |
| 478 gaim_plugin_is_loaded(const GaimPlugin *plugin) | |
| 479 { | |
| 480 g_return_val_if_fail(plugin != NULL, FALSE); | |
| 481 | |
| 482 return plugin->loaded; | |
| 483 } | |
| 484 | |
| 485 void | |
| 486 gaim_plugins_set_search_paths(size_t count, char **paths) | |
| 487 { | |
| 488 size_t s; | |
| 489 | |
| 490 g_return_if_fail(count > 0); | |
| 491 g_return_if_fail(paths != NULL); | |
| 492 | |
| 493 if (search_paths != NULL) { | |
| 494 for (s = 0; s < search_path_count; s++) | |
| 495 g_free(search_paths[s]); | |
| 496 | |
| 497 g_free(search_paths); | |
| 498 } | |
| 499 | |
| 500 search_paths = g_new0(char *, count); | |
| 501 | |
| 502 for (s = 0; s < count; s++) { | |
| 503 if (paths[s] == NULL) | |
| 504 search_paths[s] = NULL; | |
| 505 else | |
| 506 search_paths[s] = g_strdup(paths[s]); | |
| 507 } | |
| 508 | |
| 509 search_path_count = count; | |
| 510 } | |
| 511 | |
| 512 void | |
| 513 gaim_plugins_unload_all(void) | |
| 514 { | |
| 515 #ifdef GAIM_PLUGINS | |
| 516 | |
| 517 while (loaded_plugins != NULL) | |
| 518 gaim_plugin_unload(loaded_plugins->data); | |
| 519 | |
| 520 #endif /* GAIM_PLUGINS */ | |
| 521 } | |
| 522 | |
| 523 void | |
|
5242
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
524 gaim_plugins_destroy_all(void) |
|
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 #ifdef GAIM_PLUGINS |
|
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
527 |
|
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
528 while (plugins != NULL) |
|
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
529 gaim_plugin_destroy(plugins->data); |
|
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
530 |
|
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
531 #endif /* GAIM_PLUGINS */ |
|
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
532 } |
| 5838 | 533 |
| 534 void | |
| 5840 | 535 gaim_plugins_load_saved(void) |
| 5838 | 536 { |
| 537 #ifdef GAIM_PLUGINS | |
| 538 GList *f, *files = gaim_prefs_get_string_list("/plugins/loaded"); | |
| 539 | |
| 540 for(f = files; f; f = f->next) { | |
| 541 gaim_plugin_load(gaim_plugin_probe(f->data)); | |
| 542 g_free(f->data); | |
| 543 } | |
| 544 | |
| 545 g_list_free(files); | |
| 546 #endif /* GAIM_PLUGINS */ | |
| 547 } | |
| 548 | |
| 549 | |
|
5242
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
550 void |
| 5205 | 551 gaim_plugins_probe(const char *ext) |
| 552 { | |
| 553 #ifdef GAIM_PLUGINS | |
| 554 GDir *dir; | |
| 555 const gchar *file; | |
| 556 gchar *path; | |
| 557 GaimPlugin *plugin; | |
| 558 size_t i; | |
| 559 | |
| 560 if (!g_module_supported()) | |
| 561 return; | |
| 562 | |
| 563 for (i = 0; i < search_path_count; i++) { | |
| 564 if (search_paths[i] == NULL) | |
| 565 continue; | |
| 566 | |
| 567 dir = g_dir_open(search_paths[i], 0, NULL); | |
| 568 | |
| 569 if (dir != NULL) { | |
| 570 while ((file = g_dir_read_name(dir)) != NULL) { | |
| 571 path = g_build_filename(search_paths[i], file, NULL); | |
| 572 | |
| 573 if (ext == NULL || is_so_file(file, ext)) | |
| 574 plugin = gaim_plugin_probe(path); | |
| 575 | |
| 576 g_free(path); | |
| 577 } | |
| 578 | |
| 579 g_dir_close(dir); | |
| 580 } | |
| 581 } | |
| 582 | |
| 583 if (probe_cb != NULL) | |
| 584 probe_cb(probe_cb_data); | |
| 585 | |
| 586 #endif /* GAIM_PLUGINS */ | |
| 587 } | |
| 588 | |
| 589 gboolean | |
| 590 gaim_plugin_register(GaimPlugin *plugin) | |
| 591 { | |
| 592 g_return_val_if_fail(plugin != NULL, FALSE); | |
| 593 | |
| 594 if (g_list_find(plugins, plugin)) | |
| 595 return TRUE; | |
| 596 | |
| 597 /* Special exception for loader plugins. We want them loaded NOW! */ | |
| 598 if (plugin->info->type == GAIM_PLUGIN_LOADER) { | |
| 599 GList *exts; | |
| 600 | |
| 601 /* We'll just load this right now. */ | |
| 602 if (!gaim_plugin_load(plugin)) { | |
| 603 | |
| 604 gaim_plugin_destroy(plugin); | |
| 605 | |
| 606 return FALSE; | |
| 607 } | |
| 608 | |
| 609 plugin_loaders = g_list_append(plugin_loaders, plugin); | |
| 610 | |
| 611 for (exts = GAIM_PLUGIN_LOADER_INFO(plugin)->exts; | |
| 612 exts != NULL; | |
| 613 exts = exts->next) { | |
| 614 | |
| 615 gaim_plugins_probe(exts->data); | |
| 616 } | |
| 617 } | |
| 618 else if (plugin->info->type == GAIM_PLUGIN_PROTOCOL) { | |
| 619 | |
| 620 /* We'll just load this right now. */ | |
| 621 if (!gaim_plugin_load(plugin)) { | |
| 622 | |
| 623 gaim_plugin_destroy(plugin); | |
| 624 | |
| 625 return FALSE; | |
| 626 } | |
| 627 | |
| 628 if (GAIM_PLUGIN_PROTOCOL_INFO(plugin)->protocol == GAIM_PROTO_ICQ || | |
| 629 gaim_find_prpl(GAIM_PLUGIN_PROTOCOL_INFO(plugin)->protocol)) { | |
| 630 | |
| 631 /* Nothing to see here--move along, move along */ | |
| 632 gaim_plugin_destroy(plugin); | |
| 633 | |
| 634 return FALSE; | |
| 635 } | |
| 636 | |
|
5573
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
637 protocol_plugins = g_list_insert_sorted(protocol_plugins, plugin, |
|
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
638 (GCompareFunc)compare_prpl); |
| 5205 | 639 } |
| 640 | |
| 641 plugins = g_list_append(plugins, plugin); | |
| 642 | |
| 643 return TRUE; | |
| 644 } | |
| 645 | |
| 646 gboolean | |
| 647 gaim_plugins_enabled(void) | |
| 648 { | |
| 649 #ifdef GAIM_PLUGINS | |
| 650 return TRUE; | |
| 651 #else | |
| 652 return FALSE; | |
| 653 #endif | |
| 654 } | |
| 655 | |
| 656 void | |
| 657 gaim_plugins_register_probe_notify_cb(void (*func)(void *), void *data) | |
| 658 { | |
| 659 /* TODO */ | |
| 660 probe_cb = func; | |
| 661 probe_cb_data = data; | |
| 662 } | |
| 663 | |
| 664 void | |
| 665 gaim_plugins_unregister_probe_notify_cb(void (*func)(void *)) | |
| 666 { | |
| 667 /* TODO */ | |
| 668 probe_cb = NULL; | |
| 669 probe_cb_data = NULL; | |
| 670 } | |
| 671 | |
| 672 void | |
| 673 gaim_plugins_register_load_notify_cb(void (*func)(GaimPlugin *, void *), | |
| 674 void *data) | |
| 675 { | |
| 676 /* TODO */ | |
| 677 load_cb = func; | |
| 678 load_cb_data = data; | |
| 679 } | |
| 680 | |
| 681 void | |
| 682 gaim_plugins_unregister_load_notify_cb(void (*func)(GaimPlugin *, void *)) | |
| 683 { | |
| 684 /* TODO */ | |
| 685 load_cb = NULL; | |
| 686 load_cb_data = NULL; | |
| 687 } | |
| 688 | |
| 689 void | |
| 690 gaim_plugins_register_unload_notify_cb(void (*func)(GaimPlugin *, void *), | |
| 691 void *data) | |
| 692 { | |
| 693 /* TODO */ | |
| 694 unload_cb = func; | |
| 695 unload_cb_data = data; | |
| 696 } | |
| 697 | |
| 698 void | |
| 699 gaim_plugins_unregister_unload_notify_cb(void (*func)(GaimPlugin *, void *)) | |
| 700 { | |
| 701 /* TODO */ | |
| 702 unload_cb = NULL; | |
| 703 unload_cb_data = NULL; | |
| 704 } | |
| 705 | |
| 706 GaimPlugin * | |
| 707 gaim_plugins_find_with_name(const char *name) | |
| 708 { | |
| 709 GaimPlugin *plugin; | |
| 710 GList *l; | |
| 711 | |
| 712 for (l = plugins; l != NULL; l = l->next) { | |
| 713 plugin = l->data; | |
| 714 | |
| 715 if (!strcmp(plugin->info->name, name)) | |
| 716 return plugin; | |
| 717 } | |
| 718 | |
| 719 return NULL; | |
| 720 } | |
| 721 | |
| 722 GaimPlugin * | |
| 723 gaim_plugins_find_with_filename(const char *filename) | |
| 724 { | |
| 725 GaimPlugin *plugin; | |
| 726 GList *l; | |
| 727 | |
| 728 for (l = plugins; l != NULL; l = l->next) { | |
| 729 plugin = l->data; | |
| 730 | |
| 731 if (plugin->path != NULL && !strcmp(plugin->path, filename)) | |
| 732 return plugin; | |
| 733 } | |
| 734 | |
| 735 return NULL; | |
| 736 } | |
| 737 | |
| 738 GaimPlugin * | |
| 739 gaim_plugins_find_with_id(const char *id) | |
| 740 { | |
| 741 GaimPlugin *plugin; | |
| 742 GList *l; | |
| 743 | |
| 744 g_return_val_if_fail(id != NULL, NULL); | |
| 745 | |
| 746 for (l = plugins; l != NULL; l = l->next) { | |
| 747 plugin = l->data; | |
| 748 | |
| 749 if (!strcmp(plugin->info->id, id)) | |
| 750 return plugin; | |
| 751 } | |
| 752 | |
| 753 return NULL; | |
| 754 } | |
| 755 | |
| 756 GList * | |
| 757 gaim_plugins_get_loaded(void) | |
| 758 { | |
| 759 return loaded_plugins; | |
| 760 } | |
| 761 | |
| 762 GList * | |
|
5573
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
763 gaim_plugins_get_protocols(void) |
|
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
764 { |
|
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
765 return protocol_plugins; |
|
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
766 } |
|
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
767 |
|
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
768 GList * |
| 5205 | 769 gaim_plugins_get_all(void) |
| 770 { | |
| 771 return plugins; | |
| 772 } | |
| 773 |
