ct_compress,
ct_gzip,
ct_bzip2,
+ ct_lzip,
ct_lzma,
ct_lzop,
ct_xz
{ ct_compress, 2, "\037\235", COMPRESS_PROGRAM, "-Z" },
{ ct_gzip, 2, "\037\213", GZIP_PROGRAM, "-z" },
{ ct_bzip2, 3, "BZh", BZIP2_PROGRAM, "-j" },
+ { ct_lzip, 4, "LZIP", LZIP_PROGRAM, "--lzip" },
{ ct_lzma, 6, "\xFFLZMA", LZMA_PROGRAM, "--lzma" },
{ ct_lzop, 4, "\211LZO", LZOP_PROGRAM, "--lzop" },
{ ct_xz, 6, "\0xFD7zXZ", XZ_PROGRAM, "-J" },
off_t start = current_block_ordinal ();
off_t offset;
off_t nrec, nblk;
- off_t skipped = (blocking_factor - (current_block - record_start));
+ off_t skipped = (blocking_factor - (current_block - record_start))
+ * BLOCKSIZE;
- size -= skipped * BLOCKSIZE;
-
- if (size < record_size)
+ if (size <= skipped)
return 0;
- /* FIXME: flush? */
-
+
/* Compute number of records to skip */
- nrec = size / record_size;
+ nrec = (size - skipped) / record_size;
+ if (nrec == 0)
+ return 0;
offset = rmtlseek (archive, nrec * record_size, SEEK_CUR);
if (offset < 0)
return offset;
enum read_header rc;
tar_stat_init (info);
- rc = read_header (¤t_header, info, false);
+ rc = read_header (¤t_header, info, read_header_auto);
if (rc == HEADER_SUCCESS)
{
set_next_block_after (current_header);
{
case XGLTYPE:
{
- if (!read_header0 (&dummy))
- return false;
+ tar_stat_init (&dummy);
+ if (read_header (&header, &dummy, read_header_x_global)
+ != HEADER_SUCCESS_EXTENDED)
+ {
+ ERROR ((0, 0, _("This does not look like a tar archive")));
+ return false;
+ }
+
xheader_decode (&dummy); /* decodes values from the global header */
tar_stat_destroy (&dummy);
- if (!real_s_name)
- {
- /* We have read the extended header of the first member in
- this volume. Put it back, so next read_header works as
- expected. */
- current_block = record_start;
- }
+
+ /* The initial global header must be immediately followed by
+ an extended PAX header for the first member in this volume.
+ However, in some cases tar may split volumes in the middle
+ of a PAX header. This is incorrect, and should be fixed
+ in the future versions. In the meantime we must be
+ prepared to correctly list and extract such archives.
+
+ If this happens, the following call to read_header returns
+ HEADER_FAILURE, which is ignored.
+
+ See also tests/multiv07.at */
+
+ switch (read_header (&header, &dummy, read_header_auto))
+ {
+ case HEADER_SUCCESS:
+ set_next_block_after (header);
+ break;
+
+ case HEADER_FAILURE:
+ break;
+
+ default:
+ ERROR ((0, 0, _("This does not look like a tar archive")));
+ return false;
+ }
break;
}
check_label_pattern (const char *label)
{
char *string;
- bool result;
+ bool result = false;
if (fnmatch (volume_label_option, label, 0) == 0)
return true;
switch (wanted_access)
{
case ACCESS_READ:
+ case ACCESS_UPDATE:
if (volume_label_option)
match_volume_label ();
break;
if (volume_label_option)
write_volume_label ();
break;
-
- default:
- break;
}
set_volume_start_time ();
}