Proof of concept attempt to implement KAuth.

This commit is contained in:
Andrius Štikonas 2017-11-07 22:55:28 +00:00
parent e7b0192630
commit 47429dd1bf
23 changed files with 323 additions and 63 deletions

View File

@ -57,6 +57,7 @@ find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS
# Load the frameworks we need
find_package(KF5 REQUIRED
Auth
I18n
CoreAddons
WidgetsAddons

View File

@ -44,6 +44,7 @@ target_link_libraries( kpmcore
${BLKID_LIBRARIES}
${LIBATASMART_LIBRARIES}
Qt5::DBus
KF5::Auth
KF5::I18n
KF5::CoreAddons
KF5::WidgetsAddons

View File

@ -24,6 +24,7 @@
#include <QStringList>
#include <QString>
#include <QVector>
#include <QThread>
#include <KLocalizedString>
#include <KPluginFactory>
@ -33,6 +34,8 @@
CoreBackendManager::CoreBackendManager() :
m_Backend(nullptr)
{
m_KAuthThread = new QThread();
kauthThread()->start();
}
CoreBackendManager* CoreBackendManager::self()

View File

@ -23,6 +23,7 @@
#include <QVector>
class QThread;
class QString;
class QStringList;
class KPluginMetaData;
@ -77,8 +78,16 @@ public:
return m_Backend;
}
/**
* @return a pointer to the thread where ExternalCommand will start KAuth job
*/
QThread* kauthThread() {
return m_KAuthThread;
}
private:
CoreBackend* m_Backend;
QThread* m_KAuthThread;
};
#endif

View File

@ -177,10 +177,10 @@ bool fat16::updateUUID(Report& report, const QString& deviceNode) const
ExternalCommand cmd(report, QStringLiteral("dd"), { QStringLiteral("of=") + deviceNode , QStringLiteral("bs=1"), QStringLiteral("count=4"), QStringLiteral("seek=39") });
if (!cmd.start())
if (!cmd.write(QByteArray(uuid, sizeof(uuid))))
return false;
if (cmd.write(uuid, sizeof(uuid)) != sizeof(uuid))
if (!cmd.start())
return false;
return cmd.waitFor(-1);

View File

@ -59,10 +59,10 @@ bool fat32::updateUUID(Report& report, const QString& deviceNode) const
// HACK: replace this hack with fatlabel "-i" (dosfstools 4.2)
ExternalCommand cmd(report, QStringLiteral("dd"), { QStringLiteral("of=") + deviceNode, QStringLiteral("bs=1"), QStringLiteral("count=4"), QStringLiteral("seek=67") });
if (!cmd.start())
if (!cmd.write(QByteArray(uuid, sizeof(uuid))))
return false;
if (cmd.write(uuid, sizeof(uuid)) != sizeof(uuid))
if (!cmd.start())
return false;
return cmd.waitFor(-1);

View File

@ -34,6 +34,7 @@
#include <KLocalizedString>
#include <QFileInfo>
#include <QStandardPaths>
#include <QStorageInfo>
const std::array< QColor, FileSystem::__lastType > FileSystem::defaultColorCode =
@ -548,13 +549,14 @@ bool FileSystem::unmount(Report& report, const QString& deviceNode)
return false;
}
// FIXME: args and expectedCode is now unused.
bool FileSystem::findExternal(const QString& cmdName, const QStringList& args, int expectedCode)
{
ExternalCommand cmd(cmdName, args);
if (!cmd.run())
return false;
QString cmd = QStandardPaths::findExecutable(cmdName);
if (cmd.isEmpty())
cmd = QStandardPaths::findExecutable(cmdName, { QStringLiteral("/sbin/"), QStringLiteral("/usr/sbin/"), QStringLiteral("/usr/local/sbin/") });
return cmd.exitCode() == 0 || cmd.exitCode() == expectedCode;
return !cmd.isEmpty();
}
bool FileSystem::supportToolFound() const

View File

