forked from qt-creator/qt-creator
SSH: Implement recursive upload.
This commit is contained in:
@@ -34,6 +34,7 @@
|
|||||||
#include "sshexception_p.h"
|
#include "sshexception_p.h"
|
||||||
#include "sshsendfacility_p.h"
|
#include "sshsendfacility_p.h"
|
||||||
|
|
||||||
|
#include <QtCore/QDir>
|
||||||
#include <QtCore/QFile>
|
#include <QtCore/QFile>
|
||||||
#include <QtCore/QWeakPointer>
|
#include <QtCore/QWeakPointer>
|
||||||
|
|
||||||
@@ -138,8 +139,8 @@ SftpJobId SftpChannel::uploadFile(const QString &localFilePath,
|
|||||||
QSharedPointer<QFile> localFile(new QFile(localFilePath));
|
QSharedPointer<QFile> localFile(new QFile(localFilePath));
|
||||||
if (!localFile->open(QIODevice::ReadOnly))
|
if (!localFile->open(QIODevice::ReadOnly))
|
||||||
return SftpInvalidJob;
|
return SftpInvalidJob;
|
||||||
return d->createJob(Internal::SftpUpload::Ptr(
|
return d->createJob(Internal::SftpUploadFile::Ptr(
|
||||||
new Internal::SftpUpload(++d->m_nextJobId, remoteFilePath, localFile, mode)));
|
new Internal::SftpUploadFile(++d->m_nextJobId, remoteFilePath, localFile, mode)));
|
||||||
}
|
}
|
||||||
|
|
||||||
SftpJobId SftpChannel::downloadFile(const QString &remoteFilePath,
|
SftpJobId SftpChannel::downloadFile(const QString &remoteFilePath,
|
||||||
@@ -159,6 +160,26 @@ SftpJobId SftpChannel::downloadFile(const QString &remoteFilePath,
|
|||||||
new Internal::SftpDownload(++d->m_nextJobId, remoteFilePath, localFile)));
|
new Internal::SftpDownload(++d->m_nextJobId, remoteFilePath, localFile)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SftpJobId SftpChannel::uploadDir(const QString &localDirPath,
|
||||||
|
const QString &remoteParentDirPath)
|
||||||
|
{
|
||||||
|
if (state() != Initialized)
|
||||||
|
return SftpInvalidJob;
|
||||||
|
const QDir localDir(localDirPath);
|
||||||
|
if (!localDir.exists() || !localDir.isReadable())
|
||||||
|
return SftpInvalidJob;
|
||||||
|
const Internal::SftpUploadDir::Ptr uploadDirOp(
|
||||||
|
new Internal::SftpUploadDir(++d->m_nextJobId));
|
||||||
|
const QString remoteDirPath
|
||||||
|
= remoteParentDirPath + QLatin1Char('/') + localDir.dirName();
|
||||||
|
const Internal::SftpMakeDir::Ptr mkdirOp(
|
||||||
|
new Internal::SftpMakeDir(++d->m_nextJobId, remoteDirPath, uploadDirOp));
|
||||||
|
uploadDirOp->mkdirsInProgress.insert(mkdirOp,
|
||||||
|
Internal::SftpUploadDir::Dir(localDirPath, remoteDirPath));
|
||||||
|
d->createJob(mkdirOp);
|
||||||
|
return uploadDirOp->jobId;
|
||||||
|
}
|
||||||
|
|
||||||
SftpChannel::~SftpChannel()
|
SftpChannel::~SftpChannel()
|
||||||
{
|
{
|
||||||
delete d;
|
delete d;
|
||||||
@@ -300,7 +321,7 @@ void SftpChannelPrivate::handleHandle()
|
|||||||
case AbstractSftpOperation::Download:
|
case AbstractSftpOperation::Download:
|
||||||
handleGetHandle(it);
|
handleGetHandle(it);
|
||||||
break;
|
break;
|
||||||
case AbstractSftpOperation::Upload:
|
case AbstractSftpOperation::UploadFile:
|
||||||
handlePutHandle(it);
|
handlePutHandle(it);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -332,7 +353,9 @@ void SftpChannelPrivate::handleGetHandle(const JobMap::Iterator &it)
|
|||||||
|
|
||||||
void SftpChannelPrivate::handlePutHandle(const JobMap::Iterator &it)
|
void SftpChannelPrivate::handlePutHandle(const JobMap::Iterator &it)
|
||||||
{
|
{
|
||||||
SftpUpload::Ptr op = it.value().staticCast<SftpUpload>();
|
SftpUploadFile::Ptr op = it.value().staticCast<SftpUploadFile>();
|
||||||
|
if (op->parentJob && op->parentJob->hasError)
|
||||||
|
sendTransferCloseHandle(op, it.key());
|
||||||
|
|
||||||
// OpenSSH does not implement the RFC's append functionality, so we
|
// OpenSSH does not implement the RFC's append functionality, so we
|
||||||
// have to emulate it.
|
// have to emulate it.
|
||||||
@@ -359,10 +382,12 @@ void SftpChannelPrivate::handleStatus()
|
|||||||
case AbstractSftpOperation::Download:
|
case AbstractSftpOperation::Download:
|
||||||
handleGetStatus(it, response);
|
handleGetStatus(it, response);
|
||||||
break;
|
break;
|
||||||
case AbstractSftpOperation::Upload:
|
case AbstractSftpOperation::UploadFile:
|
||||||
handlePutStatus(it, response);
|
handlePutStatus(it, response);
|
||||||
break;
|
break;
|
||||||
case AbstractSftpOperation::MakeDir:
|
case AbstractSftpOperation::MakeDir:
|
||||||
|
handleMkdirStatus(it, response);
|
||||||
|
break;
|
||||||
case AbstractSftpOperation::RmDir:
|
case AbstractSftpOperation::RmDir:
|
||||||
case AbstractSftpOperation::Rm:
|
case AbstractSftpOperation::Rm:
|
||||||
case AbstractSftpOperation::Rename:
|
case AbstractSftpOperation::Rename:
|
||||||
@@ -381,6 +406,76 @@ void SftpChannelPrivate::handleStatusGeneric(const JobMap::Iterator &it,
|
|||||||
m_jobs.erase(it);
|
m_jobs.erase(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SftpChannelPrivate::handleMkdirStatus(const JobMap::Iterator &it,
|
||||||
|
const SftpStatusResponse &response)
|
||||||
|
{
|
||||||
|
SftpMakeDir::Ptr op = it.value().staticCast<SftpMakeDir>();
|
||||||
|
if (op->parentJob == SftpUploadDir::Ptr()) {
|
||||||
|
handleStatusGeneric(it, response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (op->parentJob->hasError) {
|
||||||
|
m_jobs.erase(it);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef QMap<SftpMakeDir::Ptr, SftpUploadDir::Dir>::Iterator DirIt;
|
||||||
|
DirIt dirIt = op->parentJob->mkdirsInProgress.find(op);
|
||||||
|
Q_ASSERT(dirIt != op->parentJob->mkdirsInProgress.end());
|
||||||
|
const QString &remoteDir = dirIt.value().remoteDir;
|
||||||
|
if (response.status == SSH_FX_OK) {
|
||||||
|
createDelayedDataAvailableSignal(op->parentJob->jobId,
|
||||||
|
SSH_TR("Created remote directory '%1'.").arg(remoteDir));
|
||||||
|
} else if (response.status == SSH_FX_FAILURE) {
|
||||||
|
createDelayedDataAvailableSignal(op->parentJob->jobId,
|
||||||
|
SSH_TR("Remote directory '%1' already exists.").arg(remoteDir));
|
||||||
|
} else {
|
||||||
|
op->parentJob->setError();
|
||||||
|
createDelayedJobFinishedSignal(op->parentJob->jobId,
|
||||||
|
SSH_TR("Error creating directory '%1': %2")
|
||||||
|
.arg(remoteDir, response.errorString));
|
||||||
|
m_jobs.erase(it);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDir localDir(dirIt.value().localDir);
|
||||||
|
const QFileInfoList &dirInfos
|
||||||
|
= localDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
|
||||||
|
foreach (const QFileInfo &dirInfo, dirInfos) {
|
||||||
|
const QString remoteSubDir = remoteDir + '/' + dirInfo.fileName();
|
||||||
|
const SftpMakeDir::Ptr mkdirOp(
|
||||||
|
new SftpMakeDir(++m_nextJobId, remoteSubDir, op->parentJob));
|
||||||
|
op->parentJob->mkdirsInProgress.insert(mkdirOp,
|
||||||
|
SftpUploadDir::Dir(dirInfo.absoluteFilePath(), remoteSubDir));
|
||||||
|
createJob(mkdirOp);
|
||||||
|
}
|
||||||
|
|
||||||
|
const QFileInfoList &fileInfos = localDir.entryInfoList(QDir::Files);
|
||||||
|
foreach (const QFileInfo &fileInfo, fileInfos) {
|
||||||
|
QSharedPointer<QFile> localFile(new QFile(fileInfo.absoluteFilePath()));
|
||||||
|
if (!localFile->open(QIODevice::ReadOnly)) {
|
||||||
|
op->parentJob->setError();
|
||||||
|
createDelayedJobFinishedSignal(op->parentJob->jobId,
|
||||||
|
SSH_TR("Could not open local file '%1': %2")
|
||||||
|
.arg(fileInfo.absoluteFilePath(), localFile->error()));
|
||||||
|
m_jobs.erase(it);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString remoteFilePath = remoteDir + '/' + fileInfo.fileName();
|
||||||
|
SftpUploadFile::Ptr uploadFileOp(new SftpUploadFile(++m_nextJobId,
|
||||||
|
remoteFilePath, localFile, SftpOverwriteExisting, op->parentJob));
|
||||||
|
createJob(uploadFileOp);
|
||||||
|
op->parentJob->uploadsInProgress.append(uploadFileOp);
|
||||||
|
}
|
||||||
|
|
||||||
|
op->parentJob->mkdirsInProgress.erase(dirIt);
|
||||||
|
if (op->parentJob->mkdirsInProgress.isEmpty()
|
||||||
|
&& op->parentJob->uploadsInProgress.isEmpty())
|
||||||
|
createDelayedJobFinishedSignal(op->parentJob->jobId);
|
||||||
|
m_jobs.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
void SftpChannelPrivate::handleLsStatus(const JobMap::Iterator &it,
|
void SftpChannelPrivate::handleLsStatus(const JobMap::Iterator &it,
|
||||||
const SftpStatusResponse &response)
|
const SftpStatusResponse &response)
|
||||||
{
|
{
|
||||||
@@ -457,29 +552,69 @@ void SftpChannelPrivate::handleGetStatus(const JobMap::Iterator &it,
|
|||||||
void SftpChannelPrivate::handlePutStatus(const JobMap::Iterator &it,
|
void SftpChannelPrivate::handlePutStatus(const JobMap::Iterator &it,
|
||||||
const SftpStatusResponse &response)
|
const SftpStatusResponse &response)
|
||||||
{
|
{
|
||||||
SftpUpload::Ptr job = it.value().staticCast<SftpUpload>();
|
SftpUploadFile::Ptr job = it.value().staticCast<SftpUploadFile>();
|
||||||
switch (job->state) {
|
switch (job->state) {
|
||||||
case SftpUpload::OpenRequested:
|
case SftpUploadFile::OpenRequested: {
|
||||||
createDelayedJobFinishedSignal(job->jobId,
|
bool emitError = false;
|
||||||
errorMessage(response.errorString,
|
if (job->parentJob) {
|
||||||
SSH_TR("Failed to open remote file for writing.")));
|
if (!job->parentJob->hasError) {
|
||||||
|
job->parentJob->setError();
|
||||||
|
emitError = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
emitError = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (emitError) {
|
||||||
|
createDelayedJobFinishedSignal(job->jobId,
|
||||||
|
errorMessage(response.errorString,
|
||||||
|
SSH_TR("Failed to open remote file for writing.")));
|
||||||
|
}
|
||||||
m_jobs.erase(it);
|
m_jobs.erase(it);
|
||||||
break;
|
break;
|
||||||
case SftpUpload::Open:
|
}
|
||||||
|
case SftpUploadFile::Open:
|
||||||
|
if (job->hasError || (job->parentJob && job->parentJob->hasError)) {
|
||||||
|
job->hasError = true;
|
||||||
|
finishTransferRequest(it);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (response.status == SSH_FX_OK) {
|
if (response.status == SSH_FX_OK) {
|
||||||
sendWriteRequest(it);
|
sendWriteRequest(it);
|
||||||
} else if(!job->hasError) {
|
} else {
|
||||||
|
if (job->parentJob)
|
||||||
|
job->parentJob->setError();
|
||||||
reportRequestError(job, errorMessage(response.errorString,
|
reportRequestError(job, errorMessage(response.errorString,
|
||||||
SSH_TR("Failed to write remote file.")));
|
SSH_TR("Failed to write remote file.")));
|
||||||
finishTransferRequest(it);
|
finishTransferRequest(it);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SftpUpload::CloseRequested:
|
case SftpUploadFile::CloseRequested:
|
||||||
Q_ASSERT(job->inFlightCount == 1);
|
Q_ASSERT(job->inFlightCount == 1);
|
||||||
if (!job->hasError) {
|
if (job->hasError || (job->parentJob && job->parentJob->hasError)) {
|
||||||
const QString error = errorMessage(response,
|
m_jobs.erase(it);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.status == SSH_FX_OK) {
|
||||||
|
if (job->parentJob) {
|
||||||
|
job->parentJob->uploadsInProgress.removeOne(job);
|
||||||
|
if (job->parentJob->mkdirsInProgress.isEmpty()
|
||||||
|
&& job->parentJob->uploadsInProgress.isEmpty())
|
||||||
|
createDelayedJobFinishedSignal(job->parentJob->jobId);
|
||||||
|
} else {
|
||||||
|
createDelayedJobFinishedSignal(job->jobId);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const QString error = errorMessage(response.errorString,
|
||||||
SSH_TR("Failed to close remote file."));
|
SSH_TR("Failed to close remote file."));
|
||||||
createDelayedJobFinishedSignal(job->jobId, error);
|
if (job->parentJob) {
|
||||||
|
job->parentJob->setError();
|
||||||
|
createDelayedJobFinishedSignal(job->parentJob->jobId, error);
|
||||||
|
} else {
|
||||||
|
createDelayedJobFinishedSignal(job->jobId, error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
m_jobs.erase(it);
|
m_jobs.erase(it);
|
||||||
break;
|
break;
|
||||||
@@ -559,7 +694,7 @@ void SftpChannelPrivate::handleAttrs()
|
|||||||
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
|
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
|
||||||
"Unexpected SSH_FXP_ATTRS packet.");
|
"Unexpected SSH_FXP_ATTRS packet.");
|
||||||
}
|
}
|
||||||
Q_ASSERT(transfer->type() == AbstractSftpOperation::Upload
|
Q_ASSERT(transfer->type() == AbstractSftpOperation::UploadFile
|
||||||
|| transfer->type() == AbstractSftpOperation::Download);
|
|| transfer->type() == AbstractSftpOperation::Download);
|
||||||
|
|
||||||
if (transfer->type() == AbstractSftpOperation::Download) {
|
if (transfer->type() == AbstractSftpOperation::Download) {
|
||||||
@@ -573,11 +708,19 @@ void SftpChannelPrivate::handleAttrs()
|
|||||||
op->statRequested = false;
|
op->statRequested = false;
|
||||||
spawnReadRequests(op);
|
spawnReadRequests(op);
|
||||||
} else {
|
} else {
|
||||||
SftpUpload::Ptr op = transfer.staticCast<SftpUpload>();
|
SftpUploadFile::Ptr op = transfer.staticCast<SftpUploadFile>();
|
||||||
|
if (op->parentJob && op->parentJob->hasError) {
|
||||||
|
op->hasError = true;
|
||||||
|
sendTransferCloseHandle(op, op->jobId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (response.attrs.sizePresent) {
|
if (response.attrs.sizePresent) {
|
||||||
op->offset = response.attrs.size;
|
op->offset = response.attrs.size;
|
||||||
spawnWriteRequests(it);
|
spawnWriteRequests(it);
|
||||||
} else {
|
} else {
|
||||||
|
if (op->parentJob)
|
||||||
|
op->parentJob->setError();
|
||||||
reportRequestError(op, SSH_TR("Cannot append to remote file: "
|
reportRequestError(op, SSH_TR("Cannot append to remote file: "
|
||||||
"Server does not support file size attribute."));
|
"Server does not support file size attribute."));
|
||||||
sendTransferCloseHandle(op, op->jobId);
|
sendTransferCloseHandle(op, op->jobId);
|
||||||
@@ -662,13 +805,13 @@ void SftpChannelPrivate::removeTransferRequest(const JobMap::Iterator &it)
|
|||||||
|
|
||||||
void SftpChannelPrivate::sendWriteRequest(const JobMap::Iterator &it)
|
void SftpChannelPrivate::sendWriteRequest(const JobMap::Iterator &it)
|
||||||
{
|
{
|
||||||
SftpUpload::Ptr job = it.value().staticCast<SftpUpload>();
|
SftpUploadFile::Ptr job = it.value().staticCast<SftpUploadFile>();
|
||||||
QByteArray data = job->localFile->read(AbstractSftpPacket::MaxDataSize);
|
QByteArray data = job->localFile->read(AbstractSftpPacket::MaxDataSize);
|
||||||
if (job->localFile->error() != QFile::NoError) {
|
if (job->localFile->error() != QFile::NoError) {
|
||||||
if (!job->hasError) {
|
if (job->parentJob)
|
||||||
reportRequestError(job, SSH_TR("Error reading local file: %1")
|
job->parentJob->setError();
|
||||||
.arg(job->localFile->errorString()));
|
reportRequestError(job, SSH_TR("Error reading local file: %1")
|
||||||
}
|
.arg(job->localFile->errorString()));
|
||||||
finishTransferRequest(it);
|
finishTransferRequest(it);
|
||||||
} else if (data.isEmpty()) {
|
} else if (data.isEmpty()) {
|
||||||
finishTransferRequest(it);
|
finishTransferRequest(it);
|
||||||
@@ -681,10 +824,10 @@ void SftpChannelPrivate::sendWriteRequest(const JobMap::Iterator &it)
|
|||||||
|
|
||||||
void SftpChannelPrivate::spawnWriteRequests(const JobMap::Iterator &it)
|
void SftpChannelPrivate::spawnWriteRequests(const JobMap::Iterator &it)
|
||||||
{
|
{
|
||||||
SftpUpload::Ptr op = it.value().staticCast<SftpUpload>();
|
SftpUploadFile::Ptr op = it.value().staticCast<SftpUploadFile>();
|
||||||
op->calculateInFlightCount(AbstractSftpPacket::MaxDataSize);
|
op->calculateInFlightCount(AbstractSftpPacket::MaxDataSize);
|
||||||
sendWriteRequest(it);
|
sendWriteRequest(it);
|
||||||
for (int i = 1; i < op->inFlightCount; ++i)
|
for (int i = 1; !op->hasError && i < op->inFlightCount; ++i)
|
||||||
sendWriteRequest(m_jobs.insert(++m_nextJobId, op));
|
sendWriteRequest(m_jobs.insert(++m_nextJobId, op));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -92,6 +92,8 @@ public:
|
|||||||
const QString &remoteFilePath, SftpOverwriteMode mode);
|
const QString &remoteFilePath, SftpOverwriteMode mode);
|
||||||
SftpJobId downloadFile(const QString &remoteFilePath,
|
SftpJobId downloadFile(const QString &remoteFilePath,
|
||||||
const QString &localFilePath, SftpOverwriteMode mode);
|
const QString &localFilePath, SftpOverwriteMode mode);
|
||||||
|
SftpJobId uploadDir(const QString &localDirPath,
|
||||||
|
const QString &remoteParentDirPath);
|
||||||
|
|
||||||
~SftpChannel();
|
~SftpChannel();
|
||||||
|
|
||||||
|
|||||||
@@ -84,6 +84,8 @@ private:
|
|||||||
|
|
||||||
void handleStatusGeneric(const JobMap::Iterator &it,
|
void handleStatusGeneric(const JobMap::Iterator &it,
|
||||||
const SftpStatusResponse &response);
|
const SftpStatusResponse &response);
|
||||||
|
void handleMkdirStatus(const JobMap::Iterator &it,
|
||||||
|
const SftpStatusResponse &response);
|
||||||
void handleLsStatus(const JobMap::Iterator &it,
|
void handleLsStatus(const JobMap::Iterator &it,
|
||||||
const SftpStatusResponse &response);
|
const SftpStatusResponse &response);
|
||||||
void handleGetStatus(const JobMap::Iterator &it,
|
void handleGetStatus(const JobMap::Iterator &it,
|
||||||
|
|||||||
@@ -31,7 +31,6 @@
|
|||||||
|
|
||||||
#include "sftpoutgoingpacket_p.h"
|
#include "sftpoutgoingpacket_p.h"
|
||||||
|
|
||||||
#include <QtCore/QTime>
|
|
||||||
#include <QtCore/QFile>
|
#include <QtCore/QFile>
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
@@ -44,8 +43,9 @@ AbstractSftpOperation::AbstractSftpOperation(SftpJobId jobId) : jobId(jobId)
|
|||||||
AbstractSftpOperation::~AbstractSftpOperation() { }
|
AbstractSftpOperation::~AbstractSftpOperation() { }
|
||||||
|
|
||||||
|
|
||||||
SftpMakeDir::SftpMakeDir(SftpJobId jobId, const QString &path)
|
SftpMakeDir::SftpMakeDir(SftpJobId jobId, const QString &path,
|
||||||
: AbstractSftpOperation(jobId), remoteDir(path)
|
const SftpUploadDir::Ptr &parentJob)
|
||||||
|
: AbstractSftpOperation(jobId), parentJob(parentJob), remoteDir(path)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,6 +132,8 @@ AbstractSftpTransfer::AbstractSftpTransfer(SftpJobId jobId, const QString &remot
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AbstractSftpTransfer::~AbstractSftpTransfer() {}
|
||||||
|
|
||||||
void AbstractSftpTransfer::calculateInFlightCount(quint32 chunkSize)
|
void AbstractSftpTransfer::calculateInFlightCount(quint32 chunkSize)
|
||||||
{
|
{
|
||||||
if (fileSize == 0) {
|
if (fileSize == 0) {
|
||||||
@@ -159,18 +161,23 @@ SftpOutgoingPacket &SftpDownload::initialPacket(SftpOutgoingPacket &packet)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SftpUpload::SftpUpload(SftpJobId jobId, const QString &remotePath,
|
SftpUploadFile::SftpUploadFile(SftpJobId jobId, const QString &remotePath,
|
||||||
const QSharedPointer<QFile> &localFile, SftpOverwriteMode mode)
|
const QSharedPointer<QFile> &localFile, SftpOverwriteMode mode,
|
||||||
: AbstractSftpTransfer(jobId, remotePath, localFile), mode(mode)
|
const SftpUploadDir::Ptr &parentJob)
|
||||||
|
: AbstractSftpTransfer(jobId, remotePath, localFile),
|
||||||
|
parentJob(parentJob), mode(mode)
|
||||||
{
|
{
|
||||||
fileSize = localFile->size();
|
fileSize = localFile->size();
|
||||||
}
|
}
|
||||||
|
|
||||||
SftpOutgoingPacket &SftpUpload::initialPacket(SftpOutgoingPacket &packet)
|
SftpOutgoingPacket &SftpUploadFile::initialPacket(SftpOutgoingPacket &packet)
|
||||||
{
|
{
|
||||||
state = OpenRequested;
|
state = OpenRequested;
|
||||||
return packet.generateOpenFileForWriting(remotePath, mode, jobId);
|
return packet.generateOpenFileForWriting(remotePath, mode, jobId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SftpUploadDir::~SftpUploadDir() {}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Core
|
} // namespace Core
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
#include "sftpdefs.h"
|
#include "sftpdefs.h"
|
||||||
|
|
||||||
#include <QtCore/QByteArray>
|
#include <QtCore/QByteArray>
|
||||||
|
#include <QtCore/QList>
|
||||||
#include <QtCore/QMap>
|
#include <QtCore/QMap>
|
||||||
#include <QtCore/QSharedPointer>
|
#include <QtCore/QSharedPointer>
|
||||||
|
|
||||||
@@ -49,7 +50,7 @@ struct AbstractSftpOperation
|
|||||||
{
|
{
|
||||||
typedef QSharedPointer<AbstractSftpOperation> Ptr;
|
typedef QSharedPointer<AbstractSftpOperation> Ptr;
|
||||||
enum Type {
|
enum Type {
|
||||||
ListDir, MakeDir, RmDir, Rm, Rename, CreateFile, Download, Upload
|
ListDir, MakeDir, RmDir, Rm, Rename, CreateFile, Download, UploadFile
|
||||||
};
|
};
|
||||||
|
|
||||||
AbstractSftpOperation(SftpJobId jobId);
|
AbstractSftpOperation(SftpJobId jobId);
|
||||||
@@ -64,14 +65,18 @@ private:
|
|||||||
AbstractSftpOperation &operator=(const AbstractSftpOperation &);
|
AbstractSftpOperation &operator=(const AbstractSftpOperation &);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SftpUploadDir;
|
||||||
|
|
||||||
struct SftpMakeDir : public AbstractSftpOperation
|
struct SftpMakeDir : public AbstractSftpOperation
|
||||||
{
|
{
|
||||||
typedef QSharedPointer<SftpMakeDir> Ptr;
|
typedef QSharedPointer<SftpMakeDir> Ptr;
|
||||||
|
|
||||||
SftpMakeDir(SftpJobId jobId, const QString &path);
|
SftpMakeDir(SftpJobId jobId, const QString &path,
|
||||||
|
const QSharedPointer<SftpUploadDir> &parentJob = QSharedPointer<SftpUploadDir>());
|
||||||
virtual Type type() const { return MakeDir; }
|
virtual Type type() const { return MakeDir; }
|
||||||
virtual SftpOutgoingPacket &initialPacket(SftpOutgoingPacket &packet);
|
virtual SftpOutgoingPacket &initialPacket(SftpOutgoingPacket &packet);
|
||||||
|
|
||||||
|
const QSharedPointer<SftpUploadDir> parentJob;
|
||||||
const QString remoteDir;
|
const QString remoteDir;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -152,6 +157,7 @@ struct AbstractSftpTransfer : public AbstractSftpOperationWithHandle
|
|||||||
|
|
||||||
AbstractSftpTransfer(SftpJobId jobId, const QString &remotePath,
|
AbstractSftpTransfer(SftpJobId jobId, const QString &remotePath,
|
||||||
const QSharedPointer<QFile> &localFile);
|
const QSharedPointer<QFile> &localFile);
|
||||||
|
~AbstractSftpTransfer();
|
||||||
void calculateInFlightCount(quint32 chunkSize);
|
void calculateInFlightCount(quint32 chunkSize);
|
||||||
|
|
||||||
static const int MaxInFlightCount;
|
static const int MaxInFlightCount;
|
||||||
@@ -175,18 +181,47 @@ struct SftpDownload : public AbstractSftpTransfer
|
|||||||
SftpJobId eofId;
|
SftpJobId eofId;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SftpUpload : public AbstractSftpTransfer
|
struct SftpUploadFile : public AbstractSftpTransfer
|
||||||
{
|
{
|
||||||
typedef QSharedPointer<SftpUpload> Ptr;
|
typedef QSharedPointer<SftpUploadFile> Ptr;
|
||||||
|
|
||||||
SftpUpload(SftpJobId jobId, const QString &remotePath,
|
SftpUploadFile(SftpJobId jobId, const QString &remotePath,
|
||||||
const QSharedPointer<QFile> &localFile, SftpOverwriteMode mode);
|
const QSharedPointer<QFile> &localFile, SftpOverwriteMode mode,
|
||||||
virtual Type type() const { return Upload; }
|
const QSharedPointer<SftpUploadDir> &parentJob = QSharedPointer<SftpUploadDir>());
|
||||||
|
virtual Type type() const { return UploadFile; }
|
||||||
virtual SftpOutgoingPacket &initialPacket(SftpOutgoingPacket &packet);
|
virtual SftpOutgoingPacket &initialPacket(SftpOutgoingPacket &packet);
|
||||||
|
|
||||||
|
const QSharedPointer<SftpUploadDir> parentJob;
|
||||||
SftpOverwriteMode mode;
|
SftpOverwriteMode mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Composite operation.
|
||||||
|
struct SftpUploadDir
|
||||||
|
{
|
||||||
|
typedef QSharedPointer<SftpUploadDir> Ptr;
|
||||||
|
|
||||||
|
struct Dir {
|
||||||
|
Dir(const QString &l, const QString &r) : localDir(l), remoteDir(r) {}
|
||||||
|
QString localDir;
|
||||||
|
QString remoteDir;
|
||||||
|
};
|
||||||
|
|
||||||
|
SftpUploadDir(SftpJobId jobId) : jobId(jobId), hasError(false) {}
|
||||||
|
~SftpUploadDir();
|
||||||
|
|
||||||
|
void setError()
|
||||||
|
{
|
||||||
|
hasError = true;
|
||||||
|
uploadsInProgress.clear();
|
||||||
|
mkdirsInProgress.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
const SftpJobId jobId;
|
||||||
|
bool hasError;
|
||||||
|
QList<SftpUploadFile::Ptr> uploadsInProgress;
|
||||||
|
QMap<SftpMakeDir::Ptr, Dir> mkdirsInProgress;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Core
|
} // namespace Core
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user