diff libpurple/protocols/bonjour/mdns_win32.c @ 18845:09f52521ff5b

Fix bonjour buddy icons to work with iChat.
author Daniel Atallah <daniel.atallah@gmail.com>
date Wed, 08 Aug 2007 18:14:46 +0000
parents 7bf6b9a70b41
children 44ad08a02ead
line wrap: on
line diff
--- a/libpurple/protocols/bonjour/mdns_win32.c	Wed Aug 08 01:50:01 2007 +0000
+++ b/libpurple/protocols/bonjour/mdns_win32.c	Wed Aug 08 18:14:46 2007 +0000
@@ -37,14 +37,12 @@
 
 /* data used by win32 bonjour implementation */
 typedef struct _win32_session_impl_data {
-	DNSServiceRef advertisement_svc;
+	DNSServiceRef presence_svc;
 	DNSServiceRef browser_svc;
-	DNSServiceRef buddy_icon_svc;
 	DNSRecordRef buddy_icon_rec;
 
-	guint advertisement_handler; /* hack... windows bonjour is broken, so we have to have this */
+	guint presence_handler; /* hack... windows bonjour is broken, so we have to have this */
 	guint browser_handler;
-	guint buddy_icon_handler;
 } Win32SessionImplData;
 
 typedef struct _win32_buddy_impl_data {
@@ -199,17 +197,6 @@
 }
 
 static void DNSSD_API
-_mdns_set_buddy_icon_cb(DNSServiceRef sdRef, DNSRecordRef RecordRef, DNSServiceFlags flags, DNSServiceErrorType errorCode,
-			void *context) {
-	if (kDNSServiceErr_NoError != errorCode)
-		purple_debug_error("bonjour", "Error (%d) registering buddy icon data.\n", errorCode);
-	else {
-		purple_debug_info("bonjour", "Registered buddy icon data.\n");
-		bonjour_dns_sd_buddy_icon_data_set((BonjourDnsSd *) context);
-	}
-}
-
-static void DNSSD_API
 _mdns_service_browse_callback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
     DNSServiceErrorType errorCode, const char *serviceName, const char *regtype, const char *replyDomain, void *context)
 {
@@ -321,14 +308,15 @@
 
 		switch (type) {
 			case PUBLISH_START:
-				purple_debug_info("bonjour", "Registering service on port %d\n", data->port_p2pj);
-				err = DNSServiceRegister(&idata->advertisement_svc, 0, 0, purple_account_get_username(data->account), ICHAT_SERVICE,
+				purple_debug_info("bonjour", "Registering presence on port %d\n", data->port_p2pj);
+				err = DNSServiceRegister(&idata->presence_svc, 0, 0, purple_account_get_username(data->account), ICHAT_SERVICE,
 					NULL, NULL, htons(data->port_p2pj), TXTRecordGetLength(&dns_data), TXTRecordGetBytesPtr(&dns_data),
 					_mdns_service_register_callback, NULL);
 				break;
 
 			case PUBLISH_UPDATE:
-				err = DNSServiceUpdateRecord(idata->advertisement_svc, NULL, 0, TXTRecordGetLength(&dns_data), TXTRecordGetBytesPtr(&dns_data), 0);
+				purple_debug_info("bonjour", "Updating presence.\n");
+				err = DNSServiceUpdateRecord(idata->presence_svc, NULL, 0, TXTRecordGetLength(&dns_data), TXTRecordGetBytesPtr(&dns_data), 0);
 				break;
 		}
 
@@ -337,8 +325,8 @@
 			ret = FALSE;
 		} else if (type == PUBLISH_START) {
 			/* hack: Bonjour on windows is broken. We don't care about the callback but we have to listen anyway */
-			idata->advertisement_handler = purple_input_add(DNSServiceRefSockFD(idata->advertisement_svc),
-				PURPLE_INPUT_READ, _mdns_handle_event, idata->advertisement_svc);
+			idata->presence_handler = purple_input_add(DNSServiceRefSockFD(idata->presence_svc),
+				PURPLE_INPUT_READ, _mdns_handle_event, idata->presence_svc);
 		}
 	}
 
@@ -369,10 +357,10 @@
 	if (idata == NULL)
 		return;
 
-	if (idata->advertisement_svc != NULL) {
+	if (idata->presence_svc != NULL) {
 		/* hack: for win32, we need to stop listening to the advertisement pipe too */
-		purple_input_remove(idata->advertisement_handler);
-		DNSServiceRefDeallocate(idata->advertisement_svc);
+		purple_input_remove(idata->presence_handler);
+		DNSServiceRefDeallocate(idata->presence_svc);
 	}
 
 	if (idata->browser_svc != NULL) {
@@ -380,68 +368,37 @@
 		DNSServiceRefDeallocate(idata->browser_svc);
 	}
 
-	if (idata->buddy_icon_svc != NULL) {
-		purple_input_remove(idata->buddy_icon_handler);
-		DNSServiceRefDeallocate(idata->buddy_icon_svc);
-	}
-
-
 	g_free(idata);
 
 	data->mdns_impl_data = NULL;
 }
 
