summaryrefslogtreecommitdiff
path: root/usr.bin/cksum
diff options
context:
space:
mode:
authorhubertf <hubertf@NetBSD.org>2006-04-23 16:40:16 +0000
committerhubertf <hubertf@NetBSD.org>2006-04-23 16:40:16 +0000
commitf9e91b57edf9e97f27b4066d796cf48334ef1789 (patch)
tree38d41027f5d21b945a45a253fd0755787e9d44c1 /usr.bin/cksum
parent3fe7a640a3d5cff113f5dfa8bbc974349ef95e0b (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.130
-rw-r--r--usr.bin/cksum/cksum.c239
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,