/** * @file config.cpp * @author Lewis Price (lewis.e.price@outlook.com) * @brief Implementation for environment utilities and cross-platform config loader * @version 1.0.0 * @date 2026-06-09 * * @copyright Copyright (c) 2026 * */ #include "config.hpp" #include #include #include #include /** * @brief Helper utility to set environment variables across operating systems */ static int set_env_variable(const std::string& key, const std::string& value) { #if defined(_WIN32) return _putenv_s(key.c_str(), value.c_str()); #else return setenv(key.c_str(), value.c_str(), 1); #endif } bool check_for_config() { const std::string config_path = "lumberjack.config"; // Returns true only if lumberjack.config exists on disk and is a file (not a directory) return std::filesystem::exists(config_path) && std::filesystem::is_regular_file(config_path); } void make_config() { const std::string config_path = "lumberjack.config"; if (std::filesystem::exists(config_path)) { return; } std::ofstream file(config_path); if (!file.is_open()) { std::cerr << "Error: Could not generate a default " << config_path << " configuration template file." << std::endl; return; } // Write out the clean template configuration block file << "# ParseLogCLI Global Environment Configuration\n"; file << "# Generated on 2026-06-09\n\n"; file << "# Path to the MaxMind GeoLite2 City Database binary\n"; file << "DB_PATH=./data/GeoLite2-City.mmdb\n\n"; file << "# Absolute or relative path to the server access logs target file\n"; file << "LOG_PATH=./access.log.txt\n"; file.close(); } void load_config_file(const std::string& config_path) { std::ifstream file(config_path); if (!file.is_open()) { std::cerr << "Warning: Could not open " << config_path << " file." << std::endl; return; } std::string line; while (std::getline(file, line)) { // Skip completely empty lines or comment configurations if (line.empty() || line[0] == '#') continue; std::size_t delimiter_pos = line.find('='); if (delimiter_pos != std::string::npos) { std::string key = line.substr(0, delimiter_pos); std::string value = line.substr(delimiter_pos + 1); // Clean up hidden trailing Windows carriage returns (\r) safely if (!value.empty() && value.back() == '\r') { value.pop_back(); } // Expose the key-value pair globally to the active process lifecycle set_env_variable(key, value); } } }