1 /* $NetBSD: cksum.c,v 1.45 2011/08/29 14:12:29 joerg Exp $ */
4 * Copyright (c) 1991, 1993
5 * The Regents of the University of California. All rights reserved.
7 * This code is derived from software contributed to Berkeley by
8 * James W. Williams of NASA Goddard Space Flight Center.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * Copyright (c) 1997 Jason R. Thorpe. All rights reserved.
38 * This code is derived from software contributed to Berkeley by
39 * James W. Williams of NASA Goddard Space Flight Center.
41 * Redistribution and use in source and binary forms, with or without
42 * modification, are permitted provided that the following conditions
44 * 1. Redistributions of source code must retain the above copyright
45 * notice, this list of conditions and the following disclaimer.
46 * 2. Redistributions in binary form must reproduce the above copyright
47 * notice, this list of conditions and the following disclaimer in the
48 * documentation and/or other materials provided with the distribution.
49 * 3. All advertising materials mentioning features or use of this software
50 * must display the following acknowledgement:
51 * This product includes software developed by the University of
52 * California, Berkeley and its contributors.
53 * 4. Neither the name of the University nor the names of its contributors
54 * may be used to endorse or promote products derived from this software
55 * without specific prior written permission.
57 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
58 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
59 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
60 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
61 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
62 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
63 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
64 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
65 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
66 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
70 #if HAVE_NBTOOL_CONFIG_H
71 #include "nbtool_config.h"
74 #include <sys/cdefs.h>
75 #if defined(__COPYRIGHT) && !defined(lint)
76 __COPYRIGHT("@(#) Copyright (c) 1991, 1993\
77 The Regents of the University of California. All rights reserved.");
80 #if defined(__RCSID) && !defined(lint)
82 static char sccsid
[] = "@(#)cksum.c 8.2 (Berkeley) 4/28/95";
84 __RCSID("$NetBSD: cksum.c,v 1.45 2011/08/29 14:12:29 joerg Exp $");
87 #include <sys/types.h>
107 typedef char *(*_filefunc
)(const char *, char *);
110 const char *progname
;
111 const char *hashname
;
112 void (*stringfunc
)(const char *);
113 void (*timetrialfunc
)(void);
114 void (*testsuitefunc
)(void);
115 void (*filterfunc
)(int);
116 char *(*filefunc
)(const char *, char *);
119 MD2String
, MD2TimeTrial
, MD2TestSuite
,
120 MD2Filter
, MD2File
},
122 MD4String
, MD4TimeTrial
, MD4TestSuite
,
123 MD4Filter
, MD4File
},
125 MD5String
, MD5TimeTrial
, MD5TestSuite
,
126 MD5Filter
, MD5File
},
127 { "rmd160", "RMD160",
128 RMD160String
, RMD160TimeTrial
, RMD160TestSuite
,
129 RMD160Filter
, (_filefunc
) RMD160File
},
131 SHA1String
, SHA1TimeTrial
, SHA1TestSuite
,
132 SHA1Filter
, (_filefunc
) SHA1File
},
133 { "sha256", "SHA256",
134 SHA256_String
, SHA256_TimeTrial
, SHA256_TestSuite
,
135 SHA256_Filter
, (_filefunc
) SHA256_File
},
136 { "sha384", "SHA384",
137 SHA384_String
, SHA384_TimeTrial
, SHA384_TestSuite
,
138 SHA384_Filter
, (_filefunc
) SHA384_File
},
139 { "sha512", "SHA512",
140 SHA512_String
, SHA512_TimeTrial
, SHA512_TestSuite
,
141 SHA512_Filter
, (_filefunc
) SHA512_File
},
142 { .progname
= NULL
, },
145 static int hash_digest_file(char *, const struct hash
*, int);
146 __dead
static void requirehash(const char *);
147 __dead
static void usage(void);
150 main(int argc
, char **argv
)
152 int ch
, fd
, rval
, dosum
, pflag
, nohashstdin
;
156 const char *progname
;
157 int (*cfncn
) (int, u_int32_t
*, off_t
*);
158 void (*pfncn
) (char *, u_int32_t
, off_t
);
159 const struct hash
*hash
;
160 int normal
, i
, check_warn
, do_check
;
164 dosum
= pflag
= nohashstdin
= 0;
169 setlocale(LC_ALL
, "");
171 progname
= getprogname();
173 for (hash
= hashes
; hash
->hashname
!= NULL
; hash
++)
174 if (strcmp(progname
, hash
->progname
) == 0)
177 if (hash
->hashname
== NULL
) {
180 if (!strcmp(progname
, "sum")) {
190 while ((ch
= getopt(argc
, argv
, "a:cno:ps:twx")) != -1)
194 warnx("illegal use of -a option\n");
198 while (hashes
[i
].hashname
!= NULL
) {
199 if (!strcasecmp(hashes
[i
].hashname
, optarg
)) {
206 if (!strcasecmp(optarg
, "old1")) {
209 } else if (!strcasecmp(optarg
, "old2")) {
212 } else if (!strcasecmp(optarg
, "crc")) {
216 warnx("illegal argument to -a option");
229 warnx("%s mutually exclusive with sum",
233 if (!strcmp(optarg
, "1")) {
236 } else if (!strcmp(optarg
, "2")) {
240 warnx("illegal argument to -o option");
253 hash
->stringfunc(optarg
);
259 hash
->timetrialfunc();
268 hash
->testsuitefunc();
283 char *s
, *p_filename
, *p_cksum
;
284 int l_filename
, l_cksum
;
285 char filename
[BUFSIZ
];
293 f
= fdopen(STDIN_FILENO
, "r");
295 f
= fopen(argv
[0], "r");
298 err(1, "Cannot read %s",
299 argc
>0?argv
[0]:"stdin");
301 while(fgets(buf
, sizeof(buf
), f
) != NULL
) {
302 s
=strrchr(buf
, '\n');
306 p_cksum
= p_filename
= NULL
;
308 p_filename
= strchr(buf
, '(');
311 * Assume 'normal' output if there's a '('
316 p_cksum
= strrchr(p_filename
, ')');
317 if (p_cksum
== NULL
) {
319 warnx("bogus format: %s. "
327 l_cksum
= strlen(p_cksum
);
328 l_filename
= p_cksum
- p_filename
- 4;
330 /* Sanity check, and find proper hash if
331 * it's not the same as the current program
334 strncmp(buf
, hash
->hashname
,
335 strlen(hash
->hashname
)) != 0) {
339 const struct hash
*nhash
;
341 for (nhash
= hashes
;
342 nhash
->hashname
!= NULL
;
346 strlen(nhash
->hashname
)) == 0)
350 if (nhash
->hashname
== NULL
) {
352 warnx("unknown hash: %s",
366 * 'normal' output, no (ck)sum
372 p_filename
= strchr(buf
, ' ');
373 if (p_filename
== NULL
) {
375 warnx("no filename in %s? "
380 while (isspace((int)*++p_filename
))
382 l_filename
= strlen(p_filename
);
383 l_cksum
= p_filename
- buf
- nspaces
;
386 * sum/cksum output format
389 s
=strchr(p_cksum
, ' ');
392 warnx("bogus format: %s."
398 l_cksum
= s
- p_cksum
;
400 p_filename
= strrchr(buf
, ' ');
401 if (p_filename
== NULL
) {
403 warnx("no filename in %s?"
410 l_filename
= strlen(p_filename
);
414 strlcpy(filename
, p_filename
, l_filename
+1);
415 strlcpy(cksum
, p_cksum
, l_cksum
+1);
418 if (access(filename
, R_OK
) == 0
419 && strcmp(cksum
, hash
->filefunc(filename
, NULL
)) == 0)
424 if ((fd
= open(filename
, O_RDONLY
, 0)) < 0) {
426 warn("%s", filename
);
430 if (cfncn(fd
, &val
, &len
))
433 u_int32_t should_val
;
436 strtoul(cksum
, NULL
, 10);
437 if (val
== should_val
)
448 printf("(%s) ", hash
->hashname
);
449 printf("%s: FAILED\n", filename
);
462 * Calculate checksums
472 if (hash_digest_file(fn
, hash
, normal
)) {
478 if ((fd
= open(fn
, O_RDONLY
, 0)) < 0) {
483 } else if (hash
&& !nohashstdin
) {
484 hash
->filterfunc(pflag
);
488 if (cfncn(fd
, &val
, &len
)) {
489 warn("%s", fn
? fn
: "stdin");
501 hash_digest_file(char *fn
, const struct hash
*hash
, int normal
)
505 cp
= hash
->filefunc(fn
, NULL
);
510 printf("%s %s\n", cp
, fn
);
512 printf("%s (%s) = %s\n", hash
->hashname
, fn
, cp
);
520 requirehash(const char *flg
)
522 warnx("%s flag requires `-a algorithm'", flg
);
529 const char fileargs
[] = "[file ... | -c [-w] [sumfile]]";
530 const char sumargs
[] = "[-n] [-a algorithm [-ptx] [-s string]] [-o 1|2]";
531 const char hashargs
[] = "[-nptx] [-s string]";
533 (void)fprintf(stderr
, "usage: cksum %s\n %s\n",
535 (void)fprintf(stderr
, " sum %s\n %s\n",
537 (void)fprintf(stderr
, " md2 %s %s\n", hashargs
, fileargs
);
538 (void)fprintf(stderr
, " md4 %s %s\n", hashargs
, fileargs
);
539 (void)fprintf(stderr
, " md5 %s %s\n", hashargs
, fileargs
);
540 (void)fprintf(stderr
, " rmd160 %s %s\n", hashargs
, fileargs
);
541 (void)fprintf(stderr
, " sha1 %s %s\n", hashargs
, fileargs
);