[tar/f18] Restore standard behavior of --keep-old-files

Pavel Raiskup praiskup at fedoraproject.org
Thu Oct 18 11:19:51 UTC 2012


commit 1640ed0ae0bcccfcd642314d893e16dd726d78e4
Author: Pavel Raiskup <praiskup at redhat.com>
Date:   Thu Oct 18 13:17:08 2012 +0200

    Restore standard behavior of --keep-old-files
    
    - and add --skip-old-files option
    
      Resolves: #799252

 tar-1.26-add-skip-old-files-option.patch |  403 ++++++++++++++++++++++++++++++
 tar.spec                                 |    9 +-
 2 files changed, 411 insertions(+), 1 deletions(-)
---
diff --git a/tar-1.26-add-skip-old-files-option.patch b/tar-1.26-add-skip-old-files-option.patch
new file mode 100644
index 0000000..da72c44
--- /dev/null
+++ b/tar-1.26-add-skip-old-files-option.patch
@@ -0,0 +1,403 @@
+From d839cf02caafbefec027a04632778a668e4eaba8 Mon Sep 17 00:00:00 2001
+From: Pavel Raiskup <praiskup at redhat.com>
+Date: Thu, 18 Oct 2012 11:42:05 +0200
+Subject: [PATCH] Add --skip-old-files option and restore traditional behavior
+ of --keep-old-files
+
+---
+ doc/tar.texi       | 76 ++++++++++++++++++++++++++++++++++++++++++------------
+ src/common.h       |  4 ++-
+ src/extract.c      |  7 ++++-
+ src/tar.c          | 11 +++++++-
+ src/warning.c      |  4 ++-
+ tests/Makefile.am  |  2 ++
+ tests/extrac18.at  | 60 ++++++++++++++++++++++++++++++++++++++++++
+ tests/extrac19.at  | 44 +++++++++++++++++++++++++++++++
+ tests/testsuite.at |  3 +++
+ 9 files changed, 190 insertions(+), 21 deletions(-)
+ create mode 100644 tests/extrac18.at
+ create mode 100644 tests/extrac19.at
+
+diff --git a/doc/tar.texi b/doc/tar.texi
+index a41912a..5652a11 100644
+--- a/doc/tar.texi
++++ b/doc/tar.texi
+@@ -37,7 +37,8 @@ This manual is for @acronym{GNU} @command{tar} (version
+ from archives.
+ 
+ Copyright @copyright{} 1992, 1994, 1995, 1996, 1997, 1999, 2000, 2001,
+-2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
++2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software
++Foundation, Inc.
+ 
+ @quotation
+ Permission is granted to copy, distribute and/or modify this document
+@@ -1881,6 +1882,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.
+ 
++ at anchor{exit status}
+ @cindex exit status
+ @cindex return status
+ Besides successful exits, @GNUTAR{} may fail for
+@@ -2819,7 +2821,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
++ at ref{--skip-old-files}.
++
+ @xref{Keep Old Files}.
+ 
+ @opsummary{label}
+@@ -3291,6 +3296,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}.
+ 
++ at opsummary{skip-old-files}
++ at 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
+@@ -4471,11 +4490,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 at footnote{Unless you give it
+- at option{--keep-old-files} option, or the disk copy is newer than
+-the one in the archive and you invoke @command{tar} with
+- at 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.
++ at 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
++ at 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}
+@@ -5151,10 +5170,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
++ at 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:
++
++ at 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
++ at end example
++
++ at xopindex{skip-old-files, introduced}
++If you wish to preserve old files untouched, but don't want
++ at command{tar} to treat them as errors, use the
++ at 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
+@@ -5220,16 +5254,24 @@ archive, but remove other files before extracting.
+ @node Keep Old Files
+ @unnumberedsubsubsec Keep Old Files
+ 
++ at 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
+- at 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
+- at 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}).
++
++ at 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
++ at 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
+diff --git a/src/common.h b/src/common.h
+index 439bf42..502393f 100644
+--- a/src/common.h
++++ b/src/common.h
+@@ -182,6 +182,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;
+@@ -825,11 +826,12 @@ void checkpoint_run (bool do_write);
+ #define WARN_UNKNOWN_KEYWORD     0x00020000
+ #define WARN_XDEV                0x00040000
+ #define WARN_DECOMPRESS_PROGRAM  0x00080000
++#define WARN_EXISTING_FILE       0x00100000
+ 
+ /* The warnings composing WARN_VERBOSE_WARNINGS are enabled by default
+    in verbose mode */
+ #define WARN_VERBOSE_WARNINGS    (WARN_RENAME_DIRECTORY|WARN_NEW_DIRECTORY|\
+-				  WARN_DECOMPRESS_PROGRAM)
++				  WARN_DECOMPRESS_PROGRAM|WARN_EXISTING_FILE)
+ #define WARN_ALL                 (~WARN_VERBOSE_WARNINGS)
+ 
+ void set_warning_option (const char *arg);
+diff --git a/src/extract.c b/src/extract.c
+index 063895d..501824d 100644
+--- a/src/extract.c
++++ b/src/extract.c
+@@ -695,9 +695,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 0669a01..ba97abe 100644
+--- a/src/tar.c
++++ b/src/tar.c
+@@ -333,6 +333,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,
+@@ -458,7 +459,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,
+@@ -1636,6 +1641,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/src/warning.c b/src/warning.c
+index 5d1bcab..102364d 100644
+--- a/src/warning.c
++++ b/src/warning.c
+@@ -42,6 +42,7 @@ static char const *const warning_args[] = {
+   "unknown-keyword",
+   "xdev",
+   "decompress-program",
++  "existing-file",
+   NULL
+ };
+ 
+@@ -66,7 +67,8 @@ static int warning_types[] = {
+   WARN_UNKNOWN_CAST,
+   WARN_UNKNOWN_KEYWORD,
+   WARN_XDEV,
+-  WARN_DECOMPRESS_PROGRAM
++  WARN_DECOMPRESS_PROGRAM,
++  WARN_EXISTING_FILE
+ };
+ 
+ ARGMATCH_VERIFY (warning_args, warning_types);
+diff --git a/tests/Makefile.am b/tests/Makefile.am
+index 119f1f3..3d78ea2 100644
+--- a/tests/Makefile.am
++++ b/tests/Makefile.am
+@@ -77,6 +77,8 @@ TESTSUITE_AT = \
+  extrac07.at\
+  extrac08.at\
+  extrac09.at\
++ extrac18.at\
++ extrac19.at\
+  extrac10.at\
+  extrac11.at\
+  extrac12.at\
+diff --git a/tests/extrac18.at b/tests/extrac18.at
+new file mode 100644
+index 0000000..8b42ef7
+--- /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 at frenzied.us>,
++#              Gary Partis <gary at partis.co.uk>,
++#              Jim Meyering <jim at meyering.net>
++#              
++# References: <20111117045433.GA8245 at algol.frenzied.us>,
++#             <4F3D824717847C4487F77228F83329A3514CBB at server.Partis.local>,
++#             <87wrar6zzz.fsf at 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 0000000..43c4c50
+--- /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 13f7506..2fd755c 100644
+--- a/tests/testsuite.at
++++ b/tests/testsuite.at
+@@ -166,6 +166,9 @@ 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])
+ m4_include([label03.at])
+-- 
+1.7.11.7
+
diff --git a/tar.spec b/tar.spec
index 3fc66e8..3d500b5 100644
--- a/tar.spec
+++ b/tar.spec
@@ -5,7 +5,7 @@ Summary: A GNU file archiving program
 Name: tar
 Epoch: 2
 Version: 1.26
