diff options
author | Tim Kientzle <kientzle@acm.org> | 2016-02-21 12:34:57 -0800 |
---|---|---|
committer | Tim Kientzle <kientzle@acm.org> | 2016-02-21 12:34:57 -0800 |
commit | 3477e4e33fb83a721ba274e49df9c2c92e4c953d (patch) | |
tree | 3b64688c95209dcdd29e28e5bdbd6a2240fa8e45 /libarchive/archive_write_set_format_pax.c | |
parent | 37649d274867edd2dd25d8a3057c3b6cd81ce83e (diff) | |
download | libarchive-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.c | 37 |
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); |