summaryrefslogtreecommitdiff
path: root/src/fileio.cpp
diff options
context:
space:
mode:
authorCharles Pigott <charlespigott@googlemail.com>2020-12-06 18:49:28 +0000
committerCharles Pigott <charlespigott@googlemail.com>2021-01-02 19:46:08 +0000
commit3dfee979a7e486b8d90f6398ea557d2889855059 (patch)
treece9eed1f60a868f30b80d08e2033d7615042f9b4 /src/fileio.cpp
parentc288eba81389d07e27b32f28c6dc4dc518824d2b (diff)
downloadopenttd-3dfee979a7e486b8d90f6398ea557d2889855059.tar.xz
Codechange: Drop libxdg-basedir dependency in favour of finding the directories ourselves
Diffstat (limited to 'src/fileio.cpp')
-rw-r--r--src/fileio.cpp102
1 files changed, 58 insertions, 44 deletions
diff --git a/src/fileio.cpp b/src/fileio.cpp
index cba18873a..44f2cf5c7 100644
--- a/src/fileio.cpp
+++ b/src/fileio.cpp
@@ -28,10 +28,6 @@
#include <array>
#include <sstream>
-#ifdef WITH_XDG_BASEDIR
-#include <basedir.h>
-#endif
-
#include "safeguards.h"
/** Size of the #Fio data buffer. */
@@ -978,54 +974,65 @@ bool DoScanWorkingDirectory()
}
/**
+ * Gets the home directory of the user.
+ * May return an empty string in the unlikely scenario that the home directory cannot be found.
+ * @return User's home directory
+ */
+static std::string GetHomeDir()
+{
+#ifdef __HAIKU__
+ BPath path;
+ find_directory(B_USER_SETTINGS_DIRECTORY, &path);
+ return std::string(path.Path());
+#else
+ const char *home_env = getenv("HOME"); // Stack var, shouldn't be freed
+ if (home_env != nullptr) return std::string(home_env);
+
+ const struct passwd *pw = getpwuid(getuid());
+ if (pw != nullptr) return std::string(pw->pw_dir);
+#endif
+ return {};
+}
+
+/**
* Determine the base (personal dir and game data dir) paths
* @param exe the path to the executable
*/
void DetermineBasePaths(const char *exe)
{
std::string tmp;
-#if defined(WITH_XDG_BASEDIR) && defined(WITH_PERSONAL_DIR)
- const char *xdg_data_home = xdgDataHome(nullptr);
- tmp = xdg_data_home;
- tmp += PATHSEP;
- tmp += PERSONAL_DIR[0] == '.' ? &PERSONAL_DIR[1] : PERSONAL_DIR;
- free(xdg_data_home);
+ const std::string homedir = GetHomeDir();
+#ifdef USE_XDG
+ const char *xdg_data_home = getenv("XDG_DATA_HOME");
+ if (xdg_data_home != nullptr) {
+ tmp = xdg_data_home;
+ tmp += PATHSEP;
+ tmp += PERSONAL_DIR[0] == '.' ? &PERSONAL_DIR[1] : PERSONAL_DIR;
+ AppendPathSeparator(tmp);
- AppendPathSeparator(tmp);
- _searchpaths[SP_PERSONAL_DIR_XDG] = tmp;
-#endif
-#if defined(OS2) || !defined(WITH_PERSONAL_DIR)
- _searchpaths[SP_PERSONAL_DIR].clear();
-#else
-#ifdef __HAIKU__
- BPath path;
- find_directory(B_USER_SETTINGS_DIRECTORY, &path);
- const char *homedir = stredup(path.Path());
-#else
- /* getenv is highly unsafe; duplicate it as soon as possible,
- * or at least before something else touches the environment
- * variables in any way. It can also contain all kinds of
- * unvalidated data we rather not want internally. */
- const char *homedir = getenv("HOME");
- if (homedir != nullptr) {
- homedir = stredup(homedir);
- }
+ _searchpaths[SP_PERSONAL_DIR_XDG] = tmp;
+ } else if (!homedir.empty()) {
+ tmp = homedir;
+ tmp += PATHSEP ".local" PATHSEP "share" PATHSEP;
+ tmp += PERSONAL_DIR[0] == '.' ? &PERSONAL_DIR[1] : PERSONAL_DIR;
+ AppendPathSeparator(tmp);
- if (homedir == nullptr) {
- const struct passwd *pw = getpwuid(getuid());
- homedir = (pw == nullptr) ? nullptr : stredup(pw->pw_dir);
+ _searchpaths[SP_PERSONAL_DIR_XDG] = tmp;
+ } else {
+ _searchpaths[SP_PERSONAL_DIR_XDG].clear();
}
#endif
- if (homedir != nullptr) {
- ValidateString(homedir);
+#if defined(OS2) || !defined(WITH_PERSONAL_DIR)
+ _searchpaths[SP_PERSONAL_DIR].clear();
+#else
+ if (!homedir.empty()) {
tmp = homedir;
tmp += PATHSEP;
tmp += PERSONAL_DIR;
AppendPathSeparator(tmp);
_searchpaths[SP_PERSONAL_DIR] = tmp;
- free(homedir);
} else {
_searchpaths[SP_PERSONAL_DIR].clear();
}
@@ -1111,13 +1118,20 @@ void DeterminePaths(const char *exe)
{
DetermineBasePaths(exe);
-#if defined(WITH_XDG_BASEDIR) && defined(WITH_PERSONAL_DIR)
- const char *xdg_config_home = xdgConfigHome(nullptr);
- std::string config_home(xdg_config_home);
- config_home += PATHSEP;
- config_home += PERSONAL_DIR[0] == '.' ? &PERSONAL_DIR[1] : PERSONAL_DIR;
- free(xdg_config_home);
-
+#ifdef USE_XDG
+ std::string config_home;
+ const std::string homedir = GetHomeDir();
+ const char *xdg_config_home = getenv("XDG_CONFIG_HOME");
+ if (xdg_config_home != nullptr) {
+ config_home = xdg_config_home;
+ config_home += PATHSEP;
+ config_home += PERSONAL_DIR[0] == '.' ? &PERSONAL_DIR[1] : PERSONAL_DIR;
+ } else if (!homedir.empty()) {
+ /* Defaults to ~/.config */
+ config_home = homedir;
+ config_home += PATHSEP ".config" PATHSEP;
+ config_home += PERSONAL_DIR[0] == '.' ? &PERSONAL_DIR[1] : PERSONAL_DIR;
+ }
AppendPathSeparator(config_home);
#endif
@@ -1137,7 +1151,7 @@ void DeterminePaths(const char *exe)
if (end != std::string::npos) personal_dir.erase(end + 1);
config_dir = personal_dir;
} else {
-#if defined(WITH_XDG_BASEDIR) && defined(WITH_PERSONAL_DIR)
+#ifdef USE_XDG
/* No previous configuration file found. Use the configuration folder from XDG. */
config_dir = config_home;
#else
@@ -1165,7 +1179,7 @@ void DeterminePaths(const char *exe)
extern std::string _windows_file;
_windows_file = config_dir + "windows.cfg";
-#if defined(WITH_XDG_BASEDIR) && defined(WITH_PERSONAL_DIR)
+#ifdef USE_XDG
if (config_dir == config_home) {
/* We are using the XDG configuration home for the config file,
* then store the rest in the XDG data home folder. */