1*0a6a1f1dSLionel Sambuc /* $NetBSD: cksum.c,v 1.48 2015/06/16 22:54:10 christos Exp $ */
2280d8c66SLionel Sambuc
3280d8c66SLionel Sambuc /*-
4280d8c66SLionel Sambuc * Copyright (c) 1991, 1993
5280d8c66SLionel Sambuc * The Regents of the University of California. All rights reserved.
6280d8c66SLionel Sambuc *
7280d8c66SLionel Sambuc * This code is derived from software contributed to Berkeley by
8280d8c66SLionel Sambuc * James W. Williams of NASA Goddard Space Flight Center.
9280d8c66SLionel Sambuc *
10280d8c66SLionel Sambuc * Redistribution and use in source and binary forms, with or without
11280d8c66SLionel Sambuc * modification, are permitted provided that the following conditions
12280d8c66SLionel Sambuc * are met:
13280d8c66SLionel Sambuc * 1. Redistributions of source code must retain the above copyright
14280d8c66SLionel Sambuc * notice, this list of conditions and the following disclaimer.
15280d8c66SLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright
16280d8c66SLionel Sambuc * notice, this list of conditions and the following disclaimer in the
17280d8c66SLionel Sambuc * documentation and/or other materials provided with the distribution.
18280d8c66SLionel Sambuc * 3. Neither the name of the University nor the names of its contributors
19280d8c66SLionel Sambuc * may be used to endorse or promote products derived from this software
20280d8c66SLionel Sambuc * without specific prior written permission.
21280d8c66SLionel Sambuc *
22280d8c66SLionel Sambuc * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23280d8c66SLionel Sambuc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24280d8c66SLionel Sambuc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25280d8c66SLionel Sambuc * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26280d8c66SLionel Sambuc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27280d8c66SLionel Sambuc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28280d8c66SLionel Sambuc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29280d8c66SLionel Sambuc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30280d8c66SLionel Sambuc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31280d8c66SLionel Sambuc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32280d8c66SLionel Sambuc * SUCH DAMAGE.
33280d8c66SLionel Sambuc */
34280d8c66SLionel Sambuc
35280d8c66SLionel Sambuc /*-
36280d8c66SLionel Sambuc * Copyright (c) 1997 Jason R. Thorpe. All rights reserved.
37280d8c66SLionel Sambuc *
38280d8c66SLionel Sambuc * This code is derived from software contributed to Berkeley by
39280d8c66SLionel Sambuc * James W. Williams of NASA Goddard Space Flight Center.
40280d8c66SLionel Sambuc *
41280d8c66SLionel Sambuc * Redistribution and use in source and binary forms, with or without
42280d8c66SLionel Sambuc * modification, are permitted provided that the following conditions
43280d8c66SLionel Sambuc * are met:
44280d8c66SLionel Sambuc * 1. Redistributions of source code must retain the above copyright
45280d8c66SLionel Sambuc * notice, this list of conditions and the following disclaimer.
46280d8c66SLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright
47280d8c66SLionel Sambuc * notice, this list of conditions and the following disclaimer in the
48280d8c66SLionel Sambuc * documentation and/or other materials provided with the distribution.
49280d8c66SLionel Sambuc * 3. All advertising materials mentioning features or use of this software
50280d8c66SLionel Sambuc * must display the following acknowledgement:
51280d8c66SLionel Sambuc * This product includes software developed by the University of
52280d8c66SLionel Sambuc * California, Berkeley and its contributors.
53280d8c66SLionel Sambuc * 4. Neither the name of the University nor the names of its contributors
54280d8c66SLionel Sambuc * may be used to endorse or promote products derived from this software
55280d8c66SLionel Sambuc * without specific prior written permission.
56280d8c66SLionel Sambuc *
57280d8c66SLionel Sambuc * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
58280d8c66SLionel Sambuc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
59280d8c66SLionel Sambuc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
60280d8c66SLionel Sambuc * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
61280d8c66SLionel Sambuc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
62280d8c66SLionel Sambuc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
63280d8c66SLionel Sambuc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
64280d8c66SLionel Sambuc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
65280d8c66SLionel Sambuc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
66280d8c66SLionel Sambuc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
67280d8c66SLionel Sambuc * SUCH DAMAGE.
68280d8c66SLionel Sambuc */
69280d8c66SLionel Sambuc
70280d8c66SLionel Sambuc #if HAVE_NBTOOL_CONFIG_H
71280d8c66SLionel Sambuc #include "nbtool_config.h"
72280d8c66SLionel Sambuc #endif
73280d8c66SLionel Sambuc
74280d8c66SLionel Sambuc #include <sys/cdefs.h>
75280d8c66SLionel Sambuc #if defined(__COPYRIGHT) && !defined(lint)
76280d8c66SLionel Sambuc __COPYRIGHT("@(#) Copyright (c) 1991, 1993\
77280d8c66SLionel Sambuc The Regents of the University of California. All rights reserved.");
78280d8c66SLionel Sambuc #endif /* not lint */
79280d8c66SLionel Sambuc
80280d8c66SLionel Sambuc #if defined(__RCSID) && !defined(lint)
81280d8c66SLionel Sambuc #if 0
82280d8c66SLionel Sambuc static char sccsid[] = "@(#)cksum.c 8.2 (Berkeley) 4/28/95";
83280d8c66SLionel Sambuc #endif
84*0a6a1f1dSLionel Sambuc __RCSID("$NetBSD: cksum.c,v 1.48 2015/06/16 22:54:10 christos Exp $");
85280d8c66SLionel Sambuc #endif /* not lint */
86280d8c66SLionel Sambuc
87280d8c66SLionel Sambuc #include <sys/types.h>
88280d8c66SLionel Sambuc
89280d8c66SLionel Sambuc #include <ctype.h>
90280d8c66SLionel Sambuc #include <err.h>
91280d8c66SLionel Sambuc #include <errno.h>
92280d8c66SLionel Sambuc #include <fcntl.h>
93280d8c66SLionel Sambuc #include <locale.h>
94280d8c66SLionel Sambuc #include <md2.h>
95280d8c66SLionel Sambuc #include <md4.h>
96280d8c66SLionel Sambuc #include <md5.h>
97280d8c66SLionel Sambuc #include <rmd160.h>
98280d8c66SLionel Sambuc #include <sha1.h>
99280d8c66SLionel Sambuc #include <sha2.h>
100280d8c66SLionel Sambuc #include <stdio.h>
101280d8c66SLionel Sambuc #include <stdlib.h>
102280d8c66SLionel Sambuc #include <string.h>
103280d8c66SLionel Sambuc #include <unistd.h>
104280d8c66SLionel Sambuc
105280d8c66SLionel Sambuc #include "extern.h"
106280d8c66SLionel Sambuc
107*0a6a1f1dSLionel Sambuc #define PRINT_NORMAL 0x01
108*0a6a1f1dSLionel Sambuc #define PRINT_QUIET 0x02
109*0a6a1f1dSLionel Sambuc
110280d8c66SLionel Sambuc typedef char *(*_filefunc)(const char *, char *);
111280d8c66SLionel Sambuc
112280d8c66SLionel Sambuc const struct hash {
113280d8c66SLionel Sambuc const char *progname;
114280d8c66SLionel Sambuc const char *hashname;
115280d8c66SLionel Sambuc void (*stringfunc)(const char *);
116280d8c66SLionel Sambuc void (*timetrialfunc)(void);
117280d8c66SLionel Sambuc void (*testsuitefunc)(void);
118280d8c66SLionel Sambuc void (*filterfunc)(int);
119280d8c66SLionel Sambuc char *(*filefunc)(const char *, char *);
120280d8c66SLionel Sambuc } hashes[] = {
121280d8c66SLionel Sambuc { "md2", "MD2",
122280d8c66SLionel Sambuc MD2String, MD2TimeTrial, MD2TestSuite,
123280d8c66SLionel Sambuc MD2Filter, MD2File },
124280d8c66SLionel Sambuc { "md4", "MD4",
125280d8c66SLionel Sambuc MD4String, MD4TimeTrial, MD4TestSuite,
126280d8c66SLionel Sambuc MD4Filter, MD4File },
127280d8c66SLionel Sambuc { "md5", "MD5",
128280d8c66SLionel Sambuc MD5String, MD5TimeTrial, MD5TestSuite,
129280d8c66SLionel Sambuc MD5Filter, MD5File },
130280d8c66SLionel Sambuc { "rmd160", "RMD160",
131280d8c66SLionel Sambuc RMD160String, RMD160TimeTrial, RMD160TestSuite,
132280d8c66SLionel Sambuc RMD160Filter, (_filefunc) RMD160File },
133280d8c66SLionel Sambuc { "sha1", "SHA1",
134280d8c66SLionel Sambuc SHA1String, SHA1TimeTrial, SHA1TestSuite,
135280d8c66SLionel Sambuc SHA1Filter, (_filefunc) SHA1File },
136280d8c66SLionel Sambuc { "sha256", "SHA256",
137280d8c66SLionel Sambuc SHA256_String, SHA256_TimeTrial, SHA256_TestSuite,
138280d8c66SLionel Sambuc SHA256_Filter, (_filefunc) SHA256_File },
139280d8c66SLionel Sambuc { "sha384", "SHA384",
140280d8c66SLionel Sambuc SHA384_String, SHA384_TimeTrial, SHA384_TestSuite,
141280d8c66SLionel Sambuc SHA384_Filter, (_filefunc) SHA384_File },
142280d8c66SLionel Sambuc { "sha512", "SHA512",
143280d8c66SLionel Sambuc SHA512_String, SHA512_TimeTrial, SHA512_TestSuite,
144280d8c66SLionel Sambuc SHA512_Filter, (_filefunc) SHA512_File },
145280d8c66SLionel Sambuc { .progname = NULL, },
146280d8c66SLionel Sambuc };
147280d8c66SLionel Sambuc
148280d8c66SLionel Sambuc static int hash_digest_file(char *, const struct hash *, int);
149280d8c66SLionel Sambuc __dead static void requirehash(const char *);
150280d8c66SLionel Sambuc __dead static void usage(void);
151280d8c66SLionel Sambuc
152280d8c66SLionel Sambuc int
main(int argc,char ** argv)153280d8c66SLionel Sambuc main(int argc, char **argv)
154280d8c66SLionel Sambuc {
15584d9c625SLionel Sambuc int ch, fd, rval, pflag, nohashstdin;
156280d8c66SLionel Sambuc u_int32_t val;
157280d8c66SLionel Sambuc off_t len;
158280d8c66SLionel Sambuc char *fn;
159280d8c66SLionel Sambuc const char *progname;
160280d8c66SLionel Sambuc int (*cfncn) (int, u_int32_t *, off_t *);
161280d8c66SLionel Sambuc void (*pfncn) (char *, u_int32_t, off_t);
162280d8c66SLionel Sambuc const struct hash *hash;
163*0a6a1f1dSLionel Sambuc int i, check_warn, do_check;
164*0a6a1f1dSLionel Sambuc int print_flags;
165280d8c66SLionel Sambuc
166280d8c66SLionel Sambuc cfncn = NULL;
167280d8c66SLionel Sambuc pfncn = NULL;
16884d9c625SLionel Sambuc pflag = nohashstdin = 0;
169280d8c66SLionel Sambuc check_warn = 0;
170280d8c66SLionel Sambuc do_check = 0;
171*0a6a1f1dSLionel Sambuc print_flags = 0;
172280d8c66SLionel Sambuc
173280d8c66SLionel Sambuc setlocale(LC_ALL, "");
174280d8c66SLionel Sambuc
175280d8c66SLionel Sambuc progname = getprogname();
176280d8c66SLionel Sambuc
177280d8c66SLionel Sambuc for (hash = hashes; hash->hashname != NULL; hash++)
178280d8c66SLionel Sambuc if (strcmp(progname, hash->progname) == 0)
179280d8c66SLionel Sambuc break;
180280d8c66SLionel Sambuc
181280d8c66SLionel Sambuc if (hash->hashname == NULL) {
182280d8c66SLionel Sambuc hash = NULL;
183280d8c66SLionel Sambuc
184280d8c66SLionel Sambuc if (!strcmp(progname, "sum")) {
185280d8c66SLionel Sambuc cfncn = csum1;
186280d8c66SLionel Sambuc pfncn = psum1;
187280d8c66SLionel Sambuc } else {
188280d8c66SLionel Sambuc cfncn = crc;
189280d8c66SLionel Sambuc pfncn = pcrc;
190280d8c66SLionel Sambuc }
191280d8c66SLionel Sambuc }
192280d8c66SLionel Sambuc
193*0a6a1f1dSLionel Sambuc while ((ch = getopt(argc, argv, "a:cno:pqs:twx")) != -1)
194280d8c66SLionel Sambuc switch(ch) {
195280d8c66SLionel Sambuc case 'a':
196280d8c66SLionel Sambuc if (hash) {
197*0a6a1f1dSLionel Sambuc warnx("illegal use of -a option");
198280d8c66SLionel Sambuc usage();
199280d8c66SLionel Sambuc }
200280d8c66SLionel Sambuc i = 0;
201280d8c66SLionel Sambuc while (hashes[i].hashname != NULL) {
202280d8c66SLionel Sambuc if (!strcasecmp(hashes[i].hashname, optarg)) {
203280d8c66SLionel Sambuc hash = &hashes[i];
204280d8c66SLionel Sambuc break;
205280d8c66SLionel Sambuc }
206280d8c66SLionel Sambuc i++;
207280d8c66SLionel Sambuc }
208280d8c66SLionel Sambuc if (hash == NULL) {
209280d8c66SLionel Sambuc if (!strcasecmp(optarg, "old1")) {
210280d8c66SLionel Sambuc cfncn = csum1;
211280d8c66SLionel Sambuc pfncn = psum1;
212280d8c66SLionel Sambuc } else if (!strcasecmp(optarg, "old2")) {
213280d8c66SLionel Sambuc cfncn = csum2;
214280d8c66SLionel Sambuc pfncn = psum2;
215280d8c66SLionel Sambuc } else if (!strcasecmp(optarg, "crc")) {
216280d8c66SLionel Sambuc cfncn = crc;
217280d8c66SLionel Sambuc pfncn = pcrc;
218280d8c66SLionel Sambuc } else {
219280d8c66SLionel Sambuc warnx("illegal argument to -a option");
220280d8c66SLionel Sambuc usage();
221280d8c66SLionel Sambuc }
222280d8c66SLionel Sambuc }
223280d8c66SLionel Sambuc break;
224280d8c66SLionel Sambuc case 'c':
225280d8c66SLionel Sambuc do_check = 1;
226280d8c66SLionel Sambuc break;
227280d8c66SLionel Sambuc case 'n':
228*0a6a1f1dSLionel Sambuc print_flags |= PRINT_NORMAL;
229280d8c66SLionel Sambuc break;
230280d8c66SLionel Sambuc case 'o':
231280d8c66SLionel Sambuc if (hash) {
232280d8c66SLionel Sambuc warnx("%s mutually exclusive with sum",
233280d8c66SLionel Sambuc hash->hashname);
234280d8c66SLionel Sambuc usage();
235280d8c66SLionel Sambuc }
236280d8c66SLionel Sambuc if (!strcmp(optarg, "1")) {
237280d8c66SLionel Sambuc cfncn = csum1;
238280d8c66SLionel Sambuc pfncn = psum1;
239280d8c66SLionel Sambuc } else if (!strcmp(optarg, "2")) {
240280d8c66SLionel Sambuc cfncn = csum2;
241280d8c66SLionel Sambuc pfncn = psum2;
242280d8c66SLionel Sambuc } else {
243280d8c66SLionel Sambuc warnx("illegal argument to -o option");
244280d8c66SLionel Sambuc usage();
245280d8c66SLionel Sambuc }
246280d8c66SLionel Sambuc break;
247280d8c66SLionel Sambuc case 'p':
248280d8c66SLionel Sambuc if (hash == NULL)
249280d8c66SLionel Sambuc requirehash("-p");
250280d8c66SLionel Sambuc pflag = 1;
251280d8c66SLionel Sambuc break;
252*0a6a1f1dSLionel Sambuc case 'q':
253*0a6a1f1dSLionel Sambuc print_flags |= PRINT_QUIET;
254*0a6a1f1dSLionel Sambuc break;
255280d8c66SLionel Sambuc case 's':
256280d8c66SLionel Sambuc if (hash == NULL)
257280d8c66SLionel Sambuc requirehash("-s");
258280d8c66SLionel Sambuc nohashstdin = 1;
259280d8c66SLionel Sambuc hash->stringfunc(optarg);
260280d8c66SLionel Sambuc break;
261280d8c66SLionel Sambuc case 't':
262280d8c66SLionel Sambuc if (hash == NULL)
263280d8c66SLionel Sambuc requirehash("-t");
264280d8c66SLionel Sambuc nohashstdin = 1;
265280d8c66SLionel Sambuc hash->timetrialfunc();
266280d8c66SLionel Sambuc break;
267280d8c66SLionel Sambuc case 'w':
268280d8c66SLionel Sambuc check_warn = 1;
269280d8c66SLionel Sambuc break;
270280d8c66SLionel Sambuc case 'x':
271280d8c66SLionel Sambuc if (hash == NULL)
272280d8c66SLionel Sambuc requirehash("-x");
273280d8c66SLionel Sambuc nohashstdin = 1;
274280d8c66SLionel Sambuc hash->testsuitefunc();
275280d8c66SLionel Sambuc break;
276280d8c66SLionel Sambuc case '?':
277280d8c66SLionel Sambuc default:
278280d8c66SLionel Sambuc usage();
279280d8c66SLionel Sambuc }
280280d8c66SLionel Sambuc argc -= optind;
281280d8c66SLionel Sambuc argv += optind;
282280d8c66SLionel Sambuc
283280d8c66SLionel Sambuc if (do_check) {
284280d8c66SLionel Sambuc /*
285280d8c66SLionel Sambuc * Verify checksums
286280d8c66SLionel Sambuc */
287280d8c66SLionel Sambuc FILE *f;
288280d8c66SLionel Sambuc char buf[BUFSIZ];
289280d8c66SLionel Sambuc char *s, *p_filename, *p_cksum;
290280d8c66SLionel Sambuc int l_filename, l_cksum;
291280d8c66SLionel Sambuc char filename[BUFSIZ];
292280d8c66SLionel Sambuc char cksum[BUFSIZ];
293280d8c66SLionel Sambuc int ok,cnt,badcnt;
294280d8c66SLionel Sambuc
295280d8c66SLionel Sambuc rval = 0;
296280d8c66SLionel Sambuc cnt = badcnt = 0;
297280d8c66SLionel Sambuc
298280d8c66SLionel Sambuc if (argc == 0) {
299280d8c66SLionel Sambuc f = fdopen(STDIN_FILENO, "r");
300280d8c66SLionel Sambuc } else {
301280d8c66SLionel Sambuc f = fopen(argv[0], "r");
302280d8c66SLionel Sambuc }
303280d8c66SLionel Sambuc if (f == NULL)
304280d8c66SLionel Sambuc err(1, "Cannot read %s",
305280d8c66SLionel Sambuc argc>0?argv[0]:"stdin");
306280d8c66SLionel Sambuc
307280d8c66SLionel Sambuc while(fgets(buf, sizeof(buf), f) != NULL) {
308280d8c66SLionel Sambuc s = strrchr(buf, '\n');
309280d8c66SLionel Sambuc if (s)
310280d8c66SLionel Sambuc *s = '\0';
311280d8c66SLionel Sambuc
312280d8c66SLionel Sambuc p_cksum = p_filename = NULL;
313280d8c66SLionel Sambuc
314280d8c66SLionel Sambuc p_filename = strchr(buf, '(');
315280d8c66SLionel Sambuc if (p_filename) {
316280d8c66SLionel Sambuc /*
317280d8c66SLionel Sambuc * Assume 'normal' output if there's a '('
318280d8c66SLionel Sambuc */
319280d8c66SLionel Sambuc p_filename += 1;
320*0a6a1f1dSLionel Sambuc print_flags &= ~(PRINT_NORMAL);
321280d8c66SLionel Sambuc
322280d8c66SLionel Sambuc p_cksum = strrchr(p_filename, ')');
323280d8c66SLionel Sambuc if (p_cksum == NULL) {
324280d8c66SLionel Sambuc if (check_warn)
325280d8c66SLionel Sambuc warnx("bogus format: %s. "
326280d8c66SLionel Sambuc "Skipping...",
327280d8c66SLionel Sambuc buf);
328280d8c66SLionel Sambuc rval = 1;
329280d8c66SLionel Sambuc continue;
330280d8c66SLionel Sambuc }
331280d8c66SLionel Sambuc p_cksum += 4;
332280d8c66SLionel Sambuc
333280d8c66SLionel Sambuc l_cksum = strlen(p_cksum);
334280d8c66SLionel Sambuc l_filename = p_cksum - p_filename - 4;
335280d8c66SLionel Sambuc
336280d8c66SLionel Sambuc /* Sanity check, and find proper hash if
337280d8c66SLionel Sambuc * it's not the same as the current program
338280d8c66SLionel Sambuc */
339280d8c66SLionel Sambuc if (hash == NULL ||
340280d8c66SLionel Sambuc strncmp(buf, hash->hashname,
341280d8c66SLionel Sambuc strlen(hash->hashname)) != 0) {
342280d8c66SLionel Sambuc /*
343280d8c66SLionel Sambuc * Search proper hash
344280d8c66SLionel Sambuc */
345280d8c66SLionel Sambuc const struct hash *nhash;
346280d8c66SLionel Sambuc
347280d8c66SLionel Sambuc for (nhash = hashes ;
348280d8c66SLionel Sambuc nhash->hashname != NULL;
349280d8c66SLionel Sambuc nhash++)
350280d8c66SLionel Sambuc if (strncmp(buf,
351280d8c66SLionel Sambuc nhash->hashname,
352280d8c66SLionel Sambuc strlen(nhash->hashname)) == 0)
353280d8c66SLionel Sambuc break;
354280d8c66SLionel Sambuc
355280d8c66SLionel Sambuc
356280d8c66SLionel Sambuc if (nhash->hashname == NULL) {
357280d8c66SLionel Sambuc if (check_warn)
358280d8c66SLionel Sambuc warnx("unknown hash: %s",
359280d8c66SLionel Sambuc buf);
360280d8c66SLionel Sambuc rval = 1;
361280d8c66SLionel Sambuc continue;
362280d8c66SLionel Sambuc } else {
363280d8c66SLionel Sambuc hash = nhash;
364280d8c66SLionel Sambuc }
365280d8c66SLionel Sambuc }
366280d8c66SLionel Sambuc
367280d8c66SLionel Sambuc } else {
368280d8c66SLionel Sambuc if (hash) {
369280d8c66SLionel Sambuc int nspaces;
370280d8c66SLionel Sambuc
371280d8c66SLionel Sambuc /*
372280d8c66SLionel Sambuc * 'normal' output, no (ck)sum
373280d8c66SLionel Sambuc */
374*0a6a1f1dSLionel Sambuc print_flags |= PRINT_NORMAL;
375280d8c66SLionel Sambuc nspaces = 1;
376280d8c66SLionel Sambuc
377280d8c66SLionel Sambuc p_cksum = buf;
378280d8c66SLionel Sambuc p_filename = strchr(buf, ' ');
379280d8c66SLionel Sambuc if (p_filename == NULL) {
380280d8c66SLionel Sambuc if (check_warn)
381280d8c66SLionel Sambuc warnx("no filename in %s? "
382280d8c66SLionel Sambuc "Skipping...", buf);
383280d8c66SLionel Sambuc rval = 1;
384280d8c66SLionel Sambuc continue;
385280d8c66SLionel Sambuc }
386280d8c66SLionel Sambuc while (isspace((int)*++p_filename))
387280d8c66SLionel Sambuc nspaces++;
388280d8c66SLionel Sambuc l_filename = strlen(p_filename);
389280d8c66SLionel Sambuc l_cksum = p_filename - buf - nspaces;
390280d8c66SLionel Sambuc } else {
391280d8c66SLionel Sambuc /*
392280d8c66SLionel Sambuc * sum/cksum output format
393280d8c66SLionel Sambuc */
394280d8c66SLionel Sambuc p_cksum = buf;
395280d8c66SLionel Sambuc s=strchr(p_cksum, ' ');
396280d8c66SLionel Sambuc if (s == NULL) {
397280d8c66SLionel Sambuc if (check_warn)
398280d8c66SLionel Sambuc warnx("bogus format: %s."
399280d8c66SLionel Sambuc " Skipping...",
400280d8c66SLionel Sambuc buf);
401280d8c66SLionel Sambuc rval = 1;
402280d8c66SLionel Sambuc continue;
403280d8c66SLionel Sambuc }
404280d8c66SLionel Sambuc l_cksum = s - p_cksum;
405280d8c66SLionel Sambuc
406280d8c66SLionel Sambuc p_filename = strrchr(buf, ' ');
407280d8c66SLionel Sambuc if (p_filename == NULL) {
408280d8c66SLionel Sambuc if (check_warn)
409280d8c66SLionel Sambuc warnx("no filename in %s?"
410280d8c66SLionel Sambuc " Skipping...",
411280d8c66SLionel Sambuc buf);
412280d8c66SLionel Sambuc rval = 1;
413280d8c66SLionel Sambuc continue;
414280d8c66SLionel Sambuc }
415280d8c66SLionel Sambuc p_filename++;
416280d8c66SLionel Sambuc l_filename = strlen(p_filename);
417280d8c66SLionel Sambuc }
418280d8c66SLionel Sambuc }
419280d8c66SLionel Sambuc
420280d8c66SLionel Sambuc strlcpy(filename, p_filename, l_filename+1);
421280d8c66SLionel Sambuc strlcpy(cksum, p_cksum, l_cksum+1);
422280d8c66SLionel Sambuc
423280d8c66SLionel Sambuc if (hash) {
424280d8c66SLionel Sambuc if (access(filename, R_OK) == 0
425280d8c66SLionel Sambuc && strcmp(cksum, hash->filefunc(filename, NULL)) == 0)
426280d8c66SLionel Sambuc ok = 1;
427280d8c66SLionel Sambuc else
428280d8c66SLionel Sambuc ok = 0;
429280d8c66SLionel Sambuc } else {
430280d8c66SLionel Sambuc if ((fd = open(filename, O_RDONLY, 0)) < 0) {
431280d8c66SLionel Sambuc if (check_warn)
432280d8c66SLionel Sambuc warn("%s", filename);
433280d8c66SLionel Sambuc rval = 1;
434280d8c66SLionel Sambuc ok = 0;
435280d8c66SLionel Sambuc } else {
436280d8c66SLionel Sambuc if (cfncn(fd, &val, &len))
437280d8c66SLionel Sambuc ok = 0;
438280d8c66SLionel Sambuc else {
439280d8c66SLionel Sambuc u_int32_t should_val;
440280d8c66SLionel Sambuc
441280d8c66SLionel Sambuc should_val =
442280d8c66SLionel Sambuc strtoul(cksum, NULL, 10);
443280d8c66SLionel Sambuc if (val == should_val)
444280d8c66SLionel Sambuc ok = 1;
445280d8c66SLionel Sambuc else
446280d8c66SLionel Sambuc ok = 0;
447280d8c66SLionel Sambuc }
448280d8c66SLionel Sambuc close(fd);
449280d8c66SLionel Sambuc }
450280d8c66SLionel Sambuc }
451280d8c66SLionel Sambuc
452280d8c66SLionel Sambuc if (! ok) {
453280d8c66SLionel Sambuc if (hash)
454280d8c66SLionel Sambuc printf("(%s) ", hash->hashname);
455280d8c66SLionel Sambuc printf("%s: FAILED\n", filename);
456280d8c66SLionel Sambuc badcnt++;
457280d8c66SLionel Sambuc }
458280d8c66SLionel Sambuc cnt++;
459280d8c66SLionel Sambuc
460280d8c66SLionel Sambuc }
461280d8c66SLionel Sambuc fclose(f);
462280d8c66SLionel Sambuc
463280d8c66SLionel Sambuc if (badcnt > 0)
464280d8c66SLionel Sambuc rval = 1;
465280d8c66SLionel Sambuc
466280d8c66SLionel Sambuc } else {
467280d8c66SLionel Sambuc /*
468280d8c66SLionel Sambuc * Calculate checksums
469280d8c66SLionel Sambuc */
470280d8c66SLionel Sambuc
471280d8c66SLionel Sambuc fd = STDIN_FILENO;
472280d8c66SLionel Sambuc fn = NULL;
473280d8c66SLionel Sambuc rval = 0;
474280d8c66SLionel Sambuc do {
475280d8c66SLionel Sambuc if (*argv) {
476280d8c66SLionel Sambuc fn = *argv++;
477280d8c66SLionel Sambuc if (hash != NULL) {
478*0a6a1f1dSLionel Sambuc if (hash_digest_file(fn, hash, print_flags)) {
479280d8c66SLionel Sambuc warn("%s", fn);
480280d8c66SLionel Sambuc rval = 1;
481280d8c66SLionel Sambuc }
482280d8c66SLionel Sambuc continue;
483280d8c66SLionel Sambuc }
484280d8c66SLionel Sambuc if ((fd = open(fn, O_RDONLY, 0)) < 0) {
485280d8c66SLionel Sambuc warn("%s", fn);
486280d8c66SLionel Sambuc rval = 1;
487280d8c66SLionel Sambuc continue;
488280d8c66SLionel Sambuc }
489280d8c66SLionel Sambuc } else if (hash && !nohashstdin) {
490280d8c66SLionel Sambuc hash->filterfunc(pflag);
491280d8c66SLionel Sambuc }
492280d8c66SLionel Sambuc
493280d8c66SLionel Sambuc if (hash == NULL) {
494280d8c66SLionel Sambuc if (cfncn(fd, &val, &len)) {
495280d8c66SLionel Sambuc warn("%s", fn ? fn : "stdin");
496280d8c66SLionel Sambuc rval = 1;
497280d8c66SLionel Sambuc } else
498280d8c66SLionel Sambuc pfncn(fn, val, len);
499280d8c66SLionel Sambuc (void)close(fd);
500280d8c66SLionel Sambuc }
501280d8c66SLionel Sambuc } while (*argv);
502280d8c66SLionel Sambuc }
503280d8c66SLionel Sambuc exit(rval);
504280d8c66SLionel Sambuc }
505280d8c66SLionel Sambuc
506280d8c66SLionel Sambuc static int
hash_digest_file(char * fn,const struct hash * hash,int flags)507*0a6a1f1dSLionel Sambuc hash_digest_file(char *fn, const struct hash *hash, int flags)
508280d8c66SLionel Sambuc {
509280d8c66SLionel Sambuc char *cp;
510280d8c66SLionel Sambuc
511280d8c66SLionel Sambuc cp = hash->filefunc(fn, NULL);
512280d8c66SLionel Sambuc if (cp == NULL)
513280d8c66SLionel Sambuc return 1;
514280d8c66SLionel Sambuc
515*0a6a1f1dSLionel Sambuc if (flags & PRINT_QUIET)
516*0a6a1f1dSLionel Sambuc printf("%s\n", cp);
517*0a6a1f1dSLionel Sambuc else if (flags & PRINT_NORMAL)
518280d8c66SLionel Sambuc printf("%s %s\n", cp, fn);
519280d8c66SLionel Sambuc else
520280d8c66SLionel Sambuc printf("%s (%s) = %s\n", hash->hashname, fn, cp);
521280d8c66SLionel Sambuc
522280d8c66SLionel Sambuc free(cp);
523280d8c66SLionel Sambuc
524280d8c66SLionel Sambuc return 0;
525280d8c66SLionel Sambuc }
526280d8c66SLionel Sambuc
527280d8c66SLionel Sambuc static void
requirehash(const char * flg)528280d8c66SLionel Sambuc requirehash(const char *flg)
529280d8c66SLionel Sambuc {
530280d8c66SLionel Sambuc warnx("%s flag requires `-a algorithm'", flg);
531280d8c66SLionel Sambuc usage();
532280d8c66SLionel Sambuc }
533280d8c66SLionel Sambuc
534280d8c66SLionel Sambuc static void
usage(void)535280d8c66SLionel Sambuc usage(void)
536280d8c66SLionel Sambuc {
537280d8c66SLionel Sambuc const char fileargs[] = "[file ... | -c [-w] [sumfile]]";
538280d8c66SLionel Sambuc const char sumargs[] = "[-n] [-a algorithm [-ptx] [-s string]] [-o 1|2]";
539280d8c66SLionel Sambuc const char hashargs[] = "[-nptx] [-s string]";
540280d8c66SLionel Sambuc
541280d8c66SLionel Sambuc (void)fprintf(stderr, "usage: cksum %s\n %s\n",
542280d8c66SLionel Sambuc sumargs, fileargs);
543280d8c66SLionel Sambuc (void)fprintf(stderr, " sum %s\n %s\n",
544280d8c66SLionel Sambuc sumargs, fileargs);
545280d8c66SLionel Sambuc (void)fprintf(stderr, " md2 %s %s\n", hashargs, fileargs);
546280d8c66SLionel Sambuc (void)fprintf(stderr, " md4 %s %s\n", hashargs, fileargs);
547280d8c66SLionel Sambuc (void)fprintf(stderr, " md5 %s %s\n", hashargs, fileargs);
548280d8c66SLionel Sambuc (void)fprintf(stderr, " rmd160 %s %s\n", hashargs, fileargs);
549280d8c66SLionel Sambuc (void)fprintf(stderr, " sha1 %s %s\n", hashargs, fileargs);
550280d8c66SLionel Sambuc exit(1);
551280d8c66SLionel Sambuc }
552