From 380195f7cd5e57acf2c1cf2bc41069e6b0b979ed Mon Sep 17 00:00:00 2001 From: Anders Betts Date: Thu, 17 Sep 2026 19:55:36 +0200 Subject: Initial commit: daemon, clients, docs, Docker deploy pipeline --- src/config.c | 171 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 src/config.c (limited to 'src/config.c') diff --git a/src/config.c b/src/config.c new file mode 100644 index 0000000..3bce6e9 --- /dev/null +++ b/src/config.c @@ -0,0 +1,171 @@ +#include "config.h" + +#include +#include +#include + +#include "log.h" +#include "util.h" + +struct config g_cfg; + +static void set_str(char **dst, const char *val) +{ + free(*dst); + *dst = xstrdup(val); +} + +void config_defaults(void) +{ + memset(&g_cfg, 0, sizeof g_cfg); + g_cfg.socket_path = xstrdup("/run/bokfd/bokfd.sock"); + g_cfg.db_path = xstrdup("/var/lib/bokfd/bokfd.db"); + g_cfg.backup_dir = xstrdup("/var/lib/bokfd/backup"); + g_cfg.export_dir = xstrdup("/var/lib/bokfd/export"); + g_cfg.tcp_addr = NULL; + g_cfg.tcp_enabled = 0; + g_cfg.log_level = LOG_INFO; + g_cfg.allow_org_create = 1; + g_cfg.audit_reads = 0; + g_cfg.synchronous = xstrdup("FULL"); + g_cfg.chart_k2_file = xstrdup("/usr/local/share/bokf/bas_k2.csv"); + g_cfg.chart_k3_file = xstrdup("/usr/local/share/bokf/bas_k3.csv"); + g_cfg.session_ttl = 8 * 3600; + g_cfg.max_line_bytes = 1024 * 1024; + g_cfg.max_attachment_bytes = 10 * 1024 * 1024; +} + +static int apply_kv(const char *key, const char *val, char **err) +{ + if (strcmp(key, "socket") == 0) + set_str(&g_cfg.socket_path, val); + else if (strcmp(key, "db") == 0) + set_str(&g_cfg.db_path, val); + else if (strcmp(key, "backup_dir") == 0) + set_str(&g_cfg.backup_dir, val); + else if (strcmp(key, "export_dir") == 0) + set_str(&g_cfg.export_dir, val); + else if (strcmp(key, "tcp") == 0) { + if (strcmp(val, "off") == 0 || strcmp(val, "") == 0) { + g_cfg.tcp_enabled = 0; + } else { + set_str(&g_cfg.tcp_addr, val); + g_cfg.tcp_enabled = 1; + } + } else if (strcmp(key, "log_level") == 0) { + g_cfg.log_level = log_level_from_name(val); + } else if (strcmp(key, "allow_org_create") == 0) { + g_cfg.allow_org_create = strcmp(val, "false") != 0; + } else if (strcmp(key, "audit_reads") == 0) { + g_cfg.audit_reads = strcmp(val, "true") == 0; + } else if (strcmp(key, "synchronous") == 0) { + set_str(&g_cfg.synchronous, val); + } else if (strcmp(key, "chart_k2") == 0) { + set_str(&g_cfg.chart_k2_file, val); + } else if (strcmp(key, "chart_k3") == 0) { + set_str(&g_cfg.chart_k3_file, val); + } else if (strcmp(key, "session_ttl") == 0) { + g_cfg.session_ttl = strtol(val, NULL, 10); + } else if (strcmp(key, "max_line_bytes") == 0) { + g_cfg.max_line_bytes = strtol(val, NULL, 10); + } else if (strcmp(key, "max_attachment_bytes") == 0) { + g_cfg.max_attachment_bytes = strtol(val, NULL, 10); + } else { + char buf[256]; + snprintf(buf, sizeof buf, "unknown config key: %s", key); + if (err) + *err = xstrdup(buf); + return -1; + } + return 0; +} + +int config_load_file(const char *path, char **err) +{ + FILE *f = fopen(path, "r"); + if (!f) { + char buf[512]; + snprintf(buf, sizeof buf, "cannot open config file %s", path); + if (err) + *err = xstrdup(buf); + return -1; + } + char line[1024]; + int lineno = 0; + int rc = 0; + while (fgets(line, sizeof line, f)) { + lineno++; + char *s = line; + char *hash = strchr(s, '#'); + if (hash) + *hash = '\0'; + s = util_str_trim(s); + if (!*s) + continue; + char *eq = strchr(s, '='); + if (!eq) { + char buf[512]; + snprintf(buf, sizeof buf, "%s:%d: expected key = value", path, + lineno); + if (err) + *err = xstrdup(buf); + rc = -1; + break; + } + *eq = '\0'; + char *key = util_str_trim(s); + char *val = util_str_trim(eq + 1); + if (apply_kv(key, val, err) != 0) { + rc = -1; + break; + } + } + fclose(f); + return rc; +} + +void config_apply_env(void) +{ + const char *v; + if ((v = getenv("BOKFD_SOCKET"))) + set_str(&g_cfg.socket_path, v); + if ((v = getenv("BOKFD_DB"))) + set_str(&g_cfg.db_path, v); + if ((v = getenv("BOKFD_BACKUP_DIR"))) + set_str(&g_cfg.backup_dir, v); + if ((v = getenv("BOKFD_EXPORT_DIR"))) + set_str(&g_cfg.export_dir, v); + if ((v = getenv("BOKFD_TCP"))) + apply_kv("tcp", v, NULL); + if ((v = getenv("BOKFD_LOG_LEVEL"))) + g_cfg.log_level = log_level_from_name(v); + if ((v = getenv("BOKFD_ALLOW_ORG_CREATE"))) + g_cfg.allow_org_create = strcmp(v, "false") != 0; + if ((v = getenv("BOKFD_AUDIT_READS"))) + g_cfg.audit_reads = strcmp(v, "true") == 0; + if ((v = getenv("BOKFD_SYNCHRONOUS"))) + set_str(&g_cfg.synchronous, v); + if ((v = getenv("BOKFD_CHART_K2"))) + set_str(&g_cfg.chart_k2_file, v); + if ((v = getenv("BOKFD_CHART_K3"))) + set_str(&g_cfg.chart_k3_file, v); + if ((v = getenv("BOKFD_SESSION_TTL"))) + g_cfg.session_ttl = strtol(v, NULL, 10); + if ((v = getenv("BOKFD_MAX_LINE_BYTES"))) + g_cfg.max_line_bytes = strtol(v, NULL, 10); + if ((v = getenv("BOKFD_MAX_ATTACHMENT_BYTES"))) + g_cfg.max_attachment_bytes = strtol(v, NULL, 10); +} + +void config_free(void) +{ + free(g_cfg.socket_path); + free(g_cfg.db_path); + free(g_cfg.backup_dir); + free(g_cfg.export_dir); + free(g_cfg.tcp_addr); + free(g_cfg.synchronous); + free(g_cfg.chart_k2_file); + free(g_cfg.chart_k3_file); + memset(&g_cfg, 0, sizeof g_cfg); +} -- cgit v1.3