Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 133575
Collapse All | Expand All

(-)configure.in (+3 lines)
Lines 398-403 Link Here
398
dnl Check for optional server location protocol support (used by MacOS X)
398
dnl Check for optional server location protocol support (used by MacOS X)
399
NETATALK_SRVLOC
399
NETATALK_SRVLOC
400
400
401
dnl Check for optional Zeroconf support
402
NETATALK_ZEROCONF
403
401
dnl Check for PAM libs
404
dnl Check for PAM libs
402
netatalk_cv_use_pam=no
405
netatalk_cv_use_pam=no
403
AC_PATH_PAM([
406
AC_PATH_PAM([
(-)config/afpd.conf.tmpl (+2 lines)
Lines 51-56 Link Here
51
#			  empty string.
51
#			  empty string.
52
#     -noslp              Don't register this server with the Service
52
#     -noslp              Don't register this server with the Service
53
#			  Location Protocol.
53
#			  Location Protocol.
54
#     -nozeroconf              Don't register this server with the Multicats
55
#			  DNS Protocol.
54
#
56
#
55
#
57
#
56
#   Authentication Methods:
58
#   Authentication Methods:
(-)contrib/a2boot/Makefile.am (-1 / +1 lines)
Lines 10-16 Link Here
10
EXTRA_DIST = COPYRIGHT VERSION
10
EXTRA_DIST = COPYRIGHT VERSION
11
11
12
CFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/sys \
12
CFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/sys \
13
	 @CFLAGS@ @SLP_CFLAGS@ \
13
	 @CFLAGS@ @SLP_CFLAGS@ @ZEROCONF_CFLAGS@ \
14
	 -D_PATH_A_GS_BLOCKS=\"$(PKGCONFDIR)/a2boot/ProDOS16\ Boot\ Blocks\" \
14
	 -D_PATH_A_GS_BLOCKS=\"$(PKGCONFDIR)/a2boot/ProDOS16\ Boot\ Blocks\" \
15
	 -D_PATH_A_2E_BLOCKS=\"$(PKGCONFDIR)/a2boot/Apple\ :2f:2fe\ Boot\ Blocks\" \
15
	 -D_PATH_A_2E_BLOCKS=\"$(PKGCONFDIR)/a2boot/Apple\ :2f:2fe\ Boot\ Blocks\" \
16
	 -D_PATH_P16_IMAGE=\"$(PKGCONFDIR)/a2boot/ProDOS16\ Image\"
16
	 -D_PATH_P16_IMAGE=\"$(PKGCONFDIR)/a2boot/ProDOS16\ Image\"
(-)etc/afpd/Makefile.am (-4 / +6 lines)
Lines 8-26 Link Here
8
	 file.c enumerate.c desktop.c filedir.c fork.c appl.c gettok.c \
8
	 file.c enumerate.c desktop.c filedir.c fork.c appl.c gettok.c \
9
	 mangle.c status.c afp_options.c afp_asp.c afp_dsi.c messages.c  \
9
	 mangle.c status.c afp_options.c afp_asp.c afp_dsi.c messages.c  \
10
	 afp_config.c nfsquota.c quota.c uam.c afs.c uid.c afp_util.c \
10
	 afp_config.c nfsquota.c quota.c uam.c afs.c uid.c afp_util.c \
11
         catsearch.c afprun.c
11
         catsearch.c afprun.c \
12
         afp_zeroconf.c afp_avahi.c afp_bonjour.c afp_howl.c
12
13
13
afpd_LDADD =  $(top_builddir)/libatalk/cnid/libcnid.la $(top_builddir)/libatalk/libatalk.la
14
afpd_LDADD =  $(top_builddir)/libatalk/cnid/libcnid.la $(top_builddir)/libatalk/libatalk.la
14
afpd_LDFLAGS = -export-dynamic
15
afpd_LDFLAGS = -export-dynamic
15
16
16
noinst_HEADERS = auth.h afp_config.h desktop.h directory.h file.h \
17
noinst_HEADERS = auth.h afp_config.h desktop.h directory.h file.h \
17
	 filedir.h fork.h globals.h icon.h mangle.h misc.h status.h switch.h \
18
	 filedir.h fork.h globals.h icon.h mangle.h misc.h status.h switch.h \
18
	 uam_auth.h uid.h unix.h volume.h
19
	 uam_auth.h uid.h unix.h volume.h \
20
         afp_zeroconf.h afp_avahi.h afp_bonjour.h afp_howl.h
19
21
20
LIBS = @LIBS@ @PAM_LIBS@ @QUOTA_LIBS@ @SLP_LIBS@ @WRAP_LIBS@
22
LIBS = @LIBS@ @PAM_LIBS@ @QUOTA_LIBS@ @SLP_LIBS@ @ZEROCONF_LIBS@ @WRAP_LIBS@
21
23
22
CFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/sys \
24
CFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/sys \
23
	 @CFLAGS@ @SLP_CFLAGS@ \
25
	 @CFLAGS@ @SLP_CFLAGS@ @ZEROCONF_CFLAGS@ \
24
	 -D_PATH_AFPDDEFVOL=\"$(pkgconfdir)/AppleVolumes.default\" \
26
	 -D_PATH_AFPDDEFVOL=\"$(pkgconfdir)/AppleVolumes.default\" \
25
	 -D_PATH_AFPDSYSVOL=\"$(pkgconfdir)/AppleVolumes.system\" \
27
	 -D_PATH_AFPDSYSVOL=\"$(pkgconfdir)/AppleVolumes.system\" \
26
	 -D_PATH_AFPDPWFILE=\"$(pkgconfdir)/afppasswd\" \
28
	 -D_PATH_AFPDPWFILE=\"$(pkgconfdir)/afppasswd\" \
(-)etc/afpd/afp_config.c (-2 / +50 lines)
Lines 50-55 Link Here
50
#ifdef USE_SRVLOC
50
#ifdef USE_SRVLOC
51
#include <slp.h>
51
#include <slp.h>
52
#endif /* USE_SRVLOC */
52
#endif /* USE_SRVLOC */
53
#ifdef USE_ZEROCONF
54
#include "afp_zeroconf.h"
55
#endif /* USE_ZEROCONF */
53
56
54
#include "globals.h"
57
#include "globals.h"
55
#include "afp_config.h"
58
#include "afp_config.h"
Lines 154-162 Link Here
154
}
157
}
155
#endif /* USE_SRVLOC */
158
#endif /* USE_SRVLOC */
156
159
157
#ifdef USE_SRVLOC
158
static void dsi_cleanup(const AFPConfig *config)
160
static void dsi_cleanup(const AFPConfig *config)
159
{
161
{
162
#ifdef USE_SRVLOC
160
    SLPError err;
163
    SLPError err;
161
    SLPError callbackerr;
164
    SLPError callbackerr;
162
    SLPHandle hslp;
165
    SLPHandle hslp;
Lines 189-196 Link Here
189
srvloc_dereg_err:
192
srvloc_dereg_err:
190
    dsi->srvloc_url[0] = '\0';
193
    dsi->srvloc_url[0] = '\0';
191
    SLPClose(hslp);
194
    SLPClose(hslp);
192
}
195
#elif defined (USE_ZEROCONF)
196
    DSI *dsi = (DSI *)config->obj.handle;
197
198
    /*  Do nothing if we didn't register.  */
199
    if (!dsi || dsi->zeroconf_registered == 0)
200
        return;
201
202
    zeroconf_deregister();
193
#endif /* USE_SRVLOC */
203
#endif /* USE_SRVLOC */
204
}
194
205
195
#ifndef NO_DDP
206
#ifndef NO_DDP
196
static void asp_cleanup(const AFPConfig *config)
207
static void asp_cleanup(const AFPConfig *config)
Lines 355-360 Link Here
355
    struct servent *afpovertcp;
366
    struct servent *afpovertcp;
356
    int afp_port = 548;
367
    int afp_port = 548;
357
    char *srvloc_hostname, *hostname;
368
    char *srvloc_hostname, *hostname;
369
#elif defined (USE_ZEROCONF)
370
    struct servent *afpovertcp;
371
    int afp_port = 548;
372
    char *hostname = NULL;
358
#endif /* USE_SRVLOC */
373
#endif /* USE_SRVLOC */
359
374
360
    if ((config = (AFPConfig *) calloc(1, sizeof(AFPConfig))) == NULL) {
375
    if ((config = (AFPConfig *) calloc(1, sizeof(AFPConfig))) == NULL) {
Lines 449-454 Link Here
449
    }
464
    }
450
#endif /* USE_SRVLOC */
465
#endif /* USE_SRVLOC */
451
466
467
#ifdef USE_ZEROCONF
468
    dsi->zeroconf_registered = 0; /*  Mark that we haven't registered.  */
469
470
    if (!(options->flags & OPTION_NOZEROCONF)) {
471
        /* XXX We don't want to tack on the port number if we don't have to.
472
    	   * Why?
473
    	   * Well, this seems to break MacOS < 10.  If the user _really_ wants to
474
    	   * use a non-default port, they can, but be aware, this server might
475
    	   * not show up int the Network Browser.
476
    	   */
477
        afpovertcp = getservbyname("afpovertcp", "tcp");
478
        if (afpovertcp != NULL) {
479
    	      afp_port = ntohs(afpovertcp->s_port);
480
        }
481
482
        /* If specified use the FQDN to register with srvloc, otherwise use IP. */
483
        p = NULL;
484
        if (options->fqdn) {
485
            hostname = options->fqdn;
486
            p = strchr(hostname, ':');
487
        }	
488
        else 
489
            hostname = inet_ntoa(dsi->server.sin_addr);
490
491
        if (!(options->flags & OPTION_NOSLP)) {
492
            zeroconf_register(afp_port, hostname);
493
            dsi->zeroconf_registered = 1; /*  Mark that we have registered.  */
494
        }
495
    }
496
#endif /* USE_ZEROCONF */
452
497
453
    config->fd = dsi->serversock;
498
    config->fd = dsi->serversock;
454
    config->obj.handle = dsi;
499
    config->obj.handle = dsi;
Lines 469-474 Link Here
469
#ifdef USE_SRVLOC
514
#ifdef USE_SRVLOC
470
    config->server_cleanup = dsi_cleanup;
515
    config->server_cleanup = dsi_cleanup;
471
#endif 
516
#endif 
517
#ifdef USE_ZEROCONF
518
    config->server_cleanup = dsi_cleanup;
519
#endif
472
    return config;
520
    return config;
473
}
521
}
474
522
(-)etc/afpd/afp_options.c (+11 lines)
Lines 202-211 Link Here
202
    /* parse toggles */
