config: Minor --config improvements, fixes (#4034)

* Follow symlink, only file, absolute path for -c

* Create config file only for default paths

* Skip non-file source= glob results

* Check for absolute path on XDG_CONFIG_HOME

As per spec, all non-absolute paths should be ignored.
https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
This commit is contained in:
dranull 2023-12-04 01:35:24 +00:00 committed by GitHub
parent e496b0f250
commit 9a9528d093
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 28 additions and 21 deletions

View file

@ -48,12 +48,11 @@ CConfigManager::CConfigManager() {
std::string CConfigManager::getConfigDir() { std::string CConfigManager::getConfigDir() {
static const char* xdgConfigHome = getenv("XDG_CONFIG_HOME"); static const char* xdgConfigHome = getenv("XDG_CONFIG_HOME");
std::string configPath;
if (!xdgConfigHome) if (xdgConfigHome && std::filesystem::path(xdgConfigHome).is_absolute())
configPath = getenv("HOME") + std::string("/.config"); return xdgConfigHome;
else
configPath = xdgConfigHome; return getenv("HOME") + std::string("/.config");
return configPath;
} }
std::string CConfigManager::getMainConfigPath() { std::string CConfigManager::getMainConfigPath() {
@ -1263,7 +1262,12 @@ void CConfigManager::handleSource(const std::string& command, const std::string&
for (size_t i = 0; i < glob_buf->gl_pathc; i++) { for (size_t i = 0; i < glob_buf->gl_pathc; i++) {
auto value = absolutePath(glob_buf->gl_pathv[i], configCurrentPath); auto value = absolutePath(glob_buf->gl_pathv[i], configCurrentPath);
if (!std::filesystem::exists(value)) { if (!std::filesystem::is_regular_file(value)) {
if (std::filesystem::exists(value)) {
Debug::log(WARN, "source= skipping non-file {}", value);
continue;
}
Debug::log(ERR, "source= file doesnt exist"); Debug::log(ERR, "source= file doesnt exist");
parseError = "source file " + value + " doesn't exist!"; parseError = "source file " + value + " doesn't exist!";
return; return;
@ -1570,20 +1574,20 @@ void CConfigManager::loadConfigLoadVars() {
std::string mainConfigPath = getMainConfigPath(); std::string mainConfigPath = getMainConfigPath();
Debug::log(LOG, "Using config: {}", mainConfigPath); Debug::log(LOG, "Using config: {}", mainConfigPath);
configPaths.push_back(mainConfigPath); configPaths.push_back(mainConfigPath);
std::string configPath = mainConfigPath.substr(0, mainConfigPath.find_last_of('/'));
// find_last_of never returns npos since main_config at least has /hypr/
if (!std::filesystem::is_directory(configPath)) { if (g_pCompositor->explicitConfigPath.empty() && !std::filesystem::exists(mainConfigPath)) {
Debug::log(WARN, "Creating config home directory"); std::string configPath = std::filesystem::path(mainConfigPath).parent_path();
try {
std::filesystem::create_directories(configPath); if (!std::filesystem::is_directory(configPath)) {
} catch (...) { Debug::log(WARN, "Creating config home directory");
parseError = "Broken config file! (Could not create config directory)"; try {
return; std::filesystem::create_directories(configPath);
} catch (...) {
parseError = "Broken config file! (Could not create config directory)";
return;
}
} }
}
if (!std::filesystem::exists(mainConfigPath)) {
Debug::log(WARN, "No config file found; attempting to generate."); Debug::log(WARN, "No config file found; attempting to generate.");
std::ofstream ofs; std::ofstream ofs;
ofs.open(mainConfigPath, std::ios::trunc); ofs.open(mainConfigPath, std::ios::trunc);

View file

@ -54,14 +54,17 @@ int main(int argc, char** argv) {
} }
std::string next_arg = std::next(it)->c_str(); std::string next_arg = std::next(it)->c_str();
if (!std::filesystem::exists(next_arg)) { if (std::filesystem::is_symlink(next_arg))
std::cerr << "[ ERROR ] Config path '" << next_arg << "' doesn't exist!\n"; next_arg = std::filesystem::read_symlink(next_arg);
if (!std::filesystem::is_regular_file(next_arg)) {
std::cerr << "[ ERROR ] Config file '" << next_arg << "' doesn't exist!\n";
help(); help();
return 1; return 1;
} }
configPath = next_arg; configPath = std::filesystem::weakly_canonical(next_arg);
Debug::log(LOG, "User-specified config location: '{}'", configPath); Debug::log(LOG, "User-specified config location: '{}'", configPath);
it++; it++;