The branch, master has been updated
       via  9e6070b s3-pylibsmb: Add get_oplock_break
       via  ff68408 s3-pylibsmb: Factor out py_tevent_cond_signal
       via  d0a0fb3 s3-pylibsmb: Reduce the number of warnings
       via  7305660 s3: Convert cli_oplock_break_waiter to smbXcli
       via  982ddc4 s3: Add "readdir" to pylibsmb
       via  a272635 s3: Fix some nonempty line endings
       via  e0fdeda s3-pylibsmb: move py_tevent_req_wait_exc up in the file
       via  9475205 s3-pylibsmb: Factor out py_tevent_cond_wait
      from  8e5f30c build: Remove unused define UNIXWARE

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 9e6070b5fcc17f0e866367c4d3f4dfcb95be6c46
Author: Volker Lendecke <v...@samba.org>
Date:   Sat Sep 22 10:45:32 2012 -0700

    s3-pylibsmb: Add get_oplock_break
    
    Autobuild-User(master): Volker Lendecke <v...@samba.org>
    Autobuild-Date(master): Sun Sep 23 18:01:28 CEST 2012 on sn-devel-104

commit ff6840815d6e6252aa3fa27a4f04d992ab912d14
Author: Volker Lendecke <v...@samba.org>
Date:   Sat Sep 22 10:40:06 2012 -0700

    s3-pylibsmb: Factor out py_tevent_cond_signal

commit d0a0fb32929e26ea9dd30cb3e2cacff03f68b9d2
Author: Volker Lendecke <v...@samba.org>
Date:   Sat Sep 22 10:38:46 2012 -0700

    s3-pylibsmb: Reduce the number of warnings

commit 7305660c1139fc1d2dc40fb3324855ec7381eac5
Author: Volker Lendecke <v...@samba.org>
Date:   Sat Sep 22 18:57:47 2012 +0200

    s3: Convert cli_oplock_break_waiter to smbXcli

commit 982ddc478551c3eb11a6d01acaea22fb60743d2a
Author: Volker Lendecke <v...@samba.org>
Date:   Mon Aug 20 14:38:42 2012 +0200

    s3: Add "readdir" to pylibsmb

commit a272635b792a806f589cd5a6a3a345cdc855b4be
Author: Volker Lendecke <v...@samba.org>
Date:   Tue Sep 18 16:19:07 2012 -0700

    s3: Fix some nonempty line endings

commit e0fdeda86cfc75cfe2bdd7dffeef7fc9e173c8aa
Author: Christian Ambach <a...@samba.org>
Date:   Sun Sep 16 11:39:26 2012 -0700

    s3-pylibsmb: move py_tevent_req_wait_exc up in the file
    
    this is needed to be able to use it in other functions and
    spares the prototype
    
    Pair-Programmed-With: Volker Lendecke <v...@samba.org>

commit 947520521ed3da2f0787e17a9fe906024fdee7e3
Author: Volker Lendecke <v...@samba.org>
Date:   Fri Sep 21 12:05:04 2012 -0700

    s3-pylibsmb: Factor out py_tevent_cond_wait

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

Summary of changes:
 source3/libsmb/clioplock.c |   31 +++--
 source3/libsmb/pylibsmb.c  |  317 +++++++++++++++++++++++++++++++++++++-------
 2 files changed, 291 insertions(+), 57 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/libsmb/clioplock.c b/source3/libsmb/clioplock.c
index 0b3ca2c..d9ab414 100644
--- a/source3/libsmb/clioplock.c
+++ b/source3/libsmb/clioplock.c
@@ -1,18 +1,18 @@
-/* 
+/*
    Unix SMB/CIFS implementation.
    SMB client oplock functions
    Copyright (C) Andrew Tridgell 2001
-   
+
    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/>.
 */
@@ -47,7 +47,8 @@ struct tevent_req 
*cli_smb_oplock_break_waiter_send(TALLOC_CTX *mem_ctx,
         * Create a fake SMB request that we will never send out. This is only
         * used to be set into the pending queue with the right mid.
         */
-       subreq = cli_smb_req_create(mem_ctx, ev, cli, 0, 0, 0, NULL, 0, NULL);
+       subreq = smb1cli_req_create(mem_ctx, ev, cli->conn, 0, 0, 0, 0, 0, 0,
+                                   0, NULL, NULL, 0, NULL, 0, NULL);
        if (tevent_req_nomem(subreq, req)) {
                return tevent_req_post(req, ev);
        }
@@ -67,19 +68,31 @@ static void cli_smb_oplock_break_waiter_done(struct 
tevent_req *subreq)
                subreq, struct tevent_req);
        struct cli_smb_oplock_break_waiter_state *state = tevent_req_data(
                req, struct cli_smb_oplock_break_waiter_state);
