diff libpurple/protocols/msn/cmdproc.c @ 31292:47b6eda87723

propagate from branch 'im.pidgin.pidgin' (head 07d0765c444a097af45c2650f54323afb900a07b) to branch 'im.pidgin.soc.2010.msn-tlc' (head f3998422a4724ab424e4e2328f58fc0504856557)
author masca@cpw.pidgin.im
date Mon, 19 Jul 2010 21:11:32 +0000
parents 230caecf5435
children 4bc5b483699e
line wrap: on
line diff
--- a/libpurple/protocols/msn/cmdproc.c	Mon Jul 19 18:25:47 2010 +0000
+++ b/libpurple/protocols/msn/cmdproc.c	Mon Jul 19 21:11:32 2010 +0000
@@ -21,8 +21,12 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  */
-#include "msn.h"
+
+#include "internal.h"
+#include "debug.h"
+
 #include "cmdproc.h"
+#include "error.h"
 
 MsnCmdProc *
 msn_cmdproc_new(MsnSession *session)
@@ -122,7 +126,8 @@
 		return;
 	}
 
-	msn_history_add(cmdproc->history, trans);
+	if (trans->saveable)
+		msn_history_add(cmdproc->history, trans);
 
 	data = msn_transaction_to_string(trans);
 
@@ -155,75 +160,6 @@
 }
 
 void
