changeset 31018:9c8b28dc6656

The hostname used for a bonjour account should always be the current machine name. This fixes our behavior so the previous statement is always the case. Unfortunately, this means that if the hostname was previously not the current machine name, the bonjour jid ends up looking like "username\40otherhost@hostname". Fixes #12674
author Daniel Atallah <daniel.atallah@gmail.com>
date Mon, 04 Oct 2010 00:48:25 +0000
parents 014a58e994da
children ab8d9cea5a30
files libpurple/protocols/bonjour/bonjour.c libpurple/protocols/bonjour/bonjour.h libpurple/protocols/bonjour/bonjour_ft.c libpurple/protocols/bonjour/jabber.c libpurple/protocols/bonjour/mdns_avahi.c libpurple/protocols/bonjour/mdns_common.c libpurple/protocols/bonjour/mdns_common.h libpurple/protocols/bonjour/mdns_win32.c
diffstat 8 files changed, 81 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/bonjour/bonjour.c	Mon Oct 04 00:35:26 2010 +0000
+++ b/libpurple/protocols/bonjour/bonjour.c	Mon Oct 04 00:48:25 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	Mon Oct 04 00:35:26 2010 +0000
+++ b/libpurple/protocols/bonjour/bonjour.h	Mon Oct 04 00:48:25 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	Mon Oct 04 00:35:26 2010 +0000
+++ b/libpurple/protocols/bonjour/bonjour_ft.c	Mon Oct 04 00:48:25 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/jabber.c	Mon Oct 04 00:35:26 2010 +0000
+++ b/libpurple/protocols/bonjour/jabber.c	Mon Oct 04 00:48:25 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;
@@ -1044,7 +1044,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 +1259,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	Mon Oct 04 00:35:26 2010 +0000
+++ b/libpurple/protocols/bonjour/mdns_avahi.c	Mon Oct 04 00:48:25 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	Mon Oct 04 00:35:26 2010 +0000
+++ b/libpurple/protocols/bonjour/mdns_common.c	Mon Oct 04 00:48:25 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(account_name, hostname) == ++tmp
+	    && *(tmp + 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);
+	}
+}
\ No newline at end of file
--- a/libpurple/protocols/bonjour/mdns_common.h	Mon Oct 04 00:35:26 2010 +0000
+++ b/libpurple/protocols/bonjour/mdns_common.h	Mon Oct 04 00:48:25 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	Mon Oct 04 00:35:26 2010 +0000
+++ b/libpurple/protocols/bonjour/mdns_win32.c	Mon Oct 04 00:48:25 2010 +0000
@@ -26,6 +26,7 @@
 #include "mdns_interface.h"
 #include "dns_sd_proxy.h"
 #include "mdns_common.h"
+#include "bonjour.h"
 
 static GSList *pending_buddies = NULL;
 
@@ -326,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);
@@ -454,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;
 }
 
@@ -486,7 +490,7 @@
 			case PUBLISH_START:
 				purple_debug_info("bonjour", "Registering presence on port %d\n", data->port_p2pj);
 				errorCode = DNSServiceRegister(&presence_sr, kDNSServiceInterfaceIndexAny,
-					0, purple_account_get_username(data->account), LINK_LOCAL_RECORD_NAME,
+					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;