]> pd.if.org Git - zpackage/blobdiff - lib/zpm_hash.c
separate zpm_hash function
[zpackage] / lib / zpm_hash.c
diff --git a/lib/zpm_hash.c b/lib/zpm_hash.c
new file mode 100644 (file)
index 0000000..a14f7d6
--- /dev/null
@@ -0,0 +1,61 @@
+#define _POSIX_C_SOURCE 200809L
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include "zpm.h"
+#include "elf.h"
+
+#include "sha256.h"
+
+/* flags 0, close mmap, flags 1, return mmap fd */
+int zpm_hash(char *path, char *hash, uint32_t flags) {
+       int fd;
+       void *content;
+       struct stat sbuf;
+       struct sha256_state md;
+       int j;
+       unsigned char tmp[32];
+
+       /* mmap the file */
+       fd = open(path, O_RDONLY);
+       if (fd == -1) {
+               fprintf(stderr, "%s can't open %s: %s\n", __FUNCTION__, path,strerror(errno));
+               return 0;
+       }
+       if (fstat(fd, &sbuf) == -1) {
+               fprintf(stderr, "%s can't fstat %s: %s\n", __FUNCTION__, path,strerror(errno));
+               return 0;
+       }
+       /* not a regular file? */
+       if (!S_ISREG(sbuf.st_mode)) {
+               /* TODO this is ok, just stored differently */
+               fprintf(stderr, "%s non-regular files unsupported %s\n", __FUNCTION__, path);
+               return 0;
+       }
+
+       content = mmap(0, sbuf.st_size, PROT_READ,MAP_PRIVATE, fd, 0);
+       close(fd);
+       if (!content) {
+               fprintf(stderr, "%s can't mmap %s: %s\n", __FUNCTION__, path,strerror(errno));
+               return 0;
+       }
+
+       /* get hash */
+       sha256_init(&md);
+       sha256_process(&md, content, sbuf.st_size);
+       sha256_done(&md, tmp);
+       for (j=0;j<32;j++) {
+               sprintf(hash+j*2, "%02x", (unsigned)tmp[j]);
+       }
+       hash[64] = 0;
+       munmap(content, sbuf.st_size);
+       return flags ? fd : 1;
+}