202
    /* parse toggles */
203
    if (strstr(buf, " -nodebug"))
203
    if (strstr(buf, " -nodebug"))
204
        options->flags &= ~OPTION_DEBUG;
204
        options->flags &= ~OPTION_DEBUG;
205
205
#ifdef USE_SRVLOC
206
#ifdef USE_SRVLOC
206
    if (strstr(buf, " -noslp"))
207
    if (strstr(buf, " -noslp"))
207
        options->flags |= OPTION_NOSLP;
208
        options->flags |= OPTION_NOSLP;
208
#endif /* USE_SRVLOC */
209
#endif /* USE_SRVLOC */
210
#ifdef USE_ZEROCONF
211
    if (strstr(buf, " -nozeroconf"))
212
        options->flags |= OPTION_NOZEROCONF;
213
#endif
209
214
210
    if (strstr(buf, " -nouservolfirst"))
215
    if (strstr(buf, " -nouservolfirst"))
211
        options->flags &= ~OPTION_USERVOLFIRST;
216
        options->flags &= ~OPTION_USERVOLFIRST;
Lines 578-583 Link Here
578
	puts( "No" );
583
	puts( "No" );
579
#endif
584
#endif
580
585
586
#ifdef USE_ZEROCONF
587
	puts( "Yes" );
588
#else
589
	puts( "No" );
590
#endif
591
581
	printf( "  TCP wrappers support:\t" );
592
	printf( "  TCP wrappers support:\t" );
582
#ifdef TCPWRAP
593
#ifdef TCPWRAP
583
	puts( "Yes" );
594
	puts( "Yes" );
(-)etc/afpd/globals.h (+1 lines)
Lines 40-45 Link Here
40
#define OPTION_CUSTOMICON    (1 << 4)
40
#define OPTION_CUSTOMICON    (1 << 4)
41
#define OPTION_NOSLP         (1 << 5)
41
#define OPTION_NOSLP         (1 << 5)
42
#define OPTION_ANNOUNCESSH   (1 << 6)
42
#define OPTION_ANNOUNCESSH   (1 << 6)
43
#define OPTION_NOZEROCONF    (1 << 7)
43
44
44
#ifdef FORCE_UIDGID
45
#ifdef FORCE_UIDGID
45
/* set up a structure for this */
46
/* set up a structure for this */
(-)include/atalk/dsi.h (+4 lines)
Lines 85-90 Link Here
85
  char srvloc_url[512];
85
  char srvloc_url[512];
