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$"); 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[16*1024]; 54 MDX_CTX ctx; 55 struct stat stbuf; 56 int fd, readrv, e; 57 off_t remain; 58 59 if (len < 0) { 60 errno = EINVAL; 61 return NULL; 62 } 63 64 MDXInit(&ctx); 65 fd = open(filename, O_RDONLY); 66 if (fd < 0) 67 return NULL; 68 if (ofs != 0) { 69 errno = 0; 70 if (lseek(fd, ofs, SEEK_SET) != ofs || 71 (ofs == -1 && errno != 0)) { 72 readrv = -1; 73 goto error; 74 } 75 } 76 remain = len; 77 readrv = 0; 78 while (len == 0 || remain > 0) { 79 if (len == 0 || remain > sizeof(buffer)) 80 readrv = read(fd, buffer, sizeof(buffer)); 81 else 82 readrv = read(fd, buffer, remain); 83 if (readrv <= 0) 84 break; 85 MDXUpdate(&ctx, buffer, readrv); 86 remain -= readrv; 87 } 88 error: 89 e = errno; 90 close(fd); 91 errno = e; 92 if (readrv < 0) 93 return NULL; 94 return (MDXEnd(&ctx, buf)); 95 } 96 97 char * 98 MDXData (const void *data, unsigned int len, char *buf) 99 { 100 MDX_CTX ctx; 101 102 MDXInit(&ctx); 103 MDXUpdate(&ctx,data,len); 104 return (MDXEnd(&ctx, buf)); 105 } 106 107 #ifdef WEAK_REFS 108 /* When building libmd, provide weak references. Note: this is not 109 activated in the context of compiling these sources for internal 110 use in libcrypt. 111 */ 112 #undef MDXEnd 113 __weak_reference(_libmd_MDXEnd, MDXEnd); 114 #undef MDXFile 115 __weak_reference(_libmd_MDXFile, MDXFile); 116 #undef MDXFileChunk 117 __weak_reference(_libmd_MDXFileChunk, MDXFileChunk); 118 #undef MDXData 119 __weak_reference(_libmd_MDXData, MDXData); 120 #endif 121