Fixup fromcvs/togit conversion
[minix-pkgsrc.git] / pkgtools / digest / files / digest.c
blob4fd5ef97d42921976bd833e3d440a1ced7dbdebb
1 /* $NetBSD: digest.c,v 1.14 2007/09/14 08:12:29 joerg Exp $ */
3 /*
4 * Copyright (c) 2001-2005 Alistair G. Crooks. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by Alistair G. Crooks.
17 * 4. The name of the author may not be used to endorse or promote
18 * products derived from this software without specific prior written
19 * permission.
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
22 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
27 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 #ifdef HAVE_CONFIG_H
34 #include "config.h"
35 #endif
37 #ifndef lint
38 __COPYRIGHT("@(#) Copyright (c) 2001-2005 \
39 The NetBSD Foundation, Inc. All rights reserved.");
40 __RCSID("$NetBSD: digest.c,v 1.14 2007/09/14 08:12:29 joerg Exp $");
41 #endif
44 #ifdef HAVE_ERRNO_H
45 #include <errno.h>
46 #endif
47 #ifdef HAVE_LOCALE_H
48 #include <locale.h>
49 #endif
50 #include <md5.h>
51 #include <rmd160.h>
52 #include <sha1.h>
53 #include <sha2.h>
54 #include <stdio.h>
55 #include <stdlib.h>
56 #include <string.h>
57 #include <tiger.h>
58 #include <whirlpool.h>
59 #ifdef HAVE_UNISTD_H
60 #include <unistd.h>
61 #endif
63 typedef void (*HASH_init)(void *);
64 typedef void (*HASH_update)(void *, const uint8_t *, size_t);
65 typedef char *(*HASH_end)(void *, char *);
66 typedef char *(*HASH_file)(char *, char *);
68 /* this struct defines a message digest algorithm */
69 typedef struct alg_t {
70 const char *name;
71 int hash_len;
72 HASH_init hash_init;
73 HASH_update hash_update;
74 HASH_end hash_end;
75 HASH_file hash_file;
76 union {
77 MD5_CTX m;
78 SHA1_CTX sha;
79 RMD160_CTX rmd;
80 SHA256_CTX sha256;
81 SHA384_CTX sha384;
82 SHA512_CTX sha512;
83 tiger_context_t tiger;
84 whirlpool_context_t whirlpool;
85 } hash_ctx, hash_ctx2;
86 } alg_t;
88 /* list of supported message digest algorithms */
89 static alg_t algorithms[] = {
90 { "MD5", 16,
91 (HASH_init) MD5Init, (HASH_update) MD5Update,
92 (HASH_end) MD5End, (HASH_file) MD5File },
93 { "RMD160", 20,
94 (HASH_init) RMD160Init, (HASH_update) RMD160Update,
95 (HASH_end) RMD160End, (HASH_file) RMD160File },
96 { "SHA1", 20,
97 (HASH_init) SHA1Init, (HASH_update) SHA1Update,
98 (HASH_end) SHA1End, (HASH_file) SHA1File },
99 { "SHA256", SHA256_DIGEST_LENGTH,
100 (HASH_init) SHA256_Init, (HASH_update) SHA256_Update,
101 (HASH_end) SHA256_End, (HASH_file) SHA256_File },
102 { "SHA384", SHA384_DIGEST_LENGTH,
103 (HASH_init) SHA384_Init, (HASH_update) SHA384_Update,
104 (HASH_end) SHA384_End, (HASH_file) SHA384_File },
105 { "SHA512", SHA512_DIGEST_LENGTH,
106 (HASH_init) SHA512_Init, (HASH_update) SHA512_Update,
107 (HASH_end) SHA512_End, (HASH_file) SHA512_File },
108 { "TIGER", 24,
109 (HASH_init) TIGERInit, (HASH_update) TIGERUpdate,
110 (HASH_end) TIGEREnd, (HASH_file) TIGERFile },
111 { "WHIRLPOOL", WHIRLPOOL_DIGEST_BYTES,
112 (HASH_init) whirlpool_init, (HASH_update) whirlpool_update,
113 (HASH_end) whirlpool_end, (HASH_file) whirlpool_file },
114 { NULL }
117 /* find an algorithm, given a name */
118 static alg_t *
119 find_algorithm(const char *a)
121 alg_t *alg;
123 for (alg = algorithms ; alg->name && strcasecmp(alg->name, a) != 0 ; alg++) {
125 return (alg->name) ? alg : NULL;
128 /* compute a digest, and print the results if successful */
129 static int
130 digest_file(char *fn, alg_t *alg)
132 char in[BUFSIZ * 20];
133 char *digest;
134 int cc, rc;
136 digest = malloc(alg->hash_len * 2 + 1);
138 if (fn == NULL) {
139 (*alg->hash_init)(&alg->hash_ctx);
140 while ((cc = read(STDIN_FILENO, in, sizeof(in))) > 0) {
141 (*alg->hash_update)(&alg->hash_ctx, (uint8_t *)in,
142 (unsigned) cc);
144 (void) printf("%s\n", (*alg->hash_end)(&alg->hash_ctx, digest));
145 rc = 1;
146 } else {
147 if ((*alg->hash_file)(fn, digest) == NULL) {
148 rc = 0;
149 } else {
150 (void) printf("%s (%s) = %s\n", alg->name, fn, digest);
151 rc = 1;
155 free(digest);
157 return (rc);
161 main(int argc, char **argv)
163 alg_t *alg;
164 int rval;
165 int i;
167 #ifdef HAVE_SETLOCALE
168 (void) setlocale(LC_ALL, "");
169 #endif
170 while ((i = getopt(argc, argv, "V")) != -1) {
171 switch(i) {
172 case 'V':
173 printf("%s\n", VERSION);
174 return EXIT_SUCCESS;
177 argc -= optind;
178 argv += optind;
180 if (argc == 0) {
181 (void) fprintf(stderr, "Usage: %s algorithm [file...]\n",
182 argv[-optind]);
183 return EXIT_FAILURE;
185 if ((alg = find_algorithm(argv[0])) == NULL) {
186 (void) fprintf(stderr, "No such algorithm `%s'\n", argv[0]);
187 exit(EXIT_FAILURE);
189 argc--;
190 argv++;
191 rval = EXIT_SUCCESS;
192 if (argc == 0) {
193 if (!digest_file(NULL, alg)) {
194 (void) fprintf(stderr, "stdin\n");
195 rval = EXIT_FAILURE;
197 } else {
198 for (i = 0 ; i < argc ; i++) {
199 if (!digest_file(argv[i], alg)) {
200 (void) fprintf(stderr, "%s\n", argv[i]);
201 rval = EXIT_FAILURE;
205 return rval;