From: Tim Beale Date: Mon, 3 Dec 2018 03:33:19 +0000 (+1300) Subject: s3:pylibsmb: Add .chkpath() API to SMB py bindings X-Git-Tag: tdb-1.3.17~101 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c4dee3437afcf4ccba70cb3fd5848b65fd229781;p=thirdparty%2Fsamba.git s3:pylibsmb: Add .chkpath() API to SMB py bindings Note that this is checking the existence of *directories*, not *files*. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13676 Signed-off-by: Tim Beale Reviewed-by: Andrew Bartlett --- diff --git a/python/samba/tests/smb.py b/python/samba/tests/smb.py index 25cca33926e..497f57d8e65 100644 --- a/python/samba/tests/smb.py +++ b/python/samba/tests/smb.py @@ -118,7 +118,7 @@ class SMBTests(samba.tests.TestCase): # sanity-check these dirs/files exist for subdir in dirpaths + empty_dirs: - self.assertTrue(self.conn.chkpath(subdir), + self.assertTrue(self.smb_conn.chkpath(subdir), "Failed to create {0}".format(subdir)) for path in filepaths: self.assertTrue(self.file_exists(path), @@ -127,7 +127,7 @@ class SMBTests(samba.tests.TestCase): # try using deltree to remove a single empty directory path = empty_dirs.pop(0) self.conn.deltree(path) - self.assertFalse(self.conn.chkpath(path), + self.assertFalse(self.smb_conn.chkpath(path), "Failed to delete {0}".format(path)) # try using deltree to remove a single file @@ -141,7 +141,7 @@ class SMBTests(samba.tests.TestCase): # now check that all the dirs/files are no longer there for subdir in dirpaths + empty_dirs: - self.assertFalse(self.conn.chkpath(subdir), + self.assertFalse(self.smb_conn.chkpath(subdir), "Failed to delete {0}".format(subdir)) for path in filepaths: self.assertFalse(self.file_exists(path), @@ -176,22 +176,22 @@ class SMBTests(samba.tests.TestCase): def test_chkpath(self): """Tests .chkpath determines whether or not a directory exists""" - self.assertTrue(self.conn.chkpath(test_dir)) + self.assertTrue(self.smb_conn.chkpath(test_dir)) # should return False for a non-existent directory bad_dir = self.make_sysvol_path(test_dir, 'dont_exist') - self.assertFalse(self.conn.chkpath(bad_dir)) + self.assertFalse(self.smb_conn.chkpath(bad_dir)) # should return False for files (because they're not directories) self.conn.savefile(test_file, binary_contents) - self.assertFalse(self.conn.chkpath(test_file)) + self.assertFalse(self.smb_conn.chkpath(test_file)) # check correct result after creating and then deleting a new dir new_dir = self.make_sysvol_path(test_dir, 'test-new') self.smb_conn.mkdir(new_dir) - self.assertTrue(self.conn.chkpath(new_dir)) + self.assertTrue(self.smb_conn.chkpath(new_dir)) self.smb_conn.rmdir(new_dir) - self.assertFalse(self.conn.chkpath(new_dir)) + self.assertFalse(self.smb_conn.chkpath(new_dir)) def test_save_load_text(self): diff --git a/source3/libsmb/pylibsmb.c b/source3/libsmb/pylibsmb.c index ecd2acf58d0..61f256b6f99 100644 --- a/source3/libsmb/pylibsmb.c +++ b/source3/libsmb/pylibsmb.c @@ -1071,6 +1071,42 @@ static PyObject *py_smb_mkdir(struct py_cli_state *self, PyObject *args) Py_RETURN_NONE; } +/* + * Checks existence of a directory + */ +static bool check_dir_path(struct py_cli_state *self, const char *path) +{ + NTSTATUS status; + + if (self->is_smb1) { + struct tevent_req *req = NULL; + + req = cli_chkpath_send(NULL, self->ev, self->cli, path); + if (!py_tevent_req_wait_exc(self, req)) { + return false; + } + status = cli_chkpath_recv(req); + TALLOC_FREE(req); + } else { + status = cli_chkpath(self->cli, path); + } + + return NT_STATUS_IS_OK(status); +} + +static PyObject *py_smb_chkpath(struct py_cli_state *self, PyObject *args) +{ + const char *path; + bool dir_exists; + + if (!PyArg_ParseTuple(args, "s:chkpath", &path)) { + return NULL; + } + + dir_exists = check_dir_path(self, path); + return PyBool_FromLong(dir_exists); +} + static PyMethodDef py_cli_state_methods[] = { { "settimeout", (PyCFunction)py_cli_settimeout, METH_VARARGS, "settimeout(new_timeout_msecs) => return old_timeout_msecs" }, @@ -1100,6 +1136,9 @@ static PyMethodDef py_cli_state_methods[] = { "mkdir(path) -> None\n\n \t\tCreate a directory." }, { "rmdir", (PyCFunction)py_smb_rmdir, METH_VARARGS, "rmdir(path) -> None\n\n \t\tDelete a directory." }, + { "chkpath", (PyCFunction)py_smb_chkpath, METH_VARARGS, + "chkpath(dir_path) -> True or False\n\n" + "\t\tReturn true if directory exists, false otherwise." }, { NULL, NULL, 0, NULL } };