diff --git a/Makefile b/Makefile index 7150cbf..7b0fe3d 100644 --- a/Makefile +++ b/Makefile @@ -323,6 +323,10 @@ test-filename-escape: test-cli-comment-line: $(MAKE) -C tests test_cli_comment_line +.PHONY: test-cli-ignore-missing +test-cli-ignore-missing: + $(MAKE) -C tests test_cli_ignore_missing + .PHONY: armtest armtest: clean @echo ---- test ARM compilation ---- diff --git a/cli/xxhsum.c b/cli/xxhsum.c index 8df299b..76fc88f 100644 --- a/cli/xxhsum.c +++ b/cli/xxhsum.c @@ -526,8 +526,10 @@ typedef struct { unsigned long nProperlyFormattedLines; unsigned long nImproperlyFormattedLines; unsigned long nMismatchedChecksums; + unsigned long nMatchedChecksums; unsigned long nOpenOrReadFailures; unsigned long nMixedFormatLines; + unsigned long nMissing; int quit; } ParseFileReport; @@ -540,6 +542,7 @@ typedef struct { char* blockBuf; XSUM_U32 strictMode; XSUM_U32 statusOnly; + XSUM_U32 ignoreMissing; XSUM_U32 warn; XSUM_U32 quiet; XSUM_U32 algoBitmask; @@ -896,10 +899,14 @@ static void XSUM_parseFile1(ParseFileArg* XSUM_parseFileArg, int rev) break; case LineStatus_failedToOpen: - report->nOpenOrReadFailures++; - if (!XSUM_parseFileArg->statusOnly) { - XSUM_output("%s:%lu: Could not open or read '%s': %s.\n", - inFileName, lineNumber, parsedLine.filename, strerror(errno)); + if (XSUM_parseFileArg->ignoreMissing) { + report->nMissing++; + } else { + report->nOpenOrReadFailures++; + if (!XSUM_parseFileArg->statusOnly) { + XSUM_output("%s:%lu: Could not open or read '%s': %s.\n", + inFileName, lineNumber, parsedLine.filename, strerror(errno)); + } } break; @@ -907,6 +914,7 @@ static void XSUM_parseFile1(ParseFileArg* XSUM_parseFileArg, int rev) case LineStatus_hashFailed: { int b = 1; if (lineStatus == LineStatus_hashOk) { + report->nMatchedChecksums++; /* If --quiet is specified, don't display "OK" */ if (XSUM_parseFileArg->quiet) b = 0; } else { @@ -933,6 +941,7 @@ static void XSUM_parseFile1(ParseFileArg* XSUM_parseFileArg, int rev) * * If strictMode != 0, return error code if any line is invalid. * If statusOnly != 0, don't generate any output. + * If ignoreMissing != 0, ignore missing file. But if no file was verified, returns 0 (failed). * If warn != 0, print a warning message to stderr. * If quiet != 0, suppress "OK" line. * @@ -946,6 +955,7 @@ static int XSUM_checkFile(const char* inFileName, const Display_endianess displayEndianess, XSUM_U32 strictMode, XSUM_U32 statusOnly, + XSUM_U32 ignoreMissing, XSUM_U32 warn, XSUM_U32 quiet, XSUM_U32 algoBitmask) @@ -981,6 +991,7 @@ static int XSUM_checkFile(const char* inFileName, XSUM_parseFileArg->blockBuf = (char*) malloc(XSUM_parseFileArg->blockSize); XSUM_parseFileArg->strictMode = strictMode; XSUM_parseFileArg->statusOnly = statusOnly; + XSUM_parseFileArg->ignoreMissing = ignoreMissing; XSUM_parseFileArg->warn = warn; XSUM_parseFileArg->quiet = quiet; XSUM_parseFileArg->algoBitmask = algoBitmask; @@ -1025,6 +1036,14 @@ static int XSUM_checkFile(const char* inFileName, && report->nOpenOrReadFailures == 0 && (!strictMode || report->nImproperlyFormattedLines == 0) && report->quit == 0; + + /* If "--ignore-missing" is enabled and there's no matched checksum, report it as error. + * See https://github.com/coreutils/coreutils/blob/2f1cffe07ab0f0b4135a52d95f1689d7fc7f26c9/src/digest.c#L1325-L1328 */ + if (ignoreMissing && report->nMatchedChecksums == 0) { + XSUM_output("%s: no file was verified\n", inFileName); + result = 0; + } + return result; } @@ -1033,6 +1052,7 @@ static int XSUM_checkFiles(const char* fnList[], int fnTotal, const Display_endianess displayEndianess, XSUM_U32 strictMode, XSUM_U32 statusOnly, + XSUM_U32 ignoreMissing, XSUM_U32 warn, XSUM_U32 quiet, XSUM_U32 algoBitmask) @@ -1042,11 +1062,11 @@ static int XSUM_checkFiles(const char* fnList[], int fnTotal, /* Special case for stdinName "-", * note: stdinName is not a string. It's special pointer. */ if (fnTotal==0) { - ok &= XSUM_checkFile(stdinName, displayEndianess, strictMode, statusOnly, warn, quiet, algoBitmask); + ok &= XSUM_checkFile(stdinName, displayEndianess, strictMode, statusOnly, ignoreMissing, warn, quiet, algoBitmask); } else { int fnNb; for (fnNb=0; fnNb ./.test.xxh +./xxhsum --check ./.test.xxh + + +# Missing, expect error +# (1) Create checksum file. +# (2) Remove one of them. +# (3) --check it +# (4) Expect NG (missing file) +cp Makefile .test.makefile +./xxhsum ./.test.makefile > ./.test.xxh +rm ./.test.makefile +! ./xxhsum --check ./.test.xxh # Put '!' for expecting error + + +# Missing, --ignore-missing +# (1) Create checksum file. +# (2) Remove one of them. +# (3) --check it with --ignore-missing. +# (4) Expect OK + +cp Makefile .test.makefile +./xxhsum Makefile ./.test.makefile > ./.test.xxh +rm ./.test.makefile +./xxhsum --check --ignore-missing ./.test.xxh + + +# Missing, --ignore-missing, expect error +# (1) Create checksum file. +# (2) Remove all of them. +# (3) --check it with --ignore-missing. +# (4) Expect NG (no file was verified). + +cp Makefile .test.makefile +./xxhsum ./.test.makefile > ./.test.xxh +rm ./.test.makefile +! ./xxhsum --check --ignore-missing ./.test.xxh # Put '!' for expecting error + + +# Cleanup +( rm ./.test.* ) || true + +echo OK