changeset 25733:51cbb9be484e

Set state error on IBBSession if the receiver gives an error. Handle errors better in si.c
author Marcus Lundblad <ml@update.uu.se>
date Sun, 12 Oct 2008 17:41:26 +0000
parents d6351b105e42
children 0b13cf2b286e
files libpurple/protocols/jabber/ibb.c libpurple/protocols/jabber/si.c
diffstat 2 files changed, 83 insertions(+), 52 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/jabber/ibb.c	Wed Oct 01 18:19:00 2008 +0000
+++ b/libpurple/protocols/jabber/ibb.c	Sun Oct 12 17:41:26 2008 +0000
@@ -102,14 +102,14 @@
 void
 jabber_ibb_session_destroy(JabberIBBSession *sess)
 {
-	purple_debug_info("jabber", "IBB: destroying session %lx %s\n", sess, 
+	purple_debug_info("jabber", "IBB: destroying session %p %s\n", sess, 
 		sess->sid);
 	
 	if (jabber_ibb_session_get_state(sess) == JABBER_IBB_SESSION_OPENED) {
 		jabber_ibb_session_close(sess);
 	}
 	
-	purple_debug_info("jabber", "IBB: last_iq_id: %lx\n", sess->last_iq_id);
+	purple_debug_info("jabber", "IBB: last_iq_id: %s\n", sess->last_iq_id);
 	if (sess->last_iq_id) {
 		purple_debug_info("jabber", "IBB: removing callback for <iq/> %s\n",
 			sess->last_iq_id);
@@ -224,8 +224,12 @@
 {
 	JabberIBBSession *sess = (JabberIBBSession *) data;
 
-	sess->state = JABBER_IBB_SESSION_OPENED;
-	
+	if (strcmp(xmlnode_get_attrib(packet, "type"), "error") == 0) {
+		sess->state = JABBER_IBB_SESSION_ERROR;
+	} else {
+		sess->state = JABBER_IBB_SESSION_OPENED;
+	}
+		
 	if (sess->opened_cb) {
 		sess->opened_cb(sess);
 	}
@@ -328,7 +332,7 @@
 {
 	JabberIBBSessionState state = jabber_ibb_session_get_state(sess);
 	
-	purple_debug_info("jabber", "sending data block of %d bytes on IBB stream\n",
+	purple_debug_info("jabber", "sending data block of %ld bytes on IBB stream\n",
 		size);
 	
 	if (state != JABBER_IBB_SESSION_OPENED) {
@@ -354,11 +358,11 @@
 		xmlnode_insert_child(set->node, data_element);
 	
 		purple_debug_info("jabber", 
-			"IBB: setting send <iq/> callback for session %lx %s\n", sess,
+			"IBB: setting send <iq/> callback for session %p %s\n", sess,
 			sess->sid);
 		jabber_iq_set_callback(set, jabber_ibb_session_send_acknowledge_cb, sess);
 		sess->last_iq_id = g_strdup(xmlnode_get_attrib(set->node, "id"));
-		purple_debug_info("jabber", "IBB: set sess->last_iq_id: %lx %lx\n",
+		purple_debug_info("jabber", "IBB: set sess->last_iq_id: %s %s\n",
 			sess->last_iq_id, xmlnode_get_attrib(set->node, "id"));
 		jabber_iq_send(set);
 		
@@ -367,6 +371,26 @@
 	}
 }
 
+static void
+jabber_ibb_send_error_response(JabberStream *js, xmlnode *packet)
+{
+	JabberIq *result = jabber_iq_new(js, JABBER_IQ_ERROR);
+	xmlnode *error = xmlnode_new("error");
+	xmlnode *item_not_found = xmlnode_new("item-not-found");
+	
+	xmlnode_set_namespace(item_not_found, 
+		"urn:ietf:params:xml:ns:xmpp-stanzas");
+	xmlnode_set_attrib(error, "code", "440");
+	xmlnode_set_attrib(error, "type", "cancel");
+	jabber_iq_set_id(result, xmlnode_get_attrib(packet, "id"));
+	xmlnode_set_attrib(result->node, "to", 
+		xmlnode_get_attrib(packet, "from"));
+	xmlnode_insert_child(error, item_not_found);
+	xmlnode_insert_child(result->node, error);
+	
+	jabber_iq_send(result);
+}
+
 void
 jabber_ibb_parse(JabberStream *js, xmlnode *packet)
 {
@@ -412,7 +436,7 @@
 					
 					if (rawdata) {
 						purple_debug_info("jabber", 
-							"got %d bytes of data on IBB stream\n", size);
+							"got %ld bytes of data on IBB stream\n", size);
 						if (size > jabber_ibb_session_get_block_size(sess)) {
 							purple_debug_error("jabber",
 								"IBB: received a too large packet\n");
@@ -471,23 +495,11 @@
 				return;
 			}
 		}
+		/* no open callback returned success, reject */
+		jabber_ibb_send_error_response(js, packet);
 	} else {
 		/* send error reply */
-		JabberIq *result = jabber_iq_new(js, JABBER_IQ_ERROR);
-		xmlnode *error = xmlnode_new("error");
-		xmlnode *item_not_found = xmlnode_new("item-not-found");
-		
-		xmlnode_set_namespace(item_not_found, 
-			"urn:ietf:params:xml:ns:xmpp-stanzas");
-		xmlnode_set_attrib(error, "code", "440");
-		xmlnode_set_attrib(error, "type", "cancel");
-		jabber_iq_set_id(result, xmlnode_get_attrib(packet, "id"));
-		xmlnode_set_attrib(result->node, "to", 
-			xmlnode_get_attrib(packet, "from"));
-		xmlnode_insert_child(error, item_not_found);
-		xmlnode_insert_child(result->node, error);
-		
-		jabber_iq_send(result);
+		jabber_ibb_send_error_response(js, packet);
 	}
 }
 
--- a/libpurple/protocols/jabber/si.c	Wed Oct 01 18:19:00 2008 +0000
+++ b/libpurple/protocols/jabber/si.c	Sun Oct 12 17:41:26 2008 +0000
@@ -1004,32 +1004,39 @@
 	xmlnode *open = xmlnode_get_child(packet, "open");
 	const gchar *sid = xmlnode_get_attrib(open, "sid");
 	PurpleXfer *xfer = jabber_si_xfer_find(js, sid, who);
-	JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
-	JabberIBBSession *sess = 
-		jabber_ibb_session_create_from_xmlnode(js, packet, xfer);
-	
-	if (sess) {
-		/* setup callbacks here...*/
-		jabber_ibb_session_set_data_received_callback(sess,
-			jabber_si_xfer_ibb_recv_data_cb);
-		jabber_ibb_session_set_closed_callback(sess, 
-			jabber_si_xfer_ibb_closed_cb);
-		jabber_ibb_session_set_error_callback(sess,
-			jabber_si_xfer_ibb_error_cb);
+	if (xfer) {
+		JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
+		JabberIBBSession *sess = 
+			jabber_ibb_session_create_from_xmlnode(js, packet, xfer);
 		
-		/* open the file to write to */
-		jsx->fp = g_fopen(purple_xfer_get_local_filename(xfer), "wb");
-		
-		jsx->ibb_session = sess;
-		
-		/* start the transfer */
-		purple_xfer_start(xfer, 0, NULL, 0);
-		return TRUE;
+		if (sess) {
+			/* setup callbacks here...*/
+			jabber_ibb_session_set_data_received_callback(sess,
+				jabber_si_xfer_ibb_recv_data_cb);
+			jabber_ibb_session_set_closed_callback(sess, 
+				jabber_si_xfer_ibb_closed_cb);
+			jabber_ibb_session_set_error_callback(sess,
+				jabber_si_xfer_ibb_error_cb);
+			
+			/* open the file to write to */
+			jsx->fp = g_fopen(purple_xfer_get_local_filename(xfer), "wb");
+			
+			jsx->ibb_session = sess;
+			
+			/* start the transfer */
+			purple_xfer_start(xfer, 0, NULL, 0);
+			return TRUE;
+		} else {
+			/* failed to create IBB session */
+			purple_debug_error("jabber", "failed to create IBB session\n");
+			jabber_si_xfer_cancel_recv(xfer);
+			purple_xfer_end(xfer);
+			return FALSE;
+		}
 	} else {
-		/* failed to create IBB session */
-		purple_debug_error("jabber", "failed to create IBB session\n");
-		jabber_si_xfer_cancel_recv(xfer);
-		purple_xfer_end(xfer);
+		/* we got an IBB <open/> for an unknown file transfer, pass along... */
+		purple_debug_info("jabber", 
+			"IBB open did not match any SI file transfer\n");
 		return FALSE;
 	}
 }
@@ -1085,11 +1092,23 @@
 	PurpleXfer *xfer = (PurpleXfer *) jabber_ibb_session_get_user_data(sess);
 	JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
 	
-	purple_xfer_start(xfer, 0, NULL, 0);
-	purple_xfer_set_bytes_sent(xfer, 0);
-	purple_xfer_update_progress(xfer);
-	jsx->fp = g_fopen(purple_xfer_get_local_filename(xfer), "rb");
-	jabber_si_xfer_ibb_send_data(sess);
+	if (jabber_ibb_session_get_state(sess) == JABBER_IBB_SESSION_OPENED) {
+		purple_xfer_start(xfer, 0, NULL, 0);
+		purple_xfer_set_bytes_sent(xfer, 0);
+		purple_xfer_update_progress(xfer);
+		jsx->fp = g_fopen(purple_xfer_get_local_filename(xfer), "rb");
+		jabber_si_xfer_ibb_send_data(sess);
+	} else {
+		/* error */
+		JabberStream *js = jabber_ibb_session_get_js(sess);
+		PurpleConnection *gc = js->gc;
+		PurpleAccount *account = purple_connection_get_account(gc);
+		jabber_si_xfer_free(xfer);
+		purple_xfer_error(purple_xfer_get_type(xfer), account,
+			jabber_ibb_session_get_who(sess), 
+			_("Failed to open in-band bytestream"));
+		purple_xfer_end(xfer);
+	}
 }
 
 static void