From fa944345a63a083555a1f1933aabf4ea6f27a307 Mon Sep 17 00:00:00 2001 From: "C. McEnroe" Date: Tue, 5 Oct 2021 23:16:32 -0400 Subject: Refactor XDG base directory iterator API Finally something more reasonable for call sites. --- bounce.c | 8 +++--- bounce.h | 4 +-- local.c | 17 ++++++------- server.c | 20 +++++++-------- xdg.c | 89 ++++++++++++++++++++++++++++++---------------------------------- 5 files changed, 65 insertions(+), 73 deletions(-) diff --git a/bounce.c b/bounce.c index 7f0add5..12cacf5 100644 --- a/bounce.c +++ b/bounce.c @@ -139,10 +139,10 @@ static void unveilTarget(const char *path, const char *mode) { } static void unveilConfig(const char *path) { - const char *dirs = NULL; - for (const char *abs; NULL != (abs = configPath(&dirs, path));) { - unveilParent(abs, "r"); - unveilTarget(abs, "r"); + char buf[PATH_MAX]; + for (int i = 0; configPath(buf, sizeof(buf), path, i); ++i) { + unveilParent(buf, "r"); + unveilTarget(buf, "r"); } } #endif /* __OpenBSD__ */ diff --git a/bounce.h b/bounce.h index 295a448..8e6ed09 100644 --- a/bounce.h +++ b/bounce.h @@ -249,8 +249,8 @@ void stateSync(struct Client *client); const char *stateNick(void); const char *stateEcho(void); -const char *configPath(const char **dirs, const char *path); -const char *dataPath(const char **dirs, const char *path); +char *configPath(char *buf, size_t cap, const char *path, int i); +char *dataPath(char *buf, size_t cap, const char *path, int i); FILE *configOpen(const char *path, const char *mode); FILE *dataOpen(const char *path, const char *mode); diff --git a/local.c b/local.c index 35286b3..ece94ca 100644 --- a/local.c +++ b/local.c @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -52,24 +53,22 @@ int localConfig( if (!config) errx(EX_SOFTWARE, "tls_config_new"); int error; - const char *dirs = NULL; - for (const char *path; NULL != (path = configPath(&dirs, cert));) { - error = tls_config_set_cert_file(config, path); + char buf[PATH_MAX]; + for (int i = 0; configPath(buf, sizeof(buf), cert, i); ++i) { + error = tls_config_set_cert_file(config, buf); if (!error) break; } if (error) goto fail; - dirs = NULL; - for (const char *path; NULL != (path = configPath(&dirs, priv));) { - error = tls_config_set_key_file(config, path); + for (int i = 0; configPath(buf, sizeof(buf), priv, i); ++i) { + error = tls_config_set_key_file(config, buf); if (!error) break; } if (error) goto fail; if (ca) { - dirs = NULL; - for (const char *path; NULL != (path = configPath(&dirs, ca));) { - error = tls_config_set_ca_file(config, path); + for (int i = 0; configPath(buf, sizeof(buf), ca, i); ++i) { + error = tls_config_set_ca_file(config, buf); if (!error) break; } if (error) goto fail; diff --git a/server.c b/server.c index 552f521..0c6bccc 100644 --- a/server.c +++ b/server.c @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -47,6 +48,7 @@ void serverConfig( bool insecure, const char *trust, const char *cert, const char *priv ) { int error = 0; + char buf[PATH_MAX]; config = tls_config_new(); if (!config) errx(EX_SOFTWARE, "tls_config_new"); @@ -54,32 +56,30 @@ void serverConfig( tls_config_insecure_noverifycert(config); tls_config_insecure_noverifyname(config); } + if (trust) { tls_config_insecure_noverifyname(config); - const char *dirs = NULL; - for (const char *path; NULL != (path = configPath(&dirs, trust));) { - error = tls_config_set_ca_file(config, path); + for (int i = 0; configPath(buf, sizeof(buf), trust, i); ++i) { + error = tls_config_set_ca_file(config, buf); if (!error) break; } if (error) errx(EX_NOINPUT, "%s: %s", trust, tls_config_error(config)); } if (cert) { - const char *dirs = NULL; - for (const char *path; NULL != (path = configPath(&dirs, cert));) { + for (int i = 0; configPath(buf, sizeof(buf), cert, i); ++i) { if (priv) { - error = tls_config_set_cert_file(config, path); + error = tls_config_set_cert_file(config, buf); } else { - error = tls_config_set_keypair_file(config, path, path); + error = tls_config_set_keypair_file(config, buf, buf); } if (!error) break; } if (error) errx(EX_NOINPUT, "%s: %s", cert, tls_config_error(config)); } if (priv) { - const char *dirs = NULL; - for (const char *path; NULL != (path = configPath(&dirs, priv));) { - error = tls_config_set_key_file(config, path); + for (int i = 0; configPath(buf, sizeof(buf), priv, i); ++i) { + error = tls_config_set_key_file(config, buf); if (!error) break; } if (error) errx(EX_NOINPUT, "%s: %s", priv, tls_config_error(config)); diff --git a/xdg.c b/xdg.c index 67f4ab0..5147471 100644 --- a/xdg.c +++ b/xdg.c @@ -59,80 +59,73 @@ static const struct Base Data = { .defDirs = "/usr/local/share:/usr/share", }; -static const char * -basePath(struct Base base, const char **dirs, const char *path) { - static char buf[PATH_MAX]; - - if (*dirs) { - if (!**dirs) return NULL; - size_t len = strcspn(*dirs, ":"); - snprintf(buf, sizeof(buf), "%.*s/" SUBDIR "/%s", (int)len, *dirs, path); - *dirs += len; - if (**dirs) *dirs += 1; +static char *basePath( + struct Base base, char *buf, size_t cap, const char *path, int i +) { + if (path[strspn(path, ".")] == '/') { + if (i > 0) return NULL; + snprintf(buf, cap, "%s", path); return buf; } - if (path[strspn(path, ".")] == '/') { - *dirs = ""; - return path; + if (i > 0) { + const char *dirs = getenv(base.envDirs); + if (!dirs) dirs = base.defDirs; + for (; i > 1; --i) { + dirs += strcspn(dirs, ":"); + dirs += (*dirs == ':'); + } + if (!*dirs) return NULL; + snprintf( + buf, cap, "%.*s/" SUBDIR "/%s", + (int)strcspn(dirs, ":"), dirs, path + ); + return buf; } - *dirs = getenv(base.envDirs); - if (!*dirs) *dirs = base.defDirs; - const char *home = getenv("HOME"); const char *baseHome = getenv(base.envHome); if (baseHome) { - snprintf(buf, sizeof(buf), "%s/" SUBDIR "/%s", baseHome, path); + snprintf(buf, cap, "%s/" SUBDIR "/%s", baseHome, path); } else if (home) { - snprintf( - buf, sizeof(buf), "%s/%s/" SUBDIR "/%s", - home, base.defHome, path - ); + snprintf(buf, cap, "%s/%s/" SUBDIR "/%s", home, base.defHome, path); } else { - errx(EX_CONFIG, "HOME unset"); + errx(EX_USAGE, "HOME unset"); } return buf; } -const char *configPath(const char **dirs, const char *path) { - return basePath(Config, dirs, path); +char *configPath(char *buf, size_t cap, const char *path, int i) { + return basePath(Config, buf, cap, path, i); } -const char *dataPath(const char **dirs, const char *path) { - return basePath(Data, dirs, path); +char *dataPath(char *buf, size_t cap, const char *path, int i) { + return basePath(Data, buf, cap, path, i); } FILE *configOpen(const char *path, const char *mode) { - const char *dirs = NULL; - for (const char *abs; NULL != (abs = configPath(&dirs, path));) { - FILE *file = fopen(abs, mode); + char buf[PATH_MAX]; + for (int i = 0; configPath(buf, sizeof(buf), path, i); ++i) { + FILE *file = fopen(buf, mode); if (file) return file; - if (errno != ENOENT) warn("%s", abs); + if (errno != ENOENT) warn("%s", buf); } - dirs = NULL; - warn("%s", configPath(&dirs, path)); + warn("%s", configPath(buf, sizeof(buf), path, 0)); return NULL; } -static void dataMkdir(const char *path) { - const char *dirs = NULL; - path = dataPath(&dirs, path); - int error = mkdir(path, S_IRWXU); - if (error && errno != EEXIST) warn("%s", path); -} - FILE *dataOpen(const char *path, const char *mode) { - const char *dirs = NULL; - for (const char *abs; NULL != (abs = dataPath(&dirs, path));) { - FILE *file = fopen(abs, mode); + char buf[PATH_MAX]; + for (int i = 0; dataPath(buf, sizeof(buf), path, i); ++i) { + FILE *file = fopen(buf, mode); if (file) return file; - if (errno != ENOENT) warn("%s", abs); + if (errno != ENOENT) warn("%s", buf); + } + if (mode[0] != 'r') { + int error = mkdir(dataPath(buf, sizeof(buf), "", 0), S_IRWXU); + if (error && errno != EEXIST) warn("%s", buf); } - if (mode[0] != 'r') dataMkdir(""); - dirs = NULL; - path = dataPath(&dirs, path); - FILE *file = fopen(path, mode); - if (!file) warn("%s", path); + FILE *file = fopen(dataPath(buf, sizeof(buf), path, 0), mode); + if (!file) warn("%s", buf); return file; } -- cgit 1.4.1