diff options
| author | hubertf <hubertf@NetBSD.org> | 2006-04-23 16:40:16 +0000 |
|---|---|---|
| committer | hubertf <hubertf@NetBSD.org> | 2006-04-23 16:40:16 +0000 |
| commit | f9e91b57edf9e97f27b4066d796cf48334ef1789 (patch) | |
| tree | 38d41027f5d21b945a45a253fd0755787e9d44c1 /usr.bin/cksum | |
| parent | 3fe7a640a3d5cff113f5dfa8bbc974349ef95e0b (diff) | |
Add a switch "-c file" to verify a list of checksums generated by the
cksum program and stored in file against files on disk. E.g. first
run "md5 *.tgz >MD5" to generate a list of MD5 checksums in MD5, then
use the following command to verify them use "md5 -c MD5"
Inspired by Linux' md5sum,
called for by Jukka Salmi <j+nbsd@2006.salmi.ch>on netbsd-help@,
reviewed by rui@.
Diffstat (limited to 'usr.bin/cksum')
| -rw-r--r-- | usr.bin/cksum/cksum.1 | 30 | ||||
| -rw-r--r-- | usr.bin/cksum/cksum.c | 239 |
2 files changed, 235 insertions, 34 deletions
diff --git a/usr.bin/cksum/cksum.1 b/usr.bin/cksum/cksum.1 index 12458ef9968..b7c3ef4959a 100644 --- a/usr.bin/cksum/cksum.1 +++ b/usr.bin/cksum/cksum.1 @@ -1,4 +1,4 @@ -.\" $NetBSD: cksum.1,v 1.32 2005/09/11 23:11:48 wiz Exp $ +.\" $NetBSD: cksum.1,v 1.33 2006/04/23 16:40:16 hubertf Exp $ .\" .\" Copyright (c) 1991, 1993 .\" The Regents of the University of California. All rights reserved. @@ -32,7 +32,7 @@ .\" .\" @(#)cksum.1 8.2 (Berkeley) 4/28/95 .\" -.Dd August 24, 2005 +.Dd April 24, 2006 .Dt CKSUM 1 .Os .Sh NAME @@ -49,14 +49,17 @@ .Op Fl n .Oo .Fl a Ar algorithm | +.Fl c Ar file | .Op Fl o Ar 1 | Ar 2 .Oc .Op Ar .Nm sum +.Op Fl c Ar file .Op Ar .Nm md2 .Op Fl n .Oo +.Fl c Ar file | .Fl p | .Fl t | .Fl x | @@ -66,6 +69,7 @@ .Nm md4 .Op Fl n .Oo +.Fl c Ar file | .Fl p | .Fl t | .Fl x | @@ -75,6 +79,7 @@ .Nm md5 .Op Fl n .Oo +.Fl c Ar file | .Fl p | .Fl t | .Fl x | @@ -84,6 +89,7 @@ .Nm sha1 .Op Fl n .Oo +.Fl c Ar file | .Fl p | .Fl t | .Fl x | @@ -93,6 +99,7 @@ .Nm rmd160 .Op Fl n .Oo +.Fl c Ar file | .Fl p | .Fl t | .Fl x | @@ -202,6 +209,18 @@ and .Fl o Ar 2 , respectively. The default is CRC. +.It Fl c Ar file +Verify a list of checksums generated by the +.Nm +program and stored in +.Pa file +against files on disk. +E.g. first run +.Dl Ic md5 *.tgz >MD5 +to generate a list of MD5 checksums in +.Pa MD5, +then use the following command to verify them: +.Dl Ic md5 -c MD5 .It Fl o Use historic algorithms instead of the (superior) default one. .Pp @@ -314,6 +333,9 @@ and .Nm sum utilities exit 0 on success, and \*[Gt]0 if an error occurs. .Sh SEE ALSO +.Xr openssl 1 , +.Xr mtree 8 +.Pp The default calculation is identical to that given in pseudo-code in the following .Tn ACM @@ -362,6 +384,10 @@ and .Nm rmd160 was added in .Nx 1.6 . +The functionality to verify checksum stored in a file +.Fl ( c ) +first appeared in +.Nx 4.0 . .\" .Pp .\" The .\" .Nm sum diff --git a/usr.bin/cksum/cksum.c b/usr.bin/cksum/cksum.c index 11baf16a863..ad6e9ceeacc 100644 --- a/usr.bin/cksum/cksum.c +++ b/usr.bin/cksum/cksum.c @@ -1,4 +1,4 @@ -/* $NetBSD: cksum.c,v 1.32 2006/01/15 16:50:05 elad Exp $ */ +/* $NetBSD: cksum.c,v 1.33 2006/04/23 16:40:16 hubertf Exp $ */ /*- * Copyright (c) 1991, 1993 @@ -81,7 +81,7 @@ __COPYRIGHT("@(#) Copyright (c) 1991, 1993\n\ #if 0 static char sccsid[] = "@(#)cksum.c 8.2 (Berkeley) 4/28/95"; #endif -__RCSID("$NetBSD: cksum.c,v 1.32 2006/01/15 16:50:05 elad Exp $"); +__RCSID("$NetBSD: cksum.c,v 1.33 2006/04/23 16:40:16 hubertf Exp $"); #endif /* not lint */ #include <sys/cdefs.h> @@ -163,12 +163,15 @@ main(int argc, char **argv) int (*cfncn) (int, u_int32_t *, off_t *); void (*pfncn) (char *, u_int32_t, off_t); struct hash *hash; - int normal, i; + int normal, i, check_warn; + char *checkfile; cfncn = NULL; pfncn = NULL; dosum = pflag = nohashstdin = 0; normal = 0; + checkfile = NULL; + check_warn = 0; setlocale(LC_ALL, ""); @@ -196,7 +199,7 @@ main(int argc, char **argv) * are still supported in code to not break anything that might * be using them. */ - while ((ch = getopt(argc, argv, "a:mno:ps:tx12456")) != -1) + while ((ch = getopt(argc, argv, "a:c:mno:ps:twx12456")) != -1) switch(ch) { case 'a': if (hash != NULL || dosum) { @@ -263,6 +266,9 @@ main(int argc, char **argv) } hash = &hashes[HASH_RMD160]; break; + case 'c': + checkfile = optarg; + break; case 'n': normal = 1; break; @@ -300,6 +306,9 @@ main(int argc, char **argv) nohashstdin = 1; hash->timetrialfunc(); break; + case 'w': + check_warn = 1; + break; case 'x': if (hash == NULL) requirehash("-x"); @@ -313,37 +322,204 @@ main(int argc, char **argv) argc -= optind; argv += optind; - fd = STDIN_FILENO; - fn = NULL; - rval = 0; - do { - if (*argv) { - fn = *argv++; - if (hash != NULL) { - if (hash_digest_file(fn, hash, normal)) { - warn("%s", fn); + if (checkfile) { + /* + * Verify checksums + */ + FILE *f; + char buf[BUFSIZ]; + char *s, *p_filename, *p_cksum; + int l_filename, l_cksum; + char filename[BUFSIZ]; + char cksum[BUFSIZ]; + int ok,cnt,badcnt; + + rval = 0; + cnt = badcnt = 0; + + f = fopen(checkfile, "r"); + if (f == NULL) + err(1, "Cannot read %s", checkfile); + while(fgets(buf, sizeof(buf), f) != NULL) { + s=strrchr(buf, '\n'); + if (s) + *s = '\0'; + + p_cksum = p_filename = NULL; + + p_filename = strchr(buf, '('); + if (p_filename) { + /* + * Assume 'normal' output if there's a '(' + */ + p_filename += 1; + normal = 0; + + p_cksum = strrchr(p_filename, ')'); + if (p_cksum == NULL) { + if (check_warn) + warnx("bogus format: %s. " + "Skipping...", + buf); + rval = 1; + continue; + } + p_cksum += 4; + + l_cksum = strlen(p_cksum); + l_filename = p_cksum - p_filename - 4; + + /* Sanity check */ + if (strncmp(buf, hash->hashname, + strlen(hash->hashname)) != 0) { + warnx("%.*s: %s checksum expected, " + "%.*s found, skipping.", + l_filename, + p_filename, + hash->hashname, + strlen(hash->hashname), + buf); + rval = 1; + continue; + } + + } else { + if (hash) { + /* + * 'normal' output, no (ck)sum + */ + normal = 1; + + p_cksum = buf; + p_filename = strchr(buf, ' '); + if (p_filename == NULL) { + if (check_warn) + warnx("no filename in %s? " + "Skipping...", buf); + rval = 1; + continue; + } + p_filename++; + l_filename = strlen(p_filename); + l_cksum = p_filename - buf - 1; + } else { + /* + * sum/cksum output format + */ + p_cksum = buf; + s=strchr(p_cksum, ' '); + if (s == NULL) { + if (check_warn) + warnx("bogus format: %s." + " Skipping...", + buf); + rval = 1; + continue; + } + l_cksum = s - p_cksum; + + p_filename = strrchr(buf, ' '); + if (p_filename == NULL) { + if (check_warn) + warnx("no filename in %s?" + " Skipping...", + buf); + rval = 1; + continue; + } + p_filename++; + l_filename = strlen(p_filename); + } + } + + strlcpy(filename, p_filename, l_filename+1); + strlcpy(cksum, p_cksum, l_cksum+1); + + if (hash) { + if (access(filename, R_OK) == 0 + && strcmp(cksum, hash->filefunc(filename, NULL)) == 0) + ok = 1; + else + ok = 0; + } else { + if ((fd = open(filename, O_RDONLY, 0)) < 0) { + if (check_warn) + warn("%s", filename); rval = 1; + ok = 0; + } else { + if (cfncn(fd, &val, &len)) + ok = 0; + else { + u_int32_t should_val; + + should_val = + strtoul(cksum, NULL, 10); + if (val == should_val) + ok = 1; + else + ok = 0; + } } - continue; } - if ((fd = open(fn, O_RDONLY, 0)) < 0) { - warn("%s", fn); - rval = 1; - continue; + + if (ok) +#ifdef LINUX_CHECK_COMPAT + printf("%s: OK\n", filename) +#endif + ; + else { + printf("%s: FAILED\n", filename); + badcnt++; } - } else if (hash && !nohashstdin) { - hash->filterfunc(pflag); - } + cnt++; - if (hash == NULL) { - if (cfncn(fd, &val, &len)) { - warn("%s", fn ? fn : "stdin"); - rval = 1; - } else - pfncn(fn, val, len); - (void)close(fd); } - } while (*argv); + fclose(f); + +#ifdef LINUX_CHECK_COMPAT + if (badcnt > 0) + printf("%s: WARNING: %d of %d computed checksums did NOT match\n", + progname, badcnt, cnt); +#endif + + } else { + /* + * Calculate checksums + */ + + fd = STDIN_FILENO; + fn = NULL; + rval = 0; + do { + if (*argv) { + fn = *argv++; + if (hash != NULL) { + if (hash_digest_file(fn, hash, normal)) { + warn("%s", fn); + rval = 1; + } + continue; + } + if ((fd = open(fn, O_RDONLY, 0)) < 0) { + warn("%s", fn); + rval = 1; + continue; + } + } else if (hash && !nohashstdin) { + hash->filterfunc(pflag); + } + + if (hash == NULL) { + if (cfncn(fd, &val, &len)) { + warn("%s", fn ? fn : "stdin"); + rval = 1; + } else + pfncn(fn, val, len); + (void)close(fd); + } + } while (*argv); + } exit(rval); } @@ -378,9 +554,8 @@ void usage(void) { - (void)fprintf(stderr, "usage: cksum [-n] [-a algorithm] [file ...]\n"); - (void)fprintf(stderr, " cksum [-n] [-m | -1 | -2 | -4 | -5 | -6 | [-o 1 | 2]] [file ...]\n"); - (void)fprintf(stderr, " sum [file ...]\n"); + (void)fprintf(stderr, "usage: cksum [-nw] [-a algorithm | -c file | -m | -1 | -2 | -4 | -5 | -6 \n\t\t| [-o 1 | 2]] [file ...]\n"); + (void)fprintf(stderr, " sum [-c] [file ...]\n"); (void)fprintf(stderr, " md2 [-n] [-p | -t | -x | -s string] [file ...]\n"); (void)fprintf(stderr, |
