aboutsummaryrefslogtreecommitdiffstats
path: root/config/archive/freenas/diffs
diff options
context:
space:
mode:
Diffstat (limited to 'config/archive/freenas/diffs')
-rw-r--r--config/archive/freenas/diffs/netatalk-2.0.3-afpd-zeroconf.patch1386
1 files changed, 1386 insertions, 0 deletions
diff --git a/config/archive/freenas/diffs/netatalk-2.0.3-afpd-zeroconf.patch b/config/archive/freenas/diffs/netatalk-2.0.3-afpd-zeroconf.patch
new file mode 100644
index 00000000..74ee8795
--- /dev/null
+++ b/config/archive/freenas/diffs/netatalk-2.0.3-afpd-zeroconf.patch
@@ -0,0 +1,1386 @@
+? etc/afpd/afp_avahi.c
+? etc/afpd/afp_avahi.c.org
+? etc/afpd/afp_avahi.h
+? etc/afpd/afp_avahi.h.org
+? etc/afpd/afp_bonjour.c
+? etc/afpd/afp_bonjour.c.org
+? etc/afpd/afp_bonjour.h
+? etc/afpd/afp_bonjour.h.org
+? etc/afpd/afp_howl.c
+? etc/afpd/afp_howl.c.org
+? etc/afpd/afp_howl.h
+? etc/afpd/afp_howl.h.org
+? etc/afpd/afp_zeroconf.c
+? etc/afpd/afp_zeroconf.c.org
+? etc/afpd/afp_zeroconf.h
+? etc/afpd/afp_zeroconf.h.org
+? macros/zeroconf.m4
+? macros/zeroconf.m4.org
+Index: configure.in
+===================================================================
+RCS file: /cvsroot/netatalk/netatalk/configure.in,v
+retrieving revision 1.203
+diff -u -r1.203 configure.in
+--- configure.in 28 Apr 2005 20:49:17 -0000 1.203
++++ configure.in 5 May 2006 10:46:30 -0000
+@@ -398,6 +398,9 @@
+ dnl Check for optional server location protocol support (used by MacOS X)
+ NETATALK_SRVLOC
+
++dnl Check for optional Zeroconf support
++NETATALK_ZEROCONF
++
+ dnl Check for PAM libs
+ netatalk_cv_use_pam=no
+ AC_PATH_PAM([
+Index: config/afpd.conf.tmpl
+===================================================================
+RCS file: /cvsroot/netatalk/netatalk/config/afpd.conf.tmpl,v
+retrieving revision 1.16
+diff -u -r1.16 afpd.conf.tmpl
+--- config/afpd.conf.tmpl 28 Apr 2005 20:49:20 -0000 1.16
++++ config/afpd.conf.tmpl 5 May 2006 10:46:31 -0000
+@@ -51,6 +51,8 @@
+ # empty string.
+ # -noslp Don't register this server with the Service
+ # Location Protocol.
++# -nozeroconf Don't register this server with the Multicats
++# DNS Protocol.
+ #
+ #
+ # Authentication Methods:
+Index: contrib/a2boot/Makefile.am
+===================================================================
+RCS file: /cvsroot/netatalk/netatalk/contrib/a2boot/Makefile.am,v
+retrieving revision 1.5
+diff -u -r1.5 Makefile.am
+--- contrib/a2boot/Makefile.am 28 Apr 2005 20:49:21 -0000 1.5
++++ contrib/a2boot/Makefile.am 5 May 2006 10:46:32 -0000
+@@ -10,7 +10,7 @@
+ EXTRA_DIST = COPYRIGHT VERSION
+
+ CFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/sys \
+- @CFLAGS@ @SLP_CFLAGS@ \
++ @CFLAGS@ @SLP_CFLAGS@ @ZEROCONF_CFLAGS@ \
+ -D_PATH_A_GS_BLOCKS=\"$(PKGCONFDIR)/a2boot/ProDOS16\ Boot\ Blocks\" \
+ -D_PATH_A_2E_BLOCKS=\"$(PKGCONFDIR)/a2boot/Apple\ :2f:2fe\ Boot\ Blocks\" \
+ -D_PATH_P16_IMAGE=\"$(PKGCONFDIR)/a2boot/ProDOS16\ Image\"
+Index: etc/afpd/Makefile.am
+===================================================================
+RCS file: /cvsroot/netatalk/netatalk/etc/afpd/Makefile.am,v
+retrieving revision 1.38
+diff -u -r1.38 Makefile.am
+--- etc/afpd/Makefile.am 30 Apr 2005 21:33:41 -0000 1.38
++++ etc/afpd/Makefile.am 5 May 2006 10:46:33 -0000
+@@ -8,19 +8,21 @@
+ file.c enumerate.c desktop.c filedir.c fork.c appl.c gettok.c \
+ mangle.c status.c afp_options.c afp_asp.c afp_dsi.c messages.c \
+ afp_config.c nfsquota.c quota.c uam.c afs.c uid.c afp_util.c \
+- catsearch.c afprun.c
++ catsearch.c afprun.c \
++ afp_zeroconf.c afp_avahi.c afp_bonjour.c afp_howl.c
+
+ afpd_LDADD = $(top_builddir)/libatalk/cnid/libcnid.la $(top_builddir)/libatalk/libatalk.la
+ afpd_LDFLAGS = -export-dynamic
+
+ noinst_HEADERS = auth.h afp_config.h desktop.h directory.h file.h \
+ filedir.h fork.h globals.h icon.h mangle.h misc.h status.h switch.h \
+- uam_auth.h uid.h unix.h volume.h
++ uam_auth.h uid.h unix.h volume.h \
++ afp_zeroconf.h afp_avahi.h afp_bonjour.h afp_howl.h
+
+-LIBS = @LIBS@ @PAM_LIBS@ @QUOTA_LIBS@ @SLP_LIBS@ @WRAP_LIBS@
++LIBS = @LIBS@ @PAM_LIBS@ @QUOTA_LIBS@ @SLP_LIBS@ @ZEROCONF_LIBS@ @WRAP_LIBS@
+
+ CFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/sys \
+- @CFLAGS@ @SLP_CFLAGS@ \
++ @CFLAGS@ @SLP_CFLAGS@ @ZEROCONF_CFLAGS@ \
+ -D_PATH_AFPDDEFVOL=\"$(pkgconfdir)/AppleVolumes.default\" \
+ -D_PATH_AFPDSYSVOL=\"$(pkgconfdir)/AppleVolumes.system\" \
+ -D_PATH_AFPDPWFILE=\"$(pkgconfdir)/afppasswd\" \
+Index: etc/afpd/afp_config.c
+===================================================================
+RCS file: /cvsroot/netatalk/netatalk/etc/afpd/afp_config.c,v
+retrieving revision 1.23
+diff -u -r1.23 afp_config.c
+--- etc/afpd/afp_config.c 28 Apr 2005 20:49:39 -0000 1.23
++++ etc/afpd/afp_config.c 5 May 2006 10:46:35 -0000
+@@ -50,6 +50,9 @@
+ #ifdef USE_SRVLOC
+ #include <slp.h>
+ #endif /* USE_SRVLOC */
++#ifdef USE_ZEROCONF
++#include "afp_zeroconf.h"
++#endif /* USE_ZEROCONF */
+
+ #include "globals.h"
+ #include "afp_config.h"
+@@ -154,9 +157,9 @@
+ }
+ #endif /* USE_SRVLOC */
+
+-#ifdef USE_SRVLOC
+ static void dsi_cleanup(const AFPConfig *config)
+ {
++#ifdef USE_SRVLOC
+ SLPError err;
+ SLPError callbackerr;
+ SLPHandle hslp;
+@@ -189,8 +192,16 @@
+ srvloc_dereg_err:
+ dsi->srvloc_url[0] = '\0';
+ SLPClose(hslp);
+-}
++#elif defined (USE_ZEROCONF)
++ DSI *dsi = (DSI *)config->obj.handle;
++
++ /* Do nothing if we didn't register. */
++ if (!dsi || dsi->zeroconf_registered == 0)
++ return;
++
++ zeroconf_deregister();
+ #endif /* USE_SRVLOC */
++}
+
+ #ifndef NO_DDP
+ static void asp_cleanup(const AFPConfig *config)
+@@ -355,6 +366,10 @@
+ struct servent *afpovertcp;
+ int afp_port = 548;
+ char *srvloc_hostname, *hostname;
++#elif defined (USE_ZEROCONF)
++ struct servent *afpovertcp;
++ int afp_port = 548;
++ char *hostname = NULL;
+ #endif /* USE_SRVLOC */
+
+ if ((config = (AFPConfig *) calloc(1, sizeof(AFPConfig))) == NULL) {
+@@ -449,6 +464,36 @@
+ }
+ #endif /* USE_SRVLOC */
+
++#ifdef USE_ZEROCONF
++ dsi->zeroconf_registered = 0; /* Mark that we haven't registered. */
++
++ if (!(options->flags & OPTION_NOZEROCONF)) {
++ /* XXX We don't want to tack on the port number if we don't have to.
++ * Why?
++ * Well, this seems to break MacOS < 10. If the user _really_ wants to
++ * use a non-default port, they can, but be aware, this server might
++ * not show up int the Network Browser.
++ */
++ afpovertcp = getservbyname("afpovertcp", "tcp");
++ if (afpovertcp != NULL) {
++ afp_port = ntohs(afpovertcp->s_port);
++ }
++
++ /* If specified use the FQDN to register with srvloc, otherwise use IP. */
++ p = NULL;
++ if (options->fqdn) {
++ hostname = options->fqdn;
++ p = strchr(hostname, ':');
++ }
++ else
++ hostname = inet_ntoa(dsi->server.sin_addr);
++
++ if (!(options->flags & OPTION_NOSLP)) {
++ zeroconf_register(afp_port, hostname);
++ dsi->zeroconf_registered = 1; /* Mark that we have registered. */
++ }
++ }
++#endif /* USE_ZEROCONF */
+
+ config->fd = dsi->serversock;
+ config->obj.handle = dsi;
+@@ -469,6 +514,9 @@
+ #ifdef USE_SRVLOC
+ config->server_cleanup = dsi_cleanup;
+ #endif
++#ifdef USE_ZEROCONF
++ config->server_cleanup = dsi_cleanup;
++#endif
+ return config;
+ }
+
+Index: etc/afpd/afp_options.c
+===================================================================
+RCS file: /cvsroot/netatalk/netatalk/etc/afpd/afp_options.c,v
+retrieving revision 1.35
+diff -u -r1.35 afp_options.c
+--- etc/afpd/afp_options.c 28 Apr 2005 20:49:39 -0000 1.35
++++ etc/afpd/afp_options.c 5 May 2006 10:46:39 -0000
+@@ -202,10 +202,15 @@
+ /* parse toggles */
+ if (strstr(buf, " -nodebug"))
+ options->flags &= ~OPTION_DEBUG;
++
+ #ifdef USE_SRVLOC
+ if (strstr(buf, " -noslp"))
+ options->flags |= OPTION_NOSLP;
+ #endif /* USE_SRVLOC */
++#ifdef USE_ZEROCONF
++ if (strstr(buf, " -nozeroconf"))
++ options->flags |= OPTION_NOZEROCONF;
++#endif
+
+ if (strstr(buf, " -nouservolfirst"))
+ options->flags &= ~OPTION_USERVOLFIRST;
+@@ -578,6 +583,12 @@
+ puts( "No" );
+ #endif
+
++#ifdef USE_ZEROCONF
++ puts( "Yes" );
++#else
++ puts( "No" );
++#endif
++
+ printf( " TCP wrappers support:\t" );
+ #ifdef TCPWRAP
+ puts( "Yes" );
+Index: etc/afpd/globals.h
+===================================================================
+RCS file: /cvsroot/netatalk/netatalk/etc/afpd/globals.h,v
+retrieving revision 1.21
+diff -u -r1.21 globals.h
+--- etc/afpd/globals.h 28 Apr 2005 20:49:43 -0000 1.21
++++ etc/afpd/globals.h 5 May 2006 10:46:39 -0000
+@@ -40,6 +40,7 @@
+ #define OPTION_CUSTOMICON (1 << 4)
+ #define OPTION_NOSLP (1 << 5)
+ #define OPTION_ANNOUNCESSH (1 << 6)
++#define OPTION_NOZEROCONF (1 << 7)
+
+ #ifdef FORCE_UIDGID
+ /* set up a structure for this */
+Index: include/atalk/dsi.h
+===================================================================
+RCS file: /cvsroot/netatalk/netatalk/include/atalk/dsi.h,v
+retrieving revision 1.6
+diff -u -r1.6 dsi.h
+--- include/atalk/dsi.h 3 May 2005 14:55:12 -0000 1.6
++++ include/atalk/dsi.h 5 May 2006 10:46:41 -0000
+@@ -85,6 +85,10 @@
+ char srvloc_url[512];
+ #endif
+
++#ifdef USE_ZEROCONF
++ int zeroconf_registered;
++#endif
++
+ /* buffer for OSX deadlock */
+ int noblocking;
+ char *buffer;
+Index: macros/summary.m4
+===================================================================
+RCS file: /cvsroot/netatalk/netatalk/macros/summary.m4,v
+retrieving revision 1.2
+diff -u -r1.2 summary.m4
+--- macros/summary.m4 28 Apr 2005 20:50:05 -0000 1.2
++++ macros/summary.m4 5 May 2006 10:46:46 -0000
+@@ -44,6 +44,7 @@
+ AC_MSG_RESULT([ Options:])
+ AC_MSG_RESULT([ CUPS support: $netatalk_cv_use_cups])
+ AC_MSG_RESULT([ SLP support: $netatalk_cv_srvloc])
++ AC_MSG_RESULT([ Zeroconf support: $netatalk_cv_zeroconf])
+ AC_MSG_RESULT([ tcp wrapper support: $netatalk_cv_tcpwrap])
+ dnl if test x"$netatalk_cv_linux_sendfile" != x; then
+ dnl AC_MSG_RESULT([ Linux sendfile support: $netatalk_cv_linux_sendfile])
+Index: man/man5/afpd.conf.5.tmpl
+===================================================================
+RCS file: /cvsroot/netatalk/netatalk/man/man5/afpd.conf.5.tmpl,v
+retrieving revision 1.4
+diff -u -r1.4 afpd.conf.5.tmpl
+--- man/man5/afpd.conf.5.tmpl 28 Apr 2005 20:50:06 -0000 1.4
++++ man/man5/afpd.conf.5.tmpl 5 May 2006 10:46:48 -0000
+@@ -210,6 +210,9 @@
+ Protocol (if SLP support was compiled in). This is useful if you are
+ running multiple servers and want one to be hidden, perhaps because
+ it is advertised elsewhere, ie. by a SLP Directory Agent.
++\-noslp
++Do not register this server using the Multicast DNS
++Protocol (if Zeroconf support was compiled in).
+ .SH "MISCELLANEOUS OPTIONS"
+ .TP
+ \-admingroup \fI[group]\fR
+--- etc/afpd/afp_avahi.c.org 2006-04-21 10:29:22.000000000 +0200
++++ etc/afpd/afp_avahi.c 2006-04-22 08:34:34.000000000 +0200
+@@ -0,0 +1,500 @@
++/* -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2 -*- */
++/*
++ * Author: Daniel S. Haischt <me@daniel.stefan.haischt.name>
++ * Purpose: Avahi based Zeroconf support
++ * Docs: http://avahi.org/download/doxygen/
++ *
++ */
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#ifdef HAVE_AVAHI
++
++#include "afp_avahi.h"
++
++static void publish_reply(AvahiEntryGroup *g,
++ AvahiEntryGroupState state,
++ void *userdata);
++
++/*
++ * This function tries to register the AFP DNS
++ * SRV service type.
++ */
++static void register_stuff(struct context *ctx) {
++ char r[128];
++ int ret;
++
++ assert(ctx->client);
++
++ if (!ctx->group) {
++
++ if (!(ctx->group = avahi_entry_group_new(ctx->client,
++ publish_reply,
++ ctx))) {
++ LOG(log_error,
++ logtype_afpd,
++ "Failed to create entry group: %s\n",
++ avahi_strerror(avahi_client_errno(ctx->client)));
++ goto fail;
++ }
++
++ }
++
++ LOG(log_info, logtype_afpd, "Adding service '%s'\n", ctx->name);
++
++ if (avahi_entry_group_is_empty(ctx->group)) {
++ /* Register our service */
++
++ if (avahi_entry_group_add_service(ctx->group,
++ AVAHI_IF_UNSPEC,
++ AVAHI_PROTO_UNSPEC,
++ 0,
++ ctx->name,
++ AFP_DNS_SERVICE_TYPE,
++ NULL,
++ NULL,
++ ctx->port,
++ NULL) < 0) {
++ LOG(log_error,
++ logtype_afpd,
++ "Failed to add service: %s\n",
++ avahi_strerror(avahi_client_errno(ctx->client)));
++ goto fail;
++ }
++
++ if (avahi_entry_group_commit(ctx->group) < 0) {
++ LOG(log_error,
++ logtype_afpd,
++ "Failed to commit entry group: %s\n",
++ avahi_strerror(avahi_client_errno(ctx->client)));
++ goto fail;
++ }
++ }
++
++ return;
++
++ fail:
++ avahi_client_free (ctx->client);
++#ifndef HAVE_AVAHI_THREADED_POLL
++ avahi_simple_poll_quit(ctx->simple_poll);
++#else
++ avahi_threaded_poll_quit(ctx->threaded_poll);
++#endif
++}
++
++/* Called when publishing of service data completes */
++static void publish_reply(AvahiEntryGroup *g,
++ AvahiEntryGroupState state,
++ AVAHI_GCC_UNUSED void *userdata)
++{
++ struct context *ctx = userdata;
++
++ assert(g == ctx->group);
++
++ switch (state) {
++
++ case AVAHI_ENTRY_GROUP_ESTABLISHED :
++ /* The entry group has been established successfully */
++ break;
++
++ case AVAHI_ENTRY_GROUP_COLLISION: {
++ char *n;
++
++ /* Pick a new name for our service */
++
++ n = avahi_alternative_service_name(ctx->name);
++ assert(n);
++
++ avahi_free(ctx->name);
++ ctx->name = n;
++
++ register_stuff(ctx);
++ break;
++ }
++
++ case AVAHI_ENTRY_GROUP_FAILURE: {
++ LOG(log_error,
++ logtype_afpd,
++ "Failed to register service: %s\n",
++ avahi_strerror(avahi_client_errno(ctx->client)));
++ avahi_client_free (avahi_entry_group_get_client(g));
++#ifndef HAVE_AVAHI_THREADED_POLL
++ avahi_simple_poll_quit(ctx->simple_poll);
++#else
++ avahi_threaded_poll_quit(ctx->threaded_poll);
++#endif
++ break;
++ }
++
++ case AVAHI_ENTRY_GROUP_UNCOMMITED:
++ case AVAHI_ENTRY_GROUP_REGISTERING:
++ ;
++ }
++}
++
++static void client_callback(AvahiClient *client,
++ AvahiClientState state,
++ void *userdata)
++{
++ struct context *ctx = userdata;
++
++ ctx->client = client;
++
++ switch (state) {
++
++ case AVAHI_CLIENT_S_RUNNING:
++
++ /* The server has startup successfully and registered its host
++ * name on the network, so it's time to create our services */
++ if (!ctx->group)
++ register_stuff(ctx);
++ break;
++
++ case AVAHI_CLIENT_S_COLLISION:
++
++ if (ctx->group)
++ avahi_entry_group_reset(ctx->group);
++ break;
++
++ case AVAHI_CLIENT_FAILURE: {
++
++ if (avahi_client_errno(client) == AVAHI_ERR_DISCONNECTED) {
++ int error;
++
++ avahi_client_free(ctx->client);
++ ctx->client = NULL;
++ ctx->group = NULL;
++
++ /* Reconnect to the server */
++
++#ifndef HAVE_AVAHI_THREADED_POLL
++ if (!(ctx->client = avahi_client_new(avahi_simple_poll_get(ctx->simple_poll),
++#else
++ if (!(ctx->client = avahi_client_new(avahi_threaded_poll_get(ctx->threaded_poll),
++#endif
++ AVAHI_CLIENT_NO_FAIL,
++ client_callback,
++ ctx,
++ &error))) {
++
++ LOG(log_error,
++ logtype_afpd,
++ "Failed to contact server: %s\n",
++ avahi_strerror(error));
++
++ avahi_client_free (ctx->client);
++#ifndef HAVE_AVAHI_THREADED_POLL
++ avahi_simple_poll_quit(ctx->simple_poll);
++#else
++ avahi_threaded_poll_quit(ctx->threaded_poll);
++#endif
++ }
++
++ } else {
++ LOG(log_error,
++ logtype_afpd,
++ "Client failure: %s\n",
++ avahi_strerror(avahi_client_errno(client)));
++
++ avahi_client_free (ctx->client);
++#ifndef HAVE_AVAHI_THREADED_POLL
++ avahi_simple_poll_quit(ctx->simple_poll);
++#else
++ avahi_threaded_poll_quit(ctx->threaded_poll);
++#endif
++ }
++
++ break;
++ }
++
++ case AVAHI_CLIENT_S_REGISTERING:
++ case AVAHI_CLIENT_CONNECTING:
++ ;
++ }
++}
++
++static void* thread(void *userdata) {
++#ifndef HAVE_AVAHI_THREADED_POLL
++ struct context *ctx = userdata;
++ sigset_t mask;
++ int r;
++
++ /* Make sure that signals are delivered to the main thread */
++ sigfillset(&mask);
++ pthread_sigmask(SIG_BLOCK, &mask, NULL);
++
++ pthread_mutex_lock(&ctx->mutex);
++
++ /* Run the main loop */
++ LOG(log_info, logtype_afpd, "Starting avahi loop...");
++ r = avahi_simple_poll_loop(ctx->simple_poll);
++
++ /* Cleanup some stuff */
++ if (ctx->client)
++ avahi_client_free(ctx->client);
++ ctx->client = NULL;
++ ctx->group = NULL;
++
++ pthread_mutex_unlock(&ctx->mutex);
++#endif
++ return NULL;
++}
++
++static int poll_func(struct pollfd *ufds,
++ unsigned int nfds,
++ int timeout,
++ void *userdata) {
++#ifndef HAVE_AVAHI_THREADED_POLL
++ pthread_mutex_t *mutex = userdata;
++ int r;
++
++ /* Before entering poll() we unlock the mutex, so that
++ * avahi_simple_poll_quit() can succeed from another thread. */
++
++ pthread_mutex_unlock(mutex);
++ r = poll(ufds, nfds, timeout);
++ pthread_mutex_lock(mutex);
++
++ return r;
++#else
++ return 0;
++#endif
++}
++
++/*
++ * Tries to setup the Zeroconf thread and any
++ * neccessary config setting.
++ */
++void* av_zeroconf_setup(unsigned long port, const char *name) {
++ struct context *ctx = NULL;
++
++ /* default service name, if there's none in
++ * the config file.
++ */
++ char service[256] = "AFP Server on ";
++ int error, ret;
++
++ /* initialize the struct that holds our
++ * config settings.
++ */
++ ctx = malloc(sizeof(struct context));
++ assert(ctx);
++ ctx->client = NULL;
++ ctx->group = NULL;
++#ifndef HAVE_AVAHI_THREADED_POLL
++ ctx->simple_poll = NULL;
++ pthread_mutex_init(&ctx->mutex, NULL);
++#else
++ ctx->threaded_poll = NULL;
++#endif
++ ctx->thread_running = 0;
++
++ LOG(log_info,
++ logtype_afpd,
++ "Setting port for Zeroconf service to: %i.\n",
++ port);
++ ctx->port = port;
++
++ /* Prepare service name */
++ if (!name) {
++ LOG(log_info,
++ logtype_afpd,
++ "Assigning default service name.\n");
++ gethostname(service+14, sizeof(service)-15);
++ service[sizeof(service)-1] = 0;
++
++ ctx->name = strdup(service);
++ }
++ else {
++ ctx->name = strdup(name);
++ }
++
++ assert(ctx->name);
++
++/* first of all we need to initialize our threading env */
++#ifdef HAVE_AVAHI_THREADED_POLL
++ if (!(ctx->threaded_poll = avahi_threaded_poll_new())) {
++ goto fail;
++ }
++#else
++ if (!(ctx->simple_poll = avahi_simple_poll_new())) {
++ LOG(log_error,
++ logtype_afpd,
++ "Failed to create event loop object.\n");
++ goto fail;
++ }
++
++ avahi_simple_poll_set_func(ctx->simple_poll, poll_func, &ctx->mutex);
++#endif
++
++/* now we need to acquire a client */
++#ifdef HAVE_AVAHI_THREADED_POLL
++ if (!(ctx->client = avahi_client_new(avahi_threaded_poll_get(ctx->threaded_poll),
++ AVAHI_CLIENT_NO_FAIL,
++ client_callback,
++ ctx,
++ &error))) {
++ LOG(log_error,
++ logtype_afpd,
++ "Failed to create client object: %s\n",
++ avahi_strerror(avahi_client_errno(ctx->client)));
++ goto fail;
++ }
++#else
++ if (!(ctx->client = avahi_client_new(avahi_simple_poll_get(ctx->simple_poll),
++ AVAHI_CLIENT_NO_FAIL,
++ client_callback,
++ ctx,
++ &error))) {
++ LOG(log_error,
++ logtype_afpd,
++ "Failed to create client object: %s\n",
++ avahi_strerror(avahi_client_errno(ctx->client)));
++ goto fail;
++ }
++#endif
++
++ return ctx;
++
++fail:
++
++ if (ctx)
++ av_zeroconf_unregister(ctx);
++
++ return NULL;
++}
++
++/*
++ * This function finally runs the loop impl.
++ */
++int av_zeroconf_run(void *u) {
++ struct context *ctx = u;
++ int ret;
++
++#ifdef HAVE_AVAHI_THREADED_POLL
++ /* Finally, start the event loop thread */
++ if (avahi_threaded_poll_start(ctx->threaded_poll) < 0) {
++ LOG(log_error,
++ logtype_afpd,
++ "Failed to create thread: %s\n",
++ avahi_strerror(avahi_client_errno(ctx->client)));
++ goto fail;
++ } else {
++ LOG(log_info, logtype_afpd, "Successfully started avahi loop.\n");
++ }
++#else
++ /* Create the mDNS event handler */
++ if ((ret = pthread_create(&ctx->thread_id, NULL, thread, ctx)) < 0) {
++ LOG(log_error,
++ logtype_afpd,
++ "Failed to create thread: %s\n", strerror(ret));
++ goto fail;
++ } else {
++ LOG(log_info, logtype_afpd, "Successfully started avahi loop.\n");
++ }
++#endif
++
++ ctx->thread_running = 1;
++
++ return 0;
++
++fail:
++
++ if (ctx)
++ av_zeroconf_unregister(ctx);
++
++ return -1;
++}
++
++/*
++ * Used to lock access to the loop.
++ * Currently unused.
++ */
++void av_zeroconf_lock(void *u) {
++#ifdef HAVE_AVAHI_THREADED_POLL
++ struct context *ctx = u;
++
++ avahi_threaded_poll_lock(ctx->threaded_poll);
++#endif
++}
++
++/*
++ * Used to unlock access to the loop.
++ * Currently unused.
++ */
++void av_zeroconf_unlock(void *u) {
++#ifdef HAVE_AVAHI_THREADED_POLL
++ struct context *ctx = u;
++
++ avahi_threaded_poll_unlock(ctx->threaded_poll);
++#endif
++}
++
++/*
++ * Tries to shutdown this loop impl.
++ * Call this function from outside this thread.
++ */
++void av_zeroconf_shutdown(void *u) {
++ struct context *ctx = u;
++
++ /* Call this when the app shuts down */
++#ifdef HAVE_AVAHI_THREADED_POLL
++ avahi_threaded_poll_stop(ctx->threaded_poll);
++ avahi_free(ctx->name);
++ avahi_client_free(ctx->client);
++ avahi_threaded_poll_free(ctx->threaded_poll);
++#else
++ av_zeroconf_unregister(ctx);
++#endif
++}
++
++/*
++ * Tries to shutdown this loop impl.
++ * Call this function from inside this thread.
++ */
++int av_zeroconf_unregister(void *u) {
++ struct context *ctx = u;
++
++ if (ctx->thread_running) {
++#ifndef HAVE_AVAHI_THREADED_POLL
++ pthread_mutex_lock(&ctx->mutex);
++ avahi_simple_poll_quit(ctx->simple_poll);
++ pthread_mutex_unlock(&ctx->mutex);
++
++ pthread_join(ctx->thread_id, NULL);
++#else
++ /* First, block the event loop */
++ avahi_threaded_poll_lock(ctx->threaded_poll);
++
++ /* Than, do your stuff */
++ avahi_threaded_poll_quit(ctx->threaded_poll);
++
++ /* Finally, unblock the event loop */
++ avahi_threaded_poll_unlock(ctx->threaded_poll);
++#endif
++ ctx->thread_running = 0;
++ }
++
++ avahi_free(ctx->name);
++
++ if (ctx->client)
++ avahi_client_free(ctx->client);
++
++#ifndef HAVE_AVAHI_THREADED_POLL
++ if (ctx->simple_poll)
++ avahi_simple_poll_free(ctx->simple_poll);
++
++ pthread_mutex_destroy(&ctx->mutex);
++#else
++ if (ctx->threaded_poll)
++ avahi_threaded_poll_free(ctx->threaded_poll);
++#endif
++
++ free(ctx);
++
++ return 0;
++}
++
++#endif /* USE_AVAHI */
+--- etc/afpd/afp_avahi.h.org 2006-04-21 10:29:23.000000000 +0200
++++ etc/afpd/afp_avahi.h 2006-04-22 07:40:05.000000000 +0200
+@@ -0,0 +1,58 @@
++/* -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2 -*- */
++/*
++ * Author: Daniel S. Haischt <me@daniel.stefan.haischt.name>
++ * Purpose: Avahi based Zeroconf support
++ * Docs: http://avahi.org/download/doxygen/
++ *
++ */
++
++#ifndef AFPD_AVAHI_H
++#define AFPD_AVAHI_H
++
++#include <stdlib.h>
++#include <assert.h>
++#include <string.h>
++
++#include <avahi-client/client.h>
++#include <avahi-client/publish.h>
++
++#include <avahi-common/alternative.h>
++
++#ifndef HAVE_AVAHI_THREADED_POLL
++#include <avahi-common/simple-watch.h>
++#include <signal.h> /* SIG_BLOCK */
++#else
++#include <avahi-common/thread-watch.h>
++#endif
++
++#include <avahi-common/malloc.h>
++#include <avahi-common/error.h>
++
++#include <atalk/logger.h>
++
++#define AFP_DNS_SERVICE_TYPE "_afpovertcp._tcp"
++
++struct context {
++ int thread_running;
++ pthread_t thread_id;
++ pthread_mutex_t mutex;
++ char *name;
++#ifndef HAVE_AVAHI_THREADED_POLL
++ AvahiSimplePoll *simple_poll;
++#else
++ AvahiThreadedPoll *threaded_poll;
++#endif
++ AvahiClient *client;
++ AvahiEntryGroup *group;
++ unsigned long port;
++};
++
++/* prototype definitions */
++void* av_zeroconf_setup(unsigned long, const char *);
++int av_zeroconf_run(void*);
++int av_zeroconf_unregister(void*);
++void av_zeroconf_shutdown(void*);
++void av_zeroconf_lock(void *);
++void av_zeroconf_unlock(void *);
++
++#endif /* AFPD_AVAHI_H */
+--- etc/afpd/afp_bonjour.h.org 2006-04-21 10:29:30.000000000 +0200
++++ etc/afpd/afp_bonjour.h 2006-04-21 07:37:05.000000000 +0200
+@@ -0,0 +1,27 @@
++/* -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2 -*- */
++/*
++ * Author: Daniel S. Haischt <me@daniel.stefan.haischt.name>
++ * Purpose: Bonjour based Zeroconf support
++ * Docs: http://developer.apple.com/documentation/Networking/Reference/DNSServiceDiscovery_CRef/dns_sd/
++ *
++ */
++
++#ifndef AFPD_BONJOUR_H
++#define AFPD_BONJOUR_H
++
++#include <stdlib.h>
++#include <assert.h>
++#include <string.h>
++
++#include <dns_sd.h> /* DNSServiceRegister(), DNSServiceDiscoveryDeallocate() */
++
++#include <atalk/logger.h>
++
++#define AFP_DNS_SERVICE_TYPE "_afpovertcp._tcp"
++
++/* prototype definitions */
++void* bo_zeroconf_setup(unsigned long, const char *);
++int bo_zeroconf_unregister(void);
++int bo_zeroconf_run(void);
++
++#endif /* AFPD_BONJOUR_H */
+--- etc/afpd/afp_bonjour.c.org 2006-04-21 10:29:28.000000000 +0200
++++ etc/afpd/afp_bonjour.c 2006-04-21 09:45:13.000000000 +0200
+@@ -0,0 +1,112 @@
++/* -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2 -*- */
++/*
++ * Author: Daniel S. Haischt <me@daniel.stefan.haischt.name>
++ * Purpose: Bonjour based Zeroconf support
++ * Docs: http://developer.apple.com/documentation/Networking/Reference/DNSServiceDiscovery_CRef/dns_sd/
++ *
++ */
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#ifdef HAVE_BONJOUR
++
++#include "afp_bonjour.h"
++
++DNSServiceRef publish_session = NULL;
++
++static void DNSSD_API
++publish_reply(DNSServiceRef,
++ const DNSServiceFlags,
++ DNSServiceErrorType,
++ const char *,
++ const char *,
++ const char *,
++ void *);
++
++static void DNSSD_API
++publish_reply (DNSServiceRef sdRef,
++ const DNSServiceFlags flags,
++ DNSServiceErrorType errorCode,
++ const char *name,
++ const char *regtype,
++ const char *domain,
++ void *context)
++{
++}
++
++void* bo_zeroconf_setup(unsigned long port, const char *name) {
++ DNSServiceErrorType err;
++ char service[256] = "AFP Server on ";
++
++ /* Prepare service name */
++ if (!name) {
++ LOG(log_info, logtype_afpd,, "Assigning default service name.\n");
++ gethostname(service+14, sizeof(service)-15);
++ service[sizeof(service)-1] = 0;
++
++ name = strdup(service);
++ }
++
++ assert(name);
++ assert(port);
++
++ err = DNSServiceRegister (&publish_session,
++ 0, /* flags */
++ 0, /* interface; 0 for all */
++ name, /* name */
++ AFP_DNS_SERVICE_TYPE, /* type */
++ NULL, /* domain */
++ NULL, /* hostname */
++ htons (port), /* port in network byte order */
++ 0, /* text record length */
++ NULL, /* text record */
++ publish_reply, /* callback */
++ NULL); /* context */
++
++ if (err == kDNSServiceErr_NoError) {
++ LOG(log_info, logtype_afpd, "Adding service '%s'\n", name);
++ } else {
++ LOG(log_error, logtype_afpd, "Adding service '%s' failed\n", name);
++ bo_zeroconf_unregister();
++ }
++}
++
++int bo_zeroconf_run(void) {
++ fd_set set;
++ int fd;
++ struct timeval timeout;
++
++ /* Initialize the file descriptor set. */
++ FD_ZERO (&set);
++ FD_SET (fd, &set);
++
++ /* Initialize the timeout data structure. */
++ /* TODO: Should the value for sec be configurable? */
++ timeout.tv_sec = 10;
++ timeout.tv_usec = 0;
++
++ if (publish_session != NULL) {
++ fd = DNSServiceRefSockFD(publish_session);
++
++ if (select(FD_SETSIZE,
++ &set, NULL, NULL,
++ &timeout) > 0) {
++ DNSServiceProcessResult(publish_session);
++ }
++ }
++
++ return 0;
++}
++
++int bo_zeroconf_unregister(void) {
++ if (publish_session != NULL) {
++ DNSServiceRefDeallocate(publish_session);
++ publish_session = NULL;
++ }
++
++ return 0;
++}
++
++#endif /* HAVE_BONJOUR */
+--- etc/afpd/afp_howl.c.org 2006-04-21 10:29:34.000000000 +0200
++++ etc/afpd/afp_howl.c 2006-04-21 09:46:11.000000000 +0200
+@@ -0,0 +1,92 @@
++/* -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2 -*- */
++/*
++ * Author: Daniel S. Haischt <me@daniel.stefan.haischt.name>
++ * Purpose: Howl based Zeroconf support
++ * Doc: http://www.porchdogsoft.com/products/howl/docs/
++ *
++ */
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#ifdef HAVE_HOWL
++
++#include "afp_howl.h"
++
++sw_discovery discovery = NULL;
++
++static sw_result HOWL_API publish_reply(sw_discovery,
++ sw_discovery_oid,
++ sw_discovery_publish_status,
++ sw_opaque);
++
++static sw_result HOWL_API publish_reply(sw_discovery discovery,
++ sw_discovery_oid oid,
++ sw_discovery_publish_status status,
++ sw_opaque extra) {
++ static sw_string
++ status_text[] =
++ {
++ "Started",
++ "Stopped",
++ "Name Collision",
++ "Invalid"
++ };
++
++ LOG(log_info, logtype_afpd, "publish reply: %s\n", status_text[status]);
++ return SW_OKAY;
++}
++
++void* ho_zeroconf_setup(unsigned long port, const char *name) {
++ sw_result result;
++ sw_discovery_publish_id id;
++ char service[256] = "AFP Server on ";
++
++ if (sw_discovery_init (&discovery) != SW_OKAY) {
++ LOG(log_error,
++ logtype_afpd,
++ "AFPD could not be started. \nTry running mDNSResponder.");
++ return;
++ }
++
++ /* Prepare service name */
++ if (!name) {
++ LOG(log_info, logtype_afpd, "Assigning default service name.\n");
++ gethostname(service+14, sizeof(service)-15);
++ service[sizeof(service)-1] = 0;
++
++ name = strdup(service);
++ }
++
++ assert(name);
++
++ if (!(result = sw_discovery_publish (discovery,
++ 0,
++ name,
++ AFP_DNS_SERVICE_TYPE,
++ NULL,
++ NULL,
++ port,
++ NULL,
++ 0,
++ publish_reply,
++ NULL,
++ &id)) != SW_OKAY) {
++ LOG(log_info, logtype_afpd, "Adding service '%s'\n", name);
++ } else {
++ LOG(log_error, logtype_afpd, "Adding service '%s' failed\n", name);
++ ho_zeroconf_unregister();
++ }
++}
++
++void* ho_zeroconf_run(void) {
++ sw_discovery_run(discovery);
++}
++
++void* ho_zeroconf_unregister(void) {
++ sw_discovery_stop_run(discovery);
++ sw_discovery_fina(discovery);
++}
++
++#endif /* USE_HOWL */
+--- etc/afpd/afp_howl.h.org 2006-04-21 10:29:33.000000000 +0200
++++ etc/afpd/afp_howl.h 2006-04-21 07:37:11.000000000 +0200
+@@ -0,0 +1,27 @@
++/* -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2 -*- */
++/*
++ * Author: Daniel S. Haischt <me@daniel.stefan.haischt.name>
++ * Purpose: Howl based Zeroconf support
++ * Doc: http://www.porchdogsoft.com/products/howl/docs/
++ *
++ */
++
++#ifndef AFPD_HOWL_H
++#define AFPD_HOWL_H
++
++#include <stdlib.h>
++#include <assert.h>
++#include <string.h>
++
++#include <howl.h>
++
++#include <atalk/logger.h>
++
++#define NTP_DNS_SERVICE_TYPE "_afpovertcp._tcp"
++
++/* prototype definitions */
++void* ho_zeroconf_setup(unsigned long, const char *);
++void* ho_zeroconf_unregister(void);
++void* ho_zeroconf_run(void);
++
++#endif /* AFPD_HOWL_H */
+--- etc/afpd/afp_zeroconf.h.org 2006-04-21 10:29:39.000000000 +0200
++++ etc/afpd/afp_zeroconf.h 2006-04-21 11:39:20.000000000 +0200
+@@ -0,0 +1,40 @@
++/* -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2 -*- */
++/*
++ * Author: Daniel S. Haischt <me@daniel.stefan.haischt.name>
++ * Purpose: Zeroconf facade, that abstracts access to a
++ * particular Zeroconf implementation
++ * Doc: http://www.dns-sd.org/
++ *
++ */
++
++#ifndef AFPD_ZEROCONF_H
++#define AFPD_ZEROCONF_H
++
++#include <netinet/in.h> /* htons() */
++#include <atalk/logger.h>
++
++# ifdef HAVE_BONJOUR
++# include "afp_bonjour.h"
++# elif defined (HAVE_HOWL)
++# include "afp_howl.h"
++# elif defined (HAVE_AVAHI)
++# include "afp_avahi.h"
++# endif
++
++#define AFP_PORT 548
++
++/*
++ * Prototype Definitions
++ */
++
++/*
++ * registers the ntpd service with a particular Zerconf implemenation.
++ */
++void zeroconf_register(int port, char *hostname);
++
++/*
++ * de-registers the ntpd service with a particular Zerconf implemenation.
++ */
++void zeroconf_deregister(void);
++
++#endif AFPD_ZEROCONF_H
+--- etc/afpd/afp_zeroconf.c.org 2006-04-21 10:29:38.000000000 +0200
++++ etc/afpd/afp_zeroconf.c 2006-04-21 13:12:38.000000000 +0200
+@@ -0,0 +1,97 @@
++/* -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2 -*- */
++/*
++ * Author: Daniel S. Haischt <me@daniel.stefan.haischt.name>
++ * Purpose: Zeroconf facade, that abstracts access to a
++ * particular Zeroconf implementation
++ * Doc: http://www.dns-sd.org/
++ *
++ */
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include "afp_zeroconf.h"
++
++/*
++ * Global Definitions
++ */
++#ifdef HAVE_AVAHI
++struct context *ctx = NULL;
++#endif
++
++/*
++ * Functions (actually they are just facades)
++ */
++void zeroconf_register(int port, char *hostname)
++{
++#ifdef HAVE_BONJOUR
++ LOG(log_info,
++ logtype_afpd,
++ "Attempting to register with mDNS using Apple's Bonjour\n");
++ if (hostname && strlen(hostname) > 0 && port)
++ {
++ bo_zeroconf_setup(port, hostname);
++ }
++ else if (hostname && strlen(hostname) > 0)
++ {
++ bo_zeroconf_setup(AFP_PORT, hostname);
++ }
++ else
++ {
++ bo_zeroconf_setup(AFP_PORT, NULL);
++ }
++ bo_zeroconf_run();
++#elif defined (HAVE_HOWL)
++ LOG(log_info,
++ logtype_afpd,
++ "Attempting to register with mDNS using Porchdog's Howl\n");
++ if (hostname && strlen(hostname) > 0 && port)
++ {
++ ho_zeroconf_setup(port, hostname);
++ }
++ else if (hostname && strlen(hostname) > 0)
++ {
++ ho_zeroconf_setup(AFP_PORT, hostname);
++ }
++ else
++ {
++ ho_zeroconf_setup(AFP_PORT, NULL);
++ }
++ bo_zeroconf_run();
++#elif defined (HAVE_AVAHI)
++ LOG(log_info, logtype_afpd, "Attempting to register with mDNS using Avahi\n");
++ if (hostname && strlen(hostname) > 0 && port)
++ {
++ ctx = av_zeroconf_setup(port, hostname);
++ }
++ else if (hostname && strlen(hostname) > 0)
++ {
++ ctx = av_zeroconf_setup(AFP_PORT, hostname);
++ }
++ else
++ {
++ ctx = av_zeroconf_setup(AFP_PORT, NULL);
++ }
++ av_zeroconf_run(ctx);
++#endif
++}
++
++void zeroconf_deregister(void)
++{
++#ifdef HAVE_BONJOUR
++ LOG(log_error,
++ logtype_afpd,
++ "Attempting to de-register mDNS using Apple's Bonjour\n");
++ bo_zeroconf_unregister();
++#elif defined (HAVE_HOWL)
++ LOG(log_error,
++ logtype_afpd,
++ "Attempting to de-register mDNS using Porchdog's Howl\n");
++ ho_zeroconf_unregister();
++#elif defined (HAVE_AVAHI)
++ LOG(log_error, logtype_afpd, "Attempting to de-register mDNS using Avahi\n");
++ if (ctx)
++ av_zeroconf_shutdown(ctx);
++#endif
++}
+--- macros/zeroconf.m4.org 2006-04-21 10:29:51.000000000 +0200
++++ macros/zeroconf.m4 2006-04-22 07:26:56.000000000 +0200
+@@ -0,0 +1,101 @@
++dnl Check for optional Zeroconf support
++
++dnl $Id$
++
++AC_DEFUN([NETATALK_ZEROCONF], [
++
++ ZEROCONF_LIBS=""
++ ZEROCONF_CFLAGS=""
++ found_zeroconf=no
++ zeroconf_dir=""
++
++ AC_ARG_ENABLE(zeroconf,
++ [ --enable-zeroconf[[=DIR]] enable Zeroconf support [[auto]]],
++ [zeroconf=$enableval],
++ [zeroconf=try]
++ )
++
++ dnl make sure atalk_libname is defined beforehand
++ [[ -n "$atalk_libname" ]] || AC_MSG_ERROR([internal error, atalk_libname undefined])
++
++ if test "x$zeroconf" != "xno"; then
++
++ savedcppflags="$CPPFLAGS"
++ savedldflags="$LDFLAGS"
++
++ if test "x$zeroconf" = "xyes" -o "x$zeroconf" = "xtry"; then
++ zeroconf_dir="/usr"
++ else
++ zeroconf_dir="$zeroconf"
++ fi
++
++ # mDNS support using Apple's Bonjour
++ AC_CHECK_HEADER(dns_sd.h,
++ [AC_CHECK_LIB(dns_sd,
++ DNSServiceRegister,
++ [AC_DEFINE(USE_ZEROCONF, 1,
++ [Use DNS-SD registration])])])
++ case "$ac_cv_lib_dns_sd_DNSServiceRegister" in
++ yes)
++ ZEROCONF_LIBS="-L$zeroconf_dir/lib -ldns_sd"
++ ZEROCONF_LIBS="-I$zeroconf_dir/include"
++ AC_DEFINE(HAVE_BONJOUR, 1, [Use Bonjour/DNS-SD registration])
++ found_zeroconf=yes
++ ;;
++ esac
++ # mDNS support using Porchdog's Howl
++ AC_CHECK_HEADER(howl.h,
++ [AC_CHECK_LIB(howl,
++ sw_discovery_publish,
++ [AC_DEFINE(USE_ZEROCONF, 1,
++ [Use DNS-SD registration])])])
++ case "$ac_cv_lib_howl_sw_discovery_publish" in
++ yes)
++ PKG_CHECK_MODULES(HOWL, [ howl >= 1.0.0 ])
++ ZEROCONF_LIBS="$HOWL_LIBS"
++ ZEROCONF_CFLAGS="$HOWL_CFLAGS"
++ AC_DEFINE(HAVE_HOWL, 1, [Use Howl/DNS-SD registration])
++ found_zeroconf=yes
++ ;;
++ esac
++ # mDNS support using Avahi
++ AC_CHECK_HEADER(avahi-client/client.h,
++ [AC_CHECK_LIB(avahi-client,
++ avahi_client_new,
++ [AC_DEFINE(USE_ZEROCONF, 1,
++ [Use DNS-SD registration])])])
++ case "$ac_cv_lib_avahi_client_avahi_client_new" in
++ yes)
++ PKG_CHECK_MODULES(AVAHI, [ avahi-client >= 0.6 ])
++ PKG_CHECK_MODULES(AVAHI_TPOLL, [ avahi-client >= 0.6.4 ],
++ [AC_DEFINE(HAVE_AVAHI_THREADED_POLL, 1, [Uses Avahis threaded poll implementation])],
++ [AC_MSG_WARN(This Avahi implementation is not supporting threaded poll objects. Maybe this is not what you want.)])
++ ZEROCONF_LIBS="$AVAHI_LIBS"
++ ZEROCONF_CFLAGS="$AVAHI_CFLAGS"
++ AC_DEFINE(HAVE_AVAHI, 1, [Use Avahi/DNS-SD registration])
++ found_zeroconf=yes
++ ;;
++ esac
++
++ CPPFLAGS="$savedcppflags"
++ LDFLAGS="$savedldflags"
++ fi
++
++ netatalk_cv_zeroconf=no
++ AC_MSG_CHECKING([whether to enable Zerconf support])
++ if test "x$found_zeroconf" = "xyes"; then
++ AC_MSG_RESULT([yes])
++ AC_DEFINE(USE_ZEROCONF, 1, [Define to enable Zeroconf support])
++ netatalk_cv_zeroconf=yes
++ else
++ AC_MSG_RESULT([no])
++ if test "x$zeroconf" != "xno" -a "x$zeroconf" != "xtry"; then
++ AC_MSG_ERROR([Zeroconf installation not found])
++ fi
++ fi
++
++ LIB_REMOVE_USR_LIB(ZEROCONF_LIBS)
++ CFLAGS_REMOVE_USR_INCLUDE(ZEROCONF_CFLAGS)
++ AC_SUBST(ZEROCONF_LIBS)
++ AC_SUBST(ZEROCONF_CFLAGS)
++])