1 /* $NetBSD: cksum.c,v 1.48 2015/06/16 22:54:10 christos 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.48 2015/06/16 22:54:10 christos Exp $");
87 #include <sys/types.h>
107 #define PRINT_NORMAL 0x01
108 #define PRINT_QUIET 0x02
110 typedef char *(*_filefunc
)(const char *, char *);
113 const char *progname
;
114 const char *hashname
;
115 void (*stringfunc
)(const char *);
116 void (*timetrialfunc
)(void);
117 void (*testsuitefunc
)(void);
118 void (*filterfunc
)(int);
119 char *(*filefunc
)(const char *, char *);
122 MD2String
, MD2TimeTrial
, MD2TestSuite
,
123 MD2Filter
, MD2File
},
125 MD4String
, MD4TimeTrial
, MD4TestSuite
,
126 MD4Filter
, MD4File
},
128 MD5String
, MD5TimeTrial
, MD5TestSuite
,
129 MD5Filter
, MD5File
},
130 { "rmd160", "RMD160",
131 RMD160String
, RMD160TimeTrial
, RMD160TestSuite
,
132 RMD160Filter
, (_filefunc
) RMD160File
},
134 SHA1String
, SHA1TimeTrial
, SHA1TestSuite
,
135 SHA1Filter
, (_filefunc
) SHA1File
},
136 { "sha256", "SHA256",
137 SHA256_String
, SHA256_TimeTrial
, SHA256_TestSuite
,
138 SHA256_Filter
, (_filefunc
) SHA256_File
},
139 { "sha384", "SHA384",
140 SHA384_String
, SHA384_TimeTrial
, SHA384_TestSuite
,
141 SHA384_Filter
, (_filefunc
) SHA384_File
},
142 { "sha512", "SHA512",
143 SHA512_String
, SHA512_TimeTrial
, SHA512_TestSuite
,
144 SHA512_Filter
, (_filefunc
) SHA512_File
},
145 { .progname
= NULL
, },
148 static int hash_digest_file(char *, const struct hash
*, int);
149 __dead
static void requirehash(const char *);
150 __dead
static void usage(void);
153 main(int argc
, char **argv
)
155 int ch
, fd
, rval
, pflag
, nohashstdin
;
159 const char *progname
;
160 int (*cfncn
) (int, u_int32_t
*, off_t
*);
161 void (*pfncn
) (char *, u_int32_t
, off_t
);
162 const struct hash
*hash
;
163 int i
, check_warn
, do_check
;
168 pflag
= nohashstdin
= 0;
173 setlocale(LC_ALL
, "");
175 progname
= getprogname();
177 for (hash
= hashes
; hash
->hashname
!= NULL
; hash
++)
178 if (strcmp(progname
, hash
->progname
) == 0)
181 if (hash
->hashname
== NULL
) {
184 if (!strcmp(progname
, "sum")) {
193 while ((ch
= getopt(argc
, argv
, "a:cno:pqs:twx")) != -1)
197 warnx("illegal use of -a option");
201 while (hashes
[i
].hashname
!= NULL
) {
202 if (!strcasecmp(hashes
[i
].hashname
, optarg
)) {
209 if (!strcasecmp(optarg
, "old1")) {
212 } else if (!strcasecmp(optarg
, "old2")) {
215 } else if (!strcasecmp(optarg
, "crc")) {
219 warnx("illegal argument to -a option");
228 print_flags
|= PRINT_NORMAL
;
232 warnx("%s mutually exclusive with sum",
236 if (!strcmp(optarg
, "1")) {
239 } else if (!strcmp(optarg
, "2")) {
243 warnx("illegal argument to -o option");
253 print_flags
|= PRINT_QUIET
;
259 hash
->stringfunc(optarg
);
265 hash
->timetrialfunc();
274 hash
->testsuitefunc();
289 char *s
, *p_filename
, *p_cksum
;
290 int l_filename
, l_cksum
;
291 char filename
[BUFSIZ
];
299 f
= fdopen(STDIN_FILENO
, "r");
301 f
= fopen(argv
[0], "r");
304 err(1, "Cannot read %s",
305 argc
>0?argv
[0]:"stdin");
307 while(fgets(buf
, sizeof(buf
), f
) != NULL
) {
308 s
= strrchr(buf
, '\n');
312 p_cksum
= p_filename
= NULL
;
314 p_filename
= strchr(buf
, '(');
317 * Assume 'normal' output if there's a '('
320 print_flags
&= ~(PRINT_NORMAL
);
322 p_cksum
= strrchr(p_filename
, ')');
323 if (p_cksum
== NULL
) {
325 warnx("bogus format: %s. "
333 l_cksum
= strlen(p_cksum
);
334 l_filename
= p_cksum
- p_filename
- 4;
336 /* Sanity check, and find proper hash if
337 * it's not the same as the current program
340 strncmp(buf
, hash
->hashname
,
341 strlen(hash
->hashname
)) != 0) {
345 const struct hash
*nhash
;
347 for (nhash
= hashes
;
348 nhash
->hashname
!= NULL
;
352 strlen(nhash
->hashname
)) == 0)
356 if (nhash
->hashname
== NULL
) {
358 warnx("unknown hash: %s",
372 * 'normal' output, no (ck)sum
374 print_flags
|= PRINT_NORMAL
;
378 p_filename
= strchr(buf
, ' ');
379 if (p_filename
== NULL
) {
381 warnx("no filename in %s? "
386 while (isspace((int)*++p_filename
))
388 l_filename
= strlen(p_filename
);
389 l_cksum
= p_filename
- buf
- nspaces
;
392 * sum/cksum output format
395 s
=strchr(p_cksum
, ' ');
398 warnx("bogus format: %s."
404 l_cksum
= s
- p_cksum
;
406 p_filename
= strrchr(buf
, ' ');
407 if (p_filename
== NULL
) {
409 warnx("no filename in %s?"
416 l_filename
= strlen(p_filename
);
420 strlcpy(filename
, p_filename
, l_filename
+1);
421 strlcpy(cksum
, p_cksum
, l_cksum
+1);
424 if (access(filename
, R_OK
) == 0
425 && strcmp(cksum
, hash
->filefunc(filename
, NULL
)) == 0)
430 if ((fd
= open(filename
, O_RDONLY
, 0)) < 0) {
432 warn("%s", filename
);
436 if (cfncn(fd
, &val
, &len
))
439 u_int32_t should_val
;
442 strtoul(cksum
, NULL
, 10);
443 if (val
== should_val
)
454 printf("(%s) ", hash
->hashname
);
455 printf("%s: FAILED\n", filename
);
468 * Calculate checksums
478 if (hash_digest_file(fn
, hash
, print_flags
)) {
484 if ((fd
= open(fn
, O_RDONLY
, 0)) < 0) {
489 } else if (hash
&& !nohashstdin
) {
490 hash
->filterfunc(pflag
);
494 if (cfncn(fd
, &val
, &len
)) {
495 warn("%s", fn
? fn
: "stdin");
507 hash_digest_file(char *fn
, const struct hash
*hash
, int flags
)
511 cp
= hash
->filefunc(fn
, NULL
);
515 if (flags
& PRINT_QUIET
)
517 else if (flags
& PRINT_NORMAL
)
518 printf("%s %s\n", cp
, fn
);
520 printf("%s (%s) = %s\n", hash
->hashname
, fn
, cp
);
528 requirehash(const char *flg
)
530 warnx("%s flag requires `-a algorithm'", flg
);
537 const char fileargs
[] = "[file ... | -c [-w] [sumfile]]";
538 const char sumargs
[] = "[-n] [-a algorithm [-ptx] [-s string]] [-o 1|2]";
539 const char hashargs
[] = "[-nptx] [-s string]";
541 (void)fprintf(stderr
, "usage: cksum %s\n %s\n",
543 (void)fprintf(stderr
, " sum %s\n %s\n",
545 (void)fprintf(stderr
, " md2 %s %s\n", hashargs
, fileargs
);
546 (void)fprintf(stderr
, " md4 %s %s\n", hashargs
, fileargs
);
547 (void)fprintf(stderr
, " md5 %s %s\n", hashargs
, fileargs
);
548 (void)fprintf(stderr
, " rmd160 %s %s\n", hashargs
, fileargs
);
549 (void)fprintf(stderr
, " sha1 %s %s\n", hashargs
, fileargs
);