This commit is contained in:
parent
547482edc6
commit
61218f8866
@ -32,6 +32,9 @@ configure_file(
|
||||
# Set CMAKE_MODULE_PATH to include our custom find modules
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
|
||||
|
||||
# Find required libraries
|
||||
find_package(LibSSH REQUIRED)
|
||||
|
||||
# Auto-detect source files
|
||||
file(GLOB_RECURSE SOURCES "src/*.cpp")
|
||||
file(GLOB_RECURSE HEADERS "src/*.hpp")
|
||||
@ -45,6 +48,7 @@ target_include_directories(dropshell PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/utils
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/contrib
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/src>
|
||||
${LIBSSH_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
include(FetchContent)
|
||||
@ -54,7 +58,7 @@ FetchContent_Declare(
|
||||
GIT_TAG v2.1.5 # <HASH or TAG>
|
||||
)
|
||||
FetchContent_MakeAvailable(libassert)
|
||||
target_link_libraries(dropshell libassert::assert)
|
||||
target_link_libraries(dropshell PRIVATE libassert::assert)
|
||||
|
||||
# On windows copy libassert.dll to the same directory as the executable for your_target
|
||||
if(WIN32)
|
||||
@ -68,6 +72,7 @@ endif()
|
||||
|
||||
# Link libraries
|
||||
target_link_libraries(dropshell PRIVATE
|
||||
${LIBSSH_LIBRARIES}
|
||||
)
|
||||
|
||||
# Install targets
|
||||
|
35
cmake/FindLibSSH.cmake
Normal file
35
cmake/FindLibSSH.cmake
Normal file
@ -0,0 +1,35 @@
|
||||
# - Try to find LibSSH
|
||||
# Once done this will define
|
||||
# LIBSSH_FOUND - System has LibSSH
|
||||
# LIBSSH_INCLUDE_DIRS - The LibSSH include directories
|
||||
# LIBSSH_LIBRARIES - The libraries needed to use LibSSH
|
||||
# LIBSSH_DEFINITIONS - Compiler switches required for using LibSSH
|
||||
|
||||
find_package(PkgConfig QUIET)
|
||||
if(PKG_CONFIG_FOUND)
|
||||
pkg_check_modules(PC_LIBSSH QUIET libssh)
|
||||
set(LIBSSH_DEFINITIONS ${PC_LIBSSH_CFLAGS_OTHER})
|
||||
endif()
|
||||
|
||||
find_path(LIBSSH_INCLUDE_DIR
|
||||
NAMES libssh/libssh.h
|
||||
HINTS ${PC_LIBSSH_INCLUDEDIR} ${PC_LIBSSH_INCLUDE_DIRS}
|
||||
PATH_SUFFIXES libssh
|
||||
)
|
||||
|
||||
find_library(LIBSSH_LIBRARY
|
||||
NAMES ssh libssh
|
||||
HINTS ${PC_LIBSSH_LIBDIR} ${PC_LIBSSH_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
# Handle the QUIETLY and REQUIRED arguments and set LIBSSH_FOUND to TRUE
|
||||
# if all listed variables are TRUE
|
||||
find_package_handle_standard_args(LibSSH DEFAULT_MSG
|
||||
LIBSSH_LIBRARY LIBSSH_INCLUDE_DIR
|
||||
)
|
||||
|
||||
mark_as_advanced(LIBSSH_INCLUDE_DIR LIBSSH_LIBRARY)
|
||||
|
||||
set(LIBSSH_LIBRARIES ${LIBSSH_LIBRARY})
|
||||
set(LIBSSH_INCLUDE_DIRS ${LIBSSH_INCLUDE_DIR})
|
@ -66,6 +66,9 @@ bool service_runner::install(bool silent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// make sure all shell files are executable
|
||||
make_shell_files_executable(tinfo.local_template_path().string());
|
||||
|
||||
// Copy template files
|
||||
{
|
||||
if (!rsync_copy(tinfo.local_template_path().string()+"/", remotepath::service_template(mServer, mService)+"/", silent)) {
|
||||
@ -387,7 +390,7 @@ bool service_runner::interactive_ssh(const std::string & server_name, const std:
|
||||
std::cerr << "Error: Invalid server environment file: " << server_name << std::endl;
|
||||
return false;
|
||||
}
|
||||
return 0==runner::execute_cmd("bash",{}, "", {}, false, true, env.get_SSH_INFO());
|
||||
return 0==runner::execute_cmd("", {}, "", {}, false, true, env.get_SSH_INFO());
|
||||
}
|
||||
|
||||
void service_runner::edit_server(const std::string &server_name)
|
||||
|
@ -118,36 +118,56 @@ std::string ssh_build_command_only(const std::string& command, const std::vector
|
||||
}
|
||||
|
||||
int ssh_interactive_shell_session(ssh_session session, ssh_channel channel, const std::string& remote_cmd_str, const std::string& command, std::string* output) {
|
||||
// Request a PTY with xterm-256color type for color support
|
||||
// First try using default terminal settings - should work with libssh 0.9.0+
|
||||
int rc = ssh_channel_request_pty(channel);
|
||||
if (rc != SSH_OK) {
|
||||
if (output) *output = std::string("Failed to request pty: ") + ssh_get_error(session);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Try to explicitly tell the server we want colors through additional means
|
||||
// 1. Set TERM environment variable
|
||||
rc = ssh_channel_request_env(channel, "TERM", "xterm-256color");
|
||||
// Ignore errors - this is optional
|
||||
|
||||
// 2. Request a shell
|
||||
rc = ssh_channel_request_shell(channel);
|
||||
if (rc != SSH_OK) {
|
||||
if (output) *output = std::string("Failed to request shell: ") + ssh_get_error(session);
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct termios orig_termios, raw_termios;
|
||||
tcgetattr(STDIN_FILENO, &orig_termios);
|
||||
raw_termios = orig_termios;
|
||||
cfmakeraw(&raw_termios);
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &raw_termios);
|
||||
|
||||
if (!command.empty()) {
|
||||
ssh_channel_write(channel, remote_cmd_str.c_str(), remote_cmd_str.size());
|
||||
ssh_channel_write(channel, "\n", 1);
|
||||
} else {
|
||||
// Initialize bash with color support if no specific command
|
||||
std::string init_cmd = "export TERM=xterm-256color && if [ -f ~/.bashrc ]; then source ~/.bashrc; fi";
|
||||
ssh_channel_write(channel, init_cmd.c_str(), init_cmd.size());
|
||||
ssh_channel_write(channel, "\n", 1);
|
||||
}
|
||||
|
||||
int maxfd = STDIN_FILENO > STDOUT_FILENO ? STDIN_FILENO : STDOUT_FILENO;
|
||||
maxfd = maxfd > ssh_get_fd(session) ? maxfd : ssh_get_fd(session);
|
||||
char buffer[4096];
|
||||
bool done = false;
|
||||
|
||||
while (!done) {
|
||||
fd_set fds_read;
|
||||
FD_ZERO(&fds_read);
|
||||
FD_SET(STDIN_FILENO, &fds_read);
|
||||
FD_SET(ssh_get_fd(session), &fds_read);
|
||||
|
||||
int ret = select(maxfd + 1, &fds_read, nullptr, nullptr, nullptr);
|
||||
if (ret < 0) break;
|
||||
|
||||
if (FD_ISSET(STDIN_FILENO, &fds_read)) {
|
||||
ssize_t n = read(STDIN_FILENO, buffer, sizeof(buffer));
|
||||
if (n > 0) {
|
||||
@ -157,6 +177,7 @@ int ssh_interactive_shell_session(ssh_session session, ssh_channel channel, cons
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (FD_ISSET(ssh_get_fd(session), &fds_read)) {
|
||||
int n = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
|
||||
if (n > 0) {
|
||||
@ -165,10 +186,12 @@ int ssh_interactive_shell_session(ssh_session session, ssh_channel channel, cons
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (ssh_channel_is_closed(channel) || ssh_channel_is_eof(channel)) {
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &orig_termios);
|
||||
return 0;
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ int execute_cmd(
|
||||
const std::map<std::string, std::string>& env,
|
||||
const bool silent,
|
||||
const bool interactive,
|
||||
const copySSHPtr sshinfo = nullptr,
|
||||
const copySSHPtr& sshinfo = nullptr,
|
||||
std::string* output = nullptr
|
||||
);
|
||||
|
||||
|
@ -312,6 +312,32 @@ std::string random_alphanumeric_string(int length)
|
||||
return random_string;
|
||||
}
|
||||
|
||||
void make_shell_files_executable(const std::string &dir_path)
|
||||
{ // recursively make all shell files in the directory executable
|
||||
|
||||
const auto desired_perms = std::filesystem::perms::owner_read | std::filesystem::perms::owner_exec |
|
||||
std::filesystem::perms::group_read | std::filesystem::perms::group_exec |
|
||||
std::filesystem::perms::others_read | std::filesystem::perms::others_exec;
|
||||
|
||||
for (const auto& entry : std::filesystem::directory_iterator(dir_path)) {
|
||||
if (entry.path().extension() == ".sh") {
|
||||
// check if permissions are already set
|
||||
auto currentperms = std::filesystem::status(entry.path()).permissions();
|
||||
if ((currentperms & desired_perms) == desired_perms) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// set permissions
|
||||
std::cout << "Setting executable permissions for " << entry.path() << std::endl;
|
||||
|
||||
std::filesystem::permissions(entry.path(), desired_perms, std::filesystem::perm_options::add);
|
||||
}
|
||||
else if (std::filesystem::is_directory(entry.path())) {
|
||||
make_shell_files_executable(entry.path());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string requote(std::string str) {
|
||||
return quote(trim(dequote(trim(str))));
|
||||
}
|
||||
|
@ -41,4 +41,6 @@ std::string replace_with_environment_variables_like_bash(std::string str);
|
||||
|
||||
std::string random_alphanumeric_string(int length);
|
||||
|
||||
void make_shell_files_executable(const std::string& dir_path);
|
||||
|
||||
} // namespace dropshell
|
0
templates/dropshell-agent/_nuke_other.sh
Normal file → Executable file
0
templates/dropshell-agent/_nuke_other.sh
Normal file → Executable file
0
templates/dropshell-agent/install.sh
Normal file → Executable file
0
templates/dropshell-agent/install.sh
Normal file → Executable file
0
templates/dropshell-agent/shared/_allservicesstatus.sh
Normal file → Executable file
0
templates/dropshell-agent/shared/_allservicesstatus.sh
Normal file → Executable file
0
templates/dropshell-agent/shared/_autocommands.sh
Normal file → Executable file
0
templates/dropshell-agent/shared/_autocommands.sh
Normal file → Executable file
0
templates/dropshell-agent/shared/_common.sh
Normal file → Executable file
0
templates/dropshell-agent/shared/_common.sh
Normal file → Executable file
0
templates/dropshell-agent/uninstall.sh
Normal file → Executable file
0
templates/dropshell-agent/uninstall.sh
Normal file → Executable file
0
templates/squashkiwi/backup.sh
Normal file → Executable file
0
templates/squashkiwi/backup.sh
Normal file → Executable file
0
templates/squashkiwi/install.sh
Normal file → Executable file
0
templates/squashkiwi/install.sh
Normal file → Executable file
0
templates/squashkiwi/logs.sh
Normal file → Executable file
0
templates/squashkiwi/logs.sh
Normal file → Executable file
0
templates/squashkiwi/nuke.sh
Normal file → Executable file
0
templates/squashkiwi/nuke.sh
Normal file → Executable file
0
templates/squashkiwi/ports.sh
Normal file → Executable file
0
templates/squashkiwi/ports.sh
Normal file → Executable file
0
templates/squashkiwi/restore.sh
Normal file → Executable file
0
templates/squashkiwi/restore.sh
Normal file → Executable file
0
templates/squashkiwi/ssh.sh
Normal file → Executable file
0
templates/squashkiwi/ssh.sh
Normal file → Executable file
0
templates/squashkiwi/start.sh
Normal file → Executable file
0
templates/squashkiwi/start.sh
Normal file → Executable file
0
templates/squashkiwi/status.sh
Normal file → Executable file
0
templates/squashkiwi/status.sh
Normal file → Executable file
0
templates/squashkiwi/stop.sh
Normal file → Executable file
0
templates/squashkiwi/stop.sh
Normal file → Executable file
0
templates/squashkiwi/uninstall.sh
Normal file → Executable file
0
templates/squashkiwi/uninstall.sh
Normal file → Executable file
Loading…
x
Reference in New Issue
Block a user