1 /* $NetBSD: cksum.c,v 1.24 2005/02/05 00:13:34 simonb Exp $ */ 2 3 /*- 4 * Copyright (c) 1991, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * James W. Williams of NASA Goddard Space Flight Center. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 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. 21 * 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 32 * SUCH DAMAGE. 33 */ 34 35 /*- 36 * Copyright (c) 1997 Jason R. Thorpe. All rights reserved. 37 * 38 * This code is derived from software contributed to Berkeley by 39 * James W. Williams of NASA Goddard Space Flight Center. 40 * 41 * Redistribution and use in source and binary forms, with or without 42 * modification, are permitted provided that the following conditions 43 * are met: 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. 56 * 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 67 * SUCH DAMAGE. 68 */ 69 70 #if HAVE_NBTOOL_CONFIG_H 71 #include "nbtool_config.h" 72 #endif 73 74 #include <sys/cdefs.h> 75 #if defined(__COPYRIGHT) && !defined(lint) 76 __COPYRIGHT("@(#) Copyright (c) 1991, 1993\n\ 77 The Regents of the University of California. All rights reserved.\n"); 78 #endif /* not lint */ 79 80 #if defined(__RCSID) && !defined(lint) 81 #if 0 82 static char sccsid[] = "@(#)cksum.c 8.2 (Berkeley) 4/28/95"; 83 #endif 84 __RCSID("$NetBSD: cksum.c,v 1.24 2005/02/05 00:13:34 simonb Exp $"); 85 #endif /* not lint */ 86 87 #include <sys/cdefs.h> 88 #include <sys/types.h> 89 90 #include <err.h> 91 #include <errno.h> 92 #include <fcntl.h> 93 #include <locale.h> 94 #include <md5.h> 95 #include <md4.h> 96 #include <md2.h> 97 #include <sha1.h> 98 #include <rmd160.h> 99 #include <stdio.h> 100 #include <stdlib.h> 101 #include <string.h> 102 #include <unistd.h> 103 104 #include "extern.h" 105 106 #define HASH_MD2 0 107 #define HASH_MD4 1 108 #define HASH_MD5 2 109 #define HASH_SHA1 3 110 #define HASH_RMD160 4 111 112 typedef char *(*_filefunc)(const char *, char *); 113 114 struct hash { 115 const char *progname; 116 const char *hashname; 117 void (*stringfunc)(const char *); 118 void (*timetrialfunc)(void); 119 void (*testsuitefunc)(void); 120 void (*filterfunc)(int); 121 char *(*filefunc)(const char *, char *); 122 } hashes[] = { 123 { "md2", "MD2", 124 MD2String, MD2TimeTrial, MD2TestSuite, 125 MD2Filter, MD2File }, 126 { "md4", "MD4", 127 MD4String, MD4TimeTrial, MD4TestSuite, 128 MD4Filter, MD4File }, 129 { "md5", "MD5", 130 MD5String, MD5TimeTrial, MD5TestSuite, 131 MD5Filter, MD5File }, 132 { "sha1", "SHA1", 133 SHA1String, SHA1TimeTrial, SHA1TestSuite, 134 SHA1Filter, (_filefunc) SHA1File }, 135 { "rmd160", "RMD160", 136 RMD160String, RMD160TimeTrial, RMD160TestSuite, 137 RMD160Filter, (_filefunc) RMD160File }, 138 { NULL } 139 }; 140 141 int hash_digest_file(char *, struct hash *, int); 142 void requirehash(const char *); 143 void usage(void); 144 145 int 146 main(int argc, char **argv) 147 { 148 int ch, fd, rval, dosum, pflag, nohashstdin; 149 u_int32_t val; 150 off_t len; 151 char *fn; 152 const char *progname; 153 int (*cfncn) (int, u_int32_t *, off_t *); 154 void (*pfncn) (char *, u_int32_t, off_t); 155 struct hash *hash; 156 int normal; 157 158 cfncn = NULL; 159 pfncn = NULL; 160 dosum = pflag = nohashstdin = 0; 161 normal = 0; 162 163 setlocale(LC_ALL, ""); 164 165 progname = getprogname(); 166 167 for (hash = hashes; hash->hashname != NULL; hash++) 168 if (strcmp(progname, hash->progname) == 0) 169 break; 170 171 if (hash->hashname == NULL) { 172 hash = NULL; 173 174 if (!strcmp(progname, "sum")) { 175 dosum = 1; 176 cfncn = csum1; 177 pfncn = psum1; 178 } else { 179 cfncn = crc; 180 pfncn = pcrc; 181 } 182 } 183 184 while ((ch = getopt(argc, argv, "mno:ps:tx12456")) != -1) 185 switch(ch) { 186 case '2': 187 if (dosum) { 188 warnx("sum mutually exclusive with md2"); 189 usage(); 190 } 191 hash = &hashes[HASH_MD2]; 192 break; 193 case '4': 194 if (dosum) { 195 warnx("sum mutually exclusive with md4"); 196 usage(); 197 } 198 hash = &hashes[HASH_MD4]; 199 break; 200 case 'm': 201 case '5': 202 if (dosum) { 203 warnx("sum mutually exclusive with md5"); 204 usage(); 205 } 206 hash = &hashes[HASH_MD5]; 207 break; 208 case '1': 209 if (dosum) { 210 warnx("sum mutually exclusive with sha1"); 211 usage(); 212 } 213 hash = &hashes[HASH_SHA1]; 214 break; 215 case '6': 216 if (dosum) { 217 warnx("sum mutually exclusive with rmd160"); 218 usage(); 219 } 220 hash = &hashes[HASH_RMD160]; 221 break; 222 case 'n': 223 normal = 1; 224 break; 225 case 'o': 226 if (hash) { 227 warnx("%s mutually exclusive with sum", 228 hash->hashname); 229 usage(); 230 } 231 if (!strcmp(optarg, "1")) { 232 cfncn = csum1; 233 pfncn = psum1; 234 } else if (!strcmp(optarg, "2")) { 235 cfncn = csum2; 236 pfncn = psum2; 237 } else { 238 warnx("illegal argument to -o option"); 239 usage(); 240 } 241 break; 242 case 'p': 243 if (hash == NULL) 244 requirehash("-p"); 245 pflag = 1; 246 break; 247 case 's': 248 if (hash == NULL) 249 requirehash("-s"); 250 nohashstdin = 1; 251 hash->stringfunc(optarg); 252 break; 253 case 't': 254 if (hash == NULL) 255 requirehash("-t"); 256 nohashstdin = 1; 257 hash->timetrialfunc(); 258 break; 259 case 'x': 260 if (hash == NULL) 261 requirehash("-x"); 262 nohashstdin = 1; 263 hash->testsuitefunc(); 264 break; 265 case '?': 266 default: 267 usage(); 268 } 269 argc -= optind; 270 argv += optind; 271 272 fd = STDIN_FILENO; 273 fn = NULL; 274 rval = 0; 275 do { 276 if (*argv) { 277 fn = *argv++; 278 if (hash != NULL) { 279 if (hash_digest_file(fn, hash, normal)) { 280 warn("%s", fn); 281 rval = 1; 282 } 283 continue; 284 } 285 if ((fd = open(fn, O_RDONLY, 0)) < 0) { 286 warn("%s", fn); 287 rval = 1; 288 continue; 289 } 290 } else if (hash && !nohashstdin) { 291 hash->filterfunc(pflag); 292 } 293 294 if (hash == NULL) { 295 if (cfncn(fd, &val, &len)) { 296 warn("%s", fn ? fn : "stdin"); 297 rval = 1; 298 } else 299 pfncn(fn, val, len); 300 (void)close(fd); 301 } 302 } while (*argv); 303 exit(rval); 304 } 305 306 int 307 hash_digest_file(char *fn, struct hash *hash, int normal) 308 { 309 char buf[41], *cp; 310 311 cp = hash->filefunc(fn, buf); 312 if (cp == NULL) 313 return 1; 314 315 if (normal) 316 printf("%s %s\n", cp, fn); 317 else 318 printf("%s (%s) = %s\n", hash->hashname, fn, cp); 319 return 0; 320 } 321 322 void 323 requirehash(const char *flg) 324 { 325 warnx("%s flag requires `md2', `md4', `md5', `sha1', or `rmd160'", 326 flg); 327 usage(); 328 } 329 330 void 331 usage(void) 332 { 333 334 (void)fprintf(stderr, "usage: cksum [-n] [-m | -1 | -2 | -4 | -5 | -6 | [-o 1 | 2]] [file ...]\n"); 335 (void)fprintf(stderr, " sum [file ...]\n"); 336 (void)fprintf(stderr, 337 " md2 [-n] [-p | -t | -x | -s string] [file ...]\n"); 338 (void)fprintf(stderr, 339 " md4 [-n] [-p | -t | -x | -s string] [file ...]\n"); 340 (void)fprintf(stderr, 341 " md5 [-n] [-p | -t | -x | -s string] [file ...]\n"); 342 (void)fprintf(stderr, 343 " sha1 [-n] [-p | -t | -x | -s string] [file ...]\n"); 344 (void)fprintf(stderr, 345 " rmd160 [-n] [-p | -t | -x | -s string] [file ...]\n"); 346 exit(1); 347 } 348