Mercurial > pidgin.yaz
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