diff options
author | cperciva <cperciva@FreeBSD.org> | 2007-01-03 13:16:59 +0000 |
---|---|---|
committer | cperciva <cperciva@FreeBSD.org> | 2007-01-03 13:16:59 +0000 |
commit | 13863638a524af6cfd2680ea8f971e75c89cb671 (patch) | |
tree | 174c5f6034f1d3df1f633fd80a876c4f89e3cf51 /lib | |
parent | 2ccef570147b02f17967d546d2519b725f295b1c (diff) | |
download | FreeBSD-src-13863638a524af6cfd2680ea8f971e75c89cb671.zip FreeBSD-src-13863638a524af6cfd2680ea8f971e75c89cb671.tar.gz |
Insert zero-padding between sparse blocks in archive_read_data(). This
fixes "tar -c @foo.tar" where "foo.tar" contains sparse entries.
MFC after: 1 week
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libarchive/archive_read.c | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/lib/libarchive/archive_read.c b/lib/libarchive/archive_read.c index 26ad816..aa90b3f 100644 --- a/lib/libarchive/archive_read.c +++ b/lib/libarchive/archive_read.c @@ -430,7 +430,28 @@ archive_read_data(struct archive *a, void *buff, size_t s) archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT, "Encountered out-of-order sparse blocks"); return (ARCHIVE_RETRY); - } else { + } + + /* Compute the amount of zero padding needed. */ + if (a->read_data_output_offset + s < + a->read_data_offset) { + len = s; + } else if (a->read_data_output_offset < + a->read_data_offset) { + len = a->read_data_offset - + a->read_data_output_offset; + } else + len = 0; + + /* Add zeroes. */ + memset(dest, 0, len); + s -= len; + a->read_data_output_offset += len; + dest += len; + bytes_read += len; + + /* Copy data if there is any space left. */ + if (s > 0) { len = a->read_data_remaining; if (len > s) len = s; |