changeset 18859:c1546f6c0432

Yay for code reuse.
author Daniel Atallah <daniel.atallah@gmail.com>
date Fri, 10 Aug 2007 01:29:48 +0000
parents f773aa054dca
children 0a8dc9eb4f8e
files libpurple/protocols/bonjour/mdns_avahi.c libpurple/protocols/bonjour/mdns_common.c libpurple/protocols/bonjour/mdns_howl.c libpurple/protocols/bonjour/mdns_interface.h libpurple/protocols/bonjour/mdns_win32.c
diffstat 5 files changed, 112 insertions(+), 152 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/bonjour/mdns_avahi.c	Thu Aug 09 22:49:53 2007 +0000
+++ b/libpurple/protocols/bonjour/mdns_avahi.c	Fri Aug 10 01:29:48 2007 +0000
@@ -267,10 +267,8 @@
 	return TRUE;
 }
 
-gboolean _mdns_publish(BonjourDnsSd *data, PublishType type) {
+gboolean _mdns_publish(BonjourDnsSd *data, PublishType type, GSList *records) {
 	int publish_result = 0;
-	char portstring[6];
-	const char *jid, *aim, *email;
 	AvahiSessionImplData *idata = data->mdns_impl_data;
 	AvahiStringList *lst = NULL;
 
@@ -287,44 +285,11 @@
 		}
 	}
 
