new_build_system (#18)
All checks were successful
BlockStorage/repertory/pipeline/head This commit looks good

Reviewed-on: #18
This commit is contained in:
Scott E. Graves 2024-09-06 15:05:48 +00:00
parent 9d3e4b8767
commit a7239558bd
191 changed files with 10683 additions and 10598 deletions

5
.clangd Normal file
View File

@ -0,0 +1,5 @@
{
"CompileFlags": {
"Remove": ["-flarge-source-files", "-fext-numeric-literals"]
}
}

View File

@ -1,3 +1,7 @@
_lseeki64
_sh_denyno
_sh_denyrd
_sh_denyrw
aarch64 aarch64
advapi32 advapi32
armv8 armv8
@ -22,6 +26,8 @@ crypto_aead_xchacha20poly1305_ietf_npubbytes
cstdint cstdint
cxxflags cxxflags
cxxstd cxxstd
d_largefile64_source
d_largefile_source
d_ndebug d_ndebug
dbackward_shared dbackward_shared
dbghelp dbghelp
@ -83,13 +89,18 @@ ecdh
endforeach endforeach
endfunction endfunction
eventlib eventlib
expect_streq
fallocate_impl
fext fext
fgetattr fgetattr
flac_version flac_version
flag_nopath
flarge flarge
fontconfig_version fontconfig_version
freetype2_version freetype2_version
fsetattr_x fsetattr_x
fusermount
futimens
getxtimes getxtimes
glapi glapi
gmock gmock
@ -107,6 +118,7 @@ iphlpapi
libbitcoin libbitcoin
libbitcoinsystem libbitcoinsystem
libcurl libcurl
libdsm
libevent libevent
libexample libexample
libfuse3 libfuse3
@ -119,14 +131,18 @@ libsfml
libsodium_type libsodium_type
libuuid libuuid
libuuid_include_dirs libuuid_include_dirs
libvlc
linkflags linkflags
mbig mbig
msvc msvc
msvcr120 msvcr120
mtune mtune
nana
ncrypt ncrypt
nlohmann_json nlohmann_json
nmakeprg nmakeprg
nominmax
ntstatus
nuspell_version nuspell_version
oleaut32 oleaut32
openal_version openal_version
@ -134,13 +150,20 @@ openssldir
pkgconfig pkgconfig
project_enable_fontconfig project_enable_fontconfig
project_enable_gtkmm project_enable_gtkmm
project_enable_libdsm
project_enable_nana
propgrid propgrid
psecurity_descriptor
pugi pugi
pugixml_project pugixml_project
puint32
pvoid
pwstr
remote_winfsp remote_winfsp
richtext richtext
rocksdb_library rocksdb_library
rpcrt4 rpcrt4
sddl_revision_1
secp256k1 secp256k1
secur32 secur32
sfml_project sfml_project
@ -148,13 +171,19 @@ shlwapi
source_subdir source_subdir
spdlog spdlog
spdlog_project spdlog_project
st_ctim
static-libgcc static-libgcc
static-libstdc++ static-libstdc++
stbuf
stduuid_project stduuid_project
strequal strequal
ularge_integer
uring uring
userenv userenv
utimens_impl
utimensat
vorbis_version vorbis_version
waggressive
wall wall
wcast-align wcast-align
wconversion wconversion
@ -162,6 +191,7 @@ wdouble-promotion
wduplicated-branches wduplicated-branches
wduplicated-cond wduplicated-cond
wextra wextra
wfloat
wformat=2 wformat=2
winfsp winfsp
winhttp winhttp
@ -179,5 +209,6 @@ wserialization
wshadow wshadow
wsign-conversion wsign-conversion
wunused wunused
wuseless
wxwidgets_version wxwidgets_version
xattr xattr

View File

@ -52,7 +52,7 @@ pipeline {
agent any agent any
steps { steps {
sh 'scripts/deliver.sh /mnt/repertory "" "" "" "" 1 0' sh 'scripts/deliver.sh /mnt/repertory "" "" "" "" 1 1'
sh 'scripts/deliver.sh /mnt/repertory "" aarch64' sh 'scripts/deliver.sh /mnt/repertory "" aarch64'
sh 'scripts/deliver.sh /mnt/repertory' sh 'scripts/deliver.sh /mnt/repertory'
} }

View File

@ -18,6 +18,8 @@ if(HAS_SETXATTR)
add_definitions(-DHAS_SETXATTR) add_definitions(-DHAS_SETXATTR)
endif() endif()
include(cmake/hashes.cmake)
include(cmake/versions.cmake) include(cmake/versions.cmake)
include(cmake/arch.cmake) include(cmake/arch.cmake)
include(cmake/os.cmake) include(cmake/os.cmake)
@ -32,6 +34,9 @@ endif()
if(PROJECT_IS_MINGW) if(PROJECT_IS_MINGW)
add_definitions(-DPROJECT_IS_MINGW) add_definitions(-DPROJECT_IS_MINGW)
if(PROJECT_IS_MINGW_UNIX)
add_definitions(-DPROJECT_IS_MINGW_UNIX)
endif()
endif() endif()
if(PROJECT_REQUIRE_ALPINE) if(PROJECT_REQUIRE_ALPINE)
@ -42,6 +47,13 @@ if(PROJECT_IS_ARM64)
add_definitions(-DPROJECT_IS_ARM64) add_definitions(-DPROJECT_IS_ARM64)
endif() endif()
if(PROJECT_IS_MINGW)
option(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES "Enable path sizes of 32767 characters on Windows" OFF)
if(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
add_definitions(-DPROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
endif()
endif()
include(cmake/settings.cmake) include(cmake/settings.cmake)
include(cmake/flags.cmake) include(cmake/flags.cmake)
@ -127,7 +139,7 @@ endif()
-DPROJECT_COPYRIGHT=${PROJECT_COPYRIGHT} -DPROJECT_COPYRIGHT=${PROJECT_COPYRIGHT}
-DPROJECT_DESC=${PROJECT_DESC} -DPROJECT_DESC=${PROJECT_DESC}
-DPROJECT_DIST_DIR=${PROJECT_DIST_DIR} -DPROJECT_DIST_DIR=${PROJECT_DIST_DIR}
-DPROJECT_ENABLE_BACKWARD_CPP=${PROJECT_ENABLE_BACKWARD_CPP} -DPROJECT_ENABLE_WIN32_LONG_PATH_NAMES=${PROJECT_ENABLE_WIN32_LONG_PATH_NAMES}
-DPROJECT_ENABLE_BOOST=${PROJECT_ENABLE_BOOST} -DPROJECT_ENABLE_BOOST=${PROJECT_ENABLE_BOOST}
-DPROJECT_ENABLE_CPP_HTTPLIB=${PROJECT_ENABLE_CPP_HTTPLIB} -DPROJECT_ENABLE_CPP_HTTPLIB=${PROJECT_ENABLE_CPP_HTTPLIB}
-DPROJECT_ENABLE_CURL=${PROJECT_ENABLE_CURL} -DPROJECT_ENABLE_CURL=${PROJECT_ENABLE_CURL}

View File

@ -59,8 +59,7 @@ list(APPEND PROJECT_CFLAGS_LIST
list(APPEND PROJECT_CXXFLAGS_LIST list(APPEND PROJECT_CXXFLAGS_LIST
${PROJECT_COMMON_FLAG_LIST} ${PROJECT_COMMON_FLAG_LIST}
-fext-numeric-literals -std=gnu++${CMAKE_CXX_STANDARD}
-std=c++${CMAKE_CXX_STANDARD}
) )
if(PROJECT_STATIC_LINK) if(PROJECT_STATIC_LINK)

View File

@ -26,7 +26,7 @@ function(set_common_target_options name)
endif() endif()
endfunction(set_common_target_options) endfunction(set_common_target_options)
function(add_project_executable2 name dependencies libraries headers sources) function(add_project_executable2 name dependencies libraries headers sources is_win32)
if (PROJECT_WINDOWS_VERSION_RC) if (PROJECT_WINDOWS_VERSION_RC)
list(APPEND sources ${PROJECT_WINDOWS_VERSION_RC}) list(APPEND sources ${PROJECT_WINDOWS_VERSION_RC})
endif() endif()
@ -52,6 +52,10 @@ function(add_project_executable2 name dependencies libraries headers sources)
if(PROJECT_ENABLE_SDL AND PROJECT_IS_MINGW) if(PROJECT_ENABLE_SDL AND PROJECT_IS_MINGW)
target_link_libraries(${name} PRIVATE SDL2::SDL2main) target_link_libraries(${name} PRIVATE SDL2::SDL2main)
endif () endif ()
if (is_win32 AND PROJECT_IS_MINGW)
target_link_options(${name} PRIVATE -mwindows)
endif()
endfunction(add_project_executable2) endfunction(add_project_executable2)
function(add_project_executable name dependencies libraries) function(add_project_executable name dependencies libraries)
@ -69,7 +73,15 @@ function(add_project_executable name dependencies libraries)
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/src/*.cxx ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/src/*.cxx
) )
add_project_executable2(${name} "${dependencies}" "${libraries}" "${headers}" "${sources}") if(PROJECT_ENABLE_WXWIDGETS OR PROJECT_ENABLE_SDL OR PROJECT_ENABLE_SFML OR PROJECT_ENABLE_NANA)
set(IS_WIN32 ON)
endif()
add_project_executable2(${name} "${dependencies}" "${libraries}" "${headers}" "${sources}" "${IS_WIN32}")
if(PROJECT_ENABLE_WXWIDGETS)
target_link_libraries(${name} PRIVATE ${wxWidgets_LIBRARIES})
endif()
endfunction(add_project_executable) endfunction(add_project_executable)
function(add_project_library name dependencies libraries additional_sources) function(add_project_library name dependencies libraries additional_sources)
@ -121,7 +133,7 @@ function(add_project_test_executable name dependencies libraries)
${additional_sources} ${additional_sources}
) )
add_project_executable2(${name} "${dependencies}" "${libraries}" "${headers}" "${sources}") add_project_executable2(${name} "${dependencies}" "${libraries}" "${headers}" "${sources}" OFF)
target_compile_definitions(${name} PRIVATE -DPROJECT_TESTING) target_compile_definitions(${name} PRIVATE -DPROJECT_TESTING)

41
cmake/hashes.cmake Normal file
View File

@ -0,0 +1,41 @@
set(BINUTILS_HASH ae9a5789e23459e59606e6714723f2d3ffc31c03174191ef0d015bdf06007450)
set(BOOST2_HASH 7bd7ddceec1a1dfdcbdb3e609b60d01739c38390a5f956385a12f3122049f0ca)
set(BOOST_HASH be0d91732d5b0cc6fbb275c7939974457e79b54d6f07ce2e3dfdd68bef883b0b)
set(CLI11_HASH f2d893a65c3b1324c50d4e682c0cdc021dd0477ae2c048544f39eed6654b699a)
set(CPP_HTTPLIB_HASH c1742fc7179aaae2a67ad9bba0740b7e9ffaf4f5e62feef53101ecdef1478716)
set(CURL_HASH d714818f6ac41ae9154850158fed44b7a87650a6d52f83d3bcb9aa527be354d7)
set(CXXOPTS_HASH 841f49f2e045b9c6365997c2a8fbf76e6f215042dda4511a5bb04bc5ebc7f88a)
set(EXPAT_HASH fbd032683370d761ba68dba2566d3280a154f5290634172d60a79b24d366d9dc)
set(FLAC_HASH 0a4bb82a30609b606650d538a804a7b40205366ce8fc98871b0ecf3fbb0611ee)
set(FMT_HASH 6cb1e6d37bdcb756dbbe59be438790db409cdb4868c66e888d5df9f13f7c027f)
set(FONTCONFIG_HASH f5f359d6332861bd497570848fcb42520964a9e83d5e3abe397b6b6db9bcaaf4)
set(FREETYPE2_HASH 5c3a8e78f7b24c20b25b54ee575d6daa40007a5f4eea2845861c3409b3021747)
set(GCC_HASH 7d376d445f93126dc545e2c0086d0f647c3094aae081cdb78f42ce2bc25e7293)
set(GTEST_HASH 7b42b4d6ed48810c5362c265a17faebe90dc2373c885e5216439d37927f02926)
set(ICU_HASH 925e6b4b8cf8856e0ac214f6f34e30dee63b7bb7a50460ab4603950eff48f89e)
set(JSON_HASH 0d8ef5af7f9794e3263480193c491549b2ba6cc74bb018906202ada498a79406)
set(LIBDSM_HASH 747c4563d6291303d9b085c9e7dc96ac44f91871dcac3e20480fdcc066eee88a)
set(LIBEVENT_HASH 7180a979aaa7000e1264da484f712d403fcf7679b1e9212c4e3d09f5c93efc24)
set(LIBICONV_HASH 8f74213b56238c85a50a5329f77e06198771e70dd9a739779f4c02f65d971313)
set(LIBJPEG_TURBO_HASH a649205a90e39a548863a3614a9576a3fb4465f8e8e66d54999f127957c25b21)
set(LIBPNG_HASH fecc95b46cf05e8e3fc8a414750e0ba5aad00d89e9fdf175e94ff041caf1a03a)
set(LIBSODIUM_HASH 8e5aeca07a723a27bbecc3beef14b0068d37e7fc0e97f51b3f1c82d2a58005c1)
set(LIBTASN_HASH 1613f0ac1cf484d6ec0ce3b8c06d56263cc7242f1c23b30d82d23de345a63f7a)
set(MINGW_HASH 3f66bce069ee8bed7439a1a13da7cb91a5e67ea6170f21317ac7f5794625ee10)
set(NANA_HASH 56f7b1ed006c750fccf8ef15ab1e83f96751f2dfdcb68d93e5f712a6c9b58bcb)
set(NUSPELL_HASH 5d4baa1daf833a18dc06ae0af0571d9574cc849d47daff6b9ce11dac0a5ded6a)
set(OGG_HASH 0eb4b4b9420a0f51db142ba3f9c64b333f826532dc0f48c6410ae51f4799b664)
set(OPENAL_HASH dfddf3a1f61059853c625b7bb03de8433b455f2f79f89548cbcbd5edca3d4a4a)
set(OPENSSL_HASH 777cd596284c883375a2a7a11bf5d2786fc5413255efab20c50d6ffe6d020b7e)
set(PKG_CONFIG_HASH 6fc69c01688c9458a57eb9a1664c9aba372ccda420a02bf4429fe610e7e7d591)
set(PUGIXML_HASH 2f10e276870c64b1db6809050a75e11a897a8d7456c4be5c6b2e35a11168a015)
set(ROCKSDB_HASH b20780586d3df4a3c5bcbde341a2c1946b03d18237960bda5bc5e9538f42af40)
set(SDL_HASH 254a767aa486fa6308d4473159c1f23c794610be775d63e98084111d96814b85)
set(SECP256K1_HASH 61583939f1f25b92e6401e5b819e399da02562de663873df3056993b40148701)
set(SFML_HASH 82535db9e57105d4f3a8aedabd138631defaedc593cab589c924b7d7a11ffb9d)
set(SPDLOG_HASH 1586508029a7d0670dfcb2d97575dcdc242d3868a259742b69f100801ab4e16b)
set(SQLITE_HASH 77823cb110929c2bcb0f5d48e4833b5c59a8a6e40cdea3936b99e199dbbe5784)
set(STDUUID_HASH b1176597e789531c38481acbbed2a6894ad419aab0979c10410d59eb0ebf40d3)
set(VORBIS_HASH 270c76933d0934e42c5ee0a54a36280e2d87af1de3cc3e584806357e237afd13)
set(WXWIDGETS_HASH 0ad86a3ad3e2e519b6a705248fc9226e3a09bbf069c6c692a02acf7c2d1c6b51)
set(ZLIB_HASH 17e88863f3600672ab49182f217281b6fc4d3c762bde361935e436a95214d05c)

View File

@ -11,7 +11,6 @@ include(cmake/libraries/openssl.cmake)
include(cmake/libraries/boost.cmake) include(cmake/libraries/boost.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)
include(cmake/libraries/fuse.cmake) include(cmake/libraries/fuse.cmake)

View File

@ -1,11 +0,0 @@
if(PROJECT_ENABLE_BACKWARD_CPP AND PROJECT_BUILD)
if(PROJECT_IS_MINGW)
add_definitions(-DPROJECT_ENABLE_BACKWARD_CPP)
link_libraries(msvcr90)
else()
add_definitions(-DBACKWARD_HAS_BFD)
link_libraries(bfd)
endif()
endif()

View File

@ -46,66 +46,72 @@ if(PROJECT_ENABLE_BOOST)
${Boost_LIBRARIES} ${Boost_LIBRARIES}
) )
elseif(NOT PROJECT_IS_MINGW OR CMAKE_HOST_WIN32) elseif(NOT PROJECT_IS_MINGW OR CMAKE_HOST_WIN32)
if(PROJECT_CMAKE_BUILD_TYPE STREQUAL "Debug") if (PROJECT_ENABLE_LIBBITCOIN_SYSTEM OR NOT CMAKE_HOST_WIN32)
set(BOOST_BUILD_TYPE_LOWER debug) if(PROJECT_CMAKE_BUILD_TYPE STREQUAL "Debug")
else() set(BOOST_BUILD_TYPE_LOWER debug)
set(BOOST_BUILD_TYPE_LOWER release) else()
set(BOOST_BUILD_TYPE_LOWER release)
endif()
if(PROJECT_IS_ARM64)
set(BOOST_ARCH arm)
else()
set(BOOST_ARCH x86)
endif()
if(PROJECT_STATIC_LINK)
set(BOOST_LINK static)
else()
set(BOOST_LINK "static,shared")
endif()
set(BOOST_BUILD_ARGS
--openssldir=$ENV{OPENSSL_ROOT_DIR}
--prefix=${PROJECT_EXTERNAL_BUILD_ROOT}
address-model=64
architecture=${BOOST_ARCH}
cxxstd=20
cxxstd-dialect=gnu
cxxflags=-std=gnu++${CMAKE_CXX_STANDARD}
cxxstd=${CMAKE_CXX_STANDARD}
define=BOOST_ASIO_HAS_STD_STRING_VIEW
define=BOOST_SYSTEM_NO_DEPRECATED
link=${BOOST_LINK}
linkflags=-std=gnu++${CMAKE_CXX_STANDARD}
threading=multi
variant=${BOOST_BUILD_TYPE_LOWER}
)
if(PROJECT_ENABLE_LIBBITCOIN_SYSTEM)
set(BOOST_URL_HASH SHA256=${BOOST2_HASH})
else()
set(BOOST_URL_HASH SHA256=${BOOST_HASH})
endif()
ExternalProject_Add(boost_project
PREFIX external
URL ${PROJECT_3RD_PARTY_DIR}/boost_${BOOST_MAJOR_VERSION}_${BOOST_MINOR_VERSION}_${BOOST_PATCH_VERSION}.tar.gz
URL_HASH ${BOOST_URL_HASH}
BUILD_IN_SOURCE 1
LIST_SEPARATOR |
CONFIGURE_COMMAND ./bootstrap.sh
--with-libraries=atomic,chrono,date_time,filesystem,iostreams,locale,log,program_options,random,regex,serialization,system,test,thread
BUILD_COMMAND
./b2
-j1
${BOOST_BUILD_ARGS}
INSTALL_COMMAND
./b2
-j1
${BOOST_BUILD_ARGS}
install
)
list(APPEND PROJECT_DEPENDENCIES boost_project)
if (NOT CMAKE_HOST_WIN32)
add_dependencies(boost_project openssl_project)
endif()
endif() endif()
if(PROJECT_IS_ARM64)
set(BOOST_ARCH arm)
else()
set(BOOST_ARCH x86)
endif()
if(PROJECT_STATIC_LINK)
set(BOOST_LINK static)
else()
set(BOOST_LINK "static,shared")
endif()
set(BOOST_BUILD_ARGS
--openssldir=$ENV{OPENSSL_ROOT_DIR}
--prefix=${PROJECT_EXTERNAL_BUILD_ROOT}
address-model=64
architecture=${BOOST_ARCH}
cxxflags=-std=c++${CMAKE_CXX_STANDARD}
cxxstd=${CMAKE_CXX_STANDARD}
define=BOOST_ASIO_HAS_STD_STRING_VIEW
define=BOOST_SYSTEM_NO_DEPRECATED
link=${BOOST_LINK}
linkflags=-std=c++${CMAKE_CXX_STANDARD}
threading=multi
variant=${BOOST_BUILD_TYPE_LOWER}
)
if(PROJECT_ENABLE_LIBBITCOIN_SYSTEM)
set(BOOST_URL_HASH SHA256=7bd7ddceec1a1dfdcbdb3e609b60d01739c38390a5f956385a12f3122049f0ca)
else()
set(BOOST_URL_HASH SHA256=be0d91732d5b0cc6fbb275c7939974457e79b54d6f07ce2e3dfdd68bef883b0b)
endif()
ExternalProject_Add(boost_project
PREFIX external
URL ${PROJECT_3RD_PARTY_DIR}/boost_${BOOST_MAJOR_VERSION}_${BOOST_MINOR_VERSION}_${BOOST_PATCH_VERSION}.tar.gz
URL_HASH ${BOOST_URL_HASH}
BUILD_IN_SOURCE 1
LIST_SEPARATOR |
CONFIGURE_COMMAND ./bootstrap.sh
--with-libraries=atomic,chrono,date_time,filesystem,iostreams,locale,log,program_options,random,regex,serialization,system,test,thread
BUILD_COMMAND
./b2
-j1
${BOOST_BUILD_ARGS}
INSTALL_COMMAND
./b2
-j1
${BOOST_BUILD_ARGS}
install
)
list(APPEND PROJECT_DEPENDENCIES boost_project)
add_dependencies(boost_project openssl_project)
endif() endif()
endif() endif()

View File

@ -10,7 +10,7 @@ if(PROJECT_ENABLE_CPP_HTTPLIB)
ExternalProject_Add(cpphttplib_project ExternalProject_Add(cpphttplib_project
PREFIX external PREFIX external
URL ${PROJECT_3RD_PARTY_DIR}/cpp-httplib-${CPP_HTTPLIB_VERSION}.tar.gz URL ${PROJECT_3RD_PARTY_DIR}/cpp-httplib-${CPP_HTTPLIB_VERSION}.tar.gz
URL_HASH SHA256=c125022eb85eaa12235518dc4638be93b62c3216d0f87b655af7b17b71b38851 URL_HASH SHA256=${CPP_HTTPLIB_HASH}
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}
@ -24,9 +24,9 @@ if(PROJECT_ENABLE_CPP_HTTPLIB)
list(APPEND PROJECT_DEPENDENCIES cpphttplib_project) list(APPEND PROJECT_DEPENDENCIES cpphttplib_project)
add_dependencies(cpphttplib_project add_dependencies(cpphttplib_project curl_project)
curl_project if (NOT CMAKE_HOST_WIN32)
openssl_project add_dependencies(cpphttplib_project openssl_project)
) endif()
endif() endif()
endif() endif()

View File

@ -16,7 +16,7 @@ if(PROJECT_ENABLE_CURL)
ExternalProject_Add(curl_project ExternalProject_Add(curl_project
PREFIX external PREFIX external
URL ${PROJECT_3RD_PARTY_DIR}/curl-${CURL_VERSION}.tar.gz URL ${PROJECT_3RD_PARTY_DIR}/curl-${CURL_VERSION}.tar.gz
URL_HASH SHA256=77c0e1cd35ab5b45b659645a93b46d660224d0024f1185e8a95cdb27ae3d787d URL_HASH SHA256=${CURL_HASH}
LIST_SEPARATOR | LIST_SEPARATOR |
CMAKE_ARGS CMAKE_ARGS
${PROJECT_EXTERNAL_CMAKE_FLAGS} ${PROJECT_EXTERNAL_CMAKE_FLAGS}
@ -42,6 +42,8 @@ if(PROJECT_ENABLE_CURL)
list(APPEND PROJECT_DEPENDENCIES curl_project) list(APPEND PROJECT_DEPENDENCIES curl_project)
add_dependencies(curl_project openssl_project) if (NOT CMAKE_HOST_WIN32)
add_dependencies(curl_project openssl_project)
endif()
endif() endif()
endif() endif()

View File

@ -13,7 +13,7 @@ if(PROJECT_ENABLE_JSON)
ExternalProject_Add(json_project ExternalProject_Add(json_project
PREFIX external PREFIX external
URL ${PROJECT_3RD_PARTY_DIR}/json-${JSON_VERSION}.tar.gz URL ${PROJECT_3RD_PARTY_DIR}/json-${JSON_VERSION}.tar.gz
URL_HASH SHA256=0d8ef5af7f9794e3263480193c491549b2ba6cc74bb018906202ada498a79406 URL_HASH SHA256=${JSON_HASH}
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}

View File

@ -1,6 +1,6 @@
if(PROJECT_ENABLE_LIBSODIUM) if(PROJECT_ENABLE_LIBSODIUM)
if(PROJECT_BUILD) if(PROJECT_BUILD)
pkg_check_modules(SODIUM libsodium=${LIBSODIUM_VERSION} REQUIRED) pkg_check_modules(SODIUM libsodium>=${LIBSODIUM_VERSION} REQUIRED)
add_definitions(-DPROJECT_ENABLE_LIBSODIUM) add_definitions(-DPROJECT_ENABLE_LIBSODIUM)
@ -15,7 +15,7 @@ if(PROJECT_ENABLE_LIBSODIUM)
else() else()
link_libraries(${SODIUM_LIBRARIES}) link_libraries(${SODIUM_LIBRARIES})
endif() endif()
elseif(NOT PROJECT_IS_MINGW OR CMAKE_HOST_WIN32) elseif(NOT PROJECT_IS_MINGW)
if(PROJECT_IS_MINGW) if(PROJECT_IS_MINGW)
set(LIBSODIUM_TYPE mingw64) set(LIBSODIUM_TYPE mingw64)
else() else()
@ -31,7 +31,7 @@ if(PROJECT_ENABLE_LIBSODIUM)
ExternalProject_Add(libsodium_project ExternalProject_Add(libsodium_project
PREFIX external PREFIX external
URL ${PROJECT_3RD_PARTY_DIR}/libsodium-${LIBSODIUM_VERSION}.tar.gz URL ${PROJECT_3RD_PARTY_DIR}/libsodium-${LIBSODIUM_VERSION}.tar.gz
URL_HASH SHA256=ebb65ef6ca439333c2bb41a0c1990587288da07f6c7fd07cb3a18cc18d30ce19 URL_HASH SHA256=${LIBSODIUM_HASH}
BUILD_IN_SOURCE 1 BUILD_IN_SOURCE 1
LIST_SEPARATOR | LIST_SEPARATOR |
CONFIGURE_COMMAND ${PROJECT_3RD_PARTY_DIR}/libsodium_configure.sh CONFIGURE_COMMAND ${PROJECT_3RD_PARTY_DIR}/libsodium_configure.sh

View File

@ -12,7 +12,7 @@ if(PROJECT_ENABLE_OPENSSL)
OpenSSL::Crypto OpenSSL::Crypto
OpenSSL::SSL OpenSSL::SSL
) )
elseif(NOT PROJECT_IS_MINGW OR CMAKE_HOST_WIN32) 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_ARM64) elseif(PROJECT_IS_ARM64)
@ -34,7 +34,7 @@ if(PROJECT_ENABLE_OPENSSL)
ExternalProject_Add(openssl_project ExternalProject_Add(openssl_project
PREFIX external PREFIX external
URL ${PROJECT_3RD_PARTY_DIR}/openssl-${OPENSSL_VERSION}.tar.gz URL ${PROJECT_3RD_PARTY_DIR}/openssl-${OPENSSL_VERSION}.tar.gz
URL_HASH SHA256=777cd596284c883375a2a7a11bf5d2786fc5413255efab20c50d6ffe6d020b7e URL_HASH SHA256=${OPENSSL_HASH}
BUILD_IN_SOURCE 1 BUILD_IN_SOURCE 1
LIST_SEPARATOR | LIST_SEPARATOR |
CONFIGURE_COMMAND ./Configure CONFIGURE_COMMAND ./Configure

View File

@ -11,11 +11,11 @@ if(PROJECT_ENABLE_PUGIXML)
else() else()
link_libraries(pugixml::pugixml) link_libraries(pugixml::pugixml)
endif() endif()
elseif(NOT PROJECT_IS_MINGW OR CMAKE_HOST_WIN32) elseif(NOT PROJECT_IS_MINGW)
ExternalProject_Add(pugixml_project ExternalProject_Add(pugixml_project
PREFIX external PREFIX external
URL ${PROJECT_3RD_PARTY_DIR}/pugixml-${PUGIXML_VERSION}.tar.gz URL ${PROJECT_3RD_PARTY_DIR}/pugixml-${PUGIXML_VERSION}.tar.gz
URL_HASH SHA256=2f10e276870c64b1db6809050a75e11a897a8d7456c4be5c6b2e35a11168a015 URL_HASH SHA256=${PUGIXML_HASH}
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}

View File

@ -11,11 +11,10 @@ if(PROJECT_ENABLE_SPDLOG)
ExternalProject_Add(spdlog_project ExternalProject_Add(spdlog_project
PREFIX external PREFIX external
URL ${PROJECT_3RD_PARTY_DIR}/spdlog-${SPDLOG_VERSION}.tar.gz URL ${PROJECT_3RD_PARTY_DIR}/spdlog-${SPDLOG_VERSION}.tar.gz
URL_HASH SHA256=1586508029a7d0670dfcb2d97575dcdc242d3868a259742b69f100801ab4e16b URL_HASH SHA256=${SPDLOG_HASH}
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}
-DBUILD_STATIC_LIBS=ON
-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

View File

@ -1,19 +1,24 @@
if(PROJECT_ENABLE_SQLITE) if(PROJECT_ENABLE_SQLITE)
if(PROJECT_BUILD) if(PROJECT_BUILD)
add_definitions(-DPROJECT_ENABLE_SQLITE) add_definitions(-DPROJECT_ENABLE_SQLITE)
if (PROJECT_IS_MINGW AND NOT PROJECT_IS_MINGW_UNIX)
pkg_check_modules(SQLITE3 REQUIRED sqlite3>=${SQLITE2_VERSION})
include_directories(SYSTEM BEFORE ${SQLITE3_INCLUDE_DIRS})
link_libraries(${SQLITE3_LIBRARIES})
else()
set(SQLITE_SYSTEM_ROOT ${PROJECT_BUILD_DIR}/external/src/sqlite_project)
set(SQLITE_SYSTEM_ROOT ${PROJECT_BUILD_DIR}/external/src/sqlite_project) include_directories(SYSTEM BEFORE ${SQLITE_SYSTEM_ROOT})
include_directories(SYSTEM BEFORE ${SQLITE_SYSTEM_ROOT}) list(APPEND PROJECT_ADDITIONAL_SOURCES
${SQLITE_SYSTEM_ROOT}/sqlite3.c
list(APPEND PROJECT_ADDITIONAL_SOURCES )
${SQLITE_SYSTEM_ROOT}/sqlite3.c endif()
) elseif(NOT PROJECT_IS_MINGW OR PROJECT_IS_MINGW_UNIX)
else()
ExternalProject_Add(sqlite_project ExternalProject_Add(sqlite_project
PREFIX external PREFIX external
URL ${PROJECT_3RD_PARTY_DIR}/sqlite-amalgamation-${SQLITE_VERSION}.zip URL ${PROJECT_3RD_PARTY_DIR}/sqlite-amalgamation-${SQLITE_VERSION}.zip
URL_HASH SHA256=712a7d09d2a22652fb06a49af516e051979a3984adb067da86760e60ed51a7f5 URL_HASH SHA256=${SQLITE_HASH}
CONFIGURE_COMMAND echo "No configure" CONFIGURE_COMMAND echo "No configure"
BUILD_COMMAND echo "No build" BUILD_COMMAND echo "No build"
INSTALL_COMMAND echo "No install" INSTALL_COMMAND echo "No install"

View File

@ -11,7 +11,7 @@ if(PROJECT_ENABLE_STDUUID)
ExternalProject_Add(stduuid_project ExternalProject_Add(stduuid_project
PREFIX external PREFIX external
URL ${PROJECT_3RD_PARTY_DIR}/stduuid-${STDUUID_VERSION}.tar.gz URL ${PROJECT_3RD_PARTY_DIR}/stduuid-${STDUUID_VERSION}.tar.gz
URL_HASH SHA256=b1176597e789531c38481acbbed2a6894ad419aab0979c10410d59eb0ebf40d3 URL_HASH SHA256=${STDUUID_HASH}
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}

View File

@ -1,11 +1,11 @@
if (PROJECT_ENABLE_TESTING) if (PROJECT_ENABLE_TESTING)
if(PROJECT_BUILD) if(PROJECT_BUILD)
add_definitions(-DPROJECT_ENABLE_TESTING) add_definitions(-DPROJECT_ENABLE_TESTING)
elseif(NOT PROJECT_IS_MINGW OR CMAKE_HOST_WIN32) elseif(NOT PROJECT_IS_MINGW)
ExternalProject_Add(gtest_project ExternalProject_Add(gtest_project
PREFIX external PREFIX external
URL ${PROJECT_3RD_PARTY_DIR}/googletest-${GTEST_VERSION}.tar.gz URL ${PROJECT_3RD_PARTY_DIR}/googletest-${GTEST_VERSION}.tar.gz
URL_HASH SHA256=7315acb6bf10e99f332c8a43f00d5fbb1ee6ca48c52f6b936991b216c586aaad URL_HASH SHA256=${GTEST_HASH}
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}

View File

@ -1,4 +1,3 @@
option(PROJECT_ENABLE_BACKWARD_CPP "Enable backward-cpp" ON)
option(PROJECT_ENABLE_BOOST "Enable boost libraries" ON) option(PROJECT_ENABLE_BOOST "Enable boost libraries" ON)
option(PROJECT_ENABLE_CPP_HTTPLIB "Enable cpp-httplib" ON) option(PROJECT_ENABLE_CPP_HTTPLIB "Enable cpp-httplib" ON)
option(PROJECT_ENABLE_CURL "Enable curl library" ON) option(PROJECT_ENABLE_CURL "Enable curl library" ON)

View File

@ -6,41 +6,48 @@ set(BOOST_MAJOR_VERSION 1)
set(BOOST_MINOR_VERSION 85) set(BOOST_MINOR_VERSION 85)
set(BOOST_PATCH_VERSION 0) set(BOOST_PATCH_VERSION 0)
set(CLI11_VERSION 2.4.2) set(CLI11_VERSION 2.4.2)
set(CPP_HTTPLIB_VERSION 0.16.0) set(CPP_HTTPLIB_VERSION 0.16.3)
set(CURL_VERSION 8.8.0) set(CURL2_VERSION 8_9_1)
set(CXXOPTS_VERSION 3.2.0) set(CURL_VERSION 8.9.1)
set(CXXOPTS_VERSION 3.2.1)
set(DTL_VERSION 2.01) set(DTL_VERSION 2.01)
set(EXPAT2_VERSION 2_6_2)
set(EXPAT_VERSION 2.6.2) set(EXPAT_VERSION 2.6.2)
set(FLAC_VERSION 1.4.3) set(FLAC_VERSION 1.4.3)
set(FMT_VERSION 10.2.1) set(FMT_VERSION 11.0.2)
set(FONTCONFIG_VERSION 2.15.0) set(FONTCONFIG_VERSION 2.15.0)
set(FREETYPE2_VERSION 2.13.2) set(FREETYPE2_VERSION 2.13.3)
set(GCC_VERSION 13.2.0) set(GCC_VERSION 14.2.0)
set(GTEST_VERSION 1.15.0) set(GTEST_VERSION 1.15.2)
set(GTKMM_VERSION 3.0) set(GTKMM_VERSION 3.0)
set(ICU_VERSION 75-1) set(ICU_VERSION 75-1)
set(JSON_VERSION 3.11.3) set(JSON_VERSION 3.11.3)
set(LIBBITCOIN_SYSTEM_VERSION 3.8.0) set(LIBBITCOIN_SYSTEM_VERSION 3.8.0)
set(LIBDSM_VERSION 0.4.3)
set(LIBEVENT_VERSION 2.1.12) set(LIBEVENT_VERSION 2.1.12)
set(LIBICONV_VERSION 1.17)
set(LIBJPEG_TURBO_VERSION 3.0.3) set(LIBJPEG_TURBO_VERSION 3.0.3)
set(LIBPNG_VERSION 1.6.43) set(LIBPNG_VERSION 1.6.43)
set(LIBSODIUM_VERSION 1.0.20) set(LIBSODIUM_VERSION 1.0.20)
set(LIBTASN_VERSION 4.19.0)
set(MESA_VERSION 23.3.3) set(MESA_VERSION 23.3.3)
set(MINGW_VERSION 11.0.1) set(MINGW_VERSION 11.0.1)
set(NANA_VERSION 1.7.4) set(NANA_VERSION 1.7.4)
set(NUSPELL_VERSION 5.1.4) set(NUSPELL_VERSION 5.1.6)
set(OGG_VERSION 1.3.5) set(OGG_VERSION 1.3.5)
set(OPENAL_VERSION 1.23.1) set(OPENAL_VERSION 1.23.1)
set(OPENSSL_VERSION 3.3.1) set(OPENSSL_VERSION 3.3.1)
set(PKG_CONFIG_VERSION 0.29.2) set(PKG_CONFIG_VERSION 0.29.2)
set(PUGIXML_VERSION 1.14) set(PUGIXML_VERSION 1.14)
set(ROCKSDB_VERSION 9.4.0) set(ROCKSDB_VERSION 9.5.2)
set(SDL_VERSION 2.30.5) set(SDL_VERSION 2.30.6)
set(SECP256K1_VERSION 0.1.0.20) set(SECP256K1_VERSION 0.1.0.20)
set(SFML_VERSION 2.6.1) set(SFML_VERSION 2.6.1)
set(SPDLOG_VERSION 1.14.1) set(SPDLOG_VERSION 1.14.1)
set(SQLITE_VERSION 3460000) set(SQLITE2_VERSION 3.46.1)
set(SQLITE_VERSION 3460100)
set(STDUUID_VERSION 1.2.3) set(STDUUID_VERSION 1.2.3)
set(VLC_VERSION 3.0)
set(VORBIS_VERSION 1.3.7) set(VORBIS_VERSION 1.3.7)
set(WXWIDGETS_VERSION 3.2.5) set(WXWIDGETS_VERSION 3.2.5)
set(ZLIB_VERSION 1.3.1) set(ZLIB_VERSION 1.3.1)

View File

@ -19,7 +19,9 @@ PROJECT_APP_LIST=(${PROJECT_NAME})
PROJECT_PRIVATE_KEY=${DEVELOPER_PRIVATE_KEY} PROJECT_PRIVATE_KEY=${DEVELOPER_PRIVATE_KEY}
PROJECT_PUBLIC_KEY=${DEVELOPER_PUBLIC_KEY} PROJECT_PUBLIC_KEY=${DEVELOPER_PUBLIC_KEY}
PROJECT_ENABLE_BACKWARD_CPP=ON PROJECT_ENABLE_WIN32_LONG_PATH_NAMES=OFF
PROJECT_ENABLE_BACKWARD_CPP=OFF
PROJECT_ENABLE_BOOST=ON PROJECT_ENABLE_BOOST=ON
PROJECT_ENABLE_CPP_HTTPLIB=ON PROJECT_ENABLE_CPP_HTTPLIB=ON
PROJECT_ENABLE_CURL=ON PROJECT_ENABLE_CURL=ON
@ -34,7 +36,6 @@ PROJECT_ENABLE_STDUUID=ON
PROJECT_ENABLE_TESTING=ON PROJECT_ENABLE_TESTING=ON
PROJECT_ENABLE_WINFSP=ON PROJECT_ENABLE_WINFSP=ON
PROJECT_KEEP_BACKWARD_CPP=1
PROJECT_STATIC_LINK=ON PROJECT_STATIC_LINK=ON
PROJECT_MINGW64_COPY_DEPENDENCIES+=() PROJECT_MINGW64_COPY_DEPENDENCIES+=()

View File

@ -10,6 +10,7 @@ RUN apk add \
bash \ bash \
binutils \ binutils \
binutils-dev \ binutils-dev \
bison \
boost-dev \ boost-dev \
bzip2-static \ bzip2-static \
cmake \ cmake \

View File

@ -10,6 +10,7 @@ RUN apk add \
bash \ bash \
binutils \ binutils \
binutils-dev \ binutils-dev \
bison \
boost-dev \ boost-dev \
bzip2-static \ bzip2-static \
cmake \ cmake \

View File

@ -1,4 +1,4 @@
# comment #comment
FROM alpine:3.20.2 FROM alpine:3.20.2
RUN apk update RUN apk update
@ -60,6 +60,9 @@ ENV MY_MINGW_PREFIX=${MINGW_PREFIX}
ARG NUM_JOBS=2 ARG NUM_JOBS=2
ENV MY_NUM_JOBS=${NUM_JOBS} ENV MY_NUM_JOBS=${NUM_JOBS}
ARG CXX_STANDARD=20
ENV MY_CXX_STANDARD=${CXX_STANDARD}
ARG TOOLCHAIN_FILE_CMAKE=/cmake_toolchain.cmake ARG TOOLCHAIN_FILE_CMAKE=/cmake_toolchain.cmake
ENV MY_TOOLCHAIN_FILE_CMAKE=${TOOLCHAIN_FILE_CMAKE} ENV MY_TOOLCHAIN_FILE_CMAKE=${TOOLCHAIN_FILE_CMAKE}
RUN echo -e \ RUN echo -e \
@ -89,8 +92,8 @@ RUN echo -e \
"windres = '${MY_MINGW_PREFIX}-windres'\n"\ "windres = '${MY_MINGW_PREFIX}-windres'\n"\
"exe_wrapper = 'wine64'\n"\ "exe_wrapper = 'wine64'\n"\
"[properties]\n"\ "[properties]\n"\
"c_args = []\n"\ "c_args = ['-I${MY_MINGW_DIR}/include']\n"\
"c_link_args = []\n"\ "c_link_args = ['-L${MY_MINGW_DIR}/lib', '-L${MY_MINGW_DIR}/lib64']\n"\
"[host_machine]\n"\ "[host_machine]\n"\
"cpu = 'x86_64'\n"\ "cpu = 'x86_64'\n"\
"cpu_family = 'x86_64'\n"\ "cpu_family = 'x86_64'\n"\
@ -106,15 +109,12 @@ RUN mkdir -p \
${MY_MINGW_DIR}/lib/pkgconfig \ ${MY_MINGW_DIR}/lib/pkgconfig \
${MY_MINGW_DIR}/lib64/pkgconfig ${MY_MINGW_DIR}/lib64/pkgconfig
ENV LDFLAGS="-L${MY_MINGW_DIR}/lib -L${MY_MINGW_DIR}/lib64"
ENV PATH="${MY_MINGW_DIR}/bin:/usr/local/bin:${PATH}"
ENV PKG_CONFIG_PATH="${MY_MINGW_DIR}/lib/pkgconfig:${MY_MINGW_DIR}/lib64/pkgconfig"
ADD ./3rd_party /3rd_party ADD ./3rd_party /3rd_party
ARG BINUTILS_VERSION ARG BINUTILS_VERSION
ENV MY_BINUTILS_VERSION=${BINUTILS_VERSION} ENV MY_BINUTILS_VERSION=${BINUTILS_VERSION}
RUN tar xvJf /3rd_party/mingw64/binutils-${MY_BINUTILS_VERSION}.tar.xz \ RUN cd /3rd_party/mingw64 && sha256sum -c ./binutils-${MY_BINUTILS_VERSION}.tar.xz.sha256 && cd - \
&& tar xvJf /3rd_party/mingw64/binutils-${MY_BINUTILS_VERSION}.tar.xz \
&& cd binutils-${MY_BINUTILS_VERSION} \ && cd binutils-${MY_BINUTILS_VERSION} \
&& ./configure \ && ./configure \
--disable-lto \ --disable-lto \
@ -134,10 +134,11 @@ RUN tar xvJf /3rd_party/mingw64/binutils-${MY_BINUTILS_VERSION}.tar.xz \
ARG MINGW_VERSION ARG MINGW_VERSION
ENV MY_MINGW_VERSION=${MINGW_VERSION} ENV MY_MINGW_VERSION=${MINGW_VERSION}
RUN tar xvzf /3rd_party/mingw64/mingw-w64-${MY_MINGW_VERSION}.tar.gz \ RUN cd /3rd_party/mingw64 && sha256sum -c ./mingw-w64-v${MY_MINGW_VERSION}.tar.bz2.sha256 && cd - \
&& tar xvjf /3rd_party/mingw64/mingw-w64-v${MY_MINGW_VERSION}.tar.bz2 \
&& mkdir mingw-w64 \ && mkdir mingw-w64 \
&& cd mingw-w64 \ && cd mingw-w64 \
&& ../mingw-w64-${MY_MINGW_VERSION}/mingw-w64-headers/configure \ && ../mingw-w64-v${MY_MINGW_VERSION}/mingw-w64-headers/configure \
--enable-sdk=all \ --enable-sdk=all \
--host=${MY_MINGW_PREFIX} \ --host=${MY_MINGW_PREFIX} \
--prefix=/usr/local/${MY_MINGW_PREFIX} \ --prefix=/usr/local/${MY_MINGW_PREFIX} \
@ -145,7 +146,8 @@ RUN tar xvzf /3rd_party/mingw64/mingw-w64-${MY_MINGW_VERSION}.tar.gz \
ARG GCC_VERSION ARG GCC_VERSION
ENV MY_GCC_VERSION=${GCC_VERSION} ENV MY_GCC_VERSION=${GCC_VERSION}
RUN tar xvzf /3rd_party/mingw64/gcc-${MY_GCC_VERSION}.tar.gz \ RUN cd /3rd_party/mingw64 && sha256sum -c ./gcc-${MY_GCC_VERSION}.tar.gz.sha256 && cd - \
&& tar xvzf /3rd_party/mingw64/gcc-${MY_GCC_VERSION}.tar.gz \
&& (mv gcc-releases-gcc-${MY_GCC_VERSION} gcc-${MY_GCC_VERSION} || echo "") \ && (mv gcc-releases-gcc-${MY_GCC_VERSION} gcc-${MY_GCC_VERSION} || echo "") \
&& mkdir gcc \ && mkdir gcc \
&& cd gcc \ && cd gcc \
@ -188,7 +190,7 @@ RUN tar xvzf /3rd_party/mingw64/gcc-${MY_GCC_VERSION}.tar.gz \
&& make install-gcc && make install-gcc
RUN cd mingw-w64 \ RUN cd mingw-w64 \
&& ../mingw-w64-${MY_MINGW_VERSION}/mingw-w64-crt/configure \ && ../mingw-w64-v${MY_MINGW_VERSION}/mingw-w64-crt/configure \
--disable-lib32 \ --disable-lib32 \
--enable-lib64 \ --enable-lib64 \
--enable-wildcard \ --enable-wildcard \
@ -198,7 +200,7 @@ RUN cd mingw-w64 \
&& make install && make install
RUN cd mingw-w64 \ RUN cd mingw-w64 \
&& ../mingw-w64-${MY_MINGW_VERSION}/mingw-w64-libraries/winpthreads/configure \ && ../mingw-w64-v${MY_MINGW_VERSION}/mingw-w64-libraries/winpthreads/configure \
--enable-shared \ --enable-shared \
--enable-static \ --enable-static \
--host=${MY_MINGW_PREFIX} \ --host=${MY_MINGW_PREFIX} \
@ -213,11 +215,12 @@ RUN cd gcc \
RUN cp /usr/local/${MY_MINGW_PREFIX}/lib/*.dll ${MY_MINGW_DIR}/bin \ RUN cp /usr/local/${MY_MINGW_PREFIX}/lib/*.dll ${MY_MINGW_DIR}/bin \
&& cp /usr/local/${MY_MINGW_PREFIX}/bin/*.dll ${MY_MINGW_DIR}/bin \ && cp /usr/local/${MY_MINGW_PREFIX}/bin/*.dll ${MY_MINGW_DIR}/bin \
&& rm -r gcc gcc-${MY_GCC_VERSION} \ && rm -r gcc gcc-${MY_GCC_VERSION} \
&& rm -r mingw-w64 mingw-w64-${MY_MINGW_VERSION} && rm -r mingw-w64 mingw-w64-v${MY_MINGW_VERSION}
ARG PKG_CONFIG_VERSION ARG PKG_CONFIG_VERSION
ENV MY_PKG_CONFIG_VERSION=${PKG_CONFIG_VERSION} ENV MY_PKG_CONFIG_VERSION=${PKG_CONFIG_VERSION}
RUN tar xvzf /3rd_party/mingw64/pkg-config-${MY_PKG_CONFIG_VERSION}.tar.gz \ RUN cd /3rd_party/mingw64 && sha256sum -c ./pkg-config-${MY_PKG_CONFIG_VERSION}.tar.gz.sha256 && cd - \
&& tar xvzf /3rd_party/mingw64/pkg-config-${MY_PKG_CONFIG_VERSION}.tar.gz \
&& cd pkg-config-${MY_PKG_CONFIG_VERSION} \ && cd pkg-config-${MY_PKG_CONFIG_VERSION} \
&& ./configure \ && ./configure \
--disable-nls \ --disable-nls \
@ -234,16 +237,24 @@ RUN python3 -m pip install --break-system-packages -U mako
RUN python3 -m pip install --break-system-packages -U meson RUN python3 -m pip install --break-system-packages -U meson
RUN python3 -m pip install --break-system-packages -U packaging RUN python3 -m pip install --break-system-packages -U packaging
ENV CXXFLAGS="-std=gnu++20"
ENV LDFLAGS="-L${MY_MINGW_DIR}/lib -L${MY_MINGW_DIR}/lib64"
ENV PATH="${MY_MINGW_DIR}/bin:/usr/local/bin:${PATH}"
ENV PKG_CONFIG_PATH="${MY_MINGW_DIR}/lib/pkgconfig:${MY_MINGW_DIR}/lib64/pkgconfig"
ARG ZLIB_VERSION ARG ZLIB_VERSION
ENV MY_ZLIB_VERSION=${ZLIB_VERSION} ENV MY_ZLIB_VERSION=${ZLIB_VERSION}
RUN tar xvzf /3rd_party/mingw64/zlib-${MY_ZLIB_VERSION}.tar.gz \ RUN cd /3rd_party/mingw64 && sha256sum -c ./zlib-${MY_ZLIB_VERSION}.tar.gz.sha256 && cd - \
&& tar xvzf /3rd_party/mingw64/zlib-${MY_ZLIB_VERSION}.tar.gz \
&& cd zlib-${MY_ZLIB_VERSION} \ && cd zlib-${MY_ZLIB_VERSION} \
&& mkdir build \ && mkdir build \
&& cd build \ && cd build \
&& cmake .. -DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \ && cmake .. \
-DBUILD_SHARED_LIBS=ON \ -DBUILD_SHARED_LIBS=ON \
-DBUILD_STATIC_LIBS=ON \ -DBUILD_STATIC_LIBS=ON \
-DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \ -DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
-DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
&& make -j${MY_NUM_JOBS} \ && make -j${MY_NUM_JOBS} \
&& make install \ && make install \
&& cd ${MY_WORKDIR} \ && cd ${MY_WORKDIR} \
@ -252,18 +263,21 @@ RUN tar xvzf /3rd_party/mingw64/zlib-${MY_ZLIB_VERSION}.tar.gz \
ARG LIBJPEG_TURBO_VERSION ARG LIBJPEG_TURBO_VERSION
ENV MY_LIBJPEG_TURBO_VERSION=${LIBJPEG_TURBO_VERSION} ENV MY_LIBJPEG_TURBO_VERSION=${LIBJPEG_TURBO_VERSION}
RUN if [ -f "/3rd_party/libjpeg_turbo-${MY_LIBJPEG_TURBO_VERSION}.tar.gz" ]; then \ RUN if [ -f "/3rd_party/libjpeg_turbo-${MY_LIBJPEG_TURBO_VERSION}.tar.gz" ]; then \
tar xvzf /3rd_party/libjpeg_turbo-${MY_LIBJPEG_TURBO_VERSION}.tar.gz \ cd /3rd_party && sha256sum -c ./libjpeg_turbo-${MY_LIBJPEG_TURBO_VERSION}.tar.gz.sha256 && cd - \
&& tar xvzf /3rd_party/libjpeg_turbo-${MY_LIBJPEG_TURBO_VERSION}.tar.gz \
&& cd libjpeg-turbo-${MY_LIBJPEG_TURBO_VERSION} \ && cd libjpeg-turbo-${MY_LIBJPEG_TURBO_VERSION} \
&& mkdir _build \ && mkdir _build \
&& cd _build \ && cd _build \
&& cmake .. -DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \ && cmake .. \
-DCMAKE_SYSTEM_PROCESSOR=AMD64 \
-DBUILD_SHARED_LIBS=ON \ -DBUILD_SHARED_LIBS=ON \
-DBUILD_STATIC_LIBS=ON \ -DBUILD_STATIC_LIBS=ON \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
-DCMAKE_SYSTEM_PROCESSOR=AMD64 \
-DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
-DENABLE_SHARED=ON \ -DENABLE_SHARED=ON \
-DENABLE_STATIC=ON \ -DENABLE_STATIC=ON \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
&& make -j${MY_NUM_JOBS} \ && make -j${MY_NUM_JOBS} \
&& make install \ && make install \
&& cd ${MY_WORKDIR} \ && cd ${MY_WORKDIR} \
@ -271,17 +285,20 @@ RUN if [ -f "/3rd_party/libjpeg_turbo-${MY_LIBJPEG_TURBO_VERSION}.tar.gz" ]; the
; fi ; fi
ARG LIBPNG_VERSION ARG LIBPNG_VERSION
ENV MY_LIBPNG_VERSION=${LIBPNG_VERSION} ENV MY_LIBPNG_VERSION=${LIBPNG_VERSION}
RUN if [ -f "/3rd_party/libpng-v${MY_LIBPNG_VERSION}.tar.gz" ]; then \ RUN if [ -f "/3rd_party/libpng-v${MY_LIBPNG_VERSION}.tar.gz" ]; then \
tar xvzf /3rd_party/libpng-v${MY_LIBPNG_VERSION}.tar.gz \ cd /3rd_party && sha256sum -c ./libpng-v${MY_LIBPNG_VERSION}.tar.gz.sha256 && cd - \
&& tar xvzf /3rd_party/libpng-v${MY_LIBPNG_VERSION}.tar.gz \
&& cd libpng-${MY_LIBPNG_VERSION} \ && cd libpng-${MY_LIBPNG_VERSION} \
&& mkdir _build \ && mkdir _build \
&& cd _build \ && cd _build \
&& cmake .. -DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \ && cmake .. \
-DBUILD_SHARED_LIBS=ON \ -DBUILD_SHARED_LIBS=ON \
-DBUILD_STATIC_LIBS=ON \ -DBUILD_STATIC_LIBS=ON \
-DCMAKE_BUILD_TYPE=Release \ -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \ -DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
-DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
-DPNG_SHARED=ON \ -DPNG_SHARED=ON \
-DPNG_STATIC=ON \ -DPNG_STATIC=ON \
-DPNG_TESTS=OFF \ -DPNG_TESTS=OFF \
@ -295,7 +312,8 @@ RUN if [ -f "/3rd_party/libpng-v${MY_LIBPNG_VERSION}.tar.gz" ]; then \
ARG FREETYPE2_VERSION ARG FREETYPE2_VERSION
ENV MY_FREETYPE2_VERSION=${FREETYPE2_VERSION} ENV MY_FREETYPE2_VERSION=${FREETYPE2_VERSION}
RUN if [ -f "/3rd_party/freetype-${MY_FREETYPE2_VERSION}.tar.gz" ]; then \ RUN if [ -f "/3rd_party/freetype-${MY_FREETYPE2_VERSION}.tar.gz" ]; then \
tar xvzf /3rd_party/freetype-${MY_FREETYPE2_VERSION}.tar.gz \ cd /3rd_party && sha256sum -c ./freetype-${MY_FREETYPE2_VERSION}.tar.gz.sha256 && cd - \
&& tar xvzf /3rd_party/freetype-${MY_FREETYPE2_VERSION}.tar.gz \
&& cd freetype-${MY_FREETYPE2_VERSION} \ && cd freetype-${MY_FREETYPE2_VERSION} \
&& meson setup \ && meson setup \
--cross-file ${MY_TOOLCHAIN_FILE_MESON} \ --cross-file ${MY_TOOLCHAIN_FILE_MESON} \
@ -311,26 +329,30 @@ RUN if [ -f "/3rd_party/freetype-${MY_FREETYPE2_VERSION}.tar.gz" ]; then \
ARG EXPAT_VERSION ARG EXPAT_VERSION
ENV MY_EXPAT_VERSION=${EXPAT_VERSION} ENV MY_EXPAT_VERSION=${EXPAT_VERSION}
RUN tar xvzf /3rd_party/mingw64/expat-${MY_EXPAT_VERSION}.tar.gz \ RUN cd /3rd_party/mingw64 && sha256sum -c ./expat-${MY_EXPAT_VERSION}.tar.gz.sha256 && cd - \
&& cd expat-${MY_EXPAT_VERSION} \ && tar xvzf /3rd_party/mingw64/expat-${MY_EXPAT_VERSION}.tar.gz \
&& cd libexpat-*/expat \
&& mkdir build \ && mkdir build \
&& cd build \ && cd build \
&& cmake .. -DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \ && cmake .. \
-DBUILD_SHARED_LIBS=ON \ -DBUILD_SHARED_LIBS=ON \
-DBUILD_STATIC_LIBS=ON \ -DBUILD_STATIC_LIBS=ON \
-DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \ -DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
-DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
-DEXPAT_BUILD_DOCS=OFF \ -DEXPAT_BUILD_DOCS=OFF \
-DEXPAT_BUILD_EXAMPLES=OFF \ -DEXPAT_BUILD_EXAMPLES=OFF \
-DEXPAT_BUILD_TESTS=OFF \ -DEXPAT_BUILD_TESTS=OFF \
&& make -j${MY_NUM_JOBS} \ && make -j${MY_NUM_JOBS} \
&& make install \ && make install \
&& cd ${MY_WORKDIR} \ && cd ${MY_WORKDIR} \
&& rm -r expat-${MY_EXPAT_VERSION} && rm -r libexpat-*
ARG FONTCONFIG_VERSION ARG FONTCONFIG_VERSION
ENV MY_FONTCONFIG_VERSION=${FONTCONFIG_VERSION} ENV MY_FONTCONFIG_VERSION=${FONTCONFIG_VERSION}
RUN if [ -f "/3rd_party/fontconfig-${MY_FONTCONFIG_VERSION}.tar.gz" ]; then \ RUN if [ -f "/3rd_party/fontconfig-${MY_FONTCONFIG_VERSION}.tar.gz" ]; then \
tar xvzf /3rd_party/fontconfig-${MY_FONTCONFIG_VERSION}.tar.gz \ cd /3rd_party && sha256sum -c ./fontconfig-${MY_FONTCONFIG_VERSION}.tar.gz.sha256 && cd - \
&& tar xvzf /3rd_party/fontconfig-${MY_FONTCONFIG_VERSION}.tar.gz \
&& cd fontconfig-${MY_FONTCONFIG_VERSION} \ && cd fontconfig-${MY_FONTCONFIG_VERSION} \
&& meson setup \ && meson setup \
--cross-file ${MY_TOOLCHAIN_FILE_MESON} \ --cross-file ${MY_TOOLCHAIN_FILE_MESON} \
@ -350,12 +372,15 @@ RUN if [ -f "/3rd_party/fontconfig-${MY_FONTCONFIG_VERSION}.tar.gz" ]; then \
ARG OPENAL_VERSION ARG OPENAL_VERSION
ENV MY_OPENAL_VERSION=${OPENAL_VERSION} ENV MY_OPENAL_VERSION=${OPENAL_VERSION}
RUN if [ -f "/3rd_party/openal-${MY_OPENAL_VERSION}.tar.gz" ]; then \ RUN if [ -f "/3rd_party/openal-${MY_OPENAL_VERSION}.tar.gz" ]; then \
tar xvzf /3rd_party/openal-${MY_OPENAL_VERSION}.tar.gz \ cd /3rd_party && sha256sum -c ./openal-${MY_OPENAL_VERSION}.tar.gz.sha256 && cd - \
&& tar xvzf /3rd_party/openal-${MY_OPENAL_VERSION}.tar.gz \
&& cd openal-soft-${MY_OPENAL_VERSION} \ && cd openal-soft-${MY_OPENAL_VERSION} \
&& mkdir _build \ && mkdir _build \
&& cd _build \ && cd _build \
&& cmake .. -DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \ && cmake .. \
-DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \ -DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
-DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
&& make -j${MY_NUM_JOBS} \ && make -j${MY_NUM_JOBS} \
&& make install \ && make install \
&& mv ${MY_MINGW_DIR}/bin/OpenAL32.dll ${MY_MINGW_DIR}/bin/openal32.dll \ && mv ${MY_MINGW_DIR}/bin/OpenAL32.dll ${MY_MINGW_DIR}/bin/openal32.dll \
@ -365,10 +390,11 @@ RUN if [ -f "/3rd_party/openal-${MY_OPENAL_VERSION}.tar.gz" ]; then \
ARG ICU_VERSION ARG ICU_VERSION
ENV MY_ICU_VERSION=${ICU_VERSION} ENV MY_ICU_VERSION=${ICU_VERSION}
RUN tar xvzf /3rd_party/mingw64/icu-release-${MY_ICU_VERSION}.tar.gz \ RUN cd /3rd_party/mingw64 && sha256sum -c ./icu-release-${MY_ICU_VERSION}.tar.gz.sha256 && cd - \
&& tar xvzf /3rd_party/mingw64/icu-release-${MY_ICU_VERSION}.tar.gz \
&& cp -r icu-release-${MY_ICU_VERSION} icu-release-${MY_ICU_VERSION}-cross \ && cp -r icu-release-${MY_ICU_VERSION} icu-release-${MY_ICU_VERSION}-cross \
&& cd icu-release-${MY_ICU_VERSION}-cross/icu4c/source \ && cd icu-release-${MY_ICU_VERSION}-cross/icu4c/source \
&& ./configure \ && CXXFLAGS="-std=gnu++17" ./configure \
--disable-samples \ --disable-samples \
--disable-tests \ --disable-tests \
--enable-shared \ --enable-shared \
@ -379,7 +405,7 @@ RUN tar xvzf /3rd_party/mingw64/icu-release-${MY_ICU_VERSION}.tar.gz \
RUN cd ${MY_WORKDIR} \ RUN cd ${MY_WORKDIR} \
&& cd icu-release-${MY_ICU_VERSION}/icu4c/source \ && cd icu-release-${MY_ICU_VERSION}/icu4c/source \
&& ./configure \ && CXXFLAGS="-std=gnu++17" ./configure \
--build=x86_64-alpine-linux-musl \ --build=x86_64-alpine-linux-musl \
--disable-samples \ --disable-samples \
--disable-tests \ --disable-tests \
@ -398,7 +424,8 @@ RUN cd ${MY_WORKDIR} \
ARG OPENSSL_VERSION ARG OPENSSL_VERSION
ENV MY_OPENSSL_VERSION=${OPENSSL_VERSION} ENV MY_OPENSSL_VERSION=${OPENSSL_VERSION}
RUN if [ -f "/3rd_party/openssl-${MY_OPENSSL_VERSION}.tar.gz" ]; then \ RUN if [ -f "/3rd_party/openssl-${MY_OPENSSL_VERSION}.tar.gz" ]; then \
tar xvzf /3rd_party/openssl-${MY_OPENSSL_VERSION}.tar.gz \ cd /3rd_party && sha256sum -c ./openssl-${MY_OPENSSL_VERSION}.tar.gz.sha256 && cd - \
&& tar xvzf /3rd_party/openssl-${MY_OPENSSL_VERSION}.tar.gz \
&& cd openssl-${MY_OPENSSL_VERSION} \ && cd openssl-${MY_OPENSSL_VERSION} \
&& ./Configure \ && ./Configure \
--cross-compile-prefix=${MY_MINGW_PREFIX}- \ --cross-compile-prefix=${MY_MINGW_PREFIX}- \
@ -421,11 +448,14 @@ ARG BOOST2_PATCH_VERSION
ENV MY_BOOST2_PATCH_VERSION=${BOOST2_PATCH_VERSION} ENV MY_BOOST2_PATCH_VERSION=${BOOST2_PATCH_VERSION}
ENV MY_BOOST2_VERSION=${MY_BOOST2_MAJOR_VERSION}_${MY_BOOST2_MINOR_VERSION}_${MY_BOOST2_PATCH_VERSION} ENV MY_BOOST2_VERSION=${MY_BOOST2_MAJOR_VERSION}_${MY_BOOST2_MINOR_VERSION}_${MY_BOOST2_PATCH_VERSION}
RUN if [ -f "/3rd_party/boost_${MY_BOOST2_MAJOR_VERSION}_${MY_BOOST2_MINOR_VERSION}_${MY_BOOST2_PATCH_VERSION}.tar.gz" ]; then \ RUN if [ -f "/3rd_party/boost_${MY_BOOST2_MAJOR_VERSION}_${MY_BOOST2_MINOR_VERSION}_${MY_BOOST2_PATCH_VERSION}.tar.gz" ]; then \
tar xvzf /3rd_party/boost_${MY_BOOST2_MAJOR_VERSION}_${MY_BOOST2_MINOR_VERSION}_${MY_BOOST2_PATCH_VERSION}.tar.gz \ cd /3rd_party && sha256sum -c ./boost_${MY_BOOST2_MAJOR_VERSION}_${MY_BOOST2_MINOR_VERSION}_${MY_BOOST2_PATCH_VERSION}.tar.gz.sha256 && cd - \
&& tar xvzf /3rd_party/boost_${MY_BOOST2_MAJOR_VERSION}_${MY_BOOST2_MINOR_VERSION}_${MY_BOOST2_PATCH_VERSION}.tar.gz \
&& cd boost_${MY_BOOST2_VERSION} \ && cd boost_${MY_BOOST2_VERSION} \
&& ./bootstrap.sh \ && ./bootstrap.sh \
--with-libraries=atomic,chrono,date_time,filesystem,iostreams,locale,log,program_options,random,regex,serialization,system,test,thread \ --with-libraries=atomic,chrono,date_time,filesystem,iostreams,locale,log,program_options,random,regex,serialization,system,test,thread \
address-model=64 \ address-model=64 \
cxxstd=${MY_CXX_STANDARD} \
cxxstd-dialect=gnu \
architecture=x86 \ architecture=x86 \
link=static,shared \ link=static,shared \
target-os=windows \ target-os=windows \
@ -438,6 +468,8 @@ RUN if [ -f "/3rd_party/boost_${MY_BOOST2_MAJOR_VERSION}_${MY_BOOST2_MINOR_VERSI
--prefix=${MY_MINGW_DIR} \ --prefix=${MY_MINGW_DIR} \
-j${MY_NUM_JOBS} \ -j${MY_NUM_JOBS} \
address-model=64 \ address-model=64 \
cxxstd=${MY_CXX_STANDARD} \
cxxstd-dialect=gnu \
architecture=x86 \ architecture=x86 \
link=static,shared \ link=static,shared \
target-os=windows \ target-os=windows \
@ -457,7 +489,8 @@ ARG BOOST_PATCH_VERSION
ENV MY_BOOST_PATCH_VERSION=${BOOST_PATCH_VERSION} ENV MY_BOOST_PATCH_VERSION=${BOOST_PATCH_VERSION}
ENV MY_BOOST_VERSION=${MY_BOOST_MAJOR_VERSION}_${MY_BOOST_MINOR_VERSION}_${MY_BOOST_PATCH_VERSION} ENV MY_BOOST_VERSION=${MY_BOOST_MAJOR_VERSION}_${MY_BOOST_MINOR_VERSION}_${MY_BOOST_PATCH_VERSION}
RUN if [ -f "/3rd_party/boost_${MY_BOOST_MAJOR_VERSION}_${MY_BOOST_MINOR_VERSION}_${MY_BOOST_PATCH_VERSION}.tar.gz" ]; then \ RUN if [ -f "/3rd_party/boost_${MY_BOOST_MAJOR_VERSION}_${MY_BOOST_MINOR_VERSION}_${MY_BOOST_PATCH_VERSION}.tar.gz" ]; then \
tar xvzf /3rd_party/boost_${MY_BOOST_MAJOR_VERSION}_${MY_BOOST_MINOR_VERSION}_${MY_BOOST_PATCH_VERSION}.tar.gz \ cd /3rd_party && sha256sum -c ./boost_${MY_BOOST_MAJOR_VERSION}_${MY_BOOST_MINOR_VERSION}_${MY_BOOST_PATCH_VERSION}.tar.gz.sha256 && cd - \
&& tar xvzf /3rd_party/boost_${MY_BOOST_MAJOR_VERSION}_${MY_BOOST_MINOR_VERSION}_${MY_BOOST_PATCH_VERSION}.tar.gz \
&& cd boost_${MY_BOOST_VERSION} \ && cd boost_${MY_BOOST_VERSION} \
&& echo "using gcc : gcc : ${MY_MINGW_PREFIX}-g++ ;" \ && echo "using gcc : gcc : ${MY_MINGW_PREFIX}-g++ ;" \
>./user-config.jam \ >./user-config.jam \
@ -465,6 +498,8 @@ RUN if [ -f "/3rd_party/boost_${MY_BOOST_MAJOR_VERSION}_${MY_BOOST_MINOR_VERSION
--with-libraries=atomic,chrono,date_time,filesystem,iostreams,locale,log,program_options,random,regex,serialization,system,test,thread \ --with-libraries=atomic,chrono,date_time,filesystem,iostreams,locale,log,program_options,random,regex,serialization,system,test,thread \
address-model=64 \ address-model=64 \
architecture=x86 \ architecture=x86 \
cxxstd=${MY_CXX_STANDARD} \
cxxstd-dialect=gnu \
link=static,shared \ link=static,shared \
target-os=windows \ target-os=windows \
threading=multi \ threading=multi \
@ -476,6 +511,8 @@ RUN if [ -f "/3rd_party/boost_${MY_BOOST_MAJOR_VERSION}_${MY_BOOST_MINOR_VERSION
-j${MY_NUM_JOBS} \ -j${MY_NUM_JOBS} \
address-model=64 \ address-model=64 \
architecture=x86 \ architecture=x86 \
cxxstd=${MY_CXX_STANDARD} \
cxxstd-dialect=gnu \
link=static,shared \ link=static,shared \
target-os=windows \ target-os=windows \
threading=multi \ threading=multi \
@ -488,30 +525,37 @@ RUN if [ -f "/3rd_party/boost_${MY_BOOST_MAJOR_VERSION}_${MY_BOOST_MINOR_VERSION
ARG OGG_VERSION ARG OGG_VERSION
ENV MY_OGG_VERSION=${OGG_VERSION} ENV MY_OGG_VERSION=${OGG_VERSION}
RUN if [ -f "/3rd_party/ogg-v${MY_OGG_VERSION}.tar.gz" ]; then \ RUN if [ -f "/3rd_party/ogg-v${MY_OGG_VERSION}.tar.gz" ]; then \
tar xvzf /3rd_party/ogg-v${MY_OGG_VERSION}.tar.gz \ cd /3rd_party && sha256sum -c ./ogg-v${MY_OGG_VERSION}.tar.gz.sha256 && cd - \
&& cd ogg-${MY_OGG_VERSION} \ && tar xvzf /3rd_party/ogg-v${MY_OGG_VERSION}.tar.gz \
&& cd libogg-${MY_OGG_VERSION} \
&& mkdir build \ && mkdir build \
&& cd build \ && cd build \
&& cmake .. -DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \ && cmake .. \
-DBUILD_SHARED_LIBS=ON \ -DBUILD_SHARED_LIBS=ON \
-DBUILD_STATIC_LIBS=ON \ -DBUILD_STATIC_LIBS=ON \
-DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \ -DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
-DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
&& make -j${MY_NUM_JOBS} \ && make -j${MY_NUM_JOBS} \
&& make install \ && make install \
&& cd ${MY_WORKDIR} \ && cd ${MY_WORKDIR} \
&& rm -r ogg-${MY_OGG_VERSION} \ && rm -r libogg-${MY_OGG_VERSION} \
; fi ; fi
ARG VORBIS_VERSION ARG VORBIS_VERSION
ENV MY_VORBIS_VERSION=${VORBIS_VERSION} ENV MY_VORBIS_VERSION=${VORBIS_VERSION}
RUN if [ -f "/3rd_party/vorbis-v${MY_VORBIS_VERSION}.tar.gz" ]; then \ RUN if [ -f "/3rd_party/vorbis-v${MY_VORBIS_VERSION}.tar.gz" ]; then \
tar xvzf /3rd_party/vorbis-v${MY_VORBIS_VERSION}.tar.gz \ cd /3rd_party && sha256sum -c ./vorbis-v${MY_VORBIS_VERSION}.tar.gz.sha256 && cd - \
&& tar xvzf /3rd_party/vorbis-v${MY_VORBIS_VERSION}.tar.gz \
&& cd vorbis-${MY_VORBIS_VERSION} \ && cd vorbis-${MY_VORBIS_VERSION} \
&& /3rd_party/vorbis_patch.sh /3rd_party . \
&& mkdir build \ && mkdir build \
&& cd build \ && cd build \
&& cmake .. -DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \ && cmake .. \
-DBUILD_SHARED_LIBS=OFF \ -DBUILD_SHARED_LIBS=OFF \
-DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \ -DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
-DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
&& make -j${MY_NUM_JOBS} \ && make -j${MY_NUM_JOBS} \
&& make install \ && make install \
&& cd ${MY_WORKDIR} \ && cd ${MY_WORKDIR} \
@ -521,18 +565,21 @@ RUN if [ -f "/3rd_party/vorbis-v${MY_VORBIS_VERSION}.tar.gz" ]; then \
ARG FLAC_VERSION ARG FLAC_VERSION
ENV MY_FLAC_VERSION=${FLAC_VERSION} ENV MY_FLAC_VERSION=${FLAC_VERSION}
RUN if [ -f "/3rd_party/flac-${MY_FLAC_VERSION}.tar.gz" ]; then \ RUN if [ -f "/3rd_party/flac-${MY_FLAC_VERSION}.tar.gz" ]; then \
tar xvzf /3rd_party/flac-${MY_FLAC_VERSION}.tar.gz \ cd /3rd_party && sha256sum -c ./flac-${MY_FLAC_VERSION}.tar.gz.sha256 && cd - \
&& tar xvzf /3rd_party/flac-${MY_FLAC_VERSION}.tar.gz \
&& cd flac-${MY_FLAC_VERSION} \ && cd flac-${MY_FLAC_VERSION} \
&& mkdir build \ && mkdir build \
&& cd build \ && cd build \
&& cmake .. -DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \ && cmake .. \
-DBUILD_SHARED_LIBS=ON \ -DBUILD_DOCS=OFF \
-DBUILD_STATIC_LIBS=ON \
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
-DBUILD_EXAMPLES=ON \ -DBUILD_EXAMPLES=ON \
-DBUILD_PROGRAMS=ON \ -DBUILD_PROGRAMS=ON \
-DBUILD_SHARED_LIBS=ON \
-DBUILD_STATIC_LIBS=ON \
-DBUILD_TESTING=OFF \ -DBUILD_TESTING=OFF \
-DBUILD_DOCS=OFF \ -DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
-DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
-DINSTALL_MANPAGES=OFF \ -DINSTALL_MANPAGES=OFF \
&& make -j${MY_NUM_JOBS} \ && make -j${MY_NUM_JOBS} \
&& make install \ && make install \
@ -543,7 +590,8 @@ RUN if [ -f "/3rd_party/flac-${MY_FLAC_VERSION}.tar.gz" ]; then \
ARG SFML_VERSION ARG SFML_VERSION
ENV MY_SFML_VERSION=${SFML_VERSION} ENV MY_SFML_VERSION=${SFML_VERSION}
RUN if [ -f "/3rd_party/SFML-${MY_SFML_VERSION}.tar.gz" ]; then \ RUN if [ -f "/3rd_party/SFML-${MY_SFML_VERSION}.tar.gz" ]; then \
tar xvzf /3rd_party/SFML-${MY_SFML_VERSION}.tar.gz \ cd /3rd_party && sha256sum -c ./SFML-${MY_SFML_VERSION}.tar.gz.sha256 && cd - \
&& tar xvzf /3rd_party/SFML-${MY_SFML_VERSION}.tar.gz \
&& cd SFML-${MY_SFML_VERSION} \ && cd SFML-${MY_SFML_VERSION} \
&& sed -i s/set_target_properties\(\$\{target\}\ PROPERTIES\ PREFIX\ \"\"\)// \ && sed -i s/set_target_properties\(\$\{target\}\ PROPERTIES\ PREFIX\ \"\"\)// \
cmake/Macros.cmake \ cmake/Macros.cmake \
@ -551,10 +599,12 @@ RUN if [ -f "/3rd_party/SFML-${MY_SFML_VERSION}.tar.gz" ]; then \
cmake/Macros.cmake \ cmake/Macros.cmake \
&& mkdir build \ && mkdir build \
&& cd build \ && cd build \
&& cmake .. -DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \ && cmake .. \
-DBUILD_SHARED_LIBS=ON \ -DBUILD_SHARED_LIBS=ON \
-DBUILD_STATIC_LIBS=ON \ -DBUILD_STATIC_LIBS=ON \
-DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \ -DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
-DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
&& make -j${MY_NUM_JOBS} \ && make -j${MY_NUM_JOBS} \
&& make install \ && make install \
&& cd ${MY_WORKDIR} \ && cd ${MY_WORKDIR} \
@ -564,14 +614,16 @@ RUN if [ -f "/3rd_party/SFML-${MY_SFML_VERSION}.tar.gz" ]; then \
ARG SPDLOG_VERSION ARG SPDLOG_VERSION
ENV MY_SPDLOG_VERSION=${SPDLOG_VERSION} ENV MY_SPDLOG_VERSION=${SPDLOG_VERSION}
RUN if [ -f "/3rd_party/spdlog-${MY_SPDLOG_VERSION}.tar.gz" ]; then \ RUN if [ -f "/3rd_party/spdlog-${MY_SPDLOG_VERSION}.tar.gz" ]; then \
tar xvzf /3rd_party/spdlog-${MY_SPDLOG_VERSION}.tar.gz \ cd /3rd_party && sha256sum -c ./spdlog-${MY_SPDLOG_VERSION}.tar.gz.sha256 && cd - \
&& tar xvzf /3rd_party/spdlog-${MY_SPDLOG_VERSION}.tar.gz \
&& cd spdlog-${MY_SPDLOG_VERSION} \ && cd spdlog-${MY_SPDLOG_VERSION} \
&& mkdir build \ && mkdir build \
&& cd build \ && cd build \
&& cmake .. -DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \ && cmake .. \
-DBUILD_SHARED_LIBS=OFF \
-DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \ -DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
-DSPDLOG_BUILD_SHARED=ON \ -DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
-DSPDLOG_BUILD_STATIC=ON \
-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 \
@ -584,19 +636,22 @@ RUN if [ -f "/3rd_party/spdlog-${MY_SPDLOG_VERSION}.tar.gz" ]; then \
ARG CLI11_VERSION ARG CLI11_VERSION
ENV MY_CLI11_VERSION=${CLI11_VERSION} ENV MY_CLI11_VERSION=${CLI11_VERSION}
RUN if [ -f "/3rd_party/CLI11-${MY_CLI11_VERSION}.tar.gz" ]; then \ RUN if [ -f "/3rd_party/CLI11-${MY_CLI11_VERSION}.tar.gz" ]; then \
tar xvzf /3rd_party/CLI11-${MY_CLI11_VERSION}.tar.gz \ cd /3rd_party && sha256sum -c ./CLI11-${MY_CLI11_VERSION}.tar.gz.sha256 && cd - \
&& tar xvzf /3rd_party/CLI11-${MY_CLI11_VERSION}.tar.gz \
&& cd CLI11-${MY_CLI11_VERSION} \ && cd CLI11-${MY_CLI11_VERSION} \
&& mkdir build \ && mkdir build \
&& cd build \ && cd build \
&& cmake .. -DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \ && cmake .. \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
-DCLI11_WARNINGS_AS_ERRORS=OFF \
-DCLI11_SINGLE_FILE=ON \
-DCLI11_BUILD_DOCS=OFF \ -DCLI11_BUILD_DOCS=OFF \
-DCLI11_BUILD_TESTS=OFF \
-DCLI11_BUILD_EXAMPLES=OFF \ -DCLI11_BUILD_EXAMPLES=OFF \
-DCLI11_BUILD_TESTS=OFF \
-DCLI11_INSTALL=ON \ -DCLI11_INSTALL=ON \
-DCLI11_SINGLE_FILE=ON \
-DCLI11_WARNINGS_AS_ERRORS=OFF \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
-DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
&& make -j${MY_NUM_JOBS} \ && make -j${MY_NUM_JOBS} \
&& make install \ && make install \
&& cd ${MY_WORKDIR} \ && cd ${MY_WORKDIR} \
@ -605,17 +660,22 @@ RUN if [ -f "/3rd_party/CLI11-${MY_CLI11_VERSION}.tar.gz" ]; then \
ARG CURL_VERSION ARG CURL_VERSION
ENV MY_CURL_VERSION=${CURL_VERSION} ENV MY_CURL_VERSION=${CURL_VERSION}
ARG CURL2_VERSION
ENV MY_CURL2_VERSION=${CURL2_VERSION}
RUN if [ -f "/3rd_party/curl-${MY_CURL_VERSION}.tar.gz" ]; then \ RUN if [ -f "/3rd_party/curl-${MY_CURL_VERSION}.tar.gz" ]; then \
tar xvzf /3rd_party/curl-${MY_CURL_VERSION}.tar.gz \ cd /3rd_party && sha256sum -c ./curl-${MY_CURL_VERSION}.tar.gz.sha256 && cd - \
&& cd curl-${MY_CURL_VERSION} \ && tar xvzf /3rd_party/curl-${MY_CURL_VERSION}.tar.gz \
&& cd curl-curl-${MY_CURL2_VERSION} \
&& mkdir build \ && mkdir build \
&& cd build \ && cd build \
&& cmake .. -DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \ && cmake .. \
-DBUILD_CURL_EXE=ON \ -DBUILD_CURL_EXE=ON \
-DBUILD_SHARED_LIBS=OFF \ -DBUILD_SHARED_LIBS=OFF \
-DBUILD_STATIC_LIBS=ON \ -DBUILD_STATIC_LIBS=ON \
-DBUILD_TESTING=OFF \ -DBUILD_TESTING=OFF \
-DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \ -DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
-DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
-DCURL_CA_BUNDLE=./cacert.pem \ -DCURL_CA_BUNDLE=./cacert.pem \
-DCURL_CA_FALLBACK=ON \ -DCURL_CA_FALLBACK=ON \
-DCURL_DISABLE_LDAP=ON \ -DCURL_DISABLE_LDAP=ON \
@ -630,22 +690,25 @@ RUN if [ -f "/3rd_party/curl-${MY_CURL_VERSION}.tar.gz" ]; then \
&& make -j${MY_NUM_JOBS} \ && make -j${MY_NUM_JOBS} \
&& make install \ && make install \
&& cd ${MY_WORKDIR} \ && cd ${MY_WORKDIR} \
&& rm -r curl-${MY_CURL_VERSION} \ && rm -r curl-curl-${MY_CURL2_VERSION} \
; fi ; fi
ARG CPP_HTTPLIB_VERSION ARG CPP_HTTPLIB_VERSION
ENV MY_CPP_HTTPLIB_VERSION=${CPP_HTTPLIB_VERSION} ENV MY_CPP_HTTPLIB_VERSION=${CPP_HTTPLIB_VERSION}
RUN if [ -f "/3rd_party/cpp-httplib-${MY_CPP_HTTPLIB_VERSION}.tar.gz" ]; then \ RUN if [ -f "/3rd_party/cpp-httplib-${MY_CPP_HTTPLIB_VERSION}.tar.gz" ]; then \
tar xvzf /3rd_party/cpp-httplib-${MY_CPP_HTTPLIB_VERSION}.tar.gz \ cd /3rd_party && sha256sum -c ./cpp-httplib-${MY_CPP_HTTPLIB_VERSION}.tar.gz.sha256 && cd - \
&& tar xvzf /3rd_party/cpp-httplib-${MY_CPP_HTTPLIB_VERSION}.tar.gz \
&& cd cpp-httplib-${MY_CPP_HTTPLIB_VERSION} \ && cd cpp-httplib-${MY_CPP_HTTPLIB_VERSION} \
&& mkdir build \ && mkdir build \
&& cd build \ && cd build \
&& cmake .. -DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \ && cmake .. \
-DCMAKE_BUILD_TYPE=Release \ -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \ -DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
-DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
-DHTTPLIB_REQUIRE_BROTLI=OFF \
-DHTTPLIB_REQUIRE_OPENSSL=ON \ -DHTTPLIB_REQUIRE_OPENSSL=ON \
-DHTTPLIB_REQUIRE_ZLIB=ON \ -DHTTPLIB_REQUIRE_ZLIB=ON \
-DHTTPLIB_REQUIRE_BROTLI=OFF \
-DHTTPLIB_TEST=OFF \ -DHTTPLIB_TEST=OFF \
&& make -j${MY_NUM_JOBS} \ && make -j${MY_NUM_JOBS} \
&& make install \ && make install \
@ -656,14 +719,17 @@ RUN if [ -f "/3rd_party/cpp-httplib-${MY_CPP_HTTPLIB_VERSION}.tar.gz" ]; then \
ARG FMT_VERSION ARG FMT_VERSION
ENV MY_FMT_VERSION=${FMT_VERSION} ENV MY_FMT_VERSION=${FMT_VERSION}
RUN if [ -f "/3rd_party/fmt-${MY_FMT_VERSION}.tar.gz" ]; then \ RUN if [ -f "/3rd_party/fmt-${MY_FMT_VERSION}.tar.gz" ]; then \
tar xvzf /3rd_party/fmt-${MY_FMT_VERSION}.tar.gz \ cd /3rd_party && sha256sum -c ./fmt-${MY_FMT_VERSION}.tar.gz.sha256 && cd - \
&& tar xvzf /3rd_party/fmt-${MY_FMT_VERSION}.tar.gz \
&& cd fmt-${MY_FMT_VERSION} \ && cd fmt-${MY_FMT_VERSION} \
&& mkdir build \ && mkdir build \
&& cd build \ && cd build \
&& cmake .. -DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \ && cmake .. \
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
-DBUILD_SHARED_LIBS=ON \ -DBUILD_SHARED_LIBS=ON \
-DBUILD_STATIC_LIBS=ON \ -DBUILD_STATIC_LIBS=ON \
-DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
-DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
-DFMT_DOC=OFF \ -DFMT_DOC=OFF \
-DFMT_TEST=OFF \ -DFMT_TEST=OFF \
&& make -j${MY_NUM_JOBS} \ && make -j${MY_NUM_JOBS} \
@ -675,13 +741,16 @@ RUN if [ -f "/3rd_party/fmt-${MY_FMT_VERSION}.tar.gz" ]; then \
ARG GTEST_VERSION ARG GTEST_VERSION
ENV MY_GTEST_VERSION=${GTEST_VERSION} ENV MY_GTEST_VERSION=${GTEST_VERSION}
RUN if [ -f "/3rd_party/googletest-${MY_GTEST_VERSION}.tar.gz" ]; then \ RUN if [ -f "/3rd_party/googletest-${MY_GTEST_VERSION}.tar.gz" ]; then \
tar xvzf /3rd_party/googletest-${MY_GTEST_VERSION}.tar.gz \ cd /3rd_party && sha256sum -c ./googletest-${MY_GTEST_VERSION}.tar.gz.sha256 && cd - \
&& tar xvzf /3rd_party/googletest-${MY_GTEST_VERSION}.tar.gz \
&& cd googletest-${MY_GTEST_VERSION} \ && cd googletest-${MY_GTEST_VERSION} \
&& mkdir build \ && mkdir build \
&& cd build \ && cd build \
&& cmake .. -DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \ && cmake .. \
-DCMAKE_BUILD_TYPE=Release \ -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \ -DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
-DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
&& make -j${MY_NUM_JOBS} \ && make -j${MY_NUM_JOBS} \
&& make install \ && make install \
&& cd ${MY_WORKDIR} \ && cd ${MY_WORKDIR} \
@ -691,13 +760,16 @@ RUN if [ -f "/3rd_party/googletest-${MY_GTEST_VERSION}.tar.gz" ]; then \
ARG JSON_VERSION ARG JSON_VERSION
ENV MY_JSON_VERSION=${JSON_VERSION} ENV MY_JSON_VERSION=${JSON_VERSION}
RUN if [ -f "/3rd_party/json-${MY_JSON_VERSION}.tar.gz" ]; then \ RUN if [ -f "/3rd_party/json-${MY_JSON_VERSION}.tar.gz" ]; then \
tar xvzf /3rd_party/json-${MY_JSON_VERSION}.tar.gz \ cd /3rd_party && sha256sum -c ./json-${MY_JSON_VERSION}.tar.gz.sha256 && cd - \
&& tar xvzf /3rd_party/json-${MY_JSON_VERSION}.tar.gz \
&& cd json-${MY_JSON_VERSION} \ && cd json-${MY_JSON_VERSION} \
&& mkdir build \ && mkdir build \
&& cd build \ && cd build \
&& cmake .. -DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \ && cmake .. \
-DCMAKE_BUILD_TYPE=Release \ -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \ -DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
-DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
-DJSON_BuildTests=OFF \ -DJSON_BuildTests=OFF \
-DJSON_Install=ON \ -DJSON_Install=ON \
-DJSON_MultipleHeaders=OFF \ -DJSON_MultipleHeaders=OFF \
@ -710,13 +782,16 @@ RUN if [ -f "/3rd_party/json-${MY_JSON_VERSION}.tar.gz" ]; then \
ARG LIBEVENT_VERSION ARG LIBEVENT_VERSION
ENV MY_LIBEVENT_VERSION=${LIBEVENT_VERSION} ENV MY_LIBEVENT_VERSION=${LIBEVENT_VERSION}
RUN if [ -f "/3rd_party/libevent-${MY_LIBEVENT_VERSION}-stable.tar.gz" ]; then \ RUN if [ -f "/3rd_party/libevent-${MY_LIBEVENT_VERSION}-stable.tar.gz" ]; then \
tar xvzf /3rd_party/libevent-${MY_LIBEVENT_VERSION}-stable.tar.gz \ cd /3rd_party && sha256sum -c ./libevent-${MY_LIBEVENT_VERSION}-stable.tar.gz.sha256 && cd - \
&& cd libevent-${MY_LIBEVENT_VERSION}-stable \ && tar xvzf /3rd_party/libevent-${MY_LIBEVENT_VERSION}-stable.tar.gz \
&& cd libevent-release-${MY_LIBEVENT_VERSION}-stable \
&& mkdir build \ && mkdir build \
&& cd build \ && cd build \
&& cmake .. -DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \ && cmake .. \
-DCMAKE_BUILD_TYPE=Release \ -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \ -DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
-DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
-DEVENT__DISABLE_OPENSSL=ON \ -DEVENT__DISABLE_OPENSSL=ON \
-DEVENT__DISABLE_SAMPLES=ON \ -DEVENT__DISABLE_SAMPLES=ON \
-DEVENT__DISABLE_TESTS=ON \ -DEVENT__DISABLE_TESTS=ON \
@ -724,14 +799,15 @@ RUN if [ -f "/3rd_party/libevent-${MY_LIBEVENT_VERSION}-stable.tar.gz" ]; then \
&& make -j${MY_NUM_JOBS} \ && make -j${MY_NUM_JOBS} \
&& make install \ && make install \
&& cd ${MY_WORKDIR} \ && cd ${MY_WORKDIR} \
&& rm -r libevent-${MY_LIBEVENT_VERSION}-stable \ && rm -r libevent-release-${MY_LIBEVENT_VERSION}-stable \
; fi ; fi
ARG LIBSODIUM_VERSION ARG LIBSODIUM_VERSION
ENV MY_LIBSODIUM_VERSION=${LIBSODIUM_VERSION} ENV MY_LIBSODIUM_VERSION=${LIBSODIUM_VERSION}
RUN if [ -f "/3rd_party/libsodium-${MY_LIBSODIUM_VERSION}.tar.gz" ]; then \ RUN if [ -f "/3rd_party/libsodium-${MY_LIBSODIUM_VERSION}.tar.gz" ]; then \
tar xvzf /3rd_party/libsodium-${MY_LIBSODIUM_VERSION}.tar.gz \ cd /3rd_party && sha256sum -c ./libsodium-${MY_LIBSODIUM_VERSION}.tar.gz.sha256 && cd - \
&& cd libsodium-${MY_LIBSODIUM_VERSION} \ && tar xvzf /3rd_party/libsodium-${MY_LIBSODIUM_VERSION}.tar.gz \
&& cd libsodium-${MY_LIBSODIUM_VERSION}-RELEASE \
&& CFLAGS="-O3 -fomit-frame-pointer -m64 -mtune=generic" ./configure \ && CFLAGS="-O3 -fomit-frame-pointer -m64 -mtune=generic" ./configure \
--enable-shared=yes \ --enable-shared=yes \
--enable-static=yes \ --enable-static=yes \
@ -740,21 +816,25 @@ RUN if [ -f "/3rd_party/libsodium-${MY_LIBSODIUM_VERSION}.tar.gz" ]; then \
&& make -j${MY_NUM_JOBS} \ && make -j${MY_NUM_JOBS} \
&& make install \ && make install \
&& cd ${MY_WORKDIR} \ && cd ${MY_WORKDIR} \
&& rm -r libsodium-${MY_LIBSODIUM_VERSION} \ && rm -r libsodium-${MY_LIBSODIUM_VERSION}-RELEASE \
; fi ; fi
ARG NUSPELL_VERSION ARG NUSPELL_VERSION
ENV MY_NUSPELL_VERSION=${NUSPELL_VERSION} ENV MY_NUSPELL_VERSION=${NUSPELL_VERSION}
RUN if [ -f "/3rd_party/nuspell-v${MY_NUSPELL_VERSION}.tar.gz" ]; then \ RUN if [ -f "/3rd_party/nuspell-v${MY_NUSPELL_VERSION}.tar.gz" ]; then \
tar xvzf /3rd_party/nuspell-v${MY_NUSPELL_VERSION}.tar.gz \ cd /3rd_party && sha256sum -c ./nuspell-v${MY_NUSPELL_VERSION}.tar.gz.sha256 && cd - \
&& tar xvzf /3rd_party/nuspell-v${MY_NUSPELL_VERSION}.tar.gz \
&& cd nuspell-${MY_NUSPELL_VERSION} \ && cd nuspell-${MY_NUSPELL_VERSION} \
&& mkdir build \ && mkdir build \
&& cd build \ && cd build \
&& cmake .. -DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \ && cmake .. \
-DCMAKE_BUILD_TYPE=Release \ -DBUILD_DOCS=OFF \
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
-DBUILD_TESTING=OFF \ -DBUILD_TESTING=OFF \
-DBUILD_TOOLS=OFF \ -DBUILD_TOOLS=OFF \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
-DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
&& make -j${MY_NUM_JOBS} \ && make -j${MY_NUM_JOBS} \
&& make install \ && make install \
&& cd ${MY_WORKDIR} \ && cd ${MY_WORKDIR} \
@ -764,13 +844,16 @@ RUN if [ -f "/3rd_party/nuspell-v${MY_NUSPELL_VERSION}.tar.gz" ]; then \
ARG PUGIXML_VERSION ARG PUGIXML_VERSION
ENV MY_PUGIXML_VERSION=${PUGIXML_VERSION} ENV MY_PUGIXML_VERSION=${PUGIXML_VERSION}
RUN if [ -f "/3rd_party/pugixml-${MY_PUGIXML_VERSION}.tar.gz" ]; then \ RUN if [ -f "/3rd_party/pugixml-${MY_PUGIXML_VERSION}.tar.gz" ]; then \
tar xvzf /3rd_party/pugixml-${MY_PUGIXML_VERSION}.tar.gz \ cd /3rd_party && sha256sum -c ./pugixml-${MY_PUGIXML_VERSION}.tar.gz.sha256 && cd - \
&& tar xvzf /3rd_party/pugixml-${MY_PUGIXML_VERSION}.tar.gz \
&& cd pugixml-${MY_PUGIXML_VERSION} \ && cd pugixml-${MY_PUGIXML_VERSION} \
&& mkdir build \ && mkdir build \
&& cd build \ && cd build \
&& cmake .. -DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \ && cmake .. \
-DCMAKE_BUILD_TYPE=Release \ -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \ -DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
-DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
&& make -j${MY_NUM_JOBS} \ && make -j${MY_NUM_JOBS} \
&& make install \ && make install \
&& cd ${MY_WORKDIR} \ && cd ${MY_WORKDIR} \
@ -780,14 +863,17 @@ RUN if [ -f "/3rd_party/pugixml-${MY_PUGIXML_VERSION}.tar.gz" ]; then \
ARG ROCKSDB_VERSION ARG ROCKSDB_VERSION
ENV MY_ROCKSDB_VERSION=${ROCKSDB_VERSION} ENV MY_ROCKSDB_VERSION=${ROCKSDB_VERSION}
RUN if [ -f "/3rd_party/rocksdb-${MY_ROCKSDB_VERSION}.tar.gz" ]; then \ RUN if [ -f "/3rd_party/rocksdb-${MY_ROCKSDB_VERSION}.tar.gz" ]; then \
tar xvzf /3rd_party/rocksdb-${MY_ROCKSDB_VERSION}.tar.gz \ cd /3rd_party && sha256sum -c ./rocksdb-${MY_ROCKSDB_VERSION}.tar.gz.sha256 && cd - \
&& tar xvzf /3rd_party/rocksdb-${MY_ROCKSDB_VERSION}.tar.gz \
&& cd rocksdb-${MY_ROCKSDB_VERSION} \ && cd rocksdb-${MY_ROCKSDB_VERSION} \
&& echo -e "add_definitions(-include cstdint)">>CMakeLists.txt \ && echo -e "add_definitions(-include cstdint)">>CMakeLists.txt \
&& mkdir build \ && mkdir build \
&& cd build \ && cd build \
&& cmake .. -DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \ && cmake .. \
-DCMAKE_BUILD_TYPE=Release \ -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \ -DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
-DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
-DFAIL_ON_WARNINGS=OFF \ -DFAIL_ON_WARNINGS=OFF \
-DPORTABLE=1 \ -DPORTABLE=1 \
-DROCKSDB_INSTALL_ON_WINDOWS=ON \ -DROCKSDB_INSTALL_ON_WINDOWS=ON \
@ -811,7 +897,8 @@ RUN if [ -f "/3rd_party/rocksdb-${MY_ROCKSDB_VERSION}.tar.gz" ]; then \
ARG SECP256K1_VERSION ARG SECP256K1_VERSION
ENV MY_SECP256K1_VERSION=${SECP256K1_VERSION} ENV MY_SECP256K1_VERSION=${SECP256K1_VERSION}
RUN if [ -f "/3rd_party/secp256k1-${MY_SECP256K1_VERSION}.tar.gz" ]; then \ RUN if [ -f "/3rd_party/secp256k1-${MY_SECP256K1_VERSION}.tar.gz" ]; then \
tar xvzf /3rd_party/secp256k1-${MY_SECP256K1_VERSION}.tar.gz \ cd /3rd_party && sha256sum -c ./secp256k1-${MY_SECP256K1_VERSION}.tar.gz.sha256 && cd - \
&& tar xvzf /3rd_party/secp256k1-${MY_SECP256K1_VERSION}.tar.gz \
&& cd secp256k1-${MY_SECP256K1_VERSION} \ && cd secp256k1-${MY_SECP256K1_VERSION} \
&& ./autogen.sh && ./configure \ && ./autogen.sh && ./configure \
--host=${MY_MINGW_PREFIX} \ --host=${MY_MINGW_PREFIX} \
@ -829,13 +916,16 @@ RUN if [ -f "/3rd_party/secp256k1-${MY_SECP256K1_VERSION}.tar.gz" ]; then \
ARG STDUUID_VERSION ARG STDUUID_VERSION
ENV MY_STDUUID_VERSION=${STDUUID_VERSION} ENV MY_STDUUID_VERSION=${STDUUID_VERSION}
RUN if [ -f "/3rd_party/stduuid-${MY_STDUUID_VERSION}.tar.gz" ]; then \ RUN if [ -f "/3rd_party/stduuid-${MY_STDUUID_VERSION}.tar.gz" ]; then \
tar xvzf /3rd_party/stduuid-${MY_STDUUID_VERSION}.tar.gz \ cd /3rd_party && sha256sum -c ./stduuid-${MY_STDUUID_VERSION}.tar.gz.sha256 && cd - \
&& tar xvzf /3rd_party/stduuid-${MY_STDUUID_VERSION}.tar.gz \
&& cd stduuid-${MY_STDUUID_VERSION} \ && cd stduuid-${MY_STDUUID_VERSION} \
&& mkdir build \ && mkdir build \
&& cd build \ && cd build \
&& cmake .. -DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \ && cmake .. \
-DCMAKE_BUILD_TYPE=Release \ -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \ -DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
-DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
-DUUID_BUILD_TESTS=OFF \ -DUUID_BUILD_TESTS=OFF \
-DUUID_ENABLE_INSTALL=ON \ -DUUID_ENABLE_INSTALL=ON \
-DUUID_USING_CXX20_SPAN=ON \ -DUUID_USING_CXX20_SPAN=ON \
@ -846,16 +936,19 @@ RUN if [ -f "/3rd_party/stduuid-${MY_STDUUID_VERSION}.tar.gz" ]; then \
; fi ; fi
RUN if [ -f "/3rd_party/tiny-process-library.tar.gz" ]; then \ RUN if [ -f "/3rd_party/tiny-process-library.tar.gz" ]; then \
tar xvzf /3rd_party/tiny-process-library.tar.gz \ cd /3rd_party && sha256sum -c ./tiny-process-library.tar.gz.sha256 && cd - \
&& tar xvzf /3rd_party/tiny-process-library.tar.gz \
&& cd tiny-process-library-master \ && cd tiny-process-library-master \
&& mkdir build \ && mkdir build \
&& cd build \ && cd build \
&& cmake .. -DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \ && cmake .. \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
-DBUILD_SHARED_LIBS=ON \ -DBUILD_SHARED_LIBS=ON \
-DBUILD_STATIC_LIBS=ON \ -DBUILD_STATIC_LIBS=ON \
-DBUILD_TESTING=OFF \ -DBUILD_TESTING=OFF \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
-DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
&& make -j${MY_NUM_JOBS} \ && make -j${MY_NUM_JOBS} \
&& make install \ && make install \
&& cd ${MY_WORKDIR} \ && cd ${MY_WORKDIR} \
@ -865,15 +958,18 @@ RUN if [ -f "/3rd_party/tiny-process-library.tar.gz" ]; then \
ARG WXWIDGETS_VERSION ARG WXWIDGETS_VERSION
ENV MY_WXWIDGETS_VERSION=${WXWIDGETS_VERSION} ENV MY_WXWIDGETS_VERSION=${WXWIDGETS_VERSION}
RUN if [ -f "/3rd_party/wxWidgets-${MY_WXWIDGETS_VERSION}.tar.bz2" ]; then \ RUN if [ -f "/3rd_party/wxWidgets-${MY_WXWIDGETS_VERSION}.tar.bz2" ]; then \
tar xvjf /3rd_party/wxWidgets-${MY_WXWIDGETS_VERSION}.tar.bz2 \ cd /3rd_party && sha256sum -c ./wxWidgets-${MY_WXWIDGETS_VERSION}.tar.bz2.sha256 && cd - \
&& tar xvjf /3rd_party/wxWidgets-${MY_WXWIDGETS_VERSION}.tar.bz2 \
&& cd wxWidgets-${MY_WXWIDGETS_VERSION} \ && cd wxWidgets-${MY_WXWIDGETS_VERSION} \
&& mkdir _build \ && mkdir _build \
&& cd _build \ && cd _build \
&& cmake .. -DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \ && cmake .. \
-DBUILD_SHARED_LIBS=ON \ -DBUILD_SHARED_LIBS=ON \
-DBUILD_STATIC_LIBS=ON \ -DBUILD_STATIC_LIBS=ON \
-DCMAKE_BUILD_TYPE=Release \ -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \ -DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
-DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
-DwxBUILD_MONOLITHIC=OFF \ -DwxBUILD_MONOLITHIC=OFF \
-DwxBUILD_SHARED=ON \ -DwxBUILD_SHARED=ON \
&& make -j${MY_NUM_JOBS} \ && make -j${MY_NUM_JOBS} \
@ -885,15 +981,18 @@ RUN if [ -f "/3rd_party/wxWidgets-${MY_WXWIDGETS_VERSION}.tar.bz2" ]; then \
ARG CXXOPTS_VERSION ARG CXXOPTS_VERSION
ENV MY_CXXOPTS_VERSION=${CXXOPTS_VERSION} ENV MY_CXXOPTS_VERSION=${CXXOPTS_VERSION}
RUN if [ -f "/3rd_party/cxxopts-v${MY_CXXOPTS_VERSION}.tar.gz" ]; then \ RUN if [ -f "/3rd_party/cxxopts-v${MY_CXXOPTS_VERSION}.tar.gz" ]; then \
tar xvzf /3rd_party/cxxopts-v${MY_CXXOPTS_VERSION}.tar.gz \ cd /3rd_party && sha256sum -c ./cxxopts-v${MY_CXXOPTS_VERSION}.tar.gz.sha256 && cd - \
&& tar xvzf /3rd_party/cxxopts-v${MY_CXXOPTS_VERSION}.tar.gz \
&& cd cxxopts-${MY_CXXOPTS_VERSION} \ && cd cxxopts-${MY_CXXOPTS_VERSION} \
&& mkdir _build \ && mkdir _build \
&& cd _build \ && cd _build \
&& cmake .. -DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \ && cmake .. \
-DBUILD_SHARED_LIBS=ON \ -DBUILD_SHARED_LIBS=ON \
-DBUILD_STATIC_LIBS=ON \ -DBUILD_STATIC_LIBS=ON \
-DCMAKE_BUILD_TYPE=Release \ -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \ -DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
-DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
-DCXXOPTS_BUILD_EXAMPLES=OFF \ -DCXXOPTS_BUILD_EXAMPLES=OFF \
-DCXXOPTS_BUILD_TESTS=OFF \ -DCXXOPTS_BUILD_TESTS=OFF \
-DCXXOPTS_ENABLE_INSTALL=ON \ -DCXXOPTS_ENABLE_INSTALL=ON \
@ -908,15 +1007,19 @@ RUN if [ -f "/3rd_party/cxxopts-v${MY_CXXOPTS_VERSION}.tar.gz" ]; then \
ARG NANA_VERSION ARG NANA_VERSION
ENV MY_NANA_VERSION=${NANA_VERSION} ENV MY_NANA_VERSION=${NANA_VERSION}
RUN if [ -f "/3rd_party/nana-v${MY_NANA_VERSION}.tar.gz" ]; then \ RUN if [ -f "/3rd_party/nana-v${MY_NANA_VERSION}.tar.gz" ]; then \
tar xvzf /3rd_party/nana-v${MY_NANA_VERSION}.tar.gz \ cd /3rd_party && sha256sum -c ./nana-v${MY_NANA_VERSION}.tar.gz.sha256 && cd - \
&& tar xvzf /3rd_party/nana-v${MY_NANA_VERSION}.tar.gz \
&& cd nana-${MY_NANA_VERSION} \ && cd nana-${MY_NANA_VERSION} \
&& /3rd_party/nana_patch.sh /3rd_party . \
&& mkdir _build \ && mkdir _build \
&& cd _build \ && cd _build \
&& cmake .. -DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \ && cmake .. \
-DBUILD_SHARED_LIBS=ON \ -DBUILD_SHARED_LIBS=ON \
-DBUILD_STATIC_LIBS=ON \ -DBUILD_STATIC_LIBS=ON \
-DCMAKE_BUILD_TYPE=Release \ -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \ -DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
-DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
-DNANA_CMAKE_ENABLE_AUDIO=OFF \ -DNANA_CMAKE_ENABLE_AUDIO=OFF \
-DNANA_CMAKE_ENABLE_JPEG=ON \ -DNANA_CMAKE_ENABLE_JPEG=ON \
-DNANA_CMAKE_ENABLE_PNG=ON \ -DNANA_CMAKE_ENABLE_PNG=ON \
@ -930,7 +1033,8 @@ RUN if [ -f "/3rd_party/nana-v${MY_NANA_VERSION}.tar.gz" ]; then \
ARG SDL_VERSION ARG SDL_VERSION
ENV MY_SDL_VERSION=${SDL_VERSION} ENV MY_SDL_VERSION=${SDL_VERSION}
RUN if [ -f "/3rd_party/sdl-${MY_SDL_VERSION}.tar.gz" ]; then \ RUN if [ -f "/3rd_party/sdl-${MY_SDL_VERSION}.tar.gz" ]; then \
tar xvzf /3rd_party/sdl-${MY_SDL_VERSION}.tar.gz \ cd /3rd_party && sha256sum -c ./sdl-${MY_SDL_VERSION}.tar.gz.sha256 && cd - \
&& tar xvzf /3rd_party/sdl-${MY_SDL_VERSION}.tar.gz \
&& cd SDL-release-${MY_SDL_VERSION} \ && cd SDL-release-${MY_SDL_VERSION} \
&& ./configure \ && ./configure \
--host=${MY_MINGW_PREFIX} \ --host=${MY_MINGW_PREFIX} \
@ -943,6 +1047,69 @@ RUN if [ -f "/3rd_party/sdl-${MY_SDL_VERSION}.tar.gz" ]; then \
&& rm -r SDL-release-${MY_SDL_VERSION} \ && rm -r SDL-release-${MY_SDL_VERSION} \
; fi ; fi
ARG LIBTASN_VERSION
ENV MY_LIBTASN_VERSION=${LIBTASN_VERSION}
RUN if [ -f "/3rd_party/libtasn1-${MY_LIBTASN_VERSION}.tar.gz" ]; then \
cd /3rd_party && sha256sum -c ./libtasn1-${MY_LIBTASN_VERSION}.tar.gz.sha256 && cd - \
&& tar xvzf /3rd_party/libtasn1-${MY_LIBTASN_VERSION}.tar.gz \
&& cd libtasn1-${MY_LIBTASN_VERSION} \
&& ./configure \
--disable-doc \
--enable-static=yes \
--enable-shared=no \
--host=${MY_MINGW_PREFIX} \
--prefix=${MY_MINGW_DIR} \
&& make -j${MY_NUM_JOBS} \
&& make install \
&& cd ${MY_WORKDIR} \
&& rm -r libtasn1-${MY_LIBTASN_VERSION} \
&& echo -e \
"#!/bin/bash\n"\
"\n"\
"wine ${MY_MINGW_DIR}/bin/asn1Parser.exe \$@\n"\
> ${MY_MINGW_DIR}/bin/asn1Parser \
&& chmod +x ${MY_MINGW_DIR}/bin/asn1Parser \
; fi
ARG LIBICONV_VERSION
ENV MY_LIBICONV_VERSION=${LIBICONV_VERSION}
RUN if [ -f "/3rd_party/libiconv-${MY_LIBICONV_VERSION}.tar.gz" ]; then \
cd /3rd_party && sha256sum -c ./libiconv-${MY_LIBICONV_VERSION}.tar.gz.sha256 && cd - \
&& tar xvzf /3rd_party/libiconv-${MY_LIBICONV_VERSION}.tar.gz \
&& cd libiconv-${MY_LIBICONV_VERSION} \
&& ./configure \
--enable-static=yes \
--enable-shared=no \
--host=${MY_MINGW_PREFIX} \
--prefix=${MY_MINGW_DIR} \
&& make -j${MY_NUM_JOBS} \
&& make install \
&& cd ${MY_WORKDIR} \
&& rm -r libiconv-${MY_LIBICONV_VERSION} \
; fi
ARG LIBDSM_VERSION
ENV MY_LIBDSM_VERSION=${LIBDSM_VERSION}
RUN if [ -f "/3rd_party/libdsm-${MY_LIBDSM_VERSION}.tar.gz" ]; then \
cd /3rd_party && sha256sum -c ./libdsm-${MY_LIBDSM_VERSION}.tar.gz.sha256 && cd - \
&& tar xvzf /3rd_party/libdsm-${MY_LIBDSM_VERSION}.tar.gz \
&& cd libdsm-${MY_LIBDSM_VERSION} \
&& /3rd_party/libdsm_patch.sh /3rd_party . \
&& meson setup \
--bindir=${MY_MINGW_DIR}/bin \
--cross-file ${MY_TOOLCHAIN_FILE_MESON} \
--prefix=${MY_MINGW_DIR} \
-Dbinaries=false \
-Ddefault_library=static \
_build \
&& meson compile \
-C _build \
&& meson install \
-C _build \
&& cd ${MY_WORKDIR} \
&& rm -r libdsm-${MY_LIBDSM_VERSION} \
; fi
RUN (mv ${MY_MINGW_DIR}/lib/*.dll ${MY_MINGW_DIR}/bin || echo "no dll's found") \ RUN (mv ${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

View File

@ -1,15 +1,3 @@
if (NOT PROJECT_STATIC_LINK)
include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/deps/include)
if(PROJECT_IS_MINGW)
link_libraries(msvcr90)
endif()
list(APPEND PROJECT_ADDITIONAL_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/deps/src/backward.cpp
)
endif()
set(CMAKE_CXX_FLAGS "-include common.hpp ${CMAKE_CXX_FLAGS}") set(CMAKE_CXX_FLAGS "-include common.hpp ${CMAKE_CXX_FLAGS}")
add_project_library(lib${PROJECT_NAME} "" "" "${PROJECT_ADDITIONAL_SOURCES}") add_project_library(lib${PROJECT_NAME} "" "" "${PROJECT_ADDITIONAL_SOURCES}")

View File

@ -45,9 +45,6 @@ public:
[[nodiscard]] static auto [[nodiscard]] static auto
default_rpc_port(const provider_type &prov) -> std::uint16_t; default_rpc_port(const provider_type &prov) -> std::uint16_t;
[[nodiscard]] static auto
get_provider_api_password(const provider_type &prov) -> std::string;
[[nodiscard]] static auto [[nodiscard]] static auto
get_provider_display_name(const provider_type &prov) -> std::string; get_provider_display_name(const provider_type &prov) -> std::string;

View File

@ -26,8 +26,7 @@
#include "comm/i_http_comm.hpp" #include "comm/i_http_comm.hpp"
#include "events/event_system.hpp" #include "events/event_system.hpp"
#include "events/events.hpp" #include "events/events.hpp"
#include "utils/encrypt.hpp" #include "utils/encryption.hpp"
#include "utils/utils.hpp"
namespace repertory { namespace repertory {
class curl_comm final : public i_http_comm { class curl_comm final : public i_http_comm {
@ -42,8 +41,8 @@ private:
using write_callback = size_t (*)(char *, size_t, size_t, void *); using write_callback = size_t (*)(char *, size_t, size_t, void *);
struct read_write_info final { struct read_write_info final {
repertory::data_buffer data{}; data_buffer data{};
repertory::stop_type &stop_requested; stop_type &stop_requested;
}; };
static const write_callback write_data; static const write_callback write_data;
@ -56,6 +55,11 @@ private:
private: private:
bool use_s3_path_style_{false}; bool use_s3_path_style_{false};
public:
[[nodiscard]] static auto create_curl() -> CURL *;
[[nodiscard]] static auto reset_curl(CURL *curl_handle) -> CURL *;
public: public:
[[nodiscard]] static auto [[nodiscard]] static auto
construct_url(CURL *curl, const std::string &relative_path, construct_url(CURL *curl, const std::string &relative_path,
@ -92,32 +96,31 @@ public:
const auto key = const auto key =
utils::encryption::generate_key<utils::encryption::hash_256_t>( utils::encryption::generate_key<utils::encryption::hash_256_t>(
request.decryption_token.value()); request.decryption_token.value());
const auto result = utils::encryption::read_encrypted_range( if (not utils::encryption::read_encrypted_range(
request.range.value(), key, request.range.value(), key,
[&](data_buffer &ct, std::uint64_t start_offset, [&](data_buffer &ct, std::uint64_t start_offset,
std::uint64_t end_offset) -> api_error { std::uint64_t end_offset) -> bool {
auto encrypted_request = request; auto encrypted_request = request;
encrypted_request.decryption_token = std::nullopt; encrypted_request.decryption_token = std::nullopt;
encrypted_request.range = {{start_offset, end_offset}}; encrypted_request.range = {{start_offset, end_offset}};
encrypted_request.response_handler = [&ct](const auto &encrypted_data, encrypted_request.response_handler =
long /*response_code*/) { [&ct](const auto &encrypted_data, long /*response_code*/) {
ct = encrypted_data; ct = encrypted_data;
}; };
encrypted_request.total_size = std::nullopt; encrypted_request.total_size = std::nullopt;
if (not make_request(cfg, encrypted_request, response_code, if (not make_request(cfg, encrypted_request, response_code,
stop_requested)) { stop_requested)) {
return api_error::comm_error; return false;
} }
if (response_code != 200) { if (response_code != 200) {
return api_error::comm_error; return false;
} }
return api_error::success; return true;
}, },
request.total_size.value(), data); request.total_size.value(), data)) {
if (result != api_error::success) {
return false; return false;
} }
@ -140,7 +143,7 @@ public:
response_code = 0; response_code = 0;
auto *curl = utils::create_curl(); auto *curl = create_curl();
if (not request.set_method(curl, stop_requested)) { if (not request.set_method(curl, stop_requested)) {
return false; return false;
} }

View File

@ -23,7 +23,7 @@
#define INCLUDE_COMM_CURL_CURL_REQUESTS_HTTP_REQUEST_BASE_HPP_ #define INCLUDE_COMM_CURL_CURL_REQUESTS_HTTP_REQUEST_BASE_HPP_
#include "types/repertory.hpp" #include "types/repertory.hpp"
#include "utils/native_file.hpp" #include "utils/file.hpp"
namespace repertory::curl::requests { namespace repertory::curl::requests {
using read_callback = size_t (*)(char *, size_t, size_t, void *); using read_callback = size_t (*)(char *, size_t, size_t, void *);
@ -33,7 +33,7 @@ using response_callback =
struct read_file_info final { struct read_file_info final {
stop_type &stop_requested; stop_type &stop_requested;
native_file::native_file_ptr nf{}; std::unique_ptr<utils::file::i_file> file{};
std::uint64_t offset{}; std::uint64_t offset{};
}; };
@ -41,9 +41,9 @@ inline const auto read_file_data = static_cast<read_callback>(
[](char *buffer, size_t size, size_t nitems, void *instream) -> size_t { [](char *buffer, size_t size, size_t nitems, void *instream) -> size_t {
auto *read_info = reinterpret_cast<read_file_info *>(instream); auto *read_info = reinterpret_cast<read_file_info *>(instream);
std::size_t bytes_read{}; std::size_t bytes_read{};
auto ret = read_info->nf->read_bytes( auto ret =
reinterpret_cast<unsigned char *>(buffer), size * nitems, read_info->file->read(reinterpret_cast<unsigned char *>(buffer),
read_info->offset, bytes_read); size * nitems, read_info->offset, &bytes_read);
if (ret) { if (ret) {
read_info->offset += bytes_read; read_info->offset += bytes_read;
} }
@ -66,7 +66,7 @@ struct http_request_base {
std::optional<std::string> decryption_token{}; std::optional<std::string> decryption_token{};
http_headers headers{}; http_headers headers{};
std::string path{}; std::string path{};
query_parameters query{}; http_query_parameters query{};
std::optional<http_range> range{}; std::optional<http_range> range{};
std::optional<response_callback> response_handler; std::optional<response_callback> response_handler;
std::optional<http_headers> response_headers; std::optional<http_headers> response_headers;

View File

@ -61,17 +61,7 @@ inline constexpr const std::uint64_t REPERTORY_CONFIG_VERSION = 0ULL;
inline constexpr const std::string_view REPERTORY_DATA_NAME = "repertory2"; inline constexpr const std::string_view REPERTORY_DATA_NAME = "repertory2";
inline constexpr const std::string_view REPERTORY_MIN_REMOTE_VERSION = "2.0.0"; inline constexpr const std::string_view REPERTORY_MIN_REMOTE_VERSION = "2.0.0";
#if defined(_WIN32)
#define REPERTORY_INVALID_HANDLE INVALID_HANDLE_VALUE #define REPERTORY_INVALID_HANDLE INVALID_HANDLE_VALUE
#define REPERTORY_API_INVALID_HANDLE static_cast<std::uint64_t>(-1)
using native_handle = HANDLE;
#else
#define REPERTORY_INVALID_HANDLE (-1)
#define REPERTORY_API_INVALID_HANDLE REPERTORY_INVALID_HANDLE
using native_handle = int;
#endif
inline constexpr const auto NANOS_PER_SECOND = 1000000000L;
#define WINFSP_ALLOCATION_UNIT UINT64(4096U) #define WINFSP_ALLOCATION_UNIT UINT64(4096U)

View File

@ -64,15 +64,15 @@ private:
struct fuse_operations fuse_ops_ {}; struct fuse_operations fuse_ops_ {};
private: private:
[[nodiscard]] auto execute_callback( [[nodiscard]] auto
std::string_view function_name, const char *from, const char *to, execute_callback(std::string_view function_name, const char *from,
const std::function<api_error(const std::string &, const std::string &)> const char *to,
&cb, const std::function<api_error(std::string, std::string)> &cb,
bool disable_logging = false) -> int; bool disable_logging = false) -> int;
[[nodiscard]] auto [[nodiscard]] auto
execute_callback(std::string_view function_name, const char *path, execute_callback(std::string_view function_name, const char *path,
const std::function<api_error(const std::string &)> &cb, const std::function<api_error(std::string)> &cb,
bool disable_logging = false) -> int; bool disable_logging = false) -> int;
static void execute_void_callback(std::string_view function_name, static void execute_void_callback(std::string_view function_name,
@ -83,7 +83,7 @@ private:
const std::function<void *()> &cb) -> void *; const std::function<void *()> &cb) -> void *;
void raise_fuse_event(std::string_view function_name, void raise_fuse_event(std::string_view function_name,
const std::string &api_path, int ret, std::string_view api_path, int ret,
bool disable_logging); bool disable_logging);
private: private:

View File

@ -1269,7 +1269,7 @@ public:
data_buffer buffer(write_size); data_buffer buffer(write_size);
if ((ret = request->decode(buffer.data(), buffer.size())) == 0) { if ((ret = request->decode(buffer.data(), buffer.size())) == 0) {
buffer = macaron::Base64::Decode( buffer = macaron::Base64::Decode(
std::string{buffer.begin(), buffer.end()}); std::string(buffer.begin(), buffer.end()));
write_size = buffer.size(); write_size = buffer.size();
remote::file_offset write_offset{}; remote::file_offset write_offset{};

View File

@ -42,9 +42,9 @@ private:
private: private:
#if defined(_WIN32) #if defined(_WIN32)
#define to_handle(x) (x) #define to_handle(x) (x)
#else #else // !defined(_WIN32)
static auto to_handle(PVOID file_desc) -> native_handle; static auto to_handle(PVOID file_desc) -> native_handle;
#endif #endif // defined(_WIN32)
public: public:
auto json_create_directory_snapshot(const std::string &path, json &json_data) auto json_create_directory_snapshot(const std::string &path, json &json_data)

View File

@ -30,7 +30,7 @@
#include "file_manager/i_upload_manager.hpp" #include "file_manager/i_upload_manager.hpp"
#include "platform/platform.hpp" #include "platform/platform.hpp"
#include "types/repertory.hpp" #include "types/repertory.hpp"
#include "utils/native_file.hpp" #include "utils/file.hpp"
namespace repertory { namespace repertory {
class app_config; class app_config;
@ -131,7 +131,7 @@ public:
std::atomic<std::chrono::system_clock::time_point> last_access_{ std::atomic<std::chrono::system_clock::time_point> last_access_{
std::chrono::system_clock::now()}; std::chrono::system_clock::now()};
bool modified_{false}; bool modified_{false};
native_file_ptr nf_; std::unique_ptr<utils::file::i_file> nf_;
mutable std::mutex io_thread_mtx_; mutable std::mutex io_thread_mtx_;
std::condition_variable io_thread_notify_; std::condition_variable io_thread_notify_;
std::deque<std::shared_ptr<io_item>> io_thread_queue_; std::deque<std::shared_ptr<io_item>> io_thread_queue_;

View File

@ -29,6 +29,9 @@
namespace repertory { namespace repertory {
class encrypt_provider final : public i_provider { class encrypt_provider final : public i_provider {
public:
static const constexpr auto type{provider_type::encrypt};
public: public:
explicit encrypt_provider(app_config &config); explicit encrypt_provider(app_config &config);
@ -70,10 +73,9 @@ private:
const std::string &source_path)> const std::string &source_path)>
callback) const -> api_error; callback) const -> api_error;
auto auto process_directory_entry(const utils::file::i_fs_item &dir_entry,
process_directory_entry(const std::filesystem::directory_entry &dir_entry, const encrypt_config &cfg,
const encrypt_config &cfg, std::string &api_path) const -> bool;
std::string &api_path) const -> bool;
void remove_deleted_files(); void remove_deleted_files();
@ -81,74 +83,68 @@ public:
[[nodiscard]] auto create_directory(const std::string &api_path, [[nodiscard]] auto create_directory(const std::string &api_path,
api_meta_map &meta) -> api_error override; api_meta_map &meta) -> api_error override;
[[nodiscard]] auto [[nodiscard]] auto create_directory_clone_source_meta(
create_directory_clone_source_meta(const std::string & /*source_api_path*/, const std::string & /*source_api_path*/,
const std::string & /*api_path*/) const std::string & /*api_path*/) -> api_error override {
-> api_error override {
return api_error::not_implemented;
}
[[nodiscard]] auto create_file(const std::string & /*api_path*/,
api_meta_map & /*meta*/)
-> api_error override {
return api_error::not_implemented; return api_error::not_implemented;
} }
[[nodiscard]] auto [[nodiscard]] auto
get_api_path_from_source(const std::string & /*source_path*/, create_file(const std::string & /*api_path*/,
std::string & /*api_path*/) const api_meta_map & /*meta*/) -> api_error override {
-> api_error override; return api_error::not_implemented;
}
[[nodiscard]] auto get_api_path_from_source(
const std::string & /*source_path*/,
std::string & /*api_path*/) const -> api_error override;
[[nodiscard]] auto get_directory_item_count(const std::string &api_path) const [[nodiscard]] auto get_directory_item_count(const std::string &api_path) const
-> std::uint64_t override; -> std::uint64_t override;
[[nodiscard]] auto get_directory_items(const std::string &api_path, [[nodiscard]] auto
directory_item_list &list) const get_directory_items(const std::string &api_path,
-> api_error override; directory_item_list &list) const -> api_error override;
[[nodiscard]] auto get_file(const std::string &api_path, api_file &file) const [[nodiscard]] auto get_file(const std::string &api_path,
-> api_error override; api_file &file) const -> api_error override;
[[nodiscard]] auto get_file_list(api_file_list &list) const
-> api_error override;
[[nodiscard]] auto get_file_size(const std::string &api_path,
std::uint64_t &file_size) const
-> api_error override;
[[nodiscard]] auto get_filesystem_item(const std::string &api_path,
bool directory,
filesystem_item &fsi) const
-> api_error override;
[[nodiscard]] auto get_filesystem_item_and_file(const std::string &api_path,
api_file &file,
filesystem_item &fsi) const
-> api_error override;
[[nodiscard]] auto [[nodiscard]] auto
get_filesystem_item_from_source_path(const std::string &source_path, get_file_list(api_file_list &list) const -> api_error override;
filesystem_item &fsi) const
-> api_error override;
[[nodiscard]] auto get_pinned_files() const [[nodiscard]] auto
-> std::vector<std::string> override; get_file_size(const std::string &api_path,
std::uint64_t &file_size) const -> api_error override;
[[nodiscard]] auto get_item_meta(const std::string &api_path, [[nodiscard]] auto
api_meta_map &meta) const get_filesystem_item(const std::string &api_path, bool directory,
-> api_error override; filesystem_item &fsi) const -> api_error override;
[[nodiscard]] auto get_item_meta(const std::string &api_path, [[nodiscard]] auto get_filesystem_item_and_file(
const std::string &key, const std::string &api_path, api_file &file,
std::string &value) const filesystem_item &fsi) const -> api_error override;
-> api_error override;
[[nodiscard]] auto get_filesystem_item_from_source_path(
const std::string &source_path,
filesystem_item &fsi) const -> api_error override;
[[nodiscard]] auto
get_pinned_files() const -> std::vector<std::string> override;
[[nodiscard]] auto
get_item_meta(const std::string &api_path,
api_meta_map &meta) const -> api_error override;
[[nodiscard]] auto
get_item_meta(const std::string &api_path, const std::string &key,
std::string &value) const -> api_error override;
[[nodiscard]] auto get_total_drive_space() const -> std::uint64_t override; [[nodiscard]] auto get_total_drive_space() const -> std::uint64_t override;
[[nodiscard]] auto get_total_item_count() const -> std::uint64_t override; [[nodiscard]] auto get_total_item_count() const -> std::uint64_t override;
[[nodiscard]] auto get_provider_type() const -> provider_type override { [[nodiscard]] auto get_provider_type() const -> provider_type override {
return provider_type::encrypt; return type;
} }
[[nodiscard]] auto get_used_drive_space() const -> std::uint64_t override; [[nodiscard]] auto get_used_drive_space() const -> std::uint64_t override;
@ -158,54 +154,52 @@ public:
[[nodiscard]] auto is_directory(const std::string &api_path, [[nodiscard]] auto is_directory(const std::string &api_path,
bool &exists) const -> api_error override; bool &exists) const -> api_error override;
[[nodiscard]] auto is_file(const std::string &api_path, bool &exists) const [[nodiscard]] auto is_file(const std::string &api_path,
-> api_error override; bool &exists) const -> api_error override;
[[nodiscard]] auto is_file_writeable(const std::string &api_path) const [[nodiscard]] auto
-> bool override; is_file_writeable(const std::string &api_path) const -> bool override;
[[nodiscard]] auto is_online() const -> bool override; [[nodiscard]] auto is_online() const -> bool override;
[[nodiscard]] auto is_rename_supported() const -> bool override; [[nodiscard]] auto is_rename_supported() const -> bool override;
[[nodiscard]] auto read_file_bytes(const std::string &api_path, [[nodiscard]] auto
std::size_t size, std::uint64_t offset, read_file_bytes(const std::string &api_path, std::size_t size,
data_buffer &data, std::uint64_t offset, data_buffer &data,
stop_type &stop_requested) stop_type &stop_requested) -> api_error override;
-> api_error override;
[[nodiscard]] auto remove_directory(const std::string & /*api_path*/) [[nodiscard]] auto
-> api_error override { remove_directory(const std::string & /*api_path*/) -> api_error override {
return api_error::not_implemented; return api_error::not_implemented;
} }
[[nodiscard]] auto remove_file(const std::string & /*api_path*/) [[nodiscard]] auto
-> api_error override { remove_file(const std::string & /*api_path*/) -> api_error override {
return api_error::not_implemented; return api_error::not_implemented;
} }
[[nodiscard]] auto remove_item_meta(const std::string & /*api_path*/, [[nodiscard]] auto
const std::string & /*key*/) remove_item_meta(const std::string & /*api_path*/,
-> api_error override { const std::string & /*key*/) -> api_error override {
return api_error::success; return api_error::success;
} }
[[nodiscard]] auto rename_file(const std::string & /*from_api_path*/, [[nodiscard]] auto
const std::string & /*to_api_path*/) rename_file(const std::string & /*from_api_path*/,
-> api_error override { const std::string & /*to_api_path*/) -> api_error override {
return api_error::not_implemented; return api_error::not_implemented;
} }
[[nodiscard]] auto set_item_meta(const std::string & /*api_path*/, [[nodiscard]] auto
const std::string & /*key*/, set_item_meta(const std::string & /*api_path*/, const std::string & /*key*/,
const std::string & /*value*/) const std::string & /*value*/) -> api_error override {
-> api_error override {
return api_error::success; return api_error::success;
} }
[[nodiscard]] auto set_item_meta(const std::string & /*api_path*/, [[nodiscard]] auto
const api_meta_map & /*meta*/) set_item_meta(const std::string & /*api_path*/,
-> api_error override { const api_meta_map & /*meta*/) -> api_error override {
return api_error::success; return api_error::success;
} }
@ -214,10 +208,10 @@ public:
void stop() override; void stop() override;
[[nodiscard]] auto upload_file(const std::string & /*api_path*/, [[nodiscard]] auto
const std::string & /*source_path*/, upload_file(const std::string & /*api_path*/,
stop_type & /*stop_requested*/) const std::string & /*source_path*/,
-> api_error override { stop_type & /*stop_requested*/) -> api_error override {
return api_error::not_implemented; return api_error::not_implemented;
} }
}; };

View File

@ -32,6 +32,9 @@ class i_http_comm;
struct head_object_result; struct head_object_result;
class s3_provider final : public base_provider { class s3_provider final : public base_provider {
public:
static const constexpr auto type{provider_type::s3};
public: public:
s3_provider(app_config &config, i_http_comm &comm); s3_provider(app_config &config, i_http_comm &comm);
@ -92,6 +95,9 @@ protected:
stop_type &stop_requested) -> api_error override; stop_type &stop_requested) -> api_error override;
public: public:
[[nodiscard]] static auto
convert_api_date(std::string_view date) -> std::uint64_t;
[[nodiscard]] auto get_directory_item_count(const std::string &api_path) const [[nodiscard]] auto get_directory_item_count(const std::string &api_path) const
-> std::uint64_t override; -> std::uint64_t override;
@ -104,7 +110,7 @@ public:
[[nodiscard]] auto get_total_drive_space() const -> std::uint64_t override; [[nodiscard]] auto get_total_drive_space() const -> std::uint64_t override;
[[nodiscard]] auto get_provider_type() const -> provider_type override { [[nodiscard]] auto get_provider_type() const -> provider_type override {
return provider_type::s3; return type;
} }
[[nodiscard]] auto is_direct_only() const -> bool override { return false; } [[nodiscard]] auto is_direct_only() const -> bool override { return false; }

View File

@ -31,6 +31,9 @@ class i_file_manager;
class i_http_comm; class i_http_comm;
class sia_provider : public base_provider { class sia_provider : public base_provider {
public:
static const constexpr auto type{provider_type::sia};
public: public:
sia_provider(app_config &config, i_http_comm &comm); sia_provider(app_config &config, i_http_comm &comm);
@ -50,40 +53,39 @@ private:
nlohmann::json &object_list) const -> bool; nlohmann::json &object_list) const -> bool;
protected: protected:
[[nodiscard]] auto create_directory_impl(const std::string &api_path, [[nodiscard]] auto
api_meta_map &meta) create_directory_impl(const std::string &api_path,
-> api_error override; api_meta_map &meta) -> api_error override;
[[nodiscard]] auto get_directory_items_impl(const std::string &api_path, [[nodiscard]] auto get_directory_items_impl(const std::string &api_path,
directory_item_list &list) const directory_item_list &list) const
-> api_error override; -> api_error override;
[[nodiscard]] auto get_used_drive_space_impl() const [[nodiscard]] auto
-> std::uint64_t override; get_used_drive_space_impl() const -> std::uint64_t override;
[[nodiscard]] auto remove_directory_impl(const std::string &api_path) [[nodiscard]] auto
-> api_error override; remove_directory_impl(const std::string &api_path) -> api_error override;
[[nodiscard]] auto remove_file_impl(const std::string &api_path) [[nodiscard]] auto
-> api_error override; remove_file_impl(const std::string &api_path) -> api_error override;
[[nodiscard]] auto upload_file_impl(const std::string &api_path, [[nodiscard]] auto
const std::string &source_path, upload_file_impl(const std::string &api_path, const std::string &source_path,
stop_type &stop_requested) stop_type &stop_requested) -> api_error override;
-> api_error override;
public: public:
[[nodiscard]] auto get_directory_item_count(const std::string &api_path) const [[nodiscard]] auto get_directory_item_count(const std::string &api_path) const
-> std::uint64_t override; -> std::uint64_t override;
[[nodiscard]] auto get_file(const std::string &api_path, api_file &file) const [[nodiscard]] auto get_file(const std::string &api_path,
-> api_error override; api_file &file) const -> api_error override;
[[nodiscard]] auto get_file_list(api_file_list &list) const [[nodiscard]] auto
-> api_error override; get_file_list(api_file_list &list) const -> api_error override;
[[nodiscard]] auto get_provider_type() const -> provider_type override { [[nodiscard]] auto get_provider_type() const -> provider_type override {
return provider_type::sia; return type;
} }
[[nodiscard]] auto get_total_drive_space() const -> std::uint64_t override; [[nodiscard]] auto get_total_drive_space() const -> std::uint64_t override;
@ -93,8 +95,8 @@ public:
[[nodiscard]] auto is_directory(const std::string &api_path, [[nodiscard]] auto is_directory(const std::string &api_path,
bool &exists) const -> api_error override; bool &exists) const -> api_error override;
[[nodiscard]] auto is_file(const std::string &api_path, bool &exists) const [[nodiscard]] auto is_file(const std::string &api_path,
-> api_error override; bool &exists) const -> api_error override;
[[nodiscard]] auto is_online() const -> bool override; [[nodiscard]] auto is_online() const -> bool override;
@ -102,15 +104,14 @@ public:
return true; return true;
} }
[[nodiscard]] auto read_file_bytes(const std::string &api_path, [[nodiscard]] auto
std::size_t size, std::uint64_t offset, read_file_bytes(const std::string &api_path, std::size_t size,
data_buffer &buffer, std::uint64_t offset, data_buffer &buffer,
stop_type &stop_requested) stop_type &stop_requested) -> api_error override;
-> api_error override;
[[nodiscard]] auto rename_file(const std::string &from_api_path, [[nodiscard]] auto
const std::string &to_api_path) rename_file(const std::string &from_api_path,
-> api_error override; const std::string &to_api_path) -> api_error override;
[[nodiscard]] auto start(api_item_added_callback api_item_added, [[nodiscard]] auto start(api_item_added_callback api_item_added,
i_file_manager *mgr) -> bool override; i_file_manager *mgr) -> bool override;

View File

@ -22,14 +22,14 @@
#ifndef INCLUDE_TYPES_REMOTE_HPP_ #ifndef INCLUDE_TYPES_REMOTE_HPP_
#define INCLUDE_TYPES_REMOTE_HPP_ #define INCLUDE_TYPES_REMOTE_HPP_
#define PACKET_SERVICE_FUSE 1U inline constexpr const auto PACKET_SERVICE_FUSE{1U};
#define PACKET_SERVICE_WINFSP 2U inline constexpr const auto PACKET_SERVICE_WINFSP{2U};
#if defined(_WIN32) #if defined(_WIN32)
#define PACKET_SERVICE_FLAGS PACKET_SERVICE_WINFSP inline constexpr const auto PACKET_SERVICE_FLAGS{PACKET_SERVICE_WINFSP};
#else #else // !defined(_WIN32)
#define PACKET_SERVICE_FLAGS PACKET_SERVICE_FUSE inline constexpr const auto PACKET_SERVICE_FLAGS{PACKET_SERVICE_FUSE};
#endif #endif // defined(_WIN32)
namespace repertory::remote { namespace repertory::remote {
using block_count = std::uint64_t; using block_count = std::uint64_t;
@ -65,16 +65,19 @@ enum class open_flags : std::uint32_t {
dsync = 131072U, dsync = 131072U,
}; };
inline auto operator|(const open_flags &flag_1, #if defined(__GNUG__)
const open_flags &flag_2) -> open_flags { __attribute__((unused))
using t = std::underlying_type_t<open_flags>; #endif // defined(__GNUG__)
return static_cast<open_flags>(static_cast<t>(flag_1) | inline auto
static_cast<t>(flag_2)); operator|(const open_flags &flag_1, const open_flags &flag_2) -> open_flags {
using flag_t = std::underlying_type_t<open_flags>;
return static_cast<open_flags>(static_cast<flag_t>(flag_1) |
static_cast<flag_t>(flag_2));
} }
#if defined(__GNUG__) #if defined(__GNUG__)
__attribute__((unused)) __attribute__((unused))
#endif #endif // defined(__GNUG__)
inline auto inline auto
operator|=(open_flags &flag_1, const open_flags &flag_2) -> open_flags & { operator|=(open_flags &flag_1, const open_flags &flag_2) -> open_flags & {
flag_1 = flag_1 | flag_2; flag_1 = flag_1 | flag_2;
@ -83,69 +86,69 @@ operator|=(open_flags &flag_1, const open_flags &flag_2) -> open_flags & {
#if defined(__GNUG__) #if defined(__GNUG__)
__attribute__((unused)) __attribute__((unused))
#endif #endif // defined(__GNUG__)
inline auto inline auto
operator&(const open_flags &flag_1, const open_flags &flag_2) -> open_flags { operator&(const open_flags &flag_1, const open_flags &flag_2) -> open_flags {
using t = std::underlying_type_t<open_flags>; using flag_t = std::underlying_type_t<open_flags>;
return static_cast<open_flags>(static_cast<t>(flag_1) & return static_cast<open_flags>(static_cast<flag_t>(flag_1) &
static_cast<t>(flag_2)); static_cast<flag_t>(flag_2));
} }
#pragma pack(1) #pragma pack(1)
struct file_info { struct file_info final {
UINT32 FileAttributes; UINT32 FileAttributes{};
UINT32 ReparseTag; UINT32 ReparseTag{};
UINT64 AllocationSize; UINT64 AllocationSize{};
UINT64 FileSize; UINT64 FileSize{};
UINT64 CreationTime; UINT64 CreationTime{};
UINT64 LastAccessTime; UINT64 LastAccessTime{};
UINT64 LastWriteTime; UINT64 LastWriteTime{};
UINT64 ChangeTime; UINT64 ChangeTime{};
UINT64 IndexNumber; UINT64 IndexNumber{};
UINT32 HardLinks; UINT32 HardLinks{};
UINT32 EaSize; UINT32 EaSize{};
}; };
struct setattr_x { struct setattr_x final {
std::int32_t valid; std::int32_t valid{};
file_mode mode; file_mode mode{};
user_id uid; user_id uid{};
group_id gid; group_id gid{};
file_size size; file_size size{};
file_time acctime; file_time acctime{};
file_time modtime; file_time modtime{};
file_time crtime; file_time crtime{};
file_time chgtime; file_time chgtime{};
file_time bkuptime; file_time bkuptime{};
std::uint32_t flags; std::uint32_t flags{};
}; };
struct stat { struct stat final {
file_mode st_mode; file_mode st_mode{};
file_nlink st_nlink; file_nlink st_nlink{};
user_id st_uid; user_id st_uid{};
group_id st_gid; group_id st_gid{};
file_time st_atimespec; file_time st_atimespec{};
file_time st_mtimespec; file_time st_mtimespec{};
file_time st_ctimespec; file_time st_ctimespec{};
file_time st_birthtimespec; file_time st_birthtimespec{};
file_size st_size; file_size st_size{};
block_count st_blocks; block_count st_blocks{};
block_size st_blksize; block_size st_blksize{};
std::uint32_t st_flags; std::uint32_t st_flags{};
}; };
struct statfs { struct statfs {
std::uint64_t f_bavail; std::uint64_t f_bavail{};
std::uint64_t f_bfree; std::uint64_t f_bfree{};
std::uint64_t f_blocks; std::uint64_t f_blocks{};
std::uint64_t f_favail; std::uint64_t f_favail{};
std::uint64_t f_ffree; std::uint64_t f_ffree{};
std::uint64_t f_files; std::uint64_t f_files{};
}; };
struct statfs_x : public statfs { struct statfs_x final : public statfs {
char f_mntfromname[1024]; std::array<char, 1024U> f_mntfromname{};
}; };
#pragma pack() #pragma pack()
@ -154,7 +157,7 @@ struct statfs_x : public statfs {
[[nodiscard]] auto [[nodiscard]] auto
create_os_open_flags(const open_flags &flags) -> std::uint32_t; create_os_open_flags(const open_flags &flags) -> std::uint32_t;
#endif #endif // !defined(_WIN32)
} // namespace repertory::remote } // namespace repertory::remote
#endif // INCLUDE_TYPES_REMOTE_HPP_ #endif // INCLUDE_TYPES_REMOTE_HPP_

View File

@ -23,26 +23,26 @@
#define INCLUDE_TYPES_REPERTORY_HPP_ #define INCLUDE_TYPES_REPERTORY_HPP_
namespace repertory { namespace repertory {
constexpr const auto max_time = 0xFFFFFFFFFFFFFFFFULL; inline constexpr const auto max_time{std::numeric_limits<std::uint64_t>::max()};
const std::string META_ACCESSED = "accessed"; inline constexpr const std::string META_ACCESSED{"accessed"};
const std::string META_ATTRIBUTES = "attributes"; inline constexpr const std::string META_ATTRIBUTES{"attributes"};
const std::string META_BACKUP = "backup"; inline constexpr const std::string META_BACKUP{"backup"};
const std::string META_CHANGED = "changed"; inline constexpr const std::string META_CHANGED{"changed"};
const std::string META_CREATION = "creation"; inline constexpr const std::string META_CREATION{"creation"};
const std::string META_DIRECTORY = "directory"; inline constexpr const std::string META_DIRECTORY{"directory"};
const std::string META_GID = "gid"; inline constexpr const std::string META_GID{"gid"};
const std::string META_KEY = "key"; inline constexpr const std::string META_KEY{"key"};
const std::string META_MODE = "mode"; inline constexpr const std::string META_MODE{"mode"};
const std::string META_MODIFIED = "modified"; inline constexpr const std::string META_MODIFIED{"modified"};
const std::string META_OSXFLAGS = "flags"; inline constexpr const std::string META_OSXFLAGS{"flags"};
const std::string META_PINNED = "pinned"; inline constexpr const std::string META_PINNED{"pinned"};
const std::string META_SIZE = "size"; inline constexpr const std::string META_SIZE{"size"};
const std::string META_SOURCE = "source"; inline constexpr const std::string META_SOURCE{"source"};
const std::string META_UID = "uid"; inline constexpr const std::string META_UID{"uid"};
const std::string META_WRITTEN = "written"; inline constexpr const std::string META_WRITTEN{"written"};
const std::vector<std::string> META_USED_NAMES = { inline constexpr const std::array<std::string, 16U> META_USED_NAMES = {
META_ACCESSED, META_ATTRIBUTES, META_BACKUP, META_CHANGED, META_ACCESSED, META_ATTRIBUTES, META_BACKUP, META_CHANGED,
META_CREATION, META_DIRECTORY, META_GID, META_KEY, META_CREATION, META_DIRECTORY, META_GID, META_KEY,
META_MODE, META_MODIFIED, META_OSXFLAGS, META_PINNED, META_MODE, META_MODIFIED, META_OSXFLAGS, META_PINNED,
@ -51,8 +51,6 @@ const std::vector<std::string> META_USED_NAMES = {
using api_meta_map = std::map<std::string, std::string>; using api_meta_map = std::map<std::string, std::string>;
using stop_type = std::atomic<bool>;
enum class api_error { enum class api_error {
success = 0, success = 0,
access_denied, access_denied,
@ -152,28 +150,28 @@ enum class provider_type : std::size_t {
}; };
#if defined(_WIN32) #if defined(_WIN32)
struct open_file_data { struct open_file_data final {
void *directory_buffer{}; void *directory_buffer{};
}; };
#else #else
using open_file_data = int; using open_file_data = int;
#endif #endif
struct api_file { struct api_file final {
std::string api_path; std::string api_path{};
std::string api_parent; std::string api_parent{};
std::uint64_t accessed_date{}; std::uint64_t accessed_date{};
std::uint64_t changed_date{}; std::uint64_t changed_date{};
std::uint64_t creation_date{}; std::uint64_t creation_date{};
std::uint64_t file_size{}; std::uint64_t file_size{};
std::string key; std::string key{};
std::uint64_t modified_date{}; std::uint64_t modified_date{};
std::string source_path; std::string source_path;
}; };
struct directory_item { struct directory_item final {
std::string api_path; std::string api_path{};
std::string api_parent; std::string api_parent{};
bool directory{false}; bool directory{false};
std::uint64_t size{}; std::uint64_t size{};
api_meta_map meta{}; api_meta_map meta{};
@ -190,26 +188,30 @@ struct directory_item {
} }
[[nodiscard]] auto to_json() const -> json { [[nodiscard]] auto to_json() const -> json {
return {{"path", api_path}, return {
{"parent", api_parent}, {"path", api_path}, {"parent", api_parent}, {"size", size},
{"size", size}, {"directory", directory}, {"meta", meta},
{"directory", directory}, };
{"meta", meta}};
} }
}; };
struct filesystem_item { struct encrypt_config final {
std::string api_path; std::string encryption_token{};
std::string api_parent; std::string path{};
bool directory{false};
std::uint64_t size{};
std::string source_path;
}; };
struct host_config { struct filesystem_item final {
std::string agent_string; std::string api_path{};
std::string api_password; std::string api_parent{};
std::string api_user; bool directory{false};
std::uint64_t size{};
std::string source_path{};
};
struct host_config final {
std::string agent_string{};
std::string api_password{};
std::string api_user{};
std::uint16_t api_port{}; std::uint16_t api_port{};
std::string host_name_or_ip{"localhost"}; std::string host_name_or_ip{"localhost"};
std::string path{}; std::string path{};
@ -265,25 +267,15 @@ from_json(const json &j, host_config &hc) {
j.at("TimeoutMs").get_to(hc.timeout_ms); j.at("TimeoutMs").get_to(hc.timeout_ms);
} }
struct http_range { struct s3_config final {
std::uint64_t begin; std::string access_key{};
std::uint64_t end; std::string bucket{};
};
struct encrypt_config {
std::string encryption_token;
std::string path;
};
struct s3_config {
std::string access_key;
std::string bucket;
std::uint16_t cache_timeout_secs{60U}; std::uint16_t cache_timeout_secs{60U};
std::string encryption_token; std::string encryption_token{};
std::string region{"any"}; std::string region{"any"};
std::string secret_key; std::string secret_key{};
std::uint32_t timeout_ms{60000U}; std::uint32_t timeout_ms{60000U};
std::string url; std::string url{};
bool use_path_style{false}; bool use_path_style{false};
bool use_region_in_url{false}; bool use_region_in_url{false};
}; };
@ -292,11 +284,7 @@ using api_file_list = std::vector<api_file>;
using api_file_provider_callback = std::function<void(api_file &)>; using api_file_provider_callback = std::function<void(api_file &)>;
using api_item_added_callback = std::function<api_error(bool, api_file &)>; using api_item_added_callback = std::function<api_error(bool, api_file &)>;
using directory_item_list = std::vector<directory_item>; using directory_item_list = std::vector<directory_item>;
using http_headers = std::unordered_map<std::string, std::string>;
using http_parameters = std::unordered_map<std::string, std::string>;
using http_ranges = std::vector<http_range>;
using meta_provider_callback = std::function<void(directory_item &)>; using meta_provider_callback = std::function<void(directory_item &)>;
using query_parameters = std::map<std::string, std::string>;
} // namespace repertory } // namespace repertory
#endif // INCLUDE_TYPES_REPERTORY_HPP_ #endif // INCLUDE_TYPES_REPERTORY_HPP_

View File

@ -79,8 +79,8 @@ struct head_object_result {
#else #else
strptime(date.c_str(), "%a, %d %b %Y %H:%M:%S %Z", &tm1); strptime(date.c_str(), "%a, %d %b %Y %H:%M:%S %Z", &tm1);
#endif #endif
last_modified = last_modified = static_cast<std::uint64_t>(mktime(&tm1)) *
static_cast<std::uint64_t>(mktime(&tm1)) * NANOS_PER_SECOND; utils::time::NANOS_PER_SECOND;
} }
return *this; return *this;
} }

View File

@ -22,64 +22,17 @@
#ifndef INCLUDE_UTILS_FILE_UTILS_HPP_ #ifndef INCLUDE_UTILS_FILE_UTILS_HPP_
#define INCLUDE_UTILS_FILE_UTILS_HPP_ #define INCLUDE_UTILS_FILE_UTILS_HPP_
#include "types/repertory.hpp"
#include "utils/file.hpp" #include "utils/file.hpp"
#include "utils/native_file.hpp"
namespace repertory::utils::file { namespace repertory::utils::file {
// Prototypes
[[nodiscard]] auto calculate_used_space(std::string path,
bool recursive) -> std::uint64_t;
void change_to_process_directory();
[[nodiscard]] auto copy_directory_recursively(std::string from_path,
std::string to_path) -> bool;
[[nodiscard]] auto copy_file(std::string from_path,
std::string to_path) -> bool;
[[nodiscard]] auto create_full_directory_path(std::string path) -> bool;
[[nodiscard]] auto delete_directory(std::string path,
bool recursive = false) -> bool;
[[nodiscard]] auto delete_directory_recursively(std::string path) -> bool;
[[nodiscard]] auto delete_file(std::string path) -> bool;
[[nodiscard]] auto generate_sha256(const std::string &file_path) -> std::string;
[[nodiscard]] auto get_accessed_time(const std::string &path,
std::uint64_t &accessed) -> bool;
[[nodiscard]] auto [[nodiscard]] auto
get_directory_files(std::string path, bool oldest_first, get_directory_files(std::string_view path, bool oldest_first,
bool recursive = false) -> std::deque<std::string>; bool recursive = false) -> std::deque<std::string>;
[[nodiscard]] auto
get_free_drive_space(const std::string &path) -> std::uint64_t;
[[nodiscard]] auto
get_total_drive_space(const std::string &path) -> std::uint64_t;
[[nodiscard]] auto get_modified_time(const std::string &path,
std::uint64_t &modified) -> bool;
[[nodiscard]] auto
is_modified_date_older_than(const std::string &path,
const std::chrono::hours &hours) -> bool;
[[nodiscard]] auto move_file(std::string from, std::string to) -> bool;
[[nodiscard]] auto [[nodiscard]] auto
read_file_lines(const std::string &path) -> std::vector<std::string>; read_file_lines(const std::string &path) -> std::vector<std::string>;
[[nodiscard]] auto reset_modified_time(const std::string &path) -> bool; [[nodiscard]] auto reset_modified_time(const std::string &path) -> bool;
[[nodiscard]] auto retry_delete_directory(const std::string &dir) -> bool;
[[nodiscard]] auto retry_delete_file(const std::string &file) -> bool;
} // namespace repertory::utils::file } // namespace repertory::utils::file
#endif // INCLUDE_UTILS_FILE_UTILS_HPP_ #endif // INCLUDE_UTILS_FILE_UTILS_HPP_

View File

@ -1,117 +0,0 @@
/*
Copyright <2018-2024> <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 INCLUDE_UTILS_NATIVEFILE_HPP_
#define INCLUDE_UTILS_NATIVEFILE_HPP_
#include "types/repertory.hpp"
namespace repertory {
class native_file final {
public:
native_file(const native_file &) = delete;
native_file(native_file &&) = delete;
auto operator=(const native_file &) -> native_file & = delete;
auto operator=(native_file &&) -> native_file & = delete;
using native_file_ptr = std::shared_ptr<native_file>;
public:
[[nodiscard]] static auto attach(native_handle handle) -> native_file_ptr {
return std::shared_ptr<native_file>(new native_file(handle));
}
[[nodiscard]] static auto
clone(const native_file_ptr &ptr) -> native_file_ptr;
[[nodiscard]] static auto create_or_open(std::string_view source_path,
bool read_only,
native_file_ptr &ptr) -> api_error;
[[nodiscard]] static auto create_or_open(std::string_view source_path,
native_file_ptr &ptr) -> api_error;
[[nodiscard]] static auto open(std::string_view source_path,
native_file_ptr &ptr) -> api_error;
[[nodiscard]] static auto open(std::string_view source_path, bool read_only,
native_file_ptr &ptr) -> api_error;
private:
explicit native_file(const native_handle &handle) : handle_(handle) {}
public:
~native_file();
private:
native_handle handle_;
private:
bool auto_close{false};
#if defined(_WIN32)
std::recursive_mutex read_write_mutex_;
#endif
public:
[[nodiscard]] auto allocate(std::uint64_t file_size) -> bool;
void close();
[[nodiscard]] auto copy_from(const native_file_ptr &ptr) -> bool;
[[nodiscard]] auto copy_from(const std::string &path) -> bool;
void flush();
[[nodiscard]] auto get_file_size(std::uint64_t &file_size) -> bool;
[[nodiscard]] auto get_handle() -> native_handle;
#if defined(_WIN32)
[[nodiscard]] auto read_bytes(unsigned char *buffer, std::size_t read_size,
std::uint64_t read_offset,
std::size_t &bytes_read) -> bool;
#else
[[nodiscard]] auto read_bytes(unsigned char *buffer, std::size_t read_size,
std::uint64_t read_offset,
std::size_t &bytes_read) -> bool;
#endif
void set_auto_close(bool b) { auto_close = b; }
[[nodiscard]] auto truncate(std::uint64_t file_size) -> bool;
#if defined(_WIN32)
[[nodiscard]] auto write_bytes(const unsigned char *buffer,
std::size_t write_size,
std::uint64_t write_offset,
std::size_t &bytes_written) -> bool;
#else
[[nodiscard]] auto write_bytes(const unsigned char *buffer,
std::size_t write_size,
std::uint64_t write_offset,
std::size_t &bytes_written) -> bool;
#endif
};
using native_file_ptr = native_file::native_file_ptr;
} // namespace repertory
#endif // INCLUDE_UTILS_NATIVEFILE_HPP_

View File

@ -43,15 +43,9 @@ inline const std::array<std::string, 4U> attribute_namespaces = {
[[nodiscard]] auto unix_error_to_windows(int err) -> std::uint32_t; [[nodiscard]] auto unix_error_to_windows(int err) -> std::uint32_t;
[[nodiscard]] auto
unix_time_to_windows_time(const remote::file_time &file_time) -> UINT64;
void windows_create_to_unix(const UINT32 &create_options, void windows_create_to_unix(const UINT32 &create_options,
const UINT32 &granted_access, std::uint32_t &flags, const UINT32 &granted_access, std::uint32_t &flags,
remote::file_mode &mode); remote::file_mode &mode);
[[nodiscard]] auto
windows_time_to_unix_time(std::uint64_t win_time) -> remote::file_time;
} // namespace repertory::utils } // namespace repertory::utils
#endif // !_WIN32 #endif // !_WIN32

View File

@ -29,27 +29,10 @@ void calculate_allocation_size(bool directory, std::uint64_t file_size,
UINT64 allocation_size, UINT64 allocation_size,
std::string &allocation_meta_size); std::string &allocation_meta_size);
[[nodiscard]] auto convert_api_date(const std::string &date) -> std::uint64_t;
[[nodiscard]] auto create_curl() -> CURL *;
[[nodiscard]] auto [[nodiscard]] auto
create_volume_label(const provider_type &prov) -> std::string; create_volume_label(const provider_type &prov) -> std::string;
[[nodiscard]] auto get_attributes_from_meta(const api_meta_map &meta) -> DWORD; [[nodiscard]] auto get_attributes_from_meta(const api_meta_map &meta) -> DWORD;
[[nodiscard]] auto reset_curl(CURL *curl_handle) -> CURL *;
[[nodiscard]] auto
retryable_action(const std::function<bool()> &action) -> bool;
void spin_wait_for_mutex(std::function<bool()> complete,
std::condition_variable &cond, std::mutex &mtx,
const std::string &text = "");
void spin_wait_for_mutex(bool &complete, std::condition_variable &cond,
std::mutex &mtx, const std::string &text = "");
} // namespace repertory::utils } // namespace repertory::utils
#endif // INCLUDE_UTILS_UTILS_HPP_ #endif // INCLUDE_UTILS_UTILS_HPP_

View File

@ -100,18 +100,17 @@ app_config::app_config(const provider_type &prov,
log_directory_ = utils::path::combine(data_directory_, {"logs"}); log_directory_ = utils::path::combine(data_directory_, {"logs"});
hc_.agent_string = default_agent_name(prov_); hc_.agent_string = default_agent_name(prov_);
hc_.api_password = get_provider_api_password(prov_);
hc_.api_port = default_api_port(prov_); hc_.api_port = default_api_port(prov_);
if (not utils::file::create_full_directory_path(data_directory_)) { if (not utils::file::directory(data_directory_).create_directory()) {
throw startup_exception("unable to create: " + data_directory_); throw startup_exception("unable to create: " + data_directory_);
} }
if (not utils::file::create_full_directory_path(cache_directory_)) { if (not utils::file::directory(cache_directory_).create_directory()) {
throw startup_exception("unable to create: " + cache_directory_); throw startup_exception("unable to create: " + cache_directory_);
} }
if (not utils::file::create_full_directory_path(log_directory_)) { if (not utils::file::directory(log_directory_).create_directory()) {
throw startup_exception("unable to create: " + log_directory_); throw startup_exception("unable to create: " + log_directory_);
} }
@ -318,39 +317,12 @@ auto app_config::get_json() const -> json {
} }
auto app_config::get_max_cache_size_bytes() const -> std::uint64_t { auto app_config::get_max_cache_size_bytes() const -> std::uint64_t {
const auto max_space = auto max_space =
std::max(static_cast<std::uint64_t>(100ULL * 1024ULL * 1024ULL), std::max(static_cast<std::uint64_t>(100ULL * 1024ULL * 1024ULL),
max_cache_size_bytes_); max_cache_size_bytes_);
return std::min(utils::file::get_free_drive_space(get_cache_directory()), auto free_space = utils::file::get_free_drive_space(get_cache_directory());
max_space); return free_space.has_value() ? std::min(free_space.value(), max_space)
} : max_space;
auto app_config::get_provider_api_password(const provider_type &prov)
-> std::string {
#if defined(_WIN32)
auto api_file = utils::path::combine(utils::get_local_app_data_directory(),
{
get_provider_display_name(prov),
"apipassword",
});
#else
#if defined(__APPLE__)
auto api_file = utils::path::combine("~", {
"/",
"Library",
"Application Support",
get_provider_display_name(prov),
"apipassword",
});
#else
auto api_file = utils::path::combine("~/.", {
get_provider_name(prov),
"apipassword",
});
#endif
#endif
auto lines = utils::file::read_file_lines(api_file);
return lines.empty() ? "" : utils::string::trim(lines[0U]);
} }
auto app_config::get_provider_display_name(const provider_type &prov) auto app_config::get_provider_display_name(const provider_type &prov)
@ -542,12 +514,11 @@ auto app_config::load() -> bool {
static_cast<const char *>(__FUNCTION__), static_cast<const char *>(__FUNCTION__),
}; };
auto ret = false; auto ret{false};
const auto config_file_path = get_config_file_path(); const auto config_file_path = get_config_file_path();
std::cout << config_file_path << std::endl;
recur_mutex_lock lock(read_write_mutex_); recur_mutex_lock lock(read_write_mutex_);
if (utils::file::is_file(config_file_path)) { if (utils::file::file(config_file_path).exists()) {
try { try {
std::ifstream config_file(config_file_path.data()); std::ifstream config_file(config_file_path.data());
if (config_file.is_open()) { if (config_file.is_open()) {
@ -606,13 +577,6 @@ auto app_config::load() -> bool {
ret = false; ret = false;
} }
if (hc_.api_password.empty()) {
hc_.api_password = get_provider_api_password(prov_);
if (hc_.api_password.empty()) {
ret = false;
}
}
if (json_document.find("S3Config") != json_document.end()) { if (json_document.find("S3Config") != json_document.end()) {
auto s3_config_json = json_document["S3Config"]; auto s3_config_json = json_document["S3Config"];
auto s3_cfg = s3_config_; auto s3_cfg = s3_config_;
@ -713,9 +677,9 @@ void app_config::save() {
const auto file_path = get_config_file_path(); const auto file_path = get_config_file_path();
recur_mutex_lock lock(read_write_mutex_); recur_mutex_lock lock(read_write_mutex_);
if (config_changed_ || not utils::file::is_file(file_path)) { if (config_changed_ || not utils::file::file(file_path).exists()) {
if (not utils::file::is_directory(data_directory_)) { if (not utils::file::directory(data_directory_).exists()) {
if (not utils::file::create_full_directory_path(data_directory_)) { if (not utils::file::directory{data_directory_}.create_directory()) {
utils::error::raise_error( utils::error::raise_error(
function_name, "failed to create directory|sp|" + data_directory_ + function_name, "failed to create directory|sp|" + data_directory_ +
"|err|" + "|err|" +

View File

@ -92,6 +92,16 @@ auto curl_comm::construct_url(CURL *curl, const std::string &relative_path,
relative_path, url); relative_path, url);
} }
auto curl_comm::create_curl() -> CURL * { return reset_curl(curl_easy_init()); }
auto curl_comm::reset_curl(CURL *curl_handle) -> CURL * {
curl_easy_reset(curl_handle);
#if defined(__APPLE__)
curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1);
#endif // defined(__APPLE__)
return curl_handle;
}
auto curl_comm::create_host_config(const s3_config &cfg, auto curl_comm::create_host_config(const s3_config &cfg,
bool use_s3_path_style) -> host_config { bool use_s3_path_style) -> host_config {
host_config host_cfg{}; host_config host_cfg{};

View File

@ -24,8 +24,8 @@
#include "utils/string.hpp" #include "utils/string.hpp"
namespace repertory::curl::requests { namespace repertory::curl::requests {
auto http_put_file::set_method(CURL *curl, stop_type &stop_requested) const auto http_put_file::set_method(CURL *curl,
-> bool { stop_type &stop_requested) const -> bool {
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT"); curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
@ -46,19 +46,14 @@ auto http_put_file::set_method(CURL *curl, stop_type &stop_requested) const
read_info = std::make_shared<read_file_info>(read_file_info{ read_info = std::make_shared<read_file_info>(read_file_info{
stop_requested, stop_requested,
utils::file::file::open_or_create_file(source_path),
}); });
if (native_file::create_or_open(source_path, read_info->nf) != if (not *read_info->file) {
api_error::success) {
return false; return false;
} }
read_info->nf->set_auto_close(true); auto file_size = read_info->file->size();
std::uint64_t file_size{};
if (not read_info->nf->get_file_size(file_size)) {
return false;
}
curl_easy_setopt(curl, CURLOPT_READDATA, read_info.get()); curl_easy_setopt(curl, CURLOPT_READDATA, read_info.get());
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_file_data); curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_file_data);

View File

@ -38,7 +38,7 @@ void packet::clear() {
auto packet::decode(std::string &data) -> packet::error_type { auto packet::decode(std::string &data) -> packet::error_type {
const auto *str = reinterpret_cast<const char *>(&buffer_[decode_offset_]); const auto *str = reinterpret_cast<const char *>(&buffer_[decode_offset_]);
const auto length = strnlen(str, buffer_.size() - decode_offset_); const auto length = strnlen(str, buffer_.size() - decode_offset_);
data = std::string{str, length}; data = std::string(str, length);
decode_offset_ += (length + 1); decode_offset_ += (length + 1);
return utils::from_api_error(api_error::success); return utils::from_api_error(api_error::success);
@ -194,7 +194,7 @@ auto packet::decode(remote::statfs &val) -> packet::error_type {
auto packet::decode(remote::statfs_x &val) -> packet::error_type { auto packet::decode(remote::statfs_x &val) -> packet::error_type {
auto ret = decode(*dynamic_cast<remote::statfs *>(&val)); auto ret = decode(*dynamic_cast<remote::statfs *>(&val));
if (ret == 0) { if (ret == 0) {
ret = decode(&val.f_mntfromname[0U], sizeof(val.f_mntfromname)); ret = decode(val.f_mntfromname.data(), val.f_mntfromname.size());
} }
return ret; return ret;
} }
@ -372,9 +372,9 @@ void packet::encode(remote::statfs val, bool should_reserve) {
void packet::encode(remote::statfs_x val) { void packet::encode(remote::statfs_x val) {
buffer_.reserve(buffer_.size() + sizeof(remote::statfs) + buffer_.reserve(buffer_.size() + sizeof(remote::statfs) +
sizeof(val.f_mntfromname)); val.f_mntfromname.size());
encode(*dynamic_cast<remote::statfs *>(&val), false); encode(*dynamic_cast<remote::statfs *>(&val), false);
encode(&val.f_mntfromname[0], sizeof(val.f_mntfromname), false); encode(val.f_mntfromname.data(), val.f_mntfromname.size(), false);
} }
void packet::encode(remote::file_info val) { void packet::encode(remote::file_info val) {
@ -501,8 +501,8 @@ void packet::encode_top(remote::statfs val, bool should_reserve) {
void packet::encode_top(remote::statfs_x val) { void packet::encode_top(remote::statfs_x val) {
buffer_.reserve(buffer_.size() + sizeof(remote::statfs) + buffer_.reserve(buffer_.size() + sizeof(remote::statfs) +
sizeof(val.f_mntfromname)); val.f_mntfromname.size());
encode_top(&val.f_mntfromname[0], sizeof(val.f_mntfromname), false); encode_top(val.f_mntfromname.data(), val.f_mntfromname.size(), false);
encode_top(*dynamic_cast<remote::statfs *>(&val), false); encode_top(*dynamic_cast<remote::statfs *>(&val), false);
} }

View File

@ -85,7 +85,7 @@ void directory_cache::service_function() {
auto lookup = directory_lookup_; auto lookup = directory_lookup_;
directory_lock.unlock(); directory_lock.unlock();
for (const auto &kv : lookup) { for (auto &&kv : lookup) {
if (std::chrono::duration_cast<std::chrono::seconds>( if (std::chrono::duration_cast<std::chrono::seconds>(
std::chrono::system_clock::now() - kv.second.last_update) >= 120s) { std::chrono::system_clock::now() - kv.second.last_update) >= 120s) {
directory_lock.lock(); directory_lock.lock();

View File

@ -38,37 +38,31 @@ auto eviction::check_minimum_requirements(const std::string &file_path)
static_cast<const char *>(__FUNCTION__), static_cast<const char *>(__FUNCTION__),
}; };
std::uint64_t file_size{}; auto opt_size = utils::file::file{file_path}.size();
if (not utils::file::get_file_size(file_path, file_size)) { if (not opt_size.has_value()) {
utils::error::raise_error(function_name, utils::get_last_error_code(), utils::error::raise_error(function_name, utils::get_last_error_code(),
file_path, "failed to get file size"); file_path, "failed to get file size");
return false; return false;
} }
auto ret = false; auto file_size{opt_size.value()};
if (file_size != 0U) { if (file_size == 0U) {
std::uint64_t reference_time{}; return false;
ret = config_.get_eviction_uses_accessed_time()
? utils::file::get_accessed_time(file_path, reference_time)
: utils::file::get_modified_time(file_path, reference_time);
if (ret) {
#if defined(_WIN32)
const auto now = std::chrono::system_clock::now();
const auto delay =
std::chrono::minutes(config_.get_eviction_delay_mins());
ret = ((std::chrono::system_clock::from_time_t(
static_cast<time_t>(reference_time)) +
delay) <= now);
#else
const auto now = utils::time::get_time_now();
const auto delay =
(config_.get_eviction_delay_mins() * 60L) * NANOS_PER_SECOND;
ret = ((reference_time + static_cast<std::uint64_t>(delay)) <= now);
#endif
}
} }
return ret; auto reference_time = utils::file::file{file_path}.get_time(
config_.get_eviction_uses_accessed_time()
? utils::file::time_type::accessed
: utils::file::time_type::modified);
if (not reference_time.has_value()) {
return false;
}
auto delay = (config_.get_eviction_delay_mins() * 60UL) *
utils::time::NANOS_PER_SECOND;
return ((reference_time.value() + static_cast<std::uint64_t>(delay)) <=
utils::time::get_time_now());
} }
auto eviction::get_filtered_cached_files() -> std::deque<std::string> { auto eviction::get_filtered_cached_files() -> std::deque<std::string> {
@ -91,7 +85,7 @@ void eviction::service_function() {
// Handle maximum cache size eviction // Handle maximum cache size eviction
auto used_bytes = auto used_bytes =
utils::file::calculate_used_space(config_.get_cache_directory(), false); utils::file::directory{config_.get_cache_directory()}.size();
if (config_.get_enable_max_cache_size()) { if (config_.get_enable_max_cache_size()) {
should_evict = (used_bytes > config_.get_max_cache_size_bytes()); should_evict = (used_bytes > config_.get_max_cache_size_bytes());
} }
@ -110,9 +104,9 @@ void eviction::service_function() {
if (provider_.get_filesystem_item_and_file(api_path, file, fsi) == if (provider_.get_filesystem_item_and_file(api_path, file, fsi) ==
api_error::success) { api_error::success) {
// Only evict files that match expected size // Only evict files that match expected size
std::uint64_t file_size{}; auto opt_size = utils::file::file{cached_files_list.front()}.size();
if (utils::file::get_file_size(cached_files_list.front(), if (opt_size.has_value()) {
file_size)) { auto file_size{opt_size.value()};
if (file_size == fsi.size) { if (file_size == fsi.size) {
// Try to evict file // Try to evict file
if (fm_.evict_file(fsi.api_path) && if (fm_.evict_file(fsi.api_path) &&

View File

@ -106,8 +106,8 @@ auto fuse_base::access_(const char *path, int mask) -> int {
}; };
return instance().instance().execute_callback( return instance().instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error { function_name, path, [&](std::string api_path) -> api_error {
return instance().access_impl(api_path, mask); return instance().access_impl(std::move(api_path), mask);
}); });
} }
@ -118,8 +118,8 @@ auto fuse_base::chflags_(const char *path, uint32_t flags) -> int {
}; };
return instance().instance().execute_callback( return instance().instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error { function_name, path, [&](std::string api_path) -> api_error {
return instance().chflags_impl(api_path, flags); return instance().chflags_impl(std::move(api_path), flags);
}); });
} }
#endif // __APPLE__ #endif // __APPLE__
@ -132,8 +132,8 @@ auto fuse_base::chmod_(const char *path, mode_t mode,
}; };
return instance().execute_callback( return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error { function_name, path, [&](std::string api_path) -> api_error {
return instance().chmod_impl(api_path, mode, fi); return instance().chmod_impl(std::move(api_path), mode, fi);
}); });
} }
#else #else
@ -143,8 +143,8 @@ auto fuse_base::chmod_(const char *path, mode_t mode) -> int {
}; };
return instance().execute_callback( return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error { function_name, path, [&](std::string api_path) -> api_error {
return instance().chmod_impl(api_path, mode); return instance().chmod_impl(std::move(api_path), mode);
}); });
} }
#endif #endif
@ -157,8 +157,8 @@ auto fuse_base::chown_(const char *path, uid_t uid, gid_t gid,
}; };
return instance().execute_callback( return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error { function_name, path, [&](std::string api_path) -> api_error {
return instance().chown_impl(api_path, uid, gid, fi); return instance().chown_impl(std::move(api_path), uid, gid, fi);
}); });
} }
#else #else
@ -168,8 +168,8 @@ auto fuse_base::chown_(const char *path, uid_t uid, gid_t gid) -> int {
}; };
return instance().execute_callback( return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error { function_name, path, [&](std::string api_path) -> api_error {
return instance().chown_impl(api_path, uid, gid); return instance().chown_impl(std::move(api_path), uid, gid);
}); });
} }
#endif #endif
@ -181,8 +181,8 @@ auto fuse_base::create_(const char *path, mode_t mode,
}; };
return instance().execute_callback( return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error { function_name, path, [&](std::string api_path) -> api_error {
return instance().create_impl(api_path, mode, fi); return instance().create_impl(std::move(api_path), mode, fi);
}); });
} }
@ -223,12 +223,12 @@ void fuse_base::display_version_information(std::vector<const char *> args) {
auto fuse_base::execute_callback( auto fuse_base::execute_callback(
std::string_view function_name, const char *from, const char *to, std::string_view function_name, const char *from, const char *to,
const std::function<api_error(const std::string &from_api_file, const std::function<api_error(std::string from_api_file,
const std::string &to_api_path)> &cb, std::string to_api_path)> &cb,
bool disable_logging) -> int { bool disable_logging) -> int {
const auto from_api_file = utils::path::create_api_path(from ? from : ""); auto from_api_file = utils::path::create_api_path(from ? from : "");
const auto to_api_file = utils::path::create_api_path(to ? to : ""); auto to_api_file = utils::path::create_api_path(to ? to : "");
const auto res = utils::from_api_error(cb(from_api_file, to_api_file)); auto res = utils::from_api_error(cb(from_api_file, to_api_file));
raise_fuse_event(function_name, raise_fuse_event(function_name,
"from|" + from_api_file + "|to|" + to_api_file, res, "from|" + from_api_file + "|to|" + to_api_file, res,
disable_logging); disable_logging);
@ -237,7 +237,7 @@ auto fuse_base::execute_callback(
auto fuse_base::execute_callback( auto fuse_base::execute_callback(
std::string_view function_name, const char *path, std::string_view function_name, const char *path,
const std::function<api_error(const std::string &api_path)> &cb, const std::function<api_error(std::string api_path)> &cb,
bool disable_logging) -> int { bool disable_logging) -> int {
const auto api_path = utils::path::create_api_path(path ? path : ""); const auto api_path = utils::path::create_api_path(path ? path : "");
const auto res = utils::from_api_error(cb(api_path)); const auto res = utils::from_api_error(cb(api_path));
@ -269,8 +269,9 @@ auto fuse_base::fallocate_(const char *path, int mode, off_t offset,
}; };
return instance().execute_callback( return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error { function_name, path, [&](std::string api_path) -> api_error {
return instance().fallocate_impl(api_path, mode, offset, length, fi); return instance().fallocate_impl(std::move(api_path), mode, offset,
length, fi);
}); });
} }
@ -282,8 +283,8 @@ auto fuse_base::fgetattr_(const char *path, struct stat *st,
}; };
return instance().execute_callback( return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error { function_name, path, [&](std::string api_path) -> api_error {
return instance().fgetattr_impl(api_path, st, fi); return instance().fgetattr_impl(std::move(api_path), st, fi);
}); });
} }
#endif #endif
@ -296,8 +297,8 @@ auto fuse_base::fsetattr_x_(const char *path, struct setattr_x *attr,
}; };
return instance().execute_callback( return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error { function_name, path, [&](std::string api_path) -> api_error {
return instance().fsetattr_x_impl(api_path, attr, fi); return instance().fsetattr_x_impl(std::move(api_path), attr, fi);
}); });
} }
#endif // __APPLE__ #endif // __APPLE__
@ -309,8 +310,8 @@ auto fuse_base::fsync_(const char *path, int datasync,
}; };
return instance().execute_callback( return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error { function_name, path, [&](std::string api_path) -> api_error {
return instance().fsync_impl(api_path, datasync, fi); return instance().fsync_impl(std::move(api_path), datasync, fi);
}); });
} }
@ -322,8 +323,8 @@ auto fuse_base::ftruncate_(const char *path, off_t size,
}; };
return instance().execute_callback( return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error { function_name, path, [&](std::string api_path) -> api_error {
return instance().ftruncate_impl(api_path, size, fi); return instance().ftruncate_impl(std::move(api_path), size, fi);
}); });
} }
#endif #endif
@ -336,8 +337,8 @@ auto fuse_base::getattr_(const char *path, struct stat *st,
}; };
return instance().execute_callback( return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error { function_name, path, [&](std::string api_path) -> api_error {
return instance().getattr_impl(api_path, st, fi); return instance().getattr_impl(std::move(api_path), st, fi);
}); });
} }
#else #else
@ -347,8 +348,8 @@ auto fuse_base::getattr_(const char *path, struct stat *st) -> int {
}; };
return instance().execute_callback( return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error { function_name, path, [&](std::string api_path) -> api_error {
return instance().getattr_impl(api_path, st); return instance().getattr_impl(std::move(api_path), st);
}); });
} }
#endif #endif
@ -361,8 +362,8 @@ auto fuse_base::getxtimes_(const char *path, struct timespec *bkuptime,
}; };
return instance().execute_callback( return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error { function_name, path, [&](std::string api_path) -> api_error {
return instance().getxtimes_impl(api_path, bkuptime, crtime); return instance().getxtimes_impl(std::move(api_path), bkuptime, crtime);
}); });
} }
#endif // __APPLE__ #endif // __APPLE__
@ -392,31 +393,34 @@ auto fuse_base::init_(struct fuse_conn_info *conn) -> void * {
#if FUSE_USE_VERSION >= 30 #if FUSE_USE_VERSION >= 30
auto fuse_base::init_impl([[maybe_unused]] struct fuse_conn_info *conn, auto fuse_base::init_impl([[maybe_unused]] struct fuse_conn_info *conn,
struct fuse_config *cfg) -> void * { struct fuse_config *cfg) -> void * {
#else #else // FUSE_USE_VERSION < 30
auto fuse_base::init_impl(struct fuse_conn_info *conn) -> void * { auto fuse_base::init_impl(struct fuse_conn_info *conn) -> void * {
#endif #endif // FUSE_USE_VERSION >= 30
static constexpr const std::string_view function_name{ static constexpr const std::string_view function_name{
static_cast<const char *>(__FUNCTION__), static_cast<const char *>(__FUNCTION__),
}; };
utils::file::change_to_process_directory();
if (not console_enabled_) {
if (not repertory::project_initialize()) {
utils::error::raise_error(function_name,
"failed to initialize repertory");
event_system::instance().raise<unmount_requested>();
}
}
#if defined(__APPLE__) #if defined(__APPLE__)
conn->want |= FUSE_CAP_VOL_RENAME; conn->want |= FUSE_CAP_VOL_RENAME;
conn->want |= FUSE_CAP_XTIMES; conn->want |= FUSE_CAP_XTIMES;
#endif // __APPLE__ #endif // defined(__APPLE__)
#if FUSE_USE_VERSION >= 30 #if FUSE_USE_VERSION >= 30
cfg->nullpath_ok = 0; cfg->nullpath_ok = 0;
cfg->hard_remove = 1; cfg->hard_remove = 1;
#endif #endif // FUSE_USE_VERSION >= 30
if (not utils::file::change_to_process_directory()) {
utils::error::raise_error(function_name,
"failed to change to process directory");
event_system::instance().raise<unmount_requested>();
return this;
}
if (not console_enabled_ && not repertory::project_initialize()) {
utils::error::raise_error(function_name, "failed to initialize repertory");
event_system::instance().raise<unmount_requested>();
}
return this; return this;
} }
@ -427,8 +431,8 @@ auto fuse_base::mkdir_(const char *path, mode_t mode) -> int {
}; };
return instance().execute_callback( return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error { function_name, path, [&](std::string api_path) -> api_error {
return instance().mkdir_impl(api_path, mode); return instance().mkdir_impl(std::move(api_path), mode);
}); });
} }
@ -436,7 +440,7 @@ auto fuse_base::mount(std::vector<std::string> args) -> int {
auto ret = parse_args(args); auto ret = parse_args(args);
if (ret == 0) { if (ret == 0) {
std::vector<const char *> fuse_argv(args.size()); std::vector<const char *> fuse_argv(args.size());
for (std::size_t i = 0u; i < args.size(); i++) { for (std::size_t i = 0u; i < args.size(); ++i) {
fuse_argv[i] = args[i].c_str(); fuse_argv[i] = args[i].c_str();
} }
@ -486,8 +490,8 @@ auto fuse_base::open_(const char *path, struct fuse_file_info *fi) -> int {
}; };
return instance().execute_callback( return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error { function_name, path, [&](std::string api_path) -> api_error {
return instance().open_impl(api_path, fi); return instance().open_impl(std::move(api_path), fi);
}); });
} }
@ -497,8 +501,8 @@ auto fuse_base::opendir_(const char *path, struct fuse_file_info *fi) -> int {
}; };
return instance().execute_callback( return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error { function_name, path, [&](std::string api_path) -> api_error {
return instance().opendir_impl(api_path, fi); return instance().opendir_impl(std::move(api_path), fi);
}); });
} }
@ -511,9 +515,9 @@ auto fuse_base::read_(const char *path, char *buffer, size_t read_size,
std::size_t bytes_read{}; std::size_t bytes_read{};
const auto res = instance().execute_callback( const auto res = instance().execute_callback(
function_name, path, function_name, path,
[&](const std::string &api_path) -> api_error { [&](std::string api_path) -> api_error {
return instance().read_impl(api_path, buffer, read_size, read_offset, return instance().read_impl(std::move(api_path), buffer, read_size,
fi, bytes_read); read_offset, fi, bytes_read);
}, },
true); true);
return (res == 0) ? static_cast<int>(bytes_read) : res; return (res == 0) ? static_cast<int>(bytes_read) : res;
@ -529,9 +533,9 @@ auto fuse_base::readdir_(const char *path, void *buf,
}; };
return instance().execute_callback( return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error { function_name, path, [&](std::string api_path) -> api_error {
return instance().readdir_impl(api_path, buf, fuse_fill_dir, offset, fi, return instance().readdir_impl(std::move(api_path), buf, fuse_fill_dir,
flags); offset, fi, flags);
}); });
} }
#else #else
@ -543,9 +547,9 @@ auto fuse_base::readdir_(const char *path, void *buf,
}; };
return instance().execute_callback( return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error { function_name, path, [&](std::string api_path) -> api_error {
return instance().readdir_impl(api_path, buf, fuse_fill_dir, offset, return instance().readdir_impl(std::move(api_path), buf, fuse_fill_dir,
fi); offset, fi);
}); });
} }
#endif #endif
@ -556,8 +560,8 @@ auto fuse_base::release_(const char *path, struct fuse_file_info *fi) -> int {
}; };
return instance().execute_callback( return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error { function_name, path, [&](std::string api_path) -> api_error {
return instance().release_impl(api_path, fi); return instance().release_impl(std::move(api_path), fi);
}); });
} }
@ -568,8 +572,8 @@ auto fuse_base::releasedir_(const char *path,
}; };
return instance().execute_callback( return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error { function_name, path, [&](std::string api_path) -> api_error {
return instance().releasedir_impl(api_path, fi); return instance().releasedir_impl(std::move(api_path), fi);
}); });
} }
@ -582,9 +586,9 @@ auto fuse_base::rename_(const char *from, const char *to,
return instance().execute_callback( return instance().execute_callback(
function_name, from, to, function_name, from, to,
[&](const std::string &from_api_file, [&](std::string from_api_file, std::string to_api_path) -> api_error {
const std::string &to_api_path) -> api_error { return instance().rename_impl(std::move(from_api_file),
return instance().rename_impl(from_api_file, to_api_path, flags); std::move(to_api_path), flags);
}); });
} }
#else #else
@ -595,9 +599,9 @@ auto fuse_base::rename_(const char *from, const char *to) -> int {
return instance().execute_callback( return instance().execute_callback(
function_name, from, to, function_name, from, to,
[&](const std::string &from_api_file, [&](std::string from_api_file, std::string to_api_path) -> api_error {
const std::string &to_api_path) -> api_error { return instance().rename_impl(std::move(from_api_file),
return instance().rename_impl(from_api_file, to_api_path); std::move(to_api_path));
}); });
} }
#endif #endif
@ -608,8 +612,8 @@ auto fuse_base::rmdir_(const char *path) -> int {
}; };
return instance().execute_callback( return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error { function_name, path, [&](std::string api_path) -> api_error {
return instance().rmdir_impl(api_path); return instance().rmdir_impl(std::move(api_path));
}); });
} }
@ -623,9 +627,9 @@ auto fuse_base::getxattr_(const char *path, const char *name, char *value,
int attribute_size = 0; int attribute_size = 0;
const auto res = instance().execute_callback( const auto res = instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error { function_name, path, [&](std::string api_path) -> api_error {
return instance().getxattr_impl(api_path, name, value, size, position, return instance().getxattr_impl(std::move(api_path), name, value, size,
attribute_size); position, attribute_size);
}); });
return res == 0 ? attribute_size : res; return res == 0 ? attribute_size : res;
@ -639,8 +643,8 @@ auto fuse_base::getxattr_(const char *path, const char *name, char *value,
int attribute_size = 0; int attribute_size = 0;
const auto res = instance().execute_callback( const auto res = instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error { function_name, path, [&](std::string api_path) -> api_error {
return instance().getxattr_impl(api_path, name, value, size, return instance().getxattr_impl(std::move(api_path), name, value, size,
attribute_size); attribute_size);
}); });
@ -657,9 +661,9 @@ auto fuse_base::listxattr_(const char *path, char *buffer, size_t size) -> int {
bool return_size = false; bool return_size = false;
const auto res = instance().execute_callback( const auto res = instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error { function_name, path, [&](std::string api_path) -> api_error {
return instance().listxattr_impl(api_path, buffer, size, required_size, return instance().listxattr_impl(std::move(api_path), buffer, size,
return_size); required_size, return_size);
}); });
return return_size ? required_size : res; return return_size ? required_size : res;
@ -676,14 +680,14 @@ void fuse_base::notify_fuse_args_parsed(const std::vector<std::string> &args) {
auto fuse_base::parse_args(std::vector<std::string> &args) -> int { auto fuse_base::parse_args(std::vector<std::string> &args) -> int {
auto force_no_console = false; auto force_no_console = false;
for (std::size_t i = 1u; !force_no_console && (i < args.size()); i++) { for (std::size_t i = 1u; !force_no_console && (i < args.size()); ++i) {
if (args[i] == "-nc") { if (args[i] == "-nc") {
force_no_console = true; force_no_console = true;
} }
} }
utils::collection::remove_element(args, "-nc"); utils::collection::remove_element(args, "-nc");
for (std::size_t i = 1u; i < args.size(); i++) { for (std::size_t i = 1u; i < args.size(); ++i) {
if (args[i] == "-f") { if (args[i] == "-f") {
console_enabled_ = not force_no_console; console_enabled_ = not force_no_console;
} else if (args[i].find("-o") == 0) { } else if (args[i].find("-o") == 0) {
@ -697,7 +701,7 @@ auto fuse_base::parse_args(std::vector<std::string> &args) -> int {
} }
const auto option_parts = utils::string::split(options, ',', true); const auto option_parts = utils::string::split(options, ',', true);
for (const auto &option : option_parts) { for (auto &&option : option_parts) {
if (option.find("gid") == 0) { if (option.find("gid") == 0) {
const auto parts = utils::string::split(option, '=', true); const auto parts = utils::string::split(option, '=', true);
if (parts.size() == 2u) { if (parts.size() == 2u) {
@ -752,7 +756,7 @@ auto fuse_base::parse_args(std::vector<std::string> &args) -> int {
} }
void fuse_base::raise_fuse_event(std::string_view function_name, void fuse_base::raise_fuse_event(std::string_view function_name,
const std::string &api_path, int ret, std::string_view api_path, int ret,
bool disable_logging) { bool disable_logging) {
if ((ret >= 0) && disable_logging) { if ((ret >= 0) && disable_logging) {
return; return;
@ -766,7 +770,7 @@ void fuse_base::raise_fuse_event(std::string_view function_name,
(config_.get_event_level() >= event_level::trace)) { (config_.get_event_level() >= event_level::trace)) {
std::string func{function_name}; std::string func{function_name};
event_system::instance().raise<fuse_event>( event_system::instance().raise<fuse_event>(
utils::string::right_trim(func, '_'), api_path, ret); utils::string::right_trim(func, '_'), std::string{api_path}, ret);
} }
} }
@ -776,8 +780,8 @@ auto fuse_base::removexattr_(const char *path, const char *name) -> int {
}; };
return instance().execute_callback( return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error { function_name, path, [&](std::string api_path) -> api_error {
return instance().removexattr_impl(api_path, name); return instance().removexattr_impl(std::move(api_path), name);
}); });
} }
@ -789,9 +793,9 @@ auto fuse_base::setxattr_(const char *path, const char *name, const char *value,
}; };
const auto res = instance().execute_callback( const auto res = instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error { function_name, path, [&](std::string api_path) -> api_error {
return instance().setxattr_impl(api_path, name, value, size, flags, return instance().setxattr_impl(std::move(api_path), name, value, size,
position); flags, position);
}); });
if (res != 0) { if (res != 0) {
errno = std::abs(res); errno = std::abs(res);
@ -807,8 +811,9 @@ auto fuse_base::setxattr_(const char *path, const char *name, const char *value,
}; };
const auto res = instance().execute_callback( const auto res = instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error { function_name, path, [&](std::string api_path) -> api_error {
return instance().setxattr_impl(api_path, name, value, size, flags); return instance().setxattr_impl(std::move(api_path), name, value, size,
flags);
}); });
if (res != 0) { if (res != 0) {
errno = std::abs(res); errno = std::abs(res);
@ -832,8 +837,8 @@ auto fuse_base::setattr_x_(const char *path, struct setattr_x *attr) -> int {
}; };
return instance().execute_callback( return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error { function_name, path, [&](std::string api_path) -> api_error {
return instance().setattr_x_impl(api_path, attr); return instance().setattr_x_impl(std::move(api_path), attr);
}); });
} }
@ -844,8 +849,8 @@ auto fuse_base::setbkuptime_(const char *path,
}; };
return instance().execute_callback( return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error { function_name, path, [&](std::string api_path) -> api_error {
return instance().setbkuptime_impl(api_path, bkuptime); return instance().setbkuptime_impl(std::move(api_path), bkuptime);
}); });
} }
@ -856,8 +861,8 @@ auto fuse_base::setchgtime_(const char *path,
}; };
return instance().execute_callback( return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error { function_name, path, [&](std::string api_path) -> api_error {
return instance().setchgtime_impl(api_path, chgtime); return instance().setchgtime_impl(std::move(api_path), chgtime);
}); });
} }
@ -868,8 +873,8 @@ auto fuse_base::setcrtime_(const char *path,
}; };
return instance().execute_callback( return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error { function_name, path, [&](std::string api_path) -> api_error {
return instance().setcrtime_impl(api_path, crtime); return instance().setcrtime_impl(std::move(api_path), crtime);
}); });
} }
@ -879,8 +884,8 @@ auto fuse_base::setvolname_(const char *volname) -> int {
}; };
return instance().execute_callback( return instance().execute_callback(
function_name, volname, [&](const std::string &api_path) -> api_error { function_name, volname, [&](std::string api_path) -> api_error {
return instance().setvolname_impl(volname); return instance().setvolname_impl(std::move(volname));
}); });
} }
@ -890,8 +895,8 @@ auto fuse_base::statfs_x_(const char *path, struct statfs *stbuf) -> int {
}; };
return instance().execute_callback( return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error { function_name, path, [&](std::string api_path) -> api_error {
return instance().statfs_x_impl(api_path, stbuf); return instance().statfs_x_impl(std::move(api_path), stbuf);
}); });
} }
#else // __APPLE__ #else // __APPLE__
@ -901,8 +906,8 @@ auto fuse_base::statfs_(const char *path, struct statvfs *stbuf) -> int {
}; };
return instance().execute_callback( return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error { function_name, path, [&](std::string api_path) -> api_error {
return instance().statfs_impl(api_path, stbuf); return instance().statfs_impl(std::move(api_path), stbuf);
}); });
} }
#endif // __APPLE__ #endif // __APPLE__
@ -915,8 +920,8 @@ auto fuse_base::truncate_(const char *path, off_t size,
}; };
return instance().execute_callback( return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error { function_name, path, [&](std::string api_path) -> api_error {
return instance().truncate_impl(api_path, size, fi); return instance().truncate_impl(std::move(api_path), size, fi);
}); });
} }
#else #else
@ -926,8 +931,8 @@ auto fuse_base::truncate_(const char *path, off_t size) -> int {
}; };
return instance().execute_callback( return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error { function_name, path, [&](std::string api_path) -> api_error {
return instance().truncate_impl(api_path, size); return instance().truncate_impl(std::move(api_path), size);
}); });
} }
#endif #endif
@ -938,8 +943,8 @@ auto fuse_base::unlink_(const char *path) -> int {
}; };
return instance().execute_callback( return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error { function_name, path, [&](std::string api_path) -> api_error {
return instance().unlink_impl(api_path); return instance().unlink_impl(std::move(api_path));
}); });
} }
@ -965,8 +970,8 @@ auto fuse_base::utimens_(const char *path, const struct timespec tv[2],
}; };
return instance().execute_callback( return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error { function_name, path, [&](std::string api_path) -> api_error {
return instance().utimens_impl(api_path, tv, fi); return instance().utimens_impl(std::move(api_path), tv, fi);
}); });
} }
#else #else
@ -976,8 +981,8 @@ auto fuse_base::utimens_(const char *path, const struct timespec tv[2]) -> int {
}; };
return instance().execute_callback( return instance().execute_callback(
function_name, path, [&](const std::string &api_path) -> api_error { function_name, path, [&](std::string api_path) -> api_error {
return instance().utimens_impl(api_path, tv); return instance().utimens_impl(std::move(api_path), tv);
}); });
} }
#endif #endif
@ -992,9 +997,9 @@ auto fuse_base::write_(const char *path, const char *buffer, size_t write_size,
const auto res = instance().execute_callback( const auto res = instance().execute_callback(
function_name, path, function_name, path,
[&](const std::string &api_path) -> api_error { [&](std::string api_path) -> api_error {
return instance().write_impl(api_path, buffer, write_size, write_offset, return instance().write_impl(std::move(api_path), buffer, write_size,
fi, bytes_written); write_offset, fi, bytes_written);
}, },
true); true);
return (res == 0) ? static_cast<int>(bytes_written) : res; return (res == 0) ? static_cast<int>(bytes_written) : res;

View File

@ -163,7 +163,7 @@ auto fuse_drive::create_impl(std::string api_path, mode_t mode,
{ {
std::shared_ptr<i_open_file> open_file; std::shared_ptr<i_open_file> open_file;
if (is_create_op) { if (is_create_op) {
const auto now = utils::time::get_file_time_now(); const auto now = utils::time::get_time_now();
#if defined(__APPLE__) #if defined(__APPLE__)
const auto osx_flags = static_cast<std::uint32_t>(file_info->flags); const auto osx_flags = static_cast<std::uint32_t>(file_info->flags);
#else // !defined(__APPLE__) #else // !defined(__APPLE__)
@ -614,7 +614,7 @@ auto fuse_drive::mkdir_impl(std::string api_path, mode_t mode) -> api_error {
return res; return res;
} }
const auto now = utils::time::get_file_time_now(); const auto now = utils::time::get_time_now();
auto meta = create_meta_attributes(now, FILE_ATTRIBUTE_DIRECTORY, now, now, auto meta = create_meta_attributes(now, FILE_ATTRIBUTE_DIRECTORY, now, now,
true, get_effective_gid(), "", mode, now, true, get_effective_gid(), "", mode, now,
0U, 0U, 0U, "", get_effective_uid(), now); 0U, 0U, 0U, "", get_effective_uid(), now);
@ -915,7 +915,7 @@ auto fuse_drive::listxattr_impl(std::string api_path, char *buffer, size_t size,
api_meta_map meta; api_meta_map meta;
if ((res = provider_.get_item_meta(api_path, meta)) == api_error::success) { if ((res = provider_.get_item_meta(api_path, meta)) == api_error::success) {
for (const auto &meta_item : meta) { for (auto &&meta_item : meta) {
if (utils::collection::excludes(META_USED_NAMES, meta_item.first)) { if (utils::collection::excludes(META_USED_NAMES, meta_item.first)) {
auto attribute_name = meta_item.first; auto attribute_name = meta_item.first;
#if defined(__APPLE__) #if defined(__APPLE__)
@ -1155,8 +1155,8 @@ auto fuse_drive::setbkuptime_impl(
std::string api_path, const struct timespec *bkuptime) -> api_error { std::string api_path, const struct timespec *bkuptime) -> api_error {
return check_and_perform( return check_and_perform(
api_path, X_OK, [&](api_meta_map &meta) -> api_error { api_path, X_OK, [&](api_meta_map &meta) -> api_error {
const auto nanos = const auto nanos = bkuptime->tv_nsec +
bkuptime->tv_nsec + (bkuptime->tv_nsec * NANOS_PER_SECOND); (bkuptime->tv_nsec * utils::time::NANOS_PER_SECOND);
return provider_.set_item_meta(api_path, META_BACKUP, return provider_.set_item_meta(api_path, META_BACKUP,
std::to_string(nanos)); std::to_string(nanos));
}); });
@ -1166,8 +1166,8 @@ auto fuse_drive::setchgtime_impl(std::string api_path,
const struct timespec *chgtime) -> api_error { const struct timespec *chgtime) -> api_error {
return check_and_perform( return check_and_perform(
api_path, X_OK, [&](api_meta_map &meta) -> api_error { api_path, X_OK, [&](api_meta_map &meta) -> api_error {
const auto nanos = const auto nanos = chgtime->tv_nsec +
chgtime->tv_nsec + (chgtime->tv_nsec * NANOS_PER_SECOND); (chgtime->tv_nsec * utils::time::NANOS_PER_SECOND);
return provider_.set_item_meta(api_path, META_CHANGED, return provider_.set_item_meta(api_path, META_CHANGED,
std::to_string(nanos)); std::to_string(nanos));
}); });
@ -1178,7 +1178,7 @@ auto fuse_drive::setcrtime_impl(std::string api_path,
return check_and_perform( return check_and_perform(
api_path, X_OK, [&](api_meta_map &meta) -> api_error { api_path, X_OK, [&](api_meta_map &meta) -> api_error {
const auto nanos = const auto nanos =
crtime->tv_nsec + (crtime->tv_nsec * NANOS_PER_SECOND); crtime->tv_nsec + (crtime->tv_nsec * utils::time::NANOS_PER_SECOND);
return provider_.set_item_meta(api_path, META_CREATION, return provider_.set_item_meta(api_path, META_CREATION,
std::to_string(nanos)); std::to_string(nanos));
}); });
@ -1310,19 +1310,24 @@ auto fuse_drive::utimens_impl(std::string api_path,
} }
meta.clear(); meta.clear();
if ((tv == nullptr) || (tv[0U].tv_nsec == UTIME_NOW)) {
meta[META_ACCESSED] = std::to_string(utils::time::get_file_time_now());
} else if (tv[0U].tv_nsec != UTIME_OMIT) {
const auto val = tv[0U].tv_nsec + (tv[0U].tv_sec * NANOS_PER_SECOND);
meta[META_ACCESSED] = std::to_string(val);
}
if ((tv == nullptr) || (tv[1U].tv_nsec == UTIME_NOW)) { const auto process_timespec = [&meta, &tv](const auto &src,
meta[META_MODIFIED] = std::to_string(utils::time::get_file_time_now()); std::string attr) {
} else if (tv[1U].tv_nsec != UTIME_OMIT) { if ((tv == nullptr) || (src.tv_nsec == UTIME_NOW)) {
const auto val = tv[1U].tv_nsec + (tv[1U].tv_sec * NANOS_PER_SECOND); meta[attr] = std::to_string(utils::time::get_time_now());
meta[META_MODIFIED] = std::to_string(val); return;
} }
if (src.tv_nsec != UTIME_OMIT) {
meta[attr] = std::to_string(
src.tv_nsec +
(src.tv_sec * static_cast<std::decay_t<decltype(src.tv_sec)>>(
utils::time::NANOS_PER_SECOND)));
}
};
process_timespec(tv[0U], META_ACCESSED);
process_timespec(tv[1U], META_MODIFIED);
if (not meta.empty()) { if (not meta.empty()) {
return provider_.set_item_meta(api_path, meta); return provider_.set_item_meta(api_path, meta);
@ -1369,8 +1374,7 @@ void fuse_drive::update_accessed_time(const std::string &api_path) {
if (atime_enabled_) { if (atime_enabled_) {
auto res = provider_.set_item_meta( auto res = provider_.set_item_meta(
api_path, META_ACCESSED, api_path, META_ACCESSED, std::to_string(utils::time::get_time_now()));
std::to_string(utils::time::get_file_time_now()));
if (res != api_error::success) { if (res != api_error::success) {
utils::error::raise_api_path_error(function_name, api_path, res, utils::error::raise_api_path_error(function_name, api_path, res,
"failed to set accessed time"); "failed to set accessed time");

View File

@ -26,6 +26,7 @@
#include "platform/platform.hpp" #include "platform/platform.hpp"
#include "providers/i_provider.hpp" #include "providers/i_provider.hpp"
#include "utils/common.hpp" #include "utils/common.hpp"
#include "utils/time.hpp"
namespace repertory { namespace repertory {
auto fuse_drive_base::access_impl(std::string api_path, int mask) -> api_error { auto fuse_drive_base::access_impl(std::string api_path, int mask) -> api_error {
@ -165,9 +166,9 @@ auto fuse_drive_base::check_parent_access(const std::string &api_path,
// Ignore root // Ignore root
if (api_path != "/") { if (api_path != "/") {
if ((mask & X_OK) == X_OK) { if ((mask & X_OK) == X_OK) {
for (auto parent = utils::path::get_parent_directory(api_path); for (auto parent = utils::path::get_parent_path(api_path);
(ret == api_error::success) && not parent.empty(); (ret == api_error::success) && not parent.empty();
parent = utils::path::get_parent_directory(parent)) { parent = utils::path::get_parent_path(parent)) {
if (((ret = check_access(parent, X_OK)) == api_error::success) && if (((ret = check_access(parent, X_OK)) == api_error::success) &&
(parent == "/")) { (parent == "/")) {
break; break;
@ -178,7 +179,7 @@ auto fuse_drive_base::check_parent_access(const std::string &api_path,
if (ret == api_error::success) { if (ret == api_error::success) {
mask &= (~X_OK); mask &= (~X_OK);
if (mask != 0) { if (mask != 0) {
ret = check_access(utils::path::get_parent_directory(api_path), mask); ret = check_access(utils::path::get_parent_path(api_path), mask);
} }
} }
} }
@ -233,9 +234,9 @@ auto fuse_drive_base::get_mode_from_meta(const api_meta_map &meta) -> mode_t {
void fuse_drive_base::get_timespec_from_meta(const api_meta_map &meta, void fuse_drive_base::get_timespec_from_meta(const api_meta_map &meta,
const std::string &name, const std::string &name,
struct timespec &ts) { struct timespec &ts) {
const auto meta_time = utils::string::to_int64(meta.at(name)); auto meta_time = utils::string::to_uint64(meta.at(name));
ts.tv_nsec = meta_time % NANOS_PER_SECOND; ts.tv_nsec = meta_time % utils::time::NANOS_PER_SECOND;
ts.tv_sec = meta_time / NANOS_PER_SECOND; ts.tv_sec = meta_time / utils::time::NANOS_PER_SECOND;
} }
auto fuse_drive_base::get_uid_from_meta(const api_meta_map &meta) -> uid_t { auto fuse_drive_base::get_uid_from_meta(const api_meta_map &meta) -> uid_t {
@ -299,7 +300,7 @@ void fuse_drive_base::populate_stat(const std::string &api_path,
std::uint64_t size_or_count, std::uint64_t size_or_count,
const api_meta_map &meta, bool directory, const api_meta_map &meta, bool directory,
i_provider &provider, struct stat *st) { i_provider &provider, struct stat *st) {
memset(st, 0, sizeof(struct stat)); std::memset(st, 0, sizeof(struct stat));
st->st_nlink = static_cast<nlink_t>( st->st_nlink = static_cast<nlink_t>(
directory ? 2 + (size_or_count == 0U directory ? 2 + (size_or_count == 0U
? provider.get_directory_item_count(api_path) ? provider.get_directory_item_count(api_path)
@ -341,9 +342,9 @@ void fuse_drive_base::populate_stat(const std::string &api_path,
void fuse_drive_base::set_timespec_from_meta(const api_meta_map &meta, void fuse_drive_base::set_timespec_from_meta(const api_meta_map &meta,
const std::string &name, const std::string &name,
struct timespec &ts) { struct timespec &ts) {
const auto meta_time = utils::string::to_int64(meta.at(name)); auto meta_time = utils::string::to_uint64(meta.at(name));
ts.tv_nsec = meta_time % NANOS_PER_SECOND; ts.tv_nsec = meta_time % utils::time::NANOS_PER_SECOND;
ts.tv_sec = meta_time / NANOS_PER_SECOND; ts.tv_sec = meta_time / utils::time::NANOS_PER_SECOND;
} }
} // namespace repertory } // namespace repertory

View File

@ -36,6 +36,7 @@
#include "utils/error_utils.hpp" #include "utils/error_utils.hpp"
#include "utils/file_utils.hpp" #include "utils/file_utils.hpp"
#include "utils/path.hpp" #include "utils/path.hpp"
#include "utils/time.hpp"
#include "utils/utils.hpp" #include "utils/utils.hpp"
namespace repertory::remote_fuse { namespace repertory::remote_fuse {
@ -142,16 +143,17 @@ api_error remote_fuse_drive::fsetattr_x_impl(std::string api_path,
attributes.uid = attr->uid; attributes.uid = attr->uid;
attributes.gid = attr->gid; attributes.gid = attr->gid;
attributes.size = attr->size; attributes.size = attr->size;
attributes.acctime = attributes.acctime = ((attr->acctime.tv_sec * utils::time::NANOS_PER_SECOND) +
((attr->acctime.tv_sec * NANOS_PER_SECOND) + attr->acctime.tv_nsec); attr->acctime.tv_nsec);
attributes.modtime = attributes.modtime = ((attr->modtime.tv_sec * utils::time::NANOS_PER_SECOND) +
((attr->modtime.tv_sec * NANOS_PER_SECOND) + attr->modtime.tv_nsec); attr->modtime.tv_nsec);
attributes.crtime = attributes.crtime = ((attr->crtime.tv_sec * utils::time::NANOS_PER_SECOND) +
((attr->crtime.tv_sec * NANOS_PER_SECOND) + attr->crtime.tv_nsec); attr->crtime.tv_nsec);
attributes.chgtime = attributes.chgtime = ((attr->chgtime.tv_sec * utils::time::NANOS_PER_SECOND) +
((attr->chgtime.tv_sec * NANOS_PER_SECOND) + attr->chgtime.tv_nsec); attr->chgtime.tv_nsec);
attributes.bkuptime = attributes.bkuptime =
((attr->bkuptime.tv_sec * NANOS_PER_SECOND) + attr->bkuptime.tv_nsec); ((attr->bkuptime.tv_sec * utils::time::NANOS_PER_SECOND) +
attr->bkuptime.tv_nsec);
attributes.flags = attr->flags; attributes.flags = attr->flags;
return utils::to_api_error(remote_instance_->fuse_fsetattr_x( return utils::to_api_error(remote_instance_->fuse_fsetattr_x(
api_path.c_str(), attributes, f_info->fh)); api_path.c_str(), attributes, f_info->fh));
@ -208,10 +210,11 @@ api_error remote_fuse_drive::getxtimes_impl(std::string api_path,
api_path.c_str(), repertory_bkuptime, repertory_crtime); api_path.c_str(), repertory_bkuptime, repertory_crtime);
if (res == 0) { if (res == 0) {
bkuptime->tv_nsec = bkuptime->tv_nsec =
static_cast<long>(repertory_bkuptime % NANOS_PER_SECOND); static_cast<long>(repertory_bkuptime % utils::time::NANOS_PER_SECOND);
bkuptime->tv_sec = repertory_bkuptime / NANOS_PER_SECOND; bkuptime->tv_sec = repertory_bkuptime / utils::time::NANOS_PER_SECOND;
crtime->tv_nsec = static_cast<long>(repertory_crtime % NANOS_PER_SECOND); crtime->tv_nsec =
crtime->tv_sec = repertory_crtime / NANOS_PER_SECOND; static_cast<long>(repertory_crtime % utils::time::NANOS_PER_SECOND);
crtime->tv_sec = repertory_crtime / utils::time::NANOS_PER_SECOND;
} }
return utils::to_api_error(res); return utils::to_api_error(res);
@ -296,42 +299,51 @@ auto remote_fuse_drive::opendir_impl(
void remote_fuse_drive::populate_stat(const remote::stat &r_stat, void remote_fuse_drive::populate_stat(const remote::stat &r_stat,
bool directory, struct stat &unix_st) { bool directory, struct stat &unix_st) {
memset(&unix_st, 0, sizeof(struct stat)); std::memset(&unix_st, 0, sizeof(struct stat));
#if defined(__APPLE__) #if defined(__APPLE__)
unix_st.st_blksize = 0; unix_st.st_blksize = 0;
unix_st.st_atimespec.tv_nsec = r_stat.st_atimespec % NANOS_PER_SECOND; unix_st.st_atimespec.tv_nsec =
unix_st.st_atimespec.tv_sec = r_stat.st_atimespec / NANOS_PER_SECOND; r_stat.st_atimespec % utils::time::NANOS_PER_SECOND;
unix_st.st_atimespec.tv_sec =
r_stat.st_atimespec / utils::time::NANOS_PER_SECOND;
unix_st.st_birthtimespec.tv_nsec = r_stat.st_birthtimespec % NANOS_PER_SECOND; unix_st.st_birthtimespec.tv_nsec =
unix_st.st_birthtimespec.tv_sec = r_stat.st_birthtimespec / NANOS_PER_SECOND; r_stat.st_birthtimespec % utils::time::NANOS_PER_SECOND;
unix_st.st_birthtimespec.tv_sec =
r_stat.st_birthtimespec / utils::time::NANOS_PER_SECOND;
unix_st.st_ctimespec.tv_nsec = r_stat.st_ctimespec % NANOS_PER_SECOND; unix_st.st_ctimespec.tv_nsec =
unix_st.st_ctimespec.tv_sec = r_stat.st_ctimespec / NANOS_PER_SECOND; r_stat.st_ctimespec % utils::time::NANOS_PER_SECOND;
unix_st.st_ctimespec.tv_sec =
r_stat.st_ctimespec / utils::time::NANOS_PER_SECOND;
unix_st.st_mtimespec.tv_nsec = r_stat.st_mtimespec % NANOS_PER_SECOND; unix_st.st_mtimespec.tv_nsec =
unix_st.st_mtimespec.tv_sec = r_stat.st_mtimespec / NANOS_PER_SECOND; r_stat.st_mtimespec % utils::time::NANOS_PER_SECOND;
unix_st.st_mtimespec.tv_sec =
r_stat.st_mtimespec / utils::time::NANOS_PER_SECOND;
unix_st.st_flags = r_stat.st_flags; unix_st.st_flags = r_stat.st_flags;
#else #else // !defined(__APPLE__)
unix_st.st_blksize = 4096; unix_st.st_blksize = 4096;
unix_st.st_atim.tv_nsec = unix_st.st_atim.tv_nsec = static_cast<suseconds_t>(
static_cast<suseconds_t>(r_stat.st_atimespec % NANOS_PER_SECOND); r_stat.st_atimespec % utils::time::NANOS_PER_SECOND);
unix_st.st_atim.tv_sec = unix_st.st_atim.tv_sec = static_cast<suseconds_t>(
static_cast<suseconds_t>(r_stat.st_atimespec / NANOS_PER_SECOND); r_stat.st_atimespec / utils::time::NANOS_PER_SECOND);
unix_st.st_ctim.tv_nsec = unix_st.st_ctim.tv_nsec = static_cast<suseconds_t>(
static_cast<suseconds_t>(r_stat.st_ctimespec % NANOS_PER_SECOND); r_stat.st_ctimespec % utils::time::NANOS_PER_SECOND);
unix_st.st_ctim.tv_sec = unix_st.st_ctim.tv_sec = static_cast<suseconds_t>(
static_cast<suseconds_t>(r_stat.st_ctimespec / NANOS_PER_SECOND); r_stat.st_ctimespec / utils::time::NANOS_PER_SECOND);
unix_st.st_mtim.tv_nsec = static_cast<suseconds_t>(
r_stat.st_mtimespec % utils::time::NANOS_PER_SECOND);
unix_st.st_mtim.tv_sec = static_cast<suseconds_t>(
r_stat.st_mtimespec / utils::time::NANOS_PER_SECOND);
#endif // defined(__APPLE__)
unix_st.st_mtim.tv_nsec =
static_cast<suseconds_t>(r_stat.st_mtimespec % NANOS_PER_SECOND);
unix_st.st_mtim.tv_sec =
static_cast<suseconds_t>(r_stat.st_mtimespec / NANOS_PER_SECOND);
#endif
if (not directory) { if (not directory) {
const auto block_size_stat = static_cast<std::uint64_t>(512U); const auto block_size_stat = static_cast<std::uint64_t>(512U);
const auto block_size = static_cast<std::uint64_t>(4096U); const auto block_size = static_cast<std::uint64_t>(4096U);
@ -440,16 +452,17 @@ api_error remote_fuse_drive::setattr_x_impl(std::string api_path,
attributes.uid = attr->uid; attributes.uid = attr->uid;
attributes.gid = attr->gid; attributes.gid = attr->gid;
attributes.size = attr->size; attributes.size = attr->size;
attributes.acctime = attributes.acctime = ((attr->acctime.tv_sec * utils::time::NANOS_PER_SECOND) +
((attr->acctime.tv_sec * NANOS_PER_SECOND) + attr->acctime.tv_nsec); attr->acctime.tv_nsec);
attributes.modtime = attributes.modtime = ((attr->modtime.tv_sec * utils::time::NANOS_PER_SECOND) +
((attr->modtime.tv_sec * NANOS_PER_SECOND) + attr->modtime.tv_nsec); attr->modtime.tv_nsec);
attributes.crtime = attributes.crtime = ((attr->crtime.tv_sec * utils::time::NANOS_PER_SECOND) +
((attr->crtime.tv_sec * NANOS_PER_SECOND) + attr->crtime.tv_nsec); attr->crtime.tv_nsec);
attributes.chgtime = attributes.chgtime = ((attr->chgtime.tv_sec * utils::time::NANOS_PER_SECOND) +
((attr->chgtime.tv_sec * NANOS_PER_SECOND) + attr->chgtime.tv_nsec); attr->chgtime.tv_nsec);
attributes.bkuptime = attributes.bkuptime =
((attr->bkuptime.tv_sec * NANOS_PER_SECOND) + attr->bkuptime.tv_nsec); ((attr->bkuptime.tv_sec * utils::time::NANOS_PER_SECOND) +
attr->bkuptime.tv_nsec);
attributes.flags = attr->flags; attributes.flags = attr->flags;
return utils::to_api_error( return utils::to_api_error(
remote_instance_->fuse_setattr_x(api_path.c_str(), attributes)); remote_instance_->fuse_setattr_x(api_path.c_str(), attributes));
@ -458,7 +471,7 @@ api_error remote_fuse_drive::setattr_x_impl(std::string api_path,
api_error remote_fuse_drive::setbkuptime_impl(std::string api_path, api_error remote_fuse_drive::setbkuptime_impl(std::string api_path,
const struct timespec *bkuptime) { const struct timespec *bkuptime) {
remote::file_time repertory_bkuptime = remote::file_time repertory_bkuptime =
((bkuptime->tv_sec * NANOS_PER_SECOND) + bkuptime->tv_nsec); ((bkuptime->tv_sec * utils::time::NANOS_PER_SECOND) + bkuptime->tv_nsec);
return utils::to_api_error( return utils::to_api_error(
remote_instance_->fuse_setbkuptime(api_path.c_str(), repertory_bkuptime)); remote_instance_->fuse_setbkuptime(api_path.c_str(), repertory_bkuptime));
} }
@ -466,7 +479,7 @@ api_error remote_fuse_drive::setbkuptime_impl(std::string api_path,
api_error remote_fuse_drive::setchgtime_impl(std::string api_path, api_error remote_fuse_drive::setchgtime_impl(std::string api_path,
const struct timespec *chgtime) { const struct timespec *chgtime) {
remote::file_time repertory_chgtime = remote::file_time repertory_chgtime =
((chgtime->tv_sec * NANOS_PER_SECOND) + chgtime->tv_nsec); ((chgtime->tv_sec * utils::time::NANOS_PER_SECOND) + chgtime->tv_nsec);
return utils::to_api_error( return utils::to_api_error(
remote_instance_->fuse_setchgtime(api_path.c_str(), repertory_chgtime)); remote_instance_->fuse_setchgtime(api_path.c_str(), repertory_chgtime));
} }
@ -474,7 +487,7 @@ api_error remote_fuse_drive::setchgtime_impl(std::string api_path,
api_error remote_fuse_drive::setcrtime_impl(std::string api_path, api_error remote_fuse_drive::setcrtime_impl(std::string api_path,
const struct timespec *crtime) { const struct timespec *crtime) {
remote::file_time repertory_crtime = remote::file_time repertory_crtime =
((crtime->tv_sec * NANOS_PER_SECOND) + crtime->tv_nsec); ((crtime->tv_sec * utils::time::NANOS_PER_SECOND) + crtime->tv_nsec);
return utils::to_api_error( return utils::to_api_error(
remote_instance_->fuse_setcrtime(api_path.c_str(), repertory_crtime)); remote_instance_->fuse_setcrtime(api_path.c_str(), repertory_crtime));
} }
@ -555,10 +568,14 @@ auto remote_fuse_drive::utimens_impl(std::string api_path,
#endif #endif
remote::file_time rtv[2U] = {0}; remote::file_time rtv[2U] = {0};
if (tv != nullptr) { if (tv != nullptr) {
rtv[0U] = static_cast<remote::file_time>( const auto update_timespec = [](auto &dst, const auto &src) {
tv[0U].tv_nsec + (tv[0U].tv_sec * NANOS_PER_SECOND)); dst = static_cast<remote::file_time>(
rtv[1U] = static_cast<remote::file_time>( src.tv_nsec +
tv[1U].tv_nsec + (tv[1U].tv_sec * NANOS_PER_SECOND)); (src.tv_sec * static_cast<std::decay_t<decltype(src.tv_sec)>>(
utils::time::NANOS_PER_SECOND)));
};
update_timespec(rtv[0U], tv[0U]);
update_timespec(rtv[1U], tv[1U]);
} }
return utils::to_api_error(remote_instance_->fuse_utimens( return utils::to_api_error(remote_instance_->fuse_utimens(

View File

@ -93,9 +93,10 @@ auto remote_server::populate_file_info(const std::string &api_path,
auto error = drive_.get_item_meta(api_path, META_ATTRIBUTES, meta_attributes); auto error = drive_.get_item_meta(api_path, META_ATTRIBUTES, meta_attributes);
if (error == api_error::success) { if (error == api_error::success) {
if (meta_attributes.empty()) { if (meta_attributes.empty()) {
meta_attributes = utils::file::is_directory(construct_path(api_path)) meta_attributes =
? std::to_string(FILE_ATTRIBUTE_DIRECTORY) utils::file::directory(construct_path(api_path)).exists()
: std::to_string(FILE_ATTRIBUTE_NORMAL); ? std::to_string(FILE_ATTRIBUTE_DIRECTORY)
: std::to_string(FILE_ATTRIBUTE_NORMAL);
drive_.set_item_meta(api_path, META_ATTRIBUTES, meta_attributes); drive_.set_item_meta(api_path, META_ATTRIBUTES, meta_attributes);
} }
const auto attributes = utils::string::to_uint32(meta_attributes); const auto attributes = utils::string::to_uint32(meta_attributes);
@ -124,18 +125,18 @@ void remote_server::populate_file_info(const std::string &api_path,
file_info.AllocationSize = file_info.AllocationSize =
utils::divide_with_ceiling(file_size, WINFSP_ALLOCATION_UNIT) * utils::divide_with_ceiling(file_size, WINFSP_ALLOCATION_UNIT) *
WINFSP_ALLOCATION_UNIT; WINFSP_ALLOCATION_UNIT;
file_info.ChangeTime = utils::unix_time_to_windows_time( file_info.ChangeTime = utils::time::unix_time_to_windows_time(
utils::string::to_uint64(empty_as_zero(meta[META_MODIFIED]))); utils::string::to_uint64(empty_as_zero(meta[META_MODIFIED])));
file_info.CreationTime = utils::unix_time_to_windows_time( file_info.CreationTime = utils::time::unix_time_to_windows_time(
utils::string::to_uint64(empty_as_zero(meta[META_CREATION]))); utils::string::to_uint64(empty_as_zero(meta[META_CREATION])));
file_info.EaSize = 0; file_info.EaSize = 0;
file_info.FileAttributes = attributes; file_info.FileAttributes = attributes;
file_info.FileSize = file_size; file_info.FileSize = file_size;
file_info.HardLinks = 0; file_info.HardLinks = 0;
file_info.IndexNumber = 0; file_info.IndexNumber = 0;
file_info.LastAccessTime = utils::unix_time_to_windows_time( file_info.LastAccessTime = utils::time::unix_time_to_windows_time(
utils::string::to_uint64(empty_as_zero(meta[META_ACCESSED]))); utils::string::to_uint64(empty_as_zero(meta[META_ACCESSED])));
file_info.LastWriteTime = utils::unix_time_to_windows_time( file_info.LastWriteTime = utils::time::unix_time_to_windows_time(
utils::string::to_uint64(empty_as_zero(meta[META_WRITTEN]))); utils::string::to_uint64(empty_as_zero(meta[META_WRITTEN])));
if (meta[META_WRITTEN].empty() || (meta[META_WRITTEN] == "0") || if (meta[META_WRITTEN].empty() || (meta[META_WRITTEN] == "0") ||
(meta[META_WRITTEN] == "116444736000000000")) { (meta[META_WRITTEN] == "116444736000000000")) {
@ -147,30 +148,45 @@ void remote_server::populate_file_info(const std::string &api_path,
void remote_server::populate_stat(const struct stat64 &unix_st, void remote_server::populate_stat(const struct stat64 &unix_st,
remote::stat &r_stat) { remote::stat &r_stat) {
memset(&r_stat, 0, sizeof(r_stat)); r_stat = {};
#if defined(__APPLE__) #if defined(__APPLE__)
r_stat.st_flags = unix_st.st_flags; r_stat.st_flags = unix_st.st_flags;
r_stat.st_atimespec = unix_st.st_atimespec.tv_nsec + r_stat.st_atimespec =
(unix_st.st_atimespec.tv_sec * NANOS_PER_SECOND); unix_st.st_atimespec.tv_nsec +
(unix_st.st_atimespec.tv_sec * utils::time::NANOS_PER_SECOND);
r_stat.st_birthtimespec = r_stat.st_birthtimespec =
unix_st.st_birthtimespec.tv_nsec + unix_st.st_birthtimespec.tv_nsec +
(unix_st.st_birthtimespec.tv_sec * NANOS_PER_SECOND); (unix_st.st_birthtimespec.tv_sec * utils::time::NANOS_PER_SECOND);
r_stat.st_ctimespec = unix_st.st_ctimespec.tv_nsec + r_stat.st_ctimespec =
(unix_st.st_ctimespec.tv_sec * NANOS_PER_SECOND); unix_st.st_ctimespec.tv_nsec +
r_stat.st_mtimespec = unix_st.st_mtimespec.tv_nsec + (unix_st.st_ctimespec.tv_sec * utils::time::NANOS_PER_SECOND);
(unix_st.st_mtimespec.tv_sec * NANOS_PER_SECOND); r_stat.st_mtimespec =
unix_st.st_mtimespec.tv_nsec +
(unix_st.st_mtimespec.tv_sec * utils::time::NANOS_PER_SECOND);
#else // !defined(__APPLE__) #else // !defined(__APPLE__)
r_stat.st_flags = 0; r_stat.st_flags = 0;
r_stat.st_atimespec = static_cast<remote::file_time>( r_stat.st_atimespec =
unix_st.st_atim.tv_nsec + (unix_st.st_atim.tv_sec * NANOS_PER_SECOND)); static_cast<remote::file_time>(unix_st.st_atim.tv_nsec) +
r_stat.st_birthtimespec = static_cast<remote::file_time>( (static_cast<remote::file_time>(unix_st.st_atim.tv_sec) *
unix_st.st_ctim.tv_nsec + (unix_st.st_ctim.tv_sec * NANOS_PER_SECOND)); utils::time::NANOS_PER_SECOND);
r_stat.st_ctimespec = static_cast<remote::file_time>(
unix_st.st_ctim.tv_nsec + (unix_st.st_ctim.tv_sec * NANOS_PER_SECOND)); r_stat.st_birthtimespec =
r_stat.st_mtimespec = static_cast<remote::file_time>( static_cast<remote::file_time>(unix_st.st_ctim.tv_nsec) +
unix_st.st_mtim.tv_nsec + (unix_st.st_mtim.tv_sec * NANOS_PER_SECOND)); (static_cast<remote::file_time>(unix_st.st_ctim.tv_sec) *
utils::time::NANOS_PER_SECOND);
r_stat.st_ctimespec =
static_cast<remote::file_time>(unix_st.st_ctim.tv_nsec) +
(static_cast<remote::file_time>(unix_st.st_ctim.tv_sec) *
utils::time::NANOS_PER_SECOND);
r_stat.st_mtimespec =
static_cast<remote::file_time>(unix_st.st_mtim.tv_nsec) +
(static_cast<remote::file_time>(unix_st.st_mtim.tv_sec) *
utils::time::NANOS_PER_SECOND);
#endif // defined(__APPLE__) #endif // defined(__APPLE__)
r_stat.st_blksize = static_cast<remote::block_size>(unix_st.st_blksize); r_stat.st_blksize = static_cast<remote::block_size>(unix_st.st_blksize);
r_stat.st_blocks = static_cast<remote::block_count>(unix_st.st_blocks); r_stat.st_blocks = static_cast<remote::block_count>(unix_st.st_blocks);
@ -319,12 +335,13 @@ auto remote_server::fuse_fgetattr(
static_cast<const char *>(__FUNCTION__), static_cast<const char *>(__FUNCTION__),
}; };
r_stat = {};
const auto file_path = construct_path(path); const auto file_path = construct_path(path);
memset(&r_stat, 0, sizeof(remote::stat));
auto res = has_open_info(static_cast<native_handle>(handle), EBADF); auto res = has_open_info(static_cast<native_handle>(handle), EBADF);
if (res == 0) { if (res == 0) {
directory = utils::file::is_directory(file_path); directory = utils::file::directory(file_path).exists();
struct stat64 unix_st {}; struct stat64 unix_st {};
res = fstat64(static_cast<native_handle>(handle), &unix_st); res = fstat64(static_cast<native_handle>(handle), &unix_st);
if (res == 0) { if (res == 0) {
@ -405,16 +422,18 @@ auto remote_server::fuse_fsetattr_x(
if (SETATTR_WANTS_MODTIME(&attr)) { if (SETATTR_WANTS_MODTIME(&attr)) {
struct timeval val[2]; struct timeval val[2];
if (SETATTR_WANTS_ACCTIME(&attr)) { if (SETATTR_WANTS_ACCTIME(&attr)) {
val[0U].tv_sec = static_cast<time_t>(attr.acctime / NANOS_PER_SECOND); val[0U].tv_sec =
val[0U].tv_usec = static_cast<time_t>(attr.acctime / utils::time::NANOS_PER_SECOND);
static_cast<time_t>((attr.acctime % NANOS_PER_SECOND) / 1000); val[0U].tv_usec = static_cast<time_t>(
(attr.acctime % utils::time::NANOS_PER_SECOND) / 1000);
} else { } else {
gettimeofday(&val[0U], nullptr); gettimeofday(&val[0U], nullptr);
} }
val[1U].tv_sec = static_cast<time_t>(attr.modtime / NANOS_PER_SECOND); val[1U].tv_sec =
val[1U].tv_usec = static_cast<time_t>(attr.modtime / utils::time::NANOS_PER_SECOND);
static_cast<time_t>((attr.modtime % NANOS_PER_SECOND) / 1000); val[1U].tv_usec = static_cast<time_t>(
(attr.modtime % utils::time::NANOS_PER_SECOND) / 1000);
res = utimes(file_path.c_str(), &val[0U]); res = utimes(file_path.c_str(), &val[0U]);
} }
@ -486,9 +505,10 @@ auto remote_server::fuse_getattr(const char *path, remote::stat &r_stat,
const auto api_path = utils::path::create_api_path(path); const auto api_path = utils::path::create_api_path(path);
const auto file_path = construct_path(api_path); const auto file_path = construct_path(api_path);
const auto parent_api_path = utils::path::get_parent_api_path(api_path); const auto parent_api_path = utils::path::get_parent_api_path(api_path);
memset(&r_stat, 0, sizeof(remote::stat));
directory = utils::file::is_directory(file_path); r_stat = {};
directory = utils::file::directory(file_path).exists();
struct stat64 unix_st {}; struct stat64 unix_st {};
auto res = stat64(file_path.c_str(), &unix_st); auto res = stat64(file_path.c_str(), &unix_st);
@ -651,7 +671,7 @@ auto remote_server::fuse_opendir(const char *path, remote::file_handle &handle)
auto res = -1; auto res = -1;
errno = ENOENT; errno = ENOENT;
if (utils::file::is_directory(file_path)) { if (utils::file::directory(file_path).exists()) {
auto iter = std::make_shared<directory_iterator>( auto iter = std::make_shared<directory_iterator>(
drive_.get_directory_items(utils::path::create_api_path(path))); drive_.get_directory_items(utils::path::create_api_path(path)));
@ -949,10 +969,10 @@ auto remote_server::fuse_statfs_x(const char *path, std::uint64_t bsize,
r_stat.f_blocks ? (r_stat.f_blocks - used_blocks) : 0; r_stat.f_blocks ? (r_stat.f_blocks - used_blocks) : 0;
r_stat.f_ffree = r_stat.f_favail = r_stat.f_ffree = r_stat.f_favail =
r_stat.f_files - drive_.get_total_item_count(); r_stat.f_files - drive_.get_total_item_count();
std::memset(&r_stat.f_mntfromname[0U], 0, sizeof(r_stat.f_mntfromname)); std::memset(r_stat.f_mntfromname.data(), 0, r_stat.f_mntfromname.size());
strncpy(&r_stat.f_mntfromname[0U], strncpy(r_stat.f_mntfromname.data(),
(utils::create_volume_label(config_.get_provider_type())).c_str(), (utils::create_volume_label(config_.get_provider_type())).c_str(),
sizeof(r_stat.f_mntfromname) - 1U); r_stat.f_mntfromname.size() - 1U);
RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, 0); RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, 0);
return 0; return 0;
@ -993,21 +1013,19 @@ auto remote_server::fuse_utimens(const char *path, const remote::file_time *tv,
const auto file_path = construct_path(path); const auto file_path = construct_path(path);
struct timespec tv2[2] = {{0, 0}}; struct timespec tv2[2] = {{0, 0}};
if ((op0 == UTIME_NOW) || (op0 == UTIME_OMIT)) { const auto process_timespec = [](auto op, const auto &src, auto &dst) {
tv2[0U].tv_nsec = static_cast<time_t>(op0); if ((op == UTIME_NOW) || (op == UTIME_OMIT)) {
tv2[0U].tv_sec = 0; dst.tv_nsec = static_cast<time_t>(op);
} else { dst.tv_sec = 0;
tv2[0U].tv_nsec = static_cast<time_t>(tv[0U] % NANOS_PER_SECOND); return;
tv2[0U].tv_sec = static_cast<time_t>(tv[0U] / NANOS_PER_SECOND); }
}
if ((op1 == UTIME_NOW) || (op1 == UTIME_OMIT)) { dst.tv_nsec = static_cast<time_t>(src % utils::time::NANOS_PER_SECOND);
tv2[1U].tv_nsec = static_cast<time_t>(op1); dst.tv_sec = static_cast<time_t>(src / utils::time::NANOS_PER_SECOND);
tv2[1U].tv_sec = 0; };
} else {
tv2[1U].tv_nsec = static_cast<time_t>(tv[1U] % NANOS_PER_SECOND); process_timespec(op0, tv[0U], tv2[0U]);
tv2[1U].tv_sec = static_cast<time_t>(tv[1U] / NANOS_PER_SECOND); process_timespec(op1, tv[1U], tv2[1U]);
}
const auto res = const auto res =
utimensat(0, file_path.c_str(), &tv2[0U], AT_SYMLINK_NOFOLLOW); utimensat(0, file_path.c_str(), &tv2[0U], AT_SYMLINK_NOFOLLOW);
@ -1065,7 +1083,7 @@ auto remote_server::winfsp_can_delete(PVOID file_desc,
STATUS_INVALID_HANDLE)); STATUS_INVALID_HANDLE));
if (ret == STATUS_SUCCESS) { if (ret == STATUS_SUCCESS) {
ret = static_cast<packet::error_type>( ret = static_cast<packet::error_type>(
utils::file::is_directory(file_path) utils::file::directory(file_path).exists()
? drive_.get_directory_item_count( ? drive_.get_directory_item_count(
utils::path::create_api_path(relative_path)) utils::path::create_api_path(relative_path))
? STATUS_DIRECTORY_NOT_EMPTY ? STATUS_DIRECTORY_NOT_EMPTY
@ -1090,7 +1108,7 @@ auto remote_server::winfsp_cleanup(PVOID /*file_desc*/, PWSTR file_name,
const auto file_path = construct_path(relative_path); const auto file_path = construct_path(relative_path);
was_closed = 0; was_closed = 0;
const auto directory = utils::file::is_directory(file_path); const auto directory = utils::file::directory(file_path).exists();
if (flags & FileSystemBase::FspCleanupDelete) { if (flags & FileSystemBase::FspCleanupDelete) {
remove_all(file_path); remove_all(file_path);
was_closed = 1; was_closed = 1;
@ -1170,7 +1188,7 @@ auto remote_server::winfsp_create(PWSTR file_name, UINT32 create_options,
const auto relative_path = utils::string::to_utf8(file_name); const auto relative_path = utils::string::to_utf8(file_name);
const auto file_path = construct_path(relative_path); const auto file_path = construct_path(relative_path);
exists = utils::file::is_file(file_path); exists = utils::file::file(file_path).exists();
if ((create_options & FILE_DIRECTORY_FILE) != 0U) { if ((create_options & FILE_DIRECTORY_FILE) != 0U) {
attributes |= FILE_ATTRIBUTE_DIRECTORY; attributes |= FILE_ATTRIBUTE_DIRECTORY;
@ -1268,8 +1286,8 @@ auto remote_server::winfsp_get_security_by_name(
auto ret = static_cast<packet::error_type>(STATUS_SUCCESS); auto ret = static_cast<packet::error_type>(STATUS_SUCCESS);
const auto file_path = construct_path(file_name); const auto file_path = construct_path(file_name);
if (utils::file::is_file(file_path) || if (utils::file::file(file_path).exists() ||
(utils::file::is_directory(file_path))) { (utils::file::directory(file_path).exists())) {
if (attributes) { if (attributes) {
remote::file_info file_info{}; remote::file_info file_info{};
if ((ret = populate_file_info(construct_api_path(file_path), if ((ret = populate_file_info(construct_api_path(file_path),
@ -1318,7 +1336,7 @@ auto remote_server::winfsp_open(
const auto relative_path = utils::string::to_utf8(file_name); const auto relative_path = utils::string::to_utf8(file_name);
const auto file_path = construct_path(relative_path); const auto file_path = construct_path(relative_path);
const auto directory = utils::file::is_directory(file_path); const auto directory = utils::file::directory(file_path).exists();
if (directory) { if (directory) {
create_options |= FILE_DIRECTORY_FILE; create_options |= FILE_DIRECTORY_FILE;
} }
@ -1489,11 +1507,11 @@ auto remote_server::winfsp_rename(
auto res = -1; auto res = -1;
errno = ENOENT; errno = ENOENT;
if (utils::file::is_file(file_path)) { if (utils::file::file(file_path).exists()) {
res = drive_.rename_file(construct_api_path(file_path), res = drive_.rename_file(construct_api_path(file_path),
construct_api_path(new_file_path), construct_api_path(new_file_path),
replace_if_exists != 0U); replace_if_exists != 0U);
} else if (utils::file::is_directory(file_path)) { } else if (utils::file::directory(file_path).exists()) {
res = drive_.rename_directory(construct_api_path(file_path), res = drive_.rename_directory(construct_api_path(file_path),
construct_api_path(new_file_path)); construct_api_path(new_file_path));
} }
@ -1523,7 +1541,7 @@ auto remote_server::winfsp_set_basic_info(
if (attributes == INVALID_FILE_ATTRIBUTES) { if (attributes == INVALID_FILE_ATTRIBUTES) {
attributes = 0; attributes = 0;
} else if (attributes == 0) { } else if (attributes == 0) {
attributes = utils::file::is_directory(file_path) attributes = utils::file::directory(file_path).exists()
? FILE_ATTRIBUTE_DIRECTORY ? FILE_ATTRIBUTE_DIRECTORY
: FILE_ATTRIBUTE_NORMAL; : FILE_ATTRIBUTE_NORMAL;
} }
@ -1542,25 +1560,28 @@ auto remote_server::winfsp_set_basic_info(
if ((creation_time != 0U) && (creation_time != max_time)) { if ((creation_time != 0U) && (creation_time != max_time)) {
drive_.set_item_meta( drive_.set_item_meta(
api_path, META_CREATION, api_path, META_CREATION,
std::to_string(utils::windows_time_to_unix_time(creation_time))); std::to_string(
utils::time::windows_time_to_unix_time(creation_time)));
} }
if ((last_access_time != 0U) && (last_access_time != max_time)) { if ((last_access_time != 0U) && (last_access_time != max_time)) {
drive_.set_item_meta( drive_.set_item_meta(
api_path, META_ACCESSED, api_path, META_ACCESSED,
std::to_string(utils::windows_time_to_unix_time(last_access_time))); std::to_string(
utils::time::windows_time_to_unix_time(last_access_time)));
} }
if ((last_write_time != 0U) && (last_write_time != max_time)) { if ((last_write_time != 0U) && (last_write_time != max_time)) {
drive_.set_item_meta( drive_.set_item_meta(
api_path, META_WRITTEN, api_path, META_WRITTEN,
std::to_string(utils::windows_time_to_unix_time(last_write_time))); std::to_string(
utils::time::windows_time_to_unix_time(last_write_time)));
} }
if ((change_time != 0U) && (change_time != max_time)) { if ((change_time != 0U) && (change_time != max_time)) {
drive_.set_item_meta( drive_.set_item_meta(
api_path, META_MODIFIED, api_path, META_MODIFIED,
std::to_string(utils::windows_time_to_unix_time(change_time))); std::to_string(utils::time::windows_time_to_unix_time(change_time)));
} }
ret = populate_file_info(api_path, *file_info); ret = populate_file_info(api_path, *file_info);
@ -1679,7 +1700,7 @@ auto remote_server::json_create_directory_snapshot(
auto res = -1; auto res = -1;
errno = ENOENT; errno = ENOENT;
if (utils::file::is_directory(file_path)) { if (utils::file::directory(file_path).exists()) {
auto iter = std::make_shared<directory_iterator>( auto iter = std::make_shared<directory_iterator>(
drive_.get_directory_items(api_path)); drive_.get_directory_items(api_path));
auto handle = get_next_handle(); auto handle = get_next_handle();
@ -1745,12 +1766,22 @@ auto remote_server::json_release_directory_snapshot(
auto remote_server::update_to_windows_format(json &item) -> json & { auto remote_server::update_to_windows_format(json &item) -> json & {
const auto api_path = item["path"].get<std::string>(); const auto api_path = item["path"].get<std::string>();
item["meta"][META_MODIFIED] = std::to_string(utils::unix_time_to_windows_time( item["meta"][META_ACCESSED] = std::to_string(
utils::string::to_uint64(empty_as_zero(item["meta"][META_MODIFIED])))); utils::string::to_uint64(empty_as_zero(item["meta"][META_ACCESSED])));
item["meta"][META_CREATION] = std::to_string(utils::unix_time_to_windows_time( item["meta"][META_CREATION] = std::to_string(
utils::string::to_uint64(empty_as_zero(item["meta"][META_CREATION])))); utils::string::to_uint64(empty_as_zero(item["meta"][META_CREATION])));
item["meta"][META_ACCESSED] = std::to_string(utils::unix_time_to_windows_time( item["meta"][META_MODIFIED] = std::to_string(
utils::string::to_uint64(empty_as_zero(item["meta"][META_ACCESSED])))); utils::string::to_uint64(empty_as_zero(item["meta"][META_MODIFIED])));
if (item["meta"][META_WRITTEN].empty() ||
(item["meta"][META_WRITTEN].get<std::string>() == "0") ||
(item["meta"][META_WRITTEN].get<std::string>() ==
std::to_string(utils::time::WIN32_TIME_CONVERSION))) {
drive_.set_item_meta(api_path, META_WRITTEN,
item["meta"][META_MODIFIED].get<std::string>());
item["meta"][META_WRITTEN] = item["meta"][META_MODIFIED];
}
if (item["meta"][META_ATTRIBUTES].empty()) { if (item["meta"][META_ATTRIBUTES].empty()) {
item["meta"][META_ATTRIBUTES] = item["meta"][META_ATTRIBUTES] =
item["directory"].get<bool>() ? std::to_string(FILE_ATTRIBUTE_DIRECTORY) item["directory"].get<bool>() ? std::to_string(FILE_ATTRIBUTE_DIRECTORY)
@ -1759,19 +1790,6 @@ auto remote_server::update_to_windows_format(json &item) -> json & {
item["meta"][META_ATTRIBUTES].get<std::string>()); item["meta"][META_ATTRIBUTES].get<std::string>());
} }
if (item["meta"][META_WRITTEN].empty() ||
(item["meta"][META_WRITTEN].get<std::string>() == "0") ||
(item["meta"][META_WRITTEN].get<std::string>() == "116444736000000000")) {
drive_.set_item_meta(api_path, META_WRITTEN,
item["meta"][META_MODIFIED].get<std::string>());
item["meta"][META_WRITTEN] = std::to_string(
utils::unix_time_to_windows_time(utils::string::to_uint64(
empty_as_zero(item["meta"][META_MODIFIED]))));
} else {
item["meta"][META_WRITTEN] = std::to_string(
utils::unix_time_to_windows_time(utils::string::to_uint64(
empty_as_zero(item["meta"][META_WRITTEN]))));
}
return item; return item;
} }
} // namespace repertory::remote_fuse } // namespace repertory::remote_fuse

View File

@ -39,14 +39,14 @@ void remote_open_file_table::add_directory(const std::string &client_id,
void remote_open_file_table::close_all(const std::string &client_id) { void remote_open_file_table::close_all(const std::string &client_id) {
std::vector<remote::file_handle> compat_handles; std::vector<remote::file_handle> compat_handles;
unique_recur_mutex_lock compat_lock(compat_mutex_); unique_recur_mutex_lock compat_lock(compat_mutex_);
for (auto &kv : compat_lookup_) { for (auto &&kv : compat_lookup_) {
if (kv.second.client_id == client_id) { if (kv.second.client_id == client_id) {
compat_handles.emplace_back(kv.first); compat_handles.emplace_back(kv.first);
} }
} }
compat_lock.unlock(); compat_lock.unlock();
for (auto &handle : compat_handles) { for (auto &&handle : compat_handles) {
#if defined(_WIN32) #if defined(_WIN32)
_close(static_cast<int>(handle)); _close(static_cast<int>(handle));
#else #else
@ -57,14 +57,14 @@ void remote_open_file_table::close_all(const std::string &client_id) {
std::vector<native_handle> handles; std::vector<native_handle> handles;
unique_recur_mutex_lock file_lock(file_mutex_); unique_recur_mutex_lock file_lock(file_mutex_);
for (auto &kv : file_lookup_) { for (auto &&kv : file_lookup_) {
if (kv.second.client_id == client_id) { if (kv.second.client_id == client_id) {
handles.emplace_back(kv.first); handles.emplace_back(kv.first);
} }
} }
file_lock.unlock(); file_lock.unlock();
for (auto &handle : handles) { for (auto &&handle : handles) {
#if defined(_WIN32) #if defined(_WIN32)
::CloseHandle(handle); ::CloseHandle(handle);
#else #else
@ -75,7 +75,7 @@ void remote_open_file_table::close_all(const std::string &client_id) {
std::vector<std::uint64_t> dirs; std::vector<std::uint64_t> dirs;
unique_recur_mutex_lock directory_lock(directory_mutex_); unique_recur_mutex_lock directory_lock(directory_mutex_);
for (auto &kv : directory_lookup_) { for (auto &&kv : directory_lookup_) {
if (kv.first == client_id) { if (kv.first == client_id) {
dirs.insert(dirs.end(), kv.second.begin(), kv.second.end()); dirs.insert(dirs.end(), kv.second.begin(), kv.second.end());
} }
@ -183,11 +183,11 @@ void remote_open_file_table::remove_all(const std::string &file_path) {
}); });
file_lock.unlock(); file_lock.unlock();
for (auto &handle : open_list) { for (auto &&handle : open_list) {
remove_open_info(handle); remove_open_info(handle);
} }
for (auto &handle : compat_open_list) { for (auto &&handle : compat_open_list) {
remove_compat_open_info(handle); remove_compat_open_info(handle);
} }
} }

View File

@ -65,7 +65,10 @@ auto remote_client::winfsp_can_delete(PVOID file_desc,
request.encode(file_name); request.encode(file_name);
std::uint32_t service_flags{}; std::uint32_t service_flags{};
const auto ret = packet_client_.send(function_name, request, service_flags); auto ret{
packet_client_.send(function_name, request, service_flags),
};
RAISE_REMOTE_WINFSP_CLIENT_EVENT( RAISE_REMOTE_WINFSP_CLIENT_EVENT(
function_name, function_name,
utils::path::create_api_path(utils::string::to_utf8(file_name)), ret); utils::path::create_api_path(utils::string::to_utf8(file_name)), ret);
@ -83,8 +86,9 @@ auto remote_client::json_create_directory_snapshot(
packet response; packet response;
std::uint32_t service_flags{}; std::uint32_t service_flags{};
auto ret = auto ret{
packet_client_.send(function_name, request, response, service_flags); packet_client_.send(function_name, request, response, service_flags),
};
if (ret == 0) { if (ret == 0) {
ret = packet::decode_json(response, json_data); ret = packet::decode_json(response, json_data);
} }
@ -107,8 +111,9 @@ auto remote_client::json_read_directory_snapshot(
packet response; packet response;
std::uint32_t service_flags{}; std::uint32_t service_flags{};
auto ret = auto ret{
packet_client_.send(function_name, request, response, service_flags); packet_client_.send(function_name, request, response, service_flags),
};
if (ret == 0) { if (ret == 0) {
ret = packet::decode_json(response, json_data); ret = packet::decode_json(response, json_data);
} }
@ -129,7 +134,9 @@ auto remote_client::json_release_directory_snapshot(
request.encode(handle); request.encode(handle);
std::uint32_t service_flags{}; std::uint32_t service_flags{};
const auto ret = packet_client_.send(function_name, request, service_flags); auto ret{
packet_client_.send(function_name, request, service_flags),
};
RAISE_REMOTE_WINFSP_CLIENT_EVENT(function_name, path, ret); RAISE_REMOTE_WINFSP_CLIENT_EVENT(function_name, path, ret);
return ret; return ret;
@ -142,8 +149,14 @@ auto remote_client::winfsp_cleanup(PVOID file_desc, PWSTR file_name,
static_cast<const char *>(__FUNCTION__), static_cast<const char *>(__FUNCTION__),
}; };
auto handle = to_handle(file_desc); auto handle{
const auto file_path = get_open_file_path(handle); to_handle(file_desc),
};
auto file_path{
get_open_file_path(handle),
};
was_closed = 0; was_closed = 0;
packet request; packet request;
@ -153,8 +166,9 @@ auto remote_client::winfsp_cleanup(PVOID file_desc, PWSTR file_name,
packet response; packet response;
std::uint32_t service_flags{}; std::uint32_t service_flags{};
auto ret = auto ret{
packet_client_.send(function_name, request, response, service_flags); packet_client_.send(function_name, request, response, service_flags),
};
DECODE_OR_IGNORE(&response, was_closed); DECODE_OR_IGNORE(&response, was_closed);
if (was_closed != 0U) { if (was_closed != 0U) {
remove_all(file_path); remove_all(file_path);
@ -168,15 +182,21 @@ auto remote_client::winfsp_close(PVOID file_desc) -> packet::error_type {
static_cast<const char *>(__FUNCTION__), static_cast<const char *>(__FUNCTION__),
}; };
auto handle = to_handle(file_desc); auto handle{
to_handle(file_desc),
};
if (has_open_info(handle, STATUS_INVALID_HANDLE) == STATUS_SUCCESS) { if (has_open_info(handle, STATUS_INVALID_HANDLE) == STATUS_SUCCESS) {
const auto file_path = get_open_file_path(handle); auto file_path{
get_open_file_path(handle),
};
packet request; packet request;
request.encode(file_desc); request.encode(file_desc);
std::uint32_t service_flags{}; std::uint32_t service_flags{};
const auto ret = packet_client_.send(function_name, request, service_flags); auto ret{
packet_client_.send(function_name, request, service_flags),
};
if ((ret == STATUS_SUCCESS) || if ((ret == STATUS_SUCCESS) ||
(ret == static_cast<packet::error_type>(STATUS_INVALID_HANDLE))) { (ret == static_cast<packet::error_type>(STATUS_INVALID_HANDLE))) {
remove_open_info(handle); remove_open_info(handle);
@ -206,8 +226,9 @@ auto remote_client::winfsp_create(PWSTR file_name, UINT32 create_options,
packet response; packet response;
std::uint32_t service_flags{}; std::uint32_t service_flags{};
auto ret = auto ret{
packet_client_.send(function_name, request, response, service_flags); packet_client_.send(function_name, request, response, service_flags),
};
if (ret == STATUS_SUCCESS) { if (ret == STATUS_SUCCESS) {
HANDLE handle{}; HANDLE handle{};
DECODE_OR_IGNORE(&response, handle); DECODE_OR_IGNORE(&response, handle);
@ -243,8 +264,9 @@ auto remote_client::winfsp_flush(PVOID file_desc, remote::file_info *file_info)
packet response; packet response;
std::uint32_t service_flags{}; std::uint32_t service_flags{};
auto ret = auto ret{
packet_client_.send(function_name, request, response, service_flags); packet_client_.send(function_name, request, response, service_flags),
};
DECODE_OR_IGNORE(&response, *file_info); DECODE_OR_IGNORE(&response, *file_info);
RAISE_REMOTE_WINFSP_CLIENT_EVENT( RAISE_REMOTE_WINFSP_CLIENT_EVENT(
@ -274,8 +296,9 @@ auto remote_client::winfsp_get_file_info(
packet response; packet response;
std::uint32_t service_flags{}; std::uint32_t service_flags{};
auto ret = auto ret{
packet_client_.send(function_name, request, response, service_flags); packet_client_.send(function_name, request, response, service_flags),
};
DECODE_OR_IGNORE(&response, *file_info); DECODE_OR_IGNORE(&response, *file_info);
RAISE_REMOTE_WINFSP_CLIENT_EVENT( RAISE_REMOTE_WINFSP_CLIENT_EVENT(
@ -298,8 +321,9 @@ auto remote_client::winfsp_get_security_by_name(
packet response; packet response;
std::uint32_t service_flags{}; std::uint32_t service_flags{};
auto ret = auto ret{
packet_client_.send(function_name, request, response, service_flags); packet_client_.send(function_name, request, response, service_flags),
};
string_descriptor.clear(); string_descriptor.clear();
DECODE_OR_IGNORE(&response, string_descriptor); DECODE_OR_IGNORE(&response, string_descriptor);
@ -326,8 +350,9 @@ auto remote_client::winfsp_get_volume_info(
packet request; packet request;
packet response; packet response;
std::uint32_t service_flags{}; std::uint32_t service_flags{};
auto ret = auto ret{
packet_client_.send(function_name, request, response, service_flags); packet_client_.send(function_name, request, response, service_flags),
};
DECODE_OR_IGNORE(&response, total_size); DECODE_OR_IGNORE(&response, total_size);
DECODE_OR_IGNORE(&response, free_size); DECODE_OR_IGNORE(&response, free_size);
DECODE_OR_IGNORE(&response, volume_label); DECODE_OR_IGNORE(&response, volume_label);
@ -346,8 +371,13 @@ auto remote_client::winfsp_mounted(const std::wstring &location)
request.encode(location); request.encode(location);
std::uint32_t service_flags{}; std::uint32_t service_flags{};
const auto ret = packet_client_.send(function_name, request, service_flags); auto ret{
const auto mount_location = utils::string::to_utf8(location); packet_client_.send(function_name, request, service_flags),
};
auto mount_location{
utils::string::to_utf8(location),
};
event_system::instance().raise<drive_mounted>(mount_location); event_system::instance().raise<drive_mounted>(mount_location);
RAISE_REMOTE_WINFSP_CLIENT_EVENT(function_name, mount_location, ret); RAISE_REMOTE_WINFSP_CLIENT_EVENT(function_name, mount_location, ret);
@ -369,8 +399,9 @@ auto remote_client::winfsp_open(
packet response; packet response;
std::uint32_t service_flags{}; std::uint32_t service_flags{};
auto ret = auto ret{
packet_client_.send(function_name, request, response, service_flags); packet_client_.send(function_name, request, response, service_flags),
};
if (ret == STATUS_SUCCESS) { if (ret == STATUS_SUCCESS) {
HANDLE handle{}; HANDLE handle{};
DECODE_OR_IGNORE(&response, handle); DECODE_OR_IGNORE(&response, handle);
@ -406,8 +437,9 @@ auto remote_client::winfsp_overwrite(
packet response; packet response;
std::uint32_t service_flags{}; std::uint32_t service_flags{};
auto ret = auto ret{
packet_client_.send(function_name, request, response, service_flags); packet_client_.send(function_name, request, response, service_flags),
};
DECODE_OR_IGNORE(&response, *file_info); DECODE_OR_IGNORE(&response, *file_info);
RAISE_REMOTE_WINFSP_CLIENT_EVENT( RAISE_REMOTE_WINFSP_CLIENT_EVENT(
@ -429,8 +461,9 @@ auto remote_client::winfsp_read(PVOID file_desc, PVOID buffer, UINT64 offset,
packet response; packet response;
std::uint32_t service_flags{}; std::uint32_t service_flags{};
auto ret = auto ret{
packet_client_.send(function_name, request, response, service_flags); packet_client_.send(function_name, request, response, service_flags),
};
DECODE_OR_IGNORE(&response, *bytes_transferred); DECODE_OR_IGNORE(&response, *bytes_transferred);
if (ret == STATUS_SUCCESS) { if (ret == STATUS_SUCCESS) {
ret = response.decode(buffer, *bytes_transferred); ret = response.decode(buffer, *bytes_transferred);
@ -464,8 +497,9 @@ auto remote_client::winfsp_read_directory(PVOID file_desc, PWSTR pattern,
packet response; packet response;
std::uint32_t service_flags{}; std::uint32_t service_flags{};
auto ret = auto ret{
packet_client_.send(function_name, request, response, service_flags); packet_client_.send(function_name, request, response, service_flags),
};
if (ret == STATUS_SUCCESS) { if (ret == STATUS_SUCCESS) {
ret = packet::decode_json(response, item_list); ret = packet::decode_json(response, item_list);
} }
@ -489,7 +523,10 @@ auto remote_client::winfsp_rename(
request.encode(replace_if_exists); request.encode(replace_if_exists);
std::uint32_t service_flags{}; std::uint32_t service_flags{};
const auto ret = packet_client_.send(function_name, request, service_flags); auto ret{
packet_client_.send(function_name, request, service_flags),
};
RAISE_REMOTE_WINFSP_CLIENT_EVENT( RAISE_REMOTE_WINFSP_CLIENT_EVENT(
function_name, function_name,
utils::path::create_api_path(utils::string::to_utf8(file_name)) + "|" + utils::path::create_api_path(utils::string::to_utf8(file_name)) + "|" +
@ -516,8 +553,9 @@ auto remote_client::winfsp_set_basic_info(
packet response; packet response;
std::uint32_t service_flags{}; std::uint32_t service_flags{};
auto ret = auto ret{
packet_client_.send(function_name, request, response, service_flags); packet_client_.send(function_name, request, response, service_flags),
};
DECODE_OR_IGNORE(&response, *file_info); DECODE_OR_IGNORE(&response, *file_info);
RAISE_REMOTE_WINFSP_CLIENT_EVENT( RAISE_REMOTE_WINFSP_CLIENT_EVENT(
@ -539,8 +577,9 @@ auto remote_client::winfsp_set_file_size(
packet response; packet response;
std::uint32_t service_flags{}; std::uint32_t service_flags{};
auto ret = auto ret{
packet_client_.send(function_name, request, response, service_flags); packet_client_.send(function_name, request, response, service_flags),
};
DECODE_OR_IGNORE(&response, *file_info); DECODE_OR_IGNORE(&response, *file_info);
RAISE_REMOTE_WINFSP_CLIENT_EVENT( RAISE_REMOTE_WINFSP_CLIENT_EVENT(
@ -554,13 +593,17 @@ auto remote_client::winfsp_unmounted(const std::wstring &location)
static_cast<const char *>(__FUNCTION__), static_cast<const char *>(__FUNCTION__),
}; };
const auto mount_location = utils::string::to_utf8(location); auto mount_location{
utils::string::to_utf8(location),
};
event_system::instance().raise<drive_unmount_pending>(mount_location); event_system::instance().raise<drive_unmount_pending>(mount_location);
packet request; packet request;
request.encode(location); request.encode(location);
std::uint32_t service_flags{}; std::uint32_t service_flags{};
const auto ret = packet_client_.send(function_name, request, service_flags); auto ret{
packet_client_.send(function_name, request, service_flags),
};
event_system::instance().raise<drive_unmounted>(mount_location); event_system::instance().raise<drive_unmounted>(mount_location);
RAISE_REMOTE_WINFSP_CLIENT_EVENT(function_name, mount_location, ret); RAISE_REMOTE_WINFSP_CLIENT_EVENT(function_name, mount_location, ret);
@ -587,8 +630,9 @@ auto remote_client::winfsp_write(
packet response; packet response;
std::uint32_t service_flags{}; std::uint32_t service_flags{};
auto ret = auto ret{
packet_client_.send(function_name, request, response, service_flags); packet_client_.send(function_name, request, response, service_flags),
};
DECODE_OR_IGNORE(&response, *bytes_transferred); DECODE_OR_IGNORE(&response, *bytes_transferred);
DECODE_OR_IGNORE(&response, *file_info); DECODE_OR_IGNORE(&response, *file_info);
@ -603,5 +647,5 @@ auto remote_client::winfsp_write(
auto remote_client::to_handle(PVOID file_desc) -> native_handle { auto remote_client::to_handle(PVOID file_desc) -> native_handle {
return static_cast<native_handle>(reinterpret_cast<std::uint64_t>(file_desc)); return static_cast<native_handle>(reinterpret_cast<std::uint64_t>(file_desc));
} }
#endif #endif // !defined(_WIN32)
} // namespace repertory::remote_winfsp } // namespace repertory::remote_winfsp

View File

@ -38,18 +38,11 @@
#include "types/remote.hpp" #include "types/remote.hpp"
#include "types/repertory.hpp" #include "types/repertory.hpp"
#include "utils/common.hpp" #include "utils/common.hpp"
#include "utils/file.hpp"
#include "utils/file_utils.hpp" #include "utils/file_utils.hpp"
#include "utils/path.hpp" #include "utils/path.hpp"
#include "utils/time.hpp" #include "utils/time.hpp"
#if !defined(_SH_DENYNO)
#define _SH_DENYRW 0x10 // deny read/write mode
#define _SH_DENYWR 0x20 // deny write mode
#define _SH_DENYRD 0x30 // deny read mode
#define _SH_DENYNO 0x40 // deny none mode
#define _SH_SECURE 0x80 // secure mode
#endif
namespace repertory::remote_winfsp { namespace repertory::remote_winfsp {
#define RAISE_REMOTE_WINFSP_SERVER_EVENT(func, file, ret) \ #define RAISE_REMOTE_WINFSP_SERVER_EVENT(func, file, ret) \
if (config_.get_enable_drive_events() && \ if (config_.get_enable_drive_events() && \
@ -99,10 +92,14 @@ void remote_server::populate_stat(const char *path, bool directory,
directory ? 2 + drive_.get_directory_item_count( directory ? 2 + drive_.get_directory_item_count(
utils::path::create_api_path(path)) utils::path::create_api_path(path))
: 1); : 1);
r_stat.st_atimespec = utils::time::time64_to_unix_time(unix_st.st_atime); r_stat.st_atimespec =
r_stat.st_birthtimespec = utils::time::time64_to_unix_time(unix_st.st_ctime); utils::time::windows_time_t_to_unix_time(unix_st.st_atime);
r_stat.st_ctimespec = utils::time::time64_to_unix_time(unix_st.st_ctime); r_stat.st_birthtimespec =
r_stat.st_mtimespec = utils::time::time64_to_unix_time(unix_st.st_mtime); utils::time::windows_time_t_to_unix_time(unix_st.st_ctime);
r_stat.st_ctimespec =
utils::time::windows_time_t_to_unix_time(unix_st.st_ctime);
r_stat.st_mtimespec =
utils::time::windows_time_t_to_unix_time(unix_st.st_mtime);
r_stat.st_size = static_cast<remote::file_size>(unix_st.st_size); r_stat.st_size = static_cast<remote::file_size>(unix_st.st_size);
r_stat.st_mode = unix_st.st_mode; r_stat.st_mode = unix_st.st_mode;
} }
@ -114,10 +111,22 @@ auto remote_server::fuse_access(const char *path, const std::int32_t &mask)
static_cast<const char *>(__FUNCTION__), static_cast<const char *>(__FUNCTION__),
}; };
const auto file_path = construct_path(path); auto file_path{
const auto windows_mask = utils::unix_access_mask_to_windows(mask); construct_path(path),
const auto res = _access(file_path.c_str(), windows_mask); };
const auto ret = ((res < 0) ? -errno : 0);
auto windows_mask{
utils::unix_access_mask_to_windows(mask),
};
auto res{
_access(file_path.c_str(), windows_mask),
};
auto ret{
((res < 0) ? -errno : 0),
};
RAISE_REMOTE_WINFSP_SERVER_EVENT(function_name, file_path, ret); RAISE_REMOTE_WINFSP_SERVER_EVENT(function_name, file_path, ret);
return ret; return ret;
} }
@ -188,12 +197,15 @@ auto remote_server::fuse_fgetattr(
static_cast<const char *>(__FUNCTION__), static_cast<const char *>(__FUNCTION__),
}; };
const auto file_path = construct_path(path); r_stat = {};
memset(&r_stat, 0, sizeof(remote::stat));
auto res = has_compat_open_info(handle, EBADF); const auto file_path = construct_path(path);
auto res{
has_compat_open_info(handle, EBADF),
};
if (res == 0) { if (res == 0) {
directory = utils::file::is_directory(file_path); directory = utils::file::directory(file_path).exists();
struct _stat64 unix_st {}; struct _stat64 unix_st {};
res = _fstat64(static_cast<int>(handle), &unix_st); res = _fstat64(static_cast<int>(handle), &unix_st);
if (res == 0) { if (res == 0) {
@ -228,7 +240,9 @@ auto remote_server::fuse_fsync(
const auto file_path = construct_path(path); const auto file_path = construct_path(path);
auto res = has_compat_open_info(handle, EBADF); auto res{
has_compat_open_info(handle, EBADF),
};
if (res == 0) { if (res == 0) {
res = -1; res = -1;
errno = EBADF; errno = EBADF;
@ -257,7 +271,9 @@ auto remote_server::fuse_ftruncate(
const auto file_path = construct_path(path); const auto file_path = construct_path(path);
auto res = has_compat_open_info(handle, EBADF); auto res{
has_compat_open_info(handle, EBADF),
};
if (res == 0) { if (res == 0) {
res = -1; res = -1;
errno = EBADF; errno = EBADF;
@ -286,13 +302,16 @@ auto remote_server::fuse_getattr(const char *path, remote::stat &r_st,
static_cast<const char *>(__FUNCTION__), static_cast<const char *>(__FUNCTION__),
}; };
const auto file_path = construct_path(path); r_st = {};
memset(&r_st, 0, sizeof(remote::stat));
directory = utils::file::is_directory(file_path); const auto file_path = construct_path(path);
directory = utils::file::directory(file_path).exists();
struct _stat64 st1 {}; struct _stat64 st1 {};
const auto res = _stat64(file_path.c_str(), &st1); auto res{
_stat64(file_path.c_str(), &st1),
};
if (res == 0) { if (res == 0) {
populate_stat(path, directory, r_st, st1); populate_stat(path, directory, r_st, st1);
} }
@ -352,7 +371,9 @@ auto remote_server::fuse_mkdir(const char *path,
}; };
const auto file_path = construct_path(path); const auto file_path = construct_path(path);
const auto res = _mkdir(file_path.c_str()); auto res{
_mkdir(file_path.c_str()),
};
const auto ret = ((res < 0) ? -errno : 0); const auto ret = ((res < 0) ? -errno : 0);
RAISE_REMOTE_WINFSP_SERVER_EVENT(function_name, file_path, ret); RAISE_REMOTE_WINFSP_SERVER_EVENT(function_name, file_path, ret);
return ret; return ret;
@ -366,7 +387,7 @@ auto remote_server::fuse_opendir(const char *path, remote::file_handle &handle)
const auto file_path = construct_path(path); const auto file_path = construct_path(path);
const auto unicode_file_path = utils::string::from_utf8(file_path); const auto unicode_file_path = utils::string::from_utf8(file_path);
auto res = -1; auto res{-1};
errno = ENOENT; errno = ENOENT;
if (::PathIsDirectoryW(unicode_file_path.c_str()) != 0) { if (::PathIsDirectoryW(unicode_file_path.c_str()) != 0) {
@ -409,8 +430,9 @@ auto remote_server::fuse_create(const char *path, const remote::file_mode &mode,
ret = -EACCES; ret = -EACCES;
} else { } else {
int file = -1; int file = -1;
const auto res = auto res{
_sopen_s(&file, file_path.c_str(), open_flags, _SH_DENYNO, perms); _sopen_s(&file, file_path.c_str(), open_flags, _SH_DENYNO, perms),
};
if (res == 0) { if (res == 0) {
handle = static_cast<remote::file_handle>(file); handle = static_cast<remote::file_handle>(file);
ret = 0; ret = 0;
@ -432,7 +454,7 @@ auto remote_server::fuse_open(const char *path, const remote::open_flags &flags,
}; };
const auto file_path = construct_path(path); const auto file_path = construct_path(path);
auto res = -1; auto res{-1};
if ((flags & remote::open_flags::directory) == if ((flags & remote::open_flags::directory) ==
remote::open_flags::directory) { remote::open_flags::directory) {
@ -467,34 +489,21 @@ auto remote_server::fuse_read(
const auto file_path = construct_path(path); const auto file_path = construct_path(path);
auto &data = *reinterpret_cast<data_buffer *>(buffer); auto &data = *reinterpret_cast<data_buffer *>(buffer);
auto res = 0; auto res{0};
if (read_size > std::numeric_limits<std::size_t>::max()) { if (read_size > std::numeric_limits<std::size_t>::max()) {
res = -1; res = -1;
errno = ERANGE; errno = ERANGE;
} else if ((res = has_compat_open_info(handle, EBADF)) == 0) { } else if ((res = has_compat_open_info(handle, EBADF)) == 0) {
res = -1; res = static_cast<std::decay_t<decltype(res)>>(_lseeki64(
errno = EBADF; static_cast<int>(handle), static_cast<__int64>(read_offset), SEEK_SET));
auto *os_handle = if (res != -1) {
reinterpret_cast<HANDLE>(_get_osfhandle(static_cast<int>(handle))); data.resize(read_size);
if (os_handle != INVALID_HANDLE_VALUE) { res = read(static_cast<int>(handle), data.data(),
errno = EFAULT; static_cast<unsigned int>(data.size()));
if (res == -1) {
auto file = native_file::attach(os_handle); data.resize(0U);
std::uint64_t file_size{}; } else if (data.size() != static_cast<std::size_t>(res)) {
if (file->get_file_size(file_size)) { data.resize(static_cast<std::size_t>(res));
data.resize(utils::calculate_read_size(
file_size, static_cast<std::size_t>(read_size), read_offset));
if (!data.empty()) {
std::size_t bytes_read{};
if (file->read_bytes(data.data(), data.size(), read_offset,
bytes_read)) {
res = 0;
errno = 0;
}
} else {
res = 0;
errno = 0;
}
} }
} }
} }
@ -514,7 +523,9 @@ auto remote_server::fuse_rename(const char *from,
const auto from_path = utils::path::combine(mount_location_, {from}); const auto from_path = utils::path::combine(mount_location_, {from});
const auto to_path = utils::path::combine(mount_location_, {to}); const auto to_path = utils::path::combine(mount_location_, {to});
const auto res = rename(from_path.c_str(), to_path.c_str()); auto res{
rename(from_path.c_str(), to_path.c_str()),
};
const auto ret = ((res < 0) ? -errno : 0); const auto ret = ((res < 0) ? -errno : 0);
RAISE_REMOTE_WINFSP_SERVER_EVENT(function_name, from + std::string("|") + to, RAISE_REMOTE_WINFSP_SERVER_EVENT(function_name, from + std::string("|") + to,
@ -532,26 +543,21 @@ auto remote_server::fuse_write(
const auto file_path = construct_path(path); const auto file_path = construct_path(path);
std::size_t bytes_written{}; std::size_t bytes_written{};
auto res = 0; auto res{0};
if (write_size > std::numeric_limits<std::size_t>::max()) { if (write_size > std::numeric_limits<std::size_t>::max()) {
res = -1; res = -1;
errno = ERANGE; errno = ERANGE;
} else { } else {
res = has_compat_open_info(handle, EBADF); res = has_compat_open_info(handle, EBADF);
if (res == 0) { if (res == 0) {
res = -1; res = static_cast<std::decay_t<decltype(res)>>(
errno = EBADF; _lseeki64(static_cast<int>(handle),
auto *os_handle = static_cast<__int64>(write_offset), SEEK_SET));
reinterpret_cast<HANDLE>(_get_osfhandle(static_cast<int>(handle))); if (res != -1) {
if (os_handle != INVALID_HANDLE_VALUE) { res = write(static_cast<int>(handle), buffer,
errno = EFAULT; static_cast<unsigned int>(write_size));
if ((write_size == 0) || if (res != -1) {
native_file::attach(os_handle)->write_bytes( bytes_written = static_cast<std::size_t>(res);
reinterpret_cast<const unsigned char *>(buffer),
static_cast<std::size_t>(write_size), write_offset,
bytes_written)) {
res = 0;
errno = 0;
} }
} }
} }
@ -582,7 +588,7 @@ auto remote_server::fuse_readdir(const char *path,
}; };
const auto file_path = construct_path(path); const auto file_path = construct_path(path);
auto res = 0; auto res{0};
if (offset > std::numeric_limits<std::size_t>::max()) { if (offset > std::numeric_limits<std::size_t>::max()) {
errno = ERANGE; errno = ERANGE;
res = -1; res = -1;
@ -610,7 +616,9 @@ auto remote_server::fuse_release(
const auto file_path = construct_path(path); const auto file_path = construct_path(path);
remove_compat_open_info(handle); remove_compat_open_info(handle);
const auto res = _close(static_cast<int>(handle)); auto res{
_close(static_cast<int>(handle)),
};
const auto ret = ((res < 0) ? -errno : 0); const auto ret = ((res < 0) ? -errno : 0);
RAISE_REMOTE_WINFSP_SERVER_EVENT(function_name, file_path, ret); RAISE_REMOTE_WINFSP_SERVER_EVENT(function_name, file_path, ret);
@ -642,7 +650,9 @@ auto remote_server::fuse_rmdir(const char *path) -> packet::error_type {
}; };
const auto file_path = construct_path(path); const auto file_path = construct_path(path);
const auto res = _rmdir(file_path.c_str()); auto res{
_rmdir(file_path.c_str()),
};
const auto ret = ((res < 0) ? -errno : 0); const auto ret = ((res < 0) ? -errno : 0);
RAISE_REMOTE_WINFSP_SERVER_EVENT(function_name, file_path, ret); RAISE_REMOTE_WINFSP_SERVER_EVENT(function_name, file_path, ret);
return ret; return ret;
@ -767,9 +777,9 @@ auto remote_server::fuse_statfs_x(const char *path, std::uint64_t bsize,
r_stat.f_files = 4294967295; r_stat.f_files = 4294967295;
r_stat.f_ffree = r_stat.f_favail = r_stat.f_ffree = r_stat.f_favail =
r_stat.f_files - drive_.get_total_item_count(); r_stat.f_files - drive_.get_total_item_count();
strncpy(&r_stat.f_mntfromname[0U], strncpy(r_stat.f_mntfromname.data(),
(utils::create_volume_label(config_.get_provider_type())).c_str(), (utils::create_volume_label(config_.get_provider_type())).c_str(),
sizeof(r_stat.f_mntfromname) - 1U); r_stat.f_mntfromname.size() - 1U);
RAISE_REMOTE_WINFSP_SERVER_EVENT(function_name, file_path, 0); RAISE_REMOTE_WINFSP_SERVER_EVENT(function_name, file_path, 0);
return 0; return 0;
@ -783,7 +793,7 @@ auto remote_server::fuse_truncate(
const auto file_path = construct_path(path); const auto file_path = construct_path(path);
const auto unicode_file_path = utils::string::from_utf8(file_path); const auto unicode_file_path = utils::string::from_utf8(file_path);
auto res = -1; auto res{-1};
errno = ENOENT; errno = ENOENT;
const auto flags_and_attributes = const auto flags_and_attributes =
@ -818,7 +828,9 @@ auto remote_server::fuse_unlink(const char *path) -> packet::error_type {
}; };
const auto file_path = construct_path(path); const auto file_path = construct_path(path);
const auto res = _unlink(file_path.c_str()); auto res{
_unlink(file_path.c_str()),
};
const auto ret = ((res < 0) ? -errno : 0); const auto ret = ((res < 0) ? -errno : 0);
RAISE_REMOTE_WINFSP_SERVER_EVENT(function_name, file_path, ret); RAISE_REMOTE_WINFSP_SERVER_EVENT(function_name, file_path, ret);
return ret; return ret;
@ -834,7 +846,7 @@ auto remote_server::fuse_utimens(const char *path, const remote::file_time *tv,
const auto file_path = construct_path(path); const auto file_path = construct_path(path);
const auto unicode_file_path = utils::string::from_utf8(file_path); const auto unicode_file_path = utils::string::from_utf8(file_path);
auto res = -1; auto res{-1};
errno = ENOENT; errno = ENOENT;
const auto flags_and_attributes = const auto flags_and_attributes =
@ -849,29 +861,27 @@ auto remote_server::fuse_utimens(const char *path, const remote::file_time *tv,
if (os_handle != INVALID_HANDLE_VALUE) { if (os_handle != INVALID_HANDLE_VALUE) {
FILETIME access_time{}; FILETIME access_time{};
FILETIME write_time{}; FILETIME write_time{};
FILETIME *access_time_ptr = nullptr; FILETIME *access_time_ptr{nullptr};
FILETIME *write_time_ptr = nullptr; FILETIME *write_time_ptr{nullptr};
if ((tv[0U] == 0U) || (op0 == UTIME_NOW)) { const auto proccess_timespec = [](auto op, const auto &src, auto &dst,
const auto now = utils::time::get_file_time_now(); auto *&dst_ptr) {
access_time.dwHighDateTime = if ((src == 0U) || (op == UTIME_NOW)) {
static_cast<DWORD>((now >> 32U) & 0xFFFFFFFF); auto now =
access_time.dwLowDateTime = now & 0xFFFFFFFF; utils::time::unix_time_to_windows_time(utils::time::get_time_now());
access_time_ptr = &access_time; dst.dwHighDateTime = static_cast<DWORD>((now >> 32U) & 0xFFFFFFFF);
} else if (op0 != UTIME_OMIT) { dst.dwLowDateTime = now & 0xFFFFFFFF;
access_time = utils::time::unix_time_to_filetime(tv[0U]); dst_ptr = &dst;
access_time_ptr = &access_time; return;
} }
if ((tv[1U] == 0U) || (op1 == UTIME_NOW)) { if (op != UTIME_OMIT) {
const auto now = utils::time::get_file_time_now(); dst = utils::time::unix_time_to_filetime(src);
write_time.dwHighDateTime = static_cast<DWORD>((now >> 32U) & 0xFFFFFFFF); dst_ptr = &dst;
write_time.dwLowDateTime = now & 0xFFFFFFFF; }
write_time_ptr = &write_time; };
} else if (op1 != UTIME_OMIT) { proccess_timespec(op0, tv[0U], access_time, access_time_ptr);
write_time = utils::time::unix_time_to_filetime(tv[1U]); proccess_timespec(op1, tv[1U], write_time, write_time_ptr);
write_time_ptr = &write_time;
}
errno = EFAULT; errno = EFAULT;
if (::SetFileTime(os_handle, nullptr, access_time_ptr, write_time_ptr) != if (::SetFileTime(os_handle, nullptr, access_time_ptr, write_time_ptr) !=
@ -879,6 +889,7 @@ auto remote_server::fuse_utimens(const char *path, const remote::file_time *tv,
res = 0; res = 0;
errno = 0; errno = 0;
} }
::CloseHandle(os_handle); ::CloseHandle(os_handle);
} }
@ -896,10 +907,10 @@ auto remote_server::json_create_directory_snapshot(
const auto file_path = construct_path(path); const auto file_path = construct_path(path);
auto res = -1; auto res{-1};
errno = ENOENT; errno = ENOENT;
if (utils::file::is_directory(file_path)) { if (utils::file::directory(file_path).exists()) {
auto iter = std::make_shared<directory_iterator>( auto iter = std::make_shared<directory_iterator>(
drive_.get_directory_items(utils::path::create_api_path(path))); drive_.get_directory_items(utils::path::create_api_path(path)));
auto handle = get_next_handle(); auto handle = get_next_handle();
@ -1037,8 +1048,11 @@ auto remote_server::winfsp_create(PWSTR file_name, UINT32 create_options,
const auto file_path = utils::string::from_utf8(utils::path::combine( const auto file_path = utils::string::from_utf8(utils::path::combine(
mount_location_, {utils::string::to_utf8(file_name)})); mount_location_, {utils::string::to_utf8(file_name)}));
exists = static_cast<BOOLEAN>(utils::file::is_file(utils::path::combine( exists = static_cast<BOOLEAN>(
mount_location_, {utils::string::to_utf8(file_name)}))); utils::file::file(
utils::path::combine(mount_location_,
{utils::string::to_utf8(file_name)}))
.exists());
auto create_flags = FILE_FLAG_BACKUP_SEMANTICS; auto create_flags = FILE_FLAG_BACKUP_SEMANTICS;
if ((create_options & FILE_DIRECTORY_FILE) != 0U) { if ((create_options & FILE_DIRECTORY_FILE) != 0U) {
@ -1500,4 +1514,4 @@ auto remote_server::winfsp_get_dir_buffer(PVOID /*file_desc*/, PVOID *& /*ptr*/)
} }
} // namespace repertory::remote_winfsp } // namespace repertory::remote_winfsp
#endif // _WIN32 #endif // defined(_WIN32)

View File

@ -62,7 +62,7 @@ auto remote_winfsp_drive::winfsp_service::OnStart(ULONG, PWSTR *) -> NTSTATUS {
(mount_location[1u] == ':'); (mount_location[1u] == ':');
auto ret = drive_letter ? STATUS_DEVICE_BUSY : STATUS_NOT_SUPPORTED; auto ret = drive_letter ? STATUS_DEVICE_BUSY : STATUS_NOT_SUPPORTED;
if ((drive_letter && not utils::file::is_directory(mount_location))) { if ((drive_letter && not utils::file::directory(mount_location).exists())) {
auto unicode_mount_location = utils::string::from_utf8(mount_location); auto unicode_mount_location = utils::string::from_utf8(mount_location);
host_.SetFileSystemName(&unicode_mount_location[0u]); host_.SetFileSystemName(&unicode_mount_location[0u]);
if (config_.get_enable_mount_manager()) { if (config_.get_enable_mount_manager()) {
@ -230,7 +230,7 @@ auto remote_winfsp_drive::Init(PVOID host) -> NTSTATUS {
file_system_host->SetPersistentAcls(FALSE); file_system_host->SetPersistentAcls(FALSE);
file_system_host->SetPostCleanupWhenModifiedOnly(TRUE); file_system_host->SetPostCleanupWhenModifiedOnly(TRUE);
file_system_host->SetPassQueryDirectoryPattern(FALSE); file_system_host->SetPassQueryDirectoryPattern(FALSE);
file_system_host->SetVolumeCreationTime(utils::time::get_file_time_now()); file_system_host->SetVolumeCreationTime(utils::time::get_time_now());
file_system_host->SetVolumeSerialNumber(0); file_system_host->SetVolumeSerialNumber(0);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -363,33 +363,33 @@ auto remote_winfsp_drive::ReadDirectory(PVOID /*file_node*/, PVOID file_desc,
utils::path::strip_to_file_name(item_path)); utils::path::strip_to_file_name(item_path));
if (not marker || (marker && item_found)) { if (not marker || (marker && item_found)) {
// if (not utils::path::is_ads_file_path(item_path)) { // if (not utils::path::is_ads_file_path(item_path)) {
union { union {
UINT8 B[FIELD_OFFSET(FSP_FSCTL_DIR_INFO, FileNameBuf) + UINT8 B[FIELD_OFFSET(FSP_FSCTL_DIR_INFO, FileNameBuf) +
((MAX_PATH + 1) * sizeof(WCHAR))]; ((MAX_PATH + 1) * sizeof(WCHAR))];
FSP_FSCTL_DIR_INFO D; FSP_FSCTL_DIR_INFO D;
} directory_info_buffer; } directory_info_buffer;
auto *directory_info = &directory_info_buffer.D; auto *directory_info = &directory_info_buffer.D;
::ZeroMemory(directory_info, sizeof(*directory_info)); ::ZeroMemory(directory_info, sizeof(*directory_info));
directory_info->Size = static_cast<UINT16>( directory_info->Size = static_cast<UINT16>(
FIELD_OFFSET(FSP_FSCTL_DIR_INFO, FileNameBuf) + FIELD_OFFSET(FSP_FSCTL_DIR_INFO, FileNameBuf) +
(std::min((size_t)MAX_PATH, display_name.size()) * (std::min(static_cast<size_t>(MAX_PATH), display_name.size()) *
sizeof(WCHAR))); sizeof(WCHAR)));
if (not item["meta"].empty() || if (not item["meta"].empty() ||
((item_path != ".") && (item_path != ".."))) { ((item_path != ".") && (item_path != ".."))) {
populate_file_info(item, directory_info->FileInfo); populate_file_info(item, directory_info->FileInfo);
} }
if (ret == STATUS_SUCCESS) { if (ret == STATUS_SUCCESS) {
::wcscpy_s(&directory_info->FileNameBuf[0], MAX_PATH, ::wcscpy_s(&directory_info->FileNameBuf[0], MAX_PATH,
&display_name[0]); &display_name[0]);
FspFileSystemFillDirectoryBuffer(directory_buffer, FspFileSystemFillDirectoryBuffer(directory_buffer, directory_info,
directory_info, &ret); &ret);
if (ret != STATUS_SUCCESS) { if (ret != STATUS_SUCCESS) {
break; break;
}
} }
}
// } // }
} else { } else {
item_found = display_name == std::wstring(marker); item_found = display_name == std::wstring(marker);

View File

@ -81,7 +81,7 @@ auto winfsp_drive::winfsp_service::OnStart(ULONG /*Argc*/,
(mount_location[1U] == ':'); (mount_location[1U] == ':');
auto ret = drive_letter ? STATUS_DEVICE_BUSY : STATUS_NOT_SUPPORTED; auto ret = drive_letter ? STATUS_DEVICE_BUSY : STATUS_NOT_SUPPORTED;
if ((drive_letter && not utils::file::is_directory(mount_location))) { if ((drive_letter && not utils::file::directory(mount_location).exists())) {
auto unicode_mount_location = utils::string::from_utf8(mount_location); auto unicode_mount_location = utils::string::from_utf8(mount_location);
host_.SetFileSystemName(unicode_mount_location.data()); host_.SetFileSystemName(unicode_mount_location.data());
if (config_.get_enable_mount_manager()) { if (config_.get_enable_mount_manager()) {
@ -215,7 +215,7 @@ VOID winfsp_drive::Cleanup(PVOID file_node, PVOID file_desc,
if ((flags & (FspCleanupSetLastAccessTime | FspCleanupSetLastWriteTime | if ((flags & (FspCleanupSetLastAccessTime | FspCleanupSetLastWriteTime |
FspCleanupSetChangeTime)) != 0U) { FspCleanupSetChangeTime)) != 0U) {
const auto now = utils::time::get_file_time_now(); const auto now = utils::time::get_time_now();
if ((flags & FspCleanupSetLastAccessTime) != 0U) { if ((flags & FspCleanupSetLastAccessTime) != 0U) {
auto res = provider_.set_item_meta(api_path, META_ACCESSED, auto res = provider_.set_item_meta(api_path, META_ACCESSED,
std::to_string(now)); std::to_string(now));
@ -238,8 +238,10 @@ VOID winfsp_drive::Cleanup(PVOID file_node, PVOID file_desc,
if ((flags & FspCleanupSetChangeTime) != 0U) { if ((flags & FspCleanupSetChangeTime) != 0U) {
auto res = provider_.set_item_meta( auto res = provider_.set_item_meta(
api_path, {{META_CHANGED, std::to_string(now)}, api_path, {
{META_MODIFIED, std::to_string(now)}}); {META_CHANGED, std::to_string(now)},
{META_MODIFIED, std::to_string(now)},
});
if (res != api_error::success) { if (res != api_error::success) {
utils::error::raise_api_path_error( utils::error::raise_api_path_error(
function_name, api_path, res, function_name, api_path, res,
@ -310,7 +312,7 @@ auto winfsp_drive::Create(PWSTR file_name, UINT32 create_options,
attributes = FILE_ATTRIBUTE_NORMAL; attributes = FILE_ATTRIBUTE_NORMAL;
} }
const auto now = utils::time::get_file_time_now(); const auto now = utils::time::get_time_now();
auto meta = create_meta_attributes( auto meta = create_meta_attributes(
now, attributes, now, now, (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0U, now, attributes, now, now, (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0U,
0U, "", 0U, now, 0U, 0U, 0U, 0U, "", 0U, now, 0U, 0U, 0U,
@ -477,8 +479,7 @@ auto winfsp_drive::get_security_by_name(
if (descriptor_size != nullptr) { if (descriptor_size != nullptr) {
ULONG size{}; ULONG size{};
PSECURITY_DESCRIPTOR sec_desc{}; PSECURITY_DESCRIPTOR sec_desc{};
if (::ConvertStringSecurityDescriptorToSecurityDescriptorA(
if (::ConvertStringSecurityDescriptorToSecurityDescriptor(
"O:BAG:BAD:P(A;;FA;;;SY)(A;;FA;;;BA)(A;;FA;;;WD)", "O:BAG:BAD:P(A;;FA;;;SY)(A;;FA;;;BA)(A;;FA;;;WD)",
SDDL_REVISION_1, &sec_desc, &size) != 0) { SDDL_REVISION_1, &sec_desc, &size) != 0) {
if (size > *descriptor_size) { if (size > *descriptor_size) {
@ -512,6 +513,7 @@ auto winfsp_drive::GetSecurityByName(PWSTR file_name, PUINT32 attributes,
if (sds != 0U) { if (sds != 0U) {
*descriptor_size = static_cast<SIZE_T>(sds); *descriptor_size = static_cast<SIZE_T>(sds);
} }
RAISE_WINFSP_EVENT(function_name, api_path, ret); RAISE_WINFSP_EVENT(function_name, api_path, ret);
return ret; return ret;
} }
@ -579,7 +581,7 @@ auto winfsp_drive::Init(PVOID host) -> NTSTATUS {
file_system_host->SetPersistentAcls(FALSE); file_system_host->SetPersistentAcls(FALSE);
file_system_host->SetPostCleanupWhenModifiedOnly(TRUE); file_system_host->SetPostCleanupWhenModifiedOnly(TRUE);
file_system_host->SetPassQueryDirectoryPattern(FALSE); file_system_host->SetPassQueryDirectoryPattern(FALSE);
file_system_host->SetVolumeCreationTime(utils::time::get_file_time_now()); file_system_host->SetVolumeCreationTime(utils::time::get_time_now());
file_system_host->SetVolumeSerialNumber(0); file_system_host->SetVolumeSerialNumber(0);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -590,7 +592,7 @@ auto winfsp_drive::mount(const std::vector<std::string> &drive_args) -> int {
const auto force_no_console = utils::collection::includes(drive_args, "-nc"); const auto force_no_console = utils::collection::includes(drive_args, "-nc");
auto enable_console = false; auto enable_console = false;
for (const auto &arg : drive_args) { for (auto &&arg : drive_args) {
if (arg == "-f") { if (arg == "-f") {
if (not force_no_console) { if (not force_no_console) {
enable_console = true; enable_console = true;
@ -620,10 +622,14 @@ auto winfsp_drive::Mounted(PVOID host) -> NTSTATUS {
static_cast<const char *>(__FUNCTION__), static_cast<const char *>(__FUNCTION__),
}; };
auto ret = STATUS_SUCCESS; auto ret{STATUS_SUCCESS};
utils::file::change_to_process_directory(); if (not utils::file::change_to_process_directory()) {
return static_cast<NTSTATUS>(utils::get_last_error_code());
}
auto *file_system_host = reinterpret_cast<FileSystemHost *>(host); auto *file_system_host{
reinterpret_cast<FileSystemHost *>(host),
};
polling::instance().start(&config_); polling::instance().start(&config_);
fm_ = std::make_unique<file_manager>(config_, provider_); fm_ = std::make_unique<file_manager>(config_, provider_);
server_ = std::make_unique<full_server>(config_, provider_, *fm_); server_ = std::make_unique<full_server>(config_, provider_, *fm_);
@ -868,7 +874,7 @@ auto winfsp_drive::Read(PVOID /*file_node*/, PVOID file_desc, PVOID buffer,
data.clear(); data.clear();
auto res = provider_.set_item_meta( auto res = provider_.set_item_meta(
api_path, META_ACCESSED, api_path, META_ACCESSED,
std::to_string(utils::time::get_file_time_now())); std::to_string(utils::time::get_time_now()));
if (res != api_error::success) { if (res != api_error::success) {
utils::error::raise_api_path_error( utils::error::raise_api_path_error(
function_name, api_path, res, function_name, api_path, res,
@ -929,10 +935,9 @@ auto winfsp_drive::ReadDirectory(PVOID /*file_node*/, PVOID file_desc,
api_path, {utils::string::to_utf8(marker)}))); api_path, {utils::string::to_utf8(marker)})));
while ((error = iterator.get_directory_item( while ((error = iterator.get_directory_item(
offset++, dir_item)) == api_error::success) { offset++, dir_item)) == api_error::success) {
// if (utils::path::is_ads_file_path(dir_item.api_path) || if (dir_item.api_path == "." || dir_item.api_path == "..") {
// dir_item.api_path == "." || dir_item.api_path == "..") { continue;
// continue; }
// }
if (dir_item.meta.empty()) { if (dir_item.meta.empty()) {
utils::error::raise_api_path_error( utils::error::raise_api_path_error(
@ -1058,17 +1063,22 @@ auto winfsp_drive::SetBasicInfo(PVOID /*file_node*/, PVOID file_desc,
meta[META_ATTRIBUTES] = std::to_string(attributes); meta[META_ATTRIBUTES] = std::to_string(attributes);
} }
if ((creation_time != 0U) && (creation_time != max_time)) { if ((creation_time != 0U) && (creation_time != max_time)) {
meta[META_CREATION] = std::to_string(creation_time); meta[META_CREATION] = std::to_string(
utils::time::windows_time_to_unix_time(creation_time));
} }
if ((last_access_time != 0U) && (last_access_time != max_time)) { if ((last_access_time != 0U) && (last_access_time != max_time)) {
meta[META_ACCESSED] = std::to_string(last_access_time); meta[META_ACCESSED] = std::to_string(
utils::time::windows_time_to_unix_time(last_access_time));
} }
if ((last_write_time != 0U) && (last_write_time != max_time)) { if ((last_write_time != 0U) && (last_write_time != max_time)) {
meta[META_WRITTEN] = std::to_string(last_write_time); meta[META_WRITTEN] = std::to_string(
utils::time::windows_time_to_unix_time(last_write_time));
} }
if ((change_time != 0U) && (change_time != max_time)) { if ((change_time != 0U) && (change_time != max_time)) {
meta[META_CHANGED] = std::to_string(change_time); meta[META_CHANGED] =
meta[META_MODIFIED] = std::to_string(change_time); std::to_string(utils::time::windows_time_to_unix_time(change_time));
meta[META_MODIFIED] =
std::to_string(utils::time::windows_time_to_unix_time(change_time));
} }
error = provider_.set_item_meta(api_path, meta); error = provider_.set_item_meta(api_path, meta);

View File

@ -116,7 +116,7 @@ file_manager::file_manager(app_config &config, i_provider &provider)
} }
db_.reset(db3); db_.reset(db3);
for (const auto &create_item : sql_create_tables) { for (auto &&create_item : sql_create_tables) {
std::string err; std::string err;
if (not db::execute_sql(*db_, create_item.second, err)) { if (not db::execute_sql(*db_, create_item.second, err)) {
db_.reset(); db_.reset();
@ -176,12 +176,12 @@ void file_manager::close_timed_out_files() {
} }
return items; return items;
}); });
for (const auto &closeable_file : closeable_list) { for (auto &&closeable_file : closeable_list) {
open_file_lookup_.erase(closeable_file->get_api_path()); open_file_lookup_.erase(closeable_file->get_api_path());
} }
file_lock.unlock(); file_lock.unlock();
for (auto &closeable_file : closeable_list) { for (auto &&closeable_file : closeable_list) {
closeable_file->close(); closeable_file->close();
event_system::instance().raise<item_timeout>( event_system::instance().raise<item_timeout>(
closeable_file->get_api_path()); closeable_file->get_api_path());
@ -244,7 +244,7 @@ auto file_manager::evict_file(const std::string &api_path) -> bool {
open_file_lookup_.erase(api_path); open_file_lookup_.erase(api_path);
auto removed = utils::file::retry_delete_file(source_path); auto removed = utils::file::file(source_path).remove();
if (removed) { if (removed) {
event_system::instance().raise<filesystem_item_evicted>(api_path, event_system::instance().raise<filesystem_item_evicted>(api_path,
source_path); source_path);
@ -329,7 +329,7 @@ auto file_manager::get_open_files() const
std::unordered_map<std::string, std::size_t> ret; std::unordered_map<std::string, std::size_t> ret;
recur_mutex_lock open_lock(open_file_mtx_); recur_mutex_lock open_lock(open_file_mtx_);
for (const auto &item : open_file_lookup_) { for (auto &&item : open_file_lookup_) {
ret[item.first] = item.second->get_open_file_count(); ret[item.first] = item.second->get_open_file_count();
} }
@ -513,8 +513,8 @@ void file_manager::queue_upload(const std::string &api_path,
db::db_insert{*db_.get(), upload_table} db::db_insert{*db_.get(), upload_table}
.or_replace() .or_replace()
.column_value("api_path", api_path) .column_value("api_path", api_path)
.column_value("date_time", static_cast<std::int64_t>( .column_value("date_time",
utils::time::get_file_time_now())) static_cast<std::int64_t>(utils::time::get_time_now()))
.column_value("source_path", source_path) .column_value("source_path", source_path)
.go(); .go();
if (result.ok()) { if (result.ok()) {
@ -557,7 +557,7 @@ auto file_manager::remove_file(const std::string &api_path) -> api_error {
return res; return res;
} }
if (not utils::file::retry_delete_file(fsi.source_path)) { if (not utils::file::file(fsi.source_path).remove()) {
utils::error::raise_api_path_error( utils::error::raise_api_path_error(
function_name, fsi.api_path, fsi.source_path, function_name, fsi.api_path, fsi.source_path,
utils::get_last_error_code(), "failed to delete source"); utils::get_last_error_code(), "failed to delete source");
@ -778,14 +778,9 @@ auto file_manager::rename_file(const std::string &from_api_path,
return res; return res;
} }
std::uint64_t file_size{};
if (not utils::file::get_file_size(fsi.source_path, file_size)) {
return api_error::os_error;
}
res = remove_file(to_api_path); res = remove_file(to_api_path);
if ((res == api_error::success) || (res == api_error::item_not_found)) { if ((res == api_error::success) || (res == api_error::item_not_found)) {
if (not utils::file::retry_delete_file(fsi.source_path)) { if (not utils::file::file(fsi.source_path).remove()) {
utils::error::raise_api_path_error( utils::error::raise_api_path_error(
function_name, fsi.api_path, fsi.source_path, function_name, fsi.api_path, fsi.source_path,
utils::get_last_error_code(), "failed to delete source path"); utils::get_last_error_code(), "failed to delete source path");
@ -848,7 +843,7 @@ void file_manager::start() {
} }
} }
for (const auto &active_item : active_items) { for (auto &&active_item : active_items) {
queue_upload(active_item.api_path, active_item.source_path, false); queue_upload(active_item.api_path, active_item.source_path, false);
} }
active_items.clear(); active_items.clear();
@ -878,8 +873,9 @@ void file_manager::start() {
auto res = provider_.get_filesystem_item(api_path, false, fsi); auto res = provider_.get_filesystem_item(api_path, false, fsi);
if (res == api_error::success) { if (res == api_error::success) {
if (source_path == fsi.source_path) { if (source_path == fsi.source_path) {
std::uint64_t file_size{}; auto opt_size = utils::file::file{fsi.source_path}.size();
if (utils::file::get_file_size(fsi.source_path, file_size)) { if (opt_size.has_value()) {
auto file_size{opt_size.value()};
if (file_size == fsi.size) { if (file_size == fsi.size) {
auto closeable_file = std::make_shared<open_file>( auto closeable_file = std::make_shared<open_file>(
chunk_size, chunk_size,
@ -941,7 +937,7 @@ void file_manager::stop() {
open_file_lookup_.clear(); open_file_lookup_.clear();
upload_lock.lock(); upload_lock.lock();
for (auto &item : upload_lookup_) { for (auto &&item : upload_lookup_) {
item.second->stop(); item.second->stop();
} }
upload_notify_.notify_all(); upload_notify_.notify_all();
@ -1027,7 +1023,7 @@ void file_manager::upload_completed(const file_upload_completed &evt) {
bool exists{}; bool exists{};
auto res = provider_.is_file(evt.get_api_path(), exists); auto res = provider_.is_file(evt.get_api_path(), exists);
if ((res == api_error::success && not exists) || if ((res == api_error::success && not exists) ||
not utils::file::is_file(evt.get_source().get<std::string>())) { not utils::file::file(evt.get_source().get<std::string>()).exists()) {
event_system::instance().raise<file_upload_not_found>( event_system::instance().raise<file_upload_not_found>(
evt.get_api_path(), evt.get_source()); evt.get_api_path(), evt.get_source());
remove_upload(evt.get_api_path(), true); remove_upload(evt.get_api_path(), true);
@ -1129,7 +1125,7 @@ void file_manager::upload_handler() {
void file_manager::update_used_space(std::uint64_t &used_space) const { void file_manager::update_used_space(std::uint64_t &used_space) const {
recur_mutex_lock open_lock(open_file_mtx_); recur_mutex_lock open_lock(open_file_mtx_);
for (const auto &item : open_file_lookup_) { for (auto &&item : open_file_lookup_) {
std::uint64_t file_size{}; std::uint64_t file_size{};
auto res = provider_.get_file_size(item.second->get_api_path(), file_size); auto res = provider_.get_file_size(item.second->get_api_path(), file_size);
if ((res == api_error::success) && if ((res == api_error::success) &&

View File

@ -66,8 +66,9 @@ file_manager::open_file::open_file(
} }
if (not fsi.directory) { if (not fsi.directory) {
set_api_error(native_file::create_or_open(fsi.source_path, nf_ = utils::file::file::open_or_create_file(fsi.source_path,
provider_.is_direct_only(), nf_)); provider_.is_direct_only());
set_api_error(*nf_ ? api_error::success : api_error::os_error);
if (get_api_error() == api_error::success) { if (get_api_error() == api_error::success) {
if (read_state.has_value()) { if (read_state.has_value()) {
read_state_ = read_state.value(); read_state_ = read_state.value();
@ -77,19 +78,15 @@ file_manager::open_file::open_file(
fsi_.size, chunk_size)), fsi_.size, chunk_size)),
false); false);
std::uint64_t file_size{}; auto file_size = nf_->size();
if (nf_->get_file_size(file_size)) { if (provider_.is_direct_only() || file_size == fsi.size) {
if (provider_.is_direct_only() || file_size == fsi.size) { read_state_.set(0U, read_state_.size(), true);
read_state_.set(0U, read_state_.size(), true); } else if (not nf_->truncate(fsi.size)) {
} else if (not nf_->truncate(fsi.size)) {
set_api_error(api_error::os_error);
}
} else {
set_api_error(api_error::os_error); set_api_error(api_error::os_error);
} }
} }
if (get_api_error() != api_error::success && nf_) { if (get_api_error() != api_error::success && *nf_) {
nf_->close(); nf_->close();
} }
} }
@ -185,8 +182,7 @@ void file_manager::open_file::download_chunk(std::size_t chunk,
res = do_io([&]() -> api_error { res = do_io([&]() -> api_error {
std::size_t bytes_written{}; std::size_t bytes_written{};
if (not nf_->write_bytes(data.data(), data.size(), data_offset, if (not nf_->write(data, data_offset, &bytes_written)) {
bytes_written)) {
return api_error::os_error; return api_error::os_error;
} }
@ -296,14 +292,7 @@ auto file_manager::open_file::native_operation(
} }
{ {
std::uint64_t file_size{}; auto file_size = nf_->size().value_or(0U);
if (not nf_->get_file_size(file_size)) {
utils::error::raise_api_path_error(function_name, get_api_path(),
utils::get_last_error_code(),
"failed to get file size");
return set_api_error(api_error::os_error);
}
if (file_size != new_file_size) { if (file_size != new_file_size) {
utils::error::raise_api_path_error( utils::error::raise_api_path_error(
function_name, get_api_path(), api_error::file_size_mismatch, function_name, get_api_path(), api_error::file_size_mismatch,
@ -331,7 +320,7 @@ auto file_manager::open_file::native_operation(
set_modified(); set_modified();
fsi_.size = new_file_size; fsi_.size = new_file_size;
const auto now = std::to_string(utils::time::get_file_time_now()); const auto now = std::to_string(utils::time::get_time_now());
res = provider_.set_item_meta( res = provider_.set_item_meta(
fsi_.api_path, { fsi_.api_path, {
{META_CHANGED, now}, {META_CHANGED, now},
@ -372,7 +361,7 @@ auto file_manager::open_file::read(std::size_t read_size,
data.resize(read_size); data.resize(read_size);
std::size_t bytes_read{}; std::size_t bytes_read{};
return nf_->read_bytes(data.data(), read_size, read_offset, bytes_read) return nf_->read(data.data(), read_size, read_offset, &bytes_read)
? api_error::success ? api_error::success
: api_error::os_error; : api_error::os_error;
}); });
@ -461,7 +450,6 @@ auto file_manager::open_file::close() -> bool {
} }
nf_->close(); nf_->close();
nf_.reset();
if (modified_ && (get_api_error() == api_error::success)) { if (modified_ && (get_api_error() == api_error::success)) {
mgr_.queue_upload(*this); mgr_.queue_upload(*this);
@ -470,13 +458,13 @@ auto file_manager::open_file::close() -> bool {
mgr_.store_resume(*this); mgr_.store_resume(*this);
} else if (get_api_error() != api_error::success) { } else if (get_api_error() != api_error::success) {
mgr_.remove_resume(get_api_path(), get_source_path()); mgr_.remove_resume(get_api_path(), get_source_path());
if (not utils::file::retry_delete_file(fsi_.source_path)) { if (not utils::file::file(fsi_.source_path).remove()) {
utils::error::raise_api_path_error( utils::error::raise_api_path_error(
function_name, get_api_path(), fsi_.source_path, function_name, get_api_path(), fsi_.source_path,
utils::get_last_error_code(), "failed to delete file"); utils::get_last_error_code(), "failed to delete file");
} }
auto parent = utils::path::remove_file_name(fsi_.source_path); auto parent = utils::path::get_parent_path(fsi_.source_path);
fsi_.source_path = fsi_.source_path =
utils::path::combine(parent, {utils::create_uuid_string()}); utils::path::combine(parent, {utils::create_uuid_string()});
const auto res = provider_.set_item_meta(fsi_.api_path, META_SOURCE, const auto res = provider_.set_item_meta(fsi_.api_path, META_SOURCE,
@ -587,8 +575,7 @@ auto file_manager::open_file::write(std::uint64_t write_offset,
} }
auto res = do_io([&]() -> api_error { auto res = do_io([&]() -> api_error {
if (not nf_->write_bytes(data.data(), data.size(), write_offset, if (not nf_->write(data, write_offset, &bytes_written)) {
bytes_written)) {
return api_error::os_error; return api_error::os_error;
} }
@ -599,7 +586,7 @@ auto file_manager::open_file::write(std::uint64_t write_offset,
return set_api_error(res); return set_api_error(res);
} }
const auto now = std::to_string(utils::time::get_file_time_now()); const auto now = std::to_string(utils::time::get_time_now());
res = provider_.set_item_meta(fsi_.api_path, { res = provider_.set_item_meta(fsi_.api_path, {
{META_CHANGED, now}, {META_CHANGED, now},
{META_MODIFIED, now}, {META_MODIFIED, now},

View File

@ -157,7 +157,7 @@ auto file_manager::open_file_base::get_handles() const
-> std::vector<std::uint64_t> { -> std::vector<std::uint64_t> {
recur_mutex_lock file_lock(file_mtx_); recur_mutex_lock file_lock(file_mtx_);
std::vector<std::uint64_t> ret; std::vector<std::uint64_t> ret;
for (const auto &item : open_data_) { for (auto &&item : open_data_) {
ret.emplace_back(item.first); ret.emplace_back(item.first);
} }

View File

@ -64,7 +64,7 @@ file_manager::ring_buffer_open_file::ring_buffer_open_file(
ring_state_.set(0U, ring_state_.size(), true); ring_state_.set(0U, ring_state_.size(), true);
buffer_directory = utils::path::absolute(buffer_directory); buffer_directory = utils::path::absolute(buffer_directory);
if (not utils::file::create_full_directory_path(buffer_directory)) { if (not utils::file::directory(buffer_directory).create_directory()) {
throw std::runtime_error("failed to create buffer directory|path|" + throw std::runtime_error("failed to create buffer directory|path|" +
buffer_directory + "|err|" + buffer_directory + "|err|" +
std::to_string(utils::get_last_error_code())); std::to_string(utils::get_last_error_code()));
@ -72,8 +72,8 @@ file_manager::ring_buffer_open_file::ring_buffer_open_file(
fsi_.source_path = fsi_.source_path =
utils::path::combine(buffer_directory, {utils::create_uuid_string()}); utils::path::combine(buffer_directory, {utils::create_uuid_string()});
auto res = native_file::create_or_open(fsi_.source_path, nf_); nf_ = utils::file::file::open_or_create_file(fsi_.source_path);
if (res != api_error::success) { if (not *nf_) {
throw std::runtime_error("failed to create buffer file|err|" + throw std::runtime_error("failed to create buffer file|err|" +
std::to_string(utils::get_last_error_code())); std::to_string(utils::get_last_error_code()));
} }
@ -93,7 +93,7 @@ file_manager::ring_buffer_open_file::~ring_buffer_open_file() {
close(); close();
nf_->close(); nf_->close();
if (not utils::file::retry_delete_file(fsi_.source_path)) { if (not utils::file::file(fsi_.source_path).remove()) {
utils::error::raise_api_path_error( utils::error::raise_api_path_error(
function_name, fsi_.api_path, fsi_.source_path, function_name, fsi_.api_path, fsi_.source_path,
utils::get_last_error_code(), "failed to delete file"); utils::get_last_error_code(), "failed to delete file");
@ -128,9 +128,8 @@ auto file_manager::file_manager::ring_buffer_open_file::download_chunk(
if (res == api_error::success) { if (res == api_error::success) {
res = do_io([&]() -> api_error { res = do_io([&]() -> api_error {
std::size_t bytes_written{}; std::size_t bytes_written{};
if (not nf_->write_bytes(buffer.data(), buffer.size(), if (not nf_->write(buffer, (chunk % ring_state_.size()) * chunk_size_,
(chunk % ring_state_.size()) * chunk_size_, &bytes_written)) {
bytes_written)) {
return api_error::os_error; return api_error::os_error;
} }
@ -169,8 +168,8 @@ void file_manager::ring_buffer_open_file::forward(std::size_t count) {
last_chunk_ = last_chunk_ =
std::min(total_chunks_ - 1U, first_chunk_ + ring_state_.size() - 1U); std::min(total_chunks_ - 1U, first_chunk_ + ring_state_.size() - 1U);
} else { } else {
for (std::size_t i = 0U; i < added; i++) { for (std::size_t idx = 0U; idx < added; ++idx) {
ring_state_[(first_chunk_ + i) % ring_state_.size()] = true; ring_state_[(first_chunk_ + idx) % ring_state_.size()] = true;
} }
first_chunk_ += added; first_chunk_ += added;
current_chunk_ += count; current_chunk_ += count;
@ -221,8 +220,8 @@ void file_manager::ring_buffer_open_file::reverse(std::size_t count) {
last_chunk_ = last_chunk_ =
std::min(total_chunks_ - 1U, first_chunk_ + ring_state_.size() - 1U); std::min(total_chunks_ - 1U, first_chunk_ + ring_state_.size() - 1U);
} else { } else {
for (std::size_t i = 0U; i < removed; i++) { for (std::size_t idx = 0U; idx < removed; ++idx) {
ring_state_[(last_chunk_ - i) % ring_state_.size()] = true; ring_state_[(last_chunk_ - idx) % ring_state_.size()] = true;
} }
first_chunk_ -= removed; first_chunk_ -= removed;
current_chunk_ -= count; current_chunk_ -= count;
@ -255,7 +254,7 @@ auto file_manager::ring_buffer_open_file::read(std::size_t read_size,
auto res = api_error::success; auto res = api_error::success;
for (std::size_t chunk = start_chunk_index; for (std::size_t chunk = start_chunk_index;
(res == api_error::success) && (read_size > 0U); chunk++) { (res == api_error::success) && (read_size > 0U); ++chunk) {
if (chunk > current_chunk_) { if (chunk > current_chunk_) {
forward(chunk - current_chunk_); forward(chunk - current_chunk_);
} else if (chunk < current_chunk_) { } else if (chunk < current_chunk_) {
@ -270,11 +269,11 @@ auto file_manager::ring_buffer_open_file::read(std::size_t read_size,
res = do_io([this, &buffer, &chunk, &data, read_offset, res = do_io([this, &buffer, &chunk, &data, read_offset,
&to_read]() -> api_error { &to_read]() -> api_error {
std::size_t bytes_read{}; std::size_t bytes_read{};
auto ret = nf_->read_bytes(buffer.data(), buffer.size(), auto ret =
((chunk % ring_state_.size()) * chunk_size_), nf_->read(buffer, ((chunk % ring_state_.size()) * chunk_size_),
bytes_read) &bytes_read)
? api_error::success ? api_error::success
: api_error::os_error; : api_error::os_error;
if (ret == api_error::success) { if (ret == api_error::success) {
data.insert(data.end(), data.insert(data.end(),
buffer.begin() + static_cast<std::int64_t>(read_offset), buffer.begin() + static_cast<std::int64_t>(read_offset),

View File

@ -29,8 +29,8 @@
#if defined(PROJECT_REQUIRE_ALPINE) && !defined(PROJECT_IS_MINGW) #if defined(PROJECT_REQUIRE_ALPINE) && !defined(PROJECT_IS_MINGW)
#include <filesystem> #include <filesystem>
#include <stdlib.h>
#include <pthread.h> #include <pthread.h>
#include <stdlib.h>
#endif // defined(PROJECT_REQUIRE_ALPINE) && !defined (PROJECT_IS_MINGW) #endif // defined(PROJECT_REQUIRE_ALPINE) && !defined (PROJECT_IS_MINGW)
#if defined(PROJECT_ENABLE_LIBSODIUM) #if defined(PROJECT_ENABLE_LIBSODIUM)
@ -44,6 +44,9 @@
#include "spdlog/spdlog.h" #include "spdlog/spdlog.h"
#include "initialize.hpp" #include "initialize.hpp"
#if defined(PROJECT_REQUIRE_ALPINE) && !defined(PROJECT_IS_MINGW)
#include "utils/path.hpp"
#endif // defined(PROJECT_REQUIRE_ALPINE) && !defined (PROJECT_IS_MINGW)
namespace repertory { namespace repertory {
auto project_initialize() -> bool { auto project_initialize() -> bool {
@ -61,11 +64,7 @@ auto project_initialize() -> bool {
pthread_attr_setguardsize(&attr, guard_size); pthread_attr_setguardsize(&attr, guard_size);
pthread_setattr_default_np(&attr); pthread_setattr_default_np(&attr);
const auto icu_dir = setenv("ICU_DATA", utils::path::combine(".", {"/icu"}).c_str(), 1);
std::filesystem::absolute(std::filesystem::path{"./icu"})
.lexically_normal()
.string();
setenv("ICU_DATA", icu_dir.c_str(), 1);
} }
#endif // defined(PROJECT_REQUIRE_ALPINE) && !defined (PROJECT_IS_MINGW) #endif // defined(PROJECT_REQUIRE_ALPINE) && !defined (PROJECT_IS_MINGW)

View File

@ -57,7 +57,7 @@ lock_data::~lock_data() {
auto lock_data::get_lock_data_file() -> std::string { auto lock_data::get_lock_data_file() -> std::string {
const auto dir = get_state_directory(); const auto dir = get_state_directory();
if (not utils::file::create_full_directory_path(dir)) { if (not utils::file::directory(dir).create_directory()) {
throw startup_exception("failed to create directory|sp|" + dir + "|err|" + throw startup_exception("failed to create directory|sp|" + dir + "|err|" +
std::to_string(utils::get_last_error_code())); std::to_string(utils::get_last_error_code()));
} }
@ -67,7 +67,7 @@ auto lock_data::get_lock_data_file() -> std::string {
auto lock_data::get_lock_file() -> std::string { auto lock_data::get_lock_file() -> std::string {
const auto dir = get_state_directory(); const auto dir = get_state_directory();
if (not utils::file::create_full_directory_path(dir)) { if (not utils::file::directory(dir).create_directory()) {
throw startup_exception("failed to create directory|sp|" + dir + "|err|" + throw startup_exception("failed to create directory|sp|" + dir + "|err|" +
std::to_string(utils::get_last_error_code())); std::to_string(utils::get_last_error_code()));
} }
@ -184,8 +184,11 @@ auto lock_data::wait_for_lock(int fd, std::uint8_t retry_count) -> int {
if (lock_status == -1) { if (lock_status == -1) {
lock_status = errno; lock_status = errno;
if (lock_status == EWOULDBLOCK) { if (lock_status == EWOULDBLOCK) {
auto sleep_ms = auto sleep_ms = std::min(remain, max_sleep);
utils::generate_random_between(1U, std::min(remain, max_sleep)); if (sleep_ms > 1U) {
sleep_ms = utils::generate_random_between(1U, sleep_ms);
}
std::this_thread::sleep_for(std::chrono::milliseconds(sleep_ms)); std::this_thread::sleep_for(std::chrono::milliseconds(sleep_ms));
remain -= sleep_ms; remain -= sleep_ms;
} }

View File

@ -37,10 +37,10 @@ auto base_provider::create_api_file(std::string path, std::string key,
api_file file{}; api_file file{};
file.api_path = utils::path::create_api_path(path); file.api_path = utils::path::create_api_path(path);
file.api_parent = utils::path::get_parent_api_path(file.api_path); file.api_parent = utils::path::get_parent_api_path(file.api_path);
file.accessed_date = utils::time::get_file_time_now(); file.accessed_date = utils::time::get_time_now();
file.changed_date = utils::time::get_file_time_now(); file.changed_date = utils::time::get_time_now();
file.creation_date = utils::time::get_file_time_now(); file.creation_date = utils::time::get_time_now();
file.modified_date = utils::time::get_file_time_now(); file.modified_date = utils::time::get_time_now();
file.key = key; file.key = key;
file.file_size = size; file.file_size = size;
return file; return file;
@ -455,7 +455,7 @@ void base_provider::remove_deleted_files() {
std::vector<removed_item> removed_list{}; std::vector<removed_item> removed_list{};
for (const auto &api_path : db3_->get_api_path_list()) { for (auto &&api_path : db3_->get_api_path_list()) {
api_meta_map meta{}; api_meta_map meta{};
if (get_item_meta(api_path, meta) == api_error::success) { if (get_item_meta(api_path, meta) == api_error::success) {
if (utils::string::to_bool(meta[META_DIRECTORY])) { if (utils::string::to_bool(meta[META_DIRECTORY])) {
@ -480,12 +480,12 @@ void base_provider::remove_deleted_files() {
} }
} }
for (const auto &item : removed_list) { for (auto &&item : removed_list) {
if (not item.directory) { if (not item.directory) {
if (utils::file::is_file(item.source_path)) { if (utils::file::file(item.source_path).exists()) {
const auto orphaned_directory = const auto orphaned_directory =
utils::path::combine(config_.get_data_directory(), {"orphaned"}); utils::path::combine(config_.get_data_directory(), {"orphaned"});
if (utils::file::create_full_directory_path(orphaned_directory)) { if (utils::file::directory(orphaned_directory).create_directory()) {
const auto parts = utils::string::split(item.api_path, '/', false); const auto parts = utils::string::split(item.api_path, '/', false);
const auto orphaned_file = utils::path::combine( const auto orphaned_file = utils::path::combine(
orphaned_directory, orphaned_directory,
@ -495,7 +495,8 @@ void base_provider::remove_deleted_files() {
event_system::instance().raise<orphaned_file_detected>( event_system::instance().raise<orphaned_file_detected>(
item.source_path); item.source_path);
if (utils::file::reset_modified_time(item.source_path) && if (utils::file::reset_modified_time(item.source_path) &&
utils::file::copy_file(item.source_path, orphaned_file)) { utils::file::file(item.source_path)
.copy_to(orphaned_file, true)) {
event_system::instance().raise<orphaned_file_processed>( event_system::instance().raise<orphaned_file_processed>(
item.source_path, orphaned_file); item.source_path, orphaned_file);
} else { } else {
@ -506,7 +507,7 @@ void base_provider::remove_deleted_files() {
} else { } else {
utils::error::raise_error( utils::error::raise_error(
function_name, std::to_string(utils::get_last_error_code()), function_name, std::to_string(utils::get_last_error_code()),
"failed to create orphaned director|sp|" + orphaned_directory); "failed to create orphaned directory|sp|" + orphaned_directory);
continue; continue;
} }
} }
@ -519,7 +520,7 @@ void base_provider::remove_deleted_files() {
} }
} }
for (const auto &item : removed_list) { for (auto &&item : removed_list) {
if (item.directory) { if (item.directory) {
db3_->remove_api_path(item.api_path); db3_->remove_api_path(item.api_path);
event_system::instance().raise<directory_removed_externally>( event_system::instance().raise<directory_removed_externally>(
@ -640,9 +641,9 @@ auto base_provider::start(api_item_added_callback api_item_added,
repertory::event_consumer consumer( repertory::event_consumer consumer(
"unmount_requested", "unmount_requested",
[&unmount_requested](const event &) { unmount_requested = true; }); [&unmount_requested](const event &) { unmount_requested = true; });
for (std::uint16_t i = 0U; not online && not unmount_requested && for (std::uint16_t idx = 0U; not online && not unmount_requested &&
(i < config_.get_online_check_retry_secs()); (idx < config_.get_online_check_retry_secs());
i++) { ++idx) {
online = is_online(); online = is_online();
if (not online) { if (not online) {
event_system::instance().raise<provider_offline>( event_system::instance().raise<provider_offline>(

View File

@ -28,12 +28,11 @@
#include "events/events.hpp" #include "events/events.hpp"
#include "types/repertory.hpp" #include "types/repertory.hpp"
#include "utils/collection.hpp" #include "utils/collection.hpp"
#include "utils/encrypt.hpp"
#include "utils/encrypting_reader.hpp" #include "utils/encrypting_reader.hpp"
#include "utils/encryption.hpp"
#include "utils/file_utils.hpp" #include "utils/file_utils.hpp"
#include "utils/path.hpp" #include "utils/path.hpp"
#include "utils/polling.hpp" #include "utils/polling.hpp"
#include "utils/time.hpp"
namespace { namespace {
const std::string directory_table = "directory"; const std::string directory_table = "directory";
@ -72,61 +71,24 @@ encrypt_provider::encrypt_provider(app_config &config) : config_(config) {}
auto encrypt_provider::create_api_file( auto encrypt_provider::create_api_file(
const std::string &api_path, bool directory, const std::string &api_path, bool directory,
const std::string &source_path) -> api_file { const std::string &source_path) -> api_file {
#if defined(_WIN32) auto times = utils::file::get_times(source_path);
struct _stat64 buf {}; if (not times.has_value()) {
_stat64(source_path.c_str(), &buf); throw std::runtime_error("failed to get file times");
#else }
struct stat buf {};
stat(source_path.c_str(), &buf);
#endif
api_file file{}; api_file file{};
file.accessed_date = times->get(utils::file::time_type::accessed);
file.api_path = api_path; file.api_path = api_path;
file.api_parent = utils::path::get_parent_api_path(api_path); file.api_parent = utils::path::get_parent_api_path(api_path);
file.changed_date = times->get(utils::file::time_type::modified);
file.creation_date = times->get(utils::file::time_type::created);
file.file_size = file.file_size =
directory directory
? 0U ? 0U
: utils::encryption::encrypting_reader::calculate_encrypted_size( : utils::encryption::encrypting_reader::calculate_encrypted_size(
source_path); source_path);
file.modified_date = times->get(utils::file::time_type::written);
file.source_path = source_path; file.source_path = source_path;
#if defined(__APPLE__)
file.changed_date =
buf.st_ctimespec.tv_nsec + (buf.st_ctimespec.tv_sec * NANOS_PER_SECOND);
file.accessed_date =
buf.st_atimespec.tv_nsec + (buf.st_atimespec.tv_sec * NANOS_PER_SECOND);
file.creation_date = buf.st_birthtimespec.tv_nsec +
(buf.st_birthtimespec.tv_sec * NANOS_PER_SECOND);
file.modified_date =
buf.st_mtimespec.tv_nsec + (buf.st_mtimespec.tv_sec * NANOS_PER_SECOND);
#elif defined(_WIN32)
auto ft = utils::time::unix_time_to_filetime(
utils::time::time64_to_unix_time(buf.st_atime));
file.accessed_date =
(static_cast<std::uint64_t>(ft.dwHighDateTime) << 32U) | ft.dwLowDateTime;
ft = utils::time::unix_time_to_filetime(
utils::time::time64_to_unix_time(buf.st_mtime));
file.changed_date =
(static_cast<std::uint64_t>(ft.dwHighDateTime) << 32U) | ft.dwLowDateTime;
ft = utils::time::unix_time_to_filetime(
utils::time::time64_to_unix_time(buf.st_ctime));
file.creation_date =
(static_cast<std::uint64_t>(ft.dwHighDateTime) << 32U) | ft.dwLowDateTime;
ft = utils::time::unix_time_to_filetime(utils::time::time64_to_unix_time(buf.st_mtime));
file.modified_date =
(static_cast<std::uint64_t>(ft.dwHighDateTime) << 32U) | ft.dwLowDateTime;
#else
file.changed_date = static_cast<std::uint64_t>(
buf.st_mtim.tv_nsec + (buf.st_mtim.tv_sec * NANOS_PER_SECOND));
file.accessed_date = static_cast<std::uint64_t>(
buf.st_atim.tv_nsec + (buf.st_atim.tv_sec * NANOS_PER_SECOND));
file.creation_date = static_cast<std::uint64_t>(
buf.st_ctim.tv_nsec + (buf.st_ctim.tv_sec * NANOS_PER_SECOND));
file.modified_date = static_cast<std::uint64_t>(
buf.st_mtim.tv_nsec + (buf.st_mtim.tv_sec * NANOS_PER_SECOND));
#endif
return file; return file;
} }
@ -136,19 +98,21 @@ void encrypt_provider::create_item_meta(api_meta_map &meta, bool directory,
#if defined(_WIN32) #if defined(_WIN32)
struct _stat64 buf {}; struct _stat64 buf {};
_stat64(file.source_path.c_str(), &buf); _stat64(file.source_path.c_str(), &buf);
#else #else // !defined(_WIN32)
struct stat buf {}; struct stat buf {};
stat(file.source_path.c_str(), &buf); stat(file.source_path.c_str(), &buf);
#endif #endif // defined(_WIN32)
meta[META_ACCESSED] = std::to_string(file.accessed_date); meta[META_ACCESSED] = std::to_string(file.accessed_date);
#if defined(_WIN32) #if defined(_WIN32)
meta[META_ATTRIBUTES] = meta[META_ATTRIBUTES] =
std::to_string(::GetFileAttributesA(file.source_path.c_str())); std::to_string(::GetFileAttributesA(file.source_path.c_str()) &
#endif ~static_cast<DWORD>(FILE_ATTRIBUTE_REPARSE_POINT));
#endif // defined(_WIN32)
#if defined(__APPLE__) #if defined(__APPLE__)
meta[META_BACKUP]; meta[META_BACKUP];
#endif #endif // defined(__APPLE__)
meta[META_CHANGED] = std::to_string(file.changed_date); meta[META_CHANGED] = std::to_string(file.changed_date);
meta[META_CREATION] = std::to_string(file.creation_date); meta[META_CREATION] = std::to_string(file.creation_date);
meta[META_DIRECTORY] = utils::string::from_bool(directory); meta[META_DIRECTORY] = utils::string::from_bool(directory);
@ -157,7 +121,7 @@ void encrypt_provider::create_item_meta(api_meta_map &meta, bool directory,
meta[META_MODIFIED] = std::to_string(file.modified_date); meta[META_MODIFIED] = std::to_string(file.modified_date);
#if defined(__APPLE__) #if defined(__APPLE__)
meta[META_OSXFLAGS]; meta[META_OSXFLAGS];
#endif #endif // defined(__APPLE__)
meta[META_SIZE] = std::to_string(file.file_size); meta[META_SIZE] = std::to_string(file.file_size);
meta[META_SOURCE] = file.source_path; meta[META_SOURCE] = file.source_path;
meta[META_UID] = std::to_string(buf.st_uid); meta[META_UID] = std::to_string(buf.st_uid);
@ -180,13 +144,10 @@ auto encrypt_provider::do_fs_operation(
callback) const -> api_error { callback) const -> api_error {
auto cfg = config_.get_encrypt_config(); auto cfg = config_.get_encrypt_config();
std::string source_path{api_path}; std::string source_path{api_path};
if (api_path != "/") { if (api_path != "/" && not utils::encryption::decrypt_file_path(
auto res = cfg.encryption_token, source_path)) {
utils::encryption::decrypt_file_path(cfg.encryption_token, source_path); return directory ? api_error::directory_not_found
if (res != api_error::success) { : api_error::item_not_found;
return directory ? api_error::directory_not_found
: api_error::item_not_found;
}
} }
source_path = utils::path::combine(cfg.path, {source_path}); source_path = utils::path::combine(cfg.path, {source_path});
@ -197,7 +158,11 @@ auto encrypt_provider::do_fs_operation(
: api_error::item_not_found; : api_error::item_not_found;
} }
auto exists = utils::file::is_file(source_path); auto exists =
utils::file::file{
source_path,
}
.exists();
if (exists && directory) { if (exists && directory) {
return api_error::item_exists; return api_error::item_exists;
} }
@ -205,7 +170,11 @@ auto encrypt_provider::do_fs_operation(
return api_error::item_not_found; return api_error::item_not_found;
} }
exists = utils::file::is_directory(source_path); exists =
utils::file::directory{
source_path,
}
.exists();
if (exists && not directory) { if (exists && not directory) {
return api_error::item_exists; return api_error::item_exists;
} }
@ -271,10 +240,7 @@ auto encrypt_provider::get_directory_item_count(
[&api_path, &count](const encrypt_config & /* cfg */, [&api_path, &count](const encrypt_config & /* cfg */,
const std::string &source_path) -> api_error { const std::string &source_path) -> api_error {
try { try {
for ([[maybe_unused]] const auto &dir_entry : count = utils::file::directory{source_path}.count();
std::filesystem::directory_iterator(source_path)) {
count++;
}
} catch (const std::exception &ex) { } catch (const std::exception &ex) {
utils::error::raise_api_path_error( utils::error::raise_api_path_error(
function_name, api_path, source_path, ex, function_name, api_path, source_path, ex,
@ -301,15 +267,15 @@ auto encrypt_provider::get_directory_items(
[this, &list](const encrypt_config &cfg, [this, &list](const encrypt_config &cfg,
const std::string &source_path) -> api_error { const std::string &source_path) -> api_error {
try { try {
for (const auto &dir_entry : for (auto &&dir_entry :
std::filesystem::directory_iterator(source_path)) { utils::file::directory{source_path}.get_items()) {
try { try {
std::string current_api_path{}; std::string current_api_path{};
if (dir_entry.is_directory()) { if (dir_entry->is_directory_item()) {
auto result = db::db_select{*db_, directory_table} auto result = db::db_select{*db_, directory_table}
.column("api_path") .column("api_path")
.where("source_path") .where("source_path")
.equals(dir_entry.path().string()) .equals(dir_entry->get_path())
.go(); .go();
std::optional<db::db_select::row> row; std::optional<db::db_select::row> row;
if (result.get_row(row) && row.has_value()) { if (result.get_row(row) && row.has_value()) {
@ -317,12 +283,13 @@ auto encrypt_provider::get_directory_items(
row->get_column("api_path").get_value<std::string>(); row->get_column("api_path").get_value<std::string>();
} }
if (current_api_path.empty()) { if (current_api_path.empty()) {
process_directory_entry(dir_entry, cfg, current_api_path); process_directory_entry(*dir_entry.get(), cfg,
current_api_path);
result = db::db_select{*db_, directory_table} result = db::db_select{*db_, directory_table}
.column("api_path") .column("api_path")
.where("source_path") .where("source_path")
.equals(dir_entry.path().string()) .equals(dir_entry->get_path())
.go(); .go();
row.reset(); row.reset();
if (not(result.get_row(row) && row.has_value())) { if (not(result.get_row(row) && row.has_value())) {
@ -337,7 +304,7 @@ auto encrypt_provider::get_directory_items(
auto result = db::db_select{*db_, file_table} auto result = db::db_select{*db_, file_table}
.column("data") .column("data")
.where("source_path") .where("source_path")
.equals(dir_entry.path().string()) .equals(dir_entry->get_path())
.go(); .go();
std::optional<db::db_select::row> row; std::optional<db::db_select::row> row;
if (result.get_row(row) && row.has_value()) { if (result.get_row(row) && row.has_value()) {
@ -346,7 +313,7 @@ auto encrypt_provider::get_directory_items(
} }
if (api_path_data.empty()) { if (api_path_data.empty()) {
if (not process_directory_entry(dir_entry, cfg, if (not process_directory_entry(*dir_entry.get(), cfg,
current_api_path)) { current_api_path)) {
continue; continue;
} }
@ -357,14 +324,14 @@ auto encrypt_provider::get_directory_items(
} }
} }
auto file = auto file = create_api_file(current_api_path,
create_api_file(current_api_path, dir_entry.is_directory(), dir_entry->is_directory_item(),
dir_entry.path().string()); dir_entry->get_path());
directory_item dir_item{}; directory_item dir_item{};
dir_item.api_parent = file.api_parent; dir_item.api_parent = file.api_parent;
dir_item.api_path = file.api_path; dir_item.api_path = file.api_path;
dir_item.directory = dir_entry.is_directory(); dir_item.directory = dir_entry->is_directory_item();
dir_item.resolved = true; dir_item.resolved = true;
dir_item.size = file.file_size; dir_item.size = file.file_size;
create_item_meta(dir_item.meta, dir_item.directory, file); create_item_meta(dir_item.meta, dir_item.directory, file);
@ -372,7 +339,7 @@ auto encrypt_provider::get_directory_items(
list.emplace_back(std::move(dir_item)); list.emplace_back(std::move(dir_item));
} catch (const std::exception &ex) { } catch (const std::exception &ex) {
utils::error::raise_error(function_name, ex, utils::error::raise_error(function_name, ex,
dir_entry.path().string(), dir_entry->get_path(),
"failed to process directory item"); "failed to process directory item");
} }
} }
@ -405,28 +372,40 @@ auto encrypt_provider::get_directory_items(
auto encrypt_provider::get_file(const std::string &api_path, auto encrypt_provider::get_file(const std::string &api_path,
api_file &file) const -> api_error { api_file &file) const -> api_error {
bool exists{}; static constexpr const std::string_view function_name{
auto res = is_directory(api_path, exists); static_cast<const char *>(__FUNCTION__),
if (res != api_error::success) { };
return res;
} try {
if (exists) { bool exists{};
return api_error::directory_exists; auto res = is_directory(api_path, exists);
if (res != api_error::success) {
return res;
}
if (exists) {
return api_error::directory_exists;
}
auto result = db::db_select{*db_, source_table}
.column("source_path")
.where("api_path")
.equals(api_path)
.go();
std::optional<db::db_select::row> row;
if (not(result.get_row(row) && row.has_value())) {
return api_error::item_not_found;
}
file = create_api_file(
api_path, false,
row->get_column("source_path").get_value<std::string>());
return api_error::success;
} catch (const std::exception &ex) {
utils::error::raise_error(function_name, ex, api_path,
"failed to get file");
} }
auto result = db::db_select{*db_, source_table} return api_error::error;
.column("source_path")
.where("api_path")
.equals(api_path)
.go();
std::optional<db::db_select::row> row;
if (not(result.get_row(row) && row.has_value())) {
return api_error::item_not_found;
}
file = create_api_file(
api_path, false, row->get_column("source_path").get_value<std::string>());
return api_error::success;
} }
auto encrypt_provider::get_file_list(api_file_list &list) const -> api_error { auto encrypt_provider::get_file_list(api_file_list &list) const -> api_error {
@ -435,14 +414,15 @@ auto encrypt_provider::get_file_list(api_file_list &list) const -> api_error {
}; };
const auto cfg = config_.get_encrypt_config(); const auto cfg = config_.get_encrypt_config();
event_system::instance().raise<debug_log>(std::string{function_name},
cfg.path, "");
try { try {
for (const auto &dir_entry : for (auto &&dir_entry : utils::file::directory{cfg.path}.get_items()) {
std::filesystem::recursive_directory_iterator(cfg.path)) {
std::string api_path{}; std::string api_path{};
if (process_directory_entry(dir_entry, cfg, api_path)) { if (process_directory_entry(*dir_entry.get(), cfg, api_path)) {
list.emplace_back(create_api_file(api_path, dir_entry.is_directory(), list.emplace_back(create_api_file(
dir_entry.path().string())); api_path, dir_entry->is_directory_item(), dir_entry->get_path()));
} }
} }
@ -565,22 +545,33 @@ auto encrypt_provider::get_filesystem_item_from_source_path(
auto encrypt_provider::get_filesystem_item_and_file( auto encrypt_provider::get_filesystem_item_and_file(
const std::string &api_path, api_file &file, const std::string &api_path, api_file &file,
filesystem_item &fsi) const -> api_error { filesystem_item &fsi) const -> api_error {
bool exists{}; static constexpr const std::string_view function_name{
auto res = is_directory(api_path, exists); static_cast<const char *>(__FUNCTION__),
if (res != api_error::success) { };
return res;
} try {
if (exists) { bool exists{};
return api_error::directory_exists; auto res = is_directory(api_path, exists);
if (res != api_error::success) {
return res;
}
if (exists) {
return api_error::directory_exists;
}
auto ret = get_filesystem_item(api_path, exists, fsi);
if (ret != api_error::success) {
return ret;
}
file = create_api_file(api_path, false, fsi.source_path);
return api_error::success;
} catch (const std::exception &ex) {
utils::error::raise_error(function_name, ex, api_path,
"failed to get filesystem_item and file");
} }
auto ret = get_filesystem_item(api_path, exists, fsi); return api_error::error;
if (ret != api_error::success) {
return ret;
}
file = create_api_file(api_path, false, fsi.source_path);
return api_error::success;
} }
auto encrypt_provider::get_pinned_files() const -> std::vector<std::string> { auto encrypt_provider::get_pinned_files() const -> std::vector<std::string> {
@ -589,27 +580,38 @@ auto encrypt_provider::get_pinned_files() const -> std::vector<std::string> {
auto encrypt_provider::get_item_meta(const std::string &api_path, auto encrypt_provider::get_item_meta(const std::string &api_path,
api_meta_map &meta) const -> api_error { api_meta_map &meta) const -> api_error {
auto result = db::db_select{*db_, source_table} static constexpr const std::string_view function_name{
.column("source_path") static_cast<const char *>(__FUNCTION__),
.where("api_path") };
.equals(api_path)
.go(); try {
std::optional<db::db_select::row> row; auto result = db::db_select{*db_, source_table}
if (not(result.get_row(row) && row.has_value())) { .column("source_path")
return api_error::item_not_found; .where("api_path")
.equals(api_path)
.go();
std::optional<db::db_select::row> row;
if (not(result.get_row(row) && row.has_value())) {
return api_error::item_not_found;
}
auto source_path = row->get_column("source_path").get_value<std::string>();
bool exists{};
auto res = is_directory(api_path, exists);
if (res != api_error::success) {
return res;
}
auto file = create_api_file(api_path, exists, source_path);
create_item_meta(meta, exists, file);
return api_error::success;
} catch (const std::exception &ex) {
utils::error::raise_error(function_name, ex, api_path,
"failed to get item meta");
} }
auto source_path = row->get_column("source_path").get_value<std::string>(); return api_error::error;
bool exists{};
auto res = is_directory(api_path, exists);
if (res != api_error::success) {
return res;
}
auto file = create_api_file(api_path, exists, source_path);
create_item_meta(meta, exists, file);
return api_error::success;
} }
auto encrypt_provider::get_item_meta(const std::string &api_path, auto encrypt_provider::get_item_meta(const std::string &api_path,
@ -626,8 +628,9 @@ auto encrypt_provider::get_item_meta(const std::string &api_path,
} }
auto encrypt_provider::get_total_drive_space() const -> std::uint64_t { auto encrypt_provider::get_total_drive_space() const -> std::uint64_t {
const auto cfg = config_.get_encrypt_config(); auto total_space =
return utils::file::get_total_drive_space(cfg.path); utils::file::get_total_drive_space(config_.get_encrypt_config().path);
return total_space.value_or(0U);
} }
auto encrypt_provider::get_total_item_count() const -> std::uint64_t { auto encrypt_provider::get_total_item_count() const -> std::uint64_t {
@ -644,8 +647,10 @@ auto encrypt_provider::get_total_item_count() const -> std::uint64_t {
} }
auto encrypt_provider::get_used_drive_space() const -> std::uint64_t { auto encrypt_provider::get_used_drive_space() const -> std::uint64_t {
const auto cfg = config_.get_encrypt_config(); auto free_space =
return get_total_drive_space() - utils::file::get_free_drive_space(cfg.path); utils::file::get_free_drive_space(config_.get_encrypt_config().path);
return free_space.has_value() ? get_total_drive_space() - free_space.value()
: 0U;
} }
auto encrypt_provider::is_directory(const std::string &api_path, auto encrypt_provider::is_directory(const std::string &api_path,
@ -661,8 +666,11 @@ auto encrypt_provider::is_directory(const std::string &api_path,
return api_error::success; return api_error::success;
} }
exists = utils::file::is_directory( exists =
row->get_column("source_path").get_value<std::string>()); utils::file::directory{
row->get_column("source_path").get_value<std::string>(),
}
.exists();
return api_error::success; return api_error::success;
} }
@ -679,8 +687,11 @@ auto encrypt_provider::is_file(const std::string &api_path,
return api_error::success; return api_error::success;
} }
exists = utils::file::is_file( exists =
row->get_column("source_path").get_value<std::string>()); utils::file::file{
row->get_column("source_path").get_value<std::string>(),
}
.exists();
return api_error::success; return api_error::success;
} }
@ -690,20 +701,24 @@ auto encrypt_provider::is_file_writeable(const std::string & /*api_path*/) const
} }
auto encrypt_provider::is_online() const -> bool { auto encrypt_provider::is_online() const -> bool {
return std::filesystem::exists(config_.get_encrypt_config().path); return utils::file::directory{
config_.get_encrypt_config().path,
}
.exists();
} }
auto encrypt_provider::is_rename_supported() const -> bool { return false; } auto encrypt_provider::is_rename_supported() const -> bool { return false; }
auto encrypt_provider::process_directory_entry( auto encrypt_provider::process_directory_entry(
const std::filesystem::directory_entry &dir_entry, const utils::file::i_fs_item &dir_entry, const encrypt_config &cfg,
const encrypt_config &cfg, std::string &api_path) const -> bool { std::string &api_path) const -> bool {
const auto add_directory = [this, &cfg](auto dir_path) -> std::string { const auto add_directory = [this,
&cfg](std::string_view dir_path) -> std::string {
auto encrypted_parts = utils::string::split( auto encrypted_parts = utils::string::split(
utils::path::create_api_path(dir_path.string()), '/', false); utils::path::create_api_path(dir_path), '/', false);
for (std::size_t part_idx = 1U; part_idx < encrypted_parts.size(); for (std::size_t part_idx = 1U; part_idx < encrypted_parts.size();
part_idx++) { ++part_idx) {
data_buffer encrypted_data; data_buffer encrypted_data;
utils::encryption::encrypt_data( utils::encryption::encrypt_data(
cfg.encryption_token, cfg.encryption_token,
@ -718,14 +733,9 @@ auto encrypt_provider::process_directory_entry(
std::size_t current_idx{1U}; std::size_t current_idx{1U};
std::string current_encrypted_path{}; std::string current_encrypted_path{};
std::string current_source_path{cfg.path}; auto current_source_path{cfg.path};
for (const auto &part : dir_path) { for (auto &&part : utils::path::get_parts(dir_path)) {
if (part.string() == "/") { current_source_path = utils::path::combine(current_source_path, {part});
continue;
}
current_source_path =
utils::path::combine(current_source_path, {part.string()});
std::string current_api_path{}; std::string current_api_path{};
auto result = db::db_select{*db_, directory_table} auto result = db::db_select{*db_, directory_table}
@ -767,19 +777,21 @@ auto encrypt_provider::process_directory_entry(
return current_encrypted_path; return current_encrypted_path;
}; };
if (dir_entry.is_directory()) { if (dir_entry.is_directory_item()) {
api_path = add_directory(dir_entry.path().lexically_relative(cfg.path)); api_path = add_directory(
utils::path::get_relative_path(dir_entry.get_path(), cfg.path));
return false; return false;
} }
if (dir_entry.is_regular_file() && not dir_entry.is_symlink()) { if (dir_entry.is_file_item() && not dir_entry.is_symlink()) {
const auto relative_path = dir_entry.path().lexically_relative(cfg.path); auto relative_path =
utils::path::get_relative_path(dir_entry.get_path(), cfg.path);
std::string api_path_data{}; std::string api_path_data{};
auto result = db::db_select{*db_, file_table} auto result = db::db_select{*db_, file_table}
.column("data") .column("data")
.where("source_path") .where("source_path")
.equals(dir_entry.path().string()) .equals(dir_entry.get_path())
.go(); .go();
std::optional<db::db_select::row> row; std::optional<db::db_select::row> row;
if (result.get_row(row) && row.has_value()) { if (result.get_row(row) && row.has_value()) {
@ -790,7 +802,7 @@ auto encrypt_provider::process_directory_entry(
result = db::db_select{*db_, directory_table} result = db::db_select{*db_, directory_table}
.column("api_path") .column("api_path")
.where("source_path") .where("source_path")
.equals(dir_entry.path().parent_path().string()) .equals(utils::path::get_parent_path(dir_entry.get_path()))
.go(); .go();
row.reset(); row.reset();
if (result.get_row(row) && row.has_value()) { if (result.get_row(row) && row.has_value()) {
@ -798,15 +810,15 @@ auto encrypt_provider::process_directory_entry(
} }
if (api_parent.empty()) { if (api_parent.empty()) {
api_parent = add_directory(relative_path.parent_path()); api_parent = add_directory(utils::path::get_parent_path(relative_path));
} }
if (api_path_data.empty()) { if (api_path_data.empty()) {
stop_type stop_requested = false; stop_type stop_requested = false;
utils::encryption::encrypting_reader reader( utils::encryption::encrypting_reader reader(
relative_path.filename().string(), dir_entry.path().string(), utils::path::strip_to_file_name(relative_path), dir_entry.get_path(),
stop_requested, cfg.encryption_token, stop_requested, cfg.encryption_token,
relative_path.parent_path().string()); utils::path::get_parent_path(relative_path));
api_path = utils::path::create_api_path(api_parent + "/" + api_path = utils::path::create_api_path(api_parent + "/" +
reader.get_encrypted_file_name()); reader.get_encrypted_file_name());
@ -814,17 +826,22 @@ auto encrypt_provider::process_directory_entry(
json data = { json data = {
{"api_path", api_path}, {"api_path", api_path},
{"iv_list", iv_list}, {"iv_list", iv_list},
{"original_file_size", dir_entry.file_size()}, {
"original_file_size",
(dynamic_cast<const utils::file::i_file *>(&dir_entry)
->size()
.value_or(0U)),
},
}; };
auto ins_res = db::db_insert{*db_, file_table} auto ins_res = db::db_insert{*db_, file_table}
.column_value("source_path", dir_entry.path().string()) .column_value("source_path", dir_entry.get_path())
.column_value("data", data.dump()) .column_value("data", data.dump())
.go(); .go();
// TODO handle error // TODO handle error
ins_res = db::db_insert{*db_, source_table} ins_res = db::db_insert{*db_, source_table}
.column_value("api_path", api_path) .column_value("api_path", api_path)
.column_value("source_path", dir_entry.path().string()) .column_value("source_path", dir_entry.get_path())
.go(); .go();
// TODO handle error // TODO handle error
event_system::instance().raise<filesystem_item_added>(api_path, event_system::instance().raise<filesystem_item_added>(api_path,
@ -874,11 +891,13 @@ auto encrypt_provider::read_file_bytes(const std::string &api_path,
auto file_data = row->get_column("data").get_value_as_json(); auto file_data = row->get_column("data").get_value_as_json();
std::uint64_t file_size{}; auto opt_size = utils::file::file{source_path}.size();
if (not utils::file::get_file_size(source_path, file_size)) { if (not opt_size.has_value()) {
return api_error::os_error; return api_error::os_error;
} }
auto file_size{opt_size.value()};
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{};
@ -888,13 +907,12 @@ auto encrypt_provider::read_file_bytes(const std::string &api_path,
unique_recur_mutex_lock reader_lookup_lock(reader_lookup_mtx_); unique_recur_mutex_lock reader_lookup_lock(reader_lookup_mtx_);
if (file_data.at("original_file_size").get<std::uint64_t>() != file_size) { if (file_data.at("original_file_size").get<std::uint64_t>() != file_size) {
const auto relative_path = auto relative_path = utils::path::get_relative_path(source_path, cfg.path);
std::filesystem::path(source_path).lexically_relative(cfg.path);
auto info = std::make_shared<reader_info>(); auto info = std::make_shared<reader_info>();
info->reader = std::make_unique<utils::encryption::encrypting_reader>( info->reader = std::make_unique<utils::encryption::encrypting_reader>(
relative_path.filename().string(), source_path, stop_requested, relative_path, source_path, stop_requested, cfg.encryption_token,
cfg.encryption_token, relative_path.parent_path().string()); utils::path::get_parent_path(relative_path));
reader_lookup_[source_path] = info; reader_lookup_[source_path] = info;
iv_list = info->reader->get_iv_list(); iv_list = info->reader->get_iv_list();
@ -965,9 +983,9 @@ void encrypt_provider::remove_deleted_files() {
} }
} }
for (const auto &row : row_list) { for (auto &&row : row_list) {
auto source_path = row.get_column("source_path").get_value<std::string>(); auto source_path = row.get_column("source_path").get_value<std::string>();
if (not std::filesystem::exists(source_path)) { if (not utils::path::exists(source_path)) {
auto api_path = row.get_column("api_path").get_value<std::string>(); auto api_path = row.get_column("api_path").get_value<std::string>();
result = db::db_select{*db_, file_table} result = db::db_select{*db_, file_table}
.column("source_path") .column("source_path")
@ -979,7 +997,7 @@ void encrypt_provider::remove_deleted_files() {
} }
} }
for (const auto &item : removed_list) { for (auto &&item : removed_list) {
if (not item.directory) { if (not item.directory) {
auto del_res = db::db_select{*db_, source_table} auto del_res = db::db_select{*db_, source_table}
.delete_query() .delete_query()
@ -998,7 +1016,7 @@ void encrypt_provider::remove_deleted_files() {
} }
} }
for (const auto &item : removed_list) { for (auto &&item : removed_list) {
if (item.directory) { if (item.directory) {
auto del_res = db::db_select{*db_, source_table} auto del_res = db::db_select{*db_, source_table}
.delete_query() .delete_query()
@ -1043,7 +1061,7 @@ auto encrypt_provider::start(api_item_added_callback /*api_item_added*/,
} }
db_.reset(db3); db_.reset(db3);
for (const auto &create : sql_create_tables) { for (auto &&create : sql_create_tables) {
std::string err; std::string err;
if (not db::execute_sql(*db_, create.second, err)) { if (not db::execute_sql(*db_, create.second, err)) {
utils::error::raise_error(function_name, "failed to create table|" + utils::error::raise_error(function_name, "failed to create table|" +

View File

@ -288,7 +288,7 @@ auto meta_db::set_item_meta(const std::string &api_path,
// TODO handle error // TODO handle error
} }
for (const auto &item : meta) { for (auto &&item : meta) {
existing_meta[item.first] = item.second; existing_meta[item.first] = item.second;
} }

View File

@ -27,12 +27,11 @@
#include "file_manager/i_file_manager.hpp" #include "file_manager/i_file_manager.hpp"
#include "types/repertory.hpp" #include "types/repertory.hpp"
#include "types/s3.hpp" #include "types/s3.hpp"
#include "types/startup_exception.hpp"
#include "utils/collection.hpp" #include "utils/collection.hpp"
#include "utils/encrypt.hpp"
#include "utils/encrypting_reader.hpp" #include "utils/encrypting_reader.hpp"
#include "utils/encryption.hpp"
#include "utils/error_utils.hpp" #include "utils/error_utils.hpp"
#include "utils/file_utils.hpp" #include "utils/file.hpp"
#include "utils/path.hpp" #include "utils/path.hpp"
#include "utils/polling.hpp" #include "utils/polling.hpp"
#include "utils/string.hpp" #include "utils/string.hpp"
@ -60,6 +59,24 @@ auto s3_provider::add_if_not_found(
return api_error::success; return api_error::success;
} }
auto s3_provider::convert_api_date(std::string_view date) -> std::uint64_t {
// 2009-10-12T17:50:30.000Z
auto date_parts = utils::string::split(date, '.', true);
auto date_time = date_parts.at(0U);
auto nanos = utils::string::to_uint64(
utils::string::split(date_parts.at(1U), 'Z', true).at(0U));
struct tm tm1 {};
#if defined(_WIN32)
utils::time::strptime(date_time.c_str(), "%Y-%m-%dT%T", &tm1);
#else
strptime(date_time.c_str(), "%Y-%m-%dT%T", &tm1);
#endif
return nanos + (static_cast<std::uint64_t>(mktime(&tm1)) *
utils::time::NANOS_PER_SECOND);
}
auto s3_provider::create_directory_impl(const std::string &api_path, auto s3_provider::create_directory_impl(const std::string &api_path,
api_meta_map &meta) -> api_error { api_meta_map &meta) -> api_error {
static constexpr const std::string_view function_name{ static constexpr const std::string_view function_name{
@ -162,13 +179,13 @@ auto s3_provider::create_path_directories(
std::string cur_key{'/'}; std::string cur_key{'/'};
std::string cur_path{'/'}; std::string cur_path{'/'};
for (std::size_t i = 0U; i < path_parts.size(); i++) { for (std::size_t idx = 0U; idx < path_parts.size(); ++idx) {
if (is_encrypted) { if (is_encrypted) {
cur_key = utils::path::create_api_path( cur_key = utils::path::create_api_path(
utils::path::combine(cur_key, {key_parts.at(i)})); utils::path::combine(cur_key, {key_parts.at(idx)}));
} }
cur_path = utils::path::create_api_path( cur_path = utils::path::create_api_path(
utils::path::combine(cur_path, {path_parts.at(i)})); utils::path::combine(cur_path, {path_parts.at(idx)}));
api_meta_map meta{}; api_meta_map meta{};
auto res = get_item_meta(cur_path, meta); auto res = get_item_meta(cur_path, meta);
@ -189,11 +206,10 @@ auto s3_provider::create_path_directories(
auto s3_provider::decrypt_object_name(std::string &object_name) const auto s3_provider::decrypt_object_name(std::string &object_name) const
-> api_error { -> api_error {
auto parts = utils::string::split(object_name, '/', false); auto parts = utils::string::split(object_name, '/', false);
for (auto &part : parts) { for (auto &&part : parts) {
auto err = utils::encryption::decrypt_file_name( if (not utils::encryption::decrypt_file_name(
get_config().get_s3_config().encryption_token, part); get_config().get_s3_config().encryption_token, part)) {
if (err != api_error::success) { return api_error::decryption_error;
return err;
} }
} }
@ -313,10 +329,9 @@ auto s3_provider::get_directory_items_impl(
std::string child_object_name; std::string child_object_name;
if (is_encrypted) { if (is_encrypted) {
child_object_name = child_api_path; child_object_name = child_api_path;
ret = utils::encryption::decrypt_file_path(cfg.encryption_token, if (not utils::encryption::decrypt_file_path(cfg.encryption_token,
child_api_path); child_api_path)) {
if (ret != api_error::success) { return api_error::decryption_error;
return ret;
} }
} }
@ -353,14 +368,14 @@ auto s3_provider::get_directory_items_impl(
}; };
auto node_list = doc.select_nodes("/ListBucketResult/CommonPrefixes/Prefix"); auto node_list = doc.select_nodes("/ListBucketResult/CommonPrefixes/Prefix");
for (const auto &node : node_list) { for (auto &&node : node_list) {
add_directory_item( add_directory_item(
true, node.node().text().as_string(), true, node.node().text().as_string(),
[](const directory_item &) -> std::uint64_t { return 0U; }); [](const directory_item &) -> std::uint64_t { return 0U; });
} }
node_list = doc.select_nodes("/ListBucketResult/Contents"); node_list = doc.select_nodes("/ListBucketResult/Contents");
for (const auto &node : node_list) { for (auto &&node : node_list) {
auto child_object_name = utils::path::create_api_path( auto child_object_name = utils::path::create_api_path(
node.node().select_node("Key").node().text().as_string()); node.node().select_node("Key").node().text().as_string());
if (child_object_name != utils::path::create_api_path(prefix)) { if (child_object_name != utils::path::create_api_path(prefix)) {
@ -394,7 +409,7 @@ auto s3_provider::get_file(const std::string &api_path,
return res; return res;
} }
file.accessed_date = utils::time::get_file_time_now(); file.accessed_date = utils::time::get_time_now();
file.api_path = api_path; file.api_path = api_path;
file.api_parent = utils::path::get_parent_api_path(file.api_path); file.api_parent = utils::path::get_parent_api_path(file.api_path);
file.changed_date = utils::aws::format_time(result.last_modified); file.changed_date = utils::aws::format_time(result.last_modified);
@ -431,7 +446,7 @@ auto s3_provider::get_file_list(api_file_list &list) const -> api_error {
} }
auto node_list = doc.select_nodes("/ListBucketResult/Contents"); auto node_list = doc.select_nodes("/ListBucketResult/Contents");
for (const auto &node : node_list) { for (auto &&node : node_list) {
auto api_path = auto api_path =
std::string{node.node().select_node("Key").node().text().as_string()}; std::string{node.node().select_node("Key").node().text().as_string()};
if (not utils::string::ends_with(api_path, "/")) { if (not utils::string::ends_with(api_path, "/")) {
@ -449,8 +464,8 @@ auto s3_provider::get_file_list(api_file_list &list) const -> api_error {
api_file file{}; api_file file{};
file.api_path = utils::path::create_api_path(api_path); file.api_path = utils::path::create_api_path(api_path);
file.api_parent = utils::path::get_parent_api_path(file.api_path); file.api_parent = utils::path::get_parent_api_path(file.api_path);
file.accessed_date = utils::time::get_file_time_now(); file.accessed_date = utils::time::get_time_now();
file.changed_date = utils::convert_api_date( file.changed_date = convert_api_date(
node.node().select_node("LastModified").node().text().as_string()); node.node().select_node("LastModified").node().text().as_string());
file.creation_date = file.changed_date; file.creation_date = file.changed_date;
file.file_size = file.file_size =
@ -674,10 +689,10 @@ auto s3_provider::read_file_bytes(const std::string &api_path, std::size_t size,
&stop_requested](std::size_t read_size, std::size_t read_offset, &stop_requested](std::size_t read_size, std::size_t read_offset,
data_buffer &read_buffer) -> api_error { data_buffer &read_buffer) -> api_error {
auto res = api_error::error; auto res = api_error::error;
for (std::uint32_t i = 0U; for (std::uint32_t idx = 0U;
not stop_requested && res != api_error::success && not stop_requested && res != api_error::success &&
i < get_config().get_retry_read_count() + 1U; idx < get_config().get_retry_read_count() + 1U;
i++) { ++idx) {
curl::requests::http_get get{}; curl::requests::http_get get{};
get.aws_service = "aws:amz:" + cfg.region + ":s3"; get.aws_service = "aws:amz:" + cfg.region + ":s3";
get.headers["response-content-type"] = "binary/octet-stream"; get.headers["response-content-type"] = "binary/octet-stream";
@ -698,13 +713,13 @@ auto s3_provider::read_file_bytes(const std::string &api_path, std::size_t size,
function_name, api_path, api_error::comm_error, function_name, api_path, api_error::comm_error,
"read file bytes failed|offset|" + std::to_string(read_offset) + "read file bytes failed|offset|" + std::to_string(read_offset) +
"|size|" + std::to_string(read_size) + "|retry|" + "|size|" + std::to_string(read_size) + "|retry|" +
std::to_string(i + 1U)); std::to_string(idx + 1U));
} else { } else {
utils::error::raise_api_path_error( utils::error::raise_api_path_error(
function_name, api_path, response_code, function_name, api_path, response_code,
"read file bytes failed|offset|" + std::to_string(read_offset) + "read file bytes failed|offset|" + std::to_string(read_offset) +
"|size|" + std::to_string(read_size) + "|retry|" + "|size|" + std::to_string(read_size) + "|retry|" +
std::to_string(i + 1U)); std::to_string(idx + 1U));
} }
std::this_thread::sleep_for(1s); std::this_thread::sleep_for(1s);
}; };
@ -735,15 +750,18 @@ auto s3_provider::read_file_bytes(const std::string &api_path, std::size_t size,
const auto total_size = utils::string::to_uint64(temp); const auto total_size = utils::string::to_uint64(temp);
return utils::encryption::read_encrypted_range( return utils::encryption::read_encrypted_range(
{offset, offset + size - 1U}, {offset, offset + size - 1U},
utils::encryption::generate_key<utils::encryption::hash_256_t>( utils::encryption::generate_key<utils::encryption::hash_256_t>(
cfg.encryption_token), cfg.encryption_token),
[&](data_buffer &ct_buffer, std::uint64_t start_offset, [&](data_buffer &ct_buffer, std::uint64_t start_offset,
std::uint64_t end_offset) -> api_error { std::uint64_t end_offset) -> bool {
return read_bytes((end_offset - start_offset + 1U), start_offset, return read_bytes((end_offset - start_offset + 1U),
ct_buffer); start_offset,
}, ct_buffer) == api_error::success;
total_size, data); },
total_size, data)
? api_error::success
: api_error::decryption_error;
} }
return read_bytes(size, offset, data); return read_bytes(size, offset, data);
@ -865,9 +883,12 @@ auto s3_provider::upload_file_impl(const std::string &api_path,
const std::string &source_path, const std::string &source_path,
stop_type &stop_requested) -> api_error { stop_type &stop_requested) -> api_error {
std::uint64_t file_size{}; std::uint64_t file_size{};
if (utils::file::is_file(source_path) && if (utils::file::file{source_path}.exists()) {
not utils::file::get_file_size(source_path, file_size)) { auto opt_size = utils::file::file{source_path}.size();
return api_error::comm_error; if (not opt_size.has_value()) {
return api_error::comm_error;
}
file_size = opt_size.value();
} }
const auto cfg = get_config().get_s3_config(); const auto cfg = get_config().get_s3_config();

View File

@ -80,7 +80,7 @@ auto sia_provider::get_directory_item_count(const std::string &api_path) const
std::uint64_t item_count{}; std::uint64_t item_count{};
if (object_list.contains("entries")) { if (object_list.contains("entries")) {
for (const auto &entry : object_list.at("entries")) { for (auto &&entry : object_list.at("entries")) {
try { try {
auto name = entry.at("name").get<std::string>(); auto name = entry.at("name").get<std::string>();
auto entry_api_path = utils::path::create_api_path(name); auto entry_api_path = utils::path::create_api_path(name);
@ -118,7 +118,7 @@ auto sia_provider::get_directory_items_impl(
} }
if (object_list.contains("entries")) { if (object_list.contains("entries")) {
for (const auto &entry : object_list.at("entries")) { for (auto &&entry : object_list.at("entries")) {
try { try {
auto name = entry.at("name").get<std::string>(); auto name = entry.at("name").get<std::string>();
auto entry_api_path = utils::path::create_api_path(name); auto entry_api_path = utils::path::create_api_path(name);
@ -208,7 +208,7 @@ auto sia_provider::get_file_list(api_file_list &list) const -> api_error {
} }
if (object_list.contains("entries")) { if (object_list.contains("entries")) {
for (const auto &entry : object_list.at("entries")) { for (auto &&entry : object_list.at("entries")) {
auto name = entry.at("name").get<std::string>(); auto name = entry.at("name").get<std::string>();
auto entry_api_path = utils::path::create_api_path(name); auto entry_api_path = utils::path::create_api_path(name);
@ -534,9 +534,10 @@ auto sia_provider::read_file_bytes(const std::string &api_path,
long /*response_code*/) { buffer = data; }; long /*response_code*/) { buffer = data; };
auto res = api_error::comm_error; auto res = api_error::comm_error;
for (std::uint32_t i = 0U; not stop_requested && res != api_error::success && for (std::uint32_t idx = 0U;
i < get_config().get_retry_read_count() + 1U; not stop_requested && res != api_error::success &&
i++) { idx < get_config().get_retry_read_count() + 1U;
++idx) {
long response_code{}; long response_code{};
const auto notify_retry = [&]() { const auto notify_retry = [&]() {
if (response_code == 0) { if (response_code == 0) {
@ -544,13 +545,13 @@ auto sia_provider::read_file_bytes(const std::string &api_path,
function_name, api_path, api_error::comm_error, function_name, api_path, api_error::comm_error,
"read file bytes failed|offset|" + std::to_string(offset) + "read file bytes failed|offset|" + std::to_string(offset) +
"|size|" + std::to_string(size) + "|retry|" + "|size|" + std::to_string(size) + "|retry|" +
std::to_string(i + 1U)); std::to_string(idx + 1U));
} else { } else {
utils::error::raise_api_path_error( utils::error::raise_api_path_error(
function_name, api_path, response_code, function_name, api_path, response_code,
"read file bytes failed|offset|" + std::to_string(offset) + "read file bytes failed|offset|" + std::to_string(offset) +
"|size|" + std::to_string(size) + "|retry|" + "|size|" + std::to_string(size) + "|retry|" +
std::to_string(i + 1U)); std::to_string(idx + 1U));
} }
std::this_thread::sleep_for(1s); std::this_thread::sleep_for(1s);
}; };

View File

@ -22,12 +22,11 @@
#include "rpc/server/full_server.hpp" #include "rpc/server/full_server.hpp"
#include "app_config.hpp" #include "app_config.hpp"
#include "drives/directory_iterator.hpp"
#include "file_manager/i_file_manager.hpp" #include "file_manager/i_file_manager.hpp"
#include "providers/i_provider.hpp" #include "providers/i_provider.hpp"
#include "types/repertory.hpp" #include "types/repertory.hpp"
#include "types/rpc.hpp" #include "types/rpc.hpp"
#include "utils/file_utils.hpp" #include "utils/file.hpp"
#include "utils/path.hpp" #include "utils/path.hpp"
namespace repertory { namespace repertory {
@ -51,11 +50,11 @@ void full_server::handle_get_directory_items(const httplib::Request &req,
void full_server::handle_get_drive_information(const httplib::Request & /*req*/, void full_server::handle_get_drive_information(const httplib::Request & /*req*/,
httplib::Response &res) { httplib::Response &res) {
auto dir_size =
utils::file::directory(get_config().get_cache_directory()).size();
res.set_content( res.set_content(
json({ json({
{"cache_space_used", {"cache_space_used", dir_size},
utils::file::calculate_used_space(
get_config().get_cache_directory(), false)},
{"drive_space_total", provider_.get_total_drive_space()}, {"drive_space_total", provider_.get_total_drive_space()},
{"drive_space_used", provider_.get_used_drive_space()}, {"drive_space_used", provider_.get_used_drive_space()},
{"item_count", provider_.get_total_item_count()}, {"item_count", provider_.get_total_item_count()},

View File

@ -1,21 +0,0 @@
#include "utils/action_queue.hpp"
#include "types/repertory.hpp"
namespace repertory::utils::action_queue {
action_queue::action_queue(const std::string &id,
std::uint8_t max_concurrent_actions)
: single_thread_service_base("action_queue_" + id),
id_(id),
max_concurrent_actions_(max_concurrent_actions) {}
void action_queue::service_function() {
//
}
void action_queue::push(std::function<void()> action) {
unique_mutex_lock queue_lock(queue_mtx_);
queue_.emplace_back(action);
queue_notify_.notify_all();
}
} // namespace repertory::utils::action_queue

View File

@ -23,7 +23,8 @@
#include "app_config.hpp" #include "app_config.hpp"
#include "utils/collection.hpp" #include "utils/collection.hpp"
#include "utils/file_utils.hpp" #include "utils/common.hpp"
#include "utils/file.hpp"
#include "utils/path.hpp" #include "utils/path.hpp"
#include "utils/string.hpp" #include "utils/string.hpp"
#include "utils/utils.hpp" #include "utils/utils.hpp"
@ -38,7 +39,7 @@ void get_api_authentication_data(std::string &user, std::string &password,
{"config.json"}); {"config.json"});
json data; json data;
const auto success = utils::retryable_action([&]() -> bool { const auto success = utils::retry_action([&]() -> bool {
return utils::file::read_json_file(cfg_file_path, data); return utils::file::read_json_file(cfg_file_path, data);
}); });

View File

@ -1,117 +0,0 @@
/*
Copyright <2018-2024> <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/encrypt.hpp"
#include "events/event_system.hpp"
#include "events/events.hpp"
#include "types/repertory.hpp"
#include "utils/collection.hpp"
#include "utils/encrypting_reader.hpp"
#include "utils/encryption.hpp"
#include "utils/utils.hpp"
namespace repertory::utils::encryption {
auto decrypt_file_path(std::string_view encryption_token,
std::string &file_path) -> api_error {
std::string decrypted_file_path{};
for (const auto &part : std::filesystem::path(file_path)) {
auto file_name = part.string();
if (file_name == "/") {
continue;
}
auto res = decrypt_file_name(encryption_token, file_name);
if (res != api_error::success) {
return res;
}
decrypted_file_path += '/' + file_name;
}
file_path = decrypted_file_path;
return api_error::success;
}
auto decrypt_file_name(std::string_view encryption_token,
std::string &file_name) -> api_error {
data_buffer buffer;
if (not utils::collection::from_hex_string(file_name, buffer)) {
return api_error::error;
}
file_name.clear();
if (not utils::encryption::decrypt_data(encryption_token, buffer,
file_name)) {
return api_error::decryption_error;
}
return api_error::success;
}
auto read_encrypted_range(const http_range &range,
const utils::encryption::hash_256_t &key,
reader_func reader, std::uint64_t total_size,
data_buffer &data) -> api_error {
const auto encrypted_chunk_size =
utils::encryption::encrypting_reader::get_encrypted_chunk_size();
const auto data_chunk_size =
utils::encryption::encrypting_reader::get_data_chunk_size();
const auto start_chunk =
static_cast<std::size_t>(range.begin / data_chunk_size);
const 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);
for (std::size_t chunk = start_chunk; chunk <= end_chunk; chunk++) {
data_buffer cypher;
const auto start_offset = chunk * encrypted_chunk_size;
const 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));
const auto result = reader(cypher, start_offset, end_offset);
if (result != api_error::success) {
return result;
}
data_buffer source_buffer;
if (not utils::encryption::decrypt_data(key, cypher, source_buffer)) {
return api_error::decryption_error;
}
cypher.clear();
const 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::back_inserter(data));
remain -= data_size;
source_offset = 0U;
}
return api_error::success;
}
} // namespace repertory::utils::encryption

View File

@ -21,392 +21,77 @@
*/ */
#include "utils/file_utils.hpp" #include "utils/file_utils.hpp"
#include "types/repertory.hpp"
#include "utils/collection.hpp"
#include "utils/error_utils.hpp" #include "utils/error_utils.hpp"
#include "utils/file.hpp"
#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/utils.hpp"
namespace repertory::utils::file { namespace repertory::utils::file {
auto calculate_used_space(std::string path, bool recursive) -> std::uint64_t { auto get_directory_files(std::string_view path, bool oldest_first,
path = utils::path::absolute(path);
std::uint64_t ret{};
#if defined(_WIN32)
WIN32_FIND_DATA fd{};
const auto search = utils::path::combine(path, {"*.*"});
auto find = ::FindFirstFile(search.c_str(), &fd);
if (find != INVALID_HANDLE_VALUE) {
do {
const auto file_name = std::string(fd.cFileName);
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
if (recursive && (file_name != ".") && (file_name != "..")) {
ret += calculate_used_space(utils::path::combine(path, {file_name}),
recursive);
}
} else {
std::uint64_t file_size{};
if (get_file_size(utils::path::combine(path, {file_name}), file_size)) {
ret += file_size;
}
}
} while (::FindNextFile(find, &fd) != 0);
::FindClose(find);
}
#else
auto *root = opendir(path.c_str());
if (root) {
struct dirent *de{};
while ((de = readdir(root)) != nullptr) {
if (de->d_type == DT_DIR) {
if (recursive && (strcmp(de->d_name, ".") != 0) &&
(strcmp(de->d_name, "..") != 0)) {
ret += calculate_used_space(utils::path::combine(path, {de->d_name}),
recursive);
}
} else {
std::uint64_t file_size{};
if (get_file_size(utils::path::combine(path, {de->d_name}),
file_size)) {
ret += file_size;
}
}
}
closedir(root);
}
#endif
return ret;
}
void change_to_process_directory() {
#if defined(_WIN32)
std::string file_name;
file_name.resize(MAX_PATH);
::GetModuleFileNameA(nullptr, &file_name[0U],
static_cast<DWORD>(file_name.size()));
std::string path = file_name.c_str();
::PathRemoveFileSpecA(&path[0U]);
::SetCurrentDirectoryA(&path[0U]);
#else
std::string path;
path.resize(PATH_MAX + 1);
#if defined(__APPLE__)
proc_pidpath(getpid(), &path[0U], path.size());
#else
readlink("/proc/self/exe", &path[0U], path.size());
#endif
path = utils::path::get_parent_directory(path);
chdir(path.c_str());
#endif
}
auto copy_file(std::string from_path, std::string to_path) -> bool {
from_path = utils::path::absolute(from_path);
to_path = utils::path::absolute(to_path);
if (is_file(from_path) && not is_directory(to_path)) {
return std::filesystem::copy_file(from_path, to_path);
}
return false;
}
auto copy_directory_recursively(std::string from_path,
std::string to_path) -> bool {
from_path = utils::path::absolute(from_path);
to_path = utils::path::absolute(to_path);
auto ret = create_full_directory_path(to_path);
if (ret) {
#if defined(_WIN32)
WIN32_FIND_DATA fd{};
const auto search = utils::path::combine(from_path, {"*.*"});
auto find = ::FindFirstFile(search.c_str(), &fd);
if (find != INVALID_HANDLE_VALUE) {
ret = true;
do {
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
if ((std::string(fd.cFileName) != ".") &&
(std::string(fd.cFileName) != "..")) {
ret = copy_directory_recursively(
utils::path::combine(from_path, {fd.cFileName}),
utils::path::combine(to_path, {fd.cFileName}));
}
} else {
ret = copy_file(utils::path::combine(from_path, {fd.cFileName}),
utils::path::combine(to_path, {fd.cFileName}));
}
} while (ret && (::FindNextFile(find, &fd) != 0));
::FindClose(find);
}
#else
auto *root = opendir(from_path.c_str());
if (root) {
struct dirent *de{};
while (ret && (de = readdir(root))) {
if (de->d_type == DT_DIR) {
if ((strcmp(de->d_name, ".") != 0) &&
(strcmp(de->d_name, "..") != 0)) {
ret = copy_directory_recursively(
utils::path::combine(from_path, {de->d_name}),
utils::path::combine(to_path, {de->d_name}));
}
} else {
ret = copy_file(utils::path::combine(from_path, {de->d_name}),
utils::path::combine(to_path, {de->d_name}));
}
}
closedir(root);
}
#endif
}
return ret;
}
auto create_full_directory_path(std::string path) -> bool {
#if defined(_WIN32)
const auto unicode_path =
utils::string::from_utf8(utils::path::absolute(path));
return is_directory(path) ||
(::SHCreateDirectory(nullptr, unicode_path.c_str()) == ERROR_SUCCESS);
#else
auto ret = true;
const auto paths = utils::string::split(
utils::path::absolute(path), utils::path::directory_seperator[0U], false);
std::string current_path;
for (std::size_t i = 0U; ret && (i < paths.size()); i++) {
if (paths[i].empty()) { // Skip root
current_path = utils::path::directory_seperator;
} else {
current_path = utils::path::combine(current_path, {paths[i]});
const auto status = mkdir(current_path.c_str(), S_IRWXU);
ret = ((status == 0) || (errno == EEXIST));
}
}
return ret;
#endif
}
auto delete_directory(std::string path, bool recursive) -> bool {
if (recursive) {
return delete_directory_recursively(path);
}
path = utils::path::absolute(path);
#if defined(_WIN32)
return (not is_directory(path) || utils::retryable_action([&]() -> bool {
return !!::RemoveDirectoryA(path.c_str());
}));
#else
return not is_directory(path) || (rmdir(path.c_str()) == 0);
#endif
}
auto delete_directory_recursively(std::string path) -> bool {
path = utils::path::absolute(path);
#if defined(_WIN32)
WIN32_FIND_DATA fd{};
const auto search = utils::path::combine(path, {"*.*"});
auto find = ::FindFirstFile(search.c_str(), &fd);
if (find != INVALID_HANDLE_VALUE) {
auto res = true;
do {
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
if ((std::string(fd.cFileName) != ".") &&
(std::string(fd.cFileName) != "..")) {
res = delete_directory_recursively(
utils::path::combine(path, {fd.cFileName}));
}
} else {
res = retry_delete_file(utils::path::combine(path, {fd.cFileName}));
}
} while (res && (::FindNextFile(find, &fd) != 0));
::FindClose(find);
}
#else
auto *root = opendir(path.c_str());
if (root) {
auto res = true;
struct dirent *de{};
while (res && (de = readdir(root))) {
if (de->d_type == DT_DIR) {
if ((strcmp(de->d_name, ".") != 0) && (strcmp(de->d_name, "..") != 0)) {
res = delete_directory_recursively(
utils::path::combine(path, {de->d_name}));
}
} else {
res = retry_delete_file(utils::path::combine(path, {de->d_name}));
}
}
closedir(root);
}
#endif
return delete_directory(path, false);
}
auto delete_file(std::string path) -> bool {
path = utils::path::absolute(path);
#if defined(_WIN32)
return (not is_file(path) || utils::retryable_action([&]() -> bool {
const auto ret = !!::DeleteFileA(path.c_str());
if (not ret) {
std::cout << "delete failed:" << path << std::endl;
}
return ret;
}));
#else
return (not is_file(path) || (unlink(path.c_str()) == 0));
#endif
}
auto generate_sha256(const std::string &file_path) -> std::string {
crypto_hash_sha256_state state{};
auto res = crypto_hash_sha256_init(&state);
if (res != 0) {
throw std::runtime_error("failed to initialize sha256|" +
std::to_string(res));
}
native_file_ptr nf;
if (native_file::open(file_path, nf) != api_error::success) {
throw std::runtime_error("failed to open file|" + file_path);
}
{
data_buffer buffer(1048576u);
std::uint64_t read_offset = 0U;
std::size_t bytes_read = 0U;
while (
nf->read_bytes(buffer.data(), buffer.size(), read_offset, bytes_read)) {
if (not bytes_read) {
break;
}
read_offset += bytes_read;
res = crypto_hash_sha256_update(
&state, reinterpret_cast<const unsigned char *>(buffer.data()),
bytes_read);
if (res != 0) {
nf->close();
throw std::runtime_error("failed to update sha256|" +
std::to_string(res));
}
}
nf->close();
}
std::array<unsigned char, crypto_hash_sha256_BYTES> out{};
res = crypto_hash_sha256_final(&state, out.data());
if (res != 0) {
throw std::runtime_error("failed to finalize sha256|" +
std::to_string(res));
}
return utils::collection::to_hex_string(out);
}
auto get_free_drive_space(const std::string &path) -> std::uint64_t {
#if defined(_WIN32)
ULARGE_INTEGER li{};
::GetDiskFreeSpaceEx(path.c_str(), &li, nullptr, nullptr);
return li.QuadPart;
#endif
#if defined(__linux__)
std::uint64_t ret = 0;
struct statfs64 st {};
if (statfs64(path.c_str(), &st) == 0) {
ret = st.f_bfree * st.f_bsize;
}
return ret;
#endif
#if defined(__APPLE__)
struct statvfs st {};
statvfs(path.c_str(), &st);
return st.f_bfree * st.f_frsize;
#endif
}
auto get_total_drive_space(const std::string &path) -> std::uint64_t {
#if defined(_WIN32)
ULARGE_INTEGER li{};
::GetDiskFreeSpaceEx(path.c_str(), nullptr, &li, nullptr);
return li.QuadPart;
#endif
#if defined(__linux__)
std::uint64_t ret = 0;
struct statfs64 st {};
if (statfs64(path.c_str(), &st) == 0) {
ret = st.f_blocks * st.f_bsize;
}
return ret;
#endif
#if defined(__APPLE__)
struct statvfs st {};
statvfs(path.c_str(), &st);
return st.f_blocks * st.f_frsize;
#endif
}
auto get_directory_files(std::string path, bool oldest_first,
bool recursive) -> std::deque<std::string> { bool recursive) -> std::deque<std::string> {
path = utils::path::absolute(path); static constexpr const std::string_view function_name{
static_cast<const char *>(__FUNCTION__),
};
auto abs_path = utils::path::absolute(path);
std::deque<std::string> ret; std::deque<std::string> ret;
std::unordered_map<std::string, std::uint64_t> lookup; std::unordered_map<std::string, std::uint64_t> lookup;
#if defined(_WIN32) #if defined(_WIN32)
WIN32_FIND_DATA fd{}; WIN32_FIND_DATA fd{};
const auto search = utils::path::combine(path, {"*.*"}); auto search = utils::path::combine(abs_path, {"*.*"});
auto find = ::FindFirstFile(search.c_str(), &fd); auto find = ::FindFirstFile(search.c_str(), &fd);
if (find != INVALID_HANDLE_VALUE) { if (find != INVALID_HANDLE_VALUE) {
do { try {
const auto full_path = utils::path::combine(path, {fd.cFileName}); do {
if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == auto full_path = utils::path::combine(abs_path, {fd.cFileName});
FILE_ATTRIBUTE_DIRECTORY) { if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ==
if (recursive) { FILE_ATTRIBUTE_DIRECTORY) {
const auto sub_files = if (recursive) {
get_directory_files(full_path, oldest_first, recursive); auto sub_files =
ret.insert(ret.end(), sub_files.begin(), sub_files.end()); get_directory_files(full_path, oldest_first, recursive);
} else { ret.insert(ret.end(), sub_files.begin(), sub_files.end());
ULARGE_INTEGER li{}; } else {
li.HighPart = fd.ftLastWriteTime.dwHighDateTime; ULARGE_INTEGER li{};
li.LowPart = fd.ftLastWriteTime.dwLowDateTime; li.HighPart = fd.ftLastWriteTime.dwHighDateTime;
lookup[full_path] = li.QuadPart; li.LowPart = fd.ftLastWriteTime.dwLowDateTime;
ret.emplace_back(full_path); lookup[full_path] = li.QuadPart;
ret.emplace_back(full_path);
}
} }
} } while (::FindNextFile(find, &fd) != 0);
} while (::FindNextFile(find, &fd) != 0); } catch (const std::exception &e) {
utils::error::raise_error(function_name, e,
"failed to get directory files");
}
::FindClose(find); ::FindClose(find);
std::sort(ret.begin(), ret.end(), std::sort(ret.begin(), ret.end(), [&](auto &&path1, auto &&path2) -> bool {
[&](const auto &p1, const auto &p2) -> bool { return (oldest_first != 0) == (lookup[path1] < lookup[path2]);
return (oldest_first != 0) == (lookup[p1] < lookup[p2]); });
});
} }
#else #else // !defined(_WIN32)
auto *root = opendir(path.c_str()); auto *root = opendir(abs_path.c_str());
if (root) { if (root) {
struct dirent *de{}; try {
while ((de = readdir(root)) != nullptr) { struct dirent *de{};
if (de->d_type == DT_DIR) { while ((de = readdir(root)) != nullptr) {
if (recursive) { if (de->d_type == DT_DIR) {
const auto sub_files = if (recursive) {
get_directory_files(utils::path::combine(path, {de->d_name}), auto sub_files = get_directory_files(
oldest_first, recursive); utils::path::combine(abs_path, {de->d_name}), oldest_first,
ret.insert(ret.end(), sub_files.begin(), sub_files.end()); recursive);
ret.insert(ret.end(), sub_files.begin(), sub_files.end());
}
} else {
ret.emplace_back(utils::path::combine(abs_path, {de->d_name}));
} }
} else {
ret.emplace_back(utils::path::combine(path, {de->d_name}));
} }
} catch (const std::exception &e) {
utils::error::raise_error(function_name, e,
"failed to get directory files");
} }
closedir(root); closedir(root);
const auto add_to_lookup = [&](const std::string &lookup_path) { const auto add_to_lookup = [&](const std::string &lookup_path) {
@ -414,118 +99,32 @@ auto get_directory_files(std::string path, bool oldest_first,
struct stat st {}; struct stat st {};
stat(lookup_path.c_str(), &st); stat(lookup_path.c_str(), &st);
#if defined(__APPLE__) #if defined(__APPLE__)
lookup[lookup_path] = static_cast<std::uint64_t>( lookup[lookup_path] =
(st.st_mtimespec.tv_sec * NANOS_PER_SECOND) + (static_cast<std::uint64_t>(st.st_mtimespec.tv_sec) *
st.st_mtimespec.tv_nsec); utils::time::NANOS_PER_SECOND) +
#else static_cast<std::uint64_t>(st.st_mtimespec.tv_nsec);
lookup[lookup_path] = static_cast<std::uint64_t>( #else // !defined(__APPLE__)
(st.st_mtim.tv_sec * NANOS_PER_SECOND) + st.st_mtim.tv_nsec); lookup[lookup_path] = (static_cast<std::uint64_t>(st.st_mtim.tv_sec) *
#endif utils::time::NANOS_PER_SECOND) +
static_cast<std::uint64_t>(st.st_mtim.tv_nsec);
#endif // defined(__APPLE__)
} }
}; };
std::sort(ret.begin(), ret.end(), std::sort(ret.begin(), ret.end(), [&](auto &&path1, auto &&path2) -> bool {
[&](const auto &p1, const auto &p2) -> bool { add_to_lookup(path1);
add_to_lookup(p1); add_to_lookup(path2);
add_to_lookup(p2); return (oldest_first != 0) == (lookup.at(path1) < lookup.at(path2));
return (oldest_first != 0) == (lookup[p1] < lookup[p2]); });
});
} }
#endif #endif // defined(_WIN32)
return ret;
}
auto get_accessed_time(const std::string &path,
std::uint64_t &accessed) -> bool {
auto ret = false;
accessed = 0;
#if defined(_WIN32)
struct _stat64 st {};
if (_stat64(path.c_str(), &st) != -1) {
accessed = static_cast<uint64_t>(st.st_atime);
#else
struct stat st {};
if (stat(path.c_str(), &st) != -1) {
#if defined(__APPLE__)
accessed = static_cast<uint64_t>(
st.st_atimespec.tv_nsec + (st.st_atimespec.tv_sec * NANOS_PER_SECOND));
#else
accessed = static_cast<uint64_t>(st.st_atim.tv_nsec +
(st.st_atim.tv_sec * NANOS_PER_SECOND));
#endif
#endif
ret = true;
}
return ret;
}
auto get_modified_time(const std::string &path,
std::uint64_t &modified) -> bool {
auto ret = false;
modified = 0U;
#if defined(_WIN32)
struct _stat64 st {};
if (_stat64(path.c_str(), &st) != -1) {
modified = static_cast<uint64_t>(st.st_mtime);
#else
struct stat st {};
if (stat(path.c_str(), &st) != -1) {
#if defined(__APPLE__)
modified = static_cast<uint64_t>(
st.st_mtimespec.tv_nsec + (st.st_mtimespec.tv_sec * NANOS_PER_SECOND));
#else
modified = static_cast<uint64_t>(st.st_mtim.tv_nsec +
(st.st_mtim.tv_sec * NANOS_PER_SECOND));
#endif
#endif
ret = true;
}
return ret;
}
auto is_modified_date_older_than(const std::string &path,
const std::chrono::hours &hours) -> bool {
auto ret = false;
std::uint64_t modified{};
if (get_modified_time(path, modified)) {
const auto seconds =
std::chrono::duration_cast<std::chrono::seconds>(hours);
#if defined(_WIN32)
return (std::chrono::system_clock::from_time_t(
static_cast<time_t>(modified)) +
seconds) < std::chrono::system_clock::now();
#else
return (modified +
static_cast<std::uint64_t>(seconds.count() * NANOS_PER_SECOND)) <
utils::time::get_time_now();
#endif
}
return ret;
}
auto move_file(std::string from, std::string to) -> bool {
from = utils::path::absolute(from);
to = utils::path::absolute(to);
const auto directory = utils::path::remove_file_name(to);
if (not create_full_directory_path(directory)) {
return false;
}
#if defined(_WIN32)
const bool ret = ::MoveFile(from.c_str(), to.c_str()) != 0;
#else
const bool ret = (rename(from.c_str(), to.c_str()) == 0);
#endif
return ret; return ret;
} }
auto read_file_lines(const std::string &path) -> std::vector<std::string> { auto read_file_lines(const std::string &path) -> std::vector<std::string> {
std::vector<std::string> ret; std::vector<std::string> ret;
if (is_file(path)) { if (utils::file::file(path).exists()) {
std::ifstream fs(path); std::ifstream fs(path);
std::string current_line; std::string current_line;
while (not fs.eof() && std::getline(fs, current_line)) { while (not fs.eof() && std::getline(fs, current_line)) {
@ -538,7 +137,7 @@ auto read_file_lines(const std::string &path) -> std::vector<std::string> {
} }
auto reset_modified_time(const std::string &path) -> bool { auto reset_modified_time(const std::string &path) -> bool {
auto ret = false; auto ret{false};
#if defined(_WIN32) #if defined(_WIN32)
SYSTEMTIME st{}; SYSTEMTIME st{};
::GetSystemTime(&st); ::GetSystemTime(&st);
@ -554,33 +153,14 @@ auto reset_modified_time(const std::string &path) -> bool {
::CloseHandle(handle); ::CloseHandle(handle);
} }
} }
#else #else // !defined(_WIN32)
auto fd = open(path.c_str(), O_RDWR); auto fd = open(path.c_str(), O_RDWR);
if ((ret = (fd != -1))) { if ((ret = (fd != -1))) {
ret = not futimens(fd, nullptr); ret = futimens(fd, nullptr) == 0;
close(fd); close(fd);
} }
#endif #endif // defined(_WIN32)
return ret; return ret;
} }
auto retry_delete_directory(const std::string &dir) -> bool {
auto deleted = false;
for (std::uint8_t i = 0U; not(deleted = delete_directory(dir)) && (i < 200U);
i++) {
std::this_thread::sleep_for(10ms);
}
return deleted;
}
auto retry_delete_file(const std::string &file) -> bool {
auto deleted = false;
for (std::uint8_t i = 0U; not(deleted = delete_file(file)) && (i < 200U);
i++) {
std::this_thread::sleep_for(10ms);
}
return deleted;
}
} // namespace repertory::utils::file } // namespace repertory::utils::file

View File

@ -1,319 +0,0 @@
/*
Copyright <2018-2024> <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/native_file.hpp"
#include "platform/platform.hpp"
#include "types/repertory.hpp"
#include "utils/string.hpp"
#include "utils/utils.hpp"
namespace repertory {
auto native_file::get_handle() -> native_handle { return handle_; }
native_file::~native_file() {
if (auto_close) {
close();
}
}
auto native_file::clone(const native_file_ptr &ptr) -> native_file_ptr {
std::string source_path;
#if defined(_WIN32)
source_path.resize(MAX_PATH + 1);
::GetFinalPathNameByHandleA(ptr->get_handle(), source_path.data(),
MAX_PATH + 1,
FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
#else
source_path.resize(PATH_MAX + 1);
#if defined(__APPLE__)
fcntl(ptr->get_handle(), F_GETPATH, source_path.data());
#else
readlink(("/proc/self/fd/" + std::to_string(ptr->get_handle())).c_str(),
source_path.data(), source_path.size());
#endif
#endif
source_path = source_path.c_str();
native_file_ptr clone;
auto res = native_file::open(source_path, clone);
if (res != api_error::success) {
throw std::runtime_error("unable to open file|sp|" + source_path + "|err|" +
api_error_to_string(res));
}
return clone;
}
auto native_file::create_or_open(std::string_view source_path, bool read_only,
native_file_ptr &ptr) -> api_error {
#if defined(_WIN32)
auto handle =
read_only ? ::CreateFileA(std::string{source_path}.c_str(), GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr,
OPEN_ALWAYS, FILE_FLAG_RANDOM_ACCESS, nullptr)
: ::CreateFileA(std::string{source_path}.c_str(),
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr,
OPEN_ALWAYS, FILE_FLAG_RANDOM_ACCESS, nullptr);
#else
auto handle = read_only ? ::open(std::string{source_path}.c_str(),
O_CREAT | O_RDONLY | O_CLOEXEC, 0600U)
: ::open(std::string{source_path}.c_str(),
O_CREAT | O_RDWR | O_CLOEXEC, 0600U);
if (not read_only) {
chmod(std::string{source_path}.c_str(), 0600U);
}
#endif
ptr = native_file::attach(handle);
return ((handle == REPERTORY_INVALID_HANDLE) ? api_error::os_error
: api_error::success);
}
auto native_file::create_or_open(std::string_view source_path,
native_file_ptr &ptr) -> api_error {
return create_or_open(source_path, false, ptr);
}
auto native_file::open(std::string_view source_path,
native_file_ptr &ptr) -> api_error {
return open(source_path, false, ptr);
}
auto native_file::open(std::string_view source_path, bool read_only,
native_file_ptr &ptr) -> api_error {
#if defined(_WIN32)
auto handle =
read_only
? ::CreateFileA(std::string{source_path}.c_str(), GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr,
OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, nullptr)
: ::CreateFileA(std::string{source_path}.c_str(),
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr,
OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, nullptr);
#else
auto handle =
read_only ? ::open(std::string{source_path}.c_str(), O_RDONLY | O_CLOEXEC)
: ::open(std::string{source_path}.c_str(), O_RDWR | O_CLOEXEC);
if (not read_only) {
chmod(std::string{source_path}.c_str(), 0600U);
}
#endif
ptr = native_file::attach(handle);
return ((handle == REPERTORY_INVALID_HANDLE) ? api_error::os_error
: api_error::success);
}
auto native_file::allocate(std::uint64_t file_size) -> bool {
#if defined(_WIN32)
LARGE_INTEGER li{};
li.QuadPart = static_cast<LONGLONG>(file_size);
return (::SetFilePointerEx(handle_, li, nullptr, FILE_BEGIN) &&
::SetEndOfFile(handle_));
#endif
#if defined(__linux__)
return (fallocate(handle_, 0, 0, static_cast<off_t>(file_size)) >= 0);
#endif
#if defined(__APPLE__)
return (ftruncate(handle_, file_size) >= 0);
#endif
}
void native_file::close() {
if (handle_ != REPERTORY_INVALID_HANDLE) {
#if defined(_WIN32)
::CloseHandle(handle_);
#else
::close(handle_);
#endif
handle_ = REPERTORY_INVALID_HANDLE;
}
}
auto native_file::copy_from(const native_file_ptr &ptr) -> bool {
std::uint64_t file_size{};
auto ret = ptr->get_file_size(file_size);
if (ret) {
data_buffer buffer;
buffer.resize(65536ULL * 2ULL);
std::uint64_t offset{};
while (ret && (file_size > 0U)) {
std::size_t bytes_read{};
ret = ptr->read_bytes(buffer.data(), buffer.size(), offset, bytes_read);
if (ret) {
std::size_t bytes_written{};
ret = write_bytes(buffer.data(), bytes_read, offset, bytes_written);
file_size -= bytes_read;
offset += bytes_read;
}
}
flush();
}
return ret;
}
auto native_file::copy_from(const std::string &path) -> bool {
auto ret = false;
native_file_ptr ptr;
if (native_file::create_or_open(path, ptr) == api_error ::success) {
ret = copy_from(ptr);
ptr->close();
}
return ret;
}
void native_file::flush() {
#if defined(_WIN32)
recur_mutex_lock l(read_write_mutex_);
::FlushFileBuffers(handle_);
#else
fsync(handle_);
#endif
}
auto native_file::get_file_size(std::uint64_t &file_size) -> bool {
auto ret = false;
#if defined(_WIN32)
LARGE_INTEGER li{};
if ((ret = ::GetFileSizeEx(handle_, &li) && (li.QuadPart >= 0))) {
file_size = static_cast<std::uint64_t>(li.QuadPart);
}
#else
#if defined(__APPLE__)
struct stat unix_st {};
if (fstat(handle_, &unix_st) >= 0) {
#else
struct stat64 unix_st {};
if (fstat64(handle_, &unix_st) >= 0) {
#endif
ret = (unix_st.st_size >= 0);
if (ret) {
file_size = static_cast<uint64_t>(unix_st.st_size);
}
}
#endif
return ret;
}
#if defined(_WIN32)
auto native_file::read_bytes(unsigned char *buffer, std::size_t read_size,
std::uint64_t read_offset,
std::size_t &bytes_read) -> bool {
recur_mutex_lock l(read_write_mutex_);
auto ret = false;
bytes_read = 0u;
LARGE_INTEGER li{};
li.QuadPart = static_cast<LONGLONG>(read_offset);
if ((ret = !!::SetFilePointerEx(handle_, li, nullptr, FILE_BEGIN))) {
DWORD current_read = 0u;
do {
current_read = 0u;
ret = !!::ReadFile(handle_, &buffer[bytes_read],
static_cast<DWORD>(read_size - bytes_read),
&current_read, nullptr);
bytes_read += current_read;
} while (ret && (bytes_read < read_size) && (current_read != 0));
}
if (ret && (read_size != bytes_read)) {
::SetLastError(ERROR_HANDLE_EOF);
}
return ret;
}
#else
auto native_file::read_bytes(unsigned char *buffer, std::size_t read_size,
std::uint64_t read_offset,
std::size_t &bytes_read) -> bool {
bytes_read = 0U;
ssize_t result = 0;
do {
result = pread64(handle_, &buffer[bytes_read], read_size - bytes_read,
static_cast<off_t>(read_offset + bytes_read));
if (result > 0) {
bytes_read += static_cast<size_t>(result);
}
} while ((result > 0) && (bytes_read < read_size));
return (result >= 0);
}
#endif
auto native_file::truncate(std::uint64_t file_size) -> bool {
#if defined(_WIN32)
recur_mutex_lock l(read_write_mutex_);
LARGE_INTEGER li{};
li.QuadPart = static_cast<LONGLONG>(file_size);
return (::SetFilePointerEx(handle_, li, nullptr, FILE_BEGIN) &&
::SetEndOfFile(handle_));
#else
return (ftruncate(handle_, static_cast<off_t>(file_size)) >= 0);
#endif
}
#if defined(_WIN32)
auto native_file::write_bytes(const unsigned char *buffer,
std::size_t write_size,
std::uint64_t write_offset,
std::size_t &bytes_written) -> bool {
recur_mutex_lock l(read_write_mutex_);
bytes_written = 0u;
auto ret = true;
LARGE_INTEGER li{};
li.QuadPart = static_cast<LONGLONG>(write_offset);
if ((ret = !!::SetFilePointerEx(handle_, li, nullptr, FILE_BEGIN))) {
do {
DWORD current_write = 0u;
ret = !!::WriteFile(handle_, &buffer[bytes_written],
static_cast<DWORD>(write_size - bytes_written),
&current_write, nullptr);
bytes_written += current_write;
} while (ret && (bytes_written < write_size));
}
return ret;
}
#else
auto native_file::write_bytes(const unsigned char *buffer,
std::size_t write_size,
std::uint64_t write_offset,
std::size_t &bytes_written) -> bool {
bytes_written = 0U;
ssize_t result{};
do {
result =
pwrite64(handle_, &buffer[bytes_written], write_size - bytes_written,
static_cast<off_t>(write_offset + bytes_written));
if (result > 0) {
bytes_written += static_cast<size_t>(result);
}
} while ((result >= 0) && (bytes_written < write_size));
return (bytes_written == write_size);
}
#endif
} // namespace repertory

View File

@ -201,10 +201,6 @@ auto unix_error_to_windows(int err) -> std::uint32_t {
} }
} }
auto unix_time_to_windows_time(const remote::file_time &file_time) -> UINT64 {
return (file_time / 100ULL) + 116444736000000000ULL;
}
void windows_create_to_unix(const UINT32 &create_options, void windows_create_to_unix(const UINT32 &create_options,
const UINT32 &granted_access, std::uint32_t &flags, const UINT32 &granted_access, std::uint32_t &flags,
remote::file_mode &mode) { remote::file_mode &mode) {
@ -221,10 +217,6 @@ void windows_create_to_unix(const UINT32 &create_options,
mode |= (S_IXUSR); mode |= (S_IXUSR);
} }
} }
auto windows_time_to_unix_time(std::uint64_t win_time) -> remote::file_time {
return (win_time - 116444736000000000ULL) * 100ULL;
}
} // namespace repertory::utils } // namespace repertory::utils
#endif // !_WIN32 #endif // !_WIN32

View File

@ -22,16 +22,8 @@
#include "utils/utils.hpp" #include "utils/utils.hpp"
#include "app_config.hpp" #include "app_config.hpp"
#include "events/event_system.hpp"
#include "events/events.hpp"
#include "providers/i_provider.hpp"
#include "types/startup_exception.hpp"
#include "utils/com_init_wrapper.hpp"
#include "utils/common.hpp" #include "utils/common.hpp"
#include "utils/native_file.hpp"
#include "utils/path.hpp"
#include "utils/string.hpp" #include "utils/string.hpp"
#include "utils/time.hpp"
namespace repertory::utils { namespace repertory::utils {
void calculate_allocation_size(bool directory, std::uint64_t file_size, void calculate_allocation_size(bool directory, std::uint64_t file_size,
@ -53,32 +45,6 @@ void calculate_allocation_size(bool directory, std::uint64_t file_size,
allocation_meta_size = std::to_string(allocation_size); allocation_meta_size = std::to_string(allocation_size);
} }
auto convert_api_date(const std::string &date) -> std::uint64_t {
// 2009-10-12T17:50:30.000Z
const auto date_parts = utils::string::split(date, '.', true);
const auto date_time = date_parts[0U];
const auto nanos = utils::string::to_uint64(
utils::string::split(date_parts[1U], 'Z', true)[0U]);
struct tm tm1 {};
#if defined(_WIN32)
utils::time::strptime(date_time.c_str(), "%Y-%m-%dT%T", &tm1);
#else
strptime(date_time.c_str(), "%Y-%m-%dT%T", &tm1);
#endif
return nanos + (static_cast<std::uint64_t>(mktime(&tm1)) * NANOS_PER_SECOND);
}
auto create_curl() -> CURL * {
static std::recursive_mutex mtx;
unique_recur_mutex_lock lock(mtx);
curl_global_init(CURL_GLOBAL_DEFAULT);
lock.unlock();
return reset_curl(curl_easy_init());
}
auto create_volume_label(const provider_type &prov) -> std::string { auto create_volume_label(const provider_type &prov) -> std::string {
return "repertory_" + app_config::get_provider_name(prov); return "repertory_" + app_config::get_provider_name(prov);
} }
@ -86,54 +52,4 @@ auto create_volume_label(const provider_type &prov) -> std::string {
auto get_attributes_from_meta(const api_meta_map &meta) -> DWORD { auto get_attributes_from_meta(const api_meta_map &meta) -> DWORD {
return static_cast<DWORD>(utils::string::to_uint32(meta.at(META_ATTRIBUTES))); return static_cast<DWORD>(utils::string::to_uint32(meta.at(META_ATTRIBUTES)));
} }
auto reset_curl(CURL *curl_handle) -> CURL * {
curl_easy_reset(curl_handle);
#if defined(__APPLE__)
curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1);
#endif
return curl_handle;
}
auto retryable_action(const std::function<bool()> &action) -> bool {
static constexpr const auto retry_count = 20U;
auto succeeded = false;
for (std::uint8_t i = 0U; not(succeeded = action()) && (i < retry_count);
i++) {
std::this_thread::sleep_for(100ms);
}
return succeeded;
}
void spin_wait_for_mutex(std::function<bool()> complete,
std::condition_variable &cond, std::mutex &mtx,
const std::string &text) {
while (not complete()) {
unique_mutex_lock lock(mtx);
if (not complete()) {
if (not text.empty()) {
/* event_system::instance().raise<DebugLog>(__FUNCTION__,
* "spin_wait_for_mutex", text); */
}
cond.wait_for(lock, 1s);
}
lock.unlock();
}
}
void spin_wait_for_mutex(bool &complete, std::condition_variable &cond,
std::mutex &mtx, const std::string &text) {
while (not complete) {
unique_mutex_lock lock(mtx);
if (not complete) {
if (not text.empty()) {
/* event_system::instance().raise<DebugLog>(__FUNCTION__,
* "spin_wait_for_mutex", text); */
}
cond.wait_for(lock, 1s);
}
lock.unlock();
}
}
} // namespace repertory::utils } // namespace repertory::utils

View File

@ -23,9 +23,8 @@
#include "utils/windows/windows_utils.hpp" #include "utils/windows/windows_utils.hpp"
#include "types/startup_exception.hpp"
#include "utils/com_init_wrapper.hpp"
#include "utils/string.hpp" #include "utils/string.hpp"
#include "utils/time.hpp"
#if !defined(STATUS_DEVICE_INSUFFICIENT_RESOURCES) #if !defined(STATUS_DEVICE_INSUFFICIENT_RESOURCES)
#define STATUS_DEVICE_INSUFFICIENT_RESOURCES static_cast<NTSTATUS>(0xC0000468L) #define STATUS_DEVICE_INSUFFICIENT_RESOURCES static_cast<NTSTATUS>(0xC0000468L)
@ -88,19 +87,23 @@ auto from_api_error(const api_error &e) -> NTSTATUS {
} }
auto get_accessed_time_from_meta(const api_meta_map &meta) -> std::uint64_t { auto get_accessed_time_from_meta(const api_meta_map &meta) -> std::uint64_t {
return utils::string::to_uint64(meta.at(META_ACCESSED)); return utils::time::unix_time_to_windows_time(
utils::string::to_uint64(meta.at(META_ACCESSED)));
} }
auto get_changed_time_from_meta(const api_meta_map &meta) -> std::uint64_t { auto get_changed_time_from_meta(const api_meta_map &meta) -> std::uint64_t {
return utils::string::to_uint64(meta.at(META_MODIFIED)); return utils::time::unix_time_to_windows_time(
utils::string::to_uint64(meta.at(META_MODIFIED)));
} }
auto get_creation_time_from_meta(const api_meta_map &meta) -> std::uint64_t { auto get_creation_time_from_meta(const api_meta_map &meta) -> std::uint64_t {
return utils::string::to_uint64(meta.at(META_CREATION)); return utils::time::unix_time_to_windows_time(
utils::string::to_uint64(meta.at(META_CREATION)));
} }
auto get_written_time_from_meta(const api_meta_map &meta) -> std::uint64_t { auto get_written_time_from_meta(const api_meta_map &meta) -> std::uint64_t {
return utils::string::to_uint64(meta.at(META_WRITTEN)); return utils::time::unix_time_to_windows_time(
utils::string::to_uint64(meta.at(META_WRITTEN)));
} }
auto unix_access_mask_to_windows(std::int32_t mask) -> int { auto unix_access_mask_to_windows(std::int32_t mask) -> int {

View File

@ -80,7 +80,7 @@ mount(std::vector<const char *> args, std::string data_directory,
std::cout << "Generated " << app_config::get_provider_display_name(prov) std::cout << "Generated " << app_config::get_provider_display_name(prov)
<< " Configuration" << std::endl; << " Configuration" << std::endl;
std::cout << config.get_config_file_path() << std::endl; std::cout << config.get_config_file_path() << std::endl;
ret = utils::file::is_file(config.get_config_file_path()) ret = utils::file::file(config.get_config_file_path()).exists()
? exit_code::success ? exit_code::success
: exit_code::file_creation_failed; : exit_code::file_creation_failed;
} else { } else {

View File

@ -21,7 +21,7 @@
*/ */
#if defined(PROJECT_ENABLE_BACKWARD_CPP) #if defined(PROJECT_ENABLE_BACKWARD_CPP)
#include "backward.hpp" #include "backward.hpp"
#endif #endif // defined(PROJECT_ENABLE_BACKWARD_CPP)
#include "cli/actions.hpp" #include "cli/actions.hpp"
#include "initialize.hpp" #include "initialize.hpp"
@ -34,7 +34,7 @@ using namespace repertory;
auto main(int argc, char **argv) -> int { auto main(int argc, char **argv) -> int {
#if defined(PROJECT_ENABLE_BACKWARD_CPP) #if defined(PROJECT_ENABLE_BACKWARD_CPP)
static backward::SignalHandling sh; static backward::SignalHandling sh;
#endif #endif // defined(PROJECT_ENABLE_BACKWARD_CPP)
if (not repertory::project_initialize()) { if (not repertory::project_initialize()) {
std::cerr << "fatal: failed to initialize repertory" << std::endl; std::cerr << "fatal: failed to initialize repertory" << std::endl;

View File

@ -0,0 +1,235 @@
/*
Copyright <2018-2024> <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 REPERTORY_TEST_INCLUDE_FIXTURES_FUSE_FIXTURE_HPP
#define REPERTORY_TEST_INCLUDE_FIXTURES_FUSE_FIXTURE_HPP
#if !defined(_WIN32)
#include "test_common.hpp"
#include "app_config.hpp"
#include "comm/curl/curl_comm.hpp"
#include "drives/fuse/fuse_drive.hpp"
#include "platform/platform.hpp"
#include "providers/encrypt/encrypt_provider.hpp"
#include "providers/s3/s3_provider.hpp"
#include "providers/sia/sia_provider.hpp"
#include "utils/file_utils.hpp"
#include "utils/path.hpp"
#if !defined(ACCESSPERMS)
#define ACCESSPERMS (S_IRWXU | S_IRWXG | S_IRWXO) /* 0777 */
#endif
namespace repertory {
inline constexpr const auto SLEEP_SECONDS{1.5s};
template <typename provider_t> class fuse_test : public ::testing::Test {
public:
static std::string cfg_directory;
static std::unique_ptr<curl_comm> comm;
static std::unique_ptr<app_config> config;
static std::filesystem::path current_directory;
static std::unique_ptr<fuse_drive> drive;
static lock_data lock_data_;
static std::string mount_location;
static std::unique_ptr<i_provider> provider;
static std::string test_directory;
protected:
static void SetUpTestCase() {
current_directory = std::filesystem::current_path();
test_directory = utils::path::combine(
test::get_test_output_dir(),
{
"fuse_test",
std::to_string(static_cast<std::uint8_t>(provider_t::type)),
});
ASSERT_TRUE(utils::file::directory(test_directory).remove_recursively());
mount_location = utils::path::combine(test_directory, {"mount"});
ASSERT_TRUE(utils::file::directory(mount_location).create_directory());
cfg_directory = utils::path::combine(test_directory, {"cfg"});
ASSERT_TRUE(utils::file::directory(cfg_directory).create_directory());
config = std::make_unique<app_config>(provider_t::type, cfg_directory);
std::vector<std::string> drive_args{};
switch (provider_t::type) {
case provider_type::s3: {
{
app_config src_cfg{
provider_type::s3,
utils::path::combine(test::get_test_input_dir(), {"storj"}),
};
config->set_enable_drive_events(true);
config->set_event_level(event_level::trace);
config->set_s3_config(src_cfg.get_s3_config());
}
comm = std::make_unique<curl_comm>(config->get_s3_config());
drive_args = std::vector<std::string>({
"-s3",
"-na",
"storj",
});
} break;
case provider_type::sia: {
{
app_config src_cfg{
provider_type::sia,
utils::path::combine(test::get_test_input_dir(), {"sia"}),
};
config->set_enable_drive_events(true);
config->set_event_level(event_level::debug);
config->set_host_config(src_cfg.get_host_config());
}
comm = std::make_unique<curl_comm>(config->get_host_config());
} break;
// case 0U: {
// config =
// std::make_unique<app_config>(provider_type::encrypt,
// cfg_directory);
// {
// app_config src_cfg(
// provider_type::s3,
// utils::path::combine(test::get_test_input_dir(), {"encrypt"}));
// config->set_enable_drive_events(true);
// config->set_event_level(event_level::trace);
// config->set_s3_config(src_cfg.get_s3_config());
// }
//
// comm = std::make_unique<curl_comm>(config->get_s3_config());
// provider = std::make_unique<s3_provider>(*config, *comm);
// drive_args = std::vector<std::string>({"-en"});
// } break;
default:
throw std::runtime_error("provider type is not implemented");
return;
}
provider = std::make_unique<provider_t>(*config, *comm);
drive_args.push_back(mount_location);
execute_mount(drive_args);
}
static void TearDownTestCase() {
execute_unmount();
std::filesystem::current_path(current_directory);
[[maybe_unused]] auto ret =
utils::file::directory(test_directory).remove_recursively();
}
public:
static auto create_file_and_test(std::string name) -> std::string {
auto file_path = utils::path::combine(mount_location, {name});
auto fd =
open(file_path.c_str(), O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP);
EXPECT_LE(1, fd);
EXPECT_TRUE(utils::file::file(file_path).exists());
EXPECT_FALSE(utils::file::directory(file_path).exists());
auto opt_size = utils::file::file{file_path}.size();
EXPECT_TRUE(opt_size.has_value());
EXPECT_EQ(0U, opt_size.value());
EXPECT_EQ(0, close(fd));
std::this_thread::sleep_for(SLEEP_SECONDS);
return file_path;
}
static void execute_mount(auto &&drive_args) {
auto mount_cmd = "./repertory -dd \"" + config->get_data_directory() +
"\"" + " " + utils::string::join(drive_args, ' ');
std::cout << "mount command: " << mount_cmd << std::endl;
ASSERT_EQ(0, system(mount_cmd.c_str()));
std::this_thread::sleep_for(5s);
EXPECT_EQ(0, system(("mount|grep \"" + mount_location + "\"").c_str()));
}
static void execute_unmount() {
auto unmounted{false};
for (int i = 0; not unmounted && (i < 50); i++) {
unmounted = (fuse_base::unmount(mount_location) == 0);
if (not unmounted) {
std::this_thread::sleep_for(100ms);
}
}
EXPECT_TRUE(unmounted);
}
static void unlink_file_and_test(const std::string &file_path) {
int ret = 0;
for (auto i = 0; ((ret = unlink(file_path.c_str())) != 0) && (i < 20);
i++) {
std::this_thread::sleep_for(100ms);
}
EXPECT_EQ(0, ret);
std::this_thread::sleep_for(SLEEP_SECONDS);
EXPECT_FALSE(utils::file::directory(file_path).exists());
EXPECT_FALSE(utils::file::file(file_path).exists());
}
};
template <typename provider_t>
std::string fuse_test<provider_t>::cfg_directory{};
template <typename provider_t>
std::unique_ptr<curl_comm> fuse_test<provider_t>::comm{};
template <typename provider_t>
std::unique_ptr<app_config> fuse_test<provider_t>::config{};
template <typename provider_t>
std::filesystem::path fuse_test<provider_t>::current_directory{};
template <typename provider_t>
std::unique_ptr<fuse_drive> fuse_test<provider_t>::drive{};
template <typename provider_t> lock_data fuse_test<provider_t>::lock_data_{};
template <typename provider_t>
std::string fuse_test<provider_t>::mount_location{};
template <typename provider_t>
std::unique_ptr<i_provider> fuse_test<provider_t>::provider{};
template <typename provider_t>
std::string fuse_test<provider_t>::test_directory;
typedef ::testing::Types<s3_provider, sia_provider> fuse_provider_types;
} // namespace repertory
#endif // !defined(_WIN32)
#endif // REPERTORY_TEST_INCLUDE_FIXTURES_FUSE_FIXTURE_HPP

View File

@ -19,8 +19,8 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
*/ */
#ifndef REPERTORY_WINFSP_FIXTURE_HPP #ifndef REPERTORY_TEST_INCLUDE_FIXTURES_WINFSP_FIXTURE_HPP
#define REPERTORY_WINFSP_FIXTURE_HPP #define REPERTORY_TEST_INCLUDE_FIXTURES_WINFSP_FIXTURE_HPP
#if defined(_WIN32) #if defined(_WIN32)
#include "test_common.hpp" #include "test_common.hpp"
@ -31,6 +31,8 @@
#include "platform/platform.hpp" #include "platform/platform.hpp"
#include "providers/s3/s3_provider.hpp" #include "providers/s3/s3_provider.hpp"
#include "providers/sia/sia_provider.hpp" #include "providers/sia/sia_provider.hpp"
#include "utils/file_utils.hpp"
#include "utils/path.hpp"
extern std::size_t PROVIDER_INDEX; extern std::size_t PROVIDER_INDEX;
@ -47,14 +49,20 @@ protected:
void SetUp() override { void SetUp() override {
if (PROVIDER_INDEX != 0) { if (PROVIDER_INDEX != 0) {
if (PROVIDER_INDEX == 1) { if (PROVIDER_INDEX == 1) {
EXPECT_TRUE(utils::file::delete_directory_recursively( EXPECT_TRUE(utils::file::directory(
"./test_config/winfsp_test" + std::to_string(PROVIDER_INDEX))); utils::path::combine(
test::get_test_output_dir(),
{"winfsp_test" + std::to_string(PROVIDER_INDEX)}))
.remove_recursively());
app_config src_cfg(provider_type::s3, app_config src_cfg(
utils::path::combine(get_test_dir(), {"storj"})); provider_type::s3,
utils::path::combine(test::get_test_input_dir(), {"storj"}));
config = std::make_unique<app_config>( config = std::make_unique<app_config>(
provider_type::s3, provider_type::s3,
"./test_config/winfsp_test" + std::to_string(PROVIDER_INDEX)); utils::path::combine(
test::get_test_output_dir(),
{"winfsp_test" + std::to_string(PROVIDER_INDEX)}));
EXPECT_FALSE(config EXPECT_FALSE(config
->set_value_by_name("S3Config.AccessKey", ->set_value_by_name("S3Config.AccessKey",
src_cfg.get_s3_config().access_key) src_cfg.get_s3_config().access_key)
@ -89,14 +97,20 @@ protected:
} }
if (PROVIDER_INDEX == 2) { if (PROVIDER_INDEX == 2) {
EXPECT_TRUE(utils::file::delete_directory_recursively( EXPECT_TRUE(utils::file::directory(
"./test_config/winfsp_test" + std::to_string(PROVIDER_INDEX))); utils::path::combine(
test::get_test_output_dir(),
{"winfsp_test" + std::to_string(PROVIDER_INDEX)}))
.remove_recursively());
app_config src_cfg(provider_type::sia, app_config src_cfg(
utils::path::combine(get_test_dir(), {"sia"})); provider_type::sia,
utils::path::combine(test::get_test_input_dir(), {"sia"}));
config = std::make_unique<app_config>( config = std::make_unique<app_config>(
provider_type::sia, provider_type::sia,
"./test_config/winfsp_test" + std::to_string(PROVIDER_INDEX)); utils::path::combine(
test::get_test_output_dir(),
{"winfsp_test" + std::to_string(PROVIDER_INDEX)}));
[[maybe_unused]] auto val = config->set_value_by_name( [[maybe_unused]] auto val = config->set_value_by_name(
"HostConfig.AgentString", src_cfg.get_host_config().agent_string); "HostConfig.AgentString", src_cfg.get_host_config().agent_string);
EXPECT_FALSE( EXPECT_FALSE(
@ -135,12 +149,15 @@ protected:
config.reset(); config.reset();
event_system::instance().stop(); event_system::instance().stop();
EXPECT_TRUE(utils::file::delete_directory_recursively( EXPECT_TRUE(utils::file::directory(
"./test_config/winfsp_test" + std::to_string(PROVIDER_INDEX))); utils::path::combine(
test::get_test_output_dir(),
{"winfsp_test" + std::to_string(PROVIDER_INDEX)}))
.remove_recursively());
} }
} }
}; };
} // namespace repertory } // namespace repertory
#endif #endif
#endif // REPERTORY_WINFSP_FIXTURE_HPP #endif // REPERTORY_TEST_INCLUDE_FIXTURES_WINFSP_FIXTURE_HPP

View File

@ -19,8 +19,8 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
*/ */
#ifndef TESTS_MOCKS_MOCK_FUSE_DRIVE_HPP_ #ifndef REPERTORY_TEST_INCLUDE_FIXTURES_MOCKS_MOCK_FUSE_DRIVE_HPP_
#define TESTS_MOCKS_MOCK_FUSE_DRIVE_HPP_ #define REPERTORY_TEST_INCLUDE_FIXTURES_MOCKS_MOCK_FUSE_DRIVE_HPP_
#if !defined(_WIN32) #if !defined(_WIN32)
#include "test_common.hpp" #include "test_common.hpp"
@ -68,10 +68,10 @@ public:
dir_item.size = 0; dir_item.size = 0;
dir_item.meta = { dir_item.meta = {
{META_ATTRIBUTES, "16"}, {META_ATTRIBUTES, "16"},
{META_MODIFIED, std::to_string(utils::time::get_file_time_now())}, {META_MODIFIED, std::to_string(utils::time::get_time_now())},
{META_WRITTEN, std::to_string(utils::time::get_file_time_now())}, {META_WRITTEN, std::to_string(utils::time::get_time_now())},
{META_ACCESSED, std::to_string(utils::time::get_file_time_now())}, {META_ACCESSED, std::to_string(utils::time::get_time_now())},
{META_CREATION, std::to_string(utils::time::get_file_time_now())}}; {META_CREATION, std::to_string(utils::time::get_time_now())}};
list.emplace_back(dir_item); list.emplace_back(dir_item);
dir_item.api_path = ".."; dir_item.api_path = "..";
@ -132,11 +132,11 @@ public:
utils::path::combine(mount_location_, {to_api_path}); utils::path::combine(mount_location_, {to_api_path});
if (overwrite) { if (overwrite) {
if (not utils::file::retry_delete_file(to_file_path)) { if (not utils::file::file(to_file_path).remove()) {
return -1; return -1;
} }
} else if (utils::file::is_directory(to_file_path) || } else if (utils::file::directory(to_file_path).exists() ||
utils::file::is_file(to_file_path)) { utils::file::file(to_file_path).exists()) {
errno = EEXIST; errno = EEXIST;
return -1; return -1;
} }
@ -155,5 +155,5 @@ public:
}; };
} // namespace repertory } // namespace repertory
#endif // _WIN32 #endif // !defined(_WIN32)
#endif // TESTS_MOCKS_MOCK_FUSE_DRIVE_HPP_ #endif // REPERTORY_TEST_INCLUDE_FIXTURES_MOCKS_MOCK_FUSE_DRIVE_HPP_

View File

@ -19,8 +19,8 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
*/ */
#ifndef TESTS_MOCKS_MOCK_OPEN_FILE_HPP_ #ifndef REPERTORY_TEST_INCLUDE_MOCKS_MOCK_OPEN_FILE_HPP_
#define TESTS_MOCKS_MOCK_OPEN_FILE_HPP_ #define REPERTORY_TEST_INCLUDE_MOCKS_MOCK_OPEN_FILE_HPP_
#include "test_common.hpp" #include "test_common.hpp"
@ -95,4 +95,4 @@ public:
}; };
} // namespace repertory } // namespace repertory
#endif // TESTS_MOCKS_MOCK_OPEN_FILE_HPP_ #endif // REPERTORY_TEST_INCLUDE_MOCKS_MOCK_OPEN_FILE_HPP_

View File

@ -19,8 +19,8 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
*/ */
#ifndef TESTS_MOCKS_MOCK_PROVIDER_HPP_ #ifndef REPERTORY_TEST_INCLUDE_MOCKS_MOCK_PROVIDER_HPP_
#define TESTS_MOCKS_MOCK_PROVIDER_HPP_ #define REPERTORY_TEST_INCLUDE_MOCKS_MOCK_PROVIDER_HPP_
#include "test_common.hpp" #include "test_common.hpp"
@ -159,4 +159,4 @@ public:
}; };
} // namespace repertory } // namespace repertory
#endif // TESTS_MOCKS_MOCK_PROVIDER_HPP_ #endif // REPERTORY_TEST_INCLUDE_MOCKS_MOCK_PROVIDER_HPP_

View File

@ -19,8 +19,8 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
*/ */
#ifndef TESTS_MOCKS_MOCK_UPLOAD_MANAGER_HPP_ #ifndef REPERTORY_TEST_INCLUDE_MOCKS_MOCK_UPLOAD_MANAGER_HPP_
#define TESTS_MOCKS_MOCK_UPLOAD_MANAGER_HPP_ #define REPERTORY_TEST_INCLUDE_MOCKS_MOCK_UPLOAD_MANAGER_HPP_
#include "test_common.hpp" #include "test_common.hpp"
@ -41,4 +41,4 @@ public:
}; };
} // namespace repertory } // namespace repertory
#endif // TESTS_MOCKS_MOCK_UPLOAD_MANAGER_HPP_ #endif // REPERTORY_TEST_INCLUDE_MOCKS_MOCK_UPLOAD_MANAGER_HPP_

View File

@ -19,8 +19,8 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
*/ */
#ifndef TESTS_MOCKS_MOCK_WINFSP_DRIVE_HPP_ #ifndef REPERTORY_TEST_INCLUDE_MOCKS_MOCK_WINFSP_DRIVE_HPP_
#define TESTS_MOCKS_MOCK_WINFSP_DRIVE_HPP_ #define REPERTORY_TEST_INCLUDE_MOCKS_MOCK_WINFSP_DRIVE_HPP_
#if defined(_WIN32) #if defined(_WIN32)
#include "test_common.hpp" #include "test_common.hpp"
@ -57,10 +57,10 @@ public:
di.size = 0u; di.size = 0u;
di.meta = { di.meta = {
{META_ATTRIBUTES, "16"}, {META_ATTRIBUTES, "16"},
{META_MODIFIED, std::to_string(utils::time::get_file_time_now())}, {META_MODIFIED, std::to_string(utils::time::get_time_now())},
{META_WRITTEN, std::to_string(utils::time::get_file_time_now())}, {META_WRITTEN, std::to_string(utils::time::get_time_now())},
{META_ACCESSED, std::to_string(utils::time::get_file_time_now())}, {META_ACCESSED, std::to_string(utils::time::get_time_now())},
{META_CREATION, std::to_string(utils::time::get_file_time_now())}}; {META_CREATION, std::to_string(utils::time::get_time_now())}};
list.emplace_back(di); list.emplace_back(di);
di.api_path = ".."; di.api_path = "..";
@ -138,7 +138,7 @@ public:
auto populate_file_info(const std::string &api_path, auto populate_file_info(const std::string &api_path,
remote::file_info &file_info) -> api_error override { remote::file_info &file_info) -> api_error override {
const auto file_path = utils::path::combine(mount_location_, {api_path}); const auto file_path = utils::path::combine(mount_location_, {api_path});
const auto directory = utils::file::is_directory(file_path); const auto directory = utils::file::directory(file_path).exists();
const auto attributes = const auto attributes =
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_BACKUP_SEMANTICS |
(directory ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL); (directory ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL);
@ -148,8 +148,14 @@ public:
FILE_BASIC_INFO fi{}; FILE_BASIC_INFO fi{};
::GetFileInformationByHandleEx(handle, FileBasicInfo, &fi, sizeof(fi)); ::GetFileInformationByHandleEx(handle, FileBasicInfo, &fi, sizeof(fi));
if (not directory) { if (not directory) {
utils::file::get_file_size(file_path, file_info.FileSize); auto opt_size = utils::file::file{file_path}.size();
if (not opt_size.has_value()) {
return api_error::os_error;
}
file_info.FileSize = opt_size.value();
} }
file_info.AllocationSize = file_info.AllocationSize =
directory ? 0 directory ? 0
: utils::divide_with_ceiling(file_info.FileSize, : utils::divide_with_ceiling(file_info.FileSize,
@ -167,4 +173,4 @@ public:
} // namespace repertory } // namespace repertory
#endif // _WIN32 #endif // _WIN32
#endif // TESTS_MOCKS_MOCK_WINFSP_DRIVE_HPP_ #endif // REPERTORY_TEST_INCLUDE_MOCKS_MOCK_WINFSP_DRIVE_HPP_

View File

@ -19,47 +19,15 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
*/ */
#ifndef TESTS_TEST_COMMON_HPP_ #ifndef REPERTORY_TEST_INCLUDE_TEST_COMMON_HPP_
#define TESTS_TEST_COMMON_HPP_ #define REPERTORY_TEST_INCLUDE_TEST_COMMON_HPP_
#if defined(U)
#undef U
#endif
REPERTORY_IGNORE_WARNINGS_ENABLE() REPERTORY_IGNORE_WARNINGS_ENABLE()
#include <gmock/gmock.h> #include "test.hpp"
#include <gtest/gtest.h>
REPERTORY_IGNORE_WARNINGS_DISABLE() REPERTORY_IGNORE_WARNINGS_DISABLE()
#include "events/consumers/console_consumer.hpp" #include "events/consumers/console_consumer.hpp"
#include "events/event_system.hpp" #include "events/event_system.hpp"
#include "events/events.hpp" #include "events/events.hpp"
#include "utils/encrypt.hpp"
#include "utils/file_utils.hpp"
#include "utils/native_file.hpp"
#define COMMA , #endif // REPERTORY_TEST_INCLUDE_TEST_COMMON_HPP_
using ::testing::_;
using namespace ::testing;
namespace repertory {
[[nodiscard]] auto create_random_file(std::string path,
std::size_t size) -> native_file_ptr;
void delete_generated_files();
[[nodiscard]] auto generate_test_file_name(
const std::string &directory,
const std::string &file_name_no_extension) -> std::string;
template <typename T, typename T2>
static void decrypt_and_verify(const T &buffer, const std::string &token,
T2 &result) {
EXPECT_TRUE(utils::encryption::decrypt_data(token, buffer, result));
}
[[nodiscard]] auto get_test_dir() -> std::string;
} // namespace repertory
#endif // TESTS_TEST_COMMON_HPP_

View File

@ -19,8 +19,8 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
*/ */
#ifndef TESTS_UTILS_EVENT_CAPTURE_HPP_ #ifndef REPERTORY_TEST_INCLUDE_UTILS_EVENT_CAPTURE_HPP_
#define TESTS_UTILS_EVENT_CAPTURE_HPP_ #define REPERTORY_TEST_INCLUDE_UTILS_EVENT_CAPTURE_HPP_
#include "test_common.hpp" #include "test_common.hpp"
@ -106,4 +106,4 @@ public:
}; };
} // namespace repertory } // namespace repertory
#endif // TESTS_UTILS_EVENT_CAPTURE_HPP_ #endif // REPERTORY_TEST_INCLUDE_UTILS_EVENT_CAPTURE_HPP_

View File

@ -63,8 +63,6 @@ auto main(int argc, char **argv) -> int {
::testing::InitGoogleTest(&argc, argv); ::testing::InitGoogleTest(&argc, argv);
auto ret = RUN_ALL_TESTS(); auto ret = RUN_ALL_TESTS();
delete_generated_files();
repertory::project_cleanup(); repertory::project_cleanup();
return ret; return ret;

View File

@ -33,20 +33,24 @@ public:
static console_consumer cs; static console_consumer cs;
std::string s3_directory{ std::string s3_directory{
utils::path::combine("./test_config", {"config_test", "s3"})}; utils::path::combine(test::get_test_output_dir(), {"config_test", "s3"})};
std::string sia_directory{ std::string sia_directory{utils::path::combine(test::get_test_output_dir(),
utils::path::combine("./test_config", {"config_test", "sia"})}; {"config_test", "sia"})};
void SetUp() override { void SetUp() override {
event_system::instance().start(); event_system::instance().start();
ASSERT_TRUE(utils::file::delete_directory_recursively( ASSERT_TRUE(
utils::path::combine("./test_config", {"config_test"}))); utils::file::directory(
utils::path::combine(test::get_test_output_dir(), {"config_test"}))
.remove_recursively());
} }
void TearDown() override { void TearDown() override {
ASSERT_TRUE(utils::file::delete_directory_recursively( ASSERT_TRUE(
utils::path::combine("./test_config", {"config_test"}))); utils::file::directory(
utils::path::combine(test::get_test_output_dir(), {"config_test"}))
.remove_recursively());
event_system::instance().stop(); event_system::instance().stop();
} }
}; };
@ -163,10 +167,12 @@ TEST_F(config_test, sia_default_settings) {
json data; json data;
EXPECT_TRUE(utils::file::read_json_file(config_file, data)); EXPECT_TRUE(utils::file::read_json_file(config_file, data));
EXPECT_STREQ(DEFAULT_SIA_CONFIG.c_str(), data.dump(2).c_str()); EXPECT_STREQ(DEFAULT_SIA_CONFIG.c_str(), data.dump(2).c_str());
EXPECT_TRUE(utils::file::is_directory( EXPECT_TRUE(
utils::path::combine(sia_directory, {"cache"}))); utils::file::directory(utils::path::combine(sia_directory, {"cache"}))
EXPECT_TRUE(utils::file::is_directory( .exists());
utils::path::combine(sia_directory, {"logs"}))); EXPECT_TRUE(
utils::file::directory(utils::path::combine(sia_directory, {"logs"}))
.exists());
} }
} }
@ -180,10 +186,12 @@ TEST_F(config_test, s3_default_settings) {
json data; json data;
EXPECT_TRUE(utils::file::read_json_file(config_file, data)); EXPECT_TRUE(utils::file::read_json_file(config_file, data));
EXPECT_STREQ(DEFAULT_S3_CONFIG.c_str(), data.dump(2).c_str()); EXPECT_STREQ(DEFAULT_S3_CONFIG.c_str(), data.dump(2).c_str());
EXPECT_TRUE(utils::file::is_directory( EXPECT_TRUE(
utils::path::combine(s3_directory, {"cache"}))); utils::file::directory(utils::path::combine(s3_directory, {"cache"}))
EXPECT_TRUE(utils::file::is_directory( .exists());
utils::path::combine(s3_directory, {"logs"}))); EXPECT_TRUE(
utils::file::directory(utils::path::combine(s3_directory, {"logs"}))
.exists());
} }
} }

View File

@ -35,8 +35,9 @@ TEST(database, db_insert) {
{ {
sqlite3 *db3_ptr{nullptr}; sqlite3 *db3_ptr{nullptr};
auto res = sqlite3_open_v2( auto res = sqlite3_open_v2(
utils::path::combine(get_test_dir(), {"test.db3"}).c_str(), &db3_ptr, utils::path::combine(test::get_test_input_dir(), {"test.db3"})
SQLITE_OPEN_READWRITE, nullptr); .c_str(),
&db3_ptr, SQLITE_OPEN_READWRITE, nullptr);
ASSERT_EQ(SQLITE_OK, res); ASSERT_EQ(SQLITE_OK, res);
ASSERT_TRUE(db3_ptr != nullptr); ASSERT_TRUE(db3_ptr != nullptr);
@ -78,8 +79,9 @@ TEST(database, db_select) {
{ {
sqlite3 *db3_ptr{nullptr}; sqlite3 *db3_ptr{nullptr};
auto res = sqlite3_open_v2( auto res = sqlite3_open_v2(
utils::path::combine(get_test_dir(), {"test.db3"}).c_str(), &db3_ptr, utils::path::combine(test::get_test_input_dir(), {"test.db3"})
SQLITE_OPEN_READWRITE, nullptr); .c_str(),
&db3_ptr, SQLITE_OPEN_READWRITE, nullptr);
ASSERT_EQ(SQLITE_OK, res); ASSERT_EQ(SQLITE_OK, res);
ASSERT_TRUE(db3_ptr != nullptr); ASSERT_TRUE(db3_ptr != nullptr);

View File

@ -55,7 +55,7 @@ static void validate_write(file_manager::open_file &o, std::size_t offset,
TEST(open_file, properly_initializes_state_for_0_byte_file) { TEST(open_file, properly_initializes_state_for_0_byte_file) {
const auto source_path = const auto source_path =
generate_test_file_name("./test_config", "file_manager_open_file_test"); test::generate_test_file_name("file_manager_open_file_test");
mock_provider mp; mock_provider mp;
mock_upload_manager um; mock_upload_manager um;
@ -76,7 +76,7 @@ TEST(open_file, properly_initializes_state_for_0_byte_file) {
TEST(open_file, properly_initializes_state_based_on_chunk_size) { TEST(open_file, properly_initializes_state_based_on_chunk_size) {
const auto source_path = const auto source_path =
generate_test_file_name("./test_config", "file_manager_open_file_test"); test::generate_test_file_name("file_manager_open_file_test");
mock_provider mp; mock_provider mp;
mock_upload_manager um; mock_upload_manager um;
@ -109,7 +109,7 @@ TEST(open_file, properly_initializes_state_based_on_chunk_size) {
TEST(open_file, will_not_change_source_path_for_0_byte_file) { TEST(open_file, will_not_change_source_path_for_0_byte_file) {
const auto source_path = const auto source_path =
generate_test_file_name("./test_config", "file_manager_open_file_test"); test::generate_test_file_name("file_manager_open_file_test");
mock_provider mp; mock_provider mp;
mock_upload_manager um; mock_upload_manager um;
@ -128,12 +128,12 @@ TEST(open_file, will_not_change_source_path_for_0_byte_file) {
o.close(); o.close();
EXPECT_EQ(api_error::success, o.get_api_error()); EXPECT_EQ(api_error::success, o.get_api_error());
EXPECT_STREQ(source_path.c_str(), o.get_source_path().c_str()); EXPECT_STREQ(source_path.c_str(), o.get_source_path().c_str());
EXPECT_TRUE(utils::file::is_file(fsi.source_path)); EXPECT_TRUE(utils::file::file(fsi.source_path).exists());
} }
TEST(open_file, will_change_source_path_if_file_size_is_greater_than_0) { TEST(open_file, will_change_source_path_if_file_size_is_greater_than_0) {
const auto source_path = const auto source_path =
generate_test_file_name("./test_config", "file_manager_open_file_test"); test::generate_test_file_name("file_manager_open_file_test");
mock_provider mp; mock_provider mp;
mock_upload_manager um; mock_upload_manager um;
@ -166,14 +166,14 @@ TEST(open_file, will_change_source_path_if_file_size_is_greater_than_0) {
o.close(); o.close();
EXPECT_EQ(api_error::download_stopped, o.get_api_error()); EXPECT_EQ(api_error::download_stopped, o.get_api_error());
EXPECT_STRNE(source_path.c_str(), o.get_source_path().c_str()); EXPECT_STRNE(source_path.c_str(), o.get_source_path().c_str());
EXPECT_FALSE(utils::file::is_file(source_path)); EXPECT_FALSE(utils::file::file(source_path).exists());
} }
TEST(open_file, TEST(open_file,
will_not_change_source_path_if_file_size_matches_existing_source) { will_not_change_source_path_if_file_size_matches_existing_source) {
const auto source_path = auto &rf = test::create_random_file(test_chunk_size);
generate_test_file_name("./test_config", "file_manager_open_file_test"); const auto source_path = rf.get_path();
create_random_file(source_path, test_chunk_size)->close(); rf.close();
mock_provider mp; mock_provider mp;
mock_upload_manager um; mock_upload_manager um;
@ -192,15 +192,12 @@ TEST(open_file,
o.close(); o.close();
EXPECT_EQ(api_error::success, o.get_api_error()); EXPECT_EQ(api_error::success, o.get_api_error());
EXPECT_STREQ(source_path.c_str(), o.get_source_path().c_str()); EXPECT_STREQ(source_path.c_str(), o.get_source_path().c_str());
EXPECT_TRUE(utils::file::is_file(source_path)); EXPECT_TRUE(utils::file::file(source_path).exists());
} }
TEST(open_file, write_with_incomplete_download) { TEST(open_file, write_with_incomplete_download) {
const auto source_path = const auto source_path = test::generate_test_file_name("test");
generate_test_file_name("./test_config", "file_manager_open_file_test"); auto &nf = test::create_random_file(test_chunk_size * 2u);
auto nf = create_random_file(
generate_test_file_name("./test_config", "file_manager_open_file_test"),
test_chunk_size * 2u);
mock_provider mp; mock_provider mp;
mock_upload_manager um; mock_upload_manager um;
@ -236,9 +233,8 @@ TEST(open_file, write_with_incomplete_download) {
if (offset == 0u) { if (offset == 0u) {
std::size_t bytes_read{}; std::size_t bytes_read{};
data.resize(size); data.resize(size);
auto ret = nf->read_bytes(&data[0u], size, offset, bytes_read) auto ret = nf.read(data, offset, &bytes_read) ? api_error::success
? api_error::success : api_error::os_error;
: api_error::os_error;
EXPECT_EQ(bytes_read, data.size()); EXPECT_EQ(bytes_read, data.size());
return ret; return ret;
} }
@ -278,18 +274,18 @@ TEST(open_file, write_with_incomplete_download) {
test_state(); test_state();
o.close(); o.close();
nf->close(); nf.close();
test_state(); test_state();
EXPECT_EQ(api_error::download_incomplete, o.get_api_error()); EXPECT_EQ(api_error::download_incomplete, o.get_api_error());
EXPECT_TRUE(utils::file::is_file(fsi.source_path)); EXPECT_TRUE(utils::file::file(fsi.source_path).exists());
} }
TEST(open_file, write_new_file) { TEST(open_file, write_new_file) {
const auto source_path = const auto source_path =
generate_test_file_name("./test_config", "file_manager_open_file_test"); test::generate_test_file_name("file_manager_open_file_test");
mock_provider mp; mock_provider mp;
mock_upload_manager um; mock_upload_manager um;
@ -357,12 +353,12 @@ TEST(open_file, write_new_file) {
EXPECT_EQ(api_error::success, o.get_api_error()); EXPECT_EQ(api_error::success, o.get_api_error());
EXPECT_TRUE(utils::file::is_file(fsi.source_path)); EXPECT_TRUE(utils::file::file(fsi.source_path).exists());
} }
TEST(open_file, write_new_file_multiple_chunks) { TEST(open_file, write_new_file_multiple_chunks) {
const auto source_path = const auto source_path =
generate_test_file_name("./test_config", "file_manager_open_file_test"); test::generate_test_file_name("file_manager_open_file_test");
mock_provider mp; mock_provider mp;
mock_upload_manager um; mock_upload_manager um;
@ -449,13 +445,13 @@ TEST(open_file, write_new_file_multiple_chunks) {
EXPECT_EQ(api_error::success, o.get_api_error()); EXPECT_EQ(api_error::success, o.get_api_error());
EXPECT_TRUE(utils::file::is_file(fsi.source_path)); EXPECT_TRUE(utils::file::file(fsi.source_path).exists());
} }
TEST(open_file, resize_file_to_0_bytes) { TEST(open_file, resize_file_to_0_bytes) {
const auto source_path = auto &rf = test::create_random_file(test_chunk_size * 4u);
generate_test_file_name("./test_config", "file_manager_open_file_test"); const auto source_path = rf.get_path();
create_random_file(source_path, test_chunk_size * 4u)->close(); rf.close();
mock_provider mp; mock_provider mp;
mock_upload_manager um; mock_upload_manager um;
@ -503,9 +499,9 @@ TEST(open_file, resize_file_to_0_bytes) {
} }
TEST(open_file, resize_file_by_full_chunk) { TEST(open_file, resize_file_by_full_chunk) {
const auto source_path = auto &rf = test::create_random_file(test_chunk_size * 4u);
generate_test_file_name("./test_config", "file_manager_open_file_test"); const auto source_path = rf.get_path();
create_random_file(source_path, test_chunk_size * 4u)->close(); rf.close();
mock_provider mp; mock_provider mp;
mock_upload_manager um; mock_upload_manager um;
@ -556,7 +552,7 @@ TEST(open_file, can_add_handle) {
event_system::instance().start(); event_system::instance().start();
console_consumer c; console_consumer c;
const auto source_path = const auto source_path =
generate_test_file_name("./test_config", "file_manager_open_file_test"); test::generate_test_file_name("file_manager_open_file_test");
mock_provider mp; mock_provider mp;
mock_upload_manager um; mock_upload_manager um;
@ -618,7 +614,7 @@ TEST(open_file, can_remove_handle) {
console_consumer c; console_consumer c;
const auto source_path = const auto source_path =
generate_test_file_name("./test_config", "file_manager_open_file_test"); test::generate_test_file_name("file_manager_open_file_test");
mock_provider mp; mock_provider mp;
mock_upload_manager um; mock_upload_manager um;

View File

@ -31,11 +31,11 @@
namespace repertory { namespace repertory {
static constexpr const std::size_t test_chunk_size = 1024u; static constexpr const std::size_t test_chunk_size = 1024u;
static std::string ring_buffer_dir = utils::path::combine( static std::string ring_buffer_dir = utils::path::combine(
"./test_config", {"file_manager_ring_buffer_open_file_test"}); test::get_test_output_dir(), {"file_manager_ring_buffer_open_file_test"});
TEST(ring_buffer_open_file, can_forward_to_last_chunk) { TEST(ring_buffer_open_file, can_forward_to_last_chunk) {
const auto source_path = const auto source_path =
generate_test_file_name("./test_config", "ring_buffer_open_file"); test::generate_test_file_name("ring_buffer_open_file");
mock_provider mp; mock_provider mp;
@ -61,13 +61,13 @@ TEST(ring_buffer_open_file, can_forward_to_last_chunk) {
} }
} }
EXPECT_TRUE(utils::file::delete_directory_recursively(ring_buffer_dir)); EXPECT_TRUE(utils::file::directory(ring_buffer_dir).remove_recursively());
} }
TEST(ring_buffer_open_file, TEST(ring_buffer_open_file,
can_forward_to_last_chunk_if_count_is_greater_than_remaining) { can_forward_to_last_chunk_if_count_is_greater_than_remaining) {
const auto source_path = const auto source_path =
generate_test_file_name("./test_config", "ring_buffer_open_file"); test::generate_test_file_name("ring_buffer_open_file");
mock_provider mp; mock_provider mp;
@ -93,12 +93,12 @@ TEST(ring_buffer_open_file,
} }
} }
EXPECT_TRUE(utils::file::delete_directory_recursively(ring_buffer_dir)); EXPECT_TRUE(utils::file::directory(ring_buffer_dir).remove_recursively());
} }
TEST(ring_buffer_open_file, can_forward_after_last_chunk) { TEST(ring_buffer_open_file, can_forward_after_last_chunk) {
const auto source_path = const auto source_path =
generate_test_file_name("./test_config", "ring_buffer_open_file"); test::generate_test_file_name("ring_buffer_open_file");
mock_provider mp; mock_provider mp;
@ -125,12 +125,12 @@ TEST(ring_buffer_open_file, can_forward_after_last_chunk) {
} }
} }
EXPECT_TRUE(utils::file::delete_directory_recursively(ring_buffer_dir)); EXPECT_TRUE(utils::file::directory(ring_buffer_dir).remove_recursively());
} }
TEST(ring_buffer_open_file, can_forward_and_rollover_after_last_chunk) { TEST(ring_buffer_open_file, can_forward_and_rollover_after_last_chunk) {
const auto source_path = const auto source_path =
generate_test_file_name("./test_config", "ring_buffer_open_file"); test::generate_test_file_name("ring_buffer_open_file");
mock_provider mp; mock_provider mp;
@ -153,12 +153,12 @@ TEST(ring_buffer_open_file, can_forward_and_rollover_after_last_chunk) {
EXPECT_EQ(std::size_t(28u), rb.get_last_chunk()); EXPECT_EQ(std::size_t(28u), rb.get_last_chunk());
} }
EXPECT_TRUE(utils::file::delete_directory_recursively(ring_buffer_dir)); EXPECT_TRUE(utils::file::directory(ring_buffer_dir).remove_recursively());
} }
TEST(ring_buffer_open_file, can_reverse_to_first_chunk) { TEST(ring_buffer_open_file, can_reverse_to_first_chunk) {
const auto source_path = const auto source_path =
generate_test_file_name("./test_config", "ring_buffer_open_file"); test::generate_test_file_name("ring_buffer_open_file");
mock_provider mp; mock_provider mp;
@ -184,13 +184,13 @@ TEST(ring_buffer_open_file, can_reverse_to_first_chunk) {
} }
} }
EXPECT_TRUE(utils::file::delete_directory_recursively(ring_buffer_dir)); EXPECT_TRUE(utils::file::directory(ring_buffer_dir).remove_recursively());
} }
TEST(ring_buffer_open_file, TEST(ring_buffer_open_file,
can_reverse_to_first_chunk_if_count_is_greater_than_remaining) { can_reverse_to_first_chunk_if_count_is_greater_than_remaining) {
const auto source_path = const auto source_path =
generate_test_file_name("./test_config", "ring_buffer_open_file"); test::generate_test_file_name("ring_buffer_open_file");
mock_provider mp; mock_provider mp;
@ -216,12 +216,12 @@ TEST(ring_buffer_open_file,
} }
} }
EXPECT_TRUE(utils::file::delete_directory_recursively(ring_buffer_dir)); EXPECT_TRUE(utils::file::directory(ring_buffer_dir).remove_recursively());
} }
TEST(ring_buffer_open_file, can_reverse_before_first_chunk) { TEST(ring_buffer_open_file, can_reverse_before_first_chunk) {
const auto source_path = const auto source_path =
generate_test_file_name("./test_config", "ring_buffer_open_file"); test::generate_test_file_name("ring_buffer_open_file");
mock_provider mp; mock_provider mp;
@ -248,12 +248,12 @@ TEST(ring_buffer_open_file, can_reverse_before_first_chunk) {
} }
} }
EXPECT_TRUE(utils::file::delete_directory_recursively(ring_buffer_dir)); EXPECT_TRUE(utils::file::directory(ring_buffer_dir).remove_recursively());
} }
TEST(ring_buffer_open_file, can_reverse_and_rollover_before_first_chunk) { TEST(ring_buffer_open_file, can_reverse_and_rollover_before_first_chunk) {
const auto source_path = const auto source_path =
generate_test_file_name("./test_config", "ring_buffer_open_file"); test::generate_test_file_name("ring_buffer_open_file");
mock_provider mp; mock_provider mp;
@ -284,12 +284,12 @@ TEST(ring_buffer_open_file, can_reverse_and_rollover_before_first_chunk) {
} }
} }
EXPECT_TRUE(utils::file::delete_directory_recursively(ring_buffer_dir)); EXPECT_TRUE(utils::file::directory(ring_buffer_dir).remove_recursively());
} }
TEST(ring_buffer_open_file, can_reverse_full_ring) { TEST(ring_buffer_open_file, can_reverse_full_ring) {
const auto source_path = const auto source_path =
generate_test_file_name("./test_config", "ring_buffer_open_file"); test::generate_test_file_name("ring_buffer_open_file");
mock_provider mp; mock_provider mp;
@ -316,16 +316,14 @@ TEST(ring_buffer_open_file, can_reverse_full_ring) {
} }
} }
EXPECT_TRUE(utils::file::delete_directory_recursively(ring_buffer_dir)); EXPECT_TRUE(utils::file::directory(ring_buffer_dir).remove_recursively());
} }
TEST(ring_buffer_open_file, read_full_file) { TEST(ring_buffer_open_file, read_full_file) {
const auto download_source_path = auto &nf = test::create_random_file(test_chunk_size * 32u);
generate_test_file_name("./test_config", "ring_buffer_open_file"); const auto download_source_path = nf.get_path();
auto nf = create_random_file(download_source_path, test_chunk_size * 32u);
const auto dest_path = const auto dest_path = test::generate_test_file_name("ring_buffer_open_file");
generate_test_file_name("./test_config", "ring_buffer_open_file");
mock_provider mp; mock_provider mp;
@ -335,8 +333,7 @@ TEST(ring_buffer_open_file, read_full_file) {
fsi.directory = false; fsi.directory = false;
fsi.api_path = "/test.txt"; fsi.api_path = "/test.txt";
fsi.size = test_chunk_size * 32u; fsi.size = test_chunk_size * 32u;
fsi.source_path = fsi.source_path = test::generate_test_file_name("ring_buffer_open_file");
generate_test_file_name("./test_config", "ring_buffer_open_file");
EXPECT_CALL(mp, read_file_bytes) EXPECT_CALL(mp, read_file_bytes)
.WillRepeatedly([&nf](const std::string & /* api_path */, .WillRepeatedly([&nf](const std::string & /* api_path */,
@ -346,9 +343,8 @@ TEST(ring_buffer_open_file, read_full_file) {
EXPECT_FALSE(stop_requested); EXPECT_FALSE(stop_requested);
std::size_t bytes_read{}; std::size_t bytes_read{};
data.resize(size); data.resize(size);
auto ret = nf->read_bytes(&data[0u], size, offset, bytes_read) auto ret = nf.read(data, offset, &bytes_read) ? api_error::success
? api_error::success : api_error::os_error;
: api_error::os_error;
EXPECT_EQ(bytes_read, data.size()); EXPECT_EQ(bytes_read, data.size());
return ret; return ret;
}); });
@ -356,8 +352,9 @@ TEST(ring_buffer_open_file, read_full_file) {
file_manager::ring_buffer_open_file rb(ring_buffer_dir, test_chunk_size, file_manager::ring_buffer_open_file rb(ring_buffer_dir, test_chunk_size,
30U, fsi, mp, 8u); 30U, fsi, mp, 8u);
native_file_ptr nf2; auto ptr = utils::file::file::open_or_create_file(dest_path);
EXPECT_EQ(api_error::success, native_file::create_or_open(dest_path, nf2)); auto &nf2 = *ptr;
EXPECT_TRUE(nf2);
auto to_read = fsi.size; auto to_read = fsi.size;
std::size_t chunk = 0u; std::size_t chunk = 0u;
@ -367,28 +364,31 @@ TEST(ring_buffer_open_file, read_full_file) {
rb.read(test_chunk_size, chunk * test_chunk_size, data)); rb.read(test_chunk_size, chunk * test_chunk_size, data));
std::size_t bytes_written{}; std::size_t bytes_written{};
EXPECT_TRUE(nf2->write_bytes(data.data(), data.size(), EXPECT_TRUE(nf2.write(data, chunk * test_chunk_size, &bytes_written));
chunk * test_chunk_size, bytes_written));
chunk++; chunk++;
to_read -= data.size(); to_read -= data.size();
} }
nf2->close(); nf2.close();
nf->close(); nf.close();
EXPECT_STREQ(utils::file::generate_sha256(download_source_path).c_str(), auto hash1 = utils::file::file(download_source_path).sha256();
utils::file::generate_sha256(dest_path).c_str()); auto hash2 = utils::file::file(dest_path).sha256();
EXPECT_TRUE(hash1.has_value());
EXPECT_TRUE(hash2.has_value());
if (hash1.has_value() && hash2.has_value()) {
EXPECT_STREQ(hash1.value().c_str(), hash2.value().c_str());
}
} }
EXPECT_TRUE(utils::file::delete_directory_recursively(ring_buffer_dir)); EXPECT_TRUE(utils::file::directory(ring_buffer_dir).remove_recursively());
} }
TEST(ring_buffer_open_file, read_full_file_in_reverse) { TEST(ring_buffer_open_file, read_full_file_in_reverse) {
const auto download_source_path = auto &nf = test::create_random_file(test_chunk_size * 32u);
generate_test_file_name("./test_config", "ring_buffer_open_file"); const auto download_source_path = nf.get_path();
auto nf = create_random_file(download_source_path, test_chunk_size * 32u);
const auto dest_path = const auto dest_path = test::generate_test_file_name("ring_buffer_open_file");
generate_test_file_name("./test_config", "ring_buffer_open_file");
mock_provider mp; mock_provider mp;
@ -398,8 +398,7 @@ TEST(ring_buffer_open_file, read_full_file_in_reverse) {
fsi.directory = false; fsi.directory = false;
fsi.api_path = "/test.txt"; fsi.api_path = "/test.txt";
fsi.size = test_chunk_size * 32u; fsi.size = test_chunk_size * 32u;
fsi.source_path = fsi.source_path = test::generate_test_file_name("ring_buffer_open_file");
generate_test_file_name("./test_config", "ring_buffer_open_file");
EXPECT_CALL(mp, read_file_bytes) EXPECT_CALL(mp, read_file_bytes)
.WillRepeatedly([&nf](const std::string & /* api_path */, .WillRepeatedly([&nf](const std::string & /* api_path */,
@ -409,9 +408,8 @@ TEST(ring_buffer_open_file, read_full_file_in_reverse) {
EXPECT_FALSE(stop_requested); EXPECT_FALSE(stop_requested);
std::size_t bytes_read{}; std::size_t bytes_read{};
data.resize(size); data.resize(size);
auto ret = nf->read_bytes(&data[0u], size, offset, bytes_read) auto ret = nf.read(data, offset, &bytes_read) ? api_error::success
? api_error::success : api_error::os_error;
: api_error::os_error;
EXPECT_EQ(bytes_read, data.size()); EXPECT_EQ(bytes_read, data.size());
return ret; return ret;
}); });
@ -419,8 +417,9 @@ TEST(ring_buffer_open_file, read_full_file_in_reverse) {
file_manager::ring_buffer_open_file rb(ring_buffer_dir, test_chunk_size, file_manager::ring_buffer_open_file rb(ring_buffer_dir, test_chunk_size,
30U, fsi, mp, 8u); 30U, fsi, mp, 8u);
native_file_ptr nf2; auto ptr = utils::file::file::open_or_create_file(dest_path);
EXPECT_EQ(api_error::success, native_file::create_or_open(dest_path, nf2)); auto &nf2 = *ptr;
EXPECT_TRUE(nf2);
auto to_read = fsi.size; auto to_read = fsi.size;
std::size_t chunk = rb.get_total_chunks() - 1u; std::size_t chunk = rb.get_total_chunks() - 1u;
@ -430,28 +429,31 @@ TEST(ring_buffer_open_file, read_full_file_in_reverse) {
rb.read(test_chunk_size, chunk * test_chunk_size, data)); rb.read(test_chunk_size, chunk * test_chunk_size, data));
std::size_t bytes_written{}; std::size_t bytes_written{};
EXPECT_TRUE(nf2->write_bytes(data.data(), data.size(), EXPECT_TRUE(nf2.write(data, chunk * test_chunk_size, &bytes_written));
chunk * test_chunk_size, bytes_written));
chunk--; chunk--;
to_read -= data.size(); to_read -= data.size();
} }
nf2->close(); nf2.close();
nf->close(); nf.close();
EXPECT_STREQ(utils::file::generate_sha256(download_source_path).c_str(), auto hash1 = utils::file::file(download_source_path).sha256();
utils::file::generate_sha256(dest_path).c_str()); auto hash2 = utils::file::file(dest_path).sha256();
EXPECT_TRUE(hash1.has_value());
EXPECT_TRUE(hash2.has_value());
if (hash1.has_value() && hash2.has_value()) {
EXPECT_STREQ(hash1.value().c_str(), hash2.value().c_str());
}
} }
EXPECT_TRUE(utils::file::delete_directory_recursively(ring_buffer_dir)); EXPECT_TRUE(utils::file::directory(ring_buffer_dir).remove_recursively());
} }
TEST(ring_buffer_open_file, read_full_file_in_partial_chunks) { TEST(ring_buffer_open_file, read_full_file_in_partial_chunks) {
const auto download_source_path = auto &nf = test::create_random_file(test_chunk_size * 32u);
generate_test_file_name("./test_config", "ring_buffer_open_file"); const auto download_source_path = nf.get_path();
auto nf = create_random_file(download_source_path, test_chunk_size * 32u);
const auto dest_path = const auto dest_path = test::generate_test_file_name("test");
generate_test_file_name("./test_config", "ring_buffer_open_file");
mock_provider mp; mock_provider mp;
@ -461,8 +463,7 @@ TEST(ring_buffer_open_file, read_full_file_in_partial_chunks) {
fsi.directory = false; fsi.directory = false;
fsi.api_path = "/test.txt"; fsi.api_path = "/test.txt";
fsi.size = test_chunk_size * 32u; fsi.size = test_chunk_size * 32u;
fsi.source_path = fsi.source_path = test::generate_test_file_name("test");
generate_test_file_name("./test_config", "ring_buffer_open_file");
EXPECT_CALL(mp, read_file_bytes) EXPECT_CALL(mp, read_file_bytes)
.WillRepeatedly([&nf](const std::string & /* api_path */, .WillRepeatedly([&nf](const std::string & /* api_path */,
@ -472,9 +473,8 @@ TEST(ring_buffer_open_file, read_full_file_in_partial_chunks) {
EXPECT_FALSE(stop_requested); EXPECT_FALSE(stop_requested);
std::size_t bytes_read{}; std::size_t bytes_read{};
data.resize(size); data.resize(size);
auto ret = nf->read_bytes(&data[0u], size, offset, bytes_read) auto ret = nf.read(data, offset, &bytes_read) ? api_error::success
? api_error::success : api_error::os_error;
: api_error::os_error;
EXPECT_EQ(bytes_read, data.size()); EXPECT_EQ(bytes_read, data.size());
return ret; return ret;
}); });
@ -482,8 +482,11 @@ TEST(ring_buffer_open_file, read_full_file_in_partial_chunks) {
file_manager::ring_buffer_open_file rb(ring_buffer_dir, test_chunk_size, file_manager::ring_buffer_open_file rb(ring_buffer_dir, test_chunk_size,
30U, fsi, mp, 8u); 30U, fsi, mp, 8u);
native_file_ptr nf2; auto ptr = utils::file::file::open_or_create_file(dest_path);
EXPECT_EQ(api_error::success, native_file::create_or_open(dest_path, nf2)); auto &nf2 = *ptr;
EXPECT_TRUE(nf2);
// EXPECT_EQ(api_error::success, native_file::create_or_open(dest_path,
// nf2));
auto total_read = std::uint64_t(0u); auto total_read = std::uint64_t(0u);
@ -492,27 +495,31 @@ TEST(ring_buffer_open_file, read_full_file_in_partial_chunks) {
EXPECT_EQ(api_error::success, rb.read(3u, total_read, data)); EXPECT_EQ(api_error::success, rb.read(3u, total_read, data));
std::size_t bytes_written{}; std::size_t bytes_written{};
EXPECT_TRUE(nf2->write_bytes(data.data(), data.size(), total_read, EXPECT_TRUE(
bytes_written)); nf2.write(data.data(), data.size(), total_read, &bytes_written));
total_read += data.size(); total_read += data.size();
} }
nf2->close(); nf2.close();
nf->close(); nf.close();
EXPECT_STREQ(utils::file::generate_sha256(download_source_path).c_str(), auto hash1 = utils::file::file(download_source_path).sha256();
utils::file::generate_sha256(dest_path).c_str()); auto hash2 = utils::file::file(dest_path).sha256();
EXPECT_TRUE(hash1.has_value());
EXPECT_TRUE(hash2.has_value());
if (hash1.has_value() && hash2.has_value()) {
EXPECT_STREQ(hash1.value().c_str(), hash2.value().c_str());
}
} }
EXPECT_TRUE(utils::file::delete_directory_recursively(ring_buffer_dir)); EXPECT_TRUE(utils::file::directory(ring_buffer_dir).remove_recursively());
} }
TEST(ring_buffer_open_file, read_full_file_in_partial_chunks_in_reverse) { TEST(ring_buffer_open_file, read_full_file_in_partial_chunks_in_reverse) {
const auto download_source_path = auto &nf = test::create_random_file(test_chunk_size * 32u);
generate_test_file_name("./test_config", "ring_buffer_open_file"); const auto download_source_path = nf.get_path();
auto nf = create_random_file(download_source_path, test_chunk_size * 32u);
const auto dest_path = const auto dest_path = test::generate_test_file_name("ring_buffer_open_file");
generate_test_file_name("./test_config", "ring_buffer_open_file");
mock_provider mp; mock_provider mp;
@ -522,8 +529,7 @@ TEST(ring_buffer_open_file, read_full_file_in_partial_chunks_in_reverse) {
fsi.directory = false; fsi.directory = false;
fsi.api_path = "/test.txt"; fsi.api_path = "/test.txt";
fsi.size = test_chunk_size * 32u; fsi.size = test_chunk_size * 32u;
fsi.source_path = fsi.source_path = test::generate_test_file_name("ring_buffer_open_file");
generate_test_file_name("./test_config", "ring_buffer_open_file");
EXPECT_CALL(mp, read_file_bytes) EXPECT_CALL(mp, read_file_bytes)
.WillRepeatedly([&nf](const std::string & /* api_path */, .WillRepeatedly([&nf](const std::string & /* api_path */,
@ -533,9 +539,8 @@ TEST(ring_buffer_open_file, read_full_file_in_partial_chunks_in_reverse) {
EXPECT_FALSE(stop_requested); EXPECT_FALSE(stop_requested);
std::size_t bytes_read{}; std::size_t bytes_read{};
data.resize(size); data.resize(size);
auto ret = nf->read_bytes(&data[0u], size, offset, bytes_read) auto ret = nf.read(data, offset, &bytes_read) ? api_error::success
? api_error::success : api_error::os_error;
: api_error::os_error;
EXPECT_EQ(bytes_read, data.size()); EXPECT_EQ(bytes_read, data.size());
return ret; return ret;
}); });
@ -543,11 +548,12 @@ TEST(ring_buffer_open_file, read_full_file_in_partial_chunks_in_reverse) {
file_manager::ring_buffer_open_file rb(ring_buffer_dir, test_chunk_size, file_manager::ring_buffer_open_file rb(ring_buffer_dir, test_chunk_size,
30U, fsi, mp, 8u); 30U, fsi, mp, 8u);
native_file_ptr nf2; auto ptr = utils::file::file::open_or_create_file(dest_path);
EXPECT_EQ(api_error::success, native_file::create_or_open(dest_path, nf2)); auto &nf2 = *ptr;
EXPECT_TRUE(nf2);
auto total_read = std::uint64_t(0u); std::uint64_t total_read{0U};
const auto read_size = 3u; const auto read_size{3U};
while (total_read < fsi.size) { while (total_read < fsi.size) {
const auto offset = fsi.size - total_read - read_size; const auto offset = fsi.size - total_read - read_size;
@ -560,18 +566,23 @@ TEST(ring_buffer_open_file, read_full_file_in_partial_chunks_in_reverse) {
(remain >= read_size) ? offset : 0u, data)); (remain >= read_size) ? offset : 0u, data));
std::size_t bytes_written{}; std::size_t bytes_written{};
EXPECT_TRUE(nf2->write_bytes(data.data(), data.size(), EXPECT_TRUE(
(remain >= read_size) ? offset : 0u, nf2.write(data, (remain >= read_size) ? offset : 0u, &bytes_written));
bytes_written));
total_read += data.size(); total_read += data.size();
} }
nf2->close(); nf2.close();
nf->close(); nf.close();
EXPECT_STREQ(utils::file::generate_sha256(download_source_path).c_str(), auto hash1 = utils::file::file(download_source_path).sha256();
utils::file::generate_sha256(dest_path).c_str()); auto hash2 = utils::file::file(dest_path).sha256();
EXPECT_TRUE(hash1.has_value());
EXPECT_TRUE(hash2.has_value());
if (hash1.has_value() && hash2.has_value()) {
EXPECT_STREQ(hash1.value().c_str(), hash2.value().c_str());
}
} }
EXPECT_TRUE(utils::file::delete_directory_recursively(ring_buffer_dir)); EXPECT_TRUE(utils::file::directory(ring_buffer_dir).remove_recursively());
} }
} // namespace repertory } // namespace repertory

View File

@ -34,7 +34,6 @@
#include "utils/encrypting_reader.hpp" #include "utils/encrypting_reader.hpp"
#include "utils/event_capture.hpp" #include "utils/event_capture.hpp"
#include "utils/file_utils.hpp" #include "utils/file_utils.hpp"
#include "utils/native_file.hpp"
#include "utils/path.hpp" #include "utils/path.hpp"
#include "utils/polling.hpp" #include "utils/polling.hpp"
#include "utils/string.hpp" #include "utils/string.hpp"
@ -43,7 +42,7 @@
namespace repertory { namespace repertory {
static std::string file_manager_dir = static std::string file_manager_dir =
utils::path::combine("./test_config", {"file_manager_test"}); utils::path::combine(test::get_test_output_dir(), {"file_manager_test"});
auto file_manager::open(std::shared_ptr<i_closeable_open_file> of, auto file_manager::open(std::shared_ptr<i_closeable_open_file> of,
const open_file_data &ofd, std::uint64_t &handle, const open_file_data &ofd, std::uint64_t &handle,
@ -85,7 +84,7 @@ TEST(file_manager, can_start_and_stop) {
} }
event_system::instance().stop(); event_system::instance().stop();
// EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); // EXPECT_TRUE(utils::file::remove_directory(file_manager_dir, true));
} }
TEST(file_manager, can_create_and_close_file) { TEST(file_manager, can_create_and_close_file) {
@ -118,7 +117,7 @@ TEST(file_manager, can_create_and_close_file) {
{ {
std::shared_ptr<i_open_file> f; std::shared_ptr<i_open_file> f;
const auto now = utils::time::get_file_time_now(); const auto now = utils::time::get_time_now();
auto meta = create_meta_attributes( auto meta = create_meta_attributes(
now, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_ARCHIVE, now + 1u, now, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_ARCHIVE, now + 1u,
now + 2u, false, 1, "key", 2, now + 3u, 3u, 4u, 0u, source_path, 10, now + 2u, false, 1, "key", 2, now + 3u, 3u, 4u, 0u, source_path, 10,
@ -202,7 +201,7 @@ TEST(file_manager, can_create_and_close_file) {
polling::instance().stop(); polling::instance().stop();
event_system::instance().stop(); event_system::instance().stop();
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
} }
TEST(file_manager, can_open_and_close_file) { TEST(file_manager, can_open_and_close_file) {
@ -233,7 +232,7 @@ TEST(file_manager, can_open_and_close_file) {
std::uint64_t handle{}; std::uint64_t handle{};
{ {
const auto now = utils::time::get_file_time_now(); const auto now = utils::time::get_time_now();
auto meta = create_meta_attributes( auto meta = create_meta_attributes(
now, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_ARCHIVE, now + 1u, now, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_ARCHIVE, now + 1u,
now + 2u, false, 1, "key", 2, now + 3u, 3u, 4u, 0u, source_path, 10, now + 2u, false, 1, "key", 2, now + 3u, 3u, 4u, 0u, source_path, 10,
@ -318,7 +317,7 @@ TEST(file_manager, can_open_and_close_file) {
polling::instance().stop(); polling::instance().stop();
event_system::instance().stop(); event_system::instance().stop();
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
} }
TEST(file_manager, can_open_and_close_multiple_handles_for_same_file) { TEST(file_manager, can_open_and_close_multiple_handles_for_same_file) {
@ -340,7 +339,7 @@ TEST(file_manager, can_open_and_close_multiple_handles_for_same_file) {
const auto source_path = utils::path::combine( const auto source_path = utils::path::combine(
cfg.get_cache_directory(), {utils::create_uuid_string()}); cfg.get_cache_directory(), {utils::create_uuid_string()});
const auto now = utils::time::get_file_time_now(); const auto now = utils::time::get_time_now();
auto meta = create_meta_attributes( auto meta = create_meta_attributes(
now, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_ARCHIVE, now + 1u, now, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_ARCHIVE, now + 1u,
now + 2u, false, 1, "key", 2, now + 3u, 3u, 4u, 0u, source_path, 10, now + 2u, false, 1, "key", 2, now + 3u, 3u, 4u, 0u, source_path, 10,
@ -391,7 +390,7 @@ TEST(file_manager, can_open_and_close_multiple_handles_for_same_file) {
polling::instance().stop(); polling::instance().stop();
event_system::instance().stop(); event_system::instance().stop();
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
} }
TEST(file_manager, download_is_stored_after_write_if_partially_downloaded) { TEST(file_manager, download_is_stored_after_write_if_partially_downloaded) {
@ -420,15 +419,14 @@ TEST(file_manager, download_is_stored_after_write_if_partially_downloaded) {
event_capture ec({"download_stored"}, event_capture ec({"download_stored"},
{"file_upload_completed", "file_upload_queued"}); {"file_upload_completed", "file_upload_queued"});
const auto now = utils::time::get_file_time_now(); const auto now = utils::time::get_time_now();
auto meta = create_meta_attributes( auto meta = create_meta_attributes(
now, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_ARCHIVE, now + 1u, now + 2u, now, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_ARCHIVE, now + 1u, now + 2u,
false, 1, "key", 2, now + 3u, 3u, 4u, false, 1, "key", 2, now + 3u, 3u, 4u,
utils::encryption::encrypting_reader::get_data_chunk_size() * 4u, utils::encryption::encrypting_reader::get_data_chunk_size() * 4u,
source_path, 10, now + 4u); source_path, 10, now + 4u);
auto nf = create_random_file( auto &nf =
generate_test_file_name("./test_config", "file_manage_test"), test::create_random_file(utils::string::to_uint64(meta[META_SIZE]));
utils::string::to_uint64(meta[META_SIZE]));
EXPECT_CALL(mp, get_filesystem_item) EXPECT_CALL(mp, get_filesystem_item)
.WillRepeatedly([&meta](const std::string &api_path, bool directory, .WillRepeatedly([&meta](const std::string &api_path, bool directory,
@ -465,9 +463,8 @@ TEST(file_manager, download_is_stored_after_write_if_partially_downloaded) {
if (offset == 0u) { if (offset == 0u) {
std::size_t bytes_read{}; std::size_t bytes_read{};
data.resize(size); data.resize(size);
auto ret = nf->read_bytes(&data[0u], size, offset, bytes_read) auto ret = nf.read(data, offset, &bytes_read) ? api_error::success
? api_error::success : api_error::os_error;
: api_error::os_error;
EXPECT_EQ(bytes_read, data.size()); EXPECT_EQ(bytes_read, data.size());
return ret; return ret;
} }
@ -542,11 +539,11 @@ TEST(file_manager, download_is_stored_after_write_if_partially_downloaded) {
EXPECT_EQ(std::size_t(0u), fm.get_open_file_count()); EXPECT_EQ(std::size_t(0u), fm.get_open_file_count());
EXPECT_EQ(std::size_t(0u), fm.get_open_handle_count()); EXPECT_EQ(std::size_t(0u), fm.get_open_handle_count());
nf->close(); nf.close();
} }
event_system::instance().stop(); event_system::instance().stop();
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
} }
TEST(file_manager, upload_occurs_after_write_if_fully_downloaded) { TEST(file_manager, upload_occurs_after_write_if_fully_downloaded) {
@ -583,15 +580,14 @@ TEST(file_manager, upload_occurs_after_write_if_fully_downloaded) {
}); });
event_capture ec({"download_end"}); event_capture ec({"download_end"});
const auto now = utils::time::get_file_time_now(); const auto now = utils::time::get_time_now();
auto meta = create_meta_attributes( auto meta = create_meta_attributes(
now, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_ARCHIVE, now + 1u, now + 2u, now, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_ARCHIVE, now + 1u, now + 2u,
false, 1, "key", 2, now + 3u, 3u, 4u, false, 1, "key", 2, now + 3u, 3u, 4u,
utils::encryption::encrypting_reader::get_data_chunk_size() * 4u, utils::encryption::encrypting_reader::get_data_chunk_size() * 4u,
source_path, 10, now + 4u); source_path, 10, now + 4u);
auto nf = create_random_file( auto &nf =
generate_test_file_name("./test_config", "file_manage_test"), test::create_random_file(utils::string::to_uint64(meta[META_SIZE]));
utils::string::to_uint64(meta[META_SIZE]));
EXPECT_CALL(mp, get_filesystem_item) EXPECT_CALL(mp, get_filesystem_item)
.WillRepeatedly([&meta](const std::string &api_path, bool directory, .WillRepeatedly([&meta](const std::string &api_path, bool directory,
@ -623,9 +619,8 @@ TEST(file_manager, upload_occurs_after_write_if_fully_downloaded) {
stop_type & /* stop_requested */) -> api_error { stop_type & /* stop_requested */) -> api_error {
std::size_t bytes_read{}; std::size_t bytes_read{};
data.resize(size); data.resize(size);
auto ret = nf->read_bytes(&data[0u], size, offset, bytes_read) auto ret = nf.read(data, offset, &bytes_read) ? api_error::success
? api_error::success : api_error::os_error;
: api_error::os_error;
EXPECT_EQ(bytes_read, data.size()); EXPECT_EQ(bytes_read, data.size());
return ret; return ret;
}); });
@ -660,16 +655,16 @@ TEST(file_manager, upload_occurs_after_write_if_fully_downloaded) {
fm.stop(); fm.stop();
nf->close(); nf.close();
} }
polling::instance().stop(); polling::instance().stop();
event_system::instance().stop(); event_system::instance().stop();
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
} }
TEST(file_manager, can_evict_file) { TEST(file_manager, can_evict_file) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{ {
console_consumer c; console_consumer c;
event_system::instance().start(); event_system::instance().start();
@ -694,7 +689,7 @@ TEST(file_manager, can_evict_file) {
const auto source_path = utils::path::combine( const auto source_path = utils::path::combine(
cfg.get_cache_directory(), {utils::create_uuid_string()}); cfg.get_cache_directory(), {utils::create_uuid_string()});
const auto now = utils::time::get_file_time_now(); const auto now = utils::time::get_time_now();
auto meta = create_meta_attributes( auto meta = create_meta_attributes(
now, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_ARCHIVE, now + 1u, now + 2u, now, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_ARCHIVE, now + 1u, now + 2u,
@ -735,15 +730,15 @@ TEST(file_manager, can_evict_file) {
std::size_t bytes_written{}; std::size_t bytes_written{};
EXPECT_EQ(api_error::success, f->write(0U, data, bytes_written)); EXPECT_EQ(api_error::success, f->write(0U, data, bytes_written));
std::uint64_t file_size{}; auto opt_size = utils::file::file{source_path}.size();
EXPECT_TRUE(utils::file::get_file_size(source_path, file_size)); EXPECT_TRUE(opt_size.has_value());
EXPECT_EQ(static_cast<std::uint64_t>(data.size()), file_size); EXPECT_EQ(static_cast<std::uint64_t>(data.size()), opt_size.value());
} }
fm.close(handle); fm.close(handle);
capture.wait_for_empty(); capture.wait_for_empty();
EXPECT_TRUE(utils::retryable_action( EXPECT_TRUE(utils::retry_action(
[&fm]() -> bool { return not fm.is_processing("/test_evict.txt"); })); [&fm]() -> bool { return not fm.is_processing("/test_evict.txt"); }));
EXPECT_CALL(mp, get_item_meta(_, META_SOURCE, _)) EXPECT_CALL(mp, get_item_meta(_, META_SOURCE, _))
@ -764,17 +759,17 @@ TEST(file_manager, can_evict_file) {
return api_error::success; return api_error::success;
}); });
EXPECT_TRUE(fm.evict_file("/test_evict.txt")); EXPECT_TRUE(fm.evict_file("/test_evict.txt"));
EXPECT_FALSE(utils::file::is_file(source_path)); EXPECT_FALSE(utils::file::file(source_path).exists());
fm.stop(); fm.stop();
} }
event_system::instance().stop(); event_system::instance().stop();
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
} }
TEST(file_manager, evict_file_fails_if_file_is_pinned) { TEST(file_manager, evict_file_fails_if_file_is_pinned) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{ {
app_config cfg(provider_type::sia, file_manager_dir); app_config cfg(provider_type::sia, file_manager_dir);
cfg.set_enable_chunk_downloader_timeout(false); cfg.set_enable_chunk_downloader_timeout(false);
@ -796,11 +791,11 @@ TEST(file_manager, evict_file_fails_if_file_is_pinned) {
} }
event_system::instance().stop(); event_system::instance().stop();
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
} }
TEST(file_manager, evict_file_fails_if_provider_is_direct_only) { TEST(file_manager, evict_file_fails_if_provider_is_direct_only) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{ {
app_config cfg(provider_type::sia, file_manager_dir); app_config cfg(provider_type::sia, file_manager_dir);
@ -812,11 +807,11 @@ TEST(file_manager, evict_file_fails_if_provider_is_direct_only) {
EXPECT_FALSE(fm.evict_file("/test.txt")); EXPECT_FALSE(fm.evict_file("/test.txt"));
} }
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
} }
TEST(file_manager, evict_file_fails_if_file_is_open) { TEST(file_manager, evict_file_fails_if_file_is_open) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{ {
app_config cfg(provider_type::sia, file_manager_dir); app_config cfg(provider_type::sia, file_manager_dir);
@ -862,12 +857,12 @@ TEST(file_manager, evict_file_fails_if_file_is_open) {
fm.close(handle); fm.close(handle);
} }
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
} }
TEST(file_manager, TEST(file_manager,
evict_file_fails_if_unable_to_get_source_path_from_item_meta) { evict_file_fails_if_unable_to_get_source_path_from_item_meta) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{ {
app_config cfg(provider_type::sia, file_manager_dir); app_config cfg(provider_type::sia, file_manager_dir);
@ -897,11 +892,11 @@ TEST(file_manager,
EXPECT_FALSE(fm.evict_file("/test_open.txt")); EXPECT_FALSE(fm.evict_file("/test_open.txt"));
} }
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
} }
TEST(file_manager, evict_file_fails_if_source_path_is_empty) { TEST(file_manager, evict_file_fails_if_source_path_is_empty) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{ {
app_config cfg(provider_type::sia, file_manager_dir); app_config cfg(provider_type::sia, file_manager_dir);
@ -931,11 +926,11 @@ TEST(file_manager, evict_file_fails_if_source_path_is_empty) {
EXPECT_FALSE(fm.evict_file("/test_open.txt")); EXPECT_FALSE(fm.evict_file("/test_open.txt"));
} }
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
} }
TEST(file_manager, evict_file_fails_if_file_is_uploading) { TEST(file_manager, evict_file_fails_if_file_is_uploading) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{ {
console_consumer c; console_consumer c;
event_system::instance().start(); event_system::instance().start();
@ -960,7 +955,7 @@ TEST(file_manager, evict_file_fails_if_file_is_uploading) {
const auto source_path = utils::path::combine( const auto source_path = utils::path::combine(
cfg.get_cache_directory(), {utils::create_uuid_string()}); cfg.get_cache_directory(), {utils::create_uuid_string()});
const auto now = utils::time::get_file_time_now(); const auto now = utils::time::get_time_now();
auto meta = create_meta_attributes( auto meta = create_meta_attributes(
now, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_ARCHIVE, now + 1u, now + 2u, now, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_ARCHIVE, now + 1u, now + 2u,
@ -1008,29 +1003,30 @@ TEST(file_manager, evict_file_fails_if_file_is_uploading) {
std::size_t bytes_written{}; std::size_t bytes_written{};
EXPECT_EQ(api_error::success, f->write(0U, data, bytes_written)); EXPECT_EQ(api_error::success, f->write(0U, data, bytes_written));
std::uint64_t file_size{}; auto opt_size = utils::file::file{source_path}.size();
EXPECT_TRUE(utils::file::get_file_size(source_path, file_size)); EXPECT_TRUE(opt_size.has_value());
EXPECT_EQ(static_cast<std::uint64_t>(data.size()), file_size); EXPECT_EQ(static_cast<std::uint64_t>(data.size()), opt_size.value());
fm.close(handle); fm.close(handle);
EXPECT_TRUE(utils::retryable_action( EXPECT_TRUE(utils::retry_action(
[&fm]() -> bool { return fm.is_processing("/test_evict.txt"); })); [&fm]() -> bool { return fm.is_processing("/test_evict.txt"); }));
EXPECT_FALSE(fm.evict_file("/test_evict.txt")); EXPECT_FALSE(fm.evict_file("/test_evict.txt"));
} }
capture.wait_for_empty(); capture.wait_for_empty();
EXPECT_TRUE(utils::file::is_file(source_path)); EXPECT_TRUE(utils::file::file(source_path).exists());
fm.stop(); fm.stop();
} }
event_system::instance().stop(); event_system::instance().stop();
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
} }
TEST(file_manager, evict_file_fails_if_file_is_in_upload_queue) { TEST(file_manager, evict_file_fails_if_file_is_in_upload_queue) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{ {
app_config cfg(provider_type::sia, file_manager_dir); app_config cfg(provider_type::sia, file_manager_dir);
@ -1051,11 +1047,11 @@ TEST(file_manager, evict_file_fails_if_file_is_in_upload_queue) {
EXPECT_FALSE(fm.evict_file("/test_evict.txt")); EXPECT_FALSE(fm.evict_file("/test_evict.txt"));
} }
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
} }
TEST(file_manager, evict_file_fails_if_file_is_modified) { TEST(file_manager, evict_file_fails_if_file_is_modified) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{ {
app_config cfg(provider_type::sia, file_manager_dir); app_config cfg(provider_type::sia, file_manager_dir);
@ -1097,11 +1093,11 @@ TEST(file_manager, evict_file_fails_if_file_is_modified) {
EXPECT_FALSE(fm.evict_file("/test_evict.txt")); EXPECT_FALSE(fm.evict_file("/test_evict.txt"));
} }
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
} }
TEST(file_manager, evict_file_fails_if_file_is_not_complete) { TEST(file_manager, evict_file_fails_if_file_is_not_complete) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{ {
app_config cfg(provider_type::sia, file_manager_dir); app_config cfg(provider_type::sia, file_manager_dir);
@ -1145,11 +1141,11 @@ TEST(file_manager, evict_file_fails_if_file_is_not_complete) {
EXPECT_FALSE(fm.evict_file("/test_evict.txt")); EXPECT_FALSE(fm.evict_file("/test_evict.txt"));
} }
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
} }
TEST(file_manager, can_get_directory_items) { TEST(file_manager, can_get_directory_items) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{ {
app_config cfg(provider_type::sia, file_manager_dir); app_config cfg(provider_type::sia, file_manager_dir);
@ -1179,11 +1175,11 @@ TEST(file_manager, can_get_directory_items) {
EXPECT_EQ(std::size_t(2U), list.size()); EXPECT_EQ(std::size_t(2U), list.size());
} }
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
} }
TEST(file_manager, file_is_not_opened_if_provider_create_file_fails) { TEST(file_manager, file_is_not_opened_if_provider_create_file_fails) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{ {
app_config cfg(provider_type::sia, file_manager_dir); app_config cfg(provider_type::sia, file_manager_dir);
@ -1192,7 +1188,7 @@ TEST(file_manager, file_is_not_opened_if_provider_create_file_fails) {
EXPECT_CALL(mp, is_direct_only()).WillRepeatedly(Return(false)); EXPECT_CALL(mp, is_direct_only()).WillRepeatedly(Return(false));
const auto now = utils::time::get_file_time_now(); const auto now = utils::time::get_time_now();
auto meta = create_meta_attributes( auto meta = create_meta_attributes(
now, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_ARCHIVE, now + 1u, now + 2u, now, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_ARCHIVE, now + 1u, now + 2u,
false, 1, "", 2, now + 3u, 3u, 4u, 0u, "/test_create.src", 10, false, 1, "", 2, now + 3u, 3u, 4u, 0u, "/test_create.src", 10,
@ -1215,11 +1211,11 @@ TEST(file_manager, file_is_not_opened_if_provider_create_file_fails) {
EXPECT_EQ(std::size_t(0U), fm.get_open_file_count()); EXPECT_EQ(std::size_t(0U), fm.get_open_file_count());
} }
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
} }
TEST(file_manager, create_fails_if_provider_create_is_unsuccessful) { TEST(file_manager, create_fails_if_provider_create_is_unsuccessful) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{ {
app_config cfg(provider_type::sia, file_manager_dir); app_config cfg(provider_type::sia, file_manager_dir);
@ -1246,12 +1242,12 @@ TEST(file_manager, create_fails_if_provider_create_is_unsuccessful) {
EXPECT_EQ(std::size_t(0U), fm.get_open_file_count()); EXPECT_EQ(std::size_t(0U), fm.get_open_file_count());
} }
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
} }
TEST(file_manager, get_open_file_fails_if_file_is_not_open) { TEST(file_manager, get_open_file_fails_if_file_is_not_open) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{ {
app_config cfg(provider_type::sia, file_manager_dir); app_config cfg(provider_type::sia, file_manager_dir);
@ -1270,12 +1266,12 @@ TEST(file_manager, get_open_file_fails_if_file_is_not_open) {
EXPECT_FALSE(f); EXPECT_FALSE(f);
} }
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
} }
TEST(file_manager, TEST(file_manager,
get_open_file_promotes_non_writeable_file_if_writeable_is_specified) { get_open_file_promotes_non_writeable_file_if_writeable_is_specified) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{ {
app_config cfg(provider_type::sia, file_manager_dir); app_config cfg(provider_type::sia, file_manager_dir);
@ -1355,11 +1351,11 @@ TEST(file_manager,
EXPECT_EQ(std::size_t(1U), fm.get_open_file_count()); EXPECT_EQ(std::size_t(1U), fm.get_open_file_count());
} }
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
} }
TEST(file_manager, open_file_fails_if_file_is_not_found) { TEST(file_manager, open_file_fails_if_file_is_not_found) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{ {
app_config cfg(provider_type::sia, file_manager_dir); app_config cfg(provider_type::sia, file_manager_dir);
@ -1380,11 +1376,11 @@ TEST(file_manager, open_file_fails_if_file_is_not_found) {
EXPECT_EQ(std::size_t(0U), fm.get_open_file_count()); EXPECT_EQ(std::size_t(0U), fm.get_open_file_count());
} }
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
} }
TEST(file_manager, open_file_fails_if_provider_get_filesystem_item_fails) { TEST(file_manager, open_file_fails_if_provider_get_filesystem_item_fails) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{ {
app_config cfg(provider_type::sia, file_manager_dir); app_config cfg(provider_type::sia, file_manager_dir);
@ -1424,11 +1420,11 @@ TEST(file_manager, open_file_fails_if_provider_get_filesystem_item_fails) {
EXPECT_EQ(std::size_t(0U), fm.get_open_file_count()); EXPECT_EQ(std::size_t(0U), fm.get_open_file_count());
} }
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
} }
TEST(file_manager, open_file_fails_if_provider_set_item_meta_fails) { TEST(file_manager, open_file_fails_if_provider_set_item_meta_fails) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{ {
app_config cfg(provider_type::sia, file_manager_dir); app_config cfg(provider_type::sia, file_manager_dir);
@ -1475,11 +1471,11 @@ TEST(file_manager, open_file_fails_if_provider_set_item_meta_fails) {
EXPECT_EQ(std::size_t(0U), fm.get_open_file_count()); EXPECT_EQ(std::size_t(0U), fm.get_open_file_count());
} }
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
} }
TEST(file_manager, open_file_creates_source_path_if_empty) { TEST(file_manager, open_file_creates_source_path_if_empty) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{ {
app_config cfg(provider_type::sia, file_manager_dir); app_config cfg(provider_type::sia, file_manager_dir);
@ -1538,11 +1534,11 @@ TEST(file_manager, open_file_creates_source_path_if_empty) {
EXPECT_EQ(std::size_t(1U), fm.get_open_file_count()); EXPECT_EQ(std::size_t(1U), fm.get_open_file_count());
} }
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
} }
TEST(file_manager, open_file_first_file_handle_is_not_zero) { TEST(file_manager, open_file_first_file_handle_is_not_zero) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{ {
app_config cfg(provider_type::sia, file_manager_dir); app_config cfg(provider_type::sia, file_manager_dir);
@ -1586,11 +1582,11 @@ TEST(file_manager, open_file_first_file_handle_is_not_zero) {
EXPECT_GT(handle, std::uint64_t(0U)); EXPECT_GT(handle, std::uint64_t(0U));
} }
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
} }
TEST(file_manager, can_remove_file) { TEST(file_manager, can_remove_file) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{ {
app_config cfg(provider_type::sia, file_manager_dir); app_config cfg(provider_type::sia, file_manager_dir);
@ -1601,11 +1597,11 @@ TEST(file_manager, can_remove_file) {
file_manager fm(cfg, mp); file_manager fm(cfg, mp);
native_file::native_file_ptr f{}; {
EXPECT_EQ(api_error::success, auto file = utils::file::file::open_or_create_file("./test_remove.txt");
native_file::create_or_open("./test_remove.txt", f)); EXPECT_TRUE(*file);
f->close(); }
EXPECT_TRUE(utils::file::is_file("./test_remove.txt")); EXPECT_TRUE(utils::file::file("./test_remove.txt").exists());
EXPECT_CALL(mp, get_filesystem_item) EXPECT_CALL(mp, get_filesystem_item)
.WillOnce([](const std::string &api_path, bool directory, .WillOnce([](const std::string &api_path, bool directory,
@ -1624,14 +1620,14 @@ TEST(file_manager, can_remove_file) {
EXPECT_EQ(api_error::success, fm.remove_file("/test_remove.txt")); EXPECT_EQ(api_error::success, fm.remove_file("/test_remove.txt"));
EXPECT_FALSE(utils::file::is_file("./test_remove.txt")); EXPECT_FALSE(utils::file::file("./test_remove.txt").exists());
} }
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
} }
TEST(file_manager, can_queue_and_remove_upload) { TEST(file_manager, can_queue_and_remove_upload) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
console_consumer c; console_consumer c;
event_system::instance().start(); event_system::instance().start();
@ -1662,11 +1658,11 @@ TEST(file_manager, can_queue_and_remove_upload) {
} }
event_system::instance().stop(); event_system::instance().stop();
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
} }
TEST(file_manager, remove_file_fails_if_open_file_is_modified) { TEST(file_manager, remove_file_fails_if_open_file_is_modified) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{ {
app_config cfg(provider_type::sia, file_manager_dir); app_config cfg(provider_type::sia, file_manager_dir);
@ -1716,7 +1712,7 @@ TEST(file_manager, remove_file_fails_if_open_file_is_modified) {
EXPECT_EQ(api_error::file_in_use, fm.remove_file("/test_remove.txt")); EXPECT_EQ(api_error::file_in_use, fm.remove_file("/test_remove.txt"));
} }
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
} }
TEST(file_manager, file_is_closed_after_download_timeout) { TEST(file_manager, file_is_closed_after_download_timeout) {
@ -1744,7 +1740,7 @@ TEST(file_manager, file_is_closed_after_download_timeout) {
ee.get_api_path().get<std::string>().c_str()); ee.get_api_path().get<std::string>().c_str());
}); });
const auto now = utils::time::get_file_time_now(); const auto now = utils::time::get_time_now();
auto meta = create_meta_attributes( auto meta = create_meta_attributes(
now, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_ARCHIVE, now + 1u, now + 2u, now, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_ARCHIVE, now + 1u, now + 2u,
false, 1, "key", 2, now + 3u, 3u, 4u, false, 1, "key", 2, now + 3u, 3u, 4u,
@ -1814,11 +1810,11 @@ TEST(file_manager, file_is_closed_after_download_timeout) {
} }
event_system::instance().stop(); event_system::instance().stop();
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
} }
TEST(file_manager, remove_file_fails_if_file_does_not_exist) { TEST(file_manager, remove_file_fails_if_file_does_not_exist) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{ {
app_config cfg(provider_type::sia, file_manager_dir); app_config cfg(provider_type::sia, file_manager_dir);
cfg.set_enable_chunk_downloader_timeout(false); cfg.set_enable_chunk_downloader_timeout(false);
@ -1839,11 +1835,11 @@ TEST(file_manager, remove_file_fails_if_file_does_not_exist) {
EXPECT_EQ(api_error::item_not_found, fm.remove_file("/test_remove.txt")); EXPECT_EQ(api_error::item_not_found, fm.remove_file("/test_remove.txt"));
} }
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
} }
TEST(file_manager, remove_file_fails_if_provider_remove_file_fails) { TEST(file_manager, remove_file_fails_if_provider_remove_file_fails) {
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
{ {
app_config cfg(provider_type::sia, file_manager_dir); app_config cfg(provider_type::sia, file_manager_dir);
@ -1871,6 +1867,6 @@ TEST(file_manager, remove_file_fails_if_provider_remove_file_fails) {
EXPECT_EQ(api_error::item_not_found, fm.remove_file("/test_remove.txt")); EXPECT_EQ(api_error::item_not_found, fm.remove_file("/test_remove.txt"));
} }
EXPECT_TRUE(utils::file::delete_directory_recursively(file_manager_dir)); EXPECT_TRUE(utils::file::directory(file_manager_dir).remove_recursively());
} }
} // namespace repertory } // namespace repertory

View File

@ -35,8 +35,7 @@ TEST(upload, can_upload_a_valid_file) {
event_system::instance().start(); event_system::instance().start();
const auto source_path = const auto source_path = test::generate_test_file_name("upload_test");
generate_test_file_name("./test_config", "upload_test");
mock_provider mp; mock_provider mp;
@ -79,8 +78,7 @@ TEST(upload, can_cancel_upload) {
event_system::instance().start(); event_system::instance().start();
const auto source_path = const auto source_path = test::generate_test_file_name("upload_test");
generate_test_file_name("./test_config", "upload_test");
mock_provider mp; mock_provider mp;
@ -145,8 +143,7 @@ TEST(upload, can_stop_upload) {
event_system::instance().start(); event_system::instance().start();
const auto source_path = const auto source_path = test::generate_test_file_name("upload_test");
generate_test_file_name("./test_config", "upload_test");
mock_provider mp; mock_provider mp;

File diff suppressed because it is too large Load Diff

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