refactor: move address option to deskflow-core, split into --interface (-i) and --port (-p) options

This commit is contained in:
sithlord48
2025-08-22 19:35:18 -04:00
committed by Chris Rizzitello
parent 5e02adc772
commit ead49c4025
15 changed files with 124 additions and 53 deletions

View File

@ -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);

View File

@ -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)) {

View File

@ -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;

View File

@ -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})

View File

@ -102,7 +102,6 @@ void ClientApp::help()
std::stringstream help;
help << "\n\nClient Mode:\n\n"
<< "Usage: " << kAppId << "-core client"
<< " [--address <address>]"
<< " [--yscroll <delta>]"
<< " [--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 <address> local network interface address.\n"
<< s_helpGeneralArgs << " --yscroll <delta> defines the vertical scrolling delta,\n"
<< " which is 120 by default.\n"
<< " --sync-language enable language synchronization.\n"

View File

@ -24,7 +24,7 @@ CoreArgParser::CoreArgParser(const QStringList &args)
m_parser.parse(args);
m_parser.setApplicationDescription(kAppDescription);
m_helpText = m_parser.helpText().replace("<executable_name>", QString("%1-core").arg(kAppId));
m_helpText = m_parser.helpText().replace("<executable_name>", 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

View File

@ -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};
};

View File

@ -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 <pathname>"
<< " [--address <address>]"
#if WINAPI_XWINDOWS
<< " [--display <display>]"
#endif
<< s_helpCommonArgs << "\n"
<< " -a, --address <address> listen for clients on the given address.\n"
<< " -c, --config <pathname> 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: [<hostname>][:<port>]. "
"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());
}

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -22,7 +22,6 @@ private Q_SLOTS:
void getArgv();
void assembleCommand();
void serverArgs();
void server_setAddress();
void server_setConfigFile();
void server_unexpectedParam();
void clientArgs();

View File

@ -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

View File

@ -0,0 +1,63 @@
/*
* Deskflow -- mouse and keyboard sharing utility
* SPDX-FileCopyrightText: (C) 2025 Chris Rizzitello <sithlord48@gmail.com>
* 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)

View File

@ -0,0 +1,25 @@
/*
* Deskflow -- mouse and keyboard sharing utility
* SPDX-FileCopyrightText: (C) 2025 Chris Rizzitello <sithlord48@gmail.com>
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
*/
#include "deskflow/CoreArgParser.h"
#include <QTest>
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);
};