From: Michihiro NAKAJIMA Date: Thu, 19 Jan 2012 11:15:41 +0000 (-0500) Subject: Add archive_read_disk_set_behavior function and drop archive_read_disk_honor_nodump and X-Git-Tag: v3.0.4~2^2~168 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3df7554a9745565e8b9ad830ce5d65facdae475f;p=thirdparty%2Flibarchive.git Add archive_read_disk_set_behavior function and drop archive_read_disk_honor_nodump and archive_read_disk_disable_mac_copyfile. SVN-Revision: 4184 --- diff --git a/libarchive/archive.h b/libarchive/archive.h index 524f210c9..56d677f0a 100644 --- a/libarchive/archive.h +++ b/libarchive/archive.h @@ -755,8 +755,23 @@ __LA_DECL int archive_read_disk_current_filesystem_is_synthetic(struct archive * __LA_DECL int archive_read_disk_current_filesystem_is_remote(struct archive *); /* Request that the access time of the entry visited by travesal be restored. */ __LA_DECL int archive_read_disk_set_atime_restored(struct archive *); -__LA_DECL int archive_read_disk_honor_nodump(struct archive *); -__LA_DECL int archive_read_disk_disable_mac_copyfile(struct archive *); +/* + * Set behavior. The "flags" argument selects optional behavior. + */ +/* Request that the access time of the entry visited by travesal be restored. + * This is the same as archive_read_disk_set_atime_restored. */ +#define ARCHIVE_READDISK_RESTORE_ATIME (0x0001) +/* Default: Do not skip an entry which has nodump flags. */ +#define ARCHIVE_READDISK_HONOR_NODUMP (0x0002) +/* Default: Skip a mac resource fork file whose prefix is "._" because of + * using copyfile. */ +#define ARCHIVE_READDISK_MAC_COPYFILE (0x0004) +/* Default: Do not traverse mount points. */ +#define ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS (0x0008) + +__LA_DECL int archive_read_disk_set_behavior(struct archive *, + int flags); + /* * Set archive_matching object that will be used in archive_read_disk to * know whether an entry should be skipped. The callback function diff --git a/libarchive/archive_read_disk_posix.c b/libarchive/archive_read_disk_posix.c index 15c778637..ddf39d1c6 100644 --- a/libarchive/archive_read_disk_posix.c +++ b/libarchive/archive_read_disk_posix.c @@ -452,6 +452,7 @@ archive_read_disk_new(void) a->lookup_uname = trivial_lookup_uname; a->lookup_gname = trivial_lookup_gname; a->enable_copyfile = 1; + a->traversal_mount_points = 1; a->entry_wd_fd = -1; return (&a->archive); } @@ -569,23 +570,34 @@ archive_read_disk_set_atime_restored(struct archive *_a) } int -archive_read_disk_honor_nodump(struct archive *_a) +archive_read_disk_set_behavior(struct archive *_a, int flags) { struct archive_read_disk *a = (struct archive_read_disk *)_a; + int r = ARCHIVE_OK; + archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_ANY, "archive_read_disk_honor_nodump"); - a->honor_nodump = 1; - return (ARCHIVE_OK); -} -int -archive_read_disk_disable_mac_copyfile(struct archive *_a) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, - ARCHIVE_STATE_ANY, "archive_read_disk_disable_mac_copyfile"); - a->enable_copyfile = 0; - return (ARCHIVE_OK); + if (flags & ARCHIVE_READDISK_RESTORE_ATIME) + r = archive_read_disk_set_atime_restored(_a); + else { + a->restore_time = 0; + if (a->tree != NULL) + a->tree->flags &= ~needsRestoreTimes; + } + if (flags & ARCHIVE_READDISK_HONOR_NODUMP) + a->honor_nodump = 1; + else + a->honor_nodump = 0; + if (flags & ARCHIVE_READDISK_MAC_COPYFILE) + a->enable_copyfile = 1; + else + a->enable_copyfile = 0; + if (flags & ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS) + a->traversal_mount_points = 0; + else + a->traversal_mount_points = 1; + return (r); } /* diff --git a/libarchive/archive_read_disk_private.h b/libarchive/archive_read_disk_private.h index c0367e5de..ff50ebdcd 100644 --- a/libarchive/archive_read_disk_private.h +++ b/libarchive/archive_read_disk_private.h @@ -63,6 +63,8 @@ struct archive_read_disk { int honor_nodump; /* Set 1 if users request to enable mac copyfile. */ int enable_copyfile; + /* Set 1 if users request to traversal mount points. */ + int traversal_mount_points; int entry_wd_fd; diff --git a/libarchive/archive_read_disk_windows.c b/libarchive/archive_read_disk_windows.c index 58369db56..cad57a1eb 100644 --- a/libarchive/archive_read_disk_windows.c +++ b/libarchive/archive_read_disk_windows.c @@ -394,6 +394,8 @@ archive_read_disk_new(void) a->archive.vtable = archive_read_disk_vtable(); a->lookup_uname = trivial_lookup_uname; a->lookup_gname = trivial_lookup_gname; + a->enable_copyfile = 1; + a->traversal_mount_points = 1; a->entry_wd_fd = -1; return (&a->archive); } @@ -496,23 +498,34 @@ archive_read_disk_set_atime_restored(struct archive *_a) } int -archive_read_disk_honor_nodump(struct archive *_a) +archive_read_disk_set_behavior(struct archive *_a, int flags) { struct archive_read_disk *a = (struct archive_read_disk *)_a; + int r = ARCHIVE_OK; + archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_ANY, "archive_read_disk_honor_nodump"); - a->honor_nodump = 1; - return (ARCHIVE_OK); -} -int -archive_read_disk_disable_mac_copyfile(struct archive *_a) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, - ARCHIVE_STATE_ANY, "archive_read_disk_disable_mac_copyfile"); - a->enable_copyfile = 0; - return (ARCHIVE_OK); + if (flags & ARCHIVE_READDISK_RESTORE_ATIME) + r = archive_read_disk_set_atime_restored(_a); + else { + a->restore_time = 0; + if (a->tree != NULL) + a->tree->flags &= ~needsRestoreTimes; + } + if (flags & ARCHIVE_READDISK_HONOR_NODUMP) + a->honor_nodump = 1; + else + a->honor_nodump = 0; + if (flags & ARCHIVE_READDISK_MAC_COPYFILE) + a->enable_copyfile = 1; + else + a->enable_copyfile = 0; + if (flags & ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS) + a->traversal_mount_points = 0; + else + a->traversal_mount_points = 1; + return (r); } /* diff --git a/libarchive/test/test_read_disk_directory_traversals.c b/libarchive/test/test_read_disk_directory_traversals.c index 3f9a8a7ea..be77304f9 100644 --- a/libarchive/test/test_read_disk_directory_traversals.c +++ b/libarchive/test/test_read_disk_directory_traversals.c @@ -1236,8 +1236,8 @@ test_restore_atime(void) assertUtimes("at/fe", 886611, 0, 886611, 0); assertUtimes("at", 886622, 0, 886622, 0); file_count = 2; - assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_set_atime_restored(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_honor_nodump(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_set_behavior(a, + ARCHIVE_READDISK_RESTORE_ATIME | ARCHIVE_READDISK_HONOR_NODUMP)); assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "at")); failure("Directory traversals should work as well"); @@ -1509,8 +1509,8 @@ test_nodump(void) assertUtimes("nd/fe", 886611, 0, 886611, 0); assertUtimes("nd", 886622, 0, 886622, 0); - assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_honor_nodump(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_set_atime_restored(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_set_behavior(a, + ARCHIVE_READDISK_RESTORE_ATIME | ARCHIVE_READDISK_HONOR_NODUMP)); failure("Directory traversals should work as well"); assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "nd")); diff --git a/tar/bsdtar.c b/tar/bsdtar.c index a2d4617f0..9ed1d6f89 100644 --- a/tar/bsdtar.c +++ b/tar/bsdtar.c @@ -241,10 +241,10 @@ main(int argc, char **argv) * Enable Mac OS "copyfile()" extension by default. * This has no effect on other platforms. */ - bsdtar->enable_copyfile = 1; + bsdtar->readdisk_flags |= ARCHIVE_READDISK_MAC_COPYFILE; #ifdef COPYFILE_DISABLE_VAR if (getenv(COPYFILE_DISABLE_VAR)) - bsdtar->enable_copyfile = 0; + bsdtar->readdisk_flags &= ~ARCHIVE_READDISK_MAC_COPYFILE; #endif bsdtar->matching = archive_matching_new(); if (bsdtar->matching == NULL) @@ -290,7 +290,7 @@ main(int argc, char **argv) bsdtar->option_chroot = 1; break; case OPTION_DISABLE_COPYFILE: /* Mac OS X */ - bsdtar->enable_copyfile = 0; + bsdtar->readdisk_flags &= ~ARCHIVE_READDISK_MAC_COPYFILE; break; case OPTION_EXCLUDE: /* GNU tar */ if (archive_matching_exclude_pattern( @@ -424,7 +424,7 @@ main(int argc, char **argv) archive_error_string(bsdtar->matching)); break; case OPTION_NODUMP: /* star */ - bsdtar->option_honor_nodump = 1; + bsdtar->readdisk_flags |= ARCHIVE_READDISK_HONOR_NODUMP; break; case OPTION_NO_SAME_OWNER: /* GNU tar */ bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_OWNER; @@ -614,7 +614,7 @@ main(int argc, char **argv) only_mode(bsdtar, "--one-file-system", "cru"); if (bsdtar->option_fast_read) only_mode(bsdtar, "--fast-read", "xt"); - if (bsdtar->option_honor_nodump) + if (bsdtar->readdisk_flags & ARCHIVE_READDISK_HONOR_NODUMP) only_mode(bsdtar, "--nodump", "cru"); if (option_o > 0) { switch (bsdtar->mode) { diff --git a/tar/bsdtar.h b/tar/bsdtar.h index a85e9364a..c9bf9544b 100644 --- a/tar/bsdtar.h +++ b/tar/bsdtar.h @@ -50,6 +50,7 @@ struct bsdtar { int bytes_in_last_block; /* See -b handling. */ int verbose; /* -v */ int extract_flags; /* Flags for extract operation */ + int readdisk_flags; /* Flags for read disk operation */ int strip_components; /* Remove this many leading dirs */ int gid; /* --gid */ const char *gname; /* --gname */ @@ -64,7 +65,6 @@ struct bsdtar { char option_dont_traverse_mounts; /* --one-file-system */ char option_fast_read; /* --fast-read */ const char *option_options; /* --options */ - char option_honor_nodump; /* --nodump */ char option_interactive; /* -w */ char option_no_owner; /* -o */ char option_no_subdirs; /* -n */ @@ -75,7 +75,6 @@ struct bsdtar { char option_unlink_first; /* -U */ char option_warn_links; /* --check-links */ char day_first; /* show day before month in -tv output */ - char enable_copyfile; /* For Mac OS */ /* Option parser state */ int getopt_state; diff --git a/tar/write.c b/tar/write.c index cb5e8f160..b3b8355ba 100644 --- a/tar/write.c +++ b/tar/write.c @@ -430,11 +430,9 @@ write_archive(struct archive *a, struct bsdtar *bsdtar) bsdtar->matching, excluded_callback, bsdtar); archive_read_disk_set_metadata_filter_callback( bsdtar->diskreader, metadata_filter, bsdtar); - /* Skip a file if it has nodump flag. */ - if (bsdtar->option_honor_nodump) - archive_read_disk_honor_nodump(bsdtar->diskreader); - if (!bsdtar->enable_copyfile) - archive_read_disk_disable_mac_copyfile(bsdtar->diskreader); + /* Set the behavior of archive_read_disk. */ + archive_read_disk_set_behavior(bsdtar->diskreader, + bsdtar->readdisk_flags); archive_read_disk_set_standard_lookup(bsdtar->diskreader); if (bsdtar->names_from_file != NULL)