SSH: Implement pseudo terminal support.

Untested yet, because SSH tests are currently broken.
(They are fixed in 2.2 and will be merged back soon.)
This commit is contained in:
Christian Kandeler
2011-04-01 10:08:09 +02:00
parent 5488849c40
commit 7373155c0a
6 changed files with 45 additions and 3 deletions

View File

@@ -154,6 +154,23 @@ void SshOutgoingPacket::generateEnvPacket(quint32 remoteChannel,
.appendBool(false).appendString(var).appendString(value).finalize(); .appendBool(false).appendString(var).appendString(value).finalize();
} }
void SshOutgoingPacket::generatePtyRequestPacket(quint32 remoteChannel,
const SshPseudoTerminal &terminal)
{
init(SSH_MSG_CHANNEL_REQUEST).appendInt(remoteChannel)
.appendString("pty-req").appendBool(false)
.appendString(terminal.termType).appendInt(terminal.columnCount)
.appendInt(terminal.rowCount);
QByteArray modeString;
for (SshPseudoTerminal::ModeMap::ConstIterator it = terminal.modes.constBegin();
it != terminal.modes.constEnd(); ++it) {
modeString += encodeInt(static_cast<quint8>(it.key()));
modeString += encodeInt(it.value());
}
modeString += encodeInt(static_cast<quint8>(0)); // TTY_OP_END
appendString(modeString).finalize();
}
void SshOutgoingPacket::generateExecPacket(quint32 remoteChannel, void SshOutgoingPacket::generateExecPacket(quint32 remoteChannel,
const QByteArray &command) const QByteArray &command)
{ {

View File

@@ -36,6 +36,8 @@
#include "sshpacket_p.h" #include "sshpacket_p.h"
#include "sshpseudoterminal.h"
namespace Utils { namespace Utils {
namespace Internal { namespace Internal {
@@ -65,6 +67,8 @@ public:
quint32 maxPacketSize); quint32 maxPacketSize);
void generateEnvPacket(quint32 remoteChannel, const QByteArray &var, void generateEnvPacket(quint32 remoteChannel, const QByteArray &var,
const QByteArray &value); const QByteArray &value);
void generatePtyRequestPacket(quint32 remoteChannel,
const SshPseudoTerminal &terminal);
void generateExecPacket(quint32 remoteChannel, const QByteArray &command); void generateExecPacket(quint32 remoteChannel, const QByteArray &command);
void generateSftpPacket(quint32 remoteChannel); void generateSftpPacket(quint32 remoteChannel);
void generateWindowAdjustPacket(quint32 remoteChannel, quint32 bytesToAdd); void generateWindowAdjustPacket(quint32 remoteChannel, quint32 bytesToAdd);

View File

@@ -39,6 +39,8 @@
#include <botan/exceptn.h> #include <botan/exceptn.h>
#include <utils/qtcassert.h>
#include <QtCore/QTimer> #include <QtCore/QTimer>
/*! /*!
@@ -57,8 +59,8 @@
Therefore, the only sensible use case for calling closeChannel() is to Therefore, the only sensible use case for calling closeChannel() is to
get rid of an SshRemoteProces object before the process is actually started. get rid of an SshRemoteProces object before the process is actually started.
Note that the process does not have a terminal, so you can't use it If the process needs a pseudo terminal, you can request one
for applications that require one. via requestTerminal() before calling start().
*/ */
namespace Utils { namespace Utils {
@@ -105,6 +107,13 @@ void SshRemoteProcess::addToEnvironment(const QByteArray &var, const QByteArray
d->m_env << qMakePair(var, value); // Cached locally and sent on start() d->m_env << qMakePair(var, value); // Cached locally and sent on start()
} }
void SshRemoteProcess::requestTerminal(const SshPseudoTerminal &terminal)
{
QTC_ASSERT(d->channelState() == Internal::SshRemoteProcessPrivate::Inactive, return);
d->m_useTerminal = true;
d->m_terminal = terminal;
}
void SshRemoteProcess::start() void SshRemoteProcess::start()
{ {
if (d->channelState() == Internal::SshRemoteProcessPrivate::Inactive) { if (d->channelState() == Internal::SshRemoteProcessPrivate::Inactive) {
@@ -154,7 +163,8 @@ namespace Internal {
SshRemoteProcessPrivate::SshRemoteProcessPrivate(const QByteArray &command, SshRemoteProcessPrivate::SshRemoteProcessPrivate(const QByteArray &command,
quint32 channelId, SshSendFacility &sendFacility, SshRemoteProcess *proc) quint32 channelId, SshSendFacility &sendFacility, SshRemoteProcess *proc)
: AbstractSshChannel(channelId, sendFacility), m_procState(NotYetStarted), : AbstractSshChannel(channelId, sendFacility), m_procState(NotYetStarted),
m_wasRunning(false), m_exitCode(0), m_command(command), m_proc(proc) m_wasRunning(false), m_exitCode(0), m_command(command),
m_useTerminal(false), m_proc(proc)
{ {
} }
@@ -189,6 +199,10 @@ void SshRemoteProcessPrivate::handleOpenSuccessInternal()
envVar.second); envVar.second);
} }
if (m_useTerminal) {
// TODO: Encode m_terminal
}
m_sendFacility.sendExecPacket(remoteChannel(), m_command); m_sendFacility.sendExecPacket(remoteChannel(), m_command);
setProcState(ExecRequested); setProcState(ExecRequested);
m_timeoutTimer->start(ReplyTimeout); m_timeoutTimer->start(ReplyTimeout);

View File

@@ -44,6 +44,7 @@ class QByteArray;
QT_END_NAMESPACE QT_END_NAMESPACE
namespace Utils { namespace Utils {
class SshPseudoTerminal;
namespace Internal { namespace Internal {
class SshChannelManager; class SshChannelManager;
class SshRemoteProcessPrivate; class SshRemoteProcessPrivate;
@@ -84,6 +85,7 @@ public:
*/ */
void addToEnvironment(const QByteArray &var, const QByteArray &value); void addToEnvironment(const QByteArray &var, const QByteArray &value);
void requestTerminal(const SshPseudoTerminal &terminal);
void start(); void start();
void closeChannel(); void closeChannel();

View File

@@ -34,6 +34,8 @@
#ifndef SSHREMOTEPROCESS_P_H #ifndef SSHREMOTEPROCESS_P_H
#define SSHREMOTEPROCESS_P_H #define SSHREMOTEPROCESS_P_H
#include "sshpseudoterminal.h"
#include "sshchannel_p.h" #include "sshchannel_p.h"
#include <QtCore/QList> #include <QtCore/QList>
@@ -88,6 +90,8 @@ private:
typedef QPair<QByteArray, QByteArray> EnvVar; typedef QPair<QByteArray, QByteArray> EnvVar;
QList<EnvVar> m_env; QList<EnvVar> m_env;
bool m_useTerminal;
SshPseudoTerminal m_terminal;
SshRemoteProcess *m_proc; SshRemoteProcess *m_proc;
}; };

View File

@@ -172,6 +172,7 @@ HEADERS += $$PWD/environment.h \
$$PWD/ssh/sftpchannel_p.h \ $$PWD/ssh/sftpchannel_p.h \
$$PWD/ssh/sshremoteprocessrunner.h \ $$PWD/ssh/sshremoteprocessrunner.h \
$$PWD/ssh/sshconnectionmanager.h \ $$PWD/ssh/sshconnectionmanager.h \
$$PWD/ssh/sshpseudoterminal.h \
$$PWD/statuslabel.h $$PWD/statuslabel.h
FORMS += $$PWD/filewizardpage.ui \ FORMS += $$PWD/filewizardpage.ui \