diff --git a/debian/changelog b/debian/changelog index 9a75e85..19d106b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -5,4 +5,4 @@ dropshell (1.0.0-1) unstable; urgency=medium * Added proper system status monitoring * Improved server management functionality - -- j842 Sun, 21 Apr 2025 12:00:00 +0000 \ No newline at end of file + -- j842 Sun, 21 Apr 2025 12:00:00 +0000 \ No newline at end of file diff --git a/debian/control b/debian/control index 6b8f572..861aa18 100644 --- a/debian/control +++ b/debian/control @@ -1,7 +1,7 @@ Source: dropshell Section: utils Priority: optional -Maintainer: j842 +Maintainer: j842 Build-Depends: debhelper (>= 10), cmake, libboost-all-dev Standards-Version: 4.5.0 Homepage: https://github.com/j842/dropshell diff --git a/src/config.cpp b/src/config.cpp index e73981a..1f3f96c 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -1,4 +1,5 @@ #include "dropshell.hpp" +#include "init_user_directory.hpp" #include #include #include @@ -11,7 +12,6 @@ namespace pt = boost::property_tree; namespace dropshell { // Default user directory -static std::string user_directory; static bool config_loaded = false; bool is_config_loaded() { @@ -36,11 +36,6 @@ bool get_config_path(std::string& path) { return false; } -bool get_user_directory(std::string& path) { - path = user_directory; - return !path.empty(); -} - bool load_config() { std::string config_path; if (!get_config_path(config_path)) @@ -54,14 +49,18 @@ bool load_config() { try { pt::ptree tree; pt::read_ini(config_path, tree); - bool config_okay = true; + bool config_okay = false; // Try to read user directory from config try { - user_directory = tree.get("user.directory"); + std::string user_dir; + user_dir = tree.get("user.directory"); + // Update user directory through the new interface + set_user_directory(user_dir); + config_okay = true; + } catch (const pt::ptree_error&) { std::cerr << "Warning: User directory not set in config" << std::endl; - config_okay = false; // Not a critical error } // config loaded okay. @@ -74,57 +73,4 @@ bool load_config() { } } -void init_user_directory(const std::string& path) { - // Convert to absolute path - fs::path abs_path = fs::absolute(path); - - // The directory must exist - if (!fs::exists(abs_path)) { - throw std::runtime_error("The user directory does not exist: " + abs_path.string()); - } - - // create the servers subdirectory if it doesn't exist - fs::path servers_dir = abs_path / "servers"; - if (!fs::exists(servers_dir)) { - fs::create_directories(servers_dir); - } - - // Update config file - std::string config_path; - if (!get_config_path(config_path)) { - // No config file exists, create one in user's home directory - const char* home = std::getenv("HOME"); - if (!home) { - throw std::runtime_error("HOME environment variable not set"); - } - - fs::path config_dir = fs::path(home) / ".config" / "dropshell"; - if (!fs::exists(config_dir)) { - fs::create_directories(config_dir); - } - config_path = (config_dir / "dropshell.conf").string(); - } - - try { - pt::ptree tree; - // Read existing config if it exists - if (fs::exists(config_path)) { - pt::read_ini(config_path, tree); - } - - // Update user directory - tree.put("user.directory", abs_path.string()); - - // Write back to config file - pt::write_ini(config_path, tree); - - // Update in-memory value - user_directory = abs_path.string(); - - std::cout << "User directory initialized to: " << abs_path.string() << std::endl; - } catch (const std::exception& e) { - throw std::runtime_error("Failed to update config: " + std::string(e.what())); - } -} - } // namespace dropshell \ No newline at end of file diff --git a/src/config.hpp b/src/config.hpp index b559f69..4a5b752 100644 --- a/src/config.hpp +++ b/src/config.hpp @@ -9,6 +9,5 @@ bool get_config_path(std::string& path); bool load_config(); bool is_config_loaded(); bool get_user_directory(std::string& path); -void init_user_directory(const std::string& path); } // namespace dropshell \ No newline at end of file diff --git a/src/init_user_directory.cpp b/src/init_user_directory.cpp new file mode 100644 index 0000000..63f6ef3 --- /dev/null +++ b/src/init_user_directory.cpp @@ -0,0 +1,76 @@ +#include "init_user_directory.hpp" +#include "config.hpp" +#include +#include +#include +#include +#include + +namespace fs = boost::filesystem; +namespace pt = boost::property_tree; + +namespace dropshell { + +static std::string user_directory; +bool get_user_directory(std::string& path) { + path = user_directory; + return !path.empty(); +} +void set_user_directory(const std::string& path) { + user_directory = path; +} + +void init_user_directory(const std::string& path) { + // Convert to canonical path + fs::path abs_path = fs::canonical(path); + + // The directory must exist + if (!fs::exists(abs_path)) { + throw std::runtime_error("The user directory does not exist: " + abs_path.string()); + } + + // create the servers subdirectory if it doesn't exist + fs::path servers_dir = abs_path / "servers"; + if (!fs::exists(servers_dir)) { + fs::create_directories(servers_dir); + } + + // Update config file + std::string config_path; + if (!get_config_path(config_path)) { + // No config file exists, create one in user's home directory + const char* home = std::getenv("HOME"); + if (!home) { + throw std::runtime_error("HOME environment variable not set"); + } + + fs::path config_dir = fs::path(home) / ".config" / "dropshell"; + if (!fs::exists(config_dir)) { + fs::create_directories(config_dir); + } + config_path = (config_dir / "dropshell.conf").string(); + } + + try { + pt::ptree tree; + // Read existing config if it exists + if (fs::exists(config_path)) { + pt::read_ini(config_path, tree); + } + + // Update user directory + tree.put("user.directory", abs_path.string()); + + // Write back to config file + pt::write_ini(config_path, tree); + + // Update in-memory value + user_directory = abs_path.string(); + + std::cout << "User directory initialized to: " << abs_path.string() << std::endl; + } catch (const std::exception& e) { + throw std::runtime_error("Failed to update config: " + std::string(e.what())); + } +} + +} // namespace dropshell \ No newline at end of file diff --git a/src/init_user_directory.hpp b/src/init_user_directory.hpp new file mode 100644 index 0000000..2eed7fb --- /dev/null +++ b/src/init_user_directory.hpp @@ -0,0 +1,11 @@ +#pragma once + +#include + +namespace dropshell { + +// User directory initialization function +void init_user_directory(const std::string& path); +bool get_user_directory(std::string& path); +void set_user_directory(const std::string& path); +} // namespace dropshell \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 977c5df..643a4bb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,4 +1,7 @@ #include "dropshell.hpp" +#include "init_user_directory.hpp" +#include "config.hpp" + #include #include #include diff --git a/src/server_env.cpp b/src/server_env.cpp index f16de4b..ebea347 100644 --- a/src/server_env.cpp +++ b/src/server_env.cpp @@ -3,9 +3,33 @@ #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; } @@ -20,24 +44,52 @@ server_env::server_env(const std::string& path) : mValid(false) { } try { - // Read the INI file - boost::property_tree::ptree pt; - boost::property_tree::ini_parser::read_ini(env_path.string(), pt); - - // Store all variables - for (const auto& section : pt) { - for (const auto& key_value : section.second) { - variables[key_value.first] = key_value.second.get_value(); + // 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 - if (variables.find("SSH_HOST") == variables.end() || - variables.find("SSH_USER") == variables.end() || - variables.find("SSH_PORT") == variables.end()) { - throw std::runtime_error("Missing required variables in server environment file"); + for (const auto& var : {"SSH_HOST", "SSH_USER", "SSH_PORT"}) { + 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) { diff --git a/src/server_service.hpp b/src/server_service.hpp new file mode 100644 index 0000000..c16a51d --- /dev/null +++ b/src/server_service.hpp @@ -0,0 +1,18 @@ +#include +#include + +namespace dropshell { + +std::vector get_server_services(const std::string& server_name); + +class server_service { + public: + server_service(); + bool init(const std::string& server_name, const std::string& service_name); + bool install(); + bool is_installed(); + + bool run_command(const std::string& command); +}; + +} // namespace dropshell diff --git a/src/servers.cpp b/src/servers.cpp index fddaaa5..4bd0588 100644 --- a/src/servers.cpp +++ b/src/servers.cpp @@ -30,7 +30,7 @@ std::vector get_configured_servers() { for (const auto& entry : fs::directory_iterator(servers_dir)) { if (fs::is_directory(entry)) { - fs::path env_file = entry.path() / "_server.env"; + fs::path env_file = entry.path(); server_env env(env_file.string()); if (!env.is_valid()) { std::cerr << "Error: Invalid server environment file: " << env_file.string() << std::endl;