summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
f2b8b4a)
All callers changed.
(deal_with_sparse): Don't keep reading after read errors.
(finish_sparse_file): Just abort if there is an internal error.
Use error message functions to report errors consistently.
(dump_file): Fix typo: stat_warn and stat_error were interchanged.
Quote file names with colons if possible.
Don't restore access times on directories during incremental dumps
until after dealing with the directory.
If ignoring failed reads, count closedir errors as warnings, not errors.
Fix buffer overrun problem when dumping sparse files.
If ignoring failed reads, count read errors as warnings, not errors.
Use error message functions to report errors consistently.
If ignoring failed reads, count unknown files as warnings, not errors.
-static void
-find_new_file_size (off_t *filesize, int highest_index)
+static off_t
+find_new_file_size (int sparses)
- int counter;
-
- *filesize = 0;
- for (counter = 0;
- sparsearray[counter].numbytes && counter <= highest_index;
- counter++)
- *filesize += sparsearray[counter].numbytes;
+ int i;
+ off_t s = 0;
+ for (i = 0; i < sparses; i++)
+ s += sparsearray[i].numbytes;
+ return s;
}
/*-----------------------------------------------------------------------.
}
/*-----------------------------------------------------------------------.
size_t numbytes = 0;
off_t offset = 0;
int file;
size_t numbytes = 0;
off_t offset = 0;
int file;
ssize_t count;
char buffer[BLOCKSIZE];
ssize_t count;
char buffer[BLOCKSIZE];
init_sparsearray ();
clear_buffer (buffer);
init_sparsearray ();
clear_buffer (buffer);
- while (count = safe_read (file, buffer, sizeof buffer), count != 0)
+ while (0 < (count = safe_read (file, buffer, sizeof buffer)))
{
/* Realloc the scratch area as necessary. FIXME: should reallocate
only at beginning of a new instance of non-zero data. */
{
/* Realloc the scratch area as necessary. FIXME: should reallocate
only at beginning of a new instance of non-zero data. */
- if (sparse_index > sp_array_size - 1)
+ if (sp_array_size <= sparses)
{
sparsearray =
xrealloc (sparsearray,
{
sparsearray =
xrealloc (sparsearray,
- sparsearray[sparse_index++].numbytes = numbytes;
+ sparsearray[sparses++].numbytes = numbytes;
numbytes = 0;
}
}
else
{
if (!numbytes)
numbytes = 0;
}
}
else
{
if (!numbytes)
- sparsearray[sparse_index].offset = offset;
+ sparsearray[sparses].offset = offset;
if (!zero_block_p (buffer))
{
if (!numbytes)
if (!zero_block_p (buffer))
{
if (!numbytes)
- sparsearray[sparse_index].offset = offset;
+ sparsearray[sparses].offset = offset;
numbytes += count;
}
else
numbytes += count;
}
else
- sparsearray[sparse_index++].numbytes = numbytes;
+ sparsearray[sparses++].numbytes = numbytes;
- sparsearray[sparse_index].offset = offset - 1;
- sparsearray[sparse_index++].numbytes = 1;
+ sparsearray[sparses].offset = offset - 1;
+ sparsearray[sparses++].numbytes = 1;
- return sparse_index - 1;
+ return count < 0 ? 0 : sparses;
{
union block *start;
size_t bufsize;
{
union block *start;
size_t bufsize;
ssize_t count;
while (*sizeleft > 0)
{
start = find_next_block ();
memset (start->buffer, 0, BLOCKSIZE);
ssize_t count;
while (*sizeleft > 0)
{
start = find_next_block ();
memset (start->buffer, 0, BLOCKSIZE);
- bufsize = sparsearray[sparse_index].numbytes;
- if (!bufsize)
- {
- /* We blew it, maybe. */
- char buf1[UINTMAX_STRSIZE_BOUND];
- char buf2[UINTMAX_STRSIZE_BOUND];
-
- ERROR ((0, 0, _("Wrote %s of %s bytes to file %s"),
- STRINGIFY_BIGINT (fullsize - *sizeleft, buf1),
- STRINGIFY_BIGINT (fullsize, buf2), quote (name)));
- break;
- }
+ bufsize = sparsearray[sparses].numbytes;
+ if (! bufsize)
+ abort ();
- if (lseek (file, sparsearray[sparse_index++].offset, SEEK_SET) < 0)
+ if (lseek (file, sparsearray[sparses++].offset, SEEK_SET) < 0)
- char buf[UINTMAX_STRSIZE_BOUND];
- int e = errno;
- ERROR ((0, e, _("lseek error at byte %s in file %s"),
- STRINGIFY_BIGINT (sparsearray[sparse_index - 1].offset,
- buf),
- quote (name)));
+ (ignore_failed_read_option ? seek_warn_details : seek_error_details)
+ (name, sparsearray[sparses - 1].offset);
while (bufsize > BLOCKSIZE)
{
while (bufsize > BLOCKSIZE)
{
-#if 0
- if (amount_read)
- {
- count = safe_read (file, start->buffer + amount_read,
- BLOCKSIZE - amount_read);
- bufsize -= BLOCKSIZE - amount_read;
- amount_read = 0;
- set_next_block_after (start);
- start = find_next_block ();
- memset (start->buffer, 0, BLOCKSIZE);
- }
-#endif
- /* Store the data. */
-
count = safe_read (file, start->buffer, BLOCKSIZE);
if (count < 0)
{
count = safe_read (file, start->buffer, BLOCKSIZE);
if (count < 0)
{
- char buf[UINTMAX_STRSIZE_BOUND];
- int e = errno;
- ERROR ((0, e,
- _("Read error at byte %s, reading %lu bytes, in file %s"),
- STRINGIFY_BIGINT (fullsize - *sizeleft, buf),
- (unsigned long) bufsize, quote (name)));
+ (ignore_failed_read_option
+ ? read_warn_details
+ : read_error_details)
+ (name, fullsize - *sizeleft, bufsize);
return 1;
}
bufsize -= count;
return 1;
}
bufsize -= count;
- char buf[UINTMAX_STRSIZE_BOUND];
- int e = errno;
- ERROR ((0, e,
- _("Read error at byte %s, reading %lu bytes, in file %s"),
- STRINGIFY_BIGINT (fullsize - *sizeleft, buf),
- (unsigned long) bufsize, quote (name)));
+ (ignore_failed_read_option
+ ? read_warn_details
+ : read_error_details)
+ (name, fullsize - *sizeleft, bufsize);
-#if 0
- if (amount_read >= BLOCKSIZE)
- {
- amount_read = 0;
- set_next_block_after (start + (count - 1) / BLOCKSIZE);
- if (count != bufsize)
- {
- ERROR ((0, 0,
- _("File %s shrunk, padding with zeros"), quote (name)));
- return 1;
- }
- start = find_next_block ();
- }
- else
- amount_read += bufsize;
-#endif
*sizeleft -= count;
set_next_block_after (start);
*sizeleft -= count;
set_next_block_after (start);
}
free (sparsearray);
#if 0
}
free (sparsearray);
#if 0
time_t original_ctime;
struct utimbuf restore_times;
time_t original_ctime;
struct utimbuf restore_times;
- /* FIXME: `header' and `upperbound' might be used uninitialized in this
+ /* FIXME: `header' and `sparses' might be used uninitialized in this
function. Reported by Bruno Haible. */
if (interactive_option && !confirm ("add", p))
function. Reported by Bruno Haible. */
if (interactive_option && !confirm ("add", p))
if (deref_stat (dereference_option, p, ¤t_stat) != 0)
{
if (ignore_failed_read_option)
if (deref_stat (dereference_option, p, ¤t_stat) != 0)
{
if (ignore_failed_read_option)
&& (!after_date_option || current_stat.st_ctime < newer_ctime_option))
{
if (0 < top_level)
&& (!after_date_option || current_stat.st_ctime < newer_ctime_option))
{
if (0 < top_level)
- WARN ((0, 0, _("%s is unchanged; not dumped"), quote (p)));
+ WARN ((0, 0, _("%s: file is unchanged; not dumped"),
+ quotearg_colon (p)));
/* FIXME: recheck this return. */
return;
}
/* FIXME: recheck this return. */
return;
}
if (ar_dev && current_stat.st_dev == ar_dev && current_stat.st_ino == ar_ino)
{
if (ar_dev && current_stat.st_dev == ar_dev && current_stat.st_ino == ar_ino)
{
- WARN ((0, 0, _("%s is the archive; not dumped"), quote (p)));
+ WARN ((0, 0, _("%s: file is the archive; not dumped"),
+ quotearg_colon (p)));
}
if (multi_volume_option)
assign_string (&save_name, 0);
}
if (multi_volume_option)
assign_string (&save_name, 0);
- if (atime_preserve_option)
- utime (p, &restore_times);
- return;
}
/* See if we are about to recurse into a directory, and avoid doing
so if the user wants that we do not descend into directories. */
if (no_recurse_option)
}
/* See if we are about to recurse into a directory, and avoid doing
so if the user wants that we do not descend into directories. */
if (no_recurse_option)
/* See if we are crossing from one file system to another, and
avoid doing so if the user only wants to dump one file system. */
/* See if we are crossing from one file system to another, and
avoid doing so if the user only wants to dump one file system. */
&& parent_device != current_stat.st_dev)
{
if (verbose_option)
&& parent_device != current_stat.st_dev)
{
if (verbose_option)
- WARN ((0, 0, _("%s is on a different filesystem; not dumped"),
- quote (p)));
- return;
+ WARN ((0, 0,
+ _("%s: file is on a different filesystem; not dumped"),
+ quotearg_colon (p)));
+ goto finish_dir;
}
/* Now output all the files in the directory. */
}
/* Now output all the files in the directory. */
if (closedir (directory) != 0)
if (closedir (directory) != 0)
+ {
+ if (ignore_failed_read_option)
+ closedir_warn (p);
+ else
+ closedir_error (p);
+ }
+
free (namebuf);
if (atime_preserve_option)
utime (p, &restore_times);
free (namebuf);
if (atime_preserve_option)
utime (p, &restore_times);
union block *start;
int header_moved;
char isextended = 0;
union block *start;
int header_moved;
char isextended = 0;
< (current_stat.st_size / ST_NBLOCKSIZE
+ (current_stat.st_size % ST_NBLOCKSIZE != 0)))
{
< (current_stat.st_size / ST_NBLOCKSIZE
+ (current_stat.st_size % ST_NBLOCKSIZE != 0)))
{
- off_t filesize = current_stat.st_size;
int counter;
header = start_header (p, ¤t_stat);
int counter;
header = start_header (p, ¤t_stat);
header_moved = 1;
/* Call the routine that figures out the layout of the
header_moved = 1;
/* Call the routine that figures out the layout of the
- sparse file in question. UPPERBOUND is the index of the
- last element of the "sparsearray," i.e., the number of
- elements it needed to describe the file. */
+ sparse file in question. SPARSES is the index of the
+ first unused element of the "sparsearray," i.e.,
+ the number of elements it needed to describe the file. */
- upperbound = deal_with_sparse (p, header);
+ sparses = deal_with_sparse (p, header);
/* See if we'll need an extended header later. */
/* See if we'll need an extended header later. */
- if (upperbound > SPARSES_IN_OLDGNU_HEADER - 1)
+ if (SPARSES_IN_OLDGNU_HEADER < sparses)
header->oldgnu_header.isextended = 1;
/* We store the "real" file size so we can show that in
header->oldgnu_header.isextended = 1;
/* We store the "real" file size so we can show that in
of the file minus the blocks of holes that we're
skipping over. */
of the file minus the blocks of holes that we're
skipping over. */
- find_new_file_size (&filesize, upperbound);
- current_stat.st_size = filesize;
- OFF_TO_CHARS (filesize, header->header.size);
+ current_stat.st_size = find_new_file_size (sparses);
+ OFF_TO_CHARS (current_stat.st_size, header->header.size);
- for (counter = 0; counter < SPARSES_IN_OLDGNU_HEADER; counter++)
+ for (counter = 0;
+ counter < sparses && counter < SPARSES_IN_OLDGNU_HEADER;
+ counter++)
- if (!sparsearray[counter].numbytes)
- break;
-
OFF_TO_CHARS (sparsearray[counter].offset,
header->oldgnu_header.sp[counter].offset);
SIZE_TO_CHARS (sparsearray[counter].numbytes,
header->oldgnu_header.sp[counter].numbytes);
}
OFF_TO_CHARS (sparsearray[counter].offset,
header->oldgnu_header.sp[counter].offset);
SIZE_TO_CHARS (sparsearray[counter].numbytes,
header->oldgnu_header.sp[counter].numbytes);
}
- upperbound = SPARSES_IN_OLDGNU_HEADER - 1;
+ sparses = SPARSES_IN_OLDGNU_HEADER;
sizeleft = current_stat.st_size;
sizeleft = current_stat.st_size;
if (f < 0)
{
if (! top_level && errno == ENOENT)
if (f < 0)
{
if (! top_level && errno == ENOENT)
- WARN ((0, 0, _("File %s removed before we read it"),
- quote (p)));
- else if (ignore_failed_read_option)
- open_warn (p);
+ WARN ((0, 0, _("%s: File removed before we read it"),
+ quotearg_colon (p)));
+ (ignore_failed_read_option ? open_warn : open_error) (p);
memset (exhdr->buffer, 0, BLOCKSIZE);
for (counter = 0; counter < SPARSES_IN_SPARSE_HEADER; counter++)
{
memset (exhdr->buffer, 0, BLOCKSIZE);
for (counter = 0; counter < SPARSES_IN_SPARSE_HEADER; counter++)
{
- if (counter + index_offset > upperbound)
+ if (sparses <= counter + index_offset)
break;
SIZE_TO_CHARS (sparsearray[counter + index_offset].numbytes,
break;
SIZE_TO_CHARS (sparsearray[counter + index_offset].numbytes,
exhdr->sparse_header.sp[counter].offset);
}
set_next_block_after (exhdr);
exhdr->sparse_header.sp[counter].offset);
}
set_next_block_after (exhdr);
- if (index_offset + counter <= upperbound)
+ if (counter + index_offset < sparses)
{
index_offset += counter;
exhdr->sparse_header.isextended = 1;
{
index_offset += counter;
exhdr->sparse_header.isextended = 1;
count = safe_read (f, start->buffer, bufsize);
if (count < 0)
{
count = safe_read (f, start->buffer, bufsize);
if (count < 0)
{
- char buf[UINTMAX_STRSIZE_BOUND];
- int e = errno;
- ERROR ((0, e,
- _("Read error at byte %s, reading %lu bytes, in file %s"),
- STRINGIFY_BIGINT (current_stat.st_size - sizeleft,
- buf),
- (unsigned long) bufsize, quote (p)));
+ (ignore_failed_read_option
+ ? read_warn_details
+ : read_error_details)
+ (p, current_stat.st_size - sizeleft, bufsize);
goto padit;
}
sizeleft -= count;
goto padit;
}
sizeleft -= count;
else
{
char buf[UINTMAX_STRSIZE_BOUND];
else
{
char buf[UINTMAX_STRSIZE_BOUND];
- ERROR ((0, 0,
- _("File %s shrunk by %s bytes, padding with zeros"),
- quote (p), STRINGIFY_BIGINT (sizeleft, buf)));
+ WARN ((0, 0,
+ _("%s: File shrank by %s bytes; padding with zeros"),
+ quotearg_colon (p),
+ STRINGIFY_BIGINT (sizeleft, buf)));
+ if (! ignore_failed_read_option)
+ exit_status = TAREXIT_FAILURE;
goto padit; /* short read */
}
}
goto padit; /* short read */
}
}
{
struct stat final_stat;
if (fstat (f, &final_stat) != 0)
{
struct stat final_stat;
if (fstat (f, &final_stat) != 0)
+ {
+ if (ignore_failed_read_option)
+ stat_warn (p);
+ else
+ stat_error (p);
+ }
else if (final_stat.st_ctime != original_ctime)
else if (final_stat.st_ctime != original_ctime)
- ERROR ((0, 0, _("File %s changed as we read it"), quote (p)));
+ {
+ char const *qp = quotearg_colon (p);
+ WARN ((0, 0, _("%s: file changed as we read it"), qp));
+ if (! ignore_failed_read_option)
+ exit_status = TAREXIT_FAILURE;
+ }
+ {
+ if (ignore_failed_read_option)
+ close_warn (p);
+ else
+ close_error (p);
+ }
if (atime_preserve_option)
utime (p, &restore_times);
}
if (atime_preserve_option)
utime (p, &restore_times);
}
- ERROR ((0, 0, _("%s: Unknown file type; file ignored"),
- quotearg_colon (p)));
+ WARN ((0, 0, _("%s: Unknown file type; file ignored"),
+ quotearg_colon (p)));
+ if (! ignore_failed_read_option)
+ exit_status = TAREXIT_FAILURE;