From 2444f5d41a3ccefdf14f5336430ef46baf976626 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Mon, 16 Jun 2008 02:48:07 +0000 Subject: Backport Bonjour support from trunk Thanks to Qball, pat, and jat :) ------------------------------------------------------------------------ r6477 | jat | 2007-06-04 19:41:18 +0200 (Mo, 04 Jun 2007) | 4 lines Don't initialize zeroconf until after we've daemonized and log output has been redirected. This prevents zeroconf from blocking daemonization, and makes sure any errors get sent to the logs and not stdout. ------------------------------------------------------------------------ r6474 | jat | 2007-06-03 22:09:12 +0200 (So, 03 Jun 2007) | 3 lines Adding ChangeLog entry for zeroconf_enabled, adding Zeroconf section to mpdconf.example, and updating the zeroconf_* docs. ------------------------------------------------------------------------ r6471 | jat | 2007-06-03 21:44:19 +0200 (So, 03 Jun 2007) | 4 lines Define HAVE_ZEROCONF if Avahi or Bonjour support is enabled, so that we can silence a warning about an unused variable without using stupid checks for HAVE_AVAHI || HAVE_BONJOUR. ------------------------------------------------------------------------ r6467 | pat | 2007-06-03 20:08:51 +0200 (So, 03 Jun 2007) | 2 lines allow zeroconf to be disabled. ------------------------------------------------------------------------ r6464 | jat | 2007-06-03 02:03:20 +0200 (So, 03 Jun 2007) | 2 lines Cleaning up zeroconf configure magic. ------------------------------------------------------------------------ r6463 | jat | 2007-06-03 00:58:51 +0200 (So, 03 Jun 2007) | 2 lines Check if we need -ldns_sd for Bonjour. ------------------------------------------------------------------------ r6462 | jat | 2007-06-03 00:52:53 +0200 (So, 03 Jun 2007) | 2 lines Adding a missing include. ------------------------------------------------------------------------ r6453 | pat | 2007-06-02 19:06:08 +0200 (Sa, 02 Jun 2007) | 3 lines Added Bonjour zeroconf support. This works now natively on MacOS X. I couldn't test mDNSResponder support on Linux, as Debian doesn't include it - but should work as well. git-svn-id: https://svn.musicpd.org/mpd/branches/branch-0.13.0-fixes@7381 09075e82-0dd4-0310-85a5-a0d7c8717e4f --- src/zeroconf.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 118 insertions(+), 10 deletions(-) (limited to 'src/zeroconf.c') diff --git a/src/zeroconf.c b/src/zeroconf.c index 0b0163218..6ded363bf 100644 --- a/src/zeroconf.c +++ b/src/zeroconf.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "zeroconf.h" #include "conf.h" @@ -35,6 +36,17 @@ */ #define SERVICE_NAME "Music Player" +#ifdef HAVE_ZEROCONF +static struct ioOps zeroConfIo = { +}; +#endif + +#ifdef HAVE_BONJOUR +#include + +static DNSServiceRef dnsReference; +#endif + /* Here is the implementation for Avahi (http://avahi.org) Zeroconf support */ #ifdef HAVE_AVAHI @@ -55,10 +67,6 @@ static int avahiRunning; static int avahiFdset( fd_set* rfds, fd_set* wfds, fd_set* efds ); static int avahiFdconsume( int fdCount, fd_set* rfds, fd_set* wfds, fd_set* efds ); -static struct ioOps avahiIo = { - .fdset = avahiFdset, - .consume = avahiFdconsume, -}; /* Forward Declaration */ static void avahiRegisterService(AvahiClient *c); @@ -453,36 +461,127 @@ static void init_avahi(const char *serviceName) goto fail; } - avahiIo.fdset = avahiFdset; - avahiIo.consume = avahiFdconsume; - registerIO( &avahiIo ); + zeroConfIo.fdset = avahiFdset; + zeroConfIo.consume = avahiFdconsume; + registerIO( &zeroConfIo ); return; fail: finishZeroconf(); } -#else /* !HAVE_AVAHI */ -static void init_avahi(const char *serviceName) { } #endif /* HAVE_AVAHI */ +#ifdef HAVE_BONJOUR +static int dnsRegisterFdset(fd_set* rfds, fd_set* wfds, fd_set* efds) +{ + int fd; + + if (dnsReference == NULL) + return -1; + + fd = DNSServiceRefSockFD(dnsReference); + if (fd == -1) + return -1; + + FD_SET(fd, rfds); + + return fd; +} + +static int dnsRegisterFdconsume(int fdCount, fd_set* rfds, fd_set* wfds, + fd_set* efds) +{ + int fd; + + if (dnsReference == NULL) + return -1; + + fd = DNSServiceRefSockFD(dnsReference); + if (fd == -1) + return -1; + + if (FD_ISSET(fd, rfds)) { + FD_CLR(fd, rfds); + + DNSServiceProcessResult(dnsReference); + + return fdCount - 1; + } + + return fdCount; +} + +static void dnsRegisterCallback (DNSServiceRef sdRef, DNSServiceFlags flags, + DNSServiceErrorType errorCode, const char *name, + const char *regtype, const char *domain, void *context) +{ + if (errorCode != kDNSServiceErr_NoError) { + ERROR("Failed to register zeroconf service.\n"); + + DNSServiceRefDeallocate(dnsReference); + dnsReference = NULL; + deregisterIO( &zeroConfIo ); + } else { + DEBUG("Registered zeroconf service with name '%s'\n", name); + } +} + +static void init_zeroconf_osx(const char *serviceName) +{ + DNSServiceErrorType error = DNSServiceRegister(&dnsReference, + 0, 0, serviceName, SERVICE_TYPE, NULL, NULL, htons(getBoundPort()), 0, + NULL, dnsRegisterCallback, NULL); + + if (error != kDNSServiceErr_NoError) { + ERROR("Failed to register zeroconf service.\n"); + + if (dnsReference) { + DNSServiceRefDeallocate(dnsReference); + dnsReference = NULL; + } + return; + } + + zeroConfIo.fdset = dnsRegisterFdset; + zeroConfIo.consume = dnsRegisterFdconsume; + registerIO( &zeroConfIo ); +} +#endif + void initZeroconf(void) { const char* serviceName = SERVICE_NAME; ConfigParam *param; + int enabled = getBoolConfigParam(CONF_ZEROCONF_ENABLED); + + if (enabled != -1 && enabled != 1) + return; param = getConfigParam(CONF_ZEROCONF_NAME); if (param && strlen(param->value) > 0) serviceName = param->value; + +#ifdef HAVE_AVAHI init_avahi(serviceName); +#endif + +#ifdef HAVE_BONJOUR + init_zeroconf_osx(serviceName); +#endif } void finishZeroconf(void) { + int enabled = getBoolConfigParam(CONF_ZEROCONF_ENABLED); + + if (enabled != -1 && enabled != 1) + return; + #ifdef HAVE_AVAHI DEBUG( "Avahi: Shutting down interface\n" ); - deregisterIO( &avahiIo ); + deregisterIO( &zeroConfIo ); if( avahiGroup ) { avahi_entry_group_free( avahiGroup ); @@ -497,4 +596,13 @@ void finishZeroconf(void) avahi_free( avahiName ); avahiName = NULL; #endif /* HAVE_AVAHI */ + +#ifdef HAVE_BONJOUR + deregisterIO( &zeroConfIo ); + if (dnsReference != NULL) { + DNSServiceRefDeallocate(dnsReference); + dnsReference = NULL; + DEBUG("Deregistered Zeroconf service.\n"); + } +#endif } -- cgit v1.2.3