diff options
author | Volker Lendecke <vl@samba.org> | 2009-03-20 14:55:05 +0100 |
---|---|---|
committer | Karolin Seeger <kseeger@samba.org> | 2009-04-15 09:07:35 +0200 |
commit | 0eb8bfe65f1535c358ba23b8a63e17e40dde8b5d (patch) | |
tree | 271125c7bb5ab9ebfd4ebb4c58cf35aebf7854a9 /source3 | |
parent | 909ad2afeeba31ad45c7c3b8cf94299fd8b4533b (diff) | |
download | samba-0eb8bfe65f1535c358ba23b8a63e17e40dde8b5d.tar.gz samba-0eb8bfe65f1535c358ba23b8a63e17e40dde8b5d.tar.xz samba-0eb8bfe65f1535c358ba23b8a63e17e40dde8b5d.zip |
Add tevent avahi binding
(cherry picked from commit 49fc1138b5e4dcf66b84a14ba47cc1da40c764f2)
Diffstat (limited to 'source3')
-rw-r--r-- | source3/Makefile.in | 8 | ||||
-rw-r--r-- | source3/configure.in | 2 | ||||
-rw-r--r-- | source3/include/proto.h | 5 | ||||
-rw-r--r-- | source3/lib/avahi.c | 268 |
4 files changed, 279 insertions, 4 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in index 581f2efbe0a..8e575463a01 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -257,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 @@ -732,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@ \ @@ -1376,7 +1378,7 @@ bin/smbd@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) @@ -1562,7 +1564,7 @@ bin/pdbtest@EXEEXT@: $(BINARY_PREREQS) $(PDBTEST_OBJ) @BUILD_POPT@ @LIBTALLOC_SH bin/vfstest@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 11939972b12..b1ffc4371cd 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -6031,12 +6031,12 @@ if test x"$enable_avahi" != x"no"; then 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) else if test x"$enable_avahi" = x"yes"; then AC_MSG_ERROR(avahi support not available) fi fi - fi ################################################# diff --git a/source3/include/proto.h b/source3/include/proto.h index dc26f6d6e52..82d9ae9ba8e 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -7217,6 +7217,11 @@ 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); + /* Misc protos */ #endif /* _PROTO_H_ */ diff --git a/source3/lib/avahi.c b/source3/lib/avahi.c new file mode 100644 index 00000000000..ac9867a1fce --- /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; +} |