diff options
Diffstat (limited to 'src/util.c')
-rw-r--r-- | src/util.c | 41 |
1 files changed, 41 insertions, 0 deletions
@@ -16,6 +16,7 @@ #include <string.h> #include "util.h" +#include "sha1.h" #define _FILENAME "util.c" #include "dbg.h" @@ -80,3 +81,43 @@ char *concat(size_t count, ...) { va_end(ap2); return result; } + +/* Hash the target file, returning a pointer to the heap allocated hash. */ +unsigned char *hash_file(FILE *fp) { + unsigned char *hash = xmalloc(20); + + SHA_CTX context; + unsigned char data[8192]; + size_t read; + + SHA1_Init(&context); + while ((read = fread(data, 1, sizeof data, fp))) + SHA1_Update(&context, data, read); + + if (ferror(fp)) + fatal("redo: failed to read data"); + SHA1_Final(hash, &context); + + return hash; +} + +/* Requires a buffer of at least 20*2+1 = 41 bytes */ +void sha1_to_hex(const unsigned char *sha1, char *buf) { + static const char hex[] = "0123456789abcdef"; + + for (int i = 0; i < 20; ++i) { + char *pos = buf + i*2; + *pos++ = hex[sha1[i] >> 4]; + *pos = hex[sha1[i] & 0xf]; + } + + buf[40] = '\0'; +} + +void hex_to_sha1(const char *s, unsigned char *sha1) { + static const char hex[] = "0123456789abcdef"; + + for (; *s; s += 2, ++sha1) + *sha1 = ((strchr(hex, *s) - hex) << 4) + strchr(hex, *(s+1)) - hex; +} + |