72 Commits

Author SHA1 Message Date
5f5b1f751b fix
Some checks reported errors
BlockStorage/repertory_osx_builds/pipeline/head Something is wrong with the build of this commit
BlockStorage/repertory_linux_builds/pipeline/head Something is wrong with the build of this commit
2023-11-18 17:18:03 -06:00
24c5dad929 fix lib64 directory issue 2023-11-18 17:14:38 -06:00
f0046fcd57 updated ignore list 2023-11-18 17:04:10 -06:00
3c3e415175 refactor 2023-11-18 17:03:42 -06:00
00d3355f43 updated openssl 2023-11-18 16:56:37 -06:00
907a14faff fix tests
All checks were successful
BlockStorage/repertory_osx_builds/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head This commit looks good
2023-11-18 16:34:40 -06:00
4348e89f99 refactor tests
All checks were successful
BlockStorage/repertory_osx_builds/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head This commit looks good
2023-11-18 15:34:43 -06:00
7a24cc54f8 refactor
All checks were successful
BlockStorage/repertory_osx_builds/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head This commit looks good
2023-11-16 08:08:03 -06:00
80f6e3c272 extract common behavior
All checks were successful
BlockStorage/repertory_osx_builds/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head This commit looks good
2023-11-15 20:54:28 -06:00
edb1297c4a fix boost version
All checks were successful
BlockStorage/repertory_linux_builds/pipeline/head This commit looks good
BlockStorage/repertory_osx_builds/pipeline/head This commit looks good
2023-11-15 19:56:44 -06:00
1ee157f943 switch to storj for binary hosting
All checks were successful
BlockStorage/repertory_linux_builds/pipeline/head This commit looks good
BlockStorage/repertory_osx_builds/pipeline/head This commit looks good
2023-11-15 19:17:21 -06:00
1b2981b06e removed logs
All checks were successful
BlockStorage/repertory_osx_builds/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head This commit looks good
2023-11-14 20:34:43 -06:00
7203fefd33 refactor
All checks were successful
BlockStorage/repertory_osx_builds/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head This commit looks good
2023-11-14 20:28:47 -06:00
d808b2dd19 refactor
All checks were successful
BlockStorage/repertory_osx_builds/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head This commit looks good
2023-11-14 20:09:50 -06:00
ee34a1e361 extract common behavior
All checks were successful
BlockStorage/repertory_osx_builds/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head This commit looks good
2023-11-14 19:49:46 -06:00
1766f91697 extract common behavior
All checks were successful
BlockStorage/repertory_osx_builds/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head This commit looks good
2023-11-14 18:35:18 -06:00
b3aa28d085 refactor
Some checks are pending
BlockStorage/repertory_linux_builds/pipeline/head Build queued...
BlockStorage/repertory_osx_builds/pipeline/head This commit looks good
2023-11-14 18:26:00 -06:00
a605d7af11 Merge branch 'development' of ssh://git.fifthgrid.com:3022/BlockStorage/repertory into development
All checks were successful
BlockStorage/repertory_osx_builds/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head This commit looks good
2023-11-14 18:24:27 -06:00
19b1a33c48 extract common behavior 2023-11-14 18:20:11 -06:00
04aa511448 Address compiler warnings #10
All checks were successful
BlockStorage/repertory_osx_builds/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head This commit looks good
2023-11-12 19:44:58 -06:00
8dc3d4466b refactor 2023-11-12 19:43:52 -06:00
0716a58ff0 Address compiler warnings #10
All checks were successful
BlockStorage/repertory_osx_builds/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head This commit looks good
2023-11-12 19:36:00 -06:00
60052081b4 fix
All checks were successful
BlockStorage/repertory_osx_builds/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head This commit looks good
2023-11-12 14:36:02 -06:00
f11d49b264 fix test
All checks were successful
BlockStorage/repertory_osx_builds/pipeline/head This commit looks good
2023-11-12 14:34:58 -06:00
103dae6d08 unit tests and fixes
Some checks are pending
BlockStorage/repertory_linux_builds/pipeline/head Build queued...
BlockStorage/repertory_osx_builds/pipeline/head This commit looks good
2023-11-12 14:33:19 -06:00
821ed7b25e fix test 2023-11-12 14:27:11 -06:00
87f83b6f30 fix test
All checks were successful
BlockStorage/repertory_osx_builds/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head This commit looks good
2023-11-12 14:08:02 -06:00
ace81d797e cleanup 2023-11-12 14:01:53 -06:00
57ca2c7c6d refactor
All checks were successful
BlockStorage/repertory_osx_builds/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head This commit looks good
2023-11-12 12:41:18 -06:00
8360d9e045 extract common behavior
All checks were successful
BlockStorage/repertory_osx_builds/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head This commit looks good
2023-11-12 12:36:44 -06:00
560ffbbb6a fix events
All checks were successful
BlockStorage/repertory_osx_builds/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head This commit looks good
2023-11-12 11:49:03 -06:00
72314606f3 extract common behavior 2023-11-12 11:45:54 -06:00
db009b69dd fix
All checks were successful
BlockStorage/repertory_osx_builds/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head This commit looks good
2023-11-11 21:24:15 -06:00
3ed99dc0ce cleanup
All checks were successful
BlockStorage/repertory_osx_builds/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head This commit looks good
2023-11-11 21:17:07 -06:00
762a7c99d5 refactor s3 provider
All checks were successful
BlockStorage/repertory_osx_builds/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head This commit looks good
2023-11-11 21:15:08 -06:00
4e62156b70 added read retry to s3 provider
All checks were successful
BlockStorage/repertory_osx_builds/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head This commit looks good
2023-11-11 21:04:21 -06:00
cc49536755 fix
All checks were successful
BlockStorage/repertory_osx_builds/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head This commit looks good
2023-11-11 20:33:57 -06:00
54b844dc3b fix
Some checks are pending
BlockStorage/repertory_linux_builds/pipeline/head Build queued...
BlockStorage/repertory_osx_builds/pipeline/head This commit looks good
2023-11-11 20:24:21 -06:00
1e8ba13f66 s3 provider fixes
Some checks failed
BlockStorage/repertory_osx_builds/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head There was a failure building this commit
2023-11-11 20:21:12 -06:00
93011cee9c refactor s3 provider
Some checks failed
BlockStorage/repertory_osx_builds/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head There was a failure building this commit
2023-11-11 19:05:27 -06:00
a474a5c73c refactor s3 provider
Some checks failed
BlockStorage/repertory_osx_builds/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head There was a failure building this commit
2023-11-11 18:49:15 -06:00
17b98ca99d refactor
Some checks failed
BlockStorage/repertory_osx_builds/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head There was a failure building this commit
2023-11-11 18:31:49 -06:00
281eedb71e refactor s3 provider
Some checks failed
BlockStorage/repertory_osx_builds/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head There was a failure building this commit
2023-11-11 16:42:38 -06:00
1ee533591c refactor s3 provider
Some checks failed
BlockStorage/repertory_osx_builds/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head There was a failure building this commit
2023-11-11 16:28:00 -06:00
b87e1df140 refactor s3 provider 2023-11-11 15:35:35 -06:00
f88239a13e updated changelog 2023-11-11 11:52:19 -06:00
68476cbc00 refactor s3 provider 2023-11-11 11:32:14 -06:00
f2c1f64f02 Address compiler warnings #10
All checks were successful
BlockStorage/repertory_osx_builds/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head This commit looks good
2023-11-08 19:53:12 -06:00
a7209184c8 changed number of jobs
All checks were successful
BlockStorage/repertory_osx_builds/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head This commit looks good
2023-11-01 13:59:36 -05:00
ba59e29499 fix build
Some checks failed
BlockStorage/repertory_linux_builds/pipeline/head This commit looks good
BlockStorage/repertory/pipeline/head There was a failure building this commit
BlockStorage/repertory_osx_builds/pipeline/head There was a failure building this commit
2023-10-31 16:03:03 -05:00
f94196d865 Address compiler warnings #10
Some checks failed
BlockStorage/repertory_osx/pipeline/head There was a failure building this commit
BlockStorage/repertory_linux_builds/pipeline/head This commit looks good
2023-10-30 19:33:18 -05:00
bb5a9f9737 fix
Some checks failed
BlockStorage/repertory_linux_builds/pipeline/head Build queued...
BlockStorage/repertory_osx/pipeline/head There was a failure building this commit
2023-10-30 19:08:35 -05:00
4bc5cf7c64 [require c++20] [moved to stduuid]
Some checks failed
BlockStorage/repertory_osx/pipeline/head There was a failure building this commit
BlockStorage/repertory_linux_builds/pipeline/head Build started...
2023-10-30 19:03:12 -05:00
639d14452b Address compiler warnings #10
Some checks failed
BlockStorage/repertory_osx/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head There was a failure building this commit
2023-10-30 13:31:52 -05:00
e7413fb741 Address compiler warnings #10
All checks were successful
BlockStorage/repertory_osx/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head This commit looks good
2023-10-30 12:06:07 -05:00
c0e720498d Address compiler warnings #10
All checks were successful
BlockStorage/repertory_osx/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head This commit looks good
2023-10-30 11:49:56 -05:00
383c3b4be6 Address compiler warnings #10 [Wconversion] 2023-10-30 11:41:45 -05:00
e9b202f5c8 \#10 Address compiler warnings
All checks were successful
BlockStorage/repertory_osx/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head This commit looks good
2023-10-30 11:07:42 -05:00
bc3005a6a4 \#10 Address compiler warnings 2023-10-30 10:59:04 -05:00
8cf19e0594 \#10 Address compiler warnings 2023-10-30 10:54:35 -05:00
b137b57dbc \#10 Address compiler warnings 2023-10-30 10:36:31 -05:00
5dff8927da build win32 last
All checks were successful
BlockStorage/repertory_osx/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head This commit looks good
2023-10-30 10:04:00 -05:00
197e79dd07 fix mingw64 jenkins build
All checks were successful
BlockStorage/repertory_osx/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head This commit looks good
2023-10-30 10:02:55 -05:00
6262aca761 cmake build cleanup
Some checks failed
BlockStorage/repertory_osx/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head There was a failure building this commit
2023-10-29 20:38:13 -05:00
c156ae704b cmake build refactor
All checks were successful
BlockStorage/repertory_osx/pipeline/head This commit looks good
2023-10-29 20:21:37 -05:00
a67979ec40 cleanup build
All checks were successful
BlockStorage/repertory_osx/pipeline/head This commit looks good
2023-10-29 20:05:38 -05:00
54bfc11620 fix erroneous nodiscard
All checks were successful
BlockStorage/repertory_osx/pipeline/head This commit looks good
2023-10-29 19:45:21 -05:00
d33c2cd3a2 removed msvc compilation support
Some checks are pending
BlockStorage/repertory_linux_builds/pipeline/head Build queued...
BlockStorage/repertory_osx/pipeline/head Build queued...
2023-10-29 19:40:29 -05:00
3a5f428fb6 [boost to v1.83.0] [curl to v8.4.0] [libsodium to v1.0.19] [rocksdb to v8.6.7]
Some checks reported errors
BlockStorage/repertory_windows/pipeline/head Something is wrong with the build of this commit
BlockStorage/repertory_osx/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head There was a failure building this commit
2023-10-29 19:26:09 -05:00
0331152569 add zlib as project dependency
All checks were successful
BlockStorage/repertory_windows/pipeline/head This commit looks good
BlockStorage/repertory_osx/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head This commit looks good
2023-10-29 19:12:16 -05:00
1b7e854f5f added zlib
All checks were successful
BlockStorage/repertory_windows/pipeline/head This commit looks good
BlockStorage/repertory_osx/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head This commit looks good
2023-10-29 19:05:40 -05:00
12a945d863 updated version
All checks were successful
BlockStorage/repertory_osx/pipeline/head This commit looks good
BlockStorage/repertory_windows/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head This commit looks good
2023-10-29 01:59:00 -05:00
128 changed files with 5949 additions and 9615 deletions

View File

@ -1,38 +1,8 @@
--- ---
Checks: 'clang-*,misc-unused-*,llvm-header-guard,llvm-include-order,modernize-*' Checks: '-*,clang-diagnostic-*,clang-analyzer-*,bugprone-*,concurrency-*,cppcoreguidelines-*,modernize-*,readability-*,-readability-redundant-access-specifiers,-readability-function-cognitive-complexity'
WarningsAsErrors: '' WarningsAsErrors: ''
HeaderFilterRegex: '' HeaderFilterRegex: ''
AnalyzeTemporaryDtors: false AnalyzeTemporaryDtors: false
FormatStyle: none FormatStyle: none
User: sgraves User: sgraves
CheckOptions:
- key: cert-dcl16-c.NewSuffixes
value: 'L;LL;LU;LLU'
- key: cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField
value: '0'
- key: cppcoreguidelines-explicit-virtual-functions.IgnoreDestructors
value: '1'
- key: cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic
value: '1'
- key: google-readability-braces-around-statements.ShortStatementLines
value: '1'
- key: google-readability-function-size.StatementThreshold
value: '800'
- key: google-readability-namespace-comments.ShortNamespaceLines
value: '10'
- key: google-readability-namespace-comments.SpacesBeforeComments
value: '2'
- key: modernize-loop-convert.MaxCopySize
value: '16'
- key: modernize-loop-convert.MinConfidence
value: reasonable
- key: modernize-loop-convert.NamingStyle
value: CamelCase
- key: modernize-pass-by-value.IncludeStyle
value: llvm
- key: modernize-replace-auto-ptr.IncludeStyle
value: llvm
- key: modernize-use-nullptr.NullMacros
value: 'NULL'
... ...

View File

@ -144,6 +144,7 @@ lptr
lpwstr lpwstr
lzma lzma
makefiles makefiles
markdownlint
mbig mbig
mockwinfspdrive mockwinfspdrive
mqtt mqtt
@ -157,6 +158,8 @@ nmake
noappledouble noappledouble
nocache nocache
nocloseprocess nocloseprocess
nolintbegin
nolintend
nopath nopath
npubbytes npubbytes
ntfs ntfs
@ -209,6 +212,7 @@ smatch
sopen sopen
stbuf stbuf
stdc stdc
stduuid
stod stod
stoi stoi
stoll stoll
@ -224,6 +228,7 @@ szlib_libpath
target_precompile_headers target_precompile_headers
teventsystem teventsystem
tolower tolower
tomykaira
toolset toolset
ttmath ttmath
ularge ularge
@ -254,6 +259,7 @@ woverloaded
wpedantic wpedantic
wshadow wshadow
wsign wsign
wunknown
wunused wunused
wuseless wuseless
xattr xattr

1
.gitignore vendored
View File

@ -15,3 +15,4 @@ tags
src/common.cpp src/common.cpp
cspell.json cspell.json
dviml dviml
*.log

View File

@ -6,7 +6,7 @@ pipeline {
environment { environment {
BUILD_ARGS = '--build . -j 8' BUILD_ARGS = '--build . -j 8'
CONFIGURE_ARGS = '../.. -DCMAKE_BUILD_TYPE=Release -DREPERTORY_ENABLE_S3=ON' CONFIGURE_ARGS = '../.. -DCMAKE_BUILD_TYPE=Release -DREPERTORY_ENABLE_S3=ON'
CONFIGURE_MINGW64_ARGS = '../.. -DCMAKE_BUILD_TYPE=Release -DREPERTORY_ENABLE_S3=ON -DCMAKE_TOOLCHAIN_FILE=../../cmake/mingw-w64-x86_64.cmake' CONFIGURE_MINGW64_ARGS = '../.. -DCMAKE_BUILD_TYPE=Release -DREPERTORY_ENABLE_S3=ON -DCMAKE_TOOLCHAIN_FILE=${WORKSPACE}/cmake/mingw-w64-x86_64.cmake'
REPERTORY_TEST_DIR = "${HOME}/.ci/cfg" REPERTORY_TEST_DIR = "${HOME}/.ci/cfg"
} }
@ -86,9 +86,9 @@ pipeline {
agent any agent any
steps { steps {
sh 'scripts/make_package.sh alpine /home/sgraves/cert build/alpine_arm64 . /mnt/filebase 1' sh 'scripts/make_package.sh alpine /home/sgraves/cert build/alpine_arm64 . /mnt/storj 1'
sh 'scripts/make_package.sh alpine /home/sgraves/cert build/alpine . /mnt/filebase' sh 'scripts/make_package.sh alpine /home/sgraves/cert build/alpine . /mnt/storj'
sh 'scripts/make_package.sh mingw64 /home/sgraves/cert build/mingw64 . /mnt/filebase' sh 'scripts/make_package.sh mingw64 /home/sgraves/cert build/mingw64 . /mnt/storj'
} }
} }
} }

View File

@ -36,7 +36,7 @@ pipeline {
steps { steps {
retry(2) { retry(2) {
sleep time: 5, unit: 'SECONDS' sleep time: 5, unit: 'SECONDS'
cmake arguments: '--build . -j 4', installation: 'InSearchPath', workingDir: 'build' cmake arguments: '--build . -j 3', installation: 'InSearchPath', workingDir: 'build'
} }
} }
} }
@ -47,7 +47,7 @@ pipeline {
} }
steps { steps {
sh 'scripts/make_package.sh darwin /Users/sgraves/cert build . /Users/sgraves/mnt/filebase' sh 'scripts/make_package.sh darwin /Users/sgraves/cert build . /Users/sgraves/mnt/storj'
} }
} }
} }

View File

@ -1,39 +0,0 @@
#!groovy
pipeline {
agent any
environment {
REPERTORY_TEST_DIR = "C:\\.ci\\cfg"
}
options {
disableConcurrentBuilds()
retry(2)
}
stages {
stage('clean') {
steps {
bat 'del /q build\\Release\\librepertory.lib || exit 0'
bat 'del /q build\\Release\\unittests.exe || exit 0'
bat 'del /q build\\Release\\repertory.exe || exit 0'
}
}
stage('configure') {
steps {
cmake arguments: '.. -DCMAKE_BUILD_TYPE=Release -DREPERTORY_ENABLE_S3=ON', installation: 'InSearchPath', workingDir: 'build'
}
}
stage('build') {
steps {
retry(2) {
sleep time: 5, unit: 'SECONDS'
cmake arguments: '--build . --target ALL_BUILD --config Release -j 4', installation: 'InSearchPath', workingDir: 'build'
}
}
}
}
}

File diff suppressed because it is too large Load Diff

876
3rd_party/stduuid/stduuid.h vendored Normal file
View File

@ -0,0 +1,876 @@
#ifndef STDUUID_H
#define STDUUID_H
#include <cstring>
#include <string>
#include <sstream>
#include <iomanip>
#include <array>
#include <string_view>
#include <iterator>
#include <random>
#include <memory>
#include <functional>
#include <type_traits>
#include <optional>
#include <chrono>
#include <numeric>
#include <atomic>
#ifdef __cplusplus
#if (__cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
#define LIBUUID_CPP20_OR_GREATER
#endif
#endif
#ifdef LIBUUID_CPP20_OR_GREATER
#include <span>
#else
#include <gsl/span>
#endif
#ifdef _WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#ifndef NOMINMAX
#define NOMINMAX
#endif
#ifdef UUID_SYSTEM_GENERATOR
#include <objbase.h>
#endif
#ifdef UUID_TIME_GENERATOR
#include <iphlpapi.h>
#pragma comment(lib, "IPHLPAPI.lib")
#endif
#elif defined(__linux__) || defined(__unix__)
#ifdef UUID_SYSTEM_GENERATOR
#include <uuid/uuid.h>
#endif
#elif defined(__APPLE__)
#ifdef UUID_SYSTEM_GENERATOR
#include <CoreFoundation/CFUUID.h>
#endif
#endif
namespace uuids {
#ifdef __cpp_lib_span
template <class ElementType, std::size_t Extent>
using span = std::span<ElementType, Extent>;
#else
template <class ElementType, std::ptrdiff_t Extent>
using span = gsl::span<ElementType, Extent>;
#endif
namespace detail {
template <typename TChar>
[[nodiscard]] constexpr inline unsigned char hex2char(TChar const ch) noexcept {
if (ch >= static_cast<TChar>('0') && ch <= static_cast<TChar>('9'))
return static_cast<unsigned char>(ch - static_cast<TChar>('0'));
if (ch >= static_cast<TChar>('a') && ch <= static_cast<TChar>('f'))
return static_cast<unsigned char>(10 + ch - static_cast<TChar>('a'));
if (ch >= static_cast<TChar>('A') && ch <= static_cast<TChar>('F'))
return static_cast<unsigned char>(10 + ch - static_cast<TChar>('A'));
return 0;
}
template <typename TChar>
[[nodiscard]] constexpr inline bool is_hex(TChar const ch) noexcept {
return (ch >= static_cast<TChar>('0') && ch <= static_cast<TChar>('9')) ||
(ch >= static_cast<TChar>('a') && ch <= static_cast<TChar>('f')) ||
(ch >= static_cast<TChar>('A') && ch <= static_cast<TChar>('F'));
}
template <typename TChar>
[[nodiscard]] constexpr std::basic_string_view<TChar>
to_string_view(TChar const *str) noexcept {
if (str)
return str;
return {};
}
template <typename StringType>
[[nodiscard]] constexpr std::basic_string_view<typename StringType::value_type,
typename StringType::traits_type>
to_string_view(StringType const &str) noexcept {
return str;
}
class sha1 {
public:
using digest32_t = uint32_t[5];
using digest8_t = uint8_t[20];
static constexpr unsigned int block_bytes = 64;
[[nodiscard]] inline static uint32_t
left_rotate(uint32_t value, size_t const count) noexcept {
return (value << count) ^ (value >> (32 - count));
}
sha1() { reset(); }
void reset() noexcept {
m_digest[0] = 0x67452301;
m_digest[1] = 0xEFCDAB89;
m_digest[2] = 0x98BADCFE;
m_digest[3] = 0x10325476;
m_digest[4] = 0xC3D2E1F0;
m_blockByteIndex = 0;
m_byteCount = 0;
}
void process_byte(uint8_t octet) {
this->m_block[this->m_blockByteIndex++] = octet;
++this->m_byteCount;
if (m_blockByteIndex == block_bytes) {
this->m_blockByteIndex = 0;
process_block();
}
}
void process_block(void const *const start, void const *const end) {
const uint8_t *begin = static_cast<const uint8_t *>(start);
const uint8_t *finish = static_cast<const uint8_t *>(end);
while (begin != finish) {
process_byte(*begin);
begin++;
}
}
void process_bytes(void const *const data, size_t const len) {
const uint8_t *block = static_cast<const uint8_t *>(data);
process_block(block, block + len);
}
uint32_t const *get_digest(digest32_t digest) {
size_t const bitCount = this->m_byteCount * 8;
process_byte(0x80);
if (this->m_blockByteIndex > 56) {
while (m_blockByteIndex != 0) {
process_byte(0);
}
while (m_blockByteIndex < 56) {
process_byte(0);
}
} else {
while (m_blockByteIndex < 56) {
process_byte(0);
}
}
process_byte(0);
process_byte(0);
process_byte(0);
process_byte(0);
process_byte(static_cast<unsigned char>((bitCount >> 24) & 0xFF));
process_byte(static_cast<unsigned char>((bitCount >> 16) & 0xFF));
process_byte(static_cast<unsigned char>((bitCount >> 8) & 0xFF));
process_byte(static_cast<unsigned char>((bitCount)&0xFF));
memcpy(digest, m_digest, 5 * sizeof(uint32_t));
return digest;
}
uint8_t const *get_digest_bytes(digest8_t digest) {
digest32_t d32;
get_digest(d32);
size_t di = 0;
digest[di++] = static_cast<uint8_t>(d32[0] >> 24);
digest[di++] = static_cast<uint8_t>(d32[0] >> 16);
digest[di++] = static_cast<uint8_t>(d32[0] >> 8);
digest[di++] = static_cast<uint8_t>(d32[0] >> 0);
digest[di++] = static_cast<uint8_t>(d32[1] >> 24);
digest[di++] = static_cast<uint8_t>(d32[1] >> 16);
digest[di++] = static_cast<uint8_t>(d32[1] >> 8);
digest[di++] = static_cast<uint8_t>(d32[1] >> 0);
digest[di++] = static_cast<uint8_t>(d32[2] >> 24);
digest[di++] = static_cast<uint8_t>(d32[2] >> 16);
digest[di++] = static_cast<uint8_t>(d32[2] >> 8);
digest[di++] = static_cast<uint8_t>(d32[2] >> 0);
digest[di++] = static_cast<uint8_t>(d32[3] >> 24);
digest[di++] = static_cast<uint8_t>(d32[3] >> 16);
digest[di++] = static_cast<uint8_t>(d32[3] >> 8);
digest[di++] = static_cast<uint8_t>(d32[3] >> 0);
digest[di++] = static_cast<uint8_t>(d32[4] >> 24);
digest[di++] = static_cast<uint8_t>(d32[4] >> 16);
digest[di++] = static_cast<uint8_t>(d32[4] >> 8);
digest[di++] = static_cast<uint8_t>(d32[4] >> 0);
return digest;
}
private:
void process_block() {
uint32_t w[80];
for (size_t i = 0; i < 16; i++) {
w[i] = static_cast<uint32_t>(m_block[i * 4 + 0] << 24);
w[i] |= static_cast<uint32_t>(m_block[i * 4 + 1] << 16);
w[i] |= static_cast<uint32_t>(m_block[i * 4 + 2] << 8);
w[i] |= static_cast<uint32_t>(m_block[i * 4 + 3]);
}
for (size_t i = 16; i < 80; i++) {
w[i] = left_rotate((w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16]), 1);
}
uint32_t a = m_digest[0];
uint32_t b = m_digest[1];
uint32_t c = m_digest[2];
uint32_t d = m_digest[3];
uint32_t e = m_digest[4];
for (std::size_t i = 0; i < 80; ++i) {
uint32_t f = 0;
uint32_t k = 0;
if (i < 20) {
f = (b & c) | (~b & d);
k = 0x5A827999;
} else if (i < 40) {
f = b ^ c ^ d;
k = 0x6ED9EBA1;
} else if (i < 60) {
f = (b & c) | (b & d) | (c & d);
k = 0x8F1BBCDC;
} else {
f = b ^ c ^ d;
k = 0xCA62C1D6;
}
uint32_t temp = left_rotate(a, 5) + f + e + k + w[i];
e = d;
d = c;
c = left_rotate(b, 30);
b = a;
a = temp;
}
m_digest[0] += a;
m_digest[1] += b;
m_digest[2] += c;
m_digest[3] += d;
m_digest[4] += e;
}
private:
digest32_t m_digest;
uint8_t m_block[64];
size_t m_blockByteIndex;
size_t m_byteCount;
};
template <typename CharT>
inline constexpr CharT empty_guid[37] = "00000000-0000-0000-0000-000000000000";
template <>
inline constexpr wchar_t empty_guid<wchar_t>[37] =
L"00000000-0000-0000-0000-000000000000";
template <typename CharT>
inline constexpr CharT guid_encoder[17] = "0123456789abcdef";
template <>
inline constexpr wchar_t guid_encoder<wchar_t>[17] = L"0123456789abcdef";
} // namespace detail
// --------------------------------------------------------------------------------------------------------------------------
// UUID format https://tools.ietf.org/html/rfc4122
// --------------------------------------------------------------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------------
// Field NDR Data Type Octet # Note
// --------------------------------------------------------------------------------------------------------------------------
// time_low unsigned long 0 - 3 The low field
// of the timestamp. time_mid unsigned short 4 - 5
// The middle field of the timestamp.
// time_hi_and_version unsigned short 6 - 7 The high
// field of the timestamp multiplexed with the version number.
// clock_seq_hi_and_reserved unsigned small 8 The high field of
// the clock sequence multiplexed with the variant. clock_seq_low
// unsigned small 9 The low field of the clock sequence. node
// character 10 - 15 The spatially unique node identifier.
// --------------------------------------------------------------------------------------------------------------------------
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | time_low |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | time_mid | time_hi_and_version |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// |clk_seq_hi_res | clk_seq_low | node (0-1) |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | node (2-5) |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// --------------------------------------------------------------------------------------------------------------------------
// enumerations
// --------------------------------------------------------------------------------------------------------------------------
// indicated by a bit pattern in octet 8, marked with N in
// xxxxxxxx-xxxx-xxxx-Nxxx-xxxxxxxxxxxx
enum class uuid_variant {
// NCS backward compatibility (with the obsolete Apollo Network Computing
// System 1.5 UUID format) N bit pattern: 0xxx > the first 6 octets of the
// UUID are a 48-bit timestamp (the number of 4 microsecond units of time
// since 1 Jan 1980 UTC); > the next 2 octets are reserved; > the next octet
// is the "address family"; > the final 7 octets are a 56-bit host ID in the
// form specified by the address family
ncs,
// RFC 4122/DCE 1.1
// N bit pattern: 10xx
// > big-endian byte order
rfc,
// Microsoft Corporation backward compatibility
// N bit pattern: 110x
// > little endian byte order
// > formely used in the Component Object Model (COM) library
microsoft,
// reserved for possible future definition
// N bit pattern: 111x
reserved
};
// indicated by a bit pattern in octet 6, marked with M in
// xxxxxxxx-xxxx-Mxxx-xxxx-xxxxxxxxxxxx
enum class uuid_version {
none = 0, // only possible for nil or invalid uuids
time_based = 1, // The time-based version specified in RFC 4122
dce_security = 2, // DCE Security version, with embedded POSIX UIDs.
name_based_md5 =
3, // The name-based version specified in RFS 4122 with MD5 hashing
random_number_based = 4, // The randomly or pseudo-randomly generated version
// specified in RFS 4122
name_based_sha1 =
5 // The name-based version specified in RFS 4122 with SHA1 hashing
};
// Forward declare uuid & to_string so that we can declare to_string as a friend
// later.
class uuid;
template <class CharT = char, class Traits = std::char_traits<CharT>,
class Allocator = std::allocator<CharT>>
std::basic_string<CharT, Traits, Allocator> to_string(uuid const &id);
// --------------------------------------------------------------------------------------------------------------------------
// uuid class
// --------------------------------------------------------------------------------------------------------------------------
class uuid {
public:
using value_type = uint8_t;
constexpr uuid() noexcept = default;
uuid(value_type (&arr)[16]) noexcept {
std::copy(std::cbegin(arr), std::cend(arr), std::begin(data));
}
constexpr uuid(std::array<value_type, 16> const &arr) noexcept : data{arr} {}
explicit uuid(span<value_type, 16> bytes) {
std::copy(std::cbegin(bytes), std::cend(bytes), std::begin(data));
}
template <typename ForwardIterator>
explicit uuid(ForwardIterator first, ForwardIterator last) {
if (std::distance(first, last) == 16)
std::copy(first, last, std::begin(data));
}
[[nodiscard]] constexpr uuid_variant variant() const noexcept {
if ((data[8] & 0x80) == 0x00)
return uuid_variant::ncs;
else if ((data[8] & 0xC0) == 0x80)
return uuid_variant::rfc;
else if ((data[8] & 0xE0) == 0xC0)
return uuid_variant::microsoft;
else
return uuid_variant::reserved;
}
[[nodiscard]] constexpr uuid_version version() const noexcept {
if ((data[6] & 0xF0) == 0x10)
return uuid_version::time_based;
else if ((data[6] & 0xF0) == 0x20)
return uuid_version::dce_security;
else if ((data[6] & 0xF0) == 0x30)
return uuid_version::name_based_md5;
else if ((data[6] & 0xF0) == 0x40)
return uuid_version::random_number_based;
else if ((data[6] & 0xF0) == 0x50)
return uuid_version::name_based_sha1;
else
return uuid_version::none;
}
[[nodiscard]] constexpr bool is_nil() const noexcept {
for (size_t i = 0; i < data.size(); ++i)
if (data[i] != 0)
return false;
return true;
}
void swap(uuid &other) noexcept { data.swap(other.data); }
[[nodiscard]] inline span<std::byte const, 16> as_bytes() const {
return span<std::byte const, 16>(
reinterpret_cast<std::byte const *>(data.data()), 16);
}
template <typename StringType>
[[nodiscard]] constexpr static bool
is_valid_uuid(StringType const &in_str) noexcept {
auto str = detail::to_string_view(in_str);
bool firstDigit = true;
size_t hasBraces = 0;
size_t index = 0;
if (str.empty())
return false;
if (str.front() == '{')
hasBraces = 1;
if (hasBraces && str.back() != '}')
return false;
for (size_t i = hasBraces; i < str.size() - hasBraces; ++i) {
if (str[i] == '-')
continue;
if (index >= 16 || !detail::is_hex(str[i])) {
return false;
}
if (firstDigit) {
firstDigit = false;
} else {
index++;
firstDigit = true;
}
}
if (index < 16) {
return false;
}
return true;
}
template <typename StringType>
[[nodiscard]] constexpr static std::optional<uuid>
from_string(StringType const &in_str) noexcept {
auto str = detail::to_string_view(in_str);
bool firstDigit = true;
size_t hasBraces = 0;
size_t index = 0;
std::array<uint8_t, 16> data{{0}};
if (str.empty())
return {};
if (str.front() == '{')
hasBraces = 1;
if (hasBraces && str.back() != '}')
return {};
for (size_t i = hasBraces; i < str.size() - hasBraces; ++i) {
if (str[i] == '-')
continue;
if (index >= 16 || !detail::is_hex(str[i])) {
return {};
}
if (firstDigit) {
data[index] = static_cast<uint8_t>(detail::hex2char(str[i]) << 4);
firstDigit = false;
} else {
data[index] =
static_cast<uint8_t>(data[index] | detail::hex2char(str[i]));
index++;
firstDigit = true;
}
}
if (index < 16) {
return {};
}
return uuid{data};
}
private:
std::array<value_type, 16> data{{0}};
friend bool operator==(uuid const &lhs, uuid const &rhs) noexcept;
friend bool operator<(uuid const &lhs, uuid const &rhs) noexcept;
template <class Elem, class Traits>
friend std::basic_ostream<Elem, Traits> &
operator<<(std::basic_ostream<Elem, Traits> &s, uuid const &id);
template <class CharT, class Traits, class Allocator>
friend std::basic_string<CharT, Traits, Allocator> to_string(uuid const &id);
friend std::hash<uuid>;
};
// --------------------------------------------------------------------------------------------------------------------------
// operators and non-member functions
// --------------------------------------------------------------------------------------------------------------------------
[[nodiscard]] inline bool operator==(uuid const &lhs,
uuid const &rhs) noexcept {
return lhs.data == rhs.data;
}
[[nodiscard]] inline bool operator!=(uuid const &lhs,
uuid const &rhs) noexcept {
return !(lhs == rhs);
}
[[nodiscard]] inline bool operator<(uuid const &lhs, uuid const &rhs) noexcept {
return lhs.data < rhs.data;
}
template <class CharT, class Traits, class Allocator>
[[nodiscard]] inline std::basic_string<CharT, Traits, Allocator>
to_string(uuid const &id) {
std::basic_string<CharT, Traits, Allocator> uustr{detail::empty_guid<CharT>};
for (size_t i = 0, index = 0; i < 36; ++i) {
if (i == 8 || i == 13 || i == 18 || i == 23) {
continue;
}
uustr[i] = detail::guid_encoder<CharT>[id.data[index] >> 4 & 0x0f];
uustr[++i] = detail::guid_encoder<CharT>[id.data[index] & 0x0f];
index++;
}
return uustr;
}
template <class Elem, class Traits>
std::basic_ostream<Elem, Traits> &
operator<<(std::basic_ostream<Elem, Traits> &s, uuid const &id) {
s << to_string(id);
return s;
}
inline void swap(uuids::uuid &lhs, uuids::uuid &rhs) noexcept { lhs.swap(rhs); }
// --------------------------------------------------------------------------------------------------------------------------
// namespace IDs that could be used for generating name-based uuids
// --------------------------------------------------------------------------------------------------------------------------
// Name string is a fully-qualified domain name
static uuid uuid_namespace_dns{{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1,
0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30,
0xc8}};
// Name string is a URL
static uuid uuid_namespace_url{{0x6b, 0xa7, 0xb8, 0x11, 0x9d, 0xad, 0x11, 0xd1,
0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30,
0xc8}};
// Name string is an ISO OID (See https://oidref.com/,
// https://en.wikipedia.org/wiki/Object_identifier)
static uuid uuid_namespace_oid{{0x6b, 0xa7, 0xb8, 0x12, 0x9d, 0xad, 0x11, 0xd1,
0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30,
0xc8}};
// Name string is an X.500 DN, in DER or a text output format (See
// https://en.wikipedia.org/wiki/X.500,
// https://en.wikipedia.org/wiki/Abstract_Syntax_Notation_One)
static uuid uuid_namespace_x500{{0x6b, 0xa7, 0xb8, 0x14, 0x9d, 0xad, 0x11, 0xd1,
0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30,
0xc8}};
// --------------------------------------------------------------------------------------------------------------------------
// uuid generators
// --------------------------------------------------------------------------------------------------------------------------
#ifdef UUID_SYSTEM_GENERATOR
class uuid_system_generator {
public:
using result_type = uuid;
uuid operator()() {
#ifdef _WIN32
GUID newId;
HRESULT hr = ::CoCreateGuid(&newId);
if (FAILED(hr)) {
throw std::system_error(hr, std::system_category(),
"CoCreateGuid failed");
}
std::array<uint8_t, 16> bytes = {
{static_cast<unsigned char>((newId.Data1 >> 24) & 0xFF),
static_cast<unsigned char>((newId.Data1 >> 16) & 0xFF),
static_cast<unsigned char>((newId.Data1 >> 8) & 0xFF),
static_cast<unsigned char>((newId.Data1) & 0xFF),
(unsigned char)((newId.Data2 >> 8) & 0xFF),
(unsigned char)((newId.Data2) & 0xFF),
(unsigned char)((newId.Data3 >> 8) & 0xFF),
(unsigned char)((newId.Data3) & 0xFF),
newId.Data4[0], newId.Data4[1], newId.Data4[2], newId.Data4[3],
newId.Data4[4], newId.Data4[5], newId.Data4[6], newId.Data4[7]}};
return uuid{std::begin(bytes), std::end(bytes)};
#elif defined(__linux__) || defined(__unix__)
uuid_t id;
uuid_generate(id);
std::array<uint8_t, 16> bytes = {{id[0], id[1], id[2], id[3], id[4], id[5],
id[6], id[7], id[8], id[9], id[10],
id[11], id[12], id[13], id[14], id[15]}};
return uuid{std::begin(bytes), std::end(bytes)};
#elif defined(__APPLE__)
auto newId = CFUUIDCreate(NULL);
auto bytes = CFUUIDGetUUIDBytes(newId);
CFRelease(newId);
std::array<uint8_t, 16> arrbytes = {
{bytes.byte0, bytes.byte1, bytes.byte2, bytes.byte3, bytes.byte4,
bytes.byte5, bytes.byte6, bytes.byte7, bytes.byte8, bytes.byte9,
bytes.byte10, bytes.byte11, bytes.byte12, bytes.byte13, bytes.byte14,
bytes.byte15}};
return uuid{std::begin(arrbytes), std::end(arrbytes)};
#else
return uuid{};
#endif
}
};
#endif
template <typename UniformRandomNumberGenerator>
class basic_uuid_random_generator {
public:
using engine_type = UniformRandomNumberGenerator;
explicit basic_uuid_random_generator(engine_type &gen)
: generator(&gen, [](auto) {}) {}
explicit basic_uuid_random_generator(engine_type *gen)
: generator(gen, [](auto) {}) {}
[[nodiscard]] uuid operator()() {
alignas(uint32_t) uint8_t bytes[16];
for (int i = 0; i < 16; i += 4)
*reinterpret_cast<uint32_t *>(bytes + i) = distribution(*generator);
// variant must be 10xxxxxx
bytes[8] &= 0xBF;
bytes[8] |= 0x80;
// version must be 0100xxxx
bytes[6] &= 0x4F;
bytes[6] |= 0x40;
return uuid{std::begin(bytes), std::end(bytes)};
}
private:
std::uniform_int_distribution<uint32_t> distribution;
std::shared_ptr<UniformRandomNumberGenerator> generator;
};
using uuid_random_generator = basic_uuid_random_generator<std::mt19937>;
class uuid_name_generator {
public:
explicit uuid_name_generator(uuid const &namespace_uuid) noexcept
: nsuuid(namespace_uuid) {}
template <typename StringType>
[[nodiscard]] uuid operator()(StringType const &name) {
reset();
process_characters(detail::to_string_view(name));
return make_uuid();
}
private:
void reset() {
hasher.reset();
std::byte bytes[16];
auto nsbytes = nsuuid.as_bytes();
std::copy(std::cbegin(nsbytes), std::cend(nsbytes), bytes);
hasher.process_bytes(bytes, 16);
}
template <typename CharT, typename Traits>
void process_characters(std::basic_string_view<CharT, Traits> const str) {
for (uint32_t c : str) {
hasher.process_byte(static_cast<uint8_t>(c & 0xFF));
if constexpr (!std::is_same_v<CharT, char>) {
hasher.process_byte(static_cast<uint8_t>((c >> 8) & 0xFF));
hasher.process_byte(static_cast<uint8_t>((c >> 16) & 0xFF));
hasher.process_byte(static_cast<uint8_t>((c >> 24) & 0xFF));
}
}
}
[[nodiscard]] uuid make_uuid() {
detail::sha1::digest8_t digest;
hasher.get_digest_bytes(digest);
// variant must be 0b10xxxxxx
digest[8] &= 0xBF;
digest[8] |= 0x80;
// version must be 0b0101xxxx
digest[6] &= 0x5F;
digest[6] |= 0x50;
return uuid{digest, digest + 16};
}
private:
uuid nsuuid;
detail::sha1 hasher;
};
#ifdef UUID_TIME_GENERATOR
// !!! DO NOT USE THIS IN PRODUCTION
// this implementation is unreliable for good uuids
class uuid_time_generator {
using mac_address = std::array<unsigned char, 6>;
std::optional<mac_address> device_address;
[[nodiscard]] bool get_mac_address() {
if (device_address.has_value()) {
return true;
}
#ifdef _WIN32
DWORD len = 0;
auto ret = GetAdaptersInfo(nullptr, &len);
if (ret != ERROR_BUFFER_OVERFLOW)
return false;
std::vector<unsigned char> buf(len);
auto pips = reinterpret_cast<PIP_ADAPTER_INFO>(&buf.front());
ret = GetAdaptersInfo(pips, &len);
if (ret != ERROR_SUCCESS)
return false;
mac_address addr;
std::copy(pips->Address, pips->Address + 6, std::begin(addr));
device_address = addr;
#endif
return device_address.has_value();
}
[[nodiscard]] long long get_time_intervals() {
auto start = std::chrono::system_clock::from_time_t(time_t(-12219292800));
auto diff = std::chrono::system_clock::now() - start;
auto ns =
std::chrono::duration_cast<std::chrono::nanoseconds>(diff).count();
return ns / 100;
}
[[nodiscard]] static unsigned short get_clock_sequence() {
static std::mt19937 clock_gen(std::random_device{}());
static std::uniform_int_distribution<unsigned short> clock_dis;
static std::atomic_ushort clock_sequence = clock_dis(clock_gen);
return clock_sequence++;
}
public:
[[nodiscard]] uuid operator()() {
if (get_mac_address()) {
std::array<uuids::uuid::value_type, 16> data;
auto tm = get_time_intervals();
auto clock_seq = get_clock_sequence();
auto ptm = reinterpret_cast<uuids::uuid::value_type *>(&tm);
memcpy(&data[0], ptm + 4, 4);
memcpy(&data[4], ptm + 2, 2);
memcpy(&data[6], ptm, 2);
memcpy(&data[8], &clock_seq, 2);
// variant must be 0b10xxxxxx
data[8] &= 0xBF;
data[8] |= 0x80;
// version must be 0b0001xxxx
data[6] &= 0x1F;
data[6] |= 0x10;
memcpy(&data[10], &device_address.value()[0], 6);
return uuids::uuid{std::cbegin(data), std::cend(data)};
}
return {};
}
};
#endif
} // namespace uuids
namespace std {
template <> struct hash<uuids::uuid> {
using argument_type = uuids::uuid;
using result_type = std::size_t;
[[nodiscard]] result_type operator()(argument_type const &uuid) const {
#ifdef UUID_HASH_STRING_BASED
std::hash<std::string> hasher;
return static_cast<result_type>(hasher(uuids::to_string(uuid)));
#else
uint64_t l = static_cast<uint64_t>(uuid.data[0]) << 56 |
static_cast<uint64_t>(uuid.data[1]) << 48 |
static_cast<uint64_t>(uuid.data[2]) << 40 |
static_cast<uint64_t>(uuid.data[3]) << 32 |
static_cast<uint64_t>(uuid.data[4]) << 24 |
static_cast<uint64_t>(uuid.data[5]) << 16 |
static_cast<uint64_t>(uuid.data[6]) << 8 |
static_cast<uint64_t>(uuid.data[7]);
uint64_t h = static_cast<uint64_t>(uuid.data[8]) << 56 |
static_cast<uint64_t>(uuid.data[9]) << 48 |
static_cast<uint64_t>(uuid.data[10]) << 40 |
static_cast<uint64_t>(uuid.data[11]) << 32 |
static_cast<uint64_t>(uuid.data[12]) << 24 |
static_cast<uint64_t>(uuid.data[13]) << 16 |
static_cast<uint64_t>(uuid.data[14]) << 8 |
static_cast<uint64_t>(uuid.data[15]);
if constexpr (sizeof(result_type) > 4) {
return result_type(l ^ h);
} else {
uint64_t hash64 = l ^ h;
return result_type(uint32_t(hash64 >> 32) ^ uint32_t(hash64));
}
#endif
}
};
} // namespace std
#endif /* STDUUID_H */

View File

@ -1,7 +1,25 @@
# Changelog # Changelog
## 2.0.1-rc
### Issues
* \#10 Address compiler warnings
### Changes from v2.0.0-rc
* Refactored S3 provider
* Require `c++20`
* Removed MSVC compilation support (MinGW-64 should be used)
* Updated `boost` to v1.83.0
* Updated `curl` to v8.4.0
* Updated `libsodium` to v1.0.19
* Updated `OpenSSL` to v3.1.4
* Updated `rocksdb` to v8.6.7
## 2.0.0-rc ## 2.0.0-rc
<!-- markdownlint-disable-next-line -->
### Issues ### Issues
* \#1 \[bug\] Unable to mount S3 due to 'item_not_found' exception * \#1 \[bug\] Unable to mount S3 due to 'item_not_found' exception

View File

@ -11,7 +11,7 @@ include(ExternalProject)
set(REPERTORY_MAJOR 2) set(REPERTORY_MAJOR 2)
set(REPERTORY_MINOR 0) set(REPERTORY_MINOR 0)
set(REPERTORY_REV 0) set(REPERTORY_REV 1)
set(REPERTORY_RELEASE_NUM 0) set(REPERTORY_RELEASE_NUM 0)
set(REPERTORY_RELEASE_ITER rc) set(REPERTORY_RELEASE_ITER rc)
set(REPERTORY_VERSION ${REPERTORY_MAJOR}.${REPERTORY_MINOR}.${REPERTORY_REV}-${REPERTORY_RELEASE_ITER}) set(REPERTORY_VERSION ${REPERTORY_MAJOR}.${REPERTORY_MINOR}.${REPERTORY_REV}-${REPERTORY_RELEASE_ITER})
@ -44,24 +44,13 @@ if (UNIX)
endif() endif()
endif() endif()
if (MSVC OR MINGW)
set(WINFSP_LIBRARY_BASENAME winfsp-x64)
include_directories(SYSTEM ${CMAKE_SOURCE_DIR}/3rd_party/winfsp-${WINFSP_VERSION}/inc)
link_directories(${CMAKE_SOURCE_DIR}/3rd_party/winfsp-${WINFSP_VERSION}/lib)
set(REPERTORY_LINK_LIBRARIES
${REPERTORY_LINK_LIBRARIES}
${WINFSP_LIBRARY_BASENAME}.lib
)
endif()
if (LINUX OR MINGW) if (LINUX OR MINGW)
if (CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.0) if (CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.0)
message(FATAL_ERROR "Require at least gcc-8.0") message(FATAL_ERROR "Require at least gcc-8.0")
endif() endif()
set(ENV{PKG_CONFIG_PATH} set(ENV{PKG_CONFIG_PATH}
"${EXTERNAL_BUILD_ROOT}/lib/pkgconfig:${EXTERNAL_BUILD_ROOT}/lib64/pkgconfig:$ENV{PKG_CONFIG_PATH}" "${EXTERNAL_BUILD_ROOT}/lib/pkgconfig:$ENV{PKG_CONFIG_PATH}"
) )
find_package(PkgConfig REQUIRED) find_package(PkgConfig REQUIRED)
@ -163,27 +152,20 @@ elseif (MACOS)
"-framework SystemConfiguration" "-framework SystemConfiguration"
) )
elseif (MSVC) elseif (MSVC)
set(OPENSSL_USE_STATIC_LIBS TRUE) message(FATAL_ERROR "MSVC is currently not supported [MinGW-64 should be used]")
if (NOT OPENSSL_ROOT_DIR)
set (OPENSSL_ROOT_DIR "$ENV{USERPROFILE}\\scoop\\apps\\openssl\\current")
endif()
find_package(OpenSSL 1.1.1 REQUIRED)
set(OPENSSL_LIBRARIES OpenSSL::SSL OpenSSL::Crypto)
set(REPERTORY_DEFINITIONS ${REPERTORY_DEFINITIONS} -D_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING)
if (NOT CMAKE_GENERATOR_LOWER STREQUAL "nmake makefiles")
set(REPERTORY_OUTPUT_DIR ${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE})
endif()
endif() endif()
if (MINGW) if (MINGW)
set(WINFSP_LIBRARY_BASENAME winfsp-x64)
include_directories(SYSTEM ${CMAKE_SOURCE_DIR}/3rd_party/winfsp-${WINFSP_VERSION}/inc)
link_directories(${CMAKE_SOURCE_DIR}/3rd_party/winfsp-${WINFSP_VERSION}/lib)
set(REPERTORY_LINK_LIBRARIES set(REPERTORY_LINK_LIBRARIES
${REPERTORY_LINK_LIBRARIES} ${REPERTORY_LINK_LIBRARIES}
${WINFSP_LIBRARY_BASENAME}.lib
mswsock mswsock
) )
endif()
if (MSVC OR MINGW)
set(REPERTORY_VER_FILEVERSION ${REPERTORY_MAJOR},${REPERTORY_MINOR},${REPERTORY_REV},${REPERTORY_RELEASE_NUM}) set(REPERTORY_VER_FILEVERSION ${REPERTORY_MAJOR},${REPERTORY_MINOR},${REPERTORY_REV},${REPERTORY_RELEASE_NUM})
set(REPERTORY_VER_FILEVERSION_STR ${REPERTORY_MAJOR}.${REPERTORY_MINOR}.${REPERTORY_REV}.${REPERTORY_RELEASE_NUM}) set(REPERTORY_VER_FILEVERSION_STR ${REPERTORY_MAJOR}.${REPERTORY_MINOR}.${REPERTORY_REV}.${REPERTORY_RELEASE_NUM})
set(REPERTORY_VER_PRODUCTVERSION ${REPERTORY_MAJOR},${REPERTORY_MINOR},${REPERTORY_REV},${REPERTORY_RELEASE_NUM}) set(REPERTORY_VER_PRODUCTVERSION ${REPERTORY_MAJOR},${REPERTORY_MINOR},${REPERTORY_REV},${REPERTORY_RELEASE_NUM})
@ -195,10 +177,6 @@ if (MSVC OR MINGW)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/version.rc.in ${CMAKE_CURRENT_SOURCE_DIR}/src/version.rc @ONLY) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/version.rc.in ${CMAKE_CURRENT_SOURCE_DIR}/src/version.rc @ONLY)
set(WINDOWS_VERSION_RC ${CMAKE_CURRENT_SOURCE_DIR}/src/version.rc) set(WINDOWS_VERSION_RC ${CMAKE_CURRENT_SOURCE_DIR}/src/version.rc)
if (MSVC)
set(LIB_EXT .lib)
endif()
set(REPERTORY_LINK_LIBRARIES set(REPERTORY_LINK_LIBRARIES
${REPERTORY_LINK_LIBRARIES} ${REPERTORY_LINK_LIBRARIES}
advapi32${LIB_EXT} advapi32${LIB_EXT}
@ -232,27 +210,27 @@ include_directories(SYSTEM
link_directories( link_directories(
${EXTERNAL_BUILD_ROOT}/lib ${EXTERNAL_BUILD_ROOT}/lib
${EXTERNAL_BUILD_ROOT}/lib64
) )
include(cmake/zlib.cmake) include(cmake/zlib.cmake)
include(cmake/openssl.cmake) include(cmake/openssl.cmake)
include(cmake/curl.cmake) include(cmake/curl.cmake)
include(cmake/boost.cmake) include(cmake/boost.cmake)
include(cmake/libuuid.cmake)
include(cmake/rocksdb.cmake) include(cmake/rocksdb.cmake)
include(cmake/libsodium.cmake) include(cmake/libsodium.cmake)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/common.cpp.in ${CMAKE_CURRENT_SOURCE_DIR}/src/common.cpp @ONLY)
include_directories(include) include_directories(include)
include_directories(SYSTEM include_directories(SYSTEM
${Boost_INCLUDE_DIR} ${Boost_INCLUDE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/cpp-httplib ${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/cpp-httplib
${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/stduuid
${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/json ${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/json
${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/pugixml/src ${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/pugixml/src
${CURL_INCLUDE_DIRS} ${CURL_INCLUDE_DIRS}
${LIBFUSE2_INCLUDE_DIRS} ${LIBFUSE2_INCLUDE_DIRS}
${LIBFUSE3_INCLUDE_DIRS} ${LIBFUSE3_INCLUDE_DIRS}
${LIBUUID_INCLUDE_DIR}
${OPENSSL_INCLUDE_DIR} ${OPENSSL_INCLUDE_DIR}
${ROCKSDB_INCLUDE_DIRS} ${ROCKSDB_INCLUDE_DIRS}
) )
@ -261,7 +239,6 @@ set(REPERTORY_LINK_LIBRARIES
${ROCKSDB_LIBRARIES} ${ROCKSDB_LIBRARIES}
${LIBFUSE2_LIBRARIES} ${LIBFUSE2_LIBRARIES}
${LIBFUSE3_LIBRARIES} ${LIBFUSE3_LIBRARIES}
${LIBUUID_LIBRARIES}
${Boost_LIBRARIES} ${Boost_LIBRARIES}
${CURL_LIBRARIES} ${CURL_LIBRARIES}
${OPENSSL_LIBRARIES} ${OPENSSL_LIBRARIES}
@ -287,8 +264,6 @@ file(GLOB_RECURSE REPERTORY_SOURCES
) )
list(REMOVE_ITEM REPERTORY_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp) list(REMOVE_ITEM REPERTORY_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/common.cpp.in ${CMAKE_CURRENT_SOURCE_DIR}/src/common.cpp @ONLY)
include(cmake/helpers.cmake) include(cmake/helpers.cmake)
include(cmake/librepertory.cmake) include(cmake/librepertory.cmake)
include(cmake/repertory.cmake) include(cmake/repertory.cmake)

View File

@ -36,7 +36,6 @@ on Windows.
* [boost c++ libraries](https://www.boost.org/) * [boost c++ libraries](https://www.boost.org/)
* [cpp-httplib](https://github.com/yhirose/cpp-httplib) * [cpp-httplib](https://github.com/yhirose/cpp-httplib)
* [curl](https://curl.haxx.se/) * [curl](https://curl.haxx.se/)
* [Filebase](https://filebase.com/)
* [FUSE for macOS](https://osxfuse.github.io/) * [FUSE for macOS](https://osxfuse.github.io/)
* [Google Test](https://github.com/google/googletest) * [Google Test](https://github.com/google/googletest)
* [JSON for Modern C++](https://github.com/nlohmann/json) * [JSON for Modern C++](https://github.com/nlohmann/json)
@ -47,6 +46,8 @@ on Windows.
* [RocksDB](https://rocksdb.org/) * [RocksDB](https://rocksdb.org/)
* [ScPrime](https://scpri.me/) * [ScPrime](https://scpri.me/)
* [Sia Decentralized Cloud Storage](https://sia.tech/) * [Sia Decentralized Cloud Storage](https://sia.tech/)
* [stduuid](https://github.com/mariusbancila/stduuid)
* [Storj](https://storj.io/)
* [WinFSP - FUSE for Windows](https://github.com/billziss-gh/winfsp) * [WinFSP - FUSE for Windows](https://github.com/billziss-gh/winfsp)
* [zlib](https://zlib.net/) * [zlib](https://zlib.net/)

View File

@ -1,24 +1,26 @@
set(BOOST_VERSION ${BOOST_MAJOR_VERSION}.${BOOST_MINOR_VERSION}.${BOOST_REVISION})
set(BOOST_VERSION2 ${BOOST_MAJOR_VERSION}_${BOOST_MINOR_VERSION}_${BOOST_REVISION})
set(BOOST_PROJECT_NAME boost_${BOOST_VERSION}) set(BOOST_PROJECT_NAME boost_${BOOST_VERSION})
set(BOOST_BUILD_ROOT ${EXTERNAL_BUILD_ROOT}/builds/${BOOST_PROJECT_NAME}) set(BOOST_BUILD_ROOT ${EXTERNAL_BUILD_ROOT}/builds/${BOOST_PROJECT_NAME})
set(BOOST_ADDRESS_MODEL 64) set(BOOST_ADDRESS_MODEL 64)
set(BOOST_DLL_ARCH x64)
set(BOOST_DOWNLOAD_URL https://boostorg.jfrog.io/artifactory/main/release/${BOOST_VERSION}/source/boost_${BOOST_VERSION_DL}.tar.gz)
if (UNIX OR MINGW) set(BOOST_DOWNLOAD_URL https://boostorg.jfrog.io/artifactory/main/release/${BOOST_VERSION}/source/boost_${BOOST_VERSION2}.tar.gz)
if (IS_CLANG_COMPILER)
if (IS_CLANG_COMPILER)
set(BOOST_TOOLSET --with-toolset=clang) set(BOOST_TOOLSET --with-toolset=clang)
else () else ()
set(BOOST_OPENSSL_DIR "--openssldir=${EXTERNAL_BUILD_ROOT}") set(BOOST_OPENSSL_DIR "--openssldir=${EXTERNAL_BUILD_ROOT}")
endif() endif()
if (IS_ARM64) if (IS_ARM64)
set (BOOST_ARCH arm) set (BOOST_ARCH arm)
else() else()
set (BOOST_ARCH x86) set (BOOST_ARCH x86)
endif() endif()
set (BOOST_COMMON_ARGS set (BOOST_COMMON_ARGS
${BOOST_OPENSSL_DIR} ${BOOST_OPENSSL_DIR}
--prefix=${EXTERNAL_BUILD_ROOT} --prefix=${EXTERNAL_BUILD_ROOT}
address-model=${BOOST_ADDRESS_MODEL} address-model=${BOOST_ADDRESS_MODEL}
@ -31,17 +33,20 @@ if (UNIX OR MINGW)
linkflags=-std=c++${CMAKE_CXX_STANDARD} linkflags=-std=c++${CMAKE_CXX_STANDARD}
threading=multi threading=multi
variant=${CMAKE_BUILD_TYPE_LOWER} variant=${CMAKE_BUILD_TYPE_LOWER}
) -sZLIB_BINARY=zlibstatic${DEBUG_EXTRA}
-sZLIB_LIBPATH="${EXTERNAL_BUILD_ROOT}/lib"
-sZLIB_INCLUDE="${EXTERNAL_BUILD_ROOT}/include"
)
if (MINGW) if (MINGW)
set(BOOST_COMMON_ARGS set(BOOST_COMMON_ARGS
${BOOST_COMMON_ARGS} ${BOOST_COMMON_ARGS}
--user-config=./user-config.jam --user-config=./user-config.jam
) )
set(BOOST_TARGET_OS target-os=windows) set(BOOST_TARGET_OS target-os=windows)
endif() endif()
ExternalProject_Add(boost_project ExternalProject_Add(boost_project
DOWNLOAD_NO_PROGRESS 1 DOWNLOAD_NO_PROGRESS 1
URL ${BOOST_DOWNLOAD_URL} URL ${BOOST_DOWNLOAD_URL}
PREFIX ${BOOST_BUILD_ROOT} PREFIX ${BOOST_BUILD_ROOT}
@ -61,19 +66,19 @@ if (UNIX OR MINGW)
${BOOST_COMMON_ARGS} ${BOOST_COMMON_ARGS}
${BOOST_TARGET_OS} ${BOOST_TARGET_OS}
install install
) )
add_dependencies(boost_project openssl_project) add_dependencies(boost_project openssl_project)
set(BOOST_ROOT ${BOOST_BUILD_ROOT}/src/boost_project) set(BOOST_ROOT ${BOOST_BUILD_ROOT}/src/boost_project)
if (MINGW) if (MINGW)
set(BOOST_GCC_VERSION ${CMAKE_CXX_COMPILER_VERSION}) set(BOOST_GCC_VERSION ${CMAKE_CXX_COMPILER_VERSION})
string(REPLACE "." ";" BOOST_GCC_VERSION_LIST ${BOOST_GCC_VERSION}) string(REPLACE "." ";" BOOST_GCC_VERSION_LIST ${BOOST_GCC_VERSION})
list(GET BOOST_GCC_VERSION_LIST 0 BOOST_GCC_MAJOR_VERSION) list(GET BOOST_GCC_VERSION_LIST 0 BOOST_GCC_MAJOR_VERSION)
# set(BOOST_LIB_EXTRA "-mgw${BOOST_GCC_MAJOR_VERSION}-mt-x64-${BOOST_MAJOR_VERSION}_${BOOST_MINOR_VERSION}") # set(BOOST_LIB_EXTRA "-mgw${BOOST_GCC_MAJOR_VERSION}-mt-x64-${BOOST_MAJOR_VERSION}_${BOOST_MINOR_VERSION}")
endif() endif()
set(Boost_LIBRARIES set(Boost_LIBRARIES
libboost_system${BOOST_LIB_EXTRA}.a libboost_system${BOOST_LIB_EXTRA}.a
libboost_atomic${BOOST_LIB_EXTRA}.a libboost_atomic${BOOST_LIB_EXTRA}.a
libboost_chrono${BOOST_LIB_EXTRA}.a libboost_chrono${BOOST_LIB_EXTRA}.a
@ -83,55 +88,6 @@ if (UNIX OR MINGW)
libboost_regex${BOOST_LIB_EXTRA}.a libboost_regex${BOOST_LIB_EXTRA}.a
libboost_serialization${BOOST_LIB_EXTRA}.a libboost_serialization${BOOST_LIB_EXTRA}.a
libboost_thread${BOOST_LIB_EXTRA}.a libboost_thread${BOOST_LIB_EXTRA}.a
) )
elseif(MSVC)
set (BOOST_COMMON_ARGS
--with-date_time
--with-regex
--with-serialization
--with-system
--with-filesystem
--prefix=${EXTERNAL_BUILD_ROOT}
runtime-link=shared
threading=multi
address-model=${BOOST_ADDRESS_MODEL}
architecture=x86
toolset=${BOOST_MSVC_TOOLSET}
variant=${CMAKE_BUILD_TYPE_LOWER}
-sZLIB_BINARY=zlibstatic${DEBUG_EXTRA}
-sZLIB_LIBPATH="${EXTERNAL_BUILD_ROOT}/lib"
-sZLIB_INCLUDE="${EXTERNAL_BUILD_ROOT}/include"
)
ExternalProject_Add(boost_project add_dependencies(boost_project zlib_project)
DOWNLOAD_NO_PROGRESS 1
URL ${BOOST_DOWNLOAD_URL}
PREFIX ${BOOST_BUILD_ROOT}
BUILD_IN_SOURCE 1
CONFIGURE_COMMAND
bootstrap.bat
--with-date_time
--with-regex
--with-system
--with-serialization
--with-filesystem
BUILD_COMMAND
b2.exe
${BOOST_COMMON_ARGS}
INSTALL_COMMAND
b2.exe
install
${BOOST_COMMON_ARGS}
)
add_dependencies(boost_project zlib_project)
set(BOOST_ROOT ${BOOST_BUILD_ROOT}/src/boost_project)
set(Boost_INCLUDE_DIR ${EXTERNAL_BUILD_ROOT}/include/boost-${BOOST_VERSION_DLL})
set(Boost_LIBRARIES
${EXTERNAL_BUILD_ROOT}/lib/libboost_date_time-vc${BOOST_MSVC_TOOLSET_DLL}-mt-${BOOST_DEBUG_EXTRA}${BOOST_DLL_ARCH}-${BOOST_VERSION_DLL}.lib
${EXTERNAL_BUILD_ROOT}/lib/libboost_filesystem-vc${BOOST_MSVC_TOOLSET_DLL}-mt-${BOOST_DEBUG_EXTRA}${BOOST_DLL_ARCH}-${BOOST_VERSION_DLL}.lib
${EXTERNAL_BUILD_ROOT}/lib/libboost_regex-vc${BOOST_MSVC_TOOLSET_DLL}-mt-${BOOST_DEBUG_EXTRA}${BOOST_DLL_ARCH}-${BOOST_VERSION_DLL}.lib
${EXTERNAL_BUILD_ROOT}/lib/libboost_serialization-vc${BOOST_MSVC_TOOLSET_DLL}-mt-${BOOST_DEBUG_EXTRA}${BOOST_DLL_ARCH}-${BOOST_VERSION_DLL}.lib
${EXTERNAL_BUILD_ROOT}/lib/libboost_system-vc${BOOST_MSVC_TOOLSET_DLL}-mt-${BOOST_DEBUG_EXTRA}${BOOST_DLL_ARCH}-${BOOST_VERSION_DLL}.lib
)
endif()

View File

@ -31,14 +31,20 @@ set(CURL_CMAKE_ARGS
-DUSE_LIBIDN2=OFF -DUSE_LIBIDN2=OFF
) )
if (MINGW AND CMAKE_TOOLCHAIN_FILE) if (CMAKE_TOOLCHAIN_FILE)
set(CURL_CMAKE_ARGS set(CURL_CMAKE_ARGS
${CURL_CMAKE_ARGS} ${CURL_CMAKE_ARGS}
-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
)
endif()
if (MINGW)
set(CURL_CMAKE_ARGS
${CURL_CMAKE_ARGS}
-DCURL_USE_OPENSSL=OFF -DCURL_USE_OPENSSL=OFF
-DUSE_WIN32_CRYPTO=ON -DUSE_WIN32_CRYPTO=ON
) )
elseif(NOT MINGW) else()
set(CURL_CMAKE_ARGS set(CURL_CMAKE_ARGS
${CURL_CMAKE_ARGS} ${CURL_CMAKE_ARGS}
-DCURL_USE_OPENSSL=ON -DCURL_USE_OPENSSL=ON
@ -54,9 +60,8 @@ ExternalProject_Add(curl_project
set(REPERTORY_DEFINITIONS ${REPERTORY_DEFINITIONS} -DCURL_STATICLIB=ON -DCURL_DISABLE_LDAP=ON) set(REPERTORY_DEFINITIONS ${REPERTORY_DEFINITIONS} -DCURL_STATICLIB=ON -DCURL_DISABLE_LDAP=ON)
if (MSVC) set(CURL_LIBRARIES libcurl${DEBUG_EXTRA2}${CMAKE_STATIC_LIBRARY_SUFFIX})
set(CURL_LIBRARIES ${EXTERNAL_BUILD_ROOT}/lib/libcurl${DEBUG_EXTRA2}${CMAKE_STATIC_LIBRARY_SUFFIX}) add_dependencies(curl_project
else() openssl_project
set(CURL_LIBRARIES libcurl${DEBUG_EXTRA2}${CMAKE_STATIC_LIBRARY_SUFFIX}) zlib_project
add_dependencies(curl_project openssl_project) )
endif()

View File

@ -73,41 +73,6 @@ if (UNIX OR MINGW)
${REPERTORY_COMMON_FLAG_LIST} ${REPERTORY_COMMON_FLAG_LIST}
-std=c++${CMAKE_CXX_STANDARD} -std=c++${CMAKE_CXX_STANDARD}
) )
elseif (MSVC)
set(REPERTORY_C_FLAGS_LIST
${REPERTORY_C_FLAGS_LIST}
/D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING
/DNOMINMAX
/bigobj
/Zi
)
set(REPERTORY_CXX_FLAGS_LIST
${REPERTORY_CXX_FLAGS_LIST}
/D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING
/DNOMINMAX
/bigobj
/Zi
)
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
set(REPERTORY_C_FLAGS_LIST
${REPERTORY_C_FLAGS_LIST}
/DEBUG
)
set(REPERTORY_CXX_FLAGS_LIST
${REPERTORY_CXX_FLAGS_LIST}
/DEBUG
)
set(REPERTORY_SHARED_LINKER_FLAGS_LIST
${REPERTORY_SHARED_LINKER_FLAGS_LIST}
/DEBUG
/OPT:REF
/OPT:ICF
)
endif()
endif() endif()
list(JOIN REPERTORY_CXX_FLAGS_LIST " " REPERTORY_CXX_FLAGS_LIST) list(JOIN REPERTORY_CXX_FLAGS_LIST " " REPERTORY_CXX_FLAGS_LIST)

View File

@ -1,5 +1,5 @@
function(copy_support_files target) function(copy_support_files target)
if (MSVC OR MINGW) if (MINGW)
add_custom_command( add_custom_command(
TARGET ${target} TARGET ${target}
POST_BUILD POST_BUILD

View File

@ -16,17 +16,7 @@ add_dependencies(librepertory
boost_project boost_project
curl_project curl_project
libsodium_project libsodium_project
openssl_project
rocksdb_project rocksdb_project
zlib_project
) )
if (LINUX)
add_dependencies(librepertory libuuid_project)
endif()
if (LINUX OR MINGW OR MACOS)
add_dependencies(librepertory openssl_project)
endif()
if (MSVC OR MINGW)
add_dependencies(librepertory zlib_project)
endif()

View File

@ -2,33 +2,11 @@ set(LIBSODIUM_PROJECT_NAME libsodium_${LIBSODIUM_VERSION})
set(LIBSODIUM_BUILD_ROOT ${EXTERNAL_BUILD_ROOT}/builds/${LIBSODIUM_PROJECT_NAME}) set(LIBSODIUM_BUILD_ROOT ${EXTERNAL_BUILD_ROOT}/builds/${LIBSODIUM_PROJECT_NAME})
set(LIBSODIUM_BUILD_TYPE ${EXTERNAL_BUILD_TYPE}) set(LIBSODIUM_BUILD_TYPE ${EXTERNAL_BUILD_TYPE})
if (MSVC) if (MINGW)
ExternalProject_Add(libsodium_project
DOWNLOAD_NO_PROGRESS 1
PREFIX ${LIBSODIUM_BUILD_ROOT}
BUILD_IN_SOURCE 1
URL https://github.com/jedisct1/libsodium/releases/download/${LIBSODIUM_VERSION}-RELEASE/libsodium-${LIBSODIUM_VERSION}.tar.gz
CONFIGURE_COMMAND echo "Skipping Configure"
BUILD_COMMAND cd builds\\msvc\\vs2019 && msbuild
libsodium.sln
/p:Configuration=Static${LIBSODIUM_BUILD_TYPE}
/p:Platform=x64
/t:libsodium
INSTALL_COMMAND echo "Skipping Install"
)
link_directories(PRIVATE ${LIBSODIUM_BUILD_ROOT}/src/libsodium_project/bin/x64/${LIBSODIUM_BUILD_TYPE}/v142/static)
set(LIBSODIUM_LIBRARIES libsodium.lib)
add_definitions(-DSODIUM_STATIC)
include_directories(SYSTEM
${LIBSODIUM_BUILD_ROOT}/src/libsodium_project/src/libsodium/include
${LIBSODIUM_BUILD_ROOT}/src/libsodium_project/builds/msvc
)
else()
if (MINGW)
set(LIBSODIUM_HOST --host=x86_64-w64-mingw32) set(LIBSODIUM_HOST --host=x86_64-w64-mingw32)
endif() endif()
ExternalProject_Add(libsodium_project ExternalProject_Add(libsodium_project
DOWNLOAD_NO_PROGRESS 1 DOWNLOAD_NO_PROGRESS 1
PREFIX ${LIBSODIUM_BUILD_ROOT} PREFIX ${LIBSODIUM_BUILD_ROOT}
BUILD_IN_SOURCE 1 BUILD_IN_SOURCE 1
@ -42,6 +20,8 @@ else()
--disable-asm --disable-asm
BUILD_COMMAND make BUILD_COMMAND make
INSTALL_COMMAND make install INSTALL_COMMAND make install
) )
set(LIBSODIUM_LIBRARIES libsodium.a)
endif() set(LIBSODIUM_LIBRARIES libsodium.a)
add_dependencies(libsodium_project zlib_project)

View File

@ -1,17 +0,0 @@
if (LINUX)
set(LIBUUID_PROJECT_NAME libuuid_${LIBUUID_VERSION})
set(LIBUUID_BUILD_ROOT ${EXTERNAL_BUILD_ROOT}/builds/${LIBUUID_PROJECT_NAME})
#URL "https://www.mirrorservice.org/sites/ftp.ossp.org/pkg/lib/uuid/uuid-${LIBUUID_VERSION}.tar.gz"
ExternalProject_Add(libuuid_project
DOWNLOAD_NO_PROGRESS 1
PREFIX ${LIBUUID_BUILD_ROOT}
URL https://src.fedoraproject.org/repo/pkgs/uuid/uuid-${LIBUUID_VERSION}.tar.gz/5db0d43a9022a6ebbbc25337ae28942f/uuid-${LIBUUID_VERSION}.tar.gz
BUILD_IN_SOURCE 1
CONFIGURE_COMMAND cp ${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/config.guess ./config.guess &&
cp ${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/config.sub ./config.sub &&
CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER};./configure --disable-shared --enable-static --prefix=${EXTERNAL_BUILD_ROOT}
BUILD_COMMAND CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER};make
INSTALL_COMMAND make install
)
set(LIBUUID_LIBRARIES libuuid.a)
endif()

View File

@ -1,43 +1,36 @@
if (MACOS OR LINUX OR MINGW) if (IS_CLANG_COMPILER)
if (IS_CLANG_COMPILER)
set(OPENSSL_COMPILE_TYPE_EXTRA -clang) set(OPENSSL_COMPILE_TYPE_EXTRA -clang)
endif() endif()
if (MACOS) if (MACOS)
set(OPENSSL_COMPILE_TYPE darwin64-x86_64-cc) set(OPENSSL_COMPILE_TYPE darwin64-x86_64-cc)
elseif(IS_ARM64) elseif(IS_ARM64)
set(OPENSSL_COMPILE_TYPE linux-aarch64${OPENSSL_COMPILE_TYPE_EXTRA}) set(OPENSSL_COMPILE_TYPE linux-aarch64${OPENSSL_COMPILE_TYPE_EXTRA})
elseif(MINGW) elseif(MINGW)
if (CMAKE_TOOLCHAIN_FILE) if (CMAKE_TOOLCHAIN_FILE)
set(OPENSSL_COMPILE_TYPE --cross-compile-prefix=x86_64-w64-mingw32- mingw64${OPENSSL_COMPILE_TYPE_EXTRA}) set(OPENSSL_COMPILE_TYPE --cross-compile-prefix=x86_64-w64-mingw32- mingw64${OPENSSL_COMPILE_TYPE_EXTRA})
else() else()
set(OPENSSL_COMPILE_TYPE mingw64${OPENSSL_COMPILE_TYPE_EXTRA}) set(OPENSSL_COMPILE_TYPE mingw64${OPENSSL_COMPILE_TYPE_EXTRA})
endif() endif()
else() else()
set(OPENSSL_COMPILE_TYPE linux-x86_64${OPENSSL_COMPILE_TYPE_EXTRA}) set(OPENSSL_COMPILE_TYPE linux-x86_64${OPENSSL_COMPILE_TYPE_EXTRA})
endif() endif()
set(OPENSSL_PROJECT_NAME openssl_${OPENSSL_VERSION}) set(OPENSSL_PROJECT_NAME openssl_${OPENSSL_VERSION})
set(OPENSSL_BUILD_ROOT ${EXTERNAL_BUILD_ROOT}/builds/${OPENSSL_PROJECT_NAME}) set(OPENSSL_BUILD_ROOT ${EXTERNAL_BUILD_ROOT}/builds/${OPENSSL_PROJECT_NAME})
ExternalProject_Add(openssl_project ExternalProject_Add(openssl_project
DOWNLOAD_NO_PROGRESS 1 DOWNLOAD_NO_PROGRESS 1
URL https://github.com/openssl/openssl/archive/refs/tags/OpenSSL_${OPENSSL_VERSION}.tar.gz URL https://github.com/openssl/openssl/releases/download/openssl-${OPENSSL_VERSION}/openssl-${OPENSSL_VERSION}.tar.gz
PREFIX ${OPENSSL_BUILD_ROOT} PREFIX ${OPENSSL_BUILD_ROOT}
BUILD_IN_SOURCE 1 BUILD_IN_SOURCE 1
CONFIGURE_COMMAND ./Configure no-shared ${OPENSSL_COMPILE_TYPE} --openssldir=${EXTERNAL_BUILD_ROOT}/ssl --prefix=${EXTERNAL_BUILD_ROOT} CONFIGURE_COMMAND ./Configure no-shared ${OPENSSL_COMPILE_TYPE} --openssldir=${EXTERNAL_BUILD_ROOT}/ssl --prefix=${EXTERNAL_BUILD_ROOT}
BUILD_COMMAND make -j1 BUILD_COMMAND make -j1
INSTALL_COMMAND make install INSTALL_COMMAND make install
) )
if (MACOS) set(OPENSSL_LIBRARIES
set(OPENSSL_LIBRARIES
${EXTERNAL_BUILD_ROOT}/lib/libssl.a ${EXTERNAL_BUILD_ROOT}/lib/libssl.a
${EXTERNAL_BUILD_ROOT}/lib/libcrypto.a ${EXTERNAL_BUILD_ROOT}/lib/libcrypto.a
) )
else()
set(OPENSSL_LIBRARIES add_dependencies(openssl_project zlib_project)
libssl.a
libcrypto.a
)
endif()
endif()

View File

@ -26,24 +26,7 @@ set(ROCKSDB_CMAKE_ARGS
-DWITH_TOOLS=OFF -DWITH_TOOLS=OFF
) )
if(MSVC) if (MINGW)
ExternalProject_Add(rocksdb_project
DOWNLOAD_NO_PROGRESS 1
URL https://github.com/facebook/rocksdb/archive/v${ROCKSDB_VERSION}.tar.gz
PREFIX ${ROCKSDB_BUILD_ROOT}
CMAKE_ARGS ${ROCKSDB_CMAKE_ARGS}
INSTALL_COMMAND ${CMAKE_COMMAND} -E echo "Skipping install step."
)
set(ROCKSDB_INCLUDE_DIRS ${ROCKSDB_BUILD_ROOT}/src/rocksdb_project/include)
if (CMAKE_GENERATOR_LOWER STREQUAL "nmake makefiles")
set(ROCKSDB_LIBRARIES ${ROCKSDB_BUILD_ROOT}/src/rocksdb_project-build/rocksdb.lib)
else ()
set(ROCKSDB_LIBRARIES ${ROCKSDB_BUILD_ROOT}/src/rocksdb_project-build/${CMAKE_BUILD_TYPE}/rocksdb.lib)
endif ()
else()
if (MINGW)
if (CMAKE_TOOLCHAIN_FILE) if (CMAKE_TOOLCHAIN_FILE)
set(ROCKSDB_CMAKE_ARGS set(ROCKSDB_CMAKE_ARGS
${ROCKSDB_CMAKE_ARGS} ${ROCKSDB_CMAKE_ARGS}
@ -61,7 +44,7 @@ else()
set(ROCKSDB_LIBRARIES ${ROCKSDB_BUILD_ROOT}/src/rocksdb_project-build/librocksdb.a) set(ROCKSDB_LIBRARIES ${ROCKSDB_BUILD_ROOT}/src/rocksdb_project-build/librocksdb.a)
include_directories(SYSTEM ${ROCKSDB_BUILD_ROOT}/src/rocksdb_project/include) include_directories(SYSTEM ${ROCKSDB_BUILD_ROOT}/src/rocksdb_project/include)
else() else()
ExternalProject_Add(rocksdb_project ExternalProject_Add(rocksdb_project
DOWNLOAD_NO_PROGRESS 1 DOWNLOAD_NO_PROGRESS 1
URL https://github.com/facebook/rocksdb/archive/v${ROCKSDB_VERSION}.tar.gz URL https://github.com/facebook/rocksdb/archive/v${ROCKSDB_VERSION}.tar.gz
@ -74,9 +57,10 @@ else()
else() else()
set(ROCKSDB_LIBRARIES librocksdb.a) set(ROCKSDB_LIBRARIES librocksdb.a)
endif() endif()
endif()
endif() endif()
if (MSVC OR LINUX OR MINGW) if (LINUX OR MINGW)
add_dependencies(rocksdb_project curl_project) add_dependencies(rocksdb_project curl_project)
endif() endif()
add_dependencies(rocksdb_project zlib_project)

View File

@ -8,7 +8,7 @@ else()
endif() endif()
set(CMAKE_COLOR_MAKEFILE OFF) set(CMAKE_COLOR_MAKEFILE OFF)
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(THREADS_PREFER_PTHREAD_FLAG ON) set(THREADS_PREFER_PTHREAD_FLAG ON)
@ -32,3 +32,8 @@ set(REPERTORY_OUTPUT_DIR ${CMAKE_BINARY_DIR})
set(EXTERNAL_BUILD_ROOT ${CMAKE_BINARY_DIR}/external) set(EXTERNAL_BUILD_ROOT ${CMAKE_BINARY_DIR}/external)
set(EXTERNAL_BUILD_TYPE ${CMAKE_BUILD_TYPE}) set(EXTERNAL_BUILD_TYPE ${CMAKE_BUILD_TYPE})
if (UNIX)
file(MAKE_DIRECTORY ${EXTERNAL_BUILD_ROOT}/lib)
file(CREATE_LINK ${EXTERNAL_BUILD_ROOT}/lib ${EXTERNAL_BUILD_ROOT}/lib64 SYMBOLIC)
endif()

View File

@ -4,20 +4,6 @@ if (REPERTORY_ENABLE_TESTING)
set(GTEST_PROJECT_NAME gtest_${GTEST_VERSION}) set(GTEST_PROJECT_NAME gtest_${GTEST_VERSION})
set(GTEST_BUILD_ROOT ${EXTERNAL_BUILD_ROOT}/builds/${GTEST_PROJECT_NAME}) set(GTEST_BUILD_ROOT ${EXTERNAL_BUILD_ROOT}/builds/${GTEST_PROJECT_NAME})
if (MSVC)
ExternalProject_Add(gtest_project
DOWNLOAD_NO_PROGRESS 1
URL https://github.com/google/googletest/archive/refs/tags/${GTEST_VERSION}.tar.gz
PREFIX ${GTEST_BUILD_ROOT}
CMAKE_ARGS
-DCMAKE_POSITION_INDEPENDENT_CODE=${CMAKE_POSITION_INDEPENDENT_CODE}
-DCMAKE_BUILD_TYPE=${EXTERNAL_BUILD_TYPE}
-Dgtest_force_shared_crt=OFF
-DBUILD_SHARED_LIBS=ON
-DCMAKE_CXX_FLAGS=/D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING
INSTALL_COMMAND ${CMAKE_COMMAND} -E echo "Skipping install step."
)
else()
if (MACOS) if (MACOS)
set(GTEST_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden") set(GTEST_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden")
set(GTEST_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden") set(GTEST_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
@ -38,24 +24,13 @@ if (REPERTORY_ENABLE_TESTING)
-DCMAKE_BUILD_TYPE=${EXTERNAL_BUILD_TYPE} -DCMAKE_BUILD_TYPE=${EXTERNAL_BUILD_TYPE}
INSTALL_COMMAND ${CMAKE_COMMAND} -E echo "Skipping install step." INSTALL_COMMAND ${CMAKE_COMMAND} -E echo "Skipping install step."
) )
endif()
set(GTEST_INCLUDE_DIRS set(GTEST_INCLUDE_DIRS
${GTEST_BUILD_ROOT}/src/gtest_project/googletest/include ${GTEST_BUILD_ROOT}/src/gtest_project/googletest/include
${GTEST_BUILD_ROOT}/src/gtest_project/googlemock/include ${GTEST_BUILD_ROOT}/src/gtest_project/googlemock/include
) )
if (MSVC) if(UNIX OR MINGW)
if (NOT CMAKE_GENERATOR_LOWER STREQUAL "nmake makefiles")
set (GTEST_PATH_EXTRA ${CMAKE_BUILD_TYPE}/)
endif()
set(GTEST_LIBRARIES
${GTEST_BUILD_ROOT}/src/gtest_project-build/lib/${GTEST_PATH_EXTRA}gmock${DEBUG_EXTRA}.lib
${GTEST_BUILD_ROOT}/src/gtest_project-build/lib/${GTEST_PATH_EXTRA}gmock_main${DEBUG_EXTRA}.lib
${GTEST_BUILD_ROOT}/src/gtest_project-build/lib/${GTEST_PATH_EXTRA}gtest${DEBUG_EXTRA}.lib
${GTEST_BUILD_ROOT}/src/gtest_project-build/lib/${GTEST_PATH_EXTRA}gtest_main${DEBUG_EXTRA}.lib
)
elseif (UNIX OR MINGW)
set(GTEST_LIBRARIES set(GTEST_LIBRARIES
${GTEST_BUILD_ROOT}/src/gtest_project-build/lib/libgmock.a ${GTEST_BUILD_ROOT}/src/gtest_project-build/lib/libgmock.a
${GTEST_BUILD_ROOT}/src/gtest_project-build/lib/libgtest.a ${GTEST_BUILD_ROOT}/src/gtest_project-build/lib/libgtest.a
@ -72,7 +47,11 @@ if (REPERTORY_ENABLE_TESTING)
) )
add_project_executable(unittests "${UNITTEST_SOURCES}") add_project_executable(unittests "${UNITTEST_SOURCES}")
add_dependencies(unittests gtest_project) add_dependencies(unittests
gtest_project
zlib_project
)
target_compile_definitions(unittests PUBLIC target_compile_definitions(unittests PUBLIC
GTEST_LINKED_AS_SHARED_LIBRARY=1 GTEST_LINKED_AS_SHARED_LIBRARY=1
REPERTORY_TESTING REPERTORY_TESTING
@ -83,28 +62,5 @@ if (REPERTORY_ENABLE_TESTING)
) )
target_link_libraries(unittests PRIVATE ${GTEST_LIBRARIES}) target_link_libraries(unittests PRIVATE ${GTEST_LIBRARIES})
if (MSVC)
add_custom_command(TARGET unittests
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy ${GTEST_BUILD_ROOT}/src/gtest_project-build/bin/${GTEST_PATH_EXTRA}gmock${DEBUG_EXTRA}.dll ${CMAKE_CURRENT_BINARY_DIR}/${GTEST_PATH_EXTRA}
)
add_custom_command(TARGET unittests
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy ${GTEST_BUILD_ROOT}/src/gtest_project-build/bin/${GTEST_PATH_EXTRA}gmock_main${DEBUG_EXTRA}.dll ${CMAKE_CURRENT_BINARY_DIR}/${GTEST_PATH_EXTRA}
)
add_custom_command(TARGET unittests
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy ${GTEST_BUILD_ROOT}/src/gtest_project-build/bin/${GTEST_PATH_EXTRA}gtest${DEBUG_EXTRA}.dll ${CMAKE_CURRENT_BINARY_DIR}/${GTEST_PATH_EXTRA}
)
add_custom_command(TARGET unittests
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy ${GTEST_BUILD_ROOT}/src/gtest_project-build/bin/${GTEST_PATH_EXTRA}gtest_main${DEBUG_EXTRA}.dll ${CMAKE_CURRENT_BINARY_DIR}/${GTEST_PATH_EXTRA}
)
endif()
if (CMAKE_GENERATOR_LOWER STREQUAL "nmake makefiles")
add_test(NAME AllTests COMMAND unittests WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
else()
add_test(NAME AllTests COMMAND unittests WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}) add_test(NAME AllTests COMMAND unittests WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE})
endif()
endif() endif()

View File

@ -1,16 +1,11 @@
set(BOOST_MAJOR_VERSION 1) set(BOOST_MAJOR_VERSION 1)
set(BOOST_MINOR_VERSION 78) set(BOOST_MINOR_VERSION 83)
set(BOOST_MSVC_TOOLSET msvc-14.2)
set(BOOST_MSVC_TOOLSET_DLL 142)
set(BOOST_REVISION 0) set(BOOST_REVISION 0)
set(BOOST_VERSION ${BOOST_MAJOR_VERSION}.${BOOST_MINOR_VERSION}.${BOOST_REVISION}) set(CURL_VERSION 8_4_0)
set(BOOST_VERSION_DL ${BOOST_MAJOR_VERSION}_${BOOST_MINOR_VERSION}_${BOOST_REVISION})
set(BOOST_VERSION_DLL ${BOOST_MAJOR_VERSION}_${BOOST_MINOR_VERSION})
set(CURL_VERSION 8_3_0)
set(GTEST_VERSION v1.14.0) set(GTEST_VERSION v1.14.0)
set(LIBSODIUM_VERSION 1.0.18) set(LIBSODIUM_VERSION 1.0.19)
set(LIBUUID_VERSION 1.6.2) set(LIBUUID_VERSION 1.6.2)
set(OPENSSL_VERSION 1_1_1w) set(OPENSSL_VERSION 3.1.4)
set(ROCKSDB_VERSION 8.5.3) set(ROCKSDB_VERSION 8.6.7)
set(WINFSP_VERSION 2.0) set(WINFSP_VERSION 2.0)
set(ZLIB_VERSION v1.3) set(ZLIB_VERSION v1.3)

View File

@ -1,7 +1,6 @@
if (MSVC OR MINGW) set(ZLIB_PROJECT_NAME zlib_${ZLIB_VERSION})
set(ZLIB_PROJECT_NAME zlib_${ZLIB_VERSION}) set(ZLIB_BUILD_ROOT ${EXTERNAL_BUILD_ROOT}/builds/${ZLIB_PROJECT_NAME})
set(ZLIB_BUILD_ROOT ${EXTERNAL_BUILD_ROOT}/builds/${ZLIB_PROJECT_NAME}) set(ZLIB_CMAKE_ARGS
set(ZLIB_CMAKE_ARGS
-DCMAKE_BUILD_TYPE=${EXTERNAL_BUILD_TYPE} -DCMAKE_BUILD_TYPE=${EXTERNAL_BUILD_TYPE}
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
-DCMAKE_C_FLAGS=${CMAKE_C_FLAGS} -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS}
@ -9,34 +8,24 @@ if (MSVC OR MINGW)
-DCMAKE_INSTALL_PREFIX=${EXTERNAL_BUILD_ROOT} -DCMAKE_INSTALL_PREFIX=${EXTERNAL_BUILD_ROOT}
-DCMAKE_POSITION_INDEPENDENT_CODE=${CMAKE_POSITION_INDEPENDENT_CODE} -DCMAKE_POSITION_INDEPENDENT_CODE=${CMAKE_POSITION_INDEPENDENT_CODE}
-DCMAKE_SHARED_LINKER_FLAGS=${CMAKE_SHARED_LINKER_FLAGS} -DCMAKE_SHARED_LINKER_FLAGS=${CMAKE_SHARED_LINKER_FLAGS}
) )
if (MINGW AND CMAKE_TOOLCHAIN_FILE) if (CMAKE_TOOLCHAIN_FILE)
set(ZLIB_CMAKE_ARGS set(ZLIB_CMAKE_ARGS
${ZLIB_CMAKE_ARGS} ${ZLIB_CMAKE_ARGS}
-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
) )
endif() endif()
ExternalProject_Add(zlib_project ExternalProject_Add(zlib_project
DOWNLOAD_NO_PROGRESS 1 DOWNLOAD_NO_PROGRESS 1
URL https://github.com/madler/zlib/archive/${ZLIB_VERSION}.tar.gz URL https://github.com/madler/zlib/archive/${ZLIB_VERSION}.tar.gz
PREFIX ${ZLIB_BUILD_ROOT} PREFIX ${ZLIB_BUILD_ROOT}
CMAKE_ARGS ${ZLIB_CMAKE_ARGS} CMAKE_ARGS ${ZLIB_CMAKE_ARGS}
) )
if (MINGW) if(MINGW)
set(ZLIB_LIBRARIES ${EXTERNAL_BUILD_ROOT}/lib/libzlibstatic${CMAKE_STATIC_LIBRARY_SUFFIX}) set(ZLIB_LIBRARIES ${EXTERNAL_BUILD_ROOT}/lib/libzlibstatic${CMAKE_STATIC_LIBRARY_SUFFIX})
else() else()
set(ZLIB_LIBRARIES ${EXTERNAL_BUILD_ROOT}/lib/zlibstatic${DEBUG_EXTRA}${CMAKE_STATIC_LIBRARY_SUFFIX}) set(ZLIB_LIBRARIES ${EXTERNAL_BUILD_ROOT}/lib/libz${CMAKE_STATIC_LIBRARY_SUFFIX})
endif()
elseif(LINUX)
find_library(ZLIB_LIBRARIES NO_CACHE NAMES z)
if (NOT ZLIB_LIBRARIES)
message(FATAL_ERROR "'zlib' not found")
endif()
if (REPERTORY_MUSL)
set(ZLIB_LIBRARIES libz.a)
endif()
endif() endif()

View File

@ -30,39 +30,39 @@
namespace repertory { namespace repertory {
class app_config final { class app_config final {
public: public:
[[nodiscard]] static auto default_agent_name(const provider_type &pt) [[nodiscard]] static auto default_agent_name(const provider_type &prov)
-> std::string; -> std::string;
[[nodiscard]] static auto default_api_port(const provider_type &pt) [[nodiscard]] static auto default_api_port(const provider_type &prov)
-> std::uint16_t; -> std::uint16_t;
[[nodiscard]] static auto default_data_directory(const provider_type &pt) [[nodiscard]] static auto default_data_directory(const provider_type &prov)
-> std::string; -> std::string;
[[nodiscard]] static auto default_rpc_port(const provider_type &pt) [[nodiscard]] static auto default_rpc_port(const provider_type &prov)
-> std::uint16_t; -> std::uint16_t;
[[nodiscard]] static auto get_provider_api_password(const provider_type &pt) [[nodiscard]] static auto get_provider_api_password(const provider_type &prov)
-> std::string; -> std::string;
[[nodiscard]] static auto get_provider_display_name(const provider_type &pt) [[nodiscard]] static auto get_provider_display_name(const provider_type &prov)
-> std::string; -> std::string;
[[nodiscard]] static auto get_provider_name(const provider_type &pt) [[nodiscard]] static auto get_provider_name(const provider_type &prov)
-> std::string; -> std::string;
public: public:
app_config(const provider_type &pt, const std::string &data_directory = ""); app_config(const provider_type &prov, const std::string &data_directory = "");
~app_config() { save(); } ~app_config() { save(); }
private: private:
const provider_type pt_; provider_type prov_;
std::string api_auth_; std::string api_auth_;
std::uint16_t api_port_; std::uint16_t api_port_;
std::string api_user_; std::string api_user_;
bool config_changed_; bool config_changed_;
const std::string data_directory_; std::string data_directory_;
std::uint8_t download_timeout_secs_; std::uint8_t download_timeout_secs_;
bool enable_chunk_downloader_timeout_; bool enable_chunk_downloader_timeout_;
bool enable_comm_duration_events_; bool enable_comm_duration_events_;
@ -129,7 +129,7 @@ private:
template <typename dest, typename source> template <typename dest, typename source>
auto set_value(dest &dst, const source &src) -> bool { auto set_value(dest &dst, const source &src) -> bool {
auto ret = false; auto ret = false;
recur_mutex_lock l(read_write_mutex_); recur_mutex_lock lock(read_write_mutex_);
if (dst != src) { if (dst != src) {
dst = src; dst = src;
config_changed_ = true; config_changed_ = true;
@ -244,7 +244,9 @@ public:
download_type::fallback); download_type::fallback);
} }
[[nodiscard]] auto get_provider_type() const -> provider_type { return pt_; } [[nodiscard]] auto get_provider_type() const -> provider_type {
return prov_;
}
[[nodiscard]] auto get_read_ahead_count() const -> std::uint8_t { [[nodiscard]] auto get_read_ahead_count() const -> std::uint8_t {
return std::max(static_cast<std::uint8_t>(1U), read_ahead_count_); return std::max(static_cast<std::uint8_t>(1U), read_ahead_count_);
@ -358,9 +360,17 @@ public:
} }
#ifdef REPERTORY_TESTING #ifdef REPERTORY_TESTING
void set_host_config(host_config hc) { hc_ = std::move(hc); } void set_host_config(host_config hc) {
config_changed_ = true;
hc_ = std::move(hc);
save();
}
void set_s3_config(s3_config s3) { s3_config_ = std::move(s3); } void set_s3_config(s3_config s3) {
config_changed_ = true;
s3_config_ = std::move(s3);
save();
}
#endif #endif
void set_is_remote_mount(bool is_remote_mount); void set_is_remote_mount(bool is_remote_mount);

View File

@ -23,14 +23,12 @@
#define INCLUDE_CLI_ACTIONS_HPP_ #define INCLUDE_CLI_ACTIONS_HPP_
#include "cli/check_version.hpp" #include "cli/check_version.hpp"
#include "cli/create_directory.hpp"
#include "cli/display_config.hpp" #include "cli/display_config.hpp"
#include "cli/drive_information.hpp" #include "cli/drive_information.hpp"
#include "cli/get.hpp" #include "cli/get.hpp"
#include "cli/get_directory_items.hpp" #include "cli/get_directory_items.hpp"
#include "cli/get_pinned_files.hpp" #include "cli/get_pinned_files.hpp"
#include "cli/help.hpp" #include "cli/help.hpp"
#include "cli/list_objects.hpp"
#include "cli/mount.hpp" #include "cli/mount.hpp"
#include "cli/open_files.hpp" #include "cli/open_files.hpp"
#include "cli/pin_file.hpp" #include "cli/pin_file.hpp"
@ -57,11 +55,6 @@ static const std::unordered_map<utils::cli::option, action, option_hasher>
option_actions = { option_actions = {
{utils::cli::options::check_version_option, {utils::cli::options::check_version_option,
cli::actions::check_version}, cli::actions::check_version},
#if defined(REPERTORY_ENABLE_S3)
{utils::cli::options::create_directory_option,
cli::actions::create_directory},
{utils::cli::options::list_objects_option, cli::actions::list_objects},
#endif
{utils::cli::options::display_config_option, {utils::cli::options::display_config_option,
cli::actions::display_config}, cli::actions::display_config},
{utils::cli::options::drive_information_option, {utils::cli::options::drive_information_option,

View File

@ -1,80 +0,0 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef INCLUDE_CLI_CREATE_DIRECTORY_HPP_
#define INCLUDE_CLI_CREATE_DIRECTORY_HPP_
#if defined(REPERTORY_ENABLE_S3)
#include "app_config.hpp"
#include "comm/s3/s3_comm.hpp"
#include "platform/platform.hpp"
#include "providers/i_provider.hpp"
#include "providers/provider.hpp"
#include "rpc/client/client.hpp"
#include "types/repertory.hpp"
#include "utils/cli_utils.hpp"
namespace repertory::cli::actions {
[[nodiscard]] inline auto
create_directory(int argc, char *argv[], const std::string &data_directory,
const provider_type &pt, const std::string &unique_id,
std::string /* user */, std::string /* password */)
-> exit_code {
auto ret = exit_code::invalid_provider_type;
if (pt == provider_type::s3) {
std::string api_path;
if ((ret = utils::cli::parse_string_option(
argc, argv, utils::cli::options::create_directory_option,
api_path)) == exit_code::success) {
lock_data lock(pt, unique_id);
const auto res = lock.grab_lock(1u);
/* if (res == lock_result::locked) { */
/* auto port = app_config::default_api_port(pt); */
/* utils::cli::get_api_authentication_data(user, password, port, pt,
* data_directory); */
/* const auto response = */
/* client({"localhost", password, port,
* user}).create_directory(api_path); */
/* std::cout << static_cast<int>(response.response_type) << std::endl; */
/* std::cout << response.data.dump(2) << std::endl; */
/* } else */
if (res == lock_result::success) {
std::cout << "creating directory: '" << api_path << "'" << std::endl;
app_config config(pt, data_directory);
s3_comm comm(config);
const auto res = comm.create_directory(api_path);
std::cout << api_error_to_string(res) << std::endl;
ret = exit_code::success;
} else {
std::cout << "failed to grab lock: '" << static_cast<int>(res) << "'"
<< std::endl;
ret = exit_code::lock_failed;
}
}
}
return ret;
}
} // namespace repertory::cli::actions
#endif // REPERTORY_ENABLE_S3
#endif // INCLUDE_CLI_CREATE_DIRECTORY_HPP_

View File

@ -42,11 +42,6 @@ template <typename drive> inline void help(int argc, char *argv[]) {
std::cout << " -na,--name Unique name for S3 " std::cout << " -na,--name Unique name for S3 "
"instance [Required]" "instance [Required]"
<< std::endl; << std::endl;
std::cout
<< " -cd,--create_directory [API path] Create directory object in S3"
<< std::endl;
std::cout << " -lo,--list_objects List all S3 objects"
<< std::endl;
#endif // defined(REPERTORY_ENABLE_S3) #endif // defined(REPERTORY_ENABLE_S3)
std::cout std::cout
<< " -gc,--generate_config Generate initial configuration" << " -gc,--generate_config Generate initial configuration"

View File

@ -1,81 +0,0 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef INCLUDE_CLI_LIST_OBJECTS_HPP_
#define INCLUDE_CLI_LIST_OBJECTS_HPP_
#if defined(REPERTORY_ENABLE_S3)
#include "app_config.hpp"
#include "comm/s3/s3_comm.hpp"
#include "platform/platform.hpp"
#include "providers/i_provider.hpp"
#include "providers/provider.hpp"
#include "rpc/client/client.hpp"
#include "types/repertory.hpp"
#include "utils/cli_utils.hpp"
namespace repertory::cli::actions {
[[nodiscard]] inline auto
list_objects(int /* argc */, char * /* argv */[],
const std::string &data_directory, const provider_type &pt,
const std::string &unique_id, std::string /* user */,
std::string /* password */) -> exit_code {
auto ret = exit_code::invalid_provider_type;
if (pt == provider_type::s3) {
lock_data lock(pt, unique_id);
const auto res = lock.grab_lock(1u);
/* if (res == lock_result::locked) { */
/* auto port = app_config::default_api_port(pt); */
/* utils::cli::get_api_authentication_data(user, password, port, pt,
* data_directory); */
/* const auto response = */
/* client({"localhost", password, port,
* user}).create_directory(api_path); */
/* std::cout << static_cast<int>(response.response_type) << std::endl; */
/* std::cout << response.data.dump(2) << std::endl; */
/* } else */
if (res == lock_result::success) {
app_config config(pt, data_directory);
s3_comm comm(config);
std::vector<directory_item> list{};
const auto res = comm.get_object_list(list);
if (res == api_error::success) {
for (const auto &di : list) {
std::cout << di.to_json().dump(2) << std::endl;
}
ret = exit_code::success;
} else {
std::cout << api_error_to_string(res) << std::endl;
}
} else {
std::cout << "failed to grab lock: '" << static_cast<int>(res) << "'"
<< std::endl;
ret = exit_code::lock_failed;
}
}
return ret;
}
} // namespace repertory::cli::actions
#endif // REPERTORY_ENABLE_S3
#endif // INCLUDE_CLI_LIST_OBJECTS_HPP_

View File

@ -32,9 +32,9 @@ class curl_comm final : public i_http_comm {
public: public:
curl_comm() = delete; curl_comm() = delete;
explicit curl_comm(host_config hc); explicit curl_comm(host_config cfg);
explicit curl_comm(s3_config s3); explicit curl_comm(s3_config cfg);
private: private:
using write_callback = size_t (*)(char *, size_t, size_t, void *); using write_callback = size_t (*)(char *, size_t, size_t, void *);
@ -57,9 +57,10 @@ private:
public: public:
[[nodiscard]] static auto construct_url(CURL *curl, [[nodiscard]] static auto construct_url(CURL *curl,
const std::string &relative_path, const std::string &relative_path,
const host_config &hc) -> std::string; const host_config &cfg)
-> std::string;
[[nodiscard]] static auto create_host_config(const s3_config &config, [[nodiscard]] static auto create_host_config(const s3_config &cfg,
bool use_s3_path_style) bool use_s3_path_style)
-> host_config; -> host_config;
@ -68,7 +69,7 @@ public:
template <typename request_type> template <typename request_type>
[[nodiscard]] static auto [[nodiscard]] static auto
make_encrypted_request(const host_config &hc, const request_type &request, make_encrypted_request(const host_config &cfg, const request_type &request,
long &response_code, stop_type &stop_requested) long &response_code, stop_type &stop_requested)
-> bool { -> bool {
response_code = 0; response_code = 0;
@ -102,7 +103,7 @@ public:
}; };
encrypted_request.total_size = std::nullopt; encrypted_request.total_size = std::nullopt;
if (not make_request(hc, encrypted_request, response_code, if (not make_request(cfg, encrypted_request, response_code,
stop_requested)) { stop_requested)) {
return api_error::comm_error; return api_error::comm_error;
} }
@ -127,11 +128,12 @@ public:
template <typename request_type> template <typename request_type>
[[nodiscard]] static auto [[nodiscard]] static auto
make_request(const host_config &hc, const request_type &request, make_request(const host_config &cfg, const request_type &request,
long &response_code, stop_type &stop_requested) -> bool { long &response_code, stop_type &stop_requested) -> bool {
if (request.decryption_token.has_value() && if (request.decryption_token.has_value() &&
not request.decryption_token.value().empty()) { not request.decryption_token.value().empty()) {
return make_encrypted_request(hc, request, response_code, stop_requested); return make_encrypted_request(cfg, request, response_code,
stop_requested);
} }
response_code = 0; response_code = 0;
@ -141,12 +143,12 @@ public:
return false; return false;
} }
if (not hc.agent_string.empty()) { if (not cfg.agent_string.empty()) {
curl_easy_setopt(curl, CURLOPT_USERAGENT, hc.agent_string.c_str()); curl_easy_setopt(curl, CURLOPT_USERAGENT, cfg.agent_string.c_str());
} }
if (request.allow_timeout && hc.timeout_ms) { if (request.allow_timeout && cfg.timeout_ms) {
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, hc.timeout_ms); curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, cfg.timeout_ms);
} }
std::string range_list{}; std::string range_list{};
@ -169,16 +171,16 @@ public:
} }
std::string parameters{}; std::string parameters{};
for (const auto &kv : request.query) { for (const auto &param : request.query) {
parameters += (parameters.empty() ? '?' : '&') + kv.first + '=' + parameters += (parameters.empty() ? '?' : '&') + param.first + '=' +
url_encode(curl, kv.second, false); url_encode(curl, param.second, false);
} }
if (not hc.api_password.empty()) { if (not cfg.api_password.empty()) {
curl_easy_setopt(curl, CURLOPT_USERNAME, hc.api_user.c_str()); curl_easy_setopt(curl, CURLOPT_USERNAME, cfg.api_user.c_str());
curl_easy_setopt(curl, CURLOPT_PASSWORD, hc.api_password.c_str()); curl_easy_setopt(curl, CURLOPT_PASSWORD, cfg.api_password.c_str());
} else if (not hc.api_user.empty()) { } else if (not cfg.api_user.empty()) {
curl_easy_setopt(curl, CURLOPT_USERNAME, hc.api_user.c_str()); curl_easy_setopt(curl, CURLOPT_USERNAME, cfg.api_user.c_str());
} }
if (request.aws_service.has_value()) { if (request.aws_service.has_value()) {
@ -186,7 +188,7 @@ public:
request.aws_service.value().c_str()); request.aws_service.value().c_str());
} }
auto url = construct_url(curl, request.get_path(), hc) + parameters; auto url = construct_url(curl, request.get_path(), cfg) + parameters;
curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
multi_request curl_request(curl, stop_requested); multi_request curl_request(curl, stop_requested);
@ -194,6 +196,7 @@ public:
CURLcode curl_code{}; CURLcode curl_code{};
curl_request.get_result(curl_code, response_code); curl_request.get_result(curl_code, response_code);
if (curl_code != CURLE_OK) { if (curl_code != CURLE_OK) {
std::cout << curl_easy_strerror(curl_code) << std::endl;
return false; return false;
} }

View File

@ -26,6 +26,11 @@
namespace repertory::curl::requests { namespace repertory::curl::requests {
struct http_get final : http_request_base { struct http_get final : http_request_base {
http_get() = default;
http_get(const http_get &) = default;
http_get(http_get &&) = default;
auto operator=(const http_get &) -> http_get & = default;
auto operator=(http_get &&) -> http_get & = default;
~http_get() override = default; ~http_get() override = default;
[[nodiscard]] auto set_method(CURL *curl, [[nodiscard]] auto set_method(CURL *curl,

View File

@ -27,14 +27,17 @@
namespace repertory::curl::requests { namespace repertory::curl::requests {
struct http_put_file final : http_request_base { struct http_put_file final : http_request_base {
http_put_file() = default;
http_put_file(const http_put_file &) = default;
http_put_file(http_put_file &&) = default;
auto operator=(const http_put_file &) -> http_put_file & = default;
auto operator=(http_put_file &&) -> http_put_file & = default;
~http_put_file() override = default; ~http_put_file() override = default;
std::optional<std::string> encryption_token{}; std::shared_ptr<utils::encryption::encrypting_reader> reader;
std::string file_name{}; std::string source_path;
mutable std::shared_ptr<utils::encryption::encrypting_reader> reader{};
std::string source_path{};
[[nodiscard]] auto get_path() const -> std::string override;
[[nodiscard]] auto set_method(CURL *curl, stop_type &stop_requested) const [[nodiscard]] auto set_method(CURL *curl, stop_type &stop_requested) const
-> bool override; -> bool override;

View File

@ -39,17 +39,25 @@ struct read_file_info final {
inline const auto read_file_data = static_cast<read_callback>( inline const auto read_file_data = static_cast<read_callback>(
[](char *buffer, size_t size, size_t nitems, void *instream) -> size_t { [](char *buffer, size_t size, size_t nitems, void *instream) -> size_t {
auto *rd = reinterpret_cast<read_file_info *>(instream); auto *read_info = reinterpret_cast<read_file_info *>(instream);
std::size_t bytes_read{}; std::size_t bytes_read{};
auto ret = auto ret = read_info->nf->read_bytes(buffer, size * nitems,
rd->nf->read_bytes(buffer, size * nitems, rd->offset, bytes_read); read_info->offset, bytes_read);
if (ret) { if (ret) {
rd->offset += bytes_read; read_info->offset += bytes_read;
} }
return ret && not rd->stop_requested ? bytes_read : CURL_READFUNC_ABORT; return ret && not read_info->stop_requested ? bytes_read
: CURL_READFUNC_ABORT;
}); });
struct http_request_base { struct http_request_base {
http_request_base() = default;
http_request_base(const http_request_base &) = default;
http_request_base(http_request_base &&) = default;
auto operator=(const http_request_base &) -> http_request_base & = default;
auto operator=(http_request_base &&) -> http_request_base & = default;
virtual ~http_request_base() = default; virtual ~http_request_base() = default;
bool allow_timeout{}; bool allow_timeout{};

View File

@ -1,109 +0,0 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef INCLUDE_COMM_I_S3_COMM_HPP_
#define INCLUDE_COMM_I_S3_COMM_HPP_
#if defined(REPERTORY_ENABLE_S3)
#include "types/repertory.hpp"
#include "types/s3.hpp"
namespace repertory {
class i_provider;
class i_s3_comm {
INTERFACE_SETUP(i_s3_comm);
public:
[[nodiscard]] virtual auto create_directory(const std::string &api_path)
-> api_error = 0;
[[nodiscard]] virtual auto directory_exists(const std::string &api_path) const
-> api_error = 0;
[[nodiscard]] virtual auto file_exists(const std::string &api_path,
const get_key_callback &get_key) const
-> api_error = 0;
[[nodiscard]] virtual auto
get_directory_item_count(const std::string &api_path,
meta_provider_callback meta_provider) const
-> std::size_t = 0;
[[nodiscard]] virtual auto
get_directory_items(const std::string &api_path,
meta_provider_callback meta_provider,
directory_item_list &list) const -> api_error = 0;
[[nodiscard]] virtual auto get_directory_list(api_file_list &list) const
-> api_error = 0;
[[nodiscard]] virtual auto get_file(const std::string &api_path,
const get_key_callback &get_key,
const get_name_callback &get_name,
const get_token_callback &get_token,
api_file &file) const -> api_error = 0;
[[nodiscard]] virtual auto
get_file_list(const get_api_file_token_callback &get_api_file_token,
const get_name_callback &get_name, api_file_list &list) const
-> api_error = 0;
[[nodiscard]] virtual auto
get_object_list(std::vector<directory_item> &list) const -> api_error = 0;
[[nodiscard]] virtual auto
get_object_name(const std::string &api_path,
const get_key_callback &get_key) const -> std::string = 0;
[[nodiscard]] virtual auto get_s3_config() -> s3_config = 0;
[[nodiscard]] virtual auto get_s3_config() const -> s3_config = 0;
[[nodiscard]] virtual auto is_online() const -> bool = 0;
[[nodiscard]] virtual auto read_file_bytes(
const std::string &api_path, std::size_t size, std::uint64_t offset,
data_buffer &data, const get_key_callback &get_key,
const get_size_callback &get_size, const get_token_callback &get_token,
stop_type &stop_requested) const -> api_error = 0;
[[nodiscard]] virtual auto remove_directory(const std::string &api_path)
-> api_error = 0;
[[nodiscard]] virtual auto remove_file(const std::string &api_path,
const get_key_callback &get_key)
-> api_error = 0;
[[nodiscard]] virtual auto rename_file(const std::string &api_path,
const std::string &new_api_path)
-> api_error = 0;
[[nodiscard]] virtual auto
upload_file(const std::string &api_path, const std::string &source_path,
const std::string &encryption_token,
const get_key_callback &get_key, const set_key_callback &set_key,
stop_type &stop_requested) -> api_error = 0;
};
} // namespace repertory
#endif // REPERTORY_ENABLE_S3
#endif // INCLUDE_COMM_I_S3_COMM_HPP_

View File

@ -56,11 +56,17 @@ private:
~pool() { shutdown(); } ~pool() { shutdown(); }
public:
pool(const pool &) = delete;
pool(pool &&) = delete;
auto operator=(const pool &) -> pool & = delete;
auto operator=(pool &&) -> pool & = delete;
private: private:
std::vector<std::unique_ptr<work_queue>> pool_queues_; std::vector<std::unique_ptr<work_queue>> pool_queues_;
std::vector<std::thread> pool_threads_; std::vector<std::thread> pool_threads_;
bool shutdown_ = false; bool shutdown_{false};
std::atomic<std::uint8_t> thread_index_; std::atomic<std::uint8_t> thread_index_{};
public: public:
void execute(std::uint64_t thread_id, const worker_callback &worker, void execute(std::uint64_t thread_id, const worker_callback &worker,
@ -70,17 +76,26 @@ private:
}; };
public: public:
explicit client_pool(std::uint8_t pool_size = 10u) explicit client_pool(std::uint8_t pool_size = min_pool_size)
: pool_size_(pool_size ? pool_size : 10u) {} : pool_size_(pool_size == 0U ? min_pool_size : pool_size) {}
~client_pool() { shutdown(); } ~client_pool() { shutdown(); }
public:
client_pool(const client_pool &) = delete;
client_pool(client_pool &&) = delete;
auto operator=(const client_pool &) -> client_pool & = delete;
auto operator=(client_pool &&) -> client_pool & = delete;
private: private:
const std::uint8_t pool_size_; std::uint8_t pool_size_;
std::unordered_map<std::string, std::shared_ptr<pool>> pool_lookup_; std::unordered_map<std::string, std::shared_ptr<pool>> pool_lookup_;
std::mutex pool_mutex_; std::mutex pool_mutex_;
bool shutdown_ = false; bool shutdown_ = false;
private:
static constexpr const auto min_pool_size = 10U;
public: public:
void execute(const std::string &client_id, std::uint64_t thread_id, void execute(const std::string &client_id, std::uint64_t thread_id,
const worker_callback &worker, const worker_callback &worker,

View File

@ -44,14 +44,16 @@ public:
explicit packet(data_buffer &&buffer) : buffer_(std::move(buffer)) {} explicit packet(data_buffer &&buffer) : buffer_(std::move(buffer)) {}
packet(const packet &p) noexcept = default; packet(const packet &pkt) noexcept = default;
packet(packet &&p) noexcept packet(packet &&pkt) noexcept
: buffer_(std::move(p.buffer_)), decode_offset_(p.decode_offset_) {} : buffer_(std::move(pkt.buffer_)), decode_offset_(pkt.decode_offset_) {}
~packet() = default;
private: private:
data_buffer buffer_; data_buffer buffer_;
std::size_t decode_offset_ = 0u; std::size_t decode_offset_ = 0U;
public: public:
[[nodiscard]] static auto decode_json(packet &response, json &json_data) [[nodiscard]] static auto decode_json(packet &response, json &json_data)
@ -78,48 +80,46 @@ public:
[[nodiscard]] auto decode(void *&ptr) -> error_type; [[nodiscard]] auto decode(void *&ptr) -> error_type;
[[nodiscard]] auto decode(std::int8_t &i) -> error_type; [[nodiscard]] auto decode(std::int8_t &val) -> error_type;
[[nodiscard]] auto decode(std::uint8_t &i) -> error_type; [[nodiscard]] auto decode(std::uint8_t &val) -> error_type;
[[nodiscard]] auto decode(std::int16_t &i) -> error_type; [[nodiscard]] auto decode(std::int16_t &val) -> error_type;
[[nodiscard]] auto decode(std::uint16_t &i) -> error_type; [[nodiscard]] auto decode(std::uint16_t &val) -> error_type;
[[nodiscard]] auto decode(std::int32_t &i) -> error_type; [[nodiscard]] auto decode(std::int32_t &val) -> error_type;
[[nodiscard]] auto decode(std::uint32_t &i) -> error_type; [[nodiscard]] auto decode(std::uint32_t &val) -> error_type;
[[nodiscard]] auto decode(std::int64_t &i) -> error_type; [[nodiscard]] auto decode(std::int64_t &val) -> error_type;
[[nodiscard]] auto decode(std::uint64_t &i) -> error_type; [[nodiscard]] auto decode(std::uint64_t &val) -> error_type;
[[nodiscard]] auto decode(remote::open_flags &i) -> error_type { [[nodiscard]] auto decode(remote::open_flags &val) -> error_type {
return decode(reinterpret_cast<std::uint32_t &>(i)); return decode(reinterpret_cast<std::uint32_t &>(val));
} }
[[nodiscard]] auto decode(remote::setattr_x &i) -> error_type; [[nodiscard]] auto decode(remote::setattr_x &val) -> error_type;
[[nodiscard]] auto decode(remote::stat &i) -> error_type; [[nodiscard]] auto decode(remote::stat &val) -> error_type;
[[nodiscard]] auto decode(remote::statfs &i) -> error_type; [[nodiscard]] auto decode(remote::statfs &val) -> error_type;
[[nodiscard]] auto decode(remote::statfs_x &i) -> error_type; [[nodiscard]] auto decode(remote::statfs_x &val) -> error_type;
[[nodiscard]] auto decode(remote::file_info &i) -> error_type; [[nodiscard]] auto decode(remote::file_info &val) -> error_type;
[[nodiscard]] auto decrypt(const std::string &token) -> error_type; [[nodiscard]] auto decrypt(const std::string &token) -> error_type;
void encode(const void *buffer, std::size_t size, bool should_reserve = true); void encode(const void *buffer, std::size_t size, bool should_reserve = true);
void encode(char *str) { encode(std::string(str ? str : "")); } void encode(const char *str) {
encode(std::string(str == nullptr ? "" : str));
void encode(const char *str) { encode(std::string(str ? str : "")); } }
void encode(const std::string &str); void encode(const std::string &str);
void encode(wchar_t *str);
void encode(const wchar_t *str); void encode(const wchar_t *str);
void encode(const std::wstring &str); void encode(const std::wstring &str);
@ -128,33 +128,35 @@ public:
encode(static_cast<std::uint64_t>(reinterpret_cast<std::uintptr_t>(ptr))); encode(static_cast<std::uint64_t>(reinterpret_cast<std::uintptr_t>(ptr)));
} }
void encode(std::int8_t i); void encode(std::int8_t val);
void encode(std::uint8_t i); void encode(std::uint8_t val);
void encode(std::int16_t i); void encode(std::int16_t val);
void encode(std::uint16_t i); void encode(std::uint16_t val);
void encode(std::int32_t i); void encode(std::int32_t val);
void encode(std::uint32_t i); void encode(std::uint32_t val);
void encode(std::int64_t i); void encode(std::int64_t val);
void encode(std::uint64_t i); void encode(std::uint64_t val);
void encode(remote::open_flags i) { encode(static_cast<std::uint32_t>(i)); } void encode(remote::open_flags val) {
encode(static_cast<std::uint32_t>(val));
}
void encode(remote::setattr_x i); void encode(remote::setattr_x val);
void encode(remote::stat i); void encode(remote::stat val);
void encode(remote::statfs i, bool should_reserve = true); void encode(remote::statfs val, bool should_reserve = true);
void encode(remote::statfs_x i); void encode(remote::statfs_x val);
void encode(remote::file_info i); void encode(remote::file_info val);
void encode_top(const void *buffer, std::size_t size, void encode_top(const void *buffer, std::size_t size,
bool should_reserve = true); bool should_reserve = true);
@ -168,35 +170,35 @@ public:
static_cast<std::uint64_t>(reinterpret_cast<std::uintptr_t>(ptr))); static_cast<std::uint64_t>(reinterpret_cast<std::uintptr_t>(ptr)));
} }
void encode_top(std::int8_t i); void encode_top(std::int8_t val);
void encode_top(std::uint8_t i); void encode_top(std::uint8_t val);
void encode_top(std::int16_t i); void encode_top(std::int16_t val);
void encode_top(std::uint16_t i); void encode_top(std::uint16_t val);
void encode_top(std::int32_t i); void encode_top(std::int32_t val);
void encode_top(std::uint32_t i); void encode_top(std::uint32_t val);
void encode_top(std::int64_t i); void encode_top(std::int64_t val);
void encode_top(std::uint64_t i); void encode_top(std::uint64_t val);
void encode_top(remote::open_flags i) { void encode_top(remote::open_flags val) {
encode_top(static_cast<std::uint32_t>(i)); encode_top(static_cast<std::uint32_t>(val));
} }
void encode_top(remote::setattr_x i); void encode_top(remote::setattr_x val);
void encode_top(remote::stat i); void encode_top(remote::stat val);
void encode_top(remote::statfs i, bool should_reserve = true); void encode_top(remote::statfs val, bool should_reserve = true);
void encode_top(remote::statfs_x i); void encode_top(remote::statfs_x val);
void encode_top(remote::file_info i); void encode_top(remote::file_info val);
void encrypt(const std::string &token); void encrypt(const std::string &token);
@ -211,9 +213,9 @@ public:
auto operator=(data_buffer &&buffer) noexcept -> packet &; auto operator=(data_buffer &&buffer) noexcept -> packet &;
auto operator=(const packet &p) noexcept -> packet &; auto operator=(const packet &pkt) noexcept -> packet &;
auto operator=(packet &&p) noexcept -> packet &; auto operator=(packet &&pkt) noexcept -> packet &;
[[nodiscard]] auto operator[](std::size_t index) -> char & { [[nodiscard]] auto operator[](std::size_t index) -> char & {
return buffer_[index]; return buffer_[index];

View File

@ -1,177 +0,0 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef INCLUDE_COMM_S3_S3_COMM_HPP_
#define INCLUDE_COMM_S3_S3_COMM_HPP_
#if defined(REPERTORY_ENABLE_S3)
#include "comm/i_http_comm.hpp"
#include "comm/i_s3_comm.hpp"
#include "types/repertory.hpp"
namespace repertory {
class app_config;
class s3_comm final : public i_s3_comm {
public:
explicit s3_comm(const app_config &config);
s3_comm(s3_comm &&comm);
~s3_comm() override;
private:
struct cache_entry final {
std::chrono::system_clock::time_point expiration;
directory_item_list items;
void reset_timeout(std::chrono::seconds timeout) {
timeout = std::max(std::chrono::seconds(5u), timeout);
expiration = std::chrono::system_clock::now() + timeout;
}
};
private:
const app_config &config_;
s3_config s3_config_;
std::unique_ptr<i_http_comm> s3_client_;
private:
mutable std::recursive_mutex cached_directories_mutex_;
mutable std::unordered_map<std::string, cache_entry> cached_directories_;
protected:
bool active_ = true;
private:
void clear_expired_directories();
[[nodiscard]] auto
get_cached_directory_item_count(const std::string &api_path,
std::size_t &count) const -> bool;
[[nodiscard]] auto
get_cached_directory_items(const std::string &api_path,
meta_provider_callback meta_provider,
directory_item_list &list) const -> bool;
[[nodiscard]] auto get_cached_file_exists(const std::string &api_path) const
-> bool;
[[nodiscard]] auto grab_directory_items(const std::string &api_path,
meta_provider_callback meta_provider,
directory_item_list &list) const
-> api_error;
void raise_begin(const std::string &function_name,
const std::string &api_path) const;
[[nodiscard]] auto raise_end(const std::string &function_name,
const std::string &api_path,
const api_error &error, long code) const
-> api_error;
void remove_cached_directory(const std::string &api_path);
void set_cached_directory_items(const std::string &api_path,
directory_item_list list) const;
public:
[[nodiscard]] auto create_directory(const std::string &api_path)
-> api_error override;
[[nodiscard]] auto directory_exists(const std::string &api_path) const
-> api_error override;
[[nodiscard]] auto file_exists(const std::string &api_path,
const get_key_callback &get_key) const
-> api_error override;
[[nodiscard]] auto
get_directory_item_count(const std::string &api_path,
meta_provider_callback meta_provider) const
-> std::size_t override;
[[nodiscard]] auto get_directory_items(const std::string &api_path,
meta_provider_callback meta_provider,
directory_item_list &list) const
-> api_error override;
[[nodiscard]] auto get_directory_list(api_file_list &list) const
-> api_error override;
[[nodiscard]] auto get_file(const std::string &api_path,
const get_key_callback &get_key,
const get_name_callback &get_name,
const get_token_callback &get_token,
api_file &file) const -> api_error override;
[[nodiscard]] auto
get_file_list(const get_api_file_token_callback &get_api_file_token,
const get_name_callback &get_name, api_file_list &list) const
-> api_error override;
[[nodiscard]] auto get_object_list(std::vector<directory_item> &list) const
-> api_error override;
[[nodiscard]] auto get_object_name(const std::string &api_path,
const get_key_callback &getKey) const
-> std::string override;
[[nodiscard]] auto get_s3_config() -> s3_config override {
return s3_config_;
}
[[nodiscard]] auto get_s3_config() const -> s3_config override {
return s3_config_;
}
[[nodiscard]] auto is_online() const -> bool override {
// TODO implement this
return true;
}
[[nodiscard]] auto read_file_bytes(
const std::string &api_path, std::size_t size, std::uint64_t offset,
data_buffer &data, const get_key_callback &get_key,
const get_size_callback &get_size, const get_token_callback &get_token,
stop_type &stop_requested) const -> api_error override;
[[nodiscard]] auto remove_directory(const std::string &api_path)
-> api_error override;
[[nodiscard]] auto remove_file(const std::string &api_path,
const get_key_callback &get_key)
-> api_error override;
[[nodiscard]] auto rename_file(const std::string &api_path,
const std::string &new_api_path)
-> api_error override;
[[nodiscard]] auto
upload_file(const std::string &api_path, const std::string &source_path,
const std::string &encryption_token,
const get_key_callback &get_key, const set_key_callback &set_key,
stop_type &stop_requested) -> api_error override;
};
} // namespace repertory
#endif // REPERTORY_ENABLE_S3
#endif // INCLUDE_COMM_S3_S3_COMM_HPP_

View File

@ -1,117 +0,0 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef INCLUDE_COMM_S3_S3_REQUESTS_HPP_
#define INCLUDE_COMM_S3_S3_REQUESTS_HPP_
#if defined(REPERTORY_ENABLE_S3)
#include "comm/s3/s3_requests_curl.hpp"
#include "types/repertory.hpp"
#include "types/s3.hpp"
#include "utils/string_utils.hpp"
namespace repertory {
template <typename client_type>
[[nodiscard]] inline auto
create_directory_object_request(client_type &client, const s3_config &config,
const std::string &object_name,
long &response_code) -> bool {
return create_directory_object_request_impl(client, config, object_name,
response_code);
}
template <typename client_type>
[[nodiscard]] inline auto delete_object_request(client_type &client,
const s3_config &config,
const std::string &object_name,
long &response_code) -> bool {
return delete_object_request_impl(client, config, object_name, response_code);
}
template <typename client_type>
[[nodiscard]] inline auto
head_object_request(client_type &client, const s3_config &config,
const std::string &object_name, head_object_result &result,
long &response_code) -> bool {
return head_object_request_impl(client, config, object_name, result,
response_code);
}
template <typename client_type>
[[nodiscard]] inline auto
list_directories_request(client_type &client, const s3_config &config,
list_directories_result &result, long &response_code)
-> bool {
return list_directories_request_impl(client, config, result, response_code);
}
template <typename client_type>
[[nodiscard]] inline auto
list_files_request(client_type &client, const s3_config &config,
const get_api_file_token_callback &get_api_file_token,
const get_name_callback &get_name, list_files_result &result,
long &response_code) -> bool {
return list_files_request_impl(client, config, get_api_file_token, get_name,
result, response_code);
}
template <typename client_type>
[[nodiscard]] inline auto list_objects_in_directory_request(
client_type &client, const s3_config &config,
const std::string &object_name, meta_provider_callback meta_provider,
list_objects_result &result, long &response_code) -> bool {
return list_objects_in_directory_request_impl(
client, config, object_name, meta_provider, result, response_code);
}
template <typename client_type>
[[nodiscard]] inline auto
list_objects_request(client_type &client, const s3_config &config,
list_objects_result &result, long &response_code) -> bool {
return list_objects_request_impl(client, config, result, response_code);
}
template <typename client_type>
[[nodiscard]] inline auto
put_object_request(client_type &client, const s3_config &config,
std::string object_name, const std::string &source_path,
const std::string &encryption_token,
get_key_callback get_key, set_key_callback set_key,
long &response_code, stop_type &stop_requested) -> bool {
return put_object_request_impl(client, config, object_name, source_path,
encryption_token, get_key, set_key,
response_code, stop_requested);
}
template <typename client_type>
[[nodiscard]] inline auto
read_object_request(client_type &client, const s3_config &config,
const std::string &object_name, std::size_t size,
std::uint64_t offset, data_buffer &data,
long &response_code, stop_type &stop_requested) -> bool {
return read_object_request_impl(client, config, object_name, size, offset,
data, response_code, stop_requested);
}
} // namespace repertory
#endif
#endif // INCLUDE_COMM_S3_S3_REQUESTS_HPP_

View File

@ -1,83 +0,0 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef INCLUDE_COMM_S3_S3_REQUESTS_CURL_HPP_
#define INCLUDE_COMM_S3_S3_REQUESTS_CURL_HPP_
#if defined(REPERTORY_ENABLE_S3)
#include "comm/i_http_comm.hpp"
#include "types/repertory.hpp"
#include "types/s3.hpp"
#include "utils/string_utils.hpp"
#include "utils/utils.hpp"
namespace repertory {
[[nodiscard]] auto create_directory_object_request_impl(
i_http_comm &client, const s3_config &config,
const std::string &object_name, long &response_code) -> bool;
[[nodiscard]] auto delete_object_request_impl(i_http_comm &client,
const s3_config &config,
const std::string &object_name,
long &response_code) -> bool;
[[nodiscard]] auto head_object_request_impl(i_http_comm &client,
const s3_config &config,
const std::string &object_name,
head_object_result &result,
long &response_code) -> bool;
[[nodiscard]] auto
list_directories_request_impl(i_http_comm &client, const s3_config &config,
list_directories_result &result,
long &response_code) -> bool;
[[nodiscard]] auto
list_files_request_impl(i_http_comm &client, const s3_config &config,
const get_api_file_token_callback &get_api_file_token,
const get_name_callback &get_name,
list_files_result &result, long &response_code) -> bool;
[[nodiscard]] auto list_objects_in_directory_request_impl(
i_http_comm &client, const s3_config &config,
const std::string &object_name, meta_provider_callback meta_provider,
list_objects_result &result, long &response_code) -> bool;
[[nodiscard]] auto list_objects_request_impl(i_http_comm &client,
const s3_config &config,
list_objects_result &result,
long &response_code) -> bool;
[[nodiscard]] auto
put_object_request_impl(i_http_comm &client, const s3_config &config,
std::string object_name, const std::string &source_path,
const std::string &encryption_token,
get_key_callback get_key, set_key_callback set_key,
long &response_code, stop_type &stop_requested) -> bool;
[[nodiscard]] auto read_object_request_impl(
i_http_comm &client, const s3_config &config,
const std::string &object_name, std::size_t size, std::uint64_t offset,
data_buffer &data, long &response_code, stop_type &stop_requested) -> bool;
} // namespace repertory
#endif // REPERTORY_ENABLE_S3
#endif // INCLUDE_COMM_S3_S3_REQUESTS_CURL_HPP_

View File

@ -59,11 +59,6 @@
#include <sys/mount.h> #include <sys/mount.h>
#include <sys/statvfs.h> #include <sys/statvfs.h>
#endif #endif
#if __linux__
#include <utils/uuid++.hh>
#else
#include <uuid/uuid.h>
#endif
#endif #endif
#include <algorithm> #include <algorithm>
@ -82,7 +77,6 @@
#include <optional> #include <optional>
#include <random> #include <random>
#include <sstream> #include <sstream>
#include <sstream>
#include <string> #include <string>
#include <string_view> #include <string_view>
#include <thread> #include <thread>
@ -90,6 +84,14 @@
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
#include <sodium.h>
template <typename data_type>
[[nodiscard]] inline auto repertory_rand() -> data_type {
data_type ret{};
randombytes_buf(&ret, sizeof(ret));
return ret;
}
#include <boost/archive/text_iarchive.hpp> #include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp> #include <boost/archive/text_oarchive.hpp>
#include <boost/asio.hpp> #include <boost/asio.hpp>
@ -102,6 +104,7 @@
#include <curl/multi.h> #include <curl/multi.h>
#include <json.hpp> #include <json.hpp>
#include <rocksdb/db.h> #include <rocksdb/db.h>
#include <stduuid.h>
#ifdef _WIN32 #ifdef _WIN32
#include <sddl.h> #include <sddl.h>
@ -116,7 +119,6 @@
#endif #endif
#include <pugixml.hpp> #include <pugixml.hpp>
#include <sodium.h>
#define CPPHTTPLIB_TCP_NODELAY true #define CPPHTTPLIB_TCP_NODELAY true
#define CPPHTTPLIB_OPENSSL_SUPPORT #define CPPHTTPLIB_OPENSSL_SUPPORT
@ -136,12 +138,12 @@ using json = nlohmann::json;
#define REPERTORY_API_INVALID_HANDLE static_cast<std::uint64_t>(-1) #define REPERTORY_API_INVALID_HANDLE static_cast<std::uint64_t>(-1)
using native_handle = HANDLE; using native_handle = HANDLE;
#else #else
#define REPERTORY_INVALID_HANDLE -1 #define REPERTORY_INVALID_HANDLE (-1)
#define REPERTORY_API_INVALID_HANDLE REPERTORY_INVALID_HANDLE #define REPERTORY_API_INVALID_HANDLE REPERTORY_INVALID_HANDLE
using native_handle = int; using native_handle = int;
#endif #endif
#define NANOS_PER_SECOND 1000000000L constexpr const auto NANOS_PER_SECOND = 1000000000L;
#ifdef _WIN32 #ifdef _WIN32
#ifdef CreateDirectory #ifdef CreateDirectory
@ -339,6 +341,7 @@ using WCHAR = wchar_t;
#define STATUS_OBJECT_NAME_NOT_FOUND std::int32_t(0xC0000034L) #define STATUS_OBJECT_NAME_NOT_FOUND std::int32_t(0xC0000034L)
#define STATUS_OBJECT_PATH_INVALID std::int32_t(0xC0000039L) #define STATUS_OBJECT_PATH_INVALID std::int32_t(0xC0000039L)
#define STATUS_UNEXPECTED_IO_ERROR std::int32_t(0xC00000E9L) #define STATUS_UNEXPECTED_IO_ERROR std::int32_t(0xC00000E9L)
#define CONVERT_STATUS_NOT_IMPLEMENTED(e) \ #define CONVERT_STATUS_NOT_IMPLEMENTED(e) \
((std::int32_t(e) == STATUS_NOT_IMPLEMENTED) ? -ENOTSUP : e) ((std::int32_t(e) == STATUS_NOT_IMPLEMENTED) ? -ENOTSUP : e)

View File

@ -1,117 +0,0 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef INCLUDE_DB_DIRECTORY_DB_HPP_
#define INCLUDE_DB_DIRECTORY_DB_HPP_
#include "app_config.hpp"
#include "types/repertory.hpp"
#include "utils/rocksdb_utils.hpp"
namespace repertory {
class directory_db final {
private:
class directory_tree final {
private:
std::unordered_map<std::string, std::vector<std::string>>
sub_directory_lookup_;
public:
void add_path(const std::string &api_path,
const std::vector<std::string> &files, rocksdb::DB &db);
[[nodiscard]] auto get_count(const std::string &api_path) const
-> std::size_t;
[[nodiscard]] auto get_directories() const -> std::vector<std::string>;
[[nodiscard]] auto get_sub_directories(const std::string &api_path) const
-> std::vector<std::string>;
[[nodiscard]] auto is_directory(const std::string &api_path) const -> bool;
void remove_directory(const std::string &api_path, rocksdb::DB &db,
bool allow_remove_root = false);
};
public:
explicit directory_db(const app_config &config);
public:
~directory_db();
private:
mutable std::recursive_mutex directory_mutex_;
std::unique_ptr<rocksdb::DB> db_;
directory_tree tree_;
const std::string DIRDB_NAME = "directory_db";
private:
[[nodiscard]] auto get_directory_data(const std::string &api_path) const
-> json;
public:
[[nodiscard]] auto create_directory(const std::string &api_path,
bool create_always = false) -> api_error;
[[nodiscard]] auto create_file(const std::string &api_path) -> api_error;
[[nodiscard]] auto get_directory_item_count(const std::string &api_path) const
-> std::uint64_t;
[[nodiscard]] auto
get_file(const std::string &api_path, api_file &file,
api_file_provider_callback api_file_provider) const -> api_error;
[[nodiscard]] auto
get_file_list(api_file_list &list,
api_file_provider_callback api_file_provider) const
-> api_error;
[[nodiscard]] auto get_sub_directory_count(const std::string &api_path) const
-> std::size_t;
[[nodiscard]] auto get_total_item_count() const -> std::uint64_t;
[[nodiscard]] auto is_directory(const std::string &api_path) const -> bool;
[[nodiscard]] auto is_file(const std::string &api_path) const -> bool;
void populate_directory_files(const std::string &api_path,
meta_provider_callback meta_provider,
directory_item_list &list) const;
void populate_sub_directories(const std::string &api_path,
meta_provider_callback meta_provider,
directory_item_list &list) const;
[[nodiscard]] auto remove_directory(const std::string &api_path,
bool allow_remove_root = false)
-> api_error;
[[nodiscard]] auto remove_file(const std::string &api_path) -> bool;
[[nodiscard]] auto rename_file(const std::string &from_api_path,
const std::string &to_api_path) -> api_error;
};
} // namespace repertory
#endif // INCLUDE_DB_DIRECTORY_DB_HPP_

View File

@ -1,109 +0,0 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef INCLUDE_DB_META_DB_HPP_
#define INCLUDE_DB_META_DB_HPP_
#include "app_config.hpp"
#include "types/repertory.hpp"
#include "utils/rocksdb_utils.hpp"
namespace repertory {
class meta_db final {
public:
explicit meta_db(const app_config &config);
public:
~meta_db();
private:
std::unique_ptr<rocksdb::DB> db_;
rocksdb::ColumnFamilyHandle *default_family_{};
rocksdb::ColumnFamilyHandle *source_family_{};
rocksdb::ColumnFamilyHandle *keys_family_{};
const std::string METADB_NAME = "meta_db";
private:
[[nodiscard]] auto
perform_action(const std::string &function_name,
const std::function<rocksdb::Status()> &action) const
-> api_error;
[[nodiscard]] auto get_item_meta_json(const std::string &api_path,
json &json_data) const -> api_error;
[[nodiscard]] auto store_item_meta(const std::string &api_path,
const std::string &key,
const std::string &value) -> api_error;
public:
[[nodiscard]] auto create_iterator(bool source_family) const
-> std::shared_ptr<rocksdb::Iterator>;
[[nodiscard]] auto get_api_path_from_key(const std::string &key,
std::string &api_path) const
-> api_error;
[[nodiscard]] auto get_api_path_from_source(const std::string &source_path,
std::string &api_path) const
-> api_error;
[[nodiscard]] auto get_item_meta(const std::string &api_path,
api_meta_map &meta) const -> api_error;
[[nodiscard]] auto get_item_meta(const std::string &api_path,
const std::string &key,
std::string &value) const -> api_error;
[[nodiscard]] auto get_item_meta_exists(const std::string &api_path) const
-> bool;
[[nodiscard]] auto get_total_item_count() const -> std::uint64_t;
[[nodiscard]] auto get_pinned_files() const -> std::vector<std::string>;
[[nodiscard]] auto
get_source_path_exists(const std::string &source_path) const -> bool;
[[nodiscard]] auto remove_item_meta(const std::string &api_path) -> api_error;
[[nodiscard]] auto remove_item_meta(const std::string &api_path,
const std::string &key) -> api_error;
[[nodiscard]] auto rename_item_meta(const std::string &source_path,
const std::string &from_api_path,
const std::string &to_api_path)
-> api_error;
[[nodiscard]] auto set_item_meta(const std::string &api_path,
const std::string &key,
const std::string &value) -> api_error;
[[nodiscard]] auto set_item_meta(const std::string &api_path,
const api_meta_map &meta) -> api_error;
[[nodiscard]] auto set_source_path(const std::string &api_path,
const std::string &source_path)
-> api_error;
};
} // namespace repertory
#endif // INCLUDE_DB_META_DB_HPP_

View File

@ -27,12 +27,12 @@
#include "file_manager/file_manager.hpp" #include "file_manager/file_manager.hpp"
namespace repertory { namespace repertory {
class i_provider;
class app_config; class app_config;
class console_consumer; class console_consumer;
class directory_cache; class directory_cache;
class eviction; class eviction;
class full_server; class full_server;
class i_provider;
class lock_data; class lock_data;
class logging_consumer; class logging_consumer;
namespace remote_fuse { namespace remote_fuse {
@ -45,6 +45,13 @@ public:
~fuse_drive() override = default; ~fuse_drive() override = default;
public:
fuse_drive(const fuse_drive &) = delete;
fuse_drive(fuse_drive &&) = delete;
auto operator=(const fuse_drive &) -> fuse_drive & = delete;
auto operator=(fuse_drive &&) -> fuse_drive & = delete;
private: private:
lock_data &lock_data_; lock_data &lock_data_;
i_provider &provider_; i_provider &provider_;
@ -69,7 +76,7 @@ protected:
#if FUSE_USE_VERSION >= 30 #if FUSE_USE_VERSION >= 30
[[nodiscard]] auto chmod_impl(std::string api_path, mode_t mode, [[nodiscard]] auto chmod_impl(std::string api_path, mode_t mode,
struct fuse_file_info *fi) struct fuse_file_info *file_info)
-> api_error override; -> api_error override;
#else #else
[[nodiscard]] auto chmod_impl(std::string api_path, mode_t mode) [[nodiscard]] auto chmod_impl(std::string api_path, mode_t mode)
@ -78,7 +85,7 @@ protected:
#if FUSE_USE_VERSION >= 30 #if FUSE_USE_VERSION >= 30
[[nodiscard]] auto chown_impl(std::string api_path, uid_t uid, gid_t gid, [[nodiscard]] auto chown_impl(std::string api_path, uid_t uid, gid_t gid,
struct fuse_file_info *fi) 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, gid_t gid) [[nodiscard]] auto chown_impl(std::string api_path, uid_t uid, gid_t gid)
@ -86,40 +93,40 @@ protected:
#endif #endif
[[nodiscard]] auto create_impl(std::string api_path, mode_t mode, [[nodiscard]] auto create_impl(std::string api_path, mode_t mode,
struct fuse_file_info *fi) 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 fallocate_impl(std::string api_path, int mode, [[nodiscard]] auto fallocate_impl(std::string api_path, int mode,
off_t offset, off_t length, off_t offset, off_t length,
struct fuse_file_info *fi) struct fuse_file_info *file_info)
-> api_error override; -> api_error override;
[[nodiscard]] auto fgetattr_impl(std::string api_path, struct stat *st, [[nodiscard]] auto fgetattr_impl(std::string api_path, struct stat *st,
struct fuse_file_info *fi) struct fuse_file_info *file_info)
-> api_error override; -> api_error override;
#ifdef __APPLE__ #ifdef __APPLE__
[[nodiscard]] auto fsetattr_x_impl(std::string api_path, [[nodiscard]] auto fsetattr_x_impl(std::string api_path,
struct setattr_x *attr, struct setattr_x *attr,
struct fuse_file_info *fi) struct fuse_file_info *file_info)
-> api_error override; -> api_error override;
#endif // __APPLE__ #endif // __APPLE__
[[nodiscard]] auto fsync_impl(std::string api_path, int datasync, [[nodiscard]] auto fsync_impl(std::string api_path, int datasync,
struct fuse_file_info *fi) struct fuse_file_info *file_info)
-> api_error override; -> api_error override;
#if FUSE_USE_VERSION < 30 #if FUSE_USE_VERSION < 30
[[nodiscard]] auto ftruncate_impl(std::string api_path, off_t size, [[nodiscard]] auto ftruncate_impl(std::string api_path, off_t size,
struct fuse_file_info *fi) 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 getattr_impl(std::string api_path, struct stat *st, [[nodiscard]] auto getattr_impl(std::string api_path, struct stat *st,
struct fuse_file_info *fi) struct fuse_file_info *file_info)
-> api_error override; -> api_error override;
#else #else
[[nodiscard]] auto getattr_impl(std::string api_path, struct stat *st) [[nodiscard]] auto getattr_impl(std::string api_path, struct stat *st)
@ -145,37 +152,38 @@ protected:
void notify_fuse_main_exit(int &ret) override; void notify_fuse_main_exit(int &ret) override;
[[nodiscard]] auto open_impl(std::string api_path, struct fuse_file_info *fi) [[nodiscard]] auto open_impl(std::string api_path,
struct fuse_file_info *file_info)
-> api_error override; -> api_error override;
[[nodiscard]] auto opendir_impl(std::string api_path, [[nodiscard]] auto opendir_impl(std::string api_path,
struct fuse_file_info *fi) 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,
struct fuse_file_info *fi, struct fuse_file_info *file_info,
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 readdir_impl(std::string api_path, void *buf, [[nodiscard]] auto readdir_impl(std::string api_path, void *buf,
fuse_fill_dir_t fuse_fill_dir, off_t offset, fuse_fill_dir_t fuse_fill_dir, off_t offset,
struct fuse_file_info *fi, struct fuse_file_info *file_info,
fuse_readdir_flags flags) fuse_readdir_flags flags)
-> api_error override; -> api_error override;
#else #else
[[nodiscard]] auto readdir_impl(std::string api_path, void *buf, [[nodiscard]] auto readdir_impl(std::string api_path, void *buf,
fuse_fill_dir_t fuse_fill_dir, off_t offset, fuse_fill_dir_t fuse_fill_dir, off_t offset,
struct fuse_file_info *fi) struct fuse_file_info *file_info)
-> api_error override; -> api_error override;
#endif #endif
[[nodiscard]] auto release_impl(std::string api_path, [[nodiscard]] auto release_impl(std::string api_path,
struct fuse_file_info *fi) struct fuse_file_info *file_info)
-> api_error override; -> api_error override;
[[nodiscard]] auto releasedir_impl(std::string api_path, [[nodiscard]] auto releasedir_impl(std::string api_path,
struct fuse_file_info *fi) struct fuse_file_info *file_info)
-> api_error override; -> api_error override;
#if FUSE_USE_VERSION >= 30 #if FUSE_USE_VERSION >= 30
@ -197,8 +205,7 @@ protected:
#ifdef __APPLE__ #ifdef __APPLE__
[[nodiscard]] auto getxattr_impl(std::string api_path, const char *name, [[nodiscard]] auto getxattr_impl(std::string api_path, const char *name,
char *value, size_t size, char *value, size_t size, uint32_t position,
[[nodiscard]] uint32_t position,
int &attribute_size) -> api_error override; int &attribute_size) -> api_error override;
#else // __APPLE__ #else // __APPLE__
[[nodiscard]] auto getxattr_impl(std::string api_path, const char *name, [[nodiscard]] auto getxattr_impl(std::string api_path, const char *name,
@ -252,7 +259,7 @@ protected:
#if FUSE_USE_VERSION >= 30 #if FUSE_USE_VERSION >= 30
[[nodiscard]] auto truncate_impl(std::string api_path, off_t size, [[nodiscard]] auto truncate_impl(std::string api_path, off_t size,
struct fuse_file_info *fi) struct fuse_file_info *file_info)
-> api_error override; -> api_error override;
#else #else
[[nodiscard]] auto truncate_impl(std::string api_path, off_t size) [[nodiscard]] auto truncate_impl(std::string api_path, off_t size)
@ -264,7 +271,7 @@ protected:
#if FUSE_USE_VERSION >= 30 #if FUSE_USE_VERSION >= 30
[[nodiscard]] auto utimens_impl(std::string api_path, [[nodiscard]] auto utimens_impl(std::string api_path,
const struct timespec tv[2], const struct timespec tv[2],
struct fuse_file_info *fi) struct fuse_file_info *file_info)
-> api_error override; -> api_error override;
#else #else
[[nodiscard]] auto utimens_impl(std::string api_path, [[nodiscard]] auto utimens_impl(std::string api_path,
@ -274,7 +281,7 @@ protected:
[[nodiscard]] auto write_impl(std::string api_path, const char *buffer, [[nodiscard]] auto write_impl(std::string api_path, const char *buffer,
size_t write_size, off_t write_offset, size_t write_size, off_t write_offset,
struct fuse_file_info *fi, struct fuse_file_info *file_info,
std::size_t &bytes_written) std::size_t &bytes_written)
-> api_error override; -> api_error override;
@ -309,7 +316,8 @@ public:
[[nodiscard]] auto is_processing(const std::string &api_path) const [[nodiscard]] auto is_processing(const std::string &api_path) const
-> bool override; -> bool override;
void populate_stat(const directory_item &di, struct stat &st) const override; void populate_stat(const directory_item &dir_item,
struct stat &st) const override;
[[nodiscard]] auto rename_directory(const std::string &from_api_path, [[nodiscard]] auto rename_directory(const std::string &from_api_path,
const std::string &to_api_path) const std::string &to_api_path)

View File

@ -69,7 +69,7 @@ public:
[[nodiscard]] virtual auto is_processing(const std::string &api_path) const [[nodiscard]] virtual auto is_processing(const std::string &api_path) const
-> bool = 0; -> bool = 0;
virtual void populate_stat(const directory_item &di, virtual void populate_stat(const directory_item &dir_item,
struct stat &st) const = 0; struct stat &st) const = 0;
[[nodiscard]] virtual auto rename_directory(const std::string &from_api_path, [[nodiscard]] virtual auto rename_directory(const std::string &from_api_path,

View File

@ -237,12 +237,12 @@ public:
} }
[[nodiscard]] auto json_create_directory_snapshot(const std::string &path, [[nodiscard]] auto json_create_directory_snapshot(const std::string &path,
json &jsonData) json &json_data)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto json_read_directory_snapshot( [[nodiscard]] auto json_read_directory_snapshot(
const std::string &path, const remote::file_handle &handle, const std::string &path, const remote::file_handle &handle,
std::uint32_t page, json &jsonData) -> packet::error_type override; std::uint32_t page, json &json_data) -> packet::error_type override;
[[nodiscard]] auto [[nodiscard]] auto
json_release_directory_snapshot(const std::string &path, json_release_directory_snapshot(const std::string &path,
@ -254,7 +254,7 @@ public:
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto winfsp_cleanup(PVOID file_desc, PWSTR file_name, [[nodiscard]] auto winfsp_cleanup(PVOID file_desc, PWSTR file_name,
UINT32 flags, BOOLEAN &wasClosed) UINT32 flags, BOOLEAN &was_closed)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto winfsp_close(PVOID file_desc) [[nodiscard]] auto winfsp_close(PVOID file_desc)
@ -275,8 +275,8 @@ public:
[[nodiscard]] auto [[nodiscard]] auto
winfsp_get_security_by_name(PWSTR file_name, PUINT32 attributes, winfsp_get_security_by_name(PWSTR file_name, PUINT32 attributes,
std::uint64_t * /*securityDescriptorSize*/, std::uint64_t * /*security_descriptor_size*/,
std::wstring & /*strDescriptor*/) std::wstring & /*str_descriptor*/)
-> packet::error_type override; -> packet::error_type override;
[[nodiscard]] auto winfsp_get_volume_info(UINT64 &total_size, [[nodiscard]] auto winfsp_get_volume_info(UINT64 &total_size,
@ -317,7 +317,7 @@ public:
UINT64 last_access_time, UINT64 last_write_time, UINT64 change_time, UINT64 last_access_time, UINT64 last_write_time, UINT64 change_time,
remote::file_info *file_info) -> packet::error_type override; remote::file_info *file_info) -> packet::error_type override;
[[nodiscard]] auto winfsp_set_file_size(PVOID file_desc, UINT64 newSize, [[nodiscard]] auto winfsp_set_file_size(PVOID file_desc, UINT64 new_size,
BOOLEAN set_allocation_size, BOOLEAN set_allocation_size,
remote::file_info *file_info) remote::file_info *file_info)
-> packet::error_type override; -> packet::error_type override;

View File

@ -44,9 +44,15 @@ class remote_server_base : public remote_open_file_table,
public virtual remote_winfsp::i_remote_instance, public virtual remote_winfsp::i_remote_instance,
public virtual remote_fuse::i_remote_instance { public virtual remote_fuse::i_remote_instance {
public: public:
remote_server_base(app_config &config, drive &d, std::string mount_location) remote_server_base(const remote_server_base &) = delete;
remote_server_base(remote_server_base &&) = delete;
auto operator=(const remote_server_base &) -> remote_server_base & = delete;
auto operator=(remote_server_base &&) -> remote_server_base & = delete;
public:
remote_server_base(app_config &config, drive &drv, std::string mount_location)
: config_(config), : config_(config),
drive_(d), drive_(drv),
mount_location_(std::move(mount_location)), mount_location_(std::move(mount_location)),
client_pool_(config.get_remote_client_pool_size()) { client_pool_(config.get_remote_client_pool_size()) {
event_system::instance().raise<service_started>("remote_server_base"); event_system::instance().raise<service_started>("remote_server_base");
@ -57,14 +63,13 @@ public:
packet &) -> packet::error_type { packet &) -> packet::error_type {
auto ret = STATUS_SUCCESS; auto ret = STATUS_SUCCESS;
HANDLE file_desc; HANDLE file_desc{};
DECODE_OR_RETURN(request, file_desc); DECODE_OR_RETURN(request, file_desc);
std::wstring file_name; std::wstring file_name;
DECODE_OR_RETURN(request, file_name); DECODE_OR_RETURN(request, file_name);
ret = this->winfsp_can_delete(file_desc, &file_name[0]); return this->winfsp_can_delete(file_desc, file_name.data());
return ret;
}}); }});
handler_lookup_.insert( handler_lookup_.insert(
{"::winfsp_cleanup", {"::winfsp_cleanup",
@ -73,17 +78,17 @@ public:
packet &response) -> packet::error_type { packet &response) -> packet::error_type {
auto ret = STATUS_SUCCESS; auto ret = STATUS_SUCCESS;
HANDLE file_desc; HANDLE file_desc{};
DECODE_OR_RETURN(request, file_desc); DECODE_OR_RETURN(request, file_desc);
std::wstring file_name; std::wstring file_name;
DECODE_OR_RETURN(request, file_name); DECODE_OR_RETURN(request, file_name);
UINT32 flags; UINT32 flags{};
DECODE_OR_RETURN(request, flags); DECODE_OR_RETURN(request, flags);
BOOLEAN was_closed; BOOLEAN was_closed{};
ret = this->winfsp_cleanup(file_desc, &file_name[0], flags, ret = this->winfsp_cleanup(file_desc, file_name.data(), flags,
was_closed); was_closed);
response.encode(was_closed); response.encode(was_closed);
@ -96,11 +101,10 @@ public:
packet &) -> packet::error_type { packet &) -> packet::error_type {
auto ret = STATUS_SUCCESS; auto ret = STATUS_SUCCESS;
HANDLE file_desc; HANDLE file_desc{};
DECODE_OR_RETURN(request, file_desc); DECODE_OR_RETURN(request, file_desc);
ret = this->winfsp_close(file_desc); return this->winfsp_close(file_desc);
return ret;
}}); }});
handler_lookup_.insert( handler_lookup_.insert(
{"::winfsp_create", {"::winfsp_create",
@ -112,23 +116,23 @@ public:
std::wstring file_name; std::wstring file_name;
DECODE_OR_RETURN(request, file_name); DECODE_OR_RETURN(request, file_name);
UINT32 create_options; UINT32 create_options{};
DECODE_OR_RETURN(request, create_options); DECODE_OR_RETURN(request, create_options);
UINT32 granted_access; UINT32 granted_access{};
DECODE_OR_RETURN(request, granted_access); DECODE_OR_RETURN(request, granted_access);
UINT32 attributes; UINT32 attributes{};
DECODE_OR_RETURN(request, attributes); DECODE_OR_RETURN(request, attributes);
UINT64 allocation_size; UINT64 allocation_size{};
DECODE_OR_RETURN(request, allocation_size); DECODE_OR_RETURN(request, allocation_size);
BOOLEAN exists = 0; BOOLEAN exists{0};
remote::file_info file_info{}; remote::file_info file_info{};
std::string normalized_name; std::string normalized_name;
PVOID file_desc; PVOID file_desc{};
ret = this->winfsp_create(&file_name[0], create_options, ret = this->winfsp_create(file_name.data(), create_options,
granted_access, attributes, granted_access, attributes,
allocation_size, &file_desc, &file_info, allocation_size, &file_desc, &file_info,
normalized_name, exists); normalized_name, exists);
@ -136,7 +140,9 @@ public:
#ifdef _WIN32 #ifdef _WIN32
this->set_client_id(file_desc, client_id); this->set_client_id(file_desc, client_id);
#else #else
this->set_client_id(reinterpret_cast<std::uintptr_t>(file_desc), this->set_client_id(
static_cast<native_handle>(
reinterpret_cast<std::uintptr_t>(file_desc)),
client_id); client_id);
#endif #endif
response.encode(file_desc); response.encode(file_desc);
@ -154,7 +160,7 @@ public:
packet &response) -> packet::error_type { packet &response) -> packet::error_type {
auto ret = STATUS_SUCCESS; auto ret = STATUS_SUCCESS;
HANDLE file_desc; HANDLE file_desc{};
DECODE_OR_RETURN(request, file_desc); DECODE_OR_RETURN(request, file_desc);
remote::file_info file_info{}; remote::file_info file_info{};
@ -172,7 +178,7 @@ public:
packet &response) -> packet::error_type { packet &response) -> packet::error_type {
auto ret = STATUS_SUCCESS; auto ret = STATUS_SUCCESS;
HANDLE file_desc; HANDLE file_desc{};
DECODE_OR_RETURN(request, file_desc); DECODE_OR_RETURN(request, file_desc);
remote::file_info file_info{}; remote::file_info file_info{};
@ -192,21 +198,22 @@ public:
std::wstring file_name; std::wstring file_name;
DECODE_OR_RETURN(request, file_name); DECODE_OR_RETURN(request, file_name);
std::uint64_t descriptor_size; std::uint64_t descriptor_size{};
DECODE_OR_RETURN(request, descriptor_size); DECODE_OR_RETURN(request, descriptor_size);
std::uint8_t get_attributes; std::uint8_t get_attributes{};
DECODE_OR_RETURN(request, get_attributes); DECODE_OR_RETURN(request, get_attributes);
UINT32 attributes; UINT32 attributes{};
auto *attrPtr = get_attributes ? &attributes : nullptr; auto *attr_ptr = get_attributes == 0U ? nullptr : &attributes;
std::wstring string_descriptor; std::wstring string_descriptor;
ret = this->winfsp_get_security_by_name( ret = this->winfsp_get_security_by_name(
&file_name[0], attrPtr, file_name.data(), attr_ptr,
descriptor_size ? &descriptor_size : nullptr, string_descriptor); descriptor_size == 0U ? nullptr : &descriptor_size,
string_descriptor);
if (ret == STATUS_SUCCESS) { if (ret == STATUS_SUCCESS) {
response.encode(string_descriptor); response.encode(string_descriptor);
if (get_attributes) { if (get_attributes != 0U) {
response.encode(attributes); response.encode(attributes);
} }
} }
@ -219,8 +226,8 @@ public:
packet &response) -> packet::error_type { packet &response) -> packet::error_type {
auto ret = STATUS_SUCCESS; auto ret = STATUS_SUCCESS;
UINT64 total_size = 0u; UINT64 total_size{};
UINT64 free_size = 0u; UINT64 free_size{};
std::string volume_label; std::string volume_label;
if ((ret = this->winfsp_get_volume_info( if ((ret = this->winfsp_get_volume_info(
total_size, free_size, volume_label)) == total_size, free_size, volume_label)) ==
@ -257,23 +264,25 @@ public:
std::wstring file_name; std::wstring file_name;
DECODE_OR_RETURN(request, file_name); DECODE_OR_RETURN(request, file_name);
UINT32 create_options; UINT32 create_options{};
DECODE_OR_RETURN(request, create_options); DECODE_OR_RETURN(request, create_options);
UINT32 granted_access; UINT32 granted_access{};
DECODE_OR_RETURN(request, granted_access); DECODE_OR_RETURN(request, granted_access);
remote::file_info file_info{}; remote::file_info file_info{};
std::string normalized_name; std::string normalized_name;
PVOID file_desc; PVOID file_desc{};
ret = ret = this->winfsp_open(file_name.data(), create_options,
this->winfsp_open(&file_name[0], create_options, granted_access, granted_access, &file_desc, &file_info,
&file_desc, &file_info, normalized_name); normalized_name);
if (ret == STATUS_SUCCESS) { if (ret == STATUS_SUCCESS) {
#ifdef _WIN32 #ifdef _WIN32
this->set_client_id(file_desc, client_id); this->set_client_id(file_desc, client_id);
#else #else
this->set_client_id(reinterpret_cast<std::uintptr_t>(file_desc), this->set_client_id(
static_cast<native_handle>(
reinterpret_cast<std::uintptr_t>(file_desc)),
client_id); client_id);
#endif #endif
response.encode(file_desc); response.encode(file_desc);
@ -290,16 +299,16 @@ public:
packet &response) -> packet::error_type { packet &response) -> packet::error_type {
auto ret = STATUS_SUCCESS; auto ret = STATUS_SUCCESS;
HANDLE file_desc; HANDLE file_desc{};
DECODE_OR_RETURN(request, file_desc); DECODE_OR_RETURN(request, file_desc);
UINT32 attributes; UINT32 attributes{};
DECODE_OR_RETURN(request, attributes); DECODE_OR_RETURN(request, attributes);
BOOLEAN replace_attributes; BOOLEAN replace_attributes{};
DECODE_OR_RETURN(request, replace_attributes); DECODE_OR_RETURN(request, replace_attributes);
UINT64 allocation_size; UINT64 allocation_size{};
DECODE_OR_RETURN(request, allocation_size); DECODE_OR_RETURN(request, allocation_size);
remote::file_info file_info{}; remote::file_info file_info{};
@ -318,23 +327,23 @@ public:
packet &response) -> packet::error_type { packet &response) -> packet::error_type {
auto ret = STATUS_SUCCESS; auto ret = STATUS_SUCCESS;
HANDLE file_desc; HANDLE file_desc{};
DECODE_OR_RETURN(request, file_desc); DECODE_OR_RETURN(request, file_desc);
UINT64 offset; UINT64 offset{};
DECODE_OR_RETURN(request, offset); DECODE_OR_RETURN(request, offset);
UINT32 length; UINT32 length{};
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 = 0;
ret = this->winfsp_read(file_desc, &buffer[0], offset, length, ret = this->winfsp_read(file_desc, buffer.data(), offset, length,
&bytes_transferred); &bytes_transferred);
if (ret == STATUS_SUCCESS) { if (ret == STATUS_SUCCESS) {
response.encode(static_cast<UINT32>(bytes_transferred)); response.encode(static_cast<UINT32>(bytes_transferred));
if (bytes_transferred) { if (bytes_transferred != 0U) {
response.encode(&buffer[0], bytes_transferred); response.encode(buffer.data(), bytes_transferred);
} }
} }
return ret; return ret;
@ -346,7 +355,7 @@ public:
packet &response) -> packet::error_type { packet &response) -> packet::error_type {
auto ret = STATUS_SUCCESS; auto ret = STATUS_SUCCESS;
HANDLE file_desc; HANDLE file_desc{};
DECODE_OR_RETURN(request, file_desc); DECODE_OR_RETURN(request, file_desc);
std::wstring pattern; std::wstring pattern;
@ -355,13 +364,14 @@ public:
std::wstring marker; std::wstring marker;
DECODE_OR_IGNORE(request, marker); DECODE_OR_IGNORE(request, marker);
json itemList; json item_list;
ret = this->winfsp_read_directory( ret = this->winfsp_read_directory(
file_desc, &pattern[0], file_desc, pattern.data(),
wcsnlen(&marker[0], marker.size()) ? &marker[0] : nullptr, wcsnlen(marker.data(), marker.size()) == 0U ? nullptr
itemList); : marker.data(),
item_list);
if (ret == STATUS_SUCCESS) { if (ret == STATUS_SUCCESS) {
response.encode(itemList.dump(0)); response.encode(item_list.dump(0));
} }
return ret; return ret;
}}); }});
@ -372,7 +382,7 @@ public:
packet &) -> packet::error_type { packet &) -> packet::error_type {
auto ret = STATUS_SUCCESS; auto ret = STATUS_SUCCESS;
HANDLE file_desc; HANDLE file_desc{};
DECODE_OR_RETURN(request, file_desc); DECODE_OR_RETURN(request, file_desc);
std::wstring file_name; std::wstring file_name;
@ -381,11 +391,11 @@ public:
std::wstring new_file_name; std::wstring new_file_name;
DECODE_OR_RETURN(request, new_file_name); DECODE_OR_RETURN(request, new_file_name);
BOOLEAN replace_if_exists; BOOLEAN replace_if_exists{};
DECODE_OR_RETURN(request, replace_if_exists); DECODE_OR_RETURN(request, replace_if_exists);
ret = this->winfsp_rename(file_desc, &file_name[0], ret = this->winfsp_rename(file_desc, file_name.data(),
&new_file_name[0], replace_if_exists); new_file_name.data(), replace_if_exists);
return ret; return ret;
}}); }});
handler_lookup_.insert( handler_lookup_.insert(
@ -395,22 +405,22 @@ public:
packet &response) -> packet::error_type { packet &response) -> packet::error_type {
auto ret = STATUS_SUCCESS; auto ret = STATUS_SUCCESS;
HANDLE file_desc; HANDLE file_desc{};
DECODE_OR_RETURN(request, file_desc); DECODE_OR_RETURN(request, file_desc);
UINT32 attributes; UINT32 attributes{};
DECODE_OR_RETURN(request, attributes); DECODE_OR_RETURN(request, attributes);
UINT64 creation_time; UINT64 creation_time{};
DECODE_OR_RETURN(request, creation_time); DECODE_OR_RETURN(request, creation_time);
UINT64 last_access_time; UINT64 last_access_time{};
DECODE_OR_RETURN(request, last_access_time); DECODE_OR_RETURN(request, last_access_time);
UINT64 last_write_time; UINT64 last_write_time{};
DECODE_OR_RETURN(request, last_write_time); DECODE_OR_RETURN(request, last_write_time);
UINT64 change_time; UINT64 change_time{};
DECODE_OR_RETURN(request, change_time); DECODE_OR_RETURN(request, change_time);
remote::file_info file_info{}; remote::file_info file_info{};
@ -429,13 +439,13 @@ public:
packet &response) -> packet::error_type { packet &response) -> packet::error_type {
auto ret = STATUS_SUCCESS; auto ret = STATUS_SUCCESS;
HANDLE file_desc; HANDLE file_desc{};
DECODE_OR_RETURN(request, file_desc); DECODE_OR_RETURN(request, file_desc);
UINT64 new_size; UINT64 new_size{};
DECODE_OR_RETURN(request, new_size); DECODE_OR_RETURN(request, new_size);
BOOLEAN set_allocation_size; BOOLEAN set_allocation_size{};
DECODE_OR_RETURN(request, set_allocation_size); DECODE_OR_RETURN(request, set_allocation_size);
remote::file_info file_info{}; remote::file_info file_info{};
@ -456,8 +466,7 @@ public:
std::wstring location; std::wstring location;
DECODE_OR_RETURN(request, location); DECODE_OR_RETURN(request, location);
ret = this->winfsp_unmounted(location); return this->winfsp_unmounted(location);
return ret;
}}); }});
handler_lookup_.insert( handler_lookup_.insert(
{"::winfsp_write", {"::winfsp_write",
@ -466,19 +475,19 @@ public:
packet &response) -> packet::error_type { packet &response) -> packet::error_type {
auto ret = STATUS_SUCCESS; auto ret = STATUS_SUCCESS;
HANDLE file_desc; HANDLE file_desc{};
DECODE_OR_RETURN(request, file_desc); DECODE_OR_RETURN(request, file_desc);
UINT32 length; UINT32 length{};
DECODE_OR_RETURN(request, length); DECODE_OR_RETURN(request, length);
UINT64 offset; UINT64 offset{};
DECODE_OR_RETURN(request, offset); DECODE_OR_RETURN(request, offset);
BOOLEAN write_to_end; BOOLEAN write_to_end{};
DECODE_OR_RETURN(request, write_to_end); DECODE_OR_RETURN(request, write_to_end);
BOOLEAN constrained_io; BOOLEAN constrained_io{};
DECODE_OR_RETURN(request, constrained_io); DECODE_OR_RETURN(request, constrained_io);
auto *buffer = request->current_pointer(); auto *buffer = request->current_pointer();
@ -504,10 +513,10 @@ public:
std::string path; std::string path;
DECODE_OR_RETURN(request, path); DECODE_OR_RETURN(request, path);
std::int32_t mask; std::int32_t mask{};
DECODE_OR_RETURN(request, mask); DECODE_OR_RETURN(request, mask);
return this->fuse_access(&path[0], mask); return this->fuse_access(path.data(), mask);
}}); }});
handler_lookup_.insert( handler_lookup_.insert(
{"::fuse_chflags", {"::fuse_chflags",
@ -519,10 +528,10 @@ public:
std::string path; std::string path;
DECODE_OR_RETURN(request, path); DECODE_OR_RETURN(request, path);
std::uint32_t flags; std::uint32_t flags{};
DECODE_OR_RETURN(request, flags); DECODE_OR_RETURN(request, flags);
return this->fuse_chflags(&path[0], flags); return this->fuse_chflags(path.data(), flags);
}}); }});
handler_lookup_.insert( handler_lookup_.insert(
{"::fuse_chmod", {"::fuse_chmod",
@ -549,10 +558,10 @@ public:
std::string path; std::string path;
DECODE_OR_RETURN(request, path); DECODE_OR_RETURN(request, path);
remote::user_id uid; remote::user_id uid{};
DECODE_OR_RETURN(request, uid); DECODE_OR_RETURN(request, uid);
remote::group_id gid; remote::group_id gid{};
DECODE_OR_RETURN(request, gid); DECODE_OR_RETURN(request, gid);
return this->fuse_chown(&path[0], uid, gid); return this->fuse_chown(&path[0], uid, gid);
@ -567,18 +576,19 @@ public:
std::string path; std::string path;
DECODE_OR_RETURN(request, path); DECODE_OR_RETURN(request, path);
remote::file_mode mode; remote::file_mode mode{};
DECODE_OR_RETURN(request, mode); DECODE_OR_RETURN(request, mode);
remote::open_flags flags; remote::open_flags flags{};
DECODE_OR_RETURN(request, flags); DECODE_OR_RETURN(request, flags);
remote::file_handle handle; remote::file_handle handle{};
if ((ret = this->fuse_create(&path[0], mode, flags, handle)) >= 0) { if ((ret = this->fuse_create(path.data(), mode, flags, handle)) >=
0) {
#ifdef _WIN32 #ifdef _WIN32
this->set_compat_client_id(handle, client_id); this->set_compat_client_id(handle, client_id);
#else #else
this->set_client_id(handle, client_id); this->set_client_id(static_cast<native_handle>(handle), client_id);
#endif #endif
response.encode(handle); response.encode(handle);
} }
@ -623,18 +633,18 @@ public:
std::string path; std::string path;
DECODE_OR_RETURN(request, path); DECODE_OR_RETURN(request, path);
remote::file_handle handle; remote::file_handle handle{};
DECODE_OR_RETURN(request, handle); DECODE_OR_RETURN(request, handle);
remote::user_id uid; remote::user_id uid{};
DECODE_OR_RETURN(request, uid); DECODE_OR_RETURN(request, uid);
remote::group_id gid; remote::group_id gid{};
DECODE_OR_RETURN(request, gid); DECODE_OR_RETURN(request, gid);
remote::stat st{}; remote::stat st{};
bool directory = false; bool directory = false;
ret = this->fuse_fgetattr(&path[0], st, directory, handle); ret = this->fuse_fgetattr(path.data(), st, directory, handle);
if (ret == 0) { if (ret == 0) {
st.st_uid = uid; st.st_uid = uid;
st.st_gid = gid; st.st_gid = gid;
@ -657,10 +667,10 @@ public:
remote::setattr_x attr{}; remote::setattr_x attr{};
DECODE_OR_RETURN(request, attr); DECODE_OR_RETURN(request, attr);
remote::file_handle handle; remote::file_handle handle{};
DECODE_OR_RETURN(request, handle); DECODE_OR_RETURN(request, handle);
return this->fuse_fsetattr_x(&path[0], attr, handle); return this->fuse_fsetattr_x(path.data(), attr, handle);
}}); }});
handler_lookup_.insert( handler_lookup_.insert(
{"::fuse_fsync", {"::fuse_fsync",
@ -833,7 +843,7 @@ public:
#ifdef _WIN32 #ifdef _WIN32
this->set_compat_client_id(handle, client_id); this->set_compat_client_id(handle, client_id);
#else #else
this->set_client_id(handle, client_id); this->set_client_id(static_cast<native_handle>(handle), client_id);
#endif #endif
response.encode(handle); response.encode(handle);
} }
@ -965,7 +975,7 @@ public:
[this](std::uint32_t, const std::string &, std::uint64_t, [this](std::uint32_t, const std::string &, std::uint64_t,
const std::string &, packet *request, const std::string &, packet *request,
packet &) -> packet::error_type { packet &) -> packet::error_type {
auto ret = 0; std::int32_t ret{0};
std::string from; std::string from;
DECODE_OR_RETURN(request, from); DECODE_OR_RETURN(request, from);
@ -973,26 +983,26 @@ public:
std::string to; std::string to;
DECODE_OR_RETURN(request, to); DECODE_OR_RETURN(request, to);
return this->fuse_rename(&from[0], &to[0]); return this->fuse_rename(from.data(), to.data());
}}); }});
handler_lookup_.insert( handler_lookup_.insert(
{"::fuse_rmdir", {"::fuse_rmdir",
[this](std::uint32_t, const std::string &, std::uint64_t, [this](std::uint32_t, const std::string &, std::uint64_t,
const std::string &, packet *request, const std::string &, packet *request,
packet &) -> packet::error_type { packet &) -> packet::error_type {
auto ret = 0; std::int32_t ret{0};
std::string path; std::string path;
DECODE_OR_RETURN(request, path); DECODE_OR_RETURN(request, path);
return this->fuse_rmdir(&path[0]); return this->fuse_rmdir(path.data());
}}); }});
handler_lookup_.insert( handler_lookup_.insert(
{"::fuse_setattr_x", {"::fuse_setattr_x",
[this](std::uint32_t, const std::string &, std::uint64_t, [this](std::uint32_t, const std::string &, std::uint64_t,
const std::string &, packet *request, const std::string &, packet *request,
packet &) -> packet::error_type { packet &) -> packet::error_type {
auto ret = 0; std::int32_t ret{0};
std::string path; std::string path;
DECODE_OR_RETURN(request, path); DECODE_OR_RETURN(request, path);
@ -1000,64 +1010,64 @@ public:
remote::setattr_x attr{}; remote::setattr_x attr{};
DECODE_OR_RETURN(request, attr); DECODE_OR_RETURN(request, attr);
return this->fuse_setattr_x(&path[0], attr); return this->fuse_setattr_x(path.data(), attr);
}}); }});
handler_lookup_.insert( handler_lookup_.insert(
{"::fuse_setbkuptime", {"::fuse_setbkuptime",
[this](std::uint32_t, const std::string &, std::uint64_t, [this](std::uint32_t, const std::string &, std::uint64_t,
const std::string &, packet *request, const std::string &, packet *request,
packet &) -> packet::error_type { packet &) -> packet::error_type {
auto ret = 0; std::int32_t ret{0};
std::string path; std::string path;
DECODE_OR_RETURN(request, path); DECODE_OR_RETURN(request, path);
remote::file_time bkuptime; remote::file_time bkuptime{};
DECODE_OR_RETURN(request, bkuptime); DECODE_OR_RETURN(request, bkuptime);
return this->fuse_setbkuptime(&path[0], bkuptime); return this->fuse_setbkuptime(path.data(), bkuptime);
}}); }});
handler_lookup_.insert( handler_lookup_.insert(
{"::fuse_setchgtime", {"::fuse_setchgtime",
[this](std::uint32_t, const std::string &, std::uint64_t, [this](std::uint32_t, const std::string &, std::uint64_t,
const std::string &, packet *request, const std::string &, packet *request,
packet &) -> packet::error_type { packet &) -> packet::error_type {
auto ret = 0; std::int32_t ret{0};
std::string path; std::string path;
DECODE_OR_RETURN(request, path); DECODE_OR_RETURN(request, path);
remote::file_time chgtime; remote::file_time chgtime{};
DECODE_OR_RETURN(request, chgtime); DECODE_OR_RETURN(request, chgtime);
return this->fuse_setchgtime(&path[0], chgtime); return this->fuse_setchgtime(path.data(), chgtime);
}}); }});
handler_lookup_.insert( handler_lookup_.insert(
{"::fuse_setcrtime", {"::fuse_setcrtime",
[this](std::uint32_t, const std::string &, std::uint64_t, [this](std::uint32_t, const std::string &, std::uint64_t,
const std::string &, packet *request, const std::string &, packet *request,
packet &) -> packet::error_type { packet &) -> packet::error_type {
auto ret = 0; std::int32_t ret{0};
std::string path; std::string path;
DECODE_OR_RETURN(request, path); DECODE_OR_RETURN(request, path);
remote::file_time crtime; remote::file_time crtime{};
DECODE_OR_RETURN(request, crtime); DECODE_OR_RETURN(request, crtime);
return this->fuse_setcrtime(&path[0], crtime); return this->fuse_setcrtime(path.data(), crtime);
}}); }});
handler_lookup_.insert( handler_lookup_.insert(
{"::fuse_setvolname", {"::fuse_setvolname",
[this](std::uint32_t, const std::string &, std::uint64_t, [this](std::uint32_t, const std::string &, std::uint64_t,
const std::string &, packet *request, const std::string &, packet *request,
packet &) -> packet::error_type { packet &) -> packet::error_type {
auto ret = 0; std::int32_t ret{0};
std::string name; std::string name;
DECODE_OR_RETURN(request, name); DECODE_OR_RETURN(request, name);
return this->fuse_setvolname(&name[0]); return this->fuse_setvolname(name.data());
}}); }});
/*handlerLookup_.insert({"::fuse_setxattr", /*handlerLookup_.insert({"::fuse_setxattr",
[this](std::uint32_t serviceFlags, const std::string [this](std::uint32_t serviceFlags, const std::string
@ -1125,16 +1135,16 @@ public:
[this](std::uint32_t, const std::string &, std::uint64_t, [this](std::uint32_t, const std::string &, std::uint64_t,
const std::string &, packet *request, const std::string &, packet *request,
packet &response) -> packet::error_type { packet &response) -> packet::error_type {
auto ret = -1; std::int32_t ret{-1};
std::string path; std::string path;
DECODE_OR_RETURN(request, path); DECODE_OR_RETURN(request, path);
std::uint64_t frsize; std::uint64_t frsize{};
DECODE_OR_RETURN(request, frsize); DECODE_OR_RETURN(request, frsize);
remote::statfs st{}; remote::statfs st{};
ret = this->fuse_statfs(&path[0], frsize, st); ret = this->fuse_statfs(path.data(), frsize, st);
if (ret == 0) { if (ret == 0) {
response.encode(st); response.encode(st);
} }
@ -1145,16 +1155,16 @@ public:
[this](std::uint32_t, const std::string &, std::uint64_t, [this](std::uint32_t, const std::string &, std::uint64_t,
const std::string &, packet *request, const std::string &, packet *request,
packet &response) -> packet::error_type { packet &response) -> packet::error_type {
auto ret = -1; std::int32_t ret{-1};
std::string path; std::string path;
DECODE_OR_RETURN(request, path); DECODE_OR_RETURN(request, path);
std::uint64_t bsize; std::uint64_t bsize{};
DECODE_OR_RETURN(request, bsize); DECODE_OR_RETURN(request, bsize);
remote::statfs_x st{}; remote::statfs_x st{};
ret = this->fuse_statfs_x(&path[0], bsize, st); ret = this->fuse_statfs_x(path.data(), bsize, st);
if (ret == 0) { if (ret == 0) {
response.encode(st); response.encode(st);
} }
@ -1165,34 +1175,34 @@ public:
[this](std::uint32_t, const std::string &, std::uint64_t, [this](std::uint32_t, const std::string &, std::uint64_t,
const std::string &, packet *request, const std::string &, packet *request,
packet &) -> packet::error_type { packet &) -> packet::error_type {
auto ret = 0; std::int32_t ret{};
std::string path; std::string path;
DECODE_OR_RETURN(request, path); DECODE_OR_RETURN(request, path);
remote::file_offset size; remote::file_offset size{};
DECODE_OR_IGNORE(request, size); DECODE_OR_IGNORE(request, size);
return this->fuse_truncate(&path[0], size); return this->fuse_truncate(path.data(), size);
}}); }});
handler_lookup_.insert( handler_lookup_.insert(
{"::fuse_unlink", {"::fuse_unlink",
[this](std::uint32_t, const std::string &, std::uint64_t, [this](std::uint32_t, const std::string &, std::uint64_t,
const std::string &, packet *request, const std::string &, packet *request,
packet &) -> packet::error_type { packet &) -> packet::error_type {
auto ret = 0; std::int32_t ret{};
std::string path; std::string path;
DECODE_OR_RETURN(request, path); DECODE_OR_RETURN(request, path);
return this->fuse_unlink(&path[0]); return this->fuse_unlink(path.data());
}}); }});
handler_lookup_.insert( handler_lookup_.insert(
{"::fuse_utimens", {"::fuse_utimens",
[this](std::uint32_t, const std::string &, std::uint64_t, [this](std::uint32_t, const std::string &, std::uint64_t,
const std::string &, packet *request, const std::string &, packet *request,
packet &) -> packet::error_type { packet &) -> packet::error_type {
auto ret = 0; std::int32_t ret{};
std::string path; std::string path;
DECODE_OR_RETURN(request, path); DECODE_OR_RETURN(request, path);
@ -1200,13 +1210,13 @@ public:
remote::file_time tv[2] = {0}; remote::file_time tv[2] = {0};
if ((ret = request->decode(&tv[0], sizeof(remote::file_time) * 2)) == if ((ret = request->decode(&tv[0], sizeof(remote::file_time) * 2)) ==
0) { 0) {
std::uint64_t op0; std::uint64_t op0{};
DECODE_OR_RETURN(request, op0); DECODE_OR_RETURN(request, op0);
std::uint64_t op1; std::uint64_t op1{};
DECODE_OR_RETURN(request, op1); DECODE_OR_RETURN(request, op1);
ret = this->fuse_utimens(&path[0], tv, op0, op1); ret = this->fuse_utimens(path.data(), tv, op0, op1);
} }
return ret; return ret;
}}); }});
@ -1215,27 +1225,27 @@ public:
[this](std::uint32_t, const std::string &, std::uint64_t, [this](std::uint32_t, const std::string &, std::uint64_t,
const std::string &, packet *request, const std::string &, packet *request,
packet &) -> packet::error_type { packet &) -> packet::error_type {
std::int32_t ret = 0; std::int32_t ret{};
std::string path; std::string path;
DECODE_OR_RETURN(request, path); DECODE_OR_RETURN(request, path);
remote::file_size writeSize; remote::file_size write_size{};
DECODE_OR_RETURN(request, writeSize); DECODE_OR_RETURN(request, write_size);
if (writeSize > std::numeric_limits<std::size_t>::max()) { if (write_size > std::numeric_limits<std::size_t>::max()) {
return -ERANGE; return -ERANGE;
} }
data_buffer buffer(static_cast<std::size_t>(writeSize)); data_buffer buffer(static_cast<std::size_t>(write_size));
if ((ret = request->decode(&buffer[0], buffer.size())) == 0) { if ((ret = request->decode(buffer.data(), buffer.size())) == 0) {
remote::file_offset write_offset; remote::file_offset write_offset{};
DECODE_OR_RETURN(request, write_offset); DECODE_OR_RETURN(request, write_offset);
remote::file_handle handle; remote::file_handle handle{};
DECODE_OR_RETURN(request, handle); DECODE_OR_RETURN(request, handle);
ret = this->fuse_write(&path[0], &buffer[0], writeSize, ret = this->fuse_write(path.data(), buffer.data(), write_size,
write_offset, handle); write_offset, handle);
} }
return ret; return ret;
@ -1245,12 +1255,12 @@ public:
[this](std::uint32_t, const std::string &, std::uint64_t, [this](std::uint32_t, const std::string &, std::uint64_t,
const std::string &, packet *request, const std::string &, packet *request,
packet &) -> packet::error_type { packet &) -> packet::error_type {
std::int32_t ret = 0; std::int32_t ret{};
std::string path; std::string path;
DECODE_OR_RETURN(request, path); DECODE_OR_RETURN(request, path);
remote::file_size write_size; remote::file_size write_size{};
DECODE_OR_RETURN(request, write_size); DECODE_OR_RETURN(request, write_size);
if (write_size > std::numeric_limits<std::size_t>::max()) { if (write_size > std::numeric_limits<std::size_t>::max()) {
@ -1258,18 +1268,18 @@ public:
} }
data_buffer buffer(static_cast<std::size_t>(write_size)); data_buffer buffer(static_cast<std::size_t>(write_size));
if ((ret = request->decode(&buffer[0], buffer.size())) == 0) { if ((ret = request->decode(buffer.data(), buffer.size())) == 0) {
buffer = macaron::Base64::Decode( buffer = macaron::Base64::Decode(
std::string(buffer.begin(), buffer.end())); std::string(buffer.begin(), buffer.end()));
write_size = buffer.size(); write_size = buffer.size();
remote::file_offset write_offset; remote::file_offset write_offset{};
DECODE_OR_RETURN(request, write_offset); DECODE_OR_RETURN(request, write_offset);
remote::file_handle handle; remote::file_handle handle{};
DECODE_OR_RETURN(request, handle); DECODE_OR_RETURN(request, handle);
ret = this->fuse_write(&path[0], &buffer[0], write_size, ret = this->fuse_write(path.data(), buffer.data(), write_size,
write_offset, handle); write_offset, handle);
} }
return ret; return ret;
@ -1279,7 +1289,7 @@ public:
[this](std::uint32_t, const std::string &client_id, std::uint64_t, [this](std::uint32_t, const std::string &client_id, std::uint64_t,
const std::string &, packet *request, const std::string &, packet *request,
packet &response) -> packet::error_type { packet &response) -> packet::error_type {
std::int32_t ret = 0; std::int32_t ret{};
std::string path; std::string path;
DECODE_OR_RETURN(request, path); DECODE_OR_RETURN(request, path);
@ -1288,7 +1298,7 @@ public:
json_data["handle"] = -1; json_data["handle"] = -1;
json_data["page_count"] = 0; json_data["page_count"] = 0;
json_data["path"] = path; json_data["path"] = path;
if ((ret = this->json_create_directory_snapshot(&path[0], if ((ret = this->json_create_directory_snapshot(path.data(),
json_data)) == 0) { json_data)) == 0) {
this->add_directory(client_id, this->add_directory(client_id,
reinterpret_cast<void *>( reinterpret_cast<void *>(
@ -1307,10 +1317,10 @@ public:
std::string path; std::string path;
DECODE_OR_RETURN(request, path); DECODE_OR_RETURN(request, path);
remote::file_handle handle; remote::file_handle handle{};
DECODE_OR_RETURN(request, handle); DECODE_OR_RETURN(request, handle);
std::uint32_t page; std::uint32_t page{};
DECODE_OR_RETURN(request, page); DECODE_OR_RETURN(request, page);
ret = -EBADF; ret = -EBADF;
@ -1338,10 +1348,10 @@ public:
std::string path; std::string path;
DECODE_OR_RETURN(request, path); DECODE_OR_RETURN(request, path);
remote::file_handle handle; remote::file_handle handle{};
DECODE_OR_RETURN(request, handle); DECODE_OR_RETURN(request, handle);
ret = this->json_release_directory_snapshot(&path[0], handle); ret = this->json_release_directory_snapshot(path.data(), handle);
if (this->remove_directory(client_id, if (this->remove_directory(client_id,
reinterpret_cast<void *>(handle))) { reinterpret_cast<void *>(handle))) {
return ret; return ret;
@ -1380,7 +1390,7 @@ public:
protected: protected:
app_config &config_; app_config &config_;
drive &drive_; drive &drive_;
const std::string mount_location_; std::string mount_location_;
private: private:
client_pool client_pool_; client_pool client_pool_;
@ -1422,7 +1432,7 @@ protected:
} }
void delete_open_directory(void *dir) override { void delete_open_directory(void *dir) override {
if (dir) { if (dir != nullptr) {
delete reinterpret_cast<directory_iterator *>(dir); delete reinterpret_cast<directory_iterator *>(dir);
} }
} }

View File

@ -29,84 +29,84 @@ class i_remote_instance : public virtual i_remote_json {
INTERFACE_SETUP(i_remote_instance); INTERFACE_SETUP(i_remote_instance);
public: public:
virtual auto winfsp_can_delete(PVOID fileDesc, PWSTR fileName) virtual auto winfsp_can_delete(PVOID file_desc, PWSTR file_name)
-> packet::error_type = 0; -> packet::error_type = 0;
virtual auto winfsp_cleanup(PVOID fileDesc, PWSTR fileName, UINT32 flags, virtual auto winfsp_cleanup(PVOID file_desc, PWSTR file_name, UINT32 flags,
BOOLEAN &wasClosed) -> packet::error_type = 0; BOOLEAN &was_closed) -> packet::error_type = 0;
virtual auto winfsp_close(PVOID fileDesc) -> packet::error_type = 0; virtual auto winfsp_close(PVOID file_desc) -> packet::error_type = 0;
virtual auto winfsp_create(PWSTR fileName, UINT32 createOptions, virtual auto winfsp_create(PWSTR file_name, UINT32 create_options,
UINT32 grantedAccess, UINT32 fileAttributes, UINT32 granted_access, UINT32 file_attributes,
UINT64 allocationSize, PVOID *fileDesc, UINT64 allocation_size, PVOID *file_desc,
remote::file_info *fileInfo, remote::file_info *file_info,
std::string &normalizedName, BOOLEAN &exists) std::string &normalized_name, BOOLEAN &exists)
-> packet::error_type = 0; -> packet::error_type = 0;
virtual auto winfsp_flush(PVOID fileDesc, remote::file_info *fileInfo) virtual auto winfsp_flush(PVOID file_desc, remote::file_info *file_info)
-> packet::error_type = 0; -> packet::error_type = 0;
virtual auto winfsp_get_dir_buffer(PVOID fileDesc, PVOID *&ptr) virtual auto winfsp_get_dir_buffer(PVOID file_desc, PVOID *&ptr)
-> packet::error_type = 0; -> packet::error_type = 0;
virtual auto winfsp_get_file_info(PVOID fileDesc, remote::file_info *fileInfo) virtual auto winfsp_get_file_info(PVOID file_desc, remote::file_info *file_info)
-> packet::error_type = 0; -> packet::error_type = 0;
virtual auto virtual auto
winfsp_get_security_by_name(PWSTR fileName, PUINT32 fileAttributes, winfsp_get_security_by_name(PWSTR file_name, PUINT32 file_attributes,
std::uint64_t *securityDescriptorSize, std::uint64_t *security_descriptor_size,
std::wstring &strDescriptor) std::wstring &str_descriptor)
-> packet::error_type = 0; -> packet::error_type = 0;
virtual auto winfsp_get_volume_info(UINT64 &totalSize, UINT64 &freeSize, virtual auto winfsp_get_volume_info(UINT64 &total_size, UINT64 &free_size,
std::string &volumeLabel) std::string &volume_label)
-> packet::error_type = 0; -> packet::error_type = 0;
virtual auto winfsp_mounted(const std::wstring &location) virtual auto winfsp_mounted(const std::wstring &location)
-> packet::error_type = 0; -> packet::error_type = 0;
virtual auto winfsp_open(PWSTR fileName, UINT32 createOptions, virtual auto winfsp_open(PWSTR file_name, UINT32 create_options,
UINT32 grantedAccess, PVOID *fileDesc, UINT32 granted_access, PVOID *file_desc,
remote::file_info *fileInfo, remote::file_info *file_info,
std::string &normalizedName) std::string &normalized_name)
-> packet::error_type = 0; -> packet::error_type = 0;
virtual auto winfsp_overwrite(PVOID fileDesc, UINT32 fileAttributes, virtual auto winfsp_overwrite(PVOID file_desc, UINT32 file_attributes,
BOOLEAN replaceFileAttributes, BOOLEAN replace_file_attributes,
UINT64 allocationSize, UINT64 allocation_size,
remote::file_info *fileInfo) remote::file_info *file_info)
-> packet::error_type = 0; -> packet::error_type = 0;
virtual auto winfsp_read(PVOID fileDesc, PVOID buffer, UINT64 offset, virtual auto winfsp_read(PVOID file_desc, PVOID buffer, UINT64 offset,
UINT32 length, PUINT32 bytesTransferred) UINT32 length, PUINT32 bytes_transferred)
-> packet::error_type = 0; -> packet::error_type = 0;
virtual auto winfsp_read_directory(PVOID fileDesc, PWSTR pattern, virtual auto winfsp_read_directory(PVOID file_desc, PWSTR pattern,
PWSTR marker, json &itemList) PWSTR marker, json &itemList)
-> packet::error_type = 0; -> packet::error_type = 0;
virtual auto winfsp_rename(PVOID fileDesc, PWSTR fileName, PWSTR newFileName, virtual auto winfsp_rename(PVOID file_desc, PWSTR file_name, PWSTR new_file_name,
BOOLEAN replaceIfExists) -> packet::error_type = 0; BOOLEAN replace_if_exists) -> packet::error_type = 0;
virtual auto winfsp_set_basic_info(PVOID fileDesc, UINT32 fileAttributes, virtual auto winfsp_set_basic_info(PVOID file_desc, UINT32 file_attributes,
UINT64 creationTime, UINT64 lastAccessTime, UINT64 creation_time, UINT64 last_access_time,
UINT64 lastWriteTime, UINT64 changeTime, UINT64 last_write_time, UINT64 change_time,
remote::file_info *fileInfo) remote::file_info *file_info)
-> packet::error_type = 0; -> packet::error_type = 0;
virtual auto winfsp_set_file_size(PVOID fileDesc, UINT64 newSize, virtual auto winfsp_set_file_size(PVOID file_desc, UINT64 new_size,
BOOLEAN setAllocationSize, BOOLEAN set_allocation_size,
remote::file_info *fileInfo) remote::file_info *file_info)
-> packet::error_type = 0; -> packet::error_type = 0;
virtual auto winfsp_unmounted(const std::wstring &location) virtual auto winfsp_unmounted(const std::wstring &location)
-> packet::error_type = 0; -> packet::error_type = 0;
virtual auto winfsp_write(PVOID fileDesc, PVOID buffer, UINT64 offset, virtual auto winfsp_write(PVOID file_desc, PVOID buffer, UINT64 offset,
UINT32 length, BOOLEAN writeToEndOfFile, UINT32 length, BOOLEAN write_to_end,
BOOLEAN constrainedIo, PUINT32 bytesTransferred, BOOLEAN constrained_io, PUINT32 bytes_transferred,
remote::file_info *fileInfo) remote::file_info *file_info)
-> packet::error_type = 0; -> packet::error_type = 0;
}; };

View File

@ -266,7 +266,7 @@ public:
remote::file_info *file_info) remote::file_info *file_info)
-> packet::error_type override; -> packet::error_type override;
auto winfsp_set_file_size(PVOID file_desc, UINT64 newSize, auto winfsp_set_file_size(PVOID file_desc, UINT64 new_size,
BOOLEAN set_allocation_size, BOOLEAN set_allocation_size,
remote::file_info *file_info) remote::file_info *file_info)
-> packet::error_type override; -> packet::error_type override;

View File

@ -172,7 +172,7 @@ public:
PULONG bytes_transferred) -> NTSTATUS override; PULONG bytes_transferred) -> NTSTATUS override;
auto Rename(PVOID file_node, PVOID file_desc, PWSTR file_name, auto Rename(PVOID file_node, PVOID file_desc, PWSTR file_name,
PWSTR newFileName, BOOLEAN replace_if_exists) PWSTR new_file_name, BOOLEAN replace_if_exists)
-> NTSTATUS override; -> NTSTATUS override;
auto SetBasicInfo(PVOID file_node, PVOID file_desc, UINT32 attributes, auto SetBasicInfo(PVOID file_node, PVOID file_desc, UINT32 attributes,

View File

@ -23,7 +23,13 @@
#define INCLUDE_EVENTS_EVENT_HPP_ #define INCLUDE_EVENTS_EVENT_HPP_
namespace repertory { namespace repertory {
enum class event_level { error, warn, normal, debug, verbose }; enum class event_level {
error,
warn,
normal,
debug,
verbose,
};
auto event_level_from_string(std::string level) -> event_level; auto event_level_from_string(std::string level) -> event_level;
@ -37,10 +43,14 @@ protected:
: allow_async_(allow_async), ss_(ss.str()), j_(std::move(j)) {} : allow_async_(allow_async), ss_(ss.str()), j_(std::move(j)) {}
public: public:
event(const event &) = delete;
event(event &&) = delete;
auto operator=(const event &) -> event & = delete;
auto operator=(event &&) -> event & = delete;
virtual ~event() = default; virtual ~event() = default;
private: private:
const bool allow_async_; bool allow_async_;
protected: protected:
std::stringstream ss_; std::stringstream ss_;

View File

@ -32,12 +32,12 @@ using event_consumer = event_system::event_consumer;
#define E_CAST(t) ((std::string)t) #define E_CAST(t) ((std::string)t)
#define E_DOUBLE(d) std::to_string(d) #define E_DOUBLE(d) std::to_string(d)
#define E_DOUBLE_PRECISE(d) \ #define E_DOUBLE_PRECISE(dbl_val) \
([](const double &d) -> std::string { \ ([](const double &d) -> std::string { \
std::stringstream ss; \ std::stringstream ss; \
ss << std::fixed << std::setprecision(2) << d; \ ss << std::fixed << std::setprecision(2) << d; \
return ss.str(); \ return ss.str(); \
})(d) })(dbl_val)
#define E_FROM_BOOL(t) std::to_string(t) #define E_FROM_BOOL(t) std::to_string(t)
#define E_FROM_EXCEPTION(e) std::string(e.what() ? e.what() : "") #define E_FROM_EXCEPTION(e) std::string(e.what() ? e.what() : "")
#define E_FROM_INT32(t) std::to_string(t) #define E_FROM_INT32(t) std::to_string(t)
@ -69,8 +69,9 @@ using event_consumer = event_system::event_consumer;
#define E_PROP(type, name, short_name, ts) \ #define E_PROP(type, name, short_name, ts) \
private: \ private: \
void init_##short_name(const type &val) { \ void init_##short_name(const type &val) { \
ss_ << "|" << #short_name << "|" << ts(val); \ auto ts_val = ts(val); \
j_[#name] = ts(val); \ ss_ << "|" << #short_name << "|" << ts_val; \
j_[#name] = ts_val; \
} \ } \
\ \
public: \ public: \

View File

@ -54,6 +54,12 @@ public:
~event_consumer() { t_event_system::instance().release(this); } ~event_consumer() { t_event_system::instance().release(this); }
public:
event_consumer(const event_consumer &) = delete;
event_consumer(event_consumer &&) = delete;
auto operator=(const event_consumer &) -> event_consumer & = delete;
auto operator=(event_consumer &&) -> event_consumer & = delete;
private: private:
std::function<void(const event &)> callback_; std::function<void(const event &)> callback_;
@ -82,9 +88,9 @@ private:
void process_events() { void process_events() {
std::vector<std::shared_ptr<event_type>> events; std::vector<std::shared_ptr<event_type>> events;
{ {
unique_mutex_lock l(event_mutex_); unique_mutex_lock lock(event_mutex_);
if (not stop_requested_ && event_list_.empty()) { if (not stop_requested_ && event_list_.empty()) {
event_notify_.wait_for(l, 1s); event_notify_.wait_for(lock, 1s);
} }
if (not event_list_.empty()) { if (not event_list_.empty()) {
@ -96,15 +102,16 @@ private:
const auto notify_events = [this](const std::string &name, const auto notify_events = [this](const std::string &name,
const event_type &event) { const event_type &event) {
std::deque<std::future<void>> futures; std::deque<std::future<void>> futures;
recur_mutex_lock l(consumer_mutex_); recur_mutex_lock lock(consumer_mutex_);
if (event_consumers_.find(name) != event_consumers_.end()) { if (event_consumers_.find(name) != event_consumers_.end()) {
for (auto *ec : event_consumers_[name]) { for (auto *consumer : event_consumers_[name]) {
if (event.get_allow_async()) { if (event.get_allow_async()) {
futures.emplace_back(std::async(std::launch::async, [ec, &event]() { futures.emplace_back(
ec->notify_event(event); std::async(std::launch::async, [consumer, &event]() {
consumer->notify_event(event);
})); }));
} else { } else {
ec->notify_event(event); consumer->notify_event(event);
} }
} }
} }
@ -115,48 +122,48 @@ private:
} }
}; };
for (const auto &e : events) { for (const auto &evt : events) {
notify_events("", *e.get()); notify_events("", *evt.get());
notify_events(e->get_name(), *e.get()); notify_events(evt->get_name(), *evt.get());
} }
} }
void queue_event(event_type *e) { void queue_event(std::shared_ptr<event_type> evt) {
mutex_lock l(event_mutex_); mutex_lock lock(event_mutex_);
event_list_.emplace_back(std::shared_ptr<event_type>(e)); event_list_.push_back(std::move(evt));
event_notify_.notify_all(); event_notify_.notify_all();
} }
public: public:
void attach(event_consumer *ec) { void attach(event_consumer *consumer) {
recur_mutex_lock l(consumer_mutex_); recur_mutex_lock lock(consumer_mutex_);
event_consumers_[""].push_back(ec); event_consumers_[""].push_back(consumer);
} }
void attach(const std::string &event_name, event_consumer *ec) { void attach(const std::string &event_name, event_consumer *consumer) {
recur_mutex_lock l(consumer_mutex_); recur_mutex_lock lock(consumer_mutex_);
event_consumers_[event_name].push_back(ec); event_consumers_[event_name].push_back(consumer);
} }
template <typename t, typename... args> void raise(args &&...a) { template <typename event_t, typename... arg_t> void raise(arg_t &&...args) {
queue_event(new t(std::forward<args>(a)...)); queue_event(std::make_shared<event_t>(std::forward<arg_t>(args)...));
} }
void release(event_consumer *ec) { void release(event_consumer *consumer) {
recur_mutex_lock l(consumer_mutex_); recur_mutex_lock lock(consumer_mutex_);
auto it = std::find_if(event_consumers_.begin(), event_consumers_.end(), auto iter =
[&](const auto &kv) -> bool { std::find_if(event_consumers_.begin(), event_consumers_.end(),
return utils::collection_includes(kv.second, ec); [&](const auto &item) -> bool {
return utils::collection_includes(item.second, consumer);
}); });
if (it != event_consumers_.end()) { if (iter != event_consumers_.end()) {
auto &q = (*it).second; utils::remove_element_from((*iter).second, consumer);
utils::remove_element_from(q, ec);
} }
} }
void start() { void start() {
mutex_lock l(run_mutex_); mutex_lock lock(run_mutex_);
if (not event_thread_) { if (not event_thread_) {
stop_requested_ = false; stop_requested_ = false;
event_thread_ = std::make_unique<std::thread>([this]() { event_thread_ = std::make_unique<std::thread>([this]() {
@ -168,7 +175,7 @@ public:
} }
void stop() { void stop() {
mutex_lock l(run_mutex_); mutex_lock lock(run_mutex_);
if (event_thread_) { if (event_thread_) {
stop_requested_ = true; stop_requested_ = true;
event_notify_.notify_all(); event_notify_.notify_all();

View File

@ -72,13 +72,13 @@ public:
auto operator=(const download &) noexcept -> download & = delete; auto operator=(const download &) noexcept -> download & = delete;
private: private:
bool complete_ = false; bool complete_{false};
api_error error_ = api_error::success; api_error error_{api_error::success};
std::mutex mtx_; std::mutex mtx_;
std::condition_variable notify_; std::condition_variable notify_;
public: public:
void notify(const api_error &e); void notify(const api_error &err);
auto wait() -> api_error; auto wait() -> api_error;
}; };
@ -117,18 +117,18 @@ public:
i_provider &provider_; i_provider &provider_;
private: private:
api_error error_ = api_error::success; api_error error_{api_error::success};
mutable std::mutex error_mtx_; mutable std::mutex error_mtx_;
stop_type io_stop_requested_ = false; stop_type io_stop_requested_{false};
std::unique_ptr<std::thread> io_thread_; std::unique_ptr<std::thread> io_thread_;
protected: protected:
std::unordered_map<std::size_t, std::shared_ptr<download>> std::unordered_map<std::size_t, std::shared_ptr<download>>
active_downloads_; active_downloads_;
mutable std::recursive_mutex file_mtx_; mutable std::recursive_mutex file_mtx_;
std::atomic<std::chrono::system_clock::time_point> last_access_ = std::atomic<std::chrono::system_clock::time_point> last_access_{
std::chrono::system_clock::now(); std::chrono::system_clock::now()};
bool modified_ = false; bool modified_{false};
native_file_ptr nf_; native_file_ptr nf_;
mutable std::mutex io_thread_mtx_; mutable std::mutex io_thread_mtx_;
std::condition_variable io_thread_notify_; std::condition_variable io_thread_notify_;
@ -194,17 +194,17 @@ public:
class open_file final : public open_file_base { class open_file final : public open_file_base {
public: public:
open_file(std::uint64_t chunk_size, std::uint8_t chunk_timeout, open_file(std::uint64_t chunk_size, std::uint8_t chunk_timeout,
filesystem_item fsi, i_provider &provider, i_upload_manager &um); filesystem_item fsi, i_provider &provider, i_upload_manager &mgr);
open_file(std::uint64_t chunk_size, std::uint8_t chunk_timeout, open_file(std::uint64_t chunk_size, std::uint8_t chunk_timeout,
filesystem_item fsi, filesystem_item fsi,
std::map<std::uint64_t, open_file_data> open_data, std::map<std::uint64_t, open_file_data> open_data,
i_provider &provider, i_upload_manager &um); i_provider &provider, i_upload_manager &mgr);
open_file(std::uint64_t chunk_size, std::uint8_t chunk_timeout, open_file(std::uint64_t chunk_size, std::uint8_t chunk_timeout,
filesystem_item fsi, i_provider &provider, filesystem_item fsi, i_provider &provider,
std::optional<boost::dynamic_bitset<>> read_state, std::optional<boost::dynamic_bitset<>> read_state,
i_upload_manager &um); i_upload_manager &mgr);
private: private:
open_file(std::uint64_t chunk_size, std::uint8_t chunk_timeout, open_file(std::uint64_t chunk_size, std::uint8_t chunk_timeout,
@ -212,7 +212,7 @@ public:
std::map<std::uint64_t, open_file_data> open_data, std::map<std::uint64_t, open_file_data> open_data,
i_provider &provider, i_provider &provider,
std::optional<boost::dynamic_bitset<>> read_state, std::optional<boost::dynamic_bitset<>> read_state,
i_upload_manager &um); i_upload_manager &mgr);
public: public:
open_file() = delete; open_file() = delete;
@ -225,11 +225,11 @@ public:
~open_file() override; ~open_file() override;
private: private:
i_upload_manager &um_; i_upload_manager &mgr_;
private: private:
bool notified_ = false; bool notified_ = false;
std::size_t read_chunk_index_ = 0u; std::size_t read_chunk_index_{};
boost::dynamic_bitset<> read_state_; boost::dynamic_bitset<> read_state_;
std::unique_ptr<std::thread> reader_thread_; std::unique_ptr<std::thread> reader_thread_;
std::unique_ptr<std::thread> download_thread_; std::unique_ptr<std::thread> download_thread_;
@ -262,11 +262,13 @@ public:
auto is_write_supported() const -> bool override { return true; } auto is_write_supported() const -> bool override { return true; }
[[nodiscard]] auto native_operation(const native_operation_callback &cb) [[nodiscard]] auto
native_operation(const native_operation_callback &callback)
-> api_error override; -> api_error override;
[[nodiscard]] auto native_operation(std::uint64_t new_file_size, [[nodiscard]] auto
const native_operation_callback &cb) native_operation(std::uint64_t new_file_size,
const native_operation_callback &callback)
-> api_error override; -> api_error override;
void remove(std::uint64_t handle) override; void remove(std::uint64_t handle) override;
@ -313,8 +315,8 @@ public:
std::unique_ptr<std::thread> chunk_reverse_thread_; std::unique_ptr<std::thread> chunk_reverse_thread_;
std::condition_variable chunk_notify_; std::condition_variable chunk_notify_;
mutable std::mutex chunk_mtx_; mutable std::mutex chunk_mtx_;
std::size_t current_chunk_ = 0u; std::size_t current_chunk_{};
std::size_t first_chunk_ = 0u; std::size_t first_chunk_{};
std::size_t last_chunk_; std::size_t last_chunk_;
private: private:
@ -355,7 +357,8 @@ public:
auto is_write_supported() const -> bool override { return false; } auto is_write_supported() const -> bool override { return false; }
[[nodiscard]] auto native_operation(const native_operation_callback &cb) [[nodiscard]] auto
native_operation(const native_operation_callback &callback)
-> api_error override; -> api_error override;
[[nodiscard]] auto native_operation(std::uint64_t, [[nodiscard]] auto native_operation(std::uint64_t,
@ -536,9 +539,6 @@ public:
const open_file_data &ofd, std::uint64_t &handle, const open_file_data &ofd, std::uint64_t &handle,
std::shared_ptr<i_open_file> &f) -> api_error; std::shared_ptr<i_open_file> &f) -> api_error;
auto perform_locked_operation(locked_operation_callback locked_operation)
-> bool override;
[[nodiscard]] auto remove_file(const std::string &api_path) -> api_error; [[nodiscard]] auto remove_file(const std::string &api_path) -> api_error;
[[nodiscard]] auto rename_directory(const std::string &from_api_path, [[nodiscard]] auto rename_directory(const std::string &from_api_path,

View File

@ -30,9 +30,6 @@ class i_provider;
class i_file_manager { class i_file_manager {
INTERFACE_SETUP(i_file_manager); INTERFACE_SETUP(i_file_manager);
public:
using locked_operation_callback = std::function<bool(i_provider &)>;
public: public:
[[nodiscard]] virtual auto evict_file(const std::string &api_path) [[nodiscard]] virtual auto evict_file(const std::string &api_path)
-> bool = 0; -> bool = 0;
@ -49,10 +46,6 @@ public:
[[nodiscard]] virtual auto is_processing(const std::string &api_path) const [[nodiscard]] virtual auto is_processing(const std::string &api_path) const
-> bool = 0; -> bool = 0;
virtual auto
perform_locked_operation(locked_operation_callback locked_operation)
-> bool = 0;
virtual void update_used_space(std::uint64_t &used_space) const = 0; virtual void update_used_space(std::uint64_t &used_space) const = 0;
}; };
} // namespace repertory } // namespace repertory

View File

@ -56,11 +56,11 @@ public:
[[nodiscard]] virtual auto is_directory() const -> bool = 0; [[nodiscard]] virtual auto is_directory() const -> bool = 0;
[[nodiscard]] virtual auto [[nodiscard]] virtual auto
native_operation(const native_operation_callback &cb) -> api_error = 0; native_operation(const native_operation_callback &callback) -> api_error = 0;
[[nodiscard]] virtual auto [[nodiscard]] virtual auto
native_operation(std::uint64_t new_file_size, native_operation(std::uint64_t new_file_size,
const native_operation_callback &cb) -> api_error = 0; const native_operation_callback &callback) -> api_error = 0;
[[nodiscard]] virtual auto read(std::size_t read_size, [[nodiscard]] virtual auto read(std::size_t read_size,
std::uint64_t read_offset, data_buffer &data) std::uint64_t read_offset, data_buffer &data)

View File

@ -68,11 +68,10 @@ public:
[[nodiscard]] auto create_meta_attributes( [[nodiscard]] auto create_meta_attributes(
std::uint64_t accessed_date, std::uint32_t attributes, std::uint64_t accessed_date, std::uint32_t attributes,
std::uint64_t changed_date, std::uint64_t creation_date, bool directory, std::uint64_t changed_date, std::uint64_t creation_date, bool directory,
const std::string &encryption_token, std::uint32_t gid, std::uint32_t gid, const std::string &key, std::uint32_t mode,
const std::string &key, std::uint32_t mode, std::uint64_t modified_date, std::uint64_t modified_date, std::uint32_t osx_backup,
std::uint32_t osx_backup, std::uint32_t osx_flags, std::uint64_t size, std::uint32_t osx_flags, std::uint64_t size, const std::string &source_path,
const std::string &source_path, std::uint32_t uid, std::uint32_t uid, std::uint64_t written_date) -> api_meta_map;
std::uint64_t written_date) -> api_meta_map;
[[nodiscard]] auto provider_meta_handler(i_provider &provider, bool directory, [[nodiscard]] auto provider_meta_handler(i_provider &provider, bool directory,
const api_file &file) -> api_error; const api_file &file) -> api_error;

View File

@ -73,11 +73,10 @@ public:
[[nodiscard]] auto create_meta_attributes( [[nodiscard]] auto create_meta_attributes(
std::uint64_t accessed_date, std::uint32_t attributes, std::uint64_t accessed_date, std::uint32_t attributes,
std::uint64_t changed_date, std::uint64_t creation_date, bool directory, std::uint64_t changed_date, std::uint64_t creation_date, bool directory,
const std::string &encryption_token, std::uint32_t gid, std::uint32_t gid, const std::string &key, std::uint32_t mode,
const std::string &key, std::uint32_t mode, std::uint64_t modified_date, std::uint64_t modified_date, std::uint32_t osx_backup,
std::uint32_t osx_backup, std::uint32_t osx_flags, std::uint64_t size, std::uint32_t osx_flags, std::uint64_t size, const std::string &source_path,
const std::string &source_path, std::uint32_t uid, std::uint32_t uid, std::uint64_t written_date) -> api_meta_map;
std::uint64_t written_date) -> api_meta_map;
[[nodiscard]] auto provider_meta_handler(i_provider &provider, bool directory, [[nodiscard]] auto provider_meta_handler(i_provider &provider, bool directory,
const api_file &file) -> api_error; const api_file &file) -> api_error;

View File

@ -22,95 +22,92 @@
#ifndef INCLUDE_PROVIDERS_BASE_PROVIDER_HPP_ #ifndef INCLUDE_PROVIDERS_BASE_PROVIDER_HPP_
#define INCLUDE_PROVIDERS_BASE_PROVIDER_HPP_ #define INCLUDE_PROVIDERS_BASE_PROVIDER_HPP_
#include "db/meta_db.hpp"
#include "providers/i_provider.hpp" #include "providers/i_provider.hpp"
#include "types/repertory.hpp"
namespace repertory { namespace repertory {
class app_config; class app_config;
class i_file_manager; class i_file_manager;
class i_http_comm;
class base_provider : public i_provider { class base_provider : public i_provider {
public: public:
explicit base_provider(app_config &config); base_provider(app_config &config, i_http_comm &comm)
: config_(config), comm_(comm) {}
~base_provider() override = default;
private: private:
app_config &config_; app_config &config_;
std::atomic<std::uint64_t> used_space_{0U}; i_http_comm &comm_;
protected: private:
api_item_added_callback api_item_added_; api_item_added_callback api_item_added_;
std::unique_ptr<meta_db> meta_db_; std::unique_ptr<rocksdb::DB> db_;
mutable std::recursive_mutex notify_added_mutex_; std::string DB_NAME = "meta_db";
i_file_manager *fm_ = nullptr; i_file_manager *fm_{};
stop_type stop_requested_ = false;
private:
void remove_deleted_files();
protected: protected:
void calculate_used_drive_space(bool add_missing); [[nodiscard]] static auto create_api_file(std::string path, std::string key,
std::uint64_t size) -> api_file;
[[nodiscard]] static auto create_api_file(std::string path,
std::uint64_t size,
api_meta_map &meta) -> api_file;
[[nodiscard]] virtual auto create_directory_impl(const std::string &api_path,
api_meta_map &meta)
-> api_error = 0;
[[nodiscard]] virtual auto [[nodiscard]] virtual auto
check_file_exists(const std::string &api_path) const -> api_error = 0; create_file_extra(const std::string & /* api_path */,
api_meta_map & /* meta */) -> api_error {
return api_error::success;
}
void cleanup(); [[nodiscard]] auto get_api_item_added() -> api_item_added_callback & {
return api_item_added_;
}
[[nodiscard]] auto get_api_item_added() const
-> const api_item_added_callback & {
return api_item_added_;
}
[[nodiscard]] auto get_comm() const -> i_http_comm & { return comm_; }
[[nodiscard]] auto get_config() -> app_config & { return config_; } [[nodiscard]] auto get_config() -> app_config & { return config_; }
[[nodiscard]] auto get_config() const -> app_config & { return config_; } [[nodiscard]] auto get_config() const -> const app_config & {
return config_;
[[nodiscard]] virtual auto
handle_rename_file(const std::string &from_api_path,
const std::string &to_api_path,
const std::string &source_path) -> api_error = 0;
[[nodiscard]] auto notify_directory_added(const std::string &api_path,
const std::string &api_parent) const
-> api_error {
return const_cast<base_provider *>(this)->notify_directory_added(
api_path, api_parent);
} }
[[nodiscard]] virtual auto [[nodiscard]] virtual auto
notify_directory_added(const std::string &api_path, get_directory_items_impl(const std::string &api_path,
const std::string &api_parent) -> api_error;
[[nodiscard]] auto notify_file_added(const std::string &api_path,
const std::string &api_parent,
std::uint64_t size) const -> api_error {
return const_cast<base_provider *>(this)->notify_file_added(
api_path, api_parent, size);
}
[[nodiscard]] virtual auto notify_file_added(const std::string &api_path,
const std::string &api_parent,
std::uint64_t size)
-> api_error = 0;
[[nodiscard]] virtual auto
populate_directory_items(const std::string &api_path,
directory_item_list &list) const -> api_error = 0; directory_item_list &list) const -> api_error = 0;
[[nodiscard]] virtual auto populate_file(const std::string &api_path, [[nodiscard]] auto get_db() const -> rocksdb::DB * { return db_.get(); }
api_file &file) const
-> api_error = 0;
auto processed_orphaned_file(const std::string &source_path, [[nodiscard]] auto get_file_mgr() -> i_file_manager * { return fm_; }
const std::string &api_path = "") const -> bool;
void remove_deleted_files(); [[nodiscard]] auto get_file_mgr() const -> const i_file_manager * {
return fm_;
void remove_expired_orphaned_files();
void remove_unknown_source_files();
[[nodiscard]] auto remove_item_meta(const std::string &api_path)
-> api_error {
return meta_db_->remove_item_meta(api_path);
} }
void update_filesystem_item(bool directory, const api_error &error, [[nodiscard]] virtual auto get_used_drive_space_impl() const
const std::string &api_path, -> std::uint64_t = 0;
filesystem_item &fsi) const;
[[nodiscard]] virtual auto remove_directory_impl(const std::string &api_path)
-> api_error = 0;
[[nodiscard]] virtual auto remove_file_impl(const std::string &api_path)
-> api_error = 0;
[[nodiscard]] virtual auto upload_file_impl(const std::string &api_path,
const std::string &source_path,
stop_type &stop_requested)
-> api_error = 0;
public: public:
[[nodiscard]] auto [[nodiscard]] auto
@ -118,6 +115,9 @@ public:
const std::string &api_path) const std::string &api_path)
-> api_error override; -> api_error override;
[[nodiscard]] auto create_directory(const std::string &api_path,
api_meta_map &meta) -> api_error override;
[[nodiscard]] auto create_file(const std::string &api_path, [[nodiscard]] auto create_file(const std::string &api_path,
api_meta_map &meta) -> api_error override; api_meta_map &meta) -> api_error override;
@ -129,9 +129,6 @@ public:
directory_item_list &list) const directory_item_list &list) const
-> api_error override; -> api_error override;
[[nodiscard]] auto get_file(const std::string &api_path, api_file &file) const
-> api_error override;
[[nodiscard]] auto get_file_size(const std::string &api_path, [[nodiscard]] auto get_file_size(const std::string &api_path,
std::uint64_t &file_size) const std::uint64_t &file_size) const
-> api_error override; -> api_error override;
@ -142,7 +139,7 @@ public:
-> api_error override; -> api_error override;
[[nodiscard]] auto get_filesystem_item_and_file(const std::string &api_path, [[nodiscard]] auto get_filesystem_item_and_file(const std::string &api_path,
api_file &file, api_file &f,
filesystem_item &fsi) const filesystem_item &fsi) const
-> api_error override; -> api_error override;
@ -161,44 +158,43 @@ public:
-> api_error override; -> api_error override;
[[nodiscard]] auto get_pinned_files() const [[nodiscard]] auto get_pinned_files() const
-> std::vector<std::string> override { -> std::vector<std::string> override;
return meta_db_->get_pinned_files();
} [[nodiscard]] auto get_total_item_count() const -> std::uint64_t override;
[[nodiscard]] auto get_used_drive_space() const -> std::uint64_t override; [[nodiscard]] auto get_used_drive_space() const -> std::uint64_t override;
[[nodiscard]] auto is_file_writeable(const std::string &) const [[nodiscard]] auto is_file_writeable(const std::string &api_path) const
-> bool override { -> bool override;
return true;
} [[nodiscard]] auto remove_directory(const std::string &api_path)
-> api_error override;
[[nodiscard]] auto remove_file(const std::string &api_path)
-> api_error override;
[[nodiscard]] auto remove_item_meta(const std::string &api_path, [[nodiscard]] auto remove_item_meta(const std::string &api_path,
const std::string &key) const std::string &key)
-> api_error override {
return meta_db_->remove_item_meta(api_path, key);
}
[[nodiscard]] auto rename_file(const std::string &from_api_path,
const std::string &to_api_path)
-> api_error override; -> api_error override;
[[nodiscard]] auto set_item_meta(const std::string &api_path, [[nodiscard]] auto set_item_meta(const std::string &api_path,
const std::string &key, const std::string &key,
const std::string &value) const std::string &value)
-> api_error override { -> api_error override;
return meta_db_->set_item_meta(api_path, key, value);
}
[[nodiscard]] auto set_item_meta(const std::string &api_path, [[nodiscard]] auto set_item_meta(const std::string &api_path,
const api_meta_map &meta) const api_meta_map &meta)
-> api_error override { -> api_error override;
return meta_db_->set_item_meta(api_path, meta);
}
[[nodiscard]] auto start(api_item_added_callback api_item_added, [[nodiscard]] auto start(api_item_added_callback api_item_added,
i_file_manager *fm) -> bool override; i_file_manager *mgr) -> bool override;
void stop() override; void stop() override;
[[nodiscard]] auto upload_file(const std::string &api_path,
const std::string &source_path,
stop_type &stop_requested)
-> api_error override;
}; };
} // namespace repertory } // namespace repertory

View File

@ -33,6 +33,12 @@ public:
~encrypt_provider() override = default; ~encrypt_provider() override = default;
public:
encrypt_provider(const encrypt_provider &) = delete;
encrypt_provider(encrypt_provider &&) = delete;
auto operator=(const encrypt_provider &) -> encrypt_provider & = delete;
auto operator=(encrypt_provider &&) -> encrypt_provider & = delete;
private: private:
struct reader_info final { struct reader_info final {
std::chrono::system_clock::time_point last_access_time = std::chrono::system_clock::time_point last_access_time =
@ -47,7 +53,7 @@ private:
rocksdb::ColumnFamilyHandle *dir_family_{}; rocksdb::ColumnFamilyHandle *dir_family_{};
rocksdb::ColumnFamilyHandle *file_family_{}; rocksdb::ColumnFamilyHandle *file_family_{};
rocksdb::ColumnFamilyHandle *source_family_{}; rocksdb::ColumnFamilyHandle *source_family_{};
const std::string DB_NAME = "meta_db"; std::string DB_NAME = "meta_db";
private: private:
i_file_manager *fm_ = nullptr; i_file_manager *fm_ = nullptr;
@ -56,7 +62,7 @@ private:
std::recursive_mutex reader_lookup_mtx_{}; std::recursive_mutex reader_lookup_mtx_{};
private: private:
static auto create_api_file(const std::string api_path, bool directory, static auto create_api_file(const std::string &api_path, bool directory,
const std::string &source_path) -> api_file; const std::string &source_path) -> api_file;
static void create_item_meta(api_meta_map &meta, bool directory, static void create_item_meta(api_meta_map &meta, bool directory,
@ -201,13 +207,12 @@ public:
} }
[[nodiscard]] auto start(api_item_added_callback api_item_added, [[nodiscard]] auto start(api_item_added_callback api_item_added,
i_file_manager *fm) -> bool override; i_file_manager *mgr) -> bool override;
void stop() override; void stop() override;
[[nodiscard]] auto upload_file(const std::string & /*api_path*/, [[nodiscard]] auto upload_file(const std::string & /*api_path*/,
const std::string & /*source_path*/, const std::string & /*source_path*/,
const std::string & /*encryption_token*/,
stop_type & /*stop_requested*/) stop_type & /*stop_requested*/)
-> api_error override { -> api_error override {
return api_error::not_implemented; return api_error::not_implemented;

View File

@ -143,13 +143,13 @@ public:
-> api_error = 0; -> api_error = 0;
[[nodiscard]] virtual auto start(api_item_added_callback api_item_added, [[nodiscard]] virtual auto start(api_item_added_callback api_item_added,
i_file_manager *fm) -> bool = 0; i_file_manager *mgr) -> bool = 0;
virtual void stop() = 0; virtual void stop() = 0;
[[nodiscard]] virtual auto [[nodiscard]] virtual auto upload_file(const std::string &api_path,
upload_file(const std::string &api_path, const std::string &source_path, const std::string &source_path,
const std::string &encryption_token, stop_type &stop_requested) stop_type &stop_requested)
-> api_error = 0; -> api_error = 0;
}; };
} // namespace repertory } // namespace repertory

View File

@ -23,87 +23,93 @@
#define INCLUDE_PROVIDERS_S3_S3_PROVIDER_HPP_ #define INCLUDE_PROVIDERS_S3_S3_PROVIDER_HPP_
#if defined(REPERTORY_ENABLE_S3) #if defined(REPERTORY_ENABLE_S3)
#include "db/directory_db.hpp"
#include "providers/base_provider.hpp" #include "providers/base_provider.hpp"
#include "types/repertory.hpp" #include "types/repertory.hpp"
namespace repertory { namespace repertory {
class app_config; class app_config;
class i_file_manager; class i_file_manager;
class i_s3_comm; class i_http_comm;
struct head_object_result;
class s3_provider final : public base_provider { class s3_provider final : public base_provider {
public: public:
s3_provider(app_config &config, i_s3_comm &s3_comm); s3_provider(app_config &config, i_http_comm &comm);
~s3_provider() override = default; ~s3_provider() override = default;
private: public:
i_s3_comm &s3_comm_; s3_provider(const s3_provider &) = delete;
s3_provider(s3_provider &&) = delete;
auto operator=(const s3_provider &) -> s3_provider & = delete;
auto operator=(s3_provider &&) -> s3_provider & = delete;
private: private:
std::unique_ptr<directory_db> directory_db_; [[nodiscard]] auto add_if_not_found(api_file &file,
std::unique_ptr<std::thread> background_thread_; const std::string &object_name) const
-> api_error;
private: [[nodiscard]] auto create_file_extra(const std::string &api_path,
void create_directories(); api_meta_map &meta)
-> api_error override;
void create_parent_directories(const api_file &file, bool directory); [[nodiscard]] auto create_path_directories(const std::string &api_path,
const std::string &key) const
-> api_error;
void update_item_meta(directory_item &di) const; [[nodiscard]] auto decrypt_object_name(std::string &object_name) const
-> api_error;
[[nodiscard]] auto
get_object_info(bool directory, const std::string &api_path,
bool &is_encrypted, std::string &object_name,
head_object_result &result) const -> api_error;
[[nodiscard]] auto
get_object_list(std::string &response_data, long &response_code,
std::optional<std::string> delimiter = std::nullopt,
std::optional<std::string> prefix = std::nullopt) const
-> bool;
protected: protected:
[[nodiscard]] auto check_file_exists(const std::string &api_path) const [[nodiscard]] auto create_directory_impl(const std::string &api_path,
api_meta_map &meta)
-> api_error override; -> api_error override;
[[nodiscard]] auto handle_rename_file(const std::string &from_api_path, [[nodiscard]] auto get_directory_items_impl(const std::string &api_path,
const std::string &to_api_path,
const std::string &source_path)
-> api_error override;
[[nodiscard]] auto notify_directory_added(const std::string &api_path,
const std::string &api_parent)
-> api_error override;
[[nodiscard]] auto notify_file_added(const std::string &api_path,
const std::string &api_parent,
std::uint64_t size)
-> api_error override;
[[nodiscard]] auto populate_directory_items(const std::string &api_path,
directory_item_list &list) const directory_item_list &list) const
-> api_error override; -> api_error override;
[[nodiscard]] auto populate_file(const std::string &api_path, [[nodiscard]] auto get_used_drive_space_impl() const
api_file &file) const -> api_error override; -> std::uint64_t override;
[[nodiscard]] auto remove_directory_impl(const std::string &api_path)
-> api_error override;
[[nodiscard]] auto remove_file_impl(const std::string &api_path)
-> api_error override;
[[nodiscard]] auto upload_file_impl(const std::string &api_path,
const std::string &source_path,
stop_type &stop_requested)
-> api_error override;
public: public:
#ifdef REPERTORY_TESTING
void set_callback(api_item_added_callback cb) { api_item_added_ = cb; }
#endif // REPERTORY_TESTING
[[nodiscard]] auto create_directory(const std::string &api_path,
api_meta_map &meta) -> api_error override;
[[nodiscard]] auto create_file(const std::string &api_path,
api_meta_map &meta) -> api_error override;
[[nodiscard]] auto get_directory_item_count(const std::string &api_path) const [[nodiscard]] auto get_directory_item_count(const std::string &api_path) const
-> std::uint64_t override; -> std::uint64_t override;
[[nodiscard]] auto get_file(const std::string &api_path, api_file &file) const
-> api_error override;
[[nodiscard]] auto get_file_list(api_file_list &list) const [[nodiscard]] auto get_file_list(api_file_list &list) const
-> api_error override; -> api_error override;
[[nodiscard]] auto get_total_drive_space() const -> std::uint64_t override;
[[nodiscard]] auto get_provider_type() const -> provider_type override { [[nodiscard]] auto get_provider_type() const -> provider_type override {
return provider_type::s3; return provider_type::s3;
} }
[[nodiscard]] auto get_total_drive_space() const -> std::uint64_t override {
return std::numeric_limits<std::int64_t>::max() / std::int64_t(2);
}
[[nodiscard]] auto get_total_item_count() const -> std::uint64_t override;
[[nodiscard]] auto is_direct_only() const -> bool override { return false; } [[nodiscard]] auto is_direct_only() const -> bool override { return false; }
[[nodiscard]] auto is_directory(const std::string &api_path, [[nodiscard]] auto is_directory(const std::string &api_path,
@ -116,7 +122,7 @@ public:
[[nodiscard]] auto is_rename_supported() const -> bool override { [[nodiscard]] auto is_rename_supported() const -> bool override {
return false; return false;
} };
[[nodiscard]] auto read_file_bytes(const std::string &api_path, [[nodiscard]] auto read_file_bytes(const std::string &api_path,
std::size_t size, std::uint64_t offset, std::size_t size, std::uint64_t offset,
@ -124,21 +130,14 @@ public:
stop_type &stop_requested) stop_type &stop_requested)
-> api_error override; -> api_error override;
[[nodiscard]] auto remove_directory(const std::string &api_path) [[nodiscard]] auto rename_file(const std::string &from_api_path,
-> api_error override; const std::string &to_api_path)
[[nodiscard]] auto remove_file(const std::string &api_path)
-> api_error override; -> api_error override;
[[nodiscard]] auto start(api_item_added_callback api_item_added, [[nodiscard]] auto start(api_item_added_callback api_item_added,
i_file_manager *fm) -> bool override; i_file_manager *mgr) -> bool override;
void stop() override; void stop() override;
[[nodiscard]] auto
upload_file(const std::string &api_path, const std::string &source_path,
const std::string &encryption_token, stop_type &stop_requested)
-> api_error override;
}; };
} // namespace repertory } // namespace repertory

View File

@ -22,7 +22,7 @@
#ifndef INCLUDE_PROVIDERS_SIA_SIA_PROVIDER_HPP_ #ifndef INCLUDE_PROVIDERS_SIA_SIA_PROVIDER_HPP_
#define INCLUDE_PROVIDERS_SIA_SIA_PROVIDER_HPP_ #define INCLUDE_PROVIDERS_SIA_SIA_PROVIDER_HPP_
#include "providers/i_provider.hpp" #include "providers/base_provider.hpp"
#include "types/repertory.hpp" #include "types/repertory.hpp"
namespace repertory { namespace repertory {
@ -30,108 +30,64 @@ class app_config;
class i_file_manager; class i_file_manager;
class i_http_comm; class i_http_comm;
class sia_provider : public i_provider { class sia_provider : public base_provider {
public: public:
sia_provider(app_config &config, i_http_comm &comm); sia_provider(app_config &config, i_http_comm &comm);
~sia_provider() override = default; ~sia_provider() override = default;
private: public:
app_config &config_; sia_provider(const sia_provider &) = delete;
i_http_comm &comm_; sia_provider(sia_provider &&) = delete;
auto operator=(const sia_provider &) -> sia_provider & = delete;
auto operator=(sia_provider &&) -> sia_provider & = delete;
private: private:
const std::string DB_NAME = "meta_db";
api_item_added_callback api_item_added_;
std::unique_ptr<rocksdb::DB> db_;
i_file_manager *fm_ = nullptr;
private:
[[nodiscard]] static auto create_api_file(std::string path,
std::uint64_t size) -> api_file;
[[nodiscard]] static auto create_api_file(std::string path,
std::uint64_t size,
api_meta_map &meta) -> api_file;
[[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 get_object_list(const std::string &api_path,
nlohmann::json &object_list) const -> bool; nlohmann::json &object_list) const -> bool;
void remove_deleted_files(); protected:
[[nodiscard]] auto create_directory_impl(const std::string &api_path,
public: api_meta_map &meta)
[[nodiscard]] auto create_directory(const std::string &api_path,
api_meta_map &meta) -> api_error override;
[[nodiscard]] auto
create_directory_clone_source_meta(const std::string &source_api_path,
const std::string &api_path)
-> api_error override; -> api_error override;
[[nodiscard]] auto get_directory_item_count(const std::string &api_path) const [[nodiscard]] auto get_directory_items_impl(const std::string &api_path,
-> std::uint64_t override;
[[nodiscard]] auto create_file(const std::string &api_path,
api_meta_map &meta) -> api_error override;
[[nodiscard]] auto get_api_path_from_source(const std::string &source_path,
std::string &api_path) const
-> api_error override;
[[nodiscard]] auto get_directory_items(const std::string &api_path,
directory_item_list &list) const directory_item_list &list) const
-> api_error override; -> api_error override;
[[nodiscard]] auto get_used_drive_space_impl() const
-> std::uint64_t override;
[[nodiscard]] auto remove_directory_impl(const std::string &api_path)
-> api_error override;
[[nodiscard]] auto remove_file_impl(const std::string &api_path)
-> api_error override;
[[nodiscard]] auto upload_file_impl(const std::string &api_path,
const std::string &source_path,
stop_type &stop_requested)
-> api_error override;
public:
[[nodiscard]] auto get_directory_item_count(const std::string &api_path) const
-> std::uint64_t override;
[[nodiscard]] auto get_file(const std::string &api_path, api_file &file) const [[nodiscard]] auto get_file(const std::string &api_path, api_file &file) const
-> api_error override; -> api_error override;
[[nodiscard]] auto get_file_list(api_file_list &list) const [[nodiscard]] auto get_file_list(api_file_list &list) const
-> api_error override; -> api_error override;
[[nodiscard]] auto get_file_size(const std::string &api_path,
std::uint64_t &file_size) const
-> api_error override;
[[nodiscard]] auto get_filesystem_item(const std::string &api_path,
bool directory,
filesystem_item &fsi) const
-> api_error override;
[[nodiscard]] auto get_filesystem_item_and_file(const std::string &api_path,
api_file &f,
filesystem_item &fsi) const
-> api_error override;
[[nodiscard]] auto
get_filesystem_item_from_source_path(const std::string &source_path,
filesystem_item &fsi) const
-> api_error override;
[[nodiscard]] auto get_item_meta(const std::string &api_path,
api_meta_map &meta) const
-> api_error override;
[[nodiscard]] auto get_item_meta(const std::string &api_path,
const std::string &key,
std::string &value) const
-> api_error override;
[[nodiscard]] auto get_pinned_files() const
-> std::vector<std::string> override;
[[nodiscard]] auto get_provider_type() const -> provider_type override { [[nodiscard]] auto get_provider_type() const -> provider_type override {
return provider_type::sia; return provider_type::sia;
} }
[[nodiscard]] auto get_total_drive_space() const -> std::uint64_t override; [[nodiscard]] auto get_total_drive_space() const -> std::uint64_t override;
[[nodiscard]] auto get_total_item_count() const -> std::uint64_t override;
[[nodiscard]] auto get_used_drive_space() const -> std::uint64_t override;
[[nodiscard]] auto is_direct_only() const -> bool override { return false; } [[nodiscard]] auto is_direct_only() const -> bool override { return false; }
[[nodiscard]] auto is_directory(const std::string &api_path, [[nodiscard]] auto is_directory(const std::string &api_path,
@ -140,9 +96,6 @@ public:
[[nodiscard]] auto is_file(const std::string &api_path, bool &exists) const [[nodiscard]] auto is_file(const std::string &api_path, bool &exists) const
-> api_error override; -> api_error override;
[[nodiscard]] auto is_file_writeable(const std::string &api_path) const
-> bool override;
[[nodiscard]] auto is_online() const -> bool override; [[nodiscard]] auto is_online() const -> bool override;
[[nodiscard]] auto is_rename_supported() const -> bool override { [[nodiscard]] auto is_rename_supported() const -> bool override {
@ -155,39 +108,14 @@ public:
stop_type &stop_requested) stop_type &stop_requested)
-> api_error override; -> api_error override;
[[nodiscard]] auto remove_directory(const std::string &api_path)
-> api_error override;
[[nodiscard]] auto remove_file(const std::string &api_path)
-> api_error override;
[[nodiscard]] auto remove_item_meta(const std::string &api_path,
const std::string &key)
-> api_error 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)
-> api_error override; -> api_error override;
[[nodiscard]] auto set_item_meta(const std::string &api_path,
const std::string &key,
const std::string &value)
-> api_error override;
[[nodiscard]] auto set_item_meta(const std::string &api_path,
const api_meta_map &meta)
-> api_error override;
[[nodiscard]] auto start(api_item_added_callback api_item_added, [[nodiscard]] auto start(api_item_added_callback api_item_added,
i_file_manager *fm) -> bool override; i_file_manager *mgr) -> bool override;
void stop() override; void stop() override;
[[nodiscard]] auto upload_file(const std::string &api_path,
const std::string &source_path,
const std::string & /* encryption_token */,
stop_type &stop_requested)
-> api_error override;
}; };
} // namespace repertory } // namespace repertory

View File

@ -22,8 +22,8 @@
#ifndef INCLUDE_TYPES_REMOTE_HPP_ #ifndef INCLUDE_TYPES_REMOTE_HPP_
#define INCLUDE_TYPES_REMOTE_HPP_ #define INCLUDE_TYPES_REMOTE_HPP_
#define PACKET_SERVICE_FUSE std::uint32_t(1) #define PACKET_SERVICE_FUSE 1U
#define PACKET_SERVICE_WINFSP std::uint32_t(2) #define PACKET_SERVICE_WINFSP 2U
#ifdef _WIN32 #ifdef _WIN32
#define PACKET_SERVICE_FLAGS PACKET_SERVICE_WINFSP #define PACKET_SERVICE_FLAGS PACKET_SERVICE_WINFSP
@ -44,48 +44,51 @@ using group_id = std::uint32_t;
using user_id = std::uint32_t; using user_id = std::uint32_t;
enum class open_flags : std::uint32_t { enum class open_flags : std::uint32_t {
read_only = 0u, read_only = 0U,
write_only = 1u, write_only = 1U,
read_write = 2u, read_write = 2U,
create = 4u, create = 4U,
excl = 8u, excl = 8U,
no_ctty = 16u, no_ctty = 16U,
truncate = 32u, truncate = 32U,
append = 64u, append = 64U,
non_blocking = 128u, non_blocking = 128U,
sync = 256u, sync = 256U,
async = 512u, async = 512U,
directory = 1024u, directory = 1024U,
no_follow = 2048u, no_follow = 2048U,
clo_exec = 4096u, clo_exec = 4096U,
direct = 8192u, direct = 8192U,
no_atime = 16384u, no_atime = 16384U,
path = 32768u, path = 32768U,
temp_file = 65536u, temp_file = 65536U,
dsync = 131072u, dsync = 131072U,
}; };
inline auto operator|(const open_flags &a, const open_flags &b) -> open_flags { inline auto operator|(const open_flags &flag_1, const open_flags &flag_2)
-> open_flags {
using t = std::underlying_type_t<open_flags>; using t = std::underlying_type_t<open_flags>;
return static_cast<open_flags>(static_cast<t>(a) | static_cast<t>(b)); return static_cast<open_flags>(static_cast<t>(flag_1) |
static_cast<t>(flag_2));
} }
#ifdef __GNUG__ #ifdef __GNUG__
__attribute__((unused)) __attribute__((unused))
#endif #endif
inline auto inline auto
operator|=(open_flags &a, const open_flags &b) -> open_flags & { operator|=(open_flags &flag_1, const open_flags &flag_2) -> open_flags & {
a = a | b; flag_1 = flag_1 | flag_2;
return a; return flag_1;
} }
#ifdef __GNUG__ #ifdef __GNUG__
__attribute__((unused)) __attribute__((unused))
#endif #endif
inline auto inline auto
operator&(const open_flags &a, const open_flags &b) -> open_flags { operator&(const open_flags &flag_1, const open_flags &flag_2) -> open_flags {
using t = std::underlying_type_t<open_flags>; using t = std::underlying_type_t<open_flags>;
return static_cast<open_flags>(static_cast<t>(a) & static_cast<t>(b)); return static_cast<open_flags>(static_cast<t>(flag_1) &
static_cast<t>(flag_2));
} }
#pragma pack(1) #pragma pack(1)

View File

@ -29,7 +29,6 @@ const std::string META_BACKUP = "backup";
const std::string META_CHANGED = "changed"; const std::string META_CHANGED = "changed";
const std::string META_CREATION = "creation"; const std::string META_CREATION = "creation";
const std::string META_DIRECTORY = "directory"; const std::string META_DIRECTORY = "directory";
const std::string META_ENCRYPTION_TOKEN = "token";
const std::string META_GID = "gid"; const std::string META_GID = "gid";
const std::string META_ID = "id"; const std::string META_ID = "id";
const std::string META_KEY = "key"; const std::string META_KEY = "key";
@ -43,24 +42,10 @@ const std::string META_UID = "uid";
const std::string META_WRITTEN = "written"; const std::string META_WRITTEN = "written";
const std::vector<std::string> META_USED_NAMES = { const std::vector<std::string> META_USED_NAMES = {
META_ACCESSED, META_ACCESSED, META_ATTRIBUTES, META_BACKUP, META_CHANGED, META_CREATION,
META_ATTRIBUTES, META_DIRECTORY, META_GID, META_ID, META_KEY, META_MODE,
META_BACKUP, META_MODIFIED, META_OSXFLAGS, META_PINNED, META_SIZE, META_SOURCE,
META_CHANGED, META_UID, META_WRITTEN,
META_CREATION,
META_DIRECTORY,
META_ENCRYPTION_TOKEN,
META_GID,
META_ID,
META_KEY,
META_MODE,
META_MODIFIED,
META_OSXFLAGS,
META_PINNED,
META_SIZE,
META_SOURCE,
META_UID,
META_WRITTEN,
}; };
using api_meta_map = std::map<std::string, std::string>; using api_meta_map = std::map<std::string, std::string>;
@ -139,6 +124,12 @@ enum class exit_code : std::int32_t {
init_failed = -18, init_failed = -18,
}; };
enum http_error_codes : std::int32_t {
ok = 200,
multiple_choices = 300,
not_found = 404,
};
enum class lock_result { enum class lock_result {
success, success,
locked, locked,
@ -149,39 +140,37 @@ enum class provider_type : std::size_t {
sia, sia,
remote, remote,
s3, s3,
passthrough,
encrypt, encrypt,
unknown, unknown,
}; };
#ifdef _WIN32 #ifdef _WIN32
struct open_file_data { struct open_file_data {
void *directory_buffer = nullptr; void *directory_buffer{};
}; };
#else #else
using open_file_data = int; using open_file_data = int;
#endif #endif
struct api_file { struct api_file {
std::string api_path{}; std::string api_path;
std::string api_parent{}; std::string api_parent;
std::uint64_t accessed_date = 0u; std::uint64_t accessed_date{};
std::uint64_t changed_date = 0u; std::uint64_t changed_date{};
std::uint64_t creation_date = 0u; std::uint64_t creation_date{};
std::string encryption_token{}; std::uint64_t file_size{};
std::uint64_t file_size = 0u; std::string key;
std::string key{}; std::uint64_t modified_date{};
std::uint64_t modified_date = 0u; std::string source_path;
std::string source_path{};
}; };
struct directory_item { struct directory_item {
std::string api_path{}; std::string api_path;
std::string api_parent{}; std::string api_parent;
bool directory = false; bool directory{false};
std::uint64_t size = 0u; std::uint64_t size{};
api_meta_map meta{}; api_meta_map meta{};
bool resolved = false; bool resolved{false};
[[nodiscard]] static auto from_json(const json &item) -> directory_item { [[nodiscard]] static auto from_json(const json &item) -> directory_item {
directory_item ret{}; directory_item ret{};
@ -203,27 +192,22 @@ struct directory_item {
}; };
struct filesystem_item { struct filesystem_item {
std::string api_path{}; std::string api_path;
std::string api_parent{}; std::string api_parent;
bool directory = false; bool directory{false};
std::string encryption_token{}; std::uint64_t size{};
std::uint64_t size = 0u; std::string source_path;
std::string source_path{};
[[nodiscard]] auto is_encrypted() const -> bool {
return not encryption_token.empty();
}
}; };
struct host_config { struct host_config {
std::string agent_string{}; std::string agent_string;
std::string api_password{}; std::string api_password;
std::string api_user{}; std::string api_user;
std::uint16_t api_port = 0u; std::uint16_t api_port{};
std::string host_name_or_ip = "localhost"; std::string host_name_or_ip{"localhost"};
std::string path{}; std::string path{};
std::string protocol = "http"; std::string protocol{"http"};
std::uint32_t timeout_ms = 60000u; std::uint32_t timeout_ms{60000U};
auto operator==(const host_config &hc) const noexcept -> bool { auto operator==(const host_config &hc) const noexcept -> bool {
if (&hc != this) { if (&hc != this) {
@ -275,29 +259,25 @@ from_json(const json &j, host_config &hc) {
} }
struct http_range { struct http_range {
std::uint64_t begin = 0u; std::uint64_t begin;
std::uint64_t end = 0u; std::uint64_t end;
};
struct passthrough_config {
std::string location{};
std::string name{};
}; };
struct encrypt_config { struct encrypt_config {
std::string encryption_token{}; std::string encryption_token;
std::string path{}; std::string path;
}; };
struct s3_config { struct s3_config {
std::string access_key{}; std::string access_key;
std::string bucket{}; std::string bucket;
std::uint16_t cache_timeout_secs = 60u; std::uint16_t cache_timeout_secs{60U};
std::string encryption_token{}; std::string encryption_token;
std::string region = "any"; std::string region = "any";
std::string secret_key{}; std::string secret_key;
std::uint32_t timeout_ms = 60000u; std::uint32_t timeout_ms{60000U};
std::string url; std::string url;
bool use_path_style{false};
bool use_region_in_url{false}; bool use_region_in_url{false};
}; };

View File

@ -1,3 +1,4 @@
// NOLINTBEGIN
#ifndef _MACARON_BASE64_H_ #ifndef _MACARON_BASE64_H_
#define _MACARON_BASE64_H_ #define _MACARON_BASE64_H_
@ -25,11 +26,22 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunknown-warning-option"
#endif
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wconversion"
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Wuseless-cast"
#endif
#include <string> #include <string>
#include <vector> #include <vector>
namespace macaron { namespace macaron::Base64 {
namespace Base64 {
static std::string Encode(const char *data, const size_t &len) { static std::string Encode(const char *data, const size_t &len) {
static constexpr char sEncodingTable[] = { static constexpr char sEncodingTable[] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
@ -135,7 +147,16 @@ static std::string Encode(const char *data, const size_t &len) {
return out; return out;
} }
} // namespace Base64 } // namespace macaron::Base64
} // namespace macaron
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#endif /* _MACARON_BASE64_H_ */ #endif /* _MACARON_BASE64_H_ */
// NOLINTEND

View File

@ -34,8 +34,6 @@ static const option data_directory_option = {"-dd", "--data_directory"};
static const option encrypt_option = {"-en", "--encrypt"}; static const option encrypt_option = {"-en", "--encrypt"};
static const option drive_information_option = {"-di", "--drive_information"}; static const option drive_information_option = {"-di", "--drive_information"};
#if defined(REPERTORY_ENABLE_S3) #if defined(REPERTORY_ENABLE_S3)
static const option create_directory_option = {"-cd", "--create_directory"};
static const option list_objects_option = {"-lo", "--list_objects"};
static const option name_option = {"-na", "--name"}; static const option name_option = {"-na", "--name"};
static const option s3_option = {"-s3", "--s3"}; static const option s3_option = {"-s3", "--s3"};
#endif // defined(REPERTORY_ENABLE_S3) #endif // defined(REPERTORY_ENABLE_S3)
@ -67,8 +65,6 @@ static const std::vector<option> option_list = {
#if defined(REPERTORY_ENABLE_S3) #if defined(REPERTORY_ENABLE_S3)
s3_option, s3_option,
name_option, name_option,
create_directory_option,
list_objects_option,
#endif // defined(REPERTORY_ENABLE_S3) #endif // defined(REPERTORY_ENABLE_S3)
generate_config_option, generate_config_option,
get_option, get_option,

View File

@ -30,11 +30,15 @@ using key_type = std::array<unsigned char, 32U>;
class encrypting_reader final { class encrypting_reader final {
public: public:
encrypting_reader( encrypting_reader(const std::string &file_name,
const std::string &file_name, const std::string &source_path, const std::string &source_path, stop_type &stop_requested,
stop_type &stop_requested, const std::string &token, const std::string &token,
std::optional<std::string> relative_parent_path = std::nullopt, std::optional<std::string> relative_parent_path,
const size_t error_return = 0); std::size_t error_return = 0U);
encrypting_reader(const std::string &encrypted_file_path,
const std::string &source_path, stop_type &stop_requested,
const std::string &token, std::size_t error_return = 0U);
encrypting_reader( encrypting_reader(
const std::string &encrypted_file_path, const std::string &source_path, const std::string &encrypted_file_path, const std::string &source_path,
@ -42,9 +46,13 @@ public:
std::vector<std::array<unsigned char, std::vector<std::array<unsigned char,
crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>> crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>>
iv_list, iv_list,
const size_t error_return = 0); std::size_t error_return = 0U);
encrypting_reader(const encrypting_reader &r); encrypting_reader(const encrypting_reader &reader);
encrypting_reader(encrypting_reader &&) = delete;
auto operator=(const encrypting_reader &) -> encrypting_reader & = delete;
auto operator=(encrypting_reader &&) -> encrypting_reader & = delete;
~encrypting_reader(); ~encrypting_reader();
@ -62,11 +70,11 @@ private:
std::vector< std::vector<
std::array<unsigned char, crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>> std::array<unsigned char, crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>>
iv_list_; iv_list_;
std::size_t last_data_chunk_ = 0u; std::size_t last_data_chunk_{};
std::size_t last_data_chunk_size_ = 0u; std::size_t last_data_chunk_size_{};
std::uint64_t read_offset_ = 0u; std::uint64_t read_offset_{};
native_file_ptr source_file_; native_file_ptr source_file_;
std::uint64_t total_size_ = 0u; std::uint64_t total_size_{};
private: private:
static const std::size_t header_size_; static const std::size_t header_size_;

View File

@ -38,11 +38,13 @@ void calculate_allocation_size(bool directory, std::uint64_t file_size,
template <typename t> template <typename t>
[[nodiscard]] auto collection_excludes(t collection, [[nodiscard]] auto collection_excludes(t collection,
const typename t::value_type &v) -> bool; const typename t::value_type &val)
-> bool;
template <typename t> template <typename t>
[[nodiscard]] auto collection_includes(t collection, [[nodiscard]] auto collection_includes(t collection,
const typename t::value_type &v) -> bool; const typename t::value_type &val)
-> bool;
[[nodiscard]] auto compare_version_strings(std::string version1, [[nodiscard]] auto compare_version_strings(std::string version1,
std::string version2) -> int; std::string version2) -> int;
@ -53,7 +55,8 @@ template <typename t>
[[nodiscard]] auto create_uuid_string() -> std::string; [[nodiscard]] auto create_uuid_string() -> std::string;
[[nodiscard]] auto create_volume_label(const provider_type &pt) -> std::string; [[nodiscard]] auto create_volume_label(const provider_type &prov)
-> std::string;
template <typename t> template <typename t>
[[nodiscard]] auto divide_with_ceiling(const t &n, const t &d) -> t; [[nodiscard]] auto divide_with_ceiling(const t &n, const t &d) -> t;
@ -66,7 +69,7 @@ template <typename t>
-> std::string; -> std::string;
template <typename t> template <typename t>
[[nodiscard]] auto from_hex_string(const std::string &str, t &v) -> bool; [[nodiscard]] auto from_hex_string(const std::string &str, t &val) -> bool;
[[nodiscard]] auto generate_random_string(std::uint16_t length) -> std::string; [[nodiscard]] auto generate_random_string(std::uint16_t length) -> std::string;
@ -77,7 +80,7 @@ template <typename t>
[[nodiscard]] auto get_file_time_now() -> std::uint64_t; [[nodiscard]] auto get_file_time_now() -> std::uint64_t;
void get_local_time_now(struct tm &localTime); void get_local_time_now(struct tm &local_time);
[[nodiscard]] auto get_next_available_port(std::uint16_t first_port, [[nodiscard]] auto get_next_available_port(std::uint16_t first_port,
std::uint16_t &available_port) std::uint16_t &available_port)
@ -85,11 +88,12 @@ void get_local_time_now(struct tm &localTime);
[[nodiscard]] auto get_time_now() -> std::uint64_t; [[nodiscard]] auto get_time_now() -> std::uint64_t;
template <typename t> template <typename data_type>
[[nodiscard]] auto random_between(const t &begin, const t &end) -> t; [[nodiscard]] auto random_between(const data_type &begin, const data_type &end)
-> data_type;
template <typename t> template <typename t>
void remove_element_from(t &v, const typename t::value_type &value); void remove_element_from(t &collection, const typename t::value_type &val);
[[nodiscard]] auto reset_curl(CURL *curl_handle) -> CURL *; [[nodiscard]] auto reset_curl(CURL *curl_handle) -> CURL *;
@ -97,28 +101,30 @@ void remove_element_from(t &v, const typename t::value_type &value);
-> bool; -> bool;
void spin_wait_for_mutex(std::function<bool()> complete, void spin_wait_for_mutex(std::function<bool()> complete,
std::condition_variable &cv, std::mutex &mtx, std::condition_variable &cond, std::mutex &mtx,
const std::string &txt = ""); const std::string &text = "");
void spin_wait_for_mutex(bool &complete, std::condition_variable &cv, void spin_wait_for_mutex(bool &complete, std::condition_variable &cond,
std::mutex &mtx, const std::string &txt = ""); std::mutex &mtx, const std::string &text = "");
template <typename t> template <typename collection_t>
[[nodiscard]] auto to_hex_string(const t &v) -> std::string; [[nodiscard]] auto to_hex_string(const collection_t &collection) -> std::string;
// template implementations // template implementations
template <typename t> template <typename t>
[[nodiscard]] auto collection_excludes(t collection, [[nodiscard]] auto collection_excludes(t collection,
const typename t::value_type &v) const typename t::value_type &val)
-> bool { -> bool {
return std::find(collection.begin(), collection.end(), v) == collection.end(); return std::find(collection.begin(), collection.end(), val) ==
collection.end();
} }
template <typename t> template <typename t>
[[nodiscard]] auto collection_includes(t collection, [[nodiscard]] auto collection_includes(t collection,
const typename t::value_type &v) const typename t::value_type &val)
-> bool { -> bool {
return std::find(collection.begin(), collection.end(), v) != collection.end(); return std::find(collection.begin(), collection.end(), val) !=
collection.end();
} }
template <typename t> template <typename t>
@ -127,12 +133,14 @@ template <typename t>
} }
template <typename t> template <typename t>
[[nodiscard]] auto from_hex_string(const std::string &str, t &v) -> bool { [[nodiscard]] auto from_hex_string(const std::string &str, t &val) -> bool {
v.clear(); static constexpr const auto base16 = 16;
if (not(str.length() % 2u)) {
for (std::size_t i = 0u; i < str.length(); i += 2u) { val.clear();
v.emplace_back(static_cast<typename t::value_type>( if (not(str.length() % 2U)) {
strtol(str.substr(i, 2u).c_str(), nullptr, 16))); for (std::size_t i = 0U; i < str.length(); i += 2U) {
val.emplace_back(static_cast<typename t::value_type>(
strtol(str.substr(i, 2U).c_str(), nullptr, base16)));
} }
return true; return true;
} }
@ -140,33 +148,33 @@ template <typename t>
return false; return false;
} }
template <typename t> template <typename data_type>
[[nodiscard]] auto random_between(const t &begin, const t &end) -> t { [[nodiscard]] auto random_between(const data_type &begin, const data_type &end)
srand(static_cast<unsigned int>(get_time_now())); -> data_type {
return begin + rand() % ((end + 1) - begin); return begin + repertory_rand<data_type>() % ((end + 1) - begin);
} }
template <typename t> template <typename collection_t>
void remove_element_from(t &v, const typename t::value_type &value) { void remove_element_from(collection_t &collection,
v.erase(std::remove(v.begin(), v.end(), value), v.end()); const typename collection_t::value_type &value) {
collection.erase(std::remove(collection.begin(), collection.end(), value),
collection.end());
} }
template <typename t> template <typename collection_t>
[[nodiscard]] auto to_hex_string(const t &value) -> std::string { [[nodiscard]] auto to_hex_string(const collection_t &collection)
std::string ret{}; -> std::string {
static_assert(sizeof(typename collection_t::value_type) == 1U,
"value_type must be 1 byte in size");
static constexpr const auto mask = 0xFF;
std::array<char, 3> h{}; std::stringstream stream;
for (const auto &num : value) { for (const auto &val : collection) {
#ifdef _WIN32 stream << std::setfill('0') << std::setw(2) << std::hex
sprintf_s(h.data(), h.size() - 1U, "%x", static_cast<std::uint8_t>(num)); << (static_cast<std::uint32_t>(val) & mask);
#else
sprintf(h.data(), "%x", static_cast<std::uint8_t>(num));
#endif
ret += (strlen(h.data()) == 1) ? std::string("0") + h.data() : h.data();
} }
return ret; return stream.str();
} }
} // namespace repertory::utils } // namespace repertory::utils

View File

@ -1,331 +0,0 @@
/*
** MODIFIED BY <scott.e.graves@gmail.com>
** - Modifications for C++11
** - Memory leak avoidance
**
** OSSP uuid - Universally Unique Identifier
** Copyright (c) 2004-2008 Ralf S. Engelschall <rse@engelschall.com>
** Copyright (c) 2004-2008 The OSSP Project <http://www.ossp.org/>
**
** This file is part of OSSP uuid, a library for the generation
** of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/
**
** Permission to use, copy, modify, and distribute this software for
** any purpose with or without fee is hereby granted, provided that
** the above copyright notice and this permission notice appear in all
** copies.
**
** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
** IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
** USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
** OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
** SUCH DAMAGE.
**
** uuid++.hh: library C++ API definition
*/
#if __linux__
#ifndef __UUIDXX_HH__
#define __UUIDXX_HH__
#include <cstdarg>
#include <string>
#include <exception>
#include <vector>
#include <uuid.h>
namespace repertory {
/* UUID exception class */
class uuid_error_t : public virtual std::exception {
public:
uuid_error_t() : rc(UUID_RC_OK){};
explicit uuid_error_t(const uuid_rc_t &code) : rc(code) {}
private:
const uuid_rc_t rc;
public:
uuid_rc_t code() const { return rc; };
const char *what() const noexcept override {
static std::string ret;
if (ret.empty()) {
auto *p = uuid_error(rc);
ret = std::string(p, strlen(p));
free(p);
}
return ret.c_str();
}
};
/* UUID object class */
class uuid {
public:
/* construction & destruction */
/* standard constructor */
uuid() {
uuid_rc_t rc;
if ((rc = uuid_create(&ctx)) != UUID_RC_OK)
throw uuid_error_t(rc);
}
/* copy constructor */
uuid(const uuid &obj) {
/* Notice: the copy constructor is the same as the assignment
operator (with the object as the argument) below, except that
(1) no check for self-assignment is required, (2) no existing
internals have to be destroyed and (3) no return value is given back. */
uuid_rc_t rc;
if ((rc = uuid_clone(obj.ctx, &ctx)) != UUID_RC_OK)
throw uuid_error_t(rc);
}
/* import constructor */
explicit uuid(const uuid_t *obj) {
uuid_rc_t rc;
if (obj == nullptr)
throw uuid_error_t(UUID_RC_ARG);
if ((rc = uuid_clone(obj, &ctx)) != UUID_RC_OK)
throw uuid_error_t(rc);
}
/* import constructor */
explicit uuid(const std::vector<void *> &bin) {
uuid_rc_t rc;
if (bin.empty())
throw uuid_error_t(UUID_RC_ARG);
if ((rc = uuid_create(&ctx)) != UUID_RC_OK)
throw uuid_error_t(rc);
import(bin);
}
/* import constructor */
explicit uuid(const std::string &str) {
uuid_rc_t rc;
if (str.empty())
throw uuid_error_t(UUID_RC_ARG);
if ((rc = uuid_create(&ctx)) != UUID_RC_OK)
throw uuid_error_t(rc);
import(str);
}
/* move constructor */
uuid(uuid &&obj) noexcept : ctx(obj.ctx) {}
/* destructor */
~uuid() { uuid_destroy(ctx); }
private:
uuid_t *ctx = nullptr;
public:
/* copying & cloning */
/* copy assignment operator */
uuid &operator=(const uuid &obj) {
uuid_rc_t rc;
if (this != &obj) {
if ((rc = uuid_destroy(ctx)) != UUID_RC_OK)
throw uuid_error_t(rc);
if ((rc = uuid_clone(obj.ctx, &ctx)) != UUID_RC_OK)
throw uuid_error_t(rc);
}
return *this;
}
/* move assignment operator */
uuid &operator=(uuid &&obj) {
if (this != &obj) {
ctx = obj.ctx;
}
return *this;
}
/* import assignment operator */
uuid &operator=(const uuid_t *obj) {
uuid_rc_t rc;
if (obj == nullptr)
throw uuid_error_t(UUID_RC_ARG);
if ((rc = uuid_clone(obj, &ctx)) != UUID_RC_OK)
throw uuid_error_t(rc);
return *this;
}
/* import assignment operator */
uuid &operator=(const std::vector<void *> &bin) {
if (bin.empty())
throw uuid_error_t(UUID_RC_ARG);
import(bin);
return *this;
}
/* import assignment operator */
uuid &operator=(const std::string &str) {
if (str.empty())
throw uuid_error_t(UUID_RC_ARG);
import(str);
return *this;
}
/* regular method */
uuid clone() { return uuid(*this); }
/* content generation */
/* regular method */
void load(const std::string &name) {
uuid_rc_t rc;
if (name.empty())
throw uuid_error_t(UUID_RC_ARG);
if ((rc = uuid_load(ctx, &name[0])) != UUID_RC_OK)
throw uuid_error_t(rc);
}
/* regular method */
void make(unsigned int mode, ...) {
uuid_rc_t rc;
va_list ap;
va_start(ap, mode);
if ((mode & UUID_MAKE_V3) || (mode & UUID_MAKE_V5)) {
const uuid *ns = (const uuid *)va_arg(ap, const uuid *);
const char *name = (const char *)va_arg(ap, char *);
if (ns == nullptr || name == nullptr)
throw uuid_error_t(UUID_RC_ARG);
rc = uuid_make(ctx, mode, ns->ctx, name);
} else
rc = uuid_make(ctx, mode);
va_end(ap);
if (rc != UUID_RC_OK)
throw uuid_error_t(rc);
}
/* content comparison */
/* regular method */
int isnil() {
uuid_rc_t rc;
int rv;
if ((rc = uuid_isnil(ctx, &rv)) != UUID_RC_OK)
throw uuid_error_t(rc);
return rv;
}
/* regular method */
int compare(const uuid &obj) {
uuid_rc_t rc;
int rv;
if ((rc = uuid_compare(ctx, obj.ctx, &rv)) != UUID_RC_OK)
throw uuid_error_t(rc);
return rv;
}
/* comparison operator */
int operator==(const uuid &obj) { return (compare(obj) == 0); }
/* comparison operator */
int operator!=(const uuid &obj) { return (compare(obj) != 0); }
/* comparison operator */
int operator<(const uuid &obj) { return (compare(obj) < 0); }
/* comparison operator */
int operator<=(const uuid &obj) { return (compare(obj) <= 0); }
/* comparison operator */
int operator>(const uuid &obj) { return (compare(obj) > 0); }
/* comparison operator */
int operator>=(const uuid &obj) { return (compare(obj) >= 0); }
/* content importing & exporting */
/* regular method */
void import(const std::vector<void *> &bin) {
uuid_rc_t rc;
if ((rc = uuid_import(ctx, UUID_FMT_BIN, &bin[0], UUID_LEN_BIN)) !=
UUID_RC_OK)
throw uuid_error_t(rc);
}
/* regular method */
void import(const std::string &str) {
uuid_rc_t rc;
if ((rc = uuid_import(ctx, UUID_FMT_STR, &str[0], UUID_LEN_STR)) !=
UUID_RC_OK)
if ((rc = uuid_import(ctx, UUID_FMT_SIV, &str[0], UUID_LEN_SIV)) !=
UUID_RC_OK)
throw uuid_error_t(rc);
}
/* regular method */
std::vector<void *> binary() {
uuid_rc_t rc;
void *bin = nullptr;
if ((rc = uuid_export(ctx, UUID_FMT_BIN, &bin, nullptr)) != UUID_RC_OK)
throw uuid_error_t(rc);
std::vector<void *> data;
data.resize(UUID_LEN_BIN);
memcpy(&data[0], bin, UUID_LEN_BIN);
free(bin);
return data;
}
/* regular method */
std::string string() {
uuid_rc_t rc;
char *str = nullptr;
if ((rc = uuid_export(ctx, UUID_FMT_STR, (void **)&str, nullptr)) !=
UUID_RC_OK)
throw uuid_error_t(rc);
std::string data;
data.resize(UUID_LEN_STR + 1);
memcpy(&data[0], str, UUID_LEN_STR);
free(str);
return &data[0];
}
/* regular method */
std::string integer() {
uuid_rc_t rc;
char *str = nullptr;
if ((rc = uuid_export(ctx, UUID_FMT_SIV, (void **)&str, nullptr)) !=
UUID_RC_OK)
throw uuid_error_t(rc);
std::string data;
data.resize(UUID_LEN_SIV + 1);
memcpy(&data[0], str, UUID_LEN_SIV);
free(str);
return &data[0];
}
/* regular method */
std::string summary() {
uuid_rc_t rc;
char *txt = nullptr;
if ((rc = uuid_export(ctx, UUID_FMT_TXT, (void **)&txt, nullptr)) !=
UUID_RC_OK)
throw uuid_error_t(rc);
std::string data(txt, strlen(txt));
free(txt);
return data;
}
/* regular method */
unsigned long version() { return uuid_version(); }
};
} // namespace repertory
#endif /* __UUIDXX_HH__ */
#endif

View File

@ -1,115 +0,0 @@
@echo off
setlocal
setlocal enabledelayedexpansion
set SIGNING_FOLDER=%1
set BINARY_FOLDER=%2
set SOURCE_FOLDER=%3
set OUTPUT_FOLDER=%4
set PATH=%~dp0%..\bin;!PATH!
if "%SIGNING_FOLDER%" == "" (
call :EXIT_SCRIPT "'SIGNING_FOLDER' is not set (arg1)"
)
if "%BINARY_FOLDER%" == "" (
call :EXIT_SCRIPT "'BINARY_FOLDER' is not set (arg2)"
)
if "%SOURCE_FOLDER%" == "" (
call :EXIT_SCRIPT "'SOURCE_FOLDER' is not set (arg3)"
)
if "%OUTPUT_FOLDER%" == "" (
call :EXIT_SCRIPT "'OUTPUT_FOLDER' is not set (arg4)"
)
call :NORMALIZE "%SIGNING_FOLDER%"
set SIGNING_FOLDER=%RETVAL%
call :NORMALIZE "%BINARY_FOLDER%"
set BINARY_FOLDER=%RETVAL%
call :NORMALIZE "%SOURCE_FOLDER%"
set SOURCE_FOLDER=%RETVAL%
set BUILD_ARCH=Win64
set OPENSSL_BIN="c:\OpenSSL-%BUILD_ARCH%\bin\openssl.exe"
if NOT EXIST %OPENSSL_BIN% (
set OPENSSL_BIN="c:\Program Files\OpenSSL-%BUILD_ARCH%\bin\openssl.exe"
set REPERTORY_OPENSSL_ROOT="c:\Program Files\OpenSSL-%BUILD_ARCH%"
)
pushd "%SOURCE_FOLDER%"
for /F "tokens=*" %%f in ('git rev-parse --short HEAD') do (set GIT_REV=%%f)
for /F "tokens=*" %%f in ('git branch --show-current') do (set GIT_BRANCH=%%f)
for /F "tokens=*" %%f in ('grep set(REPERTORY_MAJOR .\CMakeLists.txt ^| sed "s/)//g" ^| awk "{print $2}"') do (set REPERTORY_VERSION=%%f)
for /F "tokens=*" %%f in ('grep set(REPERTORY_MINOR .\CMakeLists.txt ^| sed "s/)//g" ^| awk "{print $2}"') do (set REPERTORY_VERSION=%REPERTORY_VERSION%.%%f)
for /F "tokens=*" %%f in ('grep set(REPERTORY_REV .\CMakeLists.txt ^| sed "s/)//g" ^| awk "{print $2}"') do (set REPERTORY_VERSION=%REPERTORY_VERSION%.%%f)
for /F "tokens=*" %%f in ('grep set(REPERTORY_RELEASE_ITER .\CMakeLists.txt ^| sed "s/)//g" ^| awk "{print $2}"') do (set REPERTORY_VERSION=%REPERTORY_VERSION%-%%f)
popd
if "%GIT_BRANCH%" == "development" (
set RELEASE_FOLDER=nightly
) else (
set RELEASE_FOLDER=%REPERTORY_RELEASE_ITER%
)
call :NORMALIZE "%OUTPUT_FOLDER%\!RELEASE_FOLDER!"
set OUTPUT_FOLDER=%RETVAL%
set OUT_FILE=repertory_%REPERTORY_VERSION%_%GIT_REV%_windows_amd64.zip
set OUT_ZIP=%BINARY_FOLDER%\%OUT_FILE%
set FILE_LIST=repertory.exe repertory.exe.sha256 repertory.exe.sig winfsp-x64.dll winfsp-x64.dll.sha256 winfsp-x64.dll.sig cacert.pem cacert.pem.sha256 cacert.pem.sig
pushd "%BINARY_FOLDER%"
call :CLEANUP
call :CREATE_HASH "%BINARY_FOLDER%\repertory.exe"
call :CREATE_HASH "%BINARY_FOLDER%\winfsp-x64.dll"
call :CREATE_HASH "%BINARY_FOLDER%\cacert.pem"
(7za u "%OUT_FILE%" %FILE_LIST%) || (7z u "%OUT_FILE%" %FILE_LIST%) || (call :EXIT_SCRIPT "Create repertory zip failed")
call :CREATE_HASH "%OUT_FILE%"
copy /y "%OUT_ZIP%" "%OUTPUT_FOLDER%" || call :EXIT_SCRIPT "Copy %OUT_ZIP% to %OUTPUT_FOLDER% failed"
copy /y "%OUT_ZIP%.sha256" "%OUTPUT_FOLDER%" || call :EXIT_SCRIPT "Copy %OUT_ZIP%.sha256 to %OUTPUT_FOLDER% failed"
copy /y "%OUT_ZIP%.sig" "%OUTPUT_FOLDER%" || call :EXIT_SCRIPT "Copy %OUT_ZIP%.sig to %OUTPUT_FOLDER% failed"
call :CLEANUP
popd
goto :END
:CREATE_HASH
call :NORMALIZE %1
set HASH_FILE=%RETVAL%
(%OPENSSL_BIN% dgst -sha256 -sign "%SIGNING_FOLDER%\blockstorage_dev_private.pem" -out "%HASH_FILE%.sig" "%HASH_FILE%") || (call :EXIT_SCRIPT "Create %HASH_FILE% signature failed")
(%OPENSSL_BIN% dgst -sha256 -verify "%SIGNING_FOLDER%\blockstorage_dev_public.pem" -signature "%HASH_FILE%.sig" "%HASH_FILE%") || (call :EXIT_SCRIPT "Verify %HASH_FILE% signature failed")
((certutil -hashfile "%HASH_FILE%" SHA256 | sed -e "1d" -e "$d" -e "s/\ //g") > "%HASH_FILE%.sha256") || (call :EXIT_SCRIPT "Create %HASH_FILE% sha-256 failed")
EXIT /B
:CLEANUP
del /q "%OUT_ZIP%" 1>NUL 2>&1
del /q "%OUT_ZIP%.sha256" 1>NUL 2>&1
del /q "%OUT_ZIP%.sig" 1>NUL 2>&1
del /q "%BINARY_FOLDER%\cacert.pem.sha256" 1>NUL 2>&1
del /q "%BINARY_FOLDER%\cacert.pem.sig" 1>NUL 2>&1
del /q "%BINARY_FOLDER%\repertory.exe.sha256" 1>NUL 2>&1
del /q "%BINARY_FOLDER%\repertory.exe.sig" 1>NUL 2>&1
del /q "%BINARY_FOLDER%\winfsp-x64.dll.sha256" 1>NUL 2>&1
del /q "%BINARY_FOLDER%\winfsp-x64.dll.sig" 1>NUL 2>&1
EXIT /B
:NORMALIZE
SET RETVAL=%~f1
exit /B
:EXIT_SCRIPT
echo %1
exit 1
:END
echo Done

View File

@ -1,44 +0,0 @@
@echo off
set MSVC_BUILD_TYPE=%1
set BUILD_CLEAN=%2
if "%MSVC_BUILD_TYPE%" == "" (
echo "Build type not set"
exit 1
)
if "%MSVC_BUILD_TYPE%" == "Debug" (
set BUILD_FOLDER=debug
) else (
if "%MSVC_BUILD_TYPE%" == "Release" (
set BUILD_FOLDER=release
) else (
set BUILD_FOLDER=%MSVC_BUILD_TYPE%
)
set MSVC_BUILD_TYPE=Release
)
if EXIST "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat" (
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat"
) else (
if EXIST "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Auxiliary\Build\vcvars64.bat" (
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Auxiliary\Build\vcvars64.bat"
)
)
pushd "%~dp0%"
md ..\build2\%BUILD_FOLDER%
del /q ..\build2\%BUILD_FOLDER%\librepertory.lib
del /q ..\build2\%BUILD_FOLDER%\repertory.exe
del /q ..\build2\%BUILD_FOLDER%\unittests.exe
pushd "..\build2\%BUILD_FOLDER%"
cmake ..\.. -G "NMake Makefiles" -DREPERTORY_ENABLE_S3_TESTING=ON -DREPERTORY_ENABLE_S3=ON -DCMAKE_BUILD_TYPE=%MSVC_BUILD_TYPE% || exit 1
copy /y compile_commands.json ..
if "%BUILD_CLEAN%" == "clean" (
nmake clean || exit 1
)
nmake || exit 1
popd
popd

View File

@ -29,19 +29,16 @@
#include "utils/utils.hpp" #include "utils/utils.hpp"
namespace repertory { namespace repertory {
app_config::app_config(const provider_type &pt, app_config::app_config(const provider_type &prov,
const std::string &data_directory) const std::string &data_directory)
: pt_(pt), : prov_(prov),
api_auth_(utils::generate_random_string(48u)), api_auth_(utils::generate_random_string(48U)),
api_port_(default_rpc_port(pt)), api_port_(default_rpc_port(prov)),
api_user_("repertory"), api_user_("repertory"),
config_changed_(false), config_changed_(false),
data_directory_( data_directory_(data_directory.empty()
data_directory.empty() ? default_data_directory(pt) ? default_data_directory(prov)
: ((pt == provider_type::remote) || (pt == provider_type::s3)) : utils::path::absolute(data_directory)),
? utils::path::absolute(data_directory)
: utils::path::absolute(utils::path::combine(
data_directory, {get_provider_name(pt)}))),
download_timeout_secs_(30), download_timeout_secs_(30),
enable_chunk_downloader_timeout_(true), enable_chunk_downloader_timeout_(true),
enable_comm_duration_events_(false), enable_comm_duration_events_(false),
@ -58,7 +55,7 @@ app_config::app_config(const provider_type &pt,
is_remote_mount_(false), is_remote_mount_(false),
low_freq_interval_secs_(60 * 60), low_freq_interval_secs_(60 * 60),
max_cache_size_bytes_(20 * 1024 * 1024 * 1024ULL), max_cache_size_bytes_(20 * 1024 * 1024 * 1024ULL),
max_upload_count_(5u), max_upload_count_(5U),
min_download_timeout_secs_(5), min_download_timeout_secs_(5),
online_check_retry_secs_(60), online_check_retry_secs_(60),
orphaned_file_retention_days_(15), orphaned_file_retention_days_(15),
@ -68,9 +65,9 @@ app_config::app_config(const provider_type &pt,
remote_client_pool_size_(10), remote_client_pool_size_(10),
remote_host_name_or_ip_(""), remote_host_name_or_ip_(""),
remote_max_connections_(20), remote_max_connections_(20),
remote_port_((pt == provider_type::sia) ? 20000 remote_port_((prov == provider_type::sia) ? 20000
: (pt == provider_type::s3) ? 20001 : (prov == provider_type::s3) ? 20001
: (pt == provider_type::encrypt) ? 20002 : (prov == provider_type::encrypt) ? 20002
: 20003), : 20003),
remote_receive_timeout_secs_(120), remote_receive_timeout_secs_(120),
remote_send_timeout_secs_(30), remote_send_timeout_secs_(30),
@ -80,18 +77,21 @@ app_config::app_config(const provider_type &pt,
cache_directory_ = utils::path::combine(data_directory_, {"cache"}); cache_directory_ = utils::path::combine(data_directory_, {"cache"});
log_directory_ = utils::path::combine(data_directory_, {"logs"}); log_directory_ = utils::path::combine(data_directory_, {"logs"});
hc_.agent_string = default_agent_name(pt_); hc_.agent_string = default_agent_name(prov_);
hc_.api_password = get_provider_api_password(pt_); hc_.api_password = get_provider_api_password(prov_);
hc_.api_port = default_api_port(pt_); hc_.api_port = default_api_port(prov_);
if (not utils::file::create_full_directory_path(data_directory_)) if (not utils::file::create_full_directory_path(data_directory_)) {
throw startup_exception("unable to create: " + data_directory_); throw startup_exception("unable to create: " + data_directory_);
}
if (not utils::file::create_full_directory_path(cache_directory_)) if (not utils::file::create_full_directory_path(cache_directory_)) {
throw startup_exception("unable to create: " + cache_directory_); throw startup_exception("unable to create: " + cache_directory_);
}
if (not utils::file::create_full_directory_path(log_directory_)) if (not utils::file::create_full_directory_path(log_directory_)) {
throw startup_exception("unable to create: " + log_directory_); throw startup_exception("unable to create: " + log_directory_);
}
if (not load()) { if (not load()) {
save(); save();
@ -102,48 +102,51 @@ auto app_config::get_config_file_path() const -> std::string {
return utils::path::combine(data_directory_, {"config.json"}); return utils::path::combine(data_directory_, {"config.json"});
} }
auto app_config::default_agent_name(const provider_type &pt) -> std::string { auto app_config::default_agent_name(const provider_type &prov) -> std::string {
static const std::array<std::string, static const std::array<std::string,
static_cast<std::size_t>(provider_type::unknown)> static_cast<std::size_t>(provider_type::unknown)>
PROVIDER_AGENT_NAMES = {"Sia-Agent", "", "", "", ""}; PROVIDER_AGENT_NAMES = {"Sia-Agent", "", "", ""};
return PROVIDER_AGENT_NAMES[static_cast<std::size_t>(pt)]; return PROVIDER_AGENT_NAMES[static_cast<std::size_t>(prov)];
} }
auto app_config::default_api_port(const provider_type &pt) -> std::uint16_t { auto app_config::default_api_port(const provider_type &prov) -> std::uint16_t {
static const std::array<std::uint16_t, static const std::array<std::uint16_t,
static_cast<std::size_t>(provider_type::unknown)> static_cast<std::size_t>(provider_type::unknown)>
PROVIDER_API_PORTS = {9980u, 0u, 0u, 0u, 0u}; PROVIDER_API_PORTS = {9980U, 0U, 0U, 0U};
return PROVIDER_API_PORTS[static_cast<std::size_t>(pt)]; return PROVIDER_API_PORTS[static_cast<std::size_t>(prov)];
} }
auto app_config::default_data_directory(const provider_type &pt) auto app_config::default_data_directory(const provider_type &prov)
-> std::string { -> std::string {
#ifdef _WIN32 #ifdef _WIN32
auto data_directory = utils::path::combine( auto data_directory = utils::path::combine(
utils::get_local_app_data_directory(), utils::get_local_app_data_directory(),
{REPERTORY_DATA_NAME, app_config::get_provider_name(pt)}); {REPERTORY_DATA_NAME, app_config::get_provider_name(prov)});
#else #else
#ifdef __APPLE__ #ifdef __APPLE__
auto data_directory = utils::path::resolve( auto data_directory = utils::path::resolve(
std::string("~/Library/Application Support/") + REPERTORY_DATA_NAME + std::string("~/Library/Application Support/") + REPERTORY_DATA_NAME +
'/' + app_config::get_provider_name(pt)); '/' + app_config::get_provider_name(prov));
#else #else
auto data_directory = auto data_directory =
utils::path::resolve(std::string("~/.local/") + REPERTORY_DATA_NAME + utils::path::resolve(std::string("~/.local/") + REPERTORY_DATA_NAME +
'/' + app_config::get_provider_name(pt)); '/' + app_config::get_provider_name(prov));
#endif #endif
#endif #endif
return data_directory; return data_directory;
} }
auto app_config::default_rpc_port(const provider_type &pt) -> std::uint16_t { auto app_config::default_rpc_port(const provider_type &prov) -> std::uint16_t {
static const std::array<std::uint16_t, static const std::array<std::uint16_t,
static_cast<std::size_t>(provider_type::unknown)> static_cast<std::size_t>(provider_type::unknown)>
PROVIDER_RPC_PORTS = { PROVIDER_RPC_PORTS = {
11101u, 11102u, 11103u, 11104u, 11105u, 11101U,
11102U,
11103U,
11104U,
}; };
return PROVIDER_RPC_PORTS[static_cast<std::size_t>(pt)]; return PROVIDER_RPC_PORTS[static_cast<std::size_t>(prov)];
} }
auto app_config::get_json() const -> json { auto app_config::get_json() const -> json {
@ -209,11 +212,12 @@ auto app_config::get_json() const -> json {
{"SecretKey", s3_config_.secret_key}, {"SecretKey", s3_config_.secret_key},
{"TimeoutMs", s3_config_.timeout_ms}, {"TimeoutMs", s3_config_.timeout_ms},
{"URL", s3_config_.url}, {"URL", s3_config_.url},
{"UsePathStyle", s3_config_.use_path_style},
{"UseRegionInURL", s3_config_.use_region_in_url}, {"UseRegionInURL", s3_config_.use_region_in_url},
}}, }},
{"Version", version_}}; {"Version", version_}};
if (pt_ == provider_type::encrypt) { if (prov_ == provider_type::encrypt) {
ret.erase("ChunkDownloaderTimeoutSeconds"); ret.erase("ChunkDownloaderTimeoutSeconds");
ret.erase("EnableChunkDownloaderTimeout"); ret.erase("EnableChunkDownloaderTimeout");
ret.erase("EnableMaxCacheSize"); ret.erase("EnableMaxCacheSize");
@ -229,13 +233,13 @@ auto app_config::get_json() const -> json {
ret.erase("RetryReadCount"); ret.erase("RetryReadCount");
ret.erase("RingBufferFileSize"); ret.erase("RingBufferFileSize");
ret.erase("S3Config"); ret.erase("S3Config");
} else if (pt_ == provider_type::s3) { } else if (prov_ == provider_type::s3) {
ret.erase("EncryptConfig"); ret.erase("EncryptConfig");
ret.erase("HostConfig"); ret.erase("HostConfig");
} else if (pt_ == provider_type::sia) { } else if (prov_ == provider_type::sia) {
ret.erase("EncryptConfig"); ret.erase("EncryptConfig");
ret.erase("S3Config"); ret.erase("S3Config");
} else if (pt_ == provider_type::remote) { } else if (prov_ == provider_type::remote) {
ret.erase("ChunkDownloaderTimeoutSeconds"); ret.erase("ChunkDownloaderTimeoutSeconds");
ret.erase("EnableChunkDownloaderTimeout"); ret.erase("EnableChunkDownloaderTimeout");
ret.erase("EnableChunkDownloaderTimeout"); ret.erase("EnableChunkDownloaderTimeout");
@ -261,50 +265,56 @@ auto app_config::get_json() const -> json {
auto app_config::get_max_cache_size_bytes() const -> std::uint64_t { auto app_config::get_max_cache_size_bytes() const -> std::uint64_t {
const auto max_space = const auto max_space =
std::max(static_cast<std::uint64_t>(100ull * 1024ull * 1024ull), std::max(static_cast<std::uint64_t>(100ULL * 1024ULL * 1024ULL),
max_cache_size_bytes_); max_cache_size_bytes_);
return std::min(utils::file::get_free_drive_space(get_cache_directory()), return std::min(utils::file::get_free_drive_space(get_cache_directory()),
max_space); max_space);
} }
auto app_config::get_provider_api_password(const provider_type &pt) auto app_config::get_provider_api_password(const provider_type &prov)
-> std::string { -> std::string {
#ifdef _WIN32 #ifdef _WIN32
auto api_file = auto api_file =
utils::path::combine(utils::get_local_app_data_directory(), utils::path::combine(utils::get_local_app_data_directory(),
{get_provider_display_name(pt), "apipassword"}); {get_provider_display_name(prov), "apipassword"});
#else #else
#ifdef __APPLE__ #ifdef __APPLE__
auto api_file = auto api_file =
utils::path::combine(utils::path::resolve("~"), utils::path::combine(utils::path::resolve("~"),
{"/Library/Application Support", {"/Library/Application Support",
get_provider_display_name(pt), "apipassword"}); get_provider_display_name(prov), "apipassword"});
#else #else
auto api_file = utils::path::combine(utils::path::resolve("~/."), auto api_file = utils::path::combine(
{get_provider_name(pt), "apipassword"}); utils::path::resolve("~/."), {get_provider_name(prov), "apipassword"});
#endif #endif
#endif #endif
auto lines = utils::file::read_file_lines(api_file); auto lines = utils::file::read_file_lines(api_file);
return lines.empty() ? "" : utils::string::trim(lines[0]); return lines.empty() ? "" : utils::string::trim(lines[0]);
} }
auto app_config::get_provider_display_name(const provider_type &pt) auto app_config::get_provider_display_name(const provider_type &prov)
-> std::string { -> std::string {
static const std::array<std::string, static const std::array<std::string,
static_cast<std::size_t>(provider_type::unknown)> static_cast<std::size_t>(provider_type::unknown)>
PROVIDER_DISPLAY_NAMES = { PROVIDER_DISPLAY_NAMES = {
"Sia", "Remote", "S3", "Passthrough", "Encrypt", "Sia",
"Remote",
"S3",
"Encrypt",
}; };
return PROVIDER_DISPLAY_NAMES[static_cast<std::size_t>(pt)]; return PROVIDER_DISPLAY_NAMES[static_cast<std::size_t>(prov)];
} }
auto app_config::get_provider_name(const provider_type &pt) -> std::string { auto app_config::get_provider_name(const provider_type &prov) -> std::string {
static const std::array<std::string, static const std::array<std::string,
static_cast<std::size_t>(provider_type::unknown)> static_cast<std::size_t>(provider_type::unknown)>
PROVIDER_NAMES = { PROVIDER_NAMES = {
"sia", "remote", "s3", "passthrough", "encrypt", "sia",
"remote",
"s3",
"encrypt",
}; };
return PROVIDER_NAMES[static_cast<std::size_t>(pt)]; return PROVIDER_NAMES[static_cast<std::size_t>(prov)];
} }
auto app_config::get_value_by_name(const std::string &name) -> std::string { auto app_config::get_value_by_name(const std::string &name) -> std::string {
@ -447,8 +457,11 @@ auto app_config::get_value_by_name(const std::string &name) -> std::string {
if (name == "S3Config.URL") { if (name == "S3Config.URL") {
return s3_config_.url; return s3_config_.url;
} }
if (name == "S3Config.UsePathStyle") {
return utils::string::from_bool(s3_config_.use_path_style);
}
if (name == "S3Config.UseRegionInURL") { if (name == "S3Config.UseRegionInURL") {
return std::to_string(s3_config_.use_region_in_url); return utils::string::from_bool(s3_config_.use_region_in_url);
} }
if (name == "S3Config.TimeoutMs") { if (name == "S3Config.TimeoutMs") {
return std::to_string(s3_config_.timeout_ms); return std::to_string(s3_config_.timeout_ms);
@ -463,14 +476,14 @@ auto app_config::load() -> bool {
auto ret = false; auto ret = false;
const auto config_file_path = get_config_file_path(); const auto config_file_path = get_config_file_path();
recur_mutex_lock l(read_write_mutex_); recur_mutex_lock lock(read_write_mutex_);
if (utils::file::is_file(config_file_path)) { if (utils::file::is_file(config_file_path)) {
try { try {
std::ifstream config_file(&config_file_path[0]); std::ifstream config_file(config_file_path.data());
if (config_file.is_open()) { if (config_file.is_open()) {
std::stringstream ss; std::stringstream stream;
ss << config_file.rdbuf(); stream << config_file.rdbuf();
const auto json_text = ss.str(); const auto json_text = stream.str();
config_file.close(); config_file.close();
if ((ret = not json_text.empty())) { if ((ret = not json_text.empty())) {
const auto json_document = json::parse(json_text); const auto json_document = json::parse(json_text);
@ -510,20 +523,20 @@ auto app_config::load() -> bool {
if (json_document.find("HostConfig") != json_document.end()) { if (json_document.find("HostConfig") != json_document.end()) {
auto host_config_json = json_document["HostConfig"]; auto host_config_json = json_document["HostConfig"];
auto hc = hc_; auto cfg = hc_;
get_value(host_config_json, "AgentString", hc.agent_string, ret); get_value(host_config_json, "AgentString", cfg.agent_string, ret);
get_value(host_config_json, "ApiPassword", hc.api_password, ret); get_value(host_config_json, "ApiPassword", cfg.api_password, ret);
get_value(host_config_json, "ApiPort", hc.api_port, ret); get_value(host_config_json, "ApiPort", cfg.api_port, ret);
get_value(host_config_json, "HostNameOrIp", hc.host_name_or_ip, get_value(host_config_json, "HostNameOrIp", cfg.host_name_or_ip,
ret); ret);
get_value(host_config_json, "TimeoutMs", hc.timeout_ms, ret); get_value(host_config_json, "TimeoutMs", cfg.timeout_ms, ret);
hc_ = hc; hc_ = cfg;
} else { } else {
ret = false; ret = false;
} }
if (hc_.api_password.empty()) { if (hc_.api_password.empty()) {
hc_.api_password = get_provider_api_password(pt_); hc_.api_password = get_provider_api_password(prov_);
if (hc_.api_password.empty()) { if (hc_.api_password.empty()) {
ret = false; ret = false;
} }
@ -531,20 +544,22 @@ auto app_config::load() -> bool {
if (json_document.find("S3Config") != json_document.end()) { if (json_document.find("S3Config") != json_document.end()) {
auto s3_config_json = json_document["S3Config"]; auto s3_config_json = json_document["S3Config"];
auto s3 = s3_config_; auto s3_cfg = s3_config_;
get_value(s3_config_json, "AccessKey", s3.access_key, ret); get_value(s3_config_json, "AccessKey", s3_cfg.access_key, ret);
get_value(s3_config_json, "Bucket", s3.bucket, ret); get_value(s3_config_json, "Bucket", s3_cfg.bucket, ret);
get_value(s3_config_json, "CacheTimeoutSeconds", get_value(s3_config_json, "CacheTimeoutSeconds",
s3.cache_timeout_secs, ret); s3_cfg.cache_timeout_secs, ret);
get_value(s3_config_json, "EncryptionToken", s3.encryption_token, get_value(s3_config_json, "EncryptionToken",
s3_cfg.encryption_token, ret);
get_value(s3_config_json, "Region", s3_cfg.region, ret);
get_value(s3_config_json, "SecretKey", s3_cfg.secret_key, ret);
get_value(s3_config_json, "TimeoutMs", s3_cfg.timeout_ms, ret);
get_value(s3_config_json, "URL", s3_cfg.url, ret);
get_value(s3_config_json, "UsePathStyle", s3_cfg.use_path_style,
ret); ret);
get_value(s3_config_json, "Region", s3.region, ret); get_value(s3_config_json, "UseRegionInURL",
get_value(s3_config_json, "SecretKey", s3.secret_key, ret); s3_cfg.use_region_in_url, ret);
get_value(s3_config_json, "TimeoutMs", s3.timeout_ms, ret); s3_config_ = s3_cfg;
get_value(s3_config_json, "URL", s3.url, ret);
get_value(s3_config_json, "UseRegionInURL", s3.use_region_in_url,
ret);
s3_config_ = s3;
} else { } else {
ret = false; ret = false;
} }
@ -593,13 +608,13 @@ auto app_config::load() -> bool {
ret = false; ret = false;
} }
std::uint64_t version = 0u; std::uint64_t version{};
get_value(json_document, "Version", version, ret); get_value(json_document, "Version", version, ret);
// Handle configuration defaults for new config versions // Handle configuration defaults for new config versions
if (version != REPERTORY_CONFIG_VERSION) { if (version != REPERTORY_CONFIG_VERSION) {
if (version > REPERTORY_CONFIG_VERSION) { if (version > REPERTORY_CONFIG_VERSION) {
version = 0u; version = 0U;
} }
version_ = version; version_ = version;
@ -621,9 +636,9 @@ auto app_config::load() -> bool {
} }
void app_config::save() { void app_config::save() {
const auto configFilePath = get_config_file_path(); const auto file_path = get_config_file_path();
recur_mutex_lock l(read_write_mutex_); recur_mutex_lock lock(read_write_mutex_);
if (config_changed_ || not utils::file::is_file(configFilePath)) { if (config_changed_ || not utils::file::is_file(file_path)) {
if (not utils::file::is_directory(data_directory_)) { if (not utils::file::is_directory(data_directory_)) {
if (not utils::file::create_full_directory_path(data_directory_)) { if (not utils::file::create_full_directory_path(data_directory_)) {
utils::error::raise_error( utils::error::raise_error(
@ -636,7 +651,7 @@ void app_config::save() {
json data = get_json(); json data = get_json();
auto success = false; auto success = false;
for (auto i = 0; not success && (i < 5); i++) { for (auto i = 0; not success && (i < 5); i++) {
if (not(success = utils::file::write_json_file(configFilePath, data))) { if (not(success = utils::file::write_json_file(file_path, data))) {
std::this_thread::sleep_for(1s); std::this_thread::sleep_for(1s);
} }
} }
@ -684,19 +699,19 @@ auto app_config::set_value_by_name(const std::string &name,
} }
if (name == "EnableChunkDownloaderTimeout") { if (name == "EnableChunkDownloaderTimeout") {
set_enable_chunk_downloader_timeout(utils::string::to_bool(value)); set_enable_chunk_downloader_timeout(utils::string::to_bool(value));
return std::to_string(get_enable_chunk_download_timeout()); return utils::string::from_bool(get_enable_chunk_download_timeout());
} }
if (name == "EnableCommDurationEvents") { if (name == "EnableCommDurationEvents") {
set_enable_comm_duration_events(utils::string::to_bool(value)); set_enable_comm_duration_events(utils::string::to_bool(value));
return std::to_string(get_enable_comm_duration_events()); return utils::string::from_bool(get_enable_comm_duration_events());
} }
if (name == "EnableDriveEvents") { if (name == "EnableDriveEvents") {
set_enable_drive_events(utils::string::to_bool(value)); set_enable_drive_events(utils::string::to_bool(value));
return std::to_string(get_enable_drive_events()); return utils::string::from_bool(get_enable_drive_events());
} }
if (name == "EnableMaxCacheSize") { if (name == "EnableMaxCacheSize") {
set_enable_max_cache_size(utils::string::to_bool(value)); set_enable_max_cache_size(utils::string::to_bool(value));
return std::to_string(get_enable_max_cache_size()); return utils::string::from_bool(get_enable_max_cache_size());
#ifdef _WIN32 #ifdef _WIN32
} }
if (name == "EnableMountManager") { if (name == "EnableMountManager") {
@ -722,7 +737,7 @@ auto app_config::set_value_by_name(const std::string &name,
} }
if (name == "EvictionUsesAccessedTime") { if (name == "EvictionUsesAccessedTime") {
set_eviction_uses_accessed_time(utils::string::to_bool(value)); set_eviction_uses_accessed_time(utils::string::to_bool(value));
return std::to_string(get_eviction_uses_accessed_time()); return utils::string::from_bool(get_eviction_uses_accessed_time());
} }
if (name == "HighFreqIntervalSeconds") { if (name == "HighFreqIntervalSeconds") {
set_high_frequency_interval_secs(utils::string::to_uint8(value)); set_high_frequency_interval_secs(utils::string::to_uint8(value));
@ -779,11 +794,11 @@ auto app_config::set_value_by_name(const std::string &name,
} }
if (name == "RemoteMount.EnableRemoteMount") { if (name == "RemoteMount.EnableRemoteMount") {
set_enable_remote_mount(utils::string::to_bool(value)); set_enable_remote_mount(utils::string::to_bool(value));
return std::to_string(get_enable_remote_mount()); return utils::string::from_bool(get_enable_remote_mount());
} }
if (name == "RemoteMount.IsRemoteMount") { if (name == "RemoteMount.IsRemoteMount") {
set_is_remote_mount(utils::string::to_bool(value)); set_is_remote_mount(utils::string::to_bool(value));
return std::to_string(get_is_remote_mount()); return utils::string::from_bool(get_is_remote_mount());
} }
if (name == "RemoteMount.RemoteClientPoolSize") { if (name == "RemoteMount.RemoteClientPoolSize") {
set_remote_client_pool_size(utils::string::to_uint8(value)); set_remote_client_pool_size(utils::string::to_uint8(value));
@ -831,7 +846,7 @@ auto app_config::set_value_by_name(const std::string &name,
} }
if (name == "S3Config.CacheTimeoutSeconds") { if (name == "S3Config.CacheTimeoutSeconds") {
const auto timeout = const auto timeout =
std::max(std::uint16_t(5u), utils::string::to_uint16(value)); std::max(std::uint16_t(5U), utils::string::to_uint16(value));
set_value(s3_config_.cache_timeout_secs, timeout); set_value(s3_config_.cache_timeout_secs, timeout);
return std::to_string(s3_config_.cache_timeout_secs); return std::to_string(s3_config_.cache_timeout_secs);
} }
@ -847,9 +862,13 @@ auto app_config::set_value_by_name(const std::string &name,
set_value(s3_config_.url, value); set_value(s3_config_.url, value);
return s3_config_.url; return s3_config_.url;
} }
if (name == "S3Config.UsePathStyle") {
set_value(s3_config_.use_path_style, utils::string::to_bool(value));
return utils::string::from_bool(s3_config_.use_path_style);
}
if (name == "S3Config.UseRegionInURL") { if (name == "S3Config.UseRegionInURL") {
set_value(s3_config_.use_region_in_url, utils::string::to_bool(value)); set_value(s3_config_.use_region_in_url, utils::string::to_bool(value));
return std::to_string(s3_config_.use_region_in_url); return utils::string::from_bool(s3_config_.use_region_in_url);
} }
if (name == "S3Config.TimeoutMs") { if (name == "S3Config.TimeoutMs") {
set_value(s3_config_.timeout_ms, utils::string::to_uint32(value)); set_value(s3_config_.timeout_ms, utils::string::to_uint32(value));

View File

@ -43,32 +43,36 @@ const curl_comm::write_callback curl_comm::write_headers =
auto &headers = *reinterpret_cast<http_headers *>(outstream); auto &headers = *reinterpret_cast<http_headers *>(outstream);
const auto header = std::string(buffer, size * nitems); const auto header = std::string(buffer, size * nitems);
const auto parts = utils::string::split(header, ':'); const auto parts = utils::string::split(header, ':');
if (parts.size() > 1u) { if (parts.size() > 1U) {
auto data = header.substr(parts[0u].size() + 1u); auto data = header.substr(parts[0U].size() + 1U);
utils::string::left_trim(data); utils::string::left_trim(data);
utils::string::right_trim(data, '\r'); utils::string::right_trim(data, '\r');
utils::string::right_trim(data, '\n'); utils::string::right_trim(data, '\n');
utils::string::right_trim(data, '\r'); utils::string::right_trim(data, '\r');
headers[utils::string::to_lower(parts[0u])] = data; headers[utils::string::to_lower(parts[0U])] = data;
} }
return size * nitems; return size * nitems;
}); });
curl_comm::curl_comm(host_config hc) curl_comm::curl_comm(host_config cfg)
: host_config_(std::move(hc)), s3_config_(std::nullopt) {} : host_config_(std::move(cfg)), s3_config_(std::nullopt) {}
curl_comm::curl_comm(s3_config s3) curl_comm::curl_comm(s3_config cfg)
: host_config_(std::nullopt), s3_config_(std::move(s3)) {} : host_config_(std::nullopt), s3_config_(std::move(cfg)) {}
auto curl_comm::construct_url(CURL *curl, const std::string &relative_path, auto curl_comm::construct_url(CURL *curl, const std::string &relative_path,
const host_config &hc) -> std::string { const host_config &cfg) -> std::string {
auto custom_port = static constexpr const auto http = 80U;
(((hc.protocol == "http") && (hc.api_port == 80U || hc.api_port == 0U)) || static constexpr const auto https = 443U;
((hc.protocol == "https") && (hc.api_port == 443U || hc.api_port == 0U)))
auto custom_port = (((cfg.protocol == "http") &&
(cfg.api_port == http || cfg.api_port == 0U)) ||
((cfg.protocol == "https") &&
(cfg.api_port == https || cfg.api_port == 0U)))
? "" ? ""
: ":" + std::to_string(hc.api_port); : ":" + std::to_string(cfg.api_port);
auto url = hc.protocol + "://" + auto url = cfg.protocol + "://" +
utils::string::trim_copy(hc.host_name_or_ip) + custom_port; utils::string::trim_copy(cfg.host_name_or_ip) + custom_port;
static const auto complete_url = [](const std::string &current_path, static const auto complete_url = [](const std::string &current_path,
const std::string &parent_path, const std::string &parent_path,
@ -80,40 +84,40 @@ auto curl_comm::construct_url(CURL *curl, const std::string &relative_path,
return final_url; return final_url;
}; };
auto path = utils::path::combine("/", {hc.path}); auto path = utils::path::combine("/", {cfg.path});
return relative_path.empty() return relative_path.empty()
? complete_url(path, hc.path, url) ? complete_url(path, cfg.path, url)
: complete_url(utils::path::combine( : complete_url(utils::path::combine(
path, {url_encode(curl, relative_path, true)}), path, {url_encode(curl, relative_path, true)}),
relative_path, url); relative_path, url);
} }
auto curl_comm::create_host_config(const s3_config &config, auto curl_comm::create_host_config(const s3_config &cfg, bool use_s3_path_style)
bool use_s3_path_style) -> host_config { -> host_config {
host_config hc{}; host_config host_cfg{};
hc.api_password = config.secret_key; host_cfg.api_password = cfg.secret_key;
hc.api_user = config.access_key; host_cfg.api_user = cfg.access_key;
auto pos = config.url.find(':'); auto pos = cfg.url.find(':');
hc.host_name_or_ip = config.url.substr(pos + 3U); host_cfg.host_name_or_ip = cfg.url.substr(pos + 3U);
if (config.use_region_in_url && not config.region.empty()) { if (cfg.use_region_in_url && not cfg.region.empty()) {
auto parts = utils::string::split(hc.host_name_or_ip, '.', false); auto parts = utils::string::split(host_cfg.host_name_or_ip, '.', false);
if (parts.size() > 1U) { if (parts.size() > 1U) {
parts.insert(parts.begin() + 1U, config.region); parts.insert(parts.begin() + 1U, cfg.region);
hc.host_name_or_ip = utils::string::join(parts, '.'); host_cfg.host_name_or_ip = utils::string::join(parts, '.');
} }
} }
if (not use_s3_path_style) { if (not use_s3_path_style) {
hc.host_name_or_ip = config.bucket + '.' + hc.host_name_or_ip; host_cfg.host_name_or_ip = cfg.bucket + '.' + host_cfg.host_name_or_ip;
} }
hc.protocol = config.url.substr(0U, pos); host_cfg.protocol = cfg.url.substr(0U, pos);
if (use_s3_path_style) { if (use_s3_path_style) {
hc.path = '/' + config.bucket; host_cfg.path = '/' + cfg.bucket;
} }
return hc; return host_cfg;
} }
void curl_comm::enable_s3_path_style(bool enable) { void curl_comm::enable_s3_path_style(bool enable) {
@ -126,7 +130,7 @@ auto curl_comm::make_request(const curl::requests::http_delete &del,
return make_request( return make_request(
s3_config_.has_value() s3_config_.has_value()
? create_host_config(s3_config_.value(), use_s3_path_style_) ? create_host_config(s3_config_.value(), use_s3_path_style_)
: host_config_.value(), : host_config_.value_or(host_config{}),
del, response_code, stop_requested); del, response_code, stop_requested);
} }
@ -136,7 +140,7 @@ auto curl_comm::make_request(const curl::requests::http_get &get,
return make_request( return make_request(
s3_config_.has_value() s3_config_.has_value()
? create_host_config(s3_config_.value(), use_s3_path_style_) ? create_host_config(s3_config_.value(), use_s3_path_style_)
: host_config_.value(), : host_config_.value_or(host_config{}),
get, response_code, stop_requested); get, response_code, stop_requested);
} }
@ -146,7 +150,7 @@ auto curl_comm::make_request(const curl::requests::http_head &head,
return make_request( return make_request(
s3_config_.has_value() s3_config_.has_value()
? create_host_config(s3_config_.value(), use_s3_path_style_) ? create_host_config(s3_config_.value(), use_s3_path_style_)
: host_config_.value(), : host_config_.value_or(host_config{}),
head, response_code, stop_requested); head, response_code, stop_requested);
} }
@ -156,7 +160,7 @@ auto curl_comm::make_request(const curl::requests::http_put_file &put_file,
return make_request( return make_request(
s3_config_.has_value() s3_config_.has_value()
? create_host_config(s3_config_.value(), use_s3_path_style_) ? create_host_config(s3_config_.value(), use_s3_path_style_)
: host_config_.value(), : host_config_.value_or(host_config{}),
put_file, response_code, stop_requested); put_file, response_code, stop_requested);
} }

View File

@ -38,6 +38,8 @@ multi_request::~multi_request() {
} }
void multi_request::get_result(CURLcode &curl_code, long &http_code) { void multi_request::get_result(CURLcode &curl_code, long &http_code) {
static constexpr const auto timeout_ms = 100;
curl_code = CURLcode::CURLE_ABORTED_BY_CALLBACK; curl_code = CURLcode::CURLE_ABORTED_BY_CALLBACK;
http_code = -1; http_code = -1;
@ -45,8 +47,8 @@ void multi_request::get_result(CURLcode &curl_code, long &http_code) {
int running_handles = 0; int running_handles = 0;
curl_multi_perform(multi_handle_, &running_handles); curl_multi_perform(multi_handle_, &running_handles);
while (not error && (running_handles > 0) && not stop_requested_) { while (not error && (running_handles > 0) && not stop_requested_) {
int ignored; int ignored{};
curl_multi_wait(multi_handle_, nullptr, 0, 100, &ignored); curl_multi_wait(multi_handle_, nullptr, 0, timeout_ms, &ignored);
const auto ret = curl_multi_perform(multi_handle_, &running_handles); const auto ret = curl_multi_perform(multi_handle_, &running_handles);
error = (ret != CURLM_CALL_MULTI_PERFORM) && (ret != CURLM_OK); error = (ret != CURLM_CALL_MULTI_PERFORM) && (ret != CURLM_OK);
@ -56,7 +58,7 @@ void multi_request::get_result(CURLcode &curl_code, long &http_code) {
int remaining_messages = 0; int remaining_messages = 0;
auto *multi_result = auto *multi_result =
curl_multi_info_read(multi_handle_, &remaining_messages); curl_multi_info_read(multi_handle_, &remaining_messages);
if (multi_result && (multi_result->msg == CURLMSG_DONE)) { if ((multi_result != nullptr) && (multi_result->msg == CURLMSG_DONE)) {
curl_easy_getinfo(multi_result->easy_handle, CURLINFO_RESPONSE_CODE, curl_easy_getinfo(multi_result->easy_handle, CURLINFO_RESPONSE_CODE,
&http_code); &http_code);
curl_code = multi_result->data.result; curl_code = multi_result->data.result;

View File

@ -24,34 +24,23 @@
#include "utils/string_utils.hpp" #include "utils/string_utils.hpp"
namespace repertory::curl::requests { namespace repertory::curl::requests {
auto http_put_file::get_path() const -> std::string {
if (reader) {
auto updated_path = path;
return utils::string::replace(updated_path, file_name,
reader->get_encrypted_file_name());
}
return http_request_base::get_path();
}
auto http_put_file::set_method(CURL *curl, stop_type &stop_requested) const auto http_put_file::set_method(CURL *curl, stop_type &stop_requested) const
-> bool { -> bool {
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT"); curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
if (not source_path.empty()) {
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
if (not encryption_token.value_or("").empty()) {
if (not reader) { if (source_path.empty()) {
reader = std::make_shared<utils::encryption::encrypting_reader>( curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, 0L);
file_name, source_path, stop_requested, encryption_token.value()); return true;
} }
if (reader) {
curl_easy_setopt(curl, CURLOPT_READDATA, reader.get()); curl_easy_setopt(curl, CURLOPT_READDATA, reader.get());
curl_easy_setopt( curl_easy_setopt(
curl, CURLOPT_READFUNCTION, curl, CURLOPT_READFUNCTION,
static_cast<curl_read_callback>( static_cast<curl_read_callback>(
utils::encryption::encrypting_reader::reader_function)); utils::encryption::encrypting_reader::reader_function));
curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, reader->get_total_size());
reader->get_total_size());
return true; return true;
} }
@ -59,7 +48,8 @@ auto http_put_file::set_method(CURL *curl, stop_type &stop_requested) const
stop_requested, stop_requested,
}); });
if (native_file::open(source_path, read_info->nf) != api_error::success) { if (native_file::create_or_open(source_path, read_info->nf) !=
api_error::success) {
return false; return false;
} }
@ -73,7 +63,6 @@ auto http_put_file::set_method(CURL *curl, stop_type &stop_requested) const
curl_easy_setopt(curl, CURLOPT_READDATA, read_info.get()); curl_easy_setopt(curl, CURLOPT_READDATA, read_info.get());
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_file_data); curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_file_data);
curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, file_size); curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, file_size);
}
return true; return true;
} }

View File

@ -30,23 +30,23 @@ void client_pool::pool::execute(
std::uint64_t thread_id, const worker_callback &worker, std::uint64_t thread_id, const worker_callback &worker,
const worker_complete_callback &worker_complete) { const worker_complete_callback &worker_complete) {
const auto index = thread_id % pool_queues_.size(); const auto index = thread_id % pool_queues_.size();
auto wi = std::make_shared<work_item>(worker, worker_complete); auto job = std::make_shared<work_item>(worker, worker_complete);
auto &pool_queue = pool_queues_[index]; auto &pool_queue = pool_queues_[index];
unique_mutex_lock queue_lock(pool_queue->mutex); unique_mutex_lock queue_lock(pool_queue->mutex);
pool_queue->queue.emplace_back(wi); pool_queue->queue.emplace_back(job);
pool_queue->notify.notify_all(); pool_queue->notify.notify_all();
queue_lock.unlock(); queue_lock.unlock();
} }
client_pool::pool::pool(std::uint8_t pool_size) { client_pool::pool::pool(std::uint8_t pool_size) {
event_system::instance().raise<service_started>("client_pool"); event_system::instance().raise<service_started>("client_pool");
thread_index_ = 0u;
for (std::uint8_t i = 0u; i < pool_size; i++) { for (std::uint8_t i = 0U; i < pool_size; i++) {
pool_queues_.emplace_back(std::make_unique<work_queue>()); pool_queues_.emplace_back(std::make_unique<work_queue>());
} }
for (std::size_t i = 0u; i < pool_queues_.size(); i++) { for (std::size_t i = 0U; i < pool_queues_.size(); i++) {
pool_threads_.emplace_back([this]() { pool_threads_.emplace_back([this]() {
const auto thread_index = thread_index_++; const auto thread_index = thread_index_++;
@ -88,12 +88,12 @@ client_pool::pool::pool(std::uint8_t pool_size) {
queue_lock.lock(); queue_lock.lock();
while (not queue.empty()) { while (not queue.empty()) {
auto wi = queue.front(); auto job = queue.front();
queue.pop_front(); queue.pop_front();
queue_notify.notify_all(); queue_notify.notify_all();
queue_lock.unlock(); queue_lock.unlock();
wi->work_complete(utils::from_api_error(api_error::download_stopped)); job->work_complete(utils::from_api_error(api_error::download_stopped));
queue_lock.lock(); queue_lock.lock();
} }
@ -108,7 +108,7 @@ void client_pool::pool::shutdown() {
shutdown_ = true; shutdown_ = true;
for (auto &pool_queue : pool_queues_) { for (auto &pool_queue : pool_queues_) {
unique_mutex_lock l(pool_queue->mutex); mutex_lock lock(pool_queue->mutex);
pool_queue->notify.notify_all(); pool_queue->notify.notify_all();
} }
@ -148,8 +148,8 @@ void client_pool::shutdown() {
unique_mutex_lock pool_lock(pool_mutex_); unique_mutex_lock pool_lock(pool_mutex_);
if (not shutdown_) { if (not shutdown_) {
shutdown_ = true; shutdown_ = true;
for (auto &kv : pool_lookup_) { for (auto &pool_entry : pool_lookup_) {
kv.second->shutdown(); pool_entry.second->shutdown();
} }
pool_lookup_.clear(); pool_lookup_.clear();
} }

View File

@ -32,7 +32,7 @@
namespace repertory { namespace repertory {
void packet::clear() { void packet::clear() {
buffer_.clear(); buffer_.clear();
decode_offset_ = 0u; decode_offset_ = 0U;
} }
auto packet::decode(std::string &data) -> packet::error_type { auto packet::decode(std::string &data) -> packet::error_type {
@ -59,7 +59,7 @@ auto packet::decode(void *&ptr) -> packet::error_type {
} }
auto packet::decode(void *buffer, std::size_t size) -> packet::error_type { auto packet::decode(void *buffer, std::size_t size) -> packet::error_type {
if (size) { if (size != 0U) {
const auto read_size = const auto read_size =
utils::calculate_read_size(buffer_.size(), size, decode_offset_); utils::calculate_read_size(buffer_.size(), size, decode_offset_);
if (read_size == size) { if (read_size == size) {
@ -75,153 +75,153 @@ auto packet::decode(void *buffer, std::size_t size) -> packet::error_type {
return utils::from_api_error(api_error::success); return utils::from_api_error(api_error::success);
} }
auto packet::decode(std::int8_t &i) -> packet::error_type { auto packet::decode(std::int8_t &val) -> packet::error_type {
const auto ret = decode(&i, sizeof(i)); const auto ret = decode(&val, sizeof(val));
if (ret == 0) { if (ret == 0) {
boost::endian::big_to_native_inplace(i); boost::endian::big_to_native_inplace(val);
} }
return ret; return ret;
} }
auto packet::decode(std::uint8_t &i) -> packet::error_type { auto packet::decode(std::uint8_t &val) -> packet::error_type {
const auto ret = decode(&i, sizeof(i)); const auto ret = decode(&val, sizeof(val));
if (ret == 0) { if (ret == 0) {
boost::endian::big_to_native_inplace(i); boost::endian::big_to_native_inplace(val);
} }
return ret; return ret;
} }
auto packet::decode(std::int16_t &i) -> packet::error_type { auto packet::decode(std::int16_t &val) -> packet::error_type {
const auto ret = decode(&i, sizeof(i)); const auto ret = decode(&val, sizeof(val));
if (ret == 0) { if (ret == 0) {
boost::endian::big_to_native_inplace(i); boost::endian::big_to_native_inplace(val);
} }
return ret; return ret;
} }
auto packet::decode(std::uint16_t &i) -> packet::error_type { auto packet::decode(std::uint16_t &val) -> packet::error_type {
const auto ret = decode(&i, sizeof(i)); const auto ret = decode(&val, sizeof(val));
if (ret == 0) { if (ret == 0) {
boost::endian::big_to_native_inplace(i); boost::endian::big_to_native_inplace(val);
} }
return ret; return ret;
} }
auto packet::decode(std::int32_t &i) -> packet::error_type { auto packet::decode(std::int32_t &val) -> packet::error_type {
const auto ret = decode(&i, sizeof(i)); const auto ret = decode(&val, sizeof(val));
if (ret == 0) { if (ret == 0) {
boost::endian::big_to_native_inplace(i); boost::endian::big_to_native_inplace(val);
} }
return ret; return ret;
} }
auto packet::decode(std::uint32_t &i) -> packet::error_type { auto packet::decode(std::uint32_t &val) -> packet::error_type {
const auto ret = decode(&i, sizeof(i)); const auto ret = decode(&val, sizeof(val));
if (ret == 0) { if (ret == 0) {
boost::endian::big_to_native_inplace(i); boost::endian::big_to_native_inplace(val);
} }
return ret; return ret;
} }
auto packet::decode(std::int64_t &i) -> packet::error_type { auto packet::decode(std::int64_t &val) -> packet::error_type {
const auto ret = decode(&i, sizeof(i)); const auto ret = decode(&val, sizeof(val));
if (ret == 0) { if (ret == 0) {
boost::endian::big_to_native_inplace(i); boost::endian::big_to_native_inplace(val);
} }
return ret; return ret;
} }
auto packet::decode(std::uint64_t &i) -> packet::error_type { auto packet::decode(std::uint64_t &val) -> packet::error_type {
const auto ret = decode(&i, sizeof(i)); const auto ret = decode(&val, sizeof(val));
if (ret == 0) { if (ret == 0) {
boost::endian::big_to_native_inplace(i); boost::endian::big_to_native_inplace(val);
} }
return ret; return ret;
} }
auto packet::decode(remote::setattr_x &i) -> packet::error_type { auto packet::decode(remote::setattr_x &val) -> packet::error_type {
const auto ret = decode(&i, sizeof(i)); const auto ret = decode(&val, sizeof(val));
if (ret == 0) { if (ret == 0) {
boost::endian::big_to_native_inplace(i.acctime); boost::endian::big_to_native_inplace(val.acctime);
boost::endian::big_to_native_inplace(i.bkuptime); boost::endian::big_to_native_inplace(val.bkuptime);
boost::endian::big_to_native_inplace(i.chgtime); boost::endian::big_to_native_inplace(val.chgtime);
boost::endian::big_to_native_inplace(i.crtime); boost::endian::big_to_native_inplace(val.crtime);
boost::endian::big_to_native_inplace(i.flags); boost::endian::big_to_native_inplace(val.flags);
boost::endian::big_to_native_inplace(i.gid); boost::endian::big_to_native_inplace(val.gid);
boost::endian::big_to_native_inplace(i.mode); boost::endian::big_to_native_inplace(val.mode);
boost::endian::big_to_native_inplace(i.modtime); boost::endian::big_to_native_inplace(val.modtime);
boost::endian::big_to_native_inplace(i.size); boost::endian::big_to_native_inplace(val.size);
boost::endian::big_to_native_inplace(i.uid); boost::endian::big_to_native_inplace(val.uid);
boost::endian::big_to_native_inplace(i.valid); boost::endian::big_to_native_inplace(val.valid);
} }
return ret; return ret;
} }
auto packet::decode(remote::stat &i) -> packet::error_type { auto packet::decode(remote::stat &val) -> packet::error_type {
const auto ret = decode(&i, sizeof(i)); const auto ret = decode(&val, sizeof(val));
if (ret == 0) { if (ret == 0) {
boost::endian::big_to_native_inplace(i.st_mode); boost::endian::big_to_native_inplace(val.st_mode);
boost::endian::big_to_native_inplace(i.st_nlink); boost::endian::big_to_native_inplace(val.st_nlink);
boost::endian::big_to_native_inplace(i.st_uid); boost::endian::big_to_native_inplace(val.st_uid);
boost::endian::big_to_native_inplace(i.st_gid); boost::endian::big_to_native_inplace(val.st_gid);
boost::endian::big_to_native_inplace(i.st_atimespec); boost::endian::big_to_native_inplace(val.st_atimespec);
boost::endian::big_to_native_inplace(i.st_mtimespec); boost::endian::big_to_native_inplace(val.st_mtimespec);
boost::endian::big_to_native_inplace(i.st_ctimespec); boost::endian::big_to_native_inplace(val.st_ctimespec);
boost::endian::big_to_native_inplace(i.st_birthtimespec); boost::endian::big_to_native_inplace(val.st_birthtimespec);
boost::endian::big_to_native_inplace(i.st_size); boost::endian::big_to_native_inplace(val.st_size);
boost::endian::big_to_native_inplace(i.st_blocks); boost::endian::big_to_native_inplace(val.st_blocks);
boost::endian::big_to_native_inplace(i.st_blksize); boost::endian::big_to_native_inplace(val.st_blksize);
boost::endian::big_to_native_inplace(i.st_flags); boost::endian::big_to_native_inplace(val.st_flags);
} }
return ret; return ret;
} }
auto packet::decode(remote::statfs &i) -> packet::error_type { auto packet::decode(remote::statfs &val) -> packet::error_type {
const auto ret = decode(&i, sizeof(i)); const auto ret = decode(&val, sizeof(val));
if (ret == 0) { if (ret == 0) {
boost::endian::big_to_native_inplace(i.f_bavail); boost::endian::big_to_native_inplace(val.f_bavail);
boost::endian::big_to_native_inplace(i.f_bfree); boost::endian::big_to_native_inplace(val.f_bfree);
boost::endian::big_to_native_inplace(i.f_blocks); boost::endian::big_to_native_inplace(val.f_blocks);
boost::endian::big_to_native_inplace(i.f_favail); boost::endian::big_to_native_inplace(val.f_favail);
boost::endian::big_to_native_inplace(i.f_ffree); boost::endian::big_to_native_inplace(val.f_ffree);
boost::endian::big_to_native_inplace(i.f_files); boost::endian::big_to_native_inplace(val.f_files);
} }
return ret; return ret;
} }
auto packet::decode(remote::statfs_x &i) -> packet::error_type { auto packet::decode(remote::statfs_x &val) -> packet::error_type {
auto ret = decode(*dynamic_cast<remote::statfs *>(&i)); auto ret = decode(*dynamic_cast<remote::statfs *>(&val));
if (ret == 0) { if (ret == 0) {
ret = decode(&i.f_mntfromname[0], 1024); ret = decode(&val.f_mntfromname[0U], sizeof(val.f_mntfromname));
} }
return ret; return ret;
} }
auto packet::decode(remote::file_info &i) -> packet::error_type { auto packet::decode(remote::file_info &val) -> packet::error_type {
const auto ret = decode(&i, sizeof(i)); const auto ret = decode(&val, sizeof(val));
if (ret == 0) { if (ret == 0) {
boost::endian::big_to_native_inplace(i.AllocationSize); boost::endian::big_to_native_inplace(val.AllocationSize);
boost::endian::big_to_native_inplace(i.ChangeTime); boost::endian::big_to_native_inplace(val.ChangeTime);
boost::endian::big_to_native_inplace(i.CreationTime); boost::endian::big_to_native_inplace(val.CreationTime);
boost::endian::big_to_native_inplace(i.EaSize); boost::endian::big_to_native_inplace(val.EaSize);
boost::endian::big_to_native_inplace(i.FileAttributes); boost::endian::big_to_native_inplace(val.FileAttributes);
boost::endian::big_to_native_inplace(i.FileSize); boost::endian::big_to_native_inplace(val.FileSize);
boost::endian::big_to_native_inplace(i.HardLinks); boost::endian::big_to_native_inplace(val.HardLinks);
boost::endian::big_to_native_inplace(i.IndexNumber); boost::endian::big_to_native_inplace(val.IndexNumber);
boost::endian::big_to_native_inplace(i.LastAccessTime); boost::endian::big_to_native_inplace(val.LastAccessTime);
boost::endian::big_to_native_inplace(i.LastWriteTime); boost::endian::big_to_native_inplace(val.LastWriteTime);
boost::endian::big_to_native_inplace(i.ReparseTag); boost::endian::big_to_native_inplace(val.ReparseTag);
} }
return ret; return ret;
} }
auto packet::decode_json(packet &response, json &json_data) -> int { auto packet::decode_json(packet &response, json &json_data) -> int {
int ret = 0;
std::string data; std::string data;
if ((ret = response.decode(data)) == 0) { auto ret = response.decode(data);
if (ret == 0) {
try { try {
json_data = json::parse(data); json_data = json::parse(data);
} catch (const std::exception &e) { } catch (const std::exception &e) {
@ -253,7 +253,7 @@ auto packet::decrypt(const std::string &token) -> packet::error_type {
} }
void packet::encode(const void *buffer, std::size_t size, bool should_reserve) { void packet::encode(const void *buffer, std::size_t size, bool should_reserve) {
if (size) { if (size != 0U) {
if (should_reserve) { if (should_reserve) {
buffer_.reserve(buffer_.size() + size); buffer_.reserve(buffer_.size() + size);
} }
@ -263,133 +263,130 @@ void packet::encode(const void *buffer, std::size_t size, bool should_reserve) {
} }
void packet::encode(const std::string &str) { void packet::encode(const std::string &str) {
const auto len = strnlen(&str[0], str.size()); const auto len = strnlen(str.c_str(), str.size());
buffer_.reserve(len + 1 + buffer_.size()); buffer_.reserve(len + 1 + buffer_.size());
encode(&str[0], len, false); encode(str.c_str(), len, false);
buffer_.emplace_back(0); buffer_.emplace_back(0);
} }
void packet::encode(wchar_t *str) {
encode(utils::string::to_utf8(str ? str : L""));
}
void packet::encode(const wchar_t *str) { void packet::encode(const wchar_t *str) {
encode(utils::string::to_utf8(str ? str : L"")); encode(utils::string::to_utf8(str == nullptr ? L"" : str));
} }
void packet::encode(const std::wstring &str) { void packet::encode(const std::wstring &str) {
encode(utils::string::to_utf8(str)); encode(utils::string::to_utf8(str));
} }
void packet::encode(std::int8_t i) { void packet::encode(std::int8_t val) {
boost::endian::native_to_big_inplace(i); boost::endian::native_to_big_inplace(val);
encode(&i, sizeof(i), true); encode(&val, sizeof(val), true);
} }
void packet::encode(std::uint8_t i) { void packet::encode(std::uint8_t val) {
boost::endian::native_to_big_inplace(i); boost::endian::native_to_big_inplace(val);
encode(&i, sizeof(i), true); encode(&val, sizeof(val), true);
} }
void packet::encode(std::int16_t i) { void packet::encode(std::int16_t val) {
boost::endian::native_to_big_inplace(i); boost::endian::native_to_big_inplace(val);
encode(&i, sizeof(i), true); encode(&val, sizeof(val), true);
} }
void packet::encode(std::uint16_t i) { void packet::encode(std::uint16_t val) {
boost::endian::native_to_big_inplace(i); boost::endian::native_to_big_inplace(val);
encode(&i, sizeof(i), true); encode(&val, sizeof(val), true);
} }
void packet::encode(std::int32_t i) { void packet::encode(std::int32_t val) {
boost::endian::native_to_big_inplace(i); boost::endian::native_to_big_inplace(val);
encode(&i, sizeof(i), true); encode(&val, sizeof(val), true);
} }
void packet::encode(std::uint32_t i) { void packet::encode(std::uint32_t val) {
boost::endian::native_to_big_inplace(i); boost::endian::native_to_big_inplace(val);
encode(&i, sizeof(i), true); encode(&val, sizeof(val), true);
} }
void packet::encode(std::int64_t i) { void packet::encode(std::int64_t val) {
boost::endian::native_to_big_inplace(i); boost::endian::native_to_big_inplace(val);
encode(&i, sizeof(i), true); encode(&val, sizeof(val), true);
} }
void packet::encode(std::uint64_t i) { void packet::encode(std::uint64_t val) {
boost::endian::native_to_big_inplace(i); boost::endian::native_to_big_inplace(val);
encode(&i, sizeof(i), true); encode(&val, sizeof(val), true);
} }
void packet::encode(remote::setattr_x i) { void packet::encode(remote::setattr_x val) {
boost::endian::native_to_big_inplace(i.acctime); boost::endian::native_to_big_inplace(val.acctime);
boost::endian::native_to_big_inplace(i.bkuptime); boost::endian::native_to_big_inplace(val.bkuptime);
boost::endian::native_to_big_inplace(i.chgtime); boost::endian::native_to_big_inplace(val.chgtime);
boost::endian::native_to_big_inplace(i.crtime); boost::endian::native_to_big_inplace(val.crtime);
boost::endian::native_to_big_inplace(i.flags); boost::endian::native_to_big_inplace(val.flags);
boost::endian::native_to_big_inplace(i.gid); boost::endian::native_to_big_inplace(val.gid);
boost::endian::native_to_big_inplace(i.mode); boost::endian::native_to_big_inplace(val.mode);
boost::endian::native_to_big_inplace(i.modtime); boost::endian::native_to_big_inplace(val.modtime);
boost::endian::native_to_big_inplace(i.size); boost::endian::native_to_big_inplace(val.size);
boost::endian::native_to_big_inplace(i.uid); boost::endian::native_to_big_inplace(val.uid);
boost::endian::native_to_big_inplace(i.valid); boost::endian::native_to_big_inplace(val.valid);
encode(&i, sizeof(i), true); encode(&val, sizeof(val), true);
} }
void packet::encode(remote::stat i) { void packet::encode(remote::stat val) {
boost::endian::native_to_big_inplace(i.st_mode); boost::endian::native_to_big_inplace(val.st_mode);
boost::endian::native_to_big_inplace(i.st_nlink); boost::endian::native_to_big_inplace(val.st_nlink);
boost::endian::native_to_big_inplace(i.st_uid); boost::endian::native_to_big_inplace(val.st_uid);
boost::endian::native_to_big_inplace(i.st_gid); boost::endian::native_to_big_inplace(val.st_gid);
boost::endian::native_to_big_inplace(i.st_atimespec); boost::endian::native_to_big_inplace(val.st_atimespec);
boost::endian::native_to_big_inplace(i.st_mtimespec); boost::endian::native_to_big_inplace(val.st_mtimespec);
boost::endian::native_to_big_inplace(i.st_ctimespec); boost::endian::native_to_big_inplace(val.st_ctimespec);
boost::endian::native_to_big_inplace(i.st_birthtimespec); boost::endian::native_to_big_inplace(val.st_birthtimespec);
boost::endian::native_to_big_inplace(i.st_size); boost::endian::native_to_big_inplace(val.st_size);
boost::endian::native_to_big_inplace(i.st_blocks); boost::endian::native_to_big_inplace(val.st_blocks);
boost::endian::native_to_big_inplace(i.st_blksize); boost::endian::native_to_big_inplace(val.st_blksize);
boost::endian::native_to_big_inplace(i.st_flags); boost::endian::native_to_big_inplace(val.st_flags);
encode(&i, sizeof(i), true); encode(&val, sizeof(val), true);
} }
void packet::encode(remote::statfs i, bool should_reserve) { void packet::encode(remote::statfs val, bool should_reserve) {
boost::endian::native_to_big_inplace(i.f_bavail); boost::endian::native_to_big_inplace(val.f_bavail);
boost::endian::native_to_big_inplace(i.f_bfree); boost::endian::native_to_big_inplace(val.f_bfree);
boost::endian::native_to_big_inplace(i.f_blocks); boost::endian::native_to_big_inplace(val.f_blocks);
boost::endian::native_to_big_inplace(i.f_favail); boost::endian::native_to_big_inplace(val.f_favail);
boost::endian::native_to_big_inplace(i.f_ffree); boost::endian::native_to_big_inplace(val.f_ffree);
boost::endian::native_to_big_inplace(i.f_files); boost::endian::native_to_big_inplace(val.f_files);
encode(&i, sizeof(remote::statfs), should_reserve); encode(&val, sizeof(remote::statfs), should_reserve);
} }
void packet::encode(remote::statfs_x i) { void packet::encode(remote::statfs_x val) {
buffer_.reserve(buffer_.size() + sizeof(remote::statfs) + 1024); buffer_.reserve(buffer_.size() + sizeof(remote::statfs) +
encode(*dynamic_cast<remote::statfs *>(&i), false); sizeof(val.f_mntfromname));
encode(&i.f_mntfromname[0], 1024, false); encode(*dynamic_cast<remote::statfs *>(&val), false);
encode(&val.f_mntfromname[0], sizeof(val.f_mntfromname), false);
} }
void packet::encode(remote::file_info i) { void packet::encode(remote::file_info val) {
boost::endian::native_to_big_inplace(i.FileAttributes); boost::endian::native_to_big_inplace(val.FileAttributes);
boost::endian::native_to_big_inplace(i.ReparseTag); boost::endian::native_to_big_inplace(val.ReparseTag);
boost::endian::native_to_big_inplace(i.AllocationSize); boost::endian::native_to_big_inplace(val.AllocationSize);
boost::endian::native_to_big_inplace(i.FileSize); boost::endian::native_to_big_inplace(val.FileSize);
boost::endian::native_to_big_inplace(i.CreationTime); boost::endian::native_to_big_inplace(val.CreationTime);
boost::endian::native_to_big_inplace(i.LastAccessTime); boost::endian::native_to_big_inplace(val.LastAccessTime);
boost::endian::native_to_big_inplace(i.LastWriteTime); boost::endian::native_to_big_inplace(val.LastWriteTime);
boost::endian::native_to_big_inplace(i.ChangeTime); boost::endian::native_to_big_inplace(val.ChangeTime);
boost::endian::native_to_big_inplace(i.IndexNumber); boost::endian::native_to_big_inplace(val.IndexNumber);
boost::endian::native_to_big_inplace(i.HardLinks); boost::endian::native_to_big_inplace(val.HardLinks);
boost::endian::native_to_big_inplace(i.EaSize); boost::endian::native_to_big_inplace(val.EaSize);
encode(&i, sizeof(i), true); encode(&val, sizeof(val), true);
} }
void packet::encode_top(const void *buffer, std::size_t size, void packet::encode_top(const void *buffer, std::size_t size,
bool should_reserve) { bool should_reserve) {
if (size) { if (size != 0U) {
if (should_reserve) { if (should_reserve) {
buffer_.reserve(buffer_.size() + size); buffer_.reserve(buffer_.size() + size);
} }
@ -401,7 +398,7 @@ void packet::encode_top(const void *buffer, std::size_t size,
void packet::encode_top(const std::string &str) { void packet::encode_top(const std::string &str) {
const auto len = strnlen(str.c_str(), str.size()); const auto len = strnlen(str.c_str(), str.size());
buffer_.reserve(len + 1U + buffer_.size()); buffer_.reserve(len + 1U + buffer_.size());
encode_top(&str[0], len, false); encode_top(str.c_str(), len, false);
buffer_.insert(buffer_.begin() + static_cast<std::int32_t>(len), 0); buffer_.insert(buffer_.begin() + static_cast<std::int32_t>(len), 0);
} }
@ -409,110 +406,111 @@ void packet::encode_top(const std::wstring &str) {
encode_top(utils::string::to_utf8(str)); encode_top(utils::string::to_utf8(str));
} }
void packet::encode_top(std::int8_t i) { void packet::encode_top(std::int8_t val) {
boost::endian::native_to_big_inplace(i); boost::endian::native_to_big_inplace(val);
encode_top(&i, sizeof(i), true); encode_top(&val, sizeof(val), true);
} }
void packet::encode_top(std::uint8_t i) { void packet::encode_top(std::uint8_t val) {
boost::endian::native_to_big_inplace(i); boost::endian::native_to_big_inplace(val);
encode_top(&i, sizeof(i), true); encode_top(&val, sizeof(val), true);
} }
void packet::encode_top(std::int16_t i) { void packet::encode_top(std::int16_t val) {
boost::endian::native_to_big_inplace(i); boost::endian::native_to_big_inplace(val);
encode_top(&i, sizeof(i), true); encode_top(&val, sizeof(val), true);
} }
void packet::encode_top(std::uint16_t i) { void packet::encode_top(std::uint16_t val) {
boost::endian::native_to_big_inplace(i); boost::endian::native_to_big_inplace(val);
encode_top(&i, sizeof(i), true); encode_top(&val, sizeof(val), true);
} }
void packet::encode_top(std::int32_t i) { void packet::encode_top(std::int32_t val) {
boost::endian::native_to_big_inplace(i); boost::endian::native_to_big_inplace(val);
encode_top(&i, sizeof(i), true); encode_top(&val, sizeof(val), true);
} }
void packet::encode_top(std::uint32_t i) { void packet::encode_top(std::uint32_t val) {
boost::endian::native_to_big_inplace(i); boost::endian::native_to_big_inplace(val);
encode_top(&i, sizeof(i), true); encode_top(&val, sizeof(val), true);
} }
void packet::encode_top(std::int64_t i) { void packet::encode_top(std::int64_t val) {
boost::endian::native_to_big_inplace(i); boost::endian::native_to_big_inplace(val);
encode_top(&i, sizeof(i), true); encode_top(&val, sizeof(val), true);
} }
void packet::encode_top(std::uint64_t i) { void packet::encode_top(std::uint64_t val) {
boost::endian::native_to_big_inplace(i); boost::endian::native_to_big_inplace(val);
encode_top(&i, sizeof(i), true); encode_top(&val, sizeof(val), true);
} }
void packet::encode_top(remote::setattr_x i) { void packet::encode_top(remote::setattr_x val) {
boost::endian::native_to_big_inplace(i.acctime); boost::endian::native_to_big_inplace(val.acctime);
boost::endian::native_to_big_inplace(i.bkuptime); boost::endian::native_to_big_inplace(val.bkuptime);
boost::endian::native_to_big_inplace(i.chgtime); boost::endian::native_to_big_inplace(val.chgtime);
boost::endian::native_to_big_inplace(i.crtime); boost::endian::native_to_big_inplace(val.crtime);
boost::endian::native_to_big_inplace(i.flags); boost::endian::native_to_big_inplace(val.flags);
boost::endian::native_to_big_inplace(i.gid); boost::endian::native_to_big_inplace(val.gid);
boost::endian::native_to_big_inplace(i.mode); boost::endian::native_to_big_inplace(val.mode);
boost::endian::native_to_big_inplace(i.modtime); boost::endian::native_to_big_inplace(val.modtime);
boost::endian::native_to_big_inplace(i.size); boost::endian::native_to_big_inplace(val.size);
boost::endian::native_to_big_inplace(i.uid); boost::endian::native_to_big_inplace(val.uid);
boost::endian::native_to_big_inplace(i.valid); boost::endian::native_to_big_inplace(val.valid);
encode_top(&i, sizeof(i), true); encode_top(&val, sizeof(val), true);
} }
void packet::encode_top(remote::stat i) { void packet::encode_top(remote::stat val) {
boost::endian::native_to_big_inplace(i.st_mode); boost::endian::native_to_big_inplace(val.st_mode);
boost::endian::native_to_big_inplace(i.st_nlink); boost::endian::native_to_big_inplace(val.st_nlink);
boost::endian::native_to_big_inplace(i.st_uid); boost::endian::native_to_big_inplace(val.st_uid);
boost::endian::native_to_big_inplace(i.st_gid); boost::endian::native_to_big_inplace(val.st_gid);
boost::endian::native_to_big_inplace(i.st_atimespec); boost::endian::native_to_big_inplace(val.st_atimespec);
boost::endian::native_to_big_inplace(i.st_mtimespec); boost::endian::native_to_big_inplace(val.st_mtimespec);
boost::endian::native_to_big_inplace(i.st_ctimespec); boost::endian::native_to_big_inplace(val.st_ctimespec);
boost::endian::native_to_big_inplace(i.st_birthtimespec); boost::endian::native_to_big_inplace(val.st_birthtimespec);
boost::endian::native_to_big_inplace(i.st_size); boost::endian::native_to_big_inplace(val.st_size);
boost::endian::native_to_big_inplace(i.st_blocks); boost::endian::native_to_big_inplace(val.st_blocks);
boost::endian::native_to_big_inplace(i.st_blksize); boost::endian::native_to_big_inplace(val.st_blksize);
boost::endian::native_to_big_inplace(i.st_flags); boost::endian::native_to_big_inplace(val.st_flags);
encode_top(&i, sizeof(i), true); encode_top(&val, sizeof(val), true);
} }
void packet::encode_top(remote::statfs i, bool should_reserve) { void packet::encode_top(remote::statfs val, bool should_reserve) {
boost::endian::native_to_big_inplace(i.f_bavail); boost::endian::native_to_big_inplace(val.f_bavail);
boost::endian::native_to_big_inplace(i.f_bfree); boost::endian::native_to_big_inplace(val.f_bfree);
boost::endian::native_to_big_inplace(i.f_blocks); boost::endian::native_to_big_inplace(val.f_blocks);
boost::endian::native_to_big_inplace(i.f_favail); boost::endian::native_to_big_inplace(val.f_favail);
boost::endian::native_to_big_inplace(i.f_ffree); boost::endian::native_to_big_inplace(val.f_ffree);
boost::endian::native_to_big_inplace(i.f_files); boost::endian::native_to_big_inplace(val.f_files);
encode_top(&i, sizeof(remote::statfs), should_reserve); encode_top(&val, sizeof(remote::statfs), should_reserve);
} }
void packet::encode_top(remote::statfs_x i) { void packet::encode_top(remote::statfs_x val) {
buffer_.reserve(buffer_.size() + sizeof(remote::statfs) + 1024); buffer_.reserve(buffer_.size() + sizeof(remote::statfs) +
encode_top(&i.f_mntfromname[0], 1024, false); sizeof(val.f_mntfromname));
encode_top(*dynamic_cast<remote::statfs *>(&i), false); encode_top(&val.f_mntfromname[0], sizeof(val.f_mntfromname), false);
encode_top(*dynamic_cast<remote::statfs *>(&val), false);
} }
void packet::encode_top(remote::file_info i) { void packet::encode_top(remote::file_info val) {
boost::endian::native_to_big_inplace(i.FileAttributes); boost::endian::native_to_big_inplace(val.FileAttributes);
boost::endian::native_to_big_inplace(i.ReparseTag); boost::endian::native_to_big_inplace(val.ReparseTag);
boost::endian::native_to_big_inplace(i.AllocationSize); boost::endian::native_to_big_inplace(val.AllocationSize);
boost::endian::native_to_big_inplace(i.FileSize); boost::endian::native_to_big_inplace(val.FileSize);
boost::endian::native_to_big_inplace(i.CreationTime); boost::endian::native_to_big_inplace(val.CreationTime);
boost::endian::native_to_big_inplace(i.LastAccessTime); boost::endian::native_to_big_inplace(val.LastAccessTime);
boost::endian::native_to_big_inplace(i.LastWriteTime); boost::endian::native_to_big_inplace(val.LastWriteTime);
boost::endian::native_to_big_inplace(i.ChangeTime); boost::endian::native_to_big_inplace(val.ChangeTime);
boost::endian::native_to_big_inplace(i.IndexNumber); boost::endian::native_to_big_inplace(val.IndexNumber);
boost::endian::native_to_big_inplace(i.HardLinks); boost::endian::native_to_big_inplace(val.HardLinks);
boost::endian::native_to_big_inplace(i.EaSize); boost::endian::native_to_big_inplace(val.EaSize);
encode_top(&i, sizeof(i), true); encode_top(&val, sizeof(val), true);
} }
void packet::encrypt(const std::string &token) { void packet::encrypt(const std::string &token) {
@ -550,19 +548,19 @@ auto packet::operator=(data_buffer &&buffer) noexcept -> packet & {
return *this; return *this;
} }
auto packet::operator=(const packet &p) noexcept -> packet & { auto packet::operator=(const packet &pkt) noexcept -> packet & {
if (this != &p) { if (this != &pkt) {
buffer_ = p.buffer_; buffer_ = pkt.buffer_;
decode_offset_ = p.decode_offset_; decode_offset_ = pkt.decode_offset_;
} }
return *this; return *this;
} }
auto packet::operator=(packet &&p) noexcept -> packet & { auto packet::operator=(packet &&pkt) noexcept -> packet & {
if (this != &p) { if (this != &pkt) {
buffer_ = std::move(p.buffer_); buffer_ = std::move(pkt.buffer_);
decode_offset_ = p.decode_offset_; decode_offset_ = pkt.decode_offset_;
} }
return *this; return *this;

View File

@ -1,575 +0,0 @@
/*
Copyright <2018-2023> <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.
*/
#if defined(REPERTORY_ENABLE_S3)
#include "comm/s3/s3_comm.hpp"
#include "app_config.hpp"
#include "comm/curl/curl_comm.hpp"
#include "comm/s3/s3_requests.hpp"
#include "events/event_system.hpp"
#include "events/events.hpp"
#include "providers/i_provider.hpp"
#include "types/repertory.hpp"
#include "types/s3.hpp"
#include "utils/encryption.hpp"
#include "utils/error_utils.hpp"
#include "utils/path_utils.hpp"
#include "utils/polling.hpp"
#include "utils/string_utils.hpp"
namespace repertory {
static const get_key_callback empty_key = []() { return ""; };
s3_comm::s3_comm(const app_config &config)
: config_(config), s3_config_(config.get_s3_config()) {
s3_config_.bucket = utils::string::trim(s3_config_.bucket);
// TODO make configurable
const auto enable_path_style =
utils::string::begins_with(s3_config_.url, "http://localhost") ||
utils::string::begins_with(s3_config_.url, "https://localhost") ||
utils::string::begins_with(s3_config_.url, "http://127.0.0.1") ||
utils::string::begins_with(s3_config_.url, "https://127.0.0.1");
s3_client_ = std::make_unique<curl_comm>(s3_config_);
s3_client_->enable_s3_path_style(enable_path_style);
polling::instance().set_callback(
{"s3_directory_cache", polling::frequency::high,
[this]() { this->clear_expired_directories(); }});
}
s3_comm::s3_comm(s3_comm &&comm)
: config_(std::move(comm.config_)),
s3_config_(std::move(comm.s3_config_)),
s3_client_(std::move(comm.s3_client_)) {
comm.active_ = false;
polling::instance().set_callback(
{"s3_directory_cache", polling::frequency::high,
[this]() { this->clear_expired_directories(); }});
}
s3_comm::~s3_comm() {
if (active_) {
polling::instance().remove_callback("s3_directory_cache");
}
}
void s3_comm::clear_expired_directories() {
recur_mutex_lock l(cached_directories_mutex_);
std::vector<std::string> expired_list;
for (const auto &kv : cached_directories_) {
if (kv.second.expiration <= std::chrono::system_clock::now()) {
expired_list.emplace_back(kv.first);
}
}
for (const auto &expired : expired_list) {
event_system::instance().raise<debug_log>(__FUNCTION__, expired, "expired");
cached_directories_.erase(expired);
}
}
auto s3_comm::create_directory(const std::string &api_path) -> api_error {
raise_begin(__FUNCTION__, api_path);
long response_code{};
auto object_name = get_object_name(api_path, empty_key) + '/';
if (not create_directory_object_request(*s3_client_, s3_config_, object_name,
response_code)) {
return raise_end(__FUNCTION__, api_path, api_error::comm_error,
response_code);
}
return raise_end(__FUNCTION__, api_path,
response_code == 200 ? api_error::success
: api_error::comm_error,
response_code);
}
auto s3_comm::directory_exists(const std::string &api_path) const -> api_error {
raise_begin(__FUNCTION__, api_path);
auto object_name = get_object_name(api_path, empty_key) + "/";
head_object_result result{};
long response_code{};
if (head_object_request(*s3_client_, s3_config_, object_name, result,
response_code)) {
if (response_code == 404) {
return raise_end(__FUNCTION__, api_path, api_error::directory_not_found,
response_code);
}
return raise_end(__FUNCTION__, api_path, api_error::directory_exists,
response_code);
}
return raise_end(__FUNCTION__, api_path, api_error::comm_error,
response_code);
}
auto s3_comm::file_exists(const std::string &api_path,
const get_key_callback &get_key) const -> api_error {
raise_begin(__FUNCTION__, api_path);
if (get_cached_file_exists(api_path)) {
return raise_end(__FUNCTION__, api_path, api_error::item_exists, 200);
}
auto object_name = get_object_name(api_path, get_key);
head_object_result result{};
long response_code{};
if (head_object_request(*s3_client_, s3_config_, object_name, result,
response_code)) {
if (response_code == 404) {
return raise_end(__FUNCTION__, api_path, api_error::item_not_found,
response_code);
}
return raise_end(__FUNCTION__, api_path, api_error::item_exists,
response_code);
}
return raise_end(__FUNCTION__, api_path, api_error::directory_exists,
response_code);
}
auto s3_comm::get_object_list(std::vector<directory_item> &list) const
-> api_error {
raise_begin(__FUNCTION__, "/");
long response_code{};
auto success =
list_objects_request(*s3_client_, s3_config_, list, response_code);
return raise_end(__FUNCTION__, "/",
success ? api_error::success : api_error::comm_error,
response_code);
}
auto s3_comm::get_object_name(const std::string &api_path,
const get_key_callback &get_key) const
-> std::string {
auto object_name = utils::path::create_api_path(api_path).substr(1);
const auto key = get_key();
if (not key.empty()) {
auto parts = utils::string::split(object_name, '/', false);
parts[parts.size() - 1u] = key;
object_name = utils::string::join(parts, '/');
}
return object_name;
}
auto s3_comm::get_cached_directory_item_count(const std::string &api_path,
std::size_t &count) const
-> bool {
recur_mutex_lock l(cached_directories_mutex_);
if (cached_directories_.find(api_path) != cached_directories_.end()) {
count = cached_directories_.at(api_path).items.size();
return true;
}
return false;
}
auto s3_comm::get_cached_directory_items(const std::string &api_path,
meta_provider_callback meta_provider,
directory_item_list &list) const
-> bool {
unique_recur_mutex_lock l(cached_directories_mutex_);
if (cached_directories_.find(api_path) != cached_directories_.end()) {
auto &cachedEntry = cached_directories_.at(api_path);
list = cachedEntry.items;
cached_directories_[api_path].reset_timeout(
std::chrono::seconds(config_.get_s3_config().cache_timeout_secs));
l.unlock();
for (auto &item : list) {
meta_provider(item);
}
return true;
}
return false;
}
auto s3_comm::get_cached_file_exists(const std::string &api_path) const
-> bool {
unique_recur_mutex_lock l(cached_directories_mutex_);
const auto parent_api_path = utils::path::get_parent_api_path(api_path);
if (cached_directories_.find(parent_api_path) != cached_directories_.end()) {
auto &entry = cached_directories_.at(parent_api_path);
if (std::find_if(entry.items.begin(), entry.items.end(),
[&api_path](const auto &item) -> bool {
return not item.directory && (api_path == item.api_path);
}) != entry.items.end()) {
cached_directories_[api_path].reset_timeout(
std::chrono::seconds(config_.get_s3_config().cache_timeout_secs));
return true;
}
}
return false;
}
auto s3_comm::get_directory_item_count(
const std::string &api_path, meta_provider_callback meta_provider) const
-> std::size_t {
raise_begin(__FUNCTION__, api_path);
std::size_t ret = 0u;
if (not get_cached_directory_item_count(api_path, ret)) {
directory_item_list list;
const auto res = grab_directory_items(api_path, meta_provider, list);
if (res != api_error::success) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, res,
"failed to grab directory items");
}
return list.size();
}
if (config_.get_event_level() >= event_level::debug) {
event_system::instance().raise<debug_log>(__FUNCTION__, api_path,
"end|" + std::to_string(ret));
}
return ret;
}
auto s3_comm::get_directory_items(const std::string &api_path,
meta_provider_callback meta_provider,
directory_item_list &list) const
-> api_error {
raise_begin(__FUNCTION__, api_path);
auto ret = api_error::success;
if (not get_cached_directory_items(api_path, meta_provider, list)) {
ret = grab_directory_items(api_path, meta_provider, list);
}
if (config_.get_event_level() >= event_level::debug) {
event_system::instance().raise<debug_log>(
__FUNCTION__, api_path, "end|" + api_error_to_string(ret));
}
return ret;
}
auto s3_comm::get_directory_list(api_file_list &list) const -> api_error {
raise_begin(__FUNCTION__, "/");
long response_code{};
auto success =
list_directories_request(*s3_client_, s3_config_, list, response_code);
return raise_end(__FUNCTION__, "/",
success ? api_error::success : api_error::comm_error,
response_code);
}
auto s3_comm::get_file(const std::string &api_path,
const get_key_callback &get_key,
const get_name_callback &get_name,
const get_token_callback &get_token,
api_file &file) const -> api_error {
raise_begin(__FUNCTION__, api_path);
auto ret = api_error::success;
auto object_name = get_object_name(api_path, get_key);
head_object_result result{};
long response_code{};
if (head_object_request(*s3_client_, s3_config_, object_name, result,
response_code)) {
const auto key = get_key();
object_name = get_name(key, object_name);
file.accessed_date = utils::get_file_time_now();
file.api_path = utils::path::create_api_path(object_name);
file.api_parent = utils::path::get_parent_api_path(file.api_path);
file.changed_date = utils::aws::format_time(result.last_modified);
file.creation_date = utils::aws::format_time(result.last_modified);
file.encryption_token = get_token();
file.file_size =
file.encryption_token.empty()
? result.content_length
: utils::encryption::encrypting_reader::calculate_decrypted_size(
result.content_length);
file.modified_date = utils::aws::format_time(result.last_modified);
} else {
utils::error::raise_api_path_error(__FUNCTION__, api_path, response_code,
"head object request failed");
ret = api_error::comm_error;
}
if (config_.get_event_level() >= event_level::debug) {
event_system::instance().raise<debug_log>(
__FUNCTION__, api_path, "end|" + api_error_to_string(ret));
}
return ret;
}
auto s3_comm::get_file_list(
const get_api_file_token_callback &get_api_file_token,
const get_name_callback &get_name, api_file_list &list) const -> api_error {
raise_begin(__FUNCTION__, "/");
long response_code{};
auto success = list_files_request(*s3_client_, s3_config_, get_api_file_token,
get_name, list, response_code);
return raise_end(__FUNCTION__, "/",
success ? api_error::success : api_error::comm_error,
response_code);
}
auto s3_comm::grab_directory_items(const std::string &api_path,
meta_provider_callback meta_provider,
directory_item_list &list) const
-> api_error {
auto object_name = get_object_name(api_path, empty_key);
long response_code{};
if (list_objects_in_directory_request(*s3_client_, s3_config_, object_name,
meta_provider, list, response_code)) {
if (response_code == 404) {
return api_error::directory_not_found;
}
if (response_code != 200) {
return api_error::comm_error;
}
set_cached_directory_items(api_path, list);
return api_error::success;
}
return api_error::comm_error;
}
void s3_comm::raise_begin(const std::string &function_name,
const std::string &api_path) const {
if (config_.get_event_level() >= event_level::debug) {
event_system::instance().raise<debug_log>(function_name, api_path,
"begin|");
}
}
auto s3_comm::raise_end(const std::string &function_name,
const std::string &api_path, const api_error &error,
long code) const -> api_error {
if (config_.get_event_level() >= event_level::debug) {
event_system::instance().raise<debug_log>(
function_name, api_path,
"end|" + api_error_to_string(error) + '|' + std::to_string(code));
}
return error;
}
auto s3_comm::read_file_bytes(const std::string &api_path, std::size_t size,
std::uint64_t offset, data_buffer &data,
const get_key_callback &get_key,
const get_size_callback &get_size,
const get_token_callback &get_token,
stop_type &stop_requested) const -> api_error {
data.clear();
auto object_name = get_object_name(api_path, get_key);
const auto encryption_token = get_token();
const auto data_size = get_size();
if (encryption_token.empty()) {
long response_code{};
if (not read_object_request(*s3_client_, s3_config_, object_name, size,
offset, data, response_code, stop_requested)) {
auto res =
stop_requested ? api_error::download_stopped : api_error::comm_error;
utils::error::raise_api_path_error(__FUNCTION__, api_path, res,
"failed to read file bytes");
return res;
}
if (response_code < 200 || response_code >= 300) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, response_code,
"failed to read file bytes");
return api_error::comm_error;
}
return api_error::success;
}
const auto key = utils::encryption::generate_key(encryption_token);
return utils::encryption::read_encrypted_range(
{offset, offset + size - 1}, key,
[&](data_buffer &ct, std::uint64_t start_offset,
std::uint64_t end_offset) -> api_error {
return read_file_bytes(
api_path, (end_offset - start_offset + 1u), start_offset, ct,
get_key, get_size, []() -> std::string { return ""; },
stop_requested);
},
data_size, data);
}
void s3_comm::remove_cached_directory(const std::string &api_path) {
recur_mutex_lock l(cached_directories_mutex_);
cached_directories_.erase(api_path);
}
auto s3_comm::remove_directory(const std::string &api_path) -> api_error {
raise_begin(__FUNCTION__, api_path);
auto object_name = get_object_name(api_path, empty_key) + "/";
long response_code{};
if (delete_object_request(*s3_client_, s3_config_, object_name,
response_code)) {
if (response_code == 404) {
return raise_end(__FUNCTION__, api_path, api_error::directory_not_found,
response_code);
}
if (response_code != 204) {
return raise_end(__FUNCTION__, api_path, api_error::comm_error,
response_code);
}
remove_cached_directory(utils::path::get_parent_api_path(api_path));
remove_cached_directory(api_path);
return raise_end(__FUNCTION__, api_path, api_error::success, response_code);
}
return raise_end(__FUNCTION__, api_path, api_error::comm_error,
response_code);
}
auto s3_comm::remove_file(const std::string &api_path,
const get_key_callback &get_key) -> api_error {
raise_begin(__FUNCTION__, api_path);
auto object_name = get_object_name(api_path, get_key);
long response_code{};
if (delete_object_request(*s3_client_, s3_config_, object_name,
response_code)) {
if (response_code == 404) {
return raise_end(__FUNCTION__, api_path, api_error::item_not_found,
response_code);
}
if (response_code != 204) {
return raise_end(__FUNCTION__, api_path, api_error::comm_error,
response_code);
}
remove_cached_directory(utils::path::get_parent_api_path(api_path));
return raise_end(__FUNCTION__, api_path, api_error::success, response_code);
}
return raise_end(__FUNCTION__, api_path, api_error::comm_error,
response_code);
}
auto s3_comm::rename_file(const std::string & /*api_path*/,
const std::string & /*new_api_path*/) -> api_error {
return api_error::not_implemented;
/* if (config_.get_event_level() >= event_level::debug) { */
/* event_system::instance().raise<debug_log>(__FUNCTION__, api_path,
* "begin"); */
/* } */
/* auto ret = api_error::success; */
/* */
/* std::string bucket_name, object_name; */
/* get_object_name(api_path, bucket_name, object_name); */
/* */
/* std::string new_object_name; */
/* get_object_name(new_api_path, bucket_name, new_object_name); */
/* */
/* Aws::S3::Model::CopyObjectRequest request{}; */
/* request.SetBucket(bucket_name); */
/* request.SetCopySource(bucket_name + '/' + object_name); */
/* request.SetKey(new_object_name); */
/* */
/* const auto outcome = s3_client_->CopyObject(request); */
/* if (outcome.IsSuccess()) { */
/* ret = remove_file(api_path); */
/* } else { */
/* const auto &error = outcome.GetError(); */
/* event_system::instance().raise<repertory_exception>(__FUNCTION__,
* error.GetExceptionName()
* +
* "|" + */
/* error.GetMessage());
*/
/* ret = api_error::comm_error; */
/* } */
/* */
/* if (config_.get_event_level() >= event_level::debug) { */
/* event_system::instance().raise<debug_log>(__FUNCTION__, api_path, */
/* "end|" +
* std::to_string(std::uint8_t(ret))); */
/* } */
/* return ret; */
}
void s3_comm::set_cached_directory_items(const std::string &api_path,
directory_item_list list) const {
recur_mutex_lock l(cached_directories_mutex_);
cached_directories_[api_path].items = std::move(list);
cached_directories_[api_path].reset_timeout(
std::chrono::seconds(config_.get_s3_config().cache_timeout_secs));
}
auto s3_comm::upload_file(const std::string &api_path,
const std::string &source_path,
const std::string &encryption_token,
const get_key_callback &get_key,
const set_key_callback &set_key,
stop_type &stop_requested) -> api_error {
raise_begin(__FUNCTION__, api_path);
auto object_name = get_object_name(api_path, get_key);
long response_code{};
if (not put_object_request(*s3_client_, s3_config_, object_name, source_path,
encryption_token, get_key, set_key, response_code,
stop_requested)) {
return raise_end(__FUNCTION__, api_path,
stop_requested ? api_error::upload_stopped
: api_error::upload_failed,
response_code);
}
if (response_code != 200) {
return raise_end(__FUNCTION__, api_path, api_error::comm_error,
response_code);
}
remove_cached_directory(utils::path::get_parent_api_path(api_path));
return raise_end(__FUNCTION__, api_path, api_error::success, response_code);
}
} // namespace repertory
#endif // REPERTORY_ENABLE_S3

View File

@ -1,399 +0,0 @@
/*
Copyright <2018-2023> <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.
*/
#if defined(REPERTORY_ENABLE_S3)
#include "comm/s3/s3_requests.hpp"
#include "comm/curl/curl_comm.hpp"
#include "comm/curl/requests/http_get.hpp"
#include "utils/encryption.hpp"
#include "utils/error_utils.hpp"
#include "utils/path_utils.hpp"
namespace repertory {
namespace {
[[nodiscard]] auto
get_object_list(i_http_comm &client, const s3_config &config,
std::string &response_data, long &response_code,
std::optional<std::string> delimiter = std::nullopt,
std::optional<std::string> prefix = std::nullopt) -> bool {
curl::requests::http_get get{};
get.aws_service = "aws:amz:" + config.region + ":s3";
get.path = '/';
get.query["list-type"] = "2";
if (delimiter.has_value() && not delimiter.value().empty()) {
get.query["delimiter"] = delimiter.value();
}
if (prefix.has_value() && not prefix.value().empty()) {
get.query["prefix"] = prefix.value();
}
get.response_handler = [&response_data](const data_buffer &data,
long /*response_code*/) {
response_data = std::string(data.begin(), data.end());
};
stop_type stop_requested{};
return client.make_request(get, response_code, stop_requested);
}
} // namespace
auto create_directory_object_request_impl(i_http_comm &client,
const s3_config &config,
const std::string &object_name,
long &response_code) -> bool {
try {
curl::requests::http_put_file put_file{};
put_file.aws_service = "aws:amz:" + config.region + ":s3";
put_file.file_name =
*(utils::string::split(object_name, '/', false).end() - 1U);
put_file.path = '/' + object_name;
stop_type stop_requested{false};
return client.make_request(put_file, response_code, stop_requested);
} catch (const std::exception &e) {
utils::error::raise_error(__FUNCTION__, e, "exception occurred");
}
return false;
}
auto delete_object_request_impl(i_http_comm &client, const s3_config &config,
const std::string &object_name,
long &response_code) -> bool {
try {
head_object_result result{};
if (not head_object_request_impl(client, config, object_name, result,
response_code)) {
return false;
}
if (response_code == 404) {
return true;
}
curl::requests::http_delete del{};
del.aws_service = "aws:amz:" + config.region + ":s3";
del.path = '/' + object_name;
stop_type stop_requested{false};
return client.make_request(del, response_code, stop_requested);
} catch (const std::exception &e) {
utils::error::raise_error(__FUNCTION__, e, "exception occurred");
}
return false;
}
auto head_object_request_impl(i_http_comm &client, const s3_config &config,
const std::string &object_name,
head_object_result &result, long &response_code)
-> bool {
try {
curl::requests::http_head head{};
head.aws_service = "aws:amz:" + config.region + ":s3";
head.path = '/' + object_name;
head.response_headers = http_headers{};
stop_type stop_requested{false};
if (not client.make_request(head, response_code, stop_requested)) {
return false;
}
if (response_code == 200) {
result.from_headers(head.response_headers.value());
}
return true;
} catch (const std::exception &e) {
utils::error::raise_error(__FUNCTION__, e, "exception occurred");
}
return false;
}
auto list_directories_request_impl(i_http_comm &client, const s3_config &config,
list_directories_result &result,
long &response_code) -> bool {
try {
std::string response_data{};
if (not get_object_list(client, config, response_data, response_code)) {
return false;
}
if (response_code != 200) {
return false;
}
pugi::xml_document doc;
auto res = doc.load_string(response_data.c_str());
if (res.status != pugi::xml_parse_status::status_ok) {
return false;
}
auto node_list = doc.select_nodes("/ListBucketResult/Contents");
for (const auto &node : node_list) {
auto object_name =
node.node().select_node("Key").node().text().as_string();
if (utils::string::ends_with(object_name, "/")) {
api_file directory{};
directory.api_path = utils::path::create_api_path(object_name);
directory.api_parent =
utils::path::get_parent_api_path(directory.api_path);
directory.accessed_date = utils::get_file_time_now();
directory.changed_date = utils::convert_api_date(
node.node().select_node("LastModified").node().text().as_string());
directory.creation_date = directory.changed_date;
directory.modified_date = directory.changed_date;
result.emplace_back(std::move(directory));
}
}
return true;
} catch (const std::exception &e) {
utils::error::raise_error(__FUNCTION__, e, "exception occurred");
}
return false;
}
auto list_files_request_impl(
i_http_comm &client, const s3_config &config,
const get_api_file_token_callback &get_api_file_token,
const get_name_callback &get_name, list_files_result &result,
long &response_code) -> bool {
try {
std::string response_data{};
if (not get_object_list(client, config, response_data, response_code)) {
return false;
}
if (response_code != 200) {
return false;
}
pugi::xml_document doc;
auto res = doc.load_string(response_data.c_str());
if (res.status != pugi::xml_parse_status::status_ok) {
return false;
}
auto node_list = doc.select_nodes("/ListBucketResult/Contents");
for (const auto &node : node_list) {
std::string object_name =
node.node().select_node("Key").node().text().as_string();
if (not utils::string::ends_with(object_name, "/")) {
api_file file{};
object_name = get_name(
*(utils::string::split(object_name, '/', false).end() - 1u),
object_name);
file.api_path = utils::path::create_api_path(object_name);
file.api_parent = utils::path::get_parent_api_path(file.api_path);
file.accessed_date = utils::get_file_time_now();
file.encryption_token = get_api_file_token(file.api_path);
auto size = node.node().select_node("Size").node().text().as_ullong();
file.file_size = file.encryption_token.empty()
? size
: utils::encryption::encrypting_reader::
calculate_decrypted_size(size);
file.changed_date = utils::convert_api_date(
node.node().select_node("LastModified").node().text().as_string());
file.creation_date = file.changed_date;
file.modified_date = file.changed_date;
result.emplace_back(std::move(file));
}
}
return true;
} catch (const std::exception &e) {
utils::error::raise_error(__FUNCTION__, e, "exception occurred");
}
return false;
}
auto list_objects_in_directory_request_impl(
i_http_comm &client, const s3_config &config,
const std::string &object_name, meta_provider_callback meta_provider,
list_objects_result &result, long &response_code) -> bool {
try {
std::string response_data{};
auto prefix = object_name.empty() ? object_name : object_name + "/";
if (not get_object_list(client, config, response_data, response_code, "/",
prefix)) {
return false;
}
if (response_code != 200) {
return false;
}
pugi::xml_document doc;
auto res = doc.load_string(response_data.c_str());
if (res.status != pugi::xml_parse_status::status_ok) {
return false;
}
const auto add_directory_item =
[&](bool directory, const std::string &name,
std::function<std::uint64_t(const directory_item &)> get_size) {
directory_item di{};
di.api_path =
utils::path::create_api_path(utils::path::combine("/", {name}));
di.api_parent = utils::path::get_parent_api_path(di.api_path);
di.directory = directory;
di.size = get_size(di);
meta_provider(di);
result.emplace_back(std::move(di));
};
auto node_list =
doc.select_nodes("/ListBucketResult/CommonPrefixes/Prefix");
for (const auto &node : node_list) {
add_directory_item(
true, node.node().text().as_string(),
[](const directory_item &) -> std::uint64_t { return 0U; });
}
node_list = doc.select_nodes("/ListBucketResult/Contents");
for (const auto &node : node_list) {
auto child_object_name =
node.node().select_node("Key").node().text().as_string();
if (child_object_name != prefix) {
auto size = node.node().select_node("Size").node().text().as_ullong();
add_directory_item(
false, child_object_name,
[&size](const directory_item &) -> std::uint64_t { return size; });
}
}
return true;
} catch (const std::exception &e) {
utils::error::raise_error(__FUNCTION__, e, "exception occurred");
}
return false;
}
auto list_objects_request_impl(i_http_comm &client, const s3_config &config,
list_objects_result &result, long &response_code)
-> bool {
try {
std::string response_data{};
if (not get_object_list(client, config, response_data, response_code)) {
return false;
}
if (response_code != 200) {
return false;
}
pugi::xml_document doc;
auto res = doc.load_string(response_data.c_str());
if (res.status != pugi::xml_parse_status::status_ok) {
return false;
}
auto node_list = doc.select_nodes("/ListBucketResult/Contents");
for (const auto &node : node_list) {
auto object_name =
node.node().select_node("Key").node().text().as_string();
auto size = node.node().select_node("Size").node().text().as_ullong();
directory_item di{};
di.api_path = utils::path::create_api_path(object_name);
di.api_parent = utils::path::get_parent_api_path(di.api_path);
di.directory = utils::string::ends_with(object_name, "/");
di.size = di.directory ? 0U : size;
di.resolved = false;
result.emplace_back(std::move(di));
}
return true;
} catch (const std::exception &e) {
utils::error::raise_error(__FUNCTION__, e, "exception occurred");
}
return false;
}
auto put_object_request_impl(i_http_comm &client, const s3_config &config,
std::string object_name,
const std::string &source_path,
const std::string &encryption_token,
get_key_callback get_key, set_key_callback set_key,
long &response_code, stop_type &stop_requested)
-> bool {
try {
curl::requests::http_put_file put_file{};
put_file.aws_service = "aws:amz:" + config.region + ":s3";
put_file.encryption_token = encryption_token;
put_file.file_name =
*(utils::string::split(object_name, '/', false).end() - 1U);
put_file.path = '/' + object_name;
put_file.source_path = source_path;
if (not encryption_token.empty()) {
static stop_type no_stop{false};
put_file.reader = std::make_shared<utils::encryption::encrypting_reader>(
put_file.file_name, source_path, no_stop, encryption_token,
std::nullopt, -1);
auto key = get_key();
if (key.empty()) {
key = put_file.reader->get_encrypted_file_name();
set_key(key);
}
}
return client.make_request(put_file, response_code, stop_requested);
} catch (const std::exception &e) {
utils::error::raise_error(__FUNCTION__, e, "exception occurred");
}
return false;
}
auto read_object_request_impl(i_http_comm &client, const s3_config &config,
const std::string &object_name, std::size_t size,
std::uint64_t offset, data_buffer &data,
long &response_code, stop_type &stop_requested)
-> bool {
try {
curl::requests::http_get get{};
get.aws_service = "aws:amz:" + config.region + ":s3";
get.headers["response-content-type"] = "binary/octet-stream";
get.path = '/' + object_name;
get.range = {{offset, offset + size - 1}};
get.response_handler = [&data](const data_buffer &response_data,
long /*response_code*/) {
data = response_data;
};
return client.make_request(get, response_code, stop_requested);
} catch (const std::exception &e) {
utils::error::raise_error(__FUNCTION__, e, "exception occurred");
}
return false;
}
} // namespace repertory
#endif

View File

@ -20,6 +20,7 @@
SOFTWARE. SOFTWARE.
*/ */
#include "types/repertory.hpp" #include "types/repertory.hpp"
#include "utils/utils.hpp"
namespace repertory { namespace repertory {
auto get_repertory_git_revision() -> const std::string & { auto get_repertory_git_revision() -> const std::string & {

View File

@ -1,370 +0,0 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "db/directory_db.hpp"
#include "utils/path_utils.hpp"
namespace repertory {
void directory_db::directory_tree::add_path(
const std::string &api_path, const std::vector<std::string> &files,
rocksdb::DB &db) {
const auto create_not_found = [&](const auto &create_path) {
std::string value;
if (not db.Get(rocksdb::ReadOptions(), create_path, &value).ok()) {
json directoryData = {
{"path", api_path},
{"files", files},
};
db.Put(rocksdb::WriteOptions(), create_path, directoryData.dump());
}
};
const auto parts = utils::string::split(api_path, '/', false);
std::string previous_directory;
for (const auto &directory_part : parts) {
if (directory_part.empty()) {
sub_directory_lookup_["/"];
previous_directory = "/";
create_not_found("/");
} else {
auto &sub_directories = sub_directory_lookup_[previous_directory];
if (std::find(sub_directories.begin(), sub_directories.end(),
directory_part) == sub_directories.end()) {
sub_directories.emplace_back(directory_part);
}
previous_directory = utils::path::create_api_path(
utils::path::combine(previous_directory, {directory_part}));
sub_directory_lookup_[previous_directory];
create_not_found(previous_directory);
}
}
}
auto directory_db::directory_tree::get_count(const std::string &api_path) const
-> std::size_t {
return (sub_directory_lookup_.find(api_path) == sub_directory_lookup_.end())
? 0
: sub_directory_lookup_.at(api_path).size();
}
auto directory_db::directory_tree::get_directories() const
-> std::vector<std::string> {
std::vector<std::string> ret;
std::transform(sub_directory_lookup_.begin(), sub_directory_lookup_.end(),
std::back_inserter(ret),
[](const auto &kv) { return kv.first; });
return ret;
}
auto directory_db::directory_tree::get_sub_directories(
const std::string &api_path) const -> std::vector<std::string> {
std::vector<std::string> ret;
if (sub_directory_lookup_.find(api_path) != sub_directory_lookup_.end()) {
const auto &lookup = sub_directory_lookup_.at(api_path);
std::transform(lookup.begin(), lookup.end(), std::back_inserter(ret),
[&api_path](const auto &directory) {
return utils::path::create_api_path(
utils::path::combine(api_path, {directory}));
});
}
return ret;
}
auto directory_db::directory_tree::is_directory(
const std::string &api_path) const -> bool {
return sub_directory_lookup_.find(api_path) != sub_directory_lookup_.end();
}
void directory_db::directory_tree::remove_directory(const std::string &api_path,
rocksdb::DB &db,
bool allow_remove_root) {
if ((allow_remove_root || (api_path != "/")) && is_directory(api_path)) {
sub_directory_lookup_.erase(api_path);
db.Delete(rocksdb::WriteOptions(), api_path);
const auto parent_api_path = utils::path::get_parent_api_path(api_path);
const auto parts = utils::string::split(api_path, '/', false);
utils::remove_element_from(sub_directory_lookup_[parent_api_path],
parts[parts.size() - 1]);
}
}
directory_db::directory_db(const app_config &config) {
utils::db::create_rocksdb(config, DIRDB_NAME, db_);
auto iterator = std::unique_ptr<rocksdb::Iterator>(
db_->NewIterator(rocksdb::ReadOptions()));
for (iterator->SeekToFirst(); iterator->Valid(); iterator->Next()) {
auto directory_data = json::parse(iterator->value().ToString());
tree_.add_path(directory_data["path"].get<std::string>(),
directory_data["files"].get<std::vector<std::string>>(),
*db_);
}
}
directory_db::~directory_db() { db_.reset(); }
auto directory_db::create_directory(const std::string &api_path,
bool create_always) -> api_error {
recur_mutex_lock directory_lock(directory_mutex_);
auto ret = api_error::directory_exists;
if (not is_directory(api_path)) {
ret = api_error::directory_not_found;
if (create_always || (api_path == "/") ||
is_directory(utils::path::get_parent_api_path(api_path))) {
ret = api_error::item_exists;
if (not is_file(api_path)) {
tree_.add_path(api_path, {}, *db_);
ret = api_error::success;
}
}
}
return ret;
}
auto directory_db::create_file(const std::string &api_path) -> api_error {
recur_mutex_lock directory_lock(directory_mutex_);
if (is_directory(api_path)) {
return api_error::directory_exists;
}
const auto parent_api_path = utils::path::get_parent_api_path(api_path);
auto directory_data = get_directory_data(parent_api_path);
if (directory_data.empty()) {
return api_error::directory_not_found;
}
const auto file_name = utils::path::strip_to_file_name(api_path);
if (utils::collection_includes(directory_data["files"], file_name)) {
return api_error::item_exists;
}
directory_data["files"].emplace_back(file_name);
db_->Put(rocksdb::WriteOptions(), parent_api_path, directory_data.dump());
return api_error::success;
}
auto directory_db::get_directory_data(const std::string &api_path) const
-> json {
std::string data;
db_->Get(rocksdb::ReadOptions(), api_path, &data);
if (data.empty()) {
return {};
}
return json::parse(data);
}
auto directory_db::get_directory_item_count(const std::string &api_path) const
-> std::uint64_t {
auto directory_data = get_directory_data(api_path);
const auto sub_directory_count = get_sub_directory_count(api_path);
const auto file_count =
(directory_data.empty() ? 0 : directory_data["files"].size());
return sub_directory_count + file_count;
}
auto directory_db::get_file(const std::string &api_path, api_file &file,
api_file_provider_callback api_file_provider) const
-> api_error {
const auto parent_api_path = utils::path::get_parent_api_path(api_path);
auto directory_data = get_directory_data(parent_api_path);
if (not directory_data.empty()) {
const auto file_name = utils::path::strip_to_file_name(api_path);
if (utils::collection_includes(directory_data["files"], file_name)) {
file.api_path = utils::path::create_api_path(
utils::path::combine(parent_api_path, {file_name})),
api_file_provider(file);
return api_error::success;
}
}
return api_error::item_not_found;
}
auto directory_db::get_file_list(
api_file_list &list, api_file_provider_callback api_file_provider) const
-> api_error {
auto iterator = std::unique_ptr<rocksdb::Iterator>(
db_->NewIterator(rocksdb::ReadOptions()));
for (iterator->SeekToFirst(); iterator->Valid(); iterator->Next()) {
auto directory_data = json::parse(iterator->value().ToString());
for (const auto &directory_file : directory_data["files"]) {
api_file file{
utils::path::create_api_path(utils::path::combine(
iterator->key().ToString(), {directory_file.get<std::string>()})),
};
api_file_provider(file);
list.emplace_back(file);
}
}
return api_error::success;
}
auto directory_db::get_sub_directory_count(const std::string &api_path) const
-> std::size_t {
recur_mutex_lock directoryLock(directory_mutex_);
return tree_.get_count(api_path);
}
auto directory_db::get_total_item_count() const -> std::uint64_t {
unique_recur_mutex_lock directory_lock(directory_mutex_);
const auto directories = tree_.get_directories();
directory_lock.unlock();
return std::accumulate(
directories.begin(), directories.end(), std::uint64_t(directories.size()),
[this](std::uint64_t c, const std::string &directory) {
const auto dirData = this->get_directory_data(directory);
return c + (dirData.empty() ? 0 : dirData["files"].size());
});
}
auto directory_db::is_directory(const std::string &api_path) const -> bool {
recur_mutex_lock directory_lock(directory_mutex_);
return tree_.is_directory(api_path);
}
auto directory_db::is_file(const std::string &api_path) const -> bool {
auto directory_data =
get_directory_data(utils::path::get_parent_api_path(api_path));
if (directory_data.empty()) {
return false;
}
const auto file_name = utils::path::strip_to_file_name(api_path);
return utils::collection_includes(directory_data["files"], file_name);
}
void directory_db::populate_directory_files(
const std::string &api_path, meta_provider_callback meta_provider,
directory_item_list &list) const {
auto directory_data = get_directory_data(api_path);
if (not directory_data.empty()) {
for (const auto &directory_file : directory_data["files"]) {
directory_item di{};
di.api_path = utils::path::create_api_path(
utils::path::combine(api_path, {directory_file.get<std::string>()}));
di.directory = false;
meta_provider(di);
di.size = utils::string::to_uint64(di.meta[META_SIZE]);
list.emplace_back(std::move(di));
}
}
}
void directory_db::populate_sub_directories(
const std::string &api_path, meta_provider_callback meta_provider,
directory_item_list &list) const {
unique_recur_mutex_lock directory_lock(directory_mutex_);
const auto directories = tree_.get_sub_directories(api_path);
directory_lock.unlock();
std::size_t offset{};
for (const auto &directory : directories) {
if (std::find_if(list.begin(), list.end(),
[&directory](const auto &di) -> bool {
return directory == di.api_path;
}) == list.end()) {
directory_item di{};
di.api_path = directory;
di.api_parent = utils::path::get_parent_api_path(directory);
di.directory = true;
di.size = get_sub_directory_count(directory);
meta_provider(di);
list.insert(list.begin() + static_cast<std::int64_t>(offset++),
std::move(di));
}
}
}
auto directory_db::remove_directory(const std::string &api_path,
bool allow_remove_root) -> api_error {
recur_mutex_lock directory_lock(directory_mutex_);
if ((api_path == "/") && not allow_remove_root) {
return api_error::access_denied;
}
if (is_file(api_path) || not is_directory(api_path)) {
return api_error::directory_not_found;
}
if (tree_.get_count(api_path) == 0) {
auto directory_data = get_directory_data(api_path);
if (directory_data.empty() || directory_data["files"].empty()) {
tree_.remove_directory(api_path, *db_, allow_remove_root);
return api_error::success;
}
}
return api_error::directory_not_empty;
}
auto directory_db::remove_file(const std::string &api_path) -> bool {
recur_mutex_lock directory_lock(directory_mutex_);
if (is_directory(api_path)) {
return false;
}
const auto parent_api_path = utils::path::get_parent_api_path(api_path);
auto directory_data = get_directory_data(parent_api_path);
if (directory_data.empty()) {
return false;
}
const auto file_name = utils::path::strip_to_file_name(api_path);
if (utils::collection_excludes(directory_data["files"], file_name)) {
return false;
}
utils::remove_element_from(directory_data["files"], file_name);
db_->Put(rocksdb::WriteOptions(), parent_api_path, directory_data.dump());
return true;
}
auto directory_db::rename_file(const std::string &from_api_path,
const std::string &to_api_path) -> api_error {
recur_mutex_lock directory_lock(directory_mutex_);
if (is_directory(from_api_path) || is_directory(to_api_path)) {
return api_error::directory_exists;
}
if (not is_directory(utils::path::get_parent_api_path(to_api_path))) {
return api_error::directory_not_found;
}
if (is_file(to_api_path)) {
return api_error::item_exists;
}
if (not remove_file(from_api_path)) {
return api_error::item_not_found;
}
return create_file(to_api_path);
}
} // namespace repertory

View File

@ -1,347 +0,0 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "db/meta_db.hpp"
#include "types/repertory.hpp"
#include "types/startup_exception.hpp"
#include "utils/error_utils.hpp"
#include "utils/file_utils.hpp"
#include "utils/path_utils.hpp"
#include "utils/utils.hpp"
namespace repertory {
meta_db::meta_db(const app_config &config) {
const auto create_resources = [this, &config](const std::string &name) {
auto families = std::vector<rocksdb::ColumnFamilyDescriptor>();
families.emplace_back(rocksdb::kDefaultColumnFamilyName,
rocksdb::ColumnFamilyOptions());
families.emplace_back("keys", rocksdb::ColumnFamilyOptions());
families.emplace_back("source", rocksdb::ColumnFamilyOptions());
auto handles = std::vector<rocksdb::ColumnFamilyHandle *>();
utils::db::create_rocksdb(config, name, families, handles, db_);
std::size_t idx{};
default_family_ = handles[idx++];
keys_family_ = handles[idx++];
source_family_ = handles[idx++];
};
create_resources(METADB_NAME);
}
meta_db::~meta_db() { db_.reset(); }
auto meta_db::create_iterator(bool source_family) const
-> std::shared_ptr<rocksdb::Iterator> {
return std::shared_ptr<rocksdb::Iterator>(
db_->NewIterator(rocksdb::ReadOptions(),
source_family ? source_family_ : default_family_));
}
auto meta_db::get_api_path_from_key(const std::string &key,
std::string &api_path) const -> api_error {
if (key.empty()) {
return api_error::item_not_found;
}
return perform_action(__FUNCTION__, [&]() -> rocksdb::Status {
return db_->Get(rocksdb::ReadOptions(), keys_family_, key, &api_path);
});
}
auto meta_db::get_api_path_from_source(const std::string &source_path,
std::string &api_path) const
-> api_error {
if (source_path.empty()) {
return api_error::item_not_found;
}
return perform_action(__FUNCTION__, [&]() -> rocksdb::Status {
return db_->Get(rocksdb::ReadOptions(), source_family_, source_path,
&api_path);
});
}
auto meta_db::get_item_meta_json(const std::string &api_path,
json &json_data) const -> api_error {
std::string value;
const auto res = perform_action(__FUNCTION__, [&]() -> rocksdb::Status {
return db_->Get(rocksdb::ReadOptions(), default_family_, api_path, &value);
});
if (res != api_error::success) {
return res;
}
json_data = json::parse(value);
return api_error::success;
}
auto meta_db::get_item_meta(const std::string &api_path,
api_meta_map &meta) const -> api_error {
json json_data;
const auto ret = get_item_meta_json(api_path, json_data);
if (ret == api_error::success) {
for (auto it = json_data.begin(); it != json_data.end(); it++) {
meta[it.key()] = it.value().get<std::string>();
}
}
return ret;
}
auto meta_db::get_item_meta(const std::string &api_path, const std::string &key,
std::string &value) const -> api_error {
json json_data;
const auto ret = get_item_meta_json(api_path, json_data);
if (ret == api_error::success) {
if (json_data.find(key) != json_data.end()) {
value = json_data[key].get<std::string>();
}
}
return ret;
}
auto meta_db::get_item_meta_exists(const std::string &api_path) const -> bool {
std::string value;
return db_->Get(rocksdb::ReadOptions(), api_path, &value).ok();
}
auto meta_db::get_pinned_files() const -> std::vector<std::string> {
std::vector<std::string> ret;
auto iterator = const_cast<meta_db *>(this)->create_iterator(false);
for (iterator->SeekToFirst(); iterator->Valid(); iterator->Next()) {
auto api_path = iterator->key().ToString();
std::string pinned;
const auto res = get_item_meta(api_path, META_PINNED, pinned);
if ((res == api_error::success) && not pinned.empty() &&
utils::string::to_bool(pinned)) {
ret.emplace_back(api_path);
}
}
return ret;
}
auto meta_db::get_source_path_exists(const std::string &source_path) const
-> bool {
std::string value;
return db_->Get(rocksdb::ReadOptions(), source_family_, source_path, &value)
.ok();
}
auto meta_db::perform_action(
const std::string &function_name,
const std::function<rocksdb::Status()> &action) const -> api_error {
const auto res = action();
if (res.ok()) {
return api_error::success;
}
if (not res.IsNotFound()) {
utils::error::raise_error(function_name, res.ToString());
}
return res.IsNotFound() ? api_error::item_not_found : api_error::error;
}
auto meta_db::get_total_item_count() const -> std::uint64_t {
std::uint64_t ret = 0u;
auto iter = create_iterator(false);
for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
ret++;
}
return ret;
}
auto meta_db::remove_item_meta(const std::string &api_path) -> api_error {
json json_data;
auto res = get_item_meta_json(api_path, json_data);
if (res != api_error::success) {
return res == api_error::item_not_found ? api_error::success : res;
}
if (not json_data[META_KEY].empty()) {
if ((res = perform_action(__FUNCTION__, [&]() -> rocksdb::Status {
return db_->Delete(rocksdb::WriteOptions(), keys_family_,
json_data[META_KEY].get<std::string>());
})) != api_error::success) {
return res;
}
}
if (not json_data[META_SOURCE].empty()) {
if ((res = perform_action(__FUNCTION__, [&]() -> rocksdb::Status {
return db_->Delete(rocksdb::WriteOptions(), source_family_,
json_data[META_SOURCE].get<std::string>());
})) != api_error::success) {
return res;
}
}
return perform_action(__FUNCTION__, [&]() -> rocksdb::Status {
return db_->Delete(rocksdb::WriteOptions(), default_family_, api_path);
});
}
auto meta_db::remove_item_meta(const std::string &api_path,
const std::string &key) -> api_error {
json json_data;
auto res = get_item_meta_json(api_path, json_data);
if (res != api_error::success) {
return res == api_error::item_not_found ? api_error::success : res;
}
if ((key == META_KEY) && not json_data[META_KEY].empty()) {
if ((res = perform_action(__FUNCTION__, [&]() -> rocksdb::Status {
return db_->Delete(rocksdb::WriteOptions(), keys_family_,
json_data[META_KEY].get<std::string>());
})) != api_error::success) {
return res;
}
}
if ((key == META_SOURCE) && not json_data[META_SOURCE].empty()) {
if ((res = perform_action(__FUNCTION__, [&]() -> rocksdb::Status {
return db_->Delete(rocksdb::WriteOptions(), source_family_,
json_data[META_SOURCE].get<std::string>());
})) != api_error::success) {
return res;
}
}
json_data.erase(key);
return perform_action(__FUNCTION__, [&]() -> rocksdb::Status {
return db_->Put(rocksdb::WriteOptions(), default_family_, api_path,
json_data.dump());
});
}
auto meta_db::rename_item_meta(const std::string &source_path,
const std::string &from_api_path,
const std::string &to_api_path) -> api_error {
api_meta_map meta{};
auto res = get_item_meta(from_api_path, meta);
if (res != api_error::success) {
return res;
}
if ((res = remove_item_meta(from_api_path)) != api_error::success) {
return res;
}
if (not source_path.empty()) {
meta[META_SOURCE] = source_path;
}
return set_item_meta(to_api_path, meta);
}
auto meta_db::set_item_meta(const std::string &api_path, const std::string &key,
const std::string &value) -> api_error {
if (key == META_SOURCE) {
return set_source_path(api_path, value);
}
if (key == META_KEY) {
const auto res = remove_item_meta(api_path, META_KEY);
if ((res != api_error::success) && (res != api_error::item_not_found)) {
return res;
}
}
auto res = store_item_meta(api_path, key, value);
if (res != api_error::success) {
return res;
}
if (key == META_KEY) {
return perform_action(__FUNCTION__, [&]() -> rocksdb::Status {
return db_->Put(rocksdb::WriteOptions(), keys_family_, value, api_path);
});
}
return api_error::success;
}
auto meta_db::set_item_meta(const std::string &api_path,
const api_meta_map &meta) -> api_error {
auto ret = api_error::success;
auto it = meta.begin();
for (std::size_t i = 0u; (ret == api_error::success) && (i < meta.size());
i++) {
ret = set_item_meta(api_path, it->first, it->second);
it++;
}
return ret;
}
auto meta_db::set_source_path(const std::string &api_path,
const std::string &source_path) -> api_error {
std::string current_source_path;
auto res = get_item_meta(api_path, META_SOURCE, current_source_path);
if ((res != api_error::success) && (res != api_error::item_not_found)) {
return res;
}
// TODO multiple db ops should be in transaction
if (not current_source_path.empty()) {
if ((res = perform_action(__FUNCTION__, [&]() -> rocksdb::Status {
return db_->Delete(rocksdb::WriteOptions(), source_family_,
current_source_path);
})) != api_error::success) {
return res;
}
}
if (not source_path.empty()) {
if ((res = perform_action(__FUNCTION__, [&]() -> rocksdb::Status {
return db_->Put(rocksdb::WriteOptions(), source_family_, source_path,
api_path);
})) != api_error::success) {
return res;
}
}
return store_item_meta(api_path, META_SOURCE, source_path);
}
auto meta_db::store_item_meta(const std::string &api_path,
const std::string &key, const std::string &value)
-> api_error {
json json_data;
auto res = get_item_meta_json(api_path, json_data);
if ((res != api_error::success) && (res != api_error::item_not_found)) {
return res;
}
json_data[key] = value;
return perform_action(__FUNCTION__, [&]() -> rocksdb::Status {
return db_->Put(rocksdb::WriteOptions(), default_family_, api_path,
json_data.dump());
});
}
} // namespace repertory

View File

@ -60,7 +60,8 @@ api_error fuse_drive::chflags_impl(std::string api_path, uint32_t flags) {
#if FUSE_USE_VERSION >= 30 #if FUSE_USE_VERSION >= 30
auto fuse_drive::chmod_impl(std::string api_path, mode_t mode, auto fuse_drive::chmod_impl(std::string api_path, mode_t mode,
struct fuse_file_info * /*fi*/) -> api_error { struct fuse_file_info * /*file_info*/)
-> api_error {
#else #else
auto fuse_drive::chmod_impl(std::string api_path, mode_t mode) -> api_error { auto fuse_drive::chmod_impl(std::string api_path, mode_t mode) -> api_error {
#endif #endif
@ -71,7 +72,8 @@ auto fuse_drive::chmod_impl(std::string api_path, mode_t mode) -> api_error {
#if FUSE_USE_VERSION >= 30 #if FUSE_USE_VERSION >= 30
auto fuse_drive::chown_impl(std::string api_path, uid_t uid, gid_t gid, auto fuse_drive::chown_impl(std::string api_path, uid_t uid, gid_t gid,
struct fuse_file_info * /*fi*/) -> api_error { struct fuse_file_info * /*file_info*/)
-> api_error {
#else #else
auto fuse_drive::chown_impl(std::string api_path, uid_t uid, gid_t gid) auto fuse_drive::chown_impl(std::string api_path, uid_t uid, gid_t gid)
-> api_error { -> api_error {
@ -96,16 +98,18 @@ auto fuse_drive::chown_impl(std::string api_path, uid_t uid, gid_t gid)
} }
auto fuse_drive::create_impl(std::string api_path, mode_t mode, auto fuse_drive::create_impl(std::string api_path, mode_t mode,
struct fuse_file_info *fi) -> api_error { struct fuse_file_info *file_info) -> api_error {
fi->fh = 0u; file_info->fh = 0U;
const auto is_directory_op = ((fi->flags & O_DIRECTORY) == O_DIRECTORY); const auto is_directory_op =
const auto is_create_op = ((fi->flags & O_CREAT) == O_CREAT); ((file_info->flags & O_DIRECTORY) == O_DIRECTORY);
const auto is_truncate_op = const auto is_create_op = ((file_info->flags & O_CREAT) == O_CREAT);
((fi->flags & O_TRUNC) && const auto is_truncate_op = (((file_info->flags & O_TRUNC) != 0) &&
((fi->flags & O_WRONLY) || (fi->flags & O_RDWR))); (((file_info->flags & O_WRONLY) != 0) ||
((file_info->flags & O_RDWR) != 0)));
if ((fi->flags & O_WRONLY) || (fi->flags & O_RDWR)) { if (((file_info->flags & O_WRONLY) != 0) ||
((file_info->flags & O_RDWR) != 0)) {
const auto res = provider_.is_file_writeable(api_path) const auto res = provider_.is_file_writeable(api_path)
? api_error::success ? api_error::success
: api_error::permission_denied; : api_error::permission_denied;
@ -154,42 +158,41 @@ auto fuse_drive::create_impl(std::string api_path, mode_t mode,
} }
} }
std::uint64_t handle = 0u; std::uint64_t handle{};
std::shared_ptr<i_open_file> f; std::shared_ptr<i_open_file> open_file;
if (is_create_op) { if (is_create_op) {
const auto now = utils::get_file_time_now(); const auto now = utils::get_file_time_now();
#ifdef __APPLE__ #ifdef __APPLE__
const auto osx_flags = static_cast<std::uint32_t>(fi->flags); const auto osx_flags = static_cast<std::uint32_t>(file_info->flags);
#else #else
const auto osx_flags = std::uint32_t(0u); const auto osx_flags = 0U;
#endif #endif
auto meta = create_meta_attributes( auto meta = create_meta_attributes(
now, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_ARCHIVE, now, now, now, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_ARCHIVE, now, now,
is_directory_op, "", get_effective_gid(), "", mode, now, 0u, osx_flags, is_directory_op, get_effective_gid(), "", mode, now, 0U, osx_flags, 0U,
0u,
utils::path::combine(config_.get_cache_directory(), utils::path::combine(config_.get_cache_directory(),
{utils::create_uuid_string()}), {utils::create_uuid_string()}),
get_effective_uid(), now); get_effective_uid(), now);
res = fm_->create(api_path, meta, fi->flags, handle, f); res = fm_->create(api_path, meta, file_info->flags, handle, open_file);
if ((res != api_error::item_exists) && (res != api_error::success)) { if ((res != api_error::item_exists) && (res != api_error::success)) {
return res; return res;
} }
} else if (((res = fm_->open(api_path, is_directory_op, fi->flags, handle, } else if (((res = fm_->open(api_path, is_directory_op, file_info->flags,
f)) != api_error::success)) { handle, open_file)) != api_error::success)) {
return res; return res;
} }
fi->fh = handle; file_info->fh = handle;
if (is_truncate_op) { if (is_truncate_op) {
#if FUSE_USE_VERSION >= 30 #if FUSE_USE_VERSION >= 30
if ((res = truncate_impl(api_path, 0, fi)) != api_error::success) { if ((res = truncate_impl(api_path, 0, file_info)) != api_error::success) {
#else #else
if ((res = ftruncate_impl(api_path, 0, fi)) != api_error::success) { if ((res = ftruncate_impl(api_path, 0, file_info)) != api_error::success) {
#endif #endif
fm_->close(handle); fm_->close(handle);
fi->fh = 0u; file_info->fh = 0U;
errno = std::abs(utils::from_api_error(res)); errno = std::abs(utils::from_api_error(res));
return res; return res;
} }
@ -198,7 +201,7 @@ auto fuse_drive::create_impl(std::string api_path, mode_t mode,
return api_error::success; return api_error::success;
} }
void fuse_drive::destroy_impl(void *) { void fuse_drive::destroy_impl(void * /* ptr */) {
event_system::instance().raise<drive_unmount_pending>(get_mount_location()); event_system::instance().raise<drive_unmount_pending>(get_mount_location());
remote_server_.reset(); remote_server_.reset();
@ -240,21 +243,21 @@ void fuse_drive::destroy_impl(void *) {
auto fuse_drive::fallocate_impl(std::string /*api_path*/, int mode, auto fuse_drive::fallocate_impl(std::string /*api_path*/, int mode,
off_t offset, off_t length, off_t offset, off_t length,
struct fuse_file_info *fi) -> api_error { struct fuse_file_info *file_info) -> api_error {
std::shared_ptr<i_open_file> f; std::shared_ptr<i_open_file> open_file;
if (not fm_->get_open_file(fi->fh, true, f)) { if (not fm_->get_open_file(file_info->fh, true, open_file)) {
return api_error::invalid_handle; return api_error::invalid_handle;
} }
auto res = auto res = check_writeable(open_file->get_open_data(file_info->fh),
check_writeable(f->get_open_data(fi->fh), api_error::invalid_handle); api_error::invalid_handle);
if (res != api_error::success) { if (res != api_error::success) {
return res; return res;
} }
if ((res = check_open_flags(f->get_open_data(fi->fh), O_WRONLY | O_APPEND, if ((res = check_open_flags(
api_error::invalid_handle)) != open_file->get_open_data(file_info->fh), O_WRONLY | O_APPEND,
api_error::success) { api_error::invalid_handle)) != api_error::success) {
return res; return res;
} }
@ -294,13 +297,14 @@ auto fuse_drive::fallocate_impl(std::string /*api_path*/, int mode,
}; };
#endif // __APPLE__ #endif // __APPLE__
return f->native_operation(offset + length, allocator); return open_file->native_operation(
static_cast<std::uint64_t>(offset + length), allocator);
} }
auto fuse_drive::fgetattr_impl(std::string api_path, struct stat *st, auto fuse_drive::fgetattr_impl(std::string api_path, struct stat *st,
struct fuse_file_info *fi) -> api_error { struct fuse_file_info *file_info) -> api_error {
std::shared_ptr<i_open_file> f; std::shared_ptr<i_open_file> open_file;
if (not fm_->get_open_file(fi->fh, false, f)) { if (not fm_->get_open_file(file_info->fh, false, open_file)) {
return api_error::invalid_handle; return api_error::invalid_handle;
} }
@ -315,17 +319,18 @@ auto fuse_drive::fgetattr_impl(std::string api_path, struct stat *st,
if (res != api_error::success) { if (res != api_error::success) {
return res; return res;
} }
fuse_drive_base::populate_stat(api_path, f->get_file_size(), meta, directory, fuse_drive_base::populate_stat(api_path, open_file->get_file_size(), meta,
provider_, st); directory, provider_, st);
return api_error::success; return api_error::success;
} }
#ifdef __APPLE__ #ifdef __APPLE__
auto fuse_drive::fsetattr_x_impl(std::string api_path, struct setattr_x *attr, auto fuse_drive::fsetattr_x_impl(std::string api_path, struct setattr_x *attr,
struct fuse_file_info *fi) -> api_error { struct fuse_file_info *file_info)
-> api_error {
std::shared_ptr<i_open_file> f; std::shared_ptr<i_open_file> f;
if (not fm_->get_open_file(fi->fh, false, f)) { if (not fm_->get_open_file(file_info->fh, false, f)) {
return api_error::invalid_handle; return api_error::invalid_handle;
} }
@ -334,13 +339,13 @@ auto fuse_drive::fsetattr_x_impl(std::string api_path, struct setattr_x *attr,
#endif // __APPLE__ #endif // __APPLE__
auto fuse_drive::fsync_impl(std::string /*api_path*/, int datasync, auto fuse_drive::fsync_impl(std::string /*api_path*/, int datasync,
struct fuse_file_info *fi) -> api_error { struct fuse_file_info *file_info) -> api_error {
std::shared_ptr<i_open_file> f; std::shared_ptr<i_open_file> open_file;
if (not fm_->get_open_file(fi->fh, false, f)) { if (not fm_->get_open_file(file_info->fh, false, open_file)) {
return api_error::invalid_handle; return api_error::invalid_handle;
} }
return f->native_operation([&datasync](int handle) -> api_error { return open_file->native_operation([&datasync](int handle) -> api_error {
if (handle != REPERTORY_INVALID_HANDLE) { if (handle != REPERTORY_INVALID_HANDLE) {
#ifdef __APPLE__ #ifdef __APPLE__
if ((datasync ? fcntl(handle, F_FULLFSYNC) : fsync(handle)) == -1) { if ((datasync ? fcntl(handle, F_FULLFSYNC) : fsync(handle)) == -1) {
@ -356,14 +361,14 @@ auto fuse_drive::fsync_impl(std::string /*api_path*/, int datasync,
#if FUSE_USE_VERSION < 30 #if FUSE_USE_VERSION < 30
api_error fuse_drive::ftruncate_impl(std::string /*api_path*/, off_t size, api_error fuse_drive::ftruncate_impl(std::string /*api_path*/, off_t size,
struct fuse_file_info *fi) { struct fuse_file_info *file_info) {
std::shared_ptr<i_open_file> f; std::shared_ptr<i_open_file> f;
if (not fm_->get_open_file(fi->fh, true, f)) { if (not fm_->get_open_file(file_info->fh, true, f)) {
return api_error::invalid_handle; return api_error::invalid_handle;
} }
const auto res = const auto res = check_writeable(f->get_open_data(file_info->fh),
check_writeable(f->get_open_data(fi->fh), api_error::invalid_handle); api_error::invalid_handle);
if (res != api_error::success) { if (res != api_error::success) {
return res; return res;
} }
@ -379,14 +384,14 @@ auto fuse_drive::get_directory_item_count(const std::string &api_path) const
auto fuse_drive::get_directory_items(const std::string &api_path) const auto fuse_drive::get_directory_items(const std::string &api_path) const
-> directory_item_list { -> directory_item_list {
directory_item_list di{}; directory_item_list list{};
auto res = provider_.get_directory_items(api_path, di); auto res = provider_.get_directory_items(api_path, list);
if (res != api_error::success) { if (res != api_error::success) {
utils::error::raise_api_path_error(__FUNCTION__, api_path, res, utils::error::raise_api_path_error(__FUNCTION__, api_path, res,
"failed to get directory items"); "failed to get directory items");
} }
return di; return list;
} }
auto fuse_drive::get_file_size(const std::string &api_path) const auto fuse_drive::get_file_size(const std::string &api_path) const
@ -420,7 +425,8 @@ auto fuse_drive::get_item_meta(const std::string &api_path,
#if FUSE_USE_VERSION >= 30 #if FUSE_USE_VERSION >= 30
auto fuse_drive::getattr_impl(std::string api_path, struct stat *st, auto fuse_drive::getattr_impl(std::string api_path, struct stat *st,
struct fuse_file_info * /*fi*/) -> api_error { struct fuse_file_info * /*file_info*/)
-> api_error {
#else #else
auto fuse_drive::getattr_impl(std::string api_path, struct stat *st) auto fuse_drive::getattr_impl(std::string api_path, struct stat *st)
-> api_error { -> api_error {
@ -434,11 +440,11 @@ auto fuse_drive::getattr_impl(std::string api_path, struct stat *st)
auto found = false; auto found = false;
directory_cache_->execute_action(parent, [&](directory_iterator &iter) { directory_cache_->execute_action(parent, [&](directory_iterator &iter) {
directory_item di{}; directory_item dir_item{};
if ((found = if ((found = (iter.get_directory_item(api_path, dir_item) ==
(iter.get_directory_item(api_path, di) == api_error::success))) { api_error::success))) {
fuse_drive_base::populate_stat(api_path, di.size, di.meta, di.directory, fuse_drive_base::populate_stat(api_path, dir_item.size, dir_item.meta,
provider_, st); dir_item.directory, provider_, st);
} }
}); });
@ -582,9 +588,9 @@ auto fuse_drive::mkdir_impl(std::string api_path, mode_t mode) -> api_error {
} }
const auto now = utils::get_file_time_now(); const auto now = utils::get_file_time_now();
auto meta = create_meta_attributes( auto meta = create_meta_attributes(now, FILE_ATTRIBUTE_DIRECTORY, now, now,
now, FILE_ATTRIBUTE_DIRECTORY, now, now, true, "", get_effective_gid(), true, get_effective_gid(), "", mode, now,
"", mode, now, 0u, 0u, 0u, "", get_effective_uid(), now); 0U, 0U, 0U, "", get_effective_uid(), now);
if ((res = provider_.create_directory(api_path, meta)) != if ((res = provider_.create_directory(api_path, meta)) !=
api_error::success) { api_error::success) {
return res; return res;
@ -611,15 +617,16 @@ void fuse_drive::notify_fuse_main_exit(int &ret) {
} }
} }
auto fuse_drive::open_impl(std::string api_path, struct fuse_file_info *fi) auto fuse_drive::open_impl(std::string api_path,
-> api_error { struct fuse_file_info *file_info) -> api_error {
fi->flags &= (~O_CREAT); file_info->flags &= (~O_CREAT);
return create_impl(api_path, 0, fi); return create_impl(api_path, 0, file_info);
} }
auto fuse_drive::opendir_impl(std::string api_path, struct fuse_file_info *fi) auto fuse_drive::opendir_impl(std::string api_path,
-> api_error { struct fuse_file_info *file_info) -> api_error {
const auto mask = (O_RDONLY != (fi->flags & O_ACCMODE) ? W_OK : R_OK) | X_OK; const auto mask =
(O_RDONLY != (file_info->flags & O_ACCMODE) ? W_OK : R_OK) | X_OK;
auto res = check_access(api_path, mask); auto res = check_access(api_path, mask);
if (res != api_error::success) { if (res != api_error::success) {
return res; return res;
@ -638,35 +645,36 @@ auto fuse_drive::opendir_impl(std::string api_path, struct fuse_file_info *fi)
return api_error::directory_not_found; return api_error::directory_not_found;
} }
directory_item_list dl{}; directory_item_list list{};
if ((res = provider_.get_directory_items(api_path, dl)) != if ((res = provider_.get_directory_items(api_path, list)) !=
api_error::success) { api_error::success) {
return res; return res;
} }
auto *iter = new directory_iterator(std::move(dl)); auto *iter = new directory_iterator(std::move(list));
fi->fh = reinterpret_cast<std::uint64_t>(iter); file_info->fh = reinterpret_cast<std::uint64_t>(iter);
directory_cache_->set_directory(api_path, iter); directory_cache_->set_directory(api_path, iter);
return api_error::success; return api_error::success;
} }
void fuse_drive::populate_stat(const directory_item &di, void fuse_drive::populate_stat(const directory_item &dir_item,
struct stat &st) const { struct stat &st) const {
fuse_drive_base::populate_stat(di.api_path, di.size, di.meta, di.directory, fuse_drive_base::populate_stat(dir_item.api_path, dir_item.size,
provider_, &st); dir_item.meta, dir_item.directory, provider_,
&st);
} }
auto fuse_drive::read_impl(std::string api_path, char *buffer, size_t read_size, auto fuse_drive::read_impl(std::string api_path, char *buffer, size_t read_size,
off_t read_offset, struct fuse_file_info *fi, off_t read_offset, struct fuse_file_info *file_info,
std::size_t &bytes_read) -> api_error { std::size_t &bytes_read) -> api_error {
std::shared_ptr<i_open_file> f; std::shared_ptr<i_open_file> open_file;
if (not fm_->get_open_file(fi->fh, false, f)) { if (not fm_->get_open_file(file_info->fh, false, open_file)) {
return api_error::item_not_found; return api_error::item_not_found;
} }
auto res = auto res = check_readable(open_file->get_open_data(file_info->fh),
check_readable(f->get_open_data(fi->fh), api_error::invalid_handle); api_error::invalid_handle);
if (res != api_error::success) { if (res != api_error::success) {
return res; return res;
} }
@ -675,11 +683,12 @@ auto fuse_drive::read_impl(std::string api_path, char *buffer, size_t read_size,
// __FUNCTION__, api_path, std::to_string(read_size) + ':' + // __FUNCTION__, api_path, std::to_string(read_size) + ':' +
// std::to_string(read_offset)); // std::to_string(read_offset));
data_buffer data; data_buffer data;
res = f->read(read_size, static_cast<std::uint64_t>(read_offset), data); res =
open_file->read(read_size, static_cast<std::uint64_t>(read_offset), data);
// event_system::instance().raise<debug_log>( // event_system::instance().raise<debug_log>(
// __FUNCTION__, api_path, std::to_string(bytes_read) + ':' + // __FUNCTION__, api_path, std::to_string(bytes_read) + ':' +
// api_error_to_string(res)); // api_error_to_string(res));
if ((bytes_read = data.size())) { if ((bytes_read = data.size()) != 0U) {
std::memcpy(buffer, data.data(), data.size()); std::memcpy(buffer, data.data(), data.size());
data.clear(); data.clear();
update_accessed_time(api_path); update_accessed_time(api_path);
@ -691,20 +700,20 @@ auto fuse_drive::read_impl(std::string api_path, char *buffer, size_t read_size,
#if FUSE_USE_VERSION >= 30 #if FUSE_USE_VERSION >= 30
auto fuse_drive::readdir_impl(std::string api_path, void *buf, auto fuse_drive::readdir_impl(std::string api_path, void *buf,
fuse_fill_dir_t fuse_fill_dir, off_t offset, fuse_fill_dir_t fuse_fill_dir, off_t offset,
struct fuse_file_info *fi, struct fuse_file_info *file_info,
fuse_readdir_flags /*flags*/) -> api_error { fuse_readdir_flags /*flags*/) -> api_error {
#else #else
auto fuse_drive::readdir_impl(std::string api_path, void *buf, auto fuse_drive::readdir_impl(std::string api_path, void *buf,
fuse_fill_dir_t fuse_fill_dir, off_t offset, fuse_fill_dir_t fuse_fill_dir, off_t offset,
struct fuse_file_info *fi) -> api_error { struct fuse_file_info *file_info) -> api_error {
#endif #endif
auto res = check_access(api_path, X_OK); auto res = check_access(api_path, X_OK);
if (res != api_error::success) { if (res != api_error::success) {
return res; return res;
} }
auto *iter = reinterpret_cast<directory_iterator *>(fi->fh); auto *iter = reinterpret_cast<directory_iterator *>(file_info->fh);
if (not iter) { if (iter == nullptr) {
return api_error::invalid_handle; return api_error::invalid_handle;
} }
@ -730,15 +739,16 @@ auto fuse_drive::readdir_impl(std::string api_path, void *buf,
} }
auto fuse_drive::release_impl(std::string /*api_path*/, auto fuse_drive::release_impl(std::string /*api_path*/,
struct fuse_file_info *fi) -> api_error { struct fuse_file_info *file_info) -> api_error {
fm_->close(fi->fh); fm_->close(file_info->fh);
return api_error::success; return api_error::success;
} }
auto fuse_drive::releasedir_impl(std::string /*api_path*/, auto fuse_drive::releasedir_impl(std::string /*api_path*/,
struct fuse_file_info *fi) -> api_error { struct fuse_file_info *file_info)
auto *iter = reinterpret_cast<directory_iterator *>(fi->fh); -> api_error {
if (not iter) { auto *iter = reinterpret_cast<directory_iterator *>(file_info->fh);
if (iter == nullptr) {
return api_error::invalid_handle; return api_error::invalid_handle;
} }
@ -808,9 +818,7 @@ auto fuse_drive::rmdir_impl(std::string api_path) -> api_error {
} }
auto *iter = directory_cache_->remove_directory(api_path); auto *iter = directory_cache_->remove_directory(api_path);
if (iter) {
delete iter; delete iter;
}
return api_error::success; return api_error::success;
} }
@ -841,10 +849,10 @@ auto fuse_drive::getxattr_common(std::string api_path, const char *name,
directory_cache_->execute_action( directory_cache_->execute_action(
utils::path::get_parent_api_path(api_path), utils::path::get_parent_api_path(api_path),
[&](directory_iterator &iterator) { [&](directory_iterator &iterator) {
directory_item di{}; directory_item dir_item{};
if ((found = (iterator.get_directory_item(api_path, di) == if ((found = (iterator.get_directory_item(api_path, dir_item) ==
api_error::success))) { api_error::success))) {
meta = di.meta; meta = dir_item.meta;
} }
}); });
@ -853,13 +861,13 @@ auto fuse_drive::getxattr_common(std::string api_path, const char *name,
res = api_error::xattr_not_found; res = api_error::xattr_not_found;
if (meta.find(attribute_name) != meta.end()) { if (meta.find(attribute_name) != meta.end()) {
const auto data = macaron::Base64::Decode(meta[attribute_name]); const auto data = macaron::Base64::Decode(meta[attribute_name]);
if (not position || (*position < data.size())) { if ((position == nullptr) || (*position < data.size())) {
res = api_error::success; res = api_error::success;
attribute_size = static_cast<int>(data.size()); attribute_size = static_cast<int>(data.size());
if (size) { if (size != 0U) {
res = api_error::xattr_buffer_small; res = api_error::xattr_buffer_small;
if (size >= data.size()) { if (size >= data.size()) {
memcpy(value, &data[0], data.size()); memcpy(value, data.data(), data.size());
return api_error::success; return api_error::success;
} }
} }
@ -897,13 +905,13 @@ auto fuse_drive::listxattr_impl(std::string api_path, char *buffer, size_t size,
api_meta_map meta; api_meta_map meta;
if ((res = provider_.get_item_meta(api_path, meta)) == api_error::success) { if ((res = provider_.get_item_meta(api_path, meta)) == api_error::success) {
for (const auto &kv : meta) { for (const auto &meta_item : meta) {
if (utils::collection_excludes(META_USED_NAMES, kv.first)) { if (utils::collection_excludes(META_USED_NAMES, meta_item.first)) {
auto attribute_name = kv.first; auto attribute_name = meta_item.first;
#ifdef __APPLE__ #ifdef __APPLE__
if (attribute_name != G_KAUTH_FILESEC_XATTR) { if (attribute_name != G_KAUTH_FILESEC_XATTR) {
#endif #endif
const auto attribute_name_size = strlen(attribute_name.c_str()) + 1u; const auto attribute_name_size = strlen(attribute_name.c_str()) + 1U;
if (size >= attribute_name_size) { if (size >= attribute_name_size) {
strncpy(&buffer[required_size], attribute_name.c_str(), strncpy(&buffer[required_size], attribute_name.c_str(),
attribute_name_size); attribute_name_size);
@ -912,7 +920,7 @@ auto fuse_drive::listxattr_impl(std::string api_path, char *buffer, size_t size,
res = api_error::xattr_buffer_small; res = api_error::xattr_buffer_small;
} }
required_size += attribute_name_size; required_size += static_cast<int>(attribute_name_size);
#ifdef __APPLE__ #ifdef __APPLE__
} }
#endif #endif
@ -972,7 +980,7 @@ auto fuse_drive::setxattr_impl(std::string api_path, const char *name,
const auto attribute_namespace = const auto attribute_namespace =
utils::string::contains(attribute_name, ".") utils::string::contains(attribute_name, ".")
? utils::string::split(attribute_name, '.', false)[0u] ? utils::string::split(attribute_name, '.', false)[0U]
: ""; : "";
if ((attribute_name.size() > XATTR_NAME_MAX) || (size > XATTR_SIZE_MAX)) { if ((attribute_name.size() > XATTR_NAME_MAX) || (size > XATTR_SIZE_MAX)) {
return api_error::xattr_too_big; return api_error::xattr_too_big;
@ -1192,7 +1200,7 @@ auto fuse_drive::statfs_x_impl(std::string /*api_path*/, struct statfs *stbuf)
#else // __APPLE__ #else // __APPLE__
auto fuse_drive::statfs_impl(std::string /*api_path*/, struct statvfs *stbuf) auto fuse_drive::statfs_impl(std::string /*api_path*/, struct statvfs *stbuf)
-> api_error { -> api_error {
if (statvfs(&config_.get_cache_directory()[0], stbuf) != 0) { if (statvfs(config_.get_cache_directory().data(), stbuf) != 0) {
return api_error::os_error; return api_error::os_error;
} }
@ -1204,7 +1212,7 @@ auto fuse_drive::statfs_impl(std::string /*api_path*/, struct statvfs *stbuf)
stbuf->f_blocks = utils::divide_with_ceiling( stbuf->f_blocks = utils::divide_with_ceiling(
total_bytes, static_cast<std::uint64_t>(stbuf->f_frsize)); total_bytes, static_cast<std::uint64_t>(stbuf->f_frsize));
stbuf->f_bavail = stbuf->f_bfree = stbuf->f_bavail = stbuf->f_bfree =
stbuf->f_blocks ? (stbuf->f_blocks - used_blocks) : 0; stbuf->f_blocks == 0U ? 0 : (stbuf->f_blocks - used_blocks);
stbuf->f_ffree = stbuf->f_favail = stbuf->f_ffree = stbuf->f_favail =
stbuf->f_files - provider_.get_total_item_count(); stbuf->f_files - provider_.get_total_item_count();
@ -1214,7 +1222,8 @@ auto fuse_drive::statfs_impl(std::string /*api_path*/, struct statvfs *stbuf)
#if FUSE_USE_VERSION >= 30 #if FUSE_USE_VERSION >= 30
auto fuse_drive::truncate_impl(std::string api_path, off_t size, auto fuse_drive::truncate_impl(std::string api_path, off_t size,
struct fuse_file_info * /*fi*/) -> api_error { struct fuse_file_info * /*file_info*/)
-> api_error {
#else #else
auto fuse_drive::truncate_impl(std::string api_path, off_t size) -> api_error { auto fuse_drive::truncate_impl(std::string api_path, off_t size) -> api_error {
#endif #endif
@ -1234,9 +1243,9 @@ auto fuse_drive::truncate_impl(std::string api_path, off_t size) -> api_error {
} }
open_file_data ofd = O_RDWR; open_file_data ofd = O_RDWR;
std::uint64_t handle = 0u; std::uint64_t handle{};
std::shared_ptr<i_open_file> f; std::shared_ptr<i_open_file> open_file;
if ((res = fm_->open(api_path, false, ofd, handle, f)) != if ((res = fm_->open(api_path, false, ofd, handle, open_file)) !=
api_error::success) { api_error::success) {
return res; return res;
} }
@ -1246,7 +1255,7 @@ auto fuse_drive::truncate_impl(std::string api_path, off_t size) -> api_error {
return err; return err;
}; };
return cleanup(f->resize(size)); return cleanup(open_file->resize(static_cast<std::uint64_t>(size)));
} }
auto fuse_drive::unlink_impl(std::string api_path) -> api_error { auto fuse_drive::unlink_impl(std::string api_path) -> api_error {
@ -1269,7 +1278,8 @@ auto fuse_drive::unlink_impl(std::string api_path) -> api_error {
#if FUSE_USE_VERSION >= 30 #if FUSE_USE_VERSION >= 30
auto fuse_drive::utimens_impl(std::string api_path, const struct timespec tv[2], auto fuse_drive::utimens_impl(std::string api_path, const struct timespec tv[2],
struct fuse_file_info * /*fi*/) -> api_error { struct fuse_file_info * /*file_info*/)
-> api_error {
#else #else
auto fuse_drive::utimens_impl(std::string api_path, const struct timespec tv[2]) auto fuse_drive::utimens_impl(std::string api_path, const struct timespec tv[2])
-> api_error { -> api_error {
@ -1285,17 +1295,17 @@ auto fuse_drive::utimens_impl(std::string api_path, const struct timespec tv[2])
} }
meta.clear(); meta.clear();
if (not tv || (tv[0].tv_nsec == UTIME_NOW)) { if ((tv == nullptr) || (tv[0U].tv_nsec == UTIME_NOW)) {
meta[META_ACCESSED] = std::to_string(utils::get_file_time_now()); meta[META_ACCESSED] = std::to_string(utils::get_file_time_now());
} else if (tv[0].tv_nsec != UTIME_OMIT) { } else if (tv[0U].tv_nsec != UTIME_OMIT) {
const auto val = tv[0].tv_nsec + (tv[0].tv_sec * NANOS_PER_SECOND); const auto val = tv[0U].tv_nsec + (tv[0U].tv_sec * NANOS_PER_SECOND);
meta[META_ACCESSED] = std::to_string(val); meta[META_ACCESSED] = std::to_string(val);
} }
if (not tv || (tv[1].tv_nsec == UTIME_NOW)) { if ((tv == nullptr) || (tv[1U].tv_nsec == UTIME_NOW)) {
meta[META_MODIFIED] = std::to_string(utils::get_file_time_now()); meta[META_MODIFIED] = std::to_string(utils::get_file_time_now());
} else if (tv[1].tv_nsec != UTIME_OMIT) { } else if (tv[1U].tv_nsec != UTIME_OMIT) {
const auto val = tv[1].tv_nsec + (tv[1].tv_sec * NANOS_PER_SECOND); const auto val = tv[1U].tv_nsec + (tv[1U].tv_sec * NANOS_PER_SECOND);
meta[META_MODIFIED] = std::to_string(val); meta[META_MODIFIED] = std::to_string(val);
} }
@ -1309,28 +1319,29 @@ auto fuse_drive::utimens_impl(std::string api_path, const struct timespec tv[2])
auto fuse_drive::write_impl(std::string /*api_path*/ auto fuse_drive::write_impl(std::string /*api_path*/
, ,
const char *buffer, size_t write_size, const char *buffer, size_t write_size,
off_t write_offset, struct fuse_file_info *fi, off_t write_offset,
struct fuse_file_info *file_info,
std::size_t &bytes_written) -> api_error { std::size_t &bytes_written) -> api_error {
std::shared_ptr<i_open_file> f; std::shared_ptr<i_open_file> open_file;
if (not fm_->get_open_file(fi->fh, true, f)) { if (not fm_->get_open_file(file_info->fh, true, open_file)) {
return api_error::item_not_found; return api_error::item_not_found;
} }
auto res = auto res = check_writeable(open_file->get_open_data(file_info->fh),
check_writeable(f->get_open_data(fi->fh), api_error::invalid_handle); api_error::invalid_handle);
if (res != api_error::success) { if (res != api_error::success) {
return res; return res;
} }
if (write_size > 0) { if (write_size > 0) {
if (f->get_open_data(fi->fh) & O_APPEND) { if ((open_file->get_open_data(file_info->fh) & O_APPEND) != 0) {
write_offset = f->get_file_size(); write_offset = static_cast<off_t>(open_file->get_file_size());
} }
data_buffer data(write_size); data_buffer data(write_size);
std::memcpy(&data[0], buffer, write_size); std::memcpy(data.data(), buffer, write_size);
return f->write(static_cast<std::uint64_t>(write_offset), std::move(data), return open_file->write(static_cast<std::uint64_t>(write_offset),
bytes_written); std::move(data), bytes_written);
} }
return api_error::success; return api_error::success;

View File

@ -60,8 +60,8 @@ auto remote_fuse_drive::chmod_impl(std::string api_path, mode_t mode,
auto remote_fuse_drive::chmod_impl(std::string api_path, mode_t mode) auto remote_fuse_drive::chmod_impl(std::string api_path, mode_t mode)
-> api_error { -> api_error {
#endif #endif
return utils::to_api_error( return utils::to_api_error(remote_instance_->fuse_chmod(
remote_instance_->fuse_chmod(api_path.c_str(), mode)); api_path.c_str(), static_cast<remote::file_mode>(mode)));
} }
#if FUSE_USE_VERSION >= 30 #if FUSE_USE_VERSION >= 30
@ -79,7 +79,9 @@ auto remote_fuse_drive::chown_impl(std::string api_path, uid_t uid, gid_t gid)
auto remote_fuse_drive::create_impl(std::string api_path, mode_t mode, auto remote_fuse_drive::create_impl(std::string api_path, mode_t mode,
struct fuse_file_info *fi) -> api_error { struct fuse_file_info *fi) -> api_error {
return utils::to_api_error(remote_instance_->fuse_create( return utils::to_api_error(remote_instance_->fuse_create(
api_path.c_str(), mode, remote::create_open_flags(fi->flags), fi->fh)); api_path.c_str(), static_cast<remote::file_mode>(mode),
remote::create_open_flags(static_cast<std::uint32_t>(fi->flags)),
fi->fh));
} }
void remote_fuse_drive::destroy_impl(void * /*ptr*/) { void remote_fuse_drive::destroy_impl(void * /*ptr*/) {
@ -248,8 +250,8 @@ auto remote_fuse_drive::init_impl(struct fuse_conn_info *conn) -> void * {
auto remote_fuse_drive::mkdir_impl(std::string api_path, mode_t mode) auto remote_fuse_drive::mkdir_impl(std::string api_path, mode_t mode)
-> api_error { -> api_error {
return utils::to_api_error( return utils::to_api_error(remote_instance_->fuse_mkdir(
remote_instance_->fuse_mkdir(api_path.c_str(), mode)); api_path.c_str(), static_cast<remote::file_mode>(mode)));
} }
void remote_fuse_drive::notify_fuse_main_exit(int &ret) { void remote_fuse_drive::notify_fuse_main_exit(int &ret) {

View File

@ -166,12 +166,12 @@ void remote_server::populate_stat(const struct stat64 &st1, remote::stat &st) {
st.st_mtimespec = st.st_mtimespec =
st1.st_mtim.tv_nsec + (st1.st_mtim.tv_sec * NANOS_PER_SECOND); st1.st_mtim.tv_nsec + (st1.st_mtim.tv_sec * NANOS_PER_SECOND);
#endif #endif
st.st_blksize = st1.st_blksize; st.st_blksize = static_cast<remote::block_size>(st1.st_blksize);
st.st_blocks = st1.st_blocks; st.st_blocks = static_cast<remote::block_count>(st1.st_blocks);
st.st_gid = st1.st_gid; st.st_gid = st1.st_gid;
st.st_mode = st1.st_mode; st.st_mode = static_cast<remote::file_mode>(st1.st_mode);
st.st_nlink = st1.st_nlink; st.st_nlink = static_cast<remote::file_nlink>(st1.st_nlink);
st.st_size = st1.st_size; st.st_size = static_cast<remote::file_size>(st1.st_size);
st.st_uid = st1.st_uid; st.st_uid = st1.st_uid;
} }
@ -227,9 +227,10 @@ auto remote_server::fuse_create(const char *path, const remote::file_mode &mode,
-> packet::error_type { -> packet::error_type {
const auto file_path = construct_path(path); const auto file_path = construct_path(path);
const auto res = const auto res =
open(file_path.c_str(), remote::create_os_open_flags(flags), mode); open(file_path.c_str(),
static_cast<int>(remote::create_os_open_flags(flags)), mode);
if (res >= 0) { if (res >= 0) {
handle = res; handle = static_cast<remote::file_handle>(res);
set_open_info(res, open_info{0, "", nullptr, file_path}); set_open_info(res, open_info{0, "", nullptr, file_path});
} }
@ -269,13 +270,12 @@ ConstructPath(path); auto ret = HasOpenFileInfo(handle, -EBADF); if (ret == 0) {
fstore.fst_offset = offset; fstore.fst_offset = offset;
fstore.fst_length = length; fstore.fst_length = length;
const auto res = fcntl(static_cast<int>(handle), F_PREALLOCATE, &fstore); const auto res = fcntl(static_cast<native_handle>(handle), F_PREALLOCATE,
ret = ((res < 0) ? -errno : 0); &fstore); ret = ((res < 0) ? -errno : 0);
} }
#else #else
const auto res = fallocate(static_cast<int>(handle), mode, offset, length); const auto res = fallocate(static_cast<native_handle>(handle), mode, offset,
ret = ((res < 0) ? -errno : 0); length); ret = ((res < 0) ? -errno : 0); #endif
#endif
} }
RAISE_REMOTE_FUSE_SERVER_EVENT(__FUNCTION__, file_path, ret); RAISE_REMOTE_FUSE_SERVER_EVENT(__FUNCTION__, file_path, ret);
@ -289,11 +289,11 @@ auto remote_server::fuse_fgetattr(const char *path, remote::stat &st,
const auto file_path = construct_path(path); const auto file_path = construct_path(path);
memset(&st, 0, sizeof(remote::stat)); memset(&st, 0, sizeof(remote::stat));
auto res = has_open_info(handle, EBADF); auto res = has_open_info(static_cast<native_handle>(handle), EBADF);
if (res == 0) { if (res == 0) {
directory = utils::file::is_directory(file_path); directory = utils::file::is_directory(file_path);
struct stat64 st1 {}; struct stat64 st1 {};
if ((res = fstat64(static_cast<int>(handle), &st1)) == 0) { if ((res = fstat64(static_cast<native_handle>(handle), &st1)) == 0) {
populate_stat(st1, st); populate_stat(st1, st);
} }
} }
@ -314,12 +314,12 @@ auto remote_server::fuse_fsetattr_x(const char *path,
if (SETATTR_WANTS_MODE(&attr)) { if (SETATTR_WANTS_MODE(&attr)) {
res = (handle == static_cast<std::uint64_t>(REPERTORY_INVALID_HANDLE)) res = (handle == static_cast<std::uint64_t>(REPERTORY_INVALID_HANDLE))
? chmod(file_path.c_str(), attr.mode) ? chmod(file_path.c_str(), attr.mode)
: fchmod(handle, attr.mode); : fchmod(static_cast<native_handle>(handle), attr.mode);
} }
if (res >= 0) { if (res >= 0) {
uid_t uid = -1; auto uid = static_cast<uid_t>(-1);
gid_t gid = -1; auto gid = static_cast<gid_t>(-1);
if (SETATTR_WANTS_UID(&attr)) { if (SETATTR_WANTS_UID(&attr)) {
uid = attr.uid; uid = attr.uid;
} }
@ -338,7 +338,7 @@ auto remote_server::fuse_fsetattr_x(const char *path,
if (SETATTR_WANTS_SIZE(&attr)) { if (SETATTR_WANTS_SIZE(&attr)) {
res = (handle == static_cast<std::uint64_t>(REPERTORY_INVALID_HANDLE)) res = (handle == static_cast<std::uint64_t>(REPERTORY_INVALID_HANDLE))
? truncate(file_path.c_str(), attr.size) ? truncate(file_path.c_str(), attr.size)
: ftruncate(handle, attr.size); : ftruncate(static_cast<native_handle>(handle), attr.size);
} }
} }
@ -397,14 +397,14 @@ auto remote_server::fuse_fsync(const char *path, const std::int32_t &datasync,
-> packet::error_type { -> packet::error_type {
const auto file_path = construct_path(path); const auto file_path = construct_path(path);
auto res = has_open_info(handle, EBADF); auto res = has_open_info(static_cast<native_handle>(handle), EBADF);
if (res == 0) { if (res == 0) {
#ifdef __APPLE__ #ifdef __APPLE__
res = datasync ? fcntl(static_cast<int>(handle), F_FULLFSYNC) res = datasync ? fcntl(static_cast<native_handle>(handle), F_FULLFSYNC)
: fsync(static_cast<int>(handle)); : fsync(static_cast<native_handle>(handle));
#else #else
res = datasync ? fdatasync(static_cast<int>(handle)) res = datasync ? fdatasync(static_cast<native_handle>(handle))
: fsync(static_cast<int>(handle)); : fsync(static_cast<native_handle>(handle));
#endif #endif
} }
@ -419,9 +419,9 @@ auto remote_server::fuse_ftruncate(const char *path,
-> packet::error_type { -> packet::error_type {
const auto file_path = construct_path(path); const auto file_path = construct_path(path);
auto res = has_open_info(handle, EBADF); auto res = has_open_info(static_cast<native_handle>(handle), EBADF);
if (res == 0) { if (res == 0) {
res = ftruncate(static_cast<int>(handle), size); res = ftruncate(static_cast<native_handle>(handle), size);
} }
auto ret = ((res < 0) ? -errno : 0); auto ret = ((res < 0) ? -errno : 0);
@ -472,7 +472,7 @@ utils::path::get_parent_api_path(api_path);
res = -ENODATA; res = -ENODATA;
if (directoryItem.MetaMap.find(name) != directoryItem.MetaMap.end()) if (directoryItem.MetaMap.find(name) != directoryItem.MetaMap.end())
{ const auto data = macaron::Base64::Decode(directoryItem.MetaMap[name]); res = { const auto data = macaron::Base64::Decode(directoryItem.MetaMap[name]); res =
static_cast<int>(data.size()); if (size) { res = -ERANGE; if (size >= static_cast<native_handle>(data.size()); if (size) { res = -ERANGE; if (size >=
data.size()) { memcpy(value, &data[0], data.size()); res = 0; data.size()) { memcpy(value, &data[0], data.size()); res = 0;
} }
} }
@ -561,9 +561,10 @@ auto remote_server::fuse_open(const char *path, const remote::open_flags &flags,
remote::file_handle &handle) remote::file_handle &handle)
-> packet::error_type { -> packet::error_type {
const auto file_path = construct_path(path); const auto file_path = construct_path(path);
const auto res = open(file_path.c_str(), remote::create_os_open_flags(flags)); const auto res = open(file_path.c_str(),
static_cast<int>(remote::create_os_open_flags(flags)));
if (res >= 0) { if (res >= 0) {
handle = res; handle = static_cast<remote::file_handle>(res);
set_open_info(res, open_info{0, "", nullptr, file_path}); set_open_info(res, open_info{0, "", nullptr, file_path});
} }
auto ret = ((res < 0) ? -errno : 0); auto ret = ((res < 0) ? -errno : 0);
@ -600,18 +601,21 @@ auto remote_server::fuse_read(const char *path, char *buffer,
const remote::file_handle &handle) const remote::file_handle &handle)
-> packet::error_type { -> packet::error_type {
const auto file_path = construct_path(path); const auto file_path = construct_path(path);
auto &b = *reinterpret_cast<data_buffer *>(buffer); auto &data = *reinterpret_cast<data_buffer *>(buffer);
auto res = has_open_info(handle, EBADF);
if (res == 0) { ssize_t bytes_read{has_open_info(static_cast<native_handle>(handle), EBADF)};
b.resize(read_size); if (bytes_read == 0) {
res = pread64(static_cast<int>(handle), &b[0], read_size, read_offset); data.resize(read_size);
bytes_read = pread64(static_cast<native_handle>(handle), data.data(),
read_size, static_cast<off_t>(read_offset));
} }
auto ret = ((res < 0) ? -errno : res); auto ret = ((bytes_read < 0) ? -errno : bytes_read);
if (ret < 0) { if (ret < 0) {
RAISE_REMOTE_FUSE_SERVER_EVENT(__FUNCTION__, file_path, ret); RAISE_REMOTE_FUSE_SERVER_EVENT(__FUNCTION__, file_path, ret);
} }
return ret;
return static_cast<packet::error_type>(ret);
} }
auto remote_server::fuse_rename(const char *from, const char *to) auto remote_server::fuse_rename(const char *from, const char *to)
@ -628,7 +632,7 @@ auto remote_server::fuse_rename(const char *from, const char *to)
auto remote_server::fuse_readdir(const char *path, auto remote_server::fuse_readdir(const char *path,
const remote::file_offset &offset, const remote::file_offset &offset,
const remote::file_handle &handle, const remote::file_handle &handle,
std::string &itemPath) -> packet::error_type { std::string &item_path) -> packet::error_type {
const auto file_path = construct_path(path); const auto file_path = construct_path(path);
auto res = 0; auto res = 0;
if (offset > std::numeric_limits<std::size_t>::max()) { if (offset > std::numeric_limits<std::size_t>::max()) {
@ -636,8 +640,8 @@ auto remote_server::fuse_readdir(const char *path,
res = -1; res = -1;
} else { } else {
auto *iterator = reinterpret_cast<directory_iterator *>(handle); auto *iterator = reinterpret_cast<directory_iterator *>(handle);
if (iterator) { if (iterator != nullptr) {
res = iterator->get(static_cast<std::size_t>(offset), itemPath); res = iterator->get(static_cast<std::size_t>(offset), item_path);
} else { } else {
res = -1; res = -1;
errno = EFAULT; errno = EFAULT;
@ -655,10 +659,10 @@ 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); const auto file_path = construct_path(path);
auto res = has_open_info(handle, EBADF); auto res = has_open_info(static_cast<native_handle>(handle), EBADF);
if (res == 0) { if (res == 0) {
res = close(static_cast<int>(handle)); res = close(static_cast<native_handle>(handle));
remove_open_info(handle); remove_open_info(static_cast<native_handle>(handle));
} }
ret = ((res < 0) ? -errno : 0); ret = ((res < 0) ? -errno : 0);
@ -697,7 +701,7 @@ auto remote_server::fuse_rmdir(const char *path) -> packet::error_type {
const auto file_path = construct_path(path); const auto file_path = construct_path(path);
const auto res = rmdir(file_path.c_str()); const auto res = rmdir(file_path.c_str());
if (res == 0) { if (res == 0) {
auto iterator = auto *iterator =
directory_cache_.remove_directory(utils::path::create_api_path(path)); directory_cache_.remove_directory(utils::path::create_api_path(path));
if (iterator == nullptr) { if (iterator == nullptr) {
utils::error::raise_error( utils::error::raise_error(
@ -890,16 +894,20 @@ auto remote_server::fuse_write(const char *path, const char *buffer,
const remote::file_handle &handle) const remote::file_handle &handle)
-> packet::error_type { -> packet::error_type {
const auto file_path = construct_path(path); const auto file_path = construct_path(path);
auto res = has_open_info(handle, EBADF);
if (res == 0) { ssize_t bytes_written{
res = pwrite64(static_cast<int>(handle), buffer, write_size, write_offset); has_open_info(static_cast<native_handle>(handle), EBADF)};
if (bytes_written == 0) {
bytes_written = pwrite64(static_cast<native_handle>(handle), buffer,
write_size, static_cast<off_t>(write_offset));
} }
auto ret = ((res < 0) ? -errno : res); auto ret = ((bytes_written < 0) ? -errno : bytes_written);
if (ret < 0) { if (ret < 0) {
RAISE_REMOTE_FUSE_SERVER_EVENT(__FUNCTION__, file_path, ret); RAISE_REMOTE_FUSE_SERVER_EVENT(__FUNCTION__, file_path, ret);
} }
return ret;
return static_cast<packet::error_type>(ret);
} }
auto remote_server::fuse_write_base64( auto remote_server::fuse_write_base64(
@ -916,7 +924,9 @@ auto remote_server::winfsp_can_delete(PVOID file_desc, PWSTR file_name)
-> packet::error_type { -> packet::error_type {
const auto relative_path = utils::string::to_utf8(file_name); const auto relative_path = utils::string::to_utf8(file_name);
const auto file_path = construct_path(relative_path); const auto file_path = construct_path(relative_path);
auto ret = has_open_info(reinterpret_cast<remote::file_handle>(file_desc), auto ret =
has_open_info(static_cast<native_handle>(
reinterpret_cast<remote::file_handle>(file_desc)),
STATUS_INVALID_HANDLE); STATUS_INVALID_HANDLE);
if (ret == STATUS_SUCCESS) { if (ret == STATUS_SUCCESS) {
ret = ret =
@ -994,10 +1004,11 @@ auto remote_server::winfsp_cleanup(PVOID /*file_desc*/, PWSTR file_name,
auto remote_server::winfsp_close(PVOID file_desc) -> packet::error_type { auto remote_server::winfsp_close(PVOID file_desc) -> packet::error_type {
std::string file_path; std::string file_path;
const auto handle = reinterpret_cast<remote::file_handle>(file_desc); const auto handle = reinterpret_cast<remote::file_handle>(file_desc);
if (has_open_info(handle, STATUS_INVALID_HANDLE) == STATUS_SUCCESS) { if (has_open_info(static_cast<native_handle>(handle),
file_path = get_open_file_path(handle); STATUS_INVALID_HANDLE) == STATUS_SUCCESS) {
close(handle); file_path = get_open_file_path(static_cast<native_handle>(handle));
remove_open_info(handle); close(static_cast<native_handle>(handle));
remove_open_info(static_cast<native_handle>(handle));
} }
RAISE_REMOTE_FUSE_SERVER_EVENT(__FUNCTION__, file_path, STATUS_SUCCESS); RAISE_REMOTE_FUSE_SERVER_EVENT(__FUNCTION__, file_path, STATUS_SUCCESS);
@ -1006,7 +1017,7 @@ auto remote_server::winfsp_close(PVOID file_desc) -> packet::error_type {
auto remote_server::winfsp_create(PWSTR file_name, UINT32 create_options, auto remote_server::winfsp_create(PWSTR file_name, UINT32 create_options,
UINT32 granted_access, UINT32 attributes, UINT32 granted_access, UINT32 attributes,
UINT64 /*allocationSize*/, PVOID *file_desc, UINT64 /*allocation_size*/, PVOID *file_desc,
remote::file_info *file_info, remote::file_info *file_info,
std::string &normalized_name, BOOLEAN &exists) std::string &normalized_name, BOOLEAN &exists)
-> packet::error_type { -> packet::error_type {
@ -1056,15 +1067,19 @@ auto remote_server::winfsp_create(PWSTR file_name, UINT32 create_options,
auto remote_server::winfsp_flush(PVOID file_desc, remote::file_info *file_info) auto remote_server::winfsp_flush(PVOID file_desc, remote::file_info *file_info)
-> packet::error_type { -> packet::error_type {
const auto handle = reinterpret_cast<remote::file_handle>(file_desc); const auto handle = reinterpret_cast<remote::file_handle>(file_desc);
auto ret = has_open_info(handle, STATUS_INVALID_HANDLE); auto ret =
has_open_info(static_cast<native_handle>(handle), STATUS_INVALID_HANDLE);
if (ret == STATUS_SUCCESS) { if (ret == STATUS_SUCCESS) {
ret = (fsync(static_cast<int>(handle)) < 0) ret = (fsync(static_cast<native_handle>(handle)) < 0)
? utils::unix_error_to_windows(errno) ? utils::unix_error_to_windows(errno)
: populate_file_info( : populate_file_info(construct_api_path(get_open_file_path(
construct_api_path(get_open_file_path(handle)), *file_info); static_cast<native_handle>(handle))),
*file_info);
} }
RAISE_REMOTE_FUSE_SERVER_EVENT(__FUNCTION__, get_open_file_path(handle), ret); RAISE_REMOTE_FUSE_SERVER_EVENT(
__FUNCTION__, get_open_file_path(static_cast<native_handle>(handle)),
ret);
return ret; return ret;
} }
@ -1072,20 +1087,24 @@ auto remote_server::winfsp_get_file_info(PVOID file_desc,
remote::file_info *file_info) remote::file_info *file_info)
-> packet::error_type { -> packet::error_type {
const auto handle = reinterpret_cast<remote::file_handle>(file_desc); const auto handle = reinterpret_cast<remote::file_handle>(file_desc);
auto ret = has_open_info(handle, STATUS_INVALID_HANDLE); auto ret =
has_open_info(static_cast<native_handle>(handle), STATUS_INVALID_HANDLE);
if (ret == STATUS_SUCCESS) { if (ret == STATUS_SUCCESS) {
ret = populate_file_info(construct_api_path(get_open_file_path(handle)), ret = populate_file_info(construct_api_path(get_open_file_path(
static_cast<native_handle>(handle))),
*file_info); *file_info);
} }
RAISE_REMOTE_FUSE_SERVER_EVENT(__FUNCTION__, get_open_file_path(handle), ret); RAISE_REMOTE_FUSE_SERVER_EVENT(
__FUNCTION__, get_open_file_path(static_cast<native_handle>(handle)),
ret);
return ret; return ret;
} }
auto remote_server::winfsp_get_security_by_name( auto remote_server::winfsp_get_security_by_name(
PWSTR file_name, PUINT32 attributes, PWSTR file_name, PUINT32 attributes,
std::uint64_t * /*securityDescriptorSize*/, std::uint64_t * /*security_descriptor_size*/,
std::wstring & /*strDescriptor*/) -> packet::error_type { std::wstring & /*str_descriptor*/) -> packet::error_type {
auto ret = STATUS_SUCCESS; auto ret = STATUS_SUCCESS;
const auto file_path = construct_path(file_name); const auto file_path = construct_path(file_name);
if (utils::file::is_file(file_path) || if (utils::file::is_file(file_path) ||
@ -1159,14 +1178,16 @@ auto remote_server::winfsp_open(PWSTR file_name, UINT32 create_options,
auto remote_server::winfsp_overwrite(PVOID file_desc, UINT32 attributes, auto remote_server::winfsp_overwrite(PVOID file_desc, UINT32 attributes,
BOOLEAN replace_attributes, BOOLEAN replace_attributes,
UINT64 /*allocationSize*/, UINT64 /*allocation_size*/,
remote::file_info *file_info) remote::file_info *file_info)
-> packet::error_type { -> packet::error_type {
const auto handle = reinterpret_cast<remote::file_handle>(file_desc); const auto handle = reinterpret_cast<remote::file_handle>(file_desc);
auto ret = has_open_info(handle, STATUS_INVALID_HANDLE); auto ret =
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(get_open_file_path(handle)); const auto api_path = construct_api_path(
const auto res = ftruncate(handle, 0); get_open_file_path(static_cast<native_handle>(handle)));
const 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) {
@ -1195,14 +1216,17 @@ auto remote_server::winfsp_overwrite(PVOID file_desc, UINT32 attributes,
drive_.set_item_meta(api_path, META_ATTRIBUTES, drive_.set_item_meta(api_path, META_ATTRIBUTES,
std::to_string(attributes)); std::to_string(attributes));
} }
ret = populate_file_info(construct_api_path(get_open_file_path(handle)), ret = populate_file_info(construct_api_path(get_open_file_path(
static_cast<native_handle>(handle))),
*file_info); *file_info);
} else { } else {
ret = utils::unix_error_to_windows(errno); ret = utils::unix_error_to_windows(errno);
} }
} }
RAISE_REMOTE_FUSE_SERVER_EVENT(__FUNCTION__, get_open_file_path(handle), ret); RAISE_REMOTE_FUSE_SERVER_EVENT(
__FUNCTION__, get_open_file_path(static_cast<native_handle>(handle)),
ret);
return ret; return ret;
} }
@ -1212,17 +1236,21 @@ auto remote_server::winfsp_read(PVOID file_desc, PVOID buffer, UINT64 offset,
*bytes_transferred = 0; *bytes_transferred = 0;
const auto handle = reinterpret_cast<remote::file_handle>(file_desc); const auto handle = reinterpret_cast<remote::file_handle>(file_desc);
auto ret = has_open_info(handle, STATUS_INVALID_HANDLE); auto ret =
has_open_info(static_cast<native_handle>(handle), STATUS_INVALID_HANDLE);
if (ret == STATUS_SUCCESS) { if (ret == STATUS_SUCCESS) {
const auto res = pread64(handle, buffer, length, offset); const auto res = pread64(static_cast<native_handle>(handle), buffer, length,
static_cast<off_t>(offset));
if (res >= 0) { if (res >= 0) {
*bytes_transferred = res; *bytes_transferred = static_cast<UINT32>(res);
} else { } else {
ret = utils::unix_error_to_windows(errno); ret = utils::unix_error_to_windows(errno);
} }
} }
RAISE_REMOTE_FUSE_SERVER_EVENT(__FUNCTION__, get_open_file_path(handle), ret); RAISE_REMOTE_FUSE_SERVER_EVENT(
__FUNCTION__, get_open_file_path(static_cast<native_handle>(handle)),
ret);
return ret; return ret;
} }
@ -1232,9 +1260,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); const auto handle = reinterpret_cast<remote::file_handle>(file_desc);
auto ret = has_open_info(handle, STATUS_INVALID_HANDLE); auto ret =
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(get_open_file_path(handle)); const auto api_path = construct_api_path(
get_open_file_path(static_cast<native_handle>(handle)));
auto list = drive_.get_directory_items(api_path); auto list = drive_.get_directory_items(api_path);
directory_iterator iterator(std::move(list)); directory_iterator iterator(std::move(list));
auto offset = marker auto offset = marker
@ -1253,7 +1283,9 @@ auto remote_server::winfsp_read_directory(PVOID file_desc, PWSTR /*pattern*/,
ret = STATUS_SUCCESS; ret = STATUS_SUCCESS;
} }
RAISE_REMOTE_FUSE_SERVER_EVENT(__FUNCTION__, get_open_file_path(handle), ret); RAISE_REMOTE_FUSE_SERVER_EVENT(
__FUNCTION__, get_open_file_path(static_cast<native_handle>(handle)),
ret);
return ret; return ret;
} }
@ -1288,9 +1320,11 @@ auto remote_server::winfsp_set_basic_info(
UINT64 last_access_time, UINT64 last_write_time, UINT64 change_time, UINT64 last_access_time, UINT64 last_write_time, UINT64 change_time,
remote::file_info *file_info) -> packet::error_type { remote::file_info *file_info) -> packet::error_type {
const auto handle = reinterpret_cast<remote::file_handle>(file_desc); const auto handle = reinterpret_cast<remote::file_handle>(file_desc);
auto ret = has_open_info(handle, STATUS_INVALID_HANDLE); auto ret =
has_open_info(static_cast<native_handle>(handle), STATUS_INVALID_HANDLE);
if (ret == STATUS_SUCCESS) { if (ret == STATUS_SUCCESS) {
const auto file_path = get_open_file_path(handle); const auto file_path =
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) {
@ -1337,7 +1371,9 @@ auto remote_server::winfsp_set_basic_info(
ret = populate_file_info(api_path, *file_info); ret = populate_file_info(api_path, *file_info);
} }
RAISE_REMOTE_FUSE_SERVER_EVENT(__FUNCTION__, get_open_file_path(handle), ret); RAISE_REMOTE_FUSE_SERVER_EVENT(
__FUNCTION__, get_open_file_path(static_cast<native_handle>(handle)),
ret);
return ret; return ret;
} }
@ -1346,17 +1382,24 @@ auto remote_server::winfsp_set_file_size(PVOID file_desc, UINT64 new_size,
remote::file_info *file_info) remote::file_info *file_info)
-> packet::error_type { -> packet::error_type {
const auto handle = reinterpret_cast<remote::file_handle>(file_desc); const auto handle = reinterpret_cast<remote::file_handle>(file_desc);
auto ret = has_open_info(handle, STATUS_INVALID_HANDLE); auto ret =
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 ? 0 : ftruncate(handle, new_size); const auto res =
set_allocation_size
? 0
: ftruncate(static_cast<native_handle>(handle), new_size);
ret = ((res < 0) ? utils::unix_error_to_windows(errno) : 0); ret = ((res < 0) ? utils::unix_error_to_windows(errno) : 0);
if (ret == 0) { if (ret == 0) {
ret = populate_file_info(construct_api_path(get_open_file_path(handle)), ret = populate_file_info(construct_api_path(get_open_file_path(
static_cast<native_handle>(handle))),
*file_info); *file_info);
} }
} }
RAISE_REMOTE_FUSE_SERVER_EVENT(__FUNCTION__, get_open_file_path(handle), ret); RAISE_REMOTE_FUSE_SERVER_EVENT(
__FUNCTION__, get_open_file_path(static_cast<native_handle>(handle)),
ret);
return ret; return ret;
} }
@ -1375,9 +1418,11 @@ auto remote_server::winfsp_write(PVOID file_desc, PVOID buffer, UINT64 offset,
-> packet::error_type { -> packet::error_type {
*bytes_transferred = 0; *bytes_transferred = 0;
const auto handle = reinterpret_cast<remote::file_handle>(file_desc); const auto handle = reinterpret_cast<remote::file_handle>(file_desc);
auto ret = has_open_info(handle, STATUS_INVALID_HANDLE); auto ret =
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(get_open_file_path(handle)); const auto api_path = construct_api_path(
get_open_file_path(static_cast<native_handle>(handle)));
const auto file_size = drive_.get_file_size(api_path); const auto file_size = drive_.get_file_size(api_path);
if (write_to_end) { if (write_to_end) {
offset = file_size; offset = file_size;
@ -1389,17 +1434,19 @@ auto remote_server::winfsp_write(PVOID file_desc, PVOID buffer, UINT64 offset,
ret = STATUS_SUCCESS; ret = STATUS_SUCCESS;
should_write = false; should_write = false;
} else if ((offset + length) > file_size) { } else if ((offset + length) > file_size) {
length = static_cast<UINT64>(file_size - offset); length = static_cast<UINT32>(file_size - offset);
} }
} }
if (should_write) { if (should_write) {
if (length > 0) { if (length > 0) {
const auto res = pwrite64(handle, buffer, length, offset); const auto res = pwrite64(static_cast<native_handle>(handle), buffer,
length, static_cast<off_t>(offset));
if (res >= 0) { if (res >= 0) {
*bytes_transferred = res; *bytes_transferred = static_cast<UINT32>(res);
ret = populate_file_info( ret = populate_file_info(construct_api_path(get_open_file_path(
construct_api_path(get_open_file_path(handle)), *file_info); static_cast<native_handle>(handle))),
*file_info);
} else { } else {
ret = utils::unix_error_to_windows(errno); ret = utils::unix_error_to_windows(errno);
} }
@ -1407,7 +1454,9 @@ auto remote_server::winfsp_write(PVOID file_desc, PVOID buffer, UINT64 offset,
} }
} }
RAISE_REMOTE_FUSE_SERVER_EVENT(__FUNCTION__, get_open_file_path(handle), ret); RAISE_REMOTE_FUSE_SERVER_EVENT(
__FUNCTION__, get_open_file_path(static_cast<native_handle>(handle)),
ret);
return ret; return ret;
} }
@ -1444,8 +1493,8 @@ auto remote_server::json_read_directory_snapshot(
std::uint32_t page, json &json_data) -> packet::error_type { std::uint32_t page, json &json_data) -> packet::error_type {
const auto file_path = construct_path(path); const auto file_path = construct_path(path);
auto *iterator = reinterpret_cast<directory_iterator *>(handle); auto *iterator = reinterpret_cast<directory_iterator *>(handle);
std::size_t offset = 0u; std::size_t offset{};
int res; int res{};
json item_json; json item_json;
while ((json_data["directory_list"].size() < REPERTORY_DIRECTORY_PAGE_SIZE) && while ((json_data["directory_list"].size() < REPERTORY_DIRECTORY_PAGE_SIZE) &&
(res = iterator->get_json( (res = iterator->get_json(

View File

@ -260,8 +260,8 @@ VOID winfsp_drive::Close(PVOID /*file_node*/, PVOID file_desc) {
RAISE_WINFSP_EVENT(__FUNCTION__, api_path, 0); RAISE_WINFSP_EVENT(__FUNCTION__, api_path, 0);
} }
auto winfsp_drive::Create(PWSTR fileName, UINT32 create_options, auto winfsp_drive::Create(PWSTR file_name, UINT32 create_options,
UINT32 /*grantedAccess*/, UINT32 attributes, UINT32 /*granted_access*/, UINT32 attributes,
PSECURITY_DESCRIPTOR /*descriptor*/, PSECURITY_DESCRIPTOR /*descriptor*/,
UINT64 /*allocation_size*/, PVOID * /*file_node*/, UINT64 /*allocation_size*/, PVOID * /*file_node*/,
PVOID *file_desc, OpenFileInfo *ofi) -> NTSTATUS { PVOID *file_desc, OpenFileInfo *ofi) -> NTSTATUS {
@ -281,8 +281,8 @@ auto winfsp_drive::Create(PWSTR fileName, UINT32 create_options,
const auto now = utils::get_file_time_now(); const auto now = utils::get_file_time_now();
auto meta = create_meta_attributes( auto meta = create_meta_attributes(
now, attributes, now, now, attributes & FILE_ATTRIBUTE_DIRECTORY, "", 0U, now, attributes, now, now, attributes & FILE_ATTRIBUTE_DIRECTORY, 0U, "",
"", 0U, now, 0U, 0U, 0U, 0U, now, 0U, 0U, 0U,
(attributes & FILE_ATTRIBUTE_DIRECTORY) (attributes & FILE_ATTRIBUTE_DIRECTORY)
? "" ? ""
: utils::path::combine(config_.get_cache_directory(), : utils::path::combine(config_.get_cache_directory(),
@ -290,7 +290,7 @@ auto winfsp_drive::Create(PWSTR fileName, UINT32 create_options,
0U, now); 0U, now);
const auto api_path = const auto api_path =
utils::path::create_api_path(utils::string::to_utf8(fileName)); utils::path::create_api_path(utils::string::to_utf8(file_name));
open_file_data ofd{}; open_file_data ofd{};
std::uint64_t handle{}; std::uint64_t handle{};
@ -315,7 +315,7 @@ auto winfsp_drive::Create(PWSTR fileName, UINT32 create_options,
} }
auto winfsp_drive::Flush(PVOID /*file_node*/, PVOID file_desc, auto winfsp_drive::Flush(PVOID /*file_node*/, PVOID file_desc,
FileInfo *fileInfo) -> NTSTATUS { FileInfo *file_info) -> NTSTATUS {
std::string api_path; std::string api_path;
auto error = api_error::success; auto error = api_error::success;
auto handle = auto handle =
@ -336,7 +336,7 @@ auto winfsp_drive::Flush(PVOID /*file_node*/, PVOID file_desc,
// Populate file information // Populate file information
api_meta_map meta; api_meta_map meta;
if (provider_.get_item_meta(api_path, meta) == api_error::success) { if (provider_.get_item_meta(api_path, meta) == api_error::success) {
populate_file_info(f->get_file_size(), meta, *fileInfo); populate_file_info(f->get_file_size(), meta, *file_info);
} }
} }
} }
@ -363,7 +363,7 @@ auto winfsp_drive::get_directory_items(const std::string &api_path) const
} }
auto winfsp_drive::GetFileInfo(PVOID /*file_node*/, PVOID file_desc, auto winfsp_drive::GetFileInfo(PVOID /*file_node*/, PVOID file_desc,
FileInfo *fileInfo) -> NTSTATUS { FileInfo *file_info) -> NTSTATUS {
std::string api_path; std::string api_path;
auto error = api_error::invalid_handle; auto error = api_error::invalid_handle;
auto handle = auto handle =
@ -375,7 +375,7 @@ auto winfsp_drive::GetFileInfo(PVOID /*file_node*/, PVOID file_desc,
api_meta_map meta; api_meta_map meta;
if ((error = provider_.get_item_meta(api_path, meta)) == if ((error = provider_.get_item_meta(api_path, meta)) ==
api_error::success) { api_error::success) {
populate_file_info(f->get_file_size(), meta, *fileInfo); populate_file_info(f->get_file_size(), meta, *file_info);
} }
} }
} }
@ -414,12 +414,12 @@ auto winfsp_drive::get_item_meta(const std::string &api_path,
return ret; return ret;
} }
auto winfsp_drive::get_security_by_name(PWSTR fileName, PUINT32 attributes, auto winfsp_drive::get_security_by_name(PWSTR file_name, PUINT32 attributes,
PSECURITY_DESCRIPTOR descriptor, PSECURITY_DESCRIPTOR descriptor,
std::uint64_t *descriptor_size) std::uint64_t *descriptor_size)
-> NTSTATUS { -> NTSTATUS {
const auto api_path = const auto api_path =
utils::path::create_api_path(utils::string::to_utf8(fileName)); utils::path::create_api_path(utils::string::to_utf8(file_name));
api_meta_map meta{}; api_meta_map meta{};
auto error = provider_.get_item_meta(api_path, meta); auto error = provider_.get_item_meta(api_path, meta);
@ -451,13 +451,13 @@ auto winfsp_drive::get_security_by_name(PWSTR fileName, PUINT32 attributes,
return utils::from_api_error(error); return utils::from_api_error(error);
} }
auto winfsp_drive::GetSecurityByName(PWSTR fileName, PUINT32 attributes, auto winfsp_drive::GetSecurityByName(PWSTR file_name, PUINT32 attributes,
PSECURITY_DESCRIPTOR descriptor, PSECURITY_DESCRIPTOR descriptor,
SIZE_T *descriptor_size) -> NTSTATUS { SIZE_T *descriptor_size) -> NTSTATUS {
const auto api_path = const auto api_path =
utils::path::create_api_path(utils::string::to_utf8(fileName)); utils::path::create_api_path(utils::string::to_utf8(file_name));
std::uint64_t sds = descriptor_size ? *descriptor_size : 0U; std::uint64_t sds = descriptor_size ? *descriptor_size : 0U;
auto ret = get_security_by_name(fileName, attributes, descriptor, auto ret = get_security_by_name(file_name, attributes, descriptor,
sds > 0U ? &sds : nullptr); sds > 0U ? &sds : nullptr);
if (sds) { if (sds) {
*descriptor_size = static_cast<SIZE_T>(sds); *descriptor_size = static_cast<SIZE_T>(sds);
@ -939,7 +939,7 @@ auto winfsp_drive::Rename(PVOID /*file_node*/, PVOID /*file_desc*/,
auto winfsp_drive::SetBasicInfo(PVOID /*file_node*/, PVOID file_desc, auto winfsp_drive::SetBasicInfo(PVOID /*file_node*/, PVOID file_desc,
UINT32 attributes, UINT64 creation_time, UINT32 attributes, UINT64 creation_time,
UINT64 last_access_time, UINT64 last_write_time, UINT64 last_access_time, UINT64 last_write_time,
UINT64 change_time, FileInfo *fileInfo) UINT64 change_time, FileInfo *file_info)
-> NTSTATUS { -> NTSTATUS {
std::string api_path; std::string api_path;
auto error = api_error::invalid_handle; auto error = api_error::invalid_handle;
@ -983,7 +983,7 @@ auto winfsp_drive::SetBasicInfo(PVOID /*file_node*/, PVOID file_desc,
// Populate file information // Populate file information
if (provider_.get_item_meta(api_path, meta) == api_error::success) { if (provider_.get_item_meta(api_path, meta) == api_error::success) {
populate_file_info(utils::string::to_uint64(meta[META_SIZE]), meta, populate_file_info(utils::string::to_uint64(meta[META_SIZE]), meta,
*fileInfo); *file_info);
} }
} }
} }

View File

@ -137,7 +137,7 @@ void file_manager::close_timed_out_files() {
for (const auto &api_path : closeable_list) { for (const auto &api_path : closeable_list) {
auto closeable_file = open_file_lookup_.at(api_path); auto closeable_file = open_file_lookup_.at(api_path);
open_file_lookup_.erase(api_path); open_file_lookup_.erase(api_path);
open_files.emplace_back(closeable_file); open_files.push_back(std::move(closeable_file));
} }
closeable_list.clear(); closeable_list.clear();
file_lock.unlock(); file_lock.unlock();
@ -364,9 +364,9 @@ auto file_manager::open(const std::string &api_path, bool directory,
}; };
recur_mutex_lock open_lock(open_file_mtx_); recur_mutex_lock open_lock(open_file_mtx_);
auto it = open_file_lookup_.find(api_path); auto iter = open_file_lookup_.find(api_path);
if (it != open_file_lookup_.end()) { if (iter != open_file_lookup_.end()) {
create_and_add_handle(it->second); create_and_add_handle(iter->second);
return api_error::success; return api_error::success;
} }
@ -400,12 +400,6 @@ auto file_manager::open(const std::string &api_path, bool directory,
return api_error::success; return api_error::success;
} }
auto file_manager::perform_locked_operation(
locked_operation_callback locked_operation) -> bool {
recur_mutex_lock open_lock(open_file_mtx_);
return locked_operation(provider_);
}
void file_manager::queue_upload(const i_open_file &o) { void file_manager::queue_upload(const i_open_file &o) {
return queue_upload(o.get_api_path(), o.get_source_path(), false); return queue_upload(o.get_api_path(), o.get_source_path(), false);
} }
@ -952,7 +946,7 @@ void file_manager::upload_handler() {
} break; } break;
} }
} else { } else {
iterator.release(); iterator.reset();
upload_notify_.wait(upload_lock); upload_notify_.wait(upload_lock);
} }
} else { } else {

View File

@ -35,29 +35,30 @@ namespace repertory {
file_manager::open_file::open_file(std::uint64_t chunk_size, file_manager::open_file::open_file(std::uint64_t chunk_size,
std::uint8_t chunk_timeout, std::uint8_t chunk_timeout,
filesystem_item fsi, i_provider &provider, filesystem_item fsi, i_provider &provider,
i_upload_manager &um) i_upload_manager &mgr)
: open_file(chunk_size, chunk_timeout, fsi, {}, provider, std::nullopt, : open_file(chunk_size, chunk_timeout, fsi, {}, provider, std::nullopt,
um) {} mgr) {}
file_manager::open_file::open_file( file_manager::open_file::open_file(
std::uint64_t chunk_size, std::uint8_t chunk_timeout, filesystem_item fsi, std::uint64_t chunk_size, std::uint8_t chunk_timeout, filesystem_item fsi,
std::map<std::uint64_t, open_file_data> open_data, i_provider &provider, std::map<std::uint64_t, open_file_data> open_data, i_provider &provider,
i_upload_manager &um) i_upload_manager &mgr)
: open_file(chunk_size, chunk_timeout, fsi, open_data, provider, : open_file(chunk_size, chunk_timeout, fsi, open_data, provider,
std::nullopt, um) {} std::nullopt, mgr) {}
file_manager::open_file::open_file( file_manager::open_file::open_file(
std::uint64_t chunk_size, std::uint8_t chunk_timeout, filesystem_item fsi, std::uint64_t chunk_size, std::uint8_t chunk_timeout, filesystem_item fsi,
i_provider &provider, std::optional<boost::dynamic_bitset<>> read_state, i_provider &provider, std::optional<boost::dynamic_bitset<>> read_state,
i_upload_manager &um) i_upload_manager &mgr)
: open_file(chunk_size, chunk_timeout, fsi, {}, provider, read_state, um) {} : open_file(chunk_size, chunk_timeout, fsi, {}, provider, read_state, mgr) {
}
file_manager::open_file::open_file( file_manager::open_file::open_file(
std::uint64_t chunk_size, std::uint8_t chunk_timeout, filesystem_item fsi, std::uint64_t chunk_size, std::uint8_t chunk_timeout, filesystem_item fsi,
std::map<std::uint64_t, open_file_data> open_data, i_provider &provider, std::map<std::uint64_t, open_file_data> open_data, i_provider &provider,
std::optional<boost::dynamic_bitset<>> read_state, i_upload_manager &um) std::optional<boost::dynamic_bitset<>> read_state, i_upload_manager &mgr)
: open_file_base(chunk_size, chunk_timeout, fsi, open_data, provider), : open_file_base(chunk_size, chunk_timeout, fsi, open_data, provider),
um_(um) { mgr_(mgr) {
if (fsi_.directory && read_state.has_value()) { if (fsi_.directory && read_state.has_value()) {
throw startup_exception("cannot resume a directory|" + fsi.api_path); throw startup_exception("cannot resume a directory|" + fsi.api_path);
} }
@ -68,9 +69,9 @@ file_manager::open_file::open_file(
if (get_api_error() == api_error::success) { if (get_api_error() == api_error::success) {
if (read_state.has_value()) { if (read_state.has_value()) {
modified_ = true; modified_ = true;
um_.store_resume(*this); mgr_.store_resume(*this);
read_state_ = read_state.value(); read_state_ = read_state.value();
} else if (fsi_.size > 0u) { } else if (fsi_.size > 0U) {
read_state_.resize(static_cast<std::size_t>(utils::divide_with_ceiling( read_state_.resize(static_cast<std::size_t>(utils::divide_with_ceiling(
fsi_.size, chunk_size)), fsi_.size, chunk_size)),
false); false);
@ -78,7 +79,7 @@ file_manager::open_file::open_file(
std::uint64_t file_size{}; std::uint64_t file_size{};
if (nf_->get_file_size(file_size)) { if (nf_->get_file_size(file_size)) {
if (provider_.is_direct_only() || file_size == fsi.size) { if (provider_.is_direct_only() || file_size == fsi.size) {
read_state_.set(0u, read_state_.size(), true); read_state_.set(0U, read_state_.size(), true);
} else if (not nf_->truncate(fsi.size)) { } else if (not nf_->truncate(fsi.size)) {
set_api_error(api_error::os_error); set_api_error(api_error::os_error);
} }
@ -103,13 +104,13 @@ void file_manager::open_file::download_chunk(std::size_t chunk,
reset_timeout(); reset_timeout();
} }
unique_recur_mutex_lock file_lock(file_mtx_); unique_recur_mutex_lock download_lock(file_mtx_);
if ((get_api_error() == api_error::success) && (chunk < read_state_.size()) && if ((get_api_error() == api_error::success) && (chunk < read_state_.size()) &&
not read_state_[chunk]) { not read_state_[chunk]) {
if (active_downloads_.find(chunk) != active_downloads_.end()) { if (active_downloads_.find(chunk) != active_downloads_.end()) {
if (not skip_active) { if (not skip_active) {
auto active_download = active_downloads_.at(chunk); auto active_download = active_downloads_.at(chunk);
file_lock.unlock(); download_lock.unlock();
active_download->wait(); active_download->wait();
} }
@ -119,8 +120,8 @@ void file_manager::open_file::download_chunk(std::size_t chunk,
const auto data_offset = chunk * chunk_size_; const auto data_offset = chunk * chunk_size_;
const auto data_size = const auto data_size =
(chunk == read_state_.size() - 1u) ? last_chunk_size_ : chunk_size_; (chunk == read_state_.size() - 1U) ? last_chunk_size_ : chunk_size_;
if (active_downloads_.empty() && (read_state_.count() == 0u)) { if (active_downloads_.empty() && (read_state_.count() == 0U)) {
event_system::instance().raise<download_begin>(fsi_.api_path, event_system::instance().raise<download_begin>(fsi_.api_path,
fsi_.source_path); fsi_.source_path);
} }
@ -129,7 +130,7 @@ void file_manager::open_file::download_chunk(std::size_t chunk,
read_state_.count()); read_state_.count());
active_downloads_[chunk] = std::make_shared<download>(); active_downloads_[chunk] = std::make_shared<download>();
file_lock.unlock(); download_lock.unlock();
if (should_reset) { if (should_reset) {
reset_timeout(); reset_timeout();
@ -237,19 +238,19 @@ auto file_manager::open_file::is_complete() const -> bool {
} }
auto file_manager::open_file::native_operation( auto file_manager::open_file::native_operation(
const i_open_file::native_operation_callback &operation) -> api_error { const i_open_file::native_operation_callback &callback) -> api_error {
unique_recur_mutex_lock file_lock(file_mtx_); unique_recur_mutex_lock file_lock(file_mtx_);
if (stop_requested_) { if (stop_requested_) {
return api_error::download_stopped; return api_error::download_stopped;
} }
file_lock.unlock(); file_lock.unlock();
return do_io([&]() -> api_error { return operation(nf_->get_handle()); }); return do_io([&]() -> api_error { return callback(nf_->get_handle()); });
} }
auto file_manager::open_file::native_operation( auto file_manager::open_file::native_operation(
std::uint64_t new_file_size, std::uint64_t new_file_size,
const i_open_file::native_operation_callback &operation) -> api_error { const i_open_file::native_operation_callback &callback) -> api_error {
if (fsi_.directory) { if (fsi_.directory) {
return api_error::invalid_operation; return api_error::invalid_operation;
} }
@ -260,17 +261,17 @@ auto file_manager::open_file::native_operation(
} }
file_lock.unlock(); file_lock.unlock();
const auto is_empty_file = new_file_size == 0u; const auto is_empty_file = new_file_size == 0U;
const auto last_chunk = const auto last_chunk =
is_empty_file ? std::size_t(0u) is_empty_file ? std::size_t(0U)
: static_cast<std::size_t>(utils::divide_with_ceiling( : static_cast<std::size_t>(utils::divide_with_ceiling(
new_file_size, chunk_size_)) - new_file_size, chunk_size_)) -
1u; 1U;
file_lock.lock(); file_lock.lock();
if (not is_empty_file && (last_chunk < read_state_.size())) { if (not is_empty_file && (last_chunk < read_state_.size())) {
file_lock.unlock(); file_lock.unlock();
update_background_reader(0u); update_background_reader(0U);
download_chunk(last_chunk, false, true); download_chunk(last_chunk, false, true);
if (get_api_error() != api_error::success) { if (get_api_error() != api_error::success) {
@ -281,7 +282,7 @@ auto file_manager::open_file::native_operation(
const auto original_file_size = get_file_size(); const auto original_file_size = get_file_size();
auto res = do_io([&]() -> api_error { return operation(nf_->get_handle()); }); auto res = do_io([&]() -> api_error { return callback(nf_->get_handle()); });
if (res != api_error::success) { if (res != api_error::success) {
utils::error::raise_api_path_error(__FUNCTION__, get_api_path(), utils::error::raise_api_path_error(__FUNCTION__, get_api_path(),
utils::get_last_error_code(), utils::get_last_error_code(),
@ -308,8 +309,8 @@ auto file_manager::open_file::native_operation(
} }
} }
if (is_empty_file || (read_state_.size() != (last_chunk + 1u))) { if (is_empty_file || (read_state_.size() != (last_chunk + 1U))) {
read_state_.resize(is_empty_file ? 0u : last_chunk + 1u); read_state_.resize(is_empty_file ? 0U : last_chunk + 1U);
if (not is_empty_file) { if (not is_empty_file) {
read_state_[last_chunk] = true; read_state_[last_chunk] = true;
@ -317,16 +318,16 @@ auto file_manager::open_file::native_operation(
last_chunk_size_ = static_cast<std::size_t>( last_chunk_size_ = static_cast<std::size_t>(
new_file_size <= chunk_size_ ? new_file_size new_file_size <= chunk_size_ ? new_file_size
: new_file_size % chunk_size_ ? new_file_size % chunk_size_ : (new_file_size % chunk_size_) == 0U ? chunk_size_
: chunk_size_); : new_file_size % chunk_size_);
} }
if (original_file_size != new_file_size) { if (original_file_size != new_file_size) {
if (not modified_) { if (not modified_) {
um_.store_resume(*this); mgr_.store_resume(*this);
} }
modified_ = true; modified_ = true;
um_.remove_upload(get_api_path()); mgr_.remove_upload(get_api_path());
fsi_.size = new_file_size; fsi_.size = new_file_size;
const auto now = std::to_string(utils::get_file_time_now()); const auto now = std::to_string(utils::get_file_time_now());
@ -356,7 +357,7 @@ auto file_manager::open_file::read(std::size_t read_size,
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) {
return api_error::success; return api_error::success;
} }
@ -405,7 +406,7 @@ void file_manager::open_file::remove(std::uint64_t handle) {
open_file_base::remove(handle); open_file_base::remove(handle);
if (modified_ && read_state_.all() && if (modified_ && read_state_.all() &&
(get_api_error() == api_error::success)) { (get_api_error() == api_error::success)) {
um_.queue_upload(*this); mgr_.queue_upload(*this);
modified_ = false; modified_ = false;
} }
} }
@ -443,7 +444,7 @@ auto file_manager::open_file::close() -> bool {
err == api_error::download_stopped) { err == api_error::download_stopped) {
if (modified_ && not read_state_.all()) { if (modified_ && not read_state_.all()) {
set_api_error(api_error::download_incomplete); set_api_error(api_error::download_incomplete);
} else if (not modified_ && (fsi_.size > 0u) && } else if (not modified_ && (fsi_.size > 0U) &&
not read_state_.all()) { not read_state_.all()) {
set_api_error(api_error::download_stopped); set_api_error(api_error::download_stopped);
} }
@ -454,12 +455,12 @@ auto file_manager::open_file::close() -> bool {
nf_.reset(); nf_.reset();
if (modified_ && (get_api_error() == api_error::success)) { if (modified_ && (get_api_error() == api_error::success)) {
um_.queue_upload(*this); mgr_.queue_upload(*this);
} else if (modified_ && } else if (modified_ &&
(get_api_error() == api_error::download_incomplete)) { (get_api_error() == api_error::download_incomplete)) {
um_.store_resume(*this); mgr_.store_resume(*this);
} else if (get_api_error() != api_error::success) { } else if (get_api_error() != api_error::success) {
um_.remove_resume(get_api_path(), get_source_path()); mgr_.remove_resume(get_api_path(), get_source_path());
if (not utils::file::retry_delete_file(fsi_.source_path)) { if (not utils::file::retry_delete_file(fsi_.source_path)) {
utils::error::raise_api_path_error( utils::error::raise_api_path_error(
__FUNCTION__, get_api_path(), fsi_.source_path, __FUNCTION__, get_api_path(), fsi_.source_path,
@ -486,15 +487,15 @@ auto file_manager::open_file::close() -> bool {
} }
void file_manager::open_file::update_background_reader(std::size_t read_chunk) { void file_manager::open_file::update_background_reader(std::size_t read_chunk) {
recur_mutex_lock file_lock(file_mtx_); recur_mutex_lock reader_lock(file_mtx_);
read_chunk_index_ = read_chunk; read_chunk_index_ = read_chunk;
if (not reader_thread_ && not stop_requested_) { if (not reader_thread_ && not stop_requested_) {
reader_thread_ = std::make_unique<std::thread>([this]() { reader_thread_ = std::make_unique<std::thread>([this]() {
auto next_chunk = 0u; std::size_t next_chunk{};
while (not stop_requested_) { while (not stop_requested_) {
unique_recur_mutex_lock file_lock(file_mtx_); unique_recur_mutex_lock file_lock(file_mtx_);
if ((fsi_.size == 0u) || read_state_.all()) { if ((fsi_.size == 0U) || read_state_.all()) {
file_lock.unlock(); file_lock.unlock();
unique_mutex_lock io_lock(io_thread_mtx_); unique_mutex_lock io_lock(io_thread_mtx_);
@ -506,10 +507,10 @@ void file_manager::open_file::update_background_reader(std::size_t read_chunk) {
} else { } else {
do { do {
next_chunk = read_chunk_index_ = next_chunk = read_chunk_index_ =
((read_chunk_index_ + 1u) >= read_state_.size()) ((read_chunk_index_ + 1U) >= read_state_.size())
? 0u ? 0U
: read_chunk_index_ + 1u; : read_chunk_index_ + 1U;
} while ((next_chunk != 0u) && (active_downloads_.find(next_chunk) != } while ((next_chunk != 0U) && (active_downloads_.find(next_chunk) !=
active_downloads_.end())); active_downloads_.end()));
file_lock.unlock(); file_lock.unlock();
@ -523,7 +524,7 @@ void file_manager::open_file::update_background_reader(std::size_t read_chunk) {
auto file_manager::open_file::write(std::uint64_t write_offset, auto file_manager::open_file::write(std::uint64_t write_offset,
const data_buffer &data, const data_buffer &data,
std::size_t &bytes_written) -> api_error { std::size_t &bytes_written) -> api_error {
bytes_written = 0u; bytes_written = 0U;
if (fsi_.directory || provider_.is_direct_only()) { if (fsi_.directory || provider_.is_direct_only()) {
return api_error::invalid_operation; return api_error::invalid_operation;
@ -533,11 +534,11 @@ auto file_manager::open_file::write(std::uint64_t write_offset,
return api_error::success; return api_error::success;
} }
unique_recur_mutex_lock file_lock(file_mtx_); unique_recur_mutex_lock write_lock(file_mtx_);
if (stop_requested_) { if (stop_requested_) {
return api_error::download_stopped; return api_error::download_stopped;
} }
file_lock.unlock(); write_lock.unlock();
const auto start_chunk_index = const auto start_chunk_index =
static_cast<std::size_t>(write_offset / chunk_size_); static_cast<std::size_t>(write_offset / chunk_size_);
@ -547,12 +548,12 @@ auto file_manager::open_file::write(std::uint64_t write_offset,
update_background_reader(start_chunk_index); update_background_reader(start_chunk_index);
download_range(start_chunk_index, download_range(start_chunk_index,
std::min(read_state_.size() - 1u, end_chunk_index), true); std::min(read_state_.size() - 1U, end_chunk_index), true);
if (get_api_error() != api_error::success) { if (get_api_error() != api_error::success) {
return get_api_error(); return get_api_error();
} }
file_lock.lock(); write_lock.lock();
if ((write_offset + data.size()) > fsi_.size) { if ((write_offset + data.size()) > fsi_.size) {
auto res = resize(write_offset + data.size()); auto res = resize(write_offset + data.size());
if (res != api_error::success) { if (res != api_error::success) {
@ -586,10 +587,10 @@ auto file_manager::open_file::write(std::uint64_t write_offset,
} }
if (not modified_) { if (not modified_) {
um_.store_resume(*this); mgr_.store_resume(*this);
} }
modified_ = true; modified_ = true;
um_.remove_upload(get_api_path()); mgr_.remove_upload(get_api_path());
return api_error::success; return api_error::success;
} }

View File

@ -38,8 +38,8 @@ file_manager::open_file_base::open_file_base(
fsi_(std::move(fsi)), fsi_(std::move(fsi)),
last_chunk_size_(static_cast<std::size_t>( last_chunk_size_(static_cast<std::size_t>(
fsi.size <= chunk_size ? fsi.size fsi.size <= chunk_size ? fsi.size
: fsi.size % chunk_size ? fsi.size % chunk_size : (fsi.size % chunk_size) == 0U ? chunk_size
: chunk_size)), : fsi.size % chunk_size)),
open_data_(std::move(open_data)), open_data_(std::move(open_data)),
provider_(provider) { provider_(provider) {
if (not fsi.directory) { if (not fsi.directory) {
@ -51,7 +51,7 @@ void file_manager::open_file_base::add(std::uint64_t handle,
open_file_data ofd) { open_file_data ofd) {
recur_mutex_lock file_lock(file_mtx_); recur_mutex_lock file_lock(file_mtx_);
open_data_[handle] = ofd; open_data_[handle] = ofd;
if (open_data_.size() == 1u) { if (open_data_.size() == 1U) {
event_system::instance().raise<filesystem_item_opened>( event_system::instance().raise<filesystem_item_opened>(
fsi_.api_path, fsi_.source_path, fsi_.directory); fsi_.api_path, fsi_.source_path, fsi_.directory);
} }
@ -157,8 +157,8 @@ auto file_manager::open_file_base::get_handles() const
-> std::vector<std::uint64_t> { -> std::vector<std::uint64_t> {
recur_mutex_lock file_lock(file_mtx_); recur_mutex_lock file_lock(file_mtx_);
std::vector<std::uint64_t> ret; std::vector<std::uint64_t> ret;
for (const auto &kv : open_data_) { for (const auto &item : open_data_) {
ret.emplace_back(kv.first); ret.emplace_back(item.first);
} }
return ret; return ret;
@ -201,14 +201,14 @@ void file_manager::open_file_base::reset_timeout() {
last_access_ = std::chrono::system_clock::now(); last_access_ = std::chrono::system_clock::now();
} }
auto file_manager::open_file_base::set_api_error(const api_error &e) auto file_manager::open_file_base::set_api_error(const api_error &err)
-> api_error { -> api_error {
mutex_lock error_lock(error_mtx_); mutex_lock error_lock(error_mtx_);
if (error_ != e) { if (error_ != err) {
return ((error_ = (error_ == api_error::success || return ((error_ = (error_ == api_error::success ||
error_ == api_error::download_incomplete || error_ == api_error::download_incomplete ||
error_ == api_error::download_stopped error_ == api_error::download_stopped
? e ? err
: error_))); : error_)));
} }

View File

@ -37,7 +37,7 @@ file_manager::ring_buffer_open_file::ring_buffer_open_file(
std::uint8_t chunk_timeout, filesystem_item fsi, i_provider &provider) std::uint8_t chunk_timeout, filesystem_item fsi, i_provider &provider)
: ring_buffer_open_file(std::move(buffer_directory), chunk_size, : ring_buffer_open_file(std::move(buffer_directory), chunk_size,
chunk_timeout, std::move(fsi), provider, chunk_timeout, std::move(fsi), provider,
(1024ull * 1024ull * 1024ull) / chunk_size) {} (1024ULL * 1024ULL * 1024ULL) / chunk_size) {}
file_manager::ring_buffer_open_file::ring_buffer_open_file( file_manager::ring_buffer_open_file::ring_buffer_open_file(
std::string buffer_directory, std::uint64_t chunk_size, std::string buffer_directory, std::uint64_t chunk_size,
@ -47,11 +47,11 @@ file_manager::ring_buffer_open_file::ring_buffer_open_file(
ring_state_(ring_size), ring_state_(ring_size),
total_chunks_(static_cast<std::size_t>( total_chunks_(static_cast<std::size_t>(
utils::divide_with_ceiling(fsi.size, chunk_size_))) { utils::divide_with_ceiling(fsi.size, chunk_size_))) {
if (ring_size % 2u) { if ((ring_size % 2U) != 0U) {
throw std::runtime_error("ring size must be a multiple of 2"); throw std::runtime_error("ring size must be a multiple of 2");
} }
if (ring_size < 4u) { if (ring_size < 4U) {
throw std::runtime_error("ring size must be greater than or equal to 4"); throw std::runtime_error("ring size must be greater than or equal to 4");
} }
@ -59,8 +59,8 @@ file_manager::ring_buffer_open_file::ring_buffer_open_file(
throw std::runtime_error("file size is less than ring buffer size"); throw std::runtime_error("file size is less than ring buffer size");
} }
last_chunk_ = ring_state_.size() - 1u; last_chunk_ = ring_state_.size() - 1U;
ring_state_.set(0u, ring_state_.size(), true); ring_state_.set(0U, ring_state_.size(), true);
buffer_directory = utils::path::absolute(buffer_directory); buffer_directory = utils::path::absolute(buffer_directory);
if (not utils::file::create_full_directory_path(buffer_directory)) { if (not utils::file::create_full_directory_path(buffer_directory)) {
@ -113,7 +113,7 @@ auto file_manager::file_manager::ring_buffer_open_file::download_chunk(
chunk_notify_.notify_all(); chunk_notify_.notify_all();
chunk_lock.unlock(); chunk_lock.unlock();
data_buffer buffer((chunk == (total_chunks_ - 1u)) ? last_chunk_size_ data_buffer buffer((chunk == (total_chunks_ - 1U)) ? last_chunk_size_
: chunk_size_); : chunk_size_);
stop_type stop_requested = !!ring_state_[chunk % ring_state_.size()]; stop_type stop_requested = !!ring_state_[chunk % ring_state_.size()];
@ -149,8 +149,8 @@ auto file_manager::file_manager::ring_buffer_open_file::download_chunk(
void file_manager::ring_buffer_open_file::forward(std::size_t count) { void file_manager::ring_buffer_open_file::forward(std::size_t count) {
mutex_lock chunk_lock(chunk_mtx_); mutex_lock chunk_lock(chunk_mtx_);
if ((current_chunk_ + count) > (total_chunks_ - 1u)) { if ((current_chunk_ + count) > (total_chunks_ - 1U)) {
count = (total_chunks_ - 1u) - current_chunk_; count = (total_chunks_ - 1U) - current_chunk_;
} }
if ((current_chunk_ + count) <= last_chunk_) { if ((current_chunk_ + count) <= last_chunk_) {
@ -158,19 +158,19 @@ void file_manager::ring_buffer_open_file::forward(std::size_t count) {
} else { } else {
const auto added = count - (last_chunk_ - current_chunk_); const auto added = count - (last_chunk_ - current_chunk_);
if (added >= ring_state_.size()) { if (added >= ring_state_.size()) {
ring_state_.set(0u, ring_state_.size(), true); ring_state_.set(0U, ring_state_.size(), true);
current_chunk_ += count; current_chunk_ += count;
first_chunk_ += added; first_chunk_ += added;
last_chunk_ = last_chunk_ =
std::min(total_chunks_ - 1u, first_chunk_ + ring_state_.size() - 1u); std::min(total_chunks_ - 1U, first_chunk_ + ring_state_.size() - 1U);
} else { } else {
for (std::size_t i = 0u; i < added; i++) { for (std::size_t i = 0U; i < added; i++) {
ring_state_[(first_chunk_ + i) % ring_state_.size()] = true; ring_state_[(first_chunk_ + i) % ring_state_.size()] = true;
} }
first_chunk_ += added; first_chunk_ += added;
current_chunk_ += count; current_chunk_ += count;
last_chunk_ = last_chunk_ =
std::min(total_chunks_ - 1u, first_chunk_ + ring_state_.size() - 1u); std::min(total_chunks_ - 1U, first_chunk_ + ring_state_.size() - 1U);
} }
} }
@ -195,8 +195,8 @@ auto file_manager::ring_buffer_open_file::is_download_complete() const -> bool {
} }
auto file_manager::ring_buffer_open_file::native_operation( auto file_manager::ring_buffer_open_file::native_operation(
const i_open_file::native_operation_callback &operation) -> api_error { const i_open_file::native_operation_callback &callback) -> api_error {
return do_io([&]() -> api_error { return operation(nf_->get_handle()); }); return do_io([&]() -> api_error { return callback(nf_->get_handle()); });
} }
void file_manager::ring_buffer_open_file::reverse(std::size_t count) { void file_manager::ring_buffer_open_file::reverse(std::size_t count) {
@ -210,19 +210,19 @@ void file_manager::ring_buffer_open_file::reverse(std::size_t count) {
} else { } else {
const auto removed = count - (current_chunk_ - first_chunk_); const auto removed = count - (current_chunk_ - first_chunk_);
if (removed >= ring_state_.size()) { if (removed >= ring_state_.size()) {
ring_state_.set(0u, ring_state_.size(), true); ring_state_.set(0U, ring_state_.size(), true);
current_chunk_ -= count; current_chunk_ -= count;
first_chunk_ = current_chunk_; first_chunk_ = current_chunk_;
last_chunk_ = last_chunk_ =
std::min(total_chunks_ - 1u, first_chunk_ + ring_state_.size() - 1u); std::min(total_chunks_ - 1U, first_chunk_ + ring_state_.size() - 1U);
} else { } else {
for (std::size_t i = 0u; i < removed; i++) { for (std::size_t i = 0U; i < removed; i++) {
ring_state_[(last_chunk_ - i) % ring_state_.size()] = true; ring_state_[(last_chunk_ - i) % ring_state_.size()] = true;
} }
first_chunk_ -= removed; first_chunk_ -= removed;
current_chunk_ -= count; current_chunk_ -= count;
last_chunk_ = last_chunk_ =
std::min(total_chunks_ - 1u, first_chunk_ + ring_state_.size() - 1u); std::min(total_chunks_ - 1U, first_chunk_ + ring_state_.size() - 1U);
} }
} }
@ -239,7 +239,7 @@ auto file_manager::ring_buffer_open_file::read(std::size_t read_size,
reset_timeout(); reset_timeout();
read_size = utils::calculate_read_size(fsi_.size, read_size, read_offset); read_size = utils::calculate_read_size(fsi_.size, read_size, read_offset);
if (read_size == 0u) { if (read_size == 0U) {
return api_error::success; return api_error::success;
} }
@ -250,7 +250,7 @@ auto file_manager::ring_buffer_open_file::read(std::size_t read_size,
auto res = api_error::success; auto res = api_error::success;
for (std::size_t chunk = start_chunk_index; for (std::size_t chunk = start_chunk_index;
(res == api_error::success) && (read_size > 0u); chunk++) { (res == api_error::success) && (read_size > 0U); chunk++) {
if (chunk > current_chunk_) { if (chunk > current_chunk_) {
forward(chunk - current_chunk_); forward(chunk - current_chunk_);
} else if (chunk < current_chunk_) { } else if (chunk < current_chunk_) {
@ -264,20 +264,20 @@ auto file_manager::ring_buffer_open_file::read(std::size_t read_size,
res = do_io([this, &buffer, &chunk, &data, read_offset, res = do_io([this, &buffer, &chunk, &data, read_offset,
&to_read]() -> api_error { &to_read]() -> api_error {
std::size_t bytes_read{}; std::size_t bytes_read{};
auto res = nf_->read_bytes(buffer.data(), buffer.size(), auto ret = nf_->read_bytes(buffer.data(), buffer.size(),
((chunk % ring_state_.size()) * chunk_size_), ((chunk % ring_state_.size()) * chunk_size_),
bytes_read) bytes_read)
? api_error::success ? api_error::success
: api_error::os_error; : api_error::os_error;
if (res == api_error::success) { if (ret == api_error::success) {
data.insert(data.end(), buffer.begin() + read_offset, data.insert(data.end(), buffer.begin() + read_offset,
buffer.begin() + read_offset + to_read); buffer.begin() + read_offset + to_read);
reset_timeout(); reset_timeout();
} }
return res; return ret;
}); });
read_offset = 0u; read_offset = 0U;
read_size -= to_read; read_size -= to_read;
} }
} }
@ -294,7 +294,7 @@ void file_manager::ring_buffer_open_file::set(std::size_t first_chunk,
} }
first_chunk_ = first_chunk; first_chunk_ = first_chunk;
last_chunk_ = first_chunk_ + ring_state_.size() - 1u; last_chunk_ = first_chunk_ + ring_state_.size() - 1U;
if (current_chunk > last_chunk_) { if (current_chunk > last_chunk_) {
chunk_notify_.notify_all(); chunk_notify_.notify_all();
@ -303,7 +303,7 @@ void file_manager::ring_buffer_open_file::set(std::size_t first_chunk,
} }
current_chunk_ = current_chunk; current_chunk_ = current_chunk;
ring_state_.set(0u, ring_state_.size(), false); ring_state_.set(0U, ring_state_.size(), false);
chunk_notify_.notify_all(); chunk_notify_.notify_all();
} }

View File

@ -48,8 +48,8 @@ void file_manager::upload::cancel() {
void file_manager::upload::stop() { stop_requested_ = true; } void file_manager::upload::stop() { stop_requested_ = true; }
void file_manager::upload::upload_thread() { void file_manager::upload::upload_thread() {
error_ = provider_.upload_file(fsi_.api_path, fsi_.source_path, error_ =
fsi_.encryption_token, stop_requested_); provider_.upload_file(fsi_.api_path, fsi_.source_path, stop_requested_);
if (not utils::file::reset_modified_time(fsi_.source_path)) { if (not utils::file::reset_modified_time(fsi_.source_path)) {
utils::error::raise_api_path_error( utils::error::raise_api_path_error(
__FUNCTION__, fsi_.api_path, fsi_.source_path, __FUNCTION__, fsi_.api_path, fsi_.source_path,

View File

@ -56,11 +56,11 @@ auto main(int argc, char **argv) -> int {
if (argc == 1) { if (argc == 1) {
argc++; argc++;
static std::string cmd(argv[0U]); static std::string cmd(argv[0U]);
static std::vector<const char *> v({&cmd[0U], "-h"}); static std::vector<const char *> v({cmd.data(), "-h"});
argv = (char **)&v[0U]; argv = (char **)v.data();
} }
auto pt = utils::cli::get_provider_type_from_args(argc, argv); auto prov = utils::cli::get_provider_type_from_args(argc, argv);
std::string data_directory; std::string data_directory;
auto res = utils::cli::parse_string_option( auto res = utils::cli::parse_string_option(
@ -81,7 +81,7 @@ auto main(int argc, char **argv) -> int {
std::string remote_host; std::string remote_host;
std::uint16_t remote_port{}; std::uint16_t remote_port{};
std::string unique_id; std::string unique_id;
if ((res == exit_code::success) && (pt == provider_type::remote)) { if ((res == exit_code::success) && (prov == provider_type::remote)) {
std::string data; std::string data;
if ((res = utils::cli::parse_string_option( if ((res = utils::cli::parse_string_option(
argc, argv, utils::cli::options::remote_mount_option, data)) == argc, argv, utils::cli::options::remote_mount_option, data)) ==
@ -98,7 +98,7 @@ auto main(int argc, char **argv) -> int {
try { try {
remote_port = utils::string::to_uint16(parts[1U]); remote_port = utils::string::to_uint16(parts[1U]);
data_directory = utils::path::combine( data_directory = utils::path::combine(
data_directory.empty() ? app_config::default_data_directory(pt) data_directory.empty() ? app_config::default_data_directory(prov)
: data_directory, : data_directory,
{utils::string::replace_copy(unique_id, ':', '_')}); {utils::string::replace_copy(unique_id, ':', '_')});
} catch (const std::exception &e) { } catch (const std::exception &e) {
@ -111,7 +111,7 @@ auto main(int argc, char **argv) -> int {
} }
#ifdef REPERTORY_ENABLE_S3 #ifdef REPERTORY_ENABLE_S3
if ((res == exit_code::success) && (pt == provider_type::s3)) { if ((res == exit_code::success) && (prov == provider_type::s3)) {
std::string data; std::string data;
if ((res = utils::cli::parse_string_option(argc, argv, if ((res = utils::cli::parse_string_option(argc, argv,
utils::cli::options::name_option, utils::cli::options::name_option,
@ -121,10 +121,11 @@ auto main(int argc, char **argv) -> int {
std::cerr << "Name of S3 instance not provided" << std::endl; std::cerr << "Name of S3 instance not provided" << std::endl;
res = exit_code::invalid_syntax; res = exit_code::invalid_syntax;
} else { } else {
data_directory = utils::path::combine( data_directory = utils::path::absolute(
data_directory.empty() ? app_config::default_data_directory(pt) data_directory.empty()
: data_directory, ? utils::path::combine(app_config::default_data_directory(prov),
{unique_id}); {unique_id})
: data_directory);
} }
} }
} }
@ -145,11 +146,11 @@ auto main(int argc, char **argv) -> int {
idx++) { idx++) {
res = cli::actions::perform_action( res = cli::actions::perform_action(
utils::cli::options::option_list[idx], argc, argv, data_directory, utils::cli::options::option_list[idx], argc, argv, data_directory,
pt, unique_id, user, password); prov, unique_id, user, password);
} }
if (res == exit_code::option_not_found) { if (res == exit_code::option_not_found) {
res = cli::actions::mount(argc, argv, data_directory, mount_result, pt, res = cli::actions::mount(argc, argv, data_directory, mount_result,
remote_host, remote_port, unique_id); prov, remote_host, remote_port, unique_id);
} }
} }
} }

View File

@ -185,11 +185,10 @@ auto lock_data::wait_for_lock(int fd, std::uint8_t retry_count) -> int {
auto create_meta_attributes( auto create_meta_attributes(
std::uint64_t accessed_date, std::uint32_t attributes, std::uint64_t accessed_date, std::uint32_t attributes,
std::uint64_t changed_date, std::uint64_t creation_date, bool directory, std::uint64_t changed_date, std::uint64_t creation_date, bool directory,
const std::string &encryption_token, std::uint32_t gid, std::uint32_t gid, const std::string &key, std::uint32_t mode,
const std::string &key, std::uint32_t mode, std::uint64_t modified_date, std::uint64_t modified_date, std::uint32_t osx_backup,
std::uint32_t osx_backup, std::uint32_t osx_flags, std::uint64_t size, std::uint32_t osx_flags, std::uint64_t size, const std::string &source_path,
const std::string &source_path, std::uint32_t uid, std::uint32_t uid, std::uint64_t written_date) -> api_meta_map {
std::uint64_t written_date) -> api_meta_map {
return { return {
{META_ACCESSED, std::to_string(accessed_date)}, {META_ACCESSED, std::to_string(accessed_date)},
{META_ATTRIBUTES, std::to_string(attributes)}, {META_ATTRIBUTES, std::to_string(attributes)},
@ -197,7 +196,6 @@ auto create_meta_attributes(
{META_CHANGED, std::to_string(changed_date)}, {META_CHANGED, std::to_string(changed_date)},
{META_CREATION, std::to_string(creation_date)}, {META_CREATION, std::to_string(creation_date)},
{META_DIRECTORY, utils::string::from_bool(directory)}, {META_DIRECTORY, utils::string::from_bool(directory)},
{META_ENCRYPTION_TOKEN, encryption_token},
{META_GID, std::to_string(gid)}, {META_GID, std::to_string(gid)},
{META_KEY, key}, {META_KEY, key},
{META_MODE, std::to_string(mode)}, {META_MODE, std::to_string(mode)},
@ -217,8 +215,7 @@ auto provider_meta_handler(i_provider &provider, bool directory,
file.accessed_date, file.accessed_date,
directory ? FILE_ATTRIBUTE_DIRECTORY directory ? FILE_ATTRIBUTE_DIRECTORY
: FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_ARCHIVE, : FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_ARCHIVE,
file.changed_date, file.creation_date, directory, file.encryption_token, file.changed_date, file.creation_date, directory, getgid(), file.key,
getgid(), file.key,
directory ? S_IFDIR | S_IRUSR | S_IWUSR | S_IXUSR directory ? S_IFDIR | S_IRUSR | S_IWUSR | S_IXUSR
: S_IFREG | S_IRUSR | S_IWUSR, : S_IFREG | S_IRUSR | S_IWUSR,
file.modified_date, 0u, 0u, file.file_size, file.source_path, getuid(), file.modified_date, 0u, 0u, file.file_size, file.source_path, getuid(),

View File

@ -166,11 +166,10 @@ auto lock_data::set_mount_state(bool active, const std::string &mount_location,
auto create_meta_attributes( auto create_meta_attributes(
std::uint64_t accessed_date, std::uint32_t attributes, std::uint64_t accessed_date, std::uint32_t attributes,
std::uint64_t changed_date, std::uint64_t creation_date, bool directory, std::uint64_t changed_date, std::uint64_t creation_date, bool directory,
const std::string &encryption_token, std::uint32_t gid, std::uint32_t gid, const std::string &key, std::uint32_t mode,
const std::string &key, std::uint32_t mode, std::uint64_t modified_date, std::uint64_t modified_date, std::uint32_t osx_backup,
std::uint32_t osx_backup, std::uint32_t osx_flags, std::uint64_t size, std::uint32_t osx_flags, std::uint64_t size, const std::string &source_path,
const std::string &source_path, std::uint32_t uid, std::uint32_t uid, std::uint64_t written_date) -> api_meta_map {
std::uint64_t written_date) -> api_meta_map {
return { return {
{META_ACCESSED, std::to_string(accessed_date)}, {META_ACCESSED, std::to_string(accessed_date)},
{META_ATTRIBUTES, std::to_string(attributes)}, {META_ATTRIBUTES, std::to_string(attributes)},
@ -178,7 +177,6 @@ auto create_meta_attributes(
{META_CHANGED, std::to_string(changed_date)}, {META_CHANGED, std::to_string(changed_date)},
{META_CREATION, std::to_string(creation_date)}, {META_CREATION, std::to_string(creation_date)},
{META_DIRECTORY, utils::string::from_bool(directory)}, {META_DIRECTORY, utils::string::from_bool(directory)},
{META_ENCRYPTION_TOKEN, encryption_token},
{META_GID, std::to_string(gid)}, {META_GID, std::to_string(gid)},
{META_KEY, key}, {META_KEY, key},
{META_MODE, std::to_string(mode)}, {META_MODE, std::to_string(mode)},
@ -198,9 +196,9 @@ auto provider_meta_handler(i_provider &provider, bool directory,
file.accessed_date, file.accessed_date,
directory ? FILE_ATTRIBUTE_DIRECTORY directory ? FILE_ATTRIBUTE_DIRECTORY
: FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_ARCHIVE, : FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_ARCHIVE,
file.changed_date, file.creation_date, directory, file.encryption_token, file.changed_date, file.creation_date, directory, 0u, file.key,
0u, file.key, directory ? S_IFDIR : S_IFREG, file.modified_date, 0u, 0u, directory ? S_IFDIR : S_IFREG, file.modified_date, 0u, 0u, file.file_size,
file.file_size, file.source_path, 0u, file.modified_date); file.source_path, 0u, file.modified_date);
auto res = provider.set_item_meta(file.api_path, meta); auto res = provider.set_item_meta(file.api_path, meta);
if (res == api_error::success) { if (res == api_error::success) {
event_system::instance().raise<filesystem_item_added>( event_system::instance().raise<filesystem_item_added>(

File diff suppressed because it is too large Load Diff

View File

@ -33,7 +33,7 @@
namespace repertory { namespace repertory {
encrypt_provider::encrypt_provider(app_config &config) : config_(config) {} encrypt_provider::encrypt_provider(app_config &config) : config_(config) {}
auto encrypt_provider::create_api_file(const std::string api_path, auto encrypt_provider::create_api_file(const std::string &api_path,
bool directory, bool directory,
const std::string &source_path) const std::string &source_path)
-> api_file { -> api_file {
@ -222,21 +222,23 @@ auto encrypt_provider::get_directory_items(const std::string &api_path,
for (const auto &dir_entry : for (const auto &dir_entry :
std::filesystem::directory_iterator(source_path)) { std::filesystem::directory_iterator(source_path)) {
try { try {
std::string api_path{}; std::string entry_api_path{};
if (dir_entry.is_directory()) { if (dir_entry.is_directory()) {
db_->Get(rocksdb::ReadOptions(), dir_family_, db_->Get(rocksdb::ReadOptions(), dir_family_,
dir_entry.path().string(), &api_path); dir_entry.path().string(), &entry_api_path);
if (api_path.empty()) { if (entry_api_path.empty()) {
const auto cfg = config_.get_encrypt_config(); const auto cfg = config_.get_encrypt_config();
for (const auto &child_dir_entry : for (const auto &child_dir_entry :
std::filesystem::directory_iterator(dir_entry.path())) { std::filesystem::directory_iterator(dir_entry.path())) {
if (process_directory_entry(child_dir_entry, cfg, api_path)) { if (process_directory_entry(child_dir_entry, cfg,
api_path = utils::path::get_parent_api_path(api_path); entry_api_path)) {
entry_api_path =
utils::path::get_parent_api_path(entry_api_path);
break; break;
} }
} }
if (api_path.empty()) { if (entry_api_path.empty()) {
continue; continue;
} }
} }
@ -246,16 +248,16 @@ auto encrypt_provider::get_directory_items(const std::string &api_path,
dir_entry.path().string(), &api_path_data); dir_entry.path().string(), &api_path_data);
if (api_path_data.empty()) { if (api_path_data.empty()) {
const auto cfg = config_.get_encrypt_config(); const auto cfg = config_.get_encrypt_config();
if (not process_directory_entry(dir_entry, cfg, api_path)) { if (not process_directory_entry(dir_entry, cfg, entry_api_path)) {
continue; continue;
} }
} else { } else {
api_path = entry_api_path =
json::parse(api_path_data).at("api_path").get<std::string>(); json::parse(api_path_data).at("api_path").get<std::string>();
} }
} }
auto file = create_api_file(api_path, dir_entry.is_directory(), auto file = create_api_file(entry_api_path, dir_entry.is_directory(),
dir_entry.path().string()); dir_entry.path().string());
directory_item di{}; directory_item di{};
@ -464,13 +466,13 @@ auto encrypt_provider::get_filesystem_item(const std::string &api_path,
} }
if (directory) { if (directory) {
std::string api_path{}; std::string db_api_path{};
db_->Get(rocksdb::ReadOptions(), dir_family_, source_path, &api_path); db_->Get(rocksdb::ReadOptions(), dir_family_, source_path, &db_api_path);
if (api_path.empty()) { if (db_api_path.empty()) {
return api_error::item_not_found; return api_error::item_not_found;
} }
fsi.api_parent = utils::path::get_parent_api_path(api_path); fsi.api_parent = utils::path::get_parent_api_path(db_api_path);
fsi.api_path = api_path; fsi.api_path = db_api_path;
fsi.directory = true; fsi.directory = true;
fsi.size = 0U; fsi.size = 0U;
fsi.source_path = source_path; fsi.source_path = source_path;
@ -761,7 +763,7 @@ void encrypt_provider::remove_deleted_files() {
} }
auto encrypt_provider::start(api_item_added_callback /*api_item_added*/, auto encrypt_provider::start(api_item_added_callback /*api_item_added*/,
i_file_manager * /*fm*/) -> bool { i_file_manager * /*mgr*/) -> bool {
if (not is_online()) { if (not is_online()) {
return false; return false;
} }

View File

@ -24,8 +24,6 @@
#include "app_config.hpp" #include "app_config.hpp"
#include "comm/curl/curl_comm.hpp" #include "comm/curl/curl_comm.hpp"
#include "comm/i_http_comm.hpp" #include "comm/i_http_comm.hpp"
#include "comm/i_s3_comm.hpp"
#include "comm/s3/s3_comm.hpp"
#include "events/events.hpp" #include "events/events.hpp"
#include "providers/encrypt/encrypt_provider.hpp" #include "providers/encrypt/encrypt_provider.hpp"
#include "providers/s3/s3_provider.hpp" #include "providers/s3/s3_provider.hpp"
@ -51,9 +49,6 @@ auto create_provider(const provider_type &pt, app_config &config)
mutex_lock lock(mutex); mutex_lock lock(mutex);
static std::unique_ptr<i_http_comm> comm; static std::unique_ptr<i_http_comm> comm;
#if defined(REPERTORY_ENABLE_S3)
static std::unique_ptr<i_s3_comm> s3_comm_;
#endif // defined(REPERTORY_ENABLE_S3)
switch (pt) { switch (pt) {
case provider_type::sia: { case provider_type::sia: {
@ -64,9 +59,10 @@ auto create_provider(const provider_type &pt, app_config &config)
} }
#if defined(REPERTORY_ENABLE_S3) #if defined(REPERTORY_ENABLE_S3)
case provider_type::s3: { case provider_type::s3: {
create_comm<i_s3_comm, s3_comm, app_config>(s3_comm_, config); create_comm<i_http_comm, curl_comm, s3_config>(comm,
config.get_s3_config());
return std::unique_ptr<i_provider>( return std::unique_ptr<i_provider>(
dynamic_cast<i_provider *>(new s3_provider(config, *s3_comm_))); dynamic_cast<i_provider *>(new s3_provider(config, *comm)));
} }
#endif // defined(REPERTORY_ENABLE_S3) #endif // defined(REPERTORY_ENABLE_S3)
case provider_type::encrypt: { case provider_type::encrypt: {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -26,160 +26,92 @@ namespace repertory::remote {
auto create_open_flags(std::uint32_t flags) -> open_flags { auto create_open_flags(std::uint32_t flags) -> open_flags {
open_flags ret{}; open_flags ret{};
{ {
const auto f = (flags & 3u); const auto val = (flags & 3U);
ret |= (f == 1u) ? open_flags::write_only ret |= (val == 1U) ? open_flags::write_only
: (f == 2u) ? open_flags::read_write : (val == 2U) ? open_flags::read_write
: open_flags::read_only; : open_flags::read_only;
} }
if (flags & static_cast<std::uint32_t>(O_CREAT)) {
ret |= open_flags::create;
}
if (flags & static_cast<std::uint32_t>(O_EXCL)) { const auto set_if_has_flag = [&flags, &ret](auto flag, open_flags o_flag) {
ret |= open_flags::excl; if ((flags & static_cast<std::uint32_t>(flag)) != 0U) {
ret |= o_flag;
} }
};
if (flags & static_cast<std::uint32_t>(O_NOCTTY)) { set_if_has_flag(O_APPEND, open_flags::append);
ret |= open_flags::no_ctty; set_if_has_flag(O_ASYNC, open_flags::async);
} set_if_has_flag(O_CLOEXEC, open_flags::clo_exec);
set_if_has_flag(O_CREAT, open_flags::create);
if (flags & static_cast<std::uint32_t>(O_TRUNC)) {
ret |= open_flags::truncate;
}
if (flags & static_cast<std::uint32_t>(O_APPEND)) {
ret |= open_flags::append;
}
if (flags & static_cast<std::uint32_t>(O_NONBLOCK)) {
ret |= open_flags::non_blocking;
}
if (flags & static_cast<std::uint32_t>(O_SYNC)) {
ret |= open_flags::sync;
}
if (flags & static_cast<std::uint32_t>(O_ASYNC)) {
ret |= open_flags::async;
}
if (flags & static_cast<std::uint32_t>(O_DIRECTORY)) {
ret |= open_flags::directory;
}
if (flags & static_cast<std::uint32_t>(O_NOFOLLOW)) {
ret |= open_flags::no_follow;
}
if (flags & static_cast<std::uint32_t>(O_CLOEXEC)) {
ret |= open_flags::clo_exec;
}
#ifdef O_DIRECT #ifdef O_DIRECT
if (flags & static_cast<std::uint32_t>(O_DIRECT)) { set_if_has_flag(O_DIRECT, open_flags::direct);
ret |= open_flags::direct;
}
#endif
#ifdef O_NOATIME
if (flags & static_cast<std::uint32_t>(O_NOATIME)) {
ret |= open_flags::no_atime;
}
#endif
#ifdef O_PATH
if (flags & static_cast<std::uint32_t>(O_PATH)) {
ret |= open_flags::path;
}
#endif
#ifdef O_TMPFILE
if (flags & static_cast<std::uint32_t>(O_TMPFILE)) {
ret |= open_flags::temp_file;
}
#endif #endif
set_if_has_flag(O_DIRECTORY, open_flags::directory);
#ifdef O_DSYNC #ifdef O_DSYNC
if (flags & static_cast<std::uint32_t>(O_DSYNC)) { set_if_has_flag(O_DSYNC, open_flags::dsync);
ret |= open_flags::dsync;
}
#endif #endif
set_if_has_flag(O_EXCL, open_flags::excl);
#ifdef O_NOATIME
set_if_has_flag(O_NOATIME, open_flags::no_atime);
#endif
set_if_has_flag(O_NOCTTY, open_flags::no_ctty);
set_if_has_flag(O_NOFOLLOW, open_flags::no_follow);
set_if_has_flag(O_NONBLOCK, open_flags::non_blocking);
#ifdef O_PATH
set_if_has_flag(O_PATH, open_flags::path);
#endif
set_if_has_flag(O_SYNC, open_flags::sync);
#ifdef O_TMPFILE
set_if_has_flag(O_TMPFILE, open_flags::temp_file);
#endif
set_if_has_flag(O_TRUNC, open_flags::truncate);
return ret; return ret;
} }
auto create_os_open_flags(const open_flags &flags) -> std::uint32_t { auto create_os_open_flags(const open_flags &flags) -> std::uint32_t {
std::uint32_t ret = 0u; std::uint32_t ret{};
if ((flags & open_flags::read_write) == open_flags::read_write) { const auto set_if_has_flag = [&flags, &ret](auto o_flag, auto flag) -> bool {
ret |= static_cast<std::uint32_t>(O_RDWR); if ((flags & o_flag) == o_flag) {
} else if ((flags & open_flags::write_only) == open_flags::write_only) { ret |= static_cast<std::uint32_t>(flag);
ret |= static_cast<std::uint32_t>(O_WRONLY); return true;
} else { }
return false;
};
if (not set_if_has_flag(open_flags::read_write, O_RDWR)) {
if (not set_if_has_flag(open_flags::write_only, O_WRONLY)) {
ret |= static_cast<std::uint32_t>(O_RDONLY); ret |= static_cast<std::uint32_t>(O_RDONLY);
} }
if ((flags & open_flags::create) == open_flags::create) {
ret |= static_cast<std::uint32_t>(O_CREAT);
} }
if ((flags & open_flags::excl) == open_flags::excl) { set_if_has_flag(open_flags::append, O_APPEND);
ret |= static_cast<std::uint32_t>(O_EXCL); set_if_has_flag(open_flags::async, O_ASYNC);
} set_if_has_flag(open_flags::clo_exec, O_CLOEXEC);
set_if_has_flag(open_flags::create, O_CREAT);
if ((flags & open_flags::no_ctty) == open_flags::no_ctty) {
ret |= static_cast<std::uint32_t>(O_NOCTTY);
}
if ((flags & open_flags::truncate) == open_flags::truncate) {
ret |= static_cast<std::uint32_t>(O_TRUNC);
}
if ((flags & open_flags::append) == open_flags::append) {
ret |= static_cast<std::uint32_t>(O_APPEND);
}
if ((flags & open_flags::non_blocking) == open_flags::non_blocking) {
ret |= static_cast<std::uint32_t>(O_NONBLOCK);
}
if ((flags & open_flags::sync) == open_flags::sync) {
ret |= static_cast<std::uint32_t>(O_SYNC);
}
if ((flags & open_flags::async) == open_flags::async) {
ret |= static_cast<std::uint32_t>(O_ASYNC);
}
if ((flags & open_flags::directory) == open_flags::directory) {
ret |= static_cast<std::uint32_t>(O_DIRECTORY);
}
if ((flags & open_flags::no_follow) == open_flags::no_follow) {
ret |= static_cast<std::uint32_t>(O_NOFOLLOW);
}
if ((flags & open_flags::clo_exec) == open_flags::clo_exec) {
ret |= static_cast<std::uint32_t>(O_CLOEXEC);
}
#ifdef O_DIRECT #ifdef O_DIRECT
if ((flags & open_flags::direct) == open_flags::direct) { set_if_has_flag(open_flags::direct, O_DIRECT);
ret |= static_cast<std::uint32_t>(O_DIRECT);
}
#endif
#ifdef O_NOATIME
if ((flags & open_flags::no_atime) == open_flags::no_atime) {
ret |= static_cast<std::uint32_t>(O_NOATIME);
}
#endif
#ifdef O_PATH
if ((flags & open_flags::path) == open_flags::path) {
ret |= static_cast<std::uint32_t>(O_PATH);
}
#endif
#ifdef O_TMPFILE
if ((flags & open_flags::temp_file) == open_flags::temp_file) {
ret |= static_cast<std::uint32_t>(O_TMPFILE);
}
#endif #endif
set_if_has_flag(open_flags::directory, O_DIRECTORY);
#ifdef O_DSYNC #ifdef O_DSYNC
if ((flags & open_flags::dsync) == open_flags::dsync) { set_if_has_flag(open_flags::dsync, O_DSYNC);
ret |= static_cast<std::uint32_t>(O_DSYNC);
}
#endif #endif
set_if_has_flag(open_flags::excl, O_EXCL);
#ifdef O_NOATIME
set_if_has_flag(open_flags::no_atime, O_NOATIME);
#endif
set_if_has_flag(open_flags::no_ctty, O_NOCTTY);
set_if_has_flag(open_flags::no_follow, O_NOFOLLOW);
set_if_has_flag(open_flags::non_blocking, O_NONBLOCK);
#ifdef O_PATH
set_if_has_flag(open_flags::path, O_PATH);
#endif
set_if_has_flag(open_flags::sync, O_SYNC);
#ifdef O_TMPFILE
set_if_has_flag(open_flags::temp_file, O_TMPFILE);
#endif
set_if_has_flag(open_flags::truncate, O_TRUNC);
return ret; return ret;
} }
#endif #endif

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