mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 16:37:19 +09:00
89 lines
2.4 KiB
C
89 lines
2.4 KiB
C
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
|
|
#include "memory-util.h"
|
|
#include "sysupdate-cache.h"
|
|
|
|
#define WEB_CACHE_ENTRIES_MAX 64U
|
|
#define WEB_CACHE_ITEM_SIZE_MAX (64U*1024U*1024U)
|
|
|
|
static WebCacheItem* web_cache_item_free(WebCacheItem *i) {
|
|
if (!i)
|
|
return NULL;
|
|
|
|
free(i->url);
|
|
return mfree(i);
|
|
}
|
|
|
|
DEFINE_TRIVIAL_CLEANUP_FUNC(WebCacheItem*, web_cache_item_free);
|
|
|
|
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(web_cache_hash_ops, char, string_hash_func, string_compare_func, WebCacheItem, web_cache_item_free);
|
|
|
|
int web_cache_add_item(
|
|
Hashmap **web_cache,
|
|
const char *url,
|
|
bool verified,
|
|
const void *data,
|
|
size_t size) {
|
|
|
|
_cleanup_(web_cache_item_freep) WebCacheItem *item = NULL;
|
|
_cleanup_free_ char *u = NULL;
|
|
int r;
|
|
|
|
assert(web_cache);
|
|
assert(url);
|
|
assert(data || size == 0);
|
|
|
|
if (size > WEB_CACHE_ITEM_SIZE_MAX)
|
|
return -E2BIG;
|
|
|
|
item = web_cache_get_item(*web_cache, url, verified);
|
|
if (item && memcmp_nn(item->data, item->size, data, size) == 0)
|
|
return 0;
|
|
|
|
if (hashmap_size(*web_cache) >= (size_t) (WEB_CACHE_ENTRIES_MAX + !!hashmap_get(*web_cache, url)))
|
|
return -ENOSPC;
|
|
|
|
r = hashmap_ensure_allocated(web_cache, &web_cache_hash_ops);
|
|
if (r < 0)
|
|
return r;
|
|
|
|
u = strdup(url);
|
|
if (!u)
|
|
return -ENOMEM;
|
|
|
|
item = malloc(offsetof(WebCacheItem, data) + size + 1);
|
|
if (!item)
|
|
return -ENOMEM;
|
|
|
|
*item = (WebCacheItem) {
|
|
.url = TAKE_PTR(u),
|
|
.size = size,
|
|
.verified = verified,
|
|
};
|
|
|
|
/* Just to be extra paranoid, let's NUL terminate the downloaded buffer */
|
|
*(uint8_t*) mempcpy(item->data, data, size) = 0;
|
|
|
|
web_cache_item_free(hashmap_remove(*web_cache, url));
|
|
|
|
r = hashmap_put(*web_cache, item->url, item);
|
|
if (r < 0)
|
|
return r;
|
|
|
|
TAKE_PTR(item);
|
|
return 1;
|
|
}
|
|
|
|
WebCacheItem* web_cache_get_item(Hashmap *web_cache, const char *url, bool verified) {
|
|
WebCacheItem *i;
|
|
|
|
i = hashmap_get(web_cache, url);
|
|
if (!i)
|
|
return NULL;
|
|
|
|
if (i->verified != verified)
|
|
return NULL;
|
|
|
|
return i;
|
|
}
|