Репозитории ALT
S: | 1.35.0.20.1cdad4cc-alt1 |
5.1: | 1.23-alt4 |
4.1: | 1.20-alt1.M41.1 |
4.0: | 1.15.1-alt8 |
3.0: | 1.15.1-alt2 |
+updates: | 1.15.1-alt4.M30.2 |
Группа :: Архивирование/Резервное копирование
Пакет: tar
Главная Изменения Спек Патчи Sources Загрузить Gear Bugs and FR Repocop
Патч: tar-1.23-alt4.patch
Скачать
Скачать
NEWS | 49 ++++++++++++++++++--
THANKS | 2 +-
doc/tar.texi | 128 +++++++++++++++++++++++++++++---------------------
lib/rtapelib.c | 16 ++++++-
src/buffer.c | 10 ++--
src/common.h | 4 +-
src/create.c | 45 +++++++++++-------
src/extract.c | 65 +++++++++++++++++++-------
src/list.c | 25 +++++-----
src/misc.c | 98 +++++++++++++++++++++++++++++++++++++--
src/names.c | 52 +++++++++++++++++---
src/system.c | 20 ++++++++-
src/tar.c | 40 +++++++++-------
src/xheader.c | 4 +-
tests/Makefile.am | 5 ++
tests/extrac07.at | 4 +-
tests/genfile.c | 12 +++--
tests/label03.at | 89 +++++++++++++++++++++++++++++++++++
tests/label04.at | 53 +++++++++++++++++++++
tests/label05.at | 50 ++++++++++++++++++++
tests/remfiles01.at | 5 ++-
tests/remfiles03.at | 45 ++++++++++++++++++
tests/sigpipe.at | 39 +++++++++++++++
tests/testsuite.at | 6 ++
24 files changed, 713 insertions(+), 153 deletions(-)
diff --git a/NEWS b/NEWS
index 3254266..8b55ece 100644
--- a/NEWS
+++ b/NEWS
@@ -1,7 +1,48 @@
-GNU tar NEWS - User visible changes. 2010-03-10
+GNU tar NEWS - User visible changes. 2010-03-20
Please send GNU tar bug reports to <bug-tar@gnu.org>
+
+* Bugfixes.
+
+** Spurious error diagnostics on broken pipe.
+
+When receiving SIGPIPE, tar would exit with error status and
+"write error" diagnostics. In particular, this occurred if
+invoked as in the example below:
+
+ tar tf archive.tar | head -n 1
+
+** --remove-files
+
+Tar --remove-files failed to remove a directory which contained
+symlinks to another files within that directory.
+
+** --test-label behavior
+
+In case of a mismatch, `tar --test-label LABEL' exits with code 1,
+not 2 as it did in previous versions.
+
+The `--verbose' option used with `--test-label' provides additional
+diagnostics.
+
+Several volume labels may be specified in a command line, e.g.:
+
+ tar --test-label -f archive 'My volume' 'New volume' 'Test volume'
+
+In this case, tar exits with code 0 if any one of the arguments
+matches the actual volume label.
+
+** --label used with --update
+
+The `--label' option can be used with `--update' to prevent accidental
+update of an archive:
+
+ tar -rf archive --label 'My volume' .
+
+This did not work in previous versions, in spite of what the docs said.
+
+
version 1.23 - Sergey Poznyakoff, 2010-03-10
* Record size autodetection
@@ -694,7 +735,7 @@ tar.
* New message translations fi (Finnish), gl (Galician), hr (Croatian),
hu (Hungarian), ms (Malaysian), nb (Norwegian), ro (Romanian), sk
(Slovak), zh_CN (Chinese simplified), zh_TW (Chinese traditional).
- The code 'no' for Norwegian (Bokmц╔l) has been withdrawn; use 'nb' instead.
+ The code 'no' for Norwegian (BokmЕl) has been withdrawn; use 'nb' instead.
* Bug fixes.
@@ -1019,7 +1060,7 @@ version 1.13 - Paul Eggert, 1999-07-08.
but they have been removed to maintain compatibility with paxutils.
Please try --use=bzip2 instead of --bzip2.
-Version 1.12 - Franц╖ois Pinard, 1997-04.
+Version 1.12 - FranГois Pinard, 1997-04.
Sensitive matters
* Use shell globbing patterns for --label, instead of regular expressions.
@@ -1062,7 +1103,7 @@ Various changes
Many bugs are squashed, while others still run free.
-Version 1.11.8 - Franц╖ois Pinard, 1995-06.
+Version 1.11.8 - FranГois Pinard, 1995-06.
* Messages available in French, German, Portuguese and Swedish.
* The distribution provides a rudimentary Texinfo manual.
diff --git a/THANKS b/THANKS
index 525981c..0364c50 100644
--- a/THANKS
+++ b/THANKS
@@ -133,7 +133,7 @@ David Steiner dsteiner@ispa.uni-osnabrueck.de
David Taylor taylor@think.com
Dean Gaudet dgaudet@watdragon.uwaterloo.ca
Demizu Noritoshi nori-d@is.aist-nara.ac.jp
-Denis Excoffier denis.excoffier@airbus.com
+Denis Excoffier denis.excoffier@free.fr
Denis Fortin fortin@acm.org
Dennis Pixton dennis@math.binghamton.edu
Dick Streefland dicks@tasking.nl
diff --git a/doc/tar.texi b/doc/tar.texi
index 0fcd04b..18ffea0 100644
--- a/doc/tar.texi
+++ b/doc/tar.texi
@@ -449,7 +449,7 @@ operations (@samp{create}, @samp{list}, and @samp{extract}) as well as
two frequently used options (@samp{file} and @samp{verbose}). The other
chapters do not refer to the tutorial frequently; however, if a section
discusses something which is a complex variant of a basic concept, there
-may be a cross reference to that basic concept. (The entire book,
+may be a cross-reference to that basic concept. (The entire book,
including the tutorial, assumes that the reader understands some basic
concepts of using a Unix-type operating system; @pxref{Tutorial}.)
@@ -3210,7 +3210,7 @@ successfully. This option is intended for use in shell scripts.
Here is an example of what you can see using this option:
@smallexample
-$ tar --show-defaults
+$ @kbd{tar --show-defaults}
--format=gnu -f- -b20 --quoting-style=escape
--rmt-command=/usr/libexec/rmt --rsh-command=/usr/bin/rsh
@end smallexample
@@ -3342,12 +3342,12 @@ To see transformed member names in verbose listings, use
@opsummary{uncompress}
@item --uncompress
-(See @option{--compress}. @pxref{gzip})
+(See @option{--compress}, @pxref{gzip})
@opsummary{ungzip}
@item --ungzip
-(See @option{--gzip}. @pxref{gzip})
+(See @option{--gzip}, @pxref{gzip})
@opsummary{unlink-first}
@item --unlink-first
@@ -4551,7 +4551,7 @@ $ @kbd{tar --extract -vv --occurrence --file=collection.tar blues}
@end smallexample
@xref{Writing}, for more information on @option{--extract} and
-@xref{Option Summary, --occurrence}, for the description of
+see @ref{Option Summary, --occurrence}, for a description of
@option{--occurrence} option.
@node update
@@ -4599,7 +4599,7 @@ To see the @option{--update} option at work, create a new file,
@file{classical}, in your practice directory, and some extra text to the
file @file{blues}, using any text editor. Then invoke @command{tar} with
the @samp{update} operation and the @option{--verbose} (@option{-v})
-option specified, using the names of all the files in the practice
+option specified, using the names of all the files in the @file{practice}
directory as file name arguments:
@smallexample
@@ -4646,8 +4646,8 @@ To use @option{--concatenate}, give the first archive with
@option{--file} option and name the rest of archives to be
concatenated on the command line. The members, and their member
names, will be copied verbatim from those archives to the first
-one@footnote{This can cause multiple members to have the same name, for
-information on how this affects reading the archive, @ref{multiple}.}.
+one@footnote{This can cause multiple members to have the same name. For
+information on how this affects reading the archive, see @ref{multiple}.}.
The new, concatenated archive will be called by the same name as the
one given with the @option{--file} option. As usual, if you omit
@option{--file}, @command{tar} will use the value of the environment
@@ -4811,7 +4811,7 @@ tar: funk not found in archive
The spirit behind the @option{--compare} (@option{--diff},
@option{-d}) option is to check whether the archive represents the
current state of files on disk, more than validating the integrity of
-the archive media. For this latter goal, @xref{verify}.
+the archive media. For this latter goal, see @ref{verify}.
@node create options
@section Options Used by @option{--create}
@@ -4869,7 +4869,7 @@ either a textual date representation in almost arbitrary format
with @samp{/} or @samp{.}. In the latter case, the modification time
of that file will be used.
-The following example will set the modification date to 00:00:00 UTC,
+The following example will set the modification date to 00:00:00,
January 1, 1970:
@smallexample
@@ -5536,9 +5536,9 @@ space, you can use @option{--starting-file=@var{name}} (@option{-K
archive. This assumes, of course, that there is now free space, or
that you are now extracting into a different file system. (You could
also choose to suspend @command{tar}, remove unnecessary files from
-the file system, and then restart the same @command{tar} operation.
-In this case, @option{--starting-file} is not necessary.
-@xref{Incremental Dumps}, @xref{interactive}, and @ref{exclude}.)
+the file system, and then resume the same @command{tar} operation.
+In this case, @option{--starting-file} is not necessary.) See also
+@ref{interactive}, and @ref{exclude}.
@node Same Order
@unnumberedsubsubsec Same Order
@@ -5692,16 +5692,20 @@ $ @kbd{tar -C sourcedir -cf - . | tar -C targetdir -xf -}
The command also works using long option forms:
@smallexample
+@group
$ @kbd{(cd sourcedir; tar --create --file=- . ) \
| (cd targetdir; tar --extract --file=-)}
+@end group
@end smallexample
@noindent
or
@smallexample
-$ @kbd{tar --directory sourcedir --create --file=- . ) \
+@group
+$ @kbd{tar --directory sourcedir --create --file=- . \
| tar --directory targetdir --extract --file=-}
+@end group
@end smallexample
@noindent
@@ -8069,8 +8073,8 @@ $ @kbd{tar --transform 's,^,/usr/local/,S', -c -v -f arch.tar \
--show-transformed /lib}
drwxr-xr-x root/root 0 2008-07-08 16:20 /usr/local/lib/
-rwxr-xr-x root/root 1250840 2008-05-25 07:44 /usr/local/lib/libc-2.3.2.so
-lrwxrwxrwx root/root 0 2008-06-24 17:12 /usr/local/lib/libc.so.6 ->
-libc-2.3.2.so
+lrwxrwxrwx root/root 0 2008-06-24 17:12 /usr/local/lib/libc.so.6 \
+ -> libc-2.3.2.so
@end smallexample
Unlike @option{--strip-components}, @option{--transform} can be used
@@ -8691,7 +8695,7 @@ $ @kbd{tar cfa archive.tar.lzma .}
@end smallexample
For a complete list of file name suffixes recognized by @GNUTAR{},
-@ref{auto-compress}.
+see @ref{auto-compress}.
Reading compressed archive is even simpler: you don't need to specify
any additional options as @GNUTAR{} recognizes its format
@@ -8709,7 +8713,7 @@ The format recognition algorithm is based on @dfn{signatures}, a
special byte sequences in the beginning of file, that are specific for
certain compression formats. If this approach fails, @command{tar}
falls back to using archive name suffix to determine its format
-(@xref{auto-compress}, for a list of recognized suffixes).
+(@pxref{auto-compress}, for a list of recognized suffixes).
The only case when you have to specify a decompression option while
reading the archive is when reading from a pipe or from a tape drive
@@ -9370,7 +9374,7 @@ free from many of @samp{v7}'s drawbacks.
@cindex ustar archive format
Archive format defined by @acronym{POSIX}.1-1988 specification is called
@code{ustar}. Although it is more flexible than the V7 format, it
-still has many restrictions (@xref{Formats,ustar}, for the detailed
+still has many restrictions (@pxref{Formats,ustar}, for the detailed
description of @code{ustar} format). Along with V7 format,
@code{ustar} format is a good choice for archives intended to be read
with other implementations of @command{tar}.
@@ -9800,7 +9804,7 @@ The condensed file will contain both file map and file data, so no
additional data will be needed to restore it. If the original file
name was @file{@var{dir}/@var{name}}, then the condensed file will be
named @file{@var{dir}/@/GNUSparseFile.@var{n}/@/@var{name}}, where
-@var{n} is a decimal number@footnote{technically speaking, @var{n} is a
+@var{n} is a decimal number@footnote{Technically speaking, @var{n} is a
@dfn{process @acronym{ID}} of the @command{tar} process which created the
archive (@pxref{PAX keywords}).}.
@@ -10233,16 +10237,8 @@ Archive file is local even if it contains a colon.
@opindex rsh-command
@item --rsh-command=@var{command}
-Use remote @var{command} instead of @command{rsh}. This option exists
-so that people who use something other than the standard @command{rsh}
-(e.g., a Kerberized @command{rsh}) can access a remote device.
-
-When this command is not used, the shell command found when
-the @command{tar} program was installed is used instead. This is
-the first found of @file{/usr/ucb/rsh}, @file{/usr/bin/remsh},
-@file{/usr/bin/rsh}, @file{/usr/bsd/rsh} or @file{/usr/bin/nsh}.
-The installer may have overridden this by defining the environment
-variable @env{RSH} @emph{at installation time}.
+Use remote @var{command} instead of the compile-time default (if any).
+The typical setting to use is @code{--rsh-command=/usr/bin/ssh}.
@item -[0-7][lmh]
Specify drive and density.
@@ -11300,9 +11296,9 @@ archive which will be displayed when the archive is listed with
@option{--multi-volume} (@pxref{Using Multiple Tapes}), then the
volume label will have @samp{Volume @var{nnn}} appended to the name
you give, where @var{nnn} is the number of the volume of the archive.
-If you use the @option{--label=@var{volume-label}}) option when
+If you use the @option{--label=@var{volume-label}} option when
reading an archive, it checks to make sure the label on the tape
-matches the one you give. @xref{label}.
+matches the one you gave. @xref{label}.
When @command{tar} writes an archive to tape, it creates a single
tape file. If multiple archives are written to the same tape, one
@@ -11351,15 +11347,16 @@ will usually see lots of spurious messages.
@cindex Labeling an archive
@cindex Labels on the archive media
@cindex Labeling multi-volume archives
-@UNREVISED
@opindex label
To avoid problems caused by misplaced paper labels on the archive
-media, you can include a @dfn{label} entry---an archive member which
-contains the name of the archive---in the archive itself. Use the
+media, you can include a @dfn{label} entry --- an archive member which
+contains the name of the archive --- in the archive itself. Use the
@option{--label=@var{archive-label}} (@option{-V @var{archive-label}})
-option in conjunction with the @option{--create} operation to include
-a label entry in the archive as it is being created.
+option@footnote{Until version 1.10, that option was called
+@option{--volume}, but is not available under that name anymore.} in
+conjunction with the @option{--create} operation to include a label
+entry in the archive as it is being created.
@table @option
@item --label=@var{archive-label}
@@ -11398,7 +11395,7 @@ V--------- 0 0 0 1992-03-07 12:01 iamalabel--Volume Header--
However, @option{--list} option will cause listing entire
contents of the archive, which may be undesirable (for example, if the
archive is stored on a tape). You can request checking only the volume
-by specifying @option{--test-label} option. This option reads only the
+label by specifying @option{--test-label} option. This option reads only the
first block of an archive, so it can be used with slow storage
devices. For example:
@@ -11409,16 +11406,35 @@ iamalabel
@end group
@end smallexample
- If @option{--test-label} is used with a single command line
-argument, @command{tar} compares the volume label with the
-argument. It exits with code 0 if the two strings match, and with code
-2 otherwise. In this case no output is displayed. For example:
+ If @option{--test-label} is used with one or more command line
+arguments, @command{tar} compares the volume label with each
+argument. It exits with code 0 if a match is found, and with code 1
+otherwise@footnote{Note that @GNUTAR{} versions up to 1.23 indicated
+mismatch with an exit code 2 and printed a spurious diagnostics on
+stderr.}. No output is displayed, unless you also used the
+@option{--verbose} option. For example:
@smallexample
@group
-$ @kbd{tar --test-label --file=iamanarchive 'iamalable'}
+$ @kbd{tar --test-label --file=iamanarchive 'iamalabel'}
@result{} 0
-$ @kbd{tar --test-label --file=iamanarchive 'iamalable' alabel}
+$ @kbd{tar --test-label --file=iamanarchive 'alabel'}
+@result{} 1
+@end group
+@end smallexample
+
+ When used with the @option{--verbose} option, @command{tar}
+prints the actual volume label (if any), and a verbose diagnostics in
+case of a mismatch:
+
+@smallexample
+@group
+$ @kbd{tar --test-label --verbose --file=iamanarchive 'iamalabel'}
+iamalabel
+@result{} 0
+$ @kbd{tar --test-label --verbose --file=iamanarchive 'alabel'}
+iamalabel
+tar: Archive label mismatch
@result{} 1
@end group
@end smallexample
@@ -11458,9 +11474,6 @@ up. Since the volume numbering is automatically added in labels at
creation time, it sounded logical to equally help the user taking care
of it when the archive is being read.
- The @option{--label} was once called @option{--volume}, but is not
-available under that name anymore.
-
You can also use @option{--label} to get a common information on
all tapes of a series. For having this information different in each
series created through a single script used on a regular basis, just
@@ -11474,13 +11487,19 @@ $ @kbd{tar --create --file=/dev/tape --multi-volume \
@end group
@end smallexample
- Also note that each label has its own date and time, which corresponds
-to when @GNUTAR{} initially attempted to write it,
+ Some more notes about volume labels:
+
+@itemize @bullet
+@item Each label has its own date and time, which corresponds
+to the time when @GNUTAR{} initially attempted to write it,
often soon after the operator launches @command{tar} or types the
-carriage return telling that the next tape is ready. Comparing date
-labels does give an idea of tape throughput only if the delays for
-rewinding tapes and the operator switching them were negligible, which
-is usually not the case.
+carriage return telling that the next tape is ready.
+
+@item Comparing date labels to get an idea of tape throughput is
+unreliable. It gives correct results only if the delays for rewinding
+tapes and the operator switching them were negligible, which is
+usually not the case.
+@end itemize
@node verify
@section Verifying Data as It is Stored
@@ -11907,7 +11926,8 @@ Right margin of the text output. Used for wrapping.
This appendix contains an index of all @GNUTAR{} long command line
options. The options are listed without the preceding double-dash.
-For a cross-reference of short command line options, @ref{Short Option Summary}.
+For a cross-reference of short command line options, see
+@ref{Short Option Summary}.
@printindex op
diff --git a/lib/rtapelib.c b/lib/rtapelib.c
index cb645db..435c17c 100644
--- a/lib/rtapelib.c
+++ b/lib/rtapelib.c
@@ -367,6 +367,15 @@ rmt_open__ (const char *file_name, int open_mode, int bias,
char *remote_file; /* remote file name (often a device) */
char *remote_user; /* remote user name */
+#ifndef REMOTE_SHELL
+ /* We could use a more specific error message here (such as to recommend the
+ use of --rsh-command), but this one already has translations to languages
+ other than English. */
+ if (!remote_shell)
+ error (EXIT_ON_EXEC_ERROR, 0, "%s: %s",
+ file_name, _("Cannot execute remote shell"));
+#endif
+
/* Find an unused pair of file descriptors. */
for (remote_pipe_number = 0;
@@ -459,6 +468,7 @@ rmt_open__ (const char *file_name, int open_mode, int bias,
#ifdef REMOTE_SHELL
remote_shell = REMOTE_SHELL;
#else
+ /* "Can't happen" given the check at the beginning of this function. */
free (file_name_copy);
errno = EIO;
return -1;
@@ -491,12 +501,14 @@ rmt_open__ (const char *file_name, int open_mode, int bias,
/* Child. */
close (STDIN_FILENO);
- dup (to_remote[remote_pipe_number][PREAD]);
+ if (dup (to_remote[remote_pipe_number][PREAD]) != STDIN_FILENO)
+ error (EXIT_ON_EXEC_ERROR, errno, _("Cannot dup"));
close (to_remote[remote_pipe_number][PREAD]);
close (to_remote[remote_pipe_number][PWRITE]);
close (STDOUT_FILENO);
- dup (from_remote[remote_pipe_number][PWRITE]);
+ if (dup (from_remote[remote_pipe_number][PWRITE]) != STDOUT_FILENO)
+ error (EXIT_ON_EXEC_ERROR, errno, _("Cannot dup"));
close (from_remote[remote_pipe_number][PREAD]);
close (from_remote[remote_pipe_number][PWRITE]);
diff --git a/src/buffer.c b/src/buffer.c
index 8147def..d3bdaf8 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -1374,7 +1374,6 @@ static bool
check_label_pattern (const char *label)
{
char *string;
- bool result;
if (fnmatch (volume_label_option, label, 0) == 0)
return true;
@@ -1385,10 +1384,11 @@ check_label_pattern (const char *label)
string = drop_volume_label_suffix (label);
if (string)
{
- result = fnmatch (string, volume_label_option, 0) == 0;
+ bool result = fnmatch (string, volume_label_option, 0) == 0;
free (string);
+ return result;
}
- return result;
+ return false;
}
/* Check if the next block contains a volume label and if this matches
@@ -1841,6 +1841,7 @@ open_archive (enum access_mode wanted_access)
switch (wanted_access)
{
case ACCESS_READ:
+ case ACCESS_UPDATE:
if (volume_label_option)
match_volume_label ();
break;
@@ -1850,9 +1851,6 @@ open_archive (enum access_mode wanted_access)
if (volume_label_option)
write_volume_label ();
break;
-
- default:
- break;
}
set_volume_start_time ();
}
diff --git a/src/common.h b/src/common.h
index d2de528..8e7e255 100644
--- a/src/common.h
+++ b/src/common.h
@@ -835,7 +835,9 @@ void checkpoint_run (bool do_write);
/* The warnings composing WARN_VERBOSE_WARNINGS are enabled by default
in verbose mode */
-#define WARN_VERBOSE_WARNINGS (WARN_RENAME_DIRECTORY|WARN_NEW_DIRECTORY)
+#define WARN_VERBOSE_WARNINGS (WARN_ALONE_ZERO_BLOCK | \
+ WARN_RENAME_DIRECTORY | \
+ WARN_NEW_DIRECTORY)
#define WARN_ALL (0xffffffff & ~WARN_VERBOSE_WARNINGS)
void set_warning_option (const char *arg);
diff --git a/src/create.c b/src/create.c
index c69d340..355cedd 100644
--- a/src/create.c
+++ b/src/create.c
@@ -575,7 +575,12 @@ write_gnu_long_link (struct tar_stat_info *st, const char *p, char type)
GNAME_TO_CHARS (tmpname, header->header.gname);
free (tmpname);
- strcpy (header->header.magic, OLDGNU_MAGIC);
+ /* OLDGNU_MAGIC is string of 7 chars and trailing \0 */
+ strncpy (header->header.magic,
+ OLDGNU_MAGIC, sizeof(header->header.magic));
+ strncpy (header->header.version,
+ OLDGNU_MAGIC + sizeof(header->header.magic),
+ sizeof(header->header.version));
header->header.typeflag = type;
finish_header (st, header, -1);
@@ -910,9 +915,13 @@ start_header (struct tar_stat_info *st)
break;
case OLDGNU_FORMAT:
- case GNU_FORMAT: /*FIXME?*/
- /* Overwrite header->header.magic and header.version in one blow. */
- strcpy (header->header.magic, OLDGNU_MAGIC);
+ case GNU_FORMAT:
+ /* OLDGNU_MAGIC is string of 7 chars and trailing \0 */
+ strncpy (header->header.magic, OLDGNU_MAGIC,
+ sizeof(header->header.magic));
+ strncpy (header->header.version,
+ OLDGNU_MAGIC + sizeof(header->header.magic),
+ sizeof(header->header.version));
break;
case POSIX_FORMAT:
@@ -1554,6 +1563,19 @@ dump_file0 (struct tar_stat_info *st, const char *p,
return;
}
+ if (S_ISSOCK (st->stat.st_mode))
+ {
+ WARNOPT (WARN_FILE_IGNORED,
+ (0, 0, _("%s: socket ignored"), quotearg_colon (p)));
+ return;
+ }
+ else if (S_ISDOOR (st->stat.st_mode))
+ {
+ WARNOPT (WARN_FILE_IGNORED,
+ (0, 0, _("%s: door ignored"), quotearg_colon (p)));
+ return;
+ }
+
is_dir = S_ISDIR (st->stat.st_mode) != 0;
if (!is_dir && dump_hard_link (st))
@@ -1666,7 +1688,8 @@ dump_file0 (struct tar_stat_info *st, const char *p,
set_exit_status (TAREXIT_DIFFERS);
}
else if (atime_preserve_option == replace_atime_preserve
- && set_file_atime (fd, p, restore_times) != 0)
+ && set_file_atime (fd, p, restore_times) != 0
+ && errno != EROFS )
utime_error (p);
}
@@ -1725,18 +1748,6 @@ dump_file0 (struct tar_stat_info *st, const char *p,
type = BLKTYPE;
else if (S_ISFIFO (st->stat.st_mode))
type = FIFOTYPE;
- else if (S_ISSOCK (st->stat.st_mode))
- {
- WARNOPT (WARN_FILE_IGNORED,
- (0, 0, _("%s: socket ignored"), quotearg_colon (p)));
- return;
- }
- else if (S_ISDOOR (st->stat.st_mode))
- {
- WARNOPT (WARN_FILE_IGNORED,
- (0, 0, _("%s: door ignored"), quotearg_colon (p)));
- return;
- }
else
{
unknown_file_error (p);
diff --git a/src/extract.c b/src/extract.c
index 32a883f..8ac39dd 100644
--- a/src/extract.c
+++ b/src/extract.c
@@ -131,6 +131,33 @@ extr_init (void)
}
}
+static int
+fstat_or_stat (int fd, const char *name, struct stat *st)
+{
+ if (fd != -1)
+ return fstat (fd, st);
+ else
+ return stat (name, st);
+}
+
+static int
+fchown_or_chown (int fd, const char *name, uid_t uid, uid_t gid)
+{
+ if (fd != -1)
+ return fchown (fd, uid, gid);
+ else
+ return chown (name, uid, gid);
+}
+
+static int
+fchmod_or_chmod (int fd, const char *name, mode_t mode)
+{
+ if (fd != -1)
+ return fchmod (fd, mode);
+ else
+ return chmod(name, mode);
+}
+
/* If restoring permissions, restore the mode for FILE_NAME from
information given in *STAT_INFO (where *CUR_INFO gives
the current status if CUR_INFO is nonzero); otherwise invert the
@@ -138,7 +165,7 @@ extr_init (void)
PERMSTATUS specifies the status of the file's permissions.
TYPEFLAG specifies the type of the file. */
static void
-set_mode (char const *file_name,
+set_mode (int fd, char const *file_name,
struct stat const *stat_info,
struct stat const *cur_info,
mode_t invert_permissions, enum permstatus permstatus,
@@ -178,7 +205,7 @@ set_mode (char const *file_name,
struct stat st;
if (! cur_info)
{
- if (stat (file_name, &st) != 0)
+ if (fstat_or_stat (fd, file_name, &st) != 0)
{
stat_error (file_name);
return;
@@ -188,7 +215,7 @@ set_mode (char const *file_name,
mode = cur_info->st_mode ^ invert_permissions;
}
- failed = chmod (file_name, mode) != 0;
+ failed = fchmod_or_chmod (fd, file_name, mode) != 0;
if (failed && errno == EPERM)
{
/* On Solaris, chmod may fail if we don't have PRIV_ALL. */
@@ -247,7 +274,7 @@ check_time (char const *file_name, struct timespec t)
punt for the rest. Sigh! */
static void
-set_stat (char const *file_name,
+set_stat (int fd, char const *file_name,
struct tar_stat_info const *st,
struct stat const *cur_info,
mode_t invert_permissions, enum permstatus permstatus,
@@ -273,7 +300,7 @@ set_stat (char const *file_name,
ts[0] = start_time;
ts[1] = st->mtime;
- if (utimens (file_name, ts) != 0)
+ if (gl_futimens (fd, file_name, ts) != 0)
utime_error (file_name);
else
{
@@ -306,7 +333,8 @@ set_stat (char const *file_name,
}
else
{
- chown_result = chown (file_name, st->stat.st_uid, st->stat.st_gid);
+ chown_result = fchown_or_chown (fd, file_name, st->stat.st_uid,
+ st->stat.st_gid);
}
if (chown_result == 0)
@@ -324,7 +352,7 @@ set_stat (char const *file_name,
}
if (typeflag != SYMTYPE)
- set_mode (file_name, &st->stat, cur_info,
+ set_mode (fd, file_name, &st->stat, cur_info,
invert_permissions, permstatus, typeflag);
}
@@ -624,7 +652,7 @@ apply_nonancestor_delayed_set_stat (char const *file_name, bool after_links)
sb.stat.st_gid = data->gid;
sb.atime = data->atime;
sb.mtime = data->mtime;
- set_stat (data->file_name, &sb, cur_info,
+ set_stat (-1, data->file_name, &sb, cur_info,
data->invert_permissions, data->permstatus, DIRTYPE);
}
@@ -675,7 +703,7 @@ extract_dir (char *file_name, int typeflag)
|| old_files_option == OVERWRITE_OLD_FILES))
{
struct stat st;
- if (stat (file_name, &st) == 0)
+ if (lstat (file_name, &st) == 0)
{
if (interdir_made)
{
@@ -854,6 +882,12 @@ extract_file (char *file_name, int typeflag)
mv_end ();
+ if (!to_stdout_option && !to_command_option)
+ set_stat (fd, file_name, ¤t_stat_info, NULL, invert_permissions,
+ (old_files_option == OVERWRITE_OLD_FILES ?
+ UNKNOWN_PERMSTATUS : ARCHIVED_PERMSTATUS),
+ typeflag);
+
/* If writing to stdout, don't try to do anything to the filename;
it doesn't exist, or we don't want to touch it anyway. */
@@ -866,11 +900,6 @@ extract_file (char *file_name, int typeflag)
if (to_command_option)
sys_wait_command ();
- else
- set_stat (file_name, ¤t_stat_info, NULL, invert_permissions,
- (old_files_option == OVERWRITE_OLD_FILES ?
- UNKNOWN_PERMSTATUS : ARCHIVED_PERMSTATUS),
- typeflag);
return status;
}
@@ -1023,7 +1052,7 @@ extract_symlink (char *file_name, int typeflag)
break;
if (status == 0)
- set_stat (file_name, ¤t_stat_info, NULL, 0, 0, SYMTYPE);
+ set_stat (-1, file_name, ¤t_stat_info, NULL, 0, 0, SYMTYPE);
else
symlink_error (current_stat_info.link_name, file_name);
return status;
@@ -1060,7 +1089,7 @@ extract_node (char *file_name, int typeflag)
if (status != 0)
mknod_error (file_name);
else
- set_stat (file_name, ¤t_stat_info, NULL, invert_permissions,
+ set_stat (-1, file_name, ¤t_stat_info, NULL, invert_permissions,
ARCHIVED_PERMSTATUS, typeflag);
return status;
}
@@ -1081,7 +1110,7 @@ extract_fifo (char *file_name, int typeflag)
break;
if (status == 0)
- set_stat (file_name, ¤t_stat_info, NULL, invert_permissions,
+ set_stat (-1, file_name, ¤t_stat_info, NULL, invert_permissions,
ARCHIVED_PERMSTATUS, typeflag);
else
mkfifo_error (file_name);
@@ -1335,7 +1364,7 @@ apply_delayed_links (void)
struct tar_stat_info st1;
st1.stat.st_uid = ds->uid;
st1.stat.st_gid = ds->gid;
- set_stat (source, &st1, NULL, 0, 0, SYMTYPE);
+ set_stat (-1, source, &st1, NULL, 0, 0, SYMTYPE);
valid_source = source;
}
}
diff --git a/src/list.c b/src/list.c
index 716c0b4..0474fb1 100644
--- a/src/list.c
+++ b/src/list.c
@@ -1412,22 +1412,23 @@ test_archive_label ()
if (read_header (¤t_header, ¤t_stat_info, read_header_auto)
== HEADER_SUCCESS)
{
- char *s = NULL;
-
decode_header (current_header,
¤t_stat_info, ¤t_format, 0);
if (current_header->header.typeflag == GNUTYPE_VOLHDR)
assign_string (&volume_label, current_header->header.name);
-
- if (volume_label
- && (name_match (volume_label)
- || (multi_volume_option
- && (s = drop_volume_label_suffix (volume_label))
- && name_match (s))))
- if (verbose_option)
- print_volume_label ();
- free (s);
+
+ if (volume_label)
+ {
+ if (verbose_option)
+ print_volume_label ();
+ if (!name_match (volume_label) && multi_volume_option)
+ {
+ char *s = drop_volume_label_suffix (volume_label);
+ name_match (s);
+ free (s);
+ }
+ }
}
close_archive ();
- names_notfound ();
+ label_notfound ();
}
diff --git a/src/misc.c b/src/misc.c
index f81111f..ff7e4b2 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -25,7 +25,6 @@
#include <xgetcwd.h>
#include <unlinkdir.h>
#include <utimens.h>
-#include <canonicalize.h>
#if HAVE_STROPTS_H
# include <stropts.h>
@@ -34,6 +33,10 @@
# include <sys/filio.h>
#endif
+#ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT
+# define DOUBLE_SLASH_IS_DISTINCT_ROOT 0
+#endif
+
/* Handling strings. */
@@ -230,10 +233,99 @@ zap_slashes (char *name)
return name;
}
+/* Normalize NAME by resolving any relative references and
+ removing trailing slashes. Destructive version: modifies its argument. */
+int
+normalize_filename_x (char *name)
+{
+ char *p, *q;
+
+ p = name;
+ if (DOUBLE_SLASH_IS_DISTINCT_ROOT && ISSLASH (*p))
+ p++;
+
+ /* Remove /./, resolve /../ and compress sequences of slashes */
+ for (q = p; *q; )
+ {
+ if (ISSLASH (*q))
+ {
+ *p++ = *q++;
+ while (ISSLASH (*q))
+ q++;
+ continue;
+ }
+ else if (p == name)
+ {
+ if (*q == '.')
+ {
+ if (ISSLASH (q[1]))
+ {
+ q += 2;
+ continue;
+ }
+ if (q[1] == '.' && ISSLASH (q[2]))
+ return 1;
+ }
+ }
+ else
+ {
+ if (*q == '.' && ISSLASH (p[-1]))
+ {
+ if (ISSLASH (q[1]))
+ {
+ q += 2;
+ while (ISSLASH (*q))
+ q++;
+ continue;
+ }
+ else if (q[1] == '.' && ISSLASH (q[2]))
+ {
+ do
+ {
+ --p;
+ }
+ while (p > name && !ISSLASH (p[-1]));
+ q += 3;
+ continue;
+ }
+ }
+ }
+ *p++ = *q++;
+ }
+
+ /* Remove trailing slashes */
+ while (p - 1 > name && ISSLASH (p[-1]))
+ p--;
+
+ *p = 0;
+ return 0;
+}
+
+/* Normalize NAME by resolving any relative references, removing trailing
+ slashes, and converting it to absolute file name. Return the normalized
+ name, or NULL in case of error. */
+
char *
normalize_filename (const char *name)
{
- return zap_slashes (canonicalize_filename_mode (name, CAN_MISSING));
+ char *copy;
+
+ if (name[0] != '/')
+ {
+ copy = xgetcwd ();
+ copy = xrealloc (copy, strlen (copy) + strlen (name) + 2);
+
+ strcat (copy, "/");
+ strcat (copy, name);
+ }
+ else
+ copy = xstrdup (name);
+ if (normalize_filename_x (copy))
+ {
+ free (copy);
+ return NULL;
+ }
+ return xrealloc (copy, strlen (copy) + 1);
}
@@ -870,5 +962,3 @@ namebuf_name (namebuf_t buf, const char *name)
return buf->buffer;
}
-
-
diff --git a/src/names.c b/src/names.c
index 1146020..2beaf3e 100644
--- a/src/names.c
+++ b/src/names.c
@@ -589,7 +589,7 @@ all_names_found (struct tar_stat_info *p)
return true;
}
-static void
+static int
regex_usage_warning (const char *name)
{
static int warned_once = 0;
@@ -603,6 +603,7 @@ regex_usage_warning (const char *name)
_("Use --wildcards to enable pattern matching,"
" or --no-wildcards to suppress this warning")));
}
+ return warned_once;
}
/* Print the names of things in the namelist that were not matched. */
@@ -615,12 +616,11 @@ names_notfound (void)
if (!WASFOUND (cursor) && cursor->name[0])
{
regex_usage_warning (cursor->name);
- if (cursor->found_count == 0)
- ERROR ((0, 0, _("%s: Not found in archive"),
- quotearg_colon (cursor->name)));
- else
- ERROR ((0, 0, _("%s: Required occurrence not found in archive"),
- quotearg_colon (cursor->name)));
+ ERROR ((0, 0,
+ (cursor->found_count == 0) ?
+ _("%s: Not found in archive") :
+ _("%s: Required occurrence not found in archive"),
+ quotearg_colon (cursor->name)));
}
/* Don't bother freeing the name list; we're about to exit. */
@@ -639,6 +639,42 @@ names_notfound (void)
}
}
}
+
+void
+label_notfound (void)
+{
+ struct name const *cursor;
+
+ if (!namelist)
+ return;
+
+ for (cursor = namelist; cursor; cursor = cursor->next)
+ if (WASFOUND (cursor))
+ return;
+
+ if (verbose_option)
+ error (0, 0, _("Archive label mismatch"));
+ set_exit_status (TAREXIT_DIFFERS);
+
+ for (cursor = namelist; cursor; cursor = cursor->next)
+ {
+ if (regex_usage_warning (cursor->name))
+ break;
+ }
+
+ /* Don't bother freeing the name list; we're about to exit. */
+ namelist = NULL;
+ nametail = NULL;
+
+ if (same_order_option)
+ {
+ const char *name;
+
+ while ((name = name_next (1)) != NULL
+ && regex_usage_warning (name) == 0)
+ ;
+ }
+}
/* Sorting name lists. */
@@ -871,7 +907,7 @@ void
collect_and_sort_names (void)
{
struct name *name;
- struct name *next_name, *prev_name;
+ struct name *next_name, *prev_name = NULL;
int num_names;
struct stat statbuf;
Hash_table *nametab;
diff --git a/src/system.c b/src/system.c
index d646822..0adbb92 100644
--- a/src/system.c
+++ b/src/system.c
@@ -230,7 +230,25 @@ int
sys_truncate (int fd)
{
off_t pos = lseek (fd, (off_t) 0, SEEK_CUR);
- return pos < 0 ? -1 : ftruncate (fd, pos);
+
+ if (pos < 0)
+ return -1;
+
+ if (ftruncate (fd, pos) && errno == EPERM) {
+ /*
+ * ftruncate may fail to grow the size of a file with some OS and
+ * filesystem combinations. Linux and vfat/fat is one example.
+ * If this is the case do a write to grow the file to the desired length.
+ */
+ struct stat st;
+
+ if (fstat (fd, &st) ||
+ st.st_size >= pos ||
+ lseek (fd, pos - 1, SEEK_SET) == (off_t)-1 ||
+ write (fd, "\0", 1) != 1)
+ return -1;
+ }
+ return 0;
}
/* Return nonzero if NAME is the name of a regular file, or if the file
diff --git a/src/tar.c b/src/tar.c
index da12419..380da10 100644
--- a/src/tar.c
+++ b/src/tar.c
@@ -1254,7 +1254,7 @@ tar_help_filter (int key, const char *text, void *input)
{
struct obstack stk;
char *s;
-
+
switch (key)
{
default:
@@ -1286,19 +1286,23 @@ tar_help_filter (int key, const char *text, void *input)
break;
case ARGP_KEY_HELP_EXTRA:
- obstack_init (&stk);
- s = _("Valid arguments for the --quoting-style option are:");
- obstack_grow (&stk, s, strlen (s));
- obstack_grow (&stk, "\n\n", 2);
- tar_list_quoting_styles (&stk, " ");
- s = _("\n*This* tar defaults to:\n");
- obstack_grow (&stk, s, strlen (s));
- s = format_default_settings ();
- obstack_grow (&stk, s, strlen (s));
- obstack_1grow (&stk, '\n');
- obstack_1grow (&stk, 0);
- s = xstrdup (obstack_finish (&stk));
- obstack_free (&stk, NULL);
+ {
+ const char *tstr;
+
+ obstack_init (&stk);
+ tstr = _("Valid arguments for the --quoting-style option are:");
+ obstack_grow (&stk, tstr, strlen (tstr));
+ obstack_grow (&stk, "\n\n", 2);
+ tar_list_quoting_styles (&stk, " ");
+ tstr = _("\n*This* tar defaults to:\n");
+ obstack_grow (&stk, tstr, strlen (tstr));
+ s = format_default_settings ();
+ obstack_grow (&stk, s, strlen (s));
+ obstack_1grow (&stk, '\n');
+ obstack_1grow (&stk, 0);
+ s = xstrdup (obstack_finish (&stk));
+ obstack_free (&stk, NULL);
+ }
}
return s;
}
@@ -1463,7 +1467,11 @@ parse_opt (int key, char *arg, struct argp_state *state)
ignore_zeros_option = true;
break;
-
+
+ case 'y':
+ WARN ((0, 0, _("Warning: option '%c' is deprecated!"
+ " Next time use -j instead."), key));
+ /* Fall through to using bzip2. */
case 'j':
set_use_compress_program_option (BZIP2_PROGRAM);
break;
@@ -2566,8 +2574,6 @@ main (int argc, char **argv)
obstack_init (&argv_stk);
- /* Ensure default behavior for some signals */
- signal (SIGPIPE, SIG_IGN);
/* System V fork+wait does not work if SIGCHLD is ignored. */
signal (SIGCHLD, SIG_DFL);
diff --git a/src/xheader.c b/src/xheader.c
index b5c9869..04eca6f 100644
--- a/src/xheader.c
+++ b/src/xheader.c
@@ -261,7 +261,7 @@ xheader_format_name (struct tar_stat_info *st, const char *fmt, size_t n)
char *dir = NULL;
char *base = NULL;
char pidbuf[UINTMAX_STRSIZE_BOUND];
- char const *pptr;
+ char const *pptr = NULL;
char nbuf[UINTMAX_STRSIZE_BOUND];
char const *nptr = NULL;
@@ -1330,7 +1330,7 @@ sparse_map_decoder (struct tar_stat_info *st,
{
uintmax_t u;
char *delim;
- struct sp_array e;
+ struct sp_array e = {0, 0};
if (!ISDIGIT (*arg))
{
diff --git a/tests/Makefile.am b/tests/Makefile.am
index e9b753c..31811b0 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -89,6 +89,9 @@ TESTSUITE_AT = \
ignfail.at\
label01.at\
label02.at\
+ label03.at\
+ label04.at\
+ label05.at\
link01.at\
link02.at\
link03.at\
@@ -118,11 +121,13 @@ TESTSUITE_AT = \
rename05.at\
remfiles01.at\
remfiles02.at\
+ remfiles03.at\
same-order01.at\
same-order02.at\
shortfile.at\
shortupd.at\
shortrec.at\
+ sigpipe.at\
sparse01.at\
sparse02.at\
sparse03.at\
diff --git a/tests/extrac07.at b/tests/extrac07.at
index 1c45e97..bd301ab 100644
--- a/tests/extrac07.at
+++ b/tests/extrac07.at
@@ -52,7 +52,9 @@ Extract
dir/
dir/foo
],
-[],[],[ustar]) # Testing one format is enough
+[],[],[],[ustar]) # Testing one format is enough
+
+chmod +w ustar/out/dir
AT_CLEANUP
diff --git a/tests/genfile.c b/tests/genfile.c
index 7ebeddf..4e915a4 100644
--- a/tests/genfile.c
+++ b/tests/genfile.c
@@ -488,7 +488,8 @@ mkhole (int fd, off_t displ)
{
if (lseek (fd, displ, SEEK_CUR) == -1)
error (EXIT_FAILURE, errno, "lseek");
- ftruncate (fd, lseek (fd, 0, SEEK_CUR));
+ if (ftruncate (fd, lseek (fd, 0, SEEK_CUR)))
+ error (EXIT_FAILURE, errno, "ftruncate");
}
static void
@@ -686,13 +687,15 @@ exec_checkpoint (struct action *p)
error (0, errno, _("cannot open `%s'"), p->name);
break;
}
- ftruncate (fd, p->size);
+ if (ftruncate (fd, p->size))
+ error (0, errno, _("cannot truncate `%s'"), p->name);
close (fd);
}
break;
case OPT_EXEC:
- system (p->name);
+ if (system (p->name) == -1)
+ error (0, errno, _("cannot execute `%s'"), p->name);
break;
case OPT_UNLINK:
@@ -762,7 +765,8 @@ exec_command (void)
signal (SIGCHLD, SIG_DFL);
#endif
- pipe (fd);
+ if (pipe (fd))
+ error (EXIT_FAILURE, errno, "pipe");
pid = fork ();
if (pid == -1)
diff --git a/tests/label03.at b/tests/label03.at
new file mode 100644
index 0000000..71a422f
--- /dev/null
+++ b/tests/label03.at
@@ -0,0 +1,89 @@
+# 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/>.
+
+# Description: Test the functionality of the --test-label option.
+# In versions up to 1.23 it did not match the documentation. This
+# test case follows the examples from "9.7 Including a Label in the Archive".
+# References: <15929_1268069389_4B95340D_15929_35_1_D621E31C29598A43AF7B4BBD30CCDDFD0838294A@fr0-mailmb04.res.airbus.corp>
+#
+
+AT_SETUP([test-label option])
+AT_KEYWORDS([label label03 test-label])
+
+AT_TAR_CHECK([
+exec <&-
+genfile --file file
+tar -c --label='iamalabel' --file iamanarchive file
+tar -c --file unlabeled.tar file
+decho "# Display label"
+tar --test-label --file=iamanarchive; echo $?
+decho "# Display label: unlabeled"
+tar --test-label --file=unlabeled.tar; echo $?
+decho "# Test label: success"
+tar --test-label --file=iamanarchive 'iamalabel'; echo $?
+decho "# Test label: failure"
+tar --test-label --file=iamanarchive 'amalabel'; echo $?
+decho "# Test label: unlabeled"
+tar --test-label --file=unlabeled.tar 'amalabel'; echo $?
+decho "# Test label, verbose: success"
+tar --test-label --verbose --file=iamanarchive 'iamalabel'; echo $?
+decho "# Test label, verbose: failure"
+tar --test-label --verbose --file=iamanarchive 'amalabel'; echo $?
+decho "# Test label: multiple arguments"
+tar --test-label --file=iamanarchive a iamalabel b; echo $?
+decho "# Test label: wildcards"
+tar --test-label --file=iamanarchive --wildcards '*label'; echo $?
+],
+[0],
+[# Display label
+iamalabel
+0
+# Display label: unlabeled
+0
+# Test label: success
+0
+# Test label: failure
+1
+# Test label: unlabeled
+1
+# Test label, verbose: success
+iamalabel
+0
+# Test label, verbose: failure
+iamalabel
+1
+# Test label: multiple arguments
+0
+# Test label: wildcards
+0
+],
+[# Display label
+# Display label: unlabeled
+# Test label: success
+# Test label: failure
+# Test label: unlabeled
+# Test label, verbose: success
+# Test label, verbose: failure
+tar: Archive label mismatch
+# Test label: multiple arguments
+# Test label: wildcards
+],[],[],[gnu,oldgnu,posix])
+
+AT_CLEANUP
+
+
diff --git a/tests/label04.at b/tests/label04.at
new file mode 100644
index 0000000..e551502
--- /dev/null
+++ b/tests/label04.at
@@ -0,0 +1,53 @@
+# 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/>.
+
+# Description: Test the functionality of the --label option used in
+# conjunction with an operation, other than create. It was broken
+# in versions up to 1.23.
+# References: <15929_1268069389_4B95340D_15929_35_1_D621E31C29598A43AF7B4BBD30CCDDFD0838294A@fr0-mailmb04.res.airbus.corp>
+#
+
+AT_SETUP([label with non-create option])
+AT_KEYWORDS([label label04])
+
+AT_TAR_CHECK([
+exec <&-
+genfile --file file
+decho "# Create volume"
+tar -c -f archive --label='New volume' file
+decho "# Update: wrong label"
+tar -rf archive --label='My volume' file; echo $?
+decho "# Update: right label"
+tar -rf archive --label='New volume' file
+],
+[0],
+[# Create volume
+# Update: wrong label
+2
+# Update: right label
+],
+[# Create volume
+# Update: wrong label
+tar: Volume `New volume' does not match `My volume'
+tar: Error is not recoverable: exiting now
+# Update: right label
+],[],[],[gnu,oldgnu,posix])
+
+AT_CLEANUP
+
+
diff --git a/tests/label05.at b/tests/label05.at
new file mode 100644
index 0000000..5f8cffc
--- /dev/null
+++ b/tests/label05.at
@@ -0,0 +1,50 @@
+# 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/>.
+
+# Description: See label04. This testcase uses an unlabeled archive
+# volume.
+
+AT_SETUP([label with non-create option])
+AT_KEYWORDS([label label05])
+
+AT_TAR_CHECK([
+exec <&-
+genfile --file file
+decho "# Create volume"
+tar -c -f archive file
+decho "# Update: wrong label"
+tar -rf archive --label='My volume' file; echo $?
+decho "# Update: right label"
+tar -rf archive file
+],
+[0],
+[# Create volume
+# Update: wrong label
+2
+# Update: right label
+],
+[# Create volume
+# Update: wrong label
+tar: Archive not labeled to match `My volume'
+tar: Error is not recoverable: exiting now
+# Update: right label
+],[],[],[gnu,oldgnu,posix])
+
+AT_CLEANUP
+
+
diff --git a/tests/remfiles01.at b/tests/remfiles01.at
index 940fd95..86b5c03 100644
--- a/tests/remfiles01.at
+++ b/tests/remfiles01.at
@@ -30,6 +30,7 @@ AT_KEYWORDS([create remove-files remfiles01 gzip])
unset TAR_OPTIONS
AT_CHECK([
+AT_UNPRIVILEGED_PREREQ
AT_GZIP_PREREQ
AT_SORT_PREREQ
@@ -51,7 +52,9 @@ EC=$?
sed -n '/(child)/p' err >&2
rm err
find . | sort
-exit $EC
+# Gzip exit code is propagated to the shell. Usually it is
+# 141. We convert all non-zero exits to 2 to make it predictable.
+test $EC && exit 2
],
[2],
[.
diff --git a/tests/remfiles03.at b/tests/remfiles03.at
new file mode 100644
index 0000000..02104e9
--- /dev/null
+++ b/tests/remfiles03.at
@@ -0,0 +1,45 @@
+# Process this file with autom4te to create testsuite. -*- Autotest -*-
+
+# Test suite for GNU tar.
+# Copyright (C) 2009 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+
+# Description: Called with --remove-files, tar 1.23 failed
+# to remove a directory if it contained symlinks to another files
+# within that directory.
+# Reported-by: Alexander Kozlov <akozlov@nada.kth.se>
+# References: http://lists.gnu.org/archive/html/bug-tar/2010-03/msg00028.html
+# <Pine.SOC.4.64.1003150951060.28948@faun.nada.kth.se>
+
+AT_SETUP([remove-files with symbolic links])
+AT_KEYWORDS([create remove-files remfiles03])
+
+AT_CHECK([
+mkdir a
+mkdir a/b
+ln -s b a/c || AT_SKIP_TEST
+tar --remove-files -cf a.tar a
+genfile --stat a
+],
+[0],
+[],
+[genfile: stat(a) failed: No such file or directory
+])
+
+AT_CLEANUP
+
+
diff --git a/tests/sigpipe.at b/tests/sigpipe.at
new file mode 100644
index 0000000..9edca77
--- /dev/null
+++ b/tests/sigpipe.at
@@ -0,0 +1,39 @@
+# 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([sigpipe handling])
+AT_KEYWORDS([sigpipe])
+
+# Description: Tar 1.23 ignored sigpipe which lead to spurious "write
+# error" diagnostics when piping output to another programs.
+# Reported-by: "Dmitry V. Levin" <ldv@altlinux.org>
+# References: http://lists.gnu.org/archive/html/bug-tar/2010-03/msg00039.html
+# <20100319184141.GC30047@wo.int.altlinux.org>
+
+AT_CHECK([
+genfile --length 2048 --file first
+genfile --length 2048 --file second
+genfile --length 2049 --file third
+
+tar cf archive first second third
+
+tar tf archive | :
+],
+[0])
+
+AT_CLEANUP
diff --git a/tests/testsuite.at b/tests/testsuite.at
index f581071..9205d52 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -148,6 +148,9 @@ m4_include([extrac08.at])
m4_include([label01.at])
m4_include([label02.at])
+m4_include([label03.at])
+m4_include([label04.at])
+m4_include([label05.at])
m4_include([backup01.at])
@@ -226,6 +229,9 @@ m4_include([grow.at])
m4_include([remfiles01.at])
m4_include([remfiles02.at])
+m4_include([remfiles03.at])
+
+m4_include([sigpipe.at])
m4_include([star/gtarfail.at])
m4_include([star/gtarfail2.at])