Home | History | Annotate | Line # | Download | only in hash
hashhl.c revision 1.8
      1  1.8       mrg /* $NetBSD: hashhl.c,v 1.8 2023/09/04 20:51:39 mrg Exp $ */
      2  1.1  christos 
      3  1.1  christos /*
      4  1.1  christos  * ----------------------------------------------------------------------------
      5  1.1  christos  * "THE BEER-WARE LICENSE" (Revision 42):
      6  1.1  christos  * <phk (at) login.dkuug.dk> wrote this file.  As long as you retain this notice you
      7  1.1  christos  * can do whatever you want with this stuff. If we meet some day, and you think
      8  1.1  christos  * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
      9  1.1  christos  * ----------------------------------------------------------------------------
     10  1.1  christos  */
     11  1.1  christos 
     12  1.1  christos /*
     13  1.1  christos  * Modified September 24, 2005 by Elad Efrat <elad (at) NetBSD.org>
     14  1.1  christos  * Modified April 29, 1997 by Jason R. Thorpe <thorpej (at) NetBSD.org>
     15  1.1  christos  */
     16  1.1  christos 
     17  1.1  christos #ifdef HASH_ALGORITHM
     18  1.1  christos 
     19  1.3       apb #if HAVE_NBTOOL_CONFIG_H
     20  1.3       apb #include "nbtool_config.h"
     21  1.3       apb #endif
     22  1.3       apb 
     23  1.1  christos /*
     24  1.1  christos  * Do all the name mangling before we include "namespace.h"
     25  1.1  christos  */
     26  1.1  christos #define	CONCAT(x,y)	__CONCAT(x,y)
     27  1.1  christos 
     28  1.1  christos #ifndef HASH_FNPREFIX
     29  1.1  christos #define	HASH_FNPREFIX	HASH_ALGORITHM
     30  1.1  christos #endif /* !HASH_FNPREFIX */
     31  1.1  christos 
     32  1.1  christos #define	FNPREFIX(x)	CONCAT(HASH_FNPREFIX,x)
     33  1.1  christos #define	HASH_CTX	CONCAT(HASH_ALGORITHM,_CTX)
     34  1.1  christos #define	HASH_LEN	CONCAT(HASH_ALGORITHM,_DIGEST_LENGTH)
     35  1.1  christos #define	HASH_STRLEN	CONCAT(HASH_ALGORITHM,_DIGEST_STRING_LENGTH)
     36  1.1  christos 
     37  1.3       apb #if !defined(_KERNEL) && defined(__weak_alias) && !defined(HAVE_NBTOOL_CONFIG_H)
     38  1.1  christos #define	WA(a,b)	__weak_alias(a,b)
     39  1.1  christos WA(FNPREFIX(End),CONCAT(_,FNPREFIX(End)))
     40  1.1  christos WA(FNPREFIX(FileChunk),CONCAT(_,FNPREFIX(FileChunk)))
     41  1.1  christos WA(FNPREFIX(File),CONCAT(_,FNPREFIX(File)))
     42  1.1  christos WA(FNPREFIX(Data),CONCAT(_,FNPREFIX(Data)))
     43  1.1  christos #undef WA
     44  1.1  christos #endif
     45  1.1  christos 
     46  1.1  christos #include "namespace.h"
     47  1.1  christos #include HASH_INCLUDE
     48  1.1  christos 
     49  1.1  christos #include <sys/types.h>
     50  1.1  christos #include <sys/stat.h>
     51  1.1  christos 
     52  1.1  christos #include <assert.h>
     53  1.1  christos #include <fcntl.h>
     54  1.1  christos #include <errno.h>
     55  1.1  christos #include <stdio.h>
     56  1.1  christos #include <stdlib.h>
     57  1.1  christos #include <unistd.h>
     58  1.1  christos 
     59  1.1  christos #ifndef MIN
     60  1.1  christos #define	MIN(x,y)	((x)<(y)?(x):(y))
     61  1.1  christos #endif /* !MIN */
     62  1.1  christos 
     63  1.1  christos char *
     64  1.8       mrg FNPREFIX(End)(HASH_CTX *ctx, char buf[HASH_STRLEN])
     65  1.1  christos {
     66  1.1  christos 	int i;
     67  1.1  christos 	unsigned char digest[HASH_LEN];
     68  1.1  christos 	static const char hex[]="0123456789abcdef";
     69  1.1  christos 
     70  1.1  christos 	_DIAGASSERT(ctx != 0);
     71  1.1  christos 
     72  1.1  christos 	if (buf == NULL)
     73  1.1  christos 		buf = malloc((size_t)HASH_STRLEN);
     74  1.1  christos 	if (buf == NULL)
     75  1.1  christos 		return (NULL);
     76  1.1  christos 
     77  1.1  christos 	FNPREFIX(Final)(digest, ctx);
     78  1.1  christos 
     79  1.1  christos 	for (i = 0; i < HASH_LEN; i++) {
     80  1.1  christos 		buf[i+i] = hex[(u_int32_t)digest[i] >> 4];
     81  1.1  christos 		buf[i+i+1] = hex[digest[i] & 0x0f];
     82  1.1  christos 	}
     83  1.1  christos 
     84  1.1  christos 	buf[i+i] = '\0';
     85  1.1  christos 	return (buf);
     86  1.1  christos }
     87  1.1  christos 
     88  1.1  christos char *
     89  1.1  christos FNPREFIX(FileChunk)(const char *filename, char *buf, off_t off, off_t len)
     90  1.1  christos {
     91  1.1  christos 	struct stat sb;
     92  1.1  christos 	u_char buffer[BUFSIZ];
     93  1.1  christos 	HASH_CTX ctx;
     94  1.1  christos 	int fd, save_errno;
     95  1.1  christos 	ssize_t nr;
     96  1.1  christos 
     97  1.1  christos 	FNPREFIX(Init)(&ctx);
     98  1.1  christos 
     99  1.5  christos 	if ((fd = open(filename, O_RDONLY | O_CLOEXEC)) < 0)
    100  1.1  christos 		return (NULL);
    101  1.1  christos 	if (len == 0) {
    102  1.1  christos 		if (fstat(fd, &sb) == -1) {
    103  1.1  christos 			close(fd);
    104  1.1  christos 			return (NULL);
    105  1.1  christos 		}
    106  1.1  christos 		len = sb.st_size;
    107  1.1  christos 	}
    108  1.4       wiz 	if (off > 0 && lseek(fd, off, SEEK_SET) < 0) {
    109  1.4       wiz 		close(fd);
    110  1.1  christos 		return (NULL);
    111  1.4       wiz 	}
    112  1.1  christos 
    113  1.2     lukem 	while ((nr = read(fd, buffer, (size_t) MIN((off_t)sizeof(buffer), len)))
    114  1.1  christos 	    > 0) {
    115  1.1  christos 		FNPREFIX(Update)(&ctx, buffer, (unsigned int)nr);
    116  1.1  christos 		if (len > 0 && (len -= nr) == 0)
    117  1.1  christos 			break;
    118  1.1  christos 	}
    119  1.1  christos 
    120  1.1  christos 	save_errno = errno;
    121  1.1  christos 	close(fd);
    122  1.1  christos 	errno = save_errno;
    123  1.1  christos 	return (nr < 0 ? NULL : FNPREFIX(End)(&ctx, buf));
    124  1.1  christos }
    125  1.1  christos 
    126  1.1  christos char *
    127  1.1  christos FNPREFIX(File)(const char *filename, char *buf)
    128  1.1  christos {
    129  1.1  christos 	return (FNPREFIX(FileChunk)(filename, buf, (off_t)0, (off_t)0));
    130  1.1  christos }
    131  1.1  christos 
    132  1.1  christos char *
    133  1.8       mrg FNPREFIX(Data)(const unsigned char *data, size_t len, char buf[HASH_STRLEN])
    134  1.1  christos {
    135  1.1  christos 	HASH_CTX ctx;
    136  1.1  christos 
    137  1.1  christos 	_DIAGASSERT(data != 0);
    138  1.1  christos 
    139  1.1  christos 	FNPREFIX(Init)(&ctx);
    140  1.1  christos 	FNPREFIX(Update)(&ctx, data, (unsigned int)len);
    141  1.1  christos 	return (FNPREFIX(End)(&ctx, buf));
    142  1.1  christos }
    143  1.1  christos 
    144  1.1  christos #endif /* HASH_ALGORITHM */
    145