[SCM] Samba Shared Repository - branch master updated
Volker Lendecke
vlendec at samba.org
Sun Sep 23 10:02:02 MDT 2012
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 <vl at samba.org>
Date: Sat Sep 22 10:45:32 2012 -0700
s3-pylibsmb: Add get_oplock_break
Autobuild-User(master): Volker Lendecke <vl at samba.org>
Autobuild-Date(master): Sun Sep 23 18:01:28 CEST 2012 on sn-devel-104
commit ff6840815d6e6252aa3fa27a4f04d992ab912d14
Author: Volker Lendecke <vl at samba.org>
Date: Sat Sep 22 10:40:06 2012 -0700
s3-pylibsmb: Factor out py_tevent_cond_signal
commit d0a0fb32929e26ea9dd30cb3e2cacff03f68b9d2
Author: Volker Lendecke <vl at samba.org>
Date: Sat Sep 22 10:38:46 2012 -0700
s3-pylibsmb: Reduce the number of warnings
commit 7305660c1139fc1d2dc40fb3324855ec7381eac5
Author: Volker Lendecke <vl at samba.org>
Date: Sat Sep 22 18:57:47 2012 +0200
s3: Convert cli_oplock_break_waiter to smbXcli
commit 982ddc478551c3eb11a6d01acaea22fb60743d2a
Author: Volker Lendecke <vl at samba.org>
Date: Mon Aug 20 14:38:42 2012 +0200
s3: Add "readdir" to pylibsmb
commit a272635b792a806f589cd5a6a3a345cdc855b4be
Author: Volker Lendecke <vl at samba.org>
Date: Tue Sep 18 16:19:07 2012 -0700
s3: Fix some nonempty line endings
commit e0fdeda86cfc75cfe2bdd7dffeef7fc9e173c8aa
Author: Christian Ambach <ambi at 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 <vl at samba.org>
commit 947520521ed3da2f0787e17a9fe906024fdee7e3
Author: Volker Lendecke <vl at 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
More information about the samba-cvs
mailing list