Compare commits
107 Commits
master
...
v2.0.6-rel
Author | SHA1 | Date | |
---|---|---|---|
4e418c8969 | |||
d664c6a884 | |||
430fc1a651 | |||
314ee5b664 | |||
9eb8b5e682 | |||
bd386314a4 | |||
aee2413440 | |||
307fcb3332 | |||
28fefca765 | |||
3e09adaba3 | |||
e01ed2c1b8 | |||
ece42df528 | |||
45080aa32f | |||
fb9c8c8bb6 | |||
7a3ce13db0 | |||
6945a16f78 | |||
1153598c62 | |||
2afa403c8c | |||
d09210d9c4 | |||
2ca2002423 | |||
011d32f9cf | |||
7487caca2a | |||
f921295dbd | |||
13b2ee6f7a | |||
144baf4371 | |||
c6ade2e5f7 | |||
fb89cc08ae | |||
f08870b03c | |||
711e3f73cf | |||
ebb620fdb2 | |||
fbf9c85d48 | |||
d5e0252ed3 | |||
06b79ffd2d | |||
690902b31d | |||
0bfe1e1ccd | |||
a8723a6b02 | |||
1d88d26d0a | |||
757c880616 | |||
d65bd6af35 | |||
b285478cc5 | |||
31cd5acaee | |||
65036f2957 | |||
2362300bba | |||
f61f3d5fa4 | |||
a2b8998f4a | |||
a4d53c1011 | |||
4b925c15c2 | |||
bbd82e3f0f | |||
37f2cbc78d | |||
1ad3704fa0 | |||
a6e70d93cb | |||
967324a368 | |||
69b31bfde8 | |||
8b4724a9c1 | |||
6a0d50bc66 | |||
69910bef4c | |||
8c298c84c5 | |||
47dea2cc38 | |||
d8b476e80a | |||
c86c6e2ec6 | |||
c397497eb7 | |||
f8803dfbf0 | |||
5d5cacc482 | |||
3ce4210d56 | |||
d109344544 | |||
ff746a7bec | |||
a613ec77ff | |||
00d3dd95a8 | |||
28d1789f04 | |||
0603463885 | |||
88398485e1 | |||
908e75c696 | |||
dab8c61f87 | |||
e0cf58b01e | |||
281d3758e0 | |||
dfa170022a | |||
52c2780283 | |||
c2dbfc970a | |||
6f9b1f8f08 | |||
078d603be9 | |||
983e47103b | |||
8d2024d34b | |||
4f2ee2ad99 | |||
533938bcef | |||
98edf33be4 | |||
a080c9ff86 | |||
e6cdcd74a1 | |||
573ae549be | |||
fca149f998 | |||
76e375c488 | |||
3f9322f659 | |||
c286d496c3 | |||
56ba0fcb83 | |||
dcafb104ea | |||
ab757dfd36 | |||
eec2d2e9a9 | |||
8c1c91e02b | |||
bb85015733 | |||
883de836c6 | |||
bf2bdd1b5d | |||
f1e82d8f9f | |||
f5c4aebdac | |||
f2f9e8fd15 | |||
2a673915af | |||
df3db38ae7 | |||
b0b69c6dd4 | |||
11b118a30f |
@ -1,36 +0,0 @@
|
|||||||
{
|
|
||||||
"configurations": {
|
|
||||||
"UnixDebug": {
|
|
||||||
"adapter": "vscode-cpptools",
|
|
||||||
"configuration": {
|
|
||||||
"request": "launch",
|
|
||||||
"program": "${workspaceRoot}/build/debug/repertory",
|
|
||||||
"args": ["-f", "/home/sgraves/mnt"],
|
|
||||||
"cwd": "${workspaceRoot}/build/debug",
|
|
||||||
"environment": [],
|
|
||||||
"externalConsole": true,
|
|
||||||
"MIMode": "gdb",
|
|
||||||
"stopAtEntry": true,
|
|
||||||
"logging": {
|
|
||||||
"engineLogging": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"UnixDebugTest": {
|
|
||||||
"adapter": "vscode-cpptools",
|
|
||||||
"configuration": {
|
|
||||||
"request": "launch",
|
|
||||||
"program": "${workspaceRoot}/build/debug/unittests",
|
|
||||||
"args": ["--gtest_filter=file_manager.can_close_after_download_timeout"],
|
|
||||||
"cwd": "${workspaceRoot}/build",
|
|
||||||
"environment": [],
|
|
||||||
"externalConsole": true,
|
|
||||||
"MIMode": "gdb",
|
|
||||||
"stopAtEntry": true,
|
|
||||||
"logging": {
|
|
||||||
"engineLogging": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
24
CHANGELOG.md
24
CHANGELOG.md
@ -1,7 +1,30 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## v2.0.6-release
|
||||||
|
|
||||||
|
### Issues
|
||||||
|
|
||||||
|
* ~~\#12 [Unit Test] Complete all providers unit tests~~
|
||||||
|
* ~~\#21 [Unit Test] Complete WinFSP unit tests~~
|
||||||
|
* ~~\#22 [Unit Test] Complete FUSE unit tests~~
|
||||||
|
* ~~\#33 Complete initial v2.0 documentation~~
|
||||||
|
* \#42 [bug] Remote mount directory listing on Windows connected to Linux is failing
|
||||||
|
* \#43 [bug] Directories are not importing properly for Sia
|
||||||
|
* \#44 [bug] Windows-to-Linux remote mount ignores `CREATE_NEW`
|
||||||
|
* \#45 [bug] Windows-to-Linux remote mount is not handling attempts to remove a non-empty directory properly
|
||||||
|
* \#46 [bug] Changes to maximum cache size should be updated live
|
||||||
|
* \#47 [bug] Windows-to-Linux remote mount is allowing directory rename when directory is not empty
|
||||||
|
* \#48 [bug] Windows-to-Linux remote mount overlapped I/O is not detecting EOF for read operations
|
||||||
|
|
||||||
|
### Changes from v2.0.5-rc
|
||||||
|
|
||||||
|
* Drive letters in UI should always be lowercase
|
||||||
|
* Fixed WinFSP directory rename for non-empty directories
|
||||||
|
* Migrated to v2 error handling
|
||||||
|
|
||||||
## v2.0.5-rc
|
## v2.0.5-rc
|
||||||
|
|
||||||
|
<!-- markdownlint-disable-next-line -->
|
||||||
### Issues
|
### Issues
|
||||||
|
|
||||||
* \#39 Create management portal in Flutter
|
* \#39 Create management portal in Flutter
|
||||||
@ -69,6 +92,7 @@
|
|||||||
|
|
||||||
## v2.0.2-rc
|
## v2.0.2-rc
|
||||||
|
|
||||||
|
<!-- markdownlint-disable-next-line -->
|
||||||
### BREAKING CHANGES
|
### BREAKING CHANGES
|
||||||
|
|
||||||
* Refactored `config.json` - will need to verify configuration settings prior to mounting
|
* Refactored `config.json` - will need to verify configuration settings prior to mounting
|
||||||
|
@ -1,20 +1,20 @@
|
|||||||
set(BINUTILS_HASH b53606f443ac8f01d1d5fc9c39497f2af322d99e14cea5c0b4b124d630379365)
|
set(BINUTILS_HASH ce2017e059d63e67ddb9240e9d4ec49c2893605035cd60e92ad53177f4377237)
|
||||||
set(BOOST2_HASH 7bd7ddceec1a1dfdcbdb3e609b60d01739c38390a5f956385a12f3122049f0ca)
|
set(BOOST2_HASH 7bd7ddceec1a1dfdcbdb3e609b60d01739c38390a5f956385a12f3122049f0ca)
|
||||||
set(BOOST_HASH f55c340aa49763b1925ccf02b2e83f35fdcf634c9d5164a2acb87540173c741d)
|
set(BOOST_HASH 3621533e820dcab1e8012afd583c0c73cf0f77694952b81352bf38c1488f9cb4)
|
||||||
set(CPP_HTTPLIB_HASH c9b9e0524666e1cd088f0874c57c1ce7c0eaa8552f9f4e15c755d5201fc8c608)
|
set(CPP_HTTPLIB_HASH 18064587e0cc6a0d5d56d619f4cbbcaba47aa5d84d86013abbd45d95c6653866)
|
||||||
set(CURL_HASH 6edc063d1ebaf9cf3b3b46e9fef2f3cd8932694989ecd43d005d6e828426d09f)
|
set(CURL_HASH ccc5ba45d9f5320c70ffb24e5411b66ba55ea1f333bf78be0963ed90a9328699)
|
||||||
set(EXPAT_HASH 372b18f6527d162fa9658f1c74d22a37429b82d822f5a1e1fc7e00f6045a06a2)
|
set(EXPAT_HASH 85372797ff0673a8fc4a6be16466bb5a0ca28c0dcf3c6f7ac1686b4a3ba2aabb)
|
||||||
set(GCC_HASH 7d376d445f93126dc545e2c0086d0f647c3094aae081cdb78f42ce2bc25e7293)
|
set(GCC_HASH 7d376d445f93126dc545e2c0086d0f647c3094aae081cdb78f42ce2bc25e7293)
|
||||||
set(GTEST_HASH 78c676fc63881529bf97bf9d45948d905a66833fbfa5318ea2cd7478cb98f399)
|
set(GTEST_HASH 78c676fc63881529bf97bf9d45948d905a66833fbfa5318ea2cd7478cb98f399)
|
||||||
set(ICU_HASH a2c443404f00098e9e90acf29dc318e049d2dc78d9ae5f46efb261934a730ce2)
|
set(ICU_HASH a2c443404f00098e9e90acf29dc318e049d2dc78d9ae5f46efb261934a730ce2)
|
||||||
set(JSON_HASH 0d8ef5af7f9794e3263480193c491549b2ba6cc74bb018906202ada498a79406)
|
set(JSON_HASH 4b92eb0c06d10683f7447ce9406cb97cd4b453be18d7279320f7b2f025c10187)
|
||||||
set(LIBSODIUM_HASH 8e5aeca07a723a27bbecc3beef14b0068d37e7fc0e97f51b3f1c82d2a58005c1)
|
set(LIBSODIUM_HASH 8e5aeca07a723a27bbecc3beef14b0068d37e7fc0e97f51b3f1c82d2a58005c1)
|
||||||
set(MINGW_HASH cc41898aac4b6e8dd5cffd7331b9d9515b912df4420a3a612b5ea2955bbeed2f)
|
set(MINGW_HASH cc41898aac4b6e8dd5cffd7331b9d9515b912df4420a3a612b5ea2955bbeed2f)
|
||||||
set(OPENSSL_HASH 002a2d6b30b58bf4bea46c43bdd96365aaf8daa6c428782aa4feee06da197df3)
|
set(OPENSSL_HASH 344d0a79f1a9b08029b0744e2cc401a43f9c90acd1044d09a530b4885a8e9fc0)
|
||||||
set(PKG_CONFIG_HASH 6fc69c01688c9458a57eb9a1664c9aba372ccda420a02bf4429fe610e7e7d591)
|
set(PKG_CONFIG_HASH 6fc69c01688c9458a57eb9a1664c9aba372ccda420a02bf4429fe610e7e7d591)
|
||||||
set(PUGIXML_HASH 655ade57fa703fb421c2eb9a0113b5064bddb145d415dd1f88c79353d90d511a)
|
set(PUGIXML_HASH 655ade57fa703fb421c2eb9a0113b5064bddb145d415dd1f88c79353d90d511a)
|
||||||
set(ROCKSDB_HASH fdccab16133c9d927a183c2648bcea8d956fb41eb1df2aacaa73eb0b95e43724)
|
set(ROCKSDB_HASH 3fdc9ca996971c4c039959866382c4a3a6c8ade4abf888f3b2ff77153e07bf28)
|
||||||
set(SPDLOG_HASH 25c843860f039a1600f232c6eb9e01e6627f7d030a2ae5e232bdd3c9205d26cc)
|
set(SPDLOG_HASH 7a80896357f3e8e920e85e92633b14ba0f229c506e6f978578bdc35ba09e9a5d)
|
||||||
set(SQLITE_HASH 6cebd1d8403fc58c30e93939b246f3e6e58d0765a5cd50546f16c00fd805d2c3)
|
set(SQLITE_HASH 6cebd1d8403fc58c30e93939b246f3e6e58d0765a5cd50546f16c00fd805d2c3)
|
||||||
set(STDUUID_HASH b1176597e789531c38481acbbed2a6894ad419aab0979c10410d59eb0ebf40d3)
|
set(STDUUID_HASH b1176597e789531c38481acbbed2a6894ad419aab0979c10410d59eb0ebf40d3)
|
||||||
set(ZLIB_HASH 17e88863f3600672ab49182f217281b6fc4d3c762bde361935e436a95214d05c)
|
set(ZLIB_HASH 17e88863f3600672ab49182f217281b6fc4d3c762bde361935e436a95214d05c)
|
||||||
|
@ -1,27 +1,27 @@
|
|||||||
set(BINUTILS_VERSION 2.43)
|
set(BINUTILS_VERSION 2.44)
|
||||||
set(BOOST2_MAJOR_VERSION 1)
|
set(BOOST2_MAJOR_VERSION 1)
|
||||||
set(BOOST2_MINOR_VERSION 76)
|
set(BOOST2_MINOR_VERSION 76)
|
||||||
set(BOOST2_PATCH_VERSION 0)
|
set(BOOST2_PATCH_VERSION 0)
|
||||||
set(BOOST_MAJOR_VERSION 1)
|
set(BOOST_MAJOR_VERSION 1)
|
||||||
set(BOOST_MINOR_VERSION 87)
|
set(BOOST_MINOR_VERSION 88)
|
||||||
set(BOOST_PATCH_VERSION 0)
|
set(BOOST_PATCH_VERSION 0)
|
||||||
set(CPP_HTTPLIB_VERSION 0.19.0)
|
set(CPP_HTTPLIB_VERSION 0.20.0)
|
||||||
set(CURL2_VERSION 8_12_1)
|
set(CURL2_VERSION 8_13_0)
|
||||||
set(CURL_VERSION 8.12.1)
|
set(CURL_VERSION 8.13.0)
|
||||||
set(EXPAT2_VERSION 2_6_4)
|
set(EXPAT2_VERSION 2_7_1)
|
||||||
set(EXPAT_VERSION 2.6.4)
|
set(EXPAT_VERSION 2.7.1)
|
||||||
set(GCC_VERSION 14.2.0)
|
set(GCC_VERSION 14.2.0)
|
||||||
set(GTEST_VERSION 1.16.0)
|
set(GTEST_VERSION 1.16.0)
|
||||||
set(ICU_VERSION 76-1)
|
set(ICU_VERSION 76-1)
|
||||||
set(JSON_VERSION 3.11.3)
|
set(JSON_VERSION 3.12.0)
|
||||||
set(LIBSODIUM_VERSION 1.0.20)
|
set(LIBSODIUM_VERSION 1.0.20)
|
||||||
set(MESA_VERSION 23.3.3)
|
set(MESA_VERSION 23.3.3)
|
||||||
set(MINGW_VERSION 12.0.0)
|
set(MINGW_VERSION 12.0.0)
|
||||||
set(OPENSSL_VERSION 3.4.1)
|
set(OPENSSL_VERSION 3.5.0)
|
||||||
set(PKG_CONFIG_VERSION 0.29.2)
|
set(PKG_CONFIG_VERSION 0.29.2)
|
||||||
set(PUGIXML_VERSION 1.15)
|
set(PUGIXML_VERSION 1.15)
|
||||||
set(ROCKSDB_VERSION 9.10.0)
|
set(ROCKSDB_VERSION 10.0.1)
|
||||||
set(SPDLOG_VERSION 1.15.1)
|
set(SPDLOG_VERSION 1.15.2)
|
||||||
set(SQLITE2_VERSION 3.49.1)
|
set(SQLITE2_VERSION 3.49.1)
|
||||||
set(SQLITE_VERSION 3490100)
|
set(SQLITE_VERSION 3490100)
|
||||||
set(STDUUID_VERSION 1.2.3)
|
set(STDUUID_VERSION 1.2.3)
|
||||||
|
@ -10,7 +10,7 @@ PROJECT_DESC="Mount utility for Sia and S3"
|
|||||||
|
|
||||||
PROJECT_MAJOR_VERSION=2
|
PROJECT_MAJOR_VERSION=2
|
||||||
PROJECT_MINOR_VERSION=0
|
PROJECT_MINOR_VERSION=0
|
||||||
PROJECT_REVISION_VERSION=5
|
PROJECT_REVISION_VERSION=6
|
||||||
PROJECT_RELEASE_NUM=0
|
PROJECT_RELEASE_NUM=0
|
||||||
PROJECT_RELEASE_ITER=rc
|
PROJECT_RELEASE_ITER=rc
|
||||||
|
|
||||||
@ -21,6 +21,7 @@ PROJECT_PUBLIC_KEY=${DEVELOPER_PUBLIC_KEY}
|
|||||||
|
|
||||||
PROJECT_FLUTTER_BASE_HREF="/ui/"
|
PROJECT_FLUTTER_BASE_HREF="/ui/"
|
||||||
|
|
||||||
|
PROJECT_ENABLE_V2_ERRORS=ON
|
||||||
PROJECT_ENABLE_WIN32_LONG_PATH_NAMES=OFF
|
PROJECT_ENABLE_WIN32_LONG_PATH_NAMES=OFF
|
||||||
|
|
||||||
PROJECT_ENABLE_BACKWARD_CPP=OFF
|
PROJECT_ENABLE_BACKWARD_CPP=OFF
|
||||||
|
@ -351,9 +351,9 @@ RUN cd /3rd_party/mingw64 && sha256sum -c ./expat-${MY_EXPAT_VERSION}.tar.gz.sha
|
|||||||
|
|
||||||
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.xz" ]; then \
|
||||||
cd /3rd_party && sha256sum -c ./fontconfig-${MY_FONTCONFIG_VERSION}.tar.gz.sha256 && cd - \
|
cd /3rd_party && sha256sum -c ./fontconfig-${MY_FONTCONFIG_VERSION}.tar.xz.sha256 && cd - \
|
||||||
&& tar xvzf /3rd_party/fontconfig-${MY_FONTCONFIG_VERSION}.tar.gz \
|
&& tar xvJf /3rd_party/fontconfig-${MY_FONTCONFIG_VERSION}.tar.xz \
|
||||||
&& 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} \
|
||||||
|
@ -225,8 +225,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (curl_code != CURLE_OK) {
|
if (curl_code != CURLE_OK) {
|
||||||
event_system::instance().raise<curl_error>(curl_code, function_name,
|
event_system::instance().raise<curl_error>(curl_code, function_name, url);
|
||||||
url);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,12 +54,13 @@ REPERTORY_IGNORE_WARNINGS_DISABLE()
|
|||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
|
|
||||||
inline constexpr const std::string_view REPERTORY = "repertory";
|
inline constexpr const std::string_view REPERTORY{"repertory"};
|
||||||
inline constexpr const std::wstring_view REPERTORY_W = L"repertory";
|
inline constexpr const std::string_view REPERTORY_DATA_NAME{"repertory2"};
|
||||||
|
inline constexpr const std::wstring_view REPERTORY_W{L"repertory"};
|
||||||
|
|
||||||
inline constexpr const std::uint64_t REPERTORY_CONFIG_VERSION = 2ULL;
|
inline constexpr const std::uint64_t REPERTORY_CONFIG_VERSION{2ULL};
|
||||||
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";
|
inline constexpr const std::string_view RENTERD_MIN_VERSION{"2.0.0"};
|
||||||
|
|
||||||
#define REPERTORY_INVALID_HANDLE INVALID_HANDLE_VALUE
|
#define REPERTORY_INVALID_HANDLE INVALID_HANDLE_VALUE
|
||||||
|
|
||||||
@ -221,11 +222,11 @@ using WCHAR = wchar_t;
|
|||||||
|
|
||||||
#define MAX_PATH 260
|
#define MAX_PATH 260
|
||||||
|
|
||||||
#define STATUS_SUCCESS std::uint32_t{0U}
|
|
||||||
#define STATUS_ACCESS_DENIED std::uint32_t{0xC0000022L}
|
#define STATUS_ACCESS_DENIED std::uint32_t{0xC0000022L}
|
||||||
#define STATUS_DEVICE_BUSY std::uint32_t{0x80000011L}
|
#define STATUS_DEVICE_BUSY std::uint32_t{0x80000011L}
|
||||||
#define STATUS_DEVICE_INSUFFICIENT_RESOURCES std::uint32_t{0xC0000468L}
|
#define STATUS_DEVICE_INSUFFICIENT_RESOURCES std::uint32_t{0xC0000468L}
|
||||||
#define STATUS_DIRECTORY_NOT_EMPTY std::uint32_t{0xC0000101L}
|
#define STATUS_DIRECTORY_NOT_EMPTY std::uint32_t{0xC0000101L}
|
||||||
|
#define STATUS_END_OF_FILE std::uint32_t{0xC0000011L}
|
||||||
#define STATUS_FILE_IS_A_DIRECTORY std::uint32_t{0xC00000BAL}
|
#define STATUS_FILE_IS_A_DIRECTORY std::uint32_t{0xC00000BAL}
|
||||||
#define STATUS_FILE_TOO_LARGE std::uint32_t{0xC0000904L}
|
#define STATUS_FILE_TOO_LARGE std::uint32_t{0xC0000904L}
|
||||||
#define STATUS_INSUFFICIENT_RESOURCES std::uint32_t{0xC000009AL}
|
#define STATUS_INSUFFICIENT_RESOURCES std::uint32_t{0xC000009AL}
|
||||||
@ -234,11 +235,13 @@ using WCHAR = wchar_t;
|
|||||||
#define STATUS_INVALID_HANDLE std::uint32_t{0xC0000006L}
|
#define STATUS_INVALID_HANDLE std::uint32_t{0xC0000006L}
|
||||||
#define STATUS_INVALID_IMAGE_FORMAT std::uint32_t{0xC000007BL}
|
#define STATUS_INVALID_IMAGE_FORMAT std::uint32_t{0xC000007BL}
|
||||||
#define STATUS_INVALID_PARAMETER std::uint32_t{0xC000000DL}
|
#define STATUS_INVALID_PARAMETER std::uint32_t{0xC000000DL}
|
||||||
#define STATUS_NO_MEMORY std::uint32_t{0xC0000017L}
|
|
||||||
#define STATUS_NOT_IMPLEMENTED std::uint32_t{0xC0000002L}
|
#define STATUS_NOT_IMPLEMENTED std::uint32_t{0xC0000002L}
|
||||||
|
#define STATUS_NO_MEMORY std::uint32_t{0xC0000017L}
|
||||||
|
#define STATUS_OBJECT_NAME_COLLISION std::uint32_t{0xC0000035L}
|
||||||
#define STATUS_OBJECT_NAME_EXISTS std::uint32_t{0x40000000L}
|
#define STATUS_OBJECT_NAME_EXISTS std::uint32_t{0x40000000L}
|
||||||
#define STATUS_OBJECT_NAME_NOT_FOUND std::uint32_t{0xC0000034L}
|
#define STATUS_OBJECT_NAME_NOT_FOUND std::uint32_t{0xC0000034L}
|
||||||
#define STATUS_OBJECT_PATH_INVALID std::uint32_t{0xC0000039L}
|
#define STATUS_OBJECT_PATH_INVALID std::uint32_t{0xC0000039L}
|
||||||
|
#define STATUS_SUCCESS std::uint32_t{0U}
|
||||||
#define STATUS_UNEXPECTED_IO_ERROR std::uint32_t{0xC00000E9L}
|
#define STATUS_UNEXPECTED_IO_ERROR std::uint32_t{0xC00000E9L}
|
||||||
|
|
||||||
#define CONVERT_STATUS_NOT_IMPLEMENTED(e) \
|
#define CONVERT_STATUS_NOT_IMPLEMENTED(e) \
|
||||||
|
@ -73,92 +73,95 @@ private:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
[[nodiscard]] auto chflags_impl(std::string api_path,
|
[[nodiscard]] auto chflags_impl(std::string api_path, uint32_t flags)
|
||||||
uint32_t flags) -> api_error override;
|
-> api_error override;
|
||||||
#endif // __APPLE__
|
#endif // __APPLE__
|
||||||
|
|
||||||
#if FUSE_USE_VERSION >= 30
|
#if FUSE_USE_VERSION >= 30
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto chmod_impl(std::string api_path, mode_t mode,
|
||||||
chmod_impl(std::string api_path, mode_t mode,
|
struct fuse_file_info *file_info)
|
||||||
struct fuse_file_info *file_info) -> api_error override;
|
-> api_error override;
|
||||||
#else
|
#else
|
||||||
[[nodiscard]] auto chmod_impl(std::string api_path,
|
[[nodiscard]] auto chmod_impl(std::string api_path, mode_t mode)
|
||||||
mode_t mode) -> api_error override;
|
-> api_error override;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if FUSE_USE_VERSION >= 30
|
#if FUSE_USE_VERSION >= 30
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto chown_impl(std::string api_path, uid_t uid, gid_t gid,
|
||||||
chown_impl(std::string api_path, uid_t uid, gid_t gid,
|
struct fuse_file_info *file_info)
|
||||||
struct fuse_file_info *file_info) -> api_error override;
|
-> api_error override;
|
||||||
#else
|
#else
|
||||||
[[nodiscard]] auto chown_impl(std::string api_path, uid_t uid,
|
[[nodiscard]] auto chown_impl(std::string api_path, uid_t uid, gid_t gid)
|
||||||
gid_t gid) -> api_error override;
|
-> api_error override;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto create_impl(std::string api_path, mode_t mode,
|
||||||
create_impl(std::string api_path, mode_t mode,
|
struct fuse_file_info *file_info)
|
||||||
struct fuse_file_info *file_info) -> api_error override;
|
-> api_error override;
|
||||||
|
|
||||||
void destroy_impl(void *ptr) override;
|
void destroy_impl(void *ptr) override;
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto fallocate_impl(std::string api_path, int mode,
|
||||||
fallocate_impl(std::string api_path, int mode, off_t offset, off_t length,
|
off_t offset, off_t length,
|
||||||
struct fuse_file_info *file_info) -> api_error override;
|
struct fuse_file_info *file_info)
|
||||||
|
-> api_error override;
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto fgetattr_impl(std::string api_path, struct stat *unix_st,
|
||||||
fgetattr_impl(std::string api_path, struct stat *unix_st,
|
struct fuse_file_info *file_info)
|
||||||
struct fuse_file_info *file_info) -> api_error override;
|
-> api_error override;
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto fsetattr_x_impl(std::string api_path,
|
||||||
fsetattr_x_impl(std::string api_path, struct setattr_x *attr,
|
struct setattr_x *attr,
|
||||||
struct fuse_file_info *file_info) -> api_error override;
|
struct fuse_file_info *file_info)
|
||||||
|
-> api_error override;
|
||||||
#endif // __APPLE__
|
#endif // __APPLE__
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto fsync_impl(std::string api_path, int datasync,
|
||||||
fsync_impl(std::string api_path, int datasync,
|
struct fuse_file_info *file_info)
|
||||||
struct fuse_file_info *file_info) -> api_error override;
|
-> api_error override;
|
||||||
|
|
||||||
#if FUSE_USE_VERSION < 30
|
#if FUSE_USE_VERSION < 30
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto ftruncate_impl(std::string api_path, off_t size,
|
||||||
ftruncate_impl(std::string api_path, off_t size,
|
struct fuse_file_info *file_info)
|
||||||
struct fuse_file_info *file_info) -> api_error override;
|
-> api_error override;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if FUSE_USE_VERSION >= 30
|
#if FUSE_USE_VERSION >= 30
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto getattr_impl(std::string api_path, struct stat *unix_st,
|
||||||
getattr_impl(std::string api_path, struct stat *unix_st,
|
struct fuse_file_info *file_info)
|
||||||
struct fuse_file_info *file_info) -> api_error override;
|
-> api_error override;
|
||||||
#else
|
#else
|
||||||
[[nodiscard]] auto getattr_impl(std::string api_path,
|
[[nodiscard]] auto getattr_impl(std::string api_path, struct stat *unix_st)
|
||||||
struct stat *unix_st) -> api_error override;
|
-> api_error override;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto getxtimes_impl(std::string api_path,
|
||||||
getxtimes_impl(std::string api_path, struct timespec *bkuptime,
|
struct timespec *bkuptime,
|
||||||
struct timespec *crtime) -> api_error override;
|
struct timespec *crtime)
|
||||||
|
-> api_error override;
|
||||||
#endif // __APPLE__
|
#endif // __APPLE__
|
||||||
|
|
||||||
#if FUSE_USE_VERSION >= 30
|
#if FUSE_USE_VERSION >= 30
|
||||||
auto init_impl(struct fuse_conn_info *conn,
|
auto init_impl(struct fuse_conn_info *conn, struct fuse_config *cfg)
|
||||||
struct fuse_config *cfg) -> void * override;
|
-> void * override;
|
||||||
#else
|
#else
|
||||||
auto init_impl(struct fuse_conn_info *conn) -> void * override;
|
auto init_impl(struct fuse_conn_info *conn) -> void * override;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
[[nodiscard]] auto mkdir_impl(std::string api_path,
|
[[nodiscard]] auto mkdir_impl(std::string api_path, mode_t mode)
|
||||||
mode_t mode) -> api_error override;
|
-> api_error override;
|
||||||
|
|
||||||
void notify_fuse_main_exit(int &ret) override;
|
void notify_fuse_main_exit(int &ret) override;
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto open_impl(std::string api_path,
|
||||||
open_impl(std::string api_path,
|
struct fuse_file_info *file_info)
|
||||||
struct fuse_file_info *file_info) -> api_error override;
|
-> api_error override;
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto opendir_impl(std::string api_path,
|
||||||
opendir_impl(std::string api_path,
|
struct fuse_file_info *file_info)
|
||||||
struct fuse_file_info *file_info) -> api_error override;
|
-> api_error override;
|
||||||
|
|
||||||
[[nodiscard]] auto read_impl(std::string api_path, char *buffer,
|
[[nodiscard]] auto read_impl(std::string api_path, char *buffer,
|
||||||
size_t read_size, off_t read_offset,
|
size_t read_size, off_t read_offset,
|
||||||
@ -166,29 +169,30 @@ protected:
|
|||||||
std::size_t &bytes_read) -> api_error override;
|
std::size_t &bytes_read) -> api_error override;
|
||||||
|
|
||||||
#if FUSE_USE_VERSION >= 30
|
#if FUSE_USE_VERSION >= 30
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto readdir_impl(std::string api_path, void *buf,
|
||||||
readdir_impl(std::string api_path, void *buf, fuse_fill_dir_t fuse_fill_dir,
|
fuse_fill_dir_t fuse_fill_dir, off_t offset,
|
||||||
off_t offset, struct fuse_file_info *file_info,
|
struct fuse_file_info *file_info,
|
||||||
fuse_readdir_flags flags) -> api_error override;
|
fuse_readdir_flags flags)
|
||||||
|
-> api_error override;
|
||||||
#else
|
#else
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto readdir_impl(std::string api_path, void *buf,
|
||||||
readdir_impl(std::string api_path, void *buf, fuse_fill_dir_t fuse_fill_dir,
|
fuse_fill_dir_t fuse_fill_dir, off_t offset,
|
||||||
off_t offset,
|
struct fuse_file_info *file_info)
|
||||||
struct fuse_file_info *file_info) -> api_error override;
|
-> api_error override;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto release_impl(std::string api_path,
|
||||||
release_impl(std::string api_path,
|
struct fuse_file_info *file_info)
|
||||||
struct fuse_file_info *file_info) -> api_error override;
|
-> api_error override;
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto releasedir_impl(std::string api_path,
|
||||||
releasedir_impl(std::string api_path,
|
struct fuse_file_info *file_info)
|
||||||
struct fuse_file_info *file_info) -> api_error override;
|
-> api_error override;
|
||||||
|
|
||||||
#if FUSE_USE_VERSION >= 30
|
#if FUSE_USE_VERSION >= 30
|
||||||
[[nodiscard]] auto rename_impl(std::string from_api_path,
|
[[nodiscard]] auto rename_impl(std::string from_api_path,
|
||||||
std::string to_api_path,
|
std::string to_api_path, unsigned int flags)
|
||||||
unsigned int flags) -> api_error override;
|
-> api_error override;
|
||||||
#else
|
#else
|
||||||
[[nodiscard]] auto rename_impl(std::string from_api_path,
|
[[nodiscard]] auto rename_impl(std::string from_api_path,
|
||||||
std::string to_api_path) -> api_error override;
|
std::string to_api_path) -> api_error override;
|
||||||
@ -199,8 +203,8 @@ protected:
|
|||||||
#if defined(HAS_SETXATTR)
|
#if defined(HAS_SETXATTR)
|
||||||
[[nodiscard]] auto getxattr_common(std::string api_path, const char *name,
|
[[nodiscard]] auto getxattr_common(std::string api_path, const char *name,
|
||||||
char *value, size_t size,
|
char *value, size_t size,
|
||||||
int &attribute_size,
|
int &attribute_size, uint32_t *position)
|
||||||
uint32_t *position) -> api_error;
|
-> api_error;
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
[[nodiscard]] auto getxattr_impl(std::string api_path, const char *name,
|
[[nodiscard]] auto getxattr_impl(std::string api_path, const char *name,
|
||||||
@ -216,8 +220,8 @@ protected:
|
|||||||
size_t size, int &required_size,
|
size_t size, int &required_size,
|
||||||
bool &return_size) -> api_error override;
|
bool &return_size) -> api_error override;
|
||||||
|
|
||||||
[[nodiscard]] auto removexattr_impl(std::string api_path,
|
[[nodiscard]] auto removexattr_impl(std::string api_path, const char *name)
|
||||||
const char *name) -> api_error override;
|
-> api_error override;
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
[[nodiscard]] auto setxattr_impl(std::string api_path, const char *name,
|
[[nodiscard]] auto setxattr_impl(std::string api_path, const char *name,
|
||||||
@ -225,62 +229,64 @@ protected:
|
|||||||
uint32_t position) -> api_error override;
|
uint32_t position) -> api_error override;
|
||||||
#else // __APPLE__
|
#else // __APPLE__
|
||||||
[[nodiscard]] auto setxattr_impl(std::string api_path, const char *name,
|
[[nodiscard]] auto setxattr_impl(std::string api_path, const char *name,
|
||||||
const char *value, size_t size,
|
const char *value, size_t size, int flags)
|
||||||
int flags) -> api_error override;
|
-> api_error override;
|
||||||
#endif // __APPLE__
|
#endif // __APPLE__
|
||||||
#endif // HAS_SETXATTR
|
#endif // HAS_SETXATTR
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto setattr_x_impl(std::string api_path,
|
||||||
setattr_x_impl(std::string api_path,
|
struct setattr_x *attr)
|
||||||
struct setattr_x *attr) -> api_error override;
|
-> api_error override;
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto setbkuptime_impl(std::string api_path,
|
||||||
setbkuptime_impl(std::string api_path,
|
const struct timespec *bkuptime)
|
||||||
const struct timespec *bkuptime) -> api_error override;
|
-> api_error override;
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto setchgtime_impl(std::string api_path,
|
||||||
setchgtime_impl(std::string api_path,
|
const struct timespec *chgtime)
|
||||||
const struct timespec *chgtime) -> api_error override;
|
-> api_error override;
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto setcrtime_impl(std::string api_path,
|
||||||
setcrtime_impl(std::string api_path,
|
const struct timespec *crtime)
|
||||||
const struct timespec *crtime) -> api_error override;
|
-> api_error override;
|
||||||
|
|
||||||
[[nodiscard]] auto setvolname_impl(const char *volname) -> api_error override;
|
[[nodiscard]] auto setvolname_impl(const char *volname) -> api_error override;
|
||||||
|
|
||||||
[[nodiscard]] auto statfs_x_impl(std::string api_path,
|
[[nodiscard]] auto statfs_x_impl(std::string api_path, struct statfs *stbuf)
|
||||||
struct statfs *stbuf) -> api_error override;
|
-> api_error override;
|
||||||
#else // __APPLE__
|
#else // __APPLE__
|
||||||
[[nodiscard]] auto statfs_impl(std::string api_path,
|
[[nodiscard]] auto statfs_impl(std::string api_path, struct statvfs *stbuf)
|
||||||
struct statvfs *stbuf) -> api_error override;
|
-> api_error override;
|
||||||
#endif // __APPLE__
|
#endif // __APPLE__
|
||||||
|
|
||||||
#if FUSE_USE_VERSION >= 30
|
#if FUSE_USE_VERSION >= 30
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto truncate_impl(std::string api_path, off_t size,
|
||||||
truncate_impl(std::string api_path, off_t size,
|
struct fuse_file_info *file_info)
|
||||||
struct fuse_file_info *file_info) -> api_error override;
|
-> api_error override;
|
||||||
#else
|
#else
|
||||||
[[nodiscard]] auto truncate_impl(std::string api_path,
|
[[nodiscard]] auto truncate_impl(std::string api_path, off_t size)
|
||||||
off_t size) -> api_error override;
|
-> api_error override;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
[[nodiscard]] auto unlink_impl(std::string api_path) -> api_error override;
|
[[nodiscard]] auto unlink_impl(std::string api_path) -> api_error override;
|
||||||
|
|
||||||
#if FUSE_USE_VERSION >= 30
|
#if FUSE_USE_VERSION >= 30
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto utimens_impl(std::string api_path,
|
||||||
utimens_impl(std::string api_path, const struct timespec tv[2],
|
const struct timespec tv[2],
|
||||||
struct fuse_file_info *file_info) -> api_error override;
|
struct fuse_file_info *file_info)
|
||||||
|
-> api_error override;
|
||||||
#else
|
#else
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto utimens_impl(std::string api_path,
|
||||||
utimens_impl(std::string api_path,
|
const struct timespec tv[2])
|
||||||
const struct timespec tv[2]) -> api_error override;
|
-> api_error override;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto write_impl(std::string api_path, const char *buffer,
|
||||||
write_impl(std::string api_path, const char *buffer, size_t write_size,
|
size_t write_size, off_t write_offset,
|
||||||
off_t write_offset, struct fuse_file_info *file_info,
|
struct fuse_file_info *file_info,
|
||||||
std::size_t &bytes_written) -> api_error override;
|
std::size_t &bytes_written)
|
||||||
|
-> 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
|
||||||
@ -289,16 +295,17 @@ public:
|
|||||||
[[nodiscard]] auto get_directory_items(const std::string &api_path) const
|
[[nodiscard]] auto get_directory_items(const std::string &api_path) const
|
||||||
-> directory_item_list override;
|
-> directory_item_list override;
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto get_file_size(const std::string &api_path) const
|
||||||
get_file_size(const std::string &api_path) const -> std::uint64_t override;
|
-> std::uint64_t override;
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto get_item_meta(const std::string &api_path,
|
||||||
get_item_meta(const std::string &api_path,
|
api_meta_map &meta) const
|
||||||
api_meta_map &meta) const -> api_error override;
|
-> api_error override;
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto get_item_meta(const std::string &api_path,
|
||||||
get_item_meta(const std::string &api_path, const std::string &name,
|
const std::string &name,
|
||||||
std::string &value) const -> api_error override;
|
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;
|
||||||
|
|
||||||
@ -309,19 +316,22 @@ public:
|
|||||||
void get_volume_info(UINT64 &total_size, UINT64 &free_size,
|
void get_volume_info(UINT64 &total_size, UINT64 &free_size,
|
||||||
std::string &volume_label) const override;
|
std::string &volume_label) const override;
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto is_processing(const std::string &api_path) const
|
||||||
is_processing(const std::string &api_path) const -> bool override;
|
-> bool override;
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto rename_directory(const std::string &from_api_path,
|
||||||
rename_directory(const std::string &from_api_path,
|
const std::string &to_api_path)
|
||||||
const std::string &to_api_path) -> int override;
|
-> int override;
|
||||||
|
|
||||||
[[nodiscard]] auto rename_file(const std::string &from_api_path,
|
[[nodiscard]] auto rename_file(const std::string &from_api_path,
|
||||||
const std::string &to_api_path,
|
const std::string &to_api_path, bool overwrite)
|
||||||
bool overwrite) -> int override;
|
-> int override;
|
||||||
|
|
||||||
void set_item_meta(const std::string &api_path, const std::string &key,
|
void set_item_meta(const std::string &api_path, const std::string &key,
|
||||||
const std::string &value) override;
|
const std::string &value) override;
|
||||||
|
|
||||||
|
void set_item_meta(const std::string &api_path,
|
||||||
|
const api_meta_map &meta) override;
|
||||||
};
|
};
|
||||||
} // namespace repertory
|
} // namespace repertory
|
||||||
|
|
||||||
|
@ -30,29 +30,32 @@ class i_fuse_drive {
|
|||||||
INTERFACE_SETUP(i_fuse_drive);
|
INTERFACE_SETUP(i_fuse_drive);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
[[nodiscard]] virtual auto
|
[[nodiscard]] virtual auto check_owner(const std::string &api_path) const
|
||||||
check_owner(const std::string &api_path) const -> api_error = 0;
|
-> api_error = 0;
|
||||||
|
|
||||||
|
[[nodiscard]] virtual auto check_parent_access(const std::string &api_path,
|
||||||
|
int mask) const
|
||||||
|
-> api_error = 0;
|
||||||
|
|
||||||
[[nodiscard]] virtual auto
|
[[nodiscard]] virtual auto
|
||||||
check_parent_access(const std::string &api_path,
|
get_directory_item_count(const std::string &api_path) const
|
||||||
int mask) const -> api_error = 0;
|
-> std::uint64_t = 0;
|
||||||
|
|
||||||
[[nodiscard]] virtual auto get_directory_item_count(
|
|
||||||
const std::string &api_path) const -> std::uint64_t = 0;
|
|
||||||
|
|
||||||
[[nodiscard]] virtual auto get_directory_items(
|
|
||||||
const std::string &api_path) const -> directory_item_list = 0;
|
|
||||||
|
|
||||||
[[nodiscard]] virtual auto
|
[[nodiscard]] virtual auto
|
||||||
get_file_size(const std::string &api_path) const -> std::uint64_t = 0;
|
get_directory_items(const std::string &api_path) const
|
||||||
|
-> directory_item_list = 0;
|
||||||
|
|
||||||
[[nodiscard]] virtual auto
|
[[nodiscard]] virtual auto get_file_size(const std::string &api_path) const
|
||||||
get_item_meta(const std::string &api_path,
|
-> std::uint64_t = 0;
|
||||||
api_meta_map &meta) const -> api_error = 0;
|
|
||||||
|
|
||||||
[[nodiscard]] virtual auto
|
[[nodiscard]] virtual auto get_item_meta(const std::string &api_path,
|
||||||
get_item_meta(const std::string &api_path, const std::string &name,
|
api_meta_map &meta) const
|
||||||
std::string &value) const -> api_error = 0;
|
-> api_error = 0;
|
||||||
|
|
||||||
|
[[nodiscard]] virtual auto get_item_meta(const std::string &api_path,
|
||||||
|
const std::string &name,
|
||||||
|
std::string &value) const
|
||||||
|
-> api_error = 0;
|
||||||
|
|
||||||
[[nodiscard]] virtual auto get_total_drive_space() const -> std::uint64_t = 0;
|
[[nodiscard]] virtual auto get_total_drive_space() const -> std::uint64_t = 0;
|
||||||
|
|
||||||
@ -63,12 +66,12 @@ public:
|
|||||||
virtual void get_volume_info(UINT64 &total_size, UINT64 &free_size,
|
virtual void get_volume_info(UINT64 &total_size, UINT64 &free_size,
|
||||||
std::string &volume_label) const = 0;
|
std::string &volume_label) const = 0;
|
||||||
|
|
||||||
[[nodiscard]] virtual auto
|
[[nodiscard]] virtual auto is_processing(const std::string &api_path) const
|
||||||
is_processing(const std::string &api_path) const -> bool = 0;
|
-> bool = 0;
|
||||||
|
|
||||||
[[nodiscard]] virtual auto
|
[[nodiscard]] virtual auto rename_directory(const std::string &from_api_path,
|
||||||
rename_directory(const std::string &from_api_path,
|
const std::string &to_api_path)
|
||||||
const std::string &to_api_path) -> int = 0;
|
-> int = 0;
|
||||||
|
|
||||||
[[nodiscard]] virtual auto rename_file(const std::string &from_api_path,
|
[[nodiscard]] virtual auto rename_file(const std::string &from_api_path,
|
||||||
const std::string &to_api_path,
|
const std::string &to_api_path,
|
||||||
@ -77,6 +80,9 @@ public:
|
|||||||
virtual void set_item_meta(const std::string &api_path,
|
virtual void set_item_meta(const std::string &api_path,
|
||||||
const std::string &key,
|
const std::string &key,
|
||||||
const std::string &value) = 0;
|
const std::string &value) = 0;
|
||||||
|
|
||||||
|
virtual void set_item_meta(const std::string &api_path,
|
||||||
|
const api_meta_map &meta) = 0;
|
||||||
};
|
};
|
||||||
} // namespace repertory
|
} // namespace repertory
|
||||||
|
|
||||||
|
@ -59,7 +59,8 @@ private:
|
|||||||
|
|
||||||
static void populate_stat(const struct stat64 &unix_st, remote::stat &r_stat);
|
static void populate_stat(const struct stat64 &unix_st, remote::stat &r_stat);
|
||||||
|
|
||||||
[[nodiscard]] auto update_to_windows_format(json &item) -> json &;
|
[[nodiscard]] auto update_to_windows_format(const std::string &root_api_path,
|
||||||
|
json &item) -> json &;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// FUSE Layer
|
// FUSE Layer
|
||||||
|
@ -143,14 +143,17 @@ public:
|
|||||||
allocation_size, &file_desc, &file_info,
|
allocation_size, &file_desc, &file_info,
|
||||||
normalized_name, exists);
|
normalized_name, exists);
|
||||||
if (ret == STATUS_SUCCESS) {
|
if (ret == STATUS_SUCCESS) {
|
||||||
|
if (exists == 0U) {
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
this->set_client_id(file_desc, client_id);
|
this->set_client_id(file_desc, client_id);
|
||||||
#else // !defined(_WIN32)
|
#else // !defined(_WIN32)
|
||||||
this->set_client_id(
|
this->set_client_id(
|
||||||
static_cast<native_handle>(
|
static_cast<native_handle>(
|
||||||
reinterpret_cast<std::uintptr_t>(file_desc)),
|
reinterpret_cast<std::uintptr_t>(file_desc)),
|
||||||
client_id);
|
client_id);
|
||||||
#endif // defined(_WIN32)
|
#endif // defined(_WIN32)
|
||||||
|
}
|
||||||
|
|
||||||
response.encode(file_desc);
|
response.encode(file_desc);
|
||||||
response.encode(file_info);
|
response.encode(file_info);
|
||||||
response.encode(normalized_name);
|
response.encode(normalized_name);
|
||||||
@ -343,15 +346,16 @@ public:
|
|||||||
DECODE_OR_RETURN(request, length);
|
DECODE_OR_RETURN(request, length);
|
||||||
|
|
||||||
data_buffer buffer(length);
|
data_buffer buffer(length);
|
||||||
UINT32 bytes_transferred{0};
|
UINT32 bytes_transferred{0U};
|
||||||
ret = this->winfsp_read(file_desc, buffer.data(), offset, length,
|
ret = this->winfsp_read(file_desc, buffer.data(), offset, length,
|
||||||
&bytes_transferred);
|
&bytes_transferred);
|
||||||
if (ret == STATUS_SUCCESS) {
|
response.encode(bytes_transferred);
|
||||||
response.encode(bytes_transferred);
|
buffer.resize(bytes_transferred);
|
||||||
if (bytes_transferred != 0U) {
|
|
||||||
response.encode(buffer.data(), bytes_transferred);
|
if ((ret == STATUS_SUCCESS) && (bytes_transferred != 0U)) {
|
||||||
}
|
response.encode(buffer.data(), bytes_transferred);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}});
|
}});
|
||||||
handler_lookup_.insert(
|
handler_lookup_.insert(
|
||||||
@ -589,8 +593,9 @@ public:
|
|||||||
DECODE_OR_RETURN(request, flags);
|
DECODE_OR_RETURN(request, flags);
|
||||||
|
|
||||||
remote::file_handle handle{};
|
remote::file_handle handle{};
|
||||||
if ((ret = this->fuse_create(path.data(), mode, flags, handle)) >=
|
|
||||||
0) {
|
ret = this->fuse_create(path.data(), mode, flags, handle);
|
||||||
|
if (ret >= 0) {
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
this->set_compat_client_id(handle, client_id);
|
this->set_compat_client_id(handle, client_id);
|
||||||
#else // !defined(_WIN32)
|
#else // !defined(_WIN32)
|
||||||
@ -846,7 +851,8 @@ public:
|
|||||||
DECODE_OR_RETURN(request, flags);
|
DECODE_OR_RETURN(request, flags);
|
||||||
|
|
||||||
remote::file_handle handle;
|
remote::file_handle handle;
|
||||||
if ((ret = this->fuse_open(path.c_str(), flags, handle)) >= 0) {
|
ret = this->fuse_open(path.c_str(), flags, handle);
|
||||||
|
if (ret >= 0) {
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
this->set_compat_client_id(handle, client_id);
|
this->set_compat_client_id(handle, client_id);
|
||||||
#else // !defined(_WIN32)
|
#else // !defined(_WIN32)
|
||||||
@ -867,7 +873,8 @@ public:
|
|||||||
DECODE_OR_RETURN(request, path);
|
DECODE_OR_RETURN(request, path);
|
||||||
|
|
||||||
remote::file_handle handle{0};
|
remote::file_handle handle{0};
|
||||||
if ((ret = this->fuse_opendir(path.c_str(), handle)) >= 0) {
|
ret = this->fuse_opendir(path.c_str(), handle);
|
||||||
|
if (ret >= 0) {
|
||||||
this->add_directory(client_id, handle);
|
this->add_directory(client_id, handle);
|
||||||
response.encode(handle);
|
response.encode(handle);
|
||||||
}
|
}
|
||||||
|
68
repertory/librepertory/include/events/types/info_log.hpp
Normal file
68
repertory/librepertory/include/events/types/info_log.hpp
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
Copyright <2018-2025> <scott.e.graves@protonmail.com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
#ifndef REPERTORY_INCLUDE_EVENTS_TYPES_INFO_LOG_HPP_
|
||||||
|
#define REPERTORY_INCLUDE_EVENTS_TYPES_INFO_LOG_HPP_
|
||||||
|
|
||||||
|
#include "events/i_event.hpp"
|
||||||
|
#include "types/repertory.hpp"
|
||||||
|
|
||||||
|
namespace repertory {
|
||||||
|
struct info_log final : public i_event {
|
||||||
|
info_log() = default;
|
||||||
|
info_log(std::string_view function_name_, std::string msg_)
|
||||||
|
: function_name(std::string(function_name_)), msg(std::move(msg_)) {}
|
||||||
|
|
||||||
|
static constexpr const event_level level{event_level::info};
|
||||||
|
static constexpr const std::string_view name{"info_log"};
|
||||||
|
|
||||||
|
std::string function_name;
|
||||||
|
std::string msg;
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_event_level() const -> event_level override {
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_name() const -> std::string_view override {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_single_line() const -> std::string override {
|
||||||
|
return fmt::format("{}|func|{}|msg|{}", name, function_name, msg);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace repertory
|
||||||
|
|
||||||
|
NLOHMANN_JSON_NAMESPACE_BEGIN
|
||||||
|
template <> struct adl_serializer<repertory::info_log> {
|
||||||
|
static void to_json(json &data, const repertory::info_log &value) {
|
||||||
|
data["function_name"] = value.function_name;
|
||||||
|
data["msg"] = value.msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void from_json(const json &data, repertory::info_log &value) {
|
||||||
|
data.at("function_name").get_to<std::string>(value.function_name);
|
||||||
|
data.at("msg").get_to<std::string>(value.msg);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
NLOHMANN_JSON_NAMESPACE_END
|
||||||
|
|
||||||
|
#endif // REPERTORY_INCLUDE_EVENTS_TYPES_INFO_LOG_HPP_
|
68
repertory/librepertory/include/events/types/trace_log.hpp
Normal file
68
repertory/librepertory/include/events/types/trace_log.hpp
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
Copyright <2018-2025> <scott.e.graves@protonmail.com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
#ifndef REPERTORY_INCLUDE_EVENTS_TYPES_TRACE_LOG_HPP_
|
||||||
|
#define REPERTORY_INCLUDE_EVENTS_TYPES_TRACE_LOG_HPP_
|
||||||
|
|
||||||
|
#include "events/i_event.hpp"
|
||||||
|
#include "types/repertory.hpp"
|
||||||
|
|
||||||
|
namespace repertory {
|
||||||
|
struct trace_log final : public i_event {
|
||||||
|
trace_log() = default;
|
||||||
|
trace_log(std::string_view function_name_, std::string msg_)
|
||||||
|
: function_name(std::string(function_name_)), msg(std::move(msg_)) {}
|
||||||
|
|
||||||
|
static constexpr const event_level level{event_level::trace};
|
||||||
|
static constexpr const std::string_view name{"trace_log"};
|
||||||
|
|
||||||
|
std::string function_name;
|
||||||
|
std::string msg;
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_event_level() const -> event_level override {
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_name() const -> std::string_view override {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_single_line() const -> std::string override {
|
||||||
|
return fmt::format("{}|func|{}|msg|{}", name, function_name, msg);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace repertory
|
||||||
|
|
||||||
|
NLOHMANN_JSON_NAMESPACE_BEGIN
|
||||||
|
template <> struct adl_serializer<repertory::trace_log> {
|
||||||
|
static void to_json(json &data, const repertory::trace_log &value) {
|
||||||
|
data["function_name"] = value.function_name;
|
||||||
|
data["msg"] = value.msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void from_json(const json &data, repertory::trace_log &value) {
|
||||||
|
data.at("function_name").get_to<std::string>(value.function_name);
|
||||||
|
data.at("msg").get_to<std::string>(value.msg);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
NLOHMANN_JSON_NAMESPACE_END
|
||||||
|
|
||||||
|
#endif // REPERTORY_INCLUDE_EVENTS_TYPES_TRACE_LOG_HPP_
|
68
repertory/librepertory/include/events/types/warn_log.hpp
Normal file
68
repertory/librepertory/include/events/types/warn_log.hpp
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
Copyright <2018-2025> <scott.e.graves@protonmail.com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
#ifndef REPERTORY_INCLUDE_EVENTS_TYPES_WARN_LOG_HPP_
|
||||||
|
#define REPERTORY_INCLUDE_EVENTS_TYPES_WARN_LOG_HPP_
|
||||||
|
|
||||||
|
#include "events/i_event.hpp"
|
||||||
|
#include "types/repertory.hpp"
|
||||||
|
|
||||||
|
namespace repertory {
|
||||||
|
struct warn_log final : public i_event {
|
||||||
|
warn_log() = default;
|
||||||
|
warn_log(std::string_view function_name_, std::string msg_)
|
||||||
|
: function_name(std::string(function_name_)), msg(std::move(msg_)) {}
|
||||||
|
|
||||||
|
static constexpr const event_level level{event_level::warn};
|
||||||
|
static constexpr const std::string_view name{"warn_log"};
|
||||||
|
|
||||||
|
std::string function_name;
|
||||||
|
std::string msg;
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_event_level() const -> event_level override {
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_name() const -> std::string_view override {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_single_line() const -> std::string override {
|
||||||
|
return fmt::format("{}|func|{}|msg|{}", name, function_name, msg);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace repertory
|
||||||
|
|
||||||
|
NLOHMANN_JSON_NAMESPACE_BEGIN
|
||||||
|
template <> struct adl_serializer<repertory::warn_log> {
|
||||||
|
static void to_json(json &data, const repertory::warn_log &value) {
|
||||||
|
data["function_name"] = value.function_name;
|
||||||
|
data["msg"] = value.msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void from_json(const json &data, repertory::warn_log &value) {
|
||||||
|
data.at("function_name").get_to<std::string>(value.function_name);
|
||||||
|
data.at("msg").get_to<std::string>(value.msg);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
NLOHMANN_JSON_NAMESPACE_END
|
||||||
|
|
||||||
|
#endif // REPERTORY_INCLUDE_EVENTS_TYPES_WARN_LOG_HPP_
|
@ -49,16 +49,28 @@ private:
|
|||||||
sia_config sia_config_;
|
sia_config sia_config_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
[[nodiscard]] auto create_directory_key(const std::string &api_path) const
|
||||||
|
-> repertory::api_error;
|
||||||
|
|
||||||
|
[[nodiscard]] auto ensure_directory_exists(const std::string &api_path) const
|
||||||
|
-> api_error;
|
||||||
|
|
||||||
[[nodiscard]] auto get_object_info(const std::string &api_path,
|
[[nodiscard]] auto get_object_info(const std::string &api_path,
|
||||||
json &object_info) const -> api_error;
|
json &object_info) const -> api_error;
|
||||||
|
|
||||||
[[nodiscard]] auto get_object_list(const std::string &api_path,
|
[[nodiscard]] auto
|
||||||
nlohmann::json &object_list) const -> bool;
|
get_object_list(const std::string &api_path, nlohmann::json &object_list,
|
||||||
|
std::optional<std::string> marker = std::nullopt) const
|
||||||
|
-> bool;
|
||||||
|
|
||||||
[[nodiscard]] auto get_sia_config() const -> const auto & {
|
[[nodiscard]] auto get_sia_config() const -> const auto & {
|
||||||
return sia_config_;
|
return sia_config_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void iterate_objects(
|
||||||
|
const std::string &api_path, const json &object_list,
|
||||||
|
std::function<void(const std::string &, bool, json)> handle_entry) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
[[nodiscard]] auto create_directory_impl(const std::string &api_path,
|
[[nodiscard]] auto create_directory_impl(const std::string &api_path,
|
||||||
api_meta_map &meta)
|
api_meta_map &meta)
|
||||||
|
@ -39,33 +39,34 @@ auto directory_iterator::fill_buffer(const remote::file_offset &offset,
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
std::string item_name;
|
auto next_offset{offset + 1U};
|
||||||
struct stat st{};
|
|
||||||
struct stat *pst = nullptr;
|
|
||||||
switch (offset) {
|
|
||||||
case 0: {
|
|
||||||
item_name = ".";
|
|
||||||
} break;
|
|
||||||
|
|
||||||
|
std::string item_name;
|
||||||
|
struct stat u_stat{};
|
||||||
|
|
||||||
|
switch (offset) {
|
||||||
|
case 0:
|
||||||
case 1: {
|
case 1: {
|
||||||
item_name = "..";
|
item_name = offset == 0U ? "." : "..";
|
||||||
|
u_stat.st_mode = S_IFDIR | 0755;
|
||||||
|
u_stat.st_nlink = 2;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
const auto &item = items_[offset];
|
const auto &item = items_.at(offset);
|
||||||
item_name = utils::path::strip_to_file_name(item.api_path);
|
item_name = utils::path::strip_to_file_name(item.api_path);
|
||||||
populate_stat(item.api_path, item.size, item.meta, item.directory, &st);
|
populate_stat(item.api_path, item.size, item.meta, item.directory,
|
||||||
pst = &st;
|
&u_stat);
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if FUSE_USE_VERSION >= 30
|
#if FUSE_USE_VERSION >= 30
|
||||||
if (filler_function(buffer, item_name.data(), pst,
|
if (filler_function(buffer, item_name.data(), &u_stat,
|
||||||
static_cast<off_t>(offset + 1),
|
static_cast<off_t>(next_offset),
|
||||||
FUSE_FILL_DIR_PLUS) != 0)
|
FUSE_FILL_DIR_PLUS) != 0)
|
||||||
#else // FUSE_USE_VERSION < 30
|
#else // FUSE_USE_VERSION < 30
|
||||||
if (filler_function(buffer, item_name.data(), pst,
|
if (filler_function(buffer, item_name.data(), &u_stat,
|
||||||
static_cast<off_t>(offset + 1)) != 0)
|
static_cast<off_t>(next_offset)) != 0)
|
||||||
#endif // FUSE_USE_VERSION >= 30
|
#endif // FUSE_USE_VERSION >= 30
|
||||||
{
|
{
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
|
@ -374,13 +374,13 @@ auto fuse_base::init_impl(struct fuse_conn_info *conn) -> void * {
|
|||||||
if (not utils::file::change_to_process_directory()) {
|
if (not utils::file::change_to_process_directory()) {
|
||||||
utils::error::raise_error(function_name,
|
utils::error::raise_error(function_name,
|
||||||
"failed to change to process directory");
|
"failed to change to process directory");
|
||||||
event_system::instance().raise<unmount_requested>();
|
event_system::instance().raise<unmount_requested>(function_name);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (not console_enabled_ && not repertory::project_initialize()) {
|
if (not console_enabled_ && not repertory::project_initialize()) {
|
||||||
utils::error::raise_error(function_name, "failed to initialize repertory");
|
utils::error::raise_error(function_name, "failed to initialize repertory");
|
||||||
event_system::instance().raise<unmount_requested>();
|
event_system::instance().raise<unmount_requested>(function_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
|
@ -85,8 +85,8 @@ auto fuse_drive::chown_impl(std::string api_path, uid_t uid, gid_t gid,
|
|||||||
struct fuse_file_info * /*file_info*/)
|
struct fuse_file_info * /*file_info*/)
|
||||||
-> api_error {
|
-> api_error {
|
||||||
#else
|
#else
|
||||||
auto fuse_drive::chown_impl(std::string api_path, uid_t uid,
|
auto fuse_drive::chown_impl(std::string api_path, uid_t uid, gid_t gid)
|
||||||
gid_t gid) -> api_error {
|
-> api_error {
|
||||||
#endif
|
#endif
|
||||||
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 {
|
||||||
@ -464,7 +464,7 @@ auto fuse_drive::get_file_size(const std::string &api_path) const
|
|||||||
|
|
||||||
std::uint64_t file_size{};
|
std::uint64_t file_size{};
|
||||||
auto res = provider_.get_file_size(api_path, file_size);
|
auto res = provider_.get_file_size(api_path, file_size);
|
||||||
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 get file size from provider");
|
"failed to get file size from provider");
|
||||||
}
|
}
|
||||||
@ -494,8 +494,8 @@ auto fuse_drive::getattr_impl(std::string api_path, struct stat *unix_st,
|
|||||||
struct fuse_file_info * /*file_info*/)
|
struct fuse_file_info * /*file_info*/)
|
||||||
-> api_error {
|
-> api_error {
|
||||||
#else
|
#else
|
||||||
auto fuse_drive::getattr_impl(std::string api_path,
|
auto fuse_drive::getattr_impl(std::string api_path, struct stat *unix_st)
|
||||||
struct stat *unix_st) -> api_error {
|
-> api_error {
|
||||||
#endif
|
#endif
|
||||||
auto parent = utils::path::get_parent_api_path(api_path);
|
auto parent = utils::path::get_parent_api_path(api_path);
|
||||||
|
|
||||||
@ -561,8 +561,8 @@ auto fuse_drive::getxtimes_impl(std::string api_path, struct timespec *bkuptime,
|
|||||||
#endif // __APPLE__
|
#endif // __APPLE__
|
||||||
|
|
||||||
#if FUSE_USE_VERSION >= 30
|
#if FUSE_USE_VERSION >= 30
|
||||||
auto fuse_drive::init_impl(struct fuse_conn_info *conn,
|
auto fuse_drive::init_impl(struct fuse_conn_info *conn, struct fuse_config *cfg)
|
||||||
struct fuse_config *cfg) -> void * {
|
-> void * {
|
||||||
#else
|
#else
|
||||||
void *fuse_drive::init_impl(struct fuse_conn_info *conn) {
|
void *fuse_drive::init_impl(struct fuse_conn_info *conn) {
|
||||||
#endif
|
#endif
|
||||||
@ -804,8 +804,9 @@ auto fuse_drive::release_impl(std::string /*api_path*/,
|
|||||||
return api_error::success;
|
return api_error::success;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto fuse_drive::releasedir_impl(
|
auto fuse_drive::releasedir_impl(std::string /*api_path*/,
|
||||||
std::string /*api_path*/, struct fuse_file_info *file_info) -> api_error {
|
struct fuse_file_info *file_info)
|
||||||
|
-> api_error {
|
||||||
auto iter = directory_cache_->get_directory(file_info->fh);
|
auto iter = directory_cache_->get_directory(file_info->fh);
|
||||||
if (iter == nullptr) {
|
if (iter == nullptr) {
|
||||||
return api_error::invalid_handle;
|
return api_error::invalid_handle;
|
||||||
@ -823,8 +824,8 @@ auto fuse_drive::rename_directory(const std::string &from_api_path,
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto fuse_drive::rename_file(const std::string &from_api_path,
|
auto fuse_drive::rename_file(const std::string &from_api_path,
|
||||||
const std::string &to_api_path,
|
const std::string &to_api_path, bool overwrite)
|
||||||
bool overwrite) -> int {
|
-> int {
|
||||||
auto res = fm_->rename_file(from_api_path, to_api_path, overwrite);
|
auto res = fm_->rename_file(from_api_path, to_api_path, overwrite);
|
||||||
errno = std::abs(utils::from_api_error(res));
|
errno = std::abs(utils::from_api_error(res));
|
||||||
return (res == api_error::success) ? 0 : -1;
|
return (res == api_error::success) ? 0 : -1;
|
||||||
@ -834,8 +835,8 @@ auto fuse_drive::rename_file(const std::string &from_api_path,
|
|||||||
auto fuse_drive::rename_impl(std::string from_api_path, std::string to_api_path,
|
auto fuse_drive::rename_impl(std::string from_api_path, std::string to_api_path,
|
||||||
unsigned int /*flags*/) -> api_error {
|
unsigned int /*flags*/) -> api_error {
|
||||||
#else
|
#else
|
||||||
auto fuse_drive::rename_impl(std::string from_api_path,
|
auto fuse_drive::rename_impl(std::string from_api_path, std::string to_api_path)
|
||||||
std::string to_api_path) -> api_error {
|
-> api_error {
|
||||||
#endif
|
#endif
|
||||||
auto res = check_parent_access(to_api_path, W_OK | X_OK);
|
auto res = check_parent_access(to_api_path, W_OK | X_OK);
|
||||||
if (res != api_error::success) {
|
if (res != api_error::success) {
|
||||||
@ -937,15 +938,15 @@ auto fuse_drive::getxattr_impl(std::string api_path, const char *name,
|
|||||||
}
|
}
|
||||||
#else // __APPLE__
|
#else // __APPLE__
|
||||||
auto fuse_drive::getxattr_impl(std::string api_path, const char *name,
|
auto fuse_drive::getxattr_impl(std::string api_path, const char *name,
|
||||||
char *value, size_t size,
|
char *value, size_t size, int &attribute_size)
|
||||||
int &attribute_size) -> api_error {
|
-> api_error {
|
||||||
return getxattr_common(api_path, name, value, size, attribute_size, nullptr);
|
return getxattr_common(api_path, name, value, size, attribute_size, nullptr);
|
||||||
}
|
}
|
||||||
#endif // __APPLE__
|
#endif // __APPLE__
|
||||||
|
|
||||||
auto fuse_drive::listxattr_impl(std::string api_path, char *buffer, size_t size,
|
auto fuse_drive::listxattr_impl(std::string api_path, char *buffer, size_t size,
|
||||||
int &required_size,
|
int &required_size, bool &return_size)
|
||||||
bool &return_size) -> api_error {
|
-> api_error {
|
||||||
auto check_size = (size == 0);
|
auto check_size = (size == 0);
|
||||||
|
|
||||||
auto res = check_parent_access(api_path, X_OK);
|
auto res = check_parent_access(api_path, X_OK);
|
||||||
@ -985,8 +986,8 @@ auto fuse_drive::listxattr_impl(std::string api_path, char *buffer, size_t size,
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto fuse_drive::removexattr_impl(std::string api_path,
|
auto fuse_drive::removexattr_impl(std::string api_path, const char *name)
|
||||||
const char *name) -> api_error {
|
-> api_error {
|
||||||
std::string attribute_name;
|
std::string attribute_name;
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
auto res = parse_xattr_parameters(name, 0, attribute_name, api_path);
|
auto res = parse_xattr_parameters(name, 0, attribute_name, api_path);
|
||||||
@ -1014,8 +1015,8 @@ auto fuse_drive::setxattr_impl(std::string api_path, const char *name,
|
|||||||
uint32_t position) -> api_error {
|
uint32_t position) -> api_error {
|
||||||
#else // __APPLE__
|
#else // __APPLE__
|
||||||
auto fuse_drive::setxattr_impl(std::string api_path, const char *name,
|
auto fuse_drive::setxattr_impl(std::string api_path, const char *name,
|
||||||
const char *value, size_t size,
|
const char *value, size_t size, int flags)
|
||||||
int flags) -> api_error {
|
-> api_error {
|
||||||
#endif
|
#endif
|
||||||
std::string attribute_name;
|
std::string attribute_name;
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
@ -1086,15 +1087,27 @@ void fuse_drive::set_item_meta(const std::string &api_path,
|
|||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
auto res = provider_.set_item_meta(api_path, key, value);
|
auto res = provider_.set_item_meta(api_path, key, value);
|
||||||
|
if (res != api_error::success) {
|
||||||
|
utils::error::raise_api_path_error(
|
||||||
|
function_name, api_path, res,
|
||||||
|
fmt::format("failed to set item meta|key|{}", key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void fuse_drive::set_item_meta(const std::string &api_path,
|
||||||
|
const api_meta_map &meta) {
|
||||||
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
|
auto res = provider_.set_item_meta(api_path, meta);
|
||||||
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,
|
||||||
"key|" + key + "|value|" + value);
|
"failed to set item meta");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
auto fuse_drive::setattr_x_impl(std::string api_path,
|
auto fuse_drive::setattr_x_impl(std::string api_path, struct setattr_x *attr)
|
||||||
struct setattr_x *attr) -> api_error {
|
-> api_error {
|
||||||
bool exists{};
|
bool exists{};
|
||||||
auto res = provider_.is_file(api_path, exists);
|
auto res = provider_.is_file(api_path, exists);
|
||||||
if (res != api_error::success) {
|
if (res != api_error::success) {
|
||||||
@ -1148,7 +1161,7 @@ auto fuse_drive::setattr_x_impl(std::string api_path,
|
|||||||
ts[0].tv_sec = attr->acctime.tv_sec;
|
ts[0].tv_sec = attr->acctime.tv_sec;
|
||||||
ts[0].tv_nsec = attr->acctime.tv_nsec;
|
ts[0].tv_nsec = attr->acctime.tv_nsec;
|
||||||
} else {
|
} else {
|
||||||
struct timeval tv {};
|
struct timeval tv{};
|
||||||
gettimeofday(&tv, NULL);
|
gettimeofday(&tv, NULL);
|
||||||
ts[0].tv_sec = tv.tv_sec;
|
ts[0].tv_sec = tv.tv_sec;
|
||||||
ts[0].tv_nsec = tv.tv_usec * 1000;
|
ts[0].tv_nsec = tv.tv_usec * 1000;
|
||||||
@ -1193,8 +1206,9 @@ auto fuse_drive::setattr_x_impl(std::string api_path,
|
|||||||
return api_error::success;
|
return api_error::success;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto fuse_drive::setbkuptime_impl(
|
auto fuse_drive::setbkuptime_impl(std::string api_path,
|
||||||
std::string api_path, const struct timespec *bkuptime) -> api_error {
|
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 {
|
||||||
auto nanos = bkuptime->tv_nsec +
|
auto nanos = bkuptime->tv_nsec +
|
||||||
@ -1230,8 +1244,8 @@ auto fuse_drive::setvolname_impl(const char * /*volname*/) -> api_error {
|
|||||||
return api_error::success;
|
return api_error::success;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto fuse_drive::statfs_x_impl(std::string /*api_path*/,
|
auto fuse_drive::statfs_x_impl(std::string /*api_path*/, struct statfs *stbuf)
|
||||||
struct statfs *stbuf) -> api_error {
|
-> api_error {
|
||||||
if (statfs(&config_.get_cache_directory()[0], stbuf) != 0) {
|
if (statfs(&config_.get_cache_directory()[0], stbuf) != 0) {
|
||||||
return api_error::os_error;
|
return api_error::os_error;
|
||||||
}
|
}
|
||||||
@ -1256,8 +1270,8 @@ auto fuse_drive::statfs_x_impl(std::string /*api_path*/,
|
|||||||
return api_error::success;
|
return api_error::success;
|
||||||
}
|
}
|
||||||
#else // __APPLE__
|
#else // __APPLE__
|
||||||
auto fuse_drive::statfs_impl(std::string /*api_path*/,
|
auto fuse_drive::statfs_impl(std::string /*api_path*/, struct statvfs *stbuf)
|
||||||
struct statvfs *stbuf) -> api_error {
|
-> api_error {
|
||||||
if (statvfs(config_.get_cache_directory().data(), stbuf) != 0) {
|
if (statvfs(config_.get_cache_directory().data(), stbuf) != 0) {
|
||||||
return api_error::os_error;
|
return api_error::os_error;
|
||||||
}
|
}
|
||||||
@ -1341,8 +1355,8 @@ auto fuse_drive::utimens_impl(std::string api_path, const struct timespec tv[2],
|
|||||||
struct fuse_file_info * /*file_info*/)
|
struct fuse_file_info * /*file_info*/)
|
||||||
-> api_error {
|
-> api_error {
|
||||||
#else
|
#else
|
||||||
auto fuse_drive::utimens_impl(std::string api_path,
|
auto fuse_drive::utimens_impl(std::string api_path, const struct timespec tv[2])
|
||||||
const struct timespec tv[2]) -> api_error {
|
-> api_error {
|
||||||
#endif
|
#endif
|
||||||
api_meta_map meta;
|
api_meta_map meta;
|
||||||
auto res = provider_.get_item_meta(api_path, meta);
|
auto res = provider_.get_item_meta(api_path, meta);
|
||||||
|
@ -259,7 +259,7 @@ auto remote_fuse_drive::init_impl(struct fuse_conn_info *conn) -> void * {
|
|||||||
if (remote_instance_->fuse_init() != 0) {
|
if (remote_instance_->fuse_init() != 0) {
|
||||||
utils::error::raise_error(function_name,
|
utils::error::raise_error(function_name,
|
||||||
"failed to connect to remote server");
|
"failed to connect to remote server");
|
||||||
event_system::instance().raise<unmount_requested>();
|
event_system::instance().raise<unmount_requested>(function_name);
|
||||||
} else {
|
} else {
|
||||||
server_ = std::make_shared<server>(config_);
|
server_ = std::make_shared<server>(config_);
|
||||||
server_->start();
|
server_->start();
|
||||||
|
@ -82,18 +82,21 @@ auto remote_server::get_next_handle() -> std::uint64_t {
|
|||||||
auto remote_server::populate_file_info(const std::string &api_path,
|
auto remote_server::populate_file_info(const std::string &api_path,
|
||||||
remote::file_info &file_info)
|
remote::file_info &file_info)
|
||||||
-> packet::error_type {
|
-> packet::error_type {
|
||||||
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
std::string meta_attributes;
|
std::string meta_attributes;
|
||||||
auto error = drive_.get_item_meta(api_path, META_ATTRIBUTES, meta_attributes);
|
auto directory = utils::file::directory(construct_path(api_path)).exists();
|
||||||
if (error == api_error::success) {
|
|
||||||
|
auto res = drive_.get_item_meta(api_path, META_ATTRIBUTES, meta_attributes);
|
||||||
|
if (res == api_error::success) {
|
||||||
if (meta_attributes.empty()) {
|
if (meta_attributes.empty()) {
|
||||||
meta_attributes =
|
meta_attributes = directory ? std::to_string(FILE_ATTRIBUTE_DIRECTORY)
|
||||||
utils::file::directory(construct_path(api_path)).exists()
|
: std::to_string(FILE_ATTRIBUTE_ARCHIVE);
|
||||||
? std::to_string(FILE_ATTRIBUTE_DIRECTORY)
|
|
||||||
: std::to_string(FILE_ATTRIBUTE_ARCHIVE);
|
|
||||||
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 file_size = drive_.get_file_size(api_path);
|
auto attributes = utils::string::to_uint32(meta_attributes);
|
||||||
|
auto file_size = directory ? 0U : drive_.get_file_size(api_path);
|
||||||
populate_file_info(api_path, file_size, attributes, file_info);
|
populate_file_info(api_path, file_size, attributes, file_info);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -108,7 +111,7 @@ void remote_server::populate_file_info(const std::string &api_path,
|
|||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
api_meta_map meta{};
|
api_meta_map meta{};
|
||||||
const auto res = drive_.get_item_meta(api_path, meta);
|
auto res = drive_.get_item_meta(api_path, meta);
|
||||||
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,
|
||||||
"get item meta failed");
|
"get item meta failed");
|
||||||
@ -192,10 +195,10 @@ auto remote_server::fuse_access(const char *path, const std::int32_t &mask)
|
|||||||
-> packet::error_type {
|
-> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
const auto api_path = utils::path::create_api_path(path);
|
auto api_path = utils::path::create_api_path(path);
|
||||||
const auto file_path = construct_path(path);
|
auto file_path = construct_path(path);
|
||||||
|
|
||||||
const auto res = access(file_path.c_str(), mask);
|
auto res = access(file_path.c_str(), mask);
|
||||||
auto ret = ((res < 0) ? -errno : 0);
|
auto ret = ((res < 0) ? -errno : 0);
|
||||||
RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, ret);
|
RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, ret);
|
||||||
return ret;
|
return ret;
|
||||||
@ -205,8 +208,8 @@ auto remote_server::fuse_chflags(const char *path, std::uint32_t flags)
|
|||||||
-> packet::error_type {
|
-> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
const auto api_path = utils::path::create_api_path(path);
|
auto api_path = utils::path::create_api_path(path);
|
||||||
const auto file_path = construct_path(path);
|
auto file_path = construct_path(path);
|
||||||
|
|
||||||
auto ret = -EACCES;
|
auto ret = -EACCES;
|
||||||
if (drive_.check_parent_access(api_path, X_OK) == api_error::success) {
|
if (drive_.check_parent_access(api_path, X_OK) == api_error::success) {
|
||||||
@ -225,8 +228,8 @@ auto remote_server::fuse_chmod(const char *path, const remote::file_mode &mode)
|
|||||||
-> packet::error_type {
|
-> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
const auto file_path = construct_path(path);
|
auto file_path = construct_path(path);
|
||||||
const auto res = chmod(file_path.c_str(), mode);
|
auto res = chmod(file_path.c_str(), mode);
|
||||||
auto ret = ((res < 0) ? -errno : 0);
|
auto ret = ((res < 0) ? -errno : 0);
|
||||||
RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, ret);
|
RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, ret);
|
||||||
return ret;
|
return ret;
|
||||||
@ -237,8 +240,8 @@ auto remote_server::fuse_chown(const char *path, const remote::user_id &uid,
|
|||||||
-> packet::error_type {
|
-> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
const auto file_path = construct_path(path);
|
auto file_path = construct_path(path);
|
||||||
const auto res = chown(file_path.c_str(), uid, gid);
|
auto res = chown(file_path.c_str(), uid, gid);
|
||||||
auto ret = ((res < 0) ? -errno : 0);
|
auto ret = ((res < 0) ? -errno : 0);
|
||||||
RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, ret);
|
RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, ret);
|
||||||
return ret;
|
return ret;
|
||||||
@ -250,10 +253,9 @@ auto remote_server::fuse_create(const char *path, const remote::file_mode &mode,
|
|||||||
-> packet::error_type {
|
-> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
const auto file_path = construct_path(path);
|
auto file_path = construct_path(path);
|
||||||
const auto res =
|
auto res = open(file_path.c_str(),
|
||||||
open(file_path.c_str(),
|
static_cast<int>(remote::create_os_open_flags(flags)), mode);
|
||||||
static_cast<int>(remote::create_os_open_flags(flags)), mode);
|
|
||||||
if (res >= 0) {
|
if (res >= 0) {
|
||||||
handle = static_cast<remote::file_handle>(res);
|
handle = static_cast<remote::file_handle>(res);
|
||||||
set_open_info(res, open_info{
|
set_open_info(res, open_info{
|
||||||
@ -322,7 +324,7 @@ auto remote_server::fuse_fgetattr(const char *path, remote::stat &r_stat,
|
|||||||
|
|
||||||
r_stat = {};
|
r_stat = {};
|
||||||
|
|
||||||
const auto file_path = construct_path(path);
|
auto file_path = construct_path(path);
|
||||||
|
|
||||||
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) {
|
||||||
@ -345,8 +347,8 @@ auto remote_server::fuse_fsetattr_x(const char *path,
|
|||||||
-> packet::error_type {
|
-> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
const auto api_path = utils::path::create_api_path(path);
|
auto api_path = utils::path::create_api_path(path);
|
||||||
const auto file_path = construct_path(path);
|
auto file_path = construct_path(path);
|
||||||
|
|
||||||
auto res = 0;
|
auto res = 0;
|
||||||
if (SETATTR_WANTS_MODE(&attr)) {
|
if (SETATTR_WANTS_MODE(&attr)) {
|
||||||
@ -440,7 +442,7 @@ auto remote_server::fuse_fsync(const char *path, const std::int32_t &datasync,
|
|||||||
-> packet::error_type {
|
-> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
const auto file_path = construct_path(path);
|
auto file_path = construct_path(path);
|
||||||
|
|
||||||
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) {
|
||||||
@ -464,7 +466,7 @@ auto remote_server::fuse_ftruncate(const char *path,
|
|||||||
-> packet::error_type {
|
-> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
const auto file_path = construct_path(path);
|
auto file_path = construct_path(path);
|
||||||
|
|
||||||
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) {
|
||||||
@ -481,9 +483,9 @@ auto remote_server::fuse_getattr(const char *path, remote::stat &r_stat,
|
|||||||
bool &directory) -> packet::error_type {
|
bool &directory) -> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
const auto api_path = utils::path::create_api_path(path);
|
auto api_path = utils::path::create_api_path(path);
|
||||||
const auto file_path = construct_path(api_path);
|
auto file_path = construct_path(api_path);
|
||||||
const auto parent_api_path = utils::path::get_parent_api_path(api_path);
|
auto parent_api_path = utils::path::get_parent_api_path(api_path);
|
||||||
|
|
||||||
r_stat = {};
|
r_stat = {};
|
||||||
|
|
||||||
@ -560,8 +562,8 @@ auto remote_server::fuse_getxtimes(const char *path,
|
|||||||
-> packet::error_type {
|
-> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
const auto api_path = utils::path::create_api_path(path);
|
auto api_path = utils::path::create_api_path(path);
|
||||||
const auto file_path = construct_path(path);
|
auto file_path = construct_path(path);
|
||||||
|
|
||||||
auto ret = -EACCES;
|
auto ret = -EACCES;
|
||||||
if (drive_.check_parent_access(api_path, X_OK) == api_error::success) {
|
if (drive_.check_parent_access(api_path, X_OK) == api_error::success) {
|
||||||
@ -608,8 +610,8 @@ auto remote_server::fuse_mkdir(const char *path, const remote::file_mode &mode)
|
|||||||
-> packet::error_type {
|
-> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
const auto file_path = construct_path(path);
|
auto file_path = construct_path(path);
|
||||||
const auto res = mkdir(file_path.c_str(), mode);
|
auto res = mkdir(file_path.c_str(), mode);
|
||||||
auto ret = ((res < 0) ? -errno : 0);
|
auto ret = ((res < 0) ? -errno : 0);
|
||||||
RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, ret);
|
RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, ret);
|
||||||
return ret;
|
return ret;
|
||||||
@ -620,9 +622,9 @@ auto remote_server::fuse_open(const char *path, const remote::open_flags &flags,
|
|||||||
-> packet::error_type {
|
-> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
const auto file_path = construct_path(path);
|
auto file_path = construct_path(path);
|
||||||
const auto res = open(file_path.c_str(),
|
auto res = open(file_path.c_str(),
|
||||||
static_cast<int>(remote::create_os_open_flags(flags)));
|
static_cast<int>(remote::create_os_open_flags(flags)));
|
||||||
if (res >= 0) {
|
if (res >= 0) {
|
||||||
handle = static_cast<remote::file_handle>(res);
|
handle = static_cast<remote::file_handle>(res);
|
||||||
set_open_info(res, open_info{
|
set_open_info(res, open_info{
|
||||||
@ -641,7 +643,7 @@ auto remote_server::fuse_opendir(const char *path, remote::file_handle &handle)
|
|||||||
-> packet::error_type {
|
-> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
const auto file_path = construct_path(path);
|
auto file_path = construct_path(path);
|
||||||
|
|
||||||
auto res = -1;
|
auto res = -1;
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
@ -669,7 +671,7 @@ auto remote_server::fuse_read(const char *path, char *buffer,
|
|||||||
-> packet::error_type {
|
-> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
const auto file_path = construct_path(path);
|
auto file_path = construct_path(path);
|
||||||
auto &data = *reinterpret_cast<data_buffer *>(buffer);
|
auto &data = *reinterpret_cast<data_buffer *>(buffer);
|
||||||
|
|
||||||
ssize_t bytes_read{has_open_info(static_cast<native_handle>(handle), EBADF)};
|
ssize_t bytes_read{has_open_info(static_cast<native_handle>(handle), EBADF)};
|
||||||
@ -691,9 +693,9 @@ auto remote_server::fuse_rename(const char *from, const char *to)
|
|||||||
-> packet::error_type {
|
-> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
const auto from_path = utils::path::combine(mount_location_, {from});
|
auto from_path = utils::path::combine(mount_location_, {from});
|
||||||
const auto to_path = utils::path::combine(mount_location_, {to});
|
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());
|
||||||
auto ret = ((res < 0) ? -errno : 0);
|
auto ret = ((res < 0) ? -errno : 0);
|
||||||
RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, from + std::string("|") + to,
|
RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, from + std::string("|") + to,
|
||||||
ret);
|
ret);
|
||||||
@ -706,7 +708,7 @@ auto remote_server::fuse_readdir(const char *path,
|
|||||||
std::string &item_path) -> packet::error_type {
|
std::string &item_path) -> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
const auto file_path = construct_path(path);
|
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;
|
||||||
@ -733,7 +735,7 @@ auto remote_server::fuse_release(const char *path,
|
|||||||
|
|
||||||
packet::error_type ret = 0;
|
packet::error_type ret = 0;
|
||||||
|
|
||||||
const auto file_path = construct_path(path);
|
auto file_path = construct_path(path);
|
||||||
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) {
|
||||||
res = close(static_cast<native_handle>(handle));
|
res = close(static_cast<native_handle>(handle));
|
||||||
@ -750,7 +752,7 @@ auto remote_server::fuse_releasedir(const char *path,
|
|||||||
-> packet::error_type {
|
-> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
const auto file_path = construct_path(path);
|
auto file_path = construct_path(path);
|
||||||
|
|
||||||
directory_cache_.remove_directory(handle);
|
directory_cache_.remove_directory(handle);
|
||||||
|
|
||||||
@ -771,8 +773,8 @@ removexattr(file_path.c_str(), name); #endif auto ret = ((res < 0) ? -errno :
|
|||||||
auto remote_server::fuse_rmdir(const char *path) -> packet::error_type {
|
auto remote_server::fuse_rmdir(const char *path) -> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
const auto file_path = construct_path(path);
|
auto file_path = construct_path(path);
|
||||||
const auto res = rmdir(file_path.c_str());
|
auto res = rmdir(file_path.c_str());
|
||||||
if (res == 0) {
|
if (res == 0) {
|
||||||
directory_cache_.remove_directory(utils::path::create_api_path(path));
|
directory_cache_.remove_directory(utils::path::create_api_path(path));
|
||||||
}
|
}
|
||||||
@ -785,7 +787,7 @@ auto remote_server::fuse_setattr_x(const char *path, remote::setattr_x &attr)
|
|||||||
-> packet::error_type {
|
-> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
const auto file_path = construct_path(path);
|
auto file_path = construct_path(path);
|
||||||
auto ret = fuse_fsetattr_x(
|
auto ret = fuse_fsetattr_x(
|
||||||
path, attr, static_cast<remote::file_handle>(REPERTORY_INVALID_HANDLE));
|
path, attr, static_cast<remote::file_handle>(REPERTORY_INVALID_HANDLE));
|
||||||
RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, ret);
|
RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, ret);
|
||||||
@ -797,8 +799,8 @@ auto remote_server::fuse_setbkuptime(const char *path,
|
|||||||
-> packet::error_type {
|
-> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
const auto api_path = utils::path::create_api_path(path);
|
auto api_path = utils::path::create_api_path(path);
|
||||||
const auto file_path = construct_path(path);
|
auto file_path = construct_path(path);
|
||||||
|
|
||||||
auto ret = -EACCES;
|
auto ret = -EACCES;
|
||||||
if (drive_.check_parent_access(api_path, X_OK) == api_error::success) {
|
if (drive_.check_parent_access(api_path, X_OK) == api_error::success) {
|
||||||
@ -818,8 +820,8 @@ auto remote_server::fuse_setchgtime(const char *path,
|
|||||||
-> packet::error_type {
|
-> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
const auto api_path = utils::path::create_api_path(path);
|
auto api_path = utils::path::create_api_path(path);
|
||||||
const auto file_path = construct_path(path);
|
auto file_path = construct_path(path);
|
||||||
|
|
||||||
auto ret = -EACCES;
|
auto ret = -EACCES;
|
||||||
if (drive_.check_parent_access(api_path, X_OK) == api_error::success) {
|
if (drive_.check_parent_access(api_path, X_OK) == api_error::success) {
|
||||||
@ -839,8 +841,8 @@ auto remote_server::fuse_setcrtime(const char *path,
|
|||||||
-> packet::error_type {
|
-> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
const auto api_path = utils::path::create_api_path(path);
|
auto api_path = utils::path::create_api_path(path);
|
||||||
const auto file_path = construct_path(path);
|
auto file_path = construct_path(path);
|
||||||
|
|
||||||
auto ret = -EACCES;
|
auto ret = -EACCES;
|
||||||
if (drive_.check_parent_access(api_path, X_OK) == api_error::success) {
|
if (drive_.check_parent_access(api_path, X_OK) == api_error::success) {
|
||||||
@ -886,11 +888,11 @@ auto remote_server::fuse_statfs(const char *path, std::uint64_t frsize,
|
|||||||
remote::statfs &r_stat) -> packet::error_type {
|
remote::statfs &r_stat) -> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
const auto file_path = construct_path(path);
|
auto file_path = construct_path(path);
|
||||||
|
|
||||||
const auto total_bytes = drive_.get_total_drive_space();
|
auto total_bytes = drive_.get_total_drive_space();
|
||||||
const auto total_used = drive_.get_used_drive_space();
|
auto total_used = drive_.get_used_drive_space();
|
||||||
const auto used_blocks = utils::divide_with_ceiling(total_used, frsize);
|
auto used_blocks = utils::divide_with_ceiling(total_used, frsize);
|
||||||
r_stat.f_files = 4294967295;
|
r_stat.f_files = 4294967295;
|
||||||
r_stat.f_blocks = utils::divide_with_ceiling(total_bytes, frsize);
|
r_stat.f_blocks = utils::divide_with_ceiling(total_bytes, frsize);
|
||||||
r_stat.f_bavail = r_stat.f_bfree =
|
r_stat.f_bavail = r_stat.f_bfree =
|
||||||
@ -907,11 +909,11 @@ auto remote_server::fuse_statfs_x(const char *path, std::uint64_t bsize,
|
|||||||
-> packet::error_type {
|
-> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
const auto file_path = construct_path(path);
|
auto file_path = construct_path(path);
|
||||||
|
|
||||||
const auto total_bytes = drive_.get_total_drive_space();
|
auto total_bytes = drive_.get_total_drive_space();
|
||||||
const auto total_used = drive_.get_used_drive_space();
|
auto total_used = drive_.get_used_drive_space();
|
||||||
const auto used_blocks = utils::divide_with_ceiling(total_used, bsize);
|
auto used_blocks = utils::divide_with_ceiling(total_used, bsize);
|
||||||
r_stat.f_files = 4294967295;
|
r_stat.f_files = 4294967295;
|
||||||
r_stat.f_blocks = utils::divide_with_ceiling(total_bytes, bsize);
|
r_stat.f_blocks = utils::divide_with_ceiling(total_bytes, bsize);
|
||||||
r_stat.f_bavail = r_stat.f_bfree =
|
r_stat.f_bavail = r_stat.f_bfree =
|
||||||
@ -932,8 +934,8 @@ auto remote_server::fuse_truncate(const char *path,
|
|||||||
-> packet::error_type {
|
-> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
const auto file_path = construct_path(path);
|
auto file_path = construct_path(path);
|
||||||
const auto res = truncate(file_path.c_str(), static_cast<off_t>(size));
|
auto res = truncate(file_path.c_str(), static_cast<off_t>(size));
|
||||||
auto ret = ((res < 0) ? -errno : 0);
|
auto ret = ((res < 0) ? -errno : 0);
|
||||||
RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, ret);
|
RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, ret);
|
||||||
return ret;
|
return ret;
|
||||||
@ -942,8 +944,8 @@ auto remote_server::fuse_truncate(const char *path,
|
|||||||
auto remote_server::fuse_unlink(const char *path) -> packet::error_type {
|
auto remote_server::fuse_unlink(const char *path) -> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
const auto file_path = construct_path(path);
|
auto file_path = construct_path(path);
|
||||||
const auto res = unlink(file_path.c_str());
|
auto res = unlink(file_path.c_str());
|
||||||
auto ret = ((res < 0) ? -errno : 0);
|
auto ret = ((res < 0) ? -errno : 0);
|
||||||
RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, ret);
|
RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, ret);
|
||||||
return ret;
|
return ret;
|
||||||
@ -954,7 +956,7 @@ auto remote_server::fuse_utimens(const char *path, const remote::file_time *tv,
|
|||||||
-> packet::error_type {
|
-> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
const auto file_path = construct_path(path);
|
auto file_path = construct_path(path);
|
||||||
|
|
||||||
struct timespec tv2[2] = {{0, 0}};
|
struct timespec tv2[2] = {{0, 0}};
|
||||||
const auto process_timespec = [](auto op, const auto &src, auto &dst) {
|
const auto process_timespec = [](auto op, const auto &src, auto &dst) {
|
||||||
@ -971,8 +973,7 @@ auto remote_server::fuse_utimens(const char *path, const remote::file_time *tv,
|
|||||||
process_timespec(op0, tv[0U], tv2[0U]);
|
process_timespec(op0, tv[0U], tv2[0U]);
|
||||||
process_timespec(op1, tv[1U], tv2[1U]);
|
process_timespec(op1, tv[1U], tv2[1U]);
|
||||||
|
|
||||||
const auto res =
|
auto res = utimensat(0, file_path.c_str(), &tv2[0U], AT_SYMLINK_NOFOLLOW);
|
||||||
utimensat(0, file_path.c_str(), &tv2[0U], AT_SYMLINK_NOFOLLOW);
|
|
||||||
auto ret = ((res < 0) ? -errno : 0);
|
auto ret = ((res < 0) ? -errno : 0);
|
||||||
RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, ret);
|
RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, ret);
|
||||||
return ret;
|
return ret;
|
||||||
@ -985,7 +986,7 @@ auto remote_server::fuse_write(const char *path, const char *buffer,
|
|||||||
-> packet::error_type {
|
-> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
const auto file_path = construct_path(path);
|
auto file_path = construct_path(path);
|
||||||
|
|
||||||
ssize_t bytes_written{
|
ssize_t bytes_written{
|
||||||
has_open_info(static_cast<native_handle>(handle), EBADF)};
|
has_open_info(static_cast<native_handle>(handle), EBADF)};
|
||||||
@ -1016,8 +1017,8 @@ auto remote_server::winfsp_can_delete(PVOID file_desc, PWSTR file_name)
|
|||||||
-> packet::error_type {
|
-> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
const auto relative_path = utils::string::to_utf8(file_name);
|
auto relative_path = utils::string::to_utf8(file_name);
|
||||||
const auto file_path = construct_path(relative_path);
|
auto file_path = construct_path(relative_path);
|
||||||
auto ret = static_cast<packet::error_type>(
|
auto ret = static_cast<packet::error_type>(
|
||||||
has_open_info(static_cast<native_handle>(
|
has_open_info(static_cast<native_handle>(
|
||||||
reinterpret_cast<remote::file_handle>(file_desc)),
|
reinterpret_cast<remote::file_handle>(file_desc)),
|
||||||
@ -1026,13 +1027,12 @@ auto remote_server::winfsp_can_delete(PVOID file_desc, PWSTR file_name)
|
|||||||
ret = static_cast<packet::error_type>(
|
ret = static_cast<packet::error_type>(
|
||||||
utils::file::directory(file_path).exists()
|
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)) == 0U
|
||||||
? STATUS_DIRECTORY_NOT_EMPTY
|
? STATUS_SUCCESS
|
||||||
: STATUS_SUCCESS
|
: STATUS_DIRECTORY_NOT_EMPTY
|
||||||
|
|
||||||
: STATUS_SUCCESS);
|
: STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, ret);
|
RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -1042,22 +1042,25 @@ auto remote_server::winfsp_cleanup(PVOID /*file_desc*/, PWSTR file_name,
|
|||||||
-> packet::error_type {
|
-> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
const auto relative_path = utils::string::to_utf8(file_name);
|
auto relative_path = utils::string::to_utf8(file_name);
|
||||||
const auto file_path = construct_path(relative_path);
|
auto file_path = construct_path(relative_path);
|
||||||
was_deleted = 0U;
|
was_deleted = 0U;
|
||||||
|
|
||||||
const auto directory = utils::file::directory(file_path).exists();
|
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_deleted = 1U;
|
was_deleted = 1U;
|
||||||
|
|
||||||
if (directory) {
|
if (directory) {
|
||||||
rmdir(file_path.c_str());
|
if (drive_.get_directory_item_count(
|
||||||
|
utils::path::create_api_path(relative_path)) == 0U) {
|
||||||
|
rmdir(file_path.c_str());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
unlink(file_path.c_str());
|
unlink(file_path.c_str());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const auto api_path = utils::path::create_api_path(relative_path);
|
auto api_path = utils::path::create_api_path(relative_path);
|
||||||
if ((flags & FileSystemBase::FspCleanupSetArchiveBit) && not directory) {
|
if ((flags & FileSystemBase::FspCleanupSetArchiveBit) && not directory) {
|
||||||
api_meta_map meta;
|
api_meta_map meta;
|
||||||
if (drive_.get_item_meta(api_path, meta) == api_error::success) {
|
if (drive_.get_item_meta(api_path, meta) == api_error::success) {
|
||||||
@ -1071,7 +1074,7 @@ auto remote_server::winfsp_cleanup(PVOID /*file_desc*/, PWSTR file_name,
|
|||||||
if (flags & (FileSystemBase::FspCleanupSetLastAccessTime |
|
if (flags & (FileSystemBase::FspCleanupSetLastAccessTime |
|
||||||
FileSystemBase::FspCleanupSetLastWriteTime |
|
FileSystemBase::FspCleanupSetLastWriteTime |
|
||||||
FileSystemBase::FspCleanupSetChangeTime)) {
|
FileSystemBase::FspCleanupSetChangeTime)) {
|
||||||
const auto file_time_now = utils::time::get_time_now();
|
auto file_time_now = utils::time::get_time_now();
|
||||||
if (flags & FileSystemBase::FspCleanupSetLastAccessTime) {
|
if (flags & FileSystemBase::FspCleanupSetLastAccessTime) {
|
||||||
drive_.set_item_meta(api_path, META_ACCESSED,
|
drive_.set_item_meta(api_path, META_ACCESSED,
|
||||||
std::to_string(file_time_now));
|
std::to_string(file_time_now));
|
||||||
@ -1100,7 +1103,7 @@ auto remote_server::winfsp_close(PVOID file_desc) -> packet::error_type {
|
|||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
std::string file_path;
|
std::string file_path;
|
||||||
const auto handle = reinterpret_cast<remote::file_handle>(file_desc);
|
auto handle = reinterpret_cast<remote::file_handle>(file_desc);
|
||||||
if (has_open_info(static_cast<native_handle>(handle),
|
if (has_open_info(static_cast<native_handle>(handle),
|
||||||
STATUS_INVALID_HANDLE) == STATUS_SUCCESS) {
|
STATUS_INVALID_HANDLE) == STATUS_SUCCESS) {
|
||||||
file_path = get_open_file_path(static_cast<native_handle>(handle));
|
file_path = get_open_file_path(static_cast<native_handle>(handle));
|
||||||
@ -1120,49 +1123,55 @@ auto remote_server::winfsp_create(PWSTR file_name, UINT32 create_options,
|
|||||||
-> packet::error_type {
|
-> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
const auto relative_path = utils::string::to_utf8(file_name);
|
auto relative_path = utils::string::to_utf8(file_name);
|
||||||
const auto file_path = construct_path(relative_path);
|
auto file_path = construct_path(relative_path);
|
||||||
exists = utils::file::file(file_path).exists();
|
exists = utils::file::file{file_path}.exists() ||
|
||||||
|
utils::file::directory{file_path}.exists()
|
||||||
if ((create_options & FILE_DIRECTORY_FILE) != 0U) {
|
? 1
|
||||||
attributes |= FILE_ATTRIBUTE_DIRECTORY;
|
: 0;
|
||||||
} else {
|
auto ret{static_cast<packet::error_type>(STATUS_SUCCESS)};
|
||||||
attributes &= static_cast<UINT32>(~FILE_ATTRIBUTE_DIRECTORY);
|
if (exists == 0U) {
|
||||||
attributes |= FILE_ATTRIBUTE_ARCHIVE;
|
if ((create_options & FILE_DIRECTORY_FILE) != 0U) {
|
||||||
}
|
attributes |= FILE_ATTRIBUTE_DIRECTORY;
|
||||||
|
} else {
|
||||||
remote::file_mode mode{0U};
|
attributes &= static_cast<UINT32>(~FILE_ATTRIBUTE_DIRECTORY);
|
||||||
std::uint32_t flags{0U};
|
attributes |= FILE_ATTRIBUTE_ARCHIVE;
|
||||||
utils::windows_create_to_unix(create_options, granted_access, flags, mode);
|
|
||||||
|
|
||||||
int res = 0;
|
|
||||||
if ((create_options & FILE_DIRECTORY_FILE) != 0U) {
|
|
||||||
res = mkdir(file_path.c_str(), mode);
|
|
||||||
if (res >= 0) {
|
|
||||||
res = open(file_path.c_str(), static_cast<int>(flags));
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
res = open(file_path.c_str(), static_cast<int>(flags), mode);
|
remote::file_mode mode{0U};
|
||||||
|
std::uint32_t flags{0U};
|
||||||
|
utils::windows_create_to_unix(create_options, granted_access, flags, mode);
|
||||||
|
|
||||||
|
auto res{0};
|
||||||
|
if ((create_options & FILE_DIRECTORY_FILE) != 0U) {
|
||||||
|
res = mkdir(file_path.c_str(), mode);
|
||||||
|
if (res >= 0) {
|
||||||
|
res = open(file_path.c_str(), static_cast<int>(flags));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
res = open(file_path.c_str(), static_cast<int>(flags), mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res >= 0) {
|
||||||
|
*file_desc = reinterpret_cast<PVOID>(res);
|
||||||
|
drive_.set_item_meta(construct_api_path(file_path), META_ATTRIBUTES,
|
||||||
|
std::to_string(attributes));
|
||||||
|
set_open_info(res, open_info{
|
||||||
|
"",
|
||||||
|
nullptr,
|
||||||
|
{},
|
||||||
|
file_path,
|
||||||
|
});
|
||||||
|
|
||||||
|
auto api_path = utils::path::create_api_path(relative_path);
|
||||||
|
normalized_name = utils::string::replace_copy(api_path, '/', '\\');
|
||||||
|
populate_file_info(api_path, 0, attributes, *file_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = static_cast<packet::error_type>(
|
||||||
|
utils::unix_error_to_windows((res < 0) ? errno : 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res >= 0) {
|
|
||||||
*file_desc = reinterpret_cast<PVOID>(res);
|
|
||||||
drive_.set_item_meta(construct_api_path(file_path), META_ATTRIBUTES,
|
|
||||||
std::to_string(attributes));
|
|
||||||
set_open_info(res, open_info{
|
|
||||||
"",
|
|
||||||
nullptr,
|
|
||||||
{},
|
|
||||||
file_path,
|
|
||||||
});
|
|
||||||
|
|
||||||
const auto api_path = utils::path::create_api_path(relative_path);
|
|
||||||
normalized_name = utils::string::replace_copy(api_path, '/', '\\');
|
|
||||||
populate_file_info(api_path, 0, attributes, *file_info);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto ret = static_cast<packet::error_type>(
|
|
||||||
utils::unix_error_to_windows((res < 0) ? errno : 0));
|
|
||||||
RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, ret);
|
RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -1171,7 +1180,7 @@ auto remote_server::winfsp_flush(PVOID file_desc, remote::file_info *file_info)
|
|||||||
-> packet::error_type {
|
-> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
const auto handle = reinterpret_cast<remote::file_handle>(file_desc);
|
auto handle = reinterpret_cast<remote::file_handle>(file_desc);
|
||||||
auto ret = static_cast<packet::error_type>(
|
auto ret = static_cast<packet::error_type>(
|
||||||
has_open_info(static_cast<native_handle>(handle), STATUS_INVALID_HANDLE));
|
has_open_info(static_cast<native_handle>(handle), STATUS_INVALID_HANDLE));
|
||||||
if (ret == STATUS_SUCCESS) {
|
if (ret == STATUS_SUCCESS) {
|
||||||
@ -1194,7 +1203,7 @@ auto remote_server::winfsp_get_file_info(PVOID file_desc,
|
|||||||
-> packet::error_type {
|
-> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
const auto handle = reinterpret_cast<remote::file_handle>(file_desc);
|
auto handle = reinterpret_cast<remote::file_handle>(file_desc);
|
||||||
auto ret = static_cast<packet::error_type>(
|
auto ret = static_cast<packet::error_type>(
|
||||||
has_open_info(static_cast<native_handle>(handle), STATUS_INVALID_HANDLE));
|
has_open_info(static_cast<native_handle>(handle), STATUS_INVALID_HANDLE));
|
||||||
if (ret == STATUS_SUCCESS) {
|
if (ret == STATUS_SUCCESS) {
|
||||||
@ -1216,7 +1225,7 @@ auto remote_server::winfsp_get_security_by_name(
|
|||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_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);
|
auto file_path = construct_path(file_name);
|
||||||
if (utils::file::file(file_path).exists() ||
|
if (utils::file::file(file_path).exists() ||
|
||||||
(utils::file::directory(file_path).exists())) {
|
(utils::file::directory(file_path).exists())) {
|
||||||
if (attributes) {
|
if (attributes) {
|
||||||
@ -1261,9 +1270,9 @@ auto remote_server::winfsp_open(PWSTR file_name, UINT32 create_options,
|
|||||||
-> packet::error_type {
|
-> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
const auto relative_path = utils::string::to_utf8(file_name);
|
auto relative_path = utils::string::to_utf8(file_name);
|
||||||
const auto file_path = construct_path(relative_path);
|
auto file_path = construct_path(relative_path);
|
||||||
const auto directory = utils::file::directory(file_path).exists();
|
auto directory = utils::file::directory(file_path).exists();
|
||||||
if (directory) {
|
if (directory) {
|
||||||
create_options |= FILE_DIRECTORY_FILE;
|
create_options |= FILE_DIRECTORY_FILE;
|
||||||
}
|
}
|
||||||
@ -1283,7 +1292,7 @@ auto remote_server::winfsp_open(PWSTR file_name, UINT32 create_options,
|
|||||||
file_path,
|
file_path,
|
||||||
});
|
});
|
||||||
|
|
||||||
const auto api_path = utils::path::create_api_path(relative_path);
|
auto api_path = utils::path::create_api_path(relative_path);
|
||||||
normalized_name = utils::string::replace_copy(api_path, '/', '\\');
|
normalized_name = utils::string::replace_copy(api_path, '/', '\\');
|
||||||
res = populate_file_info(api_path, *file_info);
|
res = populate_file_info(api_path, *file_info);
|
||||||
if (res != STATUS_SUCCESS) {
|
if (res != STATUS_SUCCESS) {
|
||||||
@ -1306,20 +1315,20 @@ auto remote_server::winfsp_overwrite(PVOID file_desc, UINT32 attributes,
|
|||||||
-> packet::error_type {
|
-> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
const auto handle = reinterpret_cast<remote::file_handle>(file_desc);
|
auto handle = reinterpret_cast<remote::file_handle>(file_desc);
|
||||||
auto ret = static_cast<packet::error_type>(
|
auto ret = static_cast<packet::error_type>(
|
||||||
has_open_info(static_cast<native_handle>(handle), STATUS_INVALID_HANDLE));
|
has_open_info(static_cast<native_handle>(handle), STATUS_INVALID_HANDLE));
|
||||||
if (ret == STATUS_SUCCESS) {
|
if (ret == STATUS_SUCCESS) {
|
||||||
const auto api_path = construct_api_path(
|
auto api_path = construct_api_path(
|
||||||
get_open_file_path(static_cast<native_handle>(handle)));
|
get_open_file_path(static_cast<native_handle>(handle)));
|
||||||
const auto res = ftruncate(static_cast<native_handle>(handle), 0);
|
auto res = ftruncate(static_cast<native_handle>(handle), 0);
|
||||||
if (res >= 0) {
|
if (res >= 0) {
|
||||||
auto set_attributes = false;
|
auto set_attributes = false;
|
||||||
if (replace_attributes) {
|
if (replace_attributes) {
|
||||||
set_attributes = true;
|
set_attributes = true;
|
||||||
} else if (attributes) {
|
} else if (attributes) {
|
||||||
std::string current_attributes;
|
std::string current_attributes;
|
||||||
const auto err =
|
auto err =
|
||||||
drive_.get_item_meta(api_path, META_ATTRIBUTES, current_attributes);
|
drive_.get_item_meta(api_path, META_ATTRIBUTES, current_attributes);
|
||||||
if (err != api_error::success) {
|
if (err != api_error::success) {
|
||||||
utils::error::raise_api_path_error(function_name, api_path, err,
|
utils::error::raise_api_path_error(function_name, api_path, err,
|
||||||
@ -1361,16 +1370,19 @@ auto remote_server::winfsp_read(PVOID file_desc, PVOID buffer, UINT64 offset,
|
|||||||
-> packet::error_type {
|
-> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
*bytes_transferred = 0;
|
*bytes_transferred = 0U;
|
||||||
|
|
||||||
const auto handle = reinterpret_cast<remote::file_handle>(file_desc);
|
auto handle = reinterpret_cast<remote::file_handle>(file_desc);
|
||||||
auto ret = static_cast<packet::error_type>(
|
auto ret = static_cast<packet::error_type>(
|
||||||
has_open_info(static_cast<native_handle>(handle), STATUS_INVALID_HANDLE));
|
has_open_info(static_cast<native_handle>(handle), STATUS_INVALID_HANDLE));
|
||||||
if (ret == STATUS_SUCCESS) {
|
if (ret == STATUS_SUCCESS) {
|
||||||
const auto res = pread64(static_cast<native_handle>(handle), buffer, length,
|
auto res = pread64(static_cast<native_handle>(handle), buffer, length,
|
||||||
static_cast<off_t>(offset));
|
static_cast<off_t>(offset));
|
||||||
if (res >= 0) {
|
if (res >= 0) {
|
||||||
*bytes_transferred = static_cast<UINT32>(res);
|
*bytes_transferred = static_cast<UINT32>(res);
|
||||||
|
if (*bytes_transferred == 0U) {
|
||||||
|
ret = static_cast<packet::error_type>(STATUS_END_OF_FILE);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ret =
|
ret =
|
||||||
static_cast<packet::error_type>(utils::unix_error_to_windows(errno));
|
static_cast<packet::error_type>(utils::unix_error_to_windows(errno));
|
||||||
@ -1390,11 +1402,11 @@ auto remote_server::winfsp_read_directory(PVOID file_desc, PWSTR /*pattern*/,
|
|||||||
|
|
||||||
item_list.clear();
|
item_list.clear();
|
||||||
|
|
||||||
const auto handle = reinterpret_cast<remote::file_handle>(file_desc);
|
auto handle = reinterpret_cast<remote::file_handle>(file_desc);
|
||||||
auto ret = static_cast<packet::error_type>(
|
auto ret = static_cast<packet::error_type>(
|
||||||
has_open_info(static_cast<native_handle>(handle), STATUS_INVALID_HANDLE));
|
has_open_info(static_cast<native_handle>(handle), STATUS_INVALID_HANDLE));
|
||||||
if (ret == STATUS_SUCCESS) {
|
if (ret == STATUS_SUCCESS) {
|
||||||
const auto api_path = construct_api_path(
|
auto api_path = construct_api_path(
|
||||||
get_open_file_path(static_cast<native_handle>(handle)));
|
get_open_file_path(static_cast<native_handle>(handle)));
|
||||||
directory_iterator iterator(drive_.get_directory_items(api_path));
|
directory_iterator iterator(drive_.get_directory_items(api_path));
|
||||||
auto offset = marker == nullptr
|
auto offset = marker == nullptr
|
||||||
@ -1405,7 +1417,7 @@ auto remote_server::winfsp_read_directory(PVOID file_desc, PWSTR /*pattern*/,
|
|||||||
json item;
|
json item;
|
||||||
while (iterator.get_json(offset++, item) == 0) {
|
while (iterator.get_json(offset++, item) == 0) {
|
||||||
try {
|
try {
|
||||||
item_list.emplace_back(update_to_windows_format(item));
|
item_list.emplace_back(update_to_windows_format(api_path, item));
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
utils::error::raise_error(function_name, e, "exception occurred");
|
utils::error::raise_error(function_name, e, "exception occurred");
|
||||||
}
|
}
|
||||||
@ -1425,25 +1437,40 @@ auto remote_server::winfsp_rename(PVOID /*file_desc*/, PWSTR file_name,
|
|||||||
-> packet::error_type {
|
-> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
const auto relative_path = utils::string::to_utf8(file_name);
|
auto relative_path = utils::string::to_utf8(file_name);
|
||||||
const auto file_path = construct_path(relative_path);
|
auto file_path = construct_path(relative_path);
|
||||||
const auto new_relative_path = utils::string::to_utf8(new_file_name);
|
auto new_relative_path = utils::string::to_utf8(new_file_name);
|
||||||
const auto new_file_path = construct_path(new_relative_path);
|
auto new_file_path = construct_path(new_relative_path);
|
||||||
|
|
||||||
auto res = -1;
|
packet::error_type ret{};
|
||||||
|
auto res{-1};
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
if (utils::file::file(file_path).exists()) {
|
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::directory(file_path).exists()) {
|
ret = ((res < 0) ? static_cast<packet::error_type>(
|
||||||
res = drive_.rename_directory(construct_api_path(file_path),
|
utils::unix_error_to_windows(errno))
|
||||||
construct_api_path(new_file_path));
|
: 0);
|
||||||
|
} else {
|
||||||
|
auto dir{utils::file::directory(file_path)};
|
||||||
|
if (dir.exists()) {
|
||||||
|
auto count{dir.count(false)};
|
||||||
|
if (count == 0U) {
|
||||||
|
res = drive_.rename_directory(construct_api_path(file_path),
|
||||||
|
construct_api_path(new_file_path));
|
||||||
|
ret = ((res < 0)
|
||||||
|
? errno == EISDIR
|
||||||
|
? static_cast<packet::error_type>(STATUS_ACCESS_DENIED)
|
||||||
|
: static_cast<packet::error_type>(
|
||||||
|
utils::unix_error_to_windows(errno))
|
||||||
|
: 0);
|
||||||
|
} else {
|
||||||
|
ret = static_cast<packet::error_type>(STATUS_ACCESS_DENIED);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ret = ((res < 0) ? static_cast<packet::error_type>(
|
|
||||||
utils::unix_error_to_windows(errno))
|
|
||||||
: 0);
|
|
||||||
RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path + "|" + new_file_path,
|
RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path + "|" + new_file_path,
|
||||||
ret);
|
ret);
|
||||||
return ret;
|
return ret;
|
||||||
@ -1455,12 +1482,11 @@ auto remote_server::winfsp_set_basic_info(
|
|||||||
remote::file_info *file_info) -> packet::error_type {
|
remote::file_info *file_info) -> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
const auto handle = reinterpret_cast<remote::file_handle>(file_desc);
|
auto handle = reinterpret_cast<remote::file_handle>(file_desc);
|
||||||
auto ret = static_cast<packet::error_type>(
|
auto ret = static_cast<packet::error_type>(
|
||||||
has_open_info(static_cast<native_handle>(handle), STATUS_INVALID_HANDLE));
|
has_open_info(static_cast<native_handle>(handle), STATUS_INVALID_HANDLE));
|
||||||
if (ret == STATUS_SUCCESS) {
|
if (ret == STATUS_SUCCESS) {
|
||||||
const auto file_path =
|
auto file_path = get_open_file_path(static_cast<native_handle>(handle));
|
||||||
get_open_file_path(static_cast<native_handle>(handle));
|
|
||||||
if (attributes == INVALID_FILE_ATTRIBUTES) {
|
if (attributes == INVALID_FILE_ATTRIBUTES) {
|
||||||
attributes = 0;
|
attributes = 0;
|
||||||
} else if (attributes == 0) {
|
} else if (attributes == 0) {
|
||||||
@ -1469,7 +1495,7 @@ auto remote_server::winfsp_set_basic_info(
|
|||||||
: FILE_ATTRIBUTE_ARCHIVE;
|
: FILE_ATTRIBUTE_ARCHIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto api_path = construct_api_path(file_path);
|
auto api_path = construct_api_path(file_path);
|
||||||
api_meta_map meta;
|
api_meta_map meta;
|
||||||
if (attributes != 0U) {
|
if (attributes != 0U) {
|
||||||
attributes &= static_cast<UINT32>(~FILE_ATTRIBUTE_NORMAL);
|
attributes &= static_cast<UINT32>(~FILE_ATTRIBUTE_NORMAL);
|
||||||
@ -1522,14 +1548,14 @@ auto remote_server::winfsp_set_file_size(PVOID file_desc, UINT64 new_size,
|
|||||||
-> packet::error_type {
|
-> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
const auto handle = reinterpret_cast<remote::file_handle>(file_desc);
|
auto handle = reinterpret_cast<remote::file_handle>(file_desc);
|
||||||
auto ret = static_cast<packet::error_type>(
|
auto ret = static_cast<packet::error_type>(
|
||||||
has_open_info(static_cast<native_handle>(handle), STATUS_INVALID_HANDLE));
|
has_open_info(static_cast<native_handle>(handle), STATUS_INVALID_HANDLE));
|
||||||
if (ret == STATUS_SUCCESS) {
|
if (ret == STATUS_SUCCESS) {
|
||||||
const auto res = set_allocation_size == 0U
|
auto res = set_allocation_size == 0U
|
||||||
? ftruncate(static_cast<native_handle>(handle),
|
? ftruncate(static_cast<native_handle>(handle),
|
||||||
static_cast<off_t>(new_size))
|
static_cast<off_t>(new_size))
|
||||||
: 0;
|
: 0;
|
||||||
ret = ((res < 0) ? static_cast<packet::error_type>(
|
ret = ((res < 0) ? static_cast<packet::error_type>(
|
||||||
utils::unix_error_to_windows(errno))
|
utils::unix_error_to_windows(errno))
|
||||||
: 0);
|
: 0);
|
||||||
@ -1563,14 +1589,15 @@ auto remote_server::winfsp_write(PVOID file_desc, PVOID buffer, UINT64 offset,
|
|||||||
-> packet::error_type {
|
-> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
*bytes_transferred = 0;
|
*bytes_transferred = 0U;
|
||||||
const auto handle = reinterpret_cast<remote::file_handle>(file_desc);
|
|
||||||
|
auto handle = reinterpret_cast<remote::file_handle>(file_desc);
|
||||||
auto ret = static_cast<packet::error_type>(
|
auto ret = static_cast<packet::error_type>(
|
||||||
has_open_info(static_cast<native_handle>(handle), STATUS_INVALID_HANDLE));
|
has_open_info(static_cast<native_handle>(handle), STATUS_INVALID_HANDLE));
|
||||||
if (ret == STATUS_SUCCESS) {
|
if (ret == STATUS_SUCCESS) {
|
||||||
const auto api_path = construct_api_path(
|
auto api_path = construct_api_path(
|
||||||
get_open_file_path(static_cast<native_handle>(handle)));
|
get_open_file_path(static_cast<native_handle>(handle)));
|
||||||
const auto file_size = drive_.get_file_size(api_path);
|
auto file_size = drive_.get_file_size(api_path);
|
||||||
if (write_to_end != 0U) {
|
if (write_to_end != 0U) {
|
||||||
offset = file_size;
|
offset = file_size;
|
||||||
}
|
}
|
||||||
@ -1587,8 +1614,8 @@ auto remote_server::winfsp_write(PVOID file_desc, PVOID buffer, UINT64 offset,
|
|||||||
|
|
||||||
if (should_write) {
|
if (should_write) {
|
||||||
if (length > 0) {
|
if (length > 0) {
|
||||||
const auto res = pwrite64(static_cast<native_handle>(handle), buffer,
|
auto res = pwrite64(static_cast<native_handle>(handle), buffer, length,
|
||||||
length, static_cast<off_t>(offset));
|
static_cast<off_t>(offset));
|
||||||
if (res >= 0) {
|
if (res >= 0) {
|
||||||
*bytes_transferred = static_cast<UINT32>(res);
|
*bytes_transferred = static_cast<UINT32>(res);
|
||||||
ret = populate_file_info(construct_api_path(get_open_file_path(
|
ret = populate_file_info(construct_api_path(get_open_file_path(
|
||||||
@ -1613,8 +1640,8 @@ auto remote_server::json_create_directory_snapshot(const std::string &path,
|
|||||||
-> packet::error_type {
|
-> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
const auto api_path = utils::path::create_api_path(path);
|
auto api_path = utils::path::create_api_path(path);
|
||||||
const auto file_path = construct_path(api_path);
|
auto file_path = construct_path(api_path);
|
||||||
|
|
||||||
auto res = -1;
|
auto res = -1;
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
@ -1645,7 +1672,7 @@ auto remote_server::json_read_directory_snapshot(
|
|||||||
|
|
||||||
int res{-EBADF};
|
int res{-EBADF};
|
||||||
|
|
||||||
const auto file_path = construct_path(path);
|
auto file_path = construct_path(path);
|
||||||
auto iter = directory_cache_.get_directory(handle);
|
auto iter = directory_cache_.get_directory(handle);
|
||||||
if (iter != nullptr) {
|
if (iter != nullptr) {
|
||||||
std::size_t offset{};
|
std::size_t offset{};
|
||||||
@ -1673,39 +1700,83 @@ auto remote_server::json_release_directory_snapshot(
|
|||||||
-> packet::error_type {
|
-> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
const auto file_path = construct_path(path);
|
auto file_path = construct_path(path);
|
||||||
directory_cache_.remove_directory(handle);
|
directory_cache_.remove_directory(handle);
|
||||||
RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, 0);
|
RAISE_REMOTE_FUSE_SERVER_EVENT(function_name, file_path, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto remote_server::update_to_windows_format(json &item) -> json & {
|
auto remote_server::update_to_windows_format(const std::string &root_api_path,
|
||||||
const auto api_path = item["path"].get<std::string>();
|
json &item) -> json & {
|
||||||
item["meta"][META_ACCESSED] = std::to_string(
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
utils::string::to_uint64(empty_as_zero(item["meta"][META_ACCESSED])));
|
|
||||||
item["meta"][META_CREATION] = std::to_string(
|
|
||||||
utils::string::to_uint64(empty_as_zero(item["meta"][META_CREATION])));
|
|
||||||
item["meta"][META_MODIFIED] = std::to_string(
|
|
||||||
utils::string::to_uint64(empty_as_zero(item["meta"][META_MODIFIED])));
|
|
||||||
|
|
||||||
if (item["meta"][META_WRITTEN].empty() ||
|
auto api_path = item[JSON_API_PATH].get<std::string>();
|
||||||
(item["meta"][META_WRITTEN].get<std::string>() == "0") ||
|
if (api_path == "." || api_path == "..") {
|
||||||
(item["meta"][META_WRITTEN].get<std::string>() ==
|
auto orig_api_path{api_path};
|
||||||
std::to_string(utils::time::WIN32_TIME_CONVERSION))) {
|
|
||||||
drive_.set_item_meta(api_path, META_WRITTEN,
|
api_path = api_path == "."
|
||||||
item["meta"][META_MODIFIED].get<std::string>());
|
? root_api_path
|
||||||
item["meta"][META_WRITTEN] = item["meta"][META_MODIFIED];
|
: utils::path::get_parent_api_path(root_api_path);
|
||||||
|
|
||||||
|
api_meta_map meta;
|
||||||
|
auto res = drive_.get_item_meta(api_path, meta);
|
||||||
|
if (res != api_error::success) {
|
||||||
|
utils::error::raise_api_path_error(
|
||||||
|
function_name, api_path, res,
|
||||||
|
fmt::format("failed to get '{}' meta", orig_api_path));
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
item[JSON_DIRECTORY] = true;
|
||||||
|
meta[META_DIRECTORY] = utils::string::from_bool(true);
|
||||||
|
item[JSON_META] = meta;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item["meta"][META_ATTRIBUTES].empty()) {
|
item[JSON_META][META_ACCESSED] = std::to_string(
|
||||||
item["meta"][META_ATTRIBUTES] =
|
utils::string::to_uint64(empty_as_zero(item[JSON_META][META_ACCESSED])));
|
||||||
item["directory"].get<bool>() ? std::to_string(FILE_ATTRIBUTE_DIRECTORY)
|
item[JSON_META][META_CREATION] = std::to_string(
|
||||||
: std::to_string(FILE_ATTRIBUTE_ARCHIVE);
|
utils::string::to_uint64(empty_as_zero(item[JSON_META][META_CREATION])));
|
||||||
drive_.set_item_meta(api_path, META_ATTRIBUTES,
|
item[JSON_META][META_MODIFIED] = std::to_string(
|
||||||
item["meta"][META_ATTRIBUTES].get<std::string>());
|
utils::string::to_uint64(empty_as_zero(item[JSON_META][META_MODIFIED])));
|
||||||
|
|
||||||
|
auto update_meta{false};
|
||||||
|
if (item[JSON_META][META_WRITTEN].empty() ||
|
||||||
|
(item[JSON_META][META_WRITTEN].get<std::string>() == "0") ||
|
||||||
|
(item[JSON_META][META_WRITTEN].get<std::string>() ==
|
||||||
|
std::to_string(utils::time::WIN32_TIME_CONVERSION))) {
|
||||||
|
item[JSON_META][META_WRITTEN] =
|
||||||
|
item[JSON_META][META_MODIFIED].get<std::string>();
|
||||||
|
update_meta = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item[JSON_META][META_ATTRIBUTES].empty()) {
|
||||||
|
item[JSON_META][META_ATTRIBUTES] = "0";
|
||||||
|
}
|
||||||
|
|
||||||
|
auto attributes = utils::string::to_uint32(
|
||||||
|
item[JSON_META][META_ATTRIBUTES].get<std::string>());
|
||||||
|
if (item[JSON_DIRECTORY].get<bool>()) {
|
||||||
|
if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY) {
|
||||||
|
attributes |= FILE_ATTRIBUTE_DIRECTORY;
|
||||||
|
attributes &= static_cast<std::uint32_t>(~FILE_ATTRIBUTE_ARCHIVE);
|
||||||
|
item[JSON_META][META_ATTRIBUTES] = std::to_string(attributes);
|
||||||
|
update_meta = true;
|
||||||
|
}
|
||||||
|
} else if ((attributes & FILE_ATTRIBUTE_DIRECTORY) ==
|
||||||
|
FILE_ATTRIBUTE_DIRECTORY ||
|
||||||
|
attributes == 0U) {
|
||||||
|
attributes |= FILE_ATTRIBUTE_ARCHIVE;
|
||||||
|
attributes &= static_cast<std::uint32_t>(~FILE_ATTRIBUTE_DIRECTORY);
|
||||||
|
item[JSON_META][META_ATTRIBUTES] = std::to_string(attributes);
|
||||||
|
update_meta = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (update_meta) {
|
||||||
|
drive_.set_item_meta(api_path, item[JSON_META].get<api_meta_map>());
|
||||||
}
|
}
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
} // namespace repertory::remote_fuse
|
} // namespace repertory::remote_fuse
|
||||||
|
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
@ -188,7 +188,7 @@ auto remote_client::winfsp_create(PWSTR file_name, UINT32 create_options,
|
|||||||
DECODE_OR_IGNORE(&response, normalized_name);
|
DECODE_OR_IGNORE(&response, normalized_name);
|
||||||
DECODE_OR_IGNORE(&response, exists);
|
DECODE_OR_IGNORE(&response, exists);
|
||||||
|
|
||||||
if (ret == STATUS_SUCCESS) {
|
if (exists == 0U) {
|
||||||
*file_desc = reinterpret_cast<PVOID>(handle);
|
*file_desc = reinterpret_cast<PVOID>(handle);
|
||||||
set_open_info(to_handle(*file_desc),
|
set_open_info(to_handle(*file_desc),
|
||||||
open_info{
|
open_info{
|
||||||
@ -197,11 +197,6 @@ auto remote_client::winfsp_create(PWSTR file_name, UINT32 create_options,
|
|||||||
{},
|
{},
|
||||||
utils::string::to_utf8(file_name),
|
utils::string::to_utf8(file_name),
|
||||||
});
|
});
|
||||||
#if defined(_WIN32)
|
|
||||||
if (exists) {
|
|
||||||
::SetLastError(ERROR_ALREADY_EXISTS);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,7 +227,8 @@ auto remote_client::winfsp_get_dir_buffer([[maybe_unused]] PVOID file_desc,
|
|||||||
if (get_directory_buffer(reinterpret_cast<native_handle>(file_desc), ptr)) {
|
if (get_directory_buffer(reinterpret_cast<native_handle>(file_desc), ptr)) {
|
||||||
return static_cast<packet::error_type>(STATUS_SUCCESS);
|
return static_cast<packet::error_type>(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
#endif
|
#endif // defined(_WIN32)
|
||||||
|
|
||||||
return static_cast<packet::error_type>(STATUS_INVALID_HANDLE);
|
return static_cast<packet::error_type>(STATUS_INVALID_HANDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -392,6 +388,8 @@ auto remote_client::winfsp_read(PVOID file_desc, PVOID buffer, UINT64 offset,
|
|||||||
-> packet::error_type {
|
-> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
|
*bytes_transferred = 0U;
|
||||||
|
|
||||||
packet request;
|
packet request;
|
||||||
request.encode(file_desc);
|
request.encode(file_desc);
|
||||||
request.encode(offset);
|
request.encode(offset);
|
||||||
@ -403,14 +401,8 @@ auto remote_client::winfsp_read(PVOID file_desc, PVOID buffer, UINT64 offset,
|
|||||||
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) && (*bytes_transferred != 0U)) {
|
||||||
ret = response.decode(buffer, *bytes_transferred);
|
ret = response.decode(buffer, *bytes_transferred);
|
||||||
#if defined(_WIN32)
|
|
||||||
if ((ret == STATUS_SUCCESS) &&
|
|
||||||
((*bytes_transferred == 0U) || (*bytes_transferred != length))) {
|
|
||||||
::SetLastError(ERROR_HANDLE_EOF);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -529,6 +521,8 @@ auto remote_client::winfsp_write(PVOID file_desc, PVOID buffer, UINT64 offset,
|
|||||||
-> packet::error_type {
|
-> packet::error_type {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
|
*bytes_transferred = 0U;
|
||||||
|
|
||||||
packet request;
|
packet request;
|
||||||
request.encode(file_desc);
|
request.encode(file_desc);
|
||||||
request.encode(length);
|
request.encode(length);
|
||||||
|
@ -1061,7 +1061,7 @@ auto remote_server::winfsp_get_security_by_name(PWSTR file_name,
|
|||||||
auto file_path = utils::string::from_utf8(utils::path::combine(
|
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)}));
|
||||||
|
|
||||||
auto ret = STATUS_BUFFER_OVERFLOW;
|
auto ret{STATUS_BUFFER_OVERFLOW};
|
||||||
if ((descriptor_size == nullptr) ||
|
if ((descriptor_size == nullptr) ||
|
||||||
(*descriptor_size <= std::numeric_limits<SIZE_T>::max())) {
|
(*descriptor_size <= std::numeric_limits<SIZE_T>::max())) {
|
||||||
auto *descriptor = descriptor_size == nullptr
|
auto *descriptor = descriptor_size == nullptr
|
||||||
@ -1221,6 +1221,7 @@ auto remote_server::winfsp_read(PVOID file_desc, PVOID buffer, UINT64 offset,
|
|||||||
? STATUS_SUCCESS
|
? STATUS_SUCCESS
|
||||||
: FspNtStatusFromWin32(::GetLastError());
|
: FspNtStatusFromWin32(::GetLastError());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret != STATUS_SUCCESS) {
|
if (ret != STATUS_SUCCESS) {
|
||||||
RAISE_REMOTE_WINFSP_SERVER_EVENT(function_name,
|
RAISE_REMOTE_WINFSP_SERVER_EVENT(function_name,
|
||||||
get_open_file_path(file_desc), ret);
|
get_open_file_path(file_desc), ret);
|
||||||
|
@ -131,18 +131,21 @@ auto remote_winfsp_drive::Create(PWSTR file_name, UINT32 create_options,
|
|||||||
UINT64 allocation_size, PVOID * /*file_node*/,
|
UINT64 allocation_size, PVOID * /*file_node*/,
|
||||||
PVOID *file_desc, OpenFileInfo *ofi)
|
PVOID *file_desc, OpenFileInfo *ofi)
|
||||||
-> NTSTATUS {
|
-> NTSTATUS {
|
||||||
remote::file_info fi{};
|
remote::file_info f_info{};
|
||||||
std::string normalized_name;
|
std::string normalized_name;
|
||||||
BOOLEAN exists = 0;
|
BOOLEAN exists{0};
|
||||||
auto ret = remote_instance_->winfsp_create(
|
auto ret = remote_instance_->winfsp_create(
|
||||||
file_name, create_options, granted_access, attributes, allocation_size,
|
file_name, create_options, granted_access, attributes, allocation_size,
|
||||||
file_desc, &fi, normalized_name, exists);
|
file_desc, &f_info, normalized_name, exists);
|
||||||
if (ret == STATUS_SUCCESS) {
|
if (ret == STATUS_SUCCESS) {
|
||||||
set_file_info(ofi->FileInfo, fi);
|
set_file_info(ofi->FileInfo, f_info);
|
||||||
auto file_path = utils::string::from_utf8(normalized_name);
|
auto file_path = utils::string::from_utf8(normalized_name);
|
||||||
wcsncpy(ofi->NormalizedName, file_path.data(), wcslen(file_path.c_str()));
|
wcsncpy(ofi->NormalizedName, file_path.data(), wcslen(file_path.c_str()));
|
||||||
ofi->NormalizedNameSize =
|
ofi->NormalizedNameSize =
|
||||||
static_cast<UINT16>(wcslen(file_path.c_str()) * sizeof(WCHAR));
|
static_cast<UINT16>(wcslen(file_path.c_str()) * sizeof(WCHAR));
|
||||||
|
if (exists != 0U) {
|
||||||
|
ret = STATUS_OBJECT_NAME_COLLISION;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -168,24 +171,32 @@ auto remote_winfsp_drive::GetSecurityByName(PWSTR file_name, PUINT32 attributes,
|
|||||||
PSECURITY_DESCRIPTOR descriptor,
|
PSECURITY_DESCRIPTOR descriptor,
|
||||||
SIZE_T *descriptor_size)
|
SIZE_T *descriptor_size)
|
||||||
-> NTSTATUS {
|
-> NTSTATUS {
|
||||||
|
std::uint64_t sds{
|
||||||
|
(descriptor_size == nullptr) ? 0U : *descriptor_size,
|
||||||
|
};
|
||||||
|
|
||||||
std::wstring string_descriptor;
|
std::wstring string_descriptor;
|
||||||
std::uint64_t sds = (descriptor_size == nullptr) ? 0 : *descriptor_size;
|
auto ret{
|
||||||
auto ret = remote_instance_->winfsp_get_security_by_name(
|
remote_instance_->winfsp_get_security_by_name(
|
||||||
file_name, attributes, descriptor_size ? &sds : nullptr,
|
file_name, attributes, descriptor_size ? &sds : nullptr,
|
||||||
string_descriptor);
|
string_descriptor),
|
||||||
*descriptor_size = static_cast<SIZE_T>(sds);
|
};
|
||||||
if ((ret == STATUS_SUCCESS) && *descriptor_size) {
|
|
||||||
PSECURITY_DESCRIPTOR sd{nullptr};
|
if ((ret == STATUS_SUCCESS) && (descriptor_size != nullptr)) {
|
||||||
ULONG sz2{0U};
|
*descriptor_size = static_cast<SIZE_T>(sds);
|
||||||
|
|
||||||
|
PSECURITY_DESCRIPTOR desc{nullptr};
|
||||||
|
ULONG size{0U};
|
||||||
if (::ConvertStringSecurityDescriptorToSecurityDescriptorW(
|
if (::ConvertStringSecurityDescriptorToSecurityDescriptorW(
|
||||||
string_descriptor.data(), SDDL_REVISION_1, &sd, &sz2)) {
|
string_descriptor.data(), SDDL_REVISION_1, &desc, &size)) {
|
||||||
if (sz2 > *descriptor_size) {
|
if (size > *descriptor_size) {
|
||||||
ret = STATUS_BUFFER_TOO_SMALL;
|
ret = STATUS_BUFFER_TOO_SMALL;
|
||||||
} else {
|
} else {
|
||||||
::CopyMemory(descriptor, sd, sz2);
|
::CopyMemory(descriptor, desc, size);
|
||||||
}
|
}
|
||||||
*descriptor_size = sz2;
|
|
||||||
::LocalFree(sd);
|
*descriptor_size = size;
|
||||||
|
::LocalFree(desc);
|
||||||
} else {
|
} else {
|
||||||
ret = FspNtStatusFromWin32(::GetLastError());
|
ret = FspNtStatusFromWin32(::GetLastError());
|
||||||
}
|
}
|
||||||
@ -338,9 +349,14 @@ void remote_winfsp_drive::populate_file_info(const json &item,
|
|||||||
auto remote_winfsp_drive::Read(PVOID /*file_node*/, PVOID file_desc,
|
auto remote_winfsp_drive::Read(PVOID /*file_node*/, PVOID file_desc,
|
||||||
PVOID buffer, UINT64 offset, ULONG length,
|
PVOID buffer, UINT64 offset, ULONG length,
|
||||||
PULONG bytes_transferred) -> NTSTATUS {
|
PULONG bytes_transferred) -> NTSTATUS {
|
||||||
return remote_instance_->winfsp_read(
|
auto ret = remote_instance_->winfsp_read(
|
||||||
file_desc, buffer, offset, length,
|
file_desc, buffer, offset, length,
|
||||||
reinterpret_cast<PUINT32>(bytes_transferred));
|
reinterpret_cast<PUINT32>(bytes_transferred));
|
||||||
|
if ((ret == STATUS_SUCCESS) && (*bytes_transferred != length)) {
|
||||||
|
::SetLastError(ERROR_HANDLE_EOF);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto remote_winfsp_drive::ReadDirectory(PVOID /*file_node*/, PVOID file_desc,
|
auto remote_winfsp_drive::ReadDirectory(PVOID /*file_node*/, PVOID file_desc,
|
||||||
@ -361,11 +377,10 @@ auto remote_winfsp_drive::ReadDirectory(PVOID /*file_node*/, PVOID file_desc,
|
|||||||
&ret)) {
|
&ret)) {
|
||||||
auto item_found = false;
|
auto item_found = false;
|
||||||
for (const auto &item : item_list) {
|
for (const auto &item : item_list) {
|
||||||
auto item_path = item["path"].get<std::string>();
|
auto item_path = item[JSON_API_PATH].get<std::string>();
|
||||||
auto display_name = utils::string::from_utf8(
|
auto display_name = utils::string::from_utf8(
|
||||||
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)) {
|
|
||||||
union {
|
union {
|
||||||
UINT8 B[FIELD_OFFSET(FSP_FSCTL_DIR_INFO, FileNameBuf) +
|
UINT8 B[FIELD_OFFSET(FSP_FSCTL_DIR_INFO, FileNameBuf) +
|
||||||
((repertory::max_path_length + 1U) * sizeof(WCHAR))];
|
((repertory::max_path_length + 1U) * sizeof(WCHAR))];
|
||||||
@ -380,10 +395,8 @@ auto remote_winfsp_drive::ReadDirectory(PVOID /*file_node*/, PVOID file_desc,
|
|||||||
display_name.size()) *
|
display_name.size()) *
|
||||||
sizeof(WCHAR)));
|
sizeof(WCHAR)));
|
||||||
|
|
||||||
if (not item["meta"].empty() ||
|
populate_file_info(item, directory_info->FileInfo);
|
||||||
((item_path != ".") && (item_path != ".."))) {
|
|
||||||
populate_file_info(item, directory_info->FileInfo);
|
|
||||||
}
|
|
||||||
if (ret == STATUS_SUCCESS) {
|
if (ret == STATUS_SUCCESS) {
|
||||||
::wcscpy_s(&directory_info->FileNameBuf[0],
|
::wcscpy_s(&directory_info->FileNameBuf[0],
|
||||||
repertory::max_path_length, &display_name[0]);
|
repertory::max_path_length, &display_name[0]);
|
||||||
@ -394,7 +407,6 @@ auto remote_winfsp_drive::ReadDirectory(PVOID /*file_node*/, PVOID file_desc,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// }
|
|
||||||
} else {
|
} else {
|
||||||
item_found = display_name == std::wstring(marker);
|
item_found = display_name == std::wstring(marker);
|
||||||
}
|
}
|
||||||
@ -418,8 +430,13 @@ auto remote_winfsp_drive::ReadDirectory(PVOID /*file_node*/, PVOID file_desc,
|
|||||||
auto remote_winfsp_drive::Rename(PVOID /*file_node*/, PVOID file_desc,
|
auto remote_winfsp_drive::Rename(PVOID /*file_node*/, PVOID file_desc,
|
||||||
PWSTR file_name, PWSTR new_file_name,
|
PWSTR file_name, PWSTR new_file_name,
|
||||||
BOOLEAN replace_if_exists) -> NTSTATUS {
|
BOOLEAN replace_if_exists) -> NTSTATUS {
|
||||||
return remote_instance_->winfsp_rename(file_desc, file_name, new_file_name,
|
auto res = remote_instance_->winfsp_rename(file_desc, file_name,
|
||||||
replace_if_exists);
|
new_file_name, replace_if_exists);
|
||||||
|
if (res == STATUS_OBJECT_NAME_EXISTS) {
|
||||||
|
return FspNtStatusFromWin32(ERROR_ALREADY_EXISTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto remote_winfsp_drive::SetBasicInfo(PVOID /*file_node*/, PVOID file_desc,
|
auto remote_winfsp_drive::SetBasicInfo(PVOID /*file_node*/, PVOID file_desc,
|
||||||
@ -428,11 +445,11 @@ auto remote_winfsp_drive::SetBasicInfo(PVOID /*file_node*/, PVOID file_desc,
|
|||||||
UINT64 last_write_time,
|
UINT64 last_write_time,
|
||||||
UINT64 change_time, FileInfo *file_info)
|
UINT64 change_time, FileInfo *file_info)
|
||||||
-> NTSTATUS {
|
-> NTSTATUS {
|
||||||
remote::file_info fi{};
|
remote::file_info f_info{};
|
||||||
auto ret = remote_instance_->winfsp_set_basic_info(
|
auto ret = remote_instance_->winfsp_set_basic_info(
|
||||||
file_desc, attributes, creation_time, last_access_time, last_write_time,
|
file_desc, attributes, creation_time, last_access_time, last_write_time,
|
||||||
change_time, &fi);
|
change_time, &f_info);
|
||||||
set_file_info(*file_info, fi);
|
set_file_info(*file_info, f_info);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -473,7 +490,6 @@ VOID remote_winfsp_drive::Unmounted(PVOID host) {
|
|||||||
}
|
}
|
||||||
remote_instance_->winfsp_unmounted(file_system_host->MountPoint());
|
remote_instance_->winfsp_unmounted(file_system_host->MountPoint());
|
||||||
remote_instance_.reset();
|
remote_instance_.reset();
|
||||||
mount_location_ = "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto remote_winfsp_drive::Write(PVOID /*file_node*/, PVOID file_desc,
|
auto remote_winfsp_drive::Write(PVOID /*file_node*/, PVOID file_desc,
|
||||||
|
@ -1023,8 +1023,15 @@ auto winfsp_drive::Rename(PVOID /*file_node*/, PVOID /*file_desc*/,
|
|||||||
|
|
||||||
const auto handle_error = [this, &from_api_path,
|
const auto handle_error = [this, &from_api_path,
|
||||||
&to_api_path](api_error error) -> NTSTATUS {
|
&to_api_path](api_error error) -> NTSTATUS {
|
||||||
return this->handle_error(function_name, from_api_path + '|' + to_api_path,
|
auto ret = this->handle_error(
|
||||||
error, nullptr, 0U);
|
function_name, from_api_path + '|' + to_api_path, error, nullptr, 0U);
|
||||||
|
if (ret == FspNtStatusFromWin32(ERROR_FILE_EXISTS)) {
|
||||||
|
ret = FspNtStatusFromWin32(ERROR_ALREADY_EXISTS);
|
||||||
|
} else if (ret == STATUS_OBJECT_NAME_EXISTS) {
|
||||||
|
ret = STATUS_ACCESS_DENIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool exists{};
|
bool exists{};
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
#include "events/types/invalid_cache_size.hpp"
|
#include "events/types/invalid_cache_size.hpp"
|
||||||
#include "events/types/max_cache_size_reached.hpp"
|
#include "events/types/max_cache_size_reached.hpp"
|
||||||
#include "types/startup_exception.hpp"
|
#include "types/startup_exception.hpp"
|
||||||
#include "utils/file_utils.hpp"
|
#include "utils/file.hpp"
|
||||||
|
|
||||||
namespace repertory {
|
namespace repertory {
|
||||||
cache_size_mgr cache_size_mgr::instance_{};
|
cache_size_mgr cache_size_mgr::instance_{};
|
||||||
@ -49,16 +49,15 @@ auto cache_size_mgr::expand(std::uint64_t size) -> api_error {
|
|||||||
auto last_cache_size{cache_size_};
|
auto last_cache_size{cache_size_};
|
||||||
cache_size_ += size;
|
cache_size_ += size;
|
||||||
|
|
||||||
auto max_cache_size{cfg_->get_max_cache_size_bytes()};
|
|
||||||
|
|
||||||
auto cache_dir{
|
auto cache_dir{
|
||||||
utils::file::directory{cfg_->get_cache_directory()},
|
utils::file::directory{cfg_->get_cache_directory()},
|
||||||
};
|
};
|
||||||
while (not get_stop_requested() && cache_size_ > max_cache_size &&
|
while (not get_stop_requested() &&
|
||||||
|
cache_size_ > cfg_->get_max_cache_size_bytes() &&
|
||||||
cache_dir.count() > 1U) {
|
cache_dir.count() > 1U) {
|
||||||
if (last_cache_size != cache_size_) {
|
if (last_cache_size != cache_size_) {
|
||||||
event_system::instance().raise<max_cache_size_reached>(
|
event_system::instance().raise<max_cache_size_reached>(
|
||||||
cache_size_, function_name, max_cache_size);
|
cache_size_, function_name, cfg_->get_max_cache_size_bytes());
|
||||||
last_cache_size = cache_size_;
|
last_cache_size = cache_size_;
|
||||||
}
|
}
|
||||||
notify_.wait_for(lock, cache_wait_secs);
|
notify_.wait_for(lock, cache_wait_secs);
|
||||||
|
@ -122,8 +122,8 @@ open_file::open_file(std::uint64_t chunk_size, std::uint8_t chunk_timeout,
|
|||||||
|
|
||||||
open_file::~open_file() { close(); }
|
open_file::~open_file() { close(); }
|
||||||
|
|
||||||
auto open_file::adjust_cache_size(std::uint64_t file_size,
|
auto open_file::adjust_cache_size(std::uint64_t file_size, bool shrink)
|
||||||
bool shrink) -> api_error {
|
-> api_error {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
if (file_size == get_file_size()) {
|
if (file_size == get_file_size()) {
|
||||||
@ -554,6 +554,7 @@ auto open_file::read(std::size_t read_size, std::uint64_t read_offset,
|
|||||||
read_size =
|
read_size =
|
||||||
utils::calculate_read_size(get_file_size(), read_size, read_offset);
|
utils::calculate_read_size(get_file_size(), read_size, read_offset);
|
||||||
if (read_size == 0U) {
|
if (read_size == 0U) {
|
||||||
|
data.resize(0U);
|
||||||
return api_error::success;
|
return api_error::success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,6 +207,7 @@ auto ring_buffer_base::read(std::size_t read_size, std::uint64_t read_offset,
|
|||||||
read_size =
|
read_size =
|
||||||
utils::calculate_read_size(get_file_size(), read_size, read_offset);
|
utils::calculate_read_size(get_file_size(), read_size, read_offset);
|
||||||
if (read_size == 0U) {
|
if (read_size == 0U) {
|
||||||
|
data.resize(0U);
|
||||||
return api_error::success;
|
return api_error::success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,20 +314,26 @@ auto base_provider::get_directory_items(const std::string &api_path,
|
|||||||
(item1.api_path.compare(item2.api_path) < 0));
|
(item1.api_path.compare(item2.api_path) < 0));
|
||||||
});
|
});
|
||||||
|
|
||||||
list.insert(list.begin(), directory_item{
|
list.insert(list.begin(),
|
||||||
"..",
|
directory_item{
|
||||||
"",
|
"..",
|
||||||
true,
|
"",
|
||||||
0U,
|
true,
|
||||||
{},
|
0U,
|
||||||
});
|
{
|
||||||
list.insert(list.begin(), directory_item{
|
{META_DIRECTORY, utils::string::from_bool(true)},
|
||||||
".",
|
},
|
||||||
"",
|
});
|
||||||
true,
|
list.insert(list.begin(),
|
||||||
0U,
|
directory_item{
|
||||||
{},
|
".",
|
||||||
});
|
"",
|
||||||
|
true,
|
||||||
|
0U,
|
||||||
|
{
|
||||||
|
{META_DIRECTORY, utils::string::from_bool(true)},
|
||||||
|
},
|
||||||
|
});
|
||||||
return api_error::success;
|
return api_error::success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +40,6 @@
|
|||||||
#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 <spdlog/fmt/bundled/base.h>
|
|
||||||
|
|
||||||
namespace repertory {
|
namespace repertory {
|
||||||
encrypt_provider::encrypt_provider(app_config &config)
|
encrypt_provider::encrypt_provider(app_config &config)
|
||||||
@ -225,8 +224,7 @@ auto encrypt_provider::get_directory_items(const std::string &api_path,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (result == api_error::directory_not_found) {
|
if (result == api_error::directory_not_found) {
|
||||||
process_directory_entry(*dir_entry.get(), cfg,
|
process_directory_entry(*dir_entry, cfg, current_api_path);
|
||||||
current_api_path);
|
|
||||||
|
|
||||||
result = db_->get_directory_api_path(dir_entry->get_path(),
|
result = db_->get_directory_api_path(dir_entry->get_path(),
|
||||||
current_api_path);
|
current_api_path);
|
||||||
@ -247,7 +245,7 @@ auto encrypt_provider::get_directory_items(const std::string &api_path,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (result == api_error::item_not_found &&
|
if (result == api_error::item_not_found &&
|
||||||
not process_directory_entry(*dir_entry.get(), cfg,
|
not process_directory_entry(*dir_entry, cfg,
|
||||||
current_api_path)) {
|
current_api_path)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -286,20 +284,26 @@ auto encrypt_provider::get_directory_items(const std::string &api_path,
|
|||||||
(item1.api_path.compare(item2.api_path) < 0));
|
(item1.api_path.compare(item2.api_path) < 0));
|
||||||
});
|
});
|
||||||
|
|
||||||
list.insert(list.begin(), directory_item{
|
list.insert(list.begin(),
|
||||||
"..",
|
directory_item{
|
||||||
"",
|
"..",
|
||||||
true,
|
"",
|
||||||
0U,
|
true,
|
||||||
{},
|
0U,
|
||||||
});
|
{
|
||||||
list.insert(list.begin(), directory_item{
|
{META_DIRECTORY, utils::string::from_bool(true)},
|
||||||
".",
|
},
|
||||||
"",
|
});
|
||||||
true,
|
list.insert(list.begin(),
|
||||||
0U,
|
directory_item{
|
||||||
{},
|
".",
|
||||||
});
|
"",
|
||||||
|
true,
|
||||||
|
0U,
|
||||||
|
{
|
||||||
|
{META_DIRECTORY, utils::string::from_bool(true)},
|
||||||
|
},
|
||||||
|
});
|
||||||
return api_error::success;
|
return api_error::success;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -347,12 +351,12 @@ auto encrypt_provider::get_file_list(api_file_list &list,
|
|||||||
for (const auto &dir_entry : utils::file::directory{path}.get_items()) {
|
for (const auto &dir_entry : utils::file::directory{path}.get_items()) {
|
||||||
std::string api_path{};
|
std::string api_path{};
|
||||||
if (dir_entry->is_directory_item()) {
|
if (dir_entry->is_directory_item()) {
|
||||||
process_directory_entry(*dir_entry.get(), cfg, api_path);
|
process_directory_entry(*dir_entry, cfg, api_path);
|
||||||
process_directory(dir_entry->get_path());
|
process_directory(dir_entry->get_path());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (process_directory_entry(*dir_entry.get(), cfg, api_path)) {
|
if (process_directory_entry(*dir_entry, cfg, api_path)) {
|
||||||
list.emplace_back(create_api_file(
|
list.emplace_back(create_api_file(
|
||||||
api_path, dir_entry->is_directory_item(), dir_entry->get_path()));
|
api_path, dir_entry->is_directory_item(), dir_entry->get_path()));
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ auto sia_provider::check_version(std::string &required_version,
|
|||||||
std::string &returned_version) const -> bool {
|
std::string &returned_version) const -> bool {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
required_version = "2.0.0";
|
required_version = RENTERD_MIN_VERSION;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
curl::requests::http_get get{};
|
curl::requests::http_get get{};
|
||||||
@ -149,12 +149,58 @@ auto sia_provider::create_directory_impl(const std::string &api_path,
|
|||||||
return api_error::success;
|
return api_error::success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto sia_provider::create_directory_key(const std::string &api_path) const
|
||||||
|
-> api_error {
|
||||||
|
auto parent_api_path = utils::path::get_parent_api_path(api_path);
|
||||||
|
|
||||||
|
json object_list;
|
||||||
|
if (not get_object_list(parent_api_path, object_list)) {
|
||||||
|
return api_error::comm_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (not object_list.contains("objects")) {
|
||||||
|
return api_error::directory_not_found;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto &list = object_list.at("objects");
|
||||||
|
if (std::ranges::find_if(list, [&api_path](auto &&entry) -> bool {
|
||||||
|
return entry.at("key").template get<std::string>() == api_path + '/';
|
||||||
|
}) == list.end()) {
|
||||||
|
return api_error::directory_not_found;
|
||||||
|
}
|
||||||
|
|
||||||
|
api_meta_map meta;
|
||||||
|
return const_cast<sia_provider *>(this)->create_directory_impl(api_path,
|
||||||
|
meta);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto sia_provider::ensure_directory_exists(const std::string &api_path) const
|
||||||
|
-> api_error {
|
||||||
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
|
bool exists{};
|
||||||
|
auto res{is_directory(api_path, exists)};
|
||||||
|
if (res != api_error::success) {
|
||||||
|
utils::error::raise_api_path_error(function_name, api_path, res,
|
||||||
|
"failed detect existing directory");
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (not exists) {
|
||||||
|
utils::error::raise_api_path_error(function_name, api_path, res,
|
||||||
|
"directory not found");
|
||||||
|
return api_error::directory_not_found;
|
||||||
|
}
|
||||||
|
|
||||||
|
return api_error::success;
|
||||||
|
}
|
||||||
|
|
||||||
auto sia_provider::get_directory_item_count(const std::string &api_path) const
|
auto sia_provider::get_directory_item_count(const std::string &api_path) const
|
||||||
-> std::uint64_t {
|
-> std::uint64_t {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
json object_list{};
|
json object_list;
|
||||||
if (not get_object_list(api_path, object_list)) {
|
if (not get_object_list(api_path, object_list)) {
|
||||||
return 0U;
|
return 0U;
|
||||||
}
|
}
|
||||||
@ -192,41 +238,25 @@ auto sia_provider::get_directory_items_impl(const std::string &api_path,
|
|||||||
-> api_error {
|
-> api_error {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
json object_list{};
|
json object_list;
|
||||||
if (not get_object_list(api_path, object_list)) {
|
if (not get_object_list(api_path, object_list)) {
|
||||||
return api_error::comm_error;
|
return api_error::comm_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (object_list.contains("objects")) {
|
iterate_objects(
|
||||||
for (const auto &entry : object_list.at("objects")) {
|
api_path, object_list,
|
||||||
try {
|
[&](auto &&entry_api_path, auto &&directory, auto &&entry) {
|
||||||
auto name{entry.at("key").get<std::string>()};
|
api_meta_map meta;
|
||||||
auto entry_api_path{utils::path::create_api_path(name)};
|
auto res{get_item_meta(entry_api_path, meta)};
|
||||||
|
if (res != api_error::success) {
|
||||||
auto directory{utils::string::ends_with(name, "/")};
|
utils::error::raise_api_path_error(function_name, entry_api_path, res,
|
||||||
if (directory && (entry_api_path == api_path)) {
|
"failed to get item meta");
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
api_file file{};
|
auto file = create_api_file(
|
||||||
api_meta_map meta{};
|
entry_api_path,
|
||||||
if (get_item_meta(entry_api_path, meta) == api_error::item_not_found) {
|
directory ? 0U : entry["size"].template get<std::uint64_t>(), meta);
|
||||||
file = create_api_file(entry_api_path, "",
|
|
||||||
directory ? 0U
|
|
||||||
: entry["size"].get<std::uint64_t>(),
|
|
||||||
get_last_modified(entry));
|
|
||||||
get_api_item_added()(directory, file);
|
|
||||||
auto res{get_item_meta(entry_api_path, meta)};
|
|
||||||
if (res != api_error::success) {
|
|
||||||
utils::error::raise_api_path_error(function_name, entry_api_path,
|
|
||||||
res, "failed to get item meta");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
file = create_api_file(
|
|
||||||
entry_api_path,
|
|
||||||
directory ? 0U : entry["size"].get<std::uint64_t>(), meta);
|
|
||||||
}
|
|
||||||
|
|
||||||
directory_item dir_item{};
|
directory_item dir_item{};
|
||||||
dir_item.api_parent = file.api_parent;
|
dir_item.api_parent = file.api_parent;
|
||||||
@ -235,13 +265,7 @@ auto sia_provider::get_directory_items_impl(const std::string &api_path,
|
|||||||
dir_item.meta = meta;
|
dir_item.meta = meta;
|
||||||
dir_item.size = file.file_size;
|
dir_item.size = file.file_size;
|
||||||
list.emplace_back(std::move(dir_item));
|
list.emplace_back(std::move(dir_item));
|
||||||
} catch (const std::exception &e) {
|
});
|
||||||
utils::error::raise_api_path_error(function_name, api_path, e,
|
|
||||||
"failed to process entry|" +
|
|
||||||
entry.dump());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return api_error::success;
|
return api_error::success;
|
||||||
}
|
}
|
||||||
@ -290,73 +314,45 @@ auto sia_provider::get_file(const std::string &api_path, api_file &file) const
|
|||||||
return api_error::error;
|
return api_error::error;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto sia_provider::get_file_list(api_file_list &list,
|
auto sia_provider::get_file_list(api_file_list &list, std::string &marker) const
|
||||||
std::string & /* marker */) const
|
|
||||||
-> api_error {
|
-> api_error {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
using dir_func = std::function<api_error(std::string api_path)>;
|
try {
|
||||||
const dir_func get_files_in_dir = [&](std::string api_path) -> api_error {
|
json object_list;
|
||||||
try {
|
if (not get_object_list("", object_list, marker)) {
|
||||||
nlohmann::json object_list{};
|
return api_error::comm_error;
|
||||||
if (not get_object_list(api_path, object_list)) {
|
|
||||||
return api_error::comm_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (object_list.contains("objects")) {
|
|
||||||
for (const auto &entry : object_list.at("objects")) {
|
|
||||||
auto name{entry.at("key").get<std::string>()};
|
|
||||||
auto entry_api_path{utils::path::create_api_path(name)};
|
|
||||||
|
|
||||||
if (utils::string::ends_with(name, "/")) {
|
|
||||||
if (entry_api_path == utils::path::create_api_path(api_path)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
api_meta_map meta{};
|
|
||||||
if (get_item_meta(entry_api_path, meta) ==
|
|
||||||
api_error::item_not_found) {
|
|
||||||
auto dir{
|
|
||||||
create_api_file(entry_api_path, "", 0U,
|
|
||||||
get_last_modified(entry)),
|
|
||||||
};
|
|
||||||
get_api_item_added()(true, dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto res{get_files_in_dir(entry_api_path)};
|
|
||||||
if (res != api_error::success) {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
api_file file{};
|
|
||||||
api_meta_map meta{};
|
|
||||||
if (get_item_meta(entry_api_path, meta) ==
|
|
||||||
api_error::item_not_found) {
|
|
||||||
file = create_api_file(entry_api_path, "",
|
|
||||||
entry["size"].get<std::uint64_t>(),
|
|
||||||
get_last_modified(entry));
|
|
||||||
get_api_item_added()(false, file);
|
|
||||||
} else {
|
|
||||||
file = create_api_file(entry_api_path,
|
|
||||||
entry["size"].get<std::uint64_t>(), meta);
|
|
||||||
}
|
|
||||||
|
|
||||||
list.emplace_back(std::move(file));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return api_error::success;
|
|
||||||
} catch (const std::exception &e) {
|
|
||||||
utils::error::raise_api_path_error(function_name, api_path, e,
|
|
||||||
"failed to process directory");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return api_error::error;
|
iterate_objects("/", object_list,
|
||||||
};
|
[&](auto &&entry_api_path, auto &&directory, auto &&entry) {
|
||||||
|
if (directory) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
return get_files_in_dir("");
|
api_meta_map meta;
|
||||||
|
auto res{get_item_meta(entry_api_path, meta)};
|
||||||
|
if (res != api_error::success) {
|
||||||
|
utils::error::raise_api_path_error(
|
||||||
|
function_name, entry_api_path, res,
|
||||||
|
"failed to get item meta");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
list.emplace_back(create_api_file(
|
||||||
|
entry_api_path,
|
||||||
|
entry["size"].template get<std::uint64_t>(), meta));
|
||||||
|
});
|
||||||
|
|
||||||
|
marker = object_list.at("nextMarker").get<std::string>();
|
||||||
|
return object_list.at("hasMore").get<bool>() ? api_error::more_data
|
||||||
|
: api_error::success;
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
utils::error::raise_api_path_error(function_name, "/", e,
|
||||||
|
"failed to process directory");
|
||||||
|
}
|
||||||
|
|
||||||
|
return api_error::error;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto sia_provider::get_object_info(const std::string &api_path,
|
auto sia_provider::get_object_info(const std::string &api_path,
|
||||||
@ -408,7 +404,9 @@ auto sia_provider::get_object_info(const std::string &api_path,
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto sia_provider::get_object_list(const std::string &api_path,
|
auto sia_provider::get_object_list(const std::string &api_path,
|
||||||
nlohmann::json &object_list) const -> bool {
|
nlohmann::json &object_list,
|
||||||
|
std::optional<std::string> marker) const
|
||||||
|
-> bool {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -416,7 +414,12 @@ auto sia_provider::get_object_list(const std::string &api_path,
|
|||||||
get.allow_timeout = true;
|
get.allow_timeout = true;
|
||||||
get.path = "/api/bus/objects" + api_path + "/";
|
get.path = "/api/bus/objects" + api_path + "/";
|
||||||
get.query["bucket"] = get_bucket(get_sia_config());
|
get.query["bucket"] = get_bucket(get_sia_config());
|
||||||
get.query["delimiter"] = "/";
|
if (marker.has_value()) {
|
||||||
|
get.query["limit"] = "1000";
|
||||||
|
get.query["marker"] = marker.value();
|
||||||
|
} else {
|
||||||
|
get.query["delimiter"] = "/";
|
||||||
|
}
|
||||||
|
|
||||||
std::string error_data;
|
std::string error_data;
|
||||||
get.response_handler = [&error_data, &object_list](auto &&data,
|
get.response_handler = [&error_data, &object_list](auto &&data,
|
||||||
@ -513,6 +516,14 @@ auto sia_provider::is_directory(const std::string &api_path, bool &exists) const
|
|||||||
json file_data{};
|
json file_data{};
|
||||||
auto res{get_object_info(api_path + '/', file_data)};
|
auto res{get_object_info(api_path + '/', file_data)};
|
||||||
if (res == api_error::item_not_found) {
|
if (res == api_error::item_not_found) {
|
||||||
|
if (create_directory_key(api_path) == api_error::success) {
|
||||||
|
exists = true;
|
||||||
|
return api_error::success;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res == api_error::directory_not_found ||
|
||||||
|
res == api_error::item_not_found) {
|
||||||
return api_error::success;
|
return api_error::success;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -609,6 +620,52 @@ auto sia_provider::is_online() const -> bool {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sia_provider::iterate_objects(
|
||||||
|
const std::string &api_path, const json &object_list,
|
||||||
|
std::function<void(const std::string &, bool, json)> handle_entry) const {
|
||||||
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
|
if (not object_list.contains("objects")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto &entry : object_list.at("objects")) {
|
||||||
|
try {
|
||||||
|
auto name{entry.at("key").get<std::string>()};
|
||||||
|
|
||||||
|
auto directory{utils::string::ends_with(name, "/")};
|
||||||
|
auto entry_api_path{utils::path::create_api_path(name)};
|
||||||
|
|
||||||
|
{
|
||||||
|
api_meta_map meta{};
|
||||||
|
if (get_item_meta(entry_api_path, meta) == api_error::item_not_found) {
|
||||||
|
auto file = create_api_file(
|
||||||
|
entry_api_path, "",
|
||||||
|
directory ? 0U : entry["size"].get<std::uint64_t>(),
|
||||||
|
get_last_modified(entry));
|
||||||
|
if (directory) {
|
||||||
|
auto res{ensure_directory_exists(entry_api_path)};
|
||||||
|
if (res != api_error::success) {
|
||||||
|
utils::error::raise_api_path_error(
|
||||||
|
function_name, entry_api_path, res,
|
||||||
|
"failed detect existing directory");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get_api_item_added()(directory, file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handle_entry(entry_api_path, directory, entry);
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
utils::error::raise_api_path_error(
|
||||||
|
function_name, api_path, e,
|
||||||
|
fmt::format("failed to process entry|{}", entry.dump()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto sia_provider::read_file_bytes(const std::string &api_path,
|
auto sia_provider::read_file_bytes(const std::string &api_path,
|
||||||
std::size_t size, std::uint64_t offset,
|
std::size_t size, std::uint64_t offset,
|
||||||
data_buffer &buffer,
|
data_buffer &buffer,
|
||||||
@ -636,7 +693,6 @@ auto sia_provider::read_file_bytes(const std::string &api_path,
|
|||||||
++idx) {
|
++idx) {
|
||||||
long response_code{};
|
long response_code{};
|
||||||
const auto notify_retry = [&]() {
|
const auto notify_retry = [&]() {
|
||||||
fmt::println("{}", std::string(buffer.begin(), buffer.end()));
|
|
||||||
if (response_code == 0) {
|
if (response_code == 0) {
|
||||||
utils::error::raise_api_path_error(
|
utils::error::raise_api_path_error(
|
||||||
function_name, api_path, api_error::comm_error,
|
function_name, api_path, api_error::comm_error,
|
||||||
|
@ -68,7 +68,9 @@ void server::handle_set_config_value_by_name(const httplib::Request &req,
|
|||||||
|
|
||||||
void server::handle_unmount(const httplib::Request & /*req*/,
|
void server::handle_unmount(const httplib::Request & /*req*/,
|
||||||
httplib::Response &res) {
|
httplib::Response &res) {
|
||||||
event_system::instance().raise<unmount_requested>();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
|
event_system::instance().raise<unmount_requested>(function_name);
|
||||||
res.status = http_error_codes::ok;
|
res.status = http_error_codes::ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,13 +22,23 @@
|
|||||||
#include "utils/error_utils.hpp"
|
#include "utils/error_utils.hpp"
|
||||||
|
|
||||||
#include "events/event_system.hpp"
|
#include "events/event_system.hpp"
|
||||||
|
#include "events/types/debug_log.hpp"
|
||||||
|
#include "events/types/info_log.hpp"
|
||||||
#include "events/types/repertory_exception.hpp"
|
#include "events/types/repertory_exception.hpp"
|
||||||
|
#include "events/types/trace_log.hpp"
|
||||||
|
#include "events/types/warn_log.hpp"
|
||||||
#include "types/repertory.hpp"
|
#include "types/repertory.hpp"
|
||||||
#include "utils/error.hpp"
|
#include "utils/error.hpp"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
struct repertory_exception_handler final
|
struct repertory_exception_handler final
|
||||||
: repertory::utils::error::i_exception_handler {
|
: repertory::utils::error::i_exception_handler {
|
||||||
|
void handle_debug(std::string_view function_name,
|
||||||
|
std::string_view msg) const override {
|
||||||
|
repertory::event_system::instance().raise<repertory::debug_log>(
|
||||||
|
function_name, std::string{msg});
|
||||||
|
}
|
||||||
|
|
||||||
void handle_error(std::string_view function_name,
|
void handle_error(std::string_view function_name,
|
||||||
std::string_view msg) const override {
|
std::string_view msg) const override {
|
||||||
repertory::utils::error::raise_error(function_name, msg);
|
repertory::utils::error::raise_error(function_name, msg);
|
||||||
@ -42,6 +52,24 @@ struct repertory_exception_handler final
|
|||||||
const std::exception &ex) const override {
|
const std::exception &ex) const override {
|
||||||
repertory::utils::error::raise_error(function_name, ex);
|
repertory::utils::error::raise_error(function_name, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handle_info(std::string_view function_name,
|
||||||
|
std::string_view msg) const override {
|
||||||
|
repertory::event_system::instance().raise<repertory::info_log>(
|
||||||
|
function_name, std::string{msg});
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_trace(std::string_view function_name,
|
||||||
|
std::string_view msg) const override {
|
||||||
|
repertory::event_system::instance().raise<repertory::trace_log>(
|
||||||
|
function_name, std::string{msg});
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_warn(std::string_view function_name,
|
||||||
|
std::string_view msg) const override {
|
||||||
|
repertory::event_system::instance().raise<repertory::warn_log>(
|
||||||
|
function_name, std::string{msg});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto repertory_handler{
|
const auto repertory_handler{
|
||||||
|
@ -79,7 +79,7 @@ private:
|
|||||||
void handle_get_mount(const httplib::Request &req,
|
void handle_get_mount(const httplib::Request &req,
|
||||||
httplib::Response &res) const;
|
httplib::Response &res) const;
|
||||||
|
|
||||||
void handle_get_mount_list(httplib::Response &res) const;
|
static void handle_get_mount_list(httplib::Response &res);
|
||||||
|
|
||||||
void handle_get_mount_location(const httplib::Request &req,
|
void handle_get_mount_location(const httplib::Request &req,
|
||||||
httplib::Response &res) const;
|
httplib::Response &res) const;
|
||||||
|
@ -44,7 +44,7 @@ auto main(int argc, char **argv) -> int {
|
|||||||
std::vector<const char *> args;
|
std::vector<const char *> args;
|
||||||
{
|
{
|
||||||
auto args_span = std::span(argv, static_cast<std::size_t>(argc));
|
auto args_span = std::span(argv, static_cast<std::size_t>(argc));
|
||||||
std::copy(args_span.begin(), args_span.end(), std::back_inserter(args));
|
std::ranges::copy(args_span, std::back_inserter(args));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc == 1) {
|
if (argc == 1) {
|
||||||
|
@ -34,7 +34,9 @@
|
|||||||
#include "utils/path.hpp"
|
#include "utils/path.hpp"
|
||||||
#include "utils/string.hpp"
|
#include "utils/string.hpp"
|
||||||
|
|
||||||
#include <boost/process.hpp>
|
#include <boost/process/v1/args.hpp>
|
||||||
|
#include <boost/process/v1/child.hpp>
|
||||||
|
#include <boost/process/v1/io.hpp>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
[[nodiscard]] auto decrypt(std::string_view data, std::string_view password)
|
[[nodiscard]] auto decrypt(std::string_view data, std::string_view password)
|
||||||
@ -183,7 +185,7 @@ handlers::handlers(mgmt_app_config *config, httplib::Server *server)
|
|||||||
handle_get_mount_location(req, res);
|
handle_get_mount_location(req, res);
|
||||||
});
|
});
|
||||||
|
|
||||||
server->Get("/api/v1/mount_list", [this](auto && /* req */, auto &&res) {
|
server->Get("/api/v1/mount_list", [](auto && /* req */, auto &&res) {
|
||||||
handle_get_mount_list(res);
|
handle_get_mount_list(res);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -326,9 +328,9 @@ void handlers::handle_put_mount_location(const httplib::Request &req,
|
|||||||
void handlers::handle_get_available_locations(httplib::Response &res) {
|
void handlers::handle_get_available_locations(httplib::Response &res) {
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
constexpr const std::array<std::string_view, 26U> letters{
|
constexpr const std::array<std::string_view, 26U> letters{
|
||||||
"A:", "B:", "C:", "D:", "E:", "F:", "G:", "H:", "I:",
|
"a:", "b:", "c:", "d:", "e:", "f:", "g:", "h:", "i:",
|
||||||
"J:", "K:", "L:", "M:", "N:", "O:", "P:", "Q:", "R:",
|
"j:", "k:", "l:", "m:", "n:", "o:", "p:", "q:", "r:",
|
||||||
"S:", "T:", "U:", "V:", "W:", "X:", "Y:", "Z:",
|
"s:", "t:", "u:", "v:", "w:", "x:", "y:", "z:",
|
||||||
};
|
};
|
||||||
|
|
||||||
auto available = std::accumulate(
|
auto available = std::accumulate(
|
||||||
@ -382,7 +384,7 @@ void handlers::handle_get_mount(const httplib::Request &req,
|
|||||||
res.status = http_error_codes::ok;
|
res.status = http_error_codes::ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
void handlers::handle_get_mount_list(httplib::Response &res) const {
|
void handlers::handle_get_mount_list(httplib::Response &res) {
|
||||||
auto data_dir = utils::file::directory{app_config::get_root_data_directory()};
|
auto data_dir = utils::file::directory{app_config::get_root_data_directory()};
|
||||||
|
|
||||||
nlohmann::json result;
|
nlohmann::json result;
|
||||||
@ -693,9 +695,10 @@ auto handlers::launch_process(provider_type prov, std::string_view name,
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::process::ipstream out;
|
boost::process::v1::ipstream out;
|
||||||
boost::process::child proc(repertory_binary_, boost::process::args(args),
|
boost::process::v1::child proc(repertory_binary_,
|
||||||
boost::process::std_out > out);
|
boost::process::v1::args(args),
|
||||||
|
boost::process::v1::std_out > out);
|
||||||
|
|
||||||
std::string data;
|
std::string data;
|
||||||
std::string line;
|
std::string line;
|
||||||
|
@ -54,21 +54,31 @@ namespace repertory {
|
|||||||
struct local_s3 final {
|
struct local_s3 final {
|
||||||
static constexpr const provider_type type{provider_type::s3};
|
static constexpr const provider_type type{provider_type::s3};
|
||||||
static constexpr const provider_type type2{provider_type::s3};
|
static constexpr const provider_type type2{provider_type::s3};
|
||||||
|
static constexpr const std::uint16_t port{0U};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct local_sia final {
|
struct local_sia final {
|
||||||
static constexpr const provider_type type{provider_type::sia};
|
static constexpr const provider_type type{provider_type::sia};
|
||||||
static constexpr const provider_type type2{provider_type::sia};
|
static constexpr const provider_type type2{provider_type::sia};
|
||||||
|
static constexpr const std::uint16_t port{0U};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct remote_s3 final {
|
struct remote_s3 final {
|
||||||
static constexpr const provider_type type{provider_type::remote};
|
static constexpr const provider_type type{provider_type::remote};
|
||||||
static constexpr const provider_type type2{provider_type::s3};
|
static constexpr const provider_type type2{provider_type::s3};
|
||||||
|
static constexpr const std::uint16_t port{0U};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct remote_sia final {
|
struct remote_sia final {
|
||||||
static constexpr const provider_type type{provider_type::remote};
|
static constexpr const provider_type type{provider_type::remote};
|
||||||
static constexpr const provider_type type2{provider_type::sia};
|
static constexpr const provider_type type2{provider_type::sia};
|
||||||
|
static constexpr const std::uint16_t port{0U};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct remote_linux_to_winfsp final {
|
||||||
|
static constexpr const provider_type type{provider_type::remote};
|
||||||
|
static constexpr const provider_type type2{provider_type::unknown};
|
||||||
|
static constexpr const std::uint16_t port{40001U};
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename provider_t> class fuse_test : public ::testing::Test {
|
template <typename provider_t> class fuse_test : public ::testing::Test {
|
||||||
@ -113,7 +123,7 @@ protected:
|
|||||||
|
|
||||||
auto r_cfg = config->get_remote_mount();
|
auto r_cfg = config->get_remote_mount();
|
||||||
r_cfg.enable = true;
|
r_cfg.enable = true;
|
||||||
r_cfg.api_port = 30000U;
|
r_cfg.api_port = 40000U;
|
||||||
config->set_remote_mount(r_cfg);
|
config->set_remote_mount(r_cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,7 +170,7 @@ protected:
|
|||||||
|
|
||||||
auto r_cfg = config->get_remote_mount();
|
auto r_cfg = config->get_remote_mount();
|
||||||
r_cfg.enable = true;
|
r_cfg.enable = true;
|
||||||
r_cfg.api_port = 30000U;
|
r_cfg.api_port = 40000U;
|
||||||
config->set_remote_mount(r_cfg);
|
config->set_remote_mount(r_cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,7 +188,7 @@ protected:
|
|||||||
execute_mount(drive_args, mount_location);
|
execute_mount(drive_args, mount_location);
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto mount_remote = [&]() {
|
const auto mount_remote = [&](std::uint16_t port = 40000U) {
|
||||||
{
|
{
|
||||||
mount_location2 = mount_location;
|
mount_location2 = mount_location;
|
||||||
|
|
||||||
@ -187,7 +197,8 @@ protected:
|
|||||||
{
|
{
|
||||||
"fuse_test",
|
"fuse_test",
|
||||||
app_config::get_provider_name(provider_t::type) + '_' +
|
app_config::get_provider_name(provider_t::type) + '_' +
|
||||||
app_config::get_provider_name(provider_t::type2),
|
app_config::get_provider_name(provider_t::type2) + '_' +
|
||||||
|
std::to_string(port),
|
||||||
});
|
});
|
||||||
|
|
||||||
mount_location = utils::path::combine(test_directory, {"mount"});
|
mount_location = utils::path::combine(test_directory, {"mount"});
|
||||||
@ -206,7 +217,7 @@ protected:
|
|||||||
"-dd",
|
"-dd",
|
||||||
config2->get_data_directory(),
|
config2->get_data_directory(),
|
||||||
"-rm",
|
"-rm",
|
||||||
"localhost:30000",
|
fmt::format("localhost:{}", port),
|
||||||
mount_location,
|
mount_location,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -233,6 +244,10 @@ protected:
|
|||||||
mount_sia();
|
mount_sia();
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case provider_type::unknown:
|
||||||
|
mount_remote(provider_t::port);
|
||||||
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw std::runtime_error("remote provider type is not implemented");
|
throw std::runtime_error("remote provider type is not implemented");
|
||||||
return;
|
return;
|
||||||
@ -307,6 +322,8 @@ public:
|
|||||||
mkdir(dir_path.c_str(), perms);
|
mkdir(dir_path.c_str(), perms);
|
||||||
|
|
||||||
EXPECT_TRUE(utils::file::directory(dir_path).exists());
|
EXPECT_TRUE(utils::file::directory(dir_path).exists());
|
||||||
|
EXPECT_EQ(0U, utils::file::directory(dir_path).count(false));
|
||||||
|
EXPECT_EQ(0U, utils::file::directory(dir_path).count(true));
|
||||||
EXPECT_FALSE(utils::file::file(dir_path).exists());
|
EXPECT_FALSE(utils::file::file(dir_path).exists());
|
||||||
|
|
||||||
struct stat64 unix_st{};
|
struct stat64 unix_st{};
|
||||||
@ -410,9 +427,15 @@ std::string fuse_test<provider_t>::mount_location;
|
|||||||
template <typename provider_t>
|
template <typename provider_t>
|
||||||
std::string fuse_test<provider_t>::mount_location2;
|
std::string fuse_test<provider_t>::mount_location2;
|
||||||
|
|
||||||
// using fuse_provider_types = ::testing::Types<local_s3, remote_s3>;
|
#if defined(__linux__)
|
||||||
using fuse_provider_types =
|
using fuse_provider_types =
|
||||||
::testing::Types<local_s3, remote_s3, local_sia, remote_sia>;
|
::testing::Types<local_s3, remote_s3, local_sia, remote_sia>;
|
||||||
|
// using fuse_provider_types =
|
||||||
|
// ::testing::Types<local_s3, remote_s3, local_sia, remote_sia,
|
||||||
|
// remote_linux_to_winfsp>;
|
||||||
|
#else // !defined(__linux__)
|
||||||
|
build fails here
|
||||||
|
#endif // defined(_WIN32)
|
||||||
} // namespace repertory
|
} // namespace repertory
|
||||||
|
|
||||||
#endif // !defined(_WIN32)
|
#endif // !defined(_WIN32)
|
||||||
|
@ -45,21 +45,31 @@ namespace repertory {
|
|||||||
struct local_s3 final {
|
struct local_s3 final {
|
||||||
static constexpr const provider_type type{provider_type::s3};
|
static constexpr const provider_type type{provider_type::s3};
|
||||||
static constexpr const provider_type type2{provider_type::s3};
|
static constexpr const provider_type type2{provider_type::s3};
|
||||||
|
static constexpr const std::uint16_t port{0U};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct local_sia final {
|
struct local_sia final {
|
||||||
static constexpr const provider_type type{provider_type::sia};
|
static constexpr const provider_type type{provider_type::sia};
|
||||||
static constexpr const provider_type type2{provider_type::sia};
|
static constexpr const provider_type type2{provider_type::sia};
|
||||||
|
static constexpr const std::uint16_t port{0U};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct remote_s3 final {
|
struct remote_s3 final {
|
||||||
static constexpr const provider_type type{provider_type::remote};
|
static constexpr const provider_type type{provider_type::remote};
|
||||||
static constexpr const provider_type type2{provider_type::s3};
|
static constexpr const provider_type type2{provider_type::s3};
|
||||||
|
static constexpr const std::uint16_t port{0U};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct remote_sia final {
|
struct remote_sia final {
|
||||||
static constexpr const provider_type type{provider_type::remote};
|
static constexpr const provider_type type{provider_type::remote};
|
||||||
static constexpr const provider_type type2{provider_type::sia};
|
static constexpr const provider_type type2{provider_type::sia};
|
||||||
|
static constexpr const std::uint16_t port{0U};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct remote_winfsp_to_linux final {
|
||||||
|
static constexpr const provider_type type{provider_type::remote};
|
||||||
|
static constexpr const provider_type type2{provider_type::unknown};
|
||||||
|
static constexpr const std::uint16_t port{40001U};
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename provider_t> class winfsp_test : public ::testing::Test {
|
template <typename provider_t> class winfsp_test : public ::testing::Test {
|
||||||
@ -102,7 +112,7 @@ protected:
|
|||||||
|
|
||||||
auto r_cfg = config->get_remote_mount();
|
auto r_cfg = config->get_remote_mount();
|
||||||
r_cfg.enable = true;
|
r_cfg.enable = true;
|
||||||
r_cfg.api_port = 30000U;
|
r_cfg.api_port = 40000U;
|
||||||
config->set_remote_mount(r_cfg);
|
config->set_remote_mount(r_cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,7 +141,7 @@ protected:
|
|||||||
ASSERT_TRUE(utils::file::directory(cfg_directory).create_directory());
|
ASSERT_TRUE(utils::file::directory(cfg_directory).create_directory());
|
||||||
|
|
||||||
auto config =
|
auto config =
|
||||||
std::make_unique<app_config>(provider_type::s3, cfg_directory);
|
std::make_unique<app_config>(provider_type::sia, cfg_directory);
|
||||||
{
|
{
|
||||||
app_config src_cfg{
|
app_config src_cfg{
|
||||||
provider_type::sia,
|
provider_type::sia,
|
||||||
@ -144,7 +154,7 @@ protected:
|
|||||||
|
|
||||||
auto r_cfg = config->get_remote_mount();
|
auto r_cfg = config->get_remote_mount();
|
||||||
r_cfg.enable = true;
|
r_cfg.enable = true;
|
||||||
r_cfg.api_port = 30000U;
|
r_cfg.api_port = 40000U;
|
||||||
config->set_remote_mount(r_cfg);
|
config->set_remote_mount(r_cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,13 +170,15 @@ protected:
|
|||||||
execute_mount(drive_args, mount_location);
|
execute_mount(drive_args, mount_location);
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto mount_remote = [&]() {
|
const auto mount_remote = [&](std::uint16_t port = 40000U) {
|
||||||
{
|
{
|
||||||
auto test_directory = utils::path::combine(
|
auto test_directory = utils::path::combine(
|
||||||
test::get_test_output_dir(),
|
test::get_test_output_dir(),
|
||||||
{
|
{
|
||||||
"winfsp_test",
|
"winfsp_test",
|
||||||
app_config::get_provider_name(provider_type::remote),
|
app_config::get_provider_name(provider_t::type) + '_' +
|
||||||
|
app_config::get_provider_name(provider_t::type2) + '_' +
|
||||||
|
std::to_string(port),
|
||||||
});
|
});
|
||||||
|
|
||||||
mount_location2 = mount_location;
|
mount_location2 = mount_location;
|
||||||
@ -184,7 +196,7 @@ protected:
|
|||||||
"-dd",
|
"-dd",
|
||||||
config->get_data_directory(),
|
config->get_data_directory(),
|
||||||
"-rm",
|
"-rm",
|
||||||
"localhost:30000",
|
fmt::format("localhost:{}", port),
|
||||||
mount_location,
|
mount_location,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -211,6 +223,10 @@ protected:
|
|||||||
mount_sia();
|
mount_sia();
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case provider_type::unknown:
|
||||||
|
mount_remote(provider_t::port);
|
||||||
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw std::runtime_error("remote provider type is not implemented");
|
throw std::runtime_error("remote provider type is not implemented");
|
||||||
return;
|
return;
|
||||||
@ -228,7 +244,9 @@ protected:
|
|||||||
static void TearDownTestCase() {
|
static void TearDownTestCase() {
|
||||||
if (provider_t::type == provider_type::remote) {
|
if (provider_t::type == provider_type::remote) {
|
||||||
execute_unmount(drive_args2, mount_location);
|
execute_unmount(drive_args2, mount_location);
|
||||||
execute_unmount(drive_args, mount_location2);
|
if (provider_t::type2 != provider_type::unknown) {
|
||||||
|
execute_unmount(drive_args, mount_location2);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
execute_unmount(drive_args, mount_location);
|
execute_unmount(drive_args, mount_location);
|
||||||
}
|
}
|
||||||
@ -245,6 +263,7 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void execute_unmount(auto args, auto location) {
|
static void execute_unmount(auto args, auto location) {
|
||||||
|
std::this_thread::sleep_for(10s);
|
||||||
auto unmounted{false};
|
auto unmounted{false};
|
||||||
|
|
||||||
auto unmount_cmd =
|
auto unmount_cmd =
|
||||||
@ -280,9 +299,9 @@ std::string winfsp_test<provider_t>::mount_location;
|
|||||||
template <typename provider_t>
|
template <typename provider_t>
|
||||||
std::string winfsp_test<provider_t>::mount_location2;
|
std::string winfsp_test<provider_t>::mount_location2;
|
||||||
|
|
||||||
// using winfsp_provider_types = ::testing::Types<local_s3, remote_s3,
|
using winfsp_provider_types =
|
||||||
// local_sia, remote_sia>;
|
::testing::Types<local_s3, remote_s3, local_sia, remote_sia,
|
||||||
using winfsp_provider_types = ::testing::Types<local_s3, remote_s3>;
|
remote_winfsp_to_linux>;
|
||||||
} // namespace repertory
|
} // namespace repertory
|
||||||
|
|
||||||
#endif // defined(_WIN32)
|
#endif // defined(_WIN32)
|
||||||
|
@ -48,8 +48,8 @@ public:
|
|||||||
return api_error::success;
|
return api_error::success;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto check_parent_access(const std::string &,
|
auto check_parent_access(const std::string &, int) const
|
||||||
int) const -> api_error override {
|
-> api_error override {
|
||||||
return api_error::success;
|
return api_error::success;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,8 +84,8 @@ public:
|
|||||||
return 0U;
|
return 0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto get_item_meta(const std::string &api_path,
|
auto get_item_meta(const std::string &api_path, api_meta_map &meta) const
|
||||||
api_meta_map &meta) const -> api_error override {
|
-> api_error override {
|
||||||
meta = const_cast<mock_fuse_drive *>(this)->meta_[api_path];
|
meta = const_cast<mock_fuse_drive *>(this)->meta_[api_path];
|
||||||
return api_error::success;
|
return api_error::success;
|
||||||
}
|
}
|
||||||
@ -124,8 +124,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto rename_file(const std::string &from_api_path,
|
auto rename_file(const std::string &from_api_path,
|
||||||
const std::string &to_api_path,
|
const std::string &to_api_path, bool overwrite)
|
||||||
bool overwrite) -> int override {
|
-> int override {
|
||||||
const auto from_file_path =
|
const auto from_file_path =
|
||||||
utils::path::combine(mount_location_, {from_api_path});
|
utils::path::combine(mount_location_, {from_api_path});
|
||||||
const auto to_file_path =
|
const auto to_file_path =
|
||||||
@ -152,7 +152,13 @@ public:
|
|||||||
const std::string &value) override {
|
const std::string &value) override {
|
||||||
meta_[api_path][key] = value;
|
meta_[api_path][key] = value;
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
void set_item_meta(const std::string &api_path,
|
||||||
|
const api_meta_map &meta) override {
|
||||||
|
for (const auto &[key, value] : meta) {
|
||||||
|
meta_[api_path][key] = value;
|
||||||
|
}
|
||||||
|
};
|
||||||
} // namespace repertory
|
} // namespace repertory
|
||||||
|
|
||||||
#endif // !defined(_WIN32)
|
#endif // !defined(_WIN32)
|
||||||
|
@ -334,6 +334,9 @@ static void test_overlapped_file(auto &&mount_location, auto &&file_path,
|
|||||||
EXPECT_EQ(0,
|
EXPECT_EQ(0,
|
||||||
std::memcmp(write_buffer.data(), read_buffer.data(), bytes_read));
|
std::memcmp(write_buffer.data(), read_buffer.data(), bytes_read));
|
||||||
|
|
||||||
|
LARGE_INTEGER size{};
|
||||||
|
::GetFileSizeEx(handle, &size);
|
||||||
|
|
||||||
read_buffer.clear();
|
read_buffer.clear();
|
||||||
read_buffer.resize(buffer_size);
|
read_buffer.resize(buffer_size);
|
||||||
overlapped.Offset = 3U * bytes_per_sector;
|
overlapped.Offset = 3U * bytes_per_sector;
|
||||||
|
@ -65,13 +65,16 @@ TYPED_TEST(winfsp_test, rename_fails_if_dest_exists_and_replace_is_false) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto dir_path{
|
auto dir_path{
|
||||||
utils::path::combine(this->mount_location, {"test_dir_4"}),
|
utils::path::combine(this->mount_location, {"test_dir_5"}),
|
||||||
};
|
};
|
||||||
auto file_path{
|
auto file_path{
|
||||||
utils::path::combine(dir_path, {"test_file_4"}),
|
utils::path::combine(dir_path, {"test_file_5"}),
|
||||||
};
|
};
|
||||||
auto file_path2{
|
auto file_path2{
|
||||||
utils::path::combine(dir_path, {"test_file2_4"}),
|
utils::path::combine(dir_path, {"test_file2_5"}),
|
||||||
|
};
|
||||||
|
auto file_path3{
|
||||||
|
utils::path::combine(dir_path, {"test_file3_5"}),
|
||||||
};
|
};
|
||||||
|
|
||||||
ASSERT_TRUE(::CreateDirectoryA(dir_path.c_str(), nullptr));
|
ASSERT_TRUE(::CreateDirectoryA(dir_path.c_str(), nullptr));
|
||||||
@ -84,9 +87,16 @@ TYPED_TEST(winfsp_test, rename_fails_if_dest_exists_and_replace_is_false) {
|
|||||||
|
|
||||||
EXPECT_TRUE(::MoveFileExA(file_path.c_str(), file_path2.c_str(), 0));
|
EXPECT_TRUE(::MoveFileExA(file_path.c_str(), file_path2.c_str(), 0));
|
||||||
|
|
||||||
EXPECT_FALSE(::MoveFileExA(file_path.c_str(), file_path2.c_str(), 0));
|
handle = ::CreateFileA(file_path3.c_str(), GENERIC_READ | GENERIC_WRITE,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr,
|
||||||
|
CREATE_NEW, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||||
|
ASSERT_NE(INVALID_HANDLE_VALUE, handle);
|
||||||
|
::CloseHandle(handle);
|
||||||
|
|
||||||
|
EXPECT_FALSE(::MoveFileExA(file_path3.c_str(), file_path2.c_str(), 0));
|
||||||
EXPECT_EQ(ERROR_ALREADY_EXISTS, ::GetLastError());
|
EXPECT_EQ(ERROR_ALREADY_EXISTS, ::GetLastError());
|
||||||
|
|
||||||
|
EXPECT_TRUE(::DeleteFileA(file_path3.c_str()));
|
||||||
EXPECT_TRUE(::DeleteFileA(file_path2.c_str()));
|
EXPECT_TRUE(::DeleteFileA(file_path2.c_str()));
|
||||||
EXPECT_TRUE(::RemoveDirectoryA(dir_path.c_str()));
|
EXPECT_TRUE(::RemoveDirectoryA(dir_path.c_str()));
|
||||||
}
|
}
|
||||||
@ -97,13 +107,16 @@ TYPED_TEST(winfsp_test, rename_succeeds_if_dest_exists_and_replace_is_true) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto dir_path{
|
auto dir_path{
|
||||||
utils::path::combine(this->mount_location, {"test_dir_4"}),
|
utils::path::combine(this->mount_location, {"test_dir_6"}),
|
||||||
};
|
};
|
||||||
auto file_path{
|
auto file_path{
|
||||||
utils::path::combine(dir_path, {"test_file_4"}),
|
utils::path::combine(dir_path, {"test_file_6"}),
|
||||||
};
|
};
|
||||||
auto file_path2{
|
auto file_path2{
|
||||||
utils::path::combine(dir_path, {"test_file2_4"}),
|
utils::path::combine(dir_path, {"test_file2_6"}),
|
||||||
|
};
|
||||||
|
auto file_path3{
|
||||||
|
utils::path::combine(dir_path, {"test_file3_6"}),
|
||||||
};
|
};
|
||||||
|
|
||||||
ASSERT_TRUE(::CreateDirectoryA(dir_path.c_str(), nullptr));
|
ASSERT_TRUE(::CreateDirectoryA(dir_path.c_str(), nullptr));
|
||||||
@ -116,29 +129,29 @@ TYPED_TEST(winfsp_test, rename_succeeds_if_dest_exists_and_replace_is_true) {
|
|||||||
|
|
||||||
EXPECT_TRUE(::MoveFileExA(file_path.c_str(), file_path2.c_str(), 0));
|
EXPECT_TRUE(::MoveFileExA(file_path.c_str(), file_path2.c_str(), 0));
|
||||||
|
|
||||||
handle = ::CreateFileA(file_path.c_str(), GENERIC_READ | GENERIC_WRITE,
|
handle = ::CreateFileA(file_path3.c_str(), GENERIC_READ | GENERIC_WRITE,
|
||||||
FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr,
|
FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr,
|
||||||
CREATE_NEW, FILE_ATTRIBUTE_NORMAL, nullptr);
|
CREATE_NEW, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||||
ASSERT_NE(INVALID_HANDLE_VALUE, handle);
|
ASSERT_NE(INVALID_HANDLE_VALUE, handle);
|
||||||
::CloseHandle(handle);
|
::CloseHandle(handle);
|
||||||
|
|
||||||
EXPECT_TRUE(::MoveFileExA(file_path.c_str(), file_path2.c_str(),
|
EXPECT_TRUE(::MoveFileExA(file_path3.c_str(), file_path2.c_str(),
|
||||||
MOVEFILE_REPLACE_EXISTING));
|
MOVEFILE_REPLACE_EXISTING));
|
||||||
|
|
||||||
EXPECT_TRUE(::DeleteFileA(file_path2.c_str()));
|
EXPECT_TRUE(::DeleteFileA(file_path2.c_str()));
|
||||||
EXPECT_TRUE(::RemoveDirectoryA(dir_path.c_str()));
|
EXPECT_TRUE(::RemoveDirectoryA(dir_path.c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
TYPED_TEST(winfsp_test, rename_can_rename_dir_if_dest_does_not_exist) {
|
TYPED_TEST(winfsp_test, rename_dir_succeeds_if_dest_does_not_exist) {
|
||||||
if (this->current_provider == provider_type::s3) {
|
if (this->current_provider == provider_type::s3) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto dir_path{
|
auto dir_path{
|
||||||
utils::path::combine(this->mount_location, {"test_dir_4"}),
|
utils::path::combine(this->mount_location, {"test_dir_7"}),
|
||||||
};
|
};
|
||||||
auto dir_path2{
|
auto dir_path2{
|
||||||
utils::path::combine(this->mount_location, {"test_dir2_4"}),
|
utils::path::combine(this->mount_location, {"test_dir2_7"}),
|
||||||
};
|
};
|
||||||
|
|
||||||
ASSERT_TRUE(::CreateDirectoryA(dir_path.c_str(), nullptr));
|
ASSERT_TRUE(::CreateDirectoryA(dir_path.c_str(), nullptr));
|
||||||
@ -154,10 +167,10 @@ TYPED_TEST(winfsp_test, rename_dir_fails_if_dest_exists_and_replace_is_false) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto dir_path{
|
auto dir_path{
|
||||||
utils::path::combine(this->mount_location, {"test_dir_4"}),
|
utils::path::combine(this->mount_location, {"test_dir_8"}),
|
||||||
};
|
};
|
||||||
auto dir_path2{
|
auto dir_path2{
|
||||||
utils::path::combine(this->mount_location, {"test_dir2_4"}),
|
utils::path::combine(this->mount_location, {"test_dir2_8"}),
|
||||||
};
|
};
|
||||||
|
|
||||||
ASSERT_TRUE(::CreateDirectoryA(dir_path.c_str(), nullptr));
|
ASSERT_TRUE(::CreateDirectoryA(dir_path.c_str(), nullptr));
|
||||||
@ -176,10 +189,10 @@ TYPED_TEST(winfsp_test, rename_dir_fails_if_dest_exists_and_replace_is_true) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto dir_path{
|
auto dir_path{
|
||||||
utils::path::combine(this->mount_location, {"test_dir_4"}),
|
utils::path::combine(this->mount_location, {"test_dir_9"}),
|
||||||
};
|
};
|
||||||
auto dir_path2{
|
auto dir_path2{
|
||||||
utils::path::combine(this->mount_location, {"test_dir2_4"}),
|
utils::path::combine(this->mount_location, {"test_dir2_9"}),
|
||||||
};
|
};
|
||||||
|
|
||||||
ASSERT_TRUE(::CreateDirectoryA(dir_path.c_str(), nullptr));
|
ASSERT_TRUE(::CreateDirectoryA(dir_path.c_str(), nullptr));
|
||||||
@ -200,13 +213,13 @@ TYPED_TEST(winfsp_test,
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto dir_path{
|
auto dir_path{
|
||||||
utils::path::combine(this->mount_location, {"test_dir_4"}),
|
utils::path::combine(this->mount_location, {"test_dir_10"}),
|
||||||
};
|
};
|
||||||
auto dir_path2{
|
auto dir_path2{
|
||||||
utils::path::combine(this->mount_location, {"test_dir2_4"}),
|
utils::path::combine(this->mount_location, {"test_dir2_10"}),
|
||||||
};
|
};
|
||||||
auto file_path{
|
auto file_path{
|
||||||
utils::path::combine(dir_path, {"test_file_4"}),
|
utils::path::combine(dir_path, {"test_file_10"}),
|
||||||
};
|
};
|
||||||
|
|
||||||
ASSERT_TRUE(::CreateDirectoryA(dir_path.c_str(), nullptr));
|
ASSERT_TRUE(::CreateDirectoryA(dir_path.c_str(), nullptr));
|
||||||
@ -231,13 +244,13 @@ TYPED_TEST(winfsp_test,
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto dir_path{
|
auto dir_path{
|
||||||
utils::path::combine(this->mount_location, {"test_dir_4"}),
|
utils::path::combine(this->mount_location, {"test_dir_11"}),
|
||||||
};
|
};
|
||||||
auto dir_path2{
|
auto dir_path2{
|
||||||
utils::path::combine(this->mount_location, {"test_dir2_4"}),
|
utils::path::combine(this->mount_location, {"test_dir2_11"}),
|
||||||
};
|
};
|
||||||
auto file_path{
|
auto file_path{
|
||||||
utils::path::combine(dir_path, {"test_file_4"}),
|
utils::path::combine(dir_path, {"test_file_11"}),
|
||||||
};
|
};
|
||||||
|
|
||||||
ASSERT_TRUE(::CreateDirectoryA(dir_path.c_str(), nullptr));
|
ASSERT_TRUE(::CreateDirectoryA(dir_path.c_str(), nullptr));
|
||||||
|
@ -50,10 +50,17 @@ TYPED_TEST(winfsp_test, volume_can_get_volume_info) {
|
|||||||
flags);
|
flags);
|
||||||
EXPECT_EQ(255U, max_component_length);
|
EXPECT_EQ(255U, max_component_length);
|
||||||
EXPECT_EQ(0U, serial_num);
|
EXPECT_EQ(0U, serial_num);
|
||||||
EXPECT_STREQ(
|
if (this->current_provider == provider_type::unknown) {
|
||||||
("repertory_" + app_config::get_provider_name(this->current_provider))
|
EXPECT_STREQ(
|
||||||
.c_str(),
|
("repertory_" + app_config::get_provider_name(provider_type::sia))
|
||||||
volume_label.c_str());
|
.c_str(),
|
||||||
|
volume_label.c_str());
|
||||||
|
} else {
|
||||||
|
EXPECT_STREQ(
|
||||||
|
("repertory_" + app_config::get_provider_name(this->current_provider))
|
||||||
|
.c_str(),
|
||||||
|
volume_label.c_str());
|
||||||
|
}
|
||||||
EXPECT_STREQ(this->mount_location.c_str(), fs_name.c_str());
|
EXPECT_STREQ(this->mount_location.c_str(), fs_name.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,30 +1,30 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
declare -A PROJECT_VERSIONS
|
declare -A PROJECT_VERSIONS
|
||||||
PROJECT_VERSIONS[BINUTILS]="2.43"
|
PROJECT_VERSIONS[BINUTILS]="2.44"
|
||||||
PROJECT_VERSIONS[BOOST2_MAJOR]="1"
|
PROJECT_VERSIONS[BOOST2_MAJOR]="1"
|
||||||
PROJECT_VERSIONS[BOOST2_MINOR]="76"
|
PROJECT_VERSIONS[BOOST2_MINOR]="76"
|
||||||
PROJECT_VERSIONS[BOOST2_PATCH]="0"
|
PROJECT_VERSIONS[BOOST2_PATCH]="0"
|
||||||
PROJECT_VERSIONS[BOOST_MAJOR]="1"
|
PROJECT_VERSIONS[BOOST_MAJOR]="1"
|
||||||
PROJECT_VERSIONS[BOOST_MINOR]="87"
|
PROJECT_VERSIONS[BOOST_MINOR]="88"
|
||||||
PROJECT_VERSIONS[BOOST_PATCH]="0"
|
PROJECT_VERSIONS[BOOST_PATCH]="0"
|
||||||
PROJECT_VERSIONS[CPP_HTTPLIB]="0.19.0"
|
PROJECT_VERSIONS[CPP_HTTPLIB]="0.20.0"
|
||||||
PROJECT_VERSIONS[CURL]="8.12.1"
|
PROJECT_VERSIONS[CURL]="8.13.0"
|
||||||
PROJECT_VERSIONS[CURL2]="8_12_1"
|
PROJECT_VERSIONS[CURL2]="8_13_0"
|
||||||
PROJECT_VERSIONS[EXPAT]="2.6.4"
|
PROJECT_VERSIONS[EXPAT]="2.7.1"
|
||||||
PROJECT_VERSIONS[EXPAT2]="2_6_4"
|
PROJECT_VERSIONS[EXPAT2]="2_7_1"
|
||||||
PROJECT_VERSIONS[GCC]="14.2.0"
|
PROJECT_VERSIONS[GCC]="14.2.0"
|
||||||
PROJECT_VERSIONS[GTEST]="1.16.0"
|
PROJECT_VERSIONS[GTEST]="1.16.0"
|
||||||
PROJECT_VERSIONS[ICU]="76-1"
|
PROJECT_VERSIONS[ICU]="76-1"
|
||||||
PROJECT_VERSIONS[JSON]="3.11.3"
|
PROJECT_VERSIONS[JSON]="3.12.0"
|
||||||
PROJECT_VERSIONS[LIBSODIUM]="1.0.20"
|
PROJECT_VERSIONS[LIBSODIUM]="1.0.20"
|
||||||
PROJECT_VERSIONS[MESA]="23.3.3"
|
PROJECT_VERSIONS[MESA]="23.3.3"
|
||||||
PROJECT_VERSIONS[MINGW]="12.0.0"
|
PROJECT_VERSIONS[MINGW]="12.0.0"
|
||||||
PROJECT_VERSIONS[OPENSSL]="3.4.1"
|
PROJECT_VERSIONS[OPENSSL]="3.5.0"
|
||||||
PROJECT_VERSIONS[PKG_CONFIG]="0.29.2"
|
PROJECT_VERSIONS[PKG_CONFIG]="0.29.2"
|
||||||
PROJECT_VERSIONS[PUGIXML]="1.15"
|
PROJECT_VERSIONS[PUGIXML]="1.15"
|
||||||
PROJECT_VERSIONS[ROCKSDB]="9.10.0"
|
PROJECT_VERSIONS[ROCKSDB]="10.0.1"
|
||||||
PROJECT_VERSIONS[SPDLOG]="1.15.1"
|
PROJECT_VERSIONS[SPDLOG]="1.15.2"
|
||||||
PROJECT_VERSIONS[SQLITE]="3490100"
|
PROJECT_VERSIONS[SQLITE]="3490100"
|
||||||
PROJECT_VERSIONS[SQLITE2]="3.49.1"
|
PROJECT_VERSIONS[SQLITE2]="3.49.1"
|
||||||
PROJECT_VERSIONS[STDUUID]="1.2.3"
|
PROJECT_VERSIONS[STDUUID]="1.2.3"
|
||||||
|
BIN
support/3rd_party/boost_1_87_0.tar.gz
(Stored with Git LFS)
vendored
BIN
support/3rd_party/boost_1_87_0.tar.gz
(Stored with Git LFS)
vendored
Binary file not shown.
1
support/3rd_party/boost_1_87_0.tar.gz.sha256
vendored
1
support/3rd_party/boost_1_87_0.tar.gz.sha256
vendored
@ -1 +0,0 @@
|
|||||||
f55c340aa49763b1925ccf02b2e83f35fdcf634c9d5164a2acb87540173c741d *boost_1_87_0.tar.gz
|
|
BIN
support/3rd_party/boost_1_88_0.tar.gz
(Stored with Git LFS)
vendored
Normal file
BIN
support/3rd_party/boost_1_88_0.tar.gz
(Stored with Git LFS)
vendored
Normal file
Binary file not shown.
1
support/3rd_party/boost_1_88_0.tar.gz.sha256
vendored
Normal file
1
support/3rd_party/boost_1_88_0.tar.gz.sha256
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
3621533e820dcab1e8012afd583c0c73cf0f77694952b81352bf38c1488f9cb4 boost_1_88_0.tar.gz
|
BIN
support/3rd_party/cpp-httplib-0.19.0.tar.gz
(Stored with Git LFS)
vendored
BIN
support/3rd_party/cpp-httplib-0.19.0.tar.gz
(Stored with Git LFS)
vendored
Binary file not shown.
@ -1 +0,0 @@
|
|||||||
c9b9e0524666e1cd088f0874c57c1ce7c0eaa8552f9f4e15c755d5201fc8c608 *cpp-httplib-0.19.0.tar.gz
|
|
BIN
support/3rd_party/cpp-httplib-0.20.0.tar.gz
(Stored with Git LFS)
vendored
Normal file
BIN
support/3rd_party/cpp-httplib-0.20.0.tar.gz
(Stored with Git LFS)
vendored
Normal file
Binary file not shown.
1
support/3rd_party/cpp-httplib-0.20.0.tar.gz.sha256
vendored
Normal file
1
support/3rd_party/cpp-httplib-0.20.0.tar.gz.sha256
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
18064587e0cc6a0d5d56d619f4cbbcaba47aa5d84d86013abbd45d95c6653866 cpp-httplib-0.20.0.tar.gz
|
BIN
support/3rd_party/curl-8.12.1.tar.gz
(Stored with Git LFS)
vendored
BIN
support/3rd_party/curl-8.12.1.tar.gz
(Stored with Git LFS)
vendored
Binary file not shown.
1
support/3rd_party/curl-8.12.1.tar.gz.sha256
vendored
1
support/3rd_party/curl-8.12.1.tar.gz.sha256
vendored
@ -1 +0,0 @@
|
|||||||
6edc063d1ebaf9cf3b3b46e9fef2f3cd8932694989ecd43d005d6e828426d09f *curl-8.12.1.tar.gz
|
|
BIN
support/3rd_party/curl-8.13.0.tar.gz
(Stored with Git LFS)
vendored
Normal file
BIN
support/3rd_party/curl-8.13.0.tar.gz
(Stored with Git LFS)
vendored
Normal file
Binary file not shown.
1
support/3rd_party/curl-8.13.0.tar.gz.sha256
vendored
Normal file
1
support/3rd_party/curl-8.13.0.tar.gz.sha256
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
ccc5ba45d9f5320c70ffb24e5411b66ba55ea1f333bf78be0963ed90a9328699 curl-8.13.0.tar.gz
|
BIN
support/3rd_party/json-3.11.3.tar.gz
(Stored with Git LFS)
vendored
BIN
support/3rd_party/json-3.11.3.tar.gz
(Stored with Git LFS)
vendored
Binary file not shown.
1
support/3rd_party/json-3.11.3.tar.gz.sha256
vendored
1
support/3rd_party/json-3.11.3.tar.gz.sha256
vendored
@ -1 +0,0 @@
|
|||||||
0d8ef5af7f9794e3263480193c491549b2ba6cc74bb018906202ada498a79406 json-3.11.3.tar.gz
|
|
BIN
support/3rd_party/json-3.12.0.tar.gz
(Stored with Git LFS)
vendored
Normal file
BIN
support/3rd_party/json-3.12.0.tar.gz
(Stored with Git LFS)
vendored
Normal file
Binary file not shown.
1
support/3rd_party/json-3.12.0.tar.gz.sha256
vendored
Normal file
1
support/3rd_party/json-3.12.0.tar.gz.sha256
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
4b92eb0c06d10683f7447ce9406cb97cd4b453be18d7279320f7b2f025c10187 json-3.12.0.tar.gz
|
BIN
support/3rd_party/mingw64/binutils-2.43.tar.xz
(Stored with Git LFS)
vendored
BIN
support/3rd_party/mingw64/binutils-2.43.tar.xz
(Stored with Git LFS)
vendored
Binary file not shown.
@ -1 +0,0 @@
|
|||||||
b53606f443ac8f01d1d5fc9c39497f2af322d99e14cea5c0b4b124d630379365 binutils-2.43.tar.xz
|
|
BIN
support/3rd_party/mingw64/binutils-2.44.tar.xz
(Stored with Git LFS)
vendored
Normal file
BIN
support/3rd_party/mingw64/binutils-2.44.tar.xz
(Stored with Git LFS)
vendored
Normal file
Binary file not shown.
1
support/3rd_party/mingw64/binutils-2.44.tar.xz.sha256
vendored
Normal file
1
support/3rd_party/mingw64/binutils-2.44.tar.xz.sha256
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
ce2017e059d63e67ddb9240e9d4ec49c2893605035cd60e92ad53177f4377237 binutils-2.44.tar.xz
|
BIN
support/3rd_party/mingw64/expat-2.6.4.tar.gz
(Stored with Git LFS)
vendored
BIN
support/3rd_party/mingw64/expat-2.6.4.tar.gz
(Stored with Git LFS)
vendored
Binary file not shown.
@ -1 +0,0 @@
|
|||||||
372b18f6527d162fa9658f1c74d22a37429b82d822f5a1e1fc7e00f6045a06a2 *expat-2.6.4.tar.gz
|
|
BIN
support/3rd_party/mingw64/expat-2.7.1.tar.gz
(Stored with Git LFS)
vendored
Normal file
BIN
support/3rd_party/mingw64/expat-2.7.1.tar.gz
(Stored with Git LFS)
vendored
Normal file
Binary file not shown.
1
support/3rd_party/mingw64/expat-2.7.1.tar.gz.sha256
vendored
Normal file
1
support/3rd_party/mingw64/expat-2.7.1.tar.gz.sha256
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
85372797ff0673a8fc4a6be16466bb5a0ca28c0dcf3c6f7ac1686b4a3ba2aabb expat-2.7.1.tar.gz
|
BIN
support/3rd_party/openssl-3.4.1.tar.gz
(Stored with Git LFS)
vendored
BIN
support/3rd_party/openssl-3.4.1.tar.gz
(Stored with Git LFS)
vendored
Binary file not shown.
@ -1 +0,0 @@
|
|||||||
002a2d6b30b58bf4bea46c43bdd96365aaf8daa6c428782aa4feee06da197df3 *openssl-3.4.1.tar.gz
|
|
BIN
support/3rd_party/openssl-3.5.0.tar.gz
(Stored with Git LFS)
vendored
Normal file
BIN
support/3rd_party/openssl-3.5.0.tar.gz
(Stored with Git LFS)
vendored
Normal file
Binary file not shown.
1
support/3rd_party/openssl-3.5.0.tar.gz.sha256
vendored
Normal file
1
support/3rd_party/openssl-3.5.0.tar.gz.sha256
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
344d0a79f1a9b08029b0744e2cc401a43f9c90acd1044d09a530b4885a8e9fc0 openssl-3.5.0.tar.gz
|
BIN
support/3rd_party/rocksdb-10.0.1.tar.gz
(Stored with Git LFS)
vendored
Normal file
BIN
support/3rd_party/rocksdb-10.0.1.tar.gz
(Stored with Git LFS)
vendored
Normal file
Binary file not shown.
1
support/3rd_party/rocksdb-10.0.1.tar.gz.sha256
vendored
Normal file
1
support/3rd_party/rocksdb-10.0.1.tar.gz.sha256
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
3fdc9ca996971c4c039959866382c4a3a6c8ade4abf888f3b2ff77153e07bf28 rocksdb-10.0.1.tar.gz
|
BIN
support/3rd_party/rocksdb-9.10.0.tar.gz
(Stored with Git LFS)
vendored
BIN
support/3rd_party/rocksdb-9.10.0.tar.gz
(Stored with Git LFS)
vendored
Binary file not shown.
@ -1 +0,0 @@
|
|||||||
fdccab16133c9d927a183c2648bcea8d956fb41eb1df2aacaa73eb0b95e43724 *rocksdb-9.10.0.tar.gz
|
|
BIN
support/3rd_party/spdlog-1.15.1.tar.gz
(Stored with Git LFS)
vendored
BIN
support/3rd_party/spdlog-1.15.1.tar.gz
(Stored with Git LFS)
vendored
Binary file not shown.
@ -1 +0,0 @@
|
|||||||
25c843860f039a1600f232c6eb9e01e6627f7d030a2ae5e232bdd3c9205d26cc *spdlog-1.15.1.tar.gz
|
|
BIN
support/3rd_party/spdlog-1.15.2.tar.gz
(Stored with Git LFS)
vendored
Normal file
BIN
support/3rd_party/spdlog-1.15.2.tar.gz
(Stored with Git LFS)
vendored
Normal file
Binary file not shown.
1
support/3rd_party/spdlog-1.15.2.tar.gz.sha256
vendored
Normal file
1
support/3rd_party/spdlog-1.15.2.tar.gz.sha256
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
7a80896357f3e8e920e85e92633b14ba0f229c506e6f978578bdc35ba09e9a5d spdlog-1.15.2.tar.gz
|
@ -157,6 +157,7 @@ auto get_next_available_port(std::uint16_t first_port,
|
|||||||
++check_port;
|
++check_port;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
acceptor.set_option(boost::asio::ip::tcp::acceptor::linger(true, 0));
|
acceptor.set_option(boost::asio::ip::tcp::acceptor::linger(true, 0));
|
||||||
acceptor.bind({tcp::v4(), static_cast<std::uint16_t>(check_port)},
|
acceptor.bind({tcp::v4(), static_cast<std::uint16_t>(check_port)},
|
||||||
error_code);
|
error_code);
|
||||||
|
@ -86,11 +86,13 @@ auto traverse_directory(
|
|||||||
struct dirent *de{nullptr};
|
struct dirent *de{nullptr};
|
||||||
while (res && (de = readdir(root)) && !is_stop_requested()) {
|
while (res && (de = readdir(root)) && !is_stop_requested()) {
|
||||||
if (de->d_type == DT_DIR) {
|
if (de->d_type == DT_DIR) {
|
||||||
if ((std::string_view(de->d_name) != ".") &&
|
if ((std::string_view(de->d_name) == ".") ||
|
||||||
(std::string_view(de->d_name) != "..")) {
|
(std::string_view(de->d_name) == "..")) {
|
||||||
res = directory_action(repertory::utils::file::directory(
|
continue;
|
||||||
repertory::utils::path::combine(path, {de->d_name})));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
res = directory_action(repertory::utils::file::directory(
|
||||||
|
repertory::utils::path::combine(path, {de->d_name})));
|
||||||
} else {
|
} else {
|
||||||
res = file_action(repertory::utils::file::file(
|
res = file_action(repertory::utils::file::file(
|
||||||
repertory::utils::path::combine(path, {de->d_name})));
|
repertory::utils::path::combine(path, {de->d_name})));
|
||||||
@ -105,8 +107,8 @@ auto traverse_directory(
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace repertory::utils::file {
|
namespace repertory::utils::file {
|
||||||
auto directory::copy_to(std::string_view new_path,
|
auto directory::copy_to(std::string_view new_path, bool overwrite) const
|
||||||
bool overwrite) const -> bool {
|
-> bool {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -213,7 +215,7 @@ auto directory::exists() const -> bool {
|
|||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
return ::PathIsDirectoryA(path_.c_str()) != 0;
|
return ::PathIsDirectoryA(path_.c_str()) != 0;
|
||||||
#else // !defined(_WIN32)
|
#else // !defined(_WIN32)
|
||||||
struct stat64 st {};
|
struct stat64 st{};
|
||||||
return (stat64(path_.c_str(), &st) == 0 && S_ISDIR(st.st_mode));
|
return (stat64(path_.c_str(), &st) == 0 && S_ISDIR(st.st_mode));
|
||||||
#endif // defined(_WIN32)
|
#endif // defined(_WIN32)
|
||||||
|
|
||||||
@ -266,8 +268,8 @@ auto directory::get_directories() const -> std::vector<fs_directory_t> {
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto directory::create_file(std::string_view file_name,
|
auto directory::create_file(std::string_view file_name, bool read_only) const
|
||||||
bool read_only) const -> fs_file_t {
|
-> fs_file_t {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user