|
|
885e9e |
From d66dfc2815153b315f5b3fd9d3f93be670def26a Mon Sep 17 00:00:00 2001
|
|
|
885e9e |
From: Jaroslav Rohel <jrohel@redhat.com>
|
|
|
885e9e |
Date: Tue, 3 Sep 2019 12:55:51 +0200
|
|
|
885e9e |
Subject: [PATCH 09/10] Added dnf_move_recursive()
|
|
|
885e9e |
|
|
|
885e9e |
Moves a directory and its contents. If native move operations are
|
|
|
885e9e |
supported then this is used, otherwise a copy + delete fallback is used.
|
|
|
885e9e |
---
|
|
|
885e9e |
libdnf/hy-iutil-private.hpp | 1 +
|
|
|
885e9e |
libdnf/hy-iutil.cpp | 95 +++++++++++++++++++++++++++++++++++--
|
|
|
885e9e |
2 files changed, 93 insertions(+), 3 deletions(-)
|
|
|
885e9e |
|
|
|
885e9e |
diff --git a/libdnf/hy-iutil-private.hpp b/libdnf/hy-iutil-private.hpp
|
|
|
885e9e |
index 8b2b06d5..4920ad39 100644
|
|
|
885e9e |
--- a/libdnf/hy-iutil-private.hpp
|
|
|
885e9e |
+++ b/libdnf/hy-iutil-private.hpp
|
|
|
885e9e |
@@ -41,6 +41,7 @@ char *abspath(const char *path);
|
|
|
885e9e |
int is_readable_rpm(const char *fn);
|
|
|
885e9e |
int mkcachedir(char *path);
|
|
|
885e9e |
gboolean mv(const char *old_path, const char *new_path, GError **error);
|
|
|
885e9e |
+gboolean dnf_move_recursive(const gchar *src_dir, const gchar *dst_dir, GError **error);
|
|
|
885e9e |
char *this_username(void);
|
|
|
885e9e |
|
|
|
885e9e |
/* misc utils */
|
|
|
885e9e |
diff --git a/libdnf/hy-iutil.cpp b/libdnf/hy-iutil.cpp
|
|
|
885e9e |
index 2c5af481..d3b57c79 100644
|
|
|
885e9e |
--- a/libdnf/hy-iutil.cpp
|
|
|
885e9e |
+++ b/libdnf/hy-iutil.cpp
|
|
|
885e9e |
@@ -20,12 +20,14 @@
|
|
|
885e9e |
|
|
|
885e9e |
#include <assert.h>
|
|
|
885e9e |
#include <errno.h>
|
|
|
885e9e |
+#include <dirent.h>
|
|
|
885e9e |
#include <fcntl.h>
|
|
|
885e9e |
#include <linux/limits.h>
|
|
|
885e9e |
#include <pwd.h>
|
|
|
885e9e |
#include <unistd.h>
|
|
|
885e9e |
#include <stdio.h>
|
|
|
885e9e |
#include <stdlib.h>
|
|
|
885e9e |
+#include <string.h>
|
|
|
885e9e |
#include <sys/stat.h>
|
|
|
885e9e |
#include <sys/types.h>
|
|
|
885e9e |
#include <sys/utsname.h>
|
|
|
885e9e |
@@ -41,9 +43,6 @@ extern "C" {
|
|
|
885e9e |
#include <solv/pool_parserpmrichdep.h>
|
|
|
885e9e |
}
|
|
|
885e9e |
|
|
|
885e9e |
-// glib
|
|
|
885e9e |
-#include <glib.h>
|
|
|
885e9e |
-
|
|
|
885e9e |
// hawkey
|
|
|
885e9e |
#include "dnf-advisory-private.hpp"
|
|
|
885e9e |
#include "dnf-types.h"
|
|
|
885e9e |
@@ -58,6 +57,12 @@ extern "C" {
|
|
|
885e9e |
#include "utils/bgettext/bgettext-lib.h"
|
|
|
885e9e |
#include "sack/packageset.hpp"
|
|
|
885e9e |
|
|
|
885e9e |
+// glib
|
|
|
885e9e |
+#include <glib.h>
|
|
|
885e9e |
+#include <gio/gio.h>
|
|
|
885e9e |
+
|
|
|
885e9e |
+#include <string>
|
|
|
885e9e |
+
|
|
|
885e9e |
#define BUF_BLOCK 4096
|
|
|
885e9e |
#define CHKSUM_TYPE REPOKEY_TYPE_SHA256
|
|
|
885e9e |
#define CHKSUM_IDENT "H000"
|
|
|
885e9e |
@@ -328,6 +333,90 @@ mv(const char* old_path, const char* new_path, GError** error)
|
|
|
885e9e |
return TRUE;
|
|
|
885e9e |
}
|
|
|
885e9e |
|
|
|
885e9e |
+static gboolean
|
|
|
885e9e |
+copyFile(const std::string & srcPath, const std::string & dstPath, GError ** error)
|
|
|
885e9e |
+{
|
|
|
885e9e |
+ g_autoptr(GFile) src = g_file_new_for_path(srcPath.c_str());
|
|
|
885e9e |
+ g_autoptr(GFile) dest = g_file_new_for_path(dstPath.c_str());
|
|
|
885e9e |
+ return g_file_copy(src, dest,
|
|
|
885e9e |
+ static_cast<GFileCopyFlags>(G_FILE_COPY_NOFOLLOW_SYMLINKS | G_FILE_COPY_ALL_METADATA)
|
|
|
885e9e |
+ , NULL, NULL, NULL, error);
|
|
|
885e9e |
+}
|
|
|
885e9e |
+
|
|
|
885e9e |
+static gboolean
|
|
|
885e9e |
+copyRecursive(const std::string & srcPath, const std::string & dstPath, GError ** error)
|
|
|
885e9e |
+{
|
|
|
885e9e |
+ struct stat info;
|
|
|
885e9e |
+ if (!stat(srcPath.c_str(), &info)) {
|
|
|
885e9e |
+ if (S_ISDIR(info.st_mode)) {
|
|
|
885e9e |
+ if (mkdir(dstPath.c_str(), info.st_mode) == -1) {
|
|
|
885e9e |
+ auto err = errno;
|
|
|
885e9e |
+ g_set_error(error,
|
|
|
885e9e |
+ DNF_ERROR,
|
|
|
885e9e |
+ DNF_ERROR_INTERNAL_ERROR,
|
|
|
885e9e |
+ _("cannot create directory %1$s: %2$s"),
|
|
|
885e9e |
+ dstPath.c_str(), strerror(err));
|
|
|
885e9e |
+ return FALSE;
|
|
|
885e9e |
+ }
|
|
|
885e9e |
+ if (auto fd = opendir(srcPath.c_str())) {
|
|
|
885e9e |
+ int ret = TRUE;
|
|
|
885e9e |
+ while (auto dent = readdir(fd)) {
|
|
|
885e9e |
+ auto name = dent->d_name;
|
|
|
885e9e |
+ if (name[0] == '.' && (name[1] == '\0' || (name[1] == '.' && name[2] == '\0')))
|
|
|
885e9e |
+ continue;
|
|
|
885e9e |
+ std::string srcItem = srcPath + "/" + name;
|
|
|
885e9e |
+ std::string dstItem = dstPath + "/" + name;
|
|
|
885e9e |
+ ret = copyRecursive(srcItem, dstItem, error);
|
|
|
885e9e |
+ if (!ret)
|
|
|
885e9e |
+ break;
|
|
|
885e9e |
+ }
|
|
|
885e9e |
+ closedir(fd);
|
|
|
885e9e |
+ return ret;
|
|
|
885e9e |
+ } else {
|
|
|
885e9e |
+ auto err = errno;
|
|
|
885e9e |
+ g_set_error(error,
|
|
|
885e9e |
+ DNF_ERROR,
|
|
|
885e9e |
+ DNF_ERROR_INTERNAL_ERROR,
|
|
|
885e9e |
+ _("cannot open directory %1$s: %2$s"),
|
|
|
885e9e |
+ srcPath.c_str(), strerror(err));
|
|
|
885e9e |
+ return FALSE;
|
|
|
885e9e |
+ }
|
|
|
885e9e |
+ } else {
|
|
|
885e9e |
+ return copyFile(srcPath, dstPath, error);
|
|
|
885e9e |
+ }
|
|
|
885e9e |
+ } else {
|
|
|
885e9e |
+ auto err = errno;
|
|
|
885e9e |
+ g_set_error(error,
|
|
|
885e9e |
+ DNF_ERROR,
|
|
|
885e9e |
+ DNF_ERROR_INTERNAL_ERROR,
|
|
|
885e9e |
+ _("cannot stat path %1$s: %2$s"),
|
|
|
885e9e |
+ srcPath.c_str(), strerror(err));
|
|
|
885e9e |
+ return FALSE;
|
|
|
885e9e |
+ }
|
|
|
885e9e |
+}
|
|
|
885e9e |
+
|
|
|
885e9e |
+/**
|
|
|
885e9e |
+ * dnf_move_recursive:
|
|
|
885e9e |
+ * @src_dir: A source directory path
|
|
|
885e9e |
+ * @dst_dir: A destination directory path
|
|
|
885e9e |
+ * @error: A #GError, or %NULL
|
|
|
885e9e |
+ *
|
|
|
885e9e |
+ * Moves a directory and its contents. Native move is preferred,
|
|
|
885e9e |
+ * if not supported copy and delete fallback is used.
|
|
|
885e9e |
+ *
|
|
|
885e9e |
+ * Returns: %TRUE on successful move, %FALSE otherwise
|
|
|
885e9e |
+ **/
|
|
|
885e9e |
+gboolean
|
|
|
885e9e |
+dnf_move_recursive(const char * srcDir, const char * dstDir, GError ** error)
|
|
|
885e9e |
+{
|
|
|
885e9e |
+ if (rename(srcDir, dstDir) == -1) {
|
|
|
885e9e |
+ if (!copyRecursive(srcDir, dstDir, error))
|
|
|
885e9e |
+ return FALSE;
|
|
|
885e9e |
+ return dnf_remove_recursive(srcDir, error);
|
|
|
885e9e |
+ }
|
|
|
885e9e |
+ return TRUE;
|
|
|
885e9e |
+}
|
|
|
885e9e |
+
|
|
|
885e9e |
char *
|
|
|
885e9e |
this_username(void)
|
|
|
885e9e |
{
|
|
|
885e9e |
--
|
|
|
885e9e |
2.21.0
|
|
|
885e9e |
|