summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTing-Wei Lan <lantw44@gmail.com>2013-08-04 17:11:25 +0800
committerLAN-TW <lantw44@gmail.com>2013-08-04 17:16:58 +0800
commit8c0cf46bde30e010a50f39ca906732534bfa466a (patch)
treeb438d9ad311ab9f074b727e78c42aaf18b689369
parent5e5939d1ab9e62f7b7eb33bdf0ce41aa048817a0 (diff)
downloadgsoc2013-libgnome-autoar-8c0cf46bde30e010a50f39ca906732534bfa466a.tar
gsoc2013-libgnome-autoar-8c0cf46bde30e010a50f39ca906732534bfa466a.tar.gz
gsoc2013-libgnome-autoar-8c0cf46bde30e010a50f39ca906732534bfa466a.tar.bz2
gsoc2013-libgnome-autoar-8c0cf46bde30e010a50f39ca906732534bfa466a.tar.lz
gsoc2013-libgnome-autoar-8c0cf46bde30e010a50f39ca906732534bfa466a.tar.xz
gsoc2013-libgnome-autoar-8c0cf46bde30e010a50f39ca906732534bfa466a.tar.zst
gsoc2013-libgnome-autoar-8c0cf46bde30e010a50f39ca906732534bfa466a.zip
Move local variables into objects or smaller blocks
The previous commit modified AutoarExtract; this commit modified AutoarCreate.
-rw-r--r--gnome-autoar/autoar-common.c8
-rw-r--r--gnome-autoar/autoar-common.h4
-rw-r--r--gnome-autoar/autoar-create.c731
-rw-r--r--gnome-autoar/autoar-create.h7
-rw-r--r--tests/test-create.c2
5 files changed, 404 insertions, 348 deletions
diff --git a/gnome-autoar/autoar-common.c b/gnome-autoar/autoar-common.c
index bdb1f7f..39cc554 100644
--- a/gnome-autoar/autoar-common.c
+++ b/gnome-autoar/autoar-common.c
@@ -178,3 +178,11 @@ autoar_common_g_error_new_a (GQuark quark,
archive_error_string (a));
return newerror;
}
+
+GError*
+autoar_common_g_error_new_a_entry (GQuark quark,
+ struct archive *a,
+ struct archive_entry *entry)
+{
+ return autoar_common_g_error_new_a (quark, a, archive_entry_pathname (entry));
+}
diff --git a/gnome-autoar/autoar-common.h b/gnome-autoar/autoar-common.h
index 2867f45..874483e 100644
--- a/gnome-autoar/autoar-common.h
+++ b/gnome-autoar/autoar-common.h
@@ -28,6 +28,7 @@
#define AUTOAR_COMMON_H
#include <archive.h>
+#include <archive_entry.h>
#include <glib.h>
#include <glib-object.h>
@@ -43,5 +44,8 @@ void autoar_common_g_signal_emit (gpointer instance,
GError* autoar_common_g_error_new_a (GQuark quark,
struct archive *a,
const char *pathname);
+GError* autoar_common_g_error_new_a_entry (GQuark quark,
+ struct archive *a,
+ struct archive_entry *entry);
#endif /* AUTOAR_COMMON_H */
diff --git a/gnome-autoar/autoar-create.c b/gnome-autoar/autoar-create.c
index 61c648f..bb181fb 100644
--- a/gnome-autoar/autoar-create.c
+++ b/gnome-autoar/autoar-create.c
@@ -64,12 +64,24 @@ struct _AutoarCreatePrivate
void *buffer;
gssize buffer_size;
GError *error;
+
+ GCancellable *cancellable;
+
+ struct archive *a;
+ struct archive_entry *entry;
+ struct archive_entry_linkresolver *resolver;
+ GHashTable *pathname_to_g_file;
+ char *source_basename_noext;
+
+ int in_thread : 1;
+ int prepend_basename : 1;
};
enum
{
DECIDE_DEST,
PROGRESS,
+ CANCELLED,
COMPLETED,
ERROR,
LAST_SIGNAL
@@ -258,6 +270,18 @@ autoar_create_dispose (GObject *object)
g_clear_object (&(arcreate->priv->arpref));
+ if (arcreate->priv->ostream != NULL) {
+ if (!g_output_stream_is_closed (arcreate->priv->ostream)) {
+ g_output_stream_close (arcreate->priv->ostream, NULL, NULL);
+ }
+ g_object_unref (arcreate->priv->ostream);
+ }
+
+ if (arcreate->priv->pathname_to_g_file != NULL) {
+ g_hash_table_unref (arcreate->priv->pathname_to_g_file);
+ arcreate->priv->pathname_to_g_file = NULL;
+ }
+
G_OBJECT_CLASS (autoar_create_parent_class)->dispose (object);
}
@@ -278,21 +302,38 @@ autoar_create_finalize (GObject *object)
g_free (priv->output);
priv->output = NULL;
- if (priv->ostream != NULL) {
- if (!g_output_stream_is_closed (priv->ostream)) {
- g_output_stream_close (priv->ostream, NULL, NULL);
- }
- g_object_unref (priv->ostream);
- }
-
g_free (priv->buffer);
priv->buffer = NULL;
+ /* If priv->error == NULL, no errors occurs. Therefore, we can safely free
+ * libarchive objects because it will not call the callbacks during the
+ * the process of freeing.
+ * If priv->error != NULL, we must free libarchive objects beforce freeing
+ * priv->error in order to prevent libarchive callbacks from accessing
+ * freed private objects and buffers. */
+ if (priv->a != NULL) {
+ archive_write_free (priv->a);
+ priv->a = NULL;
+ }
+
+ if (priv->entry != NULL) {
+ archive_entry_free (priv->entry);
+ priv->entry = NULL;
+ }
+
+ if (priv->resolver != NULL) {
+ archive_entry_linkresolver_free (priv->resolver);
+ priv->resolver = NULL;
+ }
+
if (priv->error != NULL) {
g_error_free (priv->error);
priv->error = NULL;
}
+ g_free (priv->source_basename_noext);
+ priv->source_basename_noext = NULL;
+
G_OBJECT_CLASS (autoar_create_parent_class)->finalize (object);
}
@@ -374,28 +415,66 @@ libarchive_write_write_cb (struct archive *ar_write,
return write_size;
}
+static inline void
+autoar_create_signal_decide_dest (AutoarCreate *arcreate)
+{
+ autoar_common_g_signal_emit (arcreate, arcreate->priv->in_thread,
+ autoar_create_signals[DECIDE_DEST], 0,
+ arcreate->priv->dest);
+}
+
+static inline void
+autoar_create_signal_progress (AutoarCreate *arcreate)
+{
+ autoar_common_g_signal_emit (arcreate, arcreate->priv->in_thread,
+ autoar_create_signals[PROGRESS], 0,
+ arcreate->priv->completed_size,
+ arcreate->priv->completed_files);
+}
+
+static inline void
+autoar_create_signal_cancelled (AutoarCreate *arcreate)
+{
+ autoar_common_g_signal_emit (arcreate, arcreate->priv->in_thread,
+ autoar_create_signals[CANCELLED], 0);
+
+}
+
+static inline void
+autoar_create_signal_completed (AutoarCreate *arcreate)
+{
+ autoar_common_g_signal_emit (arcreate, arcreate->priv->in_thread,
+ autoar_create_signals[COMPLETED], 0);
+
+}
+
+static inline void
+autoar_create_signal_error (AutoarCreate *arcreate)
+{
+ autoar_common_g_signal_emit (arcreate, arcreate->priv->in_thread,
+ autoar_create_signals[ERROR], 0,
+ arcreate->priv->error);
+}
+
static void
autoar_create_do_write_data (AutoarCreate *arcreate,
- struct archive *a,
struct archive_entry *entry,
- GFile *file,
- gboolean in_thread)
+ GFile *file)
{
int r;
+ AutoarCreatePrivate *priv;
g_debug ("autoar_create_do_write_data: called");
if (arcreate->priv->error != NULL)
return;
- while ((r = archive_write_header (a, entry)) == ARCHIVE_RETRY);
+ priv = arcreate->priv;
+
+ while ((r = archive_write_header (priv->a, entry)) == ARCHIVE_RETRY);
if (r == ARCHIVE_FATAL) {
- if (arcreate->priv->error == NULL)
- arcreate->priv->error = g_error_new (autoar_create_quark,
- archive_errno (a),
- "\'%s\': %s",
- archive_entry_pathname (entry),
- archive_error_string (a));
+ if (priv->error == NULL)
+ priv->error = autoar_common_g_error_new_a_entry (autoar_create_quark, priv->a, entry);
return;
}
@@ -413,30 +492,25 @@ autoar_create_do_write_data (AutoarCreate *arcreate,
written_actual = 0;
written_try = 0;
- istream = (GInputStream*)g_file_read (file, NULL, &(arcreate->priv->error));
+ istream = (GInputStream*)g_file_read (file, NULL, &(priv->error));
if (istream == NULL)
return;
- arcreate->priv->completed_files++;
+ priv->completed_files++;
do {
read_actual = g_input_stream_read (istream,
- arcreate->priv->buffer,
- arcreate->priv->buffer_size,
+ priv->buffer,
+ priv->buffer_size,
NULL,
- &(arcreate->priv->error));
- arcreate->priv->completed_size += read_actual > 0 ? read_actual : 0;
- autoar_common_g_signal_emit (in_thread,
- arcreate,
- autoar_create_signals[PROGRESS],
- 0,
- arcreate->priv->completed_size,
- arcreate->priv->completed_files);
+ &(priv->error));
+ priv->completed_size += read_actual > 0 ? read_actual : 0;
+ autoar_create_signal_progress (arcreate);
if (read_actual > 0) {
written_acc = 0;
written_try = 0;
do {
- written_actual = archive_write_data (a, (const char*)(arcreate->priv->buffer) + written_acc, read_actual);
+ written_actual = archive_write_data (priv->a, (const char*)(priv->buffer) + written_acc, read_actual);
written_acc += written_actual > 0 ? written_actual : 0;
written_try = written_actual ? 0 : written_try + 1;
/* archive_write_data may return zero, so we have to limit the
@@ -453,117 +527,102 @@ autoar_create_do_write_data (AutoarCreate *arcreate,
return;
if (written_actual < 0 || written_try >= ARCHIVE_WRITE_RETRY_TIMES) {
- if (arcreate->priv->error == NULL)
- arcreate->priv->error = g_error_new (autoar_create_quark,
- archive_errno (a),
- "\'%s\': %s",
- archive_entry_pathname (entry),
- archive_error_string (a));
+ if (priv->error == NULL)
+ priv->error = autoar_common_g_error_new_a_entry (autoar_create_quark, priv->a, entry);
return;
}
g_debug ("autoar_create_do_write_data: write data OK");
} else {
g_debug ("autoar_create_do_write_data: no data, return now!");
- arcreate->priv->completed_files++;
- autoar_common_g_signal_emit (in_thread,
- arcreate,
- autoar_create_signals[PROGRESS],
- 0,
- arcreate->priv->completed_size,
- arcreate->priv->completed_files);
+ priv->completed_files++;
+ autoar_create_signal_progress (arcreate);
}
}
static void
autoar_create_do_add_to_archive (AutoarCreate *arcreate,
- struct archive *a,
- struct archive_entry *entry,
- struct archive_entry_linkresolver *resolver,
GFile *root,
- GFile *file,
- const char *basename,
- gboolean prepend_basename,
- gboolean in_thread,
- GHashTable *pathname_to_g_file)
+ GFile *file)
{
+ AutoarCreatePrivate *priv;
GFileInfo *info;
GFileType filetype;
- char *root_basename;
- char *pathname_relative;
- char *pathname;
-
- time_t atime, btime, ctime, mtime;
- long atimeu, btimeu, ctimeu, mtimeu;
- struct archive_entry *sparse;
-
-#ifdef HAVE_STAT
- struct stat filestat;
- char *local_pathname;
-#endif
+ priv = arcreate->priv;
- archive_entry_clear (entry);
+ archive_entry_clear (priv->entry);
info = g_file_query_info (file, "*", G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
NULL, &(arcreate->priv->error));
if (info == NULL)
return;
- switch (archive_format (a)) {
- /* ar format does not support directories */
- case ARCHIVE_FORMAT_AR:
- case ARCHIVE_FORMAT_AR_GNU:
- case ARCHIVE_FORMAT_AR_BSD:
- pathname = g_file_get_basename (file);
- archive_entry_set_pathname (entry, pathname);
- g_free (pathname);
- break;
-
- default:
- root_basename = g_file_get_basename (root);
- pathname_relative = g_file_get_relative_path (root, file);
- pathname = g_strconcat (prepend_basename ? basename : "",
- prepend_basename ? "/" : "",
- root_basename,
- pathname_relative != NULL ? "/" : "",
- pathname_relative != NULL ? pathname_relative : "",
- NULL);
- archive_entry_set_pathname (entry, pathname);
- g_free (root_basename);
- g_free (pathname_relative);
- g_free (pathname);
+ {
+ char *root_basename;
+ char *pathname_relative;
+ char *pathname;
+
+ switch (archive_format (priv->a)) {
+ /* ar format does not support directories */
+ case ARCHIVE_FORMAT_AR:
+ case ARCHIVE_FORMAT_AR_GNU:
+ case ARCHIVE_FORMAT_AR_BSD:
+ pathname = g_file_get_basename (file);
+ archive_entry_set_pathname (priv->entry, pathname);
+ g_free (pathname);
+ break;
+
+ default:
+ root_basename = g_file_get_basename (root);
+ pathname_relative = g_file_get_relative_path (root, file);
+ pathname = g_strconcat (priv->prepend_basename ? priv->source_basename_noext : "",
+ priv->prepend_basename ? "/" : "",
+ root_basename,
+ pathname_relative != NULL ? "/" : "",
+ pathname_relative != NULL ? pathname_relative : "",
+ NULL);
+ archive_entry_set_pathname (priv->entry, pathname);
+ g_free (root_basename);
+ g_free (pathname_relative);
+ g_free (pathname);
+ }
}
- g_debug ("autoar_create_do_add_to_archive: %s", archive_entry_pathname (entry));
+ g_debug ("autoar_create_do_add_to_archive: %s", archive_entry_pathname (priv->entry));
- atime = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_ACCESS);
- btime = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_CREATED);
- ctime = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_CHANGED);
- mtime = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED);
+ {
+ time_t atime, btime, ctime, mtime;
+ long atimeu, btimeu, ctimeu, mtimeu;
- atimeu = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_TIME_ACCESS_USEC);
- btimeu = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_TIME_CREATED_USEC);
- ctimeu = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_TIME_CHANGED_USEC);
- mtimeu = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC);
+ atime = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_ACCESS);
+ btime = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_CREATED);
+ ctime = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_CHANGED);
+ mtime = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED);
- archive_entry_set_atime (entry, atime, atimeu * 1000);
- archive_entry_set_birthtime (entry, btime, btimeu * 1000);
- archive_entry_set_ctime (entry, ctime, ctimeu * 1000);
- archive_entry_set_mtime (entry, mtime, mtimeu * 1000);
+ atimeu = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_TIME_ACCESS_USEC);
+ btimeu = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_TIME_CREATED_USEC);
+ ctimeu = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_TIME_CHANGED_USEC);
+ mtimeu = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC);
- archive_entry_set_uid (entry, g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_UID));
- archive_entry_set_gid (entry, g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_GID));
- archive_entry_set_uname (entry, g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_OWNER_USER));
- archive_entry_set_gname (entry, g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_OWNER_GROUP));
- archive_entry_set_mode (entry, g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_MODE));
+ archive_entry_set_atime (priv->entry, atime, atimeu * 1000);
+ archive_entry_set_birthtime (priv->entry, btime, btimeu * 1000);
+ archive_entry_set_ctime (priv->entry, ctime, ctimeu * 1000);
+ archive_entry_set_mtime (priv->entry, mtime, mtimeu * 1000);
+
+ archive_entry_set_uid (priv->entry, g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_UID));
+ archive_entry_set_gid (priv->entry, g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_GID));
+ archive_entry_set_uname (priv->entry, g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_OWNER_USER));
+ archive_entry_set_gname (priv->entry, g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_OWNER_GROUP));
+ archive_entry_set_mode (priv->entry, g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_MODE));
+ }
- archive_entry_set_size (entry, g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_STANDARD_SIZE));
- archive_entry_set_dev (entry, g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_DEVICE));
- archive_entry_set_ino64 (entry, g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_UNIX_INODE));
- archive_entry_set_nlink (entry, g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_NLINK));
- archive_entry_set_rdev (entry, g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_RDEV));
+ archive_entry_set_size (priv->entry, g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_STANDARD_SIZE));
+ archive_entry_set_dev (priv->entry, g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_DEVICE));
+ archive_entry_set_ino64 (priv->entry, g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_UNIX_INODE));
+ archive_entry_set_nlink (priv->entry, g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_NLINK));
+ archive_entry_set_rdev (priv->entry, g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_RDEV));
filetype = g_file_info_get_file_type (info);
- switch (archive_format (a)) {
+ switch (archive_format (priv->a)) {
case ARCHIVE_FORMAT_AR:
case ARCHIVE_FORMAT_AR_GNU:
case ARCHIVE_FORMAT_AR_BSD:
@@ -590,39 +649,44 @@ autoar_create_do_add_to_archive (AutoarCreate *arcreate,
switch (filetype) {
case G_FILE_TYPE_DIRECTORY:
g_debug ("autoar_create_do_add_to_archive: file type set to DIR");
- archive_entry_set_filetype (entry, AE_IFDIR);
+ archive_entry_set_filetype (priv->entry, AE_IFDIR);
break;
case G_FILE_TYPE_SYMBOLIC_LINK:
g_debug ("autoar_create_do_add_to_archive: file type set to SYMLINK");
- archive_entry_set_filetype (entry, AE_IFLNK);
- archive_entry_set_symlink (entry, g_file_info_get_attribute_byte_string (info, G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET));
+ archive_entry_set_filetype (priv->entry, AE_IFLNK);
+ archive_entry_set_symlink (priv->entry, g_file_info_get_attribute_byte_string (info, G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET));
break;
case G_FILE_TYPE_SPECIAL:
#ifdef HAVE_STAT
- local_pathname = g_file_get_path (file);
- if (local_pathname != NULL && stat (local_pathname, &filestat) >= 0) {
- if (S_ISBLK (filestat.st_mode)) {
- g_debug ("autoar_create_do_add_to_archive: file type set to BLOCK");
- archive_entry_set_filetype (entry, AE_IFBLK);
- } else if (S_ISSOCK (filestat.st_mode)) {
- g_debug ("autoar_create_do_add_to_archive: file type set to SOCKET");
- archive_entry_set_filetype (entry, AE_IFSOCK);
- } else if (S_ISCHR (filestat.st_mode)) {
- g_debug ("autoar_create_do_add_to_archive: file type set to CHAR");
- archive_entry_set_filetype (entry, AE_IFCHR);
- } else if (S_ISFIFO (filestat.st_mode)) {
- g_debug ("autoar_create_do_add_to_archive: file type set to FIFO");
- archive_entry_set_filetype (entry, AE_IFIFO);
+ {
+ struct stat filestat;
+ char *local_pathname;
+
+ local_pathname = g_file_get_path (file);
+ if (local_pathname != NULL && stat (local_pathname, &filestat) >= 0) {
+ if (S_ISBLK (filestat.st_mode)) {
+ g_debug ("autoar_create_do_add_to_archive: file type set to BLOCK");
+ archive_entry_set_filetype (priv->entry, AE_IFBLK);
+ } else if (S_ISSOCK (filestat.st_mode)) {
+ g_debug ("autoar_create_do_add_to_archive: file type set to SOCKET");
+ archive_entry_set_filetype (priv->entry, AE_IFSOCK);
+ } else if (S_ISCHR (filestat.st_mode)) {
+ g_debug ("autoar_create_do_add_to_archive: file type set to CHAR");
+ archive_entry_set_filetype (priv->entry, AE_IFCHR);
+ } else if (S_ISFIFO (filestat.st_mode)) {
+ g_debug ("autoar_create_do_add_to_archive: file type set to FIFO");
+ archive_entry_set_filetype (priv->entry, AE_IFIFO);
+ } else {
+ g_debug ("autoar_create_do_add_to_archive: file type set to REGULAR");
+ archive_entry_set_filetype (priv->entry, AE_IFREG);
+ }
+ g_free (local_pathname);
} else {
g_debug ("autoar_create_do_add_to_archive: file type set to REGULAR");
- archive_entry_set_filetype (entry, AE_IFREG);
+ archive_entry_set_filetype (priv->entry, AE_IFREG);
}
- g_free (local_pathname);
- } else {
- g_debug ("autoar_create_do_add_to_archive: file type set to REGULAR");
- archive_entry_set_filetype (entry, AE_IFREG);
}
break;
@@ -633,34 +697,39 @@ autoar_create_do_add_to_archive (AutoarCreate *arcreate,
case G_FILE_TYPE_REGULAR:
default:
g_debug ("autoar_create_do_add_to_archive: file type set to REGULAR");
- archive_entry_set_filetype (entry, AE_IFREG);
+ archive_entry_set_filetype (priv->entry, AE_IFREG);
break;
}
- g_hash_table_insert (pathname_to_g_file,
- g_strdup (archive_entry_pathname (entry)),
+ g_hash_table_insert (priv->pathname_to_g_file,
+ g_strdup (archive_entry_pathname (priv->entry)),
g_object_ref (file));
- archive_entry_linkify (resolver, &entry, &sparse);
-
- if (entry != NULL) {
- GFile *file_to_read;
- const char *pathname_in_entry;
- pathname_in_entry = archive_entry_pathname (entry);
- file_to_read = g_hash_table_lookup (pathname_to_g_file, pathname_in_entry);
- autoar_create_do_write_data (arcreate, a, entry, file_to_read, in_thread);
- g_hash_table_remove (pathname_to_g_file, pathname_in_entry);
- /* We have registered g_object_unref function to free the GFile object,
- * so we do not have to unref it here. */
- }
+ {
+ struct archive_entry *entry, *sparse;
+
+ entry = priv->entry;
+ archive_entry_linkify (priv->resolver, &entry, &sparse);
+
+ if (entry != NULL) {
+ GFile *file_to_read;
+ const char *pathname_in_entry;
+ pathname_in_entry = archive_entry_pathname (entry);
+ file_to_read = g_hash_table_lookup (priv->pathname_to_g_file, pathname_in_entry);
+ autoar_create_do_write_data (arcreate, entry, file_to_read);
+ g_hash_table_remove (priv->pathname_to_g_file, pathname_in_entry);
+ /* We have registered g_object_unref function to free the GFile object,
+ * so we do not have to unref it here. */
+ }
- if (sparse != NULL) {
- GFile *file_to_read;
- const char *pathname_in_entry;
- pathname_in_entry = archive_entry_pathname (entry);
- file_to_read = g_hash_table_lookup (pathname_to_g_file, pathname_in_entry);
- autoar_create_do_write_data (arcreate, a, sparse, file_to_read, in_thread);
- g_hash_table_remove (pathname_to_g_file, pathname_in_entry);
+ if (sparse != NULL) {
+ GFile *file_to_read;
+ const char *pathname_in_entry;
+ pathname_in_entry = archive_entry_pathname (entry);
+ file_to_read = g_hash_table_lookup (priv->pathname_to_g_file, pathname_in_entry);
+ autoar_create_do_write_data (arcreate, sparse, file_to_read);
+ g_hash_table_remove (priv->pathname_to_g_file, pathname_in_entry);
+ }
}
g_object_unref (info);
@@ -668,15 +737,8 @@ autoar_create_do_add_to_archive (AutoarCreate *arcreate,
static void
autoar_create_do_recursive_read (AutoarCreate *arcreate,
- struct archive *a,
- struct archive_entry *entry,
- struct archive_entry_linkresolver *resolver,
GFile *root,
- GFile *file,
- const char *basename,
- gboolean prepend_basename,
- gboolean in_thread,
- GHashTable *pathname_to_g_file)
+ GFile *file)
{
GFileEnumerator *enumerator;
GFileInfo *info;
@@ -694,9 +756,7 @@ autoar_create_do_recursive_read (AutoarCreate *arcreate,
while ((info = g_file_enumerator_next_file (enumerator, NULL, &(arcreate->priv->error))) != NULL) {
thisname = g_file_info_get_name (info);
thisfile = g_file_get_child (file, thisname);
- autoar_create_do_add_to_archive (arcreate, a, entry, resolver, root,
- thisfile, basename, prepend_basename,
- in_thread, pathname_to_g_file);
+ autoar_create_do_add_to_archive (arcreate, root, thisfile);
if (arcreate->priv->error != NULL) {
g_object_unref (thisfile);
g_object_unref (info);
@@ -704,9 +764,7 @@ autoar_create_do_recursive_read (AutoarCreate *arcreate,
}
if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY)
- autoar_create_do_recursive_read (arcreate, a, entry, resolver, root,
- thisfile, basename, prepend_basename,
- in_thread, pathname_to_g_file);
+ autoar_create_do_recursive_read (arcreate, root, thisfile);
g_object_unref (thisfile);
g_object_unref (info);
@@ -823,6 +881,16 @@ autoar_create_class_init (AutoarCreateClass *klass)
G_TYPE_UINT64,
G_TYPE_UINT);
+ autoar_create_signals[CANCELLED] =
+ g_signal_new ("cancelled",
+ type,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (AutoarCreateClass, cancelled),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
autoar_create_signals[COMPLETED] =
g_signal_new ("completed",
type,
@@ -869,6 +937,17 @@ autoar_create_init (AutoarCreate *arcreate)
priv->buffer_size = BUFFER_SIZE;
priv->buffer = g_new (char, priv->buffer_size);
priv->error = NULL;
+
+ priv->cancellable = NULL;
+
+ priv->a = archive_write_new ();
+ priv->entry = archive_entry_new ();
+ priv->resolver = archive_entry_linkresolver_new ();;
+ priv->pathname_to_g_file = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
+ priv->source_basename_noext = NULL;
+
+ priv->in_thread = FALSE;
+ priv->prepend_basename = FALSE;
}
AutoarCreate*
@@ -915,82 +994,66 @@ autoar_create_new (AutoarPref *arpref,
}
static void
-autoar_create_run (AutoarCreate *arcreate,
- gboolean in_thread)
+autoar_create_run (AutoarCreate *arcreate)
{
- struct archive *a;
- struct archive_entry *entry, *sparse;
- struct archive_entry_linkresolver *resolver;
-
AutoarPrefFormat format;
AutoarPrefFilter filter;
const char *format_extension;
const char *filter_extension;
- const char *basename;
- gboolean prepend_basename;
-
- GFileInfo *tmp_info;
- GFile *file_source;
- GFile *file_output;
- GFile *file_dest;
- char *source_basename;
- char *source_basename_noext;
- char *dest_basename;
-
- GHashTable *pathname_to_g_file;
-
+ AutoarCreatePrivate *priv;
int i, r;
g_return_if_fail (AUTOAR_IS_CREATE (arcreate));
- g_return_if_fail (arcreate->priv->source != NULL);
- g_return_if_fail (arcreate->priv->output != NULL);
+ priv = arcreate->priv;
+
+ g_return_if_fail (priv->source != NULL);
+ g_return_if_fail (priv->output != NULL);
/* A string array without a string is not allowed */
- g_return_if_fail (*(arcreate->priv->source) != NULL);
+ g_return_if_fail (*(priv->source) != NULL);
- format = autoar_pref_get_default_format (arcreate->priv->arpref);
- filter = autoar_pref_get_default_filter (arcreate->priv->arpref);
+ format = autoar_pref_get_default_format (priv->arpref);
+ filter = autoar_pref_get_default_filter (priv->arpref);
g_return_if_fail (format > 0 && format < AUTOAR_PREF_FORMAT_LAST);
g_return_if_fail (filter > 0 && filter < AUTOAR_PREF_FILTER_LAST);
- a = archive_write_new ();
- archive_write_set_bytes_in_last_block (a, 1);
+ archive_write_set_bytes_in_last_block (priv->a, 1);
switch (filter) {
case AUTOAR_PREF_FILTER_COMPRESS:
- archive_write_add_filter_compress (a);
+ archive_write_add_filter_compress (priv->a);
filter_extension = ".Z";
break;
case AUTOAR_PREF_FILTER_GZIP:
- archive_write_add_filter_gzip (a);
+ archive_write_add_filter_gzip (priv->a);
filter_extension = ".gz";
break;
case AUTOAR_PREF_FILTER_BZIP2:
- archive_write_add_filter_bzip2 (a);
+ archive_write_add_filter_bzip2 (priv->a);
filter_extension = ".bz2";
break;
case AUTOAR_PREF_FILTER_XZ:
- archive_write_add_filter_xz (a);
+ archive_write_add_filter_xz (priv->a);
filter_extension = ".xz";
break;
case AUTOAR_PREF_FILTER_LZMA:
- archive_write_add_filter_lzma (a);
+ archive_write_add_filter_lzma (priv->a);
filter_extension = ".lzma";
break;
case AUTOAR_PREF_FILTER_LZIP:
- archive_write_add_filter_lzip (a);
+ archive_write_add_filter_lzip (priv->a);
filter_extension = ".lz";
break;
case AUTOAR_PREF_FILTER_LZOP:
- archive_write_add_filter_lzop (a);
+ archive_write_add_filter_lzop (priv->a);
filter_extension = ".lzo";
break;
case AUTOAR_PREF_FILTER_GRZIP:
- archive_write_add_filter_grzip (a);
+ archive_write_add_filter_grzip (priv->a);
filter_extension = ".grz";
break;
case AUTOAR_PREF_FILTER_LRZIP:
- archive_write_add_filter_lrzip (a);
+ archive_write_add_filter_lrzip (priv->a);
filter_extension = ".lrz";
break;
case AUTOAR_PREF_FILTER_NONE:
@@ -1000,47 +1063,47 @@ autoar_create_run (AutoarCreate *arcreate,
switch (format) {
case AUTOAR_PREF_FORMAT_ZIP:
- archive_write_set_format_zip (a);
+ archive_write_set_format_zip (priv->a);
format_extension = ".zip";
break;
case AUTOAR_PREF_FORMAT_TAR:
- archive_write_set_format_pax_restricted (a);
+ archive_write_set_format_pax_restricted (priv->a);
format_extension = ".tar";
break;
case AUTOAR_PREF_FORMAT_CPIO:
- archive_write_set_format_cpio (a);
+ archive_write_set_format_cpio (priv->a);
format_extension = ".cpio";
break;
case AUTOAR_PREF_FORMAT_7ZIP:
- archive_write_set_format_7zip (a);
+ archive_write_set_format_7zip (priv->a);
format_extension = ".7z";
break;
case AUTOAR_PREF_FORMAT_AR_BSD:
- archive_write_set_format_ar_bsd (a);
+ archive_write_set_format_ar_bsd (priv->a);
format_extension = ".a";
break;
case AUTOAR_PREF_FORMAT_AR_SVR4:
- archive_write_set_format_ar_svr4 (a);
+ archive_write_set_format_ar_svr4 (priv->a);
format_extension = ".a";
break;
case AUTOAR_PREF_FORMAT_CPIO_NEWC:
- archive_write_set_format_cpio_newc (a);
+ archive_write_set_format_cpio_newc (priv->a);
format_extension = ".cpio";
break;
case AUTOAR_PREF_FORMAT_GNUTAR:
- archive_write_set_format_gnutar (a);
+ archive_write_set_format_gnutar (priv->a);
format_extension = ".tar";
break;
case AUTOAR_PREF_FORMAT_ISO9660:
- archive_write_set_format_iso9660 (a);
+ archive_write_set_format_iso9660 (priv->a);
format_extension = ".iso";
break;
case AUTOAR_PREF_FORMAT_PAX:
- archive_write_set_format_pax (a);
+ archive_write_set_format_pax (priv->a);
format_extension = ".tar";
break;
case AUTOAR_PREF_FORMAT_XAR:
- archive_write_set_format_xar (a);
+ archive_write_set_format_xar (priv->a);
format_extension = ".xar";
break;
default:
@@ -1050,104 +1113,106 @@ autoar_create_run (AutoarCreate *arcreate,
/* Step 1: Set the destination file name
* Use the first source file name */
g_debug ("autoar_extract_run: Step 1, Filename");
- basename = *(arcreate->priv->source);
- file_source = g_file_new_for_commandline_arg (basename);
- tmp_info = g_file_query_info (file_source,
- G_FILE_ATTRIBUTE_STANDARD_TYPE,
- G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
- NULL,
- &(arcreate->priv->error));
- if (tmp_info == NULL) {
- g_object_unref (file_source);
- autoar_common_g_signal_emit (in_thread, arcreate,
- autoar_create_signals[ERROR],
- 0, arcreate->priv->error);
- return;
- }
+ {
+ GFile *file_output;
+ GFile *file_dest;
+
+ {
+ GFile *file_source;
+ GFileInfo *source_info;
+ char *source_basename;
+ const char *basename;
+
+ basename = *(priv->source);
+ file_source = g_file_new_for_commandline_arg (basename);
+ source_info = g_file_query_info (file_source,
+ G_FILE_ATTRIBUTE_STANDARD_TYPE,
+ G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+ NULL,
+ &(priv->error));
+ if (source_info == NULL) {
+ g_object_unref (file_source);
+ autoar_create_signal_error (arcreate);
+ return;
+ }
- source_basename = g_file_get_basename (file_source);
- if (g_file_info_get_file_type (tmp_info) == G_FILE_TYPE_REGULAR)
- source_basename_noext = autoar_common_get_basename_remove_extension (source_basename);
- else
- source_basename_noext = g_strdup (source_basename);
- g_object_unref (tmp_info);
-
- file_output = g_file_new_for_commandline_arg (arcreate->priv->output);
- dest_basename = g_strconcat (source_basename_noext,
- format_extension,
- filter_extension,
- NULL);
- file_dest = g_file_get_child (file_output, dest_basename);
-
- for (i = 1; g_file_query_exists (file_dest, NULL); i++) {
- g_free (dest_basename);
- g_object_unref (file_dest);
- dest_basename = g_strdup_printf ("%s(%d)%s%s",
- source_basename_noext,
- i,
- format_extension,
- filter_extension);
- file_dest = g_file_get_child (file_output, dest_basename);
- }
+ source_basename = g_file_get_basename (file_source);
+ if (g_file_info_get_file_type (source_info) == G_FILE_TYPE_REGULAR)
+ priv->source_basename_noext = autoar_common_get_basename_remove_extension (source_basename);
+ else
+ priv->source_basename_noext = g_strdup (source_basename);
- if (!g_file_query_exists (file_output, NULL)) {
- g_file_make_directory_with_parents (file_output, NULL, &(arcreate->priv->error));
- if (arcreate->priv->error) {
- autoar_common_g_signal_emit (in_thread, arcreate,
- autoar_create_signals[ERROR],
- 0, arcreate->priv->error);
g_object_unref (file_source);
- g_object_unref (file_output);
- g_object_unref (file_dest);
+ g_object_unref (source_info);
g_free (source_basename);
- g_free (source_basename_noext);
+ }
+
+ {
+ char *dest_basename;
+
+ file_output = g_file_new_for_commandline_arg (priv->output);
+ dest_basename = g_strconcat (priv->source_basename_noext,
+ format_extension,
+ filter_extension,
+ NULL);
+ file_dest = g_file_get_child (file_output, dest_basename);
+
+ for (i = 1; g_file_query_exists (file_dest, NULL); i++) {
+ g_free (dest_basename);
+ g_object_unref (file_dest);
+ dest_basename = g_strdup_printf ("%s(%d)%s%s",
+ priv->source_basename_noext,
+ i,
+ format_extension,
+ filter_extension);
+ file_dest = g_file_get_child (file_output, dest_basename);
+ }
+
g_free (dest_basename);
- return;
}
- }
- arcreate->priv->dest = g_object_ref (file_dest);
- autoar_common_g_signal_emit (in_thread, arcreate,
- autoar_create_signals[DECIDE_DEST],
- 0, file_dest);
+ {
+ if (!g_file_query_exists (file_output, NULL)) {
+ g_file_make_directory_with_parents (file_output, NULL, &(arcreate->priv->error));
+ if (arcreate->priv->error) {
+ autoar_create_signal_error (arcreate);
+ g_object_unref (file_output);
+ g_object_unref (file_dest);
+ return;
+ }
+ }
+ }
+
+ arcreate->priv->dest = g_object_ref (file_dest);
+ autoar_create_signal_decide_dest (arcreate);
- g_object_unref (file_source);
- g_object_unref (file_output);
- g_object_unref (file_dest);
- g_free (source_basename);
- g_free (dest_basename);
+ g_object_unref (file_output);
+ g_object_unref (file_dest);
+ }
/* Step 2: Create and open the new archive file */
g_debug ("autoar_extract_run: Step 2, Create and Write");
- r = archive_write_open (a, arcreate,
+ r = archive_write_open (priv->a, arcreate,
libarchive_write_open_cb,
libarchive_write_write_cb,
libarchive_write_close_cb);
if (r != ARCHIVE_OK) {
- archive_write_free (a);
- if (arcreate->priv->error == NULL)
- arcreate->priv->error = g_error_new (autoar_create_quark,
- archive_errno (a),
- "%s",
- archive_error_string (a));
- autoar_common_g_signal_emit (in_thread, arcreate,
- autoar_create_signals[ERROR],
- 0, arcreate->priv->error);
- g_free (source_basename_noext);
+ if (priv->error == NULL)
+ priv->error = autoar_common_g_error_new_a (autoar_create_quark, priv->a, NULL);
+ autoar_create_signal_error (arcreate);
return;
}
/* Check whether we have multiple source files */
if (arcreate->priv->source[1] == NULL)
- prepend_basename = FALSE;
+ priv->prepend_basename = FALSE;
else
- prepend_basename = TRUE;
+ priv->prepend_basename = TRUE;
- entry = archive_entry_new ();
- resolver = archive_entry_linkresolver_new ();
- archive_entry_linkresolver_set_strategy (resolver, archive_format (a));
- pathname_to_g_file = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
+ priv->entry = archive_entry_new ();
+ priv->resolver = archive_entry_linkresolver_new ();
+ archive_entry_linkresolver_set_strategy (priv->resolver, archive_format (priv->a));
for (i = 0; arcreate->priv->source[i] != NULL; i++) {
GFile *file;
@@ -1161,88 +1226,61 @@ autoar_create_run (AutoarCreate *arcreate,
NULL,
&(arcreate->priv->error));
if (arcreate->priv->error != NULL) {
- autoar_common_g_signal_emit (in_thread, arcreate,
- autoar_create_signals[ERROR],
- 0, arcreate->priv->error);
+ autoar_create_signal_error (arcreate);
g_object_unref (file);
g_object_unref (fileinfo);
- g_free (source_basename_noext);
- archive_write_free (a);
- archive_entry_free (entry);
- archive_entry_linkresolver_free (resolver);
- g_hash_table_unref (pathname_to_g_file);
return;
}
- autoar_create_do_add_to_archive (arcreate, a, entry, resolver, file, file,
- source_basename_noext, prepend_basename,
- in_thread, pathname_to_g_file);
+ autoar_create_do_add_to_archive (arcreate, file, file);
if (g_file_info_get_file_type (fileinfo) == G_FILE_TYPE_DIRECTORY)
- autoar_create_do_recursive_read (arcreate, a, entry, resolver, file, file,
- source_basename_noext, prepend_basename,
- in_thread, pathname_to_g_file);
+ autoar_create_do_recursive_read (arcreate, file, file);
g_object_unref (file);
g_object_unref (fileinfo);
if (arcreate->priv->error != NULL) {
- autoar_common_g_signal_emit (in_thread, arcreate,
- autoar_create_signals[ERROR],
- 0, arcreate->priv->error);
- g_free (source_basename_noext);
- archive_write_free (a);
- archive_entry_free (entry);
- archive_entry_linkresolver_free (resolver);
- g_hash_table_unref (pathname_to_g_file);
+ autoar_create_signal_error (arcreate);
return;
}
}
- archive_entry_free (entry);
- entry = NULL;
- archive_entry_linkify (resolver, &entry, &sparse);
- if (entry != NULL) {
- GFile *file_to_read;
- const char *pathname_in_entry;
- pathname_in_entry = archive_entry_pathname (entry);
- file_to_read = g_hash_table_lookup (pathname_to_g_file, pathname_in_entry);
- autoar_create_do_write_data (arcreate, a, entry, file_to_read, in_thread);
- /* I think we do not have to remove the entry in the hash table now
- * because we are going to free the entire hash table. */
+ {
+ struct archive_entry *entry, *sparse;
+ entry = NULL;
+ archive_entry_linkify (priv->resolver, &entry, &sparse);
+ if (entry != NULL) {
+ GFile *file_to_read;
+ const char *pathname_in_entry;
+ pathname_in_entry = archive_entry_pathname (entry);
+ file_to_read = g_hash_table_lookup (priv->pathname_to_g_file, pathname_in_entry);
+ autoar_create_do_write_data (arcreate, entry, file_to_read);
+ /* I think we do not have to remove the entry in the hash table now
+ * because we are going to free the entire hash table. */
+ }
}
- g_free (source_basename_noext);
- archive_entry_linkresolver_free (resolver);
- g_hash_table_unref (pathname_to_g_file);
-
- if (arcreate->priv->error != NULL) {
- archive_write_free (a);
+ if (arcreate->priv->error != NULL)
return;
- }
- r = archive_write_close (a);
+ r = archive_write_close (priv->a);
if (r != ARCHIVE_OK) {
if (arcreate->priv->error == NULL)
- arcreate->priv->error = g_error_new (autoar_create_quark,
- archive_errno (a),
- "%s",
- archive_error_string (a));
-
- archive_write_free (a);
+ priv->error = autoar_common_g_error_new_a (autoar_create_quark, priv->a, NULL);
return;
}
- archive_write_free (a);
-
- autoar_common_g_signal_emit (in_thread, arcreate,
- autoar_create_signals[COMPLETED], 0);
+ autoar_create_signal_completed (arcreate);
}
void
-autoar_create_start (AutoarCreate *arcreate)
+autoar_create_start (AutoarCreate *arcreate,
+ GCancellable *cancellable)
{
- autoar_create_run (arcreate, FALSE);
+ arcreate->priv->cancellable = cancellable;
+ arcreate->priv->in_thread = FALSE;
+ autoar_create_run (arcreate);
}
static void
@@ -1252,18 +1290,21 @@ autoar_create_start_async_thread (GTask *task,
GCancellable *cancellable)
{
AutoarCreate *arcreate = source_object;
- autoar_create_run (arcreate, TRUE);
+ autoar_create_run (arcreate);
g_task_return_pointer (task, NULL, g_free);
g_object_unref (arcreate);
g_object_unref (task);
}
void
-autoar_create_start_async (AutoarCreate *arcreate)
+autoar_create_start_async (AutoarCreate *arcreate,
+ GCancellable *cancellable)
{
GTask *task;
g_object_ref (arcreate);
+ arcreate->priv->cancellable = cancellable;
+ arcreate->priv->in_thread = TRUE;
task = g_task_new (arcreate, NULL, NULL, NULL);
g_task_set_task_data (task, NULL, NULL);
diff --git a/gnome-autoar/autoar-create.h b/gnome-autoar/autoar-create.h
index bfbc542..11ca98c 100644
--- a/gnome-autoar/autoar-create.h
+++ b/gnome-autoar/autoar-create.h
@@ -60,6 +60,7 @@ struct _AutoarCreateClass
void (* progress) (AutoarCreate *arcreate,
guint64 completed_size,
guint completed_files);
+ void (* cancelled) (AutoarCreate *arcreate);
void (* completed) (AutoarCreate *arcreate);
void (* error) (AutoarCreate *arcreate,
GError *error);
@@ -74,8 +75,10 @@ AutoarCreate* autoar_create_newv (AutoarPref *arpref,
const char *output,
const char **source);
-void autoar_create_start (AutoarCreate *arcreate);
-void autoar_create_start_async (AutoarCreate *arcreate);
+void autoar_create_start (AutoarCreate *arcreate,
+ GCancellable *cancellable);
+void autoar_create_start_async (AutoarCreate *arcreate,
+ GCancellable *cancellable);
char **autoar_create_get_source (AutoarCreate *arcreate);
char *autoar_create_get_output (AutoarCreate *arcreate);
diff --git a/tests/test-create.c b/tests/test-create.c
index f63142b..a96bb24 100644
--- a/tests/test-create.c
+++ b/tests/test-create.c
@@ -65,7 +65,7 @@ main (int argc,
g_signal_connect (arcreate, "error", G_CALLBACK (my_handler_error), NULL);
g_signal_connect (arcreate, "completed", G_CALLBACK (my_handler_completed), NULL);
- autoar_create_start (arcreate);
+ autoar_create_start (arcreate, NULL);
g_object_unref (arpref);
g_object_unref (arcreate);