From ead49c402512c6b9faff71280897de43efdf9364 Mon Sep 17 00:00:00 2001 From: sithlord48 Date: Fri, 22 Aug 2025 19:35:18 -0400 Subject: [PATCH] refactor: move address option to deskflow-core, split into --interface (-i) and --port (-p) options --- src/lib/client/Client.cpp | 7 ++- src/lib/deskflow/ArgParser.cpp | 4 +- src/lib/deskflow/ArgsBase.h | 3 - src/lib/deskflow/CMakeLists.txt | 2 +- src/lib/deskflow/ClientApp.cpp | 2 - src/lib/deskflow/CoreArgParser.cpp | 10 ++- src/lib/deskflow/CoreArgs.h | 10 ++- src/lib/deskflow/ServerApp.cpp | 17 ++--- src/lib/gui/core/CoreProcess.cpp | 13 ---- src/lib/gui/core/CoreProcess.h | 1 - src/unittests/deskflow/ArgParserTests.cpp | 11 ---- src/unittests/deskflow/ArgParserTests.h | 1 - src/unittests/deskflow/CMakeLists.txt | 8 +++ src/unittests/deskflow/CoreArgParserTests.cpp | 63 +++++++++++++++++++ src/unittests/deskflow/CoreArgParserTests.h | 25 ++++++++ 15 files changed, 124 insertions(+), 53 deletions(-) create mode 100644 src/unittests/deskflow/CoreArgParserTests.cpp create mode 100644 src/unittests/deskflow/CoreArgParserTests.h diff --git a/src/lib/client/Client.cpp b/src/lib/client/Client.cpp index 375b6b750..9591e0864 100644 --- a/src/lib/client/Client.cpp +++ b/src/lib/client/Client.cpp @@ -13,6 +13,7 @@ #include "base/Log.h" #include "base/TMethodJob.h" #include "client/ServerProxy.h" +#include "common/Settings.h" #include "deskflow/AppUtil.h" #include "deskflow/DeskflowException.h" #include "deskflow/IPlatformScreen.h" @@ -631,10 +632,10 @@ void Client::handleResume() void Client::bindNetworkInterface(IDataSocket *socket) const { try { - if (!m_args.m_deskflowAddress.empty()) { - LOG_DEBUG1("bind to network interface: %s", m_args.m_deskflowAddress.c_str()); + if (const auto address = Settings::value(Settings::Core::Interface).toString(); !address.isEmpty()) { + LOG_DEBUG1("bind to network interface: %s", qPrintable(address)); - NetworkAddress bindAddress(m_args.m_deskflowAddress); + NetworkAddress bindAddress(address.toStdString()); bindAddress.resolve(); socket->bind(bindAddress); diff --git a/src/lib/deskflow/ArgParser.cpp b/src/lib/deskflow/ArgParser.cpp index 4513c47f2..73aa69b30 100644 --- a/src/lib/deskflow/ArgParser.cpp +++ b/src/lib/deskflow/ArgParser.cpp @@ -122,9 +122,7 @@ bool ArgParser::parsePlatformArgs(deskflow::ArgsBase &argsBase, const int &argc, bool ArgParser::parseGenericArgs(int argc, const char *const *argv, int &i) const { - if (isArg(i, argc, argv, "-a", "--address", 1)) { - argsBase().m_deskflowAddress = argv[++i]; - } else if (isArg(i, argc, argv, "-d", "--debug", 1)) { + if (isArg(i, argc, argv, "-d", "--debug", 1)) { // change logging level argsBase().m_logFilter = argv[++i]; } else if (isArg(i, argc, argv, "-l", "--log", 1)) { diff --git a/src/lib/deskflow/ArgsBase.h b/src/lib/deskflow/ArgsBase.h index 0abf297f8..9e4e5da32 100644 --- a/src/lib/deskflow/ArgsBase.h +++ b/src/lib/deskflow/ArgsBase.h @@ -59,9 +59,6 @@ public: /// @brief Will cause the application to exit with fail code when set to true bool m_shouldExitFail = false; - /// @brief Bind to this address - std::string m_deskflowAddress; - /// @brief Should the connections be TLS encrypted bool m_enableCrypto = false; diff --git a/src/lib/deskflow/CMakeLists.txt b/src/lib/deskflow/CMakeLists.txt index 68efb683c..d79d35e04 100644 --- a/src/lib/deskflow/CMakeLists.txt +++ b/src/lib/deskflow/CMakeLists.txt @@ -136,7 +136,7 @@ add_library(${lib_name} STATIC ${PLATFORM_CODE} ipc/DaemonIpcServer.h ) -target_link_libraries(${lib_name} PUBLIC Qt6::Core Qt6::Network) +target_link_libraries(${lib_name} PUBLIC common Qt6::Core Qt6::Network) if(WIN32) target_link_libraries(${lib_name} PRIVATE ${cli11_lib} ${tomlPP_lib}) diff --git a/src/lib/deskflow/ClientApp.cpp b/src/lib/deskflow/ClientApp.cpp index 04a48b187..f38278ca6 100644 --- a/src/lib/deskflow/ClientApp.cpp +++ b/src/lib/deskflow/ClientApp.cpp @@ -102,7 +102,6 @@ void ClientApp::help() std::stringstream help; help << "\n\nClient Mode:\n\n" << "Usage: " << kAppId << "-core client" - << " [--address
]" << " [--yscroll ]" << " [--sync-language]" << " [--invert-scroll]" @@ -113,7 +112,6 @@ void ClientApp::help() << "\n\n" << "Connect to a " << kAppName << " mouse/keyboard sharing server.\n" << "\n" - << " -a, --address
local network interface address.\n" << s_helpGeneralArgs << " --yscroll defines the vertical scrolling delta,\n" << " which is 120 by default.\n" << " --sync-language enable language synchronization.\n" diff --git a/src/lib/deskflow/CoreArgParser.cpp b/src/lib/deskflow/CoreArgParser.cpp index cefb14059..b37df4cef 100644 --- a/src/lib/deskflow/CoreArgParser.cpp +++ b/src/lib/deskflow/CoreArgParser.cpp @@ -24,7 +24,7 @@ CoreArgParser::CoreArgParser(const QStringList &args) m_parser.parse(args); m_parser.setApplicationDescription(kAppDescription); - m_helpText = m_parser.helpText().replace("", QString("%1-core").arg(kAppId)); + m_helpText = m_parser.helpText().replace("", s_appName); m_helpText.replace("[options] coremode", "coremode [options]"); } @@ -48,6 +48,14 @@ void CoreArgParser::parse() if (m_parser.isSet(CoreArgs::configOption)) { Settings::setSettingFile(m_parser.value(CoreArgs::configOption)); } + + if (m_parser.isSet(CoreArgs::interfaceOption)) { + Settings::setValue(Settings::Core::Interface, m_parser.value(CoreArgs::interfaceOption)); + } + + if (m_parser.isSet(CoreArgs::portOption)) { + Settings::setValue(Settings::Core::Port, m_parser.value(CoreArgs::portOption)); + } } [[noreturn]] void CoreArgParser::showHelpText() const diff --git a/src/lib/deskflow/CoreArgs.h b/src/lib/deskflow/CoreArgs.h index fe71cccf6..8e1d96e01 100644 --- a/src/lib/deskflow/CoreArgs.h +++ b/src/lib/deskflow/CoreArgs.h @@ -18,5 +18,13 @@ struct CoreArgs inline static const auto configOption = QCommandLineOption( {"s", "settings"}, "override configuration file to use", "configFile" ); // use -c later, now avoid breaking the serverApp args. - inline static const auto options = {helpOption, versionOption, configOption}; + inline static const auto interfaceOption = QCommandLineOption( + {"i", "interface"}, + "Use a specific interface for the connection. Instead of any address in client mode or listening on all " + "addresses in server mode address.\n address must be the IP address or hostname of an interface on the system.", + "address" + ); + inline static const auto portOption = + QCommandLineOption({"p", "port"}, "Port to use in place of default port", "port"); + inline static const auto options = {helpOption, versionOption, configOption, interfaceOption, portOption}; }; diff --git a/src/lib/deskflow/ServerApp.cpp b/src/lib/deskflow/ServerApp.cpp index 23af03f52..fef66f96c 100644 --- a/src/lib/deskflow/ServerApp.cpp +++ b/src/lib/deskflow/ServerApp.cpp @@ -13,6 +13,7 @@ #include "base/Log.h" #include "base/Path.h" #include "common/ExitCodes.h" +#include "common/Settings.h" #include "deskflow/App.h" #include "deskflow/ArgParser.h" #include "deskflow/Screen.h" @@ -86,9 +87,9 @@ void ServerApp::parseArgs(int argc, const char *const *argv) bye(s_exitArgs); } } else { - if (!args().m_deskflowAddress.empty()) { + if (const auto address = Settings::value(Settings::Core::Interface).toString(); !address.isEmpty()) { try { - *m_deskflowAddress = NetworkAddress(args().m_deskflowAddress, kDefaultPort); + *m_deskflowAddress = NetworkAddress(address.toStdString(), kDefaultPort); m_deskflowAddress->resolve(); } catch (SocketAddressException &e) { LOG_CRIT("%s: %s" BYE, args().m_pname, e.what(), args().m_pname); @@ -104,14 +105,12 @@ void ServerApp::help() help << "\n\nServer Mode:\n\n" << "Usage: " << kAppId << "-core server" << " --config " - << " [--address
]" #if WINAPI_XWINDOWS << " [--display ]" #endif << s_helpCommonArgs << "\n" - << " -a, --address
listen for clients on the given address.\n" << " -c, --config path of the configuration file\n" << s_helpGeneralArgs << " --disable-client-cert-check disable client SSL certificate \n" @@ -125,15 +124,7 @@ void ServerApp::help() << "* marks defaults.\n" - << s_helpNoWayland - - << "\n" - << "The argument for --address is of the form: [][:]. " - "The\n" - << "hostname must be the address or hostname of an interface on the " - << "system.\n" - << "The default is to listen on all interfaces. The port overrides the\n" - << "default port, " << kDefaultPort << ".\n"; + << s_helpNoWayland; LOG_PRINT("%s", help.str().c_str()); } diff --git a/src/lib/gui/core/CoreProcess.cpp b/src/lib/gui/core/CoreProcess.cpp index a887f4ffd..50f0d3682 100644 --- a/src/lib/gui/core/CoreProcess.cpp +++ b/src/lib/gui/core/CoreProcess.cpp @@ -488,12 +488,6 @@ bool CoreProcess::addServerArgs(QStringList &args) return false; } - // the address arg is dual purpose; when in listening mode, it's the address - // that the server listens on. when tcp sockets are inverted, it connects to - // that address. this is a bit confusing, and there should be probably be - // different args for different purposes. - args << "--address" << correctedInterface(); - args << "-c" << configFilename; qInfo("core config file: %s", qPrintable(configFilename)); // bizarrely, the tls cert path arg was being given to the core client. @@ -650,13 +644,6 @@ void CoreProcess::checkOSXNotification(const QString &line) } #endif -QString CoreProcess::correctedInterface() const -{ - const QString interface = wrapIpv6(Settings::value(Settings::Core::Interface).toString()); - const auto port = Settings::value(Settings::Core::Port).toString(); - return QStringLiteral("%1:%2").arg(interface, port); -} - QString CoreProcess::correctedAddress() const { return wrapIpv6(m_address); diff --git a/src/lib/gui/core/CoreProcess.h b/src/lib/gui/core/CoreProcess.h index 82de404d7..daabf3447 100644 --- a/src/lib/gui/core/CoreProcess.h +++ b/src/lib/gui/core/CoreProcess.h @@ -126,7 +126,6 @@ private: void checkLogLine(const QString &line); bool checkSecureSocket(const QString &line); void handleLogLines(const QString &text); - QString correctedInterface() const; QString correctedAddress() const; QString requestDaemonLogPath(); void persistLogDir() const; diff --git a/src/unittests/deskflow/ArgParserTests.cpp b/src/unittests/deskflow/ArgParserTests.cpp index 74c78413a..1f2a5c060 100644 --- a/src/unittests/deskflow/ArgParserTests.cpp +++ b/src/unittests/deskflow/ArgParserTests.cpp @@ -162,17 +162,6 @@ void ArgParserTests::assembleCommand() QCOMPARE(command, "\"stub1 space\" stub2 \"stub3 space\""); } -void ArgParserTests::server_setAddress() -{ - deskflow::ServerArgs serverArgs; - const int argc = 3; - const char *kAddressCmd[argc] = {"stub", "--address", "mock_address"}; - - m_parser.parseServerArgs(serverArgs, argc, kAddressCmd); - - QCOMPARE(serverArgs.m_deskflowAddress, "mock_address"); -} - void ArgParserTests::server_setConfigFile() { deskflow::ServerArgs serverArgs; diff --git a/src/unittests/deskflow/ArgParserTests.h b/src/unittests/deskflow/ArgParserTests.h index 9af31c623..eddf3f550 100644 --- a/src/unittests/deskflow/ArgParserTests.h +++ b/src/unittests/deskflow/ArgParserTests.h @@ -22,7 +22,6 @@ private Q_SLOTS: void getArgv(); void assembleCommand(); void serverArgs(); - void server_setAddress(); void server_setConfigFile(); void server_unexpectedParam(); void clientArgs(); diff --git a/src/unittests/deskflow/CMakeLists.txt b/src/unittests/deskflow/CMakeLists.txt index 418ea68be..ce9f0f623 100644 --- a/src/unittests/deskflow/CMakeLists.txt +++ b/src/unittests/deskflow/CMakeLists.txt @@ -13,6 +13,14 @@ create_test( WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/src/lib/deskflow" ) +create_test( + NAME CoreArgParserTests + DEPENDS app + LIBS ${extra_libs} + SOURCE CoreArgParserTests.cpp + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/src/lib/deskflow" +) + create_test( NAME ClipboardTests DEPENDS app diff --git a/src/unittests/deskflow/CoreArgParserTests.cpp b/src/unittests/deskflow/CoreArgParserTests.cpp new file mode 100644 index 000000000..bdf9fe356 --- /dev/null +++ b/src/unittests/deskflow/CoreArgParserTests.cpp @@ -0,0 +1,63 @@ +/* + * Deskflow -- mouse and keyboard sharing utility + * SPDX-FileCopyrightText: (C) 2025 Chris Rizzitello + * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception + */ + +#include "CoreArgParserTests.h" +#include "common/Settings.h" +#include "deskflow/CoreArgParser.h" + +void CoreArgParserTests::initTestCase() +{ + QDir dir; + QVERIFY(dir.mkpath(m_settingsPath)); + + QFile oldSettings(m_settingsFile); + if (oldSettings.exists()) + oldSettings.remove(); + + Settings::setSettingFile(m_settingsFile); +} + +void CoreArgParserTests::interfaceLong() +{ + QStringList args = {"stub", "client", "--interface", "mock_address"}; + + CoreArgParser parser(args); + parser.parse(); + + QCOMPARE(Settings::value(Settings::Core::Interface).toString(), "mock_address"); +} + +void CoreArgParserTests::interfaceShort() +{ + QStringList args = {"stub", "client", "-i", "address"}; + + CoreArgParser parser(args); + parser.parse(); + + QCOMPARE(Settings::value(Settings::Core::Interface).toString(), "address"); +} + +void CoreArgParserTests::portLong() +{ + QStringList args = {"stub", "client", "--port", "28771"}; + + CoreArgParser parser(args); + parser.parse(); + + QCOMPARE(Settings::value(Settings::Core::Port).toInt(), 28771); +} + +void CoreArgParserTests::portShort() +{ + QStringList args = {"stub", "client", "--p", "18768"}; + + CoreArgParser parser(args); + parser.parse(); + + QCOMPARE(Settings::value(Settings::Core::Port).toInt(), 18768); +} + +QTEST_MAIN(CoreArgParserTests) diff --git a/src/unittests/deskflow/CoreArgParserTests.h b/src/unittests/deskflow/CoreArgParserTests.h new file mode 100644 index 000000000..071316a06 --- /dev/null +++ b/src/unittests/deskflow/CoreArgParserTests.h @@ -0,0 +1,25 @@ +/* + * Deskflow -- mouse and keyboard sharing utility + * SPDX-FileCopyrightText: (C) 2025 Chris Rizzitello + * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception + */ + +#include "deskflow/CoreArgParser.h" + +#include + +class CoreArgParserTests : public QObject +{ + Q_OBJECT +private Q_SLOTS: + void initTestCase(); + // Test are run in order top to bottom + void interfaceLong(); + void interfaceShort(); + void portLong(); + void portShort(); + +private: + inline static const QString m_settingsPath = QStringLiteral("tmp/test"); + inline static const QString m_settingsFile = QStringLiteral("%1/Deskflow.conf").arg(m_settingsPath); +};