bin/86690: bsdtar sparse file problems
Tim Kientzle
kientzle at freebsd.org
Sun Oct 2 20:21:22 PDT 2005
Juergen Lock wrote:
>
> Hmm i just tried it on a 60beta4 vm i still had lying around:
>
> FreeBSD qemutest.kn-bremen.de 6.0-BETA4 FreeBSD 6.0-BETA4 #0: Sun Sep 4 09:18:09 UTC 2005 root at x64.samsco.home:/usr/obj/usr/src/sys/GENERIC i386
>
> and there it still extracts it to a 1 byte file. Has this been
> fixed between beta4 and 5?
Juergen,
Try the attached patch against libarchive in 6.0 and let me know if this
fixes it for you. Looks like the offset for the very first sparse block
was being ignored.
Tim
-------------- next part --------------
Index: archive_read_support_format_tar.c
===================================================================
RCS file: /home/ncvs/src/lib/libarchive/archive_read_support_format_tar.c,v
retrieving revision 1.36
diff -u -r1.36 archive_read_support_format_tar.c
--- archive_read_support_format_tar.c 24 Sep 2005 21:15:00 -0000 1.36
+++ archive_read_support_format_tar.c 3 Oct 2005 03:17:35 -0000
@@ -450,24 +450,34 @@
struct sparse_block *p;
tar = *(a->pformat_data);
- if (tar->entry_bytes_remaining > 0) {
- bytes_read = (a->compression_read_ahead)(a, buff, 1);
- if (bytes_read <= 0)
- return (ARCHIVE_FATAL);
- if (bytes_read > tar->entry_bytes_remaining)
- bytes_read = tar->entry_bytes_remaining;
+ if (tar->sparse_list != NULL) {
+ /* Remove exhausted entries from sparse list. */
while (tar->sparse_list != NULL &&
tar->sparse_list->remaining == 0) {
p = tar->sparse_list;
tar->sparse_list = p->next;
free(p);
- if (tar->sparse_list != NULL)
- tar->entry_offset = tar->sparse_list->offset;
}
+ if (tar->sparse_list == NULL) {
+ /* We exhausted the entire sparse list. */
+ tar->entry_bytes_remaining = 0;
+ }
+ }
+
+ if (tar->entry_bytes_remaining > 0) {
+ bytes_read = (a->compression_read_ahead)(a, buff, 1);
+ if (bytes_read <= 0)
+ return (ARCHIVE_FATAL);
+ if (bytes_read > tar->entry_bytes_remaining)
+ bytes_read = tar->entry_bytes_remaining;
if (tar->sparse_list != NULL) {
+ /* Don't read more than is available in the
+ * current sparse block. */
if (tar->sparse_list->remaining < bytes_read)
bytes_read = tar->sparse_list->remaining;
+ tar->entry_offset = tar->sparse_list->offset;
tar->sparse_list->remaining -= bytes_read;
+ tar->sparse_list->offset += bytes_read;
}
*size = bytes_read;
*offset = tar->entry_offset;
More information about the freebsd-bugs
mailing list