refactor: Update IPC server to handle log level and elevate mode changes
This commit is contained in:
parent
53038760de
commit
7c672b06d8
7 changed files with 162 additions and 88 deletions
|
|
@ -9,6 +9,7 @@
|
||||||
#include "base/Log.h"
|
#include "base/Log.h"
|
||||||
#include "common/constants.h"
|
#include "common/constants.h"
|
||||||
#include "deskflow/DaemonApp.h"
|
#include "deskflow/DaemonApp.h"
|
||||||
|
#include "deskflow/ipc/DaemonIpcServer.h"
|
||||||
|
|
||||||
#include "arch/Arch.h"
|
#include "arch/Arch.h"
|
||||||
#include "base/EventQueue.h"
|
#include "base/EventQueue.h"
|
||||||
|
|
@ -44,28 +45,58 @@ int main(int argc, char **argv)
|
||||||
QCoreApplication app(argc, argv);
|
QCoreApplication app(argc, argv);
|
||||||
|
|
||||||
const auto pDaemon = &DaemonApp::instance();
|
const auto pDaemon = &DaemonApp::instance();
|
||||||
QObject::connect(pDaemon, &DaemonApp::mainLoopFinished, &app, &QCoreApplication::quit);
|
const auto initResult = pDaemon->init(&events, argc, argv);
|
||||||
QObject::connect(pDaemon, &DaemonApp::fatalErrorOccurred, &app, &QCoreApplication::quit);
|
|
||||||
QObject::connect(pDaemon, &DaemonApp::serviceInstalled, &app, &QCoreApplication::quit);
|
|
||||||
QObject::connect(pDaemon, &DaemonApp::serviceUninstalled, &app, &QCoreApplication::quit);
|
|
||||||
pDaemon->init(&events, argc, argv);
|
|
||||||
|
|
||||||
// Thread must be on the heap, as the thread needs to be deleted only when the loop finishes,
|
switch (initResult) {
|
||||||
// and not when we go out of scope.
|
using enum DaemonApp::InitResult;
|
||||||
// Deliberately do not set ownership of the thread to the daemon, as we want to delete the thread
|
|
||||||
// when the loop finishes, and not when the daemon is deleted.
|
|
||||||
QThread *thread = new QThread(); // NOSONAR
|
|
||||||
pDaemon->moveToThread(thread);
|
|
||||||
QObject::connect(thread, &QThread::started, pDaemon, &DaemonApp::run);
|
|
||||||
QObject::connect(thread, &QThread::finished, pDaemon, &QObject::deleteLater);
|
|
||||||
QObject::connect(thread, &QThread::finished, thread, &QThread::deleteLater);
|
|
||||||
thread->start();
|
|
||||||
|
|
||||||
return QCoreApplication::exec();
|
case StartDaemon: {
|
||||||
|
using namespace deskflow::core;
|
||||||
|
|
||||||
|
QCoreApplication app(argc, argv);
|
||||||
|
|
||||||
|
auto *pDaemonThread = new QThread(); // NOSONAR
|
||||||
|
pDaemon->moveToThread(pDaemonThread);
|
||||||
|
|
||||||
|
QObject::connect(pDaemonThread, &QThread::started, pDaemon, &DaemonApp::run);
|
||||||
|
QObject::connect(pDaemonThread, &QThread::finished, pDaemon, &QObject::deleteLater);
|
||||||
|
QObject::connect(pDaemonThread, &QThread::finished, pDaemonThread, &QThread::deleteLater);
|
||||||
|
QObject::connect(pDaemonThread, &QThread::finished, QCoreApplication::instance(), &QCoreApplication::quit);
|
||||||
|
|
||||||
|
// The daemon app is on it's own thread which doesn't have a Qt event loop, so we need to use direct connection.
|
||||||
|
auto *ipcServer = new ipc::DaemonIpcServer(&app); // NOSONAR
|
||||||
|
QObject::connect(
|
||||||
|
ipcServer, &ipc::DaemonIpcServer::logLevelChanged, pDaemon, &DaemonApp::saveLogLevel, //
|
||||||
|
Qt::DirectConnection
|
||||||
|
);
|
||||||
|
QObject::connect(
|
||||||
|
ipcServer, &ipc::DaemonIpcServer::elevateModeChanged, pDaemon, &DaemonApp::setElevate, //
|
||||||
|
Qt::DirectConnection
|
||||||
|
);
|
||||||
|
QObject::connect(
|
||||||
|
ipcServer, &ipc::DaemonIpcServer::commandChanged, pDaemon, &DaemonApp::setCommand, //
|
||||||
|
Qt::DirectConnection
|
||||||
|
);
|
||||||
|
QObject::connect(
|
||||||
|
ipcServer, &ipc::DaemonIpcServer::restartRequested, pDaemon, &DaemonApp::restartCoreProcess, //
|
||||||
|
Qt::DirectConnection
|
||||||
|
);
|
||||||
|
pDaemonThread->start();
|
||||||
|
return QCoreApplication::exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
case FatalError:
|
||||||
|
return kExitFailed;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return kExitSuccess;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SYSAPI_WIN32
|
#if SYSAPI_WIN32
|
||||||
|
|
||||||
|
// Win32 subsystem entry point (simply forwards to main).
|
||||||
|
// We need this because using regular main under the Win32 subsystem results in empty args.
|
||||||
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
|
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
|
||||||
{
|
{
|
||||||
return main(__argc, __argv);
|
return main(__argc, __argv);
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Deskflow -- mouse and keyboard sharing utility
|
* Deskflow -- mouse and keyboard sharing utility
|
||||||
* SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd.
|
* SPDX-FileCopyrightText: (C) 2010 - 2018, 2024 - 2025 Symless Ltd.
|
||||||
* SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman
|
* SPDX-FileCopyrightText: (C) 2002 - 2007 Chris Schoeneman
|
||||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -22,8 +22,8 @@
|
||||||
// make assert available since we use it a lot
|
// make assert available since we use it a lot
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h> // IWYU pragma: keep
|
||||||
#include <string.h>
|
#include <string.h> // IWYU pragma: keep
|
||||||
|
|
||||||
// defined in Carbon
|
// defined in Carbon
|
||||||
#if !defined(__MACTYPES__)
|
#if !defined(__MACTYPES__)
|
||||||
|
|
@ -35,10 +35,9 @@
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
kExitSuccess = 0, // successful completion
|
kExitSuccess = 0, // successful completion
|
||||||
kExitFailed = 1, // general failure
|
kExitFailed = 1, // general failure
|
||||||
kExitTerminated = 2, // killed by signal
|
kExitTerminated = 2, // killed by signal
|
||||||
kExitArgs = 3, // bad arguments
|
kExitArgs = 3, // bad arguments
|
||||||
kExitConfig = 4, // cannot read configuration
|
kExitConfig = 4, // cannot read configuration
|
||||||
kExitSubscription = 5 // subscription error
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Deskflow -- mouse and keyboard sharing utility
|
* Deskflow -- mouse and keyboard sharing utility
|
||||||
* SPDX-FileCopyrightText: (C) 2024 Chris Rizzitello <sithlord48@gmail.com>
|
* SPDX-FileCopyrightText: (C) 2024 Chris Rizzitello <sithlord48@gmail.com>
|
||||||
* SPDX-FileCopyrightText: (C) 2012 - 2025 Symless Ltd.
|
* SPDX-FileCopyrightText: (C) 2025 Symless Ltd.
|
||||||
* SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Deskflow -- mouse and keyboard sharing utility
|
* Deskflow -- mouse and keyboard sharing utility
|
||||||
* SPDX-FileCopyrightText: (C) 2012 Symless Ltd.
|
* SPDX-FileCopyrightText: (C) 2012 - 2025 Symless Ltd.
|
||||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -19,7 +19,6 @@
|
||||||
#include "deskflow/ArgParser.h"
|
#include "deskflow/ArgParser.h"
|
||||||
#include "deskflow/ClientArgs.h"
|
#include "deskflow/ClientArgs.h"
|
||||||
#include "deskflow/ServerArgs.h"
|
#include "deskflow/ServerArgs.h"
|
||||||
#include "ipc/DaemonIpcServer.h"
|
|
||||||
#include "ipc/IpcClientProxy.h"
|
#include "ipc/IpcClientProxy.h"
|
||||||
#include "ipc/IpcLogOutputter.h"
|
#include "ipc/IpcLogOutputter.h"
|
||||||
#include "ipc/IpcMessage.h"
|
#include "ipc/IpcMessage.h"
|
||||||
|
|
@ -37,16 +36,10 @@
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
|
||||||
#elif SYSAPI_UNIX
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <filesystem>
|
||||||
#include <QObject>
|
#include <iostream>
|
||||||
#include <QThread>
|
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
@ -99,13 +92,13 @@ int winMainLoopStatic(int, const char **)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DaemonApp::DaemonApp() : m_ipcServer{new ipc::DaemonIpcServer(this)}
|
void showHelp(int argc, char **argv) // NOSONAR - CLI args
|
||||||
{
|
{
|
||||||
connect(m_ipcServer, &ipc::DaemonIpcServer::elevateModeChanged, this, &DaemonApp::handleElevateModeChanged);
|
const auto binName = argc > 0 ? std::filesystem::path(argv[0]).filename().string() : "deskflow-core";
|
||||||
connect(m_ipcServer, &ipc::DaemonIpcServer::commandChanged, this, &DaemonApp::handleCommandChanged);
|
std::cout << "Usage: " << binName << " daemon [-f|--foreground] [--install] [--uninstall]" << std::endl;
|
||||||
connect(m_ipcServer, &ipc::DaemonIpcServer::restartRequested, this, &DaemonApp::handleRestartRequested);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DaemonApp::DaemonApp() = default;
|
||||||
DaemonApp::~DaemonApp() = default;
|
DaemonApp::~DaemonApp() = default;
|
||||||
|
|
||||||
void DaemonApp::run()
|
void DaemonApp::run()
|
||||||
|
|
@ -125,34 +118,62 @@ void DaemonApp::run()
|
||||||
ARCH->daemonize(kAppName, unixMainLoopStatic);
|
ARCH->daemonize(kAppName, unixMainLoopStatic);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_EMIT mainLoopFinished();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DaemonApp::handleElevateModeChanged(int mode)
|
void DaemonApp::saveLogLevel(const QString &logLevel) const
|
||||||
{
|
{
|
||||||
LOG_DEBUG("elevate mode changed: %d", mode);
|
LOG_DEBUG("log level changed: %s", logLevel.toUtf8().constData());
|
||||||
m_elevateMode = mode;
|
CLOG->setFilter(logLevel.toUtf8().constData());
|
||||||
|
|
||||||
|
try {
|
||||||
|
// saves setting for next time the daemon starts.
|
||||||
|
ARCH->setting("LogLevel", logLevel.toStdString());
|
||||||
|
} catch (XArch &e) {
|
||||||
|
LOG((CLOG_ERR "failed to save log level setting: %s", e.what()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DaemonApp::handleCommandChanged(const QString &command)
|
void DaemonApp::setElevate(bool elevate)
|
||||||
|
{
|
||||||
|
LOG((CLOG_DEBUG "elevate value changed: %s", elevate ? "yes" : "no"));
|
||||||
|
m_elevate = elevate;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// saves setting for next time the daemon starts.
|
||||||
|
ARCH->setting("Elevate", std::string(elevate ? "1" : "0"));
|
||||||
|
} catch (XArch &e) {
|
||||||
|
LOG((CLOG_ERR "failed to save elevate setting: %s", e.what()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DaemonApp::setCommand(const QString &command)
|
||||||
{
|
{
|
||||||
LOG_DEBUG("service command updated");
|
LOG_DEBUG("service command updated");
|
||||||
m_command = command.toStdString();
|
m_command = command.toStdString();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// saves setting for next time the daemon starts.
|
||||||
|
ARCH->setting("Command", command.toStdString());
|
||||||
|
} catch (XArch &e) {
|
||||||
|
LOG((CLOG_ERR "failed to save command setting: %s", e.what()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DaemonApp::handleRestartRequested()
|
void DaemonApp::restartCoreProcess()
|
||||||
{
|
{
|
||||||
LOG_DEBUG("service restart requested");
|
LOG_DEBUG("service restart requested");
|
||||||
|
|
||||||
#if SYSAPI_WIN32
|
#if SYSAPI_WIN32
|
||||||
m_watchdog->setCommand(m_command, m_elevateMode);
|
m_watchdog->setCommand(m_command, m_elevate);
|
||||||
#else
|
#else
|
||||||
LOG_ERR("restart not implemented on this platform");
|
LOG_ERR("restart not implemented on this platform");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void DaemonApp::init(IEventQueue *events, int argc, char **argv) // NOSONAR
|
DaemonApp::InitResult DaemonApp::init(IEventQueue *events, int argc, char **argv) // NOSONAR - CLI args
|
||||||
{
|
{
|
||||||
|
using enum InitResult;
|
||||||
|
|
||||||
if (events == nullptr) {
|
if (events == nullptr) {
|
||||||
throw XDeskflow("event queue not set");
|
throw XDeskflow("event queue not set");
|
||||||
}
|
}
|
||||||
|
|
@ -168,26 +189,30 @@ void DaemonApp::init(IEventQueue *events, int argc, char **argv) // NOSONAR
|
||||||
for (int i = 1; i < argc; ++i) {
|
for (int i = 1; i < argc; ++i) {
|
||||||
string arg(argv[i]);
|
string arg(argv[i]);
|
||||||
|
|
||||||
if (arg == "-f") {
|
if (arg == "-h" || arg == "--help") {
|
||||||
|
showHelp(argc, argv);
|
||||||
|
return ShowHelp;
|
||||||
|
} else if (arg == "-f" || arg == "--foreground") {
|
||||||
m_foreground = true;
|
m_foreground = true;
|
||||||
}
|
}
|
||||||
#if SYSAPI_WIN32
|
#if SYSAPI_WIN32
|
||||||
else if (arg == "--install" || arg == "/install") {
|
else if (arg == "--install" || arg == "/install") {
|
||||||
LOG((CLOG_NOTE "installing windows daemon"));
|
LOG((CLOG_NOTE "installing windows daemon"));
|
||||||
ARCH->installDaemon();
|
ARCH->installDaemon();
|
||||||
Q_EMIT serviceInstalled();
|
return Installed;
|
||||||
} else if (arg == "--uninstall" || arg == "/uninstall") {
|
} else if (arg == "--uninstall" || arg == "/uninstall") {
|
||||||
LOG((CLOG_NOTE "uninstalling windows daemon"));
|
LOG((CLOG_NOTE "uninstalling windows daemon"));
|
||||||
isUninstalling = true;
|
isUninstalling = true;
|
||||||
ARCH->uninstallDaemon();
|
ARCH->uninstallDaemon();
|
||||||
Q_EMIT serviceUninstalled();
|
return Uninstalled;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else {
|
else {
|
||||||
stringstream ss;
|
stringstream ss;
|
||||||
ss << "Unrecognized argument: " << arg;
|
ss << "Unrecognized argument: " << arg;
|
||||||
foregroundError(ss.str().c_str());
|
handleError(ss.str().c_str());
|
||||||
Q_EMIT fatalErrorOccurred();
|
showHelp(argc, argv);
|
||||||
|
return ArgsError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -198,6 +223,9 @@ void DaemonApp::init(IEventQueue *events, int argc, char **argv) // NOSONAR
|
||||||
CLOG->insert(new MSWindowsDebugOutputter()); // NOSONAR - Adopted by `Log`
|
CLOG->insert(new MSWindowsDebugOutputter()); // NOSONAR - Adopted by `Log`
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return StartDaemon;
|
||||||
|
|
||||||
} catch (XArch &e) {
|
} catch (XArch &e) {
|
||||||
std::string message = e.what();
|
std::string message = e.what();
|
||||||
if (isUninstalling && (message.find("The service has not been started") != std::string::npos)) {
|
if (isUninstalling && (message.find("The service has not been started") != std::string::npos)) {
|
||||||
|
|
@ -207,16 +235,15 @@ void DaemonApp::init(IEventQueue *events, int argc, char **argv) // NOSONAR
|
||||||
// horribly wrong, but it's just the service manager reporting a false
|
// horribly wrong, but it's just the service manager reporting a false
|
||||||
// positive (the service has actually shut down in most cases).
|
// positive (the service has actually shut down in most cases).
|
||||||
} else {
|
} else {
|
||||||
foregroundError(message.c_str());
|
handleError(message.c_str());
|
||||||
}
|
}
|
||||||
Q_EMIT fatalErrorOccurred();
|
|
||||||
} catch (std::exception &e) {
|
} catch (std::exception &e) {
|
||||||
foregroundError(e.what());
|
handleError(e.what());
|
||||||
Q_EMIT fatalErrorOccurred();
|
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
foregroundError("Unrecognized error.");
|
handleError("Unrecognized error.");
|
||||||
Q_EMIT fatalErrorOccurred();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return FatalError;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DaemonApp::mainLoop(bool logToFile, bool foreground)
|
void DaemonApp::mainLoop(bool logToFile, bool foreground)
|
||||||
|
|
@ -268,12 +295,14 @@ void DaemonApp::mainLoop(bool logToFile, bool foreground)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DaemonApp::foregroundError(const char *message)
|
void DaemonApp::handleError(const char *message)
|
||||||
{
|
{
|
||||||
|
// Always print error to stdout in case run as CLI program.
|
||||||
|
LOG_ERR("%s", message);
|
||||||
|
|
||||||
#if SYSAPI_WIN32
|
#if SYSAPI_WIN32
|
||||||
MessageBoxA(NULL, message, "Deskflow Service", MB_OK | MB_ICONERROR);
|
// Show a message box for when run from MSI in Win32 subsystem.
|
||||||
#elif SYSAPI_UNIX
|
MessageBoxA(nullptr, message, "Deskflow daemon error", MB_OK | MB_ICONERROR);
|
||||||
cerr << message << endl;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Deskflow -- mouse and keyboard sharing utility
|
* Deskflow -- mouse and keyboard sharing utility
|
||||||
* SPDX-FileCopyrightText: (C) 2012 Symless Ltd.
|
* SPDX-FileCopyrightText: (C) 2012 - 2025 Symless Ltd.
|
||||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -37,9 +37,23 @@ class DaemonApp : public QObject
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void init(IEventQueue *events, int argc, char **argv);
|
enum class InitResult
|
||||||
|
{
|
||||||
|
Installed,
|
||||||
|
Uninstalled,
|
||||||
|
StartDaemon,
|
||||||
|
ShowHelp,
|
||||||
|
ArgsError,
|
||||||
|
FatalError,
|
||||||
|
};
|
||||||
|
|
||||||
|
InitResult init(IEventQueue *events, int argc, char **argv);
|
||||||
void run();
|
void run();
|
||||||
void mainLoop(bool logToFile, bool foreground = false);
|
void mainLoop(bool logToFile, bool foreground = false);
|
||||||
|
void restartCoreProcess();
|
||||||
|
void saveLogLevel(const QString &logLevel) const;
|
||||||
|
void setElevate(bool elevate);
|
||||||
|
void setCommand(const QString &command);
|
||||||
|
|
||||||
static DaemonApp &instance()
|
static DaemonApp &instance()
|
||||||
{
|
{
|
||||||
|
|
@ -47,25 +61,14 @@ public:
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
signals:
|
|
||||||
void mainLoopFinished();
|
|
||||||
void fatalErrorOccurred();
|
|
||||||
void serviceInstalled();
|
|
||||||
void serviceUninstalled();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit DaemonApp();
|
explicit DaemonApp();
|
||||||
~DaemonApp() override;
|
~DaemonApp() override;
|
||||||
|
|
||||||
void daemonize();
|
void daemonize();
|
||||||
void foregroundError(const char *message);
|
void handleError(const char *message);
|
||||||
std::string logFilename();
|
std::string logFilename();
|
||||||
void handleIpcMessage(const Event &, void *);
|
void handleIpcMessage(const Event &e, void *);
|
||||||
|
|
||||||
private slots:
|
|
||||||
void handleElevateModeChanged(int mode);
|
|
||||||
void handleCommandChanged(const QString &command);
|
|
||||||
void handleRestartRequested();
|
|
||||||
|
|
||||||
#if SYSAPI_WIN32
|
#if SYSAPI_WIN32
|
||||||
std::unique_ptr<MSWindowsWatchdog> m_watchdog;
|
std::unique_ptr<MSWindowsWatchdog> m_watchdog;
|
||||||
|
|
@ -77,6 +80,6 @@ private:
|
||||||
FileLogOutputter *m_fileLogOutputter = nullptr;
|
FileLogOutputter *m_fileLogOutputter = nullptr;
|
||||||
deskflow::core::ipc::DaemonIpcServer *m_ipcServer = nullptr;
|
deskflow::core::ipc::DaemonIpcServer *m_ipcServer = nullptr;
|
||||||
std::string m_command = "";
|
std::string m_command = "";
|
||||||
int m_elevateMode = 0;
|
bool m_elevate = false;
|
||||||
bool m_foreground = false;
|
bool m_foreground = false;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -100,15 +100,27 @@ void DaemonIpcServer::processMessage(QLocalSocket *clientSocket, const QString &
|
||||||
LOG_DEBUG("ipc server got message: %s", message.toUtf8().constData());
|
LOG_DEBUG("ipc server got message: %s", message.toUtf8().constData());
|
||||||
if (message == "hello") {
|
if (message == "hello") {
|
||||||
clientSocket->write("hello\n");
|
clientSocket->write("hello\n");
|
||||||
|
} else if (message == "noop") {
|
||||||
|
clientSocket->write(kAckMessage);
|
||||||
|
} else if (message.startsWith("logLevel=")) {
|
||||||
|
const auto logLevel = message.split('=')[1];
|
||||||
|
if (logLevel.isEmpty()) {
|
||||||
|
LOG_ERR("ipc server got empty log level");
|
||||||
|
clientSocket->write(kErrorMessage);
|
||||||
|
} else {
|
||||||
|
LOG_DEBUG("ipc server got new log level: %s", logLevel.toUtf8().constData());
|
||||||
|
Q_EMIT logLevelChanged(logLevel);
|
||||||
|
clientSocket->write(kAckMessage);
|
||||||
|
}
|
||||||
} else if (message.startsWith("elevate=")) {
|
} else if (message.startsWith("elevate=")) {
|
||||||
const auto elevateMode = message.split('=')[1].toInt();
|
const auto elevateMode = message.split('=')[1];
|
||||||
if (elevateMode < 0 || elevateMode > 2) {
|
if (elevateMode != "yes" && elevateMode != "no") {
|
||||||
LOG_ERR("ipc server got invalid elevate mode: %d", elevateMode);
|
LOG_ERR("ipc server got invalid elevate value: %s", elevateMode.toUtf8().constData());
|
||||||
clientSocket->write(kErrorMessage);
|
clientSocket->write(kErrorMessage);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
LOG_DEBUG("ipc server got new elevate mode: %d", elevateMode);
|
LOG_DEBUG("ipc server got new elevate value: %s", elevateMode.toUtf8().constData());
|
||||||
Q_EMIT elevateModeChanged(elevateMode);
|
Q_EMIT elevateModeChanged(elevateMode == "yes");
|
||||||
clientSocket->write(kAckMessage);
|
clientSocket->write(kAckMessage);
|
||||||
}
|
}
|
||||||
} else if (message.startsWith("command=")) {
|
} else if (message.startsWith("command=")) {
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,8 @@ public:
|
||||||
~DaemonIpcServer();
|
~DaemonIpcServer();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void elevateModeChanged(int mode);
|
void logLevelChanged(const QString &logLevel);
|
||||||
|
void elevateModeChanged(bool elevate);
|
||||||
void commandChanged(const QString &command);
|
void commandChanged(const QString &command);
|
||||||
void restartRequested();
|
void restartRequested();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue