aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTim Kientzle <kientzle@FreeBSD.org>2006-11-27 16:30:32 +0000
committerTim Kientzle <kientzle@FreeBSD.org>2006-11-27 16:30:32 +0000
commita6fac34b43cd0afe1df8496b2a193335731e91b3 (patch)
treea41899b133dd2abd971e861588672c1c9e70783b /lib
parentafe7b9fbb5378532b626782b90246285a023cf6a (diff)
downloadsrc-a6fac34b43cd0afe1df8496b2a193335731e91b3.tar.gz
src-a6fac34b43cd0afe1df8496b2a193335731e91b3.zip
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
Notes
Notes: svn path=/head/; revision=164674
Diffstat (limited to 'lib')
-rw-r--r--lib/libarchive/archive_read_support_format_iso9660.c29
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 00f20321f2b0..7ef079f01400 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;