Bladeren bron

Fix `--test-label' and `--label -r' behavior.

* doc/tar.texi (Including a Label in the Archive): Revise
the section.
* NEWS: Update

* src/buffer.c (open_archive): Check volume label on
ACCESS_UPDATE as well.
* src/list.c (test_archive_label): Rewrite to match the
documentation.
* src/names.c (regex_usage_warning): Return int.
(names_notfound): Rewrite the conditional.
(label_notfound): New function.

* tests/label03.at: New testcase.
* tests/label04.at: New testcase.
* tests/label05.at: New testcase.
* tests/Makefile.am: Add new testcases.
* tests/testsuite.at: Likewise.
Sergey Poznyakoff 15 jaren geleden
bovenliggende
commit
0ba8bdf5f3
10 gewijzigde bestanden met toevoegingen van 329 en 47 verwijderingen
  1. 30 4
      NEWS
  2. 44 21
      doc/tar.texi
  3. 1 3
      src/buffer.c
  4. 13 12
      src/list.c
  5. 43 7
      src/names.c
  6. 3 0
      tests/Makefile.am
  7. 89 0
      tests/label03.at
  8. 53 0
      tests/label04.at
  9. 50 0
      tests/label05.at
  10. 3 0
      tests/testsuite.at

+ 30 - 4
NEWS

@@ -1,6 +1,32 @@
-GNU tar NEWS - User visible changes. 2010-03-10
+GNU tar NEWS - User visible changes. 2010-03-11
 Please send GNU tar bug reports to <[email protected]>
 Please send GNU tar bug reports to <[email protected]>
 
 
+
+
+* --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
 version 1.23 - Sergey Poznyakoff, 2010-03-10
 
 
@@ -694,7 +720,7 @@ tar.
 * New message translations fi (Finnish), gl (Galician), hr (Croatian),
 * New message translations fi (Finnish), gl (Galician), hr (Croatian),
   hu (Hungarian), ms (Malaysian), nb (Norwegian), ro (Romanian), sk
   hu (Hungarian), ms (Malaysian), nb (Norwegian), ro (Romanian), sk
   (Slovak), zh_CN (Chinese simplified), zh_TW (Chinese traditional).
   (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.
 * Bug fixes.
 
 
@@ -1019,7 +1045,7 @@ version 1.13 - Paul Eggert, 1999-07-08.
   but they have been removed to maintain compatibility with paxutils.
   but they have been removed to maintain compatibility with paxutils.
   Please try --use=bzip2 instead of --bzip2.
   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
 Sensitive matters
 * Use shell globbing patterns for --label, instead of regular expressions.
 * Use shell globbing patterns for --label, instead of regular expressions.
@@ -1062,7 +1088,7 @@ Various changes
 
 
 Many bugs are squashed, while others still run free.
 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.
 * Messages available in French, German, Portuguese and Swedish.
 * The distribution provides a rudimentary Texinfo manual.
 * The distribution provides a rudimentary Texinfo manual.

+ 44 - 21
doc/tar.texi

@@ -11355,15 +11355,16 @@ will usually see lots of spurious messages.
 @cindex Labeling an archive
 @cindex Labeling an archive
 @cindex Labels on the archive media
 @cindex Labels on the archive media
 @cindex Labeling multi-volume archives
 @cindex Labeling multi-volume archives
-@UNREVISED
 
 
 @opindex label
 @opindex label
   To avoid problems caused by misplaced paper labels on the archive
   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{--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
 @table @option
 @item --label=@var{archive-label}
 @item --label=@var{archive-label}
@@ -11402,7 +11403,7 @@ V--------- 0 0        0 1992-03-07 12:01 iamalabel--Volume Header--
   However, @option{--list} option will cause listing entire
   However, @option{--list} option will cause listing entire
 contents of the archive, which may be undesirable (for example, if the
 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
 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
 first block of an archive, so it can be used with slow storage
 devices.  For example:
 devices.  For example:
 
 
@@ -11413,16 +11414,35 @@ iamalabel
 @end group
 @end group
 @end smallexample
 @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 'iamalabel'}
+@result{} 0
+$ @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
 @smallexample
 @group
 @group
-$ @kbd{tar --test-label --file=iamanarchive 'iamalable'}
+$ @kbd{tar --test-label --verbose --file=iamanarchive 'iamalabel'}
+iamalabel
 @result{} 0
 @result{} 0
-$ @kbd{tar --test-label --file=iamanarchive 'iamalable' alabel}
+$ @kbd{tar --test-label --verbose --file=iamanarchive 'alabel'}
+iamalabel
+tar: Archive label mismatch
 @result{} 1
 @result{} 1
 @end group
 @end group
 @end smallexample
 @end smallexample
@@ -11462,9 +11482,6 @@ up.  Since the volume numbering is automatically added in labels at
 creation time, it sounded logical to equally help the user taking care
 creation time, it sounded logical to equally help the user taking care
 of it when the archive is being read.
 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
   You can also use @option{--label} to get a common information on
 all tapes of a series.  For having this information different in each
 all tapes of a series.  For having this information different in each
 series created through a single script used on a regular basis, just
 series created through a single script used on a regular basis, just
@@ -11478,13 +11495,19 @@ $ @kbd{tar --create --file=/dev/tape --multi-volume \
 @end group
 @end group
 @end smallexample
 @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
 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
 @node verify
 @section Verifying Data as It is Stored
 @section Verifying Data as It is Stored

+ 1 - 3
src/buffer.c

@@ -1841,6 +1841,7 @@ open_archive (enum access_mode wanted_access)
   switch (wanted_access)
   switch (wanted_access)
     {
     {
     case ACCESS_READ:
     case ACCESS_READ:
+    case ACCESS_UPDATE:
       if (volume_label_option)
       if (volume_label_option)
         match_volume_label ();
         match_volume_label ();
       break;
       break;
@@ -1850,9 +1851,6 @@ open_archive (enum access_mode wanted_access)
       if (volume_label_option)
       if (volume_label_option)
         write_volume_label ();
         write_volume_label ();
       break;
       break;
-
-    default:
-      break;
     }
     }
   set_volume_start_time ();
   set_volume_start_time ();
 }
 }

+ 13 - 12
src/list.c

@@ -1412,22 +1412,23 @@ test_archive_label ()
   if (read_header (&current_header, &current_stat_info, read_header_auto)
   if (read_header (&current_header, &current_stat_info, read_header_auto)
       == HEADER_SUCCESS)
       == HEADER_SUCCESS)
     {
     {
-      char *s = NULL;
-	
       decode_header (current_header,
       decode_header (current_header,
 		     &current_stat_info, &current_format, 0);
 		     &current_stat_info, &current_format, 0);
       if (current_header->header.typeflag == GNUTYPE_VOLHDR)
       if (current_header->header.typeflag == GNUTYPE_VOLHDR)
 	assign_string (&volume_label, current_header->header.name);
 	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 ();
   close_archive ();
-  names_notfound ();
+  label_notfound ();
 }
 }

+ 43 - 7
src/names.c

@@ -589,7 +589,7 @@ all_names_found (struct tar_stat_info *p)
   return true;
   return true;
 }
 }
 
 
