summary refs log tree commit diff
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2020-01-11 01:53:02 -0500
committerJune McEnroe <june@causal.agency>2020-01-11 02:01:01 -0500
commitdc3c4797b321bfe80897ac7dc91d7b3a04507a72 (patch)
tree4b44d2d26d4ae8ad08c93866b107aa4c99587ecf
parentOpen database readwrite in scoop (diff)
downloadlitterbox-dc3c4797b321bfe80897ac7dc91d7b3a04507a72.tar.gz
litterbox-dc3c4797b321bfe80897ac7dc91d7b3a04507a72.zip
Search for config files in XDG base directories
-rw-r--r--config.c42
-rw-r--r--litterbox.118
2 files changed, 58 insertions, 2 deletions
diff --git a/config.c b/config.c
index ce1bd25..a6cd55b 100644
--- a/config.c
+++ b/config.c
@@ -15,11 +15,51 @@
  */
 
 #include <err.h>
+#include <errno.h>
 #include <getopt.h>
+#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
+#define CONFIG_DIR "litterbox"
+
+static FILE *find(const char *path, const char *mode) {
+	if (path[0] == '/' || path[0] == '.') goto local;
+
+	const char *home = getenv("HOME");
+	const char *configHome = getenv("XDG_CONFIG_HOME");
+	const char *configDirs = getenv("XDG_CONFIG_DIRS");
+
+	char buf[PATH_MAX];
+	if (configHome) {
+		snprintf(buf, sizeof(buf), "%s/" CONFIG_DIR "/%s", configHome, path);
+	} else {
+		if (!home) goto local;
+		snprintf(buf, sizeof(buf), "%s/.config/" CONFIG_DIR "/%s", home, path);
+	}
+	FILE *file = fopen(buf, mode);
+	if (file) return file;
+	if (errno != ENOENT) return NULL;
+
+	if (!configDirs) configDirs = "/etc/xdg";
+	while (*configDirs) {
+		size_t len = strcspn(configDirs, ":");
+		snprintf(
+			buf, sizeof(buf), "%.*s/" CONFIG_DIR "/%s",
+			(int)len, configDirs, path
+		);
+		file = fopen(buf, mode);
+		if (file) return file;
+		if (errno != ENOENT) return NULL;
+		configDirs += len;
+		if (*configDirs) configDirs++;
+	}
+
+local:
+	return fopen(path, mode);
+}
+
 #define WS "\t "
 
 static const char *path;
@@ -51,7 +91,7 @@ int getopt_config(
 			if (optind < argc) {
 				num = 0;
 				path = argv[optind++];
-				file = fopen(path, "r");
+				file = find(path, "r");
 				if (!file) {
 					warn("%s", path);
 					return clean('?');
diff --git a/litterbox.1 b/litterbox.1
index d8fc311..79bec7e 100644
--- a/litterbox.1
+++ b/litterbox.1
@@ -1,4 +1,4 @@
-.Dd January 4, 2020
+.Dd January 11, 2020
 .Dt LITTERBOX 1
 .Os
 .
@@ -46,6 +46,12 @@ an existing database can be migrated with
 .Pp
 Options can be loaded from
 files listed on the command line.
+Files are searched for in
+.Pa $XDG_CONFIG_DIRS/litterbox
+unless the path starts with
+.Ql /
+or
+.Ql \&. .
 Each option is placed on a line,
 and lines beginning with
 .Ql #
@@ -169,6 +175,16 @@ Log in with the server password
 .
 .Sh FILES
 .Bl -tag -width Ds
+.It Pa $XDG_CONFIG_DIRS/litterbox
+Configuration files are searched for first in
+.Ev $XDG_CONFIG_HOME ,
+usually
+.Pa ~/.config ,
+followed by the colon-separated list of paths
+.Ev $XDG_CONFIG_DIRS ,
+usually
+.Pa /etc/xdg .
+.
 .It Pa $XDG_DATA_DIRS/litterbox/litterbox.sqlite
 The database file is searched for first in
 .Ev $XDG_DATA_HOME ,