summaryrefslogtreecommitdiff
path: root/libpurple/protocols
diff options
context:
space:
mode:
authorDaniel Atallah <datallah@pidgin.im>2007-11-15 14:53:53 +0000
committerDaniel Atallah <datallah@pidgin.im>2007-11-15 14:53:53 +0000
commitb22ec09cf752cf1f319aff527f0de88a418b3114 (patch)
tree6235fc5147ca324af7647e9174c762ca867f6f0c /libpurple/protocols
parentfc46fc12e7a662f2c9ea042b94bfaafaeec0678f (diff)
downloadpidgin-b22ec09cf752cf1f319aff527f0de88a418b3114.tar.gz
Fix a couple bugs in the Bonjour XEP-0065 implementation, mainly related to error handling, but also send a <streamhost-used /> result. Also fix a XEP-0096 bug where the SI profile wasn't being specified. These bring ft with gajim closer to working, but we aren't there yet.
Diffstat (limited to 'libpurple/protocols')
-rw-r--r--libpurple/protocols/bonjour/bonjour.c5
-rw-r--r--libpurple/protocols/bonjour/bonjour_ft.c255
-rw-r--r--libpurple/protocols/bonjour/bonjour_ft.h2
-rw-r--r--libpurple/protocols/bonjour/jabber.c33
-rw-r--r--libpurple/protocols/bonjour/jabber.h5
5 files changed, 183 insertions, 117 deletions
diff --git a/libpurple/protocols/bonjour/bonjour.c b/libpurple/protocols/bonjour/bonjour.c
index 65c6f7615a..605951f76b 100644
--- a/libpurple/protocols/bonjour/bonjour.c
+++ b/libpurple/protocols/bonjour/bonjour.c
@@ -193,6 +193,11 @@ bonjour_close(PurpleConnection *connection)
if (bonjour_group != NULL)
purple_blist_remove_group(bonjour_group);
+ /* Cancel any file transfers */
+ while (bd != NULL && bd->xfer_lists) {
+ purple_xfer_cancel_local(bd->xfer_lists->data);
+ }
+
g_free(bd);
connection->proto_data = NULL;
}
diff --git a/libpurple/protocols/bonjour/bonjour_ft.c b/libpurple/protocols/bonjour/bonjour_ft.c
index 7c9020ff1f..5d9ba853f0 100644
--- a/libpurple/protocols/bonjour/bonjour_ft.c
+++ b/libpurple/protocols/bonjour/bonjour_ft.c
@@ -45,34 +45,39 @@ static void bonjour_free_xfer(PurpleXfer *xfer);
static unsigned int next_id = 0;
static void
-xep_ft_si_reject(PurpleXfer *xfer, char *to)
+xep_ft_si_reject(BonjourData *bd, const char *id, const char *to, const char *error_code, const char *error_type)
{
xmlnode *error_node = NULL;
xmlnode *tmp_node = NULL;
XepIq *iq = NULL;
- XepXfer *xf = NULL;
- if(!to || !xfer)
- return;
- xf = xfer->data;
- if(!xf)
+ g_return_if_fail(error_code != NULL);
+ g_return_if_fail(error_type != NULL);
+
+ if(!to || !id)
return;
purple_debug_info("bonjour", "xep file transfer stream initialization error.\n");
- iq = xep_iq_new(xf->data, XEP_IQ_ERROR, to, xf->sid);
+ iq = xep_iq_new(bd, XEP_IQ_ERROR, to, purple_account_get_username(bd->jabber_data->account), id);
if(iq == NULL)
return;
error_node = xmlnode_new_child(iq->node, "error");
- xmlnode_set_attrib(error_node, "code", "403");
- xmlnode_set_attrib(error_node, "type", "cancel");
-
- tmp_node = xmlnode_new_child(error_node, "forbidden");
- xmlnode_set_namespace(tmp_node, "urn:ietf:params:xml:ns:xmpp-stanzas");
-
- tmp_node = xmlnode_new_child(error_node, "text");
- xmlnode_set_namespace(tmp_node, "urn:ietf:params:xml:ns:xmpp-stanzas");
- xmlnode_insert_data(tmp_node, "Offer Declined", -1);
+ xmlnode_set_attrib(error_node, "code", error_code);
+ xmlnode_set_attrib(error_node, "type", error_type);
+
+ /* TODO: Make this better */
+ if (!strcmp(error_code, "403")) {
+ tmp_node = xmlnode_new_child(error_node, "forbidden");
+ xmlnode_set_namespace(tmp_node, "urn:ietf:params:xml:ns:xmpp-stanzas");
+
+ tmp_node = xmlnode_new_child(error_node, "text");
+ xmlnode_set_namespace(tmp_node, "urn:ietf:params:xml:ns:xmpp-stanzas");
+ xmlnode_insert_data(tmp_node, "Offer Declined", -1);
+ } else if (!strcmp(error_code, "404")) {
+ tmp_node = xmlnode_new_child(error_node, "item-not-found");
+ xmlnode_set_namespace(tmp_node, "urn:ietf:params:xml:ns:xmpp-stanzas");
+ }
xep_iq_send_and_free(iq);
}
@@ -85,8 +90,14 @@ static void bonjour_xfer_cancel_send(PurpleXfer *xfer)
static void bonjour_xfer_request_denied(PurpleXfer *xfer)
{
+ XepXfer *xf = NULL;
+
purple_debug_info("bonjour", "Bonjour-xfer-request-denied.\n");
- xep_ft_si_reject(xfer, xfer->who);
+
+ xf = xfer->data;
+ if(xf)
+ xep_ft_si_reject(xf->data, xf->sid, xfer->who, "403", "cancel");
+
bonjour_free_xfer(xfer);
}
@@ -193,7 +204,7 @@ xep_ft_si_offer(PurpleXfer *xfer, const gchar *to)
/* Assign stream id. */
memset(buf, 0, 32);
g_snprintf(buf, sizeof(buf), "%u", next_id++);
- iq = xep_iq_new(xf->data, XEP_IQ_SET, to, buf);
+ iq = xep_iq_new(xf->data, XEP_IQ_SET, to, purple_account_get_username(bd->jabber_data->account), buf);
if(iq == NULL)
return;
@@ -202,6 +213,7 @@ xep_ft_si_offer(PurpleXfer *xfer, const gchar *to)
/*Construct Stream initialization offer message.*/
si_node = xmlnode_new_child(iq->node, "si");
xmlnode_set_namespace(si_node, "http://jabber.org/protocol/si");
+ xmlnode_set_attrib(si_node, "profile", "http://jabber.org/protocol/si/profile/file-transfer");
file = xmlnode_new_child(si_node, "file");
xmlnode_set_namespace(file, "http://jabber.org/protocol/si/profile/file-transfer");
@@ -236,37 +248,6 @@ xep_ft_si_offer(PurpleXfer *xfer, const gchar *to)
}
static void
-xep_ft_si_reject2(BonjourData *bd, const char *to, const char *sid)
-{
- xmlnode *error_node = NULL;
- xmlnode *tmp_node = NULL;
- XepIq *iq = NULL;
-
- g_return_if_fail(bd != NULL);
-
- if(!to || !sid)
- return;
-
- purple_debug_info("bonjour", "xep file transfer stream initialization error.\n");
- iq = xep_iq_new(bd, XEP_IQ_ERROR, to, sid);
- if(iq == NULL)
- return;
-
- error_node = xmlnode_new_child(iq->node, "error");
- xmlnode_set_attrib(error_node, "code", "403");
- xmlnode_set_attrib(error_node, "type", "cancel");
-
- tmp_node = xmlnode_new_child(error_node, "forbidden");
- xmlnode_set_namespace(tmp_node, "urn:ietf:params:xml:ns:xmpp-stanzas");
-
- tmp_node = xmlnode_new_child(error_node, "text");
- xmlnode_set_namespace(tmp_node, "urn:ietf:params:xml:ns:xmpp-stanzas");
- xmlnode_insert_data(tmp_node, "Offer Declined", -1);
-
- xep_iq_send_and_free(iq);
-}
-
-static void
xep_ft_si_result(PurpleXfer *xfer, char *to)
{
xmlnode *si_node = NULL;
@@ -276,6 +257,7 @@ xep_ft_si_result(PurpleXfer *xfer, char *to)
xmlnode *x = NULL;
XepIq *iq = NULL;
XepXfer *xf = NULL;
+ BonjourData *bd;
if(!to || !xfer)
return;
@@ -283,13 +265,16 @@ xep_ft_si_result(PurpleXfer *xfer, char *to)
if(!xf)
return;
+ bd = xf->data;
+
purple_debug_info("bonjour", "xep file transfer stream initialization result.\n");
- iq = xep_iq_new(xf->data, XEP_IQ_RESULT, to, xf->sid);
+ iq = xep_iq_new(bd, XEP_IQ_RESULT, to, purple_account_get_username(bd->jabber_data->account), xf->sid);
if(iq == NULL)
return;
si_node = xmlnode_new_child(iq->node, "si");
xmlnode_set_namespace(si_node, "http://jabber.org/protocol/si");
+ /*xmlnode_set_attrib(si_node, "profile", "http://jabber.org/protocol/si/profile/file-transfer");*/
feature = xmlnode_new_child(si_node, "feature");
xmlnode_set_namespace(feature, "http://jabber.org/protocol/feature-neg");
@@ -331,6 +316,7 @@ bonjour_free_xfer(PurpleXfer *xfer)
purple_proxy_connect_cancel(xf->proxy_connection);
if (xf->listen_data != NULL)
purple_network_listen_cancel(xf->listen_data);
+ g_free(xf->iq_id);
g_free(xf->jid);
g_free(xf->proxy_host);
g_free(xf->buddy_ip);
@@ -364,7 +350,9 @@ bonjour_new_xfer(PurpleConnection *gc, const char *who)
purple_debug_info("bonjour", "Bonjour-new-xfer bd=%p data=%p.\n", bd, xep_xfer->data);
- xep_xfer->mode = XEP_BYTESTREAMS | XEP_IBB;
+ /* We don't support IBB yet */
+ /*xep_xfer->mode = XEP_BYTESTREAMS | XEP_IBB;*/
+ xep_xfer->mode = XEP_BYTESTREAMS;
xep_xfer->sid = NULL;
purple_xfer_set_init_fnc(xfer, bonjour_xfer_init);
@@ -379,14 +367,15 @@ bonjour_new_xfer(PurpleConnection *gc, const char *who)
void
bonjour_send_file(PurpleConnection *gc, const char *who, const char *file)
{
-
PurpleXfer *xfer = NULL;
- if(gc == NULL || who == NULL)
- return;
+
+ g_return_if_fail(gc != NULL);
+ g_return_if_fail(who != NULL);
+
purple_debug_info("bonjour", "Bonjour-send-file to=%s.\n", who);
+
xfer = bonjour_new_xfer(gc, who);
- if(xfer == NULL)
- return;
+
if (file)
purple_xfer_request_accepted(xfer, file);
else
@@ -401,11 +390,10 @@ bonjour_xfer_init(PurpleXfer *xfer)
BonjourBuddy *bd = NULL;
XepXfer *xf = NULL;
- if(xfer == NULL)
- return;
xf = (XepXfer*)xfer->data;
if(xf == NULL)
return;
+
purple_debug_info("bonjour", "Bonjour-xfer-init.\n");
buddy = purple_find_buddy(xfer->account, xfer->who);
@@ -419,25 +407,19 @@ bonjour_xfer_init(PurpleXfer *xfer)
/* initiate file transfer, send SI offer. */
purple_debug_info("bonjour", "Bonjour xfer type is PURPLE_XFER_SEND.\n");
xep_ft_si_offer(xfer, xfer->who);
-
} else {
/* accept file transfer request, send SI result. */
xep_ft_si_result(xfer, xfer->who);
purple_debug_info("bonjour", "Bonjour xfer type is PURPLE_XFER_RECEIVE.\n");
}
- return;
}
-
void
xep_si_parse(PurpleConnection *pc, xmlnode *packet, PurpleBuddy *pb)
{
- const char *type = NULL, *from = NULL, *id = NULL;
- xmlnode *si = NULL, *file = NULL;
+ const char *type, *id;
BonjourData *bd = NULL;
PurpleXfer *xfer = NULL;
- const char *filename = NULL, *filesize_str = NULL;
- int filesize = 0, option = XEP_BYTESTREAMS;
if(pc == NULL || packet == NULL || pb == NULL)
return;
@@ -448,51 +430,73 @@ xep_si_parse(PurpleConnection *pc, xmlnode *packet, PurpleBuddy *pb)
purple_debug_info("bonjour", "xep-si-parse.\n");
type = xmlnode_get_attrib(packet, "type");
- from = pb->name;
id = xmlnode_get_attrib(packet, "id");
if(type) {
- if(!strcmp(type, "set")){
- si = xmlnode_get_child(packet,"si");
+ if(!strcmp(type, "set")) {
+ const char *profile;
+ xmlnode *si;
+ gboolean parsed_receive = FALSE;
+
+ si = xmlnode_get_child(packet, "si");
+
purple_debug_info("bonjour", "si offer Message type - SET.\n");
- file = xmlnode_get_child(si, "file");
- /**/
- filename = xmlnode_get_attrib(file, "name");
- if((filesize_str = xmlnode_get_attrib(file, "size")))
- filesize = atoi(filesize_str);
- bonjour_xfer_receive(pc, id, from, filesize, filename, option);
- } else if(!strcmp(type, "result")){
- si = xmlnode_get_child(packet,"si");
+ if (si && (profile = xmlnode_get_attrib(si, "profile"))
+ && !strcmp(profile, "http://jabber.org/protocol/si/profile/file-transfer")) {
+ const char *filename = NULL, *filesize_str = NULL;
+ int filesize = 0;
+ xmlnode *file;
+
+ if ((file = xmlnode_get_child(si, "file"))) {
+ filename = xmlnode_get_attrib(file, "name");
+ if((filesize_str = xmlnode_get_attrib(file, "size")))
+ filesize = atoi(filesize_str);
+ }
+
+ /* TODO: Make sure that it is advertising a bytestreams transfer */
+
+ bonjour_xfer_receive(pc, id, pb->name, filesize, filename, XEP_BYTESTREAMS);
+
+ parsed_receive = TRUE;
+ }
+
+ if (!parsed_receive) {
+ purple_debug_info("bonjour", "rejecting unrecognized si SET offer.\n");
+ xep_ft_si_reject((BonjourData *)pc->proto_data, id, pb->name, "403", "cancel");
+ /*TODO: Send Cancel (501) */
+ }
+ } else if(!strcmp(type, "result")) {
purple_debug_info("bonjour", "si offer Message type - RESULT.\n");
- xfer = bonjour_si_xfer_find(bd, id, from);
- if(xfer == NULL){
+
+ xfer = bonjour_si_xfer_find(bd, id, pb->name);
+
+ if(xfer == NULL) {
purple_debug_info("bonjour", "xfer find fail.\n");
- xep_ft_si_reject2((BonjourData *)pc->proto_data, from, id);
- } else {
+ xep_ft_si_reject((BonjourData *)pc->proto_data, id, pb->name, "403", "cancel");
+ } else
bonjour_bytestreams_init(xfer);
- }
- } else if(!strcmp(type, "error")){
+
+ } else if(!strcmp(type, "error")) {
purple_debug_info("bonjour", "si offer Message type - ERROR.\n");
- xfer = bonjour_si_xfer_find(bd, id, from);
- if(xfer == NULL){
+
+ xfer = bonjour_si_xfer_find(bd, id, pb->name);
+
+ if(xfer == NULL)
purple_debug_info("bonjour", "xfer find fail.\n");
- } else {
+ else
purple_xfer_cancel_remote(xfer);
- }
- } else {
+ } else
purple_debug_info("bonjour", "si offer Message type - Unknown-%d.\n", type);
- }
}
}
void
xep_bytestreams_parse(PurpleConnection *pc, xmlnode *packet, PurpleBuddy *pb)
{
- const char *type = NULL, *from = NULL, *id = NULL;
+ const char *type = NULL, *from = NULL;
xmlnode *query = NULL, *streamhost = NULL;
BonjourData *bd = NULL;
PurpleXfer *xfer = NULL;
XepXfer *xf = NULL;
- const char *jid=NULL, *host=NULL, *port=NULL;
int portnum;
if(pc == NULL || packet == NULL || pb == NULL)
@@ -508,13 +512,20 @@ xep_bytestreams_parse(PurpleConnection *pc, xmlnode *packet, PurpleBuddy *pb)
from = pb->name;
query = xmlnode_get_child(packet,"query");
if(type) {
- if(!strcmp(type, "set")){
+ if(!strcmp(type, "set")) {
+ const char *iq_id, *sid;
+ gboolean found = FALSE;
+
purple_debug_info("bonjour", "bytestream offer Message type - SET.\n");
- id = xmlnode_get_attrib(query, "sid");
- xfer = bonjour_si_xfer_find(bd, id, from);
+ iq_id = xmlnode_get_attrib(packet, "id");
+
+ sid = xmlnode_get_attrib(query, "sid");
+ xfer = bonjour_si_xfer_find(bd, sid, from);
+
+ if(xfer) {
+ const char *jid, *host, *port;
- if(xfer){
xf = (XepXfer*)xfer->data;
for(streamhost = xmlnode_get_child(query, "streamhost");
streamhost;
@@ -526,15 +537,17 @@ xep_bytestreams_parse(PurpleConnection *pc, xmlnode *packet, PurpleBuddy *pb)
(portnum = atoi(port))) {
if(!strcmp(host, xf->buddy_ip)) {
+ g_free(xf->iq_id);
+ xf->iq_id = g_strdup(iq_id);
xf->jid = g_strdup(jid);
xf->proxy_host = g_strdup(host);
xf->proxy_port = portnum;
purple_debug_info("bonjour", "bytestream offer parse"
"jid=%s host=%s port=%d.\n", jid, host, portnum);
bonjour_bytestreams_connect(xfer);
+ found = TRUE;
break;
}
-
} else {
purple_debug_info("bonjour", "bytestream offer Message parse error.\n");
}
@@ -543,8 +556,15 @@ xep_bytestreams_parse(PurpleConnection *pc, xmlnode *packet, PurpleBuddy *pb)
}
+ if (!found) {
+ purple_debug_error("bonjour", "Didn't find an acceptable streamhost.\n");
+
+ if (iq_id)
+ xep_ft_si_reject(bd, iq_id, xfer->who, "404", "cancel");
+ }
+
} else {
- purple_debug_info("bonjour", "bytestream offer Message type - Unknown-%d.\n", type);
+ purple_debug_info("bonjour", "bytestream offer Message type - Unknown-%s.\n", type);
}
}
}
@@ -557,7 +577,7 @@ bonjour_xfer_receive(PurpleConnection *pc, const char *id, const char *from,
XepXfer *xf = NULL;
BonjourData *bd = NULL;
- if(pc == NULL || id == NULL || from == NULL || filename == NULL)
+ if(pc == NULL || id == NULL || from == NULL)
return;
bd = (BonjourData*) pc->proto_data;
@@ -593,9 +613,6 @@ bonjour_sock5_request_cb(gpointer data, gint source, PurpleInputCondition cond)
int acceptfd;
int len = 0;
- if(xfer == NULL)
- return;
-
xf = xfer->data;
if(xf == NULL)
return;
@@ -608,7 +625,7 @@ bonjour_sock5_request_cb(gpointer data, gint source, PurpleInputCondition cond)
if(acceptfd == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
} else if(acceptfd == -1) {
-
+ /* TODO: This should cancel the ft */
} else {
int flags;
@@ -720,6 +737,7 @@ bonjour_bytestreams_listen(int sock, gpointer data)
const char *next_ip;
const char *local_ip = NULL;
char token [] = ";";
+ BonjourData *bd;
purple_debug_info("bonjour", "Bonjour-bytestreams-listen. sock=%d.\n", sock);
if (sock < 0 || xfer == NULL) {
@@ -732,7 +750,9 @@ bonjour_bytestreams_listen(int sock, gpointer data)
xf = (XepXfer*)xfer->data;
xf->listen_data = NULL;
- iq = xep_iq_new(xf->data, XEP_IQ_SET, xfer->who, xf->sid);
+ bd = xf->data;
+
+ iq = xep_iq_new(bd, XEP_IQ_SET, xfer->who, purple_account_get_username(bd->jabber_data->account), xf->sid);
query = xmlnode_new_child(iq->node, "query");
xmlnode_set_namespace(query, "http://jabber.org/protocol/bytestreams");
@@ -745,15 +765,15 @@ bonjour_bytestreams_listen(int sock, gpointer data)
/* cheat a little here - the intent of the "const" attribute is to make it clear that the string doesn't need to be freed */
next_ip = strtok((char *)local_ip, token);
+ port = g_strdup_printf("%hu", xfer->local_port);
while(next_ip != NULL) {
streamhost = xmlnode_new_child(query, "streamhost");
xmlnode_set_attrib(streamhost, "jid", xf->sid);
xmlnode_set_attrib(streamhost, "host", next_ip);
- port = g_strdup_printf("%hu", xfer->local_port);
xmlnode_set_attrib(streamhost, "port", port);
- g_free(port);
next_ip = strtok(NULL, token);
}
+ g_free(port);
xep_iq_send_and_free(iq);
}
@@ -781,14 +801,32 @@ bonjour_bytestreams_connect_cb(gpointer data, gint source, const gchar *error_me
{
PurpleXfer *xfer = data;
XepXfer *xf = xfer->data;
+ XepIq *iq = NULL;
+ xmlnode *q_node, *tmp_node;
+ BonjourData *bd;
- if(data == NULL || source < 0)
+ if(data == NULL || source < 0) {
+ xep_ft_si_reject(xf->data, xf->iq_id, xfer->who, "404", "cancel");
+ /* Cancel the connection */
+ purple_xfer_cancel_local(xfer);
return;
+ }
+
+ bd = xf->data;
purple_proxy_info_destroy(xf->proxy_info);
xf->proxy_connection = NULL;
xf->proxy_info = NULL;
/* Here, start the file transfer.*/
+
+ /* Notify Initiator of Connection */
+ iq = xep_iq_new(bd, XEP_IQ_RESULT, xfer->who, purple_account_get_username(bd->jabber_data->account), xf->iq_id);
+ q_node = xmlnode_new_child(iq->node, "query");
+ xmlnode_set_namespace(q_node, "http://jabber.org/protocol/bytestreams");
+ tmp_node = xmlnode_new_child(q_node, "streamhost-used");
+ xmlnode_set_attrib(tmp_node, "jid", xf->jid);
+ xep_iq_send_and_free(iq);
+
purple_xfer_start(xfer, source, NULL, -1);
}
@@ -829,8 +867,11 @@ bonjour_bytestreams_connect(PurpleXfer *xfer)
bonjour_bytestreams_connect_cb, xfer);
if(xf->proxy_connection == NULL) {
- purple_proxy_info_destroy(xf->proxy_info);
- xf->proxy_info = NULL;
+ xep_ft_si_reject(xf->data, xf->iq_id, xfer->who, "404", "cancel");
+ /* Cancel the connection */
+ purple_xfer_cancel_local(xfer);
+ /*purple_proxy_info_destroy(xf->proxy_info);
+ xf->proxy_info = NULL;*/
}
}
diff --git a/libpurple/protocols/bonjour/bonjour_ft.h b/libpurple/protocols/bonjour/bonjour_ft.h
index fdec83dec1..0be3912cb9 100644
--- a/libpurple/protocols/bonjour/bonjour_ft.h
+++ b/libpurple/protocols/bonjour/bonjour_ft.h
@@ -35,7 +35,7 @@ struct _XepXfer
void *data;
char *filename;
int filesize;
- int id;
+ char *iq_id;
char *sid;
char *recv_id;
char *buddy_ip;
diff --git a/libpurple/protocols/bonjour/jabber.c b/libpurple/protocols/bonjour/jabber.c
index 0974077e2d..7fce6cc282 100644
--- a/libpurple/protocols/bonjour/jabber.c
+++ b/libpurple/protocols/bonjour/jabber.c
@@ -89,13 +89,14 @@ _font_size_purple_to_ichat(int size)
#endif
static BonjourJabberConversation *
-bonjour_jabber_conv_new() {
+bonjour_jabber_conv_new(PurpleBuddy *pb) {
BonjourJabberConversation *bconv = g_new0(BonjourJabberConversation, 1);
bconv->socket = -1;
bconv->tx_buf = purple_circ_buffer_new(512);
bconv->tx_handler = 0;
bconv->rx_handler = 0;
+ bconv->pb = pb;
return bconv;
}
@@ -401,7 +402,6 @@ void bonjour_jabber_stream_ended(PurpleBuddy *pb) {
bonjour_jabber_close_conversation(bb->conversation);
bb->conversation = NULL;
}
-
}
void bonjour_jabber_stream_started(PurpleBuddy *pb) {
@@ -573,7 +573,7 @@ _server_socket_handler(gpointer data, int server_socket, PurpleInputCondition co
/* Check if the conversation has been previously started */
if (bb->conversation == NULL)
{
- bb->conversation = bonjour_jabber_conv_new();
+ bb->conversation = bonjour_jabber_conv_new(pb);
if (!bonjour_jabber_stream_init(pb, client_socket)) {
close(client_socket);
@@ -752,7 +752,7 @@ _find_or_start_conversation(BonjourJabber *data, const gchar *to)
return NULL;
}
- bb->conversation = bonjour_jabber_conv_new();
+ bb->conversation = bonjour_jabber_conv_new(pb);
bb->conversation->connect_data = connect_data;
/* We don't want _send_data() to register the tx_handler;
* that neeeds to wait until we're actually connected. */
@@ -816,8 +816,25 @@ bonjour_jabber_send_message(BonjourJabber *data, const gchar *to, const gchar *b
void
bonjour_jabber_close_conversation(BonjourJabberConversation *bconv)
{
- if (bconv != NULL)
- {
+ if (bconv != NULL) {
+ GList *xfers, *tmp_next;
+ BonjourData *bd = bconv->pb->account->gc->proto_data;
+
+ /* Cancel any file transfers that are waiting to begin */
+ xfers = bd->xfer_lists;
+ while(xfers != NULL) {
+ PurpleXfer *xfer = xfers->data;
+ tmp_next = xfers->next;
+ /* We only need to cancel this if it hasn't actually started transferring. */
+ /* This will change if we ever support IBB transfers. */
+ if (strcmp(xfer->who, bconv->pb->name) == 0
+ && (purple_xfer_get_status(xfer) == PURPLE_XFER_STATUS_NOT_STARTED
+ || purple_xfer_get_status(xfer) == PURPLE_XFER_STATUS_UNKNOWN)) {
+ purple_xfer_cancel_remote(xfer);
+ }
+ xfers = tmp_next;
+ }
+
/* Close the socket and remove the watcher */
if (bconv->socket >= 0) {
/* Send the end of the stream to the other end of the conversation */
@@ -874,7 +891,7 @@ bonjour_jabber_stop(BonjourJabber *data)
}
XepIq *
-xep_iq_new(void *data, XepIqType type, const gchar *to, const gchar *id)
+xep_iq_new(void *data, XepIqType type, const char *to, const char *from, const char *id)
{
xmlnode *iq_node = NULL;
XepIq *iq = NULL;
@@ -886,6 +903,7 @@ xep_iq_new(void *data, XepIqType type, const gchar *to, const gchar *id)
iq_node = xmlnode_new("iq");
xmlnode_set_attrib(iq_node, "to", to);
+ xmlnode_set_attrib(iq_node, "from", from);
xmlnode_set_attrib(iq_node, "id", id);
switch (type) {
case XEP_IQ_SET:
@@ -911,6 +929,7 @@ xep_iq_new(void *data, XepIqType type, const gchar *to, const gchar *id)
iq->type = type;
iq->data = ((BonjourData*)data)->jabber_data;
iq->to = (char*)to;
+
return iq;
}
diff --git a/libpurple/protocols/bonjour/jabber.h b/libpurple/protocols/bonjour/jabber.h
index 085aecb972..6da2e1a894 100644
--- a/libpurple/protocols/bonjour/jabber.h
+++ b/libpurple/protocols/bonjour/jabber.h
@@ -53,6 +53,7 @@ typedef struct _BonjourJabberConversation
gpointer stream_data;
xmlParserCtxt *context;
xmlnode *current;
+ PurpleBuddy *pb;
} BonjourJabberConversation;
/**
@@ -63,7 +64,7 @@ typedef struct _BonjourJabberConversation
*/
gint bonjour_jabber_start(BonjourJabber *data);
-int bonjour_jabber_send_message(BonjourJabber *data, const gchar *to, const gchar *body);
+int bonjour_jabber_send_message(BonjourJabber *data, const char *to, const char *body);
void bonjour_jabber_close_conversation(BonjourJabberConversation *bconv);
@@ -91,7 +92,7 @@ typedef struct _XepIq {
void *data;
} XepIq;
-XepIq *xep_iq_new(void *data, XepIqType type, const gchar *to, const gchar *id);
+XepIq *xep_iq_new(void *data, XepIqType type, const char *to, const char *from, const char *id);
int xep_iq_send_and_free(XepIq *iq);
const char *purple_network_get_my_ip_ext2(int fd);