-void _mdns_set_buddy_icon_data(BonjourDnsSd *data, gconstpointer avatar_data, gsize avatar_len) {
+gboolean _mdns_set_buddy_icon_data(BonjourDnsSd *data, gconstpointer avatar_data, gsize avatar_len) {
 	Win32SessionImplData *idata = data->mdns_impl_data;
-	gboolean new_svc = FALSE;
 	DNSServiceErrorType err = kDNSServiceErr_NoError;
 
-	g_return_if_fail(idata != NULL);
-
-	if (avatar_data != NULL && idata->buddy_icon_svc == NULL) {
-		gchar *svc_name = g_strdup_printf("%s." ICHAT_SERVICE "local", purple_account_get_username(data->account));
-
-		purple_debug_info("bonjour", "Setting new buddy icon.\n");
-
-		err = DNSServiceCreateConnection(&idata->buddy_icon_svc);
-		if (err == kDNSServiceErr_NoError) {
-			err = DNSServiceRegisterRecord(idata->buddy_icon_svc,
-				&idata->buddy_icon_rec, kDNSServiceFlagsShared, kDNSServiceInterfaceIndexAny, svc_name,
-				kDNSServiceType_NULL, kDNSServiceClass_IN,
-				avatar_len, avatar_data, 10, _mdns_set_buddy_icon_cb, data);
+	g_return_val_if_fail(idata != NULL, FALSE);
 
-			if (err != kDNSServiceErr_NoError) {
-				DNSServiceRefDeallocate(idata->buddy_icon_svc);
-				idata->buddy_icon_svc = NULL;
-			}
-		}
-
-		g_free(svc_name);
-
-		if (err == kDNSServiceErr_NoError)
-			idata->buddy_icon_handler = purple_input_add(DNSServiceRefSockFD(idata->buddy_icon_svc),
-				PURPLE_INPUT_READ, _mdns_handle_event, idata->buddy_icon_svc);
-
-		new_svc = TRUE;
+	if (avatar_data != NULL && idata->buddy_icon_rec == NULL) {
+		purple_debug_info("bonjour", "Setting new buddy icon.\n");
+		err = DNSServiceAddRecord(idata->presence_svc, &idata->buddy_icon_rec,
+			0, kDNSServiceType_NULL, avatar_len, avatar_data, 0);
 	} else if (avatar_data != NULL) {
 		purple_debug_info("bonjour", "Updating existing buddy icon.\n");
-		err = DNSServiceUpdateRecord(idata->buddy_icon_svc, idata->buddy_icon_rec,
-			0, avatar_len, avatar_data, 10);
-	} else if (idata->buddy_icon_svc != NULL) {
+		err = DNSServiceUpdateRecord(idata->presence_svc, idata->buddy_icon_rec,
+			0, avatar_len, avatar_data, 0);
+	} else if (idata->buddy_icon_rec != NULL) {
 		purple_debug_info("bonjour", "Removing existing buddy icon.\n");
-		/* Must be removing the buddy icon */
-		purple_input_remove(idata->buddy_icon_handler);
-		idata->buddy_icon_handler = 0;
-		DNSServiceRefDeallocate(idata->buddy_icon_svc);
-		idata->buddy_icon_svc = NULL;
+		DNSServiceRemoveRecord(idata->presence_svc, idata->buddy_icon_rec, 0);
 		idata->buddy_icon_rec = NULL;
 	}
 
 	if (err != kDNSServiceErr_NoError)
 		purple_debug_error("bonjour", "Error (%d) setting buddy icon record.\n", err);
+
+	return (err == kDNSServiceErr_NoError);
 }
 
-
 void _mdns_init_buddy(BonjourBuddy *buddy) {
 	buddy->mdns_impl_data = g_new0(Win32BuddyImplData, 1);
 }
@@ -466,9 +423,9 @@
 	buddy->mdns_impl_data = NULL;
 }
 
-void bonjour_dns_sd_retrieve_buddy_icon(BonjourBuddy* buddy) {
+void _mdns_retrieve_retrieve_buddy_icon(BonjourBuddy* buddy) {
 	Win32BuddyImplData *idata = buddy->mdns_impl_data;
-	gchar *svc_name;
+	char svc_name[kDNSServiceMaxDomainName];
 
 	g_return_if_fail(idata != NULL);
 
@@ -480,13 +437,12 @@
 		idata->null_query = NULL;
 	}
 
-	svc_name = g_strdup_printf("%s." ICHAT_SERVICE "local", buddy->name);
+	DNSServiceConstructFullName(svc_name, buddy->name, ICHAT_SERVICE, "local");
 	if (kDNSServiceErr_NoError == DNSServiceQueryRecord(&idata->null_query, 0, 0, svc_name,
 			kDNSServiceType_NULL, kDNSServiceClass_IN, _mdns_text_record_query_callback, buddy)) {
 		idata->null_query_handler = purple_input_add(DNSServiceRefSockFD(idata->null_query),
 			PURPLE_INPUT_READ, _mdns_handle_event, idata->null_query);
 	}
-	g_free(svc_name);
 
 }