1 /* $NetBSD: cksum.c,v 1.21 2004/07/09 11:44:30 wiz 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.21 2004/07/09 11:44:30 wiz 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 main __P((int, char **)); 142 int hash_digest_file __P((char *, struct hash *, int)); 143 void requirehash __P((const char *)); 144 void usage __P((void)); 145 146 int 147 main(argc, argv) 148 int argc; 149 char **argv; 150 { 151 register int ch, fd, rval, dosum, pflag, nohashstdin; 152 u_int32_t val; 153 off_t len; 154 char *fn; 155 const char *progname; 156 int (*cfncn) __P((int, u_int32_t *, off_t *)); 157 void (*pfncn) __P((char *, u_int32_t, off_t)); 158 struct hash *hash; 159 int normal; 160 161 cfncn = NULL; 162 pfncn = NULL; 163 dosum = pflag = nohashstdin = 0; 164 normal = 0; 165 166 setlocale(LC_ALL, ""); 167 168 progname = getprogname(); 169 170 for (hash = hashes; hash->hashname != NULL; hash++) 171 if (strcmp(progname, hash->progname) == 0) 172 break; 173 174 if (hash->hashname == NULL) { 175 hash = NULL; 176 177 if (!strcmp(progname, "sum")) { 178 dosum = 1; 179 cfncn = csum1; 180 pfncn = psum1; 181 } else { 182 cfncn = crc; 183 pfncn = pcrc; 184 } 185 } 186 187 while ((ch = getopt(argc, argv, "mno:ps:tx12456")) != -1) 188 switch(ch) { 189 case '2': 190 if (dosum) { 191 warnx("sum mutually exclusive with md2"); 192 usage(); 193 } 194 hash = &hashes[HASH_MD2]; 195 break; 196 case '4': 197 if (dosum) { 198 warnx("sum mutually exclusive with md4"); 199 usage(); 200 } 201 hash = &hashes[HASH_MD4]; 202 break; 203 case 'm': 204 case '5': 205 if (dosum) { 206 warnx("sum mutually exclusive with md5"); 207 usage(); 208 } 209 hash = &hashes[HASH_MD5]; 210 break; 211 case '1': 212 if (dosum) { 213 warnx("sum mutually exclusive with sha1"); 214 usage(); 215 } 216 hash = &hashes[HASH_SHA1]; 217 break; 218 case '6': 219 if (dosum) { 220 warnx("sum mutually exclusive with rmd160"); 221 usage(); 222 } 223 hash = &hashes[HASH_RMD160]; 224 break; 225 case 'n': 226 normal = 1; 227 break; 228 case 'o': 229 if (hash) { 230 warnx("%s mutually exclusive with sum", 231 hash->hashname); 232 usage(); 233 } 234 if (!strcmp(optarg, "1")) { 235 cfncn = csum1; 236 pfncn = psum1; 237 } else if (!strcmp(optarg, "2")) { 238 cfncn = csum2; 239 pfncn = psum2; 240 } else { 241 warnx("illegal argument to -o option"); 242 usage(); 243 } 244 break; 245 case 'p': 246 if (hash == NULL) 247 requirehash("-p"); 248 pflag = 1; 249 break; 250 case 's': 251 if (hash == NULL) 252 requirehash("-s"); 253 nohashstdin = 1; 254 hash->stringfunc(optarg); 255 break; 256 case 't': 257 if (hash == NULL) 258 requirehash("-t"); 259 nohashstdin = 1; 260 hash->timetrialfunc(); 261 break; 262 case 'x': 263 if (hash == NULL) 264 requirehash("-x"); 265 nohashstdin = 1; 266 hash->testsuitefunc(); 267 break; 268 case '?': 269 default: 270 usage(); 271 } 272 argc -= optind; 273 argv += optind; 274 275 fd = STDIN_FILENO; 276 fn = NULL; 277 rval = 0; 278 do { 279 if (*argv) { 280 fn = *argv++; 281 if (hash != NULL) { 282 if (hash_digest_file(fn, hash, normal)) { 283 warn("%s", fn); 284 rval = 1; 285 } 286 continue; 287 } 288 if ((fd = open(fn, O_RDONLY, 0)) < 0) { 289 warn("%s", fn); 290 rval = 1; 291 continue; 292 } 293 } else if (hash && !nohashstdin) { 294 hash->filterfunc(pflag); 295 } 296 297 if (hash == NULL) { 298 if (cfncn(fd, &val, &len)) { 299 warn("%s", fn ? fn : "stdin"); 300 rval = 1; 301 } else 302 pfncn(fn, val, len); 303 (void)close(fd); 304 } 305 } while (*argv); 306 exit(rval); 307 } 308 309 int 310 hash_digest_file(fn, hash, normal) 311 char *fn; 312 struct hash *hash; 313 int normal; 314 { 315 char buf[41], *cp; 316 317 cp = hash->filefunc(fn, buf); 318 if (cp == NULL) 319 return (1); 320 321 if (normal) 322 printf("%s %s\n", cp, fn); 323 else 324 printf("%s (%s) = %s\n", hash->hashname, fn, cp); 325 return (0); 326 } 327 328 void 329 requirehash(flg) 330 const char *flg; 331 { 332 warnx("%s flag requires `md2', `md4', `md5', `sha1', or `rmd160'", 333 flg); 334 usage(); 335 } 336 337 void 338 usage() 339 { 340 341 (void)fprintf(stderr, "usage: cksum [-n] [-m | -1 | -2 | -4 | -5 | -6 | [-o 1 | 2]] [file ...]\n"); 342 (void)fprintf(stderr, " sum [file ...]\n"); 343 (void)fprintf(stderr, 344 " md2 [-n] [-p | -t | -x | -s string] [file ...]\n"); 345 (void)fprintf(stderr, 346 " md4 [-n] [-p | -t | -x | -s string] [file ...]\n"); 347 (void)fprintf(stderr, 348 " md5 [-n] [-p | -t | -x | -s string] [file ...]\n"); 349 (void)fprintf(stderr, 350 " sha1 [-n] [-p | -t | -x | -s string] [file ...]\n"); 351 (void)fprintf(stderr, 352 " rmd160 [-n] [-p | -t | -x | -s string] [file ...]\n"); 353 exit(1); 354 } 355