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 * libjpeg-turbo Modifications:
8 * Copyright (C) 2016, D. R. Commander.
9 * Modifications are under the same license as the original code (see above)
10 * ----------------------------------------------------------------------------
11 */
12
13 #include <sys/types.h>
14 #include <sys/stat.h>
15 #include <fcntl.h>
16 #ifdef _WIN32
17 #include <io.h>
18 #define close _close
19 #define fstat _fstat
20 #define lseek _lseek
21 #define read _read
22 #define stat _stat
23 #else
24 #include <unistd.h>
25 #endif
26
27 #include <errno.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30
31 #define LENGTH 16
32
33 #include "./md5.h"
34
35 char *
MD5End(MD5_CTX * ctx,char * buf)36 MD5End(MD5_CTX *ctx, char *buf)
37 {
38 int i;
39 unsigned char digest[LENGTH];
40 static const char hex[]="0123456789abcdef";
41
42 if (!buf)
43 buf = malloc(2*LENGTH + 1);
44 if (!buf)
45 return 0;
46 MD5Final(digest, ctx);
47 for (i = 0; i < LENGTH; i++) {
48 buf[i+i] = hex[digest[i] >> 4];
49 buf[i+i+1] = hex[digest[i] & 0x0f];
50 }
51 buf[i+i] = '\0';
52 return buf;
53 }
54
55 char *
MD5File(const char * filename,char * buf)56 MD5File(const char *filename, char *buf)
57 {
58 return (MD5FileChunk(filename, buf, 0, 0));
59 }
60
61 char *
MD5FileChunk(const char * filename,char * buf,off_t ofs,off_t len)62 MD5FileChunk(const char *filename, char *buf, off_t ofs, off_t len)
63 {
64 unsigned char buffer[BUFSIZ];
65 MD5_CTX ctx;
66 struct stat stbuf;
67 int f, i, e;
68 off_t n;
69
70 MD5Init(&ctx);
71 #if _WIN32
72 f = _open(filename, O_RDONLY|O_BINARY);
73 #else
74 f = open(filename, O_RDONLY);
75 #endif
76 if (f < 0)
77 return 0;
78 if (fstat(f, &stbuf) < 0)
79 return 0;
80 if (ofs > stbuf.st_size)
81 ofs = stbuf.st_size;
82 if ((len == 0) || (len > stbuf.st_size - ofs))
83 len = stbuf.st_size - ofs;
84 if (lseek(f, ofs, SEEK_SET) < 0)
85 return 0;
86 n = len;
87 i = 0;
88 while (n > 0) {
89 if (n > sizeof(buffer))
90 i = read(f, buffer, sizeof(buffer));
91 else
92 i = read(f, buffer, n);
93 if (i < 0)
94 break;
95 MD5Update(&ctx, buffer, i);
96 n -= i;
97 }
98 e = errno;
99 close(f);
100 errno = e;
101 if (i < 0)
102 return 0;
103 return (MD5End(&ctx, buf));
104 }
105
106 char *
MD5Data(const void * data,unsigned int len,char * buf)107 MD5Data (const void *data, unsigned int len, char *buf)
108 {
109 MD5_CTX ctx;
110
111 MD5Init(&ctx);
112 MD5Update(&ctx,data,len);
113 return (MD5End(&ctx, buf));
114 }
115