/*** Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: Resources.cpp Date: 2021-6-16 Author: Reece ***/ #include #include "FS.hpp" #include "Resources.hpp" #if defined(AURORA_PLATFORM_LINUX) #include #include #include #elif defined(AURORA_PLATFORM_WIN32) #include #endif namespace Aurora::IO::FS { static AuString gHomeDirectory; static AuString gApplicationData; static AuOptional gSystemLibPath; static AuOptional gSystemLibPath2; static AuOptional gUserLibPath; static AuOptional gUserLibPath2; AUKN_SYM bool GetSystemDomain(AuString &path) { path = gApplicationData; return true; } AUKN_SYM bool GetProfileDomain(AuString &path) { path = gHomeDirectory; return true; } AUKN_SYM bool GetSystemResourcePath(const AuString &fileName, AuString &path) { path.clear(); if (fileName.find("..") != AuString::npos) { LogWarn("Exploit Attempt? A system resource path may not contain relative directory move tokens: {}", fileName); return false; } { AuString tempPath; if (Process::GetWorkingDirectory(tempPath)) { tempPath += "/" + fileName; if (FileExists(tempPath)) { path = tempPath; return true; } } } { AuString tempPath; if (Process::GetProcPath(tempPath)) { tempPath += "/" + fileName; if (FileExists(tempPath)) { path = tempPath; return true; } } } { auto systemPath = gHomeDirectory + fileName; if (FileExists(systemPath)) { path = systemPath; return true; } } { auto systemPath = gApplicationData + fileName; if (FileExists(systemPath)) { path = systemPath; return true; } } return false; } #if defined(AURORA_PLATFORM_WIN32) static AuString GetSpecialDir(REFKNOWNFOLDERID rfid) { PWSTR directory; if (SHGetKnownFolderPath(rfid, KF_FLAG_DEFAULT, NULL, &directory) != S_OK) { SysPanic("Couldn't get known special directory path of [MS:{}-{}-{}-{}{}{}{}{}{}{}{}] with a NULL access token", rfid.Data1, rfid.Data2, rfid.Data3, rfid.Data4[0], rfid.Data4[1], rfid.Data4[2], rfid.Data4[3], rfid.Data4[4], rfid.Data4[5], rfid.Data4[6], rfid.Data4[7]); } return Locale::ConvertFromWChar(directory); } static void SetNamespaceDirectories() { gHomeDirectory = GetSpecialDir(FOLDERID_RoamingAppData); gApplicationData = GetSpecialDir(FOLDERID_ProgramData); gSystemLibPath = GetSpecialDir(FOLDERID_System); } #elif defined(AURORA_PLATFORM_LINUX) || defined(AURORA_PLATFORM_BSD) static void SetUnixPaths(AuOptional &primary, AuOptional &secondary, const AuString &base) { primary = base; if (Aurora::Build::IsPlatformX32()) { secondary = base + "32"; } else { secondary = base + "64"; } if (DirExists(*secondary)) { std::swap(secondary, primary); } else { secondary.reset(); } if (!DirExists(*primary)) { primary.reset(); } } static void SetNamespaceDirectories() { const char *homedir; homedir = getenv("HOME"); if (!homedir) { homedir = getpwuid(getuid())->pw_dir; } gHomeDirectory = homedir ? homedir : ""; if (gHomeDirectory.empty()) { gHomeDirectory = "."; } gApplicationData = gHomeDirectory; SetUnixPaths(gUserLibPath, gUserLibPath2, "/usr/lib"); SetUnixPaths(gSystemLibPath, gSystemLibPath2, "/lib"); } #else static void SetNamespaceDirectories() { gHomeDirectory = "."; gApplicationData = "."; } #endif AuOptional GetSystemLibPath() { return gSystemLibPath; } AuOptional GetUserLibPath() { return gUserLibPath; } AuOptional GetSystemLibPath2() { return gSystemLibPath2; } AuOptional GetUserLibPath2() { return gUserLibPath2; } static void ChangeDir() { #if !defined(AU_NO_AU_HOME_BRANDING) if (gRuntimeConfig.fio.defaultBrand.has_value()) { gApplicationData += "/" + gRuntimeConfig.fio.defaultBrand.value() + "/System"; gHomeDirectory += "/" + gRuntimeConfig.fio.defaultBrand.value() + "/Profile"; } else #endif { gApplicationData += "/.application"; gHomeDirectory += "/.config"; //most unix programs hide their private user data under here } NormalizePath(gApplicationData); NormalizePath(gHomeDirectory); // Noting we append a path splitter to prevent hair pulling over missing path delimiters // Eg: GetHome() + "myAwesomeApp/Config" = %HOME%/Aurora/ProfilemyAwsomeApp/Config gApplicationData += kPathSplitter; gHomeDirectory += kPathSplitter; } void InitResources() { SetNamespaceDirectories(); ChangeDir(); } }