return false;
st->archive_file_size = 0;
-
+
if (!tar_sparse_scan (file, scan_begin, NULL))
return false;
memset (blk->buffer + bytes_read, 0, BLOCKSIZE - bytes_read);
bytes_left -= bytes_read;
file->dumped_size += bytes_read;
- mv_size_left (file->stat_info->archive_file_size - file->dumped_size);
set_next_block_after (blk);
}
{
size_t i;
- mv_begin (file.stat_info);
+ mv_begin_write (file.stat_info->file_name,
+ file.stat_info->stat.st_size,
+ file.stat_info->archive_file_size - file.dumped_size);
for (i = 0; rc && i < file.stat_info->sparse_map_avail; i++)
rc = tar_sparse_dump_region (&file, i);
- mv_end ();
}
}
return false;
size_left = file->stat_info->sparse_map[i].numbytes;
mv_size_left (file->stat_info->archive_file_size - file->dumped_size);
-
+
while (size_left > 0)
{
size_t bytes_read;
file.stat_info = st;
file.fd = fd;
file.seekable = true; /* File *must* be seekable for compare to work */
-
+
rc = tar_sparse_decode_header (&file);
- mv_begin (st);
+ mv_begin_read (st);
for (i = 0; rc && i < file.stat_info->sparse_map_avail; i++)
{
rc = check_sparse_region (&file,
if (!rc)
skip_file (file.stat_info->archive_file_size - file.dumped_size);
mv_end ();
-
+
tar_sparse_done (&file);
return rc;
}
instances of GNU.sparse.offset/GNU.sparse.numbytes variables, whereas
POSIX requires the latest occurrence of the variable to override all
previous occurrences.
-
+
To avoid this incompatibility two following versions were introduced.
* 0.1
Used by tar 1.15.2 -- 1.15.91 (alpha releases).
-
+
The sparse file map is stored in
x header:
Starting from this version, the exact sparse format version is specified
explicitely in the header using the following variables:
- GNU.sparse.major Major version
+ GNU.sparse.major Major version
GNU.sparse.minor Minor version
X header keeps the following variables:
-
+
GNU.sparse.name Real file name of the sparse file
GNU.sparse.realsize Real size of the stored file (corresponds to the old
GNU.sparse.size variable)
The name field of the ustar header is constructed using the pattern
"%d/GNUSparseFile.%p/%f".
-
+
The sparse map itself is stored in the file data block, preceding the actual
file data. It consists of a series of octal numbers of arbitrary length,
delimited by newlines. The map is padded with nulls to the nearest block
char nbuf[UINTMAX_STRSIZE_BOUND];
struct sp_array *map = file->stat_info->sparse_map;
char *save_file_name = NULL;
-
+
/* Store the real file size */
xheader_store ("GNU.sparse.size", file->stat_info, NULL);
xheader_store ("GNU.sparse.numblocks", file->stat_info, NULL);
-
+
if (xheader_keyword_deleted_p ("GNU.sparse.map")
|| tar_sparse_minor == 0)
{
#define COPY_STRING(b,dst,src) do \
{ \
char *endp = b->buffer + BLOCKSIZE; \
- char *srcp = src; \
+ char const *srcp = src; \
while (*srcp) \
{ \
if (dst == endp) \
} \
*dst++ = *srcp++; \
} \
- } while (0)
+ } while (0)
/* Compute stored file size */
p = umaxtostr (file->stat_info->sparse_map_avail, nbuf);
size = (size + BLOCKSIZE - 1) / BLOCKSIZE;
file->stat_info->archive_file_size += size * BLOCKSIZE;
file->dumped_size += size * BLOCKSIZE;
-
+
/* Store sparse file identification */
xheader_store ("GNU.sparse.major", file->stat_info, NULL);
xheader_store ("GNU.sparse.minor", file->stat_info, NULL);
xheader_store ("GNU.sparse.name", file->stat_info, NULL);
xheader_store ("GNU.sparse.realsize", file->stat_info, NULL);
-
+
file->stat_info->file_name = xheader_format_name (file->stat_info,
"%d/GNUSparseFile.%p/%f", 0);
if (!ISDIGIT (*arg))
return false;
-
+
u = strtoumax (arg, &arg_lim, 10);
if (! (u <= maxval && errno != ERANGE) || *arg_lim)
return false;
-
+
*num = u;
return true;
}
} \
while (*dst++ != '\n'); \
dst[-1] = 0; \
- } while (0)
+ } while (0)
set_next_block_after (current_header);
file->dumped_size += BLOCKSIZE;
COPY_BUF (blk,nbuf,p);
if (!decode_num (&u, nbuf, TYPE_MAXIMUM (size_t)))
{
- ERROR ((0, 0, _("%s: malformed sparse archive member"),
+ ERROR ((0, 0, _("%s: malformed sparse archive member"),
file->stat_info->orig_file_name));
return false;
}
for (i = 0; i < file->stat_info->sparse_map_size; i++)
{
struct sp_array sp;
-
+
COPY_BUF (blk,nbuf,p);
if (!decode_num (&u, nbuf, TYPE_MAXIMUM (off_t)))
{
- ERROR ((0, 0, _("%s: malformed sparse archive member"),
+ ERROR ((0, 0, _("%s: malformed sparse archive member"),
file->stat_info->orig_file_name));
return false;
}
COPY_BUF (blk,nbuf,p);
if (!decode_num (&u, nbuf, TYPE_MAXIMUM (size_t)))
{
- ERROR ((0, 0, _("%s: malformed sparse archive member"),
+ ERROR ((0, 0, _("%s: malformed sparse archive member"),
file->stat_info->orig_file_name));
return false;
}
}
set_next_block_after (blk);
}
-
+
return true;
}
pax_sparse_member_p,
pax_dump_header,
NULL,
- pax_decode_header,
+ pax_decode_header,
NULL, /* No scan_block function */
sparse_dump_region,
sparse_extract_region,