# HG changeset patch # User Daniel Atallah # Date 1186596886 0 # Node ID 09f52521ff5b719c11b19009fc6403b3d7cf2e86 # Parent 7bf6b9a70b41485e4eabcdf08d6441d88089c228 Fix bonjour buddy icons to work with iChat. diff -r 7bf6b9a70b41 -r 09f52521ff5b libpurple/protocols/bonjour/issues.txt --- a/libpurple/protocols/bonjour/issues.txt Wed Aug 08 01:50:01 2007 +0000 +++ b/libpurple/protocols/bonjour/issues.txt Wed Aug 08 18:14:46 2007 +0000 @@ -3,6 +3,5 @@ ========================================== * Status changes don't work -* Avatars * File transfers * Typing notifications diff -r 7bf6b9a70b41 -r 09f52521ff5b libpurple/protocols/bonjour/mdns_avahi.c --- a/libpurple/protocols/bonjour/mdns_avahi.c Wed Aug 08 01:50:01 2007 +0000 +++ b/libpurple/protocols/bonjour/mdns_avahi.c Wed Aug 08 18:14:46 2007 +0000 @@ -317,10 +317,10 @@ return TRUE; } -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) { + return FALSE; } - void _mdns_stop(BonjourDnsSd *data) { AvahiSessionImplData *idata = data->mdns_impl_data; @@ -344,5 +344,5 @@ void _mdns_delete_buddy(BonjourBuddy *buddy) { } -void bonjour_dns_sd_retrieve_buddy_icon(BonjourBuddy* buddy) { +void _mdns_retrieve_retrieve_buddy_icon(BonjourBuddy* buddy) { } diff -r 7bf6b9a70b41 -r 09f52521ff5b libpurple/protocols/bonjour/mdns_common.c --- a/libpurple/protocols/bonjour/mdns_common.c Wed Aug 08 01:50:01 2007 +0000 +++ b/libpurple/protocols/bonjour/mdns_common.c Wed Aug 08 18:14:46 2007 +0000 @@ -67,40 +67,11 @@ _mdns_publish(data, PUBLISH_UPDATE); /* <--We must control the errors */ } -void -bonjour_dns_sd_buddy_icon_data_set(BonjourDnsSd *data) { - PurpleStoredImage *img = purple_buddy_icons_find_account_icon(data->account); - gconstpointer avatar_data; - gsize avatar_len; - gchar *enc; - int i; - unsigned char hashval[20]; - char *p, hash[41]; - - g_return_if_fail(img != NULL); - - avatar_data = purple_imgstore_get_data(img); - avatar_len = purple_imgstore_get_size(img); - - enc = purple_base64_encode(avatar_data, avatar_len); - - purple_cipher_digest_region("sha1", avatar_data, - avatar_len, sizeof(hashval), - hashval, NULL); - - purple_imgstore_unref(img); - - p = hash; - for(i=0; i<20; i++, p+=2) - snprintf(p, 3, "%02x", hashval[i]); - - g_free(data->phsh); - data->phsh = g_strdup(hash); - - g_free(enc); - - /* Update our TXT record */ - _mdns_publish(data, PUBLISH_UPDATE); +/** + * Retrieve the buddy icon blob + */ +void bonjour_dns_sd_retrieve_buddy_icon(BonjourBuddy* buddy) { + _mdns_retrieve_retrieve_buddy_icon(buddy); } void @@ -114,7 +85,30 @@ avatar_data = purple_imgstore_get_data(img); avatar_len = purple_imgstore_get_size(img); - _mdns_set_buddy_icon_data(data, avatar_data, avatar_len); + if (_mdns_set_buddy_icon_data(data, avatar_data, avatar_len)) { + int i; + gchar *enc; + char *p, hash[41]; + unsigned char hashval[20]; + + enc = purple_base64_encode(avatar_data, avatar_len); + + purple_cipher_digest_region("sha1", avatar_data, + avatar_len, sizeof(hashval), + hashval, NULL); + + p = hash; + for(i=0; i<20; i++, p+=2) + snprintf(p, 3, "%02x", hashval[i]); + + g_free(data->phsh); + data->phsh = g_strdup(hash); + + g_free(enc); + + /* Update our TXT record */ + _mdns_publish(data, PUBLISH_UPDATE); + } purple_imgstore_unref(img); } else { diff -r 7bf6b9a70b41 -r 09f52521ff5b libpurple/protocols/bonjour/mdns_common.h --- a/libpurple/protocols/bonjour/mdns_common.h Wed Aug 08 01:50:01 2007 +0000 +++ b/libpurple/protocols/bonjour/mdns_common.h Wed Aug 08 18:14:46 2007 +0000 @@ -47,11 +47,6 @@ void bonjour_dns_sd_update_buddy_icon(BonjourDnsSd *data); /** - * The buddy icon blob has been set, notify everyone watching the TXT record - */ -void bonjour_dns_sd_buddy_icon_data_set(BonjourDnsSd *data); - -/** * Advertise our presence within the dns-sd daemon and start * browsing for other bonjour peers. */ diff -r 7bf6b9a70b41 -r 09f52521ff5b libpurple/protocols/bonjour/mdns_howl.c --- a/libpurple/protocols/bonjour/mdns_howl.c Wed Aug 08 01:50:01 2007 +0000 +++ b/libpurple/protocols/bonjour/mdns_howl.c Wed Aug 08 18:14:46 2007 +0000 @@ -287,10 +287,10 @@ return FALSE; } -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) { + return FALSE; } - void _mdns_stop(BonjourDnsSd *data) { HowlSessionImplData *idata = data->mdns_impl_data; @@ -315,7 +315,7 @@ void _mdns_delete_buddy(BonjourBuddy *buddy) { } -void bonjour_dns_sd_retrieve_buddy_icon(BonjourBuddy* buddy) { +void _mdns_retrieve_retrieve_buddy_icon(BonjourBuddy* buddy) { } diff -r 7bf6b9a70b41 -r 09f52521ff5b libpurple/protocols/bonjour/mdns_interface.h --- a/libpurple/protocols/bonjour/mdns_interface.h Wed Aug 08 01:50:01 2007 +0000 +++ b/libpurple/protocols/bonjour/mdns_interface.h Wed Aug 08 18:14:46 2007 +0000 @@ -28,13 +28,12 @@ void _mdns_stop(BonjourDnsSd *data); -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); void _mdns_init_buddy(BonjourBuddy *buddy); void _mdns_delete_buddy(BonjourBuddy *buddy); -/* This doesn't quite belong here, but there really isn't any shared functionality */ -void bonjour_dns_sd_retrieve_buddy_icon(BonjourBuddy* buddy); +void _mdns_retrieve_retrieve_buddy_icon(BonjourBuddy* buddy); #endif diff -r 7bf6b9a70b41 -r 09f52521ff5b libpurple/protocols/bonjour/mdns_win32.c --- 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); }