Compare commits

...

41 Commits

Author SHA1 Message Date
afe9e648b5 fix: try to fix build process of git actions
Some checks are pending
Doxygen Generation / Dispatch to GpgFrontend-Doxygen (push) Waiting to run
Build & Package Qt5 / build (ubuntu-20.04) (push) Waiting to run
Build & Package Qt5 / build (windows-2019) (push) Waiting to run
Build & Package / build (macos-12) (push) Waiting to run
Build & Package / build (macos-13) (push) Waiting to run
Build & Package / build (macos-14) (push) Waiting to run
Build & Package / build (ubuntu-20.04) (push) Waiting to run
Build & Package / build (windows-2019) (push) Waiting to run
2024-07-28 21:05:25 +02:00
ad558726a3 fix: application should link gpgfrontend_core 2024-07-28 20:29:22 +02:00
cf9d6538e6 fix: correct header search path of application 2024-07-28 20:21:38 +02:00
aee8017b52 fix: must install all headers of test, ui and core and set include path properly 2024-07-28 20:09:15 +02:00
a03c18045f fix: remove libs from install lists at app build only mode 2024-07-28 19:53:59 +02:00
3ef497cbeb feat: support more build mode 2024-07-28 19:47:40 +02:00
a3d7a46fc4 fix: errors in judgment conditions 2024-07-28 18:11:40 +02:00
cb626d06de feat: user can prevent all modules 2024-07-28 18:00:30 +02:00
28546a83da feat: search for keywords in all uids 2024-07-28 17:32:25 +02:00
cb15c1a06a feat: double-click key table row wil show detail dialog 2024-07-28 17:24:14 +02:00
0f0b10586f feat: log pattern should be different at release mode 2024-07-28 17:23:16 +02:00
4e0db9ef4b feat: add paper key module support 2024-07-28 17:08:56 +02:00
9ee5e37b6e fix: remove invalid parameters from the SDK 2024-07-28 17:08:11 +02:00
adc5d89717 fix: correct the spelling of 'deactivate' 2024-07-28 17:07:15 +02:00
c1d0552cb3 fix: can not import binary key data 2024-07-28 15:28:14 +02:00
8bb3bf646e fix: passphrase corrected is not correct as the real one 2024-07-28 14:23:17 +02:00
0a61ccd17a fix: do some clean up for removal of pinentry 2024-07-27 14:22:01 +02:00
e8efa4d104 feat: move pinentry out of source code 2024-07-27 14:18:56 +02:00
5be04d1602 feat: improve sdk api for pinentry module 2024-07-27 14:18:26 +02:00
1c44454085 fix: discover and solve some memory issues 2024-07-27 10:56:19 +02:00
ca3a64b4a5 fix: indirect memory leak issues 2024-07-26 18:41:17 +02:00
3d84beaf22 fix: clean up warnings 2024-07-26 18:33:09 +02:00
37a62a8d0b feat: remove spdlog and clean up log 2024-07-26 18:24:34 +02:00
d322e76533 fix: correct urls at appdata.xml 2024-07-26 12:34:19 +02:00
09f6952d0a fix: solve the wayland issue of flatpak and fix urls at appstream meta file
cause: QApplication inadvertently initialised twice
2024-07-26 12:08:07 +02:00
85eff35d7b fix: Qt6CoreConfigureFileTemplate.in does not exist 2024-07-25 19:15:21 +02:00
cc9b3fcdd7 fix: update GeneralSettings ui file 2024-07-25 18:24:34 +02:00
6728888b87 feat: add an ASAN option to enable a memory debugging mode 2024-07-25 13:31:16 +02:00
ed9f905440 feat: update mimalloc to v2.1.7 2024-07-25 13:26:44 +02:00
71ca9724b8 feat: move out GnuPGTab 2024-07-24 16:01:55 +02:00
d1d6859e2a feat: add some ui apis to sdk 2024-07-12 20:38:16 +02:00
bc52ba74b4 feat: adjust modules loading path 2024-07-12 15:18:34 +02:00
9f61a1f86c feat: improve the project structure 2024-07-12 14:58:34 +02:00
c0a2987afd feat: move modules' code out of repo 2024-07-10 16:17:40 +02:00
30c3a52fc7 feat: add macos 13 and 14 and remove macos 11 in ci build config 2024-07-05 19:54:13 +02:00
12fdf94b85 feat: support generate elgamal subkey 2024-06-29 13:21:52 +02:00
2c42d6cb72 feat: enable sorting and add column "comment" at key table 2024-06-28 23:31:45 +02:00
19926663f1 refactor: rewrite KeyMenuAbility 2024-06-28 23:20:04 +02:00
d0333031c1 feat: user can select shown columns at key table 2024-06-28 23:05:25 +02:00
e7694f9a07 feat: rewrite key list structure and logic 2024-06-02 22:03:59 +02:00
63dbe4a917 fix: cannot show version in about tab 2024-05-17 18:33:21 +02:00
211 changed files with 3421 additions and 8127 deletions

View File

