diff options
author | kientzle <kientzle@FreeBSD.org> | 2004-07-26 02:54:42 +0000 |
---|---|---|
committer | kientzle <kientzle@FreeBSD.org> | 2004-07-26 02:54:42 +0000 |
commit | c6ae412b294af5529ca02501331a3352128fa173 (patch) | |
tree | 19c188bcc8e6cb2fa7f037365230a663da2ec971 /lib/libarchive/archive_write_set_format_pax.c | |
parent | ec34d4330fc3137407640bc672d19416d492f62a (diff) | |
download | FreeBSD-src-c6ae412b294af5529ca02501331a3352128fa173.zip FreeBSD-src-c6ae412b294af5529ca02501331a3352128fa173.tar.gz |
When writing "pax" format, readers are supposed to ignore fields
in the regular ustar header that are overridden by the pax
extended attributes. As a result, it makes perfect sense to
use numeric extensions in the regular ustar header so that readers
that don't understand pax extensions but do understand some other
extensions can still get useful information out of it.
This is especially important for filesizes, as the failure to
read a file size correctly can get the reader out of sync.
This commit introduces a "non-strict" option into the internal
function to format a ustar header. In non-strict mode, the formatter
will use longer octal values (overwriting terminators) or binary
("base-256") values as needed to ensure that large file sizes,
negative mtimes, etc, have the correct values stored in the regular
ustar header.
Diffstat (limited to 'lib/libarchive/archive_write_set_format_pax.c')
-rw-r--r-- | lib/libarchive/archive_write_set_format_pax.c | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/lib/libarchive/archive_write_set_format_pax.c b/lib/libarchive/archive_write_set_format_pax.c index cc4b82e..a8e5be8 100644 --- a/lib/libarchive/archive_write_set_format_pax.c +++ b/lib/libarchive/archive_write_set_format_pax.c @@ -500,7 +500,6 @@ archive_write_pax_header(struct archive *a, if (!need_extension && p != NULL && *p != '\0') need_extension = 1; - /* If there are non-trivial ACL entries, we need an extension. */ if (!need_extension && archive_entry_acl_count(entry_original, ARCHIVE_ENTRY_ACL_TYPE_ACCESS) > 0) @@ -595,9 +594,33 @@ archive_write_pax_header(struct archive *a, if (hardlink != NULL) archive_entry_set_size(entry_main, 0); - /* Format 'ustar' header for main entry. */ - /* We don't care if this returns an error. */ - __archive_write_format_header_ustar(a, ustarbuff, entry_main, -1); + /* Format 'ustar' header for main entry. + * + * The trouble with file size: If the reader can't understand + * the file size, they may not be able to locate the next + * entry and the rest of the archive is toast. Pax-compliant + * readers are supposed to ignore the file size in the main + * header, so the question becomes how to maximize portability + * for readers that don't support pax attribute extensions. + * For maximum compatibility, I permit numeric extensions in + * the main header so that the file size stored will always be + * correct, even if it's in a format that only some + * implementations understand. The technique used here is: + * + * a) If possible, follow the standard exactly. This handles + * files up to 8 gigabytes minus 1. + * + * b) If that fails, try octal but omit the field terminator. + * That handles files up to 64 gigabytes minus 1. + * + * c) Otherwise, use base-256 extensions. That handles files + * up to 2^63 in this implementation, with the potential to + * go up to 2^94. That should hold us for a while. ;-) + * + * The non-strict formatter uses similar logic for other + * numeric fields, though they're less critical. + */ + __archive_write_format_header_ustar(a, ustarbuff, entry_main, -1, 0); /* If we built any extended attributes, write that entry first. */ ret = 0; @@ -624,7 +647,7 @@ archive_write_pax_header(struct archive *a, archive_entry_gname(entry_main)); ret = __archive_write_format_header_ustar(a, paxbuff, - pax_attr_entry, 'x'); + pax_attr_entry, 'x', 1); archive_entry_free(pax_attr_entry); archive_string_free(&pax_entry_name); |