[SCM] Samba Shared Repository - branch v3-3-test updated -
release-3-2-0pre2-5162-gb0ad526
Volker Lendecke
vlendec at samba.org
Mon Mar 23 16:09:36 GMT 2009
The branch, v3-3-test has been updated
via b0ad52693d4ee548a2d3870e28f6499f827bed31 (commit)
via cb18c1686b3cd20f0535458f8cee24a772560350 (commit)
via dcf1df139f02d54f040e0e649f6b9bf388fdfb00 (commit)
via 28abdd1ee9559bf53cbbc3372d947cbb77ea1cd5 (commit)
from 86abc613f119e7685f0664033317b5d191cc88e8 (commit)
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-3-test
- Log -----------------------------------------------------------------
commit b0ad52693d4ee548a2d3870e28f6499f827bed31
Author: Volker Lendecke <vl at samba.org>
Date: Sun Mar 22 15:59:33 2009 +0100
Use avahi to register _smb._tcp in smbd
commit cb18c1686b3cd20f0535458f8cee24a772560350
Author: Volker Lendecke <vl at samba.org>
Date: Fri Mar 20 14:55:05 2009 +0100
Add event avahi binding
commit dcf1df139f02d54f040e0e649f6b9bf388fdfb00
Author: Volker Lendecke <vl at samba.org>
Date: Fri Mar 20 14:53:10 2009 +0100
Add avahi detection to configure
commit 28abdd1ee9559bf53cbbc3372d947cbb77ea1cd5
Author: Volker Lendecke <vl at samba.org>
Date: Fri Mar 20 14:39:19 2009 +0100
Disable dns_sd by default
-----------------------------------------------------------------------
Summary of changes:
source/Makefile.in | 9 +-
source/configure.in | 40 ++++++-
source/include/proto.h | 10 ++
source/lib/avahi.c | 277 ++++++++++++++++++++++++++++++++++++++++++
source/smbd/avahi_register.c | 170 ++++++++++++++++++++++++++
source/smbd/server.c | 23 +++-
6 files changed, 518 insertions(+), 11 deletions(-)
create mode 100644 source/lib/avahi.c
create mode 100644 source/smbd/avahi_register.c
Changeset truncated at 500 lines:
diff --git a/source/Makefile.in b/source/Makefile.in
index ee22703..0500d73 100644
--- a/source/Makefile.in
+++ b/source/Makefile.in
@@ -69,6 +69,7 @@ WINBIND_NSS_EXTRA_LIBS=@WINBIND_NSS_EXTRA_LIBS@
WINBIND_NSS_PTHREAD=@WINBIND_NSS_PTHREAD@
PAM_WINBIND_EXTRA_LIBS=@PAM_WINBIND_EXTRA_LIBS@
DNSSD_LIBS=@DNSSD_LIBS@
+AVAHI_LIBS=@AVAHI_LIBS@
POPT_LIBS=@POPTLIBS@
LIBTALLOC_LIBS=@LIBTALLOC_LIBS@
LIBTDB_LIBS=@LIBTDB_LIBS@
@@ -250,6 +251,8 @@ AFS_OBJ = lib/afs.o
AFS_SETTOKEN_OBJ = lib/afs_settoken.o
+AVAHI_OBJ = @AVAHI_OBJ@
+
SERVER_MUTEX_OBJ = lib/server_mutex.o
PASSCHANGE_OBJ = libsmb/passchange.o
@@ -688,7 +691,7 @@ SMBD_OBJ_BASE = $(PARAM_WITHOUT_REG_OBJ) $(SMBD_OBJ_SRV) $(LIBSMB_OBJ) \
$(LOCKING_OBJ) $(PASSDB_OBJ) $(PRINTING_OBJ) $(PROFILE_OBJ) \
$(LIB_OBJ) $(PRINTBACKEND_OBJ) $(OPLOCK_OBJ) \
$(NOTIFY_OBJ) $(GROUPDB_OBJ) $(AUTH_OBJ) \
- $(LIBMSRPC_OBJ) $(LIBMSRPC_GEN_OBJ) \
+ $(LIBMSRPC_OBJ) $(LIBMSRPC_GEN_OBJ) $(AVAHI_OBJ) \
$(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(LIBADS_SERVER_OBJ) \
$(REG_FULL_OBJ) $(POPT_LIB_OBJ) $(BUILDOPT_OBJ) \
$(SMBLDAP_OBJ) $(LDB_OBJ) $(LIBNET_OBJ) @LIBWBCLIENT_STATIC@ \
@@ -1328,7 +1331,7 @@ bin/smbd at EXEEXT@: $(BINARY_PREREQS) $(SMBD_OBJ) @LIBTALLOC_SHARED@ @LIBTDB_SHARE
@echo Linking $@
@$(CC) $(FLAGS) -o $@ $(SMBD_OBJ) $(LDFLAGS) $(LDAP_LIBS) \
$(KRB5LIBS) $(DYNEXP) $(PRINT_LIBS) $(AUTH_LIBS) \
- $(ACL_LIBS) $(PASSDB_LIBS) $(LIBS) $(DNSSD_LIBS) \
+ $(ACL_LIBS) $(PASSDB_LIBS) $(LIBS) $(DNSSD_LIBS) $(AVAHI_LIBS) \
$(POPT_LIBS) @SMBD_LIBS@ $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) \
$(WINBIND_LIBS)
@@ -1513,7 +1516,7 @@ bin/pdbtest at EXEEXT@: $(BINARY_PREREQS) $(PDBTEST_OBJ) @BUILD_POPT@ @LIBTALLOC_SH
bin/vfstest at EXEEXT@: $(BINARY_PREREQS) $(VFSTEST_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(VFSTEST_OBJ) $(LDFLAGS) $(TERMLDFLAGS) \
+ @$(CC) $(FLAGS) -o $@ $(VFSTEST_OBJ) $(LDFLAGS) $(TERMLDFLAGS) $(AVAHI_LIBS) \
$(TERMLIBS) $(DYNEXP) $(PRINT_LIBS) $(AUTH_LIBS) $(DNSSD_LIBS) \
$(ACL_LIBS) $(LIBS) $(POPT_LIBS) $(KRB5LIBS) $(LDAP_LIBS) \
@SMBD_LIBS@ $(NSCD_LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) \
diff --git a/source/configure.in b/source/configure.in
index 95dd67d..8a1f7fc 100644
--- a/source/configure.in
+++ b/source/configure.in
@@ -6168,10 +6168,10 @@ AC_SUBST(FLAGS1)
# Check if user wants DNS service discovery support
AC_ARG_ENABLE(dnssd,
-[AS_HELP_STRING([--enable-dnssd], [Enable DNS service discovery support (default=auto)])])
+[AS_HELP_STRING([--enable-dnssd], [Enable DNS service discovery support (default=no)])])
AC_SUBST(DNSSD_LIBS)
-if test x"$enable_dnssd" != x"no"; then
+if test x"$enable_dnssd" == x"yes"; then
have_dnssd_support=yes
AC_CHECK_HEADERS(dns_sd.h)
@@ -6200,6 +6200,42 @@ if test x"$enable_dnssd" != x"no"; then
fi
#################################################
+# Check if user wants avahi support
+
+AC_ARG_ENABLE(avahi,
+[AS_HELP_STRING([--enable-avahi], [Enable Avahi support (default=auto)])])
+
+AC_SUBST(AVAHI_LIBS)
+if test x"$enable_avahi" != x"no"; then
+ have_avahi_support=yes
+
+ AC_CHECK_HEADERS(avahi-common/watch.h)
+ if test x"$ac_cv_header_avahi_common_watch_h" != x"yes"; then
+ have_avahi_support=no
+ fi
+
+ AC_CHECK_HEADERS(avahi-client/client.h)
+ if test x"$ac_cv_header_avahi_common_watch_h" != x"yes"; then
+ have_avahi_support=no
+ fi
+
+ AC_CHECK_LIB_EXT(avahi-client, AVAHI_LIBS, avahi_client_new)
+ if test x"$ac_cv_lib_ext_avahi_client_avahi_client_new" != x"yes"; then
+ have_avahi_support=no
+ fi
+
+ if test x"$have_avahi_support" = x"yes"; then
+ AC_DEFINE(WITH_AVAHI_SUPPORT, 1,
+ [Whether to enable avahi support])
+ AC_SUBST(AVAHI_OBJ, "lib/avahi.o smbd/avahi_register.o")
+ else
+ if test x"$enable_avahi" = x"yes"; then
+ AC_MSG_ERROR(avahi support not available)
+ fi
+ fi
+fi
+
+#################################################
# Check to see if we should use the included iniparser
AC_ARG_WITH(included-iniparser,
diff --git a/source/include/proto.h b/source/include/proto.h
index c2b318e..794742c 100644
--- a/source/include/proto.h
+++ b/source/include/proto.h
@@ -9751,4 +9751,14 @@ NTSTATUS idmap_sid_to_gid(const char *domname, DOM_SID *sid, gid_t *gid);
NTSTATUS nss_info_template_init( void );
+/* The following definitions come from lib/avahi.c */
+
+struct AvahiPoll *tevent_avahi_poll(TALLOC_CTX *mem_ctx,
+ struct event_context *ev);
+
+/* The following definitions come from smbd/avahi_register.c */
+
+void *avahi_start_register(TALLOC_CTX *mem_ctx, struct event_context *ev,
+ uint16_t port);
+
#endif /* _PROTO_H_ */
diff --git a/source/lib/avahi.c b/source/lib/avahi.c
new file mode 100644
index 0000000..bdc58cb
--- /dev/null
+++ b/source/lib/avahi.c
@@ -0,0 +1,277 @@
+/*
+ Unix SMB/CIFS implementation.
+ Connect avahi to lib/tevents
+ Copyright (C) Volker Lendecke 2009
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+
+#include <avahi-common/watch.h>
+
+struct avahi_poll_context {
+ struct event_context *ev;
+ AvahiWatch **watches;
+ AvahiTimeout **timeouts;
+};
+
+struct AvahiWatch {
+ struct avahi_poll_context *ctx;
+ struct fd_event *fde;
+ int fd;
+ AvahiWatchEvent latest_event;
+ AvahiWatchCallback callback;
+ void *userdata;
+};
+
+struct AvahiTimeout {
+ struct avahi_poll_context *ctx;
+ struct timed_event *te;
+ AvahiTimeoutCallback callback;
+ void *userdata;
+};
+
+static uint16_t avahi_flags_map_to_tevent(AvahiWatchEvent event)
+{
+ return ((event & AVAHI_WATCH_IN) ? EVENT_FD_READ : 0)
+ | ((event & AVAHI_WATCH_OUT) ? EVENT_FD_WRITE : 0);
+}
+
+static void avahi_fd_handler(struct event_context *ev,
+ struct fd_event *fde, uint16_t flags,
+ void *private_data);
+
+static AvahiWatch *avahi_watch_new(const AvahiPoll *api, int fd,
+ AvahiWatchEvent event,
+ AvahiWatchCallback callback,
+ void *userdata)
+{
+ struct avahi_poll_context *ctx = talloc_get_type_abort(
+ api->userdata, struct avahi_poll_context);
+ int num_watches = talloc_get_size(ctx->watches)/sizeof(*ctx->watches);
+ AvahiWatch **tmp, *watch_ctx;
+
+ tmp = talloc_realloc(ctx, ctx->watches, AvahiWatch *, num_watches + 1);
+ if (tmp == NULL) {
+ return NULL;
+ }
+ ctx->watches = tmp;
+
+ watch_ctx = talloc(tmp, AvahiWatch);
+ if (watch_ctx == NULL) {
+ goto fail;
+ }
+ ctx->watches[num_watches] = watch_ctx;
+
+ watch_ctx->ctx = ctx;
+ watch_ctx->fde = event_add_fd(ctx->ev, watch_ctx, fd,
+ avahi_flags_map_to_tevent(event),
+ avahi_fd_handler, watch_ctx);
+ if (watch_ctx->fde == NULL) {
+ goto fail;
+ }
+ watch_ctx->callback = callback;
+ watch_ctx->userdata = userdata;
+ return watch_ctx;
+
+ fail:
+ TALLOC_FREE(watch_ctx);
+ ctx->watches = talloc_realloc(ctx, ctx->watches, AvahiWatch *,
+ num_watches);
+ return NULL;
+}
+
+static void avahi_fd_handler(struct event_context *ev,
+ struct fd_event *fde, uint16_t flags,
+ void *private_data)
+{
+ AvahiWatch *watch_ctx = talloc_get_type_abort(private_data, AvahiWatch);
+
+ watch_ctx->latest_event =
+ ((flags & EVENT_FD_READ) ? AVAHI_WATCH_IN : 0)
+ | ((flags & EVENT_FD_WRITE) ? AVAHI_WATCH_OUT : 0);
+
+ watch_ctx->callback(watch_ctx, watch_ctx->fd, watch_ctx->latest_event,
+ watch_ctx->userdata);
+}
+
+static void avahi_watch_update(AvahiWatch *w, AvahiWatchEvent event)
+{
+ if (event & AVAHI_WATCH_IN) {
+ event_fd_set_readable(w->fde);
+ } else {
+ event_fd_set_not_readable(w->fde);
+ }
+ if (event & AVAHI_WATCH_OUT) {
+ event_fd_set_writeable(w->fde);
+ } else {
+ event_fd_set_not_writeable(w->fde);
+ }
+}
+
+static AvahiWatchEvent avahi_watch_get_events(AvahiWatch *w)
+{
+ return w->latest_event;
+}
+
+static void avahi_watch_free(AvahiWatch *w)
+{
+ int i, num_watches;
+ AvahiWatch **watches = w->ctx->watches;
+ struct avahi_poll_context *ctx;
+
+ num_watches = talloc_get_size(watches) / sizeof(*watches);
+
+ for (i=0; i<num_watches; i++) {
+ if (w == watches[i]) {
+ break;
+ }
+ }
+ if (i == num_watches) {
+ return;
+ }
+ ctx = w->ctx;
+ TALLOC_FREE(w);
+ memmove(&watches[i], &watches[i+1],
+ sizeof(*watches) * (num_watches - i - 1));
+ ctx->watches = talloc_realloc(ctx, watches, AvahiWatch *,
+ num_watches - 1);
+}
+
+static void avahi_timeout_handler(struct event_context *ev,
+ struct timed_event *te,
+ struct timeval current_time,
+ void *private_data);
+
+static AvahiTimeout *avahi_timeout_new(const AvahiPoll *api,
+ const struct timeval *tv,
+ AvahiTimeoutCallback callback,
+ void *userdata)
+{
+ struct avahi_poll_context *ctx = talloc_get_type_abort(
+ api->userdata, struct avahi_poll_context);
+ int num_timeouts = talloc_get_size(ctx->timeouts)/sizeof(*ctx->timeouts);
+ AvahiTimeout **tmp, *timeout_ctx;
+
+ tmp = talloc_realloc(ctx, ctx->timeouts, AvahiTimeout *,
+ num_timeouts + 1);
+ if (tmp == NULL) {
+ return NULL;
+ }
+ ctx->timeouts = tmp;
+
+ timeout_ctx = talloc(tmp, AvahiTimeout);
+ if (timeout_ctx == NULL) {
+ goto fail;
+ }
+ ctx->timeouts[num_timeouts] = timeout_ctx;
+
+ timeout_ctx->ctx = ctx;
+ if (tv == NULL) {
+ timeout_ctx->te = NULL;
+ } else {
+ timeout_ctx->te = event_add_timed(ctx->ev, timeout_ctx,
+ *tv, avahi_timeout_handler,
+ timeout_ctx);
+ if (timeout_ctx->te == NULL) {
+ goto fail;
+ }
+ }
+ timeout_ctx->callback = callback;
+ timeout_ctx->userdata = userdata;
+ return timeout_ctx;
+
+ fail:
+ TALLOC_FREE(timeout_ctx);
+ ctx->timeouts = talloc_realloc(ctx, ctx->timeouts, AvahiTimeout *,
+ num_timeouts);
+ return NULL;
+}
+
+static void avahi_timeout_handler(struct event_context *ev,
+ struct timed_event *te,
+ struct timeval current_time,
+ void *private_data)
+{
+ AvahiTimeout *timeout_ctx = talloc_get_type_abort(
+ private_data, AvahiTimeout);
+
+ TALLOC_FREE(timeout_ctx->te);
+ timeout_ctx->callback(timeout_ctx, timeout_ctx->userdata);
+}
+
+static void avahi_timeout_update(AvahiTimeout *t, const struct timeval *tv)
+{
+ TALLOC_FREE(t->te);
+
+ t->te = event_add_timed(t->ctx->ev, t, *tv, avahi_timeout_handler, t);
+ /*
+ * No failure mode defined here
+ */
+ SMB_ASSERT(t->te != NULL);
+}
+
+static void avahi_timeout_free(AvahiTimeout *t)
+{
+ int i, num_timeouts;
+ AvahiTimeout **timeouts = t->ctx->timeouts;
+ struct avahi_poll_context *ctx;
+
+ num_timeouts = talloc_get_size(timeouts)/sizeof(*timeouts);
+
+ for (i=0; i<num_timeouts; i++) {
+ if (t == timeouts[i]) {
+ break;
+ }
+ }
+ if (i == num_timeouts) {
+ return;
+ }
+ ctx = t->ctx;
+ TALLOC_FREE(t);
+ memmove(&timeouts[i], &timeouts[i+1],
+ sizeof(*timeouts) * (num_timeouts - i - 1));
+ ctx->timeouts = talloc_realloc(ctx, timeouts, AvahiTimeout *,
+ num_timeouts - 1);
+}
+
+struct AvahiPoll *tevent_avahi_poll(TALLOC_CTX *mem_ctx,
+ struct event_context *ev)
+{
+ struct AvahiPoll *result;
+ struct avahi_poll_context *ctx;
+
+ result = talloc(mem_ctx, struct AvahiPoll);
+ if (result == NULL) {
+ return result;
+ }
+ ctx = talloc_zero(result, struct avahi_poll_context);
+ if (ctx == NULL) {
+ TALLOC_FREE(result);
+ return NULL;
+ }
+ ctx->ev = ev;
+
+ result->watch_new = avahi_watch_new;
+ result->watch_update = avahi_watch_update;
+ result->watch_get_events = avahi_watch_get_events;
+ result->watch_free = avahi_watch_free;
+ result->timeout_new = avahi_timeout_new;
+ result->timeout_update = avahi_timeout_update;
+ result->timeout_free = avahi_timeout_free;
+ result->userdata = ctx;
+
+ return result;
+}
diff --git a/source/smbd/avahi_register.c b/source/smbd/avahi_register.c
new file mode 100644
index 0000000..95cb6d1
--- /dev/null
+++ b/source/smbd/avahi_register.c
@@ -0,0 +1,170 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Register _smb._tcp with avahi
+ *
+ * Copyright (C) Volker Lendecke 2009
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "includes.h"
+
+#include <avahi-client/client.h>
+#include <avahi-client/publish.h>
+#include <avahi-common/error.h>
+
+struct avahi_state_struct {
+ struct AvahiPoll *poll;
+ AvahiClient *client;
+ AvahiEntryGroup *entry_group;
+ uint16_t port;
+};
+
+static void avahi_entry_group_callback(AvahiEntryGroup *g,
+ AvahiEntryGroupState status,
+ void *userdata)
+{
+ struct avahi_state_struct *state = talloc_get_type_abort(
+ userdata, struct avahi_state_struct);
+ int error;
+
+ switch (status) {
+ case AVAHI_ENTRY_GROUP_ESTABLISHED:
+ DEBUG(10, ("avahi_entry_group_callback: "
+ "AVAHI_ENTRY_GROUP_ESTABLISHED\n"));
+ break;
+ case AVAHI_ENTRY_GROUP_FAILURE:
+ error = avahi_client_errno(state->client);
+
+ DEBUG(10, ("avahi_entry_group_callback: "
+ "AVAHI_ENTRY_GROUP_FAILURE: %s\n",
+ avahi_strerror(error)));
+ break;
+ case AVAHI_ENTRY_GROUP_COLLISION:
+ DEBUG(10, ("avahi_entry_group_callback: "
+ "AVAHI_ENTRY_GROUP_COLLISION\n"));
+ break;
+ case AVAHI_ENTRY_GROUP_UNCOMMITED:
+ DEBUG(10, ("avahi_entry_group_callback: "
+ "AVAHI_ENTRY_GROUP_UNCOMMITED\n"));
+ break;
+ case AVAHI_ENTRY_GROUP_REGISTERING:
+ DEBUG(10, ("avahi_entry_group_callback: "
+ "AVAHI_ENTRY_GROUP_REGISTERING\n"));
+ break;
+ }
+}
+
+static void avahi_client_callback(AvahiClient *c, AvahiClientState status,
+ void *userdata)
+{
+ struct avahi_state_struct *state = talloc_get_type_abort(
+ userdata, struct avahi_state_struct);
+ int error;
+
+ switch (status) {
+ case AVAHI_CLIENT_S_RUNNING:
+ DEBUG(10, ("avahi_client_callback: AVAHI_CLIENT_S_RUNNING\n"));
+
+ state->entry_group = avahi_entry_group_new(
+ c, avahi_entry_group_callback, state);
+ if (state->entry_group == NULL) {
+ error = avahi_client_errno(c);
+ DEBUG(10, ("avahi_entry_group_new failed: %s\n",
--
Samba Shared Repository
More information about the samba-cvs
mailing list