dropshell/src/server_env.cpp
2025-04-21 12:40:23 +12:00

137 lines
4.3 KiB
C++

#include "server_env.hpp"
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>
#include <boost/filesystem.hpp>
#include <cstdlib>
#include <iostream>
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