#include #include "gebs/gebs.h" #include "incbin/incbin.h" #include "stb/stb_ds.h" #include "baked.h" #include "locked.h" #include "zip.h" INCBIN(bundle_zip, "./bundle.zip"); static locked(Baked_Resource *) baked_resources = locked_init(nil); void lock_baked_resources(void) { lockx(&baked_resources); } void unlock_baked_resources(void) { unlockx(&baked_resources); } void add_baked_resource(char *key, const uchar *data, size_t size) { int fd = memfd_create(key, 0); if (fd < 0) { LOGE("Could not create resource %s. Aborting...\n", key); abort(); } write(fd, data, size); shput(baked_resources.value, key, ((Baked_Resource_Value){ .memfd = fd, .bufptr = (void *)data })); } void init_baked_resources(void) { lockx(&baked_resources); struct zip_t *zip = zip_stream_open(bundle_zip_data, bundle_zip_size, ZIP_DEFAULT_COMPRESSION_LEVEL, 'r'); size_t n = zip_entries_total(zip); for (size_t i = 0; i < n; i++) { zip_entry_openbyindex(zip, i); const char *name = strdup(zip_entry_name(zip)); size_t size = zip_entry_size(zip); char *buf = malloc(size); zip_entry_noallocread(zip, buf, size); add_baked_resource((char *)name, buf, size); zip_entry_close(zip); } zip_stream_close(zip); unlockx(&baked_resources); } void free_baked_resources(void) { lockx(&baked_resources); for (size_t i = 0; i < shlen(baked_resources.value); i++) { close(baked_resources.value[i].value.memfd); free(baked_resources.value[i].key); free(baked_resources.value[i].value.bufptr); } shfree(baked_resources.value); unlockx(&baked_resources); } bool get_baked_resource_path(char *key, char *buf, size_t size) { if (shgeti(baked_resources.value, key) != -1) { Baked_Resource_Value brv = shget(baked_resources.value, key); snprintf(buf, size, "/proc/%d/fd/%d", getpid(), brv.memfd); unlockx(&baked_resources); return true; } return false; } void baked_resource_each(void (*f)(Baked_Resource *resource, void *udata), void *udata) { for (size_t i = 0; i < shlen(baked_resources.value); i++) { f(&baked_resources.value[i], udata); } }