[libvirt] [PATCH v3 05/14] util: Implement virFileChownFiles()

Stefan Berger stefanb at linux.vnet.ibm.com
Fri May 4 20:21:16 UTC 2018


Implement virFileChownFiles() which changes file ownership of all
files in a given directory.

Signed-off-by: Stefan Berger <stefanb at linux.vnet.ibm.com>
---
 src/libvirt_private.syms |  1 +
 src/util/virfile.c       | 49 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/util/virfile.h       |  3 +++
 3 files changed, 53 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index f2a4921..33fe75b 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1761,6 +1761,7 @@ virFileActivateDirOverride;
 virFileBindMountDevice;
 virFileBuildPath;
 virFileCanonicalizePath;
+virFileChownFiles;
 virFileClose;
 virFileComparePaths;
 virFileCopyACLs;
diff --git a/src/util/virfile.c b/src/util/virfile.c
index 526b9ad..b6aaf2c 100644
--- a/src/util/virfile.c
+++ b/src/util/virfile.c
@@ -38,6 +38,7 @@
 #include <unistd.h>
 #include <dirent.h>
 #include <dirname.h>
+#include <ftw.h>
 #if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R
 # include <mntent.h>
 #endif
@@ -2949,6 +2950,54 @@ void virDirClose(DIR **dirp)
     *dirp = NULL;
 }
 
+/*
+ * virFileChownFiles:
+ * @name: name of the directory
+ * @uid: uid
+ * @gid: gid
+ *
+ * Change ownership of all regular files in a directory.
+ *
+ * Returns -1 on error, with error already reported, 0 on success.
+ */
+int virFileChownFiles(const char *name, uid_t uid, gid_t gid)
+{
+    struct dirent *ent;
+    int ret;
+    DIR *dir;
+    char *path;
+
+    if (virDirOpen(&dir, name) < 0)
+        return -1;
+
+    while ((ret = virDirRead(dir, &ent, name)) > 0) {
+        if (ent->d_type != DT_REG)
+            continue;
+
+        if (virAsprintf(&path, "%s/%s", name, ent->d_name) < 0) {
+            ret = -1;
+            break;
+        }
+        if (chown(path, uid, gid) < 0) {
+            ret = -1;
+            virReportSystemError(errno,
+                                 _("cannot chown '%s' to (%u, %u)"),
+                                 ent->d_name, (unsigned int) uid,
+                                 (unsigned int) gid);
+        }
+        VIR_FREE(path);
+        if (ret < 0)
+            break;
+    }
+
+    virDirClose(&dir);
+
+    if (ret < 0)
+        return -1;
+
+    return 0;
+}
+
 static int
 virFileMakePathHelper(char *path, mode_t mode)
 {
diff --git a/src/util/virfile.h b/src/util/virfile.h
index 13d3cf6..f0d99a0 100644
--- a/src/util/virfile.h
+++ b/src/util/virfile.h
@@ -239,6 +239,9 @@ int virFileOpenAs(const char *path, int openflags, mode_t mode,
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
 int virFileRemove(const char *path, uid_t uid, gid_t gid);
 
+int virFileChownFiles(const char *name, uid_t uid, gid_t gid)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
+
 enum {
     VIR_DIR_CREATE_NONE        = 0,
     VIR_DIR_CREATE_AS_UID      = (1 << 0),
-- 
2.5.5




More information about the libvir-list mailing list