changeset 29074:19e400679e61

propagate from branch 'im.pidgin.pidgin' (head a878de35a8972daab016ed05e7af50043bd856ca) to branch 'im.pidgin.cpw.darkrain42.msn.ft' (head f7212b36cc13bdbaf77b2c3a8dbcde9cb395c4f8)
author Elliott Sales de Andrade <qulogic@pidgin.im>
date Fri, 20 Nov 2009 00:35:30 +0000
parents 923681c5406e (current diff) 59b0c556f787 (diff)
children 6aea98f6a5cd
files libpurple/protocols/jabber/JEPS
diffstat 7 files changed, 105 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/msn/slp.c	Tue Nov 17 21:34:28 2009 +0000
+++ b/libpurple/protocols/msn/slp.c	Fri Nov 20 00:35:30 2009 +0000
@@ -96,6 +96,8 @@
 
 	g_free(content);
 	msn_slplink_send_queued_slpmsgs(slpcall->slplink);
+
+	purple_xfer_start(xfer, -1, NULL, 0);
 }
 
 void
@@ -131,6 +133,54 @@
 	}
 }
 
+gssize
+msn_xfer_write(const guchar *data, gsize len, PurpleXfer *xfer)
+{
+	MsnSlpCall *slpcall;
+
+	g_return_val_if_fail(xfer != NULL, -1);
+	g_return_val_if_fail(data != NULL, -1);
+	g_return_val_if_fail(len > 0, -1);
+
+	g_return_val_if_fail(purple_xfer_get_type(xfer) == PURPLE_XFER_SEND, -1);
+
+	slpcall = xfer->data;
+	/* Not sure I trust it'll be there */
+	g_return_val_if_fail(slpcall != NULL, -1);
+
+	g_return_val_if_fail(slpcall->xfer_msg != NULL, -1);
+
+	slpcall->u.outgoing.len = len;
+	slpcall->u.outgoing.data = data;
+	msn_slplink_send_msgpart(slpcall->slplink, slpcall->xfer_msg);
+	return MIN(1202, len);
+}
+
+gssize
+msn_xfer_read(guchar **data, PurpleXfer *xfer)
+{
+	MsnSlpCall *slpcall;
+	gsize len;
+
+	g_return_val_if_fail(xfer != NULL, -1);
+	g_return_val_if_fail(data != NULL, -1);
+
+	g_return_val_if_fail(purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE, -1);
+
+	slpcall = xfer->data;
+	/* Not sure I trust it'll be there */
+	g_return_val_if_fail(slpcall != NULL, -1);
+
+	/* Just pass up the whole GByteArray. We'll make another. */
+	*data = slpcall->u.incoming_data->data;
+	len = slpcall->u.incoming_data->len;
+
+	g_byte_array_free(slpcall->u.incoming_data, FALSE);
+	slpcall->u.incoming_data = g_byte_array_new();
+
+	return len;
+}
+
 void
 msn_xfer_progress_cb(MsnSlpCall *slpcall, gsize total_length, gsize len, gsize offset)
 {
@@ -332,9 +382,7 @@
 
 		account = slpcall->slplink->session->account;
 
-		slpcall->cb = msn_xfer_completed_cb;
 		slpcall->end_cb = msn_xfer_end_cb;
-		slpcall->progress_cb = msn_xfer_progress_cb;
 		slpcall->branch = g_strdup(branch);
 
 		slpcall->pending = TRUE;
@@ -357,6 +405,10 @@
 			purple_xfer_set_init_fnc(xfer, msn_xfer_init);
 			purple_xfer_set_request_denied_fnc(xfer, msn_xfer_cancel);
 			purple_xfer_set_cancel_recv_fnc(xfer, msn_xfer_cancel);
+			purple_xfer_set_read_fnc(xfer, msn_xfer_read);
+			purple_xfer_set_write_fnc(xfer, msn_xfer_write);
+
+			slpcall->u.incoming_data = g_byte_array_new();
 
 			slpcall->xfer = xfer;
 			purple_xfer_ref(slpcall->xfer);
--- a/libpurple/protocols/msn/slp.h	Tue Nov 17 21:34:28 2009 +0000
+++ b/libpurple/protocols/msn/slp.h	Fri Nov 20 00:35:30 2009 +0000
@@ -41,6 +41,9 @@
 						   const guchar *body, gsize size);
 
 void msn_xfer_cancel(PurpleXfer *xfer);
