diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemoremotemounter.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemoremotemounter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..89c808003c4feedb4649a434a72aa73ed342ec1f --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-maemo/maemoremotemounter.cpp @@ -0,0 +1,309 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "maemoglobal.h" +#include "maemoremotemounter.h" +#include "maemotoolchain.h" + +#include <coreplugin/ssh/sftpchannel.h> +#include <coreplugin/ssh/sshconnection.h> +#include <coreplugin/ssh/sshremoteprocess.h> + +#include <QtCore/QProcess> + +using namespace Core; + +namespace Qt4ProjectManager { +namespace Internal { + +MaemoRemoteMounter::MaemoRemoteMounter(QObject *parent, + const MaemoToolChain *toolchain) + : QObject(parent), m_toolChain(toolchain), m_uploadJobId(SftpInvalidJob), + m_stop(false) +{ +} + +MaemoRemoteMounter::~MaemoRemoteMounter() {} + +void MaemoRemoteMounter::setConnection(const Core::SshConnection::Ptr &connection) +{ + m_connection = connection; +} + +void MaemoRemoteMounter::addMountSpecification(const MaemoMountSpecification &mountSpec) +{ + if (mountSpec.isValid()) + m_mountSpecs << mountSpec; +} + +void MaemoRemoteMounter::mount(const MaemoDeviceConfig &devConfig) +{ + m_devConfig = devConfig; + m_stop = false; + Q_ASSERT(m_utfsServers.isEmpty()); + + if (m_mountSpecs.isEmpty()) + emit mounted(); + else + deployUtfsClient(); +} + +void MaemoRemoteMounter::unmount() +{ + m_stop = false; + if (m_mountSpecs.isEmpty()) { + emit unmounted(); + return; + } + + QString remoteCall; + for (int i = 0; i < m_mountSpecs.count(); ++i) { + remoteCall += QString::fromLocal8Bit("%1 umount %2;") + .arg(MaemoGlobal::remoteSudo(), + m_mountSpecs.at(i).remoteMountPoint); + } + + m_unmountProcess = m_connection->createRemoteProcess(remoteCall.toUtf8()); + connect(m_unmountProcess.data(), SIGNAL(closed(int)), this, + SLOT(handleUnmountProcessFinished(int))); + connect(m_unmountProcess.data(), SIGNAL(errorOutputAvailable(QByteArray)), + this, SIGNAL(remoteErrorOutput(QByteArray))); + m_unmountProcess->start(); +} + +void MaemoRemoteMounter::handleUnmountProcessFinished(int exitStatus) +{ + if (m_stop) + return; + + QString errorMsg; + switch (exitStatus) { + case SshRemoteProcess::FailedToStart: + errorMsg = tr("Could not execute unmount request."); + break; + case SshRemoteProcess::KilledBySignal: + errorMsg = tr("Failure unmounting: %1") + .arg(m_unmountProcess->errorString()); + break; + case SshRemoteProcess::ExitedNormally: + break; + default: + Q_ASSERT_X(false, Q_FUNC_INFO, + "Impossible SshRemoteProcess exit status."); + } + + foreach (const ProcPtr &utfsServer, m_utfsServers) { + utfsServer->terminate(); + utfsServer->waitForFinished(1000); + utfsServer->kill(); + } + m_mountSpecs.clear(); + + if (errorMsg.isEmpty()) + emit unmounted(); + else + emit error(errorMsg); +} + +void MaemoRemoteMounter::stop() +{ + m_stop = true; + if (m_utfsClientUploader) { + disconnect(m_utfsClientUploader.data(), 0, this, 0); + m_utfsClientUploader->closeChannel(); + } + if (m_mountProcess) { + disconnect(m_mountProcess.data(), 0, this, 0); + m_mountProcess->closeChannel(); + } + if (m_unmountProcess) { + disconnect(m_unmountProcess.data(), 0, this, 0); + m_unmountProcess->closeChannel(); + } +} + +void MaemoRemoteMounter::deployUtfsClient() +{ + m_utfsClientUploader = m_connection->createSftpChannel(); + connect(m_utfsClientUploader.data(), SIGNAL(initialized()), this, + SLOT(handleUploaderInitialized())); + connect(m_utfsClientUploader.data(), SIGNAL(initializationFailed(QString)), + this, SLOT(handleUploaderInitializationFailed(QString))); + m_utfsClientUploader->initialize(); +} + +void MaemoRemoteMounter::handleUploaderInitializationFailed(const QString &reason) +{ + if (m_stop) + return; + + emit error(tr("Failed to establish SFTP connection: %1").arg(reason)); +} + +void MaemoRemoteMounter::handleUploaderInitialized() +{ + if (m_stop) + return; + + connect(m_utfsClientUploader.data(), + SIGNAL(finished(Core::SftpJobId, QString)), this, + SLOT(handleUploadFinished(Core::SftpJobId, QString))); + const QString localFile + = m_toolChain->maddeRoot() + QLatin1String("/madlib/armel/utfs-client"); + m_uploadJobId + = m_utfsClientUploader->uploadFile(localFile, utfsClientOnDevice(), + SftpOverwriteExisting); + if (m_uploadJobId == SftpInvalidJob) + emit error(tr("Could not upload UTFS client (%1).").arg(localFile)); +} + +void MaemoRemoteMounter::handleUploadFinished(Core::SftpJobId jobId, + const QString &errorMsg) +{ + if (m_stop) + return; + + if (jobId != m_uploadJobId) { + qWarning("Warning: unknown upload job %d finished.", jobId); + return; + } + + m_uploadJobId = SftpInvalidJob; + if (!errorMsg.isEmpty()) { + emit error(tr("Could not upload UTFS client: %1").arg(errorMsg)); + return; + } + + startUtfsClients(); +} + +void MaemoRemoteMounter::startUtfsClients() +{ + const QString chmodFuse + = MaemoGlobal::remoteSudo() + QLatin1String(" chmod a+r+w /dev/fuse"); + const QString chmodUtfsClient + = QLatin1String("chmod a+x ") + utfsClientOnDevice(); + const QLatin1String andOp(" && "); + QString remoteCall = chmodFuse + andOp + chmodUtfsClient; + for (int i = 0; i < m_mountSpecs.count(); ++i) { + const MaemoMountSpecification &mountSpec = m_mountSpecs.at(i); + const QString mkdir = QString::fromLocal8Bit("%1 mkdir -p %2") + .arg(MaemoGlobal::remoteSudo(), mountSpec.remoteMountPoint); + const QString chmod = QString::fromLocal8Bit("%1 chmod a+r+w+x %2") + .arg(MaemoGlobal::remoteSudo(), mountSpec.remoteMountPoint); + const QString utfsClient + = QString::fromLocal8Bit("%1 -l %2 -r %2 -b %2 %4") + .arg(utfsClientOnDevice()).arg(mountSpec.remotePort) + .arg(mountSpec.remoteMountPoint); + remoteCall += andOp + mkdir + andOp + chmod + andOp + utfsClient; + } + + m_mountProcess = m_connection->createRemoteProcess(remoteCall.toUtf8()); + connect(m_mountProcess.data(), SIGNAL(started()), this, + SLOT(handleUtfsClientsStarted())); + connect(m_mountProcess.data(), SIGNAL(closed(int)), this, + SLOT(handleUtfsClientsFinished(int))); + connect(m_mountProcess.data(), SIGNAL(errorOutputAvailable(QByteArray)), + this, SIGNAL(remoteErrorOutput(QByteArray))); + m_mountProcess->start(); +} + +void MaemoRemoteMounter::handleUtfsClientsStarted() +{ + if (!m_stop) + startUtfsServers(); +} + +void MaemoRemoteMounter::handleUtfsClientsFinished(int exitStatus) +{ + if (m_stop) + return; + + switch (exitStatus) { + case SshRemoteProcess::FailedToStart: + emit error(tr("Could not execute mount request.")); + break; + case SshRemoteProcess::KilledBySignal: + emit error(tr("Failure running UTFS client: %1") + .arg(m_mountProcess->errorString())); + break; + case SshRemoteProcess::ExitedNormally: + if (m_mountProcess->exitCode() != 0) + emit error(tr("Could not execute mount request.")); + break; + default: + Q_ASSERT_X(false, Q_FUNC_INFO, + "Impossible SshRemoteProcess exit status."); + } +} + +void MaemoRemoteMounter::startUtfsServers() +{ + for (int i = 0; i < m_mountSpecs.count(); ++i) { + const MaemoMountSpecification &mountSpec = m_mountSpecs.at(i); + const ProcPtr utfsServerProc(new QProcess); + connect(utfsServerProc.data(), SIGNAL(readyReadStandardError()), this, + SLOT(handleUtfsServerErrorOutput())); + const QString port = QString::number(mountSpec.remotePort); + const QString localSecretOpt = QLatin1String("-l"); + const QString remoteSecretOpt = QLatin1String("-r"); + const QStringList utfsServerArgs = QStringList() << localSecretOpt + << port << remoteSecretOpt << port << QLatin1String("-c") + << (m_devConfig.server.host + QLatin1Char(':') + port) + << mountSpec.localDir; + utfsServerProc->start(utfsServer(), utfsServerArgs); + if (!utfsServerProc->waitForStarted()) { + emit error(tr("Could not start UTFS server: %1") + .arg(utfsServerProc->errorString())); + return; + } + m_utfsServers << utfsServerProc; + } + + emit mounted(); +} + +void MaemoRemoteMounter::handleUtfsServerErrorOutput() +{ + emit remoteErrorOutput(qobject_cast<QProcess *>(sender())->readAllStandardError()); +} + +QString MaemoRemoteMounter::utfsClientOnDevice() const +{ + return MaemoGlobal::homeDirOnDevice(QLatin1String("developer")) + + QLatin1String("/utfs-client"); +} + +QString MaemoRemoteMounter::utfsServer() const +{ + return m_toolChain->maddeRoot() + QLatin1String("/madlib/utfs-server"); +} + +} // namespace Internal +} // namespace Qt4ProjectManager diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemoremotemounter.h b/src/plugins/qt4projectmanager/qt-maemo/maemoremotemounter.h new file mode 100644 index 0000000000000000000000000000000000000000..9324d89eeb4dd540ceb84903a9ef9aa6e3aca31b --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-maemo/maemoremotemounter.h @@ -0,0 +1,109 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef MAEMOREMOTEMOUNTER_H +#define MAEMOREMOTEMOUNTER_H + +#include "maemodeviceconfigurations.h" +#include "maemomountspecification.h" + +#include <coreplugin/ssh/sftpdefs.h> + +#include <QtCore/QList> +#include <QtCore/QObject> +#include <QtCore/QSharedPointer> +#include <QtCore/QString> + +QT_FORWARD_DECLARE_CLASS(QProcess); + +namespace Core { +class SftpChannel; +class SshConnection; +class SshRemoteProcess; +} + +namespace Qt4ProjectManager { +namespace Internal { +class MaemoToolChain; + +class MaemoRemoteMounter : public QObject +{ + Q_OBJECT +public: + MaemoRemoteMounter(QObject *parent, const MaemoToolChain *toolchain); + ~MaemoRemoteMounter(); + void addMountSpecification(const MaemoMountSpecification &mountSpec); + void mount(const MaemoDeviceConfig &devConfig); + void unmount(); + void stop(); + + // Must be connected already. + void setConnection(const QSharedPointer<Core::SshConnection> &connection); + +signals: + void mounted(); + void unmounted(); + void error(const QString &reason); + void remoteErrorOutput(const QByteArray &output); + +private slots: + void handleUploaderInitialized(); + void handleUploaderInitializationFailed(const QString &reason); + void handleUploadFinished(Core::SftpJobId jobId, const QString &error); + void handleUtfsClientsStarted(); + void handleUtfsClientsFinished(int exitStatus); + void handleUtfsServerErrorOutput(); + void handleUnmountProcessFinished(int exitStatus); + +private: + void deployUtfsClient(); + void startUtfsClients(); + void startUtfsServers(); + QString utfsClientOnDevice() const; + QString utfsServer() const; + + const MaemoToolChain * const m_toolChain; + MaemoDeviceConfig m_devConfig; + + QSharedPointer<Core::SshConnection> m_connection; + QList<MaemoMountSpecification> m_mountSpecs; + QSharedPointer<Core::SftpChannel> m_utfsClientUploader; + QSharedPointer<Core::SshRemoteProcess> m_mountProcess; + QSharedPointer<Core::SshRemoteProcess> m_unmountProcess; + Core::SftpJobId m_uploadJobId; + + typedef QSharedPointer<QProcess> ProcPtr; + QList<ProcPtr> m_utfsServers; + bool m_stop; +}; + +} // namespace Internal +} // namespace Qt4ProjectManager + +#endif // MAEMOREMOTEMOUNTER_H diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.cpp index 5701d7ce07dd3cdbb99cf844fc4cb4921b8203c7..22f38873227f5ade5a3fc2865476d6407829c5c4 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.cpp +++ b/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.cpp @@ -74,7 +74,6 @@ void MaemoRunControl::start() } else { emit appendMessage(this, tr("Preparing remote side ..."), false); m_running = true; - m_stopped = false; emit started(); disconnect(m_runner, 0, this, 0); connect(m_runner, SIGNAL(error(QString)), this, @@ -95,12 +94,7 @@ void MaemoRunControl::start() void MaemoRunControl::stop() { - m_stopped = true; - if (m_runner) { - disconnect(m_runner, 0, this, 0); - m_runner->stop(); - } - setFinished(); + m_runner->stop(); } void MaemoRunControl::handleSshError(const QString &error) @@ -122,9 +116,6 @@ void MaemoRunControl::startExecution() void MaemoRunControl::handleRemoteProcessFinished(int exitCode) { - if (m_stopped) - return; - emit appendMessage(this, tr("Finished running remote process. Exit code was %1.").arg(exitCode), false); @@ -155,6 +146,7 @@ void MaemoRunControl::handleError(const QString &errString) void MaemoRunControl::setFinished() { + disconnect(m_runner, 0, this, 0); m_running = false; emit finished(); } diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.h b/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.h index 2acf240213db8acc56eaf361346d7c194fdf549a..dd81e29dbdbbdecbe35fbbec29bf90170edac8a2 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.h +++ b/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.h @@ -72,7 +72,6 @@ private: MaemoRunConfiguration *m_runConfig; // TODO this pointer can be invalid const MaemoDeviceConfig m_devConfig; MaemoSshRunner * const m_runner; - bool m_stopped; bool m_running; }; diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemosshrunner.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemosshrunner.cpp index 7f4870a25afd85c491199e6a50127e69c851467e..bed4bf2dab593f1bb837786d1097f704612bd4e3 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemosshrunner.cpp +++ b/src/plugins/qt4projectmanager/qt-maemo/maemosshrunner.cpp @@ -36,15 +36,14 @@ #include "maemodeviceconfigurations.h" #include "maemoglobal.h" +#include "maemoremotemounter.h" +#include "maemoremotemountsmodel.h" #include "maemorunconfiguration.h" -#include "maemotoolchain.h" -#include <coreplugin/ssh/sftpchannel.h> #include <coreplugin/ssh/sshconnection.h> #include <coreplugin/ssh/sshremoteprocess.h> #include <QtCore/QFileInfo> -#include <QtCore/QProcess> using namespace Core; @@ -54,8 +53,8 @@ namespace Internal { MaemoSshRunner::MaemoSshRunner(QObject *parent, MaemoRunConfiguration *runConfig, bool debugging) : QObject(parent), m_runConfig(runConfig), - m_devConfig(runConfig->deviceConfig()), - m_uploadJobId(SftpInvalidJob), + m_mounter(new MaemoRemoteMounter(this, runConfig->toolchain())), + m_devConfig(runConfig->deviceConfig()), m_shuttingDown(false), m_debugging(debugging) { m_procsToKill @@ -63,6 +62,12 @@ MaemoSshRunner::MaemoSshRunner(QObject *parent, << QLatin1String("utfs-client"); if (debugging) m_procsToKill << QLatin1String("gdbserver"); + connect(m_mounter, SIGNAL(mounted()), this, SLOT(handleMounted())); + connect(m_mounter, SIGNAL(unmounted()), this, SLOT(handleUnmounted())); + connect(m_mounter, SIGNAL(error(QString)), this, + SLOT(handleMounterError(QString))); + connect(m_mounter, SIGNAL(remoteErrorOutput(QByteArray)), this, + SIGNAL(remoteErrorOutput(QByteArray))); } MaemoSshRunner::~MaemoSshRunner() {} @@ -74,23 +79,14 @@ void MaemoSshRunner::setConnection(const QSharedPointer<Core::SshConnection> &co void MaemoSshRunner::start() { - m_mountSpecs.clear(); - const MaemoRemoteMountsModel * const remoteMounts - = m_runConfig->remoteMounts(); - for (int i = 0; i < remoteMounts->mountSpecificationCount(); ++i) { - const MaemoMountSpecification &mountSpec - = remoteMounts->mountSpecificationAt(i); - if (mountSpec.isValid()) - m_mountSpecs << mountSpec; - } - if (m_debugging && m_runConfig->useRemoteGdb()) { - m_mountSpecs << MaemoMountSpecification( - m_runConfig->localDirToMountForRemoteGdb(), - MaemoGlobal::remoteProjectSourcesMountPoint(), - m_devConfig.debuggingPort); + // Should not happen. + if (m_shuttingDown) { + emit error(tr("Can't restart yet, haven't shut down properly.")); + return; } m_stop = false; + m_exitStatus = -1; if (m_connection) disconnect(m_connection.data(), 0, this, 0); const bool reUse = m_connection @@ -110,25 +106,15 @@ void MaemoSshRunner::start() void MaemoSshRunner::stop() { + if (m_shuttingDown) + return; + m_stop = true; disconnect(m_connection.data(), 0, this, 0); - if (m_initialCleaner) - disconnect(m_initialCleaner.data(), 0, this, 0); - if (m_utfsClientUploader) { - disconnect(m_utfsClientUploader.data(), 0, this, 0); - m_utfsClientUploader->closeChannel(); - } - if (m_mountProcess) { - disconnect(m_mountProcess.data(), 0, this, 0); - m_mountProcess->closeChannel(); - } - if (m_debugging || m_runner) { - if (m_runner) { - disconnect(m_runner.data(), 0, this, 0); - m_runner->closeChannel(); - } - cleanup(false); - } + m_mounter->stop(); + if (m_cleaner) + disconnect(m_cleaner.data(), 0, this, 0); + cleanup(false); } void MaemoSshRunner::handleConnected() @@ -147,6 +133,7 @@ void MaemoSshRunner::handleConnectionFailure() void MaemoSshRunner::cleanup(bool initialCleanup) { + m_shuttingDown = !initialCleanup; QString niceKill; QString brutalKill; foreach (const QString &proc, m_procsToKill) { @@ -154,192 +141,80 @@ void MaemoSshRunner::cleanup(bool initialCleanup) brutalKill += QString::fromLocal8Bit("pkill -x -9 %1;").arg(proc); } QString remoteCall = niceKill + QLatin1String("sleep 1; ") + brutalKill; - - for (int i = 0; i < m_mountSpecs.count(); ++i) { - remoteCall += QString::fromLocal8Bit("%1 umount %2;") - .arg(MaemoGlobal::remoteSudo(), m_mountSpecs.at(i).remoteMountPoint); - } remoteCall.remove(remoteCall.count() - 1, 1); // Get rid of trailing semicolon. - SshRemoteProcess::Ptr proc - = m_connection->createRemoteProcess(remoteCall.toUtf8()); - if (initialCleanup) { - m_initialCleaner = proc; - connect(m_initialCleaner.data(), SIGNAL(closed(int)), this, - SLOT(handleInitialCleanupFinished(int))); - } - proc->start(); + m_cleaner = m_connection->createRemoteProcess(remoteCall.toUtf8()); + connect(m_cleaner.data(), SIGNAL(closed(int)), this, + SLOT(handleCleanupFinished(int))); + m_cleaner->start(); } -void MaemoSshRunner::handleInitialCleanupFinished(int exitStatus) +void MaemoSshRunner::handleCleanupFinished(int exitStatus) { Q_ASSERT(exitStatus == SshRemoteProcess::FailedToStart || exitStatus == SshRemoteProcess::KilledBySignal || exitStatus == SshRemoteProcess::ExitedNormally); + if (m_shuttingDown) { + m_mounter->unmount(); + return; + } + if (m_stop) return; - foreach (QProcess *utfsServer, m_utfsServers) { - utfsServer->terminate(); - utfsServer->waitForFinished(1000); - utfsServer->kill(); - } - qDeleteAll(m_utfsServers); if (exitStatus != SshRemoteProcess::ExitedNormally) { emit error(tr("Initial cleanup failed: %1") - .arg(m_initialCleaner->errorString())); - } else if (!m_mountSpecs.isEmpty()) { - deployUtfsClient(); + .arg(m_cleaner->errorString())); } else { - emit readyForExecution(); + m_mounter->setConnection(m_connection); + m_mounter->unmount(); } } -void MaemoSshRunner::deployUtfsClient() -{ - m_utfsClientUploader = m_connection->createSftpChannel(); - connect(m_utfsClientUploader.data(), SIGNAL(initialized()), this, - SLOT(handleUploaderInitialized())); - connect(m_utfsClientUploader.data(), SIGNAL(initializationFailed(QString)), - this, SLOT(handleUploaderInitializationFailed(QString))); - m_utfsClientUploader->initialize(); -} - -void MaemoSshRunner::handleUploaderInitializationFailed(const QString &reason) +void MaemoSshRunner::handleUnmounted() { - if (m_stop) - return; - - emit error(tr("Failed to establish SFTP connection: %1").arg(reason)); -} - -void MaemoSshRunner::handleUploaderInitialized() -{ - if (m_stop) - return; - - connect(m_utfsClientUploader.data(), - SIGNAL(finished(Core::SftpJobId, QString)), this, - SLOT(handleUploadFinished(Core::SftpJobId,QString))); - const MaemoToolChain * const toolChain - = dynamic_cast<const MaemoToolChain *>(m_runConfig->toolchain()); - Q_ASSERT_X(toolChain, Q_FUNC_INFO, - "Impossible: Maemo run configuration has no Maemo Toolchain."); - const QString localFile - = toolChain->maddeRoot() + QLatin1String("/madlib/armel/utfs-client"); - m_uploadJobId - = m_utfsClientUploader->uploadFile(localFile, utfsClientOnDevice(), - SftpOverwriteExisting); - if (m_uploadJobId == SftpInvalidJob) - emit error(tr("Could not upload UTFS client (%1).").arg(localFile)); -} - -void MaemoSshRunner::handleUploadFinished(Core::SftpJobId jobId, - const QString &errorMsg) -{ - if (m_stop) - return; - - if (jobId != m_uploadJobId) { - qWarning("Warning: unknown upload job %d finished.", jobId); + if (m_shuttingDown) { + m_shuttingDown = false; + if (m_exitStatus == SshRemoteProcess::ExitedNormally) { + emit remoteProcessFinished(m_runner->exitCode()); + } else if (m_exitStatus == -1) { + emit remoteProcessFinished(-1); + } else { + emit error(tr("Error running remote process: %1") + .arg(m_runner->errorString())); + } + m_exitStatus = -1; return; } - m_uploadJobId = SftpInvalidJob; - if (!errorMsg.isEmpty()) { - emit error(tr("Could not upload UTFS client: %1").arg(errorMsg)); + if (m_stop) return; - } - startUtfsClients(); -} - -void MaemoSshRunner::startUtfsClients() -{ - const QString chmodFuse - = MaemoGlobal::remoteSudo() + QLatin1String(" chmod a+r+w /dev/fuse"); - const QString chmodUtfsClient - = QLatin1String("chmod a+x ") + utfsClientOnDevice(); - const QLatin1String andOp(" && "); - QString remoteCall = chmodFuse + andOp + chmodUtfsClient; - for (int i = 0; i < m_mountSpecs.count(); ++i) { - const MaemoMountSpecification &mountSpec = m_mountSpecs.at(i); - const QString port = QString::number(mountSpec.remotePort); - const QString mkdir = QString::fromLocal8Bit("%1 mkdir -p %2") - .arg(MaemoGlobal::remoteSudo(), mountSpec.remoteMountPoint); - const QString chmod = QString::fromLocal8Bit("%1 chmod a+r+w+x %2") - .arg(MaemoGlobal::remoteSudo(), mountSpec.remoteMountPoint); - const QString utfsClient - = QString::fromLocal8Bit("%1 -l %2 -r %2 -b %2 %4") - .arg(utfsClientOnDevice()).arg(port) - .arg(mountSpec.remoteMountPoint); - remoteCall += andOp + mkdir + andOp + chmod + andOp + utfsClient; + const MaemoRemoteMountsModel * const remoteMounts + = m_runConfig->remoteMounts(); + for (int i = 0; i < remoteMounts->mountSpecificationCount(); ++i) + m_mounter->addMountSpecification(remoteMounts->mountSpecificationAt(i)); + if (m_debugging && m_runConfig->useRemoteGdb()) { + m_mounter->addMountSpecification(MaemoMountSpecification( + m_runConfig->localDirToMountForRemoteGdb(), + MaemoGlobal::remoteProjectSourcesMountPoint(), + m_devConfig.debuggingPort)); } - - m_mountProcess = m_connection->createRemoteProcess(remoteCall.toUtf8()); - connect(m_mountProcess.data(), SIGNAL(started()), this, - SLOT(handleUtfsClientsStarted())); - connect(m_mountProcess.data(), SIGNAL(closed(int)), this, - SLOT(handleUtfsClientsFinished(int))); - connect(m_mountProcess.data(), SIGNAL(errorOutputAvailable(QByteArray)), - this, SIGNAL(remoteErrorOutput(QByteArray))); - m_mountProcess->start(); -} - -void MaemoSshRunner::handleUtfsClientsStarted() -{ - startUtfsServers(); + m_mounter->mount(m_devConfig); } -void MaemoSshRunner::handleUtfsClientsFinished(int exitStatus) +void MaemoSshRunner::handleMounted() { - if (m_stop) - return; - - switch (exitStatus) { - case SshRemoteProcess::FailedToStart: - emit error(tr("Could not execute mount request.")); - break; - case SshRemoteProcess::KilledBySignal: - emit error(tr("Failure running UTFS client: %1") - .arg(m_mountProcess->errorString())); - break; - case SshRemoteProcess::ExitedNormally: - if (m_mountProcess->exitCode() != 0) - emit error(tr("Could not execute mount request.")); - break; - default: - Q_ASSERT_X(false, Q_FUNC_INFO, - "Impossible SshRemoteProcess exit status."); - } + if (!m_stop) + emit readyForExecution(); } -void MaemoSshRunner::startUtfsServers() +void MaemoSshRunner::handleMounterError(const QString &errorMsg) { - for (int i = 0; i < m_mountSpecs.count(); ++i) { - const MaemoMountSpecification &mountSpec = m_mountSpecs.at(i); - QProcess * const utfsServerProc = new QProcess(this); - connect(utfsServerProc, SIGNAL(readyReadStandardError()), this, - SLOT(handleUtfsServerErrorOutput())); - const QString port = QString::number(mountSpec.remotePort); - const QString localSecretOpt = QLatin1String("-l"); - const QString remoteSecretOpt = QLatin1String("-r"); - const QStringList utfsServerArgs = QStringList() << localSecretOpt - << port << remoteSecretOpt << port << QLatin1String("-c") - << (m_devConfig.server.host + QLatin1Char(':') + port) - << mountSpec.localDir; - utfsServerProc->start(utfsServer(), utfsServerArgs); - if (!utfsServerProc->waitForStarted()) { - delete utfsServerProc; - emit error(tr("Could not start UTFS server: %1") - .arg(utfsServerProc->errorString())); - return; - } - m_utfsServers << utfsServerProc; - } - - emit readyForExecution(); + if (m_shuttingDown) + m_shuttingDown = false; + emit error(errorMsg); } void MaemoSshRunner::startExecution(const QByteArray &remoteCall) @@ -367,38 +242,10 @@ void MaemoSshRunner::handleRemoteProcessFinished(int exitStatus) || exitStatus == SshRemoteProcess::KilledBySignal || exitStatus == SshRemoteProcess::ExitedNormally); - if (m_stop) - return; - - if (exitStatus == SshRemoteProcess::ExitedNormally) { - emit remoteProcessFinished(m_runner->exitCode()); - } else { - emit error(tr("Error running remote process: %1") - .arg(m_runner->errorString())); - } + m_exitStatus = exitStatus; cleanup(false); } -QString MaemoSshRunner::utfsClientOnDevice() const -{ - return MaemoGlobal::homeDirOnDevice(QLatin1String("developer")) - + QLatin1String("/utfs-client"); -} - -QString MaemoSshRunner::utfsServer() const -{ - const MaemoToolChain * const toolChain - = dynamic_cast<const MaemoToolChain *>(m_runConfig->toolchain()); - Q_ASSERT_X(toolChain, Q_FUNC_INFO, - "Impossible: Maemo run configuration has no Maemo Toolchain."); - return toolChain->maddeRoot() + QLatin1String("/madlib/utfs-server"); -} - -void MaemoSshRunner::handleUtfsServerErrorOutput() -{ - emit remoteErrorOutput(qobject_cast<QProcess *>(sender())->readAllStandardError()); -} - } // namespace Internal } // namespace Qt4ProjectManager diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemosshrunner.h b/src/plugins/qt4projectmanager/qt-maemo/maemosshrunner.h index ff045b278669047aa40228d3a5e57945356e9e88..8c8f23b2cac836e744a6c6615ce3bf82ebdf811d 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemosshrunner.h +++ b/src/plugins/qt4projectmanager/qt-maemo/maemosshrunner.h @@ -35,26 +35,20 @@ #ifndef MAEMOSSHRUNNER_H #define MAEMOSSHRUNNER_H -#include <QtCore/QObject> -#include <QtCore/QSharedPointer> - #include "maemodeviceconfigurations.h" -#include "maemoremotemountsmodel.h" - -#include <coreplugin/ssh/sftpdefs.h> +#include <QtCore/QObject> +#include <QtCore/QSharedPointer> #include <QtCore/QStringList> -QT_FORWARD_DECLARE_CLASS(QProcess) - namespace Core { - class SftpChannel; class SshConnection; class SshRemoteProcess; } namespace Qt4ProjectManager { namespace Internal { +class MaemoRemoteMounter; class MaemoRunConfiguration; class MaemoSshRunner : public QObject @@ -85,37 +79,27 @@ signals: private slots: void handleConnected(); void handleConnectionFailure(); - void handleInitialCleanupFinished(int exitStatus); + void handleCleanupFinished(int exitStatus); void handleRemoteProcessFinished(int exitStatus); - void handleUploaderInitialized(); - void handleUploaderInitializationFailed(const QString &reason); - void handleUploadFinished(Core::SftpJobId jobId, const QString &error); - void handleUtfsClientsStarted(); - void handleUtfsClientsFinished(int exitStatus); - void handleUtfsServerErrorOutput(); + void handleMounted(); + void handleUnmounted(); + void handleMounterError(const QString &errorMsg); private: void cleanup(bool initialCleanup); - void deployUtfsClient(); - void startUtfsClients(); - void startUtfsServers(); - QString utfsClientOnDevice() const; - QString utfsServer() const; MaemoRunConfiguration * const m_runConfig; // TODO this pointer can be invalid + MaemoRemoteMounter * const m_mounter; const MaemoDeviceConfig m_devConfig; QSharedPointer<Core::SshConnection> m_connection; QSharedPointer<Core::SshRemoteProcess> m_runner; - QSharedPointer<Core::SshRemoteProcess> m_initialCleaner; - QSharedPointer<Core::SshRemoteProcess> m_mountProcess; - QSharedPointer<Core::SftpChannel> m_utfsClientUploader; + QSharedPointer<Core::SshRemoteProcess> m_cleaner; QStringList m_procsToKill; - QList<QProcess *> m_utfsServers; - QList<MaemoMountSpecification> m_mountSpecs; - Core::SftpJobId m_uploadJobId; bool m_stop; + int m_exitStatus; + bool m_shuttingDown; const bool m_debugging; }; diff --git a/src/plugins/qt4projectmanager/qt-maemo/qt-maemo.pri b/src/plugins/qt4projectmanager/qt-maemo/qt-maemo.pri index dc5c331ba7fd6ed510c0ec4f3f9b270f8dda9612..7ce8871c4cba371fe9283c9adafc6084482a523e 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/qt-maemo.pri +++ b/src/plugins/qt4projectmanager/qt-maemo/qt-maemo.pri @@ -30,7 +30,8 @@ HEADERS += \ $$PWD/maemoremotemountsmodel.h \ $$PWD/maemodeviceenvreader.h \ $$PWD/maemotemplatesmanager.h \ - $$PWD/maemomountspecification.h + $$PWD/maemomountspecification.h \ + $$PWD/maemoremotemounter.h SOURCES += \ $$PWD/maemoconfigtestdialog.cpp \ @@ -62,7 +63,8 @@ SOURCES += \ $$PWD/maemoremotemountsmodel.cpp \ $$PWD/maemodeviceenvreader.cpp \ $$PWD/maemotemplatesmanager.cpp \ - $$PWD/maemomountspecification.cpp + $$PWD/maemomountspecification.cpp \ + $$PWD/maemoremotemounter.cpp FORMS += \ $$PWD/maemoconfigtestdialog.ui \