aboutsummaryrefslogtreecommitdiffstats
path: root/src/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util.c')
-rw-r--r--src/util.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/src/util.c b/src/util.c
index bd7e0bf..35db2e3 100644
--- a/src/util.c
+++ b/src/util.c
@@ -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;
+}
+