diff options
author | saturneric <[email protected]> | 2024-07-12 18:39:17 +0000 |
---|---|---|
committer | saturneric <[email protected]> | 2024-07-12 18:39:17 +0000 |
commit | 96e4c85edc09e106631860f823a42440d013e455 (patch) | |
tree | fd69604b607da4f7d9a9d51503ef5fc64ed75f89 /src/m_gpg_info | |
parent | feat: initialize and move in two modules (diff) | |
download | Modules-96e4c85edc09e106631860f823a42440d013e455.tar.gz Modules-96e4c85edc09e106631860f823a42440d013e455.zip |
feat: try using ui and i18n apis from sdk
Diffstat (limited to 'src/m_gpg_info')
-rw-r--r-- | src/m_gpg_info/CMakeLists.txt | 56 | ||||
-rw-r--r-- | src/m_gpg_info/GnuPGInfoGatheringModule.cpp | 526 | ||||
-rw-r--r-- | src/m_gpg_info/GnuPGInfoGatheringModule.h | 56 | ||||
-rw-r--r-- | src/m_gpg_info/GpgInfo.cpp | 79 | ||||
-rw-r--r-- | src/m_gpg_info/GpgInfo.h | 88 | ||||
-rw-r--r-- | src/m_gpg_info/QtLoggerFmt.h | 68 |
6 files changed, 873 insertions, 0 deletions
diff --git a/src/m_gpg_info/CMakeLists.txt b/src/m_gpg_info/CMakeLists.txt new file mode 100644 index 0000000..1d96a5a --- /dev/null +++ b/src/m_gpg_info/CMakeLists.txt @@ -0,0 +1,56 @@ +# Copyright (C) 2021 Saturneric <[email protected]> +# +# This file is part of GpgFrontend. +# +# GpgFrontend is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GpgFrontend is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. +# +# The initial version of the source code is inherited from +# the gpg4usb project, which is under GPL-3.0-or-later. +# +# All the source code of GpgFrontend was modified and released by +# Saturneric <[email protected]> starting on May 12, 2021. +# +# SPDX-License-Identifier: GPL-3.0-or-later + +# com.bktus.gpgfrontend.module.integrated.gnupg_info_gathering + +aux_source_directory(. INTEGRATED_MODULE_SOURCE) + +# define libgpgfrontend_module +add_library(mod_gpg_info SHARED ${INTEGRATED_MODULE_SOURCE}) + +target_include_directories(mod_gpg_info PRIVATE + ${CMAKE_SOURCE_DIR}/third_party/spdlog/include) + +# install dir +install(TARGETS mod_gpg_info + LIBRARY DESTINATION "${CMAKE_INSTALL_PREFIX}/modules") + +# link sdk +target_link_libraries(mod_gpg_info PRIVATE + gpgfrontend_module_sdk) + +if(GPGFRONTEND_QT5_BUILD) + # link Qt core + target_link_libraries(mod_gpg_info PRIVATE Qt5::Core) +else() + # link Qt core + target_link_libraries(mod_gpg_info PRIVATE Qt6::Core) +endif() + +# using std c++ 17 +target_compile_features(mod_gpg_info PRIVATE cxx_std_17) + +# ui +set(CMAKE_AUTOUIC_SEARCH_PATHS ${CMAKE_AUTOUIC_SEARCH_PATHS} ${CMAKE_CURRENT_SOURCE_DIR}/ui)
\ No newline at end of file diff --git a/src/m_gpg_info/GnuPGInfoGatheringModule.cpp b/src/m_gpg_info/GnuPGInfoGatheringModule.cpp new file mode 100644 index 0000000..8d400c8 --- /dev/null +++ b/src/m_gpg_info/GnuPGInfoGatheringModule.cpp @@ -0,0 +1,526 @@ +/** + * Copyright (C) 2021 Saturneric <[email protected]> + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric <[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "GnuPGInfoGatheringModule.h" + +#include <GFSDKBasic.h> +#include <GFSDKBuildInfo.h> +#include <GFSDKLog.h> +#include <spdlog/spdlog.h> + +// qt +#include <QCryptographicHash> +#include <QFileInfo> +#include <QJsonDocument> +#include <QString> + +// c++ +#include <optional> + +#include "GpgInfo.h" + +template <> +struct fmt::formatter<QString> { + // Parses format specifications. + constexpr auto parse(format_parse_context &ctx) -> decltype(ctx.begin()) { + return ctx.begin(); + } + + // Formats the QString qstr and writes it to the output. + template <typename FormatContext> + auto format(const QString &qstr, FormatContext &ctx) const + -> decltype(ctx.out()) { + // Convert QString to UTF-8 QString (to handle Unicode characters + // correctly) + QByteArray utf8_array = qstr.toUtf8(); + return fmt::format_to(ctx.out(), "{}", utf8_array.constData()); + } +}; + +template <> +struct fmt::formatter<QByteArray> { + // Parses format specifications. + constexpr auto parse(format_parse_context &ctx) -> decltype(ctx.begin()) { + return ctx.begin(); + } + + // Formats the QString qstr and writes it to the output. + template <typename FormatContext> + auto format(const QByteArray &qarray, FormatContext &ctx) const + -> decltype(ctx.out()) { + // Convert QString to UTF-8 QString (to handle Unicode characters + // correctly) + return fmt::format_to(ctx.out(), "{}", qarray.constData()); + } +}; + +extern auto CalculateBinaryChacksum(const QString &path) + -> std::optional<QString>; + +extern void GetGpgComponentInfos(void *, int, const char *, const char *); + +extern void GetGpgDirectoryInfos(void *, int, const char *, const char *); + +extern void GetGpgOptionInfos(void *, int, const char *, const char *); + +using Context = struct { + QString gpgme_version; + QString gpgconf_path; + GpgComponentInfo component_info; +}; + +auto GFGetModuleGFSDKVersion() -> const char * { + return GFModuleStrDup(GF_SDK_VERSION_STR); +} + +auto GFGetModuleQtEnvVersion() -> const char * { + return GFModuleStrDup(QT_VERSION_STR); +} + +auto GFGetModuleID() -> const char * { + return GFModuleStrDup("com.bktus.gpgfrontend.module.gnupg_info_gathering"); +} + +auto GFGetModuleVersion() -> const char * { return GFModuleStrDup("1.0.0"); } + +auto GFGetModuleMetaData() -> GFModuleMetaData * { + auto *p_meta = static_cast<GFModuleMetaData *>( + GFAllocateMemory(sizeof(GFModuleMetaData))); + auto *h_meta = p_meta; + + p_meta->key = "Name"; + p_meta->value = "GatherGnupgInfo"; + p_meta->next = static_cast<GFModuleMetaData *>( + GFAllocateMemory(sizeof(GFModuleMetaData))); + p_meta = p_meta->next; + + p_meta->key = "Description"; + p_meta->value = "Try gathering gnupg informations"; + p_meta->next = static_cast<GFModuleMetaData *>( + GFAllocateMemory(sizeof(GFModuleMetaData))); + p_meta = p_meta->next; + + p_meta->key = "Author"; + p_meta->value = "Saturneric"; + p_meta->next = nullptr; + return h_meta; +} + +auto GFRegisterModule() -> int { + GFModuleLogDebug("gnupg info gathering module registering"); + return 0; +} + +auto GFActiveModule() -> int { + GFModuleLogDebug("gnupg info gathering module activating"); + GFModuleListenEvent(GFGetModuleID(), + GFModuleStrDup("REQUEST_GATHERING_GNUPG_INFO")); + return 0; +} + +auto GFExecuteModule(GFModuleEvent *event) -> int { + GFModuleLogDebug( + fmt::format("gnupg info gathering module executing, event id: {}", + event->id) + .c_str()); + + GFModuleLogDebug("start to load extra info at module gnupginfogathering..."); + + const auto *const gpgme_version = GFModuleRetrieveRTValueOrDefault( + GFModuleStrDup("core"), GFModuleStrDup("gpgme.version"), + GFModuleStrDup("0.0.0")); + GFModuleLogDebug( + fmt::format("got gpgme version from rt: {}", gpgme_version).c_str()); + + const auto *const gpgconf_path = GFModuleRetrieveRTValueOrDefault( + GFModuleStrDup("core"), GFModuleStrDup("gpgme.ctx.gpgconf_path"), + GFModuleStrDup("")); + GFModuleLogDebug( + fmt::format("got gpgconf path from rt: {}", gpgconf_path).c_str()); + + auto context = Context{gpgme_version, gpgconf_path}; + + // get all components + const char *argv[] = {GFModuleStrDup("--list-components")}; + GFExecuteCommandSync(gpgconf_path, 1, argv, GetGpgComponentInfos, &context); + GFModuleLogDebug("load gnupg component info done."); + +#ifdef QT5_BUILD + QVector<GFCommandExecuteContext> exec_contexts; +#else + QList<GFCommandExecuteContext> exec_contexts; +#endif + + const char **argv_0 = + static_cast<const char **>(GFAllocateMemory(sizeof(const char *))); + argv_0[0] = GFModuleStrDup("--list-dirs"); + + exec_contexts.push_back( + {gpgconf_path, 1, argv_0, GetGpgDirectoryInfos, nullptr}); + + char **components_c_array; + int ret = GFModuleListRTChildKeys( + GFGetModuleID(), GFModuleStrDup("gnupg.components"), &components_c_array); + if (components_c_array == nullptr || ret == 0) return -1; + + QStringList components; + auto *p_a = components_c_array; + for (int i = 0; i < ret; i++) components.append(QString::fromUtf8(p_a[i])); + + for (const auto &component : components) { + const auto *component_info_json = GFModuleRetrieveRTValueOrDefault( + GFGetModuleID(), + GFModuleStrDup(QString("gnupg.components.%1").arg(component).toUtf8()), + nullptr); + + if (component_info_json == nullptr) continue; + + auto jsonlized_component_info = + QJsonDocument::fromJson(component_info_json); + assert(jsonlized_component_info.isObject()); + + auto component_info = GpgComponentInfo(jsonlized_component_info.object()); + GFModuleLogDebug(fmt::format("gpgconf check options ready, " + "component: {}", + component_info.name) + .c_str()); + + if (component_info.name == "gpgme" || component_info.name == "gpgconf") { + continue; + } + + auto *context = new (GFAllocateMemory(sizeof(Context))) + Context{gpgme_version, gpgconf_path, component_info}; + + const char **argv_0 = + static_cast<const char **>(GFAllocateMemory(sizeof(const char *) * 2)); + argv_0[0] = GFModuleStrDup("--list-options"), + argv_0[1] = GFModuleStrDup(component_info.name.toUtf8()); + exec_contexts.push_back( + {gpgconf_path, 2, argv_0, GetGpgOptionInfos, context}); + } + + GFExecuteCommandBatchSync(static_cast<int32_t>(exec_contexts.size()), + exec_contexts.constData()); + GFModuleUpsertRTValueBool(GFGetModuleID(), + GFModuleStrDup("gnupg.gathering_done"), 1); + + char **event_argv = + static_cast<char **>(GFAllocateMemory(sizeof(char **) * 1)); + event_argv[0] = GFModuleStrDup("0"); + + GFModuleTriggerModuleEventCallback(event, GFGetModuleID(), 1, event_argv); + + GFModuleLogDebug("gnupg external info gathering done"); + return 0; +} + +auto GFDeactiveModule() -> int { return 0; } + +auto GFUnregisterModule() -> int { + GFModuleLogDebug("gnupg info gathering module unregistering"); + return 0; +} + +auto CalculateBinaryChacksum(const QString &path) -> std::optional<QString> { + // check file info and access rights + QFileInfo info(path); + if (!info.exists() || !info.isFile() || !info.isReadable()) { + GFModuleLogError(fmt::format("get info for file {} error, exists: {}", + info.filePath(), info.exists()) + .c_str()); + return {}; + } + + // open and read file + QFile f(info.filePath()); + if (!f.open(QIODevice::ReadOnly)) { + GFModuleLogError(fmt::format("open {} to calculate checksum error: {}", + path.toStdString(), + f.errorString().toStdString()) + .c_str()); + return {}; + } + + QCryptographicHash hash_sha(QCryptographicHash::Sha256); + + // read data by chunks + const qint64 buffer_size = 8192; // Define a suitable buffer size + while (!f.atEnd()) { + QByteArray const buffer = f.read(buffer_size); + if (buffer.isEmpty()) { + GFModuleLogError(fmt::format("error reading file {} during " + "checksum calculation", + path.toStdString()) + .c_str()); + return {}; + } + hash_sha.addData(buffer); + } + + // close the file + f.close(); + + // return the first 6 characters of the SHA-256 hash + // of the file + return QString(hash_sha.result().toHex()).left(6); +} + +void GetGpgComponentInfos(void *data, int exit_code, const char *out, + const char *err) { + auto *context = reinterpret_cast<Context *>(data); + auto p_out = QString::fromUtf8(out); + auto p_err = QString::fromUtf8(err); + + GFModuleLogDebug(fmt::format("gpgconf components exit_code: {} " + "process stdout size: {}", + exit_code, p_out.size()) + .c_str()); + + if (exit_code != 0) { + GFModuleLogError(fmt::format("gpgconf execute error, process " + "stderr: {}, " + "process stdout: {}", + p_err, p_out) + .c_str()); + return; + } + + std::vector<GpgComponentInfo> component_infos; + GpgComponentInfo c_i_gpgme; + c_i_gpgme.name = "gpgme"; + c_i_gpgme.desc = "GPG Made Easy"; + c_i_gpgme.version = context->gpgme_version; + c_i_gpgme.path = "Embedded In"; + c_i_gpgme.binary_checksum = "/"; + + GpgComponentInfo c_i_gpgconf; + c_i_gpgconf.name = "gpgconf"; + c_i_gpgconf.desc = "GPG Configure"; + c_i_gpgconf.version = "/"; + c_i_gpgconf.path = context->gpgconf_path; + auto gpgconf_binary_checksum = CalculateBinaryChacksum(context->gpgconf_path); + c_i_gpgconf.binary_checksum = + (gpgconf_binary_checksum.has_value() ? gpgconf_binary_checksum.value() + : QString("/")); + + component_infos.push_back(c_i_gpgme); + component_infos.push_back(c_i_gpgconf); + + auto const jsonlized_gpgme_component_info = c_i_gpgme.Json(); + auto const jsonlized_gpgconf_component_info = c_i_gpgconf.Json(); + GFModuleUpsertRTValue( + GFGetModuleID(), GFModuleStrDup("gnupg.components.gpgme"), + GFModuleStrDup(QJsonDocument(jsonlized_gpgme_component_info).toJson())); + GFModuleUpsertRTValue( + GFGetModuleID(), GFModuleStrDup("gnupg.components.gpgconf"), + GFModuleStrDup(QJsonDocument(jsonlized_gpgconf_component_info).toJson())); + + auto line_split_list = p_out.split("\n"); + + for (const auto &line : line_split_list) { + auto info_split_list = line.split(":"); + + if (info_split_list.size() != 3) continue; + + auto component_name = info_split_list[0].trimmed(); + auto component_desc = info_split_list[1].trimmed(); + auto component_path = info_split_list[2].trimmed(); + +#ifdef WINDOWS + // replace some special substrings on windows + // platform + component_path.replace("%3a", ":"); +#endif + + auto binary_checksum = CalculateBinaryChacksum(component_path); + + GFModuleLogDebug( + fmt::format("gnupg component name: {} desc: " + "{} checksum: {} path: {} ", + component_name, component_desc, + binary_checksum.has_value() ? binary_checksum.value() : "/", + component_path) + .c_str()); + + QString version = "/"; + + if (component_name == "gpg") { + version = GFModuleRetrieveRTValueOrDefault( + GFModuleStrDup("core"), GFModuleStrDup("gpgme.ctx.gnupg_version"), + GFModuleStrDup("2.0.0")); + } + if (component_name == "gpg-agent") { + GFModuleUpsertRTValue(GFGetModuleID(), + GFModuleStrDup("gnupg.gpg_agent_path"), + GFModuleStrDup(QString(component_path).toUtf8())); + } + if (component_name == "dirmngr") { + GFModuleUpsertRTValue(GFGetModuleID(), + GFModuleStrDup("gnupg.dirmngr_path"), + GFModuleStrDup(QString(component_path).toUtf8())); + } + if (component_name == "keyboxd") { + GFModuleUpsertRTValue(GFGetModuleID(), + GFModuleStrDup("gnupg.keyboxd_path"), + GFModuleStrDup(QString(component_path).toUtf8())); + } + + { + GpgComponentInfo c_i; + c_i.name = component_name; + c_i.desc = component_desc; + c_i.version = version; + c_i.path = component_path; + c_i.binary_checksum = + (binary_checksum.has_value() ? binary_checksum.value() + : QString("/")); + + auto const jsonlized_component_info = c_i.Json(); + GFModuleUpsertRTValue( + GFGetModuleID(), + GFModuleStrDup( + QString("gnupg.components.%1").arg(component_name).toUtf8()), + GFModuleStrDup(QJsonDocument(jsonlized_component_info).toJson())); + + component_infos.push_back(c_i); + } + + GFModuleLogDebug("load gnupg component info actually done."); + } +} + +void GetGpgDirectoryInfos(void *, int exit_code, const char *out, + const char *err) { + if (exit_code != 0) return; + + auto p_out = QString::fromUtf8(out); + auto p_err = QString::fromUtf8(err); + auto line_split_list = p_out.split("\n"); + + for (const auto &line : line_split_list) { + auto info_split_list = line.split(":"); + GFModuleLogDebug(fmt::format("gpgconf direcrotries info line: " + "{} info size: {}", + line, info_split_list.size()) + .c_str()); + + if (info_split_list.size() != 2) continue; + + auto configuration_name = info_split_list[0].trimmed(); + auto configuration_value = info_split_list[1].trimmed(); + +#ifdef WINDOWS + // replace some special substrings on windows + // platform + configuration_value.replace("%3a", ":"); +#endif + + // record gnupg home path + if (configuration_name == "homedir") { + GFModuleUpsertRTValue(GFGetModuleID(), GFModuleStrDup("gnupg.home_path"), + GFModuleStrDup(configuration_value.toUtf8())); + } + + GFModuleUpsertRTValue( + GFGetModuleID(), + GFModuleStrDup( + QString("gnupg.dirs.%1").arg(configuration_name).toUtf8()), + GFModuleStrDup(configuration_value.toUtf8())); + } +} + +void GetGpgOptionInfos(void *data, int exit_code, const char *out, + const char *err) { + if (exit_code != 0) return; + + auto p_out = QString::fromUtf8(out); + auto p_err = QString::fromUtf8(err); + auto *context = reinterpret_cast<Context *>(data); + auto component_name = context->component_info.name; + + GFModuleLogDebug(fmt::format("gpgconf {} avaliable options " + "exit_code: {} process stdout " + "size: {} ", + component_name, exit_code, p_out.size()) + .c_str()); + + std::vector<GpgOptionsInfo> options_infos; + + auto line_split_list = p_out.split("\n"); + + for (const auto &line : line_split_list) { + auto info_split_list = line.split(":"); + + GFModuleLogDebug(fmt::format("component {} avaliable options " + "line: {} info size: {}", + component_name, line, info_split_list.size()) + .c_str()); + + if (info_split_list.size() < 10) continue; + + // The format of each line is: + // name:flags:level:description:type:alt-type:argname:default:argdef:value + + auto option_name = info_split_list[0].trimmed(); + auto option_flags = info_split_list[1].trimmed(); + auto option_level = info_split_list[2].trimmed(); + auto option_desc = info_split_list[3].trimmed(); + auto option_type = info_split_list[4].trimmed(); + auto option_alt_type = info_split_list[5].trimmed(); + auto option_argname = info_split_list[6].trimmed(); + auto option_default = info_split_list[7].trimmed(); + auto option_argdef = info_split_list[8].trimmed(); + auto option_value = info_split_list[9].trimmed(); + + GpgOptionsInfo info; + info.name = option_name; + info.flags = option_flags; + info.level = option_level; + info.description = option_desc; + info.type = option_type; + info.alt_type = option_alt_type; + info.argname = option_argname; + info.default_value = option_default; + info.argdef = option_argdef; + info.value = option_value; + + auto const jsonlized_option_info = info.Json(); + GFModuleUpsertRTValue( + GFGetModuleID(), + GFModuleStrDup(QString("gnupg.components.%1.options.%2") + .arg(component_name) + .arg(option_name) + .toUtf8()), + GFModuleStrDup(QJsonDocument(jsonlized_option_info).toJson())); + options_infos.push_back(info); + } + + context->~Context(); + GFFreeMemory(context); +} diff --git a/src/m_gpg_info/GnuPGInfoGatheringModule.h b/src/m_gpg_info/GnuPGInfoGatheringModule.h new file mode 100644 index 0000000..35ee4ac --- /dev/null +++ b/src/m_gpg_info/GnuPGInfoGatheringModule.h @@ -0,0 +1,56 @@ +/** + * Copyright (C) 2021 Saturneric <[email protected]> + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric <[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#pragma once + +#include <GFSDKModule.h> + +#include "GFModuleExport.h" + +extern "C" { + +auto GF_MODULE_EXPORT GFGetModuleGFSDKVersion() -> const char *; + +auto GF_MODULE_EXPORT GFGetModuleQtEnvVersion() -> const char *; + +auto GF_MODULE_EXPORT GFGetModuleID() -> const char *; + +auto GF_MODULE_EXPORT GFGetModuleVersion() -> const char *; + +auto GF_MODULE_EXPORT GFGetModuleMetaData() -> GFModuleMetaData *; + +auto GF_MODULE_EXPORT GFRegisterModule() -> int; + +auto GF_MODULE_EXPORT GFActiveModule() -> int; + +auto GF_MODULE_EXPORT GFExecuteModule(GFModuleEvent *) -> int; + +auto GF_MODULE_EXPORT GFDeactiveModule() -> int; + +auto GF_MODULE_EXPORT GFUnregisterModule() -> int; +}; diff --git a/src/m_gpg_info/GpgInfo.cpp b/src/m_gpg_info/GpgInfo.cpp new file mode 100644 index 0000000..680f4a8 --- /dev/null +++ b/src/m_gpg_info/GpgInfo.cpp @@ -0,0 +1,79 @@ +/** + * Copyright (C) 2021 Saturneric <[email protected]> + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric <[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "GpgInfo.h" + +GpgOptionsInfo::GpgOptionsInfo(const QJsonObject &j) { + if (const auto v = j["name"]; v.isString()) name = v.toString(); + if (const auto v = j["flags"]; v.isString()) flags = v.toString(); + if (const auto v = j["level"]; v.isString()) level = v.toString(); + if (const auto v = j["description"]; v.isString()) description = v.toString(); + if (const auto v = j["type"]; v.isString()) type = v.toString(); + if (const auto v = j["alt_type"]; v.isString()) alt_type = v.toString(); + if (const auto v = j["argname"]; v.isString()) argname = v.toString(); + if (const auto v = j["default_value"]; v.isString()) { + default_value = v.toString(); + } + if (const auto v = j["argdef"]; v.isString()) argdef = v.toString(); + if (const auto v = j["value"]; v.isString()) value = v.toString(); +} + +auto GpgOptionsInfo::Json() const -> QJsonObject { + QJsonObject j; + j["name"] = name; + j["flags"] = flags; + j["level"] = level; + j["description"] = description; + j["type"] = type; + j["alt_type"] = alt_type; + j["argname"] = argname; + j["default_value"] = default_value; + j["argdef"] = argdef; + j["value"] = value; + return j; +} + +auto GpgComponentInfo::Json() const -> QJsonObject { + QJsonObject j; + j["name"] = name; + j["desc"] = desc; + j["version"] = version; + j["path"] = path; + j["binary_checksum"] = binary_checksum; + return j; +} + +GpgComponentInfo::GpgComponentInfo(const QJsonObject &j) { + if (const auto v = j["name"]; v.isString()) name = v.toString(); + if (const auto v = j["desc"]; v.isString()) desc = v.toString(); + if (const auto v = j["version"]; v.isString()) version = v.toString(); + if (const auto v = j["path"]; v.isString()) path = v.toString(); + if (const auto v = j["binary_checksum"]; v.isString()) { + binary_checksum = v.toString(); + } +} diff --git a/src/m_gpg_info/GpgInfo.h b/src/m_gpg_info/GpgInfo.h new file mode 100644 index 0000000..1aacc20 --- /dev/null +++ b/src/m_gpg_info/GpgInfo.h @@ -0,0 +1,88 @@ +/** + * Copyright (C) 2021 Saturneric <[email protected]> + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric <[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#pragma once + +#include <QJsonObject> +#include <QString> +#include <map> + +/** + * @brief Use to record some info about gnupg + * + */ +class GpgInfo { + public: + QString GnuPGHomePath; ///< value of ---homedir + + std::map<QString, std::vector<QString>> ComponentsInfo; ///< + std::map<QString, std::vector<QString>> ConfigurationsInfo; ///< + std::map<QString, std::vector<QString>> OptionsInfo; ///< + std::map<QString, std::vector<QString>> AvailableOptionsInfo; ///< +}; + +/** + * @brief Use to record some info about gnupg components + * + */ +struct GpgComponentInfo { + QString name; + QString desc; + QString version; + QString path; + QString binary_checksum; + + GpgComponentInfo() = default; + + explicit GpgComponentInfo(const QJsonObject &j); + + [[nodiscard]] auto Json() const -> QJsonObject; +}; + +/** + * The format of each line is: + * name:flags:level:description:type:alt-type:argname:default:argdef:value + */ +struct GpgOptionsInfo { + QString name; + QString flags; + QString level; + QString description; + QString type; + QString alt_type; + QString argname; + QString default_value; + QString argdef; + QString value; + + GpgOptionsInfo() = default; + + explicit GpgOptionsInfo(const QJsonObject &j); + + [[nodiscard]] auto Json() const -> QJsonObject; +}; diff --git a/src/m_gpg_info/QtLoggerFmt.h b/src/m_gpg_info/QtLoggerFmt.h new file mode 100644 index 0000000..2399746 --- /dev/null +++ b/src/m_gpg_info/QtLoggerFmt.h @@ -0,0 +1,68 @@ +/** + * Copyright (C) 2021 Saturneric <[email protected]> + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric <[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#pragma once + +#include <spdlog/spdlog.h> + +#include <QString> + +template <> +struct fmt::formatter<QString> { + // Parses format specifications. + constexpr auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) { + return ctx.begin(); + } + + // Formats the QString qstr and writes it to the output. + template <typename FormatContext> + auto format(const QString& qstr, FormatContext& ctx) const + -> decltype(ctx.out()) { + // Convert QString to UTF-8 QString (to handle Unicode characters + // correctly) + QByteArray utf8_array = qstr.toUtf8(); + return fmt::format_to(ctx.out(), "{}", utf8_array.constData()); + } +}; + +template <> +struct fmt::formatter<QByteArray> { + // Parses format specifications. + constexpr auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) { + return ctx.begin(); + } + + // Formats the QString qstr and writes it to the output. + template <typename FormatContext> + auto format(const QByteArray& qarray, FormatContext& ctx) const + -> decltype(ctx.out()) { + // Convert QString to UTF-8 QString (to handle Unicode characters + // correctly) + return fmt::format_to(ctx.out(), "{}", qarray.constData()); + } +}; |