From e8fc08387bc54be815b176afa8c4e2dcffa59c7b Mon Sep 17 00:00:00 2001 From: "C. McEnroe" Date: Sat, 16 Oct 2021 17:19:23 -0400 Subject: Import refactored xdg.c from pounce --- database.h | 14 +++++----- litterbox.c | 16 +++++------ xdg.c | 89 ++++++++++++++++++++++++++++--------------------------------- 3 files changed, 55 insertions(+), 64 deletions(-) diff --git a/database.h b/database.h index 15704f0..4de1625 100644 --- a/database.h +++ b/database.h @@ -41,11 +41,10 @@ #define SQL(...) #__VA_ARGS__ #define ARRAY_LEN(a) (sizeof(a) / sizeof((a)[0])) -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); -void dataMkdir(const char *path); int getopt_config( int argc, char *const *argv, const char *optstring, const struct option *longopts, int *longindex @@ -114,13 +113,14 @@ static inline void dbFind(const char *path, int flags) { errx(EX_NOINPUT, "%s: database not found", path); } + char buf[PATH_MAX]; if (flags & SQLITE_OPEN_CREATE) { - dataMkdir(""); + int error = mkdir(dataPath(buf, sizeof(buf), "", 0), S_IRWXU); + if (error && errno != EEXIST) err(EX_CANTCREAT, "%s", buf); } - const char *dirs = NULL; - while (NULL != (path = dataPath(&dirs, DatabasePath))) { - dbOpen(path, flags); + for (int i = 0; dataPath(buf, sizeof(buf), DatabasePath, i); ++i) { + dbOpen(buf, flags); if (db) return; } errx(EX_NOINPUT, "database not found; initialize it with litterbox -i"); diff --git a/litterbox.c b/litterbox.c index ebc9850..5d48b7a 100644 --- a/litterbox.c +++ b/litterbox.c @@ -766,7 +766,7 @@ static void quit(int sig) { int main(int argc, char *argv[]) { bool init = false; bool migrate = false; - const char *path = NULL; + const char *dbPath = NULL; const char *backup = NULL; bool insecure = false; @@ -816,7 +816,7 @@ int main(int argc, char *argv[]) { break; case 'U': scooperURL = optarg; break; case 'b': backup = optarg; break; case 'c': cert = optarg; - break; case 'd': path = optarg; + break; case 'd': dbPath = optarg; break; case 'h': host = optarg; break; case 'i': init = true; break; case 'j': join = optarg; @@ -841,7 +841,7 @@ int main(int argc, char *argv[]) { int flags = SQLITE_OPEN_READWRITE; if (init) flags |= SQLITE_OPEN_CREATE; - dbFind(path, flags); + dbFind(dbPath, flags); atexit(atExit); if (init) { @@ -870,6 +870,7 @@ int main(int argc, char *argv[]) { if (!client) errx(EX_SOFTWARE, "tls_client"); int error; + char path[PATH_MAX]; struct tls_config *config = tls_config_new(); if (!config) errx(EX_SOFTWARE, "tls_config_new"); @@ -879,8 +880,7 @@ int main(int argc, char *argv[]) { } if (trust) { tls_config_insecure_noverifyname(config); - const char *dirs = NULL; - while (NULL != (path = configPath(&dirs, trust))) { + for (int i = 0; configPath(path, sizeof(path), trust, i); ++i) { error = tls_config_set_ca_file(config, path); if (!error) break; } @@ -888,8 +888,7 @@ int main(int argc, char *argv[]) { } if (cert) { - const char *dirs = NULL; - while (NULL != (path = configPath(&dirs, cert))) { + for (int i = 0; configPath(path, sizeof(path), cert, i); ++i) { if (priv) { error = tls_config_set_cert_file(config, path); } else { @@ -900,8 +899,7 @@ int main(int argc, char *argv[]) { if (error) errx(EX_NOINPUT, "%s: %s", cert, tls_config_error(config)); } if (priv) { - const char *dirs = NULL; - while (NULL != (path = configPath(&dirs, priv))) { + for (int i = 0; configPath(path, sizeof(path), priv, i); ++i) { error = tls_config_set_key_file(config, path); if (!error) break; } diff --git a/xdg.c b/xdg.c index c22bc0a..c04e317 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; } -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