summaryrefslogtreecommitdiff
path: root/libarchive/archive_write_set_format_pax.c
diff options
context:
space:
mode:
authorTim Kientzle <kientzle@acm.org>2016-02-21 12:34:57 -0800
committerTim Kientzle <kientzle@acm.org>2016-02-21 12:34:57 -0800
commit3477e4e33fb83a721ba274e49df9c2c92e4c953d (patch)
tree3b64688c95209dcdd29e28e5bdbd6a2240fa8e45 /libarchive/archive_write_set_format_pax.c
parent37649d274867edd2dd25d8a3057c3b6cd81ce83e (diff)
downloadlibarchive-3477e4e33fb83a721ba274e49df9c2c92e4c953d.tar.gz
Fix for issue #623.
Apparently, people have come to expect that the following is sufficient to get bit-for-bit identical output from tar: * Same filenames * Same contents * Same uid, gid * Same mtime (forced via "touch -t <timestamp>") * Sorting entries Bsdtar's "restricted pax" format violated this by including ctime, atime, and birthtime (which are not updated by 'touch -t). So we should only emit those additional time values in the full pax format. People who are really serious about generating bit-for-bit identical archives should really build their own command-line interface: You can still use libarchive to build the output, but your custom CLI could sort the entries and strip everything except a bare minimum of basic metadata.
Diffstat (limited to 'libarchive/archive_write_set_format_pax.c')
-rw-r--r--libarchive/archive_write_set_format_pax.c37
1 files changed, 22 insertions, 15 deletions
diff --git a/libarchive/archive_write_set_format_pax.c b/libarchive/archive_write_set_format_pax.c
index 687f8e48..6f7fe783 100644
--- a/libarchive/archive_write_set_format_pax.c
+++ b/libarchive/archive_write_set_format_pax.c
@@ -1036,22 +1036,12 @@ archive_write_pax_header(struct archive_write *a,
need_extension = 1;
/*
- * The following items are handled differently in "pax
- * restricted" format. In particular, in "pax restricted"
- * format they won't be added unless need_extension is
- * already set (we're already generating an extended header, so
- * may as well include these).
+ * Libarchive used to include these in extended headers for
+ * restricted pax format, but that confused people who
+ * expected ustar-like time semantics. So now we only include
+ * them in full pax format.
*/
- if (a->archive.archive_format != ARCHIVE_FORMAT_TAR_PAX_RESTRICTED ||
- need_extension) {
-
- if (archive_entry_mtime(entry_main) < 0 ||
- archive_entry_mtime(entry_main) >= 0x7fffffff ||
- archive_entry_mtime_nsec(entry_main) != 0)
- add_pax_attr_time(&(pax->pax_header), "mtime",
- archive_entry_mtime(entry_main),
- archive_entry_mtime_nsec(entry_main));
-
+ if (a->archive.archive_format != ARCHIVE_FORMAT_TAR_PAX_RESTRICTED) {
if (archive_entry_ctime(entry_main) != 0 ||
archive_entry_ctime_nsec(entry_main) != 0)
add_pax_attr_time(&(pax->pax_header), "ctime",
@@ -1072,6 +1062,23 @@ archive_write_pax_header(struct archive_write *a,
"LIBARCHIVE.creationtime",
archive_entry_birthtime(entry_main),
archive_entry_birthtime_nsec(entry_main));
+ }
+
+ /*
+ * The following items are handled differently in "pax
+ * restricted" format. In particular, in "pax restricted"
+ * format they won't be added unless need_extension is
+ * already set (we're already generating an extended header, so
+ * may as well include these).
+ */
+ if (a->archive.archive_format != ARCHIVE_FORMAT_TAR_PAX_RESTRICTED ||
+ need_extension) {
+ if (archive_entry_mtime(entry_main) < 0 ||
+ archive_entry_mtime(entry_main) >= 0x7fffffff ||
+ archive_entry_mtime_nsec(entry_main) != 0)
+ add_pax_attr_time(&(pax->pax_header), "mtime",
+ archive_entry_mtime(entry_main),
+ archive_entry_mtime_nsec(entry_main));
/* I use a star-compatible file flag attribute. */
p = archive_entry_fflags_text(entry_main);