diff options
author | kientzle <kientzle@FreeBSD.org> | 2006-11-27 16:30:32 +0000 |
---|---|---|
committer | kientzle <kientzle@FreeBSD.org> | 2006-11-27 16:30:32 +0000 |
commit | b0a259a119095a312283f38b1211dee644d90232 (patch) | |
tree | a41899b133dd2abd971e861588672c1c9e70783b /lib/libarchive/archive_read_support_format_iso9660.c | |
parent | 2f8ab38300aecf93354cbcbcf42b5ef86db1de7a (diff) | |
download | FreeBSD-src-b0a259a119095a312283f38b1211dee644d90232.zip FreeBSD-src-b0a259a119095a312283f38b1211dee644d90232.tar.gz |
Improve support for large ISOs:
* Correct a signed/unsigned problem that broke handling of files >2G.
* Implement "skip" support for much faster "tar -t".
Thanks to: Robert Sciuk for sending me a DVD that illustrated the first problem
Diffstat (limited to 'lib/libarchive/archive_read_support_format_iso9660.c')
-rw-r--r-- | lib/libarchive/archive_read_support_format_iso9660.c | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/lib/libarchive/archive_read_support_format_iso9660.c b/lib/libarchive/archive_read_support_format_iso9660.c index 00f2032..7ef079f 100644 --- a/lib/libarchive/archive_read_support_format_iso9660.c +++ b/lib/libarchive/archive_read_support_format_iso9660.c @@ -219,7 +219,7 @@ struct iso9660 { ssize_t logical_block_size; off_t entry_sparse_offset; - ssize_t entry_bytes_remaining; + int64_t entry_bytes_remaining; }; static void add_entry(struct iso9660 *iso9660, struct file_info *file); @@ -227,6 +227,7 @@ static int archive_read_format_iso9660_bid(struct archive *); static int archive_read_format_iso9660_cleanup(struct archive *); static int archive_read_format_iso9660_read_data(struct archive *, const void **, size_t *, off_t *); +static int archive_read_format_iso9660_read_data_skip(struct archive *); static int archive_read_format_iso9660_read_header(struct archive *, struct archive_entry *); static const char *build_pathname(struct archive_string *, struct file_info *); @@ -245,7 +246,7 @@ static void parse_rockridge(struct iso9660 *iso9660, struct file_info *file, const unsigned char *start, const unsigned char *end); static void release_file(struct iso9660 *, struct file_info *); -static int toi(const void *p, int n); +static unsigned toi(const void *p, int n); int archive_read_support_format_iso9660(struct archive *a) @@ -267,7 +268,7 @@ archive_read_support_format_iso9660(struct archive *a) archive_read_format_iso9660_bid, archive_read_format_iso9660_read_header, archive_read_format_iso9660_read_data, - NULL, + archive_read_format_iso9660_read_data_skip, archive_read_format_iso9660_cleanup); if (r != ARCHIVE_OK) { @@ -459,6 +460,15 @@ archive_read_format_iso9660_read_header(struct archive *a, } static int +archive_read_format_iso9660_read_data_skip(struct archive *a) +{ + /* Because read_next_header always does an explicit skip + * to the next entry, we don't need to do anything here. */ + (void)a; /* UNUSED */ + return (ARCHIVE_OK); +} + +static int archive_read_format_iso9660_read_data(struct archive *a, const void **buff, size_t *size, off_t *offset) { @@ -906,6 +916,17 @@ fprintf(stderr, " *** Discarding CE data.\n"); offset = file->offset; /* Seek forward to the start of the entry. */ + /* Use fast compression_skip if it's available. */ + if (iso9660->current_position < offset + && a->compression_skip != NULL) { + ssize_t step = offset - iso9660->current_position; + ssize_t bytes_read; + bytes_read = (a->compression_skip)(a, step); + iso9660->current_position += bytes_read; + } + + /* Use a series of reads if compression_skip didn't + * get us all the way there. */ while (iso9660->current_position < offset) { ssize_t step = offset - iso9660->current_position; ssize_t bytes_read; @@ -986,7 +1007,7 @@ next_entry(struct iso9660 *iso9660) return (r); } -static int +static unsigned int toi(const void *p, int n) { const unsigned char *v = (const unsigned char *)p; |