Changeset View
Changeset View
Standalone View
Standalone View
src/util/externalcommand.cpp
1 | /************************************************************************* | 1 | /************************************************************************* | ||
---|---|---|---|---|---|
2 | * Copyright (C) 2008 by Volker Lanz <vl@fidra.de> * | 2 | * Copyright (C) 2008 by Volker Lanz <vl@fidra.de> * | ||
3 | * Copyright (C) 2016-2018 by Andrius Štikonas <andrius@stikonas.eu> * | 3 | * Copyright (C) 2016-2018 by Andrius Štikonas <andrius@stikonas.eu> * | ||
4 | * Copyright (C) 2019 by Shubham <aryan100jangid@gmail.com> * | ||||
4 | * * | 5 | * * | ||
5 | * This program is free software; you can redistribute it and/or * | 6 | * This program is free software; you can redistribute it and/or * | ||
6 | * modify it under the terms of the GNU General Public License as * | 7 | * modify it under the terms of the GNU General Public License as * | ||
7 | * published by the Free Software Foundation; either version 3 of * | 8 | * published by the Free Software Foundation; either version 3 of * | ||
8 | * the License, or (at your option) any later version. * | 9 | * the License, or (at your option) any later version. * | ||
9 | * * | 10 | * * | ||
10 | * This program is distributed in the hope that it will be useful, * | 11 | * This program is distributed in the hope that it will be useful, * | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | ||
13 | * GNU General Public License for more details. * | 14 | * GNU General Public License for more details. * | ||
14 | * * | 15 | * * | ||
15 | * You should have received a copy of the GNU General Public License * | 16 | * You should have received a copy of the GNU General Public License * | ||
16 | * along with this program. If not, see <http://www.gnu.org/licenses/>.* | 17 | * along with this program. If not, see <http://www.gnu.org/licenses/>.* | ||
17 | *************************************************************************/ | 18 | *************************************************************************/ | ||
18 | 19 | | |||
19 | #include "backend/corebackendmanager.h" | 20 | #include "backend/corebackendmanager.h" | ||
20 | #include "core/device.h" | 21 | #include "core/device.h" | ||
21 | #include "core/copysource.h" | 22 | #include "core/copysource.h" | ||
22 | #include "core/copytarget.h" | 23 | #include "core/copytarget.h" | ||
23 | #include "core/copytargetbytearray.h" | 24 | #include "core/copytargetbytearray.h" | ||
24 | #include "core/copysourcedevice.h" | 25 | #include "core/copysourcedevice.h" | ||
25 | #include "core/copytargetdevice.h" | 26 | #include "core/copytargetdevice.h" | ||
26 | #include "util/globallog.h" | 27 | #include "util/globallog.h" | ||
27 | #include "util/externalcommand.h" | 28 | #include "util/externalcommand.h" | ||
29 | #include "util/externalcommand_polkitbackend.h" | ||||
28 | #include "util/report.h" | 30 | #include "util/report.h" | ||
29 | 31 | | |||
30 | #include "externalcommandhelper_interface.h" | 32 | #include "externalcommandhelper_interface.h" | ||
31 | 33 | | |||
32 | #include <QCryptographicHash> | 34 | #include <QtDBus> | ||
33 | #include <QDBusConnection> | | |||
34 | #include <QDBusInterface> | | |||
35 | #include <QDBusReply> | | |||
36 | #include <QEventLoop> | 35 | #include <QEventLoop> | ||
37 | #include <QtGlobal> | | |||
38 | #include <QStandardPaths> | 36 | #include <QStandardPaths> | ||
39 | #include <QString> | 37 | #include <QString> | ||
40 | #include <QStringList> | 38 | #include <QStringList> | ||
41 | #include <QTimer> | | |||
42 | #include <QThread> | 39 | #include <QThread> | ||
40 | #include <QTimer> | ||||
43 | #include <QVariant> | 41 | #include <QVariant> | ||
44 | 42 | | |||
45 | #include <KAuth> | | |||
46 | #include <KJob> | 43 | #include <KJob> | ||
47 | #include <KLocalizedString> | 44 | #include <KLocalizedString> | ||
48 | 45 | | |||
46 | #include <PolkitQt1/Authority> | ||||
47 | | ||||
49 | struct ExternalCommandPrivate | 48 | struct ExternalCommandPrivate | ||
50 | { | 49 | { | ||
51 | Report *m_Report; | 50 | Report *m_Report; | ||
52 | QString m_Command; | 51 | QString m_Command; | ||
53 | QStringList m_Args; | 52 | QStringList m_Args; | ||
54 | int m_ExitCode; | 53 | int m_ExitCode; | ||
55 | QByteArray m_Output; | 54 | QByteArray m_Output; | ||
56 | QByteArray m_Input; | 55 | QByteArray m_Input; | ||
57 | DBusThread *m_thread; | | |||
58 | QProcess::ProcessChannelMode processChannelMode; | 56 | QProcess::ProcessChannelMode processChannelMode; | ||
59 | }; | 57 | }; | ||
60 | 58 | | |||
61 | KAuth::ExecuteJob* ExternalCommand::m_job; | 59 | Auth::PolkitQt1Backend* ExternalCommand::m_authJob; | ||
62 | bool ExternalCommand::helperStarted = false; | 60 | bool ExternalCommand::helperStarted = false; | ||
63 | QWidget* ExternalCommand::parent; | 61 | QWidget* ExternalCommand::parent; | ||
64 | 62 | | |||
65 | | ||||
66 | /** Creates a new ExternalCommand instance without Report. | 63 | /** Creates a new ExternalCommand instance without Report. | ||
67 | @param cmd the command to run | 64 | @param cmd the command to run | ||
68 | @param args the arguments to pass to the command | 65 | @param args the arguments to pass to the command | ||
69 | */ | 66 | */ | ||
70 | ExternalCommand::ExternalCommand(const QString& cmd, const QStringList& args, const QProcess::ProcessChannelMode processChannelMode) : | 67 | ExternalCommand::ExternalCommand(const QString& cmd, const QStringList& args, const QProcess::ProcessChannelMode processChannelMode) : | ||
71 | d(std::make_unique<ExternalCommandPrivate>()) | 68 | d(std::make_unique<ExternalCommandPrivate>()) | ||
72 | { | 69 | { | ||
73 | d->m_Report = nullptr; | 70 | d->m_Report = nullptr; | ||
74 | d->m_Command = cmd; | 71 | d->m_Command = cmd; | ||
75 | d->m_Args = args; | 72 | d->m_Args = args; | ||
76 | d->m_ExitCode = -1; | 73 | d->m_ExitCode = -1; | ||
77 | d->m_Output = QByteArray(); | 74 | d->m_Output = QByteArray(); | ||
78 | 75 | | |||
76 | m_authJob = new Auth::PolkitQt1Backend; | ||||
77 | | ||||
79 | if (!helperStarted) | 78 | if (!helperStarted) | ||
80 | if(!startHelper()) | 79 | if(!startHelper()) | ||
81 | Log(Log::Level::error) << xi18nc("@info:status", "Could not obtain administrator privileges."); | 80 | Log(Log::Level::error) << xi18nc("@info:status", "Could not obtain administrator privileges."); | ||
82 | 81 | | |||
83 | d->processChannelMode = processChannelMode; | 82 | d->processChannelMode = processChannelMode; | ||
84 | } | 83 | } | ||
85 | 84 | | |||
86 | /** Creates a new ExternalCommand instance with Report. | 85 | /** Creates a new ExternalCommand instance with Report. | ||
87 | @param report the Report to write output to. | 86 | @param report the Report to write output to. | ||
88 | @param cmd the command to run | 87 | @param cmd the command to run | ||
89 | @param args the arguments to pass to the command | 88 | @param args the arguments to pass to the command | ||
90 | */ | 89 | */ | ||
91 | ExternalCommand::ExternalCommand(Report& report, const QString& cmd, const QStringList& args, const QProcess::ProcessChannelMode processChannelMode) : | 90 | ExternalCommand::ExternalCommand(Report& report, const QString& cmd, const QStringList& args, const QProcess::ProcessChannelMode processChannelMode) : | ||
92 | d(std::make_unique<ExternalCommandPrivate>()) | 91 | d(std::make_unique<ExternalCommandPrivate>()) | ||
93 | { | 92 | { | ||
94 | d->m_Report = report.newChild(); | 93 | d->m_Report = report.newChild(); | ||
95 | d->m_Command = cmd; | 94 | d->m_Command = cmd; | ||
96 | d->m_Args = args; | 95 | d->m_Args = args; | ||
97 | d->m_ExitCode = -1; | 96 | d->m_ExitCode = -1; | ||
98 | d->m_Output = QByteArray(); | 97 | d->m_Output = QByteArray(); | ||
99 | | ||||
100 | d->processChannelMode = processChannelMode; | 98 | d->processChannelMode = processChannelMode; | ||
101 | } | 99 | } | ||
102 | 100 | | |||
103 | ExternalCommand::~ExternalCommand() | 101 | ExternalCommand::~ExternalCommand() | ||
104 | { | 102 | { | ||
105 | 103 | | |||
106 | } | 104 | } | ||
107 | 105 | | |||
108 | /* | 106 | /* | ||
109 | void ExternalCommand::setup() | 107 | void ExternalCommand::setup() | ||
110 | { | 108 | { | ||
111 | connect(this, qOverload<int, QProcess::ExitStatus>(&QProcess::finished), this, &ExternalCommand::onFinished); | 109 | connect(this, qOverload<int, QProcess::ExitStatus>(&QProcess::finished), this, &ExternalCommand::onFinished); | ||
112 | connect(this, &ExternalCommand::readyReadStandardOutput, this, &ExternalCommand::onReadOutput); | 110 | connect(this, &ExternalCommand::readyReadStandardOutput, this, &ExternalCommand::onReadOutput); | ||
113 | } | 111 | } | ||
114 | */ | 112 | */ | ||
115 | 113 | | |||
116 | /** Executes the external command. | 114 | /** Executes the external command. | ||
117 | @param timeout timeout to wait for the process to start | 115 | @param timeout timeout to wait for the process to start | ||
118 | @return true on success | 116 | @return true on success | ||
119 | */ | 117 | */ | ||
120 | bool ExternalCommand::start(int timeout) | 118 | bool ExternalCommand::start(int timeout) | ||
121 | { | 119 | { | ||
122 | if (command().isEmpty()) | | |||
123 | return false; | | |||
124 | | ||||
125 | if (!QDBusConnection::systemBus().isConnected()) { | 120 | if (!QDBusConnection::systemBus().isConnected()) { | ||
126 | qWarning() << QDBusConnection::systemBus().lastError().message(); | 121 | qWarning() << QDBusConnection::systemBus().lastError().message(); | ||
127 | QTimer::singleShot(timeout, this, &ExternalCommand::quit); | 122 | QTimer::singleShot(timeout, this, &ExternalCommand::quit); | ||
128 | return false; | 123 | return false; | ||
129 | } | 124 | } | ||
130 | 125 | | |||
126 | if (command().isEmpty()) { | ||||
127 | qInfo() << "There is no command to execute, exiting"; | ||||
128 | return false; | ||||
129 | } | ||||
130 | | ||||
131 | if (report()) | 131 | if (report()) | ||
132 | report()->setCommand(xi18nc("@info:status", "Command: %1 %2", command(), args().join(QStringLiteral(" ")))); | 132 | report()->setCommand(xi18nc("@info:status", "Command: %1 %2", command(), args().join(QStringLiteral(" ")))); | ||
133 | 133 | | |||
134 | if ( qEnvironmentVariableIsSet( "KPMCORE_DEBUG" )) | 134 | if (qEnvironmentVariableIsSet("KPMCORE_DEBUG")) | ||
135 | qDebug() << xi18nc("@info:status", "Command: %1 %2", command(), args().join(QStringLiteral(" "))); | 135 | qDebug() << xi18nc("@info:status", "Command: %1 %2", command(), args().join(QStringLiteral(" "))); | ||
136 | 136 | | |||
137 | QString cmd = QStandardPaths::findExecutable(command()); | 137 | QString cmd = QStandardPaths::findExecutable(command()); | ||
138 | | ||||
138 | if (cmd.isEmpty()) | 139 | if (cmd.isEmpty()) | ||
139 | cmd = QStandardPaths::findExecutable(command(), { QStringLiteral("/sbin/"), QStringLiteral("/usr/sbin/"), QStringLiteral("/usr/local/sbin/") }); | 140 | cmd = QStandardPaths::findExecutable(command(), { QStringLiteral("/sbin/"), QStringLiteral("/usr/sbin/"), QStringLiteral("/usr/local/sbin/") }); | ||
140 | 141 | | |||
141 | auto *interface = new org::kde::kpmcore::externalcommand(QStringLiteral("org.kde.kpmcore.externalcommand"), | 142 | auto interface = new org::kde::kpmcore::externalcommand(QStringLiteral("org.kde.kpmcore.externalcommand"), | ||
142 | QStringLiteral("/Helper"), QDBusConnection::systemBus(), this); | 143 | QStringLiteral("/Helper"), QDBusConnection::systemBus(), this); | ||
143 | 144 | | |||
144 | interface->setTimeout(10 * 24 * 3600 * 1000); // 10 days | 145 | interface->setTimeout(10 * 24 * 3600 * 1000); // 10 days | ||
145 | 146 | | |||
146 | bool rval = false; | 147 | bool rval = false; | ||
147 | 148 | | |||
148 | QDBusPendingCall pcall = interface->start(cmd, args(), d->m_Input, d->processChannelMode); | 149 | QDBusPendingCall pcall = interface->start(cmd, args(), d->m_Input, d->processChannelMode); | ||
149 | 150 | | |||
Show All 27 Lines | 177 | { | |||
177 | bool rval = true; | 178 | bool rval = true; | ||
178 | const qint64 blockSize = 10 * 1024 * 1024; // number of bytes per block to copy | 179 | const qint64 blockSize = 10 * 1024 * 1024; // number of bytes per block to copy | ||
179 | 180 | | |||
180 | if (!QDBusConnection::systemBus().isConnected()) { | 181 | if (!QDBusConnection::systemBus().isConnected()) { | ||
181 | qWarning() << QDBusConnection::systemBus().lastError().message(); | 182 | qWarning() << QDBusConnection::systemBus().lastError().message(); | ||
182 | return false; | 183 | return false; | ||
183 | } | 184 | } | ||
184 | 185 | | |||
185 | // TODO KF6:Use new signal-slot syntax | 186 | auto interface = new org::kde::kpmcore::externalcommand(QStringLiteral("org.kde.kpmcore.externalcommand"), | ||
186 | connect(m_job, SIGNAL(percent(KJob*, unsigned long)), this, SLOT(emitProgress(KJob*, unsigned long))); | | |||
187 | connect(m_job, &KAuth::ExecuteJob::newData, this, &ExternalCommand::emitReport); | | |||
188 | | ||||
189 | auto *interface = new org::kde::kpmcore::externalcommand(QStringLiteral("org.kde.kpmcore.externalcommand"), | | |||
190 | QStringLiteral("/Helper"), QDBusConnection::systemBus(), this); | 187 | QStringLiteral("/Helper"), QDBusConnection::systemBus(), this); | ||
191 | interface->setTimeout(10 * 24 * 3600 * 1000); // 10 days | 188 | interface->setTimeout(10 * 24 * 3600 * 1000); // 10 days | ||
192 | 189 | | |||
193 | QDBusPendingCall pcall = interface->copyblocks(source.path(), source.firstByte(), source.length(), | 190 | QDBusPendingCall pcall = interface->copyblocks(source.path(), source.firstByte(), source.length(), | ||
194 | target.path(), target.firstByte(), blockSize); | 191 | target.path(), target.firstByte(), blockSize); | ||
195 | 192 | | |||
196 | QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, this); | 193 | QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, this); | ||
197 | QEventLoop loop; | 194 | QEventLoop loop; | ||
Show All 27 Lines | 218 | { | |||
225 | 222 | | |||
226 | bool rval = true; | 223 | bool rval = true; | ||
227 | 224 | | |||
228 | if (!QDBusConnection::systemBus().isConnected()) { | 225 | if (!QDBusConnection::systemBus().isConnected()) { | ||
229 | qWarning() << QDBusConnection::systemBus().lastError().message(); | 226 | qWarning() << QDBusConnection::systemBus().lastError().message(); | ||
230 | return false; | 227 | return false; | ||
231 | } | 228 | } | ||
232 | 229 | | |||
233 | auto *interface = new org::kde::kpmcore::externalcommand(QStringLiteral("org.kde.kpmcore.externalcommand"), | 230 | auto interface = new org::kde::kpmcore::externalcommand(QStringLiteral("org.kde.kpmcore.externalcommand"), | ||
234 | QStringLiteral("/Helper"), QDBusConnection::systemBus(), this); | 231 | QStringLiteral("/Helper"), QDBusConnection::systemBus(), this); | ||
235 | interface->setTimeout(10 * 24 * 3600 * 1000); // 10 days | 232 | interface->setTimeout(10 * 24 * 3600 * 1000); // 10 days | ||
236 | 233 | | |||
237 | QDBusPendingCall pcall = interface->writeData(buffer, deviceNode, firstByte); | 234 | QDBusPendingCall pcall = interface->writeData(buffer, deviceNode, firstByte); | ||
238 | 235 | | |||
239 | QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, this); | 236 | QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, this); | ||
240 | QEventLoop loop; | 237 | QEventLoop loop; | ||
241 | 238 | | |||
Show All 14 Lines | |||||
256 | return rval; | 253 | return rval; | ||
257 | } | 254 | } | ||
258 | 255 | | |||
259 | 256 | | |||
260 | bool ExternalCommand::write(const QByteArray& input) | 257 | bool ExternalCommand::write(const QByteArray& input) | ||
261 | { | 258 | { | ||
262 | if ( qEnvironmentVariableIsSet( "KPMCORE_DEBUG" )) | 259 | if ( qEnvironmentVariableIsSet( "KPMCORE_DEBUG" )) | ||
263 | qDebug() << "Command input:" << QString::fromLocal8Bit(input); | 260 | qDebug() << "Command input:" << QString::fromLocal8Bit(input); | ||
261 | | ||||
264 | d->m_Input = input; | 262 | d->m_Input = input; | ||
263 | | ||||
265 | return true; | 264 | return true; | ||
266 | } | 265 | } | ||
267 | 266 | | |||
268 | /** Runs the command. | 267 | /** Runs the command. | ||
269 | @param timeout timeout to use for waiting when starting and when waiting for the process to finish | 268 | @param timeout timeout to use for waiting when starting and when waiting for the process to finish | ||
270 | @return true on success | 269 | @return true on success | ||
271 | */ | 270 | */ | ||
272 | bool ExternalCommand::run(int timeout) | 271 | bool ExternalCommand::run(int timeout) | ||
273 | { | 272 | { | ||
274 | return start(timeout) /* && exitStatus() == 0*/; | 273 | return start(timeout) /* && exitStatus() == 0*/; | ||
275 | } | 274 | } | ||
276 | 275 | | |||
277 | void ExternalCommand::onReadOutput() | 276 | //void ExternalCommand::onReadOutput() | ||
278 | { | 277 | //{ | ||
279 | // const QByteArray s = readAllStandardOutput(); | 278 | // const QByteArray s = readAllStandardOutput(); | ||
280 | // | 279 | // | ||
281 | // if(m_Output.length() > 10*1024*1024) { // prevent memory overflow for badly corrupted file systems | 280 | // if(m_Output.length() > 10*1024*1024) { // prevent memory overflow for badly corrupted file systems | ||
282 | // if (report()) | 281 | // if (report()) | ||
283 | // report()->line() << xi18nc("@info:status", "(Command is printing too much output)"); | 282 | // report()->line() << xi18nc("@info:status", "(Command is printing too much output)"); | ||
284 | // return; | 283 | // return; | ||
285 | // } | 284 | // } | ||
286 | // | 285 | // | ||
287 | // m_Output += s; | 286 | // m_Output += s; | ||
288 | // | 287 | // | ||
289 | // if (report()) | 288 | // if (report()) | ||
290 | // *report() << QString::fromLocal8Bit(s); | 289 | // *report() << QString::fromLocal8Bit(s); | ||
291 | } | 290 | //} | ||
292 | 291 | | |||
293 | void ExternalCommand::setCommand(const QString& cmd) | 292 | void ExternalCommand::setCommand(const QString& cmd) | ||
294 | { | 293 | { | ||
295 | d->m_Command = cmd; | 294 | d->m_Command = cmd; | ||
296 | } | 295 | } | ||
297 | 296 | | |||
298 | const QString& ExternalCommand::command() const | 297 | const QString& ExternalCommand::command() const | ||
299 | { | 298 | { | ||
Show All 35 Lines | 333 | { | |||
335 | return d->m_Report; | 334 | return d->m_Report; | ||
336 | } | 335 | } | ||
337 | 336 | | |||
338 | void ExternalCommand::setExitCode(int i) | 337 | void ExternalCommand::setExitCode(int i) | ||
339 | { | 338 | { | ||
340 | d->m_ExitCode = i; | 339 | d->m_ExitCode = i; | ||
341 | } | 340 | } | ||
342 | 341 | | |||
343 | /**< Dummy function for QTimer when needed. */ | 342 | /**< Dummy function for QTimer */ | ||
344 | void ExternalCommand::quit() | 343 | void ExternalCommand::quit() | ||
345 | { | 344 | { | ||
346 | 345 | | |||
347 | } | 346 | } | ||
348 | 347 | | |||
349 | bool ExternalCommand::startHelper() | 348 | bool ExternalCommand::startHelper() | ||
350 | { | 349 | { | ||
351 | if (!QDBusConnection::systemBus().isConnected()) { | 350 | if (!QDBusConnection::systemBus().isConnected()) { | ||
351 | qWarning() << "Error starting the helper application!!"; | ||||
352 | qWarning() << QDBusConnection::systemBus().lastError().message(); | 352 | qWarning() << QDBusConnection::systemBus().lastError().message(); | ||
353 | return false; | 353 | return false; | ||
354 | } | 354 | } | ||
355 | 355 | | |||
356 | QDBusInterface iface(QStringLiteral("org.kde.kpmcore.helperinterface"), QStringLiteral("/Helper"), QStringLiteral("org.kde.kpmcore.externalcommand"), QDBusConnection::systemBus()); | 356 | QDBusInterface iface(QStringLiteral("org.kde.kpmcore.helperinterface"), QStringLiteral("/Helper"), QStringLiteral("org.kde.kpmcore.externalcommand"), QDBusConnection::systemBus()); | ||
357 | | ||||
357 | if (iface.isValid()) { | 358 | if (iface.isValid()) { | ||
358 | exit(0); | 359 | exit(0); | ||
359 | } | 360 | } | ||
360 | 361 | | |||
361 | d->m_thread = new DBusThread; | 362 | /** Authorize using Polkit backend **/ | ||
362 | d->m_thread->start(); | | |||
363 | 363 | | |||
364 | KAuth::Action action = KAuth::Action(QStringLiteral("org.kde.kpmcore.externalcommand.init")); | 364 | // initialize KDE Polkit daemon | ||
365 | action.setHelperId(QStringLiteral("org.kde.kpmcore.externalcommand")); | 365 | m_authJob->initPolkitAgent(QStringLiteral("org.kde.kpmcore.externalcommand.init"), parent); | ||
366 | action.setTimeout(10 * 24 * 3600 * 1000); // 10 days | | |||
367 | action.setParentWidget(parent); | | |||
368 | QVariantMap arguments; | | |||
369 | action.setArguments(arguments); | | |||
370 | m_job = action.execute(); | | |||
371 | m_job->start(); | | |||
372 | 366 | | |||
373 | // Wait until ExternalCommand Helper is ready (helper sends newData signal just before it enters event loop) | 367 | // Kick start the helper application | ||
368 | m_authJob->startHelper(QStringLiteral("org.kde.kpmcore.externalcommand.init"), QStringLiteral("org.kde.kpmcore.externalcommand")); | ||||
369 | | ||||
370 | bool isActionAuthorized = m_authJob->authorizeAction(QStringLiteral("org.kde.kpmcore.externalcommand.init"), m_authJob->callerID()); | ||||
371 | | ||||
372 | // Wait until ExternalCommand Helper is ready and sends signal(Connect to newData signal) | ||||
374 | QEventLoop loop; | 373 | QEventLoop loop; | ||
375 | auto exitLoop = [&] () { loop.exit(); }; | 374 | auto exitLoop = [&] () { loop.exit(); }; | ||
376 | auto conn = QObject::connect(m_job, &KAuth::ExecuteJob::newData, exitLoop); | 375 | | ||
377 | QObject::connect(m_job, &KJob::finished, [=] () { if(m_job->error()) exitLoop(); } ); | 376 | connect(this, &ExternalCommand::newData, exitLoop); | ||
377 | | ||||
stikonas: Fix this, this will give you infinite recursion. | |||||
378 | loop.exec(); | 378 | loop.exec(); | ||
379 | QObject::disconnect(conn); | 379 | | ||
380 | if (!isActionAuthorized) { | ||||
381 | qDebug() << "Unable to obtain Administrative privileges, the action can not be executed!!"; | ||||
382 | } | ||||
380 | 383 | | |||
381 | helperStarted = true; | 384 | helperStarted = true; | ||
382 | return true; | 385 | return true; | ||
383 | } | 386 | } | ||
384 | 387 | | |||
385 | void ExternalCommand::stopHelper() | 388 | void ExternalCommand::stopHelper() | ||
386 | { | 389 | { | ||
387 | auto *interface = new org::kde::kpmcore::externalcommand(QStringLiteral("org.kde.kpmcore.externalcommand"), | 390 | auto interface = new org::kde::kpmcore::externalcommand(QStringLiteral("org.kde.kpmcore.externalcommand"), | ||
388 | QStringLiteral("/Helper"), QDBusConnection::systemBus()); | 391 | QStringLiteral("/Helper"), QDBusConnection::systemBus()); | ||
389 | interface->exit(); | 392 | interface->exit(); | ||
390 | 393 | | |||
391 | } | 394 | } | ||
392 | 395 | | |||
393 | void DBusThread::run() | 396 | void ExternalCommand::emitNewData(int percent) | ||
394 | { | 397 | { | ||
395 | if (!QDBusConnection::systemBus().registerService(QStringLiteral("org.kde.kpmcore.applicationinterface")) || | 398 | Q_UNUSED(percent) | ||
396 | !QDBusConnection::systemBus().registerObject(QStringLiteral("/Application"), this, QDBusConnection::ExportAllSlots)) { | 399 | emit newData(); | ||
397 | qWarning() << QDBusConnection::systemBus().lastError().message(); | | |||
398 | return; | | |||
399 | } | 400 | } | ||
400 | 401 | | |||
401 | QEventLoop loop; | 402 | void ExternalCommand::emitNewData(QString message) | ||
402 | loop.exec(); | 403 | { | ||
404 | Q_UNUSED(message) | ||||
405 | emit newData(); | ||||
403 | } | 406 | } |
Fix this, this will give you infinite recursion.