-msn_cmdproc_send_quick(MsnCmdProc *cmdproc, const char *command,
-					   const char *format, ...)
-{
-	MsnServConn *servconn;
-	char *data;
-	char *params = NULL;
-	va_list arg;
-	size_t len;
-
-	g_return_if_fail(cmdproc != NULL);
-	g_return_if_fail(command != NULL);
-
-	servconn = cmdproc->servconn;
-
-	if (!servconn->connected)
-		return;
-
-	if (format != NULL)
-	{
-		va_start(arg, format);
-		params = g_strdup_vprintf(format, arg);
-		va_end(arg);
-	}
-
-	if (params != NULL)
-		data = g_strdup_printf("%s %s\r\n", command, params);
-	else
-		data = g_strdup_printf("%s\r\n", command);
-
-	g_free(params);
-
-	len = strlen(data);
-
-	show_debug_cmd(cmdproc, FALSE, data);
-
-	msn_servconn_write(servconn, data, len);
-
-	g_free(data);
-}
-
-void
-msn_cmdproc_send(MsnCmdProc *cmdproc, const char *command,
-				 const char *format, ...)
-{
-	MsnTransaction *trans;
-	va_list arg;
-
-	g_return_if_fail(cmdproc != NULL);
-	g_return_if_fail(command != NULL);
-
-	if (!cmdproc->servconn->connected)
-		return;
-
-	trans = g_new0(MsnTransaction, 1);
-
-	trans->cmdproc = cmdproc;
-	trans->command = g_strdup(command);
-
-	if (format != NULL)
-	{
-		va_start(arg, format);
-		trans->params = g_strdup_vprintf(format, arg);
-		va_end(arg);
-	}
-
-	msn_cmdproc_send_trans(cmdproc, trans);
-}
-
-void
 msn_cmdproc_process_payload(MsnCmdProc *cmdproc, char *payload,
 							int payload_len)
 {
@@ -243,58 +179,71 @@
 msn_cmdproc_process_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
 {
 	MsnMsgTypeCb cb;
-	const char *messageId = NULL;
+	const char *message_id = NULL;
 
 	/* Multi-part messages */
-	if ((messageId = msn_message_get_attr(msg, "Message-ID")) != NULL) {
-		const char *chunk_text = msn_message_get_attr(msg, "Chunks");
+	message_id = msn_message_get_header_value(msg, "Message-ID");
+	if (message_id != NULL) {
+		/* This is the first in a series of chunks */
+
+		const char *chunk_text = msn_message_get_header_value(msg, "Chunks");
 		guint chunk;
 		if (chunk_text != NULL) {
 			chunk = strtol(chunk_text, NULL, 10);
-			/* 1024 chunks of ~1300 bytes is ~1MB, which seems OK to prevent 
+			/* 1024 chunks of ~1300 bytes is ~1MB, which seems OK to prevent
 			   some random client causing pidgin to hog a ton of memory.
 			   Probably should figure out the maximum that the official client
 			   actually supports, though. */
 			if (chunk > 0 && chunk < 1024) {
 				msg->total_chunks = chunk;
 				msg->received_chunks = 1;
-				g_hash_table_insert(cmdproc->multiparts, (gpointer)messageId, msn_message_ref(msg));
-				purple_debug_info("msn", "Received chunked message, messageId: '%s', total chunks: %d\n",
-				                  messageId, chunk);
+				g_hash_table_insert(cmdproc->multiparts, (gpointer)message_id, msn_message_ref(msg));
+				purple_debug_info("msn", "Received chunked message, message_id: '%s', total chunks: %d\n",
+				                  message_id, chunk);
 			} else {
-				purple_debug_error("msn", "MessageId '%s' has too many chunks: %d\n", messageId, chunk);
+				purple_debug_error("msn", "MessageId '%s' has too many chunks: %d\n", message_id, chunk);
 			}
 			return;
 		} else {
-			chunk_text = msn_message_get_attr(msg, "Chunk");
+			chunk_text = msn_message_get_header_value(msg, "Chunk");
 			if (chunk_text != NULL) {
-				MsnMessage *first = g_hash_table_lookup(cmdproc->multiparts, messageId);
+				/* This is one chunk in a series of chunks */
+
+				MsnMessage *first = g_hash_table_lookup(cmdproc->multiparts, message_id);
 				chunk = strtol(chunk_text, NULL, 10);
 				if (first == NULL) {
 					purple_debug_error("msn",
-					                   "Unable to find first chunk of messageId '%s' to correspond with chunk %d.\n",
-					                   messageId, chunk+1);
-				} else if (first->received_chunks == chunk) {
-					/* Chunk is from 1 to total-1 (doesn't count first one) */
-					purple_debug_info("msn", "Received chunk %d of %d, messageId: '%s'\n",
-					                  chunk+1, first->total_chunks, messageId);
-					first->body = g_realloc(first->body, first->body_len + msg->body_len);
-					memcpy(first->body + first->body_len, msg->body, msg->body_len);
-					first->body_len += msg->body_len;
-					first->received_chunks++;
-					if (first->received_chunks != first->total_chunks)
-						return;
-					else
-						/* We're done! Send it along... The caller takes care of
-						   freeing the old one. */
-						msg = first;
-				} else {
-					/* TODO: Can you legitimately receive chunks out of order? */
-					g_hash_table_remove(cmdproc->multiparts, messageId);
+					                   "Unable to find first chunk of message_id '%s' to correspond with chunk %d.\n",
+					                   message_id, chunk + 1);
+				} else if (first->received_chunks != chunk) {
+					/*
+					 * We received an out of order chunk number (i.e. not the
+					 * next one in the sequence).  Not sure if this can happen
+					 * legitimately, but we definitely don't handle it right
+					 * now.
+					 */
+					g_hash_table_remove(cmdproc->multiparts, message_id);
 					return;
 				}
+
+				/* Chunk is from 1 to total-1 (doesn't count first one) */
+				purple_debug_info("msn", "Received chunk %d of %d, message_id: '%s'\n",
+						chunk + 1, first->total_chunks, message_id);
+				first->body = g_realloc(first->body, first->body_len + msg->body_len);
+				memcpy(first->body + first->body_len, msg->body, msg->body_len);
+				first->body_len += msg->body_len;
+				first->received_chunks++;
+				if (first->received_chunks != first->total_chunks)
+					/* We're waiting for more chunks */
+					return;
+
+				/*
+				 * We have all the chunks for this message, great!  Send
+				 * it along... The caller takes care of freeing the old one.
+				 */
+				msg = first;
 			} else {
-				purple_debug_error("msn", "Received MessageId '%s' with no chunk number!\n", messageId);
+				purple_debug_error("msn", "Received MessageId '%s' with no chunk number!\n", message_id);
 			}
 		}
 	}
@@ -314,8 +263,8 @@
 		purple_debug_warning("msn", "Unhandled content-type '%s'\n",
 						   msn_message_get_content_type(msg));
 
-	if (messageId != NULL)
-		g_hash_table_remove(cmdproc->multiparts, messageId);
+	if (message_id != NULL)
+		g_hash_table_remove(cmdproc->multiparts, message_id);
 }
 
 void