Index: configure.ac
===================================================================
--- configure.ac	(revision 7379)
+++ configure.ac	(working copy)
@@ -583,26 +583,38 @@
 esac
 
 if test x$with_zeroconf != xno; then
-	if test x$with_zeroconf = xauto; then
+	if test x$with_zeroconf = xavahi || test x$with_zeroconf = xauto; then
 		PKG_CHECK_MODULES([AVAHI], [avahi-client],
-	                  [with_zeroconf=avahi;AC_DEFINE([HAVE_AVAHI], 1, [Define to enable Avahi Zeroconf support])] MPD_LIBS="$MPD_LIBS $AVAHI_LIBS" MPD_CFLAGS="$MPD_CFLAGS $AVAHI_CFLAGS",
-	                  [with_zeroconf=auto])
+		                  [found_avahi=1;AC_DEFINE([HAVE_AVAHI], 1, [Define to enable Avahi Zeroconf support])]
+		                  MPD_LIBS="$MPD_LIBS $AVAHI_LIBS" MPD_CFLAGS="$MPD_CFLAGS $AVAHI_CFLAGS",
+		                  [found_avahi=0])
+	fi
+
+	if test x$found_avahi = x1; then
+		with_zeroconf=avahi
 	elif test x$with_zeroconf = xavahi; then
-		PKG_CHECK_MODULES([AVAHI], [avahi-client],
-	                  [with_zeroconf=avahi;AC_DEFINE([HAVE_AVAHI], 1, [Define to enable Avahi Zeroconf support])] MPD_LIBS="$MPD_LIBS $AVAHI_LIBS" MPD_CFLAGS="$MPD_CFLAGS $AVAHI_CFLAGS")
+		with_zeroconf=no
 	fi
 
-	# In the future, should add bonjour support (for OSX) and check at autodetect
-	# time
-	#if test x$with_zeroconf = xbonjour -o x$with_zeroconf = xauto; then
-	if test x$with_zeroconf = xbonjour; then
-		AC_MSG_WARN([Bonjour support has not been implemented yet, disabling Zeroconf])
+	if test x$with_zeroconf = xbonjour || test x$with_zeroconf = xauto; then
+		AC_CHECK_HEADER(dns_sd.h,
+		                [found_bonjour=1;AC_DEFINE([HAVE_BONJOUR], 1, [Define to enable Bonjour Zeroconf support])],
+		                [found_bonjour=0])
+		AC_CHECK_LIB(dns_sd, DNSServiceRegister,
+		             MPD_LIBS="$MPD_LIBS -ldns_sd")
+	fi
+
+	if test x$found_bonjour = x1; then
+		with_zeroconf=bonjour
+	elif test x$with_zeroconf = xbonjour; then
 		with_zeroconf=no
 	fi
 
-	if test x$with_zeroconf = xauto; then
+	if test x$with_zeroconf = xauto || test x$with_zeroconf = xno; then
 		AC_MSG_WARN([No supported Zeroconf backend found, disabling Zeroconf])
 		with_zeroconf=no
+	else
+		AC_DEFINE([HAVE_ZEROCONF], 1, [Define to enable Zeroconf support])
 	fi
 fi
 
Index: doc/mpdconf.example
===================================================================
--- doc/mpdconf.example	(revision 7379)
+++ doc/mpdconf.example	(working copy)
@@ -45,10 +45,18 @@
 #
 #log_level                       "default"
 #
-# If Zeroconf is configured, the service name to publish.  This
-# should be unique on your local network, but name collisions
-# will be taken care of for you.
+################################################################
+
+
+########################### ZEROCONF ###########################
 #
+# If yes, service information will be published with Zeroconf.
+#
+#zeroconf_enabled                "yes"
+#
+# The service name to publish.  This name should be unique on
+# your local network.
+#
 #zeroconf_name                   "Music Player"
 #
 ################################################################
Index: doc/mpd.conf.5
===================================================================
--- doc/mpd.conf.5	(revision 7379)
+++ doc/mpd.conf.5	(working copy)
@@ -71,10 +71,14 @@
 "verbose" records excessive amounts of information for debugging purposes.  The
 default is "default".
 .TP
+.B zeroconf_enabled <yes or no>
+If yes, and MPD has been compiled with support for Avahi or Bonjour, service
+information will be published with Zeroconf.  The default is yes.
+.TP
 .B zeroconf_name <name>
-If Zerconf is compiled into MPD, this is the service name to publish.  This
-should be unique to your local network, but name collisions will be properly
-dealt with.
+If Zeroconf is enabled, this is the service name to publish.  This name should
+be unique to your local network, but name collisions will be properly dealt
+with.  The default is "Music Player".
 .TP
 .B password <password@permissions>
 This specifies a password for access to mpd.  The format is
Index: src/conf.c
===================================================================
--- src/conf.c	(revision 7379)
+++ src/conf.c	(working copy)
@@ -145,6 +145,7 @@
 	registerConfigParam(CONF_PORT,                          0,     0);
 	registerConfigParam(CONF_LOG_LEVEL,                     0,     0);
 	registerConfigParam(CONF_ZEROCONF_NAME,                 0,     0);
+	registerConfigParam(CONF_ZEROCONF_ENABLED,              0,     0);
 	registerConfigParam(CONF_PASSWORD,                      1,     0);
 	registerConfigParam(CONF_DEFAULT_PERMS,                 0,     0);
 	registerConfigParam(CONF_AUDIO_OUTPUT,                  1,     1);
Index: src/zeroconf.c
===================================================================
--- src/zeroconf.c	(revision 7379)
+++ src/zeroconf.c	(working copy)
@@ -19,6 +19,7 @@
 #include <stdlib.h>
 #include <assert.h>
 #include <string.h>
+#include <arpa/inet.h>
 
 #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 <dns_sd.h>
+
+static DNSServiceRef dnsReference;
+#endif
+
 /* Here is the implementation for Avahi (http://avahi.org) Zeroconf support */
 #ifdef HAVE_AVAHI
 
@@ -55,10 +67,6 @@
 
 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 @@
 		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 @@
 	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
 }
Index: src/conf.h
===================================================================
--- src/conf.h	(revision 7379)
+++ src/conf.h	(working copy)
@@ -33,6 +33,7 @@
 #define CONF_PORT                       "port"
 #define CONF_LOG_LEVEL                  "log_level"
 #define CONF_ZEROCONF_NAME              "zeroconf_name"
+#define CONF_ZEROCONF_ENABLED			"zeroconf_enabled"
 #define CONF_PASSWORD                   "password"
 #define CONF_DEFAULT_PERMS              "default_permissions"
 #define CONF_AUDIO_OUTPUT               "audio_output"
Index: src/main.c
===================================================================
--- src/main.c	(revision 7379)
+++ src/main.c	(working copy)
@@ -429,7 +429,6 @@
 	initAudioDriver();
 	initVolume();
 	initInterfaces();
-	initZeroconf();
 	initReplayGainState();
 	initNormalization();
 	initInputStream();
@@ -438,10 +437,10 @@
 
 	setup_log_output(options.stdOutput);
 
-
-
 	initSigHandlers();
 
+	initZeroconf();
+
 	openVolumeDevice();
 	read_state_file();
 
