md5sum, sha1sum, etc: accept new option: --strict

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.
This commit is contained in:
Patrick Schoenfeld 2011-07-07 08:57:39 +02:00 committed by Jim Meyering
parent 88bdce982a
commit 33171d049a
3 changed files with 36 additions and 2 deletions

4
NEWS
View File

@ -29,6 +29,10 @@ GNU coreutils NEWS -*- outline -*-
Note the use of single quotes, not double quotes. Note the use of single quotes, not double quotes.
That creates files named xaa.xz, xab.xz and xac.xz. 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 ** Improvements
shuf outputs small subsets of large permutations much more efficiently. shuf outputs small subsets of large permutations much more efficiently.

View 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 This option is useful only if all but a few lines in the checked input
are valid. 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 @end table
@exitstatus @exitstatus

View File

@ -122,12 +122,17 @@ static bool warn = false;
/* With --check, suppress the "OK" printed for each verified file. */ /* With --check, suppress the "OK" printed for each verified file. */
static bool quiet = false; 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 /* For long options that have no equivalent short option, use a
non-character as a pseudo short option, starting with CHAR_MAX + 1. */ non-character as a pseudo short option, starting with CHAR_MAX + 1. */
enum enum
{ {
STATUS_OPTION = CHAR_MAX + 1, STATUS_OPTION = CHAR_MAX + 1,
QUIET_OPTION QUIET_OPTION,
STRICT_OPTION
}; };
static struct option const long_options[] = static struct option const long_options[] =
@ -138,6 +143,7 @@ static struct option const long_options[] =
{ "status", no_argument, NULL, STATUS_OPTION }, { "status", no_argument, NULL, STATUS_OPTION },
{ "text", no_argument, NULL, 't' }, { "text", no_argument, NULL, 't' },
{ "warn", no_argument, NULL, 'w' }, { "warn", no_argument, NULL, 'w' },
{ "strict", no_argument, NULL, STRICT_OPTION },
{ GETOPT_HELP_OPTION_DECL }, { GETOPT_HELP_OPTION_DECL },
{ GETOPT_VERSION_OPTION_DECL }, { GETOPT_VERSION_OPTION_DECL },
{ NULL, 0, NULL, 0 } { NULL, 0, NULL, 0 }
@ -186,6 +192,9 @@ The following three options are useful only when verifying checksums:\n\
--status don't output anything, status code shows success\n\ --status don't output anything, status code shows success\n\
-w, --warn warn about improperly formatted checksum lines\n\ -w, --warn warn about improperly formatted checksum lines\n\
\n\ \n\
"), stdout);
fputs (_("\
--strict with --check, exit non-zero for any invalid input\n\
"), stdout); "), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout); fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout); fputs (VERSION_OPTION_DESCRIPTION, stdout);
@ -434,6 +443,7 @@ digest_check (const char *checkfile_name)
FILE *checkfile_stream; FILE *checkfile_stream;
uintmax_t n_misformatted_lines = 0; uintmax_t n_misformatted_lines = 0;
uintmax_t n_properly_formatted_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_mismatched_checksums = 0;
uintmax_t n_open_or_read_failures = 0; uintmax_t n_open_or_read_failures = 0;
unsigned char bin_buffer_unaligned[DIGEST_BIN_BYTES + DIGEST_ALIGN]; unsigned char bin_buffer_unaligned[DIGEST_BIN_BYTES + DIGEST_ALIGN];
@ -501,6 +511,8 @@ digest_check (const char *checkfile_name)
checkfile_name, line_number, checkfile_name, line_number,
DIGEST_TYPE_STRING); DIGEST_TYPE_STRING);
} }
++n_improperly_formatted_lines;
} }
else else
{ {
@ -603,7 +615,8 @@ digest_check (const char *checkfile_name)
return (n_properly_formatted_lines != 0 return (n_properly_formatted_lines != 0
&& n_mismatched_checksums == 0 && n_mismatched_checksums == 0
&& n_open_or_read_failures == 0); && n_open_or_read_failures == 0
&& (!strict || n_improperly_formatted_lines == 0));
} }
int int
@ -657,6 +670,9 @@ main (int argc, char **argv)
warn = false; warn = false;
quiet = true; quiet = true;
break; break;
case STRICT_OPTION:
strict = true;
break;
case_GETOPT_HELP_CHAR; case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default: default:
@ -694,6 +710,13 @@ main (int argc, char **argv)
usage (EXIT_FAILURE); 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) if (!O_BINARY && binary < 0)
binary = 0; binary = 0;