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< /dev/null 2>&1" : ""), env_vars); + std::vector cmd = {"bash", script_path}; + cmd.insert(cmd.end(), args.begin(), args.end()); + sCommand scommand(remote_service_template_path, cmd, env_vars); if (scommand.empty()) std::cerr << "Error: Failed to construct command for " << service_name << " " << command << std::endl; @@ -132,13 +134,15 @@ sCommand server_env_manager::construct_standard_template_run_cmd(const std::stri bool server_env_manager::check_remote_dir_exists(const std::string &dir_path) const { - sCommand scommand("test -d " + quote(dir_path)); - return execute_ssh_command(get_SSH_INFO(), scommand, cMode::Silent); + std::vector cmd = {"test", "-d", dir_path}; + sCommand scommand(cmd); + return execute_command(get_SSH_INFO(), scommand, cMode::Silent); } bool server_env_manager::check_remote_file_exists(const std::string& file_path) const { - sCommand scommand("test -f " + quote(file_path)); - return execute_ssh_command(get_SSH_INFO(), scommand, cMode::Silent); + std::vector cmd = {"test", "-f", file_path}; + sCommand scommand(cmd); + return execute_command(get_SSH_INFO(), scommand, cMode::Silent); } bool server_env_manager::check_remote_items_exist(const std::vector &file_paths) const @@ -151,9 +155,11 @@ bool server_env_manager::check_remote_items_exist(const std::vector file_names_str += std::filesystem::path(file_path).filename().string() + " "; } // check if all items in the vector exist on the remote server, in a single command. - sCommand scommand("for item in " + file_paths_str + "; do test -f $item; done"); + sCommand scommand({ + "bash", "-c", "for item in " + file_paths_str + "; do test -f $item; done" + }); - bool okay = execute_ssh_command(get_SSH_INFO(), scommand, cMode::Silent); + bool okay = execute_command(get_SSH_INFO(), scommand, cMode::Silent); if (!okay) { std::cerr << "Error: Required items not found on remote server: " << file_names_str << std::endl; return false; @@ -171,8 +177,8 @@ bool server_env_manager::run_remote_template_command(const std::string &service_ if (scommand.get_command_to_run().empty()) return false; - cMode mode = (command=="ssh") ? (cMode::Interactive | cMode::RawCommand) : cMode::Silent; - return execute_ssh_command(get_SSH_INFO(), scommand, mode); + cMode mode = (command=="ssh" ? cMode::Defaults : cMode::Silent); + return execute_command(get_SSH_INFO(), scommand, mode); } bool server_env_manager::run_remote_template_command_and_capture_output(const std::string &service_name, const std::string &command, std::vector args, std::string &output, bool silent, std::map extra_env_vars) const @@ -185,8 +191,8 @@ bool server_env_manager::run_remote_template_command_and_capture_output(const st for (const auto& [key, value] : extra_env_vars) scommand.add_env_var(key, value); - cMode mode = cMode::CaptureOutput | cMode::RawCommand; - return execute_ssh_command(get_SSH_INFO(), scommand, mode, &output); + cMode mode = cMode::CaptureOutput; + return execute_command(get_SSH_INFO(), scommand, mode, output); } diff --git a/src/service_runner.cpp b/src/service_runner.cpp index 8229443..f6d8573 100644 --- a/src/service_runner.cpp +++ b/src/service_runner.cpp @@ -55,16 +55,14 @@ bool service_runner::install(bool silent) { // Create service directory std::string remote_service_path = remotepath::service(mServer, mService); - std::string mkdir_cmd = "mkdir -p " + quote(remote_service_path); - if (!execute_ssh_command(mServerEnv.get_SSH_INFO(), sCommand(mkdir_cmd), cMode::Silent)) + if (!execute_command(mServerEnv.get_SSH_INFO(), sCommand({"mkdir", "-p", remote_service_path}), cMode::Silent)) { std::cerr << "Failed to create service directory " << remote_service_path << std::endl; return false; } // Check if rsync is installed on remote host - std::string check_rsync_cmd = "which rsync > /dev/null 2>&1"; - if (!execute_ssh_command(mServerEnv.get_SSH_INFO(), sCommand(check_rsync_cmd), cMode::Silent)) + if (!execute_command(mServerEnv.get_SSH_INFO(), sCommand({"which", "rsync", ">", "/dev/null", "2>&1"}), cMode::Silent)) { std::cerr << "rsync is not installed on the remote host" << std::endl; return false; @@ -73,15 +71,13 @@ bool service_runner::install(bool silent) { // Copy template files { std::cout << "Copying: [LOCAL] " << tinfo.local_template_path() << std::endl << std::string(8,' ')<<"[REMOTE] " << remotepath::service_template(mServer, mService) << "/" << std::endl; - std::string rsync_cmd = "rsync --delete -zrpc -e 'ssh -p " + mServerEnv.get_SSH_PORT() + "' " + - quote(tinfo.local_template_path().string()+"/") + " "+ - mServerEnv.get_SSH_USER() + "@" + mServerEnv.get_SSH_HOST() + ":" + - quote(remotepath::service_template(mServer, mService)+"/"); - //std::cout << std::endl << rsync_cmd << std::endl << std::endl; - if (!execute_local_command(rsync_cmd, silent ? cMode::Silent : cMode::None)) + std::vector rsync_cmd = {"rsync", "--delete", "-zrpc", "-e", "ssh","-p", mServerEnv.get_SSH_PORT(), + tinfo.local_template_path().string()+"/", + mServerEnv.get_SSH_USER() + "@" + mServerEnv.get_SSH_HOST() + ":" + quote(remotepath::service_template(mServer, mService)+"/") + }; + if (!execute_command(rsync_cmd, silent ? cMode::Silent : cMode::Defaults)) { std::cerr << "Failed to copy template files using rsync" << std::endl; - std::cerr << "Is rsync installed on the remote host?" << std::endl; return false; } } @@ -94,11 +90,11 @@ bool service_runner::install(bool silent) { return false; } std::cout << "Copying: [LOCAL] " << local_service_path << std::endl < rsync_cmd = {"rsync", "--delete", "-zrpc", "-e", "ssh", "-p", mServerEnv.get_SSH_PORT(), + quote(local_service_path + "/"), + mServerEnv.get_SSH_USER() + "@" + mServerEnv.get_SSH_HOST() + ":" + quote(remotepath::service_config(mServer,mService) + "/") + }; + if (!execute_command(rsync_cmd, silent ? cMode::Silent : cMode::Defaults)) { std::cerr << "Failed to copy service files using rsync" << std::endl; return false; @@ -141,8 +137,8 @@ bool service_runner::uninstall(bool silent) { } // 4. Remove the service directory from the server - std::string rm_cmd = "rm -rf " + quote(remotepath::service(mServer, mService)); - if (!execute_ssh_command(mServerEnv.get_SSH_INFO(), sCommand(rm_cmd), cMode::Silent)) { + std::vector rm_cmd = {"rm", "-rf", remotepath::service(mServer, mService)}; + if (!execute_command(mServerEnv.get_SSH_INFO(), sCommand(rm_cmd), cMode::Silent)) { std::cerr << "Failed to remove service directory" << std::endl; return false; } @@ -189,8 +185,8 @@ bool service_runner::fullnuke() return false; } - std::string rm_cmd = "rm -rf " + quote(local_service_path); - if (!execute_local_command(rm_cmd, cMode::Silent)) { + std::vector rm_cmd = {"rm", "-rf", local_service_path}; + if (!execute_command(sCommand(rm_cmd), cMode::Silent)) { std::cerr << "Failed to remove service directory" << std::endl; return false; } @@ -407,13 +403,13 @@ bool service_runner::interactive_ssh(const std::string & server_name, const std: return false; } - sCommand scommand("bash"); + 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 execute_command(env.get_SSH_INFO(), scommand, cMode::Defaults); } void service_runner::edit_server(const std::string &server_name) @@ -445,14 +441,14 @@ bool service_runner::edit_file(const std::string &file_path) std::string parent_dir = get_parent(file_path); std::filesystem::create_directories(parent_dir); - std::string editor_cmd; + std::vector 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); + editor_cmd = {std::string(editor_env), 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); + editor_cmd = {"nano", "-w", 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; @@ -461,7 +457,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 execute_command(editor_cmd, cMode::Defaults); } bool service_runner::interactive_ssh_service() @@ -567,8 +563,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)) { + std::vector 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_command(sCommand(scp_cmd), silent ? cMode::Silent : cMode::Defaults)) { std::cerr << "Failed to copy backup file from server" << std::endl; return false; } @@ -645,8 +641,7 @@ 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 (!execute_command(mServerEnv.get_SSH_INFO(), sCommand({"mkdir","-p",remote_backups_dir}), cMode::Silent)) { std::cerr << "Failed to create backups directory on server" << std::endl; return false; } @@ -687,10 +682,11 @@ bool service_runner::backup(bool silent) { } // Copy backup file from server to local - std::string scp_cmd = "scp -P " + mServerEnv.get_SSH_PORT() + " " + + std::vector 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)) { + remote_backup_file_path, + local_backup_file_path}; + if (!execute_command(sCommand(scp_cmd), silent ? cMode::Silent : cMode::Defaults)) { std::cerr << "Failed to copy backup file from server" << std::endl; return false; } @@ -706,8 +702,8 @@ 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)) + std::vector mkdir_cmd = {"mkdir", "-p", p}; + if (!execute_command(server_env.get_SSH_INFO(), sCommand(mkdir_cmd), cMode::Silent)) std::cerr << "Failed to create temp directory on server" << std::endl; else mPath = p; @@ -715,8 +711,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); + std::vector rm_cmd = {"rm", "-rf", mPath}; + execute_command(mServerEnv.get_SSH_INFO(), sCommand(rm_cmd), cMode::Silent); } std::string cRemoteTempFolder::path() const diff --git a/src/utils/execute.cpp b/src/utils/execute.cpp index b4a7c7e..ddd109e 100644 --- a/src/utils/execute.cpp +++ b/src/utils/execute.cpp @@ -7,22 +7,25 @@ #include #include #include - +#include #include "execute.hpp" #include "contrib/base64.hpp" #include "utils/utils.hpp" - +#include "utils/directories.hpp" bool EXITSTATUSCHECK(int ret) { return (ret != -1 && WIFEXITED(ret) && (WEXITSTATUS(ret) == 0)); // ret is -1 if the command failed to execute. } namespace dropshell { -bool execute_local_command_interactive(const sCommand &command, bool silent) +bool __execute_command(std::vector command, std::string * output) { - if (command.get_command_to_run().empty()) + int pipefd[2]; + bool capture = (output != nullptr); + if (capture && pipe(pipefd) == -1) { + perror("pipe failed"); return false; - std::string full_command = command.construct_cmd(cStyle::Raw); // Get the command string + } pid_t pid = fork(); @@ -32,20 +35,40 @@ bool execute_local_command_interactive(const sCommand &command, bool silent) return false; } else if (pid == 0) { // Child process - std::vector commandvec = {"bash", "-c", full_command.c_str(),NULL}; - - if (!silent) { - std::cout << "Executing command: "; - for (auto & x : commandvec) std::cout << x << " "; - std::cout << std::endl; + if (capture) { + close(pipefd[0]); // Close read end + dup2(pipefd[1], STDOUT_FILENO); // Redirect stdout to pipe + dup2(pipefd[1], STDERR_FILENO); // Redirect stderr to pipe + close(pipefd[1]); } + std::vector commandvec; + for (auto & x : command) { + commandvec.push_back(x.c_str()); + } + commandvec.push_back(NULL); + + // if (!silent) { + // std::cout << "Executing command: "; + // for (auto & x : commandvec) std::cout << x << " "; + // std::cout << std::endl; + // } + execvp(commandvec[0], const_cast(commandvec.data())); // If execvp returns, it means an error occurred perror("execvp failed"); exit(EXIT_FAILURE); // Exit child process on error } else { // Parent process + if (capture) { + close(pipefd[1]); // Close write end + char buffer[256]; + ssize_t count; + while ((count = read(pipefd[0], buffer, sizeof(buffer))) > 0) { + output->append(buffer, count); + } + close(pipefd[0]); + } int ret; // Wait for the child process to complete waitpid(pid, &ret, 0); @@ -54,129 +77,54 @@ bool execute_local_command_interactive(const sCommand &command, bool silent) } } -bool execute_local_command_and_capture_output(const sCommand& command, std::string * output, cMode mode) +bool execute_command(const sSSHInfo * ssh_info, const sCommand command, cMode mode, std::string * output) { - ASSERT(output != nullptr, "Output string must be provided"); - ASSERT(is_raw(mode), "Capture output mode requires raw command mode"); - ASSERT(!hasFlag(mode, cMode::Silent), "Silent mode is not allowed with capture output mode"); if (command.get_command_to_run().empty()) return false; - cStyle style = getStyle(mode); - std::string full_cmd = command.construct_cmd(style) + " 2>&1"; - FILE *pipe = popen(full_cmd.c_str(), "r"); - if (!pipe) { - return false; + + std::vector commandvec; + + if (ssh_info) + { + std::vector ssh_command = {"/usr/bin/ssh", "-p", ssh_info->port, "-tt", ssh_info->user, "@", ssh_info->host}; + commandvec.insert(commandvec.end(), ssh_command.begin(), ssh_command.end()); } - char buffer[128]; - while (fgets(buffer, sizeof(buffer), pipe) != nullptr) { - (*output) += buffer; - } - int ret = pclose(pipe); - return EXITSTATUSCHECK(ret); -} + commandvec.push_back("bash"); + commandvec.push_back("-c"); + commandvec.insert(commandvec.end(), command.get_command_to_run().begin(), command.get_command_to_run().end()); -bool execute_local_command(const sCommand & command, cMode mode, std::string * output /* = nullptr */) -{ - if (hasFlag(mode, cMode::Interactive)) { - ASSERT(! hasFlag(mode, cMode::CaptureOutput), "Interactive mode and capture output mode cannot be used together"); - ASSERT(output == nullptr, "Interactive mode and an output string cannot be used together"); - ASSERT(is_raw(mode), "Interactive mode requires raw command mode"); - - return execute_local_command_interactive(command, hasFlag(mode, cMode::Silent)); - } if (hasFlag(mode, cMode::CaptureOutput)) { - ASSERT(output != nullptr, "Capture output mode requires an output string to be provided"); - ASSERT(is_raw(mode), "Capture output mode requires raw command mode"); - ASSERT(!hasFlag(mode, cMode::Silent), "Silent mode is not allowed with capture output mode"); - - return execute_local_command_and_capture_output(command, output, mode); + ASSERT(output, "Capture output mode requires an output string to be provided"); + return __execute_command(commandvec, output); } - - if (command.get_command_to_run().empty()) - return false; - cStyle style = getStyle(mode); - std::string full_cmd = command.construct_cmd(style) + " 2>&1" + (hasFlag(mode, cMode::Silent) ? " > /dev/null" : ""); - int ret = system(full_cmd.c_str()); - - bool ok = EXITSTATUSCHECK(ret); - if (!ok) { - std::cerr << "Error: Failed to execute command: " << std::endl; - std::cerr << full_cmd << std::endl; - } - return ok; -} - -bool execute_ssh_command(const sSSHInfo &ssh_info, const sCommand &command, cMode mode, std::string *output) -{ - if (command.get_command_to_run().empty()) - return false; - - ASSERT(!(hasFlag(mode, cMode::Interactive) && !is_raw(mode)), "Interactive mode requires raw command mode"); - ASSERT(!(hasFlag(mode, cMode::CaptureOutput) && output == nullptr), "Capture output mode must be used with an output string"); - - std::stringstream ssh_cmd; - ssh_cmd << "ssh -p " << ssh_info.port << " " << (hasFlag(mode, cMode::Interactive) ? "-tt " : "") - << ssh_info.user << "@" << ssh_info.host; - - std::string cmdstr; - if (!is_raw(mode)) - cmdstr = quote("bash -c " + command.construct_cmd(cStyle::Safe)); else { - std::string raw_cmd = command.construct_cmd(cStyle::Raw); - ASSERT(raw_cmd.find("'") == std::string::npos, "Raw command must not contain single quotes"); - cmdstr = "bash -c "+ halfquote(raw_cmd); + return __execute_command(commandvec, nullptr); } - - sCommand ssh_command(ssh_cmd.str() + " " + cmdstr); - - bool rval = execute_local_command(ssh_command, mode, output); - - if (!rval) { - std::cerr < #include +#include namespace dropshell { @@ -10,15 +11,9 @@ class sCommand; // mode bitset enum class cMode { - None = 0, - Interactive = 1, - Silent = 2, - CaptureOutput = 4, - RawCommand = 8 -}; -enum class cStyle { - Safe = 0, - Raw = 1 + Defaults = 0, + Silent = 1, + CaptureOutput = 2 }; inline cMode operator&(cMode lhs, cMode rhs) {return static_cast(static_cast(lhs) & static_cast(rhs));} @@ -27,10 +22,6 @@ inline cMode operator-(cMode lhs, cMode rhs) {return static_cast(static_c inline cMode operator|(cMode lhs, cMode rhs) {return static_cast(static_cast(lhs) | static_cast(rhs));} inline cMode operator|=(cMode & lhs, cMode rhs) {return lhs = lhs | rhs;} inline bool hasFlag(cMode mode, cMode flag) {return (mode & flag) == flag;} -inline bool is_safe(cStyle style) { return style == cStyle::Safe; } -inline bool is_raw(cStyle style) { return style == cStyle::Raw; } -inline bool is_raw(cMode mode) { return hasFlag(mode, cMode::RawCommand); } -inline cStyle getStyle(cMode mode) { return is_raw(mode) ? cStyle::Raw : cStyle::Safe; } typedef struct sSSHInfo { @@ -39,11 +30,10 @@ typedef struct sSSHInfo { std::string port; } sSSHInfo; -bool execute_local_command(const sCommand & command, cMode mode = cMode::None, std::string * output = nullptr); -bool execute_ssh_command(const sSSHInfo & ssh_info, const sCommand & command, cMode mode = cMode::None, std::string * output = nullptr); - -std::string makesafecmd(const std::string& command); - +bool execute_command(const sSSHInfo ssh_info, const sCommand command, const cMode mode); +bool execute_command(const sSSHInfo ssh_info, const sCommand command, const cMode mode, std::string & output); +bool execute_command(const sCommand command, const cMode mode); +bool execute_command(const sCommand command, const cMode mode, std::string & output); // ------------------------------------------------------------------------------------------------ @@ -52,27 +42,24 @@ std::string makesafecmd(const std::string& command); // class to hold a command to run on the remote server. class sCommand { public: - sCommand(std::string directory_to_run_in, std::string command_to_run, const std::map & env_vars) : - mDir(directory_to_run_in), mCmd(command_to_run), mVars(env_vars) {} - sCommand(std::string command_to_run) : - mDir(""), mCmd(command_to_run), mVars({}) {} - sCommand() : mDir(""), mCmd(""), mVars({}) {} + sCommand(std::string directory_to_run_in, const std::vector & command_to_run, const std::map & env_vars) : + mDir(directory_to_run_in), mCmdArgs(command_to_run), mEnvVars(env_vars) {} + sCommand(const std::vector & command_to_run) : + mDir(""), mCmdArgs(command_to_run), mEnvVars({}) {} + sCommand() : mDir(""), mCmdArgs({}), mEnvVars({}) {} std::string get_directory_to_run_in() const { return mDir; } - std::string get_command_to_run() const { return mCmd; } - const std::map& get_env_vars() const { return mVars; } + const std::vector& get_command_to_run() const { return mCmdArgs; } + const std::map& get_env_vars() const { return mEnvVars; } - void add_env_var(const std::string& key, const std::string& value) { mVars[key] = value; } - - - std::string construct_cmd(cStyle style) const; + void add_env_var(const std::string& key, const std::string& value) { mEnvVars[key] = value; } - bool empty() const { return mCmd.empty(); } + bool empty() const { return mCmdArgs.empty(); } private: std::string mDir; - std::string mCmd; - std::map mVars; + std::vector mCmdArgs; + std::map mEnvVars; }; diff --git a/templates/dropshell-agent/_allservicesstatus.sh b/templates/dropshell-agent/_allservicesstatus.sh old mode 100644 new mode 100755 diff --git a/templates/dropshell-agent/_nuke_other.sh b/templates/dropshell-agent/_nuke_other.sh old mode 100644 new mode 100755 diff --git a/templates/dropshell-agent/install.sh b/templates/dropshell-agent/install.sh old mode 100644 new mode 100755 diff --git a/templates/dropshell-agent/shared/_autocommands.sh b/templates/dropshell-agent/shared/_autocommands.sh old mode 100644 new mode 100755 diff --git a/templates/dropshell-agent/shared/_common.sh b/templates/dropshell-agent/shared/_common.sh old mode 100644 new mode 100755 diff --git a/templates/dropshell-agent/shared/_run.sh b/templates/dropshell-agent/shared/_run.sh new file mode 100755 index 0000000..a954dd7 --- /dev/null +++ b/templates/dropshell-agent/shared/_run.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +directory_to_run_in=${1:-} +command_to_run_base64=${2:-} + +if [ -z "$directory_to_run_in" ]; then + echo "Usage: $0 " + exit 1 +fi + +if [ -z "$command_to_run_base64" ]; then + echo "Usage: $0 " + exit 1 +fi + +command_to_run=$(echo "$command_to_run_base64" | base64 -d) + +if [ -z "$command_to_run" ]; then + echo "Usage: $0 " + exit 1 +fi + + +if [ -n "$directory_to_run_in" ]; then + cd "$directory_to_run_in" +fi + +eval "$command_to_run" + + + + diff --git a/templates/dropshell-agent/uninstall.sh b/templates/dropshell-agent/uninstall.sh old mode 100644 new mode 100755