]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Add archive_read_disk_set_behavior function and drop archive_read_disk_honor_nodump and
authorMichihiro NAKAJIMA <ggcueroad@gmail.com>
Thu, 19 Jan 2012 11:15:41 +0000 (06:15 -0500)
committerMichihiro NAKAJIMA <ggcueroad@gmail.com>
Thu, 19 Jan 2012 11:15:41 +0000 (06:15 -0500)
archive_read_disk_disable_mac_copyfile.

SVN-Revision: 4184

libarchive/archive.h
libarchive/archive_read_disk_posix.c
libarchive/archive_read_disk_private.h
libarchive/archive_read_disk_windows.c
libarchive/test/test_read_disk_directory_traversals.c
tar/bsdtar.c
tar/bsdtar.h
tar/write.c

index 524f210c907a5843b55985a2613e0da48e7e58dc..56d677f0a164f32da5c3e3b0208abcdb0d29e89d 100644 (file)
@@ -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
index 15c778637c39b95f33f17baba027828443d92fe3..ddf39d1c699807cfe255d51f9f32fb19dda80f31 100644 (file)
@@ -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);
 }
 
 /*
index c0367e5deb70a797ea08b3294800eb1bf32bb8fa..ff50ebdcd8f8a93e6591b873387c6d160051b45e 100644 (file)
@@ -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;
 
index 58369db56f07c2bf318c88677cf41c8d41c4257a..cad57a1eb5c538b5abe9e665acb9d04b2ed42c36 100644 (file)
@@ -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);
 }
 
 /*
index 3f9a8a7ea670a9c2f2d2d55575337013ba2d1d62..be77304f93f128b17cd396d7bfa3f85f0309eb62 100644 (file)
@@ -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"));
 
index a2d4617f05e8118f80d074b4b2904c9428ea44cb..9ed1d6f8915d7abbad8236529b7ca2a36cdcc33b 100644 (file)
@@ -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) {
index a85e9364a2f23464034089c36ab85c3a862b2768..c9bf9544bc8b261ede8e5029500492df5a9bc188 100644 (file)
@@ -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;
index cb5e8f16095e8fa396190d0a3d4e7379e6f453f2..b3b8355ba1cfe20b28ab52bf7332e04e4973af91 100644 (file)
@@ -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)