[file-roller: 1/123] make FrArchive more abstract and FrCommand a subclass of it
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [file-roller: 1/123] make FrArchive more abstract and FrCommand a subclass of it
- Date: Mon, 6 Aug 2012 13:40:56 +0000 (UTC)
commit 4b64c5ece7a4e209799b72845b1587d4b9323940
Author: Paolo Bacchilega <paobac src gnome org>
Date: Mon Jul 16 20:53:20 2012 +0200
make FrArchive more abstract and FrCommand a subclass of it
this will allow to handle some archive types using a library instead of
executing external utilities.
src/Makefile.am | 2 -
src/actions.c | 14 +-
src/dlg-batch-add.c | 12 +-
src/dlg-new.c | 14 +-
src/dlg-package-installer.c | 46 +-
src/dlg-prop.c | 6 +-
src/fr-archive.c | 4142 +++++++++++++------------------------------
src/fr-archive.h | 616 +++++--
src/fr-command-7z.c | 364 ++--
src/fr-command-ace.c | 40 +-
src/fr-command-ace.h | 2 -
src/fr-command-alz.c | 50 +-
src/fr-command-ar.c | 36 +-
src/fr-command-arj.c | 58 +-
src/fr-command-cfile.c | 113 +-
src/fr-command-cfile.h | 2 +-
src/fr-command-cpio.c | 40 +-
src/fr-command-dpkg.c | 35 +-
src/fr-command-iso.c | 39 +-
src/fr-command-jar.c | 23 +-
src/fr-command-lha.c | 32 +-
src/fr-command-lrzip.c | 32 +-
src/fr-command-rar.c | 95 +-
src/fr-command-rpm.c | 32 +-
src/fr-command-tar.c | 207 ++-
src/fr-command-unarchiver.c | 54 +-
src/fr-command-unstuff.c | 38 +-
src/fr-command-zip.c | 69 +-
src/fr-command-zoo.c | 32 +-
src/fr-command.c | 3716 +++++++++++++++++++++++++++++++++------
src/fr-command.h | 300 +---
src/fr-error.c | 75 +-
src/fr-error.h | 36 +-
src/fr-init.c | 178 +-
src/fr-init.h | 12 +-
src/fr-proc-error.c | 55 -
src/fr-proc-error.h | 31 -
src/fr-process.c | 680 ++++----
src/fr-process.h | 112 +-
src/fr-window.c | 1721 +++++++++++-------
src/fr-window.h | 385 ++--
src/glib-utils.c | 23 +
src/glib-utils.h | 5 +
src/main.c | 8 +-
src/rar-utils.c | 2 +-
src/typedefs.h | 54 +-
46 files changed, 7627 insertions(+), 6011 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 7c6804f..3dbd816 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -136,8 +136,6 @@ COMMON_SOURCES = \
fr-list-model.h \
fr-stock.c \
fr-stock.h \
- fr-proc-error.c \
- fr-proc-error.h \
fr-process.c \
fr-process.h \
fr-window.c \
diff --git a/src/actions.c b/src/actions.c
index ab21347..2142439 100644
--- a/src/actions.c
+++ b/src/actions.c
@@ -267,13 +267,15 @@ new_file_response_cb (GtkWidget *w,
int response,
DlgNewData *data)
{
- char *path;
+ char *uri;
if ((response == GTK_RESPONSE_CANCEL) || (response == GTK_RESPONSE_DELETE_EVENT)) {
- fr_archive_action_completed (data->window->archive,
+ /* FIXME: libarchive
+ fr_archive_action_completed (data->window->archive,
FR_ACTION_CREATING_NEW_ARCHIVE,
FR_PROC_ERROR_STOPPED,
NULL);
+ */
gtk_widget_destroy (data->dialog);
return;
}
@@ -283,10 +285,10 @@ new_file_response_cb (GtkWidget *w,
return;
}
- path = get_archive_filename_from_selector (data);
- if (path != NULL) {
- new_archive (data, path);
- g_free (path);
+ uri = get_archive_filename_from_selector (data);
+ if (uri != NULL) {
+ new_archive (data, uri);
+ g_free (uri);
}
}
diff --git a/src/dlg-batch-add.c b/src/dlg-batch-add.c
index 4e73295..1b787c0 100644
--- a/src/dlg-batch-add.c
+++ b/src/dlg-batch-add.c
@@ -93,20 +93,20 @@ set_archive_options (DialogData *data)
int idx;
idx = gtk_combo_box_get_active (GTK_COMBO_BOX (data->archive_type_combo_box));
- if (mime_type_desc[data->supported_types[idx]].capabilities & FR_COMMAND_CAN_ENCRYPT) {
+ if (mime_type_desc[data->supported_types[idx]].capabilities & FR_ARCHIVE_CAN_ENCRYPT) {
const char *pwd;
pwd = gtk_entry_get_text (GTK_ENTRY (GET_WIDGET ("a_password_entry")));
if (pwd != NULL) {
if (strcmp (pwd, "") != 0) {
fr_window_set_password (data->window, pwd);
- if (mime_type_desc[data->supported_types[idx]].capabilities & FR_COMMAND_CAN_ENCRYPT_HEADER)
+ if (mime_type_desc[data->supported_types[idx]].capabilities & FR_ARCHIVE_CAN_ENCRYPT_HEADER)
fr_window_set_encrypt_header (data->window, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("a_encrypt_header_checkbutton"))));
}
}
}
- if ((mime_type_desc[data->supported_types[idx]].capabilities & FR_COMMAND_CAN_CREATE_VOLUMES)
+ if ((mime_type_desc[data->supported_types[idx]].capabilities & FR_ARCHIVE_CAN_CREATE_VOLUMES)
&& gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("a_volume_checkbutton"))))
{
double value;
@@ -364,15 +364,15 @@ update_sensitivity_for_mime_type (DialogData *data,
if (strcmp (mime_type_desc[i].mime_type, mime_type) == 0) {
gboolean sensitive;
- sensitive = mime_type_desc[i].capabilities & FR_COMMAND_CAN_ENCRYPT;
+ sensitive = mime_type_desc[i].capabilities & FR_ARCHIVE_CAN_ENCRYPT;
gtk_widget_set_sensitive (GET_WIDGET ("a_password_entry"), sensitive);
gtk_widget_set_sensitive (GET_WIDGET ("a_password_label"), sensitive);
- sensitive = mime_type_desc[i].capabilities & FR_COMMAND_CAN_ENCRYPT_HEADER;
+ sensitive = mime_type_desc[i].capabilities & FR_ARCHIVE_CAN_ENCRYPT_HEADER;
gtk_widget_set_sensitive (GET_WIDGET ("a_encrypt_header_checkbutton"), sensitive);
gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (GET_WIDGET ("a_encrypt_header_checkbutton")), ! sensitive);
- sensitive = mime_type_desc[i].capabilities & FR_COMMAND_CAN_CREATE_VOLUMES;
+ sensitive = mime_type_desc[i].capabilities & FR_ARCHIVE_CAN_CREATE_VOLUMES;
gtk_widget_set_sensitive (GET_WIDGET ("a_volume_box"), sensitive);
break;
diff --git a/src/dlg-new.c b/src/dlg-new.c
index d64fae6..5469a30 100644
--- a/src/dlg-new.c
+++ b/src/dlg-new.c
@@ -81,14 +81,14 @@ update_sensitivity_for_ext (DlgNewData *data,
for (i = 0; mime_type_desc[i].mime_type != NULL; i++) {
if (strcmp (mime_type_desc[i].mime_type, mime_type) == 0) {
- data->can_encrypt = mime_type_desc[i].capabilities & FR_COMMAND_CAN_ENCRYPT;
+ data->can_encrypt = mime_type_desc[i].capabilities & FR_ARCHIVE_CAN_ENCRYPT;
gtk_widget_set_sensitive (data->n_password_entry, data->can_encrypt);
gtk_widget_set_sensitive (data->n_password_label, data->can_encrypt);
- data->can_encrypt_header = mime_type_desc[i].capabilities & FR_COMMAND_CAN_ENCRYPT_HEADER;
+ data->can_encrypt_header = mime_type_desc[i].capabilities & FR_ARCHIVE_CAN_ENCRYPT_HEADER;
gtk_widget_set_sensitive (data->n_encrypt_header_checkbutton, data->can_encrypt_header);
- data->can_create_volumes = mime_type_desc[i].capabilities & FR_COMMAND_CAN_CREATE_VOLUMES;
+ data->can_create_volumes = mime_type_desc[i].capabilities & FR_ARCHIVE_CAN_CREATE_VOLUMES;
gtk_widget_set_sensitive (data->n_volume_box, data->can_create_volumes);
break;
@@ -454,7 +454,7 @@ dlg_new_data_get_password (DlgNewData *data)
if (idx < 0)
return NULL;
- if (mime_type_desc[idx].capabilities & FR_COMMAND_CAN_ENCRYPT)
+ if (mime_type_desc[idx].capabilities & FR_ARCHIVE_CAN_ENCRYPT)
password = (char*) gtk_entry_get_text (GTK_ENTRY (data->n_password_entry));
return password;
@@ -471,11 +471,11 @@ dlg_new_data_get_encrypt_header (DlgNewData *data)
if (idx < 0)
return FALSE;
- if (mime_type_desc[idx].capabilities & FR_COMMAND_CAN_ENCRYPT) {
+ if (mime_type_desc[idx].capabilities & FR_ARCHIVE_CAN_ENCRYPT) {
const char *password = gtk_entry_get_text (GTK_ENTRY (data->n_password_entry));
if (password != NULL) {
if (strcmp (password, "") != 0) {
- if (mime_type_desc[idx].capabilities & FR_COMMAND_CAN_ENCRYPT_HEADER)
+ if (mime_type_desc[idx].capabilities & FR_ARCHIVE_CAN_ENCRYPT_HEADER)
encrypt_header = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->n_encrypt_header_checkbutton));
}
}
@@ -495,7 +495,7 @@ dlg_new_data_get_volume_size (DlgNewData *data)
if (idx < 0)
return 0;
- if ((mime_type_desc[idx].capabilities & FR_COMMAND_CAN_CREATE_VOLUMES)
+ if ((mime_type_desc[idx].capabilities & FR_ARCHIVE_CAN_CREATE_VOLUMES)
&& gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->n_volume_checkbutton)))
{
double value;
diff --git a/src/dlg-package-installer.c b/src/dlg-package-installer.c
index ecc4f55..b109544 100644
--- a/src/dlg-package-installer.c
+++ b/src/dlg-package-installer.c
@@ -47,9 +47,9 @@ installer_data_free (InstallerData *idata)
static void
-package_installer_terminated (InstallerData *idata,
- FrProcErrorType error_type,
- const char *error_message)
+package_installer_terminated (InstallerData *idata,
+ FrErrorType error_type,
+ const char *error_message)
{
GdkWindow *window;
@@ -57,14 +57,16 @@ package_installer_terminated (InstallerData *idata,
if (window != NULL)
gdk_window_set_cursor (window, NULL);
- if (error_type != FR_PROC_ERROR_NONE) {
+ if (error_type != FR_ERROR_NONE) {
+ /* FIXME: libarchive
fr_archive_action_completed (idata->archive,
idata->action,
error_type,
error_message);
+ */
}
else {
- update_registered_commands_capabilities ();
+ update_registered_archives_capabilities ();
if (fr_window_is_batch_mode (idata->window))
fr_window_resume_batch (idata->window);
else
@@ -87,7 +89,7 @@ packagekit_install_package_names_ready_cb (GObject *source_object,
GDBusProxy *proxy;
GVariant *values;
GError *error = NULL;
- FrProcErrorType error_type = FR_PROC_ERROR_NONE;
+ FrErrorType error_type = FR_ERROR_NONE;
char *error_message = NULL;
proxy = G_DBUS_PROXY (source_object);
@@ -98,11 +100,11 @@ packagekit_install_package_names_ready_cb (GObject *source_object,
&& (error->message != NULL)
&& (strstr (error->message, "org.freedesktop.Packagekit.Modify.Cancelled") != NULL)))
{
- error_type = FR_PROC_ERROR_STOPPED;
+ error_type = FR_ERROR_STOPPED;
error_message = NULL;
}
else {
- error_type = FR_PROC_ERROR_GENERIC;
+ error_type = FR_ERROR_GENERIC;
error_message = g_strdup_printf ("%s\n%s",
_("There was an internal error trying to search for applications:"),
error->message);
@@ -219,7 +221,7 @@ install_packages (InstallerData *idata)
message = g_strdup_printf ("%s\n%s",
_("There was an internal error trying to search for applications:"),
error->message);
- package_installer_terminated (idata, FR_PROC_ERROR_GENERIC, message);
+ package_installer_terminated (idata, FR_ERROR_GENERIC, message);
g_clear_error (&error);
}
@@ -254,28 +256,28 @@ dlg_package_installer (FrWindow *window,
FrAction action)
{
InstallerData *idata;
- GType command_type;
- FrCommand *command;
+ GType archive_type;
+ FrArchive *preferred_archive;
idata = g_new0 (InstallerData, 1);
idata->window = g_object_ref (window);
idata->archive = g_object_ref (archive);
idata->action = action;
- command_type = get_preferred_command_for_mime_type (idata->archive->content_type, FR_COMMAND_CAN_READ_WRITE);
- if (command_type == 0)
- command_type = get_preferred_command_for_mime_type (idata->archive->content_type, FR_COMMAND_CAN_READ);
- if (command_type == 0) {
- package_installer_terminated (idata, FR_PROC_ERROR_GENERIC, _("Archive type not supported."));
+ archive_type = get_preferred_archive_for_mime_type (idata->archive->mime_type, FR_ARCHIVE_CAN_READ_WRITE);
+ if (archive_type == 0)
+ archive_type = get_preferred_archive_for_mime_type (idata->archive->mime_type, FR_ARCHIVE_CAN_READ);
+ if (archive_type == 0) {
+ package_installer_terminated (idata, FR_ERROR_GENERIC, _("Archive type not supported."));
return;
}
- command = g_object_new (command_type, 0);
- idata->packages = fr_command_get_packages (command, idata->archive->content_type);
- g_object_unref (command);
+ preferred_archive = g_object_new (archive_type, 0);
+ idata->packages = fr_archive_get_packages (preferred_archive, idata->archive->mime_type);
+ g_object_unref (preferred_archive);
if (idata->packages == NULL) {
- package_installer_terminated (idata, FR_PROC_ERROR_GENERIC, _("Archive type not supported."));
+ package_installer_terminated (idata, FR_ERROR_GENERIC, _("Archive type not supported."));
return;
}
@@ -286,7 +288,7 @@ dlg_package_installer (FrWindow *window,
GtkWidget *dialog;
secondary_text = g_strdup_printf (_("There is no command installed for %s files.\nDo you want to search for a command to open this file?"),
- g_content_type_get_description (idata->archive->content_type));
+ g_content_type_get_description (idata->archive->mime_type));
dialog = _gtk_message_dialog_new (GTK_WINDOW (idata->window),
GTK_DIALOG_MODAL,
GTK_STOCK_DIALOG_ERROR,
@@ -303,7 +305,7 @@ dlg_package_installer (FrWindow *window,
#else /* ! ENABLE_PACKAGEKIT */
- package_installer_terminated (idata, FR_PROC_ERROR_GENERIC, _("Archive type not supported."));
+ package_installer_terminated (idata, FR_ERROR_GENERIC, _("Archive type not supported."));
#endif /* ENABLE_PACKAGEKIT */
}
diff --git a/src/dlg-prop.c b/src/dlg-prop.c
index addc2d2..64e33dc 100644
--- a/src/dlg-prop.c
+++ b/src/dlg-prop.c
@@ -112,8 +112,8 @@ dlg_prop (FrWindow *window)
if (fr_window_archive_is_present (window)) {
int i;
- for (i = 0; i < window->archive->command->files->len; i++) {
- FileData *fd = g_ptr_array_index (window->archive->command->files, i);
+ for (i = 0; i < window->archive->files->len; i++) {
+ FileData *fd = g_ptr_array_index (window->archive->files, i);
uncompressed_size += fd->size;
}
}
@@ -138,7 +138,7 @@ dlg_prop (FrWindow *window)
/**/
label = _gtk_builder_get_widget (data->builder, "p_files_label");
- s = g_strdup_printf ("%d", window->archive->command->n_regular_files);
+ s = g_strdup_printf ("%d", window->archive->n_regular_files);
gtk_label_set_text (GTK_LABEL (label), s);
g_free (s);
diff --git a/src/fr-archive.c b/src/fr-archive.c
index 68bc771..9d3541a 100644
--- a/src/fr-archive.c
+++ b/src/fr-archive.c
@@ -25,7 +25,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/param.h>
-
#include <glib.h>
#include <glib/gi18n.h>
#include <gio/gio.h>
@@ -35,9 +34,9 @@
#include "file-data.h"
#include "fr-archive.h"
#include "fr-command.h"
+#include "fr-enum-types.h"
#include "fr-error.h"
#include "fr-marshal.h"
-#include "fr-proc-error.h"
#include "fr-process.h"
#include "fr-init.h"
@@ -45,121 +44,42 @@
#include <magic.h>
#endif
-#ifndef NCARGS
-#define NCARGS _POSIX_ARG_MAX
-#endif
+#define FILES_ARRAY_INITIAL_SIZE 256
-/* -- DroppedItemsData -- */
+char *action_names[] = { "NONE",
+ "CREATING_NEW_ARCHIVE",
+ "LOADING_ARCHIVE",
+ "LISTING_CONTENT",
+ "DELETING_FILES",
+ "TESTING_ARCHIVE",
+ "GETTING_FILE_LIST",
+ "COPYING_FILES_FROM_REMOTE",
+ "ADDING_FILES",
+ "EXTRACTING_FILES",
+ "COPYING_FILES_TO_REMOTE",
+ "CREATING_ARCHIVE",
+ "SAVING_REMOTE_ARCHIVE" };
-typedef struct {
- FrArchive *archive;
- GList *item_list;
- char *base_dir;
- char *dest_dir;
- gboolean update;
- char *password;
- gboolean encrypt_header;
- FrCompression compression;
- guint volume_size;
-} DroppedItemsData;
-
-
-static DroppedItemsData *
-dropped_items_data_new (FrArchive *archive,
- GList *item_list,
- const char *base_dir,
- const char *dest_dir,
- gboolean update,
- const char *password,
- gboolean encrypt_header,
- FrCompression compression,
- guint volume_size)
-{
- DroppedItemsData *data;
-
- data = g_new0 (DroppedItemsData, 1);
- data->archive = archive;
- data->item_list = _g_string_list_dup (item_list);
- if (base_dir != NULL)
- data->base_dir = g_strdup (base_dir);
- if (dest_dir != NULL)
- data->dest_dir = g_strdup (dest_dir);
- data->update = update;
- if (password != NULL)
- data->password = g_strdup (password);
- data->encrypt_header = encrypt_header;
- data->compression = compression;
- data->volume_size = volume_size;
-
- return data;
-}
+struct _FrArchivePrivate {
+ /* propeties */
-static void
-dropped_items_data_free (DroppedItemsData *data)
-{
- if (data == NULL)
- return;
- _g_string_list_free (data->item_list);
- g_free (data->base_dir);
- g_free (data->dest_dir);
- g_free (data->password);
- g_free (data);
-}
+ GFile *file;
+ FrArchiveCaps capabilities;
+ /* internal */
-struct _FrArchivePrivData {
- FakeLoadFunc fake_load_func; /* If returns TRUE, archives are not read when
- * fr_archive_load is invoked, used
- * in batch mode. */
- gpointer fake_load_data;
- 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;
+ GCancellable *cancellable;
+ gboolean creating_archive;
+ char *extraction_destination;
+ gboolean have_write_permissions; /* true if we have the
+ * permissions to write the
+ * file. */
};
-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);
- _g_string_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)
@@ -167,11 +87,11 @@ xfer_data_free (XferData *data)
#define NO_DOT_FILES (FALSE)
#define IGNORE_CASE (FALSE)
#define LIST_LENGTH_TO_USE_FILE 10 /* FIXME: find a good value */
+#define FILE_ARRAY_INITIAL_SIZE 256
enum {
START,
- DONE,
PROGRESS,
MESSAGE,
STOPPABLE,
@@ -186,84 +106,117 @@ static guint fr_archive_signals[LAST_SIGNAL] = { 0 };
G_DEFINE_TYPE (FrArchive, fr_archive, G_TYPE_OBJECT)
-static GFile *
-get_local_copy_for_file (GFile *remote_file)
-{
- char *temp_dir;
- GFile *local_copy = NULL;
-
- temp_dir = _g_path_get_temp_work_dir (NULL);
- if (temp_dir != NULL) {
- char *archive_name;
- char *local_path;
+/* Properties */
+enum {
+ PROP_0,
+ PROP_FILE,
+ PROP_MIME_TYPE,
+ PROP_PASSWORD,
+ PROP_ENCRYPT_HEADER,
+ PROP_COMPRESSION,
+ PROP_VOLUME_SIZE
+};
- 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);
+static void
+_fr_archive_set_file (FrArchive *self,
+ GFile *file)
+{
+ if (self->priv->file != NULL) {
+ g_object_unref (self->priv->file);
+ self->priv->file = NULL;
}
- g_free (temp_dir);
+ if (file != NULL)
+ self->priv->file = g_object_ref (file);
- return local_copy;
+ self->mime_type = NULL;
+
+ g_object_notify (G_OBJECT (self), "file");
}
static void
-fr_archive_set_uri (FrArchive *archive,
- const char *uri)
+_fr_archive_set_uri (FrArchive *self,
+ 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);
- }
+ GFile *file;
- 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);
- }
+ file = (uri != NULL) ? g_file_new_for_uri (uri) : NULL;
+ _fr_archive_set_file (self, file);
- g_object_unref (temp_folder);
- }
+ _g_object_unref (file);
+}
- 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)
- return;
+static void
+fr_archive_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ FrArchive *self;
- 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);
+ self = FR_ARCHIVE (object);
+
+ switch (property_id) {
+ case PROP_FILE:
+ _fr_archive_set_file (self, g_value_get_object (value));
+ break;
+ case PROP_MIME_TYPE:
+ fr_archive_set_mime_type (self, g_value_get_string (value));
+ break;
+ case PROP_PASSWORD:
+ g_free (self->password);
+ self->password = g_strdup (g_value_get_string (value));
+ break;
+ case PROP_ENCRYPT_HEADER:
+ self->encrypt_header = g_value_get_boolean (value);
+ break;
+ case PROP_COMPRESSION:
+ self->compression = g_value_get_enum (value);
+ break;
+ case PROP_VOLUME_SIZE:
+ self->volume_size = g_value_get_uint (value);
+ break;
+ default:
+ break;
+ }
}
static void
-fr_archive_remove_temp_work_dir (FrArchive *archive)
+fr_archive_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
{
- if (archive->priv->temp_dir == NULL)
- return;
- _g_path_remove_directory (archive->priv->temp_dir);
- g_free (archive->priv->temp_dir);
- archive->priv->temp_dir = NULL;
+ FrArchive *self;
+
+ self = FR_ARCHIVE (object);
+
+ switch (property_id) {
+ case PROP_FILE:
+ g_value_set_object (value, self->priv->file);
+ break;
+ case PROP_MIME_TYPE:
+ g_value_set_static_string (value, self->mime_type);
+ break;
+ case PROP_PASSWORD:
+ g_value_set_string (value, self->password);
+ break;
+ case PROP_ENCRYPT_HEADER:
+ g_value_set_boolean (value, self->encrypt_header);
+ break;
+ case PROP_COMPRESSION:
+ g_value_set_enum (value, self->compression);
+ break;
+ case PROP_VOLUME_SIZE:
+ g_value_set_uint (value, self->volume_size);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
}
@@ -277,18 +230,8 @@ fr_archive_finalize (GObject *object)
archive = FR_ARCHIVE (object);
- fr_archive_set_uri (archive, NULL);
- fr_archive_remove_temp_work_dir (archive);
- if (archive->command != NULL)
- g_object_unref (archive->command);
- g_object_unref (archive->process);
- if (archive->priv->dropped_items_data != NULL) {
- 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);
+ _fr_archive_set_uri (archive, NULL);
+ g_object_unref (archive->priv->cancellable);
/* Chain up */
@@ -297,46 +240,137 @@ fr_archive_finalize (GObject *object)
}
+const char **void_mime_types = { NULL };
+
+
+static const char **
+fr_archive_base_get_mime_types (FrArchive *self)
+{
+ return void_mime_types;
+}
+
+
+static FrArchiveCap
+fr_archive_base_get_capabilities (FrArchive *self,
+ const char *mime_type,
+ gboolean check_command)
+{
+ return FR_ARCHIVE_CAN_DO_NOTHING;
+}
+
+
+static void
+fr_archive_base_set_mime_type (FrArchive *self,
+ const char *mime_type)
+{
+ self->mime_type = _g_str_get_static (mime_type);
+ fr_archive_update_capabilities (self);
+}
+
+
+static const char *
+fr_archive_base_get_packages (FrArchive *self,
+ const char *mime_type)
+{
+ return NULL;
+}
+
+
static void
-fr_archive_class_init (FrArchiveClass *class)
+fr_archive_class_init (FrArchiveClass *klass)
{
GObjectClass *gobject_class;
- fr_archive_parent_class = g_type_class_peek_parent (class);
+ fr_archive_parent_class = g_type_class_peek_parent (klass);
+ g_type_class_add_private (klass, sizeof (FrArchivePrivate));
- gobject_class = G_OBJECT_CLASS (class);
+ gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = fr_archive_finalize;
-
- class->start = NULL;
- class->done = NULL;
- class->progress = NULL;
- class->message = NULL;
- class->working_archive = NULL;
+ gobject_class->set_property = fr_archive_set_property;
+ gobject_class->get_property = fr_archive_get_property;
+
+ klass->start = NULL;
+ klass->progress = NULL;
+ klass->message = NULL;
+ klass->stoppable = NULL;
+ klass->working_archive = NULL;
+
+ klass->get_mime_types = fr_archive_base_get_mime_types;
+ klass->get_capabilities = fr_archive_base_get_capabilities;
+ klass->set_mime_type = fr_archive_base_set_mime_type;
+ klass->get_packages = fr_archive_base_get_packages;
+ klass->load = NULL;
+ klass->add_files = NULL;
+ klass->extract_files = NULL;
+ klass->remove_files = NULL;
+ klass->test_integrity = NULL;
+ klass->rename = NULL;
+ klass->paste_clipboard = NULL;
+ klass->add_dropped_items = NULL;
+ klass->update_open_files = NULL;
+
+ /* properties */
+
+ g_object_class_install_property (gobject_class,
+ PROP_FILE,
+ g_param_spec_object ("file",
+ "File",
+ "The archive file",
+ G_TYPE_FILE,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class,
+ PROP_MIME_TYPE,
+ g_param_spec_string ("mime-type",
+ "Content type",
+ "A mime-type that describes the content type",
+ NULL,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class,
+ PROP_PASSWORD,
+ g_param_spec_string ("password",
+ "Password",
+ "The archive password",
+ NULL,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class,
+ PROP_ENCRYPT_HEADER,
+ g_param_spec_boolean ("encrypt-header",
+ "Encrypt header",
+ "Whether to encrypt the archive header when creating the archive",
+ FALSE,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class,
+ PROP_COMPRESSION,
+ g_param_spec_enum ("compression",
+ "Compression type",
+ "The compression type to use when creating the archive",
+ FR_TYPE_COMPRESSION,
+ FR_COMPRESSION_NORMAL,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class,
+ PROP_VOLUME_SIZE,
+ g_param_spec_uint ("volume-size",
+ "Volume size",
+ "The size of each volume or 0 to not use volumes",
+ 0L,
+ G_MAXUINT,
+ 0,
+ G_PARAM_READWRITE));
/* signals */
fr_archive_signals[START] =
g_signal_new ("start",
- G_TYPE_FROM_CLASS (class),
+ G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (FrArchiveClass, start),
NULL, NULL,
fr_marshal_VOID__INT,
G_TYPE_NONE,
1, G_TYPE_INT);
- fr_archive_signals[DONE] =
- g_signal_new ("done",
- G_TYPE_FROM_CLASS (class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (FrArchiveClass, done),
- NULL, NULL,
- fr_marshal_VOID__INT_BOXED,
- G_TYPE_NONE, 2,
- G_TYPE_INT,
- FR_TYPE_PROC_ERROR);
fr_archive_signals[PROGRESS] =
g_signal_new ("progress",
- G_TYPE_FROM_CLASS (class),
+ G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (FrArchiveClass, progress),
NULL, NULL,
@@ -345,7 +379,7 @@ fr_archive_class_init (FrArchiveClass *class)
G_TYPE_DOUBLE);
fr_archive_signals[MESSAGE] =
g_signal_new ("message",
- G_TYPE_FROM_CLASS (class),
+ G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (FrArchiveClass, message),
NULL, NULL,
@@ -354,7 +388,7 @@ fr_archive_class_init (FrArchiveClass *class)
G_TYPE_STRING);
fr_archive_signals[STOPPABLE] =
g_signal_new ("stoppable",
- G_TYPE_FROM_CLASS (class),
+ G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (FrArchiveClass, stoppable),
NULL, NULL,
@@ -363,7 +397,7 @@ fr_archive_class_init (FrArchiveClass *class)
1, G_TYPE_BOOLEAN);
fr_archive_signals[WORKING_ARCHIVE] =
g_signal_new ("working_archive",
- G_TYPE_FROM_CLASS (class),
+ G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (FrArchiveClass, working_archive),
NULL, NULL,
@@ -373,152 +407,238 @@ fr_archive_class_init (FrArchiveClass *class)
}
+static void
+fr_archive_init (FrArchive *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, FR_TYPE_ARCHIVE, FrArchivePrivate);
+
+ self->mime_type = NULL;
+ self->files = g_ptr_array_sized_new (FILES_ARRAY_INITIAL_SIZE);
+ self->n_regular_files = 0;
+ self->password = NULL;
+ self->encrypt_header = FALSE;
+ self->compression = FR_COMPRESSION_NORMAL;
+ self->multi_volume = FALSE;
+ self->volume_size = 0;
+ self->read_only = FALSE;
+ self->action = FR_ACTION_NONE;
+ self->extract_here = FALSE;
+ self->n_file = 0;
+ self->n_files = 0;
+
+ self->propAddCanUpdate = FALSE;
+ self->propAddCanReplace = FALSE;
+ self->propAddCanStoreFolders = FALSE;
+ self->propExtractCanAvoidOverwrite = FALSE;
+ self->propExtractCanSkipOlder = FALSE;
+ self->propExtractCanJunkPaths = FALSE;
+ self->propPassword = FALSE;
+ self->propTest = FALSE;
+ self->propCanExtractAll = TRUE;
+ self->propCanDeleteNonEmptyFolders = TRUE;
+ self->propCanExtractNonEmptyFolders = TRUE;
+ self->propListFromFile = FALSE;
+
+ self->priv->file = NULL;
+ self->priv->cancellable = g_cancellable_new ();
+ self->priv->creating_archive = FALSE;
+ self->priv->extraction_destination = NULL;
+ self->priv->have_write_permissions = FALSE;
+}
+
+
+GFile *
+fr_archive_get_file (FrArchive *self)
+{
+ return self->priv->file;
+}
+
+
+gboolean
+fr_archive_is_capable_of (FrArchive *self,
+ FrArchiveCaps requested_capabilities)
+{
+ return (((self->priv->capabilities ^ requested_capabilities) & requested_capabilities) == 0);
+}
+
+
+const char **
+fr_archive_get_mime_types (FrArchive *self)
+{
+ return FR_ARCHIVE_GET_CLASS (G_OBJECT (self))->get_mime_types (self);
+}
+
+
void
-fr_archive_stoppable (FrArchive *archive,
- gboolean stoppable)
+fr_archive_update_capabilities (FrArchive *self)
{
- g_signal_emit (G_OBJECT (archive),
- fr_archive_signals[STOPPABLE],
- 0,
- stoppable);
+ self->priv->capabilities = fr_archive_get_capabilities (self, self->mime_type, TRUE);
+ /* FIXME: check if this is correct */
+ self->read_only = ! fr_archive_is_capable_of (self, FR_ARCHIVE_CAN_WRITE);
+}
+
+
+FrArchiveCap
+fr_archive_get_capabilities (FrArchive *self,
+ const char *mime_type,
+ gboolean check_command)
+{
+ return FR_ARCHIVE_GET_CLASS (G_OBJECT (self))->get_capabilities (self, mime_type, check_command);
}
void
-fr_archive_stop (FrArchive *archive)
+fr_archive_set_mime_type (FrArchive *self,
+ const char *mime_type)
{
- if (archive->process != NULL) {
- fr_process_stop (archive->process);
- return;
- }
+ FR_ARCHIVE_GET_CLASS (G_OBJECT (self))->set_mime_type (self, mime_type);
+}
+
- if (! g_cancellable_is_cancelled (archive->priv->cancellable))
- g_cancellable_cancel (archive->priv->cancellable);
+const char *
+fr_archive_get_packages (FrArchive *self,
+ const char *mime_type)
+{
+ return FR_ARCHIVE_GET_CLASS (G_OBJECT (self))->get_packages (self, mime_type);
}
void
-fr_archive_action_completed (FrArchive *archive,
- FrAction action,
- FrProcErrorType error_type,
- const char *error_details)
+fr_archive_set_stoppable (FrArchive *archive,
+ gboolean stoppable)
{
- archive->error.type = error_type;
- archive->error.status = 0;
- g_clear_error (&archive->error.gerror);
- if (error_details != NULL)
- archive->error.gerror = g_error_new_literal (fr_error_quark (),
- 0,
- error_details);
g_signal_emit (G_OBJECT (archive),
- fr_archive_signals[DONE],
+ fr_archive_signals[STOPPABLE],
0,
- action,
- &archive->error);
+ stoppable);
}
-static gboolean
-archive_sticky_only_cb (FrProcess *process,
- FrArchive *archive)
+/* -- fr_archive_new_for_creating -- */
+
+
+static const char *
+get_mime_type_from_filename (GFile *file)
{
- fr_archive_stoppable (archive, FALSE);
- return TRUE;
+ const char *mime_type = NULL;
+ char *uri;
+
+ if (file == NULL)
+ return NULL;
+
+ uri = g_file_get_uri (file);
+ mime_type = get_mime_type_from_extension (_g_filename_get_extension (uri));
+
+ g_free (uri);
+
+ return mime_type;
}
-static void
-fr_archive_init (FrArchive *archive)
+static FrArchive *
+create_archive_for_mime_type (GType archive_type,
+ GFile *file,
+ const char *mime_type,
+ FrArchiveCaps requested_capabilities)
{
- 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;
+ FrArchive *archive;
- archive->priv = g_new0 (FrArchivePrivData, 1);
- archive->priv->fake_load_func = NULL;
- archive->priv->fake_load_data = NULL;
+ if (archive_type == 0)
+ return NULL;
- archive->priv->extraction_destination = NULL;
- archive->priv->temp_extraction_dir = NULL;
- archive->priv->cancellable = g_cancellable_new ();
-
- archive->process = fr_process_new ();
- g_signal_connect (G_OBJECT (archive->process),
- "sticky_only",
- G_CALLBACK (archive_sticky_only_cb),
- archive);
+ archive = g_object_new (archive_type,
+ "file", file,
+ "mime-type", mime_type,
+ NULL);
+
+ if (! fr_archive_is_capable_of (archive, requested_capabilities)) {
+ g_object_unref (archive);
+ return NULL;
+ }
+
+ return archive;
}
FrArchive *
-fr_archive_new (void)
+fr_archive_create (GFile *file)
{
- return FR_ARCHIVE (g_object_new (FR_TYPE_ARCHIVE, NULL));
-}
+ const char *mime_type;
+ GType archive_type;
+ FrArchive *archive;
+ GFile *parent;
+ mime_type = get_mime_type_from_filename (file);
+ archive_type = get_archive_type_from_mime_type (mime_type, FR_ARCHIVE_CAN_WRITE);
-static const char *
-get_mime_type_from_content (GFile *file)
-{
- GFileInfo *info;
- GError *err = NULL;
- const char *content_type = NULL;
-
- info = g_file_query_info (file,
- G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
- 0, NULL, &err);
- if (info == NULL) {
- g_warning ("could not get content type: %s", err->message);
- g_clear_error (&err);
- }
- else {
- content_type = _g_str_get_static (g_file_info_get_content_type (info));
- g_object_unref (info);
- }
+ archive = create_archive_for_mime_type (archive_type,
+ file,
+ mime_type,
+ FR_ARCHIVE_CAN_WRITE);
- return content_type;
+ parent = g_file_get_parent (file);
+ archive->priv->have_write_permissions = _g_file_check_permissions (parent, W_OK);
+ archive->read_only = ! fr_archive_is_capable_of (archive, FR_ARCHIVE_CAN_WRITE) || ! archive->priv->have_write_permissions;
+
+ g_object_unref (parent);
+
+ return archive;
}
-static const char *
-get_mime_type_from_magic_numbers (GFile *file)
+/* -- fr_archive_open -- */
+
+
+#define BUFFER_SIZE_FOR_PRELOAD 32
+
+
+typedef struct {
+ GFile *file;
+ GCancellable *cancellable;
+ GSimpleAsyncResult *result;
+ char *buffer;
+ gsize buffer_size;
+ FrArchive *archive;
+} OpenData;
+
+
+static void
+load_data_free (OpenData *open_data)
{
-#if ENABLE_MAGIC
- static magic_t magic = NULL;
+ g_object_unref (open_data->file);
+ _g_object_unref (open_data->cancellable);
+ _g_object_unref (open_data->result);
+ _g_object_unref (open_data->archive);
+ g_free (open_data->buffer);
+ g_free (open_data);
+}
- if (! magic) {
- magic = magic_open (MAGIC_MIME_TYPE);
- if (magic)
- magic_load (magic, NULL);
- else
- g_warning ("unable to open magic database");
- }
- if (magic) {
- const char * mime_type = NULL;
- char * filepath = g_file_get_path (file);
+static void
+load_data_complete_with_error (OpenData *load_data,
+ GError *error)
+{
+ GSimpleAsyncResult *result;
- if (filepath) {
- mime_type = magic_file (magic, filepath);
- g_free (filepath);
- }
+ result = g_object_ref (load_data->result);
+ g_simple_async_result_set_from_error (result, error);
+ g_simple_async_result_complete_in_idle (result);
+
+ g_object_unref (result);
+}
- if (mime_type)
- return mime_type;
- g_warning ("unable to detect filetype from magic: %s",
- magic_error (magic));
- }
-#else
+static const char *
+get_mime_type_from_magic_numbers (char *buffer,
+ gsize buffer_size)
+{
static const struct magic {
const unsigned int off;
const unsigned int len;
const char * const id;
const char * const mime_type;
- } magic_ids [] = {
+ }
+ magic_ids [] = {
/* magic ids taken from magic/Magdir/archive from the file-4.21 tarball */
{ 0, 6, "7z\274\257\047\034", "application/x-7z-compressed" },
{ 7, 7, "**ACE**", "application/x-ace" },
@@ -536,76 +656,27 @@ get_mime_type_from_magic_numbers (GFile *file)
{ 0, 4, "LRZI", "application/x-lrzip" },
};
- char buffer[32];
int i;
- if (! g_load_file_in_buffer (file, buffer, sizeof (buffer), NULL))
- return NULL;
-
for (i = 0; i < G_N_ELEMENTS (magic_ids); i++) {
const struct magic * const magic = &magic_ids[i];
- if (sizeof (buffer) < (magic->off + magic->len))
- g_warning ("buffer underrun for mime type '%s' magic",
- magic->mime_type);
+ if ((magic->off + magic->len) > buffer_size)
+ g_warning ("buffer underrun for mime-type '%s' magic", magic->mime_type);
else if (! memcmp (buffer + magic->off, magic->id, magic->len))
return magic->mime_type;
}
-#endif
return NULL;
}
-static const char *
-get_mime_type_from_filename (GFile *file)
-{
- const char *mime_type = NULL;
- char *filename;
-
- if (file == NULL)
- return NULL;
-
- filename = g_file_get_path (file);
- mime_type = get_mime_type_from_extension (_g_filename_get_extension (filename));
- g_free (filename);
-
- return mime_type;
-}
-
-
-static gboolean
-create_command_from_type (FrArchive *archive,
- const char *mime_type,
- GType command_type,
- FrCommandCaps requested_capabilities)
-{
- if (command_type == 0)
- return FALSE;
-
- archive->command = FR_COMMAND (g_object_new (command_type,
- "process", archive->process,
- "mime-type", mime_type,
- NULL));
-
- if (! fr_command_is_capable_of (archive->command, requested_capabilities)) {
- g_object_unref (archive->command);
- archive->command = NULL;
- archive->is_compressed_file = FALSE;
- }
- else
- archive->is_compressed_file = ! fr_command_is_capable_of (archive->command, FR_COMMAND_CAN_ARCHIVE_MANY_FILES);
-
- return (archive->command != NULL);
-}
-
-
-static gboolean
-create_command_to_load_archive (FrArchive *archive,
+static FrArchive *
+create_archive_to_load_archive (GFile *file,
const char *mime_type)
{
- FrCommandCaps requested_capabilities = FR_COMMAND_CAN_DO_NOTHING;
- GType command_type;
+ FrArchiveCaps requested_capabilities = FR_ARCHIVE_CAN_DO_NOTHING;
+ GType archive_type;
if (mime_type == NULL)
return FALSE;
@@ -614,2631 +685,613 @@ create_command_to_load_archive (FrArchive *archive,
* priority to the commands that can read and write over commands
* that can only read a specific file format. */
- requested_capabilities |= FR_COMMAND_CAN_READ_WRITE;
- command_type = get_command_type_from_mime_type (mime_type, requested_capabilities);
+ requested_capabilities |= FR_ARCHIVE_CAN_READ_WRITE;
+ archive_type = get_archive_type_from_mime_type (mime_type, requested_capabilities);
/* if no command was found, remove the write capability and try again */
- if (command_type == 0) {
- requested_capabilities ^= FR_COMMAND_CAN_WRITE;
- command_type = get_command_type_from_mime_type (mime_type, requested_capabilities);
+ if (archive_type == 0) {
+ requested_capabilities ^= FR_ARCHIVE_CAN_WRITE;
+ archive_type = get_archive_type_from_mime_type (mime_type, requested_capabilities);
}
- return create_command_from_type (archive,
- mime_type,
- command_type,
- requested_capabilities);
+ return create_archive_for_mime_type (archive_type,
+ file,
+ mime_type,
+ requested_capabilities);
}
-static gboolean
-create_command_to_create_archive (FrArchive *archive,
- const char *mime_type)
-{
- FrCommandCaps requested_capabilities = FR_COMMAND_CAN_DO_NOTHING;
- GType command_type;
+static void
+open_archive_stream_ready_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ OpenData *open_data = user_data;
+ GFileInputStream *istream = G_FILE_INPUT_STREAM (source_object);
+ GError *error = NULL;
+ gssize bytes_read;
+ const char *mime_type;
+ gboolean result_uncertain;
+ FrArchive *archive;
+ char *local_mime_type, *uri;
+
+ bytes_read = g_input_stream_read_finish (G_INPUT_STREAM (istream), result, &error);
+ if (bytes_read == -1) {
+ g_object_unref (istream);
+ load_data_complete_with_error (open_data, error);
+ return;
+ }
- if (mime_type == NULL)
- return FALSE;
+ open_data->buffer_size = bytes_read;
+ g_object_unref (istream);
+
+ archive = NULL;
+ uri = g_file_get_uri (open_data->file);
+ local_mime_type = g_content_type_guess (uri, (guchar *) open_data->buffer, open_data->buffer_size, &result_uncertain);
+ if (! result_uncertain) {
+ mime_type = _g_str_get_static (local_mime_type);
+ archive = create_archive_to_load_archive (open_data->file, mime_type);
+ }
+ if (archive == NULL) {
+ mime_type = get_mime_type_from_magic_numbers (open_data->buffer, open_data->buffer_size);
+ archive = create_archive_to_load_archive (open_data->file, mime_type);
+ if (archive == NULL) {
+ mime_type = get_mime_type_from_filename (open_data->file);
+ archive = create_archive_to_load_archive (open_data->file, mime_type);
+ if (archive == NULL) {
+ error = g_error_new (FR_ERROR,
+ FR_ERROR_UNSUPPORTED_FORMAT,
+ "%s",
+ _("Archive type not supported."));
+ load_data_complete_with_error (open_data, error);
+ return;
+ }
+ }
+ }
+
+ archive->priv->have_write_permissions = _g_file_check_permissions (fr_archive_get_file (archive), W_OK);
+ archive->read_only = ! fr_archive_is_capable_of (archive, FR_ARCHIVE_CAN_WRITE) || ! archive->priv->have_write_permissions;
+ open_data->archive = archive;
- requested_capabilities |= FR_COMMAND_CAN_WRITE;
- command_type = get_command_type_from_mime_type (mime_type, requested_capabilities);
+ g_simple_async_result_complete_in_idle (open_data->result);
- return create_command_from_type (archive,
- mime_type,
- command_type,
- requested_capabilities);
+ g_free (local_mime_type);
+ g_free (uri);
}
static void
-action_started (FrCommand *command,
- FrAction action,
- FrArchive *archive)
+open_archive_read_ready_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
{
-#ifdef DEBUG
- debug (DEBUG_INFO, "%s [START] (FR::Archive)\n", action_names[action]);
-#endif
-
- g_signal_emit (G_OBJECT (archive),
- fr_archive_signals[START],
- 0,
- action);
-}
-
+ OpenData *open_data = user_data;
+ GFileInputStream *istream;
+ GError *error = NULL;
-/* -- copy_to_remote_location -- */
+ istream = g_file_read_finish (G_FILE (source_object), result, &error);
+ if (istream == NULL) {
+ load_data_complete_with_error (open_data, error);
+ return;
+ }
+ g_input_stream_read_async (G_INPUT_STREAM (istream),
+ open_data->buffer,
+ open_data->buffer_size,
+ G_PRIORITY_DEFAULT,
+ open_data->cancellable,
+ open_archive_stream_ready_cb,
+ open_data);
+}
-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);
+void
+fr_archive_open (GFile *file,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ OpenData *open_data;
+
+ g_return_if_fail (file != NULL);
+
+ open_data = g_new0 (OpenData, 1);
+ open_data->file = g_object_ref (file);
+ open_data->cancellable = _g_object_ref (cancellable);
+ open_data->result = g_simple_async_result_new (G_OBJECT (file),
+ callback,
+ user_data,
+ fr_archive_open);
+ open_data->buffer_size = BUFFER_SIZE_FOR_PRELOAD;
+ open_data->buffer = g_new (char, open_data->buffer_size);
+ g_simple_async_result_set_op_res_gpointer (open_data->result,
+ open_data,
+ (GDestroyNotify) load_data_free);
+
+ /* FIXME: libarchive
+ fr_archive_action_started (archive, FR_ACTION_LOADING_ARCHIVE); */
+
+ /* load a few bytes to guess the archive type */
+
+ g_file_read_async (open_data->file,
+ G_PRIORITY_DEFAULT,
+ open_data->cancellable,
+ open_archive_read_ready_cb,
+ open_data);
}
-static void
-copy_to_remote_location_done (GError *error,
- gpointer user_data)
+FrArchive *
+fr_archive_open_finish (GFile *file,
+ GAsyncResult *result,
+ GError **error)
{
- XferData *xfer_data = user_data;
+ GSimpleAsyncResult *simple;
+ OpenData *open_data;
- fr_archive_copy_done (xfer_data->archive, xfer_data->action, error);
- xfer_data_free (xfer_data);
-}
+ g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (file), fr_archive_open), NULL);
+ simple = G_SIMPLE_ASYNC_RESULT (result);
-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;
+ if (g_simple_async_result_propagate_error (simple, error))
+ return FALSE;
- g_signal_emit (G_OBJECT (xfer_data->archive),
- fr_archive_signals[PROGRESS],
- 0,
- (double) current_num_bytes / total_num_bytes);
+ open_data = g_simple_async_result_get_op_res_gpointer (simple);
+ return _g_object_ref (open_data->archive);
}
-static void
-copy_to_remote_location (FrArchive *archive,
- FrAction action)
+void
+fr_archive_load (FrArchive *archive,
+ const char *password,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
- XferData *xfer_data;
+ g_return_if_fail (archive != NULL);
- xfer_data = g_new0 (XferData, 1);
- xfer_data->archive = archive;
- xfer_data->action = action;
+ if (archive->files != NULL) {
+ _g_ptr_array_free_full (archive->files, (GFunc) file_data_free, NULL);
+ archive->files = g_ptr_array_sized_new (FILE_ARRAY_INITIAL_SIZE);
+ }
- 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);
+ fr_archive_action_started (archive, FR_ACTION_LISTING_CONTENT);
+ FR_ARCHIVE_GET_CLASS (archive)->load (archive, password, cancellable, callback, user_data);
}
-/* -- copy_extracted_files_to_destination -- */
+gboolean
+fr_archive_operation_finish (FrArchive *archive,
+ GAsyncResult *result,
+ GError **error)
+{
+ return ! g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error);
+}
-static void
-move_here (FrArchive *archive)
+void
+fr_archive_add_files (FrArchive *archive,
+ GList *file_list,
+ const char *base_dir,
+ const char *dest_dir,
+ gboolean update,
+ gboolean recursive,
+ const char *password,
+ gboolean encrypt_header,
+ FrCompression compression,
+ guint volume_size,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
- char *content_uri;
- char *parent;
- char *parent_parent;
- char *new_content_uri;
- GFile *source, *destination, *parent_file;
- GError *error = NULL;
-
- content_uri = _g_uri_get_dir_content_if_unique (archive->priv->extraction_destination);
- if (content_uri == NULL)
- return;
+ g_return_if_fail (! archive->read_only);
- parent = _g_path_remove_level (content_uri);
+ g_signal_emit (G_OBJECT (archive),
+ fr_archive_signals[START],
+ 0,
+ FR_ACTION_ADDING_FILES);
- if (_g_uri_cmp (parent, archive->priv->extraction_destination) == 0) {
- char *new_uri;
+ FR_ARCHIVE_GET_CLASS (archive)->add_files (archive,
+ file_list,
+ base_dir,
+ dest_dir,
+ update,
+ recursive,
+ password,
+ encrypt_header,
+ compression,
+ volume_size,
+ cancellable,
+ callback,
+ user_data);
+}
- new_uri = _g_uri_create_alternative_for_uri (archive->priv->extraction_destination);
- source = g_file_new_for_uri (archive->priv->extraction_destination);
- destination = g_file_new_for_uri (new_uri);
- if (! g_file_move (source, destination, 0, NULL, NULL, NULL, &error)) {
- g_warning ("could not rename %s to %s: %s", archive->priv->extraction_destination, new_uri, error->message);
- g_clear_error (&error);
- }
- g_object_unref (source);
- g_object_unref (destination);
+/* -- add with wildcard -- */
- g_free (archive->priv->extraction_destination);
- archive->priv->extraction_destination = new_uri;
- g_free (parent);
-
- content_uri = _g_uri_get_dir_content_if_unique (archive->priv->extraction_destination);
- if (content_uri == NULL)
- return;
-
- parent = _g_path_remove_level (content_uri);
- }
-
- parent_parent = _g_path_remove_level (parent);
- new_content_uri = _g_uri_create_alternative (parent_parent, _g_path_get_file_name (content_uri));
-
- source = g_file_new_for_uri (content_uri);
- destination = g_file_new_for_uri (new_content_uri);
- if (! g_file_move (source, destination, 0, NULL, NULL, NULL, &error)) {
- g_warning ("could not rename %s to %s: %s", content_uri, new_content_uri, error->message);
- g_clear_error (&error);
- }
-
- parent_file = g_file_new_for_uri (parent);
- if (! g_file_delete (parent_file, NULL, &error)) {
- g_warning ("could not remove directory %s: %s", parent, error->message);
- g_clear_error (&error);
- }
- g_object_unref (parent_file);
-
- g_free (archive->priv->extraction_destination);
- archive->priv->extraction_destination = new_content_uri;
-
- g_free (parent_parent);
- g_free (parent);
- g_free (content_uri);
-}
-
-
-static void
-copy_extracted_files_done (GError *error,
- gpointer user_data)
-{
- FrArchive *archive = user_data;
-
- _g_path_remove_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);
-
-
-static void
-fr_archive_change_name (FrArchive *archive,
- const char *filename)
-{
- const char *name;
- GFile *parent;
-
- name = _g_path_get_file_name (filename);
-
- parent = g_file_get_parent (archive->file);
- 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);
-}
-
-
-static void
-action_performed (FrCommand *command,
- FrAction action,
- FrProcError *error,
- FrArchive *archive)
-{
-#ifdef DEBUG
- debug (DEBUG_INFO, "%s [DONE] (FR::Archive)\n", action_names[action]);
-#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);
- if (archive->priv->continue_adding_dropped_items) {
- add_dropped_items (archive->priv->dropped_items_data);
- return;
- }
- if (archive->priv->dropped_items_data != NULL) {
- dropped_items_data_free (archive->priv->dropped_items_data);
- archive->priv->dropped_items_data = NULL;
- }
- /* the name of the volumes are different from the
- * 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->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)) {
- _g_path_remove_directory (archive->priv->temp_extraction_dir);
- g_free (archive->priv->temp_extraction_dir);
- archive->priv->temp_extraction_dir = NULL;
- }
-
- if (archive->priv->extract_here)
- _g_uri_remove_directory (archive->priv->extraction_destination);
- }
- break;
-
- case FR_ACTION_LISTING_CONTENT:
- /* the name of the volumes are different from the
- * original name */
- if (archive->command->multi_volume)
- fr_archive_change_name (archive, archive->command->filename);
- fr_command_update_capabilities (archive->command);
- if (! fr_command_is_capable_of (archive->command, FR_COMMAND_CAN_WRITE))
- archive->read_only = TRUE;
- break;
-
- default:
- /* nothing */
- break;
- }
-
- g_signal_emit (G_OBJECT (archive),
- fr_archive_signals[DONE],
- 0,
- action,
- error);
-}
-
-
-static gboolean
-archive_progress_cb (FrCommand *command,
- double fraction,
- FrArchive *archive)
-{
- g_signal_emit (G_OBJECT (archive),
- fr_archive_signals[PROGRESS],
- 0,
- fraction);
- return TRUE;
-}
-
-
-static gboolean
-archive_message_cb (FrCommand *command,
- const char *msg,
- FrArchive *archive)
-{
- g_signal_emit (G_OBJECT (archive),
- fr_archive_signals[MESSAGE],
- 0,
- msg);
- return TRUE;
-}
-
-
-static gboolean
-archive_working_archive_cb (FrCommand *command,
- const char *archive_filename,
- FrArchive *archive)
-{
- g_signal_emit (G_OBJECT (archive),
- fr_archive_signals[WORKING_ARCHIVE],
- 0,
- archive_filename);
- return TRUE;
-}
-
-
-static void
-fr_archive_connect_to_command (FrArchive *archive)
-{
- g_signal_connect (G_OBJECT (archive->command),
- "start",
- G_CALLBACK (action_started),
- archive);
- g_signal_connect (G_OBJECT (archive->command),
- "done",
- G_CALLBACK (action_performed),
- archive);
- g_signal_connect (G_OBJECT (archive->command),
- "progress",
- G_CALLBACK (archive_progress_cb),
- archive);
- g_signal_connect (G_OBJECT (archive->command),
- "message",
- G_CALLBACK (archive_message_cb),
- archive);
- g_signal_connect (G_OBJECT (archive->command),
- "working_archive",
- G_CALLBACK (archive_working_archive_cb),
- archive);
-}
-
-
-gboolean
-fr_archive_create (FrArchive *archive,
- const char *uri)
-{
- FrCommand *tmp_command;
- const char *mime_type;
-
- if (uri == NULL)
- return FALSE;
-
- fr_archive_set_uri (archive, uri);
-
- tmp_command = archive->command;
-
- 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;
- }
-
- if (tmp_command != NULL) {
- g_signal_handlers_disconnect_by_data (tmp_command, archive);
- g_object_unref (G_OBJECT (tmp_command));
- }
-
- fr_archive_connect_to_command (archive);
- archive->read_only = FALSE;
-
- return TRUE;
-}
-
-
-void
-fr_archive_set_fake_load_func (FrArchive *archive,
- FakeLoadFunc func,
- gpointer data)
-{
- archive->priv->fake_load_func = func;
- archive->priv->fake_load_data = data;
-}
-
-
-gboolean
-fr_archive_fake_load (FrArchive *archive)
-{
- if (archive->priv->fake_load_func != NULL)
- return (*archive->priv->fake_load_func) (archive, archive->priv->fake_load_data);
- else
- return FALSE;
-}
-
-
-/* -- fr_archive_load -- */
-
-
-static void
-load_local_archive (FrArchive *archive,
- const char *password)
-{
- FrCommand *old_command;
- const char *mime_type;
-
- if (! g_file_query_exists (archive->file, archive->priv->cancellable)) {
- fr_archive_action_completed (archive,
- FR_ACTION_LOADING_ARCHIVE,
- FR_PROC_ERROR_GENERIC,
- _("File not found."));
- return;
- }
-
- archive->have_permissions = _g_file_check_permissions (archive->file, W_OK);
- archive->read_only = ! archive->have_permissions;
-
- old_command = archive->command;
-
- 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->local_copy);
- if (! create_command_to_load_archive (archive, mime_type)) {
- mime_type = get_mime_type_from_magic_numbers (archive->local_copy);
- if (! create_command_to_load_archive (archive, mime_type)) {
- archive->command = old_command;
- archive->content_type = mime_type;
- fr_archive_action_completed (archive,
- FR_ACTION_LOADING_ARCHIVE,
- FR_PROC_ERROR_UNSUPPORTED_FORMAT,
- _("Archive type not supported."));
- return;
- }
- }
- }
-
- if (old_command != NULL) {
- g_signal_handlers_disconnect_by_data (old_command, archive);
- g_object_unref (old_command);
- }
-
- fr_archive_connect_to_command (archive);
- archive->content_type = mime_type;
- if (! fr_command_is_capable_of (archive->command, FR_COMMAND_CAN_WRITE))
- archive->read_only = TRUE;
- fr_archive_stoppable (archive, TRUE);
- archive->command->fake_load = fr_archive_fake_load (archive);
-
- fr_archive_action_completed (archive,
- FR_ACTION_LOADING_ARCHIVE,
- FR_PROC_ERROR_NONE,
- NULL);
-
- /**/
-
- fr_process_clear (archive->process);
- g_object_set (archive->command,
- "file", archive->local_copy,
- "password", password,
- NULL);
- fr_command_list (archive->command);
-}
-
-
-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, archive->priv->cancellable)) {
- GError *error;
-
- error = g_error_new (G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("Archive not found"));
- 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,
- const char *password)
-{
- g_return_val_if_fail (archive != NULL, FALSE);
-
- g_signal_emit (G_OBJECT (archive),
- fr_archive_signals[START],
- 0,
- FR_ACTION_LOADING_ARCHIVE);
-
- fr_archive_set_uri (archive, uri);
- copy_remote_file (archive, password);
-
- return TRUE;
-}
-
-
-void
-fr_archive_reload (FrArchive *archive,
- const char *password)
-{
- char *uri;
-
- g_return_if_fail (archive != NULL);
- g_return_if_fail (archive->file != NULL);
-
- fr_archive_stoppable (archive, TRUE);
- archive->command->fake_load = fr_archive_fake_load (archive);
-
- uri = g_file_get_uri (archive->file);
- fr_archive_load (archive, uri, password);
- g_free (uri);
-}
-
-
-/* -- add -- */
-
-
-static char *
-create_tmp_base_dir (const char *base_dir,
- const char *dest_path)
-{
- char *dest_dir;
- char *temp_dir;
- char *tmp;
- char *parent_dir;
- char *dir;
-
- if ((dest_path == NULL)
- || (*dest_path == '\0')
- || (strcmp (dest_path, "/") == 0))
- {
- return g_strdup (base_dir);
- }
-
- dest_dir = g_strdup (dest_path);
- if (dest_dir[strlen (dest_dir) - 1] == G_DIR_SEPARATOR)
- dest_dir[strlen (dest_dir) - 1] = 0;
-
- debug (DEBUG_INFO, "base_dir: %s\n", base_dir);
- debug (DEBUG_INFO, "dest_dir: %s\n", dest_dir);
-
- temp_dir = _g_path_get_temp_work_dir (NULL);
- tmp = _g_path_remove_level (dest_dir);
- parent_dir = g_build_filename (temp_dir, tmp, NULL);
- g_free (tmp);
-
- debug (DEBUG_INFO, "mkdir %s\n", parent_dir);
- _g_path_make_directory_tree (parent_dir, 0700, NULL);
- g_free (parent_dir);
-
- dir = g_build_filename (temp_dir, "/", dest_dir, NULL);
- debug (DEBUG_INFO, "symlink %s --> %s\n", dir, base_dir);
- if (! symlink (base_dir, dir)) {
- /* void */
- }
-
- g_free (dir);
- g_free (dest_dir);
-
- return temp_dir;
-}
-
-
-static FileData *
-find_file_in_archive (FrArchive *archive,
- char *path)
-{
- int i;
-
- g_return_val_if_fail (path != NULL, NULL);
-
- i = find_path_in_file_data_array (archive->command->files, path);
- if (i >= 0)
- return (FileData *) g_ptr_array_index (archive->command->files, i);
- else
- return NULL;
-}
-
-
-static void delete_from_archive (FrArchive *archive, GList *file_list);
-
-
-static GList *
-newer_files_only (FrArchive *archive,
- GList *file_list,
- const char *base_dir)
-{
- GList *newer_files = NULL;
- GList *scan;
-
- for (scan = file_list; scan; scan = scan->next) {
- char *filename = scan->data;
- char *fullpath;
- char *uri;
- FileData *fdata;
-
- fdata = find_file_in_archive (archive, filename);
-
- if (fdata == NULL) {
- newer_files = g_list_prepend (newer_files, g_strdup (scan->data));
- continue;
- }
-
- fullpath = g_strconcat (base_dir, "/", filename, NULL);
- uri = g_filename_to_uri (fullpath, NULL, NULL);
-
- if (fdata->modified >= _g_uri_get_file_mtime (uri)) {
- g_free (fullpath);
- g_free (uri);
- continue;
- }
- g_free (fullpath);
- g_free (uri);
-
- newer_files = g_list_prepend (newer_files, g_strdup (scan->data));
- }
-
- return newer_files;
-}
-
-
-static gboolean
-save_list_to_temp_file (GList *file_list,
- char **list_dir,
- char **list_filename,
- GError **error)
-{
- gboolean error_occurred = FALSE;
- GFile *list_file;
- GFileOutputStream *ostream;
-
- if (error != NULL)
- *error = NULL;
- *list_dir = _g_path_get_temp_work_dir (NULL);
- *list_filename = g_build_filename (*list_dir, "file-list", NULL);
- list_file = g_file_new_for_path (*list_filename);
- ostream = g_file_create (list_file, G_FILE_CREATE_PRIVATE, NULL, error);
-
- if (ostream != NULL) {
- GList *scan;
-
- for (scan = file_list; scan != NULL; scan = scan->next) {
- char *filename = scan->data;
-
- filename = _g_str_substitute (filename, "\n", "\\n");
- if ((g_output_stream_write (G_OUTPUT_STREAM (ostream), filename, strlen (filename), NULL, error) < 0)
- || (g_output_stream_write (G_OUTPUT_STREAM (ostream), "\n", 1, NULL, error) < 0))
- {
- error_occurred = TRUE;
- }
-
- g_free (filename);
-
- if (error_occurred)
- break;
- }
- if (! error_occurred && ! g_output_stream_close (G_OUTPUT_STREAM (ostream), NULL, error))
- error_occurred = TRUE;
- g_object_unref (ostream);
- }
- else
- error_occurred = TRUE;
-
- if (error_occurred) {
- _g_path_remove_directory (*list_dir);
- g_free (*list_dir);
- g_free (*list_filename);
- *list_dir = NULL;
- *list_filename = NULL;
- }
-
- g_object_unref (list_file);
-
- return ! error_occurred;
-}
-
-
-static GList *
-split_in_chunks (GList *file_list)
-{
- GList *chunks = NULL;
- GList *new_file_list;
- GList *scan;
-
- new_file_list = g_list_copy (file_list);
- for (scan = new_file_list; scan != NULL; /* void */) {
- GList *prev = scan->prev;
- GList *chunk;
- int l;
-
- chunk = scan;
- l = 0;
- while ((scan != NULL) && (l < MAX_CHUNK_LEN)) {
- if (l == 0)
- l = strlen (scan->data);
- prev = scan;
- scan = scan->next;
- if (scan != NULL)
- l += strlen (scan->data);
- }
- if (prev != NULL) {
- if (prev->next != NULL)
- prev->next->prev = NULL;
- prev->next = NULL;
- }
- chunks = g_list_append (chunks, chunk);
- }
-
- return chunks;
-}
-
-
-void
-fr_archive_add (FrArchive *archive,
- GList *file_list,
- const char *base_dir,
- const char *dest_dir,
- gboolean update,
- gboolean recursive,
- const char *password,
- gboolean encrypt_header,
- FrCompression compression,
- guint volume_size)
-{
- GList *new_file_list = NULL;
- gboolean base_dir_created = FALSE;
- GList *scan;
- char *tmp_base_dir = NULL;
- char *tmp_archive_dir = NULL;
- char *archive_filename = NULL;
- char *tmp_archive_filename = NULL;
- gboolean error_occurred = FALSE;
-
- if (file_list == NULL)
- return;
-
- if (archive->read_only)
- return;
-
- g_object_set (archive->command,
- "password", password,
- "encrypt_header", encrypt_header,
- "compression", compression,
- "volume_size", volume_size,
- NULL);
-
- fr_archive_stoppable (archive, TRUE);
-
- /* dest_dir is the destination folder inside the archive */
-
- if ((dest_dir != NULL) && (*dest_dir != '\0') && (strcmp (dest_dir, "/") != 0)) {
- const char *rel_dest_dir = dest_dir;
-
- tmp_base_dir = create_tmp_base_dir (base_dir, dest_dir);
- base_dir_created = TRUE;
-
- if (dest_dir[0] == G_DIR_SEPARATOR)
- rel_dest_dir = dest_dir + 1;
-
- new_file_list = NULL;
- for (scan = file_list; scan != NULL; scan = scan->next) {
- char *filename = scan->data;
- new_file_list = g_list_prepend (new_file_list, g_build_filename (rel_dest_dir, filename, NULL));
- }
- }
- else {
- tmp_base_dir = g_strdup (base_dir);
- new_file_list = _g_string_list_dup (file_list);
- }
-
- /* if the command cannot update, get the list of files that are
- * newer than the ones in the archive. */
-
- if (update && ! archive->command->propAddCanUpdate) {
- GList *tmp_file_list;
-
- tmp_file_list = new_file_list;
- new_file_list = newer_files_only (archive, tmp_file_list, tmp_base_dir);
- _g_string_list_free (tmp_file_list);
- }
-
- if (new_file_list == NULL) {
- debug (DEBUG_INFO, "nothing to update.\n");
-
- if (base_dir_created)
- _g_path_remove_directory (tmp_base_dir);
- g_free (tmp_base_dir);
-
- archive->process->error.type = FR_PROC_ERROR_NONE;
- g_signal_emit_by_name (G_OBJECT (archive->process),
- "done",
- &archive->process->error);
- return;
- }
-
- archive->command->creating_archive = ! g_file_query_exists (archive->local_copy, archive->priv->cancellable);
-
- /* create the new archive in a temporary sub-directory, this allows
- * to cancel the operation without losing the original archive and
- * removing possible temporary files created by the command. */
-
- {
- GFile *local_copy_parent;
- char *archive_dir;
- GFile *tmp_file;
-
- /* create the new archive in a sub-folder of the original
- * archive this way the 'mv' command is fast. */
-
- local_copy_parent = g_file_get_parent (archive->local_copy);
- archive_dir = g_file_get_path (local_copy_parent);
- tmp_archive_dir = _g_path_get_temp_work_dir (archive_dir);
- archive_filename = g_file_get_path (archive->local_copy);
- tmp_archive_filename = g_build_filename (tmp_archive_dir, _g_path_get_file_name (archive_filename), NULL);
- tmp_file = g_file_new_for_path (tmp_archive_filename);
- g_object_set (archive->command, "file", tmp_file, NULL);
-
- if (! archive->command->creating_archive) {
- /* copy the original archive to the new position */
-
- fr_process_begin_command (archive->process, "cp");
- fr_process_add_arg (archive->process, "-f");
- fr_process_add_arg (archive->process, archive_filename);
- fr_process_add_arg (archive->process, tmp_archive_filename);
- fr_process_end_command (archive->process);
- }
-
- g_object_unref (tmp_file);
- g_free (archive_dir);
- g_object_unref (local_copy_parent);
- }
-
- fr_command_uncompress (archive->command);
-
- /* when files are already present in a tar archive and are added
- * again, they are not replaced, so we have to delete them first. */
-
- /* if we are adding (== ! update) and 'add' cannot replace or
- * if we are updating and 'add' cannot update,
- * delete the files first. */
-
- if ((! update && ! archive->command->propAddCanReplace)
- || (update && ! archive->command->propAddCanUpdate))
- {
- GList *del_list = NULL;
-
- for (scan = new_file_list; scan != NULL; scan = scan->next) {
- char *filename = scan->data;
- if (find_file_in_archive (archive, filename))
- del_list = g_list_prepend (del_list, filename);
- }
-
- /* delete */
-
- if (del_list != NULL) {
- delete_from_archive (archive, del_list);
- fr_process_set_ignore_error (archive->process, TRUE);
- g_list_free (del_list);
- }
- }
-
- /* add now. */
-
- fr_command_set_n_files (archive->command, g_list_length (new_file_list));
-
- if (archive->command->propListFromFile
- && (archive->command->n_files > LIST_LENGTH_TO_USE_FILE))
- {
- char *list_dir;
- char *list_filename;
- GError *error = NULL;
-
- if (! save_list_to_temp_file (new_file_list, &list_dir, &list_filename, &error)) {
- archive->process->error.type = FR_PROC_ERROR_GENERIC;
- archive->process->error.status = 0;
- archive->process->error.gerror = g_error_copy (error);
- g_signal_emit_by_name (G_OBJECT (archive->process),
- "done",
- &archive->process->error);
- g_clear_error (&error);
- error_occurred = TRUE;
- }
- else {
- fr_command_add (archive->command,
- list_filename,
- new_file_list,
- tmp_base_dir,
- update,
- recursive);
-
- /* remove the temp dir */
-
- fr_process_begin_command (archive->process, "rm");
- fr_process_set_working_dir (archive->process, g_get_tmp_dir());
- fr_process_set_sticky (archive->process, TRUE);
- fr_process_add_arg (archive->process, "-rf");
- fr_process_add_arg (archive->process, list_dir);
- fr_process_end_command (archive->process);
- }
-
- g_free (list_filename);
- g_free (list_dir);
- }
- else {
- GList *chunks = NULL;
-
- /* specify the file list on the command line, splitting
- * in more commands to avoid to overflow the command line
- * length limit. */
-
- chunks = split_in_chunks (new_file_list);
- for (scan = chunks; scan != NULL; scan = scan->next) {
- GList *chunk = scan->data;
-
- fr_command_add (archive->command,
- NULL,
- chunk,
- tmp_base_dir,
- update,
- recursive);
- g_list_free (chunk);
- }
-
- g_list_free (chunks);
- }
-
- _g_string_list_free (new_file_list);
-
- if (! error_occurred) {
- fr_command_recompress (archive->command);
-
- /* move the new archive to the original position */
-
- fr_process_begin_command (archive->process, "mv");
- fr_process_add_arg (archive->process, "-f");
- fr_process_add_arg (archive->process, tmp_archive_filename);
- fr_process_add_arg (archive->process, archive_filename);
- fr_process_end_command (archive->process);
-
- /* remove the temp sub-directory */
-
- fr_process_begin_command (archive->process, "rm");
- fr_process_set_working_dir (archive->process, g_get_tmp_dir());
- fr_process_set_sticky (archive->process, TRUE);
- fr_process_add_arg (archive->process, "-rf");
- fr_process_add_arg (archive->process, tmp_archive_dir);
- fr_process_end_command (archive->process);
-
- /* remove the base dir */
-
- if (base_dir_created) {
- fr_process_begin_command (archive->process, "rm");
- fr_process_set_working_dir (archive->process, g_get_tmp_dir());
- fr_process_set_sticky (archive->process, TRUE);
- fr_process_add_arg (archive->process, "-rf");
- fr_process_add_arg (archive->process, tmp_base_dir);
- fr_process_end_command (archive->process);
- }
- }
-
- g_free (tmp_archive_filename);
- g_free (archive_filename);
- g_free (tmp_archive_dir);
- g_free (tmp_base_dir);
-}
-
-
-static void
-fr_archive_add_local_files (FrArchive *archive,
- GList *file_list,
- const char *base_dir,
- const char *dest_dir,
- gboolean update,
- const char *password,
- gboolean encrypt_header,
- FrCompression compression,
- guint volume_size)
-{
- fr_process_clear (archive->process);
- fr_archive_add (archive,
- file_list,
- base_dir,
- dest_dir,
- update,
- FALSE,
- password,
- encrypt_header,
- compression,
- volume_size);
- fr_process_start (archive->process);
-}
-
-
-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 = _g_path_remove_level (local_uri);
- if (g_hash_table_lookup (created_folders, local_folder_uri) == NULL) {
- GError *error = NULL;
- if (! _g_uri_ensure_dir_exists (local_folder_uri, 0755, &error)) {
- g_free (local_folder_uri);
- g_free (local_uri);
- _g_file_list_free (sources);
- _g_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 = _g_string_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);
-
- _g_file_list_free (sources);
- _g_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 = _g_path_get_temp_work_dir (NULL);
- return archive->priv->temp_dir;
-}
-
-
-void
-fr_archive_add_files (FrArchive *archive,
- GList *file_list,
- const char *base_dir,
- const char *dest_dir,
- gboolean update,
- const char *password,
- gboolean encrypt_header,
- FrCompression compression,
- guint volume_size)
-{
- if (_g_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));
-}
-
-
-/* -- add with wildcard -- */
-
-
-typedef struct {
- FrArchive *archive;
- char *source_dir;
- char *dest_dir;
- gboolean update;
- char *password;
- gboolean encrypt_header;
- FrCompression compression;
- guint volume_size;
-} AddWithWildcardData;
-
-
-static void
-add_with_wildcard_data_free (AddWithWildcardData *aww_data)
-{
- g_free (aww_data->source_dir);
- g_free (aww_data->dest_dir);
- g_free (aww_data->password);
- g_free (aww_data);
-}
-
-
-static void
-add_with_wildcard__step2 (GList *file_list,
- GList *dirs_list,
- GError *error,
- gpointer data)
-{
- AddWithWildcardData *aww_data = data;
- FrArchive *archive = aww_data->archive;
-
- if (error != NULL) {
- fr_archive_action_completed (archive,
- FR_ACTION_GETTING_FILE_LIST,
- (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) ? FR_PROC_ERROR_STOPPED : FR_PROC_ERROR_GENERIC),
- error->message);
- return;
- }
-
- fr_archive_action_completed (archive,
- FR_ACTION_GETTING_FILE_LIST,
- FR_PROC_ERROR_NONE,
- NULL);
-
- if (file_list != NULL)
- fr_archive_add_files (aww_data->archive,
- file_list,
- aww_data->source_dir,
- aww_data->dest_dir,
- aww_data->update,
- aww_data->password,
- aww_data->encrypt_header,
- aww_data->compression,
- aww_data->volume_size);
-
- _g_string_list_free (file_list);
- _g_string_list_free (dirs_list);
- add_with_wildcard_data_free (aww_data);
-}
-
-
-void
-fr_archive_add_with_wildcard (FrArchive *archive,
- const char *include_files,
- const char *exclude_files,
- const char *exclude_folders,
- const char *source_dir,
- const char *dest_dir,
- gboolean update,
- gboolean follow_links,
- const char *password,
- gboolean encrypt_header,
- FrCompression compression,
- guint volume_size)
-{
- AddWithWildcardData *aww_data;
-
- g_return_if_fail (! archive->read_only);
-
- aww_data = g_new0 (AddWithWildcardData, 1);
- aww_data->archive = archive;
- aww_data->source_dir = g_strdup (source_dir);
- aww_data->dest_dir = g_strdup (dest_dir);
- aww_data->update = update;
- aww_data->password = g_strdup (password);
- aww_data->encrypt_header = encrypt_header;
- aww_data->compression = compression;
- aww_data->volume_size = volume_size;
-
- g_signal_emit (G_OBJECT (archive),
- fr_archive_signals[START],
- 0,
- FR_ACTION_GETTING_FILE_LIST);
-
- g_directory_list_async (source_dir,
- source_dir,
- TRUE,
- follow_links,
- NO_BACKUP_FILES,
- NO_DOT_FILES,
- include_files,
- exclude_files,
- exclude_folders,
- IGNORE_CASE,
- archive->priv->cancellable,
- add_with_wildcard__step2,
- aww_data);
-}
-
-
-/* -- fr_archive_add_directory -- */
-
-
-typedef struct {
- FrArchive *archive;
- char *base_dir;
- char *dest_dir;
- gboolean update;
- char *password;
- gboolean encrypt_header;
- FrCompression compression;
- guint volume_size;
-} AddDirectoryData;
-
-
-static void
-add_directory_data_free (AddDirectoryData *ad_data)
-{
- g_free (ad_data->base_dir);
- g_free (ad_data->dest_dir);
- g_free (ad_data->password);
- g_free (ad_data);
-}
-
-
-static void
-add_directory__step2 (GList *file_list,
- GList *dir_list,
- GError *error,
- gpointer data)
-{
- AddDirectoryData *ad_data = data;
- FrArchive *archive = ad_data->archive;
-
- if (error != NULL) {
- fr_archive_action_completed (archive,
- FR_ACTION_GETTING_FILE_LIST,
- (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) ? FR_PROC_ERROR_STOPPED : FR_PROC_ERROR_GENERIC),
- error->message);
- return;
- }
-
- fr_archive_action_completed (archive,
- FR_ACTION_GETTING_FILE_LIST,
- FR_PROC_ERROR_NONE,
- NULL);
-
- if (archive->command->propAddCanStoreFolders)
- file_list = g_list_concat (file_list, dir_list);
- else
- _g_string_list_free (dir_list);
-
- if (file_list != NULL) {
- fr_archive_add_files (ad_data->archive,
- file_list,
- ad_data->base_dir,
- ad_data->dest_dir,
- ad_data->update,
- ad_data->password,
- ad_data->encrypt_header,
- ad_data->compression,
- ad_data->volume_size);
- _g_string_list_free (file_list);
- }
-
- add_directory_data_free (ad_data);
-}
-
-
-void
-fr_archive_add_directory (FrArchive *archive,
- const char *directory,
- const char *base_dir,
- const char *dest_dir,
- gboolean update,
- const char *password,
- gboolean encrypt_header,
- FrCompression compression,
- guint volume_size)
-
-{
- AddDirectoryData *ad_data;
-
- g_return_if_fail (! archive->read_only);
-
- ad_data = g_new0 (AddDirectoryData, 1);
- ad_data->archive = archive;
- ad_data->base_dir = g_strdup (base_dir);
- ad_data->dest_dir = g_strdup (dest_dir);
- ad_data->update = update;
- ad_data->password = g_strdup (password);
- ad_data->encrypt_header = encrypt_header;
- ad_data->compression = compression;
- ad_data->volume_size = volume_size;
-
- g_signal_emit (G_OBJECT (archive),
- fr_archive_signals[START],
- 0,
- FR_ACTION_GETTING_FILE_LIST);
-
- g_directory_list_all_async (directory,
- base_dir,
- TRUE,
- archive->priv->cancellable,
- add_directory__step2,
- ad_data);
-}
-
-
-void
-fr_archive_add_items (FrArchive *archive,
- GList *item_list,
- const char *base_dir,
- const char *dest_dir,
- gboolean update,
- const char *password,
- gboolean encrypt_header,
- FrCompression compression,
- guint volume_size)
-
-{
- AddDirectoryData *ad_data;
-
- g_return_if_fail (! archive->read_only);
-
- ad_data = g_new0 (AddDirectoryData, 1);
- ad_data->archive = archive;
- ad_data->base_dir = g_strdup (base_dir);
- ad_data->dest_dir = g_strdup (dest_dir);
- ad_data->update = update;
- ad_data->password = g_strdup (password);
- ad_data->encrypt_header = encrypt_header;
- ad_data->compression = compression;
- ad_data->volume_size = volume_size;
-
- g_signal_emit (G_OBJECT (archive),
- fr_archive_signals[START],
- 0,
- FR_ACTION_GETTING_FILE_LIST);
-
- g_list_items_async (item_list,
- base_dir,
- archive->priv->cancellable,
- add_directory__step2,
- ad_data);
-}
-
-
-/* -- fr_archive_add_dropped_items -- */
-
-
-static gboolean
-all_files_in_same_dir (GList *list)
-{
- gboolean same_dir = TRUE;
- char *first_basedir;
- GList *scan;
-
- if (list == NULL)
- return FALSE;
-
- first_basedir = _g_path_remove_level (list->data);
- if (first_basedir == NULL)
- return TRUE;
-
- for (scan = list->next; scan; scan = scan->next) {
- char *path = scan->data;
- char *basedir;
-
- basedir = _g_path_remove_level (path);
- if (basedir == NULL) {
- same_dir = FALSE;
- break;
- }
-
- if (strcmp (first_basedir, basedir) != 0) {
- same_dir = FALSE;
- g_free (basedir);
- break;
- }
- g_free (basedir);
- }
- g_free (first_basedir);
-
- return same_dir;
-}
-
-
-static void
-add_dropped_items (DroppedItemsData *data)
-{
- FrArchive *archive = data->archive;
- GList *list = data->item_list;
- GList *scan;
-
- if (list == NULL) {
- dropped_items_data_free (archive->priv->dropped_items_data);
- archive->priv->dropped_items_data = NULL;
- fr_archive_action_completed (archive,
- FR_ACTION_ADDING_FILES,
- FR_PROC_ERROR_NONE,
- NULL);
- return;
- }
-
- /* if all files/dirs are in the same directory call fr_archive_add_items... */
-
- if (all_files_in_same_dir (list)) {
- char *first_base_dir;
-
- first_base_dir = _g_path_remove_level (list->data);
- fr_archive_add_items (data->archive,
- list,
- first_base_dir,
- data->dest_dir,
- data->update,
- data->password,
- data->encrypt_header,
- data->compression,
- data->volume_size);
- g_free (first_base_dir);
-
- dropped_items_data_free (archive->priv->dropped_items_data);
- archive->priv->dropped_items_data = NULL;
-
- return;
- }
-
- /* ...else add a directory at a time. */
-
- for (scan = list; scan; scan = scan->next) {
- char *path = scan->data;
- char *base_dir;
-
- if (! _g_uri_query_is_dir (path))
- continue;
-
- data->item_list = g_list_remove_link (list, scan);
- if (data->item_list != NULL)
- archive->priv->continue_adding_dropped_items = TRUE;
- base_dir = _g_path_remove_level (path);
-
- fr_archive_add_directory (archive,
- _g_path_get_file_name (path),
- base_dir,
- data->dest_dir,
- data->update,
- data->password,
- data->encrypt_header,
- data->compression,
- data->volume_size);
-
- g_free (base_dir);
- g_free (path);
-
- return;
- }
-
- /* if all files are in the same directory call fr_archive_add_files. */
-
- if (all_files_in_same_dir (list)) {
- char *first_basedir;
- GList *only_names_list = NULL;
-
- first_basedir = _g_path_remove_level (list->data);
-
- for (scan = list; scan; scan = scan->next) {
- char *name;
-
- name = g_uri_unescape_string (_g_path_get_file_name (scan->data), NULL);
- only_names_list = g_list_prepend (only_names_list, name);
- }
-
- fr_archive_add_files (archive,
- only_names_list,
- first_basedir,
- data->dest_dir,
- data->update,
- data->password,
- data->encrypt_header,
- data->compression,
- data->volume_size);
-
- _g_string_list_free (only_names_list);
- g_free (first_basedir);
-
- return;
- }
-
- /* ...else call fr_command_add for each file. This is needed to add
- * files without path info. FIXME: doesn't work with remote files. */
-
- fr_archive_stoppable (archive, FALSE);
- archive->command->creating_archive = ! g_file_query_exists (archive->local_copy, archive->priv->cancellable);
- g_object_set (archive->command,
- "file", archive->local_copy,
- "password", data->password,
- "encrypt_header", data->encrypt_header,
- "compression", data->compression,
- "volume_size", data->volume_size,
- NULL);
- fr_process_clear (archive->process);
- fr_command_uncompress (archive->command);
- for (scan = list; scan; scan = scan->next) {
- char *fullpath = scan->data;
- char *basedir;
- GList *singleton;
-
- basedir = _g_path_remove_level (fullpath);
- singleton = g_list_prepend (NULL, (char*)_g_path_get_file_name (fullpath));
- fr_command_add (archive->command,
- NULL,
- singleton,
- basedir,
- data->update,
- FALSE);
- g_list_free (singleton);
- g_free (basedir);
- }
- fr_command_recompress (archive->command);
- fr_process_start (archive->process);
-
- _g_string_list_free (data->item_list);
- data->item_list = NULL;
-}
-
-
-void
-fr_archive_add_dropped_items (FrArchive *archive,
- GList *item_list,
- const char *base_dir,
- const char *dest_dir,
- gboolean update,
- const char *password,
- gboolean encrypt_header,
- FrCompression compression,
- guint volume_size)
-{
- GList *scan;
- char *archive_uri;
-
- if (archive->read_only) {
- fr_archive_action_completed (archive,
- FR_ACTION_ADDING_FILES,
- FR_PROC_ERROR_GENERIC,
- ! archive->have_permissions ? _("You don't have the right permissions.") : _("This archive type cannot be modified"));
- return;
- }
-
- /* FIXME: make this check for all the add actions */
- archive_uri = g_file_get_uri (archive->file);
- for (scan = item_list; scan; scan = scan->next) {
- if (_g_uri_cmp (scan->data, archive_uri) == 0) {
- g_free (archive_uri);
- fr_archive_action_completed (archive,
- FR_ACTION_ADDING_FILES,
- FR_PROC_ERROR_GENERIC,
- _("You can't add an archive to itself."));
- return;
- }
- }
- g_free (archive_uri);
-
- if (archive->priv->dropped_items_data != NULL)
- dropped_items_data_free (archive->priv->dropped_items_data);
- archive->priv->dropped_items_data = dropped_items_data_new (
- archive,
- item_list,
- base_dir,
- dest_dir,
- update,
- password,
- encrypt_header,
- compression,
- volume_size);
- add_dropped_items (archive->priv->dropped_items_data);
-}
-
-
-/* -- remove -- */
-
-
-static gboolean
-file_is_in_subfolder_of (const char *filename,
- GList *folder_list)
-{
- GList *scan;
-
- if (filename == NULL)
- return FALSE;
-
- for (scan = folder_list; scan; scan = scan->next) {
- char *folder_in_list = (char*) scan->data;
-
- if (_g_path_is_parent_of (folder_in_list, filename))
- return TRUE;
- }
-
- return FALSE;
-}
-
-static gboolean
-archive_type_has_issues_deleting_non_empty_folders (FrArchive *archive)
-{
- return ! archive->command->propCanDeleteNonEmptyFolders;
-}
-
-
-static void
-delete_from_archive (FrArchive *archive,
- GList *file_list)
-{
- gboolean file_list_created = FALSE;
- GList *tmp_file_list = NULL;
- gboolean tmp_file_list_created = FALSE;
- GList *scan;
-
- /* file_list == NULL means delete all the files in the archive. */
-
- if (file_list == NULL) {
- int i;
-
- for (i = 0; i < archive->command->files->len; i++) {
- FileData *fdata = g_ptr_array_index (archive->command->files, i);
- file_list = g_list_prepend (file_list, fdata->original_path);
- }
-
- file_list_created = TRUE;
- }
-
- if (archive_type_has_issues_deleting_non_empty_folders (archive)) {
- GList *folders_to_remove;
-
- /* remove from the list the files contained in folders to be
- * removed. */
-
- folders_to_remove = NULL;
- for (scan = file_list; scan != NULL; scan = scan->next) {
- char *path = scan->data;
-
- if (path[strlen (path) - 1] == '/')
- folders_to_remove = g_list_prepend (folders_to_remove, path);
- }
-
- if (folders_to_remove != NULL) {
- tmp_file_list = NULL;
- for (scan = file_list; scan != NULL; scan = scan->next) {
- char *path = scan->data;
-
- if (! file_is_in_subfolder_of (path, folders_to_remove))
- tmp_file_list = g_list_prepend (tmp_file_list, path);
- }
- tmp_file_list_created = TRUE;
- g_list_free (folders_to_remove);
- }
- }
-
- if (! tmp_file_list_created)
- tmp_file_list = g_list_copy (file_list);
-
- if (file_list_created)
- g_list_free (file_list);
-
- fr_command_set_n_files (archive->command, g_list_length (tmp_file_list));
-
- if (archive->command->propListFromFile
- && (archive->command->n_files > LIST_LENGTH_TO_USE_FILE))
- {
- char *list_dir;
- char *list_filename;
-
- if (save_list_to_temp_file (tmp_file_list, &list_dir, &list_filename, NULL)) {
- fr_command_delete (archive->command,
- list_filename,
- tmp_file_list);
-
- /* remove the temp dir */
-
- fr_process_begin_command (archive->process, "rm");
- fr_process_set_working_dir (archive->process, g_get_tmp_dir());
- fr_process_set_sticky (archive->process, TRUE);
- fr_process_add_arg (archive->process, "-rf");
- fr_process_add_arg (archive->process, list_dir);
- fr_process_end_command (archive->process);
- }
-
- g_free (list_filename);
- g_free (list_dir);
- }
- else {
- for (scan = tmp_file_list; scan != NULL; ) {
- GList *prev = scan->prev;
- GList *chunk_list;
- int l;
-
- chunk_list = scan;
- l = 0;
- while ((scan != NULL) && (l < MAX_CHUNK_LEN)) {
- if (l == 0)
- l = strlen (scan->data);
- prev = scan;
- scan = scan->next;
- if (scan != NULL)
- l += strlen (scan->data);
- }
-
- prev->next = NULL;
- fr_command_delete (archive->command, NULL, chunk_list);
- prev->next = scan;
- }
- }
-
- g_list_free (tmp_file_list);
-}
-
-
-void
-fr_archive_remove (FrArchive *archive,
- GList *file_list,
- FrCompression compression)
-{
- char *tmp_archive_dir = NULL;
- char *archive_filename = NULL;
- char *tmp_archive_filename = NULL;
-
- g_return_if_fail (archive != NULL);
-
- if (archive->read_only)
- return;
-
- fr_archive_stoppable (archive, TRUE);
- archive->command->creating_archive = FALSE;
- g_object_set (archive->command, "compression", compression, NULL);
-
- /* create the new archive in a temporary sub-directory, this allows
- * to cancel the operation without losing the original archive and
- * removing possible temporary files created by the command. */
-
- {
- GFile *local_copy_parent;
- char *archive_dir;
- GFile *tmp_file;
-
- /* create the new archive in a sub-folder of the original
- * archive this way the 'mv' command is fast. */
-
- local_copy_parent = g_file_get_parent (archive->local_copy);
- archive_dir = g_file_get_path (local_copy_parent);
- tmp_archive_dir = _g_path_get_temp_work_dir (archive_dir);
- archive_filename = g_file_get_path (archive->local_copy);
- tmp_archive_filename = g_build_filename (tmp_archive_dir, _g_path_get_file_name (archive_filename), NULL);
- tmp_file = g_file_new_for_path (tmp_archive_filename);
- g_object_set (archive->command, "file", tmp_file, NULL);
-
- if (! archive->command->creating_archive) {
- /* copy the original archive to the new position */
-
- fr_process_begin_command (archive->process, "cp");
- fr_process_add_arg (archive->process, "-f");
- fr_process_add_arg (archive->process, archive_filename);
- fr_process_add_arg (archive->process, tmp_archive_filename);
- fr_process_end_command (archive->process);
- }
-
- g_object_unref (tmp_file);
- g_free (archive_dir);
- g_object_unref (local_copy_parent);
- }
-
- /* uncompress, delete and recompress */
-
- fr_command_uncompress (archive->command);
- delete_from_archive (archive, file_list);
- fr_command_recompress (archive->command);
-
- /* move the new archive to the original position */
-
- fr_process_begin_command (archive->process, "mv");
- fr_process_add_arg (archive->process, "-f");
- fr_process_add_arg (archive->process, tmp_archive_filename);
- fr_process_add_arg (archive->process, archive_filename);
- fr_process_end_command (archive->process);
-
- /* remove the temp sub-directory */
-
- fr_process_begin_command (archive->process, "rm");
- fr_process_set_working_dir (archive->process, g_get_tmp_dir());
- fr_process_set_sticky (archive->process, TRUE);
- fr_process_add_arg (archive->process, "-rf");
- fr_process_add_arg (archive->process, tmp_archive_dir);
- fr_process_end_command (archive->process);
-
- g_free (tmp_archive_filename);
- g_free (archive_filename);
- g_free (tmp_archive_dir);
-}
-
-
-/* -- extract -- */
-
-
-static void
-move_files_to_dir (FrArchive *archive,
- GList *file_list,
- const char *source_dir,
- const char *dest_dir,
- gboolean overwrite)
-{
- GList *list;
- GList *scan;
-
- /* we prefer mv instead of cp for performance reasons,
- * but if the destination folder already exists mv
- * doesn't work correctly. (bug #590027) */
-
- list = g_list_copy (file_list);
- for (scan = list; scan; /* void */) {
- GList *next = scan->next;
- char *filename = scan->data;
- char *basename;
- char *destname;
-
- basename = g_path_get_basename (filename);
- destname = g_build_filename (dest_dir, basename, NULL);
- if (g_file_test (destname, G_FILE_TEST_IS_DIR)) {
- fr_process_begin_command (archive->process, "cp");
- fr_process_add_arg (archive->process, "-R");
- if (overwrite)
- fr_process_add_arg (archive->process, "-f");
- else
- fr_process_add_arg (archive->process, "-n");
- if (filename[0] == '/')
- fr_process_add_arg_concat (archive->process, source_dir, filename, NULL);
- else
- fr_process_add_arg_concat (archive->process, source_dir, "/", filename, NULL);
- fr_process_add_arg (archive->process, dest_dir);
- fr_process_end_command (archive->process);
-
- list = g_list_remove_link (list, scan);
- g_list_free (scan);
- }
-
- g_free (destname);
- g_free (basename);
-
- scan = next;
- }
-
- if (list == NULL)
- return;
-
- /* 'list' now contains the files that can be moved without problems */
-
- fr_process_begin_command (archive->process, "mv");
- if (overwrite)
- fr_process_add_arg (archive->process, "-f");
- else
- fr_process_add_arg (archive->process, "-n");
- for (scan = list; scan; scan = scan->next) {
- char *filename = scan->data;
-
- if (filename[0] == '/')
- fr_process_add_arg_concat (archive->process, source_dir, filename, NULL);
- else
- fr_process_add_arg_concat (archive->process, source_dir, "/", filename, NULL);
- }
- fr_process_add_arg (archive->process, dest_dir);
- fr_process_end_command (archive->process);
-
- g_list_free (list);
-}
+typedef struct {
+ FrArchive *archive;
+ char *source_dir;
+ char *dest_dir;
+ gboolean update;
+ char *password;
+ gboolean encrypt_header;
+ FrCompression compression;
+ guint volume_size;
+ GCancellable *cancellable;
+ GAsyncReadyCallback callback;
+ gpointer user_data;
+} AddWithWildcardData;
static void
-move_files_in_chunks (FrArchive *archive,
- GList *file_list,
- const char *temp_dir,
- const char *dest_dir,
- gboolean overwrite)
+add_with_wildcard_data_free (AddWithWildcardData *aww_data)
{
- GList *scan;
- int temp_dir_l;
-
- temp_dir_l = strlen (temp_dir);
-
- for (scan = file_list; scan != NULL; ) {
- GList *prev = scan->prev;
- GList *chunk_list;
- int l;
-
- chunk_list = scan;
- l = 0;
- while ((scan != NULL) && (l < MAX_CHUNK_LEN)) {
- if (l == 0)
- l = temp_dir_l + 1 + strlen (scan->data);
- prev = scan;
- scan = scan->next;
- if (scan != NULL)
- l += temp_dir_l + 1 + strlen (scan->data);
- }
-
- prev->next = NULL;
- move_files_to_dir (archive, chunk_list, temp_dir, dest_dir, overwrite);
- prev->next = scan;
- }
+ g_free (aww_data->source_dir);
+ g_free (aww_data->dest_dir);
+ g_free (aww_data->password);
+ _g_object_unref (aww_data->cancellable);
+ g_free (aww_data);
}
static void
-extract_from_archive (FrArchive *archive,
- GList *file_list,
- const char *dest_dir,
- gboolean overwrite,
- gboolean skip_older,
- gboolean junk_paths,
- const char *password)
-{
- FrCommand *command = archive->command;
- GList *scan;
-
- g_object_set (command, "password", password, NULL);
-
- if (file_list == NULL) {
- fr_command_extract (command,
- NULL,
- file_list,
- dest_dir,
- overwrite,
- skip_older,
- junk_paths);
- return;
- }
-
- if (command->propListFromFile
- && (g_list_length (file_list) > LIST_LENGTH_TO_USE_FILE))
- {
- char *list_dir;
- char *list_filename;
-
- if (save_list_to_temp_file (file_list, &list_dir, &list_filename, NULL)) {
- fr_command_extract (command,
- list_filename,
- file_list,
- dest_dir,
- overwrite,
- skip_older,
- junk_paths);
-
- /* remove the temp dir */
-
- fr_process_begin_command (archive->process, "rm");
- fr_process_set_working_dir (archive->process, g_get_tmp_dir());
- fr_process_set_sticky (archive->process, TRUE);
- fr_process_add_arg (archive->process, "-rf");
- fr_process_add_arg (archive->process, list_dir);
- fr_process_end_command (archive->process);
- }
-
- g_free (list_filename);
- g_free (list_dir);
- }
- else {
- for (scan = file_list; scan != NULL; ) {
- GList *prev = scan->prev;
- GList *chunk_list;
- int l;
-
- chunk_list = scan;
- l = 0;
- while ((scan != NULL) && (l < MAX_CHUNK_LEN)) {
- if (l == 0)
- l = strlen (scan->data);
- prev = scan;
- scan = scan->next;
- if (scan != NULL)
- l += strlen (scan->data);
- }
-
- prev->next = NULL;
- fr_command_extract (command,
- NULL,
- chunk_list,
- dest_dir,
- overwrite,
- skip_older,
- junk_paths);
- prev->next = scan;
- }
- }
-}
-
-
-static char*
-compute_base_path (const char *base_dir,
- const char *path,
- gboolean junk_paths,
- gboolean can_junk_paths)
+add_with_wildcard__step2 (GList *file_list,
+ GList *dirs_list,
+ GError *error,
+ gpointer data)
{
- int base_dir_len = strlen (base_dir);
- int path_len = strlen (path);
- const char *base_path;
- char *name_end;
- char *new_path;
-
- if (junk_paths) {
- if (can_junk_paths)
- new_path = g_strdup (_g_path_get_file_name (path));
- else
- new_path = g_strdup (path);
+ AddWithWildcardData *aww_data = data;
+ FrArchive *archive = aww_data->archive;
+ GSimpleAsyncResult *result;
- /*debug (DEBUG_INFO, "%s, %s --> %s\n", base_dir, path, new_path);*/
+ result = g_simple_async_result_new (G_OBJECT (archive),
+ aww_data->callback,
+ aww_data->user_data,
+ fr_archive_add_with_wildcard);
- return new_path;
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (result, error);
+ g_simple_async_result_complete_in_idle (result);
}
-
- if (path_len <= base_dir_len)
- return NULL;
-
- base_path = path + base_dir_len;
- if (path[0] != '/')
- base_path -= 1;
- name_end = strchr (base_path, '/');
-
- if (name_end == NULL)
- new_path = g_strdup (path);
else {
- int name_len = name_end - path;
- new_path = g_strndup (path, name_len);
- }
-
- /*debug (DEBUG_INFO, "%s, %s --> %s\n", base_dir, path, new_path);*/
-
- return new_path;
-}
-
-
-static GList*
-compute_list_base_path (const char *base_dir,
- GList *filtered,
- gboolean junk_paths,
- gboolean can_junk_paths)
-{
- GList *scan;
- GList *list = NULL, *list_unique = NULL;
- GList *last_inserted;
-
- if (filtered == NULL)
- return NULL;
-
- for (scan = filtered; scan; scan = scan->next) {
- const char *path = scan->data;
- char *new_path;
-
- new_path = compute_base_path (base_dir, path, junk_paths, can_junk_paths);
- if (new_path != NULL)
- list = g_list_prepend (list, new_path);
- }
-
- /* The above operation can create duplicates, we remove them here. */
- list = g_list_sort (list, (GCompareFunc)strcmp);
-
- last_inserted = NULL;
- for (scan = list; scan; scan = scan->next) {
- const char *path = scan->data;
-
- if (last_inserted != NULL) {
- const char *last_path = (const char*)last_inserted->data;
- if (strcmp (last_path, path) == 0) {
- g_free (scan->data);
- continue;
- }
- }
-
- last_inserted = scan;
- list_unique = g_list_prepend (list_unique, scan->data);
- }
-
- g_list_free (list);
-
- return list_unique;
-}
-
-
-static gboolean
-archive_type_has_issues_extracting_non_empty_folders (FrArchive *archive)
-{
- /*if ((archive->command->files == NULL) || (archive->command->files->len == 0))
- return FALSE; FIXME: test with extract_here */
- return ! archive->command->propCanExtractNonEmptyFolders;
-}
-
-
-static gboolean
-file_list_contains_files_in_this_dir (GList *file_list,
- const char *dirname)
-{
- GList *scan;
-
- for (scan = file_list; scan; scan = scan->next) {
- char *filename = scan->data;
-
- if (_g_path_is_parent_of (dirname, filename))
- return TRUE;
- }
-
- return FALSE;
-}
-
-
-static GList*
-remove_files_contained_in_this_dir (GList *file_list,
- GList *dir_pointer)
-{
- char *dirname = dir_pointer->data;
- int dirname_l = strlen (dirname);
- GList *scan;
-
- for (scan = dir_pointer->next; scan; /* empty */) {
- char *filename = scan->data;
-
- if (strncmp (dirname, filename, dirname_l) != 0)
- break;
-
- if (_g_path_is_parent_of (dirname, filename)) {
- GList *next = scan->next;
-
- file_list = g_list_remove_link (file_list, scan);
- g_list_free (scan);
-
- scan = next;
- }
+ if (file_list == NULL)
+ g_simple_async_result_complete_in_idle (result);
else
- scan = scan->next;
- }
-
- return file_list;
+ fr_archive_add_files (aww_data->archive,
+ file_list,
+ aww_data->source_dir,
+ aww_data->dest_dir,
+ aww_data->update,
+ FALSE,
+ aww_data->password,
+ aww_data->encrypt_header,
+ aww_data->compression,
+ aww_data->volume_size,
+ aww_data->cancellable,
+ aww_data->callback,
+ aww_data->user_data);
+ }
+
+ g_object_unref (result);
+ _g_string_list_free (file_list);
+ _g_string_list_free (dirs_list);
+ add_with_wildcard_data_free (aww_data);
}
void
-fr_archive_extract_to_local (FrArchive *archive,
- GList *file_list,
- const char *destination,
- const char *base_dir,
- gboolean skip_older,
- gboolean overwrite,
- gboolean junk_paths,
- const char *password)
+fr_archive_add_with_wildcard (FrArchive *archive,
+ const char *include_files,
+ const char *exclude_files,
+ const char *exclude_folders,
+ const char *source_dir,
+ const char *dest_dir,
+ gboolean update,
+ gboolean follow_links,
+ const char *password,
+ gboolean encrypt_header,
+ FrCompression compression,
+ guint volume_size,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
- GList *filtered;
- GList *scan;
- gboolean extract_all;
- gboolean use_base_dir;
- gboolean all_options_supported;
- gboolean move_to_dest_dir;
- gboolean file_list_created = FALSE;
+ AddWithWildcardData *aww_data;
- g_return_if_fail (archive != NULL);
+ g_return_if_fail (! archive->read_only);
- fr_archive_stoppable (archive, TRUE);
- g_object_set (archive->command, "file", archive->local_copy, NULL);
+ aww_data = g_new0 (AddWithWildcardData, 1);
+ aww_data->archive = archive;
+ aww_data->source_dir = g_strdup (source_dir);
+ aww_data->dest_dir = g_strdup (dest_dir);
+ aww_data->update = update;
+ aww_data->password = g_strdup (password);
+ aww_data->encrypt_header = encrypt_header;
+ aww_data->compression = compression;
+ aww_data->volume_size = volume_size;
+ aww_data->cancellable = _g_object_ref (cancellable);
+ aww_data->callback = callback;
+ aww_data->user_data = user_data;
- /* if a command supports all the requested options use
- * fr_command_extract directly. */
+ g_signal_emit (G_OBJECT (archive),
+ fr_archive_signals[START],
+ 0,
+ FR_ACTION_GETTING_FILE_LIST);
- use_base_dir = ! ((base_dir == NULL)
- || (strcmp (base_dir, "") == 0)
- || (strcmp (base_dir, "/") == 0));
+ g_directory_list_async (source_dir,
+ source_dir,
+ TRUE,
+ follow_links,
+ NO_BACKUP_FILES,
+ NO_DOT_FILES,
+ include_files,
+ exclude_files,
+ exclude_folders,
+ IGNORE_CASE,
+ aww_data->cancellable,
+ add_with_wildcard__step2,
+ aww_data);
+}
- all_options_supported = (! use_base_dir
- && ! (! overwrite && ! archive->command->propExtractCanAvoidOverwrite)
- && ! (skip_older && ! archive->command->propExtractCanSkipOlder)
- && ! (junk_paths && ! archive->command->propExtractCanJunkPaths));
- extract_all = (file_list == NULL);
- if (extract_all && (! all_options_supported || ! archive->command->propCanExtractAll)) {
- int i;
+/* -- fr_archive_add_directory -- */
- file_list = NULL;
- for (i = 0; i < archive->command->files->len; i++) {
- FileData *fdata = g_ptr_array_index (archive->command->files, i);
- file_list = g_list_prepend (file_list, g_strdup (fdata->original_path));
- }
- file_list_created = TRUE;
- }
- if (extract_all && (file_list == NULL))
- fr_command_set_n_files (archive->command, archive->command->n_regular_files);
- else
- fr_command_set_n_files (archive->command, g_list_length (file_list));
+typedef struct {
+ FrArchive *archive;
+ char *base_dir;
+ char *dest_dir;
+ gboolean update;
+ char *password;
+ gboolean encrypt_header;
+ FrCompression compression;
+ guint volume_size;
+ GCancellable *cancellable;
+ GAsyncReadyCallback callback;
+ gpointer user_data;
+} AddDirectoryData;
- if (all_options_supported) {
- gboolean created_filtered_list = FALSE;
- if (! extract_all && archive_type_has_issues_extracting_non_empty_folders (archive)) {
- created_filtered_list = TRUE;
- filtered = g_list_copy (file_list);
- filtered = g_list_sort (filtered, (GCompareFunc) strcmp);
- for (scan = filtered; scan; scan = scan->next)
- filtered = remove_files_contained_in_this_dir (filtered, scan);
- }
- else
- filtered = file_list;
+static void
+add_directory_data_free (AddDirectoryData *ad_data)
+{
+ g_free (ad_data->base_dir);
+ g_free (ad_data->dest_dir);
+ g_free (ad_data->password);
+ _g_object_unref (ad_data->cancellable);
+ g_free (ad_data);
+}
- if (! (created_filtered_list && (filtered == NULL)))
- extract_from_archive (archive,
- filtered,
- destination,
- overwrite,
- skip_older,
- junk_paths,
- password);
- if (created_filtered_list && (filtered != NULL))
- g_list_free (filtered);
+static void
+add_directory__step2 (GList *file_list,
+ GList *dir_list,
+ GError *error,
+ gpointer user_data)
+{
+ AddDirectoryData *ad_data = user_data;
+ FrArchive *archive = ad_data->archive;
+ GSimpleAsyncResult *result;
- if (file_list_created)
- _g_string_list_free (file_list);
+ result = g_simple_async_result_new (G_OBJECT (archive),
+ ad_data->callback,
+ ad_data->user_data,
+ fr_archive_add_directory);
- return;
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (result, error);
+ g_simple_async_result_complete_in_idle (result);
}
+ else {
+ if (archive->propAddCanStoreFolders)
+ file_list = g_list_concat (file_list, dir_list);
+ else
+ _g_string_list_free (dir_list);
- /* .. else we have to implement the unsupported options. */
+ if (file_list == NULL)
+ g_simple_async_result_complete_in_idle (result);
+ else
+ fr_archive_add_files (ad_data->archive,
+ file_list,
+ ad_data->base_dir,
+ ad_data->dest_dir,
+ ad_data->update,
+ FALSE,
+ ad_data->password,
+ ad_data->encrypt_header,
+ ad_data->compression,
+ ad_data->volume_size,
+ ad_data->cancellable,
+ ad_data->callback,
+ ad_data->user_data);
+ }
+
+ g_object_unref (result);
+ _g_string_list_free (file_list);
+ _g_string_list_free (dir_list);
+ add_directory_data_free (ad_data);
+}
- move_to_dest_dir = (use_base_dir
- || ((junk_paths
- && ! archive->command->propExtractCanJunkPaths)));
- if (extract_all && ! file_list_created) {
- int i;
+void
+fr_archive_add_directory (FrArchive *archive,
+ const char *directory,
+ const char *base_dir,
+ const char *dest_dir,
+ gboolean update,
+ const char *password,
+ gboolean encrypt_header,
+ FrCompression compression,
+ guint volume_size,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
- file_list = NULL;
- for (i = 0; i < archive->command->files->len; i++) {
- FileData *fdata = g_ptr_array_index (archive->command->files, i);
- file_list = g_list_prepend (file_list, g_strdup (fdata->original_path));
- }
+{
+ AddDirectoryData *ad_data;
- file_list_created = TRUE;
- }
+ g_return_if_fail (! archive->read_only);
- filtered = NULL;
- for (scan = file_list; scan; scan = scan->next) {
- FileData *fdata;
- char *archive_list_filename = scan->data;
- char dest_filename[4096];
- const char *filename;
+ ad_data = g_new0 (AddDirectoryData, 1);
+ ad_data->archive = archive;
+ ad_data->base_dir = g_strdup (base_dir);
+ ad_data->dest_dir = g_strdup (dest_dir);
+ ad_data->update = update;
+ ad_data->password = g_strdup (password);
+ ad_data->encrypt_header = encrypt_header;
+ ad_data->compression = compression;
+ ad_data->volume_size = volume_size;
+ ad_data->cancellable = _g_object_ref (cancellable);
+ ad_data->callback = callback;
+ ad_data->user_data = user_data;
- fdata = find_file_in_archive (archive, archive_list_filename);
+ g_signal_emit (G_OBJECT (archive),
+ fr_archive_signals[START],
+ 0,
+ FR_ACTION_GETTING_FILE_LIST);
- if (fdata == NULL)
- continue;
+ g_directory_list_all_async (directory,
+ base_dir,
+ TRUE,
+ cancellable,
+ add_directory__step2,
+ ad_data);
+}
- if (archive_type_has_issues_extracting_non_empty_folders (archive)
- && fdata->dir
- && file_list_contains_files_in_this_dir (file_list, archive_list_filename))
- continue;
- /* get the destination file path. */
+void
+fr_archive_add_items (FrArchive *archive,
+ GList *item_list,
+ const char *base_dir,
+ const char *dest_dir,
+ gboolean update,
+ const char *password,
+ gboolean encrypt_header,
+ FrCompression compression,
+ guint volume_size,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
- if (! junk_paths)
- filename = archive_list_filename;
- else
- filename = _g_path_get_file_name (archive_list_filename);
+{
+ AddDirectoryData *ad_data;
- if ((destination[strlen (destination) - 1] == '/')
- || (filename[0] == '/'))
- sprintf (dest_filename, "%s%s", destination, filename);
- else
- sprintf (dest_filename, "%s/%s", destination, filename);
+ g_return_if_fail (! archive->read_only);
- /*debug (DEBUG_INFO, "-> %s\n", dest_filename);*/
+ ad_data = g_new0 (AddDirectoryData, 1);
+ ad_data->archive = archive;
+ ad_data->base_dir = g_strdup (base_dir);
+ ad_data->dest_dir = g_strdup (dest_dir);
+ ad_data->update = update;
+ ad_data->password = g_strdup (password);
+ ad_data->encrypt_header = encrypt_header;
+ ad_data->compression = compression;
+ ad_data->volume_size = volume_size;
+ ad_data->cancellable = _g_object_ref (cancellable);
+ ad_data->callback = callback;
+ ad_data->user_data = user_data;
- /**/
+ g_signal_emit (G_OBJECT (archive),
+ fr_archive_signals[START],
+ 0,
+ FR_ACTION_GETTING_FILE_LIST);
- if (! archive->command->propExtractCanSkipOlder
- && skip_older
- && g_file_test (dest_filename, G_FILE_TEST_EXISTS)
- && (fdata->modified < _g_path_get_file_mtime (dest_filename)))
- continue;
+ g_list_items_async (item_list,
+ base_dir,
+ cancellable,
+ add_directory__step2,
+ ad_data);
+}
- if (! archive->command->propExtractCanAvoidOverwrite
- && ! overwrite
- && g_file_test (dest_filename, G_FILE_TEST_EXISTS))
- continue;
- filtered = g_list_prepend (filtered, fdata->original_path);
- }
+void
+fr_archive_remove (FrArchive *archive,
+ GList *file_list,
+ FrCompression compression,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_return_if_fail (! archive->read_only);
- if (filtered == NULL) {
- /* all files got filtered, do nothing. */
- debug (DEBUG_INFO, "All files got filtered, nothing to do.\n");
+ FR_ARCHIVE_GET_CLASS (archive)->remove_files (archive,
+ file_list,
+ compression,
+ cancellable,
+ callback,
+ user_data);
+}
- if (extract_all)
- _g_string_list_free (file_list);
- return;
- }
- if (move_to_dest_dir) {
- char *temp_dir;
-
- temp_dir = _g_path_get_temp_work_dir (destination);
- extract_from_archive (archive,
- filtered,
- temp_dir,
- overwrite,
- skip_older,
- junk_paths,
- password);
-
- if (use_base_dir) {
- GList *tmp_list = compute_list_base_path (base_dir, filtered, junk_paths, archive->command->propExtractCanJunkPaths);
- g_list_free (filtered);
- filtered = tmp_list;
- }
+void
+fr_archive_extract (FrArchive *self,
+ GList *file_list,
+ const char *destination,
+ const char *base_dir,
+ gboolean skip_older,
+ gboolean overwrite,
+ gboolean junk_paths,
+ const char *password,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_free (self->priv->extraction_destination);
+ self->priv->extraction_destination = g_strdup (destination);
+
+ FR_ARCHIVE_GET_CLASS (self)->extract_files (self,
+ file_list,
+ destination,
+ base_dir,
+ skip_older,
+ overwrite,
+ junk_paths,
+ password,
+ cancellable,
+ callback,
+ user_data);
+}
- move_files_in_chunks (archive,
- filtered,
- temp_dir,
- destination,
- overwrite);
- /* remove the temp dir. */
+void
+fr_archive_extract_to_local (FrArchive *self,
+ GList *file_list,
+ const char *destination_path,
+ const char *base_dir,
+ gboolean skip_older,
+ gboolean overwrite,
+ gboolean junk_paths,
+ const char *password,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ char *destination_uri;
+
+ destination_uri = g_filename_to_uri (destination_path, NULL, NULL);
+ if (destination_uri == NULL)
+ return;
- fr_process_begin_command (archive->process, "rm");
- fr_process_add_arg (archive->process, "-rf");
- fr_process_add_arg (archive->process, temp_dir);
- fr_process_end_command (archive->process);
+ fr_archive_extract (self,
+ file_list,
+ destination_uri,
+ base_dir,
+ skip_older,
+ overwrite,
+ junk_paths,
+ password,
+ cancellable,
+ callback,
+ user_data);
- g_free (temp_dir);
- }
- else
- extract_from_archive (archive,
- filtered,
- destination,
- overwrite,
- skip_older,
- junk_paths,
- password);
-
- if (filtered != NULL)
- g_list_free (filtered);
- if (file_list_created)
- _g_string_list_free (file_list);
+ g_free (destination_uri);
}
-void
-fr_archive_extract (FrArchive *archive,
- GList *file_list,
- const char *destination,
- const char *base_dir,
- gboolean skip_older,
- gboolean overwrite,
- gboolean junk_paths,
- const char *password)
-{
- g_free (archive->priv->extraction_destination);
- archive->priv->extraction_destination = g_strdup (destination);
-
- g_free (archive->priv->temp_extraction_dir);
- archive->priv->temp_extraction_dir = NULL;
-
- archive->priv->remote_extraction = ! _g_uri_is_local (destination);
- if (archive->priv->remote_extraction) {
- archive->priv->temp_extraction_dir = _g_path_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);
- }
-}
+/* -- fr_archive_extract_here -- */
static char *
@@ -3301,7 +1354,8 @@ get_extract_here_destination (GFile *file,
g_object_unref (directory);
n++;
- } while (g_error_matches (*error, G_IO_ERROR, G_IO_ERROR_EXISTS));
+ }
+ while (g_error_matches (*error, G_IO_ERROR, G_IO_ERROR_EXISTS));
g_free (desired_destination);
@@ -3316,26 +1370,35 @@ get_extract_here_destination (GFile *file,
gboolean
-fr_archive_extract_here (FrArchive *archive,
- gboolean skip_older,
- gboolean overwrite,
- gboolean junk_path,
- const char *password)
+fr_archive_extract_here (FrArchive *archive,
+ gboolean skip_older,
+ gboolean overwrite,
+ gboolean junk_path,
+ const char *password,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
char *destination;
GError *error = NULL;
- destination = get_extract_here_destination (archive->file, &error);
+ destination = get_extract_here_destination (archive->priv->file, &error);
if (error != NULL) {
- fr_archive_action_completed (archive,
- FR_ACTION_EXTRACTING_FILES,
- FR_PROC_ERROR_GENERIC,
- error->message);
- g_clear_error (&error);
+ GSimpleAsyncResult *result;
+
+ result = g_simple_async_result_new (G_OBJECT (archive),
+ callback,
+ user_data,
+ fr_archive_extract_here);
+ g_simple_async_result_set_from_error (result, error);
+ g_simple_async_result_complete_in_idle (result);
+
+ g_error_free (error);
+
return FALSE;
}
- archive->priv->extract_here = TRUE;
+ archive->extract_here = TRUE;
fr_archive_extract (archive,
NULL,
destination,
@@ -3343,7 +1406,10 @@ fr_archive_extract_here (FrArchive *archive,
skip_older,
overwrite,
junk_path,
- password);
+ password,
+ cancellable,
+ callback,
+ user_data);
g_free (destination);
@@ -3351,6 +1417,20 @@ fr_archive_extract_here (FrArchive *archive,
}
+void
+fr_archive_set_last_extraction_destination (FrArchive *archive,
+ const char *uri)
+{
+ if (uri == archive->priv->extraction_destination)
+ return;
+
+ g_free (archive->priv->extraction_destination);
+ archive->priv->extraction_destination = NULL;
+ if (uri != NULL)
+ archive->priv->extraction_destination = g_strdup (uri);
+}
+
+
const char *
fr_archive_get_last_extraction_destination (FrArchive *archive)
{
@@ -3359,33 +1439,287 @@ fr_archive_get_last_extraction_destination (FrArchive *archive)
void
-fr_archive_test (FrArchive *archive,
- const char *password)
+fr_archive_test (FrArchive *archive,
+ const char *password,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ FR_ARCHIVE_GET_CLASS (archive)->test_integrity (archive,
+ password,
+ cancellable,
+ callback,
+ user_data);
+}
+
+
+void
+fr_archive_rename (FrArchive *archive,
+ GList *file_list,
+ const char *old_name,
+ const char *new_name,
+ const char *current_dir,
+ gboolean is_dir,
+ gboolean dir_in_archive,
+ const char *original_path,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ FR_ARCHIVE_GET_CLASS (archive)->rename (archive,
+ file_list,
+ old_name,
+ new_name,
+ current_dir,
+ is_dir,
+ dir_in_archive,
+ original_path,
+ cancellable,
+ callback,
+ user_data);
+}
+
+
+void
+fr_archive_paste_clipboard (FrArchive *archive,
+ char *archive_uri,
+ char *password,
+ gboolean encrypt_header,
+ FrCompression compression,
+ guint volume_size,
+ FrClipboardOp op,
+ char *base_dir,
+ GList *files,
+ char *tmp_dir,
+ char *current_dir,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ FR_ARCHIVE_GET_CLASS (archive)->paste_clipboard (archive,
+ archive_uri,
+ password,
+ encrypt_header,
+ compression,
+ volume_size,
+ op,
+ base_dir,
+ files,
+ tmp_dir,
+ current_dir,
+ cancellable,
+ callback,
+ user_data);
+}
+
+
+void
+fr_archive_add_dropped_items (FrArchive *archive,
+ GList *item_list,
+ const char *base_dir,
+ const char *dest_dir,
+ gboolean update,
+ const char *password,
+ gboolean encrypt_header,
+ FrCompression compression,
+ guint volume_size,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *result;
+ GList *scan;
+ char *archive_uri;
+
+ result = g_simple_async_result_new (G_OBJECT (archive),
+ callback,
+ user_data,
+ fr_archive_add_dropped_items);
+
+ if (archive->read_only) {
+ GError *error;
+
+ error = g_error_new_literal (FR_ERROR, FR_ERROR_GENERIC, ! archive->priv->have_write_permissions ? _("You don't have the right permissions.") : _("This archive type cannot be modified"));
+ g_simple_async_result_set_from_error (result, error);
+ g_simple_async_result_complete_in_idle (result);
+
+ g_error_free (error);
+ return;
+ }
+
+ /* FIXME: make this check for all the add actions */
+ archive_uri = g_file_get_uri (archive->priv->file);
+ for (scan = item_list; scan; scan = scan->next) {
+ if (_g_uri_cmp (scan->data, archive_uri) == 0) {
+ GError *error;
+
+ error = g_error_new_literal (FR_ERROR, FR_ERROR_GENERIC, _("You can't add an archive to itself."));
+ g_simple_async_result_set_from_error (result, error);
+ g_simple_async_result_complete_in_idle (result);
+
+ g_error_free (error);
+ g_free (archive_uri);
+ return;
+ }
+ }
+ g_free (archive_uri);
+
+ FR_ARCHIVE_GET_CLASS (archive)->add_dropped_items (archive,
+ item_list,
+ base_dir,
+ dest_dir,
+ update,
+ password,
+ encrypt_header,
+ compression,
+ volume_size,
+ cancellable,
+ callback,
+ user_data);
+}
+
+
+void
+fr_archive_update_open_files (FrArchive *archive,
+ GList *file_list,
+ GList *dir_list,
+ const char *password,
+ gboolean encrypt_header,
+ FrCompression compression,
+ guint volume_size,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ FR_ARCHIVE_GET_CLASS (archive)->update_open_files (archive,
+ file_list,
+ dir_list,
+ password,
+ encrypt_header,
+ compression,
+ volume_size,
+ cancellable,
+ callback,
+ user_data);
+}
+
+
+void
+fr_archive_set_multi_volume (FrArchive *self,
+ GFile *file)
+{
+ self->multi_volume = TRUE;
+ _fr_archive_set_file (self, file);
+}
+
+
+void
+fr_archive_change_name (FrArchive *archive,
+ const char *filename)
+{
+ const char *name;
+ GFile *parent;
+ GFile *file;
+
+ name = _g_path_get_file_name (filename);
+
+ parent = g_file_get_parent (archive->priv->file);
+ file = g_file_get_child (parent, name);;
+ _fr_archive_set_file (archive, file);
+
+ g_object_unref (parent);
+ g_object_unref (file);
+}
+
+
+GCancellable *
+fr_archive_get_cancellable (FrArchive *self)
+{
+ return self->priv->cancellable;
+}
+
+
+void
+fr_archive_action_started (FrArchive *self,
+ FrAction action)
+{
+ g_signal_emit (self,
+ fr_archive_signals[START],
+ 0,
+ action);
+}
+
+
+/* fraction == -1 means : I don't known how much time the current operation
+ * will take, the dialog will display this info pulsing
+ * the progress bar.
+ * fraction in [0.0, 1.0] means the amount of work, in percentage,
+ * accomplished.
+ */
+void
+fr_archive_progress (FrArchive *self,
+ double fraction)
+{
+ g_signal_emit (self,
+ fr_archive_signals[PROGRESS],
+ 0,
+ fraction);
+}
+
+
+void
+fr_archive_message (FrArchive *self,
+ const char *msg)
+{
+ g_signal_emit (self,
+ fr_archive_signals[MESSAGE],
+ 0,
+ msg);
+}
+
+
+void
+fr_archive_working_archive (FrArchive *self,
+ const char *archive_name)
+{
+ g_signal_emit (self,
+ fr_archive_signals[WORKING_ARCHIVE],
+ 0,
+ archive_name);
+}
+
+
+void
+fr_archive_set_n_files (FrArchive *self,
+ int n_files)
{
- fr_archive_stoppable (archive, TRUE);
-
- g_object_set (archive->command,
- "file", archive->local_copy,
- "password", password,
- NULL);
- fr_process_clear (archive->process);
- fr_command_set_n_files (archive->command, 0);
- fr_command_test (archive->command);
- fr_process_start (archive->process);
+ self->n_files = n_files;
+ self->n_file = 0;
}
+void
+fr_archive_add_file (FrArchive *self,
+ FileData *file_data)
+{
+ file_data_update_content_type (file_data);
+ g_ptr_array_add (self->files, file_data);
+ if (! file_data->dir)
+ self->n_regular_files++;
+}
+
+
+/* FIXME: use sniffer as in fr_archive_open */
gboolean
_g_uri_is_archive (const char *uri)
{
GFile *file;
- const char *mime_type;
+ const char *mime_type = NULL;
gboolean is_archive = FALSE;
file = g_file_new_for_uri (uri);
- mime_type = get_mime_type_from_magic_numbers (file);
- if (mime_type == NULL)
- mime_type = get_mime_type_from_content (file);
+ /* FIXME: libarchive
+ mime_type = get_mime_type_from_magic_numbers (file); */
if (mime_type == NULL)
mime_type = get_mime_type_from_filename (file);
diff --git a/src/fr-archive.h b/src/fr-archive.h
index 604977e..af7c256 100644
--- a/src/fr-archive.h
+++ b/src/fr-archive.h
@@ -3,7 +3,7 @@
/*
* File-Roller
*
- * Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2003, 2012 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,8 +23,32 @@
#define FR_ARCHIVE_H
#include <glib.h>
-#include "fr-process.h"
-#include "fr-command.h"
+#include "file-data.h"
+#include "typedefs.h"
+
+typedef enum {
+ FR_ACTION_NONE,
+ FR_ACTION_CREATING_NEW_ARCHIVE,
+ FR_ACTION_LOADING_ARCHIVE, /* loading the archive from a remote location */
+ FR_ACTION_LISTING_CONTENT, /* listing the content of the archive */
+ FR_ACTION_DELETING_FILES, /* deleting files from the archive */
+ FR_ACTION_TESTING_ARCHIVE, /* testing the archive integrity */
+ FR_ACTION_GETTING_FILE_LIST, /* getting the file list (when fr_archive_add_with_wildcard or
+ fr_archive_add_directory are used, we need to scan a directory
+ and collect the files to add to the archive, this
+ may require some time to complete, so the operation
+ is asynchronous) */
+ FR_ACTION_COPYING_FILES_FROM_REMOTE, /* copying files to be added to the archive from a remote location */
+ FR_ACTION_ADDING_FILES, /* adding files to an archive */
+ FR_ACTION_EXTRACTING_FILES, /* extracting files */
+ FR_ACTION_COPYING_FILES_TO_REMOTE, /* copying extracted files to a remote location */
+ FR_ACTION_CREATING_ARCHIVE, /* creating a local archive */
+ FR_ACTION_SAVING_REMOTE_ARCHIVE /* copying the archive to a remote location */
+} FrAction;
+
+#ifdef DEBUG
+extern char *action_names[];
+#endif
#define FR_TYPE_ARCHIVE (fr_archive_get_type ())
#define FR_ARCHIVE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FR_TYPE_ARCHIVE, FrArchive))
@@ -35,176 +59,452 @@
typedef struct _FrArchive FrArchive;
typedef struct _FrArchiveClass FrArchiveClass;
-typedef struct _FrArchivePrivData FrArchivePrivData;
+typedef struct _FrArchivePrivate FrArchivePrivate;
typedef gboolean (*FakeLoadFunc) (FrArchive *archive, gpointer data);
struct _FrArchive {
GObject __parent;
+ FrArchivePrivate *priv;
+
+ /*<public, read only>*/
+
+ const char *mime_type;
+ GPtrArray *files; /* Array of FileData* */
+ int n_regular_files;
+
+ /*<public>*/
+
+ char *password;
+ gboolean encrypt_header : 1;
+ FrCompression compression;
+ gboolean multi_volume;
+ guint volume_size;
+ gboolean read_only; /* Whether archive is
+ * read-only for whatever
+ * reason. */
+
+ /*<protected>*/
+
+ /* FIXME: remove this two attributes */
+ FrAction action; /* current action. */
+ gboolean extract_here;
+
+ /* progress data */
+
+ int n_file;
+ int n_files;
+
+ /* features. */
+
+ /* propAddCanReplace:
+ *
+ * TRUE if the command can overwrite a file in the archive.
+ */
+ guint propAddCanReplace : 1;
+
+ /* propAddCanReplace:
+ *
+ * TRUE if the command can overwrite a file in the archive if older
+ * then the file on disk.
+ */
+ guint propAddCanUpdate : 1;
+
+ /* propAddCanStoreFolders:
+ *
+ * TRUE if the command can store folder entries inside the archive.
+ */
+ guint propAddCanStoreFolders : 1;
- GFile *file;
- GFile *local_copy;
- gboolean is_remote;
- const char *content_type;
- FrCommand *command;
- FrProcess *process;
- FrProcError error;
- gboolean can_create_compressed_file;
- gboolean is_compressed_file; /* Whether the file is not an
- * archive that can contain
- * many files but simply a
- * compressed file, for
- * example foo.txt.gz is a
- * compressed file, foo.zip
- * is not. */
- gboolean read_only; /* Whether archive is
- * read-only for whatever
- * reason. */
- gboolean have_permissions; /* true if we have the
- * permissions to write the
- * file. */
-
- FrArchivePrivData *priv;
+ /* propExtractCanAvoidOverwrite:
+ *
+ * TRUE if the command can avoid to overwrite the files on disk.
+ */
+ guint propExtractCanAvoidOverwrite : 1;
+
+ /* propExtractCanSkipOlder:
+ *
+ * TRUE if the command can avoid to overwrite a file on disk when it is
+ * newer than the file in the archive.
+ */
+ guint propExtractCanSkipOlder : 1;
+
+ /* propExtractCanJunkPaths:
+ *
+ * TRUE if the command can extract the files in the current folder
+ * without recreating the directory structure.
+ */
+ guint propExtractCanJunkPaths : 1;
+
+ /* propPassword:
+ *
+ * TRUE if the command can use passwords for adding or extracting files.
+ */
+ guint propPassword : 1;
+
+ /* propTest:
+ *
+ * TRUE if the command can test the archive integrity.
+ */
+ guint propTest : 1;
+
+ /* propCanExtractAll:
+ *
+ * TRUE if the command extract all the files when no file is specified.
+ */
+ guint propCanExtractAll : 1;
+
+ /* propCanDeleteNonEmptyFolders:
+ *
+ * is used to overcome an issue with tar, that deletes only the folder
+ * entry in the archive instead of deleting the folder content
+ * recursively.
+ */
+ guint propCanDeleteNonEmptyFolders : 1;
+
+ /* propCanExtractNonEmptyFolders:
+ *
+ * is used to overcome an issue with tar. For example if
+ * the content of a tar archive is
+ *
+ * readme.txt
+ * doc/
+ * doc/page1.html
+ * doc/page2.html
+ *
+ * and we want to extract the content of the doc folder, the command:
+ *
+ * tar -xf archive.tar doc doc/page1.html doc/page2.html
+ *
+ * gives an error.
+ * To fix the issue we have to remove the files inside the doc
+ * folder from the command line, getting the following command:
+ *
+ * tar -xf archive.tar doc
+ */
+ guint propCanExtractNonEmptyFolders : 1;
+
+ /* propListFromFile:
+ *
+ * if TRUE the command has an option to read the file list from a file
+ */
+ guint propListFromFile : 1;
};
struct _FrArchiveClass {
GObjectClass __parent_class;
- /* -- Signals -- */
-
- void (*start) (FrArchive *archive,
- FrAction action);
- void (*done) (FrArchive *archive,
- FrAction action,
- FrProcError *error);
- void (*progress) (FrArchive *archive,
- double fraction);
- void (*message) (FrArchive *archive,
- const char *msg);
- void (*stoppable) (FrArchive *archive,
- gboolean value);
- void (*working_archive) (FrCommand *comm,
- const char *filename);
+ /*< signals >*/
+
+ void (*start) (FrArchive *archive,
+ FrAction action);
+ void (*progress) (FrArchive *archive,
+ double fraction);
+ void (*message) (FrArchive *archive,
+ const char *msg);
+ void (*stoppable) (FrArchive *archive,
+ gboolean value);
+ void (*working_archive) (FrArchive *archive,
+ const char *filename);
+
+ /*< virtual functions >*/
+
+ const char ** (*get_mime_types) (FrArchive *archive);
+ FrArchiveCap (*get_capabilities) (FrArchive *archive,
+ const char *mime_type,
+ gboolean check_command);
+ void (*set_mime_type) (FrArchive *archive,
+ const char *mime_type);
+ const char * (*get_packages) (FrArchive *archive,
+ const char *mime_type);
+ void (*load) (FrArchive *archive,
+ const char *password,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ void (*add_files) (FrArchive *archive,
+ GList *file_list,
+ const char *base_dir,
+ const char *dest_dir,
+ gboolean update,
+ gboolean recursive,
+ const char *password,
+ gboolean encrypt_header,
+ FrCompression compression,
+ guint volume_size,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ void (*extract_files) (FrArchive *archive,
+ GList *file_list,
+ const char *destination,
+ const char *base_dir,
+ gboolean skip_older,
+ gboolean overwrite,
+ gboolean junk_paths,
+ const char *password,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ void (*remove_files) (FrArchive *archive,
+ GList *file_list,
+ FrCompression compression,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ void (*test_integrity) (FrArchive *archive,
+ const char *password,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ void (*rename) (FrArchive *archive,
+ GList *file_list,
+ const char *old_name,
+ const char *new_name,
+ const char *current_dir,
+ gboolean is_dir,
+ gboolean dir_in_archive,
+ const char *original_path,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ void (*paste_clipboard) (FrArchive *archive,
+ char *archive_uri,
+ char *password,
+ gboolean encrypt_header,
+ FrCompression compression,
+ guint volume_size,
+ FrClipboardOp op,
+ char *base_dir,
+ GList *files,
+ char *tmp_dir,
+ char *current_dir,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ void (*add_dropped_items) (FrArchive *archive,
+ GList *item_list,
+ const char *base_dir,
+ const char *dest_dir,
+ gboolean update,
+ const char *password,
+ gboolean encrypt_header,
+ FrCompression compression,
+ guint volume_size,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ void (*update_open_files) (FrArchive *archive,
+ GList *file_list,
+ GList *dir_list,
+ const char *password,
+ gboolean encrypt_header,
+ FrCompression compression,
+ guint volume_size,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
};
-GType fr_archive_get_type (void);
-FrArchive * fr_archive_new (void);
-void fr_archive_set_fake_load_func (FrArchive *archive,
- FakeLoadFunc func,
- gpointer data);
-gboolean fr_archive_fake_load (FrArchive *archive);
-void fr_archive_stoppable (FrArchive *archive,
- gboolean stoppable);
-void fr_archive_stop (FrArchive *archive);
-void fr_archive_action_completed (FrArchive *archive,
- FrAction action,
- FrProcErrorType error_type,
- const char *error_details);
-
-/**/
-
-gboolean fr_archive_create (FrArchive *archive,
- const char *uri);
-gboolean fr_archive_load (FrArchive *archive,
- const char *uri,
- const char *password);
-void fr_archive_reload (FrArchive *archive,
- const char *password);
-
-/**/
-
-void fr_archive_add (FrArchive *archive,
- GList *file_list,
- const char *base_dir,
- const char *dest_dir,
- gboolean update,
- gboolean recursive,
- const char *password,
- gboolean encrypt_header,
- FrCompression compression,
- guint volume_size);
-void fr_archive_remove (FrArchive *archive,
- GList *file_list,
- FrCompression compression);
-void fr_archive_extract (FrArchive *archive,
- GList *file_list,
- const char *dest_uri,
- const char *base_dir,
- gboolean skip_older,
- gboolean overwrite,
- gboolean junk_path,
- const char *password);
-void fr_archive_extract_to_local (FrArchive *archive,
- GList *file_list,
- const char *dest_path,
- const char *base_dir,
- gboolean skip_older,
- gboolean overwrite,
- gboolean junk_path,
- const char *password);
-gboolean fr_archive_extract_here (FrArchive *archive,
- gboolean skip_older,
- gboolean overwrite,
- gboolean junk_path,
- const char *password);
-const char *fr_archive_get_last_extraction_destination
- (FrArchive *archive);
-
-/**/
-
-void fr_archive_add_files (FrArchive *archive,
- GList *file_list,
- const char *base_dir,
- const char *dest_dir,
- gboolean update,
- const char *password,
- gboolean encrypt_header,
- FrCompression compression,
- guint volume_size);
-void fr_archive_add_with_wildcard (FrArchive *archive,
- const char *include_files,
- const char *exclude_files,
- const char *exclude_folders,
- const char *base_dir,
- const char *dest_dir,
- gboolean update,
- gboolean follow_links,
- const char *password,
- gboolean encrypt_header,
- FrCompression compression,
- guint volume_size);
-void fr_archive_add_directory (FrArchive *archive,
- const char *directory,
- const char *base_dir,
- const char *dest_dir,
- gboolean update,
- const char *password,
- gboolean encrypt_header,
- FrCompression compression,
- guint volume_size);
-void fr_archive_add_items (FrArchive *archive,
- GList *item_list,
- const char *base_dir,
- const char *dest_dir,
- gboolean update,
- const char *password,
- gboolean encrypt_header,
- FrCompression compression,
- guint volume_size);
-void fr_archive_add_dropped_items (FrArchive *archive,
- GList *item_list,
- const char *base_dir,
- const char *dest_dir,
- gboolean update,
- const char *password,
- gboolean encrypt_header,
- FrCompression compression,
- guint volume_size);
-void fr_archive_test (FrArchive *archive,
- const char *password);
+GType fr_archive_get_type (void);
+GFile * fr_archive_get_file (FrArchive *archive);
+gboolean fr_archive_is_capable_of (FrArchive *archive,
+ FrArchiveCaps capabilities);
+const char ** fr_archive_get_mime_types (FrArchive *archive);
+void fr_archive_update_capabilities (FrArchive *archive);
+FrArchiveCap fr_archive_get_capabilities (FrArchive *archive,
+ const char *mime_type,
+ gboolean check_command);
+void fr_archive_set_mime_type (FrArchive *archive,
+ const char *mime_type);
+const char * fr_archive_get_packages (FrArchive *archive,
+ const char *mime_type);
+void fr_archive_set_stoppable (FrArchive *archive,
+ gboolean stoppable);
+FrArchive * fr_archive_create (GFile *file);
+void fr_archive_open (GFile *file,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+FrArchive * fr_archive_open_finish (GFile *file,
+ GAsyncResult *result,
+ GError **error);
+void fr_archive_load (FrArchive *archive,
+ const char *password,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean fr_archive_operation_finish (FrArchive *archive,
+ GAsyncResult *result,
+ GError **error);
+void fr_archive_add_files (FrArchive *archive,
+ GList *file_list,
+ const char *base_dir,
+ const char *dest_dir,
+ gboolean update,
+ gboolean recursive,
+ const char *password,
+ gboolean encrypt_header,
+ FrCompression compression,
+ guint volume_size,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+void fr_archive_add_with_wildcard (FrArchive *archive,
+ const char *include_files,
+ const char *exclude_files,
+ const char *exclude_folders,
+ const char *base_dir,
+ const char *dest_dir,
+ gboolean update,
+ gboolean follow_links,
+ const char *password,
+ gboolean encrypt_header,
+ FrCompression compression,
+ guint volume_size,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+void fr_archive_add_directory (FrArchive *archive,
+ const char *directory,
+ const char *base_dir,
+ const char *dest_dir,
+ gboolean update,
+ const char *password,
+ gboolean encrypt_header,
+ FrCompression compression,
+ guint volume_size,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+void fr_archive_add_items (FrArchive *archive,
+ GList *item_list,
+ const char *base_dir,
+ const char *dest_dir,
+ gboolean update,
+ const char *password,
+ gboolean encrypt_header,
+ FrCompression compression,
+ guint volume_size,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+void fr_archive_remove (FrArchive *archive,
+ GList *file_list,
+ FrCompression compression,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+void fr_archive_extract (FrArchive *archive,
+ GList *file_list,
+ const char *dest_uri,
+ const char *base_dir,
+ gboolean skip_older,
+ gboolean overwrite,
+ gboolean junk_path,
+ const char *password,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+void fr_archive_extract_to_local (FrArchive *archive,
+ GList *file_list,
+ const char *dest_path,
+ const char *base_dir,
+ gboolean skip_older,
+ gboolean overwrite,
+ gboolean junk_path,
+ const char *password,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean fr_archive_extract_here (FrArchive *archive,
+ gboolean skip_older,
+ gboolean overwrite,
+ gboolean junk_path,
+ const char *password,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+void fr_archive_set_last_extraction_destination
+ (FrArchive *archive,
+ const char *uri);
+const char * fr_archive_get_last_extraction_destination
+ (FrArchive *archive);
+void fr_archive_test (FrArchive *archive,
+ const char *password,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+void fr_archive_rename (FrArchive *archive,
+ GList *file_list,
+ const char *old_name,
+ const char *new_name,
+ const char *current_dir,
+ gboolean is_dir,
+ gboolean dir_in_archive,
+ const char *original_path,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+void fr_archive_paste_clipboard (FrArchive *archive,
+ char *archive_uri,
+ char *password,
+ gboolean encrypt_header,
+ FrCompression compression,
+ guint volume_size,
+ FrClipboardOp op,
+ char *base_dir,
+ GList *files,
+ char *tmp_dir,
+ char *current_dir,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+void fr_archive_add_dropped_items (FrArchive *archive,
+ GList *item_list,
+ const char *base_dir,
+ const char *dest_dir,
+ gboolean update,
+ const char *password,
+ gboolean encrypt_header,
+ FrCompression compression,
+ guint volume_size,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+void fr_archive_update_open_files (FrArchive *archive,
+ GList *file_list,
+ GList *dir_list,
+ const char *password,
+ gboolean encrypt_header,
+ FrCompression compression,
+ guint volume_size,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+/* protected */
+
+void fr_archive_set_multi_volume (FrArchive *archive,
+ GFile *file);
+void fr_archive_change_name (FrArchive *archive,
+ const char *filename);
+GCancellable *fr_archive_get_cancellable (FrArchive *archive);
+void fr_archive_action_started (FrArchive *archive,
+ FrAction action);
+void fr_archive_progress (FrArchive *archive,
+ double fraction);
+void fr_archive_message (FrArchive *archive,
+ const char *msg);
+void fr_archive_working_archive (FrArchive *archive,
+ const char *archive_name);
+void fr_archive_set_n_files (FrArchive *archive,
+ int n_files);
+void fr_archive_add_file (FrArchive *archive,
+ FileData *file_data);
/* utilities */
-gboolean _g_uri_is_archive (const char *uri);
+gboolean _g_uri_is_archive (const char *uri);
#endif /* FR_ARCHIVE_H */
diff --git a/src/fr-command-7z.c b/src/fr-command-7z.c
index f35c2b6..6287d23 100644
--- a/src/fr-command-7z.c
+++ b/src/fr-command-7z.c
@@ -80,14 +80,14 @@ static void
list__process_line (char *line,
gpointer data)
{
- FrCommand *comm = FR_COMMAND (data);
- FrCommand7z *p7z_comm = FR_COMMAND_7Z (comm);
+ FrCommand7z *self = FR_COMMAND_7Z (data);
+ FrArchive *archive = FR_ARCHIVE (data);
char **fields;
FileData *fdata;
g_return_if_fail (line != NULL);
- if (! p7z_comm->list_started) {
+ if (! self->list_started) {
if (strncmp (line, "p7zip Version ", 14) == 0) {
const char *ver_start;
int ver_len;
@@ -99,44 +99,44 @@ list__process_line (char *line,
version[ver_len] = 0;
if (strcmp (version, "4.55") < 0)
- p7z_comm->old_style = TRUE;
+ self->old_style = TRUE;
else
- p7z_comm->old_style = FALSE;
+ self->old_style = FALSE;
}
- else if (p7z_comm->old_style && (strncmp (line, "Listing archive: ", 17) == 0))
- p7z_comm->list_started = TRUE;
- else if (! p7z_comm->old_style && (strcmp (line, "----------") == 0))
- p7z_comm->list_started = TRUE;
+ else if (self->old_style && (strncmp (line, "Listing archive: ", 17) == 0))
+ self->list_started = TRUE;
+ else if (! self->old_style && (strcmp (line, "----------") == 0))
+ self->list_started = TRUE;
else if (strncmp (line, "Multivolume = ", 14) == 0) {
fields = g_strsplit (line, " = ", 2);
- comm->multi_volume = (strcmp (fields[1], "+") == 0);
+ archive->multi_volume = (strcmp (fields[1], "+") == 0);
g_strfreev (fields);
}
return;
}
if (strcmp (line, "") == 0) {
- if (p7z_comm->fdata != NULL) {
- if (p7z_comm->fdata->original_path == NULL) {
- file_data_free (p7z_comm->fdata);
- p7z_comm->fdata = NULL;
+ if (self->fdata != NULL) {
+ if (self->fdata->original_path == NULL) {
+ file_data_free (self->fdata);
+ self->fdata = NULL;
}
else {
- fdata = p7z_comm->fdata;
+ fdata = self->fdata;
if (fdata->dir)
fdata->name = _g_path_get_dir_name (fdata->full_path);
else
fdata->name = g_strdup (_g_path_get_file_name (fdata->full_path));
fdata->path = _g_path_remove_level (fdata->full_path);
- fr_command_add_file (comm, fdata);
- p7z_comm->fdata = NULL;
+ fr_archive_add_file (archive, fdata);
+ self->fdata = NULL;
}
}
return;
}
- if (p7z_comm->fdata == NULL)
- p7z_comm->fdata = file_data_new ();
+ if (self->fdata == NULL)
+ self->fdata = file_data_new ();
fields = g_strsplit (line, " = ", 2);
@@ -145,7 +145,7 @@ list__process_line (char *line,
return;
}
- fdata = p7z_comm->fdata;
+ fdata = self->fdata;
if (strcmp (fields[0], "Path") == 0) {
fdata->free_original_path = TRUE;
@@ -198,15 +198,15 @@ fr_command_7z_begin_command (FrCommand *comm)
static void
-add_password_arg (FrCommand *comm,
- const char *password,
- gboolean always_specify)
+add_password_arg (FrCommand *command,
+ const char *password,
+ gboolean always_specify)
{
if (always_specify || ((password != NULL) && (*password != 0))) {
char *arg;
arg = g_strconcat ("-p", password, NULL);
- fr_process_add_arg (comm->process, arg);
+ fr_process_add_arg (command->process, arg);
g_free (arg);
}
}
@@ -225,30 +225,30 @@ list__begin (gpointer data)
}
-static void
-fr_command_7z_list (FrCommand *comm)
+static gboolean
+fr_command_7z_list (FrCommand *command)
{
- rar_check_multi_volume (comm);
-
- fr_process_set_out_line_func (comm->process, list__process_line, comm);
-
- fr_command_7z_begin_command (comm);
- fr_process_set_begin_func (comm->process, list__begin, comm);
- fr_process_add_arg (comm->process, "l");
- fr_process_add_arg (comm->process, "-slt");
- fr_process_add_arg (comm->process, "-bd");
- fr_process_add_arg (comm->process, "-y");
- add_password_arg (comm, comm->password, FALSE);
- fr_process_add_arg (comm->process, "--");
- fr_process_add_arg (comm->process, comm->filename);
- fr_process_end_command (comm->process);
-
- fr_process_start (comm->process);
+ rar_check_multi_volume (command);
+
+ fr_process_set_out_line_func (command->process, list__process_line, command);
+
+ fr_command_7z_begin_command (command);
+ fr_process_set_begin_func (command->process, list__begin, command);
+ fr_process_add_arg (command->process, "l");
+ fr_process_add_arg (command->process, "-slt");
+ fr_process_add_arg (command->process, "-bd");
+ fr_process_add_arg (command->process, "-y");
+ add_password_arg (command, FR_ARCHIVE (command)->password, FALSE);
+ fr_process_add_arg (command->process, "--");
+ fr_process_add_arg (command->process, command->filename);
+ fr_process_end_command (command->process);
+
+ return TRUE;
}
static void
-parse_progress_line (FrCommand *comm,
+parse_progress_line (FrArchive *archive,
const char *prefix,
const char *message_format,
const char *line)
@@ -257,8 +257,8 @@ parse_progress_line (FrCommand *comm,
prefix_len = strlen (prefix);
if (strncmp (line, prefix, prefix_len) == 0) {
- if (comm->n_files > 1) {
- fr_command_progress (comm, (double) ++comm->n_file / (comm->n_files + 1));
+ if (archive->n_files > 1) {
+ fr_archive_progress (archive, (double) ++archive->n_file / (archive->n_files + 1));
}
else {
char filename[4196];
@@ -266,7 +266,7 @@ parse_progress_line (FrCommand *comm,
strcpy (filename, line + prefix_len);
msg = g_strdup_printf (message_format, filename, NULL);
- fr_command_message (comm, msg);
+ fr_archive_message (archive, msg);
g_free (msg);
}
@@ -278,132 +278,134 @@ static void
process_line__add (char *line,
gpointer data)
{
- FrCommand *comm = FR_COMMAND (data);
+ FrCommand *command = FR_COMMAND (data);
+ FrArchive *archive = FR_ARCHIVE (data);
- if ((comm->volume_size > 0) && (strncmp (line, "Creating archive ", 17) == 0)) {
+ if ((archive->volume_size > 0) && (strncmp (line, "Creating archive ", 17) == 0)) {
char *volume_filename;
GFile *volume_file;
- volume_filename = g_strconcat (comm->filename, ".001", NULL);
+ volume_filename = g_strconcat (command->filename, ".001", NULL);
volume_file = g_file_new_for_path (volume_filename);
- fr_command_set_multi_volume (comm, volume_file);
+ fr_archive_set_multi_volume (archive, volume_file);
g_object_unref (volume_file);
g_free (volume_filename);
}
- if (comm->n_files != 0)
- parse_progress_line (comm, "Compressing ", _("Adding \"%s\""), line);
+ if (archive->n_files != 0)
+ parse_progress_line (archive, "Compressing ", _("Adding \"%s\""), line);
}
static void
-fr_command_7z_add (FrCommand *comm,
- const char *from_file,
- GList *file_list,
- const char *base_dir,
- gboolean update,
- gboolean recursive)
+fr_command_7z_add (FrCommand *command,
+ const char *from_file,
+ GList *file_list,
+ const char *base_dir,
+ gboolean update,
+ gboolean recursive)
{
- GList *scan;
+ FrArchive *archive = FR_ARCHIVE (command);
+ GList *scan;
- fr_process_use_standard_locale (comm->process, TRUE);
- fr_process_set_out_line_func (comm->process,
+ fr_process_use_standard_locale (command->process, TRUE);
+ fr_process_set_out_line_func (command->process,
process_line__add,
- comm);
+ command);
- fr_command_7z_begin_command (comm);
+ fr_command_7z_begin_command (command);
if (update)
- fr_process_add_arg (comm->process, "u");
+ fr_process_add_arg (command->process, "u");
else
- fr_process_add_arg (comm->process, "a");
+ fr_process_add_arg (command->process, "a");
if (base_dir != NULL) {
- fr_process_set_working_dir (comm->process, base_dir);
- fr_process_add_arg_concat (comm->process, "-w", base_dir, NULL);
+ fr_process_set_working_dir (command->process, base_dir);
+ fr_process_add_arg_concat (command->process, "-w", base_dir, NULL);
}
- if (_g_mime_type_matches (comm->mime_type, "application/zip")
- || _g_mime_type_matches (comm->mime_type, "application/x-cbz"))
+ if (_g_mime_type_matches (archive->mime_type, "application/zip")
+ || _g_mime_type_matches (archive->mime_type, "application/x-cbz"))
{
- fr_process_add_arg (comm->process, "-tzip");
- fr_process_add_arg (comm->process, "-mem=AES128");
+ fr_process_add_arg (command->process, "-tzip");
+ fr_process_add_arg (command->process, "-mem=AES128");
}
- fr_process_add_arg (comm->process, "-bd");
- fr_process_add_arg (comm->process, "-y");
- fr_process_add_arg (comm->process, "-l");
- add_password_arg (comm, comm->password, FALSE);
- if ((comm->password != NULL)
- && (*comm->password != 0)
- && comm->encrypt_header
- && fr_command_is_capable_of (comm, FR_COMMAND_CAN_ENCRYPT_HEADER))
+ fr_process_add_arg (command->process, "-bd");
+ fr_process_add_arg (command->process, "-y");
+ fr_process_add_arg (command->process, "-l");
+ add_password_arg (command, archive->password, FALSE);
+ if ((archive->password != NULL)
+ && (*archive->password != 0)
+ && archive->encrypt_header
+ && fr_archive_is_capable_of (archive, FR_ARCHIVE_CAN_ENCRYPT_HEADER))
{
- fr_process_add_arg (comm->process, "-mhe=on");
+ fr_process_add_arg (command->process, "-mhe=on");
}
- /* fr_process_add_arg (comm->process, "-ms=off"); FIXME: solid mode off? */
+ /* fr_process_add_arg (command->process, "-ms=off"); FIXME: solid mode off? */
- switch (comm->compression) {
+ switch (archive->compression) {
case FR_COMPRESSION_VERY_FAST:
- fr_process_add_arg (comm->process, "-mx=1");
+ fr_process_add_arg (command->process, "-mx=1");
break;
case FR_COMPRESSION_FAST:
- fr_process_add_arg (comm->process, "-mx=5");
+ fr_process_add_arg (command->process, "-mx=5");
break;
case FR_COMPRESSION_NORMAL:
- fr_process_add_arg (comm->process, "-mx=7");
+ fr_process_add_arg (command->process, "-mx=7");
break;
case FR_COMPRESSION_MAXIMUM:
- fr_process_add_arg (comm->process, "-mx=9");
- fr_process_add_arg (comm->process, "-m0=lzma2");;
+ fr_process_add_arg (command->process, "-mx=9");
+ fr_process_add_arg (command->process, "-m0=lzma2");;
break;
}
- if (_g_mime_type_matches (comm->mime_type, "application/x-ms-dos-executable"))
- fr_process_add_arg (comm->process, "-sfx");
+ if (_g_mime_type_matches (archive->mime_type, "application/x-ms-dos-executable"))
+ fr_process_add_arg (command->process, "-sfx");
- if (comm->volume_size > 0)
- fr_process_add_arg_printf (comm->process, "-v%ub", comm->volume_size);
+ if (archive->volume_size > 0)
+ fr_process_add_arg_printf (command->process, "-v%ub", archive->volume_size);
if (from_file != NULL)
- fr_process_add_arg_concat (comm->process, "-i@", from_file, NULL);
+ fr_process_add_arg_concat (command->process, "-i@", from_file, NULL);
- fr_process_add_arg (comm->process, "--");
- fr_process_add_arg (comm->process, comm->filename);
+ fr_process_add_arg (command->process, "--");
+ fr_process_add_arg (command->process, command->filename);
if (from_file == NULL)
for (scan = file_list; scan; scan = scan->next)
- fr_process_add_arg (comm->process, scan->data);
+ fr_process_add_arg (command->process, scan->data);
- fr_process_end_command (comm->process);
+ fr_process_end_command (command->process);
}
static void
-fr_command_7z_delete (FrCommand *comm,
+fr_command_7z_delete (FrCommand *command,
const char *from_file,
GList *file_list)
{
GList *scan;
- fr_command_7z_begin_command (comm);
- fr_process_add_arg (comm->process, "d");
- fr_process_add_arg (comm->process, "-bd");
- fr_process_add_arg (comm->process, "-y");
- if (_g_mime_type_matches (comm->mime_type, "application/x-ms-dos-executable"))
- fr_process_add_arg (comm->process, "-sfx");
+ fr_command_7z_begin_command (command);
+ fr_process_add_arg (command->process, "d");
+ fr_process_add_arg (command->process, "-bd");
+ fr_process_add_arg (command->process, "-y");
+ if (_g_mime_type_matches (FR_ARCHIVE (command)->mime_type, "application/x-ms-dos-executable"))
+ fr_process_add_arg (command->process, "-sfx");
if (from_file != NULL)
- fr_process_add_arg_concat (comm->process, "-i@", from_file, NULL);
+ fr_process_add_arg_concat (command->process, "-i@", from_file, NULL);
- fr_process_add_arg (comm->process, "--");
- fr_process_add_arg (comm->process, comm->filename);
+ fr_process_add_arg (command->process, "--");
+ fr_process_add_arg (command->process, command->filename);
if (from_file == NULL)
for (scan = file_list; scan; scan = scan->next)
- fr_process_add_arg (comm->process, scan->data);
+ fr_process_add_arg (command->process, scan->data);
- fr_process_end_command (comm->process);
+ fr_process_end_command (command->process);
}
@@ -411,15 +413,15 @@ static void
process_line__extract (char *line,
gpointer data)
{
- FrCommand *comm = FR_COMMAND (data);
+ FrArchive *archive = FR_ARCHIVE (data);
- if (comm->n_files != 0)
- parse_progress_line (comm, "Extracting ", _("Extracting \"%s\""), line);
+ if (archive->n_files != 0)
+ parse_progress_line (archive, "Extracting ", _("Extracting \"%s\""), line);
}
static void
-fr_command_7z_extract (FrCommand *comm,
+fr_command_7z_extract (FrCommand *command,
const char *from_file,
GList *file_list,
const char *dest_dir,
@@ -427,76 +429,81 @@ fr_command_7z_extract (FrCommand *comm,
gboolean skip_older,
gboolean junk_paths)
{
- GList *scan;
+ FrArchive *archive = FR_ARCHIVE (command);
+ GList *scan;
- fr_process_use_standard_locale (comm->process, TRUE);
- fr_process_set_out_line_func (comm->process,
+ fr_process_use_standard_locale (command->process, TRUE);
+ fr_process_set_out_line_func (command->process,
process_line__extract,
- comm);
- fr_command_7z_begin_command (comm);
+ command);
+ fr_command_7z_begin_command (command);
if (junk_paths)
- fr_process_add_arg (comm->process, "e");
+ fr_process_add_arg (command->process, "e");
else
- fr_process_add_arg (comm->process, "x");
+ fr_process_add_arg (command->process, "x");
- fr_process_add_arg (comm->process, "-bd");
- fr_process_add_arg (comm->process, "-y");
- add_password_arg (comm, comm->password, FALSE);
+ fr_process_add_arg (command->process, "-bd");
+ fr_process_add_arg (command->process, "-y");
+ add_password_arg (command, archive->password, FALSE);
if (dest_dir != NULL)
- fr_process_add_arg_concat (comm->process, "-o", dest_dir, NULL);
+ fr_process_add_arg_concat (command->process, "-o", dest_dir, NULL);
if (from_file != NULL)
- fr_process_add_arg_concat (comm->process, "-i@", from_file, NULL);
+ fr_process_add_arg_concat (command->process, "-i@", from_file, NULL);
- fr_process_add_arg (comm->process, "--");
- fr_process_add_arg (comm->process, comm->filename);
+ fr_process_add_arg (command->process, "--");
+ fr_process_add_arg (command->process, command->filename);
if (from_file == NULL)
for (scan = file_list; scan; scan = scan->next)
- fr_process_add_arg (comm->process, scan->data);
+ fr_process_add_arg (command->process, scan->data);
- fr_process_end_command (comm->process);
+ fr_process_end_command (command->process);
}
static void
-fr_command_7z_test (FrCommand *comm)
+fr_command_7z_test (FrCommand *command)
{
- fr_command_7z_begin_command (comm);
- fr_process_add_arg (comm->process, "t");
- fr_process_add_arg (comm->process, "-bd");
- fr_process_add_arg (comm->process, "-y");
- add_password_arg (comm, comm->password, FALSE);
- fr_process_add_arg (comm->process, "--");
- fr_process_add_arg (comm->process, comm->filename);
- fr_process_end_command (comm->process);
+ FrArchive *archive = FR_ARCHIVE (command);
+
+ fr_command_7z_begin_command (command);
+ fr_process_add_arg (command->process, "t");
+ fr_process_add_arg (command->process, "-bd");
+ fr_process_add_arg (command->process, "-y");
+ add_password_arg (command, archive->password, FALSE);
+ fr_process_add_arg (command->process, "--");
+ fr_process_add_arg (command->process, command->filename);
+ fr_process_end_command (command->process);
}
static void
-fr_command_7z_handle_error (FrCommand *comm,
- FrProcError *error)
+fr_command_7z_handle_error (FrCommand *command,
+ FrError *error)
{
- if (error->type == FR_PROC_ERROR_NONE) {
+ FrArchive *archive = FR_ARCHIVE (command);
+
+ if (error->type == FR_ERROR_NONE) {
FileData *first;
char *basename;
char *testname;
/* This is a way to fix bug #582712. */
- if (comm->files->len != 1)
+ if (archive->files->len != 1)
return;
- if (! g_str_has_suffix (comm->filename, ".001"))
+ if (! g_str_has_suffix (command->filename, ".001"))
return;
- first = g_ptr_array_index (comm->files, 0);
- basename = g_path_get_basename (comm->filename);
+ first = g_ptr_array_index (archive->files, 0);
+ basename = g_path_get_basename (command->filename);
testname = g_strconcat (first->original_path, ".001", NULL);
if (strcmp (basename, testname) == 0)
- error->type = FR_PROC_ERROR_ASK_PASSWORD;
+ error->type = FR_ERROR_ASK_PASSWORD;
g_free (testname);
g_free (basename);
@@ -505,18 +512,18 @@ fr_command_7z_handle_error (FrCommand *comm,
}
if (error->status <= 1) {
- error->type = FR_PROC_ERROR_NONE;
+ error->type = FR_ERROR_NONE;
}
else {
GList *scan;
- for (scan = g_list_last (comm->process->out.raw); scan; scan = scan->prev) {
+ for (scan = g_list_last (command->process->out.raw); scan; scan = scan->prev) {
char *line = scan->data;
if ((strstr (line, "Wrong password?") != NULL)
|| (strstr (line, "Enter password") != NULL))
{
- error->type = FR_PROC_ERROR_ASK_PASSWORD;
+ error->type = FR_ERROR_ASK_PASSWORD;
break;
}
}
@@ -538,71 +545,71 @@ const char *sevenz_mime_types[] = { "application/x-7z-compressed",
static const char **
-fr_command_7z_get_mime_types (FrCommand *comm)
+fr_command_7z_get_mime_types (FrArchive *archive)
{
return sevenz_mime_types;
}
-static FrCommandCap
-fr_command_7z_get_capabilities (FrCommand *comm,
+static FrArchiveCap
+fr_command_7z_get_capabilities (FrArchive *archive,
const char *mime_type,
gboolean check_command)
{
- FrCommandCap capabilities;
+ FrArchiveCap capabilities;
- capabilities = FR_COMMAND_CAN_ARCHIVE_MANY_FILES;
+ capabilities = FR_ARCHIVE_CAN_STORE_MANY_FILES;
if (! _g_program_is_available ("7za", check_command) && ! _g_program_is_available ("7zr", check_command) && ! _g_program_is_available ("7z", check_command))
return capabilities;
if (_g_mime_type_matches (mime_type, "application/x-7z-compressed")) {
- capabilities |= FR_COMMAND_CAN_READ_WRITE | FR_COMMAND_CAN_CREATE_VOLUMES;
+ capabilities |= FR_ARCHIVE_CAN_READ_WRITE | FR_ARCHIVE_CAN_CREATE_VOLUMES;
if (_g_program_is_available ("7z", check_command))
- capabilities |= FR_COMMAND_CAN_ENCRYPT | FR_COMMAND_CAN_ENCRYPT_HEADER;
+ capabilities |= FR_ARCHIVE_CAN_ENCRYPT | FR_ARCHIVE_CAN_ENCRYPT_HEADER;
}
else if (_g_mime_type_matches (mime_type, "application/x-7z-compressed-tar")) {
- capabilities |= FR_COMMAND_CAN_READ_WRITE;
+ capabilities |= FR_ARCHIVE_CAN_READ_WRITE;
if (_g_program_is_available ("7z", check_command))
- capabilities |= FR_COMMAND_CAN_ENCRYPT | FR_COMMAND_CAN_ENCRYPT_HEADER;
+ capabilities |= FR_ARCHIVE_CAN_ENCRYPT | FR_ARCHIVE_CAN_ENCRYPT_HEADER;
}
else if (_g_program_is_available ("7z", check_command)) {
if (_g_mime_type_matches (mime_type, "application/x-rar")
|| _g_mime_type_matches (mime_type, "application/x-cbr"))
{
if (! check_command || g_file_test ("/usr/lib/p7zip/Codecs/Rar29.so", G_FILE_TEST_EXISTS))
- capabilities |= FR_COMMAND_CAN_READ;
+ capabilities |= FR_ARCHIVE_CAN_READ;
}
else
- capabilities |= FR_COMMAND_CAN_READ;
+ capabilities |= FR_ARCHIVE_CAN_READ;
if (_g_mime_type_matches (mime_type, "application/x-cbz")
|| _g_mime_type_matches (mime_type, "application/x-ms-dos-executable")
|| _g_mime_type_matches (mime_type, "application/zip"))
{
- capabilities |= FR_COMMAND_CAN_WRITE | FR_COMMAND_CAN_ENCRYPT;
+ capabilities |= FR_ARCHIVE_CAN_WRITE | FR_ARCHIVE_CAN_ENCRYPT;
}
}
else if (_g_program_is_available ("7za", check_command)) {
if (_g_mime_type_matches (mime_type, "application/vnd.ms-cab-compressed")
|| _g_mime_type_matches (mime_type, "application/zip"))
{
- capabilities |= FR_COMMAND_CAN_READ;
+ capabilities |= FR_ARCHIVE_CAN_READ;
}
if (_g_mime_type_matches (mime_type, "application/zip"))
- capabilities |= FR_COMMAND_CAN_WRITE;
+ capabilities |= FR_ARCHIVE_CAN_WRITE;
}
/* multi-volumes are read-only */
- if ((comm->files->len > 0) && comm->multi_volume && (capabilities & FR_COMMAND_CAN_WRITE))
- capabilities ^= FR_COMMAND_CAN_WRITE;
+ if ((archive->files->len > 0) && archive->multi_volume && (capabilities & FR_ARCHIVE_CAN_WRITE))
+ capabilities ^= FR_ARCHIVE_CAN_WRITE;
return capabilities;
}
static const char *
-fr_command_7z_get_packages (FrCommand *comm,
+fr_command_7z_get_packages (FrArchive *archive,
const char *mime_type)
{
if (_g_mime_type_matches (mime_type, "application/x-rar"))
@@ -630,30 +637,33 @@ static void
fr_command_7z_class_init (FrCommand7zClass *class)
{
GObjectClass *gobject_class;
- FrCommandClass *afc;
+ FrArchiveClass *archive_class;
+ FrCommandClass *command_class;
fr_command_7z_parent_class = g_type_class_peek_parent (class);
- afc = (FrCommandClass*) class;
gobject_class = G_OBJECT_CLASS (class);
gobject_class->finalize = fr_command_7z_finalize;
- afc->list = fr_command_7z_list;
- afc->add = fr_command_7z_add;
- afc->delete = fr_command_7z_delete;
- afc->extract = fr_command_7z_extract;
- afc->test = fr_command_7z_test;
- afc->handle_error = fr_command_7z_handle_error;
- afc->get_mime_types = fr_command_7z_get_mime_types;
- afc->get_capabilities = fr_command_7z_get_capabilities;
- afc->get_packages = fr_command_7z_get_packages;
+ archive_class = FR_ARCHIVE_CLASS (class);
+ archive_class->get_mime_types = fr_command_7z_get_mime_types;
+ archive_class->get_capabilities = fr_command_7z_get_capabilities;
+ archive_class->get_packages = fr_command_7z_get_packages;
+
+ command_class = FR_COMMAND_CLASS (class);
+ command_class->list = fr_command_7z_list;
+ command_class->add = fr_command_7z_add;
+ command_class->delete = fr_command_7z_delete;
+ command_class->extract = fr_command_7z_extract;
+ command_class->test = fr_command_7z_test;
+ command_class->handle_error = fr_command_7z_handle_error;
}
static void
fr_command_7z_init (FrCommand7z *self)
{
- FrCommand *base = FR_COMMAND (self);
+ FrArchive *base = FR_ARCHIVE (self);
base->propAddCanUpdate = TRUE;
base->propAddCanReplace = TRUE;
diff --git a/src/fr-command-ace.c b/src/fr-command-ace.c
index 1ddb5a8..528b5c1 100644
--- a/src/fr-command-ace.c
+++ b/src/fr-command-ace.c
@@ -148,7 +148,7 @@ process_line (char *line,
if (*fdata->name == 0)
file_data_free (fdata);
else
- fr_command_add_file (comm, fdata);
+ fr_archive_add_file (FR_ARCHIVE (comm), fdata);
}
@@ -162,7 +162,7 @@ list__begin (gpointer data)
}
-static void
+static gboolean
fr_command_ace_list (FrCommand *comm)
{
fr_process_set_out_line_func (comm->process, process_line, comm);
@@ -173,7 +173,8 @@ fr_command_ace_list (FrCommand *comm)
fr_process_add_arg (comm->process, "-y");
fr_process_add_arg (comm->process, comm->filename);
fr_process_end_command (comm->process);
- fr_process_start (comm->process);
+
+ return TRUE;
}
@@ -220,7 +221,7 @@ fr_command_ace_test (FrCommand *comm)
static void
fr_command_ace_handle_error (FrCommand *comm,
- FrProcError *error)
+ FrError *error)
{
/* FIXME */
}
@@ -230,29 +231,29 @@ const char *ace_mime_type[] = { "application/x-ace", NULL };
static const char **
-fr_command_ace_get_mime_types (FrCommand *comm)
+fr_command_ace_get_mime_types (FrArchive *archive)
{
return ace_mime_type;
}
-static FrCommandCap
-fr_command_ace_get_capabilities (FrCommand *comm,
+static FrArchiveCap
+fr_command_ace_get_capabilities (FrArchive *archive,
const char *mime_type,
gboolean check_command)
{
- FrCommandCap capabilities;
+ FrArchiveCap capabilities;
- capabilities = FR_COMMAND_CAN_ARCHIVE_MANY_FILES;
+ capabilities = FR_ARCHIVE_CAN_STORE_MANY_FILES;
if (_g_program_is_available ("unace", check_command))
- capabilities |= FR_COMMAND_CAN_READ;
+ capabilities |= FR_ARCHIVE_CAN_READ;
return capabilities;
}
static const char *
-fr_command_ace_get_packages (FrCommand *comm,
+fr_command_ace_get_packages (FrArchive *archive,
const char *mime_type)
{
return PACKAGES ("unace");
@@ -273,29 +274,32 @@ fr_command_ace_finalize (GObject *object)
static void
fr_command_ace_class_init (FrCommandAceClass *klass)
{
- GObjectClass *gobject_class;
- FrCommandClass *command_class;
+ GObjectClass *gobject_class;
+ FrArchiveClass *archive_class;
+ FrCommandClass *command_class;
- fr_command_ace_parent_class = g_type_class_peek_parent (klass);
+ fr_command_ace_parent_class = g_type_class_peek_parent (klass);
gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = fr_command_ace_finalize;
+ archive_class = FR_ARCHIVE_CLASS (klass);
+ archive_class->get_mime_types = fr_command_ace_get_mime_types;
+ archive_class->get_capabilities = fr_command_ace_get_capabilities;
+ archive_class->get_packages = fr_command_ace_get_packages;
+
command_class = FR_COMMAND_CLASS (klass);
command_class->list = fr_command_ace_list;
command_class->extract = fr_command_ace_extract;
command_class->test = fr_command_ace_test;
command_class->handle_error = fr_command_ace_handle_error;
- command_class->get_mime_types = fr_command_ace_get_mime_types;
- command_class->get_capabilities = fr_command_ace_get_capabilities;
- command_class->get_packages = fr_command_ace_get_packages;
}
static void
fr_command_ace_init (FrCommandAce *self)
{
- FrCommand *base = FR_COMMAND (self);
+ FrArchive *base = FR_ARCHIVE (self);
base->propAddCanUpdate = TRUE;
base->propAddCanReplace = TRUE;
diff --git a/src/fr-command-ace.h b/src/fr-command-ace.h
index 369366b..563a444 100644
--- a/src/fr-command-ace.h
+++ b/src/fr-command-ace.h
@@ -23,9 +23,7 @@
#define FR_COMMAND_ACE_H
#include <glib.h>
-#include "file-data.h"
#include "fr-command.h"
-#include "fr-process.h"
#define FR_TYPE_COMMAND_ACE (fr_command_ace_get_type ())
#define FR_COMMAND_ACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FR_TYPE_COMMAND_ACE, FrCommandAce))
diff --git a/src/fr-command-alz.c b/src/fr-command-alz.c
index 232cce2..4cd0252 100644
--- a/src/fr-command-alz.c
+++ b/src/fr-command-alz.c
@@ -142,7 +142,7 @@ process_line (char *line,
if (*fdata->name == 0)
file_data_free (fdata);
else
- fr_command_add_file (comm, fdata);
+ fr_archive_add_file (FR_ARCHIVE (comm), fdata);
g_free (name_field);
g_strfreev (fields);
@@ -201,7 +201,7 @@ list__begin (gpointer data)
}
-static void
+static gboolean
fr_command_alz_list (FrCommand *comm)
{
fr_process_set_out_line_func (FR_COMMAND (comm)->process, process_line, comm);
@@ -213,7 +213,8 @@ fr_command_alz_list (FrCommand *comm)
fr_process_add_arg (comm->process, comm->filename);
fr_process_end_command (comm->process);
fr_process_use_standard_locale (comm->process, TRUE);
- fr_process_start (comm->process);
+
+ return TRUE;
}
@@ -223,8 +224,8 @@ static void
process_extract_line (char *line,
gpointer data)
{
- FrCommand *comm = FR_COMMAND (data);
- FrCommandAlz *alz_comm = FR_COMMAND_ALZ (comm);
+ FrCommand *comm = FR_COMMAND (data);
+ FrCommandAlz *alz_comm = FR_COMMAND_ALZ (comm);
g_return_if_fail (line != NULL);
@@ -232,7 +233,7 @@ process_extract_line (char *line,
if (strncmp (line, "err code(28) (invalid password)", 31) == 0) {
alz_comm->invalid_password = TRUE;
- fr_process_stop (comm->process);
+ fr_process_cancel (comm->process);
return;
}
@@ -240,7 +241,7 @@ process_extract_line (char *line,
alz_comm->extract_none = FALSE;
}
else if ((strncmp (line, "done..", 6) == 0) && alz_comm->extract_none) {
- fr_process_stop (comm->process);
+ fr_process_cancel (comm->process);
return;
}
}
@@ -269,7 +270,7 @@ fr_command_alz_extract (FrCommand *comm,
fr_process_add_arg (comm->process, dest_dir);
}
add_codepage_arg (comm);
- add_password_arg (comm, comm->password, TRUE);
+ add_password_arg (comm, FR_ARCHIVE (comm)->password, TRUE);
fr_process_add_arg (comm->process, comm->filename);
for (scan = file_list; scan; scan = scan->next)
fr_process_add_arg (comm->process, scan->data);
@@ -279,12 +280,12 @@ fr_command_alz_extract (FrCommand *comm,
static void
fr_command_alz_handle_error (FrCommand *comm,
- FrProcError *error)
+ FrError *error)
{
- if ((error->type == FR_PROC_ERROR_STOPPED)) {
+ if ((error->type == FR_ERROR_STOPPED)) {
if (FR_COMMAND_ALZ (comm)->extract_none ||
- FR_COMMAND_ALZ (comm)->invalid_password ) {
- error->type = FR_PROC_ERROR_ASK_PASSWORD;
+ FR_COMMAND_ALZ (comm)->invalid_password) {
+ error->type = FR_ERROR_ASK_PASSWORD;
}
}
}
@@ -294,29 +295,29 @@ const char *alz_mime_type[] = { "application/x-alz", NULL };
static const char **
-fr_command_alz_get_mime_types (FrCommand *comm)
+fr_command_alz_get_mime_types (FrArchive *archive)
{
return alz_mime_type;
}
-static FrCommandCap
-fr_command_alz_get_capabilities (FrCommand *comm,
+static FrArchiveCap
+fr_command_alz_get_capabilities (FrArchive *archive,
const char *mime_type,
gboolean check_command)
{
- FrCommandCap capabilities;
+ FrArchiveCap capabilities;
- capabilities = FR_COMMAND_CAN_ARCHIVE_MANY_FILES;
+ capabilities = FR_ARCHIVE_CAN_STORE_MANY_FILES;
if (_g_program_is_available ("unalz", check_command))
- capabilities |= FR_COMMAND_CAN_READ;
+ capabilities |= FR_ARCHIVE_CAN_READ;
return capabilities;
}
static const char *
-fr_command_alz_get_packages (FrCommand *comm,
+fr_command_alz_get_packages (FrArchive *archive,
const char *mime_type)
{
return PACKAGES ("unalz");
@@ -338,6 +339,7 @@ static void
fr_command_alz_class_init (FrCommandAlzClass *klass)
{
GObjectClass *gobject_class;
+ FrArchiveClass *archive_class;
FrCommandClass *command_class;
fr_command_alz_parent_class = g_type_class_peek_parent (klass);
@@ -345,22 +347,24 @@ fr_command_alz_class_init (FrCommandAlzClass *klass)
gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = fr_command_alz_finalize;
+ archive_class = FR_ARCHIVE_CLASS (klass);
+ archive_class->get_mime_types = fr_command_alz_get_mime_types;
+ archive_class->get_capabilities = fr_command_alz_get_capabilities;
+ archive_class->get_packages = fr_command_alz_get_packages;
+
command_class = (FrCommandClass*) klass;
command_class->list = fr_command_alz_list;
command_class->add = NULL;
command_class->delete = NULL;
command_class->extract = fr_command_alz_extract;
command_class->handle_error = fr_command_alz_handle_error;
- command_class->get_mime_types = fr_command_alz_get_mime_types;
- command_class->get_capabilities = fr_command_alz_get_capabilities;
- command_class->get_packages = fr_command_alz_get_packages;
}
static void
fr_command_alz_init (FrCommandAlz *self)
{
- FrCommand *base = FR_COMMAND (self);
+ FrArchive *base = FR_ARCHIVE (self);
base->propAddCanUpdate = TRUE;
base->propAddCanReplace = TRUE;
diff --git a/src/fr-command-ar.c b/src/fr-command-ar.c
index 2eb4e7f..9a4dbad 100644
--- a/src/fr-command-ar.c
+++ b/src/fr-command-ar.c
@@ -176,11 +176,11 @@ process_line (char *line,
if (*fdata->name == 0)
file_data_free (fdata);
else
- fr_command_add_file (comm, fdata);
+ fr_archive_add_file (FR_ARCHIVE (comm), fdata);
}
-static void
+static gboolean
fr_command_ar_list (FrCommand *comm)
{
fr_process_set_out_line_func (comm->process, process_line, comm);
@@ -189,7 +189,8 @@ fr_command_ar_list (FrCommand *comm)
fr_process_add_arg (comm->process, "tv");
fr_process_add_arg (comm->process, comm->filename);
fr_process_end_command (comm->process);
- fr_process_start (comm->process);
+
+ return TRUE;
}
@@ -264,7 +265,7 @@ fr_command_ar_extract (FrCommand *comm,
static void
fr_command_ar_handle_error (FrCommand *comm,
- FrProcError *error)
+ FrError *error)
{
/* FIXME */
}
@@ -276,25 +277,25 @@ const char *ar_mime_type[] = { "application/x-ar",
static const char **
-fr_command_ar_get_mime_types (FrCommand *comm)
+fr_command_ar_get_mime_types (FrArchive *archive)
{
return ar_mime_type;
}
-static FrCommandCap
-fr_command_ar_get_capabilities (FrCommand *comm,
+static FrArchiveCap
+fr_command_ar_get_capabilities (FrArchive *archive,
const char *mime_type,
gboolean check_command)
{
- FrCommandCap capabilities;
+ FrArchiveCap capabilities;
- capabilities = FR_COMMAND_CAN_ARCHIVE_MANY_FILES;
+ capabilities = FR_ARCHIVE_CAN_STORE_MANY_FILES;
if (_g_program_is_available ("ar", check_command)) {
if (_g_mime_type_matches (mime_type, "application/x-deb"))
- capabilities |= FR_COMMAND_CAN_READ;
+ capabilities |= FR_ARCHIVE_CAN_READ;
else if (_g_mime_type_matches (mime_type, "application/x-ar"))
- capabilities |= FR_COMMAND_CAN_READ_WRITE;
+ capabilities |= FR_ARCHIVE_CAN_READ_WRITE;
}
return capabilities;
@@ -302,7 +303,7 @@ fr_command_ar_get_capabilities (FrCommand *comm,
static const char *
-fr_command_ar_get_packages (FrCommand *comm,
+fr_command_ar_get_packages (FrArchive *archive,
const char *mime_type)
{
return PACKAGES ("binutils");
@@ -324,6 +325,7 @@ static void
fr_command_ar_class_init (FrCommandArClass *klass)
{
GObjectClass *gobject_class;
+ FrArchiveClass *archive_class;
FrCommandClass *command_class;
fr_command_ar_parent_class = g_type_class_peek_parent (klass);
@@ -331,22 +333,24 @@ fr_command_ar_class_init (FrCommandArClass *klass)
gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = fr_command_ar_finalize;
+ archive_class = FR_ARCHIVE_CLASS (klass);
+ archive_class->get_mime_types = fr_command_ar_get_mime_types;
+ archive_class->get_capabilities = fr_command_ar_get_capabilities;
+ archive_class->get_packages = fr_command_ar_get_packages;
+
command_class = FR_COMMAND_CLASS (klass);
command_class->list = fr_command_ar_list;
command_class->add = fr_command_ar_add;
command_class->delete = fr_command_ar_delete;
command_class->extract = fr_command_ar_extract;
command_class->handle_error = fr_command_ar_handle_error;
- command_class->get_mime_types = fr_command_ar_get_mime_types;
- command_class->get_capabilities = fr_command_ar_get_capabilities;
- command_class->get_packages = fr_command_ar_get_packages;
}
static void
fr_command_ar_init (FrCommandAr *self)
{
- FrCommand *base = FR_COMMAND (self);
+ FrArchive *base = FR_ARCHIVE (self);
base->propAddCanUpdate = TRUE;
base->propAddCanReplace = TRUE;
diff --git a/src/fr-command-arj.c b/src/fr-command-arj.c
index b8e68bc..31a85b6 100644
--- a/src/fr-command-arj.c
+++ b/src/fr-command-arj.c
@@ -143,7 +143,7 @@ list__process_line (char *line,
if (*fdata->name == 0)
file_data_free (fdata);
else
- fr_command_add_file (comm, fdata);
+ fr_archive_add_file (FR_ARCHIVE (comm), fdata);
arj_comm->fdata = NULL;
}
@@ -151,7 +151,7 @@ list__process_line (char *line,
}
-static void
+static gboolean
fr_command_arj_list (FrCommand *comm)
{
fr_process_set_out_line_func (comm->process, list__process_line, comm);
@@ -162,7 +162,8 @@ fr_command_arj_list (FrCommand *comm)
fr_process_add_arg (comm->process, "-");
fr_process_add_arg (comm->process, comm->filename);
fr_process_end_command (comm->process);
- fr_process_start (comm->process);
+
+ return TRUE;
}
@@ -186,10 +187,10 @@ fr_command_arj_add (FrCommand *comm,
if (update)
fr_process_add_arg (comm->process, "-u");
- if (comm->password != NULL)
- fr_process_add_arg_concat (comm->process, "-g/", comm->password, NULL);
+ if (FR_ARCHIVE (comm)->password != NULL)
+ fr_process_add_arg_concat (comm->process, "-g/", FR_ARCHIVE (comm)->password, NULL);
- switch (comm->compression) {
+ switch (FR_ARCHIVE (comm)->compression) {
case FR_COMPRESSION_VERY_FAST:
fr_process_add_arg (comm->process, "-m3"); break;
case FR_COMPRESSION_FAST:
@@ -262,8 +263,8 @@ fr_command_arj_extract (FrCommand *comm,
if (skip_older)
fr_process_add_arg (comm->process, "-u");
- if (comm->password != NULL)
- fr_process_add_arg_concat (comm->process, "-g/", comm->password, NULL);
+ if (FR_ARCHIVE (comm)->password != NULL)
+ fr_process_add_arg_concat (comm->process, "-g/", FR_ARCHIVE (comm)->password, NULL);
else
fr_process_add_arg (comm->process, "-g/");
@@ -281,12 +282,12 @@ fr_command_arj_extract (FrCommand *comm,
static void
-fr_command_arj_test (FrCommand *comm)
+fr_command_arj_test (FrCommand *comm)
{
fr_process_begin_command (comm->process, "arj");
fr_process_add_arg (comm->process, "t");
- if (comm->password != NULL)
- fr_process_add_arg_concat (comm->process, "-g/", comm->password, NULL);
+ if (FR_ARCHIVE (comm)->password != NULL)
+ fr_process_add_arg_concat (comm->process, "-g/", FR_ARCHIVE (comm)->password, NULL);
fr_process_add_arg (comm->process, "-i");
fr_process_add_arg (comm->process, "-y");
fr_process_add_arg (comm->process, "-");
@@ -296,14 +297,14 @@ fr_command_arj_test (FrCommand *comm)
static void
-fr_command_arj_handle_error (FrCommand *comm,
- FrProcError *error)
+fr_command_arj_handle_error (FrCommand *comm,
+ FrError *error)
{
- if (error->type != FR_PROC_ERROR_NONE) {
+ if (error->type != FR_ERROR_NONE) {
if (error->status <= 1)
- error->type = FR_PROC_ERROR_NONE;
+ error->type = FR_ERROR_NONE;
else if (error->status == 3)
- error->type = FR_PROC_ERROR_ASK_PASSWORD;
+ error->type = FR_ERROR_ASK_PASSWORD;
}
}
@@ -312,29 +313,29 @@ const char *arj_mime_type[] = { "application/x-arj", NULL };
static const char **
-fr_command_arj_get_mime_types (FrCommand *comm)
+fr_command_arj_get_mime_types (FrArchive *archive)
{
return arj_mime_type;
}
-static FrCommandCap
-fr_command_arj_get_capabilities (FrCommand *comm,
+static FrArchiveCap
+fr_command_arj_get_capabilities (FrArchive *archive,
const char *mime_type,
gboolean check_command)
{
- FrCommandCap capabilities;
+ FrArchiveCap capabilities;
- capabilities = FR_COMMAND_CAN_ARCHIVE_MANY_FILES | FR_COMMAND_CAN_ENCRYPT;
+ capabilities = FR_ARCHIVE_CAN_STORE_MANY_FILES | FR_ARCHIVE_CAN_ENCRYPT;
if (_g_program_is_available ("arj", check_command))
- capabilities |= FR_COMMAND_CAN_READ_WRITE;
+ capabilities |= FR_ARCHIVE_CAN_READ_WRITE;
return capabilities;
}
static const char *
-fr_command_arj_get_packages (FrCommand *comm,
+fr_command_arj_get_packages (FrArchive *archive,
const char *mime_type)
{
return PACKAGES ("arj");
@@ -361,6 +362,7 @@ static void
fr_command_arj_class_init (FrCommandArjClass *klass)
{
GObjectClass *gobject_class;
+ FrArchiveClass *archive_class;
FrCommandClass *command_class;
fr_command_arj_parent_class = g_type_class_peek_parent (klass);
@@ -368,6 +370,11 @@ fr_command_arj_class_init (FrCommandArjClass *klass)
gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = fr_command_arj_finalize;
+ archive_class = FR_ARCHIVE_CLASS (klass);
+ archive_class->get_mime_types = fr_command_arj_get_mime_types;
+ archive_class->get_capabilities = fr_command_arj_get_capabilities;
+ archive_class->get_packages = fr_command_arj_get_packages;
+
command_class = FR_COMMAND_CLASS (klass);
command_class->list = fr_command_arj_list;
command_class->add = fr_command_arj_add;
@@ -375,16 +382,13 @@ fr_command_arj_class_init (FrCommandArjClass *klass)
command_class->extract = fr_command_arj_extract;
command_class->test = fr_command_arj_test;
command_class->handle_error = fr_command_arj_handle_error;
- command_class->get_mime_types = fr_command_arj_get_mime_types;
- command_class->get_capabilities = fr_command_arj_get_capabilities;
- command_class->get_packages = fr_command_arj_get_packages;
}
static void
fr_command_arj_init (FrCommandArj *self)
{
- FrCommand *base = FR_COMMAND (self);;
+ FrArchive *base = FR_ARCHIVE (self);
base->propAddCanUpdate = TRUE;
base->propAddCanReplace = TRUE;
diff --git a/src/fr-command-cfile.c b/src/fr-command-cfile.c
index 32812ca..15cd91c 100644
--- a/src/fr-command-cfile.c
+++ b/src/fr-command-cfile.c
@@ -44,7 +44,7 @@ get_uncompressed_name_from_archive (FrCommand *comm,
GInputStream *stream;
char *filename = NULL;
- if (! _g_mime_type_matches (comm->mime_type, "application/x-gzip"))
+ if (! _g_mime_type_matches (FR_ARCHIVE (comm)->mime_type, "application/x-gzip"))
return NULL;
file = g_file_new_for_path (archive);
@@ -126,19 +126,17 @@ list__process_line (char *line,
if (*fdata->name == 0)
file_data_free (fdata);
else
- fr_command_add_file (comm, fdata);
+ fr_archive_add_file (FR_ARCHIVE (comm), fdata);
}
-static void
-fr_command_cfile_list (FrCommand *comm)
+static gboolean
+fr_command_cfile_list (FrCommand *comm)
{
- FrCommandCFile *comm_cfile = FR_COMMAND_CFILE (comm);
-
- if (_g_mime_type_matches (comm->mime_type, "application/x-gzip")) {
+ if (_g_mime_type_matches (FR_ARCHIVE (comm)->mime_type, "application/x-gzip")) {
/* gzip let us known the uncompressed size */
- fr_process_set_out_line_func (FR_COMMAND (comm)->process,
+ fr_process_set_out_line_func (comm->process,
list__process_line,
comm);
@@ -147,7 +145,6 @@ fr_command_cfile_list (FrCommand *comm)
fr_process_add_arg (comm->process, "-q");
fr_process_add_arg (comm->process, comm->filename);
fr_process_end_command (comm->process);
- fr_process_start (comm->process);
}
else {
/* ... other compressors do not support this feature so
@@ -176,15 +173,12 @@ fr_command_cfile_list (FrCommand *comm)
if (*fdata->name == 0)
file_data_free (fdata);
else
- fr_command_add_file (comm, fdata);
-
- comm_cfile->error.type = FR_PROC_ERROR_NONE;
- comm_cfile->error.status = 0;
- g_signal_emit_by_name (G_OBJECT (comm),
- "done",
- comm->action,
- &comm_cfile->error);
+ fr_archive_add_file (FR_ARCHIVE (comm), fdata);
+
+ return FALSE;
}
+
+ return TRUE;
}
@@ -196,6 +190,7 @@ fr_command_cfile_add (FrCommand *comm,
gboolean update,
gboolean recursive)
{
+ FrArchive *archive = FR_ARCHIVE (comm);
const char *filename;
char *temp_dir;
char *temp_file;
@@ -220,7 +215,7 @@ fr_command_cfile_add (FrCommand *comm,
/**/
- if (_g_mime_type_matches (comm->mime_type, "application/x-gzip")) {
+ if (_g_mime_type_matches (archive->mime_type, "application/x-gzip")) {
fr_process_begin_command (comm->process, "gzip");
fr_process_set_working_dir (comm->process, temp_dir);
fr_process_add_arg (comm->process, "--");
@@ -228,7 +223,7 @@ fr_command_cfile_add (FrCommand *comm,
fr_process_end_command (comm->process);
compressed_filename = g_strconcat (filename, ".gz", NULL);
}
- else if (_g_mime_type_matches (comm->mime_type, "application/x-bzip")) {
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-bzip")) {
fr_process_begin_command (comm->process, "bzip2");
fr_process_set_working_dir (comm->process, temp_dir);
fr_process_add_arg (comm->process, "--");
@@ -236,7 +231,7 @@ fr_command_cfile_add (FrCommand *comm,
fr_process_end_command (comm->process);
compressed_filename = g_strconcat (filename, ".bz2", NULL);
}
- else if (_g_mime_type_matches (comm->mime_type, "application/x-compress")) {
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-compress")) {
fr_process_begin_command (comm->process, "compress");
fr_process_set_working_dir (comm->process, temp_dir);
fr_process_add_arg (comm->process, "-f");
@@ -244,7 +239,7 @@ fr_command_cfile_add (FrCommand *comm,
fr_process_end_command (comm->process);
compressed_filename = g_strconcat (filename, ".Z", NULL);
}
- else if (_g_mime_type_matches (comm->mime_type, "application/x-lzip")) {
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-lzip")) {
fr_process_begin_command (comm->process, "lzip");
fr_process_set_working_dir (comm->process, temp_dir);
fr_process_add_arg (comm->process, "--");
@@ -252,7 +247,7 @@ fr_command_cfile_add (FrCommand *comm,
fr_process_end_command (comm->process);
compressed_filename = g_strconcat (filename, ".lz", NULL);
}
- else if (_g_mime_type_matches (comm->mime_type, "application/x-lzma")) {
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-lzma")) {
fr_process_begin_command (comm->process, "lzma");
fr_process_set_working_dir (comm->process, temp_dir);
fr_process_add_arg (comm->process, "--");
@@ -260,7 +255,7 @@ fr_command_cfile_add (FrCommand *comm,
fr_process_end_command (comm->process);
compressed_filename = g_strconcat (filename, ".lzma", NULL);
}
- else if (_g_mime_type_matches (comm->mime_type, "application/x-xz")) {
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-xz")) {
fr_process_begin_command (comm->process, "xz");
fr_process_set_working_dir (comm->process, temp_dir);
fr_process_add_arg (comm->process, "--");
@@ -268,7 +263,7 @@ fr_command_cfile_add (FrCommand *comm,
fr_process_end_command (comm->process);
compressed_filename = g_strconcat (filename, ".xz", NULL);
}
- else if (_g_mime_type_matches (comm->mime_type, "application/x-lzop")) {
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-lzop")) {
fr_process_begin_command (comm->process, "lzop");
fr_process_set_working_dir (comm->process, temp_dir);
fr_process_add_arg (comm->process, "-fU");
@@ -278,7 +273,7 @@ fr_command_cfile_add (FrCommand *comm,
fr_process_end_command (comm->process);
compressed_filename = g_strconcat (filename, ".lzo", NULL);
}
- else if (_g_mime_type_matches (comm->mime_type, "application/x-rzip")) {
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-rzip")) {
fr_process_begin_command (comm->process, "rzip");
fr_process_set_working_dir (comm->process, temp_dir);
fr_process_add_arg (comm->process, filename);
@@ -329,11 +324,12 @@ fr_command_cfile_extract (FrCommand *comm,
gboolean skip_older,
gboolean junk_paths)
{
- char *temp_dir;
- char *dest_file;
- char *temp_file;
- char *uncompr_file;
- char *compr_file;
+ FrArchive *archive = FR_ARCHIVE (comm);
+ char *temp_dir;
+ char *dest_file;
+ char *temp_file;
+ char *uncompr_file;
+ char *compr_file;
/* copy file to the temp dir, remove the already existing file first */
@@ -351,7 +347,7 @@ fr_command_cfile_extract (FrCommand *comm,
/* uncompress the file */
- if (_g_mime_type_matches (comm->mime_type, "application/x-gzip")) {
+ if (_g_mime_type_matches (archive->mime_type, "application/x-gzip")) {
fr_process_begin_command (comm->process, "gzip");
fr_process_add_arg (comm->process, "-f");
fr_process_add_arg (comm->process, "-d");
@@ -359,14 +355,14 @@ fr_command_cfile_extract (FrCommand *comm,
fr_process_add_arg (comm->process, temp_file);
fr_process_end_command (comm->process);
}
- else if (_g_mime_type_matches (comm->mime_type, "application/x-bzip")) {
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-bzip")) {
fr_process_begin_command (comm->process, "bzip2");
fr_process_add_arg (comm->process, "-f");
fr_process_add_arg (comm->process, "-d");
fr_process_add_arg (comm->process, temp_file);
fr_process_end_command (comm->process);
}
- else if (_g_mime_type_matches (comm->mime_type, "application/x-compress")) {
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-compress")) {
if (_g_program_is_in_path ("gzip")) {
fr_process_begin_command (comm->process, "gzip");
fr_process_add_arg (comm->process, "-d");
@@ -378,28 +374,28 @@ fr_command_cfile_extract (FrCommand *comm,
fr_process_add_arg (comm->process, temp_file);
fr_process_end_command (comm->process);
}
- else if (_g_mime_type_matches (comm->mime_type, "application/x-lzip")) {
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-lzip")) {
fr_process_begin_command (comm->process, "lzip");
fr_process_add_arg (comm->process, "-f");
fr_process_add_arg (comm->process, "-d");
fr_process_add_arg (comm->process, temp_file);
fr_process_end_command (comm->process);
}
- else if (_g_mime_type_matches (comm->mime_type, "application/x-lzma")) {
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-lzma")) {
fr_process_begin_command (comm->process, "lzma");
fr_process_add_arg (comm->process, "-f");
fr_process_add_arg (comm->process, "-d");
fr_process_add_arg (comm->process, temp_file);
fr_process_end_command (comm->process);
}
- else if (_g_mime_type_matches (comm->mime_type, "application/x-xz")) {
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-xz")) {
fr_process_begin_command (comm->process, "xz");
fr_process_add_arg (comm->process, "-f");
fr_process_add_arg (comm->process, "-d");
fr_process_add_arg (comm->process, temp_file);
fr_process_end_command (comm->process);
}
- else if (_g_mime_type_matches (comm->mime_type, "application/x-lzop")) {
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-lzop")) {
fr_process_begin_command (comm->process, "lzop");
fr_process_set_working_dir (comm->process, temp_dir);
fr_process_add_arg (comm->process, "-d");
@@ -408,7 +404,7 @@ fr_command_cfile_extract (FrCommand *comm,
fr_process_add_arg (comm->process, temp_file);
fr_process_end_command (comm->process);
}
- else if (_g_mime_type_matches (comm->mime_type, "application/x-rzip")) {
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-rzip")) {
fr_process_begin_command (comm->process, "rzip");
fr_process_add_arg (comm->process, "-f");
fr_process_add_arg (comm->process, "-d");
@@ -462,53 +458,53 @@ const char *cfile_mime_type[] = { "application/x-gzip",
static const char **
-fr_command_cfile_get_mime_types (FrCommand *comm)
+fr_command_cfile_get_mime_types (FrArchive *archive)
{
return cfile_mime_type;
}
-static FrCommandCap
-fr_command_cfile_get_capabilities (FrCommand *comm,
+static FrArchiveCap
+fr_command_cfile_get_capabilities (FrArchive *archive,
const char *mime_type,
gboolean check_command)
{
- FrCommandCap capabilities;
+ FrArchiveCap capabilities;
- capabilities = FR_COMMAND_CAN_DO_NOTHING;
+ capabilities = FR_ARCHIVE_CAN_DO_NOTHING;
if (_g_mime_type_matches (mime_type, "application/x-gzip")) {
if (_g_program_is_available ("gzip", check_command))
- capabilities |= FR_COMMAND_CAN_READ_WRITE;
+ capabilities |= FR_ARCHIVE_CAN_READ_WRITE;
}
else if (_g_mime_type_matches (mime_type, "application/x-bzip")) {
if (_g_program_is_available ("bzip2", check_command))
- capabilities |= FR_COMMAND_CAN_READ_WRITE;
+ capabilities |= FR_ARCHIVE_CAN_READ_WRITE;
}
else if (_g_mime_type_matches (mime_type, "application/x-compress")) {
if (_g_program_is_available ("compress", check_command))
- capabilities |= FR_COMMAND_CAN_WRITE;
+ capabilities |= FR_ARCHIVE_CAN_WRITE;
if (_g_program_is_available ("uncompress", check_command) || _g_program_is_available ("gzip", check_command))
- capabilities |= FR_COMMAND_CAN_READ;
+ capabilities |= FR_ARCHIVE_CAN_READ;
}
else if (_g_mime_type_matches (mime_type, "application/x-lzip")) {
if (_g_program_is_available ("lzip", check_command))
- capabilities |= FR_COMMAND_CAN_READ_WRITE;
+ capabilities |= FR_ARCHIVE_CAN_READ_WRITE;
}
else if (_g_mime_type_matches (mime_type, "application/x-lzma")) {
if (_g_program_is_available ("lzma", check_command))
- capabilities |= FR_COMMAND_CAN_READ_WRITE;
+ capabilities |= FR_ARCHIVE_CAN_READ_WRITE;
}
else if (_g_mime_type_matches (mime_type, "application/x-xz")) {
if (_g_program_is_available ("xz", check_command))
- capabilities |= FR_COMMAND_CAN_READ_WRITE;
+ capabilities |= FR_ARCHIVE_CAN_READ_WRITE;
}
else if (_g_mime_type_matches (mime_type, "application/x-lzop")) {
if (_g_program_is_available ("lzop", check_command))
- capabilities |= FR_COMMAND_CAN_READ_WRITE;
+ capabilities |= FR_ARCHIVE_CAN_READ_WRITE;
}
else if (_g_mime_type_matches (mime_type, "application/x-rzip")) {
if (_g_program_is_available ("rzip", check_command))
- capabilities |= FR_COMMAND_CAN_READ_WRITE;
+ capabilities |= FR_ARCHIVE_CAN_READ_WRITE;
}
return capabilities;
@@ -516,7 +512,7 @@ fr_command_cfile_get_capabilities (FrCommand *comm,
static const char *
-fr_command_cfile_get_packages (FrCommand *comm,
+fr_command_cfile_get_packages (FrArchive *archive,
const char *mime_type)
{
if (_g_mime_type_matches (mime_type, "application/x-gzip"))
@@ -556,6 +552,7 @@ static void
fr_command_cfile_class_init (FrCommandCFileClass *klass)
{
GObjectClass *gobject_class;
+ FrArchiveClass *archive_class;
FrCommandClass *command_class;
fr_command_cfile_parent_class = g_type_class_peek_parent (klass);
@@ -563,21 +560,23 @@ fr_command_cfile_class_init (FrCommandCFileClass *klass)
gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = fr_command_cfile_finalize;
+ archive_class = FR_ARCHIVE_CLASS (klass);
+ archive_class->get_mime_types = fr_command_cfile_get_mime_types;
+ archive_class->get_capabilities = fr_command_cfile_get_capabilities;
+ archive_class->get_packages = fr_command_cfile_get_packages;
+
command_class = FR_COMMAND_CLASS (klass);
command_class->list = fr_command_cfile_list;
command_class->add = fr_command_cfile_add;
command_class->delete = fr_command_cfile_delete;
command_class->extract = fr_command_cfile_extract;
- command_class->get_mime_types = fr_command_cfile_get_mime_types;
- command_class->get_capabilities = fr_command_cfile_get_capabilities;
- command_class->get_packages = fr_command_cfile_get_packages;
}
static void
fr_command_cfile_init (FrCommandCFile *self)
{
- FrCommand *base = FR_COMMAND (self);
+ FrArchive *base = FR_ARCHIVE (self);
base->propAddCanUpdate = TRUE;
base->propAddCanReplace = TRUE;
diff --git a/src/fr-command-cfile.h b/src/fr-command-cfile.h
index a8e3e6b..ded2eac 100644
--- a/src/fr-command-cfile.h
+++ b/src/fr-command-cfile.h
@@ -42,7 +42,7 @@ struct _FrCommandCFile
/*<private>*/
- FrProcError error;
+ FrError error;
};
struct _FrCommandCFileClass
diff --git a/src/fr-command-cpio.c b/src/fr-command-cpio.c
index 40201c7..266968a 100644
--- a/src/fr-command-cpio.c
+++ b/src/fr-command-cpio.c
@@ -157,11 +157,11 @@ list__process_line (char *line,
if (*fdata->name == 0)
file_data_free (fdata);
else
- fr_command_add_file (comm, fdata);
+ fr_archive_add_file (FR_ARCHIVE (comm), fdata);
}
-static void
+static gboolean
fr_command_cpio_list (FrCommand *comm)
{
fr_process_set_out_line_func (comm->process, list__process_line, comm);
@@ -170,7 +170,8 @@ fr_command_cpio_list (FrCommand *comm)
fr_process_add_arg (comm->process, "-c");
fr_process_add_arg_concat (comm->process, "cpio -itv < ", comm->e_filename, NULL);
fr_process_end_command (comm->process);
- fr_process_start (comm->process);
+
+ return TRUE;
}
@@ -218,29 +219,29 @@ const char *cpio_mime_type[] = { "application/x-cpio", NULL };
static const char **
-fr_command_cpio_get_mime_types (FrCommand *comm)
+fr_command_cpio_get_mime_types (FrArchive *archive)
{
return cpio_mime_type;
}
-static FrCommandCap
-fr_command_cpio_get_capabilities (FrCommand *comm,
+static FrArchiveCap
+fr_command_cpio_get_capabilities (FrArchive *archive,
const char *mime_type,
gboolean check_command)
{
- FrCommandCap capabilities;
+ FrArchiveCap capabilities;
- capabilities = FR_COMMAND_CAN_ARCHIVE_MANY_FILES;
+ capabilities = FR_ARCHIVE_CAN_STORE_MANY_FILES;
if (_g_program_is_available ("cpio", check_command))
- capabilities |= FR_COMMAND_CAN_READ;
+ capabilities |= FR_ARCHIVE_CAN_READ;
return capabilities;
}
static const char *
-fr_command_cpio_get_packages (FrCommand *comm,
+fr_command_cpio_get_packages (FrArchive *archive,
const char *mime_type)
{
return PACKAGES ("cpio");
@@ -259,29 +260,32 @@ fr_command_cpio_finalize (GObject *object)
static void
-fr_command_cpio_class_init (FrCommandCpioClass *class)
+fr_command_cpio_class_init (FrCommandCpioClass *klass)
{
GObjectClass *gobject_class;
+ FrArchiveClass *archive_class;
FrCommandClass *command_class;
- fr_command_cpio_parent_class = g_type_class_peek_parent (class);
+ fr_command_cpio_parent_class = g_type_class_peek_parent (klass);
- gobject_class = G_OBJECT_CLASS (class);
+ gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = fr_command_cpio_finalize;
- command_class = FR_COMMAND_CLASS (class);
+ archive_class = FR_ARCHIVE_CLASS (klass);
+ archive_class->get_mime_types = fr_command_cpio_get_mime_types;
+ archive_class->get_capabilities = fr_command_cpio_get_capabilities;
+ archive_class->get_packages = fr_command_cpio_get_packages;
+
+ command_class = FR_COMMAND_CLASS (klass);
command_class->list = fr_command_cpio_list;
command_class->extract = fr_command_cpio_extract;
- command_class->get_mime_types = fr_command_cpio_get_mime_types;
- command_class->get_capabilities = fr_command_cpio_get_capabilities;
- command_class->get_packages = fr_command_cpio_get_packages;
}
static void
fr_command_cpio_init (FrCommandCpio *self)
{
- FrCommand *base = FR_COMMAND (self);
+ FrArchive *base = FR_ARCHIVE (self);
base->propAddCanUpdate = FALSE;
base->propAddCanReplace = FALSE;
diff --git a/src/fr-command-dpkg.c b/src/fr-command-dpkg.c
index 309995c..7325a71 100644
--- a/src/fr-command-dpkg.c
+++ b/src/fr-command-dpkg.c
@@ -68,7 +68,7 @@ process_metadata_line (char *line,
fdata->name = g_strdup (name);
fdata->path = g_strdup ("DEBIAN");
- fr_command_add_file (comm, fdata);
+ fr_archive_add_file (FR_ARCHIVE (comm), fdata);
}
static void
@@ -146,11 +146,11 @@ process_data_line (char *line,
if (*fdata->name == 0)
file_data_free (fdata);
else
- fr_command_add_file (comm, fdata);
+ fr_archive_add_file (FR_ARCHIVE (comm), fdata);
}
-static void
+static gboolean
fr_command_dpkg_list (FrCommand *comm)
{
fr_process_set_out_line_func (comm->process, process_data_line, comm);
@@ -159,13 +159,13 @@ fr_command_dpkg_list (FrCommand *comm)
fr_process_add_arg (comm->process, "-I");
fr_process_add_arg (comm->process, comm->filename);
fr_process_end_command (comm->process);
- fr_process_start (comm->process);
fr_process_begin_command (comm->process, "dpkg-deb");
fr_process_add_arg (comm->process, "-c");
fr_process_add_arg (comm->process, comm->filename);
fr_process_end_command (comm->process);
- fr_process_start (comm->process);
+
+ return TRUE;
}
@@ -204,29 +204,29 @@ const char *dpkg_mime_type[] = { "application/x-deb", NULL };
static const char **
-fr_command_dpkg_get_mime_types (FrCommand *comm)
+fr_command_dpkg_get_mime_types (FrArchive *archive)
{
return dpkg_mime_type;
}
-static FrCommandCap
-fr_command_dpkg_get_capabilities (FrCommand *comm,
+static FrArchiveCap
+fr_command_dpkg_get_capabilities (FrArchive *archive,
const char *mime_type,
gboolean check_command)
{
- FrCommandCap capabilities;
+ FrArchiveCap capabilities;
- capabilities = FR_COMMAND_CAN_ARCHIVE_MANY_FILES;
+ capabilities = FR_ARCHIVE_CAN_STORE_MANY_FILES;
if (_g_program_is_available ("dpkg-deb", check_command))
- capabilities |= FR_COMMAND_CAN_READ;
+ capabilities |= FR_ARCHIVE_CAN_READ;
return capabilities;
}
static const char *
-fr_command_dpkg_get_packages (FrCommand *comm,
+fr_command_dpkg_get_packages (FrArchive *archive,
const char *mime_type)
{
return PACKAGES ("dpkg");
@@ -248,6 +248,7 @@ static void
fr_command_dpkg_class_init (FrCommandDpkgClass *klass)
{
GObjectClass *gobject_class;
+ FrArchiveClass *archive_class;
FrCommandClass *command_class;
fr_command_dpkg_parent_class = g_type_class_peek_parent (klass);
@@ -255,19 +256,21 @@ fr_command_dpkg_class_init (FrCommandDpkgClass *klass)
gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = fr_command_dpkg_finalize;
+ archive_class = FR_ARCHIVE_CLASS (klass);
+ archive_class->get_mime_types = fr_command_dpkg_get_mime_types;
+ archive_class->get_capabilities = fr_command_dpkg_get_capabilities;
+ archive_class->get_packages = fr_command_dpkg_get_packages;
+
command_class = FR_COMMAND_CLASS (klass);
command_class->list = fr_command_dpkg_list;
command_class->extract = fr_command_dpkg_extract;
- command_class->get_mime_types = fr_command_dpkg_get_mime_types;
- command_class->get_capabilities = fr_command_dpkg_get_capabilities;
- command_class->get_packages = fr_command_dpkg_get_packages;
}
static void
fr_command_dpkg_init (FrCommandDpkg *self)
{
- FrCommand *base = FR_COMMAND (self);
+ FrArchive *base = FR_ARCHIVE (self);
base->propAddCanUpdate = FALSE;
base->propAddCanReplace = FALSE;
diff --git a/src/fr-command-iso.c b/src/fr-command-iso.c
index f925002..9a19863 100644
--- a/src/fr-command-iso.c
+++ b/src/fr-command-iso.c
@@ -114,7 +114,7 @@ list__process_line (char *line,
fdata->name = g_strdup (_g_path_get_file_name (fdata->full_path));
fdata->path = _g_path_remove_level (fdata->full_path);
- fr_command_add_file (comm, fdata);
+ fr_archive_add_file (FR_ARCHIVE (comm), fdata);
}
}
@@ -129,7 +129,7 @@ list__begin (gpointer data)
}
-static void
+static gboolean
fr_command_iso_list (FrCommand *comm)
{
fr_process_set_out_line_func (comm->process, list__process_line, comm);
@@ -142,7 +142,7 @@ fr_command_iso_list (FrCommand *comm)
fr_process_add_arg (comm->process, "-l");
fr_process_end_command (comm->process);
- fr_process_start (comm->process);
+ return TRUE;
}
@@ -195,29 +195,29 @@ const char *iso_mime_type[] = { "application/x-cd-image", NULL };
static const char **
-fr_command_iso_get_mime_types (FrCommand *comm)
+fr_command_iso_get_mime_types (FrArchive *archive)
{
return iso_mime_type;
}
-static FrCommandCap
-fr_command_iso_get_capabilities (FrCommand *comm,
+static FrArchiveCap
+fr_command_iso_get_capabilities (FrArchive *archive,
const char *mime_type,
gboolean check_command)
{
- FrCommandCap capabilities;
+ FrArchiveCap capabilities;
- capabilities = FR_COMMAND_CAN_ARCHIVE_MANY_FILES;
+ capabilities = FR_ARCHIVE_CAN_STORE_MANY_FILES;
if (_g_program_is_available ("isoinfo", check_command))
- capabilities |= FR_COMMAND_CAN_READ;
+ capabilities |= FR_ARCHIVE_CAN_READ;
return capabilities;
}
static const char *
-fr_command_iso_get_packages (FrCommand *comm,
+fr_command_iso_get_packages (FrArchive *archive,
const char *mime_type)
{
return PACKAGES ("genisoimage");
@@ -241,29 +241,32 @@ fr_command_iso_finalize (GObject *object)
static void
-fr_command_iso_class_init (FrCommandIsoClass *class)
+fr_command_iso_class_init (FrCommandIsoClass *klass)
{
GObjectClass *gobject_class;
+ FrArchiveClass *archive_class;
FrCommandClass *command_class;
- fr_command_iso_parent_class = g_type_class_peek_parent (class);
+ fr_command_iso_parent_class = g_type_class_peek_parent (klass);
- gobject_class = G_OBJECT_CLASS (class);
+ gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = fr_command_iso_finalize;
- command_class = FR_COMMAND_CLASS (class);
+ archive_class = FR_ARCHIVE_CLASS (klass);
+ archive_class->get_mime_types = fr_command_iso_get_mime_types;
+ archive_class->get_capabilities = fr_command_iso_get_capabilities;
+ archive_class->get_packages = fr_command_iso_get_packages;
+
+ command_class = FR_COMMAND_CLASS (klass);
command_class->list = fr_command_iso_list;
command_class->extract = fr_command_iso_extract;
- command_class->get_mime_types = fr_command_iso_get_mime_types;
- command_class->get_capabilities = fr_command_iso_get_capabilities;
- command_class->get_packages = fr_command_iso_get_packages;
}
static void
fr_command_iso_init (FrCommandIso *self)
{
- FrCommand *base = FR_COMMAND (self);
+ FrArchive *base = FR_ARCHIVE (self);
base->propAddCanUpdate = FALSE;
base->propAddCanReplace = FALSE;
diff --git a/src/fr-command-jar.c b/src/fr-command-jar.c
index f7f0ef2..a72bb56 100644
--- a/src/fr-command-jar.c
+++ b/src/fr-command-jar.c
@@ -145,29 +145,29 @@ const char *jar_mime_type[] = { "application/x-java-archive",
static const char **
-fr_command_jar_get_mime_types (FrCommand *comm)
+fr_command_jar_get_mime_types (FrArchive *archive)
{
return jar_mime_type;
}
-static FrCommandCap
-fr_command_jar_get_capabilities (FrCommand *comm,
+static FrArchiveCap
+fr_command_jar_get_capabilities (FrArchive *archive,
const char *mime_type,
gboolean check_command)
{
- FrCommandCap capabilities;
+ FrArchiveCap capabilities;
- capabilities = FR_COMMAND_CAN_ARCHIVE_MANY_FILES;
+ capabilities = FR_ARCHIVE_CAN_STORE_MANY_FILES;
if (_g_program_is_available ("zip", check_command))
- capabilities |= FR_COMMAND_CAN_READ_WRITE;
+ capabilities |= FR_ARCHIVE_CAN_READ_WRITE;
return capabilities;
}
static const char *
-fr_command_jar_get_packages (FrCommand *comm,
+fr_command_jar_get_packages (FrArchive *archive,
const char *mime_type)
{
return PACKAGES ("zip,unzip");
@@ -189,6 +189,7 @@ static void
fr_command_jar_class_init (FrCommandJarClass *klass)
{
GObjectClass *gobject_class;
+ FrArchiveClass *archive_class;
FrCommandClass *command_class;
fr_command_jar_parent_class = g_type_class_peek_parent (klass);
@@ -196,11 +197,13 @@ fr_command_jar_class_init (FrCommandJarClass *klass)
gobject_class = G_OBJECT_CLASS(klass);
gobject_class->finalize = fr_command_jar_finalize;
+ archive_class = FR_ARCHIVE_CLASS (klass);
+ archive_class->get_mime_types = fr_command_jar_get_mime_types;
+ archive_class->get_capabilities = fr_command_jar_get_capabilities;
+ archive_class->get_packages = fr_command_jar_get_packages;
+
command_class = FR_COMMAND_CLASS (klass);
command_class->add = fr_command_jar_add;
- command_class->get_mime_types = fr_command_jar_get_mime_types;
- command_class->get_capabilities = fr_command_jar_get_capabilities;
- command_class->get_packages = fr_command_jar_get_packages;
}
diff --git a/src/fr-command-lha.c b/src/fr-command-lha.c
index dff2e54..32301ed 100644
--- a/src/fr-command-lha.c
+++ b/src/fr-command-lha.c
@@ -197,11 +197,11 @@ process_line (char *line,
if (*fdata->name == 0)
file_data_free (fdata);
else
- fr_command_add_file (comm, fdata);
+ fr_archive_add_file (FR_ARCHIVE (comm), fdata);
}
-static void
+static gboolean
fr_command_lha_list (FrCommand *comm)
{
fr_process_set_out_line_func (comm->process, process_line, comm);
@@ -210,7 +210,8 @@ fr_command_lha_list (FrCommand *comm)
fr_process_add_arg (comm->process, "lq");
fr_process_add_arg (comm->process, comm->filename);
fr_process_end_command (comm->process);
- fr_process_start (comm->process);
+
+ return TRUE;
}
@@ -297,29 +298,29 @@ const char *lha_mime_type[] = { "application/x-lha", NULL };
static const char **
-fr_command_lha_get_mime_types (FrCommand *comm)
+fr_command_lha_get_mime_types (FrArchive *archive)
{
return lha_mime_type;
}
-static FrCommandCap
-fr_command_lha_get_capabilities (FrCommand *comm,
+static FrArchiveCap
+fr_command_lha_get_capabilities (FrArchive *archive,
const char *mime_type,
gboolean check_command)
{
- FrCommandCap capabilities;
+ FrArchiveCap capabilities;
- capabilities = FR_COMMAND_CAN_ARCHIVE_MANY_FILES;
+ capabilities = FR_ARCHIVE_CAN_STORE_MANY_FILES;
if (_g_program_is_available ("lha", check_command))
- capabilities |= FR_COMMAND_CAN_READ_WRITE;
+ capabilities |= FR_ARCHIVE_CAN_READ_WRITE;
return capabilities;
}
static const char *
-fr_command_lha_get_packages (FrCommand *comm,
+fr_command_lha_get_packages (FrArchive *archive,
const char *mime_type)
{
return PACKAGES ("lha");
@@ -341,6 +342,7 @@ static void
fr_command_lha_class_init (FrCommandLhaClass *klass)
{
GObjectClass *gobject_class;
+ FrArchiveClass *archive_class;
FrCommandClass *command_class;
fr_command_lha_parent_class = g_type_class_peek_parent (klass);
@@ -348,21 +350,23 @@ fr_command_lha_class_init (FrCommandLhaClass *klass)
gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = fr_command_lha_finalize;
+ archive_class = FR_ARCHIVE_CLASS (klass);
+ archive_class->get_mime_types = fr_command_lha_get_mime_types;
+ archive_class->get_capabilities = fr_command_lha_get_capabilities;
+ archive_class->get_packages = fr_command_lha_get_packages;
+
command_class = FR_COMMAND_CLASS (klass);
command_class->list = fr_command_lha_list;
command_class->add = fr_command_lha_add;
command_class->delete = fr_command_lha_delete;
command_class->extract = fr_command_lha_extract;
- command_class->get_mime_types = fr_command_lha_get_mime_types;
- command_class->get_capabilities = fr_command_lha_get_capabilities;
- command_class->get_packages = fr_command_lha_get_packages;
}
static void
fr_command_lha_init (FrCommandLha *self)
{
- FrCommand *base = FR_COMMAND (self);
+ FrArchive *base = FR_ARCHIVE (self);
base->propAddCanUpdate = TRUE;
base->propAddCanReplace = TRUE;
diff --git a/src/fr-command-lrzip.c b/src/fr-command-lrzip.c
index 7eb48ce..2e542e4 100644
--- a/src/fr-command-lrzip.c
+++ b/src/fr-command-lrzip.c
@@ -71,11 +71,11 @@ list__process_line (char *line,
if (fdata->name == 0)
file_data_free (fdata);
else
- fr_command_add_file (comm, fdata);
+ fr_archive_add_file (FR_ARCHIVE (comm), fdata);
}
-static void
+static gboolean
fr_command_lrzip_list (FrCommand *comm)
{
fr_process_set_err_line_func (comm->process, list__process_line, comm);
@@ -84,7 +84,8 @@ fr_command_lrzip_list (FrCommand *comm)
fr_process_add_arg (comm->process, "-i");
fr_process_add_arg (comm->process, comm->filename);
fr_process_end_command (comm->process);
- fr_process_start (comm->process);
+
+ return TRUE;
}
@@ -103,7 +104,7 @@ fr_command_lrzip_add (FrCommand *comm,
/* preserve links. */
- switch (comm->compression) {
+ switch (FR_ARCHIVE (comm)->compression) {
case FR_COMPRESSION_VERY_FAST:
fr_process_add_arg (comm->process, "-l"); break;
case FR_COMPRESSION_FAST:
@@ -161,28 +162,28 @@ const char *lrzip_mime_type[] = { "application/x-lrzip", NULL };
static const char **
-fr_command_lrzip_get_mime_types (FrCommand *comm)
+fr_command_lrzip_get_mime_types (FrArchive *archive)
{
return lrzip_mime_type;
}
-static FrCommandCap
-fr_command_lrzip_get_capabilities (FrCommand *comm,
+static FrArchiveCap
+fr_command_lrzip_get_capabilities (FrArchive *archive,
const char *mime_type,
gboolean check_command)
{
- FrCommandCap capabilities = FR_COMMAND_CAN_DO_NOTHING;
+ FrArchiveCap capabilities = FR_ARCHIVE_CAN_DO_NOTHING;
if (_g_program_is_available ("lrzip", check_command))
- capabilities |= FR_COMMAND_CAN_READ_WRITE;
+ capabilities |= FR_ARCHIVE_CAN_READ_WRITE;
return capabilities;
}
static const char *
-fr_command_lrzip_get_packages (FrCommand *comm,
+fr_command_lrzip_get_packages (FrArchive *archive,
const char *mime_type)
{
return PACKAGES ("lrzip");
@@ -204,6 +205,7 @@ static void
fr_command_lrzip_class_init (FrCommandLrzipClass *klass)
{
GObjectClass *gobject_class;
+ FrArchiveClass *archive_class;
FrCommandClass *command_class;
fr_command_lrzip_parent_class = g_type_class_peek_parent (klass);
@@ -211,20 +213,22 @@ fr_command_lrzip_class_init (FrCommandLrzipClass *klass)
gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = fr_command_lrzip_finalize;
+ archive_class = FR_ARCHIVE_CLASS (klass);
+ archive_class->get_mime_types = fr_command_lrzip_get_mime_types;
+ archive_class->get_capabilities = fr_command_lrzip_get_capabilities;
+ archive_class->get_packages = fr_command_lrzip_get_packages;
+
command_class = FR_COMMAND_CLASS (klass);
command_class->list = fr_command_lrzip_list;
command_class->add = fr_command_lrzip_add;
command_class->extract = fr_command_lrzip_extract;
- command_class->get_mime_types = fr_command_lrzip_get_mime_types;
- command_class->get_capabilities = fr_command_lrzip_get_capabilities;
- command_class->get_packages = fr_command_lrzip_get_packages;
}
static void
fr_command_lrzip_init (FrCommandLrzip *self)
{
- FrCommand *base = FR_COMMAND (self);
+ FrArchive *base = FR_ARCHIVE (self);
base->propAddCanUpdate = FALSE;
base->propAddCanReplace = FALSE;
diff --git a/src/fr-command-rar.c b/src/fr-command-rar.c
index cd70e59..bf9aea9 100644
--- a/src/fr-command-rar.c
+++ b/src/fr-command-rar.c
@@ -101,7 +101,7 @@ process_line (char *line,
rar_comm->odd_line = TRUE;
}
else if (strncmp (line, "Volume ", 7) == 0)
- comm->multi_volume = TRUE;
+ FR_ARCHIVE (comm)->multi_volume = TRUE;
return;
}
@@ -155,7 +155,7 @@ process_line (char *line,
else
fdata->name = g_strdup (_g_path_get_file_name (fdata->full_path));
- fr_command_add_file (comm, fdata);
+ fr_archive_add_file (FR_ARCHIVE (comm), fdata);
rar_comm->fdata = NULL;
}
@@ -200,7 +200,7 @@ add_password_arg (FrCommand *comm,
gboolean disable_query)
{
if ((password != NULL) && (password[0] != '\0')) {
- if (comm->encrypt_header)
+ if (FR_ARCHIVE (comm)->encrypt_header)
fr_process_add_arg_concat (comm->process, "-hp", password, NULL);
else
fr_process_add_arg_concat (comm->process, "-p", password, NULL);
@@ -219,7 +219,7 @@ list__begin (gpointer data)
}
-static void
+static gboolean
fr_command_rar_list (FrCommand *comm)
{
rar_check_multi_volume (comm);
@@ -235,7 +235,7 @@ fr_command_rar_list (FrCommand *comm)
fr_process_add_arg (comm->process, "-c-");
fr_process_add_arg (comm->process, "-v");
- add_password_arg (comm, comm->password, TRUE);
+ add_password_arg (comm, FR_ARCHIVE (comm)->password, TRUE);
/* stop switches scanning */
fr_process_add_arg (comm->process, "--");
@@ -243,7 +243,7 @@ fr_command_rar_list (FrCommand *comm)
fr_process_add_arg (comm->process, comm->filename);
fr_process_end_command (comm->process);
- fr_process_start (comm->process);
+ return TRUE;
}
@@ -253,12 +253,13 @@ parse_progress_line (FrCommand *comm,
const char *message_format,
const char *line)
{
- int prefix_len;
+ FrArchive *archive = FR_ARCHIVE (comm);
+ int prefix_len;
prefix_len = strlen (prefix);
if (strncmp (line, prefix, prefix_len) == 0) {
- if (comm->n_files > 1) {
- fr_command_progress (comm, (double) ++comm->n_file / (comm->n_files + 1));
+ if (archive->n_files > 1) {
+ fr_archive_progress (archive, (double) ++archive->n_file / (archive->n_files + 1));
}
else {
char filename[4096];
@@ -280,7 +281,7 @@ parse_progress_line (FrCommand *comm,
filename[len - 5] = 0;
msg = g_strdup_printf (message_format, _g_path_get_file_name (filename), NULL);
- fr_command_message (comm, msg);
+ fr_archive_message (archive, msg);
g_free (msg);
}
@@ -293,13 +294,14 @@ process_line__add (char *line,
gpointer data)
{
FrCommand *comm = FR_COMMAND (data);
+ FrArchive *archive = FR_ARCHIVE (comm);
if (strncmp (line, "Creating archive ", 17) == 0) {
const char *archive_filename = line + 17;
char *uri;
uri = g_filename_to_uri (archive_filename, NULL, NULL);
- if ((comm->volume_size > 0)
+ if ((archive->volume_size > 0)
&& g_regex_match_simple ("^.*\\.part(0)*2\\.rar$", uri, G_REGEX_CASELESS, 0))
{
char *volume_filename;
@@ -308,18 +310,18 @@ process_line__add (char *line,
volume_filename = g_strdup (archive_filename);
volume_filename[strlen (volume_filename) - 5] = '1';
volume_file = g_file_new_for_path (volume_filename);
- fr_command_set_multi_volume (comm, volume_file);
+ fr_archive_set_multi_volume (archive, volume_file);
g_object_unref (volume_file);
g_free (volume_filename);
}
- fr_command_working_archive (comm, uri);
+ fr_archive_working_archive (archive, uri);
g_free (uri);
return;
}
- if (comm->n_files != 0)
+ if (archive->n_files != 0)
parse_progress_line (comm, "Adding ", _("Adding \"%s\""), line);
}
@@ -349,7 +351,7 @@ fr_command_rar_add (FrCommand *comm,
else
fr_process_add_arg (comm->process, "a");
- switch (comm->compression) {
+ switch (FR_ARCHIVE (comm)->compression) {
case FR_COMPRESSION_VERY_FAST:
fr_process_add_arg (comm->process, "-m1"); break;
case FR_COMPRESSION_FAST:
@@ -360,10 +362,10 @@ fr_command_rar_add (FrCommand *comm,
fr_process_add_arg (comm->process, "-m5"); break;
}
- add_password_arg (comm, comm->password, FALSE);
+ add_password_arg (comm, FR_ARCHIVE (comm)->password, FALSE);
- if (comm->volume_size > 0)
- fr_process_add_arg_printf (comm->process, "-v%ub", comm->volume_size);
+ if (FR_ARCHIVE (comm)->volume_size > 0)
+ fr_process_add_arg_printf (comm->process, "-v%ub", FR_ARCHIVE (comm)->volume_size);
/* disable percentage indicator */
fr_process_add_arg (comm->process, "-Idp");
@@ -391,13 +393,13 @@ process_line__delete (char *line,
char *uri;
uri = g_filename_to_uri (line + 14, NULL, NULL);
- fr_command_working_archive (comm, uri);
+ fr_archive_working_archive (FR_ARCHIVE (comm), uri);
g_free (uri);
return;
}
- if (comm->n_files != 0)
+ if (FR_ARCHIVE (comm)->n_files != 0)
parse_progress_line (comm, "Deleting ", _("Removing \"%s\""), line);
}
@@ -440,13 +442,13 @@ process_line__extract (char *line,
char *uri;
uri = g_filename_to_uri (line + 16, NULL, NULL);
- fr_command_working_archive (comm, uri);
+ fr_archive_working_archive (FR_ARCHIVE (comm), uri);
g_free (uri);
return;
}
- if (comm->n_files != 0)
+ if (FR_ARCHIVE (comm)->n_files != 0)
parse_progress_line (comm, "Extracting ", _("Extracting \"%s\""), line);
}
@@ -488,7 +490,7 @@ fr_command_rar_extract (FrCommand *comm,
if (junk_paths)
fr_process_add_arg (comm->process, "-ep");
- add_password_arg (comm, comm->password, TRUE);
+ add_password_arg (comm, FR_ARCHIVE (comm)->password, TRUE);
/* disable percentage indicator */
fr_process_add_arg (comm->process, "-Idp");
@@ -519,7 +521,7 @@ fr_command_rar_test (FrCommand *comm)
fr_process_add_arg (comm->process, "t");
- add_password_arg (comm, comm->password, TRUE);
+ add_password_arg (comm, FR_ARCHIVE (comm)->password, TRUE);
/* disable percentage indicator */
fr_process_add_arg (comm->process, "-Idp");
@@ -534,7 +536,7 @@ fr_command_rar_test (FrCommand *comm)
static void
fr_command_rar_handle_error (FrCommand *comm,
- FrProcError *error)
+ FrError *error)
{
GList *scan;
@@ -547,25 +549,25 @@ fr_command_rar_handle_error (FrCommand *comm,
}
#endif
- if (error->type == FR_PROC_ERROR_NONE)
+ if (error->type == FR_ERROR_NONE)
return;
/*if (error->status == 3)
- error->type = FR_PROC_ERROR_ASK_PASSWORD;
+ error->type = FR_ERROR_ASK_PASSWORD;
else */
if (error->status <= 1)
- error->type = FR_PROC_ERROR_NONE;
+ error->type = FR_ERROR_NONE;
for (scan = g_list_last (comm->process->err.raw); scan; scan = scan->prev) {
char *line = scan->data;
if (strstr (line, "password incorrect") != NULL) {
- error->type = FR_PROC_ERROR_ASK_PASSWORD;
+ error->type = FR_ERROR_ASK_PASSWORD;
break;
}
if (strstr (line, "wrong password") != NULL) {
- error->type = FR_PROC_ERROR_ASK_PASSWORD;
+ error->type = FR_ERROR_ASK_PASSWORD;
break;
}
@@ -578,7 +580,7 @@ fr_command_rar_handle_error (FrCommand *comm,
g_clear_error (&error->gerror);
- error->type = FR_PROC_ERROR_MISSING_VOLUME;
+ error->type = FR_ERROR_MISSING_VOLUME;
volume_filename = g_path_get_basename (line + strlen ("Cannot find volume "));
error->gerror = g_error_new (FR_ERROR, error->status, _("Could not find the volume: %s"), volume_filename);
g_free (volume_filename);
@@ -594,35 +596,35 @@ const char *rar_mime_type[] = { "application/x-cbr",
static const char **
-fr_command_rar_get_mime_types (FrCommand *comm)
+fr_command_rar_get_mime_types (FrArchive *archive)
{
return rar_mime_type;
}
-static FrCommandCap
-fr_command_rar_get_capabilities (FrCommand *comm,
+static FrArchiveCap
+fr_command_rar_get_capabilities (FrArchive *archive,
const char *mime_type,
gboolean check_command)
{
- FrCommandCap capabilities;
+ FrArchiveCap capabilities;
- capabilities = FR_COMMAND_CAN_ARCHIVE_MANY_FILES | FR_COMMAND_CAN_ENCRYPT | FR_COMMAND_CAN_ENCRYPT_HEADER;
+ capabilities = FR_ARCHIVE_CAN_STORE_MANY_FILES | FR_ARCHIVE_CAN_ENCRYPT | FR_ARCHIVE_CAN_ENCRYPT_HEADER;
if (_g_program_is_available ("rar", check_command))
- capabilities |= FR_COMMAND_CAN_READ_WRITE | FR_COMMAND_CAN_CREATE_VOLUMES;
+ capabilities |= FR_ARCHIVE_CAN_READ_WRITE | FR_ARCHIVE_CAN_CREATE_VOLUMES;
else if (_g_program_is_available ("unrar", check_command))
- capabilities |= FR_COMMAND_CAN_READ;
+ capabilities |= FR_ARCHIVE_CAN_READ;
/* multi-volumes are read-only */
- if ((comm->files->len > 0) && comm->multi_volume && (capabilities & FR_COMMAND_CAN_WRITE))
- capabilities ^= FR_COMMAND_CAN_WRITE;
+ if ((archive->files->len > 0) && archive->multi_volume && (capabilities & FR_ARCHIVE_CAN_WRITE))
+ capabilities ^= FR_ARCHIVE_CAN_WRITE;
return capabilities;
}
static const char *
-fr_command_rar_get_packages (FrCommand *comm,
+fr_command_rar_get_packages (FrArchive *archive,
const char *mime_type)
{
return PACKAGES ("rar,unrar");
@@ -644,6 +646,7 @@ static void
fr_command_rar_class_init (FrCommandRarClass *klass)
{
GObjectClass *gobject_class;
+ FrArchiveClass *archive_class;
FrCommandClass *command_class;
fr_command_rar_parent_class = g_type_class_peek_parent (klass);
@@ -651,6 +654,11 @@ fr_command_rar_class_init (FrCommandRarClass *klass)
gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = fr_command_rar_finalize;
+ archive_class = FR_ARCHIVE_CLASS (klass);
+ archive_class->get_mime_types = fr_command_rar_get_mime_types;
+ archive_class->get_capabilities = fr_command_rar_get_capabilities;
+ archive_class->get_packages = fr_command_rar_get_packages;
+
command_class = FR_COMMAND_CLASS (klass);
command_class->list = fr_command_rar_list;
command_class->add = fr_command_rar_add;
@@ -658,16 +666,13 @@ fr_command_rar_class_init (FrCommandRarClass *klass)
command_class->extract = fr_command_rar_extract;
command_class->test = fr_command_rar_test;
command_class->handle_error = fr_command_rar_handle_error;
- command_class->get_mime_types = fr_command_rar_get_mime_types;
- command_class->get_capabilities = fr_command_rar_get_capabilities;
- command_class->get_packages = fr_command_rar_get_packages;
}
static void
fr_command_rar_init (FrCommandRar *self)
{
- FrCommand *base = FR_COMMAND (self);
+ FrArchive *base = FR_ARCHIVE (self);
base->propAddCanUpdate = TRUE;
base->propAddCanReplace = TRUE;
diff --git a/src/fr-command-rpm.c b/src/fr-command-rpm.c
index 39bb3a1..88b42c7 100644
--- a/src/fr-command-rpm.c
+++ b/src/fr-command-rpm.c
@@ -165,11 +165,11 @@ list__process_line (char *line,
if (*fdata->name == 0)
file_data_free (fdata);
else
- fr_command_add_file (comm, fdata);
+ fr_archive_add_file (FR_ARCHIVE (comm), fdata);
}
-static void
+static gboolean
fr_command_rpm_list (FrCommand *comm)
{
fr_process_set_out_line_func (comm->process, list__process_line, comm);
@@ -178,7 +178,8 @@ fr_command_rpm_list (FrCommand *comm)
fr_process_add_arg (comm->process, "-c");
fr_process_add_arg_concat (comm->process, PRIVEXECDIR "rpm2cpio ", comm->e_filename, " -itv", NULL);
fr_process_end_command (comm->process);
- fr_process_start (comm->process);
+
+ return TRUE;
}
@@ -219,29 +220,29 @@ const char *rpm_mime_type[] = { "application/x-rpm", NULL };
static const char **
-fr_command_rpm_get_mime_types (FrCommand *comm)
+fr_command_rpm_get_mime_types (FrArchive *archive)
{
return rpm_mime_type;
}
-static FrCommandCap
-fr_command_rpm_get_capabilities (FrCommand *comm,
+static FrArchiveCap
+fr_command_rpm_get_capabilities (FrArchive *archive,
const char *mime_type,
gboolean check_command)
{
- FrCommandCap capabilities;
+ FrArchiveCap capabilities;
- capabilities = FR_COMMAND_CAN_ARCHIVE_MANY_FILES;
+ capabilities = FR_ARCHIVE_CAN_STORE_MANY_FILES;
if (_g_program_is_available ("cpio", check_command))
- capabilities |= FR_COMMAND_CAN_READ;
+ capabilities |= FR_ARCHIVE_CAN_READ;
return capabilities;
}
static const char *
-fr_command_rpm_get_packages (FrCommand *comm,
+fr_command_rpm_get_packages (FrArchive *archive,
const char *mime_type)
{
return PACKAGES ("cpio,rpm");
@@ -264,6 +265,7 @@ static void
fr_command_rpm_class_init (FrCommandRpmClass *klass)
{
GObjectClass *gobject_class;
+ FrArchiveClass *archive_class;
FrCommandClass *command_class;
fr_command_rpm_parent_class = g_type_class_peek_parent (klass);
@@ -271,19 +273,21 @@ fr_command_rpm_class_init (FrCommandRpmClass *klass)
gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = fr_command_rpm_finalize;
+ archive_class = FR_ARCHIVE_CLASS (klass);
+ archive_class->get_mime_types = fr_command_rpm_get_mime_types;
+ archive_class->get_capabilities = fr_command_rpm_get_capabilities;
+ archive_class->get_packages = fr_command_rpm_get_packages;
+
command_class = FR_COMMAND_CLASS (klass);
command_class->list = fr_command_rpm_list;
command_class->extract = fr_command_rpm_extract;
- command_class->get_mime_types = fr_command_rpm_get_mime_types;
- command_class->get_capabilities = fr_command_rpm_get_capabilities;
- command_class->get_packages = fr_command_rpm_get_packages;
}
static void
fr_command_rpm_init (FrCommandRpm *self)
{
- FrCommand *base = FR_COMMAND (self);
+ FrArchive *base = FR_ARCHIVE (self);
base->propAddCanUpdate = FALSE;
base->propAddCanReplace = FALSE;
diff --git a/src/fr-command-tar.c b/src/fr-command-tar.c
index 6cc3d85..7082a04 100644
--- a/src/fr-command-tar.c
+++ b/src/fr-command-tar.c
@@ -181,41 +181,43 @@ process_line (char *line,
if (*fdata->name == 0)
file_data_free (fdata);
else
- fr_command_add_file (comm, fdata);
+ fr_archive_add_file (FR_ARCHIVE (comm), fdata);
}
static void
add_compress_arg (FrCommand *comm)
{
- if (_g_mime_type_matches (comm->mime_type, "application/x-compressed-tar"))
+ FrArchive *archive = FR_ARCHIVE (comm);
+
+ if (_g_mime_type_matches (archive->mime_type, "application/x-compressed-tar"))
fr_process_add_arg (comm->process, "-z");
- else if (_g_mime_type_matches (comm->mime_type, "application/x-bzip-compressed-tar"))
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-bzip-compressed-tar"))
fr_process_add_arg (comm->process, "--use-compress-program=bzip2");
- else if (_g_mime_type_matches (comm->mime_type, "application/x-tarz")) {
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-tarz")) {
if (_g_program_is_in_path ("gzip"))
fr_process_add_arg (comm->process, "-z");
else
fr_process_add_arg (comm->process, "-Z");
}
- else if (_g_mime_type_matches (comm->mime_type, "application/x-lrzip-compressed-tar"))
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-lrzip-compressed-tar"))
fr_process_add_arg (comm->process, "--use-compress-program=lrzip");
- else if (_g_mime_type_matches (comm->mime_type, "application/x-lzip-compressed-tar"))
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-lzip-compressed-tar"))
fr_process_add_arg (comm->process, "--use-compress-program=lzip");
- else if (_g_mime_type_matches (comm->mime_type, "application/x-lzma-compressed-tar"))
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-lzma-compressed-tar"))
fr_process_add_arg (comm->process, "--use-compress-program=lzma");
- else if (_g_mime_type_matches (comm->mime_type, "application/x-xz-compressed-tar"))
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-xz-compressed-tar"))
fr_process_add_arg (comm->process, "--use-compress-program=xz");
- else if (_g_mime_type_matches (comm->mime_type, "application/x-lzop-compressed-tar"))
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-lzop-compressed-tar"))
fr_process_add_arg (comm->process, "--use-compress-program=lzop");
- else if (_g_mime_type_matches (comm->mime_type, "application/x-7z-compressed-tar")) {
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-7z-compressed-tar")) {
FrCommandTar *comm_tar = (FrCommandTar*) comm;
char *option;
@@ -246,7 +248,7 @@ begin_tar_command (FrCommand *comm)
}
-static void
+static gboolean
fr_command_tar_list (FrCommand *comm)
{
fr_process_set_out_line_func (comm->process, process_line, comm);
@@ -258,14 +260,15 @@ fr_command_tar_list (FrCommand *comm)
fr_process_add_arg (comm->process, comm->filename);
add_compress_arg (comm);
fr_process_end_command (comm->process);
- fr_process_start (comm->process);
+
+ return TRUE;
}
static gboolean
can_create_a_compressed_archive (FrCommand *comm)
{
- return comm->creating_archive && ! _g_mime_type_matches (comm->mime_type, "application/x-7z-compressed-tar");
+ return comm->creating_archive && ! _g_mime_type_matches (FR_ARCHIVE (comm)->mime_type, "application/x-7z-compressed-tar");
}
@@ -275,6 +278,7 @@ process_line__generic (char *line,
char *message_format)
{
FrCommand *comm = FR_COMMAND (data);
+ FrArchive *archive = FR_ARCHIVE (comm);
if (line == NULL)
return;
@@ -282,13 +286,13 @@ process_line__generic (char *line,
if (line[strlen (line) - 1] == '/') /* ignore directories */
return;
- if (comm->n_files > 1) {
- double fraction = (double) ++comm->n_file / (comm->n_files + 1);
- fr_command_progress (comm, fraction);
+ if (archive->n_files > 1) {
+ double fraction = (double) ++archive->n_file / (archive->n_files + 1);
+ fr_archive_progress (archive, fraction);
}
else {
char *msg = g_strdup_printf (message_format, _g_path_get_file_name (line), NULL);
- fr_command_message (comm, msg);
+ fr_archive_message (archive, msg);
g_free (msg);
}
}
@@ -371,9 +375,10 @@ process_line__delete (char *line,
static void
begin_func__delete (gpointer data)
{
- FrCommand *comm = data;
- fr_command_progress (comm, -1.0);
- fr_command_message (comm, _("Deleting files from archive"));
+ FrArchive *archive = data;
+
+ fr_archive_progress (archive, -1.0);
+ fr_archive_message (archive, _("Deleting files from archive"));
}
@@ -475,26 +480,23 @@ fr_command_tar_extract (FrCommand *comm,
static void
begin_func__recompress (gpointer data)
{
- FrCommand *comm = data;
- fr_command_progress (comm, -1.0);
- fr_command_message (comm, _("Recompressing archive"));
+ FrArchive *archive = data;
+
+ fr_archive_progress (archive, -1.0);
+ fr_archive_message (archive, _("Recompressing archive"));
}
static gboolean
-gzip_continue_func (gpointer user_data)
+gzip_continue_func (FrError **error,
+ gpointer user_data)
{
- FrCommand *comm = user_data;
-
/* ignore gzip warnings */
- if (comm->process->error.status == 2) {
- comm->process->error.type = FR_PROC_ERROR_NONE;
- comm->process->error.status = 0;
- g_clear_error (&comm->process->error.gerror);
- }
+ if ((*error != NULL) && ((*error)->status == 2))
+ fr_clear_error (error);
- return comm->process->error.status == 0;
+ return *error == NULL;
}
@@ -502,16 +504,17 @@ static void
fr_command_tar_recompress (FrCommand *comm)
{
FrCommandTar *c_tar = FR_COMMAND_TAR (comm);
+ FrArchive *archive = FR_ARCHIVE (comm);
char *new_name = NULL;
if (can_create_a_compressed_archive (comm))
return;
- if (_g_mime_type_matches (comm->mime_type, "application/x-compressed-tar")) {
+ if (_g_mime_type_matches (archive->mime_type, "application/x-compressed-tar")) {
fr_process_begin_command (comm->process, "gzip");
fr_process_set_begin_func (comm->process, begin_func__recompress, comm);
fr_process_set_continue_func (comm->process, gzip_continue_func, comm);
- switch (comm->compression) {
+ switch (archive->compression) {
case FR_COMPRESSION_VERY_FAST:
fr_process_add_arg (comm->process, "-1"); break;
case FR_COMPRESSION_FAST:
@@ -527,10 +530,10 @@ fr_command_tar_recompress (FrCommand *comm)
new_name = g_strconcat (c_tar->uncomp_filename, ".gz", NULL);
}
- else if (_g_mime_type_matches (comm->mime_type, "application/x-bzip-compressed-tar")) {
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-bzip-compressed-tar")) {
fr_process_begin_command (comm->process, "bzip2");
fr_process_set_begin_func (comm->process, begin_func__recompress, comm);
- switch (comm->compression) {
+ switch (archive->compression) {
case FR_COMPRESSION_VERY_FAST:
fr_process_add_arg (comm->process, "-1"); break;
case FR_COMPRESSION_FAST:
@@ -546,7 +549,7 @@ fr_command_tar_recompress (FrCommand *comm)
new_name = g_strconcat (c_tar->uncomp_filename, ".bz2", NULL);
}
- else if (_g_mime_type_matches (comm->mime_type, "application/x-tarz")) {
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-tarz")) {
fr_process_begin_command (comm->process, "compress");
fr_process_set_begin_func (comm->process, begin_func__recompress, comm);
fr_process_add_arg (comm->process, "-f");
@@ -555,10 +558,10 @@ fr_command_tar_recompress (FrCommand *comm)
new_name = g_strconcat (c_tar->uncomp_filename, ".Z", NULL);
}
- else if (_g_mime_type_matches (comm->mime_type, "application/x-lrzip-compressed-tar")) {
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-lrzip-compressed-tar")) {
fr_process_begin_command (comm->process, "lrzip");
fr_process_set_begin_func (comm->process, begin_func__recompress, comm);
- switch (comm->compression) {
+ switch (archive->compression) {
case FR_COMPRESSION_VERY_FAST:
fr_process_add_arg (comm->process, "-l"); break;
case FR_COMPRESSION_FAST:
@@ -574,10 +577,10 @@ fr_command_tar_recompress (FrCommand *comm)
new_name = g_strconcat (c_tar->uncomp_filename, ".lrz", NULL);
}
- else if (_g_mime_type_matches (comm->mime_type, "application/x-lzip-compressed-tar")) {
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-lzip-compressed-tar")) {
fr_process_begin_command (comm->process, "lzip");
fr_process_set_begin_func (comm->process, begin_func__recompress, comm);
- switch (comm->compression) {
+ switch (archive->compression) {
case FR_COMPRESSION_VERY_FAST:
fr_process_add_arg (comm->process, "-1"); break;
case FR_COMPRESSION_FAST:
@@ -593,10 +596,10 @@ fr_command_tar_recompress (FrCommand *comm)
new_name = g_strconcat (c_tar->uncomp_filename, ".lz", NULL);
}
- else if (_g_mime_type_matches (comm->mime_type, "application/x-lzma-compressed-tar")) {
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-lzma-compressed-tar")) {
fr_process_begin_command (comm->process, "lzma");
fr_process_set_begin_func (comm->process, begin_func__recompress, comm);
- switch (comm->compression) {
+ switch (archive->compression) {
case FR_COMPRESSION_VERY_FAST:
fr_process_add_arg (comm->process, "-1"); break;
case FR_COMPRESSION_FAST:
@@ -612,10 +615,10 @@ fr_command_tar_recompress (FrCommand *comm)
new_name = g_strconcat (c_tar->uncomp_filename, ".lzma", NULL);
}
- else if (_g_mime_type_matches (comm->mime_type, "application/x-xz-compressed-tar")) {
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-xz-compressed-tar")) {
fr_process_begin_command (comm->process, "xz");
fr_process_set_begin_func (comm->process, begin_func__recompress, comm);
- switch (comm->compression) {
+ switch (archive->compression) {
case FR_COMPRESSION_VERY_FAST:
fr_process_add_arg (comm->process, "-1"); break;
case FR_COMPRESSION_FAST:
@@ -631,10 +634,10 @@ fr_command_tar_recompress (FrCommand *comm)
new_name = g_strconcat (c_tar->uncomp_filename, ".xz", NULL);
}
- else if (_g_mime_type_matches (comm->mime_type, "application/x-lzop-compressed-tar")) {
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-lzop-compressed-tar")) {
fr_process_begin_command (comm->process, "lzop");
fr_process_set_begin_func (comm->process, begin_func__recompress, comm);
- switch (comm->compression) {
+ switch (archive->compression) {
case FR_COMPRESSION_VERY_FAST:
fr_process_add_arg (comm->process, "-1"); break;
case FR_COMPRESSION_FAST:
@@ -651,12 +654,12 @@ fr_command_tar_recompress (FrCommand *comm)
new_name = g_strconcat (c_tar->uncomp_filename, ".lzo", NULL);
}
- else if (_g_mime_type_matches (comm->mime_type, "application/x-7z-compressed-tar")) {
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-7z-compressed-tar")) {
FrCommandTar *comm_tar = (FrCommandTar*) comm;
fr_process_begin_command (comm->process, comm_tar->compress_command);
fr_process_set_begin_func (comm->process, begin_func__recompress, comm);
- switch (comm->compression) {
+ switch (archive->compression) {
case FR_COMPRESSION_VERY_FAST:
fr_process_add_arg (comm->process, "-mx=1"); break;
case FR_COMPRESSION_FAST:
@@ -716,9 +719,10 @@ fr_command_tar_recompress (FrCommand *comm)
static void
begin_func__uncompress (gpointer data)
{
- FrCommand *comm = data;
- fr_command_progress (comm, -1.0);
- fr_command_message (comm, _("Decompressing archive"));
+ FrArchive *archive = data;
+
+ fr_archive_progress (archive, -1.0);
+ fr_archive_message (archive, _("Decompressing archive"));
}
@@ -727,10 +731,11 @@ get_uncompressed_name (FrCommandTar *c_tar,
const char *e_filename)
{
FrCommand *comm = FR_COMMAND (c_tar);
+ FrArchive *archive = FR_ARCHIVE (comm);
char *new_name = g_strdup (e_filename);
int l = strlen (new_name);
- if (_g_mime_type_matches (comm->mime_type, "application/x-compressed-tar")) {
+ if (_g_mime_type_matches (archive->mime_type, "application/x-compressed-tar")) {
/* X.tgz --> X.tar
* X.tar.gz --> X.tar */
if (_g_filename_has_extension (e_filename, ".tgz")) {
@@ -740,7 +745,7 @@ get_uncompressed_name (FrCommandTar *c_tar,
else if (_g_filename_has_extension (e_filename, ".tar.gz"))
new_name[l - 3] = 0;
}
- else if (_g_mime_type_matches (comm->mime_type, "application/x-bzip-compressed-tar")) {
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-bzip-compressed-tar")) {
/* X.tbz2 --> X.tar
* X.tar.bz2 --> X.tar */
if (_g_filename_has_extension (e_filename, ".tbz2")) {
@@ -751,7 +756,7 @@ get_uncompressed_name (FrCommandTar *c_tar,
else if (_g_filename_has_extension (e_filename, ".tar.bz2"))
new_name[l - 4] = 0;
}
- else if (_g_mime_type_matches (comm->mime_type, "application/x-tarz")) {
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-tarz")) {
/* X.taz --> X.tar
* X.tar.Z --> X.tar */
if (_g_filename_has_extension (e_filename, ".taz"))
@@ -759,7 +764,7 @@ get_uncompressed_name (FrCommandTar *c_tar,
else if (_g_filename_has_extension (e_filename, ".tar.Z"))
new_name[l - 2] = 0;
}
- else if (_g_mime_type_matches (comm->mime_type, "application/x-lrzip-compressed-tar")) {
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-lrzip-compressed-tar")) {
/* X.tlrz --> X.tar
* X.tar.lrz --> X.tar */
if (_g_filename_has_extension (e_filename, ".tlrz")) {
@@ -770,7 +775,7 @@ get_uncompressed_name (FrCommandTar *c_tar,
else if (_g_filename_has_extension (e_filename, ".tar.lrz"))
new_name[l - 4] = 0;
}
- else if (_g_mime_type_matches (comm->mime_type, "application/x-lzip-compressed-tar")) {
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-lzip-compressed-tar")) {
/* X.tlz --> X.tar
* X.tar.lz --> X.tar */
if (_g_filename_has_extension (e_filename, ".tlz")) {
@@ -780,19 +785,19 @@ get_uncompressed_name (FrCommandTar *c_tar,
else if (_g_filename_has_extension (e_filename, ".tar.lz"))
new_name[l - 3] = 0;
}
- else if (_g_mime_type_matches (comm->mime_type, "application/x-lzma-compressed-tar")) {
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-lzma-compressed-tar")) {
/* X.tar.lzma --> X.tar
* (There doesn't seem to be a shorthand suffix) */
if (_g_filename_has_extension (e_filename, ".tar.lzma"))
new_name[l - 5] = 0;
}
- else if (_g_mime_type_matches (comm->mime_type, "application/x-xz-compressed-tar")) {
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-xz-compressed-tar")) {
/* X.tar.xz --> X.tar
* (There doesn't seem to be a shorthand suffix) */
if (_g_filename_has_extension (e_filename, ".tar.xz"))
new_name[l - 3] = 0;
}
- else if (_g_mime_type_matches (comm->mime_type, "application/x-lzop-compressed-tar")) {
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-lzop-compressed-tar")) {
/* X.tzo --> X.tar
* X.tar.lzo --> X.tar */
if (_g_filename_has_extension (e_filename, ".tzo")) {
@@ -802,7 +807,7 @@ get_uncompressed_name (FrCommandTar *c_tar,
else if (_g_filename_has_extension (e_filename, ".tar.lzo"))
new_name[l - 4] = 0;
}
- else if (_g_mime_type_matches (comm->mime_type, "application/x-7z-compressed-tar")) {
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-7z-compressed-tar")) {
/* X.tar.7z --> X.tar */
if (_g_filename_has_extension (e_filename, ".tar.7z"))
new_name[l - 3] = 0;
@@ -837,6 +842,7 @@ static void
fr_command_tar_uncompress (FrCommand *comm)
{
FrCommandTar *c_tar = FR_COMMAND_TAR (comm);
+ FrArchive *archive = FR_ARCHIVE (comm);
char *tmp_name;
gboolean archive_exists;
@@ -850,7 +856,7 @@ fr_command_tar_uncompress (FrCommand *comm)
archive_exists = ! comm->creating_archive;
- c_tar->name_modified = ! _g_mime_type_matches (comm->mime_type, "application/x-tar");
+ c_tar->name_modified = ! _g_mime_type_matches (archive->mime_type, "application/x-tar");
if (c_tar->name_modified) {
tmp_name = get_temp_name (c_tar, comm->filename);
if (archive_exists) {
@@ -865,7 +871,7 @@ fr_command_tar_uncompress (FrCommand *comm)
tmp_name = g_strdup (comm->filename);
if (archive_exists) {
- if (_g_mime_type_matches (comm->mime_type, "application/x-compressed-tar")) {
+ if (_g_mime_type_matches (archive->mime_type, "application/x-compressed-tar")) {
fr_process_begin_command (comm->process, "gzip");
fr_process_set_begin_func (comm->process, begin_func__uncompress, comm);
fr_process_set_continue_func (comm->process, gzip_continue_func, comm);
@@ -874,7 +880,7 @@ fr_command_tar_uncompress (FrCommand *comm)
fr_process_add_arg (comm->process, tmp_name);
fr_process_end_command (comm->process);
}
- else if (_g_mime_type_matches (comm->mime_type, "application/x-bzip-compressed-tar")) {
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-bzip-compressed-tar")) {
fr_process_begin_command (comm->process, "bzip2");
fr_process_set_begin_func (comm->process, begin_func__uncompress, comm);
fr_process_add_arg (comm->process, "-f");
@@ -882,7 +888,7 @@ fr_command_tar_uncompress (FrCommand *comm)
fr_process_add_arg (comm->process, tmp_name);
fr_process_end_command (comm->process);
}
- else if (_g_mime_type_matches (comm->mime_type, "application/x-tarz")) {
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-tarz")) {
if (_g_program_is_in_path ("gzip")) {
fr_process_begin_command (comm->process, "gzip");
fr_process_set_continue_func (comm->process, gzip_continue_func, comm);
@@ -894,7 +900,7 @@ fr_command_tar_uncompress (FrCommand *comm)
fr_process_add_arg (comm->process, tmp_name);
fr_process_end_command (comm->process);
}
- else if (_g_mime_type_matches (comm->mime_type, "application/x-lrzip-compressed-tar")) {
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-lrzip-compressed-tar")) {
fr_process_begin_command (comm->process, "lrzip");
fr_process_set_begin_func (comm->process, begin_func__uncompress, comm);
fr_process_add_arg (comm->process, "-f");
@@ -902,7 +908,7 @@ fr_command_tar_uncompress (FrCommand *comm)
fr_process_add_arg (comm->process, tmp_name);
fr_process_end_command (comm->process);
}
- else if (_g_mime_type_matches (comm->mime_type, "application/x-lzip-compressed-tar")) {
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-lzip-compressed-tar")) {
fr_process_begin_command (comm->process, "lzip");
fr_process_set_begin_func (comm->process, begin_func__uncompress, comm);
fr_process_add_arg (comm->process, "-f");
@@ -910,7 +916,7 @@ fr_command_tar_uncompress (FrCommand *comm)
fr_process_add_arg (comm->process, tmp_name);
fr_process_end_command (comm->process);
}
- else if (_g_mime_type_matches (comm->mime_type, "application/x-lzma-compressed-tar")) {
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-lzma-compressed-tar")) {
fr_process_begin_command (comm->process, "lzma");
fr_process_set_begin_func (comm->process, begin_func__uncompress, comm);
fr_process_add_arg (comm->process, "-f");
@@ -918,7 +924,7 @@ fr_command_tar_uncompress (FrCommand *comm)
fr_process_add_arg (comm->process, tmp_name);
fr_process_end_command (comm->process);
}
- else if (_g_mime_type_matches (comm->mime_type, "application/x-xz-compressed-tar")) {
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-xz-compressed-tar")) {
fr_process_begin_command (comm->process, "xz");
fr_process_set_begin_func (comm->process, begin_func__uncompress, comm);
fr_process_add_arg (comm->process, "-f");
@@ -926,7 +932,7 @@ fr_command_tar_uncompress (FrCommand *comm)
fr_process_add_arg (comm->process, tmp_name);
fr_process_end_command (comm->process);
}
- else if (_g_mime_type_matches (comm->mime_type, "application/x-lzop-compressed-tar")) {
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-lzop-compressed-tar")) {
fr_process_begin_command (comm->process, "lzop");
fr_process_set_begin_func (comm->process, begin_func__uncompress, comm);
fr_process_add_arg (comm->process, "-dfU");
@@ -934,7 +940,7 @@ fr_command_tar_uncompress (FrCommand *comm)
fr_process_add_arg (comm->process, tmp_name);
fr_process_end_command (comm->process);
}
- else if (_g_mime_type_matches (comm->mime_type, "application/x-7z-compressed-tar")) {
+ else if (_g_mime_type_matches (archive->mime_type, "application/x-7z-compressed-tar")) {
FrCommandTar *comm_tar = (FrCommandTar*) comm;
fr_process_begin_command (comm->process, comm_tar->compress_command);
@@ -961,11 +967,11 @@ fr_command_tar_uncompress (FrCommand *comm)
static void
fr_command_tar_handle_error (FrCommand *comm,
- FrProcError *error)
+ FrError *error)
{
- if (error->type != FR_PROC_ERROR_NONE) {
+ if (error->type != FR_ERROR_NONE) {
if (error->status <= 1)
- error->type = FR_PROC_ERROR_NONE;
+ error->type = FR_ERROR_NONE;
}
}
@@ -984,61 +990,61 @@ const char *tar_mime_types[] = { "application/x-compressed-tar",
static const char **
-fr_command_tar_get_mime_types (FrCommand *comm)
+fr_command_tar_get_mime_types (FrArchive *archive)
{
return tar_mime_types;
}
-static FrCommandCap
-fr_command_tar_get_capabilities (FrCommand *comm,
+static FrArchiveCap
+fr_command_tar_get_capabilities (FrArchive *archive,
const char *mime_type,
gboolean check_command)
{
- FrCommandCap capabilities;
+ FrArchiveCap capabilities;
- capabilities = FR_COMMAND_CAN_ARCHIVE_MANY_FILES;
+ capabilities = FR_ARCHIVE_CAN_STORE_MANY_FILES;
/* In solaris gtar is present under /usr/sfw/bin */
if (! _g_program_is_available ("tar", check_command) && ! _g_program_is_available ("/usr/sfw/bin/gtar", check_command))
return capabilities;
if (_g_mime_type_matches (mime_type, "application/x-tar")) {
- capabilities |= FR_COMMAND_CAN_READ_WRITE;
+ capabilities |= FR_ARCHIVE_CAN_READ_WRITE;
}
else if (_g_mime_type_matches (mime_type, "application/x-compressed-tar")) {
if (_g_program_is_available ("gzip", check_command))
- capabilities |= FR_COMMAND_CAN_READ_WRITE;
+ capabilities |= FR_ARCHIVE_CAN_READ_WRITE;
}
else if (_g_mime_type_matches (mime_type, "application/x-bzip-compressed-tar")) {
if (_g_program_is_available ("bzip2", check_command))
- capabilities |= FR_COMMAND_CAN_READ_WRITE;
+ capabilities |= FR_ARCHIVE_CAN_READ_WRITE;
}
else if (_g_mime_type_matches (mime_type, "application/x-tarz")) {
if (_g_program_is_available ("compress", check_command) && _g_program_is_available ("uncompress", check_command))
- capabilities |= FR_COMMAND_CAN_READ_WRITE;
+ capabilities |= FR_ARCHIVE_CAN_READ_WRITE;
else if (_g_program_is_available ("gzip", check_command))
- capabilities |= FR_COMMAND_CAN_READ;
+ capabilities |= FR_ARCHIVE_CAN_READ;
}
else if (_g_mime_type_matches (mime_type, "application/x-lrzip-compressed-tar")) {
if (_g_program_is_available ("lrzip", check_command))
- capabilities |= FR_COMMAND_CAN_READ_WRITE;
+ capabilities |= FR_ARCHIVE_CAN_READ_WRITE;
}
else if (_g_mime_type_matches (mime_type, "application/x-lzip-compressed-tar")) {
if (_g_program_is_available ("lzip", check_command))
- capabilities |= FR_COMMAND_CAN_READ_WRITE;
+ capabilities |= FR_ARCHIVE_CAN_READ_WRITE;
}
else if (_g_mime_type_matches (mime_type, "application/x-lzma-compressed-tar")) {
if (_g_program_is_available ("lzma", check_command))
- capabilities |= FR_COMMAND_CAN_READ_WRITE;
+ capabilities |= FR_ARCHIVE_CAN_READ_WRITE;
}
else if (_g_mime_type_matches (mime_type, "application/x-xz-compressed-tar")) {
if (_g_program_is_available ("xz", check_command))
- capabilities |= FR_COMMAND_CAN_READ_WRITE;
+ capabilities |= FR_ARCHIVE_CAN_READ_WRITE;
}
else if (_g_mime_type_matches (mime_type, "application/x-lzop-compressed-tar")) {
if (_g_program_is_available ("lzop", check_command))
- capabilities |= FR_COMMAND_CAN_READ_WRITE;
+ capabilities |= FR_ARCHIVE_CAN_READ_WRITE;
}
else if (_g_mime_type_matches (mime_type, "application/x-7z-compressed-tar")) {
char *try_command[3] = { "7za", "7zr", "7z" };
@@ -1046,7 +1052,7 @@ fr_command_tar_get_capabilities (FrCommand *comm,
for (i = 0; i < G_N_ELEMENTS (try_command); i++) {
if (_g_program_is_available (try_command[i], check_command)) {
- capabilities |= FR_COMMAND_CAN_WRITE;
+ capabilities |= FR_ARCHIVE_CAN_WRITE;
break;
}
}
@@ -1057,12 +1063,12 @@ fr_command_tar_get_capabilities (FrCommand *comm,
static void
-fr_command_tar_set_mime_type (FrCommand *comm,
+fr_command_tar_set_mime_type (FrArchive *archive,
const char *mime_type)
{
- FrCommandTar *comm_tar = FR_COMMAND_TAR (comm);
+ FrCommandTar *comm_tar = FR_COMMAND_TAR (archive);
- FR_COMMAND_CLASS (fr_command_tar_parent_class)->set_mime_type (comm, mime_type);
+ FR_ARCHIVE_CLASS (fr_command_tar_parent_class)->set_mime_type (archive, mime_type);
if (_g_mime_type_matches (mime_type, "application/x-7z-compressed-tar")) {
char *try_command[3] = { "7za", "7zr", "7z" };
@@ -1079,7 +1085,7 @@ fr_command_tar_set_mime_type (FrCommand *comm,
static const char *
-fr_command_tar_get_packages (FrCommand *comm,
+fr_command_tar_get_packages (FrArchive *archive,
const char *mime_type)
{
if (_g_mime_type_matches (mime_type, "application/x-tar"))
@@ -1142,6 +1148,7 @@ static void
fr_command_tar_class_init (FrCommandTarClass *klass)
{
GObjectClass *gobject_class;
+ FrArchiveClass *archive_class;
FrCommandClass *command_class;
fr_command_tar_parent_class = g_type_class_peek_parent (klass);
@@ -1149,25 +1156,27 @@ fr_command_tar_class_init (FrCommandTarClass *klass)
gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = fr_command_tar_finalize;
+ archive_class = FR_ARCHIVE_CLASS (klass);
+ archive_class->get_mime_types = fr_command_tar_get_mime_types;
+ archive_class->get_capabilities = fr_command_tar_get_capabilities;
+ archive_class->set_mime_type = fr_command_tar_set_mime_type;
+ archive_class->get_packages = fr_command_tar_get_packages;
+
command_class = FR_COMMAND_CLASS (klass);
command_class->list = fr_command_tar_list;
command_class->add = fr_command_tar_add;
command_class->delete = fr_command_tar_delete;
command_class->extract = fr_command_tar_extract;
command_class->handle_error = fr_command_tar_handle_error;
- command_class->get_mime_types = fr_command_tar_get_mime_types;
- command_class->get_capabilities = fr_command_tar_get_capabilities;
- command_class->set_mime_type = fr_command_tar_set_mime_type;
command_class->recompress = fr_command_tar_recompress;
command_class->uncompress = fr_command_tar_uncompress;
- command_class->get_packages = fr_command_tar_get_packages;
}
static void
fr_command_tar_init (FrCommandTar *self)
{
- FrCommand *base = FR_COMMAND (self);
+ FrArchive *base = FR_ARCHIVE (self);
base->propAddCanUpdate = FALSE;
base->propAddCanReplace = FALSE;
diff --git a/src/fr-command-unarchiver.c b/src/fr-command-unarchiver.c
index 0a7e97f..2cad7f7 100644
--- a/src/fr-command-unarchiver.c
+++ b/src/fr-command-unarchiver.c
@@ -112,7 +112,7 @@ list_command_completed (gpointer data)
fdata->name = g_strdup (_g_path_get_file_name (fdata->full_path));
fdata->path = _g_path_remove_level (fdata->full_path);
- fr_command_add_file (FR_COMMAND (unar_comm), fdata);
+ fr_archive_add_file (FR_ARCHIVE (unar_comm), fdata);
}
}
}
@@ -121,7 +121,7 @@ list_command_completed (gpointer data)
}
-static void
+static gboolean
fr_command_unarchiver_list (FrCommand *comm)
{
FrCommandUnarchiver *unar_comm = FR_COMMAND_UNARCHIVER (comm);
@@ -134,12 +134,12 @@ fr_command_unarchiver_list (FrCommand *comm)
fr_process_begin_command (comm->process, "lsar");
fr_process_set_end_func (comm->process, list_command_completed, comm);
fr_process_add_arg (comm->process, "-j");
- if ((comm->password != NULL) && (comm->password[0] != '\0'))
- fr_process_add_arg_concat (comm->process, "-password=", comm->password, NULL);
+ if ((FR_ARCHIVE (comm)->password != NULL) && (FR_ARCHIVE (comm)->password[0] != '\0'))
+ fr_process_add_arg_concat (comm->process, "-password=", FR_ARCHIVE (comm)->password, NULL);
fr_process_add_arg (comm->process, comm->filename);
fr_process_end_command (comm->process);
- fr_process_start (comm->process);
+ return TRUE;
}
@@ -148,6 +148,7 @@ process_line__extract (char *line,
gpointer data)
{
FrCommand *comm = FR_COMMAND (data);
+ FrArchive *archive = FR_ARCHIVE (comm);
FrCommandUnarchiver *unar_comm = FR_COMMAND_UNARCHIVER (comm);
if (line == NULL)
@@ -159,12 +160,12 @@ process_line__extract (char *line,
if (unar_comm->n_line == 1)
return;
- if (comm->n_files > 1) {
- double fraction = (double) ++comm->n_file / (comm->n_files + 1);
- fr_command_progress (comm, CLAMP (fraction, 0.0, 1.0));
+ if (archive->n_files > 1) {
+ double fraction = (double) ++archive->n_file / (archive->n_files + 1);
+ fr_archive_progress (archive, CLAMP (fraction, 0.0, 1.0));
}
else
- fr_command_message (comm, line);
+ fr_archive_message (archive, line);
}
@@ -197,8 +198,8 @@ fr_command_unarchiver_extract (FrCommand *comm,
if (junk_paths)
fr_process_add_arg (comm->process, "-D");
- if ((comm->password != NULL) && (comm->password[0] != '\0'))
- fr_process_add_arg_concat (comm->process, "-password=", comm->password, NULL);
+ if ((FR_ARCHIVE (comm)->password != NULL) && (FR_ARCHIVE (comm)->password[0] != '\0'))
+ fr_process_add_arg_concat (comm->process, "-password=", FR_ARCHIVE (comm)->password, NULL);
if (dest_dir != NULL)
fr_process_add_arg_concat (comm->process, "-output-directory=", dest_dir, NULL);
@@ -214,7 +215,7 @@ fr_command_unarchiver_extract (FrCommand *comm,
static void
fr_command_unarchiver_handle_error (FrCommand *comm,
- FrProcError *error)
+ FrError *error)
{
GList *scan;
@@ -225,14 +226,14 @@ fr_command_unarchiver_handle_error (FrCommand *comm,
}
#endif
- if (error->type == FR_PROC_ERROR_NONE)
+ if (error->type == FR_ERROR_NONE)
return;
for (scan = g_list_last (comm->process->err.raw); scan; scan = scan->prev) {
char *line = scan->data;
if (strstr (line, "password") != NULL) {
- error->type = FR_PROC_ERROR_ASK_PASSWORD;
+ error->type = FR_ERROR_ASK_PASSWORD;
break;
}
}
@@ -245,29 +246,29 @@ const char *unarchiver_mime_type[] = { "application/x-cbr",
static const char **
-fr_command_unarchiver_get_mime_types (FrCommand *comm)
+fr_command_unarchiver_get_mime_types (FrArchive *archive)
{
return unarchiver_mime_type;
}
-static FrCommandCap
-fr_command_unarchiver_get_capabilities (FrCommand *comm,
+static FrArchiveCap
+fr_command_unarchiver_get_capabilities (FrArchive *archive,
const char *mime_type,
gboolean check_command)
{
- FrCommandCap capabilities;
+ FrArchiveCap capabilities;
- capabilities = FR_COMMAND_CAN_DO_NOTHING;
+ capabilities = FR_ARCHIVE_CAN_DO_NOTHING;
if (_g_program_is_available ("lsar", check_command) && _g_program_is_available ("unar", check_command))
- capabilities |= FR_COMMAND_CAN_READ;
+ capabilities |= FR_ARCHIVE_CAN_READ;
return capabilities;
}
static const char *
-fr_command_unarchiver_get_packages (FrCommand *comm,
+fr_command_unarchiver_get_packages (FrArchive *archive,
const char *mime_type)
{
return PACKAGES ("unarchiver");
@@ -294,6 +295,7 @@ static void
fr_command_unarchiver_class_init (FrCommandUnarchiverClass *klass)
{
GObjectClass *gobject_class;
+ FrArchiveClass *archive_class;
FrCommandClass *command_class;
fr_command_unarchiver_parent_class = g_type_class_peek_parent (klass);
@@ -301,20 +303,22 @@ fr_command_unarchiver_class_init (FrCommandUnarchiverClass *klass)
gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = fr_command_unarchiver_finalize;
+ archive_class = FR_ARCHIVE_CLASS (klass);
+ archive_class->get_mime_types = fr_command_unarchiver_get_mime_types;
+ archive_class->get_capabilities = fr_command_unarchiver_get_capabilities;
+ archive_class->get_packages = fr_command_unarchiver_get_packages;
+
command_class = FR_COMMAND_CLASS (klass);
command_class->list = fr_command_unarchiver_list;
command_class->extract = fr_command_unarchiver_extract;
command_class->handle_error = fr_command_unarchiver_handle_error;
- command_class->get_mime_types = fr_command_unarchiver_get_mime_types;
- command_class->get_capabilities = fr_command_unarchiver_get_capabilities;
- command_class->get_packages = fr_command_unarchiver_get_packages;
}
static void
fr_command_unarchiver_init (FrCommandUnarchiver *self)
{
- FrCommand *base = FR_COMMAND (self);;
+ FrArchive *base = FR_ARCHIVE (self);
base->propExtractCanAvoidOverwrite = TRUE;
base->propExtractCanSkipOlder = FALSE;
diff --git a/src/fr-command-unstuff.c b/src/fr-command-unstuff.c
index f696fc6..84b3999 100644
--- a/src/fr-command-unstuff.c
+++ b/src/fr-command-unstuff.c
@@ -166,7 +166,7 @@ process_line (char *line,
fdata->modified = time (NULL);
unstuff_comm->fdata = fdata;
- fr_command_add_file (comm, fdata);
+ fr_archive_add_file (FR_ARCHIVE (comm), fdata);
unlink (real_filename);
g_free (real_filename);
@@ -182,7 +182,7 @@ list__begin (gpointer data)
}
-static void
+static gboolean
fr_command_unstuff_list (FrCommand *comm)
{
char *arg, *path;
@@ -209,7 +209,8 @@ fr_command_unstuff_list (FrCommand *comm)
fr_process_add_arg (comm->process, filename);
g_free (filename);
fr_process_end_command (comm->process);
- fr_process_start (comm->process);
+
+ return TRUE;
}
@@ -260,12 +261,12 @@ fr_command_unstuff_extract (FrCommand *comm,
static void
fr_command_unstuff_handle_error (FrCommand *comm,
- FrProcError *error)
+ FrError *error)
{
- if ((error->type != FR_PROC_ERROR_NONE)
+ if ((error->type != FR_ERROR_NONE)
&& (error->status <= 1))
{
- error->type = FR_PROC_ERROR_NONE;
+ error->type = FR_ERROR_NONE;
}
}
@@ -274,29 +275,29 @@ const char *unstuff_mime_type[] = { "application/x-stuffit", NULL };
static const char **
-fr_command_unstuff_get_mime_types (FrCommand *comm)
+fr_command_unstuff_get_mime_types (FrArchive *archive)
{
return unstuff_mime_type;
}
-static FrCommandCap
-fr_command_unstuff_get_capabilities (FrCommand *comm,
+static FrArchiveCap
+fr_command_unstuff_get_capabilities (FrArchive *archive,
const char *mime_type,
gboolean check_command)
{
- FrCommandCap capabilities;
+ FrArchiveCap capabilities;
- capabilities = FR_COMMAND_CAN_ARCHIVE_MANY_FILES;
+ capabilities = FR_ARCHIVE_CAN_STORE_MANY_FILES;
if (_g_program_is_available ("unstuff", check_command))
- capabilities |= FR_COMMAND_CAN_READ;
+ capabilities |= FR_ARCHIVE_CAN_READ;
return capabilities;
}
static const char *
-fr_command_unstuff_get_packages (FrCommand *comm,
+fr_command_unstuff_get_packages (FrArchive *archive,
const char *mime_type)
{
return PACKAGES ("unstaff");
@@ -327,6 +328,7 @@ static void
fr_command_unstuff_class_init (FrCommandUnstuffClass *klass)
{
GObjectClass *gobject_class;
+ FrArchiveClass *archive_class;
FrCommandClass *command_class;
fr_command_unstuff_parent_class = g_type_class_peek_parent (klass);
@@ -334,20 +336,22 @@ fr_command_unstuff_class_init (FrCommandUnstuffClass *klass)
gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = fr_command_unstuff_finalize;
+ archive_class = FR_ARCHIVE_CLASS (klass);
+ archive_class->get_mime_types = fr_command_unstuff_get_mime_types;
+ archive_class->get_capabilities = fr_command_unstuff_get_capabilities;
+ archive_class->get_packages = fr_command_unstuff_get_packages;
+
command_class = FR_COMMAND_CLASS (klass);
command_class->list = fr_command_unstuff_list;
command_class->extract = fr_command_unstuff_extract;
command_class->handle_error = fr_command_unstuff_handle_error;
- command_class->get_mime_types = fr_command_unstuff_get_mime_types;
- command_class->get_capabilities = fr_command_unstuff_get_capabilities;
- command_class->get_packages = fr_command_unstuff_get_packages;
}
static void
fr_command_unstuff_init (FrCommandUnstuff *self)
{
- FrCommand *base = FR_COMMAND (self);
+ FrArchive *base = FR_ARCHIVE (self);
base->propAddCanUpdate = FALSE;
base->propAddCanReplace = FALSE;
diff --git a/src/fr-command-zip.c b/src/fr-command-zip.c
index 189aff4..efc9578 100644
--- a/src/fr-command-zip.c
+++ b/src/fr-command-zip.c
@@ -150,7 +150,7 @@ list__process_line (char *line,
if (*fdata->name == 0)
file_data_free (fdata);
else
- fr_command_add_file (comm, fdata);
+ fr_archive_add_file (FR_ARCHIVE (comm), fdata);
}
@@ -174,7 +174,7 @@ list__begin (gpointer data)
}
-static void
+static gboolean
fr_command_zip_list (FrCommand *comm)
{
fr_process_set_out_line_func (comm->process, list__process_line, comm);
@@ -185,7 +185,8 @@ fr_command_zip_list (FrCommand *comm)
fr_process_add_arg (comm->process, "--");
fr_process_add_arg (comm->process, comm->filename);
fr_process_end_command (comm->process);
- fr_process_start (comm->process);
+
+ return TRUE;
}
@@ -193,17 +194,18 @@ static void
process_line__common (char *line,
gpointer data)
{
- FrCommand *comm = FR_COMMAND (data);
+ FrCommand *comm = FR_COMMAND (data);
+ FrArchive *archive = FR_ARCHIVE (comm);
if (line == NULL)
return;
- if (comm->n_files > 1) {
- double fraction = (double) ++comm->n_file / (comm->n_files + 1);
- fr_command_progress (comm, fraction);
+ if (archive->n_files > 1) {
+ double fraction = (double) ++archive->n_file / (archive->n_files + 1);
+ fr_archive_progress (archive, fraction);
}
else
- fr_command_message (comm, line);
+ fr_archive_message (archive, line);
}
@@ -232,9 +234,9 @@ fr_command_zip_add (FrCommand *comm,
if (update)
fr_process_add_arg (comm->process, "-u");
- add_password_arg (comm, comm->password);
+ add_password_arg (comm, FR_ARCHIVE (comm)->password);
- switch (comm->compression) {
+ switch (FR_ARCHIVE (comm)->compression) {
case FR_COMPRESSION_VERY_FAST:
fr_process_add_arg (comm->process, "-1"); break;
case FR_COMPRESSION_FAST:
@@ -313,7 +315,7 @@ fr_command_zip_extract (FrCommand *comm,
fr_process_add_arg (comm->process, "-u");
if (junk_paths)
fr_process_add_arg (comm->process, "-j");
- add_password_arg (comm, comm->password);
+ add_password_arg (comm, FR_ARCHIVE (comm)->password);
fr_process_add_arg (comm->process, "--");
fr_process_add_arg (comm->process, comm->filename);
@@ -335,7 +337,7 @@ fr_command_zip_test (FrCommand *comm)
{
fr_process_begin_command (comm->process, "unzip");
fr_process_add_arg (comm->process, "-t");
- add_password_arg (comm, comm->password);
+ add_password_arg (comm, FR_ARCHIVE (comm)->password);
fr_process_add_arg (comm->process, "--");
fr_process_add_arg (comm->process, comm->filename);
fr_process_end_command (comm->process);
@@ -343,19 +345,19 @@ fr_command_zip_test (FrCommand *comm)
static void
-fr_command_zip_handle_error (FrCommand *comm,
- FrProcError *error)
+fr_command_zip_handle_error (FrCommand *comm,
+ FrError *error)
{
- if (error->type != FR_PROC_ERROR_NONE) {
+ if (error->type != FR_ERROR_NONE) {
if (error->status <= 1)
- error->type = FR_PROC_ERROR_NONE;
+ error->type = FR_ERROR_NONE;
else if ((error->status == 82) || (error->status == 5))
- error->type = FR_PROC_ERROR_ASK_PASSWORD;
+ error->type = FR_ERROR_ASK_PASSWORD;
else {
GList *output;
GList *scan;
- if (comm->action == FR_ACTION_TESTING_ARCHIVE)
+ if (FR_ARCHIVE (comm)->action == FR_ACTION_TESTING_ARCHIVE)
output = comm->process->out.raw;
else
output = comm->process->err.raw;
@@ -364,7 +366,7 @@ fr_command_zip_handle_error (FrCommand *comm,
char *line = scan->data;
if (strstr (line, "incorrect password") != NULL) {
- error->type = FR_PROC_ERROR_ASK_PASSWORD;
+ error->type = FR_ERROR_ASK_PASSWORD;
break;
}
}
@@ -380,35 +382,35 @@ const char *zip_mime_type[] = { "application/x-cbz",
static const char **
-fr_command_zip_get_mime_types (FrCommand *comm)
+fr_command_zip_get_mime_types (FrArchive *archive)
{
return zip_mime_type;
}
-static FrCommandCap
-fr_command_zip_get_capabilities (FrCommand *comm,
+static FrArchiveCap
+fr_command_zip_get_capabilities (FrArchive *archive,
const char *mime_type,
gboolean check_command)
{
- FrCommandCap capabilities;
+ FrArchiveCap capabilities;
- capabilities = FR_COMMAND_CAN_ARCHIVE_MANY_FILES | FR_COMMAND_CAN_ENCRYPT;
+ capabilities = FR_ARCHIVE_CAN_STORE_MANY_FILES | FR_ARCHIVE_CAN_ENCRYPT;
if (_g_program_is_available ("zip", check_command)) {
if (strcmp (mime_type, "application/x-ms-dos-executable") == 0)
- capabilities |= FR_COMMAND_CAN_READ;
+ capabilities |= FR_ARCHIVE_CAN_READ;
else
- capabilities |= FR_COMMAND_CAN_WRITE;
+ capabilities |= FR_ARCHIVE_CAN_WRITE;
}
if (_g_program_is_available ("unzip", check_command))
- capabilities |= FR_COMMAND_CAN_READ;
+ capabilities |= FR_ARCHIVE_CAN_READ;
return capabilities;
}
static const char *
-fr_command_zip_get_packages (FrCommand *comm,
+fr_command_zip_get_packages (FrArchive *archive,
const char *mime_type)
{
return PACKAGES ("zip,unzip");
@@ -430,6 +432,7 @@ static void
fr_command_zip_class_init (FrCommandZipClass *klass)
{
GObjectClass *gobject_class;
+ FrArchiveClass *archive_class;
FrCommandClass *command_class;
fr_command_zip_parent_class = g_type_class_peek_parent (klass);
@@ -437,6 +440,11 @@ fr_command_zip_class_init (FrCommandZipClass *klass)
gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = fr_command_zip_finalize;
+ archive_class = FR_ARCHIVE_CLASS (klass);
+ archive_class->get_mime_types = fr_command_zip_get_mime_types;
+ archive_class->get_capabilities = fr_command_zip_get_capabilities;
+ archive_class->get_packages = fr_command_zip_get_packages;
+
command_class = FR_COMMAND_CLASS (klass);
command_class->list = fr_command_zip_list;
command_class->add = fr_command_zip_add;
@@ -444,16 +452,13 @@ fr_command_zip_class_init (FrCommandZipClass *klass)
command_class->extract = fr_command_zip_extract;
command_class->test = fr_command_zip_test;
command_class->handle_error = fr_command_zip_handle_error;
- command_class->get_mime_types = fr_command_zip_get_mime_types;
- command_class->get_capabilities = fr_command_zip_get_capabilities;
- command_class->get_packages = fr_command_zip_get_packages;
}
static void
fr_command_zip_init (FrCommandZip *self)
{
- FrCommand *base = FR_COMMAND (self);
+ FrArchive *base = FR_ARCHIVE (self);
base->propAddCanUpdate = TRUE;
base->propAddCanReplace = TRUE;
diff --git a/src/fr-command-zoo.c b/src/fr-command-zoo.c
index 955a61a..13245e0 100644
--- a/src/fr-command-zoo.c
+++ b/src/fr-command-zoo.c
@@ -207,11 +207,11 @@ process_zoo_line (char *line,
if (*fdata->name == 0)
file_data_free (fdata);
else
- fr_command_add_file (zoo_comm, fdata);
+ fr_archive_add_file (FR_ARCHIVE (zoo_comm), fdata);
}
-static void
+static gboolean
fr_command_zoo_list (FrCommand *zoo_comm)
{
fr_process_set_out_line_func (zoo_comm->process, process_zoo_line, zoo_comm);
@@ -220,7 +220,8 @@ fr_command_zoo_list (FrCommand *zoo_comm)
fr_process_add_arg (zoo_comm->process, "lq");
fr_process_add_arg (zoo_comm->process, zoo_comm->filename);
fr_process_end_command (zoo_comm->process);
- fr_process_start (zoo_comm->process);
+
+ return TRUE;
}
@@ -316,29 +317,29 @@ const char *zoo_mime_type[] = { "application/x-zoo", NULL };
static const char **
-fr_command_zoo_get_mime_types (FrCommand *comm)
+fr_command_zoo_get_mime_types (FrArchive *archive)
{
return zoo_mime_type;
}
-static FrCommandCap
-fr_command_zoo_get_capabilities (FrCommand *comm,
+static FrArchiveCap
+fr_command_zoo_get_capabilities (FrArchive *archive,
const char *mime_type,
gboolean check_command)
{
- FrCommandCap capabilities;
+ FrArchiveCap capabilities;
- capabilities = FR_COMMAND_CAN_ARCHIVE_MANY_FILES;
+ capabilities = FR_ARCHIVE_CAN_STORE_MANY_FILES;
if (_g_program_is_available ("zoo", check_command))
- capabilities |= FR_COMMAND_CAN_READ_WRITE;
+ capabilities |= FR_ARCHIVE_CAN_READ_WRITE;
return capabilities;
}
static const char *
-fr_command_zoo_get_packages (FrCommand *comm,
+fr_command_zoo_get_packages (FrArchive *archive,
const char *mime_type)
{
return PACKAGES ("zoo");
@@ -360,6 +361,7 @@ static void
fr_command_zoo_class_init (FrCommandZooClass *klass)
{
GObjectClass *gobject_class;
+ FrArchiveClass *archive_class;
FrCommandClass *command_class;
fr_command_zoo_parent_class = g_type_class_peek_parent (klass);
@@ -367,22 +369,24 @@ fr_command_zoo_class_init (FrCommandZooClass *klass)
gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = fr_command_zoo_finalize;
+ archive_class = FR_ARCHIVE_CLASS (klass);
+ archive_class->get_mime_types = fr_command_zoo_get_mime_types;
+ archive_class->get_capabilities = fr_command_zoo_get_capabilities;
+ archive_class->get_packages = fr_command_zoo_get_packages;
+
command_class = FR_COMMAND_CLASS (klass);
command_class->list = fr_command_zoo_list;
command_class->add = fr_command_zoo_add;
command_class->delete = fr_command_zoo_delete;
command_class->extract = fr_command_zoo_extract;
command_class->test = fr_command_zoo_test;
- command_class->get_mime_types = fr_command_zoo_get_mime_types;
- command_class->get_capabilities = fr_command_zoo_get_capabilities;
- command_class->get_packages = fr_command_zoo_get_packages;
}
static void
fr_command_zoo_init (FrCommandZoo *self)
{
- FrCommand *base = FR_COMMAND (self);
+ FrArchive *base = FR_ARCHIVE (self);
base->propAddCanUpdate = TRUE;
base->propAddCanReplace = FALSE;
diff --git a/src/fr-command.c b/src/fr-command.c
index 7baf4c3..621498a 100644
--- a/src/fr-command.c
+++ b/src/fr-command.c
@@ -3,7 +3,7 @@
/*
* File-Roller
*
- * Copyright (C) 2001 The Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2003, 2007, 2008 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,234 +19,701 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <string.h>
+#include <config.h>
#include <unistd.h>
-#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/param.h>
#include <glib.h>
+#include <glib/gi18n.h>
+#include <gio/gio.h>
#include "file-data.h"
#include "file-utils.h"
#include "fr-command.h"
-#include "fr-enum-types.h"
-#include "fr-marshal.h"
-#include "fr-proc-error.h"
+#include "fr-error.h"
#include "fr-process.h"
+#include "gio-utils.h"
#include "glib-utils.h"
-#define INITIAL_SIZE 256
+#define MAX_CHUNK_LEN (NCARGS * 2 / 3) /* Max command line length */
+#define LIST_LENGTH_TO_USE_FILE 10 /* FIXME: find a good value */
+#ifndef NCARGS
+#define NCARGS _POSIX_ARG_MAX
+#endif
+
+
+/* -- DroppedItemsData -- */
+
+
+typedef struct {
+ FrCommand *command;
+ GList *item_list;
+ char *base_dir;
+ char *dest_dir;
+ gboolean update;
+ char *password;
+ gboolean encrypt_header;
+ FrCompression compression;
+ guint volume_size;
+ GCancellable *cancellable;
+ GAsyncReadyCallback callback;
+ gpointer user_data;
+} DroppedItemsData;
+
+
+static DroppedItemsData *
+dropped_items_data_new (FrCommand *command,
+ GList *item_list,
+ const char *base_dir,
+ const char *dest_dir,
+ gboolean update,
+ const char *password,
+ gboolean encrypt_header,
+ FrCompression compression,
+ guint volume_size,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ DroppedItemsData *data;
+
+ data = g_new0 (DroppedItemsData, 1);
+ data->command = command;
+ data->item_list = _g_string_list_dup (item_list);
+ if (base_dir != NULL)
+ data->base_dir = g_strdup (base_dir);
+ if (dest_dir != NULL)
+ data->dest_dir = g_strdup (dest_dir);
+ data->update = update;
+ if (password != NULL)
+ data->password = g_strdup (password);
+ data->encrypt_header = encrypt_header;
+ data->compression = compression;
+ data->volume_size = volume_size;
+ data->cancellable = _g_object_ref (cancellable);
+ data->callback = callback;
+ data->user_data = user_data;
+
+ return data;
+}
+
+
+static void
+dropped_items_data_free (DroppedItemsData *data)
+{
+ if (data == NULL)
+ return;
+ _g_string_list_free (data->item_list);
+ g_free (data->base_dir);
+ g_free (data->dest_dir);
+ g_free (data->password);
+ _g_object_unref (data->cancellable);
+ g_free (data);
+}
+
+
+/* -- XferData -- */
-G_DEFINE_TYPE (FrCommand, fr_command, G_TYPE_OBJECT)
+typedef struct {
+ FrArchive *archive;
+ char *uri;
+ FrAction action;
+ GList *file_list;
+ char *base_uri;
+ char *dest_dir;
+ gboolean update;
+ gboolean recursive;
+ char *tmp_dir;
+ guint source_id;
+ char *password;
+ gboolean encrypt_header;
+ FrCompression compression;
+ guint volume_size;
+ GCancellable *cancellable;
+ GSimpleAsyncResult *result;
+} XferData;
+
+
+static void
+xfer_data_free (XferData *data)
+{
+ if (data == NULL)
+ return;
+
+ g_free (data->uri);
+ g_free (data->password);
+ _g_string_list_free (data->file_list);
+ g_free (data->base_uri);
+ g_free (data->dest_dir);
+ g_free (data->tmp_dir);
+ _g_object_unref (data->cancellable);
+ _g_object_unref (data->result);
+ g_free (data);
+}
+
+
+/* -- FrCommand -- */
+
+
+G_DEFINE_TYPE (FrCommand, fr_command, FR_TYPE_ARCHIVE)
-/* Signals */
-enum {
- START,
- DONE,
- PROGRESS,
- MESSAGE,
- WORKING_ARCHIVE,
- LAST_SIGNAL
-};
/* Properties */
enum {
PROP_0,
- PROP_FILE,
- PROP_MIME_TYPE,
PROP_PROCESS,
- PROP_PASSWORD,
- PROP_ENCRYPT_HEADER,
- PROP_COMPRESSION,
- PROP_VOLUME_SIZE
+ PROP_FILENAME
+};
+
+
+struct _FrCommandPrivate {
+ GFile *local_copy;
+ gboolean is_remote;
+ char *temp_dir;
+ gboolean continue_adding_dropped_items;
+ DroppedItemsData *dropped_items_data;
+ char *temp_extraction_dir;
+ gboolean remote_extraction;
};
-static guint fr_command_signals[LAST_SIGNAL] = { 0 };
+static void
+_fr_command_remove_temp_work_dir (FrCommand *self)
+{
+ if (self->priv->temp_dir == NULL)
+ return;
+ _g_path_remove_directory (self->priv->temp_dir);
+ g_free (self->priv->temp_dir);
+ self->priv->temp_dir = NULL;
+}
+
+
+static const char *
+_fr_command_get_temp_work_dir (FrCommand *self)
+{
+ _fr_command_remove_temp_work_dir (self);
+ self->priv->temp_dir = _g_path_get_temp_work_dir (NULL);
+ return self->priv->temp_dir;
+}
+
+
+/* -- copy_archive_to_remote_location -- */
+
+static void
+copy_archive_to_remote_location_done (GError *error,
+ gpointer user_data)
+{
+ XferData *xfer_data = user_data;
-char *action_names[] = { "NONE",
- "CREATING_NEW_ARCHIVE",
- "LOADING_ARCHIVE",
- "LISTING_CONTENT",
- "DELETING_FILES",
- "TESTING_ARCHIVE",
- "GETTING_FILE_LIST",
- "COPYING_FILES_FROM_REMOTE",
- "ADDING_FILES",
- "EXTRACTING_FILES",
- "COPYING_FILES_TO_REMOTE",
- "CREATING_ARCHIVE",
- "SAVING_REMOTE_ARCHIVE" };
+ if (error != NULL)
+ g_simple_async_result_set_from_error (xfer_data->result, error);
+ g_simple_async_result_complete_in_idle (xfer_data->result);
+
+ xfer_data_free (xfer_data);
+}
static void
-base_fr_command_list (FrCommand *comm)
+copy_archive_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_by_name (xfer_data->archive,
+ "progress",
+ (double) current_num_bytes / total_num_bytes);
}
static void
-base_fr_command_add (FrCommand *comm,
- const char *from_file,
- GList *file_list,
- const char *base_dir,
- gboolean update,
- gboolean recursive)
+copy_archive_to_remote_location (FrArchive *archive,
+ GSimpleAsyncResult *result,
+ GCancellable *cancellable)
{
+ XferData *xfer_data;
+
+ xfer_data = g_new0 (XferData, 1);
+ xfer_data->archive = _g_object_ref (archive);
+ xfer_data->result = _g_object_ref (result);
+ xfer_data->cancellable = _g_object_ref (cancellable);
+
+ g_copy_file_async (FR_COMMAND (xfer_data->archive)->priv->local_copy,
+ fr_archive_get_file (xfer_data->archive),
+ G_FILE_COPY_OVERWRITE,
+ G_PRIORITY_DEFAULT,
+ xfer_data->cancellable,
+ copy_archive_to_remote_location_progress,
+ xfer_data,
+ copy_archive_to_remote_location_done,
+ xfer_data);
}
+/* -- copy_extracted_files_to_destination -- */
+
+
static void
-base_fr_command_delete (FrCommand *comm,
- const char *from_file,
- GList *file_list)
+move_here (FrArchive *archive,
+ GCancellable *cancellable)
{
+ const char *extraction_destination;
+ char *content_uri;
+ char *parent;
+ char *parent_parent;
+ char *new_content_uri;
+ GFile *source, *destination, *parent_file;
+ GError *error = NULL;
+
+ extraction_destination = fr_archive_get_last_extraction_destination (archive);
+ content_uri = _g_uri_get_dir_content_if_unique (extraction_destination);
+ if (content_uri == NULL)
+ return;
+
+ parent = _g_path_remove_level (content_uri);
+
+ if (_g_uri_cmp (parent, extraction_destination) == 0) {
+ char *new_uri;
+
+ new_uri = _g_uri_create_alternative_for_uri (extraction_destination);
+
+ source = g_file_new_for_uri (extraction_destination);
+ destination = g_file_new_for_uri (new_uri);
+ if (! g_file_move (source, destination, 0, NULL, NULL, NULL, &error)) {
+ g_warning ("could not rename %s to %s: %s", extraction_destination, new_uri, error->message);
+ g_clear_error (&error);
+ }
+ g_object_unref (source);
+ g_object_unref (destination);
+
+ fr_archive_set_last_extraction_destination (archive, new_uri);
+
+ g_free (parent);
+
+ content_uri = _g_uri_get_dir_content_if_unique (new_uri);
+ if (content_uri == NULL)
+ return;
+
+ parent = _g_path_remove_level (content_uri);
+ }
+
+ parent_parent = _g_path_remove_level (parent);
+ new_content_uri = _g_uri_create_alternative (parent_parent, _g_path_get_file_name (content_uri));
+
+ source = g_file_new_for_uri (content_uri);
+ destination = g_file_new_for_uri (new_content_uri);
+ if (! g_file_move (source, destination, 0, NULL, NULL, NULL, &error)) {
+ g_warning ("could not rename %s to %s: %s", content_uri, new_content_uri, error->message);
+ g_clear_error (&error);
+ }
+
+ parent_file = g_file_new_for_uri (parent);
+ if (! g_file_delete (parent_file, cancellable, &error)) {
+ g_warning ("could not remove directory %s: %s", parent, error->message);
+ g_clear_error (&error);
+ }
+ g_object_unref (parent_file);
+
+ fr_archive_set_last_extraction_destination (archive, new_content_uri);
+
+ g_free (parent_parent);
+ g_free (parent);
+ g_free (content_uri);
}
static void
-base_fr_command_extract (FrCommand *comm,
- const char *from_file,
- GList *file_list,
- const char *dest_dir,
- gboolean overwrite,
- gboolean skip_older,
- gboolean junk_paths)
+copy_extracted_files_done (GError *error,
+ gpointer user_data)
{
+ XferData *xfer_data = user_data;
+ FrCommand *self = FR_COMMAND (xfer_data->archive);
+
+ if (error != NULL)
+ g_simple_async_result_set_from_error (xfer_data->result, error);
+
+ _g_path_remove_directory (self->priv->temp_extraction_dir);
+ g_free (self->priv->temp_extraction_dir);
+ self->priv->temp_extraction_dir = NULL;
+
+ if ((error == NULL) && (xfer_data->archive->extract_here))
+ move_here (xfer_data->archive, xfer_data->cancellable);
+
+ g_simple_async_result_complete_in_idle (xfer_data->result);
+
+ xfer_data_free (xfer_data);
}
static void
-base_fr_command_test (FrCommand *comm)
+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_by_name (archive,
+ "progress",
+ (double) current_file / (total_files + 1));
}
static void
-base_fr_command_uncompress (FrCommand *comm)
+copy_extracted_files_to_destination (FrArchive *archive,
+ GSimpleAsyncResult *result,
+ GCancellable *cancellable)
{
+ FrCommand *self = FR_COMMAND (archive);
+ XferData *xfer_data;
+
+ xfer_data = g_new0 (XferData, 1);
+ xfer_data->archive = _g_object_ref (archive);
+ xfer_data->result = _g_object_ref (result);
+ xfer_data->cancellable = _g_object_ref (cancellable);
+
+ g_directory_copy_async (self->priv->temp_extraction_dir,
+ fr_archive_get_last_extraction_destination (archive),
+ G_FILE_COPY_OVERWRITE,
+ G_PRIORITY_DEFAULT,
+ cancellable,
+ copy_extracted_files_progress,
+ archive,
+ copy_extracted_files_done,
+ xfer_data);
}
+/* -- virtual functions -- */
+
+
static void
-base_fr_command_recompress (FrCommand *comm)
+fr_command_add (FrCommand *self,
+ const char *from_file,
+ GList *file_list,
+ const char *base_dir,
+ gboolean update,
+ gboolean recursive)
{
+ FrArchive *archive = FR_ARCHIVE (self);
+
+ archive->action = FR_ACTION_ADDING_FILES;
+ fr_process_set_out_line_func (self->process, NULL, NULL);
+ fr_process_set_err_line_func (self->process, NULL, NULL);
+
+ FR_COMMAND_GET_CLASS (G_OBJECT (self))->add (self,
+ from_file,
+ file_list,
+ base_dir,
+ update,
+ recursive);
}
static void
-base_fr_command_handle_error (FrCommand *comm,
- FrProcError *error)
+fr_command_delete (FrCommand *self,
+ const char *from_file,
+ GList *file_list)
{
+ FrArchive *archive = FR_ARCHIVE (self);
+
+ archive->action = FR_ACTION_DELETING_FILES;
+ fr_process_set_out_line_func (self->process, NULL, NULL);
+ fr_process_set_err_line_func (self->process, NULL, NULL);
+
+ FR_COMMAND_GET_CLASS (G_OBJECT (self))->delete (self, from_file, file_list);
}
-const char **void_mime_types = { NULL };
+static void
+fr_command_extract (FrCommand *self,
+ const char *from_file,
+ GList *file_list,
+ const char *dest_dir,
+ gboolean overwrite,
+ gboolean skip_older,
+ gboolean junk_paths)
+{
+ FrArchive *archive = FR_ARCHIVE (self);
+
+ archive->action = FR_ACTION_EXTRACTING_FILES;
+ fr_process_set_out_line_func (self->process, NULL, NULL);
+ fr_process_set_err_line_func (self->process, NULL, NULL);
+
+ FR_COMMAND_GET_CLASS (G_OBJECT (self))->extract (self,
+ from_file,
+ file_list,
+ dest_dir,
+ overwrite,
+ skip_older,
+ junk_paths);
+}
-static const char **
-base_fr_command_get_mime_types (FrCommand *comm)
+static void
+fr_command_test (FrCommand *self)
{
- return void_mime_types;
+ FrArchive *archive = FR_ARCHIVE (self);
+
+ archive->action = FR_ACTION_TESTING_ARCHIVE;
+ fr_process_set_out_line_func (self->process, NULL, NULL);
+ fr_process_set_err_line_func (self->process, NULL, NULL);
+
+ FR_COMMAND_GET_CLASS (G_OBJECT (self))->test (self);
}
-static FrCommandCap
-base_fr_command_get_capabilities (FrCommand *comm,
- const char *mime_type,
- gboolean check_command)
+static void
+fr_command_uncompress (FrCommand *self)
{
- return FR_COMMAND_CAN_DO_NOTHING;
+ FR_COMMAND_GET_CLASS (G_OBJECT (self))->uncompress (self);
}
static void
-base_fr_command_set_mime_type (FrCommand *comm,
- const char *mime_type)
+fr_command_recompress (FrCommand *self)
{
- comm->mime_type = _g_str_get_static (mime_type);
- fr_command_update_capabilities (comm);
+ FR_COMMAND_GET_CLASS (G_OBJECT (self))->recompress (self);
}
-static const char *
-base_fr_command_get_packages (FrCommand *comm,
- const char *mime_type)
+static gboolean
+fr_command_handle_process_error (FrCommand *self,
+ GAsyncResult *result,
+ FrError **error)
{
- return NULL;
+ self->process->restart = FALSE;
+
+ if (! fr_process_execute_finish (self->process, result, error)) {
+ if (g_error_matches ((*error)->gerror, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ (*error)->type = FR_ERROR_STOPPED;
+
+ if ((*error)->type != FR_ERROR_STOPPED)
+ FR_COMMAND_GET_CLASS (G_OBJECT (self))->handle_error (self, (*error));
+
+ if (self->process->restart) {
+ fr_process_restart (self->process);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
}
+/* -- command signals -- */
+
+
+#if 0
+
+
static void
-fr_command_start (FrProcess *process,
- gpointer data)
+process_start_cb (FrProcess *process,
+ gpointer user_data)
{
- FrCommand *comm = FR_COMMAND (data);
+ FrCommand *self = user_data;
+ FrArchive *archive = FR_ARCHIVE (self);
- g_signal_emit (G_OBJECT (comm),
- fr_command_signals[START],
- 0,
- comm->action);
+ fr_archive_action_started (archive, archive->action);
}
static void
-fr_command_done (FrProcess *process,
- FrProcError *error,
- gpointer data)
+process_done_cb (FrProcess *process,
+ FrError *error,
+ gpointer user_data)
{
- FrCommand *comm = FR_COMMAND (data);
+ FrCommand *self = user_data;
+ FrArchive *archive = FR_ARCHIVE (self);
+
+ process->restart = FALSE;
+ if (error->type != FR_ERROR_STOPPED)
+ fr_command_handle_error (self, error);
+
+ if (process->restart) {
+ fr_process_start (process);
+ return;
+ }
+
+ switch (archive->action) {
+ case FR_ACTION_DELETING_FILES:
+ if (error->type == FR_ERROR_NONE) {
+ if (! g_file_has_uri_scheme (fr_archive_get_file (archive), "file")) {
+ copy_archive_to_remote_location (self, action);
+ return;
+ }
+ }
+ break;
- comm->process->restart = FALSE;
- if (error->type != FR_PROC_ERROR_STOPPED)
- fr_command_handle_error (comm, error);
+ case FR_ACTION_ADDING_FILES:
+ if (error->type == FR_ERROR_NONE) {
+ fr_archive_remove_temp_work_dir (archive);
+ if (self->priv->continue_adding_dropped_items) {
+ add_dropped_items (self->priv->dropped_items_data);
+ return;
+ }
+ if (self->priv->dropped_items_data != NULL) {
+ dropped_items_data_free (self->priv->dropped_items_data);
+ self->priv->dropped_items_data = NULL;
+ }
+ /* the name of the volumes are different from the
+ * original name */
+ if (archive->multi_volume)
+ fr_archive_change_name (archive, self->filename);
+ if (! g_file_has_uri_scheme (fr_archive_get_file (archive), "file")) {
+ copy_archive_to_remote_location (self, action);
+ return;
+ }
+ }
+ break;
- if (comm->process->restart) {
- fr_process_start (comm->process);
- return;
- }
+ case FR_ACTION_EXTRACTING_FILES:
+ if (error->type == FR_ERROR_NONE) {
+ if (self->priv->remote_extraction) {
+ copy_extracted_files_to_destination (archive);
+ return;
+ }
+ else if (archive->extract_here)
+ move_here (self);
+ }
+ else {
+ /* if an error occurred during extraction remove the
+ * temp extraction dir, if used. */
+ g_print ("action_performed: ERROR!\n");
+
+ if ((self->priv->remote_extraction) && (self->priv->temp_extraction_dir != NULL)) {
+ _g_path_remove_directory (self->priv->temp_extraction_dir);
+ g_free (self->priv->temp_extraction_dir);
+ self->priv->temp_extraction_dir = NULL;
+ }
+
+ if (archive->extract_here)
+ _g_uri_remove_directory (fr_archive_get_last_extraction_destination (archive));
+ }
+ break;
+
+ case FR_ACTION_LISTING_CONTENT:
+ /* order the list by name to speed up search */
+ g_ptr_array_sort (archive->files, file_data_compare_by_path);
- if (comm->action == FR_ACTION_LISTING_CONTENT) {
- /* order the list by name to speed up search */
- g_ptr_array_sort (comm->files, file_data_compare_by_path);
+ /* the name of the volumes are different from the
+ * original name */
+ if (archive->multi_volume)
+ fr_archive_change_name (archive, self->filename);
+ fr_archive_update_capabilities (archive);
+ break;
+
+ default:
+ /* nothing */
+ break;
}
- g_signal_emit (G_OBJECT (comm),
- fr_command_signals[DONE],
- 0,
- comm->action,
- error);
+ g_signal_emit_by_name (self,
+ "done",
+ archive->action,
+ error);
+}
+
+
+#endif
+
+
+static gboolean
+process_sticky_only_cb (FrProcess *process,
+ gpointer user_data)
+{
+ FrArchive *archive = user_data;
+
+ fr_archive_set_stoppable (archive, FALSE);
+ return TRUE;
}
static void
-fr_command_set_process (FrCommand *comm,
- FrProcess *process)
+_fr_command_set_process (FrCommand *self,
+ FrProcess *process)
{
- if (comm->process != NULL) {
- g_signal_handlers_disconnect_matched (G_OBJECT (comm->process),
- G_SIGNAL_MATCH_DATA,
- 0,
- 0, NULL,
- 0,
- comm);
- g_object_unref (G_OBJECT (comm->process));
- comm->process = NULL;
+ if (self->process != NULL) {
+ g_signal_handlers_disconnect_matched (G_OBJECT (self->process),
+ G_SIGNAL_MATCH_DATA,
+ 0,
+ 0, NULL,
+ 0,
+ self);
+ g_object_unref (G_OBJECT (self->process));
+ self->process = NULL;
}
if (process == NULL)
return;
- g_object_ref (G_OBJECT (process));
- comm->process = process;
- g_signal_connect (G_OBJECT (comm->process),
- "start",
- G_CALLBACK (fr_command_start),
- comm);
- g_signal_connect (G_OBJECT (comm->process),
- "done",
- G_CALLBACK (fr_command_done),
- comm);
+ self->process = g_object_ref (process);
+ g_signal_connect (G_OBJECT (self->process),
+ "sticky_only",
+ G_CALLBACK (process_sticky_only_cb),
+ self);
+}
+
+
+static void
+_fr_command_set_filename (FrCommand *self,
+ const char *filename)
+{
+ if (self->filename != NULL) {
+ g_free (self->filename);
+ self->filename = NULL;
+ }
+
+ if (self->e_filename != NULL) {
+ g_free (self->e_filename);
+ self->e_filename = NULL;
+ }
+
+ if (filename != NULL) {
+ if (! g_path_is_absolute (filename)) {
+ char *current_dir;
+
+ current_dir = g_get_current_dir ();
+ self->filename = g_strconcat (current_dir,
+ "/",
+ filename,
+ NULL);
+ g_free (current_dir);
+ }
+ else
+ self->filename = g_strdup (filename);
+
+ self->e_filename = g_shell_quote (self->filename);
+
+ debug (DEBUG_INFO, "filename : %s\n", self->filename);
+ debug (DEBUG_INFO, "e_filename : %s\n", self->e_filename);
+ }
+
+ g_signal_emit_by_name (self, "working-archive", self->filename);
+}
+
+
+static void
+_fr_command_set_filename_from_file (FrCommand *self,
+ GFile *file)
+{
+ char *filename;
+
+ filename = g_file_get_path (file);
+ _fr_command_set_filename (self, filename);
+
+ g_free (filename);
}
@@ -256,32 +723,16 @@ fr_command_set_property (GObject *object,
const GValue *value,
GParamSpec *pspec)
{
- FrCommand *comm;
+ FrCommand *self;
- comm = FR_COMMAND (object);
+ self = FR_COMMAND (object);
switch (prop_id) {
case PROP_PROCESS:
- fr_command_set_process (comm, g_value_get_object (value));
- break;
- case PROP_FILE:
- fr_command_set_file (comm, g_value_get_object (value));
- break;
- case PROP_MIME_TYPE:
- fr_command_set_mime_type (comm, g_value_get_string (value));
- break;
- case PROP_PASSWORD:
- g_free (comm->password);
- comm->password = g_strdup (g_value_get_string (value));
+ _fr_command_set_process (self, g_value_get_object (value));
break;
- case PROP_ENCRYPT_HEADER:
- comm->encrypt_header = g_value_get_boolean (value);
- break;
- case PROP_COMPRESSION:
- comm->compression = g_value_get_enum (value);
- break;
- case PROP_VOLUME_SIZE:
- comm->volume_size = g_value_get_uint (value);
+ case PROP_FILENAME:
+ _fr_command_set_filename_from_file (self, g_value_get_object (value));
break;
default:
break;
@@ -295,31 +746,18 @@ fr_command_get_property (GObject *object,
GValue *value,
GParamSpec *pspec)
{
- FrCommand *comm;
+ FrCommand *self;
+ GFile *file;
- comm = FR_COMMAND (object);
+ self = FR_COMMAND (object);
switch (prop_id) {
case PROP_PROCESS:
- g_value_set_object (value, comm->process);
- break;
- case PROP_FILE:
- g_value_take_object (value, g_file_new_for_path (comm->filename));
- break;
- case PROP_MIME_TYPE:
- g_value_set_static_string (value, comm->mime_type);
+ g_value_set_object (value, self->process);
break;
- case PROP_PASSWORD:
- g_value_set_string (value, comm->password);
- break;
- case PROP_ENCRYPT_HEADER:
- g_value_set_boolean (value, comm->encrypt_header);
- break;
- case PROP_COMPRESSION:
- g_value_set_enum (value, comm->compression);
- break;
- case PROP_VOLUME_SIZE:
- g_value_set_uint (value, comm->volume_size);
+ case PROP_FILENAME:
+ file = g_file_new_for_path (self->filename);
+ g_value_take_object (value, file);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -331,483 +769,2733 @@ fr_command_get_property (GObject *object,
static void
fr_command_finalize (GObject *object)
{
- FrCommand* comm;
+ FrCommand *self;
g_return_if_fail (object != NULL);
g_return_if_fail (FR_IS_COMMAND (object));
- comm = FR_COMMAND (object);
+ self = FR_COMMAND (object);
- g_free (comm->filename);
- g_free (comm->e_filename);
- g_free (comm->password);
- if (comm->files != NULL)
- _g_ptr_array_free_full (comm->files, (GFunc) file_data_free, NULL);
- fr_command_set_process (comm, NULL);
+ _g_object_unref (self->process);
+ _fr_command_remove_temp_work_dir (self);
+ if (self->priv->dropped_items_data != NULL) {
+ dropped_items_data_free (self->priv->dropped_items_data);
+ self->priv->dropped_items_data = NULL;
+ }
+ g_free (self->priv->temp_extraction_dir);
- /* Chain up */
if (G_OBJECT_CLASS (fr_command_parent_class)->finalize)
G_OBJECT_CLASS (fr_command_parent_class)->finalize (object);
}
-static void
-fr_command_class_init (FrCommandClass *klass)
-{
- GObjectClass *gobject_class;
-
- fr_command_parent_class = g_type_class_peek_parent (klass);
-
- /* virtual functions */
+/* -- load -- */
- gobject_class = G_OBJECT_CLASS (klass);
- gobject_class->finalize = fr_command_finalize;
- gobject_class->set_property = fr_command_set_property;
- gobject_class->get_property = fr_command_get_property;
- klass->list = base_fr_command_list;
- klass->add = base_fr_command_add;
- klass->delete = base_fr_command_delete;
- klass->extract = base_fr_command_extract;
- klass->test = base_fr_command_test;
- klass->uncompress = base_fr_command_uncompress;
- klass->recompress = base_fr_command_recompress;
- klass->handle_error = base_fr_command_handle_error;
- klass->get_mime_types = base_fr_command_get_mime_types;
- klass->get_capabilities = base_fr_command_get_capabilities;
- klass->set_mime_type = base_fr_command_set_mime_type;
- klass->get_packages = base_fr_command_get_packages;
- klass->start = NULL;
- klass->done = NULL;
- klass->progress = NULL;
- klass->message = NULL;
-
- /* signals */
-
- fr_command_signals[START] =
- g_signal_new ("start",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (FrCommandClass, start),
- NULL, NULL,
- fr_marshal_VOID__INT,
- G_TYPE_NONE,
- 1, G_TYPE_INT);
- fr_command_signals[DONE] =
- g_signal_new ("done",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (FrCommandClass, done),
- NULL, NULL,
- fr_marshal_VOID__INT_BOXED,
- G_TYPE_NONE, 2,
- G_TYPE_INT,
- FR_TYPE_PROC_ERROR);
- fr_command_signals[PROGRESS] =
- g_signal_new ("progress",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (FrCommandClass, progress),
- NULL, NULL,
- fr_marshal_VOID__DOUBLE,
- G_TYPE_NONE, 1,
- G_TYPE_DOUBLE);
- fr_command_signals[MESSAGE] =
- g_signal_new ("message",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (FrCommandClass, message),
- NULL, NULL,
- fr_marshal_VOID__STRING,
- G_TYPE_NONE, 1,
- G_TYPE_STRING);
- fr_command_signals[WORKING_ARCHIVE] =
- g_signal_new ("working_archive",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (FrCommandClass, working_archive),
- NULL, NULL,
- fr_marshal_VOID__STRING,
- G_TYPE_NONE, 1,
- G_TYPE_STRING);
+typedef struct {
+ FrArchive *archive;
+ char *password;
+ GCancellable *cancellable;
+ GSimpleAsyncResult *result;
+} LoadData;
- /* properties */
- g_object_class_install_property (gobject_class,
- PROP_PROCESS,
- g_param_spec_object ("process",
- "Process",
- "The process object used by the command",
- FR_TYPE_PROCESS,
- G_PARAM_READWRITE));
- g_object_class_install_property (gobject_class,
- PROP_FILE,
- g_param_spec_object ("file",
- "File",
- "The archive local file",
- G_TYPE_FILE,
- G_PARAM_READWRITE));
- g_object_class_install_property (gobject_class,
- PROP_MIME_TYPE,
- g_param_spec_string ("mime-type",
- "Mime type",
- "The file mime-type",
- NULL,
- G_PARAM_READWRITE));
- g_object_class_install_property (gobject_class,
- PROP_PASSWORD,
- g_param_spec_string ("password",
- "Password",
- "The archive password",
- NULL,
- G_PARAM_READWRITE));
- g_object_class_install_property (gobject_class,
- PROP_ENCRYPT_HEADER,
- g_param_spec_boolean ("encrypt-header",
- "Encrypt header",
- "Whether to encrypt the archive header when creating the archive",
- FALSE,
- G_PARAM_READWRITE));
- g_object_class_install_property (gobject_class,
- PROP_COMPRESSION,
- g_param_spec_enum ("compression",
- "Compression type",
- "The compression type to use when creating the archive",
- FR_TYPE_COMPRESSION,
- FR_COMPRESSION_NORMAL,
- G_PARAM_READWRITE));
- g_object_class_install_property (gobject_class,
- PROP_VOLUME_SIZE,
- g_param_spec_uint ("volume-size",
- "Volume size",
- "The size of each volume or 0 to not use volumes",
- 0L,
- G_MAXUINT,
- 0,
- G_PARAM_READWRITE));
+static void
+load_data_free (LoadData *add_data)
+{
+ _g_object_unref (add_data->archive);
+ g_free (add_data->password);
+ _g_object_unref (add_data->cancellable);
+ _g_object_unref (add_data->result);
+ g_free (add_data);
}
static void
-fr_command_init (FrCommand *self)
+_fr_command_load_complete_with_error (LoadData *add_data,
+ GError *error)
{
- self->files = g_ptr_array_sized_new (INITIAL_SIZE);
+ g_return_if_fail (error != NULL);
- self->password = NULL;
- self->encrypt_header = FALSE;
- self->compression = FR_COMPRESSION_NORMAL;
- self->volume_size = 0;
- self->filename = NULL;
- self->e_filename = NULL;
- self->fake_load = FALSE;
+ g_simple_async_result_set_from_error (add_data->result, error);
+ g_simple_async_result_complete_in_idle (add_data->result);
- self->propAddCanUpdate = FALSE;
- self->propAddCanReplace = FALSE;
- self->propAddCanStoreFolders = FALSE;
- self->propExtractCanAvoidOverwrite = FALSE;
- self->propExtractCanSkipOlder = FALSE;
- self->propExtractCanJunkPaths = FALSE;
- self->propPassword = FALSE;
- self->propTest = FALSE;
- self->propCanExtractAll = TRUE;
- self->propCanDeleteNonEmptyFolders = TRUE;
- self->propCanExtractNonEmptyFolders = TRUE;
- self->propListFromFile = FALSE;
+ load_data_free (add_data);
}
static void
-fr_command_set_filename (FrCommand *comm,
- const char *filename)
+_fr_command_load_complete (LoadData *load_data)
{
- g_return_if_fail (FR_IS_COMMAND (comm));
-
- if (comm->filename != NULL) {
- g_free (comm->filename);
- comm->filename = NULL;
- }
-
- if (comm->e_filename != NULL) {
- g_free (comm->e_filename);
- comm->e_filename = NULL;
- }
+ FrArchive *archive;
- if (filename != NULL) {
- if (! g_path_is_absolute (filename)) {
- char *current_dir;
+ archive = load_data->archive;
- current_dir = g_get_current_dir ();
- comm->filename = g_strconcat (current_dir,
- "/",
- filename,
- NULL);
- g_free (current_dir);
- }
- else
- comm->filename = g_strdup (filename);
+ /* order the list by name to speed up search */
+ g_ptr_array_sort (archive->files, file_data_compare_by_path);
- comm->e_filename = g_shell_quote (comm->filename);
+ /* the name of the volumes are different from the
+ * original name */
+ if (archive->multi_volume)
+ fr_archive_change_name (archive, FR_COMMAND (archive)->filename);
+ fr_archive_update_capabilities (archive);
- debug (DEBUG_INFO, "filename : %s\n", comm->filename);
- debug (DEBUG_INFO, "e_filename : %s\n", comm->e_filename);
- }
+ g_simple_async_result_complete_in_idle (load_data->result);
- fr_command_working_archive (comm, comm->filename);
+ load_data_free (load_data);
}
-void
-fr_command_set_file (FrCommand *comm,
- GFile *file)
+static void
+load_local_archive_list_ready_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
{
- char *filename;
+ LoadData *load_data = user_data;
+ FrError *error = NULL;
- filename = g_file_get_path (file);
- fr_command_set_filename (comm, filename);
+ if (! fr_command_handle_process_error (FR_COMMAND (load_data->archive), result, &error))
+ return;
- g_free (filename);
+ if (error != NULL) {
+ _fr_command_load_complete_with_error (load_data, error->gerror);
+ fr_error_free (error);
+ return;
+ }
+
+ _fr_command_load_complete (load_data);
+
+ fr_error_free (error);
}
-void
-fr_command_set_multi_volume (FrCommand *comm,
- GFile *file)
+static void
+load_local_archive (LoadData *load_data)
{
- comm->multi_volume = TRUE;
- fr_command_set_file (comm, file);
+ FrCommand *self = FR_COMMAND (load_data->archive);
+
+ load_data->archive->action = FR_ACTION_LISTING_CONTENT;
+ fr_process_set_out_line_func (self->process, NULL, NULL);
+ fr_process_set_err_line_func (self->process, NULL, NULL);
+ fr_process_use_standard_locale (self->process, TRUE);
+ load_data->archive->multi_volume = FALSE;
+
+ g_object_set (self,
+ "filename", self->priv->local_copy,
+ "password", load_data->password,
+ NULL);
+
+ fr_process_clear (self->process);
+ if (FR_COMMAND_GET_CLASS (G_OBJECT (self))->list (self))
+ fr_process_execute (self->process,
+ load_data->cancellable,
+ load_local_archive_list_ready_cb,
+ load_data);
+ else
+ _fr_command_load_complete (load_data);
}
-void
-fr_command_list (FrCommand *comm)
+static void
+copy_remote_file_done (GError *error,
+ gpointer user_data)
{
- g_return_if_fail (FR_IS_COMMAND (comm));
+ LoadData *load_data = user_data;
- fr_command_progress (comm, -1.0);
+ if (error != NULL)
+ _fr_command_load_complete_with_error (load_data, error);
+ else
+ load_local_archive (load_data);
+}
- if (comm->files != NULL) {
- _g_ptr_array_free_full (comm->files, (GFunc) file_data_free, NULL);
- comm->files = g_ptr_array_sized_new (INITIAL_SIZE);
- }
- comm->action = FR_ACTION_LISTING_CONTENT;
- fr_process_set_out_line_func (comm->process, NULL, NULL);
- fr_process_set_err_line_func (comm->process, NULL, NULL);
- fr_process_use_standard_locale (comm->process, TRUE);
- comm->multi_volume = FALSE;
+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)
+{
+ LoadData *load_data = user_data;
- if (! comm->fake_load)
- FR_COMMAND_GET_CLASS (G_OBJECT (comm))->list (comm);
- else
- g_signal_emit (G_OBJECT (comm),
- fr_command_signals[DONE],
- 0,
- comm->action,
- &comm->process->error);
+ g_signal_emit_by_name (load_data->archive,
+ "progress",
+ (double) current_num_bytes / total_num_bytes);
}
-void
-fr_command_add (FrCommand *comm,
- const char *from_file,
- GList *file_list,
- const char *base_dir,
- gboolean update,
- gboolean recursive)
+static gboolean
+copy_remote_file_done_cb (gpointer user_data)
{
- fr_command_progress (comm, -1.0);
+ LoadData *load_data = user_data;
- comm->action = FR_ACTION_ADDING_FILES;
- fr_process_set_out_line_func (FR_COMMAND (comm)->process, NULL, NULL);
- fr_process_set_err_line_func (FR_COMMAND (comm)->process, NULL, NULL);
+ copy_remote_file_done (NULL, load_data);
- FR_COMMAND_GET_CLASS (G_OBJECT (comm))->add (comm,
- from_file,
- file_list,
- base_dir,
- update,
- recursive);
+ return FALSE;
}
-void
-fr_command_delete (FrCommand *comm,
- const char *from_file,
- GList *file_list)
+static void
+copy_remote_file (LoadData *load_data)
{
- fr_command_progress (comm, -1.0);
+ FrCommand *self = FR_COMMAND (load_data->archive);
- comm->action = FR_ACTION_DELETING_FILES;
- fr_process_set_out_line_func (FR_COMMAND (comm)->process, NULL, NULL);
- fr_process_set_err_line_func (FR_COMMAND (comm)->process, NULL, NULL);
+ if (! g_file_query_exists (fr_archive_get_file (FR_ARCHIVE (self)),
+ load_data->cancellable))
+ {
+ GError *error;
- FR_COMMAND_GET_CLASS (G_OBJECT (comm))->delete (comm, from_file, file_list);
-}
+ error = g_error_new (G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("Archive not found"));
+ _fr_command_load_complete_with_error (load_data, error);
+ g_error_free (error);
+ return;
+ }
-void
-fr_command_extract (FrCommand *comm,
- const char *from_file,
- GList *file_list,
- const char *dest_dir,
- gboolean overwrite,
- gboolean skip_older,
- gboolean junk_paths)
+ if (self->priv->is_remote)
+ g_copy_file_async (fr_archive_get_file (FR_ARCHIVE (self)),
+ self->priv->local_copy,
+ G_FILE_COPY_OVERWRITE,
+ G_PRIORITY_DEFAULT,
+ load_data->cancellable,
+ copy_remote_file_progress,
+ load_data,
+ copy_remote_file_done,
+ load_data);
+ else
+ g_idle_add (copy_remote_file_done_cb, load_data);
+}
+
+
+static void
+fr_command_load (FrArchive *archive,
+ const char *password,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ LoadData *load_data;
+
+ load_data = g_new0 (LoadData, 1);
+ load_data->archive = g_object_ref (archive);
+ load_data->password = g_strdup (password);
+ load_data->cancellable = _g_object_ref (cancellable);
+ load_data->result = g_simple_async_result_new (G_OBJECT (archive),
+ callback,
+ user_data,
+ fr_archive_load);
+
+ copy_remote_file (load_data);
+}
+
+
+/* -- add -- */
+
+
+static char *
+create_tmp_base_dir (const char *base_dir,
+ const char *dest_path)
+{
+ char *dest_dir;
+ char *temp_dir;
+ char *tmp;
+ char *parent_dir;
+ char *dir;
+
+ if ((dest_path == NULL)
+ || (*dest_path == '\0')
+ || (strcmp (dest_path, "/") == 0))
+ {
+ return g_strdup (base_dir);
+ }
+
+ dest_dir = g_strdup (dest_path);
+ if (dest_dir[strlen (dest_dir) - 1] == G_DIR_SEPARATOR)
+ dest_dir[strlen (dest_dir) - 1] = 0;
+
+ debug (DEBUG_INFO, "base_dir: %s\n", base_dir);
+ debug (DEBUG_INFO, "dest_dir: %s\n", dest_dir);
+
+ temp_dir = _g_path_get_temp_work_dir (NULL);
+ tmp = _g_path_remove_level (dest_dir);
+ parent_dir = g_build_filename (temp_dir, tmp, NULL);
+ g_free (tmp);
+
+ debug (DEBUG_INFO, "mkdir %s\n", parent_dir);
+ _g_path_make_directory_tree (parent_dir, 0700, NULL);
+ g_free (parent_dir);
+
+ dir = g_build_filename (temp_dir, "/", dest_dir, NULL);
+ debug (DEBUG_INFO, "symlink %s --> %s\n", dir, base_dir);
+ if (! symlink (base_dir, dir)) {
+ /* void */
+ }
+
+ g_free (dir);
+ g_free (dest_dir);
+
+ return temp_dir;
+}
+
+
+static FileData *
+find_file_in_archive (FrArchive *archive,
+ char *path)
+{
+ int i;
+
+ g_return_val_if_fail (path != NULL, NULL);
+
+ i = find_path_in_file_data_array (archive->files, path);
+ if (i >= 0)
+ return (FileData *) g_ptr_array_index (archive->files, i);
+ else
+ return NULL;
+}
+
+
+static void delete_from_archive (FrCommand *self,
+ GList *file_list);
+
+
+static GList *
+newer_files_only (FrArchive *archive,
+ GList *file_list,
+ const char *base_dir)
+{
+ GList *newer_files = NULL;
+ GList *scan;
+
+ for (scan = file_list; scan; scan = scan->next) {
+ char *filename = scan->data;
+ char *fullpath;
+ char *uri;
+ FileData *fdata;
+
+ fdata = find_file_in_archive (archive, filename);
+
+ if (fdata == NULL) {
+ newer_files = g_list_prepend (newer_files, g_strdup (scan->data));
+ continue;
+ }
+
+ fullpath = g_strconcat (base_dir, "/", filename, NULL);
+ uri = g_filename_to_uri (fullpath, NULL, NULL);
+
+ if (fdata->modified >= _g_uri_get_file_mtime (uri)) {
+ g_free (fullpath);
+ g_free (uri);
+ continue;
+ }
+ g_free (fullpath);
+ g_free (uri);
+
+ newer_files = g_list_prepend (newer_files, g_strdup (scan->data));
+ }
+
+ return newer_files;
+}
+
+
+static gboolean
+save_list_to_temp_file (GList *file_list,
+ char **list_dir,
+ char **list_filename,
+ GError **error)
+{
+ gboolean error_occurred = FALSE;
+ GFile *list_file;
+ GFileOutputStream *ostream;
+
+ if (error != NULL)
+ *error = NULL;
+ *list_dir = _g_path_get_temp_work_dir (NULL);
+ *list_filename = g_build_filename (*list_dir, "file-list", NULL);
+ list_file = g_file_new_for_path (*list_filename);
+ ostream = g_file_create (list_file, G_FILE_CREATE_PRIVATE, NULL, error);
+
+ if (ostream != NULL) {
+ GList *scan;
+
+ for (scan = file_list; scan != NULL; scan = scan->next) {
+ char *filename = scan->data;
+
+ filename = _g_str_substitute (filename, "\n", "\\n");
+ if ((g_output_stream_write (G_OUTPUT_STREAM (ostream), filename, strlen (filename), NULL, error) < 0)
+ || (g_output_stream_write (G_OUTPUT_STREAM (ostream), "\n", 1, NULL, error) < 0))
+ {
+ error_occurred = TRUE;
+ }
+
+ g_free (filename);
+
+ if (error_occurred)
+ break;
+ }
+ if (! error_occurred && ! g_output_stream_close (G_OUTPUT_STREAM (ostream), NULL, error))
+ error_occurred = TRUE;
+ g_object_unref (ostream);
+ }
+ else
+ error_occurred = TRUE;
+
+ if (error_occurred) {
+ _g_path_remove_directory (*list_dir);
+ g_free (*list_dir);
+ g_free (*list_filename);
+ *list_dir = NULL;
+ *list_filename = NULL;
+ }
+
+ g_object_unref (list_file);
+
+ return ! error_occurred;
+}
+
+
+static GList *
+split_in_chunks (GList *file_list)
+{
+ GList *chunks = NULL;
+ GList *new_file_list;
+ GList *scan;
+
+ new_file_list = g_list_copy (file_list);
+ for (scan = new_file_list; scan != NULL; /* void */) {
+ GList *prev = scan->prev;
+ GList *chunk;
+ int l;
+
+ chunk = scan;
+ l = 0;
+ while ((scan != NULL) && (l < MAX_CHUNK_LEN)) {
+ if (l == 0)
+ l = strlen (scan->data);
+ prev = scan;
+ scan = scan->next;
+ if (scan != NULL)
+ l += strlen (scan->data);
+ }
+ if (prev != NULL) {
+ if (prev->next != NULL)
+ prev->next->prev = NULL;
+ prev->next = NULL;
+ }
+ chunks = g_list_append (chunks, chunk);
+ }
+
+ return chunks;
+}
+
+
+static gboolean
+_fr_command_add (FrCommand *self,
+ GList *file_list,
+ const char *base_dir,
+ const char *dest_dir,
+ gboolean update,
+ gboolean recursive,
+ const char *password,
+ gboolean encrypt_header,
+ FrCompression compression,
+ guint volume_size,
+ GError **error)
+{
+ FrArchive *archive = FR_ARCHIVE (self);
+ GList *new_file_list = NULL;
+ gboolean base_dir_created = FALSE;
+ GList *scan;
+ char *tmp_base_dir = NULL;
+ char *tmp_archive_dir = NULL;
+ char *archive_filename = NULL;
+ char *tmp_archive_filename = NULL;
+ gboolean error_occurred = FALSE;
+
+ if (file_list == NULL)
+ return FALSE;
+
+ g_object_set (self,
+ "filename", self->priv->local_copy,
+ "password", password,
+ "encrypt_header", encrypt_header,
+ "compression", compression,
+ "volume_size", volume_size,
+ NULL);
+
+ fr_archive_set_stoppable (archive, TRUE);
+
+ /* dest_dir is the destination folder inside the archive */
+
+ if ((dest_dir != NULL) && (*dest_dir != '\0') && (strcmp (dest_dir, "/") != 0)) {
+ const char *rel_dest_dir = dest_dir;
+
+ tmp_base_dir = create_tmp_base_dir (base_dir, dest_dir);
+ base_dir_created = TRUE;
+
+ if (dest_dir[0] == G_DIR_SEPARATOR)
+ rel_dest_dir = dest_dir + 1;
+
+ new_file_list = NULL;
+ for (scan = file_list; scan != NULL; scan = scan->next) {
+ char *filename = scan->data;
+ new_file_list = g_list_prepend (new_file_list, g_build_filename (rel_dest_dir, filename, NULL));
+ }
+ }
+ else {
+ tmp_base_dir = g_strdup (base_dir);
+ new_file_list = _g_string_list_dup (file_list);
+ }
+
+ /* if the command cannot update, get the list of files that are
+ * newer than the ones in the archive. */
+
+ if (update && ! archive->propAddCanUpdate) {
+ GList *tmp_file_list;
+
+ tmp_file_list = new_file_list;
+ new_file_list = newer_files_only (archive, tmp_file_list, tmp_base_dir);
+ _g_string_list_free (tmp_file_list);
+ }
+
+ if (new_file_list == NULL) {
+ debug (DEBUG_INFO, "nothing to update.\n");
+
+ if (base_dir_created)
+ _g_path_remove_directory (tmp_base_dir);
+ g_free (tmp_base_dir);
+
+ return FALSE;
+ }
+
+ self->creating_archive = ! g_file_query_exists (self->priv->local_copy, fr_archive_get_cancellable (FR_ARCHIVE (self)));
+
+ /* create the new archive in a temporary sub-directory, this allows
+ * to cancel the operation without losing the original archive and
+ * removing possible temporary files created by the command. */
+
+ {
+ GFile *local_copy_parent;
+ char *archive_dir;
+ GFile *tmp_file;
+
+ /* create the new archive in a sub-folder of the original
+ * archive this way the 'mv' command is fast. */
+
+ local_copy_parent = g_file_get_parent (self->priv->local_copy);
+ archive_dir = g_file_get_path (local_copy_parent);
+ tmp_archive_dir = _g_path_get_temp_work_dir (archive_dir);
+ archive_filename = g_file_get_path (self->priv->local_copy);
+ tmp_archive_filename = g_build_filename (tmp_archive_dir,
+ _g_path_get_file_name (archive_filename),
+ NULL);
+ tmp_file = g_file_new_for_path (tmp_archive_filename);
+ g_object_set (self, "filename", tmp_file, NULL);
+
+ if (! self->creating_archive) {
+ /* copy the original archive to the new position */
+
+ fr_process_begin_command (self->process, "cp");
+ fr_process_add_arg (self->process, "-f");
+ fr_process_add_arg (self->process, archive_filename);
+ fr_process_add_arg (self->process, tmp_archive_filename);
+ fr_process_end_command (self->process);
+ }
+
+ g_object_unref (tmp_file);
+ g_free (archive_dir);
+ g_object_unref (local_copy_parent);
+ }
+
+ fr_command_uncompress (self);
+
+ /* when files are already present in a tar archive and are added
+ * again, they are not replaced, so we have to delete them first. */
+
+ /* if we are adding (== ! update) and 'add' cannot replace or
+ * if we are updating and 'add' cannot update,
+ * delete the files first. */
+
+ if ((! update && ! archive->propAddCanReplace)
+ || (update && ! archive->propAddCanUpdate))
+ {
+ GList *del_list = NULL;
+
+ for (scan = new_file_list; scan != NULL; scan = scan->next) {
+ char *filename = scan->data;
+ if (find_file_in_archive (archive, filename))
+ del_list = g_list_prepend (del_list, filename);
+ }
+
+ /* delete */
+
+ if (del_list != NULL) {
+ delete_from_archive (self, del_list);
+ fr_process_set_ignore_error (self->process, TRUE);
+ g_list_free (del_list);
+ }
+ }
+
+ /* add now. */
+
+ fr_archive_set_n_files (archive, g_list_length (new_file_list));
+
+ if (archive->propListFromFile && (archive->n_files > LIST_LENGTH_TO_USE_FILE)) {
+ char *list_dir;
+ char *list_filename;
+
+ if (! save_list_to_temp_file (new_file_list, &list_dir, &list_filename, error)) {
+ error_occurred = TRUE;
+ }
+ else {
+ fr_command_add (self,
+ list_filename,
+ new_file_list,
+ tmp_base_dir,
+ update,
+ recursive);
+
+ /* remove the temp dir */
+
+ fr_process_begin_command (self->process, "rm");
+ fr_process_set_working_dir (self->process, g_get_tmp_dir());
+ fr_process_set_sticky (self->process, TRUE);
+ fr_process_add_arg (self->process, "-rf");
+ fr_process_add_arg (self->process, list_dir);
+ fr_process_end_command (self->process);
+ }
+
+ g_free (list_filename);
+ g_free (list_dir);
+ }
+ else {
+ GList *chunks = NULL;
+
+ /* specify the file list on the command line, splitting
+ * in more commands to avoid to overflow the command line
+ * length limit. */
+
+ chunks = split_in_chunks (new_file_list);
+ for (scan = chunks; scan != NULL; scan = scan->next) {
+ GList *chunk = scan->data;
+
+ fr_command_add (self,
+ NULL,
+ chunk,
+ tmp_base_dir,
+ update,
+ recursive);
+ g_list_free (chunk);
+ }
+
+ g_list_free (chunks);
+ }
+
+ _g_string_list_free (new_file_list);
+
+ if (! error_occurred) {
+ fr_command_recompress (self);
+
+ /* move the new archive to the original position */
+
+ fr_process_begin_command (self->process, "mv");
+ fr_process_add_arg (self->process, "-f");
+ fr_process_add_arg (self->process, tmp_archive_filename);
+ fr_process_add_arg (self->process, archive_filename);
+ fr_process_end_command (self->process);
+
+ /* remove the temp sub-directory */
+
+ fr_process_begin_command (self->process, "rm");
+ fr_process_set_working_dir (self->process, g_get_tmp_dir ());
+ fr_process_set_sticky (self->process, TRUE);
+ fr_process_add_arg (self->process, "-rf");
+ fr_process_add_arg (self->process, tmp_archive_dir);
+ fr_process_end_command (self->process);
+
+ /* remove the archive dir */
+
+ if (base_dir_created) {
+ fr_process_begin_command (self->process, "rm");
+ fr_process_set_working_dir (self->process, g_get_tmp_dir ());
+ fr_process_set_sticky (self->process, TRUE);
+ fr_process_add_arg (self->process, "-rf");
+ fr_process_add_arg (self->process, tmp_base_dir);
+ fr_process_end_command (self->process);
+ }
+ }
+
+ g_free (tmp_archive_filename);
+ g_free (archive_filename);
+ g_free (tmp_archive_dir);
+ g_free (tmp_base_dir);
+
+ return ! error_occurred;
+}
+
+
+/* -- fr_command_add_files -- */
+
+
+typedef struct {
+ FrArchive *archive;
+ GCancellable *cancellable;
+ GSimpleAsyncResult *result;
+} AddData;
+
+
+static void
+add_data_free (AddData *add_data)
+{
+ _g_object_unref (add_data->archive);
+ _g_object_unref (add_data->cancellable);
+ _g_object_unref (add_data->result);
+ g_free (add_data);
+}
+
+
+static void add_dropped_items (DroppedItemsData *data);
+
+
+static void
+process_ready_for_add_files_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ AddData *add_data = user_data;
+ FrError *error = NULL;
+
+ if (! fr_process_execute_finish (FR_PROCESS (source_object), result, &error)) {
+ g_simple_async_result_set_from_error (add_data->result, error->gerror);
+ }
+ else {
+ FrArchive *archive = add_data->archive;
+ FrCommand *self = FR_COMMAND (archive);
+
+ _fr_command_remove_temp_work_dir (self);
+
+ if (self->priv->continue_adding_dropped_items) {
+ add_dropped_items (self->priv->dropped_items_data);
+ return;
+ }
+
+ if (self->priv->dropped_items_data != NULL) {
+ dropped_items_data_free (self->priv->dropped_items_data);
+ self->priv->dropped_items_data = NULL;
+ }
+
+ /* the name of the volumes are different from the
+ * original name */
+ if (archive->multi_volume)
+ fr_archive_change_name (archive, self->filename);
+
+ if (! g_file_has_uri_scheme (fr_archive_get_file (archive), "file")) {
+ copy_archive_to_remote_location (add_data->archive,
+ add_data->result,
+ add_data->cancellable);
+
+ add_data_free (add_data);
+ return;
+ }
+ }
+
+ g_simple_async_result_complete_in_idle (add_data->result);
+
+ fr_error_free (error);
+ add_data_free (add_data);
+}
+
+
+static void
+_fr_command_add_local_files (FrCommand *self,
+ GList *file_list,
+ const char *base_dir,
+ const char *dest_dir,
+ gboolean update,
+ gboolean recursive,
+ const char *password,
+ gboolean encrypt_header,
+ FrCompression compression,
+ guint volume_size,
+ GCancellable *cancellable,
+ GSimpleAsyncResult *command_result)
+{
+ AddData *add_data;
+ GError *error = NULL;
+
+ g_object_set (self, "filename", self->priv->local_copy, NULL);
+ fr_process_clear (self->process);
+ if (! _fr_command_add (self,
+ file_list,
+ base_dir,
+ dest_dir,
+ update,
+ recursive,
+ password,
+ encrypt_header,
+ compression,
+ volume_size,
+ &error))
+ {
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (command_result, error);
+ g_error_free (error);
+ }
+ g_simple_async_result_complete_in_idle (command_result);
+ return;
+ }
+
+ add_data = g_new0 (AddData, 1);
+ add_data->archive = _g_object_ref (self);
+ add_data->cancellable = _g_object_ref (cancellable);
+ add_data->result = _g_object_ref (command_result);
+
+ fr_process_execute (self->process,
+ add_data->cancellable,
+ process_ready_for_add_files_cb,
+ add_data);
+}
+
+
+static void
+copy_remote_files_done (GError *error,
+ gpointer user_data)
+{
+ XferData *xfer_data = user_data;
+
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (xfer_data->result, error);
+ g_simple_async_result_complete_in_idle (xfer_data->result);
+
+ }
+ else
+ _fr_command_add_local_files (FR_COMMAND (xfer_data->archive),
+ xfer_data->file_list,
+ xfer_data->tmp_dir,
+ xfer_data->dest_dir,
+ FALSE,
+ xfer_data->recursive,
+ xfer_data->password,
+ xfer_data->encrypt_header,
+ xfer_data->compression,
+ xfer_data->volume_size,
+ xfer_data->cancellable,
+ g_object_ref (xfer_data->result));
+
+ 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_by_name (xfer_data->archive,
+ "progress",
+ (double) current_file / (total_files + 1));
+}
+
+
+static void
+copy_remote_files (FrCommand *self,
+ GList *file_list,
+ const char *base_uri,
+ const char *dest_dir,
+ gboolean update,
+ gboolean recursive,
+ const char *password,
+ gboolean encrypt_header,
+ FrCompression compression,
+ guint volume_size,
+ const char *tmp_dir,
+ GCancellable *cancellable,
+ GSimpleAsyncResult *result)
+{
+ GList *sources = NULL;
+ GList *destinations = NULL;
+ GHashTable *created_folders;
+ GList *scan;
+ XferData *xfer_data;
+
+ sources = NULL;
+ destinations = NULL;
+ 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 = _g_path_remove_level (local_uri);
+ if (g_hash_table_lookup (created_folders, local_folder_uri) == NULL) {
+ GError *error = NULL;
+ if (! _g_uri_ensure_dir_exists (local_folder_uri, 0755, &error)) {
+ g_simple_async_result_set_from_error (result, error);
+ g_simple_async_result_complete_in_idle (result);
+
+ g_clear_error (&error);
+ g_object_unref (result);
+ g_free (local_folder_uri);
+ g_free (local_uri);
+ _g_file_list_free (sources);
+ _g_file_list_free (destinations);
+ g_hash_table_destroy (created_folders);
+
+ 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 = FR_ARCHIVE (self);
+ xfer_data->file_list = _g_string_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->recursive = recursive;
+ 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);
+ xfer_data->cancellable = _g_object_ref (cancellable);
+ xfer_data->result = result;
+
+ g_signal_emit_by_name (self, "start", FR_ACTION_COPYING_FILES_FROM_REMOTE);
+
+ g_copy_files_async (sources,
+ destinations,
+ G_FILE_COPY_OVERWRITE,
+ G_PRIORITY_DEFAULT,
+ cancellable,
+ copy_remote_files_progress,
+ xfer_data,
+ copy_remote_files_done,
+ xfer_data);
+
+ _g_file_list_free (sources);
+ _g_file_list_free (destinations);
+}
+
+
+static void
+fr_command_add_files (FrArchive *base,
+ GList *file_list,
+ const char *base_dir,
+ const char *dest_dir,
+ gboolean update,
+ gboolean recursive,
+ const char *password,
+ gboolean encrypt_header,
+ FrCompression compression,
+ guint volume_size,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ FrCommand *self = FR_COMMAND (base);
+ GSimpleAsyncResult *result;
+
+ result = g_simple_async_result_new (G_OBJECT (self),
+ callback,
+ user_data,
+ fr_archive_add_files);
+
+ if (_g_uri_is_local (base_dir)) {
+ char *local_dir;
+
+ local_dir = g_filename_from_uri (base_dir, NULL, NULL);
+ _fr_command_add_local_files (self,
+ file_list,
+ local_dir,
+ dest_dir,
+ update,
+ recursive,
+ password,
+ encrypt_header,
+ compression,
+ volume_size,
+ cancellable,
+ result);
+
+ g_free (local_dir);
+ }
+ else
+ copy_remote_files (self,
+ file_list,
+ base_dir,
+ dest_dir,
+ update,
+ recursive,
+ password,
+ encrypt_header,
+ compression,
+ volume_size,
+ _fr_command_get_temp_work_dir (self),
+ cancellable,
+ result);
+}
+
+
+/* -- remove -- */
+
+
+static gboolean
+file_is_in_subfolder_of (const char *filename,
+ GList *folder_list)
+{
+ GList *scan;
+
+ if (filename == NULL)
+ return FALSE;
+
+ for (scan = folder_list; scan; scan = scan->next) {
+ char *folder_in_list = (char*) scan->data;
+
+ if (_g_path_is_parent_of (folder_in_list, filename))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+static void
+delete_from_archive (FrCommand *self,
+ GList *file_list)
+{
+ FrArchive *archive = FR_ARCHIVE (self);
+ gboolean file_list_created = FALSE;
+ GList *tmp_file_list = NULL;
+ gboolean tmp_file_list_created = FALSE;
+ GList *scan;
+
+ /* file_list == NULL means delete all the files in the archive. */
+
+ if (file_list == NULL) {
+ int i;
+
+ for (i = 0; i < archive->files->len; i++) {
+ FileData *fdata = g_ptr_array_index (archive->files, i);
+ file_list = g_list_prepend (file_list, fdata->original_path);
+ }
+
+ file_list_created = TRUE;
+ }
+
+ if (! archive->propCanDeleteNonEmptyFolders) {
+ GList *folders_to_remove;
+
+ /* remove from the list the files contained in folders to be
+ * removed. */
+
+ folders_to_remove = NULL;
+ for (scan = file_list; scan != NULL; scan = scan->next) {
+ char *path = scan->data;
+
+ if (path[strlen (path) - 1] == '/')
+ folders_to_remove = g_list_prepend (folders_to_remove, path);
+ }
+
+ if (folders_to_remove != NULL) {
+ tmp_file_list = NULL;
+ for (scan = file_list; scan != NULL; scan = scan->next) {
+ char *path = scan->data;
+
+ if (! file_is_in_subfolder_of (path, folders_to_remove))
+ tmp_file_list = g_list_prepend (tmp_file_list, path);
+ }
+ tmp_file_list_created = TRUE;
+ g_list_free (folders_to_remove);
+ }
+ }
+
+ if (! tmp_file_list_created)
+ tmp_file_list = g_list_copy (file_list);
+
+ if (file_list_created)
+ g_list_free (file_list);
+
+ fr_archive_set_n_files (archive, g_list_length (tmp_file_list));
+
+ if (archive->propListFromFile && (archive->n_files > LIST_LENGTH_TO_USE_FILE)) {
+ char *list_dir;
+ char *list_filename;
+
+ if (save_list_to_temp_file (tmp_file_list, &list_dir, &list_filename, NULL)) {
+ fr_command_delete (self,
+ list_filename,
+ tmp_file_list);
+
+ /* remove the temp dir */
+
+ fr_process_begin_command (self->process, "rm");
+ fr_process_set_working_dir (self->process, g_get_tmp_dir());
+ fr_process_set_sticky (self->process, TRUE);
+ fr_process_add_arg (self->process, "-rf");
+ fr_process_add_arg (self->process, list_dir);
+ fr_process_end_command (self->process);
+ }
+
+ g_free (list_filename);
+ g_free (list_dir);
+ }
+ else {
+ for (scan = tmp_file_list; scan != NULL; ) {
+ GList *prev = scan->prev;
+ GList *chunk_list;
+ int l;
+
+ chunk_list = scan;
+ l = 0;
+ while ((scan != NULL) && (l < MAX_CHUNK_LEN)) {
+ if (l == 0)
+ l = strlen (scan->data);
+ prev = scan;
+ scan = scan->next;
+ if (scan != NULL)
+ l += strlen (scan->data);
+ }
+
+ prev->next = NULL;
+ fr_command_delete (self, NULL, chunk_list);
+ prev->next = scan;
+ }
+ }
+
+ g_list_free (tmp_file_list);
+}
+
+
+static void
+_fr_command_remove (FrCommand *self,
+ GList *file_list,
+ FrCompression compression)
+{
+ FrArchive *archive = FR_ARCHIVE (self);
+ char *tmp_archive_dir = NULL;
+ char *archive_filename = NULL;
+ char *tmp_archive_filename = NULL;
+
+ g_return_if_fail (self != NULL);
+
+ fr_archive_set_stoppable (archive, TRUE);
+ self->creating_archive = FALSE;
+ g_object_set (self, "compression", compression, NULL);
+
+ /* create the new archive in a temporary sub-directory, this allows
+ * to cancel the operation without losing the original archive and
+ * removing possible temporary files created by the command. */
+
+ {
+ GFile *local_copy_parent;
+ char *archive_dir;
+ GFile *tmp_file;
+
+ /* create the new archive in a sub-folder of the original
+ * archive this way the 'mv' command is fast. */
+
+ local_copy_parent = g_file_get_parent (self->priv->local_copy);
+ archive_dir = g_file_get_path (local_copy_parent);
+ tmp_archive_dir = _g_path_get_temp_work_dir (archive_dir);
+ archive_filename = g_file_get_path (self->priv->local_copy);
+ tmp_archive_filename = g_build_filename (tmp_archive_dir, _g_path_get_file_name (archive_filename), NULL);
+ tmp_file = g_file_new_for_path (tmp_archive_filename);
+ g_object_set (self, "file", tmp_file, NULL);
+
+ if (! self->creating_archive) {
+ /* copy the original self to the new position */
+
+ fr_process_begin_command (self->process, "cp");
+ fr_process_add_arg (self->process, "-f");
+ fr_process_add_arg (self->process, archive_filename);
+ fr_process_add_arg (self->process, tmp_archive_filename);
+ fr_process_end_command (self->process);
+ }
+
+ g_object_unref (tmp_file);
+ g_free (archive_dir);
+ g_object_unref (local_copy_parent);
+ }
+
+ /* uncompress, delete and recompress */
+
+ fr_command_uncompress (self);
+ delete_from_archive (self, file_list);
+ fr_command_recompress (self);
+
+ /* move the new self to the original position */
+
+ fr_process_begin_command (self->process, "mv");
+ fr_process_add_arg (self->process, "-f");
+ fr_process_add_arg (self->process, tmp_archive_filename);
+ fr_process_add_arg (self->process, archive_filename);
+ fr_process_end_command (self->process);
+
+ /* remove the temp sub-directory */
+
+ fr_process_begin_command (self->process, "rm");
+ fr_process_set_working_dir (self->process, g_get_tmp_dir ());
+ fr_process_set_sticky (self->process, TRUE);
+ fr_process_add_arg (self->process, "-rf");
+ fr_process_add_arg (self->process, tmp_archive_dir);
+ fr_process_end_command (self->process);
+
+ g_free (tmp_archive_filename);
+ g_free (archive_filename);
+ g_free (tmp_archive_dir);
+}
+
+
+static void
+process_ready_for_remove_files_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ XferData *xfer_data = user_data;
+ FrError *error = NULL;
+
+ if (! fr_process_execute_finish (FR_PROCESS (source_object), result, &error)) {
+ g_simple_async_result_set_from_error (xfer_data->result, error->gerror);
+ fr_error_free (error);
+ }
+ else {
+ if (! g_file_has_uri_scheme (fr_archive_get_file (xfer_data->archive), "file")) {
+ copy_archive_to_remote_location (xfer_data->archive,
+ xfer_data->result,
+ xfer_data->cancellable);
+
+ xfer_data_free (xfer_data);
+ return;
+ }
+ }
+
+ g_simple_async_result_complete_in_idle (xfer_data->result);
+
+ xfer_data_free (xfer_data);
+}
+
+
+static void
+fr_command_remove_files (FrArchive *archive,
+ GList *file_list,
+ FrCompression compression,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ FrCommand *self = FR_COMMAND (archive);
+ XferData *xfer_data;
+
+ xfer_data = g_new0 (XferData, 1);
+ xfer_data->archive = _g_object_ref (archive);
+ xfer_data->cancellable = _g_object_ref (cancellable);
+ xfer_data->result = g_simple_async_result_new (G_OBJECT (self),
+ callback,
+ user_data,
+ fr_archive_remove);
+
+ g_object_set (self, "filename", self->priv->local_copy, NULL);
+ fr_process_clear (self->process);
+ _fr_command_remove (self, file_list, compression);
+
+ fr_process_execute (self->process,
+ cancellable,
+ process_ready_for_remove_files_cb,
+ xfer_data);
+}
+
+
+/* -- extract -- */
+
+
+static void
+move_files_to_dir (FrCommand *self,
+ GList *file_list,
+ const char *source_dir,
+ const char *dest_dir,
+ gboolean overwrite)
+{
+ GList *list;
+ GList *scan;
+
+ /* we prefer mv instead of cp for performance reasons,
+ * but if the destination folder already exists mv
+ * doesn't work correctly. (bug #590027) */
+
+ list = g_list_copy (file_list);
+ for (scan = list; scan; /* void */) {
+ GList *next = scan->next;
+ char *filename = scan->data;
+ char *basename;
+ char *destname;
+
+ basename = g_path_get_basename (filename);
+ destname = g_build_filename (dest_dir, basename, NULL);
+ if (g_file_test (destname, G_FILE_TEST_IS_DIR)) {
+ fr_process_begin_command (self->process, "cp");
+ fr_process_add_arg (self->process, "-R");
+ if (overwrite)
+ fr_process_add_arg (self->process, "-f");
+ else
+ fr_process_add_arg (self->process, "-n");
+ if (filename[0] == '/')
+ fr_process_add_arg_concat (self->process, source_dir, filename, NULL);
+ else
+ fr_process_add_arg_concat (self->process, source_dir, "/", filename, NULL);
+ fr_process_add_arg (self->process, dest_dir);
+ fr_process_end_command (self->process);
+
+ list = g_list_remove_link (list, scan);
+ g_list_free (scan);
+ }
+
+ g_free (destname);
+ g_free (basename);
+
+ scan = next;
+ }
+
+ if (list == NULL)
+ return;
+
+ /* 'list' now contains the files that can be moved without problems */
+
+ fr_process_begin_command (self->process, "mv");
+ if (overwrite)
+ fr_process_add_arg (self->process, "-f");
+ else
+ fr_process_add_arg (self->process, "-n");
+ for (scan = list; scan; scan = scan->next) {
+ char *filename = scan->data;
+
+ if (filename[0] == '/')
+ fr_process_add_arg_concat (self->process, source_dir, filename, NULL);
+ else
+ fr_process_add_arg_concat (self->process, source_dir, "/", filename, NULL);
+ }
+ fr_process_add_arg (self->process, dest_dir);
+ fr_process_end_command (self->process);
+
+ g_list_free (list);
+}
+
+
+static void
+move_files_in_chunks (FrCommand *self,
+ GList *file_list,
+ const char *temp_dir,
+ const char *dest_dir,
+ gboolean overwrite)
+{
+ GList *scan;
+ int temp_dir_l;
+
+ temp_dir_l = strlen (temp_dir);
+
+ for (scan = file_list; scan != NULL; ) {
+ GList *prev = scan->prev;
+ GList *chunk_list;
+ int l;
+
+ chunk_list = scan;
+ l = 0;
+ while ((scan != NULL) && (l < MAX_CHUNK_LEN)) {
+ if (l == 0)
+ l = temp_dir_l + 1 + strlen (scan->data);
+ prev = scan;
+ scan = scan->next;
+ if (scan != NULL)
+ l += temp_dir_l + 1 + strlen (scan->data);
+ }
+
+ prev->next = NULL;
+ move_files_to_dir (self, chunk_list, temp_dir, dest_dir, overwrite);
+ prev->next = scan;
+ }
+}
+
+
+static void
+extract_from_archive (FrCommand *self,
+ GList *file_list,
+ const char *dest_dir,
+ gboolean overwrite,
+ gboolean skip_older,
+ gboolean junk_paths,
+ const char *password)
+{
+ GList *scan;
+
+ g_object_set (self, "password", password, NULL);
+
+ if (file_list == NULL) {
+ fr_command_extract (self,
+ NULL,
+ file_list,
+ dest_dir,
+ overwrite,
+ skip_older,
+ junk_paths);
+ return;
+ }
+
+ if (FR_ARCHIVE (self)->propListFromFile
+ && (g_list_length (file_list) > LIST_LENGTH_TO_USE_FILE))
+ {
+ char *list_dir;
+ char *list_filename;
+
+ if (save_list_to_temp_file (file_list, &list_dir, &list_filename, NULL)) {
+ fr_command_extract (self,
+ list_filename,
+ file_list,
+ dest_dir,
+ overwrite,
+ skip_older,
+ junk_paths);
+
+ /* remove the temp dir */
+
+ fr_process_begin_command (self->process, "rm");
+ fr_process_set_working_dir (self->process, g_get_tmp_dir());
+ fr_process_set_sticky (self->process, TRUE);
+ fr_process_add_arg (self->process, "-rf");
+ fr_process_add_arg (self->process, list_dir);
+ fr_process_end_command (self->process);
+ }
+
+ g_free (list_filename);
+ g_free (list_dir);
+ }
+ else {
+ for (scan = file_list; scan != NULL; ) {
+ GList *prev = scan->prev;
+ GList *chunk_list;
+ int l;
+
+ chunk_list = scan;
+ l = 0;
+ while ((scan != NULL) && (l < MAX_CHUNK_LEN)) {
+ if (l == 0)
+ l = strlen (scan->data);
+ prev = scan;
+ scan = scan->next;
+ if (scan != NULL)
+ l += strlen (scan->data);
+ }
+
+ prev->next = NULL;
+ fr_command_extract (self,
+ NULL,
+ chunk_list,
+ dest_dir,
+ overwrite,
+ skip_older,
+ junk_paths);
+ prev->next = scan;
+ }
+ }
+}
+
+
+static char*
+compute_base_path (const char *base_dir,
+ const char *path,
+ gboolean junk_paths,
+ gboolean can_junk_paths)
+{
+ int base_dir_len = strlen (base_dir);
+ int path_len = strlen (path);
+ const char *base_path;
+ char *name_end;
+ char *new_path;
+
+ if (junk_paths) {
+ if (can_junk_paths)
+ new_path = g_strdup (_g_path_get_file_name (path));
+ else
+ new_path = g_strdup (path);
+
+ /*debug (DEBUG_INFO, "%s, %s --> %s\n", base_dir, path, new_path);*/
+
+ return new_path;
+ }
+
+ if (path_len <= base_dir_len)
+ return NULL;
+
+ base_path = path + base_dir_len;
+ if (path[0] != '/')
+ base_path -= 1;
+ name_end = strchr (base_path, '/');
+
+ if (name_end == NULL)
+ new_path = g_strdup (path);
+ else {
+ int name_len = name_end - path;
+ new_path = g_strndup (path, name_len);
+ }
+
+ /*debug (DEBUG_INFO, "%s, %s --> %s\n", base_dir, path, new_path);*/
+
+ return new_path;
+}
+
+
+static GList*
+compute_list_base_path (const char *base_dir,
+ GList *filtered,
+ gboolean junk_paths,
+ gboolean can_junk_paths)
+{
+ GList *scan;
+ GList *list = NULL, *list_unique = NULL;
+ GList *last_inserted;
+
+ if (filtered == NULL)
+ return NULL;
+
+ for (scan = filtered; scan; scan = scan->next) {
+ const char *path = scan->data;
+ char *new_path;
+
+ new_path = compute_base_path (base_dir, path, junk_paths, can_junk_paths);
+ if (new_path != NULL)
+ list = g_list_prepend (list, new_path);
+ }
+
+ /* The above operation can create duplicates, we remove them here. */
+ list = g_list_sort (list, (GCompareFunc)strcmp);
+
+ last_inserted = NULL;
+ for (scan = list; scan; scan = scan->next) {
+ const char *path = scan->data;
+
+ if (last_inserted != NULL) {
+ const char *last_path = (const char*)last_inserted->data;
+ if (strcmp (last_path, path) == 0) {
+ g_free (scan->data);
+ continue;
+ }
+ }
+
+ last_inserted = scan;
+ list_unique = g_list_prepend (list_unique, scan->data);
+ }
+
+ g_list_free (list);
+
+ return list_unique;
+}
+
+
+static gboolean
+file_list_contains_files_in_this_dir (GList *file_list,
+ const char *dirname)
+{
+ GList *scan;
+
+ for (scan = file_list; scan; scan = scan->next) {
+ char *filename = scan->data;
+
+ if (_g_path_is_parent_of (dirname, filename))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+static GList*
+remove_files_contained_in_this_dir (GList *file_list,
+ GList *dir_pointer)
{
- fr_command_progress (comm, -1.0);
+ char *dirname = dir_pointer->data;
+ int dirname_l = strlen (dirname);
+ GList *scan;
- comm->action = FR_ACTION_EXTRACTING_FILES;
- fr_process_set_out_line_func (FR_COMMAND (comm)->process, NULL, NULL);
- fr_process_set_err_line_func (FR_COMMAND (comm)->process, NULL, NULL);
+ for (scan = dir_pointer->next; scan; /* empty */) {
+ char *filename = scan->data;
- FR_COMMAND_GET_CLASS (G_OBJECT (comm))->extract (comm,
- from_file,
- file_list,
- dest_dir,
- overwrite,
- skip_older,
- junk_paths);
+ if (strncmp (dirname, filename, dirname_l) != 0)
+ break;
+
+ if (_g_path_is_parent_of (dirname, filename)) {
+ GList *next = scan->next;
+
+ file_list = g_list_remove_link (file_list, scan);
+ g_list_free (scan);
+
+ scan = next;
+ }
+ else
+ scan = scan->next;
+ }
+
+ return file_list;
}
-void
-fr_command_test (FrCommand *comm)
+static void
+_fr_command_extract (FrCommand *self,
+ GList *file_list,
+ const char *destination,
+ const char *base_dir,
+ gboolean skip_older,
+ gboolean overwrite,
+ gboolean junk_paths,
+ const char *password)
{
- fr_command_progress (comm, -1.0);
+ FrArchive *archive = FR_ARCHIVE (self);
+ GList *filtered;
+ GList *scan;
+ gboolean extract_all;
+ gboolean use_base_dir;
+ gboolean all_options_supported;
+ gboolean move_to_dest_dir;
+ gboolean file_list_created = FALSE;
+
+ g_return_if_fail (archive != NULL);
+
+ fr_archive_set_stoppable (archive, TRUE);
+ g_object_set (self, "filename", self->priv->local_copy, NULL);
+
+ /* if a command supports all the requested options use
+ * fr_command_extract_files directly. */
+
+ use_base_dir = ! ((base_dir == NULL)
+ || (strcmp (base_dir, "") == 0)
+ || (strcmp (base_dir, "/") == 0));
+
+ all_options_supported = (! use_base_dir
+ && ! (! overwrite && ! archive->propExtractCanAvoidOverwrite)
+ && ! (skip_older && ! archive->propExtractCanSkipOlder)
+ && ! (junk_paths && ! archive->propExtractCanJunkPaths));
+
+ extract_all = (file_list == NULL);
+ if (extract_all && (! all_options_supported || ! archive->propCanExtractAll)) {
+ int i;
+
+ file_list = NULL;
+ for (i = 0; i < archive->files->len; i++) {
+ FileData *fdata = g_ptr_array_index (archive->files, i);
+ file_list = g_list_prepend (file_list, g_strdup (fdata->original_path));
+ }
+ file_list_created = TRUE;
+ }
+
+ if (extract_all && (file_list == NULL))
+ fr_archive_set_n_files (archive, archive->files->len);
+ else
+ fr_archive_set_n_files (archive, g_list_length (file_list));
+
+ if (all_options_supported) {
+ gboolean created_filtered_list = FALSE;
+
+ if (! extract_all && ! archive->propCanExtractNonEmptyFolders) {
+ created_filtered_list = TRUE;
+ filtered = g_list_copy (file_list);
+ filtered = g_list_sort (filtered, (GCompareFunc) strcmp);
+ for (scan = filtered; scan; scan = scan->next)
+ filtered = remove_files_contained_in_this_dir (filtered, scan);
+ }
+ else
+ filtered = file_list;
+
+ if (! (created_filtered_list && (filtered == NULL)))
+ extract_from_archive (self,
+ filtered,
+ destination,
+ overwrite,
+ skip_older,
+ junk_paths,
+ password);
+
+ if (created_filtered_list && (filtered != NULL))
+ g_list_free (filtered);
+
+ if (file_list_created)
+ _g_string_list_free (file_list);
+
+ return;
+ }
+
+ /* .. else we have to implement the unsupported options. */
+
+ move_to_dest_dir = (use_base_dir
+ || ((junk_paths
+ && ! archive->propExtractCanJunkPaths)));
- comm->action = FR_ACTION_TESTING_ARCHIVE;
- fr_process_set_out_line_func (FR_COMMAND (comm)->process, NULL, NULL);
- fr_process_set_err_line_func (FR_COMMAND (comm)->process, NULL, NULL);
+ if (extract_all && ! file_list_created) {
+ int i;
- FR_COMMAND_GET_CLASS (G_OBJECT (comm))->test (comm);
+ file_list = NULL;
+ for (i = 0; i < archive->files->len; i++) {
+ FileData *fdata = g_ptr_array_index (archive->files, i);
+ file_list = g_list_prepend (file_list, g_strdup (fdata->original_path));
+ }
+
+ file_list_created = TRUE;
+ }
+
+ filtered = NULL;
+ for (scan = file_list; scan; scan = scan->next) {
+ FileData *fdata;
+ char *archive_list_filename = scan->data;
+ char dest_filename[4096];
+ const char *filename;
+
+ fdata = find_file_in_archive (archive, archive_list_filename);
+
+ if (fdata == NULL)
+ continue;
+
+ if (! archive->propCanExtractNonEmptyFolders
+ && fdata->dir
+ && file_list_contains_files_in_this_dir (file_list, archive_list_filename))
+ continue;
+
+ /* get the destination file path. */
+
+ if (! junk_paths)
+ filename = archive_list_filename;
+ else
+ filename = _g_path_get_file_name (archive_list_filename);
+
+ if ((destination[strlen (destination) - 1] == '/')
+ || (filename[0] == '/'))
+ sprintf (dest_filename, "%s%s", destination, filename);
+ else
+ sprintf (dest_filename, "%s/%s", destination, filename);
+
+ /*debug (DEBUG_INFO, "-> %s\n", dest_filename);*/
+
+ /**/
+
+ if (! archive->propExtractCanSkipOlder
+ && skip_older
+ && g_file_test (dest_filename, G_FILE_TEST_EXISTS)
+ && (fdata->modified < _g_path_get_file_mtime (dest_filename)))
+ continue;
+
+ if (! archive->propExtractCanAvoidOverwrite
+ && ! overwrite
+ && g_file_test (dest_filename, G_FILE_TEST_EXISTS))
+ continue;
+
+ filtered = g_list_prepend (filtered, fdata->original_path);
+ }
+
+ if (filtered == NULL) {
+ /* all files got filtered, do nothing. */
+ debug (DEBUG_INFO, "All files got filtered, nothing to do.\n");
+
+ if (extract_all)
+ _g_string_list_free (file_list);
+ return;
+ }
+
+ if (move_to_dest_dir) {
+ char *temp_dir;
+
+ temp_dir = _g_path_get_temp_work_dir (destination);
+ extract_from_archive (self,
+ filtered,
+ temp_dir,
+ overwrite,
+ skip_older,
+ junk_paths,
+ password);
+
+ if (use_base_dir) {
+ GList *tmp_list = compute_list_base_path (base_dir, filtered, junk_paths, archive->propExtractCanJunkPaths);
+ g_list_free (filtered);
+ filtered = tmp_list;
+ }
+
+ move_files_in_chunks (self,
+ filtered,
+ temp_dir,
+ destination,
+ overwrite);
+
+ /* remove the temp dir. */
+
+ fr_process_begin_command (self->process, "rm");
+ fr_process_add_arg (self->process, "-rf");
+ fr_process_add_arg (self->process, temp_dir);
+ fr_process_end_command (self->process);
+
+ g_free (temp_dir);
+ }
+ else
+ extract_from_archive (self,
+ filtered,
+ destination,
+ overwrite,
+ skip_older,
+ junk_paths,
+ password);
+
+ if (filtered != NULL)
+ g_list_free (filtered);
+ if (file_list_created)
+ _g_string_list_free (file_list);
}
-void
-fr_command_uncompress (FrCommand *comm)
+/* -- _fr_command_extract_to_local -- */
+
+
+static void
+process_ready_for_extract_to_local_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
{
- fr_command_progress (comm, -1.0);
- FR_COMMAND_GET_CLASS (G_OBJECT (comm))->uncompress (comm);
+ XferData *xfer_data = user_data;
+ FrError *error = NULL;
+ FrCommand *self = FR_COMMAND (xfer_data->archive);
+
+ if (! fr_process_execute_finish (FR_PROCESS (source_object), result, &error))
+ g_simple_async_result_set_from_error (xfer_data->result, error->gerror);
+
+ if (error == NULL) {
+ if (self->priv->remote_extraction) {
+ copy_extracted_files_to_destination (xfer_data->archive,
+ xfer_data->result,
+ xfer_data->cancellable);
+ xfer_data_free (xfer_data);
+ return;
+ }
+ else if (xfer_data->archive->extract_here)
+ move_here (xfer_data->archive, xfer_data->cancellable);
+ }
+ else {
+ /* if an error occurred during extraction remove the
+ * temp extraction dir, if used. */
+ g_print ("action_performed: ERROR!\n");
+
+ if ((self->priv->remote_extraction) && (self->priv->temp_extraction_dir != NULL)) {
+ _g_path_remove_directory (self->priv->temp_extraction_dir);
+ g_free (self->priv->temp_extraction_dir);
+ self->priv->temp_extraction_dir = NULL;
+ }
+
+ if (xfer_data->archive->extract_here)
+ _g_uri_remove_directory (fr_archive_get_last_extraction_destination (xfer_data->archive));
+ }
+
+ g_simple_async_result_complete_in_idle (xfer_data->result);
+
+ fr_error_free (error);
+ xfer_data_free (xfer_data);
}
-void
-fr_command_recompress (FrCommand *comm)
+static void
+_fr_command_extract_to_local (FrCommand *self,
+ GList *file_list,
+ const char *destination,
+ const char *base_dir,
+ gboolean skip_older,
+ gboolean overwrite,
+ gboolean junk_paths,
+ const char *password,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
- fr_command_progress (comm, -1.0);
- FR_COMMAND_GET_CLASS (G_OBJECT (comm))->recompress (comm);
+ XferData *xfer_data;
+
+ fr_process_clear (self->process);
+ _fr_command_extract (self,
+ file_list,
+ destination,
+ base_dir,
+ skip_older,
+ overwrite,
+ junk_paths,
+ password);
+
+ xfer_data = g_new0 (XferData, 1);
+ xfer_data->archive = _g_object_ref (self);
+ xfer_data->cancellable = _g_object_ref (cancellable);
+ xfer_data->result = g_simple_async_result_new (G_OBJECT (self),
+ callback,
+ user_data,
+ fr_archive_extract);
+ fr_process_execute (self->process,
+ cancellable,
+ process_ready_for_extract_to_local_cb,
+ xfer_data);
}
-const char **
-fr_command_get_mime_types (FrCommand *comm)
+static void
+fr_command_extract_files (FrArchive *base,
+ GList *file_list,
+ const char *destination,
+ const char *base_dir,
+ gboolean skip_older,
+ gboolean overwrite,
+ gboolean junk_paths,
+ const char *password,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
- return FR_COMMAND_GET_CLASS (G_OBJECT (comm))->get_mime_types (comm);
+ FrCommand *self = FR_COMMAND (base);
+
+ g_free (self->priv->temp_extraction_dir);
+ self->priv->temp_extraction_dir = NULL;
+
+ self->priv->remote_extraction = ! _g_uri_is_local (destination);
+ if (self->priv->remote_extraction) {
+ self->priv->temp_extraction_dir = _g_path_get_temp_work_dir (NULL);
+ _fr_command_extract_to_local (self,
+ file_list,
+ self->priv->temp_extraction_dir,
+ base_dir,
+ skip_older,
+ overwrite,
+ junk_paths,
+ password,
+ cancellable,
+ callback,
+ user_data);
+ }
+ else {
+ char *local_destination;
+
+ local_destination = g_filename_from_uri (destination, NULL, NULL);
+ _fr_command_extract_to_local (self,
+ file_list,
+ local_destination,
+ base_dir,
+ skip_older,
+ overwrite,
+ junk_paths,
+ password,
+ cancellable,
+ callback,
+ user_data);
+ g_free (local_destination);
+ }
}
-void
-fr_command_update_capabilities (FrCommand *comm)
+/* -- fr_command_test_integrity -- */
+
+
+static void
+process_ready_for_test_integrity (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
{
- comm->capabilities = fr_command_get_capabilities (comm, comm->mime_type, TRUE);
+ XferData *xfer_data = user_data;
+ FrError *error = NULL;
+
+ if (! fr_process_execute_finish (FR_PROCESS (source_object), result, &error))
+ g_simple_async_result_set_from_error (xfer_data->result, error->gerror);
+
+ g_simple_async_result_complete_in_idle (xfer_data->result);
+
+ fr_error_free (error);
+ xfer_data_free (xfer_data);
}
-FrCommandCap
-fr_command_get_capabilities (FrCommand *comm,
- const char *mime_type,
- gboolean check_command)
+static void
+fr_command_test_integrity (FrArchive *archive,
+ const char *password,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
- return FR_COMMAND_GET_CLASS (G_OBJECT (comm))->get_capabilities (comm, mime_type, check_command);
+ FrCommand *self = FR_COMMAND (archive);
+ XferData *xfer_data;
+
+ fr_archive_set_stoppable (archive, TRUE);
+ g_object_set (self,
+ "filename", self->priv->local_copy,
+ "password", password,
+ NULL);
+ fr_archive_set_n_files (archive, 0);
+
+ fr_process_clear (self->process);
+ fr_command_test (self);
+
+ xfer_data = g_new0 (XferData, 1);
+ xfer_data->archive = _g_object_ref (self);
+ xfer_data->cancellable = _g_object_ref (cancellable);
+ xfer_data->result = g_simple_async_result_new (G_OBJECT (self),
+ callback,
+ user_data,
+ fr_archive_test);
+
+ fr_process_execute (self->process,
+ cancellable,
+ process_ready_for_test_integrity,
+ xfer_data);
}
-gboolean
-fr_command_is_capable_of (FrCommand *comm,
- FrCommandCaps requested_capabilities)
+/* -- fr_command_rename -- */
+
+
+static void
+fr_command_rename (FrArchive *archive,
+ GList *file_list,
+ const char *old_name,
+ const char *new_name,
+ const char *current_dir,
+ gboolean is_dir,
+ gboolean dir_in_archive,
+ const char *original_path,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
- return (((comm->capabilities ^ requested_capabilities) & requested_capabilities) == 0);
+ /* FIXME: libarchive */
+#if 0
+ FrCommand *self = FR_COMMAND (archive);
+ char *tmp_dir;
+ gboolean added_dir;
+ char *new_dirname;
+ GList *new_file_list;
+ GList *scan;
+ GError *error = NULL;
+
+ g_object_set (self, "filename", self->priv->local_copy, NULL);
+ tmp_dir = _g_path_get_temp_work_dir (NULL);
+
+ fr_process_clear (self->process);
+
+ _fr_command_extract (self,
+ file_list,
+ tmp_dir,
+ NULL,
+ FALSE,
+ TRUE,
+ FALSE,
+ archive->password);
+
+ /* temporarily add the dir to rename to the list if it's stored in the
+ * archive, this way it will be removed from the archive... */
+ added_dir = FALSE;
+ if (is_dir && dir_in_archive && ! g_list_find_custom (file_list, original_path, (GCompareFunc) strcmp)) {
+ file_list = g_list_prepend (file_list, g_strdup (original_path));
+ added_dir = TRUE;
+ }
+
+ _fr_command_remove (self, file_list, archive->compression);
+
+ /* ...and remove it from the list again */
+ if (added_dir) {
+ GList *tmp;
+
+ tmp = file_list;
+ file_list = g_list_remove_link (file_list, tmp);
+
+ g_free (tmp->data);
+ g_list_free (tmp);
+ }
+
+ /* rename the files. */
+
+ new_dirname = g_build_filename (current_dir + 1, new_name, "/", NULL);
+ new_file_list = NULL;
+ if (rdata->is_dir) {
+ char *old_path;
+ char *new_path;
+
+ old_path = g_build_filename (tmp_dir, current_dir, old_name, NULL);
+ new_path = g_build_filename (tmp_dir, current_dir, new_name, NULL);
+
+ fr_process_begin_command (self->process, "mv");
+ fr_process_add_arg (self->process, "-f");
+ fr_process_add_arg (self->process, old_path);
+ fr_process_add_arg (self->process, new_path);
+ fr_process_end_command (self->process);
+
+ g_free (old_path);
+ g_free (new_path);
+ }
+
+ for (scan = file_list; scan; scan = scan->next) {
+ const char *current_dir_relative = current_dir + 1;
+ const char *filename = (char*) scan->data;
+ char *old_path = NULL, *common = NULL, *new_path = NULL;
+ char *new_filename;
+
+ old_path = g_build_filename (tmp_dir, filename, NULL);
+
+ if (strlen (filename) > (strlen (current_dir) + strlen (old_name)))
+ common = g_strdup (filename + strlen (current_dir) + strlen (old_name));
+ new_path = g_build_filename (tmp_dir, current_dir, new_name, common, NULL);
+
+ if (! rdata->is_dir) {
+ fr_process_begin_command (self->process, "mv");
+ fr_process_add_arg (self->process, "-f");
+ fr_process_add_arg (self->process, old_path);
+ fr_process_add_arg (self->process, new_path);
+ fr_process_end_command (self->process);
+ }
+
+ new_filename = g_build_filename (current_dir_relative, new_name, common, NULL);
+ new_file_list = g_list_prepend (new_file_list, new_filename);
+
+ g_free (old_path);
+ g_free (common);
+ g_free (new_path);
+ }
+ new_file_list = g_list_reverse (new_file_list);
+
+ /* FIXME: this is broken for tar archives.
+ if (is_dir && dir_in_archive && ! g_list_find_custom (new_file_list, new_dirname, (GCompareFunc) strcmp))
+ new_file_list = g_list_prepend (new_file_list, g_build_filename (rdata->current_dir + 1, rdata->new_name, NULL));
+ */
+
+ if (! _fr_command_add (self,
+ new_file_list,
+ tmp_dir,
+ NULL,
+ FALSE,
+ FALSE,
+ archive->password,
+ archive->encrypt_header,
+ archive->compression,
+ archive->volume_size,
+ &error))
+ {
+ /* FIXME */
+ }
+
+ g_free (new_dirname);
+ _g_string_list_free (new_file_list);
+
+ /* remove the tmp dir */
+
+ fr_process_begin_command (self->process, "rm");
+ fr_process_set_working_dir (self->process, g_get_tmp_dir ());
+ fr_process_set_sticky (self->process, TRUE);
+ fr_process_add_arg (self->process, "-rf");
+ fr_process_add_arg (self->process, tmp_dir);
+ fr_process_end_command (self->process);
+
+ fr_process_start (self->process);
+
+ g_free (tmp_dir);
+#endif
}
-const char *
-fr_command_get_packages (FrCommand *comm,
- const char *mime_type)
+/* -- fr_command_paste_clipboard -- */
+
+
+static void
+process_ready_for_paste_clipboard (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
{
- return FR_COMMAND_GET_CLASS (G_OBJECT (comm))->get_packages (comm, mime_type);
+ XferData *xfer_data = user_data;
+ FrError *error = NULL;
+
+ if (! fr_process_execute_finish (FR_PROCESS (source_object), result, &error))
+ g_simple_async_result_set_from_error (xfer_data->result, error->gerror);
+
+ g_simple_async_result_complete_in_idle (xfer_data->result);
+
+ fr_error_free (error);
+ xfer_data_free (xfer_data);
}
-/* fraction == -1 means : I don't known how much time the current operation
- * will take, the dialog will display this info pulsing
- * the progress bar.
- * fraction in [0.0, 1.0] means the amount of work, in percentage,
- * accomplished.
- */
-void
-fr_command_progress (FrCommand *comm,
- double fraction)
+static void
+fr_command_paste_clipboard (FrArchive *archive,
+ char *archive_uri,
+ char *password,
+ gboolean encrypt_header,
+ FrCompression compression,
+ guint volume_size,
+ FrClipboardOp op,
+ char *base_dir,
+ GList *files,
+ char *tmp_dir,
+ char *current_dir,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ FrCommand *command = FR_COMMAND (archive);
+ const char *current_dir_relative = current_dir + 1;
+ GList *scan;
+ GList *new_file_list = NULL;
+ GError *error = NULL;
+ XferData *xfer_data;
+
+ fr_process_clear (command->process);
+
+ for (scan = files; scan; scan = scan->next) {
+ const char *old_name = (char*) scan->data;
+ char *new_name = g_build_filename (current_dir_relative, old_name + strlen (base_dir) - 1, NULL);
+
+ /* skip folders */
+
+ if ((strcmp (old_name, new_name) != 0)
+ && (old_name[strlen (old_name) - 1] != '/'))
+ {
+ fr_process_begin_command (command->process, "mv");
+ fr_process_set_working_dir (command->process, tmp_dir);
+ fr_process_add_arg (command->process, "-f");
+ if (old_name[0] == '/')
+ old_name = old_name + 1;
+ fr_process_add_arg (command->process, old_name);
+ fr_process_add_arg (command->process, new_name);
+ fr_process_end_command (command->process);
+ }
+
+ new_file_list = g_list_prepend (new_file_list, new_name);
+ }
+
+ if (! _fr_command_add (command,
+ new_file_list,
+ tmp_dir,
+ NULL,
+ FALSE,
+ FALSE,
+ password,
+ encrypt_header,
+ compression,
+ volume_size,
+ &error))
+ {
+ GSimpleAsyncResult *result;
+
+ result = g_simple_async_result_new (G_OBJECT (command),
+ callback,
+ user_data,
+ fr_archive_paste_clipboard);
+
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (result, error);
+ g_error_free (error);
+ }
+
+ g_simple_async_result_complete_in_idle (result);
+
+ g_object_unref (result);
+ return;
+ }
+
+ _g_string_list_free (new_file_list);
+
+ /* remove the tmp dir */
+
+ fr_process_begin_command (command->process, "rm");
+ fr_process_set_working_dir (command->process, g_get_tmp_dir ());
+ fr_process_set_sticky (command->process, TRUE);
+ fr_process_add_arg (command->process, "-rf");
+ fr_process_add_arg (command->process, tmp_dir);
+ fr_process_end_command (command->process);
+
+ /**/
+
+ xfer_data = g_new0 (XferData, 1);
+ xfer_data->archive = _g_object_ref (command);
+ xfer_data->cancellable = _g_object_ref (cancellable);
+ xfer_data->result = g_simple_async_result_new (G_OBJECT (command),
+ callback,
+ user_data,
+ fr_archive_paste_clipboard);
+
+ fr_process_execute (command->process,
+ cancellable,
+ process_ready_for_paste_clipboard,
+ xfer_data);
+}
+
+
+/* -- fr_command_add_dropped_items -- */
+
+
+static gboolean
+all_files_in_same_dir (GList *list)
+{
+ gboolean same_dir = TRUE;
+ char *first_basedir;
+ GList *scan;
+
+ if (list == NULL)
+ return FALSE;
+
+ first_basedir = _g_path_remove_level (list->data);
+ if (first_basedir == NULL)
+ return TRUE;
+
+ for (scan = list->next; scan; scan = scan->next) {
+ char *path = scan->data;
+ char *basedir;
+
+ basedir = _g_path_remove_level (path);
+ if (basedir == NULL) {
+ same_dir = FALSE;
+ break;
+ }
+
+ if (strcmp (first_basedir, basedir) != 0) {
+ same_dir = FALSE;
+ g_free (basedir);
+ break;
+ }
+ g_free (basedir);
+ }
+ g_free (first_basedir);
+
+ return same_dir;
+}
+
+
+static void
+add_dropped_items (DroppedItemsData *data)
+{
+ FrCommand *self = data->command;
+ GList *list = data->item_list;
+ GList *scan;
+
+ if (list == NULL) {
+ GSimpleAsyncResult *result;
+
+ result = g_simple_async_result_new (G_OBJECT (data->command),
+ data->callback,
+ data->user_data,
+ fr_archive_add_dropped_items);
+ g_simple_async_result_complete_in_idle (result);
+
+ dropped_items_data_free (self->priv->dropped_items_data);
+ self->priv->dropped_items_data = NULL;
+ return;
+ }
+
+ /* if all files/dirs are in the same directory call fr_archive_add_items... */
+
+ if (all_files_in_same_dir (list)) {
+ char *first_base_dir;
+
+ first_base_dir = _g_path_remove_level (list->data);
+ fr_archive_add_items (FR_ARCHIVE (self),
+ list,
+ first_base_dir,
+ data->dest_dir,
+ data->update,
+ data->password,
+ data->encrypt_header,
+ data->compression,
+ data->volume_size,
+ data->cancellable,
+ data->callback,
+ data->user_data);
+
+ g_free (first_base_dir);
+ dropped_items_data_free (self->priv->dropped_items_data);
+ self->priv->dropped_items_data = NULL;
+
+ return;
+ }
+
+ /* ...else add a directory at a time. */
+
+ for (scan = list; scan; scan = scan->next) {
+ char *path = scan->data;
+ char *base_dir;
+
+ if (! _g_uri_query_is_dir (path))
+ continue;
+
+ data->item_list = g_list_remove_link (list, scan);
+ if (data->item_list != NULL)
+ self->priv->continue_adding_dropped_items = TRUE;
+ base_dir = _g_path_remove_level (path);
+
+ fr_archive_add_directory (FR_ARCHIVE (self),
+ _g_path_get_file_name (path),
+ base_dir,
+ data->dest_dir,
+ data->update,
+ data->password,
+ data->encrypt_header,
+ data->compression,
+ data->volume_size,
+ data->cancellable,
+ data->callback,
+ data->user_data);
+
+ g_free (base_dir);
+ g_free (path);
+
+ return;
+ }
+
+ /* if all files are in the same directory call fr_archive_add_files. */
+
+ if (all_files_in_same_dir (list)) {
+ char *first_basedir;
+ GList *only_names_list = NULL;
+
+ first_basedir = _g_path_remove_level (list->data);
+
+ for (scan = list; scan; scan = scan->next) {
+ char *name;
+
+ name = g_uri_unescape_string (_g_path_get_file_name (scan->data), NULL);
+ only_names_list = g_list_prepend (only_names_list, name);
+ }
+
+ fr_archive_add_files (FR_ARCHIVE (self),
+ only_names_list,
+ first_basedir,
+ data->dest_dir,
+ data->update,
+ FALSE,
+ data->password,
+ data->encrypt_header,
+ data->compression,
+ data->volume_size,
+ data->cancellable,
+ data->callback,
+ data->user_data);
+
+ _g_string_list_free (only_names_list);
+ g_free (first_basedir);
+
+ return;
+ }
+
+ /* ...else call fr_command_add for each file. This is needed to add
+ * files without path info. FIXME: doesn't work with remote files. */
+
+ fr_archive_set_stoppable (FR_ARCHIVE (self), TRUE);
+ self->creating_archive = ! g_file_query_exists (self->priv->local_copy, data->cancellable);
+ g_object_set (self,
+ "filename", self->priv->local_copy,
+ "password", data->password,
+ "encrypt_header", data->encrypt_header,
+ "compression", data->compression,
+ "volume_size", data->volume_size,
+ NULL);
+
+ fr_process_clear (self->process);
+ fr_command_uncompress (self);
+ for (scan = list; scan; scan = scan->next) {
+ char *fullpath = scan->data;
+ char *basedir;
+ GList *singleton;
+
+ basedir = _g_path_remove_level (fullpath);
+ singleton = g_list_prepend (NULL, (char*)_g_path_get_file_name (fullpath));
+ fr_command_add (self,
+ NULL,
+ singleton,
+ basedir,
+ data->update,
+ FALSE);
+ g_list_free (singleton);
+ g_free (basedir);
+ }
+ fr_command_recompress (self);
+ fr_process_execute (self->process,
+ data->cancellable,
+ data->callback,
+ data->user_data);
+
+ _g_string_list_free (data->item_list);
+ data->item_list = NULL;
+}
+
+
+static void
+fr_command_add_dropped_items (FrArchive *archive,
+ GList *item_list,
+ const char *base_dir,
+ const char *dest_dir,
+ gboolean update,
+ const char *password,
+ gboolean encrypt_header,
+ FrCompression compression,
+ guint volume_size,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ FrCommand *self = FR_COMMAND (archive);
+
+ if (self->priv->dropped_items_data != NULL)
+ dropped_items_data_free (self->priv->dropped_items_data);
+ self->priv->dropped_items_data = dropped_items_data_new (self,
+ item_list,
+ base_dir,
+ dest_dir,
+ update,
+ password,
+ encrypt_header,
+ compression,
+ volume_size,
+ cancellable,
+ callback,
+ user_data);
+ add_dropped_items (self->priv->dropped_items_data);
+}
+
+
+/* -- fr_command_update_open_files -- */
+
+
+static void
+process_ready_for_update_open_files (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
{
- g_signal_emit (G_OBJECT (comm),
- fr_command_signals[PROGRESS],
- 0,
- fraction);
+ XferData *xfer_data = user_data;
+ FrError *error = NULL;
+
+ if (! fr_process_execute_finish (FR_PROCESS (source_object), result, &error))
+ g_simple_async_result_set_from_error (xfer_data->result, error->gerror);
+
+ g_simple_async_result_complete_in_idle (xfer_data->result);
+
+ fr_error_free (error);
+ xfer_data_free (xfer_data);
}
-void
-fr_command_message (FrCommand *comm,
- const char *msg)
+static void
+fr_command_update_open_files (FrArchive *archive,
+ GList *file_list,
+ GList *dir_list,
+ const char *password,
+ gboolean encrypt_header,
+ FrCompression compression,
+ guint volume_size,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
- g_signal_emit (G_OBJECT (comm),
- fr_command_signals[MESSAGE],
- 0,
- msg);
+ FrCommand *self = FR_COMMAND (archive);
+ GList *scan_file, *scan_dir;
+ XferData *xfer_data;
+
+ fr_process_clear (self->process);
+
+ for (scan_file = file_list, scan_dir = dir_list;
+ scan_file && scan_dir;
+ scan_file = scan_file->next, scan_dir = scan_dir->next)
+ {
+ char *filepath = scan_file->data;
+ char *dirpath = scan_dir->data;
+ GList *local_file_list;
+
+ local_file_list = g_list_append (NULL, filepath);
+ _fr_command_add (self,
+ local_file_list,
+ dirpath,
+ "/",
+ FALSE,
+ FALSE,
+ password,
+ encrypt_header,
+ compression,
+ volume_size,
+ NULL);
+
+ g_list_free (local_file_list);
+ }
+
+ /**/
+
+ xfer_data = g_new0 (XferData, 1);
+ xfer_data->archive = _g_object_ref (self);
+ xfer_data->cancellable = _g_object_ref (cancellable);
+ xfer_data->result = g_simple_async_result_new (G_OBJECT (self),
+ callback,
+ user_data,
+ fr_archive_update_open_files);
+
+ fr_process_execute (self->process,
+ cancellable,
+ process_ready_for_update_open_files,
+ xfer_data);
}
-void
-fr_command_working_archive (FrCommand *comm,
- const char *archive_name)
+static void
+fr_command_class_init (FrCommandClass *klass)
{
- g_signal_emit (G_OBJECT (comm),
- fr_command_signals[WORKING_ARCHIVE],
- 0,
- archive_name);
+ GObjectClass *gobject_class;
+ FrArchiveClass *archive_class;
+
+ fr_command_parent_class = g_type_class_peek_parent (klass);
+ g_type_class_add_private (klass, sizeof (FrCommandPrivate));
+
+ gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->set_property = fr_command_set_property;
+ gobject_class->get_property = fr_command_get_property;
+ gobject_class->finalize = fr_command_finalize;
+
+ archive_class = FR_ARCHIVE_CLASS (klass);
+ archive_class->load = fr_command_load;
+ archive_class->add_files = fr_command_add_files;
+ archive_class->remove_files = fr_command_remove_files;
+ archive_class->extract_files = fr_command_extract_files;
+ archive_class->test_integrity = fr_command_test_integrity;
+ archive_class->rename = fr_command_rename;
+ archive_class->paste_clipboard = fr_command_paste_clipboard;
+ archive_class->add_dropped_items = fr_command_add_dropped_items;
+ archive_class->update_open_files = fr_command_update_open_files;
+
+ /* properties */
+
+ g_object_class_install_property (gobject_class,
+ PROP_PROCESS,
+ g_param_spec_object ("process",
+ "Process",
+ "The process object used by the command",
+ FR_TYPE_PROCESS,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class,
+ PROP_FILENAME,
+ g_param_spec_object ("filename",
+ "Filename",
+ "The path of the archive the command will use (can be different from local_copy)",
+ G_TYPE_FILE,
+ G_PARAM_READWRITE));
}
-void
-fr_command_set_n_files (FrCommand *comm,
- int n_files)
+static GFile *
+get_local_copy_for_file (GFile *remote_file)
{
- comm->n_files = n_files;
- comm->n_file = 0;
+ char *temp_dir;
+ GFile *local_copy = NULL;
+
+ temp_dir = _g_path_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;
}
-void
-fr_command_add_file (FrCommand *comm,
- FileData *fdata)
+static void
+archive_file_changed_cb (GObject *object,
+ GParamSpec *spec,
+ gpointer user_data)
{
- file_data_update_content_type (fdata);
- g_ptr_array_add (comm->files, fdata);
- if (! fdata->dir)
- comm->n_regular_files++;
+ FrCommand *self = user_data;
+ GFile *file;
+
+ /* FIXME: if multi_volume... */
+
+ if ((self->priv->local_copy != NULL) && self->priv->is_remote) {
+ GFile *temp_folder;
+ GError *err = NULL;
+
+ g_file_delete (self->priv->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 (self->priv->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 (self->priv->local_copy != NULL) {
+ g_object_unref (self->priv->local_copy);
+ self->priv->local_copy = NULL;
+ }
+
+ file = fr_archive_get_file (FR_ARCHIVE (object));
+ self->priv->is_remote = ! g_file_has_uri_scheme (file, "file");
+ if (self->priv->is_remote)
+ self->priv->local_copy = get_local_copy_for_file (file);
+ else
+ self->priv->local_copy = g_file_dup (file);
+
+ _fr_command_set_filename_from_file (self, self->priv->local_copy);
}
-void
-fr_command_set_mime_type (FrCommand *comm,
- const char *mime_type)
+static void
+fr_command_init (FrCommand *self)
{
- FR_COMMAND_GET_CLASS (G_OBJECT (comm))->set_mime_type (comm, mime_type);
+ FrProcess *process;
+
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, FR_TYPE_COMMAND, FrCommandPrivate);
+
+ self->priv->local_copy = NULL;
+ self->priv->is_remote = FALSE;
+ self->priv->temp_dir = NULL;
+ self->priv->continue_adding_dropped_items = FALSE;
+ self->priv->dropped_items_data = NULL;
+ self->priv->temp_extraction_dir = NULL;
+ self->priv->remote_extraction = FALSE;
+
+ self->filename = NULL;
+ self->e_filename = NULL;
+ self->creating_archive = FALSE;
+
+ process = fr_process_new ();
+ _fr_command_set_process (self, process);
+ g_object_unref (process);
+
+ g_signal_connect (self,
+ "notify::file",
+ G_CALLBACK (archive_file_changed_cb),
+ self);
}
-void
-fr_command_handle_error (FrCommand *comm,
- FrProcError *error)
+GList *
+fr_command_get_last_output (FrCommand *self)
{
- FR_COMMAND_GET_CLASS (G_OBJECT (comm))->handle_error (comm, error);
+ return (self->process->err.raw != NULL) ? self->process->err.raw : self->process->out.raw;
}
diff --git a/src/fr-command.h b/src/fr-command.h
index 4c2c511..9ba01e9 100644
--- a/src/fr-command.h
+++ b/src/fr-command.h
@@ -3,7 +3,7 @@
/*
* File-Roller
*
- * Copyright (C) 2001 The Free Software Foundation, Inc.
+ * Copyright (C) 2012 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,7 +23,7 @@
#define FR_COMMAND_H
#include <glib.h>
-#include "file-data.h"
+#include "fr-archive.h"
#include "fr-process.h"
#define PACKAGES(x) (x)
@@ -35,273 +35,53 @@
#define FR_IS_COMMAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), FR_TYPE_COMMAND))
#define FR_COMMAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), FR_TYPE_COMMAND, FrCommandClass))
-typedef struct _FrCommand FrCommand;
-typedef struct _FrCommandClass FrCommandClass;
+typedef struct _FrCommand FrCommand;
+typedef struct _FrCommandClass FrCommandClass;
+typedef struct _FrCommandPrivate FrCommandPrivate;
-typedef enum {
- FR_ACTION_NONE,
- FR_ACTION_CREATING_NEW_ARCHIVE,
- FR_ACTION_LOADING_ARCHIVE, /* loading the archive from a remote location */
- FR_ACTION_LISTING_CONTENT, /* listing the content of the archive */
- FR_ACTION_DELETING_FILES, /* deleting files from the archive */
- FR_ACTION_TESTING_ARCHIVE, /* testing the archive integrity */
- FR_ACTION_GETTING_FILE_LIST, /* getting the file list (when fr_archive_add_with_wildcard or
- fr_archive_add_directory are used, we need to scan a directory
- and collect the files to add to the archive, this
- may require some time to complete, so the operation
- is asynchronous) */
- FR_ACTION_COPYING_FILES_FROM_REMOTE, /* copying files to be added to the archive from a remote location */
- FR_ACTION_ADDING_FILES, /* adding files to an archive */
- FR_ACTION_EXTRACTING_FILES, /* extracting files */
- FR_ACTION_COPYING_FILES_TO_REMOTE, /* copying extracted files to a remote location */
- FR_ACTION_CREATING_ARCHIVE, /* creating a local archive */
- FR_ACTION_SAVING_REMOTE_ARCHIVE /* copying the archive to a remote location */
-} FrAction;
+struct _FrCommand {
+ FrArchive __parent;
+ FrCommandPrivate *priv;
-#ifdef DEBUG
-extern char *action_names[];
-#endif
+ /*<protected, read only>*/
-struct _FrCommand
-{
- GObject __parent;
-
- /*<public, read only>*/
-
- GPtrArray *files; /* Array of FileData* */
- int n_regular_files;
- FrProcess *process; /* the process object used to execute
- * commands. */
- char *filename; /* archive file path. */
- char *e_filename; /* escaped archive filename. */
- const char *mime_type;
- gboolean multi_volume;
-
- /*<protected>*/
-
- /* options */
-
- char *password;
- gboolean encrypt_header : 1;
- FrCompression compression;
- guint volume_size;
- gboolean creating_archive;
-
- /* command features. */
-
- /* propAddCanReplace:
- *
- * TRUE if the command can overwrite a file in the archive.
- */
- guint propAddCanReplace : 1;
-
- /* propAddCanReplace:
- *
- * TRUE if the command can overwrite a file in the archive if older
- * then the file on disk.
- */
- guint propAddCanUpdate : 1;
-
- /* propAddCanStoreFolders:
- *
- * TRUE if the command can store folder entries inside the archive.
- */
- guint propAddCanStoreFolders : 1;
-
- /* propExtractCanAvoidOverwrite:
- *
- * TRUE if the command can avoid to overwrite the files on disk.
- */
- guint propExtractCanAvoidOverwrite : 1;
-
- /* propExtractCanSkipOlder:
- *
- * TRUE if the command can avoid to overwrite a file on disk when it is
- * newer than the file in the archive.
- */
- guint propExtractCanSkipOlder : 1;
-
- /* propExtractCanJunkPaths:
- *
- * TRUE if the command can extract the files in the current folder
- * without recreating the directory structure.
- */
- guint propExtractCanJunkPaths : 1;
-
- /* propPassword:
- *
- * TRUE if the command can use passwords for adding or extracting files.
- */
- guint propPassword : 1;
-
- /* propTest:
- *
- * TRUE if the command can test the archive integrity.
- */
- guint propTest : 1;
-
- /* propCanExtractAll:
- *
- * TRUE if the command extract all the files when no file is specified.
- */
- guint propCanExtractAll : 1;
-
- /* propCanDeleteNonEmptyFolders:
- *
- * is used to overcome an issue with tar, that deletes only the folder
- * entry in the archive instead of deleting the folder content
- * recursively.
- */
- guint propCanDeleteNonEmptyFolders : 1;
-
- /* propCanExtractNonEmptyFolders:
- *
- * is used to overcome an issue with tar. For example if
- * the content of a tar archive is
- *
- * readme.txt
- * doc/
- * doc/page1.html
- * doc/page2.html
- *
- * and we want to extract the content of the doc folder, the command:
- *
- * tar -xf archive.tar doc doc/page1.html doc/page2.html
- *
- * gives an error.
- * To fix the issue we have to remove the files inside the doc
- * folder from the command line, getting the following command:
- *
- * tar -xf archive.tar doc
- */
- guint propCanExtractNonEmptyFolders : 1;
-
- /* propListFromFile:
- *
- * if TRUE the command has an option to read the file list from a file
- */
- guint propListFromFile : 1;
-
- /*<private>*/
-
- FrCommandCaps capabilities;
- FrAction action; /* current action. */
- gboolean fake_load; /* if TRUE does nothing when the list
- * operation is invoked. */
-
- /* progress data */
-
- int n_file;
- int n_files;
+ FrProcess *process; /* the process object used to execute
+ * commands. */
+ char *filename; /* local archive file path. */
+ char *e_filename; /* escaped filename. */
+ gboolean creating_archive;
};
-struct _FrCommandClass
-{
- GObjectClass __parent_class;
+struct _FrCommandClass {
+ FrArchiveClass __parent_class;
/*<virtual functions>*/
- void (*list) (FrCommand *comm);
- void (*add) (FrCommand *comm,
- const char *from_file,
- GList *file_list,
- const char *base_dir,
- gboolean update,
- gboolean recursive);
- void (*delete) (FrCommand *comm,
- const char *from_file,
- GList *file_list);
- void (*extract) (FrCommand *comm,
- const char *from_file,
- GList *file_list,
- const char *dest_dir,
- gboolean overwrite,
- gboolean skip_older,
- gboolean junk_paths);
- void (*test) (FrCommand *comm);
- void (*uncompress) (FrCommand *comm);
- void (*recompress) (FrCommand *comm);
- void (*handle_error) (FrCommand *comm,
- FrProcError *error);
- const char ** (*get_mime_types) (FrCommand *comm);
- FrCommandCap (*get_capabilities) (FrCommand *comm,
- const char *mime_type,
- gboolean check_command);
- void (*set_mime_type) (FrCommand *comm,
- const char *mime_type);
- const char * (*get_packages) (FrCommand *comm,
- const char *mime_type);
-
- /*<signals>*/
-
- void (*start) (FrCommand *comm,
- FrAction action);
- void (*done) (FrCommand *comm,
- FrAction action,
- FrProcError *error);
- void (*progress) (FrCommand *comm,
- double fraction);
- void (*message) (FrCommand *comm,
- const char *msg);
- void (*working_archive) (FrCommand *comm,
- const char *filename);
+ gboolean (*list) (FrCommand *comm);
+ void (*add) (FrCommand *comm,
+ const char *from_file,
+ GList *file_list,
+ const char *base_dir,
+ gboolean update,
+ gboolean recursive);
+ void (*delete) (FrCommand *comm,
+ const char *from_file,
+ GList *file_list);
+ void (*extract) (FrCommand *comm,
+ const char *from_file,
+ GList *file_list,
+ const char *dest_dir,
+ gboolean overwrite,
+ gboolean skip_older,
+ gboolean junk_paths);
+ void (*test) (FrCommand *comm);
+ void (*uncompress) (FrCommand *comm);
+ void (*recompress) (FrCommand *comm);
+ void (*handle_error) (FrCommand *comm,
+ FrError *error);
};
-GType fr_command_get_type (void);
-void fr_command_set_file (FrCommand *comm,
- GFile *file);
-void fr_command_set_multi_volume (FrCommand *comm,
- GFile *file);
-void fr_command_list (FrCommand *comm);
-void fr_command_add (FrCommand *comm,
- const char *from_file,
- GList *file_list,
- const char *base_dir,
- gboolean update,
- gboolean recursive);
-void fr_command_delete (FrCommand *comm,
- const char *from_file,
- GList *file_list);
-void fr_command_extract (FrCommand *comm,
- const char *from_file,
- GList *file_list,
- const char *dest_dir,
- gboolean overwrite,
- gboolean skip_older,
- gboolean junk_paths);
-void fr_command_test (FrCommand *comm);
-void fr_command_uncompress (FrCommand *comm);
-void fr_command_recompress (FrCommand *comm);
-gboolean fr_command_is_capable_of (FrCommand *comm,
- FrCommandCaps capabilities);
-const char ** fr_command_get_mime_types (FrCommand *comm);
-void fr_command_update_capabilities (FrCommand *comm);
-FrCommandCap fr_command_get_capabilities (FrCommand *comm,
- const char *mime_type,
- gboolean check_command);
-void fr_command_set_mime_type (FrCommand *comm,
- const char *mime_type);
-gboolean fr_command_is_capable_of (FrCommand *comm,
- FrCommandCaps capabilities);
-const char * fr_command_get_packages (FrCommand *comm,
- const char *mime_type);
-
-/* protected functions */
-
-void fr_command_progress (FrCommand *comm,
- double fraction);
-void fr_command_message (FrCommand *comm,
- const char *msg);
-void fr_command_working_archive (FrCommand *comm,
- const char *archive_name);
-void fr_command_set_n_files (FrCommand *comm,
- int n_files);
-void fr_command_add_file (FrCommand *comm,
- FileData *fdata);
-
-/* private functions */
-
-void fr_command_handle_error (FrCommand *comm,
- FrProcError *error);
+GType fr_command_get_type (void);
+GList * fr_command_get_last_output (FrCommand *command);
#endif /* FR_COMMAND_H */
diff --git a/src/fr-error.c b/src/fr-error.c
index 6c4d0f5..530f3e5 100644
--- a/src/fr-error.c
+++ b/src/fr-error.c
@@ -23,13 +23,80 @@
#include "fr-error.h"
-GQuark
+GQuark
fr_error_quark (void)
{
static GQuark quark;
-
+
if (!quark)
- quark = g_quark_from_static_string ("file-roller-error");
-
+ quark = g_quark_from_static_string ("FrError");
+
return quark;
}
+
+
+G_DEFINE_BOXED_TYPE (FrError,
+ fr_error,
+ fr_error_copy,
+ fr_error_free);
+
+
+FrError *
+fr_error_new (FrErrorType type,
+ int status,
+ GError *gerror)
+{
+ FrError *error;
+
+ error = g_new0 (FrError, 1);
+ fr_error_set (error, type, status, gerror);
+
+ return error;
+}
+
+
+FrError *
+fr_error_copy (FrError *error)
+{
+ if (error != NULL)
+ return fr_error_new (error->type, error->status, error->gerror);
+ else
+ return NULL;
+}
+
+
+void
+fr_error_free (FrError *error)
+{
+ if (error == NULL)
+ return;
+ g_clear_error (&error->gerror);
+ g_free (error);
+}
+
+
+void
+fr_error_set (FrError *error,
+ FrErrorType type,
+ int status,
+ GError *gerror)
+{
+ error->type = type;
+ error->status = status;
+ if (gerror != error->gerror) {
+ g_clear_error (&error->gerror);
+ if (gerror != NULL)
+ error->gerror = g_error_copy (gerror);
+ }
+}
+
+
+void
+fr_clear_error (FrError **error)
+{
+ if ((error == NULL) || (*error == NULL))
+ return;
+
+ fr_error_free (*error);
+ *error = NULL;
+}
diff --git a/src/fr-error.h b/src/fr-error.h
index 1614954..39dc2ed 100644
--- a/src/fr-error.h
+++ b/src/fr-error.h
@@ -23,9 +23,43 @@
#define __FR_ERROR_H__
#include <glib.h>
+#include <glib-object.h>
#define FR_ERROR fr_error_quark ()
-GQuark fr_error_quark (void);
+#define FR_TYPE_ERROR (fr_error_get_type ())
+typedef enum { /*< skip >*/
+ FR_ERROR_NONE,
+ FR_ERROR_GENERIC,
+ FR_ERROR_COMMAND_ERROR,
+ FR_ERROR_COMMAND_NOT_FOUND,
+ FR_ERROR_EXITED_ABNORMALLY,
+ FR_ERROR_SPAWN,
+ FR_ERROR_STOPPED,
+ FR_ERROR_ASK_PASSWORD,
+ FR_ERROR_MISSING_VOLUME,
+ FR_ERROR_IO_CHANNEL,
+ FR_ERROR_BAD_CHARSET,
+ FR_ERROR_UNSUPPORTED_FORMAT
+} FrErrorType;
+
+typedef struct {
+ GError *gerror;
+ FrErrorType type;
+ int status;
+} FrError;
+
+GQuark fr_error_quark (void);
+GType fr_error_get_type (void);
+FrError * fr_error_new (FrErrorType type,
+ int status,
+ GError *gerror);
+FrError * fr_error_copy (FrError *error);
+void fr_error_free (FrError *error);
+void fr_error_set (FrError *error,
+ FrErrorType type,
+ int status,
+ GError *gerror);
+void fr_clear_error (FrError **error);
#endif /* __FR_ERROR_H__ */
diff --git a/src/fr-init.c b/src/fr-init.c
index 08a33ee..1dfd3d1 100644
--- a/src/fr-init.c
+++ b/src/fr-init.c
@@ -167,7 +167,7 @@ FrExtensionType file_ext_type[] = {
GList *CommandList;
gint ForceDirectoryCreation;
GHashTable *ProgramsCache;
-GPtrArray *Registered_Commands;
+GPtrArray *Registered_Archives;
int single_file_save_type[64];
int save_type[64];
int open_type[64];
@@ -200,25 +200,25 @@ migrate_options_directory (void)
}
-/* -- FrRegisteredCommand -- */
+/* -- FrRegisteredArchive -- */
-static FrRegisteredCommand *
-fr_registered_command_new (GType command_type)
+static FrRegisteredArchive *
+fr_registered_archive_new (GType command_type)
{
- FrRegisteredCommand *reg_com;
- FrCommand *command;
+ FrRegisteredArchive *reg_com;
+ FrArchive *archive;
const char **mime_types;
int i;
- reg_com = g_new0 (FrRegisteredCommand, 1);
+ reg_com = g_new0 (FrRegisteredArchive, 1);
reg_com->ref = 1;
reg_com->type = command_type;
reg_com->caps = g_ptr_array_new ();
reg_com->packages = g_ptr_array_new ();
- command = (FrCommand*) g_object_new (reg_com->type, NULL);
- mime_types = fr_command_get_mime_types (command);
+ archive = (FrArchive*) g_object_new (reg_com->type, NULL);
+ mime_types = fr_archive_get_mime_types (archive);
for (i = 0; mime_types[i] != NULL; i++) {
const char *mime_type;
FrMimeTypeCap *cap;
@@ -228,31 +228,31 @@ fr_registered_command_new (GType command_type)
cap = g_new0 (FrMimeTypeCap, 1);
cap->mime_type = mime_type;
- cap->current_capabilities = fr_command_get_capabilities (command, mime_type, TRUE);
- cap->potential_capabilities = fr_command_get_capabilities (command, mime_type, FALSE);
+ cap->current_capabilities = fr_archive_get_capabilities (archive, mime_type, TRUE);
+ cap->potential_capabilities = fr_archive_get_capabilities (archive, mime_type, FALSE);
g_ptr_array_add (reg_com->caps, cap);
packages = g_new0 (FrMimeTypePackages, 1);
packages->mime_type = mime_type;
- packages->packages = fr_command_get_packages (command, mime_type);
+ packages->packages = fr_archive_get_packages (archive, mime_type);
g_ptr_array_add (reg_com->packages, packages);
}
- g_object_unref (command);
+ g_object_unref (archive);
return reg_com;
}
G_GNUC_UNUSED static void
-fr_registered_command_ref (FrRegisteredCommand *reg_com)
+fr_registered_command_ref (FrRegisteredArchive *reg_com)
{
reg_com->ref++;
}
static void
-fr_registered_command_unref (FrRegisteredCommand *reg_com)
+fr_registered_archive_unref (FrRegisteredArchive *reg_com)
{
if (--(reg_com->ref) != 0)
return;
@@ -263,8 +263,8 @@ fr_registered_command_unref (FrRegisteredCommand *reg_com)
}
-static FrCommandCaps
-fr_registered_command_get_capabilities (FrRegisteredCommand *reg_com,
+static FrArchiveCaps
+fr_registered_archive_get_capabilities (FrRegisteredArchive *reg_com,
const char *mime_type)
{
int i;
@@ -277,18 +277,18 @@ fr_registered_command_get_capabilities (FrRegisteredCommand *reg_com,
return cap->current_capabilities;
}
- return FR_COMMAND_CAN_DO_NOTHING;
+ return FR_ARCHIVE_CAN_DO_NOTHING;
}
-static FrCommandCaps
-fr_registered_command_get_potential_capabilities (FrRegisteredCommand *reg_com,
+static FrArchiveCaps
+fr_registered_archive_get_potential_capabilities (FrRegisteredArchive *reg_com,
const char *mime_type)
{
int i;
if (mime_type == NULL)
- return FR_COMMAND_CAN_DO_NOTHING;
+ return FR_ARCHIVE_CAN_DO_NOTHING;
for (i = 0; i < reg_com->caps->len; i++) {
FrMimeTypeCap *cap;
@@ -298,31 +298,31 @@ fr_registered_command_get_potential_capabilities (FrRegisteredCommand *reg_com,
return cap->potential_capabilities;
}
- return FR_COMMAND_CAN_DO_NOTHING;
+ return FR_ARCHIVE_CAN_DO_NOTHING;
}
static void
-register_command (GType command_type)
+register_archive (GType command_type)
{
- if (Registered_Commands == NULL)
- Registered_Commands = g_ptr_array_sized_new (5);
- g_ptr_array_add (Registered_Commands, fr_registered_command_new (command_type));
+ if (Registered_Archives == NULL)
+ Registered_Archives = g_ptr_array_sized_new (5);
+ g_ptr_array_add (Registered_Archives, fr_registered_archive_new (command_type));
}
G_GNUC_UNUSED static gboolean
-unregister_command (GType command_type)
+unregister_archive (GType command_type)
{
int i;
- for (i = 0; i < Registered_Commands->len; i++) {
- FrRegisteredCommand *command;
+ for (i = 0; i < Registered_Archives->len; i++) {
+ FrRegisteredArchive *archive;
- command = g_ptr_array_index (Registered_Commands, i);
- if (command->type == command_type) {
- g_ptr_array_remove_index (Registered_Commands, i);
- fr_registered_command_unref (command);
+ archive = g_ptr_array_index (Registered_Archives, i);
+ if (archive->type == command_type) {
+ g_ptr_array_remove_index (Registered_Archives, i);
+ fr_registered_archive_unref (archive);
return TRUE;
}
}
@@ -332,53 +332,57 @@ unregister_command (GType command_type)
static void
-register_commands (void)
+register_archives (void)
{
/* The order here is important. Commands registered earlier have higher
* priority. However commands that can read and write a file format
* have higher priority over commands that can only read the same
* format, regardless of the registration order. */
- register_command (FR_TYPE_COMMAND_TAR);
- register_command (FR_TYPE_COMMAND_CFILE);
- register_command (FR_TYPE_COMMAND_7Z);
- register_command (FR_TYPE_COMMAND_DPKG);
-
- register_command (FR_TYPE_COMMAND_ACE);
- register_command (FR_TYPE_COMMAND_ALZ);
- register_command (FR_TYPE_COMMAND_AR);
- register_command (FR_TYPE_COMMAND_ARJ);
- register_command (FR_TYPE_COMMAND_CPIO);
- register_command (FR_TYPE_COMMAND_ISO);
- register_command (FR_TYPE_COMMAND_JAR);
- register_command (FR_TYPE_COMMAND_LHA);
- register_command (FR_TYPE_COMMAND_RAR);
- register_command (FR_TYPE_COMMAND_RPM);
- register_command (FR_TYPE_COMMAND_UNSTUFF);
- register_command (FR_TYPE_COMMAND_ZIP);
- register_command (FR_TYPE_COMMAND_LRZIP);
- register_command (FR_TYPE_COMMAND_ZOO);
+#if HAVE_LIBARCHIVE
+ register_archive (FR_TYPE_LIBARCHIVE);
+#endif
+
+ register_archive (FR_TYPE_COMMAND_TAR);
+ register_archive (FR_TYPE_COMMAND_CFILE);
+ register_archive (FR_TYPE_COMMAND_7Z);
+ register_archive (FR_TYPE_COMMAND_DPKG);
+
+ register_archive (FR_TYPE_COMMAND_ACE);
+ register_archive (FR_TYPE_COMMAND_ALZ);
+ register_archive (FR_TYPE_COMMAND_AR);
+ register_archive (FR_TYPE_COMMAND_ARJ);
+ register_archive (FR_TYPE_COMMAND_CPIO);
+ register_archive (FR_TYPE_COMMAND_ISO);
+ register_archive (FR_TYPE_COMMAND_JAR);
+ register_archive (FR_TYPE_COMMAND_LHA);
+ register_archive (FR_TYPE_COMMAND_RAR);
+ register_archive (FR_TYPE_COMMAND_RPM);
+ register_archive (FR_TYPE_COMMAND_UNSTUFF);
+ register_archive (FR_TYPE_COMMAND_ZIP);
+ register_archive (FR_TYPE_COMMAND_LRZIP);
+ register_archive (FR_TYPE_COMMAND_ZOO);
#if HAVE_JSON_GLIB
- register_command (FR_TYPE_COMMAND_UNARCHIVER);
+ register_archive (FR_TYPE_COMMAND_UNARCHIVER);
#endif
}
GType
-get_command_type_from_mime_type (const char *mime_type,
- FrCommandCaps requested_capabilities)
+get_archive_type_from_mime_type (const char *mime_type,
+ FrArchiveCaps requested_capabilities)
{
int i;
if (mime_type == NULL)
return 0;
- for (i = 0; i < Registered_Commands->len; i++) {
- FrRegisteredCommand *command;
- FrCommandCaps capabilities;
+ for (i = 0; i < Registered_Archives->len; i++) {
+ FrRegisteredArchive *command;
+ FrArchiveCaps capabilities;
- command = g_ptr_array_index (Registered_Commands, i);
- capabilities = fr_registered_command_get_capabilities (command, mime_type);
+ command = g_ptr_array_index (Registered_Archives, i);
+ capabilities = fr_registered_archive_get_capabilities (command, mime_type);
/* the command must support all the requested capabilities */
if (((capabilities ^ requested_capabilities) & requested_capabilities) == 0)
@@ -390,21 +394,21 @@ get_command_type_from_mime_type (const char *mime_type,
GType
-get_preferred_command_for_mime_type (const char *mime_type,
- FrCommandCaps requested_capabilities)
+get_preferred_archive_for_mime_type (const char *mime_type,
+ FrArchiveCaps requested_capabilities)
{
int i;
- for (i = 0; i < Registered_Commands->len; i++) {
- FrRegisteredCommand *command;
- FrCommandCaps capabilities;
+ for (i = 0; i < Registered_Archives->len; i++) {
+ FrRegisteredArchive *archive;
+ FrArchiveCaps capabilities;
- command = g_ptr_array_index (Registered_Commands, i);
- capabilities = fr_registered_command_get_potential_capabilities (command, mime_type);
+ archive = g_ptr_array_index (Registered_Archives, i);
+ capabilities = fr_registered_archive_get_potential_capabilities (archive, mime_type);
- /* the command must support all the requested capabilities */
+ /* the archive must support all the requested capabilities */
if (((capabilities ^ requested_capabilities) & requested_capabilities) == 0)
- return command->type;
+ return archive->type;
}
return 0;
@@ -412,27 +416,27 @@ get_preferred_command_for_mime_type (const char *mime_type,
void
-update_registered_commands_capabilities (void)
+update_registered_archives_capabilities (void)
{
int i;
g_hash_table_remove_all (ProgramsCache);
- for (i = 0; i < Registered_Commands->len; i++) {
- FrRegisteredCommand *reg_com;
- FrCommand *command;
+ for (i = 0; i < Registered_Archives->len; i++) {
+ FrRegisteredArchive *reg_com;
+ FrArchive *archive;
int j;
- reg_com = g_ptr_array_index (Registered_Commands, i);
- command = (FrCommand*) g_object_new (reg_com->type, NULL);
+ reg_com = g_ptr_array_index (Registered_Archives, i);
+ archive = g_object_new (reg_com->type, NULL);
for (j = 0; j < reg_com->caps->len; j++) {
FrMimeTypeCap *cap = g_ptr_array_index (reg_com->caps, j);
- cap->current_capabilities = fr_command_get_capabilities (command, cap->mime_type, TRUE);
- cap->potential_capabilities = fr_command_get_capabilities (command, cap->mime_type, FALSE);
+ cap->current_capabilities = fr_archive_get_capabilities (archive, cap->mime_type, TRUE);
+ cap->potential_capabilities = fr_archive_get_capabilities (archive, cap->mime_type, FALSE);
}
- g_object_unref (command);
+ g_object_unref (archive);
}
}
@@ -562,11 +566,11 @@ compute_supported_archive_types (void)
int sf_i = 0, s_i = 0, o_i = 0, c_i = 0;
int i;
- for (i = 0; i < Registered_Commands->len; i++) {
- FrRegisteredCommand *reg_com;
+ for (i = 0; i < Registered_Archives->len; i++) {
+ FrRegisteredArchive *reg_com;
int j;
- reg_com = g_ptr_array_index (Registered_Commands, i);
+ reg_com = g_ptr_array_index (Registered_Archives, i);
for (j = 0; j < reg_com->caps->len; j++) {
FrMimeTypeCap *cap;
int idx;
@@ -578,12 +582,12 @@ compute_supported_archive_types (void)
continue;
}
mime_type_desc[idx].capabilities |= cap->current_capabilities;
- if (cap->current_capabilities & FR_COMMAND_CAN_READ)
+ if (cap->current_capabilities & FR_ARCHIVE_CAN_READ)
add_if_non_present (open_type, &o_i, idx);
- if (cap->current_capabilities & FR_COMMAND_CAN_WRITE) {
- if (cap->current_capabilities & FR_COMMAND_CAN_ARCHIVE_MANY_FILES) {
+ if (cap->current_capabilities & FR_ARCHIVE_CAN_WRITE) {
+ if (cap->current_capabilities & FR_ARCHIVE_CAN_STORE_MANY_FILES) {
add_if_non_present (save_type, &s_i, idx);
- if (cap->current_capabilities & FR_COMMAND_CAN_WRITE)
+ if (cap->current_capabilities & FR_ARCHIVE_CAN_WRITE)
add_if_non_present (create_type, &c_i, idx);
}
add_if_non_present (single_file_save_type, &sf_i, idx);
@@ -617,7 +621,7 @@ initialize_data (void)
PKG_DATA_DIR G_DIR_SEPARATOR_S "icons");
migrate_options_directory ();
- register_commands ();
+ register_archives ();
compute_supported_archive_types ();
fr_stock_init ();
}
diff --git a/src/fr-init.h b/src/fr-init.h
index 2639e70..e987dd0 100644
--- a/src/fr-init.h
+++ b/src/fr-init.h
@@ -46,7 +46,7 @@ typedef struct {
extern GList *CommandList;
extern gint ForceDirectoryCreation;
extern GHashTable *ProgramsCache;
-extern GPtrArray *Registered_Commands;
+extern GPtrArray *Registered_Archives;
extern FrMimeTypeDescription mime_type_desc[];
extern FrExtensionType file_ext_type[];
extern int single_file_save_type[]; /* File types that can be saved when
@@ -57,11 +57,11 @@ extern int save_type[]; /* File types that can be
extern int open_type[]; /* File types that can be opened. */
extern int create_type[]; /* File types that can be created. */
-GType get_command_type_from_mime_type (const char *mime_type,
- FrCommandCaps requested_capabilities);
-GType get_preferred_command_for_mime_type (const char *mime_type,
- FrCommandCaps requested_capabilities);
-void update_registered_commands_capabilities (void);
+GType get_archive_type_from_mime_type (const char *mime_type,
+ FrArchiveCaps requested_capabilities);
+GType get_preferred_archive_for_mime_type (const char *mime_type,
+ FrArchiveCaps requested_capabilities);
+void update_registered_archives_capabilities (void);
const char * get_mime_type_from_extension (const char *ext);
const char * get_archive_filename_extension (const char *uri);
int get_mime_type_index (const char *mime_type);
diff --git a/src/fr-process.c b/src/fr-process.c
index 2725e45..db427cc 100644
--- a/src/fr-process.c
+++ b/src/fr-process.c
@@ -3,7 +3,7 @@
/*
* File-Roller
*
- * Copyright (C) 2001, 2003, 2008 Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2003, 2008, 2012 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -30,27 +30,14 @@
#include <unistd.h>
#include <glib.h>
#include "file-utils.h"
-#include "fr-proc-error.h"
#include "fr-process.h"
-#include "fr-marshal.h"
#include "glib-utils.h"
#define REFRESH_RATE 20
#define BUFFER_SIZE 16384
-G_DEFINE_TYPE (FrProcess, fr_process, G_TYPE_OBJECT)
-
-
-enum {
- START,
- DONE,
- STICKY_ONLY,
- LAST_SIGNAL
-};
-
-
-static guint fr_process_signals[LAST_SIGNAL] = { 0 };
+/* -- FrCommandInfo -- */
typedef struct {
@@ -107,6 +94,9 @@ fr_command_info_free (FrCommandInfo *info)
}
+/* -- FrChannelData -- */
+
+
static void
fr_channel_data_init (FrChannelData *channel)
{
@@ -202,35 +192,78 @@ fr_channel_data_set_fd (FrChannelData *channel,
}
-const char *try_charsets[] = { "UTF-8", "ISO-8859-1", "WINDOW-1252" };
-int n_charsets = G_N_ELEMENTS (try_charsets);
+/* -- ExecData -- */
+
+
+typedef struct {
+ FrProcess *process;
+ GCancellable *cancellable;
+ GSimpleAsyncResult *result;
+ gulong cancel_id;
+ int error_command; /* command that caused an error. */
+ FrError *error;
+ FrError *first_error;
+ GList *first_error_stdout;
+ GList *first_error_stderr;
+} ExecuteData;
+
+
+static void
+execute_data_free (ExecuteData *exec_data)
+{
+ if (exec_data == NULL)
+ return;
+
+ if (exec_data->cancel_id != 0)
+ g_cancellable_disconnect (exec_data->cancellable, exec_data->cancel_id);
+
+ _g_object_unref (exec_data->process);
+ _g_object_unref (exec_data->cancellable);
+ _g_object_unref (exec_data->result);
+ fr_error_free (exec_data->error);
+ fr_error_free (exec_data->first_error);
+ _g_string_list_free (exec_data->first_error_stdout);
+ _g_string_list_free (exec_data->first_error_stderr);
+ g_free (exec_data);
+}
+
+
+/* -- FrProcess -- */
+
+
+G_DEFINE_TYPE (FrProcess, fr_process, G_TYPE_OBJECT)
+
+
+enum {
+ STICKY_ONLY,
+ LAST_SIGNAL
+};
+
+
+static guint fr_process_signals[LAST_SIGNAL] = { 0 };
+static const char *try_charsets[] = { "UTF-8", "ISO-8859-1", "WINDOW-1252" };
+static int n_charsets = G_N_ELEMENTS (try_charsets);
struct _FrProcessPrivate {
GPtrArray *comm; /* FrCommandInfo elements. */
gint n_comm; /* total number of commands */
- gint current_comm; /* currenlty editing command. */
+ gint current_comm; /* currently editing command. */
GPid command_pid;
guint check_timeout;
- FrProcError first_error;
- GList *first_error_stdout;
- GList *first_error_stderr;
-
gboolean running;
gboolean stopping;
gint current_command;
- gint error_command; /* command that coused an error. */
gboolean use_standard_locale;
gboolean sticky_only; /* whether to execute only sticky
* commands. */
int current_charset;
-};
-
-static void fr_process_stop_priv (FrProcess *process, gboolean emit_signal);
+ ExecuteData *exec_data;
+};
static void
@@ -243,21 +276,12 @@ fr_process_finalize (GObject *object)
process = FR_PROCESS (object);
- fr_process_stop_priv (process, FALSE);
+ execute_data_free (process->priv->exec_data);
fr_process_clear (process);
-
g_ptr_array_free (process->priv->comm, FALSE);
-
fr_channel_data_free (&process->out);
fr_channel_data_free (&process->err);
- g_clear_error (&process->error.gerror);
- g_clear_error (&process->priv->first_error.gerror);
- _g_string_list_free (process->priv->first_error_stdout);
- _g_string_list_free (process->priv->first_error_stderr);
-
- g_free (process->priv);
-
if (G_OBJECT_CLASS (fr_process_parent_class)->finalize)
G_OBJECT_CLASS (fr_process_parent_class)->finalize (object);
}
@@ -269,47 +293,26 @@ fr_process_class_init (FrProcessClass *klass)
GObjectClass *gobject_class;
fr_process_parent_class = g_type_class_peek_parent (klass);
+ g_type_class_add_private (klass, sizeof (FrProcessPrivate));
- fr_process_signals[START] =
- g_signal_new ("start",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (FrProcessClass, start),
- NULL, NULL,
- fr_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
- fr_process_signals[DONE] =
- g_signal_new ("done",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (FrProcessClass, done),
- NULL, NULL,
- fr_marshal_VOID__BOXED,
- G_TYPE_NONE, 1,
- FR_TYPE_PROC_ERROR);
fr_process_signals[STICKY_ONLY] =
g_signal_new ("sticky_only",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (FrProcessClass, sticky_only),
NULL, NULL,
- fr_marshal_VOID__VOID,
+ g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = fr_process_finalize;
-
- klass->start = NULL;
- klass->done = NULL;
}
static void
fr_process_init (FrProcess *process)
{
- process->priv = g_new0 (FrProcessPrivate, 1);
-
- process->term_on_stop = TRUE;
+ process->priv = G_TYPE_INSTANCE_GET_PRIVATE (process, FR_TYPE_PROCESS, FrProcessPrivate);
process->priv->comm = g_ptr_array_new ();
process->priv->n_comm = -1;
@@ -319,19 +322,14 @@ fr_process_init (FrProcess *process)
fr_channel_data_init (&process->out);
fr_channel_data_init (&process->err);
- process->error.gerror = NULL;
- process->priv->first_error.gerror = NULL;
- process->priv->first_error_stdout = NULL;
- process->priv->first_error_stderr = NULL;
-
process->priv->check_timeout = 0;
process->priv->running = FALSE;
process->priv->stopping = FALSE;
process->restart = FALSE;
process->priv->current_charset = -1;
-
process->priv->use_standard_locale = FALSE;
+ process->priv->exec_data = NULL;
}
@@ -343,6 +341,29 @@ fr_process_new (void)
void
+fr_process_clear (FrProcess *process)
+{
+ gint i;
+
+ g_return_if_fail (process != NULL);
+
+ for (i = 0; i <= process->priv->n_comm; i++) {
+ FrCommandInfo *info;
+
+ info = g_ptr_array_index (process->priv->comm, i);
+ fr_command_info_free (info);
+ g_ptr_array_index (process->priv->comm, i) = NULL;
+ }
+
+ for (i = 0; i <= process->priv->n_comm; i++)
+ g_ptr_array_remove_index_fast (process->priv->comm, 0);
+
+ process->priv->n_comm = -1;
+ process->priv->current_comm = -1;
+}
+
+
+void
fr_process_begin_command (FrProcess *process,
const char *arg)
{
@@ -562,25 +583,11 @@ fr_process_end_command (FrProcess *process)
void
-fr_process_clear (FrProcess *process)
+fr_process_use_standard_locale (FrProcess *process,
+ gboolean use_stand_locale)
{
- gint i;
-
g_return_if_fail (process != NULL);
-
- for (i = 0; i <= process->priv->n_comm; i++) {
- FrCommandInfo *info;
-
- info = g_ptr_array_index (process->priv->comm, i);
- fr_command_info_free (info);
- g_ptr_array_index (process->priv->comm, i) = NULL;
- }
-
- for (i = 0; i <= process->priv->n_comm; i++)
- g_ptr_array_remove_index_fast (process->priv->comm, 0);
-
- process->priv->n_comm = -1;
- process->priv->current_comm = -1;
+ process->priv->use_standard_locale = use_stand_locale;
}
@@ -608,178 +615,141 @@ fr_process_set_err_line_func (FrProcess *process,
}
-static gboolean check_child (gpointer data);
+/* fr_process_execute */
-static void
-child_setup (gpointer user_data)
+static gboolean
+command_is_sticky (FrProcess *process,
+ int i)
{
- FrProcess *process = user_data;
-
- if (process->priv->use_standard_locale)
- putenv ("LC_MESSAGES=C");
-
- /* detach from the tty */
-
- setsid ();
-
- /* create a process group to kill all the child processes when
- * canceling the operation. */
+ FrCommandInfo *info;
- setpgid (0, 0);
+ info = g_ptr_array_index (process->priv->comm, i);
+ return info->sticky;
}
-static const char *
-fr_process_get_charset (FrProcess *process)
+static void
+allow_sticky_processes_only (ExecuteData *exec_data)
{
- const char *charset = NULL;
+ FrProcess *process = exec_data->process;
- if (process->priv->current_charset >= 0)
- charset = try_charsets[process->priv->current_charset];
- else if (g_get_charset (&charset))
- charset = NULL;
+ if (! process->priv->sticky_only) {
+ /* Remember the first error. */
- return charset;
+ exec_data->error_command = process->priv->current_command;
+ exec_data->first_error = fr_error_copy (exec_data->error);
+ exec_data->first_error_stdout = g_list_reverse (_g_string_list_dup (process->out.raw));
+ exec_data->first_error_stderr = g_list_reverse (_g_string_list_dup (process->err.raw));
+ }
+
+ process->priv->sticky_only = TRUE;
+
+ if (! process->priv->stopping)
+ g_signal_emit (G_OBJECT (process),
+ fr_process_signals[STICKY_ONLY],
+ 0);
}
static void
-start_current_command (FrProcess *process)
+execute_cancelled_cb (GCancellable *cancellable,
+ gpointer user_data)
{
- FrCommandInfo *info;
- GList *scan;
- char **argv;
- int out_fd, err_fd;
- int i = 0;
+ ExecuteData *exec_data = user_data;
+ FrProcess *process = exec_data->process;
- debug (DEBUG_INFO, "%d/%d) ", process->priv->current_command, process->priv->n_comm);
+ g_cancellable_disconnect (exec_data->cancellable, exec_data->cancel_id);
+ exec_data->cancel_id = 0;
- info = g_ptr_array_index (process->priv->comm, process->priv->current_command);
+ if (! process->priv->running)
+ return;
- argv = g_new (char *, g_list_length (info->args) + 1);
- for (scan = info->args; scan; scan = scan->next)
- argv[i++] = scan->data;
- argv[i] = NULL;
+ if (process->priv->stopping)
+ return;
-#ifdef DEBUG
- {
- int j;
+ process->priv->stopping = TRUE;
+ exec_data->error = fr_error_new (FR_ERROR_STOPPED, 0, NULL);
- if (process->priv->use_standard_locale)
- g_print ("\tLC_MESSAGES=C\n");
+ if (command_is_sticky (process, process->priv->current_command))
+ allow_sticky_processes_only (exec_data);
- if (info->dir != NULL)
- g_print ("\tcd %s\n", info->dir);
+ else if (process->priv->command_pid > 0)
+ killpg (process->priv->command_pid, SIGTERM);
- g_print ("\t");
- for (j = 0; j < i; j++)
- g_print ("%s ", argv[j]);
- g_print ("\n");
- }
-#endif
+ else {
+ if (process->priv->check_timeout != 0) {
+ g_source_remove (process->priv->check_timeout);
+ process->priv->check_timeout = 0;
+ }
- if (info->begin_func != NULL)
- (*info->begin_func) (info->begin_data);
+ process->priv->command_pid = 0;
+ fr_channel_data_close_source (&process->out);
+ fr_channel_data_close_source (&process->err);
- if (! g_spawn_async_with_pipes (info->dir,
- argv,
- NULL,
- (G_SPAWN_LEAVE_DESCRIPTORS_OPEN
- | G_SPAWN_SEARCH_PATH
- | G_SPAWN_DO_NOT_REAP_CHILD),
- child_setup,
- process,
- &process->priv->command_pid,
- NULL,
- &out_fd,
- &err_fd,
- &process->error.gerror))
- {
- process->error.type = FR_PROC_ERROR_SPAWN;
- g_signal_emit (G_OBJECT (process),
- fr_process_signals[DONE],
- 0,
- &process->error);
- g_free (argv);
- return;
- }
+ process->priv->running = FALSE;
- g_free (argv);
+ g_simple_async_result_complete_in_idle (exec_data->result);
+ }
+}
- fr_channel_data_set_fd (&process->out, out_fd, fr_process_get_charset (process));
- fr_channel_data_set_fd (&process->err, err_fd, fr_process_get_charset (process));
- process->priv->check_timeout = g_timeout_add (REFRESH_RATE,
- check_child,
- process);
-}
+static void _fr_process_start (ExecuteData *exec_data);
-static gboolean
-command_is_sticky (FrProcess *process,
- int i)
+static void
+_fr_process_restart (ExecuteData *exec_data)
{
- FrCommandInfo *info;
-
- info = g_ptr_array_index (process->priv->comm, i);
- return info->sticky;
+ exec_data->process->restart = TRUE;
+ _fr_process_start (exec_data);
}
+static void execute_current_command (ExecuteData *exec_data);
+
+
static void
-allow_sticky_processes_only (FrProcess *process,
- gboolean emit_signal)
+child_setup (gpointer user_data)
{
- if (! process->priv->sticky_only) {
- /* Remember the first error. */
- process->priv->error_command = process->priv->current_command;
- process->priv->first_error.type = process->error.type;
- process->priv->first_error.status = process->error.status;
- g_clear_error (&process->priv->first_error.gerror);
- if (process->error.gerror != NULL)
- process->priv->first_error.gerror = g_error_copy (process->error.gerror);
-
- _g_string_list_free (process->priv->first_error_stdout);
- process->priv->first_error_stdout = g_list_reverse (_g_string_list_dup (process->out.raw));
-
- _g_string_list_free (process->priv->first_error_stderr);
- process->priv->first_error_stderr = g_list_reverse (_g_string_list_dup (process->err.raw));
- }
+ FrProcess *process = user_data;
- process->priv->sticky_only = TRUE;
- if (emit_signal)
- g_signal_emit (G_OBJECT (process),
- fr_process_signals[STICKY_ONLY],
- 0);
+ if (process->priv->use_standard_locale)
+ putenv ("LC_MESSAGES=C");
+
+ /* detach from the tty */
+
+ setsid ();
+
+ /* create a process group to kill all the child processes when
+ * canceling the operation. */
+
+ setpgid (0, 0);
}
-static void
-fr_process_set_error (FrProcess *process,
- FrProcErrorType type,
- int status,
- GError *gerror)
+static const char *
+_fr_process_get_charset (FrProcess *process)
{
- process->error.type = type;
- process->error.status = status;
- if (gerror != process->error.gerror) {
- g_clear_error (&process->error.gerror);
- if (gerror != NULL)
- process->error.gerror = g_error_copy (gerror);
- }
+ const char *charset = NULL;
+
+ if (process->priv->current_charset >= 0)
+ charset = try_charsets[process->priv->current_charset];
+ else if (g_get_charset (&charset))
+ charset = NULL;
+
+ return charset;
}
static gint
check_child (gpointer data)
{
- FrProcess *process = data;
- FrCommandInfo *info;
- pid_t pid;
- int status;
- gboolean continue_process;
- gboolean channel_error = FALSE;
+ ExecuteData *exec_data = data;
+ FrProcess *process = exec_data->process;
+ FrCommandInfo *info;
+ pid_t pid;
+ int status;
+ gboolean continue_process;
info = g_ptr_array_index (process->priv->comm, process->priv->current_command);
@@ -789,12 +759,10 @@ check_child (gpointer data)
process->priv->check_timeout = 0;
if (fr_channel_data_read (&process->out) == G_IO_STATUS_ERROR) {
- fr_process_set_error (process, FR_PROC_ERROR_IO_CHANNEL, 0, process->out.error);
- channel_error = TRUE;
+ exec_data->error = fr_error_new (FR_ERROR_IO_CHANNEL, 0, process->out.error);
}
else if (fr_channel_data_read (&process->err) == G_IO_STATUS_ERROR) {
- fr_process_set_error (process, FR_PROC_ERROR_IO_CHANNEL, 0, process->err.error);
- channel_error = TRUE;
+ exec_data->error = fr_error_new (FR_ERROR_IO_CHANNEL, 0, process->err.error);
}
else {
pid = waitpid (process->priv->command_pid, &status, WNOHANG);
@@ -802,41 +770,36 @@ check_child (gpointer data)
/* Add check again. */
process->priv->check_timeout = g_timeout_add (REFRESH_RATE,
check_child,
- process);
+ exec_data);
return FALSE;
}
}
if (info->ignore_error) {
- process->error.type = FR_PROC_ERROR_NONE;
+ fr_clear_error (&exec_data->error);
debug (DEBUG_INFO, "[ignore error]\n");
}
- else if (! channel_error && (process->error.type != FR_PROC_ERROR_STOPPED)) {
+ else if (exec_data->error == NULL) {
if (WIFEXITED (status)) {
- if (WEXITSTATUS (status) == 0)
- process->error.type = FR_PROC_ERROR_NONE;
- else if (WEXITSTATUS (status) == 255)
- process->error.type = FR_PROC_ERROR_COMMAND_NOT_FOUND;
- else {
- process->error.type = FR_PROC_ERROR_COMMAND_ERROR;
- process->error.status = WEXITSTATUS (status);
+ if (WEXITSTATUS (status) == 255) {
+ exec_data->error = fr_error_new (FR_ERROR_COMMAND_NOT_FOUND, 0, NULL);
+ }
+ else if (WEXITSTATUS (status) != 0) {
+ exec_data->error = fr_error_new (FR_ERROR_COMMAND_ERROR, WEXITSTATUS (status), NULL);
}
}
else {
- process->error.type = FR_PROC_ERROR_EXITED_ABNORMALLY;
- process->error.status = 255;
+ exec_data->error = fr_error_new (FR_ERROR_EXITED_ABNORMALLY, 255, NULL);
}
}
process->priv->command_pid = 0;
- if (fr_channel_data_flush (&process->out) == G_IO_STATUS_ERROR) {
- fr_process_set_error (process, FR_PROC_ERROR_IO_CHANNEL, 0, process->out.error);
- channel_error = TRUE;
- }
- else if (fr_channel_data_flush (&process->err) == G_IO_STATUS_ERROR) {
- fr_process_set_error (process, FR_PROC_ERROR_IO_CHANNEL, 0, process->err.error);
- channel_error = TRUE;
+ if (exec_data->error == NULL) {
+ if (fr_channel_data_flush (&process->out) == G_IO_STATUS_ERROR)
+ exec_data->error = fr_error_new (FR_ERROR_IO_CHANNEL, 0, process->out.error);
+ else if (fr_channel_data_flush (&process->err) == G_IO_STATUS_ERROR)
+ exec_data->error = fr_error_new (FR_ERROR_IO_CHANNEL, 0, process->err.error);
}
if (info->end_func != NULL)
@@ -844,32 +807,30 @@ check_child (gpointer data)
/**/
- if (channel_error
- && (process->error.type == FR_PROC_ERROR_IO_CHANNEL)
- && g_error_matches (process->error.gerror, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE))
+ if ((exec_data->error != NULL)
+ && (exec_data->error->type == FR_ERROR_IO_CHANNEL)
+ && g_error_matches (exec_data->error->gerror, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE))
{
if (process->priv->current_charset < n_charsets - 1) {
/* try with another charset */
process->priv->current_charset++;
- process->priv->running = FALSE;
- process->restart = TRUE;
- fr_process_start (process);
+ _fr_process_restart (exec_data);
return FALSE;
}
- /*fr_process_set_error (process, FR_PROC_ERROR_NONE, 0, NULL);*/
- fr_process_set_error (process, FR_PROC_ERROR_BAD_CHARSET, 0, process->error.gerror);
+ fr_error_free (exec_data->error);
+ exec_data->error = fr_error_new (FR_ERROR_BAD_CHARSET, 0, exec_data->error->gerror);
}
/* Check whether to continue or stop the process */
continue_process = TRUE;
if (info->continue_func != NULL)
- continue_process = (*info->continue_func) (info->continue_data);
+ continue_process = (*info->continue_func) (&exec_data->error, info->continue_data);
- /* Execute next command. */
+ /* Execute the next command. */
if (continue_process) {
- if (process->error.type != FR_PROC_ERROR_NONE) {
- allow_sticky_processes_only (process, TRUE);
+ if (exec_data->error != NULL) {
+ allow_sticky_processes_only (exec_data);
#ifdef DEBUG
{
GList *scan;
@@ -884,14 +845,15 @@ check_child (gpointer data)
if (process->priv->sticky_only) {
do {
process->priv->current_command++;
- } while ((process->priv->current_command <= process->priv->n_comm)
- && ! command_is_sticky (process, process->priv->current_command));
+ }
+ while ((process->priv->current_command <= process->priv->n_comm)
+ && ! command_is_sticky (process, process->priv->current_command));
}
else
process->priv->current_command++;
if (process->priv->current_command <= process->priv->n_comm) {
- start_current_command (process);
+ execute_current_command (exec_data);
return FALSE;
}
}
@@ -912,122 +874,214 @@ check_child (gpointer data)
if (process->priv->sticky_only) {
/* Restore the first error. */
- fr_process_set_error (process,
- process->priv->first_error.type,
- process->priv->first_error.status,
- process->priv->first_error.gerror);
+ fr_error_free (exec_data->error);
+ exec_data->error = fr_error_copy (exec_data->first_error);
/* Restore the first error output as well. */
_g_string_list_free (process->out.raw);
- process->out.raw = process->priv->first_error_stdout;
- process->priv->first_error_stdout = NULL;
+ process->out.raw = exec_data->first_error_stdout;
+ exec_data->first_error_stdout = NULL;
_g_string_list_free (process->err.raw);
- process->err.raw = process->priv->first_error_stderr;
- process->priv->first_error_stderr = NULL;
+ process->err.raw = exec_data->first_error_stderr;
+ exec_data->first_error_stderr = NULL;
}
- g_signal_emit (G_OBJECT (process),
- fr_process_signals[DONE],
- 0,
- &process->error);
+ g_simple_async_result_complete_in_idle (exec_data->result);
return FALSE;
}
-void
-fr_process_use_standard_locale (FrProcess *process,
- gboolean use_stand_locale)
+static void
+execute_current_command (ExecuteData *exec_data)
{
- g_return_if_fail (process != NULL);
- process->priv->use_standard_locale = use_stand_locale;
+ FrProcess *process = exec_data->process;
+ FrCommandInfo *info;
+ GList *scan;
+ char **argv;
+ int out_fd, err_fd;
+ int i = 0;
+ GError *error;
+
+ debug (DEBUG_INFO, "%d/%d) ", process->priv->current_command, process->priv->n_comm);
+
+ info = g_ptr_array_index (process->priv->comm, process->priv->current_command);
+
+ argv = g_new (char *, g_list_length (info->args) + 1);
+ for (scan = info->args; scan; scan = scan->next)
+ argv[i++] = scan->data;
+ argv[i] = NULL;
+
+#ifdef DEBUG
+ {
+ int j;
+
+ if (process->priv->use_standard_locale)
+ g_print ("\tLC_MESSAGES=C\n");
+
+ if (info->dir != NULL)
+ g_print ("\tcd %s\n", info->dir);
+
+ g_print ("\t");
+ for (j = 0; j < i; j++)
+ g_print ("%s ", argv[j]);
+ g_print ("\n");
+ }
+#endif
+
+ if (info->begin_func != NULL)
+ (*info->begin_func) (info->begin_data);
+
+ if (! g_spawn_async_with_pipes (info->dir,
+ argv,
+ NULL,
+ (G_SPAWN_LEAVE_DESCRIPTORS_OPEN
+ | G_SPAWN_SEARCH_PATH
+ | G_SPAWN_DO_NOT_REAP_CHILD),
+ child_setup,
+ process,
+ &process->priv->command_pid,
+ NULL,
+ &out_fd,
+ &err_fd,
+ &error))
+ {
+ exec_data->error = fr_error_new (FR_ERROR_SPAWN, 0, error);
+ g_simple_async_result_complete_in_idle (exec_data->result);
+
+ g_error_free (error);
+ g_free (argv);
+ return;
+ }
+
+ g_free (argv);
+
+ fr_channel_data_set_fd (&process->out, out_fd, _fr_process_get_charset (process));
+ fr_channel_data_set_fd (&process->err, err_fd, _fr_process_get_charset (process));
+
+ process->priv->check_timeout = g_timeout_add (REFRESH_RATE,
+ check_child,
+ exec_data);
}
-void
-fr_process_start (FrProcess *process)
+static void
+_fr_process_start (ExecuteData *exec_data)
{
- g_return_if_fail (process != NULL);
+ FrProcess *process = exec_data->process;
- if (process->priv->running)
- return;
+ _g_string_list_free (exec_data->first_error_stdout);
+ exec_data->first_error_stdout = NULL;
+
+ _g_string_list_free (exec_data->first_error_stderr);
+ exec_data->first_error_stderr = NULL;
+
+ fr_error_free (exec_data->error);
+ exec_data->error = NULL;
fr_channel_data_reset (&process->out);
fr_channel_data_reset (&process->err);
process->priv->sticky_only = FALSE;
process->priv->current_command = 0;
- fr_process_set_error (process, FR_PROC_ERROR_NONE, 0, NULL);
-
- if (! process->restart) {
- process->priv->current_charset = -1;
- g_signal_emit (G_OBJECT (process),
- fr_process_signals[START],
- 0);
- }
-
process->priv->stopping = FALSE;
if (process->priv->n_comm == -1) {
process->priv->running = FALSE;
- g_signal_emit (G_OBJECT (process),
- fr_process_signals[DONE],
- 0,
- &process->error);
+ g_simple_async_result_complete_in_idle (exec_data->result);
}
else {
process->priv->running = TRUE;
- start_current_command (process);
+ execute_current_command (exec_data);
}
}
-static void
-fr_process_stop_priv (FrProcess *process,
- gboolean emit_signal)
+void
+fr_process_execute (FrProcess *process,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
- g_return_if_fail (process != NULL);
+ ExecuteData *exec_data;
- if (! process->priv->running)
- return;
+ g_return_if_fail (! process->priv->running);
- if (process->priv->stopping)
- return;
+ execute_data_free (process->priv->exec_data);
- process->priv->stopping = TRUE;
- process->error.type = FR_PROC_ERROR_STOPPED;
+ process->priv->exec_data = exec_data = g_new0 (ExecuteData, 1);
+ exec_data->process = g_object_ref (process);
+ exec_data->cancellable = _g_object_ref (cancellable);
+ exec_data->cancel_id = 0;
+ exec_data->result = g_simple_async_result_new (G_OBJECT (process),
+ callback,
+ user_data,
+ fr_process_execute);
- if (command_is_sticky (process, process->priv->current_command))
- allow_sticky_processes_only (process, emit_signal);
+ g_simple_async_result_set_op_res_gpointer (exec_data->result, exec_data, NULL);
- else if (process->term_on_stop && (process->priv->command_pid > 0))
- killpg (process->priv->command_pid, SIGTERM);
+ if (! process->restart)
+ process->priv->current_charset = -1;
- else {
- if (process->priv->check_timeout != 0) {
- g_source_remove (process->priv->check_timeout);
- process->priv->check_timeout = 0;
- }
+ if (cancellable != NULL) {
+ GError *error = NULL;
- process->priv->command_pid = 0;
- fr_channel_data_close_source (&process->out);
- fr_channel_data_close_source (&process->err);
+ if (g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+ exec_data->error = fr_error_new (FR_ERROR_STOPPED, 0, error);
+ g_simple_async_result_complete_in_idle (exec_data->result);
- process->priv->running = FALSE;
+ g_error_free (error);
+ return;
+ }
- if (emit_signal)
- g_signal_emit (G_OBJECT (process),
- fr_process_signals[DONE],
- 0,
- &process->error);
+ exec_data->cancel_id = g_cancellable_connect (cancellable,
+ G_CALLBACK (execute_cancelled_cb),
+ exec_data,
+ NULL);
}
+
+ _fr_process_start (exec_data);
+}
+
+
+gboolean
+fr_process_execute_finish (FrProcess *process,
+ GAsyncResult *result,
+ FrError **error)
+{
+ ExecuteData *exec_data;
+
+ g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (process), fr_process_execute), FALSE);
+
+ exec_data = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+ if (exec_data->error == NULL)
+ return TRUE;
+
+ if (error != NULL)
+ *error = fr_error_copy (exec_data->error);
+
+ return FALSE;
}
void
-fr_process_stop (FrProcess *process)
+fr_process_restart (FrProcess *process)
{
- fr_process_stop_priv (process, TRUE);
+ if (process->priv->exec_data != NULL)
+ _fr_process_start (process->priv->exec_data);
+}
+
+
+void
+fr_process_cancel (FrProcess *process)
+{
+ if (! process->priv->running)
+ return;
+ if (process->priv->exec_data == NULL)
+ return;
+ if (process->priv->exec_data->cancellable == NULL)
+ return;
+ g_cancellable_cancel (process->priv->exec_data->cancellable);
}
diff --git a/src/fr-process.h b/src/fr-process.h
index 857a74a..309f86b 100644
--- a/src/fr-process.h
+++ b/src/fr-process.h
@@ -25,6 +25,7 @@
#include <glib.h>
#include <gtk/gtk.h>
#include <sys/types.h>
+#include "fr-error.h"
#include "typedefs.h"
#define FR_TYPE_PROCESS (fr_process_get_type ())
@@ -39,7 +40,7 @@ typedef struct _FrProcessClass FrProcessClass;
typedef struct _FrProcessPrivate FrProcessPrivate;
typedef void (*ProcFunc) (gpointer data);
-typedef gboolean (*ContinueFunc) (gpointer data);
+typedef gboolean (*ContinueFunc) (FrError **error, gpointer data);
typedef void (*LineFunc) (char *line, gpointer data);
typedef struct {
@@ -54,23 +55,10 @@ typedef struct {
struct _FrProcess {
GObject __parent;
- /*< public >*/
-
- gboolean term_on_stop; /* whether we must terminate the
- * command when calling
- * fr_process_stop. */
-
- /*< public read-only >*/
-
FrChannelData out;
FrChannelData err;
- FrProcError error;
-
- /*< protected >*/
-
gboolean restart; /* whether to restart the process
* after an error. */
-
FrProcessPrivate *priv;
};
@@ -79,57 +67,61 @@ struct _FrProcessClass {
/* -- Signals -- */
- void (* start) (FrProcess *fr_proc);
- void (* done) (FrProcess *fr_proc,
- FrProcError *error);
- void (* sticky_only) (FrProcess *fr_proc);
+ void (* sticky_only) (FrProcess *fr_proc);
};
GType fr_process_get_type (void);
FrProcess * fr_process_new (void);
-void fr_process_clear (FrProcess *fr_proc);
-void fr_process_begin_command (FrProcess *fr_proc,
- const char *arg);
-void fr_process_begin_command_at (FrProcess *fr_proc,
- const char *arg,
- int index);
-void fr_process_add_arg (FrProcess *fr_proc,
- const char *arg);
-void fr_process_add_arg_concat (FrProcess *fr_proc,
- const char *arg,
+void fr_process_clear (FrProcess *fr_proc);
+void fr_process_begin_command (FrProcess *fr_proc,
+ const char *arg);
+void fr_process_begin_command_at (FrProcess *fr_proc,
+ const char *arg,
+ int index);
+void fr_process_add_arg (FrProcess *fr_proc,
+ const char *arg);
+void fr_process_add_arg_concat (FrProcess *fr_proc,
+ const char *arg,
...) G_GNUC_NULL_TERMINATED;
-void fr_process_add_arg_printf (FrProcess *fr_proc,
- const char *format,
+void fr_process_add_arg_printf (FrProcess *fr_proc,
+ const char *format,
...) G_GNUC_PRINTF (2, 3);
-void fr_process_set_arg_at (FrProcess *fr_proc,
- int n_comm,
- int n_arg,
- const char *arg);
-void fr_process_set_begin_func (FrProcess *fr_proc,
- ProcFunc func,
- gpointer func_data);
-void fr_process_set_end_func (FrProcess *fr_proc,
- ProcFunc func,
- gpointer func_data);
-void fr_process_set_continue_func (FrProcess *fr_proc,
- ContinueFunc func,
- gpointer func_data);
-void fr_process_end_command (FrProcess *fr_proc);
-void fr_process_set_working_dir (FrProcess *fr_proc,
- const char *arg);
-void fr_process_set_sticky (FrProcess *fr_proc,
- gboolean sticky);
-void fr_process_set_ignore_error (FrProcess *fr_proc,
- gboolean ignore_error);
-void fr_process_use_standard_locale (FrProcess *fr_proc,
- gboolean use_stand_locale);
-void fr_process_set_out_line_func (FrProcess *fr_proc,
- LineFunc func,
- gpointer func_data);
-void fr_process_set_err_line_func (FrProcess *fr_proc,
- LineFunc func,
- gpointer func_data);
-void fr_process_start (FrProcess *fr_proc);
-void fr_process_stop (FrProcess *fr_proc);
+void fr_process_set_arg_at (FrProcess *fr_proc,
+ int n_comm,
+ int n_arg,
+ const char *arg);
+void fr_process_set_begin_func (FrProcess *fr_proc,
+ ProcFunc func,
+ gpointer func_data);
+void fr_process_set_end_func (FrProcess *fr_proc,
+ ProcFunc func,
+ gpointer func_data);
+void fr_process_set_continue_func (FrProcess *fr_proc,
+ ContinueFunc func,
+ gpointer func_data);
+void fr_process_end_command (FrProcess *fr_proc);
+void fr_process_set_working_dir (FrProcess *fr_proc,
+ const char *arg);
+void fr_process_set_sticky (FrProcess *fr_proc,
+ gboolean sticky);
+void fr_process_set_ignore_error (FrProcess *fr_proc,
+ gboolean ignore_error);
+void fr_process_use_standard_locale (FrProcess *fr_proc,
+ gboolean use_stand_locale);
+void fr_process_set_out_line_func (FrProcess *fr_proc,
+ LineFunc func,
+ gpointer func_data);
+void fr_process_set_err_line_func (FrProcess *fr_proc,
+ LineFunc func,
+ gpointer func_data);
+void fr_process_execute (FrProcess *process,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean fr_process_execute_finish (FrProcess *process,
+ GAsyncResult *result,
+ FrError **error);
+void fr_process_restart (FrProcess *process);
+void fr_process_cancel (FrProcess *process);
#endif /* FR_PROCESS_H */
diff --git a/src/fr-window.c b/src/fr-window.c
index 247eaa6..61fc551 100644
--- a/src/fr-window.c
+++ b/src/fr-window.c
@@ -42,6 +42,7 @@
#include "fr-marshal.h"
#include "fr-list-model.h"
#include "fr-archive.h"
+#include "fr-command.h"
#include "fr-error.h"
#include "fr-stock.h"
#include "fr-window.h"
@@ -128,12 +129,6 @@ typedef struct {
} FRConvertData;
-typedef enum {
- FR_CLIPBOARD_OP_CUT,
- FR_CLIPBOARD_OP_COPY
-} FRClipboardOp;
-
-
typedef struct {
GList *file_list;
char *extract_to_dir;
@@ -172,7 +167,7 @@ typedef struct {
int refs;
char *archive_uri;
char *archive_password;
- FRClipboardOp op;
+ FrClipboardOp op;
char *base_dir;
GList *files;
char *tmp_dir;
@@ -245,7 +240,7 @@ enum {
static guint fr_window_signals[LAST_SIGNAL] = { 0 };
-struct _FrWindowPrivateData {
+struct _FrWindowPrivate {
GtkWidget *layout;
GtkWidget *contents;
GtkWidget *list_view;
@@ -388,6 +383,8 @@ struct _FrWindowPrivateData {
/* misc */
+ GCancellable *cancellable;
+
GSettings *settings_listing;
GSettings *settings_ui;
GSettings *settings_general;
@@ -512,7 +509,7 @@ fr_window_free_open_files (FrWindow *window)
static void
-fr_window_convert_data_free (FrWindow *window,
+_fr_window_convert_data_free (FrWindow *window,
gboolean all)
{
if (all) {
@@ -590,7 +587,7 @@ fr_window_free_private_data (FrWindow *window)
fr_window_free_open_files (window);
- fr_window_convert_data_free (window, TRUE);
+ _fr_window_convert_data_free (window, TRUE);
g_clear_error (&window->priv->drag_error);
_g_string_list_free (window->priv->drag_file_list);
@@ -629,6 +626,8 @@ fr_window_free_private_data (FrWindow *window)
_g_object_unref (window->priv->settings_general);
_g_object_unref (window->priv->settings_dialogs);
_g_object_unref (window->priv->settings_nautilus);
+
+ _g_object_unref (window->priv->cancellable);
}
@@ -791,11 +790,14 @@ fr_window_unrealized (GtkWidget *window,
static void
fr_window_init (FrWindow *window)
{
- window->priv = g_new0 (FrWindowPrivateData, 1);
+ window->priv = g_new0 (FrWindowPrivate, 1);
window->priv->update_dropped_files = FALSE;
window->priv->filter_mode = FALSE;
window->priv->use_progress_dialog = TRUE;
window->priv->batch_title = NULL;
+ window->priv->cancellable = g_cancellable_new ();
+
+ window->archive = NULL;
g_signal_connect (window,
"realize",
@@ -880,8 +882,8 @@ fr_window_get_current_dir_list (FrWindow *window)
files = g_ptr_array_sized_new (128);
- for (i = 0; i < window->archive->command->files->len; i++) {
- FileData *fdata = g_ptr_array_index (window->archive->command->files, i);
+ for (i = 0; i < window->archive->files->len; i++) {
+ FileData *fdata = g_ptr_array_index (window->archive->files, i);
if (fdata->list_name == NULL)
continue;
@@ -1034,8 +1036,8 @@ get_dir_size (FrWindow *window,
dirname_l = strlen (dirname);
size = 0;
- for (i = 0; i < window->archive->command->files->len; i++) {
- FileData *fd = g_ptr_array_index (window->archive->command->files, i);
+ for (i = 0; i < window->archive->files->len; i++) {
+ FileData *fd = g_ptr_array_index (window->archive->files, i);
if (strncmp (dirname, fd->full_path, dirname_l) == 0)
size += fd->size;
@@ -1182,8 +1184,8 @@ fr_window_dir_exists_in_archive (FrWindow *window,
if (strcmp (dir_name, "/") == 0)
return TRUE;
- for (i = 0; i < window->archive->command->files->len; i++) {
- FileData *fdata = g_ptr_array_index (window->archive->command->files, i);
+ for (i = 0; i < window->archive->files->len; i++) {
+ FileData *fdata = g_ptr_array_index (window->archive->files, i);
if (strncmp (dir_name, fdata->full_path, dir_name_len) == 0) {
return TRUE;
@@ -1436,7 +1438,7 @@ fr_window_update_statusbar_list_info (FrWindow *window)
if (window == NULL)
return;
- if ((window->archive == NULL) || (window->archive->command == NULL)) {
+ if (window->archive == NULL) {
gtk_statusbar_pop (GTK_STATUSBAR (window->priv->statusbar), window->priv->list_info_cid);
return;
}
@@ -1744,8 +1746,8 @@ fr_window_update_dir_tree (FrWindow *window)
dirs = g_ptr_array_sized_new (128);
dir_cache = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
- for (i = 0; i < window->archive->command->files->len; i++) {
- FileData *fdata = g_ptr_array_index (window->archive->command->files, i);
+ for (i = 0; i < window->archive->files->len; i++) {
+ FileData *fdata = g_ptr_array_index (window->archive->files, i);
char *dir;
if (gtk_entry_get_text (GTK_ENTRY (window->priv->filter_entry)) != NULL) {
@@ -1786,7 +1788,7 @@ fr_window_update_dir_tree (FrWindow *window)
char *uri;
char *name;
- uri = g_file_get_uri (window->archive->file);
+ uri = g_file_get_uri (fr_archive_get_file (window->archive));
name = _g_uri_display_basename (uri);
gtk_tree_store_append (window->priv->tree_store, &node, NULL);
@@ -1897,8 +1899,8 @@ fr_window_update_file_list (FrWindow *window,
fr_window_start_activity_mode (window);
if (window->priv->list_mode == FR_WINDOW_LIST_MODE_FLAT) {
- fr_window_compute_list_names (window, window->archive->command->files);
- files = window->archive->command->files;
+ fr_window_compute_list_names (window, window->archive->files);
+ files = window->archive->files;
free_files = FALSE;
}
else {
@@ -1917,7 +1919,7 @@ fr_window_update_file_list (FrWindow *window,
}
g_free (current_dir);
- fr_window_compute_list_names (window, window->archive->command->files);
+ fr_window_compute_list_names (window, window->archive->files);
files = fr_window_get_current_dir_list (window);
free_files = TRUE;
}
@@ -2020,7 +2022,6 @@ fr_window_update_paste_command_sensitivity (FrWindow *window,
gboolean running;
gboolean no_archive;
gboolean ro;
- gboolean compr_file;
if (window->priv->closing)
return;
@@ -2030,9 +2031,14 @@ fr_window_update_paste_command_sensitivity (FrWindow *window,
running = window->priv->activity_ref > 0;
no_archive = (window->archive == NULL) || ! window->priv->archive_present;
ro = ! no_archive && window->archive->read_only;
- compr_file = ! no_archive && window->archive->is_compressed_file;
- set_sensitive (window, "Paste", ! no_archive && ! ro && ! running && ! compr_file && (window->priv->list_mode != FR_WINDOW_LIST_MODE_FLAT) && gtk_clipboard_wait_is_target_available (clipboard, FR_SPECIAL_URI_LIST));
+ set_sensitive (window, "Paste",
+ ! no_archive
+ && ! ro
+ && ! running
+ && fr_archive_is_capable_of (window->archive, FR_ARCHIVE_CAN_STORE_MANY_FILES)
+ && (window->priv->list_mode != FR_WINDOW_LIST_MODE_FLAT)
+ && gtk_clipboard_wait_is_target_available (clipboard, FR_SPECIAL_URI_LIST));
}
@@ -2043,7 +2049,7 @@ fr_window_update_sensitivity (FrWindow *window)
gboolean ro;
gboolean file_op;
gboolean running;
- gboolean compr_file;
+ gboolean can_store_many_files;
gboolean sel_not_null;
gboolean one_file_selected;
gboolean dir_selected;
@@ -2052,23 +2058,23 @@ fr_window_update_sensitivity (FrWindow *window)
if (window->priv->batch_mode)
return;
- running = window->priv->activity_ref > 0;
- no_archive = (window->archive == NULL) || ! window->priv->archive_present;
- ro = ! no_archive && window->archive->read_only;
- file_op = ! no_archive && ! window->priv->archive_new && ! running;
- compr_file = ! no_archive && window->archive->is_compressed_file;
- n_selected = fr_window_get_n_selected_files (window);
- sel_not_null = n_selected > 0;
- one_file_selected = n_selected == 1;
- dir_selected = selection_has_a_dir (window);
-
- set_sensitive (window, "AddFiles", ! no_archive && ! ro && ! running && ! compr_file);
- set_sensitive (window, "AddFiles_Toolbar", ! no_archive && ! ro && ! running && ! compr_file);
- set_sensitive (window, "AddFolder", ! no_archive && ! ro && ! running && ! compr_file);
- set_sensitive (window, "AddFolder_Toolbar", ! no_archive && ! ro && ! running && ! compr_file);
- set_sensitive (window, "Copy", ! no_archive && ! ro && ! running && ! compr_file && sel_not_null && (window->priv->list_mode != FR_WINDOW_LIST_MODE_FLAT));
- set_sensitive (window, "Cut", ! no_archive && ! ro && ! running && ! compr_file && sel_not_null && (window->priv->list_mode != FR_WINDOW_LIST_MODE_FLAT));
- set_sensitive (window, "Delete", ! no_archive && ! ro && ! window->priv->archive_new && ! running && ! compr_file);
+ running = window->priv->activity_ref > 0;
+ no_archive = (window->archive == NULL) || ! window->priv->archive_present;
+ ro = ! no_archive && window->archive->read_only;
+ file_op = ! no_archive && ! window->priv->archive_new && ! running;
+ can_store_many_files = fr_archive_is_capable_of (window->archive, FR_ARCHIVE_CAN_STORE_MANY_FILES);
+ n_selected = fr_window_get_n_selected_files (window);
+ sel_not_null = n_selected > 0;
+ one_file_selected = n_selected == 1;
+ dir_selected = selection_has_a_dir (window);
+
+ set_sensitive (window, "AddFiles", ! no_archive && ! ro && ! running && can_store_many_files);
+ set_sensitive (window, "AddFiles_Toolbar", ! no_archive && ! ro && ! running && can_store_many_files);
+ set_sensitive (window, "AddFolder", ! no_archive && ! ro && ! running && can_store_many_files);
+ set_sensitive (window, "AddFolder_Toolbar", ! no_archive && ! ro && ! running && can_store_many_files);
+ set_sensitive (window, "Copy", ! no_archive && ! ro && ! running && can_store_many_files && sel_not_null && (window->priv->list_mode != FR_WINDOW_LIST_MODE_FLAT));
+ set_sensitive (window, "Cut", ! no_archive && ! ro && ! running && can_store_many_files && sel_not_null && (window->priv->list_mode != FR_WINDOW_LIST_MODE_FLAT));
+ set_sensitive (window, "Delete", ! no_archive && ! ro && ! window->priv->archive_new && ! running && can_store_many_files);
set_sensitive (window, "DeselectAll", ! no_archive && sel_not_null);
set_sensitive (window, "Extract", file_op);
set_sensitive (window, "Extract_Toolbar", file_op);
@@ -2078,15 +2084,15 @@ fr_window_update_sensitivity (FrWindow *window)
set_sensitive (window, "Open_Toolbar", ! running);
set_sensitive (window, "OpenSelection", file_op && sel_not_null && ! dir_selected);
set_sensitive (window, "OpenFolder", file_op && one_file_selected && dir_selected);
- set_sensitive (window, "Password", ! running && (window->priv->asked_for_password || (! no_archive && window->archive->command->propPassword)));
+ set_sensitive (window, "Password", ! running && (window->priv->asked_for_password || (! no_archive && window->archive->propPassword)));
set_sensitive (window, "Properties", file_op);
set_sensitive (window, "Close", !running || window->priv->stoppable);
set_sensitive (window, "Reload", ! (no_archive || running));
- set_sensitive (window, "Rename", ! no_archive && ! ro && ! running && ! compr_file && one_file_selected);
- set_sensitive (window, "SaveAs", ! no_archive && ! compr_file && ! running);
+ set_sensitive (window, "Rename", ! no_archive && ! ro && ! running && can_store_many_files && one_file_selected);
+ set_sensitive (window, "SaveAs", ! no_archive && can_store_many_files && ! running);
set_sensitive (window, "SelectAll", ! no_archive);
set_sensitive (window, "Stop", running && window->priv->stoppable);
- set_sensitive (window, "TestArchive", ! no_archive && ! running && window->archive->command->propTest);
+ set_sensitive (window, "TestArchive", ! no_archive && ! running && window->archive->propTest);
set_sensitive (window, "ViewSelection", file_op && one_file_selected && ! dir_selected);
set_sensitive (window, "ViewSelection_Toolbar", file_op && one_file_selected && ! dir_selected);
@@ -2378,7 +2384,7 @@ fr_window_working_archive_cb (FrCommand *command,
static gboolean
-fr_window_message_cb (FrCommand *command,
+fr_archive_message_cb (FrCommand *command,
const char *msg,
FrWindow *window)
{
@@ -2514,7 +2520,7 @@ display_progress_dialog (gpointer data)
gtk_widget_show (GTK_WIDGET (window));
gtk_widget_hide (window->priv->progress_bar);
gtk_widget_show (window->priv->progress_dialog);
- fr_window_message_cb (NULL, window->priv->pd_last_message, window);
+ fr_archive_message_cb (NULL, window->priv->pd_last_message, window);
}
window->priv->progress_timeout = 0;
@@ -2562,7 +2568,7 @@ open_progress_dialog (FrWindow *window,
static gboolean
-fr_window_progress_cb (FrArchive *archive,
+fr_archive_progress_cb (FrArchive *archive,
double fraction,
FrWindow *window)
{
@@ -2573,11 +2579,11 @@ fr_window_progress_cb (FrArchive *archive,
gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (window->priv->pd_progress_bar), fraction);
gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (window->priv->progress_bar), fraction);
- if ((archive != NULL) && (archive->command->n_files > 1)) {
+ if ((archive != NULL) && (archive->n_files > 1)) {
char *message = NULL;
int remaining_files;
- remaining_files = archive->command->n_files - archive->command->n_file + 1;
+ remaining_files = archive->n_files - archive->n_file + 1;
switch (window->priv->action) {
case FR_ACTION_ADDING_FILES:
@@ -2592,7 +2598,7 @@ fr_window_progress_cb (FrArchive *archive,
}
if (message != NULL)
- fr_command_message (archive->command, message);
+ fr_archive_message (archive, message);
}
window->priv->pd_last_fraction = fraction;
@@ -2632,8 +2638,8 @@ open_progress_dialog_with_open_destination (FrWindow *window)
gtk_widget_show (window->priv->pd_quit_button);
gtk_widget_show (window->priv->pd_close_button);
display_progress_dialog (window);
- fr_window_progress_cb (NULL, 1.0, window);
- fr_window_message_cb (NULL, _("Extraction completed successfully"), window);
+ fr_archive_progress_cb (NULL, 1.0, window);
+ fr_archive_message_cb (NULL, _("Extraction completed successfully"), window);
}
@@ -2655,8 +2661,8 @@ open_progress_dialog_with_open_archive (FrWindow *window)
gtk_widget_show (window->priv->pd_open_archive_button);
gtk_widget_show (window->priv->pd_close_button);
display_progress_dialog (window);
- fr_window_progress_cb (NULL, 1.0, window);
- fr_window_message_cb (NULL, _("Archive created successfully"), window);
+ fr_archive_progress_cb (NULL, 1.0, window);
+ fr_archive_message_cb (NULL, _("Archive created successfully"), window);
}
@@ -2712,10 +2718,8 @@ action_started (FrArchive *archive,
break;
}
- if (archive->command != NULL) {
- fr_command_progress (archive->command, -1.0);
- fr_command_message (archive->command, _("Please waitâ"));
- }
+ fr_archive_progress (archive, -1.0);
+ fr_archive_message (archive, _("Please waitâ"));
}
@@ -2726,11 +2730,11 @@ fr_window_add_to_recent_list (FrWindow *window,
if (_g_path_is_temp_dir (uri))
return;
- if (window->archive->content_type != NULL) {
+ if (window->archive->mime_type != NULL) {
GtkRecentData *recent_data;
recent_data = g_new0 (GtkRecentData, 1);
- recent_data->mime_type = g_content_type_get_mime_type (window->archive->content_type);
+ recent_data->mime_type = g_content_type_get_mime_type (window->archive->mime_type);
recent_data->app_name = "File Roller";
recent_data->app_exec = "file-roller";
gtk_recent_manager_add_full (gtk_recent_manager_get_default (), uri, recent_data);
@@ -2780,7 +2784,7 @@ fr_window_show_error_dialog (FrWindow *window,
if (window->priv->batch_mode && ! window->priv->use_progress_dialog) {
GError *error;
- error = g_error_new_literal (FR_ERROR, FR_PROC_ERROR_GENERIC, details ? details : _("Command exited abnormally."));
+ error = g_error_new_literal (FR_ERROR, FR_ERROR_GENERIC, details ? details : _("Command exited abnormally."));
g_signal_emit (window,
fr_window_signals[READY],
0,
@@ -2820,40 +2824,57 @@ fr_window_destroy_with_error_dialog (FrWindow *window)
}
-static gboolean
-handle_errors (FrWindow *window,
- FrArchive *archive,
- FrAction action,
- FrProcError *error)
-{
- if (error->type == FR_PROC_ERROR_ASK_PASSWORD) {
+static void
+_handle_archive_operation_error (FrWindow *window,
+ FrArchive *archive,
+ FrAction action,
+ GError *error,
+ gboolean *continue_batch,
+ gboolean *opens_dialog)
+{
+ GtkWindow *dialog_parent;
+ char *msg;
+ char *utf8_name;
+ char *details;
+ GList *output;
+ GtkWidget *dialog;
+
+ if (continue_batch) *continue_batch = (error == NULL);
+ if (opens_dialog) *opens_dialog = FALSE;
+
+ if (error == NULL)
+ return;
+
+ switch (error->code) {
+ case FR_ERROR_ASK_PASSWORD:
close_progress_dialog (window, TRUE);
dlg_ask_password (window);
- return FALSE;
- }
- else if (error->type == FR_PROC_ERROR_UNSUPPORTED_FORMAT) {
+ if (opens_dialog) *opens_dialog = TRUE;
+ break;
+
+ case FR_ERROR_UNSUPPORTED_FORMAT:
close_progress_dialog (window, TRUE);
dlg_package_installer (window, archive, action);
- return FALSE;
- }
+ if (opens_dialog) *opens_dialog = TRUE;
+ break;
+
#if 0
- else if (error->type == FR_PROC_ERROR_BAD_CHARSET) {
+ case FR_PROC_ERROR_BAD_CHARSET:
close_progress_dialog (window, TRUE);
/* dlg_ask_archive_charset (window); FIXME: implement after feature freeze */
- return FALSE;
- }
+ break;
#endif
- else if (error->type == FR_PROC_ERROR_STOPPED) {
+
+ case FR_ERROR_STOPPED:
/* nothing */
- }
- else if (error->type != FR_PROC_ERROR_NONE) {
- char *msg = NULL;
- char *utf8_name;
- char *details = NULL;
- GtkWindow *dialog_parent;
- GtkWidget *dialog;
- FrProcess *process = archive->process;
- GList *output = NULL;
+ break;
+
+ default:
+ /* generic error => show an error dialog */
+
+ msg = NULL;
+ details = NULL;
+ output = NULL;
if (window->priv->batch_mode) {
dialog_parent = NULL;
@@ -2913,26 +2934,23 @@ handle_errors (FrWindow *window,
break;
}
- switch (error->type) {
- case FR_PROC_ERROR_COMMAND_NOT_FOUND:
+ switch (error->code) {
+ case FR_ERROR_COMMAND_NOT_FOUND:
details = _("Command not found.");
break;
- case FR_PROC_ERROR_EXITED_ABNORMALLY:
+ case FR_ERROR_EXITED_ABNORMALLY:
details = _("Command exited abnormally.");
break;
- case FR_PROC_ERROR_SPAWN:
- details = error->gerror->message;
+ case FR_ERROR_SPAWN:
+ details = error->message;
break;
default:
- if (error->gerror != NULL)
- details = error->gerror->message;
- else
- details = NULL;
+ details = error->message;
break;
}
- if (error->type != FR_PROC_ERROR_GENERIC)
- output = (process->err.raw != NULL) ? process->err.raw : process->out.raw;
+ if ((error->code != FR_ERROR_GENERIC) && FR_IS_COMMAND (archive))
+ output = fr_command_get_last_output (FR_COMMAND (archive));
dialog = _gtk_error_dialog_new (dialog_parent,
0,
@@ -2941,55 +2959,182 @@ handle_errors (FrWindow *window,
((details != NULL) ? "%s" : NULL),
details);
fr_window_show_error_dialog (window, dialog, dialog_parent, details);
-
- return FALSE;
+ break;
}
-
- return TRUE;
}
+static void fr_window_exec_next_batch_action (FrWindow *window);
+
+
static void
-convert__action_performed (FrArchive *archive,
- FrAction action,
- FrProcError *error,
- gpointer data)
+_archive_operation_completed (FrWindow *window,
+ FrAction action,
+ GError *error)
{
- FrWindow *window = data;
+ gboolean continue_batch = FALSE;
+ gboolean opens_dialog;
+ gboolean operation_canceled;
+ char *archive_dir;
+ gboolean temp_dir;
#ifdef DEBUG
- debug (DEBUG_INFO, "%s [CONVERT::DONE] (FR::Window)\n", action_names[action]);
+ debug (DEBUG_INFO, "%s [DONE] (FR::Window)\n", action_names[action]);
#endif
- if ((action == FR_ACTION_GETTING_FILE_LIST) || (action == FR_ACTION_ADDING_FILES)) {
- fr_window_stop_activity_mode (window);
- fr_window_pop_message (window);
+ fr_window_stop_activity_mode (window);
+ fr_window_pop_message (window);
+
+ _handle_archive_operation_error (window, window->archive, action, error, &continue_batch, &opens_dialog);
+ if (opens_dialog)
+ return;
+
+ operation_canceled = ((error != NULL) && (error->code == FR_ERROR_STOPPED));
+
+ switch (action) {
+ case FR_ACTION_CREATING_NEW_ARCHIVE:
+ case FR_ACTION_CREATING_ARCHIVE:
close_progress_dialog (window, FALSE);
- }
+ if (! operation_canceled) {
+ fr_window_history_clear (window);
+ fr_window_go_to_location (window, "/", TRUE);
+ fr_window_update_dir_tree (window);
+ fr_window_update_title (window);
+ fr_window_update_sensitivity (window);
+ }
+ break;
- if (action != FR_ACTION_ADDING_FILES)
+ case FR_ACTION_LOADING_ARCHIVE:
+ close_progress_dialog (window, FALSE);
+ if (error != NULL) {
+ fr_window_remove_from_recent_list (window, window->priv->archive_uri);
+ if (window->priv->non_interactive) {
+ fr_window_archive_close (window);
+ fr_window_stop_batch (window);
+ }
+ }
+ else {
+ fr_window_add_to_recent_list (window, window->priv->archive_uri);
+ if (! window->priv->non_interactive)
+ gtk_window_present (GTK_WINDOW (window));
+ }
+ continue_batch = FALSE;
+ g_signal_emit (window,
+ fr_window_signals[ARCHIVE_LOADED],
+ 0,
+ error == NULL);
+ break;
+
+ case FR_ACTION_LISTING_CONTENT:
+ /* update the uri because multi-volume archives can have
+ * a different name after loading. */
+ g_free (window->priv->archive_uri);
+ window->priv->archive_uri = g_file_get_uri (fr_archive_get_file (window->archive));
+
+ close_progress_dialog (window, FALSE);
+ if (error != NULL) {
+ fr_window_remove_from_recent_list (window, window->priv->archive_uri);
+ fr_window_archive_close (window);
+ fr_window_set_password (window, NULL);
+ break;
+ }
+
+ /* error == NULL */
+
+ archive_dir = _g_path_remove_level (window->priv->archive_uri);
+ temp_dir = _g_path_is_temp_dir (archive_dir);
+ if (! window->priv->archive_present) {
+ window->priv->archive_present = TRUE;
+
+ fr_window_history_clear (window);
+ fr_window_history_add (window, "/");
+
+ if (! temp_dir) {
+ fr_window_set_open_default_dir (window, archive_dir);
+ fr_window_set_add_default_dir (window, archive_dir);
+ if (! window->priv->freeze_default_dir)
+ fr_window_set_extract_default_dir (window, archive_dir, FALSE);
+ }
+
+ window->priv->archive_new = FALSE;
+ }
+ g_free (archive_dir);
+
+ if (! temp_dir)
+ fr_window_add_to_recent_list (window, window->priv->archive_uri);
+
+ fr_window_update_title (window);
+ fr_window_go_to_location (window, fr_window_get_current_location (window), TRUE);
+ fr_window_update_dir_tree (window);
+ if (! window->priv->batch_mode && window->priv->non_interactive)
+ gtk_window_present (GTK_WINDOW (window));
+ break;
+
+ case FR_ACTION_DELETING_FILES:
+ close_progress_dialog (window, FALSE);
+ if (! operation_canceled)
+ fr_window_archive_reload (window);
return;
- handle_errors (window, archive, action, error);
+ case FR_ACTION_ADDING_FILES:
+ close_progress_dialog (window, FALSE);
- if (error->type == FR_PROC_ERROR_NONE)
- open_progress_dialog_with_open_archive (window);
+ /* update the uri because multi-volume archives can have
+ * a different name after creation. */
+ g_free (window->priv->archive_uri);
+ window->priv->archive_uri = g_file_get_uri (fr_archive_get_file (window->archive));
- _g_path_remove_directory (window->priv->convert_data.temp_dir);
- fr_window_convert_data_free (window, FALSE);
+ if (error == NULL) {
+ if (window->priv->archive_new)
+ window->priv->archive_new = FALSE;
+ fr_window_add_to_recent_list (window, window->priv->archive_uri);
+ }
+ if (! window->priv->batch_mode && ! operation_canceled) {
+ fr_window_archive_reload (window);
+ return;
+ }
+ break;
- fr_window_update_sensitivity (window);
- fr_window_update_statusbar_list_info (window);
+ case FR_ACTION_TESTING_ARCHIVE:
+ close_progress_dialog (window, FALSE);
+ if (error == NULL)
+ fr_window_view_last_output (window, _("Test Result"));
+ return;
+
+ case FR_ACTION_EXTRACTING_FILES:
+ if (window->priv->ask_to_open_destination_after_extraction)
+ open_progress_dialog_with_open_destination (window);
+ else
+ close_progress_dialog (window, FALSE);
+ break;
+
+ default:
+ close_progress_dialog (window, FALSE);
+ continue_batch = FALSE;
+ break;
+ }
+
+ if (window->priv->batch_action == NULL) {
+ fr_window_update_sensitivity (window);
+ fr_window_update_statusbar_list_info (window);
+ }
+
+ if (continue_batch) {
+ if (error != NULL)
+ fr_window_stop_batch (window);
+ else
+ fr_window_exec_next_batch_action (window);
+ }
}
-static void fr_window_exec_next_batch_action (FrWindow *window);
+#if 0 /* FIXME: libarchive */
static void
action_performed (FrArchive *archive,
FrAction action,
- FrProcError *error,
+ FrError *error,
gpointer data)
{
FrWindow *window = data;
@@ -3004,10 +3149,10 @@ action_performed (FrArchive *archive,
fr_window_stop_activity_mode (window);
fr_window_pop_message (window);
- continue_batch = handle_errors (window, archive, action, error);
+ continue_batch = _handle_archive_operation_error (window, archive, action, error);
- if ((error->type == FR_PROC_ERROR_ASK_PASSWORD)
- || (error->type == FR_PROC_ERROR_UNSUPPORTED_FORMAT)
+ if ((error->type == FR_ERROR_ASK_PASSWORD)
+ || (error->type == FR_ERROR_UNSUPPORTED_FORMAT)
/*|| (error->type == FR_PROC_ERROR_BAD_CHARSET)*/)
{
return;
@@ -3017,7 +3162,7 @@ action_performed (FrArchive *archive,
case FR_ACTION_CREATING_NEW_ARCHIVE:
case FR_ACTION_CREATING_ARCHIVE:
close_progress_dialog (window, FALSE);
- if (error->type != FR_PROC_ERROR_STOPPED) {
+ if (error->type != FR_ERROR_STOPPED) {
fr_window_history_clear (window);
fr_window_go_to_location (window, "/", TRUE);
fr_window_update_dir_tree (window);
@@ -3028,7 +3173,7 @@ action_performed (FrArchive *archive,
case FR_ACTION_LOADING_ARCHIVE:
close_progress_dialog (window, FALSE);
- if (error->type != FR_PROC_ERROR_NONE) {
+ if (error->type != FR_ERROR_NONE) {
fr_window_remove_from_recent_list (window, window->priv->archive_uri);
if (window->priv->non_interactive) {
fr_window_archive_close (window);
@@ -3044,7 +3189,7 @@ action_performed (FrArchive *archive,
g_signal_emit (window,
fr_window_signals[ARCHIVE_LOADED],
0,
- error->type == FR_PROC_ERROR_NONE);
+ error->type == FR_ERROR_NONE);
break;
case FR_ACTION_LISTING_CONTENT:
@@ -3054,7 +3199,7 @@ action_performed (FrArchive *archive,
window->priv->archive_uri = g_file_get_uri (window->archive->file);
close_progress_dialog (window, FALSE);
- if (error->type != FR_PROC_ERROR_NONE) {
+ if (error->type != FR_ERROR_NONE) {
fr_window_remove_from_recent_list (window, window->priv->archive_uri);
fr_window_archive_close (window);
fr_window_set_password (window, NULL);
@@ -3092,7 +3237,7 @@ action_performed (FrArchive *archive,
case FR_ACTION_DELETING_FILES:
close_progress_dialog (window, FALSE);
- if (error->type != FR_PROC_ERROR_STOPPED)
+ if (error->type != FR_ERROR_STOPPED)
fr_window_archive_reload (window);
return;
@@ -3104,12 +3249,12 @@ action_performed (FrArchive *archive,
g_free (window->priv->archive_uri);
window->priv->archive_uri = g_file_get_uri (window->archive->file);
- if (error->type == FR_PROC_ERROR_NONE) {
+ if (error->type == FR_ERROR_NONE) {
if (window->priv->archive_new)
window->priv->archive_new = FALSE;
fr_window_add_to_recent_list (window, window->priv->archive_uri);
}
- if (! window->priv->batch_mode && (error->type != FR_PROC_ERROR_STOPPED)) {
+ if (! window->priv->batch_mode && (error->type != FR_ERROR_STOPPED)) {
fr_window_archive_reload (window);
return;
}
@@ -3117,15 +3262,15 @@ action_performed (FrArchive *archive,
case FR_ACTION_TESTING_ARCHIVE:
close_progress_dialog (window, FALSE);
- if (error->type == FR_PROC_ERROR_NONE)
+ if (error->type == FR_ERROR_NONE)
fr_window_view_last_output (window, _("Test Result"));
return;
case FR_ACTION_EXTRACTING_FILES:
- if (error->type != FR_PROC_ERROR_NONE) {
+ if (error->type != FR_ERROR_NONE) {
if (window->priv->convert_data.converting) {
_g_path_remove_directory (window->priv->convert_data.temp_dir);
- fr_window_convert_data_free (window, TRUE);
+ _fr_window_convert_data_free (window, TRUE);
}
break;
}
@@ -3167,7 +3312,7 @@ action_performed (FrArchive *archive,
}
if (continue_batch) {
- if (error->type != FR_PROC_ERROR_NONE)
+ if (error->type != FR_ERROR_NONE)
fr_window_stop_batch (window);
else
fr_window_exec_next_batch_action (window);
@@ -3175,6 +3320,9 @@ action_performed (FrArchive *archive,
}
+#endif
+
+
/* -- selections -- */
@@ -3192,8 +3340,8 @@ get_dir_list_from_path (FrWindow *window,
else
dirname = g_strdup (path);
dirname_l = strlen (dirname);
- for (i = 0; i < window->archive->command->files->len; i++) {
- FileData *fd = g_ptr_array_index (window->archive->command->files, i);
+ for (i = 0; i < window->archive->files->len; i++) {
+ FileData *fd = g_ptr_array_index (window->archive->files, i);
if (strncmp (dirname, fd->full_path, dirname_l) == 0)
list = g_list_prepend (list, g_strdup (fd->original_path));
@@ -3372,8 +3520,8 @@ fr_window_get_file_list_pattern (FrWindow *window,
regexps = _g_regexp_split_from_patterns (pattern, G_REGEX_CASELESS);
list = NULL;
- for (i = 0; i < window->archive->command->files->len; i++) {
- FileData *fd = g_ptr_array_index (window->archive->command->files, i);
+ for (i = 0; i < window->archive->files->len; i++) {
+ FileData *fd = g_ptr_array_index (window->archive->files, i);
char *utf8_name;
/* FIXME: only files in the current location ? */
@@ -3956,7 +4104,7 @@ fr_window_drag_data_received (GtkWidget *widget,
if (window->priv->archive_present
&& (window->archive != NULL)
&& ! window->archive->read_only
- && ! window->archive->is_compressed_file)
+ && fr_archive_is_capable_of (window->archive, FR_ARCHIVE_CAN_STORE_MANY_FILES))
{
if (one_file && is_an_archive) {
GtkWidget *d;
@@ -4180,7 +4328,8 @@ get_selection_data_from_clipboard_data (FrWindow *window,
list = g_string_new (NULL);
- local_filename = g_file_get_uri (window->archive->local_copy);
+ /* FIXME: check if this works correctly */
+ local_filename = g_file_get_uri (fr_archive_get_file (window->archive));
g_string_append (list, local_filename);
g_free (local_filename);
@@ -4979,7 +5128,7 @@ theme_changed_cb (GtkIconTheme *theme, FrWindow *window)
static gboolean
-fr_window_stoppable_cb (FrCommand *command,
+fr_archive_stoppable_cb (FrCommand *command,
gboolean stoppable,
FrWindow *window)
{
@@ -4993,56 +5142,6 @@ fr_window_stoppable_cb (FrCommand *command,
}
-static gboolean
-fr_window_fake_load (FrArchive *archive,
- gpointer data)
-{
- /* fake loads are disabled to allow exact progress dialogs (#153281) */
-
- return FALSE;
-
-#if 0
- FrWindow *window = data;
- gboolean add_after_opening = FALSE;
- gboolean extract_after_opening = FALSE;
- GList *scan;
-
- /* fake loads are used only in batch mode to avoid unnecessary
- * archive loadings. */
-
- if (! window->priv->batch_mode)
- return FALSE;
-
- /* Check whether there is an ADD or EXTRACT action in the batch list. */
-
- for (scan = window->priv->batch_action; scan; scan = scan->next) {
- FRBatchAction *action;
-
- action = (FRBatchAction *) scan->data;
- if (action->type == FR_BATCH_ACTION_ADD) {
- add_after_opening = TRUE;
- break;
- }
- if ((action->type == FR_BATCH_ACTION_EXTRACT)
- || (action->type == FR_BATCH_ACTION_EXTRACT_HERE)
- || (action->type == FR_BATCH_ACTION_EXTRACT_INTERACT))
- {
- extract_after_opening = TRUE;
- break;
- }
- }
-
- /* use fake load when in batch mode and the archive type supports all
- * of the required features */
-
- return (window->priv->batch_mode
- && ! (add_after_opening && window->priv->update_dropped_files && ! archive->command->propAddCanUpdate)
- && ! (add_after_opening && ! window->priv->update_dropped_files && ! archive->command->propAddCanReplace)
- && ! (extract_after_opening && !archive->command->propCanExtractAll));
-#endif
-}
-
-
static void
menu_item_select_cb (GtkMenuItem *proxy,
FrWindow *window)
@@ -5366,36 +5465,6 @@ fr_window_construct (FrWindow *window)
/* Initialize Data. */
- window->archive = fr_archive_new ();
- g_signal_connect (G_OBJECT (window->archive),
- "start",
- G_CALLBACK (action_started),
- window);
- g_signal_connect (G_OBJECT (window->archive),
- "done",
- G_CALLBACK (action_performed),
- window);
- g_signal_connect (G_OBJECT (window->archive),
- "progress",
- G_CALLBACK (fr_window_progress_cb),
- window);
- g_signal_connect (G_OBJECT (window->archive),
- "message",
- G_CALLBACK (fr_window_message_cb),
- window);
- g_signal_connect (G_OBJECT (window->archive),
- "stoppable",
- G_CALLBACK (fr_window_stoppable_cb),
- window);
- g_signal_connect (G_OBJECT (window->archive),
- "working_archive",
- G_CALLBACK (fr_window_working_archive_cb),
- window);
-
- fr_archive_set_fake_load_func (window->archive,
- fr_window_fake_load,
- window);
-
window->priv->sort_method = g_settings_get_enum (window->priv->settings_listing, PREF_LISTING_SORT_METHOD);
window->priv->sort_type = g_settings_get_enum (window->priv->settings_listing, PREF_LISTING_SORT_TYPE);
@@ -5909,12 +5978,45 @@ fr_window_new (void)
static void
-fr_window_set_archive_uri (FrWindow *window,
+_fr_window_set_archive (FrWindow *window,
+ FrArchive *archive)
+{
+ if (window->archive != NULL) {
+ g_signal_handlers_disconnect_by_data (window->archive, window);
+ g_object_unref (window->archive);
+ }
+
+ window->archive = _g_object_ref (archive);
+
+ if (window->archive == NULL)
+ return;
+
+ g_signal_connect (G_OBJECT (window->archive),
+ "progress",
+ G_CALLBACK (fr_archive_progress_cb),
+ window);
+ g_signal_connect (G_OBJECT (window->archive),
+ "message",
+ G_CALLBACK (fr_archive_message_cb),
+ window);
+ g_signal_connect (G_OBJECT (window->archive),
+ "stoppable",
+ G_CALLBACK (fr_archive_stoppable_cb),
+ window);
+ g_signal_connect (G_OBJECT (window->archive),
+ "working_archive",
+ G_CALLBACK (fr_window_working_archive_cb),
+ window);
+}
+
+
+static void
+_fr_window_set_archive_uri (FrWindow *window,
const char *uri)
{
if (window->priv->archive_uri != NULL)
- g_free (window->priv->archive_uri);
- window->priv->archive_uri = g_strdup (uri);
+ g_free (window->priv->archive_uri);
+ window->priv->archive_uri = g_strdup (uri);
}
@@ -5922,30 +6024,101 @@ gboolean
fr_window_archive_new (FrWindow *window,
const char *uri)
{
- g_return_val_if_fail (window != NULL, FALSE);
+ GFile *file;
+ FrArchive *archive;
- if (! fr_archive_create (window->archive, uri)) {
- GtkWindow *file_sel = g_object_get_data (G_OBJECT (window), "fr_file_sel");
+ g_return_val_if_fail (window != NULL, FALSE);
+
+ file = g_file_new_for_uri (uri);
+ archive = fr_archive_create (file);
+ if (archive != NULL) {
+ fr_window_archive_close (window);
+ _fr_window_set_archive (window, archive);
+ _fr_window_set_archive_uri (window, uri);
+ window->priv->archive_present = TRUE;
+ window->priv->archive_new = TRUE;
+ }
+
+ g_object_unref (archive);
+ g_object_unref (file);
+
+ return archive != NULL;
+
+ /* FIXME: libarchive */
+#if 0
+
+ if (! fr_archive_create (window->archive, uri)) {
+ GtkWindow *file_sel = g_object_get_data (G_OBJECT (window), "fr_file_sel");
window->priv->load_error_parent_window = file_sel;
fr_archive_action_completed (window->archive,
FR_ACTION_CREATING_NEW_ARCHIVE,
- FR_PROC_ERROR_GENERIC,
+ FR_ERROR_GENERIC,
_("Archive type not supported."));
return FALSE;
}
- fr_window_set_archive_uri (window, uri);
+ _fr_window_set_archive_uri (window, uri);
window->priv->archive_present = TRUE;
window->priv->archive_new = TRUE;
fr_archive_action_completed (window->archive,
FR_ACTION_CREATING_NEW_ARCHIVE,
- FR_PROC_ERROR_NONE,
+ FR_ERROR_NONE,
NULL);
return TRUE;
+#endif
+}
+
+
+static void
+archive_load_ready_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ FrWindow *window = user_data;
+ GError *error = NULL;
+
+ fr_archive_operation_finish (FR_ARCHIVE (source_object), result, &error);
+ _archive_operation_completed (window, FR_ACTION_LISTING_CONTENT, error);
+
+ _g_error_free (error);
+}
+
+
+static void
+fr_window_archive_load (FrWindow *window)
+{
+ fr_archive_load (window->archive,
+ window->priv->password,
+ window->priv->cancellable,
+ archive_load_ready_cb,
+ window);
+}
+
+
+static void
+archive_open_ready_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ FrWindow *window = user_data;
+ FrArchive *archive;
+ GError *error = NULL;
+
+ archive = fr_archive_open_finish (G_FILE (source_object), result, &error);
+ if (archive == NULL) {
+ _archive_operation_completed (window, FR_ACTION_LOADING_ARCHIVE, error);
+ g_error_free (error);
+ return;
+ }
+
+ _fr_window_set_archive (window, archive);
+ fr_window_archive_load (window);
+
+ g_object_unref (archive);
}
@@ -5955,6 +6128,7 @@ fr_window_archive_open (FrWindow *current_window,
GtkWindow *parent)
{
FrWindow *window = current_window;
+ GFile *file;
if (current_window->priv->archive_present)
window = (FrWindow *) fr_window_new ();
@@ -5962,9 +6136,7 @@ fr_window_archive_open (FrWindow *current_window,
g_return_val_if_fail (window != NULL, FALSE);
fr_window_archive_close (window);
-
- fr_window_set_archive_uri (window, uri);
- window->priv->archive_present = FALSE;
+ _fr_window_set_archive_uri (window, uri);
window->priv->give_focus_to_the_list = TRUE;
window->priv->load_error_parent_window = parent;
@@ -5973,7 +6145,10 @@ fr_window_archive_open (FrWindow *current_window,
g_strdup (window->priv->archive_uri),
(GFreeFunc) g_free);
- fr_archive_load (window->archive, window->priv->archive_uri, window->priv->password);
+ file = g_file_new_for_uri (window->priv->archive_uri);
+ fr_archive_open (file, window->priv->cancellable, archive_open_ready_cb, window);
+
+ g_object_unref (file);
return window;
}
@@ -5992,9 +6167,10 @@ fr_window_archive_close (FrWindow *window)
window->priv->copy_data = NULL;
fr_window_set_password (window, NULL);
- fr_window_set_volume_size(window, 0);
+ fr_window_set_volume_size (window, 0);
fr_window_history_clear (window);
+ _fr_window_set_archive (window, NULL);
window->priv->archive_new = FALSE;
window->priv->archive_present = FALSE;
@@ -6076,6 +6252,157 @@ save_as_data_free (SaveAsData *sdata)
}
+#if 0 /* FIXME: libarchive */
+
+
+static void
+convert__action_performed (FrArchive *archive,
+ FrAction action,
+ FrError *error,
+ gpointer data)
+{
+ FrWindow *window = data;
+
+#ifdef DEBUG
+ debug (DEBUG_INFO, "%s [CONVERT::DONE] (FR::Window)\n", action_names[action]);
+#endif
+
+ if ((action == FR_ACTION_GETTING_FILE_LIST) || (action == FR_ACTION_ADDING_FILES)) {
+ fr_window_stop_activity_mode (window);
+ fr_window_pop_message (window);
+ close_progress_dialog (window, FALSE);
+ }
+
+ if (action != FR_ACTION_ADDING_FILES)
+ return;
+
+ _handle_archive_operation_error (window, archive, action, error);
+
+ if (error->type == FR_ERROR_NONE)
+ open_progress_dialog_with_open_archive (window);
+
+ _g_path_remove_directory (window->priv->convert_data.temp_dir);
+ _fr_window_convert_data_free (window, FALSE);
+
+ fr_window_update_sensitivity (window);
+ fr_window_update_statusbar_list_info (window);
+}
+
+
+#endif
+
+
+#if 0
+
+
+if (error != NULL) {
+ /* FIXME
+ if (window->priv->convert_data.converting) {
+ _g_path_remove_directory (window->priv->convert_data.temp_dir);
+ _fr_window_convert_data_free (window, TRUE);
+ }
+ */
+ break;
+}
+/* FIXME
+if (window->priv->convert_data.converting) {
+ char *source_dir;
+
+ source_dir = g_filename_to_uri (window->priv->convert_data.temp_dir, NULL, NULL);
+ fr_archive_add_with_wildcard (window->priv->convert_data.new_archive,
+ "*",
+ NULL,
+ NULL,
+ source_dir,
+ NULL,
+ FALSE,
+ TRUE,
+ window->priv->convert_data.password,
+ window->priv->convert_data.encrypt_header,
+ window->priv->compression,
+ window->priv->convert_data.volume_size);
+ g_free (source_dir);
+}
+else */ {
+ if (window->priv->ask_to_open_destination_after_extraction)
+ open_progress_dialog_with_open_destination (window);
+ else
+ close_progress_dialog (window, FALSE);
+}
+
+
+#endif
+
+
+static void
+archive_add_ready_for_conversion_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ FrWindow *window = user_data;
+ GError *error = NULL;
+
+ fr_archive_operation_finish (FR_ARCHIVE (source_object), result, &error);
+
+ fr_window_stop_activity_mode (window);
+ fr_window_pop_message (window);
+ close_progress_dialog (window, FALSE);
+
+ if (error == NULL)
+ open_progress_dialog_with_open_archive (window);
+ else
+ _handle_archive_operation_error (window,
+ window->priv->convert_data.new_archive,
+ FR_ACTION_ADDING_FILES,
+ error,
+ NULL,
+ NULL);
+
+ _g_path_remove_directory (window->priv->convert_data.temp_dir);
+ _fr_window_convert_data_free (window, FALSE);
+
+ fr_window_update_sensitivity (window);
+ fr_window_update_statusbar_list_info (window);
+}
+
+
+static void
+archive_extraction_ready_for_convertion_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ FrWindow *window = user_data;
+ GError *error = NULL;
+ char *source_dir;
+
+ if (! fr_archive_operation_finish (FR_ARCHIVE (source_object), result, &error)) {
+ _g_path_remove_directory (window->priv->convert_data.temp_dir);
+ _fr_window_convert_data_free (window, TRUE);
+ _archive_operation_completed (window, FR_ACTION_EXTRACTING_FILES, error);
+ return;
+ }
+
+ source_dir = g_filename_to_uri (window->priv->convert_data.temp_dir, NULL, NULL);
+ fr_archive_add_with_wildcard (window->priv->convert_data.new_archive,
+ "*",
+ NULL,
+ NULL,
+ source_dir,
+ NULL,
+ FALSE,
+ TRUE,
+ window->priv->convert_data.password,
+ window->priv->convert_data.encrypt_header,
+ window->priv->compression,
+ window->priv->convert_data.volume_size,
+ window->priv->cancellable,
+ archive_add_ready_for_conversion_cb,
+ window);
+
+ g_free (source_dir);
+}
+
+
void
fr_window_archive_save_as (FrWindow *window,
const char *uri,
@@ -6083,17 +6410,22 @@ fr_window_archive_save_as (FrWindow *window,
gboolean encrypt_header,
guint volume_size)
{
+ GFile *file;
+
g_return_if_fail (window != NULL);
g_return_if_fail (uri != NULL);
g_return_if_fail (window->archive != NULL);
- fr_window_convert_data_free (window, TRUE);
+ _fr_window_convert_data_free (window, TRUE);
window->priv->convert_data.new_file = g_strdup (uri);
/* create the new archive */
- window->priv->convert_data.new_archive = fr_archive_new ();
- if (! fr_archive_create (window->priv->convert_data.new_archive, uri)) {
+ file = g_file_new_for_uri (uri);
+ window->priv->convert_data.new_archive = fr_archive_create (file);
+ g_object_unref (file);
+
+ if (window->priv->convert_data.new_archive == NULL) {
GtkWidget *d;
char *utf8_name;
char *message;
@@ -6113,14 +6445,9 @@ fr_window_archive_save_as (FrWindow *window,
g_free (message);
- g_object_unref (window->priv->convert_data.new_archive);
- window->priv->convert_data.new_archive = NULL;
-
return;
}
- g_return_if_fail (window->priv->convert_data.new_archive->command != NULL);
-
if (password != NULL) {
window->priv->convert_data.password = g_strdup (password);
window->priv->convert_data.encrypt_header = encrypt_header;
@@ -6135,30 +6462,21 @@ fr_window_archive_save_as (FrWindow *window,
(GFreeFunc) save_as_data_free);
g_signal_connect (G_OBJECT (window->priv->convert_data.new_archive),
- "start",
- G_CALLBACK (action_started),
- window);
- g_signal_connect (G_OBJECT (window->priv->convert_data.new_archive),
- "done",
- G_CALLBACK (convert__action_performed),
- window);
- g_signal_connect (G_OBJECT (window->priv->convert_data.new_archive),
"progress",
- G_CALLBACK (fr_window_progress_cb),
+ G_CALLBACK (fr_archive_progress_cb),
window);
g_signal_connect (G_OBJECT (window->priv->convert_data.new_archive),
"message",
- G_CALLBACK (fr_window_message_cb),
+ G_CALLBACK (fr_archive_message_cb),
window);
g_signal_connect (G_OBJECT (window->priv->convert_data.new_archive),
"stoppable",
- G_CALLBACK (fr_window_stoppable_cb),
+ G_CALLBACK (fr_archive_stoppable_cb),
window);
window->priv->convert_data.converting = TRUE;
window->priv->convert_data.temp_dir = _g_path_get_temp_work_dir (NULL);
- fr_process_clear (window->archive->process);
fr_archive_extract_to_local (window->archive,
NULL,
window->priv->convert_data.temp_dir,
@@ -6166,8 +6484,10 @@ fr_window_archive_save_as (FrWindow *window,
TRUE,
FALSE,
FALSE,
- window->priv->password);
- fr_process_start (window->archive->process);
+ window->priv->password,
+ window->priv->cancellable,
+ archive_extraction_ready_for_convertion_cb,
+ window);
}
@@ -6180,14 +6500,31 @@ fr_window_archive_reload (FrWindow *window)
return;
if (window->priv->archive_new)
return;
+ if (window->archive == NULL)
+ return;
- fr_archive_reload (window->archive, window->priv->password);
+ fr_window_archive_load (window);
}
/**/
+static void
+archive_add_files_ready_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ FrWindow *window = user_data;
+ GError *error = NULL;
+
+ fr_archive_operation_finish (FR_ARCHIVE (source_object), result, &error);
+ _archive_operation_completed (window, FR_ACTION_ADDING_FILES, error);
+
+ _g_error_free (error);
+}
+
+
void
fr_window_archive_add_files (FrWindow *window,
GList *file_list, /* GFile list */
@@ -6225,10 +6562,14 @@ fr_window_archive_add_files (FrWindow *window,
base_uri,
fr_window_get_current_location (window),
update,
+ FALSE,
window->priv->password,
window->priv->encrypt_header,
window->priv->compression,
- window->priv->volume_size);
+ window->priv->volume_size,
+ window->priv->cancellable,
+ archive_add_files_ready_cb,
+ window);
g_free (base_uri);
_g_string_list_free (files);
@@ -6258,7 +6599,10 @@ fr_window_archive_add_with_wildcard (FrWindow *window,
window->priv->password,
window->priv->encrypt_header,
window->priv->compression,
- window->priv->volume_size);
+ window->priv->volume_size,
+ window->priv->cancellable,
+ archive_add_files_ready_cb,
+ window);
}
@@ -6277,7 +6621,10 @@ fr_window_archive_add_directory (FrWindow *window,
window->priv->password,
window->priv->encrypt_header,
window->priv->compression,
- window->priv->volume_size);
+ window->priv->volume_size,
+ window->priv->cancellable,
+ archive_add_files_ready_cb,
+ window);
}
@@ -6296,7 +6643,10 @@ fr_window_archive_add_items (FrWindow *window,
window->priv->password,
window->priv->encrypt_header,
window->priv->compression,
- window->priv->volume_size);
+ window->priv->volume_size,
+ window->priv->cancellable,
+ archive_add_files_ready_cb,
+ window);
}
@@ -6313,7 +6663,25 @@ fr_window_archive_add_dropped_items (FrWindow *window,
window->priv->password,
window->priv->encrypt_header,
window->priv->compression,
- window->priv->volume_size);
+ window->priv->volume_size,
+ window->priv->cancellable,
+ archive_add_files_ready_cb,
+ window);
+}
+
+
+static void
+archive_remove_ready_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ FrWindow *window = user_data;
+ GError *error = NULL;
+
+ fr_archive_operation_finish (FR_ARCHIVE (source_object), result, &error);
+ _archive_operation_completed (window, FR_ACTION_DELETING_FILES, error);
+
+ _g_error_free (error);
}
@@ -6322,14 +6690,16 @@ fr_window_archive_remove (FrWindow *window,
GList *file_list)
{
fr_window_clipboard_remove_file_list (window, file_list);
-
- fr_process_clear (window->archive->process);
- fr_archive_remove (window->archive, file_list, window->priv->compression);
- fr_process_start (window->archive->process);
+ fr_archive_remove (window->archive,
+ file_list,
+ window->priv->compression,
+ window->priv->cancellable,
+ archive_remove_ready_cb,
+ window);
}
-/* -- window_archive_extract -- */
+/* -- fr_window_archive_extract -- */
static ExtractData*
@@ -6387,95 +6757,6 @@ extract_data_free (ExtractData *edata)
}
-static gboolean
-archive_is_encrypted (FrWindow *window,
- GList *file_list)
-{
- gboolean encrypted = FALSE;
-
- if (file_list == NULL) {
- int i;
-
- for (i = 0; ! encrypted && i < window->archive->command->files->len; i++) {
- FileData *fdata = g_ptr_array_index (window->archive->command->files, i);
-
- if (fdata->encrypted)
- encrypted = TRUE;
- }
- }
- else {
-
- GHashTable *file_hash;
- int i;
- GList *scan;
-
- file_hash = g_hash_table_new (g_str_hash, g_str_equal);
- for (i = 0; i < window->archive->command->files->len; i++) {
- FileData *fdata = g_ptr_array_index (window->archive->command->files, i);
- g_hash_table_insert (file_hash, fdata->original_path, fdata);
- }
-
- for (scan = file_list; ! encrypted && scan; scan = scan->next) {
- char *filename = scan->data;
- FileData *fdata;
-
- fdata = g_hash_table_lookup (file_hash, filename);
- g_return_val_if_fail (fdata != NULL, FALSE);
-
- if (fdata->encrypted)
- encrypted = TRUE;
- }
-
- g_hash_table_destroy (file_hash);
- }
-
- return encrypted;
-}
-
-
-void
-fr_window_archive_extract_here (FrWindow *window,
- gboolean skip_older,
- gboolean overwrite,
- gboolean junk_paths)
-{
- ExtractData *edata;
-
- edata = extract_data_new (NULL,
- NULL,
- NULL,
- skip_older,
- overwrite,
- junk_paths,
- TRUE,
- FALSE);
- fr_window_set_current_batch_action (window,
- FR_BATCH_ACTION_EXTRACT,
- edata,
- (GFreeFunc) extract_data_free);
-
- if (archive_is_encrypted (window, NULL) && (window->priv->password == NULL)) {
- dlg_ask_password (window);
- return;
- }
-
- window->priv->ask_to_open_destination_after_extraction = edata->ask_to_open_destination;
-
- fr_process_clear (window->archive->process);
- if (fr_archive_extract_here (window->archive,
- edata->skip_older,
- edata->overwrite,
- edata->junk_paths,
- window->priv->password))
- {
- fr_process_start (window->archive->process);
- }
-}
-
-
-/* -- fr_window_archive_extract -- */
-
-
typedef struct {
FrWindow *window;
ExtractData *edata;
@@ -6489,12 +6770,26 @@ typedef struct {
static void
+archive_extraction_ready_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ FrWindow *window = user_data;
+ GError *error = NULL;
+
+ fr_archive_operation_finish (FR_ARCHIVE (source_object), result, &error);
+ _archive_operation_completed (window, FR_ACTION_EXTRACTING_FILES, error);
+
+ _g_error_free (error);
+}
+
+
+static void
_fr_window_archive_extract_from_edata (FrWindow *window,
ExtractData *edata)
{
window->priv->ask_to_open_destination_after_extraction = edata->ask_to_open_destination;
- fr_process_clear (window->archive->process);
fr_archive_extract (window->archive,
edata->file_list,
edata->extract_to_dir,
@@ -6502,8 +6797,10 @@ _fr_window_archive_extract_from_edata (FrWindow *window,
edata->skip_older,
edata->overwrite == FR_OVERWRITE_YES,
edata->junk_paths,
- window->priv->password);
- fr_process_start (window->archive->process);
+ window->priv->password,
+ window->priv->cancellable,
+ archive_extraction_ready_cb,
+ window);
}
@@ -6622,22 +6919,68 @@ _fr_window_ask_overwrite_dialog (OverwriteData *odata)
g_object_unref (info);
g_object_unref (file);
- return;
+ return;
+ }
+
+ g_object_unref (info);
+ g_object_unref (file);
+ }
+
+ if (do_not_extract) {
+ fr_window_stop_batch (odata->window);
+ g_free (odata);
+ return;
+ }
+
+ odata->edata->overwrite = FR_OVERWRITE_YES;
+ _fr_window_archive_extract_from_edata (odata->window, odata->edata);
+ g_free (odata);
+}
+
+
+static gboolean
+archive_is_encrypted (FrWindow *window,
+ GList *file_list)
+{
+ gboolean encrypted = FALSE;
+
+ if (file_list == NULL) {
+ int i;
+
+ for (i = 0; ! encrypted && i < window->archive->files->len; i++) {
+ FileData *fdata = g_ptr_array_index (window->archive->files, i);
+
+ if (fdata->encrypted)
+ encrypted = TRUE;
+ }
+ }
+ else {
+
+ GHashTable *file_hash;
+ int i;
+ GList *scan;
+
+ file_hash = g_hash_table_new (g_str_hash, g_str_equal);
+ for (i = 0; i < window->archive->files->len; i++) {
+ FileData *fdata = g_ptr_array_index (window->archive->files, i);
+ g_hash_table_insert (file_hash, fdata->original_path, fdata);
}
- g_object_unref (info);
- g_object_unref (file);
- }
+ for (scan = file_list; ! encrypted && scan; scan = scan->next) {
+ char *filename = scan->data;
+ FileData *fdata;
- if (do_not_extract) {
- fr_window_stop_batch (odata->window);
- g_free (odata);
- return;
+ fdata = g_hash_table_lookup (file_hash, filename);
+ g_return_val_if_fail (fdata != NULL, FALSE);
+
+ if (fdata->encrypted)
+ encrypted = TRUE;
+ }
+
+ g_hash_table_destroy (file_hash);
}
- odata->edata->overwrite = FR_OVERWRITE_YES;
- _fr_window_archive_extract_from_edata (odata->window, odata->edata);
- g_free (odata);
+ return encrypted;
}
@@ -6761,6 +7104,66 @@ fr_window_archive_extract (FrWindow *window,
}
+/* -- fr_window_archive_extract_here -- */
+
+
+void
+fr_window_archive_extract_here (FrWindow *window,
+ gboolean skip_older,
+ gboolean overwrite,
+ gboolean junk_paths)
+{
+ ExtractData *edata;
+
+ edata = extract_data_new (NULL,
+ NULL,
+ NULL,
+ skip_older,
+ overwrite,
+ junk_paths,
+ TRUE,
+ FALSE);
+ fr_window_set_current_batch_action (window,
+ FR_BATCH_ACTION_EXTRACT,
+ edata,
+ (GFreeFunc) extract_data_free);
+
+ if (archive_is_encrypted (window, NULL) && (window->priv->password == NULL)) {
+ dlg_ask_password (window);
+ return;
+ }
+
+ window->priv->ask_to_open_destination_after_extraction = edata->ask_to_open_destination;
+
+ fr_archive_extract_here (window->archive,
+ edata->skip_older,
+ edata->overwrite,
+ edata->junk_paths,
+ window->priv->password,
+ window->priv->cancellable,
+ archive_extraction_ready_cb,
+ window);
+}
+
+
+/* -- fr_window_archive_test -- */
+
+
+static void
+archive_test_ready_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ FrWindow *window = user_data;
+ GError *error = NULL;
+
+ fr_archive_operation_finish (FR_ARCHIVE (source_object), result, &error);
+ _archive_operation_completed (window, FR_ACTION_TESTING_ARCHIVE, error);
+
+ _g_error_free (error);
+}
+
+
void
fr_window_archive_test (FrWindow *window)
{
@@ -6768,7 +7171,11 @@ fr_window_archive_test (FrWindow *window)
FR_BATCH_ACTION_TEST,
NULL,
NULL);
- fr_archive_test (window->archive, window->priv->password);
+ fr_archive_test (window->archive,
+ window->priv->password,
+ window->priv->cancellable,
+ archive_test_ready_cb,
+ window);
}
@@ -7020,11 +7427,15 @@ fr_window_stop (FrWindow *window)
if (! window->priv->stoppable)
return;
+ g_cancellable_cancel (window->priv->cancellable);
+
+ /* FIXME: libarchive
if (window->priv->activity_ref > 0)
fr_archive_stop (window->archive);
if (window->priv->convert_data.converting)
- fr_window_convert_data_free (window, TRUE);
+ _fr_window_convert_data_free (window, TRUE);
+ */
}
@@ -7173,7 +7584,10 @@ fr_window_view_last_output (FrWindow *window,
/**/
gtk_text_buffer_get_iter_at_offset (text_buffer, &iter, 0);
- scan = window->archive->process->out.raw;
+ if (FR_IS_COMMAND (window->archive))
+ scan = fr_command_get_last_output (FR_COMMAND (window->archive));
+ else
+ scan = NULL;
for (; scan; scan = scan->next) {
char *line = scan->data;
char *utf8_line;
@@ -7252,6 +7666,21 @@ rename_data_free (RenameData *rdata)
static void
+archive_rename_ready_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ FrWindow *window = user_data;
+ GError *error = NULL;
+
+ fr_archive_operation_finish (FR_ARCHIVE (source_object), result, &error);
+ _archive_operation_completed (window, FR_ACTION_ADDING_FILES /* FIXME: FR_ACTION_RENAME_FILES ? */, error);
+
+ _g_error_free (error);
+}
+
+
+static void
rename_selection (FrWindow *window,
const char *path_to_rename,
const char *old_name,
@@ -7261,14 +7690,8 @@ rename_selection (FrWindow *window,
gboolean dir_in_archive,
const char *original_path)
{
- FrArchive *archive = window->archive;
RenameData *rdata;
- char *tmp_dir;
GList *file_list;
- gboolean added_dir;
- char *new_dirname;
- GList *new_file_list;
- GList *scan;
rdata = rename_data_new (path_to_rename,
old_name,
@@ -7282,128 +7705,31 @@ rename_selection (FrWindow *window,
rdata,
(GFreeFunc) rename_data_free);
- fr_process_clear (archive->process);
-
- tmp_dir = _g_path_get_temp_work_dir (NULL);
+ g_object_set (window->archive,
+ "compression", window->priv->compression,
+ "encrypt_header", window->priv->encrypt_header,
+ "password", window->priv->password,
+ "volume_size", window->priv->volume_size,
+ NULL);
if (is_dir)
file_list = get_dir_list_from_path (window, rdata->path_to_rename);
else
file_list = g_list_append (NULL, g_strdup (rdata->path_to_rename));
-
- fr_archive_extract_to_local (archive,
- file_list,
- tmp_dir,
- NULL,
- FALSE,
- TRUE,
- FALSE,
- window->priv->password);
-
- /* temporarily add the dir to rename to the list if it's stored in the
- * archive, this way it will be removed from the archive... */
- added_dir = FALSE;
- if (is_dir && dir_in_archive && ! g_list_find_custom (file_list, original_path, (GCompareFunc) strcmp)) {
- file_list = g_list_prepend (file_list, g_strdup (original_path));
- added_dir = TRUE;
- }
-
- fr_archive_remove (archive, file_list, window->priv->compression);
fr_window_clipboard_remove_file_list (window, file_list);
+ fr_archive_rename (window->archive,
+ file_list,
+ old_name,
+ new_name,
+ current_dir,
+ is_dir,
+ dir_in_archive,
+ original_path,
+ window->priv->cancellable,
+ archive_rename_ready_cb,
+ window);
- /* ...and remove it from the list again */
- if (added_dir) {
- GList *tmp;
-
- tmp = file_list;
- file_list = g_list_remove_link (file_list, tmp);
-
- g_free (tmp->data);
- g_list_free (tmp);
- }
-
- /* rename the files. */
-
- new_dirname = g_build_filename (rdata->current_dir + 1, rdata->new_name, "/", NULL);
- new_file_list = NULL;
- if (rdata->is_dir) {
- char *old_path;
- char *new_path;
-
- old_path = g_build_filename (tmp_dir, rdata->current_dir, rdata->old_name, NULL);
- new_path = g_build_filename (tmp_dir, rdata->current_dir, rdata->new_name, NULL);
-
- fr_process_begin_command (archive->process, "mv");
- fr_process_add_arg (archive->process, "-f");
- fr_process_add_arg (archive->process, old_path);
- fr_process_add_arg (archive->process, new_path);
- fr_process_end_command (archive->process);
-
- g_free (old_path);
- g_free (new_path);
- }
-
- for (scan = file_list; scan; scan = scan->next) {
- const char *current_dir_relative = rdata->current_dir + 1;
- const char *filename = (char*) scan->data;
- char *old_path = NULL, *common = NULL, *new_path = NULL;
- char *new_filename;
-
- old_path = g_build_filename (tmp_dir, filename, NULL);
-
- if (strlen (filename) > (strlen (rdata->current_dir) + strlen (rdata->old_name)))
- common = g_strdup (filename + strlen (rdata->current_dir) + strlen (rdata->old_name));
- new_path = g_build_filename (tmp_dir, rdata->current_dir, rdata->new_name, common, NULL);
-
- if (! rdata->is_dir) {
- fr_process_begin_command (archive->process, "mv");
- fr_process_add_arg (archive->process, "-f");
- fr_process_add_arg (archive->process, old_path);
- fr_process_add_arg (archive->process, new_path);
- fr_process_end_command (archive->process);
- }
-
- new_filename = g_build_filename (current_dir_relative, rdata->new_name, common, NULL);
- new_file_list = g_list_prepend (new_file_list, new_filename);
-
- g_free (old_path);
- g_free (common);
- g_free (new_path);
- }
- new_file_list = g_list_reverse (new_file_list);
-
- /* FIXME: this is broken for tar archives.
- if (is_dir && dir_in_archive && ! g_list_find_custom (new_file_list, new_dirname, (GCompareFunc) strcmp))
- new_file_list = g_list_prepend (new_file_list, g_build_filename (rdata->current_dir + 1, rdata->new_name, NULL));
- */
-
- fr_archive_add (archive,
- new_file_list,
- tmp_dir,
- NULL,
- FALSE,
- FALSE,
- window->priv->password,
- window->priv->encrypt_header,
- window->priv->compression,
- window->priv->volume_size);
-
- g_free (new_dirname);
- _g_string_list_free (new_file_list);
_g_string_list_free (file_list);
-
- /* remove the tmp dir */
-
- fr_process_begin_command (archive->process, "rm");
- fr_process_set_working_dir (archive->process, g_get_tmp_dir ());
- fr_process_set_sticky (archive->process, TRUE);
- fr_process_add_arg (archive->process, "-rf");
- fr_process_add_arg (archive->process, tmp_dir);
- fr_process_end_command (archive->process);
-
- fr_process_start (archive->process);
-
- g_free (tmp_dir);
}
@@ -7456,8 +7782,8 @@ name_is_present (FrWindow *window,
new_filename = g_build_filename (current_dir, new_name, NULL);
new_filename_l = strlen (new_filename);
- for (i = 0; i < window->archive->command->files->len; i++) {
- FileData *fdata = g_ptr_array_index (window->archive->command->files, i);
+ for (i = 0; i < window->archive->files->len; i++) {
+ FileData *fdata = g_ptr_array_index (window->archive->files, i);
const char *filename = fdata->full_path;
if ((strncmp (filename, new_filename, new_filename_l) == 0)
@@ -7609,6 +7935,9 @@ fr_window_rename_selection (FrWindow *window,
}
+/* -- fr_window_paste_selection -- */
+
+
static void
fr_clipboard_get (GtkClipboard *clipboard,
GtkSelectionData *selection_data,
@@ -7684,7 +8013,7 @@ fr_window_get_selection (FrWindow *window,
static void
fr_window_copy_or_cut_selection (FrWindow *window,
- FRClipboardOp op,
+ FrClipboardOp op,
gboolean from_sidebar)
{
GList *files;
@@ -7728,138 +8057,169 @@ fr_window_cut_selection (FrWindow *window,
}
-static gboolean
-always_fake_load (FrArchive *archive,
- gpointer data)
-{
- return TRUE;
-}
+/* -- fr_window_paste_from_clipboard_data -- */
static void
-add_pasted_files (FrWindow *window,
- FrClipboardData *data)
+_paste_from_archive_operation_completed (FrWindow *window,
+ FrAction action,
+ GError *error)
{
- const char *current_dir_relative = data->current_dir + 1;
- GList *scan;
- GList *new_file_list = NULL;
-
- if (window->priv->password_for_paste != NULL) {
- g_free (window->priv->password_for_paste);
- window->priv->password_for_paste = NULL;
- }
+#ifdef DEBUG
+ debug (DEBUG_INFO, "%s [DONE] (FR::Window)\n", action_names[action]);
+#endif
- fr_process_clear (window->archive->process);
- for (scan = data->files; scan; scan = scan->next) {
- const char *old_name = (char*) scan->data;
- char *new_name = g_build_filename (current_dir_relative, old_name + strlen (data->base_dir) - 1, NULL);
+ fr_window_stop_activity_mode (window);
+ fr_window_pop_message (window);
+ close_progress_dialog (window, FALSE);
- /* skip folders */
+ if (error->code == FR_ERROR_ASK_PASSWORD) {
+ dlg_ask_password_for_paste_operation (window);
+ return;
+ }
- if ((strcmp (old_name, new_name) != 0)
- && (old_name[strlen (old_name) - 1] != '/'))
- {
- fr_process_begin_command (window->archive->process, "mv");
- fr_process_set_working_dir (window->archive->process, data->tmp_dir);
- fr_process_add_arg (window->archive->process, "-f");
- if (old_name[0] == '/')
- old_name = old_name + 1;
- fr_process_add_arg (window->archive->process, old_name);
- fr_process_add_arg (window->archive->process, new_name);
- fr_process_end_command (window->archive->process);
- }
+ /* FIXME: do not use this function !! */
+ _archive_operation_completed (window, FR_ACTION_EXTRACTING_FILES, error);
- new_file_list = g_list_prepend (new_file_list, new_name);
+ if (error->code != FR_ERROR_NONE) {
+ fr_clipboard_data_unref (window->priv->clipboard_data);
+ window->priv->clipboard_data = NULL;
}
+}
- fr_archive_add (window->archive,
- new_file_list,
- data->tmp_dir,
- NULL,
- FALSE,
- FALSE,
- window->priv->password,
- window->priv->encrypt_header,
- window->priv->compression,
- window->priv->volume_size);
- _g_string_list_free (new_file_list);
+static void
+paste_from_archive_paste_clipboard_ready_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ FrWindow *window = user_data;
+ GError *error;
- /* remove the tmp dir */
+ fr_archive_operation_finish (FR_ARCHIVE (source_object), result, &error);
+ _paste_from_archive_operation_completed (window, FR_ACTION_ADDING_FILES, error);
- fr_process_begin_command (window->archive->process, "rm");
- fr_process_set_working_dir (window->archive->process, g_get_tmp_dir ());
- fr_process_set_sticky (window->archive->process, TRUE);
- fr_process_add_arg (window->archive->process, "-rf");
- fr_process_add_arg (window->archive->process, data->tmp_dir);
- fr_process_end_command (window->archive->process);
+ fr_clipboard_data_unref (window->priv->clipboard_data);
+ window->priv->clipboard_data = NULL;
- fr_process_start (window->archive->process);
+ _g_error_free (error);
}
static void
-copy_from_archive_action_performed_cb (FrArchive *archive,
- FrAction action,
- FrProcError *error,
- gpointer data)
+add_pasted_files (FrWindow *window,
+ FrClipboardData *data)
{
- FrWindow *window = data;
+ if (window->priv->password_for_paste != NULL) {
+ g_free (window->priv->password_for_paste);
+ window->priv->password_for_paste = NULL;
+ }
-#ifdef DEBUG
- debug (DEBUG_INFO, "%s [DONE] (FR::Window)\n", action_names[action]);
-#endif
+ fr_archive_paste_clipboard (window->archive,
+ data->archive_uri,
+ data->archive_password,
+ window->priv->encrypt_header,
+ window->priv->compression,
+ window->priv->volume_size,
+ data->op,
+ data->base_dir,
+ data->files,
+ data->tmp_dir,
+ data->current_dir,
+ window->priv->cancellable,
+ paste_from_archive_paste_clipboard_ready_cb,
+ window);
+}
- fr_window_stop_activity_mode (window);
- fr_window_pop_message (window);
- close_progress_dialog (window, FALSE);
- if (error->type == FR_PROC_ERROR_ASK_PASSWORD) {
- dlg_ask_password_for_paste_operation (window);
+static void
+paste_from_archive_remove_ready_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ FrWindow *window = user_data;
+ GError *error;
+
+ if (! fr_archive_operation_finish (FR_ARCHIVE (source_object), result, &error)) {
+ _paste_from_archive_operation_completed (window, FR_ACTION_DELETING_FILES, error);
+ g_error_free (error);
return;
}
- (void) handle_errors (window, archive, action, error);
+ add_pasted_files (window, window->priv->clipboard_data);
+}
+
- if (error->type != FR_PROC_ERROR_NONE) {
- fr_clipboard_data_unref (window->priv->clipboard_data);
- window->priv->clipboard_data = NULL;
+static void
+paste_from_archive_extract_ready_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ FrWindow *window = user_data;
+ GError *error;
+
+ if (! fr_archive_operation_finish (FR_ARCHIVE (source_object), result, &error)) {
+ _paste_from_archive_operation_completed (window, FR_ACTION_EXTRACTING_FILES, error);
+ g_error_free (error);
return;
}
- switch (action) {
- case FR_ACTION_LISTING_CONTENT:
- fr_process_clear (window->priv->copy_from_archive->process);
- fr_archive_extract_to_local (window->priv->copy_from_archive,
- window->priv->clipboard_data->files,
- window->priv->clipboard_data->tmp_dir,
- NULL,
- FALSE,
- TRUE,
- FALSE,
- window->priv->clipboard_data->archive_password);
- fr_process_start (window->priv->copy_from_archive->process);
- break;
+ if (window->priv->clipboard_data->op == FR_CLIPBOARD_OP_CUT)
+ fr_archive_remove (window->priv->copy_from_archive,
+ window->priv->clipboard_data->files,
+ window->priv->compression,
+ window->priv->cancellable,
+ paste_from_archive_remove_ready_cb,
+ window);
+ else
+ add_pasted_files (window, window->priv->clipboard_data);
+}
- case FR_ACTION_EXTRACTING_FILES:
- if (window->priv->clipboard_data->op == FR_CLIPBOARD_OP_CUT) {
- fr_process_clear (window->priv->copy_from_archive->process);
- fr_archive_remove (window->priv->copy_from_archive,
- window->priv->clipboard_data->files,
- window->priv->compression);
- fr_process_start (window->priv->copy_from_archive->process);
- }
- else
- add_pasted_files (window, window->priv->clipboard_data);
- break;
- case FR_ACTION_DELETING_FILES:
- add_pasted_files (window, window->priv->clipboard_data);
- break;
+static void
+paste_from_archive_open_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ FrWindow *window = user_data;
+ GError *error;
- default:
- break;
+ _g_object_unref (window->priv->copy_from_archive);
+ window->priv->copy_from_archive = fr_archive_open_finish (G_FILE (source_object), result, &error);
+ if (window->priv->copy_from_archive == NULL) {
+ _paste_from_archive_operation_completed (window, FR_ACTION_LOADING_ARCHIVE, error);
+ g_error_free (error);
+ return;
}
+
+ g_signal_connect (G_OBJECT (window->priv->copy_from_archive),
+ "start",
+ G_CALLBACK (action_started),
+ window);
+ g_signal_connect (G_OBJECT (window->priv->copy_from_archive),
+ "progress",
+ G_CALLBACK (fr_archive_progress_cb),
+ window);
+ g_signal_connect (G_OBJECT (window->priv->copy_from_archive),
+ "message",
+ G_CALLBACK (fr_archive_message_cb),
+ window);
+ g_signal_connect (G_OBJECT (window->priv->copy_from_archive),
+ "stoppable",
+ G_CALLBACK (fr_archive_stoppable_cb),
+ window);
+
+ fr_archive_extract_to_local (window->priv->copy_from_archive,
+ window->priv->clipboard_data->files,
+ window->priv->clipboard_data->tmp_dir,
+ NULL,
+ FALSE,
+ TRUE,
+ FALSE,
+ window->priv->clipboard_data->archive_password,
+ window->priv->cancellable,
+ paste_from_archive_extract_ready_cb,
+ window);
}
@@ -7870,6 +8230,7 @@ fr_window_paste_from_clipboard_data (FrWindow *window,
const char *current_dir_relative;
GHashTable *created_dirs;
GList *scan;
+ GFile *file;
if (window->priv->password_for_paste != NULL)
fr_clipboard_data_set_password (data, window->priv->password_for_paste);
@@ -7911,33 +8272,13 @@ fr_window_paste_from_clipboard_data (FrWindow *window,
/**/
- if (window->priv->copy_from_archive == NULL) {
- window->priv->copy_from_archive = fr_archive_new ();
- g_signal_connect (G_OBJECT (window->priv->copy_from_archive),
- "start",
- G_CALLBACK (action_started),
- window);
- g_signal_connect (G_OBJECT (window->priv->copy_from_archive),
- "done",
- G_CALLBACK (copy_from_archive_action_performed_cb),
- window);
- g_signal_connect (G_OBJECT (window->priv->copy_from_archive),
- "progress",
- G_CALLBACK (fr_window_progress_cb),
- window);
- g_signal_connect (G_OBJECT (window->priv->copy_from_archive),
- "message",
- G_CALLBACK (fr_window_message_cb),
- window);
- g_signal_connect (G_OBJECT (window->priv->copy_from_archive),
- "stoppable",
- G_CALLBACK (fr_window_stoppable_cb),
- window);
- fr_archive_set_fake_load_func (window->priv->copy_from_archive, always_fake_load, NULL);
- }
- fr_archive_load (window->priv->copy_from_archive,
- data->archive_uri,
- data->archive_password);
+ file = g_file_new_for_uri (data->archive_uri);
+ fr_archive_open (file,
+ window->priv->cancellable,
+ paste_from_archive_open_cb,
+ window);
+
+ g_object_unref (file);
}
@@ -8114,6 +8455,9 @@ open_files_data_free (OpenFilesData *odata)
}
+/* -- -- */
+
+
void
fr_window_update_dialog_closed (FrWindow *window)
{
@@ -8121,10 +8465,32 @@ fr_window_update_dialog_closed (FrWindow *window)
}
+static void
+update_files_ready_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ FrWindow *window = user_data;
+ GError *error;
+
+ fr_archive_operation_finish (FR_ARCHIVE (source_object), result, &error);
+
+ fr_window_stop_activity_mode (window);
+ fr_window_pop_message (window);
+
+ /* FIXME: do not use this function !!! */
+ _handle_archive_operation_error (window, window->archive, FR_ACTION_ADDING_FILES, error, NULL, NULL);
+
+ _g_error_free (error);
+}
+
+
gboolean
fr_window_update_files (FrWindow *window,
- GList *file_list)
+ GList *open_file_list)
{
+ GList *file_list;
+ GList *dir_list;
GList *scan;
if (window->priv->activity_ref > 0)
@@ -8133,27 +8499,25 @@ fr_window_update_files (FrWindow *window,
if (window->archive->read_only)
return FALSE;
- fr_process_clear (window->archive->process);
+ file_list = NULL;
+ dir_list = NULL;
+ for (scan = open_file_list; scan; scan = scan->next) {
+ OpenFile *open_file = scan->data;
- for (scan = file_list; scan; scan = scan->next) {
- OpenFile *file = scan->data;
- GList *local_file_list;
-
- local_file_list = g_list_append (NULL, file->path);
- fr_archive_add (window->archive,
- local_file_list,
- file->temp_dir,
- "/",
- FALSE,
- FALSE,
- window->priv->password,
- window->priv->encrypt_header,
- window->priv->compression,
- window->priv->volume_size);
- g_list_free (local_file_list);
+ file_list = g_list_prepend (file_list, open_file->path);
+ dir_list = g_list_prepend (dir_list, open_file->temp_dir);
}
- fr_process_start (window->archive->process);
+ fr_archive_update_open_files (window->archive,
+ file_list,
+ dir_list,
+ window->priv->password,
+ window->priv->encrypt_header,
+ window->priv->compression,
+ window->priv->volume_size,
+ window->priv->cancellable,
+ update_files_ready_cb,
+ window);
return TRUE;
}
@@ -8316,22 +8680,20 @@ fr_window_open_extracted_files (OpenFilesData *odata)
static void
-fr_window_open_files__extract_done_cb (FrArchive *archive,
- FrAction action,
- FrProcError *error,
- gpointer callback_data)
+open_files_extract_ready_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
{
- OpenFilesData *odata = callback_data;
+ OpenFilesData *odata = user_data;
+ GError *error;
- g_signal_handlers_disconnect_matched (G_OBJECT (archive),
- G_SIGNAL_MATCH_DATA,
- 0,
- 0, NULL,
- 0,
- odata);
+ if (! fr_archive_operation_finish (FR_ARCHIVE (source_object), result, &error)) {
+ /* FIXME: do not use this function!!! */
+ _archive_operation_completed (odata->window, FR_ACTION_EXTRACTING_FILES, error);
+ g_error_free (error);
+ }
- if (error->type == FR_PROC_ERROR_NONE)
- fr_window_open_extracted_files (odata);
+ fr_window_open_extracted_files (odata);
}
@@ -8351,12 +8713,6 @@ fr_window_open_files (FrWindow *window,
odata,
(GFreeFunc) open_files_data_free);
- g_signal_connect (G_OBJECT (window->archive),
- "done",
- G_CALLBACK (fr_window_open_files__extract_done_cb),
- odata);
-
- fr_process_clear (window->archive->process);
fr_archive_extract_to_local (window->archive,
odata->file_list,
odata->cdata->temp_dir,
@@ -8364,8 +8720,10 @@ fr_window_open_files (FrWindow *window,
FALSE,
TRUE,
FALSE,
- window->priv->password);
- fr_process_start (window->archive->process);
+ window->priv->password,
+ window->priv->cancellable,
+ open_files_extract_ready_cb,
+ odata);
}
@@ -8702,29 +9060,30 @@ fr_window_exec_batch_action (FrWindow *window,
void
fr_window_reset_current_batch_action (FrWindow *window)
{
- FRBatchAction *adata = &window->priv->current_batch_action;
+ FRBatchAction *action = &window->priv->current_batch_action;
- if ((adata->data != NULL) && (adata->free_func != NULL))
- (*adata->free_func) (adata->data);
- adata->type = FR_BATCH_ACTION_NONE;
- adata->data = NULL;
- adata->free_func = NULL;
+ if ((action->data != NULL) && (action->free_func != NULL))
+ (*action->free_func) (action->data);
+ action->type = FR_BATCH_ACTION_NONE;
+ action->data = NULL;
+ action->free_func = NULL;
}
void
fr_window_set_current_batch_action (FrWindow *window,
- FrBatchActionType action,
+ FrBatchActionType action_type,
void *data,
GFreeFunc free_func)
{
- FRBatchAction *adata = &window->priv->current_batch_action;
+ FRBatchAction *action;
fr_window_reset_current_batch_action (window);
- adata->type = action;
- adata->data = data;
- adata->free_func = free_func;
+ action = &window->priv->current_batch_action;
+ action->type = action_type;
+ action->data = data;
+ action->free_func = free_func;
}
@@ -8796,7 +9155,6 @@ fr_window_start_batch (FrWindow *window)
window->priv->batch_mode = TRUE;
window->priv->batch_action = window->priv->batch_action_list;
- window->archive->can_create_compressed_file = window->priv->batch_adding_one_file;
fr_window_exec_current_batch_action (window);
}
@@ -8809,7 +9167,6 @@ fr_window_stop_batch (FrWindow *window)
return;
window->priv->extract_interact_use_default_dir = FALSE;
- window->archive->can_create_compressed_file = FALSE;
if (window->priv->batch_mode) {
if (! window->priv->showing_error_dialog) {
diff --git a/src/fr-window.h b/src/fr-window.h
index 13a4ad5..723ce29 100644
--- a/src/fr-window.h
+++ b/src/fr-window.h
@@ -75,15 +75,15 @@ typedef enum {
#define FR_IS_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), FR_TYPE_WINDOW))
#define FR_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), FR_TYPE_WINDOW, FrWindowClass))
-typedef struct _FrWindow FrWindow;
-typedef struct _FrWindowClass FrWindowClass;
-typedef struct _FrWindowPrivateData FrWindowPrivateData;
+typedef struct _FrWindow FrWindow;
+typedef struct _FrWindowClass FrWindowClass;
+typedef struct _FrWindowPrivate FrWindowPrivate;
struct _FrWindow
{
GtkApplicationWindow __parent;
+ FrWindowPrivate *priv;
FrArchive *archive;
- FrWindowPrivateData *priv;
};
struct _FrWindowClass
@@ -101,221 +101,220 @@ struct _FrWindowClass
GError *error);
};
-GType fr_window_get_type (void);
-GtkWidget * fr_window_new (void);
-void fr_window_close (FrWindow *window);
+GType fr_window_get_type (void);
+GtkWidget * fr_window_new (void);
+void fr_window_close (FrWindow *window);
/* archive operations */
-gboolean fr_window_archive_new (FrWindow *window,
- const char *uri);
-FrWindow * fr_window_archive_open (FrWindow *window,
- const char *uri,
- GtkWindow *parent);
-void fr_window_archive_close (FrWindow *window);
-const char *fr_window_get_archive_uri (FrWindow *window);
-const char *fr_window_get_paste_archive_uri (FrWindow *window);
-gboolean fr_window_archive_is_present (FrWindow *window);
-void fr_window_archive_save_as (FrWindow *window,
- const char *filename,
- const char *password,
- gboolean encrypt_header,
- guint volume_size);
-void fr_window_archive_reload (FrWindow *window);
-void fr_window_archive_add_files (FrWindow *window,
- GList *file_list, /* GFile list */
- gboolean update);
-void fr_window_archive_add_with_wildcard (FrWindow *window,
- const char *include_files,
- const char *exclude_files,
- const char *exclude_folders,
- const char *base_dir,
- const char *dest_dir,
- gboolean update,
- gboolean follow_links);
-void fr_window_archive_add_directory (FrWindow *window,
- const char *directory,
- const char *base_dir,
- const char *dest_dir,
- gboolean update);
-void fr_window_archive_add_items (FrWindow *window,
- GList *dir_list,
- const char *base_dir,
- const char *dest_dir,
- gboolean update);
-void fr_window_archive_add_dropped_items (FrWindow *window,
- GList *item_list,
- gboolean update);
-void fr_window_archive_remove (FrWindow *window,
- GList *file_list);
-void fr_window_archive_extract (FrWindow *window,
- GList *file_list,
- const char *extract_to_dir,
- const char *base_dir,
- gboolean skip_older,
- FrOverwrite overwrite,
- gboolean junk_paths,
- gboolean ask_to_open_destination);
-void fr_window_archive_extract_here (FrWindow *window,
- gboolean skip_older,
- gboolean overwrite,
- gboolean junk_paths);
-void fr_window_archive_test (FrWindow *window);
+gboolean fr_window_archive_new (FrWindow *window,
+ const char *uri);
+FrWindow * fr_window_archive_open (FrWindow *window,
+ const char *uri,
+ GtkWindow *parent);
+void fr_window_archive_close (FrWindow *window);
+const char * fr_window_get_archive_uri (FrWindow *window);
+const char * fr_window_get_paste_archive_uri (FrWindow *window);
+gboolean fr_window_archive_is_present (FrWindow *window);
+void fr_window_archive_save_as (FrWindow *window,
+ const char *filename,
+ const char *password,
+ gboolean encrypt_header,
+ guint volume_size);
+void fr_window_archive_reload (FrWindow *window);
+void fr_window_archive_add_files (FrWindow *window,
+ GList *file_list, /* GFile list */
+ gboolean update);
+void fr_window_archive_add_with_wildcard (FrWindow *window,
+ const char *include_files,
+ const char *exclude_files,
+ const char *exclude_folders,
+ const char *base_dir,
+ const char *dest_dir,
+ gboolean update,
+ gboolean follow_links);
+void fr_window_archive_add_directory (FrWindow *window,
+ const char *directory,
+ const char *base_dir,
+ const char *dest_dir,
+ gboolean update);
+void fr_window_archive_add_items (FrWindow *window,
+ GList *dir_list,
+ const char *base_dir,
+ const char *dest_dir,
+ gboolean update);
+void fr_window_archive_add_dropped_items (FrWindow *window,
+ GList *item_list,
+ gboolean update);
+void fr_window_archive_remove (FrWindow *window,
+ GList *file_list);
+void fr_window_archive_extract (FrWindow *window,
+ GList *file_list,
+ const char *extract_to_dir,
+ const char *base_dir,
+ gboolean skip_older,
+ FrOverwrite overwrite,
+ gboolean junk_paths,
+ gboolean ask_to_open_destination);
+void fr_window_archive_extract_here (FrWindow *window,
+ gboolean skip_older,
+ gboolean overwrite,
+ gboolean junk_paths);
+void fr_window_archive_test (FrWindow *window);
/**/
-void fr_window_set_password (FrWindow *window,
- const char *password);
-void fr_window_set_password_for_paste (FrWindow *window,
- const char *password);
-const char *fr_window_get_password (FrWindow *window);
-void fr_window_set_encrypt_header (FrWindow *window,
- gboolean encrypt_header);
-gboolean fr_window_get_encrypt_header (FrWindow *window);
-void fr_window_set_compression (FrWindow *window,
- FrCompression compression);
-FrCompression fr_window_get_compression (FrWindow *window);
-void fr_window_set_volume_size (FrWindow *window,
- guint volume_size);
-guint fr_window_get_volume_size (FrWindow *window);
+void fr_window_set_password (FrWindow *window,
+ const char *password);
+void fr_window_set_password_for_paste (FrWindow *window,
+ const char *password);
+const char * fr_window_get_password (FrWindow *window);
+void fr_window_set_encrypt_header (FrWindow *window,
+ gboolean encrypt_header);
+gboolean fr_window_get_encrypt_header (FrWindow *window);
+void fr_window_set_compression (FrWindow *window,
+ FrCompression compression);
+FrCompression fr_window_get_compression (FrWindow *window);
+void fr_window_set_volume_size (FrWindow *window,
+ guint volume_size);
+guint fr_window_get_volume_size (FrWindow *window);
/**/
-void fr_window_go_to_location (FrWindow *window,
- const char *path,
- gboolean force_update);
-const char*fr_window_get_current_location (FrWindow *window);
-void fr_window_go_up_one_level (FrWindow *window);
-void fr_window_go_back (FrWindow *window);
-void fr_window_go_forward (FrWindow *window);
-void fr_window_current_folder_activated (FrWindow *window,
- gboolean from_sidebar);
-void fr_window_set_list_mode (FrWindow *window,
- FrWindowListMode list_mode);
+void fr_window_go_to_location (FrWindow *window,
+ const char *path,
+ gboolean force_update);
+const char * fr_window_get_current_location (FrWindow *window);
+void fr_window_go_up_one_level (FrWindow *window);
+void fr_window_go_back (FrWindow *window);
+void fr_window_go_forward (FrWindow *window);
+void fr_window_current_folder_activated (FrWindow *window,
+ gboolean from_sidebar);
+void fr_window_set_list_mode (FrWindow *window,
+ FrWindowListMode
+ list_mode);
/**/
-void fr_window_update_list_order (FrWindow *window);
-GList * fr_window_get_file_list_selection (FrWindow *window,
- gboolean recursive,
- gboolean *has_dirs);
-GList * fr_window_get_file_list_from_path_list (FrWindow *window,
- GList *path_list,
- gboolean *has_dirs);
-GList * fr_window_get_file_list_pattern (FrWindow *window,
- const char *pattern);
-int fr_window_get_n_selected_files (FrWindow *window);
-GList * fr_window_get_folder_tree_selection (FrWindow *window,
- gboolean recursive,
- gboolean *has_dirs);
-GList * fr_window_get_selection (FrWindow *window,
- gboolean from_sidebar,
- char **return_base_dir);
-GtkTreeModel *
- fr_window_get_list_store (FrWindow *window);
-void fr_window_find (FrWindow *window);
-void fr_window_select_all (FrWindow *window);
-void fr_window_unselect_all (FrWindow *window);
-void fr_window_set_sort_type (FrWindow *window,
- GtkSortType sort_type);
+void fr_window_update_list_order (FrWindow *window);
+GList * fr_window_get_file_list_selection (FrWindow *window,
+ gboolean recursive,
+ gboolean *has_dirs);
+GList * fr_window_get_file_list_from_path_list (FrWindow *window,
+ GList *path_list,
+ gboolean *has_dirs);
+GList * fr_window_get_file_list_pattern (FrWindow *window,
+ const char *pattern);
+int fr_window_get_n_selected_files (FrWindow *window);
+GList * fr_window_get_folder_tree_selection (FrWindow *window,
+ gboolean recursive,
+ gboolean *has_dirs);
+GList * fr_window_get_selection (FrWindow *window,
+ gboolean from_sidebar,
+ char **return_base_dir);
+GtkTreeModel * fr_window_get_list_store (FrWindow *window);
+void fr_window_find (FrWindow *window);
+void fr_window_select_all (FrWindow *window);
+void fr_window_unselect_all (FrWindow *window);
+void fr_window_set_sort_type (FrWindow *window,
+ GtkSortType sort_type);
/**/
-void fr_window_rename_selection (FrWindow *window,
- gboolean from_sidebar);
-void fr_window_cut_selection (FrWindow *window,
- gboolean from_sidebar);
-void fr_window_copy_selection (FrWindow *window,
- gboolean from_sidebar);
-void fr_window_paste_selection (FrWindow *window,
- gboolean from_sidebar);
+void fr_window_rename_selection (FrWindow *window,
+ gboolean from_sidebar);
+void fr_window_cut_selection (FrWindow *window,
+ gboolean from_sidebar);
+void fr_window_copy_selection (FrWindow *window,
+ gboolean from_sidebar);
+void fr_window_paste_selection (FrWindow *window,
+ gboolean from_sidebar);
/**/
-void fr_window_stop (FrWindow *window);
-void fr_window_start_activity_mode (FrWindow *window);
-void fr_window_stop_activity_mode (FrWindow *window);
+void fr_window_stop (FrWindow *window);
+void fr_window_start_activity_mode (FrWindow *window);
+void fr_window_stop_activity_mode (FrWindow *window);
/**/
-void fr_window_view_last_output (FrWindow *window,
- const char *title);
-
-void fr_window_open_files (FrWindow *window,
- GList *file_list,
- gboolean ask_application);
-void fr_window_open_files_with_command (FrWindow *window,
- GList *file_list,
- char *command);
-void fr_window_open_files_with_application (FrWindow *window,
- GList *file_list,
- GAppInfo *app);
-gboolean fr_window_update_files (FrWindow *window,
- GList *file_list);
-void fr_window_update_columns_visibility (FrWindow *window);
-void fr_window_update_history_list (FrWindow *window);
-void fr_window_set_default_dir (FrWindow *window,
- const char *default_dir,
- gboolean freeze);
-void fr_window_set_open_default_dir (FrWindow *window,
- const char *default_dir);
-const char *fr_window_get_open_default_dir (FrWindow *window);
-void fr_window_set_add_default_dir (FrWindow *window,
- const char *default_dir);
-const char *fr_window_get_add_default_dir (FrWindow *window);
-void fr_window_set_extract_default_dir (FrWindow *window,
- const char *default_dir,
- gboolean freeze);
-const char *fr_window_get_extract_default_dir (FrWindow *window);
-void fr_window_push_message (FrWindow *window,
- const char *msg);
-void fr_window_pop_message (FrWindow *window);
-void fr_window_set_toolbar_visibility (FrWindow *window,
- gboolean value);
-void fr_window_set_statusbar_visibility (FrWindow *window,
- gboolean value);
-void fr_window_set_folders_visibility (FrWindow *window,
- gboolean value);
-void fr_window_use_progress_dialog (FrWindow *window,
- gboolean value);
+void fr_window_view_last_output (FrWindow *window,
+ const char *title);
+void fr_window_open_files (FrWindow *window,
+ GList *file_list,
+ gboolean ask_application);
+void fr_window_open_files_with_command (FrWindow *window,
+ GList *file_list,
+ char *command);
+void fr_window_open_files_with_application (FrWindow *window,
+ GList *file_list,
+ GAppInfo *app);
+gboolean fr_window_update_files (FrWindow *window,
+ GList *file_list);
+void fr_window_update_columns_visibility (FrWindow *window);
+void fr_window_update_history_list (FrWindow *window);
+void fr_window_set_default_dir (FrWindow *window,
+ const char *default_dir,
+ gboolean freeze);
+void fr_window_set_open_default_dir (FrWindow *window,
+ const char *default_dir);
+const char * fr_window_get_open_default_dir (FrWindow *window);
+void fr_window_set_add_default_dir (FrWindow *window,
+ const char *default_dir);
+const char * fr_window_get_add_default_dir (FrWindow *window);
+void fr_window_set_extract_default_dir (FrWindow *window,
+ const char *default_dir,
+ gboolean freeze);
+const char * fr_window_get_extract_default_dir (FrWindow *window);
+void fr_window_push_message (FrWindow *window,
+ const char *msg);
+void fr_window_pop_message (FrWindow *window);
+void fr_window_set_toolbar_visibility (FrWindow *window,
+ gboolean value);
+void fr_window_set_statusbar_visibility (FrWindow *window,
+ gboolean value);
+void fr_window_set_folders_visibility (FrWindow *window,
+ gboolean value);
+void fr_window_use_progress_dialog (FrWindow *window,
+ gboolean value);
/* batch mode procedures. */
-void fr_window_new_batch (FrWindow *window,
- const char *title);
-const char *
- fr_window_get_batch_title (FrWindow *window);
-void fr_window_set_current_batch_action (FrWindow *window,
- FrBatchActionType action,
- void *data,
- GFreeFunc free_func);
-void fr_window_reset_current_batch_action (FrWindow *window);
-void fr_window_restart_current_batch_action (FrWindow *window);
-void fr_window_append_batch_action (FrWindow *window,
- FrBatchActionType action,
- void *data,
- GFreeFunc free_func);
-void fr_window_start_batch (FrWindow *window);
-void fr_window_stop_batch (FrWindow *window);
-void fr_window_resume_batch (FrWindow *window);
-gboolean fr_window_is_batch_mode (FrWindow *window);
-void fr_window_set_batch__extract (FrWindow *window,
- const char *filename,
- const char *dest_dir);
-void fr_window_set_batch__extract_here (FrWindow *window,
- const char *filename);
-void fr_window_set_batch__add (FrWindow *window,
- const char *archive,
- GList *file_list);
-void fr_window_destroy_with_error_dialog (FrWindow *window);
+void fr_window_new_batch (FrWindow *window,
+ const char *title);
+const char * fr_window_get_batch_title (FrWindow *window);
+void fr_window_set_current_batch_action (FrWindow *window,
+ FrBatchActionType
+ action,
+ void *data,
+ GFreeFunc free_func);
+void fr_window_reset_current_batch_action (FrWindow *window);
+void fr_window_restart_current_batch_action (FrWindow *window);
+void fr_window_append_batch_action (FrWindow *window,
+ FrBatchActionType
+ action,
+ void *data,
+ GFreeFunc free_func);
+void fr_window_start_batch (FrWindow *window);
+void fr_window_stop_batch (FrWindow *window);
+void fr_window_resume_batch (FrWindow *window);
+gboolean fr_window_is_batch_mode (FrWindow *window);
+void fr_window_set_batch__extract (FrWindow *window,
+ const char *filename,
+ const char *dest_dir);
+void fr_window_set_batch__extract_here (FrWindow *window,
+ const char *filename);
+void fr_window_set_batch__add (FrWindow *window,
+ const char *archive,
+ GList *file_list);
+void fr_window_destroy_with_error_dialog (FrWindow *window);
/**/
-gboolean fr_window_file_list_drag_data_get (FrWindow *window,
- GdkDragContext *context,
- GtkSelectionData *selection_data,
- GList *path_list);
-
-void fr_window_update_dialog_closed (FrWindow *window);
+gboolean fr_window_file_list_drag_data_get (FrWindow *window,
+ GdkDragContext *context,
+ GtkSelectionData *selection_data,
+ GList *path_list);
+void fr_window_update_dialog_closed (FrWindow *window);
#endif /* FR_WINDOW_H */
diff --git a/src/glib-utils.c b/src/glib-utils.c
index b3715c6..59e8690 100644
--- a/src/glib-utils.c
+++ b/src/glib-utils.c
@@ -50,6 +50,29 @@ _g_object_unref (gpointer object)
}
+void
+_g_clear_object (gpointer p)
+{
+ gpointer *object_p = (gpointer *) p;
+
+ if ((object_p != NULL) && (*object_p != NULL)) {
+ g_object_unref (*object_p);
+ *object_p = NULL;
+ }
+}
+
+
+/* error */
+
+
+void
+_g_error_free (GError *error)
+{
+ if (error != NULL)
+ g_error_free (error);
+}
+
+
/* string */
diff --git a/src/glib-utils.h b/src/glib-utils.h
index 7fd180b..a5a584d 100644
--- a/src/glib-utils.h
+++ b/src/glib-utils.h
@@ -48,6 +48,11 @@
gpointer _g_object_ref (gpointer object);
void _g_object_unref (gpointer object);
+void _g_clear_object (gpointer p);
+
+/* error */
+
+void _g_error_free (GError *error);
/* string */
diff --git a/src/main.c b/src/main.c
index 1bb014e..dc18820 100644
--- a/src/main.c
+++ b/src/main.c
@@ -200,16 +200,16 @@ client_save_state (EggSMClient *client,
window = window->next, i++)
{
FrWindow *session = window->data;
- gchar *key;
+ gchar *key;
key = g_strdup_printf ("archive%d", i);
- if ((session->archive == NULL) || (session->archive->file == NULL)) {
+ if ((session->archive == NULL) || (fr_archive_get_file (session->archive) == NULL)) {
g_key_file_set_string (state, "Session", key, "");
}
else {
gchar *uri;
- uri = g_file_get_uri (session->archive->file);
+ uri = g_file_get_uri (fr_archive_get_file (session->archive));
g_key_file_set_string (state, "Session", key, uri);
g_free (uri);
}
@@ -310,7 +310,7 @@ handle_method_call (GDBusConnection *connection,
GDBusMethodInvocation *invocation,
gpointer user_data)
{
- update_registered_commands_capabilities ();
+ update_registered_archives_capabilities ();
if (g_strcmp0 (method_name, "GetSupportedTypes") == 0) {
char *action;
diff --git a/src/rar-utils.c b/src/rar-utils.c
index c1a35e0..3abb7ce 100644
--- a/src/rar-utils.c
+++ b/src/rar-utils.c
@@ -125,7 +125,7 @@ rar_check_multi_volume (FrCommand *comm)
parent = g_file_get_parent (file);
volume_file = g_file_get_child (parent, volume_name);
- fr_command_set_multi_volume (comm, volume_file);
+ fr_archive_set_multi_volume (FR_ARCHIVE (comm), volume_file);
g_object_unref (volume_file);
g_object_unref (parent);
diff --git a/src/typedefs.h b/src/typedefs.h
index 28c78ab..a857e5f 100644
--- a/src/typedefs.h
+++ b/src/typedefs.h
@@ -29,6 +29,11 @@
#define ADD_FOLDER_OPTIONS_DIR "file-roller/options"
+typedef enum {
+ FR_CLIPBOARD_OP_CUT,
+ FR_CLIPBOARD_OP_COPY
+} FrClipboardOp;
+
typedef enum { /*< skip >*/
FR_WINDOW_SORT_BY_NAME = 0,
FR_WINDOW_SORT_BY_SIZE = 1,
@@ -56,44 +61,23 @@ typedef enum {
} FrOverwrite;
typedef enum { /*< skip >*/
- FR_PROC_ERROR_NONE,
- FR_PROC_ERROR_GENERIC,
- FR_PROC_ERROR_COMMAND_ERROR,
- FR_PROC_ERROR_COMMAND_NOT_FOUND,
- FR_PROC_ERROR_EXITED_ABNORMALLY,
- FR_PROC_ERROR_SPAWN,
- FR_PROC_ERROR_STOPPED,
- FR_PROC_ERROR_ASK_PASSWORD,
- FR_PROC_ERROR_MISSING_VOLUME,
- FR_PROC_ERROR_IO_CHANNEL,
- FR_PROC_ERROR_BAD_CHARSET,
- FR_PROC_ERROR_UNSUPPORTED_FORMAT
-} FrProcErrorType;
-
-typedef struct {
- FrProcErrorType type;
- int status;
- GError *gerror;
-} FrProcError;
-
-typedef enum { /*< skip >*/
- FR_COMMAND_CAN_DO_NOTHING = 0,
- FR_COMMAND_CAN_READ = 1 << 0,
- FR_COMMAND_CAN_WRITE = 1 << 1,
- FR_COMMAND_CAN_ARCHIVE_MANY_FILES = 1 << 2,
- FR_COMMAND_CAN_ENCRYPT = 1 << 3,
- FR_COMMAND_CAN_ENCRYPT_HEADER = 1 << 4,
- FR_COMMAND_CAN_CREATE_VOLUMES = 1 << 5
-} FrCommandCap;
+ FR_ARCHIVE_CAN_DO_NOTHING = 0,
+ FR_ARCHIVE_CAN_READ = 1 << 0,
+ FR_ARCHIVE_CAN_WRITE = 1 << 1,
+ FR_ARCHIVE_CAN_STORE_MANY_FILES = 1 << 2,
+ FR_ARCHIVE_CAN_ENCRYPT = 1 << 3,
+ FR_ARCHIVE_CAN_ENCRYPT_HEADER = 1 << 4,
+ FR_ARCHIVE_CAN_CREATE_VOLUMES = 1 << 5
+} FrArchiveCap;
-#define FR_COMMAND_CAN_READ_WRITE (FR_COMMAND_CAN_READ | FR_COMMAND_CAN_WRITE)
+#define FR_ARCHIVE_CAN_READ_WRITE (FR_ARCHIVE_CAN_READ | FR_ARCHIVE_CAN_WRITE)
-typedef guint8 FrCommandCaps;
+typedef guint8 FrArchiveCaps;
typedef struct {
const char *mime_type;
- FrCommandCaps current_capabilities;
- FrCommandCaps potential_capabilities;
+ FrArchiveCaps current_capabilities;
+ FrArchiveCaps potential_capabilities;
} FrMimeTypeCap;
typedef struct {
@@ -106,13 +90,13 @@ typedef struct {
GType type;
GPtrArray *caps; /* array of FrMimeTypeCap */
GPtrArray *packages; /* array of FrMimeTypePackages */
-} FrRegisteredCommand;
+} FrRegisteredArchive;
typedef struct {
const char *mime_type;
char *default_ext;
char *name;
- FrCommandCaps capabilities;
+ FrArchiveCaps capabilities;
} FrMimeTypeDescription;
typedef struct {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]