+/* 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;
+ hash_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 1;
+}
+