diff --git a/src/main.cpp b/src/main.cpp index b19e33b..f503001 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -108,7 +108,6 @@ void printversion() { int main(int argc, char* argv[]) { HAPPYEXIT("hash", hash_demo_raw(safearg(argc,argv,2))) - HAPPYEXIT("makesafecmd", std::cout< &file_paths) const @@ -150,7 +150,7 @@ bool server_env_manager::check_remote_items_exist(const std::vector } // check if all items in the vector exist on the remote server, in a single command. - return 0==runner::execute_cmd("bash",{"-c","for item in " + file_paths_str + "; do test -f $item; done"}, {}, {}, true, false, &get_SSH_INFO()); + return 0==runner::execute_cmd("bash",{"-c","for item in " + file_paths_str + "; do test -f $item; done"}, {}, {}, true, false, get_SSH_INFO()); } bool server_env_manager::run_remote_template_command(const std::string &service_name, const std::string &command, std::vector args, bool silent, std::map extra_env_vars, std::string * output) const @@ -177,7 +177,7 @@ bool server_env_manager::run_remote_template_command(const std::string &service_ ASSERT(!output || !silent); // if output is captured, silent must be false ASSERT(!interactive || !silent); // if command is ssh, silent must be false - return 0==runner::execute_cmd("bash",{"-c", quote(script_path) + argstr}, working_dir, env_vars, silent, interactive, &get_SSH_INFO(), output); + return 0==runner::execute_cmd("bash",{"-c", quote(script_path) + argstr}, working_dir, env_vars, silent, interactive, get_SSH_INFO(), output); } // base64 <<< "FOO=BAR WHEE=YAY bash ./test.sh" diff --git a/src/server_env_manager.hpp b/src/server_env_manager.hpp index 0c339fa..ca85bad 100644 --- a/src/server_env_manager.hpp +++ b/src/server_env_manager.hpp @@ -9,7 +9,7 @@ #include #include #include - +#include "utils/runner.hpp" namespace dropshell { class server_env_manager; diff --git a/src/service_runner.cpp b/src/service_runner.cpp index 197e649..d5e6a62 100644 --- a/src/service_runner.cpp +++ b/src/service_runner.cpp @@ -53,14 +53,14 @@ bool service_runner::install(bool silent) { return false; // Create service directory - if (0!=runner::execute_cmd("mkdir -p " + remotepath::service(mServer, mService),{},"",{},true,false,&mServerEnv.get_SSH_INFO())) + if (0!=runner::execute_cmd("mkdir -p " + remotepath::service(mServer, mService),{},"",{},true,false,mServerEnv.get_SSH_INFO())) { std::cerr << "Failed to create service directory " << remotepath::service(mServer, mService) << std::endl; return false; } // Check if rsync is installed on remote host - if (0!=runner::execute_cmd("which rsync",{},"",{},true,false,&mServerEnv.get_SSH_INFO())) + if (0!=runner::execute_cmd("which rsync",{},"",{},true,false,mServerEnv.get_SSH_INFO())) { std::cerr << "rsync is not installed on the remote host" << std::endl; return false; @@ -122,7 +122,7 @@ bool service_runner::uninstall(bool silent) { } // 4. Remove the service directory from the server - if (0!=runner::execute_cmd("rm -rf " + quote(remotepath::service(mServer, mService)), {}, "", {}, true, false, &mServerEnv.get_SSH_INFO())) + if (0!=runner::execute_cmd("rm -rf " + quote(remotepath::service(mServer, mService)), {}, "", {}, true, false, mServerEnv.get_SSH_INFO())) std::cerr << "Failed to remove remote service directory at " << remotepath::service(mServer, mService) << std::endl; std::cout << "Service " << mService << " successfully uninstalled from " << mServer << std::endl; @@ -167,7 +167,7 @@ bool service_runner::fullnuke() return false; } - if (0!=runner::execute_cmd("rm -rf " + quote(local_service_path), {}, "", {}, true, false, &mServerEnv.get_SSH_INFO())) + if (0!=runner::execute_cmd("rm -rf " + quote(local_service_path), {}, "", {}, true, false, mServerEnv.get_SSH_INFO())) std::cerr << "Failed to remove local service directory at " << local_service_path << std::endl; std::cout << "Service " << mService << " successfully fully nuked from " << mServer << std::endl; @@ -274,7 +274,7 @@ std::map service_runner::get_all_services_status(std std::string cmd_path = remotepath::service_template(server_name,service_name) + "/shared/"; std::string output; - if (0!=runner::execute_cmd("bash",{cmd_path+command+".sh"}, cmd_path, {}, true, false, &env.get_SSH_INFO(), &output)) + if (0!=runner::execute_cmd("bash",{cmd_path+command+".sh"}, cmd_path, {}, true, false, env.get_SSH_INFO(), &output)) { std::cerr << "Error: Failed to run command script at " << cmd_path << std::endl; return status; @@ -382,13 +382,12 @@ bool service_runner::interactive_ssh(const std::string & server_name, const std: return false; } - sCommand scommand("bash"); server_env_manager env(server_name); if (!env.is_valid()) { std::cerr << "Error: Invalid server environment file: " << server_name << std::endl; return false; } - return execute_ssh_command(env.get_SSH_INFO(), scommand, cMode::Interactive | cMode::RawCommand); + return 0==runner::execute_cmd("bash",{}, "", {}, false, true, env.get_SSH_INFO()); } void service_runner::edit_server(const std::string &server_name) @@ -424,10 +423,10 @@ bool service_runner::edit_file(const std::string &file_path) const char* editor_env = std::getenv("EDITOR"); if (editor_env && std::strlen(editor_env) > 0) { - editor_cmd = std::string(editor_env) + " " + quote(file_path); + editor_cmd = std::string(editor_env); } 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); + editor_cmd = "nano"; } 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; @@ -436,7 +435,7 @@ bool service_runner::edit_file(const std::string &file_path) } std::cout << "Editing file: " << file_path << std::endl; - return execute_local_command(editor_cmd, cMode::Interactive | cMode::RawCommand); + return 0==runner::execute_cmd(editor_cmd, {quote(file_path)}, "", {}, false, true, nullptr); } bool service_runner::interactive_ssh_service() @@ -542,8 +541,8 @@ bool service_runner::restore(std::string backup_file, bool silent) std::string remote_backup_file_path = remote_backups_dir + "/" + backup_file; // Copy backup file from local to server - std::string scp_cmd = "scp -P " + mServerEnv.get_SSH_PORT() + " " + quote(local_backup_file_path) + " " + mServerEnv.get_SSH_USER() + "@" + mServerEnv.get_SSH_HOST() + ":" + quote(remote_backup_file_path) + (silent ? " > /dev/null 2>&1" : ""); - if (!execute_local_command(scp_cmd, silent ? cMode::Silent : cMode::None)) { + if (0!=runner::execute_cmd("scp", {quote(local_backup_file_path), mServerEnv.get_SSH_USER() + "@" + mServerEnv.get_SSH_HOST() + ":" + quote(remote_backup_file_path)}, "", {}, false, false, mServerEnv.get_SSH_INFO())) + { std::cerr << "Failed to copy backup file from server" << std::endl; return false; } @@ -619,9 +618,9 @@ bool service_runner::backup(bool silent) { // Create backups directory on server if it doesn't exist std::string remote_backups_dir = remotepath::backups(mServer); - if (!silent) std::cout << "Remote backups directory on "<< mServer <<": " << remote_backups_dir << std::endl; - std::string mkdir_cmd = "mkdir -p " + quote(remote_backups_dir); - if (!execute_ssh_command(mServerEnv.get_SSH_INFO(), sCommand(mkdir_cmd), cMode::Silent)) { + if (!silent) std::cout << "Remote backups directory on "<< mServer <<": " << remote_backups_dir << std::endl; + if (0!=runner::execute_cmd("mkdir", {"-p",quote(remote_backups_dir)}, "", {}, true, false, mServerEnv.get_SSH_INFO())) + { std::cerr << "Failed to create backups directory on server" << std::endl; return false; } @@ -662,10 +661,8 @@ bool service_runner::backup(bool silent) { } // Copy backup file from server to local - std::string scp_cmd = "scp -P " + mServerEnv.get_SSH_PORT() + " " + - mServerEnv.get_SSH_USER() + "@" + mServerEnv.get_SSH_HOST() + ":" + - quote(remote_backup_file_path) + " " + quote(local_backup_file_path) + (silent ? " > /dev/null 2>&1" : ""); - if (!execute_local_command(scp_cmd, silent ? cMode::Silent : cMode::None)) { + if (0!=runner::execute_cmd("scp", {quote(remote_backup_file_path), quote(local_backup_file_path)}, "", {}, silent, false, mServerEnv.get_SSH_INFO())) + { std::cerr << "Failed to copy backup file from server" << std::endl; return false; } @@ -681,8 +678,7 @@ bool service_runner::backup(bool silent) { cRemoteTempFolder::cRemoteTempFolder(const server_env_manager &server_env) : mServerEnv(server_env) { std::string p = remotepath::temp_files(server_env.get_server_name()) + "/" + random_alphanumeric_string(10); - std::string mkdir_cmd = "mkdir -p " + quote(p); - if (!execute_ssh_command(server_env.get_SSH_INFO(), sCommand(mkdir_cmd), cMode::Silent)) + if (0!=runner::execute_cmd("mkdir", {"-p",quote(p)}, "", {}, true, false, server_env.get_SSH_INFO())) std::cerr << "Failed to create temp directory on server" << std::endl; else mPath = p; @@ -690,8 +686,8 @@ cRemoteTempFolder::cRemoteTempFolder(const server_env_manager &server_env) : mSe cRemoteTempFolder::~cRemoteTempFolder() { - std::string rm_cmd = "rm -rf " + quote(mPath); - execute_ssh_command(mServerEnv.get_SSH_INFO(), sCommand(rm_cmd), cMode::Silent); + if (0!=runner::execute_cmd("rm", {"-rf",quote(mPath)}, "", {}, true, false, mServerEnv.get_SSH_INFO())) + std::cerr << "Failed to remove temp directory on server" << std::endl; } std::string cRemoteTempFolder::path() const @@ -754,7 +750,7 @@ bool service_runner::rsync_copy(const std::string& local_path, const std::string mServerEnv.get_SSH_USER() + "@" + mServerEnv.get_SSH_HOST() + ":" + quote(remote_path); - if (0 != runner::execute_cmd(rsync_cmd, {}, "", {}, true, false, &mServerEnv.get_SSH_INFO())) { + if (0 != runner::execute_cmd(rsync_cmd, {}, "", {}, true, false, mServerEnv.get_SSH_INFO())) { std::cerr << "Failed to copy files using rsync" << std::endl; std::cerr << "Is rsync installed on the remote host?" << std::endl; return false; diff --git a/src/utils/runner.cpp b/src/utils/runner.cpp index 6e727db..0e55072 100644 --- a/src/utils/runner.cpp +++ b/src/utils/runner.cpp @@ -347,14 +347,14 @@ int execute_cmd( const std::vector& args, const std::string& working_dir, const std::map& env, - bool silent, - bool interactive, - sSSHInfo* sshinfo, + const bool silent, + const bool interactive, + const copySSHPtr& sshinfo, std::string* output ) { - if (sshinfo) { + if (sshinfo.valid()) { std::string error; - ssh_session session = ssh_connect_and_auth(sshinfo, env, &error); + ssh_session session = ssh_connect_and_auth(&sshinfo, env, &error); if (!session) { if (output) *output = error; return -1; diff --git a/src/utils/runner.hpp b/src/utils/runner.hpp index a618a69..2f6a697 100644 --- a/src/utils/runner.hpp +++ b/src/utils/runner.hpp @@ -14,14 +14,24 @@ struct sSSHInfo { std::string port; }; +class copySSHPtr { + public: + copySSHPtr(const sSSHInfo* sshinfo) : mSSHInfo(sshinfo ? *sshinfo : sSSHInfo()) {} + copySSHPtr(const sSSHInfo& sshinfo) : mSSHInfo(sshinfo) {} + bool valid() const { return !mSSHInfo.host.empty(); } + const sSSHInfo * operator&() const { return (valid() ? &mSSHInfo : nullptr); } + private: + sSSHInfo mSSHInfo; +}; + int execute_cmd( const std::string& command, const std::vector& args, const std::string& working_dir, const std::map& env, - bool silent, - bool interactive, - sSSHInfo* sshinfo = nullptr, + const bool silent, + const bool interactive, + const copySSHPtr sshinfo = nullptr, std::string* output = nullptr );