86
#endif 
86
#endif 
87
87
88
#ifdef USE_ZEROCONF
89
  int zeroconf_registered;
90
#endif
91
88
  /* buffer for OSX deadlock */
92
  /* buffer for OSX deadlock */
89
  int noblocking;
93
  int noblocking;
90
  char *buffer;
94
  char *buffer;
(-)macros/summary.m4 (+1 lines)
Lines 44-49 Link Here
44
	AC_MSG_RESULT([    Options:])
44
	AC_MSG_RESULT([    Options:])
45
	AC_MSG_RESULT([         CUPS support:           $netatalk_cv_use_cups])
45
	AC_MSG_RESULT([         CUPS support:           $netatalk_cv_use_cups])
46
	AC_MSG_RESULT([         SLP support:            $netatalk_cv_srvloc])
46
	AC_MSG_RESULT([         SLP support:            $netatalk_cv_srvloc])
47
	AC_MSG_RESULT([         Zeroconf support:       $netatalk_cv_zeroconf])
47
	AC_MSG_RESULT([         tcp wrapper support:    $netatalk_cv_tcpwrap])
48
	AC_MSG_RESULT([         tcp wrapper support:    $netatalk_cv_tcpwrap])
48
dnl	if test x"$netatalk_cv_linux_sendfile" != x; then
49
dnl	if test x"$netatalk_cv_linux_sendfile" != x; then
49
dnl		AC_MSG_RESULT([         Linux sendfile support: $netatalk_cv_linux_sendfile])
50
dnl		AC_MSG_RESULT([         Linux sendfile support: $netatalk_cv_linux_sendfile])
(-)man/man5/afpd.conf.5.tmpl (+3 lines)
Lines 210-215 Link Here
210
Protocol (if SLP support was compiled in). This is useful if you are
210
Protocol (if SLP support was compiled in). This is useful if you are
211
running multiple servers and want one to be hidden, perhaps because
211
running multiple servers and want one to be hidden, perhaps because
212
it is advertised elsewhere, ie. by a SLP Directory Agent.
212
it is advertised elsewhere, ie. by a SLP Directory Agent.
213
\-noslp
214
Do not register this server using the Multicast DNS
215
Protocol (if Zeroconf support was compiled in).
213
.SH "MISCELLANEOUS OPTIONS"
216
.SH "MISCELLANEOUS OPTIONS"
214
.TP 
217
.TP 
215
\-admingroup \fI[group]\fR
218
\-admingroup \fI[group]\fR
(-)etc/afpd/afp_avahi.c.org (+500 lines)
Line 0 Link Here
1
/* -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2 -*- */
2
/*
3
 * Author:  Daniel S. Haischt <me@daniel.stefan.haischt.name>
4
 * Purpose: Avahi based Zeroconf support
5
 * Docs:    http://avahi.org/download/doxygen/
6
 *
7
 */
8
9
#ifdef HAVE_CONFIG_H
10
#include <config.h>
11
#endif
12
13
#ifdef HAVE_AVAHI
14
15
#include "afp_avahi.h"
16
17
static void publish_reply(AvahiEntryGroup *g,
18
                          AvahiEntryGroupState state,
19
                          void *userdata);
20
21
/*
22
 * This function tries to register the AFP DNS
23
 * SRV service type.
24
 */
25
static void register_stuff(struct context *ctx) {
26
  char r[128];
27
  int ret;
28
29
  assert(ctx->client);
30
31
  if (!ctx->group) {
32
33
    if (!(ctx->group = avahi_entry_group_new(ctx->client,
34
                                             publish_reply,
35
                                             ctx))) {
36
      LOG(log_error,
37
          logtype_afpd,
38
          "Failed to create entry group: %s\n",
39
          avahi_strerror(avahi_client_errno(ctx->client)));
40
      goto fail;
41
    }
42
43
  }
44
45
  LOG(log_info, logtype_afpd, "Adding service '%s'\n", ctx->name);
46
47
  if (avahi_entry_group_is_empty(ctx->group)) {
48
    /* Register our service */
49
50
    if (avahi_entry_group_add_service(ctx->group,
51
                                      AVAHI_IF_UNSPEC,
52
                                      AVAHI_PROTO_UNSPEC,
53
                                      0,
54
                                      ctx->name,
55
                                      AFP_DNS_SERVICE_TYPE,
56
                                      NULL,
57
                                      NULL,
58
                                      ctx->port,
59
                                      NULL) < 0) {
60
      LOG(log_error,
61
          logtype_afpd,
62
          "Failed to add service: %s\n",
63
          avahi_strerror(avahi_client_errno(ctx->client)));
64
      goto fail;
65
    }
66
67
    if (avahi_entry_group_commit(ctx->group) < 0) {
68
      LOG(log_error,
69
          logtype_afpd,
70
          "Failed to commit entry group: %s\n",
71
          avahi_strerror(avahi_client_errno(ctx->client)));
72
      goto fail;
73
    }
74
  }
75
76
  return;
77
78
  fail:
79
    avahi_client_free (ctx->client);
80
#ifndef HAVE_AVAHI_THREADED_POLL
81
    avahi_simple_poll_quit(ctx->simple_poll);
82
#else
83
    avahi_threaded_poll_quit(ctx->threaded_poll);
84
#endif
85
}
86
87
/* Called when publishing of service data completes */
88
static void publish_reply(AvahiEntryGroup *g,
89
                          AvahiEntryGroupState state,
90
                          AVAHI_GCC_UNUSED void *userdata)
91
{
92
  struct context *ctx = userdata;
93
94
  assert(g == ctx->group);
95
96
  switch (state) {
97
98
  case AVAHI_ENTRY_GROUP_ESTABLISHED :
99
    /* The entry group has been established successfully */
100
    break;
101
102
  case AVAHI_ENTRY_GROUP_COLLISION: {
103
    char *n;
104
105
    /* Pick a new name for our service */
106
107
    n = avahi_alternative_service_name(ctx->name);
108
    assert(n);
109
110
    avahi_free(ctx->name);
111
    ctx->name = n;
112
113
    register_stuff(ctx);
114
    break;
115
  }
116
117
  case AVAHI_ENTRY_GROUP_FAILURE: {
118
    LOG(log_error,
119
        logtype_afpd,
120
        "Failed to register service: %s\n",
121
        avahi_strerror(avahi_client_errno(ctx->client)));
122
    avahi_client_free (avahi_entry_group_get_client(g));
123
#ifndef HAVE_AVAHI_THREADED_POLL
124
    avahi_simple_poll_quit(ctx->simple_poll);
125
#else
126
    avahi_threaded_poll_quit(ctx->threaded_poll);
127
#endif
128
    break;
129
  }
130
131
  case AVAHI_ENTRY_GROUP_UNCOMMITED:
132
  case AVAHI_ENTRY_GROUP_REGISTERING:
133
    ;
134
  }
135
}
136
137
static void client_callback(AvahiClient *client,
138
                            AvahiClientState state,
139
                            void *userdata)