+       struct iovec *iov;
        uint8_t wct;
        uint16_t *vwv;
-       uint32_t num_bytes;
-       uint8_t *bytes;
        NTSTATUS status;
 
-       status = cli_smb_recv(subreq, state, NULL, 8, &wct, &vwv,
-                             &num_bytes, &bytes);
+       status = smb1cli_req_recv(subreq, state,
+                                 &iov, /* piov */
+                                 NULL, /* phdr */
+                                 &wct,
+                                 &vwv,
+                                 NULL, /* pvwv_offset */
+                                 NULL, /* pnum_bytes */
+                                 NULL, /* pbytes */
+                                 NULL, /* pbytes_offset */
+                                 NULL, /* pinbuf */
+                                 NULL, 0); /* expected */
        TALLOC_FREE(subreq);
        if (!NT_STATUS_IS_OK(status)) {
                tevent_req_nterror(req, status);
                return;
        }
+       if (wct < 8) {
+               tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
+               return;
+       }
        state->fnum = SVAL(vwv+2, 0);
        state->level = CVAL(vwv+3, 1);
        tevent_req_done(req);
diff --git a/source3/libsmb/pylibsmb.c b/source3/libsmb/pylibsmb.c
index d31409c..e357d0f 100644
--- a/source3/libsmb/pylibsmb.c
+++ b/source3/libsmb/pylibsmb.c
@@ -25,6 +25,7 @@
 #include "system/select.h"
 #include "source4/libcli/util/pyerrors.h"
 #include "auth/credentials/pycredentials.h"
+#include "trans2.h"
 
 static PyTypeObject *get_pytype(const char *module, const char *type)
 {
@@ -49,13 +50,40 @@ static PyTypeObject *get_pytype(const char *module, const 
char *type)
        return result;
 }
 
+/*
+ * We're using "const char **" for keywords,
+ * PyArg_ParseTupleAndKeywords expects a "char **". Confine the
+ * inevitable warnings to just one place.
+ */
+static int ParseTupleAndKeywords(PyObject *args, PyObject *kw,
+                                const char *format, const char **keywords,
+                                ...)
+{
+       va_list a;
+       int ret;
+       va_start(a, keywords);
+       ret = PyArg_VaParseTupleAndKeywords(args, kw, format,
+                                           (char **)keywords, a);
+       va_end(a);
+       return ret;
+}
+
 struct py_cli_thread;
 
+struct py_cli_oplock_break {
+       uint16_t fnum;
+       uint8_t level;
+};
+
 struct py_cli_state {
        PyObject_HEAD
        struct cli_state *cli;
        struct tevent_context *ev;
        struct py_cli_thread *thread_state;
+
+       struct tevent_req *oplock_waiter;
+       struct py_cli_oplock_break *oplock_breaks;
+       struct py_tevent_cond *oplock_cond;
 };
 
 #if HAVE_PTHREAD
