96b71caeb3a8afb1813ee81b4561958116035709
[dragonfly.git] / lib / libmd / mdXhl.c
1 /* mdXhl.c * ----------------------------------------------------------------------------
2  * "THE BEER-WARE LICENSE" (Revision 42):
3  * <phk@FreeBSD.org> wrote this file.  As long as you retain this notice you
4  * can do whatever you want with this stuff. If we meet some day, and you think
5  * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
6  * ----------------------------------------------------------------------------
7  *
8  * $FreeBSD: src/lib/libmd/mdXhl.c,v 1.19 2006/01/17 15:35:56 phk Exp $
9  * $DragonFly: src/lib/libmd/mdXhl.c,v 1.3 2008/09/11 20:25:34 swildner Exp $
10  *
11  */
12
13 #include <sys/types.h>
14 #include <sys/stat.h>
15 #include <fcntl.h>
16 #include <unistd.h>
17
18 #include <errno.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21
22 #include "mdX.h"
23
24 char *
25 MDXEnd(MDX_CTX *ctx, char *buf)
26 {
27         int i;
28         unsigned char digest[LENGTH];
29         static const char hex[]="0123456789abcdef";
30
31         if (!buf)
32                 buf = malloc(2*LENGTH + 1);
33         if (!buf)
34                 return 0;
35         MDXFinal(digest, ctx);
36         for (i = 0; i < LENGTH; i++) {
37                 buf[i+i] = hex[digest[i] >> 4];
38                 buf[i+i+1] = hex[digest[i] & 0x0f];
39         }
40         buf[i+i] = '\0';
41         return buf;
42 }
43
44 char *
45 MDXFile(const char *filename, char *buf)
46 {
47         return (MDXFileChunk(filename, buf, 0, 0));
48 }
49
50 char *
51 MDXFileChunk(const char *filename, char *buf, off_t ofs, off_t len)
52 {
53         unsigned char buffer[BUFSIZ];
54         MDX_CTX ctx;
55         struct stat stbuf;
56         int f, i, e;
57         off_t n;
58
59         MDXInit(&ctx);
60         f = open(filename, O_RDONLY);
61         if (f < 0)
62                 return 0;
63         if (fstat(f, &stbuf) < 0)
64                 return 0;
65         if (ofs > stbuf.st_size)
66                 ofs = stbuf.st_size;
67         if ((len == 0) || (len > stbuf.st_size - ofs))
68                 len = stbuf.st_size - ofs;
69         if (lseek(f, ofs, SEEK_SET) < 0)
70                 return 0;
71         n = len;
72         i = 0;
73         while (n > 0) {
74                 if (n > sizeof(buffer))
75                         i = read(f, buffer, sizeof(buffer));
76                 else
77                         i = read(f, buffer, n);
78                 if (i < 0) 
79                         break;
80                 MDXUpdate(&ctx, buffer, i);
81                 n -= i;
82         } 
83         e = errno;
84         close(f);
85         errno = e;
86         if (i < 0)
87                 return 0;
88         return (MDXEnd(&ctx, buf));
89 }
90
91 char *
92 MDXData (const void *data, unsigned int len, char *buf)
93 {
94         MDX_CTX ctx;
95
96         MDXInit(&ctx);
97         MDXUpdate(&ctx,data,len);
98         return (MDXEnd(&ctx, buf));
99 }