diff --git a/CMakeLists.txt b/CMakeLists.txt index f29d8c8..f55f6ea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.16) project(QLibssh2 LANGUAGES CXX) -find_package(Qt5 REQUIRED +find_package(Qt6 REQUIRED Core Network ) @@ -27,6 +27,8 @@ add_library(qlibssh2 STATIC src/include/Ssh2Process.h src/include/Ssh2Scp.h src/include/Ssh2Types.h + src/include/Ssh2Debug.h + src/include/Ssh2Channel.h ) target_include_directories(qlibssh2 @@ -39,43 +41,46 @@ target_include_directories(qlibssh2 target_link_libraries(qlibssh2 PUBLIC - Qt5::Core - Qt5::Network + Qt6::Core + Qt6::Network Libssh2::libssh2 + PRIVATE + Qt::CorePrivate ) target_compile_features(qlibssh2 PUBLIC cxx_std_17) -# --- Create installed package -include(CMakePackageConfigHelpers) -include(GNUInstallDirs) -set(PACKAGE_NAME ${CMAKE_PROJECT_NAME}) +if(NOT ${QLIBSSH2_SKIP_INSTALL_PACKAGE}) + # --- Create installed package + include(CMakePackageConfigHelpers) + include(GNUInstallDirs) + set(PACKAGE_NAME ${CMAKE_PROJECT_NAME}) -set(TARGETS_FILE ${CMAKE_INSTALL_LIBDIR}/cmake/${PACKAGE_NAME}/${PACKAGE_NAME}Targets.cmake) -configure_package_config_file( - cmake/${PACKAGE_NAME}Config.cmake.in - ${CMAKE_BINARY_DIR}/${PACKAGE_NAME}Config.cmake - INSTALL_DESTINATION + set(TARGETS_FILE ${CMAKE_INSTALL_LIBDIR}/cmake/${PACKAGE_NAME}/${PACKAGE_NAME}Targets.cmake) + configure_package_config_file( + cmake/${PACKAGE_NAME}Config.cmake.in + ${CMAKE_BINARY_DIR}/${PACKAGE_NAME}Config.cmake + INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PACKAGE_NAME} - PATH_VARS + PATH_VARS TARGETS_FILE -) + ) -get_filename_component(TARGETS_FILE_WLE ${TARGETS_FILE} NAME_WLE) -install(TARGETS qlibssh2 - EXPORT ${TARGETS_FILE_WLE} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} -) -install(EXPORT ${TARGETS_FILE_WLE} - NAMESPACE QLIBSSH2:: - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PACKAGE_NAME} -) -install( - FILES + get_filename_component(TARGETS_FILE_WLE ${TARGETS_FILE} NAME_WLE) + install(TARGETS qlibssh2 + EXPORT ${TARGETS_FILE_WLE} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) + install(EXPORT ${TARGETS_FILE_WLE} + NAMESPACE QLIBSSH2:: + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PACKAGE_NAME} + ) + install( + FILES ${CMAKE_BINARY_DIR}/${PACKAGE_NAME}Config.cmake - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PACKAGE_NAME} -) -install(DIRECTORY src/include/ - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PACKAGE_NAME} -) - + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PACKAGE_NAME} + ) + install(DIRECTORY src/include/ + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PACKAGE_NAME} + ) +endif() diff --git a/src/Ssh2Channel.cpp b/src/Ssh2Channel.cpp index b70b359..7cbc798 100644 --- a/src/Ssh2Channel.cpp +++ b/src/Ssh2Channel.cpp @@ -27,6 +27,9 @@ SOFTWARE. #include +//Qt includes +#include + using namespace qlibssh2; Ssh2Channel::Ssh2Channel(Ssh2Client* ssh2_client) @@ -75,6 +78,11 @@ qint64 Ssh2Channel::readData(char* data, qint64 maxlen) result = -1; } + + if(result == LIBSSH2_ERROR_EAGAIN) { + return 0; + } + return result; } @@ -181,11 +189,14 @@ std::error_code Ssh2Channel::openChannelSession() setSsh2ChannelState(Opening); error_code = Ssh2Error::TryAgain; break; - case 0: + case 0: { QIODevice::open(QIODevice::ReadWrite | QIODevice::Unbuffered); setSsh2ChannelState(Opened); + QIODevicePrivate *d = reinterpret_cast(Ssh2Channel::d_ptr.data()); + d->setReadChannelCount(2); error_code = ssh2_success; break; + } default: { debugSsh2Error(ssh2_method_result); error_code = Ssh2Error::FailedToOpenChannel; @@ -200,7 +211,7 @@ std::error_code Ssh2Channel::closeChannelSession() std::error_code error_code = ssh2_success; libssh2_channel_flush_ex(ssh2_channel_, 0); libssh2_channel_flush_ex(ssh2_channel_, 1); - const int ssh2_method_result = libssh2_channel_send_eof(ssh2_channel_); + const int ssh2_method_result = libssh2_channel_close(ssh2_channel_); switch (ssh2_method_result) { case LIBSSH2_ERROR_EAGAIN: setSsh2ChannelState(ChannelStates::Closing); @@ -216,8 +227,9 @@ std::error_code Ssh2Channel::closeChannelSession() nullptr, nullptr, nullptr); - if (result == 0) + if (result == 0) { exit_signal_ = QString(exit_signal); + } destroyChannel(); } break; default: { @@ -249,9 +261,11 @@ void Ssh2Channel::checkChannelData(const Ssh2Channel::ChannelStream& stream_id) setCurrentReadChannel(1); break; } + const QByteArray data = readAll(); - if (data.size()) + if (data.size()) { emit newChannelData(data, stream_id); + } } QString Ssh2Channel::exitSignal() const diff --git a/src/Ssh2Client.cpp b/src/Ssh2Client.cpp index fc04d33..9558e65 100644 --- a/src/Ssh2Client.cpp +++ b/src/Ssh2Client.cpp @@ -32,6 +32,7 @@ SOFTWARE. #include #include +#include using namespace qlibssh2; @@ -42,19 +43,17 @@ std::atomic ssh2_initializations_count(0); void initializeSsh2() { - if (ssh2_initializations_count == 0) + if (ssh2_initializations_count == 0) { libssh2_init(0); + QObject::connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, + QCoreApplication::instance(), []() + { + libssh2_exit(); + }); + } ssh2_initializations_count++; }; -void freeSsh2() -{ - if (ssh2_initializations_count == 1) - libssh2_exit(); - if (ssh2_initializations_count > 0) - ssh2_initializations_count--; -}; - ssize_t libssh_recv(int socket, void* buffer, size_t length, int flags, void** abstract) { Q_UNUSED(socket); @@ -102,9 +101,8 @@ Ssh2Client::Ssh2Client(Ssh2Settings ssh2_settings, Ssh2Client::~Ssh2Client() { closeSession(); - if (state() == ConnectedState) + if (state() != UnconnectedState) waitForDisconnected(); - freeSsh2(); } void Ssh2Client::connectToHost(const QString& hostName, qint16 port) diff --git a/src/Ssh2Process.cpp b/src/Ssh2Process.cpp index f597889..a503549 100644 --- a/src/Ssh2Process.cpp +++ b/src/Ssh2Process.cpp @@ -85,7 +85,8 @@ void Ssh2Process::onSsh2ChannelStateChanged(const ChannelStates& state) std::error_code Ssh2Process::execSsh2Process() { std::error_code error_code = ssh2_success; - const int ssh2_method_result = libssh2_channel_exec(ssh2Channel(), qPrintable(command_)); + const QByteArray command = command_.toLocal8Bit(); + const int ssh2_method_result = libssh2_channel_exec(ssh2Channel(), command.constData()); switch (ssh2_method_result) { case LIBSSH2_ERROR_EAGAIN: setSsh2ProcessState(Starting); diff --git a/src/Ssh2Types.cpp b/src/Ssh2Types.cpp index fd0e53e..165105a 100644 --- a/src/Ssh2Types.cpp +++ b/src/Ssh2Types.cpp @@ -42,7 +42,7 @@ class Ssh2ErrorCategory : public std::error_category { switch (static_cast(ev)) { case ErrorReadKnownHosts: - return "Error in read known hosts file"; + return "Error in reading known hosts file"; case ErrorWriteKnownHosts: return "Error in writing to known hosts file"; case SessionStartupError: diff --git a/src/Ssh2Channel.h b/src/include/Ssh2Channel.h similarity index 100% rename from src/Ssh2Channel.h rename to src/include/Ssh2Channel.h diff --git a/src/Ssh2Debug.h b/src/include/Ssh2Debug.h similarity index 100% rename from src/Ssh2Debug.h rename to src/include/Ssh2Debug.h