cksum.c revision 1.13 1 /* $NetBSD: cksum.c,v 1.13 2001/03/20 18:46:25 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 #ifndef 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 #ifndef 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.13 2001/03/20 18:46:25 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 *));
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
125 cfncn = NULL;
126 pfncn = NULL;
127 dosum = pflag = nohashstdin = 0;
128
129 setlocale(LC_ALL, "");
130
131 progname = getprogname();
132
133 for (hash = hashes; hash->hashname != NULL; hash++)
134 if (strcmp(progname, hash->progname) == 0)
135 break;
136
137 if (hash->hashname == NULL) {
138 hash = NULL;
139
140 if (!strcmp(progname, "sum")) {
141 dosum = 1;
142 cfncn = csum1;
143 pfncn = psum1;
144 } else {
145 cfncn = crc;
146 pfncn = pcrc;
147 }
148 }
149
150 while ((ch = getopt(argc, argv, "mo:ps:tx12456")) != -1)
151 switch(ch) {
152 case '2':
153 if (dosum) {
154 warnx("sum mutually exclusive with md2");
155 usage();
156 }
157 hash = &hashes[HASH_MD2];
158 break;
159 case '4':
160 if (dosum) {
161 warnx("sum mutually exclusive with md4");
162 usage();
163 }
164 hash = &hashes[HASH_MD4];
165 break;
166 case 'm':
167 case '5':
168 if (dosum) {
169 warnx("sum mutually exclusive with md5");
170 usage();
171 }
172 hash = &hashes[HASH_MD5];
173 break;
174 case '1':
175 if (dosum) {
176 warnx("sum mutually exclusive with sha1");
177 usage();
178 }
179 hash = &hashes[HASH_SHA1];
180 break;
181 case '6':
182 if (dosum) {
183 warnx("sum mutually exclusive with rmd160");
184 usage();
185 }
186 hash = &hashes[HASH_RMD160];
187 break;
188 case 'o':
189 if (hash) {
190 warnx("%s mutually exclusive with sum",
191 hash->hashname);
192 usage();
193 }
194 if (!strcmp(optarg, "1")) {
195 cfncn = csum1;
196 pfncn = psum1;
197 } else if (!strcmp(optarg, "2")) {
198 cfncn = csum2;
199 pfncn = psum2;
200 } else {
201 warnx("illegal argument to -o option");
202 usage();
203 }
204 break;
205 case 'p':
206 if (hash == NULL)
207 requirehash("-p");
208 pflag = 1;
209 break;
210 case 's':
211 if (hash == NULL)
212 requirehash("-s");
213 nohashstdin = 1;
214 hash->stringfunc(optarg);
215 break;
216 case 't':
217 if (hash == NULL)
218 requirehash("-t");
219 nohashstdin = 1;
220 hash->timetrialfunc();
221 break;
222 case 'x':
223 if (hash == NULL)
224 requirehash("-x");
225 nohashstdin = 1;
226 hash->testsuitefunc();
227 break;
228 case '?':
229 default:
230 usage();
231 }
232 argc -= optind;
233 argv += optind;
234
235 fd = STDIN_FILENO;
236 fn = NULL;
237 rval = 0;
238 do {
239 if (*argv) {
240 fn = *argv++;
241 if (hash != NULL) {
242 if (hash_digest_file(fn, hash)) {
243 warn("%s", fn);
244 rval = 1;
245 }
246 continue;
247 }
248 if ((fd = open(fn, O_RDONLY, 0)) < 0) {
249 warn("%s", fn);
250 rval = 1;
251 continue;
252 }
253 } else if (hash && !nohashstdin) {
254 hash->filterfunc(pflag);
255 }
256
257 if (hash == NULL) {
258 if (cfncn(fd, &val, &len)) {
259 warn("%s", fn ? fn : "stdin");
260 rval = 1;
261 } else
262 pfncn(fn, val, len);
263 (void)close(fd);
264 }
265 } while (*argv);
266 exit(rval);
267 }
268
269 int
270 hash_digest_file(fn, hash)
271 char *fn;
272 struct hash *hash;
273 {
274 char buf[41], *cp;
275
276 cp = hash->filefunc(fn, buf);
277 if (cp == NULL)
278 return (1);
279
280 printf("%s (%s) = %s\n", hash->hashname, fn, cp);
281 return (0);
282 }
283
284 void
285 requirehash(flg)
286 const char *flg;
287 {
288 warnx("%s flag requires `md2', `md4', `md5', `sha1', or `rmd160'",
289 flg);
290 usage();
291 }
292
293 void
294 usage()
295 {
296
297 (void)fprintf(stderr, "usage: cksum [-m | [-o 1 | 2]] [file ...]\n");
298 (void)fprintf(stderr, " sum [file ...]\n");
299 (void)fprintf(stderr,
300 " md2 [-p | -t | -x | -s string] [file ...]\n");
301 (void)fprintf(stderr,
302 " md4 [-p | -t | -x | -s string] [file ...]\n");
303 (void)fprintf(stderr,
304 " md5 [-p | -t | -x | -s string] [file ...]\n");
305 (void)fprintf(stderr,
306 " sha1 [-p | -t | -x | -s string] [file ...]\n");
307 (void)fprintf(stderr,
308 " rmd160 [-p | -t | -x | -s string] [file ...]\n");
309 exit(1);
310 }
311