Supermodel/Src/OSD/Unix/FileSystemPath.cpp

166 lines
5.3 KiB
C++
Raw Normal View History

/**
** 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 <http://www.gnu.org/licenses/>.
**/
#include "FileSystemPath.h"
#include "Util/Format.h"
#include <string>
#include <sys/stat.h>
#include <sys/types.h>
#include <pwd.h>
#include <unistd.h>
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;
}
}