104819365SAxel Dörfler/* mdXhl.c * ----------------------------------------------------------------------------
204819365SAxel Dörfler * "THE BEER-WARE LICENSE" (Revision 42):
304819365SAxel Dörfler * <phk@FreeBSD.org> wrote this file.  As long as you retain this notice you
404819365SAxel Dörfler * can do whatever you want with this stuff. If we meet some day, and you think
504819365SAxel Dörfler * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
604819365SAxel Dörfler * ----------------------------------------------------------------------------
704819365SAxel Dörfler */
804819365SAxel Dörfler
904819365SAxel Dörfler#include <sys/cdefs.h>
1004819365SAxel Dörfler__FBSDID("$FreeBSD: src/lib/libmd/mdXhl.c,v 1.19 2006/01/17 15:35:56 phk Exp $");
1104819365SAxel Dörfler
1204819365SAxel Dörfler#include <sys/types.h>
1304819365SAxel Dörfler#include <sys/stat.h>
1404819365SAxel Dörfler#include <fcntl.h>
1504819365SAxel Dörfler#include <unistd.h>
1604819365SAxel Dörfler
1704819365SAxel Dörfler#include <errno.h>
1804819365SAxel Dörfler#include <stdio.h>
1904819365SAxel Dörfler#include <stdlib.h>
2004819365SAxel Dörfler
2104819365SAxel Dörfler#include "md5.h"
2204819365SAxel Dörfler
2304819365SAxel Dörflerchar *
2404819365SAxel DörflerMD5End(MD5_CTX *ctx, char *buf)
2504819365SAxel Dörfler{
2604819365SAxel Dörfler	int i;
2704819365SAxel Dörfler	unsigned char digest[MD5_DIGEST_LENGTH];
2804819365SAxel Dörfler	static const char hex[]="0123456789abcdef";
2904819365SAxel Dörfler
3004819365SAxel Dörfler	if (!buf)
3104819365SAxel Dörfler		buf = malloc(2*MD5_DIGEST_LENGTH + 1);
3204819365SAxel Dörfler	if (!buf)
3304819365SAxel Dörfler		return 0;
3404819365SAxel Dörfler	MD5Final(digest, ctx);
3504819365SAxel Dörfler	for (i = 0; i < MD5_DIGEST_LENGTH; i++) {
3604819365SAxel Dörfler		buf[i+i] = hex[digest[i] >> 4];
3704819365SAxel Dörfler		buf[i+i+1] = hex[digest[i] & 0x0f];
3804819365SAxel Dörfler	}
3904819365SAxel Dörfler	buf[i+i] = '\0';
4004819365SAxel Dörfler	return buf;
4104819365SAxel Dörfler}
4204819365SAxel Dörfler
4304819365SAxel Dörflerchar *
4404819365SAxel DörflerMD5File(const char *filename, char *buf)
4504819365SAxel Dörfler{
4604819365SAxel Dörfler	return (MD5FileChunk(filename, buf, 0, 0));
4704819365SAxel Dörfler}
4804819365SAxel Dörfler
4904819365SAxel Dörflerchar *
5004819365SAxel DörflerMD5FileChunk(const char *filename, char *buf, off_t ofs, off_t len)
5104819365SAxel Dörfler{
5204819365SAxel Dörfler	unsigned char buffer[BUFSIZ];
5304819365SAxel Dörfler	MD5_CTX ctx;
5404819365SAxel Dörfler	struct stat stbuf;
5504819365SAxel Dörfler	int f, i, e;
5604819365SAxel Dörfler	off_t n;
5704819365SAxel Dörfler
5804819365SAxel Dörfler	MD5Init(&ctx);
5904819365SAxel Dörfler	f = open(filename, O_RDONLY);
6004819365SAxel Dörfler	if (f < 0)
6104819365SAxel Dörfler		return 0;
6204819365SAxel Dörfler	if (fstat(f, &stbuf) < 0)
6304819365SAxel Dörfler		return 0;
6404819365SAxel Dörfler	if (ofs > stbuf.st_size)
6504819365SAxel Dörfler		ofs = stbuf.st_size;
6604819365SAxel Dörfler	if ((len == 0) || (len > stbuf.st_size - ofs))
6704819365SAxel Dörfler		len = stbuf.st_size - ofs;
6804819365SAxel Dörfler	if (lseek(f, ofs, SEEK_SET) < 0)
6904819365SAxel Dörfler		return 0;
7004819365SAxel Dörfler	n = len;
7104819365SAxel Dörfler	i = 0;
7204819365SAxel Dörfler	while (n > 0) {
7304819365SAxel Dörfler		if (n > sizeof(buffer))
7404819365SAxel Dörfler			i = read(f, buffer, sizeof(buffer));
7504819365SAxel Dörfler		else
7604819365SAxel Dörfler			i = read(f, buffer, n);
7704819365SAxel Dörfler		if (i < 0)
7804819365SAxel Dörfler			break;
7904819365SAxel Dörfler		MD5Update(&ctx, buffer, i);
8004819365SAxel Dörfler		n -= i;
8104819365SAxel Dörfler	}
8204819365SAxel Dörfler	e = errno;
8304819365SAxel Dörfler	close(f);
8404819365SAxel Dörfler	errno = e;
8504819365SAxel Dörfler	if (i < 0)
8604819365SAxel Dörfler		return 0;
8704819365SAxel Dörfler	return (MD5End(&ctx, buf));
8804819365SAxel Dörfler}
8904819365SAxel Dörfler
9004819365SAxel Dörflerchar *
9104819365SAxel DörflerMD5Data (const void *data, unsigned int len, char *buf)
9204819365SAxel Dörfler{
9304819365SAxel Dörfler	MD5_CTX ctx;
9404819365SAxel Dörfler
9504819365SAxel Dörfler	MD5Init(&ctx);
9604819365SAxel Dörfler	MD5Update(&ctx,data,len);
9704819365SAxel Dörfler	return (MD5End(&ctx, buf));
9804819365SAxel Dörfler}