rpms/file-roller/F-12 file-roller-2.28.2-gvfs-fuse.patch, NONE, 1.1 file-roller.spec, 1.164, 1.165
Tomas Bzatek
tbzatek at fedoraproject.org
Tue May 18 13:07:37 UTC 2010
Author: tbzatek
Update of /cvs/extras/rpms/file-roller/F-12
In directory cvs01.phx2.fedoraproject.org:/tmp/cvs-serv18352
Modified Files:
file-roller.spec
Added Files:
file-roller-2.28.2-gvfs-fuse.patch
Log Message:
* Mon May 17 2010 Tomas Bzatek <tbzatek at redhat.com> 2.28.2-3
- Fix archive handling on remote GIO mounts without running fuse daemon (#527045, #518510)
file-roller-2.28.2-gvfs-fuse.patch:
fr-archive.c | 593 +++++++++++++++++++++++++++++++++++++++++++++++++++++------
fr-archive.h | 2
fr-window.c | 8
gio-utils.c | 155 +++++++++------
gio-utils.h | 2
5 files changed, 641 insertions(+), 119 deletions(-)
--- NEW FILE file-roller-2.28.2-gvfs-fuse.patch ---
diff -up file-roller-2.28.2/src/fr-archive.c.gvfs-fuse file-roller-2.28.2/src/fr-archive.c
--- file-roller-2.28.2/src/fr-archive.c.gvfs-fuse 2009-12-15 09:46:24.000000000 +0100
+++ file-roller-2.28.2/src/fr-archive.c 2010-05-17 16:59:32.000000000 +0200
@@ -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);
@@ -500,7 +594,7 @@ create_command_from_type (FrArchive
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,
@@ -587,6 +681,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)
{
@@ -655,6 +822,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);
@@ -671,6 +893,11 @@ fr_archive_change_name (FrArchive *arch
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);
}
@@ -685,6 +912,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);
@@ -700,15 +936,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);
}
@@ -816,7 +1070,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;
@@ -870,11 +1124,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;
fr_archive_action_completed (archive,
@@ -912,6 +1166,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->uri, 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,
@@ -925,7 +1259,7 @@ fr_archive_load (FrArchive *archive,
FR_ACTION_LOADING_ARCHIVE);
fr_archive_set_uri (archive, uri);
- load_local_archive (archive, uri, password);
+ copy_remote_file (archive, password);
return TRUE;
}
@@ -944,7 +1278,7 @@ fr_archive_load_local (FrArchive *archi
FR_ACTION_LOADING_ARCHIVE);
fr_archive_set_uri (archive, uri);
- load_local_archive (archive, uri, password);
+ copy_remote_file (archive, password);
return TRUE;
}
@@ -1111,18 +1445,12 @@ convert_to_local_file_list (GList *file_
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;
@@ -1437,6 +1765,145 @@ fr_archive_add_local_files (FrArchive
}
+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,
@@ -1448,23 +1915,30 @@ fr_archive_add_files (FrArchive *arc
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));
}
@@ -2669,25 +3143,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 (archive->priv->temp_extraction_dir);
+ archive->priv->temp_extraction_dir = NULL;
- g_free (local_destination);
- g_object_unref (file);
+ 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 -up file-roller-2.28.2/src/fr-archive.h.gvfs-fuse file-roller-2.28.2/src/fr-archive.h
--- file-roller-2.28.2/src/fr-archive.h.gvfs-fuse 2009-11-07 19:38:19.000000000 +0100
+++ file-roller-2.28.2/src/fr-archive.h 2010-05-17 16:57:20.000000000 +0200
@@ -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 -up file-roller-2.28.2/src/fr-window.c.gvfs-fuse file-roller-2.28.2/src/fr-window.c
--- file-roller-2.28.2/src/fr-window.c.gvfs-fuse 2009-12-15 09:47:21.000000000 +0100
+++ file-roller-2.28.2/src/fr-window.c 2010-05-17 16:57:20.000000000 +0200
@@ -4185,14 +4185,14 @@ get_selection_data_from_clipboard_data (
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 -up file-roller-2.28.2/src/gio-utils.c.gvfs-fuse file-roller-2.28.2/src/gio-utils.c
--- file-roller-2.28.2/src/gio-utils.c.gvfs-fuse 2009-11-07 19:38:19.000000000 +0100
+++ file-roller-2.28.2/src/gio-utils.c 2010-05-17 16:57:20.000000000 +0200
@@ -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 (ForEachChildDa
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_da
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 *
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 (ForEachChild
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
}
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
{
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
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
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 (ForEachChi
* 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
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
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
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
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
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
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 (GetFileListDa
}
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 *i
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 *sou
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 (DirectoryCopyD
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 (DirectoryCopyD
}
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
{
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 -up file-roller-2.28.2/src/gio-utils.h.gvfs-fuse file-roller-2.28.2/src/gio-utils.h
--- file-roller-2.28.2/src/gio-utils.h.gvfs-fuse 2009-04-30 10:47:42.000000000 +0200
+++ file-roller-2.28.2/src/gio-utils.h 2010-05-17 16:57:20.000000000 +0200
@@ -58,7 +58,7 @@ typedef void (*CopyDoneCallback) (GE
/* 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,
Index: file-roller.spec
===================================================================
RCS file: /cvs/extras/rpms/file-roller/F-12/file-roller.spec,v
retrieving revision 1.164
retrieving revision 1.165
diff -u -p -r1.164 -r1.165
--- file-roller.spec 7 Jan 2010 22:18:09 -0000 1.164
+++ file-roller.spec 18 May 2010 13:07:37 -0000 1.165
@@ -11,7 +11,7 @@
Summary: Tool for viewing and creating archives
Name: file-roller
Version: 2.28.2
-Release: 2%{?dist}
+Release: 3%{?dist}
License: GPLv2+
Group: Applications/Archiving
URL: http://download.gnome.org/sources/file-roller/
@@ -20,6 +20,10 @@ Source: http://download.gnome.org/sourc
# https://bugzilla.gnome.org/show_bug.cgi?id=606074
Patch0: file-roller-arj-crash.patch
+# from master
+# http://bugzilla.gnome.org/show_bug.cgi?id=617769
+Patch1: file-roller-2.28.2-gvfs-fuse.patch
+
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildRequires: glib2-devel >= %{glib2_version}
BuildRequires: pango-devel >= %{pango_version}
@@ -54,6 +58,7 @@ such as tar or zip files.
%prep
%setup -q
%patch0 -p1 -b .arj-crash
+%patch1 -p1 -b .gvfs-fuse
%build
%configure --disable-scrollkeeper --disable-static
@@ -130,6 +135,9 @@ fi
%{_datadir}/icons/hicolor/scalable/apps/file-roller.svg
%changelog
+* Mon May 17 2010 Tomas Bzatek <tbzatek at redhat.com> 2.28.2-3
+- Fix archive handling on remote GIO mounts without running fuse daemon (#527045, #518510)
+
* Thu Jan 7 2010 Matthias Clasen <mclasen at redhat.com> 2.28.2-2
- Fix a crash in the arj loader (#551717)
More information about the scm-commits
mailing list