Home | History | Annotate | Line # | Download | only in hash
hashhl.c revision 1.1
      1  1.1  christos /* $NetBSD: hashhl.c,v 1.1 2005/09/28 16:31:45 christos 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.1  christos /*
     20  1.1  christos  * Do all the name mangling before we include "namespace.h"
     21  1.1  christos  */
     22  1.1  christos #define	CONCAT(x,y)	__CONCAT(x,y)
     23  1.1  christos 
     24  1.1  christos #ifndef HASH_FNPREFIX
     25  1.1  christos #define	HASH_FNPREFIX	HASH_ALGORITHM
     26  1.1  christos #endif /* !HASH_FNPREFIX */
     27  1.1  christos 
     28  1.1  christos #define	FNPREFIX(x)	CONCAT(HASH_FNPREFIX,x)
     29  1.1  christos #define	HASH_CTX	CONCAT(HASH_ALGORITHM,_CTX)
     30  1.1  christos #define	HASH_LEN	CONCAT(HASH_ALGORITHM,_DIGEST_LENGTH)
     31  1.1  christos #define	HASH_STRLEN	CONCAT(HASH_ALGORITHM,_DIGEST_STRING_LENGTH)
     32  1.1  christos 
     33  1.1  christos #if !defined(_KERNEL) && defined(__weak_alias)
     34  1.1  christos #define	WA(a,b)	__weak_alias(a,b)
     35  1.1  christos WA(FNPREFIX(End),CONCAT(_,FNPREFIX(End)))
     36  1.1  christos WA(FNPREFIX(FileChunk),CONCAT(_,FNPREFIX(FileChunk)))
     37  1.1  christos WA(FNPREFIX(File),CONCAT(_,FNPREFIX(File)))
     38  1.1  christos WA(FNPREFIX(Data),CONCAT(_,FNPREFIX(Data)))
     39  1.1  christos #undef WA
     40  1.1  christos #endif
     41  1.1  christos 
     42  1.1  christos #include "namespace.h"
     43  1.1  christos #include HASH_INCLUDE
     44  1.1  christos 
     45  1.1  christos #include <sys/types.h>
     46  1.1  christos #include <sys/stat.h>
     47  1.1  christos 
     48  1.1  christos #include <assert.h>
     49  1.1  christos #include <fcntl.h>
     50  1.1  christos #include <errno.h>
     51  1.1  christos #include <stdio.h>
     52  1.1  christos #include <stdlib.h>
     53  1.1  christos #include <unistd.h>
     54  1.1  christos 
     55  1.1  christos #if HAVE_NBTOOL_CONFIG_H
     56  1.1  christos #include "nbtool_config.h"
     57  1.1  christos #endif
     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 
     64  1.1  christos char *
     65  1.1  christos FNPREFIX(End)(HASH_CTX *ctx, char *buf)
     66  1.1  christos {
     67  1.1  christos 	int i;
     68  1.1  christos 	unsigned char digest[HASH_LEN];
     69  1.1  christos 	static const char hex[]="0123456789abcdef";
     70  1.1  christos 
     71  1.1  christos 	_DIAGASSERT(ctx != 0);
     72  1.1  christos 
     73  1.1  christos 	if (buf == NULL)
     74  1.1  christos 		buf = malloc((size_t)HASH_STRLEN);
     75  1.1  christos 	if (buf == NULL)
     76  1.1  christos 		return (NULL);
     77  1.1  christos 
     78  1.1  christos 	FNPREFIX(Final)(digest, ctx);
     79  1.1  christos 
     80  1.1  christos 	for (i = 0; i < HASH_LEN; i++) {
     81  1.1  christos 		buf[i+i] = hex[(u_int32_t)digest[i] >> 4];
     82  1.1  christos 		buf[i+i+1] = hex[digest[i] & 0x0f];
     83  1.1  christos 	}
     84  1.1  christos 
     85  1.1  christos 	buf[i+i] = '\0';
     86  1.1  christos 	return (buf);
     87  1.1  christos }
     88  1.1  christos 
     89  1.1  christos char *
     90  1.1  christos FNPREFIX(FileChunk)(const char *filename, char *buf, off_t off, off_t len)
     91  1.1  christos {
     92  1.1  christos 	struct stat sb;
     93  1.1  christos 	u_char buffer[BUFSIZ];
     94  1.1  christos 	HASH_CTX ctx;
     95  1.1  christos 	int fd, save_errno;
     96  1.1  christos 	ssize_t nr;
     97  1.1  christos 
     98  1.1  christos 	FNPREFIX(Init)(&ctx);
     99  1.1  christos 
    100  1.1  christos 	if ((fd = open(filename, O_RDONLY)) < 0)
    101  1.1  christos 		return (NULL);
    102  1.1  christos 	if (len == 0) {
    103  1.1  christos 		if (fstat(fd, &sb) == -1) {
    104  1.1  christos 			close(fd);
    105  1.1  christos 			return (NULL);
    106  1.1  christos 		}
    107  1.1  christos 		len = sb.st_size;
    108  1.1  christos 	}
    109  1.1  christos 	if (off > 0 && lseek(fd, off, SEEK_SET) < 0)
    110  1.1  christos 		return (NULL);
    111  1.1  christos 
    112  1.1  christos 	while ((nr = read(fd, buffer, (size_t) MIN(sizeof(buffer), len)))
    113  1.1  christos 	    > 0) {
    114  1.1  christos 		FNPREFIX(Update)(&ctx, buffer, (unsigned int)nr);
    115  1.1  christos 		if (len > 0 && (len -= nr) == 0)
    116  1.1  christos 			break;
    117  1.1  christos 	}
    118  1.1  christos 
    119  1.1  christos 	save_errno = errno;
    120  1.1  christos 	close(fd);
    121  1.1  christos 	errno = save_errno;
    122  1.1  christos 	return (nr < 0 ? NULL : FNPREFIX(End)(&ctx, buf));
    123  1.1  christos }
    124  1.1  christos 
    125  1.1  christos char *
    126  1.1  christos FNPREFIX(File)(const char *filename, char *buf)
    127  1.1  christos {
    128  1.1  christos 	return (FNPREFIX(FileChunk)(filename, buf, (off_t)0, (off_t)0));
    129  1.1  christos }
    130  1.1  christos 
    131  1.1  christos char *
    132  1.1  christos FNPREFIX(Data)(const unsigned char *data, size_t len, char *buf)
    133  1.1  christos {
    134  1.1  christos 	HASH_CTX ctx;
    135  1.1  christos 
    136  1.1  christos 	_DIAGASSERT(data != 0);
    137  1.1  christos 
    138  1.1  christos 	FNPREFIX(Init)(&ctx);
    139  1.1  christos 	FNPREFIX(Update)(&ctx, data, (unsigned int)len);
    140  1.1  christos 	return (FNPREFIX(End)(&ctx, buf));
    141  1.1  christos }
    142  1.1  christos 
    143  1.1  christos #endif /* HASH_ALGORITHM */
    144