[SCM] Samba Shared Repository - branch v3-4-test updated - release-4-0-0alpha7-567-g55b7bf7

Volker Lendecke vlendec at samba.org
Mon Mar 23 16:11:07 GMT 2009


The branch, v3-4-test has been updated
       via  55b7bf7338c13701944169df02ab8e9def6d43a1 (commit)
       via  49fc1138b5e4dcf66b84a14ba47cc1da40c764f2 (commit)
       via  b943e0083f6b0daa226f395158fcf7f467cdacd0 (commit)
       via  8cf21c9c7121049329f4d3e86d3021cdd2dec86a (commit)
      from  11b3f0d8deb629489de4de29cedf518adc86d196 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-4-test


- Log -----------------------------------------------------------------
commit 55b7bf7338c13701944169df02ab8e9def6d43a1
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 49fc1138b5e4dcf66b84a14ba47cc1da40c764f2
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Mar 20 14:55:05 2009 +0100

    Add tevent avahi binding

commit b943e0083f6b0daa226f395158fcf7f467cdacd0
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Mar 20 14:53:10 2009 +0100

    Add avahi detection to configure

commit 8cf21c9c7121049329f4d3e86d3021cdd2dec86a
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Mar 20 14:39:19 2009 +0100

    Disable dns_sd by default

-----------------------------------------------------------------------

Summary of changes:
 source3/Makefile.in           |    9 +-
 source3/configure.in          |   40 ++++++-
 source3/include/proto.h       |   10 ++
 source3/lib/avahi.c           |  268 +++++++++++++++++++++++++++++++++++++++++
 source3/smbd/avahi_register.c |  170 ++++++++++++++++++++++++++
 source3/smbd/server.c         |   11 ++
 6 files changed, 503 insertions(+), 5 deletions(-)
 create mode 100644 source3/lib/avahi.c
 create mode 100644 source3/smbd/avahi_register.c


Changeset truncated at 500 lines:

diff --git a/source3/Makefile.in b/source3/Makefile.in
index 5ee3f64..8e57546 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -73,6 +73,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@
@@ -256,6 +257,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
@@ -731,7 +734,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@ \
@@ -1375,7 +1378,7 @@ bin/smbd at EXEEXT@: $(BINARY_PREREQS) $(SMBD_OBJ) @LIBTALLOC_SHARED@ @LIBTDB_SHARE
 	@echo Linking $@
 	@$(CC) -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) $(ZLIB_LIBS)
 
@@ -1561,7 +1564,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) -o $@ $(VFSTEST_OBJ) $(LDFLAGS) $(TERMLDFLAGS) \
+	@$(CC) -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/source3/configure.in b/source3/configure.in
index e59386a..22bbe06 100644
--- a/source3/configure.in
+++ b/source3/configure.in
@@ -5972,10 +5972,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)
@@ -6004,6 +6004,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/source3/include/proto.h b/source3/include/proto.h
index dc26f6d..e6e925e 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -7217,6 +7217,16 @@ 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 tevent_context *ev);
+
+/* The following definitions come from smbd/avahi_register.c */
+
+void *avahi_start_register(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
+			   uint16_t port);
+
 /* Misc protos */
 
 #endif /*  _PROTO_H_  */
diff --git a/source3/lib/avahi.c b/source3/lib/avahi.c
new file mode 100644
index 0000000..ac9867a
--- /dev/null
+++ b/source3/lib/avahi.c
@@ -0,0 +1,268 @@
+/*
+   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 tevent_context *ev;
+	AvahiWatch **watches;
+	AvahiTimeout **timeouts;
+};
+
+struct AvahiWatch {
+	struct avahi_poll_context *ctx;
+	struct tevent_fd *fde;
+	int fd;
+	AvahiWatchEvent latest_event;
+	AvahiWatchCallback callback;
+	void *userdata;
+};
+
+struct AvahiTimeout {
+	struct avahi_poll_context *ctx;
+	struct tevent_timer *te;
+	AvahiTimeoutCallback callback;
+	void *userdata;
+};
+
+static uint16_t avahi_flags_map_to_tevent(AvahiWatchEvent event)
+{
+	return ((event & AVAHI_WATCH_IN) ? TEVENT_FD_READ : 0)
+		| ((event & AVAHI_WATCH_OUT) ? TEVENT_FD_WRITE : 0);
+}
+
+static void avahi_fd_handler(struct tevent_context *ev,
+			     struct tevent_fd *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_array_length(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 = tevent_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 tevent_context *ev,
+			     struct tevent_fd *fde, uint16_t flags,
+			     void *private_data)
+{
+	AvahiWatch *watch_ctx = talloc_get_type_abort(private_data, AvahiWatch);
+
+	watch_ctx->latest_event =
+		((flags & TEVENT_FD_READ) ? AVAHI_WATCH_IN : 0)
+		| ((flags & TEVENT_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)
+{
+	tevent_fd_set_flags(w->fde, avahi_flags_map_to_tevent(event));
+}
+
+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_array_length(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 tevent_context *ev,
+				  struct tevent_timer *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_array_length(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 = tevent_add_timer(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 tevent_context *ev,
+				  struct tevent_timer *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 = tevent_add_timer(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_array_length(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 tevent_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/source3/smbd/avahi_register.c b/source3/smbd/avahi_register.c
new file mode 100644
index 0000000..1903b0e
--- /dev/null
+++ b/source3/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",
+				   avahi_strerror(error)));
+			break;
+		}
+		if (avahi_entry_group_add_service(
+			    state->entry_group, AVAHI_IF_UNSPEC,
+			    AVAHI_PROTO_UNSPEC, 0, global_myname(),
+			    "_smb._tcp", NULL, NULL, state->port, NULL) < 0) {


-- 
Samba Shared Repository


More information about the samba-cvs mailing list