diff options
author | Daniel Atallah <datallah@pidgin.im> | 2007-12-03 18:49:08 +0000 |
---|---|---|
committer | Daniel Atallah <datallah@pidgin.im> | 2007-12-03 18:49:08 +0000 |
commit | 3ac06830c2f21fb7399f7cfd89273e45d972e439 (patch) | |
tree | 375b5928e1741a7ee6769912f94c0489098dadcb | |
parent | 40a885477f3b7221f7ae9c30b0de691f80b97686 (diff) | |
download | pidgin-3ac06830c2f21fb7399f7cfd89273e45d972e439.tar.gz |
applied changes from b9c97ed0f9ada9069e8bd994b01fdde0b484083c
through 4c8cd79e13fc8711ae5e749442d990cc52bdb3fe
applied changes from 4c8cd79e13fc8711ae5e749442d990cc52bdb3fe
through c8311f90dd1011e5d2d3ab22927f6db16ce52880
-rw-r--r-- | libpurple/protocols/bonjour/jabber.c | 103 | ||||
-rw-r--r-- | libpurple/protocols/bonjour/jabber.h | 2 | ||||
-rw-r--r-- | pidgin/gtkmain.c | 2 |
3 files changed, 73 insertions, 34 deletions
diff --git a/libpurple/protocols/bonjour/jabber.c b/libpurple/protocols/bonjour/jabber.c index d28f9e8a7d..b1e1e9152b 100644 --- a/libpurple/protocols/bonjour/jabber.c +++ b/libpurple/protocols/bonjour/jabber.c @@ -62,6 +62,12 @@ #define DOCTYPE "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" \ "<stream:stream xmlns=\"jabber:client\" xmlns:stream=\"http://etherx.jabber.org/streams\" from=\"%s\" to=\"%s\">" +enum sent_stream_start_types { + NOT_SENT = 0, + PARTIALLY_SENT = 1, + FULLY_SENT = 2 +}; + static void xep_iq_parse(xmlnode *packet, PurpleConnection *connection, PurpleBuddy *pb); @@ -100,6 +106,8 @@ bonjour_jabber_conv_new(PurpleBuddy *pb) { bconv->rx_handler = 0; bconv->pb = pb; + bonjour_parser_setup(bconv); + return bconv; } @@ -289,7 +297,7 @@ _send_data(PurpleBuddy *pb, char *message) /* If we're not ready to actually send, append it to the buffer */ if (bconv->tx_handler != 0 || bconv->connect_data != NULL - || !bconv->sent_stream_start + || bconv->sent_stream_start != FULLY_SENT || !bconv->recv_stream_start || purple_circ_buffer_get_max_read(bconv->tx_buf) > 0) { ret = -1; @@ -319,6 +327,7 @@ _send_data(PurpleBuddy *pb, char *message) } if (ret < len) { + /* Don't interfere with the stream starting */ if (bconv->tx_handler == 0) bconv->tx_handler = purple_input_add(bconv->socket, PURPLE_INPUT_WRITE, _send_data_write_cb, pb); @@ -409,20 +418,6 @@ void bonjour_jabber_stream_ended(PurpleBuddy *pb) { } } -void bonjour_jabber_stream_started(PurpleBuddy *pb) { - BonjourBuddy *bb = pb->proto_data; - BonjourJabberConversation *bconv = bb->conversation; - - /* If the stream has been completely started, we can start doing stuff */ - if (bconv->sent_stream_start && bconv->recv_stream_start && purple_circ_buffer_get_max_read(bconv->tx_buf) > 0) { - /* Watch for when we can write the buffered messages */ - bconv->tx_handler = purple_input_add(bconv->socket, PURPLE_INPUT_WRITE, - _send_data_write_cb, pb); - /* We can probably write the data right now. */ - _send_data_write_cb(pb, bconv->socket, PURPLE_INPUT_WRITE); - } - -} struct _stream_start_data { char *msg; @@ -478,14 +473,13 @@ _start_stream(gpointer data, gint source, PurpleInputCondition condition) /* Stream started; process the send buffer if there is one */ purple_input_remove(bconv->tx_handler); - bconv->tx_handler= 0; - bconv->sent_stream_start = TRUE; + bconv->tx_handler = 0; + bconv->sent_stream_start = FULLY_SENT; bonjour_jabber_stream_started(pb); - } -static gboolean bonjour_jabber_stream_init(PurpleBuddy *pb, int client_socket) +static gboolean bonjour_jabber_send_stream_init(PurpleBuddy *pb, int client_socket) { int ret, len; char *stream_start; @@ -495,6 +489,8 @@ static gboolean bonjour_jabber_stream_init(PurpleBuddy *pb, int client_socket) purple_buddy_get_name(pb)); len = strlen(stream_start); + bb->conversation->sent_stream_start = PARTIALLY_SENT; + /* Start the stream */ ret = send(client_socket, stream_start, len, 0); @@ -521,18 +517,55 @@ static gboolean bonjour_jabber_stream_init(PurpleBuddy *pb, int client_socket) bb->conversation->tx_handler = purple_input_add(client_socket, PURPLE_INPUT_WRITE, _start_stream, pb); } else - bb->conversation->sent_stream_start = TRUE; + bb->conversation->sent_stream_start = FULLY_SENT; g_free(stream_start); - /* setup the parser fresh for each stream */ - bonjour_parser_setup(bb->conversation); + return TRUE; +} - bb->conversation->socket = client_socket; - bb->conversation->rx_handler = purple_input_add(client_socket, - PURPLE_INPUT_READ, _client_socket_handler, pb); +static gboolean +_async_bonjour_jabber_close_conversation(gpointer data) { + BonjourJabberConversation *bconv = data; + bonjour_jabber_close_conversation(bconv); + return FALSE; +} + +void bonjour_jabber_stream_started(PurpleBuddy *pb) { + BonjourBuddy *bb = pb->proto_data; + BonjourJabberConversation *bconv = bb->conversation; + + if (bconv->sent_stream_start == NOT_SENT && !bonjour_jabber_send_stream_init(pb, bconv->socket)) { + const char *err = g_strerror(errno); + PurpleConversation *conv; + + purple_debug_error("bonjour", "Error starting stream with buddy %s at %s:%d error: %s\n", + purple_buddy_get_name(pb), bb->ip ? bb->ip : "(null)", bb->port_p2pj, err ? err : "(null)"); + + conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, bb->name, pb->account); + if (conv != NULL) + purple_conversation_write(conv, NULL, + _("Unable to send the message, the conversation couldn't be started."), + PURPLE_MESSAGE_SYSTEM, time(NULL)); + + close(bconv->socket); + /* This must be asynchronous because it destroys the parser and we + * may be in the middle of parsing. + */ + purple_timeout_add(0, _async_bonjour_jabber_close_conversation, bb->conversation); + bb->conversation = NULL; + return; + } + + /* If the stream has been completely started, we can start doing stuff */ + if (bconv->sent_stream_start == FULLY_SENT && bconv->recv_stream_start && purple_circ_buffer_get_max_read(bconv->tx_buf) > 0) { + /* Watch for when we can write the buffered messages */ + bconv->tx_handler = purple_input_add(bconv->socket, PURPLE_INPUT_WRITE, + _send_data_write_cb, pb); + /* We can probably write the data right now. */ + _send_data_write_cb(pb, bconv->socket, PURPLE_INPUT_WRITE); + } - return TRUE; } static void @@ -576,14 +609,15 @@ _server_socket_handler(gpointer data, int server_socket, PurpleInputCondition co bb = pb->proto_data; /* Check if the conversation has been previously started */ + /* This really shouldn't ever happen unless something weird is going on */ if (bb->conversation == NULL) { bb->conversation = bonjour_jabber_conv_new(pb); - if (!bonjour_jabber_stream_init(pb, client_socket)) { - close(client_socket); - return; - } + /* We wait for the stream start before doing anything else */ + bb->conversation->socket = client_socket; + bb->conversation->rx_handler = purple_input_add(client_socket, + PURPLE_INPUT_READ, _client_socket_handler, pb); } else { purple_debug_warning("bonjour", "Ignoring incoming connection because an existing connection exists.\n"); @@ -696,7 +730,7 @@ _connected_to_buddy(gpointer data, gint source, const gchar *error) return; } - if (!bonjour_jabber_stream_init(pb, source)) { + if (!bonjour_jabber_send_stream_init(pb, source)) { const char *err = g_strerror(errno); PurpleConversation *conv; @@ -714,6 +748,11 @@ _connected_to_buddy(gpointer data, gint source, const gchar *error) bb->conversation = NULL; return; } + + /* Start listening for the stream acknowledgement */ + bb->conversation->socket = source; + bb->conversation->rx_handler = purple_input_add(source, + PURPLE_INPUT_READ, _client_socket_handler, pb); } static PurpleBuddy * @@ -843,7 +882,7 @@ bonjour_jabber_close_conversation(BonjourJabberConversation *bconv) /* Close the socket and remove the watcher */ if (bconv->socket >= 0) { /* Send the end of the stream to the other end of the conversation */ - if (bconv->sent_stream_start) + if (bconv->sent_stream_start == FULLY_SENT) send(bconv->socket, STREAM_END, strlen(STREAM_END), 0); /* TODO: We're really supposed to wait for "</stream:stream>" before closing the socket */ close(bconv->socket); diff --git a/libpurple/protocols/bonjour/jabber.h b/libpurple/protocols/bonjour/jabber.h index 6da2e1a894..4af2e1521b 100644 --- a/libpurple/protocols/bonjour/jabber.h +++ b/libpurple/protocols/bonjour/jabber.h @@ -47,7 +47,7 @@ typedef struct _BonjourJabberConversation guint rx_handler; guint tx_handler; PurpleCircBuffer *tx_buf; - gboolean sent_stream_start; + int sent_stream_start; /* 0 = Unsent, 1 = Partial, 2 = Complete */ gboolean recv_stream_start; PurpleProxyConnectData *connect_data; gpointer stream_data; diff --git a/pidgin/gtkmain.c b/pidgin/gtkmain.c index b7c52632ba..2ba613473d 100644 --- a/pidgin/gtkmain.c +++ b/pidgin/gtkmain.c @@ -609,7 +609,7 @@ int main(int argc, char *argv[]) #ifndef _WIN32 "c:dhmnl::s:v", #else - "c:dhnl::v", + "c:dhmnl::v", #endif long_options, NULL)) != -1) { switch (opt) { |