+gssize msn_xfer_write(const guchar *data, gsize len, PurpleXfer *xfer);
+gssize msn_xfer_read(guchar **data, PurpleXfer *xfer);
+
 void msn_xfer_end_cb(MsnSlpCall *slpcall, MsnSession *session);
 
 void msn_queue_buddy_icon_request(MsnUser *user);
--- a/libpurple/protocols/msn/slpcall.c	Tue Nov 17 21:34:28 2009 +0000
+++ b/libpurple/protocols/msn/slpcall.c	Fri Nov 20 00:35:30 2009 +0000
@@ -105,10 +105,13 @@
 		slpcall->end_cb(slpcall, slpcall->slplink->session);
 
 	if (slpcall->xfer != NULL) {
+		if (purple_xfer_get_type(slpcall->xfer) == PURPLE_XFER_RECEIVE)
+			g_byte_array_free(slpcall->u.incoming_data, TRUE);
 		slpcall->xfer->data = NULL;
 		purple_xfer_unref(slpcall->xfer);
 	}
 
+
 	msn_slplink_remove_slpcall(slpcall->slplink, slpcall);
 
 	g_free(slpcall->id);
@@ -272,7 +275,8 @@
 				slpcall->timer = 0;
 			}
 
-			slpcall->cb(slpcall, body, body_len);
+			if (slpcall->cb)
+				slpcall->cb(slpcall, body, body_len);
 
 			slpcall->wasted = TRUE;
 		}
--- a/libpurple/protocols/msn/slpcall.h	Tue Nov 17 21:34:28 2009 +0000
+++ b/libpurple/protocols/msn/slpcall.h	Fri Nov 20 00:35:30 2009 +0000
@@ -72,6 +72,14 @@
 	char *data_info;
 
 	PurpleXfer *xfer;
+	union {
+		GByteArray *incoming_data;
+		struct {
+			gsize len;
+			const guchar *data;
+		} outgoing;
+	} u;
+	MsnSlpMessage *xfer_msg; /* A dirty hack */
 
 	MsnSlpCb cb;
 	void (*end_cb)(MsnSlpCall *slpcall, MsnSession *session);
--- a/libpurple/protocols/msn/slplink.c	Tue Nov 17 21:34:28 2009 +0000
+++ b/libpurple/protocols/msn/slplink.c	Fri Nov 20 00:35:30 2009 +0000
@@ -232,7 +232,7 @@
 	}
 }
 
-static void
+void
 msn_slplink_send_msgpart(MsnSlpLink *slplink, MsnSlpMessage *slpmsg)
 {
 	MsnMessage *msg;
@@ -247,7 +247,13 @@
 
 	if (slpmsg->offset < real_size)
 	{
-		if (slpmsg->fp)
+		if (slpmsg->slpcall && slpmsg->slpcall->xfer && purple_xfer_get_type(slpmsg->slpcall->xfer) == PURPLE_XFER_SEND &&
+				purple_xfer_get_status(slpmsg->slpcall->xfer) == PURPLE_XFER_STATUS_STARTED)
+		{
+			len = MIN(1202, slpmsg->slpcall->u.outgoing.len);
+			msn_message_set_bin_data(msg, slpmsg->slpcall->u.outgoing.data, len);
+		}
+		else if (slpmsg->fp)
 		{
 			char data[1202];
 			len = fread(data, 1, sizeof(data), slpmsg->fp);
@@ -309,7 +315,13 @@
 
 	if (slpmsg->offset < real_size)
 	{
-		msn_slplink_send_msgpart(slpmsg->slplink, slpmsg);
+		if (slpmsg->slpcall->xfer)
+		{
+			slpmsg->slpcall->xfer_msg = slpmsg;
+			purple_xfer_prpl_ready(slpmsg->slpcall->xfer);
+		}
+		else
+			msn_slplink_send_msgpart(slpmsg->slplink, slpmsg);
 	}
 	else
 	{
@@ -458,10 +470,10 @@
 
 	xfer = (PurpleXfer *)slpcall->xfer;
 	purple_xfer_start(slpcall->xfer, -1, NULL, 0);
-	slpmsg->fp = xfer->dest_fp;
 	if (g_stat(purple_xfer_get_local_filename(xfer), &st) == 0)
 		slpmsg->size = st.st_size;
-	xfer->dest_fp = NULL; /* Disable double fclose() */
+	else if (purple_xfer_get_size(xfer))
+		slpmsg->size = purple_xfer_get_size(xfer);
 
 	msn_slplink_send_slpmsg(slpcall->slplink, slpmsg);
 }
@@ -489,6 +501,7 @@
 	const char *data;
 	guint64 offset;
 	gsize len;
+	PurpleXfer *xfer = NULL;
 
 	if (purple_debug_is_verbose())
 		msn_slpmsg_show(msg);
@@ -525,12 +538,12 @@
 				if (slpmsg->flags == 0x20 ||
 				    slpmsg->flags == 0x1000020 || slpmsg->flags == 0x1000030)
 				{
-					PurpleXfer *xfer;
-
 					xfer = slpmsg->slpcall->xfer;
-
 					if (xfer != NULL)
 					{
+						slpmsg->ft = TRUE;
+						slpmsg->slpcall->xfer_msg = slpmsg;
+
 						purple_xfer_ref(xfer);
 						purple_xfer_start(xfer,	-1, NULL, 0);
 
@@ -540,14 +553,12 @@
 							g_return_if_reached();
 						} else {
 							purple_xfer_unref(xfer);
-							slpmsg->fp = xfer->dest_fp;
-							xfer->dest_fp = NULL; /* Disable double fclose() */
 						}
 					}
 				}
 			}
 		}
