summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorcperciva <cperciva@FreeBSD.org>2007-03-31 22:59:43 +0000
committercperciva <cperciva@FreeBSD.org>2007-03-31 22:59:43 +0000
commit5ca8f701f1424bb5e1b4504e01a71f01252654f1 (patch)
tree1361de2a0496b3c2146c0eb0ea65d53aa30e8982 /lib
parent7af0b4e5ce104914d5971547b0fea1984ef4d6c4 (diff)
downloadFreeBSD-src-5ca8f701f1424bb5e1b4504e01a71f01252654f1.zip
FreeBSD-src-5ca8f701f1424bb5e1b4504e01a71f01252654f1.tar.gz
Provide a dummy compression-layer skip function which just reads data and
discards it, for use when the compression layer code doesn't know how to skip data (e.g., everything other than the "none" compressor). This makes format level code simpler because that code can now assume that the compression layer always knows how to skip and will always skip exactly the requested number of bytes. Discussed with: kientzle (3 months ago)
Diffstat (limited to 'lib')
-rw-r--r--lib/libarchive/archive_read.c40
-rw-r--r--lib/libarchive/archive_read_support_format_iso9660.c28
-rw-r--r--lib/libarchive/archive_read_support_format_tar.c10
3 files changed, 44 insertions, 34 deletions
diff --git a/lib/libarchive/archive_read.c b/lib/libarchive/archive_read.c
index c92b20c..06a4e8c 100644
--- a/lib/libarchive/archive_read.c
+++ b/lib/libarchive/archive_read.c
@@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$");
static int choose_decompressor(struct archive_read *, const void*, size_t);
static int choose_format(struct archive_read *);
+static off_t dummy_skip(struct archive_read *, off_t);
/*
* Allocate, initialize and return a struct archive object.
@@ -191,6 +192,13 @@ archive_read_open2(struct archive *_a, void *client_data,
if (e == ARCHIVE_OK)
a->archive.state = ARCHIVE_STATE_HEADER;
+ /*
+ * If the decompressor didn't register a skip function, provide a
+ * dummy compression-layer skip function.
+ */
+ if (a->compression_skip == NULL)
+ a->compression_skip = dummy_skip;
+
return (e);
}
@@ -244,6 +252,38 @@ choose_decompressor(struct archive_read *a,
}
/*
+ * Dummy skip function, for use if the compression layer doesn't provide
+ * one: This code just reads data and discards it.
+ */
+static off_t
+dummy_skip(struct archive_read * a, off_t request)
+{
+ const void * dummy_buffer;
+ ssize_t bytes_read;
+ off_t bytes_skipped;
+
+ for (bytes_skipped = 0; request > 0;) {
+ bytes_read = (a->compression_read_ahead)(a, &dummy_buffer, 1);
+ if (bytes_read < 0)
+ return (bytes_read);
+ if (bytes_read == 0) {
+ /* Premature EOF. */
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Truncated input file (need to skip %jd bytes)",
+ (intmax_t)request);
+ return (ARCHIVE_FATAL);
+ }
+ if (bytes_read > request)
+ bytes_read = request;
+ (a->compression_read_consume)(a, bytes_read);
+ request -= bytes_read;
+ bytes_skipped += bytes_read;
+ }
+
+ return (bytes_skipped);
+}
+
+/*
* Read header of next entry.
*/
int
diff --git a/lib/libarchive/archive_read_support_format_iso9660.c b/lib/libarchive/archive_read_support_format_iso9660.c
index f115b0e..c892f72 100644
--- a/lib/libarchive/archive_read_support_format_iso9660.c
+++ b/lib/libarchive/archive_read_support_format_iso9660.c
@@ -917,33 +917,13 @@ 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) {
+ if (iso9660->current_position < offset) {
off_t step = offset - iso9660->current_position;
off_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;
- const void *buff;
-
- if (step > iso9660->logical_block_size)
- step = iso9660->logical_block_size;
- bytes_read = (a->compression_read_ahead)(a, &buff, step);
- if (bytes_read <= 0) {
- release_file(iso9660, file);
- return (ARCHIVE_FATAL);
- }
- if (bytes_read > step)
- bytes_read = step;
- iso9660->current_position += bytes_read;
- (a->compression_read_consume)(a, bytes_read);
+ if (bytes_read < 0)
+ return (bytes_read);
+ iso9660->current_position = offset;
}
/* We found body of file; handle it now. */
diff --git a/lib/libarchive/archive_read_support_format_tar.c b/lib/libarchive/archive_read_support_format_tar.c
index 8aa5a38..3c24733 100644
--- a/lib/libarchive/archive_read_support_format_tar.c
+++ b/lib/libarchive/archive_read_support_format_tar.c
@@ -546,18 +546,8 @@ archive_read_format_tar_skip(struct archive_read *a)
off_t bytes_skipped;
struct tar* tar;
struct sparse_block *p;
- int r = ARCHIVE_OK;
- const void *b; /* dummy variables */
- size_t s;
- off_t o;
-
tar = (struct tar *)*(a->pformat_data);
- if (a->compression_skip == NULL) {
- while (r == ARCHIVE_OK)
- r = archive_read_format_tar_read_data(a, &b, &s, &o);
- return (r);
- }
/*
* Compression layer skip functions are required to either skip the
OpenPOWER on IntegriCloud