This commit is contained in:
Your Name 2025-05-04 19:56:52 +12:00
parent 27e5cce367
commit 008cf59c48
7 changed files with 98 additions and 20 deletions

View File

@ -43,7 +43,7 @@ bool config::load_config() { // load json config file.
return true; return true;
} }
bool config::save_config() bool config::save_config(bool create_aux_directories)
{ {
std::string config_path = localfile::dropshell_json(); std::string config_path = localfile::dropshell_json();
if (config_path.empty()) if (config_path.empty())
@ -77,14 +77,26 @@ bool config::save_config()
config_file << mConfig.dump(4); config_file << mConfig.dump(4);
config_file.close(); config_file.close();
return true;
std::filesystem::create_directories(get_local_template_cache_path()); if (create_aux_directories) {
std::filesystem::create_directories(get_local_backup_path()); std::vector<std::filesystem::path> paths = {
std::filesystem::create_directories(get_local_tempfiles_path()); get_local_template_cache_path(),
get_local_backup_path(),
get_local_tempfiles_path()
};
for (auto & p : get_local_server_definition_paths()) for (auto & p : get_local_server_definition_paths())
paths.push_back(p);
for (auto & p : paths)
if (!std::filesystem::exists(p))
{
std::cout << "Creating directory: " << p << std::endl;
std::filesystem::create_directories(p); std::filesystem::create_directories(p);
} }
}
return true;
}
bool config::is_config_set() const bool config::is_config_set() const

View File

