Compare commits
41 Commits
952ed73f96
...
afe9e648b5
Author | SHA1 | Date | |
---|---|---|---|
afe9e648b5 | |||
ad558726a3 | |||
cf9d6538e6 | |||
aee8017b52 | |||
a03c18045f | |||
3ef497cbeb | |||
a3d7a46fc4 | |||
cb626d06de | |||
28546a83da | |||
cb15c1a06a | |||
0f0b10586f | |||
4e0db9ef4b | |||
9ee5e37b6e | |||
adc5d89717 | |||
c1d0552cb3 | |||
8bb3bf646e | |||
0a61ccd17a | |||
e8efa4d104 | |||
5be04d1602 | |||
1c44454085 | |||
ca3a64b4a5 | |||
3d84beaf22 | |||
37a62a8d0b | |||
d322e76533 | |||
09f6952d0a | |||
85eff35d7b | |||
cc9b3fcdd7 | |||
6728888b87 | |||
ed9f905440 | |||
71ca9724b8 | |||
d1d6859e2a | |||
bc52ba74b4 | |||
9f61a1f86c | |||
c0a2987afd | |||
30c3a52fc7 | |||
12fdf94b85 | |||
2c42d6cb72 | |||
19926663f1 | |||
d0333031c1 | |||
e7694f9a07 | |||
63dbe4a917 |
52
.github/workflows/release.yml
vendored
52
.github/workflows/release.yml
vendored
@ -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'
|
||||
|
||||
- name: Package App Image (Linux)
|
||||
if: matrix.os == 'macos-13' || matrix.os == 'macos-12' || matrix.os == 'macos-14'
|
||||
|
||||
- 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
6
.gitmodules
vendored
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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")
|
@ -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
1
modules
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit f813e3b71ee9563223f3d628374788c1d18b8504
|
@ -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"/>
|
||||
|
BIN
resource/lfs/icons/filter.png
Normal file
BIN
resource/lfs/icons/filter.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
@ -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")
|
||||
@ -329,11 +313,11 @@ if (BUILD_APPLICATION)
|
||||
add_executable(${AppName} WIN32 ${BASE_SOURCE} ${RESOURCE_FILES})
|
||||
# include qt dependencies
|
||||
if(NOT Qt6_DIR)
|
||||
add_custom_command(TARGET ${AppName} POST_BUILD
|
||||
COMMAND windeployqt --force ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${AppName}.exe)
|
||||
add_custom_command(TARGET ${AppName} POST_BUILD
|
||||
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)
|
||||
@ -499,31 +487,86 @@ endif()
|
||||
|
||||
# if building linux package
|
||||
if (LINUX AND LINUX_INSTALL_SOFTWARE)
|
||||
include(GNUInstallDirs)
|
||||
set(GPGFRONTEND_INSTALL_LIBRARIES
|
||||
mimalloc
|
||||
spdlog
|
||||
gpgfrontend_core
|
||||
gpgfrontend_ui
|
||||
gpgfrontend_test
|
||||
gpgfrontend_pinentry
|
||||
gpgfrontend_module_sdk)
|
||||
include(GNUInstallDirs)
|
||||
|
||||
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})
|
||||
if(STABLE_BUILD_ONLY_APPLICATION)
|
||||
set(GPGFRONTEND_INSTALL_LIBRARIES "")
|
||||
else()
|
||||
set(GPGFRONTEND_INSTALL_LIBRARIES
|
||||
mimalloc
|
||||
gpgfrontend_core
|
||||
gpgfrontend_ui
|
||||
gpgfrontend_test
|
||||
gpgfrontend_module_sdk)
|
||||
endif()
|
||||
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/TRANSLATORS
|
||||
DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/${AppName}/)
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/resource/appstream/com.bktus.gpgfrontend.appdata.xml
|
||||
DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/metainfo/)
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/resource/appstream/com.bktus.gpgfrontend.desktop
|
||||
DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/applications/)
|
||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/resource/lfs/pixmaps/
|
||||
DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/pixmaps/)
|
||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/resource/lfs/hicolor/
|
||||
DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/icons/hicolor/)
|
||||
message(STATUS "GpgFrontend Install Libraries: ${GPGFRONTEND_INSTALL_LIBRARIES}")
|
||||
install(TARGETS ${AppName} ${GPGFRONTEND_INSTALL_LIBRARIES}
|
||||
EXPORT GpgFrontendTargets
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/TRANSLATORS
|
||||
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${AppName}/)
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/resource/appstream/com.bktus.gpgfrontend.appdata.xml
|
||||
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/metainfo/)
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/resource/appstream/com.bktus.gpgfrontend.desktop
|
||||
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications/)
|
||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/resource/lfs/pixmaps/
|
||||
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pixmaps/)
|
||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/resource/lfs/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 ()
|
@ -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;
|
||||
|
21
src/app.cpp
21
src/app.cpp
@ -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());
|
||||
};
|
||||
|
||||
|
46
src/cmd.cpp
46
src/cmd.cpp
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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,22 +37,30 @@ 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)
|
||||
target_link_libraries(gpgfrontend_core PUBLIC mimalloc)
|
||||
if(MINGW)
|
||||
set_target_properties(mimalloc
|
||||
PROPERTIES
|
||||
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}"
|
||||
)
|
||||
endif()
|
||||
# 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
|
||||
PROPERTIES
|
||||
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}"
|
||||
)
|
||||
endif()
|
||||
|
||||
# qt-aes
|
||||
@ -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")
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -27,3 +27,5 @@
|
||||
*/
|
||||
|
||||
#include "core/GpgFrontendCore.h"
|
||||
|
||||
Q_LOGGING_CATEGORY(core, "core")
|
@ -30,3 +30,11 @@
|
||||
|
||||
// Qt
|
||||
#include <QtCore>
|
||||
|
||||
// declare area of core
|
||||
#ifdef GF_CORE
|
||||
|
||||
// declare logging category
|
||||
Q_DECLARE_LOGGING_CATEGORY(core)
|
||||
|
||||
#endif
|
@ -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,8 +113,8 @@ void ArchiveFileOperator::NewArchive2DataExchanger(
|
||||
#endif
|
||||
|
||||
if (r != ARCHIVE_OK) {
|
||||
GF_CORE_LOG_ERROR("archive_read_disk_open() failed: {}, abort...",
|
||||
archive_error_string(disk));
|
||||
qCWarning(core, "archive_read_disk_open() failed: %s, abort...",
|
||||
archive_error_string(disk));
|
||||
archive_read_free(disk);
|
||||
archive_write_free(archive);
|
||||
return -1;
|
||||
@ -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,17 +165,17 @@ 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: {}, "
|
||||
"abort ...",
|
||||
r, archive_error_string(archive));
|
||||
qCWarning(core,
|
||||
"archive_write_header() failed, ret: %d, explain: %s, "
|
||||
"abort ...",
|
||||
r, archive_error_string(archive));
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
@ -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,17 +209,17 @@ 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,
|
||||
archive_error_string(archive));
|
||||
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,
|
||||
archive_error_string(archive));
|
||||
qCWarning(core,
|
||||
"archive_read_support_format_all(), ret: %d, reason: %s", r,
|
||||
archive_error_string(archive));
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -230,16 +230,16 @@ void ArchiveFileOperator::ExtractArchiveFromDataExchanger(
|
||||
nullptr);
|
||||
|
||||
if (r != ARCHIVE_OK) {
|
||||
GF_CORE_LOG_ERROR("archive_read_open(), ret: {}, reason: {}", r,
|
||||
archive_error_string(archive));
|
||||
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,
|
||||
archive_error_string(archive));
|
||||
qCWarning(core,
|
||||
"archive_write_disk_set_options(), ret: %d, reason: %s", r,
|
||||
archive_error_string(archive));
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -248,8 +248,8 @@ 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: {}",
|
||||
r, archive_error_string(archive));
|
||||
qCWarning(core, "archive_read_next_header(), ret: %d, reason: %s",
|
||||
r, archive_error_string(archive));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -267,8 +267,8 @@ void ArchiveFileOperator::ExtractArchiveFromDataExchanger(
|
||||
|
||||
r = archive_write_header(ext, entry);
|
||||
if (r != ARCHIVE_OK) {
|
||||
GF_CORE_LOG_ERROR("archive_write_header(), ret: {}, reason: {}", r,
|
||||
archive_error_string(archive));
|
||||
qCWarning(core, "archive_write_header(), ret: %d, reason: %s", r,
|
||||
archive_error_string(archive));
|
||||
} else {
|
||||
r = CopyData(archive, ext);
|
||||
}
|
||||
@ -276,13 +276,13 @@ void ArchiveFileOperator::ExtractArchiveFromDataExchanger(
|
||||
|
||||
r = archive_read_free(archive);
|
||||
if (r != ARCHIVE_OK) {
|
||||
GF_CORE_LOG_ERROR("archive_read_free(), ret: {}, reason: {}", r,
|
||||
archive_error_string(archive));
|
||||
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,
|
||||
archive_error_string(archive));
|
||||
qCWarning(core, "archive_read_free(), ret: %d, reason: %s", r,
|
||||
archive_error_string(archive));
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -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
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -58,12 +58,6 @@ class GPGFRONTEND_CORE_EXPORT CoreSignalStation : public QObject {
|
||||
*/
|
||||
void SignalNeedUserInputPassphrase(QSharedPointer<GpgPassphraseContext>);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
*/
|
||||
void SignalUserInputPassphraseCallback(QSharedPointer<GpgPassphraseContext>);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
|
@ -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 {};
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -28,6 +28,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <qsettings.h>
|
||||
|
||||
#include "core/function/basic/GpgFunctionObject.h"
|
||||
|
||||
namespace GpgFrontend {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
@ -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
|
@ -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
|
@ -29,7 +29,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "core/GpgFrontendCoreExport.h"
|
||||
#include "core/utils/LogUtils.h"
|
||||
|
||||
namespace GpgFrontend {
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
@ -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(
|
||||
"register channel object to instances map, "
|
||||
"channel: {}, address: {}",
|
||||
channel, static_cast<void*>(p_obj.get()));
|
||||
qCDebug(core,
|
||||
"register channel object to instances map, "
|
||||
"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;
|
||||
}
|
||||
|
||||
|
@ -49,9 +49,9 @@ 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: {}",
|
||||
static_cast<void*>(global_instance.get()));
|
||||
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();
|
||||
}
|
||||
|
@ -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,59 +76,53 @@ 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: {}",
|
||||
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(
|
||||
"restart all component after core initilized failed");
|
||||
qCWarning(core,
|
||||
"restart all component after core initilized failed");
|
||||
Module::UpsertRTValue(
|
||||
"core", "gpg_advanced_operator.restart_gpg_components", false);
|
||||
return;
|
||||
@ -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());
|
||||
}});
|
||||
}
|
||||
|
@ -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> {
|
||||
|
@ -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: {}",
|
||||
data_object->GetObjectSize());
|
||||
[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: {}",
|
||||
data_object->GetObjectSize());
|
||||
[](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,
|
||||
[=](QProcess::ProcessError error) {
|
||||
GF_CORE_LOG_ERROR(
|
||||
"caught error while executing command: {} {}, error: {}", cmd,
|
||||
joined_argument, error);
|
||||
});
|
||||
QObject::connect(cmd_process, &QProcess::errorOccurred,
|
||||
[=](QProcess::ProcessError 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();
|
||||
|
@ -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
|
||||
QString passphrase = "abcdefg";
|
||||
auto pass_bytes = passphrase.toLatin1();
|
||||
auto pass_size = pass_bytes.size();
|
||||
const auto *p_pass_bytes = pass_bytes.constData();
|
||||
|
||||
auto passpahrase_size = pass.size();
|
||||
size_t off = 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);
|
||||
ssize_t res = 0;
|
||||
if (pass_size > 0) {
|
||||
ssize_t off = 0;
|
||||
ssize_t ret = 0;
|
||||
do {
|
||||
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,23 +234,22 @@ 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: {}",
|
||||
args_.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);
|
||||
|
||||
// set option auto import missing key
|
||||
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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,
|
||||
const QString& in_path, bool ascii,
|
||||
const QString& out_path)
|
||||
-> std::tuple<GpgError, DataObjectPtr> {
|
||||
auto GpgFileOpera::EncryptSignFileSync(
|
||||
const KeyArgsList& keys, const KeyArgsList& signer_keys,
|
||||
const QString& in_path, bool ascii,
|
||||
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(
|
||||
|
@ -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
|
||||
|
@ -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_;
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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,81 +94,83 @@ 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);
|
||||
auto tokens = args.split(' ');
|
||||
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;
|
||||
|
||||
switch (state) {
|
||||
case AS_START:
|
||||
if (status == "GET_LINE" && args == "keyedit.prompt") {
|
||||
return AS_COMMAND;
|
||||
}
|
||||
return AS_ERROR;
|
||||
case AS_COMMAND:
|
||||
if (status == "GET_LINE" && args == "edit_ownertrust.value") {
|
||||
return AS_VALUE;
|
||||
}
|
||||
return AS_ERROR;
|
||||
case AS_VALUE:
|
||||
if (status == "GET_LINE" && args == "keyedit.prompt") {
|
||||
return AS_QUIT;
|
||||
} else if (status == "GET_BOOL" &&
|
||||
args == "edit_ownertrust.set_ultimate.okay") {
|
||||
return AS_REALLY_ULTIMATE;
|
||||
}
|
||||
return AS_ERROR;
|
||||
case AS_REALLY_ULTIMATE:
|
||||
if (status == "GET_LINE" && args == "keyedit.prompt") {
|
||||
return AS_QUIT;
|
||||
}
|
||||
return AS_ERROR;
|
||||
case AS_QUIT:
|
||||
if (status == "GET_LINE" && args == "keyedit.save.okay") {
|
||||
return AS_SAVE;
|
||||
}
|
||||
return AS_ERROR;
|
||||
case AS_ERROR:
|
||||
if (status == "GET_LINE" && args == "keyedit.prompt") {
|
||||
return AS_QUIT;
|
||||
}
|
||||
return AS_ERROR;
|
||||
default:
|
||||
return AS_ERROR;
|
||||
};
|
||||
};
|
||||
auto tokens = args.split(' ');
|
||||
|
||||
AutomatonActionHandler action_handler =
|
||||
[trust_level](AutomatonHandelStruct& handler, AutomatonState state) {
|
||||
GF_CORE_LOG_DEBUG("action_handler state: {}", state);
|
||||
switch (state) {
|
||||
case AS_COMMAND:
|
||||
return QString("trust");
|
||||
case AS_VALUE:
|
||||
handler.SetSuccess(true);
|
||||
return QString::number(trust_level);
|
||||
case AS_REALLY_ULTIMATE:
|
||||
handler.SetSuccess(true);
|
||||
return QString("Y");
|
||||
case AS_QUIT:
|
||||
return QString("quit");
|
||||
case AS_SAVE:
|
||||
handler.SetSuccess(true);
|
||||
return QString("Y");
|
||||
case AS_START:
|
||||
if (status == "GET_LINE" && args == "keyedit.prompt") {
|
||||
return AS_COMMAND;
|
||||
}
|
||||
return AS_ERROR;
|
||||
case AS_COMMAND:
|
||||
if (status == "GET_LINE" && args == "edit_ownertrust.value") {
|
||||
return AS_VALUE;
|
||||
}
|
||||
return AS_ERROR;
|
||||
case AS_VALUE:
|
||||
if (status == "GET_LINE" && args == "keyedit.prompt") {
|
||||
return AS_QUIT;
|
||||
} else if (status == "GET_BOOL" &&
|
||||
args == "edit_ownertrust.set_ultimate.okay") {
|
||||
return AS_REALLY_ULTIMATE;
|
||||
}
|
||||
return AS_ERROR;
|
||||
case AS_REALLY_ULTIMATE:
|
||||
if (status == "GET_LINE" && args == "keyedit.prompt") {
|
||||
return AS_QUIT;
|
||||
}
|
||||
return AS_ERROR;
|
||||
case AS_QUIT:
|
||||
if (status == "GET_LINE" && args == "keyedit.save.okay") {
|
||||
return AS_SAVE;
|
||||
}
|
||||
return AS_ERROR;
|
||||
case AS_ERROR:
|
||||
return QString("");
|
||||
if (status == "GET_LINE" && args == "keyedit.prompt") {
|
||||
return AS_QUIT;
|
||||
}
|
||||
return AS_ERROR;
|
||||
default:
|
||||
return QString("");
|
||||
}
|
||||
return QString("");
|
||||
return AS_ERROR;
|
||||
};
|
||||
};
|
||||
|
||||
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");
|
||||
case AS_VALUE:
|
||||
handler.SetSuccess(true);
|
||||
return QString::number(trust_level);
|
||||
case AS_REALLY_ULTIMATE:
|
||||
handler.SetSuccess(true);
|
||||
return QString("Y");
|
||||
case AS_QUIT:
|
||||
return QString("quit");
|
||||
case AS_SAVE:
|
||||
handler.SetSuccess(true);
|
||||
return QString("Y");
|
||||
case AS_START:
|
||||
case AS_ERROR:
|
||||
return QString("");
|
||||
default:
|
||||
return QString("");
|
||||
}
|
||||
return QString("");
|
||||
};
|
||||
|
||||
auto key_fpr = key.GetFingerprint();
|
||||
AutomatonHandelStruct handel_struct(key_fpr);
|
||||
handel_struct.SetHandler(next_state_handler, action_handler);
|
||||
@ -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());
|
||||
|
@ -105,7 +105,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyManager
|
||||
AS_ERROR,
|
||||
AS_QUIT,
|
||||
};
|
||||
|
||||
|
||||
struct AutomatonHandelStruct;
|
||||
|
||||
using AutomatonActionHandler =
|
||||
|
@ -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,14 +113,12 @@ 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: {}",
|
||||
exit_code, p_out.size());
|
||||
qCDebug(core,
|
||||
"gnupg gen revoke exit_code: %d, process stdout size: %lld",
|
||||
exit_code, p_out.size());
|
||||
}
|
||||
},
|
||||
nullptr,
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -55,9 +55,9 @@ auto GpgDecryptResult::Recipients() -> std::vector<GpgRecipient> {
|
||||
try {
|
||||
result.emplace_back(reci);
|
||||
} catch (...) {
|
||||
GF_CORE_LOG_ERROR(
|
||||
"caught exception when processing invalid_recipients, "
|
||||
"maybe nullptr of fpr");
|
||||
qCWarning(core,
|
||||
"caught exception when processing invalid_recipients, "
|
||||
"maybe nullptr of fpr");
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@ -55,9 +55,9 @@ auto GpgEncryptResult::InvalidRecipients()
|
||||
try {
|
||||
result.emplace_back(QString{invalid_key->fpr}, invalid_key->reason);
|
||||
} catch (...) {
|
||||
GF_CORE_LOG_ERROR(
|
||||
"caught exception when processing invalid_recipients, "
|
||||
"maybe nullptr of fpr");
|
||||
qCWarning(core,
|
||||
"caught exception when processing invalid_recipients, "
|
||||
"maybe nullptr of fpr");
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@ -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"},
|
||||
|
172
src/core/model/GpgKeyTableModel.cpp
Normal file
172
src/core/model/GpgKeyTableModel.cpp
Normal 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
|
212
src/core/model/GpgKeyTableModel.h
Normal file
212
src/core/model/GpgKeyTableModel.h
Normal 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
|
175
src/core/model/GpgKeyTableProxyModel.cpp
Normal file
175
src/core/model/GpgKeyTableProxyModel.cpp
Normal 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
|
94
src/core/model/GpgKeyTableProxyModel.h
Normal file
94
src/core/model/GpgKeyTableProxyModel.h
Normal 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
|
@ -55,9 +55,9 @@ auto GpgSignResult::InvalidSigners()
|
||||
try {
|
||||
result.emplace_back(QString{invalid_key->fpr}, invalid_key->reason);
|
||||
} catch (...) {
|
||||
GF_CORE_LOG_ERROR(
|
||||
"caught exception when processing invalid_signers, "
|
||||
"maybe nullptr of fpr");
|
||||
qCWarning(core,
|
||||
"caught exception when processing invalid_signers, "
|
||||
"maybe nullptr of fpr");
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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(); }
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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**>(®ister_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(); }
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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)) {
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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; }
|
||||
|
@ -32,6 +32,13 @@
|
||||
|
||||
namespace GpgFrontend {
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @return QString
|
||||
*/
|
||||
auto GPGFRONTEND_CORE_EXPORT GetProjectName() -> QString;
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -48,21 +48,21 @@ auto GPGFRONTEND_CORE_EXPORT BeautifyFingerprint(QString fingerprint)
|
||||
* @param b
|
||||
* @return int
|
||||
*/
|
||||
auto GPGFRONTEND_CORE_EXPORT GFCompareSoftwareVersion(const QString& a,
|
||||
const QString& b) -> int;
|
||||
auto GPGFRONTEND_CORE_EXPORT GFCompareSoftwareVersion(const QString &a,
|
||||
const QString &b) -> int;
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @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
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -28,8 +28,6 @@
|
||||
|
||||
#include "LocalizedUtils.h"
|
||||
|
||||
#include "core/utils/LogUtils.h"
|
||||
|
||||
namespace GpgFrontend {
|
||||
|
||||
auto GetLocalizedDateByTimestamp(time_t timestamp) -> QString {
|
||||
|
@ -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
|
@ -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__)
|
39
src/init.cpp
39
src/init.cpp
@ -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);
|
||||
}
|
||||
|
||||
|
@ -32,13 +32,6 @@
|
||||
|
||||
namespace GpgFrontend {
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param args
|
||||
*/
|
||||
void InitLoggingSystem(const GFCxtSPtr &);
|
||||
|
||||
/**
|
||||
* @brief init global PATH env
|
||||
*
|
||||
|
30
src/main.cpp
30
src/main.cpp
@ -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")) {
|
||||
|
@ -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)
|
@ -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 */
|
@ -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);
|
||||
}
|
@ -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;
|
||||
};
|
@ -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();
|
||||
}
|
||||
}
|
@ -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;
|
||||
};
|
@ -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());
|
||||
}
|
||||
};
|
@ -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)
|
@ -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 */
|
@ -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());
|
||||
}
|
||||
};
|
@ -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;
|
||||
}
|
@ -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;
|
||||
};
|
@ -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_);
|
||||
}
|
@ -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_;
|
||||
};
|
@ -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");
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user