From 8a65fd032e6f74938caf84d6f6fcda6314e76a01 Mon Sep 17 00:00:00 2001 From: eunhhu Date: Fri, 25 Sep 2026 09:32:46 +0100 Subject: Move document key listing behind the store API The terminal editor listed documents by reading the flat store's obj- file names, so a UI host depended on one storage layout. pure_store_keys now lists keys through the selected store; per-object file stores share store-keys.c, linked only by hosts that browse documents, so the default CLI and HTTP hosts are unchanged. The source TUI ceiling reviews the measured 368-byte cost. --- prototypes/connections/store-keys.c | 41 +++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 prototypes/connections/store-keys.c (limited to 'prototypes/connections/store-keys.c') diff --git a/prototypes/connections/store-keys.c b/prototypes/connections/store-keys.c new file mode 100644 index 0000000..d5aeb69 --- /dev/null +++ b/prototypes/connections/store-keys.c @@ -0,0 +1,41 @@ +#define _POSIX_C_SOURCE 200809L +#include "store.h" +#include +#include +#include +#include +#include + +/* Key listing for the stores that publish each object as obj-KEY (the flat + * and paged formats). Linked only by hosts that browse documents, so the + * default CLI and HTTP hosts do not carry it. */ +static bool valid_key(const char *key) { + size_t length = strlen(key); + if (!length || length > 64) return false; + for (size_t i = 0; i < length; ++i) { + unsigned char c = (unsigned char)key[i]; + if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9') || c == '_' || c == '-')) return false; + } + return true; +} + +PureResult pure_store_keys(const char *path, bool (*visit)(void *, const char *key), + void *context) { + int descriptor = open(path, O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC); + DIR *directory = descriptor >= 0 ? fdopendir(descriptor) : NULL; + if (!directory) { + if (descriptor >= 0) close(descriptor); + return PURE_STORE_ERROR; + } + PureResult result = PURE_OK; + for (;;) { + errno = 0; + struct dirent *entry = readdir(directory); + if (!entry) { if (errno) result = PURE_STORE_ERROR; break; } + if (strncmp(entry->d_name, "obj-", 4) || !valid_key(entry->d_name + 4)) continue; + if (!visit(context, entry->d_name + 4)) break; + } + if (closedir(directory)) result = PURE_STORE_ERROR; + return result; +} -- cgit v1.2.3