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

Reply via email to