From bd54ba7c5d7a0d57feff6ac9f80919218a856bf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20=C5=A0tikonas?= Date: Wed, 21 Mar 2018 18:01:40 +0100 Subject: [PATCH] Convert copyblocks code from KAuth to DBus calls to helper daemon. --- src/CMakeLists.txt | 2 +- src/backend/corebackendmanager.cpp | 13 ++++-- src/backend/corebackendmanager.h | 12 ++++- src/util/externalcommand.cpp | 71 +++++++++--------------------- src/util/externalcommandhelper.cpp | 51 +++++++++++---------- src/util/externalcommandhelper.h | 7 +-- test/CMakeLists.txt | 13 +++--- test/testdevicescanner.cpp | 2 + test/testinit.cpp | 3 ++ test/testlist.cpp | 3 ++ test/testsmart.cpp | 4 +- 11 files changed, 90 insertions(+), 91 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bf10203..2b6365a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -39,7 +39,7 @@ set(kpmcore_SRCS ki18n_wrap_ui(kpmcore_SRCS ${gui_UIFILES}) add_library(kpmcore SHARED ${kpmcore_SRCS}) -target_link_libraries( kpmcore +target_link_libraries( kpmcore PUBLIC ${UUID_LIBRARIES} ${BLKID_LIBRARIES} Qt5::DBus diff --git a/src/backend/corebackendmanager.cpp b/src/backend/corebackendmanager.cpp index bde70a6..219a899 100644 --- a/src/backend/corebackendmanager.cpp +++ b/src/backend/corebackendmanager.cpp @@ -72,11 +72,18 @@ void CoreBackendManager::startExternalCommandHelper() m_Uuid = QUuid::createUuid().toString(); arguments.insert(QStringLiteral("callerUuid"), Uuid()); action.setArguments(arguments); - KAuth::ExecuteJob *job = action.execute(); - job->start(); + m_job = action.execute(); + job()->start(); QEventLoop loop; - QObject::connect(job, &KAuth::ExecuteJob::newData, [&] () {loop.exit();}); + auto exitLoop = [&] () {loop.exit();}; + auto conn = QObject::connect(job(), &KAuth::ExecuteJob::newData, exitLoop); loop.exec(); + QObject::disconnect(conn); + +} + +KAuth::ExecuteJob* CoreBackendManager::job() { + return m_job; } bool CoreBackendManager::load(const QString& name) diff --git a/src/backend/corebackendmanager.h b/src/backend/corebackendmanager.h index d4f1351..ed04bd7 100644 --- a/src/backend/corebackendmanager.h +++ b/src/backend/corebackendmanager.h @@ -21,6 +21,8 @@ #include "util/libpartitionmanagerexport.h" +#include + #include #include @@ -93,12 +95,18 @@ public: return m_Uuid; } + /** + * @return a pointer to the KAuth job + */ + KAuth::ExecuteJob* job(); + private: void startExternalCommandHelper(); private: - CoreBackend* m_Backend; - QThread* m_KAuthThread; + CoreBackend *m_Backend; + QThread *m_KAuthThread; + KAuth::ExecuteJob *m_job; QString m_Uuid; }; diff --git a/src/util/externalcommand.cpp b/src/util/externalcommand.cpp index ba95df0..790eb05 100644 --- a/src/util/externalcommand.cpp +++ b/src/util/externalcommand.cpp @@ -63,62 +63,31 @@ bool ExternalCommand::startCopyBlocks() bool ExternalCommand::copyBlocks() { bool rval = true; - qint64 blockSize = 10 * 1024 * 1024; // number of bytes per block to copy - qint64 blocksToCopy = m_Source->length() / blockSize; + const qint64 blockSize = 10 * 1024 * 1024; // number of bytes per block to copy - qint64 readOffset = m_Source->firstByte(); - qint64 writeOffset = m_Target->firstByte(); - qint32 copyDirection = 1; - - if (m_Target->firstByte() > m_Source->firstByte()) { - readOffset = m_Source->firstByte() + m_Source->length() - blockSize; - writeOffset = m_Target->firstByte() + m_Source->length() - blockSize; - copyDirection = -1; - } - qint64 lastBlock = m_Source->length() % blockSize; - - //report()->line() << xi18nc("@info:progress", "Copying %1 blocks (%2 bytes) from %3 to %4, direction: %5.", blocksToCopy, m_source.length(), readOffset, writeOffset, copyDirection == 1 ? i18nc("direction: left", "left") : i18nc("direction: right", "right")); - - QString cmd = QStandardPaths::findExecutable(QStringLiteral("dd")); - - if (cmd.isEmpty()) - cmd = QStandardPaths::findExecutable(QStringLiteral("dd"), { QStringLiteral("/sbin/"), QStringLiteral("/usr/sbin/"), QStringLiteral("/usr/local/sbin/") }); - - KAuth::Action action(QStringLiteral("org.kde.kpmcore.externalcommand.copyblockshelper")); - action.setHelperId(QStringLiteral("org.kde.kpmcore.externalcommand")); - - arguments.insert(QStringLiteral("command"), cmd); - arguments.insert(QStringLiteral("sourceDevice"), m_Source->path()); - arguments.insert(QStringLiteral("targetDevice"), m_Target->path()); - arguments.insert(QStringLiteral("blockSize"), blockSize); - arguments.insert(QStringLiteral("blocksToCopy"), blocksToCopy); - arguments.insert(QStringLiteral("readOffset"), readOffset); - arguments.insert(QStringLiteral("writeOffset"), writeOffset); - arguments.insert(QStringLiteral("copyDirection"), copyDirection); - arguments.insert(QStringLiteral("sourceFirstByte"), m_Source->firstByte()); - arguments.insert(QStringLiteral("targetFirstByte"), m_Target->firstByte()); - arguments.insert(QStringLiteral("lastBlock"), lastBlock); - arguments.insert(QStringLiteral("sourceLength"), m_Source->length()); - - action.setArguments(arguments); - action.setTimeout(24 * 3600 * 1000); // set 1 day DBus timeout - - KAuth::ExecuteJob *job = action.execute(); - // TODO KF6:Use new signal-slot syntax - connect(job, SIGNAL(percent(KJob*, unsigned long)), this, SLOT(emitProgress(KJob*, unsigned long))); - connect(job, &KAuth::ExecuteJob::newData, this, &ExternalCommand::emitReport); - - if (!job->exec()) { - qWarning() << "KAuth returned an error code: " << job->errorString(); -// return false; - emit finished(); + if (!QDBusConnection::systemBus().isConnected()) { + qWarning() << "Could not connect to DBus system bus"; return false; } - rval = job->data()[QStringLiteral("success")].toInt(); - setExitCode(!rval); + // TODO KF6:Use new signal-slot syntax + connect(CoreBackendManager::self()->job(), SIGNAL(percent(KJob*, unsigned long)), this, SLOT(emitProgress(KJob*, unsigned long))); + connect(CoreBackendManager::self()->job(), &KAuth::ExecuteJob::newData, this, &ExternalCommand::emitReport); + + QDBusInterface iface(QStringLiteral("org.kde.kpmcore.helperinterface"), QStringLiteral("/Helper"), QStringLiteral("org.kde.kpmcore.externalcommand"), QDBusConnection::systemBus()); + if (iface.isValid()) { + QDBusReply reply = iface.call(QStringLiteral("copyblocks"), CoreBackendManager::self()->Uuid(), m_Source->path(), m_Source->firstByte(), m_Source->length(), m_Target->path(), m_Target->firstByte(), blockSize); + if (reply.isValid()) { + rval = reply.value()[QStringLiteral("success")].toInt(); + qDebug() << rval; + } + else { + qWarning() << reply.error().message(); + } + } emit finished(); + setExitCode(!rval); return rval; } @@ -190,7 +159,7 @@ void ExternalCommand::execute() cmd = QStandardPaths::findExecutable(command(), { QStringLiteral("/sbin/"), QStringLiteral("/usr/sbin/"), QStringLiteral("/usr/local/sbin/") }); if (!QDBusConnection::systemBus().isConnected()) { - qWarning() << "Could not connect to DBus session bus"; + qWarning() << "Could not connect to DBus system bus"; return; } diff --git a/src/util/externalcommandhelper.cpp b/src/util/externalcommandhelper.cpp index ff3c72e..76cf992 100644 --- a/src/util/externalcommandhelper.cpp +++ b/src/util/externalcommandhelper.cpp @@ -59,7 +59,7 @@ ActionReply ExternalCommandHelper::init(const QVariantMap& args) @param size the number of bytes to read @return true on success */ -bool ExternalCommandHelper::readData(QString& sourceDevice, QByteArray& buffer, qint64 offset, qint64 size) +bool ExternalCommandHelper::readData(const QString& sourceDevice, QByteArray& buffer, qint64 offset, qint64 size) { QFile device(sourceDevice); @@ -89,7 +89,7 @@ bool ExternalCommandHelper::readData(QString& sourceDevice, QByteArray& buffer, @param offset offset where to begin writing @return true on success */ -bool ExternalCommandHelper::writeData(QString &targetDevice, QByteArray& buffer, qint64 offset) +bool ExternalCommandHelper::writeData(const QString &targetDevice, const QByteArray& buffer, qint64 offset) { QFile device(targetDevice); if (!device.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Unbuffered)) { @@ -109,26 +109,23 @@ bool ExternalCommandHelper::writeData(QString &targetDevice, QByteArray& buffer, return true; } -ActionReply ExternalCommandHelper::copyblockshelper(const QVariantMap& args) +QVariantMap ExternalCommandHelper::copyblocks(const QString& Uuid, const QString& sourceDevice, const qint64 sourceFirstByte, const qint64 sourceLength, const QString& targetDevice, const qint64 targetFirstByte, const qint64 blockSize) { - m_command = args[QStringLiteral("command")].toString(); - qint64 blockSize = args[QStringLiteral("blockSize")].toLongLong(); - qint64 blocksToCopy = args[QStringLiteral("blocksToCopy")].toLongLong(); - qint64 readOffset = args[QStringLiteral("readOffset")].toLongLong(); - qint64 writeOffset = args[QStringLiteral("writeOffset")].toLongLong(); - qint32 copyDirection = args[QStringLiteral("copyDirection")].toLongLong(); - QString sourceDevice = args[QStringLiteral("sourceDevice")].toString(); - QString targetDevice = args[QStringLiteral("targetDevice")].toString(); - qint64 lastBlock = args[QStringLiteral("lastBlock")].toLongLong(); - qint64 sourceFirstByte = args[QStringLiteral("sourceFirstByte")].toLongLong(); - qint64 targetFirstByte = args[QStringLiteral("targetFirstByte")].toLongLong(); - qint64 sourceLength = args[QStringLiteral("sourceLength")].toLongLong(); + isCallerAuthorized(Uuid); + QVariantMap reply; - QStringList environment = args[QStringLiteral("environment")].toStringList(); + const qint64 blocksToCopy = sourceLength / blockSize; + qint64 readOffset = sourceFirstByte; + qint64 writeOffset = targetFirstByte; + qint32 copyDirection = 1; - ActionReply reply; + if (targetFirstByte > sourceFirstByte) { + readOffset = sourceFirstByte + sourceLength - blockSize; + writeOffset = targetFirstByte + sourceLength - blockSize; + copyDirection = -1; + } - m_cmd.setEnvironment(environment); + const qint64 lastBlock = sourceLength % blockSize; qint64 bytesWritten = 0; qint64 blocksCopied = 0; @@ -193,18 +190,15 @@ ActionReply ExternalCommandHelper::copyblockshelper(const QVariantMap& args) report[QStringLiteral("report")] = xi18ncp("@info:progress argument 2 is a string such as 7 bytes (localized accordingly)", "Copying 1 block (%2) finished.", "Copying %1 blocks (%2) finished.", blocksCopied, i18np("1 byte", "%1 bytes", bytesWritten)); HelperSupport::progressStep(report); - reply.addData(QStringLiteral("success"), rval); + reply[QStringLiteral("success")] = rval; return reply; } QVariantMap ExternalCommandHelper::start(const QString& Uuid, const QString& command, const QStringList& arguments, const QByteArray& input, const QStringList& environment) { + isCallerAuthorized(Uuid); QVariantMap reply; - if (Uuid != m_callerUuid) { - qWarning() << "Caller is not authorized"; - return reply; - } // connect(&cmd, &QProcess::readyReadStandardOutput, this, &ExternalCommandHelper::onReadOutput); @@ -220,8 +214,19 @@ QVariantMap ExternalCommandHelper::start(const QString& Uuid, const QString& com return reply; } +bool ExternalCommandHelper::isCallerAuthorized(const QString& Uuid) +{ + if (Uuid != m_callerUuid) { + qWarning() << "Caller is not authorized"; + return false; + } + + return true; +} + void ExternalCommandHelper::exit(const QString& Uuid) { + isCallerAuthorized(Uuid); m_loop.exit(); } diff --git a/src/util/externalcommandhelper.h b/src/util/externalcommandhelper.h index 0f05eec..7714de3 100644 --- a/src/util/externalcommandhelper.h +++ b/src/util/externalcommandhelper.h @@ -36,17 +36,18 @@ Q_SIGNALS: void quit(); public: - bool readData(QString& sourceDevice, QByteArray& buffer, qint64 offset, qint64 size); - bool writeData(QString& targetDevice, QByteArray& buffer, qint64 offset); + bool readData(const QString& sourceDevice, QByteArray& buffer, qint64 offset, qint64 size); + bool writeData(const QString& targetDevice, const QByteArray& buffer, qint64 offset); public Q_SLOTS: ActionReply init(const QVariantMap& args); Q_SCRIPTABLE QVariantMap start(const QString& Uuid, const QString& command, const QStringList& arguments, const QByteArray& input, const QStringList& environment); + Q_SCRIPTABLE QVariantMap copyblocks(const QString& Uuid, const QString& sourceDevice, const qint64 sourceFirstByte, const qint64 sourceLength, const QString& targetDevice, const qint64 targetFirstByte, const qint64 blockSize); Q_SCRIPTABLE void exit(const QString& Uuid); - ActionReply copyblockshelper(const QVariantMap& args); private: void onReadOutput(); + bool isCallerAuthorized(const QString& Uuid); QEventLoop m_loop; QString m_callerUuid; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 66681e1..25151b8 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -15,11 +15,12 @@ add_compile_options(-fPIC) # Helper macro to link to the helper (for initialization of kpmcore) # and to add a test with the given name. # -add_library(testhelpers OBJECT helpers.cpp) +add_library(testhelpers STATIC helpers.cpp) +target_link_libraries(testhelpers KF5::Auth) macro (kpm_test name) - add_executable(${name} ${ARGN} $) - target_link_libraries(${name} kpmcore) + add_executable(${name} ${ARGN}) + target_link_libraries(${name} testhelpers kpmcore) endmacro() ### @@ -29,13 +30,13 @@ kpm_test(testinit testinit.cpp) # Default backend if(TARGET pmdummybackendplugin) add_test(NAME testinit-dummy COMMAND testinit $) endif() -if(TARGET pmlibpartedbackendplugin) - add_test(NAME testinit-parted COMMAND testinit $) +if(TARGET pmsfdiskbackendplugin) + add_test(NAME testinit-sfdisk COMMAND testinit $) else() return() # All the rest really needs a working backend endif() -set(BACKEND $) +set(BACKEND $) ### # diff --git a/test/testdevicescanner.cpp b/test/testdevicescanner.cpp index 88b2451..d3a39b6 100644 --- a/test/testdevicescanner.cpp +++ b/test/testdevicescanner.cpp @@ -30,6 +30,7 @@ #include "core/partition.h" #include "util/capacity.h" +#include #include #include @@ -63,6 +64,7 @@ PartitionList flatten(PartitionTable *table) int main( int argc, char **argv ) { + QCoreApplication app(argc, argv); if (argc != 2) { KPMCoreInitializer i; diff --git a/test/testinit.cpp b/test/testinit.cpp index 276c0f8..fd97f56 100644 --- a/test/testinit.cpp +++ b/test/testinit.cpp @@ -21,10 +21,13 @@ // the current platform, or if one is named on the command line, // loads that one. Returns 0 on success. +#include + #include "helpers.h" int main( int argc, char** argv ) { + QCoreApplication app(argc, argv); if ( argc != 2 ) { KPMCoreInitializer i; diff --git a/test/testlist.cpp b/test/testlist.cpp index 91ff06a..6b1c9eb 100644 --- a/test/testlist.cpp +++ b/test/testlist.cpp @@ -27,6 +27,7 @@ #include "core/partition.h" #include "util/capacity.h" +#include #include #include @@ -60,6 +61,8 @@ PartitionList flatten(PartitionTable *table) int main( int argc, char **argv ) { + QCoreApplication app(argc, argv); + if (argc != 2) { KPMCoreInitializer i; diff --git a/test/testsmart.cpp b/test/testsmart.cpp index ea5aa72..ad8c098 100644 --- a/test/testsmart.cpp +++ b/test/testsmart.cpp @@ -6,7 +6,7 @@ #include "core/smartstatus.h" #include "core/smartparser.h" -#include +#include #include static QString getDefaultDevicePath(); @@ -15,7 +15,7 @@ static bool testSmartParser(); int main(int argc, char **argv) { - QApplication app(argc, argv); + QCoreApplication app(argc, argv); KPMCoreInitializer i;