Mercurial > pidgin
annotate src/plugin.c @ 5867:db4df0be06fd
[gaim-migrate @ 6298]
Added a little bit of code to prevent duplicate accounts, but it doesn't
fix the problem of importing all new accounts when are importing from the
old .gaimrc and also have an accounts.xml already established.
committer: Tailor Script <tailor@pidgin.im>
| author | Christian Hammond <chipx86@chipx86.com> |
|---|---|
| date | Sat, 14 Jun 2003 12:01:19 +0000 |
| parents | 8f5ccf9e590a |
| children | 059d95c67cda |
| 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 | |
|
5794
5e93fc46d1af
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5646
diff
changeset
|
101 loader_supports_file(GaimPlugin *loader, const char *filename) |
| 5205 | 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 * | |
|
5794
5e93fc46d1af
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5646
diff
changeset
|
122 find_loader_for_plugin(const GaimPlugin *plugin) |
| 5205 | 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 && | |
|
5794
5e93fc46d1af
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5646
diff
changeset
|
134 loader_supports_file(loader, plugin->path)) { |
| 5205 | 135 |
| 136 return loader; | |
| 137 } | |
| 138 | |
| 139 loader = NULL; | |
| 140 } | |
| 141 | |
| 142 return NULL; | |
| 143 } | |
| 144 | |
| 5449 | 145 #endif /* GAIM_PLUGINS */ |
| 146 | |
| 5838 | 147 static void |
| 148 update_plugin_prefs(void) | |
| 149 { | |
| 150 GList *pl; | |
| 151 GList *files = NULL; | |
| 152 GaimPlugin *p; | |
| 153 | |
| 154 for (pl = gaim_plugins_get_loaded(); pl != NULL; pl = pl->next) { | |
| 155 p = pl->data; | |
| 156 | |
| 157 if(p->info->type != GAIM_PLUGIN_PROTOCOL && | |
| 158 p->info->type != GAIM_PLUGIN_LOADER) { | |
| 159 files = g_list_append(files, p->path); | |
| 160 } | |
| 161 } | |
| 162 | |
| 163 gaim_prefs_set_string_list("/plugins/loaded", files); | |
| 164 g_list_free(files); | |
| 165 } | |
| 166 | |
| 5205 | 167 static gint |
| 168 compare_prpl(GaimPlugin *a, GaimPlugin *b) | |
| 169 { | |
| 170 /* neg if a before b, 0 if equal, pos if a after b */ | |
| 171 return ((GAIM_IS_PROTOCOL_PLUGIN(a) | |
| 172 ? GAIM_PLUGIN_PROTOCOL_INFO(a)->protocol : -1) - | |
| 173 ((GAIM_IS_PROTOCOL_PLUGIN(b) | |
| 174 ? GAIM_PLUGIN_PROTOCOL_INFO(b)->protocol : -1))); | |
| 175 } | |
| 176 | |
| 177 GaimPlugin * | |
| 178 gaim_plugin_new(gboolean native, const char *path) | |
| 179 { | |
| 180 GaimPlugin *plugin; | |
| 181 | |
| 182 plugin = g_new0(GaimPlugin, 1); | |
| 183 | |
| 184 plugin->native_plugin = native; | |
| 185 plugin->path = (path == NULL ? NULL : g_strdup(path)); | |
| 186 | |
| 187 return plugin; | |
| 188 } | |
| 189 | |
| 190 GaimPlugin * | |
| 191 gaim_plugin_probe(const char *filename) | |
| 192 { | |
| 193 #ifdef GAIM_PLUGINS | |
| 194 GaimPlugin *plugin = NULL; | |
| 195 GaimPlugin *loader; | |
| 196 gboolean (*gaim_init_plugin)(GaimPlugin *); | |
| 197 | |
| 198 g_return_val_if_fail(filename != NULL, NULL); | |
| 199 | |
| 200 plugin = gaim_plugins_find_with_filename(filename); | |
| 201 | |
| 202 if (plugin != NULL) | |
| 203 return plugin; | |
| 204 | |
| 205 plugin = gaim_plugin_new(is_so_file(filename, PLUGIN_EXT), filename); | |
| 206 | |
| 207 if (plugin->native_plugin) { | |
| 5450 | 208 const char *error; |
| 5205 | 209 plugin->handle = g_module_open(filename, 0); |
| 210 | |
| 211 if (plugin->handle == NULL) { | |
| 5443 | 212 error = g_module_error(); |
|
5269
cd7e4ba049f9
[gaim-migrate @ 5641]
Christian Hammond <chipx86@chipx86.com>
parents:
5268
diff
changeset
|
213 gaim_debug(GAIM_DEBUG_ERROR, "plugins", "%s is unloadable: %s\n", |
| 5443 | 214 plugin->path, error ? error : "Unknown error."); |
| 5205 | 215 |
|
5269
cd7e4ba049f9
[gaim-migrate @ 5641]
Christian Hammond <chipx86@chipx86.com>
parents:
5268
diff
changeset
|
216 gaim_plugin_destroy(plugin); |
|
cd7e4ba049f9
[gaim-migrate @ 5641]
Christian Hammond <chipx86@chipx86.com>
parents:
5268
diff
changeset
|
217 |
|
cd7e4ba049f9
[gaim-migrate @ 5641]
Christian Hammond <chipx86@chipx86.com>
parents:
5268
diff
changeset
|
218 return NULL; |
| 5205 | 219 } |
| 220 | |
| 221 if (!g_module_symbol(plugin->handle, "gaim_init_plugin", | |
| 222 (gpointer *)&gaim_init_plugin)) { | |
| 223 g_module_close(plugin->handle); | |
| 224 plugin->handle = NULL; | |
| 225 | |
| 5443 | 226 error = g_module_error(); |
|
5211
0241d6b6702d
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
227 gaim_debug(GAIM_DEBUG_ERROR, "plugins", "%s is unloadable: %s\n", |
| 5443 | 228 plugin->path, error ? error : "Unknown error."); |
| 5205 | 229 |
| 230 gaim_plugin_destroy(plugin); | |
| 231 | |
| 232 return NULL; | |
| 233 } | |
| 234 } | |
| 235 else { | |
|
5794
5e93fc46d1af
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5646
diff
changeset
|
236 loader = find_loader_for_plugin(plugin); |
| 5205 | 237 |
| 238 if (loader == NULL) { | |
| 239 gaim_plugin_destroy(plugin); | |
| 240 | |
| 241 return NULL; | |
| 242 } | |
| 243 | |
| 244 gaim_init_plugin = GAIM_PLUGIN_LOADER_INFO(loader)->probe; | |
| 245 } | |
| 246 | |
| 247 plugin->error = NULL; | |
| 248 | |
| 249 if (!gaim_init_plugin(plugin) || plugin->info == NULL) { | |
| 250 char buf[BUFSIZ]; | |
| 251 | |
| 252 g_snprintf(buf, sizeof(buf), | |
| 253 _("The plugin %s did not return any valid plugin " | |
| 254 "information"), | |
| 255 plugin->path); | |
| 256 | |
|
5436
ad445074d239
[gaim-migrate @ 5818]
Christian Hammond <chipx86@chipx86.com>
parents:
5357
diff
changeset
|
257 gaim_notify_error(NULL, NULL, |
|
ad445074d239
[gaim-migrate @ 5818]
Christian Hammond <chipx86@chipx86.com>
parents:
5357
diff
changeset
|
258 _("Gaim was unable to load your plugin."), buf); |
| 5205 | 259 |
| 260 gaim_plugin_destroy(plugin); | |
| 261 | |
| 262 return NULL; | |
| 263 } | |
| 264 | |
| 265 return plugin; | |
| 266 #else | |
| 267 return NULL; | |
| 268 #endif /* !GAIM_PLUGINS */ | |
| 269 } | |
| 270 | |
| 271 gboolean | |
| 272 gaim_plugin_load(GaimPlugin *plugin) | |
| 273 { | |
| 274 #ifdef GAIM_PLUGINS | |
| 275 g_return_val_if_fail(plugin != NULL, FALSE); | |
|
5270
d1fe8e320dab
[gaim-migrate @ 5642]
Christian Hammond <chipx86@chipx86.com>
parents:
5269
diff
changeset
|
276 g_return_val_if_fail(plugin->error == NULL, FALSE); |
| 5205 | 277 |
| 278 if (gaim_plugin_is_loaded(plugin)) | |
| 279 return TRUE; | |
| 280 | |
| 281 if (plugin->native_plugin) { | |
|
5357
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
282 if (plugin->info != NULL) { |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
283 if (plugin->info->load != NULL) |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
284 plugin->info->load(plugin); |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
285 |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
286 if (plugin->info->type == GAIM_PLUGIN_LOADER) { |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
287 GaimPluginLoaderInfo *loader_info; |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
288 |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
289 loader_info = GAIM_PLUGIN_LOADER_INFO(plugin); |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
290 |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
291 if (loader_info->broadcast != NULL) |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
292 gaim_signals_register_broadcast_func(loader_info->broadcast, |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
293 NULL); |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
294 } |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
295 } |
| 5205 | 296 } |
| 297 else { | |
| 298 GaimPlugin *loader; | |
| 299 GaimPluginLoaderInfo *loader_info; | |
| 300 | |
|
5794
5e93fc46d1af
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5646
diff
changeset
|
301 loader = find_loader_for_plugin(plugin); |
| 5205 | 302 |
| 303 if (loader == NULL) | |
| 304 return FALSE; | |
| 305 | |
| 306 loader_info = GAIM_PLUGIN_LOADER_INFO(loader); | |
| 307 | |
| 308 if (loader_info->load != NULL) | |
| 309 loader_info->load(plugin); | |
| 310 } | |
| 311 | |
| 312 loaded_plugins = g_list_append(loaded_plugins, plugin); | |
| 5838 | 313 update_plugin_prefs(); |
| 5205 | 314 |
| 315 plugin->loaded = TRUE; | |
| 316 | |
| 317 /* TODO */ | |
| 318 if (load_cb != NULL) | |
| 319 load_cb(plugin, load_cb_data); | |
| 320 | |
| 321 return TRUE; | |
| 322 | |
| 323 #else | |
| 5449 | 324 return TRUE; |
| 5205 | 325 #endif /* !GAIM_PLUGINS */ |
| 326 } | |
| 327 | |
| 328 gboolean | |
| 329 gaim_plugin_unload(GaimPlugin *plugin) | |
| 330 { | |
| 331 #ifdef GAIM_PLUGINS | |
| 332 g_return_val_if_fail(plugin != NULL, FALSE); | |
| 333 | |
| 334 loaded_plugins = g_list_remove(loaded_plugins, plugin); | |
| 5838 | 335 update_plugin_prefs(); |
| 5205 | 336 |
| 337 g_return_val_if_fail(gaim_plugin_is_loaded(plugin), FALSE); | |
| 338 | |
|
5211
0241d6b6702d
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
339 gaim_debug(GAIM_DEBUG_INFO, "plugins", "Unloading plugin %s\n", |
|
0241d6b6702d
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
340 plugin->info->name); |
| 5205 | 341 |
| 342 /* cancel any pending dialogs the plugin has */ | |
|
5498
cce2d7868c78
[gaim-migrate @ 5894]
Christian Hammond <chipx86@chipx86.com>
parents:
5450
diff
changeset
|
343 gaim_request_close_with_handle(plugin); |
|
cce2d7868c78
[gaim-migrate @ 5894]
Christian Hammond <chipx86@chipx86.com>
parents:
5450
diff
changeset
|
344 gaim_notify_close_with_handle(plugin); |
| 5205 | 345 |
| 346 plugin->loaded = FALSE; | |
| 347 | |
| 348 if (plugin->native_plugin) { | |
| 349 if (plugin->info->unload != NULL) | |
| 350 plugin->info->unload(plugin); | |
| 351 | |
| 352 if (plugin->info->type == GAIM_PLUGIN_PROTOCOL) { | |
| 353 GaimPluginProtocolInfo *prpl_info; | |
| 354 GList *l; | |
| 355 | |
| 356 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(plugin); | |
| 357 | |
|
5638
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5573
diff
changeset
|
358 for (l = prpl_info->user_splits; l != NULL; l = l->next) |
|
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5573
diff
changeset
|
359 gaim_account_user_split_destroy(l->data); |
| 5205 | 360 |
|
5638
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5573
diff
changeset
|
361 for (l = prpl_info->protocol_options; l != NULL; l = l->next) |
|
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5573
diff
changeset
|
362 gaim_account_option_destroy(l->data); |
| 5205 | 363 |
|
5646
48c63ee49961
[gaim-migrate @ 6060]
Christian Hammond <chipx86@chipx86.com>
parents:
5638
diff
changeset
|
364 if (prpl_info->user_splits != NULL) |
|
48c63ee49961
[gaim-migrate @ 6060]
Christian Hammond <chipx86@chipx86.com>
parents:
5638
diff
changeset
|
365 g_list_free(prpl_info->user_splits); |
|
48c63ee49961
[gaim-migrate @ 6060]
Christian Hammond <chipx86@chipx86.com>
parents:
5638
diff
changeset
|
366 |
|
48c63ee49961
[gaim-migrate @ 6060]
Christian Hammond <chipx86@chipx86.com>
parents:
5638
diff
changeset
|
367 if (prpl_info->protocol_options != NULL) |
|
48c63ee49961
[gaim-migrate @ 6060]
Christian Hammond <chipx86@chipx86.com>
parents:
5638
diff
changeset
|
368 g_list_free(prpl_info->protocol_options); |
| 5205 | 369 } |
|
5357
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
370 else if (plugin->info->type == GAIM_PLUGIN_LOADER) { |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
371 GaimPluginLoaderInfo *loader_info; |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
372 |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
373 loader_info = GAIM_PLUGIN_LOADER_INFO(plugin); |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
374 |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
375 if (loader_info->broadcast != NULL) |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
376 gaim_signals_unregister_broadcast_func(loader_info->broadcast); |
|
2a1c92df7024
[gaim-migrate @ 5733]
Christian Hammond <chipx86@chipx86.com>
parents:
5270
diff
changeset
|
377 } |
| 5205 | 378 } |
| 379 else { | |
| 380 GaimPlugin *loader; | |
| 381 GaimPluginLoaderInfo *loader_info; | |
| 382 | |
|
5794
5e93fc46d1af
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5646
diff
changeset
|
383 loader = find_loader_for_plugin(plugin); |
| 5205 | 384 |
| 385 if (loader == NULL) | |
| 386 return FALSE; | |
| 387 | |
| 388 loader_info = GAIM_PLUGIN_LOADER_INFO(loader); | |
| 389 | |
| 390 if (loader_info->load != NULL) | |
| 391 loader_info->unload(plugin); | |
| 392 } | |
| 393 | |
| 394 gaim_signals_disconnect_by_handle(plugin); | |
| 395 | |
| 396 /* TODO */ | |
| 397 if (unload_cb != NULL) | |
| 398 unload_cb(plugin, unload_cb_data); | |
| 399 | |
| 400 return TRUE; | |
| 5449 | 401 #else |
| 402 return TRUE; | |
| 5205 | 403 #endif /* GAIM_PLUGINS */ |
| 404 } | |
| 405 | |
| 406 gboolean | |
| 407 gaim_plugin_reload(GaimPlugin *plugin) | |
| 408 { | |
| 409 #ifdef GAIM_PLUGINS | |
| 410 g_return_val_if_fail(plugin != NULL, FALSE); | |
| 411 g_return_val_if_fail(gaim_plugin_is_loaded(plugin), FALSE); | |
| 412 | |
| 413 if (!gaim_plugin_unload(plugin)) | |
| 414 return FALSE; | |
| 415 | |
| 416 if (!gaim_plugin_load(plugin)) | |
| 417 return FALSE; | |
| 418 | |
| 419 return TRUE; | |
| 420 #else | |
| 5449 | 421 return TRUE; |
| 5205 | 422 #endif /* !GAIM_PLUGINS */ |
| 423 } | |
| 424 | |
| 425 void | |
| 426 gaim_plugin_destroy(GaimPlugin *plugin) | |
| 427 { | |
| 5449 | 428 #ifdef GAIM_PLUGINS |
| 5205 | 429 g_return_if_fail(plugin != NULL); |
| 430 | |
| 431 if (gaim_plugin_is_loaded(plugin)) | |
| 432 gaim_plugin_unload(plugin); | |
| 433 | |
| 434 plugins = g_list_remove(plugins, plugin); | |
| 435 | |
|
5243
f6e0c689a88b
[gaim-migrate @ 5614]
Christian Hammond <chipx86@chipx86.com>
parents:
5242
diff
changeset
|
436 if (plugin->info != NULL && plugin->info->dependencies != NULL) |
|
f6e0c689a88b
[gaim-migrate @ 5614]
Christian Hammond <chipx86@chipx86.com>
parents:
5242
diff
changeset
|
437 g_list_free(plugin->info->dependencies); |
| 5205 | 438 |
| 439 if (plugin->native_plugin) { | |
| 440 | |
| 441 if (plugin->info != NULL && plugin->info->type == GAIM_PLUGIN_LOADER) { | |
| 442 GList *exts, *l, *next_l; | |
| 443 GaimPlugin *p2; | |
| 444 | |
| 445 for (exts = GAIM_PLUGIN_LOADER_INFO(plugin)->exts; | |
| 446 exts != NULL; | |
| 447 exts = exts->next) { | |
| 448 | |
| 449 for (l = gaim_plugins_get_all(); l != NULL; l = next_l) { | |
| 450 next_l = l->next; | |
| 451 | |
| 452 p2 = l->data; | |
| 453 | |
| 454 if (p2->path != NULL && is_so_file(p2->path, exts->data)) | |
| 455 gaim_plugin_destroy(p2); | |
| 456 } | |
| 457 } | |
| 458 | |
| 459 g_list_free(GAIM_PLUGIN_LOADER_INFO(plugin)->exts); | |
| 460 | |
| 461 plugin_loaders = g_list_remove(plugin_loaders, plugin); | |
| 462 } | |
| 463 | |
| 464 if (plugin->info != NULL && plugin->info->destroy != NULL) | |
| 465 plugin->info->destroy(plugin); | |
| 466 | |
| 467 if (plugin->handle != NULL) | |
| 468 g_module_close(plugin->handle); | |
| 469 } | |
| 470 else { | |
| 471 GaimPlugin *loader; | |
| 472 GaimPluginLoaderInfo *loader_info; | |
| 473 | |
|
5794
5e93fc46d1af
[gaim-migrate @ 6219]
Christian Hammond <chipx86@chipx86.com>
parents:
5646
diff
changeset
|
474 loader = find_loader_for_plugin(plugin); |
| 5205 | 475 |
| 476 if (loader == NULL) | |
| 477 return; | |
| 478 | |
| 479 loader_info = GAIM_PLUGIN_LOADER_INFO(loader); | |
| 480 | |
| 481 if (loader_info->destroy != NULL) | |
| 482 loader_info->destroy(plugin); | |
| 483 } | |
| 484 | |
| 485 if (plugin->path != NULL) g_free(plugin->path); | |
| 486 if (plugin->error != NULL) g_free(plugin->error); | |
| 487 | |
| 488 g_free(plugin); | |
| 5449 | 489 #endif /* !GAIM_PLUGINS */ |
| 5205 | 490 } |
| 491 | |
| 492 gboolean | |
| 493 gaim_plugin_is_loaded(const GaimPlugin *plugin) | |
| 494 { | |
| 495 g_return_val_if_fail(plugin != NULL, FALSE); | |
| 496 | |
| 497 return plugin->loaded; | |
| 498 } | |
| 499 | |
| 500 void | |
| 501 gaim_plugins_set_search_paths(size_t count, char **paths) | |
| 502 { | |
| 503 size_t s; | |
| 504 | |
| 505 g_return_if_fail(count > 0); | |
| 506 g_return_if_fail(paths != NULL); | |
| 507 | |
| 508 if (search_paths != NULL) { | |
| 509 for (s = 0; s < search_path_count; s++) | |
| 510 g_free(search_paths[s]); | |
| 511 | |
| 512 g_free(search_paths); | |
| 513 } | |
| 514 | |
| 515 search_paths = g_new0(char *, count); | |
| 516 | |
| 517 for (s = 0; s < count; s++) { | |
| 518 if (paths[s] == NULL) | |
| 519 search_paths[s] = NULL; | |
| 520 else | |
| 521 search_paths[s] = g_strdup(paths[s]); | |
| 522 } | |
| 523 | |
| 524 search_path_count = count; | |
| 525 } | |
| 526 | |
| 527 void | |
| 528 gaim_plugins_unload_all(void) | |
| 529 { | |
| 530 #ifdef GAIM_PLUGINS | |
| 531 | |
| 532 while (loaded_plugins != NULL) | |
| 533 gaim_plugin_unload(loaded_plugins->data); | |
| 534 | |
| 535 #endif /* GAIM_PLUGINS */ | |
| 536 } | |
| 537 | |
| 538 void | |
|
5242
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
539 gaim_plugins_destroy_all(void) |
|
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
540 { |
|
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
541 #ifdef GAIM_PLUGINS |
|
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
542 |
|
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
543 while (plugins != NULL) |
|
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
544 gaim_plugin_destroy(plugins->data); |
|
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
545 |
|
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
546 #endif /* GAIM_PLUGINS */ |
|
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
547 } |
| 5838 | 548 |
| 549 void | |
| 5840 | 550 gaim_plugins_load_saved(void) |
| 5838 | 551 { |
| 552 #ifdef GAIM_PLUGINS | |
| 553 GList *f, *files = gaim_prefs_get_string_list("/plugins/loaded"); | |
| 554 | |
| 555 for(f = files; f; f = f->next) { | |
| 556 gaim_plugin_load(gaim_plugin_probe(f->data)); | |
| 557 g_free(f->data); | |
| 558 } | |
| 559 | |
| 560 g_list_free(files); | |
| 561 #endif /* GAIM_PLUGINS */ | |
| 562 } | |
| 563 | |
| 564 | |
|
5242
fd81a00480ac
[gaim-migrate @ 5613]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
565 void |
| 5205 | 566 gaim_plugins_probe(const char *ext) |
| 567 { | |
| 568 #ifdef GAIM_PLUGINS | |
| 569 GDir *dir; | |
| 570 const gchar *file; | |
| 571 gchar *path; | |
| 572 GaimPlugin *plugin; | |
| 573 size_t i; | |
| 574 | |
| 575 if (!g_module_supported()) | |
| 576 return; | |
| 577 | |
| 578 for (i = 0; i < search_path_count; i++) { | |
| 579 if (search_paths[i] == NULL) | |
| 580 continue; | |
| 581 | |
| 582 dir = g_dir_open(search_paths[i], 0, NULL); | |
| 583 | |
| 584 if (dir != NULL) { | |
| 585 while ((file = g_dir_read_name(dir)) != NULL) { | |
| 586 path = g_build_filename(search_paths[i], file, NULL); | |
| 587 | |
| 588 if (ext == NULL || is_so_file(file, ext)) | |
| 589 plugin = gaim_plugin_probe(path); | |
| 590 | |
| 591 g_free(path); | |
| 592 } | |
| 593 | |
| 594 g_dir_close(dir); | |
| 595 } | |
| 596 } | |
| 597 | |
| 598 if (probe_cb != NULL) | |
| 599 probe_cb(probe_cb_data); | |
| 600 | |
| 601 #endif /* GAIM_PLUGINS */ | |
| 602 } | |
| 603 | |
| 604 gboolean | |
| 605 gaim_plugin_register(GaimPlugin *plugin) | |
| 606 { | |
| 607 g_return_val_if_fail(plugin != NULL, FALSE); | |
| 608 | |
| 609 if (g_list_find(plugins, plugin)) | |
| 610 return TRUE; | |
| 611 | |
| 612 /* Special exception for loader plugins. We want them loaded NOW! */ | |
| 613 if (plugin->info->type == GAIM_PLUGIN_LOADER) { | |
| 614 GList *exts; | |
| 615 | |
| 616 /* We'll just load this right now. */ | |
| 617 if (!gaim_plugin_load(plugin)) { | |
| 618 | |
| 619 gaim_plugin_destroy(plugin); | |
| 620 | |
| 621 return FALSE; | |
| 622 } | |
| 623 | |
| 624 plugin_loaders = g_list_append(plugin_loaders, plugin); | |
| 625 | |
| 626 for (exts = GAIM_PLUGIN_LOADER_INFO(plugin)->exts; | |
| 627 exts != NULL; | |
| 628 exts = exts->next) { | |
| 629 | |
| 630 gaim_plugins_probe(exts->data); | |
| 631 } | |
| 632 } | |
| 633 else if (plugin->info->type == GAIM_PLUGIN_PROTOCOL) { | |
| 634 | |
| 635 /* We'll just load this right now. */ | |
| 636 if (!gaim_plugin_load(plugin)) { | |
| 637 | |
| 638 gaim_plugin_destroy(plugin); | |
| 639 | |
| 640 return FALSE; | |
| 641 } | |
| 642 | |
| 643 if (GAIM_PLUGIN_PROTOCOL_INFO(plugin)->protocol == GAIM_PROTO_ICQ || | |
| 644 gaim_find_prpl(GAIM_PLUGIN_PROTOCOL_INFO(plugin)->protocol)) { | |
| 645 | |
| 646 /* Nothing to see here--move along, move along */ | |
| 647 gaim_plugin_destroy(plugin); | |
| 648 | |
| 649 return FALSE; | |
| 650 } | |
| 651 | |
|
5573
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
652 protocol_plugins = g_list_insert_sorted(protocol_plugins, plugin, |
|
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
653 (GCompareFunc)compare_prpl); |
| 5205 | 654 } |
| 655 | |
| 656 plugins = g_list_append(plugins, plugin); | |
| 657 | |
| 658 return TRUE; | |
| 659 } | |
| 660 | |
| 661 gboolean | |
| 662 gaim_plugins_enabled(void) | |
| 663 { | |
| 664 #ifdef GAIM_PLUGINS | |
| 665 return TRUE; | |
| 666 #else | |
| 667 return FALSE; | |
| 668 #endif | |
| 669 } | |
| 670 | |
| 671 void | |
| 672 gaim_plugins_register_probe_notify_cb(void (*func)(void *), void *data) | |
| 673 { | |
| 674 /* TODO */ | |
| 675 probe_cb = func; | |
| 676 probe_cb_data = data; | |
| 677 } | |
| 678 | |
| 679 void | |
| 680 gaim_plugins_unregister_probe_notify_cb(void (*func)(void *)) | |
| 681 { | |
| 682 /* TODO */ | |
| 683 probe_cb = NULL; | |
| 684 probe_cb_data = NULL; | |
| 685 } | |
| 686 | |
| 687 void | |
| 688 gaim_plugins_register_load_notify_cb(void (*func)(GaimPlugin *, void *), | |
| 689 void *data) | |
| 690 { | |
| 691 /* TODO */ | |
| 692 load_cb = func; | |
| 693 load_cb_data = data; | |
| 694 } | |
| 695 | |
| 696 void | |
| 697 gaim_plugins_unregister_load_notify_cb(void (*func)(GaimPlugin *, void *)) | |
| 698 { | |
| 699 /* TODO */ | |
| 700 load_cb = NULL; | |
| 701 load_cb_data = NULL; | |
| 702 } | |
| 703 | |
| 704 void | |
| 705 gaim_plugins_register_unload_notify_cb(void (*func)(GaimPlugin *, void *), | |
| 706 void *data) | |
| 707 { | |
| 708 /* TODO */ | |
| 709 unload_cb = func; | |
| 710 unload_cb_data = data; | |
| 711 } | |
| 712 | |
| 713 void | |
| 714 gaim_plugins_unregister_unload_notify_cb(void (*func)(GaimPlugin *, void *)) | |
| 715 { | |
| 716 /* TODO */ | |
| 717 unload_cb = NULL; | |
| 718 unload_cb_data = NULL; | |
| 719 } | |
| 720 | |
| 721 GaimPlugin * | |
| 722 gaim_plugins_find_with_name(const char *name) | |
| 723 { | |
| 724 GaimPlugin *plugin; | |
| 725 GList *l; | |
| 726 | |
| 727 for (l = plugins; l != NULL; l = l->next) { | |
| 728 plugin = l->data; | |
| 729 | |
| 730 if (!strcmp(plugin->info->name, name)) | |
| 731 return plugin; | |
| 732 } | |
| 733 | |
| 734 return NULL; | |
| 735 } | |
| 736 | |
| 737 GaimPlugin * | |
| 738 gaim_plugins_find_with_filename(const char *filename) | |
| 739 { | |
| 740 GaimPlugin *plugin; | |
| 741 GList *l; | |
| 742 | |
| 743 for (l = plugins; l != NULL; l = l->next) { | |
| 744 plugin = l->data; | |
| 745 | |
| 746 if (plugin->path != NULL && !strcmp(plugin->path, filename)) | |
| 747 return plugin; | |
| 748 } | |
| 749 | |
| 750 return NULL; | |
| 751 } | |
| 752 | |
| 753 GaimPlugin * | |
| 754 gaim_plugins_find_with_id(const char *id) | |
| 755 { | |
| 756 GaimPlugin *plugin; | |
| 757 GList *l; | |
| 758 | |
| 759 g_return_val_if_fail(id != NULL, NULL); | |
| 760 | |
| 761 for (l = plugins; l != NULL; l = l->next) { | |
| 762 plugin = l->data; | |
| 763 | |
| 764 if (!strcmp(plugin->info->id, id)) | |
| 765 return plugin; | |
| 766 } | |
| 767 | |
| 768 return NULL; | |
| 769 } | |
| 770 | |
| 771 GList * | |
| 772 gaim_plugins_get_loaded(void) | |
| 773 { | |
| 774 return loaded_plugins; | |
| 775 } | |
| 776 | |
| 777 GList * | |
|
5573
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
778 gaim_plugins_get_protocols(void) |
|
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
779 { |
|
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
780 return protocol_plugins; |
|
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
781 } |
|
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
782 |
|
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5498
diff
changeset
|
783 GList * |
| 5205 | 784 gaim_plugins_get_all(void) |
| 785 { | |
| 786 return plugins; | |
| 787 } | |
| 788 |
