Compare commits
8 Commits
2025.0518.
...
2025.0519.
Author | SHA1 | Date | |
---|---|---|---|
d8236a58df | |||
625de98890 | |||
7c1b51a93c | |||
1be7af571f | |||
1439ec2f79 | |||
6c3c35bf89 | |||
548ffea6f9 | |||
434a2bc6da |
1
.gitignore
vendored
1
.gitignore
vendored
@ -7,6 +7,7 @@ out/
|
|||||||
bin/
|
bin/
|
||||||
lib/
|
lib/
|
||||||
output/
|
output/
|
||||||
|
autogen/
|
||||||
|
|
||||||
# Compiled Object files
|
# Compiled Object files
|
||||||
*.o
|
*.o
|
||||||
|
@ -48,6 +48,19 @@ add_custom_target(run_createagent ALL
|
|||||||
add_executable(dropshell ${SOURCES})
|
add_executable(dropshell ${SOURCES})
|
||||||
add_dependencies(dropshell run_createagent)
|
add_dependencies(dropshell run_createagent)
|
||||||
|
|
||||||
|
# Mark the generated files as GENERATED so CMake knows they'll be created during build
|
||||||
|
set_source_files_properties(
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/src/autogen/_agent-remote.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/src/autogen/_agent-local.cpp
|
||||||
|
PROPERTIES GENERATED TRUE
|
||||||
|
)
|
||||||
|
|
||||||
|
# Explicitly add the generated agent files, as they might not be in the source directory when globbed at the start.
|
||||||
|
target_sources(dropshell PRIVATE
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/src/autogen/_agent-remote.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/src/autogen/_agent-local.cpp
|
||||||
|
)
|
||||||
|
|
||||||
# Set include directories
|
# Set include directories
|
||||||
# build dir goes first so that we can use the generated version.hpp
|
# build dir goes first so that we can use the generated version.hpp
|
||||||
target_include_directories(dropshell PRIVATE
|
target_include_directories(dropshell PRIVATE
|
||||||
|
83
source/agent-local/agent-install.sh
Executable file
83
source/agent-local/agent-install.sh
Executable file
@ -0,0 +1,83 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
SCRIPT_DIR=$(dirname "$0")
|
||||||
|
|
||||||
|
echo "Installing dropshell host agent on this computer..."
|
||||||
|
|
||||||
|
|
||||||
|
# Prints an error message in red and exits with status code 1.
|
||||||
|
_die() {
|
||||||
|
echo -e "Error: $1"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Checks if listed environment variables are set; calls _die() if any are missing.
|
||||||
|
_check_required_env_vars() {
|
||||||
|
local required_vars=("$@")
|
||||||
|
for var in "${required_vars[@]}"; do
|
||||||
|
if [ -z "${!var}" ]; then
|
||||||
|
_die "Required environment variable $var is not set"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Checks if Docker is installed, running, and user has permission. Returns 1 on failure.
|
||||||
|
_check_docker_installed() {
|
||||||
|
if ! command -v docker &> /dev/null; then
|
||||||
|
echo "Docker is not installed"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check if docker daemon is running
|
||||||
|
if ! docker info &> /dev/null; then
|
||||||
|
echo "Docker daemon is not running"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check if user has permission to run docker
|
||||||
|
if ! docker run --rm hello-world &> /dev/null; then
|
||||||
|
echo "User does not have permission to run docker"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
function install_bb64() {
|
||||||
|
# check curl installed
|
||||||
|
if ! command -v curl &> /dev/null; then
|
||||||
|
_die "Curl is not installed. Curl is required for agent installation."
|
||||||
|
fi
|
||||||
|
|
||||||
|
curl -fsSL "https://gitea.jde.nz/public/bb64/releases/download/latest/install.sh" | bash -s -- "$AGENT_PATH" "$(id -u $USER):$(id -g $USER)"
|
||||||
|
|
||||||
|
# test result code from curl
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
_die "Failed to install bb64. Curl returned non-zero exit code."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# test if bb64 is installed
|
||||||
|
"$AGENT_PATH/bb64" -v
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
_die "bb64 did not install correctly."
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "bb64 installed successfully."
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
set -a
|
||||||
|
AGENT_PATH="$SCRIPT_DIR"
|
||||||
|
set +a
|
||||||
|
|
||||||
|
_check_required_env_vars "AGENT_PATH"
|
||||||
|
echo "Installing host agent into $AGENT_PATH"
|
||||||
|
|
||||||
|
_check_docker_installed || _die "Docker is required."
|
||||||
|
|
||||||
|
install_bb64
|
||||||
|
|
87
source/agent-remote/agent-install.sh
Executable file
87
source/agent-remote/agent-install.sh
Executable file
@ -0,0 +1,87 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# This script is used to install the dropshell agent on a remote server.
|
||||||
|
|
||||||
|
SCRIPT_DIR=$(dirname "$0")
|
||||||
|
|
||||||
|
set -a
|
||||||
|
|
||||||
|
AGENT_PATH="$SCRIPT_DIR"
|
||||||
|
|
||||||
|
set +a
|
||||||
|
|
||||||
|
|
||||||
|
if [ -f "$SCRIPT_DIR/common.sh" ]; then
|
||||||
|
source "$SCRIPT_DIR/common.sh"
|
||||||
|
else
|
||||||
|
echo "Error: common.sh not found in $SCRIPT_DIR"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_check_required_env_vars "AGENT_PATH"
|
||||||
|
|
||||||
|
function install_bb64() {
|
||||||
|
curl -fsSL "https://gitea.jde.nz/public/bb64/releases/download/latest/install.sh" | bash -s -- "$AGENT_PATH" "$(id -u $USER):$(id -g $USER)"
|
||||||
|
|
||||||
|
# test result code from curl
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
_die "Failed to install bb64. Curl returned non-zero exit code."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# test if bb64 is installed
|
||||||
|
VER=$("$AGENT_PATH/bb64" -v)
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
_die "bb64 did not install correctly."
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "bb64 v$VER installed."
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Check pre-requisites
|
||||||
|
|
||||||
|
# Check if curl is installed
|
||||||
|
if ! command -v curl &> /dev/null; then
|
||||||
|
_die "Curl is not installed. Curl is required for agent installation."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check docker installation
|
||||||
|
if ! command -v docker &> /dev/null; then
|
||||||
|
echo "Docker is not installed. Docker is required for agent installation."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
echo "Installing dropshell agent..."
|
||||||
|
|
||||||
|
install_bb64
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# confirm we're in a good state.
|
||||||
|
|
||||||
|
required_files=(
|
||||||
|
"$AGENT_PATH/bb64"
|
||||||
|
"$AGENT_PATH/_allservicesstatus.sh"
|
||||||
|
"$AGENT_PATH/common.sh"
|
||||||
|
"$AGENT_PATH/datacommands.sh"
|
||||||
|
)
|
||||||
|
|
||||||
|
# check if all files exist
|
||||||
|
for file in "${required_files[@]}"; do
|
||||||
|
if [ ! -f "$file" ]; then
|
||||||
|
_die "$file does not exist. Please check the installation."
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
echo "Completed dropshell agent installation."
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
exit 0
|
@ -47,7 +47,7 @@ _autocommandrun_path() {
|
|||||||
local path_parent=$(dirname ${path})
|
local path_parent=$(dirname ${path})
|
||||||
local path_child=$(basename ${path})
|
local path_child=$(basename ${path})
|
||||||
if [ -d "${path_parent}/${path_child}" ]; then
|
if [ -d "${path_parent}/${path_child}" ]; then
|
||||||
docker run --rm -v ${path_parent}:/volume debian bash -c "rm -rf /volume/${path_child}" || echo "Failed to nuke path ${path}"
|
docker run --rm -v ${path_parent}:/volume debian bash -c "rm -rfv /volume/${path_child}" || echo "Failed to nuke path ${path}"
|
||||||
else
|
else
|
||||||
echo "Path ${path} does not exist - nothing to nuke"
|
echo "Path ${path} does not exist - nothing to nuke"
|
||||||
fi
|
fi
|
||||||
@ -61,8 +61,14 @@ _autocommandrun_path() {
|
|||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
restore)
|
restore)
|
||||||
echo "Restoring path ${path}"
|
if [ ! -f "${backup_folder}/backup.tgz" ]; then
|
||||||
tar -xzvf ${backup_folder}/backup.tgz -C ${path} --strip-components=1
|
echo "Backup file ${backup_folder}/backup.tgz does not exist - nothing to restore"
|
||||||
|
else
|
||||||
|
echo "Clearing existing data in path ${path}"
|
||||||
|
docker run --rm -v ${path}:/path debian bash -c "rm -rfv /path/{*,.*}"
|
||||||
|
echo "Restoring path ${path} from backup file ${backup_folder}/backup.tgz"
|
||||||
|
tar -xzvf ${backup_folder}/backup.tgz -C ${path} --strip-components=1
|
||||||
|
fi
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
@ -91,7 +97,8 @@ _autocommandrun_file() {
|
|||||||
restore)
|
restore)
|
||||||
echo "Restoring file ${filepath}"
|
echo "Restoring file ${filepath}"
|
||||||
local file_name=$(basename ${filepath})
|
local file_name=$(basename ${filepath})
|
||||||
cp ${backup_folder}/${file_name} ${filepath}
|
rm -f ${filepath} || die "Unable to remove existing file ${filepath}, restore failed."
|
||||||
|
cp ${backup_folder}/${file_name} ${filepath} || die "Unable to copy file ${backup_folder}/${file_name} to ${filepath}, restore failed."
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
@ -1,7 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
echo "Running remote agent self-test..."
|
|
||||||
|
|
||||||
echo "Completed remote agent self-test."
|
|
||||||
|
|
||||||
exit 0
|
|
@ -142,8 +142,12 @@ if [ -n "$SUDO_USER" ] && [ "$SUDO_USER" != "root" ]; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# check if dehydrate command is installed
|
||||||
|
if ! command -v dehydrate &> /dev/null; then
|
||||||
|
curl -fsSL https://gitea.jde.nz/public/dehydrate/releases/download/latest/install.sh | bash
|
||||||
|
fi
|
||||||
|
|
||||||
|
dehydrate -u
|
||||||
|
|
||||||
|
|
||||||
print_status "All dependencies installed successfully!"
|
print_status "All dependencies installed successfully!"
|
||||||
|
@ -14,6 +14,7 @@ if ! command -v dehydrate &> /dev/null; then
|
|||||||
curl -fsSL https://gitea.jde.nz/public/dehydrate/releases/download/latest/install.sh | bash
|
curl -fsSL https://gitea.jde.nz/public/dehydrate/releases/download/latest/install.sh | bash
|
||||||
fi
|
fi
|
||||||
|
|
||||||
SCRIPT_DIR=$(dirname "$0")
|
mkdir -p "${SCRIPT_DIR}/src/autogen"
|
||||||
|
|
||||||
dehydrate "${SCRIPT_DIR}/agent" "${SCRIPT_DIR}/src/autogen"
|
dehydrate "${SCRIPT_DIR}/agent-remote" "${SCRIPT_DIR}/src/autogen"
|
||||||
|
dehydrate "${SCRIPT_DIR}/agent-local" "${SCRIPT_DIR}/src/autogen"
|
||||||
|
@ -1,442 +0,0 @@
|
|||||||
#include <fstream>
|
|
||||||
#include <filesystem>
|
|
||||||
#include <string>
|
|
||||||
#include <iostream>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
THIS FILE IS AUTO-GENERATED BY DEHYDRATE.
|
|
||||||
DO NOT EDIT THIS FILE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "_agent.hpp"
|
|
||||||
namespace recreate_agent {
|
|
||||||
|
|
||||||
|
|
||||||
// Tiny dependency-free FNV-1a 64-bit hash
|
|
||||||
static uint64_t fnv1a_64(const void* data, size_t len) {
|
|
||||||
const uint8_t* p = static_cast<const uint8_t*>(data);
|
|
||||||
uint64_t h = 0xcbf29ce484222325ULL;
|
|
||||||
for (size_t i = 0; i < len; ++i)
|
|
||||||
h = (h ^ p[i]) * 0x100000001b3ULL;
|
|
||||||
return h;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Base64 decoding function - no dependencies
|
|
||||||
static void base64_decode(const char* encoded_data, size_t encoded_len, unsigned char* output, size_t* output_len) {
|
|
||||||
const char* base64_chars =
|
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
||||||
size_t out_pos = 0;
|
|
||||||
int val = 0, valb = -8;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < encoded_len; i++) {
|
|
||||||
char c = encoded_data[i];
|
|
||||||
if (c == '=') break;
|
|
||||||
|
|
||||||
// Find position in base64_chars
|
|
||||||
const char* pos = strchr(base64_chars, c);
|
|
||||||
if (pos == nullptr) continue; // Skip invalid characters
|
|
||||||
|
|
||||||
val = (val << 6) + static_cast<int>(pos - base64_chars);
|
|
||||||
valb += 6;
|
|
||||||
if (valb >= 0) {
|
|
||||||
output[out_pos++] = static_cast<unsigned char>((val >> valb) & 0xFF);
|
|
||||||
valb -= 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*output_len = out_pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Utility function to recreate a file with proper permissions
|
|
||||||
static bool _recreate_file_(const std::filesystem::path& outpath, uint64_t file_hash, std::filesystem::perms file_perms, const unsigned char* filedata, size_t filedata_len) {
|
|
||||||
namespace fs = std::filesystem;
|
|
||||||
bool needs_write = false;
|
|
||||||
|
|
||||||
// Check if file exists and has correct hash
|
|
||||||
if (fs::exists(outpath)) {
|
|
||||||
// Check content hash
|
|
||||||
std::ifstream in(outpath, std::ios::binary);
|
|
||||||
std::ostringstream oss;
|
|
||||||
oss << in.rdbuf();
|
|
||||||
std::string data = oss.str();
|
|
||||||
uint64_t existing_hash = fnv1a_64(data.data(), data.size());
|
|
||||||
needs_write = existing_hash != file_hash;
|
|
||||||
} else {
|
|
||||||
needs_write = true; // File doesn't exist, need to create it
|
|
||||||
}
|
|
||||||
|
|
||||||
bool needs_permission_update = true;
|
|
||||||
if (!needs_write) { // we always update permissions if the file is written or changed. Othewise we check.
|
|
||||||
fs::perms current_perms = fs::status(outpath).permissions();
|
|
||||||
needs_permission_update = current_perms != file_perms;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (needs_write) {
|
|
||||||
fs::create_directories(outpath.parent_path());
|
|
||||||
std::ofstream out(outpath, std::ios::binary);
|
|
||||||
out.write(reinterpret_cast<const char*>(filedata), filedata_len);
|
|
||||||
out.close();
|
|
||||||
// Set the file permissions
|
|
||||||
fs::permissions(outpath, file_perms);
|
|
||||||
|
|
||||||
if (!fs::exists(outpath)) {
|
|
||||||
std::cout << "[dehydrate] " << outpath.filename() << ": created\n";
|
|
||||||
} else {
|
|
||||||
std::cout << "[dehydrate] " << outpath.filename() << ": updated (hash changed)\n";
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (needs_permission_update) {
|
|
||||||
// Update only permissions
|
|
||||||
fs::permissions(outpath, file_perms);
|
|
||||||
std::cout << "[dehydrate] " << outpath.filename() << ": updated (permissions changed)\n";
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool recreate_tree(std::string destination_folder) {
|
|
||||||
namespace fs = std::filesystem;
|
|
||||||
bool any_written = false;
|
|
||||||
{
|
|
||||||
// File: selftest.sh
|
|
||||||
fs::path outpath = fs::path(destination_folder) / "selftest.sh";
|
|
||||||
static const char filedata_base64[] = "IyEvYmluL2Jhc2gKCmVjaG8gIlJ1bm5pbmcgcmVtb3RlIGFnZW50IHNlbGYtdGVzdC4uLiIKCmVj"\
|
|
||||||
"aG8gIkNvbXBsZXRlZCByZW1vdGUgYWdlbnQgc2VsZi10ZXN0LiIKCmV4aXQgMAo=";
|
|
||||||
|
|
||||||
// Decode Base64 data
|
|
||||||
size_t decoded_size = (strlen(filedata_base64) * 3) / 4;
|
|
||||||
unsigned char* decoded_data = new unsigned char[decoded_size];
|
|
||||||
size_t actual_size;
|
|
||||||
base64_decode(filedata_base64, strlen(filedata_base64), decoded_data, &actual_size);
|
|
||||||
|
|
||||||
bool file_written = _recreate_file_(outpath, 11594895391899191874ULL, std::filesystem::perms(493), decoded_data, actual_size);
|
|
||||||
delete[] decoded_data;
|
|
||||||
any_written = any_written || file_written;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
// File: datacommands.sh
|
|
||||||
fs::path outpath = fs::path(destination_folder) / "datacommands.sh";
|
|
||||||
static const char filedata_base64[] = "IyEvYmluL2Jhc2gKCiMgVGhpcyBzY3JpcHQgY29udGFpbnMgdGhlIGNvbW1vbiBjb2RlIGZvciB0"\
|
|
||||||
"aGUgYXV0b2NvbW1hbmRzLgoKTVlJRD0kKGlkIC11KQpNWUdSUD0kKGlkIC1nKQoKX2F1dG9jb21t"\
|
|
||||||
"YW5kcnVuX3ZvbHVtZSgpIHsKICAgIGxvY2FsIGNvbW1hbmQ9IiQxIgogICAgbG9jYWwgdm9sdW1l"\
|
|
||||||
"X25hbWU9IiQyIgogICAgbG9jYWwgYmFja3VwX2ZvbGRlcj0iJDMiCgogICAgY2FzZSAiJGNvbW1h"\
|
|
||||||
"bmQiIGluCiAgICAgICAgY3JlYXRlKQogICAgICAgICAgICBlY2hvICJDcmVhdGluZyB2b2x1bWUg"\
|
|
||||||
"JHt2b2x1bWVfbmFtZX0iCiAgICAgICAgICAgIGRvY2tlciB2b2x1bWUgY3JlYXRlICR7dm9sdW1l"\
|
|
||||||
"X25hbWV9CiAgICAgICAgICAgIDs7CiAgICAgICAgbnVrZSkKICAgICAgICAgICAgZWNobyAiTnVr"\
|
|
||||||
"aW5nIHZvbHVtZSAke3ZvbHVtZV9uYW1lfSIKICAgICAgICAgICAgZG9ja2VyIHZvbHVtZSBybSAk"\
|
|
||||||
"e3ZvbHVtZV9uYW1lfQogICAgICAgICAgICA7OwogICAgICAgIGJhY2t1cCkKICAgICAgICAgICAg"\
|
|
||||||
"ZWNobyAiQmFja2luZyB1cCB2b2x1bWUgJHt2b2x1bWVfbmFtZX0iCiAgICAgICAgICAgIGRvY2tl"\
|
|
||||||
"ciBydW4gLS1ybSAtdiAke3ZvbHVtZV9uYW1lfTovdm9sdW1lIC12ICR7YmFja3VwX2ZvbGRlcn06"\
|
|
||||||
"L2JhY2t1cCBkZWJpYW4gYmFzaCAtYyAidGFyIC1jenZmIC9iYWNrdXAvYmFja3VwLnRneiAtQyAv"\
|
|
||||||
"dm9sdW1lIC4gJiYgY2hvd24gLVIgJE1ZSUQ6JE1ZR1JQIC9iYWNrdXAiCiAgICAgICAgICAgIDs7"\
|
|
||||||
"CiAgICAgICAgcmVzdG9yZSkKICAgICAgICAgICAgZWNobyAiUmVzdG9yaW5nIHZvbHVtZSAke3Zv"\
|
|
||||||
"bHVtZV9uYW1lfSIKICAgICAgICAgICAgZG9ja2VyIHZvbHVtZSBybSAke3ZvbHVtZV9uYW1lfQog"\
|
|
||||||
"ICAgICAgICAgICBkb2NrZXIgdm9sdW1lIGNyZWF0ZSAke3ZvbHVtZV9uYW1lfQogICAgICAgICAg"\
|
|
||||||
"ICBkb2NrZXIgcnVuIC0tcm0gLXYgJHt2b2x1bWVfbmFtZX06L3ZvbHVtZSAtdiAke2JhY2t1cF9m"\
|
|
||||||
"b2xkZXJ9Oi9iYWNrdXAgZGViaWFuIGJhc2ggLWMgInRhciAteHp2ZiAvYmFja3VwL2JhY2t1cC50"\
|
|
||||||
"Z3ogLUMgL3ZvbHVtZSAtLXN0cmlwLWNvbXBvbmVudHM9MSIKICAgICAgICAgICAgOzsKICAgIGVz"\
|
|
||||||
"YWMKfSAgIAoKX2F1dG9jb21tYW5kcnVuX3BhdGgoKSB7CiAgICBsb2NhbCBjb21tYW5kPSIkMSIK"\
|
|
||||||
"ICAgIGxvY2FsIHBhdGg9IiQyIgogICAgbG9jYWwgYmFja3VwX2ZvbGRlcj0iJDMiCgogICAgY2Fz"\
|
|
||||||
"ZSAiJGNvbW1hbmQiIGluCiAgICAgICAgY3JlYXRlKQogICAgICAgICAgICBlY2hvICJDcmVhdGlu"\
|
|
||||||
"ZyBwYXRoICR7cGF0aH0iCiAgICAgICAgICAgIG1rZGlyIC1wICR7cGF0aH0KICAgICAgICAgICAg"\
|
|
||||||
"OzsKICAgICAgICBudWtlKQogICAgICAgICAgICBlY2hvICJOdWtpbmcgcGF0aCAke3BhdGh9Igog"\
|
|
||||||
"ICAgICAgICAgICBsb2NhbCBwYXRoX3BhcmVudD0kKGRpcm5hbWUgJHtwYXRofSkKICAgICAgICAg"\
|
|
||||||
"ICAgbG9jYWwgcGF0aF9jaGlsZD0kKGJhc2VuYW1lICR7cGF0aH0pCiAgICAgICAgICAgIGlmIFsg"\
|
|
||||||
"LWQgIiR7cGF0aF9wYXJlbnR9LyR7cGF0aF9jaGlsZH0iIF07IHRoZW4KICAgICAgICAgICAgICAg"\
|
|
||||||
"IGRvY2tlciBydW4gLS1ybSAtdiAke3BhdGhfcGFyZW50fTovdm9sdW1lIGRlYmlhbiBiYXNoIC1j"\
|
|
||||||
"ICJybSAtcmYgL3ZvbHVtZS8ke3BhdGhfY2hpbGR9IiB8fCBlY2hvICJGYWlsZWQgdG8gbnVrZSBw"\
|
|
||||||
"YXRoICR7cGF0aH0iCiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGVjaG8gIlBhdGgg"\
|
|
||||||
"JHtwYXRofSBkb2VzIG5vdCBleGlzdCAtIG5vdGhpbmcgdG8gbnVrZSIKICAgICAgICAgICAgZmkK"\
|
|
||||||
"ICAgICAgICAgICAgOzsKICAgICAgICBiYWNrdXApCiAgICAgICAgICAgIGVjaG8gIkJhY2tpbmcg"\
|
|
||||||
"dXAgcGF0aCAke3BhdGh9IgogICAgICAgICAgICBpZiBbIC1kICIke3BhdGh9IiBdOyB0aGVuCiAg"\
|
|
||||||
"ICAgICAgICAgICAgICBkb2NrZXIgcnVuIC0tcm0gLXYgJHtwYXRofTovcGF0aCAtdiAke2JhY2t1"\
|
|
||||||
"cF9mb2xkZXJ9Oi9iYWNrdXAgZGViaWFuIGJhc2ggLWMgInRhciAtY3p2ZiAvYmFja3VwL2JhY2t1"\
|
|
||||||
"cC50Z3ogLUMgL3BhdGggLiAmJiBjaG93biAtUiAkTVlJRDokTVlHUlAgL2JhY2t1cCIKICAgICAg"\
|
|
||||||
"ICAgICAgZWxzZQogICAgICAgICAgICAgICAgZWNobyAiUGF0aCAke3BhdGh9IGRvZXMgbm90IGV4"\
|
|
||||||
"aXN0IC0gbm90aGluZyB0byBiYWNrdXAiCiAgICAgICAgICAgIGZpCiAgICAgICAgICAgIDs7CiAg"\
|
|
||||||
"ICAgICAgcmVzdG9yZSkKICAgICAgICAgICAgZWNobyAiUmVzdG9yaW5nIHBhdGggJHtwYXRofSIK"\
|
|
||||||
"ICAgICAgICAgICAgdGFyIC14enZmICR7YmFja3VwX2ZvbGRlcn0vYmFja3VwLnRneiAtQyAke3Bh"\
|
|
||||||
"dGh9IC0tc3RyaXAtY29tcG9uZW50cz0xCiAgICAgICAgICAgIDs7CiAgICBlc2FjCn0KCl9hdXRv"\
|
|
||||||
"Y29tbWFuZHJ1bl9maWxlKCkgewogICAgbG9jYWwgY29tbWFuZD0iJDEiCiAgICBsb2NhbCBmaWxl"\
|
|
||||||
"cGF0aD0iJDIiCiAgICBsb2NhbCBiYWNrdXBfZm9sZGVyPSIkMyIKCiAgICBjYXNlICIkY29tbWFu"\
|
|
||||||
"ZCIgaW4KICAgICAgICBjcmVhdGUpCiAgICAgICAgICAgIDs7CiAgICAgICAgbnVrZSkKICAgICAg"\
|
|
||||||
"ICAgICAgcm0gLWYgJHtmaWxlcGF0aH0KICAgICAgICAgICAgOzsKICAgICAgICBiYWNrdXApCiAg"\
|
|
||||||
"ICAgICAgICAgIGVjaG8gIkJhY2tpbmcgdXAgZmlsZSAke2ZpbGVwYXRofSIKICAgICAgICAgICAg"\
|
|
||||||
"bG9jYWwgZmlsZV9wYXJlbnQ9JChkaXJuYW1lICR7ZmlsZXBhdGh9KQogICAgICAgICAgICBsb2Nh"\
|
|
||||||
"bCBmaWxlX25hbWU9JChiYXNlbmFtZSAke2ZpbGVwYXRofSkKICAgICAgICAgICAgaWYgWyAtZiAi"\
|
|
||||||
"JHtmaWxlX3BhcmVudH0vJHtmaWxlX25hbWV9IiBdOyB0aGVuCiAgICAgICAgICAgICAgICBkb2Nr"\
|
|
||||||
"ZXIgcnVuIC0tcm0gLXYgJHtmaWxlX3BhcmVudH06L3ZvbHVtZSAtdiAke2JhY2t1cF9mb2xkZXJ9"\
|
|
||||||
"Oi9iYWNrdXAgZGViaWFuIGJhc2ggLWMgImNwIC92b2x1bWUvJHtmaWxlX25hbWV9IC9iYWNrdXAv"\
|
|
||||||
"JHtmaWxlX25hbWV9ICYmIGNob3duIC1SICRNWUlEOiRNWUdSUCAvYmFja3VwIgogICAgICAgICAg"\
|
|
||||||
"ICBlbHNlCiAgICAgICAgICAgICAgICBlY2hvICJGaWxlICR7ZmlsZXBhdGh9IGRvZXMgbm90IGV4"\
|
|
||||||
"aXN0IC0gbm90aGluZyB0byBiYWNrdXAiCiAgICAgICAgICAgIGZpCiAgICAgICAgICAgIDs7CiAg"\
|
|
||||||
"ICAgICAgcmVzdG9yZSkKICAgICAgICAgICAgZWNobyAiUmVzdG9yaW5nIGZpbGUgJHtmaWxlcGF0"\
|
|
||||||
"aH0iCiAgICAgICAgICAgIGxvY2FsIGZpbGVfbmFtZT0kKGJhc2VuYW1lICR7ZmlsZXBhdGh9KQog"\
|
|
||||||
"ICAgICAgICAgICBjcCAke2JhY2t1cF9mb2xkZXJ9LyR7ZmlsZV9uYW1lfSAke2ZpbGVwYXRofQog"\
|
|
||||||
"ICAgICAgICAgICA7OwogICAgZXNhYwp9CgpfYXV0b2NvbW1hbmRwYXJzZSgpIHsKICAgICMgZmly"\
|
|
||||||
"c3QgYXJndW1lbnQgaXMgdGhlIGNvbW1hbmQKICAgICMgaWYgdGhlIGNvbW1hbmQgaXMgYmFja3Vw"\
|
|
||||||
"IG9yIHJlc3RvcmUsIHRoZW4gdGhlIGxhc3QgdHdvIGFyZ3VtZW50cyBhcmUgdGhlIGJhY2t1cCBm"\
|
|
||||||
"aWxlIGFuZCB0aGUgdGVtcG9yYXJ5IHBhdGgKICAgICMgYWxsIG90aGVyIGFyZ3VtZW50cyBhcmUg"\
|
|
||||||
"b2YgZm9ybToKICAgICMga2V5PXZhbHVlCiAgICAjIHdoZXJlIGtleSBjYW4gYmUgb25lIG9mIHZv"\
|
|
||||||
"bHVtZSwgcGF0aCBvciBmaWxlLgogICAgIyB2YWx1ZSBpcyB0aGUgcGF0aCBvciB2b2x1bWUgbmFt"\
|
|
||||||
"ZS4KCiAgICAjIHdlIGl0ZXJhdGUgb3ZlciB0aGUga2V5PXZhbHVlIGFyZ3VtZW50cywgYW5kIGZv"\
|
|
||||||
"ciBlYWNoIHdlIGNhbGw6CiAgICAjICAgIGF1dG9ydW4gPGNvbW1hbmQ+IDxiYWNrdXBmaWxlPiA8"\
|
|
||||||
"a2V5PiA8dmFsdWU+CgogICAgbG9jYWwgY29tbWFuZD0iJDEiCiAgICBzaGlmdAoKICAgIGxvY2Fs"\
|
|
||||||
"IGJhY2t1cF90ZW1wX3BhdGg9IiQxIgogICAgc2hpZnQKCiAgICBlY2hvICJhdXRvY29tbWFuZHBh"\
|
|
||||||
"cnNlOiBjb21tYW5kPSRjb21tYW5kIGJhY2t1cF90ZW1wX3BhdGg9JGJhY2t1cF90ZW1wX3BhdGgi"\
|
|
||||||
"CgogICAgIyBFeHRyYWN0IHRoZSBiYWNrdXAgZmlsZSBhbmQgdGVtcCBwYXRoIChsYXN0IHR3byBh"\
|
|
||||||
"cmd1bWVudHMpCiAgICBsb2NhbCBhcmdzPSgiJEAiKQogICAgbG9jYWwgYXJnX2NvdW50PSR7I2Fy"\
|
|
||||||
"Z3NbQF19CiAgICAKICAgICMgUHJvY2VzcyBhbGwga2V5PXZhbHVlIHBhaXJzCiAgICBmb3IgKChp"\
|
|
||||||
"PTA7IGk8JGFyZ19jb3VudDsgaSsrKSk7IGRvCiAgICAgICAgbG9jYWwgcGFpcj0iJHthcmdzWyRp"\
|
|
||||||
"XX0iCiAgICAgICAgCiAgICAgICAgIyBTa2lwIGlmIG5vdCBpbiBrZXk9dmFsdWUgZm9ybWF0CiAg"\
|
|
||||||
"ICAgICAgaWYgW1sgIiRwYWlyIiAhPSAqIj0iKiBdXTsgdGhlbgogICAgICAgICAgICBjb250aW51"\
|
|
||||||
"ZQogICAgICAgIGZpCiAgICAgICAgCiAgICAgICAgbG9jYWwga2V5PSIke3BhaXIlJT0qfSIKICAg"\
|
|
||||||
"ICAgICBsb2NhbCB2YWx1ZT0iJHtwYWlyIyo9fSIKCiAgICAgICAgIyBjcmVhdGUgYmFja3VwIGZv"\
|
|
||||||
"bGRlciB1bmlxdWUgdG8ga2V5L3ZhbHVlLgogICAgICAgIGxvY2FsIGJmb2xkZXI9JChlY2hvICIk"\
|
|
||||||
"e2tleX1fJHt2YWx1ZX0iIHwgdHIgLWNkICdbOmFsbnVtOl1fLScpCiAgICAgICAgbG9jYWwgdGFy"\
|
|
||||||
"Z2V0cGF0aD0iJHtiYWNrdXBfdGVtcF9wYXRofS8ke2Jmb2xkZXJ9IgogICAgICAgIG1rZGlyIC1w"\
|
|
||||||
"ICR7dGFyZ2V0cGF0aH0KCiAgICAgICAgIyBLZXkgbXVzdCBiZSBvbmUgb2Ygdm9sdW1lLCBwYXRo"\
|
|
||||||
"IG9yIGZpbGUKICAgICAgICBjYXNlICIka2V5IiBpbgogICAgICAgICAgICB2b2x1bWUpCiAgICAg"\
|
|
||||||
"ICAgICAgICAgICBfYXV0b2NvbW1hbmRydW5fdm9sdW1lICIkY29tbWFuZCIgIiR2YWx1ZSIgIiR0"\
|
|
||||||
"YXJnZXRwYXRoIgogICAgICAgICAgICAgICAgOzsKICAgICAgICAgICAgcGF0aCkKICAgICAgICAg"\
|
|
||||||
"ICAgICAgIF9hdXRvY29tbWFuZHJ1bl9wYXRoICIkY29tbWFuZCIgIiR2YWx1ZSIgIiR0YXJnZXRw"\
|
|
||||||
"YXRoIgogICAgICAgICAgICAgICAgOzsKICAgICAgICAgICAgZmlsZSkKICAgICAgICAgICAgICAg"\
|
|
||||||
"IF9hdXRvY29tbWFuZHJ1bl9maWxlICIkY29tbWFuZCIgIiR2YWx1ZSIgIiR0YXJnZXRwYXRoIgog"\
|
|
||||||
"ICAgICAgICAgICAgICAgOzsKICAgICAgICAgICAgKikKICAgICAgICAgICAgICAgIF9kaWUgIlVu"\
|
|
||||||
"a25vd24ga2V5ICRrZXkgcGFzc2VkIHRvIGF1dG8ke2NvbW1hbmR9LiBXZSBvbmx5IHN1cHBvcnQg"\
|
|
||||||
"dm9sdW1lLCBwYXRoIGFuZCBmaWxlLiIKICAgICAgICAgICAgICAgIDs7CiAgICAgICAgZXNhYwog"\
|
|
||||||
"ICAgZG9uZQp9CgoKZGF0YWNyZWF0ZSgpIHsKICAgIF9hdXRvY29tbWFuZHBhcnNlIGNyZWF0ZSBu"\
|
|
||||||
"b25lICIkQCIKfQoKCmRhdGFudWtlKCkgewogICAgX2F1dG9jb21tYW5kcGFyc2UgbnVrZSBub25l"\
|
|
||||||
"ICIkQCIKfQoKZGF0YWJhY2t1cCgpIHsKICAgIF9jaGVja19yZXF1aXJlZF9lbnZfdmFycyAiQkFD"\
|
|
||||||
"S1VQX0ZJTEUiICJURU1QX0RJUiIKICAgIEJBQ0tVUF9URU1QX1BBVEg9IiRURU1QX0RJUi9iYWNr"\
|
|
||||||
"dXAiCgoKICAgIG1rZGlyIC1wICIkQkFDS1VQX1RFTVBfUEFUSCIKICAgIGVjaG8gIl9hdXRvY29t"\
|
|
||||||
"bWFuZHBhcnNlIFtiYWNrdXBdIFskQkFDS1VQX1RFTVBfUEFUSF0gWyRAXSIKICAgIF9hdXRvY29t"\
|
|
||||||
"bWFuZHBhcnNlIGJhY2t1cCAiJEJBQ0tVUF9URU1QX1BBVEgiICIkQCIKCiAgICB0YXIgemN2ZiAi"\
|
|
||||||
"JEJBQ0tVUF9GSUxFIiAtQyAiJEJBQ0tVUF9URU1QX1BBVEgiIC4KfQoKZGF0YXJlc3RvcmUoKSB7"\
|
|
||||||
"CiAgICBfY2hlY2tfcmVxdWlyZWRfZW52X3ZhcnMgIkJBQ0tVUF9GSUxFIiAiVEVNUF9ESVIiCiAg"\
|
|
||||||
"ICBCQUNLVVBfVEVNUF9QQVRIPSIkVEVNUF9ESVIvcmVzdG9yZSIKCiAgICBlY2hvICJfYXV0b2Nv"\
|
|
||||||
"bW1hbmRwYXJzZSBbcmVzdG9yZV0gWyRCQUNLVVBfVEVNUF9QQVRIXSBbJEBdIgoKICAgIG1rZGly"\
|
|
||||||
"IC1wICIkQkFDS1VQX1RFTVBfUEFUSCIKICAgIHRhciB6eHZmICIkQkFDS1VQX0ZJTEUiIC1DICIk"\
|
|
||||||
"QkFDS1VQX1RFTVBfUEFUSCIgLS1zdHJpcC1jb21wb25lbnRzPTEKCiAgICBfYXV0b2NvbW1hbmRw"\
|
|
||||||
"YXJzZSByZXN0b3JlICIkQkFDS1VQX1RFTVBfUEFUSCIgIiRAIgp9Cg==";
|
|
||||||
|
|
||||||
// Decode Base64 data
|
|
||||||
size_t decoded_size = (strlen(filedata_base64) * 3) / 4;
|
|
||||||
unsigned char* decoded_data = new unsigned char[decoded_size];
|
|
||||||
size_t actual_size;
|
|
||||||
base64_decode(filedata_base64, strlen(filedata_base64), decoded_data, &actual_size);
|
|
||||||
|
|
||||||
bool file_written = _recreate_file_(outpath, 6443138635497166205ULL, std::filesystem::perms(493), decoded_data, actual_size);
|
|
||||||
delete[] decoded_data;
|
|
||||||
any_written = any_written || file_written;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
// File: _allservicesstatus.sh
|
|
||||||
fs::path outpath = fs::path(destination_folder) / "_allservicesstatus.sh";
|
|
||||||
static const char filedata_base64[] = "IyEvYmluL2Jhc2gKCiMgVGhpcyBzY3JpcHQgY2hlY2tzIEFMTCBzZXJ2aWNlcyBvbiB0aGUgc2Vy"\
|
|
||||||
"dmVyIGFuZCByZXR1cm5zIGEgc3RhdHVzIGZvciBlYWNoLgoKIyBSZXR1cm4gZm9ybWF0IGlzIHNp"\
|
|
||||||
"bXBsZSBFTlYgd2l0aCB0aGUgZm9sbG93aW5nIGZvcm1hdDoKIyBTRVJWSUNFX05BTUVfSEVBTFRI"\
|
|
||||||
"PWhlYWx0aHl8dW5oZWFsdGh5fHVua25vd24KIyBTRVJWSUNFX05BTUVfUE9SVFM9cG9ydDEscG9y"\
|
|
||||||
"dDIscG9ydDMKCiMgR2V0IGFsbCBzZXJ2aWNlcyBvbiB0aGUgc2VydmVyClNDUklQVF9ESVI9IiQo"\
|
|
||||||
"ZGlybmFtZSAiJDAiKSIKCiAgICAjIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t"\
|
|
||||||
"LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t"\
|
|
||||||
"LS0tLS0tCiAgICAjIC8vIHJlbW90ZSBwYXRocwogICAgIyAvLyBEUk9QU0hFTExfRElSCiAgICAj"\
|
|
||||||
"IC8vICAgfC0tIGJhY2t1cHMKICAgICMgLy8gICB8LS0gdGVtcF9maWxlcwogICAgIyAvLyAgIHwt"\
|
|
||||||
"LSBhZ2VudAogICAgIyAvLyAgIHwgICB8LS0gYmI2NAogICAgIyAvLyAgIHwgICB8LS0gKG90aGVy"\
|
|
||||||
"IGFnZW50IGZpbGVzLCBpbmNsdWRpbmcgX2FsbHNlcnZpY2Vzc3RhdHVzLnNoKQogICAgIyAvLyAg"\
|
|
||||||
"IHwtLSBzZXJ2aWNlcwogICAgIyAvLyAgICAgICB8LS0gc2VydmljZSBuYW1lCiAgICAjIC8vICAg"\
|
|
||||||
"ICAgICAgICB8LS0gY29uZmlnCiAgICAjIC8vICAgICAgICAgICAgICAgfC0tIHNlcnZpY2UuZW52"\
|
|
||||||
"IChhY3R1YWwgc2VydmljZSBjb25maWcpCiAgICAjIC8vICAgICAgICAgICAgICAgfC0tIC50ZW1w"\
|
|
||||||
"bGF0ZV9pbmZvLmVudgogICAgIyAvLyAgICAgICAgICAgfC0tIHRlbXBsYXRlCiAgICAjIC8vICAg"\
|
|
||||||
"ICAgICAgICAgICAgfC0tIF9kZWZhdWx0LmVudgogICAgIyAvLyAgICAgICAgICAgICAgIHwtLSAo"\
|
|
||||||
"c2NyaXB0IGZpbGVzKQogICAgIyAvLyAgICAgICAgICAgICAgIHwtLSBjb25maWcKICAgICMgLy8g"\
|
|
||||||
"ICAgICAgICAgICAgICAgICAgfC0tIHNlcnZpY2UuZW52IChkZWZhdWx0IHNlcnZpY2UgY29uZmln"\
|
|
||||||
"KQogICAgIyAvLyAgICAgICAgICAgICAgICAgICB8LS0gLnRlbXBsYXRlX2luZm8uZW52CiAgICAj"\
|
|
||||||
"IC8vICAgICAgICAgICAgICAgICAgIHwtLSAob3RoZXIgY29uZmlnIGZpbGVzIGZvciBzcGVjaWZp"\
|
|
||||||
"YyBzZXJ2ZXImc2VydmljZSkKCiMgR2V0IGFsbCBzZXJ2aWNlcyBvbiB0aGUgc2VydmVyClNFUlZJ"\
|
|
||||||
"Q0VTX1BBVEg9JChyZWFscGF0aCAiJHtTQ1JJUFRfRElSfS8uLi9zZXJ2aWNlcy8iKQoKQ1VSUkVO"\
|
|
||||||
"VF9PVVRQVVQ9IiIKQ1VSUkVOVF9FWElUX0NPREU9MAoKbG9hZF9kb3RlbnYoKXsKICAgIGxvY2Fs"\
|
|
||||||
"IGZpbGVfcGF0aD0kMQogICAgaWYgWyAtZiAiJHtmaWxlX3BhdGh9IiBdOyB0aGVuCiAgICAgICAg"\
|
|
||||||
"c291cmNlICIke2ZpbGVfcGF0aH0iCiAgICBmaQp9CgpfY2hlY2tfcmVxdWlyZWRfZW52X3ZhcnNf"\
|
|
||||||
"YWxsc2VydmljZXNzdGF0dXMoKSB7CiAgICBsb2NhbCByZXF1aXJlZF92YXJzPSgiJEAiKQogICAg"\
|
|
||||||
"Zm9yIHZhciBpbiAiJHtyZXF1aXJlZF92YXJzW0BdfSI7IGRvCiAgICAgICAgaWYgWyAteiAiJHsh"\
|
|
||||||
"dmFyfSIgXTsgdGhlbgogICAgICAgICAgICBfZGllICJSZXF1aXJlZCBlbnZpcm9ubWVudCB2YXJp"\
|
|
||||||
"YWJsZSAkdmFyIGlzIG5vdCBzZXQiCiAgICAgICAgZmkKICAgIGRvbmUKfQoKZnVuY3Rpb24gcnVu"\
|
|
||||||
"X2NvbW1hbmQoKSB7CiAgICBsb2NhbCBzZXJ2aWNlX3BhdGg9JDEKICAgIGxvY2FsIGNvbW1hbmQ9"\
|
|
||||||
"JDIKICAgIGxvY2FsIGNhcHR1cmVfb3V0cHV0PSR7MzotZmFsc2V9ICAjIGRlZmF1bHQgdG8gZmFs"\
|
|
||||||
"c2UgaWYgbm90IHNwZWNpZmllZAoKICAgICMgY2hlY2sgaWYgdGhlIGNvbW1hbmQgaXMgYSBmaWxl"\
|
|
||||||
"CiAgICBpZiBbICEgLWYgIiR7c2VydmljZV9wYXRofS90ZW1wbGF0ZS8ke2NvbW1hbmR9LnNoIiBd"\
|
|
||||||
"OyB0aGVuCiAgICAgICAgcmV0dXJuOwogICAgZmkKCiAgICAjIHJ1biB0aGUgY29tbWFuZCBpbiBh"\
|
|
||||||
"IHN1YnNoZWxsIHRvIHByZXZlbnQgZW52aXJvbm1lbnQgY2hhbmdlcwogICAgQ1VSUkVOVF9PVVRQ"\
|
|
||||||
"VVQ9JCgKICAgICAgICBzZXQgLWEKCiAgICAgICAgbG9hZF9kb3RlbnYgIiR7c2VydmljZV9wYXRo"\
|
|
||||||
"fS90ZW1wbGF0ZS9fZGVmYXVsdC5lbnYiCiAgICAgICAgbG9hZF9kb3RlbnYgIiR7c2VydmljZV9w"\
|
|
||||||
"YXRofS9jb25maWcvc2VydmljZS5lbnYiCiAgICAgICAgbG9hZF9kb3RlbnYgIiR7c2VydmljZV9w"\
|
|
||||||
"YXRofS9jb25maWcvLnRlbXBsYXRlX2luZm8uZW52IgoKICAgICAgICAjIHVwZGF0ZSB0aGUgbWFp"\
|
|
||||||
"biB2YXJpYWJsZXMuCiAgICAgICAgQ09ORklHX1BBVEg9IiR7c2VydmljZV9wYXRofS9jb25maWci"\
|
|
||||||
"CiAgICAgICAgU0VSVklDRT0iJHtTRVJWSUNFX05BTUV9IgogICAgICAgIERPQ0tFUl9DTElfSElO"\
|
|
||||||
"VFM9ZmFsc2UKCiAgICAgICAgc2V0ICthCgogICAgICAgIF9jaGVja19yZXF1aXJlZF9lbnZfdmFy"\
|
|
||||||
"c19hbGxzZXJ2aWNlc3N0YXR1cyAiQ09ORklHX1BBVEgiICJTRVJWRVIiICJTRVJWSUNFIiAiQUdF"\
|
|
||||||
"TlRfUEFUSCIgIkhPU1RfTkFNRSIgIlRFTVBMQVRFIgoKICAgICAgICBpZiBbICIkY2FwdHVyZV9v"\
|
|
||||||
"dXRwdXQiID0gInRydWUiIF07IHRoZW4KICAgICAgICAgICAgIyBDYXB0dXJlIGFuZCByZXR1cm4g"\
|
|
||||||
"b3V0cHV0CiAgICAgICAgICAgIGJhc2ggIiR7c2VydmljZV9wYXRofS90ZW1wbGF0ZS8ke2NvbW1h"\
|
|
||||||
"bmR9LnNoIiAyPiYxCiAgICAgICAgZWxzZQogICAgICAgICAgICAjIFJ1biBzaWxlbnRseSBhbmQg"\
|
|
||||||
"cmV0dXJuIGV4aXQgY29kZQogICAgICAgICAgICBiYXNoICIke3NlcnZpY2VfcGF0aH0vdGVtcGxh"\
|
|
||||||
"dGUvJHtjb21tYW5kfS5zaCIgPiAvZGV2L251bGwgMj4mMQogICAgICAgIGZpCiAgICApCiAgICBD"\
|
|
||||||
"VVJSRU5UX0VYSVRfQ09ERT0kPwp9CgpmdW5jdGlvbiBjb21tYW5kX2V4aXN0cygpIHsKICAgIGxv"\
|
|
||||||
"Y2FsIHNlcnZpY2VfcGF0aD0kMQogICAgbG9jYWwgY29tbWFuZD0kMgogICAgaWYgWyAhIC1mICIk"\
|
|
||||||
"e3NlcnZpY2VfcGF0aH0vdGVtcGxhdGUvJHtjb21tYW5kfS5zaCIgXTsgdGhlbgogICAgICAgIHJl"\
|
|
||||||
"dHVybiAxCiAgICBmaQogICAgcmV0dXJuIDAKfQoKCmlmIFsgISAtZCAiJHtTRVJWSUNFU19QQVRI"\
|
|
||||||
"fSIgXTsgdGhlbgogICAgZWNobyAiU2VydmljZXMgcGF0aCBkb2VzIG5vdCBleGlzdDogJHtTRVJW"\
|
|
||||||
"SUNFU19QQVRIfSIKICAgIGV4aXQgMApmaQoKIyBHZXQgYWxsIHNlcnZpY2UgbmFtZXMKU0VSVklD"\
|
|
||||||
"RV9OQU1FUz0kKGxzICIke1NFUlZJQ0VTX1BBVEh9IikKCiMgSXRlcmF0ZSBvdmVyIGFsbCBzZXJ2"\
|
|
||||||
"aWNlIG5hbWVzCmZvciBTRVJWSUNFX05BTUUgaW4gJHtTRVJWSUNFX05BTUVTfTsgZG8KCiAgICBT"\
|
|
||||||
"RVJWSUNFX1BBVEg9JChyZWFscGF0aCAiJHtTRVJWSUNFU19QQVRIfS8ke1NFUlZJQ0VfTkFNRX0i"\
|
|
||||||
"KQoKICAgICMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgIyBHZXQgdGhlIHNl"\
|
|
||||||
"cnZpY2UgaGVhbHRoCiAgICBpZiAhIGNvbW1hbmRfZXhpc3RzICIke1NFUlZJQ0VfUEFUSH0iICJz"\
|
|
||||||
"dGF0dXMiOyB0aGVuCiAgICAgICAgU0VSVklDRV9IRUFMVEg9InVua25vd24iCiAgICBlbHNlCiAg"\
|
|
||||||
"ICAgICAgcnVuX2NvbW1hbmQgIiR7U0VSVklDRV9QQVRIfSIgInN0YXR1cyIgImZhbHNlIgogICAg"\
|
|
||||||
"ICAgIGlmIFsgIiR7Q1VSUkVOVF9FWElUX0NPREV9IiAtZXEgMCBdOyB0aGVuCiAgICAgICAgICAg"\
|
|
||||||
"IFNFUlZJQ0VfSEVBTFRIPSJoZWFsdGh5IgogICAgICAgIGVsc2UKICAgICAgICAgICAgU0VSVklD"\
|
|
||||||
"RV9IRUFMVEg9InVuaGVhbHRoeSIKICAgICAgICBmaQogICAgZmkKCiAgICAjLS0tLS0tLS0tLS0t"\
|
|
||||||
"LS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICMgR2V0IHRoZSBzZXJ2aWNlIHBvcnRzCiAgICBpZiAh"\
|
|
||||||
"IGNvbW1hbmRfZXhpc3RzICIke1NFUlZJQ0VfUEFUSH0iICJwb3J0cyI7IHRoZW4KICAgICAgICBT"\
|
|
||||||
"RVJWSUNFX1BPUlRTPSIiCiAgICBlbHNlCiAgICAgICAgcnVuX2NvbW1hbmQgIiR7U0VSVklDRV9Q"\
|
|
||||||
"QVRIfSIgInBvcnRzIiAidHJ1ZSIKICAgICAgICBTRVJWSUNFX1BPUlRTPSIke0NVUlJFTlRfT1VU"\
|
|
||||||
"UFVUfSIKICAgIGZpCgogICAgIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAj"\
|
|
||||||
"IHJldHVybiB0aGUgaGVhbHRoIGFuZCBwb3J0cwogICAgZWNobyAiJHtTRVJWSUNFX05BTUV9X0hF"\
|
|
||||||
"QUxUSD0ke1NFUlZJQ0VfSEVBTFRIfSIKICAgIGVjaG8gIiR7U0VSVklDRV9OQU1FfV9QT1JUUz0k"\
|
|
||||||
"e1NFUlZJQ0VfUE9SVFN9Igpkb25lCg==";
|
|
||||||
|
|
||||||
// Decode Base64 data
|
|
||||||
size_t decoded_size = (strlen(filedata_base64) * 3) / 4;
|
|
||||||
unsigned char* decoded_data = new unsigned char[decoded_size];
|
|
||||||
size_t actual_size;
|
|
||||||
base64_decode(filedata_base64, strlen(filedata_base64), decoded_data, &actual_size);
|
|
||||||
|
|
||||||
bool file_written = _recreate_file_(outpath, 4669115953916396805ULL, std::filesystem::perms(493), decoded_data, actual_size);
|
|
||||||
delete[] decoded_data;
|
|
||||||
any_written = any_written || file_written;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
// File: common.sh
|
|
||||||
fs::path outpath = fs::path(destination_folder) / "common.sh";
|
|
||||||
static const char filedata_base64[] = "IyBDT01NT04gRlVOQ1RJT05TCiMgSkRFCiMgMjAyNS0wNS0wMwoKIyBUaGlzIGZpbGUgaXMgYXZh"\
|
|
||||||
"aWxhYmxlIFRPICoqKkFMTCoqKiB0ZW1wbGF0ZXMsIGFzICR7QUdFTlRfUEFUSH0vX2NvbW1vbi5z"\
|
|
||||||
"aAoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t"\
|
|
||||||
"LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgoj"\
|
|
||||||
"IHN1bW1hcnkgb2YgZnVuY3Rpb25zOgojICAgX2RpZSAibWVzc2FnZSIgICAgICAgICAgICAgICAg"\
|
|
||||||
"ICAgICAgICAgOiBQcmludHMgYW4gZXJyb3IgbWVzc2FnZSBpbiByZWQgYW5kIGV4aXRzIHdpdGgg"\
|
|
||||||
"c3RhdHVzIGNvZGUgMS4KIyAgIF9ncmV5X3N0YXJ0ICAgICAgICAgICAgICAgICAgICAgICAgICAg"\
|
|
||||||
"IDogU3dpdGNoZXMgdGVybWluYWwgb3V0cHV0IGNvbG9yIHRvIGdyZXkuCiMgICBfZ3JleV9lbmQg"\
|
|
||||||
"ICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IFJlc2V0cyB0ZXJtaW5hbCBvdXRwdXQgY29s"\
|
|
||||||
"b3IgZnJvbSBncmV5LgojICAgX2NyZWF0ZV9hbmRfc3RhcnRfY29udGFpbmVyICI8cnVuX2NtZD4i"\
|
|
||||||
"IDxjb250YWluZXJfbmFtZT4gOiBDcmVhdGVzL3N0YXJ0cyBhIGNvbnRhaW5lciwgdmVyaWZ5aW5n"\
|
|
||||||
"IGl0IHJ1bnMuCiMgICBfY3JlYXRlX2ZvbGRlciA8Zm9sZGVyX3BhdGg+ICAgICAgICAgICA6IENy"\
|
|
||||||
"ZWF0ZXMgYSBkaXJlY3RvcnkgaWYgaXQgZG9lc24ndCBleGlzdCAoY2htb2QgNzc3KS4KIyAgIF9j"\
|
|
||||||
"aGVja19kb2NrZXJfaW5zdGFsbGVkICAgICAgICAgICAgICAgOiBDaGVja3MgaWYgRG9ja2VyIGlz"\
|
|
||||||
"IGluc3RhbGxlZCwgcnVubmluZywgYW5kIHVzZXIgaGFzIHBlcm1pc3Npb24uIFJldHVybnMgMSBv"\
|
|
||||||
"biBmYWlsdXJlLgojICAgX2lzX2NvbnRhaW5lcl9leGlzdHMgPGNvbnRhaW5lcl9uYW1lPiA6IENo"\
|
|
||||||
"ZWNrcyBpZiBhIGNvbnRhaW5lciAoYW55IHN0YXRlKSBleGlzdHMuIFJldHVybnMgMSBpZiBub3Qg"\
|
|
||||||
"Zm91bmQuCiMgICBfaXNfY29udGFpbmVyX3J1bm5pbmcgPGNvbnRhaW5lcl9uYW1lPjogQ2hlY2tz"\
|
|
||||||
"IGlmIGEgY29udGFpbmVyIGlzIGN1cnJlbnRseSBydW5uaW5nLiBSZXR1cm5zIDEgaWYgbm90IHJ1"\
|
|
||||||
"bm5pbmcuCiMgICBfZ2V0X2NvbnRhaW5lcl9pZCA8Y29udGFpbmVyX25hbWU+ICAgIDogUHJpbnRz"\
|
|
||||||
"IHRoZSBJRCBvZiB0aGUgbmFtZWQgY29udGFpbmVyLgojICAgX2dldF9jb250YWluZXJfc3RhdHVz"\
|
|
||||||
"IDxjb250YWluZXJfbmFtZT46IFByaW50cyB0aGUgc3RhdHVzIHN0cmluZyBvZiB0aGUgbmFtZWQg"\
|
|
||||||
"Y29udGFpbmVyLgojICAgX3N0YXJ0X2NvbnRhaW5lciA8Y29udGFpbmVyX25hbWU+ICAgICA6IFN0"\
|
|
||||||
"YXJ0cyBhbiBleGlzdGluZywgc3RvcHBlZCBjb250YWluZXIuCiMgICBfc3RvcF9jb250YWluZXIg"\
|
|
||||||
"PGNvbnRhaW5lcl9uYW1lPiAgICAgIDogU3RvcHMgYSBydW5uaW5nIGNvbnRhaW5lci4KIyAgIF9y"\
|
|
||||||
"ZW1vdmVfY29udGFpbmVyIDxjb250YWluZXJfbmFtZT4gICAgOiBTdG9wcyAoaWYgbmVlZGVkKSBh"\
|
|
||||||
"bmQgcmVtb3ZlcyBhIGNvbnRhaW5lci4KIyAgIF9nZXRfY29udGFpbmVyX2xvZ3MgPGNvbnRhaW5l"\
|
|
||||||
"cl9uYW1lPiAgOiBQcmludHMgdGhlIGxvZ3MgZm9yIGEgY29udGFpbmVyLgojICAgX2NoZWNrX3Jl"\
|
|
||||||
"cXVpcmVkX2Vudl92YXJzICJWQVIxIiAuLi4gICAgOiBDaGVja3MgaWYgbGlzdGVkIGVudmlyb25t"\
|
|
||||||
"ZW50IHZhcmlhYmxlcyBhcmUgc2V0OyBjYWxscyBfZGllKCkgaWYgYW55IGFyZSBtaXNzaW5nLgoj"\
|
|
||||||
"ICAgX3Jvb3RfcmVtb3ZlX3RyZWUgPHBhdGg+ICAgICAgICAgICAgICA6IFJlbW92ZXMgYSBwYXRo"\
|
|
||||||
"IHVzaW5nIGEgcm9vdCBEb2NrZXIgY29udGFpbmVyIChmb3IgcGVybWlzc2lvbnMpLgoKIyAtLS0t"\
|
|
||||||
"LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t"\
|
|
||||||
"LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIFByaW50cyBh"\
|
|
||||||
"biBlcnJvciBtZXNzYWdlIGluIHJlZCBhbmQgZXhpdHMgd2l0aCBzdGF0dXMgY29kZSAxLgpfZGll"\
|
|
||||||
"KCkgewogICAgZWNobyAtZSAiRXJyb3I6ICQxIgogICAgZXhpdCAxCn0KCiMgQ3JlYXRlcy9zdGFy"\
|
|
||||||
"dHMgYSBjb250YWluZXIsIHZlcmlmeWluZyBpdCBydW5zLgpfY3JlYXRlX2FuZF9zdGFydF9jb250"\
|
|
||||||
"YWluZXIoKSB7CiAgICBpZiBbIC16ICIkMSIgXSB8fCBbIC16ICIkMiIgXTsgdGhlbgogICAgICAg"\
|
|
||||||
"IF9kaWUgIlRlbXBsYXRlIGVycm9yOiBjcmVhdGVfYW5kX3N0YXJ0X2NvbnRhaW5lciA8cnVuX2Nt"\
|
|
||||||
"ZD4gPGNvbnRhaW5lcl9uYW1lPiIKICAgIGZpCgogICAgbG9jYWwgcnVuX2NtZD0iJDEiCiAgICBs"\
|
|
||||||
"b2NhbCBjb250YWluZXJfbmFtZT0iJDIiCgogICAgaWYgX2lzX2NvbnRhaW5lcl9leGlzdHMgJGNv"\
|
|
||||||
"bnRhaW5lcl9uYW1lOyB0aGVuCiAgICAgICAgX2lzX2NvbnRhaW5lcl9ydW5uaW5nICRjb250YWlu"\
|
|
||||||
"ZXJfbmFtZSAmJiByZXR1cm4gMAogICAgICAgIF9zdGFydF9jb250YWluZXIgJGNvbnRhaW5lcl9u"\
|
|
||||||
"YW1lCiAgICBlbHNlCiAgICAgICAgJHJ1bl9jbWQKICAgIGZpCgogICAgaWYgISBfaXNfY29udGFp"\
|
|
||||||
"bmVyX3J1bm5pbmcgJGNvbnRhaW5lcl9uYW1lOyB0aGVuCiAgICAgICAgX2RpZSAiQ29udGFpbmVy"\
|
|
||||||
"ICR7Y29udGFpbmVyX25hbWV9IGZhaWxlZCB0byBzdGFydCIKICAgIGZpCgogICAgSUQ9JChfZ2V0"\
|
|
||||||
"X2NvbnRhaW5lcl9pZCAkY29udGFpbmVyX25hbWUpCiAgICBlY2hvICJDb250YWluZXIgJHtjb250"\
|
|
||||||
"YWluZXJfbmFtZX0gaXMgcnVubmluZyB3aXRoIElEICR7SUR9Igp9CgojIENyZWF0ZXMgYSBkaXJl"\
|
|
||||||
"Y3RvcnkgaWYgaXQgZG9lc24ndCBleGlzdCAoY2htb2QgNzc3KS4KX2NyZWF0ZV9mb2xkZXIoKSB7"\
|
|
||||||
"CiAgICBsb2NhbCBmb2xkZXI9IiQxIgogICAgaWYgWyAtZCAiJGZvbGRlciIgXTsgdGhlbgogICAg"\
|
|
||||||
"ICAgIHJldHVybiAwCiAgICBmaQogICAgaWYgISBta2RpciAtcCAiJGZvbGRlciI7IHRoZW4KICAg"\
|
|
||||||
"ICAgICBfZGllICJGYWlsZWQgdG8gY3JlYXRlIGZvbGRlcjogJGZvbGRlciIKICAgIGZpCiAgICBj"\
|
|
||||||
"aG1vZCA3NzcgIiRmb2xkZXIiCiAgICBlY2hvICJGb2xkZXIgY3JlYXRlZDogJGZvbGRlciIKfQoK"\
|
|
||||||
"IyBDaGVja3MgaWYgRG9ja2VyIGlzIGluc3RhbGxlZCwgcnVubmluZywgYW5kIHVzZXIgaGFzIHBl"\
|
|
||||||
"cm1pc3Npb24uIFJldHVybnMgMSBvbiBmYWlsdXJlLgpfY2hlY2tfZG9ja2VyX2luc3RhbGxlZCgp"\
|
|
||||||
"IHsKICAgIGlmICEgY29tbWFuZCAtdiBkb2NrZXIgJj4gL2Rldi9udWxsOyB0aGVuCiAgICAgICAg"\
|
|
||||||
"ZWNobyAiRG9ja2VyIGlzIG5vdCBpbnN0YWxsZWQiCiAgICAgICAgcmV0dXJuIDEKICAgIGZpCgog"\
|
|
||||||
"ICAgIyBjaGVjayBpZiBkb2NrZXIgZGFlbW9uIGlzIHJ1bm5pbmcKICAgIGlmICEgZG9ja2VyIGlu"\
|
|
||||||
"Zm8gJj4gL2Rldi9udWxsOyB0aGVuCiAgICAgICAgZWNobyAiRG9ja2VyIGRhZW1vbiBpcyBub3Qg"\
|
|
||||||
"cnVubmluZyIKICAgICAgICByZXR1cm4gMQogICAgZmkKCiAgICAjIGNoZWNrIGlmIHVzZXIgaGFz"\
|
|
||||||
"IHBlcm1pc3Npb24gdG8gcnVuIGRvY2tlcgogICAgaWYgISBkb2NrZXIgcnVuIC0tcm0gaGVsbG8t"\
|
|
||||||
"d29ybGQgJj4gL2Rldi9udWxsOyB0aGVuCiAgICAgICAgZWNobyAiVXNlciBkb2VzIG5vdCBoYXZl"\
|
|
||||||
"IHBlcm1pc3Npb24gdG8gcnVuIGRvY2tlciIKICAgICAgICByZXR1cm4gMQogICAgZmkKCiAgICBy"\
|
|
||||||
"ZXR1cm4gMAp9CgojIENoZWNrcyBpZiBhIGNvbnRhaW5lciAoYW55IHN0YXRlKSBleGlzdHMuIFJl"\
|
|
||||||
"dHVybnMgMSBpZiBub3QgZm91bmQuCl9pc19jb250YWluZXJfZXhpc3RzKCkgewogICAgaWYgISBk"\
|
|
||||||
"b2NrZXIgcHMgLWEgLS1mb3JtYXQgInt7Lk5hbWVzfX0iIHwgZ3JlcCAtcSAiXiQxJCI7IHRoZW4K"\
|
|
||||||
"ICAgICAgICByZXR1cm4gMQogICAgZmkKICAgIHJldHVybiAwCn0KCiMgQ2hlY2tzIGlmIGEgY29u"\
|
|
||||||
"dGFpbmVyIGlzIGN1cnJlbnRseSBydW5uaW5nLiBSZXR1cm5zIDEgaWYgbm90IHJ1bm5pbmcuCl9p"\
|
|
||||||
"c19jb250YWluZXJfcnVubmluZygpIHsKICAgIGlmICEgZG9ja2VyIHBzIC0tZm9ybWF0ICJ7ey5O"\
|
|
||||||
"YW1lc319IiB8IGdyZXAgLXEgIl4kMSQiOyB0aGVuCiAgICAgICAgcmV0dXJuIDEKICAgIGZpCiAg"\
|
|
||||||
"ICByZXR1cm4gMAp9CgojIFByaW50cyB0aGUgSUQgb2YgdGhlIG5hbWVkIGNvbnRhaW5lci4KX2dl"\
|
|
||||||
"dF9jb250YWluZXJfaWQoKSB7CiAgICBkb2NrZXIgcHMgLS1mb3JtYXQgInt7LklEfX0iIC0tZmls"\
|
|
||||||
"dGVyICJuYW1lPSQxIgp9CgojIFByaW50cyB0aGUgc3RhdHVzIHN0cmluZyBvZiB0aGUgbmFtZWQg"\
|
|
||||||
"Y29udGFpbmVyLgpfZ2V0X2NvbnRhaW5lcl9zdGF0dXMoKSB7CiAgICBkb2NrZXIgcHMgLS1mb3Jt"\
|
|
||||||
"YXQgInt7LlN0YXR1c319IiAtLWZpbHRlciAibmFtZT0kMSIKfQoKIyBTdGFydHMgYW4gZXhpc3Rp"\
|
|
||||||
"bmcsIHN0b3BwZWQgY29udGFpbmVyLgpfc3RhcnRfY29udGFpbmVyKCkgewogICAgX2lzX2NvbnRh"\
|
|
||||||
"aW5lcl9leGlzdHMgJDEgfHwgcmV0dXJuIDEKICAgIF9pc19jb250YWluZXJfcnVubmluZyAkMSAm"\
|
|
||||||
"JiByZXR1cm4gMAogICAgZG9ja2VyIHN0YXJ0ICQxCn0KCiMgU3RvcHMgYSBydW5uaW5nIGNvbnRh"\
|
|
||||||
"aW5lci4KX3N0b3BfY29udGFpbmVyKCkgewogICAgX2lzX2NvbnRhaW5lcl9ydW5uaW5nICQxIHx8"\
|
|
||||||
"IHJldHVybiAwOwogICAgZG9ja2VyIHN0b3AgJDEKfSAgIAoKIyBTdG9wcyAoaWYgbmVlZGVkKSBh"\
|
|
||||||
"bmQgcmVtb3ZlcyBhIGNvbnRhaW5lci4KX3JlbW92ZV9jb250YWluZXIoKSB7CiAgICBfc3RvcF9j"\
|
|
||||||
"b250YWluZXIgJDEKICAgIF9pc19jb250YWluZXJfZXhpc3RzICQxIHx8IHJldHVybiAwOwogICAg"\
|
|
||||||
"ZG9ja2VyIHJtICQxCn0KCiMgUHJpbnRzIHRoZSBsb2dzIGZvciBhIGNvbnRhaW5lci4KX2dldF9j"\
|
|
||||||
"b250YWluZXJfbG9ncygpIHsKICAgIGlmICEgX2lzX2NvbnRhaW5lcl9leGlzdHMgJDE7IHRoZW4K"\
|
|
||||||
"ICAgICAgICBlY2hvICJDb250YWluZXIgJDEgZG9lcyBub3QgZXhpc3QiCiAgICAgICAgcmV0dXJu"\
|
|
||||||
"IDEKICAgIGZpCgogICAgZG9ja2VyIGxvZ3MgJDEKfQoKIyBDaGVja3MgaWYgbGlzdGVkIGVudmly"\
|
|
||||||
"b25tZW50IHZhcmlhYmxlcyBhcmUgc2V0OyBjYWxscyBfZGllKCkgaWYgYW55IGFyZSBtaXNzaW5n"\
|
|
||||||
"LgpfY2hlY2tfcmVxdWlyZWRfZW52X3ZhcnMoKSB7CiAgICBsb2NhbCByZXF1aXJlZF92YXJzPSgi"\
|
|
||||||
"JEAiKQogICAgZm9yIHZhciBpbiAiJHtyZXF1aXJlZF92YXJzW0BdfSI7IGRvCiAgICAgICAgaWYg"\
|
|
||||||
"WyAteiAiJHshdmFyfSIgXTsgdGhlbgogICAgICAgICAgICBfZGllICJSZXF1aXJlZCBlbnZpcm9u"\
|
|
||||||
"bWVudCB2YXJpYWJsZSAkdmFyIGlzIG5vdCBzZXQiCiAgICAgICAgZmkKICAgIGRvbmUKfQoKIyBS"\
|
|
||||||
"ZW1vdmVzIGEgcGF0aCB1c2luZyBhIHJvb3QgRG9ja2VyIGNvbnRhaW5lciAoZm9yIHBlcm1pc3Np"\
|
|
||||||
"b25zKS4KX3Jvb3RfcmVtb3ZlX3RyZWUoKSB7CiAgICBsb2NhbCB0b19yZW1vdmU9IiQxIgogICAg"\
|
|
||||||
"cGFyZW50PSQoZGlybmFtZSAiJHRvX3JlbW92ZSIpCiAgICBhYnNfcGFyZW50PSQocmVhbHBhdGgg"\
|
|
||||||
"IiRwYXJlbnQiKQogICAgY2hpbGQ9JChiYXNlbmFtZSAiJHRvX3JlbW92ZSIpCiAgICBkb2NrZXIg"\
|
|
||||||
"cnVuIC0tcm0gLXYgIiRhYnNfcGFyZW50IjovZGF0YSBhbHBpbmUgcm0gLXJmICIvZGF0YS8kY2hp"\
|
|
||||||
"bGQiCn0KCgojIExvYWQgYXV0b2NvbW1hbmRzCnNvdXJjZSAiJHtBR0VOVF9QQVRIfS9kYXRhY29t"\
|
|
||||||
"bWFuZHMuc2gi";
|
|
||||||
|
|
||||||
// Decode Base64 data
|
|
||||||
size_t decoded_size = (strlen(filedata_base64) * 3) / 4;
|
|
||||||
unsigned char* decoded_data = new unsigned char[decoded_size];
|
|
||||||
size_t actual_size;
|
|
||||||
base64_decode(filedata_base64, strlen(filedata_base64), decoded_data, &actual_size);
|
|
||||||
|
|
||||||
bool file_written = _recreate_file_(outpath, 6967493376886731479ULL, std::filesystem::perms(493), decoded_data, actual_size);
|
|
||||||
delete[] decoded_data;
|
|
||||||
any_written = any_written || file_written;
|
|
||||||
}
|
|
||||||
return any_written;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
THIS FILE IS AUTO-GENERATED BY DEHYDRATE.
|
|
||||||
DO NOT EDIT THIS FILE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
namespace recreate_agent {
|
|
||||||
bool recreate_tree(std::string destination_folder);
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
// version.hpp (dummy for linter/IntelliSense)
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace dropshell {
|
|
||||||
extern const std::string VERSION;
|
|
||||||
extern const std::string RELEASE_DATE;
|
|
||||||
extern const std::string AUTHOR;
|
|
||||||
extern const std::string LICENSE;
|
|
||||||
}
|
|
@ -5,7 +5,8 @@
|
|||||||
#include "templates.hpp"
|
#include "templates.hpp"
|
||||||
#include "shared_commands.hpp"
|
#include "shared_commands.hpp"
|
||||||
#include "utils/hash.hpp"
|
#include "utils/hash.hpp"
|
||||||
#include "autogen/_agent.hpp"
|
#include "autogen/_agent-local.hpp"
|
||||||
|
#include "autogen/_agent-remote.hpp"
|
||||||
#include "services.hpp"
|
#include "services.hpp"
|
||||||
#include "utils/output.hpp"
|
#include "utils/output.hpp"
|
||||||
|
|
||||||
@ -15,6 +16,7 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include "utils/assert.hpp"
|
#include "utils/assert.hpp"
|
||||||
|
#include "servers.hpp"
|
||||||
|
|
||||||
namespace dropshell
|
namespace dropshell
|
||||||
{
|
{
|
||||||
@ -43,8 +45,8 @@ namespace dropshell
|
|||||||
Install components on a server. This is safe to re-run (non-destructive) and used to update
|
Install components on a server. This is safe to re-run (non-destructive) and used to update
|
||||||
servers and their services.
|
servers and their services.
|
||||||
|
|
||||||
install (re)install dropshell components on this computer.
|
install (re)install dropshell components on this computer, and on all servers.
|
||||||
install SERVER (re)install dropshell agent on the given server.
|
install SERVER (re)install dropshell agent on the particular given server.
|
||||||
install SERVER [SERVICE|all] (re)install the given service (or all services) on the given server.
|
install SERVER [SERVICE|all] (re)install the given service (or all services) on the given server.
|
||||||
|
|
||||||
Note you need to create the service first with:
|
Note you need to create the service first with:
|
||||||
@ -159,6 +161,8 @@ namespace dropshell
|
|||||||
|
|
||||||
int update_dropshell()
|
int update_dropshell()
|
||||||
{
|
{
|
||||||
|
maketitle("Updating dropshell on this computer...");
|
||||||
|
|
||||||
// determine path to this executable
|
// determine path to this executable
|
||||||
std::filesystem::path dropshell_path = std::filesystem::canonical("/proc/self/exe");
|
std::filesystem::path dropshell_path = std::filesystem::canonical("/proc/self/exe");
|
||||||
std::filesystem::path parent_path = dropshell_path.parent_path();
|
std::filesystem::path parent_path = dropshell_path.parent_path();
|
||||||
@ -202,8 +206,8 @@ namespace dropshell
|
|||||||
|
|
||||||
if (currentver >= newver)
|
if (currentver >= newver)
|
||||||
{
|
{
|
||||||
std::cout << "Current dropshell version: " << currentver << ", published version: " << newver << std::endl;
|
info << "Current dropshell version: " << currentver << ", published version: " << newver << std::endl;
|
||||||
std::cout << "No update needed." << std::endl;
|
info << "Release version is not newer, no update needed." << std::endl;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,20 +218,22 @@ namespace dropshell
|
|||||||
rval = system(bash_script_2.c_str());
|
rval = system(bash_script_2.c_str());
|
||||||
if (rval != 0)
|
if (rval != 0)
|
||||||
{
|
{
|
||||||
std::cerr << "Failed to install new version of dropshell." << std::endl;
|
error << "Failed to install new version of dropshell." << std::endl;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "Successfully updated " << dropshell_path << " to the latest " << arch << " version." << std::endl;
|
info << "Successfully updated " << dropshell_path << " to the latest " << arch << " version." << std::endl;
|
||||||
|
|
||||||
// execute the new version
|
// execute the new version
|
||||||
execlp("bash", "bash", "-c", (parent_path / "dropshell").c_str(), "install", (char *)nullptr);
|
execlp("bash", "bash", "-c", (parent_path / "dropshell").c_str(), "install", (char *)nullptr);
|
||||||
std::cerr << "Failed to execute new version of dropshell." << std::endl;
|
error << "Failed to execute new version of dropshell." << std::endl;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int install_local_agent()
|
int install_local_agent()
|
||||||
{
|
{
|
||||||
|
maketitle("Installing dropshell agent on this computer...");
|
||||||
|
|
||||||
std::vector<std::filesystem::path> paths = {
|
std::vector<std::filesystem::path> paths = {
|
||||||
gConfig().get_local_template_cache_path(),
|
gConfig().get_local_template_cache_path(),
|
||||||
gConfig().get_local_backup_path(),
|
gConfig().get_local_backup_path(),
|
||||||
@ -239,46 +245,20 @@ namespace dropshell
|
|||||||
for (auto &p : paths)
|
for (auto &p : paths)
|
||||||
if (!std::filesystem::exists(p))
|
if (!std::filesystem::exists(p))
|
||||||
{
|
{
|
||||||
std::cout << "Creating directory: " << p << std::endl;
|
info << "Creating directory: " << p << std::endl;
|
||||||
std::filesystem::create_directories(p);
|
std::filesystem::create_directories(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
// download bb64 for the host architecture.
|
// create the agent-local directory.
|
||||||
if (!std::filesystem::exists(localpath::agent() + "bb64"))
|
recreate_agent_local::recreate_tree(localpath::agent());
|
||||||
{
|
|
||||||
std::string cmd = "cd " + localpath::agent() + " && curl -fsSL -o bb64 https://gitea.jde.nz/public/bb64/releases/download/latest/bb64.amd64 && chmod a+x bb64";
|
|
||||||
int ret = system(cmd.c_str());
|
|
||||||
if (EXITSTATUSCHECK(ret))
|
|
||||||
std::cout << "Downloaded local bb64 to " << localpath::agent() << std::endl;
|
|
||||||
else
|
|
||||||
std::cerr << "Failed to download local bb64 to " << localpath::agent() << std::endl;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cout << "Updating local bb64..." << std::endl;
|
|
||||||
system((localpath::agent() + "bb64 -u").c_str()); // update.
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << "Creating local files to copy to remote agents..." << std::endl;
|
// run the local agent installer.
|
||||||
recreate_agent::recreate_tree(localpath::files_for_remote_agent());
|
execute_local_command(localpath::agent(), "agent-install.sh",{}, nullptr, cMode::Defaults | cMode::NoBB64);
|
||||||
|
|
||||||
return 0;
|
// create the agent-remote directory.
|
||||||
}
|
info << "Creating local files to copy to remote agents..." << std::endl;
|
||||||
|
recreate_agent_remote::recreate_tree(localpath::files_for_remote_agent());
|
||||||
|
|
||||||
int install_host()
|
|
||||||
{
|
|
||||||
// update dropshell.
|
|
||||||
// install the local dropshell agent.
|
|
||||||
|
|
||||||
int rval = update_dropshell();
|
|
||||||
if (rval != 0)
|
|
||||||
return rval;
|
|
||||||
|
|
||||||
rval = install_local_agent();
|
|
||||||
if (rval != 0)
|
|
||||||
return rval;
|
|
||||||
|
|
||||||
std::cout << "Installation complete." << std::endl;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -307,23 +287,9 @@ namespace dropshell
|
|||||||
shared_commands::rsync_tree_to_remote(localpath::files_for_remote_agent(), agent_path, server_env, false);
|
shared_commands::rsync_tree_to_remote(localpath::files_for_remote_agent(), agent_path, server_env, false);
|
||||||
info << "done." << std::endl;
|
info << "done." << std::endl;
|
||||||
|
|
||||||
// add in bb64. We can't use execute_remote_command() here, as that relies on bb64 which we're installing!
|
// run the agent installer. Can't use BB64 yet, as we're installing it on the remote server.
|
||||||
info << "Installing bb64 on " << server << "..." << std::endl
|
|
||||||
<< std::flush;
|
|
||||||
|
|
||||||
std::string remote_cmd =
|
bool okay = execute_ssh_command(server_env.get_SSH_INFO(), sCommand(agent_path, "agent-install.sh",{}), cMode::Defaults | cMode::NoBB64, nullptr);
|
||||||
"ssh -p " + server_env.get_SSH_INFO().port + " " + server_env.get_SSH_INFO().user + "@" + server_env.get_SSH_INFO().host +
|
|
||||||
" 'mkdir -p " + quote(agent_path) + " && curl -fsSL \"https://gitea.jde.nz/public/bb64/releases/download/latest/install.sh\" | bash -s -- " +
|
|
||||||
quote(agent_path) + " " + quote("$(id -u " + server_env.get_SSH_USER() + "):$(id -g " + server_env.get_SSH_USER() + ")") + "'";
|
|
||||||
|
|
||||||
// std::cout << "Executing: " << remote_cmd << std::endl;
|
|
||||||
if (!execute_local_command("", remote_cmd, {}, nullptr, cMode::Silent))
|
|
||||||
error << "Failed to download bb64 to " << agent_path << " on remote server." << std::endl;
|
|
||||||
else
|
|
||||||
debug << "Downloaded bb64 to " << agent_path << " on remote server." << std::endl;
|
|
||||||
|
|
||||||
// run the self-test.
|
|
||||||
bool okay = execute_ssh_command(server_env.get_SSH_INFO(), sCommand(agent_path, "./selftest.sh", {}), cMode::Defaults, nullptr);
|
|
||||||
if (!okay)
|
if (!okay)
|
||||||
{
|
{
|
||||||
error << "ERROR: Failed to install remote agent on " << server << std::endl;
|
error << "ERROR: Failed to install remote agent on " << server << std::endl;
|
||||||
@ -334,6 +300,35 @@ namespace dropshell
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// install_host
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
int install_host()
|
||||||
|
{
|
||||||
|
// update dropshell.
|
||||||
|
// install the local dropshell agent.
|
||||||
|
|
||||||
|
int rval = update_dropshell();
|
||||||
|
if (rval != 0)
|
||||||
|
return rval;
|
||||||
|
|
||||||
|
rval = install_local_agent();
|
||||||
|
if (rval != 0)
|
||||||
|
return rval;
|
||||||
|
|
||||||
|
// install the dropshell agent on all servers.
|
||||||
|
std::vector<ServerInfo> servers = get_configured_servers();
|
||||||
|
for (const auto &server : servers)
|
||||||
|
{
|
||||||
|
rval = install_server(server.name);
|
||||||
|
if (rval != 0)
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "Installation complete." << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// install command implementation
|
// install command implementation
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -127,6 +127,16 @@ namespace dropshell
|
|||||||
|
|
||||||
ASSERT(backup_details.has_value() && backup_details->is_valid(), "Invalid backup file.");
|
ASSERT(backup_details.has_value() && backup_details->is_valid(), "Invalid backup file.");
|
||||||
|
|
||||||
|
debug << "Backup details: " << std::endl;
|
||||||
|
debug << " Backup filename: " << backup_details->get_filename() << std::endl;
|
||||||
|
debug << " Backup template: " << backup_details->get_template_name() << std::endl;
|
||||||
|
debug << " Backup taken from server: " << backup_details->get_server() << std::endl;
|
||||||
|
debug << " Backup taken from service: " << backup_details->get_service() << std::endl;
|
||||||
|
debug << " " << std::endl;
|
||||||
|
debug << "Restoring to:" << std::endl;
|
||||||
|
debug << " Server: " << server << std::endl;
|
||||||
|
debug << " Service: " << service << std::endl;
|
||||||
|
|
||||||
std::string local_backups_dir = gConfig().get_local_backup_path();
|
std::string local_backups_dir = gConfig().get_local_backup_path();
|
||||||
if (local_backups_dir.empty() || !std::filesystem::exists(local_backups_dir))
|
if (local_backups_dir.empty() || !std::filesystem::exists(local_backups_dir))
|
||||||
{
|
{
|
||||||
@ -143,14 +153,11 @@ namespace dropshell
|
|||||||
if (backup_details->get_template_name() != service_info.template_name)
|
if (backup_details->get_template_name() != service_info.template_name)
|
||||||
{
|
{
|
||||||
error << "Error: Backup template does not match service template. Can't restore." << std::endl;
|
error << "Error: Backup template does not match service template. Can't restore." << std::endl;
|
||||||
debug << "Backup template: " << backup_details->get_template_name() << std::endl;
|
info << "Backup template: " << backup_details->get_template_name() << std::endl;
|
||||||
debug << "Service template: " << service_info.template_name << std::endl;
|
info << "Service template: " << service_info.template_name << std::endl;
|
||||||
debug << "Backup file: " << local_backup_file_path << std::endl;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
info << "Restoring " << backup_details->get_datetime() << " backup of " << backup_details->get_service() << " taken from " << backup_details->get_server() << ", onto " << server << "/" << service << std::endl;
|
|
||||||
info << std::endl;
|
|
||||||
warning << "*** ALL DATA FOR " << server << "/" << service << " WILL BE OVERWRITTEN! ***" << std::endl;
|
warning << "*** ALL DATA FOR " << server << "/" << service << " WILL BE OVERWRITTEN! ***" << std::endl;
|
||||||
|
|
||||||
// run the restore script
|
// run the restore script
|
||||||
@ -160,9 +167,9 @@ namespace dropshell
|
|||||||
info << "1) Backing up old service... " << std::endl;
|
info << "1) Backing up old service... " << std::endl;
|
||||||
if (!shared_commands::backupdata_service(server, service))
|
if (!shared_commands::backupdata_service(server, service))
|
||||||
{
|
{
|
||||||
error << "Error: Backup failed, restore aborted." << std::endl;
|
error << "Backup failed, restore aborted." << std::endl;
|
||||||
error << "You can try using dropshell install " << server << " " << service << " to install the service afresh." << std::endl;
|
info << "You can try using dropshell install " << server << " " << service << " to install the service afresh." << std::endl;
|
||||||
error << "Otherwise, stop the service, create and initialise a new one, then restore to that." << std::endl;
|
info << "Otherwise, stop the service, create and initialise a new one, then restore to that." << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
info << "Backup complete." << std::endl;
|
info << "Backup complete." << std::endl;
|
||||||
@ -191,6 +198,8 @@ namespace dropshell
|
|||||||
std::string remote_backups_dir = remotepath::backups(server);
|
std::string remote_backups_dir = remotepath::backups(server);
|
||||||
std::string remote_backup_file_path = remote_backups_dir + "/" + backup_details->get_filename();
|
std::string remote_backup_file_path = remote_backups_dir + "/" + backup_details->get_filename();
|
||||||
|
|
||||||
|
debug << "Copying backup file from local to server: " << local_backup_file_path << " -> " << remote_backup_file_path << std::endl;
|
||||||
|
|
||||||
// Copy backup file from local to server
|
// Copy backup file from local to server
|
||||||
if (!shared_commands::scp_file_to_remote(server_env, local_backup_file_path, remote_backup_file_path, false))
|
if (!shared_commands::scp_file_to_remote(server_env, local_backup_file_path, remote_backup_file_path, false))
|
||||||
{
|
{
|
||||||
@ -199,6 +208,11 @@ namespace dropshell
|
|||||||
}
|
}
|
||||||
|
|
||||||
shared_commands::cRemoteTempFolder remote_temp_folder(server_env);
|
shared_commands::cRemoteTempFolder remote_temp_folder(server_env);
|
||||||
|
|
||||||
|
debug << "Running restore script on server: " << server << std::endl;
|
||||||
|
debug << " BACKUP_FILE: " << remote_backup_file_path << std::endl;
|
||||||
|
debug << " TEMP_DIR: " << remote_temp_folder.path() << std::endl;
|
||||||
|
|
||||||
server_env.run_remote_template_command(service, "restore", {}, false, {{"BACKUP_FILE", remote_backup_file_path}, {"TEMP_DIR", remote_temp_folder.path()}});
|
server_env.run_remote_template_command(service, "restore", {}, false, {{"BACKUP_FILE", remote_backup_file_path}, {"TEMP_DIR", remote_temp_folder.path()}});
|
||||||
} // dtor of remote_temp_folder will clean up the temp folder on the server
|
} // dtor of remote_temp_folder will clean up the temp folder on the server
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ namespace dropshell
|
|||||||
|
|
||||||
std::string output;
|
std::string output;
|
||||||
if (!execute_ssh_command(env.get_SSH_INFO(), sCommand(remotepath::agent(server_name), "./_allservicesstatus.sh", {{"HOST_NAME", server_name}, {"SERVER", server_name}, {"AGENT_PATH", remotepath::agent(server_name)}}),
|
if (!execute_ssh_command(env.get_SSH_INFO(), sCommand(remotepath::agent(server_name), "./_allservicesstatus.sh", {{"HOST_NAME", server_name}, {"SERVER", server_name}, {"AGENT_PATH", remotepath::agent(server_name)}}),
|
||||||
cMode::CaptureOutput | cMode::Silent,
|
cMode::Silent,
|
||||||
&output))
|
&output))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
|
@ -218,8 +218,7 @@ bool server_env_manager::run_remote_template_command_and_capture_output(const st
|
|||||||
for (const auto& [key, value] : extra_env_vars)
|
for (const auto& [key, value] : extra_env_vars)
|
||||||
scommand->add_env_var(key, value);
|
scommand->add_env_var(key, value);
|
||||||
|
|
||||||
cMode mode = cMode::CaptureOutput;
|
return execute_ssh_command(get_SSH_INFO(), scommand.value(), cMode::Defaults, &output);
|
||||||
return execute_ssh_command(get_SSH_INFO(), scommand.value(), mode, &output);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,7 +22,6 @@ namespace dropshell
|
|||||||
return (ret != -1 && WIFEXITED(ret) && (WEXITSTATUS(ret) == 0)); // ret is -1 if the command failed to execute.
|
return (ret != -1 && WIFEXITED(ret) && (WEXITSTATUS(ret) == 0)); // ret is -1 if the command failed to execute.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------------------------
|
||||||
// execute_local_command_interactive
|
// execute_local_command_interactive
|
||||||
// ----------------------------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------------------------
|
||||||
@ -30,7 +29,7 @@ namespace dropshell
|
|||||||
{
|
{
|
||||||
if (command.get_command_to_run().empty())
|
if (command.get_command_to_run().empty())
|
||||||
return false;
|
return false;
|
||||||
std::string full_command = command.construct_cmd(localpath::agent()); // Get the command string
|
std::string full_command = command.construct_cmd(localpath::agent()+"/bb64"); // Get the command string
|
||||||
|
|
||||||
pid_t pid = fork();
|
pid_t pid = fork();
|
||||||
|
|
||||||
@ -62,7 +61,7 @@ namespace dropshell
|
|||||||
|
|
||||||
class fancypinter
|
class fancypinter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
fancypinter(sColour startColour) : startColour_(startColour), currentColour_(startColour) {}
|
fancypinter(sColour startColour) : startColour_(startColour), currentColour_(startColour) {}
|
||||||
|
|
||||||
void print_chunk(std::string chunk)
|
void print_chunk(std::string chunk)
|
||||||
@ -85,15 +84,19 @@ namespace dropshell
|
|||||||
currentColour_ = startColour_;
|
currentColour_ = startColour_;
|
||||||
}
|
}
|
||||||
colourstream(currentColour_) << chunk;
|
colourstream(currentColour_) << chunk;
|
||||||
newline_ = (chunk[chunk.size()-1] == '\n');
|
newline_ = (chunk[chunk.size() - 1] == '\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
void print(const std::string& buffer) {
|
void print(const std::string &buffer)
|
||||||
|
{
|
||||||
size_t start = 0;
|
size_t start = 0;
|
||||||
while (start < buffer.size()) {
|
while (start < buffer.size())
|
||||||
|
{
|
||||||
size_t newline_pos = buffer.find('\n', start);
|
size_t newline_pos = buffer.find('\n', start);
|
||||||
if (newline_pos == std::string::npos) {
|
if (newline_pos == std::string::npos)
|
||||||
if (start < buffer.size()) {
|
{
|
||||||
|
if (start < buffer.size())
|
||||||
|
{
|
||||||
print_chunk(buffer.substr(start));
|
print_chunk(buffer.substr(start));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -103,32 +106,36 @@ namespace dropshell
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool newline_ = true;
|
bool newline_ = true;
|
||||||
sColour startColour_;
|
sColour startColour_;
|
||||||
sColour currentColour_;
|
sColour currentColour_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
bool execute_local_command(std::string directory_to_run_in, std::string command_to_run, const std::map<std::string, std::string> &env_vars, std::string *output, cMode mode)
|
bool execute_local_command(std::string directory_to_run_in, std::string command_to_run, const std::map<std::string, std::string> &env_vars, std::string *output, cMode mode)
|
||||||
{
|
{
|
||||||
sCommand command(directory_to_run_in, command_to_run, env_vars);
|
sCommand command(directory_to_run_in, command_to_run, env_vars);
|
||||||
|
|
||||||
if (hasFlag(mode, cMode::Interactive))
|
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(output == nullptr, "Interactive mode and an output string cannot be used together");
|
||||||
|
|
||||||
return execute_local_command_interactive(command);
|
return execute_local_command_interactive(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (command.get_command_to_run().empty())
|
if (command.get_command_to_run().empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool silent = hasFlag(mode, cMode::Silent);
|
bool silent = hasFlag(mode, cMode::Silent);
|
||||||
|
|
||||||
std::string full_cmd = command.construct_cmd(localpath::agent()) + (hasFlag(mode, cMode::CaptureOutput) ? " 2>&1" : ""); // capture both stdout and stderr
|
std::string full_cmd;
|
||||||
|
if (!hasFlag(mode, cMode::NoBB64))
|
||||||
|
full_cmd = command.construct_cmd(localpath::agent()+"/bb64");
|
||||||
|
else
|
||||||
|
full_cmd = command.construct_cmd("");
|
||||||
|
|
||||||
|
if (output != nullptr)
|
||||||
|
full_cmd += " 2>&1"; // capture both stdout and stderr
|
||||||
|
|
||||||
FILE *pipe = popen(full_cmd.c_str(), "r");
|
FILE *pipe = popen(full_cmd.c_str(), "r");
|
||||||
if (!pipe)
|
if (!pipe)
|
||||||
@ -140,7 +147,7 @@ namespace dropshell
|
|||||||
while (fgets(buffer, sizeof(buffer), pipe) != nullptr)
|
while (fgets(buffer, sizeof(buffer), pipe) != nullptr)
|
||||||
{
|
{
|
||||||
if (output != nullptr)
|
if (output != nullptr)
|
||||||
(*output) += buffer;
|
(*output) += buffer;
|
||||||
|
|
||||||
if (!silent)
|
if (!silent)
|
||||||
fancyprint.print(buffer);
|
fancyprint.print(buffer);
|
||||||
@ -157,30 +164,27 @@ namespace dropshell
|
|||||||
if (remote_command.get_command_to_run().empty())
|
if (remote_command.get_command_to_run().empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ASSERT(!(hasFlag(mode, cMode::CaptureOutput) && output == nullptr), "Capture output mode must be used with an output string");
|
|
||||||
|
|
||||||
std::stringstream ssh_cmd;
|
std::stringstream ssh_cmd;
|
||||||
ssh_cmd << "ssh -p " << ssh_info.port << " " << (hasFlag(mode, cMode::Interactive) ? "-tt " : "")
|
ssh_cmd << "ssh -p " << ssh_info.port << " " << (hasFlag(mode, cMode::Interactive) ? "-tt " : "")
|
||||||
<< ssh_info.user << "@" << ssh_info.host;
|
<< ssh_info.user << "@" << ssh_info.host;
|
||||||
|
|
||||||
std::string remote_agent_path = remotepath::agent(ssh_info.server_ID);
|
std::string remote_bb64_path;
|
||||||
|
|
||||||
|
if (!hasFlag(mode, cMode::NoBB64))
|
||||||
|
remote_bb64_path = remotepath::agent(ssh_info.server_ID) + "/bb64";
|
||||||
|
|
||||||
bool rval = execute_local_command(
|
bool rval = execute_local_command(
|
||||||
"", // directory to run in
|
"", // local directory to run in
|
||||||
ssh_cmd.str() + " " + remote_command.construct_cmd(remote_agent_path), // local command to run
|
ssh_cmd.str() + " " + remote_command.construct_cmd(remote_bb64_path), // local command to run
|
||||||
{}, // environment variables
|
{}, // environment variables
|
||||||
output, // output string
|
output, // output string
|
||||||
mode // mode
|
mode // mode
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!rval && !hasFlag(mode, cMode::Silent))
|
if (!rval && !hasFlag(mode, cMode::Silent))
|
||||||
{
|
{
|
||||||
std::cerr << std::endl
|
error << "Error: Failed to execute ssh command:" << std::endl;
|
||||||
<< std::endl;
|
debug << ssh_cmd.str() + " " + remote_command.construct_cmd(remote_bb64_path) << std::endl;
|
||||||
std::cerr << "Error: Failed to execute ssh command:" << std::endl;
|
|
||||||
std::cerr << "\033[90m" << ssh_cmd.str() + " " + remote_command.construct_cmd(remote_agent_path) << "\033[0m" << std::endl;
|
|
||||||
std::cerr << std::endl
|
|
||||||
<< std::endl;
|
|
||||||
}
|
}
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
@ -188,19 +192,19 @@ namespace dropshell
|
|||||||
// ----------------------------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------------------------
|
||||||
// makesafecmd
|
// makesafecmd
|
||||||
// ----------------------------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------------------------
|
||||||
std::string sCommand::makesafecmd(std::string agent_path, const std::string &command) const
|
std::string sCommand::makesafecmd(std::string bb64path, const std::string &command) const
|
||||||
{
|
{
|
||||||
if (command.empty())
|
if (command.empty())
|
||||||
return "";
|
return "";
|
||||||
std::string encoded = base64_encode(dequote(trim(command)));
|
std::string encoded = base64_encode(dequote(trim(command)));
|
||||||
std::string commandstr = agent_path + "/bb64 " + encoded;
|
std::string commandstr = bb64path + " " + encoded;
|
||||||
return commandstr;
|
return commandstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------------------------
|
||||||
// construct_cmd
|
// construct_cmd
|
||||||
// ----------------------------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------------------------
|
||||||
std::string sCommand::construct_cmd(std::string agent_path) const
|
std::string sCommand::construct_cmd(std::string bb64path) const
|
||||||
{
|
{
|
||||||
if (mCmd.empty())
|
if (mCmd.empty())
|
||||||
return "";
|
return "";
|
||||||
@ -208,17 +212,27 @@ namespace dropshell
|
|||||||
// need to construct to change directory and set environment variables
|
// need to construct to change directory and set environment variables
|
||||||
std::string cmdstr;
|
std::string cmdstr;
|
||||||
|
|
||||||
if (!mDir.empty())
|
if (!bb64path.empty())
|
||||||
cmdstr += "cd " + quote(mDir) + " && ";
|
{
|
||||||
|
if (!mDir.empty())
|
||||||
|
cmdstr += "cd " + quote(mDir) + " && ";
|
||||||
|
|
||||||
if (!mVars.empty())
|
if (!mVars.empty())
|
||||||
for (const auto &env_var : mVars)
|
for (const auto &env_var : mVars)
|
||||||
cmdstr += env_var.first + "=" + quote(dequote(trim(env_var.second))) + " ";
|
cmdstr += env_var.first + "=" + quote(dequote(trim(env_var.second))) + " ";
|
||||||
|
|
||||||
cmdstr += mCmd;
|
cmdstr += mCmd;
|
||||||
|
|
||||||
if (!agent_path.empty())
|
cmdstr = makesafecmd(bb64path, cmdstr);
|
||||||
cmdstr = makesafecmd(agent_path, cmdstr);
|
}
|
||||||
|
else
|
||||||
|
{ // raw! bootstrapping only.
|
||||||
|
ASSERT(mVars.empty(), "Bootstrapping command must not have environment variables");
|
||||||
|
if (!mDir.empty())
|
||||||
|
cmdstr += mDir + "/" + mCmd;
|
||||||
|
else
|
||||||
|
cmdstr += mCmd;
|
||||||
|
}
|
||||||
|
|
||||||
return cmdstr;
|
return cmdstr;
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ enum class cMode {
|
|||||||
Defaults = 0,
|
Defaults = 0,
|
||||||
Interactive = 1,
|
Interactive = 1,
|
||||||
Silent = 2,
|
Silent = 2,
|
||||||
CaptureOutput = 4
|
NoBB64 = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
inline cMode operator&(cMode lhs, cMode rhs) {return static_cast<cMode>(static_cast<int>(lhs) & static_cast<int>(rhs));}
|
inline cMode operator&(cMode lhs, cMode rhs) {return static_cast<cMode>(static_cast<int>(lhs) & static_cast<int>(rhs));}
|
||||||
@ -52,10 +52,10 @@ class sCommand {
|
|||||||
|
|
||||||
bool empty() const { return mCmd.empty(); }
|
bool empty() const { return mCmd.empty(); }
|
||||||
|
|
||||||
std::string construct_cmd(std::string agent_path) const;
|
std::string construct_cmd(std::string bb64path) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string makesafecmd(std::string agent_path, const std::string& command) const;
|
std::string makesafecmd(std::string bb64path, const std::string& command) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string mDir;
|
std::string mDir;
|
||||||
|
Reference in New Issue
Block a user