+#endif
+
+void migrateCachePath()
+{
+ const std::string local_cache_path = path_user + DIR_DELIM + "cache";
+
+ // Delete tmp folder if it exists (it only ever contained
+ // a temporary ogg file, which is no longer used).
+ if (fs::PathExists(local_cache_path + DIR_DELIM + "tmp"))
+ fs::RecursiveDelete(local_cache_path + DIR_DELIM + "tmp");
+
+ // Bail if migration impossible
+ if (path_cache == local_cache_path || !fs::PathExists(local_cache_path)
+ || fs::PathExists(path_cache)) {
+ return;
+ }
+ if (!fs::Rename(local_cache_path, path_cache)) {
+ errorstream << "Failed to migrate local cache path "
+ "to system path!" << std::endl;
+ }
+}
+
+void initializePaths()
+{
+#if RUN_IN_PLACE
+ char buf[BUFSIZ];
+
+ infostream << "Using relative paths (RUN_IN_PLACE)" << std::endl;
+
+ bool success =
+ getCurrentExecPath(buf, sizeof(buf)) ||
+ getExecPathFromProcfs(buf, sizeof(buf));
+
+ if (success) {
+ pathRemoveFile(buf, DIR_DELIM_CHAR);
+ std::string execpath(buf);
+
+ path_share = execpath + DIR_DELIM "..";
+ path_user = execpath + DIR_DELIM "..";
+
+ if (detectMSVCBuildDir(execpath)) {
+ path_share += DIR_DELIM "..";
+ path_user += DIR_DELIM "..";
+ }
+ } else {
+ errorstream << "Failed to get paths by executable location, "
+ "trying cwd" << std::endl;
+
+ if (!getCurrentWorkingDir(buf, sizeof(buf)))
+ FATAL_ERROR("Ran out of methods to get paths");
+
+ size_t cwdlen = strlen(buf);
+ if (cwdlen >= 1 && buf[cwdlen - 1] == DIR_DELIM_CHAR) {
+ cwdlen--;
+ buf[cwdlen] = '\0';
+ }
+
+ if (cwdlen >= 4 && !strcmp(buf + cwdlen - 4, DIR_DELIM "bin"))
+ pathRemoveFile(buf, DIR_DELIM_CHAR);
+
+ std::string execpath(buf);
+
+ path_share = execpath;
+ path_user = execpath;
+ }
+ path_cache = path_user + DIR_DELIM + "cache";
+#else
+ infostream << "Using system-wide paths (NOT RUN_IN_PLACE)" << std::endl;
+
+ if (!setSystemPaths())
+ errorstream << "Failed to get one or more system-wide path" << std::endl;
+
+ // Initialize path_cache
+ // First try $XDG_CACHE_HOME/PROJECT_NAME
+ const char *cache_dir = getenv("XDG_CACHE_HOME");
+ const char *home_dir = getenv("HOME");
+ if (cache_dir) {
+ path_cache = std::string(cache_dir) + DIR_DELIM + PROJECT_NAME;
+ } else if (home_dir) {
+ // Then try $HOME/.cache/PROJECT_NAME
+ path_cache = std::string(home_dir) + DIR_DELIM + ".cache"
+ + DIR_DELIM + PROJECT_NAME;
+ } else {
+ // If neither works, use $PATH_USER/cache
+ path_cache = path_user + DIR_DELIM + "cache";
+ }
+ // Migrate cache folder to new location if possible
+ migrateCachePath();
+#endif
+
+ infostream << "Detected share path: " << path_share << std::endl;
+ infostream << "Detected user path: " << path_user << std::endl;
+ infostream << "Detected cache path: " << path_cache << std::endl;
+
+#if USE_GETTEXT
+ bool found_localedir = false;
+# ifdef STATIC_LOCALEDIR
+ if (STATIC_LOCALEDIR[0] && fs::PathExists(STATIC_LOCALEDIR)) {
+ found_localedir = true;
+ path_locale = STATIC_LOCALEDIR;
+ infostream << "Using locale directory " << STATIC_LOCALEDIR << std::endl;
+ } else {
+ path_locale = getDataPath("locale");
+ if (fs::PathExists(path_locale)) {
+ found_localedir = true;
+ infostream << "Using in-place locale directory " << path_locale
+ << " even though a static one was provided "
+ << "(RUN_IN_PLACE or CUSTOM_LOCALEDIR)." << std::endl;
+ }
+ }
+# else
+ path_locale = getDataPath("locale");
+ if (fs::PathExists(path_locale)) {
+ found_localedir = true;
+ }
+# endif
+ if (!found_localedir) {
+ warningstream << "Couldn't find a locale directory!" << std::endl;
+ }
+#endif // USE_GETTEXT