-	/* Convert the port to a string */
-	snprintf(portstring, sizeof(portstring), "%d", data->port_p2pj);
-
-	jid = purple_account_get_string(data->account, "jid", NULL);
-	aim = purple_account_get_string(data->account, "AIM", NULL);
-	email = purple_account_get_string(data->account, "email", NULL);
-
-	/* We should try to follow XEP-0174, but some clients have "issues", so we humor them.
-	 * See http://telepathy.freedesktop.org/wiki/SalutInteroperability
-	 */
-
-	/* Needed by iChat */
-	lst = avahi_string_list_add_pair(lst,"txtvers", "1");
-	/* Needed by Gaim/Pidgin <= 2.0.1 (remove at some point) */
-	lst = avahi_string_list_add_pair(lst, "1st", data->first);
-	/* Needed by Gaim/Pidgin <= 2.0.1 (remove at some point) */
-	lst = avahi_string_list_add_pair(lst, "last", data->last);
-	/* Needed by Adium */
-	lst = avahi_string_list_add_pair(lst, "port.p2pj", portstring);
-	/* Needed by iChat, Gaim/Pidgin <= 2.0.1 */
-	lst = avahi_string_list_add_pair(lst, "status", data->status);
-	/* Currently always set to "!" since we don't support AV and wont ever be in a conference */
-	lst = avahi_string_list_add_pair(lst, "vc", data->vc);
-	lst = avahi_string_list_add_pair(lst, "ver", VERSION);
-	if (email != NULL && *email != '\0')
-		lst = avahi_string_list_add_pair(lst, "email", email);
-	if (jid != NULL && *jid != '\0')
-		lst = avahi_string_list_add_pair(lst, "jid", jid);
-	/* Nonstandard, but used by iChat */
-	if (aim != NULL && *aim != '\0')
-		lst = avahi_string_list_add_pair(lst, "AIM", aim);
-	if (data->msg != NULL && *data->msg != '\0')
-		lst = avahi_string_list_add_pair(lst, "msg", data->msg);
-	if (data->phsh != NULL && *data->phsh != '\0')
-		lst = avahi_string_list_add_pair(lst, "phsh", data->phsh);
-
-	/* TODO: ext, nick, node */
-
+	while (records) {
+		PurpleKeyValuePair *kvp = records->data;
+		lst = avahi_string_list_add_pair(lst, kvp->key, kvp->value);
+		records = records->next;
+	}
 
 	/* Publish the service */
 	switch (type) {
--- a/libpurple/protocols/bonjour/mdns_common.c	Thu Aug 09 22:49:53 2007 +0000
+++ b/libpurple/protocols/bonjour/mdns_common.c	Fri Aug 10 01:29:48 2007 +0000
@@ -29,20 +29,15 @@
 /**
  * Allocate space for the dns-sd data.
  */
-BonjourDnsSd *
-bonjour_dns_sd_new()
-{
+BonjourDnsSd * bonjour_dns_sd_new() {
 	BonjourDnsSd *data = g_new0(BonjourDnsSd, 1);
-
 	return data;
 }
 
 /**
  * Deallocate the space of the dns-sd data.
  */
-void
-bonjour_dns_sd_free(BonjourDnsSd *data)
-{
+void bonjour_dns_sd_free(BonjourDnsSd *data) {
 	g_free(data->first);
 	g_free(data->last);
 	g_free(data->phsh);
@@ -52,11 +47,90 @@
 	g_free(data);
 }
 
+static GSList *generate_presence_txt_records(BonjourDnsSd *data) {
+	GSList *ret = NULL;
+	PurpleKeyValuePair *kvp;
+	char portstring[6];
+	const char *jid, *aim, *email;
+
+	/* Convert the port to a string */
+	snprintf(portstring, sizeof(portstring), "%d", data->port_p2pj);
+
+	jid = purple_account_get_string(data->account, "jid", NULL);
+	aim = purple_account_get_string(data->account, "AIM", NULL);
+	email = purple_account_get_string(data->account, "email", NULL);
+
+#define _M_ADD_R(k, v) \
+	kvp = g_new0(PurpleKeyValuePair, 1); \
+	kvp->key = g_strdup(k); \
+	kvp->value = g_strdup(v); \
+	ret = g_slist_prepend(ret, kvp); \
+
+	/* We should try to follow XEP-0174, but some clients have "issues", so we humor them.
+	 * See http://telepathy.freedesktop.org/wiki/SalutInteroperability
+	 */
+
+	/* Needed by iChat */
+	_M_ADD_R("txtvers", "1")
+	/* Needed by Gaim/Pidgin <= 2.0.1 (remove at some point) */
+	_M_ADD_R("1st", data->first)
+	/* Needed by Gaim/Pidgin <= 2.0.1 (remove at some point) */
+	_M_ADD_R("last", data->last)
+	/* Needed by Adium */
+	_M_ADD_R("port.p2pj", portstring)
+	/* Needed by iChat, Gaim/Pidgin <= 2.0.1 */
+	_M_ADD_R("status", data->status)
+	_M_ADD_R("node", "libpurple")
+	_M_ADD_R("ver", VERSION)
+	/* Currently always set to "!" since we don't support AV and wont ever be in a conference */
+	_M_ADD_R("vc", data->vc)
+	if (email != NULL && *email != '\0') {
+		_M_ADD_R("email", email)
+	}
+	if (jid != NULL && *jid != '\0') {
+		_M_ADD_R("jid", jid)
+	}
+	/* Nonstandard, but used by iChat */
+	if (aim != NULL && *aim != '\0') {
+		_M_ADD_R("AIM", aim)
+	}
+	if (data->msg != NULL && *data->msg != '\0') {
+		_M_ADD_R("msg", data->msg)
+	}
+	if (data->phsh != NULL && *data->phsh != '\0') {
+		_M_ADD_R("phsh", data->phsh)
+	}
+
+	/* TODO: ext, nick */
+	return ret;
+}
+
+static void free_presence_txt_records(GSList *lst) {
+	PurpleKeyValuePair *kvp;
+	while(lst) {
+		kvp = lst->data;
+		g_free(kvp->key);
+		g_free(kvp->value);
+		g_free(kvp);
+		lst = g_slist_remove(lst, lst->data);
+	}
+}
+
+static gboolean publish_presence(BonjourDnsSd *data, PublishType type) {
+	GSList *txt_records;
+	gboolean ret;
+
+	txt_records = generate_presence_txt_records(data);
+	ret = _mdns_publish(data, type, txt_records);
+	free_presence_txt_records(txt_records);
+
+	return ret;
+}
+
 /**
  * Send a new dns-sd packet updating our status.
  */
-void
-bonjour_dns_sd_send_status(BonjourDnsSd *data, const char *status, const char *status_message) {
+void bonjour_dns_sd_send_status(BonjourDnsSd *data, const char *status, const char *status_message) {
 	g_free(data->status);
 	g_free(data->msg);
 
@@ -64,7 +138,7 @@
 	data->msg = g_strdup(status_message);
 
 	/* Update our text record with the new status */
-	_mdns_publish(data, PUBLISH_UPDATE); /* <--We must control the errors */
+	publish_presence(data, PUBLISH_UPDATE);
 }
 
 /**
@@ -74,8 +148,7 @@
 	_mdns_retrieve_buddy_icon(buddy);
 }
 
-void
-bonjour_dns_sd_update_buddy_icon(BonjourDnsSd *data) {
+void bonjour_dns_sd_update_buddy_icon(BonjourDnsSd *data) {
 	PurpleStoredImage *img;
 
 	if ((img = purple_buddy_icons_find_account_icon(data->account))) {
@@ -107,7 +180,7 @@
 			g_free(enc);
 
 			/* Update our TXT record */
-			_mdns_publish(data, PUBLISH_UPDATE);
+			publish_presence(data, PUBLISH_UPDATE);
 		}
 
 		purple_imgstore_unref(img);
@@ -120,7 +193,7 @@
 			g_free(data->phsh);
 			data->phsh = NULL;
 			/* Update our TXT record */
-			_mdns_publish(data, PUBLISH_UPDATE);
+			publish_presence(data, PUBLISH_UPDATE);
 		}
 	}
 }
