]> Dogcows Code - chaz/tar/commitdiff
Fix --keep-old-files option.
authorSergey Poznyakoff <gray@gnu.org.ua>
Sat, 26 Nov 2011 13:41:43 +0000 (15:41 +0200)
committerSergey Poznyakoff <gray@gnu.org.ua>
Sat, 26 Nov 2011 13:50:40 +0000 (15:50 +0200)
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.

NEWS
configure.ac
doc/tar.texi
src/common.h
src/extract.c
src/tar.c
tests/Makefile.am
tests/extrac18.at [new file with mode: 0644]
tests/extrac19.at [new file with mode: 0644]
tests/testsuite.at

diff --git a/NEWS b/NEWS
index 06955f4f8e2d3f270320f0772f1813c6405e2b4e..6226d070e1e2951bd297ce9071caf4a681f4819a 100644 (file)
--- 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>
 
 \f
-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.
+
+\f
 version 1.26 - Sergey Poznyakoff, 2011-03-12
 
 * Bugfixes
index db69cb82b378da8b9f6437bc6b8b35ab9b3ba970..b4dc8719d092c2edf53d330bcf682da8f651786b 100644 (file)
@@ -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])
index cf305926d842518614c00892046a88d99951f0e7..1a28cb26c62612b0626d381c2ae9a54a22050128 100644 (file)
@@ -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
index b60c4a0730c45f53c16da92a92fe49bbcc7e9158..1429b22de033fa09e193634c6d47bc0c653e933d 100644 (file)
@@ -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;
index 60ec747f72a9e94d192ab30a31e4da91adf4f1a3..6c3849274e1281e72f9334e5a6e4f288e5f33022 100644 (file)
@@ -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;
index f0d8f5bfd06643430815e94abf8bd939e04029ed..21d9910712ed8aea12f2bef2ea4a984e019a6f74 100644 (file)
--- 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;
       {
index 7acc9d6dd4e02c9b1793d5709067b514b178d482..4601e0ebb9ace1383b83a84857e6ac9fb1777a6b 100644 (file)
@@ -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 (file)
index 0000000..8b42ef7
--- /dev/null
@@ -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 (file)
index 0000000..43c4c50
--- /dev/null
@@ -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
+
index 35f8c2f707a2ab2dea7c092539ffa56fef3f24d1..97f5e4120b74726df82b09b97a9c07deedb20acf 100644 (file)
@@ -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])
This page took 0.04605 seconds and 4 git commands to generate.