diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 20:49:52 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 20:49:52 +0000 |
commit | 55944e5e40b1be2afc4855d8d2baf4b73d1876b5 (patch) | |
tree | 33f869f55a1b149e9b7c2b7e201867ca5dd52992 /src/sysupdate/sysupdate-cache.c | |
parent | Initial commit. (diff) | |
download | systemd-55944e5e40b1be2afc4855d8d2baf4b73d1876b5.tar.xz systemd-55944e5e40b1be2afc4855d8d2baf4b73d1876b5.zip |
Adding upstream version 255.4.upstream/255.4
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/sysupdate/sysupdate-cache.c')
-rw-r--r-- | src/sysupdate/sysupdate-cache.c | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/src/sysupdate/sysupdate-cache.c b/src/sysupdate/sysupdate-cache.c new file mode 100644 index 0000000..8dad3ee --- /dev/null +++ b/src/sysupdate/sysupdate-cache.c @@ -0,0 +1,88 @@ +/* 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; +} |