#include "server_env.hpp" #include #include #include #include #include namespace dropshell { // Helper function to trim whitespace from both ends of a string static std::string trim(const std::string& str) { const std::string whitespace = " \t"; const auto strBegin = str.find_first_not_of(whitespace); if (strBegin == std::string::npos) { return ""; // empty string } const auto strEnd = str.find_last_not_of(whitespace); const auto strRange = strEnd - strBegin + 1; return str.substr(strBegin, strRange); } // Helper function to print the contents of a file to screen static void print_file(const std::string& path) { std::cout << "Contents of " << path << ":" << std::endl; std::ifstream file(path); std::string line; while (std::getline(file, line)) { std::cout << " " << line << std::endl; } } bool server_env::is_valid() { return mValid; } server_env::server_env(const std::string& path) : mValid(false) { // Construct the full path to _server.env boost::filesystem::path env_path = boost::filesystem::path(path) / "_server.env"; // Check if file exists if (!boost::filesystem::exists(env_path)) { throw std::runtime_error("Server environment file not found: " + env_path.string()); } try { // Read the environment file std::ifstream file(env_path.string()); std::string line; while (std::getline(file, line)) { // Skip empty lines and comments if (line.empty() || line[0] == '#') { continue; } // Find the position of the equals sign size_t pos = line.find('='); if (pos != std::string::npos) { std::string key = line.substr(0, pos); std::string value = line.substr(pos + 1); // Trim whitespace using the helper function key = trim(key); value = trim(value); // Handle ${USER} replacement size_t user_pos; while ((user_pos = value.find("${USER}")) != std::string::npos) { const char* user = std::getenv("USER"); if (user) { value.replace(user_pos, 7, user); } } variables[key] = value; } } // Verify required variables exist for (const auto& var : {"SSH_HOST", "SSH_USER", "SSH_PORT", "DROPSHELL_DIR"}) { if (variables.find(var) == variables.end()) { // print the contents of the _server.env file to screen: print_file(env_path.string()); // print variables identified in the file: std::cout << "Variables identified in the file:" << std::endl; for (const auto& var : variables) { std::cout << " " << var.first << std::endl; } throw std::runtime_error("Missing required variable: " + std::string(var)); } } mValid = true; } catch (const boost::property_tree::ini_parser_error& e) { throw std::runtime_error("Failed to parse server environment file: " + std::string(e.what())); } } std::string server_env::get_variable(const std::string& name) { auto it = variables.find(name); if (it == variables.end()) { return ""; } std::string value = it->second; // Replace ${USER} with actual username const char* username = std::getenv("USER"); if (username) { std::string user_var = "${USER}"; size_t pos = value.find(user_var); if (pos != std::string::npos) { value.replace(pos, user_var.length(), username); } } return value; } std::string server_env::get_SSH_HOST() { return get_variable("SSH_HOST"); } std::string server_env::get_SSH_USER() { return get_variable("SSH_USER"); } std::string server_env::get_SSH_PORT() { return get_variable("SSH_PORT"); } std::string server_env::get_DROPSHELL_DIR() { return get_variable("DROPSHELL_DIR"); } } // namespace dropshell