Hi all,

Attached is a patch to dmenu_path which (if enabled in the config.mk)
changes the cache file location to be XDG Base Directory Specification
compliant. After enabling the change, the cache file will live at
$XDG_CACHE_HOME/dmenu/path.cache (or $HOME/.cache/dmenu/path.cache if
$XDG_CACHE_HOME is not set), rather than in the home directory at
~/.dmenu_cache.

This patch relies on libxdg-basedir [2] being installed.

Thanks for dmenu!

-- 
- Jon Raphaelson

[1] http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
[2] http://repo.or.cz/w/libxdg-basedir.git
diff -r 2b9683c50723 config.mk
--- a/config.mk	Wed Dec 01 20:25:10 2010 +0000
+++ b/config.mk	Thu Dec 30 12:37:58 2010 -0700
@@ -14,12 +14,16 @@
 XINERAMALIBS  = -lXinerama
 XINERAMAFLAGS = -DXINERAMA
 
+# XDG path stuff, comment if you don't want it
+XDGBASEDIRLIBS = "-lxdg-basedir"
+XDGBASEDIRFLAGS = "-DXDGBASEDIR"
+
 # includes and libs
 INCS = -I${X11INC}
-LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS}
+LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${XDGBASEDIRLIBS}
 
 # flags
-CPPFLAGS = -D_BSD_SOURCE -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
+CPPFLAGS = -D_BSD_SOURCE -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} ${XDGBASEDIRFLAGS}
 CFLAGS   = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS}
 LDFLAGS  = -s ${LIBS}
 
diff -r 2b9683c50723 dmenu_path.c
--- a/dmenu_path.c	Wed Dec 01 20:25:10 2010 +0000
+++ b/dmenu_path.c	Thu Dec 30 12:37:58 2010 -0700
@@ -7,12 +7,24 @@
 #include <unistd.h>
 #include <sys/stat.h>
 
-#define CACHE ".dmenu_cache"
+#ifdef XDGBASEDIR
+	#include <basedir.h>
+	#include <basedir_fs.h>
+	#include <errno.h>
+
+	#define CACHEDIR "/dmenu"
+	#define CACHEFILE "/path.cache"
+
+	static char *cachefile;
+#else
+	#define CACHE ".dmenu_cache"
+#endif
 
 static void die(const char *s);
 static int qstrcmp(const void *a, const void *b);
 static void scan(void);
 static int uptodate(void);
+static const char * getCacheFile(void);
 
 static char **items = NULL;
 static const char *home, *path;
@@ -26,7 +38,7 @@
 	if(chdir(home) < 0)
 		die("chdir failed");
 	if(uptodate()) {
-		execlp("cat", "cat", CACHE, NULL);
+		execlp("cat", "cat", getCacheFile(), NULL);
 		die("exec failed");
 	}
 	scan();
@@ -71,7 +83,7 @@
 		closedir(dp);
 	}
 	qsort(items, count, sizeof *items, qstrcmp);
-	if(!(cache = fopen(CACHE, "w")))
+	if(!(cache = fopen(getCacheFile(), "w")))
 		die("open failed");
 	for(i = 0; i < count; i++) {
 		if(i > 0 && !strcmp(items[i], items[i-1]))
@@ -89,7 +101,7 @@
 	time_t mtime;
 	struct stat st;
 
-	if(stat(CACHE, &st) < 0)
+	if(stat(getCacheFile(), &st) < 0)
 		return 0;
 	mtime = st.st_mtime;
 	if(!(p = strdup(path)))
@@ -100,3 +112,33 @@
 	free(p);
 	return 1;
 }
+
+const char * 
+getCacheFile(void) {
+#ifdef XDGBASEDIR
+	if (cachefile == NULL) {
+		xdgHandle* handle;
+		char cachepath[256];
+
+		handle = xdgInitHandle(malloc(sizeof(xdgHandle)));
+
+		strncpy(cachepath, xdgCacheHome(handle), 256);
+		strcat(cachepath, CACHEDIR);
+
+		int ret = xdgMakePath(cachepath, 0755);
+		if (ret < 0 && errno != EEXIST) {
+			perror("couldn't make path");
+			exit(errno);
+		}
+
+		strcat(cachepath, CACHEFILE);
+
+		cachefile = malloc(strlen(cachepath) * sizeof(char));
+		strncpy(cachefile, cachepath, strlen(cachepath));
+	}
+
+	return cachefile;
+#else
+	return CACHE;
+#endif
+}

Reply via email to