md5sum, sha1sum, etc: accept new option: --strict
authorPatrick Schoenfeld <schoenfeld@debian.org>
Thu, 7 Jul 2011 06:57:39 +0000 (08:57 +0200)
committerJim Meyering <meyering@redhat.com>
Thu, 7 Jul 2011 14:42:47 +0000 (16:42 +0200)
Use this new option with --check when the input is expected to
consist solely of checksum lines.  With only --check, an invalid
line evokes a warning, but the program can still exit successfully.
With --strict, any invalid line makes the program exit non-zero.

* src/md5sum.c (strict, STRICT_OPTION): Declare/define.
(long_options): Add "strict".
(usage): Describe --strict.
(digest_check): Count improperly_formatted lines, too, and use
that number and the global "strict" to determine the return value.
(main): Handle STRICT_OPTION.
Reject --strict without --check.
* doc/coreutils.texi: Describe it.
* NEWS (New features): Mention it.

NEWS
doc/coreutils.texi
src/md5sum.c

diff --git a/NEWS b/NEWS
index f7e7823..32dab7a 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -29,6 +29,10 @@ GNU coreutils NEWS                                    -*- outline -*-
   Note the use of single quotes, not double quotes.
   That creates files named xaa.xz, xab.xz and xac.xz.
 
+  md5sum accepts the new --strict option.  With --check, it makes the
+  tool exit non-zero for any invalid input line, rather than just warning.
+  This also affects sha1sum, sha224sum, sha384sum and sha512sum.
+
 ** Improvements
 
   shuf outputs small subsets of large permutations much more efficiently.
index 11ac7fd..1ab8a92 100644 (file)
@@ -3702,6 +3702,13 @@ When verifying checksums, warn about improperly formatted MD5 checksum lines.
 This option is useful only if all but a few lines in the checked input
 are valid.
 
+@itemx --strict
+@opindex --strict
+@cindex verifying MD5 checksums
+When verifying checksums,
+if one or more input line is invalid,
+exit nonzero after all warnings have been issued.
+
 @end table
 
 @exitstatus
index 9bbdc60..ff9538a 100644 (file)
@@ -122,12 +122,17 @@ static bool warn = false;
 /* With --check, suppress the "OK" printed for each verified file.  */
 static bool quiet = false;
 
+/* With --check, exit with a non-zero return code if any line is
+   improperly formatted. */
+static bool strict = false;
+
 /* For long options that have no equivalent short option, use a
    non-character as a pseudo short option, starting with CHAR_MAX + 1.  */
 enum
 {
   STATUS_OPTION = CHAR_MAX + 1,
-  QUIET_OPTION
+  QUIET_OPTION,
+  STRICT_OPTION
 };
 
 static struct option const long_options[] =
@@ -138,6 +143,7 @@ static struct option const long_options[] =
   { "status", no_argument, NULL, STATUS_OPTION },
   { "text", no_argument, NULL, 't' },
   { "warn", no_argument, NULL, 'w' },
+  { "strict", no_argument, NULL, STRICT_OPTION },
   { GETOPT_HELP_OPTION_DECL },
   { GETOPT_VERSION_OPTION_DECL },
   { NULL, 0, NULL, 0 }
@@ -187,6 +193,9 @@ The following three options are useful only when verifying checksums:\n\
   -w, --warn           warn about improperly formatted checksum lines\n\
 \n\
 "), stdout);
+      fputs (_("\
+      --strict         with --check, exit non-zero for any invalid input\n\
+"), stdout);
       fputs (HELP_OPTION_DESCRIPTION, stdout);
       fputs (VERSION_OPTION_DESCRIPTION, stdout);
       printf (_("\
@@ -434,6 +443,7 @@ digest_check (const char *checkfile_name)
   FILE *checkfile_stream;
   uintmax_t n_misformatted_lines = 0;
   uintmax_t n_properly_formatted_lines = 0;
+  uintmax_t n_improperly_formatted_lines = 0;
   uintmax_t n_mismatched_checksums = 0;
   uintmax_t n_open_or_read_failures = 0;
   unsigned char bin_buffer_unaligned[DIGEST_BIN_BYTES + DIGEST_ALIGN];
@@ -501,6 +511,8 @@ digest_check (const char *checkfile_name)
                      checkfile_name, line_number,
                      DIGEST_TYPE_STRING);
             }
+
+          ++n_improperly_formatted_lines;
         }
       else
         {
@@ -603,7 +615,8 @@ digest_check (const char *checkfile_name)
 
   return (n_properly_formatted_lines != 0
           && n_mismatched_checksums == 0
-          && n_open_or_read_failures == 0);
+          && n_open_or_read_failures == 0
+          && (!strict || n_improperly_formatted_lines == 0));
 }
 
 int
@@ -657,6 +670,9 @@ main (int argc, char **argv)
         warn = false;
         quiet = true;
         break;
+      case STRICT_OPTION:
+        strict = true;
+        break;
       case_GETOPT_HELP_CHAR;
       case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
       default:
@@ -694,6 +710,13 @@ main (int argc, char **argv)
       usage (EXIT_FAILURE);
     }
 
+  if (strict & !do_check)
+   {
+     error (0, 0,
+        _("the --strict option is meaningful only when verifying checksums"));
+     usage (EXIT_FAILURE);
+   }
+
   if (!O_BINARY && binary < 0)
     binary = 0;