Tighten up XDG base directory path handling

Don't search base directories if path starts with "/", "./" or
"../", but still do if the path simply starts with ".". Bail early
if HOME is needed but unset. Don't attempt to open the original
path in configOpen and dataOpen.
master
C. McEnroe 2021-01-26 15:39:13 -05:00
parent 1a2a1e59dd
commit e89e6dda99
1 changed files with 12 additions and 25 deletions

37
xdg.c
View File

@ -71,7 +71,7 @@ basePath(struct Base base, const char **dirs, const char *path) {
return buf;
}
if (path[0] == '/' || path[0] == '.') {
if (path[strspn(path, ".")] == '/') {
*dirs = "";
return path;
}
@ -89,7 +89,7 @@ basePath(struct Base base, const char **dirs, const char *path) {
home, base.defHome, path
);
} else {
return NULL;
errx(EX_CONFIG, "HOME unset");
}
return buf;
}
@ -98,8 +98,7 @@ const char *configPath(const char **dirs, const char *path) {
return basePath(Config, dirs, path);
}
const char *
dataPath(const char **dirs, const char *path) {
const char *dataPath(const char **dirs, const char *path) {
return basePath(Data, dirs, path);
}
@ -110,17 +109,16 @@ FILE *configOpen(const char *path, const char *mode) {
if (file) return file;
if (errno != ENOENT) warn("%s", abs);
}
FILE *file = fopen(path, mode);
if (!file) warn("%s", path);
return file;
dirs = NULL;
warn("%s", configPath(&dirs, path));
return NULL;
}
void dataMkdir(const char *path) {
const char *dirs = NULL;
const char *abs = dataPath(&dirs, path);
if (!abs) return;
int error = mkdir(abs, S_IRWXU);
if (error && errno != EEXIST) warn("%s", abs);
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) {
@ -130,20 +128,9 @@ FILE *dataOpen(const char *path, const char *mode) {
if (file) return file;
if (errno != ENOENT) warn("%s", abs);
}
if (mode[0] != 'r') {
dataMkdir("");
dirs = NULL;
path = dataPath(&dirs, path);
if (!path) {
warn("HOME unset");
return NULL;
}
FILE *file = fopen(path, mode);
if (!file) warn("%s", path);
return file;
}
if (mode[0] != 'r') dataMkdir("");
dirs = NULL;
path = dataPath(&dirs, path);
FILE *file = fopen(path, mode);
if (!file) warn("%s", path);
return file;