xmlnode * _h_elim_init ( const char *name , const char *id , SEXP_VALUE *args , gpointer data ) { ASSERT_ALISTP( args, id, name ); char *dir = ALIST_VAL_STRING( args, "dot-dir" ); char *ui = ALIST_VAL_STRING( args, "ui-id" ); gboolean dbg = ALIST_VAL_BOOL ( args, "debug" ); if( !ui ) { ui = "elim"; } // libpurple initialisation: purple_util_set_user_dir ( dir ); purple_util_init (); purple_core_set_ui_ops ( &elim_core_ui_ops ); purple_eventloop_set_ui_ops ( &elim_eventloop_ui_ops ); purple_blist_set_ui_ops ( &elim_blist_ui_ops ); purple_accounts_set_ui_ops ( &elim_account_ui_ops ); purple_request_set_ui_ops ( &elim_request_ui_ops ); purple_idle_set_ui_ops ( &elim_idle_ui_ops ); purple_connections_set_ui_ops ( &elim_connections_ui_ops ); purple_conversations_set_ui_ops( &elim_conversation_ui_ops ); purple_notify_set_ui_ops ( &elim_notify_ui_ops ); // load any data for init: if( purple_get_core() == NULL ) { // purple debug goes to stdout if we don't divert it here: g_set_print_handler( (GPrintFunc)_h_elim_warning ); // look for plugins in user specified directory tree: char *ppath = g_build_filename( purple_user_dir(), "plugins", NULL ); purple_plugins_add_search_path ( ppath ); purple_debug_set_enabled( dbg ); purple_core_init ( ui ); purple_set_blist ( purple_blist_new() ); purple_prefs_load(); purple_blist_load(); // glib signal initialisation: elim_ft_signals_init(); // tidy up: g_free( ppath ); } else { const char *cur_ui = purple_core_get_ui(); if( strcmp( cur_ui, name ) ) { sexp_val_free( args ); return response_error( EINVAL, id, name, "purple has already been initialised" ); } } sexp_val_free( args ); xmlnode *rval = xnode_new( "alist" ); AL_STR( rval, "ui-id", purple_core_get_ui() ); return response_value( 0, id, name, rval ); }
static void auth_no_pass_cb(PurpleConnection *gc, PurpleRequestFields *fields) { /* TODO: the password prompt dialog doesn't get disposed if the account disconnects */ PURPLE_ASSERT_CONNECTION_IS_VALID(gc); /* Disable the account as the user has cancelled connecting */ purple_account_set_enabled(purple_connection_get_account(gc), purple_core_get_ui(), FALSE); }
static void hangouts_save_refresh_token_password(PurpleAccount *account, const gchar *password) { purple_account_set_password(account, password, NULL, NULL); if (g_strcmp0(purple_core_get_ui(), "BitlBee") == 0) { save_bitlbee_password(account, password); } }
static void auth_no_pass_cb(PurpleConnection *gc, PurpleRequestFields *fields) { PurpleAccount *account; JabberStream *js; /* The password prompt dialog doesn't get disposed if the account disconnects */ if (!PURPLE_CONNECTION_IS_VALID(gc)) return; account = purple_connection_get_account(gc); /* Disable the account as the user has cancelled connecting */ purple_account_set_enabled(account, purple_core_get_ui(), FALSE); }
static gboolean load_ui_plugin(gpointer data) { char *ui_plugin_id; PurplePlugin *ui_plugin; ui_plugin_id = g_strconcat(purple_core_get_ui(), "-", PLUGIN_STATIC_NAME, NULL); ui_plugin = purple_plugins_find_with_id(ui_plugin_id); if (ui_plugin != NULL) { if (!purple_plugin_load(ui_plugin)) { purple_notify_error(ui_plugin, NULL, _("Failed to load the Buddy Timezone UI."), ui_plugin->error ? ui_plugin->error : ""); } } g_free(ui_plugin_id); return FALSE; }
void AccountCollector::collectNow(PurpleAccount *account, bool remove) { if (account->ui_data == NULL) { Log("AccountCollector","freeing account " << purple_account_get_username(account)); if (remove) g_hash_table_remove(m_accounts, purple_account_get_username(account)); purple_account_set_enabled(account, purple_core_get_ui(), FALSE); purple_notify_close_with_handle(account); purple_request_close_with_handle(account); purple_accounts_remove(account); GSList *buddies = purple_find_buddies(account, NULL); while(buddies) { PurpleBuddy *b = (PurpleBuddy *) buddies->data; purple_blist_remove_buddy(b); buddies = g_slist_delete_link(buddies, buddies); } /* Remove any open conversation for this account */ for (GList *it = purple_get_conversations(); it; ) { PurpleConversation *conv = (PurpleConversation *) it->data; it = it->next; if (purple_conversation_get_account(conv) == account) purple_conversation_destroy(conv); } /* Remove this account's pounces */ // purple_pounce_destroy_all_by_account(account); /* This will cause the deletion of an old buddy icon. */ purple_buddy_icons_set_account_icon(account, NULL, 0); purple_account_destroy(account); // VALGRIND_DO_LEAK_CHECK; } }
static void pb_oauth_set_access_token_cb(gpointer data, const gchar *access_token) { PurpleAccount *account = data; gchar *real_access_token; const gchar *access_token_start; const gchar *access_token_end; gchar *strtmp; if (!access_token || !(*access_token)) { return; } if((access_token_start = strstr(access_token, "access_token="))) { access_token_start += 13; access_token_end = strchr(access_token_start, '&'); if (access_token_end) real_access_token = g_strndup(access_token_start, access_token_end - access_token_start); else real_access_token = g_strdup(access_token_start); strtmp = g_strdup(purple_url_decode(real_access_token)); g_free(real_access_token); real_access_token = strtmp; } else { real_access_token = g_strdup(access_token); } if (real_access_token && *real_access_token) { purple_account_set_remember_password(account, TRUE); purple_account_set_password(account, real_access_token); purple_account_set_enabled(account, purple_core_get_ui(), TRUE); purple_account_connect(account); } g_free(real_access_token); }
PurplePlugin * purple_plugin_probe(const char *filename) { #ifdef PURPLE_PLUGINS PurplePlugin *plugin = NULL; PurplePlugin *loader; gpointer unpunned; gchar *basename = NULL; gboolean (*purple_init_plugin)(PurplePlugin *); purple_debug_misc("plugins", "probing %s\n", filename); g_return_val_if_fail(filename != NULL, NULL); if (!g_file_test(filename, G_FILE_TEST_EXISTS)) return NULL; /* If this plugin has already been probed then exit */ basename = purple_plugin_get_basename(filename); plugin = purple_plugins_find_with_basename(basename); g_free(basename); if (plugin != NULL) { if (purple_strequal(filename, plugin->path)) return plugin; else if (!purple_plugin_is_unloadable(plugin)) { purple_debug_warning("plugins", "Not loading %s. " "Another plugin with the same name (%s) has already been loaded.\n", filename, plugin->path); return plugin; } else { /* The old plugin was a different file and it was unloadable. * There's no guarantee that this new file with the same name * will be loadable, but unless it fails in one of the silent * ways and the first one didn't, it's not any worse. The user * will still see a greyed-out plugin, which is what we want. */ purple_plugin_destroy(plugin); } } plugin = purple_plugin_new(has_file_extension(filename, G_MODULE_SUFFIX), filename); if (plugin->native_plugin) { const char *error; #ifdef _WIN32 /* Suppress error popups for failing to load plugins */ UINT old_error_mode = SetErrorMode(SEM_FAILCRITICALERRORS); #endif /* * We pass G_MODULE_BIND_LOCAL here to prevent symbols from * plugins being added to the global name space. * * G_MODULE_BIND_LOCAL was added in glib 2.3.3. */ plugin->handle = g_module_open(filename, G_MODULE_BIND_LOCAL); if (plugin->handle == NULL) { const char *error = g_module_error(); if (error != NULL && purple_str_has_prefix(error, filename)) { error = error + strlen(filename); /* These are just so we don't crash. If we * got this far, they should always be true. */ if (*error == ':') error++; if (*error == ' ') error++; } if (error == NULL || !*error) { plugin->error = g_strdup(_("Unknown error")); purple_debug_error("plugins", "%s is not loadable: Unknown error\n", plugin->path); } else { plugin->error = g_strdup(error); purple_debug_error("plugins", "%s is not loadable: %s\n", plugin->path, plugin->error); } plugin->handle = g_module_open(filename, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL); if (plugin->handle == NULL) { #ifdef _WIN32 /* Restore the original error mode */ SetErrorMode(old_error_mode); #endif purple_plugin_destroy(plugin); return NULL; } else { /* We were able to load the plugin with lazy symbol binding. * This means we're missing some symbol. Mark it as * unloadable and keep going so we get the info to display * to the user so they know to rebuild this plugin. */ plugin->unloadable = TRUE; } } if (!g_module_symbol(plugin->handle, "purple_init_plugin", &unpunned)) { purple_debug_error("plugins", "%s is not usable because the " "'purple_init_plugin' symbol could not be " "found. Does the plugin call the " "PURPLE_INIT_PLUGIN() macro?\n", plugin->path); g_module_close(plugin->handle); error = g_module_error(); if (error != NULL) purple_debug_error("plugins", "Error closing module %s: %s\n", plugin->path, error); plugin->handle = NULL; #ifdef _WIN32 /* Restore the original error mode */ SetErrorMode(old_error_mode); #endif purple_plugin_destroy(plugin); return NULL; } purple_init_plugin = unpunned; #ifdef _WIN32 /* Restore the original error mode */ SetErrorMode(old_error_mode); #endif } else { loader = find_loader_for_plugin(plugin); if (loader == NULL) { purple_plugin_destroy(plugin); return NULL; } purple_init_plugin = PURPLE_PLUGIN_LOADER_INFO(loader)->probe; } if (!purple_init_plugin(plugin) || plugin->info == NULL) { purple_plugin_destroy(plugin); return NULL; } else if (plugin->info->ui_requirement && !purple_strequal(plugin->info->ui_requirement, purple_core_get_ui())) { plugin->error = g_strdup_printf(_("You are using %s, but this plugin requires %s."), purple_core_get_ui(), plugin->info->ui_requirement); purple_debug_error("plugins", "%s is not loadable: The UI requirement is not met. (%s)\n", plugin->path, plugin->error); plugin->unloadable = TRUE; return plugin; } /* * Check to make sure a plugin has defined an id. * Not having this check caused purple_plugin_unload to * enter an infinite loop in certain situations by passing * purple_find_plugin_by_id a NULL value. -- ecoffey */ if (plugin->info->id == NULL || *plugin->info->id == '\0') { plugin->error = g_strdup(_("This plugin has not defined an ID.")); purple_debug_error("plugins", "%s is not loadable: info->id is not defined.\n", plugin->path); plugin->unloadable = TRUE; return plugin; } /* Really old plugins. */ if (plugin->info->magic != PURPLE_PLUGIN_MAGIC) { if (plugin->info->magic >= 2 && plugin->info->magic <= 4) { struct _PurplePluginInfo2 { unsigned int api_version; PurplePluginType type; char *ui_requirement; unsigned long flags; GList *dependencies; PurplePluginPriority priority; char *id; char *name; char *version; char *summary; char *description; char *author; char *homepage; gboolean (*load)(PurplePlugin *plugin); gboolean (*unload)(PurplePlugin *plugin); void (*destroy)(PurplePlugin *plugin); void *ui_info; void *extra_info; PurplePluginUiInfo *prefs_info; GList *(*actions)(PurplePlugin *plugin, gpointer context); } *info2 = (struct _PurplePluginInfo2 *)plugin->info; /* This leaks... but only for ancient plugins, so deal with it. */ plugin->info = g_new0(PurplePluginInfo, 1); /* We don't really need all these to display the plugin info, but * I'm copying them all for good measure. */ plugin->info->magic = info2->api_version; plugin->info->type = info2->type; plugin->info->ui_requirement = info2->ui_requirement; plugin->info->flags = info2->flags; plugin->info->dependencies = info2->dependencies; plugin->info->id = info2->id; plugin->info->name = info2->name; plugin->info->version = info2->version; plugin->info->summary = info2->summary; plugin->info->description = info2->description; plugin->info->author = info2->author; plugin->info->homepage = info2->homepage; plugin->info->load = info2->load; plugin->info->unload = info2->unload; plugin->info->destroy = info2->destroy; plugin->info->ui_info = info2->ui_info; plugin->info->extra_info = info2->extra_info; if (info2->api_version >= 3) plugin->info->prefs_info = info2->prefs_info; if (info2->api_version >= 4) plugin->info->actions = info2->actions; plugin->error = g_strdup_printf(_("Plugin magic mismatch %d (need %d)"), plugin->info->magic, PURPLE_PLUGIN_MAGIC); purple_debug_error("plugins", "%s is not loadable: Plugin magic mismatch %d (need %d)\n", plugin->path, plugin->info->magic, PURPLE_PLUGIN_MAGIC); plugin->unloadable = TRUE; return plugin; } purple_debug_error("plugins", "%s is not loadable: Plugin magic mismatch %d (need %d)\n", plugin->path, plugin->info->magic, PURPLE_PLUGIN_MAGIC); purple_plugin_destroy(plugin); return NULL; } if (plugin->info->major_version != PURPLE_MAJOR_VERSION || plugin->info->minor_version > PURPLE_MINOR_VERSION) { plugin->error = g_strdup_printf(_("ABI version mismatch %d.%d.x (need %d.%d.x)"), plugin->info->major_version, plugin->info->minor_version, PURPLE_MAJOR_VERSION, PURPLE_MINOR_VERSION); purple_debug_error("plugins", "%s is not loadable: ABI version mismatch %d.%d.x (need %d.%d.x)\n", plugin->path, plugin->info->major_version, plugin->info->minor_version, PURPLE_MAJOR_VERSION, PURPLE_MINOR_VERSION); plugin->unloadable = TRUE; return plugin; } if (plugin->info->type == PURPLE_PLUGIN_PROTOCOL) { /* If plugin is a PRPL, make sure it implements the required functions */ if ((PURPLE_PLUGIN_PROTOCOL_INFO(plugin)->list_icon == NULL) || (PURPLE_PLUGIN_PROTOCOL_INFO(plugin)->login == NULL) || (PURPLE_PLUGIN_PROTOCOL_INFO(plugin)->close == NULL)) { plugin->error = g_strdup(_("Plugin does not implement all required functions (list_icon, login and close)")); purple_debug_error("plugins", "%s is not loadable: %s\n", plugin->path, plugin->error); plugin->unloadable = TRUE; return plugin; } /* For debugging, let's warn about prpl prefs. */ if (plugin->info->prefs_info != NULL) { purple_debug_error("plugins", "%s has a prefs_info, but is a prpl. This is no longer supported.\n", plugin->path); } } return plugin; #else return NULL; #endif /* !PURPLE_PLUGINS */ }
void okc_post_or_get(OkCupidAccount *oca, OkCupidMethod method, const gchar *host, const gchar *url, const gchar *postdata, OkCupidProxyCallbackFunc callback_func, gpointer user_data, gboolean keepalive) { GString *request; gchar *cookies; OkCupidConnection *okconn; gchar *real_url; gboolean is_proxy = FALSE; const gchar* const *languages; gchar *language_names; PurpleProxyInfo *proxy_info = NULL; gchar *proxy_auth; gchar *proxy_auth_base64; /* TODO: Fix keepalive and use it as much as possible */ keepalive = FALSE; if (purple_account_get_bool(oca->account, "force_https", TRUE) && !(method & OKC_METHOD_SSL) && (!host || g_str_equal(host, "www.okcupid.com") || g_str_equal(host, "api.okcupid.com"))) { method |= OKC_METHOD_SSL; } if (method & OKC_METHOD_SSL) host = "www.okcupid.com"; if (host == NULL && oca && oca->account) host = purple_account_get_string(oca->account, "host", "api.okcupid.com"); if (host == NULL) host = "api.okcupid.com"; if (oca && oca->account && !(method & OKC_METHOD_SSL)) { proxy_info = purple_proxy_get_setup(oca->account); if (purple_proxy_info_get_type(proxy_info) == PURPLE_PROXY_USE_GLOBAL) proxy_info = purple_global_proxy_get_info(); if (purple_proxy_info_get_type(proxy_info) == PURPLE_PROXY_HTTP) { is_proxy = TRUE; } } if (is_proxy == TRUE) { real_url = g_strdup_printf("http://%s%s", host, url); } else { real_url = g_strdup(url); } cookies = okc_cookies_to_string(oca); if (method & OKC_METHOD_POST && !postdata) postdata = ""; /* Build the request */ request = g_string_new(NULL); g_string_append_printf(request, "%s %s HTTP/1.0\r\n", (method & OKC_METHOD_POST) ? "POST" : "GET", real_url); if (is_proxy == FALSE) g_string_append_printf(request, "Host: %s\r\n", host); g_string_append_printf(request, "Connection: %s\r\n", (keepalive ? "Keep-Alive" : "close")); g_string_append_printf(request, "User-Agent: %s (libpurple %s)\r\n", purple_core_get_ui(), purple_core_get_version()); if (method & OKC_METHOD_POST) { g_string_append_printf(request, "Content-Type: application/x-www-form-urlencoded\r\n"); g_string_append_printf(request, "Content-length: %zu\r\n", strlen(postdata)); } g_string_append_printf(request, "Accept: */*\r\n"); g_string_append_printf(request, "Cookie: %s\r\n", cookies); g_string_append_printf(request, "Accept-Encoding: gzip\r\n"); g_string_append_printf(request, "X-OkCupid-Api-Version: 1\r\n"); if (is_proxy == TRUE) { if (purple_proxy_info_get_username(proxy_info) && purple_proxy_info_get_password(proxy_info)) { proxy_auth = g_strdup_printf("%s:%s", purple_proxy_info_get_username(proxy_info), purple_proxy_info_get_password(proxy_info)); proxy_auth_base64 = purple_base64_encode((guchar *)proxy_auth, strlen(proxy_auth)); g_string_append_printf(request, "Proxy-Authorization: Basic %s\r\n", proxy_auth_base64); g_free(proxy_auth_base64); g_free(proxy_auth); } } /* Tell the server what language we accept, so that we get error messages in our language (rather than our IP's) */ languages = g_get_language_names(); language_names = g_strjoinv(", ", (gchar **)languages); purple_util_chrreplace(language_names, '_', '-'); g_string_append_printf(request, "Accept-Language: %s\r\n", language_names); g_free(language_names); purple_debug_misc("okcupid", "requesting url %s\n", url); g_string_append_printf(request, "\r\n"); if (method & OKC_METHOD_POST) g_string_append_printf(request, "%s", postdata); /* If it needs to go over a SSL connection, we probably shouldn't print * it in the debug log. Without this condition a user's password is * printed in the debug log */ if (method == OKC_METHOD_POST) purple_debug_misc("okcupid", "sending request data:\n%s\n", postdata); g_free(cookies); g_free(real_url); /* * Do a separate DNS lookup for the given host name and cache it * for next time. * * TODO: It would be better if we did this before we call * purple_proxy_connect(), so we could re-use the result. * Or even better: Use persistent HTTP connections for servers * that we access continually. * * TODO: This cache of the hostname<-->IP address does not respect * the TTL returned by the DNS server. We should expire things * from the cache after some amount of time. */ if (!is_proxy && !g_hostname_is_ip_address(host) && !(method & OKC_METHOD_SSL)) { /* Don't do this for proxy connections, since proxies do the DNS lookup */ gchar *host_ip; host_ip = g_hash_table_lookup(oca->hostname_ip_cache, host); if (host_ip != NULL) { purple_debug_info("okcupid", "swapping original host %s with cached value of %s\n", host, host_ip); host = host_ip; } else if (oca->account && !oca->account->disconnecting) { GSList *host_lookup_list = NULL; PurpleDnsQueryData *query; host_lookup_list = g_slist_prepend( host_lookup_list, g_strdup(host)); host_lookup_list = g_slist_prepend( host_lookup_list, oca); query = purple_dnsquery_a(host, 80, okc_host_lookup_cb, host_lookup_list); oca->dns_queries = g_slist_prepend(oca->dns_queries, query); host_lookup_list = g_slist_append(host_lookup_list, query); } } okconn = g_new0(OkCupidConnection, 1); okconn->oca = oca; okconn->method = method; okconn->hostname = g_strdup(host); okconn->request = request; okconn->callback = callback_func; okconn->user_data = user_data; okconn->fd = -1; okconn->connection_keepalive = keepalive; okconn->request_time = time(NULL); g_queue_push_head(oca->waiting_conns, okconn); okc_next_connection(oca); }