forked from lix-project/lix
util.{hh,cc}: Split out users.{hh,cc}
Change-Id: I1bd92479a2cb7e5c2c2e1541b80474adb05ea0df
This commit is contained in:
parent
b910551120
commit
f79ee66646
|
@ -31,6 +31,7 @@
|
||||||
#include "print.hh"
|
#include "print.hh"
|
||||||
#include "progress-bar.hh"
|
#include "progress-bar.hh"
|
||||||
#include "gc-small-vector.hh"
|
#include "gc-small-vector.hh"
|
||||||
|
#include "users.hh"
|
||||||
|
|
||||||
#if HAVE_BOEHMGC
|
#if HAVE_BOEHMGC
|
||||||
#define GC_INCLUDE_NEW
|
#define GC_INCLUDE_NEW
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#include "eval-cache.hh"
|
#include "eval-cache.hh"
|
||||||
#include "sqlite.hh"
|
#include "sqlite.hh"
|
||||||
#include "eval.hh"
|
#include "eval.hh"
|
||||||
#include "eval-inline.hh"
|
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
|
#include "users.hh"
|
||||||
|
|
||||||
namespace nix::eval_cache {
|
namespace nix::eval_cache {
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
|
#include "file-system.hh"
|
||||||
#include "globals.hh"
|
#include "globals.hh"
|
||||||
#include "profiles.hh"
|
#include "profiles.hh"
|
||||||
#include "eval.hh"
|
#include "users.hh"
|
||||||
#include "eval-settings.hh"
|
#include "eval-settings.hh"
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include "flake.hh"
|
#include "flake.hh"
|
||||||
#include "globals.hh"
|
#include "users.hh"
|
||||||
#include "fetch-settings.hh"
|
#include "fetch-settings.hh"
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
||||||
#include "finally.hh"
|
#include "finally.hh"
|
||||||
#include "util.hh"
|
#include "users.hh"
|
||||||
|
|
||||||
#include "nixexpr.hh"
|
#include "nixexpr.hh"
|
||||||
#include "eval.hh"
|
#include "eval.hh"
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include "sqlite.hh"
|
#include "sqlite.hh"
|
||||||
#include "sync.hh"
|
#include "sync.hh"
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
|
#include "users.hh"
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
#include "url-parts.hh"
|
#include "url-parts.hh"
|
||||||
#include "pathlocks.hh"
|
#include "pathlocks.hh"
|
||||||
#include "util.hh"
|
#include "users.hh"
|
||||||
#include "git.hh"
|
#include "git.hh"
|
||||||
#include "logging.hh"
|
#include "logging.hh"
|
||||||
#include "finally.hh"
|
#include "finally.hh"
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "processes.hh"
|
#include "processes.hh"
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
#include "url-parts.hh"
|
#include "url-parts.hh"
|
||||||
|
#include "users.hh"
|
||||||
|
|
||||||
#include "fetch-settings.hh"
|
#include "fetch-settings.hh"
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include "registry.hh"
|
#include "registry.hh"
|
||||||
#include "fetchers.hh"
|
#include "fetchers.hh"
|
||||||
#include "util.hh"
|
#include "users.hh"
|
||||||
#include "globals.hh"
|
#include "globals.hh"
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
#include "local-fs-store.hh"
|
#include "local-fs-store.hh"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include "environment-variables.hh"
|
#include "environment-variables.hh"
|
||||||
#include "globals.hh"
|
#include "globals.hh"
|
||||||
#include "util.hh"
|
#include "users.hh"
|
||||||
#include "archive.hh"
|
#include "archive.hh"
|
||||||
#include "args.hh"
|
#include "args.hh"
|
||||||
#include "abstract-setting-to-json.hh"
|
#include "abstract-setting-to-json.hh"
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include "sync.hh"
|
#include "sync.hh"
|
||||||
#include "sqlite.hh"
|
#include "sqlite.hh"
|
||||||
#include "globals.hh"
|
#include "globals.hh"
|
||||||
|
#include "users.hh"
|
||||||
|
|
||||||
#include <sqlite3.h>
|
#include <sqlite3.h>
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include "profiles.hh"
|
#include "profiles.hh"
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
#include "local-fs-store.hh"
|
#include "local-fs-store.hh"
|
||||||
#include "util.hh"
|
#include "users.hh"
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
// FIXME this should not be here, see TODO below on
|
// FIXME this should not be here, see TODO below on
|
||||||
// `addMultipleToStore`.
|
// `addMultipleToStore`.
|
||||||
#include "worker-protocol.hh"
|
#include "worker-protocol.hh"
|
||||||
|
#include "users.hh"
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "serialise.hh"
|
#include "serialise.hh"
|
||||||
#include "signals.hh"
|
#include "signals.hh"
|
||||||
#include "types.hh"
|
#include "types.hh"
|
||||||
|
#include "users.hh"
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@ libutil_sources = files(
|
||||||
'unix-domain-socket.cc',
|
'unix-domain-socket.cc',
|
||||||
'url.cc',
|
'url.cc',
|
||||||
'url-name.cc',
|
'url-name.cc',
|
||||||
|
'users.cc',
|
||||||
'util.cc',
|
'util.cc',
|
||||||
'xml-writer.cc',
|
'xml-writer.cc',
|
||||||
)
|
)
|
||||||
|
@ -109,6 +110,7 @@ libutil_headers = files(
|
||||||
'url-parts.hh',
|
'url-parts.hh',
|
||||||
'url-name.hh',
|
'url-name.hh',
|
||||||
'url.hh',
|
'url.hh',
|
||||||
|
'users.hh',
|
||||||
'util.hh',
|
'util.hh',
|
||||||
'variant-wrapper.hh',
|
'variant-wrapper.hh',
|
||||||
'xml-writer.hh',
|
'xml-writer.hh',
|
||||||
|
|
105
src/libutil/users.cc
Normal file
105
src/libutil/users.cc
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
#include "environment-variables.hh"
|
||||||
|
#include "file-system.hh"
|
||||||
|
#include "logging.hh"
|
||||||
|
#include "strings.hh"
|
||||||
|
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
namespace nix {
|
||||||
|
|
||||||
|
std::string getUserName()
|
||||||
|
{
|
||||||
|
auto pw = getpwuid(geteuid());
|
||||||
|
std::string name = pw ? pw->pw_name : getEnv("USER").value_or("");
|
||||||
|
if (name.empty())
|
||||||
|
throw Error("cannot figure out user name");
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
Path getHomeOf(uid_t userId)
|
||||||
|
{
|
||||||
|
std::vector<char> buf(16384);
|
||||||
|
struct passwd pwbuf;
|
||||||
|
struct passwd * pw;
|
||||||
|
if (getpwuid_r(userId, &pwbuf, buf.data(), buf.size(), &pw) != 0
|
||||||
|
|| !pw || !pw->pw_dir || !pw->pw_dir[0])
|
||||||
|
throw Error("cannot determine user's home directory");
|
||||||
|
return pw->pw_dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
Path getHome()
|
||||||
|
{
|
||||||
|
static Path homeDir = []()
|
||||||
|
{
|
||||||
|
std::optional<std::string> unownedUserHomeDir = {};
|
||||||
|
auto homeDir = getEnv("HOME");
|
||||||
|
if (homeDir) {
|
||||||
|
// Only use $HOME if doesn't exist or is owned by the current user.
|
||||||
|
struct stat st;
|
||||||
|
int result = stat(homeDir->c_str(), &st);
|
||||||
|
if (result != 0) {
|
||||||
|
if (errno != ENOENT) {
|
||||||
|
warn("couldn't stat $HOME ('%s') for reason other than not existing ('%d'), falling back to the one defined in the 'passwd' file", *homeDir, errno);
|
||||||
|
homeDir.reset();
|
||||||
|
}
|
||||||
|
} else if (st.st_uid != geteuid()) {
|
||||||
|
unownedUserHomeDir.swap(homeDir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!homeDir) {
|
||||||
|
homeDir = getHomeOf(geteuid());
|
||||||
|
if (unownedUserHomeDir.has_value() && unownedUserHomeDir != homeDir) {
|
||||||
|
warn("$HOME ('%s') is not owned by you, falling back to the one defined in the 'passwd' file ('%s')", *unownedUserHomeDir, *homeDir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return *homeDir;
|
||||||
|
}();
|
||||||
|
return homeDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Path getCacheDir()
|
||||||
|
{
|
||||||
|
auto cacheDir = getEnv("XDG_CACHE_HOME");
|
||||||
|
return cacheDir ? *cacheDir : getHome() + "/.cache";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Path getConfigDir()
|
||||||
|
{
|
||||||
|
auto configDir = getEnv("XDG_CONFIG_HOME");
|
||||||
|
return configDir ? *configDir : getHome() + "/.config";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Path> getConfigDirs()
|
||||||
|
{
|
||||||
|
Path configHome = getConfigDir();
|
||||||
|
auto configDirs = getEnv("XDG_CONFIG_DIRS").value_or("/etc/xdg");
|
||||||
|
std::vector<Path> result = tokenizeString<std::vector<std::string>>(configDirs, ":");
|
||||||
|
result.insert(result.begin(), configHome);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Path getDataDir()
|
||||||
|
{
|
||||||
|
auto dataDir = getEnv("XDG_DATA_HOME");
|
||||||
|
return dataDir ? *dataDir : getHome() + "/.local/share";
|
||||||
|
}
|
||||||
|
|
||||||
|
Path getStateDir()
|
||||||
|
{
|
||||||
|
auto stateDir = getEnv("XDG_STATE_HOME");
|
||||||
|
return stateDir ? *stateDir : getHome() + "/.local/state";
|
||||||
|
}
|
||||||
|
|
||||||
|
Path createNixStateDir()
|
||||||
|
{
|
||||||
|
Path dir = getStateDir() + "/nix";
|
||||||
|
createDirs(dir);
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
61
src/libutil/users.hh
Normal file
61
src/libutil/users.hh
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
#pragma once
|
||||||
|
///@file
|
||||||
|
|
||||||
|
#include "types.hh"
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
namespace nix {
|
||||||
|
|
||||||
|
std::string getUserName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the given user's home directory from /etc/passwd.
|
||||||
|
*/
|
||||||
|
Path getHomeOf(uid_t userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return $HOME or the user's home directory from /etc/passwd.
|
||||||
|
*/
|
||||||
|
Path getHome();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return $XDG_CACHE_HOME or $HOME/.cache.
|
||||||
|
*/
|
||||||
|
Path getCacheDir();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return $XDG_CONFIG_HOME or $HOME/.config.
|
||||||
|
*/
|
||||||
|
Path getConfigDir();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the directories to search for user configuration files
|
||||||
|
*/
|
||||||
|
std::vector<Path> getConfigDirs();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return $XDG_DATA_HOME or $HOME/.local/share.
|
||||||
|
*/
|
||||||
|
Path getDataDir();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return $XDG_STATE_HOME or $HOME/.local/state.
|
||||||
|
*
|
||||||
|
* @note Not to be confused with settings.nixStateDir.
|
||||||
|
*/
|
||||||
|
Path getStateDir();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create $XDG_STATE_HOME/nix or $HOME/.local/state/nix, and return
|
||||||
|
* the path to it.
|
||||||
|
* @note Not to be confused with settings.nixStateDir.
|
||||||
|
*/
|
||||||
|
Path createNixStateDir();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform tilde expansion on a path.
|
||||||
|
*/
|
||||||
|
std::string expandTilde(std::string_view path);
|
||||||
|
|
||||||
|
}
|
|
@ -56,103 +56,6 @@
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
|
||||||
std::string getUserName()
|
|
||||||
{
|
|
||||||
auto pw = getpwuid(geteuid());
|
|
||||||
std::string name = pw ? pw->pw_name : getEnv("USER").value_or("");
|
|
||||||
if (name.empty())
|
|
||||||
throw Error("cannot figure out user name");
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
Path getHomeOf(uid_t userId)
|
|
||||||
{
|
|
||||||
std::vector<char> buf(16384);
|
|
||||||
struct passwd pwbuf;
|
|
||||||
struct passwd * pw;
|
|
||||||
if (getpwuid_r(userId, &pwbuf, buf.data(), buf.size(), &pw) != 0
|
|
||||||
|| !pw || !pw->pw_dir || !pw->pw_dir[0])
|
|
||||||
throw Error("cannot determine user's home directory");
|
|
||||||
return pw->pw_dir;
|
|
||||||
}
|
|
||||||
|
|
||||||
Path getHome()
|
|
||||||
{
|
|
||||||
static Path homeDir = []()
|
|
||||||
{
|
|
||||||
std::optional<std::string> unownedUserHomeDir = {};
|
|
||||||
auto homeDir = getEnv("HOME");
|
|
||||||
if (homeDir) {
|
|
||||||
// Only use $HOME if doesn't exist or is owned by the current user.
|
|
||||||
struct stat st;
|
|
||||||
int result = stat(homeDir->c_str(), &st);
|
|
||||||
if (result != 0) {
|
|
||||||
if (errno != ENOENT) {
|
|
||||||
warn("couldn't stat $HOME ('%s') for reason other than not existing ('%d'), falling back to the one defined in the 'passwd' file", *homeDir, errno);
|
|
||||||
homeDir.reset();
|
|
||||||
}
|
|
||||||
} else if (st.st_uid != geteuid()) {
|
|
||||||
unownedUserHomeDir.swap(homeDir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!homeDir) {
|
|
||||||
homeDir = getHomeOf(geteuid());
|
|
||||||
if (unownedUserHomeDir.has_value() && unownedUserHomeDir != homeDir) {
|
|
||||||
warn("$HOME ('%s') is not owned by you, falling back to the one defined in the 'passwd' file ('%s')", *unownedUserHomeDir, *homeDir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return *homeDir;
|
|
||||||
}();
|
|
||||||
return homeDir;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Path getCacheDir()
|
|
||||||
{
|
|
||||||
auto cacheDir = getEnv("XDG_CACHE_HOME");
|
|
||||||
return cacheDir ? *cacheDir : getHome() + "/.cache";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Path getConfigDir()
|
|
||||||
{
|
|
||||||
auto configDir = getEnv("XDG_CONFIG_HOME");
|
|
||||||
return configDir ? *configDir : getHome() + "/.config";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<Path> getConfigDirs()
|
|
||||||
{
|
|
||||||
Path configHome = getConfigDir();
|
|
||||||
auto configDirs = getEnv("XDG_CONFIG_DIRS").value_or("/etc/xdg");
|
|
||||||
std::vector<Path> result = tokenizeString<std::vector<std::string>>(configDirs, ":");
|
|
||||||
result.insert(result.begin(), configHome);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Path getDataDir()
|
|
||||||
{
|
|
||||||
auto dataDir = getEnv("XDG_DATA_HOME");
|
|
||||||
return dataDir ? *dataDir : getHome() + "/.local/share";
|
|
||||||
}
|
|
||||||
|
|
||||||
Path getStateDir()
|
|
||||||
{
|
|
||||||
auto stateDir = getEnv("XDG_STATE_HOME");
|
|
||||||
return stateDir ? *stateDir : getHome() + "/.local/state";
|
|
||||||
}
|
|
||||||
|
|
||||||
Path createNixStateDir()
|
|
||||||
{
|
|
||||||
Path dir = getStateDir() + "/nix";
|
|
||||||
createDirs(dir);
|
|
||||||
return dir;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -39,53 +39,6 @@ struct Source;
|
||||||
extern const std::string nativeSystem;
|
extern const std::string nativeSystem;
|
||||||
|
|
||||||
|
|
||||||
std::string getUserName();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the given user's home directory from /etc/passwd.
|
|
||||||
*/
|
|
||||||
Path getHomeOf(uid_t userId);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return $HOME or the user's home directory from /etc/passwd.
|
|
||||||
*/
|
|
||||||
Path getHome();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return $XDG_CACHE_HOME or $HOME/.cache.
|
|
||||||
*/
|
|
||||||
Path getCacheDir();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return $XDG_CONFIG_HOME or $HOME/.config.
|
|
||||||
*/
|
|
||||||
Path getConfigDir();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the directories to search for user configuration files
|
|
||||||
*/
|
|
||||||
std::vector<Path> getConfigDirs();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return $XDG_DATA_HOME or $HOME/.local/share.
|
|
||||||
*/
|
|
||||||
Path getDataDir();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return $XDG_STATE_HOME or $HOME/.local/state.
|
|
||||||
*
|
|
||||||
* @note Not to be confused with settings.nixStateDir.
|
|
||||||
*/
|
|
||||||
Path getStateDir();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create $XDG_STATE_HOME/nix or $HOME/.local/state/nix, and return
|
|
||||||
* the path to it.
|
|
||||||
* @note Not to be confused with settings.nixStateDir.
|
|
||||||
*/
|
|
||||||
Path createNixStateDir();
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the current mount namespace. Ignored if called more than
|
* Save the current mount namespace. Ignored if called more than
|
||||||
* once.
|
* once.
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#include "legacy.hh"
|
#include "legacy.hh"
|
||||||
#include "fetchers.hh"
|
#include "fetchers.hh"
|
||||||
#include "eval-settings.hh" // for defexpr
|
#include "eval-settings.hh" // for defexpr
|
||||||
#include "util.hh"
|
#include "users.hh"
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
#include "local-fs-store.hh"
|
#include "local-fs-store.hh"
|
||||||
#include "user-env.hh"
|
#include "user-env.hh"
|
||||||
#include "util.hh"
|
#include "users.hh"
|
||||||
#include "value-to-json.hh"
|
#include "value-to-json.hh"
|
||||||
#include "xml-writer.hh"
|
#include "xml-writer.hh"
|
||||||
#include "legacy.hh"
|
#include "legacy.hh"
|
||||||
|
|
Loading…
Reference in a new issue