aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2024-02-07 18:25:15 +0100
committerdec05eba <dec05eba@protonmail.com>2024-02-07 18:25:15 +0100
commit8c92489212dd661fb3b32cae5c71b53ed8b2e348 (patch)
tree2617d748649db1d5e562530371b6e50b584100a2
parent9f08039ecda088f950190b173e73fa77c8f3b3f9 (diff)
Properly read retarded xdg user dirs
-rw-r--r--src/config.hpp66
1 files changed, 59 insertions, 7 deletions
diff --git a/src/config.hpp b/src/config.hpp
index 9619278..097627a 100644
--- a/src/config.hpp
+++ b/src/config.hpp
@@ -4,6 +4,7 @@
#include <string>
#include <string.h>
#include <functional>
+#include <map>
#include <unistd.h>
#include <limits.h>
#include <inttypes.h>
@@ -89,15 +90,66 @@ static std::string get_config_dir() {
return config_dir;
}
-static std::string get_videos_dir() {
- std::string videos_dir;
- const char *xdg_videos_dir = getenv("XDG_VIDEOS_DIR");
- if(xdg_videos_dir) {
- videos_dir = xdg_videos_dir;
+// Whoever designed xdg-user-dirs is retarded. Why are some XDG variables environment variables
+// while others are in this pseudo shell config file ~/.config/user-dirs.dirs
+static std::map<std::string, std::string> get_xdg_variables() {
+ std::string user_dirs_filepath;
+ const char *xdg_config_home = getenv("XDG_CONFIG_HOME");
+ if(xdg_config_home) {
+ user_dirs_filepath = xdg_config_home;
} else {
- videos_dir = get_home_dir() + "/Videos";
+ user_dirs_filepath = get_home_dir() + "/.config";
}
- return videos_dir;
+
+ user_dirs_filepath += "/user-dirs.dirs";
+
+ std::map<std::string, std::string> result;
+ FILE *f = fopen(user_dirs_filepath.c_str(), "rb");
+ if(!f)
+ return result;
+
+ char line[PATH_MAX];
+ while(fgets(line, sizeof(line), f)) {
+ int len = strlen(line);
+ if(len < 2)
+ continue;
+
+ if(line[len - 1] == '\n') {
+ line[len - 1] = '\0';
+ len--;
+ }
+
+ if(line[len - 1] != '"')
+ continue;
+
+ line[len - 1] = '\0';
+ len--;
+
+ const char *sep = strchr(line, '=');
+ if(!sep)
+ continue;
+
+ if(sep[1] != '\"')
+ continue;
+
+ std::string value(sep + 2);
+ if(strncmp(value.c_str(), "$HOME/", 6) == 0)
+ value = get_home_dir() + value.substr(5);
+
+ std::string key(line, sep - line);
+ result[std::move(key)] = std::move(value);
+ }
+
+ fclose(f);
+ return result;
+}
+
+static std::string get_videos_dir() {
+ auto xdg_vars = get_xdg_variables();
+ std::string xdg_videos_dir = xdg_vars["XDG_VIDEOS_DIR"];
+ if(xdg_videos_dir.empty())
+ xdg_videos_dir = get_home_dir() + "/Videos";
+ return xdg_videos_dir;
}
static int create_directory_recursive(char *path) {