@@ -228,33 +256,30 @@ struct py_tevent_cond {
 
 static void py_tevent_signalme(struct tevent_req *req);
 
-static int py_tevent_req_wait(struct tevent_context *ev,
-                             struct tevent_req *req)
+static int py_tevent_cond_wait(struct py_tevent_cond *cond)
 {
-       struct py_tevent_cond cond;
        int ret, result;
 
-       result = pthread_mutex_init(&cond.mutex, NULL);
+       result = pthread_mutex_init(&cond->mutex, NULL);
        if (result != 0) {
                goto fail;
        }
-       result = pthread_cond_init(&cond.cond, NULL);
+       result = pthread_cond_init(&cond->cond, NULL);
        if (result != 0) {
                goto fail_mutex;
        }
 
-       cond.is_done = false;
-       tevent_req_set_callback(req, py_tevent_signalme, &cond);
-
-       result = pthread_mutex_lock(&cond.mutex);
+       result = pthread_mutex_lock(&cond->mutex);
        if (result != 0) {
                goto fail_cond;
        }
 
-       while (!cond.is_done) {
+       cond->is_done = false;
+
+       while (!cond->is_done) {
 
                Py_BEGIN_ALLOW_THREADS
-               result = pthread_cond_wait(&cond.cond, &cond.mutex);
+               result = pthread_cond_wait(&cond->cond, &cond->mutex);
                Py_END_ALLOW_THREADS
 
                if (result != 0) {
@@ -263,22 +288,28 @@ static int py_tevent_req_wait(struct tevent_context *ev,
        }
 
 fail_unlock:
-       ret = pthread_mutex_unlock(&cond.mutex);
+       ret = pthread_mutex_unlock(&cond->mutex);
        assert(ret == 0);
 fail_cond:
-       ret = pthread_cond_destroy(&cond.cond);
+       ret = pthread_cond_destroy(&cond->cond);
        assert(ret == 0);
 fail_mutex:
-       ret = pthread_mutex_destroy(&cond.mutex);
+       ret = pthread_mutex_destroy(&cond->mutex);
        assert(ret == 0);
 fail:
        return result;
 }
 
-static void py_tevent_signalme(struct tevent_req *req)
+static int py_tevent_req_wait(struct tevent_context *ev,
+                             struct tevent_req *req)
+{
+       struct py_tevent_cond cond;
+       tevent_req_set_callback(req, py_tevent_signalme, &cond);
+       return py_tevent_cond_wait(&cond);
+}
+
+static void py_tevent_cond_signal(struct py_tevent_cond *cond)
 {
-       struct py_tevent_cond *cond = (struct py_tevent_cond *)
-               tevent_req_callback_data_void(req);
        int ret;
 
        ret = pthread_mutex_lock(&cond->mutex);
@@ -292,6 +323,14 @@ static void py_tevent_signalme(struct tevent_req *req)
        assert(ret == 0);
 }
 
+static void py_tevent_signalme(struct tevent_req *req)
+{
+       struct py_tevent_cond *cond = (struct py_tevent_cond *)
+               tevent_req_callback_data_void(req);
+
+       py_tevent_cond_signal(cond);
+}
+
 #else
 
 static bool py_cli_state_setup_ev(struct py_cli_state *self)
@@ -316,6 +355,25 @@ static int py_tevent_req_wait(struct tevent_context *ev,
 
 #endif
 
+static bool py_tevent_req_wait_exc(struct tevent_context *ev,
+                                  struct tevent_req *req)
+{
+       int ret;
+
+       if (req == NULL) {
+               PyErr_NoMemory();
+               return false;
+       }
+       ret = py_tevent_req_wait(ev, req);
+       if (ret != 0) {
+               TALLOC_FREE(req);
+               errno = ret;
+               PyErr_SetFromErrno(PyExc_RuntimeError);
+               return false;
+       }
+       return true;
+}
+
 static PyObject *py_cli_state_new(PyTypeObject *type, PyObject *args,
                                  PyObject *kwds)
 {
@@ -328,9 +386,14 @@ static PyObject *py_cli_state_new(PyTypeObject *type, 
PyObject *args,
        self->cli = NULL;
        self->ev = NULL;
        self->thread_state = NULL;
+       self->oplock_waiter = NULL;
+       self->oplock_cond = NULL;
+       self->oplock_breaks = NULL;
        return (PyObject *)self;
 }
 
+static void py_cli_got_oplock_break(struct tevent_req *req);
+
 static int py_cli_state_init(struct py_cli_state *self, PyObject *args,
                             PyObject *kwds)
 {
@@ -350,8 +413,8 @@ static int py_cli_state_init(struct py_cli_state *self, 
PyObject *args,
                return -1;
        }
 
-       ret = PyArg_ParseTupleAndKeywords(
-               args, kwds, "ss|O!", (char **)kwlist,
+       ret = ParseTupleAndKeywords(
+               args, kwds, "ss|O!", kwlist,
                &host, &share, py_type_Credentials, &creds);
 
        Py_DECREF(py_type_Credentials);
@@ -380,38 +443,123 @@ static int py_cli_state_init(struct py_cli_state *self, 
PyObject *args,
                PyErr_SetNTSTATUS(status);
                return -1;
        }
+
+       self->oplock_waiter = cli_smb_oplock_break_waiter_send(
+               self->ev, self->ev, self->cli);
+       if (self->oplock_waiter == NULL) {
+               PyErr_NoMemory();
+               return -1;
+       }
+       tevent_req_set_callback(self->oplock_waiter, py_cli_got_oplock_break,
+                               self);
        return 0;
 }
 
-static void py_cli_state_dealloc(struct py_cli_state *self)
+static void py_cli_got_oplock_break(struct tevent_req *req)
 {
-       TALLOC_FREE(self->thread_state);
-       TALLOC_FREE(self->ev);
+       struct py_cli_state *self = (struct py_cli_state *)
+               tevent_req_callback_data_void(req);
+       struct py_cli_oplock_break b;
+       struct py_cli_oplock_break *tmp;
+       size_t num_breaks;
+       NTSTATUS status;
 
-       if (self->cli != NULL) {
-               cli_shutdown(self->cli);
-               self->cli = NULL;
+       status = cli_smb_oplock_break_waiter_recv(req, &b.fnum, &b.level);
+       TALLOC_FREE(req);
+       self->oplock_waiter = NULL;
+
+       if (!NT_STATUS_IS_OK(status)) {
+               return;
        }
-       self->ob_type->tp_free((PyObject *)self);
+
+       num_breaks = talloc_array_length(self->oplock_breaks);
+       tmp = talloc_realloc(self->ev, self->oplock_breaks,
+                            struct py_cli_oplock_break, num_breaks+1);
+       if (tmp == NULL) {
+               return;
+       }
+       self->oplock_breaks = tmp;
+       self->oplock_breaks[num_breaks] = b;
+
+       if (self->oplock_cond != NULL) {
+               py_tevent_cond_signal(self->oplock_cond);
+       }
+
+       self->oplock_waiter = cli_smb_oplock_break_waiter_send(
+               self->ev, self->ev, self->cli);
+       if (self->oplock_waiter == NULL) {
+               return;
+       }
+       tevent_req_set_callback(self->oplock_waiter, py_cli_got_oplock_break,
+                               self);
 }
 
-static bool py_tevent_req_wait_exc(struct tevent_context *ev,
-                                  struct tevent_req *req)
+static PyObject *py_cli_get_oplock_break(struct py_cli_state *self,
+                                        PyObject *args)
 {
-       int ret;
+       size_t num_oplock_breaks;
 
-       if (req == NULL) {
-               PyErr_NoMemory();
-               return false;
+       if (!PyArg_ParseTuple(args, "")) {
+               return NULL;
        }
-       ret = py_tevent_req_wait(ev, req);
-       if (ret != 0) {
-               TALLOC_FREE(req);
-               errno = ret;
+
+       if (self->oplock_cond != NULL) {
+               errno = EBUSY;
                PyErr_SetFromErrno(PyExc_RuntimeError);
-               return false;
+               return NULL;
        }
-       return true;
+
+       num_oplock_breaks = talloc_array_length(self->oplock_breaks);
+
+       if (num_oplock_breaks == 0) {
+               struct py_tevent_cond cond;
+               int ret;
+
+               self->oplock_cond = &cond;
+               ret = py_tevent_cond_wait(&cond);
+               self->oplock_cond = NULL;
+
+               if (ret != 0) {
+                       errno = ret;
+                       PyErr_SetFromErrno(PyExc_RuntimeError);
+                       return NULL;
+               }
+       }
+
+       num_oplock_breaks = talloc_array_length(self->oplock_breaks);
+       if (num_oplock_breaks > 0) {
+               PyObject *result;
+
+               result = Py_BuildValue(
+                       "{s:i,s:i}",
+                       "fnum", self->oplock_breaks[0].fnum,
+                       "level", self->oplock_breaks[0].level);
+
+               memmove(&self->oplock_breaks[0], &self->oplock_breaks[1],
+                       sizeof(self->oplock_breaks[0]) *
+                       (num_oplock_breaks - 1));
+               self->oplock_breaks = talloc_realloc(
+                       NULL, self->oplock_breaks, struct py_cli_oplock_break,
+                       num_oplock_breaks - 1);
+
+               return result;
+       }
+
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+
+static void py_cli_state_dealloc(struct py_cli_state *self)
+{
+       TALLOC_FREE(self->thread_state);
+       TALLOC_FREE(self->oplock_waiter);
+       TALLOC_FREE(self->ev);
+
+       if (self->cli != NULL) {
+               cli_shutdown(self->cli);
+               self->cli = NULL;
+       }
+       self->ob_type->tp_free((PyObject *)self);
 }
 
 static PyObject *py_cli_create(struct py_cli_state *self, PyObject *args,
@@ -434,8 +582,8 @@ static PyObject *py_cli_create(struct py_cli_state *self, 
PyObject *args,
                "ShareAccess", "CreateDisposition", "CreateOptions",
                "SecurityFlags", NULL };
 
-       if (!PyArg_ParseTupleAndKeywords(
-                   args, kwds, "s|IIIIIII", (char **)kwlist,
+       if (!ParseTupleAndKeywords(
+                   args, kwds, "s|IIIIIII", kwlist,
                    &fname, &CreateFlags, &DesiredAccess, &FileAttributes,
                    &ShareAccess, &CreateDisposition, &CreateOptions,
                    &SecurityFlags)) {
@@ -499,8 +647,8 @@ static PyObject *py_cli_write(struct py_cli_state *self, 
PyObject *args,
        static const char *kwlist[] = {
                "fnum", "buffer", "offset", "mode", NULL };
 
-       if (!PyArg_ParseTupleAndKeywords(
-                   args, kwds, "Is#K|I", (char **)kwlist,
+       if (!ParseTupleAndKeywords(
+                   args, kwds, "Is#K|I", kwlist,
                    &fnum, &buf, &buflen, &offset, &mode)) {
                return NULL;
        }
@@ -535,8 +683,8 @@ static PyObject *py_cli_read(struct py_cli_state *self, 
PyObject *args,
        static const char *kwlist[] = {
                "fnum", "offset", "size", NULL };
 
-       if (!PyArg_ParseTupleAndKeywords(
-                   args, kwds, "IKI", (char **)kwlist, &fnum, &offset,
+       if (!ParseTupleAndKeywords(
+                   args, kwds, "IKI", kwlist, &fnum, &offset,
                    &size)) {
                return NULL;
        }
@@ -569,8 +717,8 @@ static PyObject *py_cli_ftruncate(struct py_cli_state 
*self, PyObject *args,
        static const char *kwlist[] = {
                "fnum", "size", NULL };
 
-       if (!PyArg_ParseTupleAndKeywords(
-                   args, kwds, "IK", (char **)kwlist, &fnum, &size)) {
+       if (!ParseTupleAndKeywords(
+                   args, kwds, "IK", kwlist, &fnum, &size)) {
                return NULL;
        }
 
@@ -600,8 +748,8 @@ static PyObject *py_cli_delete_on_close(struct py_cli_state 
*self,
        static const char *kwlist[] = {
                "fnum", "flag", NULL };
 
-       if (!PyArg_ParseTupleAndKeywords(
-                   args, kwds, "II", (char **)kwlist, &fnum, &flag)) {
+       if (!ParseTupleAndKeywords(
+                   args, kwds, "II", kwlist, &fnum, &flag)) {
                return NULL;
        }
 
@@ -621,6 +769,74 @@ static PyObject *py_cli_delete_on_close(struct 
py_cli_state *self,
        return Py_None;
 }
 
+static PyObject *py_cli_list(struct py_cli_state *self,
+                            PyObject *args,
+                            PyObject *kwds)
+{
+       char *mask;
+       unsigned attribute =
+               FILE_ATTRIBUTE_DIRECTORY |
+               FILE_ATTRIBUTE_SYSTEM |
+               FILE_ATTRIBUTE_HIDDEN;
+       unsigned info_level = SMB_FIND_FILE_BOTH_DIRECTORY_INFO;
+       struct tevent_req *req;
+       NTSTATUS status;
+       struct file_info *finfos;
+       size_t i, num_finfos;
+       PyObject *result;
+
+       const char *kwlist[] = {
+               "mask", "attribute", "info_level", NULL
+       };
+
+       if (!ParseTupleAndKeywords(
+                   args, kwds, "s|II", kwlist,
+                   &mask, &attribute, &info_level)) {
+               return NULL;
+       }
+
+       req = cli_list_send(NULL, self->ev, self->cli, mask, attribute,
+                           info_level);


-- 
Samba Shared Repository

Reply via email to