xref: /minix3/lib/libc/hash/hashhl.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
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