# HG changeset patch # User Mark Doliner # Date 1265617100 0 # Node ID d22b9e73c929fa12f37bd6f831b8d474601d618a # Parent d827357c6ce9ad7179ab09bd1d334682fba22e6d Shuffle some things around and add some comments. Hopefully cleaner. diff -r d827357c6ce9 -r d22b9e73c929 libpurple/protocols/msn/cmdproc.c --- a/libpurple/protocols/msn/cmdproc.c Mon Feb 08 08:00:22 2010 +0000 +++ b/libpurple/protocols/msn/cmdproc.c Mon Feb 08 08:18:20 2010 +0000 @@ -248,6 +248,8 @@ /* Multi-part messages */ 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) { @@ -269,31 +271,41 @@ } else { chunk_text = msn_message_get_header_value(msg, "Chunk"); if (chunk_text != NULL) { + /* 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 message_id '%s' to correspond with chunk %d.\n", - message_id, 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, 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) - 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? */ + 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", message_id); }