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

Signed-off-by: Stefan Berger <stef...@linux.vnet.ibm.com>
Reviewed-by: John Ferlan <jfer...@redhat.com>
---
 src/libvirt_private.syms |  1 +
 src/util/virfile.c       | 55 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/util/virfile.h       |  3 +++
 3 files changed, 59 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 3dece252df..e378c73057 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1764,6 +1764,7 @@ virFileActivateDirOverride;
 virFileBindMountDevice;
 virFileBuildPath;
 virFileCanonicalizePath;
+virFileChownFiles;
 virFileClose;
 virFileComparePaths;
 virFileCopyACLs;
diff --git a/src/util/virfile.c b/src/util/virfile.c
index 523241f64f..629aa67f16 100644
--- a/src/util/virfile.c
+++ b/src/util/virfile.c
@@ -2990,6 +2990,61 @@ 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 = -1;
+    int direrr;
+    DIR *dir;
+    char *path = NULL;
+
+    if (virDirOpen(&dir, name) < 0)
+        return -1;
+
+    while ((direrr = virDirRead(dir, &ent, name)) > 0) {
+        if (ent->d_type != DT_REG)
+            continue;
+
+        if (virAsprintf(&path, "%s/%s", name, ent->d_name) < 0)
+            goto cleanup;
+
+        if (chown(path, uid, gid) < 0) {
+            virReportSystemError(errno,
+                                 _("cannot chown '%s' to (%u, %u)"),
+                                 ent->d_name, (unsigned int) uid,
+                                 (unsigned int) gid);
+            goto cleanup;
+        }
+        VIR_FREE(path);
+    }
+
+    if (direrr < 0)
+        goto cleanup;
+
+    ret = 0;
+
+ cleanup:
+    VIR_FREE(path);
+
+    virDirClose(&dir);
+
+    return ret;
+}
+
+
 static int
 virFileMakePathHelper(char *path, mode_t mode)
 {
diff --git a/src/util/virfile.h b/src/util/virfile.h
index 6b0cbad4d1..c7a32c30a8 100644
--- a/src/util/virfile.h
+++ b/src/util/virfile.h
@@ -238,6 +238,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.14.3

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to