Compare commits
22 Commits
v2.0.2-rc
...
v2.1.0-rc.
| Author | SHA1 | Date | |
|---|---|---|---|
| 97d557a1a9 | |||
| a021d8cbd4 | |||
| 050f004716 | |||
| ea9a25816d | |||
| eaccfcb8fd | |||
| 2af0ab4641 | |||
| e5169445ae | |||
| 0471faab2b | |||
| d632e46dc3 | |||
| bbef6d1898 | |||
| 29c31f7f3e | |||
| 3b139d0b55 | |||
| 164abb843d | |||
| 4de61970f6 | |||
| 7d10621c0c | |||
| 20e21c0a69 | |||
| f198cd49ee | |||
| 5ab7301cbe | |||
| 87d336141c | |||
| 62555e6125 | |||
| 24418ba03d | |||
| fa439c634f |
@@ -3,7 +3,9 @@ _mkgmtime
|
|||||||
_sh_denyno
|
_sh_denyno
|
||||||
_sh_denyrd
|
_sh_denyrd
|
||||||
_sh_denyrw
|
_sh_denyrw
|
||||||
|
_spawnv
|
||||||
aarch64
|
aarch64
|
||||||
|
abcdefgh
|
||||||
advapi32
|
advapi32
|
||||||
armv8
|
armv8
|
||||||
autogen
|
autogen
|
||||||
@@ -15,8 +17,12 @@ boost_asio_has_std_string_view
|
|||||||
bugprone
|
bugprone
|
||||||
cflags
|
cflags
|
||||||
chrono
|
chrono
|
||||||
|
clsid
|
||||||
cmake_current_source_dir
|
cmake_current_source_dir
|
||||||
|
cmdc
|
||||||
|
coinit_apartmentthreaded
|
||||||
comdlg32
|
comdlg32
|
||||||
|
conin$
|
||||||
cppcoreguidelines
|
cppcoreguidelines
|
||||||
cppdbg
|
cppdbg
|
||||||
cppflags
|
cppflags
|
||||||
@@ -25,7 +31,11 @@ cpptrace
|
|||||||
cppvsdbg
|
cppvsdbg
|
||||||
create_notraverse
|
create_notraverse
|
||||||
crypto_aead_xchacha20poly1305_ietf_npubbytes
|
crypto_aead_xchacha20poly1305_ietf_npubbytes
|
||||||
|
cspan
|
||||||
cstdint
|
cstdint
|
||||||
|
curl_zstd
|
||||||
|
curle_couldnt_resolve_host
|
||||||
|
curlopt_aws_sigv4
|
||||||
cxxflags
|
cxxflags
|
||||||
cxxstd
|
cxxstd
|
||||||
d_largefile64_source
|
d_largefile64_source
|
||||||
@@ -50,6 +60,7 @@ dcurl_staticlib
|
|||||||
dcurl_use_libpsl
|
dcurl_use_libpsl
|
||||||
dcurl_use_libssh2
|
dcurl_use_libssh2
|
||||||
dcurl_zlib
|
dcurl_zlib
|
||||||
|
dcurl_zstd
|
||||||
ddebug
|
ddebug
|
||||||
decmult_gen_prec_bits
|
decmult_gen_prec_bits
|
||||||
decmult_window_size
|
decmult_window_size
|
||||||
@@ -82,6 +93,7 @@ dspdlog_fmt_external
|
|||||||
dthreads_prefer_pthread_flag
|
dthreads_prefer_pthread_flag
|
||||||
dunw_local_only
|
dunw_local_only
|
||||||
duse_libidn2
|
duse_libidn2
|
||||||
|
duse_nghttp2
|
||||||
duuid_build_tests
|
duuid_build_tests
|
||||||
dwith_benchmark
|
dwith_benchmark
|
||||||
dwith_gflags
|
dwith_gflags
|
||||||
@@ -93,6 +105,9 @@ endforeach
|
|||||||
endfunction
|
endfunction
|
||||||
eventlib
|
eventlib
|
||||||
expect_streq
|
expect_streq
|
||||||
|
expect_strne
|
||||||
|
falloc_fl_keep_size
|
||||||
|
fallocate
|
||||||
fallocate_impl
|
fallocate_impl
|
||||||
fext
|
fext
|
||||||
fgetattr
|
fgetattr
|
||||||
@@ -101,7 +116,10 @@ filebase
|
|||||||
flac_version
|
flac_version
|
||||||
flag_nopath
|
flag_nopath
|
||||||
flarge
|
flarge
|
||||||
|
folderid
|
||||||
fontconfig_version
|
fontconfig_version
|
||||||
|
foob
|
||||||
|
fooba
|
||||||
freetype2_version
|
freetype2_version
|
||||||
fsetattr_x
|
fsetattr_x
|
||||||
fusermount
|
fusermount
|
||||||
@@ -113,13 +131,18 @@ googletest
|
|||||||
gpath
|
gpath
|
||||||
gtest_version
|
gtest_version
|
||||||
has_setxattr
|
has_setxattr
|
||||||
|
hkey
|
||||||
|
hresult
|
||||||
httpapi
|
httpapi
|
||||||
httplib
|
httplib
|
||||||
|
hwnd
|
||||||
icudata
|
icudata
|
||||||
icui18n
|
icui18n
|
||||||
icuuc
|
icuuc
|
||||||
|
inproc
|
||||||
iostreams
|
iostreams
|
||||||
iphlpapi
|
iphlpapi
|
||||||
|
ipstream
|
||||||
jthread
|
jthread
|
||||||
libbitcoin
|
libbitcoin
|
||||||
libbitcoinsystem
|
libbitcoinsystem
|
||||||
@@ -127,6 +150,7 @@ libcurl
|
|||||||
libdsm
|
libdsm
|
||||||
libevent
|
libevent
|
||||||
libexample
|
libexample
|
||||||
|
libexpat
|
||||||
libfuse3
|
libfuse3
|
||||||
libgmock
|
libgmock
|
||||||
libgtest
|
libgtest
|
||||||
@@ -139,39 +163,56 @@ libuuid
|
|||||||
libuuid_include_dirs
|
libuuid_include_dirs
|
||||||
libvlc
|
libvlc
|
||||||
linkflags
|
linkflags
|
||||||
|
llabsll
|
||||||
|
localappdata
|
||||||
|
lpbyte
|
||||||
|
lpthread
|
||||||
lptr
|
lptr
|
||||||
lpwstr
|
lpwstr
|
||||||
markdownlint
|
markdownlint
|
||||||
mbig
|
mbig
|
||||||
|
minio
|
||||||
msvc
|
msvc
|
||||||
msvcr120
|
msvcr120
|
||||||
msys2
|
msys2
|
||||||
mtune
|
mtune
|
||||||
musl-libc
|
musl-libc
|
||||||
|
mwindows
|
||||||
nana
|
nana
|
||||||
ncrypt
|
ncrypt
|
||||||
|
nlohmann
|
||||||
nlohmann_json
|
nlohmann_json
|
||||||
nmakeprg
|
nmakeprg
|
||||||
|
noappledouble
|
||||||
|
nohup
|
||||||
nominmax
|
nominmax
|
||||||
ntstatus
|
ntstatus
|
||||||
|
nullptr
|
||||||
nuspell_version
|
nuspell_version
|
||||||
oleaut32
|
oleaut32
|
||||||
openal_version
|
openal_version
|
||||||
openssldir
|
openssldir
|
||||||
|
osascript
|
||||||
|
osxfuse
|
||||||
|
pistream
|
||||||
pkgconfig
|
pkgconfig
|
||||||
plarge_integer
|
plarge_integer
|
||||||
plex
|
plex
|
||||||
|
posix
|
||||||
println
|
println
|
||||||
project_enable_fontconfig
|
project_enable_fontconfig
|
||||||
project_enable_gtkmm
|
project_enable_gtkmm
|
||||||
project_enable_libdsm
|
project_enable_libdsm
|
||||||
project_enable_nana
|
project_enable_nana
|
||||||
|
project_macos_icns_name
|
||||||
propgrid
|
propgrid
|
||||||
psecurity_descriptor
|
psecurity_descriptor
|
||||||
|
pthreads
|
||||||
pugi
|
pugi
|
||||||
pugixml_project
|
pugixml_project
|
||||||
puint32
|
puint32
|
||||||
pvoid
|
pvoid
|
||||||
|
pwhash
|
||||||
pwstr
|
pwstr
|
||||||
rdrw
|
rdrw
|
||||||
remote_winfsp
|
remote_winfsp
|
||||||
@@ -179,25 +220,34 @@ renterd
|
|||||||
richtext
|
richtext
|
||||||
rocksdb_library
|
rocksdb_library
|
||||||
rpcrt4
|
rpcrt4
|
||||||
|
runas
|
||||||
s_igid
|
s_igid
|
||||||
s_isvtx
|
s_isvtx
|
||||||
s_iuid
|
s_iuid
|
||||||
sddl_revision_1
|
sddl_revision_1
|
||||||
secp256k1
|
secp256k1
|
||||||
secur32
|
secur32
|
||||||
|
see_mask_nocloseprocess
|
||||||
sfml_project
|
sfml_project
|
||||||
|
shellexecuteinfoa
|
||||||
shlwapi
|
shlwapi
|
||||||
|
sigchld
|
||||||
|
skynet
|
||||||
source_subdir
|
source_subdir
|
||||||
spdlog
|
spdlog
|
||||||
spdlog_project
|
spdlog_project
|
||||||
st_ctim
|
st_ctim
|
||||||
|
startf_useshowwindow
|
||||||
|
startupinfoa
|
||||||
static-libgcc
|
static-libgcc
|
||||||
static-libstdc++
|
static-libstdc++
|
||||||
stbuf
|
stbuf
|
||||||
stduuid_project
|
stduuid_project
|
||||||
strequal
|
strequal
|
||||||
|
sw_shownoactivate
|
||||||
ularge_integer
|
ularge_integer
|
||||||
uring
|
uring
|
||||||
|
url
|
||||||
userenv
|
userenv
|
||||||
utimens_impl
|
utimens_impl
|
||||||
utimensat
|
utimensat
|
||||||
@@ -213,6 +263,7 @@ wextra
|
|||||||
wfloat
|
wfloat
|
||||||
wformat=2
|
wformat=2
|
||||||
winfsp
|
winfsp
|
||||||
|
winfsp_drive
|
||||||
winhttp
|
winhttp
|
||||||
wininet
|
wininet
|
||||||
winspool
|
winspool
|
||||||
|
|||||||
5
.gitattributes
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
*.msi filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.tar.gz filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.tar.xz filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.tgz filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.zip filter=lfs diff=lfs merge=lfs -text
|
||||||
13
.gitignore
vendored
@@ -1,13 +1,16 @@
|
|||||||
|
.DS_Store
|
||||||
.cache/
|
.cache/
|
||||||
|
.vs/
|
||||||
|
Info.plist
|
||||||
build*/
|
build*/
|
||||||
compile_commands.json
|
compile_commands.json
|
||||||
cspell.json
|
cspell.json
|
||||||
.vs/
|
|
||||||
support/Dockerfile
|
|
||||||
dist/
|
|
||||||
deps/
|
deps/
|
||||||
|
dist/
|
||||||
|
override.sh
|
||||||
|
repertory.iss
|
||||||
scripts/cleanup.cmd
|
scripts/cleanup.cmd
|
||||||
scripts/cleanup.sh
|
scripts/cleanup.sh
|
||||||
version.rc
|
support/Dockerfile
|
||||||
version.cpp
|
version.cpp
|
||||||
override.sh
|
version.rc
|
||||||
|
|||||||
101
.jenkins_builds
@@ -5,57 +5,88 @@ pipeline {
|
|||||||
|
|
||||||
environment {
|
environment {
|
||||||
DEVELOPER_PRIVATE_KEY = "/.ci/repertory/cert/developer.priv"
|
DEVELOPER_PRIVATE_KEY = "/.ci/repertory/cert/developer.priv"
|
||||||
DEVELOPER_PUBLIC_KEY = "/.ci/repertory/cert/developer.pub"
|
DEVELOPER_PUBLIC_KEY = "/.ci/repertory/cert/developer.pub"
|
||||||
PROJECT_TEST_CONFIG_DIR = "/.ci/repertory/test_config"
|
PROJECT_TEST_CONFIG_DIR = "/.ci/repertory/test"
|
||||||
}
|
}
|
||||||
|
|
||||||
options {
|
options {
|
||||||
disableConcurrentBuilds()
|
disableConcurrentBuilds()
|
||||||
retry(2)
|
skipDefaultCheckout()
|
||||||
|
timestamps()
|
||||||
}
|
}
|
||||||
|
|
||||||
stages {
|
stages {
|
||||||
stage('linux_x86_64') {
|
stage('Build • Test • Deliver') {
|
||||||
agent any
|
agent any
|
||||||
|
stages {
|
||||||
steps {
|
stage('Checkout') {
|
||||||
retry(2) {
|
steps {
|
||||||
sleep time: 5, unit: 'SECONDS'
|
script {
|
||||||
sh 'scripts/make_unix.sh'
|
int maxAttempts = 6
|
||||||
|
int baseDelay = 10
|
||||||
|
for (int attempt = 1; attempt <= maxAttempts; attempt++) {
|
||||||
|
try {
|
||||||
|
checkout scm
|
||||||
|
break
|
||||||
|
} catch (err) {
|
||||||
|
if (attempt == maxAttempts) { throw err }
|
||||||
|
int waitSec = baseDelay * (1 << (attempt - 1))
|
||||||
|
echo "Checkout failed (attempt ${attempt}/${maxAttempts}). Waiting ${waitSec}s before retry..."
|
||||||
|
sleep time: waitSec, unit: 'SECONDS'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stage('mingw64') {
|
stage('linux_x86_64') {
|
||||||
agent any
|
steps {
|
||||||
|
script { retryWithBackoff(2, 5) { sh 'scripts/make_unix.sh' } }
|
||||||
steps {
|
}
|
||||||
retry(2) {
|
|
||||||
sleep time: 5, unit: 'SECONDS'
|
|
||||||
sh 'scripts/make_win32.sh'
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stage('linux_aarch64') {
|
stage('mingw64') {
|
||||||
agent any
|
steps {
|
||||||
|
script { retryWithBackoff(2, 5) { sh 'scripts/make_win32.sh' } }
|
||||||
steps {
|
}
|
||||||
retry(2) {
|
|
||||||
sleep time: 5, unit: 'SECONDS'
|
|
||||||
sh 'scripts/make_unix.sh aarch64'
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stage('deliver') {
|
stage('linux_aarch64') {
|
||||||
agent any
|
steps {
|
||||||
|
script { retryWithBackoff(2, 5) { sh 'scripts/make_unix.sh aarch64' } }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
steps {
|
stage('linux_x86_64_test') {
|
||||||
sh 'scripts/deliver.sh /mnt/repertory "" "" "" "" 1 1'
|
steps {
|
||||||
sh 'scripts/deliver.sh /mnt/repertory "" aarch64'
|
script { retryWithBackoff(2, 5) { sh 'scripts/run_tests.sh' } }
|
||||||
sh 'scripts/deliver.sh /mnt/repertory'
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('deliver') {
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
retryWithBackoff(3, 10) { sh 'scripts/deliver.sh /mnt/repertory "" "" "" "" 1 1' }
|
||||||
|
retryWithBackoff(3, 10) { sh 'scripts/deliver.sh /mnt/repertory "" aarch64' }
|
||||||
|
retryWithBackoff(3, 10) { sh 'scripts/deliver.sh /mnt/repertory' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def retryWithBackoff(int maxAttempts, int baseDelaySeconds, Closure body) {
|
||||||
|
for (int attempt = 1; attempt <= maxAttempts; attempt++) {
|
||||||
|
try {
|
||||||
|
body()
|
||||||
|
return
|
||||||
|
} catch (err) {
|
||||||
|
if (attempt == maxAttempts) { throw err }
|
||||||
|
int waitSec = baseDelaySeconds * (1 << (attempt - 1))
|
||||||
|
echo "Step failed (attempt ${attempt}/${maxAttempts}). Waiting ${waitSec}s before retry..."
|
||||||
|
sleep time: waitSec, unit: 'SECONDS'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
79
.jenkins_macos
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
#!groovy
|
||||||
|
|
||||||
|
pipeline {
|
||||||
|
agent none
|
||||||
|
|
||||||
|
environment {
|
||||||
|
DEVELOPER_PRIVATE_KEY = "${env.HOME}/.ci/repertory/cert/developer.priv"
|
||||||
|
DEVELOPER_PUBLIC_KEY = "${env.HOME}/.ci/repertory/cert/developer.pub"
|
||||||
|
PROJECT_TEST_CONFIG_DIR = "${env.HOME}/.ci/repertory/test"
|
||||||
|
}
|
||||||
|
|
||||||
|
options {
|
||||||
|
disableConcurrentBuilds()
|
||||||
|
skipDefaultCheckout()
|
||||||
|
timestamps()
|
||||||
|
}
|
||||||
|
|
||||||
|
stages {
|
||||||
|
stage('Build • Test • Deliver') {
|
||||||
|
agent any
|
||||||
|
stages {
|
||||||
|
stage('Checkout') {
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
int maxAttempts = 6
|
||||||
|
int baseDelay = 10
|
||||||
|
for (int attempt = 1; attempt <= maxAttempts; attempt++) {
|
||||||
|
try {
|
||||||
|
checkout scm
|
||||||
|
break
|
||||||
|
} catch (err) {
|
||||||
|
if (attempt == maxAttempts) { throw err }
|
||||||
|
int waitSec = baseDelay * (1 << (attempt - 1))
|
||||||
|
echo "Checkout failed (attempt ${attempt}/${maxAttempts}). Waiting ${waitSec}s before retry..."
|
||||||
|
sleep time: waitSec, unit: 'SECONDS'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('darwin_aarch64') {
|
||||||
|
steps { script { retryWithBackoff(2, 5) { sh 'scripts/make_unix.sh aarch64' } } }
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('darwin_x86_64') {
|
||||||
|
steps { script { retryWithBackoff(2, 5) { sh 'scripts/make_unix.sh x86_64' } } }
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('darwin_aarch64_test') {
|
||||||
|
steps { script { retryWithBackoff(2, 5) { sh 'scripts/run_tests.sh aarch64' } } }
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('deliver') {
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
retryWithBackoff(3, 10) { sh "scripts/deliver.sh ${env.HOME}/mnt/repertory '' aarch64" }
|
||||||
|
retryWithBackoff(3, 10) { sh "scripts/deliver.sh ${env.HOME}/mnt/repertory '' x86_64" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def retryWithBackoff(int maxAttempts, int baseDelaySeconds, Closure body) {
|
||||||
|
for (int attempt = 1; attempt <= maxAttempts; attempt++) {
|
||||||
|
try {
|
||||||
|
body()
|
||||||
|
return
|
||||||
|
} catch (err) {
|
||||||
|
if (attempt == maxAttempts) { throw err }
|
||||||
|
int waitSec = baseDelaySeconds * (1 << (attempt - 1))
|
||||||
|
echo "Step failed (attempt ${attempt}/${maxAttempts}). Waiting ${waitSec}s before retry..."
|
||||||
|
sleep time: waitSec, unit: 'SECONDS'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
68
.jenkins_msys2
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
#!groovy
|
||||||
|
|
||||||
|
pipeline {
|
||||||
|
agent none
|
||||||
|
|
||||||
|
environment {
|
||||||
|
PROJECT_TEST_CONFIG_DIR = "c:\\.ci\\repertory\\test"
|
||||||
|
}
|
||||||
|
|
||||||
|
options {
|
||||||
|
disableConcurrentBuilds()
|
||||||
|
skipDefaultCheckout()
|
||||||
|
timestamps()
|
||||||
|
}
|
||||||
|
|
||||||
|
stages {
|
||||||
|
stage('Build • Test') {
|
||||||
|
agent any
|
||||||
|
stages {
|
||||||
|
stage('Checkout') {
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
int maxAttempts = 6
|
||||||
|
int baseDelay = 10
|
||||||
|
for (int attempt = 1; attempt <= maxAttempts; attempt++) {
|
||||||
|
try {
|
||||||
|
checkout scm
|
||||||
|
break
|
||||||
|
} catch (err) {
|
||||||
|
if (attempt == maxAttempts) { throw err }
|
||||||
|
int waitSec = baseDelay * (1 << (attempt - 1))
|
||||||
|
echo "Checkout failed (attempt ${attempt}/${maxAttempts}). Waiting ${waitSec}s before retry..."
|
||||||
|
sleep time: waitSec, unit: 'SECONDS'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('msys2') {
|
||||||
|
steps {
|
||||||
|
script { retryWithBackoff(2, 5) { bat 'scripts\\make_win32.cmd' } }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// stage('msys2_test') {
|
||||||
|
// steps {
|
||||||
|
// script { retryWithBackoff(2, 5) { bat 'scripts\\run_tests.cmd' } }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def retryWithBackoff(int maxAttempts, int baseDelaySeconds, Closure body) {
|
||||||
|
for (int attempt = 1; attempt <= maxAttempts; attempt++) {
|
||||||
|
try {
|
||||||
|
body()
|
||||||
|
return
|
||||||
|
} catch (err) {
|
||||||
|
if (attempt == maxAttempts) { throw err }
|
||||||
|
int waitSec = baseDelaySeconds * (1 << (attempt - 1))
|
||||||
|
echo "Step failed (attempt ${attempt}/${maxAttempts}). Waiting ${waitSec}s before retry..."
|
||||||
|
sleep time: waitSec, unit: 'SECONDS'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
{
|
|
||||||
"configurations": {
|
|
||||||
"UnixDebug": {
|
|
||||||
"adapter": "vscode-cpptools",
|
|
||||||
"configuration": {
|
|
||||||
"request": "launch",
|
|
||||||
"program": "${workspaceRoot}/build/debug/repertory",
|
|
||||||
"args": ["-f", "/home/sgraves/mnt"],
|
|
||||||
"cwd": "${workspaceRoot}/build/debug",
|
|
||||||
"environment": [],
|
|
||||||
"externalConsole": true,
|
|
||||||
"MIMode": "gdb",
|
|
||||||
"stopAtEntry": true,
|
|
||||||
"logging": {
|
|
||||||
"engineLogging": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"UnixDebugTest": {
|
|
||||||
"adapter": "vscode-cpptools",
|
|
||||||
"configuration": {
|
|
||||||
"request": "launch",
|
|
||||||
"program": "${workspaceRoot}/build/debug/unittests",
|
|
||||||
"args": ["--gtest_filter=file_manager.can_close_after_download_timeout"],
|
|
||||||
"cwd": "${workspaceRoot}/build",
|
|
||||||
"environment": [],
|
|
||||||
"externalConsole": true,
|
|
||||||
"MIMode": "gdb",
|
|
||||||
"stopAtEntry": true,
|
|
||||||
"logging": {
|
|
||||||
"engineLogging": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
172
CHANGELOG.md
@@ -1,14 +1,178 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## v2.1.0-rc.2
|
||||||
|
|
||||||
|
### Issues
|
||||||
|
|
||||||
|
* \#21 [unit test] Complete WinFSP unit tests
|
||||||
|
* \#65 [bug] Mount state is not being removed after unmount on Windows
|
||||||
|
|
||||||
|
### Changes from v2.0.7-release
|
||||||
|
|
||||||
|
* Fixed Windows setup icon location
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## v2.1.0-rc
|
||||||
|
|
||||||
|
### BREAKING CHANGES
|
||||||
|
|
||||||
|
* Mount state has been moved into the configuration directory
|
||||||
|
* Unmount all active mounts prior to upgrade
|
||||||
|
* Remote mounts must be upgraded to v2.1.0+ to support new authentication scheme
|
||||||
|
* Protocol handshake added for DoS protection
|
||||||
|
|
||||||
|
<!-- markdownlint-disable-next-line -->
|
||||||
|
### Issues
|
||||||
|
|
||||||
|
* \#12 [unit test] Complete all providers unit tests
|
||||||
|
* \#22 [unit test] Complete FUSE unit tests
|
||||||
|
* \#33 Complete initial v2.0 documentation
|
||||||
|
* \#34 Add macOS support
|
||||||
|
* \#38 Pinning a file should automatically initiate a download to cache
|
||||||
|
* \#51 [ui] UI console window should close after launch
|
||||||
|
* \#52 [ui] Add auto-mount on first launch functionality
|
||||||
|
* \#53 Create Windows installer
|
||||||
|
* \#54 Remove 'default' as initial bucket name for Sia
|
||||||
|
* \#58 Create macOS bundle for simplified installation
|
||||||
|
* \#59 [bug] [ui] UI is hanging after launching repertory mount in background
|
||||||
|
* \#60 Implement secure key via KDF for transparent data encryption/decryption
|
||||||
|
* \#61 [ui] UI theme should match repertory blue
|
||||||
|
|
||||||
|
### Changes from v2.0.7-release
|
||||||
|
|
||||||
|
* Added check version support to remote mounts
|
||||||
|
* Fixed directory item count bug on S3 provider
|
||||||
|
* Fixed handling of `FALLOC_FL_KEEP_SIZE` on Linux
|
||||||
|
* Fixed intermittent client hang on remote mount server disconnect
|
||||||
|
* Implemented POSIX-compliant `unlink()` with FUSE `hard_remove`
|
||||||
|
* Open handles remain valid after `unlink()`
|
||||||
|
* Refactored CLI messages and error handling to use common methods
|
||||||
|
* Enhanced remote mount client thread mapping
|
||||||
|
* Threads are now mapped 1-1 from client to server instead of being tied to a fixed-size thread pool
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## v2.0.7-release
|
||||||
|
|
||||||
|
<!-- markdownlint-disable-next-line -->
|
||||||
|
### Issues
|
||||||
|
|
||||||
|
* \#55 [bug] UI is unable to launch `repertory.exe` on Windows when absolute path contains spaces
|
||||||
|
* \#57 [bug] Directory entries . and .. are incorrectly being reported as files in Linux remote mounts
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## v2.0.6-release
|
||||||
|
|
||||||
|
<!-- markdownlint-disable-next-line -->
|
||||||
|
### Issues
|
||||||
|
|
||||||
|
* \#42 [bug] Remote mount directory listing on Windows connected to Linux is failing
|
||||||
|
* \#43 [bug] Directories are not importing properly for Sia
|
||||||
|
* \#44 [bug] Windows-to-Linux remote mount ignores `CREATE_NEW`
|
||||||
|
* \#45 [bug] Windows-to-Linux remote mount is not handling attempts to remove a non-empty directory properly
|
||||||
|
* \#46 [bug] Changes to maximum cache size should be updated live
|
||||||
|
* \#47 [bug] Windows-to-Linux remote mount is allowing directory rename when directory is not empty
|
||||||
|
* \#48 [bug] Windows-to-Linux remote mount overlapped I/O is not detecting EOF for read operations
|
||||||
|
* \#49 [ui] Implement provider test button
|
||||||
|
|
||||||
|
### Changes from v2.0.5-rc
|
||||||
|
|
||||||
|
* Added request retry on `libcurl` error code `CURLE_COULDNT_RESOLVE_HOST`
|
||||||
|
* Added `libcurl` DNS caching
|
||||||
|
* Drive letters in UI should always be lowercase
|
||||||
|
* Fixed WinFSP directory rename for non-empty directories
|
||||||
|
* Fixed segfault in UI due to incorrect `SIGCHLD` handling
|
||||||
|
* Migrated to v2 error handling
|
||||||
|
* Upgraded WinFSP to v2.1 (2025)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## v2.0.5-rc
|
||||||
|
|
||||||
|
<!-- markdownlint-disable-next-line -->
|
||||||
|
### Issues
|
||||||
|
|
||||||
|
* \#39 Create management portal in Flutter
|
||||||
|
|
||||||
|
### Changes from v2.0.4-rc
|
||||||
|
|
||||||
|
* Continue documentation updates
|
||||||
|
* Fixed `-status` command erasing active mount information
|
||||||
|
* Fixed overlapping HTTP REST API port's
|
||||||
|
* Refactored/fixed instance locking
|
||||||
|
* Removed passwords and secret key values from API calls
|
||||||
|
* Renamed setting `ApiAuth` to `ApiPassword`
|
||||||
|
* Require `--name,-na` option for encryption provider
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## v2.0.4-rc
|
||||||
|
|
||||||
|
### BREAKING CHANGES
|
||||||
|
|
||||||
|
* `renterd` v2.0.0+ is now required. Prior versions will fail to mount.
|
||||||
|
|
||||||
|
<!-- markdownlint-disable-next-line -->
|
||||||
|
### Issues
|
||||||
|
|
||||||
|
* \#35 [bug] Low frequency check is set to '0' instead of 1 hour by default
|
||||||
|
* \#36 [bug] Max cache size bytes is set to '0' by default
|
||||||
|
|
||||||
|
### Changes from v2.0.3-rc
|
||||||
|
|
||||||
|
* Added Sia API version check prior to mounting
|
||||||
|
* Added back `-cv` (check version) CLI option
|
||||||
|
* Continue documentation updates
|
||||||
|
* Fixed setting `ApiAuth` via `set_value_by_name`
|
||||||
|
* Fixed setting `HostConfig.ApiUser` via `set_value_by_name`
|
||||||
|
* Fixed setting `HostConfig.Path` via `set_value_by_name`
|
||||||
|
* Fixed setting `HostConfig.Protocol` via `set_value_by_name`
|
||||||
|
* Improved ring buffer read-ahead
|
||||||
|
* Integrated `renterd` version 2.0.0
|
||||||
|
* Prefer using local cache file when opening files
|
||||||
|
* Refactored `app_config` unit tests
|
||||||
|
* Refactored polling to be more accurate on scheduling tasks
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## v2.0.3-rc
|
||||||
|
|
||||||
|
<!-- markdownlint-disable-next-line -->
|
||||||
|
### Issues
|
||||||
|
|
||||||
|
* \#28 \[bug\] Address slow directory responses in S3 mounts for deeply nested directories
|
||||||
|
* \#29 \[bug\] S3 error responses are not being logged
|
||||||
|
* \#30 \[bug\] Sia provider error responses are not logged
|
||||||
|
* \#31 \[bug\] S3 provider should limit max key size to 1024
|
||||||
|
|
||||||
|
### Changes from v2.0.2-rc
|
||||||
|
|
||||||
|
* Always use direct for read-only providers
|
||||||
|
* Fixed externally removed files not being processed during cleanup
|
||||||
|
* Fixed http headers not being added for requests
|
||||||
|
* Fixed incorrect `stat` values for remote mounts
|
||||||
|
* Fixed invalid directory nullptr error on remote mounts
|
||||||
|
* Fixed memory leak in event system
|
||||||
|
* Refactored application shutdown
|
||||||
|
* Refactored event system
|
||||||
|
* Updated build system to Alpine 3.21.0
|
||||||
|
* Updated build system to MinGW-w64 12.0.0
|
||||||
|
* Updated copyright to 2018-2025
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## v2.0.2-rc
|
## v2.0.2-rc
|
||||||
|
|
||||||
|
<!-- markdownlint-disable-next-line -->
|
||||||
### BREAKING CHANGES
|
### BREAKING CHANGES
|
||||||
|
|
||||||
* Refactored `config.json` - will need to verify configuration settings prior to mounting
|
* Refactored `config.json` - will need to verify configuration settings prior to mounting
|
||||||
|
|
||||||
|
<!-- markdownlint-disable-next-line -->
|
||||||
### Issues
|
### Issues
|
||||||
|
|
||||||
* \#12 \[Unit Test\] Complete all providers unit tests
|
|
||||||
* \#14 \[Unit Test\] SQLite mini-ORM unit tests and cleanup
|
* \#14 \[Unit Test\] SQLite mini-ORM unit tests and cleanup
|
||||||
* \#16 Add support for bucket name in Sia provider
|
* \#16 Add support for bucket name in Sia provider
|
||||||
* \#17 Update to common c++ build system
|
* \#17 Update to common c++ build system
|
||||||
@@ -31,6 +195,8 @@
|
|||||||
* Corrected handling of `chown()` and `chmod()`
|
* Corrected handling of `chown()` and `chmod()`
|
||||||
* Fixed erroneous download of chunks after resize
|
* Fixed erroneous download of chunks after resize
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## v2.0.1-rc
|
## v2.0.1-rc
|
||||||
|
|
||||||
<!-- markdownlint-disable-next-line -->
|
<!-- markdownlint-disable-next-line -->
|
||||||
@@ -53,6 +219,8 @@
|
|||||||
* Updated `curl` to v8.4.0
|
* Updated `curl` to v8.4.0
|
||||||
* Updated `libsodium` to v1.0.19
|
* Updated `libsodium` to v1.0.19
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## v2.0.0-rc
|
## v2.0.0-rc
|
||||||
|
|
||||||
<!-- markdownlint-disable-next-line -->
|
<!-- markdownlint-disable-next-line -->
|
||||||
@@ -97,3 +265,5 @@
|
|||||||
* Supports re-upload after mount restart for incomplete uploads
|
* Supports re-upload after mount restart for incomplete uploads
|
||||||
* NOTE: Uploads for all providers are full file (no resume support)
|
* NOTE: Uploads for all providers are full file (no resume support)
|
||||||
* Multipart upload support is planned for S3
|
* Multipart upload support is planned for S3
|
||||||
|
|
||||||
|
---
|
||||||
|
|||||||
@@ -3,6 +3,10 @@ cmake_minimum_required(VERSION 3.27)
|
|||||||
cmake_policy(SET CMP0135 NEW)
|
cmake_policy(SET CMP0135 NEW)
|
||||||
cmake_policy(SET CMP0144 NEW)
|
cmake_policy(SET CMP0144 NEW)
|
||||||
|
|
||||||
|
if (NOT PROJECT_INTERFACE)
|
||||||
|
message(FATAL_ERROR "Project must be compiled via 'make_win32.cmd'/'make_win32.sh' or 'make_unix.sh' build scripts. Invoking 'cmake' directly is not supported.")
|
||||||
|
endif()
|
||||||
|
|
||||||
project(${PROJECT_NAME}
|
project(${PROJECT_NAME}
|
||||||
DESCRIPTION ${PROJECT_DESC}
|
DESCRIPTION ${PROJECT_DESC}
|
||||||
HOMEPAGE_URL ${PROJECT_URL}
|
HOMEPAGE_URL ${PROJECT_URL}
|
||||||
@@ -47,6 +51,10 @@ if(PROJECT_IS_ARM64)
|
|||||||
add_definitions(-DPROJECT_IS_ARM64)
|
add_definitions(-DPROJECT_IS_ARM64)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(PROJECT_IS_DARWIN)
|
||||||
|
add_definitions(-DPROJECT_IS_DARWIN)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(PROJECT_IS_MINGW)
|
if(PROJECT_IS_MINGW)
|
||||||
option(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES "Enable path sizes of 32767 characters on Windows" OFF)
|
option(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES "Enable path sizes of 32767 characters on Windows" OFF)
|
||||||
if(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
|
if(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
|
||||||
@@ -54,6 +62,10 @@ if(PROJECT_IS_MINGW)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (PROJECT_ENABLE_V2_ERRORS)
|
||||||
|
add_definitions(-DPROJECT_ENABLE_V2_ERRORS)
|
||||||
|
endif()
|
||||||
|
|
||||||
include(cmake/settings.cmake)
|
include(cmake/settings.cmake)
|
||||||
|
|
||||||
include(cmake/flags.cmake)
|
include(cmake/flags.cmake)
|
||||||
@@ -107,6 +119,24 @@ if(PROJECT_BUILD)
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/version.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/version.cpp
|
||||||
@ONLY
|
@ONLY
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (PROJECT_IS_MINGW AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${PROJECT_NAME}.iss.in")
|
||||||
|
configure_file(
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${PROJECT_NAME}.iss.in
|
||||||
|
${PROJECT_DIST_DIR}/../${PROJECT_NAME}.iss
|
||||||
|
@ONLY
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (PROJECT_IS_DARWIN AND EXISTS "${CMAKE_SOURCE_DIR}/${PROJECT_NAME}/Info.plist.in")
|
||||||
|
configure_file(
|
||||||
|
${CMAKE_SOURCE_DIR}/${PROJECT_NAME}/Info.plist.in
|
||||||
|
${CMAKE_SOURCE_DIR}/${PROJECT_NAME}/Info.plist
|
||||||
|
@ONLY
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
find_package(ICU REQUIRED COMPONENTS data i18n io uc)
|
||||||
else()
|
else()
|
||||||
message(STATUS "-=[CMake Settings]=-")
|
message(STATUS "-=[CMake Settings]=-")
|
||||||
message(STATUS " C standard: ${CMAKE_C_STANDARD}")
|
message(STATUS " C standard: ${CMAKE_C_STANDARD}")
|
||||||
@@ -139,6 +169,7 @@ endif()
|
|||||||
-DPROJECT_COPYRIGHT=${PROJECT_COPYRIGHT}
|
-DPROJECT_COPYRIGHT=${PROJECT_COPYRIGHT}
|
||||||
-DPROJECT_DESC=${PROJECT_DESC}
|
-DPROJECT_DESC=${PROJECT_DESC}
|
||||||
-DPROJECT_DIST_DIR=${PROJECT_DIST_DIR}
|
-DPROJECT_DIST_DIR=${PROJECT_DIST_DIR}
|
||||||
|
-DPROJECT_ENABLE_V2_ERRORS=${PROJECT_ENABLE_V2_ERRORS}
|
||||||
-DPROJECT_ENABLE_WIN32_LONG_PATH_NAMES=${PROJECT_ENABLE_WIN32_LONG_PATH_NAMES}
|
-DPROJECT_ENABLE_WIN32_LONG_PATH_NAMES=${PROJECT_ENABLE_WIN32_LONG_PATH_NAMES}
|
||||||
-DPROJECT_ENABLE_BOOST=${PROJECT_ENABLE_BOOST}
|
-DPROJECT_ENABLE_BOOST=${PROJECT_ENABLE_BOOST}
|
||||||
-DPROJECT_ENABLE_CPP_HTTPLIB=${PROJECT_ENABLE_CPP_HTTPLIB}
|
-DPROJECT_ENABLE_CPP_HTTPLIB=${PROJECT_ENABLE_CPP_HTTPLIB}
|
||||||
@@ -158,11 +189,15 @@ endif()
|
|||||||
-DPROJECT_FUSE=${PROJECT_FUSE}
|
-DPROJECT_FUSE=${PROJECT_FUSE}
|
||||||
-DPROJECT_FUSE_INCLUDE_DIRS=${PROJECT_FUSE_INCLUDE_DIRS}
|
-DPROJECT_FUSE_INCLUDE_DIRS=${PROJECT_FUSE_INCLUDE_DIRS}
|
||||||
-DPROJECT_GIT_REV=${PROJECT_GIT_REV}
|
-DPROJECT_GIT_REV=${PROJECT_GIT_REV}
|
||||||
|
-DPROJECT_INTERFACE=1
|
||||||
-DPROJECT_IS_ALPINE=${PROJECT_IS_ALPINE}
|
-DPROJECT_IS_ALPINE=${PROJECT_IS_ALPINE}
|
||||||
-DPROJECT_IS_ARM64=${PROJECT_IS_ARM64}
|
-DPROJECT_IS_ARM64=${PROJECT_IS_ARM64}
|
||||||
|
-DPROJECT_IS_DARWIN=${PROJECT_IS_DARWIN}
|
||||||
-DPROJECT_IS_MINGW=${PROJECT_IS_MINGW}
|
-DPROJECT_IS_MINGW=${PROJECT_IS_MINGW}
|
||||||
-DPROJECT_IS_MINGW_UNIX=${PROJECT_IS_MINGW_UNIX}
|
-DPROJECT_IS_MINGW_UNIX=${PROJECT_IS_MINGW_UNIX}
|
||||||
-DPROJECT_MAJOR_VERSION=${PROJECT_MAJOR_VERSION}
|
-DPROJECT_MAJOR_VERSION=${PROJECT_MAJOR_VERSION}
|
||||||
|
-DPROJECT_MACOS_BUNDLE_ID=${PROJECT_MACOS_BUNDLE_ID}
|
||||||
|
-DPROJECT_MACOS_ICNS_NAME=${PROJECT_MACOS_ICNS_NAME}
|
||||||
-DPROJECT_MINOR_VERSION=${PROJECT_MINOR_VERSION}
|
-DPROJECT_MINOR_VERSION=${PROJECT_MINOR_VERSION}
|
||||||
-DPROJECT_NAME=${PROJECT_NAME}
|
-DPROJECT_NAME=${PROJECT_NAME}
|
||||||
-DPROJECT_RELEASE_ITER=${PROJECT_RELEASE_ITER}
|
-DPROJECT_RELEASE_ITER=${PROJECT_RELEASE_ITER}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# Repertory MIT License
|
# Repertory MIT License
|
||||||
### Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
### Copyright <2018-2025> <scott.e.graves@protonmail.com>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
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:
|
||||||
|
|
||||||
|
|||||||
875
README.md
@@ -1,117 +1,804 @@
|
|||||||
# Repertory
|
# Repertory
|
||||||
|
> /rĕp′ər-tôr″ē/
|
||||||
|
> noun
|
||||||
|
> *A place, such as a storehouse, where a stock of things is kept; a repository*
|
||||||
|
|
||||||
Repertory allows you to mount AWS S3 and Sia via FUSE on Linux ~~/OS X~~ or via WinFSP
|
Repertory allows you to mount **S3** and **Sia** storage as local drives using:
|
||||||
on Windows.
|
|
||||||
|
|
||||||
## Details and Features
|
- **FUSE** (Linux/macOS)
|
||||||
|
- **WinFSP** (Windows)
|
||||||
|
|
||||||
* Optimized for [Plex Media Server](https://www.plex.tv/)
|
It supports:
|
||||||
* Single application to mount AWS S3 and/or Sia
|
|
||||||
* Remote mounting of Repertory instances on Linux ~~, OS X~~ and Windows
|
|
||||||
* Securely share your mounts over TCP/IP (`XChaCha20-Poly1305` stream cipher)
|
|
||||||
* Cross-platform support (Linux 64-bit, Linux arm64/aarch64, ~~OS X,~~ Windows 64-bit)
|
|
||||||
|
|
||||||
## Minimum Requirements
|
- Local mounts
|
||||||
|
- Remote encrypted mounts between systems
|
||||||
|
- Optional file name and data encryption using `XChaCha20-Poly1305` and `Argon2id` for key generation
|
||||||
|
|
||||||
* [Sia renterd](https://github.com/SiaFoundation/renterd/releases) v0.4.0+ for Sia support
|
---
|
||||||
* Only 64-bit operating systems are supported
|
|
||||||
* By default, Linux requires `fusermount3`; otherwise, `repertory` must be manually compiled with `libfuse2` support
|
|
||||||
* ~~OS X requires the following dependency to be installed:~~
|
|
||||||
* ~~[FUSE for macOS v4.5.0](https://github.com/osxfuse/osxfuse/releases/download/macfuse-4.5.0/macfuse-4.5.0.dmg)~~
|
|
||||||
* Windows requires the following dependencies to be installed:
|
|
||||||
* [WinFSP 2023](https://github.com/winfsp/winfsp/releases/download/v2.0/winfsp-2.0.23075.msi)
|
|
||||||
|
|
||||||
## Supported Operating Systems
|
## 📖 Contents
|
||||||
|
|
||||||
* Linux `arm64/aarch64`
|
1. [Quick Start (Sia Example)](#-quick-start-sia-example)
|
||||||
* Linux `amd64`
|
2. [Details & Features](#-details-and-features)
|
||||||
* ~~OS X Mojave and above~~
|
3. [Minimum Requirements](#-minimum-requirements)
|
||||||
* Windows 64-bit 10, 11
|
- [Supported Operating Systems](#supported-operating-systems)
|
||||||
|
4. [Data Directories](#-data-directories)
|
||||||
|
5. [GUI](#-gui)
|
||||||
|
6. [Usage](#-usage)
|
||||||
|
- [Important Options](#important-options)
|
||||||
|
- [Unmounting](#unmounting)
|
||||||
|
7. [Sia Setup](#-sia-setup)
|
||||||
|
- [Sia Initial Configuration](#sia-initial-configuration)
|
||||||
|
- [Sia Mounting](#sia-mounting)
|
||||||
|
- [Sia Configuration File](#sia-configuration-file)
|
||||||
|
8. [S3 Setup](#-s3-setup)
|
||||||
|
- [S3 Initial Configuration](#s3-initial-configuration)
|
||||||
|
- [S3 Mounting](#s3-mounting)
|
||||||
|
- [S3 Configuration File](#s3-configuration-file)
|
||||||
|
9. [Remote Mounting](#-remote-mounting)
|
||||||
|
- [Server Setup](#server-setup)
|
||||||
|
- [Client Setup](#client-setup)
|
||||||
|
- [Remote Mount Configuration File](#remote-mount-configuration-file)
|
||||||
|
10. [Compiling from Source](#-compiling)
|
||||||
|
- [Linux Compilation](#linux-compilation)
|
||||||
|
- [macOS Compilation](#macos-compilation)
|
||||||
|
- [Windows Compilation](#windows-compilation)
|
||||||
|
11. [Credits](#-credits)
|
||||||
|
12. [Developer Public Key](#-developer-public-key)
|
||||||
|
13. [Consult the Wiki for additional information](https://git.fifthgrid.com/BlockStorage/repertory/wiki)
|
||||||
|
|
||||||
## Usage
|
---
|
||||||
|
|
||||||
### Notable Options
|
## 🚀 Quick Start (Sia Example)
|
||||||
|
|
||||||
* `-dc`
|
> 💡 Want to mount S3 instead?
|
||||||
* Display mount configuration.
|
> Skip ahead to [S3 Setup](#-s3-setup) — the process is almost identical.
|
||||||
* For Sia, `--name` is optional
|
|
||||||
* For S3, the `-s3` option is required along with `--name`
|
|
||||||
* `--help`
|
|
||||||
* Display all mount utility options.
|
|
||||||
* `--name, -na [name]`
|
|
||||||
* The `--name` option can be set to any valid value allowed as a file name for your filesystem.
|
|
||||||
* For Sia, the bucket name will be set to the same value if it is empty in the configuration file.
|
|
||||||
* If the `--name` option is not specified, `default` will be used.
|
|
||||||
* For S3, the `--name` option is required and does not affect the bucket name.
|
|
||||||
* `-set SiaConfig.Bucket`
|
|
||||||
* Set Sia bucket name for the mount.
|
|
||||||
* Can be used in combination with `--name` to target a unique configuration.
|
|
||||||
* `-set S3Config.Bucket`
|
|
||||||
* S3 bucket name for the mount.
|
|
||||||
* Must be used in combination with `--name` to target a unique configuration.
|
|
||||||
* Must be used in combination with `-s3`.
|
|
||||||
|
|
||||||
### Sia
|
This example mounts a Sia bucket from a running [renterd](https://github.com/SiaFoundation/renterd) instance.
|
||||||
|
|
||||||
* Linux
|
---
|
||||||
* `repertory /mnt/location`
|
|
||||||
* `repertory --name default /mnt/location`
|
|
||||||
* Windows
|
|
||||||
* `repertory.exe t:`
|
|
||||||
* `repertory.exe --name default t:`
|
|
||||||
|
|
||||||
### S3
|
### 1. Install dependencies
|
||||||
|
|
||||||
* Linux
|
#### Linux
|
||||||
* `repertory --name storj -s3 /mnt/location`
|
|
||||||
* Windows
|
|
||||||
* `repertory.exe --name storj -s3 t:`
|
|
||||||
|
|
||||||
## Compiling
|
``` shell
|
||||||
|
sudo apt install fuse3 # Debian/Ubuntu
|
||||||
|
# or
|
||||||
|
sudo dnf install fuse3 # Fedora
|
||||||
|
```
|
||||||
|
|
||||||
* Successful compilation will result in all required files being placed in the `dist/` directory
|
#### macOS
|
||||||
* Linux
|
|
||||||
* Ensure `docker` is installed
|
|
||||||
* For x86_64:
|
|
||||||
* RelWithDebInfo: `scripts/make_unix.sh`
|
|
||||||
* Release: `scripts/make_unix.sh x86_64 Release`
|
|
||||||
* Debug: `scripts/make_unix.sh x86_64 Debug`
|
|
||||||
* For aarch64:
|
|
||||||
* RelWithDebInfo: `scripts/make_unix.sh aarch64`
|
|
||||||
* Release: `scripts/make_unix.sh aarch64 Release`
|
|
||||||
* Debug: `scripts/make_unix.sh aarch64 Debug`
|
|
||||||
* Windows
|
|
||||||
* OFFICIAL: Cross-compiling on Linux
|
|
||||||
* Ensure `docker` is installed
|
|
||||||
* RelWithDebInfo: `scripts/make_win32.sh`
|
|
||||||
* Release: `scripts/make_win32.sh x86_64 Release`
|
|
||||||
* Debug: `scripts/make_win32.sh x86_64 Debug`
|
|
||||||
* UNOFFICIAL: Compiling on Windows
|
|
||||||
* Ensure latest [MSYS2](https://www.msys2.org/) is installed
|
|
||||||
* RelWithDebInfo: `scripts\make_win32.cmd`
|
|
||||||
* Release: `scripts\make_win32.cmd x86_64 Release`
|
|
||||||
* Debug: `scripts\make_win32.cmd x86_64 Debug`
|
|
||||||
|
|
||||||
## Credits
|
- Install [macFUSE 5.0.7](https://github.com/macfuse/macfuse/releases/download/macfuse-5.0.7/macfuse-5.0.7.dmg)
|
||||||
|
|
||||||
* [boost c++ libraries](https://www.boost.org/)
|
#### Windows
|
||||||
* [cpp-httplib](https://github.com/yhirose/cpp-httplib)
|
|
||||||
* [curl](https://curl.haxx.se/)
|
|
||||||
* ~~[FUSE for macOS](https://osxfuse.github.io/)~~
|
|
||||||
* [Google Test](https://github.com/google/googletest)
|
|
||||||
* [JSON for Modern C++](https://github.com/nlohmann/json)
|
|
||||||
* [libfuse](https://github.com/libfuse/libfuse)
|
|
||||||
* [libsodium](https://doc.libsodium.org/)
|
|
||||||
* [OpenSSL](https://www.openssl.org/)
|
|
||||||
* [ScPrime](https://scpri.me/)
|
|
||||||
* [Sia Decentralized Cloud Storage](https://sia.tech/)
|
|
||||||
* [SQLite](https://www.sqlite.org)
|
|
||||||
* [stduuid](https://github.com/mariusbancila/stduuid)
|
|
||||||
* [Storj](https://storj.io/)
|
|
||||||
* [WinFSP - FUSE for Windows](https://github.com/billziss-gh/winfsp)
|
|
||||||
* [zlib](https://zlib.net/)
|
|
||||||
|
|
||||||
## Developer Public Key
|
- Install [WinFSP 2025](https://github.com/winfsp/winfsp/releases/download/v2.1/winfsp-2.1.25156.msi)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2. Configure
|
||||||
|
|
||||||
|
Replace placeholders with your actual values:
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
repertory --name mybucket -set HostConfig.ApiPassword "<renterd api password>"
|
||||||
|
repertory --name mybucket -set SiaConfig.Bucket "<bucket name>"
|
||||||
|
```
|
||||||
|
|
||||||
|
Optional:
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
# If renterd is not running locally
|
||||||
|
repertory --name mybucket -set HostConfig.HostNameOrIp "<hostname or IP>"
|
||||||
|
|
||||||
|
# If renterd uses a non-default port (default 9980)
|
||||||
|
repertory --name mybucket -set HostConfig.ApiPort <port>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 3. Mount
|
||||||
|
|
||||||
|
<!-- markdownlint-disable-next-line -->
|
||||||
|
#### Linux
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
repertory --name mybucket /mnt/mybucket
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- markdownlint-disable-next-line -->
|
||||||
|
#### macOS
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
repertory --name mybucket /Volumes/mybucket
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- markdownlint-disable-next-line -->
|
||||||
|
#### Windows
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
repertory --name mybucket t:
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 4. Unmount
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
repertory --name mybucket --unmount
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✨ Details and Features
|
||||||
|
|
||||||
|
- **Optimized for [Plex Media Server](https://www.plex.tv/).**
|
||||||
|
- Remote mounting of `repertory` instances between Linux, macOS, and/or Windows.
|
||||||
|
- Securely share your mounts over TCP/IP via `XChaCha20-Poly1305` with other systems on your network or over the internet.
|
||||||
|
- Cross-platform support (Linux, macOS, and Windows).
|
||||||
|
- Optionally encrypt file names and file data via `XChaCha20-Poly1305` in S3 mounts.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 Minimum Requirements
|
||||||
|
|
||||||
|
- **Sia:** [renterd](https://github.com/SiaFoundation/renterd/releases) v2.0.0+ for Sia support
|
||||||
|
- **Linux:** requires `fusermount3`; otherwise, `repertory` must be manually compiled with `libfuse2` support
|
||||||
|
- **macOS:** requires:
|
||||||
|
- [macFUSE 5.0.7](https://github.com/macfuse/macfuse/releases/download/macfuse-5.0.7/macfuse-5.0.7.dmg)
|
||||||
|
- **Windows:** requires:
|
||||||
|
- [WinFSP 2025](https://github.com/winfsp/winfsp/releases/download/v2.1/winfsp-2.1.25156.msi)
|
||||||
|
|
||||||
|
### Supported Operating Systems
|
||||||
|
|
||||||
|
Only **64-bit operating systems** are supported:
|
||||||
|
|
||||||
|
- Linux `arm64/aarch64`
|
||||||
|
- Linux `x86_64`
|
||||||
|
- macOS `arm64/aarch64`
|
||||||
|
- macOS `x86_64`
|
||||||
|
- Windows `x86_64` 10, 11
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📂 Data Directories
|
||||||
|
|
||||||
|
<!-- markdownlint-disable-next-line -->
|
||||||
|
### Linux
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
# Mounts
|
||||||
|
~/.local/repertory2/encrypt
|
||||||
|
~/.local/repertory2/s3
|
||||||
|
~/.local/repertory2/sia
|
||||||
|
|
||||||
|
# UI
|
||||||
|
~/.local/repertory2
|
||||||
|
```
|
||||||
|
|
||||||
|
### macOS
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
# Mounts
|
||||||
|
~/Library/Application Support/repertory2/encrypt
|
||||||
|
~/Library/Application Support/repertory2/s3
|
||||||
|
~/Library/Application Support/repertory2/sia
|
||||||
|
|
||||||
|
# UI
|
||||||
|
~/Library/Application Support/repertory2
|
||||||
|
```
|
||||||
|
<!-- markdownlint-disable-next-line -->
|
||||||
|
### Windows
|
||||||
|
|
||||||
|
``` cmd
|
||||||
|
:: Mounts
|
||||||
|
%LOCALAPPDATA%\repertory2\encrypt
|
||||||
|
%LOCALAPPDATA%\repertory2\s3
|
||||||
|
%LOCALAPPDATA%\repertory2\sia
|
||||||
|
|
||||||
|
:: UI
|
||||||
|
%LOCALAPPDATA%\repertory2
|
||||||
|
```
|
||||||
|
|
||||||
|
**IMPORTANT:**
|
||||||
|
It is highly recommended to **exclude** these folders from any anti-virus/anti-malware applications as severe performance issues may arise. Excluding the mounted drive letter is also highly recommended.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🖥 GUI
|
||||||
|
|
||||||
|
As of `v2.0.6-release`, mounts can be managed using the **Repertory Management Portal**.
|
||||||
|
|
||||||
|
Launch the portal:
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
repertory -ui
|
||||||
|
```
|
||||||
|
|
||||||
|
### ⚠️ Security tip
|
||||||
|
|
||||||
|
- Change the default UI credentials on first launch (`ui.json`) or via the portal
|
||||||
|
- Default username: `repertory`
|
||||||
|
- Default password: `repertory`
|
||||||
|
|
||||||
|
After first launch, `ui.json` will be created in the appropriate data directory (see [Data Directories](#-data-directories)). Modify this file directly or use the portal to change the default credentials.
|
||||||
|
|
||||||
|
### Screenshots
|
||||||
|
|
||||||
|
#### Login screen
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
#### Home screen
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🛠 Usage
|
||||||
|
|
||||||
|
### Important Options
|
||||||
|
|
||||||
|
- `--help`
|
||||||
|
Display all mount utility options.
|
||||||
|
|
||||||
|
- `-f`
|
||||||
|
Keep process in foreground on Linux.
|
||||||
|
|
||||||
|
- `--name, -na [name]`
|
||||||
|
Identifies a unique configuration name to support multiple mounts.
|
||||||
|
The `--name` option can be set to any valid value allowed as a file name for your filesystem.
|
||||||
|
**The `--name` option is required.**
|
||||||
|
|
||||||
|
- `-dc`
|
||||||
|
Display mount configuration.
|
||||||
|
For Sia, the `--name` option is required.
|
||||||
|
For S3, the `-s3` and `--name` options are required.
|
||||||
|
|
||||||
|
### Unmounting
|
||||||
|
|
||||||
|
#### Remote
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
repertory -rm 192.168.0.1:20000 --unmount
|
||||||
|
```
|
||||||
|
|
||||||
|
#### S3
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
repertory -s3 --name '<my config name>' --unmount
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Sia
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
repertory --name '<my config name>' --unmount
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔒 Security Best Practices
|
||||||
|
|
||||||
|
When enabling **encryption tokens** for S3 or remote mounts:
|
||||||
|
|
||||||
|
- Use a **long, random string**.
|
||||||
|
- Store it **offline** (password manager and an offline backup).
|
||||||
|
- Losing it means **permanent data loss**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- markdownlint-disable-next-line -->
|
||||||
|
<a id="sia-setup"></a>
|
||||||
|
<!-- markdownlint-disable-next-line -->
|
||||||
|
<a id="-sia-setup"></a>
|
||||||
|
## ☁️ Sia Setup
|
||||||
|
|
||||||
|
### Sia Initial Configuration
|
||||||
|
|
||||||
|
**Required steps:**
|
||||||
|
|
||||||
|
- Set the appropriate bucket name and `renterd` API password in `repertory` configuration:
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
repertory --name '<my config name>' -set HostConfig.ApiPassword '<my password>'
|
||||||
|
repertory --name '<my config name>' -set SiaConfig.Bucket '<my bucket name>'
|
||||||
|
```
|
||||||
|
|
||||||
|
**Optional steps:**
|
||||||
|
|
||||||
|
- Set a user name used during `renterd` basic authentication:
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
repertory --name '<my config name>' -set HostConfig.ApiUser '<my user>'
|
||||||
|
```
|
||||||
|
|
||||||
|
- Set a custom agent string (default `Sia-Agent`):
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
repertory --name '<my config name>' -set HostConfig.AgentString '<my agent>'
|
||||||
|
```
|
||||||
|
|
||||||
|
- Set the host name or IP of the `renterd` instance (default `localhost`):
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
repertory --name '<my config name>' -set HostConfig.HostNameOrIp '<my host name>'
|
||||||
|
```
|
||||||
|
|
||||||
|
- Set the `renterd` API port (default `9980`):
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
repertory --name '<my config name>' -set HostConfig.ApiPort 9981
|
||||||
|
```
|
||||||
|
|
||||||
|
**Verify/view all configuration options:**
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
repertory --name '<my config name>' -dc
|
||||||
|
# Example:
|
||||||
|
repertory --name my_bucket -dc
|
||||||
|
```
|
||||||
|
|
||||||
|
### Sia Mounting
|
||||||
|
|
||||||
|
<!-- markdownlint-disable-next-line -->
|
||||||
|
#### Linux
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
repertory --name '<my config name>' /mnt/location
|
||||||
|
# Example:
|
||||||
|
repertory --name my_bucket /mnt/location
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- markdownlint-disable-next-line -->
|
||||||
|
#### macOS
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
repertory --name '<my config name>' /Volumes/mybucket
|
||||||
|
# Example:
|
||||||
|
repertory --name my_bucket /Volumes/mybucket
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- markdownlint-disable-next-line -->
|
||||||
|
#### Windows
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
repertory --name '<my config name>' t:
|
||||||
|
# Example:
|
||||||
|
repertory --name my_bucket t:
|
||||||
|
```
|
||||||
|
|
||||||
|
### Sia Configuration File
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"ApiPassword": "<random generated rpc password>",
|
||||||
|
"ApiPort": 10000,
|
||||||
|
"ApiUser": "repertory",
|
||||||
|
"DatabaseType": "rocksdb",
|
||||||
|
"DownloadTimeoutSeconds": 30,
|
||||||
|
"EnableDownloadTimeout": true,
|
||||||
|
"EnableDriveEvents": false,
|
||||||
|
"EventLevel": "info",
|
||||||
|
"EvictionDelayMinutes": 1,
|
||||||
|
"EvictionUseAccessedTime": false,
|
||||||
|
"HighFreqIntervalSeconds": 30,
|
||||||
|
"HostConfig": {
|
||||||
|
"AgentString": "Sia-Agent",
|
||||||
|
"ApiPassword": "<renterd api password>",
|
||||||
|
"ApiPort": 9980,
|
||||||
|
"ApiUser": "",
|
||||||
|
"HostNameOrIp": "localhost",
|
||||||
|
"Path": "",
|
||||||
|
"Protocol": "http",
|
||||||
|
"TimeoutMs": 60000
|
||||||
|
},
|
||||||
|
"LowFreqIntervalSeconds": 3600,
|
||||||
|
"MaxCacheSizeBytes": 21474836480,
|
||||||
|
"MaxUploadCount": 5,
|
||||||
|
"MedFreqIntervalSeconds": 120,
|
||||||
|
"OnlineCheckRetrySeconds": 60,
|
||||||
|
"PreferredDownloadType": "default",
|
||||||
|
"RemoteMount": {
|
||||||
|
"ApiPort": 20000,
|
||||||
|
"ClientPoolSize": 20,
|
||||||
|
"Enable": false,
|
||||||
|
"EncryptionToken": ""
|
||||||
|
},
|
||||||
|
"RetryReadCount": 6,
|
||||||
|
"RingBufferFileSize": 512,
|
||||||
|
"SiaConfig": {
|
||||||
|
"Bucket": "my_bucket"
|
||||||
|
},
|
||||||
|
"TaskWaitMs": 100,
|
||||||
|
"Version": 1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🪣 S3 Setup
|
||||||
|
|
||||||
|
### S3 Initial Configuration
|
||||||
|
|
||||||
|
**Required steps:**
|
||||||
|
|
||||||
|
- Set the appropriate base URL:
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
repertory -s3 --name '<my config name>' -set S3Config.URL '<my url>'
|
||||||
|
# Example:
|
||||||
|
repertory -s3 --name minio -set S3Config.URL 'http://localhost:9000'
|
||||||
|
```
|
||||||
|
|
||||||
|
- Set the appropriate bucket name:
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
repertory -s3 --name '<my config name>' -set S3Config.Bucket '<my bucket name>'
|
||||||
|
```
|
||||||
|
|
||||||
|
- Set the appropriate access key:
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
repertory -s3 --name '<my config name>' -set S3Config.AccessKey '<my access key>'
|
||||||
|
```
|
||||||
|
|
||||||
|
- Set the appropriate secret key:
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
repertory -s3 --name '<my config name>' -set S3Config.SecretKey '<my secret key>'
|
||||||
|
```
|
||||||
|
|
||||||
|
- For Sia and most local S3 gateway instances, enable path style URLs:
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
repertory -s3 --name '<my config name>' -set S3Config.UsePathStyle true
|
||||||
|
```
|
||||||
|
|
||||||
|
**Optional steps:**
|
||||||
|
|
||||||
|
- Set an appropriate region. Default is `any`:
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
repertory -s3 --name '<my config name>' -set S3Config.Region '<my region>'
|
||||||
|
```
|
||||||
|
|
||||||
|
- Enable encrypted file names and file data. Set a strong, random encryption token and store it securely:
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
repertory -s3 --name '<my config name>' -set S3Config.EncryptionToken '<my strong password>'
|
||||||
|
```
|
||||||
|
|
||||||
|
**Verify/view all configuration options:**
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
repertory -s3 --name '<my config name>' -dc
|
||||||
|
# Example:
|
||||||
|
repertory -s3 --name minio -dc
|
||||||
|
```
|
||||||
|
|
||||||
|
### S3 Mounting
|
||||||
|
|
||||||
|
<!-- markdownlint-disable-next-line -->
|
||||||
|
#### Linux
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
repertory -s3 --name '<my config name>' /mnt/location
|
||||||
|
# Example:
|
||||||
|
repertory -s3 --name minio /mnt/location
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- markdownlint-disable-next-line -->
|
||||||
|
#### macOS
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
repertory -s3 --name '<my config name>' /Volumes/minio
|
||||||
|
# Example:
|
||||||
|
repertory -s3 --name minio /Volumes/minio
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- markdownlint-disable-next-line -->
|
||||||
|
#### Windows
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
repertory -s3 --name '<my config name>' t:
|
||||||
|
# Example:
|
||||||
|
repertory -s3 --name minio t:
|
||||||
|
```
|
||||||
|
|
||||||
|
### S3 Configuration File
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"ApiPassword": "<random generated rpc password>",
|
||||||
|
"ApiPort": 10100,
|
||||||
|
"ApiUser": "repertory",
|
||||||
|
"DatabaseType": "rocksdb",
|
||||||
|
"DownloadTimeoutSeconds": 30,
|
||||||
|
"EnableDownloadTimeout": true,
|
||||||
|
"EnableDriveEvents": false,
|
||||||
|
"EventLevel": "info",
|
||||||
|
"EvictionDelayMinutes": 1,
|
||||||
|
"EvictionUseAccessedTime": false,
|
||||||
|
"HighFreqIntervalSeconds": 30,
|
||||||
|
"LowFreqIntervalSeconds": 3600,
|
||||||
|
"MaxCacheSizeBytes": 21474836480,
|
||||||
|
"MaxUploadCount": 5,
|
||||||
|
"MedFreqIntervalSeconds": 120,
|
||||||
|
"OnlineCheckRetrySeconds": 60,
|
||||||
|
"PreferredDownloadType": "default",
|
||||||
|
"RemoteMount": {
|
||||||
|
"ApiPort": 20100,
|
||||||
|
"ClientPoolSize": 20,
|
||||||
|
"Enable": false,
|
||||||
|
"EncryptionToken": ""
|
||||||
|
},
|
||||||
|
"RetryReadCount": 6,
|
||||||
|
"RingBufferFileSize": 512,
|
||||||
|
"S3Config": {
|
||||||
|
"AccessKey": "<my access key>",
|
||||||
|
"Bucket": "<my bucket name>",
|
||||||
|
"EncryptionToken": "",
|
||||||
|
"Region": "any",
|
||||||
|
"SecretKey": "<my secret key>",
|
||||||
|
"TimeoutMs": 60000,
|
||||||
|
"URL": "http://localhost:9000",
|
||||||
|
"UsePathStyle": true,
|
||||||
|
"UseRegionInURL": false
|
||||||
|
},
|
||||||
|
"TaskWaitMs": 100,
|
||||||
|
"Version": 1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🌐 Remote Mounting
|
||||||
|
|
||||||
|
`repertory` allows local mounts to be shared with other computers on your network or over the internet. This option is referred to as **remote mounting**.
|
||||||
|
|
||||||
|
### Server Setup
|
||||||
|
|
||||||
|
The following steps must be performed on the mount you wish to share with other systems. Changes to configuration will not take effect while a mount is active, so it is recommended to unmount beforehand.
|
||||||
|
|
||||||
|
**Required steps:**
|
||||||
|
|
||||||
|
- Enable remote mount:
|
||||||
|
|
||||||
|
- **Sia**
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
repertory -set RemoteMount.Enable true
|
||||||
|
repertory --name '<my config name>' -set RemoteMount.Enable true
|
||||||
|
```
|
||||||
|
|
||||||
|
- **S3**
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
repertory -set RemoteMount.Enable true
|
||||||
|
repertory -s3 --name '<my config name>' -set RemoteMount.Enable true
|
||||||
|
```
|
||||||
|
|
||||||
|
- Set a secure encryption token:
|
||||||
|
|
||||||
|
- **Sia**
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
repertory -set RemoteMount.EncryptionToken '<my secure password>'
|
||||||
|
repertory --name '<my config name>' -set RemoteMount.EncryptionToken '<my secure password>'
|
||||||
|
```
|
||||||
|
|
||||||
|
- **S3**
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
repertory -s3 --name '<my config name>' -set RemoteMount.EncryptionToken '<my secure password>'
|
||||||
|
```
|
||||||
|
|
||||||
|
**Optional steps:**
|
||||||
|
|
||||||
|
- Change the port clients will use to connect to your mount:
|
||||||
|
|
||||||
|
- **Sia**
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
repertory -set RemoteMount.ApiPort 20000
|
||||||
|
repertory --name '<my config name>' -set RemoteMount.ApiPort 20000
|
||||||
|
```
|
||||||
|
|
||||||
|
- **S3**
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
repertory -s3 --name '<my config name>' -set RemoteMount.ApiPort 20000
|
||||||
|
```
|
||||||
|
|
||||||
|
**IMPORTANT:**
|
||||||
|
|
||||||
|
Be sure to configure your firewall to allow incoming TCP connections on the port configured in `RemoteMount.ApiPort`.
|
||||||
|
|
||||||
|
#### Remote Mount Configuration File Section
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"RemoteMount": {
|
||||||
|
"ApiPort": 20000,
|
||||||
|
"ClientPoolSize": 20,
|
||||||
|
"Enable": true,
|
||||||
|
"EncryptionToken": "<my secure password>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Client Setup
|
||||||
|
|
||||||
|
Client configuration is provider agnostic, so there's no need to specify `-s3` for S3 providers.
|
||||||
|
|
||||||
|
**Required steps:**
|
||||||
|
|
||||||
|
- Set the encryption token to the same value configured during server setup:
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
repertory -rm <host name or IP>:<port> -set RemoteConfig.EncryptionToken '<my secure password>'
|
||||||
|
# Replace <host name or IP> with the host name or IP of the server
|
||||||
|
# Replace <port> with the value of RemoteMount.ApiPort used in the server configuration
|
||||||
|
# Example:
|
||||||
|
repertory -rm 192.168.1.10:20000 -set RemoteConfig.EncryptionToken '<my secure password>'
|
||||||
|
repertory -rm my.host.com:20000 -set RemoteConfig.EncryptionToken '<my secure password>'
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Client Remote Mounting
|
||||||
|
|
||||||
|
<!-- markdownlint-disable-next-line -->
|
||||||
|
##### Linux
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
repertory -rm <host name or IP>:<port> /mnt/location
|
||||||
|
# Example:
|
||||||
|
repertory -rm 192.168.1.10:20000 /mnt/location
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- markdownlint-disable-next-line -->
|
||||||
|
##### macOS
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
repertory -rm <host name or IP>:<port> /Volumes/remotemount
|
||||||
|
# Example:
|
||||||
|
repertory -rm 192.168.1.10:20000 /Volumes/remotemount
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- markdownlint-disable-next-line -->
|
||||||
|
##### Windows
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
repertory -rm <host name or IP>:<port> t:
|
||||||
|
# Example:
|
||||||
|
repertory -rm 192.168.1.10:20000 t:
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Remote Mount Configuration File
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"ApiPassword": "<random generated rpc password>",
|
||||||
|
"ApiPort": 10010,
|
||||||
|
"ApiUser": "repertory",
|
||||||
|
"EnableDriveEvents": false,
|
||||||
|
"EventLevel": "info",
|
||||||
|
"RemoteConfig": {
|
||||||
|
"ApiPort": 20000,
|
||||||
|
"EncryptionToken": "<my secure password>",
|
||||||
|
"HostNameOrIp": "192.168.1.10",
|
||||||
|
"MaxConnections": 20,
|
||||||
|
"ReceiveTimeoutMs": 120000,
|
||||||
|
"SendTimeoutMs": 30000
|
||||||
|
},
|
||||||
|
"TaskWaitMs": 100,
|
||||||
|
"Version": 1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧰 Compiling
|
||||||
|
|
||||||
|
Successful compilation will place all required files for execution in the `dist/` directory.
|
||||||
|
|
||||||
|
### Linux Compilation
|
||||||
|
|
||||||
|
- Ensure `docker` is installed
|
||||||
|
|
||||||
|
- For `x86_64`:
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
scripts/make_unix.sh x86_64
|
||||||
|
scripts/make_unix.sh x86_64 Release
|
||||||
|
scripts/make_unix.sh x86_64 Debug
|
||||||
|
```
|
||||||
|
|
||||||
|
- For `aarch64`:
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
scripts/make_unix.sh aarch64
|
||||||
|
scripts/make_unix.sh aarch64 Release
|
||||||
|
scripts/make_unix.sh aarch64 Debug
|
||||||
|
```
|
||||||
|
|
||||||
|
### macOS Compilation
|
||||||
|
|
||||||
|
- Ensure `Xcode` and `CMake` are installed
|
||||||
|
|
||||||
|
- For `x86_64`:
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
scripts/make_unix.sh x86_64
|
||||||
|
scripts/make_unix.sh x86_64 Release
|
||||||
|
scripts/make_unix.sh x86_64 Debug
|
||||||
|
```
|
||||||
|
|
||||||
|
- For `aarch64`:
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
scripts/make_unix.sh aarch64
|
||||||
|
scripts/make_unix.sh aarch64 Release
|
||||||
|
scripts/make_unix.sh aarch64 Debug
|
||||||
|
```
|
||||||
|
|
||||||
|
### Windows Compilation
|
||||||
|
|
||||||
|
- **OFFICIAL: Cross-compiling on Linux**
|
||||||
|
|
||||||
|
- Ensure `docker` is installed
|
||||||
|
|
||||||
|
``` shell
|
||||||
|
scripts/make_win32.sh x86_64
|
||||||
|
scripts/make_win32.sh x86_64 Release
|
||||||
|
scripts/make_win32.sh x86_64 Debug
|
||||||
|
```
|
||||||
|
|
||||||
|
- **UNOFFICIAL: Compiling on Windows**
|
||||||
|
|
||||||
|
- Ensure latest [MSYS2](https://www.msys2.org/) is installed
|
||||||
|
|
||||||
|
``` cmd
|
||||||
|
scripts\make_win32.cmd x86_64
|
||||||
|
scripts\make_win32.cmd x86_64 Release
|
||||||
|
scripts\make_win32.cmd x86_64 Debug
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📜 Credits
|
||||||
|
|
||||||
|
- [binutils](https://www.gnu.org/software/binutils/)
|
||||||
|
- [boost c++ libraries](https://www.boost.org/)
|
||||||
|
- [cpp-httplib](https://github.com/yhirose/cpp-httplib)
|
||||||
|
- [curl](https://curl.haxx.se/)
|
||||||
|
- [docker](https://www.docker.com/)
|
||||||
|
- [Google Test](https://github.com/google/googletest)
|
||||||
|
- [ICU](https://icu.unicode.org/)
|
||||||
|
- [JSON for Modern C++](https://github.com/nlohmann/json)
|
||||||
|
- [libexpat](https://github.com/libexpat/libexpat)
|
||||||
|
- [libfuse](https://github.com/libfuse/libfuse)
|
||||||
|
- [libsodium](https://doc.libsodium.org/)
|
||||||
|
- [macFUSE](https://macfuse.github.io/)
|
||||||
|
- [mingw-w64](https://www.mingw-w64.org/)
|
||||||
|
- [MSYS2](https://www.msys2.org)
|
||||||
|
- [OpenSSL](https://www.openssl.org/)
|
||||||
|
- [pkg-config](https://www.freedesktop.org/wiki/Software/pkg-config/)
|
||||||
|
- [pugixml](https://pugixml.org/)
|
||||||
|
- [RocksDB](https://rocksdb.org)
|
||||||
|
- [ScPrime](https://scpri.me/)
|
||||||
|
- [Sia Decentralized Cloud Storage](https://sia.tech/)
|
||||||
|
- [spdlog](https://github.com/gabime/spdlog)
|
||||||
|
- [SQLite](https://www.sqlite.org)
|
||||||
|
- [stduuid](https://github.com/mariusbancila/stduuid)
|
||||||
|
- [Storj](https://www.storj.io/)
|
||||||
|
- [WinFSP - FUSE for Windows](https://github.com/billziss-gh/winfsp)
|
||||||
|
- [zlib](https://zlib.net/)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔑 Developer Public Key
|
||||||
|
|
||||||
```text
|
```text
|
||||||
-----BEGIN PUBLIC KEY-----
|
-----BEGIN PUBLIC KEY-----
|
||||||
|
|||||||
BIN
assets/blue/icon_24X24.png
Normal file
|
After Width: | Height: | Size: 262 B |
BIN
assets/blue/icon_40x40.png
Normal file
|
After Width: | Height: | Size: 298 B |
BIN
assets/blue/icon_48x48.png
Normal file
|
After Width: | Height: | Size: 315 B |
BIN
assets/blue/logo.icns
Normal file
BIN
assets/blue/logo.iconset/icon_128x128.png
Normal file
|
After Width: | Height: | Size: 552 B |
BIN
assets/blue/logo.iconset/icon_128x128@2x.png
Normal file
|
After Width: | Height: | Size: 820 B |
BIN
assets/blue/logo.iconset/icon_16x16.png
Normal file
|
After Width: | Height: | Size: 202 B |
BIN
assets/blue/logo.iconset/icon_16x16@2x.png
Normal file
|
After Width: | Height: | Size: 281 B |
BIN
assets/blue/logo.iconset/icon_256x256.png
Normal file
|
After Width: | Height: | Size: 820 B |
BIN
assets/blue/logo.iconset/icon_256x256@2x.png
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
BIN
assets/blue/logo.iconset/icon_32x32.png
Normal file
|
After Width: | Height: | Size: 281 B |
BIN
assets/blue/logo.iconset/icon_32x32@2x.png
Normal file
|
After Width: | Height: | Size: 361 B |
BIN
assets/blue/logo.iconset/icon_512x512.png
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
BIN
assets/blue/logo.iconset/icon_512x512@2x.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
assets/blue/logo.iconset/icon_64x64.png
Normal file
|
After Width: | Height: | Size: 361 B |
BIN
assets/blue/logo.iconset/icon_64x64@2x.png
Normal file
|
After Width: | Height: | Size: 552 B |
BIN
assets/blue/logo.iconset/logo_1024x1024.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
assets/green/icon_24X24.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
assets/green/icon_40x40.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
assets/green/icon_48x48.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
assets/green/logo.icns
Normal file
BIN
assets/green/logo.iconset/icon_128x128.png
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
BIN
assets/green/logo.iconset/icon_128x128@2x.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
assets/green/logo.iconset/icon_16x16.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
assets/green/logo.iconset/icon_16x16@2x.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
assets/green/logo.iconset/icon_256x256.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
assets/green/logo.iconset/icon_256x256@2x.png
Normal file
|
After Width: | Height: | Size: 4.5 KiB |
BIN
assets/green/logo.iconset/icon_32x32.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
assets/green/logo.iconset/icon_32x32@2x.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
BIN
assets/green/logo.iconset/icon_512x512.png
Normal file
|
After Width: | Height: | Size: 4.5 KiB |
BIN
assets/green/logo.iconset/icon_512x512@2x.png
Normal file
|
After Width: | Height: | Size: 8.4 KiB |
BIN
assets/green/logo.iconset/icon_64x64.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
BIN
assets/green/logo.iconset/icon_64x64@2x.png
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
BIN
assets/green/logo.iconset/logo_1024x1024.png
Normal file
|
After Width: | Height: | Size: 8.4 KiB |
BIN
assets/home.png
Normal file
|
After Width: | Height: | Size: 165 KiB |
BIN
assets/icon.icns
Normal file
BIN
assets/icon.ico
Normal file
|
After Width: | Height: | Size: 370 KiB |
BIN
assets/login.png
Normal file
|
After Width: | Height: | Size: 221 KiB |
BIN
assets/logo_blue.xcf
Normal file
BIN
assets/logo_green.xcf
Normal file
@@ -35,13 +35,9 @@ list(APPEND PROJECT_CXXFLAGS_LIST
|
|||||||
-Wcast-align
|
-Wcast-align
|
||||||
-Wconversion
|
-Wconversion
|
||||||
-Wdouble-promotion
|
-Wdouble-promotion
|
||||||
-Wduplicated-branches
|
|
||||||
-Wduplicated-cond
|
|
||||||
-Wextra
|
-Wextra
|
||||||
-Wformat=2
|
-Wformat=2
|
||||||
-Wlogical-op
|
|
||||||
-Wmisleading-indentation
|
-Wmisleading-indentation
|
||||||
-Wno-useless-cast
|
|
||||||
-Wnon-virtual-dtor
|
-Wnon-virtual-dtor
|
||||||
-Wnull-dereference
|
-Wnull-dereference
|
||||||
-Wold-style-cast
|
-Wold-style-cast
|
||||||
@@ -52,6 +48,15 @@ list(APPEND PROJECT_CXXFLAGS_LIST
|
|||||||
-Wunused
|
-Wunused
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (NOT PROJECT_IS_DARWIN)
|
||||||
|
list(APPEND PROJECT_CXXFLAGS_LIST
|
||||||
|
-Wduplicated-branches
|
||||||
|
-Wduplicated-cond
|
||||||
|
-Wlogical-op
|
||||||
|
-Wno-useless-cast
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
list(APPEND PROJECT_CFLAGS_LIST
|
list(APPEND PROJECT_CFLAGS_LIST
|
||||||
${PROJECT_COMMON_FLAG_LIST}
|
${PROJECT_COMMON_FLAG_LIST}
|
||||||
-std=c${CMAKE_C_STANDARD}
|
-std=c${CMAKE_C_STANDARD}
|
||||||
@@ -62,7 +67,7 @@ list(APPEND PROJECT_CXXFLAGS_LIST
|
|||||||
-std=gnu++${CMAKE_CXX_STANDARD}
|
-std=gnu++${CMAKE_CXX_STANDARD}
|
||||||
)
|
)
|
||||||
|
|
||||||
if(PROJECT_STATIC_LINK)
|
if(NOT PROJECT_IS_DARWIN AND PROJECT_STATIC_LINK)
|
||||||
list(APPEND PROJECT_CMAKE_EXE_LINKER_FLAGS
|
list(APPEND PROJECT_CMAKE_EXE_LINKER_FLAGS
|
||||||
-static-libgcc
|
-static-libgcc
|
||||||
-static-libstdc++
|
-static-libstdc++
|
||||||
@@ -89,7 +94,11 @@ set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${PROJECT_RELEASE_FLAG_L
|
|||||||
|
|
||||||
set(CMAKE_EXE_LINKER_FLAGS "${PROJECT_CMAKE_EXE_LINKER_FLAGS}")
|
set(CMAKE_EXE_LINKER_FLAGS "${PROJECT_CMAKE_EXE_LINKER_FLAGS}")
|
||||||
|
|
||||||
set(EXTERNAL_CMAKE_CXX_FLAGS "-include cstdint -include utility -fext-numeric-literals ${PROJECT_COMMON_FLAG_LIST}")
|
set(EXTERNAL_CMAKE_CXX_FLAGS "-include cstdint -include utility ${PROJECT_COMMON_FLAG_LIST}")
|
||||||
|
if (NOT PROJECT_IS_DARWIN)
|
||||||
|
set(EXTERNAL_CMAKE_CXX_FLAGS "-fext-numeric-literals ${EXTERNAL_CMAKE_CXX_FLAGS}")
|
||||||
|
endif()
|
||||||
|
|
||||||
list(APPEND PROJECT_EXTERNAL_CMAKE_FLAGS
|
list(APPEND PROJECT_EXTERNAL_CMAKE_FLAGS
|
||||||
-DCMAKE_BUILD_TYPE=${PROJECT_CMAKE_BUILD_TYPE}
|
-DCMAKE_BUILD_TYPE=${PROJECT_CMAKE_BUILD_TYPE}
|
||||||
-DCMAKE_COLOR_MAKEFILE=${CMAKE_COLOR_MAKEFILE}
|
-DCMAKE_COLOR_MAKEFILE=${CMAKE_COLOR_MAKEFILE}
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
if (PROJECT_MACOS_ICNS_NAME)
|
||||||
|
set(PROJECT_MACOS_ICNS_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/assets/${PROJECT_MACOS_ICNS_NAME}")
|
||||||
|
endif()
|
||||||
|
|
||||||
function(set_common_target_options name)
|
function(set_common_target_options name)
|
||||||
target_compile_definitions(${name} PUBLIC
|
target_compile_definitions(${name} PUBLIC
|
||||||
${PROJECT_DEFINITIONS}
|
${PROJECT_DEFINITIONS}
|
||||||
@@ -12,6 +16,17 @@ function(set_common_target_options name)
|
|||||||
${PROJECT_EXTERNAL_BUILD_ROOT}/lib
|
${PROJECT_EXTERNAL_BUILD_ROOT}/lib
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (PROJECT_STATIC_LINK)
|
||||||
|
target_compile_definitions(${name} PRIVATE U_STATIC_IMPLEMENTATION)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_link_libraries(${name} PRIVATE
|
||||||
|
ICU::io
|
||||||
|
ICU::i18n
|
||||||
|
ICU::uc
|
||||||
|
ICU::data
|
||||||
|
)
|
||||||
|
|
||||||
target_include_directories(${name} AFTER PUBLIC
|
target_include_directories(${name} AFTER PUBLIC
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/include
|
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/include
|
||||||
${name}_INCLUDES
|
${name}_INCLUDES
|
||||||
@@ -31,11 +46,31 @@ function(add_project_executable2 name dependencies libraries headers sources is_
|
|||||||
list(APPEND sources ${PROJECT_WINDOWS_VERSION_RC})
|
list(APPEND sources ${PROJECT_WINDOWS_VERSION_RC})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_executable(${name}
|
if (PROJECT_IS_DARWIN AND PROJECT_MACOS_ICNS_SOURCE AND "${name}" STREQUAL "${PROJECT_NAME}")
|
||||||
${headers}
|
set_source_files_properties(${PROJECT_MACOS_ICNS_SOURCE} PROPERTIES
|
||||||
${sources}
|
MACOSX_PACKAGE_LOCATION "Resources"
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/main.cpp
|
)
|
||||||
)
|
|
||||||
|
add_executable(${name}
|
||||||
|
MACOSX_BUNDLE
|
||||||
|
${headers}
|
||||||
|
${sources}
|
||||||
|
${PROJECT_MACOS_ICNS_SOURCE}
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/main.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
set_target_properties(${name} PROPERTIES
|
||||||
|
MACOSX_BUNDLE TRUE
|
||||||
|
MACOSX_BUNDLE_ICON_FILE "${PROJECT_MACOS_ICNS_NAME}"
|
||||||
|
RESOURCE "${PROJECT_MACOS_ICNS_SOURCE}"
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
add_executable(${name}
|
||||||
|
${headers}
|
||||||
|
${sources}
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/main.cpp
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
foreach(dependency ${dependencies})
|
foreach(dependency ${dependencies})
|
||||||
set_common_target_options(${dependency})
|
set_common_target_options(${dependency})
|
||||||
|
|||||||
@@ -1,20 +1,22 @@
|
|||||||
set(BINUTILS_HASH ae9a5789e23459e59606e6714723f2d3ffc31c03174191ef0d015bdf06007450)
|
set(BINUTILS_HASH ce2017e059d63e67ddb9240e9d4ec49c2893605035cd60e92ad53177f4377237)
|
||||||
set(BOOST_HASH f55c340aa49763b1925ccf02b2e83f35fdcf634c9d5164a2acb87540173c741d)
|
|
||||||
set(BOOST2_HASH 7bd7ddceec1a1dfdcbdb3e609b60d01739c38390a5f956385a12f3122049f0ca)
|
set(BOOST2_HASH 7bd7ddceec1a1dfdcbdb3e609b60d01739c38390a5f956385a12f3122049f0ca)
|
||||||
set(CPP_HTTPLIB_HASH 405abd8170f2a446fc8612ac635d0db5947c0d2e156e32603403a4496255ff00)
|
set(BOOST_HASH 9de758db755e8330a01d995b0a24d09798048400ac25c03fc5ea9be364b13c93)
|
||||||
set(CURL_HASH 5a231145114589491fc52da118f9c7ef8abee885d1cb1ced99c7290e9a352f07)
|
set(CPP_HTTPLIB_HASH a66f908f50ccb119769adce44fe1eac75f81b6ffab7c4ac0211bb663ffeb2688)
|
||||||
set(EXPAT_HASH 372b18f6527d162fa9658f1c74d22a37429b82d822f5a1e1fc7e00f6045a06a2)
|
set(CURL_HASH d4d9a5001b491f5726efe9b50bc4aad03029506e73c9261272e809c64b05e814)
|
||||||
set(GCC_HASH 7d376d445f93126dc545e2c0086d0f647c3094aae081cdb78f42ce2bc25e7293)
|
set(EXPAT_HASH 85372797ff0673a8fc4a6be16466bb5a0ca28c0dcf3c6f7ac1686b4a3ba2aabb)
|
||||||
set(GTEST_HASH 7b42b4d6ed48810c5362c265a17faebe90dc2373c885e5216439d37927f02926)
|
set(GCC_HASH 7294d65cc1a0558cb815af0ca8c7763d86f7a31199794ede3f630c0d1b0a5723)
|
||||||
set(ICU_HASH 925e6b4b8cf8856e0ac214f6f34e30dee63b7bb7a50460ab4603950eff48f89e)
|
set(GTEST_HASH 65fab701d9829d38cb77c14acdc431d2108bfdbf8979e40eb8ae567edf10b27c)
|
||||||
set(JSON_HASH 0d8ef5af7f9794e3263480193c491549b2ba6cc74bb018906202ada498a79406)
|
set(ICU_HASH a2c443404f00098e9e90acf29dc318e049d2dc78d9ae5f46efb261934a730ce2)
|
||||||
|
set(INNOSETUP_HASH fa73bf47a4da250d185d07561c2bfda387e5e20db77e4570004cf6a133cc10b1)
|
||||||
|
set(JSON_HASH 4b92eb0c06d10683f7447ce9406cb97cd4b453be18d7279320f7b2f025c10187)
|
||||||
set(LIBSODIUM_HASH 8e5aeca07a723a27bbecc3beef14b0068d37e7fc0e97f51b3f1c82d2a58005c1)
|
set(LIBSODIUM_HASH 8e5aeca07a723a27bbecc3beef14b0068d37e7fc0e97f51b3f1c82d2a58005c1)
|
||||||
set(MINGW_HASH 3f66bce069ee8bed7439a1a13da7cb91a5e67ea6170f21317ac7f5794625ee10)
|
set(MINGW_HASH 5afe822af5c4edbf67daaf45eec61d538f49eef6b19524de64897c6b95828caf)
|
||||||
set(OPENSSL_HASH e15dda82fe2fe8139dc2ac21a36d4ca01d5313c75f99f46c4e8a27709b7294bf)
|
set(OPENSSL_HASH b6a5f44b7eb69e3fa35dbf15524405b44837a481d43d81daddde3ff21fcbb8e9)
|
||||||
set(PKG_CONFIG_HASH 6fc69c01688c9458a57eb9a1664c9aba372ccda420a02bf4429fe610e7e7d591)
|
set(PKG_CONFIG_HASH 6fc69c01688c9458a57eb9a1664c9aba372ccda420a02bf4429fe610e7e7d591)
|
||||||
set(PUGIXML_HASH 2f10e276870c64b1db6809050a75e11a897a8d7456c4be5c6b2e35a11168a015)
|
set(PUGIXML_HASH 655ade57fa703fb421c2eb9a0113b5064bddb145d415dd1f88c79353d90d511a)
|
||||||
set(ROCKSDB_HASH 9b810c81731835fda0d4bbdb51d3199d901fa4395733ab63752d297da84c5a47)
|
set(ROCKSDB_HASH 7ec942baab802b2845188d02bc5d4e42c29236e61bcbc08f5b3a6bdd92290c22)
|
||||||
set(SPDLOG_HASH 9962648c9b4f1a7bbc76fd8d9172555bad1871fdb14ff4f842ef87949682caa5)
|
set(SPDLOG_HASH 15a04e69c222eb6c01094b5c7ff8a249b36bb22788d72519646fb85feb267e67)
|
||||||
set(SQLITE_HASH 77823cb110929c2bcb0f5d48e4833b5c59a8a6e40cdea3936b99e199dbbe5784)
|
set(SQLITE_HASH 1d3049dd0f830a025a53105fc79fd2ab9431aea99e137809d064d8ee8356b032)
|
||||||
set(STDUUID_HASH b1176597e789531c38481acbbed2a6894ad419aab0979c10410d59eb0ebf40d3)
|
set(STDUUID_HASH b1176597e789531c38481acbbed2a6894ad419aab0979c10410d59eb0ebf40d3)
|
||||||
|
set(WINFSP_HASH 073a70e00f77423e34bed98b86e600def93393ba5822204fac57a29324db9f7a)
|
||||||
set(ZLIB_HASH 17e88863f3600672ab49182f217281b6fc4d3c762bde361935e436a95214d05c)
|
set(ZLIB_HASH 17e88863f3600672ab49182f217281b6fc4d3c762bde361935e436a95214d05c)
|
||||||
|
|||||||
@@ -4,13 +4,17 @@ set(Boost_USE_STATIC_LIBS ${PROJECT_STATIC_LINK})
|
|||||||
set(CURL_USE_STATIC_LIBS ${PROJECT_STATIC_LINK})
|
set(CURL_USE_STATIC_LIBS ${PROJECT_STATIC_LINK})
|
||||||
set(OPENSSL_USE_STATIC_LIBS ${PROJECT_STATIC_LINK})
|
set(OPENSSL_USE_STATIC_LIBS ${PROJECT_STATIC_LINK})
|
||||||
set(SFML_STATIC_LIBRARIES ${PROJECT_STATIC_LINK})
|
set(SFML_STATIC_LIBRARIES ${PROJECT_STATIC_LINK})
|
||||||
set(ZLIB_USE_STATIC_LIBS ${PROJECT_STATIC_LINK})
|
if (PROJECT_IS_DARWIN)
|
||||||
|
set(ZLIB_USE_STATIC_LIBS OFF)
|
||||||
|
else()
|
||||||
|
set(ZLIB_USE_STATIC_LIBS ${PROJECT_STATIC_LINK})
|
||||||
|
endif()
|
||||||
set(wxWidgets_USE_STATIC ${PROJECT_STATIC_LINK})
|
set(wxWidgets_USE_STATIC ${PROJECT_STATIC_LINK})
|
||||||
|
set(ICU_USE_STATIC_LIBS ${PROJECT_STATIC_LINK})
|
||||||
|
|
||||||
|
include(cmake/libraries/icu.cmake)
|
||||||
include(cmake/libraries/openssl.cmake)
|
include(cmake/libraries/openssl.cmake)
|
||||||
|
|
||||||
include(cmake/libraries/boost.cmake)
|
include(cmake/libraries/boost.cmake)
|
||||||
|
|
||||||
include(cmake/libraries/cpp_httplib.cmake)
|
include(cmake/libraries/cpp_httplib.cmake)
|
||||||
include(cmake/libraries/curl.cmake)
|
include(cmake/libraries/curl.cmake)
|
||||||
include(cmake/libraries/fuse.cmake)
|
include(cmake/libraries/fuse.cmake)
|
||||||
@@ -59,7 +63,7 @@ if(PROJECT_BUILD)
|
|||||||
winspool
|
winspool
|
||||||
ws2_32
|
ws2_32
|
||||||
)
|
)
|
||||||
else()
|
elseif(NOT PROJECT_IS_DARWIN)
|
||||||
link_libraries(
|
link_libraries(
|
||||||
uring
|
uring
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -39,6 +39,14 @@ if(PROJECT_ENABLE_BOOST)
|
|||||||
wserialization
|
wserialization
|
||||||
)
|
)
|
||||||
else()
|
else()
|
||||||
|
if(PROJECT_IS_DARWIN)
|
||||||
|
set(CMAKE_HAVE_THREADS_LIBRARY 1)
|
||||||
|
set(CMAKE_THREAD_LIBS_INIT "-lpthread")
|
||||||
|
set(CMAKE_USE_PTHREADS_INIT 1)
|
||||||
|
set(CMAKE_USE_WIN32_THREADS_INIT 0)
|
||||||
|
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||||
|
endif()
|
||||||
|
|
||||||
find_package(Boost ${BOOST_MAJOR_VERSION}.${BOOST_MINOR_VERSION}.${BOOST_PATCH_VERSION}
|
find_package(Boost ${BOOST_MAJOR_VERSION}.${BOOST_MINOR_VERSION}.${BOOST_PATCH_VERSION}
|
||||||
REQUIRED
|
REQUIRED
|
||||||
COMPONENTS
|
COMPONENTS
|
||||||
@@ -54,7 +62,6 @@ if(PROJECT_ENABLE_BOOST)
|
|||||||
random
|
random
|
||||||
regex
|
regex
|
||||||
serialization
|
serialization
|
||||||
system
|
|
||||||
thread
|
thread
|
||||||
wserialization
|
wserialization
|
||||||
)
|
)
|
||||||
@@ -120,17 +127,23 @@ if(PROJECT_ENABLE_BOOST)
|
|||||||
--with-libraries=atomic,chrono,date_time,filesystem,iostreams,locale,log,program_options,random,regex,serialization,system,test,thread
|
--with-libraries=atomic,chrono,date_time,filesystem,iostreams,locale,log,program_options,random,regex,serialization,system,test,thread
|
||||||
BUILD_COMMAND
|
BUILD_COMMAND
|
||||||
./b2
|
./b2
|
||||||
-j1
|
-sNO_BZIP2=1
|
||||||
|
-j$ENV{CMAKE_BUILD_PARALLEL_LEVEL}
|
||||||
${BOOST_BUILD_ARGS}
|
${BOOST_BUILD_ARGS}
|
||||||
INSTALL_COMMAND
|
INSTALL_COMMAND
|
||||||
./b2
|
./b2
|
||||||
-j1
|
-sNO_BZIP2=1
|
||||||
|
-j$ENV{CMAKE_BUILD_PARALLEL_LEVEL}
|
||||||
${BOOST_BUILD_ARGS}
|
${BOOST_BUILD_ARGS}
|
||||||
install
|
install
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND PROJECT_DEPENDENCIES boost_project)
|
list(APPEND PROJECT_DEPENDENCIES boost_project)
|
||||||
|
|
||||||
|
if(PROJECT_IS_DARWIN OR PROJECT_REQUIRE_ALPINE)
|
||||||
|
add_dependencies(boost_project icu_project)
|
||||||
|
endif()
|
||||||
|
|
||||||
if (NOT CMAKE_HOST_WIN32)
|
if (NOT CMAKE_HOST_WIN32)
|
||||||
add_dependencies(boost_project openssl_project)
|
add_dependencies(boost_project openssl_project)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -15,10 +15,14 @@ if(PROJECT_ENABLE_CPP_HTTPLIB)
|
|||||||
CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
|
CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
|
||||||
-DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
|
-DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
|
||||||
-DBUILD_STATIC_LIBS=ON
|
-DBUILD_STATIC_LIBS=ON
|
||||||
-DHTTPLIB_REQUIRE_OPENSSL=${PROJECT_ENABLE_OPENSSL}
|
-DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
|
||||||
-DHTTPLIB_REQUIRE_ZLIB=ON
|
|
||||||
-DHTTPLIB_REQUIRE_BROTLI=OFF
|
-DHTTPLIB_REQUIRE_BROTLI=OFF
|
||||||
|
-DHTTPLIB_REQUIRE_OPENSSL=ON
|
||||||
|
-DHTTPLIB_REQUIRE_ZLIB=ON
|
||||||
-DHTTPLIB_TEST=OFF
|
-DHTTPLIB_TEST=OFF
|
||||||
|
-DHTTPLIB_USE_BROTLI_IF_AVAILABLE=OFF
|
||||||
|
-DHTTPLIB_USE_OPENSSL_IF_AVAILABLE=ON
|
||||||
|
-DHTTPLIB_USE_ZLIB_IF_AVAILABLE=ON
|
||||||
-DOPENSSL_USE_STATIC_LIBS=${OPENSSL_USE_STATIC_LIBS}
|
-DOPENSSL_USE_STATIC_LIBS=${OPENSSL_USE_STATIC_LIBS}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -18,14 +18,18 @@ if(PROJECT_ENABLE_CURL)
|
|||||||
URL ${PROJECT_3RD_PARTY_DIR}/curl-${CURL_VERSION}.tar.gz
|
URL ${PROJECT_3RD_PARTY_DIR}/curl-${CURL_VERSION}.tar.gz
|
||||||
URL_HASH SHA256=${CURL_HASH}
|
URL_HASH SHA256=${CURL_HASH}
|
||||||
LIST_SEPARATOR |
|
LIST_SEPARATOR |
|
||||||
CMAKE_ARGS
|
BUILD_COMMAND
|
||||||
${PROJECT_EXTERNAL_CMAKE_FLAGS}
|
${CMAKE_COMMAND} --build . -- -j$ENV{CMAKE_BUILD_PARALLEL_LEVEL}
|
||||||
-DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
|
CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
|
||||||
-DBUILD_STATIC_LIBS=ON
|
|
||||||
-DBUILD_CURL_EXE=OFF
|
-DBUILD_CURL_EXE=OFF
|
||||||
|
-DBUILD_LIBCURL_DOCS=OFF
|
||||||
|
-DBUILD_MISC_DOCS=OFF
|
||||||
|
-DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
|
||||||
-DBUILD_STATIC_CURL=ON
|
-DBUILD_STATIC_CURL=ON
|
||||||
-DBUILD_STATIC_LIBS=ON
|
-DBUILD_STATIC_LIBS=ON
|
||||||
-DBUILD_TESTING=OFF
|
-DBUILD_TESTING=OFF
|
||||||
|
-DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
|
||||||
|
-DCURL_BROTLI=OFF
|
||||||
-DCURL_CA_BUNDLE=./cacert.pem
|
-DCURL_CA_BUNDLE=./cacert.pem
|
||||||
-DCURL_CA_FALLBACK=ON
|
-DCURL_CA_FALLBACK=ON
|
||||||
-DCURL_DISABLE_LDAP=ON
|
-DCURL_DISABLE_LDAP=ON
|
||||||
@@ -33,10 +37,13 @@ if(PROJECT_ENABLE_CURL)
|
|||||||
-DCURL_USE_LIBSSH2=OFF
|
-DCURL_USE_LIBSSH2=OFF
|
||||||
-DCURL_USE_OPENSSL=${PROJECT_ENABLE_OPENSSL}
|
-DCURL_USE_OPENSSL=${PROJECT_ENABLE_OPENSSL}
|
||||||
-DCURL_ZLIB=ON
|
-DCURL_ZLIB=ON
|
||||||
|
-DCURL_ZSTD=OFF
|
||||||
|
-DENABLE_CURL_MANUAL=OFF
|
||||||
-DENABLE_THREADED_RESOLVER=ON
|
-DENABLE_THREADED_RESOLVER=ON
|
||||||
-DOPENSSL_ROOT_DIR=${OPENSSL_ROOT_DIR}
|
-DOPENSSL_ROOT_DIR=${OPENSSL_ROOT_DIR}
|
||||||
-DOPENSSL_USE_STATIC_LIBS=${OPENSSL_USE_STATIC_LIBS}
|
-DOPENSSL_USE_STATIC_LIBS=${OPENSSL_USE_STATIC_LIBS}
|
||||||
-DUSE_LIBIDN2=OFF
|
-DUSE_LIBIDN2=OFF
|
||||||
|
-DUSE_NGHTTP2=OFF
|
||||||
-DZLIB_USE_STATIC_LIBS=${ZLIB_USE_STATIC_LIBS}
|
-DZLIB_USE_STATIC_LIBS=${ZLIB_USE_STATIC_LIBS}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -20,17 +20,25 @@ if(PROJECT_ENABLE_FUSE AND NOT PROJECT_IS_MINGW)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
pkg_check_modules(LIBFUSE3 fuse3>=3.0.0)
|
if (PROJECT_IS_DARWIN)
|
||||||
if(LIBFUSE3_FOUND)
|
find_library(OSXFUSE NO_CACHE NAMES OSXFUSE)
|
||||||
set(PROJECT_FUSE fuse3)
|
if (NOT OSXFUSE)
|
||||||
set(PROJECT_FUSE_INCLUDE_DIRS ${LIBFUSE3_INCLUDE_DIRS})
|
message(FATAL_ERROR "FUSE for macOS not found (https://macfuse.github.io)")
|
||||||
|
endif ()
|
||||||
|
set(PROJECT_FUSE fuse2)
|
||||||
else()
|
else()
|
||||||
pkg_check_modules(LIBFUSE2 fuse>=2.9.0)
|
pkg_check_modules(LIBFUSE3 fuse3>=3.0.0)
|
||||||
if(LIBFUSE2_FOUND)
|
if(LIBFUSE3_FOUND)
|
||||||
set(PROJECT_FUSE fuse2)
|
set(PROJECT_FUSE fuse3)
|
||||||
set(PROJECT_FUSE_INCLUDE_DIRS ${LIBFUSE2_INCLUDE_DIRS})
|
set(PROJECT_FUSE_INCLUDE_DIRS ${LIBFUSE3_INCLUDE_DIRS})
|
||||||
else()
|
else()
|
||||||
message(FATAL_ERROR "fuse library not found")
|
pkg_check_modules(LIBFUSE2 fuse>=2.9.0)
|
||||||
|
if(LIBFUSE2_FOUND)
|
||||||
|
set(PROJECT_FUSE fuse2)
|
||||||
|
set(PROJECT_FUSE_INCLUDE_DIRS ${LIBFUSE2_INCLUDE_DIRS})
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "fuse library not found")
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
24
cmake/libraries/icu.cmake
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
if((PROJECT_IS_DARWIN OR PROJECT_REQUIRE_ALPINE) AND NOT PROJECT_IS_MINGW AND NOT PROJECT_BUILD)
|
||||||
|
if(PROJECT_BUILD_SHARED_LIBS)
|
||||||
|
set(ICU_ENABLE_SHARED yes)
|
||||||
|
else()
|
||||||
|
set(ICU_ENABLE_SHARED no)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
ExternalProject_Add(icu_project
|
||||||
|
PREFIX external
|
||||||
|
URL ${PROJECT_3RD_PARTY_DIR}/mingw64/icu-release-${ICU_VERSION}.tar.gz
|
||||||
|
URL_HASH SHA256=${ICU_HASH}
|
||||||
|
BUILD_IN_SOURCE 1
|
||||||
|
LIST_SEPARATOR |
|
||||||
|
PATCH_COMMAND chmod +x ${PROJECT_3RD_PARTY_DIR}/icu_configure.sh
|
||||||
|
CONFIGURE_COMMAND cd icu4c/source && ${PROJECT_3RD_PARTY_DIR}/icu_configure.sh
|
||||||
|
${PROJECT_MARCH}
|
||||||
|
${PROJECT_EXTERNAL_BUILD_ROOT}
|
||||||
|
${ICU_ENABLE_SHARED}
|
||||||
|
BUILD_COMMAND cd icu4c/source && make -j$ENV{CMAKE_BUILD_PARALLEL_LEVEL}
|
||||||
|
INSTALL_COMMAND cd icu4c/source && make install
|
||||||
|
)
|
||||||
|
|
||||||
|
list(APPEND PROJECT_DEPENDENCIES icu_project)
|
||||||
|
endif()
|
||||||
@@ -18,6 +18,7 @@ if(PROJECT_ENABLE_JSON)
|
|||||||
CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
|
CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
|
||||||
-DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
|
-DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
|
||||||
-DBUILD_STATIC_LIBS=ON
|
-DBUILD_STATIC_LIBS=ON
|
||||||
|
-DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
|
||||||
-DJSON_BuildTests=OFF
|
-DJSON_BuildTests=OFF
|
||||||
-DJSON_Install=ON
|
-DJSON_Install=ON
|
||||||
-DJSON_MultipleHeaders=OFF
|
-DJSON_MultipleHeaders=OFF
|
||||||
|
|||||||
@@ -15,6 +15,12 @@ if(PROJECT_ENABLE_OPENSSL)
|
|||||||
elseif(NOT PROJECT_IS_MINGW)
|
elseif(NOT PROJECT_IS_MINGW)
|
||||||
if(PROJECT_IS_MINGW)
|
if(PROJECT_IS_MINGW)
|
||||||
set(OPENSSL_COMPILE_TYPE mingw64)
|
set(OPENSSL_COMPILE_TYPE mingw64)
|
||||||
|
elseif(PROJECT_IS_DARWIN)
|
||||||
|
if(PROJECT_IS_ARM64)
|
||||||
|
set(OPENSSL_COMPILE_TYPE darwin64-arm64)
|
||||||
|
else()
|
||||||
|
set(OPENSSL_COMPILE_TYPE darwin64-x86_64)
|
||||||
|
endif()
|
||||||
elseif(PROJECT_IS_ARM64)
|
elseif(PROJECT_IS_ARM64)
|
||||||
set(OPENSSL_COMPILE_TYPE linux-aarch64)
|
set(OPENSSL_COMPILE_TYPE linux-aarch64)
|
||||||
else()
|
else()
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ if(PROJECT_ENABLE_PUGIXML)
|
|||||||
CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
|
CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
|
||||||
-DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
|
-DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
|
||||||
-DBUILD_STATIC_LIBS=ON
|
-DBUILD_STATIC_LIBS=ON
|
||||||
|
-DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND PROJECT_DEPENDENCIES pugixml_project)
|
list(APPEND PROJECT_DEPENDENCIES pugixml_project)
|
||||||
|
|||||||
@@ -9,15 +9,19 @@ if(PROJECT_ENABLE_ROCKSDB)
|
|||||||
URL ${PROJECT_3RD_PARTY_DIR}/rocksdb-${ROCKSDB_VERSION}.tar.gz
|
URL ${PROJECT_3RD_PARTY_DIR}/rocksdb-${ROCKSDB_VERSION}.tar.gz
|
||||||
URL_HASH SHA256=${ROCKSDB_HASH}
|
URL_HASH SHA256=${ROCKSDB_HASH}
|
||||||
LIST_SEPARATOR |
|
LIST_SEPARATOR |
|
||||||
|
BUILD_COMMAND
|
||||||
|
${CMAKE_COMMAND} --build . -- -j$ENV{CMAKE_BUILD_PARALLEL_LEVEL}
|
||||||
CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
|
CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
|
||||||
-DBUILD_SHARED_LIBS=OFF
|
-DBUILD_SHARED_LIBS=OFF
|
||||||
-DBUILD_STATIC_LIBS=ON
|
-DBUILD_STATIC_LIBS=ON
|
||||||
|
-DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
|
||||||
-DFAIL_ON_WARNINGS=OFF
|
-DFAIL_ON_WARNINGS=OFF
|
||||||
-DPORTABLE=1
|
-DPORTABLE=1
|
||||||
-DROCKSDB_BUILD_SHARED=OFF
|
-DROCKSDB_BUILD_SHARED=OFF
|
||||||
-DROCKSDB_INSTALL_ON_WINDOWS=ON
|
-DROCKSDB_INSTALL_ON_WINDOWS=ON
|
||||||
-DWITH_BENCHMARK=OFF
|
-DWITH_BENCHMARK=OFF
|
||||||
-DWITH_BENCHMARK_TOOLS=OFF
|
-DWITH_BENCHMARK_TOOLS=OFF
|
||||||
|
-DWITH_BZ2=OFF
|
||||||
-DWITH_CORE_TOOLS=OFF
|
-DWITH_CORE_TOOLS=OFF
|
||||||
-DWITH_EXAMPLES=OFF
|
-DWITH_EXAMPLES=OFF
|
||||||
-DWITH_GFLAGS=OFF
|
-DWITH_GFLAGS=OFF
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ if(PROJECT_ENABLE_SPDLOG)
|
|||||||
LIST_SEPARATOR |
|
LIST_SEPARATOR |
|
||||||
CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
|
CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
|
||||||
-DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
|
-DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
|
||||||
|
-DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
|
||||||
-DSPDLOG_BUILD_EXAMPLE=OFF
|
-DSPDLOG_BUILD_EXAMPLE=OFF
|
||||||
-DSPDLOG_FMT_EXTERNAL=OFF
|
-DSPDLOG_FMT_EXTERNAL=OFF
|
||||||
-DSPDLOG_FMT_EXTERNAL_HO=OFF
|
-DSPDLOG_FMT_EXTERNAL_HO=OFF
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ if(PROJECT_ENABLE_SQLITE)
|
|||||||
if(PROJECT_BUILD)
|
if(PROJECT_BUILD)
|
||||||
add_definitions(-DPROJECT_ENABLE_SQLITE)
|
add_definitions(-DPROJECT_ENABLE_SQLITE)
|
||||||
if (PROJECT_IS_MINGW AND NOT PROJECT_IS_MINGW_UNIX)
|
if (PROJECT_IS_MINGW AND NOT PROJECT_IS_MINGW_UNIX)
|
||||||
pkg_check_modules(SQLITE3 REQUIRED sqlite3>=${SQLITE2_VERSION})
|
pkg_check_modules(SQLITE3 REQUIRED sqlite3)
|
||||||
include_directories(SYSTEM BEFORE ${SQLITE3_INCLUDE_DIRS})
|
include_directories(SYSTEM BEFORE ${SQLITE3_INCLUDE_DIRS})
|
||||||
link_libraries(${SQLITE3_LIBRARIES})
|
link_libraries(${SQLITE3_LIBRARIES})
|
||||||
else()
|
else()
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ if(PROJECT_ENABLE_STDUUID)
|
|||||||
CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
|
CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
|
||||||
-DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
|
-DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
|
||||||
-DBUILD_STATIC_LIBS=ON
|
-DBUILD_STATIC_LIBS=ON
|
||||||
|
-DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
|
||||||
-DUUID_BUILD_TESTS=OFF
|
-DUUID_BUILD_TESTS=OFF
|
||||||
-DUUID_ENABLE_INSTALL=ON
|
-DUUID_ENABLE_INSTALL=ON
|
||||||
-DUUID_USING_CXX20_SPAN=ON
|
-DUUID_USING_CXX20_SPAN=ON
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ if (PROJECT_ENABLE_TESTING)
|
|||||||
CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
|
CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
|
||||||
-DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
|
-DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
|
||||||
-DBUILD_STATIC_LIBS=ON
|
-DBUILD_STATIC_LIBS=ON
|
||||||
|
-DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND PROJECT_DEPENDENCIES gtest_project)
|
list(APPEND PROJECT_DEPENDENCIES gtest_project)
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ if(PROJECT_ENABLE_WINFSP AND PROJECT_IS_MINGW)
|
|||||||
if(PROJECT_BUILD)
|
if(PROJECT_BUILD)
|
||||||
add_definitions(-DPROJECT_ENABLE_WINFSP)
|
add_definitions(-DPROJECT_ENABLE_WINFSP)
|
||||||
|
|
||||||
include_directories(BEFORE SYSTEM ${PROJECT_3RD_PARTY_DIR}/winfsp-2.0/inc)
|
include_directories(BEFORE SYSTEM ${PROJECT_3RD_PARTY_DIR}/winfsp-2.1/inc)
|
||||||
|
|
||||||
link_directories(BEFORE ${PROJECT_3RD_PARTY_DIR}/winfsp-2.0/lib)
|
link_directories(BEFORE ${PROJECT_3RD_PARTY_DIR}/winfsp-2.1/lib)
|
||||||
|
|
||||||
if(PROJECT_IS_ARM64)
|
if(PROJECT_IS_ARM64)
|
||||||
link_libraries(winfsp-a64)
|
link_libraries(winfsp-a64)
|
||||||
|
|||||||
@@ -2,10 +2,6 @@ if(MSVC)
|
|||||||
message(FATAL_ERROR "MSVC will not be supported")
|
message(FATAL_ERROR "MSVC will not be supported")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(UNIX AND APPLE)
|
|
||||||
message(FATAL_ERROR "Apple is not currently supported")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
|
if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
|
||||||
message(FATAL_ERROR "FreeBSD is not currently supported")
|
message(FATAL_ERROR "FreeBSD is not currently supported")
|
||||||
endif()
|
endif()
|
||||||
@@ -13,3 +9,15 @@ endif()
|
|||||||
if(PROJECT_REQUIRE_ALPINE AND NOT PROJECT_IS_ALPINE AND PROJECT_IS_MINGW AND PROJECT_IS_MINGW_UNIX)
|
if(PROJECT_REQUIRE_ALPINE AND NOT PROJECT_IS_ALPINE AND PROJECT_IS_MINGW AND PROJECT_IS_MINGW_UNIX)
|
||||||
message(FATAL_ERROR "Project requires Alpine Linux to build")
|
message(FATAL_ERROR "Project requires Alpine Linux to build")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (PROJECT_IS_DARWIN)
|
||||||
|
if (PROJECT_IS_ARM64)
|
||||||
|
set(CMAKE_OSX_ARCHITECTURES "arm64")
|
||||||
|
else()
|
||||||
|
set(CMAKE_OSX_ARCHITECTURES "x86_64")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (PROJECT_IS_DARWIN AND NOT PROJECT_MACOS_BUNDLE_ID)
|
||||||
|
message(FATAL_ERROR "'PROJECT_MACOS_BUNDLE_ID' is not set in 'config.sh'")
|
||||||
|
endif()
|
||||||
|
|||||||
@@ -1,28 +1,30 @@
|
|||||||
set(BINUTILS_VERSION 2.41)
|
set(BINUTILS_VERSION 2.44)
|
||||||
|
set(BOOST_MAJOR_VERSION 1)
|
||||||
|
set(BOOST_MINOR_VERSION 89)
|
||||||
|
set(BOOST_PATCH_VERSION 0)
|
||||||
set(BOOST2_MAJOR_VERSION 1)
|
set(BOOST2_MAJOR_VERSION 1)
|
||||||
set(BOOST2_MINOR_VERSION 76)
|
set(BOOST2_MINOR_VERSION 76)
|
||||||
set(BOOST2_PATCH_VERSION 0)
|
set(BOOST2_PATCH_VERSION 0)
|
||||||
set(BOOST_MAJOR_VERSION 1)
|
set(CPP_HTTPLIB_VERSION 0.26.0)
|
||||||
set(BOOST_MINOR_VERSION 87)
|
set(CURL_VERSION 8.16.0)
|
||||||
set(BOOST_PATCH_VERSION 0)
|
set(CURL2_VERSION 8_16_0)
|
||||||
set(CPP_HTTPLIB_VERSION 0.18.1)
|
set(EXPAT_VERSION 2.7.1)
|
||||||
set(CURL2_VERSION 8_11_0)
|
set(EXPAT2_VERSION 2_7_1)
|
||||||
set(CURL_VERSION 8.11.0)
|
set(GCC_VERSION 15.2.0)
|
||||||
set(EXPAT2_VERSION 2_6_4)
|
set(GTEST_VERSION 1.17.0)
|
||||||
set(EXPAT_VERSION 2.6.4)
|
set(ICU_VERSION 76-1)
|
||||||
set(GCC_VERSION 14.2.0)
|
set(INNOSETUP_VERSION 6.5.4)
|
||||||
set(GTEST_VERSION 1.15.2)
|
set(JSON_VERSION 3.12.0)
|
||||||
set(ICU_VERSION 75-1)
|
|
||||||
set(JSON_VERSION 3.11.3)
|
|
||||||
set(LIBSODIUM_VERSION 1.0.20)
|
set(LIBSODIUM_VERSION 1.0.20)
|
||||||
set(MESA_VERSION 23.3.3)
|
set(MINGW_VERSION 13.0.0)
|
||||||
set(MINGW_VERSION 11.0.1)
|
set(OPENSSL_VERSION 3.6.0)
|
||||||
set(OPENSSL_VERSION 3.4.0)
|
|
||||||
set(PKG_CONFIG_VERSION 0.29.2)
|
set(PKG_CONFIG_VERSION 0.29.2)
|
||||||
set(PUGIXML_VERSION 1.14)
|
set(PUGIXML_VERSION 1.15)
|
||||||
set(ROCKSDB_VERSION 9.7.4)
|
set(ROCKSDB_VERSION 10.5.1)
|
||||||
set(SPDLOG_VERSION 1.15.0)
|
set(SPDLOG_VERSION 1.15.3)
|
||||||
set(SQLITE2_VERSION 3.46.1)
|
set(SQLITE_VERSION 3500400)
|
||||||
set(SQLITE_VERSION 3460100)
|
set(SQLITE2_VERSION 3.50.4)
|
||||||
set(STDUUID_VERSION 1.2.3)
|
set(STDUUID_VERSION 1.2.3)
|
||||||
|
set(WINFSP_VERSION 2.1.25156)
|
||||||
|
set(WINFSP2_VERSION 2.1)
|
||||||
set(ZLIB_VERSION 1.3.1)
|
set(ZLIB_VERSION 1.3.1)
|
||||||
|
|||||||
16
config.sh
@@ -5,20 +5,26 @@ PROJECT_NAME="repertory"
|
|||||||
PROJECT_COMPANY_NAME="https://git.fifthgrid.com/blockstorage"
|
PROJECT_COMPANY_NAME="https://git.fifthgrid.com/blockstorage"
|
||||||
PROJECT_URL="${PROJECT_COMPANY_NAME}/repertory"
|
PROJECT_URL="${PROJECT_COMPANY_NAME}/repertory"
|
||||||
|
|
||||||
PROJECT_COPYRIGHT="Copyright <2018-2024> <MIT License> <${PROJECT_URL}>"
|
PROJECT_COPYRIGHT="Copyright <2018-2025> <MIT License> <${PROJECT_URL}>"
|
||||||
PROJECT_DESC="Mount utility for Sia and S3"
|
PROJECT_DESC="Mount utility for Sia and S3"
|
||||||
|
|
||||||
|
PROJECT_MACOS_BUNDLE_ID="com.fifthgrid.blockstorage.repertory"
|
||||||
|
PROJECT_MACOS_ICNS_NAME="icon.icns"
|
||||||
|
|
||||||
PROJECT_MAJOR_VERSION=2
|
PROJECT_MAJOR_VERSION=2
|
||||||
PROJECT_MINOR_VERSION=0
|
PROJECT_MINOR_VERSION=1
|
||||||
PROJECT_REVISION_VERSION=2
|
PROJECT_REVISION_VERSION=0
|
||||||
PROJECT_RELEASE_NUM=0
|
PROJECT_RELEASE_NUM=1
|
||||||
PROJECT_RELEASE_ITER=rc
|
PROJECT_RELEASE_ITER=rc.2
|
||||||
|
|
||||||
PROJECT_APP_LIST=(${PROJECT_NAME})
|
PROJECT_APP_LIST=(${PROJECT_NAME})
|
||||||
|
|
||||||
PROJECT_PRIVATE_KEY=${DEVELOPER_PRIVATE_KEY}
|
PROJECT_PRIVATE_KEY=${DEVELOPER_PRIVATE_KEY}
|
||||||
PROJECT_PUBLIC_KEY=${DEVELOPER_PUBLIC_KEY}
|
PROJECT_PUBLIC_KEY=${DEVELOPER_PUBLIC_KEY}
|
||||||
|
|
||||||
|
PROJECT_FLUTTER_BASE_HREF="/ui/"
|
||||||
|
|
||||||
|
PROJECT_ENABLE_V2_ERRORS=ON
|
||||||
PROJECT_ENABLE_WIN32_LONG_PATH_NAMES=OFF
|
PROJECT_ENABLE_WIN32_LONG_PATH_NAMES=OFF
|
||||||
|
|
||||||
PROJECT_ENABLE_BACKWARD_CPP=OFF
|
PROJECT_ENABLE_BACKWARD_CPP=OFF
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
FROM arm64v8/alpine:3.20.3
|
#comment
|
||||||
|
FROM arm64v8/alpine:3.22.2
|
||||||
MAINTAINER Scott E. Graves <scott.e.graves@protonmail.com>
|
MAINTAINER Scott E. Graves <scott.e.graves@protonmail.com>
|
||||||
CMD bash
|
CMD bash
|
||||||
|
|
||||||
@@ -30,10 +31,7 @@ RUN apk add \
|
|||||||
gflags \
|
gflags \
|
||||||
gflags-dev \
|
gflags-dev \
|
||||||
git \
|
git \
|
||||||
gtkmm3-dev \
|
git-lfs \
|
||||||
icu-dev \
|
|
||||||
icu-libs \
|
|
||||||
icu-static \
|
|
||||||
libogg-dev \
|
libogg-dev \
|
||||||
libogg-static \
|
libogg-static \
|
||||||
libtool \
|
libtool \
|
||||||
@@ -69,7 +67,6 @@ RUN apk add \
|
|||||||
tcl \
|
tcl \
|
||||||
tcl-dev \
|
tcl-dev \
|
||||||
texinfo \
|
texinfo \
|
||||||
vlc-dev \
|
|
||||||
wget \
|
wget \
|
||||||
xz \
|
xz \
|
||||||
xz-dev \
|
xz-dev \
|
||||||
@@ -82,3 +79,6 @@ RUN apk add \
|
|||||||
zstd-libs \
|
zstd-libs \
|
||||||
zstd-static \
|
zstd-static \
|
||||||
xz-static
|
xz-static
|
||||||
|
|
||||||
|
RUN ln -sf /usr/bin/aclocal-1.17 /usr/bin/aclocal-1.16
|
||||||
|
RUN ln -sf /usr/bin/automake-1.17 /usr/bin/automake-1.16
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
FROM alpine:3.20.3
|
#comment
|
||||||
|
FROM alpine:3.22.2
|
||||||
MAINTAINER Scott E. Graves <scott.e.graves@protonmail.com>
|
MAINTAINER Scott E. Graves <scott.e.graves@protonmail.com>
|
||||||
CMD bash
|
CMD bash
|
||||||
|
|
||||||
@@ -30,9 +31,7 @@ RUN apk add \
|
|||||||
gflags \
|
gflags \
|
||||||
gflags-dev \
|
gflags-dev \
|
||||||
git \
|
git \
|
||||||
icu-dev \
|
git-lfs \
|
||||||
icu-libs \
|
|
||||||
icu-static \
|
|
||||||
libogg-dev \
|
libogg-dev \
|
||||||
libogg-static \
|
libogg-static \
|
||||||
libtool \
|
libtool \
|
||||||
@@ -80,3 +79,6 @@ RUN apk add \
|
|||||||
zstd-libs \
|
zstd-libs \
|
||||||
zstd-static \
|
zstd-static \
|
||||||
xz-static
|
xz-static
|
||||||
|
|
||||||
|
RUN ln -sf /usr/bin/aclocal-1.17 /usr/bin/aclocal-1.16
|
||||||
|
RUN ln -sf /usr/bin/automake-1.17 /usr/bin/automake-1.16
|
||||||
|
|||||||
47
docker/x86_64/flutter
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
FROM debian:latest
|
||||||
|
|
||||||
|
ARG UID=0
|
||||||
|
ARG GID=0
|
||||||
|
|
||||||
|
RUN apt-get update
|
||||||
|
RUN apt-get install -y \
|
||||||
|
bash \
|
||||||
|
curl \
|
||||||
|
fonts-droid-fallback \
|
||||||
|
gdb \
|
||||||
|
git \
|
||||||
|
lib32stdc++6 \
|
||||||
|
libglu1-mesa \
|
||||||
|
libstdc++6 \
|
||||||
|
python3 \
|
||||||
|
unzip \
|
||||||
|
wget
|
||||||
|
RUN apt-get clean
|
||||||
|
|
||||||
|
RUN git clone https://github.com/flutter/flutter.git /flutter
|
||||||
|
RUN git config --system --add safe.directory /flutter
|
||||||
|
|
||||||
|
ENV PATH="/flutter/bin:/flutter/bin/cache/dart-sdk/bin:${PATH}"
|
||||||
|
|
||||||
|
RUN flutter doctor -v
|
||||||
|
RUN flutter channel master
|
||||||
|
RUN flutter upgrade
|
||||||
|
RUN flutter --disable-analytics
|
||||||
|
|
||||||
|
RUN flutter config --no-analytics
|
||||||
|
RUN flutter config --enable-web
|
||||||
|
RUN flutter config --no-cli-animations
|
||||||
|
|
||||||
|
RUN mkdir /nonexistent
|
||||||
|
RUN chown -R $UID:$GID /nonexistent
|
||||||
|
|
||||||
|
RUN mkdir /.config
|
||||||
|
RUN chown -R $UID:$GID /.config
|
||||||
|
|
||||||
|
RUN mkdir /.dart-tool
|
||||||
|
RUN chown -R $UID:$GID /.dart-tool
|
||||||
|
|
||||||
|
RUN mkdir /.pub-cache
|
||||||
|
RUN chown -R $UID:$GID /.pub-cache
|
||||||
|
|
||||||
|
RUN chown -R $UID:$GID /flutter
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#comment
|
#comment
|
||||||
FROM alpine:3.20.3
|
FROM alpine:3.22.2
|
||||||
|
|
||||||
RUN apk update
|
RUN apk update
|
||||||
RUN apk upgrade
|
RUN apk upgrade
|
||||||
@@ -12,12 +12,14 @@ RUN apk add \
|
|||||||
bzip2 \
|
bzip2 \
|
||||||
clang17-extra-tools \
|
clang17-extra-tools \
|
||||||
cmake \
|
cmake \
|
||||||
|
curl \
|
||||||
file \
|
file \
|
||||||
flex \
|
flex \
|
||||||
g++ \
|
g++ \
|
||||||
gcc \
|
gcc \
|
||||||
gettext \
|
gettext \
|
||||||
git \
|
git \
|
||||||
|
git-lfs \
|
||||||
gmp \
|
gmp \
|
||||||
gmp-dev \
|
gmp-dev \
|
||||||
gperf \
|
gperf \
|
||||||
@@ -42,6 +44,7 @@ RUN apk add \
|
|||||||
ruby \
|
ruby \
|
||||||
texinfo \
|
texinfo \
|
||||||
unzip \
|
unzip \
|
||||||
|
xvfb \
|
||||||
wget \
|
wget \
|
||||||
wine \
|
wine \
|
||||||
xz \
|
xz \
|
||||||
@@ -101,6 +104,39 @@ RUN echo -e \
|
|||||||
"system = 'windows'\n"\
|
"system = 'windows'\n"\
|
||||||
> ${MY_TOOLCHAIN_FILE_MESON}
|
> ${MY_TOOLCHAIN_FILE_MESON}
|
||||||
|
|
||||||
|
RUN mkdir -p /opt/bin;echo -e \
|
||||||
|
"#!/bin/sh\n"\
|
||||||
|
"COUNT=0\n"\
|
||||||
|
"echo \"Start waiting on \$@\"\n"\
|
||||||
|
"while pgrep \"\$@\" > /dev/null; do \n"\
|
||||||
|
" echo \"waiting ...\"\n"\
|
||||||
|
" sleep 1;\n"\
|
||||||
|
" COUNT=\$((COUNT+1))\n"\
|
||||||
|
" if [ \$COUNT -eq 60 ]; then\n"\
|
||||||
|
" exit 3;\n"\
|
||||||
|
" fi\n"\
|
||||||
|
"done\n"\
|
||||||
|
"echo \"\$@ completed\"\n"\
|
||||||
|
> /opt/bin/waitonprocess && \
|
||||||
|
chmod +x /opt/bin/waitonprocess && \
|
||||||
|
cat /opt/bin/waitonprocess
|
||||||
|
|
||||||
|
RUN echo -e \
|
||||||
|
"#!/bin/sh\n"\
|
||||||
|
"Xvfb \$DISPLAY &\n"\
|
||||||
|
"tokill=\$!\n"\
|
||||||
|
"wine wineboot --init\n"\
|
||||||
|
"waitonprocess wineserver\n"\
|
||||||
|
"\"\$@\"\n"\
|
||||||
|
"retval=\$?\n"\
|
||||||
|
"kill -15 \$tokill\n"\
|
||||||
|
"wine wineboot --shutdown\n"\
|
||||||
|
"return \$retval\n"\
|
||||||
|
> /opt/bin/wine-x11-run && \
|
||||||
|
chmod +x /opt/bin/wine-x11-run && \
|
||||||
|
cat /opt/bin/wine-x11-run
|
||||||
|
|
||||||
|
ENV PATH="/opt/bin:${PATH}"
|
||||||
SHELL [ "/bin/bash", "-c" ]
|
SHELL [ "/bin/bash", "-c" ]
|
||||||
|
|
||||||
RUN mkdir -p \
|
RUN mkdir -p \
|
||||||
@@ -350,9 +386,9 @@ RUN cd /3rd_party/mingw64 && sha256sum -c ./expat-${MY_EXPAT_VERSION}.tar.gz.sha
|
|||||||
|
|
||||||
ARG FONTCONFIG_VERSION
|
ARG FONTCONFIG_VERSION
|
||||||
ENV MY_FONTCONFIG_VERSION=${FONTCONFIG_VERSION}
|
ENV MY_FONTCONFIG_VERSION=${FONTCONFIG_VERSION}
|
||||||
RUN if [ -f "/3rd_party/fontconfig-${MY_FONTCONFIG_VERSION}.tar.gz" ]; then \
|
RUN if [ -f "/3rd_party/fontconfig-${MY_FONTCONFIG_VERSION}.tar.xz" ]; then \
|
||||||
cd /3rd_party && sha256sum -c ./fontconfig-${MY_FONTCONFIG_VERSION}.tar.gz.sha256 && cd - \
|
cd /3rd_party && sha256sum -c ./fontconfig-${MY_FONTCONFIG_VERSION}.tar.xz.sha256 && cd - \
|
||||||
&& tar xvzf /3rd_party/fontconfig-${MY_FONTCONFIG_VERSION}.tar.gz \
|
&& tar xvJf /3rd_party/fontconfig-${MY_FONTCONFIG_VERSION}.tar.xz \
|
||||||
&& cd fontconfig-${MY_FONTCONFIG_VERSION} \
|
&& cd fontconfig-${MY_FONTCONFIG_VERSION} \
|
||||||
&& meson setup \
|
&& meson setup \
|
||||||
--cross-file ${MY_TOOLCHAIN_FILE_MESON} \
|
--cross-file ${MY_TOOLCHAIN_FILE_MESON} \
|
||||||
@@ -671,12 +707,15 @@ RUN if [ -f "/3rd_party/curl-${MY_CURL_VERSION}.tar.gz" ]; then \
|
|||||||
&& cd build \
|
&& cd build \
|
||||||
&& cmake .. \
|
&& cmake .. \
|
||||||
-DBUILD_CURL_EXE=ON \
|
-DBUILD_CURL_EXE=ON \
|
||||||
|
-DBUILD_LIBCURL_DOCS=OFF \
|
||||||
|
-DBUILD_MISC_DOCS=OFF \
|
||||||
-DBUILD_SHARED_LIBS=OFF \
|
-DBUILD_SHARED_LIBS=OFF \
|
||||||
-DBUILD_STATIC_LIBS=ON \
|
-DBUILD_STATIC_LIBS=ON \
|
||||||
-DBUILD_TESTING=OFF \
|
-DBUILD_TESTING=OFF \
|
||||||
-DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
|
-DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
|
||||||
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
|
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
|
||||||
-DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
|
-DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
|
||||||
|
-DCURL_BROTLI=OFF \
|
||||||
-DCURL_CA_BUNDLE=./cacert.pem \
|
-DCURL_CA_BUNDLE=./cacert.pem \
|
||||||
-DCURL_CA_FALLBACK=ON \
|
-DCURL_CA_FALLBACK=ON \
|
||||||
-DCURL_DISABLE_LDAP=ON \
|
-DCURL_DISABLE_LDAP=ON \
|
||||||
@@ -684,6 +723,7 @@ RUN if [ -f "/3rd_party/curl-${MY_CURL_VERSION}.tar.gz" ]; then \
|
|||||||
-DCURL_USE_LIBSSH2=OFF \
|
-DCURL_USE_LIBSSH2=OFF \
|
||||||
-DCURL_USE_OPENSSL=ON \
|
-DCURL_USE_OPENSSL=ON \
|
||||||
-DCURL_ZLIB=ON \
|
-DCURL_ZLIB=ON \
|
||||||
|
-DENABLE_CURL_MANUAL=OFF \
|
||||||
-DENABLE_THREADED_RESOLVER=ON \
|
-DENABLE_THREADED_RESOLVER=ON \
|
||||||
-DOPENSSL_USE_STATIC_LIBS=ON \
|
-DOPENSSL_USE_STATIC_LIBS=ON \
|
||||||
-DUSE_LIBIDN2=OFF \
|
-DUSE_LIBIDN2=OFF \
|
||||||
@@ -706,11 +746,15 @@ RUN if [ -f "/3rd_party/cpp-httplib-${MY_CPP_HTTPLIB_VERSION}.tar.gz" ]; then \
|
|||||||
-DCMAKE_BUILD_TYPE=Release \
|
-DCMAKE_BUILD_TYPE=Release \
|
||||||
-DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
|
-DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
|
||||||
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
|
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
|
||||||
|
-DCMAKE_SYSTEM_VERSION="10.0.0" \
|
||||||
-DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
|
-DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
|
||||||
-DHTTPLIB_REQUIRE_BROTLI=OFF \
|
-DHTTPLIB_REQUIRE_BROTLI=OFF \
|
||||||
-DHTTPLIB_REQUIRE_OPENSSL=ON \
|
-DHTTPLIB_REQUIRE_OPENSSL=ON \
|
||||||
-DHTTPLIB_REQUIRE_ZLIB=ON \
|
-DHTTPLIB_REQUIRE_ZLIB=ON \
|
||||||
-DHTTPLIB_TEST=OFF \
|
-DHTTPLIB_TEST=OFF \
|
||||||
|
-DHTTPLIB_USE_BROTLI_IF_AVAILABLE=OFF \
|
||||||
|
-DHTTPLIB_USE_OPENSSL_IF_AVAILABLE=YES \
|
||||||
|
-DHTTPLIB_USE_ZLIB_IF_AVAILABLE=ON \
|
||||||
&& make -j${MY_NUM_JOBS} \
|
&& make -j${MY_NUM_JOBS} \
|
||||||
&& make install \
|
&& make install \
|
||||||
&& cd ${MY_WORKDIR} \
|
&& cd ${MY_WORKDIR} \
|
||||||
@@ -791,6 +835,7 @@ RUN if [ -f "/3rd_party/libevent-${MY_LIBEVENT_VERSION}-stable.tar.gz" ]; then \
|
|||||||
&& cmake .. \
|
&& cmake .. \
|
||||||
-DCMAKE_BUILD_TYPE=Release \
|
-DCMAKE_BUILD_TYPE=Release \
|
||||||
-DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
|
-DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
|
||||||
|
-DCMAKE_C_FLAGS="-include winsock2.h -include ws2tcpip.h -include iphlpapi.h" \
|
||||||
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
|
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
|
||||||
-DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
|
-DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
|
||||||
-DEVENT__DISABLE_OPENSSL=ON \
|
-DEVENT__DISABLE_OPENSSL=ON \
|
||||||
@@ -880,6 +925,7 @@ RUN if [ -f "/3rd_party/rocksdb-${MY_ROCKSDB_VERSION}.tar.gz" ]; then \
|
|||||||
-DROCKSDB_INSTALL_ON_WINDOWS=ON \
|
-DROCKSDB_INSTALL_ON_WINDOWS=ON \
|
||||||
-DWITH_BENCHMARK=OFF \
|
-DWITH_BENCHMARK=OFF \
|
||||||
-DWITH_BENCHMARK_TOOLS=OFF \
|
-DWITH_BENCHMARK_TOOLS=OFF \
|
||||||
|
-DWITH_BZ2=OFF \
|
||||||
-DWITH_CORE_TOOLS=OFF \
|
-DWITH_CORE_TOOLS=OFF \
|
||||||
-DWITH_EXAMPLES=OFF \
|
-DWITH_EXAMPLES=OFF \
|
||||||
-DWITH_GFLAGS=OFF \
|
-DWITH_GFLAGS=OFF \
|
||||||
@@ -1111,6 +1157,33 @@ RUN if [ -f "/3rd_party/libdsm-${MY_LIBDSM_VERSION}.tar.gz" ]; then \
|
|||||||
&& rm -r libdsm-${MY_LIBDSM_VERSION} \
|
&& rm -r libdsm-${MY_LIBDSM_VERSION} \
|
||||||
; fi
|
; fi
|
||||||
|
|
||||||
RUN (mv ${MY_MINGW_DIR}/lib/*.dll ${MY_MINGW_DIR}/bin || echo "no dll's found") \
|
ENV DISPLAY=:90
|
||||||
|
ENV WINEDEBUG=-all,err+all
|
||||||
|
|
||||||
|
ARG INNOSETUP_VERSION
|
||||||
|
ENV MY_INNOSETUP_VERSION=${INNOSETUP_VERSION}
|
||||||
|
RUN rm -rf /root/.wine; \
|
||||||
|
wine64 reg add 'HKEY_CURRENT_USER\Software\Wine' /v ShowDotFiles /d Y \
|
||||||
|
&& while [ ! -f /root/.wine/user.reg ]; do sleep 1; done; \
|
||||||
|
wine-x11-run wine64 /3rd_party/mingw64/innosetup-${MY_INNOSETUP_VERSION}.exe /SP- /VERYSILENT /ALLUSERS /SUPPRESSMSGBOXES /DOWNLOADISCRYPT=1
|
||||||
|
|
||||||
|
ARG UID=1000
|
||||||
|
ARG GID=1000
|
||||||
|
ARG USERNAME=myuser
|
||||||
|
|
||||||
|
RUN delgroup scanner || echo "no scanner group found"
|
||||||
|
|
||||||
|
RUN addgroup -g $GID $USERNAME && \
|
||||||
|
adduser -D -u $UID -G $USERNAME -h /home/$USERNAME $USERNAME
|
||||||
|
|
||||||
|
RUN rsync -av --progress /root/.wine/ /home/$USERNAME/.wine/ && \
|
||||||
|
chown -R $UID:$GID -R /home/$USERNAME/.wine/
|
||||||
|
|
||||||
|
RUN (cp ${MY_MINGW_DIR}/lib/*.dll ${MY_MINGW_DIR}/bin || echo "no dll's found") \
|
||||||
&& chmod 0777 -R ${MY_MINGW_DIR} \
|
&& chmod 0777 -R ${MY_MINGW_DIR} \
|
||||||
&& rm -rf /3rd_party
|
&& rm -rf /3rd_party \
|
||||||
|
&& rm -rf /root/.wine
|
||||||
|
|
||||||
|
USER $USERNAME
|
||||||
|
WORKDIR /home/$USERNAME
|
||||||
|
|
||||||
|
|||||||
@@ -8,3 +8,7 @@ rsync -av --progress ${CURRENT_DIR}/${PROJECT_NAME}/${PROJECT_NAME}_test/test_in
|
|||||||
|
|
||||||
rsync -av --progress ${CURRENT_DIR}/${PROJECT_NAME}/${PROJECT_NAME}_test/test_input/ \
|
rsync -av --progress ${CURRENT_DIR}/${PROJECT_NAME}/${PROJECT_NAME}_test/test_input/ \
|
||||||
${PROJECT_DIST_DIR}/test_input/
|
${PROJECT_DIST_DIR}/test_input/
|
||||||
|
|
||||||
|
rsync -av --progress ${CURRENT_DIR}/assets/icon.ico ${PROJECT_DIST_DIR}/icon.ico
|
||||||
|
|
||||||
|
rsync -av --progress ${CURRENT_DIR}/assets/blue/logo.iconset/icon_128x128.png ${PROJECT_DIST_DIR}/repertory.png
|
||||||
|
|||||||
@@ -3,5 +3,10 @@ set(CMAKE_CXX_FLAGS "-include common.hpp ${CMAKE_CXX_FLAGS}")
|
|||||||
add_project_library(lib${PROJECT_NAME} "" "" "${PROJECT_ADDITIONAL_SOURCES}")
|
add_project_library(lib${PROJECT_NAME} "" "" "${PROJECT_ADDITIONAL_SOURCES}")
|
||||||
|
|
||||||
add_project_executable(${PROJECT_NAME} lib${PROJECT_NAME} lib${PROJECT_NAME})
|
add_project_executable(${PROJECT_NAME} lib${PROJECT_NAME} lib${PROJECT_NAME})
|
||||||
|
if (PROJECT_IS_DARWIN AND EXISTS "${CMAKE_SOURCE_DIR}/${PROJECT_NAME}/Info.plist")
|
||||||
|
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||||
|
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/Info.plist
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
add_project_test_executable(${PROJECT_NAME}_test lib${PROJECT_NAME} lib${PROJECT_NAME})
|
add_project_test_executable(${PROJECT_NAME}_test lib${PROJECT_NAME} lib${PROJECT_NAME})
|
||||||
|
|||||||
23
repertory/Info.plist.in
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
|
||||||
|
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>@PROJECT_NAME@</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>@PROJECT_MACOS_BUNDLE_ID@</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>@PROJECT_NAME@</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>@PROJECT_MAJOR_VERSION@.@PROJECT_MINOR_VERSION@.@PROJECT_REVISION_VERSION@-@PROJECT_RELEASE_ITER@_@PROJECT_GIT_REV@</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>@PROJECT_MAJOR_VERSION@.@PROJECT_MINOR_VERSION@.@PROJECT_REVISION_VERSION@.@PROJECT_RELEASE_NUM@</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>APPL</string>
|
||||||
|
<key>LSUIElement</key>
|
||||||
|
<true />
|
||||||
|
<key>CFBundleIconFile</key>
|
||||||
|
<string>@PROJECT_MACOS_ICNS_NAME@</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
421
repertory/Install repertory.command
Normal file
@@ -0,0 +1,421 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# No `-e` (we tolerate benign non-zero returns); keep -Euo
|
||||||
|
set -Euo pipefail
|
||||||
|
|
||||||
|
LOG_DIR="/tmp"
|
||||||
|
LOG_FILE="${LOG_DIR}/Install-$(date +%Y%m%d-%H%M%S).log"
|
||||||
|
exec > >(tee -a "$LOG_FILE") 2>&1
|
||||||
|
echo "Logging to: $LOG_FILE"
|
||||||
|
|
||||||
|
TARGET_DIR="/Applications"
|
||||||
|
APP_NAME="repertory.app"
|
||||||
|
|
||||||
|
# Embedded at pack time (from CFBundleIdentifier prefix)
|
||||||
|
LABEL_PREFIX="__LABEL_PREFIX__"
|
||||||
|
UI_LABEL="${LABEL_PREFIX}.ui"
|
||||||
|
|
||||||
|
staged=""
|
||||||
|
backup=""
|
||||||
|
snapfile=""
|
||||||
|
skip_ui_launch=0
|
||||||
|
|
||||||
|
log() { printf "[%(%H:%M:%S)T] %s\n" -1 "$*"; }
|
||||||
|
warn() { log "WARN: $*"; }
|
||||||
|
die() {
|
||||||
|
log "ERROR: $*"
|
||||||
|
exit 2
|
||||||
|
}
|
||||||
|
|
||||||
|
here="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
|
||||||
|
# Locate source app on the DMG (supports hidden payload dirs)
|
||||||
|
src_app="${here}/${APP_NAME}"
|
||||||
|
if [[ ! -d "$src_app" ]]; then
|
||||||
|
src_app="$(/usr/bin/find "$here" -type d -name "$APP_NAME" -print -quit 2>/dev/null || true)"
|
||||||
|
fi
|
||||||
|
[[ -d "$src_app" ]] || die "Could not find ${APP_NAME} on this disk image."
|
||||||
|
|
||||||
|
app_basename="$(basename "$src_app")"
|
||||||
|
dest_app="${TARGET_DIR}/${APP_NAME}"
|
||||||
|
|
||||||
|
bundle_id_of() { /usr/bin/defaults read "$1/Contents/Info" CFBundleIdentifier 2>/dev/null || true; }
|
||||||
|
bundle_exec_of() { /usr/bin/defaults read "$1/Contents/Info" CFBundleExecutable 2>/dev/null || echo "${app_basename%.app}"; }
|
||||||
|
bundle_version_of() {
|
||||||
|
/usr/libexec/PlistBuddy -c 'Print :CFBundleShortVersionString' "$1/Contents/Info.plist" 2>/dev/null ||
|
||||||
|
/usr/bin/defaults read "$1/Contents/Info" CFBundleShortVersionString 2>/dev/null || echo "(unknown)"
|
||||||
|
}
|
||||||
|
bundle_build_of() {
|
||||||
|
/usr/libexec/PlistBuddy -c 'Print :CFBundleVersion' "$1/Contents/Info.plist" 2>/dev/null ||
|
||||||
|
/usr/bin/defaults read "$1/Contents/Info" CFBundleVersion 2>/dev/null || echo "(unknown)"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Require /Applications; prompt for sudo if needed; abort if cannot elevate
|
||||||
|
USE_SUDO=0
|
||||||
|
SUDO=""
|
||||||
|
ensure_target_writable() {
|
||||||
|
if mkdir -p "${TARGET_DIR}/.repertory_install_test.$$" 2>/dev/null; then
|
||||||
|
rmdir "${TARGET_DIR}/.repertory_install_test.$$" 2>/dev/null || true
|
||||||
|
USE_SUDO=0
|
||||||
|
SUDO=""
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if command -v sudo >/dev/null 2>&1; then
|
||||||
|
log "Elevating privileges to write to ${TARGET_DIR}…"
|
||||||
|
sudo -v || die "Administrator privileges required to install into ${TARGET_DIR}."
|
||||||
|
USE_SUDO=1
|
||||||
|
SUDO="sudo"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
die "Cannot write to ${TARGET_DIR} and sudo is unavailable."
|
||||||
|
}
|
||||||
|
|
||||||
|
# ----- STRICT LABEL PREFIX GATE (fail if invalid) -----
|
||||||
|
_is_valid_label_prefix() {
|
||||||
|
local p="${1:-}"
|
||||||
|
[[ -n "$p" ]] && [[ "$p" != "__LABEL_PREFIX__" ]] && [[ "$p" =~ ^[A-Za-z0-9._-]+$ ]] && [[ "$p" == *.* ]]
|
||||||
|
}
|
||||||
|
if ! _is_valid_label_prefix "${LABEL_PREFIX:-}"; then
|
||||||
|
die "Invalid LABEL_PREFIX in installer (value: \"${LABEL_PREFIX:-}\"). Rebuild the DMG so the installer contains a valid reverse-DNS prefix."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ----- LaunchServices helpers -----
|
||||||
|
ls_prune_bundle_id() {
|
||||||
|
local bundle_id="$1" keep_path="$2"
|
||||||
|
[[ -z "$bundle_id" ]] && return 0
|
||||||
|
local search_roots=("/Applications" "$HOME/Applications" "/Volumes")
|
||||||
|
if [[ -n "${here:-}" && "$here" == /Volumes/* ]]; then search_roots+=("$here"); fi
|
||||||
|
local candidates=""
|
||||||
|
for root in "${search_roots[@]}"; do
|
||||||
|
[[ -d "$root" ]] || continue
|
||||||
|
candidates+=$'\n'"$(/usr/bin/mdfind -onlyin "$root" "kMDItemCFBundleIdentifier == '${bundle_id}'" 2>/dev/null || true)"
|
||||||
|
done
|
||||||
|
# Include backups adjacent to keep_path (quote-safe)
|
||||||
|
local parent_dir="${keep_path%/*.app}"
|
||||||
|
candidates+=$'\n'$(/bin/ls -1d "${parent_dir}/"*.bak 2>/dev/null || true)
|
||||||
|
local LSREG="/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister"
|
||||||
|
printf "%s\n" "$candidates" | /usr/bin/awk 'NF' | /usr/bin/sort -u | while IFS= read -r p; do
|
||||||
|
[[ -z "$p" || ! -d "$p" || "$p" == "$keep_path" ]] && continue
|
||||||
|
log "Unregistering older LS entry for ${bundle_id}: $p"
|
||||||
|
"$LSREG" -u "$p" >/dev/null 2>&1 || true
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# ----- FUSE unmount (no process killing here) -----
|
||||||
|
is_mounted() { /sbin/mount | /usr/bin/awk '{print $3}' | /usr/bin/grep -Fx "${1:-}" >/dev/null 2>&1; }
|
||||||
|
_list_repertory_fuse_mounts() { /sbin/mount | /usr/bin/grep -Ei 'macfuse|osxfuse' | /usr/bin/awk '{print $3}' | /usr/bin/grep -i "repertory" || true; }
|
||||||
|
_unmount_one() {
|
||||||
|
local mnt="${1:-}"
|
||||||
|
[[ -n "$mnt" ]] || return 0
|
||||||
|
/usr/sbin/diskutil unmount "$mnt" >/dev/null 2>&1 || /sbin/umount "$mnt" >/dev/null 2>&1 || true
|
||||||
|
if is_mounted "$mnt"; then
|
||||||
|
/usr/sbin/diskutil unmount force "$mnt" >/dev/null 2>&1 || /sbin/umount -f "$mnt" >/dev/null 2>&1 || true
|
||||||
|
fi
|
||||||
|
for _ in {1..20}; do
|
||||||
|
is_mounted "$mnt" || return 0
|
||||||
|
sleep 0.25
|
||||||
|
done
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
unmount_existing_repertory_volumes() {
|
||||||
|
# Hard-fail on the first unmount problem.
|
||||||
|
while IFS= read -r mnt; do
|
||||||
|
[[ -z "$mnt" ]] && continue
|
||||||
|
log "Unmounting FUSE mount: $mnt"
|
||||||
|
if ! _unmount_one "$mnt"; then
|
||||||
|
warn "Failed to unmount $mnt"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
done < <(_list_repertory_fuse_mounts)
|
||||||
|
sync || true
|
||||||
|
sleep 0.3
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# ----- user LaunchAgents (by LABEL_PREFIX only) -----
|
||||||
|
get_plist_label() { /usr/bin/defaults read "$1" Label 2>/dev/null || /usr/libexec/PlistBuddy -c "Print :Label" "$1" 2>/dev/null || basename "$1" .plist; }
|
||||||
|
|
||||||
|
# Return the executable path a LaunchAgent runs (ProgramArguments[0] or Program).
|
||||||
|
# Echoes empty string if neither is present.
|
||||||
|
get_plist_exec_path() {
|
||||||
|
local plist="$1" arg0=""
|
||||||
|
# Prefer ProgramArguments[0]
|
||||||
|
arg0="$(/usr/libexec/PlistBuddy -c 'Print :ProgramArguments:0' "$plist" 2>/dev/null || true)"
|
||||||
|
if [[ -z "$arg0" ]]; then
|
||||||
|
# Fallback to Program (older style)
|
||||||
|
arg0="$(/usr/libexec/PlistBuddy -c 'Print :Program' "$plist" 2>/dev/null || true)"
|
||||||
|
fi
|
||||||
|
printf '%s\n' "$arg0"
|
||||||
|
}
|
||||||
|
|
||||||
|
snapshot_launchagents_user() {
|
||||||
|
local user_agents="$HOME/Library/LaunchAgents"
|
||||||
|
snapfile="$(/usr/bin/mktemp "/tmp/repertory_launchagents.XXXXXX")" || snapfile=""
|
||||||
|
if [[ -z "$snapfile" ]]; then
|
||||||
|
warn "Could not create temporary snapshot file; skipping LaunchAgent restart snapshot."
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
[[ -d "$user_agents" ]] || return 0
|
||||||
|
|
||||||
|
# We collect non-UI first, then UI last, to preserve restart order later.
|
||||||
|
local tmp_nonui tmp_ui
|
||||||
|
tmp_nonui="$(/usr/bin/mktemp "/tmp/repertory_launchagents.nonui.XXXXXX")" || tmp_nonui=""
|
||||||
|
tmp_ui="$(/usr/bin/mktemp "/tmp/repertory_launchagents.ui.XXXXXX")" || tmp_ui=""
|
||||||
|
|
||||||
|
/usr/bin/find "$user_agents" -maxdepth 1 -type f -name "${LABEL_PREFIX}"'*.plist' -print 2>/dev/null |
|
||||||
|
while IFS= read -r plist; do
|
||||||
|
[[ -z "$plist" ]] && continue
|
||||||
|
|
||||||
|
# Label must match the prefix
|
||||||
|
local label
|
||||||
|
label="$(get_plist_label "$plist")"
|
||||||
|
[[ -n "$label" && "$label" == "${LABEL_PREFIX}"* ]] || continue
|
||||||
|
|
||||||
|
# Executable must point into the *installed* app path
|
||||||
|
local exec_path
|
||||||
|
exec_path="$(get_plist_exec_path "$plist")"
|
||||||
|
[[ -n "$exec_path" ]] || continue
|
||||||
|
# Normalize: only accept absolute paths under $dest_app (e.g. .../repertory.app/Contents/...)
|
||||||
|
if [[ "$exec_path" != "$dest_app/"* ]]; then
|
||||||
|
# Not one of ours; skip
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Defer UI label to the end
|
||||||
|
if [[ "$label" == "$UI_LABEL" ]]; then
|
||||||
|
[[ -n "$tmp_ui" ]] && printf "%s\t%s\n" "$plist" "$label" >>"$tmp_ui"
|
||||||
|
else
|
||||||
|
[[ -n "$tmp_nonui" ]] && printf "%s\t%s\n" "$plist" "$label" >>"$tmp_nonui"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Stitch together: non-UI first, then UI
|
||||||
|
[[ -s "$tmp_nonui" ]] && /bin/cat "$tmp_nonui" >>"$snapfile"
|
||||||
|
[[ -s "$tmp_ui" ]] && /bin/cat "$tmp_ui" >>"$snapfile"
|
||||||
|
|
||||||
|
[[ -n "$tmp_nonui" ]] && /bin/rm -f "$tmp_nonui" 2>/dev/null || true
|
||||||
|
[[ -n "$tmp_ui" ]] && /bin/rm -f "$tmp_ui" 2>/dev/null || true
|
||||||
|
|
||||||
|
log "Snapshot contains $(/usr/bin/wc -l <"$snapfile" 2>/dev/null || echo 0) LaunchAgent(s)."
|
||||||
|
}
|
||||||
|
|
||||||
|
unload_launchd_helpers_user() {
|
||||||
|
local uid user_agents
|
||||||
|
uid="$(id -u)"
|
||||||
|
user_agents="$HOME/Library/LaunchAgents"
|
||||||
|
[[ -d "$user_agents" ]] || return 0
|
||||||
|
|
||||||
|
while IFS= read -r plist; do
|
||||||
|
[[ -z "$plist" ]] && continue
|
||||||
|
local base label
|
||||||
|
base="$(basename "$plist")"
|
||||||
|
[[ "$base" == "${LABEL_PREFIX}"* ]] || continue
|
||||||
|
label="$(get_plist_label "$plist")"
|
||||||
|
[[ -n "$label" && "$label" == "${LABEL_PREFIX}"* ]] || continue
|
||||||
|
log "Booting out user label ${label} (${plist})"
|
||||||
|
/bin/launchctl bootout "gui/${uid}" "$plist" 2>/dev/null ||
|
||||||
|
/bin/launchctl bootout "gui/${uid}" "$label" 2>/dev/null ||
|
||||||
|
/bin/launchctl remove "$label" 2>/dev/null || true
|
||||||
|
done < <(/usr/bin/find "$user_agents" -maxdepth 1 -type f -name "${LABEL_PREFIX}"'*.plist' -print 2>/dev/null)
|
||||||
|
|
||||||
|
/bin/launchctl list 2>/dev/null | /usr/bin/awk -v pre="$LABEL_PREFIX" 'NF>=3 && index($3, pre)==1 {print $3}' |
|
||||||
|
while read -r lbl; do
|
||||||
|
[[ -z "$lbl" ]] && continue
|
||||||
|
log "Booting out leftover user label: $lbl"
|
||||||
|
/bin/launchctl bootout "gui/${uid}" "$lbl" 2>/dev/null || /bin/launchctl remove "$lbl" 2>/dev/null || true
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
restart_launchagents_from_snapshot() {
|
||||||
|
[[ -n "${snapfile:-}" && -f "${snapfile}" ]] || return 0
|
||||||
|
|
||||||
|
local uid count=0 ui_seen=0
|
||||||
|
uid="$(id -u)"
|
||||||
|
|
||||||
|
# Pass 1: restart all non-UI agents first
|
||||||
|
while IFS=$'\t' read -r plist label; do
|
||||||
|
[[ -n "$plist" && -n "$label" ]] || continue
|
||||||
|
[[ -f "$plist" ]] || continue
|
||||||
|
[[ "$label" == "$UI_LABEL" ]] && continue
|
||||||
|
|
||||||
|
log "Re-starting LaunchAgent: ${label}"
|
||||||
|
/bin/launchctl bootstrap "gui/${uid}" "$plist" 2>/dev/null || true
|
||||||
|
/bin/launchctl kickstart -k "gui/${uid}/${label}" 2>/dev/null || true
|
||||||
|
((count++)) || true
|
||||||
|
done <"$snapfile"
|
||||||
|
|
||||||
|
# Give helpers a moment to settle (e.g., automounts)
|
||||||
|
sleep 0.3
|
||||||
|
|
||||||
|
# Pass 2: restart the UI agent last (if present in the snapshot)
|
||||||
|
while IFS=$'\t' read -r plist label; do
|
||||||
|
[[ -n "$plist" && -n "$label" ]] || continue
|
||||||
|
[[ -f "$plist" ]] || continue
|
||||||
|
[[ "$label" == "$UI_LABEL" ]] || continue
|
||||||
|
|
||||||
|
log "Re-starting UI LaunchAgent last: ${label}"
|
||||||
|
/bin/launchctl bootstrap "gui/${uid}" "$plist" 2>/dev/null || true
|
||||||
|
/bin/launchctl kickstart -k "gui/${uid}/${label}" 2>/dev/null || true
|
||||||
|
ui_seen=1
|
||||||
|
((count++)) || true
|
||||||
|
done <"$snapfile"
|
||||||
|
|
||||||
|
log "Re-started ${count} LaunchAgent(s) with prefix ${LABEL_PREFIX}." || true
|
||||||
|
|
||||||
|
if ((ui_seen)); then
|
||||||
|
# If the UI label is active, skip manual open(1).
|
||||||
|
if /bin/launchctl list | /usr/bin/awk '{print $3}' | /usr/bin/grep -Fxq "$UI_LABEL"; then
|
||||||
|
log "UI LaunchAgent (${UI_LABEL}) active after restart; skipping manual UI launch."
|
||||||
|
skip_ui_launch=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# ----- quarantine helper -----
|
||||||
|
remove_quarantine() {
|
||||||
|
local path="${1:-}"
|
||||||
|
if [[ "${USE_SUDO:-0}" == "1" ]]; then
|
||||||
|
sudo /usr/bin/xattr -dr com.apple.quarantine "$path" 2>/dev/null || true
|
||||||
|
else
|
||||||
|
/usr/bin/xattr -dr com.apple.quarantine "$path" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# ----- process helpers -----
|
||||||
|
kill_repertory_processes() {
|
||||||
|
local exec_name="$1"
|
||||||
|
/usr/bin/pkill -TERM -f "$dest_app" >/dev/null 2>&1 || true
|
||||||
|
/usr/bin/pkill -TERM -x "$exec_name" >/dev/null 2>&1 || true
|
||||||
|
for _ in {1..20}; do
|
||||||
|
/usr/bin/pgrep -af "$dest_app" >/dev/null 2>&1 || /usr/bin/pgrep -x "$exec_name" >/dev/null 2>&1 || break
|
||||||
|
sleep 0.1
|
||||||
|
done
|
||||||
|
/usr/bin/pkill -KILL -f "$dest_app" >/dev/null 2>&1 || true
|
||||||
|
/usr/bin/pkill -KILL -x "$exec_name" >/dev/null 2>&1 || true
|
||||||
|
}
|
||||||
|
|
||||||
|
# ----- visibility helper -----
|
||||||
|
unhide_path() {
|
||||||
|
local path="$1"
|
||||||
|
/usr/bin/chflags -R nohidden "$path" 2>/dev/null || true
|
||||||
|
/usr/bin/xattr -d -r com.apple.FinderInfo "$path" 2>/dev/null || true
|
||||||
|
}
|
||||||
|
|
||||||
|
# ----- stage / validate / activate / post-activate -----
|
||||||
|
stage_new_app() {
|
||||||
|
staged="${dest_app}.new-$$"
|
||||||
|
log "Staging new app → $staged"
|
||||||
|
$SUDO /usr/bin/ditto "$src_app" "$staged" || die "ditto to stage failed"
|
||||||
|
remove_quarantine "$staged"
|
||||||
|
}
|
||||||
|
|
||||||
|
validate_staged_app() {
|
||||||
|
[[ -f "$staged/Contents/Info.plist" ]] || {
|
||||||
|
$SUDO /bin/rm -rf "$staged"
|
||||||
|
die "staged app missing Info.plist"
|
||||||
|
}
|
||||||
|
local exe_name_staged
|
||||||
|
exe_name_staged="$(/usr/bin/defaults read "$staged/Contents/Info" CFBundleExecutable 2>/dev/null || echo "${app_basename%.app}")"
|
||||||
|
[[ -x "$staged/Contents/MacOS/$exe_name_staged" ]] || {
|
||||||
|
$SUDO /bin/rm -rf "$staged"
|
||||||
|
die "staged app missing main executable"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
activate_staged_app() {
|
||||||
|
if [[ -d "$dest_app" ]]; then
|
||||||
|
backup="${dest_app}.$(date +%Y%m%d%H%M%S).bak"
|
||||||
|
log "Moving existing app to backup: $backup"
|
||||||
|
$SUDO /bin/mv "$dest_app" "$backup" || {
|
||||||
|
$SUDO /bin/rm -rf "$staged"
|
||||||
|
die "failed to move existing app out of the way"
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
log "Activating new app → $dest_app"
|
||||||
|
if ! $SUDO /bin/mv "$staged" "$dest_app"; then
|
||||||
|
warn "Activation failed; attempting rollback…"
|
||||||
|
[[ -n "$backup" && -d "$backup" ]] && $SUDO /bin/mv "$backup" "$dest_app" || true
|
||||||
|
$SUDO /bin/rm -rf "$staged" || true
|
||||||
|
die "install activation failed"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
post_activate_cleanup() {
|
||||||
|
log "Clearing quarantine on installed app…"
|
||||||
|
remove_quarantine "$dest_app"
|
||||||
|
log "Clearing hidden flags on installed app…"
|
||||||
|
unhide_path "$dest_app"
|
||||||
|
|
||||||
|
local LSREG="/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister"
|
||||||
|
[[ -x "$LSREG" ]] && "$LSREG" -f "$dest_app" >/dev/null 2>&1 || true
|
||||||
|
local BID
|
||||||
|
BID="$(bundle_id_of "$dest_app")"
|
||||||
|
ls_prune_bundle_id "$BID" "$dest_app"
|
||||||
|
|
||||||
|
log "Installed ${app_basename}: version=$(bundle_version_of "$dest_app") build=$(bundle_build_of "$dest_app")"
|
||||||
|
}
|
||||||
|
|
||||||
|
launch_ui() {
|
||||||
|
log "Launching the new app…"
|
||||||
|
/usr/bin/open -n "$dest_app" || warn "open -n by path failed; not falling back to -b to avoid launching a stale copy."
|
||||||
|
}
|
||||||
|
|
||||||
|
remove_backup() {
|
||||||
|
[[ -n "$backup" && -d "$backup" ]] && {
|
||||||
|
log "Removing backup: $backup"
|
||||||
|
$SUDO /bin/rm -rf "$backup" || warn "Could not remove backup (safe to delete manually): $backup"
|
||||||
|
}
|
||||||
|
log "Done."
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup_staged() {
|
||||||
|
if [[ -n "${staged:-}" && -d "${staged}" ]]; then
|
||||||
|
log "Cleaning up staged folder: ${staged}"
|
||||||
|
if [[ "${USE_SUDO:-0}" == "1" ]]; then
|
||||||
|
sudo /bin/rm -rf "${staged}" 2>/dev/null || true
|
||||||
|
else
|
||||||
|
/bin/rm -rf "${staged}" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [[ -n "${snapfile:-}" && -f "${snapfile}" ]]; then
|
||||||
|
/bin/rm -f "${snapfile}" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
ensure_target_writable
|
||||||
|
|
||||||
|
local exec_name
|
||||||
|
exec_name="$(bundle_exec_of "$src_app")"
|
||||||
|
|
||||||
|
# 1) Snapshot agents we'll restart later
|
||||||
|
snapshot_launchagents_user
|
||||||
|
|
||||||
|
# 2) Hard-fail if any FUSE unmount fails
|
||||||
|
unmount_existing_repertory_volumes || die "One or more FUSE mounts resisted unmount."
|
||||||
|
|
||||||
|
# 3) Stop user LaunchAgents (do NOT delete plists)
|
||||||
|
unload_launchd_helpers_user
|
||||||
|
|
||||||
|
# 4) Kill any remaining repertory processes
|
||||||
|
kill_repertory_processes "$exec_name"
|
||||||
|
|
||||||
|
# 5) Stage → validate → activate → post-activate
|
||||||
|
stage_new_app
|
||||||
|
validate_staged_app
|
||||||
|
activate_staged_app
|
||||||
|
post_activate_cleanup
|
||||||
|
|
||||||
|
# 6) Re-start previously-running LaunchAgents (so automount helpers come up)
|
||||||
|
restart_launchagents_from_snapshot
|
||||||
|
|
||||||
|
# 7) If UI LaunchAgent came back, skip manual launch
|
||||||
|
if ((!skip_ui_launch)); then
|
||||||
|
launch_ui
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 8) Remove backup now that everything is good
|
||||||
|
remove_backup
|
||||||
|
}
|
||||||
|
|
||||||
|
trap 'rc=$?; cleanup_staged; if (( rc != 0 )); then echo "Installer failed with code $rc. See $LOG_FILE"; fi' EXIT
|
||||||
|
main "$@"
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
Copyright <2018-2025> <scott.e.graves@protonmail.com>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -22,36 +22,42 @@
|
|||||||
#ifndef REPERTORY_INCLUDE_APP_CONFIG_HPP_
|
#ifndef REPERTORY_INCLUDE_APP_CONFIG_HPP_
|
||||||
#define REPERTORY_INCLUDE_APP_CONFIG_HPP_
|
#define REPERTORY_INCLUDE_APP_CONFIG_HPP_
|
||||||
|
|
||||||
#include "events/event.hpp"
|
|
||||||
#include "types/remote.hpp"
|
#include "types/remote.hpp"
|
||||||
#include "types/repertory.hpp"
|
#include "types/repertory.hpp"
|
||||||
|
|
||||||
namespace repertory {
|
namespace repertory {
|
||||||
class app_config final {
|
class app_config final {
|
||||||
public:
|
private:
|
||||||
[[nodiscard]] static auto
|
static stop_type stop_requested;
|
||||||
default_agent_name(const provider_type &prov) -> std::string;
|
|
||||||
|
|
||||||
[[nodiscard]] static auto
|
|
||||||
default_api_port(const provider_type &prov) -> std::uint16_t;
|
|
||||||
|
|
||||||
[[nodiscard]] static auto
|
|
||||||
default_data_directory(const provider_type &prov) -> std::string;
|
|
||||||
|
|
||||||
[[nodiscard]] static auto
|
|
||||||
default_remote_api_port(const provider_type &prov) -> std::uint16_t;
|
|
||||||
|
|
||||||
[[nodiscard]] static auto
|
|
||||||
default_rpc_port(const provider_type &prov) -> std::uint16_t;
|
|
||||||
|
|
||||||
[[nodiscard]] static auto
|
|
||||||
get_provider_display_name(const provider_type &prov) -> std::string;
|
|
||||||
|
|
||||||
[[nodiscard]] static auto
|
|
||||||
get_provider_name(const provider_type &prov) -> std::string;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
app_config(const provider_type &prov, std::string_view data_directory = "");
|
[[nodiscard]] static auto default_agent_name(provider_type prov)
|
||||||
|
-> std::string;
|
||||||
|
|
||||||
|
[[nodiscard]] static auto default_api_port(provider_type prov)
|
||||||
|
-> std::uint16_t;
|
||||||
|
|
||||||
|
[[nodiscard]] static auto default_data_directory(provider_type prov)
|
||||||
|
-> std::string;
|
||||||
|
|
||||||
|
[[nodiscard]] static auto default_remote_api_port(provider_type prov)
|
||||||
|
-> std::uint16_t;
|
||||||
|
|
||||||
|
[[nodiscard]] static auto get_provider_display_name(provider_type prov)
|
||||||
|
-> std::string;
|
||||||
|
|
||||||
|
[[nodiscard]] static auto get_provider_name(provider_type prov)
|
||||||
|
-> std::string;
|
||||||
|
|
||||||
|
[[nodiscard]] static auto get_root_data_directory() -> std::string;
|
||||||
|
|
||||||
|
public:
|
||||||
|
[[nodiscard]] static auto get_stop_requested() -> bool;
|
||||||
|
|
||||||
|
static void set_stop_requested();
|
||||||
|
|
||||||
|
public:
|
||||||
|
app_config(provider_type prov, std::string_view data_directory);
|
||||||
|
|
||||||
app_config() = delete;
|
app_config() = delete;
|
||||||
app_config(app_config &&) = delete;
|
app_config(app_config &&) = delete;
|
||||||
@@ -64,10 +70,12 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
provider_type prov_;
|
provider_type prov_;
|
||||||
atomic<std::string> api_auth_;
|
utils::atomic<std::string> api_password_;
|
||||||
std::atomic<std::uint16_t> api_port_;
|
std::atomic<std::uint16_t> api_port_;
|
||||||
atomic<std::string> api_user_;
|
utils::atomic<std::string> api_user_;
|
||||||
|
std::string cache_directory_;
|
||||||
std::atomic<bool> config_changed_;
|
std::atomic<bool> config_changed_;
|
||||||
|
std::string data_directory_;
|
||||||
std::atomic<database_type> db_type_{database_type::rocksdb};
|
std::atomic<database_type> db_type_{database_type::rocksdb};
|
||||||
std::atomic<std::uint8_t> download_timeout_secs_;
|
std::atomic<std::uint8_t> download_timeout_secs_;
|
||||||
std::atomic<bool> enable_download_timeout_;
|
std::atomic<bool> enable_download_timeout_;
|
||||||
@@ -79,32 +87,28 @@ private:
|
|||||||
std::atomic<std::uint32_t> eviction_delay_mins_;
|
std::atomic<std::uint32_t> eviction_delay_mins_;
|
||||||
std::atomic<bool> eviction_uses_accessed_time_;
|
std::atomic<bool> eviction_uses_accessed_time_;
|
||||||
std::atomic<std::uint16_t> high_freq_interval_secs_;
|
std::atomic<std::uint16_t> high_freq_interval_secs_;
|
||||||
|
std::string log_directory_;
|
||||||
std::atomic<std::uint16_t> low_freq_interval_secs_;
|
std::atomic<std::uint16_t> low_freq_interval_secs_;
|
||||||
std::atomic<std::uint64_t> max_cache_size_bytes_;
|
std::atomic<std::uint64_t> max_cache_size_bytes_;
|
||||||
std::atomic<std::uint8_t> max_upload_count_;
|
std::atomic<std::uint8_t> max_upload_count_;
|
||||||
std::atomic<std::uint16_t> med_freq_interval_secs_;
|
std::atomic<std::uint16_t> med_freq_interval_secs_;
|
||||||
std::atomic<std::uint16_t> online_check_retry_secs_;
|
std::atomic<std::uint16_t> online_check_retry_secs_;
|
||||||
std::atomic<std::uint16_t> orphaned_file_retention_days_;
|
|
||||||
std::atomic<download_type> preferred_download_type_;
|
std::atomic<download_type> preferred_download_type_;
|
||||||
std::atomic<std::uint16_t> retry_read_count_;
|
std::atomic<std::uint16_t> retry_read_count_;
|
||||||
std::atomic<std::uint16_t> ring_buffer_file_size_;
|
std::atomic<std::uint16_t> ring_buffer_file_size_;
|
||||||
std::atomic<std::uint16_t> task_wait_ms_;
|
std::atomic<std::uint16_t> task_wait_ms_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string cache_directory_;
|
utils::atomic<encrypt_config> encrypt_config_;
|
||||||
std::string data_directory_;
|
utils::atomic<host_config> host_config_;
|
||||||
atomic<encrypt_config> encrypt_config_;
|
|
||||||
atomic<host_config> host_config_;
|
|
||||||
std::string log_directory_;
|
|
||||||
mutable std::recursive_mutex read_write_mutex_;
|
mutable std::recursive_mutex read_write_mutex_;
|
||||||
atomic<remote::remote_config> remote_config_;
|
utils::atomic<remote::remote_config> remote_config_;
|
||||||
atomic<remote::remote_mount> remote_mount_;
|
utils::atomic<remote::remote_mount> remote_mount_;
|
||||||
atomic<s3_config> s3_config_;
|
utils::atomic<s3_config> s3_config_;
|
||||||
atomic<sia_config> sia_config_;
|
utils::atomic<sia_config> sia_config_;
|
||||||
std::unordered_map<std::string, std::function<std::string()>>
|
std::unordered_map<std::string, std::function<std::string()>>
|
||||||
value_get_lookup_;
|
value_get_lookup_;
|
||||||
std::unordered_map<std::string,
|
std::unordered_map<std::string, std::function<std::string(std::string_view)>>
|
||||||
std::function<std::string(const std::string &)>>
|
|
||||||
value_set_lookup_;
|
value_set_lookup_;
|
||||||
std::uint64_t version_{REPERTORY_CONFIG_VERSION};
|
std::uint64_t version_{REPERTORY_CONFIG_VERSION};
|
||||||
|
|
||||||
@@ -114,8 +118,10 @@ 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 set_value(utils::atomic<std::string> &dst, std::string_view src) -> bool;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
[[nodiscard]] auto get_api_auth() const -> std::string;
|
[[nodiscard]] auto get_api_password() const -> std::string;
|
||||||
|
|
||||||
[[nodiscard]] auto get_api_port() const -> std::uint16_t;
|
[[nodiscard]] auto get_api_port() const -> std::uint16_t;
|
||||||
|
|
||||||
@@ -165,8 +171,6 @@ public:
|
|||||||
|
|
||||||
[[nodiscard]] auto get_online_check_retry_secs() const -> std::uint16_t;
|
[[nodiscard]] auto get_online_check_retry_secs() const -> std::uint16_t;
|
||||||
|
|
||||||
[[nodiscard]] auto get_orphaned_file_retention_days() const -> std::uint16_t;
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_preferred_download_type() const -> download_type;
|
[[nodiscard]] auto get_preferred_download_type() const -> download_type;
|
||||||
|
|
||||||
[[nodiscard]] auto get_provider_type() const -> provider_type;
|
[[nodiscard]] auto get_provider_type() const -> provider_type;
|
||||||
@@ -185,18 +189,21 @@ public:
|
|||||||
|
|
||||||
[[nodiscard]] auto get_task_wait_ms() const -> std::uint16_t;
|
[[nodiscard]] auto get_task_wait_ms() const -> std::uint16_t;
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto get_value_by_name(std::string_view name) const
|
||||||
get_value_by_name(const std::string &name) const -> std::string;
|
-> std::string;
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_raw_value_by_name(std::string_view name) const
|
||||||
|
-> std::string;
|
||||||
|
|
||||||
[[nodiscard]] auto get_version() const -> std::uint64_t;
|
[[nodiscard]] auto get_version() const -> std::uint64_t;
|
||||||
|
|
||||||
void save();
|
void save();
|
||||||
|
|
||||||
void set_api_auth(const std::string &value);
|
void set_api_password(std::string_view value);
|
||||||
|
|
||||||
void set_api_port(std::uint16_t value);
|
void set_api_port(std::uint16_t value);
|
||||||
|
|
||||||
void set_api_user(const std::string &value);
|
void set_api_user(std::string_view value);
|
||||||
|
|
||||||
void set_download_timeout_secs(std::uint8_t value);
|
void set_download_timeout_secs(std::uint8_t value);
|
||||||
|
|
||||||
@@ -232,8 +239,6 @@ public:
|
|||||||
|
|
||||||
void set_online_check_retry_secs(std::uint16_t value);
|
void set_online_check_retry_secs(std::uint16_t value);
|
||||||
|
|
||||||
void set_orphaned_file_retention_days(std::uint16_t value);
|
|
||||||
|
|
||||||
void set_preferred_download_type(const download_type &value);
|
void set_preferred_download_type(const download_type &value);
|
||||||
|
|
||||||
void set_remote_config(remote::remote_config value);
|
void set_remote_config(remote::remote_config value);
|
||||||
@@ -250,8 +255,8 @@ public:
|
|||||||
|
|
||||||
void set_task_wait_ms(std::uint16_t value);
|
void set_task_wait_ms(std::uint16_t value);
|
||||||
|
|
||||||
[[nodiscard]] auto set_value_by_name(const std::string &name,
|
[[nodiscard]] auto set_value_by_name(std::string_view name,
|
||||||
const std::string &value) -> std::string;
|
std::string_view value) -> std::string;
|
||||||
};
|
};
|
||||||
} // namespace repertory
|
} // namespace repertory
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
Copyright <2018-2025> <scott.e.graves@protonmail.com>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -22,10 +22,12 @@
|
|||||||
#ifndef REPERTORY_INCLUDE_COMM_CURL_CURL_COMM_HPP_
|
#ifndef REPERTORY_INCLUDE_COMM_CURL_CURL_COMM_HPP_
|
||||||
#define REPERTORY_INCLUDE_COMM_CURL_CURL_COMM_HPP_
|
#define REPERTORY_INCLUDE_COMM_CURL_CURL_COMM_HPP_
|
||||||
|
|
||||||
|
#include "app_config.hpp"
|
||||||
|
#include "comm/curl/curl_shared.hpp"
|
||||||
#include "comm/curl/multi_request.hpp"
|
#include "comm/curl/multi_request.hpp"
|
||||||
#include "comm/i_http_comm.hpp"
|
#include "comm/i_http_comm.hpp"
|
||||||
#include "events/event_system.hpp"
|
#include "events/event_system.hpp"
|
||||||
#include "events/events.hpp"
|
#include "events/types/curl_error.hpp"
|
||||||
#include "utils/encryption.hpp"
|
#include "utils/encryption.hpp"
|
||||||
|
|
||||||
namespace repertory {
|
namespace repertory {
|
||||||
@@ -41,42 +43,40 @@ private:
|
|||||||
using write_callback = size_t (*)(char *, size_t, size_t, void *);
|
using write_callback = size_t (*)(char *, size_t, size_t, void *);
|
||||||
|
|
||||||
struct read_write_info final {
|
struct read_write_info final {
|
||||||
data_buffer data{};
|
data_buffer data;
|
||||||
stop_type &stop_requested;
|
stop_type_callback stop_requested_cb;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const write_callback write_data;
|
static const write_callback write_data;
|
||||||
static const write_callback write_headers;
|
static const write_callback write_headers;
|
||||||
|
static constexpr std::uint8_t retry_request_count{5U};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::optional<host_config> host_config_;
|
std::optional<host_config> host_config_;
|
||||||
std::optional<s3_config> s3_config_;
|
std::optional<s3_config> s3_config_;
|
||||||
|
|
||||||
private:
|
|
||||||
bool use_s3_path_style_{false};
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
[[nodiscard]] static auto create_curl() -> CURL *;
|
[[nodiscard]] static auto create_curl() -> CURL *;
|
||||||
|
|
||||||
[[nodiscard]] static auto reset_curl(CURL *curl_handle) -> CURL *;
|
[[nodiscard]] static auto reset_curl(CURL *curl_handle) -> CURL *;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
[[nodiscard]] static auto
|
[[nodiscard]] static auto construct_url(CURL *curl,
|
||||||
construct_url(CURL *curl, const std::string &relative_path,
|
std::string_view relative_path,
|
||||||
const host_config &cfg) -> std::string;
|
const host_config &cfg)
|
||||||
|
-> std::string;
|
||||||
|
|
||||||
[[nodiscard]] static auto
|
[[nodiscard]] static auto create_host_config(const s3_config &cfg)
|
||||||
create_host_config(const s3_config &cfg,
|
-> host_config;
|
||||||
bool use_s3_path_style) -> host_config;
|
|
||||||
|
|
||||||
[[nodiscard]] static auto url_encode(CURL *curl, const std::string &data,
|
[[nodiscard]] static auto url_encode(CURL *curl, std::string_view data,
|
||||||
bool allow_slash) -> std::string;
|
bool allow_slash) -> std::string;
|
||||||
|
|
||||||
template <typename request_type>
|
template <typename request_type>
|
||||||
[[nodiscard]] static auto
|
[[nodiscard]] static auto
|
||||||
make_encrypted_request(const host_config &cfg, const request_type &request,
|
make_encrypted_request(const host_config &cfg, const request_type &request,
|
||||||
long &response_code,
|
long &response_code, stop_type &stop_requested)
|
||||||
stop_type &stop_requested) -> bool {
|
-> bool {
|
||||||
response_code = 0;
|
response_code = 0;
|
||||||
|
|
||||||
if (not request.decryption_token.has_value() ||
|
if (not request.decryption_token.has_value() ||
|
||||||
@@ -93,19 +93,19 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
data_buffer data{};
|
data_buffer data{};
|
||||||
const auto key =
|
const auto key = utils::encryption::generate_key<utils::hash::hash_256_t>(
|
||||||
utils::encryption::generate_key<utils::encryption::hash_256_t>(
|
request.decryption_token.value());
|
||||||
request.decryption_token.value());
|
|
||||||
if (not utils::encryption::read_encrypted_range(
|
if (not utils::encryption::read_encrypted_range(
|
||||||
request.range.value(), key,
|
request.range.value(), key,
|
||||||
[&](data_buffer &ct, std::uint64_t start_offset,
|
[&](data_buffer &buffer, std::uint64_t start_offset,
|
||||||
std::uint64_t end_offset) -> bool {
|
std::uint64_t end_offset) -> bool {
|
||||||
auto encrypted_request = request;
|
auto encrypted_request = request;
|
||||||
encrypted_request.decryption_token = std::nullopt;
|
encrypted_request.decryption_token = std::nullopt;
|
||||||
encrypted_request.range = {{start_offset, end_offset}};
|
encrypted_request.range = {{start_offset, end_offset}};
|
||||||
encrypted_request.response_handler =
|
encrypted_request.response_handler =
|
||||||
[&ct](const auto &encrypted_data, long /*response_code*/) {
|
[&buffer](const auto &encrypted_data,
|
||||||
ct = encrypted_data;
|
long /*response_code*/) {
|
||||||
|
buffer = encrypted_data;
|
||||||
};
|
};
|
||||||
encrypted_request.total_size = std::nullopt;
|
encrypted_request.total_size = std::nullopt;
|
||||||
|
|
||||||
@@ -114,7 +114,7 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response_code != 200) {
|
if (response_code != http_error_codes::ok) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,106 +135,154 @@ public:
|
|||||||
[[nodiscard]] static auto
|
[[nodiscard]] static auto
|
||||||
make_request(const host_config &cfg, 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() &&
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
not request.decryption_token.value().empty()) {
|
|
||||||
return make_encrypted_request(cfg, request, response_code,
|
|
||||||
stop_requested);
|
|
||||||
}
|
|
||||||
|
|
||||||
response_code = 0;
|
|
||||||
|
|
||||||
auto *curl = create_curl();
|
|
||||||
if (not request.set_method(curl, stop_requested)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (not cfg.agent_string.empty()) {
|
|
||||||
curl_easy_setopt(curl, CURLOPT_USERAGENT, cfg.agent_string.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (request.allow_timeout && cfg.timeout_ms) {
|
|
||||||
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, cfg.timeout_ms);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string range_list{};
|
|
||||||
if (request.range.has_value()) {
|
|
||||||
range_list = std::to_string(request.range.value().begin) + '-' +
|
|
||||||
std::to_string(request.range.value().end);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_RANGE, range_list.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (request.response_headers.has_value()) {
|
|
||||||
curl_easy_setopt(curl, CURLOPT_HEADERDATA,
|
|
||||||
&request.response_headers.value());
|
|
||||||
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, write_headers);
|
|
||||||
}
|
|
||||||
|
|
||||||
read_write_info write_info{{}, stop_requested};
|
|
||||||
if (request.response_handler.has_value()) {
|
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &write_info);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string parameters{};
|
|
||||||
for (const auto ¶m : request.query) {
|
|
||||||
parameters += (parameters.empty() ? '?' : '&') + param.first + '=' +
|
|
||||||
url_encode(curl, param.second, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (not cfg.api_password.empty()) {
|
|
||||||
curl_easy_setopt(curl, CURLOPT_USERNAME, cfg.api_user.c_str());
|
|
||||||
curl_easy_setopt(curl, CURLOPT_PASSWORD, cfg.api_password.c_str());
|
|
||||||
} else if (not cfg.api_user.empty()) {
|
|
||||||
curl_easy_setopt(curl, CURLOPT_USERNAME, cfg.api_user.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (request.aws_service.has_value()) {
|
|
||||||
curl_easy_setopt(curl, CURLOPT_AWS_SIGV4,
|
|
||||||
request.aws_service.value().c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
auto url = construct_url(curl, request.get_path(), cfg) + parameters;
|
|
||||||
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
|
|
||||||
|
|
||||||
multi_request curl_request(curl, stop_requested);
|
|
||||||
|
|
||||||
CURLcode curl_code{};
|
CURLcode curl_code{};
|
||||||
curl_request.get_result(curl_code, response_code);
|
const auto do_request = [&]() -> bool {
|
||||||
if (curl_code != CURLE_OK) {
|
if (request.decryption_token.has_value() &&
|
||||||
event_system::instance().raise<curl_error>(url, curl_code);
|
not request.decryption_token.value().empty()) {
|
||||||
return false;
|
return make_encrypted_request(cfg, request, response_code,
|
||||||
|
stop_requested);
|
||||||
|
}
|
||||||
|
|
||||||
|
response_code = 0;
|
||||||
|
|
||||||
|
auto *curl = create_curl();
|
||||||
|
if (not request.set_method(curl, stop_requested)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (not cfg.agent_string.empty()) {
|
||||||
|
curl_easy_setopt(curl, CURLOPT_USERAGENT, cfg.agent_string.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.allow_timeout && cfg.timeout_ms) {
|
||||||
|
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, cfg.timeout_ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string range_list{};
|
||||||
|
if (request.range.has_value()) {
|
||||||
|
range_list = std::to_string(request.range.value().begin) + '-' +
|
||||||
|
std::to_string(request.range.value().end);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_RANGE, range_list.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.response_headers.has_value()) {
|
||||||
|
curl_easy_setopt(curl, CURLOPT_HEADERDATA,
|
||||||
|
&request.response_headers.value());
|
||||||
|
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, write_headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
read_write_info write_info{
|
||||||
|
{},
|
||||||
|
[&stop_requested]() -> bool {
|
||||||
|
return stop_requested || app_config::get_stop_requested();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
if (request.response_handler.has_value()) {
|
||||||
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &write_info);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string parameters{};
|
||||||
|
for (const auto ¶m : request.query) {
|
||||||
|
parameters += (parameters.empty() ? '?' : '&') + param.first + '=' +
|
||||||
|
url_encode(curl, param.second, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (not cfg.api_password.empty()) {
|
||||||
|
curl_easy_setopt(curl, CURLOPT_USERNAME, cfg.api_user.c_str());
|
||||||
|
curl_easy_setopt(curl, CURLOPT_PASSWORD, cfg.api_password.c_str());
|
||||||
|
} else if (not cfg.api_user.empty()) {
|
||||||
|
curl_easy_setopt(curl, CURLOPT_USERNAME, cfg.api_user.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.aws_service.has_value()) {
|
||||||
|
curl_easy_setopt(curl, CURLOPT_AWS_SIGV4,
|
||||||
|
request.aws_service.value().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_slist *header_list{nullptr};
|
||||||
|
if (not request.headers.empty()) {
|
||||||
|
for (const auto &header : request.headers) {
|
||||||
|
header_list = curl_slist_append(
|
||||||
|
header_list,
|
||||||
|
fmt::format("{}: {}", header.first, header.second).c_str());
|
||||||
|
}
|
||||||
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_shared::set_share(curl);
|
||||||
|
|
||||||
|
auto url = construct_url(curl, request.get_path(), cfg) + parameters;
|
||||||
|
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
|
||||||
|
|
||||||
|
multi_request curl_request(curl, stop_requested);
|
||||||
|
|
||||||
|
curl_code = CURLE_OK;
|
||||||
|
curl_request.get_result(curl_code, response_code);
|
||||||
|
|
||||||
|
if (header_list != nullptr) {
|
||||||
|
curl_slist_free_all(header_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (curl_code != CURLE_OK) {
|
||||||
|
event_system::instance().raise<curl_error>(curl_code, function_name,
|
||||||
|
request.get_type(), url);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.response_handler.has_value()) {
|
||||||
|
request.response_handler.value()(write_info.data, response_code);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool ret{false};
|
||||||
|
for (std::uint8_t retry = 0U; !ret && retry < retry_request_count;
|
||||||
|
++retry) {
|
||||||
|
ret = do_request();
|
||||||
|
if (ret) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (curl_code == CURLE_COULDNT_RESOLVE_HOST) {
|
||||||
|
std::this_thread::sleep_for(1s);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request.response_handler.has_value()) {
|
return ret;
|
||||||
request.response_handler.value()(write_info.data, response_code);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void enable_s3_path_style(bool enable) override;
|
[[nodiscard]] auto make_request(const curl::requests::http_delete &del,
|
||||||
|
long &response_code,
|
||||||
|
stop_type &stop_requested) const
|
||||||
|
-> bool override;
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto make_request(const curl::requests::http_get &get,
|
||||||
make_request(const curl::requests::http_delete &del, long &response_code,
|
long &response_code,
|
||||||
stop_type &stop_requested) const -> bool override;
|
stop_type &stop_requested) const
|
||||||
|
-> bool override;
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto make_request(const curl::requests::http_head &head,
|
||||||
make_request(const curl::requests::http_get &get, long &response_code,
|
long &response_code,
|
||||||
stop_type &stop_requested) const -> bool override;
|
stop_type &stop_requested) const
|
||||||
|
-> bool override;
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto make_request(const curl::requests::http_post &post_file,
|
||||||
make_request(const curl::requests::http_head &head, long &response_code,
|
long &response_code,
|
||||||
stop_type &stop_requested) const -> bool override;
|
stop_type &stop_requested) const
|
||||||
|
-> bool override;
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto make_request(const curl::requests::http_put_file &put_file,
|
||||||
make_request(const curl::requests::http_post &post_file, long &response_code,
|
long &response_code,
|
||||||
stop_type &stop_requested) const -> bool override;
|
stop_type &stop_requested) const
|
||||||
|
-> bool override;
|
||||||
[[nodiscard]] auto
|
|
||||||
make_request(const curl::requests::http_put_file &put_file,
|
|
||||||
long &response_code,
|
|
||||||
stop_type &stop_requested) const -> bool override;
|
|
||||||
};
|
};
|
||||||
} // namespace repertory
|
} // namespace repertory
|
||||||
|
|
||||||
|
|||||||
67
repertory/librepertory/include/comm/curl/curl_shared.hpp
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
Copyright <2018-2025> <scott.e.graves@protonmail.com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
#ifndef REPERTORY_INCLUDE_COMM_CURL_CURL_SHARED_HPP_
|
||||||
|
#define REPERTORY_INCLUDE_COMM_CURL_CURL_SHARED_HPP_
|
||||||
|
|
||||||
|
namespace repertory {
|
||||||
|
class curl_shared final {
|
||||||
|
private:
|
||||||
|
struct curl_sh_deleter final {
|
||||||
|
void operator()(CURLSH *ptr) {
|
||||||
|
if (ptr != nullptr) {
|
||||||
|
curl_share_cleanup(ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
using curl_sh_t = std::unique_ptr<CURLSH, curl_sh_deleter>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
curl_shared() = delete;
|
||||||
|
curl_shared(const curl_shared &) = delete;
|
||||||
|
curl_shared(curl_shared &&) = delete;
|
||||||
|
~curl_shared() = delete;
|
||||||
|
|
||||||
|
auto operator=(const curl_shared &) -> curl_shared & = delete;
|
||||||
|
auto operator=(curl_shared &&) -> curl_shared & = delete;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static curl_sh_t cache_;
|
||||||
|
static std::recursive_mutex mtx_;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void lock_callback(CURL * /* curl */, curl_lock_data /* data */,
|
||||||
|
curl_lock_access /* access */, void * /* ptr */);
|
||||||
|
|
||||||
|
static void unlock_callback(CURL * /* curl */, curl_lock_data /* data */,
|
||||||
|
curl_lock_access /* access */, void * /* ptr */);
|
||||||
|
|
||||||
|
public:
|
||||||
|
static void cleanup();
|
||||||
|
|
||||||
|
[[nodiscard]] static auto init() -> bool;
|
||||||
|
|
||||||
|
static void set_share(CURL *curl);
|
||||||
|
};
|
||||||
|
} // namespace repertory
|
||||||
|
|
||||||
|
#endif // REPERTORY_INCLUDE_COMM_CURL_DNS_CACHE_HPP_
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
Copyright <2018-2025> <scott.e.graves@protonmail.com>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -36,6 +36,9 @@ private:
|
|||||||
stop_type &stop_requested_;
|
stop_type &stop_requested_;
|
||||||
CURLM *multi_handle_;
|
CURLM *multi_handle_;
|
||||||
|
|
||||||
|
private:
|
||||||
|
[[nodiscard]] auto get_stop_requested() const -> bool;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void get_result(CURLcode &curl_code, long &http_code);
|
void get_result(CURLcode &curl_code, long &http_code);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
Copyright <2018-2025> <scott.e.graves@protonmail.com>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -26,11 +26,13 @@
|
|||||||
|
|
||||||
namespace repertory::curl::requests {
|
namespace repertory::curl::requests {
|
||||||
struct http_delete final : http_request_base {
|
struct http_delete final : http_request_base {
|
||||||
~http_delete() override = default;
|
[[nodiscard]] auto get_type() const -> std::string override {
|
||||||
|
return "delete";
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto set_method(CURL *curl,
|
||||||
set_method(CURL *curl,
|
stop_type & /* stop_requested */) const
|
||||||
stop_type & /* stop_requested */) const -> bool override {
|
-> bool override {
|
||||||
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE");
|
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
Copyright <2018-2025> <scott.e.graves@protonmail.com>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -33,9 +33,11 @@ struct http_get final : http_request_base {
|
|||||||
auto operator=(http_get &&) -> http_get & = default;
|
auto operator=(http_get &&) -> http_get & = default;
|
||||||
~http_get() override = default;
|
~http_get() override = default;
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto get_type() const -> std::string override { return "get"; }
|
||||||
set_method(CURL *curl,
|
|
||||||
stop_type & /*stop_requested*/) const -> bool override {
|
[[nodiscard]] auto set_method(CURL *curl,
|
||||||
|
stop_type & /*stop_requested*/) const
|
||||||
|
-> bool override {
|
||||||
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
|
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
Copyright <2018-2025> <scott.e.graves@protonmail.com>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -26,11 +26,11 @@
|
|||||||
|
|
||||||
namespace repertory::curl::requests {
|
namespace repertory::curl::requests {
|
||||||
struct http_head final : http_request_base {
|
struct http_head final : http_request_base {
|
||||||
~http_head() override = default;
|
[[nodiscard]] auto get_type() const -> std::string override { return "head"; }
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto set_method(CURL *curl,
|
||||||
set_method(CURL *curl,
|
stop_type & /* stop_requested */) const
|
||||||
stop_type & /* stop_requested */) const -> bool override {
|
-> bool override {
|
||||||
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "HEAD");
|
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "HEAD");
|
||||||
curl_easy_setopt(curl, CURLOPT_NOBODY, 1L);
|
curl_easy_setopt(curl, CURLOPT_NOBODY, 1L);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
Copyright <2018-2025> <scott.e.graves@protonmail.com>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -26,21 +26,15 @@
|
|||||||
|
|
||||||
namespace repertory::curl::requests {
|
namespace repertory::curl::requests {
|
||||||
struct http_post final : http_request_base {
|
struct http_post final : http_request_base {
|
||||||
http_post() = default;
|
|
||||||
http_post(const http_post &) = default;
|
|
||||||
http_post(http_post &&) = default;
|
|
||||||
auto operator=(const http_post &) -> http_post & = default;
|
|
||||||
auto operator=(http_post &&) -> http_post & = default;
|
|
||||||
|
|
||||||
~http_post() override;
|
|
||||||
|
|
||||||
std::optional<nlohmann::json> json;
|
std::optional<nlohmann::json> json;
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto get_type() const -> std::string override { return "post"; }
|
||||||
set_method(CURL *curl, stop_type & /*stop_requested*/) const -> bool override;
|
|
||||||
|
[[nodiscard]] auto set_method(CURL *curl,
|
||||||
|
stop_type & /*stop_requested*/) const
|
||||||
|
-> bool override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable curl_slist *headers{nullptr};
|
|
||||||
mutable std::optional<std::string> json_str;
|
mutable std::optional<std::string> json_str;
|
||||||
};
|
};
|
||||||
} // namespace repertory::curl::requests
|
} // namespace repertory::curl::requests
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
Copyright <2018-2025> <scott.e.graves@protonmail.com>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -27,18 +27,11 @@
|
|||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
std::shared_ptr<utils::encryption::encrypting_reader> reader;
|
std::shared_ptr<utils::encryption::encrypting_reader> reader;
|
||||||
std::string source_path;
|
std::string source_path;
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_type() const -> std::string override { return "put"; }
|
||||||
|
|
||||||
[[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;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
Copyright <2018-2025> <scott.e.graves@protonmail.com>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -51,7 +51,7 @@ struct http_request_base {
|
|||||||
bool allow_timeout{};
|
bool allow_timeout{};
|
||||||
std::optional<std::string> aws_service;
|
std::optional<std::string> aws_service;
|
||||||
std::optional<std::string> decryption_token{};
|
std::optional<std::string> decryption_token{};
|
||||||
http_headers headers{};
|
mutable http_headers headers{};
|
||||||
std::string path{};
|
std::string path{};
|
||||||
http_query_parameters query{};
|
http_query_parameters query{};
|
||||||
std::optional<http_range> range{};
|
std::optional<http_range> range{};
|
||||||
@@ -61,6 +61,8 @@ struct http_request_base {
|
|||||||
|
|
||||||
[[nodiscard]] virtual auto get_path() const -> std::string { return path; }
|
[[nodiscard]] virtual auto get_path() const -> std::string { return path; }
|
||||||
|
|
||||||
|
[[nodiscard]] virtual auto get_type() const -> std::string = 0;
|
||||||
|
|
||||||
[[nodiscard]] virtual auto set_method(CURL *curl,
|
[[nodiscard]] virtual auto set_method(CURL *curl,
|
||||||
stop_type &stop_requested) const
|
stop_type &stop_requested) const
|
||||||
-> bool = 0;
|
-> bool = 0;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
Copyright <2018-2025> <scott.e.graves@protonmail.com>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -34,28 +34,29 @@ struct i_http_comm {
|
|||||||
INTERFACE_SETUP(i_http_comm);
|
INTERFACE_SETUP(i_http_comm);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void enable_s3_path_style(bool enable) = 0;
|
|
||||||
|
|
||||||
[[nodiscard]] virtual auto
|
[[nodiscard]] virtual auto
|
||||||
make_request(const curl::requests::http_delete &del, long &response_code,
|
make_request(const curl::requests::http_delete &del, long &response_code,
|
||||||
stop_type &stop_requested) const -> bool = 0;
|
stop_type &stop_requested) const -> bool = 0;
|
||||||
|
|
||||||
[[nodiscard]] virtual auto
|
[[nodiscard]] virtual auto make_request(const curl::requests::http_get &get,
|
||||||
make_request(const curl::requests::http_get &get, long &response_code,
|
long &response_code,
|
||||||
stop_type &stop_requested) const -> bool = 0;
|
stop_type &stop_requested) const
|
||||||
|
-> bool = 0;
|
||||||
|
|
||||||
[[nodiscard]] virtual auto
|
[[nodiscard]] virtual auto make_request(const curl::requests::http_head &head,
|
||||||
make_request(const curl::requests::http_head &head, long &response_code,
|
long &response_code,
|
||||||
stop_type &stop_requested) const -> bool = 0;
|
stop_type &stop_requested) const
|
||||||
|
-> bool = 0;
|
||||||
|
|
||||||
[[nodiscard]] virtual auto
|
[[nodiscard]] virtual auto make_request(const curl::requests::http_post &post,
|
||||||
make_request(const curl::requests::http_post &post, long &response_code,
|
long &response_code,
|
||||||
stop_type &stop_requested) const -> bool = 0;
|
stop_type &stop_requested) const
|
||||||
|
-> bool = 0;
|
||||||
|
|
||||||
[[nodiscard]] virtual auto
|
[[nodiscard]] virtual auto
|
||||||
make_request(const curl::requests::http_put_file &put_file,
|
make_request(const curl::requests::http_put_file &put_file,
|
||||||
long &response_code,
|
long &response_code, stop_type &stop_requested) const
|
||||||
stop_type &stop_requested) const -> bool = 0;
|
-> bool = 0;
|
||||||
};
|
};
|
||||||
} // namespace repertory
|
} // namespace repertory
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
Copyright <2018-2025> <scott.e.graves@protonmail.com>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -23,10 +23,13 @@
|
|||||||
#define REPERTORY_INCLUDE_COMM_PACKET_CLIENT_POOL_HPP_
|
#define REPERTORY_INCLUDE_COMM_PACKET_CLIENT_POOL_HPP_
|
||||||
|
|
||||||
#include "comm/packet/packet.hpp"
|
#include "comm/packet/packet.hpp"
|
||||||
#include "types/repertory.hpp"
|
|
||||||
|
|
||||||
namespace repertory {
|
namespace repertory {
|
||||||
class client_pool final {
|
class client_pool final {
|
||||||
|
public:
|
||||||
|
static constexpr const std::uint16_t default_expired_seconds{120U};
|
||||||
|
static constexpr const std::uint16_t min_expired_seconds{5U};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using worker_callback = std::function<packet::error_type()>;
|
using worker_callback = std::function<packet::error_type()>;
|
||||||
using worker_complete_callback =
|
using worker_complete_callback =
|
||||||
@@ -46,15 +49,32 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct work_queue final {
|
struct work_queue final {
|
||||||
|
work_queue();
|
||||||
|
~work_queue();
|
||||||
|
|
||||||
|
work_queue(const work_queue &) = delete;
|
||||||
|
work_queue(work_queue &&) = delete;
|
||||||
|
|
||||||
|
std::deque<std::shared_ptr<work_item>> actions;
|
||||||
|
std::atomic<std::chrono::steady_clock::time_point> modified{
|
||||||
|
std::chrono::steady_clock::now(),
|
||||||
|
};
|
||||||
std::mutex mutex;
|
std::mutex mutex;
|
||||||
std::condition_variable notify;
|
std::condition_variable notify;
|
||||||
std::deque<std::shared_ptr<work_item>> queue;
|
stop_type shutdown{false};
|
||||||
|
std::unique_ptr<std::thread> thread;
|
||||||
|
|
||||||
|
auto operator=(const work_queue &) -> work_queue & = delete;
|
||||||
|
auto operator=(work_queue &&) -> work_queue & = delete;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void work_thread();
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit pool(std::uint8_t pool_size);
|
pool() noexcept = default;
|
||||||
|
|
||||||
~pool() { shutdown(); }
|
~pool();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
pool(const pool &) = delete;
|
pool(const pool &) = delete;
|
||||||
@@ -63,21 +83,20 @@ private:
|
|||||||
auto operator=(pool &&) -> pool & = delete;
|
auto operator=(pool &&) -> pool & = delete;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<std::unique_ptr<work_queue>> pool_queues_;
|
std::mutex pool_mtx_;
|
||||||
std::vector<std::thread> pool_threads_;
|
std::unordered_map<std::uint64_t, std::shared_ptr<work_queue>> pool_queues_;
|
||||||
bool shutdown_{false};
|
|
||||||
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, worker_callback worker,
|
||||||
const worker_complete_callback &worker_complete);
|
worker_complete_callback worker_complete);
|
||||||
|
|
||||||
|
void remove_expired(std::uint16_t seconds);
|
||||||
|
|
||||||
void shutdown();
|
void shutdown();
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit client_pool(std::uint8_t pool_size = min_pool_size)
|
client_pool() noexcept;
|
||||||
: pool_size_(pool_size == 0U ? min_pool_size : pool_size) {}
|
|
||||||
|
|
||||||
~client_pool() { shutdown(); }
|
~client_pool() { shutdown(); }
|
||||||
|
|
||||||
@@ -88,20 +107,23 @@ public:
|
|||||||
auto operator=(client_pool &&) -> client_pool & = delete;
|
auto operator=(client_pool &&) -> client_pool & = delete;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::uint8_t pool_size_;
|
std::unordered_map<std::string, std::unique_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;
|
stop_type shutdown_{false};
|
||||||
|
std::atomic<std::uint16_t> expired_seconds_{default_expired_seconds};
|
||||||
private:
|
|
||||||
static constexpr const auto min_pool_size = 10U;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void execute(const std::string &client_id, std::uint64_t thread_id,
|
[[nodiscard]] auto get_expired_seconds() const -> std::uint16_t;
|
||||||
const worker_callback &worker,
|
|
||||||
const worker_complete_callback &worker_complete);
|
|
||||||
|
|
||||||
void remove_client(const std::string &client_id);
|
void execute(std::string client_id, std::uint64_t thread_id,
|
||||||
|
worker_callback worker,
|
||||||
|
worker_complete_callback worker_complete);
|
||||||
|
|
||||||
|
void remove_client(std::string client_id);
|
||||||
|
|
||||||
|
void remove_expired();
|
||||||
|
|
||||||
|
void set_expired_seconds(std::uint16_t seconds);
|
||||||
|
|
||||||
void shutdown();
|
void shutdown();
|
||||||
};
|
};
|
||||||
|
|||||||
54
repertory/librepertory/include/comm/packet/common.hpp
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
Copyright <2018-2025> <scott.e.graves@protonmail.com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
#ifndef REPERTORY_INCLUDE_COMM_PACKET_COMMON_HPP_
|
||||||
|
#define REPERTORY_INCLUDE_COMM_PACKET_COMMON_HPP_
|
||||||
|
|
||||||
|
namespace repertory::comm {
|
||||||
|
inline static constexpr std::uint32_t max_packet_bytes{32U * 1024U * 1024U};
|
||||||
|
inline constexpr const std::uint8_t max_read_attempts{2U};
|
||||||
|
inline constexpr const std::uint16_t packet_nonce_size{256U};
|
||||||
|
inline constexpr const std::size_t read_write_size{131072U};
|
||||||
|
inline constexpr const std::uint16_t server_handshake_timeout_ms{3000U};
|
||||||
|
|
||||||
|
struct non_blocking_guard final {
|
||||||
|
non_blocking_guard(const non_blocking_guard &) = delete;
|
||||||
|
non_blocking_guard(non_blocking_guard &&) = delete;
|
||||||
|
|
||||||
|
auto operator=(const non_blocking_guard &) -> non_blocking_guard & = delete;
|
||||||
|
auto operator=(non_blocking_guard &&) -> non_blocking_guard & = delete;
|
||||||
|
|
||||||
|
explicit non_blocking_guard(boost::asio::ip::tcp::socket &sock_);
|
||||||
|
|
||||||
|
~non_blocking_guard();
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool non_blocking;
|
||||||
|
boost::asio::ip::tcp::socket &sock;
|
||||||
|
};
|
||||||
|
|
||||||
|
void apply_common_socket_properties(boost::asio::ip::tcp::socket &sock);
|
||||||
|
|
||||||
|
[[nodiscard]] auto is_socket_still_alive(boost::asio::ip::tcp::socket &sock)
|
||||||
|
-> bool;
|
||||||
|
} // namespace repertory::comm
|
||||||
|
|
||||||
|
#endif // REPERTORY_INCLUDE_COMM_PACKET_COMMON_HPP_
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
Copyright <2018-2025> <scott.e.graves@protonmail.com>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -200,7 +200,7 @@ public:
|
|||||||
|
|
||||||
void encode_top(remote::file_info val);
|
void encode_top(remote::file_info val);
|
||||||
|
|
||||||
void encrypt(std::string_view token);
|
void encrypt(std::string_view token, bool include_size = true);
|
||||||
|
|
||||||
[[nodiscard]] auto get_size() const -> std::uint32_t {
|
[[nodiscard]] auto get_size() const -> std::uint32_t {
|
||||||
return static_cast<std::uint32_t>(buffer_.size());
|
return static_cast<std::uint32_t>(buffer_.size());
|
||||||
|
|||||||
@@ -1,17 +1,13 @@
|
|||||||
/*
|
/*
|
||||||
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
Copyright <2018-2025> <scott.e.graves@protonmail.com>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
in the Software without restriction, including without limitation the rights
|
in the Software without restriction, including without limitation the rights
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
copies of the Software, and to permit persons to do so, subject to the
|
||||||
furnished to do so, subject to the following conditions:
|
following conditions: The above copyright notice and this permission notice
|
||||||
|
shall be included in all copies or substantial portions of the Software. THE
|
||||||
The above copyright notice and this permission notice shall be included in all
|
SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
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,
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
@@ -24,6 +20,7 @@
|
|||||||
|
|
||||||
#include "comm/packet/packet.hpp"
|
#include "comm/packet/packet.hpp"
|
||||||
#include "types/remote.hpp"
|
#include "types/remote.hpp"
|
||||||
|
#include "utils/atomic.hpp"
|
||||||
|
|
||||||
using boost::asio::ip::tcp;
|
using boost::asio::ip::tcp;
|
||||||
|
|
||||||
@@ -47,34 +44,46 @@ public:
|
|||||||
auto operator=(packet_client &&) -> packet_client & = delete;
|
auto operator=(packet_client &&) -> packet_client & = delete;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
boost::asio::io_context io_context_;
|
|
||||||
remote::remote_config cfg_;
|
remote::remote_config cfg_;
|
||||||
std::string unique_id_;
|
mutable boost::asio::io_context io_context_;
|
||||||
|
utils::atomic<std::string> unique_id_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool allow_connections_{true};
|
std::atomic<bool> allow_connections_{true};
|
||||||
boost::asio::ip::basic_resolver<boost::asio::ip::tcp>::results_type
|
utils::atomic<
|
||||||
|
boost::asio::ip::basic_resolver<boost::asio::ip::tcp>::results_type>
|
||||||
resolve_results_;
|
resolve_results_;
|
||||||
std::mutex clients_mutex_;
|
std::mutex clients_mutex_;
|
||||||
std::vector<std::shared_ptr<client>> clients_;
|
std::vector<std::shared_ptr<client>> clients_;
|
||||||
|
std::vector<std::thread> service_threads_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void close(client &cli);
|
static void close(client &cli) noexcept;
|
||||||
|
|
||||||
void close_all();
|
void close_all();
|
||||||
|
|
||||||
void connect(client &cli);
|
[[nodiscard]] auto connect(client &cli) -> bool;
|
||||||
|
|
||||||
[[nodiscard]] auto get_client() -> std::shared_ptr<client>;
|
[[nodiscard]] auto get_client() -> std::shared_ptr<client>;
|
||||||
|
|
||||||
|
[[nodiscard]] auto handshake(client &cli, std::uint32_t &min_version) const
|
||||||
|
-> bool;
|
||||||
|
|
||||||
void put_client(std::shared_ptr<client> &cli);
|
void put_client(std::shared_ptr<client> &cli);
|
||||||
|
|
||||||
[[nodiscard]] auto read_packet(client &cli, packet &response)
|
void read_data(client &cli, data_buffer &buffer) const;
|
||||||
|
|
||||||
|
[[nodiscard]] auto read_packet(client &cli, packet &response) const
|
||||||
-> packet::error_type;
|
-> packet::error_type;
|
||||||
|
|
||||||
void resolve();
|
void resolve();
|
||||||
|
|
||||||
|
void write_data(client &cli, const packet &request) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
[[nodiscard]] auto check_version(std::uint32_t client_version,
|
||||||
|
std::uint32_t &min_version) -> api_error;
|
||||||
|
|
||||||
[[nodiscard]] auto send(std::string_view method, std::uint32_t &service_flags)
|
[[nodiscard]] auto send(std::string_view method, std::uint32_t &service_flags)
|
||||||
-> packet::error_type;
|
-> packet::error_type;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
Copyright <2018-2025> <scott.e.graves@protonmail.com>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
#define REPERTORY_INCLUDE_COMM_PACKET_PACKET_SERVER_HPP_
|
#define REPERTORY_INCLUDE_COMM_PACKET_PACKET_SERVER_HPP_
|
||||||
|
|
||||||
#include "comm/packet/client_pool.hpp"
|
#include "comm/packet/client_pool.hpp"
|
||||||
|
#include "comm/packet/common.hpp"
|
||||||
#include "utils/common.hpp"
|
#include "utils/common.hpp"
|
||||||
|
|
||||||
using namespace boost::asio;
|
using namespace boost::asio;
|
||||||
@@ -31,11 +32,11 @@ using boost::asio::ip::tcp;
|
|||||||
namespace repertory {
|
namespace repertory {
|
||||||
class packet_server final {
|
class packet_server final {
|
||||||
public:
|
public:
|
||||||
using closed_callback = std::function<void(const std::string &)>;
|
using closed_callback = std::function<void(std::string)>;
|
||||||
using message_complete_callback = client_pool::worker_complete_callback;
|
using message_complete_callback = client_pool::worker_complete_callback;
|
||||||
using message_handler_callback = std::function<void(
|
using message_handler_callback =
|
||||||
std::uint32_t, const std::string &, std::uint64_t, const std::string &,
|
std::function<void(std::uint32_t, std::string, std::uint64_t, std::string,
|
||||||
packet *, packet &, message_complete_callback)>;
|
packet *, packet &, message_complete_callback)>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
packet_server(std::uint16_t port, std::string token, std::uint8_t pool_size,
|
packet_server(std::uint16_t port, std::string token, std::uint8_t pool_size,
|
||||||
@@ -61,21 +62,25 @@ private:
|
|||||||
std::string client_id;
|
std::string client_id;
|
||||||
std::string nonce;
|
std::string nonce;
|
||||||
|
|
||||||
void generate_nonce() { nonce = utils::generate_random_string(256U); }
|
void generate_nonce() {
|
||||||
|
nonce = utils::generate_random_string(comm::packet_nonce_size);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string encryption_token_;
|
std::string encryption_token_;
|
||||||
closed_callback closed_;
|
closed_callback closed_;
|
||||||
message_handler_callback message_handler_;
|
message_handler_callback message_handler_;
|
||||||
io_context io_context_;
|
mutable io_context io_context_;
|
||||||
std::unique_ptr<std::thread> server_thread_;
|
std::unique_ptr<std::thread> server_thread_;
|
||||||
std::vector<std::thread> service_threads_;
|
std::vector<std::thread> service_threads_;
|
||||||
std::recursive_mutex connection_mutex_;
|
std::recursive_mutex connection_mutex_;
|
||||||
std::unordered_map<std::string, std::uint32_t> connection_lookup_;
|
std::unordered_map<std::string, std::uint32_t> connection_lookup_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void add_client(connection &conn, const std::string &client_id);
|
void add_client(connection &conn, std::string client_id);
|
||||||
|
|
||||||
|
[[nodiscard]] auto handshake(std::shared_ptr<connection> conn) const -> bool;
|
||||||
|
|
||||||
void initialize(const uint16_t &port, uint8_t pool_size);
|
void initialize(const uint16_t &port, uint8_t pool_size);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
Copyright <2018-2025> <scott.e.graves@protonmail.com>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
#ifndef REPERTORY_INCLUDE_COMMON_HPP_
|
#ifndef REPERTORY_INCLUDE_COMMON_HPP_
|
||||||
#define REPERTORY_INCLUDE_COMMON_HPP_
|
#define REPERTORY_INCLUDE_COMMON_HPP_
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__) && !defined(PROJECT_IS_DARWIN)
|
||||||
// clang-format off
|
// clang-format off
|
||||||
#define REPERTORY_IGNORE_WARNINGS_ENABLE() \
|
#define REPERTORY_IGNORE_WARNINGS_ENABLE() \
|
||||||
_Pragma("GCC diagnostic push") \
|
_Pragma("GCC diagnostic push") \
|
||||||
@@ -54,12 +54,13 @@ REPERTORY_IGNORE_WARNINGS_DISABLE()
|
|||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
|
|
||||||
inline constexpr const std::string_view REPERTORY = "repertory";
|
inline constexpr std::string_view REPERTORY{"repertory"};
|
||||||
inline constexpr const std::wstring_view REPERTORY_W = L"repertory";
|
inline constexpr std::string_view REPERTORY_DATA_NAME{"repertory2"};
|
||||||
|
inline constexpr std::wstring_view REPERTORY_W{L"repertory"};
|
||||||
|
|
||||||
inline constexpr const std::uint64_t REPERTORY_CONFIG_VERSION = 0ULL;
|
inline constexpr std::uint64_t REPERTORY_CONFIG_VERSION{5ULL};
|
||||||
inline constexpr const std::string_view REPERTORY_DATA_NAME = "repertory2";
|
inline constexpr std::string_view REPERTORY_MIN_REMOTE_VERSION{"2.1.0"};
|
||||||
inline constexpr const std::string_view REPERTORY_MIN_REMOTE_VERSION = "2.0.0";
|
inline constexpr std::string_view RENTERD_MIN_VERSION{"2.0.0"};
|
||||||
|
|
||||||
#define REPERTORY_INVALID_HANDLE INVALID_HANDLE_VALUE
|
#define REPERTORY_INVALID_HANDLE INVALID_HANDLE_VALUE
|
||||||
|
|
||||||
@@ -221,11 +222,11 @@ using WCHAR = wchar_t;
|
|||||||
|
|
||||||
#define MAX_PATH 260
|
#define MAX_PATH 260
|
||||||
|
|
||||||
#define STATUS_SUCCESS std::uint32_t{0U}
|
|
||||||
#define STATUS_ACCESS_DENIED std::uint32_t{0xC0000022L}
|
#define STATUS_ACCESS_DENIED std::uint32_t{0xC0000022L}
|
||||||
#define STATUS_DEVICE_BUSY std::uint32_t{0x80000011L}
|
#define STATUS_DEVICE_BUSY std::uint32_t{0x80000011L}
|
||||||
#define STATUS_DEVICE_INSUFFICIENT_RESOURCES std::uint32_t{0xC0000468L}
|
#define STATUS_DEVICE_INSUFFICIENT_RESOURCES std::uint32_t{0xC0000468L}
|
||||||
#define STATUS_DIRECTORY_NOT_EMPTY std::uint32_t{0xC0000101L}
|
#define STATUS_DIRECTORY_NOT_EMPTY std::uint32_t{0xC0000101L}
|
||||||
|
#define STATUS_END_OF_FILE std::uint32_t{0xC0000011L}
|
||||||
#define STATUS_FILE_IS_A_DIRECTORY std::uint32_t{0xC00000BAL}
|
#define STATUS_FILE_IS_A_DIRECTORY std::uint32_t{0xC00000BAL}
|
||||||
#define STATUS_FILE_TOO_LARGE std::uint32_t{0xC0000904L}
|
#define STATUS_FILE_TOO_LARGE std::uint32_t{0xC0000904L}
|
||||||
#define STATUS_INSUFFICIENT_RESOURCES std::uint32_t{0xC000009AL}
|
#define STATUS_INSUFFICIENT_RESOURCES std::uint32_t{0xC000009AL}
|
||||||
@@ -234,11 +235,13 @@ using WCHAR = wchar_t;
|
|||||||
#define STATUS_INVALID_HANDLE std::uint32_t{0xC0000006L}
|
#define STATUS_INVALID_HANDLE std::uint32_t{0xC0000006L}
|
||||||
#define STATUS_INVALID_IMAGE_FORMAT std::uint32_t{0xC000007BL}
|
#define STATUS_INVALID_IMAGE_FORMAT std::uint32_t{0xC000007BL}
|
||||||
#define STATUS_INVALID_PARAMETER std::uint32_t{0xC000000DL}
|
#define STATUS_INVALID_PARAMETER std::uint32_t{0xC000000DL}
|
||||||
#define STATUS_NO_MEMORY std::uint32_t{0xC0000017L}
|
|
||||||
#define STATUS_NOT_IMPLEMENTED std::uint32_t{0xC0000002L}
|
#define STATUS_NOT_IMPLEMENTED std::uint32_t{0xC0000002L}
|
||||||
|
#define STATUS_NO_MEMORY std::uint32_t{0xC0000017L}
|
||||||
|
#define STATUS_OBJECT_NAME_COLLISION std::uint32_t{0xC0000035L}
|
||||||
#define STATUS_OBJECT_NAME_EXISTS std::uint32_t{0x40000000L}
|
#define STATUS_OBJECT_NAME_EXISTS std::uint32_t{0x40000000L}
|
||||||
#define STATUS_OBJECT_NAME_NOT_FOUND std::uint32_t{0xC0000034L}
|
#define STATUS_OBJECT_NAME_NOT_FOUND std::uint32_t{0xC0000034L}
|
||||||
#define STATUS_OBJECT_PATH_INVALID std::uint32_t{0xC0000039L}
|
#define STATUS_OBJECT_PATH_INVALID std::uint32_t{0xC0000039L}
|
||||||
|
#define STATUS_SUCCESS std::uint32_t{0U}
|
||||||
#define STATUS_UNEXPECTED_IO_ERROR std::uint32_t{0xC00000E9L}
|
#define STATUS_UNEXPECTED_IO_ERROR std::uint32_t{0xC00000E9L}
|
||||||
|
|
||||||
#define CONVERT_STATUS_NOT_IMPLEMENTED(e) \
|
#define CONVERT_STATUS_NOT_IMPLEMENTED(e) \
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
Copyright <2018-2025> <scott.e.graves@protonmail.com>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
Copyright <2018-2025> <scott.e.graves@protonmail.com>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
Copyright <2018-2025> <scott.e.graves@protonmail.com>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -29,9 +29,16 @@ class i_file_db {
|
|||||||
INTERFACE_SETUP(i_file_db);
|
INTERFACE_SETUP(i_file_db);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
struct directory_data final {
|
||||||
|
std::string api_path;
|
||||||
|
std::pair<utils::encryption::kdf_config, utils::encryption::kdf_config>
|
||||||
|
kdf_configs;
|
||||||
|
std::string source_path;
|
||||||
|
};
|
||||||
|
|
||||||
struct file_info final {
|
struct file_info final {
|
||||||
std::string api_path;
|
std::string api_path;
|
||||||
bool directory;
|
bool directory{};
|
||||||
std::string source_path;
|
std::string source_path;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -40,13 +47,14 @@ public:
|
|||||||
std::uint64_t file_size{};
|
std::uint64_t file_size{};
|
||||||
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::pair<utils::encryption::kdf_config, utils::encryption::kdf_config>
|
||||||
|
kdf_configs;
|
||||||
std::string source_path;
|
std::string source_path;
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
[[nodiscard]] virtual auto add_directory(const std::string &api_path,
|
[[nodiscard]] virtual auto add_or_update_directory(const directory_data &data)
|
||||||
const std::string &source_path)
|
|
||||||
-> api_error = 0;
|
-> api_error = 0;
|
||||||
|
|
||||||
[[nodiscard]] virtual auto add_or_update_file(const file_data &data)
|
[[nodiscard]] virtual auto add_or_update_file(const file_data &data)
|
||||||
@@ -56,38 +64,47 @@ public:
|
|||||||
|
|
||||||
[[nodiscard]] virtual auto count() const -> std::uint64_t = 0;
|
[[nodiscard]] virtual auto count() const -> std::uint64_t = 0;
|
||||||
|
|
||||||
[[nodiscard]] virtual auto get_api_path(const std::string &source_path,
|
virtual void enumerate_item_list(
|
||||||
|
std::function<void(const std::vector<i_file_db::file_info> &)> callback,
|
||||||
|
stop_type_callback stop_requested_cb) const = 0;
|
||||||
|
|
||||||
|
[[nodiscard]] virtual auto get_api_path(std::string_view source_path,
|
||||||
std::string &api_path) const
|
std::string &api_path) const
|
||||||
-> api_error = 0;
|
-> api_error = 0;
|
||||||
|
|
||||||
[[nodiscard]] virtual auto
|
[[nodiscard]] virtual auto
|
||||||
get_directory_api_path(const std::string &source_path,
|
get_directory_api_path(std::string_view source_path,
|
||||||
std::string &api_path) const -> api_error = 0;
|
std::string &api_path) const -> api_error = 0;
|
||||||
|
|
||||||
|
[[nodiscard]] virtual auto get_directory_data(std::string_view api_path,
|
||||||
|
directory_data &data) const
|
||||||
|
-> api_error = 0;
|
||||||
|
|
||||||
[[nodiscard]] virtual auto
|
[[nodiscard]] virtual auto
|
||||||
get_directory_source_path(const std::string &api_path,
|
get_directory_source_path(std::string_view api_path,
|
||||||
std::string &source_path) const -> api_error = 0;
|
std::string &source_path) const -> api_error = 0;
|
||||||
|
|
||||||
[[nodiscard]] virtual auto get_file_api_path(const std::string &source_path,
|
[[nodiscard]] virtual auto get_file_api_path(std::string_view source_path,
|
||||||
std::string &api_path) const
|
std::string &api_path) const
|
||||||
-> api_error = 0;
|
-> api_error = 0;
|
||||||
|
|
||||||
[[nodiscard]] virtual auto get_file_data(const std::string &api_path,
|
[[nodiscard]] virtual auto get_file_data(std::string_view api_path,
|
||||||
file_data &data) const
|
file_data &data) const
|
||||||
-> api_error = 0;
|
-> api_error = 0;
|
||||||
|
|
||||||
[[nodiscard]] virtual auto
|
[[nodiscard]] virtual auto
|
||||||
get_file_source_path(const std::string &api_path,
|
get_file_source_path(std::string_view api_path,
|
||||||
std::string &source_path) const -> api_error = 0;
|
std::string &source_path) const -> api_error = 0;
|
||||||
|
|
||||||
[[nodiscard]] virtual auto get_item_list() const
|
[[nodiscard]] virtual auto
|
||||||
|
get_item_list(stop_type_callback stop_requested_cb) const
|
||||||
-> std::vector<file_info> = 0;
|
-> std::vector<file_info> = 0;
|
||||||
|
|
||||||
[[nodiscard]] virtual auto get_source_path(const std::string &api_path,
|
[[nodiscard]] virtual auto get_source_path(std::string_view api_path,
|
||||||
std::string &source_path) const
|
std::string &source_path) const
|
||||||
-> api_error = 0;
|
-> api_error = 0;
|
||||||
|
|
||||||
[[nodiscard]] virtual auto remove_item(const std::string &api_path)
|
[[nodiscard]] virtual auto remove_item(std::string_view api_path)
|
||||||
-> api_error = 0;
|
-> api_error = 0;
|
||||||
};
|
};
|
||||||
} // namespace repertory
|
} // namespace repertory
|
||||||
|
|||||||