diff options
author | saturneric <[email protected]> | 2024-02-28 16:32:43 +0000 |
---|---|---|
committer | saturneric <[email protected]> | 2024-02-28 16:32:43 +0000 |
commit | 12d70e1792a5b1ff08d4b58fb49fb9e58d6551a8 (patch) | |
tree | 1b747d6a3a034814104df6f531077de9c03ecd53 | |
parent | feat: add user agent header when doing http request (diff) | |
download | GpgFrontend-12d70e1792a5b1ff08d4b58fb49fb9e58d6551a8.tar.gz GpgFrontend-12d70e1792a5b1ff08d4b58fb49fb9e58d6551a8.zip |
feat: upgrade module system
1. load module and resolve symbols at runtime
2. restrict sdk functions and structures to c style
3. add some core api to support it
36 files changed, 1143 insertions, 471 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index eab2df9d..b8cab9c3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -537,9 +537,7 @@ if (LINUX AND LINUX_INSTALL_SOFTWARE) gpgfrontend_test gpgfrontend_pinentry gpgfrontend_module_sdk - gpgfrontend_module - gpgfrontend_integrated_module_version_checking - gpgfrontend_integrated_module_gnupg_info_gathering) + gpgfrontend_module) message(STATUS "GpgFrontend Install Libraries: ${GPGFRONTEND_INSTALL_LIBRARIES}") install(TARGETS ${AppName} ${GPGFRONTEND_INSTALL_LIBRARIES} diff --git a/src/core/function/basic/GpgFunctionObject.h b/src/core/function/basic/GpgFunctionObject.h index 1ea352b6..422af4a1 100644 --- a/src/core/function/basic/GpgFunctionObject.h +++ b/src/core/function/basic/GpgFunctionObject.h @@ -29,7 +29,6 @@ #pragma once #include <mutex> -#include <stdexcept> #include "core/GpgFrontendCoreExport.h" #include "core/function/basic/ChannelObject.h" diff --git a/src/core/module/Event.cpp b/src/core/module/Event.cpp index fab26453..5a7b324c 100644 --- a/src/core/module/Event.cpp +++ b/src/core/module/Event.cpp @@ -28,6 +28,8 @@ #include "Event.h" +#include "core/utils/CommonUtils.h" + namespace GpgFrontend::Module { class Event::Impl { @@ -67,7 +69,11 @@ class Event::Impl { auto GetIdentifier() -> EventIdentifier { return event_identifier_; } - void AddParameter(const QString& key, const ParameterValue& value) { + auto GetTriggerIdentifier() -> EventTriggerIdentifier { + return trigger_uuid_; + } + + void AddParameter(const QString& key, const QString& value) { data_[key] = value; } @@ -95,9 +101,35 @@ class Event::Impl { } } + auto ToModuleEvent() -> ModuleEvent* { + auto* event = static_cast<ModuleEvent*>(SecureMalloc(sizeof(ModuleEvent))); + + event->id = GFStrDup(event_identifier_); + + ModuleEventParam* l_param = nullptr; + ModuleEventParam* p_param; + + int index = 0; + for (const auto& data : data_) { + p_param = static_cast<ModuleEventParam*>( + SecureMalloc(sizeof(ModuleEventParam))); + if (index++ == 0) event->params = p_param; + + p_param->name = GFStrDup(data.first); + p_param->value = GFStrDup(data.second); + p_param->next = nullptr; + + l_param->next = p_param; + l_param = p_param; + } + + return event; + } + private: EventIdentifier event_identifier_; - std::map<QString, ParameterValue> data_; + EventTriggerIdentifier trigger_uuid_ = QUuid::createUuid().toString(); + std::map<QString, QString> data_; EventCallback callback_; QThread* callback_thread_ = nullptr; ///< }; @@ -128,7 +160,11 @@ auto Event::Event::GetIdentifier() -> EventIdentifier { return p_->GetIdentifier(); } -void Event::AddParameter(const QString& key, const ParameterValue& value) { +auto Event::Event::GetTriggerIdentifier() -> EventTriggerIdentifier { + return p_->GetTriggerIdentifier(); +} + +void Event::AddParameter(const QString& key, const QString& value) { p_->AddParameter(key, value); } @@ -136,4 +172,6 @@ void Event::ExecuteCallback(ListenerIdentifier l_id, DataObjectPtr d_o) { p_->ExecuteCallback(std::move(l_id), d_o); } +auto Event::ToModuleEvent() -> ModuleEvent* { return p_->ToModuleEvent(); } + } // namespace GpgFrontend::Module
\ No newline at end of file diff --git a/src/core/module/Event.h b/src/core/module/Event.h index 92268216..d7c35314 100644 --- a/src/core/module/Event.h +++ b/src/core/module/Event.h @@ -34,6 +34,7 @@ #include "core/GpgFrontendCore.h" #include "core/model/DataObject.h" +#include "module/sdk/Module.h" namespace GpgFrontend::Module { @@ -41,6 +42,7 @@ class Event; using EventRefrernce = std::shared_ptr<Event>; using EventIdentifier = QString; +using EventTriggerIdentifier = QString; using Evnets = std::vector<Event>; class GPGFRONTEND_CORE_EXPORT Event { @@ -52,7 +54,7 @@ class GPGFRONTEND_CORE_EXPORT Event { std::function<void(EventIdentifier, ListenerIdentifier, DataObjectPtr)>; struct ParameterInitializer { QString key; - ParameterValue value; + QString value; }; explicit Event(const QString&, @@ -75,10 +77,14 @@ class GPGFRONTEND_CORE_EXPORT Event { auto GetIdentifier() -> EventIdentifier; - void AddParameter(const QString& key, const ParameterValue& value); + auto GetTriggerIdentifier() -> EventTriggerIdentifier; + + void AddParameter(const QString& key, const QString& value); void ExecuteCallback(ListenerIdentifier, DataObjectPtr); + auto ToModuleEvent() -> ModuleEvent*; + private: class Impl; SecureUniquePtr<Impl> p_; diff --git a/src/core/module/GlobalModuleContext.cpp b/src/core/module/GlobalModuleContext.cpp index 9bc4f06b..cf3e134b 100644 --- a/src/core/module/GlobalModuleContext.cpp +++ b/src/core/module/GlobalModuleContext.cpp @@ -31,6 +31,7 @@ #include <set> #include <unordered_map> #include <unordered_set> +#include <utility> #include "core/module/Event.h" #include "core/module/Module.h" @@ -49,6 +50,18 @@ class GlobalModuleContext::Impl { acquired_channel_.insert(kGpgFrontendNonAsciiChannel); } + auto SearchModule(ModuleIdentifier module_id) -> ModulePtr { + // Search for the module in the register table. + auto module_info_opt = search_module_register_table(module_id); + if (!module_info_opt.has_value()) { + GF_CORE_LOG_ERROR("cannot find module id {} at register table", + module_id); + return nullptr; + } + + return module_info_opt.value()->module; + } + auto GetChannel(ModuleRawPtr module) -> int { // Search for the module in the register table. auto module_info_opt = @@ -97,7 +110,7 @@ class GlobalModuleContext::Impl { return false; } - if (!module->Register()) { + if (module->Register() != 0) { GF_CORE_LOG_ERROR("register module {} failed", module->GetModuleIdentifier()); return false; @@ -222,6 +235,9 @@ class GlobalModuleContext::Impl { GF_CORE_LOG_DEBUG("event {}'s current listeners size: {}", event->GetIdentifier(), listeners_set.size()); + // register trigger id index table + module_on_triggering_events_table_[event->GetTriggerIdentifier()] = event; + // Iterate through each listener and execute the corresponding module for (const auto& listener_module_id : listeners_set) { // Search for the module's information in the registration table @@ -272,7 +288,17 @@ class GlobalModuleContext::Impl { return true; } - auto IsModuleActivated(const ModuleIdentifier& m_id) const -> bool { + auto SearchEvent(const EventTriggerIdentifier& trigger_id) + -> std::optional<EventRefrernce> { + if (module_on_triggering_events_table_.find(trigger_id) != + module_on_triggering_events_table_.end()) { + return module_on_triggering_events_table_[trigger_id]; + } + return {}; + } + + [[nodiscard]] auto IsModuleActivated(const ModuleIdentifier& m_id) const + -> bool { auto m = search_module_register_table(m_id); return m.has_value() && m->get()->activate; } @@ -290,6 +316,8 @@ class GlobalModuleContext::Impl { module_register_table_; std::map<EventIdentifier, std::unordered_set<ModuleIdentifier>> module_events_table_; + std::map<EventTriggerIdentifier, EventRefrernce> + module_on_triggering_events_table_; std::set<int> acquired_channel_; TaskRunnerPtr default_task_runner_; @@ -323,6 +351,11 @@ GlobalModuleContext::GlobalModuleContext() GlobalModuleContext::~GlobalModuleContext() = default; +auto GlobalModuleContext::SearchModule(ModuleIdentifier module_id) + -> ModulePtr { + return p_->SearchModule(std::move(module_id)); +} + // Function to get the task runner associated with a module. auto GlobalModuleContext::GetTaskRunner(ModuleRawPtr module) -> std::optional<TaskRunnerPtr> { @@ -362,6 +395,11 @@ auto GlobalModuleContext::TriggerEvent(EventRefrernce event) -> bool { return p_->TriggerEvent(std::move(event)); } +auto GlobalModuleContext::SearchEvent(EventTriggerIdentifier trigger_id) + -> std::optional<EventRefrernce> { + return p_->SearchEvent(trigger_id); +} + auto GlobalModuleContext::GetChannel(ModuleRawPtr module) -> int { return p_->GetChannel(module); } diff --git a/src/core/module/GlobalModuleContext.h b/src/core/module/GlobalModuleContext.h index 1c971bb5..7034fd77 100644 --- a/src/core/module/GlobalModuleContext.h +++ b/src/core/module/GlobalModuleContext.h @@ -58,6 +58,8 @@ class GPGFRONTEND_CORE_EXPORT GlobalModuleContext : public QObject { ~GlobalModuleContext() override; + auto SearchModule(ModuleIdentifier) -> ModulePtr; + auto GetChannel(ModuleRawPtr) -> int; static auto GetDefaultChannel(ModuleRawPtr) -> int; @@ -78,6 +80,8 @@ class GPGFRONTEND_CORE_EXPORT GlobalModuleContext : public QObject { auto TriggerEvent(EventRefrernce) -> bool; + auto SearchEvent(EventTriggerIdentifier) -> std::optional<EventRefrernce>; + auto IsModuleActivated(ModuleIdentifier) -> bool; private: diff --git a/src/core/module/Module.cpp b/src/core/module/Module.cpp index 9076dc2c..e943ab09 100644 --- a/src/core/module/Module.cpp +++ b/src/core/module/Module.cpp @@ -43,7 +43,60 @@ class Module::Impl { : m_ptr_(m_ptr), identifier_(std::move(id)), version_(std::move(version)), - meta_data_(std::move(meta_data)) {} + meta_data_(std::move(meta_data)), + good_(true) {} + + Impl(ModuleRawPtr m_ptr, QLibrary& module_library) + : m_ptr_(m_ptr), good_(false) { + for (auto& required_symbol : module_required_symbols_) { + *required_symbol.pointer = + reinterpret_cast<void*>(module_library.resolve(required_symbol.name)); + if (*required_symbol.pointer == nullptr) { + GF_CORE_LOG_WARN( + "illegal module: {}, reason: cannot load symbol: {}, abort...", + module_library.fileName(), required_symbol.name); + return; + } + } + + SPDLOG_INFO("module loaded, name: {}, verison: {}", + QString::fromUtf8(get_id_api_()), + QString::fromUtf8(get_version_api_())); + + identifier_ = QString::fromUtf8(get_id_api_()); + version_ = QString::fromUtf8(get_version_api_()); + + good_ = true; + } + + [[nodiscard]] auto IsGood() const -> bool { return good_; } + + auto Register() -> int { + if (good_ && register_api_ != nullptr) return register_api_(); + return -1; + } + + auto Active() -> int { + if (good_ && activate_api_ != nullptr) return activate_api_(); + return -1; + } + + auto Exec(const EventRefrernce& event) -> int { + if (good_ && execute_api_ != nullptr) { + return execute_api_(event->ToModuleEvent()); + } + return -1; + } + + auto Deactive() -> int { + if (good_ && deactivate_api_ != nullptr) return deactivate_api_(); + return -1; + } + + auto UnRegister() -> int { + if (good_ && unregister_api_ != nullptr) return unregister_api_(); + return -1; + } auto GetChannel() -> int { return get_gpc()->GetChannel(m_ptr_); } @@ -68,9 +121,35 @@ class Module::Impl { private: GlobalModuleContext* gpc_{}; Module* m_ptr_; - const ModuleIdentifier identifier_; - const ModuleVersion version_; - const ModuleMetaData meta_data_; + ModuleIdentifier identifier_; + ModuleVersion version_; + ModuleMetaData meta_data_; + + bool good_; + ModuleAPIGetModuleID get_id_api_; + ModuleAPIGetModuleVersion get_version_api_; + ModuleAPIGetModuleMetaData get_metadata_api_; + ModuleAPIRegisterModule register_api_; + ModuleAPIActivateModule activate_api_; + ModuleAPIExecuteModule execute_api_; + ModuleAPIDeactivateModule deactivate_api_; + ModuleAPIUnregisterModule unregister_api_; + + struct Symbol { + const char* name; + void** pointer; + }; + + QList<Symbol> module_required_symbols_ = { + {"GetModuleID", reinterpret_cast<void**>(&get_id_api_)}, + {"GetModuleVersion", reinterpret_cast<void**>(&get_version_api_)}, + {"GetModuleMetaData", reinterpret_cast<void**>(&get_metadata_api_)}, + {"RegisterModule", reinterpret_cast<void**>(®ister_api_)}, + {"ActiveModule", reinterpret_cast<void**>(&activate_api_)}, + {"ExecuteModule", reinterpret_cast<void**>(&execute_api_)}, + {"DeactiveModule", reinterpret_cast<void**>(&deactivate_api_)}, + {"UnregisterModule", reinterpret_cast<void**>(&unregister_api_)}, + }; auto get_gpc() -> GlobalModuleContext* { if (gpc_ == nullptr) { @@ -84,8 +163,25 @@ Module::Module(ModuleIdentifier id, ModuleVersion version, const ModuleMetaData& meta_data) : p_(SecureCreateUniqueObject<Impl>(this, id, version, meta_data)) {} +Module::Module(QLibrary& module_library) + : p_(SecureCreateUniqueObject<Impl>(this, module_library)) {} + Module::~Module() = default; +auto Module::IsGood() -> bool { return p_->IsGood(); } + +auto Module::Register() -> int { return p_->Register(); } + +auto Module::Active() -> int { return p_->Active(); } + +auto Module::Exec(EventRefrernce event) -> int { + return p_->Exec(std::move(event)); +} + +auto Module::Deactive() -> int { return p_->Deactive(); } + +auto Module::UnRegister() -> int { return p_->UnRegister(); } + auto Module::getChannel() -> int { return p_->GetChannel(); } auto Module::getDefaultChannel() -> int { return p_->GetDefaultChannel(); } diff --git a/src/core/module/Module.h b/src/core/module/Module.h index 2a5b54e7..5eb214cc 100644 --- a/src/core/module/Module.h +++ b/src/core/module/Module.h @@ -30,6 +30,7 @@ #include "core/module/Event.h" #include "core/thread/TaskRunner.h" +#include "module/sdk/Module.h" namespace GpgFrontend::Module { @@ -47,21 +48,27 @@ using TaskRunnerPtr = std::shared_ptr<Thread::TaskRunner>; class GPGFRONTEND_CORE_EXPORT Module : public QObject { Q_OBJECT public: - Module(ModuleIdentifier, ModuleVersion, const ModuleMetaData&); + Module(ModuleIdentifier, ModuleVersion, const ModuleMetaData &); + + explicit Module(QLibrary &module_library); ~Module(); - virtual auto Register() -> bool = 0; + auto IsGood() -> bool; + + virtual auto Register() -> int; + + virtual auto Active() -> int; - virtual auto Active() -> bool = 0; + virtual auto Exec(EventRefrernce) -> int; - virtual auto Exec(EventRefrernce) -> int = 0; + virtual auto Deactive() -> int; - virtual auto Deactive() -> bool = 0; + virtual auto UnRegister() -> int; [[nodiscard]] auto GetModuleIdentifier() const -> ModuleIdentifier; - void SetGPC(GlobalModuleContext*); + void SetGPC(GlobalModuleContext *); protected: auto getChannel() -> int; diff --git a/src/core/module/ModuleManager.cpp b/src/core/module/ModuleManager.cpp index 83e7c1ff..17191af2 100644 --- a/src/core/module/ModuleManager.cpp +++ b/src/core/module/ModuleManager.cpp @@ -29,16 +29,17 @@ #include "ModuleManager.h" #include <memory> +#include <utility> #include "GpgConstants.h" +#include "core/function/SecureMemoryAllocator.h" +#include "core/function/basic/GpgFunctionObject.h" #include "core/module/GlobalModuleContext.h" #include "core/module/GlobalRegisterTable.h" #include "core/module/Module.h" #include "core/thread/Task.h" -#include "function/SecureMemoryAllocator.h" -#include "function/basic/GpgFunctionObject.h" -#include "thread/TaskRunnerGetter.h" -#include "utils/MemoryUtils.h" +#include "core/thread/TaskRunnerGetter.h" +#include "core/utils/MemoryUtils.h" namespace GpgFrontend::Module { @@ -50,13 +51,57 @@ class ModuleManager::Impl { ~Impl() = default; + auto LoadAndRegisterModule(const QString& module_library_path) -> void { + Thread::TaskRunnerGetter::GetInstance() + .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Default) + ->PostTask(new Thread::Task( + [=](GpgFrontend::DataObjectPtr) -> int { + QLibrary module_library(module_library_path); + if (!module_library.load()) { + GF_CORE_LOG_WARN( + "module manager failed to load module, " + "reason: broken library: {} ", + module_library.fileName()); + return -1; + } + + auto module = SecureCreateSharedObject<Module>(module_library); + if (!module->IsGood()) { + GF_CORE_LOG_WARN( + "module manager failed to load module, " + "reason: illegal module: {}", + module_library.fileName()); + return -1; + } + + module->SetGPC(gmc_.get()); + return gmc_->RegisterModule(module) ? 0 : -1; + }, + __func__, nullptr)); + } + + auto SearchModule(ModuleIdentifier module_id) -> ModulePtr { + return gmc_->SearchModule(std::move(module_id)); + } + void RegisterModule(const ModulePtr& module) { Thread::TaskRunnerGetter::GetInstance() .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Default) ->PostTask(new Thread::Task( [=](GpgFrontend::DataObjectPtr) -> int { module->SetGPC(gmc_.get()); - gmc_->RegisterModule(module); + return gmc_->RegisterModule(module) ? 0 : -1; + }, + __func__, nullptr)); + } + + void ListenEvent(const ModuleIdentifier& module_id, + const EventIdentifier& event_id) { + Thread::TaskRunnerGetter::GetInstance() + .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Default) + ->PostTask(new Thread::Task( + [=](const GpgFrontend::DataObjectPtr&) -> int { + gmc_->ListenEvent(module_id, event_id); return 0; }, __func__, nullptr)); @@ -73,6 +118,11 @@ class ModuleManager::Impl { __func__, nullptr)); } + auto SearchEvent(EventTriggerIdentifier trigger_id) + -> std::optional<EventRefrernce> { + return gmc_->SearchEvent(std::move(trigger_id)); + } + void ActiveModule(const ModuleIdentifier& identifier) { Thread::TaskRunnerGetter::GetInstance() .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Default) @@ -113,6 +163,7 @@ class ModuleManager::Impl { static ModuleMangerPtr global_module_manager; SecureUniquePtr<GlobalModuleContext> gmc_; SecureUniquePtr<GlobalRegisterTable> grt_; + QList<QLibrary> module_libraries_; }; auto IsModuleAcivate(ModuleIdentifier id) -> bool { @@ -141,14 +192,32 @@ ModuleManager::ModuleManager(int channel) ModuleManager::~ModuleManager() = default; +void ModuleManager::LoadModule(QString module_library_path) { + return p_->LoadAndRegisterModule(module_library_path); +} + +auto ModuleManager::SearchModule(ModuleIdentifier module_id) -> ModulePtr { + return p_->SearchModule(std::move(module_id)); +} + void ModuleManager::RegisterModule(ModulePtr module) { return p_->RegisterModule(module); } +void ModuleManager::ListenEvent(ModuleIdentifier module, + EventIdentifier event) { + return p_->ListenEvent(module, event); +} + void ModuleManager::TriggerEvent(EventRefrernce event) { return p_->TriggerEvent(event); } +auto ModuleManager::SearchEvent(EventTriggerIdentifier trigger_id) + -> std::optional<EventRefrernce> { + return p_->SearchEvent(std::move(trigger_id)); +} + void ModuleManager::ActiveModule(ModuleIdentifier id) { return p_->ActiveModule(id); } diff --git a/src/core/module/ModuleManager.h b/src/core/module/ModuleManager.h index 93b89e95..5bebe934 100644 --- a/src/core/module/ModuleManager.h +++ b/src/core/module/ModuleManager.h @@ -65,12 +65,20 @@ class GPGFRONTEND_CORE_EXPORT ModuleManager virtual ~ModuleManager() override; + auto LoadModule(QString) -> void; + + auto SearchModule(ModuleIdentifier) -> ModulePtr; + void RegisterModule(ModulePtr); auto IsModuleActivated(ModuleIdentifier) -> bool; + void ListenEvent(ModuleIdentifier, EventIdentifier); + void TriggerEvent(EventRefrernce); + auto SearchEvent(EventTriggerIdentifier) -> std::optional<EventRefrernce>; + void ActiveModule(ModuleIdentifier); void DeactiveModule(ModuleIdentifier); diff --git a/src/core/utils/CommonUtils.cpp b/src/core/utils/CommonUtils.cpp index 0b182241..36dfe0a7 100644 --- a/src/core/utils/CommonUtils.cpp +++ b/src/core/utils/CommonUtils.cpp @@ -71,4 +71,14 @@ auto CompareSoftwareVersion(const QString& a, const QString& b) -> int { return 0; } + +auto GPGFRONTEND_CORE_EXPORT GFStrDup(const QString& str) -> char* { + auto utf8_str = str.toUtf8(); + auto* c_str = + static_cast<char*>(SecureMalloc((utf8_str.size() + 1) * sizeof(char))); + + memcpy(c_str, utf8_str.constData(), utf8_str.size()); + c_str[utf8_str.size()] = '\0'; + return c_str; +} } // namespace GpgFrontend
\ No newline at end of file diff --git a/src/core/utils/CommonUtils.h b/src/core/utils/CommonUtils.h index a45c6056..d348cc71 100644 --- a/src/core/utils/CommonUtils.h +++ b/src/core/utils/CommonUtils.h @@ -51,4 +51,11 @@ auto GPGFRONTEND_CORE_EXPORT BeautifyFingerprint(QString fingerprint) auto GPGFRONTEND_CORE_EXPORT CompareSoftwareVersion(const QString& a, const QString& b) -> int; +/** + * @brief + * + * @return char* + */ +auto GPGFRONTEND_CORE_EXPORT GFStrDup(const QString&) -> char*; + } // namespace GpgFrontend
\ No newline at end of file diff --git a/src/module/CMakeLists.txt b/src/module/CMakeLists.txt index a741f0af..90b695af 100644 --- a/src/module/CMakeLists.txt +++ b/src/module/CMakeLists.txt @@ -94,7 +94,7 @@ endif () # link all integrated modules message(STATUS "All Module Libraries: ${all_integrated_module_libraries}") -target_link_libraries(gpgfrontend_module PRIVATE ${all_integrated_module_libraries}) +# target_link_libraries(gpgfrontend_module PRIVATE ${all_integrated_module_libraries}) # using std c++ 17 target_compile_features(gpgfrontend_module PUBLIC cxx_std_17)
\ No newline at end of file diff --git a/src/module/GpgFrontendModule.h b/src/module/GpgFrontendModule.h index cf7d8557..8277a4f4 100644 --- a/src/module/GpgFrontendModule.h +++ b/src/module/GpgFrontendModule.h @@ -34,3 +34,13 @@ #include "GpgFrontend.h" #include "GpgFrontendModuleExport.h" #include "core/GpgFrontendCore.h" + +/** + * @brief logger for inner + * + */ +#define MODULE_LOG_TRACE(...) GF_LOG_TRACE("module", __VA_ARGS__) +#define MODULE_LOG_DEBUG(...) GF_LOG_DEBUG("module", __VA_ARGS__) +#define MODULE_LOG_INFO(...) GF_LOG_INFO("module", __VA_ARGS__) +#define MODULE_LOG_WARN(...) GF_LOG_WARN("module", __VA_ARGS__) +#define MODULE_LOG_ERROR(...) GF_LOG_ERROR("module", __VA_ARGS__) diff --git a/src/module/GpgFrontendModuleInit.cpp b/src/module/GpgFrontendModuleInit.cpp index 6f88b9ec..2b1d8ac9 100644 --- a/src/module/GpgFrontendModuleInit.cpp +++ b/src/module/GpgFrontendModuleInit.cpp @@ -30,14 +30,10 @@ #include <core/module/ModuleManager.h> +#include "Module.h" #include "core/thread/Task.h" #include "core/thread/TaskRunnerGetter.h" -// integrated modules -#include "integrated/gnupg_info_gathering_module/GnuPGInfoGatheringModule.h" -#include "integrated/version_checking_module/VersionCheckingModule.h" -#include "spdlog/common.h" - namespace GpgFrontend::Module { void LoadGpgFrontendModules(ModuleInitArgs) { @@ -45,17 +41,28 @@ void LoadGpgFrontendModules(ModuleInitArgs) { Thread::TaskRunnerGetter::GetInstance().GetTaskRunner()->PostTask( new Thread::Task( [](const DataObjectPtr&) -> int { - MODULE_LOG_INFO("loading integrated module..."); + MODULE_LOG_INFO("loading modules..."); + + auto exec_binary_path = QCoreApplication::applicationDirPath(); + auto mods_path = exec_binary_path + "/mods"; + + if (!QDir(mods_path).exists()) { + MODULE_LOG_WARN("module directory not found, abort..."); + return -1; + } - // VersionCheckingModule - RegisterAndActivateModule< - Integrated::VersionCheckingModule::VersionCheckingModule>(); + MODULE_LOG_INFO("the path of modules directory: {}", mods_path); - // VersionCheckingModule - RegisterAndActivateModule<Integrated::GnuPGInfoGatheringModule:: - GnuPGInfoGatheringModule>(); + for (const auto& module_library_name : + QDir(mods_path).entryList(QStringList() << "*.so" + << "*.dll" + << "*.dylib", + QDir::Files)) { + ModuleManager::GetInstance().LoadModule(mods_path + "/" + + module_library_name); + } - MODULE_LOG_INFO("load integrated module done."); + MODULE_LOG_INFO("load modules done."); return 0; }, "modules_system_init_task")); diff --git a/src/module/integrated/gnupg_info_gathering_module/CMakeLists.txt b/src/module/integrated/gnupg_info_gathering_module/CMakeLists.txt index 48dbd0de..cdd2f5b6 100644 --- a/src/module/integrated/gnupg_info_gathering_module/CMakeLists.txt +++ b/src/module/integrated/gnupg_info_gathering_module/CMakeLists.txt @@ -28,12 +28,14 @@ aux_source_directory(. INTEGRATED_MODULE_SOURCE) # define libgpgfrontend_module -add_library(gpgfrontend_integrated_module_gnupg_info_gathering SHARED ${INTEGRATED_MODULE_SOURCE}) +add_library(gpgfrontend_gnupg_info_gathering SHARED ${INTEGRATED_MODULE_SOURCE}) set(_export_file "${CMAKE_CURRENT_SOURCE_DIR}/GpgFrontendModuleExport.h") -generate_export_header(gpgfrontend_integrated_module_gnupg_info_gathering EXPORT_FILE_NAME "${_export_file}") +generate_export_header(gpgfrontend_gnupg_info_gathering + BASE_NAME "GF_MODULE" + EXPORT_FILE_NAME "${_export_file}") if (XCODE_BUILD) - set_target_properties(gpgfrontend_integrated_module_gnupg_info_gathering + set_target_properties(gpgfrontend_gnupg_info_gathering PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE} LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE} @@ -43,11 +45,15 @@ if (XCODE_BUILD) endif () # link sdk -target_link_libraries(gpgfrontend_integrated_module_gnupg_info_gathering PRIVATE +target_link_libraries(gpgfrontend_gnupg_info_gathering PRIVATE gpgfrontend_module_sdk) +# set output directory +set_target_properties(gpgfrontend_gnupg_info_gathering PROPERTIES + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/mods) + # property -set_property(TARGET gpgfrontend_integrated_module_gnupg_info_gathering PROPERTY AUTOMOC ON) +set_property(TARGET gpgfrontend_gnupg_info_gathering PROPERTY AUTOMOC ON) # using std c++ 17 -target_compile_features(gpgfrontend_integrated_module_gnupg_info_gathering PRIVATE cxx_std_17)
\ No newline at end of file +target_compile_features(gpgfrontend_gnupg_info_gathering PRIVATE cxx_std_17)
\ No newline at end of file diff --git a/src/module/integrated/gnupg_info_gathering_module/GnuPGInfoGatheringModule.cpp b/src/module/integrated/gnupg_info_gathering_module/GnuPGInfoGatheringModule.cpp index a1e5cd5a..67dd5227 100644 --- a/src/module/integrated/gnupg_info_gathering_module/GnuPGInfoGatheringModule.cpp +++ b/src/module/integrated/gnupg_info_gathering_module/GnuPGInfoGatheringModule.cpp @@ -28,29 +28,162 @@ #include "GnuPGInfoGatheringModule.h" -#include <vector> - +#include "Basic.h" #include "GpgInfo.h" #include "Log.h" -#include "core/function/gpg/GpgCommandExecutor.h" -#include "core/module/ModuleManager.h" -namespace GpgFrontend::Module::Integrated::GnuPGInfoGatheringModule { +ModuleMetaData *g_module_metadata = nullptr; + +extern auto CheckBinaryChacksum(QString path) -> std::optional<QString>; + +extern void GetGpgComponentInfos(void *, int, const char *, const char *); + +extern void GetGpgDirectoryInfos(void *, int, const char *, const char *); + +extern void GetGpgOptionInfos(void *, int, const char *, const char *); + +using Context = struct { + QString gpgme_version; + QString gpgconf_path; + GpgComponentInfo component_info; +}; + +auto RegisterModule() -> int { + ModuleLogDebug("gnupg info gathering module registering"); + + g_module_metadata = + static_cast<ModuleMetaData *>(AllocateMemory(sizeof(ModuleMetaData))); + + auto *p_meta = g_module_metadata; + p_meta->key = "description"; + p_meta->value = "try to gathering gnupg informations"; + p_meta->next = + static_cast<ModuleMetaData *>(AllocateMemory(sizeof(ModuleMetaData))); + p_meta = p_meta->next; + p_meta->key = "author"; + p_meta->value = "saturneric"; + p_meta->next = nullptr; + return 0; +} + +auto GetModuleID() -> const char * { + return "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering"; +} + +auto GetModuleVersion() -> const char * { return "1.0.0"; } + +auto GetModuleMetaData() -> ModuleMetaData * { return g_module_metadata; } + +auto ActiveModule() -> int { + ModuleLogDebug("gnupg info gathering module activating"); + ListenEvent(GetModuleID(), "GPGFRONTEND_CORE_INITLIZED"); + return 0; +} + +auto ExecuteModule(ModuleEvent *event) -> int { + ModuleLogDebug( + fmt::format("gnupg info gathering module executing, event id: {}", + event->id) + .c_str()); + + ModuleLogDebug("start to load extra info at module gnupginfogathering..."); + + const auto *const gpgme_version = + RetrieveRTValueOrDefault("core", "gpgme.version", "0.0.0"); + ModuleLogDebug( + fmt::format("got gpgme version from rt: {}", gpgme_version).c_str()); + + const auto *const gpgconf_path = + RetrieveRTValueOrDefault("core", "gpgme.ctx.gpgconf_path", ""); + ModuleLogDebug( + fmt::format("got gpgconf path from rt: {}", gpgconf_path).c_str()); + + auto context = Context{gpgme_version, gpgconf_path}; + + // get all components + const char *argv[] = {"--list-components"}; + ExecuteCommandSync(gpgconf_path, 1, argv, GetGpgComponentInfos, &context); + + QList<CommandExecuteContext> exec_contexts; + + const char *argv_0[] = {"--list-dirs"}; + exec_contexts.push_back( + {gpgconf_path, 1, argv_0, GetGpgDirectoryInfos, nullptr}); + + char **components_c_array; + int ret = + ListRTChildKeys(GetModuleID(), "gnupg.components", &components_c_array); + if (components_c_array == nullptr || ret == 0) return -1; + + QStringList components; + auto *p_a = components_c_array; + for (int i = 0; i < ret; i++) components.append(QString::fromUtf8(p_a[i])); + + for (const auto &component : components) { + const auto *component_info_json = RetrieveRTValueOrDefault( + GetModuleID(), QString("gnupg.components.%1").arg(component).toUtf8(), + nullptr); + + auto jsonlized_component_info = + QJsonDocument::fromJson(component_info_json); + assert(jsonlized_component_info.isObject()); + + auto component_info = GpgComponentInfo(jsonlized_component_info.object()); + ModuleLogDebug(fmt::format("gpgconf check options ready, component: {}", + component_info.name) + .c_str()); + + if (component_info.name == "gpgme" || component_info.name == "gpgconf") { + continue; + } + + auto context = Context{gpgme_version, gpgconf_path, component_info}; + + const char *argv_0[] = {"--list-options", component_info.name.toUtf8()}; + exec_contexts.push_back( + {gpgconf_path, 1, argv_0, GetGpgDirectoryInfos, &context}); + } + + ExecuteCommandBatchSync(static_cast<int32_t>(exec_contexts.size()), + exec_contexts.constData()); + + UpsertRTValue(GetModuleID(), "gnupg.gathering_done", "true"); + + char **event_argv = static_cast<char **>(AllocateMemory(sizeof(char *) * 1)); + event_argv[0] = static_cast<char *>(AllocateMemory(5)); + memcpy(event_argv[0], "true", 4); + event_argv[0][4] = '\0'; + + TriggerModuleEventCallback(event, GetModuleID(), 1, event_argv); + + ModuleLogDebug("gnupg external info gathering done"); + return 0; +} + +auto DeactiveModule() -> int { return 0; } + +auto UnregisterModule() -> int { + ModuleLogDebug("gnupg info gathering module unregistering"); + FreeMemory(g_module_metadata); + return 0; +} auto CheckBinaryChacksum(QString path) -> std::optional<QString> { // check file info and access rights QFileInfo info(path); if (!info.exists() || !info.isFile() || !info.isReadable()) { - MODULE_LOG_ERROR("get info for file {} error, exists: {}", info.filePath(), - info.exists()); + ModuleLogError(fmt::format("get info for file {} error, exists: {}", + info.filePath(), info.exists()) + .c_str()); return {}; } // open and read file QFile f(info.filePath()); if (!f.open(QIODevice::ReadOnly)) { - MODULE_LOG_ERROR("open {} to calculate check sum error: {}", path, - f.errorString()); + ModuleLogError(fmt::format("open {} to calculate check sum error: {}", path, + f.errorString()) + .c_str()); return {}; } @@ -64,289 +197,215 @@ auto CheckBinaryChacksum(QString path) -> std::optional<QString> { return QString(hash_sha.result().toHex()).left(6); } -GnuPGInfoGatheringModule::GnuPGInfoGatheringModule() - : Module( - "com.bktus.gpgfrontend.module.integrated.gnupg-info-gathering", - "1.0.0", - ModuleMetaData{{"description", "try to gathering gnupg informations"}, - {"author", "saturneric"}}) {} - -GnuPGInfoGatheringModule::~GnuPGInfoGatheringModule() = default; - -auto GnuPGInfoGatheringModule::Register() -> bool { - MODULE_LOG_DEBUG("gnupg info gathering module registering"); - listenEvent("GPGFRONTEND_CORE_INITLIZED"); - return true; -} - -auto GnuPGInfoGatheringModule::Active() -> bool { - MODULE_LOG_DEBUG("gnupg info gathering module activating"); - return true; -} - -auto GnuPGInfoGatheringModule::Exec(EventRefrernce event) -> int { - MODULE_LOG_DEBUG("gnupg info gathering module executing, event id: {}", - event->GetIdentifier()); - - const auto gpgme_version = RetrieveRTValueTypedOrDefault<>( - "core", "gpgme.version", QString{"0.0.0"}); - MODULE_LOG_DEBUG("got gpgme version from rt: {}", gpgme_version); - - const auto gpgconf_path = RetrieveRTValueTypedOrDefault<>( - "core", "gpgme.ctx.gpgconf_path", QString{}); - MODULE_LOG_DEBUG("got gpgconf path from rt: {}", gpgconf_path); +void GetGpgComponentInfos(void *data, int exit_code, const char *out, + const char *err) { + auto *context = reinterpret_cast<Context *>(data); + auto p_out = QString::fromUtf8(out); + auto p_err = QString::fromUtf8(err); + + ModuleLogDebug( + fmt::format("gpgconf components exit_code: {} process stdout size: {}", + exit_code, p_out.size()) + .c_str()); + + if (exit_code != 0) { + ModuleLogError(fmt::format("gpgconf execute error, process stderr: {}, " + "process stdout: {}", + p_err, p_out) + .c_str()); + return; + } - MODULE_LOG_DEBUG("start to load extra info at module gnupginfogathering..."); - - // get all components - GpgCommandExecutor::ExecuteSync( - {gpgconf_path, QStringList{"--list-components"}, - [this, gpgme_version, gpgconf_path](int exit_code, const QString &p_out, - const QString &p_err) { - MODULE_LOG_DEBUG( - "gpgconf components exit_code: {} process stdout size: {}", - exit_code, p_out.size()); - - if (exit_code != 0) { - MODULE_LOG_ERROR( - "gpgconf execute error, process stderr: {}, " - "process stdout: {}", - p_err, p_out); - return; - } - - std::vector<GpgComponentInfo> component_infos; - GpgComponentInfo c_i_gpgme; - c_i_gpgme.name = "gpgme"; - c_i_gpgme.desc = "GPG Made Easy"; - c_i_gpgme.version = gpgme_version; - c_i_gpgme.path = tr("Embedded In"); - c_i_gpgme.binary_checksum = "/"; - - GpgComponentInfo c_i_gpgconf; - c_i_gpgconf.name = "gpgconf"; - c_i_gpgconf.desc = "GPG Configure"; - c_i_gpgconf.version = "/"; - c_i_gpgconf.path = gpgconf_path; - auto gpgconf_binary_checksum = CheckBinaryChacksum(gpgconf_path); - c_i_gpgconf.binary_checksum = (gpgconf_binary_checksum.has_value() - ? gpgconf_binary_checksum.value() - : QString("/")); - - component_infos.push_back(c_i_gpgme); - component_infos.push_back(c_i_gpgconf); - - auto const jsonlized_gpgme_component_info = c_i_gpgme.Json(); - auto const jsonlized_gpgconf_component_info = c_i_gpgconf.Json(); - UpsertRTValue(GetModuleIdentifier(), "gnupg.components.gpgme", - QJsonDocument(jsonlized_gpgme_component_info).toJson()); - UpsertRTValue( - GetModuleIdentifier(), "gnupg.components.gpgconf", - QJsonDocument(jsonlized_gpgconf_component_info).toJson()); - - auto line_split_list = p_out.split("\n"); - - for (const auto &line : line_split_list) { - auto info_split_list = line.split(":"); - - if (info_split_list.size() != 3) continue; - - auto component_name = info_split_list[0].trimmed(); - auto component_desc = info_split_list[1].trimmed(); - auto component_path = info_split_list[2].trimmed(); + std::vector<GpgComponentInfo> component_infos; + GpgComponentInfo c_i_gpgme; + c_i_gpgme.name = "gpgme"; + c_i_gpgme.desc = "GPG Made Easy"; + c_i_gpgme.version = context->gpgme_version; + c_i_gpgme.path = "Embedded In"; + c_i_gpgme.binary_checksum = "/"; + + GpgComponentInfo c_i_gpgconf; + c_i_gpgconf.name = "gpgconf"; + c_i_gpgconf.desc = "GPG Configure"; + c_i_gpgconf.version = "/"; + c_i_gpgconf.path = context->gpgconf_path; + auto gpgconf_binary_checksum = CheckBinaryChacksum(context->gpgconf_path); + c_i_gpgconf.binary_checksum = + (gpgconf_binary_checksum.has_value() ? gpgconf_binary_checksum.value() + : QString("/")); + + component_infos.push_back(c_i_gpgme); + component_infos.push_back(c_i_gpgconf); + + auto const jsonlized_gpgme_component_info = c_i_gpgme.Json(); + auto const jsonlized_gpgconf_component_info = c_i_gpgconf.Json(); + UpsertRTValue(GetModuleID(), "gnupg.components.gpgme", + QJsonDocument(jsonlized_gpgme_component_info).toJson()); + UpsertRTValue(GetModuleID(), "gnupg.components.gpgconf", + QJsonDocument(jsonlized_gpgconf_component_info).toJson()); + + auto line_split_list = p_out.split("\n"); + + for (const auto &line : line_split_list) { + auto info_split_list = line.split(":"); + + if (info_split_list.size() != 3) continue; + + auto component_name = info_split_list[0].trimmed(); + auto component_desc = info_split_list[1].trimmed(); + auto component_path = info_split_list[2].trimmed(); #ifdef WINDOWS - // replace some special substrings on windows platform - component_path.replace("%3a", ":"); -#endif - - auto binary_checksum = CheckBinaryChacksum(component_path); - - MODULE_LOG_DEBUG( - "gnupg component name: {} desc: {} checksum: {} path: {} ", - component_name, component_desc, - binary_checksum.has_value() ? binary_checksum.value() : "/", - component_path); - - QString version = "/"; - - if (component_name == "gpg") { - version = RetrieveRTValueTypedOrDefault<>( - "core", "gpgme.ctx.gnupg_version", QString{"2.0.0"}); - } - if (component_name == "gpg-agent") { - UpsertRTValue(GetModuleIdentifier(), "gnupg.gpg_agent_path", - QString(component_path)); - } - if (component_name == "dirmngr") { - UpsertRTValue(GetModuleIdentifier(), "gnupg.dirmngr_path", - QString(component_path)); - } - if (component_name == "keyboxd") { - UpsertRTValue(GetModuleIdentifier(), "gnupg.keyboxd_path", - QString(component_path)); - } - - { - GpgComponentInfo c_i; - c_i.name = component_name; - c_i.desc = component_desc; - c_i.version = version; - c_i.path = component_path; - c_i.binary_checksum = - (binary_checksum.has_value() ? binary_checksum.value() - : QString("/")); - - auto const jsonlized_component_info = c_i.Json(); - UpsertRTValue(GetModuleIdentifier(), - QString("gnupg.components.%1").arg(component_name), - QJsonDocument(jsonlized_component_info).toJson()); - - component_infos.push_back(c_i); - } - } - }, - getTaskRunner()}); - - GpgCommandExecutor::ExecuteContexts exec_contexts; -#ifdef QT5_BUILD - exec_contexts.push_back(GpgCommandExecutor::ExecuteContext{ -#else - exec_contexts.emplace_back(GpgCommandExecutor::ExecuteContext{ + // replace some special substrings on windows platform + component_path.replace("%3a", ":"); #endif - gpgconf_path, QStringList{"--list-dirs"}, - [this](int exit_code, const QString &p_out, const QString &p_err) { - if (exit_code != 0) return; - auto line_split_list = p_out.split("\n"); + auto binary_checksum = CheckBinaryChacksum(component_path); - for (const auto &line : line_split_list) { - auto info_split_list = line.split(":"); - MODULE_LOG_DEBUG("gpgconf direcrotries info line: {} info size: {}", - line, info_split_list.size()); + ModuleLogDebug( + fmt::format("gnupg component name: {} desc: {} checksum: {} path: {} ", + component_name, component_desc, + binary_checksum.has_value() ? binary_checksum.value() : "/", + component_path) + .c_str()); - if (info_split_list.size() != 2) continue; + QString version = "/"; - auto configuration_name = info_split_list[0].trimmed(); - auto configuration_value = info_split_list[1].trimmed(); + if (component_name == "gpg") { + version = + RetrieveRTValueOrDefault("core", "gpgme.ctx.gnupg_version", "2.0.0"); + } + if (component_name == "gpg-agent") { + UpsertRTValue(GetModuleID(), "gnupg.gpg_agent_path", + QString(component_path).toUtf8()); + } + if (component_name == "dirmngr") { + UpsertRTValue(GetModuleID(), "gnupg.dirmngr_path", + QString(component_path).toUtf8()); + } + if (component_name == "keyboxd") { + UpsertRTValue(GetModuleID(), "gnupg.keyboxd_path", + QString(component_path).toUtf8()); + } -#ifdef WINDOWS - // replace some special substrings on windows platform - configuration_value.replace("%3a", ":"); -#endif + { + GpgComponentInfo c_i; + c_i.name = component_name; + c_i.desc = component_desc; + c_i.version = version; + c_i.path = component_path; + c_i.binary_checksum = + (binary_checksum.has_value() ? binary_checksum.value() + : QString("/")); + + auto const jsonlized_component_info = c_i.Json(); + UpsertRTValue(GetModuleID(), + QString("gnupg.components.%1").arg(component_name).toUtf8(), + QJsonDocument(jsonlized_component_info).toJson()); + + component_infos.push_back(c_i); + } + } +} - // record gnupg home path - if (configuration_name == "homedir") { - UpsertRTValue(GetModuleIdentifier(), "gnupg.home_path", - configuration_value); - } +void GetGpgDirectoryInfos(void *, int exit_code, const char *out, + const char *err) { + if (exit_code != 0) return; - UpsertRTValue(GetModuleIdentifier(), - QString("gnupg.dirs.%1").arg(configuration_name), - configuration_value); - } - }, - getTaskRunner()}); + auto p_out = QString::fromUtf8(out); + auto p_err = QString::fromUtf8(err); + auto line_split_list = p_out.split("\n"); - auto components = ListRTChildKeys(GetModuleIdentifier(), "gnupg.components"); + for (const auto &line : line_split_list) { + auto info_split_list = line.split(":"); + ModuleLogDebug( + fmt::format("gpgconf direcrotries info line: {} info size: {}", line, + info_split_list.size()) + .c_str()); - for (const auto &component : components) { - auto component_info_json = RetrieveRTValueTypedOrDefault( - GetModuleIdentifier(), QString("gnupg.components.%1").arg(component), - QByteArray{}); + if (info_split_list.size() != 2) continue; - auto jsonlized_component_info = - QJsonDocument::fromJson(component_info_json); - assert(jsonlized_component_info.isObject()); + auto configuration_name = info_split_list[0].trimmed(); + auto configuration_value = info_split_list[1].trimmed(); - auto component_info = GpgComponentInfo(jsonlized_component_info.object()); - MODULE_LOG_DEBUG("gpgconf check options ready, component: {}", - component_info.name); +#ifdef WINDOWS + // replace some special substrings on windows platform + configuration_value.replace("%3a", ":"); +#endif - if (component_info.name == "gpgme" || component_info.name == "gpgconf") { - continue; + // record gnupg home path + if (configuration_name == "homedir") { + UpsertRTValue(GetModuleID(), "gnupg.home_path", + configuration_value.toUtf8()); } -#ifdef QT5_BUILD - exec_contexts.push_back(GpgCommandExecutor::ExecuteContext{ -#else - exec_contexts.emplace_back(GpgCommandExecutor::ExecuteContext{ -#endif - gpgconf_path, QStringList{"--list-options", component_info.name}, - [this, component_info](int exit_code, const QString &p_out, - const QString &p_err) { - MODULE_LOG_DEBUG( - "gpgconf {} avaliable options exit_code: {} process stdout " - "size: {} ", - component_info.name, exit_code, p_out.size()); - - if (exit_code != 0) { - MODULE_LOG_ERROR( - "gpgconf {} avaliable options execute error, process stderr: " - "{} , process stdout:", - component_info.name, p_err, p_out); - return; - } - - std::vector<GpgOptionsInfo> options_infos; - - auto line_split_list = p_out.split("\n"); - - for (const auto &line : line_split_list) { - auto info_split_list = line.split(":"); - - MODULE_LOG_DEBUG( - "component {} avaliable options line: {} info size: {}", - component_info.name, line, info_split_list.size()); - - if (info_split_list.size() < 10) continue; - - // The format of each line is: - // name:flags:level:description:type:alt-type:argname:default:argdef:value - - auto option_name = info_split_list[0].trimmed(); - auto option_flags = info_split_list[1].trimmed(); - auto option_level = info_split_list[2].trimmed(); - auto option_desc = info_split_list[3].trimmed(); - auto option_type = info_split_list[4].trimmed(); - auto option_alt_type = info_split_list[5].trimmed(); - auto option_argname = info_split_list[6].trimmed(); - auto option_default = info_split_list[7].trimmed(); - auto option_argdef = info_split_list[8].trimmed(); - auto option_value = info_split_list[9].trimmed(); - - GpgOptionsInfo info; - info.name = option_name; - info.flags = option_flags; - info.level = option_level; - info.description = option_desc; - info.type = option_type; - info.alt_type = option_alt_type; - info.argname = option_argname; - info.default_value = option_default; - info.argdef = option_argdef; - info.value = option_value; - - auto const jsonlized_option_info = info.Json(); - UpsertRTValue(GetModuleIdentifier(), - QString("gnupg.components.%1.options.%2") - .arg(component_info.name) - .arg(option_name), - QJsonDocument(jsonlized_option_info).toJson()); - options_infos.push_back(info); - } - }, - getTaskRunner()}); + UpsertRTValue(GetModuleID(), + QString("gnupg.dirs.%1").arg(configuration_name).toUtf8(), + configuration_value.toUtf8()); } - - GpgCommandExecutor::ExecuteConcurrentlySync(exec_contexts); - UpsertRTValue(GetModuleIdentifier(), "gnupg.gathering_done", true); - event->ExecuteCallback(GetModuleIdentifier(), TransferParams(true)); - - MODULE_LOG_DEBUG("gnupg external info gathering done"); - return 0; } -auto GnuPGInfoGatheringModule::Deactive() -> bool { return true; } - -} // namespace GpgFrontend::Module::Integrated::GnuPGInfoGatheringModule +void GetGpgOptionInfos(void *data, int exit_code, const char *out, + const char *err) { + if (exit_code != 0) return; + + auto p_out = QString::fromUtf8(out); + auto p_err = QString::fromUtf8(err); + auto *context = reinterpret_cast<Context *>(data); + + ModuleLogDebug( + fmt::format("gpgconf {} avaliable options exit_code: {} process stdout " + "size: {} ", + context->component_info.name, exit_code, p_out.size()) + .c_str()); + + std::vector<GpgOptionsInfo> options_infos; + + auto line_split_list = p_out.split("\n"); + + for (const auto &line : line_split_list) { + auto info_split_list = line.split(":"); + + ModuleLogDebug( + fmt::format("component {} avaliable options line: {} info size: {}", + context->component_info.name, line, info_split_list.size()) + .c_str()); + + if (info_split_list.size() < 10) continue; + + // The format of each line is: + // name:flags:level:description:type:alt-type:argname:default:argdef:value + + auto option_name = info_split_list[0].trimmed(); + auto option_flags = info_split_list[1].trimmed(); + auto option_level = info_split_list[2].trimmed(); + auto option_desc = info_split_list[3].trimmed(); + auto option_type = info_split_list[4].trimmed(); + auto option_alt_type = info_split_list[5].trimmed(); + auto option_argname = info_split_list[6].trimmed(); + auto option_default = info_split_list[7].trimmed(); + auto option_argdef = info_split_list[8].trimmed(); + auto option_value = info_split_list[9].trimmed(); + + GpgOptionsInfo info; + info.name = option_name; + info.flags = option_flags; + info.level = option_level; + info.description = option_desc; + info.type = option_type; + info.alt_type = option_alt_type; + info.argname = option_argname; + info.default_value = option_default; + info.argdef = option_argdef; + info.value = option_value; + + auto const jsonlized_option_info = info.Json(); + UpsertRTValue(GetModuleID(), + QString("gnupg.components.%1.options.%2") + .arg(context->component_info.name) + .arg(option_name) + .toUtf8(), + QJsonDocument(jsonlized_option_info).toJson()); + options_infos.push_back(info); + } +} diff --git a/src/module/integrated/gnupg_info_gathering_module/GnuPGInfoGatheringModule.h b/src/module/integrated/gnupg_info_gathering_module/GnuPGInfoGatheringModule.h index 88f64d7d..44adbab0 100644 --- a/src/module/integrated/gnupg_info_gathering_module/GnuPGInfoGatheringModule.h +++ b/src/module/integrated/gnupg_info_gathering_module/GnuPGInfoGatheringModule.h @@ -29,27 +29,23 @@ #pragma once #include "GpgFrontendModuleExport.h" -#include "core/module/Module.h" +#include "module/sdk/Module.h" -namespace GpgFrontend::Module::Integrated::GnuPGInfoGatheringModule { +extern "C" { -/** - * @brief Use to record some info about gnupg - * - */ -class GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_EXPORT - GnuPGInfoGatheringModule : public Module { - public: - GnuPGInfoGatheringModule(); +auto GF_MODULE_EXPORT GetModuleID() -> const char *; + +auto GF_MODULE_EXPORT GetModuleVersion() -> const char *; + +auto GF_MODULE_EXPORT GetModuleMetaData() -> ModuleMetaData *; - ~GnuPGInfoGatheringModule() override; +auto GF_MODULE_EXPORT RegisterModule() -> int; - auto Register() -> bool override; +auto GF_MODULE_EXPORT ActiveModule() -> int; - auto Active() -> bool override; +auto GF_MODULE_EXPORT ExecuteModule(ModuleEvent *) -> int; - auto Exec(EventRefrernce) -> int override; +auto GF_MODULE_EXPORT DeactiveModule() -> int; - auto Deactive() -> bool override; +auto GF_MODULE_EXPORT UnregisterModule() -> int; }; -} // namespace GpgFrontend::Module::Integrated::GnuPGInfoGatheringModule diff --git a/src/module/integrated/gnupg_info_gathering_module/GpgFrontendModuleExport.h b/src/module/integrated/gnupg_info_gathering_module/GpgFrontendModuleExport.h index 3a5ba68b..fd18dfb1 100644 --- a/src/module/integrated/gnupg_info_gathering_module/GpgFrontendModuleExport.h +++ b/src/module/integrated/gnupg_info_gathering_module/GpgFrontendModuleExport.h @@ -1,42 +1,42 @@ -#ifndef GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_EXPORT_H -#define GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_EXPORT_H +#ifndef GF_MODULE_EXPORT_H +#define GF_MODULE_EXPORT_H -#ifdef GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_STATIC_DEFINE -# define GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_EXPORT -# define GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_NO_EXPORT +#ifdef GF_MODULE_STATIC_DEFINE +# define GF_MODULE_EXPORT +# define GF_MODULE_NO_EXPORT #else -# ifndef GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_EXPORT -# ifdef gpgfrontend_integrated_module_gnupg_info_gathering_EXPORTS +# ifndef GF_MODULE_EXPORT +# ifdef gpgfrontend_gnupg_info_gathering_EXPORTS /* We are building this library */ -# define GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_EXPORT __attribute__((visibility("default"))) +# define GF_MODULE_EXPORT __attribute__((visibility("default"))) # else /* We are using this library */ -# define GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_EXPORT __attribute__((visibility("default"))) +# define GF_MODULE_EXPORT __attribute__((visibility("default"))) # endif # endif -# ifndef GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_NO_EXPORT -# define GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_NO_EXPORT __attribute__((visibility("hidden"))) +# ifndef GF_MODULE_NO_EXPORT +# define GF_MODULE_NO_EXPORT __attribute__((visibility("hidden"))) # endif #endif -#ifndef GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_DEPRECATED -# define GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_DEPRECATED __attribute__ ((__deprecated__)) +#ifndef GF_MODULE_DEPRECATED +# define GF_MODULE_DEPRECATED __attribute__ ((__deprecated__)) #endif -#ifndef GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_DEPRECATED_EXPORT -# define GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_DEPRECATED_EXPORT GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_EXPORT GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_DEPRECATED +#ifndef GF_MODULE_DEPRECATED_EXPORT +# define GF_MODULE_DEPRECATED_EXPORT GF_MODULE_EXPORT GF_MODULE_DEPRECATED #endif -#ifndef GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_DEPRECATED_NO_EXPORT -# define GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_DEPRECATED_NO_EXPORT GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_NO_EXPORT GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_DEPRECATED +#ifndef GF_MODULE_DEPRECATED_NO_EXPORT +# define GF_MODULE_DEPRECATED_NO_EXPORT GF_MODULE_NO_EXPORT GF_MODULE_DEPRECATED #endif #if 0 /* DEFINE_NO_DEPRECATED */ -# ifndef GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_NO_DEPRECATED -# define GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_NO_DEPRECATED +# ifndef GF_MODULE_NO_DEPRECATED +# define GF_MODULE_NO_DEPRECATED # endif #endif -#endif /* GPGFRONTEND_INTEGRATED_MODULE_GNUPG_INFO_GATHERING_EXPORT_H */ +#endif /* GF_MODULE_EXPORT_H */ diff --git a/src/module/integrated/gnupg_info_gathering_module/GpgInfo.cpp b/src/module/integrated/gnupg_info_gathering_module/GpgInfo.cpp index 2015bc0a..2aa9c455 100644 --- a/src/module/integrated/gnupg_info_gathering_module/GpgInfo.cpp +++ b/src/module/integrated/gnupg_info_gathering_module/GpgInfo.cpp @@ -28,8 +28,6 @@ #include "module/integrated/gnupg_info_gathering_module/GpgInfo.h" -namespace GpgFrontend::Module::Integrated::GnuPGInfoGatheringModule { - GpgOptionsInfo::GpgOptionsInfo(const QJsonObject &j) { if (const auto v = j["name"]; v.isString()) name = v.toString(); if (const auto v = j["flags"]; v.isString()) flags = v.toString(); @@ -38,8 +36,9 @@ GpgOptionsInfo::GpgOptionsInfo(const QJsonObject &j) { if (const auto v = j["type"]; v.isString()) type = v.toString(); if (const auto v = j["alt_type"]; v.isString()) alt_type = v.toString(); if (const auto v = j["argname"]; v.isString()) argname = v.toString(); - if (const auto v = j["default_value"]; v.isString()) + if (const auto v = j["default_value"]; v.isString()) { default_value = v.toString(); + } if (const auto v = j["argdef"]; v.isString()) argdef = v.toString(); if (const auto v = j["value"]; v.isString()) value = v.toString(); } @@ -74,7 +73,7 @@ GpgComponentInfo::GpgComponentInfo(const QJsonObject &j) { if (const auto v = j["desc"]; v.isString()) desc = v.toString(); if (const auto v = j["version"]; v.isString()) version = v.toString(); if (const auto v = j["path"]; v.isString()) path = v.toString(); - if (const auto v = j["binary_checksum"]; v.isString()) + if (const auto v = j["binary_checksum"]; v.isString()) { binary_checksum = v.toString(); + } } -} // namespace GpgFrontend::Module::Integrated::GnuPGInfoGatheringModule diff --git a/src/module/integrated/gnupg_info_gathering_module/GpgInfo.h b/src/module/integrated/gnupg_info_gathering_module/GpgInfo.h index fb12b811..97c9f6b5 100644 --- a/src/module/integrated/gnupg_info_gathering_module/GpgInfo.h +++ b/src/module/integrated/gnupg_info_gathering_module/GpgInfo.h @@ -28,7 +28,6 @@ #pragma once -namespace GpgFrontend::Module::Integrated::GnuPGInfoGatheringModule { /** * @brief Use to record some info about gnupg * @@ -83,5 +82,3 @@ struct GpgOptionsInfo { [[nodiscard]] auto Json() const -> QJsonObject; }; - -} // namespace GpgFrontend::Module::Integrated::GnuPGInfoGatheringModule diff --git a/src/module/integrated/version_checking_module/CMakeLists.txt b/src/module/integrated/version_checking_module/CMakeLists.txt index 76459b0e..232e64a6 100644 --- a/src/module/integrated/version_checking_module/CMakeLists.txt +++ b/src/module/integrated/version_checking_module/CMakeLists.txt @@ -28,12 +28,14 @@ aux_source_directory(. INTEGRATED_MODULE_SOURCE) # define libgpgfrontend_module -add_library(gpgfrontend_integrated_module_version_checking SHARED ${INTEGRATED_MODULE_SOURCE}) +add_library(gpgfrontend_version_checking SHARED ${INTEGRATED_MODULE_SOURCE}) set(_export_file "${CMAKE_CURRENT_SOURCE_DIR}/GpgFrontendModuleExport.h") -generate_export_header(gpgfrontend_integrated_module_version_checking EXPORT_FILE_NAME "${_export_file}") +generate_export_header(gpgfrontend_version_checking + BASE_NAME "GF_MODULE" + EXPORT_FILE_NAME "${_export_file}") if (XCODE_BUILD) - set_target_properties(gpgfrontend_integrated_module_version_checking + set_target_properties(gpgfrontend_version_checking PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE} LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE} @@ -43,19 +45,23 @@ if (XCODE_BUILD) endif () # link sdk -target_link_libraries(gpgfrontend_integrated_module_version_checking PRIVATE +target_link_libraries(gpgfrontend_version_checking PRIVATE gpgfrontend_module_sdk) if(GPGFRONTEND_QT5_BUILD) # link Qt - target_link_libraries(gpgfrontend_integrated_module_version_checking PUBLIC Qt5::Network) + target_link_libraries(gpgfrontend_version_checking PUBLIC Qt5::Network) else() # link Qt - target_link_libraries(gpgfrontend_integrated_module_version_checking PUBLIC Qt6::Network) + target_link_libraries(gpgfrontend_version_checking PUBLIC Qt6::Network) endif() +# set output directory +set_target_properties(gpgfrontend_version_checking PROPERTIES + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/mods) + # property -set_property(TARGET gpgfrontend_integrated_module_version_checking PROPERTY AUTOMOC ON) +set_property(TARGET gpgfrontend_version_checking PROPERTY AUTOMOC ON) # using std c++ 17 -target_compile_features(gpgfrontend_integrated_module_version_checking PRIVATE cxx_std_17)
\ No newline at end of file +target_compile_features(gpgfrontend_version_checking PRIVATE cxx_std_17)
\ No newline at end of file diff --git a/src/module/integrated/version_checking_module/GpgFrontendModuleExport.h b/src/module/integrated/version_checking_module/GpgFrontendModuleExport.h index 0ac60b2f..6e02c878 100644 --- a/src/module/integrated/version_checking_module/GpgFrontendModuleExport.h +++ b/src/module/integrated/version_checking_module/GpgFrontendModuleExport.h @@ -1,42 +1,42 @@ -#ifndef GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_EXPORT_H -#define GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_EXPORT_H +#ifndef GF_MODULE_EXPORT_H +#define GF_MODULE_EXPORT_H -#ifdef GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_STATIC_DEFINE -# define GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_EXPORT -# define GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_NO_EXPORT +#ifdef GF_MODULE_STATIC_DEFINE +# define GF_MODULE_EXPORT +# define GF_MODULE_NO_EXPORT #else -# ifndef GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_EXPORT -# ifdef gpgfrontend_integrated_module_version_checking_EXPORTS +# ifndef GF_MODULE_EXPORT +# ifdef gpgfrontend_version_checking_EXPORTS /* We are building this library */ -# define GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_EXPORT __attribute__((visibility("default"))) +# define GF_MODULE_EXPORT __attribute__((visibility("default"))) # else /* We are using this library */ -# define GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_EXPORT __attribute__((visibility("default"))) +# define GF_MODULE_EXPORT __attribute__((visibility("default"))) # endif # endif -# ifndef GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_NO_EXPORT -# define GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_NO_EXPORT __attribute__((visibility("hidden"))) +# ifndef GF_MODULE_NO_EXPORT +# define GF_MODULE_NO_EXPORT __attribute__((visibility("hidden"))) # endif #endif -#ifndef GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_DEPRECATED -# define GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_DEPRECATED __attribute__ ((__deprecated__)) +#ifndef GF_MODULE_DEPRECATED +# define GF_MODULE_DEPRECATED __attribute__ ((__deprecated__)) #endif -#ifndef GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_DEPRECATED_EXPORT -# define GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_DEPRECATED_EXPORT GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_EXPORT GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_DEPRECATED +#ifndef GF_MODULE_DEPRECATED_EXPORT +# define GF_MODULE_DEPRECATED_EXPORT GF_MODULE_EXPORT GF_MODULE_DEPRECATED #endif -#ifndef GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_DEPRECATED_NO_EXPORT -# define GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_DEPRECATED_NO_EXPORT GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_NO_EXPORT GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_DEPRECATED +#ifndef GF_MODULE_DEPRECATED_NO_EXPORT +# define GF_MODULE_DEPRECATED_NO_EXPORT GF_MODULE_NO_EXPORT GF_MODULE_DEPRECATED #endif #if 0 /* DEFINE_NO_DEPRECATED */ -# ifndef GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_NO_DEPRECATED -# define GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_NO_DEPRECATED +# ifndef GF_MODULE_NO_DEPRECATED +# define GF_MODULE_NO_DEPRECATED # endif #endif -#endif /* GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_EXPORT_H */ +#endif /* GF_MODULE_EXPORT_H */ diff --git a/src/module/integrated/version_checking_module/SoftwareVersion.cpp b/src/module/integrated/version_checking_module/SoftwareVersion.cpp index 7d41b1c5..46b05a8a 100644 --- a/src/module/integrated/version_checking_module/SoftwareVersion.cpp +++ b/src/module/integrated/version_checking_module/SoftwareVersion.cpp @@ -34,13 +34,17 @@ namespace GpgFrontend::Module::Integrated::VersionCheckingModule { auto VersionCheckingModule::SoftwareVersion::NeedUpgrade() const -> bool { - MODULE_LOG_DEBUG("compair version current {} latest {}, result {}", - current_version, latest_version, - CompareSoftwareVersion(current_version, latest_version)); + ModuleLogDebug( + fmt::format("compair version current {} latest {}, result {}", + current_version, latest_version, + CompareSoftwareVersion(current_version, latest_version)) + .c_str()); - MODULE_LOG_DEBUG("load done: {}, pre-release: {}, draft: {}", loading_done, - latest_prerelease_version_from_remote, - latest_draft_from_remote); + ModuleLogDebug(fmt::format("load done: {}, pre-release: {}, draft: {}", + loading_done, + latest_prerelease_version_from_remote, + latest_draft_from_remote) + .c_str()); return loading_done && !latest_prerelease_version_from_remote && !latest_draft_from_remote && CompareSoftwareVersion(current_version, latest_version) < 0; diff --git a/src/module/integrated/version_checking_module/VersionCheckTask.cpp b/src/module/integrated/version_checking_module/VersionCheckTask.cpp index e81fc92d..91d5edff 100644 --- a/src/module/integrated/version_checking_module/VersionCheckTask.cpp +++ b/src/module/integrated/version_checking_module/VersionCheckTask.cpp @@ -46,7 +46,8 @@ VersionCheckTask::VersionCheckTask() } auto VersionCheckTask::Run() -> int { - MODULE_LOG_DEBUG("current project version: {}", current_version_); + ModuleLogDebug( + fmt::format("current project version: {}", current_version_).c_str()); QString latest_version_url = "https://api.github.com/repos/saturneric/gpgfrontend/releases/latest"; @@ -65,8 +66,9 @@ void VersionCheckTask::slot_parse_latest_version_info() { version_.latest_version = current_version_; version_.loading_done = false; } else if (latest_reply_->error() != QNetworkReply::NoError) { - MODULE_LOG_ERROR("latest version request error: ", - latest_reply_->errorString()); + ModuleLogError(fmt::format("latest version request error: ", + latest_reply_->errorString()) + .c_str()); version_.latest_version = current_version_; } else { latest_reply_bytes_ = latest_reply_->readAll(); @@ -79,11 +81,15 @@ void VersionCheckTask::slot_parse_latest_version_info() { auto version_match = re.match(latest_version); if (version_match.hasMatch()) { latest_version = version_match.captured(0); - MODULE_LOG_INFO("latest version from github: {}", latest_version); + ModuleLogInfo( + fmt::format("latest version from github: {}", latest_version) + .c_str()); } else { latest_version = current_version_; - MODULE_LOG_WARN("latest version unknown, set to current version: {}", - current_version_); + ModuleLogWarn( + fmt::format("latest version unknown, set to current version: {}", + current_version_) + .c_str()); } bool prerelease = latest_reply_json["prerelease"].toBool(); @@ -96,8 +102,9 @@ void VersionCheckTask::slot_parse_latest_version_info() { version_.publish_date = publish_date; version_.release_note = release_note; } else { - MODULE_LOG_WARN("cannot parse data got from github: {}", - latest_reply_bytes_); + ModuleLogWarn(fmt::format("cannot parse data got from github: {}", + latest_reply_bytes_) + .c_str()); } } @@ -109,7 +116,9 @@ void VersionCheckTask::slot_parse_latest_version_info() { QString current_version_url = "https://api.github.com/repos/saturneric/gpgfrontend/releases/tags/" + current_version_; - MODULE_LOG_DEBUG("current version info query url: {}", current_version_url); + ModuleLogDebug( + fmt::format("current version info query url: {}", current_version_url) + .c_str()); QNetworkRequest current_request(current_version_url); current_request.setHeader(QNetworkRequest::UserAgentHeader, @@ -120,7 +129,7 @@ void VersionCheckTask::slot_parse_latest_version_info() { connect(current_reply_, &QNetworkReply::finished, this, &VersionCheckTask::slot_parse_current_version_info); } catch (...) { - MODULE_LOG_ERROR("current version request create error"); + ModuleLogError("current version request create error"); emit SignalTaskShouldEnd(-1); } } @@ -131,8 +140,9 @@ void VersionCheckTask::slot_parse_current_version_info() { version_.loading_done = false; } else if (current_reply_->error() != QNetworkReply::NoError) { - MODULE_LOG_ERROR("current version request network error: {}", - current_reply_->errorString()); + ModuleLogError(fmt::format("current version request network error: {}", + current_reply_->errorString()) + .c_str()); // loading done version_.loading_done = true; @@ -150,13 +160,15 @@ void VersionCheckTask::slot_parse_current_version_info() { // loading done version_.loading_done = true; } else { - MODULE_LOG_WARN("cannot parse data got from github: {}", - current_reply_bytes_); + ModuleLogWarn(fmt::format("cannot parse data got from github: {}", + current_reply_bytes_) + .c_str()); } } - MODULE_LOG_DEBUG("current version parse done: {}", - version_.current_version_publish_in_remote); + ModuleLogDebug(fmt::format("current version parse done: {}", + version_.current_version_publish_in_remote) + .c_str()); if (current_reply_ != nullptr) current_reply_->deleteLater(); emit SignalUpgradeVersion(version_); diff --git a/src/module/integrated/version_checking_module/VersionCheckingModule.cpp b/src/module/integrated/version_checking_module/VersionCheckingModule.cpp index 9b62a9c8..f0ce207b 100644 --- a/src/module/integrated/version_checking_module/VersionCheckingModule.cpp +++ b/src/module/integrated/version_checking_module/VersionCheckingModule.cpp @@ -44,21 +44,22 @@ VersionCheckingModule::VersionCheckingModule() VersionCheckingModule::~VersionCheckingModule() = default; -auto VersionCheckingModule::Register() -> bool { - MODULE_LOG_INFO("version checking module registering"); +auto VersionCheckingModule::Register() -> int { + ModuleLogInfo("version checking module registering"); listenEvent("APPLICATION_LOADED"); listenEvent("CHECK_APPLICATION_VERSION"); - return true; + return 0; } -auto VersionCheckingModule::Active() -> bool { - MODULE_LOG_INFO("version checking module activating"); - return true; +auto VersionCheckingModule::Active() -> int { + ModuleLogInfo("version checking module activating"); + return 0; } auto VersionCheckingModule::Exec(EventRefrernce event) -> int { - MODULE_LOG_INFO("version checking module executing, event id: {}", - event->GetIdentifier()); + ModuleLogInfo(fmt::format("version checking module executing, event id: {}", + event->GetIdentifier()) + .c_str()); auto* task = new VersionCheckTask(); connect(task, &VersionCheckTask::SignalUpgradeVersion, this, @@ -73,10 +74,11 @@ auto VersionCheckingModule::Exec(EventRefrernce event) -> int { return 0; } -auto VersionCheckingModule::Deactive() -> bool { return true; } +auto VersionCheckingModule::Deactive() -> int { return 0; } void VersionCheckingModule::SlotVersionCheckDone(SoftwareVersion version) { - MODULE_LOG_DEBUG("registering software information info to rt"); + ModuleLogDebug("registering software information info to rt"); + UpsertRTValue(GetModuleIdentifier(), "version.current_version", version.current_version); UpsertRTValue(GetModuleIdentifier(), "version.latest_version", @@ -100,6 +102,7 @@ void VersionCheckingModule::SlotVersionCheckDone(SoftwareVersion version) { version.VersionWithdrawn()); UpsertRTValue(GetModuleIdentifier(), "version.loading_done", version.loading_done); - MODULE_LOG_DEBUG("register software information to rt done"); + + ModuleLogDebug("register software information to rt done"); } } // namespace GpgFrontend::Module::Integrated::VersionCheckingModule diff --git a/src/module/integrated/version_checking_module/VersionCheckingModule.h b/src/module/integrated/version_checking_module/VersionCheckingModule.h index 0730feed..65b20198 100644 --- a/src/module/integrated/version_checking_module/VersionCheckingModule.h +++ b/src/module/integrated/version_checking_module/VersionCheckingModule.h @@ -34,21 +34,20 @@ namespace GpgFrontend::Module::Integrated::VersionCheckingModule { -class GPGFRONTEND_INTEGRATED_MODULE_VERSION_CHECKING_EXPORT - VersionCheckingModule : public Module { +class GF_MODULE_EXPORT VersionCheckingModule : public Module { Q_OBJECT public: VersionCheckingModule(); ~VersionCheckingModule() override; - auto Register() -> bool override; + auto Register() -> int override; - auto Active() -> bool override; + auto Active() -> int override; auto Exec(EventRefrernce) -> int override; - auto Deactive() -> bool override; + auto Deactive() -> int override; signals: diff --git a/src/module/sdk/Basic.cpp b/src/module/sdk/Basic.cpp index 63859763..35ce8054 100644 --- a/src/module/sdk/Basic.cpp +++ b/src/module/sdk/Basic.cpp @@ -24,4 +24,52 @@ * * SPDX-License-Identifier: GPL-3.0-or-later * - */
\ No newline at end of file + */ + +#include "Basic.h" + +#include "core/function/SecureMemoryAllocator.h" +#include "core/function/gpg/GpgCommandExecutor.h" + +auto AllocateMemory(uint32_t size) -> void* { + return GpgFrontend::SecureMemoryAllocator::Allocate(size); +} + +void FreeMemory(void* ptr) { + return GpgFrontend::SecureMemoryAllocator::Deallocate(ptr); +} + +void ExecuteCommandSync(const char* cmd, int32_t argc, const char** argv, + CommandExeucteCallback cb, void* data) { + QStringList args; + for (int i = 0; i < argc; i++) { + args.append(QString::fromUtf8(argv[i])); + } + + GpgFrontend::GpgCommandExecutor::ExecuteContext context{ + cmd, args, [=](int exit_code, const QString& out, const QString& err) { + cb(data, exit_code, out.toUtf8(), err.toUtf8()); + }}; + + GpgFrontend::GpgCommandExecutor::ExecuteSync(context); +} + +void ExecuteCommandBatchSync(int32_t context_size, + const CommandExecuteContext* context) { + QList<GpgFrontend::GpgCommandExecutor::ExecuteContext> contexts; + for (int i = 0; i < context_size; i++) { + auto exec_context = context[i]; + QStringList args; + for (int i = 0; i < exec_context.argc; i++) { + args.append(QString::fromUtf8(exec_context.argv[i])); + } + contexts.append( + {exec_context.cmd, args, + [data = exec_context.data, cb = exec_context.cb]( + int exit_code, const QString& out, const QString& err) { + cb(data, exit_code, out.toUtf8(), err.toUtf8()); + }}); + } + + GpgFrontend::GpgCommandExecutor::ExecuteConcurrentlySync(contexts); +}
\ No newline at end of file diff --git a/src/module/sdk/Basic.h b/src/module/sdk/Basic.h index 62a547b3..a232fd64 100644 --- a/src/module/sdk/Basic.h +++ b/src/module/sdk/Basic.h @@ -28,9 +28,31 @@ #pragma once -namespace GpgFrontend::Module::SDK { +#include "GpgFrontendModuleSDKExport.h" +extern "C" { +using CommandExeucteCallback = void (*)(void* data, int errcode, + const char* out, const char* err); +using CommandExecuteContext = struct { + const char* cmd; + int32_t argc; + const char** argv; + CommandExeucteCallback cb; + void* data; +}; +auto GPGFRONTEND_MODULE_SDK_EXPORT AllocateMemory(uint32_t size) -> void*; + +void GPGFRONTEND_MODULE_SDK_EXPORT FreeMemory(void*); + +void GPGFRONTEND_MODULE_SDK_EXPORT ExecuteCommandSync(const char* cmd, + int32_t argc, + const char** argv, + CommandExeucteCallback cb, + void* data); + +void GPGFRONTEND_MODULE_SDK_EXPORT ExecuteCommandBatchSync( + int32_t context_size, const CommandExecuteContext* context); }
\ No newline at end of file diff --git a/src/module/sdk/Gpg.h b/src/module/sdk/Gpg.h index 0702632a..8823bfc5 100644 --- a/src/module/sdk/Gpg.h +++ b/src/module/sdk/Gpg.h @@ -26,4 +26,8 @@ * */ -#pragma once
\ No newline at end of file +#pragma once + +extern "C" { + +}
\ No newline at end of file diff --git a/src/module/sdk/Log.cpp b/src/module/sdk/Log.cpp index 384fac1d..e7448973 100644 --- a/src/module/sdk/Log.cpp +++ b/src/module/sdk/Log.cpp @@ -28,9 +28,20 @@ #include "Log.h" +#include "core/utils/LogUtils.h" -#include <stdexcept> +#define MODULE_LOG_TRACE(...) GF_LOG_TRACE("module", __VA_ARGS__) +#define MODULE_LOG_DEBUG(...) GF_LOG_DEBUG("module", __VA_ARGS__) +#define MODULE_LOG_INFO(...) GF_LOG_INFO("module", __VA_ARGS__) +#define MODULE_LOG_WARN(...) GF_LOG_WARN("module", __VA_ARGS__) +#define MODULE_LOG_ERROR(...) GF_LOG_ERROR("module", __VA_ARGS__) -#include "core/function/GlobalSettingStation.h" +void ModuleLogTrace(const char* l) { MODULE_LOG_TRACE(l); } -namespace GpgFrontend::Module::SDK {} // namespace GpgFrontend::Module::SDK +void ModuleLogDebug(const char* l) { MODULE_LOG_DEBUG(l); } + +void ModuleLogInfo(const char* l) { MODULE_LOG_INFO(l); } + +void ModuleLogWarn(const char* l) { MODULE_LOG_WARN(l); } + +void ModuleLogError(const char* l) { MODULE_LOG_ERROR(l); } diff --git a/src/module/sdk/Log.h b/src/module/sdk/Log.h index 0c40a097..761f7b07 100644 --- a/src/module/sdk/Log.h +++ b/src/module/sdk/Log.h @@ -28,44 +28,17 @@ #pragma once -#include "core/utils/LogUtils.h" -#include "module/sdk/GpgFrontendModuleSDK.h" +#include "module/sdk/GpgFrontendModuleSDKExport.h" -#define MODULE_LOG_TRACE(...) GF_LOG_TRACE("module", __VA_ARGS__) -#define MODULE_LOG_DEBUG(...) GF_LOG_DEBUG("module", __VA_ARGS__) -#define MODULE_LOG_INFO(...) GF_LOG_INFO("module", __VA_ARGS__) -#define MODULE_LOG_WARN(...) GF_LOG_WARN("module", __VA_ARGS__) -#define MODULE_LOG_ERROR(...) GF_LOG_ERROR("module", __VA_ARGS__) +extern "C" { -namespace spdlog { -class logger; -} +void GPGFRONTEND_MODULE_SDK_EXPORT ModuleLogTrace(const char*); -namespace GpgFrontend::Module::SDK { +void GPGFRONTEND_MODULE_SDK_EXPORT ModuleLogDebug(const char*); -template <typename... Args> -void ModuleLogTrace(const char* fmt, const Args&... args) { - MODULE_LOG_TRACE(fmt, args...); -} +void GPGFRONTEND_MODULE_SDK_EXPORT ModuleLogInfo(const char*); -template <typename... Args> -void ModuleLogDebug(const char* fmt, const Args&... args) { - MODULE_LOG_DEBUG(fmt, args...); -} +void GPGFRONTEND_MODULE_SDK_EXPORT ModuleLogWarn(const char*); -template <typename... Args> -void ModuleLogInfo(const char* fmt, const Args&... args) { - MODULE_LOG_INFO(fmt, args...); -} - -template <typename... Args> -void ModuleLogWarn(const char* fmt, const Args&... args) { - MODULE_LOG_WARN(fmt, args...); -} - -template <typename... Args> -void ModuleLogError(const char* fmt, const Args&... args) { - MODULE_LOG_ERROR(fmt, args...); -} - -} // namespace GpgFrontend::Module::SDK +void GPGFRONTEND_MODULE_SDK_EXPORT ModuleLogError(const char*); +}
\ No newline at end of file diff --git a/src/module/sdk/Module.cpp b/src/module/sdk/Module.cpp new file mode 100644 index 00000000..36fe7b91 --- /dev/null +++ b/src/module/sdk/Module.cpp @@ -0,0 +1,86 @@ +/** + * Copyright (C) 2021 Saturneric <[email protected]> + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric <[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "Module.h" + +#include <core/module/ModuleManager.h> + +#include "Basic.h" +#include "core/utils/CommonUtils.h" + +void ListenEvent(const char *module_id, const char *event_id) { + return GpgFrontend::Module::ModuleManager::GetInstance().ListenEvent( + module_id, event_id); +} + +auto RetrieveRTValueOrDefault(const char *namespace_, const char *key, + const char *default_value) -> const char * { + return GpgFrontend::Module::RetrieveRTValueTypedOrDefault( + namespace_, key, QString::fromUtf8(default_value)) + .toUtf8(); +} + +void UpsertRTValue(const char *namespace_, const char *key, const char *vaule) { + GpgFrontend::Module::UpsertRTValue(namespace_, key, vaule); +} + +auto ListRTChildKeys(const char *namespace_, const char *key, + char ***child_keys) -> int32_t { + *child_keys = nullptr; + auto keys = GpgFrontend::Module::ListRTChildKeys(namespace_, key); + + if (keys.empty()) return 0; + + *child_keys = + static_cast<char **>(AllocateMemory(sizeof(const char **) * keys.size())); + + for (int i = 0; i < keys.size(); i++) { + *child_keys[i] = + static_cast<char *>(AllocateMemory(sizeof(char) * keys[i].size() + 1)); + + auto key = keys[i].toUtf8(); + memcpy(reinterpret_cast<void *>(*child_keys[i]), key, key.size()); + (*child_keys[i])[key.size()] = '\0'; + } + + return static_cast<int32_t>(keys.size()); +} + +void TriggerModuleEventCallback(ModuleEvent *module_event, + const char *module_id, int argc, char **argv) { + auto data_object = GpgFrontend::TransferParams(); + for (int i = 0; i < argc; i++) { + data_object->AppendObject(QString::fromUtf8(argv[i])); + } + + auto event = GpgFrontend::Module::ModuleManager::GetInstance().SearchEvent( + module_event->triggger_id); + if (!event) return; + + event.value()->ExecuteCallback(QString::fromUtf8(module_id), data_object); +}
\ No newline at end of file diff --git a/src/module/sdk/Module.h b/src/module/sdk/Module.h new file mode 100644 index 00000000..b2f9a7ce --- /dev/null +++ b/src/module/sdk/Module.h @@ -0,0 +1,87 @@ +/** + * Copyright (C) 2021 Saturneric <[email protected]> + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric <[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#pragma once + +#include "GpgFrontendModuleSDKExport.h" + +extern "C" { + +struct GPGFRONTEND_MODULE_SDK_EXPORT ModuleMetaData { + const char *key; + const char *value; + ModuleMetaData *next; +}; + +struct GPGFRONTEND_MODULE_SDK_EXPORT ModuleEventParam { + const char *name; + const char *value; + ModuleEventParam *next; +}; + +struct GPGFRONTEND_MODULE_SDK_EXPORT ModuleEvent { + const char *id; + const char *triggger_id; + ModuleEventParam *params; +}; + +using ModuleAPIGetModuleID = auto (*)() -> const char *; + +using ModuleAPIGetModuleVersion = auto (*)() -> const char *; + +using ModuleAPIGetModuleMetaData = auto (*)() -> ModuleMetaData *; + +using ModuleAPIRegisterModule = auto (*)() -> int; + +using ModuleAPIActivateModule = auto (*)() -> int; + +using ModuleAPIExecuteModule = auto (*)(ModuleEvent *) -> int; + +using ModuleAPIDeactivateModule = auto (*)() -> int; + +using ModuleAPIUnregisterModule = auto (*)() -> int; + +void GPGFRONTEND_MODULE_SDK_EXPORT ListenEvent(const char *module_id, + const char *event_id); + +auto GPGFRONTEND_MODULE_SDK_EXPORT RetrieveRTValueOrDefault( + const char *namespace_, const char *key, const char *default_value) -> const + char *; + +void GPGFRONTEND_MODULE_SDK_EXPORT UpsertRTValue(const char *namespace_, + const char *key, + const char *vaule); + +auto GPGFRONTEND_MODULE_SDK_EXPORT ListRTChildKeys(const char *namespace_, + const char *key, + char ***child_keys) + -> int32_t; + +void GPGFRONTEND_MODULE_SDK_EXPORT TriggerModuleEventCallback( + ModuleEvent *event, const char *module_id, int argc, char **argv); +};
\ No newline at end of file diff --git a/src/module/sdk/Utils.cpp b/src/module/sdk/Utils.cpp new file mode 100644 index 00000000..8e9dbefb --- /dev/null +++ b/src/module/sdk/Utils.cpp @@ -0,0 +1,29 @@ +/** + * Copyright (C) 2021 Saturneric <[email protected]> + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric <[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "Utils.h"
\ No newline at end of file diff --git a/src/module/sdk/Utils.h b/src/module/sdk/Utils.h new file mode 100644 index 00000000..7d72e9ee --- /dev/null +++ b/src/module/sdk/Utils.h @@ -0,0 +1,34 @@ +/** + * Copyright (C) 2021 Saturneric <[email protected]> + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric <[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#pragma once + +extern "C" { + + +}
\ No newline at end of file |