[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