114 lines
2.5 KiB
C++
114 lines
2.5 KiB
C++
|
/* Re-implemented in C++ after GLib's gutils.c */
|
||
|
|
||
|
#include "standardpaths.hpp"
|
||
|
|
||
|
namespace fs = std::filesystem;
|
||
|
|
||
|
#ifdef _WIN32
|
||
|
fs::path getWindowsDirectory(void) {
|
||
|
wchar_t wcp[MAX_PATH];
|
||
|
fs::path windowsDir("");
|
||
|
|
||
|
if (GetWindowsDirectoryW(wcp, MAX_PATH)) {
|
||
|
// Usually X:\Windows, but in terminal server environments
|
||
|
// might be an UNC path, AFAIK.
|
||
|
windowsDir = widetoutf8(wcp);
|
||
|
}
|
||
|
|
||
|
if (windowsDir.empty())
|
||
|
windowsDir = "C:\\";
|
||
|
|
||
|
return windowsDir;
|
||
|
}
|
||
|
|
||
|
|
||
|
fs::path getWindowsKnownFolder(REFKNOWNFOLDERID folder_guid) {
|
||
|
wchar_t *wcp = NULL;
|
||
|
fs::path specialFolder("");
|
||
|
HRESULT hr;
|
||
|
|
||
|
hr = SHGetKnownFolderPath(folder_guid, 0, NULL, &wcp);
|
||
|
|
||
|
if (SUCCEEDED (hr)) {
|
||
|
specialFolder = widetoutf8(wcp); // XXX: convert to UTF-8
|
||
|
}
|
||
|
|
||
|
CoTaskMemFree(wcp);
|
||
|
|
||
|
return specialFolder;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
fs::path getHomeDir() {
|
||
|
const char *path_p;
|
||
|
fs::path homeDir("");
|
||
|
|
||
|
/* We first check HOME and use it if it is set */
|
||
|
if (path_p = std::getenv("HOME")) {
|
||
|
homeDir = path_p;
|
||
|
}
|
||
|
|
||
|
#ifdef _WIN32
|
||
|
/* Only believe HOME if it is an absolute path and exists.
|
||
|
*
|
||
|
* We only do this check on Windows fnot on UNIX because
|
||
|
* of things like autofs. If the user has a bogus value in
|
||
|
* $HOME they're repsonsible
|
||
|
*/
|
||
|
if (!homeDir.empty() && !(homeDir.is_absolute() && fs::is_directory(homeDir))) {
|
||
|
homeDir.clear();
|
||
|
}
|
||
|
|
||
|
if (homeDir.empty()) {
|
||
|
/* USERPROFILE is probably the closest equivalent to $HOME? */
|
||
|
if (path_p = std::getenv("USERPROFILE"))
|
||
|
homeDir = path_p;
|
||
|
}
|
||
|
|
||
|
if (homeDir.empty()) {
|
||
|
homeDir = getWindowsKnownFolder(FOLDERID_Profile);
|
||
|
}
|
||
|
|
||
|
if (homeDir.empty()) {
|
||
|
homeDir = getWindowsDirectory();
|
||
|
}
|
||
|
#endif /* _WIN32 */
|
||
|
|
||
|
#ifndef _WIN32
|
||
|
if (homeDir.empty()) {
|
||
|
/* If we didn't get it from any of those methods, we will have
|
||
|
* to read the user database entry.
|
||
|
*/
|
||
|
homeDir = getpwuid(getuid())->pw_dir;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/* If we have been denied access to /etc/passwd (for example, by an
|
||
|
* overly-zealous LSM), make up a junk value. */
|
||
|
if (homeDir.empty()) {
|
||
|
homeDir = "/";
|
||
|
}
|
||
|
|
||
|
return homeDir;
|
||
|
}
|
||
|
|
||
|
|
||
|
fs::path getUserConfigDir() {
|
||
|
const char *path_p;
|
||
|
fs::path configDir("");
|
||
|
|
||
|
if (path_p = std::getenv("XDG_CONFIG_HOME"))
|
||
|
configDir = path_p;
|
||
|
|
||
|
#ifdef _WIN32
|
||
|
else
|
||
|
configDir = getWindowsKnownFolder(FOLDERID_LocalAppData);
|
||
|
#endif
|
||
|
if (configDir.empty()) {
|
||
|
configDir = getHomeDir() / ".config", NULL;
|
||
|
}
|
||
|
|
||
|
return configDir;
|
||
|
}
|
||
|
|