]> pd.if.org Git - zpackage/blob - lib/zpm_hash.c
a14f7d62597136132486a613a04e847a83aeedbd
[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 "sha256.h"
17
18 /* flags 0, close mmap, flags 1, return mmap fd */
19 int zpm_hash(char *path, char *hash, uint32_t flags) {
20         int fd;
21         void *content;
22         struct stat sbuf;
23         struct sha256_state md;
24         int j;
25         unsigned char tmp[32];
26
27         /* mmap the file */
28         fd = open(path, O_RDONLY);
29         if (fd == -1) {
30                 fprintf(stderr, "%s can't open %s: %s\n", __FUNCTION__, path,strerror(errno));
31                 return 0;
32         }
33         if (fstat(fd, &sbuf) == -1) {
34                 fprintf(stderr, "%s can't fstat %s: %s\n", __FUNCTION__, path,strerror(errno));
35                 return 0;
36         }
37         /* not a regular file? */
38         if (!S_ISREG(sbuf.st_mode)) {
39                 /* TODO this is ok, just stored differently */
40                 fprintf(stderr, "%s non-regular files unsupported %s\n", __FUNCTION__, path);
41                 return 0;
42         }
43
44         content = mmap(0, sbuf.st_size, PROT_READ,MAP_PRIVATE, fd, 0);
45         close(fd);
46         if (!content) {
47                 fprintf(stderr, "%s can't mmap %s: %s\n", __FUNCTION__, path,strerror(errno));
48                 return 0;
49         }
50
51         /* get hash */
52         sha256_init(&md);
53         sha256_process(&md, content, sbuf.st_size);
54         sha256_done(&md, tmp);
55         for (j=0;j<32;j++) {
56                 sprintf(hash+j*2, "%02x", (unsigned)tmp[j]);
57         }
58         hash[64] = 0;
59         munmap(content, sbuf.st_size);
60         return flags ? fd : 1;
61 }