-		if (!slpmsg->fp && slpmsg->size)
+		if (!slpmsg->fp && !slpmsg->ft && slpmsg->size)
 		{
 			slpmsg->buffer = g_try_malloc(slpmsg->size);
 			if (slpmsg->buffer == NULL)
@@ -574,6 +585,13 @@
 		/* fseek(slpmsg->fp, offset, SEEK_SET); */
 		len = fwrite(data, 1, len, slpmsg->fp);
 	}
+	else if (slpmsg->ft)
+	{
+		xfer = slpmsg->slpcall->xfer;
+		slpmsg->slpcall->u.incoming_data =
+				g_byte_array_append(slpmsg->slpcall->u.incoming_data, (const guchar *)data, len);
+		purple_xfer_prpl_ready(xfer);
+	}
 	else if (slpmsg->size && slpmsg->buffer)
 	{
 		if (G_MAXSIZE - len < offset || (offset + len) > slpmsg->size)
@@ -732,7 +750,6 @@
 
 	slpcall->session_init_cb = send_file_cb;
 	slpcall->end_cb = msn_xfer_end_cb;
-	slpcall->progress_cb = msn_xfer_progress_cb;
 	slpcall->cb = msn_xfer_completed_cb;
 	slpcall->xfer = xfer;
 	purple_xfer_ref(slpcall->xfer);
@@ -740,6 +757,8 @@
 	slpcall->pending = TRUE;
 
 	purple_xfer_set_cancel_send_fnc(xfer, msn_xfer_cancel);
+	purple_xfer_set_read_fnc(xfer, msn_xfer_read);
+	purple_xfer_set_write_fnc(xfer, msn_xfer_write);
 
 	xfer->data = slpcall;
 
--- a/libpurple/protocols/msn/slplink.h	Tue Nov 17 21:34:28 2009 +0000
+++ b/libpurple/protocols/msn/slplink.h	Fri Nov 20 00:35:30 2009 +0000
@@ -84,6 +84,9 @@
 void msn_slplink_process_msg(MsnSlpLink *slplink, MsnMessage *msg);
 void msn_slplink_request_ft(MsnSlpLink *slplink, PurpleXfer *xfer);
 
+/* Only exported for msn_xfer_write */
+void msn_slplink_send_msgpart(MsnSlpLink *slplink, MsnSlpMessage *slpmsg);
+
 void msn_slplink_request_object(MsnSlpLink *slplink,
 								const char *info,
 								MsnSlpCb cb,
--- a/libpurple/protocols/msn/slpmsg.h	Tue Nov 17 21:34:28 2009 +0000
+++ b/libpurple/protocols/msn/slpmsg.h	Fri Nov 20 00:35:30 2009 +0000
@@ -55,6 +55,7 @@
 	long flags;
 
 	FILE *fp;
+	gboolean ft;
 	PurpleStoredImage *img;
 	guchar *buffer;
 	long long offset;