@@ -129,19 +202,14 @@
  * Advertise our presence within the dns-sd daemon and start browsing
  * for other bonjour peers.
  */
-gboolean
-bonjour_dns_sd_start(BonjourDnsSd *data)
-{
-	PurpleConnection *gc;
-
-	gc = purple_account_get_connection(data->account);
+gboolean bonjour_dns_sd_start(BonjourDnsSd *data) {
 
 	/* Initialize the dns-sd data and session */
 	if (!_mdns_init_session(data))
 		return FALSE;
 
 	/* Publish our bonjour IM client at the mDNS daemon */
-	if (!_mdns_publish(data, PUBLISH_START))
+	if (!publish_presence(data, PUBLISH_START))
 		return FALSE;
 
 	/* Advise the daemon that we are waiting for connections */
@@ -157,7 +225,6 @@
  * Unregister the "_presence._tcp" service at the mDNS daemon.
  */
 
-void
-bonjour_dns_sd_stop(BonjourDnsSd *data) {
+void bonjour_dns_sd_stop(BonjourDnsSd *data) {
 	_mdns_stop(data);
 }
--- a/libpurple/protocols/bonjour/mdns_howl.c	Thu Aug 09 22:49:53 2007 +0000
+++ b/libpurple/protocols/bonjour/mdns_howl.c	Fri Aug 10 01:29:48 2007 +0000
@@ -194,11 +194,9 @@
 }
 
 
-gboolean _mdns_publish(BonjourDnsSd *data, PublishType type) {
+gboolean _mdns_publish(BonjourDnsSd *data, PublishType type, GSList *records) {
 	sw_text_record dns_data;
 	sw_result publish_result = SW_OKAY;
-	char portstring[6];
-	const char *jid, *aim, *email;
 	HowlSessionImplData *idata = data->mdns_impl_data;
 
 	g_return_val_if_fail(idata != NULL, FALSE);
@@ -209,43 +207,11 @@
 		return FALSE;
 	}
 
-	/* Convert the port to a string */
-	snprintf(portstring, sizeof(portstring), "%d", data->port_p2pj);
-
-	jid = purple_account_get_string(data->account, "jid", NULL);
-	aim = purple_account_get_string(data->account, "AIM", NULL);
-	email = purple_account_get_string(data->account, "email", NULL);
-
-	/* We should try to follow XEP-0174, but some clients have "issues", so we humor them.
-	 * See http://telepathy.freedesktop.org/wiki/SalutInteroperability
-	 */
-
-	/* Needed by iChat */
-	sw_text_record_add_key_and_string_value(dns_data, "txtvers", "1");
-	/* Needed by Gaim/Pidgin <= 2.0.1 (remove at some point) */
-	sw_text_record_add_key_and_string_value(dns_data, "1st", data->first);
-	/* Needed by Gaim/Pidgin <= 2.0.1 (remove at some point) */
-	sw_text_record_add_key_and_string_value(dns_data, "last", data->last);
-	/* Needed by Adium */
-	sw_text_record_add_key_and_string_value(dns_data, "port.p2pj", portstring);
-	/* Needed by iChat, Gaim/Pidgin <= 2.0.1 */
-	sw_text_record_add_key_and_string_value(dns_data, "status", data->status);
-	/* Currently always set to "!" since we don't support AV and wont ever be in a conference */
-	sw_text_record_add_key_and_string_value(dns_data, "vc", data->vc);
-	sw_text_record_add_key_and_string_value(dns_data, "ver", VERSION);
-	if (email != NULL && *email != '\0')
-		sw_text_record_add_key_and_string_value(dns_data, "email", email);
-	if (jid != NULL && *jid != '\0')
-		sw_text_record_add_key_and_string_value(dns_data, "jid", jid);
-	/* Nonstandard, but used by iChat */
-	if (aim != NULL && *aim != '\0')
-		sw_text_record_add_key_and_string_value(dns_data, "AIM", aim);
-	if (data->msg != NULL && *data->msg != '\0')
-		sw_text_record_add_key_and_string_value(dns_data, "msg", data->msg);
-	if (data->phsh != NULL && *data->phsh != '\0')
-		sw_text_record_add_key_and_string_value(dns_data, "phsh", data->phsh);
-
-	/* TODO: ext, nick, node */
+	while (records) {
+		PurpleKeyValuePair *kvp = records->data;
+		sw_text_record_add_key_and_string_value(dns_data, kvp->key, kvp->value);
+		records = records->next;
+	}
 
 	/* Publish the service */
 	switch (type) {
--- a/libpurple/protocols/bonjour/mdns_interface.h	Thu Aug 09 22:49:53 2007 +0000
+++ b/libpurple/protocols/bonjour/mdns_interface.h	Fri Aug 10 01:29:48 2007 +0000
@@ -22,7 +22,7 @@
 
 gboolean _mdns_init_session(BonjourDnsSd *data);
 
-gboolean _mdns_publish(BonjourDnsSd *data, PublishType type);
+gboolean _mdns_publish(BonjourDnsSd *data, PublishType type, GSList *records);
 
 gboolean _mdns_browse(BonjourDnsSd *data);
 
--- a/libpurple/protocols/bonjour/mdns_win32.c	Thu Aug 09 22:49:53 2007 +0000
+++ b/libpurple/protocols/bonjour/mdns_win32.c	Fri Aug 10 01:29:48 2007 +0000
@@ -243,61 +243,23 @@
 	return TRUE;
 }
 
-gboolean _mdns_publish(BonjourDnsSd *data, PublishType type) {
+gboolean _mdns_publish(BonjourDnsSd *data, PublishType type, GSList *records) {
 	TXTRecordRef dns_data;
-	char portstring[6];
 	gboolean ret = TRUE;
-	const char *jid, *aim, *email;
-	DNSServiceErrorType set_ret;
+	DNSServiceErrorType set_ret = kDNSServiceErr_NoError;
 	Win32SessionImplData *idata = data->mdns_impl_data;
 
 	g_return_val_if_fail(idata != NULL, FALSE);
 
 	TXTRecordCreate(&dns_data, 256, NULL);
 
-	/* Convert the port to a string */
-	snprintf(portstring, sizeof(portstring), "%d", data->port_p2pj);
-
-	jid = purple_account_get_string(data->account, "jid", NULL);
-	aim = purple_account_get_string(data->account, "AIM", NULL);
-	email = purple_account_get_string(data->account, "email", NULL);
-
-	/* We should try to follow XEP-0174, but some clients have "issues", so we humor them.
-	 * See http://telepathy.freedesktop.org/wiki/SalutInteroperability
-	 */
-
-	/* Needed by iChat */
-	set_ret = TXTRecordSetValue(&dns_data, "txtvers", 1, "1");
-	/* Needed by Gaim/Pidgin <= 2.0.1 (remove at some point) */
-	if (set_ret == kDNSServiceErr_NoError)
-		set_ret = TXTRecordSetValue(&dns_data, "1st", strlen(data->first), data->first);
-	/* Needed by Gaim/Pidgin <= 2.0.1 (remove at some point) */
-	if (set_ret == kDNSServiceErr_NoError)
-		set_ret = TXTRecordSetValue(&dns_data, "last", strlen(data->last), data->last);
-	/* Needed by Adium */
-	if (set_ret == kDNSServiceErr_NoError)
-		set_ret = TXTRecordSetValue(&dns_data, "port.p2pj", strlen(portstring), portstring);
-	/* Needed by iChat, Gaim/Pidgin <= 2.0.1 */
-	if (set_ret == kDNSServiceErr_NoError)
-		set_ret = TXTRecordSetValue(&dns_data, "status", strlen(data->status), data->status);
-	if (set_ret == kDNSServiceErr_NoError)
-		set_ret = TXTRecordSetValue(&dns_data, "ver", strlen(VERSION), VERSION);
-	/* Currently always set to "!" since we don't support AV and wont ever be in a conference */
-	if (set_ret == kDNSServiceErr_NoError)
-		set_ret = TXTRecordSetValue(&dns_data, "vc", strlen(data->vc), data->vc);
-	if (set_ret == kDNSServiceErr_NoError && email != NULL && *email != '\0')
-		set_ret = TXTRecordSetValue(&dns_data, "email", strlen(email), email);
-	if (set_ret == kDNSServiceErr_NoError && jid != NULL && *jid != '\0')
-		set_ret = TXTRecordSetValue(&dns_data, "jid", strlen(jid), jid);
-	/* Nonstandard, but used by iChat */
-	if (set_ret == kDNSServiceErr_NoError && aim != NULL && *aim != '\0')
-		set_ret = TXTRecordSetValue(&dns_data, "AIM", strlen(aim), aim);
-	if (set_ret == kDNSServiceErr_NoError && data->msg != NULL && *data->msg != '\0')
-		set_ret = TXTRecordSetValue(&dns_data, "msg", strlen(data->msg), data->msg);
-	if (set_ret == kDNSServiceErr_NoError && data->phsh != NULL && *data->phsh != '\0')
-		set_ret = TXTRecordSetValue(&dns_data, "phsh", strlen(data->phsh), data->phsh);
-
-	/* TODO: ext, nick, node */
+	while (records) {
+		PurpleKeyValuePair *kvp = records->data;
+		set_ret = TXTRecordSetValue(&dns_data, kvp->key, strlen(kvp->value), kvp->value);
+		if (set_ret != kDNSServiceErr_NoError)
+			break;
+		records = records->next;
+	}
 
 	if (set_ret != kDNSServiceErr_NoError) {
 		purple_debug_error("bonjour", "Unable to allocate memory for text record.\n");