38 #include <openssl/sha.h>
40 #include "xbps_api_impl.h"
48 digest2string(
const uint8_t *digest,
char *
string,
size_t len)
51 if (*digest / 16 < 10)
52 *
string++ =
'0' + *digest / 16;
54 *
string++ =
'a' + *digest / 16 - 10;
55 if (*digest % 16 < 10)
56 *
string++ =
'0' + *digest % 16;
58 *
string++ =
'a' + *digest % 16 - 10;
68 size_t pgsize = (size_t)sysconf(_SC_PAGESIZE);
69 size_t pgmask = pgsize - 1, mapsize;
70 char hash[SHA256_DIGEST_LENGTH * 2 + 1];
71 unsigned char *buf = NULL, digest[SHA256_DIGEST_LENGTH];
73 bool need_guard =
false;
77 if ((fd = open(file, O_RDONLY|O_CLOEXEC)) == -1) {
81 memset(&st, 0,
sizeof(st));
82 if (fstat(fd, &st) == -1) {
86 if (st.st_size > SSIZE_MAX - 1) {
91 mapsize = ((size_t)st.st_size + pgmask) & ~pgmask;
92 if (mapsize < (
size_t)st.st_size) {
101 if ((st.st_size & pgmask) == 0)
104 buf = mmap(NULL, need_guard ? mapsize + pgsize : mapsize,
105 PROT_READ, MAP_PRIVATE, fd, 0);
107 if (buf == MAP_FAILED)
110 (void)madvise(buf, mapsize, MADV_SEQUENTIAL);
111 if (SHA256(buf, st.st_size, digest) == NULL) {
112 munmap(buf, mapsize);
115 (void)madvise(buf, mapsize, MADV_DONTNEED);
116 munmap(buf, mapsize);
118 digest2string(digest, hash, SHA256_DIGEST_LENGTH);
128 assert(file != NULL);
129 assert(sha256 != NULL);
135 if (strcmp(sha256, res)) {
145 file_hash_dictionary(prop_dictionary_t d,
const char *key,
const char *file)
148 prop_object_iterator_t iter;
149 const char *curfile = NULL, *sha256 = NULL;
151 assert(prop_object_type(d) == PROP_TYPE_DICTIONARY);
153 assert(file != NULL);
160 while ((obj = prop_object_iterator_next(iter)) != NULL) {
161 prop_dictionary_get_cstring_nocopy(obj,
163 if (strcmp(file, curfile) == 0) {
165 prop_dictionary_get_cstring_nocopy(obj,
170 prop_object_iterator_release(iter);
178 xbps_file_hash_check_dictionary(
struct xbps_handle *xhp,
183 const char *sha256d = NULL;
187 assert(prop_object_type(d) == PROP_TYPE_DICTIONARY);
189 assert(file != NULL);
191 if ((sha256d = file_hash_dictionary(d, key, file)) == NULL) {
198 if (strcmp(xhp->
rootdir,
"/") == 0) {
207 else if (rv == ERANGE || rv == ENOENT)