Mercurial > pidgin
changeset 18798:ed1def07d86e
Refactor the bonjour mdns implementation abstraction in preparation for the avahi implementation. Also fix alias assignment from the server to populate the server alias instead of the local alias.
| author | Daniel Atallah <daniel.atallah@gmail.com> |
|---|---|
| date | Sun, 05 Aug 2007 02:44:53 +0000 |
| parents | 95fe5195bf98 |
| children | 83719d57a8ee |
| files | libpurple/protocols/bonjour/Makefile.am libpurple/protocols/bonjour/buddy.c libpurple/protocols/bonjour/buddy.h libpurple/protocols/bonjour/mdns_common.c libpurple/protocols/bonjour/mdns_common.h libpurple/protocols/bonjour/mdns_howl.c libpurple/protocols/bonjour/mdns_howl.h libpurple/protocols/bonjour/mdns_interface.h libpurple/protocols/bonjour/mdns_types.h libpurple/protocols/bonjour/mdns_win32.c libpurple/protocols/bonjour/mdns_win32.h |
| diffstat | 11 files changed, 305 insertions(+), 308 deletions(-) [+] |
line wrap: on
line diff
--- a/libpurple/protocols/bonjour/Makefile.am Fri Aug 03 23:20:28 2007 +0000 +++ b/libpurple/protocols/bonjour/Makefile.am Sun Aug 05 02:44:53 2007 +0000 @@ -1,6 +1,5 @@ EXTRA_DIST = \ mdns_win32.c \ - mdns_win32.h \ Makefile.mingw pkgdir = $(libdir)/purple-$(PURPLE_MAJOR_VERSION) @@ -16,7 +15,7 @@ mdns_common.c \ mdns_common.h \ mdns_howl.c \ - mdns_howl.h \ + mdns_interface.h \ mdns_types.h \ parser.c \ parser.h
--- a/libpurple/protocols/bonjour/buddy.c Fri Aug 03 23:20:28 2007 +0000 +++ b/libpurple/protocols/bonjour/buddy.c Sun Aug 05 02:44:53 2007 +0000 @@ -22,6 +22,7 @@ #include "account.h" #include "blist.h" #include "bonjour.h" +#include "mdns_interface.h" #include "debug.h" /** @@ -35,6 +36,8 @@ buddy->account = account; buddy->name = g_strdup(name); + _mdns_init_buddy(buddy); + return buddy; } @@ -102,8 +105,9 @@ { PurpleBuddy *buddy; PurpleGroup *group; - const char *status_id, *first, *last; - gchar *alias; + PurpleAccount *account = bonjour_buddy->account; + const char *status_id, *first, *last, *old_hash, *new_hash; + gchar *alias = NULL; /* Translate between the Bonjour status and the Purple status */ if (g_ascii_strcasecmp("dnd", bonjour_buddy->status) == 0) @@ -116,44 +120,42 @@ * field from the DNS SD. */ - /* Create the alias for the buddy using the first and the last name */ - first = bonjour_buddy->first; - last = bonjour_buddy->last; - alias = g_strdup_printf("%s%s%s", - (first && *first ? first : ""), - (first && *first && last && *last ? " " : ""), - (last && *last ? last : "")); - /* Make sure the Bonjour group exists in our buddy list */ group = purple_find_group(BONJOUR_GROUP_NAME); /* Use the buddy's domain, instead? */ - if (group == NULL) - { + if (group == NULL) { group = purple_group_new(BONJOUR_GROUP_NAME); purple_blist_add_group(group, NULL); } /* Make sure the buddy exists in our buddy list */ - buddy = purple_find_buddy(bonjour_buddy->account, bonjour_buddy->name); + buddy = purple_find_buddy(account, bonjour_buddy->name); - if (buddy == NULL) - { - buddy = purple_buddy_new(bonjour_buddy->account, bonjour_buddy->name, alias); + if (buddy == NULL) { + buddy = purple_buddy_new(account, bonjour_buddy->name, NULL); buddy->proto_data = bonjour_buddy; purple_blist_node_set_flags((PurpleBlistNode *)buddy, PURPLE_BLIST_NODE_FLAG_NO_SAVE); purple_blist_add_buddy(buddy, NULL, group, NULL); } + /* Create the alias for the buddy using the first and the last name */ + first = bonjour_buddy->first; + last = bonjour_buddy->last; + if ((first && *first) || (last && *last)) + alias = g_strdup_printf("%s%s%s", + (first && *first ? first : ""), + (first && *first && last && *last ? " " : ""), + (last && *last ? last : "")); + serv_got_alias(purple_account_get_connection(account), buddy->name, alias); + g_free(alias); + /* Set the user's status */ if (bonjour_buddy->msg != NULL) - purple_prpl_got_user_status(bonjour_buddy->account, buddy->name, status_id, - "message", bonjour_buddy->msg, - NULL); + purple_prpl_got_user_status(account, buddy->name, status_id, + "message", bonjour_buddy->msg, NULL); else - purple_prpl_got_user_status(bonjour_buddy->account, buddy->name, status_id, - NULL); - purple_prpl_got_user_idle(bonjour_buddy->account, buddy->name, FALSE, 0); + purple_prpl_got_user_status(account, buddy->name, status_id, NULL); - g_free(alias); + purple_prpl_got_user_idle(account, buddy->name, FALSE, 0); } /** @@ -182,13 +184,8 @@ bonjour_jabber_close_conversation(buddy->conversation); buddy->conversation = NULL; -#ifdef USE_BONJOUR_APPLE - if (buddy->txt_query != NULL) - { - purple_input_remove(buddy->txt_query_fd); - DNSServiceRefDeallocate(buddy->txt_query); - } -#endif + /* Clean up any mdns implementation data */ + _mdns_delete_buddy(buddy); g_free(buddy); }
--- a/libpurple/protocols/bonjour/buddy.h Fri Aug 03 23:20:28 2007 +0000 +++ b/libpurple/protocols/bonjour/buddy.h Sun Aug 05 02:44:53 2007 +0000 @@ -19,16 +19,9 @@ #include <glib.h> -#include "config.h" #include "account.h" #include "jabber.h" -#ifdef USE_BONJOUR_APPLE -#include "dns_sd_proxy.h" -#else /* USE_BONJOUR_HOWL */ -#include <howl.h> -#endif - typedef struct _BonjourBuddy { PurpleAccount *account; @@ -53,11 +46,7 @@ BonjourJabberConversation *conversation; -#ifdef USE_BONJOUR_APPLE - DNSServiceRef txt_query; - int txt_query_fd; -#endif - + gpointer mdns_impl_data; } BonjourBuddy; static const char *const buddy_TXT_records[] = {
--- a/libpurple/protocols/bonjour/mdns_common.c Fri Aug 03 23:20:28 2007 +0000 +++ b/libpurple/protocols/bonjour/mdns_common.c Sun Aug 05 02:44:53 2007 +0000 @@ -17,8 +17,8 @@ #include <string.h> #include "internal.h" -#include "config.h" #include "mdns_common.h" +#include "mdns_interface.h" #include "bonjour.h" #include "buddy.h" #include "debug.h" @@ -73,65 +73,28 @@ gboolean bonjour_dns_sd_start(BonjourDnsSd *data) { - PurpleAccount *account; PurpleConnection *gc; - gint dns_sd_socket; - gpointer opaque_data; -#ifdef USE_BONJOUR_HOWL - sw_discovery_oid session_id; -#endif - - account = data->account; - gc = purple_account_get_connection(account); + gc = purple_account_get_connection(data->account); /* Initialize the dns-sd data and session */ -#ifndef USE_BONJOUR_APPLE - if (sw_discovery_init(&data->session) != SW_OKAY) - { - purple_debug_error("bonjour", "Unable to initialize an mDNS session.\n"); - - /* In Avahi, sw_discovery_init frees data->session but doesn't clear it */ - data->session = NULL; - + if (!_mdns_init_session(data)) return FALSE; - } -#endif /* Publish our bonjour IM client at the mDNS daemon */ - - if (0 != _mdns_publish(data, PUBLISH_START)) - { + if (!_mdns_publish(data, PUBLISH_START)) return FALSE; - } /* Advise the daemon that we are waiting for connections */ - -#ifdef USE_BONJOUR_APPLE - if (DNSServiceBrowse(&data->browser, 0, 0, ICHAT_SERVICE, NULL, _mdns_service_browse_callback, account) - != kDNSServiceErr_NoError) -#else /* USE_BONJOUR_HOWL */ - if (sw_discovery_browse(data->session, 0, ICHAT_SERVICE, NULL, _browser_reply, - account, &session_id) != SW_OKAY) -#endif - { + if (!_mdns_browse(data)) { purple_debug_error("bonjour", "Unable to get service."); return FALSE; } + /* Get the socket that communicates with the mDNS daemon and bind it to a */ /* callback that will handle the dns_sd packets */ - -#ifdef USE_BONJOUR_APPLE - dns_sd_socket = DNSServiceRefSockFD(data->browser); - opaque_data = data->browser; -#else /* USE_BONJOUR_HOWL */ - dns_sd_socket = sw_discovery_socket(data->session); - opaque_data = data->session; -#endif - - gc->inpa = purple_input_add(dns_sd_socket, PURPLE_INPUT_READ, - _mdns_handle_event, opaque_data); + gc->inpa = _mdns_register_to_mainloop(data); return TRUE; } @@ -143,34 +106,10 @@ void bonjour_dns_sd_stop(BonjourDnsSd *data) { - PurpleAccount *account; PurpleConnection *gc; -#ifdef USE_BONJOUR_APPLE - if (data->advertisement == NULL || data->browser == NULL) -#else /* USE_BONJOUR_HOWL */ - if (data->session == NULL) -#endif - return; + _mdns_stop(data); -#ifdef USE_BONJOUR_HOWL - sw_discovery_cancel(data->session, data->session_id); -#endif - - account = data->account; - gc = purple_account_get_connection(account); + gc = purple_account_get_connection(data->account); purple_input_remove(gc->inpa); - -#ifdef USE_BONJOUR_APPLE - /* hack: for win32, we need to stop listening to the advertisement pipe too */ - purple_input_remove(data->advertisement_handler); - - DNSServiceRefDeallocate(data->advertisement); - DNSServiceRefDeallocate(data->browser); - data->advertisement = NULL; - data->browser = NULL; -#else /* USE_BONJOUR_HOWL */ - g_free(data->session); - data->session = NULL; -#endif }
--- a/libpurple/protocols/bonjour/mdns_common.h Fri Aug 03 23:20:28 2007 +0000 +++ b/libpurple/protocols/bonjour/mdns_common.h Sun Aug 05 02:44:53 2007 +0000 @@ -19,11 +19,7 @@ #include "mdns_types.h" -#ifdef USE_BONJOUR_APPLE -#include "mdns_win32.h" -#elif defined USE_BONJOUR_HOWL -#include "mdns_howl.h" -#endif +#include "buddy.h" /** * Allocate space for the dns-sd data.
--- a/libpurple/protocols/bonjour/mdns_howl.c Fri Aug 03 23:20:28 2007 +0000 +++ b/libpurple/protocols/bonjour/mdns_howl.c Sun Aug 05 02:44:53 2007 +0000 @@ -15,12 +15,20 @@ */ #include "internal.h" -#include "mdns_howl.h" +#include "mdns_interface.h" #include "debug.h" #include "buddy.h" -sw_result HOWL_API +#include <howl.h> + +/* data used by howl bonjour implementation */ +typedef struct _howl_impl_data { + sw_discovery session; + sw_discovery_oid session_id; +} HowlSessionImplData; + +static sw_result HOWL_API _publish_reply(sw_discovery discovery, sw_discovery_oid oid, sw_discovery_publish_status status, sw_opaque extra) { @@ -46,7 +54,7 @@ return SW_OKAY; } -sw_result HOWL_API +static sw_result HOWL_API _resolve_reply(sw_discovery discovery, sw_discovery_oid oid, sw_uint32 interface_index, sw_const_string name, sw_const_string type, sw_const_string domain, @@ -95,7 +103,7 @@ return SW_OKAY; } -sw_result HOWL_API +static sw_result HOWL_API _browser_reply(sw_discovery discovery, sw_discovery_oid oid, sw_discovery_browse_status status, sw_uint32 interface_index, sw_const_string name, @@ -154,19 +162,49 @@ return SW_OKAY; } -int -_mdns_publish(BonjourDnsSd *data, PublishType type) +static void +_mdns_handle_event(gpointer data, gint source, PurpleInputCondition condition) { + sw_discovery_read_socket((sw_discovery)data); +} + +/**************************** + * mdns_interface functions * + ****************************/ + +gboolean _mdns_init_session(BonjourDnsSd *data) { + HowlSessionImplData *idata = g_new0(HowlSessionImplData, 1); + + if (sw_discovery_init(&idata->session) != SW_OKAY) { + purple_debug_error("bonjour", "Unable to initialize an mDNS session.\n"); + + /* In Avahi, sw_discovery_init frees data->session but doesn't clear it */ + idata->session = NULL; + + g_free(idata); + + return FALSE; + } + + data->mdns_impl_data = idata; + + return TRUE; +} + + +gboolean _mdns_publish(BonjourDnsSd *data, PublishType type) { 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); /* Fill the data for the service */ - if (sw_text_record_init(&dns_data) != SW_OKAY) - { + if (sw_text_record_init(&dns_data) != SW_OKAY) { purple_debug_error("bonjour", "Unable to initialize the data for the mDNS.\n"); - return -1; + return FALSE; } /* Convert the port to a string */ @@ -208,32 +246,69 @@ /* TODO: ext, nick, node */ /* Publish the service */ - switch (type) - { + switch (type) { case PUBLISH_START: - publish_result = sw_discovery_publish(data->session, 0, purple_account_get_username(data->account), ICHAT_SERVICE, NULL, + publish_result = sw_discovery_publish(idata->session, 0, purple_account_get_username(data->account), ICHAT_SERVICE, NULL, NULL, data->port_p2pj, sw_text_record_bytes(dns_data), sw_text_record_len(dns_data), - _publish_reply, NULL, &data->session_id); + _publish_reply, NULL, &idata->session_id); break; case PUBLISH_UPDATE: - publish_result = sw_discovery_publish_update(data->session, data->session_id, + publish_result = sw_discovery_publish_update(idata->session, idata->session_id, sw_text_record_bytes(dns_data), sw_text_record_len(dns_data)); break; } - if (publish_result != SW_OKAY) - { + + if (publish_result != SW_OKAY) { purple_debug_error("bonjour", "Unable to publish or change the status of the _presence._tcp service.\n"); - return -1; + return FALSE; } /* Free the memory used by temp data */ sw_text_record_fina(dns_data); - return 0; + return TRUE; +} + +gboolean _mdns_browse(BonjourDnsSd *data) { + HowlSessionImplData *idata = data->mdns_impl_data; + + g_return_val_if_fail(idata != NULL, FALSE); + + /* TODO: don't we need to hang onto this to cancel later? */ + sw_discovery_oid session_id; + + return (sw_discovery_browse(idata->session, 0, ICHAT_SERVICE, NULL, _browser_reply, + data->account, &session_id) == SW_OKAY); } -void -_mdns_handle_event(gpointer data, gint source, PurpleInputCondition condition) -{ - sw_discovery_read_socket((sw_discovery)data); +guint _mdns_register_to_mainloop(BonjourDnsSd *data) { + HowlSessionImplData *idata = data->mdns_impl_data; + + g_return_val_if_fail(idata != NULL, FALSE); + + return purple_input_add(sw_discovery_socket(idata->session), + PURPLE_INPUT_READ, _mdns_handle_event, idata->session); } + +void _mdns_stop(BonjourDnsSd *data) { + HowlSessionImplData *idata = data->mdns_impl_data; + + if (idata == NULL || idata->session == NULL) + return; + + sw_discovery_cancel(idata->session, idata->session_id); + + /* TODO: should this really be g_free()'d ??? */ + g_free(idata->session); + + g_free(idata); + + data->mdns_impl_data = NULL; +} + +void _mdns_init_buddy(BonjourBuddy *buddy) { +} + +void _mdns_delete_buddy(BonjourBuddy *buddy) { +} +
--- a/libpurple/protocols/bonjour/mdns_howl.h Fri Aug 03 23:20:28 2007 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -/* - * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef _BONJOUR_MDNS_HOWL -#define _BONJOUR_MDNS_HOWL - -#include "config.h" - -#ifdef USE_BONJOUR_HOWL - -#include <howl.h> -#include <glib.h> -#include "mdns_types.h" - -/* callback functions */ - -sw_result HOWL_API _publish_reply(sw_discovery discovery, sw_discovery_oid oid, sw_discovery_publish_status status, sw_opaque extra); - -sw_result HOWL_API _resolve_reply(sw_discovery discovery, sw_discovery_oid oid, sw_uint32 interface_index, sw_const_string name, - sw_const_string type, sw_const_string domain, sw_ipv4_address address, sw_port port, sw_octets text_record, - sw_ulong text_record_len, sw_opaque extra); - -sw_result HOWL_API _browser_reply(sw_discovery discovery, sw_discovery_oid oid, sw_discovery_browse_status status, - sw_uint32 interface_index, sw_const_string name, sw_const_string type, sw_const_string domain, sw_opaque_t extra); - - -/* interface functions */ - -int _mdns_publish(BonjourDnsSd *data, PublishType type); -void _mdns_handle_event(gpointer data, gint source, PurpleInputCondition condition); - -#endif - -#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/protocols/bonjour/mdns_interface.h Sun Aug 05 02:44:53 2007 +0000 @@ -0,0 +1,39 @@ +/* + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _BONJOUR_MDNS_INTERFACE +#define _BONJOUR_MDNS_INTERFACE + +#include "mdns_types.h" + +gboolean _mdns_init_session(BonjourDnsSd *data); + +gboolean _mdns_publish(BonjourDnsSd *data, PublishType type); + +gboolean _mdns_browse(BonjourDnsSd *data); + +guint _mdns_register_to_mainloop(BonjourDnsSd *data); + +void _mdns_stop(BonjourDnsSd *data); + +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); + +#endif
--- a/libpurple/protocols/bonjour/mdns_types.h Fri Aug 03 23:20:28 2007 +0000 +++ b/libpurple/protocols/bonjour/mdns_types.h Sun Aug 05 02:44:53 2007 +0000 @@ -19,31 +19,14 @@ #include <glib.h> #include "account.h" -#include "config.h" - -#ifdef USE_BONJOUR_APPLE -#include "dns_sd_proxy.h" -#else /* USE_BONJOUR_HOWL */ -#include <howl.h> -#endif #define ICHAT_SERVICE "_presence._tcp." /** * Data to be used by the dns-sd connection. */ -typedef struct _BonjourDnsSd -{ -#ifdef USE_BONJOUR_APPLE - DNSServiceRef advertisement; - DNSServiceRef browser; - - int advertisement_handler; /* hack... windows bonjour is broken, so we have to have this */ -#else /* USE_BONJOUR_HOWL */ - sw_discovery session; - sw_discovery_oid session_id; -#endif - +typedef struct _BonjourDnsSd { + gpointer mdns_impl_data; PurpleAccount *account; gchar *first; gchar *last; @@ -59,5 +42,4 @@ PUBLISH_UPDATE } PublishType; - #endif
--- a/libpurple/protocols/bonjour/mdns_win32.c Fri Aug 03 23:20:28 2007 +0000 +++ b/libpurple/protocols/bonjour/mdns_win32.c Sun Aug 05 02:44:53 2007 +0000 @@ -15,15 +15,18 @@ */ #include "internal.h" -#include "mdns_win32.h" +#include "debug.h" -#include "debug.h" +#include "buddy.h" +#include "mdns_interface.h" +#include "dns_sd_proxy.h" +#include "dnsquery.h" + /* data structure for the resolve callback */ -typedef struct _ResolveCallbackArgs -{ +typedef struct _ResolveCallbackArgs { DNSServiceRef resolver; - int resolver_fd; + guint resolver_handler; PurpleDnsQueryData *query; gchar *fqn; @@ -31,6 +34,24 @@ BonjourBuddy* buddy; } ResolveCallbackArgs; +/* data used by win32 bonjour implementation */ +typedef struct _win32_session_impl_data { + DNSServiceRef advertisement; + DNSServiceRef browser; + + guint advertisement_handler; /* hack... windows bonjour is broken, so we have to have this */ +} Win32SessionImplData; + +typedef struct _win32_buddy_impl_data { + DNSServiceRef txt_query; + guint txt_query_handler; +} Win32BuddyImplData; + +static void +_mdns_handle_event(gpointer data, gint source, PurpleInputCondition condition) { + DNSServiceProcessResult((DNSServiceRef) data); +} + static void _mdns_parse_text_record(BonjourBuddy* buddy, const char* record, uint16_t record_len) { @@ -51,11 +72,13 @@ uint16_t rrtype, uint16_t rrclass, uint16_t rdlen, const void *rdata, uint32_t ttl, void *context) { + if (kDNSServiceErr_NoError != errorCode) - purple_debug_error("bonjour", "text record query - callback error.\n"); + purple_debug_error("bonjour", "record query - callback error.\n"); else if (flags & kDNSServiceFlagsAdd) { - BonjourBuddy *buddy = (BonjourBuddy*)context; + /* New Buddy */ + BonjourBuddy *buddy = (BonjourBuddy*) context; _mdns_parse_text_record(buddy, rdata, rdlen); bonjour_buddy_add_to_purple(buddy); } @@ -68,26 +91,26 @@ if (!hosts || !hosts->data) purple_debug_error("bonjour", "host resolution - callback error.\n"); - else - { + else { struct sockaddr_in *addr = (struct sockaddr_in*)g_slist_nth_data(hosts, 1); BonjourBuddy* buddy = args->buddy; + Win32BuddyImplData *idata = buddy->mdns_impl_data; + + g_return_if_fail(idata != NULL); buddy->ip = g_strdup(inet_ntoa(addr->sin_addr)); /* finally, set up the continuous txt record watcher, and add the buddy to purple */ - if (kDNSServiceErr_NoError == DNSServiceQueryRecord(&buddy->txt_query, 0, 0, args->fqn, - kDNSServiceType_TXT, kDNSServiceClass_IN, _mdns_text_record_query_callback, buddy)) - { - gint fd = DNSServiceRefSockFD(buddy->txt_query); - buddy->txt_query_fd = purple_input_add(fd, PURPLE_INPUT_READ, _mdns_handle_event, buddy->txt_query); + if (kDNSServiceErr_NoError == DNSServiceQueryRecord(&idata->txt_query, 0, 0, buddy->full_service_name, + kDNSServiceType_TXT, kDNSServiceClass_IN, _mdns_text_record_query_callback, buddy)) { + int fd = DNSServiceRefSockFD(idata->txt_query); + idata->txt_query_handler = purple_input_add(fd, PURPLE_INPUT_READ, _mdns_handle_event, idata->txt_query); bonjour_buddy_add_to_purple(buddy); purple_debug_info("bonjour", "Found buddy %s at %s:%d\n", buddy->name, buddy->ip, buddy->port_p2pj); - } - else + } else bonjour_buddy_delete(buddy); } @@ -108,7 +131,7 @@ ResolveCallbackArgs *args = (ResolveCallbackArgs*)context; /* remove the input fd and destroy the service ref */ - purple_input_remove(args->resolver_fd); + purple_input_remove(args->resolver_handler); DNSServiceRefDeallocate(args->resolver); if (kDNSServiceErr_NoError != errorCode) @@ -150,7 +173,7 @@ purple_debug_info("bonjour", "service advertisement - callback.\n"); } -void DNSSD_API +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) { @@ -159,50 +182,52 @@ if (kDNSServiceErr_NoError != errorCode) purple_debug_error("bonjour", "service browser - callback error"); - else if (flags & kDNSServiceFlagsAdd) - { + else if (flags & kDNSServiceFlagsAdd) { /* A presence service instance has been discovered... check it isn't us! */ - if (g_ascii_strcasecmp(serviceName, account->username) != 0) - { + if (g_ascii_strcasecmp(serviceName, account->username) != 0) { /* OK, lets go ahead and resolve it to add to the buddy list */ ResolveCallbackArgs *args = g_new0(ResolveCallbackArgs, 1); args->buddy = bonjour_buddy_new(serviceName, account); - if (kDNSServiceErr_NoError != DNSServiceResolve(&args->resolver, 0, 0, serviceName, regtype, replyDomain, _mdns_service_resolve_callback, args)) - { + if (kDNSServiceErr_NoError != DNSServiceResolve(&args->resolver, 0, 0, serviceName, regtype, replyDomain, _mdns_service_resolve_callback, args)) { bonjour_buddy_delete(args->buddy); g_free(args); purple_debug_error("bonjour", "service browser - failed to resolve service.\n"); - } - else - { + } else { /* get a file descriptor for this service ref, and add it to the input list */ - gint resolver_fd = DNSServiceRefSockFD(args->resolver); - args->resolver_fd = purple_input_add(resolver_fd, PURPLE_INPUT_READ, _mdns_handle_event, args->resolver); + gint fd = DNSServiceRefSockFD(args->resolver); + args->resolver_handler = purple_input_add(fd, PURPLE_INPUT_READ, _mdns_handle_event, args->resolver); } } - } - else - { + } else { /* A peer has sent a goodbye packet, remove them from the buddy list */ purple_debug_info("bonjour", "service browser - remove notification\n"); gb = purple_find_buddy(account, serviceName); - if (gb != NULL) - { + if (gb != NULL) { bonjour_buddy_delete(gb->proto_data); purple_blist_remove_buddy(gb); } } } -int -_mdns_publish(BonjourDnsSd *data, PublishType type) -{ +/**************************** + * mdns_interface functions * + ****************************/ + +gboolean _mdns_init_session(BonjourDnsSd *data) { + data->mdns_impl_data = g_new0(Win32SessionImplData, 1); + return TRUE; +} + +gboolean _mdns_publish(BonjourDnsSd *data, PublishType type) { TXTRecordRef dns_data; char portstring[6]; - int ret = 0; + gboolean ret = TRUE; const char *jid, *aim, *email; DNSServiceErrorType set_ret; + Win32SessionImplData *idata = data->mdns_impl_data; + + g_return_val_if_fail(idata != NULL, FALSE); TXTRecordCreate(&dns_data, 256, NULL); @@ -250,41 +275,34 @@ /* TODO: ext, nick, node */ - if (set_ret != kDNSServiceErr_NoError) - { + if (set_ret != kDNSServiceErr_NoError) { purple_debug_error("bonjour", "Unable to allocate memory for text record.\n"); - ret = -1; - } - else - { + ret = FALSE; + } else { DNSServiceErrorType err = kDNSServiceErr_NoError; /* OK, we're done constructing the text record, (re)publish the service */ - switch (type) - { + switch (type) { case PUBLISH_START: purple_debug_info("bonjour", "Registering service on port %d\n", data->port_p2pj); - err = DNSServiceRegister(&data->advertisement, 0, 0, purple_account_get_username(data->account), ICHAT_SERVICE, + err = DNSServiceRegister(&idata->advertisement, 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(data->advertisement, NULL, 0, TXTRecordGetLength(&dns_data), TXTRecordGetBytesPtr(&dns_data), 0); + err = DNSServiceUpdateRecord(idata->advertisement, NULL, 0, TXTRecordGetLength(&dns_data), TXTRecordGetBytesPtr(&dns_data), 0); break; } - if (kDNSServiceErr_NoError != err) - { + if (err != kDNSServiceErr_NoError) { purple_debug_error("bonjour", "Failed to publish presence service.\n"); - ret = -1; - } - else if (PUBLISH_START == type) - { + 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 */ - gint advertisement_fd = DNSServiceRefSockFD(data->advertisement); - data->advertisement_handler = purple_input_add(advertisement_fd, PURPLE_INPUT_READ, _mdns_handle_event, data->advertisement); + gint fd = DNSServiceRefSockFD(idata->advertisement); + idata->advertisement_handler = purple_input_add(fd, PURPLE_INPUT_READ, _mdns_handle_event, idata->advertisement); } } @@ -293,8 +311,58 @@ return ret; } -void -_mdns_handle_event(gpointer data, gint source, PurpleInputCondition condition) -{ - DNSServiceProcessResult((DNSServiceRef)data); +gboolean _mdns_browse(BonjourDnsSd *data) { + Win32SessionImplData *idata = data->mdns_impl_data; + + g_return_val_if_fail(idata != NULL, FALSE); + + return (DNSServiceBrowse(&idata->browser, 0, 0, ICHAT_SERVICE, NULL, + _mdns_service_browse_callback, data->account) + == kDNSServiceErr_NoError); +} + +guint _mdns_register_to_mainloop(BonjourDnsSd *data) { + Win32SessionImplData *idata = data->mdns_impl_data; + + g_return_val_if_fail(idata != NULL, FALSE); + + return purple_input_add(DNSServiceRefSockFD(idata->browser), + PURPLE_INPUT_READ, _mdns_handle_event, idata->browser); } + +void _mdns_stop(BonjourDnsSd *data) { + Win32SessionImplData *idata = data->mdns_impl_data; + + if (idata == NULL || idata->advertisement == NULL || idata->browser == NULL) + return; + + /* hack: for win32, we need to stop listening to the advertisement pipe too */ + purple_input_remove(idata->advertisement_handler); + + DNSServiceRefDeallocate(idata->advertisement); + DNSServiceRefDeallocate(idata->browser); + + g_free(idata); + + data->mdns_impl_data = NULL; +} + +void _mdns_init_buddy(BonjourBuddy *buddy) { + buddy->mdns_impl_data = g_new0(Win32BuddyImplData, 1); +} + +void _mdns_delete_buddy(BonjourBuddy *buddy) { + Win32BuddyImplData *idata = buddy->mdns_impl_data; + + g_return_if_fail(idata != NULL); + + if (idata->txt_query != NULL) { + purple_input_remove(idata->txt_query_handler); + DNSServiceRefDeallocate(idata->txt_query); + } + + g_free(idata); + + buddy->mdns_impl_data = NULL; +} +
--- a/libpurple/protocols/bonjour/mdns_win32.h Fri Aug 03 23:20:28 2007 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* - * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef _BONJOUR_MDNS_WIN32 -#define _BONJOUR_MDNS_WIN32 - -#ifdef USE_BONJOUR_APPLE - -#include <glib.h> -#include "mdns_types.h" -#include "buddy.h" -#include "dnsquery.h" -#include "dns_sd_proxy.h" - -/* Bonjour async callbacks */ - -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); - -/* interface functions */ - -int _mdns_publish(BonjourDnsSd *data, PublishType type); -void _mdns_handle_event(gpointer data, gint source, PurpleInputCondition condition); - -#endif - -#endif
