#define compress_option(t) magic[t].option
#define compress_program(t) magic[t].program
-/* Check if the file FD is a compressed archive. FD is guaranteed to
- represent a local file */
+/* Check if the file ARCHIVE is a compressed archive. */
enum compress_type
-check_compressed_archive (int fd)
+check_compressed_archive ()
{
struct zip_magic *p;
- size_t status;
- union block buf;
-
- status = read (fd, &buf, sizeof buf);
- if (status != sizeof buf)
- {
- archive_read_error ();
- FATAL_ERROR ((0, 0, _("Quitting now.")));
- }
-
- lseek (fd, 0, SEEK_SET); /* This will fail if fd==0, but that does not
- matter, since we do not handle compressed
- stdin anyway */
-
- if (tar_checksum (&buf) == HEADER_SUCCESS)
+ bool sfr, srp;
+
+ /* Prepare global data needed for find_next_block: */
+ record_end = record_start; /* set up for 1st record = # 0 */
+ sfr = read_full_records;
+ read_full_records = true; /* Suppress fatal error on reading a partial
+ record */
+ srp = reading_from_pipe;
+ reading_from_pipe = true; /* Suppress warning message on reading a partial
+ record */
+ find_next_block ();
+
+ /* Restore global values */
+ read_full_records = sfr;
+ reading_from_pipe = srp;
+
+ if (tar_checksum (record_start, true) == HEADER_SUCCESS)
/* Probably a valid header */
return ct_none;
for (p = magic + 1; p < magic + NMAGIC; p++)
- if (memcmp (buf.buffer, p->magic, p->length) == 0)
+ if (memcmp (record_start->buffer, p->magic, p->length) == 0)
return p->type;
return ct_none;
int
open_compressed_archive ()
{
- enum compress_type type;
- int fd = rmtopen (archive_name_array[0], O_RDONLY | O_BINARY,
- MODE_RW, rsh_command_option);
- if (fd == -1 || _isrmt (fd))
- return fd;
-
- type = check_compressed_archive (fd);
-
- if (type == ct_none)
+ archive = rmtopen (archive_name_array[0], O_RDONLY | O_BINARY,
+ MODE_RW, rsh_command_option);
+ if (archive == -1)
+ return archive;
+
+ if (!multi_volume_option)
{
- if (rmtlseek (fd, (off_t) 0, SEEK_CUR) != 0)
- {
- /* Archive may be not seekable. Reopen it. */
- rmtclose (fd);
- fd = rmtopen (archive_name_array[0], O_RDONLY | O_BINARY,
- MODE_RW, rsh_command_option);
- }
- return fd;
- }
+ enum compress_type type = check_compressed_archive ();
+
+ if (type == ct_none)
+ return archive;
- /* FD is not needed any more */
- rmtclose (fd);
+ /* FD is not needed any more */
+ rmtclose (archive);
- /* Open compressed archive */
- use_compress_program_option = compress_program (type);
- child_pid = sys_child_open_for_uncompress ();
- read_full_records = reading_from_pipe = true;
+ hit_eof = false; /* It might have been set by find_next_block in
+ check_compressed_archive */
+ /* Open compressed archive */
+ use_compress_program_option = compress_program (type);
+ child_pid = sys_child_open_for_uncompress ();
+ read_full_records = reading_from_pipe = true;
+ }
+
+ records_read = 0;
+ record_end = record_start; /* set up for 1st record = # 0 */
+
return archive;
}
\f
read_full_records = read_full_records_option;
reading_from_pipe = false;
+ records_read = 0;
+
if (use_compress_program_option)
{
switch (wanted_access)
case ACCESS_READ:
child_pid = sys_child_open_for_uncompress ();
read_full_records = reading_from_pipe = true;
+ record_end = record_start; /* set up for 1st record = # 0 */
break;
case ACCESS_WRITE:
{
case ACCESS_UPDATE:
records_written = 0;
- case ACCESS_READ:
- records_read = 0;
record_end = record_start; /* set up for 1st record = # 0 */
+
+ case ACCESS_READ:
find_next_block (); /* read it in, check for EOF */
if (volume_label_option)
{
char buf[UINTMAX_STRSIZE_BOUND];
- WARN((0, 0, _("Read %s bytes from %s"),
+ WARN((0, 0,
+ ngettext ("Read %s byte from %s",
+ "Read %s bytes from %s",
+ record_size - left),
STRINGIFY_BIGINT (record_size - left, buf),
*archive_name_cursor));
}
if (volno_file_option)
closeout_volume_number ();
if (system (info_script_option) != 0)
- FATAL_ERROR ((0, 0, _("`%s' command failed"), info_script_option));
+ FATAL_ERROR ((0, 0, _("%s command failed"),
+ quote (info_script_option)));
}
else
while (1)