Keep a detailed map of archive members stored in the record buffer.
A separate map (bufmap) provides information for creating multi-volume continuation headers. * src/buffer.c (bufmap): New struct. (bufmap_head, bufmap_tail, inhibit_map): New variables. (mv_begin_write): New function. (mv_begin): Rename to mv_begin_read. Rewrite using mv_begin_write. All callers changed. (mv_total_size): Remove. (bufmap_locate, bufmap_free, bufmap_reset): New functions. (_flush_write): Update bufmap. (close_archive): Free bufmap. (add_chunk_header): Take a bufmap argument. (gnu_add_multi_volume_header): Likewise. (add_multi_volume_header): Likewise. (_gnu_flush_write): Rewrite using bufmap. (real_s_name, real_s_totsize) (real_s_sizeleft) (save_name, save_totsize, save_sizeleft): Removed. All uses updated. (mv_size_left): Update bufmap_head. (mv_end): Rewrite. (multi_volume_sync): Remove. * src/common.h (mv_begin_write): New prototype. (mv_begin): Rename to mv_begin_read. * src/create.c: Use mv_begin_write instead of mv_begin. Remove calls to mv_size_left and mv_end. * src/sparse.c: Likewise. * tests/multiv07.at: Close stdin. * tests/spmvp00.at: Update AT_KEYWORDS. * tests/spmvp10.at: Likewise. * tests/multiv08.at: New testcase. * tests/Makefile.am, tests/testsuite.at: Add multiv08.at.
This commit is contained in:
259
src/buffer.c
259
src/buffer.c
@@ -76,8 +76,7 @@ static bool read_full_records = false;
|
||||
|
||||
/* We're reading, but we just read the last block and it's time to update.
|
||||
Declared in update.c
|
||||
|
||||
As least EXTERN like this one as possible. (?? --gray)
|
||||
|
||||
FIXME: Either eliminate it or move it to common.h.
|
||||
*/
|
||||
extern bool time_to_start_writing;
|
||||
@@ -101,19 +100,94 @@ static int global_volno = 1; /* volume number to print in external
|
||||
|
||||
bool write_archive_to_stdout;
|
||||
|
||||
/* Used by flush_read and flush_write to store the real info about saved
|
||||
names. */
|
||||
static char *real_s_name;
|
||||
static off_t real_s_totsize;
|
||||
static off_t real_s_sizeleft;
|
||||
|
||||
|
||||
/* Multi-volume tracking support */
|
||||
static char *save_name; /* name of the file we are currently writing */
|
||||
static off_t save_totsize; /* total size of file we are writing, only
|
||||
valid if save_name is nonzero */
|
||||
static off_t save_sizeleft; /* where we are in the file we are writing,
|
||||
only valid if save_name is nonzero */
|
||||
|
||||
/* When creating a multi-volume archive, each `bufmap' represents
|
||||
a member stored (perhaps partly) in the current record buffer.
|
||||
After flushing the record to the output media, all bufmaps that
|
||||
represent fully written members are removed from the list, then
|
||||
the sizeleft and start numbers in the remaining bufmaps are updated.
|
||||
|
||||
When reading from a multi-volume archive, the list degrades to a
|
||||
single element, which keeps information about the member currently
|
||||
being read.
|
||||
*/
|
||||
|
||||
struct bufmap
|
||||
{
|
||||
struct bufmap *next; /* Pointer to the next map entry */
|
||||
size_t start; /* Offset of the first data block */
|
||||
char *file_name; /* Name of the stored file */
|
||||
off_t sizetotal; /* Size of the stored file */
|
||||
off_t sizeleft; /* Size left to read/write */
|
||||
};
|
||||
static struct bufmap *bufmap_head, *bufmap_tail;
|
||||
|
||||
/* This variable, when set, inhibits updating the bufmap chain after
|
||||
a write. This is necessary when writing extended POSIX headers. */
|
||||
static int inhibit_map;
|
||||
|
||||
void
|
||||
mv_begin_write (const char *file_name, off_t totsize, off_t sizeleft)
|
||||
{
|
||||
if (multi_volume_option)
|
||||
{
|
||||
struct bufmap *bp = xmalloc (sizeof bp[0]);
|
||||
if (bufmap_tail)
|
||||
bufmap_tail->next = bp;
|
||||
else
|
||||
bufmap_head = bp;
|
||||
bufmap_tail = bp;
|
||||
|
||||
bp->next = NULL;
|
||||
bp->start = current_block - record_start;
|
||||
bp->file_name = xstrdup (file_name);
|
||||
bp->sizetotal = totsize;
|
||||
bp->sizeleft = sizeleft;
|
||||
}
|
||||
}
|
||||
|
||||
static struct bufmap *
|
||||
bufmap_locate (size_t off)
|
||||
{
|
||||
struct bufmap *map;
|
||||
|
||||
for (map = bufmap_head; map; map = map->next)
|
||||
{
|
||||
if (!map->next
|
||||
|| off < map->next->start * BLOCKSIZE)
|
||||
break;
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
static void
|
||||
bufmap_free (struct bufmap *mark)
|
||||
{
|
||||
struct bufmap *map;
|
||||
for (map = bufmap_head; map && map != mark; )
|
||||
{
|
||||
struct bufmap *next = map->next;
|
||||
free (map->file_name);
|
||||
free (map);
|
||||
map = next;
|
||||
}
|
||||
bufmap_head = map;
|
||||
if (!bufmap_head)
|
||||
bufmap_tail = bufmap_head;
|
||||
}
|
||||
|
||||
static void
|
||||
bufmap_reset (struct bufmap *map, ssize_t fixup)
|
||||
{
|
||||
bufmap_free (map);
|
||||
if (map)
|
||||
{
|
||||
for (; map; map = map->next)
|
||||
map->start += fixup;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static struct tar_stat_info dummy;
|
||||
@@ -125,32 +199,23 @@ buffer_write_global_xheader ()
|
||||
}
|
||||
|
||||
void
|
||||
mv_begin (struct tar_stat_info *st)
|
||||
mv_begin_read (struct tar_stat_info *st)
|
||||
{
|
||||
if (multi_volume_option)
|
||||
{
|
||||
assign_string (&save_name, st->orig_file_name);
|
||||
save_totsize = save_sizeleft = st->stat.st_size;
|
||||
}
|
||||
mv_begin_write (st->orig_file_name, st->stat.st_size, st->stat.st_size);
|
||||
}
|
||||
|
||||
void
|
||||
mv_end ()
|
||||
{
|
||||
if (multi_volume_option)
|
||||
assign_string (&save_name, 0);
|
||||
}
|
||||
|
||||
void
|
||||
mv_total_size (off_t size)
|
||||
{
|
||||
save_totsize = size;
|
||||
bufmap_free (NULL);
|
||||
}
|
||||
|
||||
void
|
||||
mv_size_left (off_t size)
|
||||
{
|
||||
save_sizeleft = size;
|
||||
if (bufmap_head)
|
||||
bufmap_head->sizeleft = size;
|
||||
}
|
||||
|
||||
|
||||
@@ -511,9 +576,7 @@ _open_archive (enum access_mode wanted_access)
|
||||
FATAL_ERROR ((0, 0, _("No archive name given")));
|
||||
|
||||
tar_stat_destroy (¤t_stat_info);
|
||||
save_name = 0;
|
||||
real_s_name = 0;
|
||||
|
||||
|
||||
record_index = 0;
|
||||
init_buffer ();
|
||||
|
||||
@@ -673,6 +736,20 @@ _flush_write (void)
|
||||
else
|
||||
status = sys_write_archive_buffer ();
|
||||
|
||||
if (status && multi_volume_option && !inhibit_map)
|
||||
{
|
||||
struct bufmap *map = bufmap_locate (status);
|
||||
if (map)
|
||||
{
|
||||
size_t delta = status - map->start * BLOCKSIZE;
|
||||
if (delta > map->sizeleft)
|
||||
delta = map->sizeleft;
|
||||
map->sizeleft -= delta;
|
||||
if (map->sizeleft == 0)
|
||||
map = map->next;
|
||||
bufmap_reset (map, map ? (- map->start) : 0);
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -907,12 +984,9 @@ close_archive (void)
|
||||
sys_wait_for_child (child_pid, hit_eof);
|
||||
|
||||
tar_stat_destroy (¤t_stat_info);
|
||||
if (save_name)
|
||||
free (save_name);
|
||||
if (real_s_name)
|
||||
free (real_s_name);
|
||||
free (record_buffer[0]);
|
||||
free (record_buffer[1]);
|
||||
bufmap_free (NULL);
|
||||
}
|
||||
|
||||
/* Called to initialize the global volume number. */
|
||||
@@ -1280,30 +1354,30 @@ try_new_volume (void)
|
||||
break;
|
||||
}
|
||||
|
||||
if (real_s_name)
|
||||
if (bufmap_head)
|
||||
{
|
||||
uintmax_t s;
|
||||
if (!continued_file_name
|
||||
|| strcmp (continued_file_name, real_s_name))
|
||||
|| strcmp (continued_file_name, bufmap_head->file_name))
|
||||
{
|
||||
if ((archive_format == GNU_FORMAT || archive_format == OLDGNU_FORMAT)
|
||||
&& strlen (real_s_name) >= NAME_FIELD_SIZE
|
||||
&& strncmp (continued_file_name, real_s_name,
|
||||
&& strlen (bufmap_head->file_name) >= NAME_FIELD_SIZE
|
||||
&& strncmp (continued_file_name, bufmap_head->file_name,
|
||||
NAME_FIELD_SIZE) == 0)
|
||||
WARN ((0, 0,
|
||||
_("%s is possibly continued on this volume: header contains truncated name"),
|
||||
quote (real_s_name)));
|
||||
quote (bufmap_head->file_name)));
|
||||
else
|
||||
{
|
||||
WARN ((0, 0, _("%s is not continued on this volume"),
|
||||
quote (real_s_name)));
|
||||
quote (bufmap_head->file_name)));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
s = continued_file_size + continued_file_offset;
|
||||
|
||||
if (real_s_totsize != s || s < continued_file_offset)
|
||||
if (bufmap_head->sizetotal != s || s < continued_file_offset)
|
||||
{
|
||||
char totsizebuf[UINTMAX_STRSIZE_BOUND];
|
||||
char s1buf[UINTMAX_STRSIZE_BOUND];
|
||||
@@ -1311,21 +1385,22 @@ try_new_volume (void)
|
||||
|
||||
WARN ((0, 0, _("%s is the wrong size (%s != %s + %s)"),
|
||||
quote (continued_file_name),
|
||||
STRINGIFY_BIGINT (save_totsize, totsizebuf),
|
||||
STRINGIFY_BIGINT (bufmap_head->sizetotal, totsizebuf),
|
||||
STRINGIFY_BIGINT (continued_file_size, s1buf),
|
||||
STRINGIFY_BIGINT (continued_file_offset, s2buf)));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (real_s_totsize - real_s_sizeleft != continued_file_offset)
|
||||
if (bufmap_head->sizetotal - bufmap_head->sizeleft !=
|
||||
continued_file_offset)
|
||||
{
|
||||
char totsizebuf[UINTMAX_STRSIZE_BOUND];
|
||||
char s1buf[UINTMAX_STRSIZE_BOUND];
|
||||
char s2buf[UINTMAX_STRSIZE_BOUND];
|
||||
|
||||
WARN ((0, 0, _("This volume is out of sequence (%s - %s != %s)"),
|
||||
STRINGIFY_BIGINT (real_s_totsize, totsizebuf),
|
||||
STRINGIFY_BIGINT (real_s_sizeleft, s1buf),
|
||||
STRINGIFY_BIGINT (bufmap_head->sizetotal, totsizebuf),
|
||||
STRINGIFY_BIGINT (bufmap_head->sizeleft, s1buf),
|
||||
STRINGIFY_BIGINT (continued_file_offset, s2buf)));
|
||||
|
||||
return false;
|
||||
@@ -1477,26 +1552,24 @@ add_volume_label (void)
|
||||
}
|
||||
|
||||
static void
|
||||
add_chunk_header (void)
|
||||
add_chunk_header (struct bufmap *map)
|
||||
{
|
||||
if (archive_format == POSIX_FORMAT)
|
||||
{
|
||||
off_t block_ordinal;
|
||||
union block *blk;
|
||||
struct tar_stat_info st;
|
||||
static size_t real_s_part_no; /* FIXME */
|
||||
|
||||
real_s_part_no++;
|
||||
memset (&st, 0, sizeof st);
|
||||
st.orig_file_name = st.file_name = real_s_name;
|
||||
st.orig_file_name = st.file_name = map->file_name;
|
||||
st.stat.st_mode = S_IFREG|S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH;
|
||||
st.stat.st_uid = getuid ();
|
||||
st.stat.st_gid = getgid ();
|
||||
st.orig_file_name = xheader_format_name (&st,
|
||||
"%d/GNUFileParts.%p/%f.%n",
|
||||
real_s_part_no);
|
||||
volno);
|
||||
st.file_name = st.orig_file_name;
|
||||
st.archive_file_size = st.stat.st_size = real_s_sizeleft;
|
||||
st.archive_file_size = st.stat.st_size = map->sizeleft;
|
||||
|
||||
block_ordinal = current_block_ordinal ();
|
||||
blk = start_header (&st);
|
||||
@@ -1520,27 +1593,23 @@ write_volume_label (void)
|
||||
|
||||
/* Write GNU multi-volume header */
|
||||
static void
|
||||
gnu_add_multi_volume_header (void)
|
||||
gnu_add_multi_volume_header (struct bufmap *map)
|
||||
{
|
||||
int tmp;
|
||||
union block *block = find_next_block ();
|
||||
|
||||
if (strlen (real_s_name) > NAME_FIELD_SIZE)
|
||||
if (strlen (map->file_name) > NAME_FIELD_SIZE)
|
||||
WARN ((0, 0,
|
||||
_("%s: file name too long to be stored in a GNU multivolume header, truncated"),
|
||||
quotearg_colon (real_s_name)));
|
||||
quotearg_colon (map->file_name)));
|
||||
|
||||
memset (block, 0, BLOCKSIZE);
|
||||
|
||||
/* FIXME: Michael P Urban writes: [a long name file] is being written
|
||||
when a new volume rolls around [...] Looks like the wrong value is
|
||||
being preserved in real_s_name, though. */
|
||||
|
||||
strncpy (block->header.name, real_s_name, NAME_FIELD_SIZE);
|
||||
strncpy (block->header.name, map->file_name, NAME_FIELD_SIZE);
|
||||
block->header.typeflag = GNUTYPE_MULTIVOL;
|
||||
|
||||
OFF_TO_CHARS (real_s_sizeleft, block->header.size);
|
||||
OFF_TO_CHARS (real_s_totsize - real_s_sizeleft,
|
||||
OFF_TO_CHARS (map->sizeleft, block->header.size);
|
||||
OFF_TO_CHARS (map->sizetotal - map->sizeleft,
|
||||
block->oldgnu_header.offset);
|
||||
|
||||
tmp = verbose_option;
|
||||
@@ -1553,40 +1622,17 @@ gnu_add_multi_volume_header (void)
|
||||
/* Add a multi volume header to the current archive. The exact header format
|
||||
depends on the archive format. */
|
||||
static void
|
||||
add_multi_volume_header (void)
|
||||
add_multi_volume_header (struct bufmap *map)
|
||||
{
|
||||
if (archive_format == POSIX_FORMAT)
|
||||
{
|
||||
off_t d = real_s_totsize - real_s_sizeleft;
|
||||
xheader_store ("GNU.volume.filename", &dummy, real_s_name);
|
||||
xheader_store ("GNU.volume.size", &dummy, &real_s_sizeleft);
|
||||
off_t d = map->sizetotal - map->sizeleft;
|
||||
xheader_store ("GNU.volume.filename", &dummy, map->file_name);
|
||||
xheader_store ("GNU.volume.size", &dummy, &map->sizeleft);
|
||||
xheader_store ("GNU.volume.offset", &dummy, &d);
|
||||
}
|
||||
else
|
||||
gnu_add_multi_volume_header ();
|
||||
}
|
||||
|
||||
/* Synchronize multi-volume globals */
|
||||
static void
|
||||
multi_volume_sync (void)
|
||||
{
|
||||
if (multi_volume_option)
|
||||
{
|
||||
if (save_name)
|
||||
{
|
||||
assign_string (&real_s_name,
|
||||
safer_name_suffix (save_name, false,
|
||||
absolute_names_option));
|
||||
real_s_totsize = save_totsize;
|
||||
real_s_sizeleft = save_sizeleft;
|
||||
}
|
||||
else
|
||||
{
|
||||
assign_string (&real_s_name, 0);
|
||||
real_s_totsize = 0;
|
||||
real_s_sizeleft = 0;
|
||||
}
|
||||
}
|
||||
gnu_add_multi_volume_header (map);
|
||||
}
|
||||
|
||||
|
||||
@@ -1673,8 +1719,6 @@ _gnu_flush_read (void)
|
||||
archive_write_error (status);
|
||||
}
|
||||
|
||||
multi_volume_sync ();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
status = rmtread (archive, record_start->buffer, record_size);
|
||||
@@ -1726,8 +1770,8 @@ _gnu_flush_write (size_t buffer_level)
|
||||
char *copy_ptr;
|
||||
size_t copy_size;
|
||||
size_t bufsize;
|
||||
tarlong wrt;
|
||||
|
||||
struct bufmap *map;
|
||||
|
||||
status = _flush_write ();
|
||||
if (status != record_size && !multi_volume_option)
|
||||
archive_write_error (status);
|
||||
@@ -1740,10 +1784,11 @@ _gnu_flush_write (size_t buffer_level)
|
||||
|
||||
if (status == record_size)
|
||||
{
|
||||
multi_volume_sync ();
|
||||
return;
|
||||
}
|
||||
|
||||
map = bufmap_locate (status);
|
||||
|
||||
if (status % BLOCKSIZE)
|
||||
{
|
||||
ERROR ((0, 0, _("write did not end on a block boundary")));
|
||||
@@ -1755,7 +1800,6 @@ _gnu_flush_write (size_t buffer_level)
|
||||
if (status < 0 && errno != ENOSPC && errno != EIO && errno != ENXIO)
|
||||
archive_write_error (status);
|
||||
|
||||
real_s_sizeleft -= status;
|
||||
if (!new_volume (ACCESS_WRITE))
|
||||
return;
|
||||
|
||||
@@ -1767,25 +1811,28 @@ _gnu_flush_write (size_t buffer_level)
|
||||
|
||||
copy_ptr = record_start->buffer + status;
|
||||
copy_size = buffer_level - status;
|
||||
|
||||
|
||||
/* Switch to the next buffer */
|
||||
record_index = !record_index;
|
||||
init_buffer ();
|
||||
|
||||
inhibit_map = 1;
|
||||
|
||||
if (volume_label_option)
|
||||
add_volume_label ();
|
||||
|
||||
if (real_s_name)
|
||||
add_multi_volume_header ();
|
||||
if (map)
|
||||
add_multi_volume_header (map);
|
||||
|
||||
write_extended (true, &dummy, find_next_block ());
|
||||
tar_stat_destroy (&dummy);
|
||||
|
||||
if (real_s_name)
|
||||
add_chunk_header ();
|
||||
wrt = bytes_written;
|
||||
if (map)
|
||||
add_chunk_header (map);
|
||||
header = find_next_block ();
|
||||
bufmap_reset (map, header - record_start);
|
||||
bufsize = available_space_after (header);
|
||||
inhibit_map = 0;
|
||||
while (bufsize < copy_size)
|
||||
{
|
||||
memcpy (header->buffer, copy_ptr, bufsize);
|
||||
@@ -1798,16 +1845,6 @@ _gnu_flush_write (size_t buffer_level)
|
||||
memcpy (header->buffer, copy_ptr, copy_size);
|
||||
memset (header->buffer + copy_size, 0, bufsize - copy_size);
|
||||
set_next_block_after (header + (copy_size - 1) / BLOCKSIZE);
|
||||
if (multi_volume_option && wrt < bytes_written)
|
||||
{
|
||||
/* The value of bytes_written has changed while moving data;
|
||||
that means that flush_archive was executed at least once in
|
||||
between, and, as a consequence, copy_size bytes were not written
|
||||
to disk. We need to update sizeleft variables to compensate for
|
||||
that. */
|
||||
save_sizeleft += copy_size;
|
||||
multi_volume_sync ();
|
||||
}
|
||||
find_next_block ();
|
||||
}
|
||||
|
||||
|
||||
@@ -427,9 +427,10 @@ void archive_read_error (void);
|
||||
off_t seek_archive (off_t size);
|
||||
void set_start_time (void);
|
||||
|
||||
void mv_begin (struct tar_stat_info *st);
|
||||
void mv_begin_write (const char *file_name, off_t totsize, off_t sizeleft);
|
||||
|
||||
void mv_begin_read (struct tar_stat_info *st);
|
||||
void mv_end (void);
|
||||
void mv_total_size (off_t size);
|
||||
void mv_size_left (off_t size);
|
||||
|
||||
void buffer_write_global_xheader (void);
|
||||
|
||||
@@ -122,7 +122,7 @@ read_and_process (struct tar_stat_info *st, int (*processor) (size_t, char *))
|
||||
size_t data_size;
|
||||
off_t size = st->stat.st_size;
|
||||
|
||||
mv_begin (st);
|
||||
mv_begin_read (st);
|
||||
while (size)
|
||||
{
|
||||
data_block = find_next_block ();
|
||||
|
||||
11
src/create.c
11
src/create.c
@@ -1012,7 +1012,6 @@ pad_archive (off_t size_left)
|
||||
union block *blk;
|
||||
while (size_left > 0)
|
||||
{
|
||||
mv_size_left (size_left);
|
||||
blk = find_next_block ();
|
||||
memset (blk->buffer, 0, BLOCKSIZE);
|
||||
set_next_block_after (blk);
|
||||
@@ -1038,13 +1037,11 @@ dump_regular_file (int fd, struct tar_stat_info *st)
|
||||
|
||||
finish_header (st, blk, block_ordinal);
|
||||
|
||||
mv_begin (st);
|
||||
mv_begin_write (st->file_name, st->stat.st_size, st->stat.st_size);
|
||||
while (size_left > 0)
|
||||
{
|
||||
size_t bufsize, count;
|
||||
|
||||
mv_size_left (size_left);
|
||||
|
||||
blk = find_next_block ();
|
||||
|
||||
bufsize = available_space_after (blk);
|
||||
@@ -1138,11 +1135,9 @@ dump_dir0 (char *directory,
|
||||
p_buffer = buffer;
|
||||
size_left = totsize;
|
||||
|
||||
mv_begin (st);
|
||||
mv_total_size (totsize);
|
||||
mv_begin_write (st->file_name, totsize, totsize);
|
||||
while (size_left > 0)
|
||||
{
|
||||
mv_size_left (size_left);
|
||||
blk = find_next_block ();
|
||||
bufsize = available_space_after (blk);
|
||||
if (size_left < bufsize)
|
||||
@@ -1157,7 +1152,6 @@ dump_dir0 (char *directory,
|
||||
p_buffer += bufsize;
|
||||
set_next_block_after (blk + (bufsize - 1) / BLOCKSIZE);
|
||||
}
|
||||
mv_end ();
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1619,7 +1613,6 @@ dump_file0 (struct tar_stat_info *st, const char *p,
|
||||
{
|
||||
case dump_status_ok:
|
||||
case dump_status_short:
|
||||
mv_end ();
|
||||
file_count_links (st);
|
||||
break;
|
||||
|
||||
|
||||
@@ -812,7 +812,7 @@ extract_file (char *file_name, int typeflag)
|
||||
}
|
||||
}
|
||||
|
||||
mv_begin (¤t_stat_info);
|
||||
mv_begin_read (¤t_stat_info);
|
||||
if (current_stat_info.is_sparse)
|
||||
sparse_extract_file (fd, ¤t_stat_info, &size);
|
||||
else
|
||||
|
||||
@@ -1452,7 +1452,7 @@ get_gnu_dumpdir (struct tar_stat_info *stat_info)
|
||||
to = archive_dir;
|
||||
|
||||
set_next_block_after (current_header);
|
||||
mv_begin (stat_info);
|
||||
mv_begin_read (stat_info);
|
||||
|
||||
for (; size > 0; size -= copied)
|
||||
{
|
||||
|
||||
@@ -1353,7 +1353,7 @@ skip_file (off_t size)
|
||||
{
|
||||
union block *x;
|
||||
|
||||
/* FIXME: Make sure mv_begin is always called before it */
|
||||
/* FIXME: Make sure mv_begin_read is always called before it */
|
||||
|
||||
if (seekable_archive)
|
||||
{
|
||||
@@ -1388,7 +1388,7 @@ skip_member (void)
|
||||
char save_typeflag = current_header->header.typeflag;
|
||||
set_next_block_after (current_header);
|
||||
|
||||
mv_begin (¤t_stat_info);
|
||||
mv_begin_read (¤t_stat_info);
|
||||
|
||||
if (current_stat_info.is_sparse)
|
||||
sparse_skip_file (¤t_stat_info);
|
||||
|
||||
@@ -324,7 +324,6 @@ sparse_dump_region (struct tar_sparse_file *file, size_t i)
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -398,10 +397,11 @@ sparse_dump_file (int fd, struct tar_stat_info *st)
|
||||
{
|
||||
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 ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -566,7 +566,7 @@ sparse_diff_file (int fd, struct tar_stat_info *st)
|
||||
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,
|
||||
|
||||
Reference in New Issue
Block a user