libpurple/protocols/jabber/jabber.c

branch
cpw.malu.xmpp.google_relay
changeset 29475
dac1cbec5a2f
parent 29473
5fa668c7ddb6
parent 29345
5932dfc04845
child 30764
813ff2eb4f42
--- 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

mercurial