You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1218 lines
36 KiB
1218 lines
36 KiB
From 33c21fc3647af32de5a9c9d49e33765a526910f5 Mon Sep 17 00:00:00 2001
|
|
From: Tomas Bzatek <tbzatek@redhat.com>
|
|
Date: Wed, 12 May 2010 11:54:29 +0000
|
|
Subject: Bring back support for file caching when gvfs-fuse-daemon is not available
|
|
|
|
The commit 73fa5d77a60861cd35c6f3425d27c88061af081c introduced trouble
|
|
when user was trying to work with archives on remote GIO mounts and
|
|
not having the fuse daemon running. This led to segfaults and error messages.
|
|
|
|
Please see bug #617769 for details.
|
|
---
|
|
diff --git a/src/fr-archive.c b/src/fr-archive.c
|
|
index e4a1259..adf9976 100644
|
|
--- a/src/fr-archive.c
|
|
+++ b/src/fr-archive.c
|
|
@@ -114,16 +114,51 @@ struct _FrArchivePrivData {
|
|
FakeLoadFunc add_is_stoppable_func; /* Returns whether the add operation is
|
|
* stoppable. */
|
|
gpointer add_is_stoppable_data;
|
|
- GCancellable *cancellable;
|
|
+ GCancellable *cancellable;
|
|
char *temp_dir;
|
|
gboolean continue_adding_dropped_items;
|
|
DroppedItemsData *dropped_items_data;
|
|
|
|
+ char *temp_extraction_dir;
|
|
char *extraction_destination;
|
|
+ gboolean remote_extraction;
|
|
gboolean extract_here;
|
|
};
|
|
|
|
|
|
+typedef struct {
|
|
+ FrArchive *archive;
|
|
+ char *uri;
|
|
+ FrAction action;
|
|
+ GList *file_list;
|
|
+ char *base_uri;
|
|
+ char *dest_dir;
|
|
+ gboolean update;
|
|
+ char *tmp_dir;
|
|
+ guint source_id;
|
|
+ char *password;
|
|
+ gboolean encrypt_header;
|
|
+ FrCompression compression;
|
|
+ guint volume_size;
|
|
+} XferData;
|
|
+
|
|
+
|
|
+static void
|
|
+xfer_data_free (XferData *data)
|
|
+{
|
|
+ if (data == NULL)
|
|
+ return;
|
|
+
|
|
+ g_free (data->uri);
|
|
+ g_free (data->password);
|
|
+ path_list_free (data->file_list);
|
|
+ g_free (data->base_uri);
|
|
+ g_free (data->dest_dir);
|
|
+ g_free (data->tmp_dir);
|
|
+ g_free (data);
|
|
+}
|
|
+
|
|
+
|
|
#define MAX_CHUNK_LEN (NCARGS * 2 / 3) /* Max command line length */
|
|
#define UNKNOWN_TYPE "application/octet-stream"
|
|
#define SAME_FS (FALSE)
|
|
@@ -322,6 +357,8 @@ static void
|
|
fr_archive_init (FrArchive *archive)
|
|
{
|
|
archive->file = NULL;
|
|
+ archive->local_copy = NULL;
|
|
+ archive->is_remote = FALSE;
|
|
archive->command = NULL;
|
|
archive->is_compressed_file = FALSE;
|
|
archive->can_create_compressed_file = FALSE;
|
|
@@ -333,6 +370,7 @@ fr_archive_init (FrArchive *archive)
|
|
archive->priv->add_is_stoppable_data = NULL;
|
|
|
|
archive->priv->extraction_destination = NULL;
|
|
+ archive->priv->temp_extraction_dir = NULL;
|
|
archive->priv->cancellable = g_cancellable_new ();
|
|
|
|
archive->process = fr_process_new ();
|
|
@@ -350,18 +388,73 @@ fr_archive_new (void)
|
|
}
|
|
|
|
|
|
+static GFile *
|
|
+get_local_copy_for_file (GFile *remote_file)
|
|
+{
|
|
+ char *temp_dir;
|
|
+ GFile *local_copy = NULL;
|
|
+
|
|
+ temp_dir = get_temp_work_dir (NULL);
|
|
+ if (temp_dir != NULL) {
|
|
+ char *archive_name;
|
|
+ char *local_path;
|
|
+
|
|
+ archive_name = g_file_get_basename (remote_file);
|
|
+ local_path = g_build_filename (temp_dir, archive_name, NULL);
|
|
+ local_copy = g_file_new_for_path (local_path);
|
|
+
|
|
+ g_free (local_path);
|
|
+ g_free (archive_name);
|
|
+ }
|
|
+ g_free (temp_dir);
|
|
+
|
|
+ return local_copy;
|
|
+}
|
|
+
|
|
+
|
|
static void
|
|
fr_archive_set_uri (FrArchive *archive,
|
|
const char *uri)
|
|
{
|
|
+ if ((archive->local_copy != NULL) && archive->is_remote) {
|
|
+ GFile *temp_folder;
|
|
+ GError *err = NULL;
|
|
+
|
|
+ g_file_delete (archive->local_copy, NULL, &err);
|
|
+ if (err != NULL) {
|
|
+ g_warning ("Failed to delete the local copy: %s", err->message);
|
|
+ g_clear_error (&err);
|
|
+ }
|
|
+
|
|
+ temp_folder = g_file_get_parent (archive->local_copy);
|
|
+ g_file_delete (temp_folder, NULL, &err);
|
|
+ if (err != NULL) {
|
|
+ g_warning ("Failed to delete temp folder: %s", err->message);
|
|
+ g_clear_error (&err);
|
|
+ }
|
|
+
|
|
+ g_object_unref (temp_folder);
|
|
+ }
|
|
+
|
|
if (archive->file != NULL) {
|
|
g_object_unref (archive->file);
|
|
archive->file = NULL;
|
|
}
|
|
+ if (archive->local_copy != NULL) {
|
|
+ g_object_unref (archive->local_copy);
|
|
+ archive->local_copy = NULL;
|
|
+ }
|
|
archive->content_type = NULL;
|
|
|
|
- if (uri != NULL)
|
|
- archive->file = g_file_new_for_uri (uri);
|
|
+ if (uri == NULL)
|
|
+ return;
|
|
+
|
|
+ archive->file = g_file_new_for_uri (uri);
|
|
+ archive->is_remote = ! g_file_has_uri_scheme (archive->file, "file");
|
|
+ if (archive->is_remote)
|
|
+ archive->local_copy = get_local_copy_for_file (archive->file);
|
|
+ else
|
|
+ archive->local_copy = g_file_dup (archive->file);
|
|
}
|
|
|
|
|
|
@@ -395,6 +488,7 @@ fr_archive_finalize (GObject *object)
|
|
dropped_items_data_free (archive->priv->dropped_items_data);
|
|
archive->priv->dropped_items_data = NULL;
|
|
}
|
|
+ g_free (archive->priv->temp_extraction_dir);
|
|
g_free (archive->priv->extraction_destination);
|
|
g_free (archive->priv);
|
|
|
|
@@ -501,7 +595,7 @@ create_command_from_type (FrArchive *archive,
|
|
if (command_type == 0)
|
|
return FALSE;
|
|
|
|
- filename = g_file_get_path (archive->file);
|
|
+ filename = g_file_get_path (archive->local_copy);
|
|
archive->command = FR_COMMAND (g_object_new (command_type,
|
|
"process", archive->process,
|
|
"filename", filename,
|
|
@@ -588,6 +682,79 @@ action_started (FrCommand *command,
|
|
}
|
|
|
|
|
|
+/* -- copy_to_remote_location -- */
|
|
+
|
|
+
|
|
+static void
|
|
+fr_archive_copy_done (FrArchive *archive,
|
|
+ FrAction action,
|
|
+ GError *error)
|
|
+{
|
|
+ FrProcErrorType error_type = FR_PROC_ERROR_NONE;
|
|
+ const char *error_details = NULL;
|
|
+
|
|
+ if (error != NULL) {
|
|
+ error_type = (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) ? FR_PROC_ERROR_STOPPED : FR_PROC_ERROR_GENERIC);
|
|
+ error_details = error->message;
|
|
+ }
|
|
+ fr_archive_action_completed (archive, action, error_type, error_details);
|
|
+}
|
|
+
|
|
+
|
|
+static void
|
|
+copy_to_remote_location_done (GError *error,
|
|
+ gpointer user_data)
|
|
+{
|
|
+ XferData *xfer_data = user_data;
|
|
+
|
|
+ fr_archive_copy_done (xfer_data->archive, xfer_data->action, error);
|
|
+ xfer_data_free (xfer_data);
|
|
+}
|
|
+
|
|
+
|
|
+static void
|
|
+copy_to_remote_location_progress (goffset current_file,
|
|
+ goffset total_files,
|
|
+ GFile *source,
|
|
+ GFile *destination,
|
|
+ goffset current_num_bytes,
|
|
+ goffset total_num_bytes,
|
|
+ gpointer user_data)
|
|
+{
|
|
+ XferData *xfer_data = user_data;
|
|
+
|
|
+ g_signal_emit (G_OBJECT (xfer_data->archive),
|
|
+ fr_archive_signals[PROGRESS],
|
|
+ 0,
|
|
+ (double) current_num_bytes / total_num_bytes);
|
|
+}
|
|
+
|
|
+
|
|
+static void
|
|
+copy_to_remote_location (FrArchive *archive,
|
|
+ FrAction action)
|
|
+{
|
|
+ XferData *xfer_data;
|
|
+
|
|
+ xfer_data = g_new0 (XferData, 1);
|
|
+ xfer_data->archive = archive;
|
|
+ xfer_data->action = action;
|
|
+
|
|
+ g_copy_file_async (archive->local_copy,
|
|
+ archive->file,
|
|
+ G_FILE_COPY_OVERWRITE,
|
|
+ G_PRIORITY_DEFAULT,
|
|
+ archive->priv->cancellable,
|
|
+ copy_to_remote_location_progress,
|
|
+ xfer_data,
|
|
+ copy_to_remote_location_done,
|
|
+ xfer_data);
|
|
+}
|
|
+
|
|
+
|
|
+/* -- copy_extracted_files_to_destination -- */
|
|
+
|
|
+
|
|
static void
|
|
move_here (FrArchive *archive)
|
|
{
|
|
@@ -656,6 +823,61 @@ move_here (FrArchive *archive)
|
|
}
|
|
|
|
|
|
+static void
|
|
+copy_extracted_files_done (GError *error,
|
|
+ gpointer user_data)
|
|
+{
|
|
+ FrArchive *archive = user_data;
|
|
+
|
|
+ remove_local_directory (archive->priv->temp_extraction_dir);
|
|
+ g_free (archive->priv->temp_extraction_dir);
|
|
+ archive->priv->temp_extraction_dir = NULL;
|
|
+
|
|
+ fr_archive_action_completed (archive,
|
|
+ FR_ACTION_COPYING_FILES_TO_REMOTE,
|
|
+ FR_PROC_ERROR_NONE,
|
|
+ NULL);
|
|
+
|
|
+ if ((error == NULL) && (archive->priv->extract_here))
|
|
+ move_here (archive);
|
|
+
|
|
+ fr_archive_copy_done (archive, FR_ACTION_EXTRACTING_FILES, error);
|
|
+}
|
|
+
|
|
+
|
|
+static void
|
|
+copy_extracted_files_progress (goffset current_file,
|
|
+ goffset total_files,
|
|
+ GFile *source,
|
|
+ GFile *destination,
|
|
+ goffset current_num_bytes,
|
|
+ goffset total_num_bytes,
|
|
+ gpointer user_data)
|
|
+{
|
|
+ FrArchive *archive = user_data;
|
|
+
|
|
+ g_signal_emit (G_OBJECT (archive),
|
|
+ fr_archive_signals[PROGRESS],
|
|
+ 0,
|
|
+ (double) current_file / (total_files + 1));
|
|
+}
|
|
+
|
|
+
|
|
+static void
|
|
+copy_extracted_files_to_destination (FrArchive *archive)
|
|
+{
|
|
+ g_directory_copy_async (archive->priv->temp_extraction_dir,
|
|
+ archive->priv->extraction_destination,
|
|
+ G_FILE_COPY_OVERWRITE,
|
|
+ G_PRIORITY_DEFAULT,
|
|
+ archive->priv->cancellable,
|
|
+ copy_extracted_files_progress,
|
|
+ archive,
|
|
+ copy_extracted_files_done,
|
|
+ archive);
|
|
+}
|
|
+
|
|
+
|
|
static void add_dropped_items (DroppedItemsData *data);
|
|
|
|
|
|
@@ -672,6 +894,11 @@ fr_archive_change_name (FrArchive *archive,
|
|
g_object_unref (archive->file);
|
|
archive->file = g_file_get_child (parent, name);
|
|
g_object_unref (parent);
|
|
+
|
|
+ parent = g_file_get_parent (archive->local_copy);
|
|
+ g_object_unref (archive->local_copy);
|
|
+ archive->local_copy = g_file_get_child (parent, name);
|
|
+ g_object_unref (parent);
|
|
}
|
|
|
|
|
|
@@ -686,6 +913,15 @@ action_performed (FrCommand *command,
|
|
#endif
|
|
|
|
switch (action) {
|
|
+ case FR_ACTION_DELETING_FILES:
|
|
+ if (error->type == FR_PROC_ERROR_NONE) {
|
|
+ if (! g_file_has_uri_scheme (archive->file, "file")) {
|
|
+ copy_to_remote_location (archive, action);
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+ break;
|
|
+
|
|
case FR_ACTION_ADDING_FILES:
|
|
if (error->type == FR_PROC_ERROR_NONE) {
|
|
fr_archive_remove_temp_work_dir (archive);
|
|
@@ -701,15 +937,33 @@ action_performed (FrCommand *command,
|
|
* original name */
|
|
if (archive->command->multi_volume)
|
|
fr_archive_change_name (archive, archive->command->filename);
|
|
+ if (! g_file_has_uri_scheme (archive->file, "file")) {
|
|
+ copy_to_remote_location (archive, action);
|
|
+ return;
|
|
+ }
|
|
}
|
|
break;
|
|
|
|
case FR_ACTION_EXTRACTING_FILES:
|
|
if (error->type == FR_PROC_ERROR_NONE) {
|
|
- if (archive->priv->extract_here)
|
|
+ if (archive->priv->remote_extraction) {
|
|
+ copy_extracted_files_to_destination (archive);
|
|
+ return;
|
|
+ }
|
|
+ else if (archive->priv->extract_here)
|
|
move_here (archive);
|
|
}
|
|
else {
|
|
+ /* if an error occurred during extraction remove the
|
|
+ * temp extraction dir, if used. */
|
|
+ g_print ("action_performed: ERROR!\n");
|
|
+
|
|
+ if ((archive->priv->remote_extraction) && (archive->priv->temp_extraction_dir != NULL)) {
|
|
+ remove_local_directory (archive->priv->temp_extraction_dir);
|
|
+ g_free (archive->priv->temp_extraction_dir);
|
|
+ archive->priv->temp_extraction_dir = NULL;
|
|
+ }
|
|
+
|
|
if (archive->priv->extract_here)
|
|
remove_directory (archive->priv->extraction_destination);
|
|
}
|
|
@@ -817,7 +1071,7 @@ fr_archive_create (FrArchive *archive,
|
|
|
|
tmp_command = archive->command;
|
|
|
|
- mime_type = get_mime_type_from_filename (archive->file);
|
|
+ mime_type = get_mime_type_from_filename (archive->local_copy);
|
|
if (! create_command_to_create_archive (archive, mime_type)) {
|
|
archive->command = tmp_command;
|
|
return FALSE;
|
|
@@ -878,11 +1132,11 @@ load_local_archive (FrArchive *archive,
|
|
|
|
tmp_command = archive->command;
|
|
|
|
- mime_type = get_mime_type_from_filename (archive->file);
|
|
+ mime_type = get_mime_type_from_filename (archive->local_copy);
|
|
if (! create_command_to_load_archive (archive, mime_type)) {
|
|
- mime_type = get_mime_type_from_content (archive->file);
|
|
+ mime_type = get_mime_type_from_content (archive->local_copy);
|
|
if (! create_command_to_load_archive (archive, mime_type)) {
|
|
- mime_type = get_mime_type_from_magic_numbers (archive->file);
|
|
+ mime_type = get_mime_type_from_magic_numbers (archive->local_copy);
|
|
if (! create_command_to_load_archive (archive, mime_type)) {
|
|
archive->command = tmp_command;
|
|
archive->content_type = mime_type;
|
|
@@ -921,6 +1175,86 @@ load_local_archive (FrArchive *archive,
|
|
}
|
|
|
|
|
|
+static void
|
|
+copy_remote_file_done (GError *error,
|
|
+ gpointer user_data)
|
|
+{
|
|
+ XferData *xfer_data = user_data;
|
|
+
|
|
+ if (error != NULL)
|
|
+ fr_archive_copy_done (xfer_data->archive, FR_ACTION_LOADING_ARCHIVE, error);
|
|
+ else
|
|
+ load_local_archive (xfer_data->archive, xfer_data->password);
|
|
+ xfer_data_free (xfer_data);
|
|
+}
|
|
+
|
|
+
|
|
+static void
|
|
+copy_remote_file_progress (goffset current_file,
|
|
+ goffset total_files,
|
|
+ GFile *source,
|
|
+ GFile *destination,
|
|
+ goffset current_num_bytes,
|
|
+ goffset total_num_bytes,
|
|
+ gpointer user_data)
|
|
+{
|
|
+ XferData *xfer_data = user_data;
|
|
+
|
|
+ g_signal_emit (G_OBJECT (xfer_data->archive),
|
|
+ fr_archive_signals[PROGRESS],
|
|
+ 0,
|
|
+ (double) current_num_bytes / total_num_bytes);
|
|
+}
|
|
+
|
|
+
|
|
+static gboolean
|
|
+copy_remote_file_done_cb (gpointer user_data)
|
|
+{
|
|
+ XferData *xfer_data = user_data;
|
|
+
|
|
+ g_source_remove (xfer_data->source_id);
|
|
+ copy_remote_file_done (NULL, xfer_data);
|
|
+ return FALSE;
|
|
+}
|
|
+
|
|
+
|
|
+static void
|
|
+copy_remote_file (FrArchive *archive,
|
|
+ const char *password)
|
|
+{
|
|
+ XferData *xfer_data;
|
|
+
|
|
+ if (! g_file_query_exists (archive->file, NULL)) {
|
|
+ GError *error;
|
|
+ error = g_error_new (G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("The file doesn't exist"));
|
|
+ fr_archive_copy_done (archive, FR_ACTION_LOADING_ARCHIVE, error);
|
|
+ g_error_free (error);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ xfer_data = g_new0 (XferData, 1);
|
|
+ xfer_data->archive = archive;
|
|
+ xfer_data->uri = g_file_get_uri (archive->file);
|
|
+ if (password != NULL)
|
|
+ xfer_data->password = g_strdup (password);
|
|
+
|
|
+ if (! archive->is_remote) {
|
|
+ xfer_data->source_id = g_idle_add (copy_remote_file_done_cb, xfer_data);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ g_copy_file_async (archive->file,
|
|
+ archive->local_copy,
|
|
+ G_FILE_COPY_OVERWRITE,
|
|
+ G_PRIORITY_DEFAULT,
|
|
+ archive->priv->cancellable,
|
|
+ copy_remote_file_progress,
|
|
+ xfer_data,
|
|
+ copy_remote_file_done,
|
|
+ xfer_data);
|
|
+}
|
|
+
|
|
+
|
|
gboolean
|
|
fr_archive_load (FrArchive *archive,
|
|
const char *uri,
|
|
@@ -934,7 +1268,7 @@ fr_archive_load (FrArchive *archive,
|
|
FR_ACTION_LOADING_ARCHIVE);
|
|
|
|
fr_archive_set_uri (archive, uri);
|
|
- load_local_archive (archive, password);
|
|
+ copy_remote_file (archive, password);
|
|
|
|
return TRUE;
|
|
}
|
|
@@ -953,7 +1287,7 @@ fr_archive_load_local (FrArchive *archive,
|
|
FR_ACTION_LOADING_ARCHIVE);
|
|
|
|
fr_archive_set_uri (archive, uri);
|
|
- load_local_archive (archive, password);
|
|
+ copy_remote_file (archive, password);
|
|
|
|
return TRUE;
|
|
}
|
|
@@ -1120,18 +1454,12 @@ convert_to_local_file_list (GList *file_list)
|
|
GList *scan;
|
|
|
|
for (scan = file_list; scan; scan = scan->next) {
|
|
- GFile *file;
|
|
- char *uri = scan->data;
|
|
- char *local_filename;
|
|
-
|
|
- file = g_file_new_for_uri (uri);
|
|
- local_filename = g_file_get_path (file);
|
|
- if (local_filename == NULL)
|
|
- local_filename = g_strdup (uri);
|
|
+ char *uri = scan->data;
|
|
+ char *local_filename;
|
|
+
|
|
+ local_filename = g_uri_unescape_string (uri, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH);
|
|
if (local_filename != NULL)
|
|
local_file_list = g_list_prepend (local_file_list, local_filename);
|
|
-
|
|
- g_object_unref (file);
|
|
}
|
|
|
|
return local_file_list;
|
|
@@ -1446,6 +1774,145 @@ fr_archive_add_local_files (FrArchive *archive,
|
|
}
|
|
|
|
|
|
+static void
|
|
+copy_remote_files_done (GError *error,
|
|
+ gpointer user_data)
|
|
+{
|
|
+ XferData *xfer_data = user_data;
|
|
+
|
|
+ fr_archive_copy_done (xfer_data->archive, FR_ACTION_COPYING_FILES_FROM_REMOTE, error);
|
|
+
|
|
+ if (error == NULL)
|
|
+ fr_archive_add_local_files (xfer_data->archive,
|
|
+ xfer_data->file_list,
|
|
+ xfer_data->tmp_dir,
|
|
+ xfer_data->dest_dir,
|
|
+ FALSE,
|
|
+ xfer_data->password,
|
|
+ xfer_data->encrypt_header,
|
|
+ xfer_data->compression,
|
|
+ xfer_data->volume_size);
|
|
+ xfer_data_free (xfer_data);
|
|
+}
|
|
+
|
|
+
|
|
+static void
|
|
+copy_remote_files_progress (goffset current_file,
|
|
+ goffset total_files,
|
|
+ GFile *source,
|
|
+ GFile *destination,
|
|
+ goffset current_num_bytes,
|
|
+ goffset total_num_bytes,
|
|
+ gpointer user_data)
|
|
+{
|
|
+ XferData *xfer_data = user_data;
|
|
+
|
|
+ g_signal_emit (G_OBJECT (xfer_data->archive),
|
|
+ fr_archive_signals[PROGRESS],
|
|
+ 0,
|
|
+ (double) current_file / (total_files + 1));
|
|
+}
|
|
+
|
|
+
|
|
+static void
|
|
+copy_remote_files (FrArchive *archive,
|
|
+ GList *file_list,
|
|
+ const char *base_uri,
|
|
+ const char *dest_dir,
|
|
+ gboolean update,
|
|
+ const char *password,
|
|
+ gboolean encrypt_header,
|
|
+ FrCompression compression,
|
|
+ guint volume_size,
|
|
+ const char *tmp_dir)
|
|
+{
|
|
+ GList *sources = NULL, *destinations = NULL;
|
|
+ GHashTable *created_folders;
|
|
+ GList *scan;
|
|
+ XferData *xfer_data;
|
|
+
|
|
+ created_folders = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, NULL);
|
|
+ for (scan = file_list; scan; scan = scan->next) {
|
|
+ char *partial_filename = scan->data;
|
|
+ char *local_uri;
|
|
+ char *local_folder_uri;
|
|
+ char *remote_uri;
|
|
+
|
|
+ local_uri = g_strconcat ("file://", tmp_dir, "/", partial_filename, NULL);
|
|
+ local_folder_uri = remove_level_from_path (local_uri);
|
|
+ if (g_hash_table_lookup (created_folders, local_folder_uri) == NULL) {
|
|
+ GError *error = NULL;
|
|
+ if (! ensure_dir_exists (local_folder_uri, 0755, &error)) {
|
|
+ g_free (local_folder_uri);
|
|
+ g_free (local_uri);
|
|
+ gio_file_list_free (sources);
|
|
+ gio_file_list_free (destinations);
|
|
+ g_hash_table_destroy (created_folders);
|
|
+
|
|
+ fr_archive_action_completed (archive,
|
|
+ FR_ACTION_COPYING_FILES_FROM_REMOTE,
|
|
+ FR_PROC_ERROR_GENERIC,
|
|
+ error->message);
|
|
+ g_clear_error (&error);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ g_hash_table_insert (created_folders, local_folder_uri, GINT_TO_POINTER (1));
|
|
+ }
|
|
+ else
|
|
+ g_free (local_folder_uri);
|
|
+
|
|
+ remote_uri = g_strconcat (base_uri, "/", partial_filename, NULL);
|
|
+ sources = g_list_append (sources, g_file_new_for_uri (remote_uri));
|
|
+ g_free (remote_uri);
|
|
+
|
|
+ destinations = g_list_append (destinations, g_file_new_for_uri (local_uri));
|
|
+ g_free (local_uri);
|
|
+ }
|
|
+ g_hash_table_destroy (created_folders);
|
|
+
|
|
+ xfer_data = g_new0 (XferData, 1);
|
|
+ xfer_data->archive = archive;
|
|
+ xfer_data->file_list = path_list_dup (file_list);
|
|
+ xfer_data->base_uri = g_strdup (base_uri);
|
|
+ xfer_data->dest_dir = g_strdup (dest_dir);
|
|
+ xfer_data->update = update;
|
|
+ xfer_data->dest_dir = g_strdup (dest_dir);
|
|
+ xfer_data->password = g_strdup (password);
|
|
+ xfer_data->encrypt_header = encrypt_header;
|
|
+ xfer_data->compression = compression;
|
|
+ xfer_data->volume_size = volume_size;
|
|
+ xfer_data->tmp_dir = g_strdup (tmp_dir);
|
|
+
|
|
+ g_signal_emit (G_OBJECT (archive),
|
|
+ fr_archive_signals[START],
|
|
+ 0,
|
|
+ FR_ACTION_COPYING_FILES_FROM_REMOTE);
|
|
+
|
|
+ g_copy_files_async (sources,
|
|
+ destinations,
|
|
+ G_FILE_COPY_OVERWRITE,
|
|
+ G_PRIORITY_DEFAULT,
|
|
+ archive->priv->cancellable,
|
|
+ copy_remote_files_progress,
|
|
+ xfer_data,
|
|
+ copy_remote_files_done,
|
|
+ xfer_data);
|
|
+
|
|
+ gio_file_list_free (sources);
|
|
+ gio_file_list_free (destinations);
|
|
+}
|
|
+
|
|
+
|
|
+static char *
|
|
+fr_archive_get_temp_work_dir (FrArchive *archive)
|
|
+{
|
|
+ fr_archive_remove_temp_work_dir (archive);
|
|
+ archive->priv->temp_dir = get_temp_work_dir (NULL);
|
|
+ return archive->priv->temp_dir;
|
|
+}
|
|
+
|
|
+
|
|
void
|
|
fr_archive_add_files (FrArchive *archive,
|
|
GList *file_list,
|
|
@@ -1457,23 +1924,30 @@ fr_archive_add_files (FrArchive *archive,
|
|
FrCompression compression,
|
|
guint volume_size)
|
|
{
|
|
- GFile *file;
|
|
- char *local_dir;
|
|
-
|
|
- file = g_file_new_for_uri (base_dir);
|
|
- local_dir = g_file_get_path (file);
|
|
- fr_archive_add_local_files (archive,
|
|
- file_list,
|
|
- local_dir,
|
|
- dest_dir,
|
|
- update,
|
|
- password,
|
|
- encrypt_header,
|
|
- compression,
|
|
- volume_size);
|
|
-
|
|
- g_free (local_dir);
|
|
- g_object_unref (file);
|
|
+ if (uri_is_local (base_dir)) {
|
|
+ char *local_dir = g_filename_from_uri (base_dir, NULL, NULL);
|
|
+ fr_archive_add_local_files (archive,
|
|
+ file_list,
|
|
+ local_dir,
|
|
+ dest_dir,
|
|
+ update,
|
|
+ password,
|
|
+ encrypt_header,
|
|
+ compression,
|
|
+ volume_size);
|
|
+ g_free (local_dir);
|
|
+ }
|
|
+ else
|
|
+ copy_remote_files (archive,
|
|
+ file_list,
|
|
+ base_dir,
|
|
+ dest_dir,
|
|
+ update,
|
|
+ password,
|
|
+ encrypt_header,
|
|
+ compression,
|
|
+ volume_size,
|
|
+ fr_archive_get_temp_work_dir (archive));
|
|
}
|
|
|
|
|
|
@@ -2675,25 +3149,38 @@ fr_archive_extract (FrArchive *archive,
|
|
gboolean junk_paths,
|
|
const char *password)
|
|
{
|
|
- GFile *file;
|
|
- char *local_destination;
|
|
-
|
|
g_free (archive->priv->extraction_destination);
|
|
archive->priv->extraction_destination = g_strdup (destination);
|
|
|
|
- file = g_file_new_for_uri (destination);
|
|
- local_destination = g_file_get_path (file);
|
|
- fr_archive_extract_to_local (archive,
|
|
- file_list,
|
|
- local_destination,
|
|
- base_dir,
|
|
- skip_older,
|
|
- overwrite,
|
|
- junk_paths,
|
|
- password);
|
|
-
|
|
- g_free (local_destination);
|
|
- g_object_unref (file);
|
|
+ g_free (archive->priv->temp_extraction_dir);
|
|
+ archive->priv->temp_extraction_dir = NULL;
|
|
+
|
|
+ archive->priv->remote_extraction = ! uri_is_local (destination);
|
|
+ if (archive->priv->remote_extraction) {
|
|
+ archive->priv->temp_extraction_dir = get_temp_work_dir (NULL);
|
|
+ fr_archive_extract_to_local (archive,
|
|
+ file_list,
|
|
+ archive->priv->temp_extraction_dir,
|
|
+ base_dir,
|
|
+ skip_older,
|
|
+ overwrite,
|
|
+ junk_paths,
|
|
+ password);
|
|
+ }
|
|
+ else {
|
|
+ char *local_destination;
|
|
+
|
|
+ local_destination = g_filename_from_uri (destination, NULL, NULL);
|
|
+ fr_archive_extract_to_local (archive,
|
|
+ file_list,
|
|
+ local_destination,
|
|
+ base_dir,
|
|
+ skip_older,
|
|
+ overwrite,
|
|
+ junk_paths,
|
|
+ password);
|
|
+ g_free (local_destination);
|
|
+ }
|
|
}
|
|
|
|
|
|
diff --git a/src/fr-archive.h b/src/fr-archive.h
|
|
index 2c485a2..530e49e 100644
|
|
--- a/src/fr-archive.h
|
|
+++ b/src/fr-archive.h
|
|
@@ -44,6 +44,8 @@ struct _FrArchive {
|
|
GObject __parent;
|
|
|
|
GFile *file;
|
|
+ GFile *local_copy;
|
|
+ gboolean is_remote;
|
|
const char *content_type;
|
|
FrCommand *command;
|
|
FrProcess *process;
|
|
diff --git a/src/fr-window.c b/src/fr-window.c
|
|
index 8eeb833..d8fb08e 100644
|
|
--- a/src/fr-window.c
|
|
+++ b/src/fr-window.c
|
|
@@ -4226,14 +4226,14 @@ get_selection_data_from_clipboard_data (FrWindow *window,
|
|
FrClipboardData *data)
|
|
{
|
|
GString *list;
|
|
- char *archive_uri;
|
|
+ char *local_filename;
|
|
GList *scan;
|
|
|
|
list = g_string_new (NULL);
|
|
|
|
- archive_uri = g_file_get_uri (window->archive->file);
|
|
- g_string_append (list, archive_uri);
|
|
- g_free (archive_uri);
|
|
+ local_filename = g_file_get_uri (window->archive->local_copy);
|
|
+ g_string_append (list, local_filename);
|
|
+ g_free (local_filename);
|
|
|
|
g_string_append (list, "\r\n");
|
|
if (window->priv->password != NULL)
|
|
diff --git a/src/gio-utils.c b/src/gio-utils.c
|
|
index f94e94f..7886b2e 100644
|
|
--- a/src/gio-utils.c
|
|
+++ b/src/gio-utils.c
|
|
@@ -127,7 +127,7 @@ filter_empty (Filter *filter)
|
|
|
|
|
|
typedef struct {
|
|
- char *base_directory;
|
|
+ GFile *base_directory;
|
|
gboolean recursive;
|
|
gboolean follow_links;
|
|
StartDirCallback start_dir_func;
|
|
@@ -153,7 +153,8 @@ for_each_child_data_free (ForEachChildData *fec)
|
|
if (fec == NULL)
|
|
return;
|
|
|
|
- g_free (fec->base_directory);
|
|
+ if (fec->base_directory != NULL)
|
|
+ g_object_unref (fec->base_directory);
|
|
if (fec->current != NULL)
|
|
g_object_unref (fec->current);
|
|
if (fec->already_visited)
|
|
@@ -172,7 +173,7 @@ for_each_child_done_cb (gpointer user_data)
|
|
g_source_remove (fec->source_id);
|
|
if (fec->current != NULL) {
|
|
g_object_unref (fec->current);
|
|
- fec->current = NULL;
|
|
+ fec->current = NULL;
|
|
}
|
|
if (fec->done_func)
|
|
fec->done_func (fec->error, fec->user_data);
|
|
@@ -212,8 +213,8 @@ for_each_child_start (ForEachChildData *fec)
|
|
|
|
|
|
static void
|
|
-for_each_child_set_current (ForEachChildData *fec,
|
|
- const char *directory)
|
|
+for_each_child_set_current_uri (ForEachChildData *fec,
|
|
+ const char *directory)
|
|
{
|
|
if (fec->current != NULL)
|
|
g_object_unref (fec->current);
|
|
@@ -222,6 +223,15 @@ for_each_child_set_current (ForEachChildData *fec,
|
|
|
|
|
|
static void
|
|
+for_each_child_set_current (ForEachChildData *fec,
|
|
+ GFile *directory)
|
|
+{
|
|
+ if (fec->current != NULL)
|
|
+ g_object_unref (fec->current);
|
|
+ fec->current = g_file_dup (directory);
|
|
+}
|
|
+
|
|
+static void
|
|
for_each_child_start_next_sub_directory (ForEachChildData *fec)
|
|
{
|
|
char *sub_directory = NULL;
|
|
@@ -236,7 +246,7 @@ for_each_child_start_next_sub_directory (ForEachChildData *fec)
|
|
}
|
|
|
|
if (sub_directory != NULL) {
|
|
- for_each_child_set_current (fec, sub_directory);
|
|
+ for_each_child_set_current_uri (fec, sub_directory);
|
|
for_each_child_start (fec);
|
|
}
|
|
else
|
|
@@ -276,7 +286,6 @@ for_each_child_next_files_ready (GObject *source_object,
|
|
{
|
|
ForEachChildData *fec = user_data;
|
|
GList *children, *scan;
|
|
- char *current_directory;
|
|
|
|
children = g_file_enumerator_next_files_finish (fec->enumerator,
|
|
result,
|
|
@@ -291,16 +300,16 @@ for_each_child_next_files_ready (GObject *source_object,
|
|
return;
|
|
}
|
|
|
|
- current_directory = g_file_get_uri (fec->current);
|
|
for (scan = children; scan; scan = scan->next) {
|
|
GFileInfo *child_info = scan->data;
|
|
- char *name, *uri;
|
|
+ GFile *f;
|
|
+ char *uri;
|
|
|
|
- name = g_uri_escape_string (g_file_info_get_name (child_info), G_URI_RESERVED_CHARS_ALLOWED_IN_PATH_ELEMENT, FALSE);
|
|
- uri = g_strconcat (current_directory, "/", name, NULL);
|
|
+ f = g_file_get_child (fec->current, g_file_info_get_name (child_info));
|
|
+ uri = g_file_get_uri (f);
|
|
|
|
if (g_file_info_get_file_type (child_info) == G_FILE_TYPE_DIRECTORY) {
|
|
- /* avoid to visit a directory more than ones */
|
|
+ /* avoid to visit a directory more than once */
|
|
|
|
if (g_hash_table_lookup (fec->already_visited, uri) == NULL) {
|
|
char *sub_directory;
|
|
@@ -314,9 +323,8 @@ for_each_child_next_files_ready (GObject *source_object,
|
|
fec->for_each_file_func (uri, child_info, fec->user_data);
|
|
|
|
g_free (uri);
|
|
- g_free (name);
|
|
+ g_object_unref (f);
|
|
}
|
|
- g_free (current_directory);
|
|
|
|
g_file_enumerator_next_files_async (fec->enumerator,
|
|
N_FILES_PER_REQUEST,
|
|
@@ -404,7 +412,7 @@ for_each_child_start_current (ForEachChildData *fec)
|
|
* Each callback uses the same @user_data additional parameter.
|
|
*/
|
|
void
|
|
-g_directory_foreach_child (const char *directory,
|
|
+g_directory_foreach_child (GFile *directory,
|
|
gboolean recursive,
|
|
gboolean follow_links,
|
|
GCancellable *cancellable,
|
|
@@ -419,7 +427,7 @@ g_directory_foreach_child (const char *directory,
|
|
|
|
fec = g_new0 (ForEachChildData, 1);
|
|
|
|
- fec->base_directory = g_strdup (directory);
|
|
+ fec->base_directory = g_object_ref (directory);
|
|
fec->recursive = recursive;
|
|
fec->follow_links = follow_links;
|
|
fec->cancellable = cancellable;
|
|
@@ -443,8 +451,8 @@ g_directory_foreach_child (const char *directory,
|
|
typedef struct {
|
|
GList *files;
|
|
GList *dirs;
|
|
- char *directory;
|
|
- char *base_dir;
|
|
+ GFile *directory;
|
|
+ GFile *base_dir;
|
|
GCancellable *cancellable;
|
|
ListReadyCallback done_func;
|
|
gpointer done_data;
|
|
@@ -469,8 +477,10 @@ get_file_list_data_free (GetFileListData *gfl)
|
|
path_list_free (gfl->files);
|
|
path_list_free (gfl->dirs);
|
|
path_list_free (gfl->to_visit);
|
|
- g_free (gfl->directory);
|
|
- g_free (gfl->base_dir);
|
|
+ if (gfl->directory != NULL)
|
|
+ g_object_unref (gfl->directory);
|
|
+ if (gfl->base_dir != NULL)
|
|
+ g_object_unref (gfl->base_dir);
|
|
g_free (gfl);
|
|
}
|
|
|
|
@@ -479,27 +489,25 @@ get_file_list_data_free (GetFileListData *gfl)
|
|
|
|
|
|
static GList*
|
|
-get_relative_file_list (GList *rel_list,
|
|
- GList *file_list,
|
|
- const char *base_dir)
|
|
+get_relative_file_list (GList *rel_list,
|
|
+ GList *file_list,
|
|
+ GFile *base_dir)
|
|
{
|
|
GList *scan;
|
|
- int base_len;
|
|
|
|
if (base_dir == NULL)
|
|
return NULL;
|
|
|
|
- base_len = 0;
|
|
- if (strcmp (base_dir, "/") != 0)
|
|
- base_len = strlen (base_dir);
|
|
-
|
|
for (scan = file_list; scan; scan = scan->next) {
|
|
- char *full_path = scan->data;
|
|
-
|
|
- if (path_in_path (base_dir, full_path)) {
|
|
- char *rel_path = g_uri_unescape_string (full_path + base_len + 1, NULL);
|
|
- rel_list = g_list_prepend (rel_list, rel_path);
|
|
- }
|
|
+ char *full_path = scan->data;
|
|
+ GFile *f;
|
|
+ char *relative_path;
|
|
+
|
|
+ f = g_file_new_for_commandline_arg (full_path);
|
|
+ relative_path = g_file_get_relative_path (base_dir, f);
|
|
+ if (relative_path != NULL)
|
|
+ rel_list = g_list_prepend (rel_list, relative_path);
|
|
+ g_object_unref (f);
|
|
}
|
|
|
|
return rel_list;
|
|
@@ -565,6 +573,7 @@ get_file_list_done (GError *error,
|
|
GetFileListData *gfl = user_data;
|
|
GHashTable *h_dirs;
|
|
GList *scan;
|
|
+ char *uri;
|
|
|
|
gfl->files = g_list_reverse (gfl->files);
|
|
gfl->dirs = g_list_reverse (gfl->dirs);
|
|
@@ -582,7 +591,7 @@ get_file_list_done (GError *error,
|
|
if (gfl->base_dir != NULL) {
|
|
char *dir;
|
|
|
|
- dir = g_strdup (gfl->base_dir);
|
|
+ dir = g_file_get_uri (gfl->base_dir);
|
|
gfl->dirs = g_list_prepend (gfl->dirs, dir);
|
|
g_hash_table_insert (h_dirs, dir, GINT_TO_POINTER (1));
|
|
}
|
|
@@ -594,11 +603,13 @@ get_file_list_done (GError *error,
|
|
for (scan = gfl->dirs; scan; scan = scan->next)
|
|
g_hash_table_insert (h_dirs, (char*)scan->data, GINT_TO_POINTER (1));
|
|
|
|
- gfl->dirs = g_list_concat (gfl->dirs, get_dir_list_from_file_list (h_dirs, gfl->base_dir, gfl->files, FALSE));
|
|
+ uri = g_file_get_uri (gfl->base_dir);
|
|
+ gfl->dirs = g_list_concat (gfl->dirs, get_dir_list_from_file_list (h_dirs, uri, gfl->files, FALSE));
|
|
|
|
if (filter_empty (gfl->include_filter))
|
|
- gfl->dirs = g_list_concat (gfl->dirs, get_dir_list_from_file_list (h_dirs, gfl->base_dir, gfl->dirs, TRUE));
|
|
+ gfl->dirs = g_list_concat (gfl->dirs, get_dir_list_from_file_list (h_dirs, uri, gfl->dirs, TRUE));
|
|
|
|
+ g_free (uri);
|
|
/**/
|
|
|
|
if (error == NULL) {
|
|
@@ -680,8 +691,8 @@ g_directory_list_async (const char *directory,
|
|
FilterOptions filter_options;
|
|
|
|
gfl = g_new0 (GetFileListData, 1);
|
|
- gfl->directory = g_strdup (directory);
|
|
- gfl->base_dir = g_strdup (base_dir);
|
|
+ gfl->directory = g_file_new_for_commandline_arg (directory);
|
|
+ gfl->base_dir = g_file_new_for_commandline_arg (base_dir);
|
|
gfl->done_func = done_func;
|
|
gfl->done_data = done_data;
|
|
|
|
@@ -696,7 +707,7 @@ g_directory_list_async (const char *directory,
|
|
gfl->exclude_filter = filter_new (exclude_files, ignorecase ? FILTER_IGNORECASE : FILTER_DEFAULT);
|
|
gfl->exclude_folders_filter = filter_new (exclude_folders, ignorecase ? FILTER_IGNORECASE : FILTER_DEFAULT);
|
|
|
|
- g_directory_foreach_child (directory,
|
|
+ g_directory_foreach_child (gfl->directory,
|
|
recursive,
|
|
follow_links,
|
|
cancellable,
|
|
@@ -756,7 +767,9 @@ static void
|
|
get_items_for_current_dir (GetFileListData *gfl)
|
|
{
|
|
const char *directory_name;
|
|
+ GFile *directory_file;
|
|
char *directory_uri;
|
|
+ char *base_dir_uri;
|
|
|
|
if (gfl->current_dir == NULL) {
|
|
if (gfl->done_func) {
|
|
@@ -770,19 +783,20 @@ get_items_for_current_dir (GetFileListData *gfl)
|
|
}
|
|
|
|
directory_name = file_name_from_path ((char*) gfl->current_dir->data);
|
|
- if (strcmp (gfl->base_dir, "/") == 0)
|
|
- directory_uri = g_strconcat (gfl->base_dir, directory_name, NULL);
|
|
- else
|
|
- directory_uri = g_strconcat (gfl->base_dir, "/", directory_name, NULL);
|
|
+ directory_file = g_file_get_child (gfl->base_dir, directory_name);
|
|
+ directory_uri = g_file_get_uri (directory_file);
|
|
+ base_dir_uri = g_file_get_uri (gfl->base_dir);
|
|
|
|
g_directory_list_all_async (directory_uri,
|
|
- gfl->base_dir,
|
|
+ base_dir_uri,
|
|
TRUE,
|
|
gfl->cancellable,
|
|
- get_items_for_current_dir_done,
|
|
- gfl);
|
|
+ get_items_for_current_dir_done,
|
|
+ gfl);
|
|
|
|
g_free (directory_uri);
|
|
+ g_free (base_dir_uri);
|
|
+ g_object_unref (directory_file);
|
|
}
|
|
|
|
|
|
@@ -800,7 +814,7 @@ g_list_items_async (GList *items,
|
|
g_return_if_fail (base_dir != NULL);
|
|
|
|
gfl = g_new0 (GetFileListData, 1);
|
|
- gfl->base_dir = g_strdup (base_dir);
|
|
+ gfl->base_dir = g_file_new_for_commandline_arg (base_dir);
|
|
gfl->cancellable = cancellable;
|
|
gfl->done_func = done_func;
|
|
gfl->done_data = done_data;
|
|
@@ -916,6 +930,19 @@ g_copy_files_ready_cb (GObject *source_object,
|
|
GError *error = NULL;
|
|
|
|
if (! g_file_copy_finish (source, result, &error)) {
|
|
+ /* source and target are directories, ignore the error */
|
|
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_MERGE))
|
|
+ g_clear_error (&error);
|
|
+ /* source is directory, create target directory */
|
|
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_RECURSE)) {
|
|
+ g_clear_error (&error);
|
|
+ g_file_make_directory ((GFile*) cfd->destination->data,
|
|
+ cfd->cancellable,
|
|
+ &error);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (error) {
|
|
if (cfd->callback)
|
|
cfd->callback (error, cfd->user_data);
|
|
g_clear_error (&error);
|
|
@@ -1123,8 +1150,8 @@ child_data_free (ChildData *child)
|
|
|
|
|
|
typedef struct {
|
|
- char *source;
|
|
- char *destination;
|
|
+ GFile *source;
|
|
+ GFile *destination;
|
|
GFileCopyFlags flags;
|
|
int io_priority;
|
|
GCancellable *cancellable;
|
|
@@ -1149,8 +1176,10 @@ directory_copy_data_free (DirectoryCopyData *dcd)
|
|
if (dcd == NULL)
|
|
return;
|
|
|
|
- g_free (dcd->source);
|
|
- g_free (dcd->destination);
|
|
+ if (dcd->source != NULL)
|
|
+ g_object_unref (dcd->source);
|
|
+ if (dcd->destination != NULL)
|
|
+ g_object_unref (dcd->destination);
|
|
if (dcd->current_source != NULL) {
|
|
g_object_unref (dcd->current_source);
|
|
dcd->current_source = NULL;
|
|
@@ -1161,7 +1190,6 @@ directory_copy_data_free (DirectoryCopyData *dcd)
|
|
}
|
|
g_list_foreach (dcd->to_copy, (GFunc) child_data_free, NULL);
|
|
g_list_free (dcd->to_copy);
|
|
- g_object_unref (dcd->cancellable);
|
|
g_free (dcd);
|
|
}
|
|
|
|
@@ -1187,15 +1215,19 @@ static GFile *
|
|
get_destination_for_uri (DirectoryCopyData *dcd,
|
|
const char *uri)
|
|
{
|
|
- char *destination_uri;
|
|
+ GFile *f_uri;
|
|
GFile *destination_file;
|
|
+ char *relative_path;
|
|
|
|
- if (strlen (uri) <= strlen (dcd->source))
|
|
- return NULL;
|
|
+ f_uri = g_file_new_for_uri (uri);
|
|
+ relative_path = g_file_get_relative_path (dcd->source, f_uri);
|
|
+ if (relative_path != NULL)
|
|
+ destination_file = g_file_resolve_relative_path (dcd->destination, relative_path);
|
|
+ else
|
|
+ destination_file = g_file_dup (dcd->destination);
|
|
|
|
- destination_uri = g_strconcat (dcd->destination, "/", uri + strlen (dcd->source) + 1, NULL);
|
|
- destination_file = g_file_new_for_uri (destination_uri);
|
|
- g_free (destination_uri);
|
|
+ g_free (relative_path);
|
|
+ g_object_unref (f_uri);
|
|
|
|
return destination_file;
|
|
}
|
|
@@ -1417,9 +1449,10 @@ g_directory_copy_async (const char *source,
|
|
{
|
|
DirectoryCopyData *dcd;
|
|
|
|
+ /* Creating GFile objects here will save us lot of effort in path construction */
|
|
dcd = g_new0 (DirectoryCopyData, 1);
|
|
- dcd->source = g_strdup (source);
|
|
- dcd->destination = g_strdup (destination);
|
|
+ dcd->source = g_file_new_for_commandline_arg (source);
|
|
+ dcd->destination = g_file_new_for_commandline_arg (destination);
|
|
dcd->flags = flags;
|
|
dcd->io_priority = io_priority;
|
|
dcd->cancellable = cancellable;
|
|
diff --git a/src/gio-utils.h b/src/gio-utils.h
|
|
index 4cd0a49..7dfe306 100644
|
|
--- a/src/gio-utils.h
|
|
+++ b/src/gio-utils.h
|
|
@@ -58,7 +58,7 @@ typedef void (*CopyDoneCallback) (GError *error,
|
|
|
|
/* asynchronous recursive list functions */
|
|
|
|
-void g_directory_foreach_child (const char *directory,
|
|
+void g_directory_foreach_child (GFile *directory,
|
|
gboolean recursive,
|
|
gboolean follow_links,
|
|
GCancellable *cancellable,
|
|
--
|
|
cgit v0.8.3.1
|