--- a/libpurple/protocols/jabber/jabber.c Fri Jan 08 23:33:51 2010 +0000 +++ b/libpurple/protocols/jabber/jabber.c Sun Feb 14 22:26:14 2010 +0000 @@ -356,11 +356,20 @@ } if (ret < 0 && errno != EAGAIN) { - gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"), - g_strerror(errno)); - purple_connection_error_reason(js->gc, - PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); - g_free(tmp); + PurpleAccount *account = purple_connection_get_account(js->gc); + /* + * The server may have closed the socket (on a stream error), so if + * we're disconnecting, don't generate (possibly another) error that + * (for some UIs) would mask the first. + */ + if (!account->disconnecting) { + gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"), + g_strerror(errno)); + purple_connection_error_reason(js->gc, + PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); + g_free(tmp); + } + success = FALSE; } else if (ret < len) { if (ret < 0) @@ -418,13 +427,12 @@ g_free(text); } - /* If we've got a security layer, we need to encode the data, - * splitting it on the maximum buffer length negotiated */ - purple_signal_emit(purple_connection_get_prpl(js->gc), "jabber-sending-text", js->gc, &data); if (data == NULL) return; + /* If we've got a security layer, we need to encode the data, + * splitting it on the maximum buffer length negotiated */ #ifdef HAVE_CYRUS_SASL if (js->sasl_maxbuf>0) { int pos = 0; @@ -640,7 +648,7 @@ if (responses == NULL) { purple_debug_warning("jabber", "Unable to find alternative XMPP connection " - "methods after failing to connect directly."); + "methods after failing to connect directly.\n"); purple_connection_error_reason(js->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect")); @@ -678,14 +686,14 @@ jabber_login_callback(gpointer data, gint source, const gchar *error) { PurpleConnection *gc = data; - JabberStream *js = gc->proto_data; + JabberStream *js = purple_connection_get_protocol_data(gc); if (source < 0) { if (js->srv_rec != NULL) { - purple_debug_error("jabber", "Unable to connect to server: %s. Trying next SRV record.\n", error); + purple_debug_error("jabber", "Unable to connect to server: %s. Trying next SRV record or connecting directly.\n", error); try_srv_connect(js); } else { - purple_debug_info("jabber","Couldn't connect directly to %s. Trying to find alternative connection methods, like BOSH.\n", js->user->domain); + purple_debug_info("jabber","Couldn't connect directly to %s. Trying to find alternative connection methods, like BOSH.\n", js->user->domain); js->srv_query_data = purple_txt_resolve("_xmppconnect", js->user->domain, txt_resolved_cb, js); } @@ -1438,30 +1446,21 @@ */ void jabber_close(PurpleConnection *gc) { - JabberStream *js = gc->proto_data; + JabberStream *js = purple_connection_get_protocol_data(gc); /* Close all of the open Jingle sessions on this stream */ jingle_terminate_sessions(js); - /* Don't perform any actions on the ssl connection - * if we were forcibly disconnected because it will crash - * on some SSL backends. - */ - if (!gc->disconnect_timeout) { - if (js->bosh) - jabber_bosh_connection_close(js->bosh); - else if ((js->gsc && js->gsc->fd > 0) || js->fd > 0) - jabber_send_raw(js, "</stream:stream>", -1); - } + if (js->bosh) + jabber_bosh_connection_close(js->bosh); + else if ((js->gsc && js->gsc->fd > 0) || js->fd > 0) + jabber_send_raw(js, "</stream:stream>", -1); if (js->srv_query_data) purple_srv_cancel(js->srv_query_data); if(js->gsc) { -#ifdef HAVE_OPENSSL - if (!gc->disconnect_timeout) -#endif - purple_ssl_close(js->gsc); + purple_ssl_close(js->gsc); } else if (js->fd > 0) { if(js->gc->inpa) purple_input_remove(js->gc->inpa); @@ -3169,8 +3168,9 @@ purple_account_get_connection(account)->proto_data; JabberBuddy *jb; JabberBuddyResource *jbr; - PurpleMediaCaps caps = PURPLE_MEDIA_CAPS_NONE; + PurpleMediaCaps total = PURPLE_MEDIA_CAPS_NONE; gchar *resource; + GList *specific = NULL, *l; if (!js) { purple_debug_info("jabber", @@ -3178,20 +3178,37 @@ return FALSE; } - if ((resource = jabber_get_resource(who)) != NULL) { + jb = jabber_buddy_find(js, who, FALSE); + + if (!jb || !jb->resources) { + /* no resources online, we're trying to get caps for someone + * whose presence we're not subscribed to, or + * someone who is offline. */ + return total; + + } else if ((resource = jabber_get_resource(who)) != NULL) { /* they've specified a resource, no need to ask or * default or anything, just do it */ - - jb = jabber_buddy_find(js, who, FALSE); jbr = jabber_buddy_find_resource(jb, resource); g_free(resource); if (!jbr) { purple_debug_error("jabber", "jabber_get_media_caps:" " Can't find resource %s\n", who); - return caps; + return total; } + l = specific = g_list_prepend(specific, jbr); + + } else { + /* we've got multiple resources, combine their caps */ + l = jb->resources; + } + + for (; l; l = l->next) { + PurpleMediaCaps caps = PURPLE_MEDIA_CAPS_NONE; + jbr = l->data; + if (jabber_resource_has_capability(jbr, JINGLE_APP_RTP_SUPPORT_AUDIO)) caps |= PURPLE_MEDIA_CAPS_AUDIO_SINGLE_DIRECTION | @@ -3220,38 +3237,15 @@ if (jabber_resource_has_capability(jbr, NS_GOOGLE_VIDEO)) caps |= PURPLE_MEDIA_CAPS_AUDIO_VIDEO; } - return caps; + + total |= caps; } - jb = jabber_buddy_find(js, who, FALSE); - - if(!jb || !jb->resources) { - /* no resources online, we're trying to get caps for someone - * whose presence we're not subscribed to, or - * someone who is offline. */ - return caps; - } else if(!jb->resources->next) { - /* only 1 resource online (probably our most common case) */ - gchar *name; - jbr = jb->resources->data; - name = g_strdup_printf("%s/%s", who, jbr->name); - caps = jabber_get_media_caps(account, name); - g_free(name); - } else { - /* we've got multiple resources, combine their caps */ - GList *l; - - for(l = jb->resources; l; l = l->next) - { - gchar *name; - jbr = l->data; - name = g_strdup_printf("%s/%s", who, jbr->name); - caps |= jabber_get_media_caps(account, name); - g_free(name); - } + if (specific) { + g_list_free(specific); } - return caps; + return total; #else return PURPLE_MEDIA_CAPS_NONE; #endif