diff options
author | saturneric <[email protected]> | 2025-01-27 15:39:09 +0000 |
---|---|---|
committer | saturneric <[email protected]> | 2025-01-27 15:39:09 +0000 |
commit | af1870fd422fc615a7039b998f505f100e98474a (patch) | |
tree | 5453ac586ce694863ecf438136614d3675b83aca /src | |
parent | feat: allow changing sort options by ui at file page (diff) | |
download | GpgFrontend-af1870fd422fc615a7039b998f505f100e98474a.tar.gz GpgFrontend-af1870fd422fc615a7039b998f505f100e98474a.zip |
fix: kill all gnupg daemons in a proper way
Diffstat (limited to 'src')
-rw-r--r-- | src/GpgFrontendContext.h | 2 | ||||
-rw-r--r-- | src/app.cpp | 23 | ||||
-rw-r--r-- | src/core/GpgConstants.h | 1 | ||||
-rw-r--r-- | src/core/GpgCoreInit.cpp | 68 | ||||
-rw-r--r-- | src/core/function/GlobalSettingStation.cpp | 3 | ||||
-rw-r--r-- | src/core/function/GlobalSettingStation.h | 3 | ||||
-rw-r--r-- | src/core/function/gpg/GpgAdvancedOperator.cpp | 311 | ||||
-rw-r--r-- | src/core/function/gpg/GpgAdvancedOperator.h | 22 | ||||
-rw-r--r-- | src/init.cpp | 28 | ||||
-rw-r--r-- | src/ui/main_window/MainWindow.cpp | 7 | ||||
-rw-r--r-- | src/ui/main_window/MainWindowSlotUI.cpp | 9 | ||||
-rw-r--r-- | src/ui/struct/GpgOperaResult.cpp | 36 | ||||
-rw-r--r-- | src/ui/struct/GpgOperaResult.h | 5 | ||||
-rw-r--r-- | src/ui/struct/GpgOperaResultContext.cpp | 83 | ||||
-rw-r--r-- | src/ui/struct/GpgOperaResultContext.h | 49 |
15 files changed, 384 insertions, 266 deletions
diff --git a/src/GpgFrontendContext.h b/src/GpgFrontendContext.h index ae3177aa..2815caad 100644 --- a/src/GpgFrontendContext.h +++ b/src/GpgFrontendContext.h @@ -46,6 +46,8 @@ struct GpgFrontendContext { bool gather_external_gnupg_info; bool unit_test_mode; + int rtn = GpgFrontend::kCrashCode; + /** * @brief Construct a new Gpg Frontend Context object * diff --git a/src/app.cpp b/src/app.cpp index 0804d64e..6d28ac6b 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -28,8 +28,7 @@ #include "GpgFrontendContext.h" #include "core/GpgConstants.h" -#include "core/GpgCoreInit.h" -#include "core/module/ModuleInit.h" +#include "core/function/CacheManager.h" #include "ui/GpgFrontendUIInit.h" // main @@ -37,8 +36,6 @@ namespace GpgFrontend { -constexpr int kCrashCode = ~0; ///< - /** * @brief * @@ -79,26 +76,18 @@ auto StartApplication(const GFCxtWPtr& p_ctx) -> int { // load module's translations GpgFrontend::UI::InitModulesTranslations(); - - - // finally create main window return_from_event_loop_code = GpgFrontend::UI::RunGpgFrontendUI(app); } while (return_from_event_loop_code == GpgFrontend::kRestartCode && restart_count++ < 99); - // first should shutdown the module system - GpgFrontend::Module::ShutdownGpgFrontendModules(); - - // then shutdown the core - GpgFrontend::DestroyGpgFrontendCore(); + // clear cache of unsaved pages + GpgFrontend::CacheManager::GetInstance().SaveDurableCache( + "editor_unsaved_pages", QJsonDocument(QJsonArray()), true); - // deep restart mode - if (return_from_event_loop_code == GpgFrontend::kDeepRestartCode || - return_from_event_loop_code == kCrashCode) { - QProcess::startDetached(qApp->arguments()[0], qApp->arguments()); - }; + // set return code + ctx->rtn = return_from_event_loop_code; // exit the program return return_from_event_loop_code; diff --git a/src/core/GpgConstants.h b/src/core/GpgConstants.h index 6945b27a..d6632b2a 100644 --- a/src/core/GpgConstants.h +++ b/src/core/GpgConstants.h @@ -33,6 +33,7 @@ namespace GpgFrontend { constexpr int kNonRestartCode = 0; constexpr int kRestartCode = 1000; ///< only refresh ui constexpr int kDeepRestartCode = 1001; // refresh core and ui +constexpr int kCrashCode = ~0; ///< application crash // Channels constexpr int kGpgFrontendDefaultChannel = 0; ///< diff --git a/src/core/GpgCoreInit.cpp b/src/core/GpgCoreInit.cpp index 86d68af4..d6de2240 100644 --- a/src/core/GpgCoreInit.cpp +++ b/src/core/GpgCoreInit.cpp @@ -36,9 +36,7 @@ #include "core/function/gpg/GpgAdvancedOperator.h" #include "core/function/gpg/GpgContext.h" #include "core/function/gpg/GpgKeyGetter.h" -#include "core/model/SettingsObject.h" #include "core/module/ModuleManager.h" -#include "core/struct/settings_object/KeyDatabaseListSO.h" #include "core/thread/Task.h" #include "core/thread/TaskRunnerGetter.h" #include "core/utils/CommonUtils.h" @@ -47,7 +45,13 @@ namespace GpgFrontend { -void DestroyGpgFrontendCore() { SingletonStorageCollection::Destroy(); } +void DestroyGpgFrontendCore() { + // stop all task runner + Thread::TaskRunnerGetter::GetInstance().StopAllTeakRunner(); + + // destroy all singleton objects + SingletonStorageCollection::Destroy(); +} auto VerifyGpgconfPath(const QFileInfo& gnupg_install_fs_path) -> bool { return gnupg_install_fs_path.isAbsolute() && gnupg_install_fs_path.exists() && @@ -260,7 +264,8 @@ auto RefreshGpgMEBackendEngine(const QString& gpgconf_path, return true; } -auto GetGnuPGPathByGpgConf(const QString& gpgconf_install_fs_path) -> QString { +auto GetComponentPathsByGpgConf(const QString& gpgconf_install_fs_path) + -> bool { auto* process = new QProcess(QCoreApplication::instance()); process->setProgram(gpgconf_install_fs_path); process->start(); @@ -268,7 +273,7 @@ auto GetGnuPGPathByGpgConf(const QString& gpgconf_install_fs_path) -> QString { auto output_buffer = process->readAllStandardOutput(); process->deleteLater(); - if (output_buffer.isEmpty()) return {}; + if (output_buffer.isEmpty()) return false; auto line_split_list = QString(output_buffer).split("\n"); for (const auto& line : line_split_list) { @@ -276,23 +281,26 @@ auto GetGnuPGPathByGpgConf(const QString& gpgconf_install_fs_path) -> QString { if (info_split_list.size() != 3) continue; - auto component_name = info_split_list[0].trimmed(); + auto component_name = info_split_list[0].trimmed().toLower(); auto component_desc = info_split_list[1].trimmed(); auto component_path = info_split_list[2].trimmed(); - if (component_name.toLower() == "gpg") { #if defined(_WIN32) || defined(WIN32) - // replace some special substrings on windows platform - component_path.replace("%3a", ":"); + // replace some special substrings on windows platform + component_path.replace("%3a", ":"); #endif - QFileInfo file_info(component_path); - if (file_info.exists() && file_info.isFile()) { - return file_info.absoluteFilePath(); - } - return {}; - } + + QFileInfo file_info(component_path); + if (!file_info.exists() || !file_info.isFile()) continue; + + Module::UpsertRTValue("core", "gnupg.component.paths." + component_name, + file_info.absoluteFilePath()); + + LOG_D() << "gpg components: " << component_name + << "path: " << file_info.absoluteFilePath(); } - return ""; + + return true; } auto DecideGpgConfPath(const QString& default_gpgconf_path) -> QString { @@ -349,8 +357,15 @@ auto DecideGpgConfPath(const QString& default_gpgconf_path) -> QString { return ""; } -auto DecideGnuPGPath(const QString& gpgconf_path) -> QString { - return GetGnuPGPathByGpgConf(gpgconf_path); +auto DecideGnuPGPath(const QString& default_gnupg_path) -> QString { + QFileInfo info(default_gnupg_path); + + if (default_gnupg_path.isEmpty() || !info.exists() || !info.isFile()) { + return Module::RetrieveRTValueTypedOrDefault<>( + "core", "gnupg.component.paths.gpg", QString{}); + } + + return default_gnupg_path; } auto InitBasicPath() -> bool { @@ -364,12 +379,23 @@ auto InitBasicPath() -> bool { LOG_I() << "default gnupg path found by gpgme: " << default_gnupg_path; auto target_gpgconf_path = DecideGpgConfPath(default_gpgconf_path); + + if (!GetComponentPathsByGpgConf(default_gpgconf_path)) { + LOG_E() << "Cannot get components paths by gpgconf!" + << "GpgFrontend cannot start under this situation!"; + CoreSignalStation::GetInstance()->SignalBadGnupgEnv( + QCoreApplication::tr("Cannot get Infos from GpgConf")); + return false; + } + auto target_gnupg_path = default_gnupg_path; + if (target_gpgconf_path != default_gpgconf_path) { - target_gnupg_path = DecideGnuPGPath(target_gpgconf_path); + target_gnupg_path = DecideGnuPGPath(target_gnupg_path); } + LOG_I() << "gpgconf path used: " << target_gpgconf_path; - LOG_I() << "gnupg path provided by gpgconf: " << target_gnupg_path; + LOG_I() << "gnupg path used: " << target_gnupg_path; if (target_gpgconf_path.isEmpty()) { LOG_E() << "Cannot find gpgconf!" @@ -577,7 +603,7 @@ auto InitGpgFrontendCore(CoreInitArgs args) -> int { ->PostTask(task); if (!args.unit_test_mode && restart_all_gnupg_components_on_start) { - GpgAdvancedOperator::RestartGpgComponents(); + GpgAdvancedOperator::RestartGpgComponents(nullptr); } return 0; } diff --git a/src/core/function/GlobalSettingStation.cpp b/src/core/function/GlobalSettingStation.cpp index 5c6149df..62b24331 100644 --- a/src/core/function/GlobalSettingStation.cpp +++ b/src/core/function/GlobalSettingStation.cpp @@ -256,4 +256,7 @@ auto GlobalSettingStation::GetIntegratedModulePath() const -> QString { auto GlobalSettingStation::IsProtableMode() const -> bool { return p_->IsProtableMode(); } +auto GetSettings() -> QSettings { + return GlobalSettingStation::GetInstance().GetSettings(); +} } // namespace GpgFrontend
\ No newline at end of file diff --git a/src/core/function/GlobalSettingStation.h b/src/core/function/GlobalSettingStation.h index b7670b95..9ef29792 100644 --- a/src/core/function/GlobalSettingStation.h +++ b/src/core/function/GlobalSettingStation.h @@ -143,4 +143,7 @@ class GPGFRONTEND_CORE_EXPORT GlobalSettingStation class Impl; SecureUniquePtr<Impl> p_; }; + +auto GPGFRONTEND_CORE_EXPORT GetSettings() -> QSettings; + } // namespace GpgFrontend diff --git a/src/core/function/gpg/GpgAdvancedOperator.cpp b/src/core/function/gpg/GpgAdvancedOperator.cpp index 6b56d867..b310df85 100644 --- a/src/core/function/gpg/GpgAdvancedOperator.cpp +++ b/src/core/function/gpg/GpgAdvancedOperator.cpp @@ -34,6 +34,7 @@ #include "core/function/gpg/GpgCommandExecutor.h" #include "core/module/ModuleManager.h" +#include "core/utils/GpgUtils.h" void GpgFrontend::GpgAdvancedOperator::ClearGpgPasswordCache( OperationCallback cb) { @@ -42,21 +43,40 @@ void GpgFrontend::GpgAdvancedOperator::ClearGpgPasswordCache( if (gpgconf_path.isEmpty()) { FLOG_W("cannot get valid gpgconf path from rt, abort."); - cb(-1, TransferParams()); + if (cb) cb(-1, TransferParams()); return; } -#if defined(__APPLE__) && defined(__MACH__) - FLOG_I("kill all gpg components in order to clear gpg password cache"); - KillAllGpgComponents(); -#else - GpgFrontend::GpgCommandExecutor::ExecuteSync( - {gpgconf_path, QStringList{"--reload", "gpg-agent"}, - [=](int exit_code, const QString & /*p_out*/, - const QString & /*p_err*/) { - cb(exit_code == 0 ? 0 : -1, TransferParams()); - }}); -#endif + auto key_dbs = GetGpgKeyDatabaseInfos(); + auto total_tasks = static_cast<int>(key_dbs.size()); + std::atomic<int> completed_tasks{0}; + std::vector<int> results(total_tasks, 0); + + int task_index = 0; + for (const auto &key_db : key_dbs) { + const int current_index = task_index++; + const auto target_home_dir = + QDir::toNativeSeparators(QFileInfo(key_db.path).canonicalFilePath()); + + GpgFrontend::GpgCommandExecutor::ExecuteSync( + {gpgconf_path, + QStringList{"--homedir", target_home_dir, "--reload", "gpg-agent"}, + [=, &completed_tasks, &results](int exit_code, const QString &, + const QString &) { + FLOG_D("gpgconf reload exit code: %d", exit_code); + + results[current_index] = exit_code; + + if (++completed_tasks == total_tasks && cb) { + int final_result = + std::all_of(results.begin(), results.end(), + [](int result) { return result >= 0; }) + ? 0 + : -1; + cb(final_result, TransferParams()); + } + }}); + } } void GpgFrontend::GpgAdvancedOperator::ReloadGpgComponents( @@ -66,83 +86,99 @@ void GpgFrontend::GpgAdvancedOperator::ReloadGpgComponents( if (gpgconf_path.isEmpty()) { FLOG_W("cannot get valid gpgconf path from rt, abort."); - cb(-1, TransferParams()); + if (cb) cb(-1, TransferParams()); return; } - GpgFrontend::GpgCommandExecutor::ExecuteSync( - {gpgconf_path, QStringList{"--reload"}, - [=](int exit_code, const QString &, const QString &) { - FLOG_D("gpgconf reload exit code: %d", exit_code); - cb(exit_code == 0 ? 0 : -1, TransferParams()); - }}); + auto key_dbs = GetGpgKeyDatabaseInfos(); + auto total_tasks = static_cast<int>(key_dbs.size()); + std::atomic<int> completed_tasks{0}; + std::vector<int> results(total_tasks, 0); + + int task_index = 0; + for (const auto &key_db : key_dbs) { + const int current_index = task_index++; + const auto target_home_dir = + QDir::toNativeSeparators(QFileInfo(key_db.path).canonicalFilePath()); + + GpgFrontend::GpgCommandExecutor::ExecuteSync( + {gpgconf_path, + QStringList{"--homedir", target_home_dir, "--reload", "all"}, + [=, &completed_tasks, &results](int exit_code, const QString &, + const QString &) { + FLOG_D("gpgconf reload exit code: %d", exit_code); + results[current_index] = exit_code; + + if (++completed_tasks == total_tasks && cb) { + int final_result = + std::all_of(results.begin(), results.end(), + [](int result) { return result >= 0; }) + ? 0 + : -1; + cb(final_result, TransferParams()); + } + }}); + } } -void GpgFrontend::GpgAdvancedOperator::KillAllGpgComponents() { +void GpgFrontend::GpgAdvancedOperator::KillAllGpgComponents( + OperationCallback cb) { const auto gpgconf_path = Module::RetrieveRTValueTypedOrDefault<>( "core", "gpgme.ctx.gpgconf_path", QString{}); if (gpgconf_path.isEmpty()) { FLOG_W("cannot get valid gpgconf path from rt, abort."); + if (cb) cb(-1, TransferParams()); return; } - GpgFrontend::GpgCommandExecutor::ExecuteSync( - {gpgconf_path, QStringList{"--verbose", "--kill", "all"}, - [=](int exit_code, const QString &p_out, const QString &p_err) { - bool success = true; - if (exit_code != 0) { - success = false; - LOG_W() << "gpgconf execute error, process stderr: " << p_err - << ", process stdout: " << p_out; - return; - } - - FLOG_D("gpgconf --kill --all execute result: %d", success); - }}); + auto key_dbs = GetGpgKeyDatabaseInfos(); + auto total_tasks = static_cast<int>(key_dbs.size()); + std::atomic<int> completed_tasks{0}; + std::vector<int> results(total_tasks, 0); + + int task_index = 0; + for (const auto &key_db : key_dbs) { + const int current_index = task_index++; + const auto target_home_dir = + QDir::toNativeSeparators(QFileInfo(key_db.path).canonicalFilePath()); + + LOG_D() << "closing all gpg component at home path: " << target_home_dir; + GpgFrontend::GpgCommandExecutor::ExecuteSync( + {gpgconf_path, + QStringList{"--homedir", target_home_dir, "--kill", "all"}, + [=, &completed_tasks, &results](int exit_code, const QString &p_out, + const QString &p_err) { + FLOG_D("gpgconf --kill --all exit code: %d", exit_code); + + results[current_index] = exit_code; + + if (++completed_tasks == total_tasks && cb) { + int final_result = + std::all_of(results.begin(), results.end(), + [](int result) { return result >= 0; }) + ? 0 + : -1; + cb(final_result, TransferParams()); + } + }}); + } } -void GpgFrontend::GpgAdvancedOperator::RestartGpgComponents() { +void GpgFrontend::GpgAdvancedOperator::RestartGpgComponents( + OperationCallback cb) { const auto gpgconf_path = Module::RetrieveRTValueTypedOrDefault<>( "core", "gpgme.ctx.gpgconf_path", QString{}); if (gpgconf_path.isEmpty()) { FLOG_W("cannot get valid gpgconf path from rt, abort."); + if (cb) cb(-1, TransferParams()); return; } - GpgFrontend::GpgCommandExecutor::ExecuteSync( - {gpgconf_path, QStringList{"--verbose", "--kill", "all"}, - [=](int exit_code, const QString &p_out, const QString &p_err) { - FLOG_D("gpgconf --kill all command got exit code: %d", exit_code); - bool success = true; - if (exit_code != 0) { - success = false; - LOG_W() << "gpgconf execute error, process stderr: " << p_err - << ", process stdout: " << p_out; - return; - } - - FLOG_D("gpgconf --kill --all execute result: %d", success); - if (!success) { - FLOG_W("restart all component after core initalized failed"); - Module::UpsertRTValue( - "core", "gpg_advanced_operator.restart_gpg_components", false); - return; - } - -#if defined(__APPLE__) && defined(__MACH__) - FLOG_I("getting gpg-agent to start automatically on macOS"); -#else - StartGpgAgent([](int err, DataObjectPtr) { - if (err >= 0) { - Module::UpsertRTValue( - "core", "gpg_advanced_operator.restart_gpg_components", true); - return; - } - }); -#endif - }}); + KillAllGpgComponents(nullptr); + + LaunchGpgComponents(cb); } void GpgFrontend::GpgAdvancedOperator::ResetConfigures(OperationCallback cb) { @@ -151,92 +187,81 @@ void GpgFrontend::GpgAdvancedOperator::ResetConfigures(OperationCallback cb) { if (gpgconf_path.isEmpty()) { FLOG_W("cannot get valid gpgconf path from rt, abort."); - cb(-1, TransferParams()); + if (cb) cb(-1, TransferParams()); return; } - GpgFrontend::GpgCommandExecutor::ExecuteSync( - {gpgconf_path, QStringList{"--apply-defaults"}, - [=](int exit_code, const QString &, const QString &) { - FLOG_D("gpgconf apply-defaults exit code: %d", exit_code); - cb(exit_code == 0 ? 0 : -1, TransferParams()); - }}); -} - -void GpgFrontend::GpgAdvancedOperator::StartGpgAgent(OperationCallback cb) { - if (!Module::IsModuleActivate(kGnuPGInfoGatheringModuleID)) { - cb(-1, TransferParams()); - return; - } - - const auto gpg_agent_path = Module::RetrieveRTValueTypedOrDefault<>( - kGnuPGInfoGatheringModuleID, "gnupg.gpg_agent_path", QString{}); - - const auto home_path = Module::RetrieveRTValueTypedOrDefault<>( - kGnuPGInfoGatheringModuleID, "gnupg.home_path", QString{}); - - if (gpg_agent_path.isEmpty()) { - FLOG_W("cannot get valid gpg agent path from rt, abort."); - cb(-1, TransferParams()); - return; + auto key_dbs = GetGpgKeyDatabaseInfos(); + auto total_tasks = static_cast<int>(key_dbs.size()); + std::atomic<int> completed_tasks{0}; + std::vector<int> results(total_tasks, 0); + + int task_index = 0; + for (const auto &key_db : key_dbs) { + const int current_index = task_index++; + const auto target_home_dir = + QDir::toNativeSeparators(QFileInfo(key_db.path).canonicalFilePath()); + + GpgFrontend::GpgCommandExecutor::ExecuteSync( + {gpgconf_path, + QStringList{"--homedir", target_home_dir, "--apply-defaults"}, + [=, &completed_tasks, &results](int exit_code, const QString &, + const QString &) { + FLOG_D("gpgconf --apply-defaults exit code: %d", exit_code); + + results[current_index] = exit_code; + + if (++completed_tasks == total_tasks && cb) { + int final_result = + std::all_of(results.begin(), results.end(), + [](int result) { return result >= 0; }) + ? 0 + : -1; + cb(final_result, TransferParams()); + } + }}); } - - GpgFrontend::GpgCommandExecutor::ExecuteSync( - {gpg_agent_path, QStringList{"--homedir", home_path, "--daemon"}, - [=](int exit_code, const QString &, const QString &) { - FLOG_D("gpg-agent daemon exit code: %d", exit_code); - cb(exit_code >= 0 ? 0 : -1, TransferParams()); - }}); } -void GpgFrontend::GpgAdvancedOperator::StartDirmngr(OperationCallback cb) { - if (!Module::IsModuleActivate(kGnuPGInfoGatheringModuleID)) { - cb(-1, TransferParams()); - return; - } - - const auto dirmngr_path = Module::RetrieveRTValueTypedOrDefault<>( - kGnuPGInfoGatheringModuleID, "gnupg.dirmngr_path", QString{}); - - const auto home_path = Module::RetrieveRTValueTypedOrDefault<>( - kGnuPGInfoGatheringModuleID, "gnupg.home_path", QString{}); - - if (dirmngr_path.isEmpty()) { - FLOG_W("cannot get valid dirmngr path from rt, abort."); - cb(-1, TransferParams()); - return; - } - - GpgFrontend::GpgCommandExecutor::ExecuteSync( - {dirmngr_path, QStringList{"--homedir", home_path, "--daemon"}, - [=](int exit_code, const QString &, const QString &) { - FLOG_D("gpgconf daemon exit code: %d", exit_code); - cb(exit_code >= 0 ? 0 : -1, TransferParams()); - }}); -} +void GpgFrontend::GpgAdvancedOperator::LaunchGpgComponents( + OperationCallback cb) { + const auto gpgconf_path = Module::RetrieveRTValueTypedOrDefault<>( + "core", "gpgme.ctx.gpgconf_path", QString{}); -void GpgFrontend::GpgAdvancedOperator::StartKeyBoxd(OperationCallback cb) { - if (!Module::IsModuleActivate(kGnuPGInfoGatheringModuleID)) { - cb(-1, TransferParams()); + if (gpgconf_path.isEmpty()) { + FLOG_W("cannot get valid gpgconf path from rt, abort."); + if (cb) cb(-1, TransferParams()); return; } - const auto keyboxd_path = Module::RetrieveRTValueTypedOrDefault<>( - kGnuPGInfoGatheringModuleID, "gnupg.keyboxd_path", QString{}); - - const auto home_path = Module::RetrieveRTValueTypedOrDefault<>( - kGnuPGInfoGatheringModuleID, "gnupg.home_path", QString{}); - - if (keyboxd_path.isEmpty()) { - FLOG_W("cannot get valid keyboxd path from rt, abort."); - cb(-1, TransferParams()); - return; + auto key_dbs = GetGpgKeyDatabaseInfos(); + auto total_tasks = static_cast<int>(key_dbs.size()); + std::atomic<int> completed_tasks{0}; + std::vector<int> results(total_tasks, 0); + + int task_index = 0; + for (const auto &key_db : key_dbs) { + const int current_index = task_index++; + const auto target_home_dir = + QDir::toNativeSeparators(QFileInfo(key_db.path).canonicalFilePath()); + + GpgFrontend::GpgCommandExecutor::ExecuteSync( + {gpgconf_path, + QStringList{"--homedir", target_home_dir, "--launch", "all"}, + [=, &completed_tasks, &results](int exit_code, const QString &, + const QString &) { + FLOG_D("gpgconf --launch all exit code: %d", exit_code); + + results[current_index] = exit_code; + + if (++completed_tasks == total_tasks && cb) { + int final_result = + std::all_of(results.begin(), results.end(), + [](int result) { return result >= 0; }) + ? 0 + : -1; + cb(final_result, TransferParams()); + } + }}); } - - GpgFrontend::GpgCommandExecutor::ExecuteSync( - {keyboxd_path, QStringList{"--homedir", home_path, "--daemon"}, - [=](int exit_code, const QString &, const QString &) { - FLOG_D("gpgconf daemon exit code: %d", exit_code); - cb(exit_code >= 0 ? 0 : -1, TransferParams()); - }}); } diff --git a/src/core/function/gpg/GpgAdvancedOperator.h b/src/core/function/gpg/GpgAdvancedOperator.h index 1be2c2e4..cfd5fbcf 100644 --- a/src/core/function/gpg/GpgAdvancedOperator.h +++ b/src/core/function/gpg/GpgAdvancedOperator.h @@ -60,7 +60,7 @@ class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator { * @return true * @return false */ - static void RestartGpgComponents(); + static void RestartGpgComponents(OperationCallback); /** * @brief @@ -76,29 +76,13 @@ class GPGFRONTEND_CORE_EXPORT GpgAdvancedOperator { * @return true * @return false */ - static void StartGpgAgent(OperationCallback); - - /** - * @brief - * - * @return true - * @return false - */ - static void StartDirmngr(OperationCallback); - - /** - * @brief - * - * @return true - * @return false - */ - static void StartKeyBoxd(OperationCallback); + static void LaunchGpgComponents(OperationCallback); /** * @brief * */ - static void KillAllGpgComponents(); + static void KillAllGpgComponents(OperationCallback); }; } // namespace GpgFrontend diff --git a/src/init.cpp b/src/init.cpp index e1668ec5..54745d65 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -184,18 +184,30 @@ void ShutdownGlobalBasicEnv(const GFCxtWPtr &p_ctx) { } auto clear_gpg_password_cache = - GlobalSettingStation::GetInstance() - .GetSettings() - .value("basic/clear_gpg_password_cache", false) + GetSettings().value("basic/clear_gpg_password_cache", false).toBool(); + + auto kill_all_gnupg_daemon_at_close = + GetSettings() + .value("gnupg/kill_all_gnupg_daemon_at_close", false) .toBool(); - // clear password cache - if (!ctx->unit_test_mode && clear_gpg_password_cache) { - GpgAdvancedOperator::ClearGpgPasswordCache([](int, DataObjectPtr) {}); + + if (!ctx->unit_test_mode && kill_all_gnupg_daemon_at_close) { + GpgAdvancedOperator::KillAllGpgComponents(nullptr); + } else if (!ctx->unit_test_mode && clear_gpg_password_cache) { + GpgAdvancedOperator::ClearGpgPasswordCache(nullptr); } - Thread::TaskRunnerGetter::GetInstance().StopAllTeakRunner(); + // first should shutdown the module system + GpgFrontend::Module::ShutdownGpgFrontendModules(); + + // then shutdown the core + GpgFrontend::DestroyGpgFrontendCore(); - DestroyGpgFrontendCore(); + // deep restart mode + if (ctx->rtn == GpgFrontend::kDeepRestartCode || + ctx->rtn == GpgFrontend::kCrashCode) { + QProcess::startDetached(qApp->arguments()[0], qApp->arguments()); + }; } } // namespace GpgFrontend diff --git a/src/ui/main_window/MainWindow.cpp b/src/ui/main_window/MainWindow.cpp index 4817cbcd..b32d9c94 100644 --- a/src/ui/main_window/MainWindow.cpp +++ b/src/ui/main_window/MainWindow.cpp @@ -30,11 +30,12 @@ #include "core/function/CacheManager.h" #include "core/function/GlobalSettingStation.h" +#include "core/function/gpg/GpgAdvancedOperator.h" #include "core/model/SettingsObject.h" #include "core/module/ModuleManager.h" -#include "struct/settings_object/AppearanceSO.h" #include "ui/UISignalStation.h" #include "ui/main_window/GeneralMainWindow.h" +#include "ui/struct/settings_object/AppearanceSO.h" #include "ui/struct/settings_object/KeyServerSO.h" #include "ui/widgets/KeyList.h" #include "ui/widgets/TextEdit.h" @@ -274,10 +275,6 @@ void MainWindow::closeEvent(QCloseEvent* event) { } if (event->isAccepted()) { - // clear cache of unsaved page - CacheManager::GetInstance().SaveDurableCache( - "editor_unsaved_pages", QJsonDocument(QJsonArray()), true); - // call parent GeneralMainWindow::closeEvent(event); } diff --git a/src/ui/main_window/MainWindowSlotUI.cpp b/src/ui/main_window/MainWindowSlotUI.cpp index dc282c64..7ce0024e 100644 --- a/src/ui/main_window/MainWindowSlotUI.cpp +++ b/src/ui/main_window/MainWindowSlotUI.cpp @@ -330,12 +330,9 @@ void MainWindow::slot_reload_gpg_components(bool) { } void MainWindow::slot_restart_gpg_components(bool) { - GpgFrontend::GpgAdvancedOperator::RestartGpgComponents(); - Module::ListenRTPublishEvent( - this, "core", "gpg_advanced_operator.restart_gpg_components", - [=](Module::Namespace, Module::Key, int, std::any value) { - bool success_state = std::any_cast<bool>(value); - if (success_state) { + GpgFrontend::GpgAdvancedOperator::RestartGpgComponents( + [=](int err, DataObjectPtr) { + if (err >= 0) { QMessageBox::information( this, tr("Successful Operation"), tr("Restart all the GnuPG's components successfully")); diff --git a/src/ui/struct/GpgOperaResult.cpp b/src/ui/struct/GpgOperaResult.cpp new file mode 100644 index 00000000..9d612cc3 --- /dev/null +++ b/src/ui/struct/GpgOperaResult.cpp @@ -0,0 +1,36 @@ +/** + * Copyright (C) 2021-2024 Saturneric <[email protected]> + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric <[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "GpgOperaResult.h" + +namespace GpgFrontend::UI { + +GpgOperaResult::GpgOperaResult(int status, QString report, QString tag) + : status(status), report(std::move(report)), tag(std::move(tag)) {} + +} // namespace GpgFrontend::UI
\ No newline at end of file diff --git a/src/ui/struct/GpgOperaResult.h b/src/ui/struct/GpgOperaResult.h index e3bfd61a..7ee6ad37 100644 --- a/src/ui/struct/GpgOperaResult.h +++ b/src/ui/struct/GpgOperaResult.h @@ -1,5 +1,3 @@ -#include <utility> - /** * Copyright (C) 2021-2024 Saturneric <[email protected]> * @@ -37,8 +35,7 @@ struct GpgOperaResult { QString report; QString tag; - GpgOperaResult(int status, QString report, QString tag) - : status(status), report(std::move(report)), tag(std::move(tag)) {} + GpgOperaResult(int status, QString report, QString tag); }; } // namespace GpgFrontend::UI
\ No newline at end of file diff --git a/src/ui/struct/GpgOperaResultContext.cpp b/src/ui/struct/GpgOperaResultContext.cpp new file mode 100644 index 00000000..c36d0ec6 --- /dev/null +++ b/src/ui/struct/GpgOperaResultContext.cpp @@ -0,0 +1,83 @@ +/** + * Copyright (C) 2021-2024 Saturneric <[email protected]> + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric <[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "GpgOperaResultContext.h" + +namespace GpgFrontend::UI { + +GpgOperaContext::GpgOperaContext(QContainer<OperaWaitingCb>& operas, + QContainer<GpgOperaResult>& opera_results, + GpgKeyList& keys, GpgKeyList& singer_keys, + QStringList& unknown_fprs) + : operas(operas), + opera_results(opera_results), + keys(keys), + singer_keys(singer_keys), + unknown_fprs(unknown_fprs) {} + +auto GpgOperaContexts::GetContextPath(int category) -> QStringList& { + if (!categories.contains(category)) categories[category] = {}; + return categories[category].paths; +} + +auto GpgOperaContexts::GetContextOutPath(int category) -> QStringList& { + if (!categories.contains(category)) categories[category] = {}; + return categories[category].o_paths; +} + +auto GpgOperaContexts::GetAllPath() -> QStringList { + QStringList res; + + for (auto& category : categories) { + res.append(category.paths); + } + return res; +} + +auto GpgOperaContexts::GetAllOutPath() -> QStringList { + QStringList res; + + for (auto& category : categories) { + res.append(category.o_paths); + } + return res; +} + +auto GpgOperaContexts::GetContext(int category) + -> QSharedPointer<GpgOperaContext> { + if (GetContextPath(category).empty()) return nullptr; + + auto context = QSharedPointer<GpgOperaContext>::create( + operas, opera_results, keys, singer_keys, unknown_fprs); + context->ascii = ascii; + + context->paths = GetContextPath(category); + context->o_paths = GetContextOutPath(category); + return context; +} +} // namespace GpgFrontend::UI
\ No newline at end of file diff --git a/src/ui/struct/GpgOperaResultContext.h b/src/ui/struct/GpgOperaResultContext.h index ca68dde1..be245bad 100644 --- a/src/ui/struct/GpgOperaResultContext.h +++ b/src/ui/struct/GpgOperaResultContext.h @@ -1,5 +1,3 @@ -#include <utility> - /** * Copyright (C) 2021-2024 Saturneric <[email protected]> * @@ -53,12 +51,7 @@ struct GpgOperaContext { GpgOperaContext(QContainer<OperaWaitingCb>& operas, QContainer<GpgOperaResult>& opera_results, GpgKeyList& keys, - GpgKeyList& singer_keys, QStringList& unknown_fprs) - : operas(operas), - opera_results(opera_results), - keys(keys), - singer_keys(singer_keys), - unknown_fprs(unknown_fprs) {} + GpgKeyList& singer_keys, QStringList& unknown_fprs); }; struct GpgOperaContexts { @@ -71,45 +64,15 @@ struct GpgOperaContexts { QMap<int, GpgOperaCategory> categories; - auto GetContextPath(int category) -> QStringList& { - if (!categories.contains(category)) categories[category] = {}; - return categories[category].paths; - } - - auto GetContextOutPath(int category) -> QStringList& { - if (!categories.contains(category)) categories[category] = {}; - return categories[category].o_paths; - } - - auto GetAllPath() -> QStringList { - QStringList res; - - for (auto& category : categories) { - res.append(category.paths); - } - return res; - } - - auto GetAllOutPath() -> QStringList { - QStringList res; + auto GetContextPath(int category) -> QStringList&; - for (auto& category : categories) { - res.append(category.o_paths); - } - return res; - } + auto GetContextOutPath(int category) -> QStringList&; - auto GetContext(int category) -> QSharedPointer<GpgOperaContext> { - if (GetContextPath(category).empty()) return nullptr; + auto GetAllPath() -> QStringList; - auto context = QSharedPointer<GpgOperaContext>::create( - operas, opera_results, keys, singer_keys, unknown_fprs); - context->ascii = ascii; + auto GetAllOutPath() -> QStringList; - context->paths = GetContextPath(category); - context->o_paths = GetContextOutPath(category); - return context; - } + auto GetContext(int category) -> QSharedPointer<GpgOperaContext>; }; } // namespace GpgFrontend::UI
\ No newline at end of file |