From f9dca5fea17e380cd21e8afacc8515b2db9fa32f Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 10 May 2025 17:32:03 +1200 Subject: [PATCH] Sigh --- src/service_runner.cpp | 16 ++++---- src/utils/runner.cpp | 85 +++++++++++++++++++++++++----------------- 2 files changed, 57 insertions(+), 44 deletions(-) diff --git a/src/service_runner.cpp b/src/service_runner.cpp index 8bef186..e78ca7b 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; @@ -748,14 +748,12 @@ std::string service_runner::get_latest_backup_file(const std::string& server, co bool service_runner::rsync_copy(const std::string& local_path, const std::string& remote_path, bool silent) { std::cout << "Copying: [LOCAL] " << local_path << std::endl << std::string(8,' ')<<"[REMOTE] " << remote_path << std::endl; - std::string rsync_cmd = "rsync --delete -zrpc -e 'ssh -p " + mServerEnv.get_SSH_PORT() + "' " + - quote(local_path) + " " + - 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", + {"--delete","--mkpath","-zrpc","-e",quote("ssh -p " + mServerEnv.get_SSH_PORT()),local_path, + mServerEnv.get_SSH_USER()+"@"+mServerEnv.get_SSH_HOST()+":"+remote_path}, + "", {}, true, false)) { std::cerr << "Failed to copy files using rsync" << std::endl; - std::cerr << "Is rsync installed on the remote host?" << std::endl; return false; } return true; diff --git a/src/utils/runner.cpp b/src/utils/runner.cpp index 87f049f..1761460 100644 --- a/src/utils/runner.cpp +++ b/src/utils/runner.cpp @@ -88,34 +88,34 @@ std::string ssh_build_remote_command(const std::string& command, const std::vect } remote_cmd << command; for (const auto& arg : args) { - remote_cmd << " '" << arg << "'"; + remote_cmd << " " << arg; } return remote_cmd.str(); } -// Utility function to escape special shell characters -std::string escape_shell_arg(const std::string& arg) { - std::ostringstream escaped; - escaped << '"'; - for (char c : arg) { - if (c == '"' || c == '\\' || c == '$' || c == '`') { - escaped << '\\'; - } - escaped << c; - } - escaped << '"'; - return escaped.str(); -} +// // Utility function to escape special shell characters +// std::string escape_shell_arg(const std::string& arg) { +// std::ostringstream escaped; +// escaped << '"'; +// for (char c : arg) { +// if (c == '"' || c == '\\' || c == '$' || c == '`') { +// escaped << '\\'; +// } +// escaped << c; +// } +// escaped << '"'; +// return escaped.str(); +// } -// For non-interactive SSH, just build the command with args -std::string ssh_build_command_only(const std::string& command, const std::vector& args) { - std::ostringstream remote_cmd; - remote_cmd << command; - for (const auto& arg : args) { - remote_cmd << " " << escape_shell_arg(arg); - } - return remote_cmd.str(); -} +// // For non-interactive SSH, just build the command with args +// std::string ssh_build_command_only(const std::string& command, const std::vector& args) { +// std::ostringstream remote_cmd; +// remote_cmd << command; +// for (const auto& arg : args) { +// remote_cmd << " " << arg; +// } +// return remote_cmd.str(); +// } int ssh_interactive_shell_session(ssh_session session, ssh_channel channel, const std::string& remote_cmd_str, const std::string& command, std::string* output) { // Request a PTY with xterm-256color type for color support @@ -208,7 +208,7 @@ int ssh_exec_command(ssh_session session, ssh_channel channel, const std::string cmd_with_env << "env "; for (const auto& kv : env) { if (kv.first == "SSHPASS") continue; - cmd_with_env << kv.first << "='" << kv.second << "' "; + cmd_with_env << kv.first << "=\"" << kv.second << "\" "; } } @@ -219,20 +219,14 @@ int ssh_exec_command(ssh_session session, ssh_channel channel, const std::string if (!working_dir.empty()) { cmd_with_env << "cd " << working_dir << " && "; } - - // Add the command, but replace any single quotes with '\'' - std::string escaped_cmd = remote_cmd_str; - size_t pos = 0; - while ((pos = escaped_cmd.find('\'', pos)) != std::string::npos) { - escaped_cmd.replace(pos, 1, "'\\''"); - pos += 4; // Length of "'\\''" - } - cmd_with_env << escaped_cmd; + cmd_with_env << remote_cmd_str; // Close the single quote cmd_with_env << "'"; std::string final_cmd = cmd_with_env.str(); + + std::cout << "Final remote command: " << final_cmd << std::endl; int rc = ssh_channel_request_exec(channel, final_cmd.c_str()); if (rc != SSH_OK) { @@ -297,27 +291,34 @@ int local_execute_cmd( bool interactive, std::string* output ) { + std::cerr << "Local command: " << command << std::endl; + int pipefd[2]; bool use_pipe = output && !interactive; if (use_pipe && pipe(pipefd) == -1) { perror("pipe"); + std::cerr << "Pipe error: " << strerror(errno) << std::endl; return -1; } pid_t pid = fork(); if (pid == -1) { perror("fork"); + std::cerr << "Fork error: " << strerror(errno) << std::endl; return -1; } if (pid == 0) { if (!working_dir.empty()) { if (chdir(working_dir.c_str()) != 0) { perror("chdir"); + std::cerr << "Chdir error: " << strerror(errno) << std::endl; exit(-1); } } + for (const auto& kv : env) { setenv(kv.first.c_str(), kv.second.c_str(), 1); } + if (use_pipe) { close(pipefd[0]); dup2(pipefd[1], STDOUT_FILENO); @@ -338,6 +339,12 @@ int local_execute_cmd( argv.push_back(const_cast(arg.c_str())); } argv.push_back(nullptr); + + std::cerr << "Local command: " << command << std::endl; + for (const auto& arg : args) { + std::cerr << "Local arg: " << arg << std::endl; + } + execvp(command.c_str(), argv.data()); perror("execvp"); exit(-1); @@ -355,6 +362,7 @@ int local_execute_cmd( } int status = 0; waitpid(pid, &status, 0); + std::cerr << "Waitpid status: " << status << std::endl; if (WIFEXITED(status)) { return WEXITSTATUS(status); } else { @@ -380,6 +388,7 @@ int execute_cmd( ssh_session session = ssh_connect_and_auth(&sshinfo, env, &error); if (!session) { if (output) *output = error; + std::cerr << "SSH connection error: " << error << std::endl; return -1; } ssh_channel channel = ssh_channel_new(session); @@ -387,6 +396,7 @@ int execute_cmd( if (output) *output = "Failed to create SSH channel."; ssh_disconnect(session); ssh_free(session); + std::cerr << "SSH channel error: " << output->c_str() << std::endl; return -1; } int rc = ssh_channel_open_session(channel); @@ -395,16 +405,16 @@ int execute_cmd( ssh_channel_free(channel); ssh_disconnect(session); ssh_free(session); + std::cerr << "SSH channel open error: " << output->c_str() << std::endl; return -1; } int ret = 0; + std::string remote_cmd_str = ssh_build_remote_command(command, args, working_dir, {}); if (interactive) { - std::string remote_cmd_str = ssh_build_remote_command(command, args, working_dir, {}); ret = ssh_interactive_shell_session(session, channel, remote_cmd_str, command, output); } else { // For non-interactive, handle working directory in ssh_exec_command - std::string remote_cmd_str = ssh_build_command_only(command, args); ret = ssh_exec_command(session, channel, remote_cmd_str, silent, output, env, working_dir); } @@ -413,11 +423,16 @@ int execute_cmd( ssh_channel_free(channel); ssh_disconnect(session); ssh_free(session); + if (output) trim(output); + + std::cerr << "SSH command execution result: " << ret << std::endl; return ret; } else { int ret=local_execute_cmd(command, args, working_dir, env, silent, interactive, output); if (output) trim(output); + + std::cerr << "Local command execution result: " << ret << std::endl; return ret; } }