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;
}
bool config::save_config()
bool config::save_config(bool create_aux_directories)
{
std::string config_path = localfile::dropshell_json();
if (config_path.empty())
@ -77,13 +77,25 @@ bool config::save_config()
config_file << mConfig.dump(4);
config_file.close();
return true;
std::filesystem::create_directories(get_local_template_cache_path());
std::filesystem::create_directories(get_local_backup_path());
std::filesystem::create_directories(get_local_tempfiles_path());
for (auto & p : get_local_server_definition_paths())
std::filesystem::create_directories(p);
if (create_aux_directories) {
std::vector<std::filesystem::path> paths = {
get_local_template_cache_path(),
get_local_backup_path(),
get_local_tempfiles_path()
};
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);
}
}
return true;
}

View File

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

View File

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

View File

@ -11,6 +11,12 @@
#include <memory>
#include <filesystem>
#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 {
@ -24,7 +30,7 @@ server_env_manager::server_env_manager(const std::string& server_name) : mValid(
// Check if file exists
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;
}
@ -179,6 +185,43 @@ bool server_env_manager::execute_local_command(const sCommand& command) {
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)
{
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 rawcmd = "cd " + quote(mDir) + " && ";
std::string rawcmd;
if (!mDir.empty())
rawcmd = "cd " + quote(mDir) + " && ";
for (const auto& env_var : mVars) {
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;
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);
private:

View File

@ -423,10 +423,13 @@ void edit_server(const std::string &server_name)
<< "Once moved, reinstall all services with: dropshell install " << server_name;
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 << "You can manually edit this file at: " << config_file << std::endl;
std::cerr << "After editing, " << aftertext.str() << std::endl;
}
else
std::cout << aftertext.str() << std::endl;
std::cout << aftertext.str() << std::endl;
}
bool edit_file(const std::string &file_path)
@ -435,8 +438,23 @@ bool edit_file(const std::string &file_path)
std::string parent_dir = get_parent(file_path);
std::filesystem::create_directories(parent_dir);
std::string cmd = "nano -w " + file_path;
return server_env_manager::execute_local_command(cmd);
std::string editor_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()

View File

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