This diff adds a new -C flag to the md5/cksum/sha1/sha256 programs, which does the same thing as the -c flag except that it skips non-existent files in the checklist.
This is useful when you want to use a checklist file to only verify the checksums of files that actually exist. A common example is when you download just a few file sets from an OpenBSD mirror to test a snapshot, and you want to verify the checksums of those files only. Here's an example that shows the difference between -c and -C: $ ls SHA256 base51.tgz bsd bsd.rd etc51.tgz $ sha256 -c SHA256 sha256: cannot open INSTALL.amd64: No such file or directory (SHA256) INSTALL.amd64: FAILED (SHA256) base51.tgz: OK (SHA256) bsd: OK sha256: cannot open bsd.mp: No such file or directory (SHA256) bsd.mp: FAILED (SHA256) bsd.rd: OK sha256: cannot open cd51.iso: No such file or directory (SHA256) cd51.iso: FAILED sha256: cannot open cdboot: No such file or directory (SHA256) cdboot: FAILED sha256: cannot open cdbr: No such file or directory (SHA256) cdbr: FAILED sha256: cannot open comp51.tgz: No such file or directory (SHA256) comp51.tgz: FAILED (SHA256) etc51.tgz: OK sha256: cannot open floppy51.fs: No such file or directory (SHA256) floppy51.fs: FAILED sha256: cannot open game51.tgz: No such file or directory (SHA256) game51.tgz: FAILED sha256: cannot open man51.tgz: No such file or directory (SHA256) man51.tgz: FAILED sha256: cannot open pxeboot: No such file or directory (SHA256) pxeboot: FAILED sha256: cannot open install51.iso: No such file or directory (SHA256) install51.iso: FAILED sha256: cannot open xbase51.tgz: No such file or directory (SHA256) xbase51.tgz: FAILED sha256: cannot open xetc51.tgz: No such file or directory (SHA256) xetc51.tgz: FAILED sha256: cannot open xfont51.tgz: No such file or directory (SHA256) xfont51.tgz: FAILED sha256: cannot open xserv51.tgz: No such file or directory (SHA256) xserv51.tgz: FAILED sha256: cannot open xshare51.tgz: No such file or directory (SHA256) xshare51.tgz: FAILED $ sha256 -C SHA256 (SHA256) base51.tgz: OK (SHA256) bsd: OK (SHA256) bsd.rd: OK (SHA256) etc51.tgz: OK Comments? Thanks, Lawrence Index: cksum.1 =================================================================== RCS file: /cvs/src/bin/md5/cksum.1,v retrieving revision 1.23 diff -u -p -r1.23 cksum.1 --- cksum.1 7 Nov 2010 08:05:55 -0000 1.23 +++ cksum.1 23 Feb 2012 03:53:44 -0000 @@ -44,7 +44,7 @@ .Bk -words .Op Fl bpqrtx .Op Fl a Ar algorithms -.Op Fl c Op Ar checklist ... +.Op Fl c | Fl C Op Ar checklist ... .Op Fl o Ar 1 | 2 .Op Fl s Ar string .Op Ar @@ -162,6 +162,15 @@ The option may not be used in conjunction with more than a single .Fl a option. +.It Xo +.Fl C +.Op Ar checklist ... +.Xc +As option +.Fl c +above, but skip files in +.Ar checklist +that do not exist. .It Fl o Ar 1 | 2 Use historic algorithms instead of the (superior) default one (see below). Index: md5.1 =================================================================== RCS file: /cvs/src/bin/md5/md5.1,v retrieving revision 1.32 diff -u -p -r1.32 md5.1 --- md5.1 3 Sep 2010 09:53:20 -0000 1.32 +++ md5.1 23 Feb 2012 03:53:44 -0000 @@ -27,7 +27,7 @@ .Sh SYNOPSIS .Nm md5 .Op Fl bpqrtx -.Op Fl c Op Ar checklist ... +.Op Fl c | Fl C Op Ar checklist ... .Op Fl s Ar string .Op Ar .Sh DESCRIPTION @@ -67,6 +67,15 @@ and an OK or FAILED for the result of th This will validate any of the supported checksums (see .Xr cksum 1 ) . If no file is given, stdin is used. +.It Xo +.Fl C +.Op Ar checklist ... +.Xc +As option +.Fl c +above, but skip files in +.Ar checklist +that do not exist. .It Fl p Echoes stdin to stdout and appends the .Em MD5 Index: md5.c =================================================================== RCS file: /cvs/src/bin/md5/md5.c,v retrieving revision 1.53 diff -u -p -r1.53 md5.c --- md5.c 5 Jul 2011 23:39:27 -0000 1.53 +++ md5.c 23 Feb 2012 03:53:46 -0000 @@ -32,6 +32,7 @@ #include <string.h> #include <time.h> #include <unistd.h> +#include <errno.h> #include <md4.h> #include <md5.h> @@ -191,7 +192,7 @@ TAILQ_HEAD(hash_list, hash_function); void digest_end(const struct hash_function *, void *, char *, size_t, int); void digest_file(const char *, struct hash_list *, int); -int digest_filelist(const char *, struct hash_function *); +int digest_filelist(const char *, struct hash_function *, int); void digest_print(const struct hash_function *, const char *, const char *); void digest_printstr(const struct hash_function *, const char *, const char *); void digest_string(char *, struct hash_list *); @@ -212,18 +213,20 @@ main(int argc, char **argv) char *cp, *input_string; int fl, error, base64; int bflag, cflag, pflag, rflag, tflag, xflag; + int skip_nonexistent; static const char *optstr[5] = { - "bcpqrs:tx", - "bcpqrs:tx", - "bcpqrs:tx", - "a:bco:pqrs:tx", - "a:bco:pqrs:tx" + "bcCpqrs:tx", + "bcCpqrs:tx", + "bcCpqrs:tx", + "a:bcCo:pqrs:tx", + "a:bcCo:pqrs:tx" }; TAILQ_INIT(&hl); input_string = NULL; error = bflag = cflag = pflag = qflag = rflag = tflag = xflag = 0; + skip_nonexistent = 0; pmode = MODE_MD5; if (strcmp(__progname, "md5") == 0) @@ -298,6 +301,10 @@ main(int argc, char **argv) case 'c': cflag = 1; break; + case 'C': + cflag = 1; + skip_nonexistent = 1; + break; case 'o': if (strcmp(optarg, "1") == 0) hf = &functions[1]; @@ -376,11 +383,11 @@ main(int argc, char **argv) digest_string(input_string, &hl); else if (cflag) { if (argc == 0) - error = digest_filelist("-", TAILQ_FIRST(&hl)); + error = digest_filelist("-", TAILQ_FIRST(&hl), skip_nonexistent); else while (argc--) error += digest_filelist(*argv++, - TAILQ_FIRST(&hl)); + TAILQ_FIRST(&hl), skip_nonexistent); } else if (pflag || argc == 0) digest_file("-", &hl, pflag); else @@ -528,7 +535,8 @@ digest_file(const char *file, struct has * Print out the result of each comparison. */ int -digest_filelist(const char *file, struct hash_function *defhash) +digest_filelist(const char *file, struct hash_function *defhash, + int skip_nonexistent) { int found, base64, error, cmp; size_t algorithm_max, algorithm_min; @@ -655,6 +663,8 @@ digest_filelist(const char *file, struct found = 1; if ((fp = fopen(filename, "r")) == NULL) { + if (skip_nonexistent && errno == ENOENT) + continue; warn("cannot open %s", filename); (void)printf("(%s) %s: FAILED\n", algorithm, filename); error = 1; @@ -789,13 +799,13 @@ usage(void) case MODE_MD5: case MODE_SHA1: case MODE_RMD160: - fprintf(stderr, "usage: %s [-bpqrtx] [-c [checklist ...]] " + fprintf(stderr, "usage: %s [-bpqrtx] [-c | -C [checklist ...]] " "[-s string] [file ...]\n", __progname); break; case MODE_CKSUM: case MODE_SUM: fprintf(stderr, "usage: %s [-bpqrtx] [-a algorithms] " - "[-c [checklist ...]] [-o 1 | 2]\n" + "[-c | -C [checklist ...]] [-o 1 | 2]\n" " %*s [-s string] [file ...]\n", __progname, (int)strlen(__progname), ""); break; Index: sha1.1 =================================================================== RCS file: /cvs/src/bin/md5/sha1.1,v retrieving revision 1.29 diff -u -p -r1.29 sha1.1 --- sha1.1 3 Sep 2010 09:53:20 -0000 1.29 +++ sha1.1 23 Feb 2012 03:53:46 -0000 @@ -27,7 +27,7 @@ .Sh SYNOPSIS .Nm sha1 .Op Fl bpqrtx -.Op Fl c Op Ar checklist ... +.Op Fl c | Fl C Op Ar checklist ... .Op Fl s Ar string .Op Ar .Sh DESCRIPTION @@ -62,6 +62,15 @@ and an OK or FAILED for the result of th This will validate any of the supported checksums (see .Xr cksum 1 ) . If no file is given, stdin is used. +.It Xo +.Fl C +.Op Ar checklist ... +.Xc +As option +.Fl c +above, but skip files in +.Ar checklist +that do not exist. .It Fl p Echoes stdin to stdout and appends the .Em SHA-1 Index: sha256.1 =================================================================== RCS file: /cvs/src/bin/md5/sha256.1,v retrieving revision 1.3 diff -u -p -r1.3 sha256.1 --- sha256.1 3 Sep 2010 09:53:20 -0000 1.3 +++ sha256.1 23 Feb 2012 03:53:46 -0000 @@ -27,7 +27,7 @@ .Sh SYNOPSIS .Nm sha256 .Op Fl bpqrtx -.Op Fl c Op Ar checklist ... +.Op Fl c | Fl C Op Ar checklist ... .Op Fl s Ar string .Op Ar .Sh DESCRIPTION @@ -62,6 +62,15 @@ and an OK or FAILED for the result of th This will validate any of the supported checksums (see .Xr cksum 1 ) . If no file is given, stdin is used. +.It Xo +.Fl C +.Op Ar checklist ... +.Xc +As option +.Fl c +above, but skip files in +.Ar checklist +that do not exist. .It Fl p Echoes stdin to stdout and appends the .Em SHA2-256