aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsaturneric <[email protected]>2023-12-03 20:25:21 +0000
committersaturneric <[email protected]>2023-12-03 20:25:21 +0000
commit054e6e28cca2517dda2319ef683314b3318c39a6 (patch)
treeae9ff4a9fe280f3640ca249bad45ab250cfd1610
parentfix: slove issues in key/subkey generation (diff)
downloadGpgFrontend-054e6e28cca2517dda2319ef683314b3318c39a6.tar.gz
GpgFrontend-054e6e28cca2517dda2319ef683314b3318c39a6.zip
feat: standarized and speed up app env loading process
Diffstat (limited to '')
-rw-r--r--src/app.cpp26
-rw-r--r--src/cmd.cpp15
-rw-r--r--src/core/GpgCoreInit.cpp372
-rw-r--r--src/core/GpgCoreInit.h8
-rw-r--r--src/core/function/CoreSignalStation.h8
-rw-r--r--src/core/function/basic/GpgFunctionObject.h4
-rw-r--r--src/core/function/basic/SingletonStorageCollection.cpp37
-rw-r--r--src/core/function/basic/SingletonStorageCollection.h32
-rw-r--r--src/core/function/gpg/GpgBasicOperator.cpp63
-rw-r--r--src/core/function/gpg/GpgCommandExecutor.cpp31
-rw-r--r--src/core/function/gpg/GpgContext.cpp334
-rw-r--r--src/core/function/gpg/GpgContext.h19
-rw-r--r--src/core/function/gpg/GpgKeyGetter.cpp17
-rw-r--r--src/core/function/gpg/GpgKeyImportExporter.cpp18
-rw-r--r--src/core/function/gpg/GpgKeyManager.cpp23
-rw-r--r--src/core/function/gpg/GpgKeyOpera.cpp34
-rw-r--r--src/core/function/gpg/GpgUIDOperator.cpp11
-rw-r--r--src/core/module/Event.cpp4
-rw-r--r--src/core/module/GlobalModuleContext.cpp9
-rw-r--r--src/core/module/GlobalModuleContext.h2
-rw-r--r--src/core/module/ModuleManager.cpp12
-rw-r--r--src/core/module/ModuleManager.h32
-rw-r--r--src/core/thread/CtxCheckTask.cpp6
-rw-r--r--src/core/thread/CtxCheckTask.h2
-rw-r--r--src/core/utils/GpgUtils.cpp5
-rw-r--r--src/init.cpp18
-rw-r--r--src/init.h7
-rw-r--r--src/module/GpgFrontendModuleInit.cpp22
-rw-r--r--src/module/GpgFrontendModuleInit.h16
-rw-r--r--src/module/integrated/gnupg_info_gathering_module/GnuPGInfoGatheringModule.cpp7
-rw-r--r--src/module/sdk/Log.cpp10
-rw-r--r--src/ui/GpgFrontendUIInit.cpp125
-rw-r--r--src/ui/GpgFrontendUIInit.h6
-rw-r--r--src/ui/UserInterfaceUtils.cpp6
-rw-r--r--src/ui/UserInterfaceUtils.h2
35 files changed, 805 insertions, 538 deletions
diff --git a/src/app.cpp b/src/app.cpp
index 1213aebd..8df46024 100644
--- a/src/app.cpp
+++ b/src/app.cpp
@@ -79,7 +79,7 @@ auto StartApplication(InitArgs args) -> int {
args.argc, args.argv, true);
// init the logging system for main
- InitModules(args);
+ InitLoggingSystem(args);
// change path to search for related
InitGlobalPathEnv();
@@ -98,10 +98,18 @@ auto StartApplication(InitArgs args) -> int {
int r = setjmp(recover_env);
#endif
if (!r) {
- // init ui library
+ // should load module system first
+ GpgFrontend::Module::ModuleInitArgs module_init_args;
+ module_init_args.log_level = args.log_level;
+ GpgFrontend::Module::LoadGpgFrontendModules(module_init_args);
+
+ // then load core
+ GpgFrontend::InitGpgFrontendCore();
+
+ // after that load ui library
GpgFrontend::UI::InitGpgFrontendUI(app);
- // create main window
+ // finally create main window
return_from_event_loop_code = GpgFrontend::UI::RunGpgFrontendUI(app);
} else {
SPDLOG_ERROR("recover from a crash");
@@ -117,6 +125,16 @@ auto StartApplication(InitArgs args) -> int {
return_from_event_loop_code = kCrashCode;
}
+ SPDLOG_DEBUG("try to destroy modules system and core");
+
+ // first should shutdown the module system
+ GpgFrontend::Module::ShutdownGpgFrontendModules();
+
+ // then shutdown the core
+ GpgFrontend::DestroyGpgFrontendCore();
+
+ SPDLOG_DEBUG("core and modules system destroyed");
+
restart_count++;
SPDLOG_DEBUG("restart loop refresh, event loop code: {}, restart count: {}",
@@ -125,7 +143,7 @@ auto StartApplication(InitArgs args) -> int {
restart_count < 3);
// close logging system
- ShutdownModules();
+ ShutdownLoggingSystem();
// log for debug
SPDLOG_INFO("GpgFrontend is about to exit.");
diff --git a/src/cmd.cpp b/src/cmd.cpp
index 66e2604f..24080a08 100644
--- a/src/cmd.cpp
+++ b/src/cmd.cpp
@@ -36,6 +36,7 @@
// GpgFrontend
#include "GpgFrontendBuildInfo.h"
+#include "spdlog/common.h"
namespace po = boost::program_options;
@@ -61,13 +62,19 @@ auto ParseLogLevel(const po::variables_map& vm) -> spdlog::level::level_enum {
if (log_level == "trace") {
return spdlog::level::trace;
- } else if (log_level == "debug") {
+ }
+ if (log_level == "debug") {
return spdlog::level::debug;
- } else if (log_level == "info") {
+ }
+ if (log_level == "info") {
return spdlog::level::info;
- } else if (log_level == "warn") {
+ }
+ if (log_level == "warn") {
return spdlog::level::warn;
- } else if (log_level == "error") {
+ }
+ if (log_level == "error") {
return spdlog::level::err;
}
+
+ return spdlog::level::info;
} \ No newline at end of file
diff --git a/src/core/GpgCoreInit.cpp b/src/core/GpgCoreInit.cpp
index 09b3a0ec..dcd0dcfb 100644
--- a/src/core/GpgCoreInit.cpp
+++ b/src/core/GpgCoreInit.cpp
@@ -27,6 +27,7 @@
*/
#include "GpgCoreInit.h"
+#include <gpgme.h>
#include <spdlog/async.h>
#include <spdlog/common.h>
#include <spdlog/sinks/rotating_file_sink.h>
@@ -35,15 +36,19 @@
#include <boost/date_time.hpp>
#include "core/function/GlobalSettingStation.h"
+#include "core/function/basic/ChannelObject.h"
+#include "core/function/basic/SingletonStorage.h"
#include "core/function/gpg/GpgAdvancedOperator.h"
#include "core/function/gpg/GpgContext.h"
#include "core/module/ModuleManager.h"
#include "core/thread/Task.h"
#include "core/thread/TaskRunner.h"
#include "core/thread/TaskRunnerGetter.h"
+#include "core/utils/CommonUtils.h"
+#include "core/utils/GpgUtils.h"
#include "core/utils/MemoryUtils.h"
-#include "function/basic/ChannelObject.h"
-#include "function/basic/SingletonStorage.h"
+#include "function/CoreSignalStation.h"
+#include "function/gpg/GpgKeyGetter.h"
namespace GpgFrontend {
@@ -99,123 +104,206 @@ void ShutdownCoreLoggingSystem() {
#endif
}
-void ResetGpgFrontendCore() { reset_gpgfrontend_core(); }
+void DestroyGpgFrontendCore() {
+ SingletonStorageCollection::Destroy();
+ ShutdownCoreLoggingSystem();
+}
+
+auto InitGpgME() -> bool {
+ // init gpgme subsystem and get gpgme library version
+ Module::UpsertRTValue("core", "gpgme.version",
+ std::string(gpgme_check_version(nullptr)));
-void InitGpgFrontendCore() {
- /* Initialize the locale environment. */
- SPDLOG_DEBUG("locale: {}", setlocale(LC_CTYPE, nullptr));
- // init gpgme subsystem
- gpgme_check_version(nullptr);
gpgme_set_locale(nullptr, LC_CTYPE, setlocale(LC_CTYPE, nullptr));
#ifdef LC_MESSAGES
gpgme_set_locale(nullptr, LC_MESSAGES, setlocale(LC_MESSAGES, nullptr));
#endif
- // read settings
- bool forbid_all_gnupg_connection =
- GlobalSettingStation::GetInstance().LookupSettings(
- "network.forbid_all_gnupg_connection", false);
-
- bool auto_import_missing_key =
- GlobalSettingStation::GetInstance().LookupSettings(
- "network.auto_import_missing_key", false);
-
- bool use_custom_key_database_path =
- GlobalSettingStation::GetInstance().LookupSettings(
- "general.use_custom_key_database_path", false);
+ gpgme_ctx_t p_ctx;
+
+ CheckGpgError(gpgme_new(&p_ctx));
+
+ // get engine info
+ auto* engine_info = gpgme_ctx_get_engine_info(p_ctx);
+ // Check ENV before running
+ bool find_openpgp = false;
+ bool find_gpgconf = false;
+ bool find_cms = false;
+
+ while (engine_info != nullptr) {
+ if (strcmp(engine_info->version, "1.0.0") == 0) {
+ engine_info = engine_info->next;
+ continue;
+ }
+
+ SPDLOG_DEBUG(
+ "gpg context engine info: {} {} {} {}",
+ gpgme_get_protocol_name(engine_info->protocol),
+ std::string(engine_info->file_name == nullptr ? "null"
+ : engine_info->file_name),
+ std::string(engine_info->home_dir == nullptr ? "null"
+ : engine_info->home_dir),
+ std::string(engine_info->version ? "null" : engine_info->version));
+
+ switch (engine_info->protocol) {
+ case GPGME_PROTOCOL_OpenPGP:
+ find_openpgp = true;
+
+ Module::UpsertRTValue("core", "gpgme.engine.openpgp", "1");
+ Module::UpsertRTValue("core", "gpgme.ctx.app_path",
+ std::string(engine_info->file_name));
+ Module::UpsertRTValue("core", "gpgme.ctx.gnupg_version",
+ std::string(engine_info->version));
+ Module::UpsertRTValue("core", "gpgme.ctx.database_path",
+ std::string(engine_info->home_dir == nullptr
+ ? "default"
+ : engine_info->home_dir));
+ break;
+ case GPGME_PROTOCOL_CMS:
+ find_cms = true;
+ Module::UpsertRTValue("core", "gpgme.engine.cms", "1");
+ Module::UpsertRTValue("core", "gpgme.ctx.cms_path",
+ std::string(engine_info->file_name));
+
+ break;
+ case GPGME_PROTOCOL_GPGCONF:
+ find_gpgconf = true;
+
+ Module::UpsertRTValue("core", "gpgme.engine.gpgconf", "1");
+ Module::UpsertRTValue("core", "gpgme.ctx.gpgconf_path",
+ std::string(engine_info->file_name));
+ break;
+ case GPGME_PROTOCOL_ASSUAN:
+
+ Module::UpsertRTValue("core", "gpgme.engine.assuan", "1");
+ Module::UpsertRTValue("core", "gpgme.ctx.assuan_path",
+ std::string(engine_info->file_name));
+ break;
+ case GPGME_PROTOCOL_G13:
+ break;
+ case GPGME_PROTOCOL_UISERVER:
+ break;
+ case GPGME_PROTOCOL_SPAWN:
+ break;
+ case GPGME_PROTOCOL_DEFAULT:
+ break;
+ case GPGME_PROTOCOL_UNKNOWN:
+ break;
+ }
+ engine_info = engine_info->next;
+ }
- std::string custom_key_database_path =
- GlobalSettingStation::GetInstance().LookupSettings(
- "general.custom_key_database_path", std::string{});
+ const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.ctx.gnupg_version", std::string{"0.0.0"});
+ SPDLOG_DEBUG("got gnupg version from rt: {}", gnupg_version);
- bool use_custom_gnupg_install_path =
- GlobalSettingStation::GetInstance().LookupSettings(
- "general.use_custom_gnupg_install_path", false);
+ // conditional check: only support gpg 2.1.x now
+ if (!(CompareSoftwareVersion(gnupg_version, "2.1.0") >= 0 && find_gpgconf &&
+ find_openpgp && find_cms)) {
+ SPDLOG_ERROR("gpgme env check failed, abort");
+ return false;
+ }
- std::string custom_gnupg_install_path =
- GlobalSettingStation::GetInstance().LookupSettings(
- "general.custom_gnupg_install_path", std::string{});
+ Module::UpsertRTValue("core", "env.state.gpgme", std::string{"1"});
+ return true;
+}
- bool use_pinentry_as_password_input_dialog =
- GpgFrontend::GlobalSettingStation::GetInstance().LookupSettings(
- "general.use_pinentry_as_password_input_dialog", false);
+void InitGpgFrontendCore() {
+ // initialize global register table
+ Module::UpsertRTValue("core", "env.state.gpgme", std::string{"0"});
+ Module::UpsertRTValue("core", "env.state.ctx", std::string{"0"});
+ Module::UpsertRTValue("core", "env.state.gnupg", std::string{"0"});
+ Module::UpsertRTValue("core", "env.state.basic", std::string{"0"});
+ Module::UpsertRTValue("core", "env.state.all", std::string{"0"});
+
+ // initialize locale environment
+ SPDLOG_DEBUG("locale: {}", setlocale(LC_CTYPE, nullptr));
- SPDLOG_DEBUG("core loaded if use custom key databse path: {}",
- use_custom_key_database_path);
- SPDLOG_DEBUG("core loaded custom key databse path: {}",
- custom_key_database_path);
+ // initialize library gpgme
+ if (!InitGpgME()) {
+ CoreSignalStation::GetInstance()->SignalBadGnupgEnv();
+ return;
+ }
- // check gpgconf path
- std::filesystem::path custom_gnupg_install_fs_path =
- custom_gnupg_install_path;
+ // start the thread to check ctx and gnupg state
+ // it may take a few seconds or minutes
+ GpgFrontend::Thread::TaskRunnerGetter::GetInstance()
+ .GetTaskRunner()
+ ->PostTask(new Thread::Task(
+ [](const DataObjectPtr&) -> int {
+ // read settings from config file
+ auto forbid_all_gnupg_connection =
+ GlobalSettingStation::GetInstance().LookupSettings(
+ "network.forbid_all_gnupg_connection", false);
+
+ auto auto_import_missing_key =
+ GlobalSettingStation::GetInstance().LookupSettings(
+ "network.auto_import_missing_key", false);
+
+ auto use_custom_key_database_path =
+ GlobalSettingStation::GetInstance().LookupSettings(
+ "general.use_custom_key_database_path", false);
+
+ auto custom_key_database_path =
+ GlobalSettingStation::GetInstance().LookupSettings(
+ "general.custom_key_database_path", std::string{});
+
+ auto use_custom_gnupg_install_path =
+ GlobalSettingStation::GetInstance().LookupSettings(
+ "general.use_custom_gnupg_install_path", false);
+
+ auto custom_gnupg_install_path =
+ GlobalSettingStation::GetInstance().LookupSettings(
+ "general.custom_gnupg_install_path", std::string{});
+
+ auto use_pinentry_as_password_input_dialog =
+ GpgFrontend::GlobalSettingStation::GetInstance().LookupSettings(
+ "general.use_pinentry_as_password_input_dialog", false);
+
+ SPDLOG_DEBUG("core loaded if use custom key databse path: {}",
+ use_custom_key_database_path);
+ SPDLOG_DEBUG("core loaded custom key databse path: {}",
+ custom_key_database_path);
+
+ // check gpgconf path
+ std::filesystem::path custom_gnupg_install_fs_path =
+ custom_gnupg_install_path;
#ifdef WINDOWS
- custom_gnupg_install_fs_path /= "gpgconf.exe";
+ custom_gnupg_install_fs_path /= "gpgconf.exe";
#else
- custom_gnupg_install_fs_path /= "gpgconf";
+ custom_gnupg_install_fs_path /= "gpgconf";
#endif
- if (!custom_gnupg_install_fs_path.is_absolute() ||
- !std::filesystem::exists(custom_gnupg_install_fs_path) ||
- !std::filesystem::is_regular_file(custom_gnupg_install_fs_path)) {
- use_custom_gnupg_install_path = false;
- SPDLOG_ERROR("core loaded custom gpgconf path is illegal: {}",
- custom_gnupg_install_fs_path.u8string());
- } else {
- SPDLOG_DEBUG("core loaded custom gpgconf path: {}",
- custom_gnupg_install_fs_path.u8string());
- }
-
- // check key database path
- std::filesystem::path custom_key_database_fs_path = custom_key_database_path;
- if (!custom_key_database_fs_path.is_absolute() ||
- !std::filesystem::exists(custom_key_database_fs_path) ||
- !std::filesystem::is_directory(custom_key_database_fs_path)) {
- use_custom_key_database_path = false;
- SPDLOG_ERROR("core loaded custom gpg key database is illegal: {}",
- custom_key_database_fs_path.u8string());
- } else {
- SPDLOG_DEBUG("core loaded custom gpg key database path: {}",
- custom_key_database_fs_path.u8string());
- }
-
- // init default channel
- auto& default_ctx = GpgFrontend::GpgContext::CreateInstance(
- kGpgfrontendDefaultChannel, [=]() -> ChannelObjectPtr {
- GpgFrontend::GpgContextInitArgs args;
-
- // set key database path
- if (use_custom_key_database_path && !custom_key_database_path.empty()) {
- args.db_path = custom_key_database_path;
- }
-
- if (use_custom_gnupg_install_path) {
- args.custom_gpgconf = true;
- args.custom_gpgconf_path = custom_gnupg_install_fs_path.u8string();
- }
-
- args.offline_mode = forbid_all_gnupg_connection;
- args.auto_import_missing_key = auto_import_missing_key;
- args.use_pinentry = use_pinentry_as_password_input_dialog;
-
- return ConvertToChannelObjectPtr<>(SecureCreateUniqueObject<GpgContext>(
- args, kGpgFrontendDefaultChannel));
- });
-
- // exit if failed
- if (!default_ctx.Good()) {
- SPDLOG_ERROR("default gnupg context init error");
- };
-
- // async init no-ascii(binary output) channel
- Thread::TaskRunnerGetter::GetInstance()
- .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_GPG)
- ->PostTask(new Thread::Task(
- [=](const DataObjectPtr& /*data_obj*/) -> int {
- // init non-ascii channel
+ if (!custom_gnupg_install_fs_path.is_absolute() ||
+ !std::filesystem::exists(custom_gnupg_install_fs_path) ||
+ !std::filesystem::is_regular_file(
+ custom_gnupg_install_fs_path)) {
+ use_custom_gnupg_install_path = false;
+ SPDLOG_ERROR("core loaded custom gpgconf path is illegal: {}",
+ custom_gnupg_install_fs_path.u8string());
+ } else {
+ SPDLOG_DEBUG("core loaded custom gpgconf path: {}",
+ custom_gnupg_install_fs_path.u8string());
+ }
+
+ // check key database path
+ std::filesystem::path custom_key_database_fs_path =
+ custom_key_database_path;
+ if (!custom_key_database_fs_path.is_absolute() ||
+ !std::filesystem::exists(custom_key_database_fs_path) ||
+ !std::filesystem::is_directory(custom_key_database_fs_path)) {
+ use_custom_key_database_path = false;
+ SPDLOG_ERROR("core loaded custom gpg key database is illegal: {}",
+ custom_key_database_fs_path.u8string());
+ } else {
+ SPDLOG_DEBUG("core loaded custom gpg key database path: {}",
+ custom_key_database_fs_path.u8string());
+ }
+
+ // init ctx, also checking the basical env
auto& ctx = GpgFrontend::GpgContext::CreateInstance(
- kGpgfrontendNonAsciiChannel, [=]() -> ChannelObjectPtr {
+ kGpgfrontendDefaultChannel, [=]() -> ChannelObjectPtr {
GpgFrontend::GpgContextInitArgs args;
- args.ascii = false;
// set key database path
if (use_custom_key_database_path &&
@@ -223,6 +311,7 @@ void InitGpgFrontendCore() {
args.db_path = custom_key_database_path;
}
+ // set custom gnupg path
if (use_custom_gnupg_install_path) {
args.custom_gpgconf = true;
args.custom_gpgconf_path =
@@ -235,31 +324,68 @@ void InitGpgFrontendCore() {
return ConvertToChannelObjectPtr<>(
SecureCreateUniqueObject<GpgContext>(
- args, kGpgfrontendNonAsciiChannel));
+ args, kGpgFrontendDefaultChannel));
});
- if (!ctx.Good()) SPDLOG_ERROR("no-ascii channel init error");
- return ctx.Good() ? 0 : -1;
+ // exit if failed
+ if (!ctx.Good()) {
+ SPDLOG_ERROR("default gnupg context init error, abort");
+ CoreSignalStation::GetInstance()->SignalBadGnupgEnv();
+ return -1;
+ }
+ Module::UpsertRTValue("core", "env.state.ctx", std::string{"1"});
+
+ // if gnupg-info-gathering module activated
+ if (Module::IsModuleAcivate("com.bktus.gpgfrontend.module."
+ "integrated.gnupg-info-gathering")) {
+ SPDLOG_DEBUG("gnupg-info-gathering is activated");
+
+ // gather external gnupg info
+ Module::TriggerEvent(
+ "GPGFRONTEND_CORE_INITLIZED",
+ [](const Module::EventIdentifier& /*e*/,
+ const Module::Event::ListenerIdentifier& l_id,
+ DataObjectPtr o) {
+ SPDLOG_DEBUG(
+ "received event GPGFRONTEND_CORE_INITLIZED callback "
+ "from module: {}",
+ l_id);
+
+ if (l_id ==
+ "com.bktus.gpgfrontend.module.integrated.gnupg-info-"
+ "gathering") {
+ SPDLOG_DEBUG(
+ "received callback from gnupg-info-gathering ");
+
+ // try to restart all components
+ GpgFrontend::GpgAdvancedOperator::RestartGpgComponents();
+ Module::UpsertRTValue("core", "env.state.gnupg",
+ std::string{"1"});
+
+ // announce that all checkings were finished
+ SPDLOG_INFO(
+ "all env checking finished, including gpgme, "
+ "ctx and "
+ "gnupg");
+ Module::UpsertRTValue("core", "env.state.all",
+ std::string{"1"});
+ }
+ });
+ } else {
+ SPDLOG_DEBUG("gnupg-info-gathering is not activated");
+ Module::UpsertRTValue("core", "env.state.all", std::string{"1"});
+ }
+
+ GpgKeyGetter::GetInstance().FlushKeyCache();
+ SPDLOG_INFO(
+ "basic env checking finished, including gpgme, ctx, and key "
+ "infos");
+ Module::UpsertRTValue("core", "env.state.basic", std::string{"1"});
+ CoreSignalStation::GetInstance()->SignalGoodGnupgEnv();
+
+ return 0;
},
- "default_channel_ctx_init"));
-
- Module::TriggerEvent(
- "GPGFRONTEND_CORE_INITLIZED",
- [](const Module::EventIdentifier& /*e*/,
- const Module::Event::ListenerIdentifier& l_id, DataObjectPtr o) {
- if (l_id ==
- "com.bktus.gpgfrontend.module.integrated."
- "gnupginfogathering") {
- SPDLOG_DEBUG(
- "gnupg-info-gathering gnupg.gathering_done changed, restarting "
- "gpg "
- "components");
- // try to restart all components
- GpgFrontend::GpgAdvancedOperator::RestartGpgComponents();
- }
- });
+ "core_init_task"));
}
-void reset_gpgfrontend_core() { SingletonStorageCollection::GetInstance(true); }
-
} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/GpgCoreInit.h b/src/core/GpgCoreInit.h
index 0a10a639..7666761a 100644
--- a/src/core/GpgCoreInit.h
+++ b/src/core/GpgCoreInit.h
@@ -49,7 +49,7 @@ void GPGFRONTEND_CORE_EXPORT ShutdownCoreLoggingSystem();
* @brief
*
*/
-void GPGFRONTEND_CORE_EXPORT ResetGpgFrontendCore();
+void GPGFRONTEND_CORE_EXPORT DestroyGpgFrontendCore();
/**
* @brief
@@ -57,10 +57,4 @@ void GPGFRONTEND_CORE_EXPORT ResetGpgFrontendCore();
*/
void GPGFRONTEND_CORE_EXPORT InitGpgFrontendCore();
-/**
- * @brief
- *
- */
-void reset_gpgfrontend_core();
-
} // namespace GpgFrontend
diff --git a/src/core/function/CoreSignalStation.h b/src/core/function/CoreSignalStation.h
index a53f2eb4..57bd4e44 100644
--- a/src/core/function/CoreSignalStation.h
+++ b/src/core/function/CoreSignalStation.h
@@ -66,7 +66,13 @@ class GPGFRONTEND_CORE_EXPORT CoreSignalStation : public QObject {
* @brief
*
*/
- void SignalGnupgNotInstall();
+ void SignalBadGnupgEnv();
+
+ /**
+ * @brief
+ *
+ */
+ void SignalGoodGnupgEnv();
};
} // namespace GpgFrontend
diff --git a/src/core/function/basic/GpgFunctionObject.h b/src/core/function/basic/GpgFunctionObject.h
index ec0cebac..619cad04 100644
--- a/src/core/function/basic/GpgFunctionObject.h
+++ b/src/core/function/basic/GpgFunctionObject.h
@@ -79,7 +79,7 @@ class SingletonFunctionObject : public ChannelObject {
}
}
- static_assert(std::is_base_of<SingletonFunctionObject<T>, T>::value,
+ static_assert(std::is_base_of_v<SingletonFunctionObject<T>, T>,
"T not derived from SingletonFunctionObject<T>");
auto* p_storage =
@@ -123,7 +123,7 @@ class SingletonFunctionObject : public ChannelObject {
*/
static auto CreateInstance(
int channel, const std::function<ChannelObjectPtr(void)>& factory) -> T& {
- static_assert(std::is_base_of<SingletonFunctionObject<T>, T>::value,
+ static_assert(std::is_base_of_v<SingletonFunctionObject<T>, T>,
"T not derived from SingletonFunctionObject<T>");
auto* p_storage =
diff --git a/src/core/function/basic/SingletonStorageCollection.cpp b/src/core/function/basic/SingletonStorageCollection.cpp
index 144b69e2..e69c1279 100644
--- a/src/core/function/basic/SingletonStorageCollection.cpp
+++ b/src/core/function/basic/SingletonStorageCollection.cpp
@@ -28,6 +28,7 @@
#include "SingletonStorageCollection.h"
+#include <memory>
#include <shared_mutex>
#include "core/function/basic/SingletonStorage.h"
@@ -35,6 +36,10 @@
namespace GpgFrontend {
+std::unique_ptr<SingletonStorageCollection,
+ SecureObjectDeleter<SingletonStorageCollection>>
+ instance = nullptr;
+
class SingletonStorageCollection::Impl {
public:
/**
@@ -43,18 +48,22 @@ class SingletonStorageCollection::Impl {
* @return SingletonStorageCollection*
*/
static auto GetInstance(bool force_refresh) -> SingletonStorageCollection* {
- static SingletonStorageCollection* instance = nullptr;
-
if (force_refresh || instance == nullptr) {
- instance = new SingletonStorageCollection();
- SPDLOG_TRACE("new single storage collection created: {}",
- static_cast<void*>(instance));
+ instance = SecureCreateUniqueObject<SingletonStorageCollection>();
+ SPDLOG_TRACE("a new single storage collection created, address: {}",
+ static_cast<void*>(instance.get()));
}
-
- return instance;
+ return instance.get();
}
/**
+ * @brief Get the Instance object
+ *
+ * @return SingletonStorageCollection*
+ */
+ static void Destroy() { instance = nullptr; }
+
+ /**
* @brief Get the Singleton Storage object
*
* @param singleton_function_object
@@ -95,14 +104,18 @@ SingletonStorageCollection::SingletonStorageCollection() noexcept
SingletonStorageCollection::~SingletonStorageCollection() = default;
+auto GpgFrontend::SingletonStorageCollection::GetInstance(bool force_refresh)
+ -> GpgFrontend::SingletonStorageCollection* {
+ return Impl::GetInstance(force_refresh);
+}
+
+void SingletonStorageCollection::Destroy() {
+ return SingletonStorageCollection::Impl::Destroy();
+}
+
auto SingletonStorageCollection::GetSingletonStorage(
const std::type_info& type_id) -> GpgFrontend::SingletonStorage* {
return p_->GetSingletonStorage(type_id);
}
-auto GpgFrontend::SingletonStorageCollection::GetInstance(
- bool force_refresh = false) -> GpgFrontend::SingletonStorageCollection* {
- return Impl::GetInstance(force_refresh);
-}
-
} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/basic/SingletonStorageCollection.h b/src/core/function/basic/SingletonStorageCollection.h
index b96bff3d..70b91cb9 100644
--- a/src/core/function/basic/SingletonStorageCollection.h
+++ b/src/core/function/basic/SingletonStorageCollection.h
@@ -28,8 +28,6 @@
#pragma once
-#include <core/function/SecureMemoryAllocator.h>
-
#include "core/function/SecureMemoryAllocator.h"
namespace GpgFrontend {
@@ -41,6 +39,18 @@ using SingletonStoragePtr =
class GPGFRONTEND_CORE_EXPORT SingletonStorageCollection {
public:
/**
+ * @brief
+ *
+ */
+ SingletonStorageCollection() noexcept;
+
+ /**
+ * @brief
+ *
+ */
+ ~SingletonStorageCollection();
+
+ /**
* @brief Get the Instance object
*
* @return SingletonStorageCollection*
@@ -48,6 +58,12 @@ class GPGFRONTEND_CORE_EXPORT SingletonStorageCollection {
static auto GetInstance(bool force_refresh) -> SingletonStorageCollection*;
/**
+ * @brief
+ *
+ */
+ static void Destroy();
+
+ /**
* @brief Get the Singleton Storage object
*
* @param singleton_function_object
@@ -58,18 +74,6 @@ class GPGFRONTEND_CORE_EXPORT SingletonStorageCollection {
private:
class Impl;
std::unique_ptr<Impl> p_;
-
- /**
- * @brief
- *
- */
- SingletonStorageCollection() noexcept;
-
- /**
- * @brief
- *
- */
- ~SingletonStorageCollection();
};
} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/gpg/GpgBasicOperator.cpp b/src/core/function/gpg/GpgBasicOperator.cpp
index 4f524d3d..d8a45489 100644
--- a/src/core/function/gpg/GpgBasicOperator.cpp
+++ b/src/core/function/gpg/GpgBasicOperator.cpp
@@ -52,13 +52,14 @@ auto GpgFrontend::GpgBasicOperator::Encrypt(
GpgData data_in(in_buffer.data(), in_buffer.size());
GpgData data_out;
- gpgme_error_t err = CheckGpgError(gpgme_op_encrypt(
- ctx_, recipients, GPGME_ENCRYPT_ALWAYS_TRUST, data_in, data_out));
+ gpgme_error_t err = CheckGpgError(
+ gpgme_op_encrypt(ctx_.DefaultContext(), recipients,
+ GPGME_ENCRYPT_ALWAYS_TRUST, data_in, data_out));
auto temp_data_out = data_out.Read2Buffer();
std::swap(temp_data_out, out_buffer);
- auto temp_result = NewResult(gpgme_op_encrypt_result(ctx_));
+ auto temp_result = NewResult(gpgme_op_encrypt_result(ctx_.DefaultContext()));
std::swap(result, temp_result);
return err;
@@ -71,12 +72,13 @@ auto GpgFrontend::GpgBasicOperator::Decrypt(
GpgData data_in(in_buffer.data(), in_buffer.size());
GpgData data_out;
- err = CheckGpgError(gpgme_op_decrypt(ctx_, data_in, data_out));
+ err =
+ CheckGpgError(gpgme_op_decrypt(ctx_.DefaultContext(), data_in, data_out));
auto temp_data_out = data_out.Read2Buffer();
std::swap(temp_data_out, out_buffer);
- auto temp_result = NewResult(gpgme_op_decrypt_result(ctx_));
+ auto temp_result = NewResult(gpgme_op_decrypt_result(ctx_.DefaultContext()));
std::swap(result, temp_result);
return err;
@@ -93,12 +95,14 @@ auto GpgFrontend::GpgBasicOperator::Verify(BypeArrayRef& in_buffer,
if (sig_buffer != nullptr && !sig_buffer->empty()) {
GpgData sig_data(sig_buffer->data(), sig_buffer->size());
- err = CheckGpgError(gpgme_op_verify(ctx_, sig_data, data_in, nullptr));
+ err = CheckGpgError(
+ gpgme_op_verify(ctx_.DefaultContext(), sig_data, data_in, nullptr));
} else {
- err = CheckGpgError(gpgme_op_verify(ctx_, data_in, nullptr, data_out));
+ err = CheckGpgError(
+ gpgme_op_verify(ctx_.DefaultContext(), data_in, nullptr, data_out));
}
- auto temp_result = NewResult(gpgme_op_verify_result(ctx_));
+ auto temp_result = NewResult(gpgme_op_verify_result(ctx_.DefaultContext()));
std::swap(result, temp_result);
return err;
@@ -115,12 +119,13 @@ auto GpgFrontend::GpgBasicOperator::Sign(
GpgData data_in(in_buffer.data(), in_buffer.size());
GpgData data_out;
- err = CheckGpgError(gpgme_op_sign(ctx_, data_in, data_out, mode));
+ err = CheckGpgError(
+ gpgme_op_sign(ctx_.DefaultContext(), data_in, data_out, mode));
auto temp_data_out = data_out.Read2Buffer();
std::swap(temp_data_out, out_buffer);
- auto temp_result = NewResult(gpgme_op_sign_result(ctx_));
+ auto temp_result = NewResult(gpgme_op_sign_result(ctx_.DefaultContext()));
std::swap(result, temp_result);
@@ -136,15 +141,18 @@ auto GpgFrontend::GpgBasicOperator::DecryptVerify(
GpgData data_in(in_buffer.data(), in_buffer.size());
GpgData data_out;
- err = CheckGpgError(gpgme_op_decrypt_verify(ctx_, data_in, data_out));
+ err = CheckGpgError(
+ gpgme_op_decrypt_verify(ctx_.DefaultContext(), data_in, data_out));
auto temp_data_out = data_out.Read2Buffer();
std::swap(temp_data_out, out_buffer);
- auto temp_decr_result = NewResult(gpgme_op_decrypt_result(ctx_));
+ auto temp_decr_result =
+ NewResult(gpgme_op_decrypt_result(ctx_.DefaultContext()));
std::swap(decrypt_result, temp_decr_result);
- auto temp_verify_result = NewResult(gpgme_op_verify_result(ctx_));
+ auto temp_verify_result =
+ NewResult(gpgme_op_verify_result(ctx_.DefaultContext()));
std::swap(verify_result, temp_verify_result);
return err;
@@ -173,40 +181,43 @@ auto GpgFrontend::GpgBasicOperator::EncryptSign(
GpgData data_out;
// If the last parameter isnt 0, a private copy of data is made
- err = CheckGpgError(gpgme_op_encrypt_sign(
- ctx_, recipients, GPGME_ENCRYPT_ALWAYS_TRUST, data_in, data_out));
+ err = CheckGpgError(gpgme_op_encrypt_sign(ctx_.DefaultContext(), recipients,
+ GPGME_ENCRYPT_ALWAYS_TRUST, data_in,
+ data_out));
auto temp_data_out = data_out.Read2Buffer();
std::swap(temp_data_out, out_buffer);
- auto temp_encr_result = NewResult(gpgme_op_encrypt_result(ctx_));
+ auto temp_encr_result =
+ NewResult(gpgme_op_encrypt_result(ctx_.DefaultContext()));
swap(encr_result, temp_encr_result);
- auto temp_sign_result = NewResult(gpgme_op_sign_result(ctx_));
+ auto temp_sign_result =
+ NewResult(gpgme_op_sign_result(ctx_.DefaultContext()));
swap(sign_result, temp_sign_result);
return err;
}
void GpgFrontend::GpgBasicOperator::SetSigners(KeyArgsList& signers) {
- gpgme_signers_clear(ctx_);
+ gpgme_signers_clear(ctx_.DefaultContext());
for (const GpgKey& key : signers) {
SPDLOG_DEBUG("key fpr: {}", key.GetFingerprint());
if (key.IsHasActualSigningCapability()) {
SPDLOG_DEBUG("signer");
- auto error = gpgme_signers_add(ctx_, gpgme_key_t(key));
+ auto error = gpgme_signers_add(ctx_.DefaultContext(), gpgme_key_t(key));
CheckGpgError(error);
}
}
- if (signers.size() != gpgme_signers_count(ctx_))
+ if (signers.size() != gpgme_signers_count(ctx_.DefaultContext()))
SPDLOG_DEBUG("not all signers added");
}
auto GpgFrontend::GpgBasicOperator::GetSigners()
-> std::unique_ptr<GpgFrontend::KeyArgsList> {
- auto count = gpgme_signers_count(ctx_);
+ auto count = gpgme_signers_count(ctx_.DefaultContext());
auto signers = std::make_unique<std::vector<GpgKey>>();
for (auto i = 0U; i < count; i++) {
- auto key = GpgKey(gpgme_signers_enum(ctx_, i));
+ auto key = GpgKey(gpgme_signers_enum(ctx_.DefaultContext(), i));
signers->push_back(GpgKey(std::move(key)));
}
return signers;
@@ -219,15 +230,17 @@ auto GpgFrontend::GpgBasicOperator::EncryptSymmetric(
GpgData data_in(in_buffer.data(), in_buffer.size());
GpgData data_out;
- gpgme_error_t err = CheckGpgError(gpgme_op_encrypt(
- ctx_, nullptr, GPGME_ENCRYPT_SYMMETRIC, data_in, data_out));
+ gpgme_error_t err = CheckGpgError(
+ gpgme_op_encrypt(ctx_.DefaultContext(), nullptr, GPGME_ENCRYPT_SYMMETRIC,
+ data_in, data_out));
auto temp_data_out = data_out.Read2Buffer();
std::swap(temp_data_out, out_buffer);
// TODO(Saturneric): maybe a bug of gpgme
if (gpgme_err_code(err) == GPG_ERR_NO_ERROR) {
- auto temp_result = NewResult(gpgme_op_encrypt_result(ctx_));
+ auto temp_result =
+ NewResult(gpgme_op_encrypt_result(ctx_.DefaultContext()));
std::swap(result, temp_result);
}
diff --git a/src/core/function/gpg/GpgCommandExecutor.cpp b/src/core/function/gpg/GpgCommandExecutor.cpp
index d05cc626..1717c6e0 100644
--- a/src/core/function/gpg/GpgCommandExecutor.cpp
+++ b/src/core/function/gpg/GpgCommandExecutor.cpp
@@ -35,6 +35,7 @@
#include "core/module/Module.h"
#include "core/thread/Task.h"
#include "core/thread/TaskRunnerGetter.h"
+#include "spdlog/spdlog.h"
namespace GpgFrontend {
@@ -231,6 +232,9 @@ void GpgCommandExecutor::ExecuteConcurrentlyAsync(ExecuteContexts contexts) {
void GpgCommandExecutor::ExecuteConcurrentlySync(ExecuteContexts contexts) {
QEventLoop looper;
auto remaining_tasks = contexts.size();
+ Thread::TaskRunnerPtr target_task_runner = nullptr;
+
+ bool need_looper = true;
for (auto &context : contexts) {
const auto &cmd = context.cmd;
@@ -240,22 +244,37 @@ void GpgCommandExecutor::ExecuteConcurrentlySync(ExecuteContexts contexts) {
QObject::connect(task, &Thread::Task::SignalTaskEnd, [&]() {
--remaining_tasks;
+ SPDLOG_DEBUG("remaining tasks: {}", remaining_tasks);
if (remaining_tasks <= 0) {
+ SPDLOG_DEBUG("no remaining task, quit");
looper.quit();
}
});
if (context.task_runner != nullptr) {
- context.task_runner->PostTask(task);
+ target_task_runner = context.task_runner;
} else {
- GpgFrontend::Thread::TaskRunnerGetter::GetInstance()
- .GetTaskRunner(
- Thread::TaskRunnerGetter::kTaskRunnerType_External_Process)
- ->PostTask(task);
+ target_task_runner =
+ GpgFrontend::Thread::TaskRunnerGetter::GetInstance().GetTaskRunner(
+ Thread::TaskRunnerGetter::kTaskRunnerType_External_Process);
+ }
+
+ target_task_runner->PostTask(task);
+
+ // to arvoid dead lock issue we need to check if current thread is the same
+ // as
+ // target thread. if it is, we can't call exec() because it will block the
+ // current thread.
+ if (QThread::currentThread() == target_task_runner->GetThread()) {
+ need_looper = false;
}
}
- looper.exec();
+ if (need_looper) {
+ // block until task finished
+ // this is to keep reference vaild until task finished
+ looper.exec();
+ }
}
} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/gpg/GpgContext.cpp b/src/core/function/gpg/GpgContext.cpp
index 40a70cee..9b24af3c 100644
--- a/src/core/function/gpg/GpgContext.cpp
+++ b/src/core/function/gpg/GpgContext.cpp
@@ -31,17 +31,13 @@
#include <gpg-error.h>
#include <gpgme.h>
+#include <cassert>
+
#include "core/function/CoreSignalStation.h"
#include "core/function/basic/GpgFunctionObject.h"
-#include "core/function/gpg/GpgCommandExecutor.h"
-#include "core/function/gpg/GpgKeyGetter.h"
#include "core/module/ModuleManager.h"
-#include "core/thread/Task.h"
-#include "core/thread/TaskRunnerGetter.h"
-#include "core/utils/CacheUtils.h"
-#include "core/utils/CommonUtils.h"
#include "core/utils/GpgUtils.h"
-#include "function/CacheManager.h"
+#include "spdlog/spdlog.h"
#ifdef _WIN32
#include <windows.h>
@@ -49,6 +45,15 @@
namespace GpgFrontend {
+struct CtxRefDeleter {
+ void operator()(gpgme_ctx_t _ctx) {
+ if (_ctx != nullptr) gpgme_release(_ctx);
+ }
+};
+
+using CtxRefHandler =
+ std::unique_ptr<struct gpgme_context, CtxRefDeleter>; ///<
+
class GpgContext::Impl : public SingletonFunctionObject<GpgContext::Impl> {
public:
/**
@@ -58,169 +63,29 @@ class GpgContext::Impl : public SingletonFunctionObject<GpgContext::Impl> {
Impl(GpgContext *parent, const GpgContextInitArgs &args, int channel)
: SingletonFunctionObject<GpgContext::Impl>(channel),
parent_(parent),
- args_(args) {
- gpgme_ctx_t p_ctx;
-
- // get gpgme library version
- Module::UpsertRTValue("core", "gpgme.version",
- std::string(gpgme_check_version(nullptr)));
-
- // create a new context
- CheckGpgError(gpgme_new(&p_ctx));
- ctx_ref_ = CtxRefHandler(p_ctx);
-
- if (args.custom_gpgconf && !args.custom_gpgconf_path.empty()) {
- SPDLOG_DEBUG("set custom gpgconf path: {}", args.custom_gpgconf_path);
- auto err =
- gpgme_ctx_set_engine_info(ctx_ref_.get(), GPGME_PROTOCOL_GPGCONF,
- args.custom_gpgconf_path.c_str(), nullptr);
- assert(CheckGpgError(err) == GPG_ERR_NO_ERROR);
- }
-
- // set context offline mode
- SPDLOG_DEBUG("gpg context offline mode: {}", args_.offline_mode);
- gpgme_set_offline(ctx_ref_.get(), args_.offline_mode ? 1 : 0);
-
- // set option auto import missing key
- // invalid at offline mode
- SPDLOG_DEBUG("gpg context auto import missing key: {}", args_.offline_mode);
- if (!args.offline_mode && args.auto_import_missing_key) {
- CheckGpgError(gpgme_set_ctx_flag(ctx_ref_.get(), "auto-key-import", "1"));
- }
-
- // get engine info
- auto *engine_info = gpgme_ctx_get_engine_info(*this);
- // Check ENV before running
- bool check_passed = false;
- bool find_openpgp = false;
- bool find_gpgconf = false;
- bool find_cms = false;
-
- while (engine_info != nullptr) {
- if (strcmp(engine_info->version, "1.0.0") == 0) {
- engine_info = engine_info->next;
- continue;
- }
-
- SPDLOG_DEBUG(
- "gpg context engine info: {} {} {} {}",
- gpgme_get_protocol_name(engine_info->protocol),
- std::string(engine_info->file_name == nullptr
- ? "null"
- : engine_info->file_name),
- std::string(engine_info->home_dir == nullptr ? "null"
- : engine_info->home_dir),
- std::string(engine_info->version ? "null" : engine_info->version));
-
- switch (engine_info->protocol) {
- case GPGME_PROTOCOL_OpenPGP:
- find_openpgp = true;
-
- Module::UpsertRTValue("core", "gpgme.ctx.app_path",
- std::string(engine_info->file_name));
- Module::UpsertRTValue("core", "gpgme.ctx.gnupg_version",
- std::string(engine_info->version));
- Module::UpsertRTValue("core", "gpgme.ctx.database_path",
- std::string(engine_info->home_dir == nullptr
- ? "default"
- : engine_info->home_dir));
- break;
- case GPGME_PROTOCOL_CMS:
- find_cms = true;
- Module::UpsertRTValue("core", "gpgme.ctx.cms_path",
- std::string(engine_info->file_name));
-
- break;
- case GPGME_PROTOCOL_GPGCONF:
- find_gpgconf = true;
- Module::UpsertRTValue("core", "gpgme.ctx.gpgconf_path",
- std::string(engine_info->file_name));
- break;
- case GPGME_PROTOCOL_ASSUAN:
- Module::UpsertRTValue("core", "gpgme.ctx.assuan_path",
- std::string(engine_info->file_name));
- break;
- case GPGME_PROTOCOL_G13:
- break;
- case GPGME_PROTOCOL_UISERVER:
- break;
- case GPGME_PROTOCOL_SPAWN:
- break;
- case GPGME_PROTOCOL_DEFAULT:
- break;
- case GPGME_PROTOCOL_UNKNOWN:
- break;
- }
- engine_info = engine_info->next;
- }
-
- const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>(
- "core", "gpgme.ctx.gnupg_version", std::string{"0.0.0"});
- SPDLOG_DEBUG("got gnupg version from rt: {}", gnupg_version);
-
- // conditional check: only support gpg 2.x now
- if ((CompareSoftwareVersion(gnupg_version, "2.0.0") >= 0 && find_gpgconf &&
- find_openpgp && find_cms)) {
- check_passed = true;
- }
-
- if (!check_passed) {
- this->good_ = false;
- SPDLOG_ERROR("env check failed");
- return;
- }
+ args_(args),
+ good_(default_ctx_initialize(args) && binary_ctx_initialize(args)) {}
- // speed up loading process
- gpgme_set_offline(*this, 1);
-
- // set keylist mode
- if (gnupg_version >= "2.0.0") {
- CheckGpgError(gpgme_set_keylist_mode(
- *this, GPGME_KEYLIST_MODE_LOCAL | GPGME_KEYLIST_MODE_WITH_SECRET |
- GPGME_KEYLIST_MODE_SIGS |
- GPGME_KEYLIST_MODE_SIG_NOTATIONS |
- GPGME_KEYLIST_MODE_WITH_TOFU));
- } else {
- CheckGpgError(gpgme_set_keylist_mode(
- *this, GPGME_KEYLIST_MODE_LOCAL | GPGME_KEYLIST_MODE_SIGS |
- GPGME_KEYLIST_MODE_SIG_NOTATIONS |
- GPGME_KEYLIST_MODE_WITH_TOFU));
- }
-
- // async, init context
- Thread::TaskRunnerGetter::GetInstance()
- .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_GPG)
- ->PostTask(new Thread::Task(
- [=](const DataObjectPtr &) -> int {
- ctx_post_initialize();
- return 0;
- },
- "ctx_post_initialize"));
-
- good_ = true;
+ [[nodiscard]] auto BinaryContext() const -> gpgme_ctx_t {
+ return binary_ctx_ref_.get();
}
- /**
- * @brief
- *
- * @return gpgme_ctx_t
- */
- operator gpgme_ctx_t() const { return ctx_ref_.get(); }
+ [[nodiscard]] auto DefaultContext() const -> gpgme_ctx_t {
+ return ctx_ref_.get();
+ }
[[nodiscard]] auto Good() const -> bool { return good_; }
- void SetPassphraseCb(gpgme_passphrase_cb_t cb) {
- const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>(
- "core", "gpgme.ctx.gnupg_version", std::string{"2.0.0"});
-
- if (CompareSoftwareVersion(gnupg_version, "2.1.0") >= 0) {
- if (gpgme_get_pinentry_mode(*this) != GPGME_PINENTRY_MODE_LOOPBACK) {
- gpgme_set_pinentry_mode(*this, GPGME_PINENTRY_MODE_LOOPBACK);
+ auto SetPassphraseCb(const CtxRefHandler &ctx, gpgme_passphrase_cb_t cb)
+ -> bool {
+ if (gpgme_get_pinentry_mode(ctx.get()) != GPGME_PINENTRY_MODE_LOOPBACK) {
+ if (CheckGpgError(gpgme_set_pinentry_mode(
+ ctx.get(), GPGME_PINENTRY_MODE_LOOPBACK)) != GPG_ERR_NO_ERROR) {
+ return false;
}
- gpgme_set_passphrase_cb(*this, cb, reinterpret_cast<void *>(parent_));
- } else {
- SPDLOG_ERROR("not supported for gnupg version: {}", gnupg_version);
}
+ gpgme_set_passphrase_cb(ctx.get(), cb, reinterpret_cast<void *>(parent_));
+ return true;
}
static auto TestPassphraseCb(void *opaque, const char *uid_hint,
@@ -288,47 +153,82 @@ class GpgContext::Impl : public SingletonFunctionObject<GpgContext::Impl> {
}
private:
- struct CtxRefDeleter {
- void operator()(gpgme_ctx_t _ctx) {
- if (_ctx != nullptr) gpgme_release(_ctx);
+ GpgContext *parent_;
+ GpgContextInitArgs args_{}; ///<
+ CtxRefHandler ctx_ref_ = nullptr; ///<
+ CtxRefHandler binary_ctx_ref_ = nullptr; ///<
+ bool good_ = true;
+
+ static auto set_ctx_key_list_mode(const CtxRefHandler &ctx) -> bool {
+ assert(ctx.get() != nullptr);
+
+ const auto gpgme_version = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "gpgme.version", std::string{"0.0.0"});
+ SPDLOG_DEBUG("got gpgme version version from rt: {}", gpgme_version);
+
+ if (gpgme_get_keylist_mode(ctx.get()) == 0) {
+ SPDLOG_ERROR(
+ "ctx is not a valid pointer, reported by gpgme_get_keylist_mode");
+ return false;
}
- };
- using CtxRefHandler =
- std::unique_ptr<struct gpgme_context, CtxRefDeleter>; ///<
+ // set keylist mode
+ return CheckGpgError(gpgme_set_keylist_mode(
+ ctx.get(),
+ GPGME_KEYLIST_MODE_LOCAL | GPGME_KEYLIST_MODE_WITH_SECRET |
+ GPGME_KEYLIST_MODE_SIGS | GPGME_KEYLIST_MODE_SIG_NOTATIONS |
+ GPGME_KEYLIST_MODE_WITH_TOFU)) == GPG_ERR_NO_ERROR;
+ }
- GpgContext *parent_;
- GpgContextInitArgs args_{}; ///<
- CtxRefHandler ctx_ref_ = nullptr; ///<
- bool good_ = true;
+ auto common_ctx_initialize(const CtxRefHandler &ctx,
+ const GpgContextInitArgs &args) -> bool {
+ assert(ctx.get() != nullptr);
- void ctx_post_initialize() {
- const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>(
- "core", "gpgme.ctx.gnupg_version", std::string{"2.0.0"});
-
- if (args_.ascii) {
- /** Setting the output type must be done at the beginning */
- /** think this means ascii-armor --> ? */
- gpgme_set_armor(*this, 1);
- } else {
- /** Setting the output type must be done at the beginning */
- /** think this means ascii-armor --> ? */
- gpgme_set_armor(*this, 0);
+ if (args.custom_gpgconf && !args.custom_gpgconf_path.empty()) {
+ SPDLOG_DEBUG("set custom gpgconf path: {}", args.custom_gpgconf_path);
+ auto err =
+ gpgme_ctx_set_engine_info(ctx.get(), GPGME_PROTOCOL_GPGCONF,
+ args.custom_gpgconf_path.c_str(), nullptr);
+
+ assert(CheckGpgError(err) == GPG_ERR_NO_ERROR);
+ if (CheckGpgError(err) != GPG_ERR_NO_ERROR) {
+ return false;
+ }
}
- // for unit test
- if (args_.test_mode) {
- if (CompareSoftwareVersion(gnupg_version, "2.1.0") >= 0) {
- SetPassphraseCb(TestPassphraseCb);
+ // set context offline mode
+ SPDLOG_DEBUG("gpg context offline mode: {}", args_.offline_mode);
+ gpgme_set_offline(ctx.get(), args_.offline_mode ? 1 : 0);
+
+ // set option auto import missing key
+ // invalid at offline mode
+ SPDLOG_DEBUG("gpg context auto import missing key: {}", args_.offline_mode);
+ if (!args.offline_mode && args.auto_import_missing_key) {
+ if (CheckGpgError(gpgme_set_ctx_flag(ctx.get(), "auto-key-import",
+ "1")) != GPG_ERR_NO_ERROR) {
+ return false;
}
- gpgme_set_status_cb(*this, TestStatusCb, nullptr);
}
- if (!args_.use_pinentry) {
- SetPassphraseCb(CustomPassphraseCb);
+ if (!set_ctx_key_list_mode(ctx)) {
+ SPDLOG_DEBUG("set ctx key list mode failed");
+ return false;
+ }
+
+ // for unit test
+ if (args_.test_mode) {
+ if (!SetPassphraseCb(ctx, TestPassphraseCb)) {
+ SPDLOG_ERROR("set passphrase cb failed, test");
+ return false;
+ };
+ } else if (!args_.use_pinentry) {
+ if (!SetPassphraseCb(ctx, CustomPassphraseCb)) {
+ SPDLOG_DEBUG("set passphrase cb failed, custom");
+ return false;
+ }
}
- // set custom key db path
+ // set custom gpg key db path
if (!args_.db_path.empty()) {
Module::UpsertRTValue("core", "gpgme.ctx.database_path",
std::string(args_.db_path));
@@ -342,8 +242,50 @@ class GpgContext::Impl : public SingletonFunctionObject<GpgContext::Impl> {
gpgme_ctx_set_engine_info(ctx_ref_.get(), GPGME_PROTOCOL_OpenPGP,
app_path.c_str(), database_path.c_str());
SPDLOG_DEBUG("ctx set custom key db path: {}", database_path);
+
assert(CheckGpgError(err) == GPG_ERR_NO_ERROR);
+ if (CheckGpgError(err) != GPG_ERR_NO_ERROR) {
+ return false;
+ }
}
+
+ return true;
+ }
+
+ auto binary_ctx_initialize(const GpgContextInitArgs &args) -> bool {
+ gpgme_ctx_t p_ctx;
+ if (CheckGpgError(gpgme_new(&p_ctx)) != GPG_ERR_NO_ERROR) {
+ return false;
+ }
+ assert(p_ctx != nullptr);
+ binary_ctx_ref_ = CtxRefHandler(p_ctx);
+
+ if (!common_ctx_initialize(binary_ctx_ref_, args)) {
+ SPDLOG_ERROR("get new ctx failed, binary");
+ return false;
+ }
+
+ /** Setting the output type must be done at the beginning */
+ /** think this means ascii-armor --> ? */
+ gpgme_set_armor(binary_ctx_ref_.get(), 0);
+ return true;
+ }
+
+ auto default_ctx_initialize(const GpgContextInitArgs &args) -> bool {
+ gpgme_ctx_t p_ctx;
+ if (CheckGpgError(gpgme_new(&p_ctx)) != GPG_ERR_NO_ERROR) {
+ SPDLOG_ERROR("get new ctx failed, default");
+ return false;
+ }
+ assert(p_ctx != nullptr);
+ ctx_ref_ = CtxRefHandler(p_ctx);
+
+ if (!common_ctx_initialize(ctx_ref_, args)) {
+ return false;
+ }
+
+ gpgme_set_armor(ctx_ref_.get(), 1);
+ return true;
}
};
@@ -357,12 +299,10 @@ GpgContext::GpgContext(const GpgContextInitArgs &args, int channel)
auto GpgContext::Good() const -> bool { return p_->Good(); }
-void GpgContext::SetPassphraseCb(gpgme_passphrase_cb_t passphrase_cb) const {
- p_->SetPassphraseCb(passphrase_cb);
-}
+auto GpgContext::BinaryContext() -> gpgme_ctx_t { return p_->BinaryContext(); }
-GpgContext::operator gpgme_ctx_t() const {
- return static_cast<gpgme_ctx_t>(*p_);
+auto GpgContext::DefaultContext() -> gpgme_ctx_t {
+ return p_->DefaultContext();
}
GpgContext::~GpgContext() = default;
diff --git a/src/core/function/gpg/GpgContext.h b/src/core/function/gpg/GpgContext.h
index 527099fc..ea8c0e6a 100644
--- a/src/core/function/gpg/GpgContext.h
+++ b/src/core/function/gpg/GpgContext.h
@@ -37,17 +37,16 @@ namespace GpgFrontend {
*
*/
struct GpgContextInitArgs {
- std::string db_path = {};
+ std::string db_path = {}; ///<
- bool test_mode = false;
- bool ascii = true;
- bool offline_mode = false;
- bool auto_import_missing_key = false;
+ bool test_mode = false; ///<
+ bool offline_mode = false; ///<
+ bool auto_import_missing_key = false; ///<
- bool custom_gpgconf = false;
- std::string custom_gpgconf_path;
+ bool custom_gpgconf = false; ///<
+ std::string custom_gpgconf_path; ///<
- bool use_pinentry = false;
+ bool use_pinentry = false; ///<
};
/**
@@ -67,9 +66,9 @@ class GPGFRONTEND_CORE_EXPORT GpgContext
[[nodiscard]] auto Good() const -> bool;
- operator gpgme_ctx_t() const;
+ auto BinaryContext() -> gpgme_ctx_t;
- void SetPassphraseCb(gpgme_passphrase_cb_t passphrase_cb) const;
+ auto DefaultContext() -> gpgme_ctx_t;
private:
class Impl;
diff --git a/src/core/function/gpg/GpgKeyGetter.cpp b/src/core/function/gpg/GpgKeyGetter.cpp
index cad2d884..a60b66c9 100644
--- a/src/core/function/gpg/GpgKeyGetter.cpp
+++ b/src/core/function/gpg/GpgKeyGetter.cpp
@@ -54,7 +54,7 @@ class GpgKeyGetter::Impl : public SingletonFunctionObject<GpgKeyGetter::Impl> {
}
gpgme_key_t p_key = nullptr;
- gpgme_get_key(ctx_, fpr.c_str(), &p_key, 1);
+ gpgme_get_key(ctx_.DefaultContext(), fpr.c_str(), &p_key, 1);
if (p_key == nullptr) {
SPDLOG_WARN("GpgKeyGetter GetKey Private _p_key Null fpr", fpr);
return GetPubkey(fpr, true);
@@ -70,7 +70,7 @@ class GpgKeyGetter::Impl : public SingletonFunctionObject<GpgKeyGetter::Impl> {
}
gpgme_key_t p_key = nullptr;
- gpgme_get_key(ctx_, fpr.c_str(), &p_key, 0);
+ gpgme_get_key(ctx_.DefaultContext(), fpr.c_str(), &p_key, 0);
if (p_key == nullptr) SPDLOG_WARN("GpgKeyGetter GetKey _p_key Null", fpr);
return GpgKey(std::move(p_key));
}
@@ -88,13 +88,13 @@ class GpgKeyGetter::Impl : public SingletonFunctionObject<GpgKeyGetter::Impl> {
}
void FlushKeyCache() {
- SPDLOG_DEBUG("called channel id: {}", GetChannel());
+ SPDLOG_DEBUG("flush key channel called, channel: {}", GetChannel());
// clear the keys cache
keys_cache_.clear();
// init
- GpgError err = gpgme_op_keylist_start(ctx_, nullptr, 0);
+ GpgError err = gpgme_op_keylist_start(ctx_.DefaultContext(), nullptr, 0);
// for debug
assert(CheckGpgError(err) == GPG_ERR_NO_ERROR);
@@ -106,7 +106,8 @@ class GpgKeyGetter::Impl : public SingletonFunctionObject<GpgKeyGetter::Impl> {
// get the lock
std::lock_guard<std::mutex> lock(keys_cache_mutex_);
gpgme_key_t key;
- while ((err = gpgme_op_keylist_next(ctx_, &key)) == GPG_ERR_NO_ERROR) {
+ while ((err = gpgme_op_keylist_next(ctx_.DefaultContext(), &key)) ==
+ GPG_ERR_NO_ERROR) {
auto gpg_key = GpgKey(std::move(key));
// detect if the key is in a smartcard
@@ -120,14 +121,16 @@ class GpgKeyGetter::Impl : public SingletonFunctionObject<GpgKeyGetter::Impl> {
}
}
- SPDLOG_DEBUG("cache address: {} object address: {}",
+ SPDLOG_DEBUG("flush key channel cache address: {} object address: {}",
static_cast<void*>(&keys_cache_), static_cast<void*>(this));
// for debug
assert(CheckGpgError2ErrCode(err, GPG_ERR_EOF) == GPG_ERR_EOF);
- err = gpgme_op_keylist_end(ctx_);
+ err = gpgme_op_keylist_end(ctx_.DefaultContext());
assert(CheckGpgError2ErrCode(err, GPG_ERR_EOF) == GPG_ERR_NO_ERROR);
+
+ SPDLOG_DEBUG("flush key channel done, channel: {}", GetChannel());
}
auto GetKeys(const KeyIdArgsListPtr& ids) -> KeyListPtr {
diff --git a/src/core/function/gpg/GpgKeyImportExporter.cpp b/src/core/function/gpg/GpgKeyImportExporter.cpp
index c0d578c8..a2db25e1 100644
--- a/src/core/function/gpg/GpgKeyImportExporter.cpp
+++ b/src/core/function/gpg/GpgKeyImportExporter.cpp
@@ -48,11 +48,11 @@ auto GpgKeyImportExporter::ImportKey(StdBypeArrayPtr in_buffer)
if (in_buffer->empty()) return {};
GpgData data_in(in_buffer->data(), in_buffer->size());
- auto err = CheckGpgError(gpgme_op_import(ctx_, data_in));
+ auto err = CheckGpgError(gpgme_op_import(ctx_.DefaultContext(), data_in));
if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return {};
gpgme_import_result_t result;
- result = gpgme_op_import_result(ctx_);
+ result = gpgme_op_import_result(ctx_.DefaultContext());
gpgme_import_status_t status = result->imports;
auto import_info = std::make_unique<GpgImportInformation>(result);
while (status != nullptr) {
@@ -90,7 +90,8 @@ auto GpgKeyImportExporter::ExportKeys(KeyIdArgsListPtr& uid_list,
keys_array[index] = nullptr;
GpgData data_out;
- auto err = gpgme_op_export_keys(ctx_, keys_array, mode, data_out);
+ auto err =
+ gpgme_op_export_keys(ctx_.DefaultContext(), keys_array, mode, data_out);
if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return false;
delete[] keys_array;
@@ -156,7 +157,7 @@ auto GpgKeyImportExporter::ExportSecretKey(const GpgKey& key,
GpgData data_out;
// export private key to outBuffer
- gpgme_error_t err = gpgme_op_export_keys(ctx_, target_key,
+ gpgme_error_t err = gpgme_op_export_keys(ctx_.DefaultContext(), target_key,
GPGME_EXPORT_MODE_SECRET, data_out);
auto temp_out_buffer = data_out.Read2Buffer();
@@ -168,7 +169,8 @@ auto GpgKeyImportExporter::ExportSecretKey(const GpgKey& key,
auto GpgKeyImportExporter::ExportKey(const GpgKey& key,
ByteArrayPtr& out_buffer) const -> bool {
GpgData data_out;
- auto err = gpgme_op_export(ctx_, key.GetId().c_str(), 0, data_out);
+ auto err =
+ gpgme_op_export(ctx_.DefaultContext(), key.GetId().c_str(), 0, data_out);
SPDLOG_DEBUG("export keys read_bytes: {}",
gpgme_data_seek(data_out, 0, SEEK_END));
@@ -182,8 +184,8 @@ auto GpgKeyImportExporter::ExportKeyOpenSSH(const GpgKey& key,
ByteArrayPtr& out_buffer) const
-> bool {
GpgData data_out;
- auto err = gpgme_op_export(ctx_, key.GetId().c_str(), GPGME_EXPORT_MODE_SSH,
- data_out);
+ auto err = gpgme_op_export(ctx_.DefaultContext(), key.GetId().c_str(),
+ GPGME_EXPORT_MODE_SSH, data_out);
SPDLOG_DEBUG("read_bytes: {}", gpgme_data_seek(data_out, 0, SEEK_END));
@@ -195,7 +197,7 @@ auto GpgKeyImportExporter::ExportKeyOpenSSH(const GpgKey& key,
auto GpgKeyImportExporter::ExportSecretKeyShortest(
const GpgKey& key, ByteArrayPtr& out_buffer) const -> bool {
GpgData data_out;
- auto err = gpgme_op_export(ctx_, key.GetId().c_str(),
+ auto err = gpgme_op_export(ctx_.DefaultContext(), key.GetId().c_str(),
GPGME_EXPORT_MODE_MINIMAL, data_out);
SPDLOG_DEBUG("read_bytes: {}", gpgme_data_seek(data_out, 0, SEEK_END));
diff --git a/src/core/function/gpg/GpgKeyManager.cpp b/src/core/function/gpg/GpgKeyManager.cpp
index 726b2b66..4a67a3f4 100644
--- a/src/core/function/gpg/GpgKeyManager.cpp
+++ b/src/core/function/gpg/GpgKeyManager.cpp
@@ -54,9 +54,9 @@ auto GpgFrontend::GpgKeyManager::SignKey(
expires_time_t = to_time_t(*expires);
}
- auto err =
- CheckGpgError(gpgme_op_keysign(ctx_, static_cast<gpgme_key_t>(target),
- uid.c_str(), expires_time_t, flags));
+ auto err = CheckGpgError(
+ gpgme_op_keysign(ctx_.DefaultContext(), static_cast<gpgme_key_t>(target),
+ uid.c_str(), expires_time_t, flags));
return CheckGpgError(err) == GPG_ERR_NO_ERROR;
}
@@ -69,9 +69,9 @@ auto GpgFrontend::GpgKeyManager::RevSign(
for (const auto& sign_id : *signature_id) {
auto signing_key = key_getter.GetKey(sign_id.first);
assert(signing_key.IsGood());
- auto err = CheckGpgError(gpgme_op_revsig(ctx_, gpgme_key_t(key),
- gpgme_key_t(signing_key),
- sign_id.second.c_str(), 0));
+ auto err = CheckGpgError(
+ gpgme_op_revsig(ctx_.DefaultContext(), gpgme_key_t(key),
+ gpgme_key_t(signing_key), sign_id.second.c_str(), 0));
if (CheckGpgError(err) != GPG_ERR_NO_ERROR) return false;
}
return true;
@@ -90,8 +90,9 @@ auto GpgFrontend::GpgKeyManager::SetExpire(
if (subkey != nullptr) sub_fprs = subkey->GetFingerprint().c_str();
- auto err = CheckGpgError(gpgme_op_setexpire(
- ctx_, static_cast<gpgme_key_t>(key), expires_time, sub_fprs, 0));
+ auto err = CheckGpgError(gpgme_op_setexpire(ctx_.DefaultContext(),
+ static_cast<gpgme_key_t>(key),
+ expires_time, sub_fprs, 0));
return CheckGpgError(err) == GPG_ERR_NO_ERROR;
}
@@ -180,9 +181,9 @@ auto GpgFrontend::GpgKeyManager::SetOwnerTrustLevel(const GpgKey& key,
GpgData data_out;
- auto err = gpgme_op_interact(ctx_, static_cast<gpgme_key_t>(key), 0,
- GpgKeyManager::interactor_cb_fnc,
- (void*)&handel_struct, data_out);
+ auto err = gpgme_op_interact(
+ ctx_.DefaultContext(), static_cast<gpgme_key_t>(key), 0,
+ GpgKeyManager::interactor_cb_fnc, (void*)&handel_struct, data_out);
if (err != GPG_ERR_NO_ERROR) {
SPDLOG_ERROR("fail to set owner trust level {} to key {}, err: {}",
trust_level, key.GetId(), gpgme_strerror(err));
diff --git a/src/core/function/gpg/GpgKeyOpera.cpp b/src/core/function/gpg/GpgKeyOpera.cpp
index b4aa85eb..a89badc6 100644
--- a/src/core/function/gpg/GpgKeyOpera.cpp
+++ b/src/core/function/gpg/GpgKeyOpera.cpp
@@ -63,9 +63,9 @@ void GpgKeyOpera::DeleteKeys(GpgFrontend::KeyIdArgsListPtr key_ids) {
for (const auto& tmp : *key_ids) {
auto key = GpgKeyGetter::GetInstance().GetKey(tmp);
if (key.IsGood()) {
- err = CheckGpgError(
- gpgme_op_delete_ext(ctx_, static_cast<gpgme_key_t>(key),
- GPGME_DELETE_ALLOW_SECRET | GPGME_DELETE_FORCE));
+ err = CheckGpgError(gpgme_op_delete_ext(
+ ctx_.DefaultContext(), static_cast<gpgme_key_t>(key),
+ GPGME_DELETE_ALLOW_SECRET | GPGME_DELETE_FORCE));
assert(gpg_err_code(err) == GPG_ERR_NO_ERROR);
} else {
SPDLOG_WARN("GpgKeyOpera DeleteKeys get key failed", tmp);
@@ -95,11 +95,13 @@ auto GpgKeyOpera::SetExpire(const GpgKey& key, const SubkeyId& subkey_fpr,
GpgError err;
if (key.GetFingerprint() == subkey_fpr || subkey_fpr.empty()) {
- err = gpgme_op_setexpire(ctx_, static_cast<gpgme_key_t>(key), expires_time,
- nullptr, 0);
+ err =
+ gpgme_op_setexpire(ctx_.DefaultContext(), static_cast<gpgme_key_t>(key),
+ expires_time, nullptr, 0);
} else {
- err = gpgme_op_setexpire(ctx_, static_cast<gpgme_key_t>(key), expires_time,
- subkey_fpr.c_str(), 0);
+ err =
+ gpgme_op_setexpire(ctx_.DefaultContext(), static_cast<gpgme_key_t>(key),
+ expires_time, subkey_fpr.c_str(), 0);
}
return err;
@@ -192,11 +194,13 @@ void GpgKeyOpera::GenerateKey(const std::shared_ptr<GenKeyInfo>& params,
if (params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
SPDLOG_DEBUG("key generation args: {}", userid, algo, expires, flags);
- err = gpgme_op_createkey(ctx, userid, algo, 0, expires, nullptr, flags);
+ err = gpgme_op_createkey(ctx.DefaultContext(), userid, algo, 0, expires,
+ nullptr, flags);
GpgGenKeyResult result;
if (CheckGpgError(err) == GPG_ERR_NO_ERROR) {
- auto temp_result = NewResult(gpgme_op_genkey_result(ctx));
+ auto temp_result =
+ NewResult(gpgme_op_genkey_result(ctx.DefaultContext()));
std::swap(temp_result, result);
}
data_object->Swap({result});
@@ -241,8 +245,9 @@ void GpgKeyOpera::GenerateSubkey(const GpgKey& key,
SPDLOG_DEBUG("args: {} {} {} {}", key.GetId(), algo, expires, flags);
- auto err = gpgme_op_createsubkey(ctx, static_cast<gpgme_key_t>(key),
- algo, 0, expires, flags);
+ auto err = gpgme_op_createsubkey(ctx.DefaultContext(),
+ static_cast<gpgme_key_t>(key), algo, 0,
+ expires, flags);
return CheckGpgError(err);
},
callback, "gpgme_op_createsubkey", "2.1.13");
@@ -252,7 +257,8 @@ void GpgKeyOpera::ModifyPassword(const GpgKey& key,
const GpgOperationCallback& callback) {
RunGpgOperaAsync(
[&key, &ctx = ctx_](const DataObjectPtr&) -> GpgError {
- return gpgme_op_passwd(ctx, static_cast<gpgme_key_t>(key), 0);
+ return gpgme_op_passwd(ctx.DefaultContext(),
+ static_cast<gpgme_key_t>(key), 0);
},
callback, "gpgme_op_passwd", "2.0.15");
}
@@ -269,8 +275,8 @@ auto GpgKeyOpera::ModifyTOFUPolicy(const GpgKey& key,
return GPG_ERR_NOT_SUPPORTED;
}
- auto err =
- gpgme_op_tofu_policy(ctx_, static_cast<gpgme_key_t>(key), tofu_policy);
+ auto err = gpgme_op_tofu_policy(ctx_.DefaultContext(),
+ static_cast<gpgme_key_t>(key), tofu_policy);
return CheckGpgError(err);
}
diff --git a/src/core/function/gpg/GpgUIDOperator.cpp b/src/core/function/gpg/GpgUIDOperator.cpp
index a614d2ee..4610c504 100644
--- a/src/core/function/gpg/GpgUIDOperator.cpp
+++ b/src/core/function/gpg/GpgUIDOperator.cpp
@@ -39,21 +39,22 @@ GpgUIDOperator::GpgUIDOperator(int channel)
: SingletonFunctionObject<GpgUIDOperator>(channel) {}
auto GpgUIDOperator::AddUID(const GpgKey& key, const std::string& uid) -> bool {
- auto err =
- gpgme_op_adduid(ctx_, static_cast<gpgme_key_t>(key), uid.c_str(), 0);
+ auto err = gpgme_op_adduid(ctx_.DefaultContext(),
+ static_cast<gpgme_key_t>(key), uid.c_str(), 0);
return CheckGpgError(err) == GPG_ERR_NO_ERROR;
}
auto GpgUIDOperator::RevUID(const GpgKey& key, const std::string& uid) -> bool {
- auto err = CheckGpgError(
- gpgme_op_revuid(ctx_, static_cast<gpgme_key_t>(key), uid.c_str(), 0));
+ auto err = CheckGpgError(gpgme_op_revuid(
+ ctx_.DefaultContext(), static_cast<gpgme_key_t>(key), uid.c_str(), 0));
return CheckGpgError(err) == GPG_ERR_NO_ERROR;
}
auto GpgUIDOperator::SetPrimaryUID(const GpgKey& key, const std::string& uid)
-> bool {
auto err = CheckGpgError(gpgme_op_set_uid_flag(
- ctx_, static_cast<gpgme_key_t>(key), uid.c_str(), "primary", nullptr));
+ ctx_.DefaultContext(), static_cast<gpgme_key_t>(key), uid.c_str(),
+ "primary", nullptr));
return CheckGpgError(err) == GPG_ERR_NO_ERROR;
}
auto GpgUIDOperator::AddUID(const GpgKey& key, const std::string& name,
diff --git a/src/core/module/Event.cpp b/src/core/module/Event.cpp
index 020f5c69..3c1314fe 100644
--- a/src/core/module/Event.cpp
+++ b/src/core/module/Event.cpp
@@ -80,8 +80,10 @@ class Event::Impl {
void ExecuteCallback(ListenerIdentifier listener_id,
const DataObjectPtr& data_object) {
+ SPDLOG_DEBUG("try to execute callback for event {} with listener {}",
+ event_identifier_, listener_id);
if (callback_) {
- SPDLOG_DEBUG("execute callback for event {} with listener {}",
+ SPDLOG_DEBUG("executing callback for event {} with listener {}",
event_identifier_, listener_id);
if (!QMetaObject::invokeMethod(
callback_thread_,
diff --git a/src/core/module/GlobalModuleContext.cpp b/src/core/module/GlobalModuleContext.cpp
index 4195d719..88250a1e 100644
--- a/src/core/module/GlobalModuleContext.cpp
+++ b/src/core/module/GlobalModuleContext.cpp
@@ -273,8 +273,9 @@ class GlobalModuleContext::Impl {
return true;
}
- auto IsModuleExists(const ModuleIdentifier& m_id) const -> bool {
- return search_module_register_table(m_id).has_value();
+ auto IsModuleActivated(const ModuleIdentifier& m_id) const -> bool {
+ auto m = search_module_register_table(m_id);
+ return m.has_value() && m->get()->activate;
}
private:
@@ -374,8 +375,8 @@ auto GlobalModuleContext::GetDefaultChannel(ModuleRawPtr channel) -> int {
return GlobalModuleContext::Impl::GetDefaultChannel(channel);
}
-auto GlobalModuleContext::IsModuleExists(ModuleIdentifier m_id) -> bool {
- return p_->IsModuleExists(std::move(m_id));
+auto GlobalModuleContext::IsModuleActivated(ModuleIdentifier m_id) -> bool {
+ return p_->IsModuleActivated(std::move(m_id));
}
} // namespace GpgFrontend::Module
diff --git a/src/core/module/GlobalModuleContext.h b/src/core/module/GlobalModuleContext.h
index ea9465e1..1535f2ca 100644
--- a/src/core/module/GlobalModuleContext.h
+++ b/src/core/module/GlobalModuleContext.h
@@ -77,7 +77,7 @@ class GPGFRONTEND_CORE_EXPORT GlobalModuleContext : public QObject {
auto TriggerEvent(EventRefrernce) -> bool;
- auto IsModuleExists(ModuleIdentifier) -> bool;
+ auto IsModuleActivated(ModuleIdentifier) -> bool;
private:
class Impl;
diff --git a/src/core/module/ModuleManager.cpp b/src/core/module/ModuleManager.cpp
index 5e2aa994..03ac21a8 100644
--- a/src/core/module/ModuleManager.cpp
+++ b/src/core/module/ModuleManager.cpp
@@ -102,6 +102,10 @@ class ModuleManager::Impl {
return grt_->ListChildKeys(n, k);
}
+ auto IsModuleActivated(ModuleIdentifier id) -> bool {
+ return gmc_->IsModuleActivated(id);
+ }
+
private:
static ModuleMangerPtr global_module_manager;
TaskRunnerPtr task_runner_;
@@ -109,6 +113,10 @@ class ModuleManager::Impl {
GRTPtr grt_;
};
+auto IsModuleAcivate(ModuleIdentifier id) -> bool {
+ return ModuleManager::GetInstance()->IsModuleActivated(id);
+}
+
auto UpsertRTValue(const std::string& namespace_, const std::string& key,
const std::any& value) -> bool {
return ModuleManager::GetInstance()->UpsertRTValue(namespace_, key,
@@ -170,4 +178,8 @@ auto ModuleManager::ListRTChildKeys(const std::string& n, const std::string& k)
return p_->ListRTChildKeys(n, k);
}
+auto ModuleManager::IsModuleActivated(ModuleIdentifier id) -> bool {
+ return p_->IsModuleActivated(id);
+}
+
} // namespace GpgFrontend::Module \ No newline at end of file
diff --git a/src/core/module/ModuleManager.h b/src/core/module/ModuleManager.h
index 76d6c042..bc05860b 100644
--- a/src/core/module/ModuleManager.h
+++ b/src/core/module/ModuleManager.h
@@ -63,6 +63,8 @@ class GPGFRONTEND_CORE_EXPORT ModuleManager : public QObject {
void RegisterModule(ModulePtr);
+ auto IsModuleActivated(ModuleIdentifier) -> bool;
+
void TriggerEvent(EventRefrernce);
void ActiveModule(ModuleIdentifier);
@@ -110,13 +112,43 @@ void TriggerEvent(const EventIdentifier& event_id, Args&&... args,
std::move(MakeEvent(event_id, std::forward<Args>(args)..., e_cb)));
}
+/**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
+auto GPGFRONTEND_CORE_EXPORT IsModuleAcivate(ModuleIdentifier) -> bool;
+
+/**
+ * @brief
+ *
+ * @param namespace_
+ * @param key
+ * @param value
+ * @return true
+ * @return false
+ */
auto GPGFRONTEND_CORE_EXPORT UpsertRTValue(const std::string& namespace_,
const std::string& key,
const std::any& value) -> bool;
+/**
+ * @brief
+ *
+ * @return true
+ * @return false
+ */
auto GPGFRONTEND_CORE_EXPORT ListenRTPublishEvent(QObject*, Namespace, Key,
LPCallback) -> bool;
+/**
+ * @brief
+ *
+ * @param namespace_
+ * @param key
+ * @return std::vector<Key>
+ */
auto GPGFRONTEND_CORE_EXPORT ListRTChildKeys(const std::string& namespace_,
const std::string& key)
-> std::vector<Key>;
diff --git a/src/core/thread/CtxCheckTask.cpp b/src/core/thread/CtxCheckTask.cpp
index 3c24ca79..88e60f79 100644
--- a/src/core/thread/CtxCheckTask.cpp
+++ b/src/core/thread/CtxCheckTask.cpp
@@ -37,9 +37,9 @@
namespace GpgFrontend {
Thread::CoreInitTask::CoreInitTask() : Task("ctx_check_task") {
- connect(this, &CoreInitTask::SignalGnupgNotInstall,
+ connect(this, &CoreInitTask::SignalBadGnupgEnv,
CoreSignalStation::GetInstance(),
- &CoreSignalStation::SignalGnupgNotInstall);
+ &CoreSignalStation::SignalBadGnupgEnv);
}
void Thread::CoreInitTask::Run() {
@@ -48,7 +48,7 @@ void Thread::CoreInitTask::Run() {
// Create & Check Gnupg Context Status
if (!GpgContext::GetInstance().Good()) {
- emit SignalGnupgNotInstall();
+ emit SignalBadGnupgEnv();
}
// Try flushing key cache
else {
diff --git a/src/core/thread/CtxCheckTask.h b/src/core/thread/CtxCheckTask.h
index 08eb3fc3..4e5f0d84 100644
--- a/src/core/thread/CtxCheckTask.h
+++ b/src/core/thread/CtxCheckTask.h
@@ -50,7 +50,7 @@ class GPGFRONTEND_CORE_EXPORT CoreInitTask : public Task {
* @brief
*
*/
- void SignalGnupgNotInstall();
+ void SignalBadGnupgEnv();
protected:
/**
diff --git a/src/core/utils/GpgUtils.cpp b/src/core/utils/GpgUtils.cpp
index 3e8c5f44..8588f117 100644
--- a/src/core/utils/GpgUtils.cpp
+++ b/src/core/utils/GpgUtils.cpp
@@ -55,8 +55,9 @@ static inline auto Trim(std::string& s) -> std::string {
auto CheckGpgError(GpgError err) -> GpgError {
if (gpg_err_code(err) != GPG_ERR_NO_ERROR) {
- SPDLOG_ERROR("[error: {}] source: {} description: {}", gpg_err_code(err),
- gpgme_strsource(err), gpgme_strerror(err));
+ SPDLOG_ERROR(
+ "gpg operation failed [error code: {}], source: {} description: {}",
+ gpg_err_code(err), gpgme_strsource(err), gpgme_strerror(err));
}
return err;
}
diff --git a/src/init.cpp b/src/init.cpp
index 91d02ac8..f9f1801f 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -41,7 +41,7 @@
#include "core/function/GlobalSettingStation.h"
#include "core/utils/MemoryUtils.h"
#include "module/GpgFrontendModuleInit.h"
-#include "spdlog/logger.h"
+#include "module/sdk/Log.h"
#include "ui/GpgFrontendUIInit.h"
// main
@@ -88,7 +88,7 @@ void InitMainLoggingSystem(spdlog::level::level_enum level) {
spdlog::set_default_logger(main_logger);
}
-void InitModules(InitArgs args) {
+void InitLoggingSystem(InitArgs args) {
// init the logging system for main
InitMainLoggingSystem(args.log_level);
@@ -97,21 +97,15 @@ void InitModules(InitArgs args) {
// init the logging system for ui
GpgFrontend::UI::InitUILoggingSystem(args.log_level);
-
- // init the logging system for modules
- GpgFrontend::Module::ModuleInitArgs module_init_args;
- module_init_args.log_level = args.log_level;
- //
- GpgFrontend::Module::LoadGpgFrontendModules(module_init_args);
}
-void ShutdownModules() {
- // shutdown the logging system for core
- GpgFrontend::Module::ShutdownGpgFrontendModules();
-
+void ShutdownLoggingSystem() {
// shutdown the logging system for ui
GpgFrontend::UI::ShutdownUILoggingSystem();
+ // shutdown the logging system for modules
+ GpgFrontend::Module::ShutdownGpgFrontendModulesLoggingSystem();
+
// shutdown the logging system for core
GpgFrontend::ShutdownCoreLoggingSystem();
diff --git a/src/init.h b/src/init.h
index cc8e2200..32b4f490 100644
--- a/src/init.h
+++ b/src/init.h
@@ -44,16 +44,17 @@ void HandleSignal(int sig);
void BeforeExit();
/**
- * @brief initialize the logging system.
+ * @brief
*
+ * @param args
*/
-void InitModules(InitArgs);
+void InitLoggingSystem(InitArgs args);
/**
* @brief initialize the logging system.
*
*/
-void ShutdownModules();
+void ShutdownLoggingSystem();
/**
* @brief init global PATH env
diff --git a/src/module/GpgFrontendModuleInit.cpp b/src/module/GpgFrontendModuleInit.cpp
index 367d1be1..1e83af0e 100644
--- a/src/module/GpgFrontendModuleInit.cpp
+++ b/src/module/GpgFrontendModuleInit.cpp
@@ -29,7 +29,9 @@
#include "GpgFrontendModuleInit.h"
#include <core/module/ModuleManager.h>
-#include <module/sdk/Log.h>
+
+#include "core/thread/Task.h"
+#include "core/thread/TaskRunnerGetter.h"
// integrated modules
#include "integrated/gnupg_info_gathering_module/GnuPGInfoGatheringModule.h"
@@ -37,8 +39,17 @@
namespace GpgFrontend::Module {
+void LoadGpgFrontendModulesLoggingSystem(ModuleInitArgs args) {
+ GpgFrontend::Module::SDK::InitModuleLoggingSystem(args.log_level);
+}
+
+void ShutdownGpgFrontendModulesLoggingSystem() {
+ GpgFrontend::Module::SDK::ShutdownModuleLoggingSystem();
+}
+
void LoadGpgFrontendModules(ModuleInitArgs args) {
- SDK::InitModuleLoggingSystem(args.log_level);
+ // init the logging system for module system
+ LoadGpgFrontendModulesLoggingSystem(args);
MODULE_LOG_INFO("loading integrated module...");
@@ -51,8 +62,13 @@ void LoadGpgFrontendModules(ModuleInitArgs args) {
Integrated::GnuPGInfoGatheringModule::GnuPGInfoGatheringModule>();
MODULE_LOG_INFO("load integrated module done.");
+
+ // must init at default thread before core
+ Thread::TaskRunnerGetter::GetInstance().GetTaskRunner()->PostTask(
+ new Thread::Task([](const DataObjectPtr&) -> int { return 0; },
+ "modules_system_init_task"));
}
-void ShutdownGpgFrontendModules() { SDK::ShutdownModuleLoggingSystem(); }
+void ShutdownGpgFrontendModules() {}
} // namespace GpgFrontend::Module \ No newline at end of file
diff --git a/src/module/GpgFrontendModuleInit.h b/src/module/GpgFrontendModuleInit.h
index 252338bf..a706bbb4 100644
--- a/src/module/GpgFrontendModuleInit.h
+++ b/src/module/GpgFrontendModuleInit.h
@@ -37,10 +37,24 @@ struct ModuleInitArgs {
};
/**
+ * @brief
+ *
+ * @param args
+ */
+void GPGFRONTEND_MODULE_EXPORT
+LoadGpgFrontendModulesLoggingSystem(ModuleInitArgs args);
+
+/**
+ * @brief
+ *
+ */
+void GPGFRONTEND_MODULE_EXPORT ShutdownGpgFrontendModulesLoggingSystem();
+
+/**
* @brief init the module library
*
*/
-void GPGFRONTEND_MODULE_EXPORT LoadGpgFrontendModules(ModuleInitArgs);
+void GPGFRONTEND_MODULE_EXPORT LoadGpgFrontendModules(ModuleInitArgs args);
/**
* @brief shutdown the module library
diff --git a/src/module/integrated/gnupg_info_gathering_module/GnuPGInfoGatheringModule.cpp b/src/module/integrated/gnupg_info_gathering_module/GnuPGInfoGatheringModule.cpp
index 492c87f1..9477848b 100644
--- a/src/module/integrated/gnupg_info_gathering_module/GnuPGInfoGatheringModule.cpp
+++ b/src/module/integrated/gnupg_info_gathering_module/GnuPGInfoGatheringModule.cpp
@@ -97,7 +97,7 @@ int GnuPGInfoGatheringModule::Exec(EventRefrernce event) {
event->GetIdentifier());
const auto gpgme_version = RetrieveRTValueTypedOrDefault<>(
- "core", "gpgme.version", std::string{"2.0.0"});
+ "core", "gpgme.version", std::string{"0.0.0"});
MODULE_LOG_DEBUG("got gpgme version from rt: {}", gpgme_version);
const auto gpgconf_path = RetrieveRTValueTypedOrDefault<>(
@@ -289,8 +289,7 @@ int GnuPGInfoGatheringModule::Exec(EventRefrernce event) {
std::string{});
auto jsonlized_component_info = nlohmann::json::parse(component_info_json);
- GpgComponentInfo component_info =
- jsonlized_component_info.get<GpgComponentInfo>();
+ auto component_info = jsonlized_component_info.get<GpgComponentInfo>();
MODULE_LOG_DEBUG("gpgconf check options ready, component: {}",
component_info.name);
@@ -393,6 +392,8 @@ int GnuPGInfoGatheringModule::Exec(EventRefrernce event) {
UpsertRTValue(GetModuleIdentifier(), "gnupg.gathering_done", true);
event->ExecuteCallback(GetModuleIdentifier(), TransferParams(true));
+ SPDLOG_INFO("gnupg external info gathering done");
+
return 0;
}
diff --git a/src/module/sdk/Log.cpp b/src/module/sdk/Log.cpp
index 4d6620ff..b70f5bbb 100644
--- a/src/module/sdk/Log.cpp
+++ b/src/module/sdk/Log.cpp
@@ -33,6 +33,8 @@
#include <spdlog/sinks/rotating_file_sink.h>
#include <spdlog/sinks/stdout_color_sinks.h>
+#include <stdexcept>
+
#include "core/function/GlobalSettingStation.h"
namespace GpgFrontend::Module::SDK {
@@ -81,7 +83,13 @@ void ShutdownModuleLoggingSystem() {
#endif
}
-std::shared_ptr<spdlog::logger> GetModuleLogger() {
+auto GetModuleLogger() -> std::shared_ptr<spdlog::logger> {
+ // check if logging system is initalized
+ auto ptr = spdlog::get("module");
+ if (ptr == nullptr) {
+ throw std::runtime_error("logging system of modules is not initialized");
+ }
+
return spdlog::get("module");
}
diff --git a/src/ui/GpgFrontendUIInit.cpp b/src/ui/GpgFrontendUIInit.cpp
index 454e0e2a..0d2a3331 100644
--- a/src/ui/GpgFrontendUIInit.cpp
+++ b/src/ui/GpgFrontendUIInit.cpp
@@ -28,6 +28,7 @@
#include "GpgFrontendUIInit.h"
+#include <qapplication.h>
#include <spdlog/async.h>
#include <spdlog/common.h>
#include <spdlog/sinks/rotating_file_sink.h>
@@ -37,9 +38,12 @@
#include <string>
#include "core/GpgConstants.h"
+#include "core/function/CoreSignalStation.h"
#include "core/function/GlobalSettingStation.h"
+#include "core/module/ModuleManager.h"
#include "core/thread/CtxCheckTask.h"
#include "core/thread/TaskRunnerGetter.h"
+#include "spdlog/spdlog.h"
#include "ui/UISignalStation.h"
#include "ui/UserInterfaceUtils.h"
#include "ui/main_window/MainWindow.h"
@@ -52,6 +56,65 @@ namespace GpgFrontend::UI {
extern void InitLocale();
+void WaitEnvCheckingProcess() {
+ SPDLOG_DEBUG("need to waiting for env checking process");
+
+ // create and show loading window before starting the main window
+ auto* waiting_dialog = new QProgressDialog();
+ waiting_dialog->setMaximum(0);
+ waiting_dialog->setMinimum(0);
+ auto* waiting_dialog_label =
+ new QLabel(QString(_("Loading Gnupg Info...")) + "<br /><br />" +
+ _("If this process is too slow, please set the key "
+ "server address appropriately in the gnupg configuration "
+ "file (depending "
+ "on the network situation in your country or region)."));
+ waiting_dialog_label->setWordWrap(true);
+ waiting_dialog->setLabel(waiting_dialog_label);
+ waiting_dialog->resize(420, 120);
+ QApplication::connect(CoreSignalStation::GetInstance(),
+ &CoreSignalStation::SignalGoodGnupgEnv, waiting_dialog,
+ [=]() {
+ SPDLOG_DEBUG("gpg env loaded successfuly");
+ waiting_dialog->finished(0);
+ waiting_dialog->deleteLater();
+ });
+
+ // new local event looper
+ QEventLoop looper;
+ QApplication::connect(CoreSignalStation::GetInstance(),
+ &CoreSignalStation::SignalGoodGnupgEnv, &looper,
+ &QEventLoop::quit);
+
+ QApplication::connect(waiting_dialog, &QProgressDialog::canceled, [=]() {
+ SPDLOG_DEBUG("cancel clicked on wairing dialog");
+ QApplication::quit();
+ exit(0);
+ });
+
+ auto env_state = Module::RetrieveRTValueTypedOrDefault<>(
+ "core", "env.state.basic", std::string{"0"});
+
+ SPDLOG_DEBUG("ui is ready to wating for env initialized, env_state: {}",
+ env_state);
+
+ // check twice to avoid some unlucky sitations
+ if (env_state == "1") {
+ SPDLOG_DEBUG("env state turned initialized before the looper start");
+ waiting_dialog->finished(0);
+ waiting_dialog->deleteLater();
+ return;
+ }
+
+ // show the loading window
+ waiting_dialog->setModal(true);
+ waiting_dialog->setFocus();
+ waiting_dialog->show();
+
+ // block the main thread until the gpg context is loaded
+ looper.exec();
+}
+
void InitGpgFrontendUI(QApplication* app) {
// init locale
InitLocale();
@@ -132,51 +195,10 @@ void InitGpgFrontendUI(QApplication* app) {
QNetworkProxy::setApplicationProxy(QNetworkProxy::NoProxy);
}
- // create the thread to load the gpg context
- auto* init_ctx_task = new Thread::CoreInitTask();
-
- // create and show loading window before starting the main window
- auto* waiting_dialog = new QProgressDialog();
- waiting_dialog->setMaximum(0);
- waiting_dialog->setMinimum(0);
- auto waiting_dialog_label =
- new QLabel(QString(_("Loading Gnupg Info...")) + "<br /><br />" +
- _("If this process is too slow, please set the key "
- "server address appropriately in the gnupg configuration "
- "file (depending "
- "on the network situation in your country or region)."));
- waiting_dialog_label->setWordWrap(true);
- waiting_dialog->setLabel(waiting_dialog_label);
- waiting_dialog->resize(420, 120);
- app->connect(init_ctx_task, &Thread::CoreInitTask::SignalTaskEnd,
- waiting_dialog, [=]() {
- SPDLOG_DEBUG("gpg context loaded");
- waiting_dialog->finished(0);
- waiting_dialog->deleteLater();
- });
-
- app->connect(waiting_dialog, &QProgressDialog::canceled, [=]() {
- SPDLOG_DEBUG("cancel clicked");
- app->quit();
- exit(0);
- });
-
- // show the loading window
- waiting_dialog->setModal(true);
- waiting_dialog->setFocus();
- waiting_dialog->show();
-
- // new local event looper
- QEventLoop looper;
- app->connect(init_ctx_task, &Thread::CoreInitTask::SignalTaskEnd, &looper,
- &QEventLoop::quit);
-
- // start the thread to load the gpg context
- Thread::TaskRunnerGetter::GetInstance().GetTaskRunner()->PostTask(
- init_ctx_task);
-
- // block the main thread until the gpg context is loaded
- looper.exec();
+ if (Module::RetrieveRTValueTypedOrDefault<>("core", "env.state.basic",
+ std::string{"0"}) == "0") {
+ WaitEnvCheckingProcess();
+ }
}
int RunGpgFrontendUI(QApplication* app) {
@@ -187,12 +209,15 @@ int RunGpgFrontendUI(QApplication* app) {
if (CommonUtils::GetInstance()->isApplicationNeedRestart()) {
SPDLOG_DEBUG("application need to restart, before mian window init");
return kDeepRestartCode;
- } else {
- main_window->Init();
- SPDLOG_DEBUG("main window inited");
- main_window->show();
}
+ // init main window
+ main_window->Init();
+
+ // show main windows
+ SPDLOG_DEBUG("main window is ready to show");
+ main_window->show();
+
// start the main event loop
return app->exec();
}
@@ -242,6 +267,8 @@ void ShutdownUILoggingSystem() {
#endif
}
+void GPGFRONTEND_UI_EXPORT DestroyGpgFrontendUI() { ShutdownUILoggingSystem(); }
+
/**
* @brief setup the locale and load the translations
*
diff --git a/src/ui/GpgFrontendUIInit.h b/src/ui/GpgFrontendUIInit.h
index b14b43b9..0ed630bb 100644
--- a/src/ui/GpgFrontendUIInit.h
+++ b/src/ui/GpgFrontendUIInit.h
@@ -45,6 +45,12 @@ void GPGFRONTEND_UI_EXPORT InitGpgFrontendUI(QApplication *);
void GPGFRONTEND_UI_EXPORT InitUILoggingSystem(spdlog::level::level_enum level);
/**
+ * @brief init the UI library
+ *
+ */
+void GPGFRONTEND_UI_EXPORT DestroyGpgFrontendUI();
+
+/**
* @brief
*
*/
diff --git a/src/ui/UserInterfaceUtils.cpp b/src/ui/UserInterfaceUtils.cpp
index a73f56d2..6f4ca7d0 100644
--- a/src/ui/UserInterfaceUtils.cpp
+++ b/src/ui/UserInterfaceUtils.cpp
@@ -160,8 +160,8 @@ CommonUtils *CommonUtils::GetInstance() {
CommonUtils::CommonUtils() : QWidget(nullptr) {
connect(CoreSignalStation::GetInstance(),
- &CoreSignalStation::SignalGnupgNotInstall, this,
- &CommonUtils::SignalGnupgNotInstall);
+ &CoreSignalStation::SignalBadGnupgEnv, this,
+ &CommonUtils::SignalBadGnupgEnv);
connect(this, &CommonUtils::SignalKeyStatusUpdated,
UISignalStation::GetInstance(),
&UISignalStation::SignalKeyDatabaseRefresh);
@@ -184,7 +184,7 @@ CommonUtils::CommonUtils() : QWidget(nullptr) {
&UISignalStation::SignalRestartApplication, this,
&CommonUtils::SlotRestartApplication);
- connect(this, &CommonUtils::SignalGnupgNotInstall, this, [=]() {
+ connect(this, &CommonUtils::SignalBadGnupgEnv, this, [=]() {
QMessageBox msgBox;
msgBox.setText(_("GnuPG Context Loading Failed"));
msgBox.setInformativeText(
diff --git a/src/ui/UserInterfaceUtils.h b/src/ui/UserInterfaceUtils.h
index a1719016..f9210125 100644
--- a/src/ui/UserInterfaceUtils.h
+++ b/src/ui/UserInterfaceUtils.h
@@ -207,7 +207,7 @@ class CommonUtils : public QWidget {
* @brief
*
*/
- void SignalGnupgNotInstall();
+ void SignalBadGnupgEnv();
/**
* @brief emit when the key database is refreshed