diff --git a/CMakeLists.txt b/CMakeLists.txt index 1365570..0c2a128 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,9 @@ find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core RemoteObjects) # Find nlohmann_json find_package(nlohmann_json REQUIRED) +# Find CLI11 +find_package(CLI11 REQUIRED) + # Set output directories set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) diff --git a/nix/default.nix b/nix/default.nix index 15395cc..5e8c7f9 100644 --- a/nix/default.nix +++ b/nix/default.nix @@ -20,6 +20,7 @@ pkgs.zstd pkgs.gtest pkgs.nlohmann_json + pkgs.cli11 logosModule processStats logosPackageManager diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 11d6346..85a48c6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -113,6 +113,10 @@ set(LOGOS_HOST_SOURCES logos_host/command_line_parser.h logos_host/plugin_initializer.cpp logos_host/plugin_initializer.h + logos_host/qt/qt_app.cpp + logos_host/qt/qt_app.h + logos_host/qt/qt_token_receiver.cpp + logos_host/qt/qt_token_receiver.h ) # Create the logos core library @@ -222,6 +226,7 @@ target_link_libraries(logos_host PRIVATE Qt${QT_VERSION_MAJOR}::RemoteObjects logos_sdk logos_module + CLI11::CLI11 ) # Include directories for the logos host application diff --git a/src/logos_host/command_line_parser.cpp b/src/logos_host/command_line_parser.cpp index 90a6b77..31561d2 100644 --- a/src/logos_host/command_line_parser.cpp +++ b/src/logos_host/command_line_parser.cpp @@ -1,45 +1,26 @@ #include "command_line_parser.h" -#include -#include -#include -#include +#include -PluginArgs parseCommandLineArgs(QCoreApplication& app) +PluginArgs parseCommandLineArgs(int argc, char *argv[]) { - PluginArgs args; - args.valid = false; + PluginArgs result; + result.valid = false; - // Setup command line parser - QCommandLineParser parser; - parser.setApplicationDescription("Logos host for loading plugins in separate processes"); - parser.addHelpOption(); - parser.addVersionOption(); + CLI::App app{"Logos host for loading plugins in separate processes"}; + app.set_version_flag("-v,--version", "1.0"); - // Add plugin name option - QCommandLineOption pluginNameOption(QStringList() << "n" << "name", - "Name of the plugin to load", - "plugin_name"); - parser.addOption(pluginNameOption); + app.add_option("-n,--name", result.name, "Name of the plugin to load") + ->required(); + app.add_option("-p,--path", result.path, "Path to the plugin file") + ->required(); - // Add plugin path option - QCommandLineOption pluginPathOption(QStringList() << "p" << "path", - "Path to the plugin file", - "plugin_path"); - parser.addOption(pluginPathOption); - - // Process the command line arguments - parser.process(app); - - // Get plugin name and path - args.name = parser.value(pluginNameOption); - args.path = parser.value(pluginPathOption); - - if (args.name.isEmpty() || args.path.isEmpty()) { - qCritical() << "Both plugin name and path must be specified"; - qCritical() << "Usage:" << app.arguments()[0] << "--name --path "; - return args; + try { + app.parse(argc, argv); + } catch (const CLI::ParseError& e) { + app.exit(e); + return result; } - args.valid = true; - return args; + result.valid = true; + return result; } diff --git a/src/logos_host/command_line_parser.h b/src/logos_host/command_line_parser.h index d9e4b0e..c1dfe18 100644 --- a/src/logos_host/command_line_parser.h +++ b/src/logos_host/command_line_parser.h @@ -1,16 +1,14 @@ #ifndef COMMAND_LINE_PARSER_H #define COMMAND_LINE_PARSER_H -#include - -class QCoreApplication; +#include struct PluginArgs { - QString name; - QString path; + std::string name; + std::string path; bool valid; }; -PluginArgs parseCommandLineArgs(QCoreApplication& app); +PluginArgs parseCommandLineArgs(int argc, char *argv[]); #endif // COMMAND_LINE_PARSER_H diff --git a/src/logos_host/logos_host.cpp b/src/logos_host/logos_host.cpp index 7620995..24c13a2 100644 --- a/src/logos_host/logos_host.cpp +++ b/src/logos_host/logos_host.cpp @@ -1,26 +1,27 @@ -#include +#include #include "command_line_parser.h" #include "plugin_initializer.h" +#include "qt/qt_app.h" #include "logos_api.h" int main(int argc, char *argv[]) { - QCoreApplication app(argc, argv); - app.setApplicationName("logos_host"); - app.setApplicationVersion("1.0"); - - PluginArgs args = parseCommandLineArgs(app); + PluginArgs args = parseCommandLineArgs(argc, argv); if (!args.valid) { return 1; } - LogosAPI* logos_api = setupPlugin(args.name, args.path); + QtApp::init(argc, argv); + + LogosAPI* logos_api = setupPlugin(QString::fromStdString(args.name), + QString::fromStdString(args.path)); if (!logos_api) { return 1; } - int result = app.exec(); + int result = QtApp::exec(); delete logos_api; + QtApp::cleanup(); return result; -} +} diff --git a/src/logos_host/plugin_initializer.cpp b/src/logos_host/plugin_initializer.cpp index e111b3e..0651e48 100644 --- a/src/logos_host/plugin_initializer.cpp +++ b/src/logos_host/plugin_initializer.cpp @@ -1,6 +1,5 @@ #include "plugin_initializer.h" -#include -#include +#include "qt/qt_token_receiver.h" #include #include #include @@ -12,44 +11,6 @@ using namespace ModuleLib; -QString receiveAuthToken(const QString& pluginName) -{ - // Set up IPC server to receive auth token securely - QString socketName = QString("logos_token_%1").arg(pluginName); - QLocalServer* tokenServer = new QLocalServer(); - - // Remove any existing socket file - QLocalServer::removeServer(socketName); - - if (!tokenServer->listen(socketName)) { - qCritical() << "Failed to start token server:" << tokenServer->errorString(); - return QString(); - } - - QString authToken; - if (tokenServer->waitForNewConnection(10000)) { - QLocalSocket* clientSocket = tokenServer->nextPendingConnection(); - if (clientSocket->waitForReadyRead(5000)) { - QByteArray tokenData = clientSocket->readAll(); - authToken = QString::fromUtf8(tokenData); - } - clientSocket->deleteLater(); - } else { - qCritical() << "Timeout waiting for auth token"; - tokenServer->deleteLater(); - return QString(); - } - - tokenServer->deleteLater(); - - if (authToken.isEmpty()) { - qCritical() << "No auth token received"; - return QString(); - } - - return authToken; -} - LogosModule loadPlugin(const QString& pluginPath, const QString& expectedName) { // Load the plugin using module_lib for abstraction @@ -98,7 +59,7 @@ LogosAPI* initializeLogosAPI(const QString& pluginName, QObject* plugin, LogosAPI* setupPlugin(const QString& pluginName, const QString& pluginPath) { // 1. Receive auth token securely - QString authToken = receiveAuthToken(pluginName); + QString authToken = QtTokenReceiver::receiveAuthToken(pluginName); if (authToken.isEmpty()) { return nullptr; } diff --git a/src/logos_host/plugin_initializer.h b/src/logos_host/plugin_initializer.h index e48c9a7..399ace6 100644 --- a/src/logos_host/plugin_initializer.h +++ b/src/logos_host/plugin_initializer.h @@ -8,8 +8,6 @@ class PluginInterface; class LogosAPI; class QObject; -QString receiveAuthToken(const QString& pluginName); - ModuleLib::LogosModule loadPlugin(const QString& pluginPath, const QString& expectedName); LogosAPI* initializeLogosAPI(const QString& pluginName, QObject* plugin, diff --git a/src/logos_host/qt/qt_app.cpp b/src/logos_host/qt/qt_app.cpp new file mode 100644 index 0000000..a8e7e14 --- /dev/null +++ b/src/logos_host/qt/qt_app.cpp @@ -0,0 +1,24 @@ +#include "qt_app.h" +#include + +namespace { + QCoreApplication* s_app = nullptr; +} + +namespace QtApp { + + void init(int argc, char* argv[]) { + s_app = new QCoreApplication(argc, argv); + } + + int exec() { + if (!s_app) return -1; + return s_app->exec(); + } + + void cleanup() { + delete s_app; + s_app = nullptr; + } + +} diff --git a/src/logos_host/qt/qt_app.h b/src/logos_host/qt/qt_app.h new file mode 100644 index 0000000..c773d22 --- /dev/null +++ b/src/logos_host/qt/qt_app.h @@ -0,0 +1,10 @@ +#ifndef QT_APP_H +#define QT_APP_H + +namespace QtApp { + void init(int argc, char* argv[]); + int exec(); + void cleanup(); +} + +#endif // QT_APP_H diff --git a/src/logos_host/qt/qt_token_receiver.cpp b/src/logos_host/qt/qt_token_receiver.cpp new file mode 100644 index 0000000..95eac35 --- /dev/null +++ b/src/logos_host/qt/qt_token_receiver.cpp @@ -0,0 +1,44 @@ +#include "qt_token_receiver.h" +#include +#include +#include + +namespace QtTokenReceiver { + + QString receiveAuthToken(const QString& pluginName) + { + QString socketName = QString("logos_token_%1").arg(pluginName); + QLocalServer* tokenServer = new QLocalServer(); + + QLocalServer::removeServer(socketName); + + if (!tokenServer->listen(socketName)) { + qCritical() << "Failed to start token server:" << tokenServer->errorString(); + return QString(); + } + + QString authToken; + if (tokenServer->waitForNewConnection(10000)) { + QLocalSocket* clientSocket = tokenServer->nextPendingConnection(); + if (clientSocket->waitForReadyRead(5000)) { + QByteArray tokenData = clientSocket->readAll(); + authToken = QString::fromUtf8(tokenData); + } + clientSocket->deleteLater(); + } else { + qCritical() << "Timeout waiting for auth token"; + tokenServer->deleteLater(); + return QString(); + } + + tokenServer->deleteLater(); + + if (authToken.isEmpty()) { + qCritical() << "No auth token received"; + return QString(); + } + + return authToken; + } + +} diff --git a/src/logos_host/qt/qt_token_receiver.h b/src/logos_host/qt/qt_token_receiver.h new file mode 100644 index 0000000..d432116 --- /dev/null +++ b/src/logos_host/qt/qt_token_receiver.h @@ -0,0 +1,10 @@ +#ifndef QT_TOKEN_RECEIVER_H +#define QT_TOKEN_RECEIVER_H + +#include + +namespace QtTokenReceiver { + QString receiveAuthToken(const QString& pluginName); +} + +#endif // QT_TOKEN_RECEIVER_H