summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Atallah <datallah@pidgin.im>2007-12-03 18:49:08 +0000
committerDaniel Atallah <datallah@pidgin.im>2007-12-03 18:49:08 +0000
commit3ac06830c2f21fb7399f7cfd89273e45d972e439 (patch)
tree375b5928e1741a7ee6769912f94c0489098dadcb
parent40a885477f3b7221f7ae9c30b0de691f80b97686 (diff)
downloadpidgin-3ac06830c2f21fb7399f7cfd89273e45d972e439.tar.gz
applied changes from b9c97ed0f9ada9069e8bd994b01fdde0b484083c
through 4c8cd79e13fc8711ae5e749442d990cc52bdb3fe applied changes from 4c8cd79e13fc8711ae5e749442d990cc52bdb3fe through c8311f90dd1011e5d2d3ab22927f6db16ce52880
-rw-r--r--libpurple/protocols/bonjour/jabber.c103
-rw-r--r--libpurple/protocols/bonjour/jabber.h2
-rw-r--r--pidgin/gtkmain.c2
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) {