]> pd.if.org Git - zpackage/blob - lib/zpm_hash.c
2c1fc251f8be2b78a7baab113a3a0944a17e5a03
[zpackage] / lib / zpm_hash.c
1 #define _POSIX_C_SOURCE 200809L
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <sys/mman.h>
9 #include <unistd.h>
10 #include <fcntl.h>
11 #include <errno.h>
12
13 #include "zpm.h"
14 #include "elf.h"
15
16 #include "blake2.h"
17
18 int zpm_hash_mem(void *mem, size_t size, char *hash) {
19         struct blake2b_state__ blake;
20         int j;
21         unsigned char tmp[32];
22         
23         blake2b_init(&blake, sizeof tmp);
24         blake2b_update(&blake, mem, size);
25         blake2b_final(&blake, tmp, sizeof tmp);
26         for (j=0;j<32;j++) {
27                 sprintf(hash+j*2, "%02x", (unsigned)tmp[j]);
28         }
29         return 1;
30 }
31
32 /* flags 0, close mmap, flags 1, return mmap fd */
33 int zpm_hash(char *path, char *hash, uint32_t flags) {
34         int fd;
35         void *content;
36         struct stat sbuf;
37
38         /* mmap the file */
39         fd = open(path, O_RDONLY);
40         if (fd == -1) {
41                 fprintf(stderr, "%s can't open %s: %s\n", __FUNCTION__, path,strerror(errno));
42                 return 0;
43         }
44         if (fstat(fd, &sbuf) == -1) {
45                 fprintf(stderr, "%s can't fstat %s: %s\n", __FUNCTION__, path,strerror(errno));
46                 return 0;
47         }
48         /* not a regular file? */
49         if (!S_ISREG(sbuf.st_mode)) {
50                 /* TODO this is ok, just stored differently */
51                 fprintf(stderr, "%s non-regular files unsupported %s\n", __FUNCTION__, path);
52                 return 0;
53         }
54
55         content = mmap(0, sbuf.st_size, PROT_READ,MAP_PRIVATE, fd, 0);
56         close(fd);
57         if (!content) {
58                 fprintf(stderr, "%s can't mmap %s: %s\n", __FUNCTION__, path,strerror(errno));
59                 return 0;
60         }
61
62         zpm_hash_mem(content, sbuf.st_size, hash);
63         hash[64] = 0;
64         munmap(content, sbuf.st_size);
65         return flags ? fd : 1;
66 }