From 2d96173629da50974e2381508c049fb62fb44807 Mon Sep 17 00:00:00 2001 From: lteo Date: Wed, 15 Jan 2014 04:43:36 +0000 Subject: [PATCH] Add support for a -C option. It works on a checklist like -c but only does the checksum comparison for selected files that are specified on the command line. idea discussed with deraadt@ and tedu@ manpage feedback jmc@ feedback/OK deraadt@ millert@ --- bin/md5/md5.1 | 18 ++++++++++++++++-- bin/md5/md5.c | 49 +++++++++++++++++++++++++++++++++++-------------- 2 files changed, 51 insertions(+), 16 deletions(-) diff --git a/bin/md5/md5.1 b/bin/md5/md5.1 index 06a965f0b95..097253a9bab 100644 --- a/bin/md5/md5.1 +++ b/bin/md5/md5.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: md5.1,v 1.41 2014/01/10 21:45:04 deraadt Exp $ +.\" $OpenBSD: md5.1,v 1.42 2014/01/15 04:43:36 lteo Exp $ .\" .\" Copyright (c) 2003, 2004, 2006 Todd C. Miller .\" @@ -18,7 +18,7 @@ .\" Agency (DARPA) and Air Force Research Laboratory, Air Force .\" Materiel Command, USAF, under agreement number F39502-99-1-0512. .\" -.Dd $Mdocdate: January 10 2014 $ +.Dd $Mdocdate: January 15 2014 $ .Dt MD5 1 .Os .Sh NAME @@ -27,21 +27,25 @@ .Sh SYNOPSIS .Nm md5 .Op Fl bcpqrtx +.Op Fl C Ar checklist .Op Fl h Ar hashfile .Op Fl s Ar string .Op Ar .Nm sha1 .Op Fl bcpqrtx +.Op Fl C Ar checklist .Op Fl h Ar hashfile .Op Fl s Ar string .Op Ar .Nm sha256 .Op Fl bcpqrtx +.Op Fl C Ar checklist .Op Fl h Ar hashfile .Op Fl s Ar string .Op Ar .Nm sha512 .Op Fl bcpqrtx +.Op Fl C Ar checklist .Op Fl h Ar hashfile .Op Fl s Ar string .Op Ar @@ -61,6 +65,16 @@ The options for use with each command are as follows: .Bl -tag -width Ds .It Fl b Output checksums in base64 notation, not hexadecimal. +.It Fl C Ar checklist +Compare the checksum of each +.Ar file +against the checksums in the +.Ar checklist . +Any specified +.Ar file +that is not listed in the +.Ar checklist +is ignored. .It Fl c If this option is specified, the .Ar file diff --git a/bin/md5/md5.c b/bin/md5/md5.c index 559b2c0f2e3..dd9a60ea6a6 100644 --- a/bin/md5/md5.c +++ b/bin/md5/md5.c @@ -1,4 +1,4 @@ -/* $OpenBSD: md5.c,v 1.69 2014/01/12 04:37:51 deraadt Exp $ */ +/* $OpenBSD: md5.c,v 1.70 2014/01/15 04:43:36 lteo Exp $ */ /* * Copyright (c) 2001,2003,2005-2007,2010,2013,2014 @@ -210,7 +210,7 @@ TAILQ_HEAD(hash_list, hash_function); void digest_end(const struct hash_function *, void *, char *, size_t, int); int digest_file(const char *, struct hash_list *, int); -int digest_filelist(const char *, struct hash_function *); +int digest_filelist(const char *, struct hash_function *, char **); void digest_print(const struct hash_function *, const char *, const char *); #if !defined(SHA2_ONLY) void digest_printstr(const struct hash_function *, const char *, const char *); @@ -231,21 +231,22 @@ main(int argc, char **argv) struct hash_function *hf, *hftmp; struct hash_list hl; size_t len; - char *cp, *input_string; + char *cp, *input_string, *selective_checklist; const char *optstr; int fl, error, base64; int bflag, cflag, pflag, rflag, tflag, xflag; TAILQ_INIT(&hl); input_string = NULL; + selective_checklist = NULL; error = bflag = cflag = pflag = qflag = rflag = tflag = xflag = 0; #if !defined(SHA2_ONLY) if (strcmp(__progname, "cksum") == 0 || strcmp(__progname, "sum") == 0) - optstr = "a:bch:o:pqrs:tx"; + optstr = "a:bC:ch:o:pqrs:tx"; else #endif /* !defined(SHA2_ONLY) */ - optstr = "bch:pqrs:tx"; + optstr = "bC:ch:pqrs:tx"; /* Check for -b option early since it changes behavior. */ while ((fl = getopt(argc, argv, optstr)) != -1) { @@ -311,6 +312,9 @@ main(int argc, char **argv) err(1, "%s", optarg); break; #if !defined(SHA2_ONLY) + case 'C': + selective_checklist = optarg; + break; case 'c': cflag = 1; break; @@ -362,12 +366,13 @@ main(int argc, char **argv) /* Most arguments are mutually exclusive */ fl = pflag + (tflag ? 1 : 0) + xflag + cflag + (input_string != NULL); - if (fl > 1 || (fl && argc && cflag == 0) || (rflag && qflag)) + if (fl > 1 || (fl && argc && cflag == 0) || (rflag && qflag) || + (selective_checklist != NULL && argc == 0)) usage(); - if (cflag != 0) { + if (selective_checklist || cflag) { if (TAILQ_FIRST(&hl) != TAILQ_LAST(&hl, hash_list)) errx(1, "only a single algorithm may be specified " - "in -c mode"); + "in -C or -c mode"); } /* No algorithm specified, check the name we were called as. */ @@ -395,13 +400,15 @@ main(int argc, char **argv) digest_test(&hl); else if (input_string) digest_string(input_string, &hl); + else if (selective_checklist) + error = digest_filelist(selective_checklist, TAILQ_FIRST(&hl), argv); else if (cflag) { if (argc == 0) - error = digest_filelist("-", TAILQ_FIRST(&hl)); + error = digest_filelist("-", TAILQ_FIRST(&hl), NULL); else while (argc--) error += digest_filelist(*argv++, - TAILQ_FIRST(&hl)); + TAILQ_FIRST(&hl), NULL); } else #endif /* !defined(SHA2_ONLY) */ if (pflag || argc == 0) @@ -555,12 +562,12 @@ digest_file(const char *file, struct hash_list *hl, int echo) * 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, char **sel) { int found, base64, error, cmp; size_t algorithm_max, algorithm_min; const char *algorithm; - char *filename, *checksum, *buf, *p; + char *filename, *checksum, *buf, *p, **sp; char digest[MAX_DIGEST_LEN + 1]; char *lbuf = NULL; FILE *listfp, *fp; @@ -681,6 +688,19 @@ digest_filelist(const char *file, struct hash_function *defhash) } found = 1; + /* + * If only a selection of files is wanted, proceed only + * if the filename matches one of those in the selection. + */ + if (sel) { + for (sp = sel; *sp; sp++) { + if (strcmp(*sp, filename) == 0) + break; + } + if (*sp == NULL) + continue; + } + if ((fp = fopen(filename, "r")) == NULL) { warn("cannot open %s", filename); (void)printf("(%s) %s: %s\n", algorithm, filename, @@ -816,14 +836,15 @@ usage(void) { #if !defined(SHA2_ONLY) if (strcmp(__progname, "cksum") == 0 || strcmp(__progname, "sum") == 0) - fprintf(stderr, "usage: %s [-bcpqrtx] [-a algorithms] " + fprintf(stderr, "usage: %s [-bcpqrtx] [-C checklist] [-a algorithms] " "[-h hashfile] [-o 1 | 2] [-s string]\n" " [file ...]\n", __progname); else #endif /* !defined(SHA2_ONLY) */ fprintf(stderr, "usage:" - "\t%s [-bcpqrtx] [-h hashfile] [-s string] [file ...]\n", + "\t%s [-bcpqrtx] [-C checklist] [-h hashfile] [-s string] " + "[file ...]\n", __progname); exit(EXIT_FAILURE); -- 2.20.1