1*0a6a1f1dSLionel Sambuc /* $NetBSD: hashhl.c,v 1.7 2014/09/24 13:18:52 christos Exp $ */
22fe8fb19SBen Gras
32fe8fb19SBen Gras /*
42fe8fb19SBen Gras * ----------------------------------------------------------------------------
52fe8fb19SBen Gras * "THE BEER-WARE LICENSE" (Revision 42):
62fe8fb19SBen Gras * <phk@login.dkuug.dk> wrote this file. As long as you retain this notice you
72fe8fb19SBen Gras * can do whatever you want with this stuff. If we meet some day, and you think
82fe8fb19SBen Gras * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
92fe8fb19SBen Gras * ----------------------------------------------------------------------------
102fe8fb19SBen Gras */
112fe8fb19SBen Gras
122fe8fb19SBen Gras /*
132fe8fb19SBen Gras * Modified September 24, 2005 by Elad Efrat <elad@NetBSD.org>
142fe8fb19SBen Gras * Modified April 29, 1997 by Jason R. Thorpe <thorpej@NetBSD.org>
152fe8fb19SBen Gras */
162fe8fb19SBen Gras
172fe8fb19SBen Gras #ifdef HASH_ALGORITHM
182fe8fb19SBen Gras
192fe8fb19SBen Gras #if HAVE_NBTOOL_CONFIG_H
202fe8fb19SBen Gras #include "nbtool_config.h"
212fe8fb19SBen Gras #endif
222fe8fb19SBen Gras
232fe8fb19SBen Gras /*
242fe8fb19SBen Gras * Do all the name mangling before we include "namespace.h"
252fe8fb19SBen Gras */
262fe8fb19SBen Gras #define CONCAT(x,y) __CONCAT(x,y)
272fe8fb19SBen Gras
282fe8fb19SBen Gras #ifndef HASH_FNPREFIX
292fe8fb19SBen Gras #define HASH_FNPREFIX HASH_ALGORITHM
302fe8fb19SBen Gras #endif /* !HASH_FNPREFIX */
312fe8fb19SBen Gras
322fe8fb19SBen Gras #define FNPREFIX(x) CONCAT(HASH_FNPREFIX,x)
332fe8fb19SBen Gras #define HASH_CTX CONCAT(HASH_ALGORITHM,_CTX)
342fe8fb19SBen Gras #define HASH_LEN CONCAT(HASH_ALGORITHM,_DIGEST_LENGTH)
352fe8fb19SBen Gras #define HASH_STRLEN CONCAT(HASH_ALGORITHM,_DIGEST_STRING_LENGTH)
362fe8fb19SBen Gras
372fe8fb19SBen Gras #if !defined(_KERNEL) && defined(__weak_alias) && !defined(HAVE_NBTOOL_CONFIG_H)
382fe8fb19SBen Gras #define WA(a,b) __weak_alias(a,b)
WA(FNPREFIX (End),CONCAT (_,FNPREFIX (End)))392fe8fb19SBen Gras WA(FNPREFIX(End),CONCAT(_,FNPREFIX(End)))
402fe8fb19SBen Gras WA(FNPREFIX(FileChunk),CONCAT(_,FNPREFIX(FileChunk)))
412fe8fb19SBen Gras WA(FNPREFIX(File),CONCAT(_,FNPREFIX(File)))
422fe8fb19SBen Gras WA(FNPREFIX(Data),CONCAT(_,FNPREFIX(Data)))
432fe8fb19SBen Gras #undef WA
442fe8fb19SBen Gras #endif
452fe8fb19SBen Gras
462fe8fb19SBen Gras #include "namespace.h"
472fe8fb19SBen Gras #include HASH_INCLUDE
482fe8fb19SBen Gras
492fe8fb19SBen Gras #include <sys/types.h>
502fe8fb19SBen Gras #include <sys/stat.h>
512fe8fb19SBen Gras
522fe8fb19SBen Gras #include <assert.h>
532fe8fb19SBen Gras #include <fcntl.h>
542fe8fb19SBen Gras #include <errno.h>
552fe8fb19SBen Gras #include <stdio.h>
562fe8fb19SBen Gras #include <stdlib.h>
572fe8fb19SBen Gras #include <unistd.h>
582fe8fb19SBen Gras
592fe8fb19SBen Gras #ifndef MIN
602fe8fb19SBen Gras #define MIN(x,y) ((x)<(y)?(x):(y))
612fe8fb19SBen Gras #endif /* !MIN */
622fe8fb19SBen Gras
632fe8fb19SBen Gras char *
642fe8fb19SBen Gras FNPREFIX(End)(HASH_CTX *ctx, char *buf)
652fe8fb19SBen Gras {
662fe8fb19SBen Gras int i;
672fe8fb19SBen Gras unsigned char digest[HASH_LEN];
682fe8fb19SBen Gras static const char hex[]="0123456789abcdef";
692fe8fb19SBen Gras
702fe8fb19SBen Gras _DIAGASSERT(ctx != 0);
712fe8fb19SBen Gras
722fe8fb19SBen Gras if (buf == NULL)
732fe8fb19SBen Gras buf = malloc((size_t)HASH_STRLEN);
742fe8fb19SBen Gras if (buf == NULL)
752fe8fb19SBen Gras return (NULL);
762fe8fb19SBen Gras
772fe8fb19SBen Gras FNPREFIX(Final)(digest, ctx);
782fe8fb19SBen Gras
792fe8fb19SBen Gras for (i = 0; i < HASH_LEN; i++) {
802fe8fb19SBen Gras buf[i+i] = hex[(u_int32_t)digest[i] >> 4];
812fe8fb19SBen Gras buf[i+i+1] = hex[digest[i] & 0x0f];
822fe8fb19SBen Gras }
832fe8fb19SBen Gras
842fe8fb19SBen Gras buf[i+i] = '\0';
852fe8fb19SBen Gras return (buf);
862fe8fb19SBen Gras }
872fe8fb19SBen Gras
882fe8fb19SBen Gras char *
FNPREFIX(FileChunk)892fe8fb19SBen Gras FNPREFIX(FileChunk)(const char *filename, char *buf, off_t off, off_t len)
902fe8fb19SBen Gras {
912fe8fb19SBen Gras struct stat sb;
922fe8fb19SBen Gras u_char buffer[BUFSIZ];
932fe8fb19SBen Gras HASH_CTX ctx;
942fe8fb19SBen Gras int fd, save_errno;
952fe8fb19SBen Gras ssize_t nr;
962fe8fb19SBen Gras
972fe8fb19SBen Gras FNPREFIX(Init)(&ctx);
982fe8fb19SBen Gras
99*0a6a1f1dSLionel Sambuc if ((fd = open(filename, O_RDONLY | O_CLOEXEC)) < 0)
1002fe8fb19SBen Gras return (NULL);
1012fe8fb19SBen Gras if (len == 0) {
1022fe8fb19SBen Gras if (fstat(fd, &sb) == -1) {
1032fe8fb19SBen Gras close(fd);
1042fe8fb19SBen Gras return (NULL);
1052fe8fb19SBen Gras }
1062fe8fb19SBen Gras len = sb.st_size;
1072fe8fb19SBen Gras }
1082fe8fb19SBen Gras if (off > 0 && lseek(fd, off, SEEK_SET) < 0) {
1092fe8fb19SBen Gras close(fd);
1102fe8fb19SBen Gras return (NULL);
1112fe8fb19SBen Gras }
1122fe8fb19SBen Gras
1132fe8fb19SBen Gras while ((nr = read(fd, buffer, (size_t) MIN((off_t)sizeof(buffer), len)))
1142fe8fb19SBen Gras > 0) {
1152fe8fb19SBen Gras FNPREFIX(Update)(&ctx, buffer, (unsigned int)nr);
1162fe8fb19SBen Gras if (len > 0 && (len -= nr) == 0)
1172fe8fb19SBen Gras break;
1182fe8fb19SBen Gras }
1192fe8fb19SBen Gras
1202fe8fb19SBen Gras save_errno = errno;
1212fe8fb19SBen Gras close(fd);
1222fe8fb19SBen Gras errno = save_errno;
1232fe8fb19SBen Gras return (nr < 0 ? NULL : FNPREFIX(End)(&ctx, buf));
1242fe8fb19SBen Gras }
1252fe8fb19SBen Gras
1262fe8fb19SBen Gras char *
FNPREFIX(File)1272fe8fb19SBen Gras FNPREFIX(File)(const char *filename, char *buf)
1282fe8fb19SBen Gras {
1292fe8fb19SBen Gras return (FNPREFIX(FileChunk)(filename, buf, (off_t)0, (off_t)0));
1302fe8fb19SBen Gras }
1312fe8fb19SBen Gras
1322fe8fb19SBen Gras char *
FNPREFIX(Data)1332fe8fb19SBen Gras FNPREFIX(Data)(const unsigned char *data, size_t len, char *buf)
1342fe8fb19SBen Gras {
1352fe8fb19SBen Gras HASH_CTX ctx;
1362fe8fb19SBen Gras
1372fe8fb19SBen Gras _DIAGASSERT(data != 0);
1382fe8fb19SBen Gras
1392fe8fb19SBen Gras FNPREFIX(Init)(&ctx);
1402fe8fb19SBen Gras FNPREFIX(Update)(&ctx, data, (unsigned int)len);
1412fe8fb19SBen Gras return (FNPREFIX(End)(&ctx, buf));
1422fe8fb19SBen Gras }
1432fe8fb19SBen Gras
1442fe8fb19SBen Gras #endif /* HASH_ALGORITHM */
145