standardpaths/standardpaths.cpp

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;
}