From 5d0c665b5227f39406ece461b45110299c1f88a7 Mon Sep 17 00:00:00 2001 From: Mario Fetka Date: Sun, 31 May 2026 09:33:33 +0000 Subject: [PATCH] salvage: load config through ini getter --- include/nwsalvage.h | 8 ++++ src/nwsalvage.c | 51 +++++++++++++++++++++++ tests/salvage/salvage_config_smoke.c | 60 ++++++++++++++++++++++++++++ 3 files changed, 119 insertions(+) diff --git a/include/nwsalvage.h b/include/nwsalvage.h index e2126c2..6c8911c 100644 --- a/include/nwsalvage.h +++ b/include/nwsalvage.h @@ -3,6 +3,9 @@ #include +typedef int (*nwsalvage_ini_getter)(int entry, char *str, + size_t strsize, void *data); + #define NWSALVAGE_ENABLE_INI_SECTION 48 #define NWSALVAGE_REPOSITORY_INI_SECTION 49 @@ -22,8 +25,13 @@ int nwsalvage_config_defaults(struct nwsalvage_config *config); int nwsalvage_config_set_repositories(struct nwsalvage_config *config, const char *recycle_repository, const char *metadata_repository); +int nwsalvage_config_parse_enabled(struct nwsalvage_config *config, + const char *line); int nwsalvage_config_parse_repositories(struct nwsalvage_config *config, const char *line); +int nwsalvage_config_load_from_ini(struct nwsalvage_config *config, + nwsalvage_ini_getter getter, + void *data); int nwsalvage_repository_name_valid(const char *name); int nwsalvage_relative_path_valid(const char *relative_path); int nwsalvage_build_recycle_path(char *out, size_t out_len, diff --git a/src/nwsalvage.c b/src/nwsalvage.c index 116bce2..812d3ce 100644 --- a/src/nwsalvage.c +++ b/src/nwsalvage.c @@ -70,6 +70,27 @@ int nwsalvage_config_defaults(struct nwsalvage_config *config) NWSALVAGE_DEFAULT_METADATA_NAME)); } + +int nwsalvage_config_parse_enabled(struct nwsalvage_config *config, + const char *line) +{ + int enabled; + char tail; + + if (!config || !line) { + errno = EINVAL; + return(-1); + } + + if (sscanf(line, " %i %c", &enabled, &tail) != 1) { + errno = EINVAL; + return(-1); + } + + config->enabled = enabled ? 1 : 0; + return(0); +} + static int parse_token(const char **cursor, char *out, size_t out_len) { const char *p = *cursor; @@ -120,6 +141,36 @@ int nwsalvage_config_parse_repositories(struct nwsalvage_config *config, metadata_repository)); } + +int nwsalvage_config_load_from_ini(struct nwsalvage_config *config, + nwsalvage_ini_getter getter, + void *data) +{ + char line[256]; + + if (!config || !getter) { + errno = EINVAL; + return(-1); + } + + if (nwsalvage_config_defaults(config) < 0) + return(-1); + + if (getter(NWSALVAGE_ENABLE_INI_SECTION, + line, sizeof(line), data)) { + if (nwsalvage_config_parse_enabled(config, line) < 0) + return(-1); + } + + if (getter(NWSALVAGE_REPOSITORY_INI_SECTION, + line, sizeof(line), data)) { + if (nwsalvage_config_parse_repositories(config, line) < 0) + return(-1); + } + + return(0); +} + static int path_is_separator(char c) { return(c == '/'); diff --git a/tests/salvage/salvage_config_smoke.c b/tests/salvage/salvage_config_smoke.c index 478f681..d1870eb 100644 --- a/tests/salvage/salvage_config_smoke.c +++ b/tests/salvage/salvage_config_smoke.c @@ -4,6 +4,30 @@ #include #include + +struct fake_ini { + const char *enable_line; + const char *repositories_line; +}; + +static int fake_ini_getter(int entry, char *str, size_t strsize, void *data) +{ + struct fake_ini *ini = data; + const char *line = NULL; + + if (entry == NWSALVAGE_ENABLE_INI_SECTION) + line = ini->enable_line; + else if (entry == NWSALVAGE_REPOSITORY_INI_SECTION) + line = ini->repositories_line; + + if (!line) + return(0); + + if (snprintf(str, strsize, "%s", line) < 0) + return(0); + return(1); +} + static int expect_true(int condition, const char *message) { if (!condition) { @@ -17,6 +41,7 @@ int main(void) { struct nwsalvage_config config; char path[NWSALVAGE_PATH_MAX]; + struct fake_ini ini; int failures = 0; failures += expect_true(nwsalvage_config_defaults(&config) == 0, @@ -54,6 +79,41 @@ int main(void) &config, ".recycle .salvage extra") < 0, "repository line rejects extra tokens"); + failures += expect_true(nwsalvage_config_parse_enabled(&config, "0") == 0, + "section 48 parses disabled value"); + failures += expect_true(config.enabled == 0, + "section 48 disables salvage"); + failures += expect_true(nwsalvage_config_parse_enabled(&config, "1") == 0, + "section 48 parses enabled value"); + failures += expect_true(config.enabled == 1, + "section 48 enables salvage"); + failures += expect_true(nwsalvage_config_parse_enabled(&config, "bad") < 0, + "section 48 rejects invalid value"); + + ini.enable_line = "0"; + ini.repositories_line = "trash meta"; + failures += expect_true(nwsalvage_config_load_from_ini( + &config, fake_ini_getter, &ini) == 0, + "server-style ini getter loads salvage config"); + failures += expect_true(config.enabled == 0, + "ini getter applied section 48"); + failures += expect_true(!strcmp(config.recycle_repository, "trash"), + "ini getter applied section 49 recycle name"); + failures += expect_true(!strcmp(config.metadata_repository, "meta"), + "ini getter applied section 49 metadata name"); + + ini.enable_line = NULL; + ini.repositories_line = NULL; + failures += expect_true(nwsalvage_config_load_from_ini( + &config, fake_ini_getter, &ini) == 0, + "missing ini sections keep defaults"); + failures += expect_true(config.enabled == 1, + "missing section 48 keeps default enabled"); + failures += expect_true(!strcmp(config.recycle_repository, ".recycle"), + "missing section 49 keeps default recycle name"); + failures += expect_true(!strcmp(config.metadata_repository, ".salvage"), + "missing section 49 keeps default metadata name"); + failures += expect_true(nwsalvage_config_defaults(&config) == 0, "defaults reset after custom repository parse"); failures += expect_true(nwsalvage_build_recycle_path(