changeset 30592:8ada5c6f305d

merge of '2fa8397877be345efa9c19c1530ad7686236d8e4' and 'c6b054bb793c9916eb187da12bda64c518f506df'
author Paul Aurich <paul@darkrain42.org>
date Sun, 10 Oct 2010 05:25:42 +0000
parents 485eaf544bb0 (diff) 63ce2608c2c0 (current diff)
children e492df53a0f3
files
diffstat 16 files changed, 370 insertions(+), 281 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Wed Sep 29 05:38:04 2010 +0000
+++ b/ChangeLog	Sun Oct 10 05:25:42 2010 +0000
@@ -9,7 +9,7 @@
 	libpurple:
 	* Fall back to an ordinary request if a UI does not support showing a
 	  request with an icon.  Fixes receiving MSN file transfer requests
-	  including a thumbnail in Finch.
+	  including a thumbnail in Finch. (#12561)
 	* Fix an invalid memory access when removing UPnP mappings that could
 	  cause sporadic crashes, most notably when MSN Direct Connections are
 	  enabled. (#12387)
@@ -62,6 +62,8 @@
 	  solves deadlocks when a given Yahoo account has a ridiculously large
 	  (>500 buddies) list and may improve login speed for those on slow
 	  connections. (#12532)
+	* Fix sending SMS messages.  The lookup host changed on us.  (Thanks to
+	  todo) (#12688).
 
 version 2.7.3 (08/10/2010):
 	General:
--- a/libpurple/ft.c	Wed Sep 29 05:38:04 2010 +0000
+++ b/libpurple/ft.c	Sun Oct 10 05:25:42 2010 +0000
@@ -1291,6 +1291,11 @@
 	PurpleXferType type = purple_xfer_get_type(xfer);
 	PurpleXferUiOps *ui_ops = purple_xfer_get_ui_ops(xfer);
 
+	if (xfer->start_time != 0) {
+		purple_debug_error("xfer", "Transfer is being started multiple times\n");
+		g_return_if_reached();
+	}
+
 	if (ui_ops == NULL || (ui_ops->ui_read == NULL && ui_ops->ui_write == NULL)) {
 		xfer->dest_fp = g_fopen(purple_xfer_get_local_filename(xfer),
 		                        type == PURPLE_XFER_RECEIVE ? "wb" : "rb");
--- a/libpurple/protocols/bonjour/bonjour.c	Wed Sep 29 05:38:04 2010 +0000
+++ b/libpurple/protocols/bonjour/bonjour.c	Sun Oct 10 05:25:42 2010 +0000
@@ -46,7 +46,14 @@
 
 static char *default_firstname;
 static char *default_lastname;
-static char *default_hostname;
+
+const char *
+bonjour_get_jid(PurpleAccount *account)
+{
+	PurpleConnection *conn = purple_account_get_connection(account);
+	BonjourData *bd = conn->proto_data;
+	return bd->jid;
+}
 
 static void
 bonjour_removeallfromlocal(PurpleConnection *conn, PurpleGroup *bonjour_group)
@@ -182,6 +189,7 @@
 		purple_xfer_cancel_local(bd->xfer_lists->data);
 	}
 
+	g_free(bd->jid);
 	g_free(bd);
 	connection->proto_data = NULL;
 }
@@ -389,7 +397,8 @@
 		purple_notify_user_info_add_pair(user_info, _("XMPP Account"), bb->jid);
 }
 
-static void bonjour_do_group_change(PurpleBuddy *buddy, const char *new_group) {
+static void
+bonjour_do_group_change(PurpleBuddy *buddy, const char *new_group) {
 	PurpleBlistNodeFlags oldflags;
 
 	if (buddy == NULL)
@@ -445,7 +454,6 @@
 
 	g_free(default_firstname);
 	g_free(default_lastname);
-	g_free(default_hostname);
 
 	return TRUE;
 }
@@ -566,7 +574,8 @@
 };
 
 #ifdef WIN32
-static gboolean _set_default_name_cb(gpointer data) {
+static gboolean
+_set_default_name_cb(gpointer data) {
 	gchar *fullname = data;
 	const char *splitpoint;
 	GList *tmp = prpl_info.protocol_options;
@@ -603,7 +612,8 @@
 	return FALSE;
 }
 
-static gpointer _win32_name_lookup_thread(gpointer data) {
+static gpointer
+_win32_name_lookup_thread(gpointer data) {
 	gchar *fullname = NULL;
 	wchar_t username[UNLEN + 1];
 	DWORD dwLenUsername = UNLEN + 1;
@@ -707,24 +717,15 @@
 	}
 
 	g_free(conv);
-
-	/* Try to figure out a good host name to use */
-	/* TODO: Avoid 'localhost,' if possible */
-	default_hostname = g_strdup(purple_get_host_name());
 }
 
 static void
 init_plugin(PurplePlugin *plugin)
 {
-	PurpleAccountUserSplit *split;
 	PurpleAccountOption *option;
 
 	initialize_default_account_values();
 
-	/* Creating the user splits */
-	split = purple_account_user_split_new(_("Hostname"), default_hostname, '@');
-	prpl_info.user_splits = g_list_append(prpl_info.user_splits, split);
-
 	/* Creating the options for the protocol */
 	option = purple_account_option_int_new(_("Local Port"), "port", BONJOUR_DEFAULT_PORT);
 	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
--- a/libpurple/protocols/bonjour/bonjour.h	Wed Sep 29 05:38:04 2010 +0000
+++ b/libpurple/protocols/bonjour/bonjour.h	Sun Oct 10 05:25:42 2010 +0000
@@ -45,6 +45,12 @@
 	BonjourDnsSd *dns_sd_data;
 	BonjourJabber *jabber_data;
 	GSList *xfer_lists;
+	gchar *jid;
 } BonjourData;
 
+/**
+ *  This will always be username@machinename
+ */
+const char *bonjour_get_jid(PurpleAccount *account);
+
 #endif /* _BONJOUR_H_ */
--- a/libpurple/protocols/bonjour/bonjour_ft.c	Wed Sep 29 05:38:04 2010 +0000
+++ b/libpurple/protocols/bonjour/bonjour_ft.c	Sun Oct 10 05:25:42 2010 +0000
@@ -53,11 +53,12 @@
 	g_return_if_fail(error_code != NULL);
 	g_return_if_fail(error_type != NULL);
 
-	if(!to || !id)
+	if(!to || !id) {
+		purple_debug_info("bonjour", "xep file transfer stream initialization error.\n");
 		return;
+	}
 
-	purple_debug_info("bonjour", "xep file transfer stream initialization error.\n");
-	iq = xep_iq_new(bd, XEP_IQ_ERROR, to, purple_account_get_username(bd->jabber_data->account), id);
+	iq = xep_iq_new(bd, XEP_IQ_ERROR, to, bonjour_get_jid(bd->jabber_data->account), id);
 	if(iq == NULL)
 		return;
 
@@ -195,7 +196,7 @@
 	/* Assign stream id. */
 	g_free(xf->iq_id);
 	xf->iq_id = g_strdup_printf("%u", next_id++);
-	iq = xep_iq_new(xf->data, XEP_IQ_SET, to, purple_account_get_username(bd->jabber_data->account), xf->iq_id);
+	iq = xep_iq_new(xf->data, XEP_IQ_SET, to, bonjour_get_jid(bd->jabber_data->account), xf->iq_id);
 	if(iq == NULL)
 		return;
 
@@ -255,7 +256,7 @@
 	bd = xf->data;
 
 	purple_debug_info("bonjour", "xep file transfer stream initialization result.\n");
-	iq = xep_iq_new(bd, XEP_IQ_RESULT, to, purple_account_get_username(bd->jabber_data->account), xf->iq_id);
+	iq = xep_iq_new(bd, XEP_IQ_RESULT, to, bonjour_get_jid(bd->jabber_data->account), xf->iq_id);
 	if(iq == NULL)
 		return;
 
@@ -763,7 +764,7 @@
 
 	bd = xf->data;
 
-	iq = xep_iq_new(bd, XEP_IQ_SET, xfer->who, purple_account_get_username(bd->jabber_data->account), xf->sid);
+	iq = xep_iq_new(bd, XEP_IQ_SET, xfer->who, bonjour_get_jid(bd->jabber_data->account), xf->sid);
 
 	query = xmlnode_new_child(iq->node, "query");
 	xmlnode_set_namespace(query, "http://jabber.org/protocol/bytestreams");
@@ -835,7 +836,7 @@
 	/* 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);
+	iq = xep_iq_new(bd, XEP_IQ_RESULT, xfer->who, bonjour_get_jid(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");
@@ -868,7 +869,7 @@
 	name = purple_buddy_get_name(pb);
 	account = purple_buddy_get_account(pb);
 
-	p = g_strdup_printf("%s%s%s", xf->sid, name, purple_account_get_username(account));
+	p = g_strdup_printf("%s%s%s", xf->sid, name, bonjour_get_jid(account));
 	purple_cipher_digest_region("sha1", (guchar *)p, strlen(p),
 				    sizeof(hashval), hashval, NULL);
 	g_free(p);
--- a/libpurple/protocols/bonjour/dns_sd_proxy.c	Wed Sep 29 05:38:04 2010 +0000
+++ b/libpurple/protocols/bonjour/dns_sd_proxy.c	Sun Oct 10 05:25:42 2010 +0000
@@ -1,181 +1,191 @@
-/*
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here.  Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Library General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301, USA.
- */
-
-#include "win32dep.h"
-#include "dns_sd_proxy.h"
-
-#ifndef LINK_DNS_SD_DIRECTLY
-static DNSServiceErrorType (DNSSD_API* _DNSServiceAddRecord)(DNSServiceRef sdRef, DNSRecordRef *RecordRef, DNSServiceFlags flags,
-		uint16_t rrtype, uint16_t rdlen, const void *rdata, uint32_t ttl);
-static DNSServiceErrorType (DNSSD_API* _DNSServiceBrowse)(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
-	const char *regtype, const char *domain, DNSServiceBrowseReply callBack, void *context);
-static int (DNSSD_API* _DNSServiceConstructFullName)(char *fullName, const char *service, const char *regtype, const char *domain);
-static DNSServiceErrorType (DNSSD_API* _DNSServiceProcessResult)(DNSServiceRef sdRef);
-static DNSServiceErrorType (DNSSD_API* _DNSServiceQueryRecord)(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
-	const char *fullname, uint16_t rrtype, uint16_t rrclass, DNSServiceQueryRecordReply callBack, void *context);
-static void (DNSSD_API* _DNSServiceRefDeallocate)(DNSServiceRef sdRef);
-static int (DNSSD_API* _DNSServiceRefSockFD)(DNSServiceRef sdRef);
-static DNSServiceErrorType (DNSSD_API* _DNSServiceRegister)(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
-	const char *name, const char *regtype, const char *domain, const char *host, uint16_t port, uint16_t txtLen,
-	const void *txtRecord, DNSServiceRegisterReply callBack, void *context);
-static DNSServiceErrorType (DNSSD_API* _DNSServiceResolve)(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, const char *name,
-	const char *regtype, const char *domain, DNSServiceResolveReply callBack, void *context);
-static DNSServiceErrorType (DNSSD_API* _DNSServiceRemoveRecord)(DNSServiceRef sdRef, DNSRecordRef RecordRef, DNSServiceFlags flags);
-static DNSServiceErrorType (DNSSD_API* _DNSServiceUpdateRecord)(DNSServiceRef sdRef, DNSRecordRef RecordRef, DNSServiceFlags flags,
-	uint16_t rdlen, const void *rdata, uint32_t ttl);
-static void (DNSSD_API* _TXTRecordCreate)(TXTRecordRef *txtRecord, uint16_t bufferLen, void *buffer);
-static void (DNSSD_API* _TXTRecordDeallocate)(TXTRecordRef *txtRecord);
-static const void * (DNSSD_API* _TXTRecordGetBytesPtr)(const TXTRecordRef *txtRecord);
-static int16_t (DNSSD_API* _TXTRecordGetLength)(const TXTRecordRef *txtRecord);
-static const void * (DNSSD_API* _TXTRecordGetValuePtr)(uint16_t txtLen, const void *txtRecord, const char *key, uint8_t *valueLen);
-static DNSServiceErrorType (DNSSD_API* _TXTRecordSetValue)(TXTRecordRef *txtRecord, const char *key, uint8_t valueSize, const void *value);
-#endif
-
-gboolean dns_sd_available(void) {
-#ifndef LINK_DNS_SD_DIRECTLY
-	static gboolean initialized = FALSE;
-	static gboolean loaded = FALSE;
-
-	if (!initialized) {
-		initialized = TRUE;
-		if ((_DNSServiceAddRecord = (void *) wpurple_find_and_loadproc("dnssd.dll", "DNSServiceAddRecord"))
-				&& (_DNSServiceBrowse = (void *) wpurple_find_and_loadproc("dnssd.dll", "DNSServiceBrowse"))
-				&& (_DNSServiceConstructFullName = (void *) wpurple_find_and_loadproc("dnssd.dll", "DNSServiceConstructFullName"))
-				&& (_DNSServiceProcessResult = (void *) wpurple_find_and_loadproc("dnssd.dll", "DNSServiceProcessResult"))
-				&& (_DNSServiceQueryRecord = (void *) wpurple_find_and_loadproc("dnssd.dll", "DNSServiceQueryRecord"))
-				&& (_DNSServiceRefDeallocate = (void *) wpurple_find_and_loadproc("dnssd.dll", "DNSServiceRefDeallocate"))
-				&& (_DNSServiceRefSockFD = (void *) wpurple_find_and_loadproc("dnssd.dll", "DNSServiceRefSockFD"))
-				&& (_DNSServiceRegister = (void *) wpurple_find_and_loadproc("dnssd.dll", "DNSServiceRegister"))
-				&& (_DNSServiceResolve = (void *) wpurple_find_and_loadproc("dnssd.dll", "DNSServiceResolve"))
-				&& (_DNSServiceRemoveRecord = (void *) wpurple_find_and_loadproc("dnssd.dll", "DNSServiceRemoveRecord"))
-				&& (_DNSServiceUpdateRecord = (void *) wpurple_find_and_loadproc("dnssd.dll", "DNSServiceUpdateRecord"))
-				&& (_TXTRecordCreate = (void *) wpurple_find_and_loadproc("dnssd.dll", "TXTRecordCreate"))
-				&& (_TXTRecordDeallocate = (void *) wpurple_find_and_loadproc("dnssd.dll", "TXTRecordDeallocate"))
-				&& (_TXTRecordGetBytesPtr = (void *) wpurple_find_and_loadproc("dnssd.dll", "TXTRecordGetBytesPtr"))
-				&& (_TXTRecordGetLength = (void *) wpurple_find_and_loadproc("dnssd.dll", "TXTRecordGetLength"))
-				&& (_TXTRecordGetValuePtr = (void *) wpurple_find_and_loadproc("dnssd.dll", "TXTRecordGetValuePtr"))
-				&& (_TXTRecordSetValue = (void *) wpurple_find_and_loadproc("dnssd.dll", "TXTRecordSetValue"))) {
-			loaded = TRUE;
-		}
-	}
-	return loaded;
-#else
-	return TRUE;
-#endif
-}
-
-#ifndef LINK_DNS_SD_DIRECTLY
-
-DNSServiceErrorType _wpurple_DNSServiceAddRecord(DNSServiceRef sdRef, DNSRecordRef *RecordRef, DNSServiceFlags flags,
-		uint16_t rrtype, uint16_t rdlen, const void *rdata, uint32_t ttl) {
-	g_return_val_if_fail(_DNSServiceAddRecord != NULL, kDNSServiceErr_Unknown);
-	return (_DNSServiceAddRecord)(sdRef, RecordRef, flags, rrtype, rdlen, rdata, ttl);
-}
-
-DNSServiceErrorType _wpurple_DNSServiceBrowse(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
-		const char *regtype, const char *domain, DNSServiceBrowseReply callBack, void *context) {
-	g_return_val_if_fail(_DNSServiceBrowse != NULL, kDNSServiceErr_Unknown);
-	return (_DNSServiceBrowse)(sdRef, flags, interfaceIndex, regtype, domain, callBack, context);
-}
-
-int _wpurple_DNSServiceConstructFullName(char *fullName, const char *service, const char *regtype, const char *domain) {
-	g_return_val_if_fail(_DNSServiceConstructFullName != NULL, 0);
-	return (_DNSServiceConstructFullName)(fullName, service, regtype, domain);
-}
-
-DNSServiceErrorType _wpurple_DNSServiceProcessResult(DNSServiceRef sdRef) {
-	g_return_val_if_fail(_DNSServiceProcessResult != NULL, kDNSServiceErr_Unknown);
-	return (_DNSServiceProcessResult)(sdRef);
-}
-
-
-DNSServiceErrorType _wpurple_DNSServiceQueryRecord(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
-		const char *fullname, uint16_t rrtype, uint16_t rrclass, DNSServiceQueryRecordReply callBack, void *context) {
-	g_return_val_if_fail(_DNSServiceQueryRecord != NULL, kDNSServiceErr_Unknown);
-	return (_DNSServiceQueryRecord)(sdRef, flags, interfaceIndex, fullname, rrtype, rrclass, callBack, context);
-}
-
-void _wpurple_DNSServiceRefDeallocate(DNSServiceRef sdRef) {
-	g_return_if_fail(_DNSServiceRefDeallocate != NULL);
-	(_DNSServiceRefDeallocate)(sdRef);
-}
-
-int _wpurple_DNSServiceRefSockFD(DNSServiceRef sdRef) {
-	g_return_val_if_fail(_DNSServiceRefSockFD != NULL, -1);
-	return (_DNSServiceRefSockFD)(sdRef);
-}
-
-DNSServiceErrorType _wpurple_DNSServiceRegister(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
-		const char *name, const char *regtype, const char *domain, const char *host, uint16_t port, uint16_t txtLen,
-		const void *txtRecord, DNSServiceRegisterReply callBack, void *context) {
-	g_return_val_if_fail(_DNSServiceRegister != NULL, kDNSServiceErr_Unknown);
-	return (_DNSServiceRegister)(sdRef, flags, interfaceIndex, name, regtype, domain, host, port, txtLen, txtRecord, callBack, context);
-}
-
-DNSServiceErrorType _wpurple_DNSServiceResolve(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, const char *name,
-		const char *regtype, const char *domain, DNSServiceResolveReply callBack, void *context) {
-	g_return_val_if_fail(_DNSServiceResolve != NULL, kDNSServiceErr_Unknown);
-	return (_DNSServiceResolve)(sdRef, flags, interfaceIndex, name, regtype, domain, callBack, context);
-}
-
-DNSServiceErrorType _wpurple_DNSServiceRemoveRecord(DNSServiceRef sdRef, DNSRecordRef RecordRef, DNSServiceFlags flags) {
-	g_return_val_if_fail(_DNSServiceRemoveRecord != NULL, kDNSServiceErr_Unknown);
-	return (_DNSServiceRemoveRecord)(sdRef, RecordRef, flags);
-}
-
-DNSServiceErrorType _wpurple_DNSServiceUpdateRecord(DNSServiceRef sdRef, DNSRecordRef RecordRef, DNSServiceFlags flags,
-		uint16_t rdlen, const void *rdata, uint32_t ttl) {
-	g_return_val_if_fail(_DNSServiceUpdateRecord != NULL, kDNSServiceErr_Unknown);
-	return (_DNSServiceUpdateRecord)(sdRef, RecordRef, flags, rdlen, rdata, ttl);
-}
-
-void _wpurple_TXTRecordCreate(TXTRecordRef *txtRecord, uint16_t bufferLen, void *buffer) {
-	g_return_if_fail(_TXTRecordCreate != NULL);
-	(_TXTRecordCreate)(txtRecord, bufferLen, buffer);
-}
-
-void _wpurple_TXTRecordDeallocate(TXTRecordRef *txtRecord) {
-	g_return_if_fail(_TXTRecordDeallocate != NULL);
-	(_TXTRecordDeallocate)(txtRecord);
-}
-
-const void * _wpurple_TXTRecordGetBytesPtr(const TXTRecordRef *txtRecord) {
-	g_return_val_if_fail(_TXTRecordGetBytesPtr != NULL, NULL);
-	return (_TXTRecordGetBytesPtr)(txtRecord);
-}
-
-uint16_t _wpurple_TXTRecordGetLength(const TXTRecordRef *txtRecord) {
-	g_return_val_if_fail(_TXTRecordGetLength != NULL, 0);
-	return (_TXTRecordGetLength)(txtRecord);
-}
-
-const void * _wpurple_TXTRecordGetValuePtr(uint16_t txtLen, const void *txtRecord, const char *key, uint8_t *valueLen) {
-	g_return_val_if_fail(_TXTRecordGetValuePtr != NULL, NULL);
-	return (_TXTRecordGetValuePtr)(txtLen, txtRecord, key, valueLen);
-}
-
-DNSServiceErrorType _wpurple_TXTRecordSetValue(TXTRecordRef *txtRecord, const char *key, uint8_t valueSize, const void *value) {
-	g_return_val_if_fail(_TXTRecordSetValue != NULL, kDNSServiceErr_Unknown);
-	return (_TXTRecordSetValue)(txtRecord, key, valueSize, value);
-}
-
-#endif /*LINK_DNS_SD_DIRECTLY*/
-
+/*
+ *
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301, USA.
+ */
+
+#include "win32dep.h"
+#include "dns_sd_proxy.h"
+
+#ifndef LINK_DNS_SD_DIRECTLY
+static DNSServiceErrorType (DNSSD_API* _DNSServiceAddRecord)(DNSServiceRef sdRef, DNSRecordRef *RecordRef, DNSServiceFlags flags,
+		uint16_t rrtype, uint16_t rdlen, const void *rdata, uint32_t ttl);
+static DNSServiceErrorType (DNSSD_API* _DNSServiceBrowse)(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
+	const char *regtype, const char *domain, DNSServiceBrowseReply callBack, void *context);
+static int (DNSSD_API* _DNSServiceConstructFullName)(char *fullName, const char *service, const char *regtype, const char *domain);
+static DNSServiceErrorType (DNSSD_API* _DNSServiceGetAddrInfo)(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
+	DNSServiceProtocol protocol, const char *hostname, DNSServiceGetAddrInfoReply callBack, void *context);
+static DNSServiceErrorType (DNSSD_API* _DNSServiceProcessResult)(DNSServiceRef sdRef);
+static DNSServiceErrorType (DNSSD_API* _DNSServiceQueryRecord)(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
+	const char *fullname, uint16_t rrtype, uint16_t rrclass, DNSServiceQueryRecordReply callBack, void *context);
+static void (DNSSD_API* _DNSServiceRefDeallocate)(DNSServiceRef sdRef);
+static int (DNSSD_API* _DNSServiceRefSockFD)(DNSServiceRef sdRef);
+static DNSServiceErrorType (DNSSD_API* _DNSServiceRegister)(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
+	const char *name, const char *regtype, const char *domain, const char *host, uint16_t port, uint16_t txtLen,
+	const void *txtRecord, DNSServiceRegisterReply callBack, void *context);
+static DNSServiceErrorType (DNSSD_API* _DNSServiceResolve)(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, const char *name,
+	const char *regtype, const char *domain, DNSServiceResolveReply callBack, void *context);
+static DNSServiceErrorType (DNSSD_API* _DNSServiceRemoveRecord)(DNSServiceRef sdRef, DNSRecordRef RecordRef, DNSServiceFlags flags);
+static DNSServiceErrorType (DNSSD_API* _DNSServiceUpdateRecord)(DNSServiceRef sdRef, DNSRecordRef RecordRef, DNSServiceFlags flags,
+	uint16_t rdlen, const void *rdata, uint32_t ttl);
+static void (DNSSD_API* _TXTRecordCreate)(TXTRecordRef *txtRecord, uint16_t bufferLen, void *buffer);
+static void (DNSSD_API* _TXTRecordDeallocate)(TXTRecordRef *txtRecord);
+static const void * (DNSSD_API* _TXTRecordGetBytesPtr)(const TXTRecordRef *txtRecord);
+static int16_t (DNSSD_API* _TXTRecordGetLength)(const TXTRecordRef *txtRecord);
+static const void * (DNSSD_API* _TXTRecordGetValuePtr)(uint16_t txtLen, const void *txtRecord, const char *key, uint8_t *valueLen);
+static DNSServiceErrorType (DNSSD_API* _TXTRecordSetValue)(TXTRecordRef *txtRecord, const char *key, uint8_t valueSize, const void *value);
+
+#endif
+
+gboolean dns_sd_available(void) {
+#ifndef LINK_DNS_SD_DIRECTLY
+	static gboolean initialized = FALSE;
+	static gboolean loaded = FALSE;
+
+	if (!initialized) {
+		initialized = TRUE;
+		if ((_DNSServiceAddRecord = (void *) wpurple_find_and_loadproc("dnssd.dll", "DNSServiceAddRecord"))
+				&& (_DNSServiceBrowse = (void *) wpurple_find_and_loadproc("dnssd.dll", "DNSServiceBrowse"))
+				&& (_DNSServiceConstructFullName = (void *) wpurple_find_and_loadproc("dnssd.dll", "DNSServiceConstructFullName"))
+				&& (_DNSServiceGetAddrInfo = (void *) wpurple_find_and_loadproc("dnssd.dll", "DNSServiceGetAddrInfo"))
+				&& (_DNSServiceProcessResult = (void *) wpurple_find_and_loadproc("dnssd.dll", "DNSServiceProcessResult"))
+				&& (_DNSServiceQueryRecord = (void *) wpurple_find_and_loadproc("dnssd.dll", "DNSServiceQueryRecord"))
+				&& (_DNSServiceRefDeallocate = (void *) wpurple_find_and_loadproc("dnssd.dll", "DNSServiceRefDeallocate"))
+				&& (_DNSServiceRefSockFD = (void *) wpurple_find_and_loadproc("dnssd.dll", "DNSServiceRefSockFD"))
+				&& (_DNSServiceRegister = (void *) wpurple_find_and_loadproc("dnssd.dll", "DNSServiceRegister"))
+				&& (_DNSServiceResolve = (void *) wpurple_find_and_loadproc("dnssd.dll", "DNSServiceResolve"))
+				&& (_DNSServiceRemoveRecord = (void *) wpurple_find_and_loadproc("dnssd.dll", "DNSServiceRemoveRecord"))
+				&& (_DNSServiceUpdateRecord = (void *) wpurple_find_and_loadproc("dnssd.dll", "DNSServiceUpdateRecord"))
+				&& (_TXTRecordCreate = (void *) wpurple_find_and_loadproc("dnssd.dll", "TXTRecordCreate"))
+				&& (_TXTRecordDeallocate = (void *) wpurple_find_and_loadproc("dnssd.dll", "TXTRecordDeallocate"))
+				&& (_TXTRecordGetBytesPtr = (void *) wpurple_find_and_loadproc("dnssd.dll", "TXTRecordGetBytesPtr"))
+				&& (_TXTRecordGetLength = (void *) wpurple_find_and_loadproc("dnssd.dll", "TXTRecordGetLength"))
+				&& (_TXTRecordGetValuePtr = (void *) wpurple_find_and_loadproc("dnssd.dll", "TXTRecordGetValuePtr"))
+				&& (_TXTRecordSetValue = (void *) wpurple_find_and_loadproc("dnssd.dll", "TXTRecordSetValue"))) {
+			loaded = TRUE;
+		}
+	}
+	return loaded;
+#else
+	return TRUE;
+#endif
+}
+
+#ifndef LINK_DNS_SD_DIRECTLY
+
+DNSServiceErrorType _wpurple_DNSServiceAddRecord(DNSServiceRef sdRef, DNSRecordRef *RecordRef, DNSServiceFlags flags,
+		uint16_t rrtype, uint16_t rdlen, const void *rdata, uint32_t ttl) {
+	g_return_val_if_fail(_DNSServiceAddRecord != NULL, kDNSServiceErr_Unknown);
+	return (_DNSServiceAddRecord)(sdRef, RecordRef, flags, rrtype, rdlen, rdata, ttl);
+}
+
+DNSServiceErrorType _wpurple_DNSServiceBrowse(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
+		const char *regtype, const char *domain, DNSServiceBrowseReply callBack, void *context) {
+	g_return_val_if_fail(_DNSServiceBrowse != NULL, kDNSServiceErr_Unknown);
+	return (_DNSServiceBrowse)(sdRef, flags, interfaceIndex, regtype, domain, callBack, context);
+}
+
+int _wpurple_DNSServiceConstructFullName(char *fullName, const char *service, const char *regtype, const char *domain) {
+	g_return_val_if_fail(_DNSServiceConstructFullName != NULL, 0);
+	return (_DNSServiceConstructFullName)(fullName, service, regtype, domain);
+}
+
+DNSServiceErrorType _wpurple_DNSServiceGetAddrInfo(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
+		DNSServiceProtocol protocol, const char *hostname, DNSServiceGetAddrInfoReply callBack, void *context) {
+	g_return_val_if_fail(_DNSServiceGetAddrInfo != NULL, 0);
+	return (_DNSServiceGetAddrInfo)(sdRef, flags, interfaceIndex, protocol, hostname, callBack, context);
+}
+
+DNSServiceErrorType _wpurple_DNSServiceProcessResult(DNSServiceRef sdRef) {
+	g_return_val_if_fail(_DNSServiceProcessResult != NULL, kDNSServiceErr_Unknown);
+	return (_DNSServiceProcessResult)(sdRef);
+}
+
+
+DNSServiceErrorType _wpurple_DNSServiceQueryRecord(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
+		const char *fullname, uint16_t rrtype, uint16_t rrclass, DNSServiceQueryRecordReply callBack, void *context) {
+	g_return_val_if_fail(_DNSServiceQueryRecord != NULL, kDNSServiceErr_Unknown);
+	return (_DNSServiceQueryRecord)(sdRef, flags, interfaceIndex, fullname, rrtype, rrclass, callBack, context);
+}
+
+void _wpurple_DNSServiceRefDeallocate(DNSServiceRef sdRef) {
+	g_return_if_fail(_DNSServiceRefDeallocate != NULL);
+	(_DNSServiceRefDeallocate)(sdRef);
+}
+
+int _wpurple_DNSServiceRefSockFD(DNSServiceRef sdRef) {
+	g_return_val_if_fail(_DNSServiceRefSockFD != NULL, -1);
+	return (_DNSServiceRefSockFD)(sdRef);
+}
+
+DNSServiceErrorType _wpurple_DNSServiceRegister(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
+		const char *name, const char *regtype, const char *domain, const char *host, uint16_t port, uint16_t txtLen,
+		const void *txtRecord, DNSServiceRegisterReply callBack, void *context) {
+	g_return_val_if_fail(_DNSServiceRegister != NULL, kDNSServiceErr_Unknown);
+	return (_DNSServiceRegister)(sdRef, flags, interfaceIndex, name, regtype, domain, host, port, txtLen, txtRecord, callBack, context);
+}
+
+DNSServiceErrorType _wpurple_DNSServiceResolve(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, const char *name,
+		const char *regtype, const char *domain, DNSServiceResolveReply callBack, void *context) {
+	g_return_val_if_fail(_DNSServiceResolve != NULL, kDNSServiceErr_Unknown);
+	return (_DNSServiceResolve)(sdRef, flags, interfaceIndex, name, regtype, domain, callBack, context);
+}
+
+DNSServiceErrorType _wpurple_DNSServiceRemoveRecord(DNSServiceRef sdRef, DNSRecordRef RecordRef, DNSServiceFlags flags) {
+	g_return_val_if_fail(_DNSServiceRemoveRecord != NULL, kDNSServiceErr_Unknown);
+	return (_DNSServiceRemoveRecord)(sdRef, RecordRef, flags);
+}
+
+DNSServiceErrorType _wpurple_DNSServiceUpdateRecord(DNSServiceRef sdRef, DNSRecordRef RecordRef, DNSServiceFlags flags,
+		uint16_t rdlen, const void *rdata, uint32_t ttl) {
+	g_return_val_if_fail(_DNSServiceUpdateRecord != NULL, kDNSServiceErr_Unknown);
+	return (_DNSServiceUpdateRecord)(sdRef, RecordRef, flags, rdlen, rdata, ttl);
+}
+
+void _wpurple_TXTRecordCreate(TXTRecordRef *txtRecord, uint16_t bufferLen, void *buffer) {
+	g_return_if_fail(_TXTRecordCreate != NULL);
+	(_TXTRecordCreate)(txtRecord, bufferLen, buffer);
+}
+
+void _wpurple_TXTRecordDeallocate(TXTRecordRef *txtRecord) {
+	g_return_if_fail(_TXTRecordDeallocate != NULL);
+	(_TXTRecordDeallocate)(txtRecord);
+}
+
+const void * _wpurple_TXTRecordGetBytesPtr(const TXTRecordRef *txtRecord) {
+	g_return_val_if_fail(_TXTRecordGetBytesPtr != NULL, NULL);
+	return (_TXTRecordGetBytesPtr)(txtRecord);
+}
+
+uint16_t _wpurple_TXTRecordGetLength(const TXTRecordRef *txtRecord) {
+	g_return_val_if_fail(_TXTRecordGetLength != NULL, 0);
+	return (_TXTRecordGetLength)(txtRecord);
+}
+
+const void * _wpurple_TXTRecordGetValuePtr(uint16_t txtLen, const void *txtRecord, const char *key, uint8_t *valueLen) {
+	g_return_val_if_fail(_TXTRecordGetValuePtr != NULL, NULL);
+	return (_TXTRecordGetValuePtr)(txtLen, txtRecord, key, valueLen);
+}
+
+DNSServiceErrorType _wpurple_TXTRecordSetValue(TXTRecordRef *txtRecord, const char *key, uint8_t valueSize, const void *value) {
+	g_return_val_if_fail(_TXTRecordSetValue != NULL, kDNSServiceErr_Unknown);
+	return (_TXTRecordSetValue)(txtRecord, key, valueSize, value);
+}
+
+#endif /*LINK_DNS_SD_DIRECTLY*/
+
--- a/libpurple/protocols/bonjour/dns_sd_proxy.h	Wed Sep 29 05:38:04 2010 +0000
+++ b/libpurple/protocols/bonjour/dns_sd_proxy.h	Sun Oct 10 05:25:42 2010 +0000
@@ -51,6 +51,11 @@
 #define DNSServiceConstructFullName(fullName, service, regtype, domain) \
 	_wpurple_DNSServiceConstructFullName(fullName, service, regtype, domain)
 
+DNSServiceErrorType _wpurple_DNSServiceGetAddrInfo(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
+	DNSServiceProtocol protocol, const char *hostname, DNSServiceGetAddrInfoReply callBack, void *context);
+#define DNSServiceGetAddrInfo(sdRef, flags, interfaceIndex, protocol, hostname, callBack, context) \
+	_wpurple_DNSServiceGetAddrInfo(sdRef, flags, interfaceIndex, protocol, hostname, callBack, context)
+
 DNSServiceErrorType _wpurple_DNSServiceProcessResult(DNSServiceRef sdRef);
 #define DNSServiceProcessResult(sdRef) \
 	_wpurple_DNSServiceProcessResult(sdRef);
--- a/libpurple/protocols/bonjour/jabber.c	Wed Sep 29 05:38:04 2010 +0000
+++ b/libpurple/protocols/bonjour/jabber.c	Sun Oct 10 05:25:42 2010 +0000
@@ -425,7 +425,7 @@
 			bonjour_jabber_close_conversation(bconv);
 			if (bconv->pb != NULL) {
 				BonjourBuddy *bb = purple_buddy_get_protocol_data(bconv->pb);
-				
+
 				if(bb != NULL)
 					bb->conversation = NULL;
 			}
@@ -534,7 +534,7 @@
 	if (bname == NULL)
 		bname = "";
 
-	stream_start = g_strdup_printf(DOCTYPE, purple_account_get_username(bconv->account), bname);
+	stream_start = g_strdup_printf(DOCTYPE, bonjour_get_jid(bconv->account), bname);
 	len = strlen(stream_start);
 
 	bconv->sent_stream_start = PARTIALLY_SENT;
@@ -774,6 +774,10 @@
 #ifdef PF_INET6
 	if (jdata->socket6 != -1) {
 		struct sockaddr_in6 addr6;
+#ifdef IPV6_V6ONLY
+		int on = 1;
+		setsockopt(jdata->socket6, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on));
+#endif
 	        memset(&addr6, 0, sizeof(addr6));
 		addr6.sin6_family = AF_INET6;
 		addr6.sin6_port = htons(jdata->port);
@@ -1044,7 +1048,7 @@
 
 	message_node = xmlnode_new("message");
 	xmlnode_set_attrib(message_node, "to", bb->name);
-	xmlnode_set_attrib(message_node, "from", purple_account_get_username(jdata->account));
+	xmlnode_set_attrib(message_node, "from", bonjour_get_jid(jdata->account));
 	xmlnode_set_attrib(message_node, "type", "chat");
 
 	/* Enclose the message from the UI within a "font" node */
@@ -1259,7 +1263,7 @@
 
 	for(l = acc->deny; l != NULL; l = l->next) {
 		const gchar *name = purple_buddy_get_name(pb);
-		const gchar *username = purple_account_get_username(acc);
+		const gchar *username = bonjour_get_jid(acc);
 
 		if(!purple_utf8_strcasecmp(name, (char *)l->data)) {
 			purple_debug_info("bonjour", "%s has been blocked by %s.\n", name, username);
--- a/libpurple/protocols/bonjour/mdns_avahi.c	Wed Sep 29 05:38:04 2010 +0000
+++ b/libpurple/protocols/bonjour/mdns_avahi.c	Sun Oct 10 05:25:42 2010 +0000
@@ -252,7 +252,7 @@
 			/* A new peer has joined the network and uses iChat bonjour */
 			purple_debug_info("bonjour", "_browser_callback - new service\n");
 			/* Make sure it isn't us */
-			if (purple_utf8_strcasecmp(name, account->username) != 0) {
+			if (purple_utf8_strcasecmp(name, bonjour_get_jid(account)) != 0) {
 				if (!avahi_service_resolver_new(avahi_service_browser_get_client(b),
 						interface, protocol, name, type, domain, protocol,
 						0, _resolver_callback, account)) {
@@ -421,6 +421,8 @@
 
 	data->mdns_impl_data = idata;
 
+	bonjour_dns_sd_set_jid(data->account, avahi_client_get_host_name(idata->client));
+
 	return TRUE;
 }
 
@@ -454,14 +456,14 @@
 			publish_result = avahi_entry_group_add_service_strlst(
 				idata->group, AVAHI_IF_UNSPEC,
 				AVAHI_PROTO_UNSPEC, 0,
-				purple_account_get_username(data->account),
+				bonjour_get_jid(data->account),
 				LINK_LOCAL_RECORD_NAME, NULL, NULL, data->port_p2pj, lst);
 			break;
 		case PUBLISH_UPDATE:
 			publish_result = avahi_entry_group_update_service_txt_strlst(
 				idata->group, AVAHI_IF_UNSPEC,
 				AVAHI_PROTO_UNSPEC, 0,
-				purple_account_get_username(data->account),
+				bonjour_get_jid(data->account),
 				LINK_LOCAL_RECORD_NAME, NULL, lst);
 			break;
 	}
@@ -535,7 +537,7 @@
 		}
 
 		svc_name = g_strdup_printf("%s." LINK_LOCAL_RECORD_NAME "local",
-				purple_account_get_username(data->account));
+				bonjour_get_jid(data->account));
 
 		ret = avahi_entry_group_add_record(idata->buddy_icon_group, AVAHI_IF_UNSPEC,
 			AVAHI_PROTO_UNSPEC, flags, svc_name,
--- a/libpurple/protocols/bonjour/mdns_common.c	Wed Sep 29 05:38:04 2010 +0000
+++ b/libpurple/protocols/bonjour/mdns_common.c	Sun Oct 10 05:25:42 2010 +0000
@@ -252,3 +252,36 @@
 void bonjour_dns_sd_stop(BonjourDnsSd *data) {
 	_mdns_stop(data);
 }
+
+void
+bonjour_dns_sd_set_jid(PurpleAccount *account, const char *hostname)
+{
+	PurpleConnection *conn = purple_account_get_connection(account);
+	BonjourData *bd = conn->proto_data;
+	const char *tmp, *account_name = purple_account_get_username(account);
+
+	/* Previously we allowed the hostname part of the jid to be set
+	 * explicitly when it should always be the current hostname.
+	 * That is what this is intended to deal with.
+	 */
+	if ((tmp = strchr(account_name, '@'))
+	    && strstr(tmp, hostname) == (tmp + 1)
+	    && *((tmp + 1) + strlen(hostname)) == '\0')
+		bd->jid = g_strdup(account_name);
+	else {
+		const char *tmp2;
+		GString *str = g_string_new("");
+		/* Escape an '@' in the account name */
+		tmp = account_name;
+		while ((tmp2 = strchr(tmp, '@')) != NULL) {
+			g_string_append_len(str, tmp, tmp2 - tmp);
+			g_string_append(str, "\\40");
+			tmp = tmp2 + 1;
+		}
+		g_string_append(str, tmp);
+		g_string_append_c(str, '@');
+		g_string_append(str, hostname);
+
+		bd->jid = g_string_free(str, FALSE);
+	}
+}
--- a/libpurple/protocols/bonjour/mdns_common.h	Wed Sep 29 05:38:04 2010 +0000
+++ b/libpurple/protocols/bonjour/mdns_common.h	Sun Oct 10 05:25:42 2010 +0000
@@ -57,4 +57,6 @@
  */
 void bonjour_dns_sd_stop(BonjourDnsSd *data);
 
+void bonjour_dns_sd_set_jid(PurpleAccount *account, const char *hostname);
+
 #endif
--- a/libpurple/protocols/bonjour/mdns_win32.c	Wed Sep 29 05:38:04 2010 +0000
+++ b/libpurple/protocols/bonjour/mdns_win32.c	Sun Oct 10 05:25:42 2010 +0000
@@ -25,8 +25,8 @@
 #include "buddy.h"
 #include "mdns_interface.h"
 #include "dns_sd_proxy.h"
-#include "dnsquery.h"
 #include "mdns_common.h"
+#include "bonjour.h"
 
 static GSList *pending_buddies = NULL;
 
@@ -65,7 +65,6 @@
 	BonjourBuddy *bb;
 	Win32SvcResolverData *res_data;
 	gchar *full_service_name;
-	PurpleDnsQueryData *dns_query;
 } ResolveCallbackArgs;
 
 
@@ -135,7 +134,7 @@
 {
 
 	if (errorCode != kDNSServiceErr_NoError) {
-		purple_debug_error("bonjour", "record query - callback error.\n");
+		purple_debug_error("bonjour", "record query - callback error (%d).\n", errorCode);
 		/* TODO: Probably should remove the buddy when this happens */
 	} else if (flags & kDNSServiceFlagsAdd) {
 		if (rrtype == kDNSServiceType_TXT) {
@@ -161,14 +160,22 @@
 	}
 }
 
-static void
-_mdns_resolve_host_callback(GSList *hosts, gpointer data, const char *error_message)
+static void DNSSD_API
+_mdns_resolve_host_callback(DNSServiceRef sdRef, DNSServiceFlags flags,
+	uint32_t interfaceIndex, DNSServiceErrorType errorCode,
+	const char *hostname, const struct sockaddr *address,
+	uint32_t ttl, void *context)
 {
-	ResolveCallbackArgs *args = (ResolveCallbackArgs*) data;
+	ResolveCallbackArgs *args = (ResolveCallbackArgs*) context;
 	Win32BuddyImplData *idata = args->bb->mdns_impl_data;
 	gboolean delete_buddy = FALSE;
 	PurpleBuddy *pb = NULL;
 
+	purple_input_remove(args->resolver_query->input_handler);
+	DNSServiceRefDeallocate(args->resolver_query->sdRef);
+	g_free(args->resolver_query);
+	args->resolver_query = NULL;
+
 	if ((pb = purple_find_buddy(args->account, args->res_data->name))) {
 		if (pb->proto_data != args->bb) {
 			purple_debug_error("bonjour", "Found purple buddy for %s not matching bonjour buddy record.",
@@ -181,12 +188,10 @@
 		goto cleanup;
 	}
 
-	if (!hosts || !hosts->data) {
-		purple_debug_error("bonjour", "host resolution - callback error.\n");
+	if (errorCode != kDNSServiceErr_NoError) {
+		purple_debug_error("bonjour", "host resolution - callback error (%d).\n", errorCode);
 		delete_buddy = TRUE;
 	} else {
-		struct sockaddr_in *addr = g_slist_nth_data(hosts, 1);
-		DNSServiceErrorType errorCode;
 		DNSServiceRef txt_query_sr;
 
 		/* finally, set up the continuous txt record watcher, and add the buddy to purple */
@@ -194,7 +199,7 @@
 				kDNSServiceInterfaceIndexAny, args->full_service_name, kDNSServiceType_TXT,
 				kDNSServiceClass_IN, _mdns_record_query_callback, args->bb);
 		if (errorCode == kDNSServiceErr_NoError) {
-			const char *ip = inet_ntoa(addr->sin_addr);
+			const char *ip = inet_ntoa(((struct sockaddr_in *) address)->sin_addr);
 
 			purple_debug_info("bonjour", "Found buddy %s at %s:%d\n", args->bb->name, ip, args->bb->port_p2pj);
 
@@ -218,13 +223,6 @@
 
 	cleanup:
 
-	/* free the hosts list*/
-	while (hosts != NULL) {
-		hosts = g_slist_remove(hosts, hosts->data);
-		g_free(hosts->data);
-		hosts = g_slist_remove(hosts, hosts->data);
-	}
-
 	if (delete_buddy) {
 		idata->resolvers = g_slist_remove(idata->resolvers, args->res_data);
 		_cleanup_resolver_data(args->res_data);
@@ -259,17 +257,20 @@
 	/* remove the input fd and destroy the service ref */
 	purple_input_remove(args->resolver_query->input_handler);
 	DNSServiceRefDeallocate(args->resolver_query->sdRef);
-	g_free(args->resolver_query);
-	args->resolver_query = NULL;
 
 	if (errorCode != kDNSServiceErr_NoError)
-		purple_debug_error("bonjour", "service resolver - callback error.\n");
+		purple_debug_error("bonjour", "service resolver - callback error. (%d)\n", errorCode);
 	else {
+		DNSServiceRef getaddrinfo_sr;
 		/* set more arguments, and start the host resolver */
-
-		if ((args->dns_query =
-				purple_dnsquery_a(hosttarget, port, _mdns_resolve_host_callback, args)) != NULL) {
-
+		errorCode = DNSServiceGetAddrInfo(&getaddrinfo_sr, 0, interfaceIndex,
+			kDNSServiceProtocol_IPv4, hosttarget, _mdns_resolve_host_callback, args);
+		if (errorCode != kDNSServiceErr_NoError)
+			purple_debug_error("bonjour", "service resolver - host resolution failed.\n");
+		else {
+			args->resolver_query->sdRef = getaddrinfo_sr;
+			args->resolver_query->input_handler = purple_input_add(DNSServiceRefSockFD(getaddrinfo_sr),
+				PURPLE_INPUT_READ, _mdns_handle_event, args->resolver_query);
 			args->full_service_name = g_strdup(fullname);
 
 			/* TODO: Should this be per resolver? */
@@ -277,12 +278,14 @@
 
 			/* We don't want to hit the cleanup code */
 			return;
-		} else
-			purple_debug_error("bonjour", "service resolver - host resolution failed.\n");
+		}
 	}
 
 	/* If we get this far, clean up */
 
+	g_free(args->resolver_query);
+	args->resolver_query = NULL;
+
 	idata->resolvers = g_slist_remove(idata->resolvers, args->res_data);
 	_cleanup_resolver_data(args->res_data);
 
@@ -324,7 +327,7 @@
 		purple_debug_error("bonjour", "service browser - callback error (%d)\n", errorCode);
 	else if (flags & kDNSServiceFlagsAdd) {
 		/* A presence service instance has been discovered... check it isn't us! */
-		if (purple_utf8_strcasecmp(serviceName, account->username) != 0) {
+		if (purple_utf8_strcasecmp(serviceName, bonjour_get_jid(account)) != 0) {
 			DNSServiceErrorType resErrorCode;
 			/* OK, lets go ahead and resolve it to add to the buddy list */
 			ResolveCallbackArgs *args = g_new0(ResolveCallbackArgs, 1);
@@ -334,7 +337,7 @@
 							  serviceName, interfaceIndex, regtype ? regtype : "",
 							  replyDomain ? replyDomain : "");
 
-			resErrorCode = DNSServiceResolve(&resolver_sr, 0, 0, serviceName, regtype,
+			resErrorCode = DNSServiceResolve(&resolver_sr, 0, interfaceIndex, serviceName, regtype,
 					replyDomain, _mdns_service_resolve_callback, args);
 			if (resErrorCode == kDNSServiceErr_NoError) {
 				GSList *tmp = pending_buddies;
@@ -452,6 +455,9 @@
 
 gboolean _mdns_init_session(BonjourDnsSd *data) {
 	data->mdns_impl_data = g_new0(Win32SessionImplData, 1);
+
+	bonjour_dns_sd_set_jid(data->account, purple_get_host_name());
+
 	return TRUE;
 }
 
@@ -483,7 +489,8 @@
 		switch (type) {
 			case PUBLISH_START:
 				purple_debug_info("bonjour", "Registering presence on port %d\n", data->port_p2pj);
-				errorCode = DNSServiceRegister(&presence_sr, 0, 0, purple_account_get_username(data->account), LINK_LOCAL_RECORD_NAME,
+				errorCode = DNSServiceRegister(&presence_sr, kDNSServiceInterfaceIndexAny,
+					0, bonjour_get_jid(data->account), LINK_LOCAL_RECORD_NAME,
 					NULL, NULL, htons(data->port_p2pj), TXTRecordGetLength(&dns_data), TXTRecordGetBytesPtr(&dns_data),
 					_mdns_service_register_callback, NULL);
 				break;
@@ -522,8 +529,9 @@
 
 	g_return_val_if_fail(idata != NULL, FALSE);
 
-	errorCode = DNSServiceBrowse(&browser_sr, 0, 0, LINK_LOCAL_RECORD_NAME, NULL,
-		_mdns_service_browse_callback, data->account);
+	errorCode = DNSServiceBrowse(&browser_sr, 0, kDNSServiceInterfaceIndexAny,
+			LINK_LOCAL_RECORD_NAME, NULL,_mdns_service_browse_callback,
+			data->account);
 	if (errorCode == kDNSServiceErr_NoError) {
 		idata->browser_query = g_new(DnsSDServiceRefHandlerData, 1);
 		idata->browser_query->sdRef = browser_sr;
--- a/libpurple/protocols/oscar/oft.c	Wed Sep 29 05:38:04 2010 +0000
+++ b/libpurple/protocols/oscar/oft.c	Sun Oct 10 05:25:42 2010 +0000
@@ -207,7 +207,7 @@
 	checksum_data->callback = callback;
 	checksum_data->size = size;
 	checksum_data->checksum = 0xffff0000;
-	checksum_data->file = fopen(purple_xfer_get_local_filename(xfer), "rb");
+	checksum_data->file = g_fopen(purple_xfer_get_local_filename(xfer), "rb");
 
 	if (checksum_data->file == NULL)
 	{
--- a/libpurple/protocols/qq/file_trans.c	Wed Sep 29 05:38:04 2010 +0000
+++ b/libpurple/protocols/qq/file_trans.c	Sun Oct 10 05:25:42 2010 +0000
@@ -84,7 +84,7 @@
 	if (filelen > QQ_MAX_FILE_MD5_LENGTH)
 		filelen = QQ_MAX_FILE_MD5_LENGTH;
 
-	fp = fopen(filename, "rb");
+	fp = g_fopen(filename, "rb");
 	g_return_if_fail(fp != NULL);
 
 	buffer = g_newa(guint8, filelen);
@@ -202,7 +202,7 @@
 static int _qq_xfer_open_file(const gchar *filename, const gchar *method, PurpleXfer *xfer)
 {
 	ft_info *info = xfer->data;
-	info->dest_fp = fopen(purple_xfer_get_local_filename(xfer), method);
+	info->dest_fp = g_fopen(purple_xfer_get_local_filename(xfer), method);
 	if (info->dest_fp == NULL) {
 		return -1;
 	}
--- a/libpurple/protocols/yahoo/libymsg.h	Wed Sep 29 05:38:04 2010 +0000
+++ b/libpurple/protocols/yahoo/libymsg.h	Sun Oct 10 05:25:42 2010 +0000
@@ -64,7 +64,7 @@
 
 #define WEBMESSENGER_URL "http://login.yahoo.com/config/login?.src=pg"
 
-#define YAHOO_SMS_CARRIER_URL "http://lookup.msg.vip.mud.yahoo.com"
+#define YAHOO_SMS_CARRIER_URL "http://validate.msg.yahoo.com"
 
 #define YAHOO_USERINFO_URL "http://address.yahoo.com/yab/us?v=XM&sync=1&tags=short&useutf8=1&noclear=1&legenc=codepage-1252"
 #define YAHOOJP_USERINFO_URL "http://address.yahoo.co.jp/yab/jp?v=XM&sync=1&tags=short&useutf8=1&noclear=1&legenc=codepage-1252"
--- a/po/de.po	Wed Sep 29 05:38:04 2010 +0000
+++ b/po/de.po	Sun Oct 10 05:25:42 2010 +0000
@@ -11,14 +11,14 @@
 msgstr ""
 "Project-Id-Version: de\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-09-02 19:45+0200\n"
-"PO-Revision-Date: 2010-09-06 10:01+0200\n"
-"Last-Translator: Björn Voigt <bjoern@cs.tu-berlin.de>\n"
-"Language-Team: Deutsch <de@li.org>\n"
+"POT-Creation-Date: 2010-10-04 20:42+0200\n"
+"PO-Revision-Date: 2010-10-04 20:42+0200\n"
+"Last-Translator: Jochen Kemnade <jochenkemnade@web.de>\n"
+"Language-Team: German <de@li.org>\n"
+"Language: de\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Language: de\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
 #. Translators may want to transliterate the name.
@@ -534,7 +534,6 @@
 msgid "Certificate Manager"
 msgstr "Zertifikat-Manager"
 
-#. Creating the user splits
 msgid "Hostname"
 msgstr "Rechnername"
 
@@ -1710,9 +1709,12 @@
 "Das Zertifikat ist nicht mehr gültig.  Überprüfen Sie, ob Datum und Zeit "
 "Ihres Computers stimmen."
 
-msgid "The certificate has expired and should not be considered valid."
-msgstr ""
-"Das Zertifikat ist abgelaufen und sollte nicht als gültig angesehen werden."
+msgid ""
+"The certificate has expired and should not be considered valid.  Check that "
+"your computer's date and time are accurate."
+msgstr ""
+"Das Zertifikat ist abgelaufen und sollte nicht mehr als gültig betrachtet "
+"werden.  Überprüfen Sie, ob Datum und Zeit Ihres Computers stimmen."
 
 #. Translators: "domain" refers to a DNS domain (e.g. talk.google.com)
 msgid "The certificate presented is not issued to this domain."
@@ -4723,9 +4725,9 @@
 "role &lt;moderator|participant|visitor|none&gt; [nick1] [nick2] ...: Get the "
 "users with a role or set users' role with the room."
 msgstr ""
-"role &lt;moderator|participant|visitor|none&gt; [Spitzname1] [Spitzname2] ...: "
-"Benutzer mit einer Rolle für den Raum erfragen oder Benutzern eine Rolle "
-"zuweisen."
+"role &lt;moderator|participant|visitor|none&gt; [Spitzname1] "
+"[Spitzname2] ...: Benutzer mit einer Rolle für den Raum erfragen oder "
+"Benutzern eine Rolle zuweisen."
 
 msgid "invite &lt;user&gt; [message]:  Invite a user to the room."
 msgstr ""
@@ -6807,8 +6809,8 @@
 #, c-format
 msgid "Unable to send message. Could not get details for user (%s)."
 msgstr ""
-"Kann die Nachricht nicht senden. Kann die Details vom Benutzer nicht holen (%"
-"s)."
+"Kann die Nachricht nicht senden. Kann die Details vom Benutzer nicht holen "
+"(%s)."
 
 #, c-format
 msgid "Unable to add %s to your buddy list (%s)."
@@ -6826,8 +6828,8 @@
 #, c-format
 msgid "Unable to send message to %s. Could not create the conference (%s)."
 msgstr ""
-"Kann die Nachricht nicht an %s senden. Kann die Konferenz nicht erstellen (%"
-"s)."
+"Kann die Nachricht nicht an %s senden. Kann die Konferenz nicht erstellen "
+"(%s)."
 
 #, c-format
 msgid "Unable to send message. Could not create the conference (%s)."
@@ -8311,8 +8313,8 @@
 #, c-format
 msgid "<b>Joining Qun %u is approved by admin %u for %s</b>"
 msgstr ""
-"<b>Das Betreten des Qun %u wurde vom Admin bestätigt wegen by admin %u for %"
-"s</b>"
+"<b>Das Betreten des Qun %u wurde vom Admin bestätigt wegen by admin %u for "
+"%s</b>"
 
 #, c-format
 msgid "<b>Removed buddy %u.</b>"
@@ -10932,29 +10934,24 @@
 msgstr " (%s)"
 
 #. 10053
-#, c-format
 msgid "Connection interrupted by other software on your computer."
 msgstr ""
 "Die Verbindung wurde von einer anderen Software auf Ihrem Computer "
 "unterbrochen."
 
 #. 10054
-#, c-format
 msgid "Remote host closed connection."
 msgstr "Der entfernte Host hat die Verbindung beendet."
 
 #. 10060
-#, c-format
 msgid "Connection timed out."
 msgstr "Verbindungsabbruch wegen Zeitüberschreitung."
 
 #. 10061
-#, c-format
 msgid "Connection refused."
 msgstr "Verbindung abgelehnt."
 
 #. 10048
-#, c-format
 msgid "Address already in use."
 msgstr "Adresse wird bereits benutzt."
 
@@ -12400,8 +12397,8 @@
 "to multiple messaging services at once.  %s is written in C using GTK+.  %s "
 "is released, and may be modified and redistributed,  under the terms of the "
 "GPL version 2 (or later).  A copy of the GPL is distributed with %s.  %s is "
-"copyrighted by its contributors, a list of whom is also distributed with %"
-"s.  There is no warranty for %s.<BR><BR>"
+"copyrighted by its contributors, a list of whom is also distributed with "
+"%s.  There is no warranty for %s.<BR><BR>"
 msgstr ""
 "%s ist ein Nachrichtendienst, basierend auf libpurple, der die Verbindung zu "
 "mehreren Nachrichtendiensten gleichzeitig unterstützt.  %s wird in C "
@@ -12973,16 +12970,16 @@
 
 #, c-format
 msgid ""
-"Are you sure you want to permanently delete the log of the conversation in %"
-"s which started at %s?"
+"Are you sure you want to permanently delete the log of the conversation in "
+"%s which started at %s?"
 msgstr ""
 "Wollen Sie wirklich den Mitschnitt der Unterhaltung in %s, gestartet am %s, "
 "permanent löschen?"
 
 #, c-format
 msgid ""
-"Are you sure you want to permanently delete the system log which started at %"
-"s?"
+"Are you sure you want to permanently delete the system log which started at "
+"%s?"
 msgstr ""
 "Wollen Sie wirklich den Systemmitschnitt, gestartet am %s, permanent löschen?"
 
@@ -13537,6 +13534,11 @@
 msgid "Konqueror"
 msgstr "Konqueror"
 
+msgid "Google Chrome"
+msgstr "Google Chrome"
+
+#. Do not move the line below.  Code below expects gnome-open to be in
+#. * this list immediately after xdg-open!
 msgid "Desktop Default"
 msgstr "Desktop-Standard"
 
@@ -13555,6 +13557,14 @@
 msgid "Epiphany"
 msgstr "Epiphany"
 
+#. Translators: please do not translate "chromium-browser" here!
+msgid "Chromium (chromium-browser)"
+msgstr "Chromium (chromium-browser)"
+
+#. Translators: please do not translate "chrome" here!
+msgid "Chromium (chrome)"
+msgstr "Chromium (chrome)"
+
 msgid "Manual"
 msgstr "Manuell"
 
@@ -15338,13 +15348,13 @@
 #, no-c-format
 msgid ""
 "Error Installing Spellchecking ($R3).$\\rIf retrying fails, manual "
-"installation instructions are at: http://developer.pidgin.im/wiki/Installing%"
-"20Pidgin#manual_win32_spellcheck_installation"
+"installation instructions are at: http://developer.pidgin.im/wiki/Installing"
+"%20Pidgin#manual_win32_spellcheck_installation"
 msgstr ""
 "Fehler beim Installieren der Rechtschreibkontrolle ($R3).$\\rFalls ein "
 "erneuter Versuch fehlschlägt, finden Sie Anweisungen zur manuellen "
-"Installation unter: http://developer.pidgin.im/wiki/Installing%"
-"20Pidgin#manual_win32_spellcheck_installation"
+"Installation unter: http://developer.pidgin.im/wiki/Installing"
+"%20Pidgin#manual_win32_spellcheck_installation"
 
 #. Installer Subsection Text
 msgid "GTK+ Runtime (required if not present)"