s3:pylibsmb: Add .chkpath() API to SMB py bindings
authorTim Beale <timbeale@catalyst.net.nz>
Mon, 3 Dec 2018 03:33:19 +0000 (16:33 +1300)
committerTim Beale <timbeale@samba.org>
Mon, 7 Jan 2019 00:23:07 +0000 (01:23 +0100)
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 <timbeale@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
python/samba/tests/smb.py
source3/libsmb/pylibsmb.c

index 25cca33..497f57d 100644 (file)
@@ -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):
 
index ecd2acf..61f256b 100644 (file)
@@ -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 }
 };