Mercurial > pidgin
diff libpurple/protocols/bonjour/mdns_common.c @ 17495:d7b50cac1c7a
This is a patch from Chris Davies to make Bonjour work on Windows using the Apple Bonjour framework. It turns out that the actual DNS-SD library is (3 clause) BSD licensed, so we can use it.
There are a few changes by me, mainly to fix the howl implementation.
Fixes #1117 .
There appear to be a few bugs, but I believe that they were also present previously. I'm hoping to do some more tweaking before the next release.
The howl implementation will eventually be supersceded by a native avahi implementation, so I opted for a somewhat dirty hack to enable it instead of doing something with config.h.
author | Daniel Atallah <daniel.atallah@gmail.com> |
---|---|
date | Tue, 05 Jun 2007 03:38:22 +0000 |
parents | |
children | c96b085ddf5c |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/protocols/bonjour/mdns_common.c Tue Jun 05 03:38:22 2007 +0000 @@ -0,0 +1,174 @@ +/* + * 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. + */ + +#include <string.h> + +#include "config.h" +#include "mdns_common.h" +#include "bonjour.h" +#include "buddy.h" +#include "debug.h" + + +/** + * Allocate space for the dns-sd data. + */ +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) +{ + g_free(data->first); + g_free(data->last); + g_free(data->email); + g_free(data); +} + +/** + * Send a new dns-sd packet updating our status. + */ +void +bonjour_dns_sd_send_status(BonjourDnsSd *data, const char *status, const char *status_message) +{ + g_free(data->status); + g_free(data->msg); + + data->status = g_strdup(status); + data->msg = g_strdup(status_message); + + /* Update our text record with the new status */ + _mdns_publish(data, PUBLISH_UPDATE); /* <--We must control the errors */ +} + +/** + * Advertise our presence within the dns-sd daemon and start browsing + * for other bonjour peers. + */ +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); + + /* 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; + + return FALSE; + } +#endif + + /* Publish our bonjour IM client at the mDNS daemon */ + + if (0 != _mdns_publish(data, PUBLISH_START)) + { + return FALSE; + } + + /* Advise the daemon that we are waiting for connections */ + +#ifdef USE_BONJOUR_APPLE + printf("account pointer here is %x\n,", account); + 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 + { + 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); + + return TRUE; +} + +/** + * Unregister the "_presence._tcp" service at the mDNS daemon. + */ + +void +bonjour_dns_sd_stop(BonjourDnsSd *data) +{ + PurpleAccount *account; + PurpleConnection *gc; + +#ifdef USE_BONJOUR_APPLE + if (NULL == data->advertisement || NULL == data->browser) +#else /* USE_BONJOUR_HOWL */ + if (data->session == NULL) +#endif + return; + +#ifdef USE_BONJOUR_HOWL + sw_discovery_cancel(data->session, data->session_id); +#endif + + account = data->account; + gc = purple_account_get_connection(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_fd); + + DNSServiceRefDeallocate(data->advertisement); + DNSServiceRefDeallocate(data->browser); + data->advertisement = NULL; + data->browser = NULL; +#else /* USE_BONJOUR_HOWL */ + g_free(data->session); + data->session = NULL; +#endif +}