140
{
141
  struct context *ctx = userdata;
142
143
  ctx->client = client;
144
145
  switch (state) {
146
147
  case AVAHI_CLIENT_S_RUNNING:
148
149
    /* The server has startup successfully and registered its host
150
     * name on the network, so it's time to create our services */
151
    if (!ctx->group)
152
      register_stuff(ctx);
153
    break;
154
155
  case AVAHI_CLIENT_S_COLLISION:
156
157
    if (ctx->group)
158
      avahi_entry_group_reset(ctx->group);
159
    break;
160
161
  case AVAHI_CLIENT_FAILURE: {
162
163
    if (avahi_client_errno(client) == AVAHI_ERR_DISCONNECTED) {
164
      int error;
165
166
      avahi_client_free(ctx->client);
167
      ctx->client = NULL;
168
      ctx->group = NULL;
169
170
      /* Reconnect to the server */
171
172
#ifndef HAVE_AVAHI_THREADED_POLL
173
      if (!(ctx->client = avahi_client_new(avahi_simple_poll_get(ctx->simple_poll),
174
#else
175
      if (!(ctx->client = avahi_client_new(avahi_threaded_poll_get(ctx->threaded_poll),
176
#endif
177
                                           AVAHI_CLIENT_NO_FAIL,
178
                                           client_callback,
179
                                           ctx,
180
                                           &error))) {
181
182
        LOG(log_error,
183
            logtype_afpd,
184
            "Failed to contact server: %s\n",
185
            avahi_strerror(error));
186
187
        avahi_client_free (ctx->client);
188
#ifndef HAVE_AVAHI_THREADED_POLL
189
        avahi_simple_poll_quit(ctx->simple_poll);
190
#else
191
        avahi_threaded_poll_quit(ctx->threaded_poll);
192
#endif
193
      }
194
195
      } else {
196
        LOG(log_error,
197
            logtype_afpd,
198
            "Client failure: %s\n",
199
            avahi_strerror(avahi_client_errno(client)));
200
201
        avahi_client_free (ctx->client);
202
#ifndef HAVE_AVAHI_THREADED_POLL
203
        avahi_simple_poll_quit(ctx->simple_poll);
204
#else
205
        avahi_threaded_poll_quit(ctx->threaded_poll);
206
#endif
207
      }
208
209
    break;
210
  }
211
212
  case AVAHI_CLIENT_S_REGISTERING:
213
  case AVAHI_CLIENT_CONNECTING:
214
    ;
215
  }
216
}
217
218
static void* thread(void *userdata) {
219
#ifndef HAVE_AVAHI_THREADED_POLL
220
  struct context *ctx = userdata;
221
  sigset_t mask;
222
  int r;
223
224
  /* Make sure that signals are delivered to the main thread */
225
  sigfillset(&mask);
226
  pthread_sigmask(SIG_BLOCK, &mask, NULL);
227
    
228
  pthread_mutex_lock(&ctx->mutex);
229
230
  /* Run the main loop */
231
  LOG(log_info, logtype_afpd, "Starting avahi loop...");
232
  r = avahi_simple_poll_loop(ctx->simple_poll);
233
234
  /* Cleanup some stuff */
235
  if (ctx->client)
236
    avahi_client_free(ctx->client);
237
  ctx->client = NULL;
238
  ctx->group = NULL;
239
    
240
  pthread_mutex_unlock(&ctx->mutex);
241
#endif    
242
  return NULL;
243
}
244
245
static int poll_func(struct pollfd *ufds,
246
                     unsigned int nfds,
247
                     int timeout,
248
                     void *userdata) {
249
#ifndef HAVE_AVAHI_THREADED_POLL
250
  pthread_mutex_t *mutex = userdata;
251
  int r;
252
253
  /* Before entering poll() we unlock the mutex, so that
254
   * avahi_simple_poll_quit() can succeed from another thread. */
255
    
256
  pthread_mutex_unlock(mutex);
257
  r = poll(ufds, nfds, timeout);
258
  pthread_mutex_lock(mutex);
259
260
  return r;
261
#else
262
  return 0;
263
#endif
264
}
265
266
/*
267
 * Tries to setup the Zeroconf thread and any
268
 * neccessary config setting.
269
 */
270
void* av_zeroconf_setup(unsigned long port, const char *name) {
271
  struct context *ctx = NULL;
272
273
  /* default service name, if there's none in
274
   * the config file.
275
   */
276
  char service[256] = "AFP Server on ";
277
  int error, ret;
278
279
  /* initialize the struct that holds our
280
   * config settings.
281
   */
282
  ctx = malloc(sizeof(struct context));
283
  assert(ctx);
284
  ctx->client = NULL;
285
  ctx->group = NULL;
286
#ifndef HAVE_AVAHI_THREADED_POLL
287
  ctx->simple_poll = NULL;
288
  pthread_mutex_init(&ctx->mutex, NULL);
289
#else
290
  ctx->threaded_poll = NULL;
291
#endif
292
  ctx->thread_running = 0;
293
294
  LOG(log_info,
295
      logtype_afpd,
296
      "Setting port for Zeroconf service to: %i.\n",
297
      port);  
298
  ctx->port = port;
299
300
  /* Prepare service name */
301
  if (!name) {
302
    LOG(log_info,
303
        logtype_afpd,
304
        "Assigning default service name.\n");
305
    gethostname(service+14, sizeof(service)-15);
306
    service[sizeof(service)-1] = 0;
307
308
    ctx->name = strdup(service);
309
  }
310
  else {
311
    ctx->name = strdup(name);
312
  }
313
314
  assert(ctx->name);
315
316
/* first of all we need to initialize our threading env */
317
#ifdef HAVE_AVAHI_THREADED_POLL
318
  if (!(ctx->threaded_poll = avahi_threaded_poll_new())) {
319
     goto fail;
320
  }
321
#else
322
  if (!(ctx->simple_poll = avahi_simple_poll_new())) {
323
      LOG(log_error,
324
          logtype_afpd,
325
          "Failed to create event loop object.\n");
326
      goto fail;
327
  }
328
329
  avahi_simple_poll_set_func(ctx->simple_poll, poll_func, &ctx->mutex);
330
#endif
331
332
/* now we need to acquire a client */
333
#ifdef HAVE_AVAHI_THREADED_POLL
334
  if (!(ctx->client = avahi_client_new(avahi_threaded_poll_get(ctx->threaded_poll),
335
                                       AVAHI_CLIENT_NO_FAIL,
336
                                       client_callback,
337
                                       ctx,
338
                                       &error))) {
339
    LOG(log_error,
340
        logtype_afpd,
341
        "Failed to create client object: %s\n",
342
        avahi_strerror(avahi_client_errno(ctx->client)));
343
    goto fail;
344
  }
345
#else
346
  if (!(ctx->client = avahi_client_new(avahi_simple_poll_get(ctx->simple_poll),
347
                                       AVAHI_CLIENT_NO_FAIL,
348
                                       client_callback,
349
                                       ctx,
350
                                       &error))) {
351
    LOG(log_error,
352
        logtype_afpd,
353
        "Failed to create client object: %s\n",
354
        avahi_strerror(avahi_client_errno(ctx->client)));
355
    goto fail;
356
  }
357
#endif
358
359
  return ctx;
360
361
fail:
362
363
  if (ctx)
364
    av_zeroconf_unregister(ctx);
365
366
  return NULL;
367
}
368
369
/*
370
 * This function finally runs the loop impl.
371
 */
372
int av_zeroconf_run(void *u) {
373
  struct context *ctx = u;
374
  int ret;
375
376
#ifdef HAVE_AVAHI_THREADED_POLL
377
  /* Finally, start the event loop thread */
378
  if (avahi_threaded_poll_start(ctx->threaded_poll) < 0) {
379
    LOG(log_error,
380
        logtype_afpd,
381
        "Failed to create thread: %s\n",
382
        avahi_strerror(avahi_client_errno(ctx->client)));
383
    goto fail;
384
  } else {
385
    LOG(log_info, logtype_afpd, "Successfully started avahi loop.\n");
386
  }
387
#else
388
  /* Create the mDNS event handler */
389
  if ((ret = pthread_create(&ctx->thread_id, NULL, thread, ctx)) < 0) {
390
    LOG(log_error,
391
        logtype_afpd,
392
        "Failed to create thread: %s\n", strerror(ret));
393
    goto fail;
394
  } else {
395
    LOG(log_info, logtype_afpd, "Successfully started avahi loop.\n");
396
  }
397
#endif
398
399
  ctx->thread_running = 1;
400
401
  return 0;
402
403
fail:
404
405
  if (ctx)
406
    av_zeroconf_unregister(ctx);
407
408
  return -1;
409
}
410
411
/*
412
 * Used to lock access to the loop.
413
 * Currently unused.
414
 */
415
void av_zeroconf_lock(void *u) {
416
#ifdef HAVE_AVAHI_THREADED_POLL
417
  struct context *ctx = u;
418
419
  avahi_threaded_poll_lock(ctx->threaded_poll);
420
#endif
421
}
422
423
/*
424
 * Used to unlock access to the loop.
425
 * Currently unused.
426
 */
427
void av_zeroconf_unlock(void *u) {
428
#ifdef HAVE_AVAHI_THREADED_POLL
429
  struct context *ctx = u;
430
431
  avahi_threaded_poll_unlock(ctx->threaded_poll);
432
#endif
433
}
434
435
/*
436
 * Tries to shutdown this loop impl.
437
 * Call this function from outside this thread.
438
 */
439
void av_zeroconf_shutdown(void *u) {
440
  struct context *ctx = u;
441
442
  /* Call this when the app shuts down */
443
#ifdef HAVE_AVAHI_THREADED_POLL
444
  avahi_threaded_poll_stop(ctx->threaded_poll);
445
  avahi_free(ctx->name);
446
  avahi_client_free(ctx->client);
447
  avahi_threaded_poll_free(ctx->threaded_poll);
448
#else
449
  av_zeroconf_unregister(ctx);
450
#endif
451
}
452
453
/*
454
 * Tries to shutdown this loop impl.
455
 * Call this function from inside this thread.
456
 */
457
int av_zeroconf_unregister(void *u) {
458
  struct context *ctx = u;
459
460
  if (ctx->thread_running) {
461
#ifndef HAVE_AVAHI_THREADED_POLL
462
    pthread_mutex_lock(&ctx->mutex);
463
    avahi_simple_poll_quit(ctx->simple_poll);
464
    pthread_mutex_unlock(&ctx->mutex);
465
466
    pthread_join(ctx->thread_id, NULL);
467
#else
468
    /* First, block the event loop */
469
    avahi_threaded_poll_lock(ctx->threaded_poll);
470
471
    /* Than, do your stuff */
472
    avahi_threaded_poll_quit(ctx->threaded_poll);
473
474
    /* Finally, unblock the event loop */
475
    avahi_threaded_poll_unlock(ctx->threaded_poll);
476
#endif
477
    ctx->thread_running = 0;
478
  }
479
480
  avahi_free(ctx->name);
481
482
  if (ctx->client)
483
    avahi_client_free(ctx->client);
484
485
#ifndef HAVE_AVAHI_THREADED_POLL
486
  if (ctx->simple_poll)
487
    avahi_simple_poll_free(ctx->simple_poll);
488
489
  pthread_mutex_destroy(&ctx->mutex);
490
#else
491
  if (ctx->threaded_poll)
492
    avahi_threaded_poll_free(ctx->threaded_poll);
493
#endif
494
495
  free(ctx);
496
497
  return 0;
498
}
499
500
#endif /* USE_AVAHI */
(-)etc/afpd/afp_avahi.h.org (+58 lines)
Line 0 Link Here
1
/* -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2 -*- */
2
/*
3
 * Author:  Daniel S. Haischt <me@daniel.stefan.haischt.name>
4
 * Purpose: Avahi based Zeroconf support
5
 * Docs:    http://avahi.org/download/doxygen/
6
 *
7
 */
8
9
#ifndef AFPD_AVAHI_H
10
#define AFPD_AVAHI_H
11
12
#include <stdlib.h>
13
#include <assert.h>
14
#include <string.h>
15
16
#include <avahi-client/client.h>
17
#include <avahi-client/publish.h>
18
19
#include <avahi-common/alternative.h>
20
21
#ifndef HAVE_AVAHI_THREADED_POLL
22
#include <avahi-common/simple-watch.h>
23
#include <signal.h> /* SIG_BLOCK */
24
#else
25
#include <avahi-common/thread-watch.h>
26
#endif
27
28
#include <avahi-common/malloc.h>
29
#include <avahi-common/error.h>
30
31
#include <atalk/logger.h>
32
33
#define AFP_DNS_SERVICE_TYPE "_afpovertcp._tcp"
34
35
struct context {
36
  int thread_running;
37
  pthread_t thread_id;
38
  pthread_mutex_t mutex;
39
  char *name;
40
#ifndef HAVE_AVAHI_THREADED_POLL
41
  AvahiSimplePoll   *simple_poll;
42
#else
43
  AvahiThreadedPoll *threaded_poll;
44
#endif
45
  AvahiClient       *client;
46
  AvahiEntryGroup   *group;
47
  unsigned long     port;
48
};
49
50
/* prototype definitions */
51
void* av_zeroconf_setup(unsigned long, const char *);
52
int av_zeroconf_run(void*);
53
int av_zeroconf_unregister(void*);
54
void av_zeroconf_shutdown(void*);
55
void av_zeroconf_lock(void *);
56
void av_zeroconf_unlock(void *);
57
58
#endif   /* AFPD_AVAHI_H */
(-)etc/afpd/afp_bonjour.h.org (+27 lines)
Line 0 Link Here
1
/* -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2 -*- */
2
/*
3
 * Author:  Daniel S. Haischt <me@daniel.stefan.haischt.name>
4
 * Purpose: Bonjour based Zeroconf support
5
 * Docs:    http://developer.apple.com/documentation/Networking/Reference/DNSServiceDiscovery_CRef/dns_sd/
6
 *
7
 */
8
9
#ifndef AFPD_BONJOUR_H
10
#define AFPD_BONJOUR_H
11
12
#include <stdlib.h>
13
#include <assert.h>
14
#include <string.h>
15
16
#include <dns_sd.h>     /* DNSServiceRegister(), DNSServiceDiscoveryDeallocate() */
17
18
#include <atalk/logger.h>
19
20
#define AFP_DNS_SERVICE_TYPE "_afpovertcp._tcp"
21
22
/* prototype definitions */
23
void* bo_zeroconf_setup(unsigned long, const char *);
24
int bo_zeroconf_unregister(void);
25
int bo_zeroconf_run(void);
26
27
#endif   /* AFPD_BONJOUR_H */
(-)etc/afpd/afp_bonjour.c.org (+112 lines)
Line 0 Link Here
1
/* -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2 -*- */
2
/*
3
 * Author:  Daniel S. Haischt <me@daniel.stefan.haischt.name>
4
 * Purpose: Bonjour based Zeroconf support
5
 * Docs:    http://developer.apple.com/documentation/Networking/Reference/DNSServiceDiscovery_CRef/dns_sd/
6
 *
7
 */
8
9
#ifdef HAVE_CONFIG_H
10
#include <config.h>
11
#endif
12
13
#ifdef HAVE_BONJOUR
14
15
#include "afp_bonjour.h"
16
17
DNSServiceRef publish_session = NULL;
18
19
static void DNSSD_API
20
publish_reply(DNSServiceRef,
21
              const DNSServiceFlags,
22
              DNSServiceErrorType,
23
              const char *,
24
              const char *,
25
              const char *,
26
              void *);
27
28
static void DNSSD_API
29
publish_reply (DNSServiceRef sdRef,
30
         const DNSServiceFlags flags,
31
         DNSServiceErrorType errorCode,
32
         const char *name,
33
         const char *regtype,
34
         const char *domain,
35
         void *context)
36
{
37
}
38
39
void* bo_zeroconf_setup(unsigned long port, const char *name) {
40
  DNSServiceErrorType err;
41
  char service[256] = "AFP Server on ";
42
43
  /* Prepare service name */
44
  if (!name) {
45
    LOG(log_info, logtype_afpd,, "Assigning default service name.\n");
46
    gethostname(service+14, sizeof(service)-15);
47
    service[sizeof(service)-1] = 0;
48
49
    name = strdup(service);
50
  }
51
52
  assert(name);
53
  assert(port);
54
55
  err = DNSServiceRegister (&publish_session,
56
                            0,                    /* flags */
57
                            0,                    /* interface; 0 for all */
58
                            name,                 /* name */
59
                            AFP_DNS_SERVICE_TYPE, /* type */
60
                            NULL,                 /* domain */
61
                            NULL,                 /* hostname */
62
                            htons (port),         /* port in network byte order */
63
                            0,                    /* text record length */
64
                            NULL,                 /* text record */
65
                            publish_reply,        /* callback */
66
                            NULL);                /* context */
67
68
  if (err == kDNSServiceErr_NoError) {
69
    LOG(log_info, logtype_afpd, "Adding service '%s'\n", name);
70
  } else {
71
    LOG(log_error, logtype_afpd, "Adding service '%s' failed\n", name);
72
    bo_zeroconf_unregister();
73
  }
74
}
75
76
int bo_zeroconf_run(void) {
77
  fd_set set;
78
  int fd;
79
  struct timeval timeout;
80
81
  /* Initialize the file descriptor set. */
82
  FD_ZERO (&set);
83
  FD_SET (fd, &set);
84
85
  /* Initialize the timeout data structure. */
86
  /* TODO: Should the value for sec be configurable? */
87
  timeout.tv_sec = 10;
88
  timeout.tv_usec = 0;
89
90
  if (publish_session != NULL) {
91
    fd = DNSServiceRefSockFD(publish_session);
92
93
    if (select(FD_SETSIZE,
94
                  &set, NULL, NULL,
95
                  &timeout) > 0) {
96
      DNSServiceProcessResult(publish_session);
97
    }
98
  }
99
100
  return 0;
101
}
102
103
int bo_zeroconf_unregister(void) {
104
  if (publish_session != NULL) {
105
    DNSServiceRefDeallocate(publish_session);
106
    publish_session = NULL;
107
  }
108
109
  return 0;
110
}
111
112
#endif /* HAVE_BONJOUR */
(-)etc/afpd/afp_howl.c.org (+92 lines)
Line 0 Link Here
1
/* -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2 -*- */
2
/*
3
 * Author:  Daniel S. Haischt <me@daniel.stefan.haischt.name>
4
 * Purpose: Howl based Zeroconf support
5
 * Doc:     http://www.porchdogsoft.com/products/howl/docs/
6
 *
7
 */
8
9
#ifdef HAVE_CONFIG_H
10
#include <config.h>
11
#endif
12
13
#ifdef HAVE_HOWL
14
15
#include "afp_howl.h"
16
17
sw_discovery discovery = NULL;
18
19
static sw_result HOWL_API publish_reply(sw_discovery,
20
                                        sw_discovery_oid,
21
                                        sw_discovery_publish_status,
22
                                        sw_opaque);
23
24
static sw_result HOWL_API publish_reply(sw_discovery discovery,
25
                                        sw_discovery_oid oid,
26
                                        sw_discovery_publish_status status,
27
                                        sw_opaque extra) {
28
  static sw_string
29
    status_text[] =
30
    {
31
      "Started",
32
      "Stopped",
33
      "Name Collision",
34
      "Invalid"
35
    };
36
37
  LOG(log_info, logtype_afpd, "publish reply: %s\n", status_text[status]);
38
  return SW_OKAY;
39
}
40
41
void* ho_zeroconf_setup(unsigned long port, const char *name) {
42
  sw_result result;
43
  sw_discovery_publish_id id;
44
  char service[256] = "AFP Server on ";
45
46
  if (sw_discovery_init (&discovery) != SW_OKAY) {
47
    LOG(log_error,
48
        logtype_afpd,
49
        "AFPD could not be started. \nTry running mDNSResponder.");
50
    return;
51
  }
52
53
  /* Prepare service name */
54
  if (!name) {
55
    LOG(log_info, logtype_afpd, "Assigning default service name.\n");
56
    gethostname(service+14, sizeof(service)-15);
57
    service[sizeof(service)-1] = 0;
58
59
    name = strdup(service);
60
  }
61
62
  assert(name);
63
64
  if (!(result = sw_discovery_publish (discovery,
65
                                       0,
66
                                       name,
67
                                       AFP_DNS_SERVICE_TYPE,
68
                                       NULL,
69
                                       NULL,
70
                                       port,
71
                                       NULL,
72
                                       0,
73
                                       publish_reply,
74
                                       NULL,
75
                                       &id)) != SW_OKAY) {
76
    LOG(log_info, logtype_afpd, "Adding service '%s'\n", name);
77
  } else {
78
    LOG(log_error, logtype_afpd, "Adding service '%s' failed\n", name);
79
    ho_zeroconf_unregister();
80
  }
81
}
82
83
void* ho_zeroconf_run(void) {
84
  sw_discovery_run(discovery);
85
}
86
87
void* ho_zeroconf_unregister(void) {
88
  sw_discovery_stop_run(discovery);
89
  sw_discovery_fina(discovery);
90
}
91
92
#endif /* USE_HOWL */
(-)etc/afpd/afp_howl.h.org (+27 lines)
Line 0 Link Here
1
/* -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2 -*- */
2
/*
3
 * Author:  Daniel S. Haischt <me@daniel.stefan.haischt.name>
4
 * Purpose: Howl based Zeroconf support
5
 * Doc:     http://www.porchdogsoft.com/products/howl/docs/
6
 *
7
 */
8
9
#ifndef AFPD_HOWL_H
10
#define AFPD_HOWL_H
11
12
#include <stdlib.h>
13
#include <assert.h>
14
#include <string.h>
15
16
#include <howl.h>
17
18
#include <atalk/logger.h>
19
20
#define NTP_DNS_SERVICE_TYPE "_afpovertcp._tcp"
21
22
/* prototype definitions */
23
void* ho_zeroconf_setup(unsigned long, const char *);
24
void* ho_zeroconf_unregister(void);
25
void* ho_zeroconf_run(void);
26
27
#endif   /* AFPD_HOWL_H */
(-)etc/afpd/afp_zeroconf.h.org (+40 lines)
Line 0 Link Here
1
/* -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2 -*- */
2
/*
3
 * Author:  Daniel S. Haischt <me@daniel.stefan.haischt.name>
4
 * Purpose: Zeroconf facade, that abstracts access to a
5
 *          particular Zeroconf implementation
6
 * Doc:     http://www.dns-sd.org/
7
 *
8
 */
9
10
#ifndef AFPD_ZEROCONF_H
11
#define AFPD_ZEROCONF_H
12
13
#include <netinet/in.h> /* htons() */
14
#include <atalk/logger.h>
15
16
# ifdef HAVE_BONJOUR
17
# include "afp_bonjour.h"
18
# elif defined (HAVE_HOWL)
19
# include "afp_howl.h"
20
# elif defined (HAVE_AVAHI)
21
# include "afp_avahi.h"
22
# endif
23
24
#define AFP_PORT 548
25
26
/*
27
 * Prototype Definitions
28
 */
29
30
/*
31
 * registers the ntpd service with a particular Zerconf implemenation.
32
 */
33
void zeroconf_register(int port, char *hostname);
34
35
/*
36
 * de-registers the ntpd service with a particular Zerconf implemenation.
37
 */
38
void zeroconf_deregister(void);
39
40
#endif AFPD_ZEROCONF_H
(-)etc/afpd/afp_zeroconf.c.org (+97 lines)
Line 0 Link Here
1
/* -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2 -*- */
2
/*
3
 * Author:  Daniel S. Haischt <me@daniel.stefan.haischt.name>
4
 * Purpose: Zeroconf facade, that abstracts access to a
5
 *          particular Zeroconf implementation
6
 * Doc:     http://www.dns-sd.org/
7
 *
8
 */
9
10
#ifdef HAVE_CONFIG_H
11
#include <config.h>
12
#endif
13
14
#include "afp_zeroconf.h"
15
16
/*
17
 * Global Definitions
18
 */
19
#ifdef HAVE_AVAHI
20
struct context *ctx = NULL;
21
#endif
22
23
/*
24
 * Functions (actually they are just facades)
25
 */
26
void zeroconf_register(int port, char *hostname)
27
{
28
#ifdef HAVE_BONJOUR
29
  LOG(log_info,
30
      logtype_afpd,
31
      "Attempting to register with mDNS using Apple's Bonjour\n");
32
  if (hostname && strlen(hostname) > 0 && port)
33
  {
34
    bo_zeroconf_setup(port, hostname);
35
  }
36
  else if (hostname && strlen(hostname) > 0)
37
  {
38
    bo_zeroconf_setup(AFP_PORT, hostname);
39
  }
40
  else
41
  {
42
    bo_zeroconf_setup(AFP_PORT, NULL);
43
  }
44
  bo_zeroconf_run();
45
#elif defined (HAVE_HOWL)
46
  LOG(log_info,
47
      logtype_afpd,
48
      "Attempting to register with mDNS using Porchdog's Howl\n");
49
  if (hostname && strlen(hostname) > 0 && port)
50
  {
51
    ho_zeroconf_setup(port, hostname);
52
  }
53
  else if (hostname && strlen(hostname) > 0)
54
  {
55
    ho_zeroconf_setup(AFP_PORT, hostname);
56
  }
57
  else
58
  {
59
    ho_zeroconf_setup(AFP_PORT, NULL);
60
  }
61
  bo_zeroconf_run();
62
#elif defined (HAVE_AVAHI)
63
  LOG(log_info, logtype_afpd, "Attempting to register with mDNS using Avahi\n");
64
  if (hostname && strlen(hostname) > 0 && port)
65
  {
66
    ctx = av_zeroconf_setup(port, hostname);
67
  }
68
  else if (hostname && strlen(hostname) > 0)
69
  {
70
    ctx = av_zeroconf_setup(AFP_PORT, hostname);
71
  }
72
  else
73
  {
74
    ctx = av_zeroconf_setup(AFP_PORT, NULL);
75
  }
76
  av_zeroconf_run(ctx);
77
#endif
78
}
79
80
void zeroconf_deregister(void)
81
{
82
#ifdef HAVE_BONJOUR
83
  LOG(log_error,
84
      logtype_afpd,
85
      "Attempting to de-register mDNS using Apple's Bonjour\n");
86
  bo_zeroconf_unregister();
87
#elif defined (HAVE_HOWL)
88
  LOG(log_error,
89
      logtype_afpd,
90
      "Attempting to de-register mDNS using Porchdog's Howl\n");
91
  ho_zeroconf_unregister();
92
#elif defined (HAVE_AVAHI)
93
  LOG(log_error, logtype_afpd, "Attempting to de-register mDNS using Avahi\n");
94
  if (ctx)
95
    av_zeroconf_shutdown(ctx);
96
#endif
97
}
(-)macros/zeroconf.m4.org (+101 lines)
Line 0 Link Here
1
dnl Check for optional Zeroconf support
2
3
dnl $Id: $
4
5
AC_DEFUN([NETATALK_ZEROCONF], [
6
7
	ZEROCONF_LIBS=""
8
	ZEROCONF_CFLAGS=""
9
	found_zeroconf=no
10
	zeroconf_dir=""
11
12
	AC_ARG_ENABLE(zeroconf,
13
		[  --enable-zeroconf[[=DIR]]   enable Zeroconf support [[auto]]],
14
		[zeroconf=$enableval],
15
		[zeroconf=try]
16
	)
17
18
    dnl make sure atalk_libname is defined beforehand
19
    [[ -n "$atalk_libname" ]] || AC_MSG_ERROR([internal error, atalk_libname undefined])
20
21
	if test "x$zeroconf" != "xno"; then
22
23
		savedcppflags="$CPPFLAGS"
24
		savedldflags="$LDFLAGS"
25
26
		if test "x$zeroconf" = "xyes" -o "x$zeroconf" = "xtry"; then
27
			zeroconf_dir="/usr"
28
		else
29
			zeroconf_dir="$zeroconf"
30
		fi
31
32
		# mDNS support using Apple's Bonjour
33
		AC_CHECK_HEADER(dns_sd.h,
34
		  [AC_CHECK_LIB(dns_sd,
35
		    DNSServiceRegister,
36
				  [AC_DEFINE(USE_ZEROCONF, 1,
37
				  	[Use DNS-SD registration])])])
38
  	case "$ac_cv_lib_dns_sd_DNSServiceRegister" in
39
      yes)
40
      ZEROCONF_LIBS="-L$zeroconf_dir/lib -ldns_sd"
41
      ZEROCONF_LIBS="-I$zeroconf_dir/include"
42
      AC_DEFINE(HAVE_BONJOUR, 1, [Use Bonjour/DNS-SD registration])
43
      found_zeroconf=yes
44
      ;;
45
    esac
46
    # mDNS support using Porchdog's Howl
47
    AC_CHECK_HEADER(howl.h,
48
      [AC_CHECK_LIB(howl,
49
        sw_discovery_publish,
50
        [AC_DEFINE(USE_ZEROCONF, 1,
51
          [Use DNS-SD registration])])])
52
    case "$ac_cv_lib_howl_sw_discovery_publish" in
53
      yes)
54
      PKG_CHECK_MODULES(HOWL, [ howl >= 1.0.0 ])
55
      ZEROCONF_LIBS="$HOWL_LIBS"
56
      ZEROCONF_CFLAGS="$HOWL_CFLAGS"
57
      AC_DEFINE(HAVE_HOWL, 1, [Use Howl/DNS-SD registration])
58
      found_zeroconf=yes
59
      ;;
60
    esac
61
    # mDNS support using Avahi
62
    AC_CHECK_HEADER(avahi-client/client.h,
63
      [AC_CHECK_LIB(avahi-client,
64
        avahi_client_new,
65
				[AC_DEFINE(USE_ZEROCONF, 1,
66
          [Use DNS-SD registration])])])
67
    case "$ac_cv_lib_avahi_client_avahi_client_new" in
68
      yes)
69
      PKG_CHECK_MODULES(AVAHI, [ avahi-client >= 0.6 ])
70
      PKG_CHECK_MODULES(AVAHI_TPOLL, [ avahi-client >= 0.6.4 ],
71
        [AC_DEFINE(HAVE_AVAHI_THREADED_POLL, 1, [Uses Avahis threaded poll implementation])],
72
        [AC_MSG_WARN(This Avahi implementation is not supporting threaded poll objects. Maybe this is not what you want.)])
73
      ZEROCONF_LIBS="$AVAHI_LIBS"
74
      ZEROCONF_CFLAGS="$AVAHI_CFLAGS"
75
      AC_DEFINE(HAVE_AVAHI, 1, [Use Avahi/DNS-SD registration])
76
      found_zeroconf=yes
77
      ;;
78
    esac
79
80
		CPPFLAGS="$savedcppflags"
81
		LDFLAGS="$savedldflags"
82
	fi
83
	
84
	netatalk_cv_zeroconf=no
85
	AC_MSG_CHECKING([whether to enable Zerconf support])
86
	if test "x$found_zeroconf" = "xyes"; then
87
		AC_MSG_RESULT([yes])
88
		AC_DEFINE(USE_ZEROCONF, 1, [Define to enable Zeroconf support])
89
		netatalk_cv_zeroconf=yes
90
	else
91
		AC_MSG_RESULT([no])
92
		if test "x$zeroconf" != "xno" -a "x$zeroconf" != "xtry"; then
93
			AC_MSG_ERROR([Zeroconf installation not found])
94
		fi
95
	fi
96
97
	LIB_REMOVE_USR_LIB(ZEROCONF_LIBS)
98
	CFLAGS_REMOVE_USR_INCLUDE(ZEROCONF_CFLAGS)
99
	AC_SUBST(ZEROCONF_LIBS)
100
	AC_SUBST(ZEROCONF_CFLAGS)
101
])

Return to bug 133575