|
@@ -1,6 +1,6 @@
|
|
|
/* Functions for dealing with sparse files
|
|
|
|
|
|
- Copyright 2003-2007, 2010, 2013-2017 Free Software Foundation, Inc.
|
|
|
+ Copyright 2003-2007, 2010, 2013-2018 Free Software Foundation, Inc.
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify it
|
|
|
under the terms of the GNU General Public License as published by the
|
|
@@ -427,6 +427,30 @@ sparse_dump_region (struct tar_sparse_file *file, size_t i)
|
|
|
bufsize);
|
|
|
return false;
|
|
|
}
|
|
|
+ else if (bytes_read == 0)
|
|
|
+ {
|
|
|
+ char buf[UINTMAX_STRSIZE_BOUND];
|
|
|
+ struct stat st;
|
|
|
+ size_t n;
|
|
|
+ if (fstat (file->fd, &st) == 0)
|
|
|
+ n = file->stat_info->stat.st_size - st.st_size;
|
|
|
+ else
|
|
|
+ n = file->stat_info->stat.st_size
|
|
|
+ - (file->stat_info->sparse_map[i].offset
|
|
|
+ + file->stat_info->sparse_map[i].numbytes
|
|
|
+ - bytes_left);
|
|
|
+
|
|
|
+ WARNOPT (WARN_FILE_SHRANK,
|
|
|
+ (0, 0,
|
|
|
+ ngettext ("%s: File shrank by %s byte; padding with zeros",
|
|
|
+ "%s: File shrank by %s bytes; padding with zeros",
|
|
|
+ n),
|
|
|
+ quotearg_colon (file->stat_info->orig_file_name),
|
|
|
+ STRINGIFY_BIGINT (n, buf)));
|
|
|
+ if (! ignore_failed_read_option)
|
|
|
+ set_exit_status (TAREXIT_DIFFERS);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
|
|
|
memset (blk->buffer + bytes_read, 0, BLOCKSIZE - bytes_read);
|
|
|
bytes_left -= bytes_read;
|
|
@@ -464,9 +488,9 @@ sparse_extract_region (struct tar_sparse_file *file, size_t i)
|
|
|
return false;
|
|
|
}
|
|
|
set_next_block_after (blk);
|
|
|
+ file->dumped_size += BLOCKSIZE;
|
|
|
count = blocking_write (file->fd, blk->buffer, wrbytes);
|
|
|
write_size -= count;
|
|
|
- file->dumped_size += count;
|
|
|
mv_size_left (file->stat_info->archive_file_size - file->dumped_size);
|
|
|
file->offset += count;
|
|
|
if (count != wrbytes)
|
|
@@ -598,6 +622,12 @@ check_sparse_region (struct tar_sparse_file *file, off_t beg, off_t end)
|
|
|
rdsize);
|
|
|
return false;
|
|
|
}
|
|
|
+ else if (bytes_read == 0)
|
|
|
+ {
|
|
|
+ report_difference (file->stat_info, _("Size differs"));
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
if (!zero_block_p (diff_buffer, bytes_read))
|
|
|
{
|
|
|
char begbuf[INT_BUFSIZE_BOUND (off_t)];
|
|
@@ -609,6 +639,7 @@ check_sparse_region (struct tar_sparse_file *file, off_t beg, off_t end)
|
|
|
|
|
|
beg += bytes_read;
|
|
|
}
|
|
|
+
|
|
|
return true;
|
|
|
}
|
|
|
|
|
@@ -635,6 +666,7 @@ check_data_region (struct tar_sparse_file *file, size_t i)
|
|
|
return false;
|
|
|
}
|
|
|
set_next_block_after (blk);
|
|
|
+ file->dumped_size += BLOCKSIZE;
|
|
|
bytes_read = safe_read (file->fd, diff_buffer, rdsize);
|
|
|
if (bytes_read == SAFE_READ_ERROR)
|
|
|
{
|
|
@@ -645,7 +677,11 @@ check_data_region (struct tar_sparse_file *file, size_t i)
|
|
|
rdsize);
|
|
|
return false;
|
|
|
}
|
|
|
- file->dumped_size += bytes_read;
|
|
|
+ else if (bytes_read == 0)
|
|
|
+ {
|
|
|
+ report_difference (¤t_stat_info, _("Size differs"));
|
|
|
+ return false;
|
|
|
+ }
|
|
|
size_left -= bytes_read;
|
|
|
mv_size_left (file->stat_info->archive_file_size - file->dumped_size);
|
|
|
if (memcmp (blk->buffer, diff_buffer, rdsize))
|
|
@@ -1213,7 +1249,8 @@ pax_decode_header (struct tar_sparse_file *file)
|
|
|
union block *blk;
|
|
|
char *p;
|
|
|
size_t i;
|
|
|
-
|
|
|
+ off_t start;
|
|
|
+
|
|
|
#define COPY_BUF(b,buf,src) do \
|
|
|
{ \
|
|
|
char *endp = b->buffer + BLOCKSIZE; \
|
|
@@ -1229,7 +1266,6 @@ pax_decode_header (struct tar_sparse_file *file)
|
|
|
if (src == endp) \
|
|
|
{ \
|
|
|
set_next_block_after (b); \
|
|
|
- file->dumped_size += BLOCKSIZE; \
|
|
|
b = find_next_block (); \
|
|
|
src = b->buffer; \
|
|
|
endp = b->buffer + BLOCKSIZE; \
|
|
@@ -1240,8 +1276,8 @@ pax_decode_header (struct tar_sparse_file *file)
|
|
|
dst[-1] = 0; \
|
|
|
} while (0)
|
|
|
|
|
|
+ start = current_block_ordinal ();
|
|
|
set_next_block_after (current_header);
|
|
|
- file->dumped_size += BLOCKSIZE;
|
|
|
blk = find_next_block ();
|
|
|
p = blk->buffer;
|
|
|
COPY_BUF (blk,nbuf,p);
|
|
@@ -1278,6 +1314,8 @@ pax_decode_header (struct tar_sparse_file *file)
|
|
|
sparse_add_map (file->stat_info, &sp);
|
|
|
}
|
|
|
set_next_block_after (blk);
|
|
|
+
|
|
|
+ file->dumped_size += BLOCKSIZE * (current_block_ordinal () - start);
|
|
|
}
|
|
|
|
|
|
return true;
|