/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2018 Debauchee Open Source Group
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package 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 this program. If not, see .
*/
#include "../DataDirectories.h"
#include // sysconf
#include // getenv
#include // getpwuid(_r)
#include // getpwuid(_r)
namespace barrier {
static std::string pw_dir(struct passwd* pwentp)
{
if (pwentp != NULL && pwentp->pw_dir != NULL)
return pwentp->pw_dir;
return "";
}
#ifdef HAVE_GETPWUID_R
static fs::path unix_home()
{
long size = -1;
#if defined(_SC_GETPW_R_SIZE_MAX)
size = sysconf(_SC_GETPW_R_SIZE_MAX);
#endif
if (size == -1)
size = BUFSIZ;
struct passwd pwent;
struct passwd* pwentp;
std::string buffer(size, 0);
getpwuid_r(getuid(), &pwent, &buffer[0], size, &pwentp);
return fs::u8path(pw_dir(pwentp));
}
#else // not HAVE_GETPWUID_R
static fs::path unix_home()
{
return fs::u8path(pw_dir(getpwuid(getuid())));
}
#endif // HAVE_GETPWUID_R
static fs::path profile_basedir()
{
#ifdef WINAPI_XWINDOWS
// linux/bsd adheres to freedesktop standards
// https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
const char* dir = std::getenv("XDG_DATA_HOME");
if (dir != NULL)
return fs::u8path(dir);
return unix_home() / ".local/share";
#else
// macos has its own standards
// https://developer.apple.com/library/content/documentation/General/Conceptual/MOSXAppProgrammingGuide/AppRuntime/AppRuntime.html
return unix_home() / "Library/Application Support";
#endif
}
const fs::path& DataDirectories::profile()
{
if (_profile.empty())
_profile = profile_basedir() / "barrier";
return _profile;
}
const fs::path& DataDirectories::profile(const fs::path& path)
{
_profile = path;
return _profile;
}
const fs::path& DataDirectories::global()
{
if (_global.empty())
// TODO: where on a unix system should public/global shared data go?
// as of march 2018 global() is not used for unix
_global = "/tmp";
return _global;
}
const fs::path& DataDirectories::global(const fs::path& path)
{
_global = path;
return _global;
}
const fs::path& DataDirectories::systemconfig()
{
if (_systemconfig.empty())
_systemconfig = "/etc";
return _systemconfig;
}
const fs::path& DataDirectories::systemconfig(const fs::path& path)
{
_systemconfig = path;
return _systemconfig;
}
} // namespace barrier