cksum.c revision 1.17 1 /* $NetBSD: cksum.c,v 1.17 2002/10/18 20:30:13 atatat Exp $ */
2
3 /*-
4 * Copyright (c) 1997 Jason R. Thorpe. All rights reserved.
5 * Copyright (c) 1991, 1993
6 * The Regents of the University of California. All rights reserved.
7 *
8 * This code is derived from software contributed to Berkeley by
9 * James W. Williams of NASA Goddard Space Flight Center.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the University of
22 * California, Berkeley and its contributors.
23 * 4. Neither the name of the University nor the names of its contributors
24 * may be used to endorse or promote products derived from this software
25 * without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
38 */
39
40 #include <sys/cdefs.h>
41 #if defined(__COPYRIGHT) && !defined(lint)
42 __COPYRIGHT("@(#) Copyright (c) 1991, 1993\n\
43 The Regents of the University of California. All rights reserved.\n");
44 #endif /* not lint */
45
46 #if defined(__RCSID) && !defined(lint)
47 #if 0
48 static char sccsid[] = "@(#)cksum.c 8.2 (Berkeley) 4/28/95";
49 #endif
50 __RCSID("$NetBSD: cksum.c,v 1.17 2002/10/18 20:30:13 atatat Exp $");
51 #endif /* not lint */
52
53 #include <sys/cdefs.h>
54 #include <sys/types.h>
55
56 #include <err.h>
57 #include <errno.h>
58 #include <fcntl.h>
59 #include <locale.h>
60 #include <md5.h>
61 #include <md4.h>
62 #include <md2.h>
63 #include <sha1.h>
64 #include <rmd160.h>
65 #include <stdio.h>
66 #include <stdlib.h>
67 #include <string.h>
68 #include <unistd.h>
69
70 #include "extern.h"
71
72 #define HASH_MD2 0
73 #define HASH_MD4 1
74 #define HASH_MD5 2
75 #define HASH_SHA1 3
76 #define HASH_RMD160 4
77
78 typedef char *(*_filefunc)(const char *, char *);
79
80 struct hash {
81 const char *progname;
82 const char *hashname;
83 void (*stringfunc)(const char *);
84 void (*timetrialfunc)(void);
85 void (*testsuitefunc)(void);
86 void (*filterfunc)(int);
87 char *(*filefunc)(const char *, char *);
88 } hashes[] = {
89 { "md2", "MD2",
90 MD2String, MD2TimeTrial, MD2TestSuite,
91 MD2Filter, MD2File },
92 { "md4", "MD4",
93 MD4String, MD4TimeTrial, MD4TestSuite,
94 MD4Filter, MD4File },
95 { "md5", "MD5",
96 MD5String, MD5TimeTrial, MD5TestSuite,
97 MD5Filter, MD5File },
98 { "sha1", "SHA1",
99 SHA1String, SHA1TimeTrial, SHA1TestSuite,
100 SHA1Filter, (_filefunc) SHA1File },
101 { "rmd160", "RMD160",
102 RMD160String, RMD160TimeTrial, RMD160TestSuite,
103 RMD160Filter, (_filefunc) RMD160File },
104 { NULL }
105 };
106
107 int main __P((int, char **));
108 int hash_digest_file __P((char *, struct hash *, int));
109 void requirehash __P((const char *));
110 void usage __P((void));
111
112 int
113 main(argc, argv)
114 int argc;
115 char **argv;
116 {
117 register int ch, fd, rval, dosum, pflag, nohashstdin;
118 u_int32_t len, val;
119 char *fn;
120 const char *progname;
121 int (*cfncn) __P((int, u_int32_t *, u_int32_t *));
122 void (*pfncn) __P((char *, u_int32_t, u_int32_t));
123 struct hash *hash;
124 int normal;
125
126 cfncn = NULL;
127 pfncn = NULL;
128 dosum = pflag = nohashstdin = 0;
129 normal = 0;
130
131 setlocale(LC_ALL, "");
132
133 progname = getprogname();
134
135 for (hash = hashes; hash->hashname != NULL; hash++)
136 if (strcmp(progname, hash->progname) == 0)
137 break;
138
139 if (hash->hashname == NULL) {
140 hash = NULL;
141
142 if (!strcmp(progname, "sum")) {
143 dosum = 1;
144 cfncn = csum1;
145 pfncn = psum1;
146 } else {
147 cfncn = crc;
148 pfncn = pcrc;
149 }
150 }
151
152 while ((ch = getopt(argc, argv, "mno:ps:tx12456")) != -1)
153 switch(ch) {
154 case '2':
155 if (dosum) {
156 warnx("sum mutually exclusive with md2");
157 usage();
158 }
159 hash = &hashes[HASH_MD2];
160 break;
161 case '4':
162 if (dosum) {
163 warnx("sum mutually exclusive with md4");
164 usage();
165 }
166 hash = &hashes[HASH_MD4];
167 break;
168 case 'm':
169 case '5':
170 if (dosum) {
171 warnx("sum mutually exclusive with md5");
172 usage();
173 }
174 hash = &hashes[HASH_MD5];
175 break;
176 case '1':
177 if (dosum) {
178 warnx("sum mutually exclusive with sha1");
179 usage();
180 }
181 hash = &hashes[HASH_SHA1];
182 break;
183 case '6':
184 if (dosum) {
185 warnx("sum mutually exclusive with rmd160");
186 usage();
187 }
188 hash = &hashes[HASH_RMD160];
189 break;
190 case 'n':
191 normal = 1;
192 break;
193 case 'o':
194 if (hash) {
195 warnx("%s mutually exclusive with sum",
196 hash->hashname);
197 usage();
198 }
199 if (!strcmp(optarg, "1")) {
200 cfncn = csum1;
201 pfncn = psum1;
202 } else if (!strcmp(optarg, "2")) {
203 cfncn = csum2;
204 pfncn = psum2;
205 } else {
206 warnx("illegal argument to -o option");
207 usage();
208 }
209 break;
210 case 'p':
211 if (hash == NULL)
212 requirehash("-p");
213 pflag = 1;
214 break;
215 case 's':
216 if (hash == NULL)
217 requirehash("-s");
218 nohashstdin = 1;
219 hash->stringfunc(optarg);
220 break;
221 case 't':
222 if (hash == NULL)
223 requirehash("-t");
224 nohashstdin = 1;
225 hash->timetrialfunc();
226 break;
227 case 'x':
228 if (hash == NULL)
229 requirehash("-x");
230 nohashstdin = 1;
231 hash->testsuitefunc();
232 break;
233 case '?':
234 default:
235 usage();
236 }
237 argc -= optind;
238 argv += optind;
239
240 fd = STDIN_FILENO;
241 fn = NULL;
242 rval = 0;
243 do {
244 if (*argv) {
245 fn = *argv++;
246 if (hash != NULL) {
247 if (hash_digest_file(fn, hash, normal)) {
248 warn("%s", fn);
249 rval = 1;
250 }
251 continue;
252 }
253 if ((fd = open(fn, O_RDONLY, 0)) < 0) {
254 warn("%s", fn);
255 rval = 1;
256 continue;
257 }
258 } else if (hash && !nohashstdin) {
259 hash->filterfunc(pflag);
260 }
261
262 if (hash == NULL) {
263 if (cfncn(fd, &val, &len)) {
264 warn("%s", fn ? fn : "stdin");
265 rval = 1;
266 } else
267 pfncn(fn, val, len);
268 (void)close(fd);
269 }
270 } while (*argv);
271 exit(rval);
272 }
273
274 int
275 hash_digest_file(fn, hash, normal)
276 char *fn;
277 struct hash *hash;
278 int normal;
279 {
280 char buf[41], *cp;
281
282 cp = hash->filefunc(fn, buf);
283 if (cp == NULL)
284 return (1);
285
286 if (normal)
287 printf("%s %s\n", cp, fn);
288 else
289 printf("%s (%s) = %s\n", hash->hashname, fn, cp);
290 return (0);
291 }
292
293 void
294 requirehash(flg)
295 const char *flg;
296 {
297 warnx("%s flag requires `md2', `md4', `md5', `sha1', or `rmd160'",
298 flg);
299 usage();
300 }
301
302 void
303 usage()
304 {
305
306 (void)fprintf(stderr, "usage: cksum [-m | [-o 1 | 2]] [file ...]\n");
307 (void)fprintf(stderr, " sum [file ...]\n");
308 (void)fprintf(stderr,
309 " md2 [-n] [-p | -t | -x | -s string] [file ...]\n");
310 (void)fprintf(stderr,
311 " md4 [-n] [-p | -t | -x | -s string] [file ...]\n");
312 (void)fprintf(stderr,
313 " md5 [-n] [-p | -t | -x | -s string] [file ...]\n");
314 (void)fprintf(stderr,
315 " sha1 [-n] [-p | -t | -x | -s string] [file ...]\n");
316 (void)fprintf(stderr,
317 " rmd160 [-n] [-p | -t | -x | -s string] [file ...]\n");
318 exit(1);
319 }
320