# HG changeset patch # User Daniel Atallah # Date 1181282646 0 # Node ID 61005dea822bfcfac2e42d1ecabcca59b6f91959 # Parent a8aa651f341ffb3604262def5988f0ddc0317499 Cleanup, fix a leak and prevent the inbound xml from being parsed twice for every message. diff -r a8aa651f341f -r 61005dea822b libpurple/protocols/bonjour/bonjour.c --- a/libpurple/protocols/bonjour/bonjour.c Fri Jun 08 05:06:47 2007 +0000 +++ b/libpurple/protocols/bonjour/bonjour.c Fri Jun 08 06:04:06 2007 +0000 @@ -277,7 +277,7 @@ return; } - bonjour_jabber_close_conversation(((BonjourData*)(connection->proto_data))->jabber_data, buddy); + bonjour_jabber_close_conversation(buddy); } static char * @@ -320,6 +320,8 @@ static gboolean plugin_unload(PurplePlugin *plugin) { + /* These shouldn't happen here because they are allocated in _init() */ + g_free(default_firstname); g_free(default_lastname); g_free(default_hostname); diff -r a8aa651f341f -r 61005dea822b libpurple/protocols/bonjour/jabber.c --- a/libpurple/protocols/bonjour/jabber.c Fri Jun 08 05:06:47 2007 +0000 +++ b/libpurple/protocols/bonjour/jabber.c Fri Jun 08 06:04:06 2007 +0000 @@ -28,7 +28,6 @@ #endif #include #include -#include #include #include @@ -125,9 +124,9 @@ } static void -_jabber_parse_and_write_message_to_ui(char *message, PurpleConnection *connection, PurpleBuddy *gb) +_jabber_parse_and_write_message_to_ui(xmlnode *message_node, PurpleConnection *connection, PurpleBuddy *gb) { - xmlnode *message_node, *body_node, *html_node, *events_node; + xmlnode *body_node, *html_node, *events_node; char *body, *html_body = NULL; const char *ichat_balloon_color = NULL; const char *ichat_text_color = NULL; @@ -136,16 +135,9 @@ const char *font_color = NULL; gboolean composing_event = FALSE; - /* Parsing of the message */ - message_node = xmlnode_from_str(message, strlen(message)); - if (message_node == NULL) + body_node = xmlnode_get_child(message_node, "body"); + if (body_node == NULL) return; - - body_node = xmlnode_get_child(message_node, "body"); - if (body_node == NULL) { - xmlnode_free(message_node); - return; - } body = xmlnode_get_data(body_node); html_node = xmlnode_get_child(message_node, "html"); @@ -171,11 +163,8 @@ font_color = xmlnode_get_attrib(html_body_font_node, "color"); html_body = xmlnode_get_data(html_body_font_node); if (html_body == NULL) - { - gint garbage = -1; /* This is the kind of formated messages that Purple creates */ - html_body = xmlnode_to_str(html_body_font_node, &garbage); - } + html_body = xmlnode_to_str(html_body_font_node, NULL); } } } @@ -191,7 +180,6 @@ { /* The user is just typing */ /* TODO: Deal with typing notification */ - xmlnode_free(message_node); g_free(body); g_free(html_body); return; @@ -207,8 +195,9 @@ if (font_size == NULL) font_size = "3"; if (ichat_text_color == NULL) ichat_text_color = "#000000"; if (ichat_balloon_color == NULL) ichat_balloon_color = "#FFFFFF"; - body = g_strconcat("", html_body, "", NULL); + body = g_strdup_printf("%s", + font_face, font_size, ichat_text_color, ichat_balloon_color, + html_body); } /* TODO: Should we do something with "composing_event" here? */ @@ -216,8 +205,6 @@ /* Send the message to the UI */ serv_got_im(connection, gb->name, body, 0, time(NULL)); - /* Free all the strings and nodes (the attributes are freed with their nodes) */ - xmlnode_free(message_node); g_free(body); g_free(html_body); } @@ -356,7 +343,7 @@ * using a magic string, but xmlnode won't play nice when just * parsing an end tag */ - if (purple_str_has_prefix(message, STREAM_END) || (closed_conversation == TRUE)) { + if (closed_conversation || purple_str_has_prefix(message, STREAM_END)) { char *closed_conv_message; /* Close the socket, clear the watcher and free memory */ @@ -373,11 +360,14 @@ closed_conv_message = g_strdup_printf(_("%s has closed the conversation."), gb->name); purple_conversation_write(conversation, NULL, closed_conv_message, PURPLE_MESSAGE_SYSTEM, time(NULL)); g_free(closed_conv_message); - } else { + } else if (message_node != NULL) { /* Parse the message to get the data and send to the ui */ - _jabber_parse_and_write_message_to_ui(message, account->gc, gb); + _jabber_parse_and_write_message_to_ui(message_node, account->gc, gb); + } else { + /* TODO: Deal with receiving only a partial message */ } + g_free(message); if (message_node != NULL) xmlnode_free(message_node); } @@ -426,7 +416,6 @@ bb->conversation->socket = client_socket; bb->conversation->stream_started = FALSE; bb->conversation->buddy_name = g_strdup(gb->name); - bb->conversation->message_id = 1; if (bb->conversation->stream_started == FALSE) { /* Start the stream */ @@ -517,75 +506,62 @@ int bonjour_jabber_send_message(BonjourJabber *data, const gchar *to, const gchar *body) { - xmlnode *message_node = NULL; - gchar *message = NULL; - gint message_length = -1; - xmlnode *message_body_node = NULL; - xmlnode *message_html_node = NULL; - xmlnode *message_html_body_node = NULL; - xmlnode *message_html_body_font_node = NULL; - xmlnode *message_x_node = NULL; - PurpleBuddy *gb = NULL; - BonjourBuddy *bb = NULL; - PurpleConversation *conversation = NULL; - char *message_from_ui = NULL; - char *stripped_message = NULL; - gint ret; + xmlnode *message_node, *node, *node2; + gchar *message; + PurpleBuddy *pb; + BonjourBuddy *bb; + int ret; - gb = purple_find_buddy(data->account, to); - if (gb == NULL) { + pb = purple_find_buddy(data->account, to); + if (pb == NULL) { purple_debug_info("bonjour", "Can't send a message to an offline buddy (%s).\n", to); /* You can not send a message to an offline buddy */ return -10000; } - bb = (BonjourBuddy *)gb->proto_data; + bb = pb->proto_data; /* Check if there is a previously open conversation */ if (bb->conversation == NULL) { - int socket = _connect_to_buddy(gb); + int socket = _connect_to_buddy(pb); if (socket < 0) return -10001; bb->conversation = g_new(BonjourJabberConversation, 1); bb->conversation->socket = socket; bb->conversation->stream_started = FALSE; - bb->conversation->buddy_name = g_strdup(gb->name); + bb->conversation->buddy_name = g_strdup(pb->name); bb->conversation->watcher_id = purple_input_add(bb->conversation->socket, - PURPLE_INPUT_READ, _client_socket_handler, gb); + PURPLE_INPUT_READ, _client_socket_handler, pb); } + message_node = xmlnode_new("message"); + xmlnode_set_attrib(message_node, "to", bb->name); + xmlnode_set_attrib(message_node, "from", purple_account_get_username(data->account)); + xmlnode_set_attrib(message_node, "type", "chat"); + /* Enclose the message from the UI within a "font" node */ - message_body_node = xmlnode_new("body"); - stripped_message = purple_markup_strip_html(body); - xmlnode_insert_data(message_body_node, stripped_message, strlen(stripped_message)); - g_free(stripped_message); + node = xmlnode_new_child(message_node, "body"); + message = purple_markup_strip_html(body); + xmlnode_insert_data(node, message, strlen(message)); + g_free(message); - message_from_ui = g_strconcat("", body, "", NULL); - message_html_body_font_node = xmlnode_from_str(message_from_ui, strlen(message_from_ui)); - g_free(message_from_ui); - - message_html_body_node = xmlnode_new("body"); - xmlnode_insert_child(message_html_body_node, message_html_body_font_node); + node = xmlnode_new_child(message_node, "html"); + xmlnode_set_namespace(node, "http://www.w3.org/1999/xhtml"); - message_html_node = xmlnode_new("html"); - xmlnode_set_attrib(message_html_node, "xmlns", "http://www.w3.org/1999/xhtml"); - xmlnode_insert_child(message_html_node, message_html_body_node); - - message_x_node = xmlnode_new("x"); - xmlnode_set_attrib(message_x_node, "xmlns", "jabber:x:event"); - xmlnode_insert_child(message_x_node, xmlnode_new("composing")); + node = xmlnode_new_child(node, "body"); + message = g_strdup_printf("%s", body); + node2 = xmlnode_from_str(message, strlen(message)); + g_free(message); + xmlnode_insert_child(node, node2); - message_node = xmlnode_new("message"); - xmlnode_set_attrib(message_node, "to", ((BonjourBuddy*)(gb->proto_data))->name); - xmlnode_set_attrib(message_node, "from", data->account->username); - xmlnode_set_attrib(message_node, "type", "chat"); - xmlnode_insert_child(message_node, message_body_node); - xmlnode_insert_child(message_node, message_html_node); - xmlnode_insert_child(message_node, message_x_node); + node = xmlnode_new_child(message_node, "x"); + xmlnode_set_namespace(node, "jabber:x:event"); + xmlnode_insert_child(node, xmlnode_new("composing")); - message = xmlnode_to_str(message_node, &message_length); + + message = xmlnode_to_str(message_node, NULL); xmlnode_free(message_node); /* Check if the stream for the conversation has been started */ @@ -594,10 +570,12 @@ /* Start the stream */ if (send(bb->conversation->socket, DOCTYPE, strlen(DOCTYPE), 0) == -1) { + PurpleConversation *conv; + purple_debug_error("bonjour", "Unable to start a conversation\n"); purple_debug_warning("bonjour", "send error: %s\n", strerror(errno)); - conversation = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, bb->name, data->account); - purple_conversation_write(conversation, NULL, + conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, bb->name, data->account); + purple_conversation_write(conv, NULL, _("Unable to send the message, the conversation couldn't be started."), PURPLE_MESSAGE_SYSTEM, time(NULL)); close(bb->conversation->socket); @@ -625,22 +603,26 @@ } void -bonjour_jabber_close_conversation(BonjourJabber *data, PurpleBuddy *gb) +bonjour_jabber_close_conversation(PurpleBuddy *pb) { - BonjourBuddy *bb = (BonjourBuddy*)gb->proto_data; + BonjourBuddy *bb = pb->proto_data; + BonjourJabberConversation *bconv = bb->conversation; - if (bb->conversation != NULL) + if (bconv != NULL) { - /* Send the end of the stream to the other end of the conversation */ - send(bb->conversation->socket, STREAM_END, strlen(STREAM_END), 0); - /* Close the socket and remove the watcher */ - close(bb->conversation->socket); - purple_input_remove(bb->conversation->watcher_id); + if (bconv->socket >= 0) { + /* Send the end of the stream to the other end of the conversation */ + if (bconv->stream_started) + send(bconv->socket, STREAM_END, strlen(STREAM_END), 0); + /* TODO: We're really supposed to wait for "" before closing the socket */ + close(bconv->socket); + } + purple_input_remove(bconv->watcher_id); /* Free all the data related to the conversation */ - g_free(bb->conversation->buddy_name); - g_free(bb->conversation); + g_free(bconv->buddy_name); + g_free(bconv); bb->conversation = NULL; } } @@ -657,12 +639,11 @@ /* Close all the conversation sockets and remove all the watchers after sending end streams */ if (data->account->gc != NULL) { - GSList *buddies; - GSList *l; + GSList *buddies, *l; - buddies = purple_find_buddies(data->account, data->account->username); + buddies = purple_find_buddies(data->account, purple_account_get_username(data->account)); for (l = buddies; l; l = l->next) - bonjour_jabber_close_conversation(data, l->data); + bonjour_jabber_close_conversation(l->data); g_slist_free(buddies); } } diff -r a8aa651f341f -r 61005dea822b libpurple/protocols/bonjour/jabber.h --- a/libpurple/protocols/bonjour/jabber.h Fri Jun 08 05:06:47 2007 +0000 +++ b/libpurple/protocols/bonjour/jabber.h Fri Jun 08 06:04:06 2007 +0000 @@ -45,7 +45,6 @@ gint watcher_id; gchar* buddy_name; gboolean stream_started; - gint message_id; } BonjourJabberConversation; /** @@ -58,7 +57,7 @@ int bonjour_jabber_send_message(BonjourJabber *data, const gchar *to, const gchar *body); -void bonjour_jabber_close_conversation(BonjourJabber *data, PurpleBuddy *gb); +void bonjour_jabber_close_conversation(PurpleBuddy *gb); void bonjour_jabber_stop(BonjourJabber *data);