diff options
author | Jelmer Vernooij <jelmer@samba.org> | 2008-12-18 14:54:57 +0000 |
---|---|---|
committer | Jelmer Vernooij <jelmer@samba.org> | 2008-12-18 14:54:57 +0000 |
commit | d14c8604653d39dd25736279d34930ee7a3ae103 (patch) | |
tree | 626f700b9b42b798ed7459a5cba5cd27aca9753e /source4/lib | |
parent | 0c0b9c738f0fc1bf8aa64533a5e4e0635b84f58f (diff) | |
parent | fc31f2c5269fd405be96b9a036baf35a60141ccf (diff) | |
download | samba-d14c8604653d39dd25736279d34930ee7a3ae103.tar.gz samba-d14c8604653d39dd25736279d34930ee7a3ae103.tar.bz2 samba-d14c8604653d39dd25736279d34930ee7a3ae103.zip |
Merge branch 'master' of ssh://git.samba.org/data/git/samba into pyregistry
Diffstat (limited to 'source4/lib')
61 files changed, 1160 insertions, 8151 deletions
diff --git a/source4/lib/events/Makefile.in b/source4/lib/events/Makefile.in deleted file mode 100644 index 4257119849..0000000000 --- a/source4/lib/events/Makefile.in +++ /dev/null @@ -1,81 +0,0 @@ -#!gmake -# -# Makefile for tdb directory -# - -CC = @CC@ -prefix = @prefix@ -exec_prefix = @exec_prefix@ -bindir = @bindir@ -includedir = @includedir@ -libdir = @libdir@ -VPATH = @srcdir@:@libreplacedir@ -srcdir = @srcdir@ -builddir = @builddir@ -sharedbuilddir = @sharedbuilddir@ -INSTALLCMD = @INSTALL@ -CPPFLAGS = @CPPFLAGS@ -I$(srcdir)/include -Iinclude -I. -LDFLAGS = @LDFLAGS@ -EXEEXT = @EXEEXT@ -SHLD = @SHLD@ -SHLD_FLAGS = @SHLD_FLAGS@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PICFLAG = @PICFLAG@ -SHLIBEXT = @SHLIBEXT@ -SWIG = swig -PYTHON = @PYTHON@ -PYTHON_CONFIG = @PYTHON_CONFIG@ -PYTHON_BUILD_TARGET = @PYTHON_BUILD_TARGET@ -PYTHON_INSTALL_TARGET = @PYTHON_INSTALL_TARGET@ -PYTHON_CHECK_TARGET = @PYTHON_CHECK_TARGET@ -LIB_PATH_VAR = @LIB_PATH_VAR@ -eventsdir = @eventsdir@ - -TALLOC_CFLAGS = @TALLOC_CFLAGS@ -TALLOC_LDFLAGS = @TALLOC_CFLAGS@ -TALLOC_LIBS = @TALLOC_LIBS@ - -EVENTS_CFLAGS = @EVENTS_CFLAGS@ -EVENTS_LDFLAGS = @EVENTS_CFLAGS@ -EVENTS_LIBS = @EVENTS_LIBS@ - -CFLAGS = $(CPPFLAGS) $(TALLOC_CFLAGS) $(EVENTS_CFLAGS) @CFLAGS@ -LDFLAGS = $(TALLOC_LDFLAGS) $(EVENTS_LDFLAGS) @LDFLAGS@ -LIBS = $(TALLOC_LIBS) $(EVENTS_LIBS) @LIBS@ - -EVENTS_OBJ = @EVENTS_OBJ@ @LIBREPLACEOBJ@ - -default: all - -include $(eventsdir)/events.mk -include $(eventsdir)/rules.mk - -all:: showflags dirs $(PROGS) $(EVENTS_SOLIB) libevents.a $(PYTHON_BUILD_TARGET) - -install:: all -$(EVENTS_SOLIB): $(EVENTS_OBJ) - $(SHLD) $(SHLD_FLAGS) $(LDFLAGS) $(LIBS) -o $@ $(EVENTS_OBJ) @SONAMEFLAG@$(EVENTS_SONAME) - -shared-build: all - ${INSTALLCMD} -d $(sharedbuilddir)/lib - ${INSTALLCMD} -m 644 libevents.a $(sharedbuilddir)/lib - ${INSTALLCMD} -m 755 $(EVENTS_SOLIB) $(sharedbuilddir)/lib - ln -sf $(EVENTS_SOLIB) $(sharedbuilddir)/lib/$(EVENTS_SONAME) - ln -sf $(EVENTS_SOLIB) $(sharedbuilddir)/lib/libevents.so - ${INSTALLCMD} -d $(sharedbuilddir)/include - ${INSTALLCMD} -m 644 $(srcdir)/events.h $(sharedbuilddir)/include - -check: test - -test:: $(PYTHON_CHECK_TARGET) -installcheck:: test install - -clean:: - rm -f *.o *.a */*.o - -distclean:: clean - rm -f config.log config.status include/config.h config.cache - rm -f Makefile - -realdistclean:: distclean - rm -f configure include/config.h.in diff --git a/source4/lib/events/autogen.sh b/source4/lib/events/autogen.sh deleted file mode 100755 index fec05f54d4..0000000000 --- a/source4/lib/events/autogen.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh - -rm -rf autom4te.cache -rm -f configure config.h.in - -IPATHS="-I libreplace -I lib/replace -I ../libreplace -I ../replace -I ../../../lib/replace" -autoconf $IPATHS || exit 1 -autoheader $IPATHS || exit 1 - -rm -rf autom4te.cache - -swig -O -Wall -python -keyword events.i # Ignore errors for now - -echo "Now run ./configure and then make." -exit 0 - diff --git a/source4/lib/events/build_macros.m4 b/source4/lib/events/build_macros.m4 deleted file mode 100644 index c036668cd1..0000000000 --- a/source4/lib/events/build_macros.m4 +++ /dev/null @@ -1,14 +0,0 @@ -AC_DEFUN(BUILD_WITH_SHARED_BUILD_DIR, - [ AC_ARG_WITH([shared-build-dir], - [AC_HELP_STRING([--with-shared-build-dir=DIR], - [temporary build directory where libraries are installed [$srcdir/sharedbuild]])]) - - sharedbuilddir="$srcdir/sharedbuild" - if test x"$with_shared_build_dir" != x; then - sharedbuilddir=$with_shared_build_dir - CFLAGS="$CFLAGS -I$with_shared_build_dir/include" - LDFLAGS="$LDFLAGS -L$with_shared_build_dir/lib" - fi - AC_SUBST(sharedbuilddir) - ]) - diff --git a/source4/lib/events/config.mk b/source4/lib/events/config.mk index 127d964775..b9d6879b3c 100644 --- a/source4/lib/events/config.mk +++ b/source4/lib/events/config.mk @@ -1,58 +1,7 @@ -############################## -[MODULE::EVENTS_AIO] -PRIVATE_DEPENDENCIES = LIBAIO_LINUX -SUBSYSTEM = LIBEVENTS -INIT_FUNCTION = s4_events_aio_init -############################## - -EVENTS_AIO_OBJ_FILES = $(libeventssrcdir)/events_aio.o - -############################## -[MODULE::EVENTS_EPOLL] -SUBSYSTEM = LIBEVENTS -INIT_FUNCTION = s4_events_epoll_init -############################## - -EVENTS_EPOLL_OBJ_FILES = $(libeventssrcdir)/events_epoll.o - -############################## -[MODULE::EVENTS_SELECT] -SUBSYSTEM = LIBEVENTS -INIT_FUNCTION = s4_events_select_init -############################## - -EVENTS_SELECT_OBJ_FILES = $(libeventssrcdir)/events_select.o - -############################## -[MODULE::EVENTS_STANDARD] -SUBSYSTEM = LIBEVENTS -INIT_FUNCTION = s4_events_standard_init -############################## - -EVENTS_STANDARD_OBJ_FILES = $(libeventssrcdir)/events_standard.o - -################################################ -# Start SUBSYSTEM LIBEVENTS -[LIBRARY::LIBEVENTS] -PUBLIC_DEPENDENCIES = LIBTALLOC -OUTPUT_TYPE = MERGED_OBJ +[SUBSYSTEM::LIBEVENTS] +PUBLIC_DEPENDENCIES = LIBTEVENT CFLAGS = -Ilib/events -# -# End SUBSYSTEM LIBEVENTS -################################################ -LIBEVENTS_OBJ_FILES = $(addprefix $(libeventssrcdir)/, events.o events_timed.o events_signal.o events_debug.o events_util.o events_s4.o) +LIBEVENTS_OBJ_FILES = $(addprefix $(libeventssrcdir)/, events_dummy.o) PUBLIC_HEADERS += $(addprefix $(libeventssrcdir)/, events.h events_internal.h) - -[PYTHON::swig_events] -LIBRARY_REALNAME = samba/_events.$(SHLIBEXT) -PRIVATE_DEPENDENCIES = LIBEVENTS LIBSAMBA-HOSTCONFIG LIBSAMBA-UTIL - -swig_events_OBJ_FILES = $(libeventssrcdir)/events_wrap.o - -$(eval $(call python_py_module_template,samba/events.py,$(libeventssrcdir)/events.py)) - -$(swig_events_OBJ_FILES): CFLAGS+=$(CFLAG_NO_UNUSED_MACROS) $(CFLAG_NO_CAST_QUAL) - -PC_FILES += $(libeventssrcdir)/events.pc diff --git a/source4/lib/events/configure.ac b/source4/lib/events/configure.ac deleted file mode 100644 index 895f2a1daa..0000000000 --- a/source4/lib/events/configure.ac +++ /dev/null @@ -1,40 +0,0 @@ -AC_PREREQ(2.50) -AC_DEFUN([SMB_MODULE_DEFAULT], [echo -n ""]) -AC_DEFUN([SMB_LIBRARY_ENABLE], [echo -n ""]) -AC_DEFUN([SMB_ENABLE], [echo -n ""]) -AC_DEFUN([SMB_EXT_LIB], [echo -n ""]) -AC_INIT(events, 1.0.0) -AC_CONFIG_SRCDIR([events.c]) -AC_CONFIG_HEADER(config.h) -AC_LIBREPLACE_ALL_CHECKS - -AC_LD_EXPORT_DYNAMIC -AC_LD_SONAMEFLAG -AC_LD_PICFLAG -AC_LD_SHLIBEXT -AC_LIBREPLACE_SHLD -AC_LIBREPLACE_SHLD_FLAGS -AC_LIBREPLACE_RUNTIME_LIB_PATH_VAR - -m4_include(build_macros.m4) -BUILD_WITH_SHARED_BUILD_DIR - -m4_include(pkg.m4) -m4_include(libtalloc.m4) - -m4_include(libevents.m4) -AC_PATH_PROGS([PYTHON_CONFIG], [python2.6-config python2.5-config python2.4-config python-config]) -AC_PATH_PROGS([PYTHON], [python2.6 python2.5 python2.4 python]) - -PYTHON_BUILD_TARGET="build-python" -PYTHON_INSTALL_TARGET="install-python" -PYTHON_CHECK_TARGET="check-python" -AC_SUBST(PYTHON_BUILD_TARGET) -AC_SUBST(PYTHON_INSTALL_TARGET) -AC_SUBST(PYTHON_CHECK_TARGET) -if test -z "$PYTHON_CONFIG"; then - PYTHON_BUILD_TARGET="" - PYTHON_INSTALL_TARGET="" - PYTHON_CHECK_TARGET="" -fi -AC_OUTPUT(Makefile events.pc) diff --git a/source4/lib/events/events.c b/source4/lib/events/events.c deleted file mode 100644 index 52699d968e..0000000000 --- a/source4/lib/events/events.c +++ /dev/null @@ -1,310 +0,0 @@ -/* - Unix SMB/CIFS implementation. - main select loop and event handling - Copyright (C) Andrew Tridgell 2003 - - 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/>. -*/ - -/* - PLEASE READ THIS BEFORE MODIFYING! - - This module is a general abstraction for the main select loop and - event handling. Do not ever put any localised hacks in here, instead - register one of the possible event types and implement that event - somewhere else. - - There are 2 types of event handling that are handled in this module: - - 1) a file descriptor becoming readable or writeable. This is mostly - used for network sockets, but can be used for any type of file - descriptor. You may only register one handler for each file - descriptor/io combination or you will get unpredictable results - (this means that you can have a handler for read events, and a - separate handler for write events, but not two handlers that are - both handling read events) - - 2) a timed event. You can register an event that happens at a - specific time. You can register as many of these as you - like. They are single shot - add a new timed event in the event - handler to get another event. - - To setup a set of events you first need to create a event_context - structure using the function event_context_init(); This returns a - 'struct event_context' that you use in all subsequent calls. - - After that you can add/remove events that you are interested in - using event_add_*() and talloc_free() - - Finally, you call event_loop_wait_once() to block waiting for one of the - events to occor or event_loop_wait() which will loop - forever. - -*/ -#include "replace.h" -#include "events.h" -#include "events_internal.h" -#include "events_util.h" - -struct event_ops_list { - struct event_ops_list *next, *prev; - const char *name; - const struct event_ops *ops; -}; - -/* list of registered event backends */ -static struct event_ops_list *event_backends = NULL; -static char *event_default_backend = NULL; - -/* - register an events backend -*/ -bool event_register_backend(const char *name, const struct event_ops *ops) -{ - struct event_ops_list *e; - - for (e = event_backends; e != NULL; e = e->next) { - if (0 == strcmp(e->name, name)) { - /* already registered, skip it */ - return true; - } - } - - e = talloc(talloc_autofree_context(), struct event_ops_list); - if (e == NULL) return false; - - e->name = name; - e->ops = ops; - DLIST_ADD(event_backends, e); - - return true; -} - -/* - set the default event backend - */ -void event_set_default_backend(const char *backend) -{ - if (event_default_backend) free(event_default_backend); - event_default_backend = strdup(backend); -} - -/* - initialise backends if not already done -*/ -static void event_backend_init(void) -{ - events_select_init(); - events_standard_init(); -#if HAVE_EVENTS_EPOLL - events_epoll_init(); -#endif -#if HAVE_LINUX_AIO - events_aio_init(); -#endif -} - -/* - list available backends -*/ -const char **event_backend_list(TALLOC_CTX *mem_ctx) -{ - const char **list = NULL; - struct event_ops_list *e; - - event_backend_init(); - - for (e=event_backends;e;e=e->next) { - list = ev_str_list_add(list, e->name); - } - - talloc_steal(mem_ctx, list); - - return list; -} - -/* - create a event_context structure for a specific implemementation. - This must be the first events call, and all subsequent calls pass - this event_context as the first element. Event handlers also - receive this as their first argument. - - This function is for allowing third-party-applications to hook in gluecode - to their own event loop code, so that they can make async usage of our client libs - - NOTE: use event_context_init() inside of samba! -*/ -static struct event_context *event_context_init_ops(TALLOC_CTX *mem_ctx, - const struct event_ops *ops) -{ - struct event_context *ev; - int ret; - - ev = talloc_zero(mem_ctx, struct event_context); - if (!ev) return NULL; - - ev->ops = ops; - - ret = ev->ops->context_init(ev); - if (ret != 0) { - talloc_free(ev); - return NULL; - } - - return ev; -} - -/* - create a event_context structure. This must be the first events - call, and all subsequent calls pass this event_context as the first - element. Event handlers also receive this as their first argument. -*/ -struct event_context *event_context_init_byname(TALLOC_CTX *mem_ctx, const char *name) -{ - struct event_ops_list *e; - - event_backend_init(); - - if (name == NULL) { - name = event_default_backend; - } - if (name == NULL) { - name = "standard"; - } - - for (e=event_backends;e;e=e->next) { - if (strcmp(name, e->name) == 0) { - return event_context_init_ops(mem_ctx, e->ops); - } - } - return NULL; -} - - -/* - create a event_context structure. This must be the first events - call, and all subsequent calls pass this event_context as the first - element. Event handlers also receive this as their first argument. -*/ -struct event_context *event_context_init(TALLOC_CTX *mem_ctx) -{ - return event_context_init_byname(mem_ctx, NULL); -} - -/* - add a fd based event - return NULL on failure (memory allocation error) - - if flags contains EVENT_FD_AUTOCLOSE then the fd will be closed when - the returned fd_event context is freed -*/ -struct fd_event *event_add_fd(struct event_context *ev, TALLOC_CTX *mem_ctx, - int fd, uint16_t flags, event_fd_handler_t handler, - void *private_data) -{ - return ev->ops->add_fd(ev, mem_ctx, fd, flags, handler, private_data); -} - -/* - add a disk aio event -*/ -struct aio_event *event_add_aio(struct event_context *ev, - TALLOC_CTX *mem_ctx, - struct iocb *iocb, - event_aio_handler_t handler, - void *private_data) -{ - if (ev->ops->add_aio == NULL) return NULL; - return ev->ops->add_aio(ev, mem_ctx, iocb, handler, private_data); -} - -/* - return the fd event flags -*/ -uint16_t event_get_fd_flags(struct fd_event *fde) -{ - if (!fde) return 0; - return fde->event_ctx->ops->get_fd_flags(fde); -} - -/* - set the fd event flags -*/ -void event_set_fd_flags(struct fd_event *fde, uint16_t flags) -{ - if (!fde) return; - fde->event_ctx->ops->set_fd_flags(fde, flags); -} - -/* - add a timed event - return NULL on failure -*/ -struct timed_event *event_add_timed(struct event_context *ev, TALLOC_CTX *mem_ctx, - struct timeval next_event, - event_timed_handler_t handler, - void *private_data) -{ - return ev->ops->add_timed(ev, mem_ctx, next_event, handler, private_data); -} - -/* - add a signal event - - sa_flags are flags to sigaction(2) - - return NULL on failure -*/ -struct signal_event *event_add_signal(struct event_context *ev, TALLOC_CTX *mem_ctx, - int signum, - int sa_flags, - event_signal_handler_t handler, - void *private_data) -{ - return ev->ops->add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data); -} - -/* - do a single event loop using the events defined in ev -*/ -int event_loop_once(struct event_context *ev) -{ - return ev->ops->loop_once(ev); -} - -/* - return on failure or (with 0) if all fd events are removed -*/ -int event_loop_wait(struct event_context *ev) -{ - return ev->ops->loop_wait(ev); -} - -/* - find an event context that is a parent of the given memory context, - or create a new event context as a child of the given context if - none is found - - This should be used in preference to event_context_init() in places - where you would prefer to use the existing event context if possible - (which is most situations) -*/ -struct event_context *event_context_find(TALLOC_CTX *mem_ctx) -{ - struct event_context *ev = talloc_find_parent_bytype(mem_ctx, struct event_context); - if (ev == NULL) { - ev = event_context_init(mem_ctx); - } - return ev; -} diff --git a/source4/lib/events/events.h b/source4/lib/events/events.h index 1ece49697f..d2e81f5279 100644 --- a/source4/lib/events/events.h +++ b/source4/lib/events/events.h @@ -1,98 +1 @@ -/* - Unix SMB/CIFS implementation. - - generalised event loop handling - - Copyright (C) Andrew Tridgell 2005 - - 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/>. -*/ - -#ifndef __EVENTS_H__ -#define __EVENTS_H__ - -#include <stdint.h> -#include <talloc.h> - -struct event_context; -struct event_ops; -struct fd_event; -struct timed_event; -struct aio_event; -struct signal_event; - -/* event handler types */ -typedef void (*event_fd_handler_t)(struct event_context *, struct fd_event *, - uint16_t , void *); -typedef void (*event_timed_handler_t)(struct event_context *, struct timed_event *, - struct timeval , void *); -typedef void (*event_signal_handler_t)(struct event_context *, struct signal_event *, - int , int, void *, void *); -typedef void (*event_aio_handler_t)(struct event_context *, struct aio_event *, - int, void *); - -#ifdef _SAMBA_BUILD_ -struct event_context *s4_event_context_init(TALLOC_CTX *mem_ctx); -#endif - -struct event_context *event_context_init(TALLOC_CTX *mem_ctx); -struct event_context *event_context_init_byname(TALLOC_CTX *mem_ctx, const char *name); -const char **event_backend_list(TALLOC_CTX *mem_ctx); -void event_set_default_backend(const char *backend); - -struct fd_event *event_add_fd(struct event_context *ev, TALLOC_CTX *mem_ctx, - int fd, uint16_t flags, event_fd_handler_t handler, - void *private_data); - -struct timed_event *event_add_timed(struct event_context *ev, TALLOC_CTX *mem_ctx, - struct timeval next_event, - event_timed_handler_t handler, - void *private_data); - -struct signal_event *event_add_signal(struct event_context *ev, TALLOC_CTX *mem_ctx, - int signum, int sa_flags, - event_signal_handler_t handler, - void *private_data); - -struct iocb; -struct aio_event *event_add_aio(struct event_context *ev, - TALLOC_CTX *mem_ctx, - struct iocb *iocb, - event_aio_handler_t handler, - void *private_data); - -int event_loop_once(struct event_context *ev); -int event_loop_wait(struct event_context *ev); - -uint16_t event_get_fd_flags(struct fd_event *fde); -void event_set_fd_flags(struct fd_event *fde, uint16_t flags); - -struct event_context *event_context_find(TALLOC_CTX *mem_ctx); - -/* bits for file descriptor event flags */ -#define EVENT_FD_READ 1 -#define EVENT_FD_WRITE 2 -#define EVENT_FD_AUTOCLOSE 4 - -#define EVENT_FD_WRITEABLE(fde) \ - event_set_fd_flags(fde, event_get_fd_flags(fde) | EVENT_FD_WRITE) -#define EVENT_FD_READABLE(fde) \ - event_set_fd_flags(fde, event_get_fd_flags(fde) | EVENT_FD_READ) - -#define EVENT_FD_NOT_WRITEABLE(fde) \ - event_set_fd_flags(fde, event_get_fd_flags(fde) & ~EVENT_FD_WRITE) -#define EVENT_FD_NOT_READABLE(fde) \ - event_set_fd_flags(fde, event_get_fd_flags(fde) & ~EVENT_FD_READ) - -#endif /* __EVENTS_H__ */ +#include <tevent.h> diff --git a/source4/lib/events/events.i b/source4/lib/events/events.i deleted file mode 100644 index 8a0d9c4b6f..0000000000 --- a/source4/lib/events/events.i +++ /dev/null @@ -1,54 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007 - - 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/>. -*/ - -%module(docstring="Event management.",package="samba.events") events; - -%import "../../../lib/talloc/talloc.i"; - -%{ -#include "events.h" -typedef struct event_context event; -%} - -typedef struct event_context { - %extend { - %feature("docstring") event "S.__init__()"; - event(TALLOC_CTX *mem_ctx) { return event_context_init(mem_ctx); } - %feature("docstring") loop_once "S.loop_once() -> int"; - int loop_once(void); - %feature("docstring") loop_wait "S.loop_wait() -> int"; - int loop_wait(void); - } -} event; -%talloctype(event); - -%typemap(default,noblock=1) struct event_context * { - $1 = event_context_init(NULL); -} - -%typemap(default,noblock=1) struct event_context * { - $1 = event_context_init(NULL); -} - -struct event_context *event_context_init_byname(TALLOC_CTX *mem_ctx, const char *name); - -%feature("docstring") event_backend_list "event_backend_list() -> list"; -const char **event_backend_list(TALLOC_CTX *mem_ctx); -%feature("docstring") event_set_default_backend "event_set_default_backend(name) -> None"; -%rename(set_default_backend) event_set_default_backend; -void event_set_default_backend(const char *backend); diff --git a/source4/lib/events/events.mk b/source4/lib/events/events.mk deleted file mode 100644 index 2bc6221689..0000000000 --- a/source4/lib/events/events.mk +++ /dev/null @@ -1,59 +0,0 @@ - -EVENTS_SONAME = libevents.$(SHLIBEXT).0 -EVENTS_SOLIB = libevents.$(SHLIBEXT).$(PACKAGE_VERSION) - -libevents.a: $(EVENTS_OBJ) - ar -rv libevents.a $(EVENTS_OBJ) - -libevents.$(SHLIBEXT): $(EVENTS_SOLIB) - ln -fs $< $@ - -$(EVENTS_SONAME): $(EVENTS_SOLIB) - ln -fs $< $@ - -dirs:: - @mkdir -p lib - -installdirs:: - mkdir -p $(DESTDIR)$(includedir) - mkdir -p $(DESTDIR)$(libdir) - mkdir -p $(DESTDIR)$(libdir)/pkgconfig - -installheaders:: installdirs - cp $(srcdir)/events.h $(DESTDIR)$(includedir) - -installlibs:: installdirs - cp events.pc $(DESTDIR)$(libdir)/pkgconfig - cp libevents.a $(EVENTS_SOLIB) $(DESTDIR)$(libdir) - -install:: all installdirs installheaders installlibs $(PYTHON_INSTALL_TARGET) - -clean:: - rm -f $(EVENTS_SONAME) $(EVENTS_SOLIB) libevents.a libevents.$(SHLIBEXT) - rm -f events.pc - rm -f _libevents.$(SHLIBEXT) - - -#python stuff - -check-python:: build-python - $(LIB_PATH_VAR)=. PYTHONPATH=".:$(eventsdir)" $(PYTHON) $(eventsdir)/python/tests/simple.py - -install-swig:: - mkdir -p $(DESTDIR)`$(SWIG) -swiglib` - cp events.i $(DESTDIR)`$(SWIG) -swiglib` - -build-python:: _libevents.$(SHLIBEXT) - -events_wrap.o: $(eventsdir)/events_wrap.c - $(CC) $(PICFLAG) -c $(eventsdir)/events_wrap.c $(CFLAGS) `$(PYTHON_CONFIG) --cflags` - -_libevents.$(SHLIBEXT): libevents.$(SHLIBEXT) events_wrap.o - $(SHLD) $(SHLD_FLAGS) -o $@ events_wrap.o -L. -levents `$(PYTHON_CONFIG) --libs` - -install-python:: build-python - mkdir -p $(DESTDIR)`$(PYTHON) -c "import distutils.sysconfig; print distutils.sysconfig.get_python_lib(0, prefix='$(prefix)')"` \ - $(DESTDIR)`$(PYTHON) -c "import distutils.sysconfig; print distutils.sysconfig.get_python_lib(1, prefix='$(prefix)')"` - cp $(eventsdir)/events.py $(DESTDIR)`$(PYTHON) -c "import distutils.sysconfig; print distutils.sysconfig.get_python_lib(0, prefix='$(prefix)')"` - cp _libevents.$(SHLIBEXT) $(DESTDIR)`$(PYTHON) -c "import distutils.sysconfig; print distutils.sysconfig.get_python_lib(1, prefix='$(prefix)')"` - diff --git a/source4/lib/events/events.pc.in b/source4/lib/events/events.pc.in deleted file mode 100644 index 4a4c012d73..0000000000 --- a/source4/lib/events/events.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: events -Description: An event system library -Version: @PACKAGE_VERSION@ -Libs: -L${libdir} -levents -Cflags: -I${includedir} -URL: http://samba.org/ diff --git a/source4/lib/events/events.py b/source4/lib/events/events.py deleted file mode 100644 index c15ea8b9e5..0000000000 --- a/source4/lib/events/events.py +++ /dev/null @@ -1,94 +0,0 @@ -# This file was automatically generated by SWIG (http://www.swig.org). -# Version 1.3.36 -# -# Don't modify this file, modify the SWIG interface instead. - -""" -Event management. -""" - -import _events -import new -new_instancemethod = new.instancemethod -try: - _swig_property = property -except NameError: - pass # Python < 2.2 doesn't have 'property'. -def _swig_setattr_nondynamic(self,class_type,name,value,static=1): - if (name == "thisown"): return self.this.own(value) - if (name == "this"): - if type(value).__name__ == 'PySwigObject': - self.__dict__[name] = value - return - method = class_type.__swig_setmethods__.get(name,None) - if method: return method(self,value) - if (not static) or hasattr(self,name): - self.__dict__[name] = value - else: - raise AttributeError("You cannot add attributes to %s" % self) - -def _swig_setattr(self,class_type,name,value): - return _swig_setattr_nondynamic(self,class_type,name,value,0) - -def _swig_getattr(self,class_type,name): - if (name == "thisown"): return self.this.own() - method = class_type.__swig_getmethods__.get(name,None) - if method: return method(self) - raise AttributeError,name - -def _swig_repr(self): - try: strthis = "proxy of " + self.this.__repr__() - except: strthis = "" - return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,) - -import types -try: - _object = types.ObjectType - _newclass = 1 -except AttributeError: - class _object : pass - _newclass = 0 -del types - - -def _swig_setattr_nondynamic_method(set): - def set_attr(self,name,value): - if (name == "thisown"): return self.this.own(value) - if hasattr(self,name) or (name == "this"): - set(self,name,value) - else: - raise AttributeError("You cannot add attributes to %s" % self) - return set_attr - - -class event(object): - thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') - __repr__ = _swig_repr - def __init__(self, *args, **kwargs): - """S.__init__()""" - _events.event_swiginit(self,_events.new_event(*args, **kwargs)) - def loop_once(*args, **kwargs): - """S.loop_once() -> int""" - return _events.event_loop_once(*args, **kwargs) - - def loop_wait(*args, **kwargs): - """S.loop_wait() -> int""" - return _events.event_loop_wait(*args, **kwargs) - - __swig_destroy__ = _events.delete_event -event.loop_once = new_instancemethod(_events.event_loop_once,None,event) -event.loop_wait = new_instancemethod(_events.event_loop_wait,None,event) -event_swigregister = _events.event_swigregister -event_swigregister(event) - -event_context_init_byname = _events.event_context_init_byname - -def event_backend_list(*args): - """event_backend_list() -> list""" - return _events.event_backend_list(*args) - -def set_default_backend(*args, **kwargs): - """event_set_default_backend(name) -> None""" - return _events.set_default_backend(*args, **kwargs) - - diff --git a/source4/lib/events/events_aio.c b/source4/lib/events/events_aio.c deleted file mode 100644 index e30213acbc..0000000000 --- a/source4/lib/events/events_aio.c +++ /dev/null @@ -1,567 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - main select loop and event handling - aio/epoll hybrid implementation - - Copyright (C) Andrew Tridgell 2006 - - based on events_standard.c - - 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/>. -*/ -/* - this is a very strange beast. The Linux AIO implementation doesn't - yet integrate properly with epoll, but there is a kernel patch that - allows the aio wait primitives to be used to wait for epoll events, - and this can be used to give us a unified event system incorporating - both aio events and epoll events - - this is _very_ experimental code -*/ - -#include "system/filesys.h" -#include "replace.h" -#include "events.h" -#include "events_internal.h" -#include "events_util.h" -#include <sys/epoll.h> -#include <libaio.h> - -#define MAX_AIO_QUEUE_DEPTH 100 -#ifndef IOCB_CMD_EPOLL_WAIT -#define IOCB_CMD_EPOLL_WAIT 9 -#endif - -struct aio_event_context { - /* a pointer back to the generic event_context */ - struct event_context *ev; - - /* list of filedescriptor events */ - struct fd_event *fd_events; - - /* number of registered fd event handlers */ - int num_fd_events; - - uint32_t destruction_count; - - io_context_t ioctx; - - struct epoll_event epevent[MAX_AIO_QUEUE_DEPTH]; - - struct iocb *epoll_iocb; - - int epoll_fd; - int is_epoll_set; - pid_t pid; -}; - -struct aio_event { - struct event_context *event_ctx; - struct iocb iocb; - void *private_data; - event_aio_handler_t handler; -}; - -/* - map from EVENT_FD_* to EPOLLIN/EPOLLOUT -*/ -static uint32_t epoll_map_flags(uint16_t flags) -{ - uint32_t ret = 0; - if (flags & EVENT_FD_READ) ret |= (EPOLLIN | EPOLLERR | EPOLLHUP); - if (flags & EVENT_FD_WRITE) ret |= (EPOLLOUT | EPOLLERR | EPOLLHUP); - return ret; -} - -/* - free the epoll fd -*/ -static int aio_ctx_destructor(struct aio_event_context *aio_ev) -{ - io_queue_release(aio_ev->ioctx); - close(aio_ev->epoll_fd); - aio_ev->epoll_fd = -1; - return 0; -} - -static void epoll_add_event(struct aio_event_context *aio_ev, struct fd_event *fde); - -/* - reopen the epoll handle when our pid changes - see http://junkcode.samba.org/ftp/unpacked/junkcode/epoll_fork.c for an - demonstration of why this is needed - */ -static void epoll_check_reopen(struct aio_event_context *aio_ev) -{ - struct fd_event *fde; - - if (aio_ev->pid == getpid()) { - return; - } - - close(aio_ev->epoll_fd); - aio_ev->epoll_fd = epoll_create(MAX_AIO_QUEUE_DEPTH); - if (aio_ev->epoll_fd == -1) { - ev_debug(aio_ev->ev, EV_DEBUG_FATAL, "Failed to recreate epoll handle after fork\n"); - return; - } - aio_ev->pid = getpid(); - for (fde=aio_ev->fd_events;fde;fde=fde->next) { - epoll_add_event(aio_ev, fde); - } -} - -#define EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT (1<<0) -#define EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR (1<<1) -#define EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR (1<<2) - -/* - add the epoll event to the given fd_event -*/ -static void epoll_add_event(struct aio_event_context *aio_ev, struct fd_event *fde) -{ - struct epoll_event event; - if (aio_ev->epoll_fd == -1) return; - - fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; - - /* if we don't want events yet, don't add an aio_event */ - if (fde->flags == 0) return; - - memset(&event, 0, sizeof(event)); - event.events = epoll_map_flags(fde->flags); - event.data.ptr = fde; - epoll_ctl(aio_ev->epoll_fd, EPOLL_CTL_ADD, fde->fd, &event); - fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; - - /* only if we want to read we want to tell the event handler about errors */ - if (fde->flags & EVENT_FD_READ) { - fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; - } -} - -/* - delete the epoll event for given fd_event -*/ -static void epoll_del_event(struct aio_event_context *aio_ev, struct fd_event *fde) -{ - struct epoll_event event; - - DLIST_REMOVE(aio_ev->fd_events, fde); - - if (aio_ev->epoll_fd == -1) return; - - fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; - - /* if there's no aio_event, we don't need to delete it */ - if (!(fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT)) return; - - ZERO_STRUCT(event); - event.events = epoll_map_flags(fde->flags); - event.data.ptr = fde; - epoll_ctl(aio_ev->epoll_fd, EPOLL_CTL_DEL, fde->fd, &event); - - fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; -} - -/* - change the epoll event to the given fd_event -*/ -static void epoll_mod_event(struct aio_event_context *aio_ev, struct fd_event *fde) -{ - struct epoll_event event; - if (aio_ev->epoll_fd == -1) return; - - fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; - - ZERO_STRUCT(event); - event.events = epoll_map_flags(fde->flags); - event.data.ptr = fde; - epoll_ctl(aio_ev->epoll_fd, EPOLL_CTL_MOD, fde->fd, &event); - - /* only if we want to read we want to tell the event handler about errors */ - if (fde->flags & EVENT_FD_READ) { - fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; - } -} - -static void epoll_change_event(struct aio_event_context *aio_ev, struct fd_event *fde) -{ - bool got_error = (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR); - bool want_read = (fde->flags & EVENT_FD_READ); - bool want_write= (fde->flags & EVENT_FD_WRITE); - - if (aio_ev->epoll_fd == -1) return; - - fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; - - /* there's already an event */ - if (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT) { - if (want_read || (want_write && !got_error)) { - epoll_mod_event(aio_ev, fde); - return; - } - epoll_del_event(aio_ev, fde); - return; - } - - /* there's no aio_event attached to the fde */ - if (want_read || (want_write && !got_error)) { - DLIST_ADD(aio_ev->fd_events, fde); - epoll_add_event(aio_ev, fde); - return; - } -} - -static int setup_epoll_wait(struct aio_event_context *aio_ev) -{ - if (aio_ev->is_epoll_set) { - return 0; - } - memset(aio_ev->epoll_iocb, 0, sizeof(*aio_ev->epoll_iocb)); - aio_ev->epoll_iocb->aio_fildes = aio_ev->epoll_fd; - aio_ev->epoll_iocb->aio_lio_opcode = IOCB_CMD_EPOLL_WAIT; - aio_ev->epoll_iocb->aio_reqprio = 0; - - aio_ev->epoll_iocb->u.c.nbytes = MAX_AIO_QUEUE_DEPTH; - aio_ev->epoll_iocb->u.c.offset = -1; - aio_ev->epoll_iocb->u.c.buf = aio_ev->epevent; - - if (io_submit(aio_ev->ioctx, 1, &aio_ev->epoll_iocb) != 1) { - return -1; - } - aio_ev->is_epoll_set = 1; - - return 0; -} - - -/* - event loop handling using aio/epoll hybrid -*/ -static int aio_event_loop(struct aio_event_context *aio_ev, struct timeval *tvalp) -{ - int ret, i; - uint32_t destruction_count = ++aio_ev->destruction_count; - struct timespec timeout; - struct io_event events[8]; - - if (aio_ev->epoll_fd == -1) return -1; - - if (aio_ev->ev->num_signal_handlers && - common_event_check_signal(aio_ev->ev)) { - return 0; - } - - if (tvalp) { - timeout.tv_sec = tvalp->tv_sec; - timeout.tv_nsec = tvalp->tv_usec; - timeout.tv_nsec *= 1000; - } - - if (setup_epoll_wait(aio_ev) < 0) - return -1; - - ret = io_getevents(aio_ev->ioctx, 1, 8, - events, tvalp?&timeout:NULL); - - if (ret == -EINTR) { - if (aio_ev->ev->num_signal_handlers) { - common_event_check_signal(aio_ev->ev); - } - return 0; - } - - if (ret == 0 && tvalp) { - /* we don't care about a possible delay here */ - common_event_loop_timer_delay(aio_ev->ev); - return 0; - } - - for (i=0;i<ret;i++) { - struct io_event *event = &events[i]; - struct iocb *finished = event->obj; - - switch (finished->aio_lio_opcode) { - case IO_CMD_PWRITE: - case IO_CMD_PREAD: { - struct aio_event *ae = talloc_get_type(finished->data, - struct aio_event); - if (ae) { - talloc_set_destructor(ae, NULL); - ae->handler(ae->event_ctx, ae, - event->res, ae->private_data); - talloc_free(ae); - } - break; - } - case IOCB_CMD_EPOLL_WAIT: { - struct epoll_event *ep = (struct epoll_event *)finished->u.c.buf; - struct fd_event *fde; - uint16_t flags = 0; - int j; - - aio_ev->is_epoll_set = 0; - - for (j=0; j<event->res; j++, ep++) { - fde = talloc_get_type(ep->data.ptr, - struct fd_event); - if (fde == NULL) { - return -1; - } - if (ep->events & (EPOLLHUP|EPOLLERR)) { - fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR; - if (!(fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR)) { - epoll_del_event(aio_ev, fde); - continue; - } - flags |= EVENT_FD_READ; - } - if (ep->events & EPOLLIN) flags |= EVENT_FD_READ; - if (ep->events & EPOLLOUT) flags |= EVENT_FD_WRITE; - if (flags) { - fde->handler(aio_ev->ev, fde, flags, fde->private_data); - } - } - break; - } - } - if (destruction_count != aio_ev->destruction_count) { - return 0; - } - } - - return 0; -} - -/* - create a aio_event_context structure. -*/ -static int aio_event_context_init(struct event_context *ev) -{ - struct aio_event_context *aio_ev; - - aio_ev = talloc_zero(ev, struct aio_event_context); - if (!aio_ev) return -1; - - aio_ev->ev = ev; - aio_ev->epoll_iocb = talloc(aio_ev, struct iocb); - - if (io_queue_init(MAX_AIO_QUEUE_DEPTH, &aio_ev->ioctx) != 0) { - talloc_free(aio_ev); - return -1; - } - - aio_ev->epoll_fd = epoll_create(MAX_AIO_QUEUE_DEPTH); - if (aio_ev->epoll_fd == -1) { - talloc_free(aio_ev); - return -1; - } - aio_ev->pid = getpid(); - - talloc_set_destructor(aio_ev, aio_ctx_destructor); - - ev->additional_data = aio_ev; - - if (setup_epoll_wait(aio_ev) < 0) { - talloc_free(aio_ev); - return -1; - } - - return 0; -} - -/* - destroy an fd_event -*/ -static int aio_event_fd_destructor(struct fd_event *fde) -{ - struct event_context *ev = fde->event_ctx; - struct aio_event_context *aio_ev = talloc_get_type(ev->additional_data, - struct aio_event_context); - - epoll_check_reopen(aio_ev); - - aio_ev->num_fd_events--; - aio_ev->destruction_count++; - - epoll_del_event(aio_ev, fde); - - if (fde->flags & EVENT_FD_AUTOCLOSE) { - close(fde->fd); - fde->fd = -1; - } - - return 0; -} - -/* - add a fd based event - return NULL on failure (memory allocation error) -*/ -static struct fd_event *aio_event_add_fd(struct event_context *ev, TALLOC_CTX *mem_ctx, - int fd, uint16_t flags, - event_fd_handler_t handler, - void *private_data) -{ - struct aio_event_context *aio_ev = talloc_get_type(ev->additional_data, - struct aio_event_context); - struct fd_event *fde; - - epoll_check_reopen(aio_ev); - - fde = talloc(mem_ctx?mem_ctx:ev, struct fd_event); - if (!fde) return NULL; - - fde->event_ctx = ev; - fde->fd = fd; - fde->flags = flags; - fde->handler = handler; - fde->private_data = private_data; - fde->additional_flags = 0; - fde->additional_data = NULL; - - aio_ev->num_fd_events++; - talloc_set_destructor(fde, aio_event_fd_destructor); - - DLIST_ADD(aio_ev->fd_events, fde); - epoll_add_event(aio_ev, fde); - - return fde; -} - - -/* - return the fd event flags -*/ -static uint16_t aio_event_get_fd_flags(struct fd_event *fde) -{ - return fde->flags; -} - -/* - set the fd event flags -*/ -static void aio_event_set_fd_flags(struct fd_event *fde, uint16_t flags) -{ - struct event_context *ev; - struct aio_event_context *aio_ev; - - if (fde->flags == flags) return; - - ev = fde->event_ctx; - aio_ev = talloc_get_type(ev->additional_data, struct aio_event_context); - - fde->flags = flags; - - epoll_check_reopen(aio_ev); - - epoll_change_event(aio_ev, fde); -} - -/* - do a single event loop using the events defined in ev -*/ -static int aio_event_loop_once(struct event_context *ev) -{ - struct aio_event_context *aio_ev = talloc_get_type(ev->additional_data, - struct aio_event_context); - struct timeval tval; - - tval = common_event_loop_timer_delay(ev); - if (ev_timeval_is_zero(&tval)) { - return 0; - } - - epoll_check_reopen(aio_ev); - - return aio_event_loop(aio_ev, &tval); -} - -/* - return on failure or (with 0) if all fd events are removed -*/ -static int aio_event_loop_wait(struct event_context *ev) -{ - struct aio_event_context *aio_ev = talloc_get_type(ev->additional_data, - struct aio_event_context); - while (aio_ev->num_fd_events) { - if (aio_event_loop_once(ev) != 0) { - break; - } - } - - return 0; -} - -/* - called when a disk IO event needs to be cancelled -*/ -static int aio_destructor(struct aio_event *ae) -{ - struct event_context *ev = ae->event_ctx; - struct aio_event_context *aio_ev = talloc_get_type(ev->additional_data, - struct aio_event_context); - struct io_event result; - io_cancel(aio_ev->ioctx, &ae->iocb, &result); - /* TODO: handle errors from io_cancel()! */ - return 0; -} - -/* submit an aio disk IO event */ -static struct aio_event *aio_event_add_aio(struct event_context *ev, - TALLOC_CTX *mem_ctx, - struct iocb *iocb, - event_aio_handler_t handler, - void *private_data) -{ - struct aio_event_context *aio_ev = talloc_get_type(ev->additional_data, - struct aio_event_context); - struct iocb *iocbp; - struct aio_event *ae = talloc(mem_ctx?mem_ctx:ev, struct aio_event); - if (ae == NULL) return NULL; - - ae->event_ctx = ev; - ae->iocb = *iocb; - ae->handler = handler; - ae->private_data = private_data; - iocbp = &ae->iocb; - - if (io_submit(aio_ev->ioctx, 1, &iocbp) != 1) { - talloc_free(ae); - return NULL; - } - ae->iocb.data = ae; - talloc_set_destructor(ae, aio_destructor); - - return ae; -} - -static const struct event_ops aio_event_ops = { - .context_init = aio_event_context_init, - .add_fd = aio_event_add_fd, - .add_aio = aio_event_add_aio, - .get_fd_flags = aio_event_get_fd_flags, - .set_fd_flags = aio_event_set_fd_flags, - .add_timed = common_event_add_timed, - .add_signal = common_event_add_signal, - .loop_once = aio_event_loop_once, - .loop_wait = aio_event_loop_wait, -}; - -bool events_aio_init(void) -{ - return event_register_backend("aio", &aio_event_ops); -} - diff --git a/source4/lib/events/events_debug.c b/source4/lib/events/events_debug.c deleted file mode 100644 index 233844f024..0000000000 --- a/source4/lib/events/events_debug.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Copyright (C) Andrew Tridgell 2005 - Copyright (C) Jelmer Vernooij 2005 - - 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 "replace.h" -#include "events.h" -#include "events_internal.h" - -/******************************************************************** - * Debug wrapper functions, modeled (with lot's of code copied as is) - * after the ev debug wrapper functions - ********************************************************************/ - -/* - this allows the user to choose their own debug function -*/ -int ev_set_debug(struct event_context *ev, - void (*debug)(void *context, enum ev_debug_level level, - const char *fmt, va_list ap), - void *context) -{ - ev->debug_ops.debug = debug; - ev->debug_ops.context = context; - return 0; -} - -/* - debug function for ev_set_debug_stderr -*/ -void ev_debug_stderr(void *context, enum ev_debug_level level, - const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); -void ev_debug_stderr(void *context, enum ev_debug_level level, - const char *fmt, va_list ap) -{ - if (level <= EV_DEBUG_WARNING) { - vfprintf(stderr, fmt, ap); - } -} - -/* - convenience function to setup debug messages on stderr - messages of level EV_DEBUG_WARNING and higher are printed -*/ -int ev_set_debug_stderr(struct event_context *ev) -{ - return ev_set_debug(ev, ev_debug_stderr, ev); -} - -/* - * log a message - * - * The default debug action is to ignore debugging messages. - * This is the most appropriate action for a library. - * Applications using the library must decide where to - * redirect debugging messages -*/ -void ev_debug(struct event_context *ev, enum ev_debug_level level, const char *fmt, ...) -{ - va_list ap; - if (ev->debug_ops.debug == NULL) { - return; - } - va_start(ap, fmt); - ev->debug_ops.debug(ev->debug_ops.context, level, fmt, ap); - va_end(ap); -} - diff --git a/source4/lib/events/events_dummy.c b/source4/lib/events/events_dummy.c new file mode 100644 index 0000000000..15bb25e953 --- /dev/null +++ b/source4/lib/events/events_dummy.c @@ -0,0 +1,4 @@ +void __events_dummy(void) +{ +} + diff --git a/source4/lib/events/events_epoll.c b/source4/lib/events/events_epoll.c deleted file mode 100644 index d46d5c2bbc..0000000000 --- a/source4/lib/events/events_epoll.c +++ /dev/null @@ -1,482 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - main select loop and event handling - epoll implementation - - Copyright (C) Andrew Tridgell 2003-2005 - Copyright (C) Stefan Metzmacher 2005 - - 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 "replace.h" -#include "system/filesys.h" -#include "system/network.h" -#include "events.h" -#include "events_internal.h" -#include "events_util.h" -#include <sys/epoll.h> - -struct epoll_event_context { - /* a pointer back to the generic event_context */ - struct event_context *ev; - - /* list of filedescriptor events */ - struct fd_event *fd_events; - - /* number of registered fd event handlers */ - int num_fd_events; - - /* this is changed by the destructors for the fd event - type. It is used to detect event destruction by event - handlers, which means the code that is calling the event - handler needs to assume that the linked list is no longer - valid - */ - uint32_t destruction_count; - - /* when using epoll this is the handle from epoll_create */ - int epoll_fd; - - pid_t pid; -}; - -/* - called when a epoll call fails, and we should fallback - to using select -*/ -static void epoll_panic(struct epoll_event_context *epoll_ev, const char *reason) -{ - ev_debug(epoll_ev->ev, EV_DEBUG_FATAL, - "%s (%s) - calling abort()\n", reason, strerror(errno)); - abort(); -} - -/* - map from EVENT_FD_* to EPOLLIN/EPOLLOUT -*/ -static uint32_t epoll_map_flags(uint16_t flags) -{ - uint32_t ret = 0; - if (flags & EVENT_FD_READ) ret |= (EPOLLIN | EPOLLERR | EPOLLHUP); - if (flags & EVENT_FD_WRITE) ret |= (EPOLLOUT | EPOLLERR | EPOLLHUP); - return ret; -} - -/* - free the epoll fd -*/ -static int epoll_ctx_destructor(struct epoll_event_context *epoll_ev) -{ - close(epoll_ev->epoll_fd); - epoll_ev->epoll_fd = -1; - return 0; -} - -/* - init the epoll fd -*/ -static int epoll_init_ctx(struct epoll_event_context *epoll_ev) -{ - epoll_ev->epoll_fd = epoll_create(64); - epoll_ev->pid = getpid(); - talloc_set_destructor(epoll_ev, epoll_ctx_destructor); - if (epoll_ev->epoll_fd == -1) { - return -1; - } - return 0; -} - -static void epoll_add_event(struct epoll_event_context *epoll_ev, struct fd_event *fde); - -/* - reopen the epoll handle when our pid changes - see http://junkcode.samba.org/ftp/unpacked/junkcode/epoll_fork.c for an - demonstration of why this is needed - */ -static void epoll_check_reopen(struct epoll_event_context *epoll_ev) -{ - struct fd_event *fde; - - if (epoll_ev->pid == getpid()) { - return; - } - - close(epoll_ev->epoll_fd); - epoll_ev->epoll_fd = epoll_create(64); - if (epoll_ev->epoll_fd == -1) { - ev_debug(epoll_ev->ev, EV_DEBUG_FATAL, - "Failed to recreate epoll handle after fork\n"); - return; - } - epoll_ev->pid = getpid(); - for (fde=epoll_ev->fd_events;fde;fde=fde->next) { - epoll_add_event(epoll_ev, fde); - } -} - -#define EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT (1<<0) -#define EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR (1<<1) -#define EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR (1<<2) - -/* - add the epoll event to the given fd_event -*/ -static void epoll_add_event(struct epoll_event_context *epoll_ev, struct fd_event *fde) -{ - struct epoll_event event; - - if (epoll_ev->epoll_fd == -1) return; - - fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; - - /* if we don't want events yet, don't add an epoll_event */ - if (fde->flags == 0) return; - - ZERO_STRUCT(event); - event.events = epoll_map_flags(fde->flags); - event.data.ptr = fde; - if (epoll_ctl(epoll_ev->epoll_fd, EPOLL_CTL_ADD, fde->fd, &event) != 0) { - epoll_panic(epoll_ev, "EPOLL_CTL_ADD failed"); - } - fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; - - /* only if we want to read we want to tell the event handler about errors */ - if (fde->flags & EVENT_FD_READ) { - fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; - } -} - -/* - delete the epoll event for given fd_event -*/ -static void epoll_del_event(struct epoll_event_context *epoll_ev, struct fd_event *fde) -{ - struct epoll_event event; - - if (epoll_ev->epoll_fd == -1) return; - - fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; - - /* if there's no epoll_event, we don't need to delete it */ - if (!(fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT)) return; - - ZERO_STRUCT(event); - event.events = epoll_map_flags(fde->flags); - event.data.ptr = fde; - if (epoll_ctl(epoll_ev->epoll_fd, EPOLL_CTL_DEL, fde->fd, &event) != 0) { - ev_debug(epoll_ev->ev, EV_DEBUG_FATAL, - "epoll_del_event failed! probable early close bug (%s)\n", - strerror(errno)); - } - fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; -} - -/* - change the epoll event to the given fd_event -*/ -static void epoll_mod_event(struct epoll_event_context *epoll_ev, struct fd_event *fde) -{ - struct epoll_event event; - if (epoll_ev->epoll_fd == -1) return; - - fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; - - ZERO_STRUCT(event); - event.events = epoll_map_flags(fde->flags); - event.data.ptr = fde; - if (epoll_ctl(epoll_ev->epoll_fd, EPOLL_CTL_MOD, fde->fd, &event) != 0) { - epoll_panic(epoll_ev, "EPOLL_CTL_MOD failed"); - } - - /* only if we want to read we want to tell the event handler about errors */ - if (fde->flags & EVENT_FD_READ) { - fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; - } -} - -static void epoll_change_event(struct epoll_event_context *epoll_ev, struct fd_event *fde) -{ - bool got_error = (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR); - bool want_read = (fde->flags & EVENT_FD_READ); - bool want_write= (fde->flags & EVENT_FD_WRITE); - - if (epoll_ev->epoll_fd == -1) return; - - fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; - - /* there's already an event */ - if (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT) { - if (want_read || (want_write && !got_error)) { - epoll_mod_event(epoll_ev, fde); - return; - } - /* - * if we want to match the select behavior, we need to remove the epoll_event - * when the caller isn't interested in events. - * - * this is because epoll reports EPOLLERR and EPOLLHUP, even without asking for them - */ - epoll_del_event(epoll_ev, fde); - return; - } - - /* there's no epoll_event attached to the fde */ - if (want_read || (want_write && !got_error)) { - epoll_add_event(epoll_ev, fde); - return; - } -} - -/* - event loop handling using epoll -*/ -static int epoll_event_loop(struct epoll_event_context *epoll_ev, struct timeval *tvalp) -{ - int ret, i; -#define MAXEVENTS 32 - struct epoll_event events[MAXEVENTS]; - uint32_t destruction_count = ++epoll_ev->destruction_count; - int timeout = -1; - - if (epoll_ev->epoll_fd == -1) return -1; - - if (tvalp) { - /* it's better to trigger timed events a bit later than to early */ - timeout = ((tvalp->tv_usec+999) / 1000) + (tvalp->tv_sec*1000); - } - - if (epoll_ev->ev->num_signal_handlers && - common_event_check_signal(epoll_ev->ev)) { - return 0; - } - - ret = epoll_wait(epoll_ev->epoll_fd, events, MAXEVENTS, timeout); - - if (ret == -1 && errno == EINTR && epoll_ev->ev->num_signal_handlers) { - if (common_event_check_signal(epoll_ev->ev)) { - return 0; - } - } - - if (ret == -1 && errno != EINTR) { - epoll_panic(epoll_ev, "epoll_wait() failed"); - return -1; - } - - if (ret == 0 && tvalp) { - /* we don't care about a possible delay here */ - common_event_loop_timer_delay(epoll_ev->ev); - return 0; - } - - for (i=0;i<ret;i++) { - struct fd_event *fde = talloc_get_type(events[i].data.ptr, - struct fd_event); - uint16_t flags = 0; - - if (fde == NULL) { - epoll_panic(epoll_ev, "epoll_wait() gave bad data"); - return -1; - } - if (events[i].events & (EPOLLHUP|EPOLLERR)) { - fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR; - /* - * if we only wait for EVENT_FD_WRITE, we should not tell the - * event handler about it, and remove the epoll_event, - * as we only report errors when waiting for read events, - * to match the select() behavior - */ - if (!(fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR)) { - epoll_del_event(epoll_ev, fde); - continue; - } - flags |= EVENT_FD_READ; - } - if (events[i].events & EPOLLIN) flags |= EVENT_FD_READ; - if (events[i].events & EPOLLOUT) flags |= EVENT_FD_WRITE; - if (flags) { - fde->handler(epoll_ev->ev, fde, flags, fde->private_data); - if (destruction_count != epoll_ev->destruction_count) { - break; - } - } - } - - return 0; -} - -/* - create a epoll_event_context structure. -*/ -static int epoll_event_context_init(struct event_context *ev) -{ - int ret; - struct epoll_event_context *epoll_ev; - - epoll_ev = talloc_zero(ev, struct epoll_event_context); - if (!epoll_ev) return -1; - epoll_ev->ev = ev; - epoll_ev->epoll_fd = -1; - - ret = epoll_init_ctx(epoll_ev); - if (ret != 0) { - talloc_free(epoll_ev); - return ret; - } - - ev->additional_data = epoll_ev; - return 0; -} - -/* - destroy an fd_event -*/ -static int epoll_event_fd_destructor(struct fd_event *fde) -{ - struct event_context *ev = fde->event_ctx; - struct epoll_event_context *epoll_ev = talloc_get_type(ev->additional_data, - struct epoll_event_context); - - epoll_check_reopen(epoll_ev); - - epoll_ev->num_fd_events--; - epoll_ev->destruction_count++; - - DLIST_REMOVE(epoll_ev->fd_events, fde); - - epoll_del_event(epoll_ev, fde); - - if (fde->flags & EVENT_FD_AUTOCLOSE) { - close(fde->fd); - fde->fd = -1; - } - - return 0; -} - -/* - add a fd based event - return NULL on failure (memory allocation error) -*/ -static struct fd_event *epoll_event_add_fd(struct event_context *ev, TALLOC_CTX *mem_ctx, - int fd, uint16_t flags, - event_fd_handler_t handler, - void *private_data) -{ - struct epoll_event_context *epoll_ev = talloc_get_type(ev->additional_data, - struct epoll_event_context); - struct fd_event *fde; - - epoll_check_reopen(epoll_ev); - - fde = talloc(mem_ctx?mem_ctx:ev, struct fd_event); - if (!fde) return NULL; - - fde->event_ctx = ev; - fde->fd = fd; - fde->flags = flags; - fde->handler = handler; - fde->private_data = private_data; - fde->additional_flags = 0; - fde->additional_data = NULL; - - epoll_ev->num_fd_events++; - talloc_set_destructor(fde, epoll_event_fd_destructor); - - DLIST_ADD(epoll_ev->fd_events, fde); - epoll_add_event(epoll_ev, fde); - - return fde; -} - - -/* - return the fd event flags -*/ -static uint16_t epoll_event_get_fd_flags(struct fd_event *fde) -{ - return fde->flags; -} - -/* - set the fd event flags -*/ -static void epoll_event_set_fd_flags(struct fd_event *fde, uint16_t flags) -{ - struct event_context *ev; - struct epoll_event_context *epoll_ev; - - if (fde->flags == flags) return; - - ev = fde->event_ctx; - epoll_ev = talloc_get_type(ev->additional_data, struct epoll_event_context); - - fde->flags = flags; - - epoll_check_reopen(epoll_ev); - - epoll_change_event(epoll_ev, fde); -} - -/* - do a single event loop using the events defined in ev -*/ -static int epoll_event_loop_once(struct event_context *ev) -{ - struct epoll_event_context *epoll_ev = talloc_get_type(ev->additional_data, - struct epoll_event_context); - struct timeval tval; - - tval = common_event_loop_timer_delay(ev); - if (ev_timeval_is_zero(&tval)) { - return 0; - } - - epoll_check_reopen(epoll_ev); - - return epoll_event_loop(epoll_ev, &tval); -} - -/* - return on failure or (with 0) if all fd events are removed -*/ -static int epoll_event_loop_wait(struct event_context *ev) -{ - struct epoll_event_context *epoll_ev = talloc_get_type(ev->additional_data, - struct epoll_event_context); - while (epoll_ev->num_fd_events) { - if (epoll_event_loop_once(ev) != 0) { - break; - } - } - - return 0; -} - -static const struct event_ops epoll_event_ops = { - .context_init = epoll_event_context_init, - .add_fd = epoll_event_add_fd, - .get_fd_flags = epoll_event_get_fd_flags, - .set_fd_flags = epoll_event_set_fd_flags, - .add_timed = common_event_add_timed, - .add_signal = common_event_add_signal, - .loop_once = epoll_event_loop_once, - .loop_wait = epoll_event_loop_wait, -}; - -bool events_epoll_init(void) -{ - return event_register_backend("epoll", &epoll_event_ops); -} diff --git a/source4/lib/events/events_internal.h b/source4/lib/events/events_internal.h index 0d0755f298..308587ce2f 100644 --- a/source4/lib/events/events_internal.h +++ b/source4/lib/events/events_internal.h @@ -1,158 +1 @@ -/* - Unix SMB/CIFS implementation. - - generalised event loop handling - - Internal structs - - Copyright (C) Stefan Metzmacher 2005 - - 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/>. -*/ - -struct event_ops { - /* conntext init */ - int (*context_init)(struct event_context *ev); - - /* fd_event functions */ - struct fd_event *(*add_fd)(struct event_context *ev, - TALLOC_CTX *mem_ctx, - int fd, uint16_t flags, - event_fd_handler_t handler, - void *private_data); - uint16_t (*get_fd_flags)(struct fd_event *fde); - void (*set_fd_flags)(struct fd_event *fde, uint16_t flags); - - /* timed_event functions */ - struct timed_event *(*add_timed)(struct event_context *ev, - TALLOC_CTX *mem_ctx, - struct timeval next_event, - event_timed_handler_t handler, - void *private_data); - /* disk aio event functions */ - struct aio_event *(*add_aio)(struct event_context *ev, - TALLOC_CTX *mem_ctx, - struct iocb *iocb, - event_aio_handler_t handler, - void *private_data); - /* signal functions */ - struct signal_event *(*add_signal)(struct event_context *ev, - TALLOC_CTX *mem_ctx, - int signum, int sa_flags, - event_signal_handler_t handler, - void *private_data); - - /* loop functions */ - int (*loop_once)(struct event_context *ev); - int (*loop_wait)(struct event_context *ev); -}; - -struct fd_event { - struct fd_event *prev, *next; - struct event_context *event_ctx; - int fd; - uint16_t flags; /* see EVENT_FD_* flags */ - event_fd_handler_t handler; - /* this is private for the specific handler */ - void *private_data; - /* this is private for the events_ops implementation */ - uint16_t additional_flags; - void *additional_data; -}; - -struct timed_event { - struct timed_event *prev, *next; - struct event_context *event_ctx; - struct timeval next_event; - event_timed_handler_t handler; - /* this is private for the specific handler */ - void *private_data; - /* this is private for the events_ops implementation */ - void *additional_data; -}; - -struct signal_event { - struct signal_event *prev, *next; - struct event_context *event_ctx; - event_signal_handler_t handler; - void *private_data; - int signum; - int sa_flags; -}; - -/* DEBUG */ -enum ev_debug_level {EV_DEBUG_FATAL, EV_DEBUG_ERROR, - EV_DEBUG_WARNING, EV_DEBUG_TRACE}; - -struct ev_debug_ops { - void (*debug)(void *context, enum ev_debug_level level, - const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); - void *context; -}; - -int ev_set_debug(struct event_context *ev, - void (*debug)(void *context, enum ev_debug_level level, - const char *fmt, va_list ap), - void *context); -int ev_set_debug_stderr(struct event_context *ev); -void ev_debug(struct event_context *ev, enum ev_debug_level level, const char *fmt, ...); - -/* aio event is private to the aio backend */ -struct aio_event; - -struct event_context { - /* the specific events implementation */ - const struct event_ops *ops; - - /* list of timed events - used by common code */ - struct timed_event *timed_events; - - /* this is private for the events_ops implementation */ - void *additional_data; - - /* number of signal event handlers */ - int num_signal_handlers; - - /* pipe hack used with signal handlers */ - struct fd_event *pipe_fde; - - /* debugging operations */ - struct ev_debug_ops debug_ops; -}; - - -bool event_register_backend(const char *name, const struct event_ops *ops); - -bool ev_timeval_is_zero(const struct timeval *tv); -struct timed_event *common_event_add_timed(struct event_context *, TALLOC_CTX *, - struct timeval, event_timed_handler_t, void *); -struct timeval common_event_loop_timer_delay(struct event_context *); - -struct signal_event *common_event_add_signal(struct event_context *ev, - TALLOC_CTX *mem_ctx, - int signum, - int sa_flags, - event_signal_handler_t handler, - void *private_data); -int common_event_check_signal(struct event_context *ev); - - -bool events_standard_init(void); -bool events_select_init(void); -#if HAVE_EVENTS_EPOLL -bool events_epoll_init(void); -#endif -#if HAVE_LINUX_AIO -bool events_aio_init(void); -#endif +#include <tevent_internal.h> diff --git a/source4/lib/events/events_liboop.c b/source4/lib/events/events_liboop.c deleted file mode 100644 index 339297a3cf..0000000000 --- a/source4/lib/events/events_liboop.c +++ /dev/null @@ -1,288 +0,0 @@ -/* - Unix SMB/CIFS implementation. - main select loop and event handling - wrapper for http://liboop.org/ - - Copyright (C) Stefan Metzmacher 2005 - - 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 "events.h" -#include "events_internal.h" - -#include <oop.h> - -/* - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - NOTE: this code compiles fine, but is completly *UNTESTED* - and is only commited as example - - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -*/ - -static int oop_event_context_destructor(struct event_context *ev) -{ - oop_source_sys *oop_sys = ev->additional_data; - - oop_sys_delete(oop_sys); - - return 0; -} - -/* - create a oop_event_context structure. -*/ -static int oop_event_context_init(struct event_context *ev, void *private_data) -{ - oop_source_sys *oop_sys = private_data; - - if (!oop_sys) { - oop_sys = oop_sys_new(); - if (!oop_sys) { - return -1; - } - - talloc_set_destructor(ev, oop_event_context_destructor); - } - - ev->additional_data = oop_sys; - - return 0; -} - -static void *oop_event_fd_handler(oop_source *oop, int fd, oop_event oop_type, void *ptr) -{ - struct fd_event *fde = ptr; - - if (fd != fde->fd) return OOP_ERROR; - - switch(oop_type) { - case OOP_READ: - fde->handler(fde->event_ctx, fde, EVENT_FD_READ, fde->private_data); - return OOP_CONTINUE; - case OOP_WRITE: - fde->handler(fde->event_ctx, fde, EVENT_FD_WRITE, fde->private_data); - return OOP_CONTINUE; - case OOP_EXCEPTION: - return OOP_ERROR; - case OOP_NUM_EVENTS: - return OOP_ERROR; - } - - return OOP_ERROR; -} - -/* - destroy an fd_event -*/ -static int oop_event_fd_destructor(struct fd_event *fde) -{ - struct event_context *ev = fde->event_ctx; - oop_source_sys *oop_sys = ev->additional_data; - oop_source *oop = oop_sys_source(oop_sys); - - if (fde->flags & EVENT_FD_READ) - oop->cancel_fd(oop, fde->fd, OOP_READ); - if (fde->flags & EVENT_FD_WRITE) - oop->cancel_fd(oop, fde->fd, OOP_WRITE); - - if (fde->flags & EVENT_FD_AUTOCLOSE) { - close(fde->fd); - fde->fd = -1; - } - - return 0; -} - -/* - add a fd based event - return NULL on failure (memory allocation error) -*/ -static struct fd_event *oop_event_add_fd(struct event_context *ev, TALLOC_CTX *mem_ctx, - int fd, uint16_t flags, - event_fd_handler_t handler, - void *private_data) -{ - struct fd_event *fde; - oop_source_sys *oop_sys = ev->additional_data; - oop_source *oop = oop_sys_source(oop_sys); - - fde = talloc(mem_ctx?mem_ctx:ev, struct fd_event); - if (!fde) return NULL; - - fde->event_ctx = ev; - fde->fd = fd; - fde->flags = flags; - fde->handler = handler; - fde->private_data = private_data; - fde->additional_flags = 0; - fde->additional_data = NULL; - - if (fde->flags & EVENT_FD_READ) - oop->on_fd(oop, fde->fd, OOP_READ, oop_event_fd_handler, fde); - if (fde->flags & EVENT_FD_WRITE) - oop->on_fd(oop, fde->fd, OOP_WRITE, oop_event_fd_handler, fde); - - talloc_set_destructor(fde, oop_event_fd_destructor); - - return fde; -} - -/* - return the fd event flags -*/ -static uint16_t oop_event_get_fd_flags(struct fd_event *fde) -{ - return fde->flags; -} - -/* - set the fd event flags -*/ -static void oop_event_set_fd_flags(struct fd_event *fde, uint16_t flags) -{ - oop_source_sys *oop_sys; - oop_source *oop; - - oop_sys = fde->event_ctx->additional_data; - oop = oop_sys_source(oop_sys); - - if ((fde->flags & EVENT_FD_READ)&&(!(flags & EVENT_FD_READ))) - oop->cancel_fd(oop, fde->fd, OOP_READ); - - if ((!(fde->flags & EVENT_FD_READ))&&(flags & EVENT_FD_READ)) - oop->on_fd(oop, fde->fd, OOP_READ, oop_event_fd_handler, fde); - - if ((fde->flags & EVENT_FD_WRITE)&&(!(flags & EVENT_FD_WRITE))) - oop->cancel_fd(oop, fde->fd, OOP_WRITE); - - if ((!(fde->flags & EVENT_FD_WRITE))&&(flags & EVENT_FD_WRITE)) - oop->on_fd(oop, fde->fd, OOP_WRITE, oop_event_fd_handler, fde); - - fde->flags = flags; -} - -static int oop_event_timed_destructor(struct timed_event *te); - -static int oop_event_timed_deny_destructor(struct timed_event *te) -{ - return -1; -} - -static void *oop_event_timed_handler(oop_source *oop, struct timeval t, void *ptr) -{ - struct timed_event *te = ptr; - - /* deny the handler to free the event */ - talloc_set_destructor(te, oop_event_timed_deny_destructor); - te->handler(te->event_ctx, te, t, te->private_data); - - talloc_set_destructor(te, oop_event_timed_destructor); - talloc_free(te); - - return OOP_CONTINUE; -} - -/* - destroy a timed event -*/ -static int oop_event_timed_destructor(struct timed_event *te) -{ - struct event_context *ev = te->event_ctx; - oop_source_sys *oop_sys = ev->additional_data; - oop_source *oop = oop_sys_source(oop_sys); - - oop->cancel_time(oop, te->next_event, oop_event_timed_handler, te); - - return 0; -} - -/* - add a timed event - return NULL on failure (memory allocation error) -*/ -static struct timed_event *oop_event_add_timed(struct event_context *ev, TALLOC_CTX *mem_ctx, - struct timeval next_event, - event_timed_handler_t handler, - void *private_data) -{ - oop_source_sys *oop_sys = ev->additional_data; - oop_source *oop = oop_sys_source(oop_sys); - struct timed_event *te; - - te = talloc(mem_ctx?mem_ctx:ev, struct timed_event); - if (te == NULL) return NULL; - - te->event_ctx = ev; - te->next_event = next_event; - te->handler = handler; - te->private_data = private_data; - te->additional_data = NULL; - - oop->on_time(oop, te->next_event, oop_event_timed_handler, te); - - talloc_set_destructor(te, oop_event_timed_destructor); - - return te; -} - -/* - do a single event loop using the events defined in ev -*/ -static int oop_event_loop_once(struct event_context *ev) -{ - void *oop_ret; - oop_source_sys *oop_sys = ev->additional_data; - - oop_ret = oop_sys_run_once(oop_sys); - if (oop_ret == OOP_CONTINUE) { - return 0; - } - - return -1; -} - -/* - return on failure or (with 0) if all fd events are removed -*/ -static int oop_event_loop_wait(struct event_context *ev) -{ - void *oop_ret; - oop_source_sys *oop_sys = ev->additional_data; - - oop_ret = oop_sys_run(oop_sys); - if (oop_ret == OOP_CONTINUE) { - return 0; - } - - return -1; -} - -static const struct event_ops event_oop_ops = { - .context_init = oop_event_context_init, - .add_fd = oop_event_add_fd, - .get_fd_flags = oop_event_get_fd_flags, - .set_fd_flags = oop_event_set_fd_flags, - .add_timed = oop_event_add_timed, - .add_signal = common_event_add_signal, - .loop_once = oop_event_loop_once, - .loop_wait = oop_event_loop_wait, -}; - -const struct event_ops *event_liboop_get_ops(void) -{ - return &event_oop_ops; -} diff --git a/source4/lib/events/events_s4.c b/source4/lib/events/events_s4.c deleted file mode 100644 index 134f899cf8..0000000000 --- a/source4/lib/events/events_s4.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Copyright (C) Andrew Tridgell 2003 - - 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 "events.h" -#include "events_internal.h" - -NTSTATUS s4_events_standard_init(void) -{ - if (!events_standard_init()) { - return NT_STATUS_INTERNAL_ERROR; - } - return NT_STATUS_OK; -} - -NTSTATUS s4_events_select_init(void) -{ - if (!events_select_init()) { - return NT_STATUS_INTERNAL_ERROR; - } - return NT_STATUS_OK; -} - -#if HAVE_EVENTS_EPOLL -NTSTATUS s4_events_epoll_init(void) -{ - if (!events_epoll_init()) { - return NT_STATUS_INTERNAL_ERROR; - } - return NT_STATUS_OK; -} -#endif - -#if HAVE_LINUX_AIO -NTSTATUS s4_events_aio_init(void) -{ - if (!events_aio_init()) { - return NT_STATUS_INTERNAL_ERROR; - } - return NT_STATUS_OK; -} -#endif - -/* - this is used to catch debug messages from events -*/ -static void ev_wrap_debug(void *context, enum ev_debug_level level, - const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); - -static void ev_wrap_debug(void *context, enum ev_debug_level level, - const char *fmt, va_list ap) -{ - int samba_level = -1; - char *s = NULL; - switch (level) { - case EV_DEBUG_FATAL: - samba_level = 0; - break; - case EV_DEBUG_ERROR: - samba_level = 1; - break; - case EV_DEBUG_WARNING: - samba_level = 2; - break; - case EV_DEBUG_TRACE: - samba_level = 5; - break; - - }; - vasprintf(&s, fmt, ap); - if (!s) return; - DEBUG(samba_level, ("events: %s\n", s)); - free(s); -} - -/* - create a event_context structure. This must be the first events - call, and all subsequent calls pass this event_context as the first - element. Event handlers also receive this as their first argument. - - This samba4 specific call sets the samba4 debug handler. -*/ -struct event_context *s4_event_context_init(TALLOC_CTX *mem_ctx) -{ - struct event_context *ev; - - ev = event_context_init_byname(mem_ctx, NULL); - if (ev) { - ev_set_debug(ev, ev_wrap_debug, NULL); - } - return ev; -} - diff --git a/source4/lib/events/events_select.c b/source4/lib/events/events_select.c deleted file mode 100644 index 54d32204f5..0000000000 --- a/source4/lib/events/events_select.c +++ /dev/null @@ -1,302 +0,0 @@ -/* - Unix SMB/CIFS implementation. - main select loop and event handling - Copyright (C) Andrew Tridgell 2003-2005 - Copyright (C) Stefan Metzmacher 2005 - - 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/>. -*/ - -/* - This is SAMBA's default event loop code - -*/ - -#include "replace.h" -#include "system/filesys.h" -#include "system/select.h" -#include "events.h" -#include "events_util.h" -#include "events_internal.h" - -struct select_event_context { - /* a pointer back to the generic event_context */ - struct event_context *ev; - - /* list of filedescriptor events */ - struct fd_event *fd_events; - - /* list of timed events */ - struct timed_event *timed_events; - - /* the maximum file descriptor number in fd_events */ - int maxfd; - - /* information for exiting from the event loop */ - int exit_code; - - /* this is incremented when the loop over events causes something which - could change the events yet to be processed */ - uint32_t destruction_count; -}; - -/* - create a select_event_context structure. -*/ -static int select_event_context_init(struct event_context *ev) -{ - struct select_event_context *select_ev; - - select_ev = talloc_zero(ev, struct select_event_context); - if (!select_ev) return -1; - select_ev->ev = ev; - - ev->additional_data = select_ev; - return 0; -} - -/* - recalculate the maxfd -*/ -static void calc_maxfd(struct select_event_context *select_ev) -{ - struct fd_event *fde; - - select_ev->maxfd = 0; - for (fde = select_ev->fd_events; fde; fde = fde->next) { - if (fde->fd > select_ev->maxfd) { - select_ev->maxfd = fde->fd; - } - } -} - - -/* to mark the ev->maxfd invalid - * this means we need to recalculate it - */ -#define EVENT_INVALID_MAXFD (-1) - -/* - destroy an fd_event -*/ -static int select_event_fd_destructor(struct fd_event *fde) -{ - struct event_context *ev = fde->event_ctx; - struct select_event_context *select_ev = talloc_get_type(ev->additional_data, - struct select_event_context); - - if (select_ev->maxfd == fde->fd) { - select_ev->maxfd = EVENT_INVALID_MAXFD; - } - - DLIST_REMOVE(select_ev->fd_events, fde); - select_ev->destruction_count++; - - if (fde->flags & EVENT_FD_AUTOCLOSE) { - close(fde->fd); - fde->fd = -1; - } - - return 0; -} - -/* - add a fd based event - return NULL on failure (memory allocation error) -*/ -static struct fd_event *select_event_add_fd(struct event_context *ev, TALLOC_CTX *mem_ctx, - int fd, uint16_t flags, - event_fd_handler_t handler, - void *private_data) -{ - struct select_event_context *select_ev = talloc_get_type(ev->additional_data, - struct select_event_context); - struct fd_event *fde; - - fde = talloc(mem_ctx?mem_ctx:ev, struct fd_event); - if (!fde) return NULL; - - fde->event_ctx = ev; - fde->fd = fd; - fde->flags = flags; - fde->handler = handler; - fde->private_data = private_data; - fde->additional_flags = 0; - fde->additional_data = NULL; - - DLIST_ADD(select_ev->fd_events, fde); - if (fde->fd > select_ev->maxfd) { - select_ev->maxfd = fde->fd; - } - talloc_set_destructor(fde, select_event_fd_destructor); - - return fde; -} - - -/* - return the fd event flags -*/ -static uint16_t select_event_get_fd_flags(struct fd_event *fde) -{ - return fde->flags; -} - -/* - set the fd event flags -*/ -static void select_event_set_fd_flags(struct fd_event *fde, uint16_t flags) -{ - struct event_context *ev; - struct select_event_context *select_ev; - - if (fde->flags == flags) return; - - ev = fde->event_ctx; - select_ev = talloc_get_type(ev->additional_data, struct select_event_context); - - fde->flags = flags; -} - -/* - event loop handling using select() -*/ -static int select_event_loop_select(struct select_event_context *select_ev, struct timeval *tvalp) -{ - fd_set r_fds, w_fds; - struct fd_event *fde; - int selrtn; - uint32_t destruction_count = ++select_ev->destruction_count; - - /* we maybe need to recalculate the maxfd */ - if (select_ev->maxfd == EVENT_INVALID_MAXFD) { - calc_maxfd(select_ev); - } - - FD_ZERO(&r_fds); - FD_ZERO(&w_fds); - - /* setup any fd events */ - for (fde = select_ev->fd_events; fde; fde = fde->next) { - if (fde->flags & EVENT_FD_READ) { - FD_SET(fde->fd, &r_fds); - } - if (fde->flags & EVENT_FD_WRITE) { - FD_SET(fde->fd, &w_fds); - } - } - - if (select_ev->ev->num_signal_handlers && - common_event_check_signal(select_ev->ev)) { - return 0; - } - - selrtn = select(select_ev->maxfd+1, &r_fds, &w_fds, NULL, tvalp); - - if (selrtn == -1 && errno == EINTR && - select_ev->ev->num_signal_handlers) { - common_event_check_signal(select_ev->ev); - return 0; - } - - if (selrtn == -1 && errno == EBADF) { - /* the socket is dead! this should never - happen as the socket should have first been - made readable and that should have removed - the event, so this must be a bug. This is a - fatal error. */ - ev_debug(select_ev->ev, EV_DEBUG_FATAL, - "ERROR: EBADF on select_event_loop_once\n"); - select_ev->exit_code = EBADF; - return -1; - } - - if (selrtn == 0 && tvalp) { - /* we don't care about a possible delay here */ - common_event_loop_timer_delay(select_ev->ev); - return 0; - } - - if (selrtn > 0) { - /* at least one file descriptor is ready - check - which ones and call the handler, being careful to allow - the handler to remove itself when called */ - for (fde = select_ev->fd_events; fde; fde = fde->next) { - uint16_t flags = 0; - - if (FD_ISSET(fde->fd, &r_fds)) flags |= EVENT_FD_READ; - if (FD_ISSET(fde->fd, &w_fds)) flags |= EVENT_FD_WRITE; - if (flags) { - fde->handler(select_ev->ev, fde, flags, fde->private_data); - if (destruction_count != select_ev->destruction_count) { - break; - } - } - } - } - - return 0; -} - -/* - do a single event loop using the events defined in ev -*/ -static int select_event_loop_once(struct event_context *ev) -{ - struct select_event_context *select_ev = talloc_get_type(ev->additional_data, - struct select_event_context); - struct timeval tval; - - tval = common_event_loop_timer_delay(ev); - if (ev_timeval_is_zero(&tval)) { - return 0; - } - - return select_event_loop_select(select_ev, &tval); -} - -/* - return on failure or (with 0) if all fd events are removed -*/ -static int select_event_loop_wait(struct event_context *ev) -{ - struct select_event_context *select_ev = talloc_get_type(ev->additional_data, - struct select_event_context); - select_ev->exit_code = 0; - - while (select_ev->fd_events && select_ev->exit_code == 0) { - if (select_event_loop_once(ev) != 0) { - break; - } - } - - return select_ev->exit_code; -} - -static const struct event_ops select_event_ops = { - .context_init = select_event_context_init, - .add_fd = select_event_add_fd, - .get_fd_flags = select_event_get_fd_flags, - .set_fd_flags = select_event_set_fd_flags, - .add_timed = common_event_add_timed, - .add_signal = common_event_add_signal, - .loop_once = select_event_loop_once, - .loop_wait = select_event_loop_wait, -}; - -bool events_select_init(void) -{ - return event_register_backend("select", &select_event_ops); -} - diff --git a/source4/lib/events/events_signal.c b/source4/lib/events/events_signal.c deleted file mode 100644 index 652df53d4b..0000000000 --- a/source4/lib/events/events_signal.c +++ /dev/null @@ -1,291 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - common events code for signal events - - Copyright (C) Andrew Tridgell 2007 - - 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 <signal.h> -#include "replace.h" -#include "system/filesys.h" -#include "system/select.h" -#include "events.h" -#include "events_internal.h" -#include "events_util.h" - -#define NUM_SIGNALS 64 - -/* maximum number of SA_SIGINFO signals to hold in the queue */ -#define SA_INFO_QUEUE_COUNT 10 - -struct sigcounter { - uint32_t count; - uint32_t seen; -}; - -#define SIG_INCREMENT(s) (s).count++ -#define SIG_SEEN(s, n) (s).seen += (n) -#define SIG_PENDING(s) ((s).seen != (s).count) - - -/* - the poor design of signals means that this table must be static global -*/ -static struct sig_state { - struct signal_event *sig_handlers[NUM_SIGNALS+1]; - struct sigaction *oldact[NUM_SIGNALS+1]; - struct sigcounter signal_count[NUM_SIGNALS+1]; - struct sigcounter got_signal; - int pipe_hack[2]; -#ifdef SA_SIGINFO - /* with SA_SIGINFO we get quite a lot of info per signal */ - siginfo_t *sig_info[NUM_SIGNALS+1]; - struct sigcounter sig_blocked[NUM_SIGNALS+1]; -#endif -} *sig_state; - -/* - return number of sigcounter events not processed yet -*/ -static uint32_t sig_count(struct sigcounter s) -{ - if (s.count >= s.seen) { - return s.count - s.seen; - } - return 1 + (0xFFFFFFFF & ~(s.seen - s.count)); -} - -/* - signal handler - redirects to registered signals -*/ -static void signal_handler(int signum) -{ - char c = 0; - SIG_INCREMENT(sig_state->signal_count[signum]); - SIG_INCREMENT(sig_state->got_signal); - /* doesn't matter if this pipe overflows */ - write(sig_state->pipe_hack[1], &c, 1); -} - -#ifdef SA_SIGINFO -/* - signal handler with SA_SIGINFO - redirects to registered signals -*/ -static void signal_handler_info(int signum, siginfo_t *info, void *uctx) -{ - uint32_t count = sig_count(sig_state->signal_count[signum]); - sig_state->sig_info[signum][count] = *info; - - signal_handler(signum); - - /* handle SA_SIGINFO */ - if (count+1 == SA_INFO_QUEUE_COUNT) { - /* we've filled the info array - block this signal until - these ones are delivered */ - sigset_t set; - sigemptyset(&set); - sigaddset(&set, signum); - sigprocmask(SIG_BLOCK, &set, NULL); - SIG_INCREMENT(sig_state->sig_blocked[signum]); - } -} -#endif - -/* - destroy a signal event -*/ -static int signal_event_destructor(struct signal_event *se) -{ - se->event_ctx->num_signal_handlers--; - DLIST_REMOVE(sig_state->sig_handlers[se->signum], se); - if (sig_state->sig_handlers[se->signum] == NULL) { - /* restore old handler, if any */ - sigaction(se->signum, sig_state->oldact[se->signum], NULL); - sig_state->oldact[se->signum] = NULL; -#ifdef SA_SIGINFO - if (se->sa_flags & SA_SIGINFO) { - talloc_free(sig_state->sig_info[se->signum]); - sig_state->sig_info[se->signum] = NULL; - } -#endif - } - return 0; -} - -/* - this is part of the pipe hack needed to avoid the signal race condition -*/ -static void signal_pipe_handler(struct event_context *ev, struct fd_event *fde, - uint16_t flags, void *private) -{ - char c[16]; - /* its non-blocking, doesn't matter if we read too much */ - read(sig_state->pipe_hack[0], c, sizeof(c)); -} - -/* - add a signal event - return NULL on failure (memory allocation error) -*/ -struct signal_event *common_event_add_signal(struct event_context *ev, - TALLOC_CTX *mem_ctx, - int signum, - int sa_flags, - event_signal_handler_t handler, - void *private_data) -{ - struct signal_event *se; - - if (signum >= NUM_SIGNALS) { - return NULL; - } - - /* the sig_state needs to be on a global context as it can last across - multiple event contexts */ - if (sig_state == NULL) { - sig_state = talloc_zero(talloc_autofree_context(), struct sig_state); - if (sig_state == NULL) { - return NULL; - } - } - - se = talloc(mem_ctx?mem_ctx:ev, struct signal_event); - if (se == NULL) return NULL; - - se->event_ctx = ev; - se->handler = handler; - se->private_data = private_data; - se->signum = signum; - se->sa_flags = sa_flags; - - /* Ensure, no matter the destruction order, that we always have a handle on the global sig_state */ - if (!talloc_reference(se, sig_state)) { - return NULL; - } - - /* only install a signal handler if not already installed */ - if (sig_state->sig_handlers[signum] == NULL) { - struct sigaction act; - ZERO_STRUCT(act); - act.sa_handler = signal_handler; - act.sa_flags = sa_flags; -#ifdef SA_SIGINFO - if (sa_flags & SA_SIGINFO) { - act.sa_handler = NULL; - act.sa_sigaction = signal_handler_info; - if (sig_state->sig_info[signum] == NULL) { - sig_state->sig_info[signum] = talloc_array(sig_state, siginfo_t, SA_INFO_QUEUE_COUNT); - if (sig_state->sig_info[signum] == NULL) { - talloc_free(se); - return NULL; - } - } - } -#endif - sig_state->oldact[signum] = talloc(sig_state, struct sigaction); - if (sig_state->oldact[signum] == NULL) { - talloc_free(se); - return NULL; - } - if (sigaction(signum, &act, sig_state->oldact[signum]) == -1) { - talloc_free(se); - return NULL; - } - } - - DLIST_ADD(sig_state->sig_handlers[signum], se); - - talloc_set_destructor(se, signal_event_destructor); - - /* we need to setup the pipe hack handler if not already - setup */ - if (ev->pipe_fde == NULL) { - if (sig_state->pipe_hack[0] == 0 && - sig_state->pipe_hack[1] == 0) { - pipe(sig_state->pipe_hack); - ev_set_blocking(sig_state->pipe_hack[0], false); - ev_set_blocking(sig_state->pipe_hack[1], false); - } - ev->pipe_fde = event_add_fd(ev, ev, sig_state->pipe_hack[0], - EVENT_FD_READ, signal_pipe_handler, NULL); - } - ev->num_signal_handlers++; - - return se; -} - - -/* - check if a signal is pending - return != 0 if a signal was pending -*/ -int common_event_check_signal(struct event_context *ev) -{ - int i; - - if (!sig_state || !SIG_PENDING(sig_state->got_signal)) { - return 0; - } - - for (i=0;i<NUM_SIGNALS+1;i++) { - struct signal_event *se, *next; - struct sigcounter counter = sig_state->signal_count[i]; - uint32_t count = sig_count(counter); - - if (count == 0) { - continue; - } - for (se=sig_state->sig_handlers[i];se;se=next) { - next = se->next; -#ifdef SA_SIGINFO - if (se->sa_flags & SA_SIGINFO) { - int j; - for (j=0;j<count;j++) { - /* note the use of the sig_info array as a - ring buffer */ - int ofs = ((count-1) + j) % SA_INFO_QUEUE_COUNT; - se->handler(ev, se, i, 1, - (void*)&sig_state->sig_info[i][ofs], - se->private_data); - } - if (SIG_PENDING(sig_state->sig_blocked[i])) { - /* we'd filled the queue, unblock the - signal now */ - sigset_t set; - sigemptyset(&set); - sigaddset(&set, i); - SIG_SEEN(sig_state->sig_blocked[i], - sig_count(sig_state->sig_blocked[i])); - sigprocmask(SIG_UNBLOCK, &set, NULL); - } - if (se->sa_flags & SA_RESETHAND) { - talloc_free(se); - } - continue; - } -#endif - se->handler(ev, se, i, count, NULL, se->private_data); - if (se->sa_flags & SA_RESETHAND) { - talloc_free(se); - } - } - SIG_SEEN(sig_state->signal_count[i], count); - SIG_SEEN(sig_state->got_signal, count); - } - - return 1; -} diff --git a/source4/lib/events/events_standard.c b/source4/lib/events/events_standard.c deleted file mode 100644 index 11128d7623..0000000000 --- a/source4/lib/events/events_standard.c +++ /dev/null @@ -1,607 +0,0 @@ -/* - Unix SMB/CIFS implementation. - main select loop and event handling - Copyright (C) Andrew Tridgell 2003-2005 - Copyright (C) Stefan Metzmacher 2005 - - 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/>. -*/ - -/* - This is SAMBA's default event loop code - - - we try to use epoll if configure detected support for it - otherwise we use select() - - if epoll is broken on the system or the kernel doesn't support it - at runtime we fallback to select() -*/ - -#include "replace.h" -#include "system/filesys.h" -#include "system/network.h" -#include "system/select.h" /* needed for HAVE_EVENTS_EPOLL */ -#include "events.h" -#include "events_util.h" -#include "events_internal.h" - -struct std_event_context { - /* a pointer back to the generic event_context */ - struct event_context *ev; - - /* list of filedescriptor events */ - struct fd_event *fd_events; - - /* the maximum file descriptor number in fd_events */ - int maxfd; - - /* information for exiting from the event loop */ - int exit_code; - - /* this is changed by the destructors for the fd event - type. It is used to detect event destruction by event - handlers, which means the code that is calling the event - handler needs to assume that the linked list is no longer - valid - */ - uint32_t destruction_count; - - /* when using epoll this is the handle from epoll_create */ - int epoll_fd; - - /* our pid at the time the epoll_fd was created */ - pid_t pid; -}; - -/* use epoll if it is available */ -#if HAVE_EVENTS_EPOLL -/* - called when a epoll call fails, and we should fallback - to using select -*/ -static void epoll_fallback_to_select(struct std_event_context *std_ev, const char *reason) -{ - ev_debug(std_ev->ev, EV_DEBUG_FATAL, - "%s (%s) - falling back to select()\n", - reason, strerror(errno)); - close(std_ev->epoll_fd); - std_ev->epoll_fd = -1; - talloc_set_destructor(std_ev, NULL); -} - -/* - map from EVENT_FD_* to EPOLLIN/EPOLLOUT -*/ -static uint32_t epoll_map_flags(uint16_t flags) -{ - uint32_t ret = 0; - if (flags & EVENT_FD_READ) ret |= (EPOLLIN | EPOLLERR | EPOLLHUP); - if (flags & EVENT_FD_WRITE) ret |= (EPOLLOUT | EPOLLERR | EPOLLHUP); - return ret; -} - -/* - free the epoll fd -*/ -static int epoll_ctx_destructor(struct std_event_context *std_ev) -{ - if (std_ev->epoll_fd != -1) { - close(std_ev->epoll_fd); - } - std_ev->epoll_fd = -1; - return 0; -} - -/* - init the epoll fd -*/ -static void epoll_init_ctx(struct std_event_context *std_ev) -{ - std_ev->epoll_fd = epoll_create(64); - std_ev->pid = getpid(); - talloc_set_destructor(std_ev, epoll_ctx_destructor); -} - -static void epoll_add_event(struct std_event_context *std_ev, struct fd_event *fde); - -/* - reopen the epoll handle when our pid changes - see http://junkcode.samba.org/ftp/unpacked/junkcode/epoll_fork.c for an - demonstration of why this is needed - */ -static void epoll_check_reopen(struct std_event_context *std_ev) -{ - struct fd_event *fde; - - if (std_ev->pid == getpid()) { - return; - } - - close(std_ev->epoll_fd); - std_ev->epoll_fd = epoll_create(64); - if (std_ev->epoll_fd == -1) { - ev_debug(std_ev->ev, EV_DEBUG_FATAL, - "Failed to recreate epoll handle after fork\n"); - return; - } - std_ev->pid = getpid(); - for (fde=std_ev->fd_events;fde;fde=fde->next) { - epoll_add_event(std_ev, fde); - } -} - -#define EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT (1<<0) -#define EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR (1<<1) -#define EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR (1<<2) - -/* - add the epoll event to the given fd_event -*/ -static void epoll_add_event(struct std_event_context *std_ev, struct fd_event *fde) -{ - struct epoll_event event; - if (std_ev->epoll_fd == -1) return; - - fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; - - /* if we don't want events yet, don't add an epoll_event */ - if (fde->flags == 0) return; - - ZERO_STRUCT(event); - event.events = epoll_map_flags(fde->flags); - event.data.ptr = fde; - if (epoll_ctl(std_ev->epoll_fd, EPOLL_CTL_ADD, fde->fd, &event) != 0) { - epoll_fallback_to_select(std_ev, "EPOLL_CTL_ADD failed"); - } - fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; - - /* only if we want to read we want to tell the event handler about errors */ - if (fde->flags & EVENT_FD_READ) { - fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; - } -} - -/* - delete the epoll event for given fd_event -*/ -static void epoll_del_event(struct std_event_context *std_ev, struct fd_event *fde) -{ - struct epoll_event event; - if (std_ev->epoll_fd == -1) return; - - fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; - - /* if there's no epoll_event, we don't need to delete it */ - if (!(fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT)) return; - - ZERO_STRUCT(event); - event.events = epoll_map_flags(fde->flags); - event.data.ptr = fde; - epoll_ctl(std_ev->epoll_fd, EPOLL_CTL_DEL, fde->fd, &event); - fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; -} - -/* - change the epoll event to the given fd_event -*/ -static void epoll_mod_event(struct std_event_context *std_ev, struct fd_event *fde) -{ - struct epoll_event event; - if (std_ev->epoll_fd == -1) return; - - fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; - - ZERO_STRUCT(event); - event.events = epoll_map_flags(fde->flags); - event.data.ptr = fde; - if (epoll_ctl(std_ev->epoll_fd, EPOLL_CTL_MOD, fde->fd, &event) != 0) { - epoll_fallback_to_select(std_ev, "EPOLL_CTL_MOD failed"); - } - - /* only if we want to read we want to tell the event handler about errors */ - if (fde->flags & EVENT_FD_READ) { - fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; - } -} - -static void epoll_change_event(struct std_event_context *std_ev, struct fd_event *fde) -{ - bool got_error = (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR); - bool want_read = (fde->flags & EVENT_FD_READ); - bool want_write= (fde->flags & EVENT_FD_WRITE); - - if (std_ev->epoll_fd == -1) return; - - fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; - - /* there's already an event */ - if (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT) { - if (want_read || (want_write && !got_error)) { - epoll_mod_event(std_ev, fde); - return; - } - /* - * if we want to match the select behavior, we need to remove the epoll_event - * when the caller isn't interested in events. - * - * this is because epoll reports EPOLLERR and EPOLLHUP, even without asking for them - */ - epoll_del_event(std_ev, fde); - return; - } - - /* there's no epoll_event attached to the fde */ - if (want_read || (want_write && !got_error)) { - epoll_add_event(std_ev, fde); - return; - } -} - -/* - event loop handling using epoll -*/ -static int epoll_event_loop(struct std_event_context *std_ev, struct timeval *tvalp) -{ - int ret, i; -#define MAXEVENTS 8 - struct epoll_event events[MAXEVENTS]; - uint32_t destruction_count = ++std_ev->destruction_count; - int timeout = -1; - - if (std_ev->epoll_fd == -1) return -1; - - if (tvalp) { - /* it's better to trigger timed events a bit later than to early */ - timeout = ((tvalp->tv_usec+999) / 1000) + (tvalp->tv_sec*1000); - } - - if (std_ev->ev->num_signal_handlers && - common_event_check_signal(std_ev->ev)) { - return 0; - } - - ret = epoll_wait(std_ev->epoll_fd, events, MAXEVENTS, timeout); - - if (ret == -1 && errno == EINTR && std_ev->ev->num_signal_handlers) { - if (common_event_check_signal(std_ev->ev)) { - return 0; - } - } - - if (ret == -1 && errno != EINTR) { - epoll_fallback_to_select(std_ev, "epoll_wait() failed"); - return -1; - } - - if (ret == 0 && tvalp) { - /* we don't care about a possible delay here */ - common_event_loop_timer_delay(std_ev->ev); - return 0; - } - - for (i=0;i<ret;i++) { - struct fd_event *fde = talloc_get_type(events[i].data.ptr, - struct fd_event); - uint16_t flags = 0; - - if (fde == NULL) { - epoll_fallback_to_select(std_ev, "epoll_wait() gave bad data"); - return -1; - } - if (events[i].events & (EPOLLHUP|EPOLLERR)) { - fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR; - /* - * if we only wait for EVENT_FD_WRITE, we should not tell the - * event handler about it, and remove the epoll_event, - * as we only report errors when waiting for read events, - * to match the select() behavior - */ - if (!(fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR)) { - epoll_del_event(std_ev, fde); - continue; - } - flags |= EVENT_FD_READ; - } - if (events[i].events & EPOLLIN) flags |= EVENT_FD_READ; - if (events[i].events & EPOLLOUT) flags |= EVENT_FD_WRITE; - if (flags) { - fde->handler(std_ev->ev, fde, flags, fde->private_data); - if (destruction_count != std_ev->destruction_count) { - break; - } - } - } - - return 0; -} -#else -#define epoll_init_ctx(std_ev) -#define epoll_add_event(std_ev,fde) -#define epoll_del_event(std_ev,fde) -#define epoll_change_event(std_ev,fde) -#define epoll_event_loop(std_ev,tvalp) (-1) -#define epoll_check_reopen(std_ev) -#endif - -/* - create a std_event_context structure. -*/ -static int std_event_context_init(struct event_context *ev) -{ - struct std_event_context *std_ev; - - std_ev = talloc_zero(ev, struct std_event_context); - if (!std_ev) return -1; - std_ev->ev = ev; - std_ev->epoll_fd = -1; - - epoll_init_ctx(std_ev); - - ev->additional_data = std_ev; - return 0; -} - -/* - recalculate the maxfd -*/ -static void calc_maxfd(struct std_event_context *std_ev) -{ - struct fd_event *fde; - - std_ev->maxfd = 0; - for (fde = std_ev->fd_events; fde; fde = fde->next) { - if (fde->fd > std_ev->maxfd) { - std_ev->maxfd = fde->fd; - } - } -} - - -/* to mark the ev->maxfd invalid - * this means we need to recalculate it - */ -#define EVENT_INVALID_MAXFD (-1) - -/* - destroy an fd_event -*/ -static int std_event_fd_destructor(struct fd_event *fde) -{ - struct event_context *ev = fde->event_ctx; - struct std_event_context *std_ev = talloc_get_type(ev->additional_data, - struct std_event_context); - - epoll_check_reopen(std_ev); - - if (std_ev->maxfd == fde->fd) { - std_ev->maxfd = EVENT_INVALID_MAXFD; - } - - DLIST_REMOVE(std_ev->fd_events, fde); - std_ev->destruction_count++; - - epoll_del_event(std_ev, fde); - - if (fde->flags & EVENT_FD_AUTOCLOSE) { - close(fde->fd); - fde->fd = -1; - } - - return 0; -} - -/* - add a fd based event - return NULL on failure (memory allocation error) -*/ -static struct fd_event *std_event_add_fd(struct event_context *ev, TALLOC_CTX *mem_ctx, - int fd, uint16_t flags, - event_fd_handler_t handler, - void *private_data) -{ - struct std_event_context *std_ev = talloc_get_type(ev->additional_data, - struct std_event_context); - struct fd_event *fde; - - epoll_check_reopen(std_ev); - - fde = talloc(mem_ctx?mem_ctx:ev, struct fd_event); - if (!fde) return NULL; - - fde->event_ctx = ev; - fde->fd = fd; - fde->flags = flags; - fde->handler = handler; - fde->private_data = private_data; - fde->additional_flags = 0; - fde->additional_data = NULL; - - DLIST_ADD(std_ev->fd_events, fde); - if ((std_ev->maxfd != EVENT_INVALID_MAXFD) - && (fde->fd > std_ev->maxfd)) { - std_ev->maxfd = fde->fd; - } - talloc_set_destructor(fde, std_event_fd_destructor); - - epoll_add_event(std_ev, fde); - - return fde; -} - - -/* - return the fd event flags -*/ -static uint16_t std_event_get_fd_flags(struct fd_event *fde) -{ - return fde->flags; -} - -/* - set the fd event flags -*/ -static void std_event_set_fd_flags(struct fd_event *fde, uint16_t flags) -{ - struct event_context *ev; - struct std_event_context *std_ev; - - if (fde->flags == flags) return; - - ev = fde->event_ctx; - std_ev = talloc_get_type(ev->additional_data, struct std_event_context); - - fde->flags = flags; - - epoll_check_reopen(std_ev); - - epoll_change_event(std_ev, fde); -} - -/* - event loop handling using select() -*/ -static int std_event_loop_select(struct std_event_context *std_ev, struct timeval *tvalp) -{ - fd_set r_fds, w_fds; - struct fd_event *fde; - int selrtn; - uint32_t destruction_count = ++std_ev->destruction_count; - - /* we maybe need to recalculate the maxfd */ - if (std_ev->maxfd == EVENT_INVALID_MAXFD) { - calc_maxfd(std_ev); - } - - FD_ZERO(&r_fds); - FD_ZERO(&w_fds); - - /* setup any fd events */ - for (fde = std_ev->fd_events; fde; fde = fde->next) { - if (fde->flags & EVENT_FD_READ) { - FD_SET(fde->fd, &r_fds); - } - if (fde->flags & EVENT_FD_WRITE) { - FD_SET(fde->fd, &w_fds); - } - } - - if (std_ev->ev->num_signal_handlers && - common_event_check_signal(std_ev->ev)) { - return 0; - } - - selrtn = select(std_ev->maxfd+1, &r_fds, &w_fds, NULL, tvalp); - - if (selrtn == -1 && errno == EINTR && - std_ev->ev->num_signal_handlers) { - common_event_check_signal(std_ev->ev); - return 0; - } - - if (selrtn == -1 && errno == EBADF) { - /* the socket is dead! this should never - happen as the socket should have first been - made readable and that should have removed - the event, so this must be a bug. This is a - fatal error. */ - ev_debug(std_ev->ev, EV_DEBUG_FATAL, - "ERROR: EBADF on std_event_loop_once\n"); - std_ev->exit_code = EBADF; - return -1; - } - - if (selrtn == 0 && tvalp) { - /* we don't care about a possible delay here */ - common_event_loop_timer_delay(std_ev->ev); - return 0; - } - - if (selrtn > 0) { - /* at least one file descriptor is ready - check - which ones and call the handler, being careful to allow - the handler to remove itself when called */ - for (fde = std_ev->fd_events; fde; fde = fde->next) { - uint16_t flags = 0; - - if (FD_ISSET(fde->fd, &r_fds)) flags |= EVENT_FD_READ; - if (FD_ISSET(fde->fd, &w_fds)) flags |= EVENT_FD_WRITE; - if (flags) { - fde->handler(std_ev->ev, fde, flags, fde->private_data); - if (destruction_count != std_ev->destruction_count) { - break; - } - } - } - } - - return 0; -} - -/* - do a single event loop using the events defined in ev -*/ -static int std_event_loop_once(struct event_context *ev) -{ - struct std_event_context *std_ev = talloc_get_type(ev->additional_data, - struct std_event_context); - struct timeval tval; - - tval = common_event_loop_timer_delay(ev); - if (ev_timeval_is_zero(&tval)) { - return 0; - } - - epoll_check_reopen(std_ev); - - if (epoll_event_loop(std_ev, &tval) == 0) { - return 0; - } - - return std_event_loop_select(std_ev, &tval); -} - -/* - return on failure or (with 0) if all fd events are removed -*/ -static int std_event_loop_wait(struct event_context *ev) -{ - struct std_event_context *std_ev = talloc_get_type(ev->additional_data, - struct std_event_context); - std_ev->exit_code = 0; - - while (std_ev->fd_events && std_ev->exit_code == 0) { - if (std_event_loop_once(ev) != 0) { - break; - } - } - - return std_ev->exit_code; -} - -static const struct event_ops std_event_ops = { - .context_init = std_event_context_init, - .add_fd = std_event_add_fd, - .get_fd_flags = std_event_get_fd_flags, - .set_fd_flags = std_event_set_fd_flags, - .add_timed = common_event_add_timed, - .add_signal = common_event_add_signal, - .loop_once = std_event_loop_once, - .loop_wait = std_event_loop_wait, -}; - - -bool events_standard_init(void) -{ - return event_register_backend("standard", &std_event_ops); -} - diff --git a/source4/lib/events/events_timed.c b/source4/lib/events/events_timed.c deleted file mode 100644 index c58c898c6d..0000000000 --- a/source4/lib/events/events_timed.c +++ /dev/null @@ -1,230 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - common events code for timed events - - Copyright (C) Andrew Tridgell 2003-2006 - Copyright (C) Stefan Metzmacher 2005 - - 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 <sys/time.h> -#include <time.h> -#include "replace.h" -#include "system/filesys.h" -#include "system/select.h" -#include "events.h" -#include "events_internal.h" -#include "events_util.h" - -/** - compare two timeval structures. - Return -1 if tv1 < tv2 - Return 0 if tv1 == tv2 - Return 1 if tv1 > tv2 -*/ -static int ev_timeval_compare(const struct timeval *tv1, const struct timeval *tv2) -{ - if (tv1->tv_sec > tv2->tv_sec) return 1; - if (tv1->tv_sec < tv2->tv_sec) return -1; - if (tv1->tv_usec > tv2->tv_usec) return 1; - if (tv1->tv_usec < tv2->tv_usec) return -1; - return 0; -} - -/** - return a zero timeval -*/ -static struct timeval ev_timeval_zero(void) -{ - struct timeval tv; - tv.tv_sec = 0; - tv.tv_usec = 0; - return tv; -} - -/** - return a timeval for the current time -*/ -static struct timeval ev_timeval_current(void) -{ - struct timeval tv; - gettimeofday(&tv, NULL); - return tv; -} - -/** - return a timeval struct with the given elements -*/ -static struct timeval ev_timeval_set(uint32_t secs, uint32_t usecs) -{ - struct timeval tv; - tv.tv_sec = secs; - tv.tv_usec = usecs; - return tv; -} - -/** - return the difference between two timevals as a timeval - if tv1 comes after tv2, then return a zero timeval - (this is *tv2 - *tv1) -*/ -static struct timeval ev_timeval_until(const struct timeval *tv1, - const struct timeval *tv2) -{ - struct timeval t; - if (ev_timeval_compare(tv1, tv2) >= 0) { - return ev_timeval_zero(); - } - t.tv_sec = tv2->tv_sec - tv1->tv_sec; - if (tv1->tv_usec > tv2->tv_usec) { - t.tv_sec--; - t.tv_usec = 1000000 - (tv1->tv_usec - tv2->tv_usec); - } else { - t.tv_usec = tv2->tv_usec - tv1->tv_usec; - } - return t; -} - -/** - return true if a timeval is zero -*/ -bool ev_timeval_is_zero(const struct timeval *tv) -{ - return tv->tv_sec == 0 && tv->tv_usec == 0; -} - -/* - destroy a timed event -*/ -static int common_event_timed_destructor(struct timed_event *te) -{ - struct event_context *ev = talloc_get_type(te->event_ctx, - struct event_context); - DLIST_REMOVE(ev->timed_events, te); - return 0; -} - -static int common_event_timed_deny_destructor(struct timed_event *te) -{ - return -1; -} - -/* - add a timed event - return NULL on failure (memory allocation error) -*/ -struct timed_event *common_event_add_timed(struct event_context *ev, TALLOC_CTX *mem_ctx, - struct timeval next_event, - event_timed_handler_t handler, - void *private_data) -{ - struct timed_event *te, *last_te, *cur_te; - - te = talloc(mem_ctx?mem_ctx:ev, struct timed_event); - if (te == NULL) return NULL; - - te->event_ctx = ev; - te->next_event = next_event; - te->handler = handler; - te->private_data = private_data; - te->additional_data = NULL; - - /* keep the list ordered */ - last_te = NULL; - for (cur_te = ev->timed_events; cur_te; cur_te = cur_te->next) { - /* if the new event comes before the current one break */ - if (ev_timeval_compare(&te->next_event, &cur_te->next_event) < 0) { - break; - } - - last_te = cur_te; - } - - DLIST_ADD_AFTER(ev->timed_events, te, last_te); - - talloc_set_destructor(te, common_event_timed_destructor); - - return te; -} - -/* - do a single event loop using the events defined in ev - - return the delay untill the next timed event, - or zero if a timed event was triggered -*/ -struct timeval common_event_loop_timer_delay(struct event_context *ev) -{ - struct timeval current_time = ev_timeval_zero(); - struct timed_event *te = ev->timed_events; - - if (!te) { - /* have a default tick time of 30 seconds. This guarantees - that code that uses its own timeout checking will be - able to proceeed eventually */ - return ev_timeval_set(30, 0); - } - - /* - * work out the right timeout for the next timed event - * - * avoid the syscall to gettimeofday() if the timed event should - * be triggered directly - * - * if there's a delay till the next timed event, we're done - * with just returning the delay - */ - if (!ev_timeval_is_zero(&te->next_event)) { - struct timeval delay; - - current_time = ev_timeval_current(); - - delay = ev_timeval_until(¤t_time, &te->next_event); - if (!ev_timeval_is_zero(&delay)) { - return delay; - } - } - - /* - * ok, we have a timed event that we'll process ... - */ - - /* deny the handler to free the event */ - talloc_set_destructor(te, common_event_timed_deny_destructor); - - /* We need to remove the timer from the list before calling the - * handler because in a semi-async inner event loop called from the - * handler we don't want to come across this event again -- vl */ - DLIST_REMOVE(ev->timed_events, te); - - /* - * If the timed event was registered for a zero current_time, - * then we pass a zero timeval here too! To avoid the - * overhead of gettimeofday() calls. - * - * otherwise we pass the current time - */ - te->handler(ev, te, current_time, te->private_data); - - /* The destructor isn't necessary anymore, we've already removed the - * event from the list. */ - talloc_set_destructor(te, NULL); - - talloc_free(te); - - return ev_timeval_zero(); -} - diff --git a/source4/lib/events/events_util.c b/source4/lib/events/events_util.c deleted file mode 100644 index 9e7d758405..0000000000 --- a/source4/lib/events/events_util.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Copyright (C) Andrew Tridgell 2005 - Copyright (C) Jelmer Vernooij 2005 - - 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 "replace.h" -#include "talloc.h" -#include "events.h" -#include "events_internal.h" -#include "events_util.h" -#include <fcntl.h> - -/** - return the number of elements in a string list -*/ -static size_t str_list_length(const char **list) -{ - size_t ret; - for (ret=0;list && list[ret];ret++) /* noop */ ; - return ret; -} - -/** - add an entry to a string list -*/ -const char **ev_str_list_add(const char **list, const char *s) -{ - size_t len = str_list_length(list); - const char **ret; - - ret = talloc_realloc(NULL, list, const char *, len+2); - if (ret == NULL) return NULL; - - ret[len] = talloc_strdup(ret, s); - if (ret[len] == NULL) return NULL; - - ret[len+1] = NULL; - - return ret; -} - - -/** - Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available, - else - if SYSV use O_NDELAY - if BSD use FNDELAY -**/ - -int ev_set_blocking(int fd, bool set) -{ - int val; -#ifdef O_NONBLOCK -#define FLAG_TO_SET O_NONBLOCK -#else -#ifdef SYSV -#define FLAG_TO_SET O_NDELAY -#else /* BSD */ -#define FLAG_TO_SET FNDELAY -#endif -#endif - - if((val = fcntl(fd, F_GETFL, 0)) == -1) - return -1; - if(set) /* Turn blocking on - ie. clear nonblock flag */ - val &= ~FLAG_TO_SET; - else - val |= FLAG_TO_SET; - return fcntl( fd, F_SETFL, val); -#undef FLAG_TO_SET -} diff --git a/source4/lib/events/events_util.h b/source4/lib/events/events_util.h deleted file mode 100644 index 052b302aae..0000000000 --- a/source4/lib/events/events_util.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Copyright (C) Andrew Tridgell 1998-2005 - Copyright (C) Jelmer Vernooij 2005 - - 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/>. -*/ - -/* To use these macros you must have a structure containing a next and - prev pointer */ - -#ifndef _DLINKLIST_H -#define _DLINKLIST_H - - -/* hook into the front of the list */ -#define DLIST_ADD(list, p) \ -do { \ - if (!(list)) { \ - (list) = (p); \ - (p)->next = (p)->prev = NULL; \ - } else { \ - (list)->prev = (p); \ - (p)->next = (list); \ - (p)->prev = NULL; \ - (list) = (p); \ - }\ -} while (0) - -/* remove an element from a list - element doesn't have to be in list. */ -#define DLIST_REMOVE(list, p) \ -do { \ - if ((p) == (list)) { \ - (list) = (p)->next; \ - if (list) (list)->prev = NULL; \ - } else { \ - if ((p)->prev) (p)->prev->next = (p)->next; \ - if ((p)->next) (p)->next->prev = (p)->prev; \ - } \ - if ((p) != (list)) (p)->next = (p)->prev = NULL; \ -} while (0) - -/* promote an element to the top of the list */ -#define DLIST_PROMOTE(list, p) \ -do { \ - DLIST_REMOVE(list, p); \ - DLIST_ADD(list, p); \ -} while (0) - -/* hook into the end of the list - needs a tmp pointer */ -#define DLIST_ADD_END(list, p, type) \ -do { \ - if (!(list)) { \ - (list) = (p); \ - (p)->next = (p)->prev = NULL; \ - } else { \ - type tmp; \ - for (tmp = (list); tmp->next; tmp = tmp->next) ; \ - tmp->next = (p); \ - (p)->next = NULL; \ - (p)->prev = tmp; \ - } \ -} while (0) - -/* insert 'p' after the given element 'el' in a list. If el is NULL then - this is the same as a DLIST_ADD() */ -#define DLIST_ADD_AFTER(list, p, el) \ -do { \ - if (!(list) || !(el)) { \ - DLIST_ADD(list, p); \ - } else { \ - p->prev = el; \ - p->next = el->next; \ - el->next = p; \ - if (p->next) p->next->prev = p; \ - }\ -} while (0) - -/* demote an element to the end of the list, needs a tmp pointer */ -#define DLIST_DEMOTE(list, p, tmp) \ -do { \ - DLIST_REMOVE(list, p); \ - DLIST_ADD_END(list, p, tmp); \ -} while (0) - -/* concatenate two lists - putting all elements of the 2nd list at the - end of the first list */ -#define DLIST_CONCATENATE(list1, list2, type) \ -do { \ - if (!(list1)) { \ - (list1) = (list2); \ - } else { \ - type tmp; \ - for (tmp = (list1); tmp->next; tmp = tmp->next) ; \ - tmp->next = (list2); \ - if (list2) { \ - (list2)->prev = tmp; \ - } \ - } \ -} while (0) - -#endif /* _DLINKLIST_H */ - -const char **ev_str_list_add(const char **list, const char *s); -int ev_set_blocking(int fd, bool set); diff --git a/source4/lib/events/events_wrap.c b/source4/lib/events/events_wrap.c deleted file mode 100644 index 335652101b..0000000000 --- a/source4/lib/events/events_wrap.c +++ /dev/null @@ -1,3348 +0,0 @@ -/* ---------------------------------------------------------------------------- - * This file was automatically generated by SWIG (http://www.swig.org). - * Version 1.3.36 - * - * This file is not intended to be easily readable and contains a number of - * coding conventions designed to improve portability and efficiency. Do not make - * changes to this file unless you know what you are doing--modify the SWIG - * interface file instead. - * ----------------------------------------------------------------------------- */ - -#define SWIGPYTHON -#define SWIG_PYTHON_NO_BUILD_NONE -/* ----------------------------------------------------------------------------- - * This section contains generic SWIG labels for method/variable - * declarations/attributes, and other compiler dependent labels. - * ----------------------------------------------------------------------------- */ - -/* template workaround for compilers that cannot correctly implement the C++ standard */ -#ifndef SWIGTEMPLATEDISAMBIGUATOR -# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560) -# define SWIGTEMPLATEDISAMBIGUATOR template -# elif defined(__HP_aCC) -/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */ -/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */ -# define SWIGTEMPLATEDISAMBIGUATOR template -# else -# define SWIGTEMPLATEDISAMBIGUATOR -# endif -#endif - -/* inline attribute */ -#ifndef SWIGINLINE -# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__)) -# define SWIGINLINE inline -# else -# define SWIGINLINE -# endif -#endif - -/* attribute recognised by some compilers to avoid 'unused' warnings */ -#ifndef SWIGUNUSED -# if defined(__GNUC__) -# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) -# define SWIGUNUSED __attribute__ ((__unused__)) -# else -# define SWIGUNUSED -# endif -# elif defined(__ICC) -# define SWIGUNUSED __attribute__ ((__unused__)) -# else -# define SWIGUNUSED -# endif -#endif - -#ifndef SWIG_MSC_UNSUPPRESS_4505 -# if defined(_MSC_VER) -# pragma warning(disable : 4505) /* unreferenced local function has been removed */ -# endif -#endif - -#ifndef SWIGUNUSEDPARM -# ifdef __cplusplus -# define SWIGUNUSEDPARM(p) -# else -# define SWIGUNUSEDPARM(p) p SWIGUNUSED -# endif -#endif - -/* internal SWIG method */ -#ifndef SWIGINTERN -# define SWIGINTERN static SWIGUNUSED -#endif - -/* internal inline SWIG method */ -#ifndef SWIGINTERNINLINE -# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE -#endif - -/* exporting methods */ -#if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) -# ifndef GCC_HASCLASSVISIBILITY -# define GCC_HASCLASSVISIBILITY -# endif -#endif - -#ifndef SWIGEXPORT -# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) -# if defined(STATIC_LINKED) -# define SWIGEXPORT -# else -# define SWIGEXPORT __declspec(dllexport) -# endif -# else -# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY) -# define SWIGEXPORT __attribute__ ((visibility("default"))) -# else -# define SWIGEXPORT -# endif -# endif -#endif - -/* calling conventions for Windows */ -#ifndef SWIGSTDCALL -# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) -# define SWIGSTDCALL __stdcall -# else -# define SWIGSTDCALL -# endif -#endif - -/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ -#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) -# define _CRT_SECURE_NO_DEPRECATE -#endif - -/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */ -#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE) -# define _SCL_SECURE_NO_DEPRECATE -#endif - - - -/* Python.h has to appear first */ -#include <Python.h> - -/* ----------------------------------------------------------------------------- - * swigrun.swg - * - * This file contains generic CAPI SWIG runtime support for pointer - * type checking. - * ----------------------------------------------------------------------------- */ - -/* This should only be incremented when either the layout of swig_type_info changes, - or for whatever reason, the runtime changes incompatibly */ -#define SWIG_RUNTIME_VERSION "4" - -/* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */ -#ifdef SWIG_TYPE_TABLE -# define SWIG_QUOTE_STRING(x) #x -# define SWIG_EXPAND_AND_QUOTE_STRING(x) SWIG_QUOTE_STRING(x) -# define SWIG_TYPE_TABLE_NAME SWIG_EXPAND_AND_QUOTE_STRING(SWIG_TYPE_TABLE) -#else -# define SWIG_TYPE_TABLE_NAME -#endif - -/* - You can use the SWIGRUNTIME and SWIGRUNTIMEINLINE macros for - creating a static or dynamic library from the swig runtime code. - In 99.9% of the cases, swig just needs to declare them as 'static'. - - But only do this if is strictly necessary, ie, if you have problems - with your compiler or so. -*/ - -#ifndef SWIGRUNTIME -# define SWIGRUNTIME SWIGINTERN -#endif - -#ifndef SWIGRUNTIMEINLINE -# define SWIGRUNTIMEINLINE SWIGRUNTIME SWIGINLINE -#endif - -/* Generic buffer size */ -#ifndef SWIG_BUFFER_SIZE -# define SWIG_BUFFER_SIZE 1024 -#endif - -/* Flags for pointer conversions */ -#define SWIG_POINTER_DISOWN 0x1 -#define SWIG_CAST_NEW_MEMORY 0x2 - -/* Flags for new pointer objects */ -#define SWIG_POINTER_OWN 0x1 - - -/* - Flags/methods for returning states. - - The swig conversion methods, as ConvertPtr, return and integer - that tells if the conversion was successful or not. And if not, - an error code can be returned (see swigerrors.swg for the codes). - - Use the following macros/flags to set or process the returning - states. - - In old swig versions, you usually write code as: - - if (SWIG_ConvertPtr(obj,vptr,ty.flags) != -1) { - // success code - } else { - //fail code - } - - Now you can be more explicit as: - - int res = SWIG_ConvertPtr(obj,vptr,ty.flags); - if (SWIG_IsOK(res)) { - // success code - } else { - // fail code - } - - that seems to be the same, but now you can also do - - Type *ptr; - int res = SWIG_ConvertPtr(obj,(void **)(&ptr),ty.flags); - if (SWIG_IsOK(res)) { - // success code - if (SWIG_IsNewObj(res) { - ... - delete *ptr; - } else { - ... - } - } else { - // fail code - } - - I.e., now SWIG_ConvertPtr can return new objects and you can - identify the case and take care of the deallocation. Of course that - requires also to SWIG_ConvertPtr to return new result values, as - - int SWIG_ConvertPtr(obj, ptr,...) { - if (<obj is ok>) { - if (<need new object>) { - *ptr = <ptr to new allocated object>; - return SWIG_NEWOBJ; - } else { - *ptr = <ptr to old object>; - return SWIG_OLDOBJ; - } - } else { - return SWIG_BADOBJ; - } - } - - Of course, returning the plain '0(success)/-1(fail)' still works, but you can be - more explicit by returning SWIG_BADOBJ, SWIG_ERROR or any of the - swig errors code. - - Finally, if the SWIG_CASTRANK_MODE is enabled, the result code - allows to return the 'cast rank', for example, if you have this - - int food(double) - int fooi(int); - - and you call - - food(1) // cast rank '1' (1 -> 1.0) - fooi(1) // cast rank '0' - - just use the SWIG_AddCast()/SWIG_CheckState() - - - */ -#define SWIG_OK (0) -#define SWIG_ERROR (-1) -#define SWIG_IsOK(r) (r >= 0) -#define SWIG_ArgError(r) ((r != SWIG_ERROR) ? r : SWIG_TypeError) - -/* The CastRankLimit says how many bits are used for the cast rank */ -#define SWIG_CASTRANKLIMIT (1 << 8) -/* The NewMask denotes the object was created (using new/malloc) */ -#define SWIG_NEWOBJMASK (SWIG_CASTRANKLIMIT << 1) -/* The TmpMask is for in/out typemaps that use temporal objects */ -#define SWIG_TMPOBJMASK (SWIG_NEWOBJMASK << 1) -/* Simple returning values */ -#define SWIG_BADOBJ (SWIG_ERROR) -#define SWIG_OLDOBJ (SWIG_OK) -#define SWIG_NEWOBJ (SWIG_OK | SWIG_NEWOBJMASK) -#define SWIG_TMPOBJ (SWIG_OK | SWIG_TMPOBJMASK) -/* Check, add and del mask methods */ -#define SWIG_AddNewMask(r) (SWIG_IsOK(r) ? (r | SWIG_NEWOBJMASK) : r) -#define SWIG_DelNewMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_NEWOBJMASK) : r) -#define SWIG_IsNewObj(r) (SWIG_IsOK(r) && (r & SWIG_NEWOBJMASK)) -#define SWIG_AddTmpMask(r) (SWIG_IsOK(r) ? (r | SWIG_TMPOBJMASK) : r) -#define SWIG_DelTmpMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_TMPOBJMASK) : r) -#define SWIG_IsTmpObj(r) (SWIG_IsOK(r) && (r & SWIG_TMPOBJMASK)) - - -/* Cast-Rank Mode */ -#if defined(SWIG_CASTRANK_MODE) -# ifndef SWIG_TypeRank -# define SWIG_TypeRank unsigned long -# endif -# ifndef SWIG_MAXCASTRANK /* Default cast allowed */ -# define SWIG_MAXCASTRANK (2) -# endif -# define SWIG_CASTRANKMASK ((SWIG_CASTRANKLIMIT) -1) -# define SWIG_CastRank(r) (r & SWIG_CASTRANKMASK) -SWIGINTERNINLINE int SWIG_AddCast(int r) { - return SWIG_IsOK(r) ? ((SWIG_CastRank(r) < SWIG_MAXCASTRANK) ? (r + 1) : SWIG_ERROR) : r; -} -SWIGINTERNINLINE int SWIG_CheckState(int r) { - return SWIG_IsOK(r) ? SWIG_CastRank(r) + 1 : 0; -} -#else /* no cast-rank mode */ -# define SWIG_AddCast -# define SWIG_CheckState(r) (SWIG_IsOK(r) ? 1 : 0) -#endif - - - - -#include <string.h> - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void *(*swig_converter_func)(void *, int *); -typedef struct swig_type_info *(*swig_dycast_func)(void **); - -/* Structure to store information on one type */ -typedef struct swig_type_info { - const char *name; /* mangled name of this type */ - const char *str; /* human readable name of this type */ - swig_dycast_func dcast; /* dynamic cast function down a hierarchy */ - struct swig_cast_info *cast; /* linked list of types that can cast into this type */ - void *clientdata; /* language specific type data */ - int owndata; /* flag if the structure owns the clientdata */ -} swig_type_info; - -/* Structure to store a type and conversion function used for casting */ -typedef struct swig_cast_info { - swig_type_info *type; /* pointer to type that is equivalent to this type */ - swig_converter_func converter; /* function to cast the void pointers */ - struct swig_cast_info *next; /* pointer to next cast in linked list */ - struct swig_cast_info *prev; /* pointer to the previous cast */ -} swig_cast_info; - -/* Structure used to store module information - * Each module generates one structure like this, and the runtime collects - * all of these structures and stores them in a circularly linked list.*/ -typedef struct swig_module_info { - swig_type_info **types; /* Array of pointers to swig_type_info structures that are in this module */ - size_t size; /* Number of types in this module */ - struct swig_module_info *next; /* Pointer to next element in circularly linked list */ - swig_type_info **type_initial; /* Array of initially generated type structures */ - swig_cast_info **cast_initial; /* Array of initially generated casting structures */ - void *clientdata; /* Language specific module data */ -} swig_module_info; - -/* - Compare two type names skipping the space characters, therefore - "char*" == "char *" and "Class<int>" == "Class<int >", etc. - - Return 0 when the two name types are equivalent, as in - strncmp, but skipping ' '. -*/ -SWIGRUNTIME int -SWIG_TypeNameComp(const char *f1, const char *l1, - const char *f2, const char *l2) { - for (;(f1 != l1) && (f2 != l2); ++f1, ++f2) { - while ((*f1 == ' ') && (f1 != l1)) ++f1; - while ((*f2 == ' ') && (f2 != l2)) ++f2; - if (*f1 != *f2) return (*f1 > *f2) ? 1 : -1; - } - return (int)((l1 - f1) - (l2 - f2)); -} - -/* - Check type equivalence in a name list like <name1>|<name2>|... - Return 0 if not equal, 1 if equal -*/ -SWIGRUNTIME int -SWIG_TypeEquiv(const char *nb, const char *tb) { - int equiv = 0; - const char* te = tb + strlen(tb); - const char* ne = nb; - while (!equiv && *ne) { - for (nb = ne; *ne; ++ne) { - if (*ne == '|') break; - } - equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0; - if (*ne) ++ne; - } - return equiv; -} - -/* - Check type equivalence in a name list like <name1>|<name2>|... - Return 0 if equal, -1 if nb < tb, 1 if nb > tb -*/ -SWIGRUNTIME int -SWIG_TypeCompare(const char *nb, const char *tb) { - int equiv = 0; - const char* te = tb + strlen(tb); - const char* ne = nb; - while (!equiv && *ne) { - for (nb = ne; *ne; ++ne) { - if (*ne == '|') break; - } - equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0; - if (*ne) ++ne; - } - return equiv; -} - - -/* think of this as a c++ template<> or a scheme macro */ -#define SWIG_TypeCheck_Template(comparison, ty) \ - if (ty) { \ - swig_cast_info *iter = ty->cast; \ - while (iter) { \ - if (comparison) { \ - if (iter == ty->cast) return iter; \ - /* Move iter to the top of the linked list */ \ - iter->prev->next = iter->next; \ - if (iter->next) \ - iter->next->prev = iter->prev; \ - iter->next = ty->cast; \ - iter->prev = 0; \ - if (ty->cast) ty->cast->prev = iter; \ - ty->cast = iter; \ - return iter; \ - } \ - iter = iter->next; \ - } \ - } \ - return 0 - -/* - Check the typename -*/ -SWIGRUNTIME swig_cast_info * -SWIG_TypeCheck(const char *c, swig_type_info *ty) { - SWIG_TypeCheck_Template(strcmp(iter->type->name, c) == 0, ty); -} - -/* Same as previous function, except strcmp is replaced with a pointer comparison */ -SWIGRUNTIME swig_cast_info * -SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *into) { - SWIG_TypeCheck_Template(iter->type == from, into); -} - -/* - Cast a pointer up an inheritance hierarchy -*/ -SWIGRUNTIMEINLINE void * -SWIG_TypeCast(swig_cast_info *ty, void *ptr, int *newmemory) { - return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr, newmemory); -} - -/* - Dynamic pointer casting. Down an inheritance hierarchy -*/ -SWIGRUNTIME swig_type_info * -SWIG_TypeDynamicCast(swig_type_info *ty, void **ptr) { - swig_type_info *lastty = ty; - if (!ty || !ty->dcast) return ty; - while (ty && (ty->dcast)) { - ty = (*ty->dcast)(ptr); - if (ty) lastty = ty; - } - return lastty; -} - -/* - Return the name associated with this type -*/ -SWIGRUNTIMEINLINE const char * -SWIG_TypeName(const swig_type_info *ty) { - return ty->name; -} - -/* - Return the pretty name associated with this type, - that is an unmangled type name in a form presentable to the user. -*/ -SWIGRUNTIME const char * -SWIG_TypePrettyName(const swig_type_info *type) { - /* The "str" field contains the equivalent pretty names of the - type, separated by vertical-bar characters. We choose - to print the last name, as it is often (?) the most - specific. */ - if (!type) return NULL; - if (type->str != NULL) { - const char *last_name = type->str; - const char *s; - for (s = type->str; *s; s++) - if (*s == '|') last_name = s+1; - return last_name; - } - else - return type->name; -} - -/* - Set the clientdata field for a type -*/ -SWIGRUNTIME void -SWIG_TypeClientData(swig_type_info *ti, void *clientdata) { - swig_cast_info *cast = ti->cast; - /* if (ti->clientdata == clientdata) return; */ - ti->clientdata = clientdata; - - while (cast) { - if (!cast->converter) { - swig_type_info *tc = cast->type; - if (!tc->clientdata) { - SWIG_TypeClientData(tc, clientdata); - } - } - cast = cast->next; - } -} -SWIGRUNTIME void -SWIG_TypeNewClientData(swig_type_info *ti, void *clientdata) { - SWIG_TypeClientData(ti, clientdata); - ti->owndata = 1; -} - -/* - Search for a swig_type_info structure only by mangled name - Search is a O(log #types) - - We start searching at module start, and finish searching when start == end. - Note: if start == end at the beginning of the function, we go all the way around - the circular list. -*/ -SWIGRUNTIME swig_type_info * -SWIG_MangledTypeQueryModule(swig_module_info *start, - swig_module_info *end, - const char *name) { - swig_module_info *iter = start; - do { - if (iter->size) { - register size_t l = 0; - register size_t r = iter->size - 1; - do { - /* since l+r >= 0, we can (>> 1) instead (/ 2) */ - register size_t i = (l + r) >> 1; - const char *iname = iter->types[i]->name; - if (iname) { - register int compare = strcmp(name, iname); - if (compare == 0) { - return iter->types[i]; - } else if (compare < 0) { - if (i) { - r = i - 1; - } else { - break; - } - } else if (compare > 0) { - l = i + 1; - } - } else { - break; /* should never happen */ - } - } while (l <= r); - } - iter = iter->next; - } while (iter != end); - return 0; -} - -/* - Search for a swig_type_info structure for either a mangled name or a human readable name. - It first searches the mangled names of the types, which is a O(log #types) - If a type is not found it then searches the human readable names, which is O(#types). - - We start searching at module start, and finish searching when start == end. - Note: if start == end at the beginning of the function, we go all the way around - the circular list. -*/ -SWIGRUNTIME swig_type_info * -SWIG_TypeQueryModule(swig_module_info *start, - swig_module_info *end, - const char *name) { - /* STEP 1: Search the name field using binary search */ - swig_type_info *ret = SWIG_MangledTypeQueryModule(start, end, name); - if (ret) { - return ret; - } else { - /* STEP 2: If the type hasn't been found, do a complete search - of the str field (the human readable name) */ - swig_module_info *iter = start; - do { - register size_t i = 0; - for (; i < iter->size; ++i) { - if (iter->types[i]->str && (SWIG_TypeEquiv(iter->types[i]->str, name))) - return iter->types[i]; - } - iter = iter->next; - } while (iter != end); - } - - /* neither found a match */ - return 0; -} - -/* - Pack binary data into a string -*/ -SWIGRUNTIME char * -SWIG_PackData(char *c, void *ptr, size_t sz) { - static const char hex[17] = "0123456789abcdef"; - register const unsigned char *u = (unsigned char *) ptr; - register const unsigned char *eu = u + sz; - for (; u != eu; ++u) { - register unsigned char uu = *u; - *(c++) = hex[(uu & 0xf0) >> 4]; - *(c++) = hex[uu & 0xf]; - } - return c; -} - -/* - Unpack binary data from a string -*/ -SWIGRUNTIME const char * -SWIG_UnpackData(const char *c, void *ptr, size_t sz) { - register unsigned char *u = (unsigned char *) ptr; - register const unsigned char *eu = u + sz; - for (; u != eu; ++u) { - register char d = *(c++); - register unsigned char uu; - if ((d >= '0') && (d <= '9')) - uu = ((d - '0') << 4); - else if ((d >= 'a') && (d <= 'f')) - uu = ((d - ('a'-10)) << 4); - else - return (char *) 0; - d = *(c++); - if ((d >= '0') && (d <= '9')) - uu |= (d - '0'); - else if ((d >= 'a') && (d <= 'f')) - uu |= (d - ('a'-10)); - else - return (char *) 0; - *u = uu; - } - return c; -} - -/* - Pack 'void *' into a string buffer. -*/ -SWIGRUNTIME char * -SWIG_PackVoidPtr(char *buff, void *ptr, const char *name, size_t bsz) { - char *r = buff; - if ((2*sizeof(void *) + 2) > bsz) return 0; - *(r++) = '_'; - r = SWIG_PackData(r,&ptr,sizeof(void *)); - if (strlen(name) + 1 > (bsz - (r - buff))) return 0; - strcpy(r,name); - return buff; -} - -SWIGRUNTIME const char * -SWIG_UnpackVoidPtr(const char *c, void **ptr, const char *name) { - if (*c != '_') { - if (strcmp(c,"NULL") == 0) { - *ptr = (void *) 0; - return name; - } else { - return 0; - } - } - return SWIG_UnpackData(++c,ptr,sizeof(void *)); -} - -SWIGRUNTIME char * -SWIG_PackDataName(char *buff, void *ptr, size_t sz, const char *name, size_t bsz) { - char *r = buff; - size_t lname = (name ? strlen(name) : 0); - if ((2*sz + 2 + lname) > bsz) return 0; - *(r++) = '_'; - r = SWIG_PackData(r,ptr,sz); - if (lname) { - strncpy(r,name,lname+1); - } else { - *r = 0; - } - return buff; -} - -SWIGRUNTIME const char * -SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) { - if (*c != '_') { - if (strcmp(c,"NULL") == 0) { - memset(ptr,0,sz); - return name; - } else { - return 0; - } - } - return SWIG_UnpackData(++c,ptr,sz); -} - -#ifdef __cplusplus -} -#endif - -/* Errors in SWIG */ -#define SWIG_UnknownError -1 -#define SWIG_IOError -2 -#define SWIG_RuntimeError -3 -#define SWIG_IndexError -4 -#define SWIG_TypeError -5 -#define SWIG_DivisionByZero -6 -#define SWIG_OverflowError -7 -#define SWIG_SyntaxError -8 -#define SWIG_ValueError -9 -#define SWIG_SystemError -10 -#define SWIG_AttributeError -11 -#define SWIG_MemoryError -12 -#define SWIG_NullReferenceError -13 - - - - -/* Add PyOS_snprintf for old Pythons */ -#if PY_VERSION_HEX < 0x02020000 -# if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM) -# define PyOS_snprintf _snprintf -# else -# define PyOS_snprintf snprintf -# endif -#endif - -/* A crude PyString_FromFormat implementation for old Pythons */ -#if PY_VERSION_HEX < 0x02020000 - -#ifndef SWIG_PYBUFFER_SIZE -# define SWIG_PYBUFFER_SIZE 1024 -#endif - -static PyObject * -PyString_FromFormat(const char *fmt, ...) { - va_list ap; - char buf[SWIG_PYBUFFER_SIZE * 2]; - int res; - va_start(ap, fmt); - res = vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - return (res < 0 || res >= (int)sizeof(buf)) ? 0 : PyString_FromString(buf); -} -#endif - -/* Add PyObject_Del for old Pythons */ -#if PY_VERSION_HEX < 0x01060000 -# define PyObject_Del(op) PyMem_DEL((op)) -#endif -#ifndef PyObject_DEL -# define PyObject_DEL PyObject_Del -#endif - -/* A crude PyExc_StopIteration exception for old Pythons */ -#if PY_VERSION_HEX < 0x02020000 -# ifndef PyExc_StopIteration -# define PyExc_StopIteration PyExc_RuntimeError -# endif -# ifndef PyObject_GenericGetAttr -# define PyObject_GenericGetAttr 0 -# endif -#endif -/* Py_NotImplemented is defined in 2.1 and up. */ -#if PY_VERSION_HEX < 0x02010000 -# ifndef Py_NotImplemented -# define Py_NotImplemented PyExc_RuntimeError -# endif -#endif - - -/* A crude PyString_AsStringAndSize implementation for old Pythons */ -#if PY_VERSION_HEX < 0x02010000 -# ifndef PyString_AsStringAndSize -# define PyString_AsStringAndSize(obj, s, len) {*s = PyString_AsString(obj); *len = *s ? strlen(*s) : 0;} -# endif -#endif - -/* PySequence_Size for old Pythons */ -#if PY_VERSION_HEX < 0x02000000 -# ifndef PySequence_Size -# define PySequence_Size PySequence_Length -# endif -#endif - - -/* PyBool_FromLong for old Pythons */ -#if PY_VERSION_HEX < 0x02030000 -static -PyObject *PyBool_FromLong(long ok) -{ - PyObject *result = ok ? Py_True : Py_False; - Py_INCREF(result); - return result; -} -#endif - -/* Py_ssize_t for old Pythons */ -/* This code is as recommended by: */ -/* http://www.python.org/dev/peps/pep-0353/#conversion-guidelines */ -#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN) -typedef int Py_ssize_t; -# define PY_SSIZE_T_MAX INT_MAX -# define PY_SSIZE_T_MIN INT_MIN -#endif - -/* ----------------------------------------------------------------------------- - * error manipulation - * ----------------------------------------------------------------------------- */ - -SWIGRUNTIME PyObject* -SWIG_Python_ErrorType(int code) { - PyObject* type = 0; - switch(code) { - case SWIG_MemoryError: - type = PyExc_MemoryError; - break; - case SWIG_IOError: - type = PyExc_IOError; - break; - case SWIG_RuntimeError: - type = PyExc_RuntimeError; - break; - case SWIG_IndexError: - type = PyExc_IndexError; - break; - case SWIG_TypeError: - type = PyExc_TypeError; - break; - case SWIG_DivisionByZero: - type = PyExc_ZeroDivisionError; - break; - case SWIG_OverflowError: - type = PyExc_OverflowError; - break; - case SWIG_SyntaxError: - type = PyExc_SyntaxError; - break; - case SWIG_ValueError: - type = PyExc_ValueError; - break; - case SWIG_SystemError: - type = PyExc_SystemError; - break; - case SWIG_AttributeError: - type = PyExc_AttributeError; - break; - default: - type = PyExc_RuntimeError; - } - return type; -} - - -SWIGRUNTIME void -SWIG_Python_AddErrorMsg(const char* mesg) -{ - PyObject *type = 0; - PyObject *value = 0; - PyObject *traceback = 0; - - if (PyErr_Occurred()) PyErr_Fetch(&type, &value, &traceback); - if (value) { - PyObject *old_str = PyObject_Str(value); - PyErr_Clear(); - Py_XINCREF(type); - PyErr_Format(type, "%s %s", PyString_AsString(old_str), mesg); - Py_DECREF(old_str); - Py_DECREF(value); - } else { - PyErr_SetString(PyExc_RuntimeError, mesg); - } -} - - - -#if defined(SWIG_PYTHON_NO_THREADS) -# if defined(SWIG_PYTHON_THREADS) -# undef SWIG_PYTHON_THREADS -# endif -#endif -#if defined(SWIG_PYTHON_THREADS) /* Threading support is enabled */ -# if !defined(SWIG_PYTHON_USE_GIL) && !defined(SWIG_PYTHON_NO_USE_GIL) -# if (PY_VERSION_HEX >= 0x02030000) /* For 2.3 or later, use the PyGILState calls */ -# define SWIG_PYTHON_USE_GIL -# endif -# endif -# if defined(SWIG_PYTHON_USE_GIL) /* Use PyGILState threads calls */ -# ifndef SWIG_PYTHON_INITIALIZE_THREADS -# define SWIG_PYTHON_INITIALIZE_THREADS PyEval_InitThreads() -# endif -# ifdef __cplusplus /* C++ code */ - class SWIG_Python_Thread_Block { - bool status; - PyGILState_STATE state; - public: - void end() { if (status) { PyGILState_Release(state); status = false;} } - SWIG_Python_Thread_Block() : status(true), state(PyGILState_Ensure()) {} - ~SWIG_Python_Thread_Block() { end(); } - }; - class SWIG_Python_Thread_Allow { - bool status; - PyThreadState *save; - public: - void end() { if (status) { PyEval_RestoreThread(save); status = false; }} - SWIG_Python_Thread_Allow() : status(true), save(PyEval_SaveThread()) {} - ~SWIG_Python_Thread_Allow() { end(); } - }; -# define SWIG_PYTHON_THREAD_BEGIN_BLOCK SWIG_Python_Thread_Block _swig_thread_block -# define SWIG_PYTHON_THREAD_END_BLOCK _swig_thread_block.end() -# define SWIG_PYTHON_THREAD_BEGIN_ALLOW SWIG_Python_Thread_Allow _swig_thread_allow -# define SWIG_PYTHON_THREAD_END_ALLOW _swig_thread_allow.end() -# else /* C code */ -# define SWIG_PYTHON_THREAD_BEGIN_BLOCK PyGILState_STATE _swig_thread_block = PyGILState_Ensure() -# define SWIG_PYTHON_THREAD_END_BLOCK PyGILState_Release(_swig_thread_block) -# define SWIG_PYTHON_THREAD_BEGIN_ALLOW PyThreadState *_swig_thread_allow = PyEval_SaveThread() -# define SWIG_PYTHON_THREAD_END_ALLOW PyEval_RestoreThread(_swig_thread_allow) -# endif -# else /* Old thread way, not implemented, user must provide it */ -# if !defined(SWIG_PYTHON_INITIALIZE_THREADS) -# define SWIG_PYTHON_INITIALIZE_THREADS -# endif -# if !defined(SWIG_PYTHON_THREAD_BEGIN_BLOCK) -# define SWIG_PYTHON_THREAD_BEGIN_BLOCK -# endif -# if !defined(SWIG_PYTHON_THREAD_END_BLOCK) -# define SWIG_PYTHON_THREAD_END_BLOCK -# endif -# if !defined(SWIG_PYTHON_THREAD_BEGIN_ALLOW) -# define SWIG_PYTHON_THREAD_BEGIN_ALLOW -# endif -# if !defined(SWIG_PYTHON_THREAD_END_ALLOW) -# define SWIG_PYTHON_THREAD_END_ALLOW -# endif -# endif -#else /* No thread support */ -# define SWIG_PYTHON_INITIALIZE_THREADS -# define SWIG_PYTHON_THREAD_BEGIN_BLOCK -# define SWIG_PYTHON_THREAD_END_BLOCK -# define SWIG_PYTHON_THREAD_BEGIN_ALLOW -# define SWIG_PYTHON_THREAD_END_ALLOW -#endif - -/* ----------------------------------------------------------------------------- - * Python API portion that goes into the runtime - * ----------------------------------------------------------------------------- */ - -#ifdef __cplusplus -extern "C" { -#if 0 -} /* cc-mode */ -#endif -#endif - -/* ----------------------------------------------------------------------------- - * Constant declarations - * ----------------------------------------------------------------------------- */ - -/* Constant Types */ -#define SWIG_PY_POINTER 4 -#define SWIG_PY_BINARY 5 - -/* Constant information structure */ -typedef struct swig_const_info { - int type; - char *name; - long lvalue; - double dvalue; - void *pvalue; - swig_type_info **ptype; -} swig_const_info; - -#ifdef __cplusplus -#if 0 -{ /* cc-mode */ -#endif -} -#endif - - -/* ----------------------------------------------------------------------------- - * See the LICENSE file for information on copyright, usage and redistribution - * of SWIG, and the README file for authors - http://www.swig.org/release.html. - * - * pyrun.swg - * - * This file contains the runtime support for Python modules - * and includes code for managing global variables and pointer - * type checking. - * - * ----------------------------------------------------------------------------- */ - -/* Common SWIG API */ - -/* for raw pointers */ -#define SWIG_Python_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, 0) -#define SWIG_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtr(obj, pptr, type, flags) -#define SWIG_ConvertPtrAndOwn(obj,pptr,type,flags,own) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, own) -#define SWIG_NewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(ptr, type, flags) -#define SWIG_CheckImplicit(ty) SWIG_Python_CheckImplicit(ty) -#define SWIG_AcquirePtr(ptr, src) SWIG_Python_AcquirePtr(ptr, src) -#define swig_owntype int - -/* for raw packed data */ -#define SWIG_ConvertPacked(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty) -#define SWIG_NewPackedObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type) - -/* for class or struct pointers */ -#define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_ConvertPtr(obj, pptr, type, flags) -#define SWIG_NewInstanceObj(ptr, type, flags) SWIG_NewPointerObj(ptr, type, flags) - -/* for C or C++ function pointers */ -#define SWIG_ConvertFunctionPtr(obj, pptr, type) SWIG_Python_ConvertFunctionPtr(obj, pptr, type) -#define SWIG_NewFunctionPtrObj(ptr, type) SWIG_Python_NewPointerObj(ptr, type, 0) - -/* for C++ member pointers, ie, member methods */ -#define SWIG_ConvertMember(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty) -#define SWIG_NewMemberObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type) - - -/* Runtime API */ - -#define SWIG_GetModule(clientdata) SWIG_Python_GetModule() -#define SWIG_SetModule(clientdata, pointer) SWIG_Python_SetModule(pointer) -#define SWIG_NewClientData(obj) PySwigClientData_New(obj) - -#define SWIG_SetErrorObj SWIG_Python_SetErrorObj -#define SWIG_SetErrorMsg SWIG_Python_SetErrorMsg -#define SWIG_ErrorType(code) SWIG_Python_ErrorType(code) -#define SWIG_Error(code, msg) SWIG_Python_SetErrorMsg(SWIG_ErrorType(code), msg) -#define SWIG_fail goto fail - - -/* Runtime API implementation */ - -/* Error manipulation */ - -SWIGINTERN void -SWIG_Python_SetErrorObj(PyObject *errtype, PyObject *obj) { - SWIG_PYTHON_THREAD_BEGIN_BLOCK; - PyErr_SetObject(errtype, obj); - Py_DECREF(obj); - SWIG_PYTHON_THREAD_END_BLOCK; -} - -SWIGINTERN void -SWIG_Python_SetErrorMsg(PyObject *errtype, const char *msg) { - SWIG_PYTHON_THREAD_BEGIN_BLOCK; - PyErr_SetString(errtype, (char *) msg); - SWIG_PYTHON_THREAD_END_BLOCK; -} - -#define SWIG_Python_Raise(obj, type, desc) SWIG_Python_SetErrorObj(SWIG_Python_ExceptionType(desc), obj) - -/* Set a constant value */ - -SWIGINTERN void -SWIG_Python_SetConstant(PyObject *d, const char *name, PyObject *obj) { - PyDict_SetItemString(d, (char*) name, obj); - Py_DECREF(obj); -} - -/* Append a value to the result obj */ - -SWIGINTERN PyObject* -SWIG_Python_AppendOutput(PyObject* result, PyObject* obj) { -#if !defined(SWIG_PYTHON_OUTPUT_TUPLE) - if (!result) { - result = obj; - } else if (result == Py_None) { - Py_DECREF(result); - result = obj; - } else { - if (!PyList_Check(result)) { - PyObject *o2 = result; - result = PyList_New(1); - PyList_SetItem(result, 0, o2); - } - PyList_Append(result,obj); - Py_DECREF(obj); - } - return result; -#else - PyObject* o2; - PyObject* o3; - if (!result) { - result = obj; - } else if (result == Py_None) { - Py_DECREF(result); - result = obj; - } else { - if (!PyTuple_Check(result)) { - o2 = result; - result = PyTuple_New(1); - PyTuple_SET_ITEM(result, 0, o2); - } - o3 = PyTuple_New(1); - PyTuple_SET_ITEM(o3, 0, obj); - o2 = result; - result = PySequence_Concat(o2, o3); - Py_DECREF(o2); - Py_DECREF(o3); - } - return result; -#endif -} - -/* Unpack the argument tuple */ - -SWIGINTERN int -SWIG_Python_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, PyObject **objs) -{ - if (!args) { - if (!min && !max) { - return 1; - } else { - PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got none", - name, (min == max ? "" : "at least "), (int)min); - return 0; - } - } - if (!PyTuple_Check(args)) { - PyErr_SetString(PyExc_SystemError, "UnpackTuple() argument list is not a tuple"); - return 0; - } else { - register Py_ssize_t l = PyTuple_GET_SIZE(args); - if (l < min) { - PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", - name, (min == max ? "" : "at least "), (int)min, (int)l); - return 0; - } else if (l > max) { - PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", - name, (min == max ? "" : "at most "), (int)max, (int)l); - return 0; - } else { - register int i; - for (i = 0; i < l; ++i) { - objs[i] = PyTuple_GET_ITEM(args, i); - } - for (; l < max; ++l) { - objs[l] = 0; - } - return i + 1; - } - } -} - -/* A functor is a function object with one single object argument */ -#if PY_VERSION_HEX >= 0x02020000 -#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunctionObjArgs(functor, obj, NULL); -#else -#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunction(functor, "O", obj); -#endif - -/* - Helper for static pointer initialization for both C and C++ code, for example - static PyObject *SWIG_STATIC_POINTER(MyVar) = NewSomething(...); -*/ -#ifdef __cplusplus -#define SWIG_STATIC_POINTER(var) var -#else -#define SWIG_STATIC_POINTER(var) var = 0; if (!var) var -#endif - -/* ----------------------------------------------------------------------------- - * Pointer declarations - * ----------------------------------------------------------------------------- */ - -/* Flags for new pointer objects */ -#define SWIG_POINTER_NOSHADOW (SWIG_POINTER_OWN << 1) -#define SWIG_POINTER_NEW (SWIG_POINTER_NOSHADOW | SWIG_POINTER_OWN) - -#define SWIG_POINTER_IMPLICIT_CONV (SWIG_POINTER_DISOWN << 1) - -#ifdef __cplusplus -extern "C" { -#if 0 -} /* cc-mode */ -#endif -#endif - -/* How to access Py_None */ -#if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) -# ifndef SWIG_PYTHON_NO_BUILD_NONE -# ifndef SWIG_PYTHON_BUILD_NONE -# define SWIG_PYTHON_BUILD_NONE -# endif -# endif -#endif - -#ifdef SWIG_PYTHON_BUILD_NONE -# ifdef Py_None -# undef Py_None -# define Py_None SWIG_Py_None() -# endif -SWIGRUNTIMEINLINE PyObject * -_SWIG_Py_None(void) -{ - PyObject *none = Py_BuildValue((char*)""); - Py_DECREF(none); - return none; -} -SWIGRUNTIME PyObject * -SWIG_Py_None(void) -{ - static PyObject *SWIG_STATIC_POINTER(none) = _SWIG_Py_None(); - return none; -} -#endif - -/* The python void return value */ - -SWIGRUNTIMEINLINE PyObject * -SWIG_Py_Void(void) -{ - PyObject *none = Py_None; - Py_INCREF(none); - return none; -} - -/* PySwigClientData */ - -typedef struct { - PyObject *klass; - PyObject *newraw; - PyObject *newargs; - PyObject *destroy; - int delargs; - int implicitconv; -} PySwigClientData; - -SWIGRUNTIMEINLINE int -SWIG_Python_CheckImplicit(swig_type_info *ty) -{ - PySwigClientData *data = (PySwigClientData *)ty->clientdata; - return data ? data->implicitconv : 0; -} - -SWIGRUNTIMEINLINE PyObject * -SWIG_Python_ExceptionType(swig_type_info *desc) { - PySwigClientData *data = desc ? (PySwigClientData *) desc->clientdata : 0; - PyObject *klass = data ? data->klass : 0; - return (klass ? klass : PyExc_RuntimeError); -} - - -SWIGRUNTIME PySwigClientData * -PySwigClientData_New(PyObject* obj) -{ - if (!obj) { - return 0; - } else { - PySwigClientData *data = (PySwigClientData *)malloc(sizeof(PySwigClientData)); - /* the klass element */ - data->klass = obj; - Py_INCREF(data->klass); - /* the newraw method and newargs arguments used to create a new raw instance */ - if (PyClass_Check(obj)) { - data->newraw = 0; - data->newargs = obj; - Py_INCREF(obj); - } else { -#if (PY_VERSION_HEX < 0x02020000) - data->newraw = 0; -#else - data->newraw = PyObject_GetAttrString(data->klass, (char *)"__new__"); -#endif - if (data->newraw) { - Py_INCREF(data->newraw); - data->newargs = PyTuple_New(1); - PyTuple_SetItem(data->newargs, 0, obj); - } else { - data->newargs = obj; - } - Py_INCREF(data->newargs); - } - /* the destroy method, aka as the C++ delete method */ - data->destroy = PyObject_GetAttrString(data->klass, (char *)"__swig_destroy__"); - if (PyErr_Occurred()) { - PyErr_Clear(); - data->destroy = 0; - } - if (data->destroy) { - int flags; - Py_INCREF(data->destroy); - flags = PyCFunction_GET_FLAGS(data->destroy); -#ifdef METH_O - data->delargs = !(flags & (METH_O)); -#else - data->delargs = 0; -#endif - } else { - data->delargs = 0; - } - data->implicitconv = 0; - return data; - } -} - -SWIGRUNTIME void -PySwigClientData_Del(PySwigClientData* data) -{ - Py_XDECREF(data->newraw); - Py_XDECREF(data->newargs); - Py_XDECREF(data->destroy); -} - -/* =============== PySwigObject =====================*/ - -typedef struct { - PyObject_HEAD - void *ptr; - swig_type_info *ty; - int own; - PyObject *next; -} PySwigObject; - -SWIGRUNTIME PyObject * -PySwigObject_long(PySwigObject *v) -{ - return PyLong_FromVoidPtr(v->ptr); -} - -SWIGRUNTIME PyObject * -PySwigObject_format(const char* fmt, PySwigObject *v) -{ - PyObject *res = NULL; - PyObject *args = PyTuple_New(1); - if (args) { - if (PyTuple_SetItem(args, 0, PySwigObject_long(v)) == 0) { - PyObject *ofmt = PyString_FromString(fmt); - if (ofmt) { - res = PyString_Format(ofmt,args); - Py_DECREF(ofmt); - } - Py_DECREF(args); - } - } - return res; -} - -SWIGRUNTIME PyObject * -PySwigObject_oct(PySwigObject *v) -{ - return PySwigObject_format("%o",v); -} - -SWIGRUNTIME PyObject * -PySwigObject_hex(PySwigObject *v) -{ - return PySwigObject_format("%x",v); -} - -SWIGRUNTIME PyObject * -#ifdef METH_NOARGS -PySwigObject_repr(PySwigObject *v) -#else -PySwigObject_repr(PySwigObject *v, PyObject *args) -#endif -{ - const char *name = SWIG_TypePrettyName(v->ty); - PyObject *hex = PySwigObject_hex(v); - PyObject *repr = PyString_FromFormat("<Swig Object of type '%s' at 0x%s>", name, PyString_AsString(hex)); - Py_DECREF(hex); - if (v->next) { -#ifdef METH_NOARGS - PyObject *nrep = PySwigObject_repr((PySwigObject *)v->next); -#else - PyObject *nrep = PySwigObject_repr((PySwigObject *)v->next, args); -#endif - PyString_ConcatAndDel(&repr,nrep); - } - return repr; -} - -SWIGRUNTIME int -PySwigObject_print(PySwigObject *v, FILE *fp, int SWIGUNUSEDPARM(flags)) -{ -#ifdef METH_NOARGS - PyObject *repr = PySwigObject_repr(v); -#else - PyObject *repr = PySwigObject_repr(v, NULL); -#endif - if (repr) { - fputs(PyString_AsString(repr), fp); - Py_DECREF(repr); - return 0; - } else { - return 1; - } -} - -SWIGRUNTIME PyObject * -PySwigObject_str(PySwigObject *v) -{ - char result[SWIG_BUFFER_SIZE]; - return SWIG_PackVoidPtr(result, v->ptr, v->ty->name, sizeof(result)) ? - PyString_FromString(result) : 0; -} - -SWIGRUNTIME int -PySwigObject_compare(PySwigObject *v, PySwigObject *w) -{ - void *i = v->ptr; - void *j = w->ptr; - return (i < j) ? -1 : ((i > j) ? 1 : 0); -} - -SWIGRUNTIME PyTypeObject* _PySwigObject_type(void); - -SWIGRUNTIME PyTypeObject* -PySwigObject_type(void) { - static PyTypeObject *SWIG_STATIC_POINTER(type) = _PySwigObject_type(); - return type; -} - -SWIGRUNTIMEINLINE int -PySwigObject_Check(PyObject *op) { - return ((op)->ob_type == PySwigObject_type()) - || (strcmp((op)->ob_type->tp_name,"PySwigObject") == 0); -} - -SWIGRUNTIME PyObject * -PySwigObject_New(void *ptr, swig_type_info *ty, int own); - -SWIGRUNTIME void -PySwigObject_dealloc(PyObject *v) -{ - PySwigObject *sobj = (PySwigObject *) v; - PyObject *next = sobj->next; - if (sobj->own == SWIG_POINTER_OWN) { - swig_type_info *ty = sobj->ty; - PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0; - PyObject *destroy = data ? data->destroy : 0; - if (destroy) { - /* destroy is always a VARARGS method */ - PyObject *res; - if (data->delargs) { - /* we need to create a temporal object to carry the destroy operation */ - PyObject *tmp = PySwigObject_New(sobj->ptr, ty, 0); - res = SWIG_Python_CallFunctor(destroy, tmp); - Py_DECREF(tmp); - } else { - PyCFunction meth = PyCFunction_GET_FUNCTION(destroy); - PyObject *mself = PyCFunction_GET_SELF(destroy); - res = ((*meth)(mself, v)); - } - Py_XDECREF(res); - } -#if !defined(SWIG_PYTHON_SILENT_MEMLEAK) - else { - const char *name = SWIG_TypePrettyName(ty); - printf("swig/python detected a memory leak of type '%s', no destructor found.\n", (name ? name : "unknown")); - } -#endif - } - Py_XDECREF(next); - PyObject_DEL(v); -} - -SWIGRUNTIME PyObject* -PySwigObject_append(PyObject* v, PyObject* next) -{ - PySwigObject *sobj = (PySwigObject *) v; -#ifndef METH_O - PyObject *tmp = 0; - if (!PyArg_ParseTuple(next,(char *)"O:append", &tmp)) return NULL; - next = tmp; -#endif - if (!PySwigObject_Check(next)) { - return NULL; - } - sobj->next = next; - Py_INCREF(next); - return SWIG_Py_Void(); -} - -SWIGRUNTIME PyObject* -#ifdef METH_NOARGS -PySwigObject_next(PyObject* v) -#else -PySwigObject_next(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) -#endif -{ - PySwigObject *sobj = (PySwigObject *) v; - if (sobj->next) { - Py_INCREF(sobj->next); - return sobj->next; - } else { - return SWIG_Py_Void(); - } -} - -SWIGINTERN PyObject* -#ifdef METH_NOARGS -PySwigObject_disown(PyObject *v) -#else -PySwigObject_disown(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) -#endif -{ - PySwigObject *sobj = (PySwigObject *)v; - sobj->own = 0; - return SWIG_Py_Void(); -} - -SWIGINTERN PyObject* -#ifdef METH_NOARGS -PySwigObject_acquire(PyObject *v) -#else -PySwigObject_acquire(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) -#endif -{ - PySwigObject *sobj = (PySwigObject *)v; - sobj->own = SWIG_POINTER_OWN; - return SWIG_Py_Void(); -} - -SWIGINTERN PyObject* -PySwigObject_own(PyObject *v, PyObject *args) -{ - PyObject *val = 0; -#if (PY_VERSION_HEX < 0x02020000) - if (!PyArg_ParseTuple(args,(char *)"|O:own",&val)) -#else - if (!PyArg_UnpackTuple(args, (char *)"own", 0, 1, &val)) -#endif - { - return NULL; - } - else - { - PySwigObject *sobj = (PySwigObject *)v; - PyObject *obj = PyBool_FromLong(sobj->own); - if (val) { -#ifdef METH_NOARGS - if (PyObject_IsTrue(val)) { - PySwigObject_acquire(v); - } else { - PySwigObject_disown(v); - } -#else - if (PyObject_IsTrue(val)) { - PySwigObject_acquire(v,args); - } else { - PySwigObject_disown(v,args); - } -#endif - } - return obj; - } -} - -#ifdef METH_O -static PyMethodDef -swigobject_methods[] = { - {(char *)"disown", (PyCFunction)PySwigObject_disown, METH_NOARGS, (char *)"releases ownership of the pointer"}, - {(char *)"acquire", (PyCFunction)PySwigObject_acquire, METH_NOARGS, (char *)"aquires ownership of the pointer"}, - {(char *)"own", (PyCFunction)PySwigObject_own, METH_VARARGS, (char *)"returns/sets ownership of the pointer"}, - {(char *)"append", (PyCFunction)PySwigObject_append, METH_O, (char *)"appends another 'this' object"}, - {(char *)"next", (PyCFunction)PySwigObject_next, METH_NOARGS, (char *)"returns the next 'this' object"}, - {(char *)"__repr__",(PyCFunction)PySwigObject_repr, METH_NOARGS, (char *)"returns object representation"}, - {0, 0, 0, 0} -}; -#else -static PyMethodDef -swigobject_methods[] = { - {(char *)"disown", (PyCFunction)PySwigObject_disown, METH_VARARGS, (char *)"releases ownership of the pointer"}, - {(char *)"acquire", (PyCFunction)PySwigObject_acquire, METH_VARARGS, (char *)"aquires ownership of the pointer"}, - {(char *)"own", (PyCFunction)PySwigObject_own, METH_VARARGS, (char *)"returns/sets ownership of the pointer"}, - {(char *)"append", (PyCFunction)PySwigObject_append, METH_VARARGS, (char *)"appends another 'this' object"}, - {(char *)"next", (PyCFunction)PySwigObject_next, METH_VARARGS, (char *)"returns the next 'this' object"}, - {(char *)"__repr__",(PyCFunction)PySwigObject_repr, METH_VARARGS, (char *)"returns object representation"}, - {0, 0, 0, 0} -}; -#endif - -#if PY_VERSION_HEX < 0x02020000 -SWIGINTERN PyObject * -PySwigObject_getattr(PySwigObject *sobj,char *name) -{ - return Py_FindMethod(swigobject_methods, (PyObject *)sobj, name); -} -#endif - -SWIGRUNTIME PyTypeObject* -_PySwigObject_type(void) { - static char swigobject_doc[] = "Swig object carries a C/C++ instance pointer"; - - static PyNumberMethods PySwigObject_as_number = { - (binaryfunc)0, /*nb_add*/ - (binaryfunc)0, /*nb_subtract*/ - (binaryfunc)0, /*nb_multiply*/ - (binaryfunc)0, /*nb_divide*/ - (binaryfunc)0, /*nb_remainder*/ - (binaryfunc)0, /*nb_divmod*/ - (ternaryfunc)0,/*nb_power*/ - (unaryfunc)0, /*nb_negative*/ - (unaryfunc)0, /*nb_positive*/ - (unaryfunc)0, /*nb_absolute*/ - (inquiry)0, /*nb_nonzero*/ - 0, /*nb_invert*/ - 0, /*nb_lshift*/ - 0, /*nb_rshift*/ - 0, /*nb_and*/ - 0, /*nb_xor*/ - 0, /*nb_or*/ - (coercion)0, /*nb_coerce*/ - (unaryfunc)PySwigObject_long, /*nb_int*/ - (unaryfunc)PySwigObject_long, /*nb_long*/ - (unaryfunc)0, /*nb_float*/ - (unaryfunc)PySwigObject_oct, /*nb_oct*/ - (unaryfunc)PySwigObject_hex, /*nb_hex*/ -#if PY_VERSION_HEX >= 0x02050000 /* 2.5.0 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index */ -#elif PY_VERSION_HEX >= 0x02020000 /* 2.2.0 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_true_divide */ -#elif PY_VERSION_HEX >= 0x02000000 /* 2.0.0 */ - 0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_or */ -#endif - }; - - static PyTypeObject pyswigobject_type; - static int type_init = 0; - if (!type_init) { - const PyTypeObject tmp - = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - (char *)"PySwigObject", /* tp_name */ - sizeof(PySwigObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)PySwigObject_dealloc, /* tp_dealloc */ - (printfunc)PySwigObject_print, /* tp_print */ -#if PY_VERSION_HEX < 0x02020000 - (getattrfunc)PySwigObject_getattr, /* tp_getattr */ -#else - (getattrfunc)0, /* tp_getattr */ -#endif - (setattrfunc)0, /* tp_setattr */ - (cmpfunc)PySwigObject_compare, /* tp_compare */ - (reprfunc)PySwigObject_repr, /* tp_repr */ - &PySwigObject_as_number, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - (hashfunc)0, /* tp_hash */ - (ternaryfunc)0, /* tp_call */ - (reprfunc)PySwigObject_str, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - swigobject_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ -#if PY_VERSION_HEX >= 0x02020000 - 0, /* tp_iter */ - 0, /* tp_iternext */ - swigobject_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ -#endif -#if PY_VERSION_HEX >= 0x02030000 - 0, /* tp_del */ -#endif -#ifdef COUNT_ALLOCS - 0,0,0,0 /* tp_alloc -> tp_next */ -#endif - }; - pyswigobject_type = tmp; - pyswigobject_type.ob_type = &PyType_Type; - type_init = 1; - } - return &pyswigobject_type; -} - -SWIGRUNTIME PyObject * -PySwigObject_New(void *ptr, swig_type_info *ty, int own) -{ - PySwigObject *sobj = PyObject_NEW(PySwigObject, PySwigObject_type()); - if (sobj) { - sobj->ptr = ptr; - sobj->ty = ty; - sobj->own = own; - sobj->next = 0; - } - return (PyObject *)sobj; -} - -/* ----------------------------------------------------------------------------- - * Implements a simple Swig Packed type, and use it instead of string - * ----------------------------------------------------------------------------- */ - -typedef struct { - PyObject_HEAD - void *pack; - swig_type_info *ty; - size_t size; -} PySwigPacked; - -SWIGRUNTIME int -PySwigPacked_print(PySwigPacked *v, FILE *fp, int SWIGUNUSEDPARM(flags)) -{ - char result[SWIG_BUFFER_SIZE]; - fputs("<Swig Packed ", fp); - if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) { - fputs("at ", fp); - fputs(result, fp); - } - fputs(v->ty->name,fp); - fputs(">", fp); - return 0; -} - -SWIGRUNTIME PyObject * -PySwigPacked_repr(PySwigPacked *v) -{ - char result[SWIG_BUFFER_SIZE]; - if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) { - return PyString_FromFormat("<Swig Packed at %s%s>", result, v->ty->name); - } else { - return PyString_FromFormat("<Swig Packed %s>", v->ty->name); - } -} - -SWIGRUNTIME PyObject * -PySwigPacked_str(PySwigPacked *v) -{ - char result[SWIG_BUFFER_SIZE]; - if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))){ - return PyString_FromFormat("%s%s", result, v->ty->name); - } else { - return PyString_FromString(v->ty->name); - } -} - -SWIGRUNTIME int -PySwigPacked_compare(PySwigPacked *v, PySwigPacked *w) -{ - size_t i = v->size; - size_t j = w->size; - int s = (i < j) ? -1 : ((i > j) ? 1 : 0); - return s ? s : strncmp((char *)v->pack, (char *)w->pack, 2*v->size); -} - -SWIGRUNTIME PyTypeObject* _PySwigPacked_type(void); - -SWIGRUNTIME PyTypeObject* -PySwigPacked_type(void) { - static PyTypeObject *SWIG_STATIC_POINTER(type) = _PySwigPacked_type(); - return type; -} - -SWIGRUNTIMEINLINE int -PySwigPacked_Check(PyObject *op) { - return ((op)->ob_type == _PySwigPacked_type()) - || (strcmp((op)->ob_type->tp_name,"PySwigPacked") == 0); -} - -SWIGRUNTIME void -PySwigPacked_dealloc(PyObject *v) -{ - if (PySwigPacked_Check(v)) { - PySwigPacked *sobj = (PySwigPacked *) v; - free(sobj->pack); - } - PyObject_DEL(v); -} - -SWIGRUNTIME PyTypeObject* -_PySwigPacked_type(void) { - static char swigpacked_doc[] = "Swig object carries a C/C++ instance pointer"; - static PyTypeObject pyswigpacked_type; - static int type_init = 0; - if (!type_init) { - const PyTypeObject tmp - = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - (char *)"PySwigPacked", /* tp_name */ - sizeof(PySwigPacked), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)PySwigPacked_dealloc, /* tp_dealloc */ - (printfunc)PySwigPacked_print, /* tp_print */ - (getattrfunc)0, /* tp_getattr */ - (setattrfunc)0, /* tp_setattr */ - (cmpfunc)PySwigPacked_compare, /* tp_compare */ - (reprfunc)PySwigPacked_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - (hashfunc)0, /* tp_hash */ - (ternaryfunc)0, /* tp_call */ - (reprfunc)PySwigPacked_str, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - swigpacked_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ -#if PY_VERSION_HEX >= 0x02020000 - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ -#endif -#if PY_VERSION_HEX >= 0x02030000 - 0, /* tp_del */ -#endif -#ifdef COUNT_ALLOCS - 0,0,0,0 /* tp_alloc -> tp_next */ -#endif - }; - pyswigpacked_type = tmp; - pyswigpacked_type.ob_type = &PyType_Type; - type_init = 1; - } - return &pyswigpacked_type; -} - -SWIGRUNTIME PyObject * -PySwigPacked_New(void *ptr, size_t size, swig_type_info *ty) -{ - PySwigPacked *sobj = PyObject_NEW(PySwigPacked, PySwigPacked_type()); - if (sobj) { - void *pack = malloc(size); - if (pack) { - memcpy(pack, ptr, size); - sobj->pack = pack; - sobj->ty = ty; - sobj->size = size; - } else { - PyObject_DEL((PyObject *) sobj); - sobj = 0; - } - } - return (PyObject *) sobj; -} - -SWIGRUNTIME swig_type_info * -PySwigPacked_UnpackData(PyObject *obj, void *ptr, size_t size) -{ - if (PySwigPacked_Check(obj)) { - PySwigPacked *sobj = (PySwigPacked *)obj; - if (sobj->size != size) return 0; - memcpy(ptr, sobj->pack, size); - return sobj->ty; - } else { - return 0; - } -} - -/* ----------------------------------------------------------------------------- - * pointers/data manipulation - * ----------------------------------------------------------------------------- */ - -SWIGRUNTIMEINLINE PyObject * -_SWIG_This(void) -{ - return PyString_FromString("this"); -} - -SWIGRUNTIME PyObject * -SWIG_This(void) -{ - static PyObject *SWIG_STATIC_POINTER(swig_this) = _SWIG_This(); - return swig_this; -} - -/* #define SWIG_PYTHON_SLOW_GETSET_THIS */ - -SWIGRUNTIME PySwigObject * -SWIG_Python_GetSwigThis(PyObject *pyobj) -{ - if (PySwigObject_Check(pyobj)) { - return (PySwigObject *) pyobj; - } else { - PyObject *obj = 0; -#if (!defined(SWIG_PYTHON_SLOW_GETSET_THIS) && (PY_VERSION_HEX >= 0x02030000)) - if (PyInstance_Check(pyobj)) { - obj = _PyInstance_Lookup(pyobj, SWIG_This()); - } else { - PyObject **dictptr = _PyObject_GetDictPtr(pyobj); - if (dictptr != NULL) { - PyObject *dict = *dictptr; - obj = dict ? PyDict_GetItem(dict, SWIG_This()) : 0; - } else { -#ifdef PyWeakref_CheckProxy - if (PyWeakref_CheckProxy(pyobj)) { - PyObject *wobj = PyWeakref_GET_OBJECT(pyobj); - return wobj ? SWIG_Python_GetSwigThis(wobj) : 0; - } -#endif - obj = PyObject_GetAttr(pyobj,SWIG_This()); - if (obj) { - Py_DECREF(obj); - } else { - if (PyErr_Occurred()) PyErr_Clear(); - return 0; - } - } - } -#else - obj = PyObject_GetAttr(pyobj,SWIG_This()); - if (obj) { - Py_DECREF(obj); - } else { - if (PyErr_Occurred()) PyErr_Clear(); - return 0; - } -#endif - if (obj && !PySwigObject_Check(obj)) { - /* a PyObject is called 'this', try to get the 'real this' - PySwigObject from it */ - return SWIG_Python_GetSwigThis(obj); - } - return (PySwigObject *)obj; - } -} - -/* Acquire a pointer value */ - -SWIGRUNTIME int -SWIG_Python_AcquirePtr(PyObject *obj, int own) { - if (own == SWIG_POINTER_OWN) { - PySwigObject *sobj = SWIG_Python_GetSwigThis(obj); - if (sobj) { - int oldown = sobj->own; - sobj->own = own; - return oldown; - } - } - return 0; -} - -/* Convert a pointer value */ - -SWIGRUNTIME int -SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int flags, int *own) { - if (!obj) return SWIG_ERROR; - if (obj == Py_None) { - if (ptr) *ptr = 0; - return SWIG_OK; - } else { - PySwigObject *sobj = SWIG_Python_GetSwigThis(obj); - if (own) - *own = 0; - while (sobj) { - void *vptr = sobj->ptr; - if (ty) { - swig_type_info *to = sobj->ty; - if (to == ty) { - /* no type cast needed */ - if (ptr) *ptr = vptr; - break; - } else { - swig_cast_info *tc = SWIG_TypeCheck(to->name,ty); - if (!tc) { - sobj = (PySwigObject *)sobj->next; - } else { - if (ptr) { - int newmemory = 0; - *ptr = SWIG_TypeCast(tc,vptr,&newmemory); - if (newmemory == SWIG_CAST_NEW_MEMORY) { - assert(own); - if (own) - *own = *own | SWIG_CAST_NEW_MEMORY; - } - } - break; - } - } - } else { - if (ptr) *ptr = vptr; - break; - } - } - if (sobj) { - if (own) - *own = *own | sobj->own; - if (flags & SWIG_POINTER_DISOWN) { - sobj->own = 0; - } - return SWIG_OK; - } else { - int res = SWIG_ERROR; - if (flags & SWIG_POINTER_IMPLICIT_CONV) { - PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0; - if (data && !data->implicitconv) { - PyObject *klass = data->klass; - if (klass) { - PyObject *impconv; - data->implicitconv = 1; /* avoid recursion and call 'explicit' constructors*/ - impconv = SWIG_Python_CallFunctor(klass, obj); - data->implicitconv = 0; - if (PyErr_Occurred()) { - PyErr_Clear(); - impconv = 0; - } - if (impconv) { - PySwigObject *iobj = SWIG_Python_GetSwigThis(impconv); - if (iobj) { - void *vptr; - res = SWIG_Python_ConvertPtrAndOwn((PyObject*)iobj, &vptr, ty, 0, 0); - if (SWIG_IsOK(res)) { - if (ptr) { - *ptr = vptr; - /* transfer the ownership to 'ptr' */ - iobj->own = 0; - res = SWIG_AddCast(res); - res = SWIG_AddNewMask(res); - } else { - res = SWIG_AddCast(res); - } - } - } - Py_DECREF(impconv); - } - } - } - } - return res; - } - } -} - -/* Convert a function ptr value */ - -SWIGRUNTIME int -SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) { - if (!PyCFunction_Check(obj)) { - return SWIG_ConvertPtr(obj, ptr, ty, 0); - } else { - void *vptr = 0; - - /* here we get the method pointer for callbacks */ - const char *doc = (((PyCFunctionObject *)obj) -> m_ml -> ml_doc); - const char *desc = doc ? strstr(doc, "swig_ptr: ") : 0; - if (desc) { - desc = ty ? SWIG_UnpackVoidPtr(desc + 10, &vptr, ty->name) : 0; - if (!desc) return SWIG_ERROR; - } - if (ty) { - swig_cast_info *tc = SWIG_TypeCheck(desc,ty); - if (tc) { - int newmemory = 0; - *ptr = SWIG_TypeCast(tc,vptr,&newmemory); - assert(!newmemory); /* newmemory handling not yet implemented */ - } else { - return SWIG_ERROR; - } - } else { - *ptr = vptr; - } - return SWIG_OK; - } -} - -/* Convert a packed value value */ - -SWIGRUNTIME int -SWIG_Python_ConvertPacked(PyObject *obj, void *ptr, size_t sz, swig_type_info *ty) { - swig_type_info *to = PySwigPacked_UnpackData(obj, ptr, sz); - if (!to) return SWIG_ERROR; - if (ty) { - if (to != ty) { - /* check type cast? */ - swig_cast_info *tc = SWIG_TypeCheck(to->name,ty); - if (!tc) return SWIG_ERROR; - } - } - return SWIG_OK; -} - -/* ----------------------------------------------------------------------------- - * Create a new pointer object - * ----------------------------------------------------------------------------- */ - -/* - Create a new instance object, whitout calling __init__, and set the - 'this' attribute. -*/ - -SWIGRUNTIME PyObject* -SWIG_Python_NewShadowInstance(PySwigClientData *data, PyObject *swig_this) -{ -#if (PY_VERSION_HEX >= 0x02020000) - PyObject *inst = 0; - PyObject *newraw = data->newraw; - if (newraw) { - inst = PyObject_Call(newraw, data->newargs, NULL); - if (inst) { -#if !defined(SWIG_PYTHON_SLOW_GETSET_THIS) - PyObject **dictptr = _PyObject_GetDictPtr(inst); - if (dictptr != NULL) { - PyObject *dict = *dictptr; - if (dict == NULL) { - dict = PyDict_New(); - *dictptr = dict; - PyDict_SetItem(dict, SWIG_This(), swig_this); - } - } -#else - PyObject *key = SWIG_This(); - PyObject_SetAttr(inst, key, swig_this); -#endif - } - } else { - PyObject *dict = PyDict_New(); - PyDict_SetItem(dict, SWIG_This(), swig_this); - inst = PyInstance_NewRaw(data->newargs, dict); - Py_DECREF(dict); - } - return inst; -#else -#if (PY_VERSION_HEX >= 0x02010000) - PyObject *inst; - PyObject *dict = PyDict_New(); - PyDict_SetItem(dict, SWIG_This(), swig_this); - inst = PyInstance_NewRaw(data->newargs, dict); - Py_DECREF(dict); - return (PyObject *) inst; -#else - PyInstanceObject *inst = PyObject_NEW(PyInstanceObject, &PyInstance_Type); - if (inst == NULL) { - return NULL; - } - inst->in_class = (PyClassObject *)data->newargs; - Py_INCREF(inst->in_class); - inst->in_dict = PyDict_New(); - if (inst->in_dict == NULL) { - Py_DECREF(inst); - return NULL; - } -#ifdef Py_TPFLAGS_HAVE_WEAKREFS - inst->in_weakreflist = NULL; -#endif -#ifdef Py_TPFLAGS_GC - PyObject_GC_Init(inst); -#endif - PyDict_SetItem(inst->in_dict, SWIG_This(), swig_this); - return (PyObject *) inst; -#endif -#endif -} - -SWIGRUNTIME void -SWIG_Python_SetSwigThis(PyObject *inst, PyObject *swig_this) -{ - PyObject *dict; -#if (PY_VERSION_HEX >= 0x02020000) && !defined(SWIG_PYTHON_SLOW_GETSET_THIS) - PyObject **dictptr = _PyObject_GetDictPtr(inst); - if (dictptr != NULL) { - dict = *dictptr; - if (dict == NULL) { - dict = PyDict_New(); - *dictptr = dict; - } - PyDict_SetItem(dict, SWIG_This(), swig_this); - return; - } -#endif - dict = PyObject_GetAttrString(inst, (char*)"__dict__"); - PyDict_SetItem(dict, SWIG_This(), swig_this); - Py_DECREF(dict); -} - - -SWIGINTERN PyObject * -SWIG_Python_InitShadowInstance(PyObject *args) { - PyObject *obj[2]; - if (!SWIG_Python_UnpackTuple(args,(char*)"swiginit", 2, 2, obj)) { - return NULL; - } else { - PySwigObject *sthis = SWIG_Python_GetSwigThis(obj[0]); - if (sthis) { - PySwigObject_append((PyObject*) sthis, obj[1]); - } else { - SWIG_Python_SetSwigThis(obj[0], obj[1]); - } - return SWIG_Py_Void(); - } -} - -/* Create a new pointer object */ - -SWIGRUNTIME PyObject * -SWIG_Python_NewPointerObj(void *ptr, swig_type_info *type, int flags) { - if (!ptr) { - return SWIG_Py_Void(); - } else { - int own = (flags & SWIG_POINTER_OWN) ? SWIG_POINTER_OWN : 0; - PyObject *robj = PySwigObject_New(ptr, type, own); - PySwigClientData *clientdata = type ? (PySwigClientData *)(type->clientdata) : 0; - if (clientdata && !(flags & SWIG_POINTER_NOSHADOW)) { - PyObject *inst = SWIG_Python_NewShadowInstance(clientdata, robj); - if (inst) { - Py_DECREF(robj); - robj = inst; - } - } - return robj; - } -} - -/* Create a new packed object */ - -SWIGRUNTIMEINLINE PyObject * -SWIG_Python_NewPackedObj(void *ptr, size_t sz, swig_type_info *type) { - return ptr ? PySwigPacked_New((void *) ptr, sz, type) : SWIG_Py_Void(); -} - -/* -----------------------------------------------------------------------------* - * Get type list - * -----------------------------------------------------------------------------*/ - -#ifdef SWIG_LINK_RUNTIME -void *SWIG_ReturnGlobalTypeList(void *); -#endif - -SWIGRUNTIME swig_module_info * -SWIG_Python_GetModule(void) { - static void *type_pointer = (void *)0; - /* first check if module already created */ - if (!type_pointer) { -#ifdef SWIG_LINK_RUNTIME - type_pointer = SWIG_ReturnGlobalTypeList((void *)0); -#else - type_pointer = PyCObject_Import((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION, - (char*)"type_pointer" SWIG_TYPE_TABLE_NAME); - if (PyErr_Occurred()) { - PyErr_Clear(); - type_pointer = (void *)0; - } -#endif - } - return (swig_module_info *) type_pointer; -} - -#if PY_MAJOR_VERSION < 2 -/* PyModule_AddObject function was introduced in Python 2.0. The following function - is copied out of Python/modsupport.c in python version 2.3.4 */ -SWIGINTERN int -PyModule_AddObject(PyObject *m, char *name, PyObject *o) -{ - PyObject *dict; - if (!PyModule_Check(m)) { - PyErr_SetString(PyExc_TypeError, - "PyModule_AddObject() needs module as first arg"); - return SWIG_ERROR; - } - if (!o) { - PyErr_SetString(PyExc_TypeError, - "PyModule_AddObject() needs non-NULL value"); - return SWIG_ERROR; - } - - dict = PyModule_GetDict(m); - if (dict == NULL) { - /* Internal error -- modules must have a dict! */ - PyErr_Format(PyExc_SystemError, "module '%s' has no __dict__", - PyModule_GetName(m)); - return SWIG_ERROR; - } - if (PyDict_SetItemString(dict, name, o)) - return SWIG_ERROR; - Py_DECREF(o); - return SWIG_OK; -} -#endif - -SWIGRUNTIME void -SWIG_Python_DestroyModule(void *vptr) -{ - swig_module_info *swig_module = (swig_module_info *) vptr; - swig_type_info **types = swig_module->types; - size_t i; - for (i =0; i < swig_module->size; ++i) { - swig_type_info *ty = types[i]; - if (ty->owndata) { - PySwigClientData *data = (PySwigClientData *) ty->clientdata; - if (data) PySwigClientData_Del(data); - } - } - Py_DECREF(SWIG_This()); -} - -SWIGRUNTIME void -SWIG_Python_SetModule(swig_module_info *swig_module) { - static PyMethodDef swig_empty_runtime_method_table[] = { {NULL, NULL, 0, NULL} };/* Sentinel */ - - PyObject *module = Py_InitModule((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION, - swig_empty_runtime_method_table); - PyObject *pointer = PyCObject_FromVoidPtr((void *) swig_module, SWIG_Python_DestroyModule); - if (pointer && module) { - PyModule_AddObject(module, (char*)"type_pointer" SWIG_TYPE_TABLE_NAME, pointer); - } else { - Py_XDECREF(pointer); - } -} - -/* The python cached type query */ -SWIGRUNTIME PyObject * -SWIG_Python_TypeCache(void) { - static PyObject *SWIG_STATIC_POINTER(cache) = PyDict_New(); - return cache; -} - -SWIGRUNTIME swig_type_info * -SWIG_Python_TypeQuery(const char *type) -{ - PyObject *cache = SWIG_Python_TypeCache(); - PyObject *key = PyString_FromString(type); - PyObject *obj = PyDict_GetItem(cache, key); - swig_type_info *descriptor; - if (obj) { - descriptor = (swig_type_info *) PyCObject_AsVoidPtr(obj); - } else { - swig_module_info *swig_module = SWIG_Python_GetModule(); - descriptor = SWIG_TypeQueryModule(swig_module, swig_module, type); - if (descriptor) { - obj = PyCObject_FromVoidPtr(descriptor, NULL); - PyDict_SetItem(cache, key, obj); - Py_DECREF(obj); - } - } - Py_DECREF(key); - return descriptor; -} - -/* - For backward compatibility only -*/ -#define SWIG_POINTER_EXCEPTION 0 -#define SWIG_arg_fail(arg) SWIG_Python_ArgFail(arg) -#define SWIG_MustGetPtr(p, type, argnum, flags) SWIG_Python_MustGetPtr(p, type, argnum, flags) - -SWIGRUNTIME int -SWIG_Python_AddErrMesg(const char* mesg, int infront) -{ - if (PyErr_Occurred()) { - PyObject *type = 0; - PyObject *value = 0; - PyObject *traceback = 0; - PyErr_Fetch(&type, &value, &traceback); - if (value) { - PyObject *old_str = PyObject_Str(value); - Py_XINCREF(type); - PyErr_Clear(); - if (infront) { - PyErr_Format(type, "%s %s", mesg, PyString_AsString(old_str)); - } else { - PyErr_Format(type, "%s %s", PyString_AsString(old_str), mesg); - } - Py_DECREF(old_str); - } - return 1; - } else { - return 0; - } -} - -SWIGRUNTIME int -SWIG_Python_ArgFail(int argnum) -{ - if (PyErr_Occurred()) { - /* add information about failing argument */ - char mesg[256]; - PyOS_snprintf(mesg, sizeof(mesg), "argument number %d:", argnum); - return SWIG_Python_AddErrMesg(mesg, 1); - } else { - return 0; - } -} - -SWIGRUNTIMEINLINE const char * -PySwigObject_GetDesc(PyObject *self) -{ - PySwigObject *v = (PySwigObject *)self; - swig_type_info *ty = v ? v->ty : 0; - return ty ? ty->str : (char*)""; -} - -SWIGRUNTIME void -SWIG_Python_TypeError(const char *type, PyObject *obj) -{ - if (type) { -#if defined(SWIG_COBJECT_TYPES) - if (obj && PySwigObject_Check(obj)) { - const char *otype = (const char *) PySwigObject_GetDesc(obj); - if (otype) { - PyErr_Format(PyExc_TypeError, "a '%s' is expected, 'PySwigObject(%s)' is received", - type, otype); - return; - } - } else -#endif - { - const char *otype = (obj ? obj->ob_type->tp_name : 0); - if (otype) { - PyObject *str = PyObject_Str(obj); - const char *cstr = str ? PyString_AsString(str) : 0; - if (cstr) { - PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s(%s)' is received", - type, otype, cstr); - } else { - PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s' is received", - type, otype); - } - Py_XDECREF(str); - return; - } - } - PyErr_Format(PyExc_TypeError, "a '%s' is expected", type); - } else { - PyErr_Format(PyExc_TypeError, "unexpected type is received"); - } -} - - -/* Convert a pointer value, signal an exception on a type mismatch */ -SWIGRUNTIME void * -SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int argnum, int flags) { - void *result; - if (SWIG_Python_ConvertPtr(obj, &result, ty, flags) == -1) { - PyErr_Clear(); - if (flags & SWIG_POINTER_EXCEPTION) { - SWIG_Python_TypeError(SWIG_TypePrettyName(ty), obj); - SWIG_Python_ArgFail(argnum); - } - } - return result; -} - - -#ifdef __cplusplus -#if 0 -{ /* cc-mode */ -#endif -} -#endif - - - -#define SWIG_exception_fail(code, msg) do { SWIG_Error(code, msg); SWIG_fail; } while(0) - -#define SWIG_contract_assert(expr, msg) if (!(expr)) { SWIG_Error(SWIG_RuntimeError, msg); SWIG_fail; } else - - - -/* -------- TYPES TABLE (BEGIN) -------- */ - -#define SWIGTYPE_p_TALLOC_CTX swig_types[0] -#define SWIGTYPE_p_char swig_types[1] -#define SWIGTYPE_p_event_context swig_types[2] -#define SWIGTYPE_p_p_char swig_types[3] -static swig_type_info *swig_types[5]; -static swig_module_info swig_module = {swig_types, 4, 0, 0, 0, 0}; -#define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name) -#define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name) - -/* -------- TYPES TABLE (END) -------- */ - -#if (PY_VERSION_HEX <= 0x02000000) -# if !defined(SWIG_PYTHON_CLASSIC) -# error "This python version requires swig to be run with the '-classic' option" -# endif -#endif -#if (PY_VERSION_HEX <= 0x02020000) -# error "This python version requires swig to be run with the '-nomodern' option" -#endif -#if (PY_VERSION_HEX <= 0x02020000) -# error "This python version requires swig to be run with the '-nomodernargs' option" -#endif -#ifndef METH_O -# error "This python version requires swig to be run with the '-nofastunpack' option" -#endif -#ifdef SWIG_TypeQuery -# undef SWIG_TypeQuery -#endif -#define SWIG_TypeQuery SWIG_Python_TypeQuery - -/*----------------------------------------------- - @(target):= _events.so - ------------------------------------------------*/ -#define SWIG_init init_events - -#define SWIG_name "_events" - -#define SWIGVERSION 0x010336 -#define SWIG_VERSION SWIGVERSION - - -#define SWIG_as_voidptr(a) (void *)((const void *)(a)) -#define SWIG_as_voidptrptr(a) ((void)SWIG_as_voidptr(*a),(void**)(a)) - - -#include "events.h" -typedef struct event_context event; - -SWIGINTERN event *new_event(TALLOC_CTX *mem_ctx){ return event_context_init(mem_ctx); } - - #define SWIG_From_long PyInt_FromLong - - -SWIGINTERNINLINE PyObject * -SWIG_From_int (int value) -{ - return SWIG_From_long (value); -} - -SWIGINTERN void delete_event(event *self){ talloc_free(self); } - -SWIGINTERN swig_type_info* -SWIG_pchar_descriptor(void) -{ - static int init = 0; - static swig_type_info* info = 0; - if (!init) { - info = SWIG_TypeQuery("_p_char"); - init = 1; - } - return info; -} - - -SWIGINTERN int -SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc) -{ - if (PyString_Check(obj)) { - char *cstr; Py_ssize_t len; - PyString_AsStringAndSize(obj, &cstr, &len); - if (cptr) { - if (alloc) { - /* - In python the user should not be able to modify the inner - string representation. To warranty that, if you define - SWIG_PYTHON_SAFE_CSTRINGS, a new/copy of the python string - buffer is always returned. - - The default behavior is just to return the pointer value, - so, be careful. - */ -#if defined(SWIG_PYTHON_SAFE_CSTRINGS) - if (*alloc != SWIG_OLDOBJ) -#else - if (*alloc == SWIG_NEWOBJ) -#endif - { - *cptr = (char *)memcpy((char *)malloc((len + 1)*sizeof(char)), cstr, sizeof(char)*(len + 1)); - *alloc = SWIG_NEWOBJ; - } - else { - *cptr = cstr; - *alloc = SWIG_OLDOBJ; - } - } else { - *cptr = PyString_AsString(obj); - } - } - if (psize) *psize = len + 1; - return SWIG_OK; - } else { - swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); - if (pchar_descriptor) { - void* vptr = 0; - if (SWIG_ConvertPtr(obj, &vptr, pchar_descriptor, 0) == SWIG_OK) { - if (cptr) *cptr = (char *) vptr; - if (psize) *psize = vptr ? (strlen((char *)vptr) + 1) : 0; - if (alloc) *alloc = SWIG_OLDOBJ; - return SWIG_OK; - } - } - } - return SWIG_TypeError; -} - - - - -#ifdef __cplusplus -extern "C" { -#endif -SWIGINTERN PyObject *_wrap_new_event(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; - event *result = 0 ; - - arg1 = NULL; - if (!SWIG_Python_UnpackTuple(args,"new_event",0,0,0)) SWIG_fail; - result = (event *)new_event(arg1); - resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_event_context, SWIG_POINTER_NEW | 0 ); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_event_loop_once(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - event *arg1 = (event *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - int result; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_event_context, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "event_loop_once" "', argument " "1"" of type '" "event *""'"); - } - arg1 = (event *)(argp1); - result = (int)event_loop_once(arg1); - resultobj = SWIG_From_int((int)(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_event_loop_wait(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - event *arg1 = (event *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - int result; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_event_context, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "event_loop_wait" "', argument " "1"" of type '" "event *""'"); - } - arg1 = (event *)(argp1); - result = (int)event_loop_wait(arg1); - resultobj = SWIG_From_int((int)(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_delete_event(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - event *arg1 = (event *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_event_context, SWIG_POINTER_DISOWN | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_event" "', argument " "1"" of type '" "event *""'"); - } - arg1 = (event *)(argp1); - delete_event(arg1); - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *event_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *obj; - if (!SWIG_Python_UnpackTuple(args,(char*)"swigregister", 1, 1,&obj)) return NULL; - SWIG_TypeNewClientData(SWIGTYPE_p_event_context, SWIG_NewClientData(obj)); - return SWIG_Py_Void(); -} - -SWIGINTERN PyObject *event_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - return SWIG_Python_InitShadowInstance(args); -} - -SWIGINTERN PyObject *_wrap_event_context_init_byname(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; - char *arg2 = (char *) 0 ; - int res2 ; - char *buf2 = 0 ; - int alloc2 = 0 ; - PyObject * obj0 = 0 ; - char * kwnames[] = { - (char *) "name", NULL - }; - struct event_context *result = 0 ; - - arg1 = NULL; - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:event_context_init_byname",kwnames,&obj0)) SWIG_fail; - res2 = SWIG_AsCharPtrAndSize(obj0, &buf2, NULL, &alloc2); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "event_context_init_byname" "', argument " "2"" of type '" "char const *""'"); - } - arg2 = (char *)(buf2); - result = (struct event_context *)event_context_init_byname(arg1,(char const *)arg2); - resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_event_context, 0 | 0 ); - if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); - return resultobj; -fail: - if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); - return NULL; -} - - -SWIGINTERN PyObject *_wrap_event_backend_list(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; - char **result = 0 ; - - arg1 = NULL; - if (!SWIG_Python_UnpackTuple(args,"event_backend_list",0,0,0)) SWIG_fail; - result = (char **)event_backend_list(arg1); - resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_p_char, 0 | 0 ); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_set_default_backend(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - char *arg1 = (char *) 0 ; - int res1 ; - char *buf1 = 0 ; - int alloc1 = 0 ; - PyObject * obj0 = 0 ; - char * kwnames[] = { - (char *) "backend", NULL - }; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:set_default_backend",kwnames,&obj0)) SWIG_fail; - res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "set_default_backend" "', argument " "1"" of type '" "char const *""'"); - } - arg1 = (char *)(buf1); - event_set_default_backend((char const *)arg1); - resultobj = SWIG_Py_Void(); - if (alloc1 == SWIG_NEWOBJ) free((char*)buf1); - return resultobj; -fail: - if (alloc1 == SWIG_NEWOBJ) free((char*)buf1); - return NULL; -} - - -static PyMethodDef SwigMethods[] = { - { (char *)"new_event", (PyCFunction)_wrap_new_event, METH_NOARGS, (char *)"S.__init__()"}, - { (char *)"event_loop_once", (PyCFunction)_wrap_event_loop_once, METH_O, (char *)"S.loop_once() -> int"}, - { (char *)"event_loop_wait", (PyCFunction)_wrap_event_loop_wait, METH_O, (char *)"S.loop_wait() -> int"}, - { (char *)"delete_event", (PyCFunction)_wrap_delete_event, METH_O, NULL}, - { (char *)"event_swigregister", event_swigregister, METH_VARARGS, NULL}, - { (char *)"event_swiginit", event_swiginit, METH_VARARGS, NULL}, - { (char *)"event_context_init_byname", (PyCFunction) _wrap_event_context_init_byname, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"event_backend_list", (PyCFunction)_wrap_event_backend_list, METH_NOARGS, (char *)"event_backend_list() -> list"}, - { (char *)"set_default_backend", (PyCFunction) _wrap_set_default_backend, METH_VARARGS | METH_KEYWORDS, (char *)"event_set_default_backend(name) -> None"}, - { NULL, NULL, 0, NULL } -}; - - -/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */ - -static swig_type_info _swigt__p_TALLOC_CTX = {"_p_TALLOC_CTX", "TALLOC_CTX *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_event_context = {"_p_event_context", "struct event_context *|event *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_p_char = {"_p_p_char", "char **", 0, 0, (void*)0, 0}; - -static swig_type_info *swig_type_initial[] = { - &_swigt__p_TALLOC_CTX, - &_swigt__p_char, - &_swigt__p_event_context, - &_swigt__p_p_char, -}; - -static swig_cast_info _swigc__p_TALLOC_CTX[] = { {&_swigt__p_TALLOC_CTX, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_char[] = { {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_event_context[] = { {&_swigt__p_event_context, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_p_char[] = { {&_swigt__p_p_char, 0, 0, 0},{0, 0, 0, 0}}; - -static swig_cast_info *swig_cast_initial[] = { - _swigc__p_TALLOC_CTX, - _swigc__p_char, - _swigc__p_event_context, - _swigc__p_p_char, -}; - - -/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */ - -static swig_const_info swig_const_table[] = { -{0, 0, 0, 0.0, 0, 0}}; - -#ifdef __cplusplus -} -#endif -/* ----------------------------------------------------------------------------- - * Type initialization: - * This problem is tough by the requirement that no dynamic - * memory is used. Also, since swig_type_info structures store pointers to - * swig_cast_info structures and swig_cast_info structures store pointers back - * to swig_type_info structures, we need some lookup code at initialization. - * The idea is that swig generates all the structures that are needed. - * The runtime then collects these partially filled structures. - * The SWIG_InitializeModule function takes these initial arrays out of - * swig_module, and does all the lookup, filling in the swig_module.types - * array with the correct data and linking the correct swig_cast_info - * structures together. - * - * The generated swig_type_info structures are assigned staticly to an initial - * array. We just loop through that array, and handle each type individually. - * First we lookup if this type has been already loaded, and if so, use the - * loaded structure instead of the generated one. Then we have to fill in the - * cast linked list. The cast data is initially stored in something like a - * two-dimensional array. Each row corresponds to a type (there are the same - * number of rows as there are in the swig_type_initial array). Each entry in - * a column is one of the swig_cast_info structures for that type. - * The cast_initial array is actually an array of arrays, because each row has - * a variable number of columns. So to actually build the cast linked list, - * we find the array of casts associated with the type, and loop through it - * adding the casts to the list. The one last trick we need to do is making - * sure the type pointer in the swig_cast_info struct is correct. - * - * First off, we lookup the cast->type name to see if it is already loaded. - * There are three cases to handle: - * 1) If the cast->type has already been loaded AND the type we are adding - * casting info to has not been loaded (it is in this module), THEN we - * replace the cast->type pointer with the type pointer that has already - * been loaded. - * 2) If BOTH types (the one we are adding casting info to, and the - * cast->type) are loaded, THEN the cast info has already been loaded by - * the previous module so we just ignore it. - * 3) Finally, if cast->type has not already been loaded, then we add that - * swig_cast_info to the linked list (because the cast->type) pointer will - * be correct. - * ----------------------------------------------------------------------------- */ - -#ifdef __cplusplus -extern "C" { -#if 0 -} /* c-mode */ -#endif -#endif - -#if 0 -#define SWIGRUNTIME_DEBUG -#endif - - -SWIGRUNTIME void -SWIG_InitializeModule(void *clientdata) { - size_t i; - swig_module_info *module_head, *iter; - int found, init; - - clientdata = clientdata; - - /* check to see if the circular list has been setup, if not, set it up */ - if (swig_module.next==0) { - /* Initialize the swig_module */ - swig_module.type_initial = swig_type_initial; - swig_module.cast_initial = swig_cast_initial; - swig_module.next = &swig_module; - init = 1; - } else { - init = 0; - } - - /* Try and load any already created modules */ - module_head = SWIG_GetModule(clientdata); - if (!module_head) { - /* This is the first module loaded for this interpreter */ - /* so set the swig module into the interpreter */ - SWIG_SetModule(clientdata, &swig_module); - module_head = &swig_module; - } else { - /* the interpreter has loaded a SWIG module, but has it loaded this one? */ - found=0; - iter=module_head; - do { - if (iter==&swig_module) { - found=1; - break; - } - iter=iter->next; - } while (iter!= module_head); - - /* if the is found in the list, then all is done and we may leave */ - if (found) return; - /* otherwise we must add out module into the list */ - swig_module.next = module_head->next; - module_head->next = &swig_module; - } - - /* When multiple interpeters are used, a module could have already been initialized in - a different interpreter, but not yet have a pointer in this interpreter. - In this case, we do not want to continue adding types... everything should be - set up already */ - if (init == 0) return; - - /* Now work on filling in swig_module.types */ -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: size %d\n", swig_module.size); -#endif - for (i = 0; i < swig_module.size; ++i) { - swig_type_info *type = 0; - swig_type_info *ret; - swig_cast_info *cast; - -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name); -#endif - - /* if there is another module already loaded */ - if (swig_module.next != &swig_module) { - type = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, swig_module.type_initial[i]->name); - } - if (type) { - /* Overwrite clientdata field */ -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: found type %s\n", type->name); -#endif - if (swig_module.type_initial[i]->clientdata) { - type->clientdata = swig_module.type_initial[i]->clientdata; -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: found and overwrite type %s \n", type->name); -#endif - } - } else { - type = swig_module.type_initial[i]; - } - - /* Insert casting types */ - cast = swig_module.cast_initial[i]; - while (cast->type) { - /* Don't need to add information already in the list */ - ret = 0; -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: look cast %s\n", cast->type->name); -#endif - if (swig_module.next != &swig_module) { - ret = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, cast->type->name); -#ifdef SWIGRUNTIME_DEBUG - if (ret) printf("SWIG_InitializeModule: found cast %s\n", ret->name); -#endif - } - if (ret) { - if (type == swig_module.type_initial[i]) { -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: skip old type %s\n", ret->name); -#endif - cast->type = ret; - ret = 0; - } else { - /* Check for casting already in the list */ - swig_cast_info *ocast = SWIG_TypeCheck(ret->name, type); -#ifdef SWIGRUNTIME_DEBUG - if (ocast) printf("SWIG_InitializeModule: skip old cast %s\n", ret->name); -#endif - if (!ocast) ret = 0; - } - } - - if (!ret) { -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: adding cast %s\n", cast->type->name); -#endif - if (type->cast) { - type->cast->prev = cast; - cast->next = type->cast; - } - type->cast = cast; - } - cast++; - } - /* Set entry in modules->types array equal to the type */ - swig_module.types[i] = type; - } - swig_module.types[i] = 0; - -#ifdef SWIGRUNTIME_DEBUG - printf("**** SWIG_InitializeModule: Cast List ******\n"); - for (i = 0; i < swig_module.size; ++i) { - int j = 0; - swig_cast_info *cast = swig_module.cast_initial[i]; - printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name); - while (cast->type) { - printf("SWIG_InitializeModule: cast type %s\n", cast->type->name); - cast++; - ++j; - } - printf("---- Total casts: %d\n",j); - } - printf("**** SWIG_InitializeModule: Cast List ******\n"); -#endif -} - -/* This function will propagate the clientdata field of type to -* any new swig_type_info structures that have been added into the list -* of equivalent types. It is like calling -* SWIG_TypeClientData(type, clientdata) a second time. -*/ -SWIGRUNTIME void -SWIG_PropagateClientData(void) { - size_t i; - swig_cast_info *equiv; - static int init_run = 0; - - if (init_run) return; - init_run = 1; - - for (i = 0; i < swig_module.size; i++) { - if (swig_module.types[i]->clientdata) { - equiv = swig_module.types[i]->cast; - while (equiv) { - if (!equiv->converter) { - if (equiv->type && !equiv->type->clientdata) - SWIG_TypeClientData(equiv->type, swig_module.types[i]->clientdata); - } - equiv = equiv->next; - } - } - } -} - -#ifdef __cplusplus -#if 0 -{ - /* c-mode */ -#endif -} -#endif - - - -#ifdef __cplusplus -extern "C" { -#endif - - /* Python-specific SWIG API */ -#define SWIG_newvarlink() SWIG_Python_newvarlink() -#define SWIG_addvarlink(p, name, get_attr, set_attr) SWIG_Python_addvarlink(p, name, get_attr, set_attr) -#define SWIG_InstallConstants(d, constants) SWIG_Python_InstallConstants(d, constants) - - /* ----------------------------------------------------------------------------- - * global variable support code. - * ----------------------------------------------------------------------------- */ - - typedef struct swig_globalvar { - char *name; /* Name of global variable */ - PyObject *(*get_attr)(void); /* Return the current value */ - int (*set_attr)(PyObject *); /* Set the value */ - struct swig_globalvar *next; - } swig_globalvar; - - typedef struct swig_varlinkobject { - PyObject_HEAD - swig_globalvar *vars; - } swig_varlinkobject; - - SWIGINTERN PyObject * - swig_varlink_repr(swig_varlinkobject *SWIGUNUSEDPARM(v)) { - return PyString_FromString("<Swig global variables>"); - } - - SWIGINTERN PyObject * - swig_varlink_str(swig_varlinkobject *v) { - PyObject *str = PyString_FromString("("); - swig_globalvar *var; - for (var = v->vars; var; var=var->next) { - PyString_ConcatAndDel(&str,PyString_FromString(var->name)); - if (var->next) PyString_ConcatAndDel(&str,PyString_FromString(", ")); - } - PyString_ConcatAndDel(&str,PyString_FromString(")")); - return str; - } - - SWIGINTERN int - swig_varlink_print(swig_varlinkobject *v, FILE *fp, int SWIGUNUSEDPARM(flags)) { - PyObject *str = swig_varlink_str(v); - fprintf(fp,"Swig global variables "); - fprintf(fp,"%s\n", PyString_AsString(str)); - Py_DECREF(str); - return 0; - } - - SWIGINTERN void - swig_varlink_dealloc(swig_varlinkobject *v) { - swig_globalvar *var = v->vars; - while (var) { - swig_globalvar *n = var->next; - free(var->name); - free(var); - var = n; - } - } - - SWIGINTERN PyObject * - swig_varlink_getattr(swig_varlinkobject *v, char *n) { - PyObject *res = NULL; - swig_globalvar *var = v->vars; - while (var) { - if (strcmp(var->name,n) == 0) { - res = (*var->get_attr)(); - break; - } - var = var->next; - } - if (res == NULL && !PyErr_Occurred()) { - PyErr_SetString(PyExc_NameError,"Unknown C global variable"); - } - return res; - } - - SWIGINTERN int - swig_varlink_setattr(swig_varlinkobject *v, char *n, PyObject *p) { - int res = 1; - swig_globalvar *var = v->vars; - while (var) { - if (strcmp(var->name,n) == 0) { - res = (*var->set_attr)(p); - break; - } - var = var->next; - } - if (res == 1 && !PyErr_Occurred()) { - PyErr_SetString(PyExc_NameError,"Unknown C global variable"); - } - return res; - } - - SWIGINTERN PyTypeObject* - swig_varlink_type(void) { - static char varlink__doc__[] = "Swig var link object"; - static PyTypeObject varlink_type; - static int type_init = 0; - if (!type_init) { - const PyTypeObject tmp - = { - PyObject_HEAD_INIT(NULL) - 0, /* Number of items in variable part (ob_size) */ - (char *)"swigvarlink", /* Type name (tp_name) */ - sizeof(swig_varlinkobject), /* Basic size (tp_basicsize) */ - 0, /* Itemsize (tp_itemsize) */ - (destructor) swig_varlink_dealloc, /* Deallocator (tp_dealloc) */ - (printfunc) swig_varlink_print, /* Print (tp_print) */ - (getattrfunc) swig_varlink_getattr, /* get attr (tp_getattr) */ - (setattrfunc) swig_varlink_setattr, /* Set attr (tp_setattr) */ - 0, /* tp_compare */ - (reprfunc) swig_varlink_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - (reprfunc)swig_varlink_str, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - 0, /* tp_flags */ - varlink__doc__, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ -#if PY_VERSION_HEX >= 0x02020000 - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* tp_iter -> tp_weaklist */ -#endif -#if PY_VERSION_HEX >= 0x02030000 - 0, /* tp_del */ -#endif -#ifdef COUNT_ALLOCS - 0,0,0,0 /* tp_alloc -> tp_next */ -#endif - }; - varlink_type = tmp; - varlink_type.ob_type = &PyType_Type; - type_init = 1; - } - return &varlink_type; - } - - /* Create a variable linking object for use later */ - SWIGINTERN PyObject * - SWIG_Python_newvarlink(void) { - swig_varlinkobject *result = PyObject_NEW(swig_varlinkobject, swig_varlink_type()); - if (result) { - result->vars = 0; - } - return ((PyObject*) result); - } - - SWIGINTERN void - SWIG_Python_addvarlink(PyObject *p, char *name, PyObject *(*get_attr)(void), int (*set_attr)(PyObject *p)) { - swig_varlinkobject *v = (swig_varlinkobject *) p; - swig_globalvar *gv = (swig_globalvar *) malloc(sizeof(swig_globalvar)); - if (gv) { - size_t size = strlen(name)+1; - gv->name = (char *)malloc(size); - if (gv->name) { - strncpy(gv->name,name,size); - gv->get_attr = get_attr; - gv->set_attr = set_attr; - gv->next = v->vars; - } - } - v->vars = gv; - } - - SWIGINTERN PyObject * - SWIG_globals(void) { - static PyObject *_SWIG_globals = 0; - if (!_SWIG_globals) _SWIG_globals = SWIG_newvarlink(); - return _SWIG_globals; - } - - /* ----------------------------------------------------------------------------- - * constants/methods manipulation - * ----------------------------------------------------------------------------- */ - - /* Install Constants */ - SWIGINTERN void - SWIG_Python_InstallConstants(PyObject *d, swig_const_info constants[]) { - PyObject *obj = 0; - size_t i; - for (i = 0; constants[i].type; ++i) { - switch(constants[i].type) { - case SWIG_PY_POINTER: - obj = SWIG_NewPointerObj(constants[i].pvalue, *(constants[i]).ptype,0); - break; - case SWIG_PY_BINARY: - obj = SWIG_NewPackedObj(constants[i].pvalue, constants[i].lvalue, *(constants[i].ptype)); - break; - default: - obj = 0; - break; - } - if (obj) { - PyDict_SetItemString(d, constants[i].name, obj); - Py_DECREF(obj); - } - } - } - - /* -----------------------------------------------------------------------------*/ - /* Fix SwigMethods to carry the callback ptrs when needed */ - /* -----------------------------------------------------------------------------*/ - - SWIGINTERN void - SWIG_Python_FixMethods(PyMethodDef *methods, - swig_const_info *const_table, - swig_type_info **types, - swig_type_info **types_initial) { - size_t i; - for (i = 0; methods[i].ml_name; ++i) { - const char *c = methods[i].ml_doc; - if (c && (c = strstr(c, "swig_ptr: "))) { - int j; - swig_const_info *ci = 0; - const char *name = c + 10; - for (j = 0; const_table[j].type; ++j) { - if (strncmp(const_table[j].name, name, - strlen(const_table[j].name)) == 0) { - ci = &(const_table[j]); - break; - } - } - if (ci) { - size_t shift = (ci->ptype) - types; - swig_type_info *ty = types_initial[shift]; - size_t ldoc = (c - methods[i].ml_doc); - size_t lptr = strlen(ty->name)+2*sizeof(void*)+2; - char *ndoc = (char*)malloc(ldoc + lptr + 10); - if (ndoc) { - char *buff = ndoc; - void *ptr = (ci->type == SWIG_PY_POINTER) ? ci->pvalue : 0; - if (ptr) { - strncpy(buff, methods[i].ml_doc, ldoc); - buff += ldoc; - strncpy(buff, "swig_ptr: ", 10); - buff += 10; - SWIG_PackVoidPtr(buff, ptr, ty->name, lptr); - methods[i].ml_doc = ndoc; - } - } - } - } - } - } - -#ifdef __cplusplus -} -#endif - -/* -----------------------------------------------------------------------------* - * Partial Init method - * -----------------------------------------------------------------------------*/ - -#ifdef __cplusplus -extern "C" -#endif -SWIGEXPORT void SWIG_init(void) { - PyObject *m, *d; - - /* Fix SwigMethods to carry the callback ptrs when needed */ - SWIG_Python_FixMethods(SwigMethods, swig_const_table, swig_types, swig_type_initial); - - m = Py_InitModule((char *) SWIG_name, SwigMethods); - d = PyModule_GetDict(m); - - SWIG_InitializeModule(0); - SWIG_InstallConstants(d,swig_const_table); - - -} - diff --git a/source4/lib/events/libevents.m4 b/source4/lib/events/libevents.m4 deleted file mode 100644 index ed76b03d4f..0000000000 --- a/source4/lib/events/libevents.m4 +++ /dev/null @@ -1,49 +0,0 @@ -dnl find the events sources. This is meant to work both for -dnl standalone builds, and builds of packages using libevents -if test x"$eventsdir" = "x"; then - eventsdir="" - eventspaths="$srcdir $srcdir/../samba4/source/lib/events $srcdir/lib/events $srcdir/events $srcdir/../events" - for d in $eventspaths; do - if test -f "$d/events.c"; then - eventsdir="$d" - AC_SUBST(eventsdir) - break; - fi - done - if test x"$eventsdir" = "x"; then - AC_MSG_ERROR([cannot find libevents source in $eventspaths]) - fi -fi - -EVENTS_OBJ="events.o events_select.o events_signal.o events_timed.o events_standard.o events_debug.o events_util.o" -AC_LIBREPLACE_NETWORK_CHECKS - -SMB_ENABLE(EVENTS_EPOLL, NO) -SMB_ENABLE(EVENTS_AIO, NO) -AC_CHECK_HEADERS(sys/epoll.h) -AC_CHECK_FUNCS(epoll_create) -if test x"$ac_cv_header_sys_epoll_h" = x"yes" -a x"$ac_cv_func_epoll_create" = x"yes"; then - EVENTS_OBJ="$EVENTS_OBJ events_epoll.o" - SMB_ENABLE(EVENTS_EPOLL,YES) - AC_DEFINE(HAVE_EVENTS_EPOLL, 1, [Whether epoll available]) - - # check for native Linux AIO interface - AC_CHECK_HEADERS(libaio.h) - AC_CHECK_LIB_EXT(aio, AIO_LIBS, io_getevents) - if test x"$ac_cv_header_libaio_h" = x"yes" -a x"$ac_cv_lib_ext_aio_io_getevents" = x"yes";then - EVENTS_OBJ="$EVENTS_OBJ events_aio.o" - SMB_ENABLE(EVENTS_AIO,YES) - AC_DEFINE(HAVE_LINUX_AIO, 1, [Whether Linux AIO is available]) - fi -fi - -AC_SUBST(EVENTS_OBJ) -SMB_EXT_LIB(LIBAIO_LINUX, $AIO_LIBS) - -EVENTS_CFLAGS="-I$eventsdir" -AC_SUBST(EVENTS_CFLAGS) - -EVENTS_LIBS="$AIO_LIBS" -AC_SUBST(EVENTS_LIBS) - - diff --git a/source4/lib/events/libtalloc.m4 b/source4/lib/events/libtalloc.m4 deleted file mode 100644 index a4c5b8a9d9..0000000000 --- a/source4/lib/events/libtalloc.m4 +++ /dev/null @@ -1,7 +0,0 @@ -AC_SUBST(TALLOC_OBJ) -AC_SUBST(TALLOC_CFLAGS) -AC_SUBST(TALLOC_LIBS) - -AC_CHECK_HEADER(talloc.h, - [AC_CHECK_LIB(talloc, talloc_init, [TALLOC_LIBS="-ltalloc"]) ], - [PKG_CHECK_MODULES(TALLOC, talloc)]) diff --git a/source4/lib/events/pkg.m4 b/source4/lib/events/pkg.m4 deleted file mode 100644 index a8b3d06c81..0000000000 --- a/source4/lib/events/pkg.m4 +++ /dev/null @@ -1,156 +0,0 @@ -# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- -# -# Copyright © 2004 Scott James Remnant <scott@netsplit.com>. -# -# 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/>. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# PKG_PROG_PKG_CONFIG([MIN-VERSION]) -# ---------------------------------- -AC_DEFUN([PKG_PROG_PKG_CONFIG], -[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) -m4_pattern_allow([^PKG_CONFIG(_PATH)?$]) -AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])dnl -if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then - AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) -fi -if test -n "$PKG_CONFIG"; then - _pkg_min_version=m4_default([$1], [0.9.0]) - AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) - if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - PKG_CONFIG="" - fi - -fi[]dnl -])# PKG_PROG_PKG_CONFIG - -# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) -# -# Check to see whether a particular set of modules exists. Similar -# to PKG_CHECK_MODULES(), but does not set variables or print errors. -# -# -# Similar to PKG_CHECK_MODULES, make sure that the first instance of -# this or PKG_CHECK_MODULES is called, or make sure to call -# PKG_CHECK_EXISTS manually -# -------------------------------------------------------------- -AC_DEFUN([PKG_CHECK_EXISTS], -[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl -if test -n "$PKG_CONFIG" && \ - AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then - m4_ifval([$2], [$2], [:]) -m4_ifvaln([$3], [else - $3])dnl -fi]) - - -# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) -# --------------------------------------------- -m4_define([_PKG_CONFIG], -[if test -n "$PKG_CONFIG"; then - if test -n "$$1"; then - pkg_cv_[]$1="$$1" - else - PKG_CHECK_EXISTS([$3], - [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`], - [pkg_failed=yes]) - fi -else - pkg_failed=untried -fi[]dnl -])# _PKG_CONFIG - -# _PKG_SHORT_ERRORS_SUPPORTED -# ----------------------------- -AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], -[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi[]dnl -])# _PKG_SHORT_ERRORS_SUPPORTED - - -# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], -# [ACTION-IF-NOT-FOUND]) -# -# -# Note that if there is a possibility the first call to -# PKG_CHECK_MODULES might not happen, you should be sure to include an -# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac -# -# -# -------------------------------------------------------------- -AC_DEFUN([PKG_CHECK_MODULES], -[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl -AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl -AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl - -pkg_failed=no -AC_MSG_CHECKING([for $1]) - -_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) -_PKG_CONFIG([$1][_LIBS], [libs], [$2]) - -m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS -and $1[]_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details.]) - -if test $pkg_failed = yes; then - _PKG_SHORT_ERRORS_SUPPORTED - if test $_pkg_short_errors_supported = yes; then - $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "$2"` - else - $1[]_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"` - fi - # Put the nasty error message in config.log where it belongs - echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD - - ifelse([$4], , [AC_MSG_ERROR(dnl -[Package requirements ($2) were not met: - -$$1_PKG_ERRORS - -Consider adjusting the PKG_CONFIG_PATH environment variable if you -installed software in a non-standard prefix. - -_PKG_TEXT -])], - [AC_MSG_RESULT([no]) - $4]) -elif test $pkg_failed = untried; then - ifelse([$4], , [AC_MSG_FAILURE(dnl -[The pkg-config script could not be found or is too old. Make sure it -is in your PATH or set the PKG_CONFIG environment variable to the full -path to pkg-config. - -_PKG_TEXT - -To get pkg-config, see <http://www.freedesktop.org/software/pkgconfig>.])], - [$4]) -else - $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS - $1[]_LIBS=$pkg_cv_[]$1[]_LIBS - AC_MSG_RESULT([yes]) - ifelse([$3], , :, [$3]) -fi[]dnl -])# PKG_CHECK_MODULES diff --git a/source4/lib/events/rules.mk b/source4/lib/events/rules.mk deleted file mode 100644 index cfe548039b..0000000000 --- a/source4/lib/events/rules.mk +++ /dev/null @@ -1,21 +0,0 @@ -.SUFFIXES: .i _wrap.c - -.i_wrap.c: - $(SWIG) -O -Wall -python -keyword $< - -showflags:: - @echo 'libevents will be compiled with flags:' - @echo ' CFLAGS = $(CFLAGS)' - @echo ' CPPFLAGS = $(CPPFLAGS)' - @echo ' LDFLAGS = $(LDFLAGS)' - @echo ' LIBS = $(LIBS)' - -.SUFFIXES: .c .o - -.c.o: - @echo Compiling $*.c - @mkdir -p `dirname $@` - @$(CC) $(PICFLAG) $(CFLAGS) -c $< -o $@ - -distclean:: - rm -f *~ */*~ diff --git a/source4/lib/events/tests.py b/source4/lib/events/tests.py deleted file mode 100644 index 006426207e..0000000000 --- a/source4/lib/events/tests.py +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/python - -# Unix SMB/CIFS implementation. -# Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007 -# -# 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/>. -# - -from samba import events -import unittest - -# Just test the bindings are there and that calling them doesn't crash -# anything. - -class EventTestCase(unittest.TestCase): - def test_create(self): - self.assertTrue(events.event() is not None) - - def test_loop_wait(self): - self.assertEquals(0, events.event().loop_wait()) diff --git a/source4/lib/events/testsuite.c b/source4/lib/events/testsuite.c deleted file mode 100644 index 7f2729ceff..0000000000 --- a/source4/lib/events/testsuite.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - testing of the events subsystem - - Copyright (C) Stefan Metzmacher - - 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 "lib/events/events.h" -#include "system/filesys.h" -#include "torture/torture.h" - -static int fde_count; - -static void fde_handler(struct event_context *ev_ctx, struct fd_event *f, - uint16_t flags, void *private) -{ - int *fd = (int *)private; - char c; -#ifdef SA_SIGINFO - kill(getpid(), SIGUSR1); -#endif - kill(getpid(), SIGALRM); - read(fd[0], &c, 1); - write(fd[1], &c, 1); - fde_count++; -} - -static void finished_handler(struct event_context *ev_ctx, struct timed_event *te, - struct timeval tval, void *private) -{ - int *finished = (int *)private; - (*finished) = 1; -} - -static void count_handler(struct event_context *ev_ctx, struct signal_event *te, - int signum, int count, void *info, void *private) -{ - int *countp = (int *)private; - (*countp) += count; -} - -static bool test_event_context(struct torture_context *test, - const void *test_data) -{ - struct event_context *ev_ctx; - int fd[2] = { -1, -1 }; - const char *backend = (const char *)test_data; - int alarm_count=0, info_count=0; - struct fd_event *fde; - struct signal_event *se1, *se2, *se3; - int finished=0; - struct timeval t; - char c = 0; - - ev_ctx = event_context_init_byname(test, backend); - if (ev_ctx == NULL) { - torture_comment(test, "event backend '%s' not supported\n", backend); - return true; - } - - torture_comment(test, "Testing event backend '%s'\n", backend); - - /* reset globals */ - fde_count = 0; - - /* create a pipe */ - pipe(fd); - - fde = event_add_fd(ev_ctx, ev_ctx, fd[0], EVENT_FD_READ|EVENT_FD_AUTOCLOSE, - fde_handler, fd); - - event_add_timed(ev_ctx, ev_ctx, timeval_current_ofs(2,0), - finished_handler, &finished); - - se1 = event_add_signal(ev_ctx, ev_ctx, SIGALRM, SA_RESTART, count_handler, &alarm_count); - se2 = event_add_signal(ev_ctx, ev_ctx, SIGALRM, SA_RESETHAND, count_handler, &alarm_count); -#ifdef SA_SIGINFO - se3 = event_add_signal(ev_ctx, ev_ctx, SIGUSR1, SA_SIGINFO, count_handler, &info_count); -#endif - - write(fd[1], &c, 1); - - t = timeval_current(); - while (!finished) { - errno = 0; - if (event_loop_once(ev_ctx) == -1) { - talloc_free(ev_ctx); - torture_fail(test, talloc_asprintf(test, "Failed event loop %s\n", strerror(errno))); - } - } - - talloc_free(fde); - close(fd[1]); - - while (alarm_count < fde_count+1) { - if (event_loop_once(ev_ctx) == -1) { - break; - } - } - - torture_comment(test, "Got %.2f pipe events/sec\n", fde_count/timeval_elapsed(&t)); - - talloc_free(se1); - - torture_assert_int_equal(test, alarm_count, 1+fde_count, "alarm count mismatch"); - -#ifdef SA_SIGINFO - talloc_free(se3); - torture_assert_int_equal(test, info_count, fde_count, "info count mismatch"); -#endif - - talloc_free(ev_ctx); - - return true; -} - -struct torture_suite *torture_local_event(TALLOC_CTX *mem_ctx) -{ - struct torture_suite *suite = torture_suite_create(mem_ctx, "EVENT"); - const char **list = event_backend_list(suite); - int i; - - for (i=0;list && list[i];i++) { - torture_suite_add_simple_tcase_const(suite, list[i], - test_event_context, - (const void *)list[i]); - } - - return suite; -} diff --git a/source4/lib/ldb-samba/ldif_handlers.c b/source4/lib/ldb-samba/ldif_handlers.c index a16582d294..5ab31d771b 100644 --- a/source4/lib/ldb-samba/ldif_handlers.c +++ b/source4/lib/ldb-samba/ldif_handlers.c @@ -64,8 +64,8 @@ static int ldif_write_objectSid(struct ldb_context *ldb, void *mem_ctx, if (sid == NULL) { return -1; } - ndr_err = ndr_pull_struct_blob(in, sid, NULL, sid, - (ndr_pull_flags_fn_t)ndr_pull_dom_sid); + ndr_err = ndr_pull_struct_blob_all(in, sid, NULL, sid, + (ndr_pull_flags_fn_t)ndr_pull_dom_sid); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(sid); return -1; @@ -139,6 +139,36 @@ static int ldb_canonicalise_objectSid(struct ldb_context *ldb, void *mem_ctx, return ldb_handler_copy(ldb, mem_ctx, in, out); } +static int extended_dn_read_SID(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + struct dom_sid sid; + enum ndr_err_code ndr_err; + if (ldb_comparision_objectSid_isString(in)) { + if (ldif_read_objectSid(ldb, mem_ctx, in, out) == 0) { + return 0; + } + } + + /* Perhaps not a string after all */ + *out = data_blob_talloc(mem_ctx, NULL, in->length/2+1); + + if (!out->data) { + return -1; + } + + (*out).length = strhex_to_str((char *)out->data, out->length, + (const char *)in->data, in->length); + + /* Check it looks like a SID */ + ndr_err = ndr_pull_struct_blob_all(out, mem_ctx, NULL, &sid, + (ndr_pull_flags_fn_t)ndr_pull_dom_sid); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return -1; + } + return 0; +} + /* convert a ldif formatted objectGUID to a NDR formatted blob */ @@ -146,16 +176,10 @@ static int ldif_read_objectGUID(struct ldb_context *ldb, void *mem_ctx, const struct ldb_val *in, struct ldb_val *out) { struct GUID guid; - char *guid_string; NTSTATUS status; enum ndr_err_code ndr_err; - guid_string = talloc_strndup(mem_ctx, (const char *)in->data, in->length); - if (!guid_string) { - return -1; - } - status = GUID_from_string(guid_string, &guid); - talloc_free(guid_string); + status = GUID_from_data_blob(in, &guid); if (!NT_STATUS_IS_OK(status)) { return -1; } @@ -176,8 +200,8 @@ static int ldif_write_objectGUID(struct ldb_context *ldb, void *mem_ctx, { struct GUID guid; enum ndr_err_code ndr_err; - ndr_err = ndr_pull_struct_blob(in, mem_ctx, NULL, &guid, - (ndr_pull_flags_fn_t)ndr_pull_GUID); + ndr_err = ndr_pull_struct_blob_all(in, mem_ctx, NULL, &guid, + (ndr_pull_flags_fn_t)ndr_pull_GUID); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return -1; } @@ -191,20 +215,42 @@ static int ldif_write_objectGUID(struct ldb_context *ldb, void *mem_ctx, static bool ldb_comparision_objectGUID_isString(const struct ldb_val *v) { - struct GUID guid; - NTSTATUS status; - - if (v->length < 33) return false; + if (v->length != 36 && v->length != 38) return false; - /* see if the input if null-terninated (safety check for the below) */ - if (v->data[v->length] != '\0') return false; + /* Might be a GUID string, can't be a binary GUID (fixed 16 bytes) */ + return true; +} - status = GUID_from_string((const char *)v->data, &guid); - if (!NT_STATUS_IS_OK(status)) { - return false; +static int extended_dn_read_GUID(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + struct GUID guid; + enum ndr_err_code ndr_err; + if (in->length == 36 && ldif_read_objectGUID(ldb, mem_ctx, in, out) == 0) { + return 0; } - return true; + /* Try as 'hex' form */ + if (in->length != 32) { + return -1; + } + + *out = data_blob_talloc(mem_ctx, NULL, in->length/2+1); + + if (!out->data) { + return -1; + } + + (*out).length = strhex_to_str((char *)out->data, out->length, + (const char *)in->data, in->length); + + /* Check it looks like a GUID */ + ndr_err = ndr_pull_struct_blob_all(out, mem_ctx, NULL, &guid, + (ndr_pull_flags_fn_t)ndr_pull_GUID); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return -1; + } + return 0; } /* @@ -293,8 +339,9 @@ static int ldif_write_ntSecurityDescriptor(struct ldb_context *ldb, void *mem_ct if (sd == NULL) { return -1; } + /* We can't use ndr_pull_struct_blob_all because this contains relative pointers */ ndr_err = ndr_pull_struct_blob(in, sd, NULL, sd, - (ndr_pull_flags_fn_t)ndr_pull_security_descriptor); + (ndr_pull_flags_fn_t)ndr_pull_security_descriptor); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(sd); return -1; @@ -494,10 +541,10 @@ static int ldif_write_prefixMap(struct ldb_context *ldb, void *mem_ctx, if (blob == NULL) { return -1; } - ndr_err = ndr_pull_struct_blob(in, blob, - lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")), - blob, - (ndr_pull_flags_fn_t)ndr_pull_prefixMapBlob); + ndr_err = ndr_pull_struct_blob_all(in, blob, + lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")), + blob, + (ndr_pull_flags_fn_t)ndr_pull_prefixMapBlob); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(blob); return -1; @@ -578,41 +625,71 @@ static int ldif_comparison_prefixMap(struct ldb_context *ldb, void *mem_ctx, return ret; } +static int extended_dn_write_hex(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + *out = data_blob_string_const(data_blob_hex_string(mem_ctx, in)); + if (!out->data) { + return -1; + } + return 0; +} + + #define LDB_SYNTAX_SAMBA_GUID "LDB_SYNTAX_SAMBA_GUID" #define LDB_SYNTAX_SAMBA_OBJECT_CATEGORY "LDB_SYNTAX_SAMBA_OBJECT_CATEGORY" #define LDB_SYNTAX_SAMBA_PREFIX_MAP "LDB_SYNTAX_SAMBA_PREFIX_MAP" static const struct ldb_schema_syntax samba_syntaxes[] = { { - .name = LDB_SYNTAX_SAMBA_SID, - .ldif_read_fn = ldif_read_objectSid, - .ldif_write_fn = ldif_write_objectSid, - .canonicalise_fn= ldb_canonicalise_objectSid, - .comparison_fn = ldb_comparison_objectSid + .name = LDB_SYNTAX_SAMBA_SID, + .ldif_read_fn = ldif_read_objectSid, + .ldif_write_fn = ldif_write_objectSid, + .canonicalise_fn = ldb_canonicalise_objectSid, + .comparison_fn = ldb_comparison_objectSid + },{ + .name = LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR, + .ldif_read_fn = ldif_read_ntSecurityDescriptor, + .ldif_write_fn = ldif_write_ntSecurityDescriptor, + .canonicalise_fn = ldb_handler_copy, + .comparison_fn = ldb_comparison_binary + },{ + .name = LDB_SYNTAX_SAMBA_GUID, + .ldif_read_fn = ldif_read_objectGUID, + .ldif_write_fn = ldif_write_objectGUID, + .canonicalise_fn = ldb_canonicalise_objectGUID, + .comparison_fn = ldb_comparison_objectGUID },{ - .name = LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR, - .ldif_read_fn = ldif_read_ntSecurityDescriptor, - .ldif_write_fn = ldif_write_ntSecurityDescriptor, - .canonicalise_fn= ldb_handler_copy, - .comparison_fn = ldb_comparison_binary + .name = LDB_SYNTAX_SAMBA_OBJECT_CATEGORY, + .ldif_read_fn = ldb_handler_copy, + .ldif_write_fn = ldb_handler_copy, + .canonicalise_fn = ldif_canonicalise_objectCategory, + .comparison_fn = ldif_comparison_objectCategory },{ - .name = LDB_SYNTAX_SAMBA_GUID, - .ldif_read_fn = ldif_read_objectGUID, - .ldif_write_fn = ldif_write_objectGUID, - .canonicalise_fn= ldb_canonicalise_objectGUID, - .comparison_fn = ldb_comparison_objectGUID + .name = LDB_SYNTAX_SAMBA_PREFIX_MAP, + .ldif_read_fn = ldif_read_prefixMap, + .ldif_write_fn = ldif_write_prefixMap, + .canonicalise_fn = ldif_canonicalise_prefixMap, + .comparison_fn = ldif_comparison_prefixMap + } +}; + +static const struct ldb_dn_extended_syntax samba_dn_syntax[] = { + { + .name = "SID", + .read_fn = extended_dn_read_SID, + .write_clear_fn = ldif_write_objectSid, + .write_hex_fn = extended_dn_write_hex },{ - .name = LDB_SYNTAX_SAMBA_OBJECT_CATEGORY, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldb_handler_copy, - .canonicalise_fn= ldif_canonicalise_objectCategory, - .comparison_fn = ldif_comparison_objectCategory + .name = "GUID", + .read_fn = extended_dn_read_GUID, + .write_clear_fn = ldif_write_objectGUID, + .write_hex_fn = extended_dn_write_hex },{ - .name = LDB_SYNTAX_SAMBA_PREFIX_MAP, - .ldif_read_fn = ldif_read_prefixMap, - .ldif_write_fn = ldif_write_prefixMap, - .canonicalise_fn= ldif_canonicalise_prefixMap, - .comparison_fn = ldif_comparison_prefixMap + .name = "WKGUID", + .read_fn = ldb_handler_copy, + .write_clear_fn = ldb_handler_copy, + .write_hex_fn = ldb_handler_copy } }; @@ -679,5 +756,15 @@ int ldb_register_samba_handlers(struct ldb_context *ldb) } } + for (i=0; i < ARRAY_SIZE(samba_dn_syntax); i++) { + int ret; + ret = ldb_dn_extended_add_syntax(ldb, LDB_ATTR_FLAG_FIXED, &samba_dn_syntax[i]); + if (ret != LDB_SUCCESS) { + return ret; + } + + + } + return LDB_SUCCESS; } diff --git a/source4/lib/ldb/common/ldb_attributes.c b/source4/lib/ldb/common/ldb_attributes.c index 747f241781..48f9e11caf 100644 --- a/source4/lib/ldb/common/ldb_attributes.c +++ b/source4/lib/ldb/common/ldb_attributes.c @@ -225,3 +225,50 @@ int ldb_setup_wellknown_attributes(struct ldb_context *ldb) return LDB_SUCCESS; } + +/* + add a extended dn syntax to the ldb_schema +*/ +int ldb_dn_extended_add_syntax(struct ldb_context *ldb, + unsigned flags, + const struct ldb_dn_extended_syntax *syntax) +{ + int n; + struct ldb_dn_extended_syntax *a; + + if (!syntax) { + return LDB_ERR_OPERATIONS_ERROR; + } + + n = ldb->schema.num_dn_extended_syntax + 1; + + a = talloc_realloc(ldb, ldb->schema.dn_extended_syntax, + struct ldb_dn_extended_syntax, n); + + if (!a) { + return LDB_ERR_OPERATIONS_ERROR; + } + + a[ldb->schema.num_dn_extended_syntax] = *syntax; + ldb->schema.dn_extended_syntax = a; + + ldb->schema.num_dn_extended_syntax = n; + + return 0; +} + +/* + return the extended dn syntax for a given name +*/ +const struct ldb_dn_extended_syntax *ldb_dn_extended_syntax_by_name(struct ldb_context *ldb, + const char *name) +{ + int i; + for (i=0; i < ldb->schema.num_dn_extended_syntax; i++) { + if (ldb_attr_cmp(ldb->schema.dn_extended_syntax[i].name, name) == 0) { + return &ldb->schema.dn_extended_syntax[i]; + } + } + return NULL; +} + diff --git a/source4/lib/ldb/common/ldb_controls.c b/source4/lib/ldb/common/ldb_controls.c index e3f8551407..6fad5012b6 100644 --- a/source4/lib/ldb/common/ldb_controls.c +++ b/source4/lib/ldb/common/ldb_controls.c @@ -53,6 +53,26 @@ struct ldb_control *ldb_request_get_control(struct ldb_request *req, const char return NULL; } +/* check if a control with the specified "oid" exist and return it */ +/* returns NULL if not found */ +struct ldb_control *ldb_reply_get_control(struct ldb_reply *rep, const char *oid) +{ + int i; + + /* check if there's a paged request control */ + if (rep->controls != NULL) { + for (i = 0; rep->controls[i]; i++) { + if (strcmp(oid, rep->controls[i]->oid) == 0) { + break; + } + } + + return rep->controls[i]; + } + + return NULL; +} + /* saves the current controls list into the "saver" and replace the one in req with a new one excluding the "exclude" control */ /* returns False on error */ diff --git a/source4/lib/ldb/common/ldb_dn.c b/source4/lib/ldb/common/ldb_dn.c index e36aea4e69..13c01f4e70 100644 --- a/source4/lib/ldb/common/ldb_dn.c +++ b/source4/lib/ldb/common/ldb_dn.c @@ -52,6 +52,12 @@ struct ldb_dn_component { struct ldb_val cf_value; }; +struct ldb_dn_extended_component { + + char *name; + struct ldb_val value; +}; + struct ldb_dn { struct ldb_context *ldb; @@ -63,11 +69,14 @@ struct ldb_dn { bool valid_case; char *linearized; + char *extended_linearized; char *casefold; unsigned int comp_num; struct ldb_dn_component *components; + unsigned int extended_comp_num; + struct ldb_dn_extended_component *extended_components; }; /* strdn may be NULL */ @@ -85,28 +94,34 @@ struct ldb_dn *ldb_dn_from_ldb_val(void *mem_ctx, struct ldb_context *ldb, const if (strdn->data && strdn->length) { if (strdn->data[0] == '@') { dn->special = true; + } + dn->extended_linearized = talloc_strndup(dn, (const char *)strdn->data, strdn->length); + LDB_DN_NULL_FAILED(dn->extended_linearized); + + if (strdn->data[0] == '<') { + const char *p_save, *p = dn->extended_linearized; + do { + p_save = p; + p = strstr(p, ">;"); + if (p) { + p = p + 2; + } + } while (p); + + if (p_save == dn->extended_linearized) { + dn->linearized = talloc_strdup(dn, ""); + } else { + dn->linearized = talloc_strdup(dn, p_save); + } + LDB_DN_NULL_FAILED(dn->linearized); + } else { + dn->linearized = dn->extended_linearized; + dn->extended_linearized = NULL; } - if (strdn->length >= 6 && strncasecmp((const char *)strdn->data, "<GUID=", 6) == 0) { - /* this is special DN returned when the - * exploded_dn control is used */ - dn->special = true; - /* FIXME: add a GUID string to ldb_dn structure */ - } else if (strdn->length >= 5 && strncasecmp((const char *)strdn->data, "<SID=", 5) == 0) { - /* this is special DN returned when the - * exploded_dn control is used */ - dn->special = true; - /* FIXME: add a SID string to ldb_dn structure */ - } else if (strdn->length >= 8 && strncasecmp((const char *)strdn->data, "<WKGUID=", 8) == 0) { - /* this is special DN returned when the - * exploded_dn control is used */ - dn->special = true; - /* FIXME: add a WKGUID string to ldb_dn structure */ - } - dn->linearized = talloc_strndup(dn, (const char *)strdn->data, strdn->length); } else { dn->linearized = talloc_strdup(dn, ""); + LDB_DN_NULL_FAILED(dn->linearized); } - LDB_DN_NULL_FAILED(dn->linearized); return dn; @@ -126,47 +141,21 @@ struct ldb_dn *ldb_dn_new(void *mem_ctx, struct ldb_context *ldb, const char *st struct ldb_dn *ldb_dn_new_fmt(void *mem_ctx, struct ldb_context *ldb, const char *new_fmt, ...) { - struct ldb_dn *dn; char *strdn; va_list ap; if ( (! mem_ctx) || (! ldb)) return NULL; - dn = talloc_zero(mem_ctx, struct ldb_dn); - LDB_DN_NULL_FAILED(dn); - - dn->ldb = ldb; - va_start(ap, new_fmt); - strdn = talloc_vasprintf(dn, new_fmt, ap); + strdn = talloc_vasprintf(mem_ctx, new_fmt, ap); va_end(ap); - LDB_DN_NULL_FAILED(strdn); - - if (strdn[0] == '@') { - dn->special = true; - } - if (strncasecmp(strdn, "<GUID=", 6) == 0) { - /* this is special DN returned when the - * exploded_dn control is used */ - dn->special = true; - /* FIXME: add a GUID string to ldb_dn structure */ - } else if (strncasecmp(strdn, "<SID=", 5) == 0) { - /* this is special DN returned when the - * exploded_dn control is used */ - dn->special = true; - /* FIXME: add a SID string to ldb_dn structure */ - } else if (strncasecmp(strdn, "<WKGUID=", 8) == 0) { - /* this is special DN returned when the - * exploded_dn control is used */ - dn->special = true; - /* FIXME: add a WKGUID string to ldb_dn structure */ - } - dn->linearized = strdn; - return dn; - -failed: - talloc_free(dn); + if (strdn) { + struct ldb_dn *dn = ldb_dn_new(mem_ctx, ldb, strdn); + talloc_free(strdn); + return dn; + } + return NULL; } @@ -235,15 +224,19 @@ char *ldb_dn_escape_value(void *mem_ctx, struct ldb_val value) */ static bool ldb_dn_explode(struct ldb_dn *dn) { - char *p, *data, *d, *dt, *t; + char *p, *ex_name, *ex_value, *data, *d, *dt, *t; bool trim = false; + bool in_extended = false; + bool in_ex_name = false; + bool in_ex_value = false; bool in_attr = false; bool in_value = false; bool in_quote = false; bool is_oid = false; bool escape = false; unsigned x; - int l; + int l, ret; + char *parse_dn; if ( ! dn || dn->invalid) return false; @@ -251,12 +244,18 @@ static bool ldb_dn_explode(struct ldb_dn *dn) return true; } - if ( ! dn->linearized) { + if (dn->extended_linearized) { + parse_dn = dn->extended_linearized; + } else { + parse_dn = dn->linearized; + } + + if ( ! parse_dn ) { return false; } /* Empty DNs */ - if (dn->linearized[0] == '\0') { + if (parse_dn[0] == '\0') { return true; } @@ -268,6 +267,9 @@ static bool ldb_dn_explode(struct ldb_dn *dn) /* make sure we free this if alloced previously before replacing */ talloc_free(dn->components); + talloc_free(dn->extended_components); + dn->extended_components = NULL; + /* in the common case we have 3 or more components */ /* make sure all components are zeroed, other functions depend on this */ dn->components = talloc_zero_array(dn, struct ldb_dn_component, 3); @@ -277,19 +279,109 @@ static bool ldb_dn_explode(struct ldb_dn *dn) dn->comp_num = 0; /* Components data space is allocated here once */ - data = talloc_array(dn->components, char, strlen(dn->linearized) + 1); + data = talloc_array(dn->components, char, strlen(parse_dn) + 1); if (!data) { return false; } - p = dn->linearized; - in_attr = true; + p = parse_dn; + in_extended = true; + in_ex_name = false; + in_ex_value = false; trim = true; t = NULL; d = dt = data; while (*p) { + if (in_extended) { + + if (!in_ex_name && !in_ex_value) { + + if (p[0] == '<') { + p++; + ex_name = d; + in_ex_name = true; + continue; + } else if (p[0] == '\0') { + p++; + continue; + } else { + in_extended = false; + in_attr = true; + dt = d; + + continue; + } + } + + if (in_ex_name && *p == '=') { + *d++ = '\0'; + p++; + ex_value = d; + in_ex_name = false; + in_ex_value = true; + continue; + } + + if (in_ex_value && *p == '>') { + const struct ldb_dn_extended_syntax *extended_syntax; + struct ldb_val ex_val = { + .data = ex_value, + .length = d - ex_value + }; + + *d++ = '\0'; + p++; + in_ex_value = false; + + /* Process name and ex_value */ + + dn->extended_components = talloc_realloc(dn, + dn->extended_components, + struct ldb_dn_extended_component, + dn->extended_comp_num + 1); + if ( ! dn->extended_components) { + /* ouch ! */ + goto failed; + } + + extended_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, ex_name); + if (!extended_syntax) { + /* We don't know about this type of extended DN */ + goto failed; + } + + dn->extended_components[dn->extended_comp_num].name = talloc_strdup(dn->extended_components, ex_name); + if (!dn->extended_components[dn->extended_comp_num].name) { + /* ouch */ + goto failed; + } + ret = extended_syntax->read_fn(dn->ldb, dn->extended_components, + &ex_val, &dn->extended_components[dn->extended_comp_num].value); + if (ret != LDB_SUCCESS) { + dn->invalid = true; + goto failed; + } + + dn->extended_comp_num++; + if (*p == '\0') { + /* We have reached the end (extended component only)! */ + talloc_free(data); + return true; + + } else if (*p == ';') { + p++; + continue; + } else { + dn->invalid = true; + goto failed; + } + } + + *d++ = *p++; + continue; + } if (in_attr) { if (trim) { if (*p == ' ') { @@ -315,6 +407,7 @@ static bool ldb_dn_explode(struct ldb_dn *dn) goto failed; } + /* Copy this character across from parse_dn, now we have trimmed out spaces */ *d++ = *p++; continue; } @@ -339,6 +432,7 @@ static bool ldb_dn_explode(struct ldb_dn *dn) trim = true; l = 0; + /* Terminate this string in d (which is a copy of parse_dn with spaces trimmed) */ *d++ = '\0'; dn->components[dn->comp_num].name = talloc_strdup(dn->components, dt); if ( ! dn->components[dn->comp_num].name) { @@ -614,6 +708,74 @@ const char *ldb_dn_get_linearized(struct ldb_dn *dn) return dn->linearized; } +char *ldb_dn_get_extended_linearized(void *mem_ctx, struct ldb_dn *dn, int mode) +{ + const char *linearized = ldb_dn_get_linearized(dn); + char *p; + int i; + + if (!linearized) { + return NULL; + } + + if (!ldb_dn_has_extended(dn)) { + return talloc_strdup(mem_ctx, linearized); + } + + if (!ldb_dn_validate(dn)) { + return NULL; + } + + for (i=0; i < dn->extended_comp_num; i++) { + struct ldb_val val; + int ret; + const struct ldb_dn_extended_syntax *extended_syntax; + const char *name = dn->extended_components[i].name; + + extended_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name); + + if (mode == 1) { + ret = extended_syntax->write_clear_fn(dn->ldb, mem_ctx, + &dn->extended_components[i].value, + &val); + } else if (mode == 0) { + ret = extended_syntax->write_hex_fn(dn->ldb, mem_ctx, + &dn->extended_components[i].value, + &val); + } else { + ret = -1; + } + + if (ret != LDB_SUCCESS) { + return NULL; + } + + if (i == 0) { + p = talloc_asprintf(mem_ctx, "<%s=%s>", dn->extended_components[i].name, val.data); + } else { + p = talloc_asprintf_append(p, ";<%s=%s>", dn->extended_components[i].name, val.data); + } + + talloc_free(val.data); + + if (!p) { + return NULL; + } + } + + if (dn->extended_comp_num && *linearized) { + p = talloc_asprintf_append(p, ";%s", linearized); + } + + if (!p) { + return NULL; + } + + return p; +} + + + char *ldb_dn_alloc_linearized(void *mem_ctx, struct ldb_dn *dn) { return talloc_strdup(mem_ctx, ldb_dn_get_linearized(dn)); @@ -909,6 +1071,30 @@ static struct ldb_dn_component ldb_dn_copy_component(void *mem_ctx, struct ldb_d return dst; } +static struct ldb_dn_extended_component ldb_dn_extended_copy_component(void *mem_ctx, struct ldb_dn_extended_component *src) +{ + struct ldb_dn_extended_component dst; + + memset(&dst, 0, sizeof(dst)); + + if (src == NULL) { + return dst; + } + + dst.value = ldb_val_dup(mem_ctx, &(src->value)); + if (dst.value.data == NULL) { + return dst; + } + + dst.name = talloc_strdup(mem_ctx, src->name); + if (dst.name == NULL) { + LDB_FREE(dst.value.data); + return dst; + } + + return dst; +} + struct ldb_dn *ldb_dn_copy(void *mem_ctx, struct ldb_dn *dn) { struct ldb_dn *new_dn; @@ -942,6 +1128,24 @@ struct ldb_dn *ldb_dn_copy(void *mem_ctx, struct ldb_dn *dn) } } + if (dn->extended_components) { + int i; + + new_dn->extended_components = talloc_zero_array(new_dn, struct ldb_dn_extended_component, dn->extended_comp_num); + if ( ! new_dn->extended_components) { + talloc_free(new_dn); + return NULL; + } + + for (i = 0; i < dn->extended_comp_num; i++) { + new_dn->extended_components[i] = ldb_dn_extended_copy_component(new_dn->extended_components, &dn->extended_components[i]); + if ( ! new_dn->extended_components[i].value.data) { + talloc_free(new_dn); + return NULL; + } + } + } + if (dn->casefold) { new_dn->casefold = talloc_strdup(new_dn, dn->casefold); if ( ! new_dn->casefold) { @@ -958,6 +1162,14 @@ struct ldb_dn *ldb_dn_copy(void *mem_ctx, struct ldb_dn *dn) } } + if (dn->extended_linearized) { + new_dn->extended_linearized = talloc_strdup(new_dn, dn->extended_linearized); + if ( ! new_dn->extended_linearized) { + talloc_free(new_dn); + return NULL; + } + } + return new_dn; } @@ -1037,6 +1249,13 @@ bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base) dn->linearized = t; } + /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */ + if (dn->extended_linearized) { + LDB_FREE(dn->extended_linearized); + } + + LDB_FREE(dn->extended_components); + dn->extended_comp_num = 0; return true; } @@ -1149,6 +1368,12 @@ bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child) dn->linearized = t; } + /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */ + LDB_FREE(dn->extended_linearized); + + LDB_FREE(dn->extended_components); + dn->extended_comp_num = 0; + return true; } @@ -1218,6 +1443,12 @@ bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num) LDB_FREE(dn->casefold); LDB_FREE(dn->linearized); + /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */ + LDB_FREE(dn->extended_linearized); + + LDB_FREE(dn->extended_components); + dn->extended_comp_num = 0; + return true; } @@ -1256,6 +1487,11 @@ bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num) LDB_FREE(dn->casefold); LDB_FREE(dn->linearized); + /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */ + LDB_FREE(dn->extended_linearized); + + LDB_FREE(dn->extended_components); + dn->extended_comp_num = 0; return true; } @@ -1273,6 +1509,11 @@ struct ldb_dn *ldb_dn_get_parent(void *mem_ctx, struct ldb_dn *dn) return NULL; } + /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */ + LDB_FREE(dn->extended_linearized); + + LDB_FREE(dn->extended_components); + dn->extended_comp_num = 0; return new_dn; } @@ -1434,9 +1675,97 @@ int ldb_dn_set_component(struct ldb_dn *dn, int num, const char *name, const str LDB_FREE(dn->casefold); LDB_FREE(dn->linearized); + /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */ + LDB_FREE(dn->extended_linearized); + + dn->extended_comp_num = 0; + LDB_FREE(dn->extended_components); return LDB_SUCCESS; } +const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn, const char *name) +{ + int i; + if ( ! ldb_dn_validate(dn)) { + return NULL; + } + for (i=0; i < dn->extended_comp_num; i++) { + if (ldb_attr_cmp(dn->extended_components[i].name, name) == 0) { + return &dn->extended_components[i].value; + } + } + return NULL; +} + +int ldb_dn_set_extended_component(struct ldb_dn *dn, const char *name, const struct ldb_val *val) +{ + struct ldb_dn_extended_component *p; + int i; + + if ( ! ldb_dn_validate(dn)) { + return LDB_ERR_OTHER; + } + + for (i=0; i < dn->extended_comp_num; i++) { + if (ldb_attr_cmp(dn->extended_components[i].name, name) == 0) { + if (val) { + dn->extended_components[i].value = ldb_val_dup(dn->extended_components, val); + + dn->extended_components[i].name = talloc_strdup(dn->extended_components, name); + if (!dn->extended_components[i].name || !dn->extended_components[i].value.data) { + dn->invalid = true; + return LDB_ERR_OPERATIONS_ERROR; + } + + } else { + if (i != (dn->extended_comp_num - 1)) { + memmove(&dn->extended_components[i], &dn->extended_components[i+1], + ((dn->extended_comp_num-1) - i)*sizeof(*dn->extended_components)); + } + dn->extended_comp_num--; + + dn->extended_components = talloc_realloc(dn, + dn->extended_components, + struct ldb_dn_extended_component, + dn->extended_comp_num); + if (!dn->extended_components) { + dn->invalid = true; + return LDB_ERR_OPERATIONS_ERROR; + } + return 0; + } + } + } + + p = dn->extended_components + = talloc_realloc(dn, + dn->extended_components, + struct ldb_dn_extended_component, + dn->extended_comp_num + 1); + if (!dn->extended_components) { + dn->invalid = true; + return LDB_ERR_OPERATIONS_ERROR; + } + + p[dn->extended_comp_num].value = ldb_val_dup(dn->extended_components, val); + p[dn->extended_comp_num].name = talloc_strdup(p, name); + + if (!dn->extended_components[i].name || !dn->extended_components[i].value.data) { + dn->invalid = true; + return LDB_ERR_OPERATIONS_ERROR; + } + dn->extended_components = p; + dn->extended_comp_num++; + + return 0; +} + +void ldb_dn_remove_extended_components(struct ldb_dn *dn) +{ + dn->extended_comp_num = 0; + LDB_FREE(dn->extended_components); +} + bool ldb_dn_is_valid(struct ldb_dn *dn) { if ( ! dn) return false; @@ -1449,6 +1778,13 @@ bool ldb_dn_is_special(struct ldb_dn *dn) return dn->special; } +bool ldb_dn_has_extended(struct ldb_dn *dn) +{ + if ( ! dn || dn->invalid) return false; + if (dn->extended_linearized && (dn->extended_linearized[0] == '<')) return true; + return dn->extended_comp_num != 0; +} + bool ldb_dn_check_special(struct ldb_dn *dn, const char *check) { if ( ! dn || dn->invalid) return false; @@ -1458,6 +1794,7 @@ bool ldb_dn_check_special(struct ldb_dn *dn, const char *check) bool ldb_dn_is_null(struct ldb_dn *dn) { if ( ! dn || dn->invalid) return false; + if (ldb_dn_has_extended(dn)) return false; if (dn->linearized && (dn->linearized[0] == '\0')) return true; return false; } diff --git a/source4/lib/ldb/common/ldb_ldif.c b/source4/lib/ldb/common/ldb_ldif.c index 69490e670b..619c10e11e 100644 --- a/source4/lib/ldb/common/ldb_ldif.c +++ b/source4/lib/ldb/common/ldb_ldif.c @@ -278,13 +278,15 @@ int ldb_ldif_write(struct ldb_context *ldb, TALLOC_CTX *mem_ctx; unsigned int i, j; int total=0, ret; + char *p; const struct ldb_message *msg; mem_ctx = talloc_named_const(NULL, 0, "ldb_ldif_write"); msg = ldif->msg; - - ret = fprintf_fn(private_data, "dn: %s\n", ldb_dn_get_linearized(msg->dn)); + p = ldb_dn_get_extended_linearized(mem_ctx, msg->dn, 1); + ret = fprintf_fn(private_data, "dn: %s\n", p); + talloc_free(p); CHECK_RET; if (ldif->changetype != LDB_CHANGETYPE_NONE) { diff --git a/source4/lib/ldb/common/ldb_modules.c b/source4/lib/ldb/common/ldb_modules.c index ab0f4c51cc..8db28d262c 100644 --- a/source4/lib/ldb/common/ldb_modules.c +++ b/source4/lib/ldb/common/ldb_modules.c @@ -587,10 +587,13 @@ struct ldb_handle *ldb_handle_new(TALLOC_CTX *mem_ctx, struct ldb_context *ldb) * req: the original request passed to your module * msg: reply message (must be a talloc pointer, and it will be stolen * on the ldb_reply that is sent to the callback) + * ctrls: controls to send in the reply (must be a talloc pointer, and it will be stolen + * on the ldb_reply that is sent to the callback) */ int ldb_module_send_entry(struct ldb_request *req, - struct ldb_message *msg) + struct ldb_message *msg, + struct ldb_control **ctrls) { struct ldb_reply *ares; @@ -602,6 +605,7 @@ int ldb_module_send_entry(struct ldb_request *req, } ares->type = LDB_REPLY_ENTRY; ares->message = talloc_steal(ares, msg); + ares->controls = talloc_steal(ares, ctrls); ares->error = LDB_SUCCESS; return req->callback(req, ares); diff --git a/source4/lib/ldb/include/ldb.h b/source4/lib/ldb/include/ldb.h index 9bc5c183d8..e2ec869872 100644 --- a/source4/lib/ldb/include/ldb.h +++ b/source4/lib/ldb/include/ldb.h @@ -326,7 +326,6 @@ typedef int (*ldb_attr_comparison_t)(struct ldb_context *, TALLOC_CTX *mem_ctx, attribute handler structure attr -> The attribute name - flags -> LDB_ATTR_FLAG_* ldif_read_fn -> convert from ldif to binary format ldif_write_fn -> convert from binary to ldif format canonicalise_fn -> canonicalise a value, for use by indexing and dn construction @@ -350,6 +349,16 @@ struct ldb_schema_attribute { const struct ldb_schema_attribute *ldb_schema_attribute_by_name(struct ldb_context *ldb, const char *name); +struct ldb_dn_extended_syntax { + const char *name; + ldb_attr_handler_t read_fn; + ldb_attr_handler_t write_clear_fn; + ldb_attr_handler_t write_hex_fn; +}; + +const struct ldb_dn_extended_syntax *ldb_dn_extended_syntax_by_name(struct ldb_context *ldb, + const char *name); + /** The attribute is not returned by default */ @@ -1066,6 +1075,15 @@ int ldb_request_add_control(struct ldb_request *req, const char *oid, bool criti struct ldb_control *ldb_request_get_control(struct ldb_request *req, const char *oid); /** + check if a control with the specified "oid" exist and return it + \param rep the reply struct where to add the control + \param oid the object identifier of the control as string + + \return the control, NULL if not found +*/ +struct ldb_control *ldb_reply_get_control(struct ldb_reply *rep, const char *oid); + +/** Search the database This function searches the database, and returns @@ -1421,15 +1439,82 @@ int ldb_base64_decode(char *s); /* The following definitions come from lib/ldb/common/ldb_dn.c */ +/** + Get the linear form of a DN (without any extended components) + + \param dn The DN to linearize +*/ + +const char *ldb_dn_get_linearized(struct ldb_dn *dn); + +/** + Allocate a copy of the linear form of a DN (without any extended components) onto the supplied memory context + + \param dn The DN to linearize + \param mem_ctx TALLOC context to return result on +*/ + +char *ldb_dn_alloc_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn); + +/** + Get the linear form of a DN (with any extended components) + + \param mem_ctx TALLOC context to return result on + \param dn The DN to linearize + \param mode Style of extended DN to return (0 is HEX representation of binary form, 1 is a string form) +*/ +char *ldb_dn_get_extended_linearized(void *mem_ctx, struct ldb_dn *dn, int mode); +const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn, const char *name); +int ldb_dn_set_extended_component(struct ldb_dn *dn, const char *name, const struct ldb_val *val); + +void ldb_dn_remove_extended_components(struct ldb_dn *dn); +bool ldb_dn_has_extended(struct ldb_dn *dn); + +int ldb_dn_extended_add_syntax(struct ldb_context *ldb, + unsigned flags, + const struct ldb_dn_extended_syntax *syntax); + +/** + Allocate a new DN from a string + + \param mem_ctx TALLOC context to return resulting ldb_dn structure on + \param dn The new DN + + \note The DN will not be parsed at this time. Use ldb_dn_validate to tell if the DN is syntacticly correct +*/ + struct ldb_dn *ldb_dn_new(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, const char *dn); +/** + Allocate a new DN from a printf style format string and arguments + + \param mem_ctx TALLOC context to return resulting ldb_dn structure on + \param new_fms The new DN as a format string (plus arguments) + + \note The DN will not be parsed at this time. Use ldb_dn_validate to tell if the DN is syntacticly correct +*/ + struct ldb_dn *ldb_dn_new_fmt(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, const char *new_fmt, ...) PRINTF_ATTRIBUTE(3,4); +/** + Allocate a new DN from a struct ldb_val (useful to avoid buffer overrun) + + \param mem_ctx TALLOC context to return resulting ldb_dn structure on + \param dn The new DN + + \note The DN will not be parsed at this time. Use ldb_dn_validate to tell if the DN is syntacticly correct +*/ + struct ldb_dn *ldb_dn_from_ldb_val(void *mem_ctx, struct ldb_context *ldb, const struct ldb_val *strdn); + +/** + Determine if this DN is syntactically valid + + \param dn The DN to validate +*/ + bool ldb_dn_validate(struct ldb_dn *dn); char *ldb_dn_escape_value(TALLOC_CTX *mem_ctx, struct ldb_val value); -const char *ldb_dn_get_linearized(struct ldb_dn *dn); const char *ldb_dn_get_casefold(struct ldb_dn *dn); -char *ldb_dn_alloc_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn); char *ldb_dn_alloc_casefold(TALLOC_CTX *mem_ctx, struct ldb_dn *dn); int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn); diff --git a/source4/lib/ldb/include/ldb_private.h b/source4/lib/ldb/include/ldb_private.h index 90c4980017..c065288279 100644 --- a/source4/lib/ldb/include/ldb_private.h +++ b/source4/lib/ldb/include/ldb_private.h @@ -84,6 +84,9 @@ struct ldb_schema { /* attribute handling table */ unsigned num_attributes; struct ldb_schema_attribute *attributes; + + unsigned num_dn_extended_syntax; + struct ldb_dn_extended_syntax *dn_extended_syntax; }; /* @@ -262,7 +265,8 @@ int ldb_register_backend(const char *url_prefix, ldb_connect_fn); struct ldb_handle *ldb_handle_new(TALLOC_CTX *mem_ctx, struct ldb_context *ldb); int ldb_module_send_entry(struct ldb_request *req, - struct ldb_message *msg); + struct ldb_message *msg, + struct ldb_control **ctrls); int ldb_module_send_referral(struct ldb_request *req, char *ref); diff --git a/source4/lib/ldb/ldb.i b/source4/lib/ldb/ldb.i index 0f05c1fbab..7831d6da60 100644 --- a/source4/lib/ldb/ldb.i +++ b/source4/lib/ldb/ldb.i @@ -575,6 +575,8 @@ static void py_ldb_debug(void *context, enum ldb_debug_level level, const char * if (ldif == NULL) { return Py_None; } else { + /* We don't want this attached to the 'ldb' any more */ + talloc_steal(NULL, ldif); return Py_BuildValue((char *)"(iO)", ldif->changetype, SWIG_NewPointerObj(ldif->msg, SWIGTYPE_p_ldb_message, 0)); } diff --git a/source4/lib/ldb/ldb_ildap/ldb_ildap.c b/source4/lib/ldb/ldb_ildap/ldb_ildap.c index 93e81d4244..b17d063c0c 100644 --- a/source4/lib/ldb/ldb_ildap/ldb_ildap.c +++ b/source4/lib/ldb/ldb_ildap/ldb_ildap.c @@ -311,7 +311,9 @@ static void ildb_callback(struct ldap_request *req) ldbmsg->num_elements = search->num_attributes; ldbmsg->elements = talloc_move(ldbmsg, &search->attributes); - ret = ldb_module_send_entry(ac->req, ldbmsg); + controls = talloc_steal(ac, msg->controls); + + ret = ldb_module_send_entry(ac->req, ldbmsg, controls); if (ret != LDB_SUCCESS) { callback_failed = true; } @@ -428,7 +430,7 @@ static int ildb_search(struct ildb_context *ac) if (req->op.search.base == NULL) { msg->r.SearchRequest.basedn = talloc_strdup(msg, ""); } else { - msg->r.SearchRequest.basedn = ldb_dn_alloc_linearized(msg, req->op.search.base); + msg->r.SearchRequest.basedn = ldb_dn_get_extended_linearized(msg, req->op.search.base, 0); } if (msg->r.SearchRequest.basedn == NULL) { ldb_set_errstring(ac->module->ldb, "Unable to determine baseDN"); @@ -473,7 +475,7 @@ static int ildb_add(struct ildb_context *ac) msg->type = LDAP_TAG_AddRequest; - msg->r.AddRequest.dn = ldb_dn_alloc_linearized(msg, req->op.add.message->dn); + msg->r.AddRequest.dn = ldb_dn_get_extended_linearized(msg, req->op.add.message->dn, 0); if (msg->r.AddRequest.dn == NULL) { talloc_free(msg); return LDB_ERR_INVALID_DN_SYNTAX; @@ -516,7 +518,7 @@ static int ildb_modify(struct ildb_context *ac) msg->type = LDAP_TAG_ModifyRequest; - msg->r.ModifyRequest.dn = ldb_dn_alloc_linearized(msg, req->op.mod.message->dn); + msg->r.ModifyRequest.dn = ldb_dn_get_extended_linearized(msg, req->op.mod.message->dn, 0); if (msg->r.ModifyRequest.dn == NULL) { talloc_free(msg); return LDB_ERR_INVALID_DN_SYNTAX; @@ -557,7 +559,7 @@ static int ildb_delete(struct ildb_context *ac) msg->type = LDAP_TAG_DelRequest; - msg->r.DelRequest.dn = ldb_dn_alloc_linearized(msg, req->op.del.dn); + msg->r.DelRequest.dn = ldb_dn_get_extended_linearized(msg, req->op.del.dn, 0); if (msg->r.DelRequest.dn == NULL) { talloc_free(msg); return LDB_ERR_INVALID_DN_SYNTAX; @@ -580,7 +582,7 @@ static int ildb_rename(struct ildb_context *ac) } msg->type = LDAP_TAG_ModifyDNRequest; - msg->r.ModifyDNRequest.dn = ldb_dn_alloc_linearized(msg, req->op.rename.olddn); + msg->r.ModifyDNRequest.dn = ldb_dn_get_extended_linearized(msg, req->op.rename.olddn, 0); if (msg->r.ModifyDNRequest.dn == NULL) { talloc_free(msg); return LDB_ERR_INVALID_DN_SYNTAX; diff --git a/source4/lib/ldb/ldb_ldap/ldb_ldap.c b/source4/lib/ldb/ldb_ldap/ldb_ldap.c index 7caee10b47..9f8b3e9f35 100644 --- a/source4/lib/ldb/ldb_ldap/ldb_ldap.c +++ b/source4/lib/ldb/ldb_ldap/ldb_ldap.c @@ -515,7 +515,7 @@ static bool lldb_parse_result(struct lldb_context *ac, LDAPMessage *result) } if (berptr) ber_free(berptr, 0); - ret = ldb_module_send_entry(ac->req, ldbmsg); + ret = ldb_module_send_entry(ac->req, ldbmsg, NULL /* controls not yet supported */); if (ret != LDB_SUCCESS) { callback_failed = true; diff --git a/source4/lib/ldb/ldb_map/ldb_map_outbound.c b/source4/lib/ldb/ldb_map/ldb_map_outbound.c index 5f524a8be3..5588eaaf46 100644 --- a/source4/lib/ldb/ldb_map/ldb_map_outbound.c +++ b/source4/lib/ldb/ldb_map/ldb_map_outbound.c @@ -1077,7 +1077,7 @@ int map_return_entry(struct map_context *ac, struct ldb_reply *ares) } } - return ldb_module_send_entry(ac->req, ares->message); + return ldb_module_send_entry(ac->req, ares->message, ares->controls); } /* Search a record. */ diff --git a/source4/lib/ldb/ldb_tdb/ldb_index.c b/source4/lib/ldb/ldb_tdb/ldb_index.c index eedbda4170..0a10307e65 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_index.c +++ b/source4/lib/ldb/ldb_tdb/ldb_index.c @@ -36,6 +36,328 @@ #include "ldb_tdb.h" /* + the idxptr code is a bit unusual. The way it works is to replace + @IDX elements in records during a transaction with @IDXPTR + elements. The @IDXPTR elements don't contain the actual index entry + values, but contain a pointer to a linked list of values. + + This means we are storing pointers in a database, which is normally + not allowed, but in this case we are storing them only for the + duration of a transaction, and re-writing them into the normal @IDX + format at the end of the transaction. That means no other processes + are ever exposed to the @IDXPTR values. + + The advantage is that the linked list doesn't cause huge + fragmentation during a transaction. Without the @IDXPTR method we + often ended up with a ldb that was between 10x and 100x larger then + it needs to be due to massive fragmentation caused by re-writing + @INDEX records many times during indexing. + */ +struct ldb_index_pointer { + struct ldb_index_pointer *next, *prev; + struct ldb_val value; +}; + +struct ltdb_idxptr { + int num_dns; + const char **dn_list; + bool repack; +}; + +/* + add to the list of DNs that need to be fixed on transaction end + */ +static int ltdb_idxptr_add(struct ldb_module *module, const struct ldb_message *msg) +{ + struct ltdb_private *ltdb = + talloc_get_type(module->private_data, struct ltdb_private); + ltdb->idxptr->dn_list = talloc_realloc(ltdb->idxptr, ltdb->idxptr->dn_list, + const char *, ltdb->idxptr->num_dns+1); + if (ltdb->idxptr->dn_list == NULL) { + ltdb->idxptr->num_dns = 0; + return LDB_ERR_OPERATIONS_ERROR; + } + ltdb->idxptr->dn_list[ltdb->idxptr->num_dns] = + talloc_strdup(ltdb->idxptr->dn_list, ldb_dn_get_linearized(msg->dn)); + if (ltdb->idxptr->dn_list[ltdb->idxptr->num_dns] == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + ltdb->idxptr->num_dns++; + return LDB_SUCCESS; +} + +/* free an idxptr record */ +static int ltdb_free_idxptr(struct ldb_module *module, struct ldb_message_element *el) +{ + struct ldb_val val; + struct ldb_index_pointer *ptr; + + if (el->num_values != 1) { + return LDB_ERR_OPERATIONS_ERROR; + } + + val = el->values[0]; + if (val.length != sizeof(void *)) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ptr = *(struct ldb_index_pointer **)val.data; + if (talloc_get_type(ptr, struct ldb_index_pointer) != ptr) { + return LDB_ERR_OPERATIONS_ERROR; + } + + while (ptr) { + struct ldb_index_pointer *tmp = ptr; + DLIST_REMOVE(ptr, ptr); + talloc_free(tmp); + } + + return 0; +} + + +/* convert from the IDXPTR format to a ldb_message_element format */ +static int ltdb_convert_from_idxptr(struct ldb_module *module, struct ldb_message_element *el) +{ + struct ldb_val val; + struct ldb_index_pointer *ptr, *tmp; + int i; + struct ldb_val *val2; + + if (el->num_values != 1) { + return LDB_ERR_OPERATIONS_ERROR; + } + + val = el->values[0]; + if (val.length != sizeof(void *)) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ptr = *(struct ldb_index_pointer **)val.data; + if (talloc_get_type(ptr, struct ldb_index_pointer) != ptr) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* count the length of the list */ + for (i=0, tmp = ptr; tmp; tmp=tmp->next) { + i++; + } + + /* allocate the new values array */ + val2 = talloc_realloc(NULL, el->values, struct ldb_val, i); + if (val2 == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + el->values = val2; + el->num_values = i; + + /* populate the values array */ + for (i=0, tmp = ptr; tmp; tmp=tmp->next, i++) { + el->values[i].length = tmp->value.length; + /* we need to over-allocate here as there are still some places + in ldb that rely on null termination. */ + el->values[i].data = talloc_size(el->values, tmp->value.length+1); + if (el->values[i].data == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + memcpy(el->values[i].data, tmp->value.data, tmp->value.length); + el->values[i].data[tmp->value.length] = 0; + } + + /* update the name */ + el->name = LTDB_IDX; + + return LDB_SUCCESS; +} + + +/* convert to the IDXPTR format from a ldb_message_element format */ +static int ltdb_convert_to_idxptr(struct ldb_module *module, struct ldb_message_element *el) +{ + struct ldb_index_pointer *ptr, *tmp; + int i; + struct ldb_val *val2; + struct ltdb_private *ltdb = + talloc_get_type(module->private_data, struct ltdb_private); + + ptr = NULL; + + for (i=0;i<el->num_values;i++) { + tmp = talloc(ltdb->idxptr, struct ldb_index_pointer); + if (tmp == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + tmp->value = el->values[i]; + tmp->value.data = talloc_memdup(tmp, tmp->value.data, tmp->value.length); + if (tmp->value.data == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + DLIST_ADD(ptr, tmp); + } + + /* allocate the new values array */ + val2 = talloc_realloc(NULL, el->values, struct ldb_val, 1); + if (val2 == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + el->values = val2; + el->num_values = 1; + + el->values[0].data = talloc_memdup(el->values, &ptr, sizeof(ptr)); + el->values[0].length = sizeof(ptr); + + /* update the name */ + el->name = LTDB_IDXPTR; + + return LDB_SUCCESS; +} + + +/* enable the idxptr mode when transactions start */ +int ltdb_index_transaction_start(struct ldb_module *module) +{ + struct ltdb_private *ltdb = + talloc_get_type(module->private_data, struct ltdb_private); + ltdb->idxptr = talloc_zero(module, struct ltdb_idxptr); + return 0; +} + +/* + a wrapper around ltdb_search_dn1() which translates pointer based index records + and maps them into normal ldb message structures + */ +static int ltdb_search_dn1_index(struct ldb_module *module, + struct ldb_dn *dn, struct ldb_message *msg) +{ + int ret, i; + ret = ltdb_search_dn1(module, dn, msg); + if (ret != LDB_SUCCESS) { + return ret; + } + + /* if this isn't a @INDEX record then don't munge it */ + if (strncmp(ldb_dn_get_linearized(msg->dn), LTDB_INDEX ":", strlen(LTDB_INDEX) + 1) != 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + + for (i=0;i<msg->num_elements;i++) { + struct ldb_message_element *el = &msg->elements[i]; + if (strcmp(el->name, LTDB_IDXPTR) == 0) { + ret = ltdb_convert_from_idxptr(module, el); + if (ret != LDB_SUCCESS) { + return ret; + } + } + } + + return ret; +} + + + +/* + fixup the idxptr for one DN + */ +static int ltdb_idxptr_fix_dn(struct ldb_module *module, const char *strdn) +{ + struct ldb_dn *dn; + struct ldb_message *msg = ldb_msg_new(module); + int ret; + + dn = ldb_dn_new(msg, module->ldb, strdn); + if (ltdb_search_dn1_index(module, dn, msg) == LDB_SUCCESS) { + ret = ltdb_store(module, msg, TDB_REPLACE); + } + talloc_free(msg); + return ret; +} + +/* cleanup the idxptr mode when transaction commits */ +int ltdb_index_transaction_commit(struct ldb_module *module) +{ + int i; + struct ltdb_private *ltdb = + talloc_get_type(module->private_data, struct ltdb_private); + + /* fix all the DNs that we have modified */ + if (ltdb->idxptr) { + for (i=0;i<ltdb->idxptr->num_dns;i++) { + ltdb_idxptr_fix_dn(module, ltdb->idxptr->dn_list[i]); + } + + if (ltdb->idxptr->repack) { + tdb_repack(ltdb->tdb); + } + } + + talloc_free(ltdb->idxptr); + ltdb->idxptr = NULL; + return 0; +} + +/* cleanup the idxptr mode when transaction cancels */ +int ltdb_index_transaction_cancel(struct ldb_module *module) +{ + struct ltdb_private *ltdb = + talloc_get_type(module->private_data, struct ltdb_private); + talloc_free(ltdb->idxptr); + ltdb->idxptr = NULL; + return 0; +} + + + +/* a wrapper around ltdb_store() for the index code which + stores in IDXPTR format when idxptr mode is enabled + + WARNING: This modifies the msg which is passed in +*/ +int ltdb_store_idxptr(struct ldb_module *module, const struct ldb_message *msg, int flgs) +{ + struct ltdb_private *ltdb = + talloc_get_type(module->private_data, struct ltdb_private); + int ret; + + if (ltdb->idxptr) { + int i; + struct ldb_message *msg2 = ldb_msg_new(module); + + /* free any old pointer */ + ret = ltdb_search_dn1(module, msg->dn, msg2); + if (ret == 0) { + for (i=0;i<msg2->num_elements;i++) { + struct ldb_message_element *el = &msg2->elements[i]; + if (strcmp(el->name, LTDB_IDXPTR) == 0) { + ret = ltdb_free_idxptr(module, el); + if (ret != LDB_SUCCESS) { + return ret; + } + } + } + } + talloc_free(msg2); + + for (i=0;i<msg->num_elements;i++) { + struct ldb_message_element *el = &msg->elements[i]; + if (strcmp(el->name, LTDB_IDX) == 0) { + ret = ltdb_convert_to_idxptr(module, el); + if (ret != LDB_SUCCESS) { + return ret; + } + } + } + + if (ltdb_idxptr_add(module, msg) != 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + } + + ret = ltdb_store(module, msg, flgs); + return ret; +} + + +/* find an element in a list, using the given comparison function and assuming that the list is already sorted using comp_fn @@ -213,7 +535,7 @@ static int ltdb_index_dn_simple(struct ldb_module *module, return LDB_ERR_OPERATIONS_ERROR; } - ret = ltdb_search_dn1(module, dn, msg); + ret = ltdb_search_dn1_index(module, dn, msg); talloc_free(dn); if (ret != LDB_SUCCESS) { return ret; @@ -559,7 +881,7 @@ static int ltdb_index_dn_one(struct ldb_module *module, return LDB_ERR_OPERATIONS_ERROR; } - ret = ltdb_search_dn1(module, key, msg); + ret = ltdb_search_dn1_index(module, key, msg); talloc_free(key); if (ret != LDB_SUCCESS) { return ret; @@ -715,7 +1037,7 @@ static int ltdb_index_filter(const struct dn_list *dn_list, return LDB_ERR_OPERATIONS_ERROR; } - ret = ldb_module_send_entry(ac->req, msg); + ret = ldb_module_send_entry(ac->req, msg, NULL); if (ret != LDB_SUCCESS) { ac->callback_failed = true; return ret; @@ -895,7 +1217,7 @@ static int ltdb_index_add1(struct ldb_module *module, const char *dn, } talloc_steal(msg, dn_key); - ret = ltdb_search_dn1(module, dn_key, msg); + ret = ltdb_search_dn1_index(module, dn_key, msg); if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) { talloc_free(msg); return ret; @@ -920,7 +1242,7 @@ static int ltdb_index_add1(struct ldb_module *module, const char *dn, } if (ret == LDB_SUCCESS) { - ret = ltdb_store(module, msg, TDB_REPLACE); + ret = ltdb_store_idxptr(module, msg, TDB_REPLACE); } talloc_free(msg); @@ -1007,7 +1329,7 @@ int ltdb_index_del_value(struct ldb_module *module, const char *dn, return LDB_ERR_OPERATIONS_ERROR; } - ret = ltdb_search_dn1(module, dn_key, msg); + ret = ltdb_search_dn1_index(module, dn_key, msg); if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) { talloc_free(dn_key); return ret; @@ -1022,9 +1344,15 @@ int ltdb_index_del_value(struct ldb_module *module, const char *dn, i = ldb_msg_find_idx(msg, dn, &j, LTDB_IDX); if (i == -1) { + struct ldb_ldif ldif; + ldb_debug(ldb, LDB_DEBUG_ERROR, "ERROR: dn %s not found in %s\n", dn, ldb_dn_get_linearized(dn_key)); + ldif.changetype = LDB_CHANGETYPE_NONE; + ldif.msg = msg; + ldb_ldif_write_file(module->ldb, stdout, &ldif); + sleep(100); /* it ain't there. hmmm */ talloc_free(dn_key); return LDB_SUCCESS; @@ -1041,7 +1369,7 @@ int ltdb_index_del_value(struct ldb_module *module, const char *dn, if (msg->elements[i].num_values == 0) { ret = ltdb_delete_noindex(module, dn_key); } else { - ret = ltdb_store(module, msg, TDB_REPLACE); + ret = ltdb_store_idxptr(module, msg, TDB_REPLACE); } talloc_free(dn_key); @@ -1250,8 +1578,8 @@ int ltdb_reindex(struct ldb_module *module) return LDB_ERR_OPERATIONS_ERROR; } - if (tdb_repack(ltdb->tdb) != 0) { - return LDB_ERR_OPERATIONS_ERROR; + if (ltdb->idxptr) { + ltdb->idxptr->repack = true; } return LDB_SUCCESS; diff --git a/source4/lib/ldb/ldb_tdb/ldb_search.c b/source4/lib/ldb/ldb_tdb/ldb_search.c index 6ab06c4e48..35149c4b77 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_search.c +++ b/source4/lib/ldb/ldb_tdb/ldb_search.c @@ -418,7 +418,7 @@ static int search_func(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, voi return -1; } - ret = ldb_module_send_entry(ac->req, msg); + ret = ldb_module_send_entry(ac->req, msg, NULL); if (ret != LDB_SUCCESS) { ac->callback_failed = true; /* the callback failed, abort the operation */ diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c index 9e3ad80705..ea460def65 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.c @@ -850,6 +850,8 @@ static int ltdb_start_trans(struct ldb_module *module) ltdb->in_transaction++; + ltdb_index_transaction_start(module); + return LDB_SUCCESS; } @@ -860,6 +862,10 @@ static int ltdb_end_trans(struct ldb_module *module) ltdb->in_transaction--; + if (ltdb_index_transaction_commit(module) != 0) { + return ltdb_err_map(tdb_error(ltdb->tdb)); + } + if (tdb_transaction_commit(ltdb->tdb) != 0) { return ltdb_err_map(tdb_error(ltdb->tdb)); } @@ -874,6 +880,10 @@ static int ltdb_del_trans(struct ldb_module *module) ltdb->in_transaction--; + if (ltdb_index_transaction_cancel(module) != 0) { + return ltdb_err_map(tdb_error(ltdb->tdb)); + } + if (tdb_transaction_cancel(ltdb->tdb) != 0) { return ltdb_err_map(tdb_error(ltdb->tdb)); } diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.h b/source4/lib/ldb/ldb_tdb/ldb_tdb.h index c78a8172c7..7b9a76501f 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.h +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.h @@ -33,6 +33,7 @@ struct ltdb_private { int in_transaction; bool check_base; + struct ltdb_idxptr *idxptr; }; /* @@ -57,6 +58,7 @@ struct ltdb_context { #define LTDB_INDEX "@INDEX" #define LTDB_INDEXLIST "@INDEXLIST" #define LTDB_IDX "@IDX" +#define LTDB_IDXPTR "@IDXPTR" #define LTDB_IDXATTR "@IDXATTR" #define LTDB_IDXONE "@IDXONE" #define LTDB_BASEINFO "@BASEINFO" @@ -85,6 +87,9 @@ int ltdb_index_add(struct ldb_module *module, const struct ldb_message *msg); int ltdb_index_del(struct ldb_module *module, const struct ldb_message *msg); int ltdb_index_one(struct ldb_module *module, const struct ldb_message *msg, int add); int ltdb_reindex(struct ldb_module *module); +int ltdb_index_transaction_start(struct ldb_module *module); +int ltdb_index_transaction_commit(struct ldb_module *module); +int ltdb_index_transaction_cancel(struct ldb_module *module); /* The following definitions come from lib/ldb/ldb_tdb/ldb_pack.c */ diff --git a/source4/lib/ldb/modules/asq.c b/source4/lib/ldb/modules/asq.c index 835715e7dc..c650970af4 100644 --- a/source4/lib/ldb/modules/asq.c +++ b/source4/lib/ldb/modules/asq.c @@ -178,7 +178,7 @@ static int asq_reqs_callback(struct ldb_request *req, struct ldb_reply *ares) case LDB_REPLY_ENTRY: /* pass the message up to the original callback as we * do not have to elaborate on it any further */ - ret = ldb_module_send_entry(ac->req, ares->message); + ret = ldb_module_send_entry(ac->req, ares->message, ares->controls); if (ret != LDB_SUCCESS) { return ldb_module_done(ac->req, NULL, NULL, ret); } diff --git a/source4/lib/ldb/modules/operational.c b/source4/lib/ldb/modules/operational.c index abb1d4ca1a..345441b5e1 100644 --- a/source4/lib/ldb/modules/operational.c +++ b/source4/lib/ldb/modules/operational.c @@ -206,7 +206,7 @@ static int operational_callback(struct ldb_request *req, struct ldb_reply *ares) return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } - return ldb_module_send_entry(ac->req, ares->message); + return ldb_module_send_entry(ac->req, ares->message, ares->controls); case LDB_REPLY_REFERRAL: /* ignore referrals */ diff --git a/source4/lib/ldb/modules/paged_results.c b/source4/lib/ldb/modules/paged_results.c index 1a242f1be0..dfc565fef8 100644 --- a/source4/lib/ldb/modules/paged_results.c +++ b/source4/lib/ldb/modules/paged_results.c @@ -147,7 +147,7 @@ static int paged_results(struct paged_context *ac) while (ac->store->num_entries > 0 && ac->size > 0) { msg = ac->store->first; - ret = ldb_module_send_entry(ac->req, msg->r->message); + ret = ldb_module_send_entry(ac->req, msg->r->message, msg->r->controls); if (ret != LDB_SUCCESS) { return ret; } diff --git a/source4/lib/ldb/modules/paged_searches.c b/source4/lib/ldb/modules/paged_searches.c index 7a728e3bb0..56f9b1cac3 100644 --- a/source4/lib/ldb/modules/paged_searches.c +++ b/source4/lib/ldb/modules/paged_searches.c @@ -161,7 +161,7 @@ static int ps_callback(struct ldb_request *req, struct ldb_reply *ares) switch (ares->type) { case LDB_REPLY_ENTRY: - ret = ldb_module_send_entry(ac->req, ares->message); + ret = ldb_module_send_entry(ac->req, ares->message, ares->controls); if (ret != LDB_SUCCESS) { return ldb_module_done(ac->req, NULL, NULL, ret); } diff --git a/source4/lib/ldb/modules/sort.c b/source4/lib/ldb/modules/sort.c index 64d60f370c..25e56b24c8 100644 --- a/source4/lib/ldb/modules/sort.c +++ b/source4/lib/ldb/modules/sort.c @@ -152,7 +152,7 @@ static int server_sort_results(struct sort_context *ac) ares->type = LDB_REPLY_ENTRY; ares->message = talloc_move(ares, &ac->msgs[i]); - ret = ldb_module_send_entry(ac->req, ares->message); + ret = ldb_module_send_entry(ac->req, ares->message, ares->controls); if (ret != LDB_SUCCESS) { return ret; } diff --git a/source4/lib/ldb/tests/python/ldap.py b/source4/lib/ldb/tests/python/ldap.py index 71fd98876e..c64d85a0e5 100755 --- a/source4/lib/ldb/tests/python/ldap.py +++ b/source4/lib/ldb/tests/python/ldap.py @@ -74,7 +74,11 @@ class BasicTests(unittest.TestCase): self.delete_force(self.ldb, "cn=ldaptestuser,cn=users," + self.base_dn) self.delete_force(self.ldb, "cn=ldaptestgroup,cn=users," + self.base_dn) - + self.delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn) + self.delete_force(self.ldb, "cn=ldaptestgroup2,cn=users," + self.base_dn) + self.delete_force(self.ldb, "cn=ldaptestutf8user èùéìòà ,cn=users," + self.base_dn) + self.delete_force(self.ldb, "cn=ldaptestutf8user2 èùéìòà ,cn=users," + self.base_dn) + def test_group_add_invalid_member(self): """Testing group add with invalid member""" try: @@ -436,7 +440,13 @@ member: cn=ldaptestuser3,cn=users,""" + self.base_dn + """ print "Testing Renames" - ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=users," + self.base_dn) + attrs = ["objectGUID", "objectSid"] + print "Testing ldb.search for (&(cn=ldaptestUSer2)(objectClass=user))" + res_user = ldb.search(self.base_dn, expression="(&(cn=ldaptestUSer2)(objectClass=user))", scope=SCOPE_SUBTREE, attrs=attrs) + self.assertEquals(len(res_user), 1, "Could not find (&(cn=ldaptestUSer2)(objectClass=user))") + + #Check rename works with extended/alternate DN forms + ldb.rename("<SID=" + ldb.schema_format_value("objectSID", res_user[0]["objectSID"][0]) + ">" , "cn=ldaptestuser3,cn=users," + self.base_dn) ldb.rename("cn=ldaptestuser3,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=users," + self.base_dn) @@ -585,7 +595,7 @@ member: cn=ldaptestuser4,cn=ldaptestcontainer,""" + self.base_dn + """ print "Testing ldb.search for (&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group)) to check subtree renames and linked attributes" res = ldb.search(self.base_dn, expression="(&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group))", scope=SCOPE_SUBTREE) - self.assertEquals(len(res), 1, "Could not find (&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group)), perhaps linked attributes are not conistant with subtree renames?") + self.assertEquals(len(res), 1, "Could not find (&(member=CN=ldaptestuser4,CN=ldaptestcontainer2," + self.base_dn + ")(objectclass=group)), perhaps linked attributes are not consistant with subtree renames?") print "Testing ldb.rename (into itself) of cn=ldaptestcontainer2," + self.base_dn + " to cn=ldaptestcontainer,cn=ldaptestcontainer2," + self.base_dn try: @@ -737,8 +747,8 @@ member: cn=ldaptestuser4,cn=ldaptestcontainer,""" + self.base_dn + """ self.assertEquals(len(res6), 1, "Could not find (&(cn=*daptestcomputer)(objectCategory=compuTER))") self.assertEquals(res[0].dn, res6[0].dn) - - ldb.delete(res[0].dn) + + ldb.delete("<GUID=" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + ">") print "Testing ldb.search for (&(cn=ldaptest2computer)(objectClass=user))" res = ldb.search(expression="(&(cn=ldaptest2computer)(objectClass=user))") @@ -754,25 +764,29 @@ member: cn=ldaptestuser4,cn=ldaptestcontainer,""" + self.base_dn + """ self.assertEquals(int(res[0]["sAMAccountType"][0]), 805306369) self.assertEquals(int(res[0]["userAccountControl"][0]), 4096) - ldb.delete(res[0].dn) + ldb.delete("<SID=" + ldb.schema_format_value("objectSID", res[0]["objectSID"][0]) + ">") - attrs = ["cn", "name", "objectClass", "objectGUID", "whenCreated", "nTSecurityDescriptor", "memberOf", "allowedAttributes", "allowedAttributesEffective"] + attrs = ["cn", "name", "objectClass", "objectGUID", "objectSID", "whenCreated", "nTSecurityDescriptor", "memberOf", "allowedAttributes", "allowedAttributesEffective"] print "Testing ldb.search for (&(cn=ldaptestUSer2)(objectClass=user))" - res = ldb.search(self.base_dn, expression="(&(cn=ldaptestUSer2)(objectClass=user))", scope=SCOPE_SUBTREE, attrs=attrs) - self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestUSer2)(objectClass=user))") - - self.assertEquals(res[0].dn, ("CN=ldaptestuser2,CN=Users," + self.base_dn)) - self.assertEquals(res[0]["cn"], "ldaptestuser2") - self.assertEquals(res[0]["name"], "ldaptestuser2") - self.assertEquals(res[0]["objectClass"], ["top", "person", "organizationalPerson", "user"]) - self.assertTrue("objectGUID" in res[0]) - self.assertTrue("whenCreated" in res[0]) - self.assertTrue("nTSecurityDescriptor" in res[0]) - self.assertTrue("allowedAttributes" in res[0]) - self.assertTrue("allowedAttributesEffective" in res[0]) - self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper()) - - attrs = ["cn", "name", "objectClass", "objectGUID", "whenCreated", "nTSecurityDescriptor", "member", "allowedAttributes", "allowedAttributesEffective"] + res_user = ldb.search(self.base_dn, expression="(&(cn=ldaptestUSer2)(objectClass=user))", scope=SCOPE_SUBTREE, attrs=attrs) + self.assertEquals(len(res_user), 1, "Could not find (&(cn=ldaptestUSer2)(objectClass=user))") + + self.assertEquals(res_user[0].dn, ("CN=ldaptestuser2,CN=Users," + self.base_dn)) + self.assertEquals(res_user[0]["cn"], "ldaptestuser2") + self.assertEquals(res_user[0]["name"], "ldaptestuser2") + self.assertEquals(res_user[0]["objectClass"], ["top", "person", "organizationalPerson", "user"]) + self.assertTrue("objectSid" in res_user[0]) + self.assertTrue("objectGUID" in res_user[0]) + self.assertTrue("whenCreated" in res_user[0]) + self.assertTrue("nTSecurityDescriptor" in res_user[0]) + self.assertTrue("allowedAttributes" in res_user[0]) + self.assertTrue("allowedAttributesEffective" in res_user[0]) + self.assertEquals(res_user[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper()) + + ldaptestuser2_sid = res_user[0]["objectSid"][0] + ldaptestuser2_guid = res_user[0]["objectGUID"][0] + + attrs = ["cn", "name", "objectClass", "objectGUID", "objectSID", "whenCreated", "nTSecurityDescriptor", "member", "allowedAttributes", "allowedAttributesEffective"] print "Testing ldb.search for (&(cn=ldaptestgroup2)(objectClass=group))" res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs) self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))") @@ -781,7 +795,8 @@ member: cn=ldaptestuser4,cn=ldaptestcontainer,""" + self.base_dn + """ self.assertEquals(res[0]["cn"], "ldaptestgroup2") self.assertEquals(res[0]["name"], "ldaptestgroup2") self.assertEquals(res[0]["objectClass"], ["top", "group"]) - self.assertTrue("objectGuid" not in res[0]) + self.assertTrue("objectGUID" in res[0]) + self.assertTrue("objectSid" in res[0]) self.assertTrue("whenCreated" in res[0]) self.assertTrue("nTSecurityDescriptor" in res[0]) self.assertTrue("allowedAttributes" in res[0]) @@ -791,6 +806,18 @@ member: cn=ldaptestuser4,cn=ldaptestcontainer,""" + self.base_dn + """ memberUP.append(m.upper()) self.assertTrue(("CN=ldaptestuser2,CN=Users," + self.base_dn).upper() in memberUP) + res = ldb.search(self.base_dn, expression="(&(cn=ldaptestgroup2)(objectClass=group))", scope=SCOPE_SUBTREE, attrs=attrs, controls=["extended_dn:1:1"]) + self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestgroup2)(objectClass=group))") + + print res[0]["member"] + memberUP = [] + for m in res[0]["member"]: + memberUP.append(m.upper()) + print ("<GUID=" + ldb.schema_format_value("objectGUID", ldaptestuser2_guid) + ">;<SID=" + ldb.schema_format_value("objectSid", ldaptestuser2_sid) + ">;CN=ldaptestuser2,CN=Users," + self.base_dn).upper() + + self.assertTrue(("<GUID=" + ldb.schema_format_value("objectGUID", ldaptestuser2_guid) + ">;<SID=" + ldb.schema_format_value("objectSid", ldaptestuser2_sid) + ">;CN=ldaptestuser2,CN=Users," + self.base_dn).upper() in memberUP) + + print "Testing Linked attribute behaviours" ldb.modify_ldif(""" dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """ changetype: modify @@ -799,9 +826,15 @@ member: CN=ldaptestuser2,CN=Users,""" + self.base_dn + """ member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """ """) - print "Testing Linked attribute behaviours" ldb.modify_ldif(""" -dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """ +dn: <GUID=""" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + """> +changetype: modify +replace: member +member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """ +""") + + ldb.modify_ldif(""" +dn: <SID=""" + ldb.schema_format_value("objectSid", res[0]["objectSid"][0]) + """> changetype: modify delete: member """) @@ -810,7 +843,7 @@ delete: member dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """ changetype: modify add: member -member: CN=ldaptestuser2,CN=Users,""" + self.base_dn + """ +member: <GUID=""" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + """> member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """ """) @@ -824,7 +857,7 @@ replace: member dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """ changetype: modify add: member -member: CN=ldaptestuser2,CN=Users,""" + self.base_dn + """ +member: <SID=""" + ldb.schema_format_value("objectSid", res_user[0]["objectSid"][0]) + """> member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """ """) diff --git a/source4/lib/ldb/tools/ldbadd.c b/source4/lib/ldb/tools/ldbadd.c index 3749aec629..f32a4fa9bc 100644 --- a/source4/lib/ldb/tools/ldbadd.c +++ b/source4/lib/ldb/tools/ldbadd.c @@ -93,7 +93,7 @@ int main(int argc, const char **argv) options = ldb_cmdline_process(ldb, argc, argv, usage); if (ldb_transaction_start(ldb) != 0) { - printf("Failed to start transaction\n"); + printf("Failed to start transaction: %s\n", ldb_errstring(ldb)); exit(1); } @@ -114,7 +114,7 @@ int main(int argc, const char **argv) } if (count != 0 && ldb_transaction_commit(ldb) != 0) { - printf("Failed to commit transaction\n"); + printf("Failed to commit transaction: %s\n", ldb_errstring(ldb)); exit(1); } diff --git a/source4/lib/ldb/tools/ldbedit.c b/source4/lib/ldb/tools/ldbedit.c index b18aea1b10..1a684c5c2d 100644 --- a/source4/lib/ldb/tools/ldbedit.c +++ b/source4/lib/ldb/tools/ldbedit.c @@ -113,7 +113,7 @@ static int merge_edits(struct ldb_context *ldb, int adds=0, modifies=0, deletes=0; if (ldb_transaction_start(ldb) != 0) { - fprintf(stderr, "Failed to start transaction\n"); + fprintf(stderr, "Failed to start transaction: %s\n", ldb_errstring(ldb)); return -1; } @@ -156,7 +156,7 @@ static int merge_edits(struct ldb_context *ldb, } if (ldb_transaction_commit(ldb) != 0) { - fprintf(stderr, "Failed to commit transaction\n"); + fprintf(stderr, "Failed to commit transaction: %s\n", ldb_errstring(ldb)); return -1; } diff --git a/source4/lib/ldb/tools/ldbmodify.c b/source4/lib/ldb/tools/ldbmodify.c index 8b6309e016..d73937cea4 100644 --- a/source4/lib/ldb/tools/ldbmodify.c +++ b/source4/lib/ldb/tools/ldbmodify.c @@ -91,13 +91,13 @@ int main(int argc, const char **argv) ldb = ldb_init(NULL, NULL); + options = ldb_cmdline_process(ldb, argc, argv, usage); + if (ldb_transaction_start(ldb) != 0) { - printf("Failed to start transaction\n"); + printf("Failed to start transaction: %s\n", ldb_errstring(ldb)); exit(1); } - options = ldb_cmdline_process(ldb, argc, argv, usage); - if (options->argc == 0) { ret = process_file(ldb, stdin, &count); } else { @@ -114,7 +114,7 @@ int main(int argc, const char **argv) } if (count != 0 && ldb_transaction_commit(ldb) != 0) { - printf("Failed to commit transaction\n"); + printf("Failed to commit transaction: %s\n", ldb_errstring(ldb)); exit(1); } diff --git a/source4/lib/socket/connect.c b/source4/lib/socket/connect.c index 2b64668b9b..d74a7b4833 100644 --- a/source4/lib/socket/connect.c +++ b/source4/lib/socket/connect.c @@ -25,7 +25,6 @@ #include "lib/socket/socket.h" #include "lib/events/events.h" #include "libcli/composite/composite.h" -#include "libcli/resolve/resolve.h" struct connect_state { @@ -38,26 +37,16 @@ struct connect_state { static void socket_connect_handler(struct event_context *ev, struct fd_event *fde, uint16_t flags, void *private); -static void continue_resolve_name(struct composite_context *ctx); -static void continue_socket_connect(struct composite_context *creq); /* call the real socket_connect() call, and setup event handler */ static void socket_send_connect(struct composite_context *result) { - struct composite_context *creq; struct fd_event *fde; struct connect_state *state = talloc_get_type(result->private_data, struct connect_state); - creq = talloc_zero(state, struct composite_context); - if (composite_nomem(creq, result)) return; - creq->state = COMPOSITE_STATE_IN_PROGRESS; - creq->event_ctx = result->event_ctx; - creq->async.fn = continue_socket_connect; - creq->async.private_data = result; - result->status = socket_connect(state->sock, state->my_address, state->server_address, @@ -84,16 +73,13 @@ struct composite_context *socket_connect_send(struct socket_context *sock, struct socket_address *my_address, struct socket_address *server_address, uint32_t flags, - struct resolve_context *resolve_ctx, struct event_context *event_ctx) { struct composite_context *result; struct connect_state *state; - result = talloc_zero(sock, struct composite_context); + result = composite_create(sock, event_ctx); if (result == NULL) return NULL; - result->state = COMPOSITE_STATE_IN_PROGRESS; - result->event_ctx = event_ctx; state = talloc_zero(result, struct connect_state); if (composite_nomem(state, result)) return result; @@ -122,16 +108,6 @@ struct composite_context *socket_connect_send(struct socket_context *sock, set_blocking(socket_get_fd(sock), false); - if (resolve_ctx != NULL && server_address->addr && strcmp(sock->backend_name, "ipv4") == 0) { - struct nbt_name name; - struct composite_context *creq; - make_nbt_name_client(&name, server_address->addr); - creq = resolve_name_send(resolve_ctx, &name, result->event_ctx); - if (composite_nomem(creq, result)) return result; - composite_continue(result, creq, continue_resolve_name, result); - return result; - } - socket_send_connect(result); return result; @@ -156,39 +132,6 @@ static void socket_connect_handler(struct event_context *ev, } /* - recv name resolution reply then send the connect -*/ -static void continue_resolve_name(struct composite_context *creq) -{ - struct composite_context *result = talloc_get_type(creq->async.private_data, - struct composite_context); - struct connect_state *state = talloc_get_type(result->private_data, struct connect_state); - const char *addr; - - result->status = resolve_name_recv(creq, state, &addr); - if (!composite_is_ok(result)) return; - - state->server_address = socket_address_from_strings(state, state->sock->backend_name, - addr, state->server_address->port); - if (composite_nomem(state->server_address, result)) return; - - socket_send_connect(result); -} - -/* - called when a connect has finished. Complete the top level composite context -*/ -static void continue_socket_connect(struct composite_context *creq) -{ - struct composite_context *result = talloc_get_type(creq->async.private_data, - struct composite_context); - result->status = creq->status; - if (!composite_is_ok(result)) return; - composite_done(result); -} - - -/* wait for a socket_connect_send() to finish */ NTSTATUS socket_connect_recv(struct composite_context *result) @@ -205,11 +148,11 @@ NTSTATUS socket_connect_recv(struct composite_context *result) NTSTATUS socket_connect_ev(struct socket_context *sock, struct socket_address *my_address, struct socket_address *server_address, - uint32_t flags, struct resolve_context *resolve_ctx, + uint32_t flags, struct event_context *ev) { struct composite_context *ctx; ctx = socket_connect_send(sock, my_address, - server_address, flags, resolve_ctx, ev); + server_address, flags, ev); return socket_connect_recv(ctx); } diff --git a/source4/lib/socket/connect_multi.c b/source4/lib/socket/connect_multi.c index 98b4d405b3..14c475d0c3 100644 --- a/source4/lib/socket/connect_multi.c +++ b/source4/lib/socket/connect_multi.c @@ -37,8 +37,6 @@ struct connect_multi_state { int num_ports; uint16_t *ports; - struct resolve_context *resolve_ctx; - struct socket_context *sock; uint16_t result_port; @@ -89,7 +87,6 @@ _PUBLIC_ struct composite_context *socket_connect_multi_send( if (composite_nomem(multi->server_address, result)) goto failed; multi->num_ports = num_server_ports; - multi->resolve_ctx = talloc_reference(multi, resolve_ctx); multi->ports = talloc_array(multi, uint16_t, multi->num_ports); if (composite_nomem(multi->ports, result)) goto failed; @@ -105,7 +102,7 @@ _PUBLIC_ struct composite_context *socket_connect_multi_send( */ struct nbt_name name; struct composite_context *creq; - make_nbt_name_client(&name, server_address); + make_nbt_name_server(&name, server_address); creq = resolve_name_send(resolve_ctx, &name, result->event_ctx); if (composite_nomem(creq, result)) goto failed; composite_continue(result, creq, continue_resolve_name, result); @@ -159,7 +156,7 @@ static void connect_multi_next_socket(struct composite_context *result) talloc_steal(state, state->sock); creq = socket_connect_send(state->sock, NULL, - state->addr, 0, multi->resolve_ctx, + state->addr, 0, result->event_ctx); if (composite_nomem(creq, result)) return; talloc_steal(state, creq); diff --git a/source4/lib/socket/socket.h b/source4/lib/socket/socket.h index ec3afe8f7f..4741a67990 100644 --- a/source4/lib/socket/socket.h +++ b/source4/lib/socket/socket.h @@ -20,8 +20,7 @@ #ifndef _SAMBA_SOCKET_H #define _SAMBA_SOCKET_H -#include "lib/events/events.h" - +struct event_context; struct socket_context; enum socket_type { @@ -179,14 +178,12 @@ struct composite_context *socket_connect_send(struct socket_context *sock, struct socket_address *my_address, struct socket_address *server_address, uint32_t flags, - struct resolve_context *resolve_ctx, struct event_context *event_ctx); NTSTATUS socket_connect_recv(struct composite_context *ctx); NTSTATUS socket_connect_ev(struct socket_context *sock, struct socket_address *my_address, struct socket_address *server_address, uint32_t flags, - struct resolve_context *resolve_ctx, struct event_context *ev); struct composite_context *socket_connect_multi_send(TALLOC_CTX *mem_ctx, diff --git a/source4/lib/socket/testsuite.c b/source4/lib/socket/testsuite.c index 2c25d8f491..0fae880ca0 100644 --- a/source4/lib/socket/testsuite.c +++ b/source4/lib/socket/testsuite.c @@ -152,7 +152,7 @@ static bool test_tcp(struct torture_context *tctx) torture_comment(tctx, "server port is %d\n", srv_addr->port); - status = socket_connect_ev(sock2, NULL, srv_addr, 0, NULL, ev); + status = socket_connect_ev(sock2, NULL, srv_addr, 0, ev); torture_assert_ntstatus_ok(tctx, status, "connect() on socket 2"); status = socket_accept(sock1, &sock3); diff --git a/source4/lib/stream/packet.h b/source4/lib/stream/packet.h index 45826c5f14..f7b10cd878 100644 --- a/source4/lib/stream/packet.h +++ b/source4/lib/stream/packet.h @@ -20,6 +20,10 @@ */ +struct packet_context; +struct event_context; +struct fd_event; + typedef NTSTATUS (*packet_full_request_fn_t)(void *private, DATA_BLOB blob, size_t *packet_size); typedef NTSTATUS (*packet_callback_fn_t)(void *private, DATA_BLOB blob); |