Merge branch 'master' of ssh://git.samba.org/data/git/samba
authorJelmer Vernooij <jelmer@samba.org>
Sun, 4 Jan 2009 21:48:23 +0000 (22:48 +0100)
committerJelmer Vernooij <jelmer@samba.org>
Sun, 4 Jan 2009 21:48:23 +0000 (22:48 +0100)
91 files changed:
lib/replace/test/os2_delete.c
lib/tevent/config.mk [deleted file]
lib/tevent/configure.ac
lib/tevent/libtevent.m4
lib/tevent/pytevent.c
lib/tevent/samba.m4 [new file with mode: 0644]
lib/tevent/tests.py
lib/tevent/testsuite.c
lib/tevent/tevent.c
lib/tevent/tevent.h
lib/tevent/tevent.mk
lib/tevent/tevent.pc.in
lib/tevent/tevent_aio.c
lib/tevent/tevent_debug.c
lib/tevent/tevent_epoll.c
lib/tevent/tevent_fd.c [new file with mode: 0644]
lib/tevent/tevent_internal.h
lib/tevent/tevent_select.c
lib/tevent/tevent_signal.c
lib/tevent/tevent_standard.c
lib/tevent/tevent_timed.c
librpc/gen_ndr/named_pipe_auth.h
librpc/ndr/ndr_basic.c
packaging/RHEL/samba.spec.tmpl
pidl/lib/Parse/Pidl/Samba4/Header.pm
source3/Makefile.in
source3/autogen.sh
source3/client/client.c
source3/include/async_req.h
source3/include/async_sock.h
source3/include/packet.h
source3/include/proto.h
source3/include/smb.h
source3/lib/async_req.c
source3/lib/async_sock.c
source3/lib/ctdbd_conn.c
source3/lib/ldb/include/ldb.h
source3/lib/ldb/tools/ldbadd.c
source3/lib/ldb/tools/ldbmodify.c
source3/lib/packet.c
source3/lib/util_sock.c
source3/lib/wb_reqtrans.c [moved from source3/winbindd/winbindd_reqtrans.c with 77% similarity]
source3/lib/wbclient.c [new file with mode: 0644]
source3/libads/krb5_setpw.c
source3/libsmb/async_smb.c
source3/libsmb/cliconnect.c
source3/libsmb/clidfs.c
source3/libsmb/clireadwrite.c
source3/libsmb/smb_share_modes.c
source3/modules/onefs_open.c
source3/modules/vfs_smb_traffic_analyzer.c
source3/param/loadparm.c
source3/rpc_client/cli_pipe.c
source3/rpc_server/srv_pipe_hnd.c
source3/samba4.m4
source3/smbd/process.c
source3/torture/nbio.c
source3/torture/torture.c
source3/torture/utable.c
source3/utils/smbfilter.c
source3/winbindd/idmap.c
source3/winbindd/winbindd_proto.h
source4/auth/kerberos/config.mk
source4/auth/kerberos/krb5_init_context.c
source4/build/m4/public.m4
source4/configure.ac
source4/headermap.txt
source4/lib/events/config.mk
source4/lib/events/events.h
source4/lib/events/events_internal.h [deleted file]
source4/lib/events/tevent_s4.c
source4/lib/registry/pyregistry.c
source4/lib/registry/regf.c
source4/lib/registry/tools/common.c
source4/lib/registry/tools/regtree.c
source4/lib/socket/socket.c
source4/lib/socket/socket.h
source4/libcli/ldap/config.mk
source4/libcli/ldap/ldap_client.c
source4/ntvfs/posix/config.m4
source4/ntvfs/posix/config.mk
source4/ntvfs/sysdep/inotify.c
source4/selftest/tests.sh
source4/smbd/config.mk
source4/smbd/server.c
source4/smbd/service_named_pipe.c
source4/smbd/service_stream.c
source4/smbd/service_task.c
source4/torture/util_smb.c
source4/winbind/wb_init_domain.c
source4/winbind/wb_samba3_cmd.c

index b45c135355a0a7be5f339e4225f1009ea2a0a943..44efeea08a5bdcde791d64bd222aef1a08fa6881 100644 (file)
@@ -30,7 +30,9 @@ static int test_readdir_os2_delete_ret;
 static void cleanup(void)
 {
        /* I'm a lazy bastard */
-       system("rm -rf " TESTDIR);
+       if (system("rm -rf " TESTDIR)) {
+               FAILED("system");
+       }
        mkdir(TESTDIR, 0700) == 0 || FAILED("mkdir");
 }
 
@@ -118,7 +120,9 @@ int test_readdir_os2_delete(void)
 
        rmdir(TESTDIR) == 0 || FAILED("rmdir");
 
-       system("rm -rf " TESTDIR);
+       if (system("rm -rf " TESTDIR) == -1) {
+               FAILED("system");
+       }
 
        return test_readdir_os2_delete_ret;
 }
diff --git a/lib/tevent/config.mk b/lib/tevent/config.mk
deleted file mode 100644 (file)
index e4fb9a8..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-##############################
-[MODULE::TEVENT_AIO]
-PRIVATE_DEPENDENCIES = LIBAIO_LINUX
-OUTPUT_TYPE = MERGED_OBJ
-SUBSYSTEM = LIBTEVENT
-##############################
-
-TEVENT_AIO_OBJ_FILES = $(libteventsrcdir)/tevent_aio.o
-
-##############################
-[MODULE::TEVENT_EPOLL]
-OUTPUT_TYPE = MERGED_OBJ
-SUBSYSTEM = LIBTEVENT
-##############################
-
-TEVENT_EPOLL_OBJ_FILES = $(libteventsrcdir)/tevent_epoll.o
-
-##############################
-[MODULE::TEVENT_SELECT]
-OUTPUT_TYPE = MERGED_OBJ
-SUBSYSTEM = LIBTEVENT
-##############################
-
-TEVENT_SELECT_OBJ_FILES = $(libteventsrcdir)/tevent_select.o
-
-##############################
-[MODULE::TEVENT_STANDARD]
-OUTPUT_TYPE = MERGED_OBJ
-SUBSYSTEM = LIBTEVENT
-##############################
-
-TEVENT_STANDARD_OBJ_FILES = $(libteventsrcdir)/tevent_standard.o
-
-################################################
-# Start SUBSYSTEM LIBTEVENT
-[LIBRARY::LIBTEVENT]
-PUBLIC_DEPENDENCIES = LIBTALLOC
-OUTPUT_TYPE = MERGED_OBJ
-CFLAGS = -I../lib/tevent
-#
-# End SUBSYSTEM LIBTEVENT
-################################################
-
-LIBTEVENT_OBJ_FILES = $(addprefix $(libteventsrcdir)/, tevent.o tevent_timed.o tevent_signal.o tevent_debug.o tevent_util.o)
-
-PUBLIC_HEADERS += $(addprefix $(libteventsrcdir)/, tevent.h tevent_internal.h)
index 22d306b0f65bf2cf79e35ed9868ab71cf3a5e9c4..3cc06a144a53e1a82f0dfdb615af8596b367850a 100644 (file)
@@ -1,11 +1,8 @@
 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(tevent, 0.9.0)
+AC_INIT(tevent, 0.9.2)
 AC_CONFIG_SRCDIR([tevent.c])
 AC_CONFIG_HEADER(config.h)
+
 AC_LIBREPLACE_ALL_CHECKS
 
 AC_LD_EXPORT_DYNAMIC
index 30105d9bef04c25c660ca411948bc8b3545a8c59..ec2ed9cd1fd92ccc5859d236814a166d640b97e3 100644 (file)
@@ -1,12 +1,14 @@
 dnl find the tevent sources. This is meant to work both for
 dnl standalone builds, and builds of packages using libtevent
+
+AC_SUBST(teventdir)
+
 if test x"$teventdir" = "x"; then
        teventdir=""
        teventpaths="$srcdir $srcdir/../lib/tevent $srcdir/tevent $srcdir/../tevent"
        for d in $teventpaths; do
                if test -f "$d/tevent.c"; then
                        teventdir="$d"
-                       AC_SUBST(teventdir)
                        break;
                fi
        done
@@ -15,37 +17,32 @@ if test x"$teventdir" = "x"; then
        fi
 fi
 
-TEVENT_OBJ="tevent.o tevent_select.o tevent_signal.o tevent_timed.o tevent_standard.o tevent_debug.o tevent_util.o"
-AC_LIBREPLACE_NETWORK_CHECKS
+TEVENT_OBJ=""
+TEVENT_CFLAGS=""
+TEVENT_LIBS=""
+AC_SUBST(TEVENT_OBJ)
+AC_SUBST(TEVENT_CFLAGS)
+AC_SUBST(TEVENT_LIBS)
+
+TEVENT_CFLAGS="-I$teventdir"
+
+TEVENT_OBJ="tevent.o tevent_fd.o tevent_timed.o tevent_signal.o tevent_debug.o tevent_util.o"
+TEVENT_OBJ="$TEVENT_OBJ tevent_standard.o tevent_select.o"
 
-SMB_ENABLE(TEVENT_EPOLL, NO)
-SMB_ENABLE(TEVENT_AIO, NO)
+tevent_cv_aio_support=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
    TEVENT_OBJ="$TEVENT_OBJ tevent_epoll.o"
-   SMB_ENABLE(TEVENT_EPOLL,YES)
    AC_DEFINE(HAVE_EPOLL, 1, [Whether epoll available])
-   #TODO: remove HAVE_EVENTS_EPOLL and use HAVE_EPOLL
-   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)
+   AC_CHECK_LIB_EXT(aio, TEVENT_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
       TEVENT_OBJ="$TEVENT_OBJ tevent_aio.o"
-      SMB_ENABLE(TEVENT_AIO,YES)
+      tevent_cv_aio_support=yes
       AC_DEFINE(HAVE_LINUX_AIO, 1, [Whether Linux AIO is available])
    fi
 fi
 
-AC_SUBST(TEVENT_OBJ)
-SMB_EXT_LIB(LIBAIO_LINUX, $AIO_LIBS)
-
-TEVENT_CFLAGS="-I$teventdir"
-AC_SUBST(TEVENT_CFLAGS)
-
-TEVENT_LIBS="$AIO_LIBS"
-AC_SUBST(TEVENT_LIBS)
-
-
index a969373738c71ac065d34c1553c63daf4363e6a4..3d71d78397414394b92bb9e675aa54c2445c1fb5 100644 (file)
@@ -24,9 +24,9 @@
 typedef struct {
        PyObject_HEAD
        struct tevent_context *ev_ctx;
-} PyEventContextObject;
+} PyTEventContextObject;
 
