aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsaturneric <[email protected]>2024-02-28 16:32:43 +0000
committersaturneric <[email protected]>2024-02-28 16:32:43 +0000
commit12d70e1792a5b1ff08d4b58fb49fb9e58d6551a8 (patch)
tree1b747d6a3a034814104df6f531077de9c03ecd53
parentfeat: add user agent header when doing http request (diff)
downloadGpgFrontend-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
-rw-r--r--src/CMakeLists.txt4
-rw-r--r--src/core/function/basic/GpgFunctionObject.h1
-rw-r--r--src/core/module/Event.cpp44
-rw-r--r--src/core/module/Event.h10
-rw-r--r--src/core/module/GlobalModuleContext.cpp42
-rw-r--r--src/core/module/GlobalModuleContext.h4
-rw-r--r--src/core/module/Module.cpp104
-rw-r--r--src/core/module/Module.h19
-rw-r--r--src/core/module/ModuleManager.cpp79
-rw-r--r--src/core/module/ModuleManager.h8
-rw-r--r--src/core/utils/CommonUtils.cpp10
-rw-r--r--src/core/utils/CommonUtils.h7
-rw-r--r--src/module/CMakeLists.txt2
-rw-r--r--src/module/GpgFrontendModule.h10
-rw-r--r--src/module/GpgFrontendModuleInit.cpp33
-rw-r--r--src/module/integrated/gnupg_info_gathering_module/CMakeLists.txt18
-rw-r--r--src/module/integrated/gnupg_info_gathering_module/GnuPGInfoGatheringModule.cpp607
-rw-r--r--src/module/integrated/gnupg_info_gathering_module/GnuPGInfoGatheringModule.h28
-rw-r--r--src/module/integrated/gnupg_info_gathering_module/GpgFrontendModuleExport.h40
-rw-r--r--src/module/integrated/gnupg_info_gathering_module/GpgInfo.cpp9
-rw-r--r--src/module/integrated/gnupg_info_gathering_module/GpgInfo.h3
-rw-r--r--src/module/integrated/version_checking_module/CMakeLists.txt22
-rw-r--r--src/module/integrated/version_checking_module/GpgFrontendModuleExport.h40
-rw-r--r--src/module/integrated/version_checking_module/SoftwareVersion.cpp16
-rw-r--r--src/module/integrated/version_checking_module/VersionCheckTask.cpp44
-rw-r--r--src/module/integrated/version_checking_module/VersionCheckingModule.cpp25
-rw-r--r--src/module/integrated/version_checking_module/VersionCheckingModule.h9
-rw-r--r--src/module/sdk/Basic.cpp50
-rw-r--r--src/module/sdk/Basic.h24
-rw-r--r--src/module/sdk/Gpg.h6
-rw-r--r--src/module/sdk/Log.cpp17
-rw-r--r--src/module/sdk/Log.h43
-rw-r--r--src/module/sdk/Module.cpp86
-rw-r--r--src/module/sdk/Module.h87
-rw-r--r--src/module/sdk/Utils.cpp29
-rw-r--r--src/module/sdk/Utils.h34
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**>(&register_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