-Release: 10%{?dist}
+Release: 11%{?dist}
 License: GPLv3+
 Group: Applications/Archiving
 URL: http://www.gnu.org/software/tar/
@@ -36,6 +36,8 @@ Patch8: tar-1.24-openat-partial-revert.patch
 Patch9: tar-1.26-update-with-change-directory.patch
 # fix rawhide buildfailure with undefined gets
 Patch10: tar-1.26-stdio.in.patch
+# fix regression with --keep-old-files option (#799252)
+Patch11: tar-1.26-add-skip-old-files-option.patch
 BuildRequires: autoconf automake gzip texinfo gettext libacl-devel gawk rsh
 %if %{WITH_SELINUX}
 BuildRequires: libselinux-devel
@@ -69,6 +71,7 @@ the rmt package.
 %patch8 -p1 -b .openat
 %patch9 -p1 -b .update_and_changedir
 %patch10 -p1 -b .gets  %{?_rawbuild}
+%patch11 -p1 -b .skip-old-files
 
 autoreconf
 
@@ -130,6 +133,10 @@ fi
 %{_infodir}/tar.info*
 
 %changelog
+* Thu Oct 18 2012 Pavel Raiskup <praiskup at redhat.com> - 2:1.26-11
+- fix bad behaviour of --keep-old-files and add --skip-old-files option
+  (#799252)
+
 * Wed Oct 10 2012 Pavel Raiskup <praiskup at redhat.com> 2:1.26-10
 - allow to build tar in difference CoverityScan by forcing the '.gets' patch to
   be applied even in the run without patches


More information about the scm-commits mailing list