/** ** Supermodel ** A Sega Model 3 Arcade Emulator. ** Copyright 2003-2022 The Supermodel Team ** ** This file is part of Supermodel. ** ** Supermodel is free software: you can redistribute it and/or modify it under ** the terms of the GNU General Public License as published by the Free ** Software Foundation, either version 3 of the License, or (at your option) ** any later version. ** ** Supermodel is distributed in the hope that it will be useful, but WITHOUT ** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for ** more details. ** ** You should have received a copy of the GNU General Public License along ** with Supermodel. If not, see . **/ #include "FileSystemPath.h" #include "Util/Format.h" #include #include #include #include #include namespace FileSystemPath { // Checks if a directory exists (returns true if exists, false if it doesn't) bool PathExists(std::string fileSystemPath) { bool pathExists = false; struct stat pathInfo; if (stat(fileSystemPath.c_str(), &pathInfo) == 0 && S_ISDIR(pathInfo.st_mode)) { pathExists = true; } return pathExists; } // Generates a path to be used by Supermodel files std::string GetPath(PathType pathType) { std::string finalPath = ""; std::string homePath = ""; std::string strPathType = ""; struct passwd* pwd = getpwuid(getuid()); // Resolve pathType to string for later use switch (pathType) { case Analysis: strPathType = "Analysis"; break; case Config: strPathType = "Config"; break; case Log: strPathType = "Log"; break; case NVRAM: strPathType = "NVRAM"; break; case Saves: strPathType = "Saves"; break; case Screenshots: strPathType = "Screenshots"; break; case Assets: strPathType = "Assets/"; break; } // Get user's HOME directory if (pwd) { homePath = pwd->pw_dir; } else { homePath = getenv("HOME"); } // If Config path exists in current directory or the user doesn't have a HOME directory use current directory if (FileSystemPath::PathExists("Config") || homePath.empty()) { // Use current directory if (pathType == Screenshots || pathType == Log) { finalPath = ""; } else { // If directory doesn't exist, create it if (!FileSystemPath::PathExists(strPathType)) { mkdir(strPathType.c_str(), 0775); } finalPath = strPathType; } } // Check if $HOME/.supermodel exists else if (FileSystemPath::PathExists(Util::Format() << homePath << "/.supermodel")) { // Use $HOME/.supermodel finalPath = Util::Format() << homePath << "/.supermodel/" << strPathType; // If directory doesn't exist, create it if (!FileSystemPath::PathExists(finalPath)) { mkdir(finalPath.c_str(), 0775); } } // On Linux one may want to follow the XDG base directory specs (https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html) else { // Use $HOME/.config/supermodel or $HOME/.local/share/supermodel depending on the file type if (pathType == Config) { finalPath = Util::Format() << homePath << "/.config/supermodel"; // If directory doesn't exist, create it if (!FileSystemPath::PathExists(finalPath)) { mkdir(finalPath.c_str(), 0775); } // If directory doesn't exist, create it finalPath = Util::Format() << homePath << "/.config/supermodel/Config"; if (!FileSystemPath::PathExists(finalPath)) { mkdir(finalPath.c_str(), 0775); } } else { finalPath = Util::Format() << homePath << "/.local/share/supermodel"; // If directory doesn't exist, create it if (!FileSystemPath::PathExists(finalPath)) { mkdir(finalPath.c_str(), 0775); } // If directory doesn't exist, create it finalPath = Util::Format() << homePath << "/.local/share/supermodel/" << strPathType; if (!FileSystemPath::PathExists(finalPath)) { mkdir(finalPath.c_str(), 0775); } } } if (finalPath != "") { finalPath = Util::Format() << finalPath << "/"; } return finalPath; } }