Commit 53a1087d authored by Christian Kandeler's avatar Christian Kandeler

Move SSH support into a dedicated library.

It does not belong into libUtils, which is a collection of small
unrelated utility classes.

Task-number: QTCREATORBUG-7218
Change-Id: Id92b9f28678afec93e6f07166adfde6550f38072
Reviewed-by: default avatarEike Ziller <eike.ziller@nokia.com>
parent b9d9bb7b
......@@ -23,6 +23,7 @@ Project {
"src/libs/qmldebug/qmldebug.qbs",
"src/libs/qtcomponents/styleitem/styleitem.qbs",
"src/libs/symbianutils/symbianutils.qbs",
"src/libs/ssh/ssh.qbs",
"src/libs/utils/utils.qbs",
"src/libs/zeroconf/zeroconf.qbs",
"src/plugins/analyzerbase/analyzerbase.qbs",
......
......@@ -16,6 +16,7 @@ SUBDIRS = \
glsl \
qmleditorwidgets \
qtcomponents/styleitem \
ssh \
zeroconf
win32:SUBDIRS += utils/process_ctrlc_stub.pro
......
......@@ -41,7 +41,7 @@
#include <QFile>
/*!
\class Utils::SftpChannel
\class QSsh::SftpChannel
\brief This class provides SFTP operations.
......@@ -65,7 +65,7 @@
Note that directory names must not have a trailing slash.
*/
namespace Utils {
namespace QSsh {
namespace Internal {
namespace {
const quint32 ProtocolVersion = 3;
......@@ -93,13 +93,13 @@ SftpChannel::SftpChannel(quint32 channelId,
Qt::QueuedConnection);
connect(d, SIGNAL(initializationFailed(QString)), this,
SIGNAL(initializationFailed(QString)), Qt::QueuedConnection);
connect(d, SIGNAL(dataAvailable(Utils::SftpJobId,QString)), this,
SIGNAL(dataAvailable(Utils::SftpJobId,QString)), Qt::QueuedConnection);
connect(d, SIGNAL(fileInfoAvailable(Utils::SftpJobId,QList<Utils::SftpFileInfo>)), this,
SIGNAL(fileInfoAvailable(Utils::SftpJobId,QList<Utils::SftpFileInfo>)),
connect(d, SIGNAL(dataAvailable(QSsh::SftpJobId,QString)), this,
SIGNAL(dataAvailable(QSsh::SftpJobId,QString)), Qt::QueuedConnection);
connect(d, SIGNAL(fileInfoAvailable(QSsh::SftpJobId,QList<QSsh::SftpFileInfo>)), this,
SIGNAL(fileInfoAvailable(QSsh::SftpJobId,QList<QSsh::SftpFileInfo>)),
Qt::QueuedConnection);
connect(d, SIGNAL(finished(Utils::SftpJobId,QString)), this,
SIGNAL(finished(Utils::SftpJobId,QString)), Qt::QueuedConnection);
connect(d, SIGNAL(finished(QSsh::SftpJobId,QString)), this,
SIGNAL(finished(QSsh::SftpJobId,QString)), Qt::QueuedConnection);
connect(d, SIGNAL(closed()), this, SIGNAL(closed()), Qt::QueuedConnection);
}
......@@ -977,4 +977,4 @@ void SftpChannelPrivate::spawnReadRequests(const SftpDownload::Ptr &job)
}
} // namespace Internal
} // namespace Utils
} // namespace QSsh
......@@ -36,14 +36,14 @@
#include "sftpdefs.h"
#include "sftpincomingpacket_p.h"
#include <utils/utils_global.h>
#include "ssh_global.h"
#include <QByteArray>
#include <QObject>
#include <QSharedPointer>
#include <QString>
namespace Utils {
namespace QSsh {
namespace Internal {
class SftpChannelPrivate;
......@@ -51,7 +51,7 @@ class SshChannelManager;
class SshSendFacility;
} // namespace Internal
class QTCREATOR_UTILS_EXPORT SftpChannel : public QObject
class QSSH_EXPORT SftpChannel : public QObject
{
Q_OBJECT
......@@ -90,17 +90,17 @@ signals:
void closed();
// error.isEmpty <=> finished successfully
void finished(Utils::SftpJobId job, const QString &error = QString());
void finished(QSsh::SftpJobId job, const QString &error = QString());
// TODO: Also emit for each file copied by uploadDir().
void dataAvailable(Utils::SftpJobId job, const QString &data);
void dataAvailable(QSsh::SftpJobId job, const QString &data);
/*
* This signal is emitted as a result of:
* - statFile() (with the list having exactly one element)
* - listDirectory() (potentially more than once)
*/
void fileInfoAvailable(Utils::SftpJobId job, const QList<Utils::SftpFileInfo> &fileInfoList);
void fileInfoAvailable(QSsh::SftpJobId job, const QList<QSsh::SftpFileInfo> &fileInfoList);
private:
SftpChannel(quint32 channelId, Internal::SshSendFacility &sendFacility);
......@@ -108,6 +108,6 @@ private:
Internal::SftpChannelPrivate *d;
};
} // namespace Utils
} // namespace QSsh
#endif // SFTPCHANNEL_H
......@@ -42,14 +42,14 @@
#include <QByteArray>
#include <QMap>
namespace Utils {
namespace QSsh {
class SftpChannel;
namespace Internal {
class SftpChannelPrivate : public AbstractSshChannel
{
Q_OBJECT
friend class Utils::SftpChannel;
friend class QSsh::SftpChannel;
public:
enum SftpState { Inactive, SubsystemRequested, InitSent, Initialized };
......@@ -63,9 +63,9 @@ signals:
void initialized();
void initializationFailed(const QString &reason);
void closed();
void finished(Utils::SftpJobId job, const QString &error = QString());
void dataAvailable(Utils::SftpJobId job, const QString &data);
void fileInfoAvailable(Utils::SftpJobId job, const QList<Utils::SftpFileInfo> &fileInfoList);
void finished(QSsh::SftpJobId job, const QString &error = QString());
void dataAvailable(QSsh::SftpJobId job, const QString &data);
void fileInfoAvailable(QSsh::SftpJobId job, const QList<QSsh::SftpFileInfo> &fileInfoList);
private:
typedef QMap<SftpJobId, AbstractSftpOperation::Ptr> JobMap;
......@@ -130,6 +130,6 @@ private:
};
} // namespace Internal
} // namespace Utils
} // namespace QSsh
#endif // SFTPCHANNEL_P_H
......@@ -32,4 +32,4 @@
#include "sftpdefs.h"
namespace Utils { const SftpJobId SftpInvalidJob = 0; }
namespace QSsh { const SftpJobId SftpInvalidJob = 0; }
......@@ -33,15 +33,15 @@
#ifndef SFTPDEFS_H
#define SFTPDEFS_H
#include <utils/utils_global.h>
#include "ssh_global.h"
#include <QFile>
#include <QString>
namespace Utils {
namespace QSsh {
typedef quint32 SftpJobId;
QTCREATOR_UTILS_EXPORT extern const SftpJobId SftpInvalidJob;
QSSH_EXPORT extern const SftpJobId SftpInvalidJob;
enum SftpOverwriteMode {
SftpOverwriteExisting, SftpAppendToExisting, SftpSkipExisting
......@@ -49,7 +49,7 @@ enum SftpOverwriteMode {
enum SftpFileType { FileTypeRegular, FileTypeDirectory, FileTypeOther, FileTypeUnknown };
class QTCREATOR_UTILS_EXPORT SftpFileInfo
class QSSH_EXPORT SftpFileInfo
{
public:
SftpFileInfo() : type(FileTypeUnknown), sizeValid(false), permissionsValid(false) { }
......@@ -64,6 +64,6 @@ public:
bool permissionsValid;
};
} // namespace Utils
} // namespace QSsh
#endif // SFTPDEFS_H
......@@ -35,15 +35,13 @@
#include "sshconnection.h"
#include "sshconnectionmanager.h"
#include <utils/qtcassert.h>
#include <QFileInfo>
#include <QHash>
#include <QIcon>
#include <QList>
#include <QString>
namespace Utils {
namespace QSsh {
namespace Internal {
namespace {
......@@ -79,7 +77,7 @@ SftpFileNode *indexToFileNode(const QModelIndex &index)
SftpDirNode *indexToDirNode(const QModelIndex &index)
{
SftpFileNode * const fileNode = indexToFileNode(index);
QTC_CHECK(fileNode);
QSSH_ASSERT(fileNode);
return dynamic_cast<SftpDirNode *>(fileNode);
}
......@@ -116,9 +114,9 @@ SftpFileSystemModel::~SftpFileSystemModel()
void SftpFileSystemModel::setSshConnection(const SshConnectionParameters &sshParams)
{
QTC_ASSERT(!d->sshConnection, return);
QSSH_ASSERT_AND_RETURN(!d->sshConnection);
d->sshConnection = SshConnectionManager::instance().acquireConnection(sshParams);
connect(d->sshConnection.data(), SIGNAL(error(Utils::SshError)),
connect(d->sshConnection.data(), SIGNAL(error(QSsh::SshError)),
SLOT(handleSshConnectionFailure()));
if (d->sshConnection->state() == SshConnection::Connected) {
handleSshConnectionEstablished();
......@@ -148,10 +146,10 @@ QString SftpFileSystemModel::rootDirectory() const
SftpJobId SftpFileSystemModel::downloadFile(const QModelIndex &index, const QString &targetFilePath)
{
QTC_ASSERT(d->rootNode, return SftpInvalidJob);
QSSH_ASSERT_AND_RETURN_VALUE(d->rootNode, SftpInvalidJob);
const SftpFileNode * const fileNode = indexToFileNode(index);
QTC_ASSERT(fileNode, return SftpInvalidJob);
QTC_ASSERT(fileNode->fileInfo.type == FileTypeRegular, return SftpInvalidJob);
QSSH_ASSERT_AND_RETURN_VALUE(fileNode, SftpInvalidJob);
QSSH_ASSERT_AND_RETURN_VALUE(fileNode->fileInfo.type == FileTypeRegular, SftpInvalidJob);
const SftpJobId jobId = d->sftpChannel->downloadFile(fileNode->path, targetFilePath,
SftpOverwriteExisting);
if (jobId != SftpInvalidJob)
......@@ -217,8 +215,8 @@ QModelIndex SftpFileSystemModel::index(int row, int column, const QModelIndex &p
if (!parent.isValid())
return createIndex(row, column, d->rootNode);
const SftpDirNode * const parentNode = indexToDirNode(parent);
QTC_ASSERT(parentNode, return QModelIndex());
QTC_ASSERT(row < parentNode->children.count(), return QModelIndex());
QSSH_ASSERT_AND_RETURN_VALUE(parentNode, QModelIndex());
QSSH_ASSERT_AND_RETURN_VALUE(row < parentNode->children.count(), QModelIndex());
SftpFileNode * const childNode = parentNode->children.at(row);
return createIndex(row, column, childNode);
}
......@@ -229,14 +227,14 @@ QModelIndex SftpFileSystemModel::parent(const QModelIndex &child) const
return QModelIndex();
const SftpFileNode * const childNode = indexToFileNode(child);
QTC_ASSERT(childNode, return QModelIndex());
QSSH_ASSERT_AND_RETURN_VALUE(childNode, QModelIndex());
if (childNode == d->rootNode)
return QModelIndex();
SftpDirNode * const parentNode = childNode->parent;
if (parentNode == d->rootNode)
return createIndex(0, 0, d->rootNode);
const SftpDirNode * const grandParentNode = parentNode->parent;
QTC_ASSERT(grandParentNode, return QModelIndex());
QSSH_ASSERT_AND_RETURN_VALUE(grandParentNode, QModelIndex());
return createIndex(grandParentNode->children.indexOf(parentNode), 0, parentNode);
}
......@@ -290,10 +288,10 @@ void SftpFileSystemModel::handleSshConnectionFailure()
void SftpFileSystemModel::handleSftpChannelInitialized()
{
connect(d->sftpChannel.data(),
SIGNAL(fileInfoAvailable(Utils::SftpJobId,QList<Utils::SftpFileInfo>)),
SLOT(handleFileInfo(Utils::SftpJobId,QList<Utils::SftpFileInfo>)));
connect(d->sftpChannel.data(), SIGNAL(finished(Utils::SftpJobId,QString)),
SLOT(handleSftpJobFinished(Utils::SftpJobId,QString)));
SIGNAL(fileInfoAvailable(QSsh::SftpJobId,QList<QSsh::SftpFileInfo>)),
SLOT(handleFileInfo(QSsh::SftpJobId,QList<QSsh::SftpFileInfo>)));
connect(d->sftpChannel.data(), SIGNAL(finished(QSsh::SftpJobId,QString)),
SLOT(handleSftpJobFinished(QSsh::SftpJobId,QString)));
statRootDirectory();
}
......@@ -317,7 +315,7 @@ void SftpFileSystemModel::handleSftpChannelInitializationFailed(const QString &r
void SftpFileSystemModel::handleFileInfo(SftpJobId jobId, const QList<SftpFileInfo> &fileInfoList)
{
if (jobId == d->statJobId) {
QTC_ASSERT(!d->rootNode, return);
QSSH_ASSERT_AND_RETURN(!d->rootNode);
beginInsertRows(QModelIndex(), 0, 0);
d->rootNode = new SftpDirNode;
d->rootNode->path = d->rootDirectory;
......@@ -328,7 +326,7 @@ void SftpFileSystemModel::handleFileInfo(SftpJobId jobId, const QList<SftpFileIn
return;
}
SftpDirNode * const parentNode = d->lsOps.value(jobId);
QTC_ASSERT(parentNode, return);
QSSH_ASSERT_AND_RETURN(parentNode);
QList<SftpFileInfo> filteredList;
foreach (const SftpFileInfo &fi, fileInfoList) {
if (fi.name != QLatin1String(".") && fi.name != QLatin1String(".."))
......@@ -370,7 +368,7 @@ void SftpFileSystemModel::handleSftpJobFinished(SftpJobId jobId, const QString &
DirNodeHash::Iterator it = d->lsOps.find(jobId);
if (it != d->lsOps.end()) {
QTC_CHECK(it.value()->lsState == SftpDirNode::LsRunning);
QSSH_ASSERT(it.value()->lsState == SftpDirNode::LsRunning);
it.value()->lsState = SftpDirNode::LsFinished;
if (!errorMessage.isEmpty())
emit sftpOperationFailed(tr("Error listing contents of directory '%1': %2")
......@@ -380,9 +378,9 @@ void SftpFileSystemModel::handleSftpJobFinished(SftpJobId jobId, const QString &
}
const int jobIndex = d->externalJobs.indexOf(jobId);
QTC_ASSERT(jobIndex != -1, return);
QSSH_ASSERT_AND_RETURN(jobIndex != -1);
d->externalJobs.removeAt(jobIndex);
emit sftpOperationFinished(jobId, errorMessage);
}
} // namespace Utils
} // namespace QSsh
......@@ -34,17 +34,17 @@
#include "sftpdefs.h"
#include <utils/utils_global.h>
#include "ssh_global.h"
#include <QAbstractItemModel>
namespace Utils {
namespace QSsh {
class SshConnectionParameters;
namespace Internal { class SftpFileSystemModelPrivate; }
// Very simple read-only model. Symbolic links are not followed.
class QTCREATOR_UTILS_EXPORT SftpFileSystemModel : public QAbstractItemModel
class QSSH_EXPORT SftpFileSystemModel : public QAbstractItemModel
{
Q_OBJECT
public:
......@@ -80,15 +80,15 @@ signals:
void connectionError(const QString &errorMessage);
// Success <=> error.isEmpty().
void sftpOperationFinished(Utils::SftpJobId, const QString &error);
void sftpOperationFinished(QSsh::SftpJobId, const QString &error);
private slots:
void handleSshConnectionEstablished();
void handleSshConnectionFailure();
void handleSftpChannelInitialized();
void handleSftpChannelInitializationFailed(const QString &reason);
void handleFileInfo(Utils::SftpJobId jobId, const QList<Utils::SftpFileInfo> &fileInfoList);
void handleSftpJobFinished(Utils::SftpJobId jobId, const QString &errorMessage);
void handleFileInfo(QSsh::SftpJobId jobId, const QList<QSsh::SftpFileInfo> &fileInfoList);
void handleSftpJobFinished(QSsh::SftpJobId jobId, const QString &errorMessage);
private:
int columnCount(const QModelIndex &parent = QModelIndex()) const;
......@@ -105,6 +105,6 @@ private:
Internal::SftpFileSystemModelPrivate * const d;
};
} // namespace Utils;
} // namespace QSsh;
#endif // SFTPFILESYSTEMMODEL_H
......@@ -35,7 +35,7 @@
#include "sshexception_p.h"
#include "sshpacketparser_p.h"
namespace Utils {
namespace QSsh {
namespace Internal {
SftpIncomingPacket::SftpIncomingPacket() : m_length(0)
......@@ -222,4 +222,4 @@ SftpFileAttributes SftpIncomingPacket::asFileAttributes(quint32 &offset) const
}
} // namespace Internal
} // namespace Utils
} // namespace QSsh
......@@ -35,7 +35,7 @@
#include "sftppacket_p.h"
namespace Utils {
namespace QSsh {
namespace Internal {
struct SftpHandleResponse {
......@@ -109,6 +109,6 @@ private:
};
} // namespace Internal
} // namespace Utils
} // namespace QSsh
#endif // SFTPINCOMINGPACKET_P_H
......@@ -36,7 +36,7 @@
#include <QFile>
namespace Utils {
namespace QSsh {
namespace Internal {
AbstractSftpOperation::AbstractSftpOperation(SftpJobId jobId) : jobId(jobId)
......@@ -224,4 +224,4 @@ SftpOutgoingPacket &SftpUploadFile::initialPacket(SftpOutgoingPacket &packet)
SftpUploadDir::~SftpUploadDir() {}
} // namespace Internal
} // namespace Utils
} // namespace QSsh
......@@ -44,7 +44,7 @@ QT_BEGIN_NAMESPACE
class QFile;
QT_END_NAMESPACE
namespace Utils {
namespace QSsh {
namespace Internal {
class SftpOutgoingPacket;
......@@ -249,6 +249,6 @@ struct SftpUploadDir
};
} // namespace Internal
} // namespace Utils
} // namespace QSsh
#endif // SFTPOPERATION_P_H
......@@ -38,7 +38,7 @@
#include <limits>
namespace Utils {
namespace QSsh {
namespace Internal {
namespace {
......@@ -226,4 +226,4 @@ SftpOutgoingPacket &SftpOutgoingPacket::finalize()
const quint32 SftpOutgoingPacket::DefaultPermissions = std::numeric_limits<quint32>::max();
} // namespace Internal
} // namespace Utils
} // namespace QSsh
......@@ -36,7 +36,7 @@
#include "sftppacket_p.h"
#include "sftpdefs.h"
namespace Utils {
namespace QSsh {
namespace Internal {
class SftpOutgoingPacket : public AbstractSftpPacket
......@@ -89,6 +89,6 @@ private:
};
} // namespace Internal
} // namespace Utils
} // namespace QSsh
#endif // SFTPOUTGOINGPACKET_P_H
......@@ -34,7 +34,7 @@
#include "sshpacketparser_p.h"
namespace Utils {
namespace QSsh {
namespace Internal {
const quint32 AbstractSftpPacket::MaxDataSize = 32000;
......@@ -53,4 +53,4 @@ quint32 AbstractSftpPacket::requestId() const
}
} // namespace Internal
} // namespace Utils
} // namespace QSsh
......@@ -37,7 +37,7 @@
#include <QList>
#include <QString>
namespace Utils {
namespace QSsh {
namespace Internal {
enum SftpPacketType {
......@@ -114,6 +114,6 @@ protected:
};
} // namespace Internal
} // namespace Utils
} // namespace QSsh
#endif // SFTPPACKET_P_H
include(ssh_dependencies.pri)
LIBS *= -l$$qtLibraryName(QtcSsh)
TEMPLATE = lib
TARGET = QtcSsh
QT += gui network
DEFINES += QSSH_LIBRARY
include(../../qtcreatorlibrary.pri)
include(ssh_dependencies.pri)
SOURCES = $$PWD/sshsendfacility.cpp \
$$PWD/sshremoteprocess.cpp \
$$PWD/sshpacketparser.cpp \
$$PWD/sshpacket.cpp \
$$PWD/sshoutgoingpacket.cpp \
$$PWD/sshkeygenerator.cpp \
$$PWD/sshkeyexchange.cpp \
$$PWD/sshincomingpacket.cpp \
$$PWD/sshcryptofacility.cpp \
$$PWD/sshconnection.cpp \
$$PWD/sshchannelmanager.cpp \
$$PWD/sshchannel.cpp \
$$PWD/sshcapabilities.cpp \
$$PWD/sftppacket.cpp \
$$PWD/sftpoutgoingpacket.cpp \
$$PWD/sftpoperation.cpp \
$$PWD/sftpincomingpacket.cpp \
$$PWD/sftpdefs.cpp \
$$PWD/sftpchannel.cpp \
$$PWD/sshremoteprocessrunner.cpp \
$$PWD/sshconnectionmanager.cpp \
$$PWD/sshkeypasswordretriever.cpp \
$$PWD/sftpfilesystemmodel.cpp \
$$PWD/sshkeycreationdialog.cpp
HEADERS = $$PWD/sshsendfacility_p.h \
$$PWD/sshremoteprocess.h \
$$PWD/sshremoteprocess_p.h \
$$PWD/sshpacketparser_p.h \
$$PWD/sshpacket_p.h \
$$PWD/sshoutgoingpacket_p.h \
$$PWD/sshkeygenerator.h \
$$PWD/sshkeyexchange_p.h \
$$PWD/sshincomingpacket_p.h \
$$PWD/sshexception_p.h \
$$PWD/ssherrors.h \
$$PWD/sshcryptofacility_p.h \
$$PWD/sshconnection.h \
$$PWD/sshconnection_p.h \
$$PWD/sshchannelmanager_p.h \
$$PWD/sshchannel_p.h \
$$PWD/sshcapabilities_p.h \
$$PWD/sshbotanconversions_p.h \
$$PWD/sftppacket_p.h \
$$PWD/sftpoutgoingpacket_p.h \
$$PWD/sftpoperation_p.h \
$$PWD/sftpincomingpacket_p.h \
$$PWD/sftpdefs.h \
$$PWD/sftpchannel.h \
$$PWD/sftpchannel_p.h \
$$PWD/sshremoteprocessrunner.h \
$$PWD/sshconnectionmanager.h \
$$PWD/sshpseudoterminal.h \
$$PWD/sshkeypasswordretriever_p.h \
$$PWD/sftpfilesystemmodel.h \
$$PWD/sshkeycreationdialog.h \
$$PWD/ssh_global.h
FORMS = $$PWD/sshkeycreationdialog.ui
import qbs.base 1.0
import "../QtcLibrary.qbs" as QtcLibrary
QtcLibrary {