/pidgin/main: 3fd636f586dc: Merge with release-2.x.y
Daniel Atallah
datallah at pidgin.im
Sat Jan 19 14:54:52 EST 2013
Changeset: 3fd636f586dca7b82bf8f4e6fad76aa052dc432e
Author: Daniel Atallah <datallah at pidgin.im>
Date: 2013-01-19 14:54 -0500
Branch: default
URL: http://hg.pidgin.im/pidgin/main/rev/3fd636f586dc
Description:
Merge with release-2.x.y
diffstat:
ChangeLog | 5 +
Makefile.mingw | 3 +-
libpurple/protocols/bonjour/bonjour_ft.c | 166 ++++++++++++++++++++++++++----
libpurple/protocols/bonjour/bonjour_ft.h | 2 +
libpurple/win32/global.mak | 2 +-
pidgin/win32/gtkwin32dep.c | 15 ++-
6 files changed, 166 insertions(+), 27 deletions(-)
diffs (truncated from 367 to 300 lines):
diff --git a/ChangeLog b/ChangeLog
--- a/ChangeLog
+++ b/ChangeLog
@@ -96,6 +96,11 @@ version 2.10.7:
them from normal messages.
* Add support for typing notification.
* Add support for the Relationship Status profile attribute.
+ * Remove all reference to Hidden Number.
+ * Ignore new invites to join a GroupChat if you're already joined, or
+ still have a pending invite.
+ * The buddy's name was not centered vertically in the buddy-list if they
+ did not have a status-message or mood set.
Yahoo!:
* Fix a double-free in profile/picture loading code. (Mihai Serban)
diff --git a/Makefile.mingw b/Makefile.mingw
--- a/Makefile.mingw
+++ b/Makefile.mingw
@@ -45,6 +45,7 @@ gpg_sign = $(GPG_SIGN) -ab $(1) && $(GPG
STRIPPED_RELEASE_DIR = $(PIDGIN_TREE_TOP)/pidgin-$(PIDGIN_VERSION)-win32bin
DEBUG_SYMBOLS_DIR = $(PIDGIN_TREE_TOP)/pidgin-$(PIDGIN_VERSION)-dbgsym
+PIDGIN_INST_DEP_DIR="$(WIN32_DEV_TOP)/pidgin-inst-deps-20120910"
# Any *.dll or *.exe files included in win32-install-dir that we don't compile
# should be included in this list so they don't get stripped
@@ -108,7 +109,7 @@ endif
cp $(GTKSPELL_TOP)/bin/libgtkspell-0.dll $(PIDGIN_INSTALL_DIR)/spellcheck
cp $(ENCHANT_TOP)/bin/libenchant.dll $(PIDGIN_INSTALL_DIR)/spellcheck
cp -R $(ENCHANT_TOP)/lib/enchant/*.dll $(PIDGIN_INSTALL_DIR)/spellcheck/lib/enchant
- cp $(WIN32_DEV_TOP)/pidgin-inst-deps-20100315/exchndl.dll $(PIDGIN_INSTALL_DIR)
+ cp $(PIDGIN_INST_DEP_DIR)/exchndl.dll $(PIDGIN_INSTALL_DIR)
cp $(GCC_SSP_TOP)/bin/libssp-0.dll $(PIDGIN_INSTALL_DIR)
gtk_runtime_zip:
diff --git a/libpurple/protocols/bonjour/bonjour_ft.c b/libpurple/protocols/bonjour/bonjour_ft.c
--- a/libpurple/protocols/bonjour/bonjour_ft.c
+++ b/libpurple/protocols/bonjour/bonjour_ft.c
@@ -33,7 +33,7 @@
static void
bonjour_bytestreams_init(PurpleXfer *xfer);
static void
-bonjour_bytestreams_connect(PurpleXfer *xfer, PurpleBuddy *pb);
+bonjour_bytestreams_connect(PurpleXfer *xfer);
static void
bonjour_xfer_init(PurpleXfer *xfer);
static void
@@ -280,6 +280,25 @@ xep_ft_si_result(PurpleXfer *xfer, const
xep_iq_send_and_free(iq);
}
+/**
+ * Frees the whole tree of an xml node
+ *
+ * First determines the root of the xml tree and then frees the whole tree
+ * from there.
+ *
+ * @param node The node to free the tree from
+ */
+static void
+xmlnode_free_tree(xmlnode *node)
+{
+ g_return_if_fail(node != NULL);
+
+ while(xmlnode_get_parent(node))
+ node = xmlnode_get_parent(node);
+
+ xmlnode_free(node);
+}
+
static void
bonjour_free_xfer(PurpleXfer *xfer)
{
@@ -310,6 +329,9 @@ bonjour_free_xfer(PurpleXfer *xfer)
g_free(xf->proxy_host);
g_free(xf->buddy_ip);
g_free(xf->sid);
+
+ xmlnode_free_tree(xf->streamhost);
+
g_free(xf);
purple_xfer_set_protocol_data(xfer, NULL);
}
@@ -441,7 +463,7 @@ xep_si_parse(PurpleConnection *pc, xmlno
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;
+ goffset filesize = 0;
xmlnode *file;
const char *sid = xmlnode_get_attrib(si, "id");
@@ -449,7 +471,7 @@ xep_si_parse(PurpleConnection *pc, xmlno
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);
+ filesize = g_ascii_strtoll(filesize_str, NULL, 10);
}
/* TODO: Make sure that it is advertising a bytestreams transfer */
@@ -547,19 +569,97 @@ out:
return !strcmp(host, buddy_ip);
}
+static inline gint
+xep_addr_differ(const char *buddy_ip, const char *host)
+{
+ return !xep_cmp_addr(host, buddy_ip);
+}
+
+/**
+ * Create and insert an identical twin
+ *
+ * Creates a copy of the specified node and inserts it right after
+ * this original node.
+ *
+ * @param node The node to clone
+ * @return A pointer to the new, cloned twin if successful
+ * or NULL otherwise.
+ */
+static xmlnode *
+xmlnode_insert_twin_copy(xmlnode *node) {
+ xmlnode *copy;
+
+ g_return_val_if_fail(node != NULL, NULL);
+
+ copy = xmlnode_copy(node);
+ g_return_val_if_fail(copy != NULL, NULL);
+
+ copy->next = node->next;
+ node->next = copy;
+
+ return copy;
+}
+
+/**
+ * Tries to append an interface scope to an IPv6 link local address.
+ *
+ * If the given address is a link local IPv6 address (with no
+ * interface scope) then we try to determine all fitting interfaces
+ * from our Bonjour IP address list.
+ *
+ * For any such found matches we insert a copy of our current xml
+ * streamhost entry right after this streamhost entry and append
+ * the determined interface to the host address of this copy.
+ *
+ * @param cur_streamhost The XML streamhost node we examine
+ * @param host The host address to examine in text form
+ * @param pb Buddy to get the list of link local IPv6 addresses
+ * and their interface from
+ * @return Returns TRUE if the specified 'host' address is a
+ * link local IPv6 address with no interface scope.
+ * Otherwise returns FALSE.
+ */
static gboolean
-__xep_bytestreams_parse(PurpleBuddy *pb, PurpleXfer *xfer, xmlnode *query,
+add_ipv6_link_local_ifaces(xmlnode *cur_streamhost, const char *host,
+ const PurpleBuddy *pb) {
+ xmlnode *new_streamhost = NULL;
+ struct in6_addr in6_addr;
+ BonjourBuddy *bb;
+ GSList *ip_elem;
+
+ if (inet_pton(AF_INET6, host, &in6_addr) != 1 ||
+ !IN6_IS_ADDR_LINKLOCAL(&in6_addr) ||
+ strchr(host, '%'))
+ return FALSE;
+
+ bb = purple_buddy_get_protocol_data(pb);
+
+ for (ip_elem = bb->ips;
+ (ip_elem = g_slist_find_custom(ip_elem, host, (GCompareFunc)&xep_addr_differ));
+ ip_elem = ip_elem->next) {
+ purple_debug_info("bonjour", "Inserting an xmlnode twin copy for %s with new host address %s\n",
+ host, (char*)ip_elem->data);
+ new_streamhost = xmlnode_insert_twin_copy(cur_streamhost);
+ xmlnode_set_attrib(new_streamhost, "host", ip_elem->data);
+ }
+
+ if (!new_streamhost)
+ purple_debug_info("bonjour", "No interface for this IPv6 link local address found: %s\n",
+ host);
+
+ return TRUE;
+}
+
+static gboolean
+__xep_bytestreams_parse(PurpleBuddy *pb, PurpleXfer *xfer, xmlnode *streamhost,
const char *iq_id)
{
+ char *tmp_iq_id;
const char *jid, *host, *port;
int portnum;
- xmlnode *streamhost;
XepXfer *xf = purple_xfer_get_protocol_data(xfer);
- for(streamhost = xmlnode_get_child(query, "streamhost");
- streamhost;
- streamhost = xmlnode_get_next_twin(streamhost)) {
-
+ for(; streamhost; streamhost = xmlnode_get_next_twin(streamhost)) {
if(!(jid = xmlnode_get_attrib(streamhost, "jid")) ||
!(host = xmlnode_get_attrib(streamhost, "host")) ||
!(port = xmlnode_get_attrib(streamhost, "port")) ||
@@ -568,29 +668,36 @@ static gboolean
continue;
}
- if(!xep_cmp_addr(host, xf->buddy_ip))
+ /* skip IPv6 link local addresses with no interface scope
+ * (but try to add a new one with an interface scope then) */
+ if(add_ipv6_link_local_ifaces(streamhost, host, pb))
continue;
+ tmp_iq_id = g_strdup(iq_id);
g_free(xf->iq_id);
- xf->iq_id = g_strdup(iq_id);
+ g_free(xf->jid);
+ g_free(xf->proxy_host);
+
+ xf->iq_id = tmp_iq_id;
xf->jid = g_strdup(jid);
- xf->proxy_host = g_strdup(xf->buddy_ip);
+ xf->proxy_host = g_strdup(host);
xf->proxy_port = portnum;
+ xf->streamhost = streamhost;
+ xf->pb = pb;
purple_debug_info("bonjour", "bytestream offer parse"
"jid=%s host=%s port=%d.\n", jid, host, portnum);
- bonjour_bytestreams_connect(xfer, pb);
+ bonjour_bytestreams_connect(xfer);
return TRUE;
}
return FALSE;
}
-
void
xep_bytestreams_parse(PurpleConnection *pc, xmlnode *packet, PurpleBuddy *pb)
{
const char *type, *from, *iq_id, *sid;
- xmlnode *query;
+ xmlnode *query, *streamhost;
BonjourData *bd;
PurpleXfer *xfer;
@@ -610,6 +717,10 @@ xep_bytestreams_parse(PurpleConnection *
if(!type)
return;
+ query = xmlnode_copy(query);
+ if (!query)
+ return;
+
if(strcmp(type, "set")) {
purple_debug_info("bonjour", "bytestream offer Message type - Unknown-%s.\n", type);
return;
@@ -621,7 +732,9 @@ xep_bytestreams_parse(PurpleConnection *
sid = xmlnode_get_attrib(query, "sid");
xfer = bonjour_si_xfer_find(bd, sid, from);
- if(xfer && __xep_bytestreams_parse(pb, xfer, query, iq_id))
+ streamhost = xmlnode_get_child(query, "streamhost");
+
+ if(xfer && streamhost && __xep_bytestreams_parse(pb, xfer, streamhost, iq_id))
return; /* success */
purple_debug_error("bonjour", "Didn't find an acceptable streamhost.\n");
@@ -864,15 +977,22 @@ bonjour_bytestreams_connect_cb(gpointer
XepIq *iq;
xmlnode *q_node, *tmp_node;
BonjourData *bd;
+ gboolean ret = FALSE;
xf->proxy_connection = NULL;
if(source < 0) {
- purple_debug_error("bonjour", "Error connecting via SOCKS5 - %s\n",
- error_message ? error_message : "(null)");
- xep_ft_si_reject(xf->data, xf->iq_id, purple_xfer_get_remote_user(xfer), "404", "cancel");
- /* Cancel the connection */
- purple_xfer_cancel_local(xfer);
+ purple_debug_error("bonjour", "Error connecting via SOCKS5 to %s - %s\n",
+ xf->proxy_host, error_message ? error_message : "(null)");
+
+ tmp_node = xmlnode_get_next_twin(xf->streamhost);
+ ret = __xep_bytestreams_parse(xf->pb, xfer, tmp_node, xf->iq_id);
+
+ if (!ret) {
+ xep_ft_si_reject(xf->data, xf->iq_id, purple_xfer_get_remote_user(xfer), "404", "cancel");
+ /* Cancel the connection */
+ purple_xfer_cancel_local(xfer);
+ }
return;
}
@@ -894,8 +1014,9 @@ bonjour_bytestreams_connect_cb(gpointer
}
More information about the Commits
mailing list