~emersion/mrsh

44875aad0891b25908ffc8765521c3865a1c2b67 — r4pr0n 16 days ago 280fdf5 xdg-dir
Make history xdg base directory specification compliant
1 files changed, 42 insertions(+), 2 deletions(-)

M frontend/readline.c
M frontend/readline.c => frontend/readline.c +42 -2
@@ 7,6 7,9 @@
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <libgen.h>
#include <sys/stat.h>
#include <sys/types.h>
#if defined(HAVE_READLINE)
#include <readline/history.h>
#include <readline/readline.h>


@@ 36,14 39,51 @@ static void sigint_handler(int n) {
}
#endif

static int mkdir_all(const char *path) {
	struct stat st = {0};
	if (stat(path, &st) == 0 && S_ISDIR(st.st_mode)) {
		return 0;
	}

	char *subpath = strdup(path);
	subpath = dirname(subpath);

	if (strcmp(subpath, ".") != 0 && strcmp(subpath, "/") != 0) {
		int ret = mkdir_all(subpath);
		if (ret != 0) {
			return ret;
		}
	}

	free(subpath);

	return mkdir(path, 0700);
}

static char *get_history_path(void) {
	int len = strlen("/history");
	const char *xdg_data_home = getenv("XDG_DATA_HOME");
	const char *home = getenv("HOME");
	int len = snprintf(NULL, 0, "%s/.mrsh_history", home);
	if (xdg_data_home) {
		len += snprintf(NULL, 0, "%s/mrsh", xdg_data_home);
	} else {
		len += snprintf(NULL, 0, "%s/.local/share/mrsh", home);
	}

	char *path = malloc(len + 1);
	if (path == NULL) {
		return NULL;
	}
	snprintf(path, len + 1, "%s/.mrsh_history", home);

	if (xdg_data_home) {
		len += snprintf(path, len, "%s/mrsh", xdg_data_home);
	} else {
		len += snprintf(path, len, "%s/.local/share/mrsh", home);
	}

	mkdir_all(path);

	strncat(path, "/history", len - strlen(path) - 1);
	return path;
}