misc: Add cr_cp() function.
authorTomas Mlcoch <tmlcoch@redhat.com>
Thu, 28 Nov 2013 15:08:50 +0000 (16:08 +0100)
committerTomas Mlcoch <tmlcoch@redhat.com>
Thu, 28 Nov 2013 15:54:40 +0000 (16:54 +0100)
src/misc.c
src/misc.h

index 7695e34..7ac4326 100644 (file)
@@ -1093,7 +1093,9 @@ cr_warning_cb(cr_XmlParserWarningType type,
     CR_UNUSED(type);
     CR_UNUSED(err);
 
-    g_warning("%s: %s", cbdata, msg);
+    g_warning("%s: %s", (char *) cbdata, msg);
+
+    return CR_CB_RET_OK;
 }
 
 gboolean
@@ -1130,3 +1132,66 @@ cr_write_to_file(GError **err, gchar *filename, const char *format, ...)
 
     return ret;
 }
+
+gboolean
+cr_cp(const char *src,
+      const char *dst,
+      cr_CpFlags flags,
+      const char *working_directory,
+      GError **err)
+{
+    assert(src);
+    assert(dst);
+    assert(!err || *err == NULL);
+
+    GPtrArray *argv_array = g_ptr_array_new();
+    g_ptr_array_add(argv_array, "cp");
+    if (flags & CR_CP_RECURSIVE)
+        g_ptr_array_add(argv_array, "-r");
+    if (flags & CR_CP_PRESERVE_ALL) {
+        g_ptr_array_add(argv_array, "--preserve=all");
+    }
+    g_ptr_array_add(argv_array, (char *) src);
+    g_ptr_array_add(argv_array, (char *) dst);
+    g_ptr_array_add(argv_array, (char *) NULL);
+
+    GError *tmp_err = NULL;
+    gint status = 0;
+    int spawn_flags = G_SPAWN_SEARCH_PATH
+                      | G_SPAWN_STDOUT_TO_DEV_NULL;
+
+    gchar *error_str = NULL;
+
+    g_spawn_sync(working_directory,
+                 (char **) argv_array->pdata,
+                 NULL, // envp
+                 spawn_flags,
+                 NULL, // child setup function
+                 NULL, // user data for child setup
+                 NULL, // stdout
+                 &error_str, // stderr
+                 &status,
+                 &tmp_err);
+
+    g_ptr_array_free(argv_array, TRUE);
+
+    if (tmp_err) {
+        g_free(error_str);
+        g_propagate_prefixed_error(err, tmp_err, "Error during copying: ");
+        return FALSE;
+    }
+
+    gboolean ret = g_spawn_check_exit_status(status, &tmp_err);
+    if (!ret && error_str) {
+        // Remove newlines from error message
+        for (char *ptr = error_str; *ptr; ptr++)
+            if (*ptr == '\n') *ptr = ' ';
+
+        g_propagate_prefixed_error(err, tmp_err, "Error during copying: %s: ",
+                                   error_str);
+    }
+
+    g_free(error_str);
+
+    return ret;
+}
index ef36f4d..a3fef9a 100644 (file)
@@ -394,6 +394,28 @@ cr_warning_cb(cr_XmlParserWarningType type,
 gboolean
 cr_write_to_file(GError **err, gchar *filename, const char *format, ...);
 
+typedef enum {
+    CR_CP_DEFAULT       = (1<<0), /*!<
+        No attributes - default */
+    CR_CP_RECURSIVE     = (1<<1), /*!<
+        Copy directories recursively */
+    CR_CP_PRESERVE_ALL  = (1<<2), /*!<
+        preserve the all attributes (if possible) */
+} cr_CpFlags;
+
+/** Recursive copy of directory (works on files as well)
+ * @param src                   Source (supports wildcards)
+ * @param dst                   Destination (supports wildcards)
+ * @param flags                 Flags
+ * @param working_directory     Working directory
+ */
+gboolean
+cr_cp(const char *src,
+      const char *dst,
+      cr_CpFlags flags,
+      const char *working_directory,
+      GError **err);
+
 /** @} */
 
 #ifdef __cplusplus