static bool hit_eof;
/* Checkpointing counter */
-static int checkpoint;
+static unsigned checkpoint;
static bool read_full_records = false;
archive = STDIN_FILENO;
- type = check_compressed_archive (archive);
+ type = check_compressed_archive ();
if (type != ct_none)
FATAL_ERROR ((0, 0,
_("Archive is compressed. Use %s option"),
}
}
+static void
+do_checkpoint (bool write)
+{
+ if (checkpoint_option && !(++checkpoint % checkpoint_option))
+ {
+ switch (checkpoint_style)
+ {
+ case checkpoint_dot:
+ fputc ('.', stdlis);
+ fflush (stdlis);
+ break;
+
+ case checkpoint_text:
+ if (write)
+ /* TRANSLATORS: This is a ``checkpoint of write operation'',
+ *not* ``Writing a checkpoint''.
+ E.g. in Spanish ``Punto de comprobaci@'on de escritura'',
+ *not* ``Escribiendo un punto de comprobaci@'on'' */
+ WARN ((0, 0, _("Write checkpoint %u"), checkpoint));
+ else
+ /* TRANSLATORS: This is a ``checkpoint of read operation'',
+ *not* ``Reading a checkpoint''.
+ E.g. in Spanish ``Punto de comprobaci@'on de lectura'',
+ *not* ``Leyendo un punto de comprobaci@'on'' */
+ WARN ((0, 0, _("Read checkpoint %u"), checkpoint));
+ break;
+ }
+ }
+}
+
/* Perform a write to flush the buffer. */
ssize_t
_flush_write (void)
{
ssize_t status;
- if (checkpoint_option && !(++checkpoint % 10))
- /* TRANSLATORS: This is a ``checkpoint of write operation'',
- *not* ``Writing a checkpoint''.
- E.g. in Spanish ``Punto de comprobaci@'on de escritura'',
- *not* ``Escribiendo un punto de comprobaci@'on'' */
- WARN ((0, 0, _("Write checkpoint %d"), checkpoint));
-
+ do_checkpoint (true);
if (tape_length_option && tape_length_option <= bytes_written)
{
errno = ENOSPC;
records_read++;
}
-/* Perform a read to flush the buffer. */
-size_t
-_flush_read (void)
-{
- size_t status; /* result from system call */
-
- if (checkpoint_option && !(++checkpoint % 10))
- /* TRANSLATORS: This is a ``checkpoint of read operation'',
- *not* ``Reading a checkpoint''.
- E.g. in Spanish ``Punto de comprobaci@'on de lectura'',
- *not* ``Leyendo un punto de comprobaci@'on'' */
- WARN ((0, 0, _("Read checkpoint %d"), checkpoint));
-
- /* Clear the count of errors. This only applies to a single call to
- flush_read. */
-
- read_error_count = 0; /* clear error count */
-
- if (write_archive_to_stdout && record_start_block != 0)
- {
- archive = STDOUT_FILENO;
- status = sys_write_archive_buffer ();
- archive = STDIN_FILENO;
- if (status != record_size)
- archive_write_error (status);
- }
-
- status = rmtread (archive, record_start->buffer, record_size);
- if (status == record_size)
- records_read++;
- return status;
-}
-
/* Flush the current buffer to/from the archive. */
void
flush_archive (void)
{
char *input_buffer = NULL;
size_t size = 0;
-
- while (1)
+ bool stop = false;
+
+ while (!stop)
{
fputc ('\007', stderr);
fprintf (stderr,
case '?':
{
fprintf (stderr, _("\
- n [name] Give a new file name for the next (and subsequent) volume(s)\n\
+ n name Give a new file name for the next (and subsequent) volume(s)\n\
q Abort tar\n\
y or newline Continue operation\n"));
if (!restrict_option)
;
*cursor = '\0';
- /* FIXME: the following allocation is never reclaimed. */
- *archive_name_cursor = xstrdup (name);
+ if (name[0])
+ {
+ /* FIXME: the following allocation is never reclaimed. */
+ *archive_name_cursor = xstrdup (name);
+ stop = true;
+ }
+ else
+ fprintf (stderr, "%s",
+ _("File name not specified. Try again.\n"));
}
break;
}
static bool
-read_header0 ()
+read_header0 (struct tar_stat_info *info)
{
- enum read_header rc = read_header (false);
+ enum read_header rc;
+ tar_stat_init (info);
+ rc = read_header_primitive (false, info);
if (rc == HEADER_SUCCESS)
{
set_next_block_after (current_header);
{
size_t status;
union block *header;
-
+ struct tar_stat_info dummy;
+
switch (subcommand_option)
{
case APPEND_SUBCOMMAND:
header = find_next_block ();
if (!header)
return false;
+
switch (header->header.typeflag)
{
case XGLTYPE:
{
- struct tar_stat_info dummy;
- if (!read_header0 ())
+ if (!read_header0 (&dummy))
return false;
- tar_stat_init (&dummy);
xheader_decode (&dummy); /* decodes values from the global header */
tar_stat_destroy (&dummy);
if (!real_s_name)
}
case GNUTYPE_VOLHDR:
- if (!read_header0 ())
+ if (!read_header0 (&dummy))
return false;
+ tar_stat_destroy (&dummy);
assign_string (&volume_label, current_header->header.name);
set_next_block_after (header);
header = find_next_block ();
/* FALL THROUGH */
case GNUTYPE_MULTIVOL:
- if (!read_header0 ())
+ if (!read_header0 (&dummy))
return false;
+ tar_stat_destroy (&dummy);
assign_string (&continued_file_name, current_header->header.name);
continued_file_size =
UINTMAX_FROM_HEADER (current_header->header.size);
if (!continued_file_name
|| strcmp (continued_file_name, real_s_name))
{
- WARN ((0, 0, _("%s is not continued on this volume"),
- quote (real_s_name)));
- return false;
+ if ((archive_format == GNU_FORMAT || archive_format == OLDGNU_FORMAT)
+ && strlen (real_s_name) >= NAME_FIELD_SIZE
+ && strncmp (continued_file_name, real_s_name,
+ NAME_FIELD_SIZE) == 0)
+ WARN ((0, 0,
+ _("%s is possibly continued on this volume: header contains truncated name"),
+ quote (real_s_name)));
+ else
+ {
+ WARN ((0, 0, _("%s is not continued on this volume"),
+ quote (real_s_name)));
+ return false;
+ }
}
s = continued_file_size + continued_file_offset;
{
size_t status; /* result from system call */
- if (checkpoint_option && !(++checkpoint % 10))
- /* TRANSLATORS: This is a ``checkpoint of read operation'',
- *not* ``Reading a checkpoint''.
- E.g. in Spanish ``Punto de comprobaci@'on de lectura'',
- *not* ``Leyendo un punto de comprobaci@'on'' */
- WARN ((0, 0, _("Read checkpoint %d"), checkpoint));
-
+ do_checkpoint (false);
+
/* Clear the count of errors. This only applies to a single call to
flush_read. */
{
size_t status; /* result from system call */
- if (checkpoint_option && !(++checkpoint % 10))
- /* TRANSLATORS: This is a ``checkpoint of read operation'',
- *not* ``Reading a checkpoint''.
- E.g. in Spanish ``Punto de comprobaci@'on de lectura'',
- *not* ``Leyendo un punto de comprobaci@'on'' */
- WARN ((0, 0, _("Read checkpoint %d"), checkpoint));
-
+ do_checkpoint (false);
+
/* Clear the count of errors. This only applies to a single call to
flush_read. */