summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2011-11-26 15:41:43 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2011-11-26 15:50:40 +0200
commit7a5a3708cb8b33494cd6ac64bfe163f631a33edf (patch)
tree38e7e3bd4f1db04974712eb956e52ef40c0ec067
parent02bf3a96a931678211117534ee535863c780c6dc (diff)
downloadtar-7a5a3708cb8b33494cd6ac64bfe163f631a33edf.tar.gz
Fix --keep-old-files option.
The regression was introduced by 8f390db9. This patch implements additional option --skip-old-files, which silently skips members which would cause writing over existing files, and restores --keep-old-files to its traditional behavior. * NEWS: Update. * configure.ac: Update. * doc/tar.texi: Document the changes. * src/common.h (SKIP_OLD_FILES): New old_files mode. * src/extract.c (maybe_recoverable): Restore KEEP_OLD_FILES behavior. Handle SKIP_OLD_FILES. * src/tar.c: New option --skip-old-files. * tests/extrac18.at: New file. * tests/extrac19.at: New file. * tests/Makefile.am: Add new test cases. * tests/testsuite.at: Likewise.
-rw-r--r--NEWS19
-rw-r--r--configure.ac2
-rw-r--r--doc/tar.texi88
-rw-r--r--src/common.h1
-rw-r--r--src/extract.c5
-rw-r--r--src/tar.c13
-rw-r--r--tests/Makefile.am2
-rw-r--r--tests/extrac18.at60
-rw-r--r--tests/extrac19.at44
-rw-r--r--tests/testsuite.at2
10 files changed, 209 insertions, 27 deletions
diff --git a/NEWS b/NEWS
index 06955f4f..6226d070 100644
--- a/NEWS
+++ b/NEWS
@@ -1,8 +1,8 @@
-GNU tar NEWS - User visible changes. 2011-08-13
+GNU tar NEWS - User visible changes. 2011-11-26
Please send GNU tar bug reports to <bug-tar@gnu.org>
-version ?.? - ?, 201?-??-??
+version 1.26.90 (Git)
* New features
@@ -13,6 +13,21 @@ NAME:NUM, so that you can specify both symbolic name and numeric ID
for owner and group. In these options, NAME no longer needs to be
present in the current host's user and group databases.
+* The --keep-old-files and --skip-old-files options.
+
+This release restores the traditional functionality of the
+--keep-old-files. This option causes tar to avoid replacing
+existing files while extracting and to treat such files as errors.
+Tar will emit a prominent error message upon encountering such files
+and will exit with code 2 when finished extracting the archive.
+
+A new option --skip-old-files is introduced, which acts exactly as
+--keep-old-files, except that it does not treat existing files as
+errors. Instead it just silently skips them. An additional level of
+verbosity can be obtained by using the option --warning=existing-file
+together with this option.
+
+
version 1.26 - Sergey Poznyakoff, 2011-03-12
* Bugfixes
diff --git a/configure.ac b/configure.ac
index db69cb82..b4dc8719 100644
--- a/configure.ac
+++ b/configure.ac
@@ -19,7 +19,7 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
-AC_INIT([GNU tar], [1.26], [bug-tar@gnu.org])
+AC_INIT([GNU tar], [1.26.90], [bug-tar@gnu.org])
AC_CONFIG_SRCDIR([src/tar.c])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_HEADERS([config.h])
diff --git a/doc/tar.texi b/doc/tar.texi
index cf305926..1a28cb26 100644
--- a/doc/tar.texi
+++ b/doc/tar.texi
@@ -1877,6 +1877,7 @@ The other operations of @command{tar} (@option{--list},
@option{--extract}, @option{--compare}, and @option{--update})
will act on the entire contents of the archive.
+@anchor{exit status}
@cindex exit status
@cindex return status
Besides successful exits, @GNUTAR{} may fail for
@@ -2808,7 +2809,10 @@ when extracting files from an archive.
@item --keep-old-files
@itemx -k
-Do not overwrite existing files when extracting files from an archive.
+Do not overwrite existing files when extracting files from an
+archive. Return error if such files exist. See also
+@ref{--skip-old-files}.
+
@xref{Keep Old Files}.
@opsummary{label}
@@ -3261,6 +3265,20 @@ the archive creation operations it instructs @command{tar} to list the
member names stored in the archive, as opposed to the actual file
names. @xref{listing member and file names}.
+@opsummary{skip-old-files}
+@item --skip-old-files
+
+Do not overwrite existing files when extracting files from an
+archive. @xref{Keep Old Files}.
+
+This option differs from @option{--keep-old-files} in that it does not
+treat such files as an error, instead it just silently avoids
+overwriting them.
+
+The @option{--warning=existing-file} option can be used together with
+this option to produce warning messages about existing old files
+(@pxref{warnings}).
+
@opsummary{sparse}
@item --sparse
@itemx -S
@@ -4436,11 +4454,11 @@ in the archive; the most recently archived members will be extracted
last. Additionally, an extracted member will @emph{replace} a file of
the same name which existed in the directory already, and @command{tar}
will not prompt you about this@footnote{Unless you give it
-@option{--keep-old-files} option, or the disk copy is newer than
-the one in the archive and you invoke @command{tar} with
-@option{--keep-newer-files} option.}. Thus, only the most recently archived
-member will end up being extracted, as it will replace the one
-extracted before it, and so on.
+@option{--keep-old-files} (or @option{--skip-old-files}) option, or
+the disk copy is newer than the one in the archive and you invoke
+@command{tar} with @option{--keep-newer-files} option.}. Thus, only
+the most recently archived member will end up being extracted, as it
+will replace the one extracted before it, and so on.
@cindex extracting @var{n}th copy of the file
@xopindex{occurrence, described}
@@ -5131,10 +5149,25 @@ such a directory, use the @option{--no-overwrite-dir} option.
@cindex Overwriting old files, prevention
@xopindex{keep-old-files, introduced}
To be even more cautious and prevent existing files from being replaced, use
-the @option{--keep-old-files} (@option{-k}) option. It causes @command{tar} to refuse
-to replace or update a file that already exists, i.e., a file with the
-same name as an archive member prevents extraction of that archive
-member. Instead, it reports an error.
+the @option{--keep-old-files} (@option{-k}) option. It causes
+@command{tar} to refuse to replace or update a file that already
+exists, i.e., a file with the same name as an archive member prevents
+extraction of that archive member. Instead, it reports an error. For
+example:
+
+@example
+$ @kbd{ls}
+blues
+$ @kbd{tar -x -k -f archive.tar}
+tar: blues: Cannot open: File exists
+tar: Exiting with failure status due to previous errors
+@end example
+
+@xopindex{skip-old-files, introduced}
+If you wish to preserve old files untouched, but don't want
+@command{tar} to treat them as errors, use the
+@option{--skip-old-files} option. This option causes @command{tar} to
+silently skip extracting over existing files.
@xopindex{overwrite, introduced}
To be more aggressive about altering existing files, use the
@@ -5200,16 +5233,24 @@ archive, but remove other files before extracting.
@node Keep Old Files
@unnumberedsubsubsec Keep Old Files
+@GNUTAR{} provides two options to control its actions in a situation
+when it is about to extract a file which already exists on disk.
+
@table @option
@opindex keep-old-files
@item --keep-old-files
@itemx -k
-Do not replace existing files from archive. The
-@option{--keep-old-files} (@option{-k}) option prevents @command{tar}
-from replacing existing files with files with the same name from the
-archive. The @option{--keep-old-files} option is meaningless with
-@option{--list} (@option{-t}). Prevents @command{tar} from replacing
-files in the file system during extraction.
+Do not replace existing files from archive. When such a file is
+encountered, @command{tar} issues an error message. Upon end of
+extraction, @command{tar} exits with code 2 (@pxref{exit status}).
+
+@item --skip-old-files
+Do not replace existing files from archive, but do not treat that
+as error. Such files are silently skipped and do not affect
+@command{tar} exit status.
+
+Additional verbosity can be obtained using @option{--warning=existing-file}
+together with that option (@pxref{warnings}).
@end table
@node Keep Newer Files
@@ -11937,11 +11978,16 @@ lets the archive overwrite any file in your system that you can write,
the @option{--absolute-names} (@option{-P}) option should be used only
for trusted archives.
-Conversely, with the @option{--keep-old-files} (@option{-k}) option,
-@command{tar} refuses to replace existing files when extracting; and
-with the @option{--no-overwrite-dir} option, @command{tar} refuses to
-replace the permissions or ownership of already-existing directories.
-These options may help when extracting from untrusted archives.
+Conversely, with the @option{--keep-old-files} (@option{-k}) and
+@option{--skip-old-files} options, @command{tar} refuses to replace
+existing files when extracting. The difference between the two
+options is that the former treats existing files as errors whereas the
+latter just silently ignores them.
+
+Finally, with the @option{--no-overwrite-dir} option, @command{tar}
+refuses to replace the permissions or ownership of already-existing
+directories. These options may help when extracting from untrusted
+archives.
@node Live untrusted data
@subsection Dealing with Live Untrusted Data
diff --git a/src/common.h b/src/common.h
index b60c4a07..1429b22d 100644
--- a/src/common.h
+++ b/src/common.h
@@ -183,6 +183,7 @@ enum old_files
OVERWRITE_OLD_FILES, /* --overwrite */
UNLINK_FIRST_OLD_FILES, /* --unlink-first */
KEEP_OLD_FILES, /* --keep-old-files */
+ SKIP_OLD_FILES, /* --skip-old-files */
KEEP_NEWER_FILES /* --keep-newer-files */
};
GLOBAL enum old_files old_files_option;
diff --git a/src/extract.c b/src/extract.c
index 60ec747f..6c384927 100644
--- a/src/extract.c
+++ b/src/extract.c
@@ -642,11 +642,14 @@ maybe_recoverable (char *file_name, bool regular, bool *interdir_made)
switch (old_files_option)
{
- case KEEP_OLD_FILES:
+ case SKIP_OLD_FILES:
WARNOPT (WARN_EXISTING_FILE,
(0, 0, _("%s: skipping existing file"), file_name));
return RECOVER_SKIP;
+ case KEEP_OLD_FILES:
+ return RECOVER_NO;
+
case KEEP_NEWER_FILES:
if (file_newer_p (file_name, stp, &current_stat_info))
break;
diff --git a/src/tar.c b/src/tar.c
index f0d8f5bf..21d99107 100644
--- a/src/tar.c
+++ b/src/tar.c
@@ -328,6 +328,7 @@ enum
SHOW_DEFAULTS_OPTION,
SHOW_OMITTED_DIRS_OPTION,
SHOW_TRANSFORMED_NAMES_OPTION,
+ SKIP_OLD_FILES_OPTION,
SPARSE_VERSION_OPTION,
STRIP_COMPONENTS_OPTION,
SUFFIX_OPTION,
@@ -452,7 +453,11 @@ static struct argp_option options[] = {
{"remove-files", REMOVE_FILES_OPTION, 0, 0,
N_("remove files after adding them to the archive"), GRID+1 },
{"keep-old-files", 'k', 0, 0,
- N_("don't replace existing files when extracting"), GRID+1 },
+ N_("don't replace existing files when extracting, "
+ "treat them as errors"), GRID+1 },
+ {"skip-old-files", SKIP_OLD_FILES_OPTION, 0, 0,
+ N_("don't replace existing files when extracting, silently skip over them"),
+ GRID+1 },
{"keep-newer-files", KEEP_NEWER_FILES_OPTION, 0, 0,
N_("don't replace existing files that are newer than their archive copies"), GRID+1 },
{"overwrite", OVERWRITE_OPTION, 0, 0,
@@ -1544,7 +1549,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
/* Don't replace existing files. */
old_files_option = KEEP_OLD_FILES;
break;
-
+
case 'K':
starting_file_option = true;
addname (arg, 0, true, NULL);
@@ -1674,6 +1679,10 @@ parse_opt (int key, char *arg, struct argp_state *state)
sparse_option = true;
break;
+ case SKIP_OLD_FILES_OPTION:
+ old_files_option = SKIP_OLD_FILES;
+ break;
+
case SPARSE_VERSION_OPTION:
sparse_option = true;
{
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 7acc9d6d..4601e0eb 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -86,6 +86,8 @@ TESTSUITE_AT = \
extrac15.at\
extrac16.at\
extrac17.at\
+ extrac18.at\
+ extrac19.at\
filerem01.at\
filerem02.at\
gzip.at\
diff --git a/tests/extrac18.at b/tests/extrac18.at
new file mode 100644
index 00000000..8b42ef7e
--- /dev/null
+++ b/tests/extrac18.at
@@ -0,0 +1,60 @@
+# Process this file with autom4te to create testsuite. -*- Autotest -*-
+#
+# Test suite for GNU tar.
+# Copyright (C) 2011 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: Check the functionality of the --keep-old-files option.
+# It should report an error and cause tar to exit with status 2.
+#
+# There was a regression in versions 1.23 to 1.26 inclusive, where
+# this option silently skipped such files.
+# Reported by: Doug McLaren <dougmc@frenzied.us>,
+# Gary Partis <gary@partis.co.uk>,
+# Jim Meyering <jim@meyering.net>
+#
+# References: <20111117045433.GA8245@algol.frenzied.us>,
+# <4F3D824717847C4487F77228F83329A3514CBB@server.Partis.local>,
+# <87wrar6zzz.fsf@rho.meyering.net>
+
+AT_SETUP([keep-old-files])
+AT_KEYWORDS([extract extrac18 old-files keep-old-files])
+
+AT_TAR_CHECK([
+mkdir dir
+cd dir
+echo 'Old file a' > a
+echo 'Old file b' > b
+
+tar cf ../archive .
+
+rm b
+echo 'File a' > a
+
+tar -x -k -f ../archive
+echo status=$?
+
+cat a
+],
+[0],
+[status=2
+File a
+],
+[tar: ./a: Cannot open: File exists
+tar: Exiting with failure status due to previous errors
+])
+
+AT_CLEANUP
+
diff --git a/tests/extrac19.at b/tests/extrac19.at
new file mode 100644
index 00000000..43c4c507
--- /dev/null
+++ b/tests/extrac19.at
@@ -0,0 +1,44 @@
+# Process this file with autom4te to create testsuite. -*- Autotest -*-
+#
+# Test suite for GNU tar.
+# Copyright (C) 2011 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([skip-old-files])
+AT_KEYWORDS([extract extrac19 old-files skip-old-files])
+
+AT_TAR_CHECK([
+mkdir dir
+cd dir
+echo 'Old file a' > a
+echo 'Old file b' > b
+
+tar cf ../archive .
+
+rm b
+echo 'File a' > a
+
+tar -x --skip-old-files -f ../archive
+echo status=$?
+
+cat a
+],
+[0],
+[status=0
+File a
+])
+
+AT_CLEANUP
+
diff --git a/tests/testsuite.at b/tests/testsuite.at
index 35f8c2f7..97f5e412 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -166,6 +166,8 @@ m4_include([extrac14.at])
m4_include([extrac15.at])
m4_include([extrac16.at])
m4_include([extrac17.at])
+m4_include([extrac18.at])
+m4_include([extrac19.at])
m4_include([label01.at])
m4_include([label02.at])