From: Sergey Poznyakoff Date: Thu, 11 Mar 2010 15:41:23 +0000 (+0200) Subject: Fix `--test-label' and `--label -r' behavior. X-Git-Url: https://git.brokenzipper.com/gitweb?a=commitdiff_plain;h=0ba8bdf5f3401fdc8c1595857ab69f6c65e04353;p=chaz%2Ftar 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. --- diff --git a/NEWS b/NEWS index 3254266..f53f8a9 100644 --- a/NEWS +++ b/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 + + +* --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 @@ -694,7 +720,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 +1045,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 +1088,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/doc/tar.texi b/doc/tar.texi index 5ced6d1..9bca1ef 100644 --- a/doc/tar.texi +++ b/doc/tar.texi @@ -11355,15 +11355,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} @@ -11402,7 +11403,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: @@ -11413,16 +11414,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 '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 @group -$ @kbd{tar --test-label --file=iamanarchive 'iamalable'} +$ @kbd{tar --test-label --verbose --file=iamanarchive 'iamalabel'} +iamalabel @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 @end group @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 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 @@ -11478,13 +11495,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 diff --git a/src/buffer.c b/src/buffer.c index 8147def..8e1bb9b 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -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/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/names.c b/src/names.c index ea2ce76..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. */ diff --git a/tests/Makefile.am b/tests/Makefile.am index e9b753c..f546f40 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\ 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 . + +# 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 . + +# 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 . + +# 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/testsuite.at b/tests/testsuite.at index f581071..fc96479 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])