-PyAPI_DATA(PyTypeObject) PyEventContext;
+PyAPI_DATA(PyTypeObject) PyTEventContext;
 
 static PyObject *py_set_default_backend(PyObject *self, PyObject *args)
 {
@@ -34,13 +34,13 @@ static PyObject *py_set_default_backend(PyObject *self, PyObject *args)
 
     if (!PyArg_ParseTuple(args, "s", &name))
         return NULL;
-    event_set_default_backend(name);
+    tevent_set_default_backend(name);
     return Py_None;
 }
 
 static PyObject *py_backend_list(PyObject *self)
 {
-    const char **backends = event_backend_list(NULL);
+    const char **backends = tevent_backend_list(NULL);
     PyObject *ret;
     int i, len;
 
@@ -66,28 +66,28 @@ static PyObject *py_event_ctx_new(PyTypeObject *type, PyObject *args, PyObject *
     const char *kwnames[] = { "name", NULL };
     char *name = NULL;
     struct tevent_context *ev_ctx;
-    PyEventContextObject *ret;
+    PyTEventContextObject *ret;
     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s", (char **)kwnames, &name))
         return NULL;
 
     if (name == NULL)
-        ev_ctx = event_context_init(NULL);
+        ev_ctx = tevent_context_init(NULL);
     else
-        ev_ctx = event_context_init_byname(NULL, name);
+        ev_ctx = tevent_context_init_byname(NULL, name);
 
-    ret = (PyEventContextObject *)type->tp_alloc(type, 0);
+    ret = (PyTEventContextObject *)type->tp_alloc(type, 0);
     ret->ev_ctx = ev_ctx;
     return (PyObject *)ret;
 }
 
-static PyObject *py_event_ctx_loop_once(PyEventContextObject *self)
+static PyObject *py_event_ctx_loop_once(PyTEventContextObject *self)
 {
-    return PyInt_FromLong(event_loop_once(self->ev_ctx));
+    return PyInt_FromLong(tevent_loop_once(self->ev_ctx));
 }
 
-static PyObject *py_event_ctx_loop_wait(PyEventContextObject *self)
+static PyObject *py_event_ctx_loop_wait(PyTEventContextObject *self)
 {
-    return PyInt_FromLong(event_loop_wait(self->ev_ctx));
+    return PyInt_FromLong(tevent_loop_wait(self->ev_ctx));
 }
 
 static PyMethodDef py_event_ctx_methods[] = {
@@ -98,16 +98,17 @@ static PyMethodDef py_event_ctx_methods[] = {
     { NULL }
 };
 
-static void py_event_ctx_dealloc(PyEventContextObject * self)
+static void py_event_ctx_dealloc(PyTEventContextObject * self)
 {
        talloc_free(self->ev_ctx);
        self->ob_type->tp_free(self);
 }
 
-PyTypeObject PyEventContext = {
-    .tp_name = "EventContext",
+
+PyTypeObject PyTEventContext = {
+    .tp_name = "TEventContext",
     .tp_methods = py_event_ctx_methods,
-    .tp_basicsize = sizeof(PyEventContextObject),
+    .tp_basicsize = sizeof(PyTEventContextObject),
     .tp_dealloc = (destructor)py_event_ctx_dealloc,
     .tp_flags = Py_TPFLAGS_DEFAULT,
     .tp_new = py_event_ctx_new,
@@ -117,14 +118,14 @@ void inittevent(void)
 {
     PyObject *m;
 
-    if (PyType_Ready(&PyEventContext) < 0)
+    if (PyType_Ready(&PyTEventContext) < 0)
        return;
 
     m = Py_InitModule3("tevent", tevent_methods, "Event management.");
     if (m == NULL)
         return;
 
-    Py_INCREF(&PyEventContext);
-    PyModule_AddObject(m, "EventContext", (PyObject *)&PyEventContext);
+    Py_INCREF(&PyTEventContext);
+    PyModule_AddObject(m, "TEventContext", (PyObject *)&PyTEventContext);
 }
 
diff --git a/lib/tevent/samba.m4 b/lib/tevent/samba.m4
new file mode 100644 (file)
index 0000000..89b0b70
--- /dev/null
@@ -0,0 +1,16 @@
+
+teventdir="\$(libteventsrcdir)"
+m4_include(../lib/tevent/libtevent.m4)
+
+SMB_EXT_LIB(LIBTEVENT_EXT, [${TEVENT_LIBS}])
+SMB_ENABLE(LIBTEVENT_EXT)
+
+SMB_SUBSYSTEM(LIBTEVENT,
+       [\$(addprefix \$(libteventsrcdir)/, ${TEVENT_OBJ})],
+       [LIBTEVENT_EXT],
+       [${TEVENT_CFLAGS}])
+
+SMB_MAKE_SETTINGS([
+PUBLIC_HEADERS += \$(addprefix \$(libteventsrcdir)/, tevent.h tevent_internal.h)
+])
+
index 0ec736b359af2c01fbb79cc43ae1293e31a0c777..bf594a14f6e1d1c0b6e42d8d43d890fb52d2480f 100644 (file)
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
 
-import tevent as events
+import tevent
 import unittest
 
 # Just test the bindings are there and that calling them doesn't crash
 # anything.
 
-class EventTestCase(unittest.TestCase):
+class TEventTestCase(unittest.TestCase):
     def test_create(self):
-        self.assertTrue(events.EventContext() is not None)
+        self.assertTrue(tevent.TEventContext() is not None)
 
     def test_loop_wait(self):
-        self.assertEquals(0, events.EventContext().loop_wait())
+        self.assertEquals(0, tevent.TEventContext().loop_wait())
index ec57c5ad2ebae78d2e44d4c4012a8c7f55a399c0..1b811f5fa2e899a75b876353e8477fa1b87ab5b5 100644 (file)
@@ -81,8 +81,9 @@ static bool test_event_context(struct torture_context *test,
        /* create a pipe */
        pipe(fd);
 
-       fde = event_add_fd(ev_ctx, ev_ctx, fd[0], EVENT_FD_READ|EVENT_FD_AUTOCLOSE, 
+       fde = event_add_fd(ev_ctx, ev_ctx, fd[0], EVENT_FD_READ,
                           fde_handler, fd);
+       tevent_fd_set_auto_close(fde);
 
        event_add_timed(ev_ctx, ev_ctx, timeval_current_ofs(2,0), 
                        finished_handler, &finished);
index e45a690c33ae5aaacf7cd237f539e349299ed463..5582b583e7304c06867033dea97f1acdba00f7ae 100644 (file)
      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
+  structure using the function tevent_context_init(); This returns a
   'struct tevent_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()
+  using tevent_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
+  Finally, you call tevent_loop_wait_once() to block waiting for one of the
+  events to occor or tevent_loop_wait() which will loop
   forever.
 
 */
 #include "replace.h"
+#include "system/filesys.h"
 #include "tevent.h"
 #include "tevent_internal.h"
 #include "tevent_util.h"
 
-struct event_ops_list {
-       struct event_ops_list *next, *prev;
+struct tevent_ops_list {
+       struct tevent_ops_list *next, *prev;
        const char *name;
-       const struct event_ops *ops;
+       const struct tevent_ops *ops;
 };
 
 /* list of registered event backends */
-static struct event_ops_list *event_backends = NULL;
-static char *event_default_backend = NULL;
+static struct tevent_ops_list *tevent_backends = NULL;
+static char *tevent_default_backend = NULL;
 
 /*
   register an events backend
 */
-bool event_register_backend(const char *name, const struct event_ops *ops)
+bool tevent_register_backend(const char *name, const struct tevent_ops *ops)
 {
-       struct event_ops_list *e;
+       struct tevent_ops_list *e;
 
-       for (e = event_backends; e != NULL; e = e->next) {
+       for (e = tevent_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);
+       e = talloc(talloc_autofree_context(), struct tevent_ops_list);
        if (e == NULL) return false;
 
        e->name = name;
        e->ops = ops;
-       DLIST_ADD(event_backends, e);
+       DLIST_ADD(tevent_backends, e);
 
        return true;
 }
@@ -94,38 +95,39 @@ bool event_register_backend(const char *name, const struct event_ops *ops)
 /*
   set the default event backend
  */
-void event_set_default_backend(const char *backend)
+void tevent_set_default_backend(const char *backend)
 {
-       if (event_default_backend) free(event_default_backend);
-       event_default_backend = strdup(backend);
+       talloc_free(tevent_default_backend);
+       tevent_default_backend = talloc_strdup(talloc_autofree_context(),
+                                              backend);
 }
 
 /*
   initialise backends if not already done
 */
-static void event_backend_init(void)
+static void tevent_backend_init(void)
 {
-       events_select_init();
-       events_standard_init();
-#if HAVE_EVENTS_EPOLL
-       events_epoll_init();
+       tevent_select_init();
+       tevent_standard_init();
+#ifdef HAVE_EPOLL
+       tevent_epoll_init();
 #endif
-#if HAVE_LINUX_AIO
-       events_aio_init();
+#ifdef HAVE_LINUX_AIO
+       tevent_aio_init();
 #endif
 }
 
 /*
   list available backends
 */
-const char **event_backend_list(TALLOC_CTX *mem_ctx)
+const char **tevent_backend_list(TALLOC_CTX *mem_ctx)
 {
        const char **list = NULL;
-       struct event_ops_list *e;
+       struct tevent_ops_list *e;
 
-       event_backend_init();
+       tevent_backend_init();
 
-       for (e=event_backends;e;e=e->next) {
+       for (e=tevent_backends;e;e=e->next) {
                list = ev_str_list_add(list, e->name);
        }
 
@@ -143,10 +145,10 @@ const char **event_backend_list(TALLOC_CTX *mem_ctx)
   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!
+  NOTE: use tevent_context_init() inside of samba!
 */
-static struct tevent_context *event_context_init_ops(TALLOC_CTX *mem_ctx, 
-                                                   const struct event_ops *ops)
+static struct tevent_context *tevent_context_init_ops(TALLOC_CTX *mem_ctx,
+                                                     const struct tevent_ops *ops)
 {
        struct tevent_context *ev;
        int ret;
@@ -170,22 +172,23 @@ static struct tevent_context *event_context_init_ops(TALLOC_CTX *mem_ctx,
   call, and all subsequent calls pass this event_context as the first
   element. Event handlers also receive this as their first argument.
 */
-struct tevent_context *event_context_init_byname(TALLOC_CTX *mem_ctx, const char *name)
+struct tevent_context *tevent_context_init_byname(TALLOC_CTX *mem_ctx,
+                                                 const char *name)
 {
-       struct event_ops_list *e;
+       struct tevent_ops_list *e;
 
-       event_backend_init();
+       tevent_backend_init();
 
        if (name == NULL) {
-               name = event_default_backend;
+               name = tevent_default_backend;
        }
        if (name == NULL) {
                name = "standard";
        }
 
-       for (e=event_backends;e;e=e->next) {
+       for (e=tevent_backends;e;e=e->next) {
                if (strcmp(name, e->name) == 0) {
-                       return event_context_init_ops(mem_ctx, e->ops);
+                       return tevent_context_init_ops(mem_ctx, e->ops);
                }
        }
        return NULL;
@@ -197,42 +200,74 @@ struct tevent_context *event_context_init_byname(TALLOC_CTX *mem_ctx, const char
   call, and all subsequent calls pass this event_context as the first
   element. Event handlers also receive this as their first argument.
 */
-struct tevent_context *event_context_init(TALLOC_CTX *mem_ctx)
+struct tevent_context *tevent_context_init(TALLOC_CTX *mem_ctx)
 {
-       return event_context_init_byname(mem_ctx, NULL);
+       return tevent_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
+  if flags contains TEVENT_FD_AUTOCLOSE then the fd will be closed when
   the returned fd_event context is freed
 */
-struct tevent_fd *event_add_fd(struct tevent_context *ev, TALLOC_CTX *mem_ctx,
-                             int fd, uint16_t flags, event_fd_handler_t handler,
-                             void *private_data)
+struct tevent_fd *_tevent_add_fd(struct tevent_context *ev,
+                                TALLOC_CTX *mem_ctx,
+                                int fd,
+                                uint16_t flags,
+                                tevent_fd_handler_t handler,
+                                void *private_data,
+                                const char *handler_name,
+                                const char *location)
 {
-       return ev->ops->add_fd(ev, mem_ctx, fd, flags, handler, private_data);
+       return ev->ops->add_fd(ev, mem_ctx, fd, flags, handler, private_data,
+                              handler_name, location);
 }
 
 /*
   add a disk aio event
 */
-struct aio_event *event_add_aio(struct tevent_context *ev,
-                               TALLOC_CTX *mem_ctx,
-                               struct iocb *iocb,
-                               event_aio_handler_t handler,
-                               void *private_data)
+struct tevent_aio *_tevent_add_aio(struct tevent_context *ev,
+                                  TALLOC_CTX *mem_ctx,
+                                  struct iocb *iocb,
+                                  tevent_aio_handler_t handler,
+                                  void *private_data,
+                                  const char *handler_name,
+                                  const char *location)
 {
        if (ev->ops->add_aio == NULL) return NULL;
-       return ev->ops->add_aio(ev, mem_ctx, iocb, handler, private_data);
+       return ev->ops->add_aio(ev, mem_ctx, iocb, handler, private_data,
+                               handler_name, location);
+}
+
+/*
+  set a close function on the fd event
+*/
+void tevent_fd_set_close_fn(struct tevent_fd *fde,
+                           tevent_fd_close_fn_t close_fn)
+{
+       if (!fde) return;
+       fde->event_ctx->ops->set_fd_close_fn(fde, close_fn);
+}
+
+static void tevent_fd_auto_close_fn(struct tevent_context *ev,
+                                   struct tevent_fd *fde,
+                                   int fd,
+                                   void *private_data)
+{
+       close(fd);
+}
+
+void tevent_fd_set_auto_close(struct tevent_fd *fde)
+{
+       tevent_fd_set_close_fn(fde, tevent_fd_auto_close_fn);
 }
 
 /*
   return the fd event flags
 */
-uint16_t event_get_fd_flags(struct tevent_fd *fde)
+uint16_t tevent_fd_get_flags(struct tevent_fd *fde)
 {
        if (!fde) return 0;
        return fde->event_ctx->ops->get_fd_flags(fde);
@@ -241,22 +276,26 @@ uint16_t event_get_fd_flags(struct tevent_fd *fde)
 /*
   set the fd event flags
 */
-void event_set_fd_flags(struct tevent_fd *fde, uint16_t flags)
+void tevent_fd_set_flags(struct tevent_fd *fde, uint16_t flags)
 {
        if (!fde) return;
        fde->event_ctx->ops->set_fd_flags(fde, flags);
 }
 
 /*
-  add a timed event
+  add a timer event
   return NULL on failure
 */
-struct tevent_timer *event_add_timed(struct tevent_context *ev, TALLOC_CTX *mem_ctx,
-                                   struct timeval next_event, 
-                                   event_timed_handler_t handler, 
-                                   void *private_data)
+struct tevent_timer *_tevent_add_timer(struct tevent_context *ev,
+                                      TALLOC_CTX *mem_ctx,
+                                      struct timeval next_event,
+                                      tevent_timer_handler_t handler,
+                                      void *private_data,
+                                      const char *handler_name,
+                                      const char *location)
 {
-       return ev->ops->add_timer(ev, mem_ctx, next_event, handler, private_data);
+       return ev->ops->add_timer(ev, mem_ctx, next_event, handler, private_data,
+                                 handler_name, location);
 }
 
 /*
@@ -266,19 +305,23 @@ struct tevent_timer *event_add_timed(struct tevent_context *ev, TALLOC_CTX *mem_
 
   return NULL on failure
 */
-struct signal_event *event_add_signal(struct tevent_context *ev, TALLOC_CTX *mem_ctx,
-                                     int signum,
-                                     int sa_flags,
-                                     event_signal_handler_t handler, 
-                                     void *private_data)
+struct tevent_signal *_tevent_add_signal(struct tevent_context *ev,
+                                        TALLOC_CTX *mem_ctx,
+                                        int signum,
+                                        int sa_flags,
+                                        tevent_signal_handler_t handler,
+                                        void *private_data,
+                                        const char *handler_name,
+                                        const char *location)
 {
-       return ev->ops->add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data);
+       return ev->ops->add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data,
+                                  handler_name, location);
 }
 
 /*
   do a single event loop using the events defined in ev 
 */
-int event_loop_once(struct tevent_context *ev)
+int tevent_loop_once(struct tevent_context *ev)
 {
        return ev->ops->loop_once(ev);
 }
@@ -286,25 +329,7 @@ int event_loop_once(struct tevent_context *ev)
 /*
   return on failure or (with 0) if all fd events are removed
 */
-int event_loop_wait(struct tevent_context *ev)
+int tevent_loop_wait(struct tevent_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 tevent_context *event_context_find(TALLOC_CTX *mem_ctx)
-{
-       struct tevent_context *ev = talloc_find_parent_bytype(mem_ctx, struct tevent_context);
-       if (ev == NULL) {               
-               ev = event_context_init(mem_ctx);
-       }
-       return ev;
-}
index f626de9d12a82dbb4c890b631debf363ddcf5018..b57d96f5fb99eb42b9b7414cd73ac28fcc0c6913 100644 (file)
@@ -33,59 +33,93 @@ struct tevent_aio;
 struct tevent_signal;
 
 /* event handler types */
-typedef void (*tevent_fd_handler_t)(struct tevent_context *,
-                                   struct tevent_fd *,
-                                   uint16_t , void *);
-typedef void (*tevent_timer_handler_t)(struct tevent_context *,
-                                      struct tevent_timer *,
-                                      struct timeval , void *);
-typedef void (*tevent_signal_handler_t)(struct tevent_context *,
-                                       struct tevent_signal *,
-                                       int , int, void *, void *);
-typedef void (*tevent_aio_handler_t)(struct tevent_context *,
-                                    struct tevent_aio *,
-                                    int, void *);
+typedef void (*tevent_fd_handler_t)(struct tevent_context *ev,
+                                   struct tevent_fd *fde,
+                                   uint16_t flags,
+                                   void *private_data);
+typedef void (*tevent_fd_close_fn_t)(struct tevent_context *ev,
+                                    struct tevent_fd *fde,
+                                    int fd,
+                                    void *private_data);
+typedef void (*tevent_timer_handler_t)(struct tevent_context *ev,
+                                      struct tevent_timer *te,
+                                      struct timeval current_time,
+                                      void *private_data);
+typedef void (*tevent_signal_handler_t)(struct tevent_context *ev,
+                                       struct tevent_signal *se,
+                                       int signum,
+                                       int count,
+                                       void *siginfo,
+                                       void *private_data);
+typedef void (*tevent_aio_handler_t)(struct tevent_context *ev,
+                                    struct tevent_aio *ae,
+                                    int ret,
+                                    void *private_data);
 
 struct tevent_context *tevent_context_init(TALLOC_CTX *mem_ctx);
 struct tevent_context *tevent_context_init_byname(TALLOC_CTX *mem_ctx, const char *name);
 const char **tevent_backend_list(TALLOC_CTX *mem_ctx);
 void tevent_set_default_backend(const char *backend);
 
-struct tevent_fd *tevent_add_fd(struct tevent_context *ev,
-                               TALLOC_CTX *mem_ctx,
-                               int fd, uint16_t flags,
-                               tevent_fd_handler_t handler,
-                               void *private_data);
-
-struct tevent_timer *tevent_add_timer(struct tevent_context *ev,
-                                     TALLOC_CTX *mem_ctx,
-                                     struct timeval next_event,
-                                     tevent_timer_handler_t handler,
-                                     void *private_data);
-
-struct tevent_signal *tevent_add_signal(struct tevent_context *ev,
-                                       TALLOC_CTX *mem_ctx,
-                                       int signum, int sa_flags,
-                                       tevent_signal_handler_t handler,
-                                       void *private_data);
+struct tevent_fd *_tevent_add_fd(struct tevent_context *ev,
+                                TALLOC_CTX *mem_ctx,
+                                int fd,
+                                uint16_t flags,
+                                tevent_fd_handler_t handler,
+                                void *private_data,
+                                const char *handler_name,
+                                const char *location);
+#define tevent_add_fd(ev, mem_ctx, fd, flags, handler, private_data) \
+       _tevent_add_fd(ev, mem_ctx, fd, flags, handler, private_data, \
+                      #handler, __location__)
+
+struct tevent_timer *_tevent_add_timer(struct tevent_context *ev,
+                                      TALLOC_CTX *mem_ctx,
+                                      struct timeval next_event,
+                                      tevent_timer_handler_t handler,
+                                      void *private_data,
+                                      const char *handler_name,
+                                      const char *location);
+#define tevent_add_timer(ev, mem_ctx, next_event, handler, private_data) \
+       _tevent_add_timer(ev, mem_ctx, next_event, handler, private_data, \
+                         #handler, __location__);
+
+struct tevent_signal *_tevent_add_signal(struct tevent_context *ev,
+                                        TALLOC_CTX *mem_ctx,
+                                        int signum,
+                                        int sa_flags,
+                                        tevent_signal_handler_t handler,
+                                        void *private_data,
+                                        const char *handler_name,
+                                        const char *location);
+#define tevent_add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data) \
+       _tevent_add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data, \
+                          #handler, __location__)
 
 struct iocb;
-struct tevent_aio *tevent_add_aio(struct tevent_context *ev,
-                                 TALLOC_CTX *mem_ctx,
-                                 struct iocb *iocb,
-                                 tevent_aio_handler_t handler,
-                                 void *private_data);
+struct tevent_aio *_tevent_add_aio(struct tevent_context *ev,
+                                  TALLOC_CTX *mem_ctx,
+                                  struct iocb *iocb,
+                                  tevent_aio_handler_t handler,
+                                  void *private_data,
+                                  const char *handler_name,
+                                  const char *location);
+#define tevent_add_aio(ev, mem_ctx, iocb, handler, private_data) \
+       _tevent_add_aio(ev, mem_ctx, iocb, handler, private_data, \
+                       #handler, __location__);
 
 int tevent_loop_once(struct tevent_context *ev);
 int tevent_loop_wait(struct tevent_context *ev);
 
+void tevent_fd_set_close_fn(struct tevent_fd *fde,
+                           tevent_fd_close_fn_t close_fn);
+void tevent_fd_set_auto_close(struct tevent_fd *fde);
 uint16_t tevent_fd_get_flags(struct tevent_fd *fde);
 void tevent_fd_set_flags(struct tevent_fd *fde, uint16_t flags);
 
 /* bits for file descriptor event flags */
 #define TEVENT_FD_READ 1
 #define TEVENT_FD_WRITE 2
-#define TEVENT_FD_AUTOCLOSE 4
 
 #define TEVENT_FD_WRITEABLE(fde) \
        tevent_fd_set_flags(fde, tevent_fd_get_flags(fde) | TEVENT_FD_WRITE)
@@ -97,10 +131,21 @@ void tevent_fd_set_flags(struct tevent_fd *fde, uint16_t flags);
 #define TEVENT_FD_NOT_READABLE(fde) \
        tevent_fd_set_flags(fde, tevent_fd_get_flags(fde) & ~TEVENT_FD_READ)
 
-/* for now always define the compat symbols */
-#ifndef TEVENT_COMPAT_DEFINES
-#define TEVENT_COMPAT_DEFINES 1
-#endif
+/* DEBUG */
+enum tevent_debug_level {
+       TEVENT_DEBUG_FATAL,
+       TEVENT_DEBUG_ERROR,
+       TEVENT_DEBUG_WARNING,
+       TEVENT_DEBUG_TRACE
+};
+
+int tevent_set_debug(struct tevent_context *ev,
+                    void (*debug)(void *context,
+                                  enum tevent_debug_level level,
+                                  const char *fmt,
+                                  va_list ap) PRINTF_ATTRIBUTE(3,0),
+                    void *context);
+int tevent_set_debug_stderr(struct tevent_context *ev);
 
 #ifdef TEVENT_COMPAT_DEFINES
 
@@ -154,7 +199,6 @@ void tevent_fd_set_flags(struct tevent_fd *fde, uint16_t flags);
 
 #define EVENT_FD_READ          TEVENT_FD_READ
 #define EVENT_FD_WRITE         TEVENT_FD_WRITE
-#define EVENT_FD_AUTOCLOSE     TEVENT_FD_AUTOCLOSE
 
 #define EVENT_FD_WRITEABLE(fde) \
        TEVENT_FD_WRITEABLE(fde)
@@ -168,6 +212,18 @@ void tevent_fd_set_flags(struct tevent_fd *fde, uint16_t flags);
 #define EVENT_FD_NOT_READABLE(fde) \
        TEVENT_FD_NOT_READABLE(fde)
 
+#define ev_debug_level         tevent_debug_level
+
+#define EV_DEBUG_FATAL         TEVENT_DEBUG_FATAL
+#define EV_DEBUG_ERROR         TEVENT_DEBUG_ERROR
+#define EV_DEBUG_WARNING       TEVENT_DEBUG_WARNING
+#define EV_DEBUG_TRACE         TEVENT_DEBUG_TRACE
+
+#define ev_set_debug(ev, debug, context) \
+       tevent_set_debug(ev, debug, context)
+
+#define ev_set_debug_stderr(_ev) tevent_set_debug_stderr(ev)
+
 #endif /* TEVENT_COMPAT_DEFINES */
 
 #endif /* __TEVENT_H__ */
index 6538362a060dc1fcbb8da834d3e5d90001708908..be7e2982188516b38370d7b2b262bf3e349c423d 100644 (file)
@@ -1,11 +1,12 @@
-TEVENT_SONAME = libtevent.$(SHLIBEXT).0
-TEVENT_SOLIB = libtevent.$(SHLIBEXT).$(PACKAGE_VERSION)
+TEVENT_SOBASE = libtevent.$(SHLIBEXT)
+TEVENT_SONAME = $(TEVENT_SOBASE).0
+TEVENT_SOLIB = $(TEVENT_SOBASE).$(PACKAGE_VERSION)
 TEVENT_STLIB = libtevent.a
 
 $(TEVENT_STLIB): $(TEVENT_OBJ)
        ar -rv $(TEVENT_STLIB) $(TEVENT_OBJ)
 
-libtevent.$(SHLIBEXT): $(TEVENT_SOLIB)
+$(TEVENT_SOBASE): $(TEVENT_SOLIB)
        ln -fs $< $@
 
 $(TEVENT_SONAME): $(TEVENT_SOLIB)
@@ -31,7 +32,7 @@ installlibs:: installdirs
 install:: all installdirs installheaders installlibs $(PYTHON_INSTALL_TARGET)
 
 clean::
-       rm -f $(TEVENT_SONAME) $(TEVENT_SOLIB) $(TEVENT_STLIB) libtevent.$(SHLIBEXT)
+       rm -f $(TEVENT_SOBASE) $(TEVENT_SONAME) $(TEVENT_SOLIB) $(TEVENT_STLIB)
        rm -f tevent.pc
        rm -f tevent.$(SHLIBEXT)
 
@@ -45,7 +46,7 @@ build-python:: tevent.$(SHLIBEXT)
 pytevent.o: $(teventdir)/pytevent.c
        $(CC) $(PICFLAG) -c $(teventdir)/pytevent.c $(CFLAGS) `$(PYTHON_CONFIG) --cflags`
 
-tevent.$(SHLIBEXT): libtevent.$(SHLIBEXT) pytevent.o
+tevent.$(SHLIBEXT): $(TEVENT_SOBASE) $(TEVENT_SONAME) pytevent.o
        $(SHLD) $(SHLD_FLAGS) -o $@ pytevent.o -L. -ltevent `$(PYTHON_CONFIG) --libs`
 
 install-python:: build-python
index afd9fcc2796a09e410b5edd255fce82a2e1a458d..93d0cf5d8b73e6efcc7eaec37d7d96928384cf74 100644 (file)
@@ -3,7 +3,7 @@ exec_prefix=@exec_prefix@
 libdir=@libdir@
 includedir=@includedir@
 
-Name: events
+Name: tevent
 Description: An event system library
 Version: @PACKAGE_VERSION@
 Libs: -L${libdir} -ltevent
index 746e96060b3d95bd77f879e482108739d4c264b9..b15dab3aaf310f58464dacb7da76824ac2a07493 100644 (file)
   this is _very_ experimental code
 */
 
-#include "system/filesys.h"
 #include "replace.h"
+#include "system/filesys.h"
+#include "system/select.h"
 #include "tevent.h"
 #include "tevent_internal.h"
 #include "tevent_util.h"
-#include <sys/epoll.h>
 #include <libaio.h>
 
 #define MAX_AIO_QUEUE_DEPTH    100
@@ -66,11 +66,11 @@ struct aio_event_context {
        pid_t pid;
 };
 
-struct aio_event {
+struct tevent_aio {
        struct tevent_context *event_ctx;
        struct iocb iocb;
        void *private_data;
-       event_aio_handler_t handler;
+       tevent_aio_handler_t handler;
 };
 
 /*
@@ -79,8 +79,8 @@ struct aio_event {
 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);
+       if (flags & TEVENT_FD_READ) ret |= (EPOLLIN | EPOLLERR | EPOLLHUP);
+       if (flags & TEVENT_FD_WRITE) ret |= (EPOLLOUT | EPOLLERR | EPOLLHUP);
        return ret;
 }
 
@@ -113,7 +113,8 @@ static void epoll_check_reopen(struct aio_event_context *aio_ev)
        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");
+               tevent_debug(aio_ev->ev, TEVENT_DEBUG_FATAL,
+                            "Failed to recreate epoll handle after fork\n");
                return;
        }
        aio_ev->pid = getpid();
@@ -146,7 +147,7 @@ static void epoll_add_event(struct aio_event_context *aio_ev, struct tevent_fd *
        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) {
+       if (fde->flags & TEVENT_FD_READ) {
                fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
        }
 }
@@ -191,7 +192,7 @@ static void epoll_mod_event(struct aio_event_context *aio_ev, struct tevent_fd *
        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) {
+       if (fde->flags & TEVENT_FD_READ) {
                fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
        }
 }
@@ -199,8 +200,8 @@ static void epoll_mod_event(struct aio_event_context *aio_ev, struct tevent_fd *
 static void epoll_change_event(struct aio_event_context *aio_ev, struct tevent_fd *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);
+       bool want_read = (fde->flags & TEVENT_FD_READ);
+       bool want_write= (fde->flags & TEVENT_FD_WRITE);
 
        if (aio_ev->epoll_fd == -1) return;
 
@@ -260,7 +261,7 @@ static int aio_event_loop(struct aio_event_context *aio_ev, struct timeval *tval
        if (aio_ev->epoll_fd == -1) return -1;
 
        if (aio_ev->ev->num_signal_handlers && 
-           common_event_check_signal(aio_ev->ev)) {
+           tevent_common_check_signal(aio_ev->ev)) {
                return 0;
        }
 
@@ -278,14 +279,14 @@ static int aio_event_loop(struct aio_event_context *aio_ev, struct timeval *tval
 
        if (ret == -EINTR) {
                if (aio_ev->ev->num_signal_handlers) {
-                       common_event_check_signal(aio_ev->ev);
+                       tevent_common_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);
+               tevent_common_loop_timer_delay(aio_ev->ev);
                return 0;
        }
 
@@ -296,8 +297,8 @@ static int aio_event_loop(struct aio_event_context *aio_ev, struct timeval *tval
                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);
+                       struct tevent_aio *ae = talloc_get_type(finished->data, 
+                                                              struct tevent_aio);
                        if (ae) {
                                talloc_set_destructor(ae, NULL);
                                ae->handler(ae->event_ctx, ae, 
@@ -326,10 +327,10 @@ static int aio_event_loop(struct aio_event_context *aio_ev, struct timeval *tval
                                                epoll_del_event(aio_ev, fde);
                                                continue;
                                        }
-                                       flags |= EVENT_FD_READ;
+                                       flags |= TEVENT_FD_READ;
                                }
-                               if (ep->events & EPOLLIN) flags |= EVENT_FD_READ;
-                               if (ep->events & EPOLLOUT) flags |= EVENT_FD_WRITE;
+                               if (ep->events & EPOLLIN) flags |= TEVENT_FD_READ;
+                               if (ep->events & EPOLLOUT) flags |= TEVENT_FD_WRITE;
                                if (flags) {
                                        fde->handler(aio_ev->ev, fde, flags, fde->private_data);
                                }
@@ -398,8 +399,8 @@ static int aio_event_fd_destructor(struct tevent_fd *fde)
 
        epoll_del_event(aio_ev, fde);
 
-       if (fde->flags & EVENT_FD_AUTOCLOSE) {
-               close(fde->fd);
+       if (fde->close_fn) {
+               fde->close_fn(ev, fde, fde->fd, fde->private_data);
                fde->fd = -1;
        }
 
@@ -411,9 +412,11 @@ static int aio_event_fd_destructor(struct tevent_fd *fde)
   return NULL on failure (memory allocation error)
 */
 static struct tevent_fd *aio_event_add_fd(struct tevent_context *ev, TALLOC_CTX *mem_ctx,
-                                        int fd, uint16_t flags,
-                                        event_fd_handler_t handler,
-                                        void *private_data)
+                                         int fd, uint16_t flags,
+                                         tevent_fd_handler_t handler,
+                                         void *private_data,
+                                         const char *handler_name,
+                                         const char *location)
 {
        struct aio_event_context *aio_ev = talloc_get_type(ev->additional_data,
                                                           struct aio_event_context);
@@ -428,7 +431,10 @@ static struct tevent_fd *aio_event_add_fd(struct tevent_context *ev, TALLOC_CTX
        fde->fd                 = fd;
        fde->flags              = flags;
        fde->handler            = handler;
+       fde->close_fn           = NULL;
        fde->private_data       = private_data;
+       fde->handler_name       = handler_name;
+       fde->location           = location;
        fde->additional_flags   = 0;
        fde->additional_data    = NULL;
 
@@ -441,15 +447,6 @@ static struct tevent_fd *aio_event_add_fd(struct tevent_context *ev, TALLOC_CTX
        return fde;
 }
 
-
-/*
-  return the fd event flags
-*/
-static uint16_t aio_event_get_fd_flags(struct tevent_fd *fde)
-{
-       return fde->flags;
-}
-
 /*
   set the fd event flags
 */
@@ -479,7 +476,7 @@ static int aio_event_loop_once(struct tevent_context *ev)
                                                           struct aio_event_context);
        struct timeval tval;
 
-       tval = common_event_loop_timer_delay(ev);
+       tval = tevent_common_loop_timer_delay(ev);
        if (ev_timeval_is_zero(&tval)) {
                return 0;
        }
@@ -508,7 +505,7 @@ static int aio_event_loop_wait(struct tevent_context *ev)
 /*
   called when a disk IO event needs to be cancelled
 */
-static int aio_destructor(struct aio_event *ae)
+static int aio_destructor(struct tevent_aio *ae)
 {
        struct tevent_context *ev = ae->event_ctx;
        struct aio_event_context *aio_ev = talloc_get_type(ev->additional_data,
@@ -520,16 +517,18 @@ static int aio_destructor(struct aio_event *ae)
 }
 
 /* submit an aio disk IO event */
-static struct aio_event *aio_event_add_aio(struct tevent_context *ev, 
-                                          TALLOC_CTX *mem_ctx,
-                                          struct iocb *iocb,
-                                          event_aio_handler_t handler,
-                                          void *private_data)
+static struct tevent_aio *aio_event_add_aio(struct tevent_context *ev, 
+                                           TALLOC_CTX *mem_ctx,
+                                           struct iocb *iocb,
+                                           tevent_aio_handler_t handler,
+                                           void *private_data,
+                                           const char *handler_name,
+                                           const char *location)
 {
        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);
+       struct tevent_aio *ae = talloc(mem_ctx?mem_ctx:ev, struct tevent_aio);
        if (ae == NULL) return NULL;
 
        ae->event_ctx    = ev;
@@ -548,20 +547,21 @@ static struct aio_event *aio_event_add_aio(struct tevent_context *ev,
        return ae;
 }
 
-static const struct event_ops aio_event_ops = {
+static const struct tevent_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_close_fn= tevent_common_fd_set_close_fn,
+       .get_fd_flags   = tevent_common_fd_get_flags,
        .set_fd_flags   = aio_event_set_fd_flags,
-       .add_timer      = common_event_add_timed,
-       .add_signal     = common_event_add_signal,
+       .add_timer      = tevent_common_add_timer,
+       .add_signal     = tevent_common_add_signal,
        .loop_once      = aio_event_loop_once,
        .loop_wait      = aio_event_loop_wait,
 };
 
-bool events_aio_init(void)
+bool tevent_aio_init(void)
 {
-       return event_register_backend("aio", &aio_event_ops);
+       return tevent_register_backend("aio", &aio_event_ops);
 }
 
index 4fa58534b4519f0beda46a0adcd4882548d796fd..841446bf6c929652793231258dbff210b9a2d6c6 100644 (file)
 /*
   this allows the user to choose their own debug function
 */
-int ev_set_debug(struct tevent_context *ev,
-                void (*debug)(void *context, enum ev_debug_level level,
-                               const char *fmt, va_list ap),
-                void *context)
+int tevent_set_debug(struct tevent_context *ev,
+                    void (*debug)(void *context,
+                                  enum tevent_debug_level level,
+                                  const char *fmt,
+                                  va_list ap) PRINTF_ATTRIBUTE(3,0),
+                    void *context)
 {
        ev->debug_ops.debug = debug;
        ev->debug_ops.context = context;
@@ -43,23 +45,26 @@ int ev_set_debug(struct tevent_context *ev,
 /*
   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)
+static void tevent_debug_stderr(void *private_data,
+                               enum tevent_debug_level level,
+                               const char *fmt,
+                               va_list ap) PRINTF_ATTRIBUTE(3,0);
+static void tevent_debug_stderr(void *private_data,
+                               enum tevent_debug_level level,
+                               const char *fmt, va_list ap)
 {
-       if (level <= EV_DEBUG_WARNING) {
+       if (level <= TEVENT_DEBUG_WARNING) {
                vfprintf(stderr, fmt, ap);
        }
 }
 
 /*
   convenience function to setup debug messages on stderr
-  messages of level EV_DEBUG_WARNING and higher are printed
+  messages of level TEVENT_DEBUG_WARNING and higher are printed
 */
-int ev_set_debug_stderr(struct tevent_context *ev)
+int tevent_set_debug_stderr(struct tevent_context *ev)
 {
-       return ev_set_debug(ev, ev_debug_stderr, ev);
+       return tevent_set_debug(ev, tevent_debug_stderr, ev);
 }
 
 /*
@@ -70,7 +75,8 @@ int ev_set_debug_stderr(struct tevent_context *ev)
  * Applications using the library must decide where to
  * redirect debugging messages
 */
-void ev_debug(struct tevent_context *ev, enum ev_debug_level level, const char *fmt, ...)
+void tevent_debug(struct tevent_context *ev, enum tevent_debug_level level,
+                 const char *fmt, ...)
 {
        va_list ap;
        if (ev->debug_ops.debug == NULL) {
index 1ce666462cdf0f41d7459503dd0002b42475a209..38357743499c44b44f7398ed6e22022072877764 100644 (file)
 
 #include "replace.h"
 #include "system/filesys.h"
-#include "system/network.h"
+#include "system/select.h"
 #include "tevent.h"
 #include "tevent_internal.h"
 #include "tevent_util.h"
-#include <sys/epoll.h>
 
 struct epoll_event_context {
        /* a pointer back to the generic event_context */
@@ -58,19 +57,19 @@ struct epoll_event_context {
 */
 static void epoll_panic(struct epoll_event_context *epoll_ev, const char *reason)
 {
-       ev_debug(epoll_ev->ev, EV_DEBUG_FATAL,
+       tevent_debug(epoll_ev->ev, TEVENT_DEBUG_FATAL,
                 "%s (%s) - calling abort()\n", reason, strerror(errno));
        abort();
 }
 
 /*
-  map from EVENT_FD_* to EPOLLIN/EPOLLOUT
+  map from TEVENT_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);
+       if (flags & TEVENT_FD_READ) ret |= (EPOLLIN | EPOLLERR | EPOLLHUP);
+       if (flags & TEVENT_FD_WRITE) ret |= (EPOLLOUT | EPOLLERR | EPOLLHUP);
        return ret;
 }
 
@@ -116,8 +115,8 @@ static void epoll_check_reopen(struct epoll_event_context *epoll_ev)
        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");
+               tevent_debug(epoll_ev->ev, TEVENT_DEBUG_FATAL,
+                            "Failed to recreate epoll handle after fork\n");
                return;
        }
        epoll_ev->pid = getpid();
@@ -153,7 +152,7 @@ static void epoll_add_event(struct epoll_event_context *epoll_ev, struct tevent_
        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) {
+       if (fde->flags & TEVENT_FD_READ) {
                fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
        }
 }
@@ -176,9 +175,9 @@ static void epoll_del_event(struct epoll_event_context *epoll_ev, struct tevent_
        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));
+               tevent_debug(epoll_ev->ev, TEVENT_DEBUG_FATAL,
+                            "epoll_del_event failed! probable early close bug (%s)\n",
+                            strerror(errno));
        }
        fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT;
 }
@@ -201,7 +200,7 @@ static void epoll_mod_event(struct epoll_event_context *epoll_ev, struct tevent_
        }
 
        /* only if we want to read we want to tell the event handler about errors */
-       if (fde->flags & EVENT_FD_READ) {
+       if (fde->flags & TEVENT_FD_READ) {
                fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
        }
 }
@@ -209,8 +208,8 @@ static void epoll_mod_event(struct epoll_event_context *epoll_ev, struct tevent_
 static void epoll_change_event(struct epoll_event_context *epoll_ev, struct tevent_fd *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);
+       bool want_read = (fde->flags & TEVENT_FD_READ);
+       bool want_write= (fde->flags & TEVENT_FD_WRITE);
 
        if (epoll_ev->epoll_fd == -1) return;
 
@@ -258,14 +257,14 @@ static int epoll_event_loop(struct epoll_event_context *epoll_ev, struct timeval
        }
 
        if (epoll_ev->ev->num_signal_handlers && 
-           common_event_check_signal(epoll_ev->ev)) {
+           tevent_common_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)) {
+               if (tevent_common_check_signal(epoll_ev->ev)) {
                        return 0;
                }
        }
@@ -277,7 +276,7 @@ static int epoll_event_loop(struct epoll_event_context *epoll_ev, struct timeval
 
        if (ret == 0 && tvalp) {
                /* we don't care about a possible delay here */
-               common_event_loop_timer_delay(epoll_ev->ev);
+               tevent_common_loop_timer_delay(epoll_ev->ev);
                return 0;
        }
 
@@ -293,7 +292,7 @@ static int epoll_event_loop(struct epoll_event_context *epoll_ev, struct timeval
                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
+                        * if we only wait for TEVENT_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
@@ -302,10 +301,10 @@ static int epoll_event_loop(struct epoll_event_context *epoll_ev, struct timeval
                                epoll_del_event(epoll_ev, fde);
                                continue;
                        }
-                       flags |= EVENT_FD_READ;
+                       flags |= TEVENT_FD_READ;
                }
-               if (events[i].events & EPOLLIN) flags |= EVENT_FD_READ;
-               if (events[i].events & EPOLLOUT) flags |= EVENT_FD_WRITE;
+               if (events[i].events & EPOLLIN) flags |= TEVENT_FD_READ;
+               if (events[i].events & EPOLLOUT) flags |= TEVENT_FD_WRITE;
                if (flags) {
                        fde->handler(epoll_ev->ev, fde, flags, fde->private_data);
                        if (destruction_count != epoll_ev->destruction_count) {
@@ -358,8 +357,8 @@ static int epoll_event_fd_destructor(struct tevent_fd *fde)
                
        epoll_del_event(epoll_ev, fde);
 
-       if (fde->flags & EVENT_FD_AUTOCLOSE) {
-               close(fde->fd);
+       if (fde->close_fn) {
+               fde->close_fn(ev, fde, fde->fd, fde->private_data);
                fde->fd = -1;
        }
 
@@ -371,9 +370,11 @@ static int epoll_event_fd_destructor(struct tevent_fd *fde)
   return NULL on failure (memory allocation error)
 */
 static struct tevent_fd *epoll_event_add_fd(struct tevent_context *ev, TALLOC_CTX *mem_ctx,
-                                        int fd, uint16_t flags,
-                                        event_fd_handler_t handler,
-                                        void *private_data)
+                                           int fd, uint16_t flags,
+                                           tevent_fd_handler_t handler,
+                                           void *private_data,
+                                           const char *handler_name,
+                                           const char *location)
 {
        struct epoll_event_context *epoll_ev = talloc_get_type(ev->additional_data,
                                                           struct epoll_event_context);
@@ -388,7 +389,10 @@ static struct tevent_fd *epoll_event_add_fd(struct tevent_context *ev, TALLOC_CT
        fde->fd                 = fd;
        fde->flags              = flags;
        fde->handler            = handler;
+       fde->close_fn           = NULL;
        fde->private_data       = private_data;
+       fde->handler_name       = handler_name;
+       fde->location           = location;
        fde->additional_flags   = 0;
        fde->additional_data    = NULL;
 
@@ -401,15 +405,6 @@ static struct tevent_fd *epoll_event_add_fd(struct tevent_context *ev, TALLOC_CT
        return fde;
 }
 
-
-/*
-  return the fd event flags
-*/
-static uint16_t epoll_event_get_fd_flags(struct tevent_fd *fde)
-{
-       return fde->flags;
-}
-
 /*
   set the fd event flags
 */
@@ -439,7 +434,7 @@ static int epoll_event_loop_once(struct tevent_context *ev)
                                                           struct epoll_event_context);
        struct timeval tval;
 
-       tval = common_event_loop_timer_delay(ev);
+       tval = tevent_common_loop_timer_delay(ev);
        if (ev_timeval_is_zero(&tval)) {
                return 0;
        }
@@ -465,18 +460,19 @@ static int epoll_event_loop_wait(struct tevent_context *ev)
        return 0;
 }
 
-static const struct event_ops epoll_event_ops = {
+static const struct tevent_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_close_fn= tevent_common_fd_set_close_fn,
+       .get_fd_flags   = tevent_common_fd_get_flags,
        .set_fd_flags   = epoll_event_set_fd_flags,
-       .add_timer      = common_event_add_timed,
-       .add_signal     = common_event_add_signal,
+       .add_timer      = tevent_common_add_timer,
+       .add_signal     = tevent_common_add_signal,
        .loop_once      = epoll_event_loop_once,
        .loop_wait      = epoll_event_loop_wait,
 };
 
-bool events_epoll_init(void)
+bool tevent_epoll_init(void)
 {
-       return event_register_backend("epoll", &epoll_event_ops);
+       return tevent_register_backend("epoll", &epoll_event_ops);
 }
diff --git a/lib/tevent/tevent_fd.c b/lib/tevent/tevent_fd.c
new file mode 100644 (file)
index 0000000..d450e21
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   common events code for fd events
+
+   Copyright (C) Stefan Metzmacher     2009
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "tevent.h"
+#include "tevent_internal.h"
+#include "tevent_util.h"
+
+uint16_t tevent_common_fd_get_flags(struct tevent_fd *fde)
+{
+       return fde->flags;
+}
+
+void tevent_common_fd_set_flags(struct tevent_fd *fde, uint16_t flags)
+{
+       if (fde->flags == flags) return;
+       fde->flags = flags;
+}
+
+void tevent_common_fd_set_close_fn(struct tevent_fd *fde,
+                                  tevent_fd_close_fn_t close_fn)
+{
+       fde->close_fn = close_fn;
+}
index 2d6909da366dd1e9e6115993e44d9a6f512342bf..f29e9c62f5ba423e927c832289119e922a73511e 100644 (file)
@@ -30,7 +30,11 @@ struct tevent_ops {
                                    TALLOC_CTX *mem_ctx,
                                    int fd, uint16_t flags,
                                    tevent_fd_handler_t handler,
-                                   void *private_data);
+                                   void *private_data,
+                                   const char *handler_name,
+                                   const char *location);
+       void (*set_fd_close_fn)(struct tevent_fd *fde,
+                               tevent_fd_close_fn_t close_fn);
        uint16_t (*get_fd_flags)(struct tevent_fd *fde);
        void (*set_fd_flags)(struct tevent_fd *fde, uint16_t flags);
 
@@ -39,19 +43,25 @@ struct tevent_ops {
                                          TALLOC_CTX *mem_ctx,
                                          struct timeval next_event,
                                          tevent_timer_handler_t handler,
-                                         void *private_data);
+                                         void *private_data,
+                                         const char *handler_name,
+                                         const char *location);
        /* disk aio event functions */
        struct tevent_aio *(*add_aio)(struct tevent_context *ev,
                                      TALLOC_CTX *mem_ctx,
                                      struct iocb *iocb,
                                      tevent_aio_handler_t handler,
-                                     void *private_data);
+                                     void *private_data,
+                                     const char *handler_name,
+                                     const char *location);
        /* signal functions */
        struct tevent_signal *(*add_signal)(struct tevent_context *ev,
                                            TALLOC_CTX *mem_ctx,
                                            int signum, int sa_flags,
                                            tevent_signal_handler_t handler,
-                                           void *private_data);
+                                           void *private_data,
+                                           const char *handler_name,
+                                           const char *location);
 
        /* loop functions */
        int (*loop_once)(struct tevent_context *ev);
@@ -62,10 +72,14 @@ struct tevent_fd {
        struct tevent_fd *prev, *next;
        struct tevent_context *event_ctx;
        int fd;
-       uint16_t flags; /* see EVENT_FD_* flags */
+       uint16_t flags; /* see TEVENT_FD_* flags */
        tevent_fd_handler_t handler;
+       tevent_fd_close_fn_t close_fn;
        /* this is private for the specific handler */
        void *private_data;
+       /* this is for debugging only! */
+       const char *handler_name;
+       const char *location;
        /* this is private for the events_ops implementation */
        uint16_t additional_flags;
        void *additional_data;
@@ -78,6 +92,9 @@ struct tevent_timer {
        tevent_timer_handler_t handler;
        /* this is private for the specific handler */
        void *private_data;
+       /* this is for debugging only! */
+       const char *handler_name;
+       const char *location;
        /* this is private for the events_ops implementation */
        void *additional_data;
 };
@@ -85,28 +102,26 @@ struct tevent_timer {
 struct tevent_signal {
        struct tevent_signal *prev, *next;
        struct tevent_context *event_ctx;
-       tevent_signal_handler_t handler;
-       void *private_data;
        int signum;
        int sa_flags;
+       tevent_signal_handler_t handler;
+       /* this is private for the specific handler */
+       void *private_data;
+       /* this is for debugging only! */
+       const char *handler_name;
+       const char *location;
+       /* this is private for the events_ops implementation */
+       void *additional_data;
 };
 
-/* 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,
+struct tevent_debug_ops {
+       void (*debug)(void *context, enum tevent_debug_level level,
                      const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0);
        void *context;
 };
 
-int ev_set_debug(struct tevent_context *ev,
-                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_stderr(struct tevent_context *ev);
-void ev_debug(struct tevent_context *ev, enum ev_debug_level level, const char *fmt, ...);
+void tevent_debug(struct tevent_context *ev, enum tevent_debug_level level,
+                 const char *fmt, ...) PRINTF_ATTRIBUTE(3,4);
 
 /* aio event is private to the aio backend */
 struct tevent_aio;
@@ -128,34 +143,42 @@ struct tevent_context {
        struct tevent_fd *pipe_fde;
 
        /* debugging operations */
-       struct ev_debug_ops debug_ops;
+       struct tevent_debug_ops debug_ops;
 };
 
 
-bool event_register_backend(const char *name, const struct tevent_ops *ops);
+bool tevent_register_backend(const char *name, const struct tevent_ops *ops);
+
+void tevent_common_fd_set_close_fn(struct tevent_fd *fde,
+                                  tevent_fd_close_fn_t close_fn);
+uint16_t tevent_common_fd_get_flags(struct tevent_fd *fde);
+void tevent_common_fd_set_flags(struct tevent_fd *fde, uint16_t flags);
 
 bool ev_timeval_is_zero(const struct timeval *tv);
-struct tevent_timer *common_event_add_timed(struct tevent_context *,
-                                           TALLOC_CTX *,
-                                           struct timeval,
-                                           tevent_timer_handler_t,
-                                           void *);
-struct timeval common_event_loop_timer_delay(struct tevent_context *);
-
-struct tevent_signal *common_event_add_signal(struct tevent_context *ev,
-                                             TALLOC_CTX *mem_ctx,
-                                             int signum,
-                                             int sa_flags,
-                                             tevent_signal_handler_t handler,
-                                             void *private_data);
-int common_event_check_signal(struct tevent_context *ev);
-
-
-bool events_standard_init(void);
-bool events_select_init(void);
-#if HAVE_EVENTS_EPOLL
-bool events_epoll_init(void);
+struct tevent_timer *tevent_common_add_timer(struct tevent_context *ev,
+                                            TALLOC_CTX *mem_ctx,
+                                            struct timeval next_event,
+                                            tevent_timer_handler_t handler,
+                                            void *private_data,
+                                            const char *handler_name,
+                                            const char *location);
+struct timeval tevent_common_loop_timer_delay(struct tevent_context *);
+
+struct tevent_signal *tevent_common_add_signal(struct tevent_context *ev,
+                                              TALLOC_CTX *mem_ctx,
+                                              int signum,
+                                              int sa_flags,
+                                              tevent_signal_handler_t handler,
+                                              void *private_data,
+                                              const char *handler_name,
+                                              const char *location);
+int tevent_common_check_signal(struct tevent_context *ev);
+
+bool tevent_standard_init(void);
+bool tevent_select_init(void);
+#ifdef HAVE_EPOLL
+bool tevent_epoll_init(void);
 #endif
-#if HAVE_LINUX_AIO
-bool events_aio_init(void);
+#ifdef HAVE_LINUX_AIO
+bool tevent_aio_init(void);
 #endif
index 3e72ce4943a603d653c3f552f379595bbc172e3f..cf4453f64fa649940e457ff2e66979310fedb143 100644 (file)
@@ -103,8 +103,8 @@ static int select_event_fd_destructor(struct tevent_fd *fde)
        DLIST_REMOVE(select_ev->fd_events, fde);
        select_ev->destruction_count++;
 
-       if (fde->flags & EVENT_FD_AUTOCLOSE) {
-               close(fde->fd);
+       if (fde->close_fn) {
+               fde->close_fn(ev, fde, fde->fd, fde->private_data);
                fde->fd = -1;
        }
 
@@ -116,9 +116,11 @@ static int select_event_fd_destructor(struct tevent_fd *fde)
   return NULL on failure (memory allocation error)
 */
 static struct tevent_fd *select_event_add_fd(struct tevent_context *ev, TALLOC_CTX *mem_ctx,
-                                        int fd, uint16_t flags,
-                                        event_fd_handler_t handler,
-                                        void *private_data)
+                                            int fd, uint16_t flags,
+                                            tevent_fd_handler_t handler,
+                                            void *private_data,
+                                            const char *handler_name,
+                                            const char *location)
 {
        struct select_event_context *select_ev = talloc_get_type(ev->additional_data,
                                                           struct select_event_context);
@@ -131,7 +133,10 @@ static struct tevent_fd *select_event_add_fd(struct tevent_context *ev, TALLOC_C
        fde->fd                 = fd;
        fde->flags              = flags;
        fde->handler            = handler;
+       fde->close_fn           = NULL;
        fde->private_data       = private_data;
+       fde->handler_name       = handler_name;
+       fde->location           = location;
        fde->additional_flags   = 0;
        fde->additional_data    = NULL;
 
@@ -144,31 +149,6 @@ static struct tevent_fd *select_event_add_fd(struct tevent_context *ev, TALLOC_C
        return fde;
 }
 
-
-/*
-  return the fd event flags
-*/
-static uint16_t select_event_get_fd_flags(struct tevent_fd *fde)
-{
-       return fde->flags;
-}
-
-/*
-  set the fd event flags
-*/
-static void select_event_set_fd_flags(struct tevent_fd *fde, uint16_t flags)
-{
-       struct tevent_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()
 */
@@ -189,16 +169,16 @@ static int select_event_loop_select(struct select_event_context *select_ev, stru
 
        /* setup any fd events */
        for (fde = select_ev->fd_events; fde; fde = fde->next) {
-               if (fde->flags & EVENT_FD_READ) {
+               if (fde->flags & TEVENT_FD_READ) {
                        FD_SET(fde->fd, &r_fds);
                }
-               if (fde->flags & EVENT_FD_WRITE) {
+               if (fde->flags & TEVENT_FD_WRITE) {
                        FD_SET(fde->fd, &w_fds);
                }
        }
 
        if (select_ev->ev->num_signal_handlers && 
-           common_event_check_signal(select_ev->ev)) {
+           tevent_common_check_signal(select_ev->ev)) {
                return 0;
        }
 
@@ -206,7 +186,7 @@ static int select_event_loop_select(struct select_event_context *select_ev, stru
 
        if (selrtn == -1 && errno == EINTR && 
            select_ev->ev->num_signal_handlers) {
-               common_event_check_signal(select_ev->ev);
+               tevent_common_check_signal(select_ev->ev);
                return 0;
        }
 
@@ -216,15 +196,15 @@ static int select_event_loop_select(struct select_event_context *select_ev, stru
                   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");
+               tevent_debug(select_ev->ev, TEVENT_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);
+               tevent_common_loop_timer_delay(select_ev->ev);
                return 0;
        }
 
@@ -235,8 +215,8 @@ static int select_event_loop_select(struct select_event_context *select_ev, stru
                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 (FD_ISSET(fde->fd, &r_fds)) flags |= TEVENT_FD_READ;
+                       if (FD_ISSET(fde->fd, &w_fds)) flags |= TEVENT_FD_WRITE;
                        if (flags) {
                                fde->handler(select_ev->ev, fde, flags, fde->private_data);
                                if (destruction_count != select_ev->destruction_count) {
@@ -258,7 +238,7 @@ static int select_event_loop_once(struct tevent_context *ev)
                                                           struct select_event_context);
        struct timeval tval;
 
-       tval = common_event_loop_timer_delay(ev);
+       tval = tevent_common_loop_timer_delay(ev);
        if (ev_timeval_is_zero(&tval)) {
                return 0;
        }
@@ -284,19 +264,19 @@ static int select_event_loop_wait(struct tevent_context *ev)
        return select_ev->exit_code;
 }
 
-static const struct event_ops select_event_ops = {
+static const struct tevent_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_timer      = common_event_add_timed,
-       .add_signal     = common_event_add_signal,
+       .set_fd_close_fn= tevent_common_fd_set_close_fn,
+       .get_fd_flags   = tevent_common_fd_get_flags,
+       .set_fd_flags   = tevent_common_fd_set_flags,
+       .add_timer      = tevent_common_add_timer,
+       .add_signal     = tevent_common_add_signal,
        .loop_once      = select_event_loop_once,
        .loop_wait      = select_event_loop_wait,
 };
 
-bool events_select_init(void)
+bool tevent_select_init(void)
 {
-       return event_register_backend("select", &select_event_ops);
+       return tevent_register_backend("select", &select_event_ops);
 }
-
index bb50480dd7f0cd4ca378e9b3d9c90de2f1d58481..031845927b957c2afeb743b04416a4637d238584 100644 (file)
    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 "system/wait.h"
 #include "tevent.h"
 #include "tevent_internal.h"
 #include "tevent_util.h"
@@ -46,7 +45,7 @@ struct sigcounter {
   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 tevent_signal *sig_handlers[NUM_SIGNALS+1];
        struct sigaction *oldact[NUM_SIGNALS+1];
        struct sigcounter signal_count[NUM_SIGNALS+1];
        struct sigcounter got_signal;
@@ -108,7 +107,7 @@ static void signal_handler_info(int signum, siginfo_t *info, void *uctx)
 /*
   destroy a signal event
 */
-static int signal_event_destructor(struct signal_event *se)
+static int tevent_signal_destructor(struct tevent_signal *se)
 {
        se->event_ctx->num_signal_handlers--;
        DLIST_REMOVE(sig_state->sig_handlers[se->signum], se);
@@ -141,14 +140,16 @@ static void signal_pipe_handler(struct tevent_context *ev, struct tevent_fd *fde
   add a signal event
   return NULL on failure (memory allocation error)
 */
-struct signal_event *common_event_add_signal(struct tevent_context *ev, 
-                                            TALLOC_CTX *mem_ctx,
-                                            int signum,
-                                            int sa_flags,
-                                            event_signal_handler_t handler, 
-                                            void *private_data) 
+struct tevent_signal *tevent_common_add_signal(struct tevent_context *ev,
+                                              TALLOC_CTX *mem_ctx,
+                                              int signum,
+                                              int sa_flags,
+                                              tevent_signal_handler_t handler,
+                                              void *private_data,
+                                              const char *handler_name,
+                                              const char *location)
 {
-       struct signal_event *se;
+       struct tevent_signal *se;
 
        if (signum >= NUM_SIGNALS) {
                return NULL;
@@ -163,15 +164,18 @@ struct signal_event *common_event_add_signal(struct tevent_context *ev,
                }
        }
 
-       se = talloc(mem_ctx?mem_ctx:ev, struct signal_event);
+       se = talloc(mem_ctx?mem_ctx:ev, struct tevent_signal);
        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;
-       
+       se->handler             = handler;
+       se->private_data        = private_data;
+       se->handler_name        = handler_name;
+       se->location            = location;
+       se->additional_data     = NULL;
+
        /* 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;
@@ -209,7 +213,7 @@ struct signal_event *common_event_add_signal(struct tevent_context *ev,
 
        DLIST_ADD(sig_state->sig_handlers[signum], se);
 
-       talloc_set_destructor(se, signal_event_destructor);
+       talloc_set_destructor(se, tevent_signal_destructor);
 
        /* we need to setup the pipe hack handler if not already
           setup */
@@ -220,8 +224,8 @@ struct signal_event *common_event_add_signal(struct tevent_context *ev,
                        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->pipe_fde = tevent_add_fd(ev, ev, sig_state->pipe_hack[0],
+                                            TEVENT_FD_READ, signal_pipe_handler, NULL);
        }
        ev->num_signal_handlers++;
 
@@ -233,7 +237,7 @@ struct signal_event *common_event_add_signal(struct tevent_context *ev,
   check if a signal is pending
   return != 0 if a signal was pending
 */
-int common_event_check_signal(struct tevent_context *ev)
+int tevent_common_check_signal(struct tevent_context *ev)
 {
        int i;
 
@@ -242,7 +246,7 @@ int common_event_check_signal(struct tevent_context *ev)
        }
        
        for (i=0;i<NUM_SIGNALS+1;i++) {
-               struct signal_event *se, *next;
+               struct tevent_signal *se, *next;
                struct sigcounter counter = sig_state->signal_count[i];
                uint32_t count = sig_count(counter);
 
index 1c99408b8df74cc00474ecce9f0224b01f135033..2a292a4c3966ed27b7440917c6ac2eb2d3f5ce21 100644 (file)
@@ -29,8 +29,7 @@
 
 #include "replace.h"
 #include "system/filesys.h"
-#include "system/network.h"
-#include "system/select.h" /* needed for HAVE_EVENTS_EPOLL */
+#include "system/select.h"
 #include "tevent.h"
 #include "tevent_util.h"
 #include "tevent_internal.h"
@@ -64,29 +63,29 @@ struct std_event_context {
 };
 
 /* use epoll if it is available */
-#if HAVE_EVENTS_EPOLL
+#if HAVE_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));
+       tevent_debug(std_ev->ev, TEVENT_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
+  map from TEVENT_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);
+       if (flags & TEVENT_FD_READ) ret |= (EPOLLIN | EPOLLERR | EPOLLHUP);
+       if (flags & TEVENT_FD_WRITE) ret |= (EPOLLOUT | EPOLLERR | EPOLLHUP);
        return ret;
 }
 
@@ -130,8 +129,8 @@ static void epoll_check_reopen(struct std_event_context *std_ev)
        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");
+               tevent_debug(std_ev->ev, TEVENT_DEBUG_FATAL,
+                            "Failed to recreate epoll handle after fork\n");
                return;
        }
        std_ev->pid = getpid();
@@ -166,7 +165,7 @@ static void epoll_add_event(struct std_event_context *std_ev, struct tevent_fd *
        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) {
+       if (fde->flags & TEVENT_FD_READ) {
                fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
        }
 }
@@ -209,7 +208,7 @@ static void epoll_mod_event(struct std_event_context *std_ev, struct tevent_fd *
        }
 
        /* only if we want to read we want to tell the event handler about errors */
-       if (fde->flags & EVENT_FD_READ) {
+       if (fde->flags & TEVENT_FD_READ) {
                fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
        }
 }
@@ -217,8 +216,8 @@ static void epoll_mod_event(struct std_event_context *std_ev, struct tevent_fd *
 static void epoll_change_event(struct std_event_context *std_ev, struct tevent_fd *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);
+       bool want_read = (fde->flags & TEVENT_FD_READ);
+       bool want_write= (fde->flags & TEVENT_FD_WRITE);
 
        if (std_ev->epoll_fd == -1) return;
 
@@ -266,14 +265,14 @@ static int epoll_event_loop(struct std_event_context *std_ev, struct timeval *tv
        }
 
        if (std_ev->ev->num_signal_handlers && 
-           common_event_check_signal(std_ev->ev)) {
+           tevent_common_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)) {
+               if (tevent_common_check_signal(std_ev->ev)) {
                        return 0;
                }
        }
@@ -285,7 +284,7 @@ static int epoll_event_loop(struct std_event_context *std_ev, struct timeval *tv
 
        if (ret == 0 && tvalp) {
                /* we don't care about a possible delay here */
-               common_event_loop_timer_delay(std_ev->ev);
+               tevent_common_loop_timer_delay(std_ev->ev);
                return 0;
        }
 
@@ -301,7 +300,7 @@ static int epoll_event_loop(struct std_event_context *std_ev, struct timeval *tv
                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
+                        * if we only wait for TEVENT_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
@@ -310,10 +309,10 @@ static int epoll_event_loop(struct std_event_context *std_ev, struct timeval *tv
                                epoll_del_event(std_ev, fde);
                                continue;
                        }
-                       flags |= EVENT_FD_READ;
+                       flags |= TEVENT_FD_READ;
                }
-               if (events[i].events & EPOLLIN) flags |= EVENT_FD_READ;
-               if (events[i].events & EPOLLOUT) flags |= EVENT_FD_WRITE;
+               if (events[i].events & EPOLLIN) flags |= TEVENT_FD_READ;
+               if (events[i].events & EPOLLOUT) flags |= TEVENT_FD_WRITE;
                if (flags) {
                        fde->handler(std_ev->ev, fde, flags, fde->private_data);
                        if (destruction_count != std_ev->destruction_count) {
@@ -392,8 +391,8 @@ static int std_event_fd_destructor(struct tevent_fd *fde)
 
        epoll_del_event(std_ev, fde);
 
-       if (fde->flags & EVENT_FD_AUTOCLOSE) {
-               close(fde->fd);
+       if (fde->close_fn) {
+               fde->close_fn(ev, fde, fde->fd, fde->private_data);
                fde->fd = -1;
        }
 
@@ -405,9 +404,11 @@ static int std_event_fd_destructor(struct tevent_fd *fde)
   return NULL on failure (memory allocation error)
 */
 static struct tevent_fd *std_event_add_fd(struct tevent_context *ev, TALLOC_CTX *mem_ctx,
-                                        int fd, uint16_t flags,
-                                        event_fd_handler_t handler,
-                                        void *private_data)
+                                         int fd, uint16_t flags,
+                                         tevent_fd_handler_t handler,
+                                         void *private_data,
+                                         const char *handler_name,
+                                         const char *location)
 {
        struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
                                                           struct std_event_context);
@@ -422,7 +423,10 @@ static struct tevent_fd *std_event_add_fd(struct tevent_context *ev, TALLOC_CTX
        fde->fd                 = fd;
        fde->flags              = flags;
        fde->handler            = handler;
+       fde->close_fn           = NULL;
        fde->private_data       = private_data;
+       fde->handler_name       = handler_name;
+       fde->location           = location;
        fde->additional_flags   = 0;
        fde->additional_data    = NULL;
 
@@ -438,15 +442,6 @@ static struct tevent_fd *std_event_add_fd(struct tevent_context *ev, TALLOC_CTX
        return fde;
 }
 
-
-/*
-  return the fd event flags
-*/
-static uint16_t std_event_get_fd_flags(struct tevent_fd *fde)
-{
-       return fde->flags;
-}
-
 /*
   set the fd event flags
 */
@@ -487,16 +482,16 @@ static int std_event_loop_select(struct std_event_context *std_ev, struct timeva
 
        /* setup any fd events */
        for (fde = std_ev->fd_events; fde; fde = fde->next) {
-               if (fde->flags & EVENT_FD_READ) {
+               if (fde->flags & TEVENT_FD_READ) {
                        FD_SET(fde->fd, &r_fds);
                }
-               if (fde->flags & EVENT_FD_WRITE) {
+               if (fde->flags & TEVENT_FD_WRITE) {
                        FD_SET(fde->fd, &w_fds);
                }
        }
 
        if (std_ev->ev->num_signal_handlers && 
-           common_event_check_signal(std_ev->ev)) {
+           tevent_common_check_signal(std_ev->ev)) {
                return 0;
        }
 
@@ -504,7 +499,7 @@ static int std_event_loop_select(struct std_event_context *std_ev, struct timeva
 
        if (selrtn == -1 && errno == EINTR && 
            std_ev->ev->num_signal_handlers) {
-               common_event_check_signal(std_ev->ev);
+               tevent_common_check_signal(std_ev->ev);
                return 0;
        }
 
@@ -514,15 +509,15 @@ static int std_event_loop_select(struct std_event_context *std_ev, struct timeva
                   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");
+               tevent_debug(std_ev->ev, TEVENT_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);
+               tevent_common_loop_timer_delay(std_ev->ev);
                return 0;
        }
 
@@ -533,8 +528,8 @@ static int std_event_loop_select(struct std_event_context *std_ev, struct timeva
                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 (FD_ISSET(fde->fd, &r_fds)) flags |= TEVENT_FD_READ;
+                       if (FD_ISSET(fde->fd, &w_fds)) flags |= TEVENT_FD_WRITE;
                        if (flags) {
                                fde->handler(std_ev->ev, fde, flags, fde->private_data);
                                if (destruction_count != std_ev->destruction_count) {
@@ -556,7 +551,7 @@ static int std_event_loop_once(struct tevent_context *ev)
                                                           struct std_event_context);
        struct timeval tval;
 
-       tval = common_event_loop_timer_delay(ev);
+       tval = tevent_common_loop_timer_delay(ev);
        if (ev_timeval_is_zero(&tval)) {
                return 0;
        }
@@ -588,20 +583,21 @@ static int std_event_loop_wait(struct tevent_context *ev)
        return std_ev->exit_code;
 }
 
-static const struct event_ops std_event_ops = {
+static const struct tevent_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_close_fn= tevent_common_fd_set_close_fn,
+       .get_fd_flags   = tevent_common_fd_get_flags,
        .set_fd_flags   = std_event_set_fd_flags,
-       .add_timer      = common_event_add_timed,
-       .add_signal     = common_event_add_signal,
+       .add_timer      = tevent_common_add_timer,
+       .add_signal     = tevent_common_add_signal,
        .loop_once      = std_event_loop_once,
        .loop_wait      = std_event_loop_wait,
 };
 
 
-bool events_standard_init(void)
+bool tevent_standard_init(void)
 {
-       return event_register_backend("standard", &std_event_ops);
+       return tevent_register_backend("standard", &std_event_ops);
 }
 
index ce3fc8eb0060187333f467d035635443f5ef675d..dadd360416419e745338c8564ca02244b788b84d 100644 (file)
    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 "system/time.h"
 #include "tevent.h"
 #include "tevent_internal.h"
 #include "tevent_util.h"
@@ -109,7 +106,7 @@ bool ev_timeval_is_zero(const struct timeval *tv)
 /*
   destroy a timed event
 */
-static int common_event_timed_destructor(struct tevent_timer *te)
+static int tevent_common_timed_destructor(struct tevent_timer *te)
 {
        struct tevent_context *ev = talloc_get_type(te->event_ctx,
                                                   struct tevent_context);
@@ -117,7 +114,7 @@ static int common_event_timed_destructor(struct tevent_timer *te)
        return 0;
 }
 
-static int common_event_timed_deny_destructor(struct tevent_timer *te)
+static int tevent_common_timed_deny_destructor(struct tevent_timer *te)
 {
        return -1;
 }
@@ -126,10 +123,12 @@ static int common_event_timed_deny_destructor(struct tevent_timer *te)
   add a timed event
   return NULL on failure (memory allocation error)
 */
-struct tevent_timer *common_event_add_timed(struct tevent_context *ev, TALLOC_CTX *mem_ctx,
-                                          struct timeval next_event, 
-                                          event_timed_handler_t handler, 
-                                          void *private_data) 
+struct tevent_timer *tevent_common_add_timer(struct tevent_context *ev, TALLOC_CTX *mem_ctx,
+                                            struct timeval next_event,
+                                            tevent_timer_handler_t handler,
+                                            void *private_data,
+                                            const char *handler_name,
+                                            const char *location)
 {
        struct tevent_timer *te, *last_te, *cur_te;
 
@@ -140,6 +139,8 @@ struct tevent_timer *common_event_add_timed(struct tevent_context *ev, TALLOC_CT
        te->next_event          = next_event;
        te->handler             = handler;
        te->private_data        = private_data;
+       te->handler_name        = handler_name;
+       te->location            = location;
        te->additional_data     = NULL;
 
        /* keep the list ordered */
@@ -155,7 +156,7 @@ struct tevent_timer *common_event_add_timed(struct tevent_context *ev, TALLOC_CT
 
        DLIST_ADD_AFTER(ev->timer_events, te, last_te);
 
-       talloc_set_destructor(te, common_event_timed_destructor);
+       talloc_set_destructor(te, tevent_common_timed_destructor);
 
        return te;
 }
@@ -166,7 +167,7 @@ struct tevent_timer *common_event_add_timed(struct tevent_context *ev, TALLOC_CT
   return the delay untill the next timed event,
   or zero if a timed event was triggered
 */
-struct timeval common_event_loop_timer_delay(struct tevent_context *ev)
+struct timeval tevent_common_loop_timer_delay(struct tevent_context *ev)
 {
        struct timeval current_time = ev_timeval_zero();
        struct tevent_timer *te = ev->timer_events;
@@ -203,7 +204,7 @@ struct timeval common_event_loop_timer_delay(struct tevent_context *ev)
         */
 
        /* deny the handler to free the event */
-       talloc_set_destructor(te, common_event_timed_deny_destructor);
+       talloc_set_destructor(te, tevent_common_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
index 87d4bfd712f855768fdc0af8eda8853093ef49be..7ca7444c92703f2d2d903611d62181d23d94ecad 100644 (file)
@@ -19,6 +19,7 @@ struct named_pipe_auth_req {
 }/* [gensize,public] */;
 
 union named_pipe_auth_rep_info {
+       int _dummy_element;
 }/* [switch_type(uint32)] */;
 
 struct named_pipe_auth_rep {
index 921af15daebacb9468718a3c8c73f8579cfe2258..97f75051b7e713a9c99deb688ae8b355a509a4a2 100644 (file)
@@ -757,7 +757,7 @@ _PUBLIC_ void ndr_print_array_uint8(struct ndr_print *ndr, const char *name,
        ndr->depth++;
        for (i=0;i<count;i++) {
                char *idx=NULL;
-               if (asprintf(&idx, "[%d]", i) == -1) {
+               if (asprintf(&idx, "[%d]", i) != -1) {
                        ndr_print_uint8(ndr, idx, data[i]);
                        free(idx);
                }
index 92030fcd6b73a582e70f9ac1db8efa51a2479909..f674e8386c947a389c07a7bc8c2e407593cae0c7 100644 (file)
@@ -178,12 +178,6 @@ fi
 make CFLAGS="$RPM_OPT_FLAGS -D_GNU_SOURCE" %{?_smp_mflags} \
        all modules pam_smbpass
 
-## build the cifs fs mount helper
-cd client
-gcc  -o mount.cifs $RPM_OPT_FLAGS  -D_GNU_SOURCE -Wall -D_GNU_SOURCE -D_LARGEFILE64_SOURCE mount.cifs.c
-gcc  -o umount.cifs $RPM_OPT_FLAGS  -D_GNU_SOURCE -Wall -D_GNU_SOURCE -D_LARGEFILE64_SOURCE umount.cifs.c
-cd ..
-
 # Remove some permission bits to avoid to many dependencies
 cd ..
 find examples docs -type f | xargs -r chmod -x
@@ -238,8 +232,8 @@ install -m644 setup/samba.pamd $RPM_BUILD_ROOT%{_sysconfdir}/pam.d/samba
 install -m755 setup/smbprint $RPM_BUILD_ROOT%{_bindir}
 install -m644 setup/smbusers $RPM_BUILD_ROOT%{_sysconfdir}/samba/smbusers
 install -m644 setup/smb.conf $RPM_BUILD_ROOT%{_sysconfdir}/samba/smb.conf
-install -m755 source/client/mount.cifs $RPM_BUILD_ROOT/sbin/mount.cifs
-install -m755 source/client/umount.cifs $RPM_BUILD_ROOT/sbin/umount.cifs
+install -m755 source/bin/mount.cifs $RPM_BUILD_ROOT/sbin/mount.cifs
+install -m755 source/bin/umount.cifs $RPM_BUILD_ROOT/sbin/umount.cifs
 install -m755 source/script/mksmbpasswd.sh $RPM_BUILD_ROOT%{_bindir}
 
 /bin/rm $RPM_BUILD_ROOT%{_sbindir}/*mount.cifs
index 94e1efbfe4925a201c17643b3ea3e28821b103e6..0411466c8251bf55f7adbe97113347ac97d62390 100644 (file)
@@ -183,14 +183,20 @@ sub HeaderUnion($$;$)
        return if (not defined($union->{ELEMENTS}));
        pidl " {\n";
        $tab_depth++;
+       my $needed = 0;
        foreach my $e (@{$union->{ELEMENTS}}) {
                if ($e->{TYPE} ne "EMPTY") {
                        if (! defined $done{$e->{NAME}}) {
                                HeaderElement($e);
                        }
                        $done{$e->{NAME}} = 1;
+                       $needed++;
                }
        }
+       if (!$needed) {
+               # sigh - some compilers don't like empty structures
+               pidl tabs()."int _dummy_element;\n";
+       }
        $tab_depth--;
        pidl "}";
 
index 49f576f507c19cd783f9c7c8cc6f65b3c21b1e17..c13f5ae20a8eddca80fa4e1064e43061a1d23d22 100644 (file)
@@ -930,6 +930,7 @@ SMBTORTURE_OBJ1 = torture/torture.o torture/nbio.o torture/scanner.o torture/uta
 
 SMBTORTURE_OBJ = $(SMBTORTURE_OBJ1) $(PARAM_OBJ) \
        $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) \
+       lib/wb_reqtrans.o lib/wbclient.o \
        $(LIBNDR_GEN_OBJ0)
 
 MASKTEST_OBJ = torture/masktest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
@@ -1029,7 +1030,6 @@ IDMAP_ADEX_OBJ = \
 
 WINBINDD_OBJ1 = \
                winbindd/winbindd.o       \
-               winbindd/winbindd_reqtrans.o \
                winbindd/winbindd_user.o  \
                winbindd/winbindd_group.o \
                winbindd/winbindd_util.o  \
index 61316a8f70cd8c22bda7d6a3badf14200ff1bbe3..1a33eb22cc467b823ef807e1b474825102f0cf64 100755 (executable)
@@ -4,11 +4,11 @@
 
 while true; do
     case $1 in
-       (--version-file)
+       --version-file)
            VERSION_FILE=$2
            shift 2
            ;;
-       (*)
+       *)
            break
            ;;
     esac
index c63921aa1afa64bd167d464bc7a269067b451877..529f21ab302d649d9dc0d475d3f40d9d8f15b77f 100644 (file)
@@ -78,6 +78,7 @@ static bool showacls = false;
 bool lowercase = false;
 
 static struct sockaddr_storage dest_ss;
+static char dest_ss_str[INET6_ADDRSTRLEN];
 
 #define SEPARATORS " \t\n\r"
 
@@ -4043,7 +4044,8 @@ static int process_command_string(const char *cmd_in)
        /* establish the connection if not already */
 
        if (!cli) {
-               cli = cli_cm_open(talloc_tos(), NULL, desthost,
+               cli = cli_cm_open(talloc_tos(), NULL,
+                               have_ip ? dest_ss_str : desthost,
                                service, true, smb_encrypt);
                if (!cli) {
                        return 1;
@@ -4508,7 +4510,8 @@ static int process(const char *base_directory)
        int rc = 0;
 
        cli = cli_cm_open(talloc_tos(), NULL,
-                       desthost, service, true, smb_encrypt);
+                       have_ip ? dest_ss_str : desthost,
+                       service, true, smb_encrypt);
        if (!cli) {
                return 1;
        }
@@ -4586,7 +4589,8 @@ static int do_tar_op(const char *base_directory)
        /* do we already have a connection? */
        if (!cli) {
                cli = cli_cm_open(talloc_tos(), NULL,
-                       desthost, service, true, smb_encrypt);
+                       have_ip ? dest_ss_str : desthost,
+                       service, true, smb_encrypt);
                if (!cli)
                        return 1;
        }
@@ -4792,8 +4796,7 @@ static int do_message_op(struct user_auth_info *auth_info)
                                        exit(1);
                                }
                                have_ip = true;
-
-                               cli_cm_set_dest_ss(&dest_ss);
+                               print_sockaddr(dest_ss_str, sizeof(dest_ss_str), &dest_ss);
                        }
                        break;
                case 'E':
index 14a30696c4d0c906ccf404b54573e3449bdb021d..1b8dbf33468b0567a23651de2841c161df52e081 100644 (file)
@@ -96,13 +96,6 @@ struct async_req {
         **/
        NTSTATUS status;
 
-       /**
-        * @brief The event context we are using
-        *
-        * The event context that this async request works on.
-        */
-       struct event_context *event_ctx;
-
        /**
         * @brief What to do on completion
         *
@@ -122,7 +115,7 @@ struct async_req {
        } async;
 };
 
-struct async_req *async_req_new(TALLOC_CTX *mem_ctx, struct event_context *ev);
+struct async_req *async_req_new(TALLOC_CTX *mem_ctx);
 
 char *async_req_print(TALLOC_CTX *mem_ctx, struct async_req *req);
 
@@ -130,7 +123,8 @@ void async_req_done(struct async_req *req);
 
 void async_req_error(struct async_req *req, NTSTATUS status);
 
-bool async_post_status(struct async_req *req, NTSTATUS status);
+bool async_post_status(struct async_req *req, struct event_context *ev,
+                      NTSTATUS status);
 
 bool async_req_nomem(const void *p, struct async_req *req);
 
@@ -138,4 +132,22 @@ bool async_req_is_error(struct async_req *req, NTSTATUS *status);
 
 NTSTATUS async_req_simple_recv(struct async_req *req);
 
+bool async_req_set_timeout(struct async_req *req, struct event_context *ev,
+                          struct timeval to);
+
+struct async_req *async_wait_send(TALLOC_CTX *mem_ctx,
+                                 struct event_context *ev,
+                                 struct timeval to);
+
+NTSTATUS async_wait_recv(struct async_req *req);
+
+struct async_req_queue;
+
+struct async_req_queue *async_req_queue_init(TALLOC_CTX *mem_ctx);
+
+bool async_req_enqueue(struct async_req_queue *queue,
+                      struct event_context *ev,
+                      struct async_req *req,
+                      void (*trigger)(struct async_req *req));
+
 #endif
index f0cd5fdaa4e9ada828c29b63d7f6c31521160654..c6f95d64d551a201974b8155236a92abc8134bfb 100644 (file)
@@ -24,7 +24,7 @@
 
 ssize_t async_syscall_result_ssize_t(struct async_req *req, int *perrno);
 size_t async_syscall_result_size_t(struct async_req *req, int *perrno);
-ssize_t async_syscall_result_int(struct async_req *req, int *perrno);
+int async_syscall_result_int(struct async_req *req, int *perrno);
 
 struct async_req *async_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
                             int fd, const void *buffer, size_t length,
@@ -32,9 +32,11 @@ struct async_req *async_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
 struct async_req *async_recv(TALLOC_CTX *mem_ctx, struct event_context *ev,
                             int fd, void *buffer, size_t length,
                             int flags);
-struct async_req *async_connect(TALLOC_CTX *mem_ctx, struct event_context *ev,
-                               int fd, const struct sockaddr *address,
-                               socklen_t address_len);
+struct async_req *async_connect_send(TALLOC_CTX *mem_ctx,
+                                    struct event_context *ev,
+                                    int fd, const struct sockaddr *address,
+                                    socklen_t address_len);
+NTSTATUS async_connect_recv(struct async_req *req, int *perrno);
 
 struct async_req *sendall_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
                               int fd, const void *buffer, size_t length,
index 05974da8fc59e5a23ff1d7f52fb267e8caf925a3..03331da7503d64abb571df9c20f8f0c6b0347258 100644 (file)
@@ -44,12 +44,14 @@ NTSTATUS packet_fd_read_sync(struct packet_context *ctx);
  * Handle an incoming packet:
  * Return False if none is available
  * Otherwise return True and store the callback result in *status
+ * Callback must either talloc_move or talloc_free buf
  */
 bool packet_handler(struct packet_context *ctx,
-                   bool (*full_req)(const DATA_BLOB *data,
+                   bool (*full_req)(const uint8_t *buf,
+                                    size_t available,
                                     size_t *length,
                                     void *private_data),
-                   NTSTATUS (*callback)(const DATA_BLOB *data,
+                   NTSTATUS (*callback)(uint8_t *buf, size_t length,
                                         void *private_data),
                    void *private_data,
                    NTSTATUS *status);
index e1e98eb125f64d59606c7c3f9dbd85c1f0653efd..09f12ceb86ef1cf44d0fe48f4fddfd91de227aae 100644 (file)
@@ -1457,10 +1457,21 @@ int open_socket_in(int type,
                int dlevel,
                const struct sockaddr_storage *psock,
                bool rebind);
-int open_socket_out(int type,
-               const struct sockaddr_storage *pss,
-               uint16_t port,
-               int timeout);
+NTSTATUS open_socket_out(const struct sockaddr_storage *pss, uint16_t port,
+                        int timeout, int *pfd);
+struct async_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
+                                      struct event_context *ev,
+                                      const struct sockaddr_storage *pss,
+                                      uint16_t port,
+                                      int timeout);
+NTSTATUS open_socket_out_recv(struct async_req *req, int *pfd);
+struct async_req *open_socket_out_defer_send(TALLOC_CTX *mem_ctx,
+                                            struct event_context *ev,
+                                            struct timeval wait_time,
+                                            const struct sockaddr_storage *pss,
+                                            uint16_t port,
+                                            int timeout);
+NTSTATUS open_socket_out_defer_recv(struct async_req *req, int *pfd);
 bool open_any_socket_out(struct sockaddr_storage *addrs, int num_addrs,
                         int timeout, int *fd_index, int *fd);
 int open_udp_socket(const char *host, int port);
@@ -7970,4 +7981,14 @@ NTSTATUS idmap_sid_to_gid(const char *domname, DOM_SID *sid, gid_t *gid);
 
 NTSTATUS nss_info_template_init( void );
 
+/* Misc protos */
+
+struct async_req *wb_trans_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
+                               struct wb_context *wb_ctx, bool need_priv,
+                               const struct winbindd_request *wb_req);
+NTSTATUS wb_trans_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
+                      struct winbindd_response **presponse);
+struct wb_context *wb_context_init(TALLOC_CTX *mem_ctx);
+
+
 #endif /*  _PROTO_H_  */
index a8a2d981543fa58b3b0207049444630543092f74..7fd4fbb553cc2a9974d31b2f16946e306ff38097 100644 (file)
@@ -27,7 +27,7 @@
 #define _SMB_H
 
 /* logged when starting the various Samba daemons */
-#define COPYRIGHT_STARTUP_MESSAGE      "Copyright Andrew Tridgell and the Samba Team 1992-2008"
+#define COPYRIGHT_STARTUP_MESSAGE      "Copyright Andrew Tridgell and the Samba Team 1992-2009"
 
 
 #if defined(LARGE_SMB_OFF_T)
@@ -369,6 +369,7 @@ struct share_mode_entry;
 struct uuid;
 struct named_mutex;
 struct pcap_cache;
+struct wb_context;
 
 struct vfs_fsp_data {
     struct vfs_fsp_data *next;
index 159666f15c874abbf0ac859afc019e7b0459ec90..ac06df65a3ab92e400be12e3e4b425b7b8026a11 100644 (file)
@@ -49,7 +49,7 @@ char *async_req_print(TALLOC_CTX *mem_ctx, struct async_req *req)
  * The new async request will be initialized in state ASYNC_REQ_IN_PROGRESS
  */
 
-struct async_req *async_req_new(TALLOC_CTX *mem_ctx, struct event_context *ev)
+struct async_req *async_req_new(TALLOC_CTX *mem_ctx)
 {
        struct async_req *result;
 
@@ -58,7 +58,6 @@ struct async_req *async_req_new(TALLOC_CTX *mem_ctx, struct event_context *ev)
                return NULL;
        }
        result->state = ASYNC_REQ_IN_PROGRESS;
-       result->event_ctx = ev;
        result->print = async_req_print;
        return result;
 }
@@ -135,12 +134,12 @@ static void async_trigger(struct event_context *ev, struct timed_event *te,
  * conventions, independent of whether the request was actually deferred.
  */
 
-bool async_post_status(struct async_req *req, NTSTATUS status)
+bool async_post_status(struct async_req *req, struct event_context *ev,
+                      NTSTATUS status)
 {
        req->status = status;
 
-       if (event_add_timed(req->event_ctx, req, timeval_zero(),
-                           "async_trigger",
+       if (event_add_timed(ev, req, timeval_zero(), "async_trigger",
                            async_trigger, req) == NULL) {
                return false;
        }
@@ -195,3 +194,123 @@ NTSTATUS async_req_simple_recv(struct async_req *req)
        }
        return NT_STATUS_OK;
 }
+
+static void async_req_timedout(struct event_context *ev,
+                              struct timed_event *te,
+                              const struct timeval *now,
+                              void *priv)
+{
+       struct async_req *req = talloc_get_type_abort(
+               priv, struct async_req);
+       TALLOC_FREE(te);
+       async_req_error(req, NT_STATUS_IO_TIMEOUT);
+}
+
+bool async_req_set_timeout(struct async_req *req, struct event_context *ev,
+                          struct timeval to)
+{
+       return (event_add_timed(ev, req,
+                               timeval_current_ofs(to.tv_sec, to.tv_usec),
+                               "async_req_timedout", async_req_timedout, req)
+               != NULL);
+}
+
+struct async_req *async_wait_send(TALLOC_CTX *mem_ctx,
+                                 struct event_context *ev,
+                                 struct timeval to)
+{
+       struct async_req *result;
+
+       result = async_req_new(mem_ctx);
+       if (result == NULL) {
+               return result;
+       }
+       if (!async_req_set_timeout(result, ev, to)) {
+               TALLOC_FREE(result);
+               return NULL;
+       }
+       return result;
+}
+
+NTSTATUS async_wait_recv(struct async_req *req)
+{
+       return NT_STATUS_OK;
+}
+
+struct async_queue_entry {
+       struct async_queue_entry *prev, *next;
+       struct async_req_queue *queue;
+       struct async_req *req;
+       void (*trigger)(struct async_req *req);
+};
+
+struct async_req_queue {
+       struct async_queue_entry *queue;
+};
+
+struct async_req_queue *async_req_queue_init(TALLOC_CTX *mem_ctx)
+{
+       return TALLOC_ZERO_P(mem_ctx, struct async_req_queue);
+}
+
+static int async_queue_entry_destructor(struct async_queue_entry *e)
+{
+       struct async_req_queue *queue = e->queue;
+
+       DLIST_REMOVE(queue->queue, e);
+
+       if (queue->queue != NULL) {
+               queue->queue->trigger(queue->queue->req);
+       }
+
+       return 0;
+}
+
+static void async_req_immediate_trigger(struct event_context *ev,
+                                       struct timed_event *te,
+                                       const struct timeval *now,
+                                       void *priv)
+{
+       struct async_queue_entry *e = talloc_get_type_abort(
+               priv, struct async_queue_entry);
+
+       TALLOC_FREE(te);
+       e->trigger(e->req);
+}
+
+bool async_req_enqueue(struct async_req_queue *queue, struct event_context *ev,
+                      struct async_req *req,
+                      void (*trigger)(struct async_req *req))
+{
+       struct async_queue_entry *e;
+       bool busy;
+
+       busy = (queue->queue != NULL);
+
+       e = talloc(req, struct async_queue_entry);
+       if (e == NULL) {
+               return false;
+       }
+
+       e->req = req;
+       e->trigger = trigger;
+       e->queue = queue;
+
+       DLIST_ADD_END(queue->queue, e, struct async_queue_entry *);
+       talloc_set_destructor(e, async_queue_entry_destructor);
+
+       if (!busy) {
+               struct timed_event *te;
+
+               te = event_add_timed(ev, e, timeval_zero(),
+                                    "async_req_immediate_trigger",
+                                    async_req_immediate_trigger,
+                                    e);
+               if (te == NULL) {
+                       TALLOC_FREE(e);
+                       return false;
+               }
+       }
+
+       return true;
+}
index 225cc7b195e38ff2599ce603fb5ddfd5544f2480..bb89a1353ae4b21e8b3ccacd88c93c0e93689eda 100644 (file)
@@ -106,7 +106,7 @@ static struct async_req *async_syscall_new(TALLOC_CTX *mem_ctx,
        struct async_req *result;
        struct async_syscall_state *state;
 
-       result = async_req_new(mem_ctx, ev);
+       result = async_req_new(mem_ctx);
        if (result == NULL) {
                return NULL;
        }
@@ -209,7 +209,7 @@ size_t async_syscall_result_size_t(struct async_req *req, int *perrno)
  * @retval The return value from the asynchronously called syscall
  */
 
-ssize_t async_syscall_result_int(struct async_req *req, int *perrno)
+int async_syscall_result_int(struct async_req *req, int *perrno)
 {
        struct async_syscall_state *state = talloc_get_type_abort(
                req->private_data, struct async_syscall_state);
@@ -236,7 +236,10 @@ static void async_send_callback(struct event_context *ev,
                req->private_data, struct async_syscall_state);
        struct param_send *p = &state->param.param_send;
 
-       SMB_ASSERT(state->syscall_type == ASYNC_SYSCALL_SEND);
+       if (state->syscall_type != ASYNC_SYSCALL_SEND) {
+               async_req_error(req, NT_STATUS_INTERNAL_ERROR);
+               return;
+       }
 
        state->result.result_ssize_t = send(p->fd, p->buffer, p->length,
                                            p->flags);
@@ -300,7 +303,10 @@ static void async_sendall_callback(struct event_context *ev,
                req->private_data, struct async_syscall_state);
        struct param_sendall *p = &state->param.param_sendall;
 
-       SMB_ASSERT(state->syscall_type == ASYNC_SYSCALL_SENDALL);
+       if (state->syscall_type != ASYNC_SYSCALL_SENDALL) {
+               async_req_error(req, NT_STATUS_INTERNAL_ERROR);
+               return;
+       }
 
        state->result.result_ssize_t = send(p->fd, (char *)p->buffer + p->sent,
                                            p->length - p->sent, p->flags);
@@ -317,7 +323,10 @@ static void async_sendall_callback(struct event_context *ev,
        }
 
        p->sent += state->result.result_ssize_t;
-       SMB_ASSERT(p->sent <= p->length);
+       if (p->sent > p->length) {
+               async_req_error(req, NT_STATUS_INTERNAL_ERROR);
+               return;
+       }
 
        if (p->sent == p->length) {
                TALLOC_FREE(state->fde);
@@ -385,7 +394,10 @@ static void async_recv_callback(struct event_context *ev,
                req->private_data, struct async_syscall_state);
        struct param_recv *p = &state->param.param_recv;
 
-       SMB_ASSERT(state->syscall_type == ASYNC_SYSCALL_RECV);
+       if (state->syscall_type != ASYNC_SYSCALL_RECV) {
+               async_req_error(req, NT_STATUS_INTERNAL_ERROR);
+               return;
+       }
 
        state->result.result_ssize_t = recv(p->fd, p->buffer, p->length,
                                            p->flags);
@@ -450,7 +462,10 @@ static void async_recvall_callback(struct event_context *ev,
                req->private_data, struct async_syscall_state);
        struct param_recvall *p = &state->param.param_recvall;
 
-       SMB_ASSERT(state->syscall_type == ASYNC_SYSCALL_RECVALL);
+       if (state->syscall_type != ASYNC_SYSCALL_RECVALL) {
+               async_req_error(req, NT_STATUS_INTERNAL_ERROR);
+               return;
+       }
 
        state->result.result_ssize_t = recv(p->fd,
                                            (char *)p->buffer + p->received,
@@ -468,7 +483,10 @@ static void async_recvall_callback(struct event_context *ev,
        }
 
        p->received += state->result.result_ssize_t;
-       SMB_ASSERT(p->received <= p->length);
+       if (p->received > p->length) {
+               async_req_error(req, NT_STATUS_INTERNAL_ERROR);
+               return;
+       }
 
        if (p->received == p->length) {
                TALLOC_FREE(state->fde);
@@ -517,60 +535,16 @@ NTSTATUS recvall_recv(struct async_req *req)
        return async_req_simple_recv(req);
 }
 
-/**
- * fde event handler for connect(2)
- * @param[in] ev       The event context that sent us here
- * @param[in] fde      The file descriptor event associated with the connect
- * @param[in] flags    Indicate read/writeability of the socket
- * @param[in] priv     private data, "struct async_req *" in this case
- */
-
-static void async_connect_callback(struct event_context *ev,
-                                  struct fd_event *fde, uint16_t flags,
-                                  void *priv)
-{
-       struct async_req *req = talloc_get_type_abort(
-               priv, struct async_req);
-       struct async_syscall_state *state = talloc_get_type_abort(
-               req->private_data, struct async_syscall_state);
-       struct param_connect *p = &state->param.param_connect;
-
-       SMB_ASSERT(state->syscall_type == ASYNC_SYSCALL_CONNECT);
-
-       TALLOC_FREE(state->fde);
-
-       /*
-        * Stevens, Network Programming says that if there's a
-        * successful connect, the socket is only writable. Upon an
-        * error, it's both readable and writable.
-        */
-       if ((flags & (EVENT_FD_READ|EVENT_FD_WRITE))
-           == (EVENT_FD_READ|EVENT_FD_WRITE)) {
-               int sockerr;
-               socklen_t err_len = sizeof(sockerr);
-
-               if (getsockopt(p->fd, SOL_SOCKET, SO_ERROR,
-                              (void *)&sockerr, &err_len) == 0) {
-                       errno = sockerr;
-               }
-
-               state->sys_errno = errno;
-
-               DEBUG(10, ("connect returned %s\n", strerror(errno)));
-
-               sys_fcntl_long(p->fd, F_SETFL, p->old_sockflags);
-
-               async_req_error(req, map_nt_error_from_unix(state->sys_errno));
-               return;
-       }
-
-       sys_fcntl_long(p->fd, F_SETFL, p->old_sockflags);
-
-       state->result.result_int = 0;
-       state->sys_errno = 0;
+struct async_connect_state {
+       int fd;
+       int result;
+       int sys_errno;
+       long old_sockflags;
+};
 
-       async_req_done(req);
-}
+static void async_connect_connected(struct event_context *ev,
+                                   struct fd_event *fde, uint16_t flags,
+                                   void *priv);
 
 /**
  * @brief async version of connect(2)
@@ -585,47 +559,46 @@ static void async_connect_callback(struct event_context *ev,
  * connect in an async state. This will be reset when the request is finished.
  */
 
-struct async_req *async_connect(TALLOC_CTX *mem_ctx, struct event_context *ev,
-                               int fd, const struct sockaddr *address,
-                               socklen_t address_len)
+struct async_req *async_connect_send(TALLOC_CTX *mem_ctx,
+                                    struct event_context *ev,
+                                    int fd, const struct sockaddr *address,
+                                    socklen_t address_len)
 {
        struct async_req *result;
-       struct async_syscall_state *state;
-       struct param_connect *p;
+       struct async_connect_state *state;
+       struct fd_event *fde;
+       NTSTATUS status;
 
-       result = async_syscall_new(mem_ctx, ev, ASYNC_SYSCALL_CONNECT, &state);
+       result = async_req_new(mem_ctx);
        if (result == NULL) {
                return NULL;
        }
-       p = &state->param.param_connect;
+       state = talloc(result, struct async_connect_state);
+       if (state == NULL) {
+               goto fail;
+       }
+       result->private_data = state;
 
        /**
         * We have to set the socket to nonblocking for async connect(2). Keep
         * the old sockflags around.
         */
 
-       p->old_sockflags = sys_fcntl_long(fd, F_GETFL, 0);
+       state->fd = fd;
+       state->sys_errno = 0;
 
-       if (p->old_sockflags == -1) {
-               if (async_post_status(result, map_nt_error_from_unix(errno))) {
-                       return result;
-               }
-               TALLOC_FREE(result);
-               return NULL;
+       state->old_sockflags = sys_fcntl_long(fd, F_GETFL, 0);
+       if (state->old_sockflags == -1) {
+               goto post_errno;
        }
 
-       set_blocking(fd, true);
+       set_blocking(fd, false);
 
-       state->result.result_int = connect(fd, address, address_len);
-
-       if (state->result.result_int == 0) {
+       state->result = connect(fd, address, address_len);
+       if (state->result == 0) {
                state->sys_errno = 0;
-               if (async_post_status(result, NT_STATUS_OK)) {
-                       return result;
-               }
-               sys_fcntl_long(fd, F_SETFL, p->old_sockflags);
-               TALLOC_FREE(result);
-               return NULL;
+               status = NT_STATUS_OK;
+               goto post_status;
        }
 
        /**
@@ -640,31 +613,93 @@ struct async_req *async_connect(TALLOC_CTX *mem_ctx, struct event_context *ev,
              errno == EISCONN ||
 #endif
              errno == EAGAIN || errno == EINTR)) {
+               goto post_errno;
+       }
 
-               state->sys_errno = errno;
-
-               if (async_post_status(result, map_nt_error_from_unix(errno))) {
-                       return result;
-               }
-               sys_fcntl_long(fd, F_SETFL, p->old_sockflags);
-               TALLOC_FREE(result);
-               return NULL;
+       fde = event_add_fd(ev, state, fd, EVENT_FD_READ | EVENT_FD_WRITE,
+                          async_connect_connected, result);
+       if (fde == NULL) {
+               status = NT_STATUS_NO_MEMORY;
+               goto post_status;
        }
+       return result;
 
-       state->fde = event_add_fd(ev, state, fd,
-                                 EVENT_FD_READ | EVENT_FD_WRITE,
-                                 async_connect_callback, result);
-       if (state->fde == NULL) {
-               sys_fcntl_long(fd, F_SETFL, p->old_sockflags);
-               TALLOC_FREE(result);
-               return NULL;
+ post_errno:
+       state->sys_errno = errno;
+       status = map_nt_error_from_unix(state->sys_errno);
+ post_status:
+       sys_fcntl_long(fd, F_SETFL, state->old_sockflags);
+       if (!async_post_status(result, ev, status)) {
+               goto fail;
        }
-       result->private_data = state;
+       return result;
+ fail:
+       TALLOC_FREE(result);
+       return NULL;
+}
+
+/**
+ * fde event handler for connect(2)
+ * @param[in] ev       The event context that sent us here
+ * @param[in] fde      The file descriptor event associated with the connect
+ * @param[in] flags    Indicate read/writeability of the socket
+ * @param[in] priv     private data, "struct async_req *" in this case
+ */
 
-       state->param.param_connect.fd = fd;
-       state->param.param_connect.address = address;
-       state->param.param_connect.address_len = address_len;
+static void async_connect_connected(struct event_context *ev,
+                                   struct fd_event *fde, uint16_t flags,
+                                   void *priv)
+{
+       struct async_req *req = talloc_get_type_abort(
+               priv, struct async_req);
+       struct async_connect_state *state = talloc_get_type_abort(
+               req->private_data, struct async_connect_state);
 
-       return result;
+       TALLOC_FREE(fde);
+
+       /*
+        * Stevens, Network Programming says that if there's a
+        * successful connect, the socket is only writable. Upon an
+        * error, it's both readable and writable.
+        */
+       if ((flags & (EVENT_FD_READ|EVENT_FD_WRITE))
+           == (EVENT_FD_READ|EVENT_FD_WRITE)) {
+               int sockerr;
+               socklen_t err_len = sizeof(sockerr);
+
+               if (getsockopt(state->fd, SOL_SOCKET, SO_ERROR,
+                              (void *)&sockerr, &err_len) == 0) {
+                       errno = sockerr;
+               }
+
+               state->sys_errno = errno;
+
+               DEBUG(10, ("connect returned %s\n", strerror(errno)));
+
+               sys_fcntl_long(state->fd, F_SETFL, state->old_sockflags);
+               async_req_error(req, map_nt_error_from_unix(state->sys_errno));
+               return;
+       }
+
+       state->sys_errno = 0;
+       async_req_done(req);
 }
 
+NTSTATUS async_connect_recv(struct async_req *req, int *perrno)
+{
+       struct async_connect_state *state = talloc_get_type_abort(
+               req->private_data, struct async_connect_state);
+       NTSTATUS status;
+
+       sys_fcntl_long(state->fd, F_SETFL, state->old_sockflags);
+
+       *perrno = state->sys_errno;
+
+       if (async_req_is_error(req, &status)) {
+               return status;
+       }
+       if (state->sys_errno == 0) {
+               return NT_STATUS_OK;
+       }
+       return map_nt_error_from_unix(state->sys_errno);
+}
index 8d97606b856e92442c63526a98742a22be7108af..75a513312e21f27d93f35f7d6af4f894f6f87f65 100644 (file)
@@ -155,17 +155,17 @@ static NTSTATUS ctdbd_connect(TALLOC_CTX *mem_ctx,
  * Do we have a complete ctdb packet in the queue?
  */
 
-static bool ctdb_req_complete(const DATA_BLOB *data,
+static bool ctdb_req_complete(const uint8_t *buf, size_t available,
                              size_t *length,
                              void *private_data)
 {
        uint32 msglen;
 
-       if (data->length < sizeof(msglen)) {
+       if (available < sizeof(msglen)) {
                return False;
        }
 
-       msglen = *((uint32 *)data->data);
+       msglen = *((uint32 *)buf);
 
        DEBUG(10, ("msglen = %d\n", msglen));
 
@@ -176,12 +176,12 @@ static bool ctdb_req_complete(const DATA_BLOB *data,
                cluster_fatal("ctdbd protocol error\n");
        }
 
-       if (data->length >= msglen) {
-               *length = msglen;
-               return True;
+       if (available < msglen) {
+               return false;
        }
 
-       return False;
+       *length = msglen;
+       return true;
 }
 
 /*
@@ -220,16 +220,13 @@ struct req_pull_state {
  * Pull a ctdb request out of the incoming packet queue
  */
 
-static NTSTATUS ctdb_req_pull(const DATA_BLOB *data,
+static NTSTATUS ctdb_req_pull(uint8_t *buf, size_t length,
                              void *private_data)
 {
        struct req_pull_state *state = (struct req_pull_state *)private_data;
 
-       state->req = data_blob_talloc(state->mem_ctx, data->data,
-                                     data->length);
-       if (state->req.data == NULL) {
-               return NT_STATUS_NO_MEMORY;
-       }
+       state->req.data = talloc_move(state->mem_ctx, &buf);
+       state->req.length = length;
        return NT_STATUS_OK;
 }
 
@@ -497,7 +494,7 @@ NTSTATUS ctdbd_messaging_connection(TALLOC_CTX *mem_ctx,
 /*
  * Packet handler to receive and handle a ctdb message
  */
-static NTSTATUS ctdb_handle_message(const DATA_BLOB *data,
+static NTSTATUS ctdb_handle_message(uint8_t *buf, size_t length,
                                    void *private_data)
 {
        struct ctdbd_connection *conn = talloc_get_type_abort(
@@ -505,11 +502,12 @@ static NTSTATUS ctdb_handle_message(const DATA_BLOB *data,
        struct ctdb_req_message *msg;
        struct messaging_rec *msg_rec;
 
-       msg = (struct ctdb_req_message *)data->data;
+       msg = (struct ctdb_req_message *)buf;
 
        if (msg->hdr.operation != CTDB_REQ_MESSAGE) {
                DEBUG(0, ("Received async msg of type %u, discarding\n",
                          msg->hdr.operation));
+               TALLOC_FREE(buf);
                return NT_STATUS_INVALID_PARAMETER;
        }
 
@@ -519,6 +517,7 @@ static NTSTATUS ctdb_handle_message(const DATA_BLOB *data,
                DEBUG(10, ("received CTDB_SRVID_RELEASE_IP\n"));
                conn->release_ip_handler((const char *)msg->data,
                                         conn->release_ip_priv);
+               TALLOC_FREE(buf);
                return NT_STATUS_OK;
        }
 
@@ -540,6 +539,8 @@ static NTSTATUS ctdb_handle_message(const DATA_BLOB *data,
                 */
                message_send_all(conn->msg_ctx, MSG_SMB_UNLOCK, NULL, 0, NULL);
 
+               TALLOC_FREE(buf);
+
                return NT_STATUS_OK;
                
        }
@@ -548,17 +549,20 @@ static NTSTATUS ctdb_handle_message(const DATA_BLOB *data,
        if (msg->srvid != sys_getpid() && msg->srvid != MSG_SRVID_SAMBA) {
                DEBUG(0,("Got unexpected message with srvid=%llu\n", 
                         (unsigned long long)msg->srvid));
+               TALLOC_FREE(buf);
                return NT_STATUS_OK;
        }
 
-       if (!(msg_rec = ctdb_pull_messaging_rec(NULL, data->length, msg))) {
+       if (!(msg_rec = ctdb_pull_messaging_rec(NULL, length, msg))) {
                DEBUG(10, ("ctdb_pull_messaging_rec failed\n"));
+               TALLOC_FREE(buf);
                return NT_STATUS_NO_MEMORY;
        }
 
        messaging_dispatch_rec(conn->msg_ctx, msg_rec);
 
        TALLOC_FREE(msg_rec);
+       TALLOC_FREE(buf);
        return NT_STATUS_OK;
 }
 
@@ -1025,7 +1029,7 @@ struct ctdbd_traverse_state {
  * Handle a traverse record coming in on the ctdbd connection
  */
 
-static NTSTATUS ctdb_traverse_handler(const DATA_BLOB *blob,
+static NTSTATUS ctdb_traverse_handler(uint8_t *buf, size_t length,
                                      void *private_data)
 {
        struct ctdbd_traverse_state *state =
@@ -1035,11 +1039,11 @@ static NTSTATUS ctdb_traverse_handler(const DATA_BLOB *blob,
        struct ctdb_rec_data *d;
        TDB_DATA key, data;
 
-       m = (struct ctdb_req_message *)blob->data;
+       m = (struct ctdb_req_message *)buf;
 
-       if (blob->length < sizeof(*m) || m->hdr.length != blob->length) {
-               DEBUG(0, ("Got invalid message of length %d\n",
-                         (int)blob->length));
+       if (length < sizeof(*m) || m->hdr.length != length) {
+               DEBUG(0, ("Got invalid message of length %d\n", (int)length));
+               TALLOC_FREE(buf);
                return NT_STATUS_UNEXPECTED_IO_ERROR;
        }
 
@@ -1047,6 +1051,7 @@ static NTSTATUS ctdb_traverse_handler(const DATA_BLOB *blob,
        if (m->datalen < sizeof(uint32_t) || m->datalen != d->length) {
                DEBUG(0, ("Got invalid traverse data of length %d\n",
                          (int)m->datalen));
+               TALLOC_FREE(buf);
                return NT_STATUS_UNEXPECTED_IO_ERROR;
        }
 
@@ -1063,6 +1068,7 @@ static NTSTATUS ctdb_traverse_handler(const DATA_BLOB *blob,
        if (data.dsize < sizeof(struct ctdb_ltdb_header)) {
                DEBUG(0, ("Got invalid ltdb header length %d\n",
                          (int)data.dsize));
+               TALLOC_FREE(buf);
                return NT_STATUS_UNEXPECTED_IO_ERROR;
        }
        data.dsize -= sizeof(struct ctdb_ltdb_header);
@@ -1072,6 +1078,7 @@ static NTSTATUS ctdb_traverse_handler(const DATA_BLOB *blob,
                state->fn(key, data, state->private_data);
        }
 
+       TALLOC_FREE(buf);
        return NT_STATUS_OK;
 }
 
index 0a745742d9be42de225f72645e4804a9dbe1d246..3891c1c6a3124614e7fa8bb91b7ea5e731a5ae05 100644 (file)
@@ -991,7 +991,7 @@ int ldb_search(struct ldb_context *ldb,
               const struct ldb_dn *base,
               enum ldb_scope scope,
               const char *expression,
-              const char * const *attrs, struct ldb_result **res);
+              const char * const *attrs, struct ldb_result **_res);
 
 /*
  * a useful search function where you can easily define the expression and
index 4dde2a1ef537c9567c0e40cb7af029252893c182..155395e065ae957576a0d9cf070d71ac6cc60abe 100644 (file)
@@ -35,8 +35,6 @@
 #include "ldb/include/includes.h"
 #include "ldb/tools/cmdline.h"
 
-static int failures;
-
 static void usage(void)
 {
        printf("Usage: ldbadd <options> <ldif...>\n");
@@ -53,7 +51,8 @@ static void usage(void)
 /*
   add records from an opened file
 */
-static int process_file(struct ldb_context *ldb, FILE *f, int *count)
+static int process_file(struct ldb_context *ldb, FILE *f, int *count,
+                       int *failures)
 {
        struct ldb_ldif *ldif;
        int ret = LDB_SUCCESS;
@@ -71,7 +70,7 @@ static int process_file(struct ldb_context *ldb, FILE *f, int *count)
                if (ret != LDB_SUCCESS) {
                        fprintf(stderr, "ERR: \"%s\" on DN %s\n", 
                                ldb_errstring(ldb), ldb_dn_linearize(ldb, ldif->msg->dn));
-                       failures++;
+                       (*failures)++;
                } else {
                        (*count)++;
                }
@@ -86,7 +85,7 @@ static int process_file(struct ldb_context *ldb, FILE *f, int *count)
 int main(int argc, const char **argv)
 {
        struct ldb_context *ldb;
-       int i, ret=0, count=0;
+       int i, ret=0, count=0, failures=0;
        struct ldb_cmdline *options;
 
        ldb_global_init();
@@ -96,7 +95,7 @@ int main(int argc, const char **argv)
        options = ldb_cmdline_process(ldb, argc, argv, usage);
 
        if (options->argc == 0) {
-               ret = process_file(ldb, stdin, &count);
+               ret = process_file(ldb, stdin, &count, &failures);
        } else {
                for (i=0;i<options->argc;i++) {
                        const char *fname = options->argv[i];
@@ -106,7 +105,7 @@ int main(int argc, const char **argv)
                                perror(fname);
                                exit(1);
                        }
-                       ret = process_file(ldb, f, &count);
+                       ret = process_file(ldb, f, &count, &failures);
                        fclose(f);
                }
        }
index 368b4cf996f2ed7c726fb88ab08ce5ba04120127..f12387a8f645216ff06258b767e6db0fbc5ed997 100644 (file)
@@ -35,8 +35,6 @@
 #include "ldb/include/includes.h"
 #include "ldb/tools/cmdline.h"
 
-static int failures;
-
 static void usage(void)
 {
        printf("Usage: ldbmodify <options> <ldif...>\n");
@@ -52,7 +50,8 @@ static void usage(void)
 /*
   process modifies for one file
 */
-static int process_file(struct ldb_context *ldb, FILE *f, int *count)
+static int process_file(struct ldb_context *ldb, FILE *f, int *count,
+                       int *failures)
 {
        struct ldb_ldif *ldif;
        int ret = LDB_SUCCESS;
@@ -73,7 +72,7 @@ static int process_file(struct ldb_context *ldb, FILE *f, int *count)
                if (ret != LDB_SUCCESS) {
                        fprintf(stderr, "ERR: \"%s\" on DN %s\n", 
                                ldb_errstring(ldb), ldb_dn_linearize(ldb, ldif->msg->dn));
-                       failures++;
+                       (*failures)++;
                } else {
                        (*count)++;
                }
@@ -87,6 +86,7 @@ int main(int argc, const char **argv)
 {
        struct ldb_context *ldb;
        int count=0;
+       int failures=0;
        int i, ret=LDB_SUCCESS;
        struct ldb_cmdline *options;
 
@@ -97,7 +97,7 @@ int main(int argc, const char **argv)
        options = ldb_cmdline_process(ldb, argc, argv, usage);
 
        if (options->argc == 0) {
-               ret = process_file(ldb, stdin, &count);
+               ret = process_file(ldb, stdin, &count, &failures);
        } else {
                for (i=0;i<options->argc;i++) {
                        const char *fname = options->argv[i];
@@ -107,7 +107,7 @@ int main(int argc, const char **argv)
                                perror(fname);
                                exit(1);
                        }
-                       ret = process_file(ldb, f, &count);
+                       ret = process_file(ldb, f, &count, &failures);
                }
        }
 
index e4cab6ba87216499249eca1d34b5df705bfc6a51..ef28bf9f625b53b0f8ef214eaf1e0ac3fe9262d4 100644 (file)
@@ -120,33 +120,43 @@ NTSTATUS packet_fd_read_sync(struct packet_context *ctx)
 }
 
 bool packet_handler(struct packet_context *ctx,
-                   bool (*full_req)(const DATA_BLOB *data,
+                   bool (*full_req)(const uint8_t *buf,
+                                    size_t available,
                                     size_t *length,
-                                    void *private_data),
-                   NTSTATUS (*callback)(const DATA_BLOB *data,
-                                        void *private_data),
-                   void *private_data,
-                   NTSTATUS *status)
+                                    void *priv),
+                   NTSTATUS (*callback)(uint8_t *buf, size_t length,
+                                        void *priv),
+                   void *priv, NTSTATUS *status)
 {
        size_t length;
-       DATA_BLOB data;
+       uint8_t *buf;
 
-       if (!full_req(&ctx->in, &length, private_data)) {
+       if (!full_req(ctx->in.data, ctx->in.length, &length, priv)) {
                return False;
        }
 
-       SMB_ASSERT(length <= ctx->in.length);
-
-       data = data_blob(ctx->in.data, length);
-
-       memmove(ctx->in.data, ctx->in.data + length,
-               ctx->in.length - length);
-       ctx->in.length -= length;
+       if (length > ctx->in.length) {
+               *status = NT_STATUS_INTERNAL_ERROR;
+               return true;
+       }
 
-       *status = callback(&data, private_data);
+       if (length == ctx->in.length) {
+               buf = ctx->in.data;
+               ctx->in.data = NULL;
+               ctx->in.length = 0;
+       } else {
+               buf = (uint8_t *)TALLOC_MEMDUP(ctx, ctx->in.data, length);
+               if (buf == NULL) {
+                       *status = NT_STATUS_NO_MEMORY;
+                       return true;
+               }
 
-       data_blob_free(&data);
+               memmove(ctx->in.data, ctx->in.data + length,
+                       ctx->in.length - length);
+               ctx->in.length -= length;
+       }
 
+       *status = callback(buf, length, priv);
        return True;
 }
 
index d23758ad6a22bb46b7bb55ff4e0137941155e3e3..e913b35d6073ef2fae90a7765ec06446dd5a20b6 100644 (file)
@@ -707,10 +707,6 @@ ssize_t write_data_iov(int fd, const struct iovec *orig_iov, int iovcnt)
  Write data to a fd.
 ****************************************************************************/
 
-/****************************************************************************
- Write data to a fd.
-****************************************************************************/
-
 ssize_t write_data(int fd, const char *buffer, size_t N)
 {
        ssize_t ret;
@@ -948,102 +944,319 @@ int open_socket_in(int type,
        return( res );
  }
 
+struct open_socket_out_state {
+       int fd;
+       struct event_context *ev;
+       struct sockaddr_storage ss;
+       socklen_t salen;
+       uint16_t port;
+       int wait_nsec;
+};
+
+static void open_socket_out_connected(struct async_req *subreq);
+
+static int open_socket_out_state_destructor(struct open_socket_out_state *s)
+{
+       if (s->fd != -1) {
+               close(s->fd);
+       }
+       return 0;
+}
+
 /****************************************************************************
  Create an outgoing socket. timeout is in milliseconds.
 **************************************************************************/
 
-int open_socket_out(int type,
-               const struct sockaddr_storage *pss,
-               uint16_t port,
-               int timeout)
+struct async_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
+                                      struct event_context *ev,
+                                      const struct sockaddr_storage *pss,
+                                      uint16_t port,
+                                      int timeout)
 {
        char addr[INET6_ADDRSTRLEN];
-       struct sockaddr_storage sock_out = *pss;
-       int res,ret;
-       int connect_loop = 10;
-       int increment = 10;
+       struct async_req *result, *subreq;
+       struct open_socket_out_state *state;
+       NTSTATUS status;
 
-       /* create a socket to write to */
-       res = socket(pss->ss_family, type, 0);
-       if (res == -1) {
-                DEBUG(0,("socket error (%s)\n", strerror(errno)));
-               return -1;
+       result = async_req_new(mem_ctx);
+       if (result == NULL) {
+               return NULL;
        }
+       state = talloc(result, struct open_socket_out_state);
+       if (state == NULL) {
+               goto fail;
+       }
+       result->private_data = state;
+
+       state->ev = ev;
+       state->ss = *pss;
+       state->port = port;
+       state->wait_nsec = 10000;
+       state->salen = -1;
 
-       if (type != SOCK_STREAM) {
-               return res;
+       state->fd = socket(state->ss.ss_family, SOCK_STREAM, 0);
+       if (state->fd == -1) {
+               status = map_nt_error_from_unix(errno);
+               goto post_status;
+       }
+       talloc_set_destructor(state, open_socket_out_state_destructor);
+
+       if (!async_req_set_timeout(result, ev, timeval_set(0, timeout*1000))) {
+               goto fail;
        }
 
 #if defined(HAVE_IPV6)
        if (pss->ss_family == AF_INET6) {
-               struct sockaddr_in6 *psa6 = (struct sockaddr_in6 *)&sock_out;
+               struct sockaddr_in6 *psa6;
+               psa6 = (struct sockaddr_in6 *)&state->ss;
                psa6->sin6_port = htons(port);
-               if (psa6->sin6_scope_id == 0 &&
-                               IN6_IS_ADDR_LINKLOCAL(&psa6->sin6_addr)) {
-                       setup_linklocal_scope_id((struct sockaddr *)&sock_out);
+               if (psa6->sin6_scope_id == 0
+                   && IN6_IS_ADDR_LINKLOCAL(&psa6->sin6_addr)) {
+                       setup_linklocal_scope_id(
+                               (struct sockaddr *)&(state->ss));
                }
+               state->salen = sizeof(struct sockaddr_in6);
        }
 #endif
        if (pss->ss_family == AF_INET) {
-               struct sockaddr_in *psa = (struct sockaddr_in *)&sock_out;
+               struct sockaddr_in *psa;
+               psa = (struct sockaddr_in *)&state->ss;
                psa->sin_port = htons(port);
+               state->salen = sizeof(struct sockaddr_in);
        }
 
-       /* set it non-blocking */
-       set_blocking(res,false);
+       print_sockaddr(addr, sizeof(addr), &state->ss);
+       DEBUG(3,("Connecting to %s at port %u\n", addr, (unsigned int)port));
 
-       print_sockaddr(addr, sizeof(addr), &sock_out);
-       DEBUG(3,("Connecting to %s at port %u\n",
-                               addr,
-                               (unsigned int)port));
+       subreq = async_connect_send(state, state->ev, state->fd,
+                                   (struct sockaddr *)&state->ss,
+                                   state->salen);
+       if ((subreq == NULL)
+           || !async_req_set_timeout(subreq, state->ev,
+                                     timeval_set(0, state->wait_nsec))) {
+               status = NT_STATUS_NO_MEMORY;
+               goto post_status;
+       }
+       subreq->async.fn = open_socket_out_connected;
+       subreq->async.priv = result;
+       return result;
 
-       /* and connect it to the destination */
-  connect_again:
+ post_status:
+       if (!async_post_status(result, ev, status)) {
+               goto fail;
+       }
+       return result;
+ fail:
+       TALLOC_FREE(result);
+       return NULL;
+}
 
-       ret = sys_connect(res, (struct sockaddr *)&sock_out);
+static void open_socket_out_connected(struct async_req *subreq)
+{
+       struct async_req *req = talloc_get_type_abort(
+               subreq->async.priv, struct async_req);
+       struct open_socket_out_state *state = talloc_get_type_abort(
+               req->private_data, struct open_socket_out_state);
+       NTSTATUS status;
+       int sys_errno;
 
-       /* Some systems return EAGAIN when they mean EINPROGRESS */
-       if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
-                       errno == EAGAIN) && (connect_loop < timeout) ) {
-               smb_msleep(connect_loop);
-               timeout -= connect_loop;
-               connect_loop += increment;
-               if (increment < 250) {
-                       /* After 8 rounds we end up at a max of 255 msec */
-                       increment *= 1.5;
-               }
-               goto connect_again;
+       status = async_connect_recv(subreq, &sys_errno);
+       TALLOC_FREE(subreq);
+       if (NT_STATUS_IS_OK(status)) {
+               async_req_done(req);
+               return;
        }
 
-       if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
-                       errno == EAGAIN)) {
-               DEBUG(1,("timeout connecting to %s:%u\n",
-                                       addr,
-                                       (unsigned int)port));
-               close(res);
-               return -1;
+       if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)
+           || (sys_errno == EINPROGRESS)
+           || (sys_errno == EALREADY)
+           || (sys_errno == EAGAIN)) {
+
+               /*
+                * retry
+                */
+
+               if (state->wait_nsec < 250000) {
+                       state->wait_nsec *= 1.5;
+               }
+
+               subreq = async_connect_send(state, state->ev, state->fd,
+                                           (struct sockaddr *)&state->ss,
+                                           state->salen);
+               if (async_req_nomem(subreq, req)) {
+                       return;
+               }
+               if (!async_req_set_timeout(subreq, state->ev,
+                                          timeval_set(0, state->wait_nsec))) {
+                       async_req_error(req, NT_STATUS_NO_MEMORY);
+                       return;
+               }
+               subreq->async.fn = open_socket_out_connected;
+               subreq->async.priv = req;
+               return;
        }
 
 #ifdef EISCONN
-       if (ret < 0 && errno == EISCONN) {
-               errno = 0;
-               ret = 0;
+       if (sys_errno == EISCONN) {
+               async_req_done(req);
+               return;
        }
 #endif
 
-       if (ret < 0) {
-               DEBUG(2,("error connecting to %s:%d (%s)\n",
-                               addr,
-                               (unsigned int)port,
-                               strerror(errno)));
-               close(res);
-               return -1;
+       /* real error */
+       async_req_error(req, map_nt_error_from_unix(sys_errno));
+}
+
+NTSTATUS open_socket_out_recv(struct async_req *req, int *pfd)
+{
+       struct open_socket_out_state *state = talloc_get_type_abort(
+               req->private_data, struct open_socket_out_state);
+       NTSTATUS status;
+
+       if (async_req_is_error(req, &status)) {
+               return status;
+       }
+       *pfd = state->fd;
+       state->fd = -1;
+       return NT_STATUS_OK;
+}
+
+NTSTATUS open_socket_out(const struct sockaddr_storage *pss, uint16_t port,
+                        int timeout, int *pfd)
+{
+       TALLOC_CTX *frame = talloc_stackframe();
+       struct event_context *ev;
+       struct async_req *req;
+       NTSTATUS status = NT_STATUS_NO_MEMORY;
+
+       ev = event_context_init(frame);
+       if (ev == NULL) {
+               goto fail;
        }
 
-       /* set it blocking again */
-       set_blocking(res,true);
+       req = open_socket_out_send(frame, ev, pss, port, timeout);
+       if (req == NULL) {
+               goto fail;
+       }
+       while (req->state < ASYNC_REQ_DONE) {
+               event_loop_once(ev);
+       }
 
-       return res;
+       status = open_socket_out_recv(req, pfd);
+ fail:
+       TALLOC_FREE(frame);
+       return status;
+}
+
+struct open_socket_out_defer_state {
+       struct event_context *ev;
+       struct sockaddr_storage ss;
+       uint16_t port;
+       int timeout;
+       int fd;
+};
+
+static void open_socket_out_defer_waited(struct async_req *subreq);
+static void open_socket_out_defer_connected(struct async_req *subreq);
+
+struct async_req *open_socket_out_defer_send(TALLOC_CTX *mem_ctx,
+                                            struct event_context *ev,
+                                            struct timeval wait_time,
+                                            const struct sockaddr_storage *pss,
+                                            uint16_t port,
+                                            int timeout)
+{
+       struct async_req *result, *subreq;
+       struct open_socket_out_defer_state *state;
+       NTSTATUS status;
+
+       result = async_req_new(mem_ctx);
+       if (result == NULL) {
+               return NULL;
+       }
+       state = talloc(result, struct open_socket_out_defer_state);
+       if (state == NULL) {
+               goto fail;
+       }
+       result->private_data = state;
+
+       state->ev = ev;
+       state->ss = *pss;
+       state->port = port;
+       state->timeout = timeout;
+
+       subreq = async_wait_send(state, ev, wait_time);
+       if (subreq == NULL) {
+               status = NT_STATUS_NO_MEMORY;
+               goto post_status;
+       }
+       subreq->async.fn = open_socket_out_defer_waited;
+       subreq->async.priv = result;
+       return result;
+
+ post_status:
+       if (!async_post_status(result, ev, status)) {
+               goto fail;
+       }
+       return result;
+ fail:
+       TALLOC_FREE(result);
+       return NULL;
+}
+
+static void open_socket_out_defer_waited(struct async_req *subreq)
+{
+       struct async_req *req = talloc_get_type_abort(
+               subreq->async.priv, struct async_req);
+       struct open_socket_out_defer_state *state = talloc_get_type_abort(
+               req->private_data, struct open_socket_out_defer_state);
+       NTSTATUS status;
+
+       status = async_wait_recv(subreq);
+       TALLOC_FREE(subreq);
+       if (!NT_STATUS_IS_OK(status)) {
+               async_req_error(req, status);
+               return;
+       }
+
+       subreq = open_socket_out_send(state, state->ev, &state->ss,
+                                     state->port, state->timeout);
+       if (async_req_nomem(subreq, req)) {
+               return;
+       }
+       subreq->async.fn = open_socket_out_defer_connected;
+       subreq->async.priv = req;
+}
+
+static void open_socket_out_defer_connected(struct async_req *subreq)
+{
+       struct async_req *req = talloc_get_type_abort(
+               subreq->async.priv, struct async_req);
+       struct open_socket_out_defer_state *state = talloc_get_type_abort(
+               req->private_data, struct open_socket_out_defer_state);
+       NTSTATUS status;
+
+       status = open_socket_out_recv(subreq, &state->fd);
+       TALLOC_FREE(subreq);
+       if (!NT_STATUS_IS_OK(status)) {
+               async_req_error(req, status);
+               return;
+       }
+       async_req_done(req);
+}
+
+NTSTATUS open_socket_out_defer_recv(struct async_req *req, int *pfd)
+{
+       struct open_socket_out_defer_state *state = talloc_get_type_abort(
+               req->private_data, struct open_socket_out_defer_state);
+       NTSTATUS status;
+
+       if (async_req_is_error(req, &status)) {
+               return status;
+       }
+       *pfd = state->fd;
+       state->fd = -1;
+       return NT_STATUS_OK;
 }
 
 /*******************************************************************
similarity index 77%
rename from source3/winbindd/winbindd_reqtrans.c
rename to source3/lib/wb_reqtrans.c
index ea16c5f81e285c694dbfb068ae42208988d8e2f6..1f5f181aa1f5f206441e9bab67cd829671a01f92 100644 (file)
@@ -20,7 +20,7 @@
 */
 
 #include "includes.h"
-#include "winbindd.h"
+#include "winbindd/winbindd.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_WINBIND
@@ -43,7 +43,7 @@ struct async_req *wb_req_read_send(TALLOC_CTX *mem_ctx,
        struct async_req *result, *subreq;
        struct req_read_state *state;
 
-       result = async_req_new(mem_ctx, ev);
+       result = async_req_new(mem_ctx);
        if (result == NULL) {
                return NULL;
        }
@@ -205,7 +205,7 @@ struct async_req *wb_req_write_send(TALLOC_CTX *mem_ctx,
        struct async_req *result, *subreq;
        struct req_write_state *state;
 
-       result = async_req_new(mem_ctx, ev);
+       result = async_req_new(mem_ctx);
        if (result == NULL) {
                return NULL;
        }
@@ -304,7 +304,7 @@ struct async_req *wb_resp_read_send(TALLOC_CTX *mem_ctx,
        struct async_req *result, *subreq;
        struct resp_read_state *state;
 
-       result = async_req_new(mem_ctx, ev);
+       result = async_req_new(mem_ctx);
        if (result == NULL) {
                return NULL;
        }
@@ -458,7 +458,7 @@ struct async_req *wb_resp_write_send(TALLOC_CTX *mem_ctx,
        struct async_req *result, *subreq;
        struct resp_write_state *state;
 
-       result = async_req_new(mem_ctx, ev);
+       result = async_req_new(mem_ctx);
        if (result == NULL) {
                return NULL;
        }
@@ -540,146 +540,3 @@ NTSTATUS wb_resp_write_recv(struct async_req *req)
 {
        return async_req_simple_recv(req);
 }
-
-struct wb_trans_state {
-       struct event_context *ev;
-       struct timed_event *te;
-       int fd;
-       struct winbindd_response *wb_resp;
-       size_t reply_max_extra_data;
-};
-
-static void wb_trans_timeout(struct event_context *ev, struct timed_event *te,
-                            const struct timeval *now, void *priv);
-static void wb_trans_sent(struct async_req *req);
-static void wb_trans_received(struct async_req *req);
-
-struct async_req *wb_trans_send(TALLOC_CTX *mem_ctx,
-                               struct event_context *ev,
-                               int fd,
-                               struct winbindd_request *wb_req,
-                               struct timeval timeout,
-                               size_t reply_max_extra_data)
-{
-       struct async_req *result, *subreq;
-       struct wb_trans_state *state;
-
-       result = async_req_new(mem_ctx, ev);
-       if (result == NULL) {
-               return NULL;
-       }
-
-       state = talloc(result, struct wb_trans_state);
-       if (state == NULL) {
-               goto nomem;
-       }
-       result->private_data = state;
-
-       state->ev = ev;
-       state->fd = fd;
-       state->reply_max_extra_data = reply_max_extra_data;
-
-       state->te = event_add_timed(
-               ev, state,
-               timeval_current_ofs(timeout.tv_sec, timeout.tv_usec),
-               "wb_trans_timeout", wb_trans_timeout, result);
-       if (state->te == NULL) {
-               goto nomem;
-       }
-
-       subreq = wb_req_write_send(state, state->ev, state->fd, wb_req);
-       if (subreq == NULL) {
-               goto nomem;
-       }
-       subreq->async.fn = wb_trans_sent;
-       subreq->async.priv = result;
-
-       return result;
-
- nomem:
-       TALLOC_FREE(result);
-       return NULL;
-}
-
-static void wb_trans_timeout(struct event_context *ev, struct timed_event *te,
-                            const struct timeval *now, void *priv)
-{
-       struct async_req *req = talloc_get_type_abort(
-               priv, struct async_req);
-       struct wb_trans_state *state = talloc_get_type_abort(
-               req->private_data, struct wb_trans_state);
-
-       TALLOC_FREE(state->te);
-       async_req_error(req, NT_STATUS_IO_TIMEOUT);
-}
-
-static void wb_trans_sent(struct async_req *subreq)
-{
-       struct async_req *req = talloc_get_type_abort(
-               subreq->async.priv, struct async_req);
-       struct wb_trans_state *state = talloc_get_type_abort(
-               req->private_data, struct wb_trans_state);
-       NTSTATUS status;
-
-       status = wb_req_write_recv(subreq);
-       TALLOC_FREE(subreq);
-       if (!NT_STATUS_IS_OK(status)) {
-               async_req_error(req, status);
-               return;
-       }
-
-       subreq = wb_resp_read_send(state, state->ev, state->fd);
-       if (async_req_nomem(subreq, req)) {
-               return;
-       }
-
-       subreq->async.fn = wb_trans_received;
-       subreq->async.priv = req;
-};
-
-static void wb_trans_received(struct async_req *subreq)
-{
-       struct async_req *req = talloc_get_type_abort(
-               subreq->async.priv, struct async_req);
-       struct wb_trans_state *state = talloc_get_type_abort(
-               req->private_data, struct wb_trans_state);
-       NTSTATUS status;
-
-       TALLOC_FREE(state->te);
-
-       status = wb_resp_read_recv(subreq, state, &state->wb_resp);
-       TALLOC_FREE(subreq);
-       if (!NT_STATUS_IS_OK(status)) {
-               async_req_error(req, status);
-               return;
-       }
-
-       async_req_done(req);
-}
-
-NTSTATUS wb_trans_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
-                      struct winbindd_response **presp)
-{
-       struct wb_trans_state *state = talloc_get_type_abort(
-               req->private_data, struct wb_trans_state);
-       NTSTATUS status;
-
-       if (async_req_is_error(req, &status)) {
-               return status;
-       }
-       *presp = talloc_move(mem_ctx, &state->wb_resp);
-       return NT_STATUS_OK;
-}
-
-struct wb_trans_queue_state {
-       struct wb_trans_queue_state *prev, *next;
-       struct wb_trans_queue *queue;
-       struct winbindd_request *req;
-};
-
-struct wb_trans_queue {
-       int fd;
-       struct timeval timeout;
-       size_t max_resp_extra_data;
-       struct wb_trans_queue_state *queued_requests;
-};
diff --git a/source3/lib/wbclient.c b/source3/lib/wbclient.c
new file mode 100644 (file)
index 0000000..d58c934
--- /dev/null
@@ -0,0 +1,774 @@
+/*
+   Unix SMB/CIFS implementation.
+   Infrastructure for async winbind requests
+   Copyright (C) Volker Lendecke 2008
+
+   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 "winbindd/winbindd.h"
+#include "winbindd/winbindd_proto.h"
+
+static int make_nonstd_fd(int fd)
+{
+       int i;
+       int sys_errno = 0;
+       int fds[3];
+       int num_fds = 0;
+
+       if (fd == -1) {
+               return -1;
+       }
+       while (fd < 3) {
+               fds[num_fds++] = fd;
+               fd = dup(fd);
+               if (fd == -1) {
+                       sys_errno = errno;
+                       break;
+               }
+       }
+       for (i=0; i<num_fds; i++) {
+               close(fds[i]);
+       }
+       if (fd == -1) {
+               errno = sys_errno;
+       }
+       return fd;
+}
+
+/****************************************************************************
+ Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
+ else
+ if SYSV use O_NDELAY
+ if BSD use FNDELAY
+ Set close on exec also.
+****************************************************************************/
+
+static int make_safe_fd(int fd)
+{
+       int result, flags;
+       int new_fd = make_nonstd_fd(fd);
+
+       if (new_fd == -1) {
+               goto fail;
+       }
+
+       /* Socket should be nonblocking. */
+
+#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 ((flags = fcntl(new_fd, F_GETFL)) == -1) {
+               goto fail;
+       }
+
+       flags |= FLAG_TO_SET;
+       if (fcntl(new_fd, F_SETFL, flags) == -1) {
+               goto fail;
+       }
+
+#undef FLAG_TO_SET
+
+       /* Socket should be closed on exec() */
+#ifdef FD_CLOEXEC
+       result = flags = fcntl(new_fd, F_GETFD, 0);
+       if (flags >= 0) {
+               flags |= FD_CLOEXEC;
+               result = fcntl( new_fd, F_SETFD, flags );
+       }
+       if (result < 0) {
+               goto fail;
+       }
+#endif
+       return new_fd;
+
+ fail:
+       if (new_fd != -1) {
+               int sys_errno = errno;
+               close(new_fd);
+               errno = sys_errno;
+       }
+       return -1;
+}
+
+static bool winbind_closed_fd(int fd)
+{
+       struct timeval tv;
+       fd_set r_fds;
+
+       if (fd == -1) {
+               return true;
+       }
+
+       FD_ZERO(&r_fds);
+       FD_SET(fd, &r_fds);
+       ZERO_STRUCT(tv);
+
+       if ((select(fd+1, &r_fds, NULL, NULL, &tv) == -1)
+           || FD_ISSET(fd, &r_fds)) {
+               return true;
+       }
+
+       return false;
+}
+
+struct wb_context {
+       struct async_req_queue *queue;
+       int fd;
+       bool is_priv;
+};
+
+struct wb_context *wb_context_init(TALLOC_CTX *mem_ctx)
+{
+       struct wb_context *result;
+
+       result = talloc(mem_ctx, struct wb_context);
+       if (result == NULL) {
+               return NULL;
+       }
+       result->queue = async_req_queue_init(result);
+       if (result->queue == NULL) {
+               TALLOC_FREE(result);
+               return NULL;
+       }
+       result->fd = -1;
+       return result;
+}
+
+static struct async_req *wb_connect_send(TALLOC_CTX *mem_ctx,
+                                        struct event_context *ev,
+                                        struct wb_context *wb_ctx,
+                                        const char *dir)
+{
+       struct async_req *req;
+       struct sockaddr_un sunaddr;
+       struct stat st;
+       char *path = NULL;
+       NTSTATUS status;
+
+       if (wb_ctx->fd != -1) {
+               close(wb_ctx->fd);
+               wb_ctx->fd = -1;
+       }
+
+       /* Check permissions on unix socket directory */
+
+       if (lstat(dir, &st) == -1) {
+               status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+               goto post_status;
+       }
+
+       if (!S_ISDIR(st.st_mode) ||
+           (st.st_uid != 0 && st.st_uid != geteuid())) {
+               status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+               goto post_status;
+       }
+
+       /* Connect to socket */
+
+       path = talloc_asprintf(talloc_tos(), "%s/%s", dir,
+                              WINBINDD_SOCKET_NAME);
+       if (path == NULL) {
+               goto nomem;
+       }
+
+       sunaddr.sun_family = AF_UNIX;
+       strlcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path));
+       TALLOC_FREE(path);
+
+       /* If socket file doesn't exist, don't bother trying to connect
+          with retry.  This is an attempt to make the system usable when
+          the winbindd daemon is not running. */
+
+       if ((lstat(sunaddr.sun_path, &st) == -1)
+           || !S_ISSOCK(st.st_mode)
+           || (st.st_uid != 0 && st.st_uid != geteuid())) {
+               status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+               goto post_status;
+       }
+
+       wb_ctx->fd = make_safe_fd(socket(AF_UNIX, SOCK_STREAM, 0));
+       if (wb_ctx->fd == -1) {
+               status = map_nt_error_from_unix(errno);
+               goto post_status;
+       }
+
+       req = async_connect_send(mem_ctx, ev, wb_ctx->fd,
+                                (struct sockaddr *)&sunaddr,
+                                sizeof(sunaddr));
+       if (req == NULL) {
+               goto nomem;
+       }
+       if (!async_req_set_timeout(req, ev, timeval_set(30, 0))) {
+               TALLOC_FREE(req);
+               goto nomem;
+       }
+
+       return req;
+
+ nomem:
+       status = NT_STATUS_NO_MEMORY;
+ post_status:
+       req = async_req_new(mem_ctx);
+       if (req == NULL) {
+               return NULL;
+       }
+       if (async_post_status(req, ev, status)) {
+               return req;
+       }
+       TALLOC_FREE(req);
+       return NULL;
+}
+
+static NTSTATUS wb_connect_recv(struct async_req *req)
+{
+       int dummy;
+
+       return async_connect_recv(req, &dummy);
+}
+
+static struct winbindd_request *winbindd_request_copy(
+       TALLOC_CTX *mem_ctx,
+       const struct winbindd_request *req)
+{
+       struct winbindd_request *result;
+
+       result = (struct winbindd_request *)TALLOC_MEMDUP(
+               mem_ctx, req, sizeof(struct winbindd_request));
+       if (result == NULL) {
+               return NULL;
+       }
+
+       if (result->extra_len == 0) {
+               return result;
+       }
+
+       result->extra_data.data = (char *)TALLOC_MEMDUP(
+               result, result->extra_data.data, result->extra_len);
+       if (result->extra_data.data == NULL) {
+               TALLOC_FREE(result);
+               return NULL;
+       }
+       return result;
+}
+
+struct wb_int_trans_state {
+       struct event_context *ev;
+       int fd;
+       struct winbindd_request *wb_req;
+       struct winbindd_response *wb_resp;
+};
+
+static void wb_int_trans_write_done(struct async_req *subreq);
+static void wb_int_trans_read_done(struct async_req *subreq);
+
+static struct async_req *wb_int_trans_send(TALLOC_CTX *mem_ctx,
+                                          struct event_context *ev, int fd,
+                                          struct winbindd_request *wb_req)
+{
+       struct async_req *result;
+       struct async_req *subreq;
+       struct wb_int_trans_state *state;
+
+       result = async_req_new(mem_ctx);
+       if (result == NULL) {
+               return NULL;
+       }
+       state = talloc(result, struct wb_int_trans_state);
+       if (state == NULL) {
+               goto fail;
+       }
+       result->private_data = state;
+
+       if (winbind_closed_fd(fd)) {
+               if (!async_post_status(result, ev,
+                                      NT_STATUS_PIPE_DISCONNECTED)) {
+                       goto fail;
+               }
+               return result;
+       }
+
+       state->ev = ev;
+       state->fd = fd;
+       state->wb_req = wb_req;
+
+       state->wb_req->length = sizeof(struct winbindd_request);
+       state->wb_req->pid = getpid();
+
+       subreq = wb_req_write_send(state, state->ev, state->fd, state->wb_req);
+       if (subreq == NULL) {
+               goto fail;
+       }
+       subreq->async.fn = wb_int_trans_write_done;
+       subreq->async.priv = result;
+
+       return result;
+
+ fail:
+       TALLOC_FREE(result);
+       return NULL;
+}
+
+static void wb_int_trans_write_done(struct async_req *subreq)
+{
+       struct async_req *req = talloc_get_type_abort(
+               subreq->async.priv, struct async_req);
+       struct wb_int_trans_state *state = talloc_get_type_abort(
+               req->private_data, struct wb_int_trans_state);
+       NTSTATUS status;
+
+       status = wb_req_write_recv(subreq);
+       TALLOC_FREE(subreq);
+       if (!NT_STATUS_IS_OK(status)) {
+               async_req_error(req, status);
+               return;
+       }
+
+       subreq = wb_resp_read_send(state, state->ev, state->fd);
+       if (subreq == NULL) {
+               async_req_error(req, NT_STATUS_NO_MEMORY);
+       }
+       subreq->async.fn = wb_int_trans_read_done;
+       subreq->async.priv = req;
+}
+
+static void wb_int_trans_read_done(struct async_req *subreq)
+{
+       struct async_req *req = talloc_get_type_abort(
+               subreq->async.priv, struct async_req);
+       struct wb_int_trans_state *state = talloc_get_type_abort(
+               req->private_data, struct wb_int_trans_state);
+       NTSTATUS status;
+
+       status = wb_resp_read_recv(subreq, state, &state->wb_resp);
+       TALLOC_FREE(subreq);
+       if (!NT_STATUS_IS_OK(status)) {
+               async_req_error(req, status);
+               return;
+       }
+
+       async_req_done(req);
+}
+
+static NTSTATUS wb_int_trans_recv(struct async_req *req,
+                                 TALLOC_CTX *mem_ctx,
+                                 struct winbindd_response **presponse)
+{
+       struct wb_int_trans_state *state = talloc_get_type_abort(
+               req->private_data, struct wb_int_trans_state);
+       NTSTATUS status;
+
+       if (async_req_is_error(req, &status)) {
+               return status;
+       }
+
+       *presponse = talloc_move(mem_ctx, &state->wb_resp);
+       return NT_STATUS_OK;
+}
+
+static const char *winbindd_socket_dir(void)
+{
+#ifdef SOCKET_WRAPPER
+       const char *env_dir;
+
+       env_dir = getenv(WINBINDD_SOCKET_DIR_ENVVAR);
+       if (env_dir) {
+               return env_dir;
+       }
+#endif
+
+       return WINBINDD_SOCKET_DIR;
+}
+
+struct wb_open_pipe_state {
+       struct wb_context *wb_ctx;
+       struct event_context *ev;
+       bool need_priv;
+       struct winbindd_request wb_req;
+};
+
+static void wb_open_pipe_connect_nonpriv_done(struct async_req *subreq);
+static void wb_open_pipe_ping_done(struct async_req *subreq);
+static void wb_open_pipe_getpriv_done(struct async_req *subreq);
+static void wb_open_pipe_connect_priv_done(struct async_req *subreq);
+
+static struct async_req *wb_open_pipe_send(TALLOC_CTX *mem_ctx,
+                                          struct event_context *ev,
+                                          struct wb_context *wb_ctx,
+                                          bool need_priv)
+{
+       struct async_req *result;
+       struct async_req *subreq;
+       struct wb_open_pipe_state *state;
+
+       result = async_req_new(mem_ctx);
+       if (result == NULL) {
+               return NULL;
+       }
+       state = talloc(result, struct wb_open_pipe_state);
+       if (state == NULL) {
+               goto fail;
+       }
+       result->private_data = state;
+
+       state->wb_ctx = wb_ctx;
+       state->ev = ev;
+       state->need_priv = need_priv;
+
+       if (wb_ctx->fd != -1) {
+               close(wb_ctx->fd);
+               wb_ctx->fd = -1;
+       }
+
+       subreq = wb_connect_send(state, ev, wb_ctx, winbindd_socket_dir());
+       if (subreq == NULL) {
+               goto fail;
+       }
+
+       subreq->async.fn = wb_open_pipe_connect_nonpriv_done;
+       subreq->async.priv = result;
+       return result;
+
+ fail:
+       TALLOC_FREE(result);
+       return NULL;
+}
+
+static void wb_open_pipe_connect_nonpriv_done(struct async_req *subreq)
+{
+       struct async_req *req = talloc_get_type_abort(
+               subreq->async.priv, struct async_req);
+       struct wb_open_pipe_state *state = talloc_get_type_abort(
+               req->private_data, struct wb_open_pipe_state);
+       NTSTATUS status;
+
+       status = wb_connect_recv(subreq);
+       TALLOC_FREE(subreq);
+       if (!NT_STATUS_IS_OK(status)) {
+               state->wb_ctx->is_priv = true;
+               async_req_error(req, status);
+               return;
+       }
+
+       ZERO_STRUCT(state->wb_req);
+       state->wb_req.cmd = WINBINDD_INTERFACE_VERSION;
+
+       subreq = wb_int_trans_send(state, state->ev, state->wb_ctx->fd,
+                                  &state->wb_req);
+       if (async_req_nomem(subreq, req)) {
+               return;
+       }
+
+       subreq->async.fn = wb_open_pipe_ping_done;
+       subreq->async.priv = req;
+}
+
+static void wb_open_pipe_ping_done(struct async_req *subreq)
+{
+       struct async_req *req = talloc_get_type_abort(
+               subreq->async.priv, struct async_req);
+       struct wb_open_pipe_state *state = talloc_get_type_abort(
+               req->private_data, struct wb_open_pipe_state);
+       struct winbindd_response *wb_resp;
+       NTSTATUS status;
+
+       status = wb_int_trans_recv(subreq, state, &wb_resp);
+       TALLOC_FREE(subreq);
+       if (!NT_STATUS_IS_OK(status)) {
+               async_req_error(req, status);
+               return;
+       }
+
+       if (!state->need_priv) {
+               async_req_done(req);
+               return;
+       }
+
+       state->wb_req.cmd = WINBINDD_PRIV_PIPE_DIR;
+
+       subreq = wb_int_trans_send(state, state->ev, state->wb_ctx->fd,
+                                  &state->wb_req);
+       if (async_req_nomem(subreq, req)) {
+               return;
+       }
+
+       subreq->async.fn = wb_open_pipe_getpriv_done;
+       subreq->async.priv = req;
+}
+
+static void wb_open_pipe_getpriv_done(struct async_req *subreq)
+{
+       struct async_req *req = talloc_get_type_abort(
+               subreq->async.priv, struct async_req);
+       struct wb_open_pipe_state *state = talloc_get_type_abort(
+               req->private_data, struct wb_open_pipe_state);
+       struct winbindd_response *wb_resp = NULL;
+       NTSTATUS status;
+
+       status = wb_int_trans_recv(subreq, state, &wb_resp);
+       TALLOC_FREE(subreq);
+       if (!NT_STATUS_IS_OK(status)) {
+               async_req_error(req, status);
+               return;
+       }
+
+       close(state->wb_ctx->fd);
+       state->wb_ctx->fd = -1;
+
+       subreq = wb_connect_send(state, state->ev, state->wb_ctx,
+                                (char *)wb_resp->extra_data.data);
+       TALLOC_FREE(wb_resp);
+       if (async_req_nomem(subreq, req)) {
+               return;
+       }
+
+       subreq->async.fn = wb_open_pipe_connect_priv_done;
+       subreq->async.priv = req;
+}
+
+static void wb_open_pipe_connect_priv_done(struct async_req *subreq)
+{
+       struct async_req *req = talloc_get_type_abort(
+               subreq->async.priv, struct async_req);
+       struct wb_open_pipe_state *state = talloc_get_type_abort(
+               req->private_data, struct wb_open_pipe_state);
+       NTSTATUS status;
+
+       status = wb_connect_recv(subreq);
+       TALLOC_FREE(subreq);
+       if (!NT_STATUS_IS_OK(status)) {
+               async_req_error(req, status);
+               return;
+       }
+       state->wb_ctx->is_priv = true;
+       async_req_done(req);
+}
+
+static NTSTATUS wb_open_pipe_recv(struct async_req *req)
+{
+       return async_req_simple_recv(req);
+}
+
+struct wb_trans_state {
+       struct wb_trans_state *prev, *next;
+       struct wb_context *wb_ctx;
+       struct event_context *ev;
+       struct winbindd_request *wb_req;
+       struct winbindd_response *wb_resp;
+       int num_retries;
+       bool need_priv;
+};
+
+static void wb_trans_connect_done(struct async_req *subreq);
+static void wb_trans_done(struct async_req *subreq);
+static void wb_trans_retry_wait_done(struct async_req *subreq);
+
+static void wb_trigger_trans(struct async_req *req)
+{
+       struct wb_trans_state *state = talloc_get_type_abort(
+               req->private_data, struct wb_trans_state);
+       struct async_req *subreq;
+
+       if ((state->wb_ctx->fd == -1)
+           || (state->need_priv && !state->wb_ctx->is_priv)) {
+
+               subreq = wb_open_pipe_send(state, state->ev, state->wb_ctx,
+                                          state->need_priv);
+               if (async_req_nomem(subreq, req)) {
+                       return;
+               }
+               subreq->async.fn = wb_trans_connect_done;
+               subreq->async.priv = req;
+               return;
+       }
+
+       subreq = wb_int_trans_send(state, state->ev, state->wb_ctx->fd,
+                                  state->wb_req);
+       if (async_req_nomem(subreq, req)) {
+               return;
+       }
+       subreq->async.fn = wb_trans_done;
+       subreq->async.priv = req;
+}
+
+struct async_req *wb_trans_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
+                               struct wb_context *wb_ctx, bool need_priv,
+                               const struct winbindd_request *wb_req)
+{
+       struct async_req *result;
+       struct wb_trans_state *state;
+
+       result = async_req_new(mem_ctx);
+       if (result == NULL) {
+               return NULL;
+       }
+       state = talloc(result, struct wb_trans_state);
+       if (state == NULL) {
+               goto fail;
+       }
+       result->private_data = state;
+
+       state->wb_ctx = wb_ctx;
+       state->ev = ev;
+       state->wb_req = winbindd_request_copy(state, wb_req);
+       if (state->wb_req == NULL) {
+               goto fail;
+       }
+       state->num_retries = 10;
+       state->need_priv = need_priv;
+
+       if (!async_req_enqueue(wb_ctx->queue, ev, result, wb_trigger_trans)) {
+               goto fail;
+       }
+       return result;
+
+ fail:
+       TALLOC_FREE(result);
+       return NULL;
+}
+
+static bool wb_trans_retry(struct async_req *req,
+                          struct wb_trans_state *state,
+                          NTSTATUS status)
+{
+       struct async_req *subreq;
+
+       if (NT_STATUS_IS_OK(status)) {
+               return false;
+       }
+
+       if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)
+           || NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
+               /*
+                * Winbind not around or we can't connect to the pipe. Fail
+                * immediately.
+                */
+               async_req_error(req, status);
+               return true;
+       }
+
+       state->num_retries -= 1;
+       if (state->num_retries == 0) {
+               async_req_error(req, status);
+               return true;
+       }
+
+       /*
+        * The transfer as such failed, retry after one second
+        */
+
+       if (state->wb_ctx->fd != -1) {
+               close(state->wb_ctx->fd);
+               state->wb_ctx->fd = -1;
+       }
+
+       subreq = async_wait_send(state, state->ev, timeval_set(1, 0));
+       if (async_req_nomem(subreq, req)) {
+               return true;
+       }
+
+       subreq->async.fn = wb_trans_retry_wait_done;
+       subreq->async.priv = req;
+       return true;
+}
+
+static void wb_trans_retry_wait_done(struct async_req *subreq)
+{
+       struct async_req *req = talloc_get_type_abort(
+               subreq->async.priv, struct async_req);
+       struct wb_trans_state *state = talloc_get_type_abort(
+               req->private_data, struct wb_trans_state);
+       NTSTATUS status;
+
+       status = async_wait_recv(subreq);
+       TALLOC_FREE(subreq);
+       if (!NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
+               async_req_error(req, status);
+               return;
+       }
+
+       subreq = wb_open_pipe_send(state, state->ev, state->wb_ctx,
+                                  state->need_priv);
+       if (async_req_nomem(subreq, req)) {
+               return;
+       }
+       subreq->async.fn = wb_trans_connect_done;
+       subreq->async.priv = req;
+}
+
+static void wb_trans_connect_done(struct async_req *subreq)
+{
+       struct async_req *req = talloc_get_type_abort(
+               subreq->async.priv, struct async_req);
+       struct wb_trans_state *state = talloc_get_type_abort(
+               req->private_data, struct wb_trans_state);
+       NTSTATUS status;
+
+       status = wb_open_pipe_recv(subreq);
+       TALLOC_FREE(subreq);
+
+       if (wb_trans_retry(req, state, status)) {
+               return;
+       }
+
+       subreq = wb_int_trans_send(state, state->ev, state->wb_ctx->fd,
+                                  state->wb_req);
+       if (async_req_nomem(subreq, req)) {
+               return;
+       }
+
+       subreq->async.fn = wb_trans_done;
+       subreq->async.priv = req;
+}
+
+static void wb_trans_done(struct async_req *subreq)
+{
+       struct async_req *req = talloc_get_type_abort(
+               subreq->async.priv, struct async_req);
+       struct wb_trans_state *state = talloc_get_type_abort(
+               req->private_data, struct wb_trans_state);
+       NTSTATUS status;
+
+       status = wb_int_trans_recv(subreq, state, &state->wb_resp);
+       TALLOC_FREE(subreq);
+
+       if (wb_trans_retry(req, state, status)) {
+               return;
+       }
+
+       async_req_done(req);
+}
+
+NTSTATUS wb_trans_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
+                      struct winbindd_response **presponse)
+{
+       struct wb_trans_state *state = talloc_get_type_abort(
+               req->private_data, struct wb_trans_state);
+       NTSTATUS status;
+
+       if (async_req_is_error(req, &status)) {
+               return status;
+       }
+
+       *presponse = talloc_move(mem_ctx, &state->wb_resp);
+       return NT_STATUS_OK;
+}
index 5032ffd14cc3fe1d8b879b90e9248f2a564fdf34..7cdfbc58a4abcb3ee8177c6e3178677e343a2a3f 100644 (file)
@@ -425,21 +425,28 @@ static ADS_STATUS do_krb5_kpasswd_request(krb5_context context,
                if (!use_tcp) {
 
                        sock = open_udp_socket(kdc_host, DEFAULT_KPASSWD_PORT);
-
+                       if (sock == -1) {
+                               int rc = errno;
+                               SAFE_FREE(ap_req.data);
+                               krb5_auth_con_free(context, auth_context);
+                               DEBUG(1,("failed to open kpasswd socket to %s "
+                                        "(%s)\n", kdc_host, strerror(errno)));
+                               return ADS_ERROR_SYSTEM(rc);
+                       }
                } else {
-
-                       sock = open_socket_out(SOCK_STREAM, &addr, DEFAULT_KPASSWD_PORT, 
-                                              LONG_CONNECT_TIMEOUT);
+                       NTSTATUS status;
+                       status = open_socket_out(&addr, DEFAULT_KPASSWD_PORT,
+                                                LONG_CONNECT_TIMEOUT, &sock);
+                       if (!NT_STATUS_IS_OK(status)) {
+                               SAFE_FREE(ap_req.data);
+                               krb5_auth_con_free(context, auth_context);
+                               DEBUG(1,("failed to open kpasswd socket to %s "
+                                        "(%s)\n", kdc_host,
+                                        nt_errstr(status)));
+                               return ADS_ERROR_NT(status);
+                       }
                }
 
-               if (sock == -1) {
-                       int rc = errno;
-                       SAFE_FREE(ap_req.data);
-                       krb5_auth_con_free(context, auth_context);
-                       DEBUG(1,("failed to open kpasswd socket to %s (%s)\n",
-                                kdc_host, strerror(errno)));
-                       return ADS_ERROR_SYSTEM(rc);
-               }
                addr_len = sizeof(remote_addr);
                if (getpeername(sock, (struct sockaddr *)&remote_addr, &addr_len) != 0) {
                        close(sock);
index 82a919455a5229eeaddb648ef96d2cabc8f44dca..a1fcf8eb07353b52e261bd03a965bf1b269bd682 100644 (file)
@@ -435,7 +435,7 @@ static struct async_req *cli_request_chain(TALLOC_CTX *mem_ctx,
        req->async = tmp_reqs;
        req->num_async += 1;
 
-       req->async[req->num_async-1] = async_req_new(mem_ctx, ev);
+       req->async[req->num_async-1] = async_req_new(mem_ctx);
        if (req->async[req->num_async-1] == NULL) {
                DEBUG(0, ("async_req_new failed\n"));
                req->num_async -= 1;
index 5892bdc85928834ce9613c702259c6f374ea3bc0..6ddc249c04c16b7488bb758b9f570f25e20b9456 100644 (file)
@@ -1494,17 +1494,17 @@ bool cli_session_request(struct cli_state *cli,
                */
                uint16_t port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9);
                struct in_addr dest_ip;
+               NTSTATUS status;
 
                /* SESSION RETARGET */
                putip((char *)&dest_ip,cli->inbuf+4);
                in_addr_to_sockaddr_storage(&cli->dest_ss, dest_ip);
 
-               cli->fd = open_socket_out(SOCK_STREAM,
-                               &cli->dest_ss,
-                               port,
-                               LONG_CONNECT_TIMEOUT);
-               if (cli->fd == -1)
+               status = open_socket_out(&cli->dest_ss, port,
+                                        LONG_CONNECT_TIMEOUT, &cli->fd);
+               if (!NT_STATUS_IS_OK(status)) {
                        return False;
+               }
 
                DEBUG(3,("Retargeted\n"));
 
@@ -1533,6 +1533,78 @@ bool cli_session_request(struct cli_state *cli,
        return(True);
 }
 
+static void smb_sock_connected(struct async_req *req)
+{
+       int *pfd = (int *)req->async.priv;
+       int fd;
+       NTSTATUS status;
+
+       status = open_socket_out_defer_recv(req, &fd);
+       if (NT_STATUS_IS_OK(status)) {
+               *pfd = fd;
+       }
+}
+
+static NTSTATUS open_smb_socket(const struct sockaddr_storage *pss,
+                               uint16_t *port, int timeout, int *pfd)
+{
+       struct event_context *ev;
+       struct async_req *r139, *r445;
+       int fd139 = -1;
+       int fd445 = -1;
+       NTSTATUS status;
+
+       if (*port != 0) {
+               return open_socket_out(pss, *port, timeout, pfd);
+       }
+
+       ev = event_context_init(talloc_tos());
+       if (ev == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       r445 = open_socket_out_defer_send(ev, ev, timeval_set(0, 0),
+                                         pss, 445, timeout);
+       r139 = open_socket_out_defer_send(ev, ev, timeval_set(0, 3000),
+                                         pss, 139, timeout);
+       if ((r445 == NULL) || (r139 == NULL)) {
+               status = NT_STATUS_NO_MEMORY;
+               goto done;
+       }
+       r445->async.fn = smb_sock_connected;
+       r445->async.priv = &fd445;
+       r139->async.fn = smb_sock_connected;
+       r139->async.priv = &fd139;
+
+       while ((fd139 == -1) && (r139->state < ASYNC_REQ_DONE)
+              && (fd445 == -1) && (r445->state < ASYNC_REQ_DONE)) {
+               event_loop_once(ev);
+       }
+
+       if ((fd139 != -1) && (fd445 != -1)) {
+               close(fd139);
+               fd139 = -1;
+       }
+
+       if (fd445 != -1) {
+               *port = 445;
+               *pfd = fd445;
+               status = NT_STATUS_OK;
+               goto done;
+       }
+       if (fd139 != -1) {
+               *port = 139;
+               *pfd = fd139;
+               status = NT_STATUS_OK;
+               goto done;
+       }
+
+       status = open_socket_out_defer_recv(r445, &fd445);
+ done:
+       TALLOC_FREE(ev);
+       return status;
+}
+
 /****************************************************************************
  Open the client sockets.
 ****************************************************************************/
@@ -1587,16 +1659,11 @@ NTSTATUS cli_connect(struct cli_state *cli,
                if (getenv("LIBSMB_PROG")) {
                        cli->fd = sock_exec(getenv("LIBSMB_PROG"));
                } else {
-                       /* try 445 first, then 139 */
-                       uint16_t port = cli->port?cli->port:445;
-                       cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ss,
-                                                 port, cli->timeout);
-                       if (cli->fd == -1 && cli->port == 0) {
-                               port = 139;
-                               cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ss,
-                                                         port, cli->timeout);
-                       }
-                       if (cli->fd != -1) {
+                       uint16_t port = cli->port;
+                       NTSTATUS status;
+                       status = open_smb_socket(&cli->dest_ss, &port,
+                                                cli->timeout, &cli->fd);
+                       if (NT_STATUS_IS_OK(status)) {
                                cli->port = port;
                        }
                }
index 4597e63c98f4243a8c8f192c921564e3b5e62653..ac68700fd087f1e11d22bf5f4f5d5a083c3d8fa1 100644 (file)
@@ -54,8 +54,6 @@ static void cm_set_password(const char *newpass);
 
 static int port;
 static int name_type = 0x20;
-static bool have_ip;
-static struct sockaddr_storage dest_ss;
 
 static struct client_connection *connections;
 
@@ -133,8 +131,11 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx,
        }
        sharename = servicename;
        if (*sharename == '\\') {
-               server = sharename+2;
-               sharename = strchr_m(server,'\\');
+               sharename += 2;
+               if (server == NULL) {
+                       server = sharename;
+               }
+               sharename = strchr_m(sharename,'\\');
                if (!sharename) {
                        return NULL;
                }
@@ -151,8 +152,6 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx,
 
  again:
        zero_sockaddr(&ss);
-       if (have_ip)
-               ss = dest_ss;
 
        /* have to open a new connection */
        if (!(c=cli_initialise()) || (cli_set_port(c, port) != port)) {
@@ -550,15 +549,6 @@ void cli_cm_set_fallback_after_kerberos(void)
        cm_creds.fallback_after_kerberos = true;
 }
 
-/****************************************************************************
-****************************************************************************/
-
-void cli_cm_set_dest_ss(struct sockaddr_storage *pss)
-{
-       dest_ss = *pss;
-       have_ip = true;
-}
-
 /**********************************************************************
  split a dfs path into the server, share name, and extrapath components
 **********************************************************************/
index b33d0f09389a4cd9e2ac99aa3bb35997835ad534..1d5582e61d0e9810be779d5a24dc569a0d4467f4 100644 (file)
@@ -278,7 +278,7 @@ struct async_req *cli_pull_send(TALLOC_CTX *mem_ctx,
        struct cli_pull_state *state;
        int i;
 
-       result = async_req_new(mem_ctx, ev);
+       result = async_req_new(mem_ctx);
        if (result == NULL) {
                goto failed;
        }
@@ -302,7 +302,7 @@ struct async_req *cli_pull_send(TALLOC_CTX *mem_ctx,
        state->top_req = 0;
 
        if (size == 0) {
-               if (!async_post_status(result, NT_STATUS_OK)) {
+               if (!async_post_status(result, ev, NT_STATUS_OK)) {
                        goto failed;
                }
                return result;
@@ -843,7 +843,7 @@ static struct async_req *cli_writeall_send(TALLOC_CTX *mem_ctx,
        struct async_req *subreq;
        struct cli_writeall_state *state;
 
-       result = async_req_new(mem_ctx, ev);
+       result = async_req_new(mem_ctx);
        if (result == NULL) {
                goto fail;
        }
@@ -969,7 +969,7 @@ struct async_req *cli_push_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
        struct cli_push_state *state;
        int i;
 
-       result = async_req_new(mem_ctx, ev);
+       result = async_req_new(mem_ctx);
        if (result == NULL) {
                goto failed;
        }
@@ -1034,7 +1034,7 @@ struct async_req *cli_push_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
        }
 
        if (i == 0) {
-               if (!async_post_status(result, NT_STATUS_OK)) {
+               if (!async_post_status(result, ev, NT_STATUS_OK)) {
                        goto failed;
                }
                return result;
index 16b3b1092545390c03e98b846408a8fb578647a4..af3f7b0dd588a984683e1f9db1f1f2e784e7e387 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Samba share mode database library external interface library.
    Used by non-Samba products needing access to the Samba share mode db.
-                                                                                                                                  
+
    Copyright (C) Jeremy Allison 2005 - 2006
 
    sharemodes_procid functions (C) Copyright (C) Volker Lendecke 2005
@@ -9,17 +9,17 @@
      ** NOTE! The following LGPL license applies to this module only.
      ** This does NOT imply that all of Samba is released
      ** under the LGPL
-                                                                                                                                  
+
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 3 of the License, or (at your option) any later version.
-                                                                                                                                  
+
    This library 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
    Lesser General Public License for more details.
-                                                                                                                                  
+
    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */
@@ -92,16 +92,16 @@ int smb_share_mode_db_close(struct smbdb_ctx *db_ctx)
        return ret;
 }
 
-static TDB_DATA get_locking_key(uint64_t dev, uint64_t ino)
+static TDB_DATA get_locking_key(struct locking_key *lk, uint64_t dev,
+                               uint64_t ino)
 {
-       static struct locking_key lk;
        TDB_DATA ld;
 
-       memset(&lk, '\0', sizeof(struct locking_key));
-       lk.dev = (SMB_DEV_T)dev;
-       lk.inode = (SMB_INO_T)ino;
-       ld.dptr = (uint8 *)&lk;
-       ld.dsize = sizeof(lk);
+       memset(lk, '\0', sizeof(*lk));
+       lk->dev = (SMB_DEV_T)dev;
+       lk->inode = (SMB_INO_T)ino;
+       ld.dptr = (uint8 *)lk;
+       ld.dsize = sizeof(*lk);
        return ld;
 }
 
@@ -113,14 +113,17 @@ int smb_lock_share_mode_entry(struct smbdb_ctx *db_ctx,
                                uint64_t dev,
                                uint64_t ino)
 {
-       return tdb_chainlock(db_ctx->smb_tdb, get_locking_key(dev, ino));
+       struct locking_key lk;
+       return tdb_chainlock(db_ctx->smb_tdb, get_locking_key(&lk, dev, ino));
 }
-                                                                                                                                  
+
 int smb_unlock_share_mode_entry(struct smbdb_ctx *db_ctx,
                                 uint64_t dev,
                                 uint64_t ino)
 {
-       return tdb_chainunlock(db_ctx->smb_tdb, get_locking_key(dev, ino));
+       struct locking_key lk;
+       return tdb_chainunlock(db_ctx->smb_tdb,
+                              get_locking_key(&lk, dev, ino));
 }
 
 /*
@@ -172,6 +175,7 @@ int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx,
                                struct smb_share_mode_entry **pp_list,
                                unsigned char *p_delete_on_close)
 {
+       struct locking_key lk;
        TDB_DATA db_data;
        struct smb_share_mode_entry *list = NULL;
        int num_share_modes = 0;
@@ -183,7 +187,7 @@ int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx,
        *pp_list = NULL;
        *p_delete_on_close = 0;
 
-       db_data = tdb_fetch(db_ctx->smb_tdb, get_locking_key(dev, ino));
+       db_data = tdb_fetch(db_ctx->smb_tdb, get_locking_key(&lk, dev, ino));
        if (!db_data.dptr) {
                return 0;
        }
@@ -258,7 +262,8 @@ int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx,
                                const char *filename) /* Must be relative utf8 path. */
 {
        TDB_DATA db_data;
-       TDB_DATA locking_key =  get_locking_key(dev, ino);
+       struct locking_key lk;
+       TDB_DATA locking_key =  get_locking_key(&lk, dev, ino);
        int orig_num_share_modes = 0;
        struct locking_data *ld = NULL; /* internal samba db state. */
        struct share_mode_entry *shares = NULL;
@@ -371,7 +376,8 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx,
                                const struct smb_share_mode_entry *del_entry)
 {
        TDB_DATA db_data;
-       TDB_DATA locking_key =  get_locking_key(dev, ino);
+       struct locking_key lk;
+       TDB_DATA locking_key =  get_locking_key(&lk, dev, ino);
        int orig_num_share_modes = 0;
        struct locking_data *ld = NULL; /* internal samba db state. */
        struct share_mode_entry *shares = NULL;
@@ -473,7 +479,8 @@ int smb_change_share_mode_entry(struct smbdb_ctx *db_ctx,
                                const struct smb_share_mode_entry *new_entry)
 {
        TDB_DATA db_data;
-       TDB_DATA locking_key =  get_locking_key(dev, ino);
+       struct locking_key lk;
+       TDB_DATA locking_key =  get_locking_key(&lk, dev, ino);
        int num_share_modes = 0;
        struct locking_data *ld = NULL; /* internal samba db state. */
        struct share_mode_entry *shares = NULL;
index a4a317d9053ad27b3a971a49ed2830ac52494151..a86d39948d835ecb5690e2876c9cf4abcc6295c9 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Unix SMB/CIFS implementation.
  *
- * This file began with some code from source3/smbd/open.c and modified it to
- * work with ifs_createfile.
+ * This file began with some code from source3/smbd/open.c and has been
+ * modified it work with ifs_createfile.
  *
  * ifs_createfile is a CIFS-specific syscall for opening/files and
  * directories.  It adds support for:
@@ -459,7 +459,7 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
                DEBUG(10, ("onefs_open_file_ntcreate: printer open fname=%s\n",
                          fname));
 
-               return print_fsp_open(req, conn, fname, req->vuid, fsp);
+               return print_fsp_open(req, conn, fname, req->vuid, fsp, psbuf);
        }
 
        if (!parent_dirname(talloc_tos(), fname, &parent_dir, &newname)) {
index 63cc904bed1779cd57ef0b8bdae8a81584820ceb..3ac5a4971b7cb5153ac9ffdbd0beeb30a380df01 100644 (file)
@@ -78,6 +78,7 @@ static int smb_traffic_analyzer_connect_inet_socket(vfs_handle_struct *handle,
 
        for (res = ailist; res; res = res->ai_next) {
                struct sockaddr_storage ss;
+               NTSTATUS status;
 
                if (!res->ai_addr || res->ai_addrlen == 0) {
                        continue;
@@ -86,8 +87,8 @@ static int smb_traffic_analyzer_connect_inet_socket(vfs_handle_struct *handle,
                ZERO_STRUCT(ss);
                memcpy(&ss, res->ai_addr, res->ai_addrlen);
 
-               sockfd = open_socket_out(SOCK_STREAM, &ss, port, 10000);
-               if (sockfd != -1) {
+               status = open_socket_out(&ss, port, 10000, &sockfd);
+               if (NT_STATUS_IS_OK(status)) {
                        break;
                }
        }
index 274c79904e5b8c640e0631f8ca77cbd5521f5d5f..cb0ba47572e3cc7609ff4adf1af8cda7400c35ad 100644 (file)
@@ -4630,7 +4630,7 @@ static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
 {
        void *parm_ptr;
 
-       if (parm.ptr == NULL); {
+       if (parm.ptr == NULL) {
                return;
        }
 
index a2d334230dd34df8c86e4c69f93114c167a31554..3fd31e2867605ef985380b863cdbfd6d6b75ff2a 100644 (file)
@@ -2618,9 +2618,8 @@ static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
                goto fail;
        }
 
-       result->trans.sock.fd = open_socket_out(SOCK_STREAM, &addr, port, 60);
-       if (result->trans.sock.fd == -1) {
-               status = map_nt_error_from_unix(errno);
+       status = open_socket_out(&addr, port, 60, &result->trans.sock.fd);
+       if (!NT_STATUS_IS_OK(status)) {
                goto fail;
        }
 
index 1cff95dcaba0d713f5caa89cd433f0aa2854c60f..7d1f82423428df31c526ff3274dd40417f276832 100644 (file)
@@ -105,8 +105,7 @@ static bool pipe_init_outgoing_data(pipes_struct *p)
 static struct pipes_struct *make_internal_rpc_pipe_p(TALLOC_CTX *mem_ctx,
                                                     const char *pipe_name,
                                                     const char *client_address,
-                                                    struct auth_serversupplied_info *server_info,
-                                                    uint16_t vuid)
+                                                    struct auth_serversupplied_info *server_info)
 {
        pipes_struct *p;
 
@@ -1125,8 +1124,7 @@ NTSTATUS np_open(struct smb_request *smb_req, const char *name,
 
                p = make_internal_rpc_pipe_p(fsp->fake_file_handle, name,
                                             conn->client_address,
-                                            conn->server_info,
-                                            smb_req->vuid);
+                                            conn->server_info);
 
                fsp->fake_file_handle->type = FAKE_FILE_TYPE_NAMED_PIPE;
                fsp->fake_file_handle->private_data = p;
index 5199363fc3eb7b935d5fd215725865e66e86b283..a7916ef79429db4968b681ea273b6ced5eb373f7 100644 (file)
@@ -65,13 +65,8 @@ SMB_EXT_LIB_FROM_PKGCONFIG(LIBTDB, tdb >= 1.1.3,
 
 SMB_INCLUDE_MK(../lib/tdb/python.mk) 
 
-SMB_EXT_LIB_FROM_PKGCONFIG(LIBTEVENT, tevent >= 0.9.0,
-       [],
-       [
-               m4_include(../lib/tevent/libtevent.m4)
-               SMB_INCLUDE_MK(../lib/tevent/config.mk)
-               AC_CONFIG_FILES(../lib/tevent/tevent.pc)
-       ]
+SMB_EXT_LIB_FROM_PKGCONFIG(LIBTEVENT, tevent >= 0.9.2,
+       [],[m4_include(../lib/tevent/samba.m4)]
 )
 
 SMB_INCLUDE_MK(../lib/tevent/python.mk) 
@@ -114,8 +109,6 @@ SMB_INCLUDE_MK(lib/ldb/python.mk)
 SMB_ENABLE(swig_ldb,YES)
 
 m4_include(lib/tls/config.m4)
-teventdir="../lib/tevent"
-m4_include(../lib/tevent/libtevent.m4)
 
 dnl m4_include(auth/kerberos/config.m4)
 m4_include(auth/gensec/config.m4)
index 8466e841799a7626944fff056420a802f5cec6b6..67e6067b260667e3c64e615cb184799396a14772 100644 (file)
@@ -284,7 +284,7 @@ static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, int fd,
 
        if (CVAL(lenbuf,0) == 0 &&
                        min_recv_size &&
-                       smb_len_large(lenbuf) > min_recv_size && /* Could be a UNIX large writeX. */
+                       smb_len_large(lenbuf) > (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE) && /* Could be a UNIX large writeX. */
                        !srv_is_signing_active()) {
 
                return receive_smb_raw_talloc_partial_read(
index 81d0eb816b9fbdd415e21d930d7cd6facf6b1034..a010c80985e6d9ec3abe839c29a4c15a1242f135 100644 (file)
@@ -111,7 +111,9 @@ static void sigsegv(int sig)
        printf("segv at line %d\n", line_count);
        slprintf(line, sizeof(line), "/usr/X11R6/bin/xterm -e gdb /proc/%d/exe %d", 
                (int)getpid(), (int)getpid());
-       system(line);
+       if (system(line) == -1) {
+               printf("system() failed\n");
+       }
        exit(1);
 }
 
@@ -280,10 +282,16 @@ static void delete_fn(const char *mnt, file_info *finfo, const char *name, void
 
        n = SMB_STRDUP(name);
        n[strlen(n)-1] = 0;
-       asprintf(&s, "%s%s", n, finfo->name);
+       if (asprintf(&s, "%s%s", n, finfo->name) == -1) {
+               printf("asprintf failed\n");
+               return;
+       }
        if (finfo->mode & aDIR) {
                char *s2;
-               asprintf(&s2, "%s\\*", s);
+               if (asprintf(&s2, "%s\\*", s) == -1) {
+                       printf("asprintf failed\n");
+                       return;
+               }
                cli_list(c, s2, aDIR, delete_fn, NULL);
                nb_rmdir(s);
        } else {
@@ -297,7 +305,10 @@ static void delete_fn(const char *mnt, file_info *finfo, const char *name, void
 void nb_deltree(const char *dname)
 {
        char *mask;
-       asprintf(&mask, "%s\\*", dname);
+       if (asprintf(&mask, "%s\\*", dname) == -1) {
+               printf("asprintf failed\n");
+               return;
+       }
 
        total_deleted = 0;
        cli_list(c, mask, aDIR, delete_fn, NULL);
index 63942da2e5b72cd441a04b49c71eaec6ed71ae12..8a1a61e79ac57b972a8a0d4edf33dbc4c9f52d96 100644 (file)
@@ -1213,7 +1213,9 @@ static bool run_tcon2_test(int dummy)
 
        printf("starting tcon2 test\n");
 
-       asprintf(&service, "\\\\%s\\%s", host, share);
+       if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
+               return false;
+       }
 
        status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
 
@@ -5280,8 +5282,13 @@ static bool run_local_rbtree(int dummy)
        for (i=0; i<1000; i++) {
                char *key, *value;
 
-               asprintf(&key, "key%ld", random());
-               asprintf(&value, "value%ld", random());
+               if (asprintf(&key, "key%ld", random()) == -1) {
+                       goto done;
+               }
+               if (asprintf(&value, "value%ld", random()) == -1) {
+                       SAFE_FREE(key);
+                       goto done;
+               }
 
                if (!rbt_testval(db, key, value)) {
                        SAFE_FREE(key);
@@ -5290,7 +5297,10 @@ static bool run_local_rbtree(int dummy)
                }
 
                SAFE_FREE(value);
-               asprintf(&value, "value%ld", random());
+               if (asprintf(&value, "value%ld", random()) == -1) {
+                       SAFE_FREE(key);
+                       goto done;
+               }
 
                if (!rbt_testval(db, key, value)) {
                        SAFE_FREE(key);
@@ -5483,6 +5493,70 @@ static bool run_local_memcache(int dummy)
        return ret;
 }
 
+static void wbclient_done(struct async_req *req)
+{
+       NTSTATUS status;
+       struct winbindd_response *wb_resp;
+       int *i = (int *)req->async.priv;
+
+       status = wb_trans_recv(req, req, &wb_resp);
+       TALLOC_FREE(req);
+       *i += 1;
+       d_printf("wb_trans_recv %d returned %s\n", *i, nt_errstr(status));
+}
+
+static bool run_local_wbclient(int dummy)
+{
+       struct event_context *ev;
+       struct wb_context **wb_ctx;
+       struct winbindd_request wb_req;
+       bool result = false;
+       int i, j;
+
+       BlockSignals(True, SIGPIPE);
+
+       ev = event_context_init(talloc_tos());
+       if (ev == NULL) {
+               goto fail;
+       }
+
+       wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, torture_numops);
+       if (wb_ctx == NULL) {
+               goto fail;
+       }
+
+       ZERO_STRUCT(wb_req);
+       wb_req.cmd = WINBINDD_PING;
+
+       for (i=0; i<torture_numops; i++) {
+               wb_ctx[i] = wb_context_init(ev);
+               if (wb_ctx[i] == NULL) {
+                       goto fail;
+               }
+               for (j=0; j<5; j++) {
+                       struct async_req *req;
+                       req = wb_trans_send(ev, ev, wb_ctx[i],
+                                           (j % 2) == 0, &wb_req);
+                       if (req == NULL) {
+                               goto fail;
+                       }
+                       req->async.fn = wbclient_done;
+                       req->async.priv = &i;
+               }
+       }
+
+       i = 0;
+
+       while (i < 5 * torture_numops) {
+               event_loop_once(ev);
+       }
+
+       result = true;
+ fail:
+       TALLOC_FREE(ev);
+       return result;
+}
+
 static double create_procs(bool (*fn)(int), bool *result)
 {
        int i, status;
@@ -5642,6 +5716,7 @@ static struct {
        { "LOCAL-RBTREE", run_local_rbtree, 0},
        { "LOCAL-MEMCACHE", run_local_memcache, 0},
        { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
+       { "LOCAL-WBCLIENT", run_local_wbclient, 0},
        {NULL, NULL, 0}};
 
 
index 7032cea99b82aa1fe70eefbd95ebdb7a4e5c6f7b..e36b0388c4ed42a1c1b80ff30a5d6ed13006ea9a 100644 (file)
@@ -84,7 +84,11 @@ bool torture_utable(int dummy)
                d_printf("Failed to create valid.dat - %s", strerror(errno));
                return False;
        }
-       write(fd, valid, 0x10000);
+       if (write(fd, valid, 0x10000) != 0x10000) {
+               d_printf("Failed to create valid.dat - %s", strerror(errno));
+               close(fd);
+               return false;
+       }
        close(fd);
        d_printf("wrote valid.dat\n");
 
index 1e22a402013491fa7e3851173b1059b93b1b1490..1fdea818d6e47ae3a5d4ade03a4bc5c44678bfc9 100644 (file)
@@ -141,10 +141,11 @@ static bool send_smb(int fd, char *buffer)
 
 static void filter_child(int c, struct sockaddr_storage *dest_ss)
 {
-       int s;
+       NTSTATUS status;
+       int s = -1;
 
        /* we have a connection from a new client, now connect to the server */
-       s = open_socket_out(SOCK_STREAM, dest_ss, 445, LONG_CONNECT_TIMEOUT);
+       status = open_socket_out(dest_ss, 445, LONG_CONNECT_TIMEOUT, &s);
 
        if (s == -1) {
                char addr[INET6_ADDRSTRLEN];
index 6be55ef03c63235296a2c6abbb9addf722c6781c..ca07f230ab060ebe6868bcf9df587842664f2fe5 100644 (file)
@@ -735,6 +735,17 @@ NTSTATUS idmap_backends_unixid_to_sid(const char *domname, struct id_map *id)
        maps[0] = id;
        maps[1] = NULL;
 
+       /*
+        * Always give passdb a chance first
+        */
+
+       dom = idmap_init_passdb_domain(NULL);
+       if ((dom != NULL)
+           && NT_STATUS_IS_OK(dom->methods->unixids_to_sids(dom, maps))
+           && id->status == ID_MAPPED) {
+               return NT_STATUS_OK;
+       }
+
        dom = idmap_find_domain(domname);
        if (dom == NULL) {
                return NT_STATUS_NONE_MAPPED;
index 92ce1f985095008623b147bcf51106ff3e3a22d3..3869ac57712b6c7423bf3a5bc67a40fad0be5ba8 100644 (file)
@@ -88,15 +88,6 @@ struct async_req *wb_resp_write_send(TALLOC_CTX *mem_ctx,
                                     struct winbindd_response *wb_resp);
 NTSTATUS wb_resp_write_recv(struct async_req *req);
 
-struct async_req *wb_trans_send(TALLOC_CTX *mem_ctx,
-                               struct event_context *ev,
-                               int fd,
-                               struct winbindd_request *wb_req,
-                               struct timeval timeout,
-                               size_t reply_max_extra_data);
-NTSTATUS wb_trans_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
-                      struct winbindd_response **presp);
-
 /* The following definitions come from winbindd/winbindd_ads.c  */
 
 
index b724b8df3772d45438bc77c3c9f54efb4ed64e79..822bf398a76d463525698103fab0747c0f6e614b 100644 (file)
@@ -2,7 +2,7 @@
 # Start SUBSYSTEM KERBEROS
 [SUBSYSTEM::KERBEROS]
 PUBLIC_DEPENDENCIES = HEIMDAL_KRB5 NDR_KRB5PAC samba_socket LIBCLI_RESOLVE
-PRIVATE_DEPENDENCIES = ASN1_UTIL auth_sam_reply LIBPACKET LIBNDR
+PRIVATE_DEPENDENCIES = ASN1_UTIL auth_sam_reply LIBTEVENT LIBPACKET LIBNDR
 # End SUBSYSTEM KERBEROS
 #################################
 
index 2f0a2317a0a8ae0d0974c6736c3bb912307b2093..6e885842f3196a0adcfad9d47f85bc0f5a50a5bf 100644 (file)
 
 #include "includes.h"
 #include "system/kerberos.h"
+#include <tevent.h>
 #include "auth/kerberos/kerberos.h"
 #include "lib/socket/socket.h"
 #include "lib/stream/packet.h"
 #include "system/network.h"
-#include "lib/events/events.h"
 #include "param/param.h"
 #include "libcli/resolve/resolve.h"
 
@@ -159,9 +159,9 @@ static void smb_krb5_socket_send(struct smb_krb5_socket *smb_krb5)
 
        if (!NT_STATUS_IS_OK(status)) return;
        
-       EVENT_FD_READABLE(smb_krb5->fde);
+       TEVENT_FD_READABLE(smb_krb5->fde);
 
-       EVENT_FD_NOT_WRITEABLE(smb_krb5->fde);
+       TEVENT_FD_NOT_WRITEABLE(smb_krb5->fde);
        return;
 }
 
@@ -175,22 +175,22 @@ static void smb_krb5_socket_handler(struct tevent_context *ev, struct tevent_fd
        struct smb_krb5_socket *smb_krb5 = talloc_get_type(private, struct smb_krb5_socket);
        switch (smb_krb5->hi->proto) {
        case KRB5_KRBHST_UDP:
-               if (flags & EVENT_FD_READ) {
+               if (flags & TEVENT_FD_READ) {
                        smb_krb5_socket_recv(smb_krb5);
                        return;
                }
-               if (flags & EVENT_FD_WRITE) {
+               if (flags & TEVENT_FD_WRITE) {
                        smb_krb5_socket_send(smb_krb5);
                        return;
                }
                /* not reached */
                return;
        case KRB5_KRBHST_TCP:
-               if (flags & EVENT_FD_READ) {
+               if (flags & TEVENT_FD_READ) {
                        packet_recv(smb_krb5->packet);
                        return;
                }
-               if (flags & EVENT_FD_WRITE) {
+               if (flags & TEVENT_FD_WRITE) {
                        packet_queue_run(smb_krb5->packet);
                        return;
                }
@@ -284,24 +284,24 @@ krb5_error_code smb_krb5_send_and_recv_func(krb5_context context,
                 * drop) and mark as AUTOCLOSE along with the fde */
 
                /* Ths is equivilant to EVENT_FD_READABLE(smb_krb5->fde) */
-               smb_krb5->fde = event_add_fd(ev, smb_krb5->sock, 
-                                            socket_get_fd(smb_krb5->sock), 
-                                            EVENT_FD_READ|EVENT_FD_AUTOCLOSE,
-                                            smb_krb5_socket_handler, smb_krb5);
+               smb_krb5->fde = tevent_add_fd(ev, smb_krb5->sock,
+                                             socket_get_fd(smb_krb5->sock),
+                                             TEVENT_FD_READ,
+                                             smb_krb5_socket_handler, smb_krb5);
                /* its now the job of the event layer to close the socket */
+               tevent_fd_set_close_fn(smb_krb5->fde, socket_tevent_fd_close_fn);
                socket_set_flags(smb_krb5->sock, SOCKET_FLAG_NOCLOSE);
 
-               event_add_timed(ev, smb_krb5, 
-                               timeval_current_ofs(timeout, 0),
-                               smb_krb5_request_timeout, smb_krb5);
+               tevent_add_timer(ev, smb_krb5,
+                                timeval_current_ofs(timeout, 0),
+                                smb_krb5_request_timeout, smb_krb5);
 
-               
                smb_krb5->status = NT_STATUS_OK;
                smb_krb5->reply = data_blob(NULL, 0);
 
                switch (hi->proto) {
                case KRB5_KRBHST_UDP:
-                       EVENT_FD_WRITEABLE(smb_krb5->fde);
+                       TEVENT_FD_WRITEABLE(smb_krb5->fde);
                        smb_krb5->request = send_blob;
                        break;
                case KRB5_KRBHST_TCP:
@@ -329,7 +329,7 @@ krb5_error_code smb_krb5_send_and_recv_func(krb5_context context,
                        return EINVAL;
                }
                while ((NT_STATUS_IS_OK(smb_krb5->status)) && !smb_krb5->reply.length) {
-                       if (event_loop_once(ev) != 0) {
+                       if (tevent_loop_once(ev) != 0) {
                                talloc_free(smb_krb5);
                                return EINVAL;
                        }
index 5be4189e064f9af019200fa75b62fc1dd4d58de8..e51a8ac1464c71e5ce3a381c70a571abcb5357e8 100644 (file)
@@ -155,6 +155,14 @@ SMB_INFO_ENABLES="$SMB_INFO_ENABLES
 \$enabled{$1} = \"$2\";"
 ])
 
+dnl SMB_MAKE_SETTINGS(text)
+AC_DEFUN([SMB_MAKE_SETTINGS],
+[
+MAKE_SETTINGS="$MAKE_SETTINGS
+$1
+"
+])
+
 dnl SMB_WRITE_MAKEVARS(path, skip_vars)
 AC_DEFUN([SMB_WRITE_MAKEVARS],
 [
index debdc39d58abb0bfa3ebd353cb81d1e552f220ac..6c8fb0efc28c991fcf77afa75b2757244df2f6a5 100644 (file)
@@ -60,13 +60,8 @@ SMB_EXT_LIB_FROM_PKGCONFIG(LIBTDB, tdb >= 1.1.3,
 
 SMB_INCLUDE_MK(../lib/tdb/python.mk) 
 
-SMB_EXT_LIB_FROM_PKGCONFIG(LIBTEVENT, tevent >= 0.9.0,
-       [],
-       [
-               m4_include(../lib/tevent/libtevent.m4)
-               SMB_INCLUDE_MK(../lib/tevent/config.mk)
-               AC_CONFIG_FILES(../lib/tevent/tevent.pc)
-       ]
+SMB_EXT_LIB_FROM_PKGCONFIG(LIBTEVENT, tevent >= 0.9.2,
+       [],[m4_include(../lib/tevent/samba.m4)]
 )
 
 SMB_INCLUDE_MK(../lib/tevent/python.mk) 
index d5e70a73048f8e50fdfe9f3b652af63c002428ea..c27ec2f2deadf77a9c399204487eb650d205fda5 100644 (file)
@@ -49,11 +49,8 @@ param/share.h: share.h
 ../lib/util/util_tdb.h: util_tdb.h
 ../lib/util/util_ldb.h: util_ldb.h
 ../lib/util/wrap_xattr.h: wrap_xattr.h
-lib/events/events.h: events/events.h
-lib/events/events_internal.h: events/events_internal.h
 libcli/ldap/ldap_ndr.h: ldap_ndr.h
 lib/events/events.h: events.h
-lib/events/events_internal.h: events_internal.h
 ../lib/tevent/tevent.h: tevent.h
 ../lib/tevent/tevent_internal.h: tevent_internal.h
 auth/session.h: samba/session.h
index a1b2cd218ac1286c54aa836b4e97bc4d214740bf..c07a21bc75b8cfa1a36b44c9abef0cc3a0b48eef 100644 (file)
@@ -4,4 +4,4 @@ CFLAGS = -Ilib/events
 
 LIBEVENTS_OBJ_FILES = $(addprefix $(libeventssrcdir)/, tevent_s4.o)
 
-PUBLIC_HEADERS += $(addprefix $(libeventssrcdir)/, events.h events_internal.h)
+PUBLIC_HEADERS += $(addprefix $(libeventssrcdir)/, events.h)
index 698ff2919ba43c803282d6fcddbda6e97790163c..1b2dbde32b143eaa9025406f8d4437184ad6ecd9 100644 (file)
@@ -3,5 +3,5 @@
 #define TEVENT_COMPAT_DEFINES 1
 #include <../lib/tevent/tevent.h>
 struct tevent_context *s4_event_context_init(TALLOC_CTX *mem_ctx);
-struct tevent_context *event_context_find(TALLOC_CTX *mem_ctx);
+struct tevent_context *event_context_find(TALLOC_CTX *mem_ctx) _DEPRECATED_;
 #endif /* __LIB_EVENTS_H__ */
diff --git a/source4/lib/events/events_internal.h b/source4/lib/events/events_internal.h
deleted file mode 100644 (file)
index 055bfe1..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-#ifndef __LIB_EVENTS_INTERNAL_H__
-#define __LIB_EVENTS_INTERNAL_H__
-#define TEVENT_COMPAT_DEFINES 1
-#include <../lib/tevent/tevent_internal.h>
-#endif /* __LIB_EVENTS_INTERNAL_H__ */
index b3de7e667a52e7ecbaddeff0e22bd310e0909362..34a34a8e0b33a57766f60da87d61ab1f8d5cc8d8 100644 (file)
 */
 
 #include "includes.h"
-#include <events.h>
-#include <events_internal.h>
+#include "lib/events/events.h"
 
 /*
   this is used to catch debug messages from events
 */
-static void ev_wrap_debug(void *context, enum ev_debug_level level,
+static void ev_wrap_debug(void *context, enum tevent_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,
+static void ev_wrap_debug(void *context, enum tevent_debug_level level,
                          const char *fmt, va_list ap)
 {
        int samba_level = -1;
        char *s = NULL;
        switch (level) {
-       case EV_DEBUG_FATAL:
+       case TEVENT_DEBUG_FATAL:
                samba_level = 0;
                break;
-       case EV_DEBUG_ERROR:
+       case TEVENT_DEBUG_ERROR:
                samba_level = 1;
                break;
-       case EV_DEBUG_WARNING:
+       case TEVENT_DEBUG_WARNING:
                samba_level = 2;
                break;
-       case EV_DEBUG_TRACE:
+       case TEVENT_DEBUG_TRACE:
                samba_level = 5;
                break;
 
        };
        vasprintf(&s, fmt, ap);
        if (!s) return;
-       DEBUG(samba_level, ("events: %s\n", s));
+       DEBUG(samba_level, ("tevent: %s\n", s));
        free(s);
 }
 
@@ -63,10 +62,27 @@ struct tevent_context *s4_event_context_init(TALLOC_CTX *mem_ctx)
 {
        struct tevent_context *ev;
 
-       ev = event_context_init_byname(mem_ctx, NULL);
+       ev = tevent_context_init_byname(mem_ctx, NULL);
        if (ev) {
-               ev_set_debug(ev, ev_wrap_debug, NULL);
+               tevent_set_debug(ev, ev_wrap_debug, NULL);
        }
        return 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 tevent_context *event_context_find(TALLOC_CTX *mem_ctx)
+{
+       struct tevent_context *ev = talloc_find_parent_bytype(mem_ctx, struct tevent_context);
+       if (ev == NULL) {               
+               ev = tevent_context_init(mem_ctx);
+       }
+       return ev;
+}
index 2d2f2fb6859ed3d204e5f8cc39cd762f865440e6..357305c4de35316db5cca8054330ceeba5e08240 100644 (file)
@@ -357,7 +357,7 @@ static PyObject *py_open_ldb_file(PyObject *self, PyObject *args, PyObject *kwar
        session_info = NULL; /* FIXME */
 
        result = reg_open_ldb_file(NULL, location, session_info, credentials,
-                                                          event_context_init(NULL), lp_ctx, &key);
+                                                          tevent_context_init(NULL), lp_ctx, &key);
        PyErr_WERROR_IS_ERR_RAISE(result);
 
        return py_talloc_import(&PyHiveKey, key);
index a869ed44404f81014e431f594db7eed22d0b9882..4cbcb09a1027329412112b59c5411ad459d18126 100644 (file)
@@ -543,7 +543,7 @@ static WERROR regf_get_value(TALLOC_CTX *ctx, struct hive_key *key,
 
        if (vk->data_length & 0x80000000) {
                vk->data_length &=~0x80000000;
-               data->data = (uint8_t *)&vk->data_offset;
+               data->data = talloc_memdup(ctx, (uint8_t *)&vk->data_offset, vk->data_length);
                data->length = vk->data_length;
        } else {
                *data = hbin_get(regf, vk->data_offset);
@@ -2045,7 +2045,7 @@ WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, const char *location,
        struct tdr_pull *pull;
        int i;
 
-       regf = (struct regf_data *)talloc_zero(NULL, struct regf_data);
+       regf = (struct regf_data *)talloc_zero(parent_ctx, struct regf_data);
 
        regf->iconv_convenience = iconv_convenience;
 
index c9f1248bf8e628506b3dda494861f421c2650a31..d997cb0fde585d6797d6c968b1d1b5c65f3a67b0 100644 (file)
@@ -51,7 +51,7 @@ struct registry_key *reg_common_open_file(const char *path,
        struct registry_context *h = NULL;
        WERROR error;
 
-       error = reg_open_hive(NULL, path, NULL, creds, ev_ctx, lp_ctx, &hive_root);
+       error = reg_open_hive(ev_ctx, path, NULL, creds, ev_ctx, lp_ctx, &hive_root);
 
        if(!W_ERROR_IS_OK(error)) {
                fprintf(stderr, "Unable to open '%s': %s \n",
index cca009a0e2c95f7d853ab6f62ab90789d00342c9..948ed49312d4eecfef143f23759c7e0a483ecd7e 100644 (file)
@@ -55,13 +55,16 @@ static void print_tree(int level, struct registry_key *p,
                                                                      &keyname,
                                                                      NULL,
                                                                      NULL)); i++) {
-               SMB_ASSERT(strlen(keyname) > 0);
+
+               SMB_ASSERT(strlen(keyname) > 0);
                if (!W_ERROR_IS_OK(reg_open_key(mem_ctx, p, keyname, &subkey)))
-                       continue;
+                       continue;
+
                print_tree(level+1, subkey, (fullpath && strlen(name))?
-                                               talloc_asprintf(mem_ctx, "%s\\%s",
-                                                               name, keyname):
-                                               keyname, fullpath, novals);
+                                               talloc_asprintf(mem_ctx, "%s\\%s",
+                                                               name, keyname):
+                                               keyname, fullpath, novals);
+               talloc_free(subkey);
        }
        talloc_free(mem_ctx);
 
index 26cdac99a3dfe7bd48dab5b2ecece75f8f774ffa..9d30e0a77ef7f87aa893b2bd0ad2d1a2248b1b19 100644 (file)
@@ -37,6 +37,15 @@ static int socket_destructor(struct socket_context *sock)
        return 0;
 }
 
+_PUBLIC_ void socket_tevent_fd_close_fn(struct tevent_context *ev,
+                                       struct tevent_fd *fde,
+                                       int fd,
+                                       void *private_data)
+{
+       /* this might be the socket_wrapper swrap_close() */
+       close(fd);
+}
+
 _PUBLIC_ NTSTATUS socket_create_with_ops(TALLOC_CTX *mem_ctx, const struct socket_ops *ops,
                                         struct socket_context **new_sock, 
                                         enum socket_type type, uint32_t flags)
index 7a27e3070b7efedab85a4d894d08c970dc21c728..e9338127c4b398a219bb0270f41a687496922581 100644 (file)
@@ -21,6 +21,7 @@
 #define _SAMBA_SOCKET_H
 
 struct tevent_context;
+struct tevent_fd;
 struct socket_context;
 
 enum socket_type {
@@ -205,6 +206,11 @@ NTSTATUS socket_connect_multi(TALLOC_CTX *mem_ctx, const char *server_address,
 void set_socket_options(int fd, const char *options);
 void socket_set_flags(struct socket_context *socket, unsigned flags);
 
+void socket_tevent_fd_close_fn(struct tevent_context *ev,
+                              struct tevent_fd *fde,
+                              int fd,
+                              void *private_data);
+
 extern bool testnonblock;
 
 #endif /* _SAMBA_SOCKET_H */
index 2e50596dadcb5a3b8a0b2d348ebb27a8b64a7fe6..11157c5b63cb7f22a1baa55a5854d24b8547a459 100644 (file)
@@ -1,5 +1,5 @@
 [SUBSYSTEM::LIBCLI_LDAP]
-PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS LIBPACKET 
+PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBTEVENT LIBPACKET
 PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba_socket NDR_SAMR LIBTLS ASN1_UTIL \
                                           LDAP_ENCODE LIBNDR LP_RESOLVE gensec
 
index 18784135cc58297b4ae4919247ba8a5bf0191026..e30d5032fb5ebf665cc7e5dbc265a633e2ed305c 100644 (file)
 */
 
 #include "includes.h"
+#include <tevent.h>
+#include "lib/socket/socket.h"
 #include "../lib/util/asn1.h"
 #include "../lib/util/dlinklist.h"
-#include "lib/events/events.h"
-#include "lib/socket/socket.h"
 #include "libcli/ldap/ldap.h"
 #include "libcli/ldap/ldap_proto.h"
 #include "libcli/ldap/ldap_client.h"
@@ -229,11 +229,11 @@ static void ldap_io_handler(struct tevent_context *ev, struct tevent_fd *fde,
 {
        struct ldap_connection *conn = talloc_get_type(private_data, 
                                                       struct ldap_connection);
-       if (flags & EVENT_FD_WRITE) {
+       if (flags & TEVENT_FD_WRITE) {
                packet_queue_run(conn->packet);
                if (!tls_enabled(conn->sock)) return;
        }
-       if (flags & EVENT_FD_READ) {
+       if (flags & TEVENT_FD_READ) {
                ldap_read_io_handler(private_data, flags);
        }
 }
@@ -387,14 +387,15 @@ static void ldap_connect_got_sock(struct composite_context *ctx,
                                  struct ldap_connection *conn) 
 {
        /* setup a handler for events on this socket */
-       conn->event.fde = event_add_fd(conn->event.event_ctx, conn->sock, 
-                                      socket_get_fd(conn->sock), 
-                                      EVENT_FD_READ | EVENT_FD_AUTOCLOSE, ldap_io_handler, conn);
+       conn->event.fde = tevent_add_fd(conn->event.event_ctx, conn->sock,
+                                       socket_get_fd(conn->sock),
+                                       TEVENT_FD_READ, ldap_io_handler, conn);
        if (conn->event.fde == NULL) {
                composite_error(ctx, NT_STATUS_INTERNAL_ERROR);
                return;
        }
 
+       tevent_fd_set_close_fn(conn->event.fde, socket_tevent_fd_close_fn);
        socket_set_flags(conn->sock, SOCKET_FLAG_NOCLOSE);
 
        talloc_steal(conn, conn->sock);
@@ -621,8 +622,8 @@ _PUBLIC_ struct ldap_request *ldap_request_send(struct ldap_connection *conn,
                req->state = LDAP_REQUEST_DONE;
                /* we can't call the async callback now, as it isn't setup, so
                   call it as next event */
-               event_add_timed(conn->event.event_ctx, req, timeval_zero(),
-                               ldap_request_complete, req);
+               tevent_add_timer(conn->event.event_ctx, req, timeval_zero(),
+                                ldap_request_complete, req);
                return req;
        }
 
@@ -630,17 +631,17 @@ _PUBLIC_ struct ldap_request *ldap_request_send(struct ldap_connection *conn,
        DLIST_ADD(conn->pending, req);
 
        /* put a timeout on the request */
-       req->time_event = event_add_timed(conn->event.event_ctx, req, 
-                                         timeval_current_ofs(conn->timeout, 0),
-                                         ldap_request_timeout, req);
+       req->time_event = tevent_add_timer(conn->event.event_ctx, req,
+                                          timeval_current_ofs(conn->timeout, 0),
+                                          ldap_request_timeout, req);
 
        return req;
 
 failed:
        req->status = status;
        req->state = LDAP_REQUEST_ERROR;
-       event_add_timed(conn->event.event_ctx, req, timeval_zero(),
-                       ldap_request_complete, req);
+       tevent_add_timer(conn->event.event_ctx, req, timeval_zero(),
+                        ldap_request_complete, req);
 
        return req;
 }
@@ -653,7 +654,7 @@ failed:
 _PUBLIC_ NTSTATUS ldap_request_wait(struct ldap_request *req)
 {
        while (req->state < LDAP_REQUEST_DONE) {
-               if (event_loop_once(req->conn->event.event_ctx) != 0) {
+               if (tevent_loop_once(req->conn->event.event_ctx) != 0) {
                        req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR;
                        break;
                }
@@ -768,7 +769,7 @@ _PUBLIC_ NTSTATUS ldap_result_n(struct ldap_request *req, int n, struct ldap_mes
        NT_STATUS_HAVE_NO_MEMORY(req);
 
        while (req->state < LDAP_REQUEST_DONE && n >= req->num_replies) {
-               if (event_loop_once(req->conn->event.event_ctx) != 0) {
+               if (tevent_loop_once(req->conn->event.event_ctx) != 0) {
                        return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
                }
        }
index fe1997b4371dc2b4083ad680df60909091d43c2e..a6f79dfbb3839d37e2867db662d11c7594270419 100644 (file)
@@ -30,8 +30,7 @@ if test x"$ac_cv_func_ext_blkid_get_cache" = x"yes"; then
        SMB_ENABLE(BLKID,YES)
 fi
 
-AC_CHECK_HEADERS(libaio.h)
 SMB_ENABLE(pvfs_aio,NO)
-if test x"$ac_cv_header_libaio_h" = x"yes"; then
+if test x"$tevent_cv_aio_support" = x"yes"; then
        SMB_ENABLE(pvfs_aio,YES)
 fi
index ec1cdf3659b0219b86f017d71c83292714826c59..1d7949214ac26dd395e9528bcfeda99d5a7e5181 100644 (file)
@@ -29,7 +29,7 @@ pvfs_acl_nfs4_OBJ_FILES = $(ntvfssrcdir)/posix/pvfs_acl_nfs4.o
 
 ################################################
 [SUBSYSTEM::pvfs_aio]
-PRIVATE_DEPENDENCIES = LIBTEVENT LIBAIO_LINUX
+PRIVATE_DEPENDENCIES = LIBTEVENT LIBTEVENT_EXT
 ################################################
 
 pvfs_aio_OBJ_FILES = $(ntvfssrcdir)/posix/pvfs_aio.o
index f7aa91dd0e1dd7efc60a6a8c3c6b3c1472f46489..42aac0b09747ae9665ac20601563cd82afc7d42b 100644 (file)
@@ -23,8 +23,8 @@
 
 #include "includes.h"
 #include "system/filesys.h"
+#include <tevent.h>
 #include "ntvfs/sysdep/sys_notify.h"
-#include "lib/events/events.h"
 #include "../lib/util/dlinklist.h"
 #include "libcli/raw/smb.h"
 #include "param/param.h"
@@ -249,8 +249,11 @@ static void inotify_handler(struct tevent_context *ev, struct tevent_fd *fde,
 static NTSTATUS inotify_setup(struct sys_notify_context *ctx)
 {
        struct inotify_private *in;
+       struct tevent_fd *fde;
+
        in = talloc(ctx, struct inotify_private);
        NT_STATUS_HAVE_NO_MEMORY(in);
+
        in->fd = inotify_init();
        if (in->fd == -1) {
                DEBUG(0,("Failed to init inotify - %s\n", strerror(errno)));
@@ -263,8 +266,19 @@ static NTSTATUS inotify_setup(struct sys_notify_context *ctx)
        ctx->private_data = in;
 
        /* add a event waiting for the inotify fd to be readable */
-       event_add_fd(ctx->ev, in, in->fd, EVENT_FD_READ|EVENT_FD_AUTOCLOSE, inotify_handler, in);
-       
+       fde = tevent_add_fd(ctx->ev, in, in->fd,
+                          TEVENT_FD_READ, inotify_handler, in);
+       if (!fde) {
+               if (errno == 0) {
+                       errno = ENOMEM;
+               }
+               DEBUG(0,("Failed to tevent_add_fd() - %s\n", strerror(errno)));
+               talloc_free(in);
+               return map_nt_error_from_unix(errno);
+       }
+
+       tevent_fd_set_auto_close(fde);
+
        return NT_STATUS_OK;
 }
 
index 0a5bdf62cde2d393849bf5cfad274ee93179f64e..56cbacbdaf7ce9a1537b1d7af1edae5bc59990b6 100755 (executable)
@@ -401,7 +401,7 @@ plantest "samr.python" dc $SUBUNITRUN samba.tests.dcerpc.sam
 plantest "dcerpc.bare.python" dc $SUBUNITRUN samba.tests.dcerpc.bare
 plantest "unixinfo.python" dc $SUBUNITRUN samba.tests.dcerpc.unix
 plantest "samdb.python" none $SUBUNITRUN samba.tests.samdb
-plantest "events.python" none PYTHONPATH="$PYTHONPATH:../lib/tevent" $SUBUNITRUN tests
+plantest "tevent.python" none PYTHONPATH="$PYTHONPATH:../lib/tevent" $SUBUNITRUN tests
 plantest "messaging.python" none PYTHONPATH="$PYTHONPATH:lib/messaging/tests" $SUBUNITRUN bindings
 plantest "samba3sam.python" none PYTHONPATH="$PYTHONPATH:dsdb/samdb/ldb_modules/tests" $SUBUNITRUN samba3sam
 plantest "subunit.python" none $SUBUNITRUN subunit
index e0b09f4b8c2770957d93b2e305efa78f868f40be..a76d10cbe721e9c274667ae03a6cfa538ab72c46 100644 (file)
@@ -2,7 +2,7 @@
 
 [SUBSYSTEM::service]
 PRIVATE_DEPENDENCIES = \
-               LIBEVENTS MESSAGING samba_socket NDR_NAMED_PIPE_AUTH
+               LIBTEVENT MESSAGING samba_socket NDR_NAMED_PIPE_AUTH
 
 service_OBJ_FILES = $(addprefix $(smbdsrcdir)/, \
                service.o \
@@ -21,6 +21,7 @@ $(eval $(call proto_header_template,$(smbdsrcdir)/pidfile.h,$(PIDFILE_OBJ_FILES:
 [BINARY::samba]
 INSTALLDIR = SBINDIR
 PRIVATE_DEPENDENCIES = \
+               LIBEVENTS \
                process_model \
                service \
                LIBSAMBA-HOSTCONFIG \
index c1683a48dcf77eca25bc89ca63ab2043c358dad2..df970661f17c9b161da632862d409515fcdb3b66 100644 (file)
@@ -266,7 +266,7 @@ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[
        umask(0);
 
        DEBUG(0,("%s version %s started.\n", binary_name, SAMBA_VERSION_STRING));
-       DEBUGADD(0,("Copyright Andrew Tridgell and the Samba Team 1992-2008\n"));
+       DEBUGADD(0,("Copyright Andrew Tridgell and the Samba Team 1992-2009\n"));
 
        if (sizeof(uint16_t) < 2 || sizeof(uint32_t) < 4 || sizeof(uint64_t) < 8) {
                DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
@@ -323,7 +323,7 @@ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[
 
        if (opt_interactive) {
                /* terminate when stdin goes away */
-               stdin_event_flags = EVENT_FD_READ;
+               stdin_event_flags = TEVENT_FD_READ;
        } else {
                /* stay alive forever */
                stdin_event_flags = 0;
@@ -333,15 +333,15 @@ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[
 #ifdef SIGTTIN
        signal(SIGTTIN, SIG_IGN);
 #endif
-       event_add_fd(event_ctx, event_ctx, 0, stdin_event_flags,
-                    server_stdin_handler,
-                    discard_const(binary_name));
+       tevent_add_fd(event_ctx, event_ctx, 0, stdin_event_flags,
+                     server_stdin_handler,
+                     discard_const(binary_name));
 
        if (max_runtime) {
-               event_add_timed(event_ctx, event_ctx, 
-                               timeval_current_ofs(max_runtime, 0), 
-                               max_runtime_handler,
-                               discard_const(binary_name));
+               tevent_add_timer(event_ctx, event_ctx,
+                                timeval_current_ofs(max_runtime, 0),
+                                max_runtime_handler,
+                                discard_const(binary_name));
        }
 
        DEBUG(0,("%s: using '%s' process model\n", binary_name, model));
@@ -354,7 +354,7 @@ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[
 
        /* wait for events - this is where smbd sits for most of its
           life */
-       event_loop_wait(event_ctx);
+       tevent_loop_wait(event_ctx);
 
        /* as everything hangs off this event context, freeing it
           should initiate a clean shutdown of all services */
index 94fd501ffea498e5a241e52ff38ff03399d593ab..02b71de7c3f17231c0261b93e69550c67b237814 100644 (file)
@@ -20,7 +20,7 @@
 */
 
 #include "includes.h"
-#include "lib/events/events.h"
+#include <tevent.h>
 #include "lib/socket/socket.h"
 #include "smbd/service.h"
 #include "param/param.h"
@@ -49,7 +49,7 @@ static void named_pipe_handover_connection(void *private_data)
                private_data, struct named_pipe_connection);
        struct stream_connection *conn = pipe_conn->connection;
 
-       EVENT_FD_NOT_WRITEABLE(conn->event.fde);
+       TEVENT_FD_NOT_WRITEABLE(conn->event.fde);
 
        if (!NT_STATUS_IS_OK(pipe_conn->status)) {
                stream_terminate_connection(conn, nt_errstr(pipe_conn->status));
@@ -64,7 +64,7 @@ static void named_pipe_handover_connection(void *private_data)
        talloc_free(pipe_conn);
 
        /* we're now ready to start receiving events on this stream */
-       EVENT_FD_READABLE(conn->event.fde);
+       TEVENT_FD_READABLE(conn->event.fde);
 
        /*
         * hand over to the real pipe implementation,
index ef98919f937339d23be580a9278ce66484d55fdd..6dff01f4f357163323e51e15328eadc4ddc074d2 100644 (file)
@@ -21,8 +21,8 @@
 */
 
 #include "includes.h"
+#include <tevent.h>
 #include "process_model.h"
-#include "lib/events/events.h"
 #include "lib/socket/socket.h"
 #include "smbd/service.h"
 #include "smbd/service_stream.h"
@@ -72,7 +72,7 @@ void stream_terminate_connection(struct stream_connection *srv_conn, const char
                 *
                 * and we don't want to read or write to the connection...
                 */
-               event_set_fd_flags(srv_conn->event.fde, 0);
+               tevent_fd_set_flags(srv_conn->event.fde, 0);
                return;
        }
 
@@ -88,9 +88,9 @@ void stream_terminate_connection(struct stream_connection *srv_conn, const char
 static void stream_io_handler(struct stream_connection *conn, uint16_t flags)
 {
        conn->processing++;
-       if (flags & EVENT_FD_WRITE) {
+       if (flags & TEVENT_FD_WRITE) {
                conn->ops->send_handler(conn, flags);
-       } else if (flags & EVENT_FD_READ) {
+       } else if (flags & TEVENT_FD_READ) {
                conn->ops->recv_handler(conn, flags);
        }
        conn->processing--;
@@ -144,9 +144,14 @@ NTSTATUS stream_new_connection_merge(struct tevent_context *ev,
        srv_conn->msg_ctx       = msg_ctx;
        srv_conn->event.ctx     = ev;
        srv_conn->lp_ctx        = lp_ctx;
-       srv_conn->event.fde     = event_add_fd(ev, srv_conn, socket_get_fd(sock),
-                                              EVENT_FD_READ, 
-                                              stream_io_handler_fde, srv_conn);
+       srv_conn->event.fde     = tevent_add_fd(ev, srv_conn, socket_get_fd(sock),
+                                               TEVENT_FD_READ,
+                                               stream_io_handler_fde, srv_conn);
+       if (!srv_conn->event.fde) {
+               talloc_free(srv_conn);
+               return NT_STATUS_NO_MEMORY;
+       }
+
        *_srv_conn = srv_conn;
        return NT_STATUS_OK;
 }
@@ -179,14 +184,19 @@ static void stream_new_connection(struct tevent_context *ev,
        srv_conn->ops           = stream_socket->ops;
        srv_conn->event.ctx     = ev;
        srv_conn->lp_ctx        = lp_ctx;
-       srv_conn->event.fde     = event_add_fd(ev, srv_conn, socket_get_fd(sock),
-                                              0, stream_io_handler_fde, srv_conn);
 
        if (!socket_check_access(sock, "smbd", lp_hostsallow(NULL, lp_default_service(lp_ctx)), lp_hostsdeny(NULL, lp_default_service(lp_ctx)))) {
                stream_terminate_connection(srv_conn, "denied by access rules");
                return;
        }
 
+       srv_conn->event.fde     = tevent_add_fd(ev, srv_conn, socket_get_fd(sock),
+                                               0, stream_io_handler_fde, srv_conn);
+       if (!srv_conn->event.fde) {
+               stream_terminate_connection(srv_conn, "tevent_add_fd() failed");
+               return;
+       }
+
        /* setup to receive internal messages on this connection */
        srv_conn->msg_ctx = messaging_init(srv_conn, 
                                           lp_messaging_path(srv_conn, lp_ctx),
@@ -214,7 +224,7 @@ static void stream_new_connection(struct tevent_context *ev,
        talloc_free(s);
 
        /* we're now ready to start receiving events on this stream */
-       EVENT_FD_READABLE(srv_conn->event.fde);
+       TEVENT_FD_READABLE(srv_conn->event.fde);
 
        /* call the server specific accept code */
        stream_socket->ops->accept_connection(srv_conn);
@@ -258,6 +268,7 @@ NTSTATUS stream_setup_socket(struct tevent_context *event_context,
        NTSTATUS status;
        struct stream_socket *stream_socket;
        struct socket_address *socket_address;
+       struct tevent_fd *fde;
        int i;
 
        stream_socket = talloc_zero(event_context, struct stream_socket);
@@ -322,20 +333,24 @@ NTSTATUS stream_setup_socket(struct tevent_context *event_context,
                return status;
        }
 
-       /* By specifying EVENT_FD_AUTOCLOSE below, we indicate that we
-        * will close the socket using the events system.  This avoids
-        * nasty interactions with waiting for talloc to close the socket. */
-
-       socket_set_flags(stream_socket->sock, SOCKET_FLAG_NOCLOSE);
-
        /* Add the FD from the newly created socket into the event
         * subsystem.  it will call the accept handler whenever we get
         * new connections */
 
-       event_add_fd(event_context, stream_socket->sock, 
-                    socket_get_fd(stream_socket->sock), 
-                    EVENT_FD_READ|EVENT_FD_AUTOCLOSE, 
-                    stream_accept_handler, stream_socket);
+       fde = tevent_add_fd(event_context, stream_socket->sock,
+                           socket_get_fd(stream_socket->sock),
+                           TEVENT_FD_READ,
+                           stream_accept_handler, stream_socket);
+       if (!fde) {
+               DEBUG(0,("Failed to setup fd event\n"));
+               talloc_free(stream_socket);
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       /* we let events system to the close on the socket. This avoids
+        * nasty interactions with waiting for talloc to close the socket. */
+       tevent_fd_set_close_fn(fde, socket_tevent_fd_close_fn);
+       socket_set_flags(stream_socket->sock, SOCKET_FLAG_NOCLOSE);
 
        stream_socket->private          = talloc_reference(stream_socket, private);
        stream_socket->ops              = stream_ops;
index 34ce755b9316f48af773704937eb1ca4c72b192c..d3951a4a9ab8ecaedc8ea0972480d085a2c815be 100644 (file)
@@ -21,7 +21,6 @@
 
 #include "includes.h"
 #include "process_model.h"
-#include "lib/events/events.h"
 #include "smbd/service.h"
 #include "smbd/service_task.h"
 #include "lib/messaging/irpc.h"
index f88a641059b7523a5063e7f68b02fe7f3ccf6ac5..732b84af731166897b06258a2f6ef423a72c0e26 100644 (file)
@@ -656,7 +656,10 @@ double torture_create_procs(struct torture_context *tctx,
                        pid_t mypid = getpid();
                        srandom(((int)mypid) ^ ((int)time(NULL)));
 
-                       asprintf(&myname, "CLIENT%d", i);
+                       if (asprintf(&myname, "CLIENT%d", i) == -1) {
+                               printf("asprintf failed\n");
+                               return -1;
+                       }
                        lp_set_cmdline(tctx->lp_ctx, "netbios name", myname);
                        free(myname);
 
index 637cf10bb78d3520f5c8e8be68c412d4371802c4..5953474c52fdf680630685a8363b9ffbd01317d8 100644 (file)
@@ -402,8 +402,7 @@ static void init_domain_recv_samr(struct composite_context *ctx)
        talloc_steal(state->domain->libnet_ctx->samr.pipe, state->domain->samr_binding);
        state->domain->libnet_ctx->samr.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
        state->domain->libnet_ctx->samr.name = state->domain->info->name;
-       state->domain->libnet_ctx->samr.sid = dom_sid_dup(state->ctx,
-                                             state->domain->info->sid);
+       state->domain->libnet_ctx->samr.sid = state->domain->info->sid;
 
        composite_done(state->ctx);
 }
index 6cad76b08b0726a04208dbe0c8a02b786eef6683..6af92668a37ca5ffe81bbaf5f18d71caa66f08c9 100644 (file)
@@ -115,7 +115,7 @@ NTSTATUS wbsrv_samba3_priv_pipe_dir(struct wbsrv_samba3_call *s3call)
 {
        const char *path = s3call->wbconn->listen_socket->service->priv_socket_path;
        s3call->response.result          = WINBINDD_OK;
-       WBSRV_SAMBA3_SET_STRING(s3call->response.extra_data.data, path);
+       s3call->response.extra_data.data = discard_const(path);
 
        s3call->response.length += strlen(path) + 1;
        return NT_STATUS_OK;