changeset 30653:fa311a0e51c0

jabber: Don't show resources that we know for sure isn't supporting the file transfer protocols we support in the resource selector when sending a file. Closes #9791
author Marcus Lundblad <ml@update.uu.se>
date Wed, 30 Jun 2010 21:34:43 +0000
parents 53469b47d3f3
children c31e1c0cf27f
files ChangeLog libpurple/protocols/jabber/jabber.c libpurple/protocols/jabber/namespaces.h libpurple/protocols/jabber/si.c
diffstat 4 files changed, 35 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Tue Jun 29 19:22:31 2010 +0000
+++ b/ChangeLog	Wed Jun 30 21:34:43 2010 +0000
@@ -21,6 +21,8 @@
 	  a fallback to legacy IQ authentication (broken in 2.7.0).
 	* Fix a crash when receiving custom emoticons that don't adhere to
 	  the specification.
+	* When initiating a file transfer, don't show resources that are certain
+	  to not support file transfers in the resource selection dialog.
 
 	Yahoo/Yahoo JAPAN:
 	* Renamed "Use account proxy for SSL connections" to "Use account proxy
--- a/libpurple/protocols/jabber/jabber.c	Tue Jun 29 19:22:31 2010 +0000
+++ b/libpurple/protocols/jabber/jabber.c	Wed Jun 30 21:34:43 2010 +0000
@@ -3440,8 +3440,7 @@
 			for (iter = jb->resources; iter ; iter = g_list_next(iter)) {
 				JabberBuddyResource *jbr = (JabberBuddyResource *) iter->data;
 
-				if (jabber_resource_has_capability(jbr,
-						"http://jabber.org/protocol/si/profile/file-transfer")
+				if (jabber_resource_has_capability(jbr, NS_SI_FILE_TRANSFER)
 			    	&& (jabber_resource_has_capability(jbr,
 			    			NS_BYTESTREAMS)
 			        	|| jabber_resource_has_capability(jbr, NS_IBB))) {
@@ -3743,7 +3742,7 @@
 	jabber_add_feature("http://jabber.org/protocol/muc", 0);
 	jabber_add_feature("http://jabber.org/protocol/muc#user", 0);
 	jabber_add_feature("http://jabber.org/protocol/si", 0);
-	jabber_add_feature("http://jabber.org/protocol/si/profile/file-transfer", 0);
+	jabber_add_feature(NS_SI_FILE_TRANSFER, 0);
 	jabber_add_feature(NS_XHTML_IM, 0);
 	jabber_add_feature(NS_PING, 0);
 
--- a/libpurple/protocols/jabber/namespaces.h	Tue Jun 29 19:22:31 2010 +0000
+++ b/libpurple/protocols/jabber/namespaces.h	Wed Jun 30 21:34:43 2010 +0000
@@ -61,6 +61,9 @@
 #define NS_AVATAR_1_1_DATA      "urn:xmpp:avatar:data"
 #define NS_AVATAR_1_1_METADATA  "urn:xmpp:avatar:metadata"
 
+/* XEP-0096 SI File Transfer */
+#define NS_SI_FILE_TRANSFER 	"http://jabber.org/protocol/si/profile/file-transfer"
+
 /* XEP-0124 Bidirectional-streams Over Synchronous HTTP (BOSH) */
 #define NS_BOSH "http://jabber.org/protocol/httpbind"
 
--- a/libpurple/protocols/jabber/si.c	Tue Jun 29 19:22:31 2010 +0000
+++ b/libpurple/protocols/jabber/si.c	Wed Jun 30 21:34:43 2010 +0000
@@ -1262,12 +1262,10 @@
 	xmlnode_set_namespace(si, "http://jabber.org/protocol/si");
 	jsx->stream_id = jabber_get_next_id(jsx->js);
 	xmlnode_set_attrib(si, "id", jsx->stream_id);
-	xmlnode_set_attrib(si, "profile",
-			"http://jabber.org/protocol/si/profile/file-transfer");
+	xmlnode_set_attrib(si, "profile", NS_SI_FILE_TRANSFER);
 
 	file = xmlnode_new_child(si, "file");
-	xmlnode_set_namespace(file,
-			"http://jabber.org/protocol/si/profile/file-transfer");
+	xmlnode_set_namespace(file, NS_SI_FILE_TRANSFER);
 	xmlnode_set_attrib(file, "name", xfer->filename);
 	g_snprintf(buf, sizeof(buf), "%" G_GSIZE_FORMAT, xfer->size);
 	xmlnode_set_attrib(file, "size", buf);
@@ -1488,7 +1486,7 @@
 
 		if (jabber_resource_has_capability(jbr, NS_IBB))
 			jsx->stream_method |= STREAM_METHOD_IBB;
-		if (jabber_resource_has_capability(jbr, "http://jabber.org/protocol/si/profile/file-transfer")) {
+		if (jabber_resource_has_capability(jbr, NS_SI_FILE_TRANSFER)) {
 			jabber_si_xfer_send_request(xfer);
 			return;
 		}
@@ -1523,7 +1521,8 @@
 		JabberBuddy *jb;
 		JabberBuddyResource *jbr = NULL;
 		char *resource;
-
+		GList *resources = NULL;
+		
 		if(NULL != (resource = jabber_get_resource(xfer->who))) {
 			/* they've specified a resource, no need to ask or
 			 * default or anything, just do it */
@@ -1535,7 +1534,22 @@
 
 		jb = jabber_buddy_find(jsx->js, xfer->who, TRUE);
 
-		if(!jb || !jb->resources) {
+		if (jb) {
+			GList *l;
+
+			for (l = jb->resources ; l ; l = g_list_next(l)) {
+				jbr = l->data;
+
+				if (!jabber_resource_know_capabilities(jbr) ||
+				    (jabber_resource_has_capability(jbr, NS_SI_FILE_TRANSFER)
+				     && (jabber_resource_has_capability(jbr, NS_BYTESTREAMS)
+				         || jabber_resource_has_capability(jbr, NS_IBB)))) {
+					resources = g_list_append(resources, jbr);
+				}
+			}
+		}
+		
+		if (!resources) {
 			/* no resources online, we're trying to send to someone
 			 * whose presence we're not subscribed to, or
 			 * someone who is offline.  Let's inform the user */
@@ -1551,13 +1565,11 @@
 
 			purple_notify_error(jsx->js->gc, _("File Send Failed"), _("File Send Failed"), msg);
 			g_free(msg);
-		} else if(!jb->resources->next) {
+		} else if (g_list_length(resources) == 1) {
 			/* only 1 resource online (probably our most common case)
 			 * so no need to ask who to send to */
-			jbr = jb->resources->data;
-
+			jbr = resources->data;
 			do_transfer_send(xfer, jbr->name);
-
 		} else {
 			/* we've got multiple resources, we need to pick one to send to */
 			GList *l;
@@ -1565,11 +1577,9 @@
 			PurpleRequestFields *fields = purple_request_fields_new();
 			PurpleRequestField *field = purple_request_field_choice_new("resource", _("Resource"), 0);
 			PurpleRequestFieldGroup *group = purple_request_field_group_new(NULL);
-
-			for(l = jb->resources; l; l = l->next)
-			{
+			
+			for(l = resources; l; l = l->next) {
 				jbr = l->data;
-
 				purple_request_field_choice_add(field, jbr->name);
 			}
 
@@ -1583,6 +1593,8 @@
 
 			g_free(msg);
 		}
+
+		g_list_free(resources);
 	} else {
 		xmlnode *si, *feature, *x, *field, *value;
 
@@ -1695,7 +1707,7 @@
 	size_t filesize = 0;
 
 	if(!(profile = xmlnode_get_attrib(si, "profile")) ||
-			strcmp(profile, "http://jabber.org/protocol/si/profile/file-transfer"))
+			strcmp(profile, NS_SI_FILE_TRANSFER))
 		return;
 
 	if(!(stream_id = xmlnode_get_attrib(si, "id")))