1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
|
#include "SSHRemoteProcess.hpp"
#if USE_SFTP
#include "cl_command_event.h"
#include "processreaderthread.h"
#include "file_logger.h"
#include <wx/utils.h>
bool do_ssh_write(clSSHChannel::Ptr_t channel, const wxString& buffer)
{
try {
if(!channel->IsInteractive()) {
channel->Execute(buffer);
} else {
channel->Write(buffer);
}
} catch(clException& e) {
clERROR() << e.What();
return false;
}
return true;
}
SSHRemoteProcess::SSHRemoteProcess(wxEvtHandler* owner, clSSH::Ptr_t ssh, clSSHChannel::eChannelType type)
: IProcess(NULL)
, m_owner(owner)
{
m_channel.reset(new clSSHChannel(ssh, type, this));
m_channel->Open(); // may throw
Bind(wxEVT_SSH_CHANNEL_PTY, &SSHRemoteProcess::OnPty, this);
Bind(wxEVT_SSH_CHANNEL_WRITE_ERROR, &SSHRemoteProcess::OnError, this);
Bind(wxEVT_SSH_CHANNEL_READ_ERROR, &SSHRemoteProcess::OnError, this);
Bind(wxEVT_SSH_CHANNEL_CLOSED, &SSHRemoteProcess::OnTerminate, this);
Bind(wxEVT_SSH_CHANNEL_READ_OUTPUT, &SSHRemoteProcess::OnOutput, this);
}
SSHRemoteProcess::~SSHRemoteProcess() {}
void SSHRemoteProcess::Cleanup() { Detach(); }
void SSHRemoteProcess::Detach()
{
try {
m_channel->SendSignal(wxSIGTERM);
m_channel->Close();
m_channel.reset(nullptr);
} catch(clException& e) {
clWARNING() << "SSHRemoteProcess::Detach:" << e.What();
}
}
bool SSHRemoteProcess::IsAlive() { return m_channel->IsOpen(); }
bool SSHRemoteProcess::Read(wxString& buff, wxString& buffErr)
{
wxUnusedVar(buff);
wxUnusedVar(buffErr);
return false;
}
void SSHRemoteProcess::Terminate()
{
Detach();
clProcessEvent e(wxEVT_ASYNC_PROCESS_TERMINATED);
GetOwner()->AddPendingEvent(e);
}
bool SSHRemoteProcess::Write(const std::string& buff) { return do_ssh_write(m_channel, buff); }
bool SSHRemoteProcess::Write(const wxString& buff) { return do_ssh_write(m_channel, buff); }
bool SSHRemoteProcess::WriteRaw(const std::string& buff) { return do_ssh_write(m_channel, buff); }
bool SSHRemoteProcess::WriteRaw(const wxString& buff) { return do_ssh_write(m_channel, buff); }
bool SSHRemoteProcess::WriteToConsole(const wxString& buff) { return do_ssh_write(m_channel, buff); }
IProcess* SSHRemoteProcess::Create(wxEvtHandler* owner, clSSH::Ptr_t ssh, const wxString& command, bool interactive)
{
try {
SSHRemoteProcess* process = new SSHRemoteProcess(
owner, ssh, interactive ? clSSHChannel::kInterativeMode : clSSHChannel::kRemoteCommand);
if(!command.IsEmpty()) { process->Write(command); }
return process;
} catch(clException& e) {
return NULL;
}
}
void SSHRemoteProcess::OnError(clCommandEvent& event)
{
wxString msg = event.GetString(); // contains the error message
clDEBUG() << "ssh error:" << msg;
// Convert it to
Terminate();
}
void SSHRemoteProcess::OnTerminate(clCommandEvent& event) { Terminate(); }
void SSHRemoteProcess::OnOutput(clCommandEvent& event)
{
clProcessEvent e(wxEVT_ASYNC_PROCESS_OUTPUT);
e.SetOutput(event.GetString());
e.SetEventObject(this);
GetOwner()->AddPendingEvent(e);
}
void SSHRemoteProcess::OnPty(clCommandEvent& event) { SetPty(event.GetString()); }
void SSHRemoteProcess::Signal(wxSignal sig)
{
try {
m_channel->SendSignal(sig);
} catch(clException& e) {
clWARNING() << "SSHRemoteProcess::Signal():" << e.What();
}
}
#endif
|