diff options
author | saturneric <[email protected]> | 2024-11-22 22:06:30 +0000 |
---|---|---|
committer | saturneric <[email protected]> | 2024-11-22 22:06:30 +0000 |
commit | e16e15db09d89a997db73e313b966f95e6c59f56 (patch) | |
tree | 4f6be7375b983eda33b5faa37b9c7a3af0a57ed6 /src/core/GpgCoreInit.cpp | |
parent | fix: correct the path to the executable of app image mode (diff) | |
download | GpgFrontend-e16e15db09d89a997db73e313b966f95e6c59f56.tar.gz GpgFrontend-e16e15db09d89a997db73e313b966f95e6c59f56.zip |
feat: rewrite core init processes and add env option
Diffstat (limited to 'src/core/GpgCoreInit.cpp')
-rw-r--r-- | src/core/GpgCoreInit.cpp | 512 |
1 files changed, 351 insertions, 161 deletions
diff --git a/src/core/GpgCoreInit.cpp b/src/core/GpgCoreInit.cpp index e796738e..8a625f9d 100644 --- a/src/core/GpgCoreInit.cpp +++ b/src/core/GpgCoreInit.cpp @@ -89,35 +89,74 @@ auto SearchKeyDatabasePath(const QList<QString>& candidate_paths) -> QString { return {}; } -auto InitGpgME(const QString& gpgconf_path, const QString& gnupg_path) -> bool { - // init gpgme subsystem and get gpgme library version - Module::UpsertRTValue("core", "gpgme.version", - QString(gpgme_check_version(nullptr))); +auto GetDefaultKeyDatabasePath(const QString& gpgconf_path) -> QString { + if (gpgconf_path.isEmpty()) return {}; - gpgme_set_locale(nullptr, LC_CTYPE, setlocale(LC_CTYPE, nullptr)); -#ifdef LC_MESSAGES - gpgme_set_locale(nullptr, LC_MESSAGES, setlocale(LC_MESSAGES, nullptr)); -#endif + QFileInfo info(gpgconf_path); + if (!info.exists() || !info.isFile()) return {}; - if (!gpgconf_path.isEmpty()) { - CheckGpgError(gpgme_set_engine_info(GPGME_PROTOCOL_GPGCONF, - gpgconf_path.toUtf8(), nullptr)); + auto* p = new QProcess(QCoreApplication::instance()); + p->setProgram(info.absoluteFilePath()); + p->setArguments({"--list-dirs", "homedir"}); + p->start(); + + p->waitForFinished(); + auto home_path = p->readAll().trimmed(); + p->deleteLater(); + + QFileInfo home_info(home_path); + return home_info.absoluteFilePath(); +} + +auto InitGpgME() -> bool { + const auto* ver = gpgme_check_version(nullptr); + if (ver == nullptr) { + LOG_E() << "gpgme_check_version() failed, abort..."; + return false; + ; } + Module::UpsertRTValue("core", "gpgme.version", QString(ver)); - if (!gnupg_path.isEmpty()) { - CheckGpgError(gpgme_set_engine_info(GPGME_PROTOCOL_OpenPGP, - gnupg_path.toUtf8(), nullptr)); + // require gnupg version > 2.1.0 + if (gpgme_set_global_flag("require-gnupg", "2.1.0") != 0) { + LOG_E() << "gpgme_set_global_flag() with argument 'require-gnupg' failed, " + "abort..."; + return false; + } + + if (CheckGpgError( + gpgme_set_locale(nullptr, LC_CTYPE, setlocale(LC_CTYPE, nullptr))) != + GPG_ERR_NO_ERROR) { + LOG_E() << "gpgme_set_locale() with argument LC_CTYPE failed, abort..."; + return false; + } + +#ifdef LC_MESSAGES + if (CheckGpgError(gpgme_set_locale(nullptr, LC_MESSAGES, + setlocale(LC_MESSAGES, nullptr))) != + GPG_ERR_NO_ERROR) { + LOG_E() << "gpgme_set_locale() with argument LC_MESSAGES failed, abort..."; + return false; } +#endif gpgme_ctx_t p_ctx; - CheckGpgError(gpgme_new(&p_ctx)); + if (CheckGpgError(gpgme_new(&p_ctx)) != GPG_ERR_NO_ERROR) { + LOG_E() << "gpgme_new() failed, abort..."; + return false; + } // get engine info auto* engine_info = gpgme_ctx_get_engine_info(p_ctx); + if (engine_info == nullptr) { + LOG_E() << "gpgme_ctx_get_engine_info() failed, abort..."; + return false; + } + // Check ENV before running - bool find_openpgp = false; - bool find_gpgconf = false; - bool find_cms = false; + bool has_gpgconf = false; + bool has_openpgp = false; + bool has_cms = false; while (engine_info != nullptr) { if (strcmp(engine_info->version, "1.0.0") == 0) { @@ -127,7 +166,7 @@ auto InitGpgME(const QString& gpgconf_path, const QString& gnupg_path) -> bool { switch (engine_info->protocol) { case GPGME_PROTOCOL_OpenPGP: - find_openpgp = true; + has_openpgp = true; Module::UpsertRTValue("core", "gpgme.engine.openpgp", 1); Module::UpsertRTValue("core", "gpgme.ctx.app_path", @@ -140,21 +179,20 @@ auto InitGpgME(const QString& gpgconf_path, const QString& gnupg_path) -> bool { : engine_info->home_dir)); break; case GPGME_PROTOCOL_CMS: - find_cms = true; + has_cms = true; Module::UpsertRTValue("core", "gpgme.engine.cms", 1); Module::UpsertRTValue("core", "gpgme.ctx.cms_path", QString(engine_info->file_name)); break; case GPGME_PROTOCOL_GPGCONF: - find_gpgconf = true; + has_gpgconf = true; Module::UpsertRTValue("core", "gpgme.engine.gpgconf", 1); Module::UpsertRTValue("core", "gpgme.ctx.gpgconf_path", QString(engine_info->file_name)); break; case GPGME_PROTOCOL_ASSUAN: - Module::UpsertRTValue("core", "gpgme.engine.assuan", 1); Module::UpsertRTValue("core", "gpgme.ctx.assuan_path", QString(engine_info->file_name)); @@ -178,21 +216,62 @@ auto InitGpgME(const QString& gpgconf_path, const QString& gnupg_path) -> bool { const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>( "core", "gpgme.ctx.gnupg_version", QString{"0.0.0"}); + const auto gpgconf_path = Module::RetrieveRTValueTypedOrDefault<>( + "core", "gpgme.ctx.gnupg_version", QString{}); - // conditional check: only support gpg 2.1.x now - if (!(GFCompareSoftwareVersion(gnupg_version, "2.1.0") >= 0 && find_gpgconf && - find_openpgp && find_cms)) { - FLOG_W("gpgme env check failed, abort"); + if (!has_gpgconf) { + FLOG_E() << "cannot get gpgconf backend engine, abort..."; return false; } - Module::UpsertRTValue("core", "env.state.gpgme", 1); + if (!has_openpgp) { + FLOG_E() << "cannot get openpgp backend engine, abort..."; + return false; + } + + if (!has_cms) { + FLOG_E() << "cannot get cms backend engine, abort..."; + return false; + } + + // ensure, and check twice: only support gpg > 2.1.0 + if (!(GFCompareSoftwareVersion(gnupg_version, "2.1.0") >= 0)) { + FLOG_F("gpgme env check failed, abort"); + return false; + } + + return true; +} + +auto RefreshGpgMEBackendEngine(const QString& gpgconf_path, + const QString& gnupg_path, + const QString& home_path) -> bool { + if (!gpgconf_path.isEmpty()) { + auto err = CheckGpgError(gpgme_set_engine_info( + GPGME_PROTOCOL_GPGCONF, gpgconf_path.toUtf8(), nullptr)); + if (err != GPG_ERR_NO_ERROR) { + LOG_W() << "cannot set gpgconf path of gpgme, fallback using default " + "gpgconf path, target gpgconf path:" + << gpgconf_path; + } + } + + if (!gnupg_path.isEmpty()) { + auto err = CheckGpgError(gpgme_set_engine_info( + GPGME_PROTOCOL_OpenPGP, gnupg_path.toUtf8(), home_path.toUtf8())); + if (err != GPG_ERR_NO_ERROR) { + LOG_W() << "cannot set gnupg path and home path of gpgme, fallback using " + "default gpgconf path, target gnupg path:" + << gnupg_path << "target home path: " << home_path; + } + } + return true; } -auto GetGnuPGPathByGpgConf(const QString& gnupg_install_fs_path) -> QString { - auto* process = new QProcess(); - process->setProgram(gnupg_install_fs_path); +auto GetGnuPGPathByGpgConf(const QString& gpgconf_install_fs_path) -> QString { + auto* process = new QProcess(QCoreApplication::instance()); + process->setProgram(gpgconf_install_fs_path); process->start(); process->waitForFinished(1000); auto output_buffer = process->readAllStandardOutput(); @@ -224,36 +303,44 @@ auto GetGnuPGPathByGpgConf(const QString& gnupg_install_fs_path) -> QString { } return ""; } -auto DetectGpgConfPath() -> QString { + +auto DecideGpgConfPath(const QString& default_gpgconf_path) -> QString { auto settings = GlobalSettingStation::GetInstance().GetSettings(); auto use_custom_gnupg_install_path = settings.value("gnupg/use_custom_gnupg_install_path", false).toBool(); auto custom_gnupg_install_path = settings.value("gnupg/custom_gnupg_install_path", QString{}).toString(); - QString gnupg_install_fs_path; + QString gpgconf_install_fs_path; // user defined if (use_custom_gnupg_install_path && !custom_gnupg_install_path.isEmpty()) { // check gpgconf path - gnupg_install_fs_path = custom_gnupg_install_path; + gpgconf_install_fs_path = custom_gnupg_install_path; #if defined(_WIN32) || defined(WIN32) gnupg_install_fs_path += "/gpgconf.exe"; #else - gnupg_install_fs_path += "/gpgconf"; + gpgconf_install_fs_path += "/gpgconf"; #endif - if (!VerifyGpgconfPath(QFileInfo(gnupg_install_fs_path))) { - LOG_W() << "core loaded custom gpgconf path is illegal: " - << gnupg_install_fs_path; - gnupg_install_fs_path = ""; + if (!VerifyGpgconfPath(QFileInfo(gpgconf_install_fs_path))) { + LOG_W() << "the gpgconf path by settings is illegal, path: " + << gpgconf_install_fs_path; + gpgconf_install_fs_path = ""; } } + if (gpgconf_install_fs_path.isEmpty() && + !default_gpgconf_path.trimmed().isEmpty()) { + LOG_I() << "using default gpgconf path found by gpgme: " + << default_gpgconf_path; + return QFileInfo(default_gpgconf_path).absoluteFilePath(); + } + // custom not found or not defined then fallback to default candidate path - if (gnupg_install_fs_path.isEmpty()) { + if (gpgconf_install_fs_path.isEmpty()) { // platform detection #if defined(__APPLE__) && defined(__MACH__) - gnupg_install_fs_path = SearchGpgconfPath( + gpgconf_install_fs_path = SearchGpgconfPath( {"/usr/local/bin/gpgconf", "/opt/homebrew/bin/gpgconf"}); #elif defined(_WIN32) || defined(WIN32) gnupg_install_fs_path = @@ -265,35 +352,118 @@ auto DetectGpgConfPath() -> QString { #endif } - if (!gnupg_install_fs_path.isEmpty()) { - return QFileInfo(gnupg_install_fs_path).absoluteFilePath(); + if (!gpgconf_install_fs_path.isEmpty()) { + return QFileInfo(gpgconf_install_fs_path).absoluteFilePath(); } return ""; } -auto DetectGnuPGPath(QString gpgconf_path) -> QString { +auto DecideGnuPGPath(const QString& gpgconf_path) -> QString { return GetGnuPGPathByGpgConf(gpgconf_path); } -void InitGpgFrontendCore(CoreInitArgs args) { - // initialize global register table - Module::UpsertRTValue("core", "env.state.gpgme", 0); - Module::UpsertRTValue("core", "env.state.ctx", 0); - Module::UpsertRTValue("core", "env.state.basic", 0); - Module::UpsertRTValue("core", "env.state.all", 0); +auto InitBasicPath() -> bool { + auto default_gpgconf_path = Module::RetrieveRTValueTypedOrDefault<>( + "core", "gpgme.ctx.gpgconf_path", QString{}); + + auto default_gnupg_path = Module::RetrieveRTValueTypedOrDefault<>( + "core", "gpgme.ctx.app_path", QString{}); + + LOG_I() << "default gpgconf path found by gpgme: " << default_gpgconf_path; + LOG_I() << "default gnupg path found by gpgme: " << default_gnupg_path; + + auto target_gpgconf_path = DecideGpgConfPath(default_gpgconf_path); + auto target_gnupg_path = default_gnupg_path; + if (target_gpgconf_path != default_gpgconf_path) { + target_gnupg_path = DecideGnuPGPath(target_gpgconf_path); + } + LOG_I() << "gpgconf path used: " << target_gpgconf_path; + LOG_I() << "gnupg path provided by gpgconf: " << target_gnupg_path; - auto gpgconf_install_fs_path = DetectGpgConfPath(); - auto gnupg_install_fs_path = DetectGnuPGPath(gpgconf_install_fs_path); - LOG_I() << "detected gpgconf path: " << gpgconf_install_fs_path; - LOG_I() << "detected gnupg path: " << gnupg_install_fs_path; + if (target_gpgconf_path.isEmpty()) { + LOG_E() << "Cannot find gpgconf!" + << "GpgFrontend cannot start under this situation!"; + CoreSignalStation::GetInstance()->SignalBadGnupgEnv( + QCoreApplication::tr("Cannot Find GpgConf")); + return false; + } - // initialize library gpgme - if (!InitGpgME(gpgconf_install_fs_path, gnupg_install_fs_path)) { + if (target_gnupg_path.isEmpty()) { + LOG_E() << "Cannot find GnuPG by gpgconf!" + << "GpgFrontend cannot start under this situation!"; CoreSignalStation::GetInstance()->SignalBadGnupgEnv( - QCoreApplication::tr("GpgME initiation failed")); - return; + QCoreApplication::tr("Cannot Find GnuPG")); + return false; } + auto default_home_path = Module::RetrieveRTValueTypedOrDefault<>( + "core", "gpgme.ctx.default_database_path", QString{}); + if (default_home_path.trimmed().isEmpty()) { + default_home_path = GetDefaultKeyDatabasePath(target_gpgconf_path); + } + + LOG_I() << "home path provided by gpgconf: " << default_home_path; + if (default_home_path.isEmpty()) { + LOG_E() << "Cannot find default home path by gpgconf!" + << "GpgFrontend cannot start under this situation!"; + CoreSignalStation::GetInstance()->SignalBadGnupgEnv( + QCoreApplication::tr("Cannot Find Home Path")); + return false; + } + + RefreshGpgMEBackendEngine(target_gpgconf_path, target_gnupg_path, + default_home_path); + + Module::UpsertRTValue("core", "gpgme.ctx.gpgconf_path", + QString(target_gpgconf_path)); + Module::UpsertRTValue("core", "gpgme.ctx.app_path", + QString(target_gnupg_path)); + Module::UpsertRTValue("core", "gpgme.ctx.default_database_path", + QString(default_home_path)); + + return true; +} + +auto GetKeyDatabases(QString& default_home_path) -> QList<KeyDatabaseItemSO> { + auto key_db_list_so = SettingsObject("key_database_list"); + auto key_db_list = KeyDatabaseListSO(key_db_list_so); + auto key_dbs = key_db_list.key_databases; + + key_dbs.removeIf( + [default_home_path](const KeyDatabaseItemSO& key_database) -> bool { + return key_database.path == default_home_path; + }); + key_db_list_so.Store(key_db_list.ToJson()); + return key_dbs; +} + +auto InitGpgFrontendCore(CoreInitArgs args) -> int { + // initialize gpgme + if (!InitGpgME()) { + LOG_E() << "Oops, GpgME init failed!" + << "GpgFrontend cannot start under this situation!"; + Module::UpsertRTValue("core", "env.state.gpgme", -1); + CoreSignalStation::GetInstance()->SignalBadGnupgEnv( + QCoreApplication::tr("GpgME Initiation Failed")); + return -1; + } + + Module::UpsertRTValue("core", "env.state.gpgme", 1); + + // decide gpgconf, gnupg and default home path + if (!InitBasicPath()) { + LOG_E() << "Oops, Basic Path init failed!" + << "GpgFrontend cannot start under this situation!"; + return -1; + } + + auto default_gpgconf_path = Module::RetrieveRTValueTypedOrDefault<>( + "core", "gpgme.ctx.gpgconf_path", QString{}); + auto default_gnupg_path = Module::RetrieveRTValueTypedOrDefault<>( + "core", "gpgme.ctx.app_path", QString{}); + auto default_home_path = Module::RetrieveRTValueTypedOrDefault<>( + "core", "gpgme.ctx.default_database_path", QString{}); + auto settings = GlobalSettingStation::GetInstance().GetSettings(); // read settings from config file @@ -313,18 +483,72 @@ void InitGpgFrontendCore(CoreInitArgs args) { auto restart_all_gnupg_components_on_start = settings.value("gnupg/restart_gpg_agent_on_start", false).toBool(); - auto key_database_list = - KeyDatabaseListSO(SettingsObject("key_database_list")); - const auto key_databases = key_database_list.key_databases; + // unit test mode + if (!args.unit_test_mode) { + Module::UpsertRTValue("core", "env.state.basic", 1); + Module::UpsertRTValue("core", "env.state.all", 1); + CoreSignalStation::GetInstance()->SignalGoodGnupgEnv(); + LOG_I() << "Basic ENV Checking Finished"; + return 0; + } + + // load default context + auto& default_ctx = GpgFrontend::GpgContext::CreateInstance( + kGpgFrontendDefaultChannel, [=]() -> ChannelObjectPtr { + GpgFrontend::GpgContextInitArgs args; + + // set key database path + if (!default_home_path.isEmpty()) { + args.db_name = "DEFAULT"; + args.db_path = default_home_path; + } + + 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; + + LOG_D() << "gpgme default context at channel 0, key db name:" + << args.db_name << "key db path:" << args.db_path; + + return ConvertToChannelObjectPtr<>(SecureCreateUniqueObject<GpgContext>( + args, kGpgFrontendDefaultChannel)); + }); + if (!default_ctx.Good()) { + FLOG_E() << "Init GpgME Default Context failed!" + << "GpgFrontend cannot start under this situation!"; + Module::UpsertRTValue("core", "env.state.ctx", -1); + CoreSignalStation::GetInstance()->SignalBadGnupgEnv( + QCoreApplication::tr("GpgME Default Context Initiation Failed")); + return -1; + } + + Module::UpsertRTValue("core", "env.state.ctx", 1); + + if (!GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel).FlushKeyCache()) { + FLOG_E() << "Init GpgME Default Key Database failed!" + << "GpgFrontend cannot start under this situation!"; + Module::UpsertRTValue("core", "env.state.ctx", -1); + CoreSignalStation::GetInstance()->SignalBadGnupgEnv( + QCoreApplication::tr("Gpg Default Key Database Initiation Failed")); + return -1; + }; + + Module::UpsertRTValue("core", "env.state.basic", 1); + CoreSignalStation::GetInstance()->SignalGoodGnupgEnv(); + LOG_I() << "Basic ENV Checking Finished"; + + auto key_dbs = GetKeyDatabases(default_home_path); auto* task = new Thread::Task( [=](const DataObjectPtr&) -> int { // key database path QList<KeyDatabaseItemSO> buffered_key_dbs; + LOG_I() << "AAAAAA"; + // try to use user defined key database - if (!key_databases.empty()) { - for (const auto& key_database : key_databases) { + if (!key_dbs.empty()) { + for (const auto& key_database : key_dbs) { if (VerifyKeyDatabasePath(QFileInfo(key_database.path))) { auto key_database_fs_path = QFileInfo(key_database.path).absoluteFilePath(); @@ -335,109 +559,55 @@ void InitGpgFrontendCore(CoreInitArgs args) { << key_database.path; } } - } else { - QString key_database_fs_path; - -#if defined(__linux__) || (defined(__APPLE__) && defined(__MACH__)) - // use user's home path by default - key_database_fs_path = - SearchKeyDatabasePath({QDir::home().path() + "/.gnupg"}); -#endif - if (key_database_fs_path.isEmpty()) { - key_database_fs_path = Module::RetrieveRTValueTypedOrDefault<>( - "core", "gpgme.ctx.default_database_path", QString{}); - } - - // add the default key database path - if (!key_database_fs_path.isEmpty()) { - auto so = SettingsObject("key_database_list"); - auto key_database_list = KeyDatabaseListSO(so); - - auto key_database = KeyDatabaseItemSO(); - key_database.name = "Default"; - key_database.path = key_database_fs_path; - key_database_list.key_databases.append(key_database); - so.Store(key_database_list.ToJson()); - buffered_key_dbs.append(key_database); - } } - if (args.load_default_gpg_context) { - int channel_index = kGpgFrontendDefaultChannel; - for (const auto& key_db : buffered_key_dbs) { - // init ctx, also checking the basic env - auto& ctx = GpgFrontend::GpgContext::CreateInstance( - channel_index, [=]() -> ChannelObjectPtr { - GpgFrontend::GpgContextInitArgs args; - - // set key database path - if (!key_db.path.isEmpty()) { - args.db_name = key_db.name; - args.db_path = key_db.path; - } - - // set custom gnupg path - if (!gnupg_install_fs_path.isEmpty()) { - args.gpgconf_path = gnupg_install_fs_path; - } - - 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; - - LOG_D() << "new gpgme context, channel" << channel_index - << ", key db name" << args.db_name << "key db path" - << args.db_path << ""; - - return ConvertToChannelObjectPtr<>( - SecureCreateUniqueObject<GpgContext>(args, - channel_index)); - }); - - // exit if failed - if (channel_index == kGpgFrontendDefaultChannel && !ctx.Good()) { - FLOG_W() << "gnupg default context init error, key database: " - << key_db.name << "key database path: " << key_db.path; - CoreSignalStation::GetInstance()->SignalBadGnupgEnv( - QCoreApplication::tr("GpgME Context initiation failed")); - return -1; - } - - FLOG_D() << "gnupg context init success, index" << channel_index - << " key database: " << key_db.name - << "key database path: " << key_db.path; - - channel_index++; + int channel_index = kGpgFrontendDefaultChannel + 1; + for (const auto& key_db : buffered_key_dbs) { + // init ctx, also checking the basic env + auto& ctx = GpgFrontend::GpgContext::CreateInstance( + channel_index, [=]() -> ChannelObjectPtr { + GpgFrontend::GpgContextInitArgs args; + + // set key database path + if (!key_db.path.isEmpty()) { + args.db_name = key_db.name; + args.db_path = key_db.path; + } + + 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; + + LOG_D() << "new gpgme context, channel" << channel_index + << ", key db name" << args.db_name << "key db path" + << args.db_path << ""; + + return ConvertToChannelObjectPtr<>( + SecureCreateUniqueObject<GpgContext>(args, channel_index)); + }); + + if (!ctx.Good()) { + FLOG_E() << "gpgme context init failed, index:" << channel_index; + continue; } - Module::UpsertRTValue("core", "env.state.ctx", 1); - } - if (args.load_default_gpg_context) { - // load keys from all key dbs - for (int channel : GpgContext::GetAllChannelId()) { - if (!GpgKeyGetter::GetInstance(channel).FlushKeyCache()) { - CoreSignalStation::GetInstance()->SignalBadGnupgEnv( - QCoreApplication::tr("Gpg Key Database initiation failed")); - }; + if (!GpgKeyGetter::GetInstance(ctx.GetChannel()).FetchKey()) { + FLOG_E() << "gpgme context init key cache failed, index:" + << channel_index; + continue; } - } - - FLOG_D( - "basic env checking finished, including gpgme, ctx, and key infos"); - Module::UpsertRTValue("core", "env.state.basic", 1); - CoreSignalStation::GetInstance()->SignalGoodGnupgEnv(); - - if (restart_all_gnupg_components_on_start) { - GpgAdvancedOperator::RestartGpgComponents(); + channel_index++; } + Module::UpsertRTValue("core", "env.state.all", 1); + return 0; }, - "core_init_task"); + "core_key_dbs_init_task"); QObject::connect(task, &Thread::Task::SignalTaskEnd, []() { - + LOG_I() << "All Key Database(s) Initialize Finished"; }); // start the thread to check ctx and gnupg state @@ -445,25 +615,34 @@ void InitGpgFrontendCore(CoreInitArgs args) { GpgFrontend::Thread::TaskRunnerGetter::GetInstance() .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Default) ->PostTask(task); + + if (restart_all_gnupg_components_on_start) { + GpgAdvancedOperator::RestartGpgComponents(); + } + return 0; } void StartMonitorCoreInitializationStatus() { auto* task = new Thread::Task( [=](const DataObjectPtr&) -> int { + int core_init_state = Module::RetrieveRTValueTypedOrDefault<>( + "core", "env.state.basic", 0); for (;;) { - if (Module::RetrieveRTValueTypedOrDefault<>("core", "env.state.basic", - 0)) { - break; - } + if (core_init_state != 0) break; + core_init_state = Module::RetrieveRTValueTypedOrDefault<>( + "core", "env.state.basic", 0); LOG_D() << "monitor: core env is still initializing, waiting..."; QThread::msleep(15); } + if (core_init_state < 0) return -1; + // waiting for module first + bool module_init_done = + Module::ModuleManager::GetInstance().IsAllModulesRegistered(); for (;;) { - if (Module::ModuleManager::GetInstance().IsAllModulesRegistered()) - break; + if (module_init_done) break; LOG_D() << "monitor: some modules are still going to be registered, " "waiting..."; @@ -471,16 +650,27 @@ void StartMonitorCoreInitializationStatus() { } LOG_D() << "monitor: good, all module are registered."; + int key_db_init_state = + Module::RetrieveRTValueTypedOrDefault<>("core", "env.state.all", 0); + for (;;) { + if (key_db_init_state != 0) break; + key_db_init_state = Module::RetrieveRTValueTypedOrDefault<>( + "core", "env.state.all", 0); + + LOG_D() << "monitor: key dbs are still initializing, waiting..."; + QThread::msleep(15); + } + LOG_D() << "monitor: good, all key db are loaded."; + LOG_D() << "monitor: core is fully initialized, sending signal to ui..."; - Module::UpsertRTValue("core", "env.state.all", 1); CoreSignalStation::GetInstance()->SignalCoreFullyLoaded(); return 0; }, "waiting_core_init_task"); QObject::connect(task, &Thread::Task::SignalTaskEnd, [=]() { - LOG_D() << "monitor task ended, call back to main thead."; + LOG_D() << "monitor: monitor task ended, call back to main thead."; }); // start the thread to check ctx and gnupg state |