summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTing-Wei Lan <lantw44@gmail.com>2013-08-03 14:24:39 +0800
committerLAN-TW <lantw44@gmail.com>2013-08-03 14:24:39 +0800
commit416e0b638f4451d499ff6e351bb066758361a748 (patch)
tree8be67836a5454e6b9749d8496e81745b04bed170
parent89295b4ebdf97072cbde1dd68763356a0d9a79c1 (diff)
downloadgsoc2013-libgnome-autoar-416e0b638f4451d499ff6e351bb066758361a748.tar
gsoc2013-libgnome-autoar-416e0b638f4451d499ff6e351bb066758361a748.tar.gz
gsoc2013-libgnome-autoar-416e0b638f4451d499ff6e351bb066758361a748.tar.bz2
gsoc2013-libgnome-autoar-416e0b638f4451d499ff6e351bb066758361a748.tar.lz
gsoc2013-libgnome-autoar-416e0b638f4451d499ff6e351bb066758361a748.tar.xz
gsoc2013-libgnome-autoar-416e0b638f4451d499ff6e351bb066758361a748.tar.zst
gsoc2013-libgnome-autoar-416e0b638f4451d499ff6e351bb066758361a748.zip
Correct timestamps of extracted directories after all entries are written
Timestamps of extracted directories may be updated when new files are added into the directories, so we have to apply the GFileInfo again to reset the timestamps.
-rw-r--r--gnome-autoar/autoar-extract.c35
-rw-r--r--tests/test-create.c2
2 files changed, 36 insertions, 1 deletions
diff --git a/gnome-autoar/autoar-extract.c b/gnome-autoar/autoar-extract.c
index a3718bf..c8bdb9f 100644
--- a/gnome-autoar/autoar-extract.c
+++ b/gnome-autoar/autoar-extract.c
@@ -61,6 +61,8 @@ G_DEFINE_TYPE (AutoarExtract, autoar_extract, G_TYPE_OBJECT)
#define BUFFER_SIZE (64 * 1024)
#define NOT_AN_ARCHIVE_ERRNO 2013
+typedef struct _GFileAndInfo GFileAndInfo;
+
struct _AutoarExtractPrivate
{
char *source;
@@ -80,6 +82,12 @@ struct _AutoarExtractPrivate
GError *error;
};
+struct _GFileAndInfo
+{
+ GFile *file;
+ GFileInfo *info;
+};
+
enum
{
SCANNED,
@@ -456,6 +464,13 @@ g_pattern_spec_free_safe (void *pattern_compiled)
g_pattern_spec_free (pattern_compiled);
}
+static void
+g_file_and_info_free (void *g_file_and_info) {
+ GFileAndInfo *fi = g_file_and_info;
+ g_object_unref (fi->file);
+ g_object_unref (fi->info);
+}
+
static GFile*
autoar_extract_do_sanitize_pathname (const char *pathname,
const char *skip_chars,
@@ -543,6 +558,7 @@ autoar_extract_do_write_entry (AutoarExtract *arextract,
GFile *top_level_dir,
GHashTable *userhash,
GHashTable *grouphash,
+ GArray *extracted_dir_list,
gboolean in_thread,
gboolean use_raw_format)
{
@@ -565,6 +581,7 @@ autoar_extract_do_write_entry (AutoarExtract *arextract,
guint32 uid, gid;
char *str, *str2;
+ GFileAndInfo fileandinfo;
parent = g_file_get_parent (dest);
if (!g_file_query_exists (parent, NULL))
@@ -739,6 +756,9 @@ autoar_extract_do_write_entry (AutoarExtract *arextract,
return;
}
}
+ fileandinfo.file = g_object_ref (dest);
+ fileandinfo.info = g_object_ref (info);
+ g_array_append_val (extracted_dir_list, fileandinfo);
break;
case AE_IFLNK:
g_debug ("autoar_extract_do_write_entry: case LNK");
@@ -1025,6 +1045,7 @@ autoar_extract_run (AutoarExtract *arextract,
const char **pattern;
GPtrArray *pattern_compiled;
+ GArray *extracted_dir_list;
GFile *source;
char *source_basename;
@@ -1288,6 +1309,8 @@ autoar_extract_run (AutoarExtract *arextract,
}
userhash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
grouphash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+ extracted_dir_list = g_array_new (FALSE, FALSE, sizeof (GFileAndInfo));
+ g_array_set_clear_func (extracted_dir_list, g_file_and_info_free);
while ((r = archive_read_next_header (a, &entry)) == ARCHIVE_OK) {
const char *pathname;
const char *hardlink;
@@ -1328,6 +1351,7 @@ autoar_extract_run (AutoarExtract *arextract,
top_level_dir,
userhash,
grouphash,
+ extracted_dir_list,
in_thread,
use_raw_format);
@@ -1343,6 +1367,7 @@ autoar_extract_run (AutoarExtract *arextract,
g_hash_table_unref (userhash);
g_hash_table_unref (grouphash);
g_hash_table_unref (bad_filename);
+ g_array_unref (extracted_dir_list);
archive_read_close (a);
archive_read_free (a);
return;
@@ -1373,15 +1398,25 @@ autoar_extract_run (AutoarExtract *arextract,
g_hash_table_unref (userhash);
g_hash_table_unref (grouphash);
g_hash_table_unref (bad_filename);
+ g_array_unref (extracted_dir_list);
archive_read_close (a);
archive_read_free (a);
return;
}
+ for (i = 0; i < extracted_dir_list->len; i++) {
+ GFile *file = g_array_index (extracted_dir_list, GFileAndInfo, i).file;
+ GFileInfo *info = g_array_index (extracted_dir_list, GFileAndInfo, i).info;
+ g_file_set_attributes_from_info (file, info,
+ G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+ NULL, NULL);
+ }
+
g_object_unref (top_level_dir);
g_hash_table_unref (userhash);
g_hash_table_unref (grouphash);
g_hash_table_unref (bad_filename);
+ g_array_unref (extracted_dir_list);
archive_read_close (a);
archive_read_free (a);
if (arextract->priv->error != NULL) {
diff --git a/tests/test-create.c b/tests/test-create.c
index be0a279..f63142b 100644
--- a/tests/test-create.c
+++ b/tests/test-create.c
@@ -59,7 +59,7 @@ main (int argc,
autoar_pref_set_default_format (arpref, atoi (argv[1]));
autoar_pref_set_default_filter (arpref, atoi (argv[2]));
- arcreate = autoar_create_newv (arpref, argv[3], argv + 4);
+ arcreate = autoar_create_newv (arpref, argv[3], (const char**)argv + 4);
g_signal_connect (arcreate, "decide-dest", G_CALLBACK (my_handler_decide_dest), NULL);
g_signal_connect (arcreate, "progress", G_CALLBACK (my_handler_progress), NULL);
g_signal_connect (arcreate, "error", G_CALLBACK (my_handler_error), NULL);