Fix listing of volume labels (in particular in PAX archives).
* src/buffer.c (match_volume_label): Call set_volume_label. (check_label_pattern): Get label string as argument. (match_volume_label): Handle volume labels stored in global PAX headers. * src/common.c (print_header,read_header): Change signature. (read_header_primitive): Remove prototype. * src/list.c (recent_global_header): New static. (list_archive): Always print volume labels. (read_header_primitive): Remove. (read_header): Change the signature (all callers updated) Save the recent global header. (volume_label_printed): New static. (simple_print_header): New function (ex-print_header). (print_header): Change the signature (all callers updated). For POSIX formats, print first volume header (if set). * src/xheader.c (xheader_write_global): Write the data accumulated in xhdr->stk even if keyword_global_override_list is empty. (xheader_read): On unexpected EOF, report error instead of coredumping. (XHDR_PROTECTED, XHDR_GLOBAL): New defines. (struct xhdr_tab): Remove `protected' with `flags'. All uses updated. (decg): If XHDR_GLOBAL bit is set, call the keyword's decode method instead of adding it to `kwl'. * src/compare.c: Update calls to read_header. * src/create.c: Likewise. * src/delete.c: Likewise. * src/update.c: Likewise. * src/extract.c: Likewise. (extract_volhdr): Do not print "Reading <label>" statement, because it is inconsistent: it is not printed if the volume begins with a member continued from the previous volume. * tests/label01.at: New testcase. * tests/label02.at: New testcase. * tests/Makefile.am, tests/testsuite.at: Add new testcases.
This commit is contained in:
55
src/buffer.c
55
src/buffer.c
@@ -1,7 +1,8 @@
|
|||||||
/* Buffer management for tar.
|
/* Buffer management for tar.
|
||||||
|
|
||||||
Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001,
|
Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001,
|
||||||
2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
|
2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
|
||||||
|
Foundation, Inc.
|
||||||
|
|
||||||
Written by John Gilmore, on 1985-08-25.
|
Written by John Gilmore, on 1985-08-25.
|
||||||
|
|
||||||
@@ -1167,7 +1168,7 @@ read_header0 (struct tar_stat_info *info)
|
|||||||
enum read_header rc;
|
enum read_header rc;
|
||||||
|
|
||||||
tar_stat_init (info);
|
tar_stat_init (info);
|
||||||
rc = read_header_primitive (false, info);
|
rc = read_header (¤t_header, info, false);
|
||||||
if (rc == HEADER_SUCCESS)
|
if (rc == HEADER_SUCCESS)
|
||||||
{
|
{
|
||||||
set_next_block_after (current_header);
|
set_next_block_after (current_header);
|
||||||
@@ -1312,20 +1313,17 @@ try_new_volume ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Check the LABEL block against the volume label, seen as a globbing
|
/* Check LABEL against the volume label, seen as a globbing
|
||||||
pattern. Return true if the pattern matches. In case of failure,
|
pattern. Return true if the pattern matches. In case of failure,
|
||||||
retry matching a volume sequence number before giving up in
|
retry matching a volume sequence number before giving up in
|
||||||
multi-volume mode. */
|
multi-volume mode. */
|
||||||
static bool
|
static bool
|
||||||
check_label_pattern (union block *label)
|
check_label_pattern (const char *label)
|
||||||
{
|
{
|
||||||
char *string;
|
char *string;
|
||||||
bool result;
|
bool result;
|
||||||
|
|
||||||
if (! memchr (label->header.name, '\0', sizeof label->header.name))
|
if (fnmatch (volume_label_option, label, 0) == 0)
|
||||||
return false;
|
|
||||||
|
|
||||||
if (fnmatch (volume_label_option, label->header.name, 0) == 0)
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (!multi_volume_option)
|
if (!multi_volume_option)
|
||||||
@@ -1335,7 +1333,7 @@ check_label_pattern (union block *label)
|
|||||||
+ sizeof VOLUME_LABEL_APPEND + 1);
|
+ sizeof VOLUME_LABEL_APPEND + 1);
|
||||||
strcpy (string, volume_label_option);
|
strcpy (string, volume_label_option);
|
||||||
strcat (string, VOLUME_LABEL_APPEND);
|
strcat (string, VOLUME_LABEL_APPEND);
|
||||||
result = fnmatch (string, label->header.name, 0) == 0;
|
result = fnmatch (string, label, 0) == 0;
|
||||||
free (string);
|
free (string);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -1345,14 +1343,43 @@ check_label_pattern (union block *label)
|
|||||||
static void
|
static void
|
||||||
match_volume_label (void)
|
match_volume_label (void)
|
||||||
{
|
{
|
||||||
union block *label = find_next_block ();
|
if (!volume_label)
|
||||||
|
{
|
||||||
if (!label)
|
union block *label = find_next_block ();
|
||||||
|
|
||||||
|
if (!label)
|
||||||
|
FATAL_ERROR ((0, 0, _("Archive not labeled to match %s"),
|
||||||
|
quote (volume_label_option)));
|
||||||
|
if (label->header.typeflag == GNUTYPE_VOLHDR)
|
||||||
|
{
|
||||||
|
if (memchr (label->header.name, '\0', sizeof label->header.name))
|
||||||
|
assign_string (&volume_label, label->header.name);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
volume_label = xmalloc (sizeof (label->header.name) + 1);
|
||||||
|
memcpy (volume_label, label->header.name,
|
||||||
|
sizeof (label->header.name));
|
||||||
|
volume_label[sizeof (label->header.name)] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (label->header.typeflag == XGLTYPE)
|
||||||
|
{
|
||||||
|
struct tar_stat_info st;
|
||||||
|
tar_stat_init (&st);
|
||||||
|
xheader_read (&st.xhdr, label,
|
||||||
|
OFF_FROM_HEADER (label->header.size));
|
||||||
|
xheader_decode (&st);
|
||||||
|
tar_stat_destroy (&st);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!volume_label)
|
||||||
FATAL_ERROR ((0, 0, _("Archive not labeled to match %s"),
|
FATAL_ERROR ((0, 0, _("Archive not labeled to match %s"),
|
||||||
quote (volume_label_option)));
|
quote (volume_label_option)));
|
||||||
if (!check_label_pattern (label))
|
|
||||||
|
if (!check_label_pattern (volume_label))
|
||||||
FATAL_ERROR ((0, 0, _("Volume %s does not match %s"),
|
FATAL_ERROR ((0, 0, _("Volume %s does not match %s"),
|
||||||
quote_n (0, label->header.name),
|
quote_n (0, volume_label),
|
||||||
quote_n (1, volume_label_option)));
|
quote_n (1, volume_label_option)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
13
src/common.h
13
src/common.h
@@ -1,7 +1,8 @@
|
|||||||
/* Common declarations for the tar program.
|
/* Common declarations for the tar program.
|
||||||
|
|
||||||
Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001,
|
Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001,
|
||||||
2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
|
2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation,
|
||||||
|
Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it
|
This program is free software; you can redistribute it and/or modify it
|
||||||
under the terms of the GNU General Public License as published by the
|
under the terms of the GNU General Public License as published by the
|
||||||
@@ -396,6 +397,7 @@ extern enum access_mode access_mode;
|
|||||||
extern FILE *stdlis;
|
extern FILE *stdlis;
|
||||||
extern bool write_archive_to_stdout;
|
extern bool write_archive_to_stdout;
|
||||||
extern char *volume_label;
|
extern char *volume_label;
|
||||||
|
extern size_t volume_label_count;
|
||||||
extern char *continued_file_name;
|
extern char *continued_file_name;
|
||||||
extern uintmax_t continued_file_size;
|
extern uintmax_t continued_file_size;
|
||||||
extern uintmax_t continued_file_offset;
|
extern uintmax_t continued_file_offset;
|
||||||
@@ -577,11 +579,12 @@ uintmax_t uintmax_from_header (const char *buf, size_t size);
|
|||||||
|
|
||||||
void list_archive (void);
|
void list_archive (void);
|
||||||
void print_for_mkdir (char *dirname, int length, mode_t mode);
|
void print_for_mkdir (char *dirname, int length, mode_t mode);
|
||||||
void print_header (struct tar_stat_info *st, off_t block_ordinal);
|
void print_header (struct tar_stat_info *st, union block *blk,
|
||||||
|
off_t block_ordinal);
|
||||||
void read_and (void (*do_something) (void));
|
void read_and (void (*do_something) (void));
|
||||||
enum read_header read_header_primitive (bool raw_extended_headers,
|
enum read_header read_header (union block **return_block,
|
||||||
struct tar_stat_info *info);
|
struct tar_stat_info *info,
|
||||||
enum read_header read_header (bool raw_extended_headers);
|
bool raw_extended_headers);
|
||||||
enum read_header tar_checksum (union block *header, bool silent);
|
enum read_header tar_checksum (union block *header, bool silent);
|
||||||
void skip_file (off_t size);
|
void skip_file (off_t size);
|
||||||
void skip_member (void);
|
void skip_member (void);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* Diff files from a tar archive.
|
/* Diff files from a tar archive.
|
||||||
|
|
||||||
Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001,
|
Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001,
|
||||||
2003, 2004, 2005, 2006, 2007, 2009 Free Software Foundation, Inc.
|
2003, 2004, 2005, 2006, 2007, 2009, 2010 Free Software Foundation, Inc.
|
||||||
|
|
||||||
Written by John Gilmore, on 1987-04-30.
|
Written by John Gilmore, on 1987-04-30.
|
||||||
|
|
||||||
@@ -460,7 +460,7 @@ diff_archive (void)
|
|||||||
{
|
{
|
||||||
if (now_verifying)
|
if (now_verifying)
|
||||||
fprintf (stdlis, _("Verify "));
|
fprintf (stdlis, _("Verify "));
|
||||||
print_header (¤t_stat_info, -1);
|
print_header (¤t_stat_info, current_header, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (current_header->header.typeflag)
|
switch (current_header->header.typeflag)
|
||||||
@@ -578,7 +578,8 @@ verify_volume (void)
|
|||||||
flush_read ();
|
flush_read ();
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
enum read_header status = read_header (false);
|
enum read_header status = read_header (¤t_header,
|
||||||
|
¤t_stat_info, false);
|
||||||
|
|
||||||
if (status == HEADER_FAILURE)
|
if (status == HEADER_FAILURE)
|
||||||
{
|
{
|
||||||
@@ -588,7 +589,8 @@ verify_volume (void)
|
|||||||
{
|
{
|
||||||
counter++;
|
counter++;
|
||||||
set_next_block_after (current_header);
|
set_next_block_after (current_header);
|
||||||
status = read_header (false);
|
status = read_header (¤t_header, ¤t_stat_info,
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
while (status == HEADER_FAILURE);
|
while (status == HEADER_FAILURE);
|
||||||
|
|
||||||
@@ -606,7 +608,7 @@ verify_volume (void)
|
|||||||
{
|
{
|
||||||
char buf[UINTMAX_STRSIZE_BOUND];
|
char buf[UINTMAX_STRSIZE_BOUND];
|
||||||
|
|
||||||
status = read_header (false);
|
status = read_header (¤t_header, ¤t_stat_info, false);
|
||||||
if (status == HEADER_ZERO_BLOCK)
|
if (status == HEADER_ZERO_BLOCK)
|
||||||
break;
|
break;
|
||||||
WARNOPT (WARN_ALONE_ZERO_BLOCK,
|
WARNOPT (WARN_ALONE_ZERO_BLOCK,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* Create a tar archive.
|
/* Create a tar archive.
|
||||||
|
|
||||||
Copyright (C) 1985, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001,
|
Copyright (C) 1985, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001,
|
||||||
2003, 2004, 2005, 2006, 2007, 2009 Free Software Foundation, Inc.
|
2003, 2004, 2005, 2006, 2007, 2009, 2010 Free Software Foundation, Inc.
|
||||||
|
|
||||||
Written by John Gilmore, on 1985-08-25.
|
Written by John Gilmore, on 1985-08-25.
|
||||||
|
|
||||||
@@ -996,11 +996,11 @@ finish_header (struct tar_stat_info *st,
|
|||||||
&& header->header.typeflag != XHDTYPE
|
&& header->header.typeflag != XHDTYPE
|
||||||
&& header->header.typeflag != XGLTYPE)
|
&& header->header.typeflag != XGLTYPE)
|
||||||
{
|
{
|
||||||
/* These globals are parameters to print_header, sigh. */
|
/* FIXME: These globals are parameters to print_header, sigh. */
|
||||||
|
|
||||||
current_header = header;
|
current_header = header;
|
||||||
current_format = archive_format;
|
current_format = archive_format;
|
||||||
print_header (st, block_ordinal);
|
print_header (st, current_header, block_ordinal);
|
||||||
}
|
}
|
||||||
|
|
||||||
header = write_extended (false, st, header);
|
header = write_extended (false, st, header);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* Delete entries from a tar archive.
|
/* Delete entries from a tar archive.
|
||||||
|
|
||||||
Copyright (C) 1988, 1992, 1994, 1996, 1997, 2000, 2001, 2003, 2004,
|
Copyright (C) 1988, 1992, 1994, 1996, 1997, 2000, 2001, 2003, 2004,
|
||||||
2005, 2006 Free Software Foundation, Inc.
|
2005, 2006, 2010 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it
|
This program is free software; you can redistribute it and/or modify it
|
||||||
under the terms of the GNU General Public License as published by the
|
under the terms of the GNU General Public License as published by the
|
||||||
@@ -165,7 +165,9 @@ delete_archive_members (void)
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
enum read_header status = read_header (true);
|
enum read_header status = read_header (¤t_header,
|
||||||
|
¤t_stat_info,
|
||||||
|
true);
|
||||||
|
|
||||||
switch (status)
|
switch (status)
|
||||||
{
|
{
|
||||||
@@ -260,7 +262,7 @@ delete_archive_members (void)
|
|||||||
|
|
||||||
if (current_block == record_end)
|
if (current_block == record_end)
|
||||||
flush_archive ();
|
flush_archive ();
|
||||||
status = read_header (false);
|
status = read_header (¤t_header, ¤t_stat_info, false);
|
||||||
|
|
||||||
xheader_decode (¤t_stat_info);
|
xheader_decode (¤t_stat_info);
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* Extract files from a tar archive.
|
/* Extract files from a tar archive.
|
||||||
|
|
||||||
Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1998, 1999, 2000,
|
Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1998, 1999, 2000,
|
||||||
2001, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
|
2001, 2003, 2004, 2005, 2006, 2007, 2010 Free Software Foundation, Inc.
|
||||||
|
|
||||||
Written by John Gilmore, on 1985-11-19.
|
Written by John Gilmore, on 1985-11-19.
|
||||||
|
|
||||||
@@ -1092,8 +1092,6 @@ extract_fifo (char *file_name, int typeflag)
|
|||||||
static int
|
static int
|
||||||
extract_volhdr (char *file_name, int typeflag)
|
extract_volhdr (char *file_name, int typeflag)
|
||||||
{
|
{
|
||||||
if (verbose_option)
|
|
||||||
fprintf (stdlis, _("Reading %s\n"), quote (current_stat_info.file_name));
|
|
||||||
skip_member ();
|
skip_member ();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1259,7 +1257,7 @@ extract_archive (void)
|
|||||||
|
|
||||||
/* Print the block from current_header and current_stat. */
|
/* Print the block from current_header and current_stat. */
|
||||||
if (verbose_option)
|
if (verbose_option)
|
||||||
print_header (¤t_stat_info, -1);
|
print_header (¤t_stat_info, current_header, -1);
|
||||||
|
|
||||||
/* Restore stats for all non-ancestor directories, unless
|
/* Restore stats for all non-ancestor directories, unless
|
||||||
it is an incremental archive.
|
it is an incremental archive.
|
||||||
|
|||||||
93
src/list.c
93
src/list.c
@@ -1,7 +1,7 @@
|
|||||||
/* List a tar archive, with support routines for reading a tar archive.
|
/* List a tar archive, with support routines for reading a tar archive.
|
||||||
|
|
||||||
Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1998, 1999, 2000,
|
Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1998, 1999, 2000,
|
||||||
2001, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
|
2001, 2003, 2004, 2005, 2006, 2007, 2010 Free Software Foundation, Inc.
|
||||||
|
|
||||||
Written by John Gilmore, on 1985-08-26.
|
Written by John Gilmore, on 1985-08-26.
|
||||||
|
|
||||||
@@ -33,6 +33,7 @@ union block *recent_long_name; /* recent long name header and contents */
|
|||||||
union block *recent_long_link; /* likewise, for long link */
|
union block *recent_long_link; /* likewise, for long link */
|
||||||
size_t recent_long_name_blocks; /* number of blocks in recent_long_name */
|
size_t recent_long_name_blocks; /* number of blocks in recent_long_name */
|
||||||
size_t recent_long_link_blocks; /* likewise, for long link */
|
size_t recent_long_link_blocks; /* likewise, for long link */
|
||||||
|
union block *recent_global_header; /* Recent global header block */
|
||||||
|
|
||||||
static uintmax_t from_header (const char *, size_t, const char *,
|
static uintmax_t from_header (const char *, size_t, const char *,
|
||||||
uintmax_t, uintmax_t, bool, bool);
|
uintmax_t, uintmax_t, bool, bool);
|
||||||
@@ -77,7 +78,7 @@ read_and (void (*do_something) (void))
|
|||||||
prev_status = status;
|
prev_status = status;
|
||||||
tar_stat_destroy (¤t_stat_info);
|
tar_stat_destroy (¤t_stat_info);
|
||||||
|
|
||||||
status = read_header (false);
|
status = read_header (¤t_header, ¤t_stat_info, false);
|
||||||
switch (status)
|
switch (status)
|
||||||
{
|
{
|
||||||
case HEADER_STILL_UNREAD:
|
case HEADER_STILL_UNREAD:
|
||||||
@@ -138,7 +139,7 @@ read_and (void (*do_something) (void))
|
|||||||
{
|
{
|
||||||
char buf[UINTMAX_STRSIZE_BOUND];
|
char buf[UINTMAX_STRSIZE_BOUND];
|
||||||
|
|
||||||
status = read_header (false);
|
status = read_header (¤t_header, ¤t_stat_info, false);
|
||||||
if (status == HEADER_ZERO_BLOCK)
|
if (status == HEADER_ZERO_BLOCK)
|
||||||
break;
|
break;
|
||||||
WARNOPT (WARN_ALONE_ZERO_BLOCK,
|
WARNOPT (WARN_ALONE_ZERO_BLOCK,
|
||||||
@@ -205,11 +206,12 @@ void
|
|||||||
list_archive (void)
|
list_archive (void)
|
||||||
{
|
{
|
||||||
off_t block_ordinal = current_block_ordinal ();
|
off_t block_ordinal = current_block_ordinal ();
|
||||||
/* Print the header block. */
|
|
||||||
|
|
||||||
|
/* Print the header block. */
|
||||||
|
|
||||||
decode_header (current_header, ¤t_stat_info, ¤t_format, 0);
|
decode_header (current_header, ¤t_stat_info, ¤t_format, 0);
|
||||||
if (verbose_option)
|
if (verbose_option)
|
||||||
print_header (¤t_stat_info, block_ordinal);
|
print_header (¤t_stat_info, current_header, block_ordinal);
|
||||||
|
|
||||||
if (incremental_option)
|
if (incremental_option)
|
||||||
{
|
{
|
||||||
@@ -293,7 +295,8 @@ tar_checksum (union block *header, bool silent)
|
|||||||
the header which this routine reads. */
|
the header which this routine reads. */
|
||||||
|
|
||||||
enum read_header
|
enum read_header
|
||||||
read_header_primitive (bool raw_extended_headers, struct tar_stat_info *info)
|
read_header (union block **return_block, struct tar_stat_info *info,
|
||||||
|
bool raw_extended_headers)
|
||||||
{
|
{
|
||||||
union block *header;
|
union block *header;
|
||||||
union block *header_copy;
|
union block *header_copy;
|
||||||
@@ -310,7 +313,7 @@ read_header_primitive (bool raw_extended_headers, struct tar_stat_info *info)
|
|||||||
enum read_header status;
|
enum read_header status;
|
||||||
|
|
||||||
header = find_next_block ();
|
header = find_next_block ();
|
||||||
current_header = header;
|
*return_block = header;
|
||||||
if (!header)
|
if (!header)
|
||||||
return HEADER_END_OF_FILE;
|
return HEADER_END_OF_FILE;
|
||||||
|
|
||||||
@@ -392,6 +395,11 @@ read_header_primitive (bool raw_extended_headers, struct tar_stat_info *info)
|
|||||||
else if (header->header.typeflag == XGLTYPE)
|
else if (header->header.typeflag == XGLTYPE)
|
||||||
{
|
{
|
||||||
struct xheader xhdr;
|
struct xheader xhdr;
|
||||||
|
|
||||||
|
if (!recent_global_header)
|
||||||
|
recent_global_header = xmalloc (sizeof *recent_global_header);
|
||||||
|
memcpy (recent_global_header, header,
|
||||||
|
sizeof *recent_global_header);
|
||||||
memset (&xhdr, 0, sizeof xhdr);
|
memset (&xhdr, 0, sizeof xhdr);
|
||||||
xheader_read (&xhdr, header,
|
xheader_read (&xhdr, header,
|
||||||
OFF_FROM_HEADER (header->header.size));
|
OFF_FROM_HEADER (header->header.size));
|
||||||
@@ -405,7 +413,7 @@ read_header_primitive (bool raw_extended_headers, struct tar_stat_info *info)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
char const *name;
|
char const *name;
|
||||||
struct posix_header const *h = ¤t_header->header;
|
struct posix_header const *h = &header->header;
|
||||||
char namebuf[sizeof h->prefix + 1 + NAME_FIELD_SIZE + 1];
|
char namebuf[sizeof h->prefix + 1 + NAME_FIELD_SIZE + 1];
|
||||||
|
|
||||||
if (recent_long_name)
|
if (recent_long_name)
|
||||||
@@ -464,12 +472,6 @@ read_header_primitive (bool raw_extended_headers, struct tar_stat_info *info)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum read_header
|
|
||||||
read_header (bool raw_extended_headers)
|
|
||||||
{
|
|
||||||
return read_header_primitive (raw_extended_headers, ¤t_stat_info);
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
decode_xform (char *file_name, void *data)
|
decode_xform (char *file_name, void *data)
|
||||||
{
|
{
|
||||||
@@ -1019,9 +1021,6 @@ tartime (struct timespec t, bool full_time)
|
|||||||
they shouldn't. Unix tar is pretty random here anyway. */
|
they shouldn't. Unix tar is pretty random here anyway. */
|
||||||
|
|
||||||
|
|
||||||
/* FIXME: Note that print_header uses the globals HEAD, HSTAT, and
|
|
||||||
HEAD_STANDARD, which must be set up in advance. Not very clean.. */
|
|
||||||
|
|
||||||
/* Width of "user/group size", with initial value chosen
|
/* Width of "user/group size", with initial value chosen
|
||||||
heuristically. This grows as needed, though this may cause some
|
heuristically. This grows as needed, though this may cause some
|
||||||
stairstepping in the output. Make it too small and the output will
|
stairstepping in the output. Make it too small and the output will
|
||||||
@@ -1034,8 +1033,11 @@ static int ugswidth = 19;
|
|||||||
USGWIDTH, some stairstepping may occur. */
|
USGWIDTH, some stairstepping may occur. */
|
||||||
static int datewidth = sizeof "YYYY-MM-DD HH:MM" - 1;
|
static int datewidth = sizeof "YYYY-MM-DD HH:MM" - 1;
|
||||||
|
|
||||||
void
|
static bool volume_label_printed = false;
|
||||||
print_header (struct tar_stat_info *st, off_t block_ordinal)
|
|
||||||
|
static void
|
||||||
|
simple_print_header (struct tar_stat_info *st, union block *blk,
|
||||||
|
off_t block_ordinal)
|
||||||
{
|
{
|
||||||
char modes[11];
|
char modes[11];
|
||||||
char const *time_stamp;
|
char const *time_stamp;
|
||||||
@@ -1051,7 +1053,7 @@ print_header (struct tar_stat_info *st, off_t block_ordinal)
|
|||||||
int pad;
|
int pad;
|
||||||
int sizelen;
|
int sizelen;
|
||||||
|
|
||||||
if (test_label_option && current_header->header.typeflag != GNUTYPE_VOLHDR)
|
if (test_label_option && blk->header.typeflag != GNUTYPE_VOLHDR)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (show_transformed_names_option)
|
if (show_transformed_names_option)
|
||||||
@@ -1080,9 +1082,10 @@ print_header (struct tar_stat_info *st, off_t block_ordinal)
|
|||||||
/* File type and modes. */
|
/* File type and modes. */
|
||||||
|
|
||||||
modes[0] = '?';
|
modes[0] = '?';
|
||||||
switch (current_header->header.typeflag)
|
switch (blk->header.typeflag)
|
||||||
{
|
{
|
||||||
case GNUTYPE_VOLHDR:
|
case GNUTYPE_VOLHDR:
|
||||||
|
volume_label_printed = true;
|
||||||
modes[0] = 'V';
|
modes[0] = 'V';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1150,8 +1153,8 @@ print_header (struct tar_stat_info *st, off_t block_ordinal)
|
|||||||
/* Try parsing it as an unsigned integer first, and as a
|
/* Try parsing it as an unsigned integer first, and as a
|
||||||
uid_t if that fails. This method can list positive user
|
uid_t if that fails. This method can list positive user
|
||||||
ids that are too large to fit in a uid_t. */
|
ids that are too large to fit in a uid_t. */
|
||||||
uintmax_t u = from_header (current_header->header.uid,
|
uintmax_t u = from_header (blk->header.uid,
|
||||||
sizeof current_header->header.uid, 0,
|
sizeof blk->header.uid, 0,
|
||||||
(uintmax_t) 0,
|
(uintmax_t) 0,
|
||||||
(uintmax_t) TYPE_MAXIMUM (uintmax_t),
|
(uintmax_t) TYPE_MAXIMUM (uintmax_t),
|
||||||
false, false);
|
false, false);
|
||||||
@@ -1160,7 +1163,7 @@ print_header (struct tar_stat_info *st, off_t block_ordinal)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
sprintf (uform, "%ld",
|
sprintf (uform, "%ld",
|
||||||
(long) UID_FROM_HEADER (current_header->header.uid));
|
(long) UID_FROM_HEADER (blk->header.uid));
|
||||||
user = uform;
|
user = uform;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1175,8 +1178,8 @@ print_header (struct tar_stat_info *st, off_t block_ordinal)
|
|||||||
/* Try parsing it as an unsigned integer first, and as a
|
/* Try parsing it as an unsigned integer first, and as a
|
||||||
gid_t if that fails. This method can list positive group
|
gid_t if that fails. This method can list positive group
|
||||||
ids that are too large to fit in a gid_t. */
|
ids that are too large to fit in a gid_t. */
|
||||||
uintmax_t g = from_header (current_header->header.gid,
|
uintmax_t g = from_header (blk->header.gid,
|
||||||
sizeof current_header->header.gid, 0,
|
sizeof blk->header.gid, 0,
|
||||||
(uintmax_t) 0,
|
(uintmax_t) 0,
|
||||||
(uintmax_t) TYPE_MAXIMUM (uintmax_t),
|
(uintmax_t) TYPE_MAXIMUM (uintmax_t),
|
||||||
false, false);
|
false, false);
|
||||||
@@ -1185,14 +1188,14 @@ print_header (struct tar_stat_info *st, off_t block_ordinal)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
sprintf (gform, "%ld",
|
sprintf (gform, "%ld",
|
||||||
(long) GID_FROM_HEADER (current_header->header.gid));
|
(long) GID_FROM_HEADER (blk->header.gid));
|
||||||
group = gform;
|
group = gform;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Format the file size or major/minor device numbers. */
|
/* Format the file size or major/minor device numbers. */
|
||||||
|
|
||||||
switch (current_header->header.typeflag)
|
switch (blk->header.typeflag)
|
||||||
{
|
{
|
||||||
case CHRTYPE:
|
case CHRTYPE:
|
||||||
case BLKTYPE:
|
case BLKTYPE:
|
||||||
@@ -1222,7 +1225,7 @@ print_header (struct tar_stat_info *st, off_t block_ordinal)
|
|||||||
|
|
||||||
fprintf (stdlis, " %s", quotearg (temp_name));
|
fprintf (stdlis, " %s", quotearg (temp_name));
|
||||||
|
|
||||||
switch (current_header->header.typeflag)
|
switch (blk->header.typeflag)
|
||||||
{
|
{
|
||||||
case SYMTYPE:
|
case SYMTYPE:
|
||||||
fprintf (stdlis, " -> %s\n", quotearg (st->link_name));
|
fprintf (stdlis, " -> %s\n", quotearg (st->link_name));
|
||||||
@@ -1235,7 +1238,7 @@ print_header (struct tar_stat_info *st, off_t block_ordinal)
|
|||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
char type_string[2];
|
char type_string[2];
|
||||||
type_string[0] = current_header->header.typeflag;
|
type_string[0] = blk->header.typeflag;
|
||||||
type_string[1] = '\0';
|
type_string[1] = '\0';
|
||||||
fprintf (stdlis, _(" unknown file type %s\n"),
|
fprintf (stdlis, _(" unknown file type %s\n"),
|
||||||
quote (type_string));
|
quote (type_string));
|
||||||
@@ -1269,7 +1272,7 @@ print_header (struct tar_stat_info *st, off_t block_ordinal)
|
|||||||
case GNUTYPE_MULTIVOL:
|
case GNUTYPE_MULTIVOL:
|
||||||
strcpy (size,
|
strcpy (size,
|
||||||
STRINGIFY_BIGINT
|
STRINGIFY_BIGINT
|
||||||
(UINTMAX_FROM_HEADER (current_header->oldgnu_header.offset),
|
(UINTMAX_FROM_HEADER (blk->oldgnu_header.offset),
|
||||||
uintbuf));
|
uintbuf));
|
||||||
fprintf (stdlis, _("--Continued at byte %s--\n"), size);
|
fprintf (stdlis, _("--Continued at byte %s--\n"), size);
|
||||||
break;
|
break;
|
||||||
@@ -1278,6 +1281,34 @@ print_header (struct tar_stat_info *st, off_t block_ordinal)
|
|||||||
fflush (stdlis);
|
fflush (stdlis);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
print_header (struct tar_stat_info *st, union block *blk,
|
||||||
|
off_t block_ordinal)
|
||||||
|
{
|
||||||
|
if (current_format == POSIX_FORMAT && !volume_label_printed && volume_label)
|
||||||
|
{
|
||||||
|
struct tar_stat_info vstat;
|
||||||
|
union block vblk;
|
||||||
|
enum archive_format dummy;
|
||||||
|
|
||||||
|
volume_label_printed = true;
|
||||||
|
|
||||||
|
memset (&vblk, 0, sizeof (vblk));
|
||||||
|
vblk.header.typeflag = GNUTYPE_VOLHDR;
|
||||||
|
if (recent_global_header)
|
||||||
|
memcpy (vblk.header.mtime, recent_global_header->header.mtime,
|
||||||
|
sizeof vblk.header.mtime);
|
||||||
|
tar_stat_init (&vstat);
|
||||||
|
assign_string (&vstat.file_name, ".");
|
||||||
|
decode_header (&vblk, &vstat, &dummy, 0);
|
||||||
|
assign_string (&vstat.file_name, volume_label);
|
||||||
|
simple_print_header (&vstat, &vblk, block_ordinal);
|
||||||
|
tar_stat_destroy (&vstat);
|
||||||
|
}
|
||||||
|
simple_print_header (st, blk, block_ordinal);
|
||||||
|
}
|
||||||
|
|
||||||
/* Print a similar line when we make a directory automatically. */
|
/* Print a similar line when we make a directory automatically. */
|
||||||
void
|
void
|
||||||
print_for_mkdir (char *dirname, int length, mode_t mode)
|
print_for_mkdir (char *dirname, int length, mode_t mode)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* Update a tar archive.
|
/* Update a tar archive.
|
||||||
|
|
||||||
Copyright (C) 1988, 1992, 1994, 1996, 1997, 1999, 2000, 2001, 2003,
|
Copyright (C) 1988, 1992, 1994, 1996, 1997, 1999, 2000, 2001, 2003,
|
||||||
2004, 2005, 2007 Free Software Foundation, Inc.
|
2004, 2005, 2007, 2010 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it
|
This program is free software; you can redistribute it and/or modify it
|
||||||
under the terms of the GNU General Public License as published by the
|
under the terms of the GNU General Public License as published by the
|
||||||
@@ -114,7 +114,8 @@ update_archive (void)
|
|||||||
|
|
||||||
while (!found_end)
|
while (!found_end)
|
||||||
{
|
{
|
||||||
enum read_header status = read_header (false);
|
enum read_header status = read_header (¤t_header,
|
||||||
|
¤t_stat_info, false);
|
||||||
|
|
||||||
switch (status)
|
switch (status)
|
||||||
{
|
{
|
||||||
|
|||||||
105
src/xheader.c
105
src/xheader.c
@@ -1,6 +1,7 @@
|
|||||||
/* POSIX extended headers for tar.
|
/* POSIX extended headers for tar.
|
||||||
|
|
||||||
Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009 Free Software Foundation, Inc.
|
Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009, 2010 Free Software
|
||||||
|
Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it
|
This program is free software; you can redistribute it and/or modify it
|
||||||
under the terms of the GNU General Public License as published by the
|
under the terms of the GNU General Public License as published by the
|
||||||
@@ -440,30 +441,37 @@ xheader_write (char type, char *name, time_t t, struct xheader *xhdr)
|
|||||||
void
|
void
|
||||||
xheader_write_global (struct xheader *xhdr)
|
xheader_write_global (struct xheader *xhdr)
|
||||||
{
|
{
|
||||||
char *name;
|
if (keyword_global_override_list)
|
||||||
struct keyword_list *kp;
|
{
|
||||||
|
struct keyword_list *kp;
|
||||||
|
|
||||||
if (!keyword_global_override_list)
|
xheader_init (xhdr);
|
||||||
return;
|
for (kp = keyword_global_override_list; kp; kp = kp->next)
|
||||||
|
code_string (kp->value, kp->pattern, xhdr);
|
||||||
xheader_init (xhdr);
|
}
|
||||||
for (kp = keyword_global_override_list; kp; kp = kp->next)
|
if (xhdr->stk)
|
||||||
code_string (kp->value, kp->pattern, xhdr);
|
{
|
||||||
xheader_finish (xhdr);
|
char *name;
|
||||||
xheader_write (XGLTYPE, name = xheader_ghdr_name (), time (NULL), xhdr);
|
|
||||||
free (name);
|
xheader_finish (xhdr);
|
||||||
|
xheader_write (XGLTYPE, name = xheader_ghdr_name (), time (NULL), xhdr);
|
||||||
|
free (name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* General Interface */
|
/* General Interface */
|
||||||
|
|
||||||
|
#define XHDR_PROTECTED 0x01
|
||||||
|
#define XHDR_GLOBAL 0x02
|
||||||
|
|
||||||
struct xhdr_tab
|
struct xhdr_tab
|
||||||
{
|
{
|
||||||
char const *keyword;
|
char const *keyword;
|
||||||
void (*coder) (struct tar_stat_info const *, char const *,
|
void (*coder) (struct tar_stat_info const *, char const *,
|
||||||
struct xheader *, void const *data);
|
struct xheader *, void const *data);
|
||||||
void (*decoder) (struct tar_stat_info *, char const *, char const *, size_t);
|
void (*decoder) (struct tar_stat_info *, char const *, char const *, size_t);
|
||||||
bool protect;
|
int flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* This declaration must be extern, because ISO C99 section 6.9.2
|
/* This declaration must be extern, because ISO C99 section 6.9.2
|
||||||
@@ -491,7 +499,7 @@ xheader_protected_pattern_p (const char *pattern)
|
|||||||
struct xhdr_tab const *p;
|
struct xhdr_tab const *p;
|
||||||
|
|
||||||
for (p = xhdr_tab; p->keyword; p++)
|
for (p = xhdr_tab; p->keyword; p++)
|
||||||
if (p->protect && fnmatch (pattern, p->keyword, 0) == 0)
|
if ((p->flags & XHDR_PROTECTED) && fnmatch (pattern, p->keyword, 0) == 0)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -502,7 +510,7 @@ xheader_protected_keyword_p (const char *keyword)
|
|||||||
struct xhdr_tab const *p;
|
struct xhdr_tab const *p;
|
||||||
|
|
||||||
for (p = xhdr_tab; p->keyword; p++)
|
for (p = xhdr_tab; p->keyword; p++)
|
||||||
if (p->protect && strcmp (p->keyword, keyword) == 0)
|
if ((p->flags & XHDR_PROTECTED) && strcmp (p->keyword, keyword) == 0)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -633,7 +641,11 @@ decg (void *data, char const *keyword, char const *value,
|
|||||||
size_t size __attribute__((unused)))
|
size_t size __attribute__((unused)))
|
||||||
{
|
{
|
||||||
struct keyword_list **kwl = data;
|
struct keyword_list **kwl = data;
|
||||||
xheader_list_append (kwl, keyword, value);
|
struct xhdr_tab const *tab = locate_handler (keyword);
|
||||||
|
if (tab && (tab->flags & XHDR_GLOBAL))
|
||||||
|
tab->decoder (data, keyword, value, size);
|
||||||
|
else
|
||||||
|
xheader_list_append (kwl, keyword, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -695,6 +707,9 @@ xheader_read (struct xheader *xhdr, union block *p, size_t size)
|
|||||||
if (len > BLOCKSIZE)
|
if (len > BLOCKSIZE)
|
||||||
len = BLOCKSIZE;
|
len = BLOCKSIZE;
|
||||||
|
|
||||||
|
if (!p)
|
||||||
|
FATAL_ERROR ((0, 0, _("Unexpected EOF in archive")));
|
||||||
|
|
||||||
memcpy (&xhdr->buffer[j], p->buffer, len);
|
memcpy (&xhdr->buffer[j], p->buffer, len);
|
||||||
set_next_block_after (p);
|
set_next_block_after (p);
|
||||||
|
|
||||||
@@ -1491,51 +1506,53 @@ sparse_minor_decoder (struct tar_stat_info *st,
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct xhdr_tab const xhdr_tab[] = {
|
struct xhdr_tab const xhdr_tab[] = {
|
||||||
{ "atime", atime_coder, atime_decoder, false },
|
{ "atime", atime_coder, atime_decoder, 0 },
|
||||||
{ "comment", dummy_coder, dummy_decoder, false },
|
{ "comment", dummy_coder, dummy_decoder, 0 },
|
||||||
{ "charset", dummy_coder, dummy_decoder, false },
|
{ "charset", dummy_coder, dummy_decoder, 0 },
|
||||||
{ "ctime", ctime_coder, ctime_decoder, false },
|
{ "ctime", ctime_coder, ctime_decoder, 0 },
|
||||||
{ "gid", gid_coder, gid_decoder, false },
|
{ "gid", gid_coder, gid_decoder, 0 },
|
||||||
{ "gname", gname_coder, gname_decoder, false },
|
{ "gname", gname_coder, gname_decoder, 0 },
|
||||||
{ "linkpath", linkpath_coder, linkpath_decoder, false },
|
{ "linkpath", linkpath_coder, linkpath_decoder, 0 },
|
||||||
{ "mtime", mtime_coder, mtime_decoder, false },
|
{ "mtime", mtime_coder, mtime_decoder, 0 },
|
||||||
{ "path", path_coder, path_decoder, false },
|
{ "path", path_coder, path_decoder, 0 },
|
||||||
{ "size", size_coder, size_decoder, false },
|
{ "size", size_coder, size_decoder, 0 },
|
||||||
{ "uid", uid_coder, uid_decoder, false },
|
{ "uid", uid_coder, uid_decoder, 0 },
|
||||||
{ "uname", uname_coder, uname_decoder, false },
|
{ "uname", uname_coder, uname_decoder, 0 },
|
||||||
|
|
||||||
/* Sparse file handling */
|
/* Sparse file handling */
|
||||||
{ "GNU.sparse.name", path_coder, path_decoder,
|
{ "GNU.sparse.name", path_coder, path_decoder,
|
||||||
true },
|
XHDR_PROTECTED },
|
||||||
{ "GNU.sparse.major", sparse_major_coder, sparse_major_decoder,
|
{ "GNU.sparse.major", sparse_major_coder, sparse_major_decoder,
|
||||||
true },
|
XHDR_PROTECTED },
|
||||||
{ "GNU.sparse.minor", sparse_minor_coder, sparse_minor_decoder,
|
{ "GNU.sparse.minor", sparse_minor_coder, sparse_minor_decoder,
|
||||||
true },
|
XHDR_PROTECTED },
|
||||||
{ "GNU.sparse.realsize", sparse_size_coder, sparse_size_decoder,
|
{ "GNU.sparse.realsize", sparse_size_coder, sparse_size_decoder,
|
||||||
true },
|
XHDR_PROTECTED },
|
||||||
{ "GNU.sparse.numblocks", sparse_numblocks_coder, sparse_numblocks_decoder,
|
{ "GNU.sparse.numblocks", sparse_numblocks_coder, sparse_numblocks_decoder,
|
||||||
true },
|
XHDR_PROTECTED },
|
||||||
|
|
||||||
/* tar 1.14 - 1.15.90 keywords. */
|
/* tar 1.14 - 1.15.90 keywords. */
|
||||||
{ "GNU.sparse.size", sparse_size_coder, sparse_size_decoder, true },
|
{ "GNU.sparse.size", sparse_size_coder, sparse_size_decoder,
|
||||||
|
XHDR_PROTECTED },
|
||||||
/* tar 1.14 - 1.15.1 keywords. Multiple instances of these appeared in 'x'
|
/* tar 1.14 - 1.15.1 keywords. Multiple instances of these appeared in 'x'
|
||||||
headers, and each of them was meaningful. It confilcted with POSIX specs,
|
headers, and each of them was meaningful. It confilcted with POSIX specs,
|
||||||
which requires that "when extended header records conflict, the last one
|
which requires that "when extended header records conflict, the last one
|
||||||
given in the header shall take precedence." */
|
given in the header shall take precedence." */
|
||||||
{ "GNU.sparse.offset", sparse_offset_coder, sparse_offset_decoder,
|
{ "GNU.sparse.offset", sparse_offset_coder, sparse_offset_decoder,
|
||||||
true },
|
XHDR_PROTECTED },
|
||||||
{ "GNU.sparse.numbytes", sparse_numbytes_coder, sparse_numbytes_decoder,
|
{ "GNU.sparse.numbytes", sparse_numbytes_coder, sparse_numbytes_decoder,
|
||||||
true },
|
XHDR_PROTECTED },
|
||||||
/* tar 1.15.90 keyword, introduced to remove the above-mentioned conflict. */
|
/* tar 1.15.90 keyword, introduced to remove the above-mentioned conflict. */
|
||||||
{ "GNU.sparse.map", NULL /* Unused, see pax_dump_header() */,
|
{ "GNU.sparse.map", NULL /* Unused, see pax_dump_header() */,
|
||||||
sparse_map_decoder, false },
|
sparse_map_decoder, 0 },
|
||||||
|
|
||||||
{ "GNU.dumpdir", dumpdir_coder, dumpdir_decoder,
|
{ "GNU.dumpdir", dumpdir_coder, dumpdir_decoder,
|
||||||
true },
|
XHDR_PROTECTED },
|
||||||
|
|
||||||
/* Keeps the tape/volume label. May be present only in the global headers.
|
/* Keeps the tape/volume label. May be present only in the global headers.
|
||||||
Equivalent to GNUTYPE_VOLHDR. */
|
Equivalent to GNUTYPE_VOLHDR. */
|
||||||
{ "GNU.volume.label", volume_label_coder, volume_label_decoder, true },
|
{ "GNU.volume.label", volume_label_coder, volume_label_decoder,
|
||||||
|
XHDR_PROTECTED | XHDR_GLOBAL },
|
||||||
|
|
||||||
/* These may be present in a first global header of the archive.
|
/* These may be present in a first global header of the archive.
|
||||||
They provide the same functionality as GNUTYPE_MULTIVOL header.
|
They provide the same functionality as GNUTYPE_MULTIVOL header.
|
||||||
@@ -1544,9 +1561,11 @@ struct xhdr_tab const xhdr_tab[] = {
|
|||||||
GNU.volume.offset keeps the offset of the start of this volume,
|
GNU.volume.offset keeps the offset of the start of this volume,
|
||||||
otherwise kept in oldgnu_header.offset. */
|
otherwise kept in oldgnu_header.offset. */
|
||||||
{ "GNU.volume.filename", volume_label_coder, volume_filename_decoder,
|
{ "GNU.volume.filename", volume_label_coder, volume_filename_decoder,
|
||||||
true },
|
XHDR_PROTECTED | XHDR_GLOBAL },
|
||||||
{ "GNU.volume.size", volume_size_coder, volume_size_decoder, true },
|
{ "GNU.volume.size", volume_size_coder, volume_size_decoder,
|
||||||
{ "GNU.volume.offset", volume_offset_coder, volume_offset_decoder, true },
|
XHDR_PROTECTED | XHDR_GLOBAL },
|
||||||
|
{ "GNU.volume.offset", volume_offset_coder, volume_offset_decoder,
|
||||||
|
XHDR_PROTECTED | XHDR_GLOBAL },
|
||||||
|
|
||||||
{ NULL, NULL, NULL, false }
|
{ NULL, NULL, NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -87,6 +87,8 @@ TESTSUITE_AT = \
|
|||||||
incr06.at\
|
incr06.at\
|
||||||
indexfile.at\
|
indexfile.at\
|
||||||
ignfail.at\
|
ignfail.at\
|
||||||
|
label01.at\
|
||||||
|
label02.at\
|
||||||
link01.at\
|
link01.at\
|
||||||
link02.at\
|
link02.at\
|
||||||
link03.at\
|
link03.at\
|
||||||
|
|||||||
35
tests/label01.at
Normal file
35
tests/label01.at
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||||
|
|
||||||
|
# Test suite for GNU tar.
|
||||||
|
# Copyright (C) 2010 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
AT_SETUP([single-volume label])
|
||||||
|
AT_KEYWORDS([label label01])
|
||||||
|
|
||||||
|
AT_TAR_CHECK([
|
||||||
|
genfile --file foo
|
||||||
|
genfile --file bar
|
||||||
|
tar -cf archive --label=Test foo bar
|
||||||
|
tar tf archive
|
||||||
|
],
|
||||||
|
[0],
|
||||||
|
[Test
|
||||||
|
foo
|
||||||
|
bar
|
||||||
|
],
|
||||||
|
[],[],[],[gnu,oldgnu,posix])
|
||||||
|
|
||||||
|
AT_CLEANUP
|
||||||
38
tests/label02.at
Normal file
38
tests/label02.at
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||||
|
|
||||||
|
# Test suite for GNU tar.
|
||||||
|
# Copyright (C) 2010 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
AT_SETUP([multi-volume label])
|
||||||
|
AT_KEYWORDS([label label02 multi-label multivolume multiv])
|
||||||
|
|
||||||
|
AT_TAR_CHECK([
|
||||||
|
exec <&-
|
||||||
|
genfile --length 0 --file foo
|
||||||
|
genfile --length 12288 --file bar
|
||||||
|
genfile --length 12288 --file baz
|
||||||
|
tar --label=Test -cM -L10 -f 1.tar -f 2.tar -f 3.tar -f 4.tar foo bar baz
|
||||||
|
tar -Mt -f 1.tar -f 2.tar -f 3.tar -f 4.tar
|
||||||
|
],
|
||||||
|
[0],
|
||||||
|
[Test Volume 1
|
||||||
|
foo
|
||||||
|
bar
|
||||||
|
baz
|
||||||
|
],
|
||||||
|
[],[],[],[gnu,oldgnu,posix])
|
||||||
|
|
||||||
|
AT_CLEANUP
|
||||||
@@ -146,6 +146,9 @@ m4_include([extrac06.at])
|
|||||||
m4_include([extrac07.at])
|
m4_include([extrac07.at])
|
||||||
m4_include([extrac08.at])
|
m4_include([extrac08.at])
|
||||||
|
|
||||||
|
m4_include([label01.at])
|
||||||
|
m4_include([label02.at])
|
||||||
|
|
||||||
m4_include([backup01.at])
|
m4_include([backup01.at])
|
||||||
|
|
||||||
m4_include([gzip.at])
|
m4_include([gzip.at])
|
||||||
|
|||||||
Reference in New Issue
Block a user