From 9a9528d09375e6017088af354799ac381b939c1f Mon Sep 17 00:00:00 2001 From: dranull <150595692+dranull@users.noreply.github.com> Date: Mon, 4 Dec 2023 01:35:24 +0000 Subject: [PATCH] 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 --- src/config/ConfigManager.cpp | 40 ++++++++++++++++++++---------------- src/main.cpp | 9 +++++--- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 5659667e..41248d08 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -48,12 +48,11 @@ CConfigManager::CConfigManager() { std::string CConfigManager::getConfigDir() { static const char* xdgConfigHome = getenv("XDG_CONFIG_HOME"); - std::string configPath; - if (!xdgConfigHome) - configPath = getenv("HOME") + std::string("/.config"); - else - configPath = xdgConfigHome; - return configPath; + + if (xdgConfigHome && std::filesystem::path(xdgConfigHome).is_absolute()) + return xdgConfigHome; + + return getenv("HOME") + std::string("/.config"); } 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++) { 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"); parseError = "source file " + value + " doesn't exist!"; return; @@ -1570,20 +1574,20 @@ void CConfigManager::loadConfigLoadVars() { std::string mainConfigPath = getMainConfigPath(); Debug::log(LOG, "Using config: {}", 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)) { - Debug::log(WARN, "Creating config home directory"); - try { - std::filesystem::create_directories(configPath); - } catch (...) { - parseError = "Broken config file! (Could not create config directory)"; - return; + if (g_pCompositor->explicitConfigPath.empty() && !std::filesystem::exists(mainConfigPath)) { + std::string configPath = std::filesystem::path(mainConfigPath).parent_path(); + + if (!std::filesystem::is_directory(configPath)) { + Debug::log(WARN, "Creating config home directory"); + try { + 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."); std::ofstream ofs; ofs.open(mainConfigPath, std::ios::trunc); diff --git a/src/main.cpp b/src/main.cpp index 27a768ba..0f68c3b2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -54,14 +54,17 @@ int main(int argc, char** argv) { } std::string next_arg = std::next(it)->c_str(); - if (!std::filesystem::exists(next_arg)) { - std::cerr << "[ ERROR ] Config path '" << next_arg << "' doesn't exist!\n"; + if (std::filesystem::is_symlink(next_arg)) + 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(); return 1; } - configPath = next_arg; + configPath = std::filesystem::weakly_canonical(next_arg); Debug::log(LOG, "User-specified config location: '{}'", configPath); it++;