@ -12,7 +12,7 @@ class config {
~config(); ~config();
bool load_config(); bool load_config();
bool save_config(); bool save_config(bool create_aux_directories);
bool is_config_set() const; bool is_config_set() const;

View File

@ -134,6 +134,9 @@ int main(int argc, char* argv[]) {
} }
if (cmd == "edit" && argc < 3) { if (cmd == "edit" && argc < 3) {
if (!gConfig().is_config_set())
gConfig().save_config(false);
std::string config_file = localfile::dropshell_json(); std::string config_file = localfile::dropshell_json();
if (!edit_file(config_file) || !std::filesystem::exists(config_file)) if (!edit_file(config_file) || !std::filesystem::exists(config_file))
return die("Error: Failed to edit config file."); return die("Error: Failed to edit config file.");
@ -142,9 +145,8 @@ int main(int argc, char* argv[]) {
if (!gConfig().is_config_set()) if (!gConfig().is_config_set())
return die("Error: Failed to load and parse edited config file."); return die("Error: Failed to load and parse edited config file.");
gConfig().save_config(); gConfig().save_config(true);
gConfig().load_config(); std::cout << "Successfully edited config file at " << config_file << std::endl;
std::cout << "Successfully edited config file." << std::endl;
return 0; return 0;
} }

View File

@ -11,6 +11,12 @@
#include <memory> #include <memory>
#include <filesystem> #include <filesystem>
#include <fstream> #include <fstream>
#include <sys/wait.h>
#include <unistd.h>
#include <vector>
#include <string>
#include <iostream>
#include <wordexp.h> // For potential shell-like expansion if needed
namespace dropshell { namespace dropshell {
@ -24,7 +30,7 @@ server_env_manager::server_env_manager(const std::string& server_name) : mValid(
// Check if file exists // Check if file exists
if (!std::filesystem::exists(server_env_path)) { if (!std::filesystem::exists(server_env_path)) {
std::cerr << "Server environment file not found: " + server_env_path << std::endl; std::cerr << "Server environment file not found: " + server_env_path << " for server " << server_name << std::endl;
return; return;
} }
@ -179,6 +185,43 @@ bool server_env_manager::execute_local_command(const sCommand& command) {
return false; return false;
} }
bool server_env_manager::execute_local_command_interactive(const sCommand &command)
{
std::string full_command = command.construct_rawcmd(); // Get the command string
pid_t pid = fork();
if (pid == -1) {
// Fork failed
perror("fork failed");
return false;
} else if (pid == 0) {
// Child process
std::vector<const char *> commandvec = {"bash", "-c", full_command.c_str(),NULL};
std::cout << "Executing command: ";
for (auto & x : commandvec) std::cout << x << " ";
std::cout << std::endl;
execvp(commandvec[0], const_cast<char* const*>(commandvec.data()));
// If execvp returns, it means an error occurred
perror("execvp failed");
exit(EXIT_FAILURE); // Exit child process on error
} else {
// Parent process
int status;
// Wait for the child process to complete
waitpid(pid, &status, 0);
if (WIFEXITED(status)) {
return (WEXITSTATUS(status) == 0);
}
return false; // Child terminated abnormally
}
}
bool server_env_manager::execute_local_command_and_capture_output(const sCommand& command, std::string &output) bool server_env_manager::execute_local_command_and_capture_output(const sCommand& command, std::string &output)
{ {
std::string full_cmd = command.construct_safecmd() + " 2>&1"; std::string full_cmd = command.construct_safecmd() + " 2>&1";
@ -219,7 +262,9 @@ std::string sCommand::construct_safecmd() const
std::string sCommand::construct_rawcmd() const std::string sCommand::construct_rawcmd() const
{ {
std::string rawcmd = "cd " + quote(mDir) + " && "; std::string rawcmd;
if (!mDir.empty())
rawcmd = "cd " + quote(mDir) + " && ";
for (const auto& env_var : mVars) { for (const auto& env_var : mVars) {
rawcmd += env_var.first + "=" + quote(dequote(trim(env_var.second))) + " "; rawcmd += env_var.first + "=" + quote(dequote(trim(env_var.second))) + " ";

View File

@ -79,6 +79,7 @@ class server_env_manager {
bool execute_ssh_command_and_capture_output(const sCommand& command, std::string & output, bool allocateTTY=false) const; bool execute_ssh_command_and_capture_output(const sCommand& command, std::string & output, bool allocateTTY=false) const;
static bool execute_local_command(const sCommand& command); static bool execute_local_command(const sCommand& command);
static bool execute_local_command_interactive(const sCommand& command);
static bool execute_local_command_and_capture_output(const sCommand& command, std::string & output); static bool execute_local_command_and_capture_output(const sCommand& command, std::string & output);
private: private:

View File

@ -423,8 +423,11 @@ void edit_server(const std::string &server_name)
<< "Once moved, reinstall all services with: dropshell install " << server_name; << "Once moved, reinstall all services with: dropshell install " << server_name;
std::string config_file = serverpath + "/server.env"; std::string config_file = serverpath + "/server.env";
if (!edit_file(config_file)) if (!edit_file(config_file)) {
std::cerr << "Error: Failed to edit server.env" << std::endl; std::cerr << "Error: Failed to edit server.env" << std::endl;
std::cerr << "You can manually edit this file at: " << config_file << std::endl;
std::cerr << "After editing, " << aftertext.str() << std::endl;
}
else else
std::cout << aftertext.str() << std::endl; std::cout << aftertext.str() << std::endl;
} }
@ -435,8 +438,23 @@ bool edit_file(const std::string &file_path)
std::string parent_dir = get_parent(file_path); std::string parent_dir = get_parent(file_path);
std::filesystem::create_directories(parent_dir); std::filesystem::create_directories(parent_dir);
std::string cmd = "nano -w " + file_path; std::string editor_cmd;
return server_env_manager::execute_local_command(cmd); const char* editor_env = std::getenv("EDITOR");
if (editor_env && std::strlen(editor_env) > 0) {
editor_cmd = std::string(editor_env) + " " + quote(file_path);
} else if (isatty(STDIN_FILENO)) {
// Check if stdin is connected to a terminal if EDITOR is not set
editor_cmd = "nano -w " + quote(file_path);
} else {
std::cerr << "Error: Standard input is not a terminal and EDITOR environment variable is not set." << std::endl;
std::cerr << "Try setting the EDITOR environment variable (e.g., export EDITOR=nano) or run in an interactive terminal." << std::endl;
std::cerr << "You can manually edit the file at: " << file_path << std::endl;
return false;
}
std::cout << "Editing file: " << file_path << std::endl;
return server_env_manager::execute_local_command_interactive(editor_cmd);
} }
void service_runner::interactive_ssh_service() void service_runner::interactive_ssh_service()

View File

@ -46,9 +46,9 @@ namespace localfile {
namespace localpath { namespace localpath {
std::string server(const std::string &server_name) { std::string server(const std::string &server_name) {
if (server_name.empty()) return ""; if (server_name.empty()) return "";
for (auto &dir : gConfig().get_local_server_definition_paths()) for (std::filesystem::path dir : gConfig().get_local_server_definition_paths())
if (fs::exists(dir + server_name)) if (fs::exists(dir / server_name))
return dir + server_name; return dir / server_name;
return ""; return "";
} }