@ -23,7 +23,7 @@ jobs:
build:
strategy:
matrix:
os: [ 'ubuntu-20.04', 'macos-11', 'macos-12', 'windows-2019' ]
os: [ 'ubuntu-20.04', 'macos-13', 'macos-12', "macos-14", 'windows-2019' ]
runs-on: ${{ matrix.os }}
continue-on-error: true
steps:
@ -31,7 +31,7 @@ jobs:
run: |
git config --global core.autocrlf false
git config --global core.eol lf
if: matrix.os == 'windows-2019' || matrix.os == 'macos-11' || matrix.os == 'macos-12'
if: matrix.os == 'windows-2019' || matrix.os == 'macos-13' || matrix.os == 'macos-12' || matrix.os == 'macos-14'
- uses: actions/checkout@v4
with:
@ -72,21 +72,21 @@ jobs:
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles
if: matrix.os == 'macos-11' || matrix.os == 'macos-12'
if: matrix.os == 'macos-13' || matrix.os == 'macos-12' || matrix.os == 'macos-14'
- name: Install Qt6
uses: jurplel/install-qt-action@v3
with:
version: '6.5.3'
cache: 'true'
if: matrix.os == 'ubuntu-20.04' || matrix.os == 'macos-11' || matrix.os == 'macos-12'
if: matrix.os == 'ubuntu-20.04' || matrix.os == 'macos-13' || matrix.os == 'macos-12' || matrix.os == 'macos-14'
- name: Install Dependence (macOS)
run: |
brew install cmake autoconf automake texinfo gettext openssl@3
brew install ninja libarchive gpgme
brew link openssl@3 --force
if: matrix.os == 'macos-11' || matrix.os == 'macos-12'
if: matrix.os == 'macos-13' || matrix.os == 'macos-12' || matrix.os == 'macos-14'
- name: Set up MinGW (Windows)
uses: msys2/setup-msys2@v2
@ -173,19 +173,19 @@ jobs:
cd ${{github.workspace}}
if: matrix.os == 'windows-2019'
- name: Build GpgFrontend (Linux)
- name: Build & Install Full SDK
# Build your GpgFrontend with the given configuration
run: |
cmake -B ${{github.workspace}}/build -G Ninja -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
cmake --build ${{github.workspace}}/build --config {{$env.BUILD_TYPE}} -- -v
if: matrix.os == 'ubuntu-20.04'
cmake -B ${{github.workspace}}/build-full-sdk -G Ninja -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DGPGFRONTEND_BUILD_TYPE_FULL_SDK=ON
cmake --build ${{github.workspace}}/build-full-sdk --config {{$env.BUILD_TYPE}} -- -v
cmake --install ${{github.workspace}}/build-full-sdk --config {{$env.BUILD_TYPE}}
- name: Build Integrated Modules (macOS)
- name: Build Integrated Modules
# Build your GpgFrontend with the given configuration
run: |
cmake -B ${{github.workspace}}/build-mods -G Ninja -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DGPGFRONTEND_BUILD_MODS_ONLY=On
cmake --build ${{github.workspace}}/build-mods --config {{$env.BUILD_TYPE}} -- -v
if: matrix.os == 'macos-11' || matrix.os == 'macos-12'
cmake -B ${{github.workspace}}/modules/build -G Ninja -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/modules/build/artifacts
cmake --build ${{github.workspace}}/modules/build --config {{$env.BUILD_TYPE}} -- -v
cmake --install ${{github.workspace}}/modules/build --config {{$env.BUILD_TYPE}}
- name: Build & Export GpgFrontend (macOS)
# Build your GpgFrontend with the given configuration
@ -205,14 +205,14 @@ jobs:
xcodebuild -exportArchive -archivePath ${{github.workspace}}/build/GpgFrontend.xcarchive \
-exportOptionsPlist ${{github.workspace}}/build/ExportOptions.plist \
-exportPath ${{github.workspace}}/build/package/
if: matrix.os == 'macos-11' || matrix.os == 'macos-12'
if: matrix.os == 'macos-13' || matrix.os == 'macos-12' || matrix.os == 'macos-14'
- name: Copy Modules into Bundle & Deploy Qt & Code Sign (macOS)
run: |
cmake -E copy_directory ${{github.workspace}}/build-mods/artifacts/mods ${{github.workspace}}/build/package/GpgFrontend.app/Contents/PlugIns/mods
cmake -E copy_directory ${{github.workspace}}/modules/build/artifacts/modules ${{github.workspace}}/build/package/GpgFrontend.app/Contents/modules
macdeployqt ${{github.workspace}}/build/package/GpgFrontend.app -verbose=2 -appstore-compliant -always-overwrite
codesign -s "${{secrets.GPGFRONTEND_XOCDE_CODE_SIGN_IDENTITY}}" -f --deep --options=runtime ${{github.workspace}}/build/package/GpgFrontend.app
if: matrix.os == 'macos-11' || matrix.os == 'macos-12'
if: matrix.os == 'macos-13' || matrix.os == 'macos-12' || matrix.os == 'macos-14'
- name: Package & Sign App Bundle (macOS)
run: |
@ -227,7 +227,7 @@ jobs:
${{github.workspace}}/build/final-artifact/GpgFrontend-${{env.sha_short}}-x86_64.dmg
mv ${{github.workspace}}/build/GpgFrontend.app.zip \
${{github.workspace}}/build/GpgFrontend-${{env.sha_short}}-x86_64.zip
if: matrix.os == 'macos-11' || matrix.os == 'macos-12'
if: matrix.os == 'macos-13' || matrix.os == 'macos-12' || matrix.os == 'macos-14'
- name: Notarize Release Build (macOS)
run: |
@ -236,15 +236,23 @@ jobs:
--team-id ${{secrets.APPLE_DEVELOPER_TEAM_ID}} \
--password ${{secrets.APPLE_DEVELOPER_ID_SECRET}} \
${{github.workspace}}/build/GpgFrontend-${{env.sha_short}}-x86_64.zip
if: matrix.os == 'macos-11' || matrix.os == 'macos-12'
if: matrix.os == 'macos-13' || matrix.os == 'macos-12' || matrix.os == 'macos-14'
- name: Package App Image (Linux)
- name: Build GpgFrontend (Linux)
# Build your GpgFrontend with the given configuration
run: |
cmake -B ${{github.workspace}}/build -G Ninja -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DDGPGFRONTEND_BUILD_TYPE_ONLY_APPLICATION=ON
cmake --build ${{github.workspace}}/build --config {{$env.BUILD_TYPE}} -- -v
if: matrix.os == 'ubuntu-20.04'
- name: Copy Modules & Package App Image (Linux)
run: |
cmake -E copy_directory ${{github.workspace}}/modules/build/artifacts/modules ${{github.workspace}}/build/artifacts/AppDir/usr/modules
mkdir ${{github.workspace}}/build/final-artifact
cd ${{github.workspace}}/build/final-artifact
wget -c -nv https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage
chmod u+x linuxdeployqt-continuous-x86_64.AppImage
./linuxdeployqt-continuous-x86_64.AppImage ${{github.workspace}}/build/artifacts/AppDir/usr/share/applications/*.desktop -no-translations -extra-plugins=iconengines,platformthemes/libqgtk3.so -appimage -executable-dir=${{github.workspace}}/build/artifacts/AppDir/usr/plugins/mods/
./linuxdeployqt-continuous-x86_64.AppImage ${{github.workspace}}/build/artifacts/AppDir/usr/share/applications/*.desktop -no-translations -extra-plugins=iconengines,platformthemes/libqgtk3.so -appimage -executable-dir=${{github.workspace}}/build/artifacts/AppDir/usr/modules/
if: matrix.os == 'ubuntu-20.04'
- name: Configure CMake & Build Binary(Windows)
@ -268,7 +276,7 @@ jobs:
with:
name: gpgfrontend-${{matrix.os}}-${{env.BUILD_TYPE}}-${{ github.sha }}
path: ${{github.workspace}}/build/final-artifact/*
if: matrix.os == 'macos-11' || matrix.os == 'macos-12'
if: matrix.os == 'macos-13' || matrix.os == 'macos-12' || matrix.os == 'macos-14'
- name: Upload Artifact(Windows)
uses: actions/upload-artifact@master

6
.gitmodules vendored
View File

@ -1,9 +1,6 @@
[submodule "third_party/qt-aes"]
path = third_party/qt-aes
url = https://github.com/bricke/Qt-AES.git
[submodule "third_party/spdlog"]
path = third_party/spdlog
url = https://github.com/gabime/spdlog.git
[submodule "third_party/mimalloc"]
path = third_party/mimalloc
url = https://github.com/microsoft/mimalloc.git
@ -16,3 +13,6 @@
[submodule "third_party/qttranslations"]
path = third_party/qttranslations
url = https://github.com/qt/qttranslations.git
[submodule "modules"]
path = modules
url = https://github.com/saturneric/GpgFrontend-Modules.git

View File

@ -65,9 +65,12 @@ option(GPGFRONTEND_BUILD_TYPE_TEST_ALL
"Generate a graphical interface with all functions" OFF)
option(GPGFRONTEND_BUILD_TYPE_STABLE
"Generate release version" ON)
option(GPGFRONTEND_BUILD_TYPE_FULL_SDK "Build and install all headers and libs exclude application" OFF)
option(GPGFRONTEND_BUILD_TYPE_ONLY_SDK "Build and install sdk headers and libs" OFF)
option(GPGFRONTEND_BUILD_TYPE_ONLY_APPLICATION "Generate a usable SDK" OFF)
option(GPGFRONTEND_QT5_BUILD "Swith to Qt5 building mode" OFF)
option(GPGFRONTEND_GENERATE_LINUX_INSTALL_SOFTWARE "Generate an installable version" OFF)
option(GPGFRONTEND_BUILD_MODS_ONLY "Build Modules Only" OFF)
option(GPGFRONTEND_ENABLE_ASAN "Enable ASAN" OFF)
option(GPGFRONTEND_XCODE_TEAM_ID "GpgFrontend Apple Team ID" "NONE")
option(GPGFRONTEND_XOCDE_CODE_SIGN_IDENTITY "GpgFrontend Signing Certificate" "NONE")
@ -124,7 +127,7 @@ if (GPGFRONTEND_GENERATE_LINUX_INSTALL_SOFTWARE)
set(LINUX_INSTALL_SOFTWARE 1)
endif ()
if (GPGFRONTEND_BUILD_MODS_ONLY)
if (GPGFRONTEND_BUILD_TYPE_FULL_SDK)
set(GPGFRONTEND_BUILD_TYPE_TEST_CORE 0)
set(GPGFRONTEND_BUILD_TYPE_TEST_CORE_AND_COVERAGE 0)
set(GPGFRONTEND_BUILD_TYPE_TEST_UI 0)
@ -132,7 +135,29 @@ if (GPGFRONTEND_BUILD_MODS_ONLY)
unset(GPGFRONTEND_BUILD_CONFIG)
set(STABLE_BUILD_APPLICATION 0)
set(BUILD_MODS_ONLY 1)
set(STABLE_BUILD_FULL_SDK 1)
endif()
if (GPGFRONTEND_BUILD_TYPE_ONLY_SDK)
set(GPGFRONTEND_BUILD_TYPE_TEST_CORE 0)
set(GPGFRONTEND_BUILD_TYPE_TEST_CORE_AND_COVERAGE 0)
set(GPGFRONTEND_BUILD_TYPE_TEST_UI 0)
set(GPGFRONTEND_BUILD_TYPE_TEST_ALL 0)
unset(GPGFRONTEND_BUILD_CONFIG)
set(STABLE_BUILD_APPLICATION 0)
set(STABLE_BUILD_ONLY_SDK 1)
endif()
if (GPGFRONTEND_BUILD_TYPE_ONLY_APPLICATION)
set(GPGFRONTEND_BUILD_TYPE_TEST_CORE 0)
set(GPGFRONTEND_BUILD_TYPE_TEST_CORE_AND_COVERAGE 0)
set(GPGFRONTEND_BUILD_TYPE_TEST_UI 0)
set(GPGFRONTEND_BUILD_TYPE_TEST_ALL 0)
unset(GPGFRONTEND_BUILD_CONFIG)
set(STABLE_BUILD_APPLICATION 0)
set(STABLE_BUILD_ONLY_APPLICATION 1)
endif()
# C++
@ -206,6 +231,20 @@ if (CMAKE_BUILD_TYPE STREQUAL "Release" AND APPLE)
unset(GPGFRONTEND_BUILD_CONFIG)
endif ()
# if enable ASAN
if(GPGFRONTEND_ENABLE_ASAN)
# check compiler
if(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
message(FATAL_ERROR "Use GPGFRONTEND_ENABLE_ASAN only when using the clang compiler.")
endif()
add_compile_options(-fsanitize=address -fsanitize-recover=address)
add_link_options(-fsanitize=address -fsanitize-recover=address)
set(ENABLE_ASAN 1)
endif()
set(AppName GpgFrontend)
# Get Git Information
@ -353,29 +392,61 @@ else ()
endif ()
if (GPGFRONTEND_QT5_BUILD)
add_compile_definitions(QT5_BUILD)
# Introduce Qt
# Support Qt version: 5.15.x
find_package(Qt5 5.15 COMPONENTS Core Widgets PrintSupport Network LinguistTools REQUIRED)
else()
add_compile_definitions(QT6_BUILD)
# Introduce Qt
# Support Qt version: 6.x
find_package(Qt6 6 COMPONENTS Core Widgets PrintSupport Network LinguistTools REQUIRED)
endif()
# Basic ENV Configure
set(BASIC_ENV_CONFIG 1)
set(QT_MOC_CONFIG 1)
# Qt configuration
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC_OPTIONS "--compress;9")
set(CMAKE_AUTOUIC_SEARCH_PATHS ${CMAKE_AUTOUIC_SEARCH_PATHS} ${CMAKE_SOURCE_DIR}/ui)
if (STABLE_BUILD_APPLICATION)
message("[+] Build Stable Application")
message("[*] Build Stable Application")
set(BUILD_CORE 1)
set(BUILD_UI 1)
set(BUILD_MODULE 1)
set(BUILD_TEST 1)
set(BUILD_SDK 1)
set(BUILD_APPLICATION 1)
set(SUPPORT_MULTI_LANG 1)
elseif (BUILD_MODS_ONLY)
message("[+] Build Mods")
elseif (STABLE_BUILD_ONLY_SDK)
message("[*] Build SDK")
set(BUILD_CORE 1)
set(BUILD_MODULE 1)
set(BUILD_UI 1)
set(BUILD_SDK 1)
elseif (STABLE_BUILD_FULL_SDK)
message("[*] Build All Headers and Libs (SDK fully build)")
set(BUILD_CORE 1)
set(BUILD_UI 1)
set(BUILD_TEST 1)
set(BUILD_SDK 1)
elseif (GPGFRONTEND_BUILD_TYPE_ONLY_APPLICATION)
message("[*] Build executable only")
set(BUILD_CORE 0)
set(BUILD_UI 0)
set(BUILD_TEST 0)
set(BUILD_SDK 0)
set(BUILD_APPLICATION 1)
set(SUPPORT_MULTI_LANG 1)
endif ()
# For instance in order to select the highest version one
SET(CMAKE_FIND_PACKAGE_SORT_ORDER NATURAL)
SET(CMAKE_FIND_PACKAGE_SORT_DIRECTION DEC)

View File

@ -1,11 +1,11 @@
SET (CMAKE_C_FLAGS "-Wall -std=c11")
SET (CMAKE_C_FLAGS_DEBUG "-g -fsanitize=address -fsanitize-recover=address")
SET (CMAKE_C_FLAGS_DEBUG "-g")
SET (CMAKE_C_FLAGS_MINSIZERE "-Os -DNDEBUG")
SET (CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG")
SET (CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -g")
SET (CMAKE_CXX_FLAGS "-Wall -std=c++17")
SET (CMAKE_CXX_FLAGS_DEBUG "-g -fsanitize=address -fsanitize-recover=address")
SET (CMAKE_CXX_FLAGS_DEBUG "-g")
SET (CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG")
SET (CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
SET (CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")

View File

@ -97,6 +97,7 @@
<file alias="key.png">resource/lfs/icons/key.png</file>
<file alias="stairs.png">resource/lfs/icons/stairs.png</file>
<file alias="detail.png">resource/lfs/icons/detail.png</file>
<file alias="filter.png">resource/lfs/icons/filter.png</file>
</qresource>
<qresource prefix="/test/key">
<file alias="pv1.key">resource/lfs/test/data/pv1.key</file>

1
modules Submodule

@ -0,0 +1 @@
Subproject commit f813e3b71ee9563223f3d628374788c1d18b8504

View File

@ -13,10 +13,10 @@
<developer_name>Saturneric</developer_name>
<content_rating type="oars-1.0" />
<url type="homepage">https://gpgfrontend.bktus.com/</url>
<url type="homepage">https://gpgfrontend.bktus.com</url>
<url type="bugtracker">https://github.com/saturneric/GpgFrontend/issues</url>
<url type="contact">https://gpgfrontend.bktus.com/contract</url>
<url type="translate">https://gpgfrontend.bktus.com/translate-interface</url>
<url type="contact">https://www.gpgfrontend.bktus.com/overview/contact</url>
<url type="translate">https://www.gpgfrontend.bktus.com/appendix/translate-interface</url>
<url type="vcs-browser">https://github.com/saturneric/GpgFrontend</url>
<launchable type="desktop-id">com.bktus.gpgfrontend.desktop</launchable>
@ -72,6 +72,7 @@
</keywords>
<releases>
<release version="2.1.3" date="2024-05-11"/>
<release version="2.1.2" date="2024-02-02"/>
<release version="2.1.1" date="2023-09-19"/>
<release version="2.1.0" date="2023-08-01"/>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -23,6 +23,7 @@
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
if(APPLE)
add_compile_definitions("_GNU_SOURCE")
endif()
@ -30,6 +31,7 @@ endif()
# Introduce GpgME
find_package(Gpgme REQUIRED)
# Introduce OpenSSL
if (APPLE)
# Define possible OpenSSL directories
@ -51,37 +53,21 @@ if (APPLE)
message(FATAL_ERROR "OpenSSL not found in the standard directories. Please install it or set OPENSSL_ROOT_DIR manually.")
endif()
endif()
find_package(OpenSSL REQUIRED)
if(GPGFRONTEND_QT5_BUILD)
# Introduce Qt
# Support Qt version: 5.15.x
find_package(Qt5 5.15 COMPONENTS Core Widgets PrintSupport Network LinguistTools REQUIRED)
else()
# Introduce Qt
# Support Qt version: 6.x
find_package(Qt6 6 COMPONENTS Core Widgets PrintSupport Network LinguistTools REQUIRED)
endif()
# Qt configuration
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC_OPTIONS "--compress;9")
set(CMAKE_AUTOUIC_SEARCH_PATHS ${CMAKE_AUTOUIC_SEARCH_PATHS} ${CMAKE_SOURCE_DIR}/ui)
# Set Build Information
configure_file(${CMAKE_SOURCE_DIR}/src/GpgFrontend.h.in ${CMAKE_SOURCE_DIR}/src/GpgFrontend.h @ONLY)
configure_file(${CMAKE_SOURCE_DIR}/src/GpgFrontendBuildInfo.h.in ${CMAKE_SOURCE_DIR}/src/GpgFrontendBuildInfo.h @ONLY)
configure_file(${CMAKE_SOURCE_DIR}/src/GpgFrontendBuildInstallInfo.h.in ${CMAKE_SOURCE_DIR}/src/GpgFrontendBuildInstallInfo.h @ONLY)
configure_file(${CMAKE_SOURCE_DIR}/src/module/sdk/GFSDKBuildInfo.h.in ${CMAKE_SOURCE_DIR}/src/module/sdk/GFSDKBuildInfo.h @ONLY)
configure_file(${CMAKE_SOURCE_DIR}/src/sdk/GFSDKBuildInfo.h.in ${CMAKE_SOURCE_DIR}/src/sdk/GFSDKBuildInfo.h @ONLY)
if (APPLE)
configure_file(${CMAKE_SOURCE_DIR}/resource/plist/ExportOptions.plist.in ${CMAKE_BINARY_DIR}/ExportOptions.plist @ONLY)
endif ()
# Set Runtime Output Directory
if (NOT XCODE_BUILD)
# Set Binary Output Path
@ -91,18 +77,9 @@ else ()
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE})
endif ()
# configure for output path and resources
if (BUILD_APPLICATION)
aux_source_directory(. BASE_SOURCE)
set(APP_ICON_RESOURCE_WINDOWS "${CMAKE_SOURCE_DIR}/gpgfrontend.rc")
set_property(SOURCE gpgfrontend.rc APPEND PROPERTY OBJECT_DEPENDS ${CMAKE_SOURCE_DIR}/gpgfrontend.ico)
endif ()
# Print modules
if (BUILD_CORE)
# core depends pinentry
message("[+] Build Pinentry")
add_subdirectory(pinentry)
message("[+] Build Core")
add_subdirectory(core)
endif ()
@ -112,9 +89,9 @@ if (BUILD_UI)
add_subdirectory(ui)
endif ()
if (BUILD_MODULE)
message("[+] Build Module")
add_subdirectory(module)
if (BUILD_SDK)
message("[+] Build SDK")
add_subdirectory(sdk)
endif ()
# build to test gpgfrontend core
@ -124,6 +101,13 @@ if (BUILD_TEST)
add_subdirectory(test)
endif ()
# configure for output path and resources
if (BUILD_APPLICATION)
aux_source_directory(. BASE_SOURCE)
set(APP_ICON_RESOURCE_WINDOWS "${CMAKE_SOURCE_DIR}/gpgfrontend.rc")
set_property(SOURCE gpgfrontend.rc APPEND PROPERTY OBJECT_DEPENDS ${CMAKE_SOURCE_DIR}/gpgfrontend.ico)
endif ()
if (BUILD_APPLICATION)
# Set Resource Output Path
if (${CMAKE_BUILD_TYPE} STREQUAL "Release")
@ -330,10 +314,10 @@ if (BUILD_APPLICATION)
# include qt dependencies
if(NOT Qt6_DIR)
add_custom_command(TARGET ${AppName} POST_BUILD
COMMAND windeployqt --force ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${AppName}.exe)
COMMAND windeployqt --force --libdir ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} --release ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${AppName}.exe)
else()
add_custom_command(TARGET ${AppName} POST_BUILD
COMMAND windeployqt-qt6.exe --force ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${AppName}.exe)
COMMAND windeployqt-qt6.exe --force --libdir ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} --release ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${AppName}.exe)
endif()
elseif (LINUX AND NOT LINUX_INSTALL_SOFTWARE)
add_executable(${AppName} ${BASE_SOURCE} ${RESOURCE_FILES})
@ -344,17 +328,6 @@ if (BUILD_APPLICATION)
COMMENT "Copying Binary into App Image"
)
add_custom_command(TARGET ${AppName} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/AppDir/usr/plugins"
COMMENT "Complement to build the required architecture"
)
add_custom_command(TARGET ${AppName} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/AppDir/usr/plugins/mods"
COMMAND ${CMAKE_COMMAND} -E rename "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/mods" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/AppDir/usr/plugins/mods"
COMMENT "Copying Mods into App Image"
)
# app bundle packing using xcode
elseif (APPLE AND XCODE_BUILD)
# standard app bundle packing
@ -422,9 +395,22 @@ if (BUILD_APPLICATION)
endif ()
if(STABLE_BUILD_ONLY_APPLICATION)
message(STATUS "Application Headers Search Path: ${CMAKE_INSTALL_PREFIX}/include/gpgfrontend")
target_include_directories(${AppName} PUBLIC "${CMAKE_INSTALL_PREFIX}/include/gpgfrontend")
# link qt
if(GPGFRONTEND_QT5_BUILD)
target_link_libraries(${AppName} Qt5::Core Qt5::Widgets)
else()
target_link_libraries(${AppName} Qt6::Core Qt6::Widgets)
endif()
endif()
# link options for GpgFrontend
if (BUILD_APPLICATION)
target_link_libraries(${AppName} gpgfrontend_ui gpgfrontend_test)
target_link_libraries(${AppName} gpgfrontend_core gpgfrontend_ui gpgfrontend_test)
if (MINGW)
message(STATUS "Link Application Library For MINGW")
target_link_libraries(${AppName} crypto)
@ -436,6 +422,8 @@ if (BUILD_APPLICATION)
endif ()
endif ()
# add i18n support
if (BUILD_APPLICATION)
set(LOCALE_TS_PATH ${CMAKE_SOURCE_DIR}/resource/lfs/locale/ts)
@ -500,30 +488,85 @@ endif()
# if building linux package
if (LINUX AND LINUX_INSTALL_SOFTWARE)
include(GNUInstallDirs)
if(STABLE_BUILD_ONLY_APPLICATION)
set(GPGFRONTEND_INSTALL_LIBRARIES "")
else()
set(GPGFRONTEND_INSTALL_LIBRARIES
mimalloc
spdlog
gpgfrontend_core
gpgfrontend_ui
gpgfrontend_test
gpgfrontend_pinentry
gpgfrontend_module_sdk)
endif()
message(STATUS "GpgFrontend Install Libraries: ${GPGFRONTEND_INSTALL_LIBRARIES}")
install(TARGETS ${AppName} ${GPGFRONTEND_INSTALL_LIBRARIES}
EXPORT GpgFrontendTargets
RUNTIME DESTINATION ${CMAKE_INSTALL_FULL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR})
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(FILES ${CMAKE_SOURCE_DIR}/TRANSLATORS
DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/${AppName}/)
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${AppName}/)
install(FILES ${CMAKE_SOURCE_DIR}/resource/appstream/com.bktus.gpgfrontend.appdata.xml
DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/metainfo/)
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/metainfo/)
install(FILES ${CMAKE_SOURCE_DIR}/resource/appstream/com.bktus.gpgfrontend.desktop
DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/applications/)
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications/)
install(DIRECTORY ${CMAKE_SOURCE_DIR}/resource/lfs/pixmaps/
DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/pixmaps/)
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pixmaps/)
install(DIRECTORY ${CMAKE_SOURCE_DIR}/resource/lfs/hicolor/
DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/icons/hicolor/)
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/)
endif ()
# if only build sdk
if (STABLE_BUILD_ONLY_SDK)
include(GNUInstallDirs)
set(GPGFRONTEND_SDK_INSTALL_LIBRARIES
gpgfrontend_module_sdk)
install(TARGETS ${GPGFRONTEND_SDK_INSTALL_LIBRARIES}
EXPORT GpgFrontendTargets
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif ()
# if build full sdk
if (STABLE_BUILD_FULL_SDK)
include(GNUInstallDirs)
set(GPGFRONTEND_SDK_INSTALL_LIBRARIES
mimalloc
gpgfrontend_core
gpgfrontend_ui
gpgfrontend_test
gpgfrontend_module_sdk)
install(TARGETS ${GPGFRONTEND_SDK_INSTALL_LIBRARIES}
EXPORT GpgFrontendTargets
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/core"
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/gpgfrontend"
FILES_MATCHING
PATTERN "*.h"
)
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/ui"
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/gpgfrontend"
FILES_MATCHING
PATTERN "*.h"
)
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/test"
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/gpgfrontend"
FILES_MATCHING
PATTERN "*.h"
)
endif ()

View File

@ -28,6 +28,10 @@
#pragma once
#include <qapplication.h>
#include <memory>
namespace GpgFrontend {
struct GpgFrontendContext;
@ -38,7 +42,6 @@ using GFCxtSPtr = std::shared_ptr<GpgFrontendContext>;
struct GpgFrontendContext {
int argc;
char** argv;
spdlog::level::level_enum log_level;
bool gather_external_gnupg_info;
bool load_default_gpg_context;

View File

@ -34,7 +34,6 @@
// main
#include "init.h"
#include "main.h"
namespace GpgFrontend {
@ -50,20 +49,18 @@ constexpr int kCrashCode = ~0; ///<
auto StartApplication(const GFCxtWPtr& p_ctx) -> int {
GFCxtSPtr ctx = p_ctx.lock();
if (ctx == nullptr) {
GF_MAIN_LOG_ERROR("cannot get gpgfrontend context.");
qWarning("cannot get gpgfrontend context.");
return -1;
}
auto* app = ctx->GetApp();
if (app == nullptr) {
GF_MAIN_LOG_ERROR("cannot get qapplication from gpgfrontend context.");
qWarning("cannot get QApplication from gpgfrontend context.");
return -1;
}
GF_MAIN_LOG_DEBUG("start running gui application");
/**
* internationalisation. loop to restart main window
* internationalization. loop to restart main window
* with changed translation when settings change.
*/
int return_from_event_loop_code;
@ -79,13 +76,8 @@ auto StartApplication(const GFCxtWPtr& p_ctx) -> int {
// finally create main window
return_from_event_loop_code = GpgFrontend::UI::RunGpgFrontendUI(app);
GF_MAIN_LOG_DEBUG("try to destroy modules system and core");
restart_count++;
GF_MAIN_LOG_DEBUG(
"restart loop refresh, event loop code: {}, restart count: {}",
return_from_event_loop_code, restart_count);
} while (return_from_event_loop_code == GpgFrontend::kRestartCode &&
restart_count < 99);
@ -94,17 +86,10 @@ auto StartApplication(const GFCxtWPtr& p_ctx) -> int {
// then shutdown the core
GpgFrontend::DestroyGpgFrontendCore();
GF_MAIN_LOG_DEBUG("core and modules system destroyed");
// log for debug
GF_MAIN_LOG_INFO("GpgFrontend is about to exit.");
// deep restart mode
if (return_from_event_loop_code == GpgFrontend::kDeepRestartCode ||
return_from_event_loop_code == kCrashCode) {
// log for debug
GF_MAIN_LOG_DEBUG(
"deep restart or cash loop status caught, restart a new application");
QProcess::startDetached(qApp->arguments()[0], qApp->arguments());
};

View File

@ -28,13 +28,16 @@
#include "cmd.h"
#include "core/utils/BuildInfoUtils.h"
#include "main.h"
#include <qdatetime.h>
#include <qglobal.h>
#include <qloggingcategory.h>
#include <qstring.h>
#include <qtextstream.h>
// std
#include <iostream>
#include "core/utils/BuildInfoUtils.h"
// GpgFrontend
#include "GpgFrontendContext.h"
#include "test/GpgFrontendTest.h"
@ -42,7 +45,7 @@ namespace GpgFrontend {
auto PrintVersion() -> int {
QTextStream stream(stdout);
stream << PROJECT_NAME << " " << GetProjectVersion() << '\n';
stream << GetProjectName() << " " << GetProjectVersion() << '\n';
stream << "Copyright (©) 2021 Saturneric <eric@bktus.com>" << '\n'
<< QCoreApplication::tr(
"This is free software; see the source for copying conditions.")
@ -60,30 +63,29 @@ auto PrintVersion() -> int {
return 0;
}
auto ParseLogLevel(const QString& log_level) -> spdlog::level::level_enum {
if (log_level == "trace") {
return spdlog::level::trace;
}
auto ParseLogLevel(const QString& log_level) -> int {
if (log_level == "debug") {
return spdlog::level::debug;
QLoggingCategory::setFilterRules(
"core.debug=true\nui.debug=true\ntest.debug=true\nmodule.debug=true");
} else if (log_level == "info") {
QLoggingCategory::setFilterRules(
"*.debug=false\ncore.info=true\nui.info=true\ntest.info="
"true\nmodule.info=true");
} else if (log_level == "warning") {
QLoggingCategory::setFilterRules("*.debug=false\n*.info=false\n");
} else if (log_level == "critical") {
QLoggingCategory::setFilterRules(
"*.debug=false\n*.info=false\n*.warning=false\n");
} else {
qWarning() << "unknown log level: " << log_level;
}
if (log_level == "info") {
return spdlog::level::info;
}
if (log_level == "warn") {
return spdlog::level::warn;
}
if (log_level == "error") {
return spdlog::level::err;
}
return spdlog::level::info;
return 0;
}
auto RunTest(const GFCxtWPtr& p_ctx) -> int {
GpgFrontend::GFCxtSPtr const ctx = p_ctx.lock();
if (ctx == nullptr) {
GF_MAIN_LOG_ERROR("cannot get gpgfrontend context for test running");
qWarning("cannot get gpgfrontend context for test running");
return -1;
}

View File

@ -36,7 +36,7 @@ namespace GpgFrontend {
auto PrintVersion() -> int;
auto ParseLogLevel(const QString& level) -> spdlog::level::level_enum;
auto ParseLogLevel(const QString& level) -> int;
auto RunTest(const GFCxtWPtr&) -> int;

View File

@ -23,7 +23,7 @@
#
# SPDX-License-Identifier: GPL-3.0-or-later
# gather source files
aux_source_directory(./function/result_analyse CORE_SOURCE)
aux_source_directory(./function/basic CORE_SOURCE)
aux_source_directory(./function/gpg CORE_SOURCE)
@ -37,14 +37,23 @@ aux_source_directory(./utils/aes CORE_SOURCE)
aux_source_directory(./utils CORE_SOURCE)
aux_source_directory(. CORE_SOURCE)
# define libgpgfrontend_core
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
add_library(gpgfrontend_core SHARED ${CORE_SOURCE})
# generate headers
set(_export_file "${CMAKE_CURRENT_SOURCE_DIR}/GpgFrontendCoreExport.h")
generate_export_header(gpgfrontend_core EXPORT_FILE_NAME "${_export_file}")
if(NOT APPLE)
# compile definitions
target_compile_definitions(gpgfrontend_core PUBLIC GF_CORE)
# link options
target_link_libraries(gpgfrontend_core PUBLIC mimalloc)
if(MINGW)
set_target_properties(mimalloc
@ -53,7 +62,6 @@ if(NOT APPLE)
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}"
)
endif()
endif()
# qt-aes
target_sources(gpgfrontend_core PRIVATE
@ -72,15 +80,6 @@ if (MINGW)
target_link_libraries(gpgfrontend_core PUBLIC bcrypt)
endif ()
# spdlog
target_link_libraries(gpgfrontend_core PRIVATE spdlog)
if(MINGW)
set_target_properties(spdlog
PROPERTIES
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}"
)
endif()
# configure libarchive
if(NOT MINGW)
@ -123,6 +122,13 @@ target_precompile_headers(gpgfrontend_core
# using std c++ 17
target_compile_features(gpgfrontend_core PUBLIC cxx_std_17)
if (${CMAKE_BUILD_TYPE} STREQUAL "Debug")
# lib output path
set_target_properties(gpgfrontend_core PROPERTIES
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/lib
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/lib)
endif()
# link for different platforms
if (MINGW)
message(STATUS "Link GPG Static Library For MINGW")

View File

@ -53,9 +53,13 @@ constexpr const char* PGP_PRIVATE_KEY_BEGIN =
"-----BEGIN PGP PRIVATE KEY BLOCK-----"; ///<
// MODULE ID
const QString kGnuPGInfoGatheringModuleID =
constexpr const char* kGnuPGInfoGatheringModuleID =
"com.bktus.gpgfrontend.module.gnupg_info_gathering";
const QString kVersionCheckingModuleID =
constexpr const char* kVersionCheckingModuleID =
"com.bktus.gpgfrontend.module.version_checking";
constexpr const char* kPinentryModuleID =
"com.bktus.gpgfrontend.module.pinentry";
constexpr const char* kPaperKeyModuleID =
"com.bktus.gpgfrontend.module.paper_key";
} // namespace GpgFrontend

View File

@ -78,7 +78,6 @@ auto SearchGpgconfPath(const QList<QString>& candidate_paths) -> QString {
auto SearchKeyDatabasePath(const QList<QString>& candidate_paths) -> QString {
for (const auto& path : candidate_paths) {
GF_CORE_LOG_DEBUG("searh for candidate key database path: {}", path);
if (VerifyKeyDatabasePath(QFileInfo(path))) {
return path;
}
@ -97,8 +96,6 @@ auto InitGpgME(const QString& gpgconf_path, const QString& gnupg_path) -> bool {
#endif
if (!gnupg_path.isEmpty()) {
GF_CORE_LOG_DEBUG("gpgme set engine info, gpgconf path: {}, gnupg path: {}",
gpgconf_path, gnupg_path);
CheckGpgError(gpgme_set_engine_info(GPGME_PROTOCOL_GPGCONF,
gpgconf_path.toUtf8(), nullptr));
CheckGpgError(gpgme_set_engine_info(GPGME_PROTOCOL_OpenPGP,
@ -121,15 +118,6 @@ auto InitGpgME(const QString& gpgconf_path, const QString& gnupg_path) -> bool {
continue;
}
GF_CORE_LOG_DEBUG(
"gpg context engine info: {} {} {} {}",
gpgme_get_protocol_name(engine_info->protocol),
QString(engine_info->file_name == nullptr ? "null"
: engine_info->file_name),
QString(engine_info->home_dir == nullptr ? "null"
: engine_info->home_dir),
QString(engine_info->version ? "null" : engine_info->version));
switch (engine_info->protocol) {
case GPGME_PROTOCOL_OpenPGP:
find_openpgp = true;
@ -183,12 +171,11 @@ 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"});
GF_CORE_LOG_DEBUG("got gnupg version from rt: {}", gnupg_version);
// conditional check: only support gpg 2.1.x now
if (!(GFCompareSoftwareVersion(gnupg_version, "2.1.0") >= 0 && find_gpgconf &&
find_openpgp && find_cms)) {
GF_CORE_LOG_ERROR("gpgme env check failed, abort");
qCWarning(core, "gpgme env check failed, abort");
return false;
}
@ -249,8 +236,8 @@ auto DetectGpgConfPath() -> QString {
#endif
if (!VerifyGpgconfPath(QFileInfo(gnupg_install_fs_path))) {
GF_CORE_LOG_ERROR("core loaded custom gpgconf path is illegal: {}",
gnupg_install_fs_path);
qCWarning(core) << "core loaded custom gpgconf path is illegal: "
<< gnupg_install_fs_path;
gnupg_install_fs_path = "";
}
}
@ -260,15 +247,11 @@ auto DetectGpgConfPath() -> QString {
#ifdef MACOS
gnupg_install_fs_path = SearchGpgconfPath(
{"/usr/local/bin/gpgconf", "/opt/homebrew/bin/gpgconf"});
GF_CORE_LOG_DEBUG("core loaded searched gpgconf path: {}",
gnupg_install_fs_path);
#endif
#ifdef WINDOWS
gnupg_install_fs_path =
SearchGpgconfPath({"C:/Program Files (x86)/gnupg/bin"});
GF_CORE_LOG_DEBUG("core loaded searched gpgconf path: {}",
gnupg_install_fs_path);
#endif
}
@ -290,12 +273,12 @@ void InitGpgFrontendCore(CoreInitArgs args) {
Module::UpsertRTValue("core", "env.state.all", 0);
// initialize locale environment
GF_CORE_LOG_DEBUG("locale: {}", setlocale(LC_CTYPE, nullptr));
qCDebug(core, "locale info: %s", setlocale(LC_CTYPE, nullptr));
auto gpgconf_install_fs_path = DetectGpgConfPath();
auto gnupg_install_fs_path = DetectGnuPGPath(gpgconf_install_fs_path);
GF_CORE_LOG_INFO("detected gpgconf path: {}", gpgconf_install_fs_path);
GF_CORE_LOG_INFO("detected gnupg path: {}", gnupg_install_fs_path);
qCInfo(core) << "detected gpgconf path: " << gpgconf_install_fs_path;
qCInfo(core) << "detected gnupg path: " << gnupg_install_fs_path;
// initialize library gpgme
if (!InitGpgME(gpgconf_install_fs_path, gnupg_install_fs_path)) {
@ -334,11 +317,6 @@ void InitGpgFrontendCore(CoreInitArgs args) {
QString::fromLocal8Bit(qgetenv("container")) != "flatpak")
.toBool();
GF_CORE_LOG_DEBUG("core loaded if use custom key databse path: {}",
use_custom_key_database_path);
GF_CORE_LOG_DEBUG("core loaded custom key databse path: {}",
custom_key_database_path);
// check key database path
QString key_database_fs_path;
// user defined
@ -346,21 +324,17 @@ void InitGpgFrontendCore(CoreInitArgs args) {
!custom_key_database_path.isEmpty()) {
key_database_fs_path = custom_key_database_path;
if (VerifyKeyDatabasePath(QFileInfo(key_database_fs_path))) {
GF_CORE_LOG_ERROR(
"core loaded custom gpg key database is illegal: {}",
key_database_fs_path);
qCWarning(core)
<< "core loaded custom gpg key database is illegal: "
<< key_database_fs_path;
} else {
use_custom_key_database_path = true;
GF_CORE_LOG_DEBUG("core loaded custom gpg key database path: {}",
key_database_fs_path);
}
} else {
#if defined(LINUX) || defined(MACOS)
use_custom_key_database_path = true;
key_database_fs_path =
SearchKeyDatabasePath({QDir::home().path() + "/.gnupg"});
GF_CORE_LOG_DEBUG("core loaded searched key database path: {}",
key_database_fs_path);
#endif
}
@ -377,13 +351,11 @@ void InitGpgFrontendCore(CoreInitArgs args) {
if (dir_info.exists() && dir_info.isDir() &&
dir_info.isReadable() && dir_info.isWritable()) {
args.db_path = dir_info.absoluteFilePath();
GF_CORE_LOG_INFO("using key database path: {}",
args.db_path);
} else {
GF_CORE_LOG_ERROR(
"custom key database path: {}, is not point to "
"an accessible directory",
key_database_fs_path);
qCWarning(core)
<< "custom key database path: " << key_database_fs_path
<< ", is not point to "
"an accessible directory";
}
}
@ -404,7 +376,7 @@ void InitGpgFrontendCore(CoreInitArgs args) {
// exit if failed
if (!ctx.Good()) {
GF_CORE_LOG_ERROR("default gnupg context init error, abort");
qCWarning(core, "default gnupg context init error, abort");
CoreSignalStation::GetInstance()->SignalBadGnupgEnv(
QCoreApplication::tr("GpgME Context initiation failed"));
return -1;
@ -415,11 +387,12 @@ void InitGpgFrontendCore(CoreInitArgs args) {
if (args.load_default_gpg_context) {
if (!GpgKeyGetter::GetInstance().FlushKeyCache()) {
CoreSignalStation::GetInstance()->SignalBadGnupgEnv(
QCoreApplication::tr("Gpg Key Detabase initiation failed"));
QCoreApplication::tr("Gpg Key Database initiation failed"));
};
}
GF_CORE_LOG_DEBUG(
qCDebug(
core,
"basic env checking finished, including gpgme, ctx, and key infos");
Module::UpsertRTValue("core", "env.state.basic", 1);

View File

@ -27,3 +27,5 @@
*/
#include "core/GpgFrontendCore.h"
Q_LOGGING_CATEGORY(core, "core")

View File

@ -30,3 +30,11 @@
// Qt
#include <QtCore>
// declare area of core
#ifdef GF_CORE
// declare logging category
Q_DECLARE_LOGGING_CATEGORY(core)
#endif

View File

@ -46,14 +46,14 @@ auto CopyData(struct archive *ar, struct archive *aw) -> int {
r = archive_read_data_block(ar, &buff, &size, &offset);
if (r == ARCHIVE_EOF) return (ARCHIVE_OK);
if (r != ARCHIVE_OK) {
GF_CORE_LOG_ERROR("archive_read_data_block() failed: {}",
archive_error_string(ar));
qCWarning(core) << "archive_read_data_block() failed: "
<< archive_error_string(ar);
return (r);
}
r = archive_write_data_block(aw, buff, size, offset);
if (r != ARCHIVE_OK) {
GF_CORE_LOG_ERROR("archive_write_data_block() failed: {}",
archive_error_string(aw));
qCWarning(core) << "archive_write_data_block() failed: "
<< archive_error_string(aw);
return (r);
}
}
@ -113,7 +113,7 @@ void ArchiveFileOperator::NewArchive2DataExchanger(
#endif
if (r != ARCHIVE_OK) {
GF_CORE_LOG_ERROR("archive_read_disk_open() failed: {}, abort...",
qCWarning(core, "archive_read_disk_open() failed: %s, abort...",
archive_error_string(disk));
archive_read_free(disk);
archive_write_free(archive);
@ -125,8 +125,9 @@ void ArchiveFileOperator::NewArchive2DataExchanger(
r = archive_read_next_header2(disk, entry);
if (r == ARCHIVE_EOF) break;
if (r != ARCHIVE_OK) {
GF_CORE_LOG_ERROR(
"archive_read_next_header2() failed, ret: {}, explain: {}", r,
qCWarning(
core,
"archive_read_next_header2() failed, ret: %d, explain: %s", r,
archive_error_string(disk));
ret = -1;
break;
@ -164,15 +165,15 @@ void ArchiveFileOperator::NewArchive2DataExchanger(
r = archive_write_header(archive, entry);
if (r < ARCHIVE_OK) {
GF_CORE_LOG_ERROR(
"archive_write_header() failed, ret: {}, explain: {} ", r,
archive_error_string(archive));
qCWarning(core,
"archive_write_header() failed, ret: %d, explain: %s",
r, archive_error_string(archive));
continue;
}
if (r == ARCHIVE_FATAL) {
GF_CORE_LOG_ERROR(
"archive_write_header() failed, ret: {}, explain: {}, "
qCWarning(core,
"archive_write_header() failed, ret: %d, explain: %s, "
"abort ...",
r, archive_error_string(archive));
ret = -1;
@ -201,7 +202,6 @@ void ArchiveFileOperator::NewArchive2DataExchanger(
void ArchiveFileOperator::ExtractArchiveFromDataExchanger(
std::shared_ptr<GFDataExchanger> ex, const QString &target_path,
const OperationCallback &cb) {
GF_CORE_LOG_INFO("target path: {}", target_path);
RunIOOperaAsync(
[=](const DataObjectPtr &data_object) -> GFError {
auto *archive = archive_read_new();
@ -209,16 +209,16 @@ void ArchiveFileOperator::ExtractArchiveFromDataExchanger(
auto r = archive_read_support_filter_all(archive);
if (r != ARCHIVE_OK) {
GF_CORE_LOG_ERROR(
"archive_read_support_filter_all(), ret: {}, reason: {}", r,
qCWarning(core,
"archive_read_support_filter_all(), ret: %d, reason: %s", r,
archive_error_string(archive));
return r;
}
r = archive_read_support_format_all(archive);
if (r != ARCHIVE_OK) {
GF_CORE_LOG_ERROR(
"archive_read_support_format_all(), ret: {}, reason: {}", r,
qCWarning(core,
"archive_read_support_format_all(), ret: %d, reason: %s", r,
archive_error_string(archive));
return r;
}
@ -230,15 +230,15 @@ void ArchiveFileOperator::ExtractArchiveFromDataExchanger(
nullptr);
if (r != ARCHIVE_OK) {
GF_CORE_LOG_ERROR("archive_read_open(), ret: {}, reason: {}", r,
qCWarning(core, "archive_read_open(), ret: %d, reason: %s", r,
archive_error_string(archive));
return r;
}
r = archive_write_disk_set_options(ext, 0);
if (r != ARCHIVE_OK) {
GF_CORE_LOG_ERROR(
"archive_write_disk_set_options(), ret: {}, reason: {}", r,
qCWarning(core,
"archive_write_disk_set_options(), ret: %d, reason: %s", r,
archive_error_string(archive));
return r;
}
@ -248,7 +248,7 @@ void ArchiveFileOperator::ExtractArchiveFromDataExchanger(
r = archive_read_next_header(archive, &entry);
if (r == ARCHIVE_EOF) break;
if (r != ARCHIVE_OK) {
GF_CORE_LOG_ERROR("archive_read_next_header(), ret: {}, reason: {}",
qCWarning(core, "archive_read_next_header(), ret: %d, reason: %s",
r, archive_error_string(archive));
break;
}
@ -267,7 +267,7 @@ void ArchiveFileOperator::ExtractArchiveFromDataExchanger(
r = archive_write_header(ext, entry);
if (r != ARCHIVE_OK) {
GF_CORE_LOG_ERROR("archive_write_header(), ret: {}, reason: {}", r,
qCWarning(core, "archive_write_header(), ret: %d, reason: %s", r,
archive_error_string(archive));
} else {
r = CopyData(archive, ext);
@ -276,12 +276,12 @@ void ArchiveFileOperator::ExtractArchiveFromDataExchanger(
r = archive_read_free(archive);
if (r != ARCHIVE_OK) {
GF_CORE_LOG_ERROR("archive_read_free(), ret: {}, reason: {}", r,
qCWarning(core, "archive_read_free(), ret: %d, reason: %s", r,
archive_error_string(archive));
}
r = archive_write_free(ext);
if (r != ARCHIVE_OK) {
GF_CORE_LOG_ERROR("archive_read_free(), ret: {}, reason: {}", r,
qCWarning(core, "archive_read_free(), ret: %d, reason: %s", r,
archive_error_string(archive));
}
@ -302,8 +302,8 @@ void ArchiveFileOperator::ListArchive(const QString &archive_path) {
10240); // Note 1
if (r != ARCHIVE_OK) return;
while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
GF_CORE_LOG_DEBUG("File: {}", archive_entry_pathname(entry));
GF_CORE_LOG_DEBUG("File Path: {}", archive_entry_pathname(entry));
qCDebug(core, core, "File: %s", archive_entry_pathname(entry));
qCDebug(core, core, "File Path: %s", archive_entry_pathname(entry));
archive_read_data_skip(a); // Note 2
}
r = archive_read_free(a); // Note 3

View File

@ -107,7 +107,6 @@ class CacheManager::Impl : public QObject {
durable_cache_storage_.insert(key, value);
if (!key_storage_.contains(key)) {
GF_CORE_LOG_DEBUG("register new key of cache", key);
key_storage_.push_back(key);
}
@ -126,8 +125,8 @@ class CacheManager::Impl : public QObject {
return {};
}
auto LoadDurableCache(const QString& key, QJsonDocument default_value)
-> QJsonDocument {
auto LoadDurableCache(const QString& key,
QJsonDocument default_value) -> QJsonDocument {
auto data_object_key = get_data_object_key(key);
if (!durable_cache_storage_.exists(key)) {
durable_cache_storage_.insert(
@ -165,9 +164,10 @@ class CacheManager::Impl : public QObject {
*
*/
void slot_flush_cache_storage() {
qCDebug(core, "write cache to file system...");
for (const auto& cache : durable_cache_storage_.mirror()) {
auto key = get_data_object_key(cache.first);
GF_CORE_LOG_TRACE("save cache into filesystem, key {}", key);
GpgFrontend::DataObjectOperator::GetInstance().SaveDataObj(
key, QJsonDocument(cache.second));
}
@ -215,7 +215,7 @@ class CacheManager::Impl : public QObject {
*
*/
void load_all_cache_storage() {
GF_CORE_LOG_DEBUG("start to load all cache from file system");
qCDebug(core, "start to load all cache from file system");
auto stored_data =
GpgFrontend::DataObjectOperator::GetInstance().GetDataObject(drk_key_);
@ -258,9 +258,8 @@ auto CacheManager::LoadDurableCache(const QString& key) -> QJsonDocument {
return p_->LoadDurableCache(key);
}
auto CacheManager::LoadDurableCache(const QString& key,
QJsonDocument default_value)
-> QJsonDocument {
auto CacheManager::LoadDurableCache(
const QString& key, QJsonDocument default_value) -> QJsonDocument {
return p_->LoadDurableCache(key, std::move(default_value));
}

View File

@ -58,12 +58,6 @@ class GPGFRONTEND_CORE_EXPORT CoreSignalStation : public QObject {
*/
void SignalNeedUserInputPassphrase(QSharedPointer<GpgPassphraseContext>);
/**
* @brief
*
*/
void SignalUserInputPassphraseCallback(QSharedPointer<GpgPassphraseContext>);
/**
* @brief
*

View File

@ -36,7 +36,6 @@
namespace GpgFrontend {
void DataObjectOperator::init_app_secure_key() {
GF_CORE_LOG_INFO("initializing application secure key...");
WriteFile(app_secure_key_path_,
PassphraseGenerator::GetInstance().Generate(256).toUtf8());
QFile::setPermissions(app_secure_key_path_,
@ -50,8 +49,8 @@ DataObjectOperator::DataObjectOperator(int channel)
QByteArray key;
if (!ReadFile(app_secure_key_path_, key)) {
GF_CORE_LOG_ERROR("failed to read app secure key file: {}",
app_secure_key_path_);
qCWarning(core) << "failed to read app secure key file: "
<< app_secure_key_path_;
// unsafe mode
key = {};
}
@ -85,8 +84,6 @@ auto DataObjectOperator::SaveDataObj(const QString& key,
QAESEncryption(QAESEncryption::AES_256, QAESEncryption::ECB,
QAESEncryption::Padding::ISO)
.encode(value.toJson(), hash_key_);
GF_CORE_LOG_TRACE("saving data object {} to disk {} , size: {} bytes",
hash_obj_key, target_obj_path, encoded_data.size());
// recreate if not exists
if (!QDir(app_data_objs_path_).exists()) {
@ -94,7 +91,7 @@ auto DataObjectOperator::SaveDataObj(const QString& key,
}
if (!WriteFile(target_obj_path, encoded_data)) {
GF_CORE_LOG_ERROR("failed to write data object to disk: {}", key);
qCWarning(core) << "failed to write data object to disk: " << key;
}
return key.isEmpty() ? hash_obj_key : QString();
}
@ -102,20 +99,19 @@ auto DataObjectOperator::SaveDataObj(const QString& key,
auto DataObjectOperator::GetDataObject(const QString& key)
-> std::optional<QJsonDocument> {
try {
GF_CORE_LOG_TRACE("try to get data object from disk, key: {}", key);
auto hash_obj_key = QCryptographicHash::hash(hash_key_ + key.toUtf8(),
QCryptographicHash::Sha256)
.toHex();
const auto obj_path = app_data_objs_path_ + "/" + hash_obj_key;
if (!QFileInfo(obj_path).exists()) {
GF_CORE_LOG_WARN("data object not found from disk, key: {}", key);
qCWarning(core) << "data object not found from disk, key: " << key;
return {};
}
QByteArray encoded_data;
if (!ReadFile(obj_path, encoded_data)) {
GF_CORE_LOG_ERROR("failed to read data object from disk, key: {}", key);
qCWarning(core) << "failed to read data object from disk, key: " << key;
return {};
}
@ -124,11 +120,11 @@ auto DataObjectOperator::GetDataObject(const QString& key)
auto decoded_data =
encryption.removePadding(encryption.decode(encoded_data, hash_key_));
GF_CORE_LOG_TRACE("data object has been decoded, key: {}, data: {}", key,
decoded_data);
return QJsonDocument::fromJson(decoded_data);
} catch (...) {
GF_CORE_LOG_ERROR("failed to get data object, caught exception: {}", key);
qCWarning(core) << "failed to get data object:" << key
<< " caught exception.";
return {};
}
}

View File

@ -40,13 +40,11 @@ class GlobalSettingStation::Impl {
*
*/
explicit Impl() noexcept {
GF_CORE_LOG_INFO("app path: {}", GetAppDir());
GF_CORE_LOG_INFO("app working path: {}", working_path_);
qCInfo(core) << "app path: " << GetAppDir();
qCInfo(core) << "app working path: " << working_path_;
auto portable_file_path = working_path_ + "/PORTABLE.txt";
if (QFileInfo(portable_file_path).exists()) {
GF_CORE_LOG_INFO(
"dectected portable mode, reconfiguring config and data path...");
Module::UpsertRTValue("core", "env.state.portable", 1);
app_data_path_ = working_path_;
@ -56,11 +54,11 @@ class GlobalSettingStation::Impl {
portable_mode_ = true;
}
GF_CORE_LOG_INFO("app data path: {}", app_data_path_);
GF_CORE_LOG_INFO("app log path: {}", app_log_path_);
qCInfo(core) << "app data path: " << app_data_path_;
qCInfo(core) << "app log path: " << app_log_path_;
#ifdef WINDOWS
GF_CORE_LOG_INFO("app config path: {}", app_config_path_);
qCInfo(core) << "app config path: " << app_config_path_;
#endif
#ifdef WINDOWS

View File

@ -28,6 +28,8 @@
#pragma once
#include <qsettings.h>
#include "core/function/basic/GpgFunctionObject.h"
namespace GpgFrontend {

View File

@ -28,6 +28,7 @@
#include "KeyPackageOperator.h"
#include <qglobal.h>
#include <qt-aes/qaesencryption.h>
#include "core/function/KeyPackageOperator.h"
@ -44,7 +45,7 @@ namespace GpgFrontend {
auto KeyPackageOperator::GeneratePassphrase(const QString& phrase_path,
QString& phrase) -> bool {
phrase = PassphraseGenerator::GetInstance().Generate(256);
GF_CORE_LOG_DEBUG("generated passphrase: {} bytes", phrase.size());
qCDebug(core, "generated passphrase: %lld bytes", phrase.size());
return WriteFile(phrase_path, phrase.toUtf8());
}
@ -53,13 +54,11 @@ void KeyPackageOperator::GenerateKeyPackage(const QString& key_package_path,
const KeyArgsList& keys,
QString& phrase, bool secret,
const OperationCallback& cb) {
GF_CORE_LOG_DEBUG("generating key package: {}", key_package_name);
GpgKeyImportExporter::GetInstance().ExportAllKeys(
keys, secret, true, [=](GpgError err, const DataObjectPtr& data_obj) {
if (CheckGpgError(err) != GPG_ERR_NO_ERROR) {
GF_LOG_ERROR("export keys error, reason: {}",
DescribeGpgErrCode(err).second);
qCWarning(core) << "export keys error, reason: "
<< DescribeGpgErrCode(err).second;
cb(-1, data_obj);
return;
}
@ -78,7 +77,6 @@ void KeyPackageOperator::GenerateKeyPackage(const QString& key_package_path,
QAESEncryption encryption(QAESEncryption::AES_256, QAESEncryption::ECB,
QAESEncryption::Padding::ISO);
auto encoded_data = encryption.encode(data, hash_key);
GF_CORE_LOG_DEBUG("writing key package, name: {}", key_package_name);
cb(WriteFile(key_package_path, encoded_data) ? 0 : -1,
TransferParams());
@ -91,20 +89,18 @@ void KeyPackageOperator::ImportKeyPackage(const QString& key_package_path,
const OperationCallback& cb) {
RunOperaAsync(
[=](const DataObjectPtr& data_object) -> GFError {
GF_CORE_LOG_DEBUG("importing key package: {}", key_package_path);
QByteArray encrypted_data;
ReadFile(key_package_path, encrypted_data);
if (encrypted_data.isEmpty()) {
GF_CORE_LOG_ERROR("failed to read key package: {}", key_package_path);
qCWarning(core) << "failed to read key package: " << key_package_path;
return -1;
};
QByteArray passphrase;
ReadFile(phrase_path, passphrase);
if (passphrase.size() != 256) {
GF_CORE_LOG_ERROR("passphrase size mismatch: {}", phrase_path);
qCWarning(core) << "passphrase size mismatch: " << phrase_path;
return -1;
}

View File

@ -1,155 +0,0 @@
/**
* Copyright (C) 2021 Saturneric <eric@bktus.com>
*
* 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 <eric@bktus.com> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "LoggerManager.h"
#include <spdlog/async.h>
#include <spdlog/common.h>
#include <spdlog/sinks/rotating_file_sink.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include "core/function/GlobalSettingStation.h"
namespace GpgFrontend {
std::shared_ptr<spdlog::logger> LoggerManager::default_logger = nullptr;
spdlog::level::level_enum LoggerManager::default_log_level =
spdlog::level::debug;
LoggerManager::LoggerManager(int channel)
: SingletonFunctionObject<LoggerManager>(channel) {
spdlog::init_thread_pool(1024, 2);
spdlog::flush_every(std::chrono::seconds(5));
}
LoggerManager::~LoggerManager() {
#ifdef WINDOWS
// Under VisualStudio, this must be called before main finishes to workaround
// a known VS issue
spdlog::drop_all();
spdlog::shutdown();
#endif
if (default_logger) default_logger = nullptr;
}
auto LoggerManager::GetLogger(const QString& id)
-> std::shared_ptr<spdlog::logger> {
auto m_it = logger_map_.find(id);
if (m_it == logger_map_.end()) return GetDefaultLogger();
return m_it->second;
}
auto LoggerManager::RegisterAsyncLogger(const QString& id,
spdlog::level::level_enum level)
-> std::shared_ptr<spdlog::logger> {
// get the log directory
auto log_file_path =
GlobalSettingStation::GetInstance().GetLogDir() + "/" + id + ".log";
// sinks
std::vector<spdlog::sink_ptr> sinks;
sinks.push_back(GpgFrontend::SecureCreateSharedObject<
spdlog::sinks::stderr_color_sink_mt>());
sinks.push_back(GpgFrontend::SecureCreateSharedObject<
spdlog::sinks::rotating_file_sink_mt>(
log_file_path.toUtf8().constData(), 1048576 * 32, 8));
// logger
auto logger = GpgFrontend::SecureCreateSharedObject<spdlog::async_logger>(
id.toStdString(), begin(sinks), end(sinks), spdlog::thread_pool());
logger->set_pattern(
"[%H:%M:%S.%e] [T:%t] [%=6n] %^[%=8l]%$ [%s:%#] [%!] -> %v (+%ius)");
// set the level of logger
logger->set_level(level);
// flush policy
#ifdef DEBUG
logger->flush_on(spdlog::level::trace);
#else
logger->flush_on(spdlog::level::err);
#endif
logger_map_[id] = logger;
return logger;
}
auto LoggerManager::RegisterSyncLogger(const QString& id,
spdlog::level::level_enum level)
-> std::shared_ptr<spdlog::logger> {
// get the log directory
auto log_file_path =
GlobalSettingStation::GetInstance().GetLogDir() + "/" + id + ".log";
// sinks
std::vector<spdlog::sink_ptr> sinks;
sinks.push_back(GpgFrontend::SecureCreateSharedObject<
spdlog::sinks::stderr_color_sink_mt>());
sinks.push_back(GpgFrontend::SecureCreateSharedObject<
spdlog::sinks::rotating_file_sink_mt>(
log_file_path.toUtf8().constData(), 1048576 * 32, 8));
// logger
auto logger = GpgFrontend::SecureCreateSharedObject<spdlog::logger>(
id.toStdString(), begin(sinks), end(sinks));
logger->set_pattern(
"[%H:%M:%S.%e] [T:%t] [%=6n] %^[%=8l]%$ [%s:%#] [%!] -> %v (+%ius)");
// set the level of logger
logger->set_level(level);
logger_map_[id] = logger;
return logger;
}
auto LoggerManager::GetDefaultLogger() -> std::shared_ptr<spdlog::logger> {
if (default_logger == nullptr) {
// sinks
std::vector<spdlog::sink_ptr> sinks;
sinks.push_back(GpgFrontend::SecureCreateSharedObject<
spdlog::sinks::stderr_color_sink_mt>());
// logger
auto logger = GpgFrontend::SecureCreateSharedObject<spdlog::logger>(
"default", begin(sinks), end(sinks));
logger->set_pattern(
"[%H:%M:%S.%e] [T:%t] [%=6n] %^[%=8l]%$ [%s:%#] [%!] -> %v (+%ius)");
// set the level of logger
logger->set_level(default_log_level);
spdlog::set_default_logger(logger);
default_logger = logger;
}
return default_logger;
}
void LoggerManager::SetDefaultLogLevel(spdlog::level::level_enum level) {
default_log_level = level;
}
} // namespace GpgFrontend

View File

@ -1,65 +0,0 @@
/**
* Copyright (C) 2021 Saturneric <eric@bktus.com>
*
* 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 <eric@bktus.com> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#pragma once
#include "core/function/basic/GpgFunctionObject.h"
namespace spdlog {
class logger;
}
namespace GpgFrontend {
class GPGFRONTEND_CORE_EXPORT LoggerManager
: public SingletonFunctionObject<LoggerManager> {
public:
explicit LoggerManager(int channel);
~LoggerManager() override;
auto RegisterAsyncLogger(const QString& id, spdlog::level::level_enum)
-> std::shared_ptr<spdlog::logger>;
auto RegisterSyncLogger(const QString& id, spdlog::level::level_enum)
-> std::shared_ptr<spdlog::logger>;
auto GetLogger(const QString& id) -> std::shared_ptr<spdlog::logger>;
static auto GetDefaultLogger() -> std::shared_ptr<spdlog::logger>;
static void SetDefaultLogLevel(spdlog::level::level_enum);
private:
static spdlog::level::level_enum default_log_level;
static std::shared_ptr<spdlog::logger> default_logger;
std::map<QString, std::shared_ptr<spdlog::logger>> logger_map_;
};
} // namespace GpgFrontend

View File

@ -28,36 +28,20 @@
#include "SecureMemoryAllocator.h"
#if !defined(MACOS) && defined(DEBUG)
#include <mimalloc.h>
#endif
namespace GpgFrontend {
auto SecureMemoryAllocator::Allocate(std::size_t size) -> void* {
#if !defined(MACOS) && defined(DEBUG)
auto* addr = mi_malloc(size);
#else
auto* addr = malloc(size);
#endif
return addr;
}
auto SecureMemoryAllocator::Reallocate(void* ptr, std::size_t size) -> void* {
#if !defined(MACOS) && defined(DEBUG)
auto* addr = mi_realloc(ptr, size);
#else
auto* addr = realloc(ptr, size);
#endif
return addr;
}
void SecureMemoryAllocator::Deallocate(void* p) {
#if !defined(MACOS) && defined(DEBUG)
mi_free(p);
#else
free(p);
#endif
}
void SecureMemoryAllocator::Deallocate(void* p) { mi_free(p); }
} // namespace GpgFrontend

View File

@ -29,7 +29,6 @@
#pragma once
#include "core/GpgFrontendCoreExport.h"
#include "core/utils/LogUtils.h"
namespace GpgFrontend {

View File

@ -39,7 +39,7 @@ ChannelObject::ChannelObject(int channel, QString type)
#ifdef DEBUG
ChannelObject::~ChannelObject() noexcept {
// using iostream instead of spdlog bacause at this time spdlog may have
// using iostream instead of log bacause at this time log object may have
// already been destroyed.
QTextStream(stdout) << "releasing channel object: " << this->type_
<< Qt::endl;

View File

@ -44,8 +44,8 @@ std::mutex g_function_object_mutex_map_lock;
std::map<size_t, FunctionObjectTypeLockInfo> g_function_object_mutex_map;
namespace GpgFrontend {
auto GetGlobalFunctionObjectChannelLock(const std::type_info& type, int channel)
-> std::mutex& {
auto GetGlobalFunctionObjectChannelLock(const std::type_info& type,
int channel) -> std::mutex& {
std::lock_guard<std::mutex> lock_guard(g_function_object_mutex_map_lock);
auto& channel_map = g_function_object_mutex_map[type.hash_code()];
return channel_map.channel_lock_map[channel];
@ -64,24 +64,17 @@ auto GetGlobalFunctionObjectTypeLock(const std::type_info& type)
* @param channel
* @return T&
*/
auto GetChannelObjectInstance(const std::type_info& type, int channel)
-> ChannelObject* {
GF_DEFAULT_LOG_TRACE("try to get instance of type: {} at channel: {}",
type.name(), channel);
auto GetChannelObjectInstance(const std::type_info& type,
int channel) -> ChannelObject* {
// lock this channel
std::lock_guard<std::mutex> guard(
GetGlobalFunctionObjectChannelLock(type, channel));
auto* p_storage =
SingletonStorageCollection::GetInstance(false)->GetSingletonStorage(type);
GF_DEFAULT_LOG_TRACE("get singleton storage result, p_storage: {}",
static_cast<void*>(p_storage));
auto* p_pbj =
static_cast<ChannelObject*>(p_storage->FindObjectInChannel(channel));
GF_DEFAULT_LOG_TRACE("find channel object result, channel {}, p_pbj: {}",
channel, static_cast<void*>(p_pbj));
return p_pbj;
}
@ -95,8 +88,6 @@ auto CreateChannelObjectInstance(const std::type_info& type, int channel,
auto* p_storage =
SingletonStorageCollection::GetInstance(false)->GetSingletonStorage(type);
GF_DEFAULT_LOG_TRACE("create channel object, channel {}, type: {}", channel,
type.name());
// do create object of this channel
return p_storage->SetObjectInChannel(channel, std::move(channel_object));

View File

@ -53,8 +53,7 @@ class SingletonStorage::Impl {
std::shared_lock<std::shared_mutex> lock(instances_mutex_);
ins_it = instances_map_.find(channel);
if (ins_it == instances_map_.end()) {
GF_DEFAULT_LOG_TRACE("cannot find channel object, channel: {}",
channel);
qCDebug(core, "cannot find channel object, channel: %d", channel);
return nullptr;
}
return ins_it->second.get();
@ -72,14 +71,14 @@ class SingletonStorage::Impl {
auto SetObjectInChannel(int channel, ChannelObjectPtr p_obj)
-> GpgFrontend::ChannelObject* {
GF_DEFAULT_LOG_TRACE(
"set channel object, type: {} in channel: {}, address: {}",
typeid(p_obj.get()).name(), channel, static_cast<void*>(p_obj.get()));
qCDebug(core, "set channel object, type: %s in channel: %d, address: %p",
typeid(p_obj.get()).name(), channel,
static_cast<void*>(p_obj.get()));
assert(p_obj != nullptr);
if (p_obj == nullptr) {
GF_DEFAULT_LOG_ERROR(
"cannot set a nullptr as a channel obejct of channel: {}", channel);
qCWarning(core, "cannot set a nullptr as a channel object of channel: %d",
channel);
return nullptr;
}
@ -87,17 +86,16 @@ class SingletonStorage::Impl {
auto* raw_obj = p_obj.get();
{
GF_DEFAULT_LOG_TRACE(
qCDebug(core,
"register channel object to instances map, "
"channel: {}, address: {}",
"channel: %d, address: %p",
channel, static_cast<void*>(p_obj.get()));
std::unique_lock<std::shared_mutex> lock(instances_mutex_);
instances_map_[channel] = std::move(p_obj);
}
GF_DEFAULT_LOG_TRACE(
"set channel: {} success, current channel object address: {}", channel,
static_cast<void*>(raw_obj));
qCDebug(core, "set channel: %d success, current channel object address: %p",
channel, static_cast<void*>(raw_obj));
return raw_obj;
}

View File

@ -49,8 +49,8 @@ class SingletonStorageCollection::Impl {
static auto GetInstance(bool force_refresh) -> SingletonStorageCollection* {
if (force_refresh || global_instance == nullptr) {
global_instance = SecureCreateUniqueObject<SingletonStorageCollection>();
GF_DEFAULT_LOG_TRACE(
"a new global singleton storage collection created, address: {}",
qCDebug(core,
"a new global singleton storage collection created, address: %p",
static_cast<void*>(global_instance.get()));
}
return global_instance.get();
@ -80,10 +80,6 @@ class SingletonStorageCollection::Impl {
}
if (ins_it == storages_map_.end()) {
auto storage = SecureCreateUniqueObject<SingletonStorage>();
GF_DEFAULT_LOG_TRACE(
"hash: {} created, singleton storage address: {} type_name: {}",
hash, static_cast<void*>(storage.get()), type_id.name());
{
std::unique_lock<std::shared_mutex> lock(storages_mutex_);
storages_map_.insert({hash, std::move(storage)});
@ -110,8 +106,9 @@ auto GpgFrontend::SingletonStorageCollection::GetInstance(bool force_refresh)
}
void SingletonStorageCollection::Destroy() {
GF_DEFAULT_LOG_TRACE(
"global singleton storage collection is about to destroy, address: {}",
qCDebug(
core,
"global singleton storage collection is about to destroy, address: %p",
static_cast<void*>(global_instance.get()));
return SingletonStorageCollection::Impl::Destroy();
}

View File

@ -39,10 +39,9 @@ void GpgFrontend::GpgAdvancedOperator::ClearGpgPasswordCache(
OperationCallback cb) {
const auto gpgconf_path = Module::RetrieveRTValueTypedOrDefault<>(
"core", "gpgme.ctx.gpgconf_path", QString{});
GF_CORE_LOG_DEBUG("got gpgconf path from rt: {}", gpgconf_path);
if (gpgconf_path.isEmpty()) {
GF_CORE_LOG_ERROR("cannot get valid gpgconf path from rt, abort.");
qCWarning(core, "cannot get valid gpgconf path from rt, abort.");
cb(-1, TransferParams());
return;
}
@ -51,7 +50,6 @@ void GpgFrontend::GpgAdvancedOperator::ClearGpgPasswordCache(
{gpgconf_path, QStringList{"--reload", "gpg-agent"},
[=](int exit_code, const QString & /*p_out*/,
const QString & /*p_err*/) {
GF_CORE_LOG_DEBUG("gpgconf reload exit code: {}", exit_code);
cb(exit_code == 0 ? 0 : -1, TransferParams());
}});
}
@ -60,10 +58,9 @@ void GpgFrontend::GpgAdvancedOperator::ReloadGpgComponents(
OperationCallback cb) {
const auto gpgconf_path = Module::RetrieveRTValueTypedOrDefault<>(
"core", "gpgme.ctx.gpgconf_path", QString{});
GF_CORE_LOG_DEBUG("got gpgconf path from rt: {}", gpgconf_path);
if (gpgconf_path.isEmpty()) {
GF_CORE_LOG_ERROR("cannot get valid gpgconf path from rt, abort.");
qCWarning(core, "cannot get valid gpgconf path from rt, abort.");
cb(-1, TransferParams());
return;
}
@ -71,7 +68,7 @@ void GpgFrontend::GpgAdvancedOperator::ReloadGpgComponents(
GpgFrontend::GpgCommandExecutor::ExecuteSync(
{gpgconf_path, QStringList{"--reload"},
[=](int exit_code, const QString &, const QString &) {
GF_CORE_LOG_DEBUG("gpgconf reload exit code: {}", exit_code);
qCDebug(core, "gpgconf reload exit code: %d", exit_code);
cb(exit_code == 0 ? 0 : -1, TransferParams());
}});
}
@ -79,58 +76,52 @@ void GpgFrontend::GpgAdvancedOperator::ReloadGpgComponents(
void GpgFrontend::GpgAdvancedOperator::KillAllGpgComponents() {
const auto gpgconf_path = Module::RetrieveRTValueTypedOrDefault<>(
"core", "gpgme.ctx.gpgconf_path", QString{});
GF_CORE_LOG_DEBUG("got gpgconf path from rt: {}", gpgconf_path);
if (gpgconf_path.isEmpty()) {
GF_CORE_LOG_ERROR("cannot get valid gpgconf path from rt, abort.");
qCWarning(core, "cannot get valid gpgconf path from rt, abort.");
return;
}
GpgFrontend::GpgCommandExecutor::ExecuteSync(
{gpgconf_path, QStringList{"--verbose", "--kill", "all"},
[=](int exit_code, const QString &p_out, const QString &p_err) {
GF_CORE_LOG_DEBUG("gpgconf --kill all command got exit code: {}",
exit_code);
bool success = true;
if (exit_code != 0) {
success = false;
GF_CORE_LOG_ERROR(
"gpgconf execute error, process stderr: {}, process stdout: {}",
p_err, p_out);
qCWarning(core) << "gpgconf execute error, process stderr: " << p_err
<< ", process stdout: " << p_out;
return;
}
GF_CORE_LOG_DEBUG("gpgconf --kill --all execute result: {}", success);
qCDebug(core, "gpgconf --kill --all execute result: %d", success);
}});
}
void GpgFrontend::GpgAdvancedOperator::RestartGpgComponents() {
const auto gpgconf_path = Module::RetrieveRTValueTypedOrDefault<>(
"core", "gpgme.ctx.gpgconf_path", QString{});
GF_CORE_LOG_DEBUG("got gpgconf path from rt: {}", gpgconf_path);
if (gpgconf_path.isEmpty()) {
GF_CORE_LOG_ERROR("cannot get valid gpgconf path from rt, abort.");
qCWarning(core, "cannot get valid gpgconf path from rt, abort.");
return;
}
GpgFrontend::GpgCommandExecutor::ExecuteSync(
{gpgconf_path, QStringList{"--verbose", "--kill", "all"},
[=](int exit_code, const QString &p_out, const QString &p_err) {
GF_CORE_LOG_DEBUG("gpgconf --kill all command got exit code: {}",
qCDebug(core, "gpgconf --kill all command got exit code: %d",
exit_code);
bool success = true;
if (exit_code != 0) {
success = false;
GF_CORE_LOG_ERROR(
"gpgconf execute error, process stderr: {}, process stdout: {}",
p_err, p_out);
qCWarning(core) << "gpgconf execute error, process stderr: " << p_err
<< ", process stdout: " << p_out;
return;
}
GF_CORE_LOG_DEBUG("gpgconf --kill --all execute result: {}", success);
qCDebug(core, "gpgconf --kill --all execute result: %d", success);
if (!success) {
GF_CORE_LOG_ERROR(
qCWarning(core,
"restart all component after core initilized failed");
Module::UpsertRTValue(
"core", "gpg_advanced_operator.restart_gpg_components", false);
@ -150,10 +141,9 @@ void GpgFrontend::GpgAdvancedOperator::RestartGpgComponents() {
void GpgFrontend::GpgAdvancedOperator::ResetConfigures(OperationCallback cb) {
const auto gpgconf_path = Module::RetrieveRTValueTypedOrDefault<>(
"core", "gpgme.ctx.gpgconf_path", QString{});
GF_CORE_LOG_DEBUG("got gpgconf path from rt: {}", gpgconf_path);
if (gpgconf_path.isEmpty()) {
GF_CORE_LOG_ERROR("cannot get valid gpgconf path from rt, abort.");
qCWarning(core, "cannot get valid gpgconf path from rt, abort.");
cb(-1, TransferParams());
return;
}
@ -161,7 +151,7 @@ void GpgFrontend::GpgAdvancedOperator::ResetConfigures(OperationCallback cb) {
GpgFrontend::GpgCommandExecutor::ExecuteSync(
{gpgconf_path, QStringList{"--apply-defaults"},
[=](int exit_code, const QString &, const QString &) {
GF_CORE_LOG_DEBUG("gpgconf apply-defaults exit code: {}", exit_code);
qCDebug(core, "gpgconf apply-defaults exit code: %d", exit_code);
cb(exit_code == 0 ? 0 : -1, TransferParams());
}});
}
@ -174,14 +164,12 @@ void GpgFrontend::GpgAdvancedOperator::StartGpgAgent(OperationCallback cb) {
const auto gpg_agent_path = Module::RetrieveRTValueTypedOrDefault<>(
kGnuPGInfoGatheringModuleID, "gnupg.gpg_agent_path", QString{});
GF_CORE_LOG_DEBUG("got gnupg agent path from rt: {}", gpg_agent_path);
const auto home_path = Module::RetrieveRTValueTypedOrDefault<>(
kGnuPGInfoGatheringModuleID, "gnupg.home_path", QString{});
GF_CORE_LOG_DEBUG("got gnupg home path from rt: {}", home_path);
if (gpg_agent_path.isEmpty()) {
GF_CORE_LOG_ERROR("cannot get valid gpg agent path from rt, abort.");
qCWarning(core, "cannot get valid gpg agent path from rt, abort.");
cb(-1, TransferParams());
return;
}
@ -189,7 +177,7 @@ void GpgFrontend::GpgAdvancedOperator::StartGpgAgent(OperationCallback cb) {
GpgFrontend::GpgCommandExecutor::ExecuteSync(
{gpg_agent_path, QStringList{"--homedir", home_path, "--daemon"},
[=](int exit_code, const QString &, const QString &) {
GF_CORE_LOG_DEBUG("gpgconf daemon exit code: {}", exit_code);
qCDebug(core, "gpgconf daemon exit code: %d", exit_code);
cb(exit_code >= 0 ? 0 : -1, TransferParams());
}});
}
@ -202,14 +190,12 @@ void GpgFrontend::GpgAdvancedOperator::StartDirmngr(OperationCallback cb) {
const auto dirmngr_path = Module::RetrieveRTValueTypedOrDefault<>(
kGnuPGInfoGatheringModuleID, "gnupg.dirmngr_path", QString{});
GF_CORE_LOG_DEBUG("got gnupg dirmngr path from rt: {}", dirmngr_path);
const auto home_path = Module::RetrieveRTValueTypedOrDefault<>(
kGnuPGInfoGatheringModuleID, "gnupg.home_path", QString{});
GF_CORE_LOG_DEBUG("got gnupg home path from rt: {}", home_path);
if (dirmngr_path.isEmpty()) {
GF_CORE_LOG_ERROR("cannot get valid dirmngr path from rt, abort.");
qCWarning(core, "cannot get valid dirmngr path from rt, abort.");
cb(-1, TransferParams());
return;
}
@ -217,7 +203,7 @@ void GpgFrontend::GpgAdvancedOperator::StartDirmngr(OperationCallback cb) {
GpgFrontend::GpgCommandExecutor::ExecuteSync(
{dirmngr_path, QStringList{"--homedir", home_path, "--daemon"},
[=](int exit_code, const QString &, const QString &) {
GF_CORE_LOG_DEBUG("gpgconf daemon exit code: {}", exit_code);
qCDebug(core, "gpgconf daemon exit code: %d", exit_code);
cb(exit_code >= 0 ? 0 : -1, TransferParams());
}});
}
@ -230,14 +216,12 @@ void GpgFrontend::GpgAdvancedOperator::StartKeyBoxd(OperationCallback cb) {
const auto keyboxd_path = Module::RetrieveRTValueTypedOrDefault<>(
kGnuPGInfoGatheringModuleID, "gnupg.keyboxd_path", QString{});
GF_CORE_LOG_DEBUG("got gnupg keyboxd path from rt: {}", keyboxd_path);
const auto home_path = Module::RetrieveRTValueTypedOrDefault<>(
kGnuPGInfoGatheringModuleID, "gnupg.home_path", QString{});
GF_CORE_LOG_DEBUG("got gnupg home path from rt: {}", home_path);
if (keyboxd_path.isEmpty()) {
GF_CORE_LOG_ERROR("cannot get valid keyboxd path from rt, abort.");
qCWarning(core, "cannot get valid keyboxd path from rt, abort.");
cb(-1, TransferParams());
return;
}
@ -245,7 +229,7 @@ void GpgFrontend::GpgAdvancedOperator::StartKeyBoxd(OperationCallback cb) {
GpgFrontend::GpgCommandExecutor::ExecuteSync(
{keyboxd_path, QStringList{"--homedir", home_path, "--daemon"},
[=](int exit_code, const QString &, const QString &) {
GF_CORE_LOG_DEBUG("gpgconf daemon exit code: {}", exit_code);
qCDebug(core, "gpgconf daemon exit code: %d", exit_code);
cb(exit_code >= 0 ? 0 : -1, TransferParams());
}});
}

View File

@ -251,10 +251,9 @@ void GpgBasicOperator::Sign(const KeyArgsList& signers,
cb, "gpgme_op_sign", "2.1.0");
}
auto GpgBasicOperator::SignSync(const KeyArgsList& signers,
const GFBuffer& in_buffer, GpgSignMode mode,
bool ascii)
-> std::tuple<GpgError, DataObjectPtr> {
auto GpgBasicOperator::SignSync(
const KeyArgsList& signers, const GFBuffer& in_buffer, GpgSignMode mode,
bool ascii) -> std::tuple<GpgError, DataObjectPtr> {
return RunGpgOperaSync(
[=](const DataObjectPtr& data_object) -> GpgError {
if (signers.empty()) return GPG_ERR_CANCELED;
@ -391,15 +390,14 @@ void GpgBasicOperator::SetSigners(const KeyArgsList& signers, bool ascii) {
gpgme_signers_clear(ctx);
for (const GpgKey& key : signers) {
GF_CORE_LOG_DEBUG("key fpr: {}", key.GetFingerprint());
qCDebug(core) << "signer's key fpr: " << key.GetFingerprint();
if (key.IsHasActualSigningCapability()) {
GF_CORE_LOG_DEBUG("signer");
auto error = gpgme_signers_add(ctx, gpgme_key_t(key));
CheckGpgError(error);
}
}
if (signers.size() != gpgme_signers_count(ctx_.DefaultContext()))
GF_CORE_LOG_DEBUG("not all signers added");
qCDebug(core, "not all signers added");
}
auto GpgBasicOperator::GetSigners(bool ascii) -> std::unique_ptr<KeyArgsList> {

View File

@ -27,6 +27,8 @@
*/
#include "GpgCommandExecutor.h"
#include <qglobal.h>
#include "core/model/DataObject.h"
#include "core/module/Module.h"
#include "core/thread/Task.h"
@ -41,18 +43,14 @@ auto BuildTaskFromExecCtx(const GpgCommandExecutor::ExecuteContext &context)
const auto &interact_function = context.int_func;
const auto &cmd_executor_callback = context.cb_func;
const QString joined_argument = arguments.join(" ");
GF_CORE_LOG_DEBUG("building task: called cmd {} arguments size: {}", cmd,
arguments.size());
Thread::Task::TaskCallback result_callback =
[cmd, joined_argument](int /*rtn*/, const DataObjectPtr &data_object) {
GF_CORE_LOG_DEBUG(
"data object args count of cmd executor result callback: {}",
[cmd](int /*rtn*/, const DataObjectPtr &data_object) {
qCDebug(core,
"data object args count of cmd executor result callback: %ld",
data_object->GetObjectSize());
if (!data_object->Check<int, QString, GpgCommandExecutorCallback>()) {
GF_CORE_LOG_ERROR("data object checking failed");
qCWarning(core, "data object checking failed");
return;
}
@ -61,22 +59,17 @@ auto BuildTaskFromExecCtx(const GpgCommandExecutor::ExecuteContext &context)
auto callback =
ExtractParams<GpgCommandExecutorCallback>(data_object, 2);
// call callback
GF_CORE_LOG_DEBUG(
"calling custom callback from caller of cmd {} {}, "
"exit_code: {}",
cmd, joined_argument, exit_code);
callback(exit_code, process_stdout, {});
};
Thread::Task::TaskRunnable runner =
[joined_argument](const DataObjectPtr &data_object) -> int {
GF_CORE_LOG_DEBUG("process runner called, data object size: {}",
[](const DataObjectPtr &data_object) -> int {
qCDebug(core, "process runner called, data object size: %lu",
data_object->GetObjectSize());
if (!data_object->Check<QString, QStringList, GpgCommandExecutorInteractor,
GpgCommandExecutorCallback>()) {
GF_CORE_LOG_ERROR("data object checking failed");
qCWarning(core, "data object checking failed");
return -1;
}
@ -86,6 +79,7 @@ auto BuildTaskFromExecCtx(const GpgCommandExecutor::ExecuteContext &context)
auto interact_func =
ExtractParams<GpgCommandExecutorInteractor>(data_object, 2);
auto callback = ExtractParams<GpgCommandExecutorCallback>(data_object, 3);
const QString joined_argument = arguments.join(" ");
// create process
auto *cmd_process = new QProcess();
@ -106,26 +100,23 @@ auto BuildTaskFromExecCtx(const GpgCommandExecutor::ExecuteContext &context)
QObject::connect(
cmd_process, &QProcess::started, [cmd, joined_argument]() -> void {
GF_CORE_LOG_DEBUG(
"\n== Process Execute Started ==\nCommand: {}\nArguments: "
"{}\n========================",
cmd, joined_argument);
qCDebug(core) << "\n== Process Execute Started ==\nCommand: " << cmd
<< "\nArguments: " << joined_argument
<< " \n========================";
});
QObject::connect(
cmd_process, &QProcess::readyReadStandardOutput,
[interact_func, cmd_process]() { interact_func(cmd_process); });
QObject::connect(
cmd_process, &QProcess::errorOccurred,
QObject::connect(cmd_process, &QProcess::errorOccurred,
[=](QProcess::ProcessError error) {
GF_CORE_LOG_ERROR(
"caught error while executing command: {} {}, error: {}", cmd,
joined_argument, error);
qCWarning(core)
<< "caught error while executing command: " << cmd
<< joined_argument << ", error:" << error;
});
GF_CORE_LOG_DEBUG(
"\n== Process Execute Ready ==\nCommand: {}\nArguments: "
"{}\n========================",
cmd, joined_argument);
qCDebug(core) << "\n== Process Execute Ready ==\nCommand: " << cmd
<< "\nArguments: " << joined_argument
<< "\n========================";
cmd_process->start();
cmd_process->waitForFinished();
@ -133,15 +124,13 @@ auto BuildTaskFromExecCtx(const GpgCommandExecutor::ExecuteContext &context)
QString process_stdout = cmd_process->readAllStandardOutput();
int exit_code = cmd_process->exitCode();
GF_CORE_LOG_DEBUG(
"\n==== Process Execution Summary ====\n"
"Command: {}\n"
"Arguments: {}\n"
"Exit Code: {}\n"
"---- Standard Output ----\n"
"{}\n"
"===============================",
cmd, joined_argument, exit_code, process_stdout);
qCDebug(core) << "\n==== Process Execution Summary ====\n"
<< "Command: " << cmd << "\n"
<< "Arguments: " << joined_argument << "\n"
<< "Exit Code: " << exit_code << "\n"
<< "---- Standard Output ----\n"
<< process_stdout << "\n"
<< "===============================";
cmd_process->close();
cmd_process->deleteLater();
@ -177,7 +166,7 @@ void GpgCommandExecutor::ExecuteSync(ExecuteContext context) {
// 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.
GF_CORE_LOG_TRACE("blocking until gpg command finish...");
qCDebug(core, "blocking until gpg command finish...");
// block until task finished
// this is to keep reference vaild until task finished
looper.exec();
@ -185,9 +174,6 @@ void GpgCommandExecutor::ExecuteSync(ExecuteContext context) {
void GpgCommandExecutor::ExecuteConcurrentlyAsync(ExecuteContexts contexts) {
for (auto &context : contexts) {
const auto &cmd = context.cmd;
GF_CORE_LOG_INFO("gpg concurrently called cmd {}", cmd);
Thread::Task *task = BuildTaskFromExecCtx(context);
if (context.task_runner != nullptr) {
@ -208,15 +194,15 @@ void GpgCommandExecutor::ExecuteConcurrentlySync(ExecuteContexts contexts) {
for (auto &context : contexts) {
const auto &cmd = context.cmd;
GF_CORE_LOG_DEBUG("gpg concurrently called cmd: {}", cmd);
qCDebug(core) << "gpg concurrently called cmd: " << cmd;
Thread::Task *task = BuildTaskFromExecCtx(context);
QObject::connect(task, &Thread::Task::SignalTaskEnd, [&]() {
--remaining_tasks;
GF_CORE_LOG_DEBUG("remaining tasks: {}", remaining_tasks);
qCDebug(core, "remaining tasks: %lld", remaining_tasks);
if (remaining_tasks <= 0) {
GF_CORE_LOG_DEBUG("no remaining task, quit");
qCDebug(core, "no remaining task, quit");
looper.quit();
}
});
@ -232,7 +218,7 @@ void GpgCommandExecutor::ExecuteConcurrentlySync(ExecuteContexts contexts) {
target_task_runner->PostTask(task);
}
GF_CORE_LOG_TRACE("blocking until concurrent gpg commands finish...");
qCDebug(core, "blocking until concurrent gpg commands finish...");
// block until task finished
// this is to keep reference vaild until task finished
looper.exec();

View File

@ -32,6 +32,7 @@
#include <gpgme.h>
#include <cassert>
#include <cstddef>
#include <mutex>
#include "core/function/CoreSignalStation.h"
@ -77,8 +78,8 @@ class GpgContext::Impl {
[[nodiscard]] auto Good() const -> bool { return good_; }
auto SetPassphraseCb(const gpgme_ctx_t &ctx, gpgme_passphrase_cb_t cb)
-> bool {
auto SetPassphraseCb(const gpgme_ctx_t &ctx,
gpgme_passphrase_cb_t cb) -> bool {
if (gpgme_get_pinentry_mode(ctx) != GPGME_PINENTRY_MODE_LOOPBACK) {
if (CheckGpgError(gpgme_set_pinentry_mode(
ctx, GPGME_PINENTRY_MODE_LOOPBACK)) != GPG_ERR_NO_ERROR) {
@ -92,31 +93,24 @@ class GpgContext::Impl {
static auto TestPassphraseCb(void *opaque, const char *uid_hint,
const char *passphrase_info, int last_was_bad,
int fd) -> gpgme_error_t {
size_t res;
#ifdef QT5_BUILD
QString pass_qstr = "abcdefg\n";
QByteArray pass = pass_qstr.toUtf8();
#else
QString pass = "abcdefg\n";
#endif
auto passpahrase_size = pass.size();
size_t off = 0;
QString passphrase = "abcdefg";
auto pass_bytes = passphrase.toLatin1();
auto pass_size = pass_bytes.size();
const auto *p_pass_bytes = pass_bytes.constData();
ssize_t res = 0;
if (pass_size > 0) {
ssize_t off = 0;
ssize_t ret = 0;
do {
#ifdef QT5_BUILD
const char *p_pass = pass.data();
res = gpgme_io_write(fd, &p_pass[off], passpahrase_size - off);
#else
res = gpgme_io_write(fd, &pass[off], passpahrase_size - off);
#endif
if (res > 0) off += res;
} while (res > 0 && off != passpahrase_size);
ret = gpgme_io_write(fd, &p_pass_bytes[off], pass_size - off);
if (ret > 0) off += ret;
} while (ret > 0 && off != pass_size);
res = off;
}
res += gpgme_io_write(fd, "\n", 1);
return res == passpahrase_size + 1
? 0
: gpgme_error_from_errno(GPG_ERR_CANCELED);
return res == pass_size + 1 ? 0 : gpgme_error_from_errno(GPG_ERR_CANCELED);
}
static auto CustomPassphraseCb(void *hook, const char *uid_hint,
@ -130,47 +124,54 @@ class GpgContext::Impl {
passphrase_info != nullptr ? passphrase_info : "",
prev_was_bad != 0, ask_for_new));
GF_CORE_LOG_DEBUG(
"custom passphrase cb called, uid: {}, info: {}, last_was_bad: {}",
uid_hint == nullptr ? "<empty>" : QString{uid_hint},
passphrase_info == nullptr ? "<empty>" : QString{passphrase_info},
prev_was_bad);
qCDebug(core) << "custom passphrase cb called, uid: "
<< (uid_hint == nullptr ? "<empty>" : QString{uid_hint})
<< ", info: "
<< (passphrase_info == nullptr ? "<empty>"
: QString{passphrase_info})
<< ", last_was_bad: " << prev_was_bad;
QEventLoop looper;
QObject::connect(CoreSignalStation::GetInstance(),
&CoreSignalStation::SignalUserInputPassphraseCallback,
&looper, &QEventLoop::quit);
QString passphrase = "";
Module::TriggerEvent(
"REQUEST_PIN_ENTRY",
{{"uid_hint", uid_hint != nullptr ? uid_hint : ""},
{"passphrase_info", passphrase_info != nullptr ? passphrase_info : ""},
{"prev_was_bad", (prev_was_bad != 0) ? "1" : "0"},
{"ask_for_new", ask_for_new ? "1" : "0"}},
[&passphrase, &looper](Module::EventIdentifier i,
Module::Event::ListenerIdentifier ei,
Module::Event::Params p) {
passphrase = p["passphrase"];
looper.quit();
});
emit CoreSignalStation::GetInstance()->SignalNeedUserInputPassphrase(
context);
looper.exec();
ResetCacheValue("PinentryContext");
auto passphrase = context->GetPassphrase().toStdString();
auto passpahrase_size = passphrase.size();
GF_CORE_LOG_DEBUG("get passphrase from pinentry size: {}",
passpahrase_size);
size_t res = 0;
if (passpahrase_size > 0) {
size_t off = 0;
auto pass_bytes = passphrase.toLatin1();
auto pass_size = pass_bytes.size();
const auto *p_pass_bytes = pass_bytes.constData();
ssize_t res = 0;
if (pass_size > 0) {
ssize_t off = 0;
ssize_t ret = 0;
do {
res = gpgme_io_write(fd, &passphrase[off], passpahrase_size - off);
if (res > 0) off += res;
} while (res > 0 && off != passpahrase_size);
ret = gpgme_io_write(fd, &p_pass_bytes[off], pass_size - off);
if (ret > 0) off += ret;
} while (ret > 0 && off != pass_size);
res = off;
}
res += gpgme_io_write(fd, "\n", 1);
GF_CORE_LOG_DEBUG("custom passphrase cd is about to return, res: {}", res);
return res == passpahrase_size + 1
? 0
: gpgme_error_from_errno(GPG_ERR_CANCELED);
return res == pass_size + 1 ? 0 : gpgme_error_from_errno(GPG_ERR_CANCELED);
}
static auto TestStatusCb(void *hook, const char *keyword, const char *args)
-> gpgme_error_t {
GF_CORE_LOG_DEBUG("keyword {}", keyword);
static auto TestStatusCb(void *hook, const char *keyword,
const char *args) -> gpgme_error_t {
qCDebug(core, "keyword %s", keyword);
return GPG_ERR_NO_ERROR;
}
@ -188,10 +189,11 @@ class GpgContext::Impl {
const auto gpgme_version = Module::RetrieveRTValueTypedOrDefault<>(
"core", "gpgme.version", QString{"0.0.0"});
GF_CORE_LOG_DEBUG("got gpgme version version from rt: {}", gpgme_version);
qCDebug(core) << "got gpgme version version from rt: " << gpgme_version;
if (gpgme_get_keylist_mode(ctx) == 0) {
GF_CORE_LOG_ERROR(
qCWarning(
core,
"ctx is not a valid pointer, reported by gpgme_get_keylist_mode");
return false;
}
@ -210,8 +212,8 @@ class GpgContext::Impl {
const auto database_path = Module::RetrieveRTValueTypedOrDefault<>(
"core", "gpgme.ctx.database_path", QString{});
GF_CORE_LOG_DEBUG("ctx set engine info, db path: {}, app path: {}",
database_path, app_path);
qCDebug(core) << "ctx set engine info, db path: " << database_path
<< ", app path: " << app_path;
auto app_path_buffer = app_path.toUtf8();
auto database_path_buffer = database_path.toUtf8();
@ -232,22 +234,21 @@ class GpgContext::Impl {
assert(ctx != nullptr);
if (args.custom_gpgconf && !args.custom_gpgconf_path.isEmpty()) {
GF_CORE_LOG_DEBUG("set custom gpgconf path: {}",
args.custom_gpgconf_path);
qCDebug(core) << "set custom gpgconf path: " << args.custom_gpgconf_path;
auto err =
gpgme_ctx_set_engine_info(ctx, GPGME_PROTOCOL_GPGCONF,
args.custom_gpgconf_path.toUtf8(), nullptr);
if (CheckGpgError(err) != GPG_ERR_NO_ERROR) {
GF_CORE_LOG_ERROR("set gpg context engine info error: {}",
DescribeGpgErrCode(err).second);
qCWarning(core) << "set gpg context engine info error: "
<< DescribeGpgErrCode(err).second;
return false;
}
}
// set context offline mode
GF_CORE_LOG_DEBUG("gpg context: offline mode: {}", args_.offline_mode);
GF_CORE_LOG_DEBUG("gpg context: auto import missing key: {}",
qCDebug(core, "gpg context: offline mode: %d", args_.offline_mode);
qCDebug(core, "gpg context: auto import missing key: %d",
args_.auto_import_missing_key);
gpgme_set_offline(ctx, args_.offline_mode ? 1 : 0);
@ -260,19 +261,20 @@ class GpgContext::Impl {
}
if (!set_ctx_key_list_mode(ctx)) {
GF_CORE_LOG_DEBUG("set ctx key list mode failed");
qCDebug(core, "set ctx key list mode failed");
return false;
}
// for unit test
if (args_.test_mode) {
if (!SetPassphraseCb(ctx, TestPassphraseCb)) {
GF_CORE_LOG_ERROR("set passphrase cb failed, test");
qCWarning(core, "set passphrase cb failed, test");
return false;
};
} else if (!args_.use_pinentry) {
} else if (!args_.use_pinentry &&
Module::IsModuleActivate(kPinentryModuleID)) {
if (!SetPassphraseCb(ctx, CustomPassphraseCb)) {
GF_CORE_LOG_DEBUG("set passphrase cb failed, custom");
qCDebug(core, "set passphrase cb failed, custom");
return false;
}
}
@ -283,7 +285,7 @@ class GpgContext::Impl {
}
if (!set_ctx_openpgp_engine_info(ctx)) {
GF_CORE_LOG_ERROR("set gpgme context openpgp engine info failed");
qCWarning(core, "set gpgme context openpgp engine info failed");
return false;
}
@ -293,15 +295,15 @@ class GpgContext::Impl {
auto binary_ctx_initialize(const GpgContextInitArgs &args) -> bool {
gpgme_ctx_t p_ctx;
if (auto err = CheckGpgError(gpgme_new(&p_ctx)); err != GPG_ERR_NO_ERROR) {
GF_CORE_LOG_ERROR("get new gpg context error: {}",
DescribeGpgErrCode(err).second);
qCWarning(core) << "get new gpg context error: "
<< DescribeGpgErrCode(err).second;
return false;
}
assert(p_ctx != nullptr);
binary_ctx_ref_ = p_ctx;
if (!common_ctx_initialize(binary_ctx_ref_, args)) {
GF_CORE_LOG_ERROR("get new ctx failed, binary");
qCWarning(core, "get new ctx failed, binary");
return false;
}
@ -312,7 +314,7 @@ class GpgContext::Impl {
auto default_ctx_initialize(const GpgContextInitArgs &args) -> bool {
gpgme_ctx_t p_ctx;
if (CheckGpgError(gpgme_new(&p_ctx)) != GPG_ERR_NO_ERROR) {
GF_CORE_LOG_ERROR("get new ctx failed, default");
qCWarning(core, "get new ctx failed, default");
return false;
}
assert(p_ctx != nullptr);

View File

@ -40,7 +40,7 @@ namespace GpgFrontend {
*
*/
struct GpgContextInitArgs {
QString db_path = {}; ///<
QString db_path; ///<
bool test_mode = false; ///<
bool offline_mode = false; ///<
@ -63,7 +63,7 @@ class GPGFRONTEND_CORE_EXPORT GpgContext
explicit GpgContext(GpgContextInitArgs args, int channel);
virtual ~GpgContext() override;
~GpgContext();
[[nodiscard]] auto Good() const -> bool;

View File

@ -69,10 +69,9 @@ void GpgFileOpera::EncryptFile(const KeyArgsList& keys, const QString& in_path,
cb, "gpgme_op_encrypt", "2.1.0");
}
auto GpgFileOpera::EncryptFileSync(const KeyArgsList& keys,
const QString& in_path, bool ascii,
const QString& out_path)
-> std::tuple<GpgError, DataObjectPtr> {
auto GpgFileOpera::EncryptFileSync(
const KeyArgsList& keys, const QString& in_path, bool ascii,
const QString& out_path) -> std::tuple<GpgError, DataObjectPtr> {
return RunGpgOperaSync(
[=](const DataObjectPtr& data_object) -> GpgError {
std::vector<gpgme_key_t> recipients(keys.begin(), keys.end());
@ -111,7 +110,7 @@ void GpgFileOpera::EncryptDirectory(const KeyArgsList& keys,
GpgData data_in(ex);
GpgData data_out(out_path, false);
GF_CORE_LOG_DEBUG("encrypt directory start");
qCDebug(core, "encrypt directory start");
auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
auto err = CheckGpgError(gpgme_op_encrypt(ctx, recipients.data(),
@ -119,15 +118,14 @@ void GpgFileOpera::EncryptDirectory(const KeyArgsList& keys,
data_in, data_out));
data_object->Swap({GpgEncryptResult(gpgme_op_encrypt_result(ctx))});
GF_CORE_LOG_DEBUG("encrypt directory finished, err: {}", err);
qCDebug(core, "encrypt directory finished, err: %d", err);
return err;
},
cb, "gpgme_op_encrypt", "2.1.0");
ArchiveFileOperator::NewArchive2DataExchanger(
in_path, ex, [=](GFError err, const DataObjectPtr&) {
GF_CORE_LOG_DEBUG("new archive 2 data exchanger operation, err: {}",
err);
qCDebug(core, "new archive 2 data exchanger operation, err: %d", err);
if (decltype(ex) p_ex = w_ex.lock(); err < 0 && p_ex != nullptr) {
ex->CloseWrite();
}
@ -176,8 +174,8 @@ void GpgFileOpera::DecryptArchive(const QString& in_path,
ArchiveFileOperator::ExtractArchiveFromDataExchanger(
ex, out_path, [](GFError err, const DataObjectPtr&) {
GF_CORE_LOG_DEBUG(
"extract archive from data exchanger operation, err: {}", err);
qCDebug(core, "extract archive from data exchanger operation, err: %d",
err);
});
RunGpgOperaAsync(
@ -331,11 +329,10 @@ void GpgFileOpera::EncryptSignFile(const KeyArgsList& keys,
cb, "gpgme_op_encrypt_sign", "2.1.0");
}
auto GpgFileOpera::EncryptSignFileSync(const KeyArgsList& keys,
const KeyArgsList& signer_keys,
auto GpgFileOpera::EncryptSignFileSync(
const KeyArgsList& keys, const KeyArgsList& signer_keys,
const QString& in_path, bool ascii,
const QString& out_path)
-> std::tuple<GpgError, DataObjectPtr> {
const QString& out_path) -> std::tuple<GpgError, DataObjectPtr> {
return RunGpgOperaSync(
[=](const DataObjectPtr& data_object) -> GpgError {
GpgError err;
@ -399,7 +396,7 @@ void GpgFileOpera::EncryptSignDirectory(const KeyArgsList& keys,
ArchiveFileOperator::NewArchive2DataExchanger(
in_path, ex, [=](GFError err, const DataObjectPtr&) {
GF_CORE_LOG_DEBUG("new archive 2 fd operation, err: {}", err);
qCDebug(core, "new archive 2 fd operation, err: %d", err);
if (decltype(ex) p_ex = w_ex.lock(); err < 0 && p_ex != nullptr) {
ex->CloseWrite();
}
@ -459,7 +456,7 @@ void GpgFileOpera::DecryptVerifyArchive(const QString& in_path,
ArchiveFileOperator::ExtractArchiveFromDataExchanger(
ex, out_path, [](GFError err, const DataObjectPtr&) {
GF_CORE_LOG_DEBUG("extract archive from ex operation, err: {}", err);
qCDebug(core, "extract archive from ex operation, err: %d", err);
});
RunGpgOperaAsync(
@ -545,19 +542,18 @@ void GpgFileOpera::EncryptDerectorySymmetric(const QString& in_path, bool ascii,
ArchiveFileOperator::NewArchive2DataExchanger(
in_path, ex, [=](GFError err, const DataObjectPtr&) {
GF_CORE_LOG_DEBUG("new archive 2 fd operation, err: {}", err);
qCDebug(core, "new archive 2 fd operation, err: %d", err);
});
}
auto GpgFileOpera::EncryptDerectorySymmetricSync(const QString& in_path,
bool ascii,
const QString& out_path)
-> std::tuple<GpgError, DataObjectPtr> {
auto GpgFileOpera::EncryptDerectorySymmetricSync(
const QString& in_path, bool ascii,
const QString& out_path) -> std::tuple<GpgError, DataObjectPtr> {
auto ex = std::make_shared<GFDataExchanger>(kDataExchangerSize);
ArchiveFileOperator::NewArchive2DataExchanger(
in_path, ex, [=](GFError err, const DataObjectPtr&) {
GF_CORE_LOG_DEBUG("new archive 2 fd operation, err: {}", err);
qCDebug(core, "new archive 2 fd operation, err: %d", err);
});
return RunGpgOperaSync(

View File

@ -42,9 +42,7 @@ namespace GpgFrontend {
class GpgKeyGetter::Impl : public SingletonFunctionObject<GpgKeyGetter::Impl> {
public:
explicit Impl(int channel)
: SingletonFunctionObject<GpgKeyGetter::Impl>(channel) {
GF_CORE_LOG_DEBUG("called channel: {}", channel);
}
: SingletonFunctionObject<GpgKeyGetter::Impl>(channel) {}
auto GetKey(const QString& fpr, bool use_cache) -> GpgKey {
// find in cache first
@ -56,7 +54,8 @@ class GpgKeyGetter::Impl : public SingletonFunctionObject<GpgKeyGetter::Impl> {
gpgme_key_t p_key = nullptr;
gpgme_get_key(ctx_.DefaultContext(), fpr.toUtf8(), &p_key, 1);
if (p_key == nullptr) {
GF_CORE_LOG_WARN("GpgKeyGetter GetKey Private _p_key Null fpr", fpr);
qCWarning(core) << "GpgKeyGetter GetKey Private _p_key Null, fpr: "
<< fpr;
return GetPubkey(fpr, true);
}
return GpgKey(std::move(p_key));
@ -72,7 +71,7 @@ class GpgKeyGetter::Impl : public SingletonFunctionObject<GpgKeyGetter::Impl> {
gpgme_key_t p_key = nullptr;
gpgme_get_key(ctx_.DefaultContext(), fpr.toUtf8(), &p_key, 0);
if (p_key == nullptr)
GF_CORE_LOG_WARN("GpgKeyGetter GetKey _p_key Null", fpr);
qCWarning(core) << "GpgKeyGetter GetKey _p_key Null, fpr: " << fpr;
return GpgKey(std::move(p_key));
}
@ -92,9 +91,23 @@ class GpgKeyGetter::Impl : public SingletonFunctionObject<GpgKeyGetter::Impl> {
return keys_list;
}
auto FlushKeyCache() -> bool {
GF_CORE_LOG_DEBUG("flush key channel called, channel: {}", GetChannel());
auto FetchGpgKeyList() -> GpgKeyList {
if (keys_search_cache_.empty()) {
FlushKeyCache();
}
auto keys_list = GpgKeyList{};
{
// get the lock
std::lock_guard<std::mutex> lock(keys_cache_mutex_);
for (const auto& key : keys_cache_) {
keys_list.push_back(key);
}
}
return keys_list;
}
auto FlushKeyCache() -> bool {
// clear the keys cache
keys_cache_.clear();
keys_search_cache_.clear();
@ -129,17 +142,12 @@ class GpgKeyGetter::Impl : public SingletonFunctionObject<GpgKeyGetter::Impl> {
}
}
GF_CORE_LOG_DEBUG("flush key channel cache address: {} object address: {}",
static_cast<void*>(&keys_search_cache_),
static_cast<void*>(this));
// for debug
assert(CheckGpgError2ErrCode(err, GPG_ERR_EOF) == GPG_ERR_EOF);
err = gpgme_op_keylist_end(ctx_.DefaultContext());
assert(CheckGpgError2ErrCode(err, GPG_ERR_EOF) == GPG_ERR_NO_ERROR);
GF_CORE_LOG_DEBUG("flush key channel done, channel: {}", GetChannel());
return true;
}
@ -165,6 +173,11 @@ class GpgKeyGetter::Impl : public SingletonFunctionObject<GpgKeyGetter::Impl> {
return keys_copy;
}
auto GetGpgKeyTableModel() -> QSharedPointer<GpgKeyTableModel> {
return SecureCreateQSharedObject<GpgKeyTableModel>(FetchGpgKeyList(),
nullptr);
}
private:
/**
* @brief Get the gpgme context object
@ -218,9 +231,7 @@ class GpgKeyGetter::Impl : public SingletonFunctionObject<GpgKeyGetter::Impl> {
GpgKeyGetter::GpgKeyGetter(int channel)
: SingletonFunctionObject<GpgKeyGetter>(channel),
p_(SecureCreateUniqueObject<Impl>(channel)) {
GF_CORE_LOG_DEBUG("called channel: {}", channel);
}
p_(SecureCreateUniqueObject<Impl>(channel)) {}
GpgKeyGetter::~GpgKeyGetter() = default;
@ -248,4 +259,8 @@ auto GpgKeyGetter::GetKeysCopy(const KeyListPtr& keys) -> KeyListPtr {
auto GpgKeyGetter::FetchKey() -> KeyLinkListPtr { return p_->FetchKey(); }
auto GpgKeyGetter::GetGpgKeyTableModel() -> QSharedPointer<GpgKeyTableModel> {
return p_->GetGpgKeyTableModel();
}
} // namespace GpgFrontend

View File

@ -29,6 +29,7 @@
#pragma once
#include "core/function/basic/GpgFunctionObject.h"
#include "core/model/GpgKeyTableModel.h"
#include "core/typedef/GpgTypedef.h"
namespace GpgFrontend {
@ -106,6 +107,13 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyGetter
*/
auto GetKeysCopy(const KeyLinkListPtr& keys) -> KeyLinkListPtr;
/**
* @brief
*
* @return GpgKeyTableModel
*/
auto GetGpgKeyTableModel() -> QSharedPointer<GpgKeyTableModel>;
private:
class Impl;
SecureUniquePtr<Impl> p_;

View File

@ -49,11 +49,11 @@ auto GpgKeyImportExporter::ImportKey(const GFBuffer& in_buffer)
if (in_buffer.Empty()) return {};
GpgData data_in(in_buffer);
auto err = CheckGpgError(gpgme_op_import(ctx_.DefaultContext(), data_in));
auto err = CheckGpgError(gpgme_op_import(ctx_.BinaryContext(), data_in));
if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return {};
gpgme_import_result_t result;
result = gpgme_op_import_result(ctx_.DefaultContext());
result = gpgme_op_import_result(ctx_.BinaryContext());
gpgme_import_status_t status = result->imports;
auto import_info = SecureCreateSharedObject<GpgImportInformation>(result);
while (status != nullptr) {
@ -93,9 +93,6 @@ auto GpgKeyImportExporter::ExportKey(const GpgKey& key, bool secret, bool ascii,
auto err = gpgme_op_export_keys(ctx, keys_array.data(), mode, data_out);
if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return {};
GF_CORE_LOG_DEBUG(
"operation of exporting a key finished, ascii: {}, read_bytes: {}", ascii,
gpgme_data_seek(data_out, 0, SEEK_END));
return {err, data_out.Read2GFBuffer()};
}
@ -127,10 +124,6 @@ void GpgKeyImportExporter::ExportKeys(const KeyArgsList& keys, bool secret,
auto err = gpgme_op_export_keys(ctx, keys_array.data(), mode, data_out);
if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return {};
GF_CORE_LOG_DEBUG(
"operation of exporting keys finished, ascii: {}, read_bytes: {}",
ascii, gpgme_data_seek(data_out, 0, SEEK_END));
data_object->Swap({data_out.Read2GFBuffer()});
return err;
},
@ -161,9 +154,6 @@ void GpgKeyImportExporter::ExportAllKeys(const KeyArgsList& keys, bool secret,
auto err = gpgme_op_export_keys(ctx, keys_array.data(), mode, data_out);
if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return {};
GF_CORE_LOG_DEBUG(
"operation of exporting keys finished, ascii: {}, read_bytes: {}",
ascii, gpgme_data_seek(data_out, 0, SEEK_END));
auto buffer = data_out.Read2GFBuffer();
if (secret) {
@ -175,10 +165,6 @@ void GpgKeyImportExporter::ExportAllKeys(const KeyArgsList& keys, bool secret,
data_out_secret);
if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) return {};
GF_CORE_LOG_DEBUG(
"operation of exporting secret keys finished, "
"ascii: {}, read_bytes: {}",
ascii, gpgme_data_seek(data_out_secret, 0, SEEK_END));
buffer.Append(data_out_secret.Read2GFBuffer());
}

View File

@ -73,10 +73,9 @@ auto GpgFrontend::GpgKeyManager::RevSign(
return true;
}
auto GpgFrontend::GpgKeyManager::SetExpire(const GpgFrontend::GpgKey& key,
std::unique_ptr<GpgSubKey>& subkey,
std::unique_ptr<QDateTime>& expires)
-> bool {
auto GpgFrontend::GpgKeyManager::SetExpire(
const GpgFrontend::GpgKey& key, std::unique_ptr<GpgSubKey>& subkey,
std::unique_ptr<QDateTime>& expires) -> bool {
unsigned long expires_time = 0;
if (expires != nullptr) expires_time = expires->toSecsSinceEpoch();
@ -95,14 +94,15 @@ auto GpgFrontend::GpgKeyManager::SetExpire(const GpgFrontend::GpgKey& key,
auto GpgFrontend::GpgKeyManager::SetOwnerTrustLevel(const GpgKey& key,
int trust_level) -> bool {
if (trust_level < 0 || trust_level > 5) {
GF_CORE_LOG_ERROR("illegal owner trust level: {}", trust_level);
qCWarning(core, "illegal owner trust level: %d", trust_level);
}
AutomatonNextStateHandler next_state_handler = [](AutomatonState state,
QString status,
QString args) {
GF_CORE_LOG_DEBUG("next_state_handler state: {}, gpg_status: {}, args: {}",
state, status, args);
AutomatonNextStateHandler next_state_handler =
[](AutomatonState state, QString status, QString args) {
qCDebug(core) << "next_state_handler state: "
<< static_cast<unsigned int>(state)
<< ", gpg_status: " << status << ", args: " << args;
auto tokens = args.split(' ');
switch (state) {
@ -144,9 +144,10 @@ auto GpgFrontend::GpgKeyManager::SetOwnerTrustLevel(const GpgKey& key,
};
};
AutomatonActionHandler action_handler =
[trust_level](AutomatonHandelStruct& handler, AutomatonState state) {
GF_CORE_LOG_DEBUG("action_handler state: {}", state);
AutomatonActionHandler action_handler = [trust_level](
AutomatonHandelStruct& handler,
AutomatonState state) {
qCDebug(core, "action_handler state: %d", static_cast<unsigned int>(state));
switch (state) {
case AS_COMMAND:
return QString("trust");
@ -185,21 +186,19 @@ auto GpgFrontend::GpgKeyManager::SetOwnerTrustLevel(const GpgKey& key,
auto GpgFrontend::GpgKeyManager::interactor_cb_fnc(void* handle,
const char* status,
const char* args, int fd)
-> gpgme_error_t {
const char* args,
int fd) -> gpgme_error_t {
auto* handle_struct = static_cast<AutomatonHandelStruct*>(handle);
QString status_s = status;
QString args_s = args;
GF_CORE_LOG_DEBUG(
"cb start status: {}, args: {}, fd: {}, handle struct state: {}",
status_s, args_s, fd, handle_struct->CuurentStatus());
if (status_s == "KEY_CONSIDERED") {
auto tokens = QString(args).split(' ');
if (tokens.empty() || tokens[0] != handle_struct->KeyFpr()) {
GF_CORE_LOG_ERROR("handle struct key fpr {} mismatch token: {}, exit...",
handle_struct->KeyFpr(), tokens[0]);
qCWarning(core) << "handle struct key fpr " << handle_struct->KeyFpr()
<< "mismatch token: " << tokens[0] << ", exit...";
return -1;
}
@ -207,13 +206,13 @@ auto GpgFrontend::GpgKeyManager::interactor_cb_fnc(void* handle,
}
if (status_s == "GOT_IT" || status_s.isEmpty()) {
GF_CORE_LOG_DEBUG("status GOT_IT, continue...");
qCDebug(core, "status GOT_IT, continue...");
return 0;
}
AutomatonState next_state = handle_struct->NextState(status_s, args_s);
if (next_state == AS_ERROR) {
GF_CORE_LOG_DEBUG("handle struct next state caught error, skipping...");
qCDebug(core, "handle struct next state caught error, skipping...");
return GPG_ERR_FALSE;
}
@ -224,8 +223,7 @@ auto GpgFrontend::GpgKeyManager::interactor_cb_fnc(void* handle,
// set state and preform action
handle_struct->SetStatus(next_state);
Command cmd = handle_struct->Action();
GF_CORE_LOG_DEBUG("handle struct action done, next state: {}, action cmd: {}",
next_state, cmd);
if (!cmd.isEmpty()) {
auto btye_array = cmd.toUtf8();
gpgme_io_write(fd, btye_array, btye_array.size());

View File

@ -61,7 +61,7 @@ void GpgKeyOpera::DeleteKeys(KeyIdArgsListPtr key_ids) {
GPGME_DELETE_ALLOW_SECRET | GPGME_DELETE_FORCE));
assert(gpg_err_code(err) == GPG_ERR_NO_ERROR);
} else {
GF_CORE_LOG_WARN("GpgKeyOpera DeleteKeys get key failed", tmp);
qCWarning(core) << "GpgKeyOpera DeleteKeys get key failed: " << tmp;
}
}
}
@ -113,13 +113,11 @@ void GpgKeyOpera::GenerateRevokeCert(const GpgKey& key,
output_path, "--gen-revoke", key.GetFingerprint()},
[=](int exit_code, const QString& p_out, const QString& p_err) {
if (exit_code != 0) {
GF_CORE_LOG_ERROR(
"gnupg gen revoke execute error, process stderr: {}, process "
"stdout: {}",
p_err, p_out);
qCWarning(core) << "gnupg gen revoke execute error, process stderr: "
<< p_err << ", process stdout: " << p_out;
} else {
GF_CORE_LOG_DEBUG(
"gnupg gen revoke exit_code: {}, process stdout size: {}",
qCDebug(core,
"gnupg gen revoke exit_code: %d, process stdout size: %lld",
exit_code, p_out.size());
}
},
@ -128,7 +126,6 @@ void GpgKeyOpera::GenerateRevokeCert(const GpgKey& key,
// Code From Gpg4Win
while (proc->canReadLine()) {
const QString line = QString::fromUtf8(proc->readLine()).trimmed();
GF_CORE_LOG_DEBUG("line: {}", line);
if (line == QLatin1String("[GNUPG:] GET_BOOL gen_revoke.okay")) {
proc->write("y\n");
} else if (line == QLatin1String("[GNUPG:] GET_LINE "
@ -162,8 +159,8 @@ void GpgKeyOpera::GenerateKey(const std::shared_ptr<GenKeyInfo>& params,
auto userid = params->GetUserid();
auto algo = params->GetAlgo() + params->GetKeySizeStr();
GF_CORE_LOG_DEBUG("params: {} {}", params->GetAlgo(),
params->GetKeySizeStr());
qCDebug(core) << "params: " << params->GetAlgo()
<< params->GetKeySizeStr();
unsigned long expires =
QDateTime::currentDateTime().secsTo(params->GetExpireTime());
@ -178,8 +175,9 @@ void GpgKeyOpera::GenerateKey(const std::shared_ptr<GenKeyInfo>& params,
if (params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
if (params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
GF_CORE_LOG_DEBUG("key generation args: {} {} {} {}", userid, algo,
expires, flags);
qCDebug(core) << "key generation args: " << userid << algo << expires
<< flags;
err = gpgme_op_createkey(ctx.DefaultContext(), userid.toUtf8(),
algo.toUtf8(), 0, expires, nullptr, flags);
@ -202,8 +200,8 @@ auto GpgKeyOpera::GenerateKeySync(const std::shared_ptr<GenKeyInfo>& params)
auto userid = params->GetUserid();
auto algo = params->GetAlgo() + params->GetKeySizeStr();
GF_CORE_LOG_DEBUG("params: {} {}", params->GetAlgo(),
params->GetKeySizeStr());
qCDebug(core) << "params: " << params->GetAlgo()
<< params->GetKeySizeStr();
unsigned long expires =
QDateTime::currentDateTime().secsTo(params->GetExpireTime());
@ -218,8 +216,9 @@ auto GpgKeyOpera::GenerateKeySync(const std::shared_ptr<GenKeyInfo>& params)
if (params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
if (params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
GF_CORE_LOG_DEBUG("key generation args: {} {} {} {}", userid, algo,
expires, flags);
qCDebug(core) << "key generation args: " << userid << algo << expires
<< flags;
err = gpgme_op_createkey(ctx.DefaultContext(), userid.toUtf8(),
algo.toUtf8(), 0, expires, nullptr, flags);
@ -242,8 +241,8 @@ void GpgKeyOpera::GenerateSubkey(const GpgKey& key,
[key, &ctx = ctx_, params](const DataObjectPtr& data_object) -> GpgError {
if (!params->IsSubKey()) return GPG_ERR_CANCELED;
GF_CORE_LOG_DEBUG("generate subkey algo {}, key size {}",
params->GetAlgo(), params->GetKeySizeStr());
qCDebug(core) << "generate subkey algo: " << params->GetAlgo()
<< "key size: " << params->GetKeySizeStr();
auto algo = params->GetAlgo() + params->GetKeySizeStr();
unsigned long expires =
@ -257,8 +256,9 @@ void GpgKeyOpera::GenerateSubkey(const GpgKey& key,
if (params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
if (params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
GF_CORE_LOG_DEBUG("subkey generation args: {} {} {} {}", key.GetId(),
algo, expires, flags);
qCDebug(core) << "subkey generation args: " << key.GetId() << algo
<< expires << flags;
auto err = gpgme_op_createsubkey(ctx.DefaultContext(),
static_cast<gpgme_key_t>(key),
algo.toUtf8(), 0, expires, flags);
@ -281,8 +281,8 @@ auto GpgKeyOpera::GenerateSubkeySync(const GpgKey& key,
[key, &ctx = ctx_, params](const DataObjectPtr& data_object) -> GpgError {
if (!params->IsSubKey()) return GPG_ERR_CANCELED;
GF_CORE_LOG_DEBUG("generate subkey algo {} key size {}",
params->GetAlgo(), params->GetKeySizeStr());
qCDebug(core) << "generate subkey algo: " << params->GetAlgo()
<< " key size: " << params->GetKeySizeStr();
auto algo = params->GetAlgo() + params->GetKeySizeStr();
unsigned long expires =
@ -296,8 +296,7 @@ auto GpgKeyOpera::GenerateSubkeySync(const GpgKey& key,
if (params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
if (params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
GF_CORE_LOG_DEBUG("args: {} {} {} {}", key.GetId(), algo, expires,
flags);
qCDebug(core) << " args: " << key.GetId() << algo << expires << flags;
auto err = gpgme_op_createsubkey(ctx.DefaultContext(),
static_cast<gpgme_key_t>(key),
@ -337,8 +336,9 @@ void GpgKeyOpera::GenerateKeyWithSubkey(
if (params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
if (params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
GF_CORE_LOG_DEBUG("key generation args: {}", userid, algo, expires,
flags);
qCDebug(core) << "key generation args: " << userid << algo << expires
<< flags;
err = gpgme_op_createkey(ctx.DefaultContext(), userid, algo, 0, expires,
nullptr, flags);
@ -358,16 +358,11 @@ void GpgKeyOpera::GenerateKeyWithSubkey(
auto key =
GpgKeyGetter::GetInstance().GetKey(genkey_result.GetFingerprint());
if (!key.IsGood()) {
GF_CORE_LOG_ERROR("cannot get key which has been generate, fpr: {}",
genkey_result.GetFingerprint());
qCWarning(core) << "cannot get key which has been generate, fpr: "
<< genkey_result.GetFingerprint();
return err;
}
GF_CORE_LOG_DEBUG(
"try to generate subkey of key: {}, algo {} key size {}",
key.GetId(), subkey_params->GetAlgo(),
subkey_params->GetKeySizeStr());
algo = (subkey_params->GetAlgo() + subkey_params->GetKeySizeStr())
.toUtf8();
expires =
@ -380,8 +375,8 @@ void GpgKeyOpera::GenerateKeyWithSubkey(
if (subkey_params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
if (subkey_params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
GF_CORE_LOG_DEBUG("subkey generation args: {} {} {} {}", key.GetId(),
algo, expires, flags);
qCDebug(core) << "subkey generation args: " << key.GetId() << algo
<< expires << flags;
err = gpgme_op_createsubkey(ctx.DefaultContext(),
static_cast<gpgme_key_t>(key), algo, 0,
@ -422,8 +417,9 @@ auto GpgKeyOpera::GenerateKeyWithSubkeySync(
if (params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
if (params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
GF_CORE_LOG_DEBUG("key generation args: {}", userid, algo, expires,
flags);
qCDebug(core) << "key generation args: " << userid << algo << expires
<< flags;
err = gpgme_op_createkey(ctx.DefaultContext(), userid, algo, 0, expires,
nullptr, flags);
@ -443,15 +439,14 @@ auto GpgKeyOpera::GenerateKeyWithSubkeySync(
auto key =
GpgKeyGetter::GetInstance().GetKey(genkey_result.GetFingerprint());
if (!key.IsGood()) {
GF_CORE_LOG_ERROR("cannot get key which has been generate, fpr: {}",
genkey_result.GetFingerprint());
qCWarning(core) << "cannot get key which has been generate, fpr: "
<< genkey_result.GetFingerprint();
return err;
}
GF_CORE_LOG_DEBUG(
"try to generate subkey of key: {}, algo {} key size {}",
key.GetId(), subkey_params->GetAlgo(),
subkey_params->GetKeySizeStr());
qCDebug(core) << "try to generate subkey of key: " << key.GetId()
<< ", algo :" << subkey_params->GetAlgo()
<< ", key size: " << subkey_params->GetKeySizeStr();
algo = (subkey_params->GetAlgo() + subkey_params->GetKeySizeStr())
.toUtf8();
@ -465,8 +460,8 @@ auto GpgKeyOpera::GenerateKeyWithSubkeySync(
if (subkey_params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE;
if (subkey_params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD;
GF_CORE_LOG_DEBUG("subkey generation args: {} {} {} {}", key.GetId(),
algo, expires, flags);
qCDebug(core) << "subkey generation args: " << key.GetId() << algo
<< expires << flags;
err = gpgme_op_createsubkey(ctx.DefaultContext(),
static_cast<gpgme_key_t>(key), algo, 0,
@ -495,15 +490,14 @@ void GpgKeyOpera::ModifyPassword(const GpgKey& key,
callback, "gpgme_op_passwd", "2.0.15");
}
auto GpgKeyOpera::ModifyTOFUPolicy(const GpgKey& key,
gpgme_tofu_policy_t tofu_policy)
-> GpgError {
auto GpgKeyOpera::ModifyTOFUPolicy(
const GpgKey& key, gpgme_tofu_policy_t tofu_policy) -> GpgError {
const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>(
"core", "gpgme.ctx.gnupg_version", QString{"2.0.0"});
GF_CORE_LOG_DEBUG("got gnupg version from rt: {}", gnupg_version);
qCDebug(core) << "got gnupg version from rt: " << gnupg_version;
if (GFCompareSoftwareVersion(gnupg_version, "2.1.10") < 0) {
GF_CORE_LOG_ERROR("operator not support");
qCWarning(core, "operator not support");
return GPG_ERR_NOT_SUPPORTED;
}

View File

@ -48,17 +48,17 @@ auto GpgUIDOperator::RevUID(const GpgKey& key, const QString& uid) -> bool {
return CheckGpgError(err) == GPG_ERR_NO_ERROR;
}
auto GpgUIDOperator::SetPrimaryUID(const GpgKey& key, const QString& uid)
-> bool {
auto GpgUIDOperator::SetPrimaryUID(const GpgKey& key,
const QString& uid) -> bool {
auto err = CheckGpgError(gpgme_op_set_uid_flag(
ctx_.DefaultContext(), static_cast<gpgme_key_t>(key), uid.toUtf8(),
"primary", nullptr));
return CheckGpgError(err) == GPG_ERR_NO_ERROR;
}
auto GpgUIDOperator::AddUID(const GpgKey& key, const QString& name,
const QString& comment, const QString& email)
-> bool {
GF_CORE_LOG_DEBUG("new uuid: {} {} {}", name, comment, email);
const QString& comment,
const QString& email) -> bool {
qCDebug(core) << "new uuid:" << name << comment << email;
return AddUID(key, QString("%1(%2)<%3>").arg(name).arg(comment).arg(email));
}

View File

@ -70,10 +70,6 @@ class GPGFRONTEND_CORE_EXPORT DataObject {
for (size_t i = 0; i < type_list.size(); ++i) {
if (std::type_index(*type_list[i]) !=
std::type_index((*this)[i].type())) {
GF_CORE_LOG_ERROR(
"value of index {} in data object is type: {}, "
"not expected type: {}",
i, ((*this)[i]).type().name(), type_list[i]->name());
return false;
}
}

View File

@ -28,8 +28,6 @@
#include "GFDataExchanger.h"
#include "core/utils/LogUtils.h"
namespace GpgFrontend {
auto GFDataExchanger::Write(const std::byte* buffer, size_t size) -> ssize_t {
@ -40,16 +38,22 @@ auto GFDataExchanger::Write(const std::byte* buffer, size_t size) -> ssize_t {
std::unique_lock<std::mutex> lock(mutex_);
try {
for (size_t i = 0; i < size; i++) {
if (queue_.size() == queue_max_size_) not_empty_.notify_all();
not_full_.wait(lock,
[=] { return queue_.size() < queue_max_size_ || close_; });
if (queue_.size() == static_cast<unsigned long>(queue_max_size_)) {
not_empty_.notify_all();
}
not_full_.wait(lock, [=] {
return queue_.size() < static_cast<unsigned long>(queue_max_size_) ||
close_;
});
if (close_) return -1;
queue_.push(buffer[i]);
write_bytes++;
}
} catch (...) {
GF_CORE_LOG_ERROR(
qCWarning(
core,
"gf data exchanger caught exception when it writes to queue, abort...");
}
@ -72,7 +76,9 @@ auto GFDataExchanger::Read(std::byte* buffer, size_t size) -> ssize_t {
read_bytes++;
}
if (queue_.size() < queue_max_size_) not_full_.notify_all();
if (queue_.size() < static_cast<unsigned long>(queue_max_size_)) {
not_full_.notify_all();
}
return read_bytes;
}

View File

@ -55,7 +55,7 @@ auto GpgDecryptResult::Recipients() -> std::vector<GpgRecipient> {
try {
result.emplace_back(reci);
} catch (...) {
GF_CORE_LOG_ERROR(
qCWarning(core,
"caught exception when processing invalid_recipients, "
"maybe nullptr of fpr");
}

View File

@ -55,7 +55,7 @@ auto GpgEncryptResult::InvalidRecipients()
try {
result.emplace_back(QString{invalid_key->fpr}, invalid_key->reason);
} catch (...) {
GF_CORE_LOG_ERROR(
qCWarning(core,
"caught exception when processing invalid_recipients, "
"maybe nullptr of fpr");
}

View File

@ -30,13 +30,10 @@
#include <cassert>
#include "core/utils/LogUtils.h"
namespace GpgFrontend {
void GenKeyInfo::SetAlgo(const QString &t_algo_args) {
auto algo_args = t_algo_args.toLower();
GF_CORE_LOG_DEBUG("set algo args: {}", algo_args);
// reset all options
reset_options();
@ -74,6 +71,28 @@ void GenKeyInfo::SetAlgo(const QString &t_algo_args) {
suggest_max_key_size_ = 3072;
suggest_size_addition_step_ = 1024;
SetKeyLength(2048);
} else if (algo_args == "elg") {
/**
* Algorithm (DSA) as a government standard for digital signatures.
* Originally, it supported key lengths between 512 and 1024 bits.
* Recently, NIST has declared 512-bit keys obsolete:
* now, DSA is available in 1024, 2048 and 3072-bit lengths.
*/
SetAllowEncryption(true);
SetAllowAuthentication(false);
allow_change_authentication_ = false;
SetAllowSigning(false);
allow_change_signing_ = false;
SetAllowCertification(false);
allow_change_certification_ = false;
suggest_min_key_size_ = 1024;
suggest_max_key_size_ = 4096;
suggest_size_addition_step_ = 1024;
SetKeyLength(3072);
} else if (algo_args == "ed25519") {
/**
@ -105,7 +124,7 @@ void GenKeyInfo::SetAlgo(const QString &t_algo_args) {
suggest_size_addition_step_ = -1;
SetKeyLength(-1);
} else {
SPDLOG_ERROR("unsupported genkey algo arguments: {}", algo_args);
qCWarning(core) << "unsupported genkey algo arguments: " << algo_args;
return;
}
@ -189,6 +208,7 @@ auto GenKeyInfo::GetSupportedSubkeyAlgo()
static const std::vector<GenKeyInfo::KeyGenAlgo> kSupportSubkeyAlgo = {
{"RSA", "", "RSA"},
{"DSA", "", "DSA"},
{"ELG-E", "", "ELG"},
{"ECDSA", "", "ED25519"},
{"ECDH", "", "CV25519"},
{"ECDH NIST P-256", "", "NISTP256"},

View File

@ -0,0 +1,172 @@
/**
* Copyright (C) 2021 Saturneric <eric@bktus.com>
*
* 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 <eric@bktus.com> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "GpgKeyTableModel.h"
#include "core/function/gpg/GpgKeyGetter.h"
#include "core/model/GpgKey.h"
namespace GpgFrontend {
GpgKeyTableModel::GpgKeyTableModel(GpgKeyList keys, QObject *parent)
: QAbstractTableModel(parent),
buffered_keys_(keys),
column_headers_({tr("Select"), tr("Type"), tr("Name"),
tr("Email Address"), tr("Usage"), tr("Trust"),
tr("Key ID"), tr("Create Date"), tr("Algorithm"),
tr("Subkey(s)"), tr("Comment")}),
key_check_state_(buffered_keys_.size()) {}
auto GpgKeyTableModel::rowCount(const QModelIndex & /*parent*/) const -> int {
return static_cast<int>(buffered_keys_.size());
}
auto GpgKeyTableModel::columnCount(const QModelIndex & /*parent*/) const
-> int {
return 11;
}
auto GpgKeyTableModel::data(const QModelIndex &index, int role) const
-> QVariant {
if (!index.isValid() || buffered_keys_.empty()) return {};
if (role == Qt::TextAlignmentRole) {
return Qt::AlignCenter;
}
if (role == Qt::CheckStateRole) {
if (index.column() == 0) {
return key_check_state_[index.row()] ? Qt::Checked : Qt::Unchecked;
}
return {};
}
const auto &key = buffered_keys_.at(index.row());
switch (index.column()) {
case 0: {
return index.row();
}
case 1: {
QString type_sym;
type_sym += key.IsPrivateKey() ? "pub/sec" : "pub";
if (key.IsPrivateKey() && !key.IsHasMasterKey()) type_sym += "#";
if (key.IsHasCardKey()) type_sym += "^";
return type_sym;
}
case 2: {
return key.GetName();
}
case 3: {
return key.GetEmail();
}
case 4: {
QString usage_sym;
if (key.IsHasActualCertificationCapability()) usage_sym += "C";
if (key.IsHasActualEncryptionCapability()) usage_sym += "E";
if (key.IsHasActualSigningCapability()) usage_sym += "S";
if (key.IsHasActualAuthenticationCapability()) usage_sym += "A";
return usage_sym;
}
case 5: {
return key.GetOwnerTrust();
}
case 6: {
return key.GetId();
}
case 7: {
return key.GetCreateTime();
}
case 8: {
return key.GetKeyAlgo();
}
case 9: {
return static_cast<int>(key.GetSubKeys()->size());
}
case 10: {
return key.GetComment();
}
default:
return {};
}
}
auto GpgKeyTableModel::headerData(int section, Qt::Orientation orientation,
int role) const -> QVariant {
if (role != Qt::DisplayRole) return {};
if (orientation == Qt::Horizontal) {
return column_headers_[section];
}
return {};
}
auto GpgKeyTableModel::flags(const QModelIndex &index) const -> Qt::ItemFlags {
if (!index.isValid()) return Qt::NoItemFlags;
if (index.column() == 0) {
return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled;
}
return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
}
auto GpgKeyTableModel::setData(const QModelIndex &index, const QVariant &value,
int role) -> bool {
if (!index.isValid()) return false;
if (index.column() == 0 && role == Qt::CheckStateRole) {
key_check_state_[index.row()] = (value == Qt::Checked);
emit dataChanged(index, index);
return true;
}
return false;
}
auto GpgKeyTableModel::GetAllKeyIds() -> GpgKeyIDList {
GpgKeyIDList keys;
for (auto &key : buffered_keys_) {
keys.push_back(key.GetId());
}
return keys;
}
auto GpgKeyTableModel::GetKeyIDByRow(int row) const -> QString {
if (buffered_keys_.size() <= row) return {};
return buffered_keys_[row].GetId();
}
auto GpgKeyTableModel::IsPrivateKeyByRow(int row) const -> bool {
if (buffered_keys_.size() <= row) return false;
return buffered_keys_[row].IsPrivateKey();
}
} // namespace GpgFrontend

View File

@ -0,0 +1,212 @@
/**
* Copyright (C) 2021 Saturneric <eric@bktus.com>
*
* 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 <eric@bktus.com> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#pragma once
/**
* @brief
*
*/
#include "core/model/GpgKey.h"
#include "core/typedef/GpgTypedef.h"
namespace GpgFrontend {
enum class GpgKeyTableColumn : unsigned int {
kNONE = 0,
kTYPE = 1 << 0,
kNAME = 1 << 1,
kEMAIL_ADDRESS = 1 << 2,
kUSAGE = 1 << 3,
kKEY_ID = 1 << 4,
kOWNER_TRUST = 1 << 5,
kCREATE_DATE = 1 << 6,
kALGO = 1 << 7,
kSUBKEYS_NUMBER = 1 << 8,
kCOMMENT = 1 << 9,
kALL = ~0U
};
inline auto operator|(GpgKeyTableColumn lhs, GpgKeyTableColumn rhs)
-> GpgKeyTableColumn {
using T = std::underlying_type_t<GpgKeyTableColumn>;
return static_cast<GpgKeyTableColumn>(static_cast<T>(lhs) |
static_cast<T>(rhs));
}
inline auto operator|=(GpgKeyTableColumn &lhs, GpgKeyTableColumn rhs)
-> GpgKeyTableColumn & {
lhs = lhs | rhs;
return lhs;
}
inline auto operator&(GpgKeyTableColumn lhs, GpgKeyTableColumn rhs)
-> GpgKeyTableColumn {
using T = std::underlying_type_t<GpgKeyTableColumn>;
return static_cast<GpgKeyTableColumn>(static_cast<T>(lhs) &
static_cast<T>(rhs));
}
inline auto operator&=(GpgKeyTableColumn &lhs, GpgKeyTableColumn rhs)
-> GpgKeyTableColumn & {
lhs = lhs & rhs;
return lhs;
}
inline auto operator~(GpgKeyTableColumn hs) -> GpgKeyTableColumn {
using T = std::underlying_type_t<GpgKeyTableColumn>;
return static_cast<GpgKeyTableColumn>(~static_cast<T>(hs));
}
enum class GpgKeyTableDisplayMode : unsigned int {
kNONE = 0,
kPUBLIC_KEY = 1 << 0,
kPRIVATE_KEY = 1 << 1,
kFAVORITES = 1 << 2,
kALL = ~0U
};
inline auto operator|(GpgKeyTableDisplayMode lhs, GpgKeyTableDisplayMode rhs)
-> GpgKeyTableDisplayMode {
using T = std::underlying_type_t<GpgKeyTableDisplayMode>;
return static_cast<GpgKeyTableDisplayMode>(static_cast<T>(lhs) |
static_cast<T>(rhs));
}
inline auto operator|=(GpgKeyTableDisplayMode &lhs, GpgKeyTableDisplayMode rhs)
-> GpgKeyTableDisplayMode & {
lhs = lhs | rhs;
return lhs;
}
inline auto operator&(GpgKeyTableDisplayMode lhs, GpgKeyTableDisplayMode rhs)
-> bool {
using T = std::underlying_type_t<GpgKeyTableDisplayMode>;
return (static_cast<T>(lhs) & static_cast<T>(rhs)) != 0;
}
class GPGFRONTEND_CORE_EXPORT GpgKeyTableModel : public QAbstractTableModel {
Q_OBJECT
public:
/**
* @brief Construct a new Gpg Key Table Model object
*
* @param keys
* @param parent
*/
explicit GpgKeyTableModel(GpgKeyList keys, QObject *parent = nullptr);
/**
* @brief
*
* @param parent
* @return int
*/
[[nodiscard]] auto rowCount(const QModelIndex &parent) const -> int override;
/**
* @brief
*
* @param parent
* @return int
*/
[[nodiscard]] auto columnCount(const QModelIndex &parent) const
-> int override;
/**
* @brief
*
* @param index
* @param role
* @return QVariant
*/
[[nodiscard]] auto data(const QModelIndex &index, int role) const
-> QVariant override;
/**
* @brief
*
* @param section
* @param orientation
* @param role
* @return QVariant
*/
[[nodiscard]] auto headerData(int section, Qt::Orientation orientation,
int role) const -> QVariant override;
/**
* @brief Set the Data object
*
* @param index
* @param value
* @param role
* @return true
* @return false
*/
auto setData(const QModelIndex &index, const QVariant &value, int role)
-> bool override;
/**
* @brief
*
* @param index
* @return Qt::ItemFlags
*/
[[nodiscard]] auto flags(const QModelIndex &index) const
-> Qt::ItemFlags override;
/**
* @brief Get the All Key Ids object
*
* @return auto
*/
auto GetAllKeyIds() -> GpgKeyIDList;
/**
* @brief Get the Key ID By Row object
*
* @return QString
*/
[[nodiscard]] auto GetKeyIDByRow(int row) const -> QString;
/**
* @brief
*
* @param row
* @return true
* @return false
*/
[[nodiscard]] auto IsPrivateKeyByRow(int row) const -> bool;
private:
GpgKeyList buffered_keys_;
QStringList column_headers_;
QList<bool> key_check_state_;
};
} // namespace GpgFrontend

View File

@ -0,0 +1,175 @@
/**
* Copyright (C) 2021 Saturneric <eric@bktus.com>
*
* 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 <eric@bktus.com> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "GpgKeyTableProxyModel.h"
#include <utility>
#include "core/function/gpg/GpgKeyGetter.h"
#include "core/model/CacheObject.h"
#include "core/model/GpgKey.h"
namespace GpgFrontend {
GpgKeyTableProxyModel::GpgKeyTableProxyModel(
QSharedPointer<GpgKeyTableModel> model, GpgKeyTableDisplayMode display_mode,
GpgKeyTableColumn columns, KeyFilter filter, QObject *parent)
: QSortFilterProxyModel(parent),
model_(std::move(model)),
display_mode_(display_mode),
filter_columns_(columns),
custom_filter_(std::move(filter)) {
setSourceModel(model_.get());
connect(this, &GpgKeyTableProxyModel::SignalFavoritesChanged, this,
&GpgKeyTableProxyModel::slot_update_favorites);
connect(this, &GpgKeyTableProxyModel::SignalColumnTypeChange, this,
&GpgKeyTableProxyModel::slot_update_column_type);
emit SignalFavoritesChanged();
}
auto GpgKeyTableProxyModel::filterAcceptsRow(
int source_row, const QModelIndex &sourceParent) const -> bool {
auto index = sourceModel()->index(source_row, 6, sourceParent);
auto key_id = sourceModel()->data(index).toString();
auto key = GpgKeyGetter::GetInstance().GetKey(key_id);
if (!(display_mode_ & GpgKeyTableDisplayMode::kPRIVATE_KEY) &&
key.IsPrivateKey()) {
return false;
}
if (!(display_mode_ & GpgKeyTableDisplayMode::kPUBLIC_KEY) &&
!key.IsPrivateKey()) {
return false;
}
if (!custom_filter_(key)) return false;
if (display_mode_ & GpgKeyTableDisplayMode::kFAVORITES &&
!favorite_fingerprints_.contains(key.GetFingerprint())) {
return false;
}
if (filter_keywords_.isEmpty()) return true;
QStringList infos;
for (int column = 0; column < sourceModel()->columnCount(); ++column) {
auto index = sourceModel()->index(source_row, column, sourceParent);
infos << sourceModel()->data(index).toString();
const auto uids = key.GetUIDs();
for (const auto &uid : *uids) {
infos << uid.GetUID();
}
}
return std::any_of(infos.cbegin(), infos.cend(), [&](const QString &info) {
return info.contains(filter_keywords_, Qt::CaseInsensitive);
});
return false;
}
auto GpgKeyTableProxyModel::filterAcceptsColumn(
int sourceColumn, const QModelIndex &sourceParent) const -> bool {
switch (sourceColumn) {
case 0: {
return true;
}
case 1: {
return (filter_columns_ & GpgKeyTableColumn::kTYPE) !=
GpgKeyTableColumn::kNONE;
}
case 2: {
return (filter_columns_ & GpgKeyTableColumn::kNAME) !=
GpgKeyTableColumn::kNONE;
}
case 3: {
return (filter_columns_ & GpgKeyTableColumn::kEMAIL_ADDRESS) !=
GpgKeyTableColumn::kNONE;
}
case 4: {
return (filter_columns_ & GpgKeyTableColumn::kUSAGE) !=
GpgKeyTableColumn::kNONE;
}
case 5: {
return (filter_columns_ & GpgKeyTableColumn::kOWNER_TRUST) !=
GpgKeyTableColumn::kNONE;
}
case 6: {
return (filter_columns_ & GpgKeyTableColumn::kKEY_ID) !=
GpgKeyTableColumn::kNONE;
}
case 7: {
return (filter_columns_ & GpgKeyTableColumn::kCREATE_DATE) !=
GpgKeyTableColumn::kNONE;
}
case 8: {
return (filter_columns_ & GpgKeyTableColumn::kALGO) !=
GpgKeyTableColumn::kNONE;
}
case 9: {
return (filter_columns_ & GpgKeyTableColumn::kSUBKEYS_NUMBER) !=
GpgKeyTableColumn::kNONE;
}
case 10: {
return (filter_columns_ & GpgKeyTableColumn::kCOMMENT) !=
GpgKeyTableColumn::kNONE;
}
default:
return false;
}
}
void GpgKeyTableProxyModel::SetSearchKeywords(const QString &keywords) {
this->filter_keywords_ = keywords;
invalidateFilter();
}
void GpgKeyTableProxyModel::slot_update_favorites() {
// load cache
auto json_data = CacheObject("favourite_key_pair");
if (!json_data.isArray()) return;
auto key_fprs = json_data.array();
for (const auto &key_fpr : key_fprs) {
if (key_fpr.isString()) favorite_fingerprints_.append(key_fpr.toString());
}
invalidateFilter();
}
void GpgKeyTableProxyModel::slot_update_column_type(
GpgKeyTableColumn filter_columns) {
filter_columns_ = filter_columns;
invalidateColumnsFilter();
}
} // namespace GpgFrontend

View File

@ -0,0 +1,94 @@
/**
* Copyright (C) 2021 Saturneric <eric@bktus.com>
*
* 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 <eric@bktus.com> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#pragma once
#include "core/model/GpgKeyTableModel.h"
namespace GpgFrontend {
class GPGFRONTEND_CORE_EXPORT GpgKeyTableProxyModel
: public QSortFilterProxyModel {
Q_OBJECT
public:
using KeyFilter = std::function<bool(const GpgKey &)>;
explicit GpgKeyTableProxyModel(QSharedPointer<GpgKeyTableModel> model,
GpgKeyTableDisplayMode display_mode,
GpgKeyTableColumn columns, KeyFilter filter,
QObject *parent);
void SetSearchKeywords(const QString &keywords);
protected:
[[nodiscard]] auto filterAcceptsRow(int sourceRow,
const QModelIndex &sourceParent) const
-> bool override;
[[nodiscard]] auto filterAcceptsColumn(int sourceColumn,
const QModelIndex &sourceParent) const
-> bool override;
signals:
/**
* @brief
*
*/
void SignalFavoritesChanged();
/**
* @brief
*
*/
void SignalColumnTypeChange(GpgKeyTableColumn);
private slots:
/**
* @brief
*
*/
void slot_update_favorites();
/**
* @brief
*
*/
void slot_update_column_type(GpgKeyTableColumn);
private:
QSharedPointer<GpgKeyTableModel> model_;
GpgKeyTableDisplayMode display_mode_;
GpgKeyTableColumn filter_columns_;
QString filter_keywords_;
QList<QString> favorite_fingerprints_;
KeyFilter custom_filter_;
};
} // namespace GpgFrontend

View File

@ -55,7 +55,7 @@ auto GpgSignResult::InvalidSigners()
try {
result.emplace_back(QString{invalid_key->fpr}, invalid_key->reason);
} catch (...) {
GF_CORE_LOG_ERROR(
qCWarning(core,
"caught exception when processing invalid_signers, "
"maybe nullptr of fpr");
}

View File

@ -35,20 +35,17 @@ namespace GpgFrontend {
SettingsObject::SettingsObject(QString settings_name)
: settings_name_(std::move(settings_name)) {
try {
GF_CORE_LOG_DEBUG("loading settings from: {}", this->settings_name_);
auto json_optional =
DataObjectOperator::GetInstance().GetDataObject(settings_name_);
if (json_optional.has_value() && json_optional->isObject()) {
GF_CORE_LOG_DEBUG("settings object: {} loaded.", settings_name_);
QJsonObject::operator=(json_optional.value().object());
} else {
GF_CORE_LOG_DEBUG("settings object: {} not found.", settings_name_);
QJsonObject::operator=({});
}
} catch (std::exception& e) {
GF_CORE_LOG_ERROR("load setting object error: {}", e.what());
qCWarning(core) << "load setting object error: {}" << e.what();
}
}

View File

@ -34,21 +34,17 @@ namespace GpgFrontend::Module {
class Event::Impl {
public:
Impl(QString event_id, std::initializer_list<ParameterInitializer> params,
EventCallback callback)
Impl(QString event_id, Params params, EventCallback callback)
: event_identifier_(std::move(event_id)),
callback_(std::move(callback)),
callback_thread_(QThread::currentThread()) {
for (const auto& param : params) {
AddParameter(param);
}
GF_CORE_LOG_DEBUG("create event {}", event_identifier_);
data_.insert(params);
}
auto operator[](const QString& key) const -> std::optional<ParameterValue> {
auto it_data = data_.find(key);
if (it_data != data_.end()) {
return it_data->second;
return it_data.value();
}
return std::nullopt;
}
@ -82,21 +78,17 @@ class Event::Impl {
}
void ExecuteCallback(ListenerIdentifier listener_id,
const DataObjectPtr& data_object) {
GF_CORE_LOG_DEBUG("try to execute callback for event {} with listener {}",
event_identifier_, listener_id);
const Params& data_object) {
if (callback_) {
GF_CORE_LOG_DEBUG("executing callback for event {} with listener {}",
event_identifier_, listener_id);
if (!QMetaObject::invokeMethod(
callback_thread_,
[callback = callback_, event_identifier = event_identifier_,
listener_id, data_object]() {
callback(event_identifier, listener_id, data_object);
})) {
GF_CORE_LOG_ERROR(
"failed to invoke callback for event {} with listener {}",
event_identifier_, listener_id);
qCWarning(core) << "failed to invoke callback for event: "
<< event_identifier_
<< " with listener:" << listener_id;
}
}
}
@ -112,7 +104,7 @@ class Event::Impl {
GFModuleEventParam* p_param;
int index = 0;
for (const auto& data : data_) {
for (const auto& data : data_.asKeyValueRange()) {
p_param = static_cast<GFModuleEventParam*>(
SecureMalloc(sizeof(GFModuleEventParam)));
if (index++ == 0) event->params = p_param;
@ -131,14 +123,12 @@ class Event::Impl {
private:
EventIdentifier event_identifier_;
EventTriggerIdentifier trigger_uuid_ = QUuid::createUuid().toString();
std::map<QString, QString> data_;
QMap<QString, QString> data_;
EventCallback callback_;
QThread* callback_thread_ = nullptr; ///<
};
Event::Event(const QString& event_id,
std::initializer_list<ParameterInitializer> params,
EventCallback callback)
Event::Event(const QString& event_id, Params params, EventCallback callback)
: p_(SecureCreateUniqueObject<Impl>(event_id, params,
std::move(callback))) {}
@ -170,8 +160,8 @@ void Event::AddParameter(const QString& key, const QString& value) {
p_->AddParameter(key, value);
}
void Event::ExecuteCallback(ListenerIdentifier l_id, DataObjectPtr d_o) {
p_->ExecuteCallback(std::move(l_id), d_o);
void Event::ExecuteCallback(ListenerIdentifier l_id, const Params& param) {
p_->ExecuteCallback(std::move(l_id), param);
}
auto Event::ToModuleEvent() -> GFModuleEvent* { return p_->ToModuleEvent(); }

View File

@ -34,7 +34,7 @@
#include "core/GpgFrontendCore.h"
#include "core/model/DataObject.h"
#include "module/sdk/GFSDKModule.h"
#include "sdk/GFSDKModule.h"
namespace GpgFrontend::Module {
@ -50,16 +50,16 @@ class GPGFRONTEND_CORE_EXPORT Event {
using ParameterValue = std::any;
using EventIdentifier = QString;
using ListenerIdentifier = QString;
using Params = QMap<QString, QString>;
using EventCallback =
std::function<void(EventIdentifier, ListenerIdentifier, DataObjectPtr)>;
std::function<void(EventIdentifier, ListenerIdentifier, Params)>;
struct ParameterInitializer {
QString key;
QString value;
};
explicit Event(const QString&,
std::initializer_list<ParameterInitializer> = {},
EventCallback = nullptr);
explicit Event(const QString&, Params = {}, EventCallback = nullptr);
~Event();
@ -81,7 +81,7 @@ class GPGFRONTEND_CORE_EXPORT Event {
void AddParameter(const QString& key, const QString& value);
void ExecuteCallback(ListenerIdentifier, DataObjectPtr);
void ExecuteCallback(ListenerIdentifier, const Params&);
auto ToModuleEvent() -> GFModuleEvent*;
@ -91,10 +91,8 @@ class GPGFRONTEND_CORE_EXPORT Event {
};
template <typename... Args>
auto MakeEvent(const EventIdentifier& event_id, Args&&... args,
auto MakeEvent(const EventIdentifier& event_id, const Event::Params& params,
Event::EventCallback e_cb) -> EventReference {
std::initializer_list<Event::ParameterInitializer> params = {
Event::ParameterInitializer{std::forward<Args>(args)}...};
return GpgFrontend::SecureCreateSharedObject<Event>(event_id, params, e_cb);
}

View File

@ -54,8 +54,8 @@ class GlobalModuleContext::Impl {
// Search for the module in the register table.
auto module_info_opt = search_module_register_table(module_id);
if (!module_info_opt.has_value()) {
GF_CORE_LOG_ERROR("cannot find module id {} at register table",
module_id);
qCWarning(core) << "cannot find module id " << module_id
<< " at register table";
return nullptr;
}
@ -67,11 +67,11 @@ class GlobalModuleContext::Impl {
auto module_info_opt =
search_module_register_table(module->GetModuleIdentifier());
if (!module_info_opt.has_value()) {
GF_CORE_LOG_ERROR(
"cannot find module id {} at register table, fallbacking to "
"default "
"channel",
module->GetModuleIdentifier());
qCWarning(core) << "cannot find module id "
<< module->GetModuleIdentifier()
<< " at register table, fallback to "
"default channel";
return GetDefaultChannel(module);
}
@ -99,20 +99,17 @@ class GlobalModuleContext::Impl {
}
auto RegisterModule(const ModulePtr& module, bool integrated_module) -> bool {
GF_CORE_LOG_DEBUG("attempting to register module: {}",
module->GetModuleIdentifier());
// Check if the module is null or already registered.
if (module == nullptr ||
module_register_table_.find(module->GetModuleIdentifier()) !=
module_register_table_.end()) {
GF_CORE_LOG_ERROR(
"module is null or have already registered this module");
qCWarning(core, "module is null or have already registered this module");
return false;
}
if (module->Register() != 0) {
GF_CORE_LOG_ERROR("register module {} failed",
module->GetModuleIdentifier());
qCWarning(core) << "register module " << module->GetModuleIdentifier()
<< " failed";
return false;
}
@ -132,19 +129,15 @@ class GlobalModuleContext::Impl {
// Register the module with its identifier.
module_register_table_[module->GetModuleIdentifier()] = register_info;
GF_CORE_LOG_DEBUG("successfully registered module: {}",
module->GetModuleIdentifier());
return true;
}
auto ActiveModule(ModuleIdentifier module_id) -> bool {
GF_CORE_LOG_DEBUG("attempting to activate module: {}", module_id);
// Search for the module in the register table.
auto module_info_opt = search_module_register_table(module_id);
if (!module_info_opt.has_value()) {
GF_CORE_LOG_ERROR("cannot find module id {} at register table",
module_id);
qCWarning(core) << "cannot find module id " << module_id
<< " at register table";
return false;
}
@ -153,9 +146,8 @@ class GlobalModuleContext::Impl {
// try to get module from module info
auto module = module_info->module;
if (module == nullptr) {
GF_CORE_LOG_ERROR(
"module id {} at register table is releated to a null module",
module_id);
qCWarning(core) << "module id:" << module_id
<< " at register table is related to a null module";
return false;
}
@ -165,19 +157,15 @@ class GlobalModuleContext::Impl {
module_info->activate = true;
}
GF_CORE_LOG_DEBUG("module activation status: {}", module_info->activate);
return module_info->activate;
}
auto ListenEvent(ModuleIdentifier module_id, EventIdentifier event) -> bool {
GF_CORE_LOG_DEBUG("module: {} is attempting to listen to event {}",
module_id, event);
// module -> event
auto module_info_opt = search_module_register_table(module_id);
if (!module_info_opt.has_value()) {
GF_CORE_LOG_ERROR("cannot find module id {} at register table",
module_id);
qCWarning(core) << "cannot find module id" << module_id
<< "at register table";
return false;
}
@ -186,7 +174,6 @@ class GlobalModuleContext::Impl {
if (met_it == module_events_table_.end()) {
module_events_table_[event] = std::unordered_set<ModuleIdentifier>();
met_it = module_events_table_.find(event);
GF_CORE_LOG_DEBUG("new event {} of module system created", event);
}
module_info_opt.value()->listening_event_ids.push_back(event);
@ -204,14 +191,14 @@ class GlobalModuleContext::Impl {
// search for the module in the register table.
auto module_info_opt = search_module_register_table(module_id);
if (!module_info_opt.has_value()) {
GF_CORE_LOG_ERROR("cannot find module id {} at register table",
module_id);
qCWarning(core) << "cannot find module id " << module_id
<< " at register table";
return false;
}
auto module_info = module_info_opt.value();
// activate the module if it is not already deactive.
if (module_info->activate && (module_info->module->Deactive() == 0)) {
// activate the module if it is not already Deactivate.
if (module_info->activate && (module_info->module->Deactivate() == 0)) {
for (const auto& event_ids : module_info->listening_event_ids) {
auto& modules = module_events_table_[event_ids];
if (auto it = modules.find(module_id); it != modules.end()) {
@ -228,15 +215,13 @@ class GlobalModuleContext::Impl {
auto TriggerEvent(const EventReference& event) -> bool {
auto event_id = event->GetIdentifier();
GF_CORE_LOG_DEBUG("attempting to trigger event: {}", event_id);
// Find the set of listeners associated with the given event in the table
auto met_it = module_events_table_.find(event_id);
if (met_it == module_events_table_.end()) {
// Log a warning if the event is not registered and nobody is listening
GF_CORE_LOG_WARN(
"event {} is not listening by anyone and not registered as well",
event_id);
qCInfo(core) << "event: " << event_id
<< " is not listening by anyone and not registered as well.";
return false;
}
@ -246,15 +231,10 @@ class GlobalModuleContext::Impl {
// Check if the set of listeners is empty
if (listeners_set.empty()) {
// Log a warning if nobody is listening to this event
GF_CORE_LOG_WARN("event {} is not listening by anyone",
event->GetIdentifier());
qCInfo(core) << "event: " << event_id << " is not listening by anyone";
return false;
}
// Log the number of listeners for this event
GF_CORE_LOG_DEBUG("event {}'s current listeners size: {}",
event->GetIdentifier(), listeners_set.size());
// register trigger id index table
module_on_triggering_events_table_[event->GetTriggerIdentifier()] = event;
@ -265,8 +245,8 @@ class GlobalModuleContext::Impl {
// Log an error if the module is not found in the registration table
if (!module_info_opt.has_value()) {
GF_CORE_LOG_ERROR("cannot find module id {} at register table",
listener_module_id);
qCWarning(core) << "cannot find module id: " << listener_module_id
<< " at register table";
continue;
}
@ -274,11 +254,6 @@ class GlobalModuleContext::Impl {
auto module_info = module_info_opt.value();
auto module = module_info->module;
GF_CORE_LOG_DEBUG(
"module {} is listening to event {}, activate state: {}",
module_info->module->GetModuleIdentifier(), event->GetIdentifier(),
module_info->activate);
// Check if the module is activated
if (!module_info->activate) continue;
@ -289,9 +264,9 @@ class GlobalModuleContext::Impl {
[listener_module_id, event_id](int code, DataObjectPtr) {
if (code < 0) {
// Log an error if the module execution fails
GF_CORE_LOG_ERROR(
"module {} execution failed of event {}: exec return code {}",
listener_module_id, event_id, code);
qCWarning(core) << "module " << listener_module_id
<< "execution failed of event " << event_id
<< ": exec return code: " << code;
}
};

View File

@ -126,8 +126,8 @@ class GlobalRegisterTable::Impl {
return rtn;
}
auto ListenPublish(QObject* o, const Namespace& n, const Key& k, LPCallback c)
-> bool {
auto ListenPublish(QObject* o, const Namespace& n, const Key& k,
LPCallback c) -> bool {
if (o == nullptr) return false;
return QObject::connect(parent_, &GlobalRegisterTable::SignalPublish, o,
[n, k, c](const Namespace& pn, const Key& pk,
@ -138,7 +138,7 @@ class GlobalRegisterTable::Impl {
}) == nullptr;
}
auto RootRTNode() -> RTNode* { return root_node_.get(); }
auto RootRTNode() -> RTNodePtr { return root_node_; }
private:
std::shared_mutex lock_;
@ -165,8 +165,8 @@ class GlobalRegisterTableTreeModel::Impl {
return 4;
}
[[nodiscard]] auto Data(const QModelIndex& index, int role) const
-> QVariant {
[[nodiscard]] auto Data(const QModelIndex& index,
int role) const -> QVariant {
if (!index.isValid()) return {};
if (role == Qt::DisplayRole) {
@ -232,8 +232,8 @@ class GlobalRegisterTableTreeModel::Impl {
return tr("<UNSUPPORTED>");
}
[[nodiscard]] auto Index(int row, int column, const QModelIndex& parent) const
-> QModelIndex {
[[nodiscard]] auto Index(int row, int column,
const QModelIndex& parent) const -> QModelIndex {
if (!parent_->hasIndex(row, column, parent)) return {};
auto* parent_node = !parent.isValid()
@ -292,8 +292,8 @@ auto GlobalRegisterTable::PublishKV(Namespace n, Key k, std::any v) -> bool {
return p_->PublishKV(n, k, v);
}
auto GlobalRegisterTable::LookupKV(Namespace n, Key v)
-> std::optional<std::any> {
auto GlobalRegisterTable::LookupKV(Namespace n,
Key v) -> std::optional<std::any> {
return p_->LookupKV(n, v);
}
@ -302,14 +302,15 @@ auto GlobalRegisterTable::ListenPublish(QObject* o, Namespace n, Key k,
return p_->ListenPublish(o, n, k, c);
}
auto GlobalRegisterTable::ListChildKeys(Namespace n, Key k)
-> std::vector<Key> {
auto GlobalRegisterTable::ListChildKeys(Namespace n,
Key k) -> std::vector<Key> {
return p_->ListChildKeys(n, k);
}
GlobalRegisterTableTreeModel::GlobalRegisterTableTreeModel(
GlobalRegisterTable* grt)
: p_(SecureCreateUniqueObject<Impl>(this, grt->p_.get())) {}
GlobalRegisterTable* grt, QObject* parent)
: QAbstractItemModel(parent),
p_(SecureCreateUniqueObject<Impl>(this, grt->p_.get())) {}
auto GlobalRegisterTableTreeModel::rowCount(const QModelIndex& parent) const
-> int {
@ -326,9 +327,8 @@ auto GlobalRegisterTableTreeModel::data(const QModelIndex& index,
return p_->Data(index, role);
}
auto GlobalRegisterTableTreeModel::index(int row, int column,
const QModelIndex& parent) const
-> QModelIndex {
auto GlobalRegisterTableTreeModel::index(
int row, int column, const QModelIndex& parent) const -> QModelIndex {
return p_->Index(row, column, parent);
}

View File

@ -34,15 +34,16 @@ namespace GpgFrontend::Module {
class GPGFRONTEND_CORE_EXPORT GlobalRegisterTableTreeModel
: public QAbstractItemModel {
public:
explicit GlobalRegisterTableTreeModel(GlobalRegisterTable *grt);
explicit GlobalRegisterTableTreeModel(GlobalRegisterTable *grt,
QObject *parent);
[[nodiscard]] auto rowCount(const QModelIndex &parent) const -> int override;
[[nodiscard]] auto columnCount(const QModelIndex &parent) const
-> int override;
[[nodiscard]] auto data(const QModelIndex &index, int role) const
-> QVariant override;
[[nodiscard]] auto data(const QModelIndex &index,
int role) const -> QVariant override;
[[nodiscard]] auto index(int row, int column, const QModelIndex &parent) const
-> QModelIndex override;

View File

@ -31,7 +31,7 @@
#include "core/module/GlobalModuleContext.h"
#include "core/utils/CommonUtils.h"
#include "core/utils/IOUtils.h"
#include "module/sdk/GFSDKModule.h"
#include "sdk/GFSDKModule.h"
#include "utils/BuildInfoUtils.h"
namespace GpgFrontend::Module {
@ -59,9 +59,9 @@ class Module::Impl {
*required_symbol.pointer =
reinterpret_cast<void*>(module_library.resolve(required_symbol.name));
if (*required_symbol.pointer == nullptr) {
GF_CORE_LOG_WARN(
"illegal module: {}, reason: cannot load symbol: {}, abort...",
module_library.fileName(), required_symbol.name);
qCWarning(core) << "illegal module: " << module_library.fileName()
<< ", reason cannot load symbol: "
<< required_symbol.name << ", abort...";
return;
}
}
@ -72,39 +72,38 @@ class Module::Impl {
qt_env_ver_ = GFUnStrDup(get_qt_ver_api_());
if (!module_identifier_regex_exp_.match(identifier_).hasMatch()) {
GF_CORE_LOG_WARN(
"illegal module: {}, reasson invalid module id, abort...",
identifier_);
qCWarning(core) << "illegal module: " << identifier_
<< ", reason invalid module id, abort...";
return;
}
if (!module_version_regex_exp_.match(version_).hasMatch()) {
GF_CORE_LOG_WARN(
"illegal module: {}, reasson invalid version: {}, abort...",
identifier_, version_);
qCWarning(core) << "illegal module: " << identifier_
<< ", reason invalid version: " << version_
<< ", abort...";
return;
}
if (!module_version_regex_exp_.match(gf_sdk_ver_).hasMatch()) {
GF_CORE_LOG_WARN(
"illegal module: {}, reasson invalid sdk version: {}, abort...",
identifier_, gf_sdk_ver_);
qCWarning(core) << "illegal module: " << identifier_
<< ", reason invalid sdk version: " << gf_sdk_ver_
<< ", abort...";
return;
}
if (GFCompareSoftwareVersion(gf_sdk_ver_, GetProjectVersion()) > 0) {
GF_CORE_LOG_WARN(
"uncompatible module: {}, sdk version: {} greater than "
"current sdk version: {}, abort...",
identifier_, gf_sdk_ver_, GetProjectVersion());
qCWarning(core) << "uncompatible module: " << identifier_
<< ", reason sdk version: " << gf_sdk_ver_
<< "current sdk version: " << GetProjectVersion()
<< ", abort...";
return;
}
auto qt_env_ver_regex_match = module_version_regex_exp_.match(qt_env_ver_);
if (!qt_env_ver_regex_match.hasMatch()) {
GF_CORE_LOG_WARN(
"illegal module: {}, reasson invalid qt env version: {}, abort...",
identifier_, qt_env_ver_);
qCWarning(core) << "illegal module: " << identifier_
<< ", reason invalid qt env version: " << qt_env_ver_
<< ", abort...";
return;
}
@ -113,19 +112,13 @@ class Module::Impl {
if (qt_env_ver_major != QString::number(QT_VERSION_MAJOR) + "." ||
qt_env_ver_minor != QString::number(QT_VERSION_MINOR) + ".") {
GF_CORE_LOG_WARN(
"uncompatible module: {}, qt version: {} is not binary uncompatible "
"with application's qt env version: {}, abort...",
identifier_, qt_env_ver_, QString::fromUtf8(QT_VERSION_STR));
qCWarning(core) << "uncompatible module: " << identifier_
<< ", reason sdk version: " << qt_env_ver_
<< "current sdk version: "
<< QString::fromUtf8(QT_VERSION_STR) << ", abort...";
return;
}
GF_CORE_LOG_INFO(
"module loaded, id: {}, version: {}, "
"sdk version: {}, qt env version: {}, hash: {}, path: {}",
identifier_, version_, gf_sdk_ver_, qt_env_ver_, module_hash_,
module_library_path_);
::GFModuleMetaData* p_meta_data = get_metadata_api_();
while (p_meta_data != nullptr) {
@ -159,7 +152,7 @@ class Module::Impl {
return -1;
}
auto Deactive() -> int {
auto Deactivate() -> int {
if (good_ && deactivate_api_ != nullptr) return deactivate_api_();
return -1;
}
@ -255,7 +248,7 @@ class Module::Impl {
{"GFRegisterModule", reinterpret_cast<void**>(&register_api_)},
{"GFActiveModule", reinterpret_cast<void**>(&activate_api_)},
{"GFExecuteModule", reinterpret_cast<void**>(&execute_api_)},
{"GFDeactiveModule", reinterpret_cast<void**>(&deactivate_api_)},
{"GFDeactivateModule", reinterpret_cast<void**>(&deactivate_api_)},
{"GFUnregisterModule", reinterpret_cast<void**>(&unregister_api_)},
};
@ -286,7 +279,7 @@ auto Module::Exec(EventReference event) -> int {
return p_->Exec(std::move(event));
}
auto Module::Deactive() -> int { return p_->Deactive(); }
auto Module::Deactivate() -> int { return p_->Deactivate(); }
auto Module::UnRegister() -> int { return p_->UnRegister(); }

View File

@ -61,7 +61,7 @@ class GPGFRONTEND_CORE_EXPORT Module : public QObject {
virtual auto Exec(EventReference) -> int;
virtual auto Deactive() -> int;
virtual auto Deactivate() -> int;
virtual auto UnRegister() -> int;

View File

@ -39,11 +39,8 @@
namespace GpgFrontend::Module {
void LoadModuleFromPath(const QString& mods_path, bool integrated) {
for (const auto& module_library_name :
QDir(mods_path).entryList(QStringList() << "*.so"
<< "*.dll"
<< "*.dylib",
QDir::Files)) {
for (const auto& module_library_name : QDir(mods_path).entryList(
QStringList() << "*.so" << "*.dll" << "*.dylib", QDir::Files)) {
ModuleManager::GetInstance().LoadModule(
mods_path + "/" + module_library_name, integrated);
}
@ -54,34 +51,30 @@ auto LoadIntegratedMods() -> bool {
#if defined(MACOS) && defined(RELEASE)
// App Bundle
auto mods_path = exec_binary_path + "/../PlugIns/mods";
auto mods_path = exec_binary_path + "/../Modules";
#else
// Debug Or Windows Platform
auto mods_path = exec_binary_path + "/mods";
auto mods_path = exec_binary_path + "/modules";
#endif
// AppImage
if (!qEnvironmentVariable("APPIMAGE").isEmpty()) {
mods_path = qEnvironmentVariable("APPDIR") + "/usr/plugins/mods";
mods_path = qEnvironmentVariable("APPDIR") + "/usr/modules";
}
// Flatpak
if (!qEnvironmentVariable("container").isEmpty()) {
mods_path = "/app/lib/mods";
mods_path = "/app/modules";
}
GF_CORE_LOG_DEBUG("try loading integrated modules at path: {} ...",
mods_path);
if (!QDir(mods_path).exists()) {
GF_CORE_LOG_WARN(
"integrated module directory at path {} not found, abort...",
mods_path);
qCWarning(core) << "integrated module directory at path: " << mods_path
<< " not found, abort...";
return false;
}
LoadModuleFromPath(mods_path, true);
GF_CORE_LOG_DEBUG("load integrated modules done.");
return true;
}
@ -89,16 +82,14 @@ auto LoadExternalMods() -> bool {
auto mods_path =
GpgFrontend::GlobalSettingStation::GetInstance().GetModulesDir();
GF_CORE_LOG_DEBUG("try loading external modules at path: {} ...", mods_path);
if (!QDir(mods_path).exists()) {
GF_CORE_LOG_WARN("external module directory at path {} not found, abort...",
mods_path);
qCWarning(core) << "external module directory at path " << mods_path
<< " not found, abort...";
return false;
}
LoadModuleFromPath(mods_path, false);
GF_CORE_LOG_DEBUG("load integrated modules done.");
return true;
}

View File

@ -28,15 +28,11 @@
#pragma once
#include <spdlog/spdlog.h>
#include "core/GpgFrontendCoreExport.h"
namespace GpgFrontend::Module {
struct ModuleInitArgs {
spdlog::level::level_enum log_level;
};
struct ModuleInitArgs {};
/**
* @brief init the module library

View File

@ -31,6 +31,7 @@
#include <memory>
#include <utility>
#include "core/function/GlobalSettingStation.h"
#include "core/function/SecureMemoryAllocator.h"
#include "core/function/basic/GpgFunctionObject.h"
#include "core/model/SettingsObject.h"
@ -54,25 +55,31 @@ class ModuleManager::Impl {
auto LoadAndRegisterModule(const QString& module_library_path,
bool integrated_module) -> void {
// give user ability to give up all modules
auto disable_loading_all_modules =
GlobalSettingStation::GetInstance()
.GetSettings()
.value("basic/disable_loading_all_modules", false)
.toBool();
if (disable_loading_all_modules) return;
Thread::TaskRunnerGetter::GetInstance()
.GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Default)
->PostTask(new Thread::Task(
[=](GpgFrontend::DataObjectPtr) -> int {
QLibrary module_library(module_library_path);
if (!module_library.load()) {
GF_CORE_LOG_WARN(
"module manager failed to load module, "
"reason: broken library: {} ",
module_library.fileName());
qCWarning(core) << "module manager failed to load module: "
<< module_library.fileName()
<< ", reason: " << module_library.errorString();
return -1;
}
auto module = SecureCreateSharedObject<Module>(module_library);
if (!module->IsGood()) {
GF_CORE_LOG_WARN(
"module manager failed to load module, "
"reason: illegal module: {}",
module_library.fileName());
qCWarning(core) << "module manager failed to load module, "
"reason: illegal module: "
<< module_library.fileName();
return -1;
}
@ -172,7 +179,7 @@ class ModuleManager::Impl {
__func__, nullptr));
}
void DeactiveModule(const ModuleIdentifier& identifier) {
void DeactivateModule(const ModuleIdentifier& identifier) {
Thread::TaskRunnerGetter::GetInstance()
.GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Default)
->PostTask(new Thread::Task(
@ -231,13 +238,13 @@ auto UpsertRTValue(const QString& namespace_, const QString& key,
std::any(value));
}
auto ListenRTPublishEvent(QObject* o, Namespace n, Key k, LPCallback c)
-> bool {
auto ListenRTPublishEvent(QObject* o, Namespace n, Key k,
LPCallback c) -> bool {
return ModuleManager::GetInstance().ListenRTPublish(o, n, k, c);
}
auto ListRTChildKeys(const QString& namespace_, const QString& key)
-> std::vector<Key> {
auto ListRTChildKeys(const QString& namespace_,
const QString& key) -> std::vector<Key> {
return ModuleManager::GetInstance().ListRTChildKeys(namespace_, key);
}
@ -283,8 +290,8 @@ void ModuleManager::ActiveModule(ModuleIdentifier id) {
return p_->ActiveModule(id);
}
void ModuleManager::DeactiveModule(ModuleIdentifier id) {
return p_->DeactiveModule(id);
void ModuleManager::DeactivateModule(ModuleIdentifier id) {
return p_->DeactivateModule(id);
}
auto ModuleManager::GetTaskRunner(ModuleIdentifier id)
@ -296,8 +303,8 @@ auto ModuleManager::UpsertRTValue(Namespace n, Key k, std::any v) -> bool {
return p_->UpsertRTValue(n, k, v);
}
auto ModuleManager::RetrieveRTValue(Namespace n, Key k)
-> std::optional<std::any> {
auto ModuleManager::RetrieveRTValue(Namespace n,
Key k) -> std::optional<std::any> {
return p_->RetrieveRTValue(n, k);
}
@ -306,8 +313,8 @@ auto ModuleManager::ListenRTPublish(QObject* o, Namespace n, Key k,
return p_->ListenPublish(o, n, k, c);
}
auto ModuleManager::ListRTChildKeys(const QString& n, const QString& k)
-> std::vector<Key> {
auto ModuleManager::ListRTChildKeys(const QString& n,
const QString& k) -> std::vector<Key> {
return p_->ListRTChildKeys(n, k);
}

View File

@ -28,7 +28,6 @@
#pragma once
#include <mutex>
#include <vector>
#include "core/function/SecureMemoryAllocator.h"
@ -88,7 +87,7 @@ class GPGFRONTEND_CORE_EXPORT ModuleManager
void ActiveModule(ModuleIdentifier);
void DeactiveModule(ModuleIdentifier);
void DeactivateModule(ModuleIdentifier);
auto GetTaskRunner(ModuleIdentifier) -> std::optional<TaskRunnerPtr>;
@ -123,10 +122,10 @@ void RegisterAndActivateModule(Args&&... args) {
}
template <typename... Args>
void TriggerEvent(const EventIdentifier& event_id, Args&&... args,
void TriggerEvent(const EventIdentifier& event_id,
const Event::Params& params = {},
Event::EventCallback e_cb = nullptr) {
ModuleManager::GetInstance().TriggerEvent(
std::move(MakeEvent(event_id, std::forward<Args>(args)..., e_cb)));
ModuleManager::GetInstance().TriggerEvent(MakeEvent(event_id, params, e_cb));
}
/**
@ -166,13 +165,12 @@ auto GPGFRONTEND_CORE_EXPORT ListenRTPublishEvent(QObject*, Namespace, Key,
* @param key
* @return std::vector<Key>
*/
auto GPGFRONTEND_CORE_EXPORT ListRTChildKeys(const QString& namespace_,
const QString& key)
-> std::vector<Key>;
auto GPGFRONTEND_CORE_EXPORT ListRTChildKeys(
const QString& namespace_, const QString& key) -> std::vector<Key>;
template <typename T>
auto RetrieveRTValueTyped(const QString& namespace_, const QString& key)
-> std::optional<T> {
auto RetrieveRTValueTyped(const QString& namespace_,
const QString& key) -> std::optional<T> {
auto any_value =
ModuleManager::GetInstance().RetrieveRTValue(namespace_, key);
if (any_value && any_value->type() == typeid(T)) {
@ -183,8 +181,8 @@ auto RetrieveRTValueTyped(const QString& namespace_, const QString& key)
template <typename T>
auto RetrieveRTValueTypedOrDefault(const QString& namespace_,
const QString& key, const T& defaultValue)
-> T {
const QString& key,
const T& defaultValue) -> T {
auto any_value =
ModuleManager::GetInstance().RetrieveRTValue(namespace_, key);
if (any_value && any_value->type() == typeid(T)) {

View File

@ -41,17 +41,15 @@ FileReadTask::FileReadTask(QString path)
auto FileReadTask::Run() -> int {
if (QFileInfo(read_file_path_).isFile()) {
GF_CORE_LOG_DEBUG("read open file: {}", read_file_path_);
target_file_.setFileName(read_file_path_);
target_file_.open(QIODevice::ReadOnly);
if (!(target_file_.isOpen() && target_file_.isReadable())) {
GF_CORE_LOG_ERROR("file not open or not readable");
qCWarning(core, "file not open or not readable");
if (target_file_.isOpen()) target_file_.close();
return -1;
}
GF_CORE_LOG_DEBUG("started reading: {}", read_file_path_);
slot_read_bytes();
} else {
emit SignalFileBytesReadEnd();
@ -64,10 +62,8 @@ void FileReadTask::slot_read_bytes() {
if (QByteArray read_buffer;
!target_file_.atEnd() &&
(read_buffer = target_file_.read(kBufferSize)).size() > 0) {
GF_CORE_LOG_DEBUG("io thread read bytes: {}", read_buffer.size());
emit SignalFileBytesRead(std::move(read_buffer));
} else {
GF_CORE_LOG_DEBUG("io thread read bytes end");
emit SignalFileBytesReadEnd();
// announce finish task
emit SignalTaskShouldEnd(0);
@ -75,7 +71,6 @@ void FileReadTask::slot_read_bytes() {
}
FileReadTask::~FileReadTask() {
GF_CORE_LOG_DEBUG("close file: {}", read_file_path_);
if (target_file_.isOpen()) target_file_.close();
}

View File

@ -38,7 +38,6 @@ class Task::Impl {
public:
Impl(Task *parent, QString name)
: parent_(parent), uuid_(generate_uuid()), name_(std::move(name)) {
GF_CORE_LOG_TRACE("task {} created", GetFullID());
init();
}
@ -51,8 +50,6 @@ class Task::Impl {
callback_([](int, const DataObjectPtr &) {}),
callback_thread_(QThread::currentThread()),
data_object_(std::move(data_object)) {
GF_CORE_LOG_TRACE("task {} created with runnable, callback_thread_: {}",
GetFullID(), static_cast<void *>(callback_thread_));
init();
}
@ -65,13 +62,10 @@ class Task::Impl {
callback_(std::move(callback)),
callback_thread_(QThread::currentThread()),
data_object_(std::move(data_object)) {
GF_CORE_LOG_TRACE(
"task {} created with runnable and callback, callback_thread_: {}",
GetFullID(), static_cast<void *>(callback_thread_));
init();
}
~Impl() { GF_CORE_LOG_TRACE("task {} destroyed", GetFullID()); }
~Impl() = default;
/**
* @brief
@ -95,13 +89,7 @@ class Task::Impl {
* @return int
*/
auto Run() -> int {
GF_CORE_LOG_TRACE("task {} is in classical runnable and callback mode",
GetFullID());
if (runnable_) return runnable_(data_object_);
GF_CORE_LOG_WARN("no runnable in task, do callback operation, task: {}",
GetFullID());
return 0;
}
@ -137,9 +125,6 @@ class Task::Impl {
DataObjectPtr data_object_ = nullptr; ///<
void init() {
GF_CORE_LOG_TRACE("task {} created, parent: {}, impl: {}", name_,
static_cast<void *>(parent_), static_cast<void *>(this));
//
HoldOnLifeCycle(false);
@ -156,17 +141,11 @@ class Task::Impl {
SetRTN(rtn);
try {
if (callback_) {
GF_CORE_LOG_TRACE(
"task callback {} is starting with runnerable rtn: {}",
GetFullID(), rtn);
callback_(rtn_, data_object_);
GF_CORE_LOG_TRACE("task callback {} finished, rtn: {}",
GetFullID(), rtn);
}
} catch (...) {
GF_CORE_LOG_ERROR("task {} callback caught exception, rtn: {}",
GetFullID(), rtn);
qCWarning(core) << "task: {}, " << GetFullID()
<< "callback caught exception, rtn: " << rtn;
}
emit parent_->SignalTaskEnd();
});
@ -214,11 +193,7 @@ void Task::SafelyRun() { emit SignalRun(); }
int Task::Run() { return p_->Run(); }
void Task::run() {
GF_CORE_LOG_TRACE("interface run() of task {} was called by thread: {}",
GetFullID(), QThread::currentThread()->currentThreadId());
this->SafelyRun();
}
void Task::run() { this->SafelyRun(); }
Task::TaskHandler::TaskHandler(Task *task) : task_(task) {}
@ -238,14 +213,11 @@ auto Task::TaskHandler::GetTask() -> Task * {
void Task::slot_exception_safe_run() noexcept {
auto rtn = p_->GetRTN();
try {
GF_CORE_LOG_TRACE("task runnable {} is starting...", GetFullID());
// Run() will set rtn by itself
rtn = this->Run();
GF_CORE_LOG_TRACE("task runnable {} finished, rtn: {}", GetFullID());
} catch (...) {
GF_CORE_LOG_ERROR("exception was caught at task: {}", GetFullID());
qCWarning(core) << "exception was caught at task: {}" << GetFullID();
}
// raise signal to anounce after runnable returned

View File

@ -38,21 +38,19 @@ class TaskRunner::Impl : public QThread {
void PostTask(Task* task) {
if (task == nullptr) {
GF_CORE_LOG_ERROR("task posted is null");
qCWarning(core, "task posted is null");
return;
}
task->setParent(nullptr);
task->moveToThread(this);
GF_CORE_LOG_TRACE("runner starts task: {} at thread: {}", task->GetFullID(),
this->currentThreadId());
task->SafelyRun();
}
auto RegisterTask(const QString& name, const Task::TaskRunnable& runnerable,
const Task::TaskCallback& cb, DataObjectPtr params)
-> Task::TaskHandler {
const Task::TaskCallback& cb,
DataObjectPtr params) -> Task::TaskHandler {
auto* raw_task = new Task(runnerable, name, std::move(params), cb);
raw_task->setParent(nullptr);
raw_task->moveToThread(this);
@ -65,9 +63,6 @@ class TaskRunner::Impl : public QThread {
pending_tasks_.remove(raw_task->GetFullID());
});
GF_CORE_LOG_TRACE("runner starts task: {} at thread: {}",
raw_task->GetFullID(), this->currentThreadId());
return Task::TaskHandler(raw_task);
}
@ -78,7 +73,7 @@ class TaskRunner::Impl : public QThread {
void PostConcurrentTask(Task* task) {
if (task == nullptr) {
GF_CORE_LOG_ERROR("task posted is null");
qCWarning(core, "task posted is null");
return;
}
@ -93,8 +88,6 @@ class TaskRunner::Impl : public QThread {
concurrent_thread->start();
GF_CORE_LOG_TRACE("runner starts task concurrenctly: {}",
task->GetFullID());
task->SafelyRun();
}
@ -143,8 +136,8 @@ auto TaskRunner::IsRunning() -> bool { return p_->isRunning(); }
auto TaskRunner::RegisterTask(const QString& name,
const Task::TaskRunnable& runnable,
const Task::TaskCallback& cb, DataObjectPtr p_pbj)
-> Task::TaskHandler {
const Task::TaskCallback& cb,
DataObjectPtr p_pbj) -> Task::TaskHandler {
return p_->RegisterTask(name, runnable, cb, p_pbj);
}
} // namespace GpgFrontend::Thread

View File

@ -58,6 +58,8 @@ using GpgKeyLinkList = std::list<GpgKey>; ///<
using KeyLinkListPtr = std::unique_ptr<GpgKeyLinkList>; ///<
using KeyPtr = std::unique_ptr<GpgKey>; ///<
using KeyPtrArgsList = const std::initializer_list<KeyPtr>; ///<
using GpgKeyList = QList<GpgKey>; ///<
using GpgKeyIDList = QList<QString>; ///<
using GpgSignMode = gpgme_sig_mode_t;

View File

@ -42,12 +42,10 @@ auto RunGpgOperaAsync(const GpgOperaRunnable& runnable,
-> Thread::Task::TaskHandler {
const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>(
"core", "gpgme.ctx.gnupg_version", minial_version);
GF_CORE_LOG_DEBUG("got gnupg version from rt: {}, operation: {}",
gnupg_version, operation);
if (GFCompareSoftwareVersion(gnupg_version, minial_version) < 0) {
GF_CORE_LOG_ERROR("operaton {} not support for gnupg version: {}",
operation, gnupg_version);
qCWarning(core) << "operation" << operation
<< " not support for gnupg version: " << gnupg_version;
callback(GPG_ERR_NOT_SUPPORTED, TransferParams());
return Thread::Task::TaskHandler(nullptr);
}
@ -82,12 +80,10 @@ auto RunGpgOperaSync(const GpgOperaRunnable& runnable, const QString& operation,
-> std::tuple<GpgError, DataObjectPtr> {
const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>(
"core", "gpgme.ctx.gnupg_version", minial_version);
GF_CORE_LOG_DEBUG("got gnupg version from rt: {}, operation: {}",
gnupg_version, operation);
if (GFCompareSoftwareVersion(gnupg_version, minial_version) < 0) {
GF_CORE_LOG_ERROR("operaton {} not support for gnupg version: {}",
operation, gnupg_version);
qCWarning(core) << "operation" << operation
<< " not support for gnupg version: " << gnupg_version;
return {GPG_ERR_NOT_SUPPORTED, TransferParams()};
}
@ -125,8 +121,8 @@ auto RunIOOperaAsync(const OperaRunnable& runnable,
}
auto RunOperaAsync(const OperaRunnable& runnable,
const OperationCallback& callback, const QString& operation)
-> Thread::Task::TaskHandler {
const OperationCallback& callback,
const QString& operation) -> Thread::Task::TaskHandler {
auto handler =
Thread::TaskRunnerGetter::GetInstance()
.GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Default)

View File

@ -5,9 +5,12 @@
namespace GpgFrontend {
auto GetProjectName() -> QString { return {PROJECT_NAME}; }
auto GetProjectVersion() -> QString {
return QString("v") + VERSION_MAJOR + "." + VERSION_MINOR + "." +
VERSION_PATCH;
return (QStringList{} << "v" << VERSION_MAJOR << "." << VERSION_MINOR << "."
<< VERSION_PATCH)
.join("");
}
auto GetProjectBuildVersion() -> QString { return BUILD_VERSION; }

View File

@ -32,6 +32,13 @@
namespace GpgFrontend {
/**
* @brief
*
* @return QString
*/
auto GPGFRONTEND_CORE_EXPORT GetProjectName() -> QString;
/**
* @brief
*

View File

@ -82,13 +82,13 @@ auto GFStrDup(const QString& str) -> char* {
return c_str;
}
auto GPGFRONTEND_CORE_EXPORT GFUnStrDup(char* str) -> QString {
auto GFUnStrDup(char* str) -> QString {
auto qt_str = QString::fromUtf8(str);
SecureFree(static_cast<void*>(const_cast<char*>(str)));
return qt_str;
}
auto GPGFRONTEND_CORE_EXPORT GFUnStrDup(const char* str) -> QString {
auto GFUnStrDup(const char* str) -> QString {
return GFUnStrDup(const_cast<char*>(str));
}

View File

@ -56,13 +56,13 @@ auto GPGFRONTEND_CORE_EXPORT GFCompareSoftwareVersion(const QString& a,
*
* @return char*
*/
auto GPGFRONTEND_CORE_EXPORT GFStrDup(const QString&) -> char*;
auto GFStrDup(const QString &) -> char *;
/**
* @brief
*
* @return QString
*/
auto GPGFRONTEND_CORE_EXPORT GFUnStrDup(const char*) -> QString;
auto GFUnStrDup(const char *) -> QString;
} // namespace GpgFrontend

View File

@ -50,9 +50,9 @@ auto GetGpgmeErrorString(gpgme_error_t err) -> QString {
auto CheckGpgError(GpgError err) -> GpgError {
auto err_code = gpg_err_code(err);
if (err_code != GPG_ERR_NO_ERROR) {
GF_CORE_LOG_ERROR(
"gpg operation failed [error code: {}], source: {} description: {}",
err_code, gpgme_strsource(err), GetGpgmeErrorString(err));
qCWarning(core) << "gpg operation failed [error code: " << err_code
<< "], source: " << gpgme_strsource(err)
<< " description: " << GetGpgmeErrorString(err);
}
return err_code;
}
@ -61,13 +61,15 @@ auto CheckGpgError2ErrCode(GpgError err, GpgError predict) -> GpgErrorCode {
auto err_code = gpg_err_code(err);
if (err_code != gpg_err_code(predict)) {
if (err_code == GPG_ERR_NO_ERROR) {
GF_CORE_LOG_WARN("[Warning {}] Source: {} description: {} predict: {}",
gpg_err_code(err), gpgme_strsource(err),
GetGpgmeErrorString(err), GetGpgmeErrorString(predict));
qCInfo(core) << "[Warning " << gpg_err_code(err)
<< "] Source: " << gpgme_strsource(err)
<< " description: " << GetGpgmeErrorString(err)
<< " predict: " << GetGpgmeErrorString(predict);
} else {
GF_CORE_LOG_ERROR("[Error {}] Source: {} description: {} predict: {}",
gpg_err_code(err), gpgme_strsource(err),
GetGpgmeErrorString(err), GetGpgmeErrorString(predict));
qCWarning(core) << "[Error " << gpg_err_code(err)
<< "] Source: " << gpgme_strsource(err)
<< " description: " << GetGpgmeErrorString(err)
<< " predict: " << GetGpgmeErrorString(predict);
}
}
return err_code;
@ -79,8 +81,9 @@ auto DescribeGpgErrCode(GpgError err) -> GpgErrorDesc {
auto CheckGpgError(GpgError err, const QString& /*comment*/) -> GpgError {
if (gpg_err_code(err) != GPG_ERR_NO_ERROR) {
GF_CORE_LOG_WARN("[Error {}] Source: {} description: {}", gpg_err_code(err),
gpgme_strsource(err), GetGpgmeErrorString(err));
qCWarning(core) << "[Error " << gpg_err_code(err)
<< "] Source: " << gpgme_strsource(err)
<< " description: " << GetGpgmeErrorString(err);
}
return err;
}

View File

@ -49,7 +49,7 @@ auto GetFileChecksum(const QString& file_name,
auto ReadFile(const QString& file_name, QByteArray& data) -> bool {
QFile file(file_name);
if (!file.open(QIODevice::ReadOnly)) {
GF_CORE_LOG_ERROR("failed to open file: {}", file_name);
qCWarning(core) << "failed to open file: " << file_name;
return false;
}
data = file.readAll();
@ -60,7 +60,7 @@ auto ReadFile(const QString& file_name, QByteArray& data) -> bool {
auto WriteFile(const QString& file_name, const QByteArray& data) -> bool {
QFile file(file_name);
if (!file.open(QIODevice::WriteOnly)) {
GF_CORE_LOG_ERROR("failed to open file for writing: {}", file_name);
qCWarning(core) << "failed to open file for writing: " << file_name;
return false;
}
file.write(data);
@ -100,20 +100,17 @@ auto CalculateHash(const QString& file_path) -> QString {
<< Qt::endl;
// md5
ss << "- "
<< "MD5" << QCoreApplication::tr(": ")
ss << "- " << "MD5" << QCoreApplication::tr(": ")
<< GetFileChecksum(file_path, QCryptographicHash::Md5).toHex()
<< Qt::endl;
// sha1
ss << "- "
<< "SHA1" << QCoreApplication::tr(": ")
ss << "- " << "SHA1" << QCoreApplication::tr(": ")
<< GetFileChecksum(file_path, QCryptographicHash::Sha1).toHex()
<< Qt::endl;
// sha1
ss << "- "
<< "SHA256" << QCoreApplication::tr(": ")
ss << "- " << "SHA256" << QCoreApplication::tr(": ")
<< GetFileChecksum(file_path, QCryptographicHash::Sha256).toHex()
<< Qt::endl;
@ -147,8 +144,8 @@ auto CreateTempFileAndWriteData(const GFBuffer& data) -> QString {
return temp_file;
}
auto TargetFilePreCheck(const QString& path, bool read)
-> std::tuple<bool, QString> {
auto TargetFilePreCheck(const QString& path,
bool read) -> std::tuple<bool, QString> {
QFileInfo const file_info(path);
if (read) {
@ -184,16 +181,16 @@ auto CalculateBinaryChacksum(const QString& path) -> QString {
// check file info and access rights
QFileInfo info(path);
if (!info.exists() || !info.isFile() || !info.isReadable()) {
GF_CORE_LOG_ERROR("get info for file {} error, exists: {}", info.filePath(),
info.exists());
qCWarning(core) << "get info for file: " << info.filePath()
<< " error, exists: " << info.exists();
return {};
}
// open and read file
QFile f(info.filePath());
if (!f.open(QIODevice::ReadOnly)) {
GF_CORE_LOG_ERROR("open {} to calculate checksum error: {}",
path.toStdString(), f.errorString().toStdString());
qCWarning(core) << "open " << path
<< "to calculate checksum error: " << f.errorString();
return {};
}
@ -204,8 +201,8 @@ auto CalculateBinaryChacksum(const QString& path) -> QString {
while (!f.atEnd()) {
QByteArray const buffer = f.read(buffer_size);
if (buffer.isEmpty()) {
GF_CORE_LOG_ERROR("error reading file {} during checksum calculation",
path.toStdString());
qCWarning(core) << "error reading file: " << path
<< " during checksum calculation";
return {};
}
hash_sha.addData(buffer);

View File

@ -28,8 +28,6 @@
#include "LocalizedUtils.h"
#include "core/utils/LogUtils.h"
namespace GpgFrontend {
auto GetLocalizedDateByTimestamp(time_t timestamp) -> QString {

View File

@ -1,59 +0,0 @@
/**
* Copyright (C) 2021 Saturneric <eric@bktus.com>
*
* 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 <eric@bktus.com> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "LogUtils.h"
#include "core/function/LoggerManager.h"
namespace GpgFrontend {
auto GetDefaultLogger() -> std::shared_ptr<spdlog::logger> {
return LoggerManager::GetDefaultLogger();
}
auto GetCoreLogger() -> std::shared_ptr<spdlog::logger> {
return LoggerManager::GetInstance().GetLogger("core");
}
auto GetLogger(const QString& id) -> std::shared_ptr<spdlog::logger> {
return LoggerManager::GetInstance().GetLogger(id);
}
void SetDefaultLogLevel(spdlog::level::level_enum level) {
return LoggerManager::SetDefaultLogLevel(level);
}
void RegisterAsyncLogger(const QString& id, spdlog::level::level_enum level) {
LoggerManager::GetInstance().RegisterAsyncLogger(id, level);
}
void RegisterSyncLogger(const QString& id, spdlog::level::level_enum level) {
LoggerManager::GetInstance().RegisterSyncLogger(id, level);
}
} // namespace GpgFrontend

View File

@ -1,155 +0,0 @@
/**
* Copyright (C) 2021 Saturneric <eric@bktus.com>
*
* 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 <eric@bktus.com> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#pragma once
// spdlog library configuration
#undef SPDLOG_ACTIVE_LEVEL
#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_TRACE
#include <spdlog/spdlog.h>
// logger fmt
#include "core/GpgFrontendCoreExport.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());
}
};
namespace GpgFrontend {
/**
* @brief
*
* @return std::shared_ptr<spdlog::logger>
*/
auto GPGFRONTEND_CORE_EXPORT GetDefaultLogger()
-> std::shared_ptr<spdlog::logger>;
/**
* @brief
*
* @return std::shared_ptr<spdlog::logger>
*/
auto GPGFRONTEND_CORE_EXPORT GetCoreLogger() -> std::shared_ptr<spdlog::logger>;
/**
* @brief
*
* @return std::shared_ptr<spdlog::logger>
*/
auto GPGFRONTEND_CORE_EXPORT GetLogger(const QString&)
-> std::shared_ptr<spdlog::logger>;
/**
* @brief Set the Default Log Level object
*
* @return auto
*/
void GPGFRONTEND_CORE_EXPORT SetDefaultLogLevel(spdlog::level::level_enum);
/**
* @brief
*
* @return auto
*/
void GPGFRONTEND_CORE_EXPORT RegisterAsyncLogger(const QString&,
spdlog::level::level_enum);
/**
* @brief
*
* @return auto
*/
void GPGFRONTEND_CORE_EXPORT RegisterSyncLogger(const QString&,
spdlog::level::level_enum);
} // namespace GpgFrontend
#define GF_DEFAULT_LOG_TRACE(...) \
SPDLOG_LOGGER_TRACE(GpgFrontend::GetDefaultLogger(), __VA_ARGS__)
#define GF_DEFAULT_LOG_DEBUG(...) \
SPDLOG_LOGGER_DEBUG(GpgFrontend::GetDefaultLogger(), __VA_ARGS__)
#define GF_DEFAULT_LOG_INFO(...) \
SPDLOG_LOGGER_INFO(GpgFrontend::GetDefaultLogger(), __VA_ARGS__)
#define GF_DEFAULT_LOG_WARN(...) \
SPDLOG_LOGGER_WARN(GpgFrontend::GetDefaultLogger(), __VA_ARGS__)
#define GF_DEFAULT_LOG_ERROR(...) \
SPDLOG_LOGGER_ERROR(GpgFrontend::GetDefaultLogger(), __VA_ARGS__)
#define GF_CORE_LOG_TRACE(...) \
SPDLOG_LOGGER_TRACE(GpgFrontend::GetCoreLogger(), __VA_ARGS__)
#define GF_CORE_LOG_DEBUG(...) \
SPDLOG_LOGGER_DEBUG(GpgFrontend::GetCoreLogger(), __VA_ARGS__)
#define GF_CORE_LOG_INFO(...) \
SPDLOG_LOGGER_INFO(GpgFrontend::GetCoreLogger(), __VA_ARGS__)
#define GF_CORE_LOG_WARN(...) \
SPDLOG_LOGGER_WARN(GpgFrontend::GetCoreLogger(), __VA_ARGS__)
#define GF_CORE_LOG_ERROR(...) \
SPDLOG_LOGGER_ERROR(GpgFrontend::GetCoreLogger(), __VA_ARGS__)
#define GF_LOG_TRACE(ID, ...) \
SPDLOG_LOGGER_TRACE(GpgFrontend::GetLogger(ID), __VA_ARGS__)
#define GF_LOG_DEBUG(ID, ...) \
SPDLOG_LOGGER_DEBUG(GpgFrontend::GetLogger(ID), __VA_ARGS__)
#define GF_LOG_INFO(ID, ...) \
SPDLOG_LOGGER_INFO(GpgFrontend::GetLogger(ID), __VA_ARGS__)
#define GF_LOG_WARN(ID, ...) \
SPDLOG_LOGGER_WARN(GpgFrontend::GetLogger(ID), __VA_ARGS__)
#define GF_LOG_ERROR(ID, ...) \
SPDLOG_LOGGER_ERROR(GpgFrontend::GetLogger(ID), __VA_ARGS__)

View File

@ -33,12 +33,10 @@
#include "core/function/gpg/GpgAdvancedOperator.h"
#include "core/module/ModuleInit.h"
#include "core/thread/TaskRunnerGetter.h"
#include "core/utils/LogUtils.h"
#include "ui/GpgFrontendUIInit.h"
// main
#include "GpgFrontendContext.h"
#include "main.h"
namespace GpgFrontend {
@ -54,22 +52,6 @@ int setenv(const char *name, const char *value, int overwrite) {
}
#endif
void InitLoggingSystem(const GFCxtSPtr &ctx) {
#ifdef DEBUG
RegisterSyncLogger("core", ctx->log_level);
RegisterSyncLogger("main", ctx->log_level);
RegisterSyncLogger("module", ctx->log_level);
RegisterSyncLogger("ui", ctx->log_level);
RegisterSyncLogger("test", ctx->log_level);
#else
RegisterAsyncLogger("core", ctx->log_level);
RegisterAsyncLogger("main", ctx->log_level);
RegisterAsyncLogger("module", ctx->log_level);
RegisterAsyncLogger("ui", ctx->log_level);
RegisterAsyncLogger("test", ctx->log_level);
#endif
}
void InitGlobalPathEnv() {
// read settings
bool use_custom_gnupg_install_path =
@ -87,13 +69,12 @@ void InitGlobalPathEnv() {
// add custom gnupg install path into env $PATH
if (use_custom_gnupg_install_path && !custom_gnupg_install_path.isEmpty()) {
QString path_value = getenv("PATH");
GF_MAIN_LOG_DEBUG("Current System PATH: {}", path_value);
setenv("PATH",
(QDir(custom_gnupg_install_path).absolutePath() + ":" + path_value)
.toUtf8(),
1);
QString modified_path_value = getenv("PATH");
GF_MAIN_LOG_DEBUG("Modified System PATH: {}", modified_path_value);
}
if (GlobalSettingStation::GetInstance()
@ -102,7 +83,6 @@ void InitGlobalPathEnv() {
.toBool()) {
qputenv("GPGME_DEBUG",
QString("9:%1").arg(QDir::currentPath() + "/gpgme.log").toUtf8());
GF_CORE_LOG_DEBUG("GPGME_DEBUG ENV: {}", qgetenv("GPGME_DEBUG"));
}
}
@ -112,22 +92,11 @@ void InitGlobalBasicEnv(const GFCxtWPtr &p_ctx, bool gui_mode) {
return;
}
// init default locale of application
InitLocale();
// initialize logging system
SetDefaultLogLevel(ctx->log_level);
InitLoggingSystem(ctx);
// change path to search for related
InitGlobalPathEnv();
// init application
ctx->InitApplication();
// should load module system first
Module::ModuleInitArgs module_init_args;
module_init_args.log_level = ctx->log_level;
Module::LoadGpgFrontendModules(module_init_args);
// then preload ui
@ -152,12 +121,12 @@ void InitLocale() {
// read from settings file
auto lang = settings.value("basic/lang").toString();
GF_UI_LOG_INFO("current system default locale: {}", QLocale().name());
GF_UI_LOG_INFO("locale settings from config: {}", lang);
qInfo() << "current system default locale: " << QLocale().name();
qInfo() << "locale settings from config: " << lang;
auto target_locale =
lang.trimmed().isEmpty() ? QLocale::system() : QLocale(lang);
GF_UI_LOG_INFO("application's target locale: {}", target_locale.name());
qInfo() << "application's target locale: " << target_locale.name();
QLocale::setDefault(target_locale);
}

View File

@ -32,13 +32,6 @@
namespace GpgFrontend {
/**
* @brief
*
* @param args
*/
void InitLoggingSystem(const GFCxtSPtr &);
/**
* @brief init global PATH env
*

View File

@ -30,14 +30,18 @@
* \mainpage GpgFrontend Develop Document Main Page
*/
#include <qcommandlineparser.h>
#include <qloggingcategory.h>
//
#include "GpgFrontendContext.h"
#include "core/utils/MemoryUtils.h"
//
#include "app.h"
#include "cmd.h"
#include "init.h"
//
#include "core/utils/MemoryUtils.h"
/**
*
* @param argc
@ -50,6 +54,22 @@ auto main(int argc, char* argv[]) -> int {
argc, argv);
ctx->InitApplication();
#ifdef RELEASE
QLoggingCategory::setFilterRules("*.debug=false\n*.info=false\n");
qSetMessagePattern(
"[%{time yyyyMMdd h:mm:ss.zzz}] [%{category}] "
"[%{if-debug}D%{endif}%{if-info}I%{endif}%{if-warning}W%{endif}%{if-"
"critical}C%{endif}%{if-fatal}F%{endif}] [%{threadid}] - "
"%{message}");
#else
QLoggingCategory::setFilterRules("*.debug=false");
qSetMessagePattern(
"[%{time yyyyMMdd h:mm:ss.zzz}] [%{category}] "
"[%{if-debug}D%{endif}%{if-info}I%{endif}%{if-warning}W%{endif}%{if-"
"critical}C%{endif}%{if-fatal}F%{endif}] [%{threadid}] %{file}:%{line} - "
"%{message}");
#endif
auto rtn = 0;
// initialize qt resources
@ -67,14 +87,12 @@ auto main(int argc, char* argv[]) -> int {
parser.process(*ctx->GetApp());
ctx->log_level = spdlog::level::info;
if (parser.isSet("v")) {
return GpgFrontend::PrintVersion();
}
if (parser.isSet("l")) {
ctx->log_level = GpgFrontend::ParseLogLevel(parser.value("l"));
GpgFrontend::ParseLogLevel(parser.value("l"));
}
if (parser.isSet("t")) {

View File

@ -1,76 +0,0 @@
# Copyright (C) 2021 Saturneric <eric@bktus.com>
#
# 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 <eric@bktus.com> 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})
set(_export_file "${CMAKE_CURRENT_SOURCE_DIR}/GFModuleExport.h")
generate_export_header(mod_gpg_info
BASE_NAME "GF_MODULE"
EXPORT_FILE_NAME "${_export_file}")
target_include_directories(mod_gpg_info PRIVATE
${CMAKE_SOURCE_DIR}/third_party/spdlog/include)
# set output directory
set_target_properties(mod_gpg_info PROPERTIES
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/mods
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/mods)
if (XCODE_BUILD)
set_target_properties(mod_gpg_info
PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}
XCODE_ATTRIBUTE_SKIP_INSTALL "Yes"
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${GPGFRONTEND_XOCDE_CODE_SIGN_IDENTITY}")
endif ()
if (LINUX AND LINUX_INSTALL_SOFTWARE)
install(TARGETS mod_gpg_info
LIBRARY DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}/mods/")
endif()
# 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()
# property
set_property(TARGET mod_gpg_info PROPERTY AUTOMOC ON)
# using std c++ 17
target_compile_features(mod_gpg_info PRIVATE cxx_std_17)

View File

@ -1,42 +0,0 @@
#ifndef GF_MODULE_EXPORT_H
#define GF_MODULE_EXPORT_H
#ifdef GF_MODULE_STATIC_DEFINE
# define GF_MODULE_EXPORT
# define GF_MODULE_NO_EXPORT
#else
# ifndef GF_MODULE_EXPORT
# ifdef mod_gpg_info_EXPORTS
/* We are building this library */
# define GF_MODULE_EXPORT __attribute__((visibility("default")))
# else
/* We are using this library */
# define GF_MODULE_EXPORT __attribute__((visibility("default")))
# endif
# endif
# ifndef GF_MODULE_NO_EXPORT
# define GF_MODULE_NO_EXPORT __attribute__((visibility("hidden")))
# endif
#endif
#ifndef GF_MODULE_DEPRECATED
# define GF_MODULE_DEPRECATED __attribute__ ((__deprecated__))
#endif
#ifndef GF_MODULE_DEPRECATED_EXPORT
# define GF_MODULE_DEPRECATED_EXPORT GF_MODULE_EXPORT GF_MODULE_DEPRECATED
#endif
#ifndef GF_MODULE_DEPRECATED_NO_EXPORT
# define GF_MODULE_DEPRECATED_NO_EXPORT GF_MODULE_NO_EXPORT GF_MODULE_DEPRECATED
#endif
#if 0 /* DEFINE_NO_DEPRECATED */
# ifndef GF_MODULE_NO_DEPRECATED
# define GF_MODULE_NO_DEPRECATED
# endif
#endif
#endif /* GF_MODULE_EXPORT_H */

View File

@ -1,526 +0,0 @@
/**
* Copyright (C) 2021 Saturneric <eric@bktus.com>
*
* 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 <eric@bktus.com> 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);
}

View File

@ -1,56 +0,0 @@
/**
* Copyright (C) 2021 Saturneric <eric@bktus.com>
*
* 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 <eric@bktus.com> 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;
};

View File

@ -1,79 +0,0 @@
/**
* Copyright (C) 2021 Saturneric <eric@bktus.com>
*
* 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 <eric@bktus.com> 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();
}
}

View File

@ -1,88 +0,0 @@
/**
* Copyright (C) 2021 Saturneric <eric@bktus.com>
*
* 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 <eric@bktus.com> 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;
};

View File

@ -1,68 +0,0 @@
/**
* Copyright (C) 2021 Saturneric <eric@bktus.com>
*
* 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 <eric@bktus.com> 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());
}
};

View File

@ -1,76 +0,0 @@
# Copyright (C) 2021 Saturneric <eric@bktus.com>
#
# 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 <eric@bktus.com> starting on May 12, 2021.
#
# SPDX-License-Identifier: GPL-3.0-or-later
# com.bktus.gpgfrontend.module.integrated.version_checking
aux_source_directory(. INTEGRATED_MODULE_SOURCE)
# define libgpgfrontend_module
add_library(mod_ver_check SHARED ${INTEGRATED_MODULE_SOURCE})
set(_export_file "${CMAKE_CURRENT_SOURCE_DIR}/GFModuleExport.h")
generate_export_header(mod_ver_check
BASE_NAME "GF_MODULE"
EXPORT_FILE_NAME "${_export_file}")
target_include_directories(mod_ver_check PRIVATE
${CMAKE_SOURCE_DIR}/third_party/spdlog/include)
# set output directory
set_target_properties(mod_ver_check PROPERTIES
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/mods
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/mods)
if (XCODE_BUILD)
set_target_properties(mod_ver_check
PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}
XCODE_ATTRIBUTE_SKIP_INSTALL "Yes"
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${GPGFRONTEND_XOCDE_CODE_SIGN_IDENTITY}")
endif ()
if (LINUX AND LINUX_INSTALL_SOFTWARE)
install(TARGETS mod_ver_check
LIBRARY DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}/mods/")
endif()
# link sdk
target_link_libraries(mod_ver_check PRIVATE
gpgfrontend_module_sdk)
if(GPGFRONTEND_QT5_BUILD)
# link Qt
target_link_libraries(mod_ver_check PUBLIC Qt5::Core Qt5::Network)
else()
# link Qt
target_link_libraries(mod_ver_check PUBLIC Qt6::Core Qt6::Network)
endif()
# property
set_property(TARGET mod_ver_check PROPERTY AUTOMOC ON)
# using std c++ 17
target_compile_features(mod_ver_check PRIVATE cxx_std_17)

View File

@ -1,42 +0,0 @@
#ifndef GF_MODULE_EXPORT_H
#define GF_MODULE_EXPORT_H
#ifdef GF_MODULE_STATIC_DEFINE
# define GF_MODULE_EXPORT
# define GF_MODULE_NO_EXPORT
#else
# ifndef GF_MODULE_EXPORT
# ifdef mod_ver_check_EXPORTS
/* We are building this library */
# define GF_MODULE_EXPORT __attribute__((visibility("default")))
# else
/* We are using this library */
# define GF_MODULE_EXPORT __attribute__((visibility("default")))
# endif
# endif
# ifndef GF_MODULE_NO_EXPORT
# define GF_MODULE_NO_EXPORT __attribute__((visibility("hidden")))
# endif
#endif
#ifndef GF_MODULE_DEPRECATED
# define GF_MODULE_DEPRECATED __attribute__ ((__deprecated__))
#endif
#ifndef GF_MODULE_DEPRECATED_EXPORT
# define GF_MODULE_DEPRECATED_EXPORT GF_MODULE_EXPORT GF_MODULE_DEPRECATED
#endif
#ifndef GF_MODULE_DEPRECATED_NO_EXPORT
# define GF_MODULE_DEPRECATED_NO_EXPORT GF_MODULE_NO_EXPORT GF_MODULE_DEPRECATED
#endif
#if 0 /* DEFINE_NO_DEPRECATED */
# ifndef GF_MODULE_NO_DEPRECATED
# define GF_MODULE_NO_DEPRECATED
# endif
#endif
#endif /* GF_MODULE_EXPORT_H */

View File

@ -1,68 +0,0 @@
/**
* Copyright (C) 2021 Saturneric <eric@bktus.com>
*
* 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 <eric@bktus.com> 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());
}
};

View File

@ -1,100 +0,0 @@
/**
* Copyright (C) 2021 Saturneric <eric@bktus.com>
*
* 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 <eric@bktus.com> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "SoftwareVersion.h"
#include <GFSDKBasic.h>
#include <GFSDKExtra.h>
#include <GFSDKLog.h>
#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());
}
};
auto SoftwareVersion::NeedUpgrade() const -> bool {
GFModuleLogDebug(
fmt::format(
"compair version current {} latest {}, result {}", current_version,
latest_version,
GFCompareSoftwareVersion(GFModuleStrDup(current_version.toUtf8()),
GFModuleStrDup(latest_version.toUtf8())))
.c_str());
GFModuleLogDebug(fmt::format("load done: {}, pre-release: {}, draft: {}",
loading_done,
latest_prerelease_version_from_remote,
latest_draft_from_remote)
.c_str());
return loading_done && !latest_prerelease_version_from_remote &&
!latest_draft_from_remote &&
GFCompareSoftwareVersion(GFModuleStrDup(current_version.toUtf8()),
GFModuleStrDup(latest_version.toUtf8())) < 0;
}
auto SoftwareVersion::VersionWithdrawn() const -> bool {
return loading_done && !current_version_publish_in_remote &&
current_version_is_a_prerelease && !current_version_is_drafted;
}
auto SoftwareVersion::CurrentVersionReleased() const -> bool {
return loading_done && current_version_publish_in_remote;
}

View File

@ -1,83 +0,0 @@
/**
* Copyright (C) 2021 Saturneric <eric@bktus.com>
*
* 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 <eric@bktus.com> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#pragma once
#include <QString>
/**
* @brief
*
*/
struct SoftwareVersion {
QString latest_version; ///<
QString current_version; ///<
bool latest_prerelease_version_from_remote = false; ///<
bool latest_draft_from_remote = false; ///<
bool current_version_is_a_prerelease = false; ///<
bool current_version_is_drafted = false; ///<
bool loading_done = false; ///<
bool current_version_publish_in_remote = false; ///<
QString publish_date; ///<
QString release_note; ///<
/**
* @brief
*
* @return true
* @return false
*/
[[nodiscard]] auto InfoValid() const -> bool { return loading_done; }
/**
* @brief
*
* @return true
* @return false
*/
[[nodiscard]] auto NeedUpgrade() const -> bool;
/**
* @brief
*
* @return true
* @return false
*/
[[nodiscard]] auto VersionWithdrawn() const -> bool;
/**
* @brief
*
* @return true
* @return false
*/
[[nodiscard]] auto CurrentVersionReleased() const -> bool;
private:
static auto version_compare(const QString& a, const QString& b) -> int;
};

View File

@ -1,171 +0,0 @@
/**
* Copyright (C) 2021 Saturneric <eric@bktus.com>
*
* 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 <eric@bktus.com> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "VersionCheckTask.h"
#include <GFSDKBasic.h>
#include <GFSDKExtra.h>
#include <GFSDKLog.h>
#include <QMetaType>
#include <QtNetwork>
VersionCheckTask::VersionCheckTask()
: network_manager_(new QNetworkAccessManager(this)),
current_version_(GFProjectVersion()) {
qRegisterMetaType<SoftwareVersion>("SoftwareVersion");
version_.current_version = current_version_;
}
auto VersionCheckTask::Run() -> int {
GFModuleLogDebug(
fmt::format("current project version: {}", current_version_).c_str());
QString latest_version_url =
"https://api.github.com/repos/saturneric/gpgfrontend/releases/latest";
QNetworkRequest latest_request(latest_version_url);
latest_request.setHeader(QNetworkRequest::UserAgentHeader,
GFHttpRequestUserAgent());
latest_reply_ = network_manager_->get(latest_request);
connect(latest_reply_, &QNetworkReply::finished, this,
&VersionCheckTask::slot_parse_latest_version_info);
return 0;
}
void VersionCheckTask::slot_parse_latest_version_info() {
if (latest_reply_ == nullptr) {
version_.latest_version = current_version_;
version_.loading_done = false;
} else if (latest_reply_->error() != QNetworkReply::NoError) {
GFModuleLogError(fmt::format("latest version request error: ",
latest_reply_->errorString())
.c_str());
version_.latest_version = current_version_;
} else {
latest_reply_bytes_ = latest_reply_->readAll();
auto latest_reply_json = QJsonDocument::fromJson(latest_reply_bytes_);
if (latest_reply_json.isObject()) {
QString latest_version = latest_reply_json["tag_name"].toString();
QRegularExpression re(R"(^[vV](\d+\.)?(\d+\.)?(\*|\d+))");
auto version_match = re.match(latest_version);
if (version_match.hasMatch()) {
latest_version = version_match.captured(0);
GFModuleLogInfo(fmt::format("latest released version from github: {}",
latest_version)
.c_str());
} else {
latest_version = current_version_;
GFModuleLogWarn(
fmt::format("latest version unknown, set to current version: {}",
current_version_)
.c_str());
}
bool prerelease = latest_reply_json["prerelease"].toBool();
bool draft = latest_reply_json["draft"].toBool();
auto publish_date = latest_reply_json["published_at"].toString();
auto release_note = latest_reply_json["body"].toString();
version_.latest_version = latest_version;
version_.latest_prerelease_version_from_remote = prerelease;
version_.latest_draft_from_remote = draft;
version_.publish_date = publish_date;
version_.release_note = release_note;
} else {
GFModuleLogWarn(fmt::format("cannot parse data got from github: {}",
latest_reply_bytes_)
.c_str());
}
}
if (latest_reply_ != nullptr) {
latest_reply_->deleteLater();
}
try {
QString current_version_url =
"https://api.github.com/repos/saturneric/gpgfrontend/releases/tags/" +
current_version_;
GFModuleLogDebug(
fmt::format("current version info query url: {}", current_version_url)
.c_str());
QNetworkRequest current_request(current_version_url);
current_request.setHeader(QNetworkRequest::UserAgentHeader,
GFHttpRequestUserAgent());
current_reply_ = network_manager_->get(current_request);
connect(current_reply_, &QNetworkReply::finished, this,
&VersionCheckTask::slot_parse_current_version_info);
} catch (...) {
GFModuleLogError("current version request create error");
}
}
void VersionCheckTask::slot_parse_current_version_info() {
if (current_reply_ == nullptr) {
// loading done
version_.loading_done = false;
} else if (current_reply_->error() != QNetworkReply::NoError) {
GFModuleLogError(fmt::format("current version request network error: {}",
current_reply_->errorString())
.c_str());
// loading done
version_.loading_done = true;
version_.current_version_publish_in_remote = false;
} else {
version_.current_version_publish_in_remote = true;
current_reply_bytes_ = current_reply_->readAll();
auto current_reply_json = QJsonDocument::fromJson(current_reply_bytes_);
if (current_reply_json.isObject()) {
bool current_prerelease = current_reply_json["prerelease"].toBool();
bool current_draft = current_reply_json["draft"].toBool();
version_.latest_prerelease_version_from_remote = current_prerelease;
version_.latest_draft_from_remote = current_draft;
// loading done
version_.loading_done = true;
} else {
GFModuleLogWarn(fmt::format("cannot parse data got from github: {}",
current_reply_bytes_)
.c_str());
}
}
GFModuleLogDebug(fmt::format("current version parse done: {}",
version_.current_version_publish_in_remote)
.c_str());
if (current_reply_ != nullptr) current_reply_->deleteLater();
emit SignalUpgradeVersion(version_);
}

View File

@ -1,89 +0,0 @@
/**
* Copyright (C) 2021 Saturneric <eric@bktus.com>
*
* 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 <eric@bktus.com> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#pragma once
#include <core/thread/Task.h>
#include "SoftwareVersion.h"
class QNetworkReply;
class QNetworkAccessManager;
/**
* @brief
*
*/
class VersionCheckTask : public QObject {
Q_OBJECT
public:
/**
* @brief Construct a new Version Check Thread object
*
*/
VersionCheckTask();
/**
* @brief
*
* @return int
*/
auto Run() -> int;
signals:
/**
* @brief
*
* @param version
*/
void SignalUpgradeVersion(SoftwareVersion version);
private slots:
/**
* @brief
*
*/
void slot_parse_latest_version_info();
/**
* @brief
*
*/
void slot_parse_current_version_info();
private:
QByteArray latest_reply_bytes_; ///<
QByteArray current_reply_bytes_; ///<
QNetworkReply* latest_reply_ = nullptr; ///< latest version info reply
QNetworkReply* current_reply_ = nullptr; ///< current version info reply
QNetworkAccessManager* network_manager_; ///<
QString current_version_;
SoftwareVersion version_;
};

View File

@ -1,164 +0,0 @@
/**
* Copyright (C) 2021 Saturneric <eric@bktus.com>
*
* 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 <eric@bktus.com> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "VersionCheckingModule.h"
#include <GFSDKBasic.h>
#include <GFSDKBuildInfo.h>
#include <GFSDKExtra.h>
#include <GFSDKLog.h>
#include <spdlog/spdlog.h>
#include <QMetaType>
#include <QtNetwork>
#include "SoftwareVersion.h"
#include "VersionCheckTask.h"
extern void VersionCheckDone(const SoftwareVersion& version);
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.version_checking");
}
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 = "VersionChecking";
p_meta->next = static_cast<GFModuleMetaData*>(
GFAllocateMemory(sizeof(GFModuleMetaData)));
p_meta = p_meta->next;
p_meta->key = "Description";
p_meta->value = "Try checking gpgfrontend version";
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 {
GFModuleLogInfo("version checking module registering");
return 0;
}
auto GFActiveModule() -> int {
GFModuleLogInfo("version checking module activating");
GFModuleListenEvent(GFGetModuleID(), GFModuleStrDup("APPLICATION_LOADED"));
GFModuleListenEvent(GFGetModuleID(),
GFModuleStrDup("CHECK_APPLICATION_VERSION"));
return 0;
}
auto GFExecuteModule(GFModuleEvent* event) -> int {
GFModuleLogInfo(
fmt::format("version checking module executing, event id: {}", event->id)
.c_str());
auto* task = new VersionCheckTask();
QObject::connect(
task, &VersionCheckTask::SignalUpgradeVersion, QThread::currentThread(),
[event](const SoftwareVersion& version) {
VersionCheckDone(version);
char** event_argv =
static_cast<char**>(GFAllocateMemory(sizeof(char**) * 1));
event_argv[0] = GFModuleStrDup("0");
GFModuleTriggerModuleEventCallback(event, GFGetModuleID(), 1,
event_argv);
});
QObject::connect(task, &VersionCheckTask::SignalUpgradeVersion, task,
&QObject::deleteLater);
task->Run();
return 0;
}
auto GFDeactiveModule() -> int { return 0; }
auto GFUnregisterModule() -> int { return 0; }
void VersionCheckDone(const SoftwareVersion& version) {
GFModuleLogDebug("filling software information info in rt...");
GFModuleUpsertRTValue(GFGetModuleID(),
GFModuleStrDup("version.current_version"),
GFModuleStrDup(version.current_version.toUtf8()));
GFModuleUpsertRTValue(GFGetModuleID(),
GFModuleStrDup("version.latest_version"),
GFModuleStrDup(version.latest_version.toUtf8()));
GFModuleUpsertRTValueBool(
GFGetModuleID(), GFModuleStrDup("version.current_version_is_drafted"),
version.current_version_is_drafted ? 1 : 0);
GFModuleUpsertRTValueBool(
GFGetModuleID(),
GFModuleStrDup("version.current_version_is_a_prerelease"),
version.current_version_is_a_prerelease ? 1 : 0);
GFModuleUpsertRTValueBool(
GFGetModuleID(),
GFModuleStrDup("version.current_version_publish_in_remote"),
version.current_version_publish_in_remote ? 1 : 0);
GFModuleUpsertRTValueBool(
GFGetModuleID(),
GFModuleStrDup("version.latest_prerelease_version_from_remote"),
version.latest_prerelease_version_from_remote ? 1 : 0);
GFModuleUpsertRTValueBool(GFGetModuleID(),
GFModuleStrDup("version.need_upgrade"),
version.NeedUpgrade() ? 1 : 0);
GFModuleUpsertRTValueBool(GFGetModuleID(),
GFModuleStrDup("version.current_version_released"),
version.CurrentVersionReleased() ? 1 : 0);
GFModuleUpsertRTValueBool(
GFGetModuleID(), GFModuleStrDup("version.current_a_withdrawn_version"),
version.VersionWithdrawn() ? 1 : 0);
GFModuleUpsertRTValueBool(GFGetModuleID(),
GFModuleStrDup("version.loading_done"),
version.loading_done ? 1 : 0);
GFModuleLogDebug("software information filled in rt");
}

View File

@ -1,47 +0,0 @@
/**
* Copyright (C) 2021 Saturneric <eric@bktus.com>
*
* 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 <eric@bktus.com> starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "GFSDKLog.h"
#include "core/utils/LogUtils.h"
#define MODULE_LOG_TRACE(...) GF_LOG_TRACE("module", __VA_ARGS__)
#define MODULE_LOG_DEBUG(...) GF_LOG_DEBUG("module", __VA_ARGS__)
#define MODULE_LOG_INFO(...) GF_LOG_INFO("module", __VA_ARGS__)
#define MODULE_LOG_WARN(...) GF_LOG_WARN("module", __VA_ARGS__)
#define MODULE_LOG_ERROR(...) GF_LOG_ERROR("module", __VA_ARGS__)
void GFModuleLogTrace(const char* l) { MODULE_LOG_TRACE(l); }
void GFModuleLogDebug(const char* l) { MODULE_LOG_DEBUG(l); }
void GFModuleLogInfo(const char* l) { MODULE_LOG_INFO(l); }
void GFModuleLogWarn(const char* l) { MODULE_LOG_WARN(l); }
void GFModuleLogError(const char* l) { MODULE_LOG_ERROR(l); }

Some files were not shown because too many files have changed in this diff Show More