tar/tar-1.15.1-hugeSparse.patch

351 lines
9.9 KiB
Diff
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

--- tar-1.15.1/src/sparse.c.hugeSparse 2006-03-22 13:18:53.000000000 -0500
+++ tar-1.15.1/src/sparse.c 2006-03-22 13:24:54.000000000 -0500
@@ -47,9 +47,9 @@
{
int fd; /* File descriptor */
bool seekable; /* Is fd seekable? */
- size_t offset; /* Current offset in fd if seekable==false.
+ off_t offset; /* Current offset in fd if seekable==false.
Otherwise unused */
- size_t dumped_size; /* Number of bytes actually written
+ off_t dumped_size; /* Number of bytes actually written
to the archive */
struct tar_stat_info *stat_info; /* Information about the file */
struct tar_sparse_optab *optab;
@@ -59,35 +59,34 @@
/* Dump zeros to file->fd until offset is reached. It is used instead of
lseek if the output file is not seekable */
-static long
+static bool
dump_zeros (struct tar_sparse_file *file, off_t offset)
{
- char buf[BLOCKSIZE];
-
- if (offset - file->offset < 0)
+ static char const zero_buf[BLOCKSIZE];
+
+ if (offset < file->offset)
{
errno = EINVAL;
- return -1;
+ return false;
}
- memset (buf, 0, sizeof buf);
while (file->offset < offset)
{
- size_t size = offset - file->offset;
- size_t wrbytes;
-
- if (size > sizeof buf)
- size = sizeof buf;
- wrbytes = write (file->fd, buf, size);
+ size_t size = (BLOCKSIZE < offset - file->offset
+ ? BLOCKSIZE
+ : offset - file->offset);
+ ssize_t wrbytes;
+
+ wrbytes = write (file->fd, zero_buf, size);
if (wrbytes <= 0)
{
if (wrbytes == 0)
errno = EINVAL;
- return -1;
+ return false;
}
file->offset += wrbytes;
}
- return file->offset;
+ return true;
}
static bool
@@ -168,14 +167,9 @@
static bool
lseek_or_error (struct tar_sparse_file *file, off_t offset)
{
- off_t off;
-
- if (file->seekable)
- off = lseek (file->fd, offset, SEEK_SET);
- else
- off = dump_zeros (file, offset);
-
- if (off < 0)
+ if (file->seekable
+ ? lseek (file->fd, offset, SEEK_SET) < 0
+ : ! dump_zeros (file, offset))
{
seek_diag_details (file->stat_info->orig_file_name, offset);
return false;
@@ -187,7 +181,7 @@
it's made *entirely* of zeros, returning a 0 the instant it finds
something that is a nonzero, i.e., useful data. */
static bool
-zero_block_p (char *buffer, size_t size)
+zero_block_p (char const *buffer, size_t size)
{
while (size--)
if (*buffer++)
@@ -195,50 +189,36 @@
return true;
}
-#define clear_block(p) memset (p, 0, BLOCKSIZE);
-
-#define SPARSES_INIT_COUNT SPARSES_IN_SPARSE_HEADER
-
static void
-sparse_add_map (struct tar_sparse_file *file, struct sp_array *sp)
+sparse_add_map (struct tar_stat_info *st, struct sp_array const *sp)
{
- if (file->stat_info->sparse_map == NULL)
- {
- file->stat_info->sparse_map =
- xmalloc (SPARSES_INIT_COUNT * sizeof file->stat_info->sparse_map[0]);
- file->stat_info->sparse_map_size = SPARSES_INIT_COUNT;
- }
- else if (file->stat_info->sparse_map_avail == file->stat_info->sparse_map_size)
- {
- file->stat_info->sparse_map_size *= 2;
- file->stat_info->sparse_map =
- xrealloc (file->stat_info->sparse_map,
- file->stat_info->sparse_map_size
- * sizeof file->stat_info->sparse_map[0]);
- }
- file->stat_info->sparse_map[file->stat_info->sparse_map_avail++] = *sp;
+ struct sp_array *sparse_map = st->sparse_map;
+ size_t avail = st->sparse_map_avail;
+ if (avail == st->sparse_map_size)
+ st->sparse_map = sparse_map =
+ x2nrealloc (sparse_map, &st->sparse_map_size, sizeof *sparse_map);
+ sparse_map[avail] = *sp;
+ st->sparse_map_avail = avail + 1;
}
/* Scan the sparse file and create its map */
static bool
sparse_scan_file (struct tar_sparse_file *file)
{
- static char buffer[BLOCKSIZE];
+ struct tar_stat_info *st = file->stat_info;
+ int fd = file->fd;
+ char buffer[BLOCKSIZE];
size_t count;
off_t offset = 0;
struct sp_array sp = {0, 0};
if (!lseek_or_error (file, 0))
return false;
- clear_block (buffer);
-
- file->stat_info->sparse_map_avail = 0;
- file->stat_info->archive_file_size = 0;
if (!tar_sparse_scan (file, scan_begin, NULL))
return false;
- while ((count = safe_read (file->fd, buffer, sizeof buffer)) != 0
+ while ((count = safe_read (fd, buffer, sizeof buffer)) != 0
&& count != SAFE_READ_ERROR)
{
/* Analize the block */
@@ -246,7 +226,7 @@
{
if (sp.numbytes)
{
- sparse_add_map (file, &sp);
+ sparse_add_map (st, &sp);
sp.numbytes = 0;
if (!tar_sparse_scan (file, scan_block, NULL))
return false;
@@ -257,26 +237,25 @@
if (sp.numbytes == 0)
sp.offset = offset;
sp.numbytes += count;
- file->stat_info->archive_file_size += count;
+ st->archive_file_size += count;
if (!tar_sparse_scan (file, scan_block, buffer))
return false;
}
offset += count;
- clear_block (buffer);
}
if (sp.numbytes == 0)
sp.offset = offset;
- sparse_add_map (file, &sp);
- file->stat_info->archive_file_size += count;
+ sparse_add_map (st, &sp);
+ st->archive_file_size += count;
return tar_sparse_scan (file, scan_end, NULL);
}
-static struct tar_sparse_optab oldgnu_optab;
-static struct tar_sparse_optab star_optab;
-static struct tar_sparse_optab pax_optab;
+static struct tar_sparse_optab const oldgnu_optab;
+static struct tar_sparse_optab const star_optab;
+static struct tar_sparse_optab const pax_optab;
static bool
sparse_select_optab (struct tar_sparse_file *file)
@@ -321,18 +300,18 @@
size_t bytes_read;
blk = find_next_block ();
- memset (blk->buffer, 0, BLOCKSIZE);
bytes_read = safe_read (file->fd, blk->buffer, bufsize);
if (bytes_read == SAFE_READ_ERROR)
{
read_diag_details (file->stat_info->orig_file_name,
- file->stat_info->sparse_map[i].offset
- + file->stat_info->sparse_map[i].numbytes
- - bytes_left,
- bufsize);
+ (file->stat_info->sparse_map[i].offset
+ + file->stat_info->sparse_map[i].numbytes
+ - bytes_left),
+ bufsize);
return false;
}
+ memset (blk->buffer + bytes_read, 0, BLOCKSIZE - bytes_read);
bytes_left -= bytes_read;
file->dumped_size += bytes_read;
set_next_block_after (blk);
@@ -389,12 +368,11 @@
sparse_dump_file (int fd, struct tar_stat_info *st)
{
bool rc;
- struct tar_sparse_file file;
+ struct tar_sparse_file file = { 0, };
file.stat_info = st;
file.fd = fd;
file.seekable = true; /* File *must* be seekable for dump to work */
- file.offset = 0;
if (!sparse_select_optab (&file)
|| !tar_sparse_init (&file))
@@ -456,15 +434,14 @@
struct tar_sparse_file file;
size_t i;
+ if (!tar_sparse_init (&file))
+ return dump_status_not_implemented;
+
file.stat_info = st;
file.fd = fd;
file.seekable = lseek (fd, 0, SEEK_SET) == 0;
file.offset = 0;
- if (!sparse_select_optab (&file)
- || !tar_sparse_init (&file))
- return dump_status_not_implemented;
-
rc = tar_sparse_decode_header (&file);
for (i = 0; rc && i < file.stat_info->sparse_map_avail; i++)
rc = tar_sparse_extract_region (&file, i);
@@ -491,8 +468,6 @@
}
-static char diff_buffer[BLOCKSIZE];
-
static bool
check_sparse_region (struct tar_sparse_file *file, off_t beg, off_t end)
{
@@ -502,11 +477,9 @@
while (beg < end)
{
size_t bytes_read;
- size_t rdsize = end - beg;
+ size_t rdsize = BLOCKSIZE < end - beg ? BLOCKSIZE : end - beg;
+ char diff_buffer[BLOCKSIZE];
- if (rdsize > BLOCKSIZE)
- rdsize = BLOCKSIZE;
- clear_block (diff_buffer);
bytes_read = safe_read (file->fd, diff_buffer, rdsize);
if (bytes_read == SAFE_READ_ERROR)
{
@@ -539,6 +512,7 @@
{
size_t bytes_read;
size_t rdsize = (size_left > BLOCKSIZE) ? BLOCKSIZE : size_left;
+ char diff_buffer[BLOCKSIZE];
union block *blk = find_next_block ();
if (!blk)
@@ -551,9 +525,9 @@
if (bytes_read == SAFE_READ_ERROR)
{
read_diag_details (file->stat_info->orig_file_name,
- file->stat_info->sparse_map[i].offset
- + file->stat_info->sparse_map[i].numbytes
- - size_left,
+ (file->stat_info->sparse_map[i].offset
+ + file->stat_info->sparse_map[i].numbytes
+ - size_left),
rdsize);
return false;
}
@@ -647,7 +621,7 @@
|| file->stat_info->archive_file_size < 0)
return add_fail;
- sparse_add_map (file, &sp);
+ sparse_add_map (file->stat_info, &sp);
return add_ok;
}
@@ -669,7 +643,7 @@
size_t i;
union block *h = current_header;
int ext_p;
- static enum oldgnu_add_status rc;
+ enum oldgnu_add_status rc;
file->stat_info->sparse_map_avail = 0;
for (i = 0; i < SPARSES_IN_OLDGNU_HEADER; i++)
@@ -756,7 +730,7 @@
return true;
}
-static struct tar_sparse_optab oldgnu_optab = {
+static struct tar_sparse_optab const oldgnu_optab = {
NULL, /* No init function */
NULL, /* No done function */
oldgnu_sparse_member_p,
@@ -795,7 +769,7 @@
size_t i;
union block *h = current_header;
int ext_p;
- static enum oldgnu_add_status rc;
+ enum oldgnu_add_status rc;
file->stat_info->sparse_map_avail = 0;
@@ -837,7 +811,7 @@
}
-static struct tar_sparse_optab star_optab = {
+static struct tar_sparse_optab const star_optab = {
NULL, /* No init function */
NULL, /* No done function */
star_sparse_member_p,
@@ -890,7 +864,7 @@
return true;
}
-static struct tar_sparse_optab pax_optab = {
+static struct tar_sparse_optab const pax_optab = {
NULL, /* No init function */
NULL, /* No done function */
pax_sparse_member_p,