Compare commits
11 Commits
v1.1.0-rel
...
v1.1.1-rc-
| Author | SHA1 | Date | |
|---|---|---|---|
| 8f4a9f5d55 | |||
| 2ee4578c06 | |||
| c22df23cfa | |||
| 5926c11e8a | |||
| 5fe4700446 | |||
| b190099228 | |||
| 166afcb3b6 | |||
| 586f4cb036 | |||
| 55ad50d6f4 | |||
| 30d1984da7 | |||
| 8e1b5072fd |
@@ -51,6 +51,10 @@ if(PROJECT_IS_ARM64)
|
|||||||
add_definitions(-DPROJECT_IS_ARM64)
|
add_definitions(-DPROJECT_IS_ARM64)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(PROJECT_IS_DARWIN)
|
||||||
|
add_definitions(-DPROJECT_IS_DARWIN)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(PROJECT_IS_MINGW)
|
if(PROJECT_IS_MINGW)
|
||||||
option(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES "Enable path sizes of 32767 characters on Windows" OFF)
|
option(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES "Enable path sizes of 32767 characters on Windows" OFF)
|
||||||
if(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
|
if(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
|
||||||
@@ -115,6 +119,16 @@ if(PROJECT_BUILD)
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/version.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/version.cpp
|
||||||
@ONLY
|
@ONLY
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${PROJECT_NAME}.iss.in")
|
||||||
|
configure_file(
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${PROJECT_NAME}.iss.in
|
||||||
|
${PROJECT_DIST_DIR}/../${PROJECT_NAME}.iss
|
||||||
|
@ONLY
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
find_package(ICU REQUIRED COMPONENTS data i18n io uc)
|
||||||
else()
|
else()
|
||||||
message(STATUS "-=[CMake Settings]=-")
|
message(STATUS "-=[CMake Settings]=-")
|
||||||
message(STATUS " C standard: ${CMAKE_C_STANDARD}")
|
message(STATUS " C standard: ${CMAKE_C_STANDARD}")
|
||||||
@@ -164,9 +178,12 @@ endif()
|
|||||||
-DPROJECT_INTERFACE=1
|
-DPROJECT_INTERFACE=1
|
||||||
-DPROJECT_IS_ALPINE=${PROJECT_IS_ALPINE}
|
-DPROJECT_IS_ALPINE=${PROJECT_IS_ALPINE}
|
||||||
-DPROJECT_IS_ARM64=${PROJECT_IS_ARM64}
|
-DPROJECT_IS_ARM64=${PROJECT_IS_ARM64}
|
||||||
|
-DPROJECT_IS_DARWIN=${PROJECT_IS_DARWIN}
|
||||||
-DPROJECT_IS_MINGW=${PROJECT_IS_MINGW}
|
-DPROJECT_IS_MINGW=${PROJECT_IS_MINGW}
|
||||||
-DPROJECT_IS_MINGW_UNIX=${PROJECT_IS_MINGW_UNIX}
|
-DPROJECT_IS_MINGW_UNIX=${PROJECT_IS_MINGW_UNIX}
|
||||||
-DPROJECT_MAJOR_VERSION=${PROJECT_MAJOR_VERSION}
|
-DPROJECT_MAJOR_VERSION=${PROJECT_MAJOR_VERSION}
|
||||||
|
-DPROJECT_MACOS_BUNDLE_ID=${PROJECT_MACOS_BUNDLE_ID}
|
||||||
|
-DPROJECT_MACOS_ICNS_NAME=${PROJECT_MACOS_ICNS_NAME}
|
||||||
-DPROJECT_MINOR_VERSION=${PROJECT_MINOR_VERSION}
|
-DPROJECT_MINOR_VERSION=${PROJECT_MINOR_VERSION}
|
||||||
-DPROJECT_NAME=${PROJECT_NAME}
|
-DPROJECT_NAME=${PROJECT_NAME}
|
||||||
-DPROJECT_RELEASE_ITER=${PROJECT_RELEASE_ITER}
|
-DPROJECT_RELEASE_ITER=${PROJECT_RELEASE_ITER}
|
||||||
|
|||||||
@@ -35,13 +35,9 @@ list(APPEND PROJECT_CXXFLAGS_LIST
|
|||||||
-Wcast-align
|
-Wcast-align
|
||||||
-Wconversion
|
-Wconversion
|
||||||
-Wdouble-promotion
|
-Wdouble-promotion
|
||||||
-Wduplicated-branches
|
|
||||||
-Wduplicated-cond
|
|
||||||
-Wextra
|
-Wextra
|
||||||
-Wformat=2
|
-Wformat=2
|
||||||
-Wlogical-op
|
|
||||||
-Wmisleading-indentation
|
-Wmisleading-indentation
|
||||||
-Wno-useless-cast
|
|
||||||
-Wnon-virtual-dtor
|
-Wnon-virtual-dtor
|
||||||
-Wnull-dereference
|
-Wnull-dereference
|
||||||
-Wold-style-cast
|
-Wold-style-cast
|
||||||
@@ -52,6 +48,15 @@ list(APPEND PROJECT_CXXFLAGS_LIST
|
|||||||
-Wunused
|
-Wunused
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (NOT PROJECT_IS_DARWIN)
|
||||||
|
list(APPEND PROJECT_CXXFLAGS_LIST
|
||||||
|
-Wduplicated-branches
|
||||||
|
-Wduplicated-cond
|
||||||
|
-Wlogical-op
|
||||||
|
-Wno-useless-cast
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
list(APPEND PROJECT_CFLAGS_LIST
|
list(APPEND PROJECT_CFLAGS_LIST
|
||||||
${PROJECT_COMMON_FLAG_LIST}
|
${PROJECT_COMMON_FLAG_LIST}
|
||||||
-std=c${CMAKE_C_STANDARD}
|
-std=c${CMAKE_C_STANDARD}
|
||||||
@@ -62,7 +67,7 @@ list(APPEND PROJECT_CXXFLAGS_LIST
|
|||||||
-std=gnu++${CMAKE_CXX_STANDARD}
|
-std=gnu++${CMAKE_CXX_STANDARD}
|
||||||
)
|
)
|
||||||
|
|
||||||
if(PROJECT_STATIC_LINK)
|
if(NOT PROJECT_IS_DARWIN AND PROJECT_STATIC_LINK)
|
||||||
list(APPEND PROJECT_CMAKE_EXE_LINKER_FLAGS
|
list(APPEND PROJECT_CMAKE_EXE_LINKER_FLAGS
|
||||||
-static-libgcc
|
-static-libgcc
|
||||||
-static-libstdc++
|
-static-libstdc++
|
||||||
@@ -89,7 +94,11 @@ set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${PROJECT_RELEASE_FLAG_L
|
|||||||
|
|
||||||
set(CMAKE_EXE_LINKER_FLAGS "${PROJECT_CMAKE_EXE_LINKER_FLAGS}")
|
set(CMAKE_EXE_LINKER_FLAGS "${PROJECT_CMAKE_EXE_LINKER_FLAGS}")
|
||||||
|
|
||||||
set(EXTERNAL_CMAKE_CXX_FLAGS "-include cstdint -include utility -fext-numeric-literals ${PROJECT_COMMON_FLAG_LIST}")
|
set(EXTERNAL_CMAKE_CXX_FLAGS "-include cstdint -include utility ${PROJECT_COMMON_FLAG_LIST}")
|
||||||
|
if (NOT PROJECT_IS_DARWIN)
|
||||||
|
set(EXTERNAL_CMAKE_CXX_FLAGS "-fext-numeric-literals ${EXTERNAL_CMAKE_CXX_FLAGS}")
|
||||||
|
endif()
|
||||||
|
|
||||||
list(APPEND PROJECT_EXTERNAL_CMAKE_FLAGS
|
list(APPEND PROJECT_EXTERNAL_CMAKE_FLAGS
|
||||||
-DCMAKE_BUILD_TYPE=${PROJECT_CMAKE_BUILD_TYPE}
|
-DCMAKE_BUILD_TYPE=${PROJECT_CMAKE_BUILD_TYPE}
|
||||||
-DCMAKE_COLOR_MAKEFILE=${CMAKE_COLOR_MAKEFILE}
|
-DCMAKE_COLOR_MAKEFILE=${CMAKE_COLOR_MAKEFILE}
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
if (PROJECT_MACOS_ICNS_NAME)
|
||||||
|
set(PROJECT_MACOS_ICNS_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/assets/${PROJECT_MACOS_ICNS_NAME}")
|
||||||
|
endif()
|
||||||
|
|
||||||
function(set_common_target_options name)
|
function(set_common_target_options name)
|
||||||
target_compile_definitions(${name} PUBLIC
|
target_compile_definitions(${name} PUBLIC
|
||||||
${PROJECT_DEFINITIONS}
|
${PROJECT_DEFINITIONS}
|
||||||
@@ -12,6 +16,17 @@ function(set_common_target_options name)
|
|||||||
${PROJECT_EXTERNAL_BUILD_ROOT}/lib
|
${PROJECT_EXTERNAL_BUILD_ROOT}/lib
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (PROJECT_STATIC_LINK)
|
||||||
|
target_compile_definitions(${name} PRIVATE U_STATIC_IMPLEMENTATION)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_link_libraries(${name} PRIVATE
|
||||||
|
ICU::io
|
||||||
|
ICU::i18n
|
||||||
|
ICU::uc
|
||||||
|
ICU::data
|
||||||
|
)
|
||||||
|
|
||||||
target_include_directories(${name} AFTER PUBLIC
|
target_include_directories(${name} AFTER PUBLIC
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/include
|
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/include
|
||||||
${name}_INCLUDES
|
${name}_INCLUDES
|
||||||
@@ -31,11 +46,31 @@ function(add_project_executable2 name dependencies libraries headers sources is_
|
|||||||
list(APPEND sources ${PROJECT_WINDOWS_VERSION_RC})
|
list(APPEND sources ${PROJECT_WINDOWS_VERSION_RC})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (PROJECT_IS_DARWIN AND PROJECT_MACOS_ICNS_SOURCE AND "${name}" STREQUAL "${PROJECT_NAME}")
|
||||||
|
set_source_files_properties(${PROJECT_MACOS_ICNS_SOURCE} PROPERTIES
|
||||||
|
MACOSX_PACKAGE_LOCATION "Resources"
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable(${name}
|
||||||
|
MACOSX_BUNDLE
|
||||||
|
${headers}
|
||||||
|
${sources}
|
||||||
|
${PROJECT_MACOS_ICNS_SOURCE}
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/main.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
set_target_properties(${name} PROPERTIES
|
||||||
|
MACOSX_BUNDLE TRUE
|
||||||
|
MACOSX_BUNDLE_ICON_FILE "${PROJECT_MACOS_ICNS_NAME}"
|
||||||
|
RESOURCE "${PROJECT_MACOS_ICNS_SOURCE}"
|
||||||
|
)
|
||||||
|
else()
|
||||||
add_executable(${name}
|
add_executable(${name}
|
||||||
${headers}
|
${headers}
|
||||||
${sources}
|
${sources}
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/main.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/main.cpp
|
||||||
)
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
foreach(dependency ${dependencies})
|
foreach(dependency ${dependencies})
|
||||||
set_common_target_options(${dependency})
|
set_common_target_options(${dependency})
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
set(BINUTILS_HASH ce2017e059d63e67ddb9240e9d4ec49c2893605035cd60e92ad53177f4377237)
|
set(BINUTILS_HASH ce2017e059d63e67ddb9240e9d4ec49c2893605035cd60e92ad53177f4377237)
|
||||||
set(CPP_HTTPLIB_HASH 18064587e0cc6a0d5d56d619f4cbbcaba47aa5d84d86013abbd45d95c6653866)
|
set(CPP_HTTPLIB_HASH a66f908f50ccb119769adce44fe1eac75f81b6ffab7c4ac0211bb663ffeb2688)
|
||||||
set(CURL_HASH ccc5ba45d9f5320c70ffb24e5411b66ba55ea1f333bf78be0963ed90a9328699)
|
set(CURL_HASH d4d9a5001b491f5726efe9b50bc4aad03029506e73c9261272e809c64b05e814)
|
||||||
set(EXPAT_HASH 85372797ff0673a8fc4a6be16466bb5a0ca28c0dcf3c6f7ac1686b4a3ba2aabb)
|
set(EXPAT_HASH 85372797ff0673a8fc4a6be16466bb5a0ca28c0dcf3c6f7ac1686b4a3ba2aabb)
|
||||||
set(GCC_HASH 7d376d445f93126dc545e2c0086d0f647c3094aae081cdb78f42ce2bc25e7293)
|
set(GCC_HASH 7294d65cc1a0558cb815af0ca8c7763d86f7a31199794ede3f630c0d1b0a5723)
|
||||||
set(GTEST_HASH 78c676fc63881529bf97bf9d45948d905a66833fbfa5318ea2cd7478cb98f399)
|
set(GTEST_HASH 65fab701d9829d38cb77c14acdc431d2108bfdbf8979e40eb8ae567edf10b27c)
|
||||||
set(ICU_HASH a2c443404f00098e9e90acf29dc318e049d2dc78d9ae5f46efb261934a730ce2)
|
set(ICU_HASH a2c443404f00098e9e90acf29dc318e049d2dc78d9ae5f46efb261934a730ce2)
|
||||||
|
set(INNOSETUP_HASH fa73bf47a4da250d185d07561c2bfda387e5e20db77e4570004cf6a133cc10b1)
|
||||||
set(JSON_HASH 4b92eb0c06d10683f7447ce9406cb97cd4b453be18d7279320f7b2f025c10187)
|
set(JSON_HASH 4b92eb0c06d10683f7447ce9406cb97cd4b453be18d7279320f7b2f025c10187)
|
||||||
set(MINGW_HASH cc41898aac4b6e8dd5cffd7331b9d9515b912df4420a3a612b5ea2955bbeed2f)
|
set(MINGW_HASH 5afe822af5c4edbf67daaf45eec61d538f49eef6b19524de64897c6b95828caf)
|
||||||
set(OPENSSL_HASH 344d0a79f1a9b08029b0744e2cc401a43f9c90acd1044d09a530b4885a8e9fc0)
|
set(OPENSSL_HASH b6a5f44b7eb69e3fa35dbf15524405b44837a481d43d81daddde3ff21fcbb8e9)
|
||||||
set(PKG_CONFIG_HASH 6fc69c01688c9458a57eb9a1664c9aba372ccda420a02bf4429fe610e7e7d591)
|
set(PKG_CONFIG_HASH 6fc69c01688c9458a57eb9a1664c9aba372ccda420a02bf4429fe610e7e7d591)
|
||||||
set(ROCKSDB_HASH 3fdc9ca996971c4c039959866382c4a3a6c8ade4abf888f3b2ff77153e07bf28)
|
set(ROCKSDB_HASH 7ec942baab802b2845188d02bc5d4e42c29236e61bcbc08f5b3a6bdd92290c22)
|
||||||
set(SPDLOG_HASH 7a80896357f3e8e920e85e92633b14ba0f229c506e6f978578bdc35ba09e9a5d)
|
set(SPDLOG_HASH 15a04e69c222eb6c01094b5c7ff8a249b36bb22788d72519646fb85feb267e67)
|
||||||
set(ZLIB_HASH 17e88863f3600672ab49182f217281b6fc4d3c762bde361935e436a95214d05c)
|
set(ZLIB_HASH 17e88863f3600672ab49182f217281b6fc4d3c762bde361935e436a95214d05c)
|
||||||
|
|||||||
@@ -4,12 +4,16 @@ set(Boost_USE_STATIC_LIBS ${PROJECT_STATIC_LINK})
|
|||||||
set(CURL_USE_STATIC_LIBS ${PROJECT_STATIC_LINK})
|
set(CURL_USE_STATIC_LIBS ${PROJECT_STATIC_LINK})
|
||||||
set(OPENSSL_USE_STATIC_LIBS ${PROJECT_STATIC_LINK})
|
set(OPENSSL_USE_STATIC_LIBS ${PROJECT_STATIC_LINK})
|
||||||
set(SFML_STATIC_LIBRARIES ${PROJECT_STATIC_LINK})
|
set(SFML_STATIC_LIBRARIES ${PROJECT_STATIC_LINK})
|
||||||
set(ZLIB_USE_STATIC_LIBS ${PROJECT_STATIC_LINK})
|
if (PROJECT_IS_DARWIN)
|
||||||
|
set(ZLIB_USE_STATIC_LIBS OFF)
|
||||||
|
else()
|
||||||
|
set(ZLIB_USE_STATIC_LIBS ${PROJECT_STATIC_LINK})
|
||||||
|
endif()
|
||||||
set(wxWidgets_USE_STATIC ${PROJECT_STATIC_LINK})
|
set(wxWidgets_USE_STATIC ${PROJECT_STATIC_LINK})
|
||||||
|
set(ICU_USE_STATIC_LIBS ${PROJECT_STATIC_LINK})
|
||||||
|
|
||||||
|
include(cmake/libraries/icu.cmake)
|
||||||
include(cmake/libraries/openssl.cmake)
|
include(cmake/libraries/openssl.cmake)
|
||||||
|
|
||||||
|
|
||||||
include(cmake/libraries/backward_cpp.cmake)
|
include(cmake/libraries/backward_cpp.cmake)
|
||||||
include(cmake/libraries/cpp_httplib.cmake)
|
include(cmake/libraries/cpp_httplib.cmake)
|
||||||
include(cmake/libraries/curl.cmake)
|
include(cmake/libraries/curl.cmake)
|
||||||
@@ -53,7 +57,7 @@ if(PROJECT_BUILD)
|
|||||||
winspool
|
winspool
|
||||||
ws2_32
|
ws2_32
|
||||||
)
|
)
|
||||||
else()
|
elseif(NOT PROJECT_IS_DARWIN)
|
||||||
link_libraries(
|
link_libraries(
|
||||||
uring
|
uring
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ if(PROJECT_ENABLE_CPP_HTTPLIB)
|
|||||||
CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
|
CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
|
||||||
-DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
|
-DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
|
||||||
-DBUILD_STATIC_LIBS=ON
|
-DBUILD_STATIC_LIBS=ON
|
||||||
|
-DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
|
||||||
-DHTTPLIB_REQUIRE_BROTLI=OFF
|
-DHTTPLIB_REQUIRE_BROTLI=OFF
|
||||||
-DHTTPLIB_REQUIRE_OPENSSL=ON
|
-DHTTPLIB_REQUIRE_OPENSSL=ON
|
||||||
-DHTTPLIB_REQUIRE_ZLIB=ON
|
-DHTTPLIB_REQUIRE_ZLIB=ON
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ if(PROJECT_ENABLE_CURL)
|
|||||||
-DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
|
-DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
|
||||||
-DBUILD_STATIC_CURL=ON
|
-DBUILD_STATIC_CURL=ON
|
||||||
-DBUILD_STATIC_LIBS=ON
|
-DBUILD_STATIC_LIBS=ON
|
||||||
-DBUILD_STATIC_LIBS=ON
|
|
||||||
-DBUILD_TESTING=OFF
|
-DBUILD_TESTING=OFF
|
||||||
|
-DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
|
||||||
-DCURL_BROTLI=OFF
|
-DCURL_BROTLI=OFF
|
||||||
-DCURL_CA_BUNDLE=./cacert.pem
|
-DCURL_CA_BUNDLE=./cacert.pem
|
||||||
-DCURL_CA_FALLBACK=ON
|
-DCURL_CA_FALLBACK=ON
|
||||||
@@ -37,11 +37,13 @@ if(PROJECT_ENABLE_CURL)
|
|||||||
-DCURL_USE_LIBSSH2=OFF
|
-DCURL_USE_LIBSSH2=OFF
|
||||||
-DCURL_USE_OPENSSL=${PROJECT_ENABLE_OPENSSL}
|
-DCURL_USE_OPENSSL=${PROJECT_ENABLE_OPENSSL}
|
||||||
-DCURL_ZLIB=ON
|
-DCURL_ZLIB=ON
|
||||||
|
-DCURL_ZSTD=OFF
|
||||||
-DENABLE_CURL_MANUAL=OFF
|
-DENABLE_CURL_MANUAL=OFF
|
||||||
-DENABLE_THREADED_RESOLVER=ON
|
-DENABLE_THREADED_RESOLVER=ON
|
||||||
-DOPENSSL_ROOT_DIR=${OPENSSL_ROOT_DIR}
|
-DOPENSSL_ROOT_DIR=${OPENSSL_ROOT_DIR}
|
||||||
-DOPENSSL_USE_STATIC_LIBS=${OPENSSL_USE_STATIC_LIBS}
|
-DOPENSSL_USE_STATIC_LIBS=${OPENSSL_USE_STATIC_LIBS}
|
||||||
-DUSE_LIBIDN2=OFF
|
-DUSE_LIBIDN2=OFF
|
||||||
|
-DUSE_NGHTTP2=OFF
|
||||||
-DZLIB_USE_STATIC_LIBS=${ZLIB_USE_STATIC_LIBS}
|
-DZLIB_USE_STATIC_LIBS=${ZLIB_USE_STATIC_LIBS}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
24
cmake/libraries/icu.cmake
Normal file
24
cmake/libraries/icu.cmake
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
if((PROJECT_IS_DARWIN OR PROJECT_REQUIRE_ALPINE) AND NOT PROJECT_IS_MINGW AND NOT PROJECT_BUILD)
|
||||||
|
if(PROJECT_BUILD_SHARED_LIBS)
|
||||||
|
set(ICU_ENABLE_SHARED yes)
|
||||||
|
else()
|
||||||
|
set(ICU_ENABLE_SHARED no)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
ExternalProject_Add(icu_project
|
||||||
|
PREFIX external
|
||||||
|
URL ${PROJECT_3RD_PARTY_DIR}/mingw64/icu-release-${ICU_VERSION}.tar.gz
|
||||||
|
URL_HASH SHA256=${ICU_HASH}
|
||||||
|
BUILD_IN_SOURCE 1
|
||||||
|
LIST_SEPARATOR |
|
||||||
|
PATCH_COMMAND chmod +x ${PROJECT_3RD_PARTY_DIR}/icu_configure.sh
|
||||||
|
CONFIGURE_COMMAND cd icu4c/source && ${PROJECT_3RD_PARTY_DIR}/icu_configure.sh
|
||||||
|
${PROJECT_MARCH}
|
||||||
|
${PROJECT_EXTERNAL_BUILD_ROOT}
|
||||||
|
${ICU_ENABLE_SHARED}
|
||||||
|
BUILD_COMMAND cd icu4c/source && make -j$ENV{CMAKE_BUILD_PARALLEL_LEVEL}
|
||||||
|
INSTALL_COMMAND cd icu4c/source && make install
|
||||||
|
)
|
||||||
|
|
||||||
|
list(APPEND PROJECT_DEPENDENCIES icu_project)
|
||||||
|
endif()
|
||||||
@@ -18,6 +18,7 @@ if(PROJECT_ENABLE_JSON)
|
|||||||
CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
|
CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
|
||||||
-DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
|
-DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
|
||||||
-DBUILD_STATIC_LIBS=ON
|
-DBUILD_STATIC_LIBS=ON
|
||||||
|
-DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
|
||||||
-DJSON_BuildTests=OFF
|
-DJSON_BuildTests=OFF
|
||||||
-DJSON_Install=ON
|
-DJSON_Install=ON
|
||||||
-DJSON_MultipleHeaders=OFF
|
-DJSON_MultipleHeaders=OFF
|
||||||
|
|||||||
@@ -15,6 +15,12 @@ if(PROJECT_ENABLE_OPENSSL)
|
|||||||
elseif(NOT PROJECT_IS_MINGW)
|
elseif(NOT PROJECT_IS_MINGW)
|
||||||
if(PROJECT_IS_MINGW)
|
if(PROJECT_IS_MINGW)
|
||||||
set(OPENSSL_COMPILE_TYPE mingw64)
|
set(OPENSSL_COMPILE_TYPE mingw64)
|
||||||
|
elseif(PROJECT_IS_DARWIN)
|
||||||
|
if(PROJECT_IS_ARM64)
|
||||||
|
set(OPENSSL_COMPILE_TYPE darwin64-arm64)
|
||||||
|
else()
|
||||||
|
set(OPENSSL_COMPILE_TYPE darwin64-x86_64)
|
||||||
|
endif()
|
||||||
elseif(PROJECT_IS_ARM64)
|
elseif(PROJECT_IS_ARM64)
|
||||||
set(OPENSSL_COMPILE_TYPE linux-aarch64)
|
set(OPENSSL_COMPILE_TYPE linux-aarch64)
|
||||||
else()
|
else()
|
||||||
|
|||||||
@@ -14,12 +14,14 @@ if(PROJECT_ENABLE_ROCKSDB)
|
|||||||
CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
|
CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
|
||||||
-DBUILD_SHARED_LIBS=OFF
|
-DBUILD_SHARED_LIBS=OFF
|
||||||
-DBUILD_STATIC_LIBS=ON
|
-DBUILD_STATIC_LIBS=ON
|
||||||
|
-DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
|
||||||
-DFAIL_ON_WARNINGS=OFF
|
-DFAIL_ON_WARNINGS=OFF
|
||||||
-DPORTABLE=1
|
-DPORTABLE=1
|
||||||
-DROCKSDB_BUILD_SHARED=OFF
|
-DROCKSDB_BUILD_SHARED=OFF
|
||||||
-DROCKSDB_INSTALL_ON_WINDOWS=ON
|
-DROCKSDB_INSTALL_ON_WINDOWS=ON
|
||||||
-DWITH_BENCHMARK=OFF
|
-DWITH_BENCHMARK=OFF
|
||||||
-DWITH_BENCHMARK_TOOLS=OFF
|
-DWITH_BENCHMARK_TOOLS=OFF
|
||||||
|
-DWITH_BZ2=OFF
|
||||||
-DWITH_CORE_TOOLS=OFF
|
-DWITH_CORE_TOOLS=OFF
|
||||||
-DWITH_EXAMPLES=OFF
|
-DWITH_EXAMPLES=OFF
|
||||||
-DWITH_GFLAGS=OFF
|
-DWITH_GFLAGS=OFF
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ if(PROJECT_ENABLE_SPDLOG)
|
|||||||
LIST_SEPARATOR |
|
LIST_SEPARATOR |
|
||||||
CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
|
CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
|
||||||
-DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
|
-DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
|
||||||
|
-DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
|
||||||
-DSPDLOG_BUILD_EXAMPLE=OFF
|
-DSPDLOG_BUILD_EXAMPLE=OFF
|
||||||
-DSPDLOG_FMT_EXTERNAL=OFF
|
-DSPDLOG_FMT_EXTERNAL=OFF
|
||||||
-DSPDLOG_FMT_EXTERNAL_HO=OFF
|
-DSPDLOG_FMT_EXTERNAL_HO=OFF
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ if (PROJECT_ENABLE_TESTING)
|
|||||||
CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
|
CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
|
||||||
-DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
|
-DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
|
||||||
-DBUILD_STATIC_LIBS=ON
|
-DBUILD_STATIC_LIBS=ON
|
||||||
|
-DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND PROJECT_DEPENDENCIES gtest_project)
|
list(APPEND PROJECT_DEPENDENCIES gtest_project)
|
||||||
|
|||||||
@@ -2,10 +2,6 @@ if(MSVC)
|
|||||||
message(FATAL_ERROR "MSVC will not be supported")
|
message(FATAL_ERROR "MSVC will not be supported")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(UNIX AND APPLE)
|
|
||||||
message(FATAL_ERROR "Apple is not currently supported")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
|
if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
|
||||||
message(FATAL_ERROR "FreeBSD is not currently supported")
|
message(FATAL_ERROR "FreeBSD is not currently supported")
|
||||||
endif()
|
endif()
|
||||||
@@ -13,3 +9,15 @@ endif()
|
|||||||
if(PROJECT_REQUIRE_ALPINE AND NOT PROJECT_IS_ALPINE AND PROJECT_IS_MINGW AND PROJECT_IS_MINGW_UNIX)
|
if(PROJECT_REQUIRE_ALPINE AND NOT PROJECT_IS_ALPINE AND PROJECT_IS_MINGW AND PROJECT_IS_MINGW_UNIX)
|
||||||
message(FATAL_ERROR "Project requires Alpine Linux to build")
|
message(FATAL_ERROR "Project requires Alpine Linux to build")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (PROJECT_IS_DARWIN)
|
||||||
|
if (PROJECT_IS_ARM64)
|
||||||
|
set(CMAKE_OSX_ARCHITECTURES "arm64")
|
||||||
|
else()
|
||||||
|
set(CMAKE_OSX_ARCHITECTURES "x86_64")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (PROJECT_IS_DARWIN AND NOT PROJECT_MACOS_BUNDLE_ID)
|
||||||
|
message(FATAL_ERROR "'PROJECT_MACOS_BUNDLE_ID' is not set in 'config.sh'")
|
||||||
|
endif()
|
||||||
|
|||||||
@@ -3,21 +3,21 @@ set(BOOST2_MAJOR_VERSION 1)
|
|||||||
set(BOOST2_MINOR_VERSION 76)
|
set(BOOST2_MINOR_VERSION 76)
|
||||||
set(BOOST2_PATCH_VERSION 0)
|
set(BOOST2_PATCH_VERSION 0)
|
||||||
set(BOOST_MAJOR_VERSION 1)
|
set(BOOST_MAJOR_VERSION 1)
|
||||||
set(BOOST_MINOR_VERSION 88)
|
set(BOOST_MINOR_VERSION 89)
|
||||||
set(BOOST_PATCH_VERSION 0)
|
set(BOOST_PATCH_VERSION 0)
|
||||||
set(CPP_HTTPLIB_VERSION 0.20.0)
|
set(CPP_HTTPLIB_VERSION 0.26.0)
|
||||||
set(CURL2_VERSION 8_13_0)
|
set(CURL2_VERSION 8_16_0)
|
||||||
set(CURL_VERSION 8.13.0)
|
set(CURL_VERSION 8.16.0)
|
||||||
set(EXPAT2_VERSION 2_7_1)
|
set(EXPAT2_VERSION 2_7_1)
|
||||||
set(EXPAT_VERSION 2.7.1)
|
set(EXPAT_VERSION 2.7.1)
|
||||||
set(GCC_VERSION 14.2.0)
|
set(GCC_VERSION 15.2.0)
|
||||||
set(GTEST_VERSION 1.16.0)
|
set(GTEST_VERSION 1.17.0)
|
||||||
set(ICU_VERSION 76-1)
|
set(ICU_VERSION 76-1)
|
||||||
|
set(INNOSETUP_VERSION 6.5.4)
|
||||||
set(JSON_VERSION 3.12.0)
|
set(JSON_VERSION 3.12.0)
|
||||||
set(MESA_VERSION 23.3.3)
|
set(MINGW_VERSION 13.0.0)
|
||||||
set(MINGW_VERSION 12.0.0)
|
set(OPENSSL_VERSION 3.6.0)
|
||||||
set(OPENSSL_VERSION 3.5.0)
|
|
||||||
set(PKG_CONFIG_VERSION 0.29.2)
|
set(PKG_CONFIG_VERSION 0.29.2)
|
||||||
set(ROCKSDB_VERSION 10.0.1)
|
set(ROCKSDB_VERSION 10.5.1)
|
||||||
set(SPDLOG_VERSION 1.15.2)
|
set(SPDLOG_VERSION 1.15.3)
|
||||||
set(ZLIB_VERSION 1.3.1)
|
set(ZLIB_VERSION 1.3.1)
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ PROJECT_URL="https://git.fifthgrid.com/public/monitarr"
|
|||||||
|
|
||||||
PROJECT_MAJOR_VERSION=1
|
PROJECT_MAJOR_VERSION=1
|
||||||
PROJECT_MINOR_VERSION=1
|
PROJECT_MINOR_VERSION=1
|
||||||
PROJECT_REVISION_VERSION=0
|
PROJECT_REVISION_VERSION=1
|
||||||
PROJECT_RELEASE_NUM=0
|
PROJECT_RELEASE_NUM=0
|
||||||
PROJECT_RELEASE_ITER=release
|
PROJECT_RELEASE_ITER=rc
|
||||||
|
|
||||||
PROJECT_APP_LIST=(${PROJECT_NAME})
|
PROJECT_APP_LIST=(${PROJECT_NAME})
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#comment
|
#comment
|
||||||
FROM arm64v8/alpine:3.21.3
|
FROM arm64v8/alpine:3.22.2
|
||||||
MAINTAINER Scott E. Graves <scott.e.graves@protonmail.com>
|
MAINTAINER Scott E. Graves <scott.e.graves@protonmail.com>
|
||||||
CMD bash
|
CMD bash
|
||||||
|
|
||||||
@@ -32,9 +32,6 @@ RUN apk add \
|
|||||||
gflags-dev \
|
gflags-dev \
|
||||||
git \
|
git \
|
||||||
git-lfs \
|
git-lfs \
|
||||||
icu-dev \
|
|
||||||
icu-libs \
|
|
||||||
icu-static \
|
|
||||||
libogg-dev \
|
libogg-dev \
|
||||||
libogg-static \
|
libogg-static \
|
||||||
libtool \
|
libtool \
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#comment
|
#comment
|
||||||
FROM alpine:3.21.3
|
FROM alpine:3.22.2
|
||||||
MAINTAINER Scott E. Graves <scott.e.graves@protonmail.com>
|
MAINTAINER Scott E. Graves <scott.e.graves@protonmail.com>
|
||||||
CMD bash
|
CMD bash
|
||||||
|
|
||||||
@@ -32,9 +32,6 @@ RUN apk add \
|
|||||||
gflags-dev \
|
gflags-dev \
|
||||||
git \
|
git \
|
||||||
git-lfs \
|
git-lfs \
|
||||||
icu-dev \
|
|
||||||
icu-libs \
|
|
||||||
icu-static \
|
|
||||||
libogg-dev \
|
libogg-dev \
|
||||||
libogg-static \
|
libogg-static \
|
||||||
libtool \
|
libtool \
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ RUN apt-get install -y \
|
|||||||
gdb \
|
gdb \
|
||||||
git \
|
git \
|
||||||
lib32stdc++6 \
|
lib32stdc++6 \
|
||||||
libgconf-2-4 \
|
|
||||||
libglu1-mesa \
|
libglu1-mesa \
|
||||||
libstdc++6 \
|
libstdc++6 \
|
||||||
python3 \
|
python3 \
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#comment
|
#comment
|
||||||
FROM alpine:3.21.3
|
FROM alpine:3.22.2
|
||||||
|
|
||||||
RUN apk update
|
RUN apk update
|
||||||
RUN apk upgrade
|
RUN apk upgrade
|
||||||
@@ -12,6 +12,7 @@ RUN apk add \
|
|||||||
bzip2 \
|
bzip2 \
|
||||||
clang17-extra-tools \
|
clang17-extra-tools \
|
||||||
cmake \
|
cmake \
|
||||||
|
curl \
|
||||||
file \
|
file \
|
||||||
flex \
|
flex \
|
||||||
g++ \
|
g++ \
|
||||||
@@ -43,6 +44,7 @@ RUN apk add \
|
|||||||
ruby \
|
ruby \
|
||||||
texinfo \
|
texinfo \
|
||||||
unzip \
|
unzip \
|
||||||
|
xvfb \
|
||||||
wget \
|
wget \
|
||||||
wine \
|
wine \
|
||||||
xz \
|
xz \
|
||||||
@@ -102,6 +104,39 @@ RUN echo -e \
|
|||||||
"system = 'windows'\n"\
|
"system = 'windows'\n"\
|
||||||
> ${MY_TOOLCHAIN_FILE_MESON}
|
> ${MY_TOOLCHAIN_FILE_MESON}
|
||||||
|
|
||||||
|
RUN mkdir -p /opt/bin;echo -e \
|
||||||
|
"#!/bin/sh\n"\
|
||||||
|
"COUNT=0\n"\
|
||||||
|
"echo \"Start waiting on \$@\"\n"\
|
||||||
|
"while pgrep \"\$@\" > /dev/null; do \n"\
|
||||||
|
" echo \"waiting ...\"\n"\
|
||||||
|
" sleep 1;\n"\
|
||||||
|
" COUNT=\$((COUNT+1))\n"\
|
||||||
|
" if [ \$COUNT -eq 60 ]; then\n"\
|
||||||
|
" exit 3;\n"\
|
||||||
|
" fi\n"\
|
||||||
|
"done\n"\
|
||||||
|
"echo \"\$@ completed\"\n"\
|
||||||
|
> /opt/bin/waitonprocess && \
|
||||||
|
chmod +x /opt/bin/waitonprocess && \
|
||||||
|
cat /opt/bin/waitonprocess
|
||||||
|
|
||||||
|
RUN echo -e \
|
||||||
|
"#!/bin/sh\n"\
|
||||||
|
"Xvfb \$DISPLAY &\n"\
|
||||||
|
"tokill=\$!\n"\
|
||||||
|
"wine wineboot --init\n"\
|
||||||
|
"waitonprocess wineserver\n"\
|
||||||
|
"\"\$@\"\n"\
|
||||||
|
"retval=\$?\n"\
|
||||||
|
"kill -15 \$tokill\n"\
|
||||||
|
"wine wineboot --shutdown\n"\
|
||||||
|
"return \$retval\n"\
|
||||||
|
> /opt/bin/wine-x11-run && \
|
||||||
|
chmod +x /opt/bin/wine-x11-run && \
|
||||||
|
cat /opt/bin/wine-x11-run
|
||||||
|
|
||||||
|
ENV PATH="/opt/bin:${PATH}"
|
||||||
SHELL [ "/bin/bash", "-c" ]
|
SHELL [ "/bin/bash", "-c" ]
|
||||||
|
|
||||||
RUN mkdir -p \
|
RUN mkdir -p \
|
||||||
@@ -711,6 +746,7 @@ RUN if [ -f "/3rd_party/cpp-httplib-${MY_CPP_HTTPLIB_VERSION}.tar.gz" ]; then \
|
|||||||
-DCMAKE_BUILD_TYPE=Release \
|
-DCMAKE_BUILD_TYPE=Release \
|
||||||
-DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
|
-DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
|
||||||
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
|
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
|
||||||
|
-DCMAKE_SYSTEM_VERSION="10.0.0" \
|
||||||
-DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
|
-DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
|
||||||
-DHTTPLIB_REQUIRE_BROTLI=OFF \
|
-DHTTPLIB_REQUIRE_BROTLI=OFF \
|
||||||
-DHTTPLIB_REQUIRE_OPENSSL=ON \
|
-DHTTPLIB_REQUIRE_OPENSSL=ON \
|
||||||
@@ -799,6 +835,7 @@ RUN if [ -f "/3rd_party/libevent-${MY_LIBEVENT_VERSION}-stable.tar.gz" ]; then \
|
|||||||
&& cmake .. \
|
&& cmake .. \
|
||||||
-DCMAKE_BUILD_TYPE=Release \
|
-DCMAKE_BUILD_TYPE=Release \
|
||||||
-DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
|
-DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
|
||||||
|
-DCMAKE_C_FLAGS="-include winsock2.h -include ws2tcpip.h -include iphlpapi.h" \
|
||||||
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
|
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
|
||||||
-DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
|
-DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
|
||||||
-DEVENT__DISABLE_OPENSSL=ON \
|
-DEVENT__DISABLE_OPENSSL=ON \
|
||||||
@@ -888,6 +925,7 @@ RUN if [ -f "/3rd_party/rocksdb-${MY_ROCKSDB_VERSION}.tar.gz" ]; then \
|
|||||||
-DROCKSDB_INSTALL_ON_WINDOWS=ON \
|
-DROCKSDB_INSTALL_ON_WINDOWS=ON \
|
||||||
-DWITH_BENCHMARK=OFF \
|
-DWITH_BENCHMARK=OFF \
|
||||||
-DWITH_BENCHMARK_TOOLS=OFF \
|
-DWITH_BENCHMARK_TOOLS=OFF \
|
||||||
|
-DWITH_BZ2=OFF \
|
||||||
-DWITH_CORE_TOOLS=OFF \
|
-DWITH_CORE_TOOLS=OFF \
|
||||||
-DWITH_EXAMPLES=OFF \
|
-DWITH_EXAMPLES=OFF \
|
||||||
-DWITH_GFLAGS=OFF \
|
-DWITH_GFLAGS=OFF \
|
||||||
@@ -1119,6 +1157,33 @@ RUN if [ -f "/3rd_party/libdsm-${MY_LIBDSM_VERSION}.tar.gz" ]; then \
|
|||||||
&& rm -r libdsm-${MY_LIBDSM_VERSION} \
|
&& rm -r libdsm-${MY_LIBDSM_VERSION} \
|
||||||
; fi
|
; fi
|
||||||
|
|
||||||
RUN (mv ${MY_MINGW_DIR}/lib/*.dll ${MY_MINGW_DIR}/bin || echo "no dll's found") \
|
ENV DISPLAY=:90
|
||||||
|
ENV WINEDEBUG=-all,err+all
|
||||||
|
|
||||||
|
ARG INNOSETUP_VERSION
|
||||||
|
ENV MY_INNOSETUP_VERSION=${INNOSETUP_VERSION}
|
||||||
|
RUN rm -rf /root/.wine; \
|
||||||
|
wine64 reg add 'HKEY_CURRENT_USER\Software\Wine' /v ShowDotFiles /d Y \
|
||||||
|
&& while [ ! -f /root/.wine/user.reg ]; do sleep 1; done; \
|
||||||
|
wine-x11-run wine64 /3rd_party/mingw64/innosetup-${MY_INNOSETUP_VERSION}.exe /SP- /VERYSILENT /ALLUSERS /SUPPRESSMSGBOXES /DOWNLOADISCRYPT=1
|
||||||
|
|
||||||
|
ARG UID=1000
|
||||||
|
ARG GID=1000
|
||||||
|
ARG USERNAME=myuser
|
||||||
|
|
||||||
|
RUN delgroup scanner || echo "no scanner group found"
|
||||||
|
|
||||||
|
RUN addgroup -g $GID $USERNAME && \
|
||||||
|
adduser -D -u $UID -G $USERNAME -h /home/$USERNAME $USERNAME
|
||||||
|
|
||||||
|
RUN rsync -av --progress /root/.wine/ /home/$USERNAME/.wine/ && \
|
||||||
|
chown -R $UID:$GID -R /home/$USERNAME/.wine/
|
||||||
|
|
||||||
|
RUN (cp ${MY_MINGW_DIR}/lib/*.dll ${MY_MINGW_DIR}/bin || echo "no dll's found") \
|
||||||
&& chmod 0777 -R ${MY_MINGW_DIR} \
|
&& chmod 0777 -R ${MY_MINGW_DIR} \
|
||||||
&& rm -rf /3rd_party
|
&& rm -rf /3rd_party \
|
||||||
|
&& rm -rf /root/.wine
|
||||||
|
|
||||||
|
USER $USERNAME
|
||||||
|
WORKDIR /home/$USERNAME
|
||||||
|
|
||||||
|
|||||||
@@ -1,24 +1,3 @@
|
|||||||
/*
|
|
||||||
Copyright <2018-2025> <scott.e.graves@protonmail.com>
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
*/
|
|
||||||
#ifndef LIBMONITARR_INCLUDE_INITIALIZE_HPP_
|
#ifndef LIBMONITARR_INCLUDE_INITIALIZE_HPP_
|
||||||
#define LIBMONITARR_INCLUDE_INITIALIZE_HPP_
|
#define LIBMONITARR_INCLUDE_INITIALIZE_HPP_
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#include "version.hpp"
|
#include "version.hpp"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
static constexpr const std::string_view git_rev = "@PROJECT_GIT_REV@";
|
constexpr std::string_view git_rev = "@PROJECT_GIT_REV@";
|
||||||
static constexpr const std::string_view version =
|
constexpr std::string_view version =
|
||||||
"@PROJECT_MAJOR_VERSION@.@PROJECT_MINOR_VERSION@.@PROJECT_REVISION_VERSION@"
|
"@PROJECT_MAJOR_VERSION@.@PROJECT_MINOR_VERSION@.@PROJECT_REVISION_VERSION@"
|
||||||
"-@PROJECT_RELEASE_ITER@";
|
"-@PROJECT_RELEASE_ITER@";
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
PROJECT_MINGW64_COPY_DEPENDENCIES=()
|
PROJECT_MINGW64_COPY_DEPENDENCIES=()
|
||||||
|
|
||||||
@@ -194,7 +194,7 @@ if [ "${PROJECT_ENABLE_WINFSP}" == "ON" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "${WINFSP_DLL_PART}" != "" ]; then
|
if [ "${WINFSP_DLL_PART}" != "" ]; then
|
||||||
PROJECT_MINGW64_COPY_DEPENDENCIES+=(${PROJECT_3RD_PARTY_DIR}/winfsp-2.0/bin/winfsp-${WINFSP_DLL_PART}.dll)
|
PROJECT_MINGW64_COPY_DEPENDENCIES+=(${PROJECT_3RD_PARTY_DIR}/winfsp-2.1/bin/winfsp-${WINFSP_DLL_PART}.dll)
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
PROJECT_SCRIPTS_DIR=$(realpath "$0")
|
PROJECT_SCRIPTS_DIR=$(realpath "$0")
|
||||||
PROJECT_SCRIPTS_DIR=$(dirname "${PROJECT_SCRIPTS_DIR}")
|
PROJECT_SCRIPTS_DIR=$(dirname "${PROJECT_SCRIPTS_DIR}")
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
DEST_DIR=$1
|
DEST_DIR=$1
|
||||||
DIST_DIR=$2
|
DIST_DIR=$2
|
||||||
@@ -35,7 +35,7 @@ fi
|
|||||||
|
|
||||||
pushd "${PROJECT_SOURCE_DIR}"
|
pushd "${PROJECT_SOURCE_DIR}"
|
||||||
BRANCH=$(git branch --show-current)
|
BRANCH=$(git branch --show-current)
|
||||||
RELEASE=$(grep PROJECT_RELEASE_ITER= ./config.sh | sed s/PROJECT_RELEASE_ITER=//g)
|
RELEASE=$(grep PROJECT_RELEASE_ITER= ./config.sh | ${SED} s/PROJECT_RELEASE_ITER=//g)
|
||||||
popd
|
popd
|
||||||
|
|
||||||
if [ "${BRANCH}" == "master" ] || [ "${BRANCH}" == "alpha" ] ||
|
if [ "${BRANCH}" == "master" ] || [ "${BRANCH}" == "alpha" ] ||
|
||||||
@@ -62,10 +62,41 @@ if [ "${PROJECT_PRIVATE_KEY}" != "" ] && [ ! -f "./${PROJECT_OUT_FILE}.sig" ]; t
|
|||||||
error_exit "failed to find file: ${PROJECT_OUT_FILE}.sig" 1
|
error_exit "failed to find file: ${PROJECT_OUT_FILE}.sig" 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cp -f ./${PROJECT_OUT_FILE} ${DEST_DIR} || error_exit "failed to deliver file: ${PROJECT_OUT_FILE}" 1
|
cp -f ./${PROJECT_OUT_FILE} ${DEST_DIR} ||
|
||||||
cp -f ./${PROJECT_OUT_FILE}.sha256 ${DEST_DIR} || error_exit "failed to deliver file: ${PROJECT_OUT_FILE}.sha256" 1
|
error_exit "failed to deliver file: ${PROJECT_OUT_FILE}" 1
|
||||||
|
|
||||||
|
cp -f ./${PROJECT_OUT_FILE}.sha256 ${DEST_DIR} ||
|
||||||
|
error_exit "failed to deliver file: ${PROJECT_OUT_FILE}.sha256" 1
|
||||||
|
|
||||||
if [ "${PROJECT_PRIVATE_KEY}" != "" ]; then
|
if [ "${PROJECT_PRIVATE_KEY}" != "" ]; then
|
||||||
cp -f ./${PROJECT_OUT_FILE}.sig ${DEST_DIR} || error_exit "failed to deliver file: ${PROJECT_OUT_FILE}.sig" 1
|
cp -f ./${PROJECT_OUT_FILE}.sig ${DEST_DIR} ||
|
||||||
|
error_exit "failed to deliver file: ${PROJECT_OUT_FILE}.sig" 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${PROJECT_IS_MINGW}" == "1" ] && [ -f "${PROJECT_DIST_DIR}/${PROJECT_FILE_PART}_setup.exe" ]; then
|
||||||
|
cp -f "${PROJECT_DIST_DIR}/${PROJECT_FILE_PART}_setup.exe" ${DEST_DIR} ||
|
||||||
|
error_exit "failed to deliver file: ${PROJECT_DIST_DIR}/${PROJECT_FILE_PART}" 1
|
||||||
|
|
||||||
|
cp -f "${PROJECT_DIST_DIR}/${PROJECT_FILE_PART}_setup.exe.sha256" ${DEST_DIR} ||
|
||||||
|
error_exit "failed to deliver file: ${PROJECT_DIST_DIR}/${PROJECT_FILE_PART}_setup.exe.sha256" 1
|
||||||
|
|
||||||
|
if [ "${PROJECT_PRIVATE_KEY}" != "" ]; then
|
||||||
|
cp -f "${PROJECT_DIST_DIR}/${PROJECT_FILE_PART}_setup.exe.sig" ${DEST_DIR} ||
|
||||||
|
error_exit "failed to deliver file: ${PROJECT_DIST_DIR}/${PROJECT_FILE_PART}_setup.exe.sig" 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${PROJECT_IS_DARWIN}" == "1" ] && [ -f "${PROJECT_DIST_DIR}/${PROJECT_FILE_PART}.dmg" ]; then
|
||||||
|
cp -f -X "${PROJECT_DIST_DIR}/${PROJECT_FILE_PART}.dmg" ${DEST_DIR} ||
|
||||||
|
error_exit "failed to deliver file: ${PROJECT_DIST_DIR}/${PROJECT_FILE_PART}.dmg" 1
|
||||||
|
|
||||||
|
cp -f -X "${PROJECT_DIST_DIR}/${PROJECT_FILE_PART}.dmg.sha256" ${DEST_DIR} ||
|
||||||
|
error_exit "failed to deliver file: ${PROJECT_DIST_DIR}/${PROJECT_FILE_PART}.dmg.sha256" 1
|
||||||
|
|
||||||
|
if [ "${PROJECT_PRIVATE_KEY}" != "" ]; then
|
||||||
|
cp -f -X "${PROJECT_DIST_DIR}/${PROJECT_FILE_PART}.dmg.sig" ${DEST_DIR} ||
|
||||||
|
error_exit "failed to deliver file: ${PROJECT_DIST_DIR}/${PROJECT_FILE_PART}.dmg.sig" 1
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
popd
|
popd
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
if [ "${PROJECT_BUILD_ARCH}" == "aarch64" ] &&
|
if [ "${PROJECT_BUILD_ARCH}" == "aarch64" ] &&
|
||||||
[ "${PROJECT_ENABLE_MULTIARCH_DOCKER}" == "1" ]; then
|
[ "${PROJECT_ENABLE_MULTIARCH_DOCKER}" == "1" ]; then
|
||||||
@@ -26,10 +26,16 @@ if [ "${PROJECT_BUILD_ARCH}" == "aarch64" ]; then
|
|||||||
docker build ${APP_VERSION_BUILD_ARGS} \
|
docker build ${APP_VERSION_BUILD_ARGS} \
|
||||||
--platform linux/arm64 \
|
--platform linux/arm64 \
|
||||||
--build-arg NUM_JOBS=${NUM_JOBS} \
|
--build-arg NUM_JOBS=${NUM_JOBS} \
|
||||||
|
--build-arg UID=$(id -u) \
|
||||||
|
--build-arg GID=$(id -g) \
|
||||||
|
--build-arg USERNAME=$(id -un) \
|
||||||
-t ${DOCKER_TAG} . || exit 1
|
-t ${DOCKER_TAG} . || exit 1
|
||||||
else
|
else
|
||||||
docker build ${APP_VERSION_BUILD_ARGS} \
|
docker build ${APP_VERSION_BUILD_ARGS} \
|
||||||
--build-arg NUM_JOBS=${NUM_JOBS} \
|
--build-arg NUM_JOBS=${NUM_JOBS} \
|
||||||
|
--build-arg UID=$(id -u) \
|
||||||
|
--build-arg GID=$(id -g) \
|
||||||
|
--build-arg USERNAME=$(id -un) \
|
||||||
-t ${DOCKER_TAG} . || exit 1
|
-t ${DOCKER_TAG} . || exit 1
|
||||||
fi
|
fi
|
||||||
rm Dockerfile
|
rm Dockerfile
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
PROJECT_BUILD_ARCH=$1
|
PROJECT_BUILD_ARCH=$1
|
||||||
PROJECT_CMAKE_BUILD_TYPE=$2
|
PROJECT_CMAKE_BUILD_TYPE=$2
|
||||||
@@ -47,18 +47,34 @@ done
|
|||||||
|
|
||||||
PROJECT_APP_LIST=()
|
PROJECT_APP_LIST=()
|
||||||
PROJECT_CMAKE_OPTS=""
|
PROJECT_CMAKE_OPTS=""
|
||||||
PROJECT_ENABLE_WIN32_LONG_PATH_NAMES=OFF
|
|
||||||
PROJECT_ENABLE_V2_ERRORS=OFF
|
PROJECT_ENABLE_V2_ERRORS=OFF
|
||||||
|
PROJECT_ENABLE_WIN32_LONG_PATH_NAMES=OFF
|
||||||
PROJECT_IS_ALPINE=0
|
PROJECT_IS_ALPINE=0
|
||||||
PROJECT_IS_ARM64=0
|
PROJECT_IS_ARM64=0
|
||||||
|
PROJECT_IS_DARWIN=0
|
||||||
PROJECT_MINGW64_COPY_DEPENDENCIES=()
|
PROJECT_MINGW64_COPY_DEPENDENCIES=()
|
||||||
PROJECT_MSYS2_PACKAGE_LIST=()
|
PROJECT_MSYS2_PACKAGE_LIST=()
|
||||||
PROJECT_REQUIRE_ALPINE=OFF
|
PROJECT_REQUIRE_ALPINE=OFF
|
||||||
PROJECT_STATIC_LINK=OFF
|
PROJECT_STATIC_LINK=OFF
|
||||||
|
PROJECT_MACOS_BUNDLE_ID=""
|
||||||
|
PROJECT_MACOS_ICNS_NAME=""
|
||||||
|
|
||||||
|
if [ "$(uname -s)" == "Darwin" ]; then
|
||||||
|
PROJECT_IS_DARWIN=1
|
||||||
|
export SED=gsed
|
||||||
|
else
|
||||||
|
export SED=sed
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "${PROJECT_BUILD_ARCH}" == "" ]; then
|
if [ "${PROJECT_BUILD_ARCH}" == "" ]; then
|
||||||
|
if [ "$(uname -m)" == "arm64" ]; then
|
||||||
|
PROJECT_BUILD_ARCH=aarch64
|
||||||
|
else
|
||||||
PROJECT_BUILD_ARCH=x86_64
|
PROJECT_BUILD_ARCH=x86_64
|
||||||
elif [ "${PROJECT_BUILD_ARCH}" == "aarch64" ]; then
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${PROJECT_BUILD_ARCH}" == "aarch64" ]; then
|
||||||
PROJECT_IS_ARM64=1
|
PROJECT_IS_ARM64=1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -173,7 +189,11 @@ if [ "${PROJECT_STATIC_LINK}" == "ON" ]; then
|
|||||||
PROJECT_BUILD_SHARED_LIBS=OFF
|
PROJECT_BUILD_SHARED_LIBS=OFF
|
||||||
PROJECT_ENABLE_BACKWARD_CPP=OFF
|
PROJECT_ENABLE_BACKWARD_CPP=OFF
|
||||||
PROJECT_LINK_TYPE=static
|
PROJECT_LINK_TYPE=static
|
||||||
|
if [ "${PROJECT_IS_DARWIN}" == "0" ]; then
|
||||||
PROJECT_REQUIRE_ALPINE=ON
|
PROJECT_REQUIRE_ALPINE=ON
|
||||||
|
else
|
||||||
|
PROJECT_REQUIRE_ALPINE=OFF
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
PROJECT_BUILD_SHARED_LIBS=ON
|
PROJECT_BUILD_SHARED_LIBS=ON
|
||||||
PROJECT_LINK_TYPE=shared
|
PROJECT_LINK_TYPE=shared
|
||||||
@@ -186,6 +206,9 @@ PROJECT_DIST_DIR=${PROJECT_SOURCE_DIR}/dist/${PROJECT_CMAKE_BUILD_TYPE_LOWER}/${
|
|||||||
if [ "${PROJECT_IS_MINGW}" == "1" ]; then
|
if [ "${PROJECT_IS_MINGW}" == "1" ]; then
|
||||||
PROJECT_DIST_DIR=${PROJECT_DIST_DIR}/win32
|
PROJECT_DIST_DIR=${PROJECT_DIST_DIR}/win32
|
||||||
PROJECT_BUILD_DIR=${PROJECT_BUILD_DIR}/win32
|
PROJECT_BUILD_DIR=${PROJECT_BUILD_DIR}/win32
|
||||||
|
elif [ "${PROJECT_IS_DARWIN}" == "1" ]; then
|
||||||
|
PROJECT_DIST_DIR=${PROJECT_DIST_DIR}/darwin
|
||||||
|
PROJECT_BUILD_DIR=${PROJECT_BUILD_DIR}/darwin
|
||||||
else
|
else
|
||||||
PROJECT_DIST_DIR=${PROJECT_DIST_DIR}/linux
|
PROJECT_DIST_DIR=${PROJECT_DIST_DIR}/linux
|
||||||
PROJECT_BUILD_DIR=${PROJECT_BUILD_DIR}/linux
|
PROJECT_BUILD_DIR=${PROJECT_BUILD_DIR}/linux
|
||||||
@@ -220,12 +243,12 @@ if [ "${PROJECT_IS_MINGW}" == "1" ] && [ "${PROJECT_IS_MINGW_UNIX}" == "1" ]; th
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -f "${PROJECT_SOURCE_DIR}/cmake/versions.cmake" ]; then
|
if [ -f "${PROJECT_SOURCE_DIR}/cmake/versions.cmake" ]; then
|
||||||
VERSIONS=($(sed -e s/\ /=/g -e s/set\(//g -e s/\)//g "${PROJECT_SOURCE_DIR}/cmake/versions.cmake"))
|
VERSIONS=($(${SED} -e s/\ /=/g -e s/set\(//g -e s/\)//g "${PROJECT_SOURCE_DIR}/cmake/versions.cmake"))
|
||||||
|
|
||||||
PROJECT_MINGW64_DOCKER_BUILD_ARGS=()
|
PROJECT_MINGW64_DOCKER_BUILD_ARGS=()
|
||||||
|
|
||||||
for VERSION in "${VERSIONS[@]}"; do
|
for VERSION in "${VERSIONS[@]}"; do
|
||||||
LOOKUP_NAME=$(echo ${VERSION} | sed s/_VERSION.*// | sed s/GTEST/TESTING/g)
|
LOOKUP_NAME=$(echo ${VERSION} | ${SED} s/_VERSION.*// | sed s/GTEST/TESTING/g)
|
||||||
ENABLE_NAME=PROJECT_ENABLE_${LOOKUP_NAME}
|
ENABLE_NAME=PROJECT_ENABLE_${LOOKUP_NAME}
|
||||||
if [ "${!ENABLE_NAME}" != "OFF" ]; then
|
if [ "${!ENABLE_NAME}" != "OFF" ]; then
|
||||||
PROJECT_MINGW64_DOCKER_BUILD_ARGS+=("--build-arg ${VERSION}")
|
PROJECT_MINGW64_DOCKER_BUILD_ARGS+=("--build-arg ${VERSION}")
|
||||||
@@ -247,8 +270,11 @@ PROJECT_CMAKE_OPTS="-DPROJECT_EXTERNAL_BUILD_ROOT=${PROJECT_EXTERNAL_BUILD_ROOT}
|
|||||||
PROJECT_CMAKE_OPTS="-DPROJECT_GIT_REV=${PROJECT_GIT_REV} ${PROJECT_CMAKE_OPTS}"
|
PROJECT_CMAKE_OPTS="-DPROJECT_GIT_REV=${PROJECT_GIT_REV} ${PROJECT_CMAKE_OPTS}"
|
||||||
PROJECT_CMAKE_OPTS="-DPROJECT_IS_ALPINE=${PROJECT_IS_ALPINE} ${PROJECT_CMAKE_OPTS}"
|
PROJECT_CMAKE_OPTS="-DPROJECT_IS_ALPINE=${PROJECT_IS_ALPINE} ${PROJECT_CMAKE_OPTS}"
|
||||||
PROJECT_CMAKE_OPTS="-DPROJECT_IS_ARM64=${PROJECT_IS_ARM64} ${PROJECT_CMAKE_OPTS}"
|
PROJECT_CMAKE_OPTS="-DPROJECT_IS_ARM64=${PROJECT_IS_ARM64} ${PROJECT_CMAKE_OPTS}"
|
||||||
|
PROJECT_CMAKE_OPTS="-DPROJECT_IS_DARWIN=${PROJECT_IS_DARWIN} ${PROJECT_CMAKE_OPTS}"
|
||||||
PROJECT_CMAKE_OPTS="-DPROJECT_IS_MINGW=${PROJECT_IS_MINGW} ${PROJECT_CMAKE_OPTS}"
|
PROJECT_CMAKE_OPTS="-DPROJECT_IS_MINGW=${PROJECT_IS_MINGW} ${PROJECT_CMAKE_OPTS}"
|
||||||
PROJECT_CMAKE_OPTS="-DPROJECT_IS_MINGW_UNIX=${PROJECT_IS_MINGW_UNIX} ${PROJECT_CMAKE_OPTS}"
|
PROJECT_CMAKE_OPTS="-DPROJECT_IS_MINGW_UNIX=${PROJECT_IS_MINGW_UNIX} ${PROJECT_CMAKE_OPTS}"
|
||||||
|
PROJECT_CMAKE_OPTS="-DPROJECT_MACOS_BUNDLE_ID=${PROJECT_MACOS_BUNDLE_ID} ${PROJECT_CMAKE_OPTS}"
|
||||||
|
PROJECT_CMAKE_OPTS="-DPROJECT_MACOS_ICNS_NAME=${PROJECT_MACOS_ICNS_NAME} ${PROJECT_CMAKE_OPTS}"
|
||||||
PROJECT_CMAKE_OPTS="-DPROJECT_MAJOR_VERSION=${PROJECT_MAJOR_VERSION} ${PROJECT_CMAKE_OPTS}"
|
PROJECT_CMAKE_OPTS="-DPROJECT_MAJOR_VERSION=${PROJECT_MAJOR_VERSION} ${PROJECT_CMAKE_OPTS}"
|
||||||
PROJECT_CMAKE_OPTS="-DPROJECT_MINOR_VERSION=${PROJECT_MINOR_VERSION} ${PROJECT_CMAKE_OPTS}"
|
PROJECT_CMAKE_OPTS="-DPROJECT_MINOR_VERSION=${PROJECT_MINOR_VERSION} ${PROJECT_CMAKE_OPTS}"
|
||||||
PROJECT_CMAKE_OPTS="-DPROJECT_NAME=${PROJECT_NAME} ${PROJECT_CMAKE_OPTS}"
|
PROJECT_CMAKE_OPTS="-DPROJECT_NAME=${PROJECT_NAME} ${PROJECT_CMAKE_OPTS}"
|
||||||
@@ -277,6 +303,8 @@ PATH="${PROJECT_EXTERNAL_BUILD_ROOT}/bin:${PATH}"
|
|||||||
|
|
||||||
if [ "${PROJECT_IS_MINGW}" == "1" ]; then
|
if [ "${PROJECT_IS_MINGW}" == "1" ]; then
|
||||||
PROJECT_OS=windows
|
PROJECT_OS=windows
|
||||||
|
elif [ "${PROJECT_IS_DARWIN}" == "1" ]; then
|
||||||
|
PROJECT_OS=darwin
|
||||||
else
|
else
|
||||||
PROJECT_OS=linux
|
PROJECT_OS=linux
|
||||||
fi
|
fi
|
||||||
@@ -292,6 +320,8 @@ if [ "${PROJECT_IS_MINGW}" == "1" ] && [ "${PROJECT_IS_MINGW_UNIX}" != "1" ]; th
|
|||||||
MSYS=winsymlinks:nativestrict
|
MSYS=winsymlinks:nativestrict
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
PROJECT_ENABLE_INNOSETUP=1
|
||||||
|
|
||||||
export MSYS
|
export MSYS
|
||||||
export NUM_JOBS
|
export NUM_JOBS
|
||||||
export OPENSSL_ROOT_DIR
|
export OPENSSL_ROOT_DIR
|
||||||
@@ -319,9 +349,12 @@ export PROJECT_FLUTTER_BASE_HREF
|
|||||||
export PROJECT_GIT_REV
|
export PROJECT_GIT_REV
|
||||||
export PROJECT_IS_ALPINE
|
export PROJECT_IS_ALPINE
|
||||||
export PROJECT_IS_ARM64
|
export PROJECT_IS_ARM64
|
||||||
|
export PROJECT_IS_DARWIN
|
||||||
export PROJECT_IS_MINGW
|
export PROJECT_IS_MINGW
|
||||||
export PROJECT_IS_MINGW_UNIX
|
export PROJECT_IS_MINGW_UNIX
|
||||||
export PROJECT_LINK_TYPE
|
export PROJECT_LINK_TYPE
|
||||||
|
export PROJECT_MACOS_BUNDLE_ID
|
||||||
|
export PROJECT_MACOS_ICNS_NAME
|
||||||
export PROJECT_MAJOR_VERSION
|
export PROJECT_MAJOR_VERSION
|
||||||
export PROJECT_MINGW64_COPY_DEPENDENCIES
|
export PROJECT_MINGW64_COPY_DEPENDENCIES
|
||||||
export PROJECT_MINGW64_DOCKER_BUILD_ARGS
|
export PROJECT_MINGW64_DOCKER_BUILD_ARGS
|
||||||
@@ -371,6 +404,7 @@ echo " File part: ${PROJECT_FILE_PART}"
|
|||||||
echo " Flutter base href: ${PROJECT_FLUTTER_BASE_HREF}"
|
echo " Flutter base href: ${PROJECT_FLUTTER_BASE_HREF}"
|
||||||
echo " Is ARM64: ${PROJECT_IS_ARM64}"
|
echo " Is ARM64: ${PROJECT_IS_ARM64}"
|
||||||
echo " Is Alpine: ${PROJECT_IS_ALPINE}"
|
echo " Is Alpine: ${PROJECT_IS_ALPINE}"
|
||||||
|
echo " Is Darwin: ${PROJECT_IS_DARWIN}"
|
||||||
echo " Is MINGW on Unix: ${PROJECT_IS_MINGW_UNIX}"
|
echo " Is MINGW on Unix: ${PROJECT_IS_MINGW_UNIX}"
|
||||||
echo " Is MINGW: ${PROJECT_IS_MINGW}"
|
echo " Is MINGW: ${PROJECT_IS_MINGW}"
|
||||||
echo " Job count: ${NUM_JOBS}"
|
echo " Job count: ${NUM_JOBS}"
|
||||||
@@ -378,6 +412,10 @@ echo " Link type: ${PROJECT_LINK_TYPE}"
|
|||||||
if [ "${PROJECT_IS_MINGW}" == "1" ]; then
|
if [ "${PROJECT_IS_MINGW}" == "1" ]; then
|
||||||
echo " Long path names: ${PROJECT_ENABLE_WIN32_LONG_PATH_NAMES}"
|
echo " Long path names: ${PROJECT_ENABLE_WIN32_LONG_PATH_NAMES}"
|
||||||
fi
|
fi
|
||||||
|
if [ "${PROJECT_IS_DARWIN}" == "1" ]; then
|
||||||
|
echo " macOS bundle ID: ${PROJECT_MACOS_BUNDLE_ID}"
|
||||||
|
echo " macOS icns name: ${PROJECT_MACOS_ICNS_NAME}"
|
||||||
|
fi
|
||||||
echo " Meson toolchain file: ${PROJECT_TOOLCHAIN_FILE_MESON}"
|
echo " Meson toolchain file: ${PROJECT_TOOLCHAIN_FILE_MESON}"
|
||||||
if [ "${PROJECT_IS_MINGW}" == "1" ] && [ "${PROJECT_IS_MINGW_UNIX}" == "1" ]; then
|
if [ "${PROJECT_IS_MINGW}" == "1" ] && [ "${PROJECT_IS_MINGW_UNIX}" == "1" ]; then
|
||||||
echo " MinGW docker build args: ${PROJECT_MINGW64_DOCKER_BUILD_ARGS}"
|
echo " MinGW docker build args: ${PROJECT_MINGW64_DOCKER_BUILD_ARGS}"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
PROJECT_SCRIPTS_DIR=$(realpath "$0")
|
PROJECT_SCRIPTS_DIR=$(realpath "$0")
|
||||||
PROJECT_SCRIPTS_DIR=$(dirname "${PROJECT_SCRIPTS_DIR}")
|
PROJECT_SCRIPTS_DIR=$(dirname "${PROJECT_SCRIPTS_DIR}")
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
PROJECT_LIBRARIES=(
|
PROJECT_LIBRARIES=(
|
||||||
BACKWARD_CPP
|
BACKWARD_CPP
|
||||||
@@ -20,6 +20,7 @@ PROJECT_CLEANUP[EXPAT]="3rd_party/mingw64/expat-*"
|
|||||||
PROJECT_CLEANUP[GCC]="3rd_party/mingw64/gcc-*"
|
PROJECT_CLEANUP[GCC]="3rd_party/mingw64/gcc-*"
|
||||||
PROJECT_CLEANUP[ICU]="3rd_party/mingw64/icu-release-*"
|
PROJECT_CLEANUP[ICU]="3rd_party/mingw64/icu-release-*"
|
||||||
PROJECT_CLEANUP[JSON]="3rd_party/json-*"
|
PROJECT_CLEANUP[JSON]="3rd_party/json-*"
|
||||||
|
PROJECT_CLEANUP[INNOSETUP]="3rd_party/mingw64/innosetup-*"
|
||||||
PROJECT_CLEANUP[LIBBITCOIN_SYSTEM_ON]="3rd_party/boost_${PROJECT_VERSIONS[BOOST_MAJOR]}_${PROJECT_VERSIONS[BOOST_MINOR]}_*"
|
PROJECT_CLEANUP[LIBBITCOIN_SYSTEM_ON]="3rd_party/boost_${PROJECT_VERSIONS[BOOST_MAJOR]}_${PROJECT_VERSIONS[BOOST_MINOR]}_*"
|
||||||
PROJECT_CLEANUP[MINGW]="3rd_party/mingw64/mingw-w64-*"
|
PROJECT_CLEANUP[MINGW]="3rd_party/mingw64/mingw-w64-*"
|
||||||
PROJECT_CLEANUP[OPENSSL]="3rd_party/openssl-*"
|
PROJECT_CLEANUP[OPENSSL]="3rd_party/openssl-*"
|
||||||
@@ -36,10 +37,11 @@ PROJECT_DOWNLOADS[BOOST2]="https://archives.boost.io/release/${PROJECT_VERSIONS[
|
|||||||
PROJECT_DOWNLOADS[CPP_HTTPLIB]="https://github.com/yhirose/cpp-httplib/archive/refs/tags/v${PROJECT_VERSIONS[CPP_HTTPLIB]}.tar.gz;cpp-httplib-${PROJECT_VERSIONS[CPP_HTTPLIB]}.tar.gz;3rd_party"
|
PROJECT_DOWNLOADS[CPP_HTTPLIB]="https://github.com/yhirose/cpp-httplib/archive/refs/tags/v${PROJECT_VERSIONS[CPP_HTTPLIB]}.tar.gz;cpp-httplib-${PROJECT_VERSIONS[CPP_HTTPLIB]}.tar.gz;3rd_party"
|
||||||
PROJECT_DOWNLOADS[CURL]="https://github.com/curl/curl/archive/refs/tags/curl-${PROJECT_VERSIONS[CURL2]}.tar.gz;curl-${PROJECT_VERSIONS[CURL]}.tar.gz;3rd_party"
|
PROJECT_DOWNLOADS[CURL]="https://github.com/curl/curl/archive/refs/tags/curl-${PROJECT_VERSIONS[CURL2]}.tar.gz;curl-${PROJECT_VERSIONS[CURL]}.tar.gz;3rd_party"
|
||||||
PROJECT_DOWNLOADS[EXPAT]="https://github.com/libexpat/libexpat/archive/refs/tags/R_${PROJECT_VERSIONS[EXPAT2]}.tar.gz;expat-${PROJECT_VERSIONS[EXPAT]}.tar.gz;3rd_party/mingw64"
|
PROJECT_DOWNLOADS[EXPAT]="https://github.com/libexpat/libexpat/archive/refs/tags/R_${PROJECT_VERSIONS[EXPAT2]}.tar.gz;expat-${PROJECT_VERSIONS[EXPAT]}.tar.gz;3rd_party/mingw64"
|
||||||
PROJECT_DOWNLOADS[GCC]="https://ftp.gnu.org/gnu/gcc/gcc-${PROJECT_VERSIONS[GCC]}/gcc-${PROJECT_VERSIONS[GCC]}.tar.gz;gcc-${PROJECT_VERSIONS[GCC]}.tar.gz;3rd_party/mingw64"
|
PROJECT_DOWNLOADS[GCC]="https://mirrorservice.org/sites/sourceware.org/pub/gcc/releases/gcc-${PROJECT_VERSIONS[GCC]}/gcc-${PROJECT_VERSIONS[GCC]}.tar.gz;gcc-${PROJECT_VERSIONS[GCC]}.tar.gz;3rd_party/mingw64"
|
||||||
PROJECT_DOWNLOADS[GTEST]="https://github.com/google/googletest/archive/refs/tags/v${PROJECT_VERSIONS[GTEST]}.tar.gz;googletest-${PROJECT_VERSIONS[GTEST]}.tar.gz;3rd_party"
|
PROJECT_DOWNLOADS[GTEST]="https://github.com/google/googletest/archive/refs/tags/v${PROJECT_VERSIONS[GTEST]}.tar.gz;googletest-${PROJECT_VERSIONS[GTEST]}.tar.gz;3rd_party"
|
||||||
PROJECT_DOWNLOADS[ICU]="https://github.com/unicode-org/icu/archive/refs/tags/release-${PROJECT_VERSIONS[ICU]}.tar.gz;icu-release-${PROJECT_VERSIONS[ICU]}.tar.gz;3rd_party/mingw64"
|
PROJECT_DOWNLOADS[ICU]="https://github.com/unicode-org/icu/archive/refs/tags/release-${PROJECT_VERSIONS[ICU]}.tar.gz;icu-release-${PROJECT_VERSIONS[ICU]}.tar.gz;3rd_party/mingw64"
|
||||||
PROJECT_DOWNLOADS[JSON]="https://github.com/nlohmann/json/archive/refs/tags/v${PROJECT_VERSIONS[JSON]}.tar.gz;json-${PROJECT_VERSIONS[JSON]}.tar.gz;3rd_party"
|
PROJECT_DOWNLOADS[JSON]="https://github.com/nlohmann/json/archive/refs/tags/v${PROJECT_VERSIONS[JSON]}.tar.gz;json-${PROJECT_VERSIONS[JSON]}.tar.gz;3rd_party"
|
||||||
|
PROJECT_DOWNLOADS[INNOSETUP]="https://files.jrsoftware.org/is/6/innosetup-${PROJECT_VERSIONS[INNOSETUP]}.exe;innosetup-${PROJECT_VERSIONS[INNOSETUP]}.exe;3rd_party/mingw64"
|
||||||
PROJECT_DOWNLOADS[MINGW]="https://sourceforge.net/projects/mingw-w64/files/mingw-w64/mingw-w64-release/mingw-w64-v${PROJECT_VERSIONS[MINGW]}.tar.bz2;;mingw-w64-v${PROJECT_VERSIONS[MINGW]}.tar.bz2;3rd_party/mingw64"
|
PROJECT_DOWNLOADS[MINGW]="https://sourceforge.net/projects/mingw-w64/files/mingw-w64/mingw-w64-release/mingw-w64-v${PROJECT_VERSIONS[MINGW]}.tar.bz2;;mingw-w64-v${PROJECT_VERSIONS[MINGW]}.tar.bz2;3rd_party/mingw64"
|
||||||
PROJECT_DOWNLOADS[OPENSSL]="https://github.com/openssl/openssl/releases/download/openssl-${PROJECT_VERSIONS[OPENSSL]}/openssl-${PROJECT_VERSIONS[OPENSSL]}.tar.gz;openssl-${PROJECT_VERSIONS[OPENSSL]}.tar.gz;3rd_party"
|
PROJECT_DOWNLOADS[OPENSSL]="https://github.com/openssl/openssl/releases/download/openssl-${PROJECT_VERSIONS[OPENSSL]}/openssl-${PROJECT_VERSIONS[OPENSSL]}.tar.gz;openssl-${PROJECT_VERSIONS[OPENSSL]}.tar.gz;3rd_party"
|
||||||
PROJECT_DOWNLOADS[PKG_CONFIG]="https://pkgconfig.freedesktop.org/releases/pkg-config-${PROJECT_VERSIONS[PKG_CONFIG]}.tar.gz;pkg-config-${PROJECT_VERSIONS[PKG_CONFIG]}.tar.gz;3rd_party/mingw64"
|
PROJECT_DOWNLOADS[PKG_CONFIG]="https://pkgconfig.freedesktop.org/releases/pkg-config-${PROJECT_VERSIONS[PKG_CONFIG]}.tar.gz;pkg-config-${PROJECT_VERSIONS[PKG_CONFIG]}.tar.gz;3rd_party/mingw64"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
PROJECT_SCRIPTS_DIR=$(realpath "$0")
|
PROJECT_SCRIPTS_DIR=$(realpath "$0")
|
||||||
PROJECT_SCRIPTS_DIR=$(dirname "${PROJECT_SCRIPTS_DIR}")
|
PROJECT_SCRIPTS_DIR=$(dirname "${PROJECT_SCRIPTS_DIR}")
|
||||||
@@ -43,8 +43,8 @@ make -j${CMAKE_BUILD_PARALLEL_LEVEL} || exit 1
|
|||||||
popd
|
popd
|
||||||
popd
|
popd
|
||||||
|
|
||||||
if [ "${PROJECT_IS_MINGW}" != "1" ] && [ "${PROJECT_REQUIRE_ALPINE}" == "ON" ]; then
|
if [ -f "${PROJECT_SOURCE_DIR}/LICENSE.md" ]; then
|
||||||
rsync -av --progress /usr/share/icu/74.2/ "${PROJECT_DIST_DIR}/icu/"
|
rsync -av --progress "${PROJECT_SOURCE_DIR}/LICENSE.md" "${PROJECT_DIST_DIR}/"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "${PROJECT_BUILD_SHARED_LIBS}" == "ON" ] && [ "${PROJECT_IS_MINGW}" != "1" ]; then
|
if [ "${PROJECT_BUILD_SHARED_LIBS}" == "ON" ] && [ "${PROJECT_IS_MINGW}" != "1" ]; then
|
||||||
@@ -57,12 +57,26 @@ fi
|
|||||||
|
|
||||||
for APP in ${PROJECT_APP_LIST[@]}; do
|
for APP in ${PROJECT_APP_LIST[@]}; do
|
||||||
if [ "${PROJECT_BUILD_SHARED_LIBS}" == "ON" ]; then
|
if [ "${PROJECT_BUILD_SHARED_LIBS}" == "ON" ]; then
|
||||||
if [ "${PROJECT_IS_MINGW}" != "1" ]; then
|
if [ "${PROJECT_IS_MINGW}" == "1" ]; then
|
||||||
|
rsync -av --progress "${PROJECT_BUILD_DIR}/build/${APP}${PROJECT_APP_BINARY_EXT}" "${PROJECT_DIST_DIR}/"
|
||||||
|
else
|
||||||
rm "${PROJECT_DIST_DIR}/${APP}${PROJECT_APP_BINARY_EXT}"
|
rm "${PROJECT_DIST_DIR}/${APP}${PROJECT_APP_BINARY_EXT}"
|
||||||
if [ "${PROJECT_ENABLE_CURL}" == "ON" ]; then
|
if [ "${PROJECT_ENABLE_CURL}" == "ON" ]; then
|
||||||
mv "${PROJECT_DIST_DIR}/cacert.pem" "${PROJECT_DIST_DIR}/bin/cacert.pem"
|
mv "${PROJECT_DIST_DIR}/cacert.pem" "${PROJECT_DIST_DIR}/bin/cacert.pem"
|
||||||
fi
|
fi
|
||||||
rsync -av --progress "${PROJECT_BUILD_DIR}/build/${APP}${PROJECT_APP_BINARY_EXT}" "${PROJECT_DIST_DIR}/bin/"
|
rsync -av --progress "${PROJECT_BUILD_DIR}/build/${APP}${PROJECT_APP_BINARY_EXT}" "${PROJECT_DIST_DIR}/bin/"
|
||||||
|
if [ "${PROJECT_IS_DARWIN}" == "1" ]; then
|
||||||
|
cat <<EOF >>"${PROJECT_DIST_DIR}/${APP}${PROJECT_APP_BINARY_EXT}"
|
||||||
|
#!/bin/sh
|
||||||
|
PROJECT_SCRIPTS_DIR=\$(realpath "\$0")
|
||||||
|
PROJECT_SCRIPTS_DIR=\$(dirname "\${PROJECT_SCRIPTS_DIR}")
|
||||||
|
|
||||||
|
DYLD_LIBRARY_PATH="\${PROJECT_SCRIPTS_DIR}/lib:\${PROJECT_SCRIPTS_DIR}/lib64:\${DYLD_LIBRARY_PATH}"
|
||||||
|
export DYLD_LIBRARY_PATH
|
||||||
|
|
||||||
|
\${PROJECT_SCRIPTS_DIR}/bin/${APP}${PROJECT_APP_BINARY_EXT} \$*
|
||||||
|
EOF
|
||||||
|
else
|
||||||
cat <<EOF >>"${PROJECT_DIST_DIR}/${APP}${PROJECT_APP_BINARY_EXT}"
|
cat <<EOF >>"${PROJECT_DIST_DIR}/${APP}${PROJECT_APP_BINARY_EXT}"
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
PROJECT_SCRIPTS_DIR=\$(realpath "\$0")
|
PROJECT_SCRIPTS_DIR=\$(realpath "\$0")
|
||||||
@@ -72,18 +86,28 @@ export LD_LIBRARY_PATH="\${PROJECT_SCRIPTS_DIR}/lib:\${PROJECT_SCRIPTS_DIR}/lib6
|
|||||||
|
|
||||||
\${PROJECT_SCRIPTS_DIR}/bin/${APP}${PROJECT_APP_BINARY_EXT} \$*
|
\${PROJECT_SCRIPTS_DIR}/bin/${APP}${PROJECT_APP_BINARY_EXT} \$*
|
||||||
EOF
|
EOF
|
||||||
chmod +x "${PROJECT_DIST_DIR}/${APP}${PROJECT_APP_BINARY_EXT}"
|
|
||||||
else
|
|
||||||
rsync -av --progress "${PROJECT_BUILD_DIR}/build/${APP}${PROJECT_APP_BINARY_EXT}" "${PROJECT_DIST_DIR}/"
|
|
||||||
fi
|
fi
|
||||||
else
|
chmod +x "${PROJECT_DIST_DIR}/${APP}${PROJECT_APP_BINARY_EXT}"
|
||||||
|
fi
|
||||||
|
elif [ ! -d "${PROJECT_BUILD_DIR}/build/${APP}.app" ]; then
|
||||||
rsync -av --progress "${PROJECT_BUILD_DIR}/build/${APP}${PROJECT_APP_BINARY_EXT}" "${PROJECT_DIST_DIR}/"
|
rsync -av --progress "${PROJECT_BUILD_DIR}/build/${APP}${PROJECT_APP_BINARY_EXT}" "${PROJECT_DIST_DIR}/"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
if [ -d "${PROJECT_BUILD_DIR}/build/${PROJECT_NAME}.app" ]; then
|
||||||
|
rsync -av --progress "${PROJECT_BUILD_DIR}/build/${PROJECT_NAME}.app/" \
|
||||||
|
"${PROJECT_DIST_DIR}/${PROJECT_NAME}.app/"
|
||||||
|
fi
|
||||||
|
|
||||||
if [ -f "${PROJECT_SOURCE_DIR}/web/${PROJECT_NAME}/pubspec.yaml" ]; then
|
if [ -f "${PROJECT_SOURCE_DIR}/web/${PROJECT_NAME}/pubspec.yaml" ]; then
|
||||||
|
if [ -d "${PROJECT_DIST_DIR}/${PROJECT_NAME}.app" ]; then
|
||||||
|
rsync -av --progress "${PROJECT_SOURCE_DIR}/web/${PROJECT_NAME}/build/web/" \
|
||||||
|
"${PROJECT_DIST_DIR}/${PROJECT_NAME}.app/Contents/Resources/web/"
|
||||||
|
cp "${PROJECT_DIST_DIR}/cacert.pem" "${PROJECT_DIST_DIR}/${PROJECT_NAME}.app/Contents/MacOS/cacert.pem"
|
||||||
|
else
|
||||||
rsync -av --progress "${PROJECT_SOURCE_DIR}/web/${PROJECT_NAME}/build/web/" \
|
rsync -av --progress "${PROJECT_SOURCE_DIR}/web/${PROJECT_NAME}/build/web/" \
|
||||||
"${PROJECT_DIST_DIR}/web/"
|
"${PROJECT_DIST_DIR}/web/"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "${PROJECT_IS_MINGW}" == "1" ]; then
|
if [ "${PROJECT_IS_MINGW}" == "1" ]; then
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
PROJECT_SCRIPTS_DIR=$(realpath "$0")
|
PROJECT_SCRIPTS_DIR=$(realpath "$0")
|
||||||
PROJECT_SCRIPTS_DIR=$(dirname "${PROJECT_SCRIPTS_DIR}")
|
PROJECT_SCRIPTS_DIR=$(dirname "${PROJECT_SCRIPTS_DIR}")
|
||||||
. "${PROJECT_SCRIPTS_DIR}/env.sh" "$1" "$2" "$3" "$4" "$5"
|
. "${PROJECT_SCRIPTS_DIR}/env.sh" "$1" "$2" "$3" "$4" "$5"
|
||||||
|
|
||||||
if [ -f "${PROJECT_SOURCE_DIR}/web/${PROJECT_NAME}/pubspec.yaml" ]; then
|
if [ -f "${PROJECT_SOURCE_DIR}/web/${PROJECT_NAME}/pubspec.yaml" ]; then
|
||||||
if [ "${PROJECT_IS_MINGW}" == "0" ] || [ "${PROJECT_IS_MINGW_UNIX}" == "1" ]; then
|
if [[ "${PROJECT_IS_DARWIN}" == "0" && ("${PROJECT_IS_MINGW}" == "0" || "${PROJECT_IS_MINGW_UNIX}" == "1") ]]; then
|
||||||
FLUTTER_CONTAINER_NAME="${PROJECT_NAME}_flutter"
|
FLUTTER_CONTAINER_NAME="${PROJECT_NAME}_flutter"
|
||||||
FLUTTER_TAG_NAME="${PROJECT_NAME}:flutter"
|
FLUTTER_TAG_NAME="${PROJECT_NAME}:flutter"
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
TEMP_DIR=$(mktemp -d)
|
TEMP_DIR=$(mktemp -d)
|
||||||
|
|
||||||
@@ -12,6 +12,24 @@ function error_exit() {
|
|||||||
exit $2
|
exit $2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function cleanup_packages() {
|
||||||
|
local SOURCE_FILE=$1
|
||||||
|
|
||||||
|
pushd "${PROJECT_DIST_DIR}"
|
||||||
|
if [ -f "${SOURCE_FILE}" ]; then
|
||||||
|
rm -f "${SOURCE_FILE}" || error_exit "failed to delete file: ${SOURCE_FILE}" 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "${SOURCE_FILE}.sha256" ]; then
|
||||||
|
rm -f "${SOURCE_FILE}.sha256" || error_exit "failed to delete file: ${SOURCE_FILE}.sha256" 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "${SOURCE_FILE}.sig" ]; then
|
||||||
|
rm -f "${SOURCE_FILE}.sig" || error_exit "failed to delete file: ${SOURCE_FILE}.sig" 1
|
||||||
|
fi
|
||||||
|
popd
|
||||||
|
}
|
||||||
|
|
||||||
function create_file_validations() {
|
function create_file_validations() {
|
||||||
local SOURCE_FILE=$1
|
local SOURCE_FILE=$1
|
||||||
sha256sum ${SOURCE_FILE} >${SOURCE_FILE}.sha256 || error_exit "failed to create sha256 for file: ${SOURCE_FILE}" 1
|
sha256sum ${SOURCE_FILE} >${SOURCE_FILE}.sha256 || error_exit "failed to create sha256 for file: ${SOURCE_FILE}" 1
|
||||||
@@ -25,32 +43,26 @@ if [ ! -d "${PROJECT_DIST_DIR}" ]; then
|
|||||||
error_exit "dist directory not found: ${PROJECT_DIST_DIR}" 2
|
error_exit "dist directory not found: ${PROJECT_DIST_DIR}" 2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
pushd "${PROJECT_DIST_DIR}"
|
cleanup_packages "${PROJECT_OUT_FILE}"
|
||||||
if [ -f "${PROJECT_OUT_FILE}" ]; then
|
cleanup_packages "${PROJECT_FILE_PART}_setup.exe"
|
||||||
rm -f "${PROJECT_OUT_FILE}" || error_exit "failed to delete file: ${PROJECT_OUT_FILE}" 1
|
cleanup_packages "${PROJECT_FILE_PART}.dmg"
|
||||||
fi
|
|
||||||
if [ -f "${PROJECT_OUT_FILE}.sha256" ]; then
|
|
||||||
rm -f "${PROJECT_OUT_FILE}.sha256" || error_exit "failed to delete file: ${PROJECT_OUT_FILE}.sha256" 1
|
|
||||||
fi
|
|
||||||
if [ -f "${PROJECT_OUT_FILE}.sig" ]; then
|
|
||||||
rm -f "${PROJECT_OUT_FILE}.sig" || error_exit "failed to delete file: ${PROJECT_OUT_FILE}.sig" 1
|
|
||||||
fi
|
|
||||||
popd
|
|
||||||
|
|
||||||
rsync -av --progress ${PROJECT_DIST_DIR}/ ${TEMP_DIR}/${PROJECT_NAME}/ || error_exit "failed to rsync" 1
|
rsync -av --progress ${PROJECT_DIST_DIR}/ ${TEMP_DIR}/${PROJECT_NAME}/ || error_exit "failed to rsync" 1
|
||||||
|
|
||||||
for APP in ${PROJECT_APP_LIST[@]}; do
|
for APP in ${PROJECT_APP_LIST[@]}; do
|
||||||
if [ "${PROJECT_BUILD_SHARED_LIBS}" == "ON" ] && [ "${PROJECT_IS_MINGW}" != "1" ]; then
|
if [ -d "${TEMP_DIR}/${PROJECT_NAME}/${APP}.app" ]; then
|
||||||
strip ${TEMP_DIR}/${PROJECT_NAME}/bin/${APP}${PROJECT_APP_BINARY_EXT}
|
strip "${TEMP_DIR}/${PROJECT_NAME}/${APP}.app/Contents/MacOS/${APP}${PROJECT_APP_BINARY_EXT}"
|
||||||
|
elif [ "${PROJECT_BUILD_SHARED_LIBS}" == "ON" ] && [ "${PROJECT_IS_MINGW}" != "1" ]; then
|
||||||
|
strip "${TEMP_DIR}/${PROJECT_NAME}/bin/${APP}${PROJECT_APP_BINARY_EXT}"
|
||||||
else
|
else
|
||||||
strip ${TEMP_DIR}/${PROJECT_NAME}/${APP}${PROJECT_APP_BINARY_EXT}
|
strip "${TEMP_DIR}/${PROJECT_NAME}/${APP}${PROJECT_APP_BINARY_EXT}"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
pushd "${TEMP_DIR}/${PROJECT_NAME}/"
|
pushd "${TEMP_DIR}/${PROJECT_NAME}/"
|
||||||
IFS=$'\n'
|
IFS=$'\n'
|
||||||
set -f
|
set -f
|
||||||
FILE_LIST=$(find . -type f)
|
FILE_LIST=$(find . -type f -not -path "*/.app/*")
|
||||||
for FILE in ${FILE_LIST}; do
|
for FILE in ${FILE_LIST}; do
|
||||||
create_file_validations "${FILE}"
|
create_file_validations "${FILE}"
|
||||||
done
|
done
|
||||||
@@ -63,4 +75,79 @@ tar cvzf "${PROJECT_OUT_FILE}" -C ${TEMP_DIR} . || error_exit "failed to create
|
|||||||
create_file_validations "${PROJECT_OUT_FILE}"
|
create_file_validations "${PROJECT_OUT_FILE}"
|
||||||
popd
|
popd
|
||||||
|
|
||||||
|
if [ -d "${TEMP_DIR}/${PROJECT_NAME}/${PROJECT_NAME}.app" ]; then
|
||||||
|
APP_SRC="${TEMP_DIR}/${PROJECT_NAME}/${PROJECT_NAME}.app"
|
||||||
|
|
||||||
|
DMG_ROOT="${TEMP_DIR}/dmgroot"
|
||||||
|
mkdir -p "${DMG_ROOT}" || error_exit "failed to create dmgroot" 1
|
||||||
|
|
||||||
|
INSTALLER="${DMG_ROOT}/Install ${PROJECT_NAME}.command"
|
||||||
|
INSTALLER_SRC="${PROJECT_SOURCE_DIR}/${PROJECT_NAME}/Install ${PROJECT_NAME}.command"
|
||||||
|
|
||||||
|
if [ -f "${INSTALLER_SRC}" ]; then
|
||||||
|
HIDDEN_DIR="${DMG_ROOT}/.payload"
|
||||||
|
mkdir -p "${HIDDEN_DIR}" || error_exit "failed to create payload dir" 1
|
||||||
|
APP_DEST_DIR="${HIDDEN_DIR}"
|
||||||
|
else
|
||||||
|
APP_DEST_DIR="${DMG_ROOT}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
rsync -a "${APP_SRC}" "${APP_DEST_DIR}/" || error_exit "failed to stage app bundle" 1
|
||||||
|
|
||||||
|
if [ -f "${INSTALLER_SRC}" ]; then
|
||||||
|
chflags hidden "${HIDDEN_DIR}" "${HIDDEN_DIR}/${PROJECT_NAME}.app" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
ln -s /Applications "${DMG_ROOT}/Applications" 2>/dev/null || true
|
||||||
|
|
||||||
|
if [ -f "${INSTALLER_SRC}" ]; then
|
||||||
|
cp -f "${INSTALLER_SRC}" "${INSTALLER}" || error_exit "failed to copy install command" 1
|
||||||
|
chmod +x "${INSTALLER}" || error_exit "failed to chmod install command" 1
|
||||||
|
|
||||||
|
SAFE_PREFIX="$(printf '%s' "${PROJECT_MACOS_BUNDLE_ID}" | sed -e 's/[\/&]/\\&/g')"
|
||||||
|
/usr/bin/sed -i '' -e "s|^LABEL_PREFIX=.*$|LABEL_PREFIX=\"${SAFE_PREFIX}\"|g" "${INSTALLER}"
|
||||||
|
|
||||||
|
LABEL_ASSIGNED="$(/usr/bin/awk -F= '/^LABEL_PREFIX=/{sub(/^[^=]*=/,""); gsub(/^"|"$/,""); print; exit}' "${INSTALLER}")"
|
||||||
|
if ! /usr/bin/awk -v v="${LABEL_ASSIGNED}" '
|
||||||
|
BEGIN {
|
||||||
|
if (length(v) == 0) exit 1;
|
||||||
|
if (v == "__LABEL_PREFIX__") exit 1;
|
||||||
|
if (v !~ /^[A-Za-z0-9._-]+$/) exit 1;
|
||||||
|
if (v !~ /\./) exit 1;
|
||||||
|
exit 0;
|
||||||
|
}'; then
|
||||||
|
error_exit "DMG build abort: invalid LABEL_PREFIX written to installer (value: \"${LABEL_ASSIGNED}\"). Check PROJECT_MACOS_BUNDLE_ID and sed substitution." 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
DMG_OUT="${PROJECT_FILE_PART}.dmg"
|
||||||
|
hdiutil create \
|
||||||
|
-volname "${PROJECT_NAME}" \
|
||||||
|
-fs HFS+ \
|
||||||
|
-srcfolder "${DMG_ROOT}" \
|
||||||
|
-ov -format UDZO \
|
||||||
|
"${PROJECT_DIST_DIR}/${DMG_OUT}" || error_exit "hdiutil failed" 1
|
||||||
|
|
||||||
|
pushd "${PROJECT_DIST_DIR}"
|
||||||
|
create_file_validations "${DMG_OUT}"
|
||||||
|
popd
|
||||||
|
elif [ "${PROJECT_IS_MINGW}" == "1" ] && [ -f "${PROJECT_DIST_DIR}/../${PROJECT_NAME}.iss" ]; then
|
||||||
|
cp -f "${PROJECT_DIST_DIR}/../${PROJECT_NAME}.iss" "${TEMP_DIR}/${PROJECT_NAME}.iss"
|
||||||
|
rsync -av --progress --delete ${PROJECT_SOURCE_DIR}/support/3rd_party/*.msi ${TEMP_DIR}/3rd_party/
|
||||||
|
|
||||||
|
pushd "${TEMP_DIR}"
|
||||||
|
if [ "${PROJECT_IS_MINGW_UNIX}" == "1" ]; then
|
||||||
|
wine64 "c:/Program Files (x86)/Inno Setup 6/iscc.exe" "${PROJECT_NAME}.iss" || exit 1
|
||||||
|
else
|
||||||
|
iscc "${PROJECT_NAME}.iss" || exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
pushd "Output"
|
||||||
|
create_file_validations "${PROJECT_FILE_PART}_setup.exe"
|
||||||
|
cp -f * "${PROJECT_DIST_DIR}/"
|
||||||
|
popd
|
||||||
|
|
||||||
|
popd
|
||||||
|
fi
|
||||||
|
|
||||||
error_exit "created package ${PROJECT_FILE_PART}" 0
|
error_exit "created package ${PROJECT_FILE_PART}" 0
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
PROJECT_SCRIPTS_DIR=$(realpath "$0")
|
PROJECT_SCRIPTS_DIR=$(realpath "$0")
|
||||||
PROJECT_SCRIPTS_DIR=$(dirname "${PROJECT_SCRIPTS_DIR}")
|
PROJECT_SCRIPTS_DIR=$(dirname "${PROJECT_SCRIPTS_DIR}")
|
||||||
@@ -11,7 +11,7 @@ fi
|
|||||||
|
|
||||||
"${PROJECT_SOURCE_DIR}/scripts/make_flutter.sh" "${PROJECT_BUILD_ARCH}" "${PROJECT_CMAKE_BUILD_TYPE}" "${PROJECT_BUILD_CLEAN}" 0 0 || exit 1
|
"${PROJECT_SOURCE_DIR}/scripts/make_flutter.sh" "${PROJECT_BUILD_ARCH}" "${PROJECT_CMAKE_BUILD_TYPE}" "${PROJECT_BUILD_CLEAN}" 0 0 || exit 1
|
||||||
|
|
||||||
if [ "${PROJECT_REQUIRE_ALPINE}" == "ON" ] || [ "${PROJECT_IS_ARM64}" == "1" ]; then
|
if [[ "${PROJECT_IS_DARWIN}" == "0" && ("${PROJECT_REQUIRE_ALPINE}" == "ON" || "${PROJECT_IS_ARM64}" == "1") ]]; then
|
||||||
DOCKER_NAME=alpine
|
DOCKER_NAME=alpine
|
||||||
DOCKER_CONTAINER=${PROJECT_NAME}_${DOCKER_NAME}_${PROJECT_BUILD_ARCH}
|
DOCKER_CONTAINER=${PROJECT_NAME}_${DOCKER_NAME}_${PROJECT_BUILD_ARCH}
|
||||||
DOCKER_TAG=${PROJECT_NAME}:${DOCKER_NAME}
|
DOCKER_TAG=${PROJECT_NAME}:${DOCKER_NAME}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
PROJECT_SCRIPTS_DIR=$(realpath "$0")
|
PROJECT_SCRIPTS_DIR=$(realpath "$0")
|
||||||
PROJECT_SCRIPTS_DIR=$(dirname "${PROJECT_SCRIPTS_DIR}")
|
PROJECT_SCRIPTS_DIR=$(dirname "${PROJECT_SCRIPTS_DIR}")
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
DOCKER_NAME=$1
|
DOCKER_NAME=$1
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
PROJECT_SCRIPTS_DIR=$(realpath "$0")
|
PROJECT_SCRIPTS_DIR=$(realpath "$0")
|
||||||
PROJECT_SCRIPTS_DIR=$(dirname "${PROJECT_SCRIPTS_DIR}")
|
PROJECT_SCRIPTS_DIR=$(dirname "${PROJECT_SCRIPTS_DIR}")
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
PROJECT_MSYS2_PACKAGE_LIST=()
|
PROJECT_MSYS2_PACKAGE_LIST=()
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
declare -A PROJECT_VERSIONS
|
declare -A PROJECT_VERSIONS
|
||||||
PROJECT_VERSIONS[BINUTILS]="2.44"
|
PROJECT_VERSIONS[BINUTILS]="2.44"
|
||||||
@@ -6,22 +6,22 @@ PROJECT_VERSIONS[BOOST2_MAJOR]="1"
|
|||||||
PROJECT_VERSIONS[BOOST2_MINOR]="76"
|
PROJECT_VERSIONS[BOOST2_MINOR]="76"
|
||||||
PROJECT_VERSIONS[BOOST2_PATCH]="0"
|
PROJECT_VERSIONS[BOOST2_PATCH]="0"
|
||||||
PROJECT_VERSIONS[BOOST_MAJOR]="1"
|
PROJECT_VERSIONS[BOOST_MAJOR]="1"
|
||||||
PROJECT_VERSIONS[BOOST_MINOR]="88"
|
PROJECT_VERSIONS[BOOST_MINOR]="89"
|
||||||
PROJECT_VERSIONS[BOOST_PATCH]="0"
|
PROJECT_VERSIONS[BOOST_PATCH]="0"
|
||||||
PROJECT_VERSIONS[CPP_HTTPLIB]="0.20.0"
|
PROJECT_VERSIONS[CPP_HTTPLIB]="0.26.0"
|
||||||
PROJECT_VERSIONS[CURL]="8.13.0"
|
PROJECT_VERSIONS[CURL]="8.16.0"
|
||||||
PROJECT_VERSIONS[CURL2]="8_13_0"
|
PROJECT_VERSIONS[CURL2]="8_16_0"
|
||||||
PROJECT_VERSIONS[EXPAT]="2.7.1"
|
PROJECT_VERSIONS[EXPAT]="2.7.1"
|
||||||
PROJECT_VERSIONS[EXPAT2]="2_7_1"
|
PROJECT_VERSIONS[EXPAT2]="2_7_1"
|
||||||
PROJECT_VERSIONS[GCC]="14.2.0"
|
PROJECT_VERSIONS[GCC]="15.2.0"
|
||||||
PROJECT_VERSIONS[GTEST]="1.16.0"
|
PROJECT_VERSIONS[GTEST]="1.17.0"
|
||||||
PROJECT_VERSIONS[ICU]="76-1"
|
PROJECT_VERSIONS[ICU]="76-1"
|
||||||
|
PROJECT_VERSIONS[INNOSETUP]="6.5.4"
|
||||||
PROJECT_VERSIONS[JSON]="3.12.0"
|
PROJECT_VERSIONS[JSON]="3.12.0"
|
||||||
PROJECT_VERSIONS[MESA]="23.3.3"
|
PROJECT_VERSIONS[MINGW]="13.0.0"
|
||||||
PROJECT_VERSIONS[MINGW]="12.0.0"
|
PROJECT_VERSIONS[OPENSSL]="3.6.0"
|
||||||
PROJECT_VERSIONS[OPENSSL]="3.5.0"
|
|
||||||
PROJECT_VERSIONS[PKG_CONFIG]="0.29.2"
|
PROJECT_VERSIONS[PKG_CONFIG]="0.29.2"
|
||||||
PROJECT_VERSIONS[ROCKSDB]="10.0.1"
|
PROJECT_VERSIONS[ROCKSDB]="10.5.1"
|
||||||
PROJECT_VERSIONS[SPDLOG]="1.15.2"
|
PROJECT_VERSIONS[SPDLOG]="1.15.3"
|
||||||
PROJECT_VERSIONS[ZLIB]="1.3.1"
|
PROJECT_VERSIONS[ZLIB]="1.3.1"
|
||||||
export PROJECT_VERSIONS
|
export PROJECT_VERSIONS
|
||||||
|
|||||||
BIN
support/3rd_party/cpp-httplib-0.20.0.tar.gz
LFS
vendored
BIN
support/3rd_party/cpp-httplib-0.20.0.tar.gz
LFS
vendored
Binary file not shown.
@@ -1 +0,0 @@
|
|||||||
18064587e0cc6a0d5d56d619f4cbbcaba47aa5d84d86013abbd45d95c6653866 cpp-httplib-0.20.0.tar.gz
|
|
||||||
BIN
support/3rd_party/cpp-httplib-0.26.0.tar.gz
LFS
vendored
Normal file
BIN
support/3rd_party/cpp-httplib-0.26.0.tar.gz
LFS
vendored
Normal file
Binary file not shown.
1
support/3rd_party/cpp-httplib-0.26.0.tar.gz.sha256
vendored
Normal file
1
support/3rd_party/cpp-httplib-0.26.0.tar.gz.sha256
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
a66f908f50ccb119769adce44fe1eac75f81b6ffab7c4ac0211bb663ffeb2688 cpp-httplib-0.26.0.tar.gz
|
||||||
BIN
support/3rd_party/curl-8.13.0.tar.gz
LFS
vendored
BIN
support/3rd_party/curl-8.13.0.tar.gz
LFS
vendored
Binary file not shown.
1
support/3rd_party/curl-8.13.0.tar.gz.sha256
vendored
1
support/3rd_party/curl-8.13.0.tar.gz.sha256
vendored
@@ -1 +0,0 @@
|
|||||||
ccc5ba45d9f5320c70ffb24e5411b66ba55ea1f333bf78be0963ed90a9328699 curl-8.13.0.tar.gz
|
|
||||||
BIN
support/3rd_party/curl-8.16.0.tar.gz
LFS
vendored
Normal file
BIN
support/3rd_party/curl-8.16.0.tar.gz
LFS
vendored
Normal file
Binary file not shown.
1
support/3rd_party/curl-8.16.0.tar.gz.sha256
vendored
Normal file
1
support/3rd_party/curl-8.16.0.tar.gz.sha256
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
d4d9a5001b491f5726efe9b50bc4aad03029506e73c9261272e809c64b05e814 curl-8.16.0.tar.gz
|
||||||
BIN
support/3rd_party/googletest-1.15.2.tar.gz
LFS
vendored
BIN
support/3rd_party/googletest-1.15.2.tar.gz
LFS
vendored
Binary file not shown.
@@ -1 +0,0 @@
|
|||||||
7b42b4d6ed48810c5362c265a17faebe90dc2373c885e5216439d37927f02926 googletest-1.15.2.tar.gz
|
|
||||||
BIN
support/3rd_party/googletest-1.16.0.tar.gz
LFS
vendored
BIN
support/3rd_party/googletest-1.16.0.tar.gz
LFS
vendored
Binary file not shown.
@@ -1 +0,0 @@
|
|||||||
78c676fc63881529bf97bf9d45948d905a66833fbfa5318ea2cd7478cb98f399 *googletest-1.16.0.tar.gz
|
|
||||||
BIN
support/3rd_party/googletest-1.17.0.tar.gz
LFS
vendored
Normal file
BIN
support/3rd_party/googletest-1.17.0.tar.gz
LFS
vendored
Normal file
Binary file not shown.
1
support/3rd_party/googletest-1.17.0.tar.gz.sha256
vendored
Normal file
1
support/3rd_party/googletest-1.17.0.tar.gz.sha256
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
65fab701d9829d38cb77c14acdc431d2108bfdbf8979e40eb8ae567edf10b27c googletest-1.17.0.tar.gz
|
||||||
16
support/3rd_party/icu_configure.sh
vendored
Executable file
16
support/3rd_party/icu_configure.sh
vendored
Executable file
@@ -0,0 +1,16 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
if [ "$(uname -m)" == "arm64" ] &&
|
||||||
|
[ "${PROJECT_IS_ARM64}" == "0" ]; then
|
||||||
|
HOST_CFG="--host=x86_64-apple-darwin"
|
||||||
|
export CC="clang -arch x86_64"
|
||||||
|
export CXX="clang++ -arch x86_64"
|
||||||
|
fi
|
||||||
|
|
||||||
|
CXXFLAGS="-std=gnu++17 -march=$1 -mtune=generic" ./configure \
|
||||||
|
--disable-samples \
|
||||||
|
--disable-tests \
|
||||||
|
--enable-shared=$3 \
|
||||||
|
--enable-static=yes \
|
||||||
|
--prefix="$2" \
|
||||||
|
${HOST_CFG}
|
||||||
2
support/3rd_party/json-3.12.0.tar.gz.sha256
vendored
2
support/3rd_party/json-3.12.0.tar.gz.sha256
vendored
@@ -1 +1 @@
|
|||||||
4b92eb0c06d10683f7447ce9406cb97cd4b453be18d7279320f7b2f025c10187 json-3.12.0.tar.gz
|
4b92eb0c06d10683f7447ce9406cb97cd4b453be18d7279320f7b2f025c10187 *json-3.12.0.tar.gz
|
||||||
|
|||||||
BIN
support/3rd_party/mingw64/gcc-14.2.0.tar.gz
LFS
vendored
BIN
support/3rd_party/mingw64/gcc-14.2.0.tar.gz
LFS
vendored
Binary file not shown.
@@ -1 +0,0 @@
|
|||||||
7d376d445f93126dc545e2c0086d0f647c3094aae081cdb78f42ce2bc25e7293 gcc-14.2.0.tar.gz
|
|
||||||
BIN
support/3rd_party/mingw64/gcc-15.2.0.tar.gz
LFS
vendored
Normal file
BIN
support/3rd_party/mingw64/gcc-15.2.0.tar.gz
LFS
vendored
Normal file
Binary file not shown.
1
support/3rd_party/mingw64/gcc-15.2.0.tar.gz.sha256
vendored
Normal file
1
support/3rd_party/mingw64/gcc-15.2.0.tar.gz.sha256
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
7294d65cc1a0558cb815af0ca8c7763d86f7a31199794ede3f630c0d1b0a5723 gcc-15.2.0.tar.gz
|
||||||
BIN
support/3rd_party/mingw64/innosetup-6.5.4.exe
vendored
Normal file
BIN
support/3rd_party/mingw64/innosetup-6.5.4.exe
vendored
Normal file
Binary file not shown.
1
support/3rd_party/mingw64/innosetup-6.5.4.exe.sha256
vendored
Normal file
1
support/3rd_party/mingw64/innosetup-6.5.4.exe.sha256
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
fa73bf47a4da250d185d07561c2bfda387e5e20db77e4570004cf6a133cc10b1 innosetup-6.5.4.exe
|
||||||
@@ -1 +0,0 @@
|
|||||||
cc41898aac4b6e8dd5cffd7331b9d9515b912df4420a3a612b5ea2955bbeed2f mingw-w64-v12.0.0.tar.bz2
|
|
||||||
Binary file not shown.
1
support/3rd_party/mingw64/mingw-w64-v13.0.0.tar.bz2.sha256
vendored
Normal file
1
support/3rd_party/mingw64/mingw-w64-v13.0.0.tar.bz2.sha256
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
5afe822af5c4edbf67daaf45eec61d538f49eef6b19524de64897c6b95828caf mingw-w64-v13.0.0.tar.bz2
|
||||||
BIN
support/3rd_party/openssl-3.5.0.tar.gz
LFS
vendored
BIN
support/3rd_party/openssl-3.5.0.tar.gz
LFS
vendored
Binary file not shown.
@@ -1 +0,0 @@
|
|||||||
344d0a79f1a9b08029b0744e2cc401a43f9c90acd1044d09a530b4885a8e9fc0 openssl-3.5.0.tar.gz
|
|
||||||
BIN
support/3rd_party/openssl-3.6.0.tar.gz
LFS
vendored
Normal file
BIN
support/3rd_party/openssl-3.6.0.tar.gz
LFS
vendored
Normal file
Binary file not shown.
1
support/3rd_party/openssl-3.6.0.tar.gz.sha256
vendored
Normal file
1
support/3rd_party/openssl-3.6.0.tar.gz.sha256
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
b6a5f44b7eb69e3fa35dbf15524405b44837a481d43d81daddde3ff21fcbb8e9 openssl-3.6.0.tar.gz
|
||||||
BIN
support/3rd_party/rocksdb-10.0.1.tar.gz
LFS
vendored
BIN
support/3rd_party/rocksdb-10.0.1.tar.gz
LFS
vendored
Binary file not shown.
@@ -1 +0,0 @@
|
|||||||
3fdc9ca996971c4c039959866382c4a3a6c8ade4abf888f3b2ff77153e07bf28 rocksdb-10.0.1.tar.gz
|
|
||||||
BIN
support/3rd_party/rocksdb-10.5.1.tar.gz
LFS
vendored
Normal file
BIN
support/3rd_party/rocksdb-10.5.1.tar.gz
LFS
vendored
Normal file
Binary file not shown.
1
support/3rd_party/rocksdb-10.5.1.tar.gz.sha256
vendored
Normal file
1
support/3rd_party/rocksdb-10.5.1.tar.gz.sha256
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
7ec942baab802b2845188d02bc5d4e42c29236e61bcbc08f5b3a6bdd92290c22 rocksdb-10.5.1.tar.gz
|
||||||
BIN
support/3rd_party/spdlog-1.15.2.tar.gz
LFS
vendored
BIN
support/3rd_party/spdlog-1.15.2.tar.gz
LFS
vendored
Binary file not shown.
@@ -1 +0,0 @@
|
|||||||
7a80896357f3e8e920e85e92633b14ba0f229c506e6f978578bdc35ba09e9a5d spdlog-1.15.2.tar.gz
|
|
||||||
BIN
support/3rd_party/spdlog-1.15.3.tar.gz
LFS
vendored
Normal file
BIN
support/3rd_party/spdlog-1.15.3.tar.gz
LFS
vendored
Normal file
Binary file not shown.
1
support/3rd_party/spdlog-1.15.3.tar.gz.sha256
vendored
Normal file
1
support/3rd_party/spdlog-1.15.3.tar.gz.sha256
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
15a04e69c222eb6c01094b5c7ff8a249b36bb22788d72519646fb85feb267e67 spdlog-1.15.3.tar.gz
|
||||||
@@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include "utils/config.hpp"
|
#include "utils/config.hpp"
|
||||||
|
|
||||||
|
#include "utils/atomic.hpp"
|
||||||
#include "utils/base64.hpp"
|
#include "utils/base64.hpp"
|
||||||
#include "utils/collection.hpp"
|
#include "utils/collection.hpp"
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
@@ -49,6 +50,7 @@
|
|||||||
#include "utils/path.hpp"
|
#include "utils/path.hpp"
|
||||||
#include "utils/string.hpp"
|
#include "utils/string.hpp"
|
||||||
#include "utils/time.hpp"
|
#include "utils/time.hpp"
|
||||||
|
#include "utils/ttl_cache.hpp"
|
||||||
#if !defined(_WIN32)
|
#if !defined(_WIN32)
|
||||||
#include "utils/unix.hpp"
|
#include "utils/unix.hpp"
|
||||||
#endif // !defined(_WIN32)
|
#endif // !defined(_WIN32)
|
||||||
|
|||||||
118
support/include/utils/atomic.hpp
Normal file
118
support/include/utils/atomic.hpp
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
/*
|
||||||
|
Copyright <2018-2025> <scott.e.graves@protonmail.com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
#ifndef MONITARR_INCLUDE_UTILS_ATOMIC_HPP_
|
||||||
|
#define MONITARR_INCLUDE_UTILS_ATOMIC_HPP_
|
||||||
|
|
||||||
|
#include "utils/config.hpp"
|
||||||
|
|
||||||
|
namespace monitarr::utils {
|
||||||
|
template <typename data_t> class atomic final {
|
||||||
|
public:
|
||||||
|
atomic() : mtx_(std::make_shared<std::mutex>()) {}
|
||||||
|
|
||||||
|
atomic(const atomic &at_data)
|
||||||
|
: data_(at_data.load()), mtx_(std::make_shared<std::mutex>()) {}
|
||||||
|
|
||||||
|
atomic(data_t data)
|
||||||
|
: data_(std::move(data)), mtx_(std::make_shared<std::mutex>()) {}
|
||||||
|
|
||||||
|
atomic(atomic &&) = default;
|
||||||
|
|
||||||
|
~atomic() = default;
|
||||||
|
|
||||||
|
private:
|
||||||
|
data_t data_;
|
||||||
|
std::shared_ptr<std::mutex> mtx_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
[[nodiscard]] auto load() const -> data_t {
|
||||||
|
mutex_lock lock(*mtx_);
|
||||||
|
return data_;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto store(data_t data) -> data_t {
|
||||||
|
mutex_lock lock(*mtx_);
|
||||||
|
data_ = std::move(data);
|
||||||
|
return data_;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto operator=(const atomic &at_data) -> atomic & {
|
||||||
|
if (&at_data == this) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
store(at_data.load());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto operator=(atomic &&) -> atomic & = default;
|
||||||
|
|
||||||
|
auto operator=(data_t data) -> atomic & {
|
||||||
|
if (&data == &data_) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
store(std::move(data));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto operator==(const atomic &at_data) const -> bool {
|
||||||
|
if (&at_data == this) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_lock lock(*mtx_);
|
||||||
|
return at_data.load() == data_;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto operator==(const data_t &data) const -> bool {
|
||||||
|
if (&data == &data_) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_lock lock(*mtx_);
|
||||||
|
return data == data_;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto operator!=(const atomic &at_data) const -> bool {
|
||||||
|
if (&at_data == this) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_lock lock(*mtx_);
|
||||||
|
return at_data.load() != data_;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto operator!=(const data_t &data) const -> bool {
|
||||||
|
if (&data == &data_) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_lock lock(*mtx_);
|
||||||
|
return data != data_;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] operator data_t() const { return load(); }
|
||||||
|
};
|
||||||
|
} // namespace monitarr::utils
|
||||||
|
|
||||||
|
#endif // MONITARR_INCLUDE_UTILS_ATOMIC_HPP_
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
// NOLINTBEGIN
|
// NOLINTBEGIN
|
||||||
#ifndef _MACARON_BASE64_H_
|
#ifndef MACARON_BASE64_H_
|
||||||
#define _MACARON_BASE64_H_
|
#define MACARON_BASE64_H_
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
* Copyright (c) 2016 tomykaira
|
* Copyright (c) 2016 tomykaira
|
||||||
|
* Copyright (c) 2025 scott.e.graves@protonmail.com
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the
|
* a copy of this software and associated documentation files (the
|
||||||
@@ -39,121 +40,272 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <stdexcept>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace macaron::Base64 {
|
namespace macaron::Base64 {
|
||||||
static std::string Encode(const unsigned char *data, std::size_t len) {
|
|
||||||
static constexpr std::array<unsigned char, 64U> sEncodingTable{
|
// --- Alphabets --------------------------------------------------------------
|
||||||
|
|
||||||
|
static constexpr std::array<unsigned char, 64U> kStdAlphabet{
|
||||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
|
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
|
||||||
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
|
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
|
||||||
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
||||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/',
|
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/',
|
||||||
};
|
};
|
||||||
|
|
||||||
auto in_len{len};
|
static constexpr std::array<unsigned char, 64U> kUrlAlphabet{
|
||||||
std::string ret;
|
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
|
||||||
if (in_len > 0) {
|
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||||
std::size_t out_len{4U * ((in_len + 2U) / 3U)};
|
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
|
||||||
ret = std::string(out_len, '\0');
|
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
||||||
std::size_t i;
|
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_',
|
||||||
auto *p = reinterpret_cast<unsigned char *>(ret.data());
|
};
|
||||||
|
|
||||||
for (i = 0U; i < in_len - 2U; i += 3U) {
|
// Decoding table that accepts BOTH standard and URL-safe alphabets.
|
||||||
*p++ = sEncodingTable[(data[i] >> 2U) & 0x3F];
|
static constexpr std::array<unsigned char, 256U> kDecodingTable = [] {
|
||||||
*p++ = sEncodingTable[((data[i] & 0x3) << 4U) |
|
std::array<unsigned char, 256U> t{};
|
||||||
((int)(data[i + 1U] & 0xF0) >> 4U)];
|
t.fill(64U);
|
||||||
*p++ = sEncodingTable[((data[i + 1] & 0xF) << 2) |
|
// 'A'-'Z'
|
||||||
((int)(data[i + 2U] & 0xC0) >> 6U)];
|
for (unsigned char c = 'A'; c <= 'Z'; ++c)
|
||||||
*p++ = sEncodingTable[data[i + 2U] & 0x3F];
|
t[c] = static_cast<unsigned char>(c - 'A');
|
||||||
|
// 'a'-'z'
|
||||||
|
for (unsigned char c = 'a'; c <= 'z'; ++c)
|
||||||
|
t[c] = static_cast<unsigned char>(26 + c - 'a');
|
||||||
|
// '0'-'9'
|
||||||
|
for (unsigned char c = '0'; c <= '9'; ++c)
|
||||||
|
t[c] = static_cast<unsigned char>(52 + c - '0');
|
||||||
|
// Standard extras
|
||||||
|
t[static_cast<unsigned char>('+')] = 62U;
|
||||||
|
t[static_cast<unsigned char>('/')] = 63U;
|
||||||
|
// URL-safe extras
|
||||||
|
t[static_cast<unsigned char>('-')] = 62U;
|
||||||
|
t[static_cast<unsigned char>('_')] = 63U;
|
||||||
|
return t;
|
||||||
|
}();
|
||||||
|
|
||||||
|
// --- Encoding ---------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode to Base64.
|
||||||
|
* @param data pointer to bytes
|
||||||
|
* @param len number of bytes
|
||||||
|
* @param url_safe if true, use URL-safe alphabet ("-","_") instead of ("+","/")
|
||||||
|
* @param pad if true, add '=' padding; if false, omit padding (RFC 4648
|
||||||
|
* §5)
|
||||||
|
*/
|
||||||
|
static std::string Encode(const unsigned char *data, std::size_t len,
|
||||||
|
bool url_safe = false, bool pad = true) {
|
||||||
|
const auto &alpha = url_safe ? kUrlAlphabet : kStdAlphabet;
|
||||||
|
|
||||||
|
std::string out;
|
||||||
|
if (len == 0U) {
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
if (i < in_len) {
|
|
||||||
*p++ = sEncodingTable[(data[i] >> 2U) & 0x3F];
|
const std::size_t full_blocks = len / 3U;
|
||||||
if (i == (in_len - 1U)) {
|
const std::size_t rem = len % 3U;
|
||||||
*p++ = sEncodingTable[((data[i] & 0x3) << 4U)];
|
|
||||||
*p++ = '=';
|
std::size_t out_len{};
|
||||||
|
if (pad) {
|
||||||
|
out_len = 4U * ((len + 2U) / 3U);
|
||||||
} else {
|
} else {
|
||||||
*p++ = sEncodingTable[((data[i] & 0x3) << 4U) |
|
// Unpadded length per RFC 4648 §5
|
||||||
((int)(data[i + 1U] & 0xF0) >> 4U)];
|
out_len = 4U * full_blocks + (rem == 0U ? 0U : (rem == 1U ? 2U : 3U));
|
||||||
*p++ = sEncodingTable[((data[i + 1U] & 0xF) << 2U)];
|
|
||||||
}
|
}
|
||||||
|
out.assign(out_len, '\0');
|
||||||
|
|
||||||
|
auto *p = reinterpret_cast<unsigned char *>(out.data());
|
||||||
|
std::size_t i = 0;
|
||||||
|
|
||||||
|
// Full 3-byte blocks -> 4 chars
|
||||||
|
for (; i + 2U < len; i += 3U) {
|
||||||
|
const unsigned char b0 = data[i + 0U];
|
||||||
|
const unsigned char b1 = data[i + 1U];
|
||||||
|
const unsigned char b2 = data[i + 2U];
|
||||||
|
|
||||||
|
*p++ = alpha[(b0 >> 2U) & 0x3F];
|
||||||
|
*p++ = alpha[((b0 & 0x03U) << 4U) | ((b1 >> 4U) & 0x0FU)];
|
||||||
|
*p++ = alpha[((b1 & 0x0FU) << 2U) | ((b2 >> 6U) & 0x03U)];
|
||||||
|
*p++ = alpha[b2 & 0x3FU];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remainder
|
||||||
|
if (rem == 1U) {
|
||||||
|
const unsigned char b0 = data[i];
|
||||||
|
*p++ = alpha[(b0 >> 2U) & 0x3F];
|
||||||
|
*p++ = alpha[(b0 & 0x03U) << 4U];
|
||||||
|
if (pad) {
|
||||||
|
*p++ = '=';
|
||||||
|
*p++ = '=';
|
||||||
|
}
|
||||||
|
} else if (rem == 2U) {
|
||||||
|
const unsigned char b0 = data[i + 0U];
|
||||||
|
const unsigned char b1 = data[i + 1U];
|
||||||
|
*p++ = alpha[(b0 >> 2U) & 0x3F];
|
||||||
|
*p++ = alpha[((b0 & 0x03U) << 4U) | ((b1 >> 4U) & 0x0FU)];
|
||||||
|
*p++ = alpha[(b1 & 0x0FU) << 2U];
|
||||||
|
if (pad) {
|
||||||
*p++ = '=';
|
*p++ = '=';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[maybe_unused]] static std::string Encode(std::string_view data) {
|
[[maybe_unused]] static std::string
|
||||||
|
Encode(std::string_view data, bool url_safe = false, bool pad = true) {
|
||||||
return Encode(reinterpret_cast<const unsigned char *>(data.data()),
|
return Encode(reinterpret_cast<const unsigned char *>(data.data()),
|
||||||
data.size());
|
data.size(), url_safe, pad);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[maybe_unused]] static std::string
|
||||||
|
EncodeUrlSafe(const unsigned char *data, std::size_t len, bool pad = false) {
|
||||||
|
return Encode(data, len, /*url_safe=*/true, /*pad=*/pad);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[maybe_unused]] static std::string EncodeUrlSafe(std::string_view data,
|
||||||
|
bool pad = false) {
|
||||||
|
return Encode(reinterpret_cast<const unsigned char *>(data.data()),
|
||||||
|
data.size(), /*url_safe=*/true, /*pad=*/pad);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Decoding ---------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decode standard OR URL-safe Base64.
|
||||||
|
* Accepts inputs with or without '=' padding.
|
||||||
|
* Throws std::runtime_error on malformed input.
|
||||||
|
*/
|
||||||
[[maybe_unused]] static std::vector<unsigned char>
|
[[maybe_unused]] static std::vector<unsigned char>
|
||||||
Decode(std::string_view input) {
|
Decode(std::string_view input) {
|
||||||
static constexpr std::array<unsigned char, 256> kDecodingTable{
|
std::vector<unsigned char> out;
|
||||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
|
if (input.empty()) {
|
||||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
|
return out;
|
||||||
64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63, 52, 53, 54, 55, 56, 57,
|
}
|
||||||
58, 59, 60, 61, 64, 64, 64, 64, 64, 64, 64, 0, 1, 2, 3, 4, 5, 6,
|
|
||||||
7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
std::size_t inLen = input.size();
|
||||||
25, 64, 64, 64, 64, 64, 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
|
std::size_t rem = inLen % 4U;
|
||||||
37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64,
|
|
||||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
|
// padded if multiple of 4 and last char is '='
|
||||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
|
bool hasPadding = (rem == 0U) && (inLen >= 4U) && (input[inLen - 1U] == '=');
|
||||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
|
|
||||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
|
// compute output length
|
||||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
|
std::size_t outLen{};
|
||||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
|
if (hasPadding) {
|
||||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
|
outLen = (inLen / 4U) * 3U;
|
||||||
64, 64, 64, 64,
|
if (input[inLen - 1U] == '=')
|
||||||
|
outLen--;
|
||||||
|
if (input[inLen - 2U] == '=')
|
||||||
|
outLen--;
|
||||||
|
} else {
|
||||||
|
if (rem == 1U) {
|
||||||
|
throw std::runtime_error("Invalid Base64 length (mod 4 == 1)");
|
||||||
|
}
|
||||||
|
outLen = (inLen / 4U) * 3U + (rem == 0U ? 0U : (rem == 2U ? 1U : 2U));
|
||||||
|
}
|
||||||
|
|
||||||
|
out.resize(outLen);
|
||||||
|
|
||||||
|
auto readVal = [](unsigned char c) -> unsigned char {
|
||||||
|
unsigned char v = kDecodingTable[c];
|
||||||
|
if (v == 64U) {
|
||||||
|
throw std::runtime_error("Invalid Base64 character");
|
||||||
|
}
|
||||||
|
return v;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<unsigned char> out;
|
std::size_t i = 0U;
|
||||||
if (not input.empty()) {
|
std::size_t j = 0U;
|
||||||
auto in_len{input.size()};
|
|
||||||
if (in_len % 4U != 0U) {
|
// process all full unpadded quartets
|
||||||
throw std::runtime_error("Input data size is not a multiple of 4");
|
std::size_t lastFull =
|
||||||
|
hasPadding ? (inLen - 4U) : (rem == 0U ? inLen : (inLen - rem));
|
||||||
|
|
||||||
|
while (i + 4U <= lastFull) {
|
||||||
|
unsigned char a = readVal(static_cast<unsigned char>(input[i + 0U]));
|
||||||
|
unsigned char b = readVal(static_cast<unsigned char>(input[i + 1U]));
|
||||||
|
unsigned char c = readVal(static_cast<unsigned char>(input[i + 2U]));
|
||||||
|
unsigned char d = readVal(static_cast<unsigned char>(input[i + 3U]));
|
||||||
|
i += 4U;
|
||||||
|
|
||||||
|
std::uint32_t triple = (static_cast<std::uint32_t>(a) << 18U) |
|
||||||
|
(static_cast<std::uint32_t>(b) << 12U) |
|
||||||
|
(static_cast<std::uint32_t>(c) << 6U) |
|
||||||
|
(static_cast<std::uint32_t>(d));
|
||||||
|
|
||||||
|
if (j < outLen)
|
||||||
|
out[j++] = static_cast<unsigned char>((triple >> 16U) & 0xFFU);
|
||||||
|
if (j < outLen)
|
||||||
|
out[j++] = static_cast<unsigned char>((triple >> 8U) & 0xFFU);
|
||||||
|
if (j < outLen)
|
||||||
|
out[j++] = static_cast<unsigned char>(triple & 0xFFU);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t out_len{in_len / 4U * 3U};
|
// tail: padded quartet or unpadded remainder
|
||||||
if (input[in_len - 1U] == '=') {
|
if (i < inLen) {
|
||||||
out_len--;
|
std::size_t left = inLen - i;
|
||||||
}
|
|
||||||
if (input[in_len - 2U] == '=') {
|
if (left == 4U) {
|
||||||
out_len--;
|
bool thirdIsPad = (input[i + 2U] == '=');
|
||||||
|
bool fourthIsPad = (input[i + 3U] == '=');
|
||||||
|
|
||||||
|
// '=' is never allowed in positions 1 or 2 of any quartet
|
||||||
|
if (input[i + 0U] == '=' || input[i + 1U] == '=') {
|
||||||
|
throw std::runtime_error("Invalid Base64 padding placement");
|
||||||
}
|
}
|
||||||
|
|
||||||
out.resize(out_len);
|
unsigned char a = readVal(static_cast<unsigned char>(input[i + 0U]));
|
||||||
|
unsigned char b = readVal(static_cast<unsigned char>(input[i + 1U]));
|
||||||
|
unsigned char c = 0U;
|
||||||
|
unsigned char d = 0U;
|
||||||
|
|
||||||
for (std::size_t i = 0U, j = 0U; i < in_len;) {
|
if (!thirdIsPad) {
|
||||||
std::uint32_t a =
|
c = readVal(static_cast<unsigned char>(input[i + 2U]));
|
||||||
input.at(i) == '='
|
if (!fourthIsPad) {
|
||||||
? 0U & i++
|
d = readVal(static_cast<unsigned char>(input[i + 3U]));
|
||||||
: kDecodingTable[static_cast<unsigned char>(input.at(i++))];
|
}
|
||||||
std::uint32_t b =
|
} else {
|
||||||
input.at(i) == '='
|
// if the 3rd is '=', the 4th must also be '='
|
||||||
? 0U & i++
|
if (!fourthIsPad) {
|
||||||
: kDecodingTable[static_cast<unsigned char>(input.at(i++))];
|
throw std::runtime_error("Invalid Base64 padding placement");
|
||||||
std::uint32_t c =
|
}
|
||||||
input.at(i) == '='
|
}
|
||||||
? 0U & i++
|
i += 4U;
|
||||||
: kDecodingTable[static_cast<unsigned char>(input.at(i++))];
|
|
||||||
std::uint32_t d =
|
|
||||||
input.at(i) == '='
|
|
||||||
? 0U & i++
|
|
||||||
: kDecodingTable[static_cast<unsigned char>(input.at(i++))];
|
|
||||||
|
|
||||||
std::uint32_t triple =
|
std::uint32_t triple = (static_cast<std::uint32_t>(a) << 18U) |
|
||||||
(a << 3U * 6U) + (b << 2U * 6U) + (c << 1U * 6U) + (d << 0U * 6U);
|
(static_cast<std::uint32_t>(b) << 12U) |
|
||||||
|
(static_cast<std::uint32_t>(c) << 6U) |
|
||||||
|
(static_cast<std::uint32_t>(d));
|
||||||
|
|
||||||
if (j < out_len)
|
if (j < outLen)
|
||||||
out[j++] = (triple >> 2U * 8U) & 0xFF;
|
out[j++] = static_cast<unsigned char>((triple >> 16U) & 0xFFU);
|
||||||
if (j < out_len)
|
if (!thirdIsPad && j < outLen)
|
||||||
out[j++] = (triple >> 1U * 8U) & 0xFF;
|
out[j++] = static_cast<unsigned char>((triple >> 8U) & 0xFFU);
|
||||||
if (j < out_len)
|
if (!fourthIsPad && !thirdIsPad && j < outLen)
|
||||||
out[j++] = (triple >> 0U * 8U) & 0xFF;
|
out[j++] = static_cast<unsigned char>(triple & 0xFFU);
|
||||||
|
|
||||||
|
} else if (left == 2U || left == 3U) {
|
||||||
|
unsigned char a = readVal(static_cast<unsigned char>(input[i + 0U]));
|
||||||
|
unsigned char b = readVal(static_cast<unsigned char>(input[i + 1U]));
|
||||||
|
unsigned char c = (left == 3U)
|
||||||
|
? readVal(static_cast<unsigned char>(input[i + 2U]))
|
||||||
|
: 0U;
|
||||||
|
i += left;
|
||||||
|
|
||||||
|
std::uint32_t triple = (static_cast<std::uint32_t>(a) << 18U) |
|
||||||
|
(static_cast<std::uint32_t>(b) << 12U) |
|
||||||
|
(static_cast<std::uint32_t>(c) << 6U);
|
||||||
|
|
||||||
|
if (j < outLen)
|
||||||
|
out[j++] = static_cast<unsigned char>((triple >> 16U) & 0xFFU);
|
||||||
|
if (left == 3U && j < outLen)
|
||||||
|
out[j++] = static_cast<unsigned char>((triple >> 8U) & 0xFFU);
|
||||||
|
} else {
|
||||||
|
throw std::runtime_error("Invalid Base64 length (mod 4 == 1)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,6 +321,5 @@ Decode(std::string_view input) {
|
|||||||
#pragma clang diagnostic pop
|
#pragma clang diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* _MACARON_BASE64_H_ */
|
#endif /* MACARON_BASE64_H_ */
|
||||||
|
// NOLINTEND
|
||||||
// NOLINTEND
|
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ template <typename val_t>
|
|||||||
-> bool {
|
-> bool {
|
||||||
MONITARR_USES_FUNCTION_NAME();
|
MONITARR_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
static constexpr const auto base16{16};
|
static constexpr auto base16{16};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val.clear();
|
val.clear();
|
||||||
@@ -158,7 +158,7 @@ template <typename col_t>
|
|||||||
inline auto to_hex_string(const col_t &collection) -> std::string {
|
inline auto to_hex_string(const col_t &collection) -> std::string {
|
||||||
static_assert(sizeof(typename col_t::value_type) == 1U,
|
static_assert(sizeof(typename col_t::value_type) == 1U,
|
||||||
"value_type must be 1 byte in size");
|
"value_type must be 1 byte in size");
|
||||||
static constexpr const auto mask = 0xFF;
|
static constexpr auto mask{0xFF};
|
||||||
|
|
||||||
std::stringstream stream{};
|
std::stringstream stream{};
|
||||||
for (auto &&val : collection) {
|
for (auto &&val : collection) {
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ struct com_init_wrapper final {
|
|||||||
[[nodiscard]] auto is_initialized() const -> bool { return initialized_; }
|
[[nodiscard]] auto is_initialized() const -> bool { return initialized_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BOOL initialized_;
|
BOOL initialized_{};
|
||||||
};
|
};
|
||||||
} // namespace monitarr::utils
|
} // namespace monitarr::utils
|
||||||
|
|
||||||
|
|||||||
@@ -35,9 +35,10 @@ struct result final {
|
|||||||
|
|
||||||
using retryable_action_t = std::function<bool()>;
|
using retryable_action_t = std::function<bool()>;
|
||||||
|
|
||||||
[[nodiscard]] inline constexpr auto
|
[[nodiscard]] constexpr auto calculate_read_size(std::uint64_t total_size,
|
||||||
calculate_read_size(std::uint64_t total_size, std::size_t read_size,
|
std::size_t read_size,
|
||||||
std::uint64_t offset) -> std::size_t {
|
std::uint64_t offset)
|
||||||
|
-> std::size_t {
|
||||||
return static_cast<std::size_t>(
|
return static_cast<std::size_t>(
|
||||||
((offset + read_size) > total_size)
|
((offset + read_size) > total_size)
|
||||||
? ((offset < total_size) ? total_size - offset : 0U)
|
? ((offset < total_size) ? total_size - offset : 0U)
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
#define NOMINMAX
|
#define NOMINMAX
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
#define WINVER 0x0602
|
#define WINVER 0x0A00
|
||||||
#define _WIN32_WINNT WINVER
|
#define _WIN32_WINNT WINVER
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
|
||||||
@@ -106,9 +106,7 @@
|
|||||||
#include <bit>
|
#include <bit>
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <ciso646>
|
|
||||||
#include <climits>
|
#include <climits>
|
||||||
#include <codecvt>
|
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include <csignal>
|
#include <csignal>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
@@ -147,8 +145,12 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <version>
|
||||||
#endif // defined(__cplusplus)
|
#endif // defined(__cplusplus)
|
||||||
|
|
||||||
|
#include <unicode/uchar.h>
|
||||||
|
#include <unicode/utf.h>
|
||||||
|
|
||||||
#if defined(PROJECT_ENABLE_CURL)
|
#if defined(PROJECT_ENABLE_CURL)
|
||||||
#include "curl/curl.h"
|
#include "curl/curl.h"
|
||||||
#include "curl/multi.h"
|
#include "curl/multi.h"
|
||||||
@@ -415,11 +417,16 @@ using vlc_string_t = std::unique_ptr<char, vlc_string_deleter>;
|
|||||||
#endif // defined(PROJECT_ENABLE_TPL)
|
#endif // defined(PROJECT_ENABLE_TPL)
|
||||||
|
|
||||||
#if defined(PROJECT_ENABLE_WINFSP)
|
#if defined(PROJECT_ENABLE_WINFSP)
|
||||||
|
#if defined(_ReadWriteBarrier)
|
||||||
|
#undef _ReadWriteBarrier
|
||||||
|
#endif // defined(_ReadWriteBarrier)
|
||||||
#include "winfsp/winfsp.hpp"
|
#include "winfsp/winfsp.hpp"
|
||||||
#endif // defined(PROJECT_ENABLE_WINFSP)
|
#endif // defined(PROJECT_ENABLE_WINFSP)
|
||||||
|
|
||||||
namespace monitarr {
|
namespace monitarr {
|
||||||
using data_buffer = std::vector<unsigned char>;
|
using data_buffer = std::vector<unsigned char>;
|
||||||
|
using data_span = std::span<unsigned char>;
|
||||||
|
using data_cspan = std::span<const unsigned char>;
|
||||||
using mutex_lock = std::lock_guard<std::mutex>;
|
using mutex_lock = std::lock_guard<std::mutex>;
|
||||||
using recur_mutex_lock = std::lock_guard<std::recursive_mutex>;
|
using recur_mutex_lock = std::lock_guard<std::recursive_mutex>;
|
||||||
using stop_type = std::atomic_bool;
|
using stop_type = std::atomic_bool;
|
||||||
@@ -429,14 +436,14 @@ using unique_recur_mutex_lock = std::unique_lock<std::recursive_mutex>;
|
|||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
#if defined(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
|
#if defined(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
|
||||||
inline constexpr const auto max_path_length = std::size_t{32767U};
|
inline constexpr auto max_path_length = std::size_t{32767U};
|
||||||
#else // !defined(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
|
#else // !defined(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
|
||||||
inline constexpr const auto max_path_length = std::size_t{MAX_PATH};
|
inline constexpr auto max_path_length = std::size_t{MAX_PATH};
|
||||||
#endif // defined(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
|
#endif // defined(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
|
||||||
|
|
||||||
using native_handle = HANDLE;
|
using native_handle = HANDLE;
|
||||||
#else // !defined(_WIN32)
|
#else // !defined(_WIN32)
|
||||||
inline constexpr const auto max_path_length = std::size_t{PATH_MAX};
|
inline constexpr auto max_path_length = std::size_t{PATH_MAX};
|
||||||
using native_handle = int;
|
using native_handle = int;
|
||||||
#if !defined(INVALID_HANDLE_VALUE)
|
#if !defined(INVALID_HANDLE_VALUE)
|
||||||
#define INVALID_HANDLE_VALUE (-1)
|
#define INVALID_HANDLE_VALUE (-1)
|
||||||
@@ -482,7 +489,7 @@ using http_ranges = std::vector<http_range>;
|
|||||||
#endif // defined(__cplusplus)
|
#endif // defined(__cplusplus)
|
||||||
|
|
||||||
#define MONITARR_USES_FUNCTION_NAME() \
|
#define MONITARR_USES_FUNCTION_NAME() \
|
||||||
static constexpr const std::string_view function_name { \
|
static constexpr std::string_view function_name { \
|
||||||
static_cast<const char *>(__FUNCTION__), \
|
static_cast<const char *>(__FUNCTION__), \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include "utils/config.hpp"
|
#include "utils/config.hpp"
|
||||||
|
|
||||||
|
#include "utils/encryption.hpp"
|
||||||
#include "utils/hash.hpp"
|
#include "utils/hash.hpp"
|
||||||
#include "utils/types/file/i_file.hpp"
|
#include "utils/types/file/i_file.hpp"
|
||||||
|
|
||||||
@@ -37,14 +38,74 @@ public:
|
|||||||
std::optional<std::string> relative_parent_path,
|
std::optional<std::string> relative_parent_path,
|
||||||
std::size_t error_return = 0U);
|
std::size_t error_return = 0U);
|
||||||
|
|
||||||
encrypting_reader(std::string_view encrypted_file_path,
|
encrypting_reader(stop_type_callback stop_requested_cb,
|
||||||
std::string_view source_path,
|
std::string_view encrypted_file_path,
|
||||||
stop_type_callback stop_requested_cb,
|
std::string_view source_path, std::string_view token,
|
||||||
std::string_view token, std::size_t error_return = 0U);
|
std::size_t error_return = 0U);
|
||||||
|
|
||||||
encrypting_reader(
|
encrypting_reader(
|
||||||
|
stop_type_callback stop_requested_cb,
|
||||||
std::string_view encrypted_file_path, std::string_view source_path,
|
std::string_view encrypted_file_path, std::string_view source_path,
|
||||||
stop_type_callback stop_requested_cb, std::string_view token,
|
std::string_view token,
|
||||||
|
std::vector<std::array<unsigned char,
|
||||||
|
crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>>
|
||||||
|
iv_list,
|
||||||
|
std::size_t error_return = 0U);
|
||||||
|
|
||||||
|
encrypting_reader(std::string_view file_name, std::string_view source_path,
|
||||||
|
stop_type_callback stop_requested_cb,
|
||||||
|
std::string_view token, kdf_config cfg,
|
||||||
|
std::optional<std::string> relative_parent_path,
|
||||||
|
std::size_t error_return = 0U);
|
||||||
|
|
||||||
|
encrypting_reader(stop_type_callback stop_requested_cb,
|
||||||
|
std::string_view encrypted_file_path,
|
||||||
|
std::string_view source_path, std::string_view token,
|
||||||
|
kdf_config cfg, std::size_t error_return = 0U);
|
||||||
|
|
||||||
|
encrypting_reader(
|
||||||
|
stop_type_callback stop_requested_cb,
|
||||||
|
std::string_view encrypted_file_path, std::string_view source_path,
|
||||||
|
std::string_view token, kdf_config cfg,
|
||||||
|
std::vector<std::array<unsigned char,
|
||||||
|
crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>>
|
||||||
|
iv_list,
|
||||||
|
std::size_t error_return = 0U);
|
||||||
|
|
||||||
|
encrypting_reader(std::string_view file_name, std::string_view source_path,
|
||||||
|
stop_type_callback stop_requested_cb,
|
||||||
|
const utils::hash::hash_256_t &master_key,
|
||||||
|
const kdf_config &cfg,
|
||||||
|
std::optional<std::string> relative_parent_path,
|
||||||
|
std::size_t error_return = 0U);
|
||||||
|
|
||||||
|
encrypting_reader(std::string_view file_name, std::string_view source_path,
|
||||||
|
stop_type_callback stop_requested_cb,
|
||||||
|
const utils::hash::hash_256_t &master_key,
|
||||||
|
const std::pair<kdf_config, kdf_config> &configs,
|
||||||
|
std::optional<std::string> relative_parent_path,
|
||||||
|
std::size_t error_return = 0U);
|
||||||
|
|
||||||
|
encrypting_reader(stop_type_callback stop_requested_cb,
|
||||||
|
std::string_view encrypted_file_path,
|
||||||
|
std::string_view source_path,
|
||||||
|
const utils::hash::hash_256_t &master_key,
|
||||||
|
const kdf_config &cfg, std::size_t error_return = 0U);
|
||||||
|
|
||||||
|
encrypting_reader(
|
||||||
|
stop_type_callback stop_requested_cb,
|
||||||
|
std::string_view encrypted_file_path, std::string_view source_path,
|
||||||
|
const utils::hash::hash_256_t &master_key, const kdf_config &cfg,
|
||||||
|
std::vector<std::array<unsigned char,
|
||||||
|
crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>>
|
||||||
|
iv_list,
|
||||||
|
std::size_t error_return = 0U);
|
||||||
|
|
||||||
|
encrypting_reader(
|
||||||
|
stop_type_callback stop_requested_cb,
|
||||||
|
std::string_view encrypted_file_path, std::string_view source_path,
|
||||||
|
const utils::hash::hash_256_t &master_key,
|
||||||
|
const std::pair<kdf_config, kdf_config> &configs,
|
||||||
std::vector<std::array<unsigned char,
|
std::vector<std::array<unsigned char,
|
||||||
crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>>
|
crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>>
|
||||||
iv_list,
|
iv_list,
|
||||||
@@ -60,21 +121,25 @@ public:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
using iostream = std::basic_iostream<char, std::char_traits<char>>;
|
using iostream = std::basic_iostream<char, std::char_traits<char>>;
|
||||||
|
using kdf_pair_t = std::pair<data_buffer, data_buffer>;
|
||||||
|
using key_pair_t =
|
||||||
|
std::pair<utils::hash::hash_256_t, utils::hash::hash_256_t>;
|
||||||
using streambuf = std::basic_streambuf<char, std::char_traits<char>>;
|
using streambuf = std::basic_streambuf<char, std::char_traits<char>>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
utils::encryption::hash_256_t key_;
|
key_pair_t keys_;
|
||||||
stop_type_callback stop_requested_cb_;
|
stop_type_callback stop_requested_cb_;
|
||||||
size_t error_return_;
|
size_t error_return_;
|
||||||
std::unique_ptr<utils::file::i_file> source_file_;
|
std::unique_ptr<utils::file::i_file> source_file_;
|
||||||
|
|
||||||
private:
|
|
||||||
std::unordered_map<std::size_t, data_buffer> chunk_buffers_;
|
|
||||||
std::string encrypted_file_name_;
|
std::string encrypted_file_name_;
|
||||||
std::string encrypted_file_path_;
|
std::string encrypted_file_path_;
|
||||||
std::vector<
|
std::vector<
|
||||||
std::array<unsigned char, crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>>
|
std::array<unsigned char, crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>>
|
||||||
iv_list_;
|
iv_list_;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unordered_map<std::size_t, data_buffer> chunk_buffers_;
|
||||||
|
std::optional<kdf_pair_t> kdf_headers_;
|
||||||
std::size_t last_data_chunk_{};
|
std::size_t last_data_chunk_{};
|
||||||
std::size_t last_data_chunk_size_{};
|
std::size_t last_data_chunk_size_{};
|
||||||
std::uint64_t read_offset_{};
|
std::uint64_t read_offset_{};
|
||||||
@@ -88,12 +153,30 @@ private:
|
|||||||
private:
|
private:
|
||||||
auto reader_function(char *buffer, size_t size, size_t nitems) -> size_t;
|
auto reader_function(char *buffer, size_t size, size_t nitems) -> size_t;
|
||||||
|
|
||||||
|
void common_initialize(bool procces_iv_list);
|
||||||
|
|
||||||
|
void common_initialize_kdf_data(const kdf_config &cfg,
|
||||||
|
const utils::hash::hash_256_t &master_key);
|
||||||
|
|
||||||
|
void common_initialize_kdf_keys(std::string_view token, kdf_config &cfg);
|
||||||
|
|
||||||
|
void common_initialize_kdf_path(const utils::hash::hash_256_t &master_key);
|
||||||
|
|
||||||
|
void create_encrypted_paths(std::string_view file_name,
|
||||||
|
std::optional<std::string> relative_parent_path);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
[[nodiscard]] static auto calculate_decrypted_size(std::uint64_t total_size)
|
[[nodiscard]] static auto calculate_decrypted_size(std::uint64_t total_size,
|
||||||
|
bool uses_kdf)
|
||||||
-> std::uint64_t;
|
-> std::uint64_t;
|
||||||
|
|
||||||
[[nodiscard]] static auto
|
[[nodiscard]] static auto
|
||||||
calculate_encrypted_size(std::string_view source_path) -> std::uint64_t;
|
calculate_encrypted_size(std::string_view source_path, bool uses_kdf)
|
||||||
|
-> std::uint64_t;
|
||||||
|
|
||||||
|
[[nodiscard]] static auto calculate_encrypted_size(std::uint64_t size,
|
||||||
|
bool uses_kdf)
|
||||||
|
-> std::uint64_t;
|
||||||
|
|
||||||
[[nodiscard]] auto create_iostream() const -> std::shared_ptr<iostream>;
|
[[nodiscard]] auto create_iostream() const -> std::shared_ptr<iostream>;
|
||||||
|
|
||||||
@@ -127,6 +210,12 @@ public:
|
|||||||
return iv_list_;
|
return iv_list_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_kdf_config_for_data() const
|
||||||
|
-> std::optional<kdf_config>;
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_kdf_config_for_path() const
|
||||||
|
-> std::optional<kdf_config>;
|
||||||
|
|
||||||
[[nodiscard]] auto get_stop_requested() const -> bool {
|
[[nodiscard]] auto get_stop_requested() const -> bool {
|
||||||
return stop_requested_cb_();
|
return stop_requested_cb_();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,41 +25,248 @@
|
|||||||
|
|
||||||
#include "utils/config.hpp"
|
#include "utils/config.hpp"
|
||||||
|
|
||||||
|
#if defined(PROJECT_ENABLE_BOOST) && defined(PROJECT_ENABLE_JSON)
|
||||||
|
#include "utils/collection.hpp"
|
||||||
|
#endif // defined(PROJECT_ENABLE_BOOST) && defined(PROJECT_ENABLE_JSON)
|
||||||
#include "utils/error.hpp"
|
#include "utils/error.hpp"
|
||||||
#include "utils/hash.hpp"
|
#include "utils/hash.hpp"
|
||||||
|
|
||||||
namespace monitarr::utils::encryption {
|
namespace monitarr::utils::encryption {
|
||||||
inline constexpr const std::uint32_t encryption_header_size{
|
inline constexpr std::uint32_t encryption_header_size{
|
||||||
crypto_aead_xchacha20poly1305_IETF_NPUBBYTES +
|
crypto_aead_xchacha20poly1305_IETF_NPUBBYTES +
|
||||||
crypto_aead_xchacha20poly1305_IETF_ABYTES,
|
crypto_aead_xchacha20poly1305_IETF_ABYTES,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if defined(PROJECT_ENABLE_BOOST)
|
||||||
|
enum class kdf_version : std::uint8_t { v1 };
|
||||||
|
|
||||||
|
enum class kdf_type : std::uint8_t { argon2id };
|
||||||
|
|
||||||
|
enum class memlimit_level : std::uint8_t {
|
||||||
|
level1, // 64MiB
|
||||||
|
level2, // 256MiB
|
||||||
|
level3, // 512MiB
|
||||||
|
level4, // 1GiB
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class opslimit_level : std::uint8_t {
|
||||||
|
level1, // interactive
|
||||||
|
level2, // moderate
|
||||||
|
level3, // sensitive
|
||||||
|
};
|
||||||
|
|
||||||
|
[[nodiscard]] inline auto get_memlimit(memlimit_level memlimit) -> size_t {
|
||||||
|
constexpr auto mib512{512ULL * 1024ULL * 1024ULL};
|
||||||
|
|
||||||
|
switch (memlimit) {
|
||||||
|
case memlimit_level::level1:
|
||||||
|
return crypto_pwhash_MEMLIMIT_INTERACTIVE;
|
||||||
|
|
||||||
|
case memlimit_level::level2:
|
||||||
|
return crypto_pwhash_MEMLIMIT_MODERATE;
|
||||||
|
|
||||||
|
case memlimit_level::level3:
|
||||||
|
return mib512;
|
||||||
|
|
||||||
|
case memlimit_level::level4:
|
||||||
|
return crypto_pwhash_MEMLIMIT_SENSITIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mib512;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline auto get_opslimit(opslimit_level opslimit)
|
||||||
|
-> unsigned long long {
|
||||||
|
switch (opslimit) {
|
||||||
|
case opslimit_level::level1:
|
||||||
|
return crypto_pwhash_OPSLIMIT_INTERACTIVE;
|
||||||
|
|
||||||
|
case opslimit_level::level2:
|
||||||
|
return crypto_pwhash_OPSLIMIT_MODERATE;
|
||||||
|
|
||||||
|
case opslimit_level::level3:
|
||||||
|
return crypto_pwhash_OPSLIMIT_SENSITIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return crypto_pwhash_OPSLIMIT_MODERATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class kdf_context : std::uint8_t {
|
||||||
|
data,
|
||||||
|
path,
|
||||||
|
undefined,
|
||||||
|
};
|
||||||
|
using kdf_ctx_t = std::array<char, crypto_kdf_CONTEXTBYTES>;
|
||||||
|
|
||||||
|
namespace kdf {
|
||||||
|
constexpr inline std::array<
|
||||||
|
kdf_ctx_t, static_cast<std::size_t>(kdf_context::undefined) + 1U>
|
||||||
|
KDF_CTXS{
|
||||||
|
{
|
||||||
|
{'D', 'A', 'T', 'A', '_', 'C', 'T', 'X'},
|
||||||
|
{'F', 'I', 'L', 'E', '_', 'C', 'T', 'X'},
|
||||||
|
{'D', 'E', 'F', 'L', '_', 'C', 'T', 'X'},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
} // namespace kdf
|
||||||
|
|
||||||
|
[[nodiscard]] constexpr inline auto get_kdf_context_name(kdf_context ctx)
|
||||||
|
-> kdf_ctx_t {
|
||||||
|
const auto idx = static_cast<std::size_t>(ctx);
|
||||||
|
return idx < kdf::KDF_CTXS.size() ? kdf::KDF_CTXS.at(idx)
|
||||||
|
: kdf::KDF_CTXS.back();
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
struct kdf_config final {
|
||||||
|
using salt_t = std::array<std::uint8_t, crypto_pwhash_SALTBYTES>;
|
||||||
|
|
||||||
|
kdf_version version{kdf_version::v1};
|
||||||
|
kdf_type kdf{kdf_type::argon2id};
|
||||||
|
memlimit_level memlimit{memlimit_level::level3};
|
||||||
|
opslimit_level opslimit{opslimit_level::level2};
|
||||||
|
std::uint64_t unique_id{};
|
||||||
|
salt_t salt{};
|
||||||
|
std::uint64_t checksum{};
|
||||||
|
|
||||||
|
template <typename hash_t>
|
||||||
|
[[nodiscard]] auto create_subkey(kdf_context ctx, std::size_t unique_id_,
|
||||||
|
const hash_t &master_key) const
|
||||||
|
-> std::pair<hash_t, kdf_config> {
|
||||||
|
auto sub_key = derive_subkey<hash_t>(ctx, unique_id_, master_key);
|
||||||
|
|
||||||
|
auto cfg = *this;
|
||||||
|
cfg.unique_id = unique_id_;
|
||||||
|
cfg.checksum = cfg.generate_checksum();
|
||||||
|
return {sub_key, cfg};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename hash_t>
|
||||||
|
[[nodiscard]] static auto derive_subkey(kdf_context ctx,
|
||||||
|
std::size_t unique_id_,
|
||||||
|
const hash_t &master_key) -> hash_t {
|
||||||
|
MONITARR_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
|
hash_t sub_key{};
|
||||||
|
auto res = crypto_kdf_derive_from_key(
|
||||||
|
sub_key.data(), sub_key.size(), unique_id_,
|
||||||
|
get_kdf_context_name(ctx).data(), master_key.data());
|
||||||
|
if (res != 0) {
|
||||||
|
throw monitarr::utils::error::create_exception(
|
||||||
|
function_name, {
|
||||||
|
"failed to derive sub-key",
|
||||||
|
std::to_string(res),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return sub_key;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename hash_t>
|
||||||
|
[[nodiscard]] auto recreate_subkey(kdf_context ctx,
|
||||||
|
const hash_t &master_key) const -> hash_t {
|
||||||
|
return derive_subkey<hash_t>(ctx, unique_id, master_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] static auto from_header(data_cspan data, kdf_config &cfg,
|
||||||
|
bool ignore_checksum = false) -> bool;
|
||||||
|
|
||||||
|
[[nodiscard]] auto generate_checksum() const -> std::uint64_t;
|
||||||
|
|
||||||
|
void seal();
|
||||||
|
|
||||||
|
[[nodiscard]] static constexpr auto size() -> std::size_t {
|
||||||
|
return sizeof(kdf_config);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto to_header() const -> data_buffer;
|
||||||
|
|
||||||
|
[[nodiscard]] auto operator==(const kdf_config &) const -> bool = default;
|
||||||
|
[[nodiscard]] auto operator!=(const kdf_config &) const -> bool = default;
|
||||||
|
};
|
||||||
|
#pragma pack(pop)
|
||||||
|
#endif // defined(PROJECT_ENABLE_BOOST)
|
||||||
|
|
||||||
template <typename hash_t>
|
template <typename hash_t>
|
||||||
inline auto generate_key(
|
[[nodiscard]] inline auto generate_key(
|
||||||
std::string_view password,
|
std::string_view password,
|
||||||
std::function<hash_t(const unsigned char *data, std::size_t size)> hasher =
|
std::function<hash_t(const unsigned char *data, std::size_t size)> hasher =
|
||||||
default_create_hash<hash_t>()) -> hash_t;
|
utils::hash::default_create_hash<hash_t>()) -> hash_t;
|
||||||
|
|
||||||
template <typename hash_t>
|
template <typename hash_t>
|
||||||
inline auto generate_key(
|
[[nodiscard]] inline auto generate_key(
|
||||||
std::wstring_view password,
|
std::wstring_view password,
|
||||||
std::function<hash_t(const unsigned char *data, std::size_t size)> hasher =
|
std::function<hash_t(const unsigned char *data, std::size_t size)> hasher =
|
||||||
default_create_hash<hash_t>()) -> hash_t;
|
utils::hash::default_create_hash<hash_t>()) -> hash_t;
|
||||||
|
|
||||||
#if defined(PROJECT_ENABLE_BOOST)
|
#if defined(PROJECT_ENABLE_BOOST)
|
||||||
|
template <typename hash_t>
|
||||||
|
[[nodiscard]] inline auto generate_key(std::string_view password,
|
||||||
|
kdf_config &cfg) -> hash_t;
|
||||||
|
|
||||||
|
template <typename hash_t>
|
||||||
|
[[nodiscard]] inline auto generate_key(std::wstring_view password,
|
||||||
|
kdf_config &cfg) -> hash_t;
|
||||||
|
|
||||||
|
template <typename hash_t>
|
||||||
|
[[nodiscard]] inline auto recreate_key(std::string_view password,
|
||||||
|
const kdf_config &cfg) -> hash_t;
|
||||||
|
|
||||||
|
template <typename hash_t>
|
||||||
|
[[nodiscard]] inline auto recreate_key(std::wstring_view password,
|
||||||
|
const kdf_config &cfg) -> hash_t;
|
||||||
|
|
||||||
|
template <typename string_t>
|
||||||
|
[[nodiscard]] auto create_key_argon2id(string_t password, kdf_config &cfg,
|
||||||
|
utils::hash::hash_256_t &key) -> bool;
|
||||||
|
|
||||||
|
template <typename string_t>
|
||||||
|
[[nodiscard]] auto recreate_key_argon2id(string_t password,
|
||||||
|
const kdf_config &cfg,
|
||||||
|
utils::hash::hash_256_t &key) -> bool;
|
||||||
|
|
||||||
|
template <typename hash_t, typename string_t>
|
||||||
|
[[nodiscard]] inline auto
|
||||||
|
detect_and_recreate_key(string_t password, data_cspan header, hash_t &key,
|
||||||
|
std::optional<kdf_config> &cfg) -> bool;
|
||||||
|
|
||||||
|
template <typename hash_t>
|
||||||
|
[[nodiscard]] inline auto
|
||||||
|
detect_and_recreate_key(std::string_view password, data_cspan header,
|
||||||
|
hash_t &key, std::optional<kdf_config> &cfg) -> bool;
|
||||||
|
|
||||||
|
template <typename hash_t>
|
||||||
|
[[nodiscard]] inline auto
|
||||||
|
detect_and_recreate_key(std::wstring_view password, data_cspan header,
|
||||||
|
hash_t &key, std::optional<kdf_config> &cfg) -> bool;
|
||||||
|
|
||||||
[[nodiscard]] auto decrypt_file_name(std::string_view encryption_token,
|
[[nodiscard]] auto decrypt_file_name(std::string_view encryption_token,
|
||||||
std::string &file_name) -> bool;
|
std::string &file_name) -> bool;
|
||||||
|
|
||||||
[[nodiscard]] auto decrypt_file_path(std::string_view encryption_token,
|
[[nodiscard]] auto decrypt_file_path(std::string_view encryption_token,
|
||||||
std::string &file_path) -> bool;
|
std::string &file_path) -> bool;
|
||||||
|
|
||||||
|
[[nodiscard]] auto decrypt_file_name(std::string_view encryption_token,
|
||||||
|
const kdf_config &cfg,
|
||||||
|
std::string &file_name) -> bool;
|
||||||
|
|
||||||
|
[[nodiscard]] auto decrypt_file_path(std::string_view encryption_token,
|
||||||
|
const kdf_config &cfg,
|
||||||
|
std::string &file_path) -> bool;
|
||||||
|
|
||||||
|
[[nodiscard]] auto decrypt_file_name(const utils::hash::hash_256_t &master_key,
|
||||||
|
std::string &file_name) -> bool;
|
||||||
|
|
||||||
|
[[nodiscard]] auto decrypt_file_path(const utils::hash::hash_256_t &master_key,
|
||||||
|
std::string &file_path) -> bool;
|
||||||
|
|
||||||
template <typename result_t, typename arr_t, std::size_t arr_size>
|
template <typename result_t, typename arr_t, std::size_t arr_size>
|
||||||
[[nodiscard]] inline auto decrypt_data(const std::array<arr_t, arr_size> &key,
|
[[nodiscard]] inline auto decrypt_data(const std::array<arr_t, arr_size> &key,
|
||||||
const unsigned char *buffer,
|
const unsigned char *buffer,
|
||||||
std::size_t buffer_size,
|
std::size_t buffer_size, result_t &res)
|
||||||
result_t &res) -> bool {
|
-> bool {
|
||||||
if (buffer_size > encryption_header_size) {
|
if (buffer_size > encryption_header_size) {
|
||||||
const std::uint32_t size =
|
std::uint32_t size =
|
||||||
boost::endian::native_to_big(static_cast<std::uint32_t>(buffer_size));
|
boost::endian::native_to_big(static_cast<std::uint32_t>(buffer_size));
|
||||||
res.resize(buffer_size - encryption_header_size);
|
res.resize(buffer_size - encryption_header_size);
|
||||||
return crypto_aead_xchacha20poly1305_ietf_decrypt_detached(
|
return crypto_aead_xchacha20poly1305_ietf_decrypt_detached(
|
||||||
@@ -76,32 +283,53 @@ template <typename result_t, typename arr_t, std::size_t arr_size>
|
|||||||
template <typename buffer_t, typename result_t, typename arr_t,
|
template <typename buffer_t, typename result_t, typename arr_t,
|
||||||
std::size_t arr_size>
|
std::size_t arr_size>
|
||||||
[[nodiscard]] inline auto decrypt_data(const std::array<arr_t, arr_size> &key,
|
[[nodiscard]] inline auto decrypt_data(const std::array<arr_t, arr_size> &key,
|
||||||
const buffer_t &buf,
|
const buffer_t &buf, result_t &res)
|
||||||
result_t &res) -> bool {
|
-> bool {
|
||||||
return decrypt_data<result_t>(
|
return decrypt_data<result_t>(
|
||||||
key, reinterpret_cast<const unsigned char *>(buf.data()), buf.size(),
|
key, reinterpret_cast<const unsigned char *>(buf.data()), buf.size(),
|
||||||
res);
|
res);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename buffer_t, typename result_t, typename hash_t = hash_256_t>
|
template <typename buffer_t, typename result_t,
|
||||||
|
typename hash_t = utils::hash::hash_256_t>
|
||||||
[[nodiscard]] inline auto decrypt_data(
|
[[nodiscard]] inline auto decrypt_data(
|
||||||
std::string_view password, const buffer_t &buf, result_t &res,
|
std::string_view password, const buffer_t &buf, result_t &res,
|
||||||
std::function<hash_t(const unsigned char *data, std::size_t size)> hasher =
|
std::function<hash_t(const unsigned char *data, std::size_t size)> hasher =
|
||||||
default_create_hash<hash_t>()) -> bool {
|
utils::hash::default_create_hash<hash_t>()) -> bool {
|
||||||
return decrypt_data<buffer_t, result_t>(generate_key(password, hasher), buf,
|
return decrypt_data<buffer_t, result_t>(generate_key(password, hasher), buf,
|
||||||
res);
|
res);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename result_t, typename hash_t = hash_256_t>
|
template <typename buffer_t, typename result_t,
|
||||||
|
typename hash_t = utils::hash::hash_256_t>
|
||||||
|
[[nodiscard]] inline auto decrypt_data(std::string_view password,
|
||||||
|
const kdf_config &cfg,
|
||||||
|
const buffer_t &buf, result_t &res)
|
||||||
|
-> bool {
|
||||||
|
return decrypt_data<buffer_t, result_t>(recreate_key<hash_t>(password, cfg),
|
||||||
|
buf, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename result_t, typename hash_t = utils::hash::hash_256_t>
|
||||||
[[nodiscard]] inline auto decrypt_data(
|
[[nodiscard]] inline auto decrypt_data(
|
||||||
std::string_view password, const unsigned char *buffer,
|
std::string_view password, const unsigned char *buffer,
|
||||||
std::size_t buffer_size, result_t &res,
|
std::size_t buffer_size, result_t &res,
|
||||||
std::function<hash_t(const unsigned char *data, std::size_t size)> hasher =
|
std::function<hash_t(const unsigned char *data, std::size_t size)> hasher =
|
||||||
default_create_hash<hash_t>()) -> bool {
|
utils::hash::default_create_hash<hash_t>()) -> bool {
|
||||||
return decrypt_data<result_t>(generate_key(password, hasher), buffer,
|
return decrypt_data<result_t>(generate_key(password, hasher), buffer,
|
||||||
buffer_size, res);
|
buffer_size, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename result_t, typename hash_t = utils::hash::hash_256_t>
|
||||||
|
[[nodiscard]] inline auto decrypt_data(std::string_view password,
|
||||||
|
const kdf_config &cfg,
|
||||||
|
const unsigned char *buffer,
|
||||||
|
std::size_t buffer_size, result_t &res)
|
||||||
|
-> bool {
|
||||||
|
return decrypt_data<result_t>(recreate_key<hash_t>(password, cfg), buffer,
|
||||||
|
buffer_size, res);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename result_t, typename arr_t, std::size_t arr_size>
|
template <typename result_t, typename arr_t, std::size_t arr_size>
|
||||||
inline void
|
inline void
|
||||||
encrypt_data(const std::array<unsigned char,
|
encrypt_data(const std::array<unsigned char,
|
||||||
@@ -144,26 +372,44 @@ inline void encrypt_data(const std::array<arr_t, arr_size> &key,
|
|||||||
encrypt_data<result_t>(iv, key, buffer, buffer_size, res);
|
encrypt_data<result_t>(iv, key, buffer, buffer_size, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename result_t, typename hash_t = hash_256_t>
|
template <typename result_t, typename hash_t = utils::hash::hash_256_t>
|
||||||
inline void encrypt_data(
|
inline void encrypt_data(
|
||||||
std::string_view password, const unsigned char *buffer,
|
std::string_view password, const unsigned char *buffer,
|
||||||
std::size_t buffer_size, result_t &res,
|
std::size_t buffer_size, result_t &res,
|
||||||
std::function<hash_t(const unsigned char *data, std::size_t size)> hasher =
|
std::function<hash_t(const unsigned char *data, std::size_t size)> hasher =
|
||||||
default_create_hash<hash_t>()) {
|
utils::hash::default_create_hash<hash_t>()) {
|
||||||
encrypt_data<result_t>(generate_key(password, hasher), buffer, buffer_size,
|
encrypt_data<result_t>(generate_key(password, hasher), buffer, buffer_size,
|
||||||
res);
|
res);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename buffer_t, typename result_t, typename hash_t = hash_256_t>
|
template <typename result_t, typename hash_t = utils::hash::hash_256_t>
|
||||||
|
inline void encrypt_data(std::string_view password, kdf_config &cfg,
|
||||||
|
const unsigned char *buffer, std::size_t buffer_size,
|
||||||
|
result_t &res) {
|
||||||
|
encrypt_data<result_t>(generate_key<hash_t>(password, cfg), buffer,
|
||||||
|
buffer_size, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename buffer_t, typename result_t,
|
||||||
|
typename hash_t = utils::hash::hash_256_t>
|
||||||
inline void encrypt_data(
|
inline void encrypt_data(
|
||||||
std::string_view password, const buffer_t &buf, result_t &res,
|
std::string_view password, const buffer_t &buf, result_t &res,
|
||||||
std::function<hash_t(const unsigned char *data, std::size_t size)> hasher =
|
std::function<hash_t(const unsigned char *data, std::size_t size)> hasher =
|
||||||
default_create_hash<hash_t>()) {
|
utils::hash::default_create_hash<hash_t>()) {
|
||||||
encrypt_data<result_t>(generate_key(password, hasher),
|
encrypt_data<result_t>(generate_key(password, hasher),
|
||||||
reinterpret_cast<const unsigned char *>(buf.data()),
|
reinterpret_cast<const unsigned char *>(buf.data()),
|
||||||
buf.size(), res);
|
buf.size(), res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename buffer_t, typename result_t,
|
||||||
|
typename hash_t = utils::hash::hash_256_t>
|
||||||
|
inline void encrypt_data(std::string_view password, kdf_config &cfg,
|
||||||
|
const buffer_t &buf, result_t &res) {
|
||||||
|
encrypt_data<result_t>(generate_key<hash_t>(password, cfg),
|
||||||
|
reinterpret_cast<const unsigned char *>(buf.data()),
|
||||||
|
buf.size(), res);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename buffer_t, typename result_t, typename arr_t,
|
template <typename buffer_t, typename result_t, typename arr_t,
|
||||||
std::size_t arr_size>
|
std::size_t arr_size>
|
||||||
inline void encrypt_data(const std::array<arr_t, arr_size> &key,
|
inline void encrypt_data(const std::array<arr_t, arr_size> &key,
|
||||||
@@ -189,16 +435,52 @@ using reader_func_t =
|
|||||||
std::function<bool(data_buffer &cypher_text, std::uint64_t start_offset,
|
std::function<bool(data_buffer &cypher_text, std::uint64_t start_offset,
|
||||||
std::uint64_t end_offset)>;
|
std::uint64_t end_offset)>;
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto read_encrypted_range(const http_range &range,
|
||||||
read_encrypted_range(const http_range &range,
|
const utils::hash::hash_256_t &key,
|
||||||
const utils::encryption::hash_256_t &key,
|
bool uses_kdf,
|
||||||
reader_func_t reader_func, std::uint64_t total_size,
|
reader_func_t reader_func,
|
||||||
|
std::uint64_t total_size,
|
||||||
data_buffer &data) -> bool;
|
data_buffer &data) -> bool;
|
||||||
|
|
||||||
[[nodiscard]] auto read_encrypted_range(
|
[[nodiscard]] auto read_encrypted_range(
|
||||||
const http_range &range, const utils::encryption::hash_256_t &key,
|
const http_range &range, const utils::hash::hash_256_t &key, bool uses_kdf,
|
||||||
reader_func_t reader_func, std::uint64_t total_size, unsigned char *data,
|
reader_func_t reader_func, std::uint64_t total_size, unsigned char *data,
|
||||||
std::size_t size, std::size_t &bytes_read) -> bool;
|
std::size_t size, std::size_t &bytes_read) -> bool;
|
||||||
|
|
||||||
|
[[nodiscard]] inline auto
|
||||||
|
read_encrypted_range(const http_range &range,
|
||||||
|
const utils::hash::hash_256_t &key,
|
||||||
|
reader_func_t reader_func, std::uint64_t total_size,
|
||||||
|
data_buffer &data) -> bool {
|
||||||
|
return read_encrypted_range(range, key, false, reader_func, total_size, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline auto read_encrypted_range(
|
||||||
|
const http_range &range, const utils::hash::hash_256_t &key,
|
||||||
|
reader_func_t reader_func, std::uint64_t total_size, unsigned char *data,
|
||||||
|
std::size_t size, std::size_t &bytes_read) -> bool {
|
||||||
|
return read_encrypted_range(range, key, false, reader_func, total_size, data,
|
||||||
|
size, bytes_read);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename string_t>
|
||||||
|
auto create_key_argon2id(string_t password, kdf_config &cfg,
|
||||||
|
utils::hash::hash_256_t &key) -> bool {
|
||||||
|
cfg.seal();
|
||||||
|
|
||||||
|
return recreate_key_argon2id(password, cfg, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename string_t>
|
||||||
|
auto recreate_key_argon2id(string_t password, const kdf_config &cfg,
|
||||||
|
utils::hash::hash_256_t &key) -> bool {
|
||||||
|
return crypto_pwhash(
|
||||||
|
reinterpret_cast<unsigned char *>(key.data()), key.size(),
|
||||||
|
reinterpret_cast<const char *>(password.data()),
|
||||||
|
password.size() * sizeof(typename string_t::value_type),
|
||||||
|
cfg.salt.data(), get_opslimit(cfg.opslimit),
|
||||||
|
get_memlimit(cfg.memlimit), crypto_pwhash_ALG_ARGON2ID13) == 0;
|
||||||
|
}
|
||||||
#endif // defined(PROJECT_ENABLE_BOOST)
|
#endif // defined(PROJECT_ENABLE_BOOST)
|
||||||
|
|
||||||
template <typename hash_t>
|
template <typename hash_t>
|
||||||
@@ -218,7 +500,223 @@ inline auto generate_key(
|
|||||||
return hasher(reinterpret_cast<const unsigned char *>(password.data()),
|
return hasher(reinterpret_cast<const unsigned char *>(password.data()),
|
||||||
password.size() * sizeof(wchar_t));
|
password.size() * sizeof(wchar_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(PROJECT_ENABLE_BOOST)
|
||||||
|
template <typename hash_t, typename string_t>
|
||||||
|
inline auto generate_key_impl(string_t password, kdf_config &cfg) -> hash_t {
|
||||||
|
MONITARR_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
|
switch (cfg.version) {
|
||||||
|
case kdf_version::v1:
|
||||||
|
switch (cfg.kdf) {
|
||||||
|
case kdf_type::argon2id: {
|
||||||
|
hash_t key{};
|
||||||
|
if (not create_key_argon2id(password, cfg, key)) {
|
||||||
|
throw utils::error::create_exception(
|
||||||
|
function_name, {
|
||||||
|
"failed to generate argon2id key",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw utils::error::create_exception(
|
||||||
|
function_name, {
|
||||||
|
"unsupported kdf type",
|
||||||
|
std::to_string(static_cast<std::uint8_t>(cfg.kdf)),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw utils::error::create_exception(
|
||||||
|
function_name,
|
||||||
|
{
|
||||||
|
"unsupported kdf version",
|
||||||
|
std::to_string(static_cast<std::uint8_t>(cfg.version)),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename hash_t, typename string_t>
|
||||||
|
inline auto recreate_key_impl(string_t password, const kdf_config &cfg)
|
||||||
|
-> hash_t {
|
||||||
|
MONITARR_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
|
switch (cfg.version) {
|
||||||
|
case kdf_version::v1:
|
||||||
|
switch (cfg.kdf) {
|
||||||
|
case kdf_type::argon2id: {
|
||||||
|
hash_t key{};
|
||||||
|
if (not recreate_key_argon2id(password, cfg, key)) {
|
||||||
|
throw utils::error::create_exception(
|
||||||
|
function_name, {
|
||||||
|
"failed to generate argon2id key",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw utils::error::create_exception(
|
||||||
|
function_name, {
|
||||||
|
"unsupported kdf type",
|
||||||
|
std::to_string(static_cast<std::uint8_t>(cfg.kdf)),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw utils::error::create_exception(
|
||||||
|
function_name,
|
||||||
|
{
|
||||||
|
"unsupported kdf version",
|
||||||
|
std::to_string(static_cast<std::uint8_t>(cfg.version)),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename hash_t>
|
||||||
|
inline auto generate_key(std::string_view password, kdf_config &cfg) -> hash_t {
|
||||||
|
return generate_key_impl<hash_t, std::string_view>(password, cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename hash_t>
|
||||||
|
inline auto generate_key(std::wstring_view password, kdf_config &cfg)
|
||||||
|
-> hash_t {
|
||||||
|
return generate_key_impl<hash_t, std::wstring_view>(password, cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename hash_t>
|
||||||
|
inline auto recreate_key(std::string_view password, const kdf_config &cfg)
|
||||||
|
-> hash_t {
|
||||||
|
return recreate_key_impl<hash_t, std::string_view>(password, cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename hash_t>
|
||||||
|
inline auto recreate_key(std::wstring_view password, const kdf_config &cfg)
|
||||||
|
-> hash_t {
|
||||||
|
return recreate_key_impl<hash_t, std::wstring_view>(password, cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename hash_t, typename string_t>
|
||||||
|
inline auto detect_and_recreate_key(string_t password, data_cspan header,
|
||||||
|
hash_t &key, std::optional<kdf_config> &cfg)
|
||||||
|
-> bool {
|
||||||
|
if (header.size() >= kdf_config::size()) {
|
||||||
|
kdf_config tmp{};
|
||||||
|
if (kdf_config::from_header(header.first(kdf_config::size()), tmp)) {
|
||||||
|
cfg = tmp;
|
||||||
|
key = recreate_key<hash_t>(password, *cfg);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
key = generate_key<hash_t>(password);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename hash_t>
|
||||||
|
inline auto detect_and_recreate_key(std::string_view password,
|
||||||
|
data_cspan header, hash_t &key,
|
||||||
|
std::optional<kdf_config> &cfg) -> bool {
|
||||||
|
return detect_and_recreate_key<hash_t, std::string_view>(password, header,
|
||||||
|
key, cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename hash_t>
|
||||||
|
inline auto detect_and_recreate_key(std::wstring_view password,
|
||||||
|
data_cspan header, hash_t &key,
|
||||||
|
std::optional<kdf_config> &cfg) -> bool {
|
||||||
|
return detect_and_recreate_key<hash_t, std::wstring_view>(password, header,
|
||||||
|
key, cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // defined(PROJECT_ENABLE_BOOST)
|
||||||
} // namespace monitarr::utils::encryption
|
} // namespace monitarr::utils::encryption
|
||||||
|
|
||||||
|
#if defined(PROJECT_ENABLE_BOOST) && defined(PROJECT_ENABLE_JSON)
|
||||||
|
NLOHMANN_JSON_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
namespace kdf {
|
||||||
|
inline constexpr std::string_view JSON_CHECKSUM{"checksum"};
|
||||||
|
inline constexpr std::string_view JSON_KDF{"kdf"};
|
||||||
|
inline constexpr std::string_view JSON_MEMLIMIT{"memlimit"};
|
||||||
|
inline constexpr std::string_view JSON_OPSLIMIT{"opslimit"};
|
||||||
|
inline constexpr std::string_view JSON_SALT{"salt"};
|
||||||
|
inline constexpr std::string_view JSON_UNIQUE_ID{"unique_id"};
|
||||||
|
inline constexpr std::string_view JSON_VERSION{"version"};
|
||||||
|
} // namespace kdf
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct adl_serializer<monitarr::utils::encryption::kdf_config::salt_t> {
|
||||||
|
static void
|
||||||
|
to_json(json &data,
|
||||||
|
const monitarr::utils::encryption::kdf_config::salt_t &value) {
|
||||||
|
data = monitarr::utils::collection::to_hex_string(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
from_json(const json &data,
|
||||||
|
monitarr::utils::encryption::kdf_config::salt_t &value) {
|
||||||
|
MONITARR_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
|
monitarr::data_buffer buffer{};
|
||||||
|
if (not monitarr::utils::collection::from_hex_string(
|
||||||
|
data.get<std::string>(), buffer)) {
|
||||||
|
throw monitarr::utils::error::create_exception(
|
||||||
|
function_name, {
|
||||||
|
"failed to convert hex string to salt",
|
||||||
|
data.get<std::string>(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buffer.size() != value.size()) {
|
||||||
|
throw monitarr::utils::error::create_exception(
|
||||||
|
function_name, {
|
||||||
|
"unexpected length for salt after hex conversion",
|
||||||
|
"expected",
|
||||||
|
std::to_string(value.size()),
|
||||||
|
"actual",
|
||||||
|
std::to_string(buffer.size()),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
std::copy_n(buffer.begin(), value.size(), value.begin());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <> struct adl_serializer<monitarr::utils::encryption::kdf_config> {
|
||||||
|
static void to_json(json &data,
|
||||||
|
const monitarr::utils::encryption::kdf_config &value) {
|
||||||
|
data[kdf::JSON_CHECKSUM] = value.checksum;
|
||||||
|
data[kdf::JSON_KDF] = value.kdf;
|
||||||
|
data[kdf::JSON_MEMLIMIT] = value.memlimit;
|
||||||
|
data[kdf::JSON_OPSLIMIT] = value.opslimit;
|
||||||
|
data[kdf::JSON_SALT] = value.salt;
|
||||||
|
data[kdf::JSON_UNIQUE_ID] = value.unique_id;
|
||||||
|
data[kdf::JSON_VERSION] = value.version;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void from_json(const json &data,
|
||||||
|
monitarr::utils::encryption::kdf_config &value) {
|
||||||
|
data.at(kdf::JSON_CHECKSUM).get_to<std::uint64_t>(value.checksum);
|
||||||
|
data.at(kdf::JSON_KDF)
|
||||||
|
.get_to<monitarr::utils::encryption::kdf_type>(value.kdf);
|
||||||
|
data.at(kdf::JSON_MEMLIMIT)
|
||||||
|
.get_to<monitarr::utils::encryption::memlimit_level>(value.memlimit);
|
||||||
|
data.at(kdf::JSON_OPSLIMIT)
|
||||||
|
.get_to<monitarr::utils::encryption::opslimit_level>(value.opslimit);
|
||||||
|
data.at(kdf::JSON_SALT)
|
||||||
|
.get_to<monitarr::utils::encryption::kdf_config::salt_t>(value.salt);
|
||||||
|
data.at(kdf::JSON_UNIQUE_ID).get_to<std::uint64_t>(value.unique_id);
|
||||||
|
data.at(kdf::JSON_VERSION)
|
||||||
|
.get_to<monitarr::utils::encryption::kdf_version>(value.version);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
NLOHMANN_JSON_NAMESPACE_END
|
||||||
|
#endif // defined(PROJECT_ENABLE_BOOST) && defined(PROJECT_ENABLE_JSON)
|
||||||
|
|
||||||
#endif // defined(PROJECT_ENABLE_LIBSODIUM)
|
#endif // defined(PROJECT_ENABLE_LIBSODIUM)
|
||||||
#endif // MONITARR_INCLUDE_UTILS_ENCRYPTION_HPP_
|
#endif // MONITARR_INCLUDE_UTILS_ENCRYPTION_HPP_
|
||||||
|
|||||||
@@ -30,6 +30,10 @@
|
|||||||
#include "utils/types/file/i_file.hpp"
|
#include "utils/types/file/i_file.hpp"
|
||||||
#include "utils/types/file/i_fs_item.hpp"
|
#include "utils/types/file/i_fs_item.hpp"
|
||||||
|
|
||||||
|
namespace monitarr::utils::directory {
|
||||||
|
[[nodiscard]] auto temp() -> std::string;
|
||||||
|
}
|
||||||
|
|
||||||
namespace monitarr::utils::file {
|
namespace monitarr::utils::file {
|
||||||
[[nodiscard]] auto change_to_process_directory() -> bool;
|
[[nodiscard]] auto change_to_process_directory() -> bool;
|
||||||
|
|
||||||
@@ -37,13 +41,13 @@ namespace monitarr::utils::file {
|
|||||||
[[nodiscard]] auto create_temp_name(std::string_view file_part) -> std::string;
|
[[nodiscard]] auto create_temp_name(std::string_view file_part) -> std::string;
|
||||||
|
|
||||||
// INFO: has test
|
// INFO: has test
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto create_temp_name(std::wstring_view file_part)
|
||||||
create_temp_name(std::wstring_view file_part) -> std::wstring;
|
-> std::wstring;
|
||||||
|
|
||||||
// INFO: has test
|
// INFO: has test
|
||||||
[[nodiscard]] inline auto
|
[[nodiscard]] inline auto
|
||||||
directory_exists_in_path(std::string_view path,
|
directory_exists_in_path(std::string_view path, std::string_view sub_directory)
|
||||||
std::string_view sub_directory) -> bool;
|
-> bool;
|
||||||
|
|
||||||
// INFO: has test
|
// INFO: has test
|
||||||
[[nodiscard]] inline auto
|
[[nodiscard]] inline auto
|
||||||
@@ -51,45 +55,46 @@ directory_exists_in_path(std::wstring_view path,
|
|||||||
std::wstring_view sub_directory) -> bool;
|
std::wstring_view sub_directory) -> bool;
|
||||||
|
|
||||||
// INFO: has test
|
// INFO: has test
|
||||||
[[nodiscard]] inline auto
|
[[nodiscard]] inline auto file_exists_in_path(std::string_view path,
|
||||||
file_exists_in_path(std::string_view path, std::string_view file_name) -> bool;
|
std::string_view file_name)
|
||||||
|
-> bool;
|
||||||
|
|
||||||
// INFO: has test
|
// INFO: has test
|
||||||
[[nodiscard]] inline auto
|
[[nodiscard]] inline auto file_exists_in_path(std::wstring_view path,
|
||||||
file_exists_in_path(std::wstring_view path,
|
std::wstring_view file_name)
|
||||||
std::wstring_view file_name) -> bool;
|
-> bool;
|
||||||
|
|
||||||
// INFO: has test
|
// INFO: has test
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto get_free_drive_space(std::string_view path)
|
||||||
get_free_drive_space(std::string_view path) -> std::optional<std::uint64_t>;
|
-> std::optional<std::uint64_t>;
|
||||||
|
|
||||||
// INFO: has test
|
// INFO: has test
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto get_free_drive_space(std::wstring_view path)
|
||||||
get_free_drive_space(std::wstring_view path) -> std::optional<std::uint64_t>;
|
-> std::optional<std::uint64_t>;
|
||||||
|
|
||||||
// INFO: has test
|
// INFO: has test
|
||||||
[[nodiscard]] auto get_time(std::string_view path,
|
[[nodiscard]] auto get_time(std::string_view path, time_type type)
|
||||||
time_type type) -> std::optional<std::uint64_t>;
|
-> std::optional<std::uint64_t>;
|
||||||
|
|
||||||
// INFO: has test
|
// INFO: has test
|
||||||
[[nodiscard]] auto get_time(std::wstring_view path,
|
[[nodiscard]] auto get_time(std::wstring_view path, time_type type)
|
||||||
time_type type) -> std::optional<std::uint64_t>;
|
-> std::optional<std::uint64_t>;
|
||||||
|
|
||||||
// INFO: has test
|
// INFO: has test
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto get_times(std::string_view path)
|
||||||
get_times(std::string_view path) -> std::optional<file_times>;
|
-> std::optional<file_times>;
|
||||||
|
|
||||||
// INFO: has test
|
// INFO: has test
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto get_times(std::wstring_view path)
|
||||||
get_times(std::wstring_view path) -> std::optional<file_times>;
|
-> std::optional<file_times>;
|
||||||
|
|
||||||
// INFO: has test
|
// INFO: has test
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto get_total_drive_space(std::string_view path)
|
||||||
get_total_drive_space(std::string_view path) -> std::optional<std::uint64_t>;
|
-> std::optional<std::uint64_t>;
|
||||||
|
|
||||||
// INFO: has test
|
// INFO: has test
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto get_total_drive_space(std::wstring_view path)
|
||||||
get_total_drive_space(std::wstring_view path) -> std::optional<std::uint64_t>;
|
-> std::optional<std::uint64_t>;
|
||||||
|
|
||||||
#if defined(PROJECT_ENABLE_LIBDSM)
|
#if defined(PROJECT_ENABLE_LIBDSM)
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto
|
||||||
@@ -97,20 +102,20 @@ smb_create_and_validate_relative_path(std::string_view smb_path,
|
|||||||
std::string_view rel_path) -> std::string;
|
std::string_view rel_path) -> std::string;
|
||||||
|
|
||||||
// INFO: has test
|
// INFO: has test
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto smb_create_relative_path(std::string_view smb_path)
|
||||||
smb_create_relative_path(std::string_view smb_path) -> std::string;
|
-> std::string;
|
||||||
|
|
||||||
// INFO: has test
|
// INFO: has test
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto smb_create_search_path(std::string_view smb_path)
|
||||||
smb_create_search_path(std::string_view smb_path) -> std::string;
|
-> std::string;
|
||||||
|
|
||||||
// INFO: has test
|
// INFO: has test
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto smb_create_smb_path(std::string_view smb_path,
|
||||||
smb_create_smb_path(std::string_view smb_path,
|
std::string_view rel_path)
|
||||||
std::string_view rel_path) -> std::string;
|
-> std::string;
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto smb_get_parent_path(std::string_view smb_path)
|
||||||
smb_get_parent_path(std::string_view smb_path) -> std::string;
|
-> std::string;
|
||||||
|
|
||||||
[[nodiscard]] auto smb_get_root_path(std::string_view smb_path) -> std::string;
|
[[nodiscard]] auto smb_get_root_path(std::string_view smb_path) -> std::string;
|
||||||
|
|
||||||
@@ -139,27 +144,30 @@ read_json_file(std::string_view path, nlohmann::json &data,
|
|||||||
std::optional<std::string_view> password = std::nullopt) -> bool;
|
std::optional<std::string_view> password = std::nullopt) -> bool;
|
||||||
|
|
||||||
// INFO: has test
|
// INFO: has test
|
||||||
[[nodiscard]] auto read_json_file(
|
[[nodiscard]] auto
|
||||||
std::wstring_view path, nlohmann::json &data,
|
read_json_file(std::wstring_view path, nlohmann::json &data,
|
||||||
std::optional<std::wstring_view> password = std::nullopt) -> bool;
|
std::optional<std::wstring_view> password = std::nullopt)
|
||||||
|
-> bool;
|
||||||
|
|
||||||
// INFO: has test
|
// INFO: has test
|
||||||
[[nodiscard]] auto write_json_file(
|
[[nodiscard]] auto
|
||||||
std::string_view path, const nlohmann::json &data,
|
write_json_file(std::string_view path, const nlohmann::json &data,
|
||||||
std::optional<std::string_view> password = std::nullopt) -> bool;
|
std::optional<std::string_view> password = std::nullopt)
|
||||||
|
-> bool;
|
||||||
|
|
||||||
// INFO: has test
|
// INFO: has test
|
||||||
[[nodiscard]] auto write_json_file(
|
[[nodiscard]] auto
|
||||||
std::wstring_view path, const nlohmann::json &data,
|
write_json_file(std::wstring_view path, const nlohmann::json &data,
|
||||||
std::optional<std::wstring_view> password = std::nullopt) -> bool;
|
std::optional<std::wstring_view> password = std::nullopt)
|
||||||
|
-> bool;
|
||||||
#else // !defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)
|
#else // !defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)
|
||||||
// INFO: has test
|
// INFO: has test
|
||||||
[[nodiscard]] auto read_json_file(std::string_view path,
|
[[nodiscard]] auto read_json_file(std::string_view path, nlohmann::json &data)
|
||||||
nlohmann::json &data) -> bool;
|
-> bool;
|
||||||
|
|
||||||
// INFO: has test
|
// INFO: has test
|
||||||
[[nodiscard]] auto read_json_file(std::wstring_view path,
|
[[nodiscard]] auto read_json_file(std::wstring_view path, nlohmann::json &data)
|
||||||
nlohmann::json &data) -> bool;
|
-> bool;
|
||||||
|
|
||||||
// INFO: has test
|
// INFO: has test
|
||||||
[[nodiscard]] auto write_json_file(std::string_view path,
|
[[nodiscard]] auto write_json_file(std::string_view path,
|
||||||
|
|||||||
@@ -49,28 +49,28 @@ private:
|
|||||||
stop_type *stop_requested_{nullptr};
|
stop_type *stop_requested_{nullptr};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
[[nodiscard]] auto copy_to(std::string_view new_path,
|
[[nodiscard]] auto copy_to(std::string_view new_path, bool overwrite) const
|
||||||
bool overwrite) const -> bool override;
|
-> bool override;
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto count(bool recursive = false) const
|
||||||
count(bool recursive = false) const -> std::uint64_t override;
|
-> std::uint64_t override;
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto create_directory(std::string_view path = "") const
|
||||||
create_directory(std::string_view path = "") const -> fs_directory_t override;
|
-> fs_directory_t override;
|
||||||
|
|
||||||
[[nodiscard]] auto create_file(std::string_view file_name,
|
[[nodiscard]] auto create_file(std::string_view file_name,
|
||||||
bool read_only) const -> fs_file_t override;
|
bool read_only) const -> fs_file_t override;
|
||||||
|
|
||||||
[[nodiscard]] auto exists() const -> bool override;
|
[[nodiscard]] auto exists() const -> bool override;
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto get_directory(std::string_view path) const
|
||||||
get_directory(std::string_view path) const -> fs_directory_t override;
|
-> fs_directory_t override;
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto get_directories() const
|
||||||
get_directories() const -> std::vector<fs_directory_t> override;
|
-> std::vector<fs_directory_t> override;
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto get_file(std::string_view path) const
|
||||||
get_file(std::string_view path) const -> fs_file_t override;
|
-> fs_file_t override;
|
||||||
|
|
||||||
[[nodiscard]] auto get_files() const -> std::vector<fs_file_t> override;
|
[[nodiscard]] auto get_files() const -> std::vector<fs_file_t> override;
|
||||||
|
|
||||||
@@ -88,8 +88,8 @@ public:
|
|||||||
|
|
||||||
[[nodiscard]] auto remove_recursively() -> bool override;
|
[[nodiscard]] auto remove_recursively() -> bool override;
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto size(bool recursive = false) const
|
||||||
size(bool recursive = false) const -> std::uint64_t override;
|
-> std::uint64_t override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
auto operator=(const directory &) noexcept -> directory & = delete;
|
auto operator=(const directory &) noexcept -> directory & = delete;
|
||||||
|
|||||||
@@ -27,32 +27,55 @@
|
|||||||
|
|
||||||
#include "utils/error.hpp"
|
#include "utils/error.hpp"
|
||||||
|
|
||||||
namespace monitarr::utils::encryption {
|
namespace monitarr::utils::hash {
|
||||||
|
using hash_32_t = std::array<unsigned char, 4U>;
|
||||||
|
using hash_64_t = std::array<unsigned char, 8U>;
|
||||||
|
using hash_128_t = std::array<unsigned char, 16U>;
|
||||||
using hash_256_t = std::array<unsigned char, 32U>;
|
using hash_256_t = std::array<unsigned char, 32U>;
|
||||||
using hash_384_t = std::array<unsigned char, 48U>;
|
using hash_384_t = std::array<unsigned char, 48U>;
|
||||||
using hash_512_t = std::array<unsigned char, 64U>;
|
using hash_512_t = std::array<unsigned char, 64U>;
|
||||||
|
|
||||||
|
[[nodiscard]] auto create_hash_blake2b_32(std::string_view data) -> hash_32_t;
|
||||||
|
|
||||||
|
[[nodiscard]] auto create_hash_blake2b_32(std::wstring_view data) -> hash_32_t;
|
||||||
|
|
||||||
|
[[nodiscard]] auto create_hash_blake2b_32(const data_buffer &data) -> hash_32_t;
|
||||||
|
|
||||||
|
[[nodiscard]] auto create_hash_blake2b_64(std::string_view data) -> hash_64_t;
|
||||||
|
|
||||||
|
[[nodiscard]] auto create_hash_blake2b_64(std::wstring_view data) -> hash_64_t;
|
||||||
|
|
||||||
|
[[nodiscard]] auto create_hash_blake2b_64(const data_buffer &data) -> hash_64_t;
|
||||||
|
|
||||||
|
[[nodiscard]] auto create_hash_blake2b_128(std::string_view data) -> hash_128_t;
|
||||||
|
|
||||||
|
[[nodiscard]] auto create_hash_blake2b_128(std::wstring_view data)
|
||||||
|
-> hash_128_t;
|
||||||
|
|
||||||
|
[[nodiscard]] auto create_hash_blake2b_128(const data_buffer &data)
|
||||||
|
-> hash_128_t;
|
||||||
|
|
||||||
[[nodiscard]] auto create_hash_blake2b_256(std::string_view data) -> hash_256_t;
|
[[nodiscard]] auto create_hash_blake2b_256(std::string_view data) -> hash_256_t;
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto create_hash_blake2b_256(std::wstring_view data)
|
||||||
create_hash_blake2b_256(std::wstring_view data) -> hash_256_t;
|
-> hash_256_t;
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto create_hash_blake2b_256(const data_buffer &data)
|
||||||
create_hash_blake2b_256(const data_buffer &data) -> hash_256_t;
|
-> hash_256_t;
|
||||||
|
|
||||||
[[nodiscard]] auto create_hash_blake2b_384(std::string_view data) -> hash_384_t;
|
[[nodiscard]] auto create_hash_blake2b_384(std::string_view data) -> hash_384_t;
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto create_hash_blake2b_384(std::wstring_view data)
|
||||||
create_hash_blake2b_384(std::wstring_view data) -> hash_384_t;
|
-> hash_384_t;
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto create_hash_blake2b_384(const data_buffer &data)
|
||||||
create_hash_blake2b_384(const data_buffer &data) -> hash_384_t;
|
-> hash_384_t;
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto create_hash_blake2b_512(std::wstring_view data)
|
||||||
create_hash_blake2b_512(std::wstring_view data) -> hash_512_t;
|
-> hash_512_t;
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto create_hash_blake2b_512(const data_buffer &data)
|
||||||
create_hash_blake2b_512(const data_buffer &data) -> hash_512_t;
|
-> hash_512_t;
|
||||||
|
|
||||||
[[nodiscard]] auto create_hash_blake2b_512(std::string_view data) -> hash_512_t;
|
[[nodiscard]] auto create_hash_blake2b_512(std::string_view data) -> hash_512_t;
|
||||||
|
|
||||||
@@ -83,8 +106,8 @@ template <typename hash_t>
|
|||||||
std::function<hash_t(const unsigned char *data, std::size_t size)> &;
|
std::function<hash_t(const unsigned char *data, std::size_t size)> &;
|
||||||
|
|
||||||
template <typename hash_t>
|
template <typename hash_t>
|
||||||
auto create_hash_blake2b_t(const unsigned char *data,
|
auto create_hash_blake2b_t(const unsigned char *data, std::size_t data_size)
|
||||||
std::size_t data_size) -> hash_t {
|
-> hash_t {
|
||||||
MONITARR_USES_FUNCTION_NAME();
|
MONITARR_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
hash_t hash{};
|
hash_t hash{};
|
||||||
@@ -123,6 +146,27 @@ auto create_hash_blake2b_t(const unsigned char *data,
|
|||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline const std::function<hash_32_t(const unsigned char *data,
|
||||||
|
std::size_t size)>
|
||||||
|
blake2b_32_hasher =
|
||||||
|
[](const unsigned char *data, std::size_t data_size) -> hash_32_t {
|
||||||
|
return create_hash_blake2b_t<hash_32_t>(data, data_size);
|
||||||
|
};
|
||||||
|
|
||||||
|
inline const std::function<hash_64_t(const unsigned char *data,
|
||||||
|
std::size_t size)>
|
||||||
|
blake2b_64_hasher =
|
||||||
|
[](const unsigned char *data, std::size_t data_size) -> hash_64_t {
|
||||||
|
return create_hash_blake2b_t<hash_64_t>(data, data_size);
|
||||||
|
};
|
||||||
|
|
||||||
|
inline const std::function<hash_128_t(const unsigned char *data,
|
||||||
|
std::size_t size)>
|
||||||
|
blake2b_128_hasher =
|
||||||
|
[](const unsigned char *data, std::size_t data_size) -> hash_128_t {
|
||||||
|
return create_hash_blake2b_t<hash_128_t>(data, data_size);
|
||||||
|
};
|
||||||
|
|
||||||
inline const std::function<hash_256_t(const unsigned char *data,
|
inline const std::function<hash_256_t(const unsigned char *data,
|
||||||
std::size_t size)>
|
std::size_t size)>
|
||||||
blake2b_256_hasher =
|
blake2b_256_hasher =
|
||||||
@@ -158,6 +202,24 @@ inline const std::function<hash_512_t(const unsigned char *data,
|
|||||||
return create_hash_sha512(data, data_size);
|
return create_hash_sha512(data, data_size);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
[[nodiscard]] inline auto default_create_hash<hash_32_t>() -> const
|
||||||
|
std::function<hash_32_t(const unsigned char *data, std::size_t size)> & {
|
||||||
|
return blake2b_32_hasher;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
[[nodiscard]] inline auto default_create_hash<hash_64_t>() -> const
|
||||||
|
std::function<hash_64_t(const unsigned char *data, std::size_t size)> & {
|
||||||
|
return blake2b_64_hasher;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
[[nodiscard]] inline auto default_create_hash<hash_128_t>() -> const
|
||||||
|
std::function<hash_128_t(const unsigned char *data, std::size_t size)> & {
|
||||||
|
return blake2b_128_hasher;
|
||||||
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
[[nodiscard]] inline auto default_create_hash<hash_256_t>() -> const
|
[[nodiscard]] inline auto default_create_hash<hash_256_t>() -> const
|
||||||
std::function<hash_256_t(const unsigned char *data, std::size_t size)> & {
|
std::function<hash_256_t(const unsigned char *data, std::size_t size)> & {
|
||||||
@@ -175,7 +237,7 @@ template <>
|
|||||||
std::function<hash_512_t(const unsigned char *data, std::size_t size)> & {
|
std::function<hash_512_t(const unsigned char *data, std::size_t size)> & {
|
||||||
return blake2b_512_hasher;
|
return blake2b_512_hasher;
|
||||||
}
|
}
|
||||||
} // namespace monitarr::utils::encryption
|
} // namespace monitarr::utils::hash
|
||||||
|
|
||||||
#endif // defined(PROJECT_ENABLE_LIBSODIUM)
|
#endif // defined(PROJECT_ENABLE_LIBSODIUM)
|
||||||
#endif // MONITARR_INCLUDE_UTILS_HASH_HPP_
|
#endif // MONITARR_INCLUDE_UTILS_HASH_HPP_
|
||||||
|
|||||||
@@ -26,30 +26,30 @@
|
|||||||
#include "utils/string.hpp"
|
#include "utils/string.hpp"
|
||||||
|
|
||||||
namespace monitarr::utils::path {
|
namespace monitarr::utils::path {
|
||||||
inline constexpr const std::string_view backslash{"\\"};
|
inline constexpr std::string_view backslash{"\\"};
|
||||||
inline constexpr const std::wstring_view backslash_w{L"\\"};
|
inline constexpr std::wstring_view backslash_w{L"\\"};
|
||||||
inline constexpr const std::string_view dot{"."};
|
inline constexpr std::string_view dot{"."};
|
||||||
inline constexpr const std::wstring_view dot_w{L"."};
|
inline constexpr std::wstring_view dot_w{L"."};
|
||||||
inline constexpr const std::string_view dot_backslash{".\\"};
|
inline constexpr std::string_view dot_backslash{".\\"};
|
||||||
inline constexpr const std::wstring_view dot_backslash_w{L".\\"};
|
inline constexpr std::wstring_view dot_backslash_w{L".\\"};
|
||||||
inline constexpr const std::string_view dot_slash{"./"};
|
inline constexpr std::string_view dot_slash{"./"};
|
||||||
inline constexpr const std::wstring_view dot_slash_w{L"./"};
|
inline constexpr std::wstring_view dot_slash_w{L"./"};
|
||||||
inline constexpr const std::string_view long_notation{"\\\\?\\"};
|
inline constexpr std::string_view long_notation{"\\\\?\\"};
|
||||||
inline constexpr const std::wstring_view long_notation_w{L"\\\\?\\"};
|
inline constexpr std::wstring_view long_notation_w{L"\\\\?\\"};
|
||||||
inline constexpr const std::string_view slash{"/"};
|
inline constexpr std::string_view slash{"/"};
|
||||||
inline constexpr const std::wstring_view slash_w{L"/"};
|
inline constexpr std::wstring_view slash_w{L"/"};
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
inline constexpr const std::string_view directory_seperator{backslash};
|
inline constexpr std::string_view directory_seperator{backslash};
|
||||||
inline constexpr const std::wstring_view directory_seperator_w{backslash_w};
|
inline constexpr std::wstring_view directory_seperator_w{backslash_w};
|
||||||
inline constexpr const std::string_view not_directory_seperator{slash};
|
inline constexpr std::string_view not_directory_seperator{slash};
|
||||||
inline constexpr const std::wstring_view not_directory_seperator_w{slash_w};
|
inline constexpr std::wstring_view not_directory_seperator_w{slash_w};
|
||||||
inline constexpr const std::string_view unc_notation{"\\\\"};
|
inline constexpr std::string_view unc_notation{"\\\\"};
|
||||||
inline constexpr const std::wstring_view unc_notation_w{L"\\\\"};
|
inline constexpr std::wstring_view unc_notation_w{L"\\\\"};
|
||||||
#else // !defined(_WIN32)
|
#else // !defined(_WIN32)
|
||||||
inline constexpr const std::string_view directory_seperator{slash};
|
inline constexpr std::string_view directory_seperator{slash};
|
||||||
inline constexpr const std::wstring_view directory_seperator_w{slash_w};
|
inline constexpr std::wstring_view directory_seperator_w{slash_w};
|
||||||
inline constexpr const std::string_view not_directory_seperator{backslash};
|
inline constexpr std::string_view not_directory_seperator{backslash};
|
||||||
inline constexpr const std::wstring_view not_directory_seperator_w{backslash_w};
|
inline constexpr std::wstring_view not_directory_seperator_w{backslash_w};
|
||||||
#endif // defined(_WIN32)
|
#endif // defined(_WIN32)
|
||||||
|
|
||||||
template <typename char_t>
|
template <typename char_t>
|
||||||
|
|||||||
@@ -25,9 +25,9 @@
|
|||||||
#include "utils/config.hpp"
|
#include "utils/config.hpp"
|
||||||
|
|
||||||
namespace monitarr::utils::time {
|
namespace monitarr::utils::time {
|
||||||
inline constexpr const auto NANOS_PER_SECOND{1000000000ULL};
|
inline constexpr auto NANOS_PER_SECOND{1000000000ULL};
|
||||||
inline constexpr const auto WIN32_TIME_CONVERSION{116444736000000000ULL};
|
inline constexpr auto WIN32_TIME_CONVERSION{116444736000000000ULL};
|
||||||
inline constexpr const auto WIN32_TIME_NANOS_PER_TICK{100ULL};
|
inline constexpr auto WIN32_TIME_NANOS_PER_TICK{100ULL};
|
||||||
|
|
||||||
#if defined(PROJECT_ENABLE_SPDLOG) || defined(PROJECT_ENABLE_FMT)
|
#if defined(PROJECT_ENABLE_SPDLOG) || defined(PROJECT_ENABLE_FMT)
|
||||||
[[nodiscard]] inline auto convert_to_utc(time_t time) -> std::time_t {
|
[[nodiscard]] inline auto convert_to_utc(time_t time) -> std::time_t {
|
||||||
|
|||||||
59
support/include/utils/timeout.hpp
Normal file
59
support/include/utils/timeout.hpp
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
Copyright <2018-2025> <scott.e.graves@protonmail.com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
#ifndef MONITARR_INCLUDE_UTILS_TIMEOUT_HPP_
|
||||||
|
#define MONITARR_INCLUDE_UTILS_TIMEOUT_HPP_
|
||||||
|
|
||||||
|
#include "utils/config.hpp"
|
||||||
|
|
||||||
|
namespace monitarr::utils {
|
||||||
|
class timeout final {
|
||||||
|
public:
|
||||||
|
using callback_t = std::function<void()>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
timeout(const timeout &) noexcept = delete;
|
||||||
|
timeout(timeout &&) noexcept = delete;
|
||||||
|
auto operator=(const timeout &) noexcept -> timeout & = delete;
|
||||||
|
auto operator=(timeout &&) noexcept -> timeout & = delete;
|
||||||
|
|
||||||
|
public:
|
||||||
|
timeout(callback_t timeout_callback,
|
||||||
|
std::chrono::system_clock::duration duration);
|
||||||
|
|
||||||
|
~timeout();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::chrono::system_clock::duration duration_;
|
||||||
|
callback_t timeout_callback_;
|
||||||
|
std::atomic<bool> timeout_killed_{false};
|
||||||
|
std::unique_ptr<std::thread> timeout_thread_{nullptr};
|
||||||
|
std::mutex timeout_mutex_;
|
||||||
|
std::condition_variable timeout_notify_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void disable();
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
};
|
||||||
|
} // namespace monitarr::utils
|
||||||
|
|
||||||
|
#endif // MONITARR_INCLUDE_UTILS_TIMEOUT_HPP_
|
||||||
100
support/include/utils/ttl_cache.hpp
Normal file
100
support/include/utils/ttl_cache.hpp
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
#ifndef MONITARR_INCLUDE_UTILS_TTL_CACHE_HPP_
|
||||||
|
#define MONITARR_INCLUDE_UTILS_TTL_CACHE_HPP_
|
||||||
|
|
||||||
|
#include "utils/config.hpp"
|
||||||
|
|
||||||
|
namespace monitarr::utils {
|
||||||
|
template <typename data_t, template <typename> class atomic_t = std::atomic>
|
||||||
|
class ttl_cache final {
|
||||||
|
public:
|
||||||
|
using clock = std::chrono::steady_clock;
|
||||||
|
using duration = std::chrono::milliseconds;
|
||||||
|
using entry_t = atomic_t<data_t>;
|
||||||
|
using entry_ptr_t = std::shared_ptr<entry_t>;
|
||||||
|
|
||||||
|
static constexpr auto default_expiration{duration(60000U)};
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct entry final {
|
||||||
|
entry_ptr_t data;
|
||||||
|
clock::time_point expires_at;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
ttl_cache(duration ttl = default_expiration) : ttl_{ttl} {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
duration ttl_;
|
||||||
|
|
||||||
|
private:
|
||||||
|
mutable std::mutex mutex_;
|
||||||
|
std::unordered_map<std::string, entry> entries_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void clear() {
|
||||||
|
mutex_lock lock(mutex_);
|
||||||
|
entries_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void erase(const std::string &api_path) {
|
||||||
|
mutex_lock lock(mutex_);
|
||||||
|
entries_.erase(api_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto contains(const std::string &api_path) -> bool {
|
||||||
|
mutex_lock lock(mutex_);
|
||||||
|
return entries_.contains(api_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto get(const std::string &api_path) -> entry_ptr_t {
|
||||||
|
mutex_lock lock(mutex_);
|
||||||
|
auto iter = entries_.find(api_path);
|
||||||
|
if (iter == entries_.end()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
iter->second.expires_at = clock::now() + ttl_;
|
||||||
|
return iter->second.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void purge_expired() {
|
||||||
|
mutex_lock lock(mutex_);
|
||||||
|
auto now = clock::now();
|
||||||
|
for (auto iter = entries_.begin(); iter != entries_.end();) {
|
||||||
|
if (iter->second.expires_at <= now) {
|
||||||
|
iter = entries_.erase(iter);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_ttl() const -> duration {
|
||||||
|
mutex_lock lock(mutex_);
|
||||||
|
return ttl_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set(const std::string &api_path, const data_t &data) {
|
||||||
|
mutex_lock lock(mutex_);
|
||||||
|
if (entries_.contains(api_path)) {
|
||||||
|
auto &entry = entries_.at(api_path);
|
||||||
|
entry.data->store(data);
|
||||||
|
entry.expires_at = clock::now() + ttl_;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
entries_.emplace(api_path, entry{
|
||||||
|
.data = std::make_shared<entry_t>(data),
|
||||||
|
.expires_at = clock::now() + ttl_,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_ttl(duration ttl) {
|
||||||
|
mutex_lock lock(mutex_);
|
||||||
|
ttl_ = ttl;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace monitarr::utils
|
||||||
|
|
||||||
|
#endif // MONITARR_INCLUDE_UTILS_TTL_CACHE_HPP_
|
||||||
@@ -30,6 +30,7 @@
|
|||||||
namespace monitarr::utils::file {
|
namespace monitarr::utils::file {
|
||||||
enum class time_type {
|
enum class time_type {
|
||||||
accessed,
|
accessed,
|
||||||
|
changed,
|
||||||
created,
|
created,
|
||||||
modified,
|
modified,
|
||||||
written,
|
written,
|
||||||
@@ -37,6 +38,7 @@ enum class time_type {
|
|||||||
|
|
||||||
struct file_times final {
|
struct file_times final {
|
||||||
std::uint64_t accessed{};
|
std::uint64_t accessed{};
|
||||||
|
std::uint64_t changed{};
|
||||||
std::uint64_t created{};
|
std::uint64_t created{};
|
||||||
std::uint64_t modified{};
|
std::uint64_t modified{};
|
||||||
std::uint64_t written{};
|
std::uint64_t written{};
|
||||||
@@ -47,6 +49,8 @@ struct file_times final {
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case time_type::accessed:
|
case time_type::accessed:
|
||||||
return accessed;
|
return accessed;
|
||||||
|
case time_type::changed:
|
||||||
|
return changed;
|
||||||
case time_type::created:
|
case time_type::created:
|
||||||
return created;
|
return created;
|
||||||
case time_type::modified:
|
case time_type::modified:
|
||||||
@@ -70,8 +74,8 @@ struct i_fs_item {
|
|||||||
[[nodiscard]] virtual auto copy_to(std::string_view to_path,
|
[[nodiscard]] virtual auto copy_to(std::string_view to_path,
|
||||||
bool overwrite) const -> bool = 0;
|
bool overwrite) const -> bool = 0;
|
||||||
|
|
||||||
[[nodiscard]] virtual auto copy_to(std::wstring_view new_path,
|
[[nodiscard]] virtual auto copy_to(std::wstring_view new_path, bool overwrite)
|
||||||
bool overwrite) -> bool {
|
-> bool {
|
||||||
return copy_to(utils::string::to_utf8(new_path), overwrite);
|
return copy_to(utils::string::to_utf8(new_path), overwrite);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,8 +83,8 @@ struct i_fs_item {
|
|||||||
|
|
||||||
[[nodiscard]] virtual auto get_path() const -> std::string = 0;
|
[[nodiscard]] virtual auto get_path() const -> std::string = 0;
|
||||||
|
|
||||||
[[nodiscard]] virtual auto
|
[[nodiscard]] virtual auto get_time(time_type type) const
|
||||||
get_time(time_type type) const -> std::optional<std::uint64_t>;
|
-> std::optional<std::uint64_t>;
|
||||||
|
|
||||||
[[nodiscard]] virtual auto is_directory_item() const -> bool = 0;
|
[[nodiscard]] virtual auto is_directory_item() const -> bool = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,40 @@
|
|||||||
#include "utils/config.hpp"
|
#include "utils/config.hpp"
|
||||||
|
|
||||||
namespace monitarr::utils {
|
namespace monitarr::utils {
|
||||||
|
#if defined(__linux__)
|
||||||
|
struct autostart_cfg final {
|
||||||
|
std::string app_name;
|
||||||
|
std::optional<std::string> comment;
|
||||||
|
bool enabled{true};
|
||||||
|
std::vector<std::string> exec_args;
|
||||||
|
std::string exec_path;
|
||||||
|
std::optional<std::string> icon_path;
|
||||||
|
std::vector<std::string> only_show_in;
|
||||||
|
bool terminal{false};
|
||||||
|
};
|
||||||
|
#endif // defined(__linux__)
|
||||||
|
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
enum class launchctl_type : std::uint8_t {
|
||||||
|
bootout,
|
||||||
|
bootstrap,
|
||||||
|
kickstart,
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined(PROJECT_ENABLE_PUGIXML)
|
||||||
|
struct plist_cfg final {
|
||||||
|
std::vector<std::string> args;
|
||||||
|
bool keep_alive{false};
|
||||||
|
std::string label;
|
||||||
|
std::string plist_path;
|
||||||
|
bool run_at_load{false};
|
||||||
|
std::string stderr_log{"/tmp/stderr.log"};
|
||||||
|
std::string stdout_log{"/tmp/stdout.log"};
|
||||||
|
std::string working_dir{"/tmp"};
|
||||||
|
};
|
||||||
|
#endif // defined(PROJECT_ENABLE_PUGIXML)
|
||||||
|
#endif // defined(__APPLE__)
|
||||||
|
|
||||||
using passwd_callback_t = std::function<void(struct passwd *pass)>;
|
using passwd_callback_t = std::function<void(struct passwd *pass)>;
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
@@ -37,6 +71,12 @@ template <typename thread_t>
|
|||||||
[[nodiscard]] auto convert_to_uint64(const pthread_t &thread) -> std::uint64_t;
|
[[nodiscard]] auto convert_to_uint64(const pthread_t &thread) -> std::uint64_t;
|
||||||
#endif // defined(__APPLE__)
|
#endif // defined(__APPLE__)
|
||||||
|
|
||||||
|
#if defined(__linux__)
|
||||||
|
[[nodiscard]] auto create_autostart_entry(const autostart_cfg &cfg,
|
||||||
|
bool overwrite_existing = true)
|
||||||
|
-> bool;
|
||||||
|
#endif // defined(__linux__)
|
||||||
|
|
||||||
[[nodiscard]] auto get_last_error_code() -> int;
|
[[nodiscard]] auto get_last_error_code() -> int;
|
||||||
|
|
||||||
[[nodiscard]] auto get_thread_id() -> std::uint64_t;
|
[[nodiscard]] auto get_thread_id() -> std::uint64_t;
|
||||||
@@ -48,9 +88,30 @@ void set_last_error_code(int error_code);
|
|||||||
[[nodiscard]] auto use_getpwuid(uid_t uid, passwd_callback_t callback)
|
[[nodiscard]] auto use_getpwuid(uid_t uid, passwd_callback_t callback)
|
||||||
-> utils::result;
|
-> utils::result;
|
||||||
|
|
||||||
|
#if defined(__linux__)
|
||||||
|
[[nodiscard]] auto remove_autostart_entry(std::string_view name) -> bool;
|
||||||
|
#endif // defined(__linux__)
|
||||||
|
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
#if defined(PROJECT_ENABLE_PUGIXML)
|
||||||
|
[[nodiscard]] auto generate_launchd_plist(const plist_cfg &cfg,
|
||||||
|
bool overwrite_existing = true)
|
||||||
|
-> bool;
|
||||||
|
#endif // defined(PROJECT_ENABLE_PUGIXML)
|
||||||
|
|
||||||
|
#if defined(PROJECT_ENABLE_SPDLOG) || defined(PROJECT_ENABLE_FMT)
|
||||||
|
[[nodiscard]] auto launchctl_command(std::string_view label,
|
||||||
|
launchctl_type type) -> int;
|
||||||
|
|
||||||
|
[[nodiscard]] auto remove_launchd_plist(std::string_view plist_path,
|
||||||
|
std::string_view label,
|
||||||
|
bool should_bootout) -> bool;
|
||||||
|
#endif // defined(PROJECT_ENABLE_SPDLOG) || defined(PROJECT_ENABLE_FMT)
|
||||||
|
#endif // defined(__APPLE__)
|
||||||
|
|
||||||
// template implementations
|
// template implementations
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
template <typename t>
|
template <typename thread_t>
|
||||||
[[nodiscard]] auto convert_to_uint64(const thread_t *thread_ptr)
|
[[nodiscard]] auto convert_to_uint64(const thread_t *thread_ptr)
|
||||||
-> std::uint64_t {
|
-> std::uint64_t {
|
||||||
return static_cast<std::uint64_t>(
|
return static_cast<std::uint64_t>(
|
||||||
|
|||||||
@@ -30,17 +30,42 @@ void create_console();
|
|||||||
|
|
||||||
void free_console();
|
void free_console();
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_available_drive_letter(char first = 'a')
|
||||||
|
-> std::optional<std::string_view>;
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_available_drive_letters(char first = 'a')
|
||||||
|
-> std::vector<std::string_view>;
|
||||||
|
|
||||||
[[nodiscard]] auto get_local_app_data_directory() -> const std::string &;
|
[[nodiscard]] auto get_local_app_data_directory() -> const std::string &;
|
||||||
|
|
||||||
[[nodiscard]] auto get_last_error_code() -> DWORD;
|
[[nodiscard]] auto get_last_error_code() -> DWORD;
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_startup_folder() -> std::wstring;
|
||||||
|
|
||||||
[[nodiscard]] auto get_thread_id() -> std::uint64_t;
|
[[nodiscard]] auto get_thread_id() -> std::uint64_t;
|
||||||
|
|
||||||
[[nodiscard]] auto is_process_elevated() -> bool;
|
[[nodiscard]] auto is_process_elevated() -> bool;
|
||||||
|
|
||||||
[[nodiscard]] auto run_process_elevated(std::vector<const char *> args) -> int;
|
[[nodiscard]] auto run_process_elevated(std::vector<const char *> args) -> int;
|
||||||
|
|
||||||
void set_last_error_code(DWORD errorCode);
|
struct shortcut_cfg final {
|
||||||
|
std::wstring arguments;
|
||||||
|
std::wstring exe_path;
|
||||||
|
std::wstring icon_path;
|
||||||
|
std::wstring location{get_startup_folder()};
|
||||||
|
std::wstring shortcut_name;
|
||||||
|
std::wstring working_directory;
|
||||||
|
};
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
auto create_shortcut(const shortcut_cfg &cfg, bool overwrite_existing = true)
|
||||||
|
-> bool;
|
||||||
|
|
||||||
|
[[nodiscard]] auto
|
||||||
|
remove_shortcut(std::wstring shortcut_name,
|
||||||
|
const std::wstring &location = get_startup_folder()) -> bool;
|
||||||
|
|
||||||
|
void set_last_error_code(DWORD error_code);
|
||||||
} // namespace monitarr::utils
|
} // namespace monitarr::utils
|
||||||
|
|
||||||
#endif // defined(_WIN32)
|
#endif // defined(_WIN32)
|
||||||
|
|||||||
52
support/src/utils/directory.cpp
Normal file
52
support/src/utils/directory.cpp
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
Copyright <2018-2025> <scott.e.graves@protonmail.com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
#include "utils/file.hpp"
|
||||||
|
|
||||||
|
#include "utils/common.hpp"
|
||||||
|
#include "utils/error.hpp"
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#include "utils/path.hpp"
|
||||||
|
#endif // defined(_WIN32)
|
||||||
|
|
||||||
|
namespace monitarr::utils::directory {
|
||||||
|
auto temp() -> std::string {
|
||||||
|
MONITARR_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
auto ret{utils::get_environment_variable("TEMP")};
|
||||||
|
if (ret.empty()) {
|
||||||
|
ret = utils::path::combine(utils::get_environment_variable("LOCALAPPDATA"),
|
||||||
|
{"Temp"});
|
||||||
|
}
|
||||||
|
#else // !defined(_WIN32)
|
||||||
|
std::string ret{"/tmp"};
|
||||||
|
#endif // defined(_WIN32)
|
||||||
|
|
||||||
|
if (not utils::file::directory{ret}.create_directory()) {
|
||||||
|
utils::error::handle_error(function_name,
|
||||||
|
utils::error::create_error_message(
|
||||||
|
{"failed to create directory", ret}));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
} // namespace monitarr::utils::directory
|
||||||
@@ -23,8 +23,10 @@
|
|||||||
|
|
||||||
#include "utils/encrypting_reader.hpp"
|
#include "utils/encrypting_reader.hpp"
|
||||||
|
|
||||||
|
#include "utils/base64.hpp"
|
||||||
#include "utils/collection.hpp"
|
#include "utils/collection.hpp"
|
||||||
#include "utils/common.hpp"
|
#include "utils/common.hpp"
|
||||||
|
#include "utils/config.hpp"
|
||||||
#include "utils/encryption.hpp"
|
#include "utils/encryption.hpp"
|
||||||
#include "utils/error.hpp"
|
#include "utils/error.hpp"
|
||||||
#include "utils/file.hpp"
|
#include "utils/file.hpp"
|
||||||
@@ -119,7 +121,7 @@ protected:
|
|||||||
reader_.set_read_position(reinterpret_cast<std::uintptr_t>(gptr()));
|
reader_.set_read_position(reinterpret_cast<std::uintptr_t>(gptr()));
|
||||||
|
|
||||||
char c{};
|
char c{};
|
||||||
const auto res = encrypting_reader::reader_function(&c, 1U, 1U, &reader_);
|
auto res = encrypting_reader::reader_function(&c, 1U, 1U, &reader_);
|
||||||
if (res != 1) {
|
if (res != 1) {
|
||||||
return traits_type::eof();
|
return traits_type::eof();
|
||||||
}
|
}
|
||||||
@@ -180,171 +182,218 @@ encrypting_reader::encrypting_reader(
|
|||||||
std::string_view file_name, std::string_view source_path,
|
std::string_view file_name, std::string_view source_path,
|
||||||
stop_type_callback stop_requested_cb, std::string_view token,
|
stop_type_callback stop_requested_cb, std::string_view token,
|
||||||
std::optional<std::string> relative_parent_path, std::size_t error_return)
|
std::optional<std::string> relative_parent_path, std::size_t error_return)
|
||||||
: key_(utils::encryption::generate_key<utils::encryption::hash_256_t>(
|
: keys_(utils::encryption::generate_key<utils::hash::hash_256_t>(token),
|
||||||
token)),
|
utils::encryption::generate_key<utils::hash::hash_256_t>(token)),
|
||||||
stop_requested_cb_(std::move(stop_requested_cb)),
|
stop_requested_cb_(std::move(stop_requested_cb)),
|
||||||
error_return_(error_return),
|
error_return_(error_return),
|
||||||
source_file_(utils::file::file::open_or_create_file(source_path, true)) {
|
source_file_(utils::file::file::open_or_create_file(source_path, true)) {
|
||||||
MONITARR_USES_FUNCTION_NAME();
|
common_initialize(true);
|
||||||
|
create_encrypted_paths(file_name, relative_parent_path);
|
||||||
if (not*source_file_) {
|
|
||||||
throw utils::error::create_exception(function_name, {
|
|
||||||
"file open failed",
|
|
||||||
source_path,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
data_buffer result;
|
|
||||||
utils::encryption::encrypt_data(
|
|
||||||
key_, reinterpret_cast<const unsigned char *>(file_name.data()),
|
|
||||||
file_name.size(), result);
|
|
||||||
encrypted_file_name_ = utils::collection::to_hex_string(result);
|
|
||||||
|
|
||||||
if (relative_parent_path.has_value()) {
|
|
||||||
for (auto &&part :
|
|
||||||
utils::string::split(relative_parent_path.value(),
|
|
||||||
utils::path::directory_seperator, false)) {
|
|
||||||
utils::encryption::encrypt_data(
|
|
||||||
key_, reinterpret_cast<const unsigned char *>(part.c_str()),
|
|
||||||
strnlen(part.c_str(), part.size()), result);
|
|
||||||
encrypted_file_path_ += '/' + utils::collection::to_hex_string(result);
|
|
||||||
}
|
|
||||||
encrypted_file_path_ += '/' + encrypted_file_name_;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto opt_size = source_file_->size();
|
|
||||||
if (not opt_size.has_value()) {
|
|
||||||
throw utils::error::create_exception(function_name,
|
|
||||||
{
|
|
||||||
"failed to get file size",
|
|
||||||
source_file_->get_path(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
auto file_size = opt_size.value();
|
|
||||||
|
|
||||||
const auto total_chunks = utils::divide_with_ceiling(
|
|
||||||
file_size, static_cast<std::uint64_t>(data_chunk_size_));
|
|
||||||
total_size_ = file_size + (total_chunks * encryption_header_size);
|
|
||||||
last_data_chunk_ = total_chunks - 1U;
|
|
||||||
last_data_chunk_size_ = (file_size <= data_chunk_size_) ? file_size
|
|
||||||
: (file_size % data_chunk_size_) == 0U
|
|
||||||
? data_chunk_size_
|
|
||||||
: file_size % data_chunk_size_;
|
|
||||||
iv_list_.resize(total_chunks);
|
|
||||||
for (auto &iv : iv_list_) {
|
|
||||||
randombytes_buf(iv.data(), iv.size());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
encrypting_reader::encrypting_reader(std::string_view encrypted_file_path,
|
encrypting_reader::encrypting_reader(stop_type_callback stop_requested_cb,
|
||||||
|
std::string_view encrypted_file_path,
|
||||||
std::string_view source_path,
|
std::string_view source_path,
|
||||||
stop_type_callback stop_requested_cb,
|
|
||||||
std::string_view token,
|
std::string_view token,
|
||||||
std::size_t error_return)
|
std::size_t error_return)
|
||||||
: key_(utils::encryption::generate_key<utils::encryption::hash_256_t>(
|
: keys_(utils::encryption::generate_key<utils::hash::hash_256_t>(token),
|
||||||
token)),
|
utils::encryption::generate_key<utils::hash::hash_256_t>(token)),
|
||||||
stop_requested_cb_(std::move(stop_requested_cb)),
|
stop_requested_cb_(std::move(stop_requested_cb)),
|
||||||
error_return_(error_return),
|
error_return_(error_return),
|
||||||
source_file_(utils::file::file::open_or_create_file(source_path, true)) {
|
source_file_(utils::file::file::open_or_create_file(source_path, true)),
|
||||||
MONITARR_USES_FUNCTION_NAME();
|
encrypted_file_name_(
|
||||||
|
utils::path::strip_to_file_name(std::string{encrypted_file_path})),
|
||||||
if (not*source_file_) {
|
encrypted_file_path_(encrypted_file_path) {
|
||||||
throw utils::error::create_exception(function_name, {
|
common_initialize(true);
|
||||||
"file open failed",
|
|
||||||
source_path,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
encrypted_file_path_ = encrypted_file_path;
|
|
||||||
encrypted_file_name_ = utils::path::strip_to_file_name(encrypted_file_path_);
|
|
||||||
|
|
||||||
auto opt_size = source_file_->size();
|
|
||||||
if (not opt_size.has_value()) {
|
|
||||||
throw utils::error::create_exception(function_name,
|
|
||||||
{
|
|
||||||
"failed to get file size",
|
|
||||||
source_file_->get_path(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
auto file_size = opt_size.value();
|
|
||||||
|
|
||||||
const auto total_chunks = utils::divide_with_ceiling(
|
|
||||||
file_size, static_cast<std::uint64_t>(data_chunk_size_));
|
|
||||||
total_size_ = file_size + (total_chunks * encryption_header_size);
|
|
||||||
last_data_chunk_ = total_chunks - 1U;
|
|
||||||
last_data_chunk_size_ = (file_size <= data_chunk_size_) ? file_size
|
|
||||||
: (file_size % data_chunk_size_) == 0U
|
|
||||||
? data_chunk_size_
|
|
||||||
: file_size % data_chunk_size_;
|
|
||||||
iv_list_.resize(total_chunks);
|
|
||||||
for (auto &iv : iv_list_) {
|
|
||||||
randombytes_buf(iv.data(), iv.size());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
encrypting_reader::encrypting_reader(
|
encrypting_reader::encrypting_reader(
|
||||||
std::string_view encrypted_file_path, std::string_view source_path,
|
stop_type_callback stop_requested_cb, std::string_view encrypted_file_path,
|
||||||
stop_type_callback stop_requested_cb, std::string_view token,
|
std::string_view source_path, std::string_view token,
|
||||||
std::vector<
|
std::vector<
|
||||||
std::array<unsigned char, crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>>
|
std::array<unsigned char, crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>>
|
||||||
iv_list,
|
iv_list,
|
||||||
std::size_t error_return)
|
std::size_t error_return)
|
||||||
: key_(utils::encryption::generate_key<utils::encryption::hash_256_t>(
|
: keys_(utils::encryption::generate_key<utils::hash::hash_256_t>(token),
|
||||||
token)),
|
utils::encryption::generate_key<utils::hash::hash_256_t>(token)),
|
||||||
stop_requested_cb_(std::move(stop_requested_cb)),
|
stop_requested_cb_(std::move(stop_requested_cb)),
|
||||||
|
error_return_(error_return),
|
||||||
|
source_file_(utils::file::file::open_or_create_file(source_path, true)),
|
||||||
|
encrypted_file_name_(
|
||||||
|
utils::path::strip_to_file_name(std::string{encrypted_file_path})),
|
||||||
|
encrypted_file_path_(encrypted_file_path),
|
||||||
|
iv_list_(std::move(iv_list)) {
|
||||||
|
common_initialize(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
encrypting_reader::encrypting_reader(
|
||||||
|
std::string_view file_name, std::string_view source_path,
|
||||||
|
stop_type_callback stop_requested_cb, std::string_view token,
|
||||||
|
kdf_config cfg, std::optional<std::string> relative_parent_path,
|
||||||
|
std::size_t error_return)
|
||||||
|
: stop_requested_cb_(std::move(stop_requested_cb)),
|
||||||
error_return_(error_return),
|
error_return_(error_return),
|
||||||
source_file_(utils::file::file::open_or_create_file(source_path, true)) {
|
source_file_(utils::file::file::open_or_create_file(source_path, true)) {
|
||||||
MONITARR_USES_FUNCTION_NAME();
|
common_initialize_kdf_keys(token, cfg);
|
||||||
|
common_initialize(true);
|
||||||
|
create_encrypted_paths(file_name, relative_parent_path);
|
||||||
|
}
|
||||||
|
|
||||||
if (not*source_file_) {
|
encrypting_reader::encrypting_reader(stop_type_callback stop_requested_cb,
|
||||||
throw utils::error::create_exception(function_name, {
|
std::string_view encrypted_file_path,
|
||||||
"file open failed",
|
std::string_view source_path,
|
||||||
source_path,
|
std::string_view token, kdf_config cfg,
|
||||||
});
|
std::size_t error_return)
|
||||||
}
|
: stop_requested_cb_(std::move(stop_requested_cb)),
|
||||||
|
error_return_(error_return),
|
||||||
|
source_file_(utils::file::file::open_or_create_file(source_path, true)),
|
||||||
|
encrypted_file_name_(
|
||||||
|
utils::path::strip_to_file_name(std::string{encrypted_file_path})),
|
||||||
|
encrypted_file_path_(encrypted_file_path) {
|
||||||
|
common_initialize_kdf_keys(token, cfg);
|
||||||
|
common_initialize(true);
|
||||||
|
}
|
||||||
|
|
||||||
encrypted_file_path_ = encrypted_file_path;
|
encrypting_reader::encrypting_reader(
|
||||||
encrypted_file_name_ = utils::path::strip_to_file_name(encrypted_file_path_);
|
stop_type_callback stop_requested_cb, std::string_view encrypted_file_path,
|
||||||
|
std::string_view source_path, std::string_view token, kdf_config cfg,
|
||||||
|
std::vector<
|
||||||
|
std::array<unsigned char, crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>>
|
||||||
|
iv_list,
|
||||||
|
std::size_t error_return)
|
||||||
|
: stop_requested_cb_(std::move(stop_requested_cb)),
|
||||||
|
error_return_(error_return),
|
||||||
|
source_file_(utils::file::file::open_or_create_file(source_path, true)),
|
||||||
|
encrypted_file_name_(
|
||||||
|
utils::path::strip_to_file_name(std::string{encrypted_file_path})),
|
||||||
|
encrypted_file_path_(encrypted_file_path),
|
||||||
|
iv_list_(std::move(iv_list)) {
|
||||||
|
common_initialize_kdf_keys(token, cfg);
|
||||||
|
common_initialize(false);
|
||||||
|
}
|
||||||
|
|
||||||
auto opt_size = source_file_->size();
|
encrypting_reader::encrypting_reader(
|
||||||
if (not opt_size.has_value()) {
|
std::string_view file_name, std::string_view source_path,
|
||||||
throw utils::error::create_exception(
|
stop_type_callback stop_requested_cb,
|
||||||
function_name, {
|
const utils::hash::hash_256_t &master_key, const kdf_config &cfg,
|
||||||
"get file size failed",
|
std::optional<std::string> relative_parent_path, std::size_t error_return)
|
||||||
std::to_string(utils::get_last_error_code()),
|
: stop_requested_cb_(std::move(stop_requested_cb)),
|
||||||
source_file_->get_path(),
|
error_return_(error_return),
|
||||||
});
|
source_file_(utils::file::file::open_or_create_file(source_path, true)) {
|
||||||
}
|
common_initialize_kdf_data(cfg, master_key);
|
||||||
auto file_size{opt_size.value()};
|
auto [path_key, path_cfg] = cfg.create_subkey(
|
||||||
|
kdf_context::path, utils::generate_secure_random<std::uint64_t>(),
|
||||||
|
master_key);
|
||||||
|
keys_.second = std::move(path_key);
|
||||||
|
kdf_headers_->second = path_cfg.to_header();
|
||||||
|
common_initialize(true);
|
||||||
|
create_encrypted_paths(file_name, relative_parent_path);
|
||||||
|
}
|
||||||
|
|
||||||
const auto total_chunks = utils::divide_with_ceiling(
|
encrypting_reader::encrypting_reader(
|
||||||
file_size, static_cast<std::uint64_t>(data_chunk_size_));
|
std::string_view file_name, std::string_view source_path,
|
||||||
total_size_ = file_size + (total_chunks * encryption_header_size);
|
stop_type_callback stop_requested_cb,
|
||||||
last_data_chunk_ = total_chunks - 1U;
|
const utils::hash::hash_256_t &master_key,
|
||||||
last_data_chunk_size_ = (file_size <= data_chunk_size_) ? file_size
|
const std::pair<kdf_config, kdf_config> &configs,
|
||||||
: (file_size % data_chunk_size_) == 0U
|
std::optional<std::string> relative_parent_path, std::size_t error_return)
|
||||||
? data_chunk_size_
|
: stop_requested_cb_(std::move(stop_requested_cb)),
|
||||||
: file_size % data_chunk_size_;
|
error_return_(error_return),
|
||||||
iv_list_ = std::move(iv_list);
|
source_file_(utils::file::file::open_or_create_file(source_path, true)) {
|
||||||
|
keys_ = {
|
||||||
|
configs.first.recreate_subkey(utils::encryption::kdf_context::data,
|
||||||
|
master_key),
|
||||||
|
configs.second.recreate_subkey(utils::encryption::kdf_context::path,
|
||||||
|
master_key),
|
||||||
|
};
|
||||||
|
kdf_headers_ = {
|
||||||
|
configs.first.to_header(),
|
||||||
|
configs.second.to_header(),
|
||||||
|
};
|
||||||
|
common_initialize(true);
|
||||||
|
create_encrypted_paths(file_name, relative_parent_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
encrypting_reader::encrypting_reader(stop_type_callback stop_requested_cb,
|
||||||
|
std::string_view encrypted_file_path,
|
||||||
|
std::string_view source_path,
|
||||||
|
const utils::hash::hash_256_t &master_key,
|
||||||
|
const kdf_config &cfg,
|
||||||
|
std::size_t error_return)
|
||||||
|
: stop_requested_cb_(std::move(stop_requested_cb)),
|
||||||
|
error_return_(error_return),
|
||||||
|
source_file_(utils::file::file::open_or_create_file(source_path, true)),
|
||||||
|
encrypted_file_name_(
|
||||||
|
utils::path::strip_to_file_name(std::string{encrypted_file_path})),
|
||||||
|
encrypted_file_path_(encrypted_file_path) {
|
||||||
|
common_initialize_kdf_data(cfg, master_key);
|
||||||
|
common_initialize_kdf_path(master_key);
|
||||||
|
common_initialize(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
encrypting_reader::encrypting_reader(
|
||||||
|
stop_type_callback stop_requested_cb, std::string_view encrypted_file_path,
|
||||||
|
std::string_view source_path, const utils::hash::hash_256_t &master_key,
|
||||||
|
const kdf_config &cfg,
|
||||||
|
std::vector<
|
||||||
|
std::array<unsigned char, crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>>
|
||||||
|
iv_list,
|
||||||
|
std::size_t error_return)
|
||||||
|
: stop_requested_cb_(std::move(stop_requested_cb)),
|
||||||
|
error_return_(error_return),
|
||||||
|
source_file_(utils::file::file::open_or_create_file(source_path, true)),
|
||||||
|
encrypted_file_name_(
|
||||||
|
utils::path::strip_to_file_name(std::string{encrypted_file_path})),
|
||||||
|
encrypted_file_path_(encrypted_file_path),
|
||||||
|
iv_list_(std::move(iv_list)) {
|
||||||
|
common_initialize_kdf_data(cfg, master_key);
|
||||||
|
common_initialize_kdf_path(master_key);
|
||||||
|
common_initialize(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
encrypting_reader::encrypting_reader(
|
||||||
|
stop_type_callback stop_requested_cb, std::string_view encrypted_file_path,
|
||||||
|
std::string_view source_path, const utils::hash::hash_256_t &master_key,
|
||||||
|
const std::pair<kdf_config, kdf_config> &configs,
|
||||||
|
std::vector<
|
||||||
|
std::array<unsigned char, crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>>
|
||||||
|
iv_list,
|
||||||
|
std::size_t error_return)
|
||||||
|
: stop_requested_cb_(std::move(stop_requested_cb)),
|
||||||
|
error_return_(error_return),
|
||||||
|
source_file_(utils::file::file::open_or_create_file(source_path, true)),
|
||||||
|
encrypted_file_name_(
|
||||||
|
utils::path::strip_to_file_name(std::string{encrypted_file_path})),
|
||||||
|
encrypted_file_path_(encrypted_file_path),
|
||||||
|
iv_list_(std::move(iv_list)) {
|
||||||
|
keys_.first = configs.first.recreate_subkey(
|
||||||
|
utils::encryption::kdf_context::data, master_key);
|
||||||
|
keys_.second = configs.second.recreate_subkey(
|
||||||
|
utils::encryption::kdf_context::path, master_key);
|
||||||
|
kdf_headers_ = {
|
||||||
|
configs.first.to_header(),
|
||||||
|
configs.second.to_header(),
|
||||||
|
};
|
||||||
|
common_initialize(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
encrypting_reader::encrypting_reader(const encrypting_reader &reader)
|
encrypting_reader::encrypting_reader(const encrypting_reader &reader)
|
||||||
: key_(reader.key_),
|
: keys_(reader.keys_),
|
||||||
stop_requested_cb_(reader.stop_requested_cb_),
|
stop_requested_cb_(reader.stop_requested_cb_),
|
||||||
error_return_(reader.error_return_),
|
error_return_(reader.error_return_),
|
||||||
source_file_(
|
source_file_(
|
||||||
utils::file::file::open_file(reader.source_file_->get_path(), true)),
|
utils::file::file::open_file(reader.source_file_->get_path(), true)),
|
||||||
chunk_buffers_(reader.chunk_buffers_),
|
|
||||||
encrypted_file_name_(reader.encrypted_file_name_),
|
encrypted_file_name_(reader.encrypted_file_name_),
|
||||||
encrypted_file_path_(reader.encrypted_file_path_),
|
encrypted_file_path_(reader.encrypted_file_path_),
|
||||||
iv_list_(reader.iv_list_),
|
iv_list_(reader.iv_list_),
|
||||||
|
chunk_buffers_(reader.chunk_buffers_),
|
||||||
|
kdf_headers_(reader.kdf_headers_),
|
||||||
last_data_chunk_(reader.last_data_chunk_),
|
last_data_chunk_(reader.last_data_chunk_),
|
||||||
last_data_chunk_size_(reader.last_data_chunk_size_),
|
last_data_chunk_size_(reader.last_data_chunk_size_),
|
||||||
read_offset_(reader.read_offset_),
|
read_offset_(reader.read_offset_),
|
||||||
total_size_(reader.total_size_) {
|
total_size_(reader.total_size_) {
|
||||||
MONITARR_USES_FUNCTION_NAME();
|
MONITARR_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
if (not*source_file_) {
|
if (not *source_file_) {
|
||||||
throw utils::error::create_exception(
|
throw utils::error::create_exception(
|
||||||
function_name, {
|
function_name, {
|
||||||
"file open failed",
|
"file open failed",
|
||||||
@@ -354,15 +403,21 @@ encrypting_reader::encrypting_reader(const encrypting_reader &reader)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto encrypting_reader::calculate_decrypted_size(std::uint64_t total_size)
|
auto encrypting_reader::calculate_decrypted_size(std::uint64_t total_size,
|
||||||
|
bool uses_kdf)
|
||||||
-> std::uint64_t {
|
-> std::uint64_t {
|
||||||
|
if (uses_kdf) {
|
||||||
|
total_size -= kdf_config::size();
|
||||||
|
}
|
||||||
|
|
||||||
return total_size - (utils::divide_with_ceiling(
|
return total_size - (utils::divide_with_ceiling(
|
||||||
total_size, static_cast<std::uint64_t>(
|
total_size, static_cast<std::uint64_t>(
|
||||||
get_encrypted_chunk_size())) *
|
get_encrypted_chunk_size())) *
|
||||||
encryption_header_size);
|
encryption_header_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto encrypting_reader::calculate_encrypted_size(std::string_view source_path)
|
auto encrypting_reader::calculate_encrypted_size(std::string_view source_path,
|
||||||
|
bool uses_kdf)
|
||||||
-> std::uint64_t {
|
-> std::uint64_t {
|
||||||
MONITARR_USES_FUNCTION_NAME();
|
MONITARR_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
@@ -375,11 +430,135 @@ auto encrypting_reader::calculate_encrypted_size(std::string_view source_path)
|
|||||||
source_path,
|
source_path,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
auto file_size{opt_size.value()};
|
|
||||||
|
|
||||||
const auto total_chunks = utils::divide_with_ceiling(
|
return calculate_encrypted_size(opt_size.value(), uses_kdf);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto encrypting_reader::calculate_encrypted_size(std::uint64_t size,
|
||||||
|
bool uses_kdf)
|
||||||
|
-> std::uint64_t {
|
||||||
|
auto total_chunks = utils::divide_with_ceiling(
|
||||||
|
size, static_cast<std::uint64_t>(data_chunk_size_));
|
||||||
|
return size + (total_chunks * encryption_header_size) +
|
||||||
|
(uses_kdf ? kdf_config::size() : 0U);
|
||||||
|
}
|
||||||
|
|
||||||
|
void encrypting_reader::common_initialize(bool procces_iv_list) {
|
||||||
|
MONITARR_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
|
if (not *source_file_) {
|
||||||
|
throw utils::error::create_exception(function_name,
|
||||||
|
{
|
||||||
|
"file open failed",
|
||||||
|
source_file_->get_path(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
auto opt_size = source_file_->size();
|
||||||
|
if (not opt_size.has_value()) {
|
||||||
|
throw utils::error::create_exception(function_name,
|
||||||
|
{
|
||||||
|
"failed to get file size",
|
||||||
|
source_file_->get_path(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
auto file_size = opt_size.value();
|
||||||
|
|
||||||
|
auto total_chunks = utils::divide_with_ceiling(
|
||||||
file_size, static_cast<std::uint64_t>(data_chunk_size_));
|
file_size, static_cast<std::uint64_t>(data_chunk_size_));
|
||||||
return file_size + (total_chunks * encryption_header_size);
|
total_size_ = file_size + (total_chunks * encryption_header_size) +
|
||||||
|
(kdf_headers_.has_value() ? kdf_headers_->first.size() : 0U);
|
||||||
|
last_data_chunk_ = total_chunks - 1U;
|
||||||
|
last_data_chunk_size_ = (file_size <= data_chunk_size_) ? file_size
|
||||||
|
: (file_size % data_chunk_size_) == 0U
|
||||||
|
? data_chunk_size_
|
||||||
|
: file_size % data_chunk_size_;
|
||||||
|
if (not procces_iv_list) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
iv_list_.resize(total_chunks);
|
||||||
|
for (auto &data : iv_list_) {
|
||||||
|
randombytes_buf(data.data(), data.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void encrypting_reader::common_initialize_kdf_data(
|
||||||
|
const kdf_config &cfg, const utils::hash::hash_256_t &master_key) {
|
||||||
|
auto [data_key, data_cfg] = cfg.create_subkey(
|
||||||
|
kdf_context::data, utils::generate_secure_random<std::uint64_t>(),
|
||||||
|
master_key);
|
||||||
|
keys_.first = std::move(data_key);
|
||||||
|
kdf_headers_ = {data_cfg.to_header(), {}};
|
||||||
|
}
|
||||||
|
|
||||||
|
void encrypting_reader::common_initialize_kdf_keys(std::string_view token,
|
||||||
|
kdf_config &cfg) {
|
||||||
|
auto key =
|
||||||
|
utils::encryption::generate_key<utils::hash::hash_256_t>(token, cfg);
|
||||||
|
keys_ = {key, key};
|
||||||
|
kdf_headers_ = {cfg.to_header(), cfg.to_header()};
|
||||||
|
}
|
||||||
|
|
||||||
|
void encrypting_reader::common_initialize_kdf_path(
|
||||||
|
const utils::hash::hash_256_t &master_key) {
|
||||||
|
MONITARR_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
|
auto buffer = macaron::Base64::Decode(encrypted_file_path_);
|
||||||
|
|
||||||
|
kdf_config path_cfg;
|
||||||
|
if (not kdf_config::from_header(buffer, path_cfg)) {
|
||||||
|
throw utils::error::create_exception(
|
||||||
|
function_name, {"failed to create path kdf config from header"});
|
||||||
|
}
|
||||||
|
|
||||||
|
utils::hash::hash_256_t path_key;
|
||||||
|
std::tie(path_key, std::ignore) =
|
||||||
|
path_cfg.create_subkey(kdf_context::path, path_cfg.unique_id, master_key);
|
||||||
|
|
||||||
|
kdf_headers_->second = path_cfg.to_header();
|
||||||
|
}
|
||||||
|
|
||||||
|
void encrypting_reader::create_encrypted_paths(
|
||||||
|
std::string_view file_name,
|
||||||
|
std::optional<std::string> relative_parent_path) {
|
||||||
|
data_buffer result;
|
||||||
|
utils::encryption::encrypt_data(
|
||||||
|
keys_.second, reinterpret_cast<const unsigned char *>(file_name.data()),
|
||||||
|
file_name.size(), result);
|
||||||
|
if (kdf_headers_.has_value()) {
|
||||||
|
result.insert(result.begin(), kdf_headers_->second.begin(),
|
||||||
|
kdf_headers_->second.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
encrypted_file_name_ =
|
||||||
|
kdf_headers_.has_value()
|
||||||
|
? macaron::Base64::EncodeUrlSafe(result.data(), result.size())
|
||||||
|
: utils::collection::to_hex_string(result);
|
||||||
|
|
||||||
|
if (not relative_parent_path.has_value()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto &part :
|
||||||
|
utils::string::split(relative_parent_path.value(),
|
||||||
|
utils::path::directory_seperator, false)) {
|
||||||
|
utils::encryption::encrypt_data(
|
||||||
|
keys_.second, reinterpret_cast<const unsigned char *>(part.c_str()),
|
||||||
|
strnlen(part.c_str(), part.size()), result);
|
||||||
|
if (kdf_headers_.has_value()) {
|
||||||
|
result.insert(result.begin(), kdf_headers_->second.begin(),
|
||||||
|
kdf_headers_->second.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
encrypted_file_path_ +=
|
||||||
|
'/' +
|
||||||
|
(kdf_headers_.has_value()
|
||||||
|
? macaron::Base64::EncodeUrlSafe(result.data(), result.size())
|
||||||
|
: utils::collection::to_hex_string(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
encrypted_file_path_ += '/' + encrypted_file_name_;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto encrypting_reader::create_iostream() const
|
auto encrypting_reader::create_iostream() const
|
||||||
@@ -388,24 +567,93 @@ auto encrypting_reader::create_iostream() const
|
|||||||
std::make_unique<encrypting_streambuf>(*this));
|
std::make_unique<encrypting_streambuf>(*this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto encrypting_reader::get_kdf_config_for_data() const
|
||||||
|
-> std::optional<kdf_config> {
|
||||||
|
MONITARR_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
|
if (not kdf_headers_.has_value()) {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
kdf_config cfg;
|
||||||
|
if (not kdf_config::from_header(kdf_headers_->first, cfg)) {
|
||||||
|
throw utils::error::create_exception(function_name,
|
||||||
|
{
|
||||||
|
"invalid kdf header",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return cfg;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto encrypting_reader::get_kdf_config_for_path() const
|
||||||
|
-> std::optional<kdf_config> {
|
||||||
|
MONITARR_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
|
if (not kdf_headers_.has_value()) {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
kdf_config cfg;
|
||||||
|
if (not kdf_config::from_header(kdf_headers_->second, cfg)) {
|
||||||
|
throw utils::error::create_exception(function_name,
|
||||||
|
{
|
||||||
|
"invalid kdf header",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return cfg;
|
||||||
|
}
|
||||||
|
|
||||||
auto encrypting_reader::reader_function(char *buffer, size_t size,
|
auto encrypting_reader::reader_function(char *buffer, size_t size,
|
||||||
size_t nitems) -> size_t {
|
size_t nitems) -> size_t {
|
||||||
MONITARR_USES_FUNCTION_NAME();
|
MONITARR_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
const auto read_size = static_cast<std::size_t>(std::min(
|
auto read_size =
|
||||||
static_cast<std::uint64_t>(size * nitems), total_size_ - read_offset_));
|
static_cast<std::uint64_t>(size) * static_cast<std::uint64_t>(nitems);
|
||||||
|
if (read_size == 0U) {
|
||||||
|
return 0U;
|
||||||
|
}
|
||||||
|
|
||||||
auto chunk = read_offset_ / encrypted_chunk_size_;
|
std::span<char> dest(buffer, read_size);
|
||||||
auto chunk_offset = read_offset_ % encrypted_chunk_size_;
|
auto read_offset{read_offset_};
|
||||||
std::size_t total_read{};
|
std::size_t total_read{};
|
||||||
|
auto total_size{total_size_};
|
||||||
|
|
||||||
auto ret = false;
|
if (kdf_headers_.has_value()) {
|
||||||
if (read_offset_ < total_size_) {
|
auto &hdr = kdf_headers_->first;
|
||||||
|
total_size -= hdr.size();
|
||||||
|
|
||||||
|
if (read_offset < hdr.size()) {
|
||||||
|
auto to_read{
|
||||||
|
utils::calculate_read_size(hdr.size(), read_size, read_offset),
|
||||||
|
};
|
||||||
|
read_offset_ += to_read;
|
||||||
|
|
||||||
|
std::memcpy(&dest[total_read], &hdr.at(read_offset), to_read);
|
||||||
|
if (read_size - to_read == 0) {
|
||||||
|
return to_read;
|
||||||
|
}
|
||||||
|
|
||||||
|
read_offset = 0U;
|
||||||
|
read_size -= to_read;
|
||||||
|
total_read += to_read;
|
||||||
|
} else {
|
||||||
|
read_offset -= hdr.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto chunk = static_cast<std::size_t>(read_offset / encrypted_chunk_size_);
|
||||||
|
auto chunk_offset =
|
||||||
|
static_cast<std::size_t>(read_offset % encrypted_chunk_size_);
|
||||||
|
auto remain = utils::calculate_read_size(total_size, read_size, read_offset);
|
||||||
|
|
||||||
|
auto ret{false};
|
||||||
|
if (read_offset < total_size) {
|
||||||
try {
|
try {
|
||||||
ret = true;
|
ret = true;
|
||||||
auto remain = read_size;
|
|
||||||
while (not get_stop_requested() && ret && (remain != 0U)) {
|
while (not get_stop_requested() && ret && (remain != 0U)) {
|
||||||
if (chunk_buffers_.find(chunk) == chunk_buffers_.end()) {
|
if (not chunk_buffers_.contains(chunk)) {
|
||||||
auto &chunk_buffer = chunk_buffers_[chunk];
|
auto &chunk_buffer = chunk_buffers_[chunk];
|
||||||
data_buffer file_data(chunk == last_data_chunk_
|
data_buffer file_data(chunk == last_data_chunk_
|
||||||
? last_data_chunk_size_
|
? last_data_chunk_size_
|
||||||
@@ -413,24 +661,26 @@ auto encrypting_reader::reader_function(char *buffer, size_t size,
|
|||||||
chunk_buffer.resize(file_data.size() + encryption_header_size);
|
chunk_buffer.resize(file_data.size() + encryption_header_size);
|
||||||
|
|
||||||
std::size_t bytes_read{};
|
std::size_t bytes_read{};
|
||||||
if ((ret = source_file_->read(file_data, chunk * data_chunk_size_,
|
ret = source_file_->read(
|
||||||
&bytes_read))) {
|
file_data,
|
||||||
utils::encryption::encrypt_data(iv_list_.at(chunk), key_, file_data,
|
static_cast<std::uint64_t>(chunk) *
|
||||||
chunk_buffer);
|
static_cast<std::uint64_t>(data_chunk_size_),
|
||||||
|
&bytes_read);
|
||||||
|
if (ret) {
|
||||||
|
utils::encryption::encrypt_data(iv_list_.at(chunk), keys_.first,
|
||||||
|
file_data, chunk_buffer);
|
||||||
}
|
}
|
||||||
} else if (chunk) {
|
} else if (chunk != 0U) {
|
||||||
chunk_buffers_.erase(chunk - 1u);
|
chunk_buffers_.erase(chunk - 1U);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto &chunk_buffer = chunk_buffers_[chunk];
|
auto &chunk_buffer = chunk_buffers_[chunk];
|
||||||
const auto to_read = std::min(
|
auto to_read = std::min(chunk_buffer.size() - chunk_offset, remain);
|
||||||
static_cast<std::size_t>(chunk_buffer.size() - chunk_offset),
|
std::memcpy(&dest[total_read], &chunk_buffer[chunk_offset], to_read);
|
||||||
remain);
|
|
||||||
std::memcpy(buffer + total_read, &chunk_buffer[chunk_offset], to_read);
|
|
||||||
total_read += to_read;
|
total_read += to_read;
|
||||||
remain -= to_read;
|
remain -= to_read;
|
||||||
chunk_offset = 0u;
|
chunk_offset = 0U;
|
||||||
chunk++;
|
++chunk;
|
||||||
read_offset_ += to_read;
|
read_offset_ += to_read;
|
||||||
}
|
}
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
|
|||||||
@@ -23,11 +23,130 @@
|
|||||||
|
|
||||||
#include "utils/encryption.hpp"
|
#include "utils/encryption.hpp"
|
||||||
|
|
||||||
|
#include "utils/base64.hpp"
|
||||||
#include "utils/collection.hpp"
|
#include "utils/collection.hpp"
|
||||||
|
#include "utils/config.hpp"
|
||||||
#include "utils/encrypting_reader.hpp"
|
#include "utils/encrypting_reader.hpp"
|
||||||
|
#include "utils/hash.hpp"
|
||||||
#include "utils/path.hpp"
|
#include "utils/path.hpp"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
constexpr auto resize_by(monitarr::data_span &data, std::size_t /* size */)
|
||||||
|
-> monitarr::data_span & {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto resize_by(monitarr::data_buffer &data, std::size_t size)
|
||||||
|
-> monitarr::data_buffer & {
|
||||||
|
data.resize(data.size() + size);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
namespace monitarr::utils::encryption {
|
namespace monitarr::utils::encryption {
|
||||||
|
auto kdf_config::to_header() const -> data_buffer {
|
||||||
|
kdf_config tmp{*this};
|
||||||
|
tmp.checksum = boost::endian::native_to_big(tmp.checksum);
|
||||||
|
tmp.unique_id = boost::endian::native_to_big(tmp.unique_id);
|
||||||
|
|
||||||
|
data_buffer ret(size());
|
||||||
|
std::memcpy(ret.data(), &tmp, ret.size());
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto kdf_config::generate_checksum() const -> std::uint64_t {
|
||||||
|
MONITARR_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
|
kdf_config tmp = *this;
|
||||||
|
tmp.checksum = 0;
|
||||||
|
|
||||||
|
auto hash = utils::hash::create_hash_blake2b_64(tmp.to_header());
|
||||||
|
std::uint64_t ret{};
|
||||||
|
std::memcpy(&ret, hash.data(), hash.size());
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto kdf_config::from_header(data_cspan data, kdf_config &cfg,
|
||||||
|
bool ignore_checksum) -> bool {
|
||||||
|
if (data.size() < kdf_config::size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::memcpy(&cfg, data.data(), kdf_config::size());
|
||||||
|
|
||||||
|
cfg.checksum = boost::endian::big_to_native(cfg.checksum);
|
||||||
|
cfg.unique_id = boost::endian::big_to_native(cfg.unique_id);
|
||||||
|
return cfg.version == kdf_version::v1 && cfg.kdf == kdf_type::argon2id &&
|
||||||
|
cfg.memlimit >= memlimit_level::level1 &&
|
||||||
|
cfg.memlimit <= memlimit_level::level4 &&
|
||||||
|
cfg.opslimit >= opslimit_level::level1 &&
|
||||||
|
cfg.opslimit <= opslimit_level::level3 &&
|
||||||
|
(ignore_checksum || cfg.checksum == cfg.generate_checksum());
|
||||||
|
}
|
||||||
|
|
||||||
|
void kdf_config::seal() {
|
||||||
|
randombytes_buf(salt.data(), salt.size());
|
||||||
|
checksum = generate_checksum();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto decrypt_file_name(std::string_view encryption_token,
|
||||||
|
std::string &file_name) -> bool {
|
||||||
|
data_buffer buffer;
|
||||||
|
if (not utils::collection::from_hex_string(file_name, buffer)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
file_name.clear();
|
||||||
|
return utils::encryption::decrypt_data(encryption_token, buffer, file_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto decrypt_file_name(std::string_view encryption_token, const kdf_config &cfg,
|
||||||
|
std::string &file_name) -> bool {
|
||||||
|
MONITARR_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
|
try {
|
||||||
|
auto buffer = macaron::Base64::Decode(file_name);
|
||||||
|
|
||||||
|
file_name.clear();
|
||||||
|
return utils::encryption::decrypt_data(encryption_token, cfg, buffer,
|
||||||
|
file_name);
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
utils::error::handle_exception(function_name, e);
|
||||||
|
} catch (...) {
|
||||||
|
utils::error::handle_exception(function_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto decrypt_file_name(const utils::hash::hash_256_t &master_key,
|
||||||
|
std::string &file_name) -> bool {
|
||||||
|
MONITARR_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
|
try {
|
||||||
|
auto buffer = macaron::Base64::Decode(file_name);
|
||||||
|
|
||||||
|
utils::encryption::kdf_config path_cfg;
|
||||||
|
if (not utils::encryption::kdf_config::from_header(buffer, path_cfg)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto path_key = path_cfg.recreate_subkey(
|
||||||
|
utils::encryption::kdf_context::path, master_key);
|
||||||
|
|
||||||
|
file_name.clear();
|
||||||
|
return utils::encryption::decrypt_data(
|
||||||
|
path_key, &buffer[utils::encryption::kdf_config::size()],
|
||||||
|
buffer.size() - utils::encryption::kdf_config::size(), file_name);
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
utils::error::handle_exception(function_name, e);
|
||||||
|
} catch (...) {
|
||||||
|
utils::error::handle_exception(function_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
auto decrypt_file_path(std::string_view encryption_token,
|
auto decrypt_file_path(std::string_view encryption_token,
|
||||||
std::string &file_path) -> bool {
|
std::string &file_path) -> bool {
|
||||||
std::vector<std::string> decrypted_parts;
|
std::vector<std::string> decrypted_parts;
|
||||||
@@ -49,21 +168,83 @@ auto decrypt_file_path(std::string_view encryption_token,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto decrypt_file_name(std::string_view encryption_token,
|
auto decrypt_file_path(std::string_view encryption_token, const kdf_config &cfg,
|
||||||
std::string &file_name) -> bool {
|
std::string &file_path) -> bool {
|
||||||
data_buffer buffer;
|
std::vector<std::string> decrypted_parts;
|
||||||
if (not utils::collection::from_hex_string(file_name, buffer)) {
|
for (const auto &part : std::filesystem::path(file_path)) {
|
||||||
|
auto file_name = part.string();
|
||||||
|
if (file_name == "/") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (not decrypt_file_name(encryption_token, cfg, file_name)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
file_name.clear();
|
decrypted_parts.push_back(file_name);
|
||||||
return utils::encryption::decrypt_data(encryption_token, buffer, file_name);
|
}
|
||||||
|
|
||||||
|
file_path =
|
||||||
|
utils::path::create_api_path(utils::string::join(decrypted_parts, '/'));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto read_encrypted_range(const http_range &range,
|
auto decrypt_file_path(const utils::hash::hash_256_t &master_key,
|
||||||
const utils::encryption::hash_256_t &key,
|
std::string &file_path) -> bool {
|
||||||
|
std::vector<std::string> decrypted_parts;
|
||||||
|
for (const auto &part : std::filesystem::path(file_path)) {
|
||||||
|
auto file_name = part.string();
|
||||||
|
if (file_name == "/") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (not decrypt_file_name(master_key, file_name)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
decrypted_parts.push_back(file_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
file_path =
|
||||||
|
utils::path::create_api_path(utils::string::join(decrypted_parts, '/'));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename data_t>
|
||||||
|
[[nodiscard]] auto
|
||||||
|
read_encrypted_range(http_range range, const utils::hash::hash_256_t &key,
|
||||||
reader_func_t reader_func, std::uint64_t total_size,
|
reader_func_t reader_func, std::uint64_t total_size,
|
||||||
data_buffer &data) -> bool {
|
data_t &data, std::uint8_t file_header_size,
|
||||||
|
std::size_t &bytes_read) -> bool {
|
||||||
|
bytes_read = 0U;
|
||||||
|
|
||||||
|
{
|
||||||
|
if (total_size == 0U) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::uint64_t begin = range.begin;
|
||||||
|
std::uint64_t end = range.end;
|
||||||
|
|
||||||
|
if (begin >= total_size) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::uint64_t last = total_size - 1U;
|
||||||
|
if (end > last) {
|
||||||
|
end = last;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (end < begin) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
range = http_range{
|
||||||
|
.begin = begin,
|
||||||
|
.end = end,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
auto encrypted_chunk_size =
|
auto encrypted_chunk_size =
|
||||||
utils::encryption::encrypting_reader::get_encrypted_chunk_size();
|
utils::encryption::encrypting_reader::get_encrypted_chunk_size();
|
||||||
auto data_chunk_size =
|
auto data_chunk_size =
|
||||||
@@ -75,22 +256,22 @@ auto read_encrypted_range(const http_range &range,
|
|||||||
auto source_offset = static_cast<std::size_t>(range.begin % data_chunk_size);
|
auto source_offset = static_cast<std::size_t>(range.begin % data_chunk_size);
|
||||||
|
|
||||||
for (std::size_t chunk = start_chunk; chunk <= end_chunk; chunk++) {
|
for (std::size_t chunk = start_chunk; chunk <= end_chunk; chunk++) {
|
||||||
data_buffer cypher;
|
data_buffer cipher;
|
||||||
auto start_offset = chunk * encrypted_chunk_size;
|
auto start_offset = (chunk * encrypted_chunk_size) + file_header_size;
|
||||||
auto end_offset = std::min(
|
auto end_offset = std::min(
|
||||||
start_offset + (total_size - (chunk * data_chunk_size)) +
|
start_offset + (total_size - (chunk * data_chunk_size)) +
|
||||||
encryption_header_size - 1U,
|
encryption_header_size - 1U,
|
||||||
static_cast<std::uint64_t>(start_offset + encrypted_chunk_size - 1U));
|
static_cast<std::uint64_t>(start_offset + encrypted_chunk_size - 1U));
|
||||||
|
|
||||||
if (not reader_func(cypher, start_offset, end_offset)) {
|
if (not reader_func(cipher, start_offset, end_offset)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
data_buffer source_buffer;
|
data_buffer source_buffer;
|
||||||
if (not utils::encryption::decrypt_data(key, cypher, source_buffer)) {
|
if (not utils::encryption::decrypt_data(key, cipher, source_buffer)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
cypher.clear();
|
cipher.clear();
|
||||||
|
|
||||||
auto data_size = static_cast<std::size_t>(std::min(
|
auto data_size = static_cast<std::size_t>(std::min(
|
||||||
remain, static_cast<std::uint64_t>(data_chunk_size - source_offset)));
|
remain, static_cast<std::uint64_t>(data_chunk_size - source_offset)));
|
||||||
@@ -98,58 +279,8 @@ auto read_encrypted_range(const http_range &range,
|
|||||||
static_cast<std::int64_t>(source_offset)),
|
static_cast<std::int64_t>(source_offset)),
|
||||||
std::next(source_buffer.begin(),
|
std::next(source_buffer.begin(),
|
||||||
static_cast<std::int64_t>(source_offset + data_size)),
|
static_cast<std::int64_t>(source_offset + data_size)),
|
||||||
std::back_inserter(data));
|
std::next(resize_by(data, data_size).begin(),
|
||||||
remain -= data_size;
|
static_cast<std::int64_t>(bytes_read)));
|
||||||
source_offset = 0U;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto read_encrypted_range(const http_range &range,
|
|
||||||
const utils::encryption::hash_256_t &key,
|
|
||||||
reader_func_t reader_func, std::uint64_t total_size,
|
|
||||||
unsigned char *data, std::size_t size,
|
|
||||||
std::size_t &bytes_read) -> bool {
|
|
||||||
bytes_read = 0U;
|
|
||||||
|
|
||||||
auto encrypted_chunk_size =
|
|
||||||
utils::encryption::encrypting_reader::get_encrypted_chunk_size();
|
|
||||||
auto data_chunk_size =
|
|
||||||
utils::encryption::encrypting_reader::get_data_chunk_size();
|
|
||||||
|
|
||||||
auto start_chunk = static_cast<std::size_t>(range.begin / data_chunk_size);
|
|
||||||
auto end_chunk = static_cast<std::size_t>(range.end / data_chunk_size);
|
|
||||||
auto remain = range.end - range.begin + 1U;
|
|
||||||
auto source_offset = static_cast<std::size_t>(range.begin % data_chunk_size);
|
|
||||||
|
|
||||||
std::span dest_buffer(data, size);
|
|
||||||
for (std::size_t chunk = start_chunk; chunk <= end_chunk; chunk++) {
|
|
||||||
data_buffer cypher;
|
|
||||||
auto start_offset = chunk * encrypted_chunk_size;
|
|
||||||
auto end_offset = std::min(
|
|
||||||
start_offset + (total_size - (chunk * data_chunk_size)) +
|
|
||||||
encryption_header_size - 1U,
|
|
||||||
static_cast<std::uint64_t>(start_offset + encrypted_chunk_size - 1U));
|
|
||||||
|
|
||||||
if (not reader_func(cypher, start_offset, end_offset)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
data_buffer source_buffer;
|
|
||||||
if (not utils::encryption::decrypt_data(key, cypher, source_buffer)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
cypher.clear();
|
|
||||||
|
|
||||||
auto data_size = static_cast<std::size_t>(std::min(
|
|
||||||
remain, static_cast<std::uint64_t>(data_chunk_size - source_offset)));
|
|
||||||
std::copy(
|
|
||||||
std::next(source_buffer.begin(),
|
|
||||||
static_cast<std::int64_t>(source_offset)),
|
|
||||||
std::next(source_buffer.begin(),
|
|
||||||
static_cast<std::int64_t>(source_offset + data_size)),
|
|
||||||
std::next(dest_buffer.begin(), static_cast<std::int64_t>(bytes_read)));
|
|
||||||
remain -= data_size;
|
remain -= data_size;
|
||||||
bytes_read += data_size;
|
bytes_read += data_size;
|
||||||
source_offset = 0U;
|
source_offset = 0U;
|
||||||
@@ -157,6 +288,26 @@ auto read_encrypted_range(const http_range &range,
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto read_encrypted_range(const http_range &range,
|
||||||
|
const utils::hash::hash_256_t &key, bool uses_kdf,
|
||||||
|
reader_func_t reader_func, std::uint64_t total_size,
|
||||||
|
data_buffer &data) -> bool {
|
||||||
|
std::size_t bytes_read{};
|
||||||
|
return read_encrypted_range<data_buffer>(
|
||||||
|
range, key, reader_func, total_size, data,
|
||||||
|
uses_kdf ? kdf_config::size() : 0U, bytes_read);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto read_encrypted_range(
|
||||||
|
const http_range &range, const utils::hash::hash_256_t &key, bool uses_kdf,
|
||||||
|
reader_func_t reader_func, std::uint64_t total_size, unsigned char *data,
|
||||||
|
std::size_t size, std::size_t &bytes_read) -> bool {
|
||||||
|
data_span dest_buffer(data, size);
|
||||||
|
return read_encrypted_range<data_span>(
|
||||||
|
range, key, reader_func, total_size, dest_buffer,
|
||||||
|
uses_kdf ? kdf_config::size() : 0U, bytes_read);
|
||||||
|
}
|
||||||
} // namespace monitarr::utils::encryption
|
} // namespace monitarr::utils::encryption
|
||||||
|
|
||||||
#endif // defined(PROJECT_ENABLE_LIBSODIUM) && defined (PROJECT_ENABLE_BOOST)
|
#endif // defined(PROJECT_ENABLE_LIBSODIUM) && defined (PROJECT_ENABLE_BOOST)
|
||||||
|
|||||||
@@ -53,9 +53,11 @@ auto change_to_process_directory() -> bool {
|
|||||||
}
|
}
|
||||||
#else // !defined(_WIN32)
|
#else // !defined(_WIN32)
|
||||||
std::string path;
|
std::string path;
|
||||||
path.resize(PATH_MAX + 1);
|
path.resize(monitarr::max_path_length + 1);
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
proc_pidpath(getpid(), path.c_str(), path.size());
|
auto res = proc_pidpath(getpid(), reinterpret_cast<void *>(path.data()),
|
||||||
|
static_cast<uint32_t>(path.size()));
|
||||||
|
path = path.c_str();
|
||||||
#else // !defined(__APPLE__)
|
#else // !defined(__APPLE__)
|
||||||
auto res = readlink("/proc/self/exe", path.data(), path.size());
|
auto res = readlink("/proc/self/exe", path.data(), path.size());
|
||||||
if (res == -1) {
|
if (res == -1) {
|
||||||
@@ -119,7 +121,7 @@ auto get_free_drive_space(std::string_view path)
|
|||||||
try {
|
try {
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
ULARGE_INTEGER li{};
|
ULARGE_INTEGER li{};
|
||||||
if (not::GetDiskFreeSpaceEx(std::string{path}.c_str(), &li, nullptr,
|
if (not ::GetDiskFreeSpaceEx(std::string{path}.c_str(), &li, nullptr,
|
||||||
nullptr)) {
|
nullptr)) {
|
||||||
throw utils::error::create_exception(
|
throw utils::error::create_exception(
|
||||||
function_name, {
|
function_name, {
|
||||||
@@ -133,8 +135,8 @@ auto get_free_drive_space(std::string_view path)
|
|||||||
#endif // defined(_WIN32)
|
#endif // defined(_WIN32)
|
||||||
|
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
struct statfs64 st{};
|
struct statfs64 u_stat{};
|
||||||
if (statfs64(std::string{path}.c_str(), &st) != 0) {
|
if (statfs64(std::string{path}.c_str(), &u_stat) != 0) {
|
||||||
throw utils::error::create_exception(
|
throw utils::error::create_exception(
|
||||||
function_name, {
|
function_name, {
|
||||||
"failed to get free disk space",
|
"failed to get free disk space",
|
||||||
@@ -143,12 +145,12 @@ auto get_free_drive_space(std::string_view path)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return st.f_bfree * static_cast<std::uint64_t>(st.f_bsize);
|
return u_stat.f_bfree * static_cast<std::uint64_t>(u_stat.f_bsize);
|
||||||
#endif // defined(__linux__)
|
#endif // defined(__linux__)
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
struct statvfs st{};
|
struct statvfs u_stat{};
|
||||||
if (statvfs(path.c_str(), &st) != 0) {
|
if (statvfs(std::string{path}.c_str(), &u_stat) != 0) {
|
||||||
throw utils::error::create_exception(
|
throw utils::error::create_exception(
|
||||||
function_name, {
|
function_name, {
|
||||||
"failed to get free disk space",
|
"failed to get free disk space",
|
||||||
@@ -157,7 +159,7 @@ auto get_free_drive_space(std::string_view path)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return st.f_bfree * static_cast<std::uint64_t>(st.f_frsize);
|
return u_stat.f_bfree * static_cast<std::uint64_t>(u_stat.f_frsize);
|
||||||
#endif // defined(__APPLE__)
|
#endif // defined(__APPLE__)
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
utils::error::handle_exception(function_name, e);
|
utils::error::handle_exception(function_name, e);
|
||||||
@@ -207,6 +209,7 @@ auto get_times(std::string_view path) -> std::optional<file_times> {
|
|||||||
if (res) {
|
if (res) {
|
||||||
ret.accessed =
|
ret.accessed =
|
||||||
utils::time::windows_file_time_to_unix_time(times.at(1U));
|
utils::time::windows_file_time_to_unix_time(times.at(1U));
|
||||||
|
ret.changed = utils::time::windows_file_time_to_unix_time(times.at(2U));
|
||||||
ret.created = utils::time::windows_file_time_to_unix_time(times.at(0U));
|
ret.created = utils::time::windows_file_time_to_unix_time(times.at(0U));
|
||||||
ret.modified =
|
ret.modified =
|
||||||
utils::time::windows_file_time_to_unix_time(times.at(2U));
|
utils::time::windows_file_time_to_unix_time(times.at(2U));
|
||||||
@@ -215,8 +218,8 @@ auto get_times(std::string_view path) -> std::optional<file_times> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct _stat64 st{};
|
struct _stat64 u_stat{};
|
||||||
if (_stat64(std::string{path}.c_str(), &st) != 0) {
|
if (_stat64(std::string{path}.c_str(), &u_stat) != 0) {
|
||||||
throw utils::error::create_exception(
|
throw utils::error::create_exception(
|
||||||
function_name, {
|
function_name, {
|
||||||
"failed to get file times",
|
"failed to get file times",
|
||||||
@@ -225,13 +228,14 @@ auto get_times(std::string_view path) -> std::optional<file_times> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ret.accessed = utils::time::windows_time_t_to_unix_time(st.st_atime);
|
ret.accessed = utils::time::windows_time_t_to_unix_time(u_stat.st_atime);
|
||||||
ret.created = utils::time::windows_time_t_to_unix_time(st.st_ctime);
|
ret.changed = utils::time::windows_time_t_to_unix_time(u_stat.st_ctime);
|
||||||
ret.modified = utils::time::windows_time_t_to_unix_time(st.st_mtime);
|
ret.created = utils::time::windows_time_t_to_unix_time(u_stat.st_ctime);
|
||||||
ret.written = utils::time::windows_time_t_to_unix_time(st.st_mtime);
|
ret.modified = utils::time::windows_time_t_to_unix_time(u_stat.st_mtime);
|
||||||
|
ret.written = utils::time::windows_time_t_to_unix_time(u_stat.st_mtime);
|
||||||
#else // !defined(_WIN32)
|
#else // !defined(_WIN32)
|
||||||
struct stat64 st{};
|
struct stat64 u_stat{};
|
||||||
if (stat64(std::string{path}.c_str(), &st) != 0) {
|
if (stat64(std::string{path}.c_str(), &u_stat) != 0) {
|
||||||
throw utils::error::create_exception(
|
throw utils::error::create_exception(
|
||||||
function_name, {
|
function_name, {
|
||||||
"failed to get file times",
|
"failed to get file times",
|
||||||
@@ -240,19 +244,39 @@ auto get_times(std::string_view path) -> std::optional<file_times> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ret.accessed = static_cast<std::uint64_t>(st.st_atim.tv_nsec) +
|
#if defined(__APPLE__)
|
||||||
static_cast<std::uint64_t>(st.st_atim.tv_sec) *
|
ret.accessed = static_cast<std::uint64_t>(u_stat.st_atimespec.tv_nsec) +
|
||||||
|
static_cast<std::uint64_t>(u_stat.st_atimespec.tv_sec) *
|
||||||
utils::time::NANOS_PER_SECOND;
|
utils::time::NANOS_PER_SECOND;
|
||||||
ret.created = static_cast<std::uint64_t>(st.st_ctim.tv_nsec) +
|
ret.created = static_cast<std::uint64_t>(u_stat.st_birthtimespec.tv_nsec) +
|
||||||
static_cast<std::uint64_t>(st.st_ctim.tv_sec) *
|
static_cast<std::uint64_t>(u_stat.st_birthtimespec.tv_sec) *
|
||||||
utils::time::NANOS_PER_SECOND;
|
utils::time::NANOS_PER_SECOND;
|
||||||
ret.modified = static_cast<std::uint64_t>(st.st_mtim.tv_nsec) +
|
ret.changed = static_cast<std::uint64_t>(u_stat.st_ctimespec.tv_nsec) +
|
||||||
static_cast<std::uint64_t>(st.st_mtim.tv_sec) *
|
static_cast<std::uint64_t>(u_stat.st_ctimespec.tv_sec) *
|
||||||
utils::time::NANOS_PER_SECOND;
|
utils::time::NANOS_PER_SECOND;
|
||||||
ret.written = static_cast<std::uint64_t>(st.st_mtim.tv_nsec) +
|
ret.modified = static_cast<std::uint64_t>(u_stat.st_mtimespec.tv_nsec) +
|
||||||
static_cast<std::uint64_t>(st.st_mtim.tv_sec) *
|
static_cast<std::uint64_t>(u_stat.st_mtimespec.tv_sec) *
|
||||||
utils::time::NANOS_PER_SECOND;
|
utils::time::NANOS_PER_SECOND;
|
||||||
|
ret.written = static_cast<std::uint64_t>(u_stat.st_mtimespec.tv_nsec) +
|
||||||
|
static_cast<std::uint64_t>(u_stat.st_mtimespec.tv_sec) *
|
||||||
|
utils::time::NANOS_PER_SECOND;
|
||||||
|
#else // !defined(__APPLE__)
|
||||||
|
ret.accessed = static_cast<std::uint64_t>(u_stat.st_atim.tv_nsec) +
|
||||||
|
static_cast<std::uint64_t>(u_stat.st_atim.tv_sec) *
|
||||||
|
utils::time::NANOS_PER_SECOND;
|
||||||
|
ret.changed = static_cast<std::uint64_t>(u_stat.st_ctim.tv_nsec) +
|
||||||
|
static_cast<std::uint64_t>(u_stat.st_ctim.tv_sec) *
|
||||||
|
utils::time::NANOS_PER_SECOND;
|
||||||
|
ret.created = static_cast<std::uint64_t>(u_stat.st_ctim.tv_nsec) +
|
||||||
|
static_cast<std::uint64_t>(u_stat.st_ctim.tv_sec) *
|
||||||
|
utils::time::NANOS_PER_SECOND;
|
||||||
|
ret.modified = static_cast<std::uint64_t>(u_stat.st_mtim.tv_nsec) +
|
||||||
|
static_cast<std::uint64_t>(u_stat.st_mtim.tv_sec) *
|
||||||
|
utils::time::NANOS_PER_SECOND;
|
||||||
|
ret.written = static_cast<std::uint64_t>(u_stat.st_mtim.tv_nsec) +
|
||||||
|
static_cast<std::uint64_t>(u_stat.st_mtim.tv_sec) *
|
||||||
|
utils::time::NANOS_PER_SECOND;
|
||||||
|
#endif // defined(__APPLE__)
|
||||||
#endif // defined(_WIN32)
|
#endif // defined(_WIN32)
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@@ -276,7 +300,7 @@ auto get_total_drive_space(std::string_view path)
|
|||||||
try {
|
try {
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
ULARGE_INTEGER li{};
|
ULARGE_INTEGER li{};
|
||||||
if (not::GetDiskFreeSpaceEx(std::string{path}.c_str(), nullptr, &li,
|
if (not ::GetDiskFreeSpaceEx(std::string{path}.c_str(), nullptr, &li,
|
||||||
nullptr)) {
|
nullptr)) {
|
||||||
throw utils::error::create_exception(
|
throw utils::error::create_exception(
|
||||||
function_name, {
|
function_name, {
|
||||||
@@ -290,8 +314,8 @@ auto get_total_drive_space(std::string_view path)
|
|||||||
#endif // defined(_WIN32)
|
#endif // defined(_WIN32)
|
||||||
|
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
struct statfs64 st{};
|
struct statfs64 u_stat{};
|
||||||
if (statfs64(std::string{path}.c_str(), &st) != 0) {
|
if (statfs64(std::string{path}.c_str(), &u_stat) != 0) {
|
||||||
throw utils::error::create_exception(
|
throw utils::error::create_exception(
|
||||||
function_name, {
|
function_name, {
|
||||||
"failed to get total disk space",
|
"failed to get total disk space",
|
||||||
@@ -300,12 +324,12 @@ auto get_total_drive_space(std::string_view path)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return st.f_blocks * static_cast<std::uint64_t>(st.f_bsize);
|
return u_stat.f_blocks * static_cast<std::uint64_t>(u_stat.f_bsize);
|
||||||
#endif // defined(__linux__)
|
#endif // defined(__linux__)
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
struct statvfs st{};
|
struct statvfs u_stat{};
|
||||||
if (statvfs(path.c_str(), &st) != 0) {
|
if (statvfs(std::string{path}.c_str(), &u_stat) != 0) {
|
||||||
throw utils::error::create_exception(
|
throw utils::error::create_exception(
|
||||||
function_name, {
|
function_name, {
|
||||||
"failed to get total disk space",
|
"failed to get total disk space",
|
||||||
@@ -314,7 +338,7 @@ auto get_total_drive_space(std::string_view path)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return st.f_blocks * static_cast<std::uint64_t>(st.f_frsize);
|
return u_stat.f_blocks * static_cast<std::uint64_t>(u_stat.f_frsize);
|
||||||
#endif // defined(__APPLE__)
|
#endif // defined(__APPLE__)
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
utils::error::handle_exception(function_name, e);
|
utils::error::handle_exception(function_name, e);
|
||||||
@@ -376,7 +400,7 @@ auto read_json_file(std::string_view path, nlohmann::json &data) -> bool {
|
|||||||
try {
|
try {
|
||||||
auto abs_path = utils::path::absolute(path);
|
auto abs_path = utils::path::absolute(path);
|
||||||
auto file = file::open_file(abs_path);
|
auto file = file::open_file(abs_path);
|
||||||
if (not*file) {
|
if (not *file) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -498,8 +522,7 @@ auto write_json_file(std::wstring_view path, const nlohmann::json &data)
|
|||||||
#endif // defined(PROJECT_ENABLE_JSON)
|
#endif // defined(PROJECT_ENABLE_JSON)
|
||||||
|
|
||||||
#if defined(PROJECT_ENABLE_LIBDSM)
|
#if defined(PROJECT_ENABLE_LIBDSM)
|
||||||
static constexpr const auto validate_smb_path =
|
static constexpr auto validate_smb_path = [](std::string_view path) -> bool {
|
||||||
[](std::string_view path) -> bool {
|
|
||||||
return (not utils::string::begins_with(path, "///") &&
|
return (not utils::string::begins_with(path, "///") &&
|
||||||
utils::string::begins_with(path, "//") &&
|
utils::string::begins_with(path, "//") &&
|
||||||
// not utils::string::contains(path, " ") &&
|
// not utils::string::contains(path, " ") &&
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
*/
|
*/
|
||||||
#include "utils/file_directory.hpp"
|
#include "utils/file_directory.hpp"
|
||||||
|
|
||||||
|
#include "utils/com_init_wrapper.hpp"
|
||||||
#include "utils/common.hpp"
|
#include "utils/common.hpp"
|
||||||
#include "utils/error.hpp"
|
#include "utils/error.hpp"
|
||||||
#include "utils/string.hpp"
|
#include "utils/string.hpp"
|
||||||
@@ -83,17 +84,19 @@ auto traverse_directory(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
struct dirent *de{nullptr};
|
struct dirent *entry{nullptr};
|
||||||
while (res && (de = readdir(root)) && !is_stop_requested()) {
|
while (res && (entry = ::readdir(root)) && !is_stop_requested()) {
|
||||||
if (de->d_type == DT_DIR) {
|
if (entry->d_type == DT_DIR) {
|
||||||
if ((std::string_view(de->d_name) != ".") &&
|
if ((std::string_view(entry->d_name) == ".") ||
|
||||||
(std::string_view(de->d_name) != "..")) {
|
(std::string_view(entry->d_name) == "..")) {
|
||||||
res = directory_action(monitarr::utils::file::directory(
|
continue;
|
||||||
monitarr::utils::path::combine(path, {de->d_name})));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
res = directory_action(monitarr::utils::file::directory(
|
||||||
|
monitarr::utils::path::combine(path, {entry->d_name})));
|
||||||
} else {
|
} else {
|
||||||
res = file_action(monitarr::utils::file::file(
|
res = file_action(monitarr::utils::file::file(
|
||||||
monitarr::utils::path::combine(path, {de->d_name})));
|
monitarr::utils::path::combine(path, {entry->d_name})));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,21 +108,72 @@ auto traverse_directory(
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace monitarr::utils::file {
|
namespace monitarr::utils::file {
|
||||||
auto directory::copy_to(std::string_view new_path,
|
auto directory::copy_to(std::string_view new_path, bool overwrite) const
|
||||||
bool overwrite) const -> bool {
|
-> bool {
|
||||||
MONITARR_USES_FUNCTION_NAME();
|
MONITARR_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
throw utils::error::create_exception(
|
if (not exists()) {
|
||||||
function_name, {
|
throw utils::error::create_exception(function_name,
|
||||||
|
{
|
||||||
"failed to copy directory",
|
"failed to copy directory",
|
||||||
"not implemented",
|
"source does not exist",
|
||||||
utils::string::from_bool(overwrite),
|
|
||||||
new_path,
|
|
||||||
path_,
|
path_,
|
||||||
|
std::string{new_path},
|
||||||
});
|
});
|
||||||
} catch (const std::exception &e) {
|
}
|
||||||
utils::error::handle_exception(function_name, e);
|
|
||||||
|
auto src_root = utils::path::finalize(path_);
|
||||||
|
auto dst_root = utils::path::finalize(new_path);
|
||||||
|
|
||||||
|
if (directory{dst_root}.exists()) {
|
||||||
|
auto src_base = utils::path::strip_to_file_name(src_root);
|
||||||
|
dst_root = utils::path::combine(dst_root, {src_base});
|
||||||
|
} else {
|
||||||
|
auto dst_parent = utils::path::get_parent_path(dst_root);
|
||||||
|
if (not dst_parent.empty() && not directory{dst_parent}.exists()) {
|
||||||
|
auto parent_parent = utils::path::get_parent_path(dst_parent);
|
||||||
|
auto last_piece = utils::path::strip_to_file_name(dst_parent);
|
||||||
|
[[maybe_unused]] auto sub_dir =
|
||||||
|
directory{parent_parent}.create_directory(last_piece);
|
||||||
|
}
|
||||||
|
if (not directory{dst_root}.exists()) {
|
||||||
|
auto root_parent = utils::path::get_parent_path(dst_root);
|
||||||
|
auto root_name = utils::path::strip_to_file_name(dst_root);
|
||||||
|
[[maybe_unused]] auto sub_dir =
|
||||||
|
directory{root_parent}.create_directory(root_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto success = traverse_directory(
|
||||||
|
src_root,
|
||||||
|
[this, &dst_root, &src_root](auto &&dir_item) -> bool {
|
||||||
|
auto child_src = dir_item.get_path();
|
||||||
|
auto rel_path = utils::path::get_relative_path(child_src, src_root);
|
||||||
|
auto child_dst = utils::path::combine(dst_root, {rel_path});
|
||||||
|
|
||||||
|
auto child_parent = utils::path::get_parent_path(child_dst);
|
||||||
|
auto child_name = utils::path::strip_to_file_name(child_dst);
|
||||||
|
[[maybe_unused]] auto sub_dir =
|
||||||
|
directory{child_parent}.create_directory(child_name);
|
||||||
|
return not is_stop_requested();
|
||||||
|
},
|
||||||
|
[this, &dst_root, overwrite, &src_root](auto &&file_item) -> bool {
|
||||||
|
auto child_src = file_item.get_path();
|
||||||
|
auto rel_path = utils::path::get_relative_path(child_src, src_root);
|
||||||
|
auto child_dst = utils::path::combine(dst_root, {rel_path});
|
||||||
|
|
||||||
|
if (not file{child_src}.copy_to(child_dst, overwrite)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return not is_stop_requested();
|
||||||
|
},
|
||||||
|
stop_requested_);
|
||||||
|
|
||||||
|
return success && not is_stop_requested();
|
||||||
|
} catch (const std::exception &ex) {
|
||||||
|
utils::error::handle_exception(function_name, ex);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
utils::error::handle_exception(function_name);
|
utils::error::handle_exception(function_name);
|
||||||
}
|
}
|
||||||
@@ -135,7 +189,7 @@ auto directory::count(bool recursive) const -> std::uint64_t {
|
|||||||
|
|
||||||
traverse_directory(
|
traverse_directory(
|
||||||
path_,
|
path_,
|
||||||
[&ret, &recursive](auto dir_item) -> bool {
|
[&ret, &recursive](auto &&dir_item) -> bool {
|
||||||
if (recursive) {
|
if (recursive) {
|
||||||
ret += dir_item.count(true);
|
ret += dir_item.count(true);
|
||||||
}
|
}
|
||||||
@@ -143,7 +197,7 @@ auto directory::count(bool recursive) const -> std::uint64_t {
|
|||||||
++ret;
|
++ret;
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
[&ret](auto /* file_item */) -> bool {
|
[&ret](auto && /* file_item */) -> bool {
|
||||||
++ret;
|
++ret;
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
@@ -170,6 +224,8 @@ auto directory::create_directory(std::string_view path) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
|
[[maybe_unused]] thread_local const utils::com_init_wrapper wrapper;
|
||||||
|
|
||||||
auto res = ::SHCreateDirectory(nullptr,
|
auto res = ::SHCreateDirectory(nullptr,
|
||||||
utils::string::from_utf8(abs_path).c_str());
|
utils::string::from_utf8(abs_path).c_str());
|
||||||
if (res != ERROR_SUCCESS) {
|
if (res != ERROR_SUCCESS) {
|
||||||
@@ -213,8 +269,8 @@ auto directory::exists() const -> bool {
|
|||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
return ::PathIsDirectoryA(path_.c_str()) != 0;
|
return ::PathIsDirectoryA(path_.c_str()) != 0;
|
||||||
#else // !defined(_WIN32)
|
#else // !defined(_WIN32)
|
||||||
struct stat64 st {};
|
struct stat64 u_stat{};
|
||||||
return (stat64(path_.c_str(), &st) == 0 && S_ISDIR(st.st_mode));
|
return (stat64(path_.c_str(), &u_stat) == 0 && S_ISDIR(u_stat.st_mode));
|
||||||
#endif // defined(_WIN32)
|
#endif // defined(_WIN32)
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -247,14 +303,14 @@ auto directory::get_directories() const -> std::vector<fs_directory_t> {
|
|||||||
|
|
||||||
traverse_directory(
|
traverse_directory(
|
||||||
path_,
|
path_,
|
||||||
[this, &ret](auto dir_item) -> bool {
|
[this, &ret](auto &&dir_item) -> bool {
|
||||||
ret.emplace_back(fs_directory_t{
|
ret.emplace_back(fs_directory_t{
|
||||||
new directory(dir_item.get_path(), stop_requested_),
|
new directory(dir_item.get_path(), stop_requested_),
|
||||||
});
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
[](auto /* file_item */) -> bool { return true; }, stop_requested_);
|
[](auto && /* file_item */) -> bool { return true; }, stop_requested_);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
@@ -266,8 +322,8 @@ auto directory::get_directories() const -> std::vector<fs_directory_t> {
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto directory::create_file(std::string_view file_name,
|
auto directory::create_file(std::string_view file_name, bool read_only) const
|
||||||
bool read_only) const -> fs_file_t {
|
-> fs_file_t {
|
||||||
MONITARR_USES_FUNCTION_NAME();
|
MONITARR_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -306,8 +362,8 @@ auto directory::get_files() const -> std::vector<fs_file_t> {
|
|||||||
std::vector<fs_file_t> ret{};
|
std::vector<fs_file_t> ret{};
|
||||||
|
|
||||||
traverse_directory(
|
traverse_directory(
|
||||||
path_, [](auto /* dir_item */) -> bool { return true; },
|
path_, [](auto && /* dir_item */) -> bool { return true; },
|
||||||
[&ret](auto file_item) -> bool {
|
[&ret](auto &&file_item) -> bool {
|
||||||
ret.emplace_back(fs_file_t{
|
ret.emplace_back(fs_file_t{
|
||||||
new file(file_item.get_path()),
|
new file(file_item.get_path()),
|
||||||
});
|
});
|
||||||
@@ -333,13 +389,13 @@ auto directory::get_items() const -> std::vector<fs_item_t> {
|
|||||||
|
|
||||||
traverse_directory(
|
traverse_directory(
|
||||||
path_,
|
path_,
|
||||||
[this, &ret](auto dir_item) -> bool {
|
[this, &ret](auto &&dir_item) -> bool {
|
||||||
ret.emplace_back(fs_item_t{
|
ret.emplace_back(fs_item_t{
|
||||||
new directory(dir_item.get_path(), stop_requested_),
|
new directory(dir_item.get_path(), stop_requested_),
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
[&ret](auto file_item) -> bool {
|
[&ret](auto &&file_item) -> bool {
|
||||||
ret.emplace_back(fs_item_t{
|
ret.emplace_back(fs_item_t{
|
||||||
new file(file_item.get_path()),
|
new file(file_item.get_path()),
|
||||||
});
|
});
|
||||||
@@ -379,15 +435,68 @@ auto directory::move_to(std::string_view new_path) -> bool {
|
|||||||
MONITARR_USES_FUNCTION_NAME();
|
MONITARR_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
if (not exists()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto src_root = utils::path::finalize(path_);
|
||||||
|
auto dst_root = utils::path::finalize(new_path);
|
||||||
|
if (src_root == dst_root) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (directory{dst_root}.exists()) {
|
||||||
throw utils::error::create_exception(function_name,
|
throw utils::error::create_exception(function_name,
|
||||||
{
|
{
|
||||||
"failed to move directory",
|
"failed to move directory",
|
||||||
"not implemented",
|
"destination exists",
|
||||||
new_path,
|
src_root,
|
||||||
path_,
|
dst_root,
|
||||||
});
|
});
|
||||||
} catch (const std::exception &e) {
|
}
|
||||||
utils::error::handle_exception(function_name, e);
|
|
||||||
|
auto dst_parent = utils::path::get_parent_path(dst_root);
|
||||||
|
if (not dst_parent.empty() && not directory{dst_parent}.exists()) {
|
||||||
|
auto parent_parent = utils::path::get_parent_path(dst_parent);
|
||||||
|
auto last_piece = utils::path::strip_to_file_name(dst_parent);
|
||||||
|
[[maybe_unused]] auto sub_dir =
|
||||||
|
directory{parent_parent}.create_directory(last_piece);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (not directory{dst_root}.exists()) {
|
||||||
|
auto root_parent = utils::path::get_parent_path(dst_root);
|
||||||
|
auto root_name = utils::path::strip_to_file_name(dst_root);
|
||||||
|
[[maybe_unused]] auto sub_dir =
|
||||||
|
directory{root_parent}.create_directory(root_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (not copy_to(dst_root, true)) {
|
||||||
|
throw utils::error::create_exception(function_name,
|
||||||
|
{
|
||||||
|
"failed to move directory",
|
||||||
|
"copy failed",
|
||||||
|
src_root,
|
||||||
|
dst_root,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_stop_requested()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (not remove_recursively()) {
|
||||||
|
throw utils::error::create_exception(function_name,
|
||||||
|
{
|
||||||
|
"failed to move directory",
|
||||||
|
"remove source failed",
|
||||||
|
src_root,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
path_ = dst_root;
|
||||||
|
return true;
|
||||||
|
} catch (const std::exception &ex) {
|
||||||
|
utils::error::handle_exception(function_name, ex);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
utils::error::handle_exception(function_name);
|
utils::error::handle_exception(function_name);
|
||||||
}
|
}
|
||||||
@@ -434,8 +543,10 @@ auto directory::remove_recursively() -> bool {
|
|||||||
|
|
||||||
if (not traverse_directory(
|
if (not traverse_directory(
|
||||||
path_,
|
path_,
|
||||||
[](auto dir_item) -> bool { return dir_item.remove_recursively(); },
|
[](auto &&dir_item) -> bool {
|
||||||
[](auto file_item) -> bool { return file_item.remove(); },
|
return dir_item.remove_recursively();
|
||||||
|
},
|
||||||
|
[](auto &&file_item) -> bool { return file_item.remove(); },
|
||||||
stop_requested_)) {
|
stop_requested_)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -458,14 +569,14 @@ auto directory::size(bool recursive) const -> std::uint64_t {
|
|||||||
|
|
||||||
traverse_directory(
|
traverse_directory(
|
||||||
path_,
|
path_,
|
||||||
[&ret, &recursive](auto dir_item) -> bool {
|
[&ret, &recursive](auto &&dir_item) -> bool {
|
||||||
if (recursive) {
|
if (recursive) {
|
||||||
ret += dir_item.size(true);
|
ret += dir_item.size(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
[&ret](auto file_item) -> bool {
|
[&ret](auto &&file_item) -> bool {
|
||||||
auto cur_size = file_item.size();
|
auto cur_size = file_item.size();
|
||||||
if (cur_size.has_value()) {
|
if (cur_size.has_value()) {
|
||||||
ret += cur_size.value();
|
ret += cur_size.value();
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ auto enc_file::copy_to(std::string_view new_path, bool overwrite) const
|
|||||||
return file_->copy_to(new_path, overwrite);
|
return file_->copy_to(new_path, overwrite);
|
||||||
}
|
}
|
||||||
|
|
||||||
void enc_file::flush() const { return file_->flush(); }
|
void enc_file::flush() const { file_->flush(); }
|
||||||
|
|
||||||
auto enc_file::move_to(std::string_view path) -> bool {
|
auto enc_file::move_to(std::string_view path) -> bool {
|
||||||
return file_->move_to(path);
|
return file_->move_to(path);
|
||||||
@@ -68,8 +68,8 @@ auto enc_file::read(unsigned char *data, std::size_t to_read,
|
|||||||
std::size_t bytes_read{};
|
std::size_t bytes_read{};
|
||||||
auto ret{
|
auto ret{
|
||||||
utils::encryption::read_encrypted_range(
|
utils::encryption::read_encrypted_range(
|
||||||
{offset, offset + to_read - 1U},
|
{.begin = offset, .end = offset + to_read - 1U},
|
||||||
utils::encryption::generate_key<utils::encryption::hash_256_t>(
|
utils::encryption::generate_key<utils::hash::hash_256_t>(
|
||||||
encryption_token_),
|
encryption_token_),
|
||||||
[&](auto &&ct_buffer, auto &&start_offset,
|
[&](auto &&ct_buffer, auto &&start_offset,
|
||||||
auto &&end_offset) -> bool {
|
auto &&end_offset) -> bool {
|
||||||
@@ -145,7 +145,7 @@ auto enc_file::truncate(std::size_t size) -> bool {
|
|||||||
return i_file::write(data, offset);
|
return i_file::write(data, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto begin_chunk{
|
/* auto begin_chunk{
|
||||||
file_size.value() /
|
file_size.value() /
|
||||||
utils::encryption::encrypting_reader::get_data_chunk_size(),
|
utils::encryption::encrypting_reader::get_data_chunk_size(),
|
||||||
};
|
};
|
||||||
@@ -153,13 +153,14 @@ auto enc_file::truncate(std::size_t size) -> bool {
|
|||||||
utils::divide_with_ceiling(
|
utils::divide_with_ceiling(
|
||||||
file_size.value(),
|
file_size.value(),
|
||||||
utils::encryption::encrypting_reader::get_data_chunk_size()),
|
utils::encryption::encrypting_reader::get_data_chunk_size()),
|
||||||
};
|
}; */
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto enc_file::write(const unsigned char *data, std::size_t to_write,
|
auto enc_file::write(const unsigned char * /* data */, std::size_t to_write,
|
||||||
std::size_t offset, std::size_t *total_written) -> bool {
|
std::size_t offset, std::size_t * /* total_written */)
|
||||||
|
-> bool {
|
||||||
auto file_size{size()};
|
auto file_size{size()};
|
||||||
if (not file_size.has_value()) {
|
if (not file_size.has_value()) {
|
||||||
return false;
|
return false;
|
||||||
@@ -181,7 +182,7 @@ auto enc_file::size() const -> std::optional<std::uint64_t> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return utils::encryption::encrypting_reader::calculate_decrypted_size(
|
return utils::encryption::encrypting_reader::calculate_decrypted_size(
|
||||||
file_size.value());
|
file_size.value(), false);
|
||||||
}
|
}
|
||||||
} // namespace monitarr::utils::file
|
} // namespace monitarr::utils::file
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user