@ -96,7 +96,7 @@ qint64 jfs::readUsedCapacity(const QString& deviceNode) const
{
ExternalCommand cmd(QStringLiteral("jfs_debugfs"), QStringList() << deviceNode);
if (cmd.start() && cmd.write("dm") == 2 && cmd.waitFor()) {
if (cmd.write(QByteArrayLiteral("dm")) && cmd.start() && cmd.waitFor()) {
qint64 blockSize = -1;
QRegularExpression re(QStringLiteral("Block Size: (\\d+)"));
QRegularExpressionMatch reBlockSize = re.match(cmd.output());

View File

@ -127,8 +127,8 @@ bool luks::create(Report& report, const QString& deviceNode)
QStringLiteral("--force-password"),
QStringLiteral("luksFormat"),
deviceNode });
if (!( createCmd.start(-1) &&
createCmd.write(m_passphrase.toLocal8Bit() + '\n') == m_passphrase.toLocal8Bit().length() + 1 &&
if (!( createCmd.write(m_passphrase.toLocal8Bit() + '\n') &&
createCmd.start(-1) &&
createCmd.waitFor() && createCmd.exitCode() == 0))
{
return false;
@ -139,7 +139,7 @@ bool luks::create(Report& report, const QString& deviceNode)
deviceNode,
suggestedMapperName(deviceNode) });
if (!( openCmd.start(-1) && openCmd.write(m_passphrase.toLocal8Bit() + '\n') == m_passphrase.toLocal8Bit().length() + 1 && openCmd.waitFor()))
if (!( openCmd.write(m_passphrase.toLocal8Bit() + '\n') && openCmd.start(-1) && openCmd.waitFor()))
return false;
scan(deviceNode);
@ -261,8 +261,8 @@ bool luks::cryptOpen(QWidget* parent, const QString& deviceNode)
deviceNode,
suggestedMapperName(deviceNode) });
if (!( openCmd.start(-1) &&
openCmd.write(passphrase.toLocal8Bit() + '\n') == passphrase.toLocal8Bit().length() + 1 &&
if (!( openCmd.write(passphrase.toLocal8Bit() + '\n') &&
openCmd.start(-1) &&
openCmd.waitFor() && openCmd.exitCode() == 0) )
return false;

View File

@ -125,8 +125,7 @@ qint64 ntfs::readUsedCapacity(const QString& deviceNode) const
bool ntfs::writeLabel(Report& report, const QString& deviceNode, const QString& newLabel)
{
ExternalCommand writeCmd(report, QStringLiteral("ntfslabel"), { QStringLiteral("--force"), deviceNode, newLabel });
writeCmd.setProcessChannelMode(QProcess::SeparateChannels);
ExternalCommand writeCmd(report, QStringLiteral("ntfslabel"), { QStringLiteral("--force"), deviceNode, newLabel }, QProcess::SeparateChannels);
if (!writeCmd.run(-1))
return false;

View File

@ -113,9 +113,9 @@ bool ocfs2::create(Report& report, const QString& deviceNode)
{
ExternalCommand cmd(report, QStringLiteral("mkfs.ocfs2"), { deviceNode });
if (cmd.start())
if (cmd.write("y\n"))
{
cmd.write("y\n");
cmd.start();
cmd.waitFor(-1);
return cmd.exitCode() == 0;

View File

@ -154,12 +154,12 @@ bool reiserfs::resize(Report& report, const QString& deviceNode, qint64 length)
ExternalCommand cmd(report, QStringLiteral("resize_reiserfs"),
{ deviceNode, QStringLiteral("-q"), QStringLiteral("-s"), QString::number(length) });
bool rval = cmd.start(-1);
bool rval = cmd.write(QByteArrayLiteral("y\n"));
if (!rval)
return false;
if (cmd.write("y\n", 2) != 2)
if (!cmd.start(-1))
return false;
return cmd.waitFor(-1) && (cmd.exitCode() == 0 || cmd.exitCode() == 256);

View File

@ -47,8 +47,9 @@ void udf::init()
if (m_Create == cmdSupportFileSystem) {
// Detect old mkudffs prior to version 1.1 by lack of --label option
ExternalCommand cmd(QStringLiteral("mkudffs"), { QStringLiteral("--help") });
oldMkudffsVersion = cmd.run(-1) && !cmd.output().contains(QStringLiteral("--label"));
// ExternalCommand cmd(QStringLiteral("mkudffs"), { QStringLiteral("--help") });
// oldMkudffsVersion = cmd.run(-1) && !cmd.output().contains(QStringLiteral("--label"));
oldMkudffsVersion = false;
}
}

View File

@ -74,8 +74,8 @@ bool SfdiskDevice::createPartitionTable(Report& report, const PartitionTable& pt
tableType = ptable.typeName().toLocal8Bit();
ExternalCommand createCommand(report, QStringLiteral("sfdisk"), { m_device->deviceNode() } );
if ( createCommand.start(-1) && createCommand.write(QByteArrayLiteral("label: ") + tableType +
QByteArrayLiteral("\nwrite\n")) && createCommand.waitFor() ) {
if ( createCommand.write(QByteArrayLiteral("label: ") + tableType +
QByteArrayLiteral("\nwrite\n")) && createCommand.start(-1) && createCommand.waitFor() ) {
return createCommand.output().contains(QStringLiteral("Script header accepted."));
}
@ -112,7 +112,7 @@ bool SfdiskDevice::writeData(QByteArray& buffer, qint64 offset)
QStringLiteral("bs=1M"),
QStringLiteral("oflag=seek_bytes"),
QStringLiteral("conv=fsync") }, QProcess::SeparateChannels);
if ( ddCommand.start(-1) && ddCommand.write(buffer) == buffer.size() && ddCommand.waitFor() && ddCommand.exitCode() == 0 ) {
if ( ddCommand.write(buffer) && ddCommand.start(-1) && ddCommand.waitFor() && ddCommand.exitCode() == 0 ) {
return true;
}

View File

@ -74,9 +74,9 @@ QString SfdiskPartitionTable::createPartition(Report& report, const Partition& p
// NOTE: at least on GPT partition types "are" partition flags
ExternalCommand createCommand(report, QStringLiteral("sfdisk"), { QStringLiteral("--force"), QStringLiteral("--append"), partition.devicePath() } );
if ( createCommand.start(-1) && createCommand.write(QByteArrayLiteral("start=") + QByteArray::number(partition.firstSector()) +
if ( createCommand.write(QByteArrayLiteral("start=") + QByteArray::number(partition.firstSector()) +
type +
QByteArrayLiteral(" size=") + QByteArray::number(partition.length()) + QByteArrayLiteral("\nwrite\n")) && createCommand.waitFor() ) {
QByteArrayLiteral(" size=") + QByteArray::number(partition.length()) + QByteArrayLiteral("\nwrite\n")) && createCommand.start(-1) && createCommand.waitFor() ) {
QRegularExpression re(QStringLiteral("Created a new partition (\\d)"));
QRegularExpressionMatch rem = re.match(createCommand.output());
if (rem.hasMatch())
@ -101,10 +101,10 @@ bool SfdiskPartitionTable::deletePartition(Report& report, const Partition& part
bool SfdiskPartitionTable::updateGeometry(Report& report, const Partition& partition, qint64 sectorStart, qint64 sectorEnd)
{
ExternalCommand sfdiskCommand(report, QStringLiteral("sfdisk"), { QStringLiteral("--force"), partition.devicePath(), QStringLiteral("-N"), QString::number(partition.number()) } );
if ( sfdiskCommand.start(-1) && sfdiskCommand.write(QByteArrayLiteral("start=") + QByteArray::number(sectorStart) +
if ( sfdiskCommand.write(QByteArrayLiteral("start=") + QByteArray::number(sectorStart) +
QByteArrayLiteral(" size=") + QByteArray::number(sectorEnd - sectorStart + 1) +
QByteArrayLiteral("\nY\n"))
&& sfdiskCommand.waitFor() && sfdiskCommand.exitCode() == 0) {
&& sfdiskCommand.start(-1) && sfdiskCommand.waitFor() && sfdiskCommand.exitCode() == 0) {
return true;
}

View File

@ -16,3 +16,10 @@ set(UTIL_LIB_HDRS
util/htmlreport.h
util/report.h
)
add_executable(kpmcore_externalcommand util/externalcommandhelper.cpp)
target_link_libraries(kpmcore_externalcommand KF5::Auth)
install(TARGETS kpmcore_externalcommand DESTINATION ${KAUTH_HELPER_INSTALL_DIR})
kauth_install_helper_files(kpmcore_externalcommand org.kde.kpmcore.externalcommand root)
kauth_install_actions(org.kde.kpmcore.externalcommand util/org.kde.kpmcore.externalcommand.actions)

View File

@ -16,14 +16,20 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
*************************************************************************/
#include "backend/corebackendmanager.h"
#include "util/externalcommand.h"
#include "util/report.h"
#include <QDebug>
#include <QEventLoop>
#include <QtGlobal>
#include <QStandardPaths>
#include <QString>
#include <QStringList>
#include <QTimer>
#include <QThread>
#include <KAuth>
#include <KLocalizedString>
/** Creates a new ExternalCommand instance without Report.
@ -31,7 +37,6 @@
@param args the arguments to pass to the command
*/
ExternalCommand::ExternalCommand(const QString& cmd, const QStringList& args, const QProcess::ProcessChannelMode processChannelMode) :
QProcess(),
m_Report(nullptr),
m_Command(cmd),
m_Args(args),
@ -47,7 +52,6 @@ ExternalCommand::ExternalCommand(const QString& cmd, const QStringList& args, co
@param args the arguments to pass to the command
*/
ExternalCommand::ExternalCommand(Report& report, const QString& cmd, const QStringList& args, const QProcess::ProcessChannelMode processChannelMode) :
QProcess(),
m_Report(report.newChild()),
m_Command(cmd),
m_Args(args),
@ -59,11 +63,11 @@ ExternalCommand::ExternalCommand(Report& report, const QString& cmd, const QStri
void ExternalCommand::setup(const QProcess::ProcessChannelMode processChannelMode)
{
setEnvironment(QStringList() << QStringLiteral("LC_ALL=C") << QStringLiteral("PATH=") + QString::fromLocal8Bit(getenv("PATH")) << QStringLiteral("LVM_SUPPRESS_FD_WARNINGS=1"));
setProcessChannelMode(processChannelMode);
arguments.insert(QStringLiteral("environment"), QStringList() << QStringLiteral("LC_ALL=C") << QStringLiteral("LVM_SUPPRESS_FD_WARNINGS=1"));
arguments.insert(QStringLiteral("processChannelMode"), processChannelMode);
connect(this, qOverload<int, QProcess::ExitStatus>(&QProcess::finished), this, &ExternalCommand::onFinished);
connect(this, &ExternalCommand::readyReadStandardOutput, this, &ExternalCommand::onReadOutput);
// connect(this, qOverload<int, QProcess::ExitStatus>(&QProcess::finished), this, &ExternalCommand::onFinished);
// connect(this, &ExternalCommand::readyReadStandardOutput, this, &ExternalCommand::onReadOutput);
}
/** Starts the external command.
@ -72,19 +76,61 @@ void ExternalCommand::setup(const QProcess::ProcessChannelMode processChannelMod
*/
bool ExternalCommand::start(int timeout)
{
QProcess::start(command(), args());
this->moveToThread(CoreBackendManager::self()->kauthThread());
QTimer::singleShot(0, this, &ExternalCommand::execute);
QEventLoop loop;
connect(this, &ExternalCommand::finished, &loop, &QEventLoop::quit);
loop.exec();
return true;
}
/** Executes the external command in kauthThread() thread.
*/
void ExternalCommand::execute()
{
if (report()) {
report()->setCommand(xi18nc("@info:status", "Command: %1 %2", command(), args().join(QStringLiteral(" "))));
}
if (!waitForStarted(timeout))
{
if (report())
report()->line() << xi18nc("@info:status", "(Command timeout while starting)");
return false;
QString cmd = QStandardPaths::findExecutable(command());
if (cmd.isEmpty())
cmd = QStandardPaths::findExecutable(command(), { QStringLiteral("/sbin/"), QStringLiteral("/usr/sbin/"), QStringLiteral("/usr/local/sbin/") });
KAuth::Action action(QStringLiteral("org.kde.kpmcore.externalcommand.start"));
action.setHelperId(QStringLiteral("org.kde.kpmcore.externalcommand"));
arguments.insert(QStringLiteral("command"), cmd);
arguments.insert(QStringLiteral("input"), m_Input);
arguments.insert(QStringLiteral("arguments"), args());
action.setArguments(arguments);
KAuth::ExecuteJob *job = action.execute();
if (!job->exec()) {
qWarning() << "KAuth returned an error code: " << job->errorString();
// return false;
emit finished();
return;
}
m_Output = job->data()[QStringLiteral("output")].toByteArray();
setExitCode(job->data()[QStringLiteral("exitCode")].toInt());
// QProcess::start(command(), args());
// FIXME
// if (!waitForStarted(timeout))
// {
// if (report())
// report()->line() << xi18nc("@info:status", "(Command timeout while starting)");
// return false;
// }
// return true;
emit finished();
}
bool ExternalCommand::write(const QByteArray& input)
{
m_Input = input;
return true;
}
@ -94,15 +140,15 @@ bool ExternalCommand::start(int timeout)
*/
bool ExternalCommand::waitFor(int timeout)
{
closeWriteChannel();
// closeWriteChannel();
/*
if (!waitForFinished(timeout)) {
if (report())
report()->line() << xi18nc("@info:status", "(Command timeout while running)");
return false;
}
}*/
onReadOutput();
// onReadOutput();
return true;
}
@ -112,23 +158,23 @@ bool ExternalCommand::waitFor(int timeout)
*/
bool ExternalCommand::run(int timeout)
{
return start(timeout) && waitFor(timeout) && exitStatus() == 0;
return start(timeout) && waitFor(timeout)/* && exitStatus() == 0*/;
}
void ExternalCommand::onReadOutput()
{
const QByteArray s = readAllStandardOutput();
if(m_Output.length() > 10*1024*1024) { // prevent memory overflow for badly corrupted file systems
if (report())
report()->line() << xi18nc("@info:status", "(Command is printing too much output)");
return;
}
m_Output += s;
if (report())
*report() << QString::fromLocal8Bit(s);
// const QByteArray s = readAllStandardOutput();
//
// if(m_Output.length() > 10*1024*1024) { // prevent memory overflow for badly corrupted file systems
// if (report())
// report()->line() << xi18nc("@info:status", "(Command is printing too much output)");
// return;
// }
//
// m_Output += s;
//
// if (report())
// *report() << QString::fromLocal8Bit(s);
}
void ExternalCommand::onFinished(int exitCode, QProcess::ExitStatus exitStatus)

View File

@ -21,10 +21,12 @@
#include "util/libpartitionmanagerexport.h"
#include <QDebug>
#include <QtGlobal>
#include <QProcess>
#include <QStringList>
#include <QString>
#include <QtGlobal>
#include <QVariant>
class Report;
@ -35,13 +37,14 @@ class Report;
@author Volker Lanz <vl@fidra.de>
@author Andrius Štikonas <andrius@stikonas.eu>
*/
class LIBKPMCORE_EXPORT ExternalCommand : public QProcess
class LIBKPMCORE_EXPORT ExternalCommand : public QObject
{
Q_OBJECT
Q_DISABLE_COPY(ExternalCommand)
public:
explicit ExternalCommand(const QString& cmd = QString(), const QStringList& args = QStringList(), const QProcess::ProcessChannelMode processChannelMode = MergedChannels);
explicit ExternalCommand(Report& report, const QString& cmd = QString(), const QStringList& args = QStringList(), const QProcess::ProcessChannelMode processChannelMode = MergedChannels);
explicit ExternalCommand(const QString& cmd = QString(), const QStringList& args = QStringList(), const QProcess::ProcessChannelMode processChannelMode = QProcess::MergedChannels);
explicit ExternalCommand(Report& report, const QString& cmd = QString(), const QStringList& args = QStringList(), const QProcess::ProcessChannelMode processChannelMode = QProcess::MergedChannels);
public:
void setCommand(const QString& cmd) { m_Command = cmd; } /**< @param cmd the command to run */
@ -50,6 +53,7 @@ public:
void addArg(const QString& s) { m_Args << s; } /**< @param s the argument to add */
const QStringList& args() const { return m_Args; } /**< @return the arguments */
void setArgs(const QStringList& args) { m_Args = args; } /**< @param args the new arguments */
bool write(const QByteArray& input); /**< @param input the input for the program */
bool start(int timeout = 30000);
bool waitFor(int timeout = 30000);
@ -71,7 +75,12 @@ public:
return m_Report; /**< @return pointer to the Report or nullptr */
}
Q_SIGNALS:
void finished();
protected:
void execute();
void setExitCode(int i) {
m_ExitCode = i;
}
@ -81,11 +90,14 @@ protected:
void onReadOutput();
private:
QVariantMap arguments;
Report *m_Report;
QString m_Command;
QStringList m_Args;
int m_ExitCode;
QByteArray m_Output;
QByteArray m_Input;
};
#endif

View File

@ -0,0 +1,59 @@
/*************************************************************************
* Copyright (C) 2017 by Andrius Štikonas <andrius@stikonas.eu> *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation; either version 3 of *
* the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
*************************************************************************/
#include "externalcommandhelper.h"
#include <QDebug>
ActionReply ExternalCommandHelper::start(const QVariantMap& args)
{
ActionReply reply;
QString command = args[QStringLiteral("command")].toString();
QStringList arguments = args[QStringLiteral("arguments")].toStringList();
QStringList environment = args[QStringLiteral("environment")].toStringList();
QByteArray input = args[QStringLiteral("input")].toByteArray();
// connect(&cmd, &QProcess::readyReadStandardOutput, this, &ExternalCommandHelper::onReadOutput);
cmd.setEnvironment(environment);
cmd.start(command, arguments);
cmd.write(input);
cmd.waitForFinished(-1);
QByteArray output = cmd.readAllStandardOutput();
reply.addData(QStringLiteral("output"), output);
reply.addData(QStringLiteral("exitCode"), cmd.exitCode());
return reply;
}
void ExternalCommandHelper::onReadOutput()
{
// const QByteArray s = cmd.readAllStandardOutput();
// if(output.length() > 10*1024*1024) { // prevent memory overflow for badly corrupted file systems
// if (report())
// report()->line() << xi18nc("@info:status", "(Command is printing too much output)");
// return;
// }
// output += s;
// if (report())
// *report() << QString::fromLocal8Bit(s);
}
KAUTH_HELPER_MAIN("org.kde.kpmcore.externalcommand", ExternalCommandHelper)

View File

@ -0,0 +1,42 @@
/*************************************************************************
* Copyright (C) 2017 by Andrius Štikonas <andrius@stikonas.eu> *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation; either version 3 of *
* the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
*************************************************************************/
#ifndef KPMCORE_EXTERNALCOMMANDHELPER_H
#define KPMCORE_EXTERNALCOMMANDHELPER_H
#include <KAuth>
#include <QProcess>
using namespace KAuth;
class ExternalCommandHelper : public QObject
{
Q_OBJECT
public Q_SLOTS:
ActionReply start(const QVariantMap& args);
private:
void onReadOutput();
QProcess cmd;
// QByteArray output;
};
#endif

View File

@ -0,0 +1,5 @@
[org.kde.kpmcore.externalcommand.start]
Name=Run external command action
Description=Run external command as privileged user
Policy=auth_admin
Persistence=session

View File

@ -45,3 +45,10 @@ add_test(NAME testlist COMMAND testlist ${BACKEND})
kpm_test(testdevicescanner testdevicescanner.cpp)
add_test(NAME testdevicescanner COMMAND testdevicescanner ${BACKEND})
find_package (Threads)
###
#
# Execute external commands as root
kpm_test(testexternalcommand testexternalcommand.cpp)
add_test(NAME testexternalcommand COMMAND testexternalcommand ${BACKEND})

View File

@ -0,0 +1,66 @@
/*************************************************************************
* Copyright 2017 by Andrius Štikonas <andrius@stikonas.eu> *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation; either version 3 of *
* the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
*************************************************************************/
// SPDX-License-Identifier: GPL-3.0+
#include "helpers.h"
#include "backend/corebackendmanager.h"
#include "util/externalcommand.h"
#include <QApplication>
#include <QDebug>
#include <QThread>
class runcmd : public QThread {
public:
void run()
{
ExternalCommand blkidCmd(QStringLiteral("blkid"), {});
blkidCmd.run();
qDebug().noquote() << blkidCmd.output();
}
};
class runcmd2 : public QThread {
public:
void run()
{
ExternalCommand lsblkCmd(QStringLiteral("lsblk"), { QStringLiteral("--nodeps"), QStringLiteral("--json") });
lsblkCmd.run();
qDebug().noquote() << lsblkCmd.output();
}
};
int main( int argc, char **argv )
{
QApplication app(argc, argv);
KPMCoreInitializer i(QStringLiteral("pmsfdiskbackendplugin"));
runcmd a;
runcmd2 b;
a.start();
a.wait();
b.start();
b.wait();
return 0;
}