]> git.cameronkatri.com Git - apple_cmds.git/blob - text_cmds/sort/commoncrypto.c
Create README.md
[apple_cmds.git] / text_cmds / sort / commoncrypto.c
1 /* mdXhl.c
2 * ----------------------------------------------------------------------------
3 * "THE BEER-WARE LICENSE" (Revision 42):
4 * <phk@FreeBSD.org> wrote this file. As long as you retain this notice you
5 * can do whatever you want with this stuff. If we meet some day, and you think
6 * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
7 * ----------------------------------------------------------------------------
8 */
9
10 #include <sys/cdefs.h>
11 __FBSDID("$FreeBSD: head/lib/libmd/mdXhl.c 294037 2016-01-14 21:08:23Z jtl $");
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 "commoncrypto.h"
23
24 #define LENGTH CC_MD5_DIGEST_LENGTH
25
26 char *MD5FileChunk(const char *, char *, off_t, off_t);
27
28 char *
29 MD5End(CC_MD5_CTX *ctx, char *buf)
30 {
31 int i;
32 unsigned char digest[LENGTH];
33 static const char hex[]="0123456789abcdef";
34
35 if (!buf)
36 buf = malloc(2*LENGTH + 1);
37 if (!buf)
38 return 0;
39 CC_MD5_Final(digest, ctx);
40 for (i = 0; i < LENGTH; i++) {
41 buf[i+i] = hex[digest[i] >> 4];
42 buf[i+i+1] = hex[digest[i] & 0x0f];
43 }
44 buf[i+i] = '\0';
45 return buf;
46 }
47
48 char *
49 MD5File(const char *filename, char *buf)
50 {
51 return (MD5FileChunk(filename, buf, 0, 0));
52 }
53
54 char *
55 MD5FileChunk(const char *filename, char *buf, off_t ofs, off_t len)
56 {
57 unsigned char buffer[16*1024];
58 CC_MD5_CTX ctx;
59 int fd, readrv, e;
60 off_t remain;
61
62 if (len < 0) {
63 errno = EINVAL;
64 return NULL;
65 }
66
67 CC_MD5_Init(&ctx);
68 fd = open(filename, O_RDONLY);
69 if (fd < 0)
70 return NULL;
71 if (ofs != 0) {
72 errno = 0;
73 if (lseek(fd, ofs, SEEK_SET) != ofs ||
74 (ofs == -1 && errno != 0)) {
75 readrv = -1;
76 goto error;
77 }
78 }
79 remain = len;
80 readrv = 0;
81 while (len == 0 || remain > 0) {
82 if (len == 0 || remain > (off_t)sizeof(buffer))
83 readrv = read(fd, buffer, sizeof(buffer));
84 else
85 readrv = read(fd, buffer, remain);
86 if (readrv <= 0)
87 break;
88 CC_MD5_Update(&ctx, buffer, readrv);
89 remain -= readrv;
90 }
91 error:
92 e = errno;
93 close(fd);
94 errno = e;
95 if (readrv < 0)
96 return NULL;
97 return (MD5End(&ctx, buf));
98 }