-static void
+static int
 regex_usage_warning (const char *name)
 regex_usage_warning (const char *name)
 {
 {
   static int warned_once = 0;
   static int warned_once = 0;
@@ -603,6 +603,7 @@ regex_usage_warning (const char *name)
 	     _("Use --wildcards to enable pattern matching,"
 	     _("Use --wildcards to enable pattern matching,"
 	       " or --no-wildcards to suppress this warning")));
 	       " or --no-wildcards to suppress this warning")));
     }
     }
+  return warned_once;
 }
 }
 
 
 /* Print the names of things in the namelist that were not matched.  */
 /* 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])
     if (!WASFOUND (cursor) && cursor->name[0])
       {
       {
 	regex_usage_warning (cursor->name);
 	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.  */
   /* 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.  */
 /* Sorting name lists.  */
 
 

+ 3 - 0
tests/Makefile.am

@@ -89,6 +89,9 @@ TESTSUITE_AT = \
  ignfail.at\
  ignfail.at\
  label01.at\
  label01.at\
  label02.at\
  label02.at\
+ label03.at\
+ label04.at\
+ label05.at\
  link01.at\
  link01.at\
  link02.at\
  link02.at\
  link03.at\
  link03.at\

+ 89 - 0
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
+
+

+ 53 - 0
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
+
+

+ 50 - 0
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
+
+

+ 3 - 0
tests/testsuite.at

@@ -148,6 +148,9 @@ m4_include([extrac08.at])
 
 
 m4_include([label01.at])
 m4_include([label01.at])
 m4_include([label02.at])
 m4_include([label02.at])
+m4_include([label03.at])
+m4_include([label04.at])
+m4_include([label05.at])
 
 
 m4_include([backup01.at])
 m4_include([backup01.at])