improperly formatted checksum line. */
static bool warn = false;
+/* With --check, ignore missing files. */
+static bool ignore_missing = false;
+
/* With --check, suppress the "OK" printed for each verified file. */
static bool quiet = false;
non-character as a pseudo short option, starting with CHAR_MAX + 1. */
enum
{
- STATUS_OPTION = CHAR_MAX + 1,
+ IGNORE_MISSING_OPTION = CHAR_MAX + 1,
+ STATUS_OPTION,
QUIET_OPTION,
STRICT_OPTION,
TAG_OPTION
{
{ "binary", no_argument, NULL, 'b' },
{ "check", no_argument, NULL, 'c' },
+ { "ignore-missing", no_argument, NULL, IGNORE_MISSING_OPTION},
{ "quiet", no_argument, NULL, QUIET_OPTION },
{ "status", no_argument, NULL, STATUS_OPTION },
{ "text", no_argument, NULL, 't' },
"), stdout);
fputs (_("\
\n\
-The following four options are useful only when verifying checksums:\n\
+The following five options are useful only when verifying checksums:\n\
+ --ignore-missing don't fail or report status for missing files\n\
--quiet don't print OK for each successfully verified file\n\
--status don't output anything, status code shows success\n\
--strict exit non-zero for improperly formatted checksum lines\n\
fp = fopen (filename, (O_BINARY && *binary ? "rb" : "r"));
if (fp == NULL)
{
+ if (ignore_missing && errno == ENOENT)
+ {
+ *bin_result = '\0';
+ return true;
+ }
error (0, errno, "%s", quotef (filename));
return false;
}
++n_properly_formatted_lines;
+ *bin_buffer = '\1'; /* flag set to 0 for ignored missing files. */
ok = digest_file (filename, &binary, bin_buffer);
if (!ok)
printf (": %s\n", _("FAILED open or read"));
}
}
+ else if (ignore_missing && ! *bin_buffer)
+ {
+ /* Treat an empty buffer as meaning a missing file,
+ which is ignored with --ignore-missing. */
+ ;
+ }
else
{
size_t digest_bin_bytes = digest_hex_bytes / 2;
size_t cnt;
+
/* Compare generated binary number with text representation
in check file. Ignore case of hex digits. */
for (cnt = 0; cnt < digest_bin_bytes; ++cnt)
warn = true;
quiet = false;
break;
+ case IGNORE_MISSING_OPTION:
+ ignore_missing = true;
+ break;
case QUIET_OPTION:
status_only = false;
warn = false;
usage (EXIT_FAILURE);
}
+ if (ignore_missing && !do_check)
+ {
+ error (0, 0,
+ _("the --ignore-missing option is meaningful only when "
+ "verifying checksums"));
+ usage (EXIT_FAILURE);
+ }
+
if (status_only && !do_check)
{
error (0, 0,
my $degenerate = "d41d8cd98f00b204e9800998ecf8427e";
+my $try_help = "Try 'md5sum --help' for more information.\n";
+
my @Tests =
(
['1', {IN=> {f=> ''}}, {OUT=>"$degenerate f\n"}],
['check-openssl3', '--check', '--status',
{IN=> {'f.md5' => "MD5(f)= $degenerate\n"}},
{AUX=> {f=> 'bar'}}, {EXIT=> 1}],
+ ['check-ignore-missing-1', '--check', '--ignore-missing',
+ {AUX=> {f=> ''}},
+ {IN=> {'f.md5' => "$degenerate f\n".
+ "$degenerate f.missing\n"}},
+ {OUT=>"f: OK\n"}],
+ ['check-ignore-missing-2', '--check', '--ignore-missing',
+ {AUX=> {f=> ''}},
+ {IN=> {'f.md5' => "$degenerate f\n".
+ "$degenerate f.missing\n"}},
+ {OUT=>"f: OK\n"}],
+ ['check-ignore-missing-3', '--check', '--quiet', '--ignore-missing',
+ {AUX=> {f=> ''}},
+ {IN=> {'f.md5' => "$degenerate missing/f\n".
+ "$degenerate f\n"}},
+ {OUT=>""}],
+ ['check-ignore-missing-4', '--ignore-missing',
+ {IN=> {f=> ''}},
+ {ERR=>"md5sum: the --ignore-missing option is ".
+ "meaningful only when verifying checksums\n".
+ $try_help},
+ {EXIT=> 1}],
['bsd-segv', '--check', {IN=> {'z' => "MD5 ("}}, {EXIT=> 1},
{ERR=> "$prog: z: no properly formatted MD5 checksum lines found\n"}],