summaryrefslogtreecommitdiff
path: root/src/md5sum.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/md5sum.c')
-rw-r--r--src/md5sum.c34
1 files changed, 32 insertions, 2 deletions
diff --git a/src/md5sum.c b/src/md5sum.c
index 5d4b958ee..49da8edc4 100644
--- a/src/md5sum.c
+++ b/src/md5sum.c
@@ -119,6 +119,9 @@ static bool status_only = false;
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;
@@ -133,7 +136,8 @@ static int bsd_reversed = -1;
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
@@ -143,6 +147,7 @@ static struct option const long_options[] =
{
{ "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' },
@@ -197,7 +202,8 @@ Print or check %s (%d-bit) checksums.\n\
"), 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\
@@ -482,6 +488,11 @@ digest_file (const char *filename, int *binary, unsigned char *bin_result)
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;
}
@@ -597,6 +608,7 @@ digest_check (const char *checkfile_name)
++n_properly_formatted_lines;
+ *bin_buffer = '\1'; /* flag set to 0 for ignored missing files. */
ok = digest_file (filename, &binary, bin_buffer);
if (!ok)
@@ -610,10 +622,17 @@ digest_check (const char *checkfile_name)
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)
@@ -749,6 +768,9 @@ main (int argc, char **argv)
warn = true;
quiet = false;
break;
+ case IGNORE_MISSING_OPTION:
+ ignore_missing = true;
+ break;
case QUIET_OPTION:
status_only = false;
warn = false;
@@ -795,6 +817,14 @@ main (int argc, char **argv)
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,