Compare commits
370 Commits
v2.0.2-rc
...
v2.1.0-rc-
Author | SHA1 | Date | |
---|---|---|---|
ed2823ba59 | |||
e94011151a | |||
b44192da62 | |||
044cda06db | |||
ba586ad32f | |||
b28f422174 | |||
94f732df6c | |||
040fa2cd03 | |||
37e8204d92 | |||
18d3a7d843 | |||
d2eba1289c | |||
846520187b | |||
c21e141872 | |||
b077d0c746 | |||
ca9b965e5b | |||
17a28b58a4 | |||
078f679cca | |||
694f487861 | |||
ed89b3e8c2 | |||
12d1491221 | |||
eaf0018eb7 | |||
24bb67894f | |||
218545569d | |||
1ca5f41d89 | |||
f0e1cc7fc5 | |||
e3dd7c9791 | |||
8f0d8d7d6c | |||
b5fe6709d4 | |||
d6ee76ca7a | |||
3d93712aac | |||
21ac54e97c | |||
eee5587bab | |||
8475d04341 | |||
66c606a28f | |||
4267861034 | |||
57ad2e9773 | |||
158675f9c9 | |||
4f4323d7b7 | |||
873c82b84e | |||
35d1893275 | |||
caa9bf2604 | |||
b72c1822d5 | |||
d6b9a73570 | |||
61f768f306 | |||
8add58bdd3 | |||
075b15286f | |||
ca21b13ab9 | |||
9eac4a4191 | |||
c24bd2d615 | |||
99b50713ce | |||
fa0da8ec3f | |||
125b37b40a | |||
7e88142cdb | |||
1ed322b0c7 | |||
ba21676c2b | |||
de74dbcbac | |||
966d28cf5b | |||
cf9011c1ce | |||
5597c7b802 | |||
4a91d29490 | |||
d772a713a2 | |||
f0bd032cb9 | |||
68ca817fd7 | |||
7fd518a1e5 | |||
4d20715e26 | |||
2d5e28cfc2 | |||
cafa012bca | |||
88ab085846 | |||
7f2a9d99dd | |||
35be1a0d03 | |||
4f65f0379f | |||
06ae4bab43 | |||
9ce49848fd | |||
9d58e804a0 | |||
98a277713b | |||
f473d5c855 | |||
f4a7e0e187 | |||
39b5491c52 | |||
3ad0b7cdd7 | |||
1c759c2f7e | |||
a1cd963683 | |||
c277233855 | |||
0ddcb134a1 | |||
0bc07bf7fc | |||
558cbe62fc | |||
1904bd868d | |||
30633aa4ff | |||
7bfe455b1b | |||
a049542de2 | |||
6a95c8b21a | |||
13fbcbab9a | |||
78abe1ed8f | |||
2d19c57314 | |||
a1d77faa8d | |||
9de4d3172f | |||
a5ac2c3dfe | |||
06bc838e27 | |||
db70ad5aa0 | |||
6b9343371a | |||
e597bea35d | |||
237cb88d9d | |||
7e9e0f0729 | |||
87bf174bb8 | |||
7da1cfdd45 | |||
47cac7e71c | |||
f5df53f781 | |||
f16f6b808e | |||
cd28953324 | |||
da0e2ddb46 | |||
71ddf7ecf7 | |||
035a411800 | |||
fc0cff5a0c | |||
425160c390 | |||
75036f2418 | |||
f18157170b | |||
61e0ce4b97 | |||
25e3562300 | |||
5f92801860 | |||
8797134903 | |||
ad88f369bc | |||
c03877aa58 | |||
36ef520cf2 | |||
d1183c00af | |||
58451858fd | |||
4b44ce4482 | |||
1967389fdc | |||
bd913d83e1 | |||
c20574aa3b | |||
518bcc6527 | |||
ad8feafa5c | |||
5ac94667f9 | |||
4dcfdedb14 | |||
f76ba96613 | |||
6fdbaf9529 | |||
8ac7b06d68 | |||
4f63d0bb32 | |||
b143962dac | |||
9656828700 | |||
e680ec8664 | |||
b40b0397d7 | |||
932106d671 | |||
6260785b15 | |||
58a8b782c6 | |||
6f658fab35 | |||
e7fb5c5bc0 | |||
9442d4f6ee | |||
e542aa64ad | |||
5a4e1302f1 | |||
bbdf8ebad8 | |||
91463bcac0 | |||
23f1852337 | |||
edc4465d15 | |||
40e30defb3 | |||
478a5abff2 | |||
c00d5e8894 | |||
ff3b2314bf | |||
76906b04ee | |||
ee3fb40171 | |||
d13ab3106e | |||
f04d4d531a | |||
55b7afc023 | |||
5a033e7f12 | |||
8979e6e2a4 | |||
faaf7648a8 | |||
72db4e12cd | |||
62194271c0 | |||
087a2d0d6d | |||
57213c007f | |||
69d91413fc | |||
8cbaa83206 | |||
fa3419c7cc | |||
c9362b8802 | |||
cae269d4d6 | |||
1d7e96f3a4 | |||
8fabc142f2 | |||
95aa190f5f | |||
17116ecd02 | |||
83aeec51dc | |||
1fd6721d33 | |||
5782379897 | |||
1ccfae7552 | |||
31dbed7a1f | |||
b8dd642dc5 | |||
5326b3b81f | |||
b5d5e63486 | |||
f41a53c463 | |||
98a5c89d6b | |||
1a9756a86e | |||
01bb853d22 | |||
224bf37e68 | |||
14998bf952 | |||
60222b3948 | |||
e9a5b7e9af | |||
fec755dc25 | |||
60c098a5af | |||
881b5f4efd | |||
9c8f045db8 | |||
d06b24674f | |||
7299c4e96a | |||
beaf4194c2 | |||
877715aa22 | |||
a16a795300 | |||
7de7462548 | |||
3effb4c80a | |||
02d59cb047 | |||
6968feac7e | |||
c38e1ce43b | |||
efbdd08187 | |||
fcd88f8c3f | |||
546455eedc | |||
70bcfe9a9a | |||
0150cb2918 | |||
5c5b7047a0 | |||
b0c9d55658 | |||
c7e27c0080 | |||
28800625e4 | |||
666b3f2dc5 | |||
95cc859c9a | |||
e8f0b3d8dc | |||
7bfb4a9518 | |||
3f502eeb64 | |||
4dcd7bd5ce | |||
6821cf3707 | |||
8a68d025b5 | |||
6bc11ec727 | |||
b8daf9b9b7 | |||
63ef79f441 | |||
f83b5d8d07 | |||
cac52f739f | |||
02045dfd07 | |||
1a86fc5c29 | |||
ba82f322af | |||
2a40d8207e | |||
62a06281ab | |||
3a2e83682e | |||
b28496c7b6 | |||
bea5e02c2e | |||
de3eec47a0 | |||
08449b2468 | |||
84794ce862 | |||
21fc375ce0 | |||
f73cd9b6cf | |||
f674017610 | |||
48852b00f8 | |||
28480b1ee5 | |||
5916f438ca | |||
957a9f9c15 | |||
efafa6bf68 | |||
e88d53760d | |||
ccb56485d8 | |||
c91e51a445 | |||
1a6ab2d020 | |||
6dd96939c4 | |||
06aee5a899 | |||
f56302769c | |||
3e1d7e5e9b | |||
ccbf64678e | |||
a6ea47e1b0 | |||
dcddca16f3 | |||
25668a8d83 | |||
8068adb1bf | |||
c79af5b085 | |||
08057672d9 | |||
542c8b9f32 | |||
0cad44cd4e | |||
549afeacee | |||
e79322f670 | |||
10e7f72eab | |||
7c2ecd3340 | |||
29aaf625c7 | |||
eee832ce49 | |||
d8f3f87760 | |||
2df11b693c | |||
3805a27cd5 | |||
d09bd35646 | |||
5bbdcd9fb6 | |||
437a3444ec | |||
77e0633c38 | |||
ad5794c223 | |||
fdec5f7b6e | |||
|
fd1d32d314 | ||
0ca1a12cd4 | |||
6d456e5a7a | |||
07b6b5fca2 | |||
15579ef3cb | |||
d9dd2a59e7 | |||
d45d91340f | |||
039ff6ba42 | |||
81c6875382 | |||
1bbe078799 | |||
17082eb271 | |||
9e5e775c71 | |||
bf63bdb8ea | |||
a0c412bd66 | |||
d40ff7d14d | |||
85609be4b6 | |||
83fb6aaec3 | |||
22f546f14d | |||
54376ae84a | |||
2ac0f8fc52 | |||
bca7012d10 | |||
00b11da712 | |||
b438b1b1f1 | |||
5ab7301cbe | |||
b360335655 | |||
2cba8936c4 | |||
f8451c5514 | |||
462a9446bd | |||
a0a0d92169 | |||
7fb34c1b4a | |||
2ca345df8c | |||
2d53671fdf | |||
03b810ec75 | |||
3f4b88a2c6 | |||
0ad54c25a7 | |||
d97949cc3a | |||
b1a1824050 | |||
75fe994e95 | |||
9d020dd241 | |||
cbb2bfa73d | |||
0404950693 | |||
9948df0541 | |||
c53ab513a0 | |||
9e76f88c8f | |||
8da2a7d27a | |||
025a5a0db7 | |||
5fc391e5c0 | |||
5357486659 | |||
d8774ba7f7 | |||
1e7e304b43 | |||
17b7b09333 | |||
5f4b853764 | |||
6d0f2a6c36 | |||
ccdbf2efde | |||
e02eebba99 | |||
7d06fb5617 | |||
66053df28f | |||
6920db4c88 | |||
e37b2492e9 | |||
2435a765f0 | |||
f88e4181f1 | |||
5d2a1b0c17 | |||
1fff514e4e | |||
2f14e0f054 | |||
0c049a17f6 | |||
1390f96fdc | |||
1d7a3f5125 | |||
a9ebc52514 | |||
ca9eaf0249 | |||
7601746093 | |||
42f83170f7 | |||
9722cc06ff | |||
3d063a8ec2 | |||
b6719846bf | |||
9ed4187593 | |||
8c0bbe05ee | |||
c8b6d5053e | |||
4cf339cfc4 | |||
6fe23f270a | |||
c85fe76a48 | |||
4508b6d908 | |||
c74a70ce13 | |||
f5e88e44bf | |||
f11f92ba55 | |||
14d0173bd3 | |||
5b56c73528 | |||
87d336141c | |||
62555e6125 | |||
24418ba03d | |||
fa439c634f |
@@ -3,6 +3,7 @@ _mkgmtime
|
||||
_sh_denyno
|
||||
_sh_denyrd
|
||||
_sh_denyrw
|
||||
_spawnv
|
||||
aarch64
|
||||
advapi32
|
||||
armv8
|
||||
@@ -15,8 +16,11 @@ boost_asio_has_std_string_view
|
||||
bugprone
|
||||
cflags
|
||||
chrono
|
||||
clsid
|
||||
cmake_current_source_dir
|
||||
coinit_apartmentthreaded
|
||||
comdlg32
|
||||
conin$
|
||||
cppcoreguidelines
|
||||
cppdbg
|
||||
cppflags
|
||||
@@ -25,7 +29,11 @@ cpptrace
|
||||
cppvsdbg
|
||||
create_notraverse
|
||||
crypto_aead_xchacha20poly1305_ietf_npubbytes
|
||||
cspan
|
||||
cstdint
|
||||
curl_zstd
|
||||
curle_couldnt_resolve_host
|
||||
curlopt_aws_sigv4
|
||||
cxxflags
|
||||
cxxstd
|
||||
d_largefile64_source
|
||||
@@ -50,6 +58,7 @@ dcurl_staticlib
|
||||
dcurl_use_libpsl
|
||||
dcurl_use_libssh2
|
||||
dcurl_zlib
|
||||
dcurl_zstd
|
||||
ddebug
|
||||
decmult_gen_prec_bits
|
||||
decmult_window_size
|
||||
@@ -82,6 +91,7 @@ dspdlog_fmt_external
|
||||
dthreads_prefer_pthread_flag
|
||||
dunw_local_only
|
||||
duse_libidn2
|
||||
duse_nghttp2
|
||||
duuid_build_tests
|
||||
dwith_benchmark
|
||||
dwith_gflags
|
||||
@@ -93,6 +103,7 @@ endforeach
|
||||
endfunction
|
||||
eventlib
|
||||
expect_streq
|
||||
fallocate
|
||||
fallocate_impl
|
||||
fext
|
||||
fgetattr
|
||||
@@ -101,7 +112,10 @@ filebase
|
||||
flac_version
|
||||
flag_nopath
|
||||
flarge
|
||||
folderid
|
||||
fontconfig_version
|
||||
foob
|
||||
fooba
|
||||
freetype2_version
|
||||
fsetattr_x
|
||||
fusermount
|
||||
@@ -113,13 +127,18 @@ googletest
|
||||
gpath
|
||||
gtest_version
|
||||
has_setxattr
|
||||
hkey
|
||||
hresult
|
||||
httpapi
|
||||
httplib
|
||||
hwnd
|
||||
icudata
|
||||
icui18n
|
||||
icuuc
|
||||
inproc
|
||||
iostreams
|
||||
iphlpapi
|
||||
ipstream
|
||||
jthread
|
||||
libbitcoin
|
||||
libbitcoinsystem
|
||||
@@ -127,6 +146,7 @@ libcurl
|
||||
libdsm
|
||||
libevent
|
||||
libexample
|
||||
libexpat
|
||||
libfuse3
|
||||
libgmock
|
||||
libgtest
|
||||
@@ -139,25 +159,37 @@ libuuid
|
||||
libuuid_include_dirs
|
||||
libvlc
|
||||
linkflags
|
||||
localappdata
|
||||
lpbyte
|
||||
lpthread
|
||||
lptr
|
||||
lpwstr
|
||||
markdownlint
|
||||
mbig
|
||||
minio
|
||||
msvc
|
||||
msvcr120
|
||||
msys2
|
||||
mtune
|
||||
musl-libc
|
||||
mwindows
|
||||
nana
|
||||
ncrypt
|
||||
nlohmann
|
||||
nlohmann_json
|
||||
nmakeprg
|
||||
noappledouble
|
||||
nohup
|
||||
nominmax
|
||||
ntstatus
|
||||
nullptr
|
||||
nuspell_version
|
||||
oleaut32
|
||||
openal_version
|
||||
openssldir
|
||||
osascript
|
||||
osxfuse
|
||||
pistream
|
||||
pkgconfig
|
||||
plarge_integer
|
||||
plex
|
||||
@@ -166,12 +198,15 @@ project_enable_fontconfig
|
||||
project_enable_gtkmm
|
||||
project_enable_libdsm
|
||||
project_enable_nana
|
||||
project_macos_icns_name
|
||||
propgrid
|
||||
psecurity_descriptor
|
||||
pthreads
|
||||
pugi
|
||||
pugixml_project
|
||||
puint32
|
||||
pvoid
|
||||
pwhash
|
||||
pwstr
|
||||
rdrw
|
||||
remote_winfsp
|
||||
@@ -179,25 +214,34 @@ renterd
|
||||
richtext
|
||||
rocksdb_library
|
||||
rpcrt4
|
||||
runas
|
||||
s_igid
|
||||
s_isvtx
|
||||
s_iuid
|
||||
sddl_revision_1
|
||||
secp256k1
|
||||
secur32
|
||||
see_mask_nocloseprocess
|
||||
sfml_project
|
||||
shellexecuteinfoa
|
||||
shlwapi
|
||||
sigchld
|
||||
skynet
|
||||
source_subdir
|
||||
spdlog
|
||||
spdlog_project
|
||||
st_ctim
|
||||
startf_useshowwindow
|
||||
startupinfoa
|
||||
static-libgcc
|
||||
static-libstdc++
|
||||
stbuf
|
||||
stduuid_project
|
||||
strequal
|
||||
sw_shownoactivate
|
||||
ularge_integer
|
||||
uring
|
||||
url
|
||||
userenv
|
||||
utimens_impl
|
||||
utimensat
|
||||
@@ -213,6 +257,7 @@ wextra
|
||||
wfloat
|
||||
wformat=2
|
||||
winfsp
|
||||
winfsp_drive
|
||||
winhttp
|
||||
wininet
|
||||
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/
|
||||
.vs/
|
||||
Info.plist
|
||||
build*/
|
||||
compile_commands.json
|
||||
cspell.json
|
||||
.vs/
|
||||
support/Dockerfile
|
||||
dist/
|
||||
deps/
|
||||
dist/
|
||||
override.sh
|
||||
repertory.iss
|
||||
scripts/cleanup.cmd
|
||||
scripts/cleanup.sh
|
||||
version.rc
|
||||
support/Dockerfile
|
||||
version.cpp
|
||||
override.sh
|
||||
version.rc
|
||||
|
101
.jenkins_builds
@@ -5,57 +5,88 @@ pipeline {
|
||||
|
||||
environment {
|
||||
DEVELOPER_PRIVATE_KEY = "/.ci/repertory/cert/developer.priv"
|
||||
DEVELOPER_PUBLIC_KEY = "/.ci/repertory/cert/developer.pub"
|
||||
PROJECT_TEST_CONFIG_DIR = "/.ci/repertory/test_config"
|
||||
DEVELOPER_PUBLIC_KEY = "/.ci/repertory/cert/developer.pub"
|
||||
PROJECT_TEST_CONFIG_DIR = "/.ci/repertory/test"
|
||||
}
|
||||
|
||||
options {
|
||||
disableConcurrentBuilds()
|
||||
retry(2)
|
||||
skipDefaultCheckout()
|
||||
timestamps()
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('linux_x86_64') {
|
||||
stage('Build • Test • Deliver') {
|
||||
agent any
|
||||
|
||||
steps {
|
||||
retry(2) {
|
||||
sleep time: 5, unit: 'SECONDS'
|
||||
sh 'scripts/make_unix.sh'
|
||||
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('mingw64') {
|
||||
agent any
|
||||
|
||||
steps {
|
||||
retry(2) {
|
||||
sleep time: 5, unit: 'SECONDS'
|
||||
sh 'scripts/make_win32.sh'
|
||||
stage('linux_x86_64') {
|
||||
steps {
|
||||
script { retryWithBackoff(2, 5) { sh 'scripts/make_unix.sh' } }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('linux_aarch64') {
|
||||
agent any
|
||||
|
||||
steps {
|
||||
retry(2) {
|
||||
sleep time: 5, unit: 'SECONDS'
|
||||
sh 'scripts/make_unix.sh aarch64'
|
||||
stage('mingw64') {
|
||||
steps {
|
||||
script { retryWithBackoff(2, 5) { sh 'scripts/make_win32.sh' } }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('deliver') {
|
||||
agent any
|
||||
stage('linux_aarch64') {
|
||||
steps {
|
||||
script { retryWithBackoff(2, 5) { sh 'scripts/make_unix.sh aarch64' } }
|
||||
}
|
||||
}
|
||||
|
||||
steps {
|
||||
sh 'scripts/deliver.sh /mnt/repertory "" "" "" "" 1 1'
|
||||
sh 'scripts/deliver.sh /mnt/repertory "" aarch64'
|
||||
sh 'scripts/deliver.sh /mnt/repertory'
|
||||
stage('linux_x86_64_test') {
|
||||
steps {
|
||||
script { retryWithBackoff(2, 5) { sh 'scripts/run_tests.sh' } }
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
123
CHANGELOG.md
@@ -1,14 +1,135 @@
|
||||
# Changelog
|
||||
|
||||
## v2.1.0-rc
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
* Remote mounts must be upgraded to v2.1.0+ to support new authentication scheme
|
||||
|
||||
### Issues
|
||||
|
||||
* \#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
|
||||
|
||||
## 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
|
||||
|
||||
<!-- markdownlint-disable-next-line -->
|
||||
### BREAKING CHANGES
|
||||
|
||||
* Refactored `config.json` - will need to verify configuration settings prior to mounting
|
||||
|
||||
<!-- markdownlint-disable-next-line -->
|
||||
### Issues
|
||||
|
||||
* \#12 \[Unit Test\] Complete all providers unit tests
|
||||
* \#14 \[Unit Test\] SQLite mini-ORM unit tests and cleanup
|
||||
* \#16 Add support for bucket name in Sia provider
|
||||
* \#17 Update to common c++ build system
|
||||
|
@@ -3,6 +3,10 @@ cmake_minimum_required(VERSION 3.27)
|
||||
cmake_policy(SET CMP0135 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}
|
||||
DESCRIPTION ${PROJECT_DESC}
|
||||
HOMEPAGE_URL ${PROJECT_URL}
|
||||
@@ -47,6 +51,10 @@ if(PROJECT_IS_ARM64)
|
||||
add_definitions(-DPROJECT_IS_ARM64)
|
||||
endif()
|
||||
|
||||
if(PROJECT_IS_DARWIN)
|
||||
add_definitions(-DPROJECT_IS_DARWIN)
|
||||
endif()
|
||||
|
||||
if(PROJECT_IS_MINGW)
|
||||
option(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES "Enable path sizes of 32767 characters on Windows" OFF)
|
||||
if(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
|
||||
@@ -54,6 +62,10 @@ if(PROJECT_IS_MINGW)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (PROJECT_ENABLE_V2_ERRORS)
|
||||
add_definitions(-DPROJECT_ENABLE_V2_ERRORS)
|
||||
endif()
|
||||
|
||||
include(cmake/settings.cmake)
|
||||
|
||||
include(cmake/flags.cmake)
|
||||
@@ -107,6 +119,17 @@ if(PROJECT_BUILD)
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/version.cpp
|
||||
@ONLY
|
||||
)
|
||||
|
||||
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.iss.in")
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.iss.in
|
||||
${PROJECT_DIST_DIR}/../${PROJECT_NAME}.iss
|
||||
@ONLY
|
||||
)
|
||||
endif()
|
||||
|
||||
find_package(ICU REQUIRED COMPONENTS uc i18n io)
|
||||
link_libraries(ICU::uc ICU::i18n ICU::io)
|
||||
else()
|
||||
message(STATUS "-=[CMake Settings]=-")
|
||||
message(STATUS " C standard: ${CMAKE_C_STANDARD}")
|
||||
@@ -139,6 +162,7 @@ endif()
|
||||
-DPROJECT_COPYRIGHT=${PROJECT_COPYRIGHT}
|
||||
-DPROJECT_DESC=${PROJECT_DESC}
|
||||
-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_BOOST=${PROJECT_ENABLE_BOOST}
|
||||
-DPROJECT_ENABLE_CPP_HTTPLIB=${PROJECT_ENABLE_CPP_HTTPLIB}
|
||||
@@ -158,11 +182,15 @@ endif()
|
||||
-DPROJECT_FUSE=${PROJECT_FUSE}
|
||||
-DPROJECT_FUSE_INCLUDE_DIRS=${PROJECT_FUSE_INCLUDE_DIRS}
|
||||
-DPROJECT_GIT_REV=${PROJECT_GIT_REV}
|
||||
-DPROJECT_INTERFACE=1
|
||||
-DPROJECT_IS_ALPINE=${PROJECT_IS_ALPINE}
|
||||
-DPROJECT_IS_ARM64=${PROJECT_IS_ARM64}
|
||||
-DPROJECT_IS_DARWIN=${PROJECT_IS_DARWIN}
|
||||
-DPROJECT_IS_MINGW=${PROJECT_IS_MINGW}
|
||||
-DPROJECT_IS_MINGW_UNIX=${PROJECT_IS_MINGW_UNIX}
|
||||
-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_NAME=${PROJECT_NAME}
|
||||
-DPROJECT_RELEASE_ITER=${PROJECT_RELEASE_ITER}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
# 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:
|
||||
|
||||
|
847
README.md
@@ -1,117 +1,776 @@
|
||||
# Repertory
|
||||
|
||||
Repertory allows you to mount AWS S3 and Sia via FUSE on Linux ~~/OS X~~ or via WinFSP
|
||||
on Windows.
|
||||
Repertory allows you to mount **S3** and **Sia** storage as local drives using:
|
||||
|
||||
## Details and Features
|
||||
- **FUSE** (Linux/macOS)
|
||||
- **WinFSP** (Windows)
|
||||
|
||||
* Optimized for [Plex Media Server](https://www.plex.tv/)
|
||||
* 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)
|
||||
It supports:
|
||||
|
||||
## 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`
|
||||
* Linux `amd64`
|
||||
* ~~OS X Mojave and above~~
|
||||
* Windows 64-bit 10, 11
|
||||
1. [Quick Start (Sia Example)](#-quick-start-sia-example)
|
||||
2. [Details & Features](#-details-and-features)
|
||||
3. [Minimum Requirements](#-minimum-requirements)
|
||||
- [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)
|
||||
- [Sia Initial Configuration](#sia-initial-configuration)
|
||||
- [Sia Mounting](#sia-mounting)
|
||||
- [Sia Configuration File](#sia-configuration-file)
|
||||
8. [S3 Setup](#-s3)
|
||||
- [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`
|
||||
* Display mount configuration.
|
||||
* 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`.
|
||||
> 💡 Want to mount S3 instead?
|
||||
> Skip ahead to [S3 Setup](#-s3) — the process is almost identical.
|
||||
|
||||
### 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
|
||||
* `repertory --name storj -s3 /mnt/location`
|
||||
* Windows
|
||||
* `repertory.exe --name storj -s3 t:`
|
||||
#### Linux
|
||||
|
||||
## 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
|
||||
* 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`
|
||||
#### macOS
|
||||
|
||||
## Credits
|
||||
- Install [macFUSE 4.10.2](https://github.com/macfuse/macfuse/releases/download/macfuse-4.10.2/macfuse-4.10.2.dmg)
|
||||
|
||||
* [boost c++ libraries](https://www.boost.org/)
|
||||
* [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/)
|
||||
#### Windows
|
||||
|
||||
## 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 4.10.2](https://github.com/macfuse/macfuse/releases/download/macfuse-4.10.2/macfuse-4.10.2.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
|
||||
~/.local/repertory2/s3
|
||||
~/.local/repertory2/sia
|
||||
```
|
||||
|
||||
<!-- markdownlint-disable-next-line -->
|
||||
### Windows
|
||||
|
||||
``` shell
|
||||
%LOCALAPPDATA%\repertory2\s3
|
||||
%LOCALAPPDATA%\repertory2\sia
|
||||
```
|
||||
|
||||
**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**.
|
||||
|
||||
---
|
||||
|
||||
## ☁️ Sia
|
||||
|
||||
### 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
|
||||
|
||||
### 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
|
||||
|
||||
``` shell
|
||||
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
|
||||
-----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
|
||||
-Wconversion
|
||||
-Wdouble-promotion
|
||||
-Wduplicated-branches
|
||||
-Wduplicated-cond
|
||||
-Wextra
|
||||
-Wformat=2
|
||||
-Wlogical-op
|
||||
-Wmisleading-indentation
|
||||
-Wno-useless-cast
|
||||
-Wnon-virtual-dtor
|
||||
-Wnull-dereference
|
||||
-Wold-style-cast
|
||||
@@ -52,6 +48,15 @@ list(APPEND PROJECT_CXXFLAGS_LIST
|
||||
-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
|
||||
${PROJECT_COMMON_FLAG_LIST}
|
||||
-std=c${CMAKE_C_STANDARD}
|
||||
@@ -62,7 +67,7 @@ list(APPEND PROJECT_CXXFLAGS_LIST
|
||||
-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
|
||||
-static-libgcc
|
||||
-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(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
|
||||
-DCMAKE_BUILD_TYPE=${PROJECT_CMAKE_BUILD_TYPE}
|
||||
-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)
|
||||
target_compile_definitions(${name} PUBLIC
|
||||
${PROJECT_DEFINITIONS}
|
||||
@@ -12,6 +16,16 @@ function(set_common_target_options name)
|
||||
${PROJECT_EXTERNAL_BUILD_ROOT}/lib
|
||||
)
|
||||
|
||||
if (PROJECT_STATIC_LINK)
|
||||
target_compile_definitions(${name} PRIVATE U_STATIC_IMPLEMENTATION)
|
||||
endif()
|
||||
|
||||
target_link_directories(${name} PRIVATE
|
||||
ICU::uc
|
||||
ICU::i18n
|
||||
ICU::io
|
||||
)
|
||||
|
||||
target_include_directories(${name} AFTER PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/include
|
||||
${name}_INCLUDES
|
||||
@@ -31,11 +45,31 @@ function(add_project_executable2 name dependencies libraries headers sources is_
|
||||
list(APPEND sources ${PROJECT_WINDOWS_VERSION_RC})
|
||||
endif()
|
||||
|
||||
add_executable(${name}
|
||||
${headers}
|
||||
${sources}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/main.cpp
|
||||
)
|
||||
if (PROJECT_IS_DARWIN AND PROJECT_MACOS_ICNS_SOURCE AND "${name}" STREQUAL "${PROJECT_NAME}")
|
||||
set_source_files_properties(${PROJECT_MACOS_ICNS_SOURCE} PROPERTIES
|
||||
MACOSX_PACKAGE_LOCATION "Resources"
|
||||
)
|
||||
|
||||
add_executable(${name}
|
||||
MACOSX_BUNDLE
|
||||
${headers}
|
||||
${sources}
|
||||
${PROJECT_MACOS_ICNS_SOURCE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/main.cpp
|
||||
)
|
||||
|
||||
set_target_properties(${name} PROPERTIES
|
||||
MACOSX_BUNDLE TRUE
|
||||
MACOSX_BUNDLE_ICON_FILE "${PROJECT_MACOS_ICNS_NAME}"
|
||||
RESOURCE "${PROJECT_MACOS_ICNS_SOURCE}"
|
||||
)
|
||||
else()
|
||||
add_executable(${name}
|
||||
${headers}
|
||||
${sources}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/main.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
foreach(dependency ${dependencies})
|
||||
set_common_target_options(${dependency})
|
||||
|
@@ -1,20 +1,22 @@
|
||||
set(BINUTILS_HASH ae9a5789e23459e59606e6714723f2d3ffc31c03174191ef0d015bdf06007450)
|
||||
set(BOOST_HASH f55c340aa49763b1925ccf02b2e83f35fdcf634c9d5164a2acb87540173c741d)
|
||||
set(BINUTILS_HASH ce2017e059d63e67ddb9240e9d4ec49c2893605035cd60e92ad53177f4377237)
|
||||
set(BOOST2_HASH 7bd7ddceec1a1dfdcbdb3e609b60d01739c38390a5f956385a12f3122049f0ca)
|
||||
set(CPP_HTTPLIB_HASH 405abd8170f2a446fc8612ac635d0db5947c0d2e156e32603403a4496255ff00)
|
||||
set(CURL_HASH 5a231145114589491fc52da118f9c7ef8abee885d1cb1ced99c7290e9a352f07)
|
||||
set(EXPAT_HASH 372b18f6527d162fa9658f1c74d22a37429b82d822f5a1e1fc7e00f6045a06a2)
|
||||
set(GCC_HASH 7d376d445f93126dc545e2c0086d0f647c3094aae081cdb78f42ce2bc25e7293)
|
||||
set(GTEST_HASH 7b42b4d6ed48810c5362c265a17faebe90dc2373c885e5216439d37927f02926)
|
||||
set(ICU_HASH 925e6b4b8cf8856e0ac214f6f34e30dee63b7bb7a50460ab4603950eff48f89e)
|
||||
set(JSON_HASH 0d8ef5af7f9794e3263480193c491549b2ba6cc74bb018906202ada498a79406)
|
||||
set(BOOST_HASH 3621533e820dcab1e8012afd583c0c73cf0f77694952b81352bf38c1488f9cb4)
|
||||
set(CPP_HTTPLIB_HASH 410a1347ed6bcbcc4a19af8ed8ad3873fe9fa97731d52db845c4c78f3f9c31e6)
|
||||
set(CURL_HASH 2937cadde007aa3a52a17c21ac9153ea054700f37926d1d96602bf07e888c847)
|
||||
set(EXPAT_HASH 85372797ff0673a8fc4a6be16466bb5a0ca28c0dcf3c6f7ac1686b4a3ba2aabb)
|
||||
set(GCC_HASH 51b9919ea69c980d7a381db95d4be27edf73b21254eb13d752a08003b4d013b1)
|
||||
set(GTEST_HASH 65fab701d9829d38cb77c14acdc431d2108bfdbf8979e40eb8ae567edf10b27c)
|
||||
set(ICU_HASH a2c443404f00098e9e90acf29dc318e049d2dc78d9ae5f46efb261934a730ce2)
|
||||
set(INNOSETUP_HASH f3c42116542c4cc57263c5ba6c4feabfc49fe771f2f98a79d2f7628b8762723b)
|
||||
set(JSON_HASH 4b92eb0c06d10683f7447ce9406cb97cd4b453be18d7279320f7b2f025c10187)
|
||||
set(LIBSODIUM_HASH 8e5aeca07a723a27bbecc3beef14b0068d37e7fc0e97f51b3f1c82d2a58005c1)
|
||||
set(MINGW_HASH 3f66bce069ee8bed7439a1a13da7cb91a5e67ea6170f21317ac7f5794625ee10)
|
||||
set(OPENSSL_HASH e15dda82fe2fe8139dc2ac21a36d4ca01d5313c75f99f46c4e8a27709b7294bf)
|
||||
set(MINGW_HASH 5afe822af5c4edbf67daaf45eec61d538f49eef6b19524de64897c6b95828caf)
|
||||
set(OPENSSL_HASH 529043b15cffa5f36077a4d0af83f3de399807181d607441d734196d889b641f)
|
||||
set(PKG_CONFIG_HASH 6fc69c01688c9458a57eb9a1664c9aba372ccda420a02bf4429fe610e7e7d591)
|
||||
set(PUGIXML_HASH 2f10e276870c64b1db6809050a75e11a897a8d7456c4be5c6b2e35a11168a015)
|
||||
set(ROCKSDB_HASH 9b810c81731835fda0d4bbdb51d3199d901fa4395733ab63752d297da84c5a47)
|
||||
set(SPDLOG_HASH 9962648c9b4f1a7bbc76fd8d9172555bad1871fdb14ff4f842ef87949682caa5)
|
||||
set(SQLITE_HASH 77823cb110929c2bcb0f5d48e4833b5c59a8a6e40cdea3936b99e199dbbe5784)
|
||||
set(PUGIXML_HASH 655ade57fa703fb421c2eb9a0113b5064bddb145d415dd1f88c79353d90d511a)
|
||||
set(ROCKSDB_HASH afccfab496556904900afacf7d99887f1d50cb893e5d2288bd502db233adacac)
|
||||
set(SPDLOG_HASH 15a04e69c222eb6c01094b5c7ff8a249b36bb22788d72519646fb85feb267e67)
|
||||
set(SQLITE_HASH 9ad6d16cbc1df7cd55c8b55127c82a9bca5e9f287818de6dc87e04e73599d754)
|
||||
set(STDUUID_HASH b1176597e789531c38481acbbed2a6894ad419aab0979c10410d59eb0ebf40d3)
|
||||
set(WINFSP_HASH 073a70e00f77423e34bed98b86e600def93393ba5822204fac57a29324db9f7a)
|
||||
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(OPENSSL_USE_STATIC_LIBS ${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(ICU_USE_STATIC_LIBS ${PROJECT_STATIC_LINK})
|
||||
|
||||
include(cmake/libraries/icu.cmake)
|
||||
include(cmake/libraries/openssl.cmake)
|
||||
|
||||
include(cmake/libraries/boost.cmake)
|
||||
|
||||
include(cmake/libraries/cpp_httplib.cmake)
|
||||
include(cmake/libraries/curl.cmake)
|
||||
include(cmake/libraries/fuse.cmake)
|
||||
@@ -59,7 +63,7 @@ if(PROJECT_BUILD)
|
||||
winspool
|
||||
ws2_32
|
||||
)
|
||||
else()
|
||||
elseif(NOT PROJECT_IS_DARWIN)
|
||||
link_libraries(
|
||||
uring
|
||||
)
|
||||
|
@@ -39,6 +39,14 @@ if(PROJECT_ENABLE_BOOST)
|
||||
wserialization
|
||||
)
|
||||
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}
|
||||
REQUIRED
|
||||
COMPONENTS
|
||||
@@ -120,17 +128,23 @@ if(PROJECT_ENABLE_BOOST)
|
||||
--with-libraries=atomic,chrono,date_time,filesystem,iostreams,locale,log,program_options,random,regex,serialization,system,test,thread
|
||||
BUILD_COMMAND
|
||||
./b2
|
||||
-j1
|
||||
-sNO_BZIP2=1
|
||||
-j$ENV{CMAKE_BUILD_PARALLEL_LEVEL}
|
||||
${BOOST_BUILD_ARGS}
|
||||
INSTALL_COMMAND
|
||||
./b2
|
||||
-j1
|
||||
-sNO_BZIP2=1
|
||||
-j$ENV{CMAKE_BUILD_PARALLEL_LEVEL}
|
||||
${BOOST_BUILD_ARGS}
|
||||
install
|
||||
)
|
||||
|
||||
list(APPEND PROJECT_DEPENDENCIES boost_project)
|
||||
|
||||
if (PROJECT_IS_DARWIN)
|
||||
add_dependencies(boost_project icu_project)
|
||||
endif()
|
||||
|
||||
if (NOT CMAKE_HOST_WIN32)
|
||||
add_dependencies(boost_project openssl_project)
|
||||
endif()
|
||||
|
@@ -15,10 +15,14 @@ if(PROJECT_ENABLE_CPP_HTTPLIB)
|
||||
CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
|
||||
-DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
|
||||
-DBUILD_STATIC_LIBS=ON
|
||||
-DHTTPLIB_REQUIRE_OPENSSL=${PROJECT_ENABLE_OPENSSL}
|
||||
-DHTTPLIB_REQUIRE_ZLIB=ON
|
||||
-DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
|
||||
-DHTTPLIB_REQUIRE_BROTLI=OFF
|
||||
-DHTTPLIB_REQUIRE_OPENSSL=ON
|
||||
-DHTTPLIB_REQUIRE_ZLIB=ON
|
||||
-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}
|
||||
)
|
||||
|
||||
|
@@ -18,14 +18,18 @@ if(PROJECT_ENABLE_CURL)
|
||||
URL ${PROJECT_3RD_PARTY_DIR}/curl-${CURL_VERSION}.tar.gz
|
||||
URL_HASH SHA256=${CURL_HASH}
|
||||
LIST_SEPARATOR |
|
||||
CMAKE_ARGS
|
||||
${PROJECT_EXTERNAL_CMAKE_FLAGS}
|
||||
-DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
|
||||
-DBUILD_STATIC_LIBS=ON
|
||||
BUILD_COMMAND
|
||||
${CMAKE_COMMAND} --build . -- -j$ENV{CMAKE_BUILD_PARALLEL_LEVEL}
|
||||
CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
|
||||
-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_LIBS=ON
|
||||
-DBUILD_TESTING=OFF
|
||||
-DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
|
||||
-DCURL_BROTLI=OFF
|
||||
-DCURL_CA_BUNDLE=./cacert.pem
|
||||
-DCURL_CA_FALLBACK=ON
|
||||
-DCURL_DISABLE_LDAP=ON
|
||||
@@ -33,10 +37,13 @@ if(PROJECT_ENABLE_CURL)
|
||||
-DCURL_USE_LIBSSH2=OFF
|
||||
-DCURL_USE_OPENSSL=${PROJECT_ENABLE_OPENSSL}
|
||||
-DCURL_ZLIB=ON
|
||||
-DCURL_ZSTD=OFF
|
||||
-DENABLE_CURL_MANUAL=OFF
|
||||
-DENABLE_THREADED_RESOLVER=ON
|
||||
-DOPENSSL_ROOT_DIR=${OPENSSL_ROOT_DIR}
|
||||
-DOPENSSL_USE_STATIC_LIBS=${OPENSSL_USE_STATIC_LIBS}
|
||||
-DUSE_LIBIDN2=OFF
|
||||
-DUSE_NGHTTP2=OFF
|
||||
-DZLIB_USE_STATIC_LIBS=${ZLIB_USE_STATIC_LIBS}
|
||||
)
|
||||
|
||||
|
@@ -20,17 +20,25 @@ if(PROJECT_ENABLE_FUSE AND NOT PROJECT_IS_MINGW)
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
pkg_check_modules(LIBFUSE3 fuse3>=3.0.0)
|
||||
if(LIBFUSE3_FOUND)
|
||||
set(PROJECT_FUSE fuse3)
|
||||
set(PROJECT_FUSE_INCLUDE_DIRS ${LIBFUSE3_INCLUDE_DIRS})
|
||||
if (PROJECT_IS_DARWIN)
|
||||
find_library(OSXFUSE NO_CACHE NAMES OSXFUSE)
|
||||
if (NOT OSXFUSE)
|
||||
message(FATAL_ERROR "FUSE for macOS not found (https://macfuse.github.io)")
|
||||
endif ()
|
||||
set(PROJECT_FUSE fuse2)
|
||||
else()
|
||||
pkg_check_modules(LIBFUSE2 fuse>=2.9.0)
|
||||
if(LIBFUSE2_FOUND)
|
||||
set(PROJECT_FUSE fuse2)
|
||||
set(PROJECT_FUSE_INCLUDE_DIRS ${LIBFUSE2_INCLUDE_DIRS})
|
||||
pkg_check_modules(LIBFUSE3 fuse3>=3.0.0)
|
||||
if(LIBFUSE3_FOUND)
|
||||
set(PROJECT_FUSE fuse3)
|
||||
set(PROJECT_FUSE_INCLUDE_DIRS ${LIBFUSE3_INCLUDE_DIRS})
|
||||
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()
|
||||
|
24
cmake/libraries/icu.cmake
Normal file
@@ -0,0 +1,24 @@
|
||||
if(PROJECT_IS_DARWIN 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}
|
||||
-DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
|
||||
-DBUILD_STATIC_LIBS=ON
|
||||
-DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
|
||||
-DJSON_BuildTests=OFF
|
||||
-DJSON_Install=ON
|
||||
-DJSON_MultipleHeaders=OFF
|
||||
|
@@ -15,6 +15,12 @@ if(PROJECT_ENABLE_OPENSSL)
|
||||
elseif(NOT PROJECT_IS_MINGW)
|
||||
if(PROJECT_IS_MINGW)
|
||||
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)
|
||||
set(OPENSSL_COMPILE_TYPE linux-aarch64)
|
||||
else()
|
||||
|
@@ -20,6 +20,7 @@ if(PROJECT_ENABLE_PUGIXML)
|
||||
CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
|
||||
-DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
|
||||
-DBUILD_STATIC_LIBS=ON
|
||||
-DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
|
||||
)
|
||||
|
||||
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_HASH SHA256=${ROCKSDB_HASH}
|
||||
LIST_SEPARATOR |
|
||||
BUILD_COMMAND
|
||||
${CMAKE_COMMAND} --build . -- -j$ENV{CMAKE_BUILD_PARALLEL_LEVEL}
|
||||
CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
|
||||
-DBUILD_SHARED_LIBS=OFF
|
||||
-DBUILD_STATIC_LIBS=ON
|
||||
-DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
|
||||
-DFAIL_ON_WARNINGS=OFF
|
||||
-DPORTABLE=1
|
||||
-DROCKSDB_BUILD_SHARED=OFF
|
||||
-DROCKSDB_INSTALL_ON_WINDOWS=ON
|
||||
-DWITH_BENCHMARK=OFF
|
||||
-DWITH_BENCHMARK_TOOLS=OFF
|
||||
-DWITH_BZ2=OFF
|
||||
-DWITH_CORE_TOOLS=OFF
|
||||
-DWITH_EXAMPLES=OFF
|
||||
-DWITH_GFLAGS=OFF
|
||||
@@ -31,4 +35,4 @@ if(PROJECT_ENABLE_ROCKSDB)
|
||||
|
||||
list(APPEND PROJECT_DEPENDENCIES rocksdb_project)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
@@ -15,6 +15,7 @@ if(PROJECT_ENABLE_SPDLOG)
|
||||
LIST_SEPARATOR |
|
||||
CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
|
||||
-DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
|
||||
-DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
|
||||
-DSPDLOG_BUILD_EXAMPLE=OFF
|
||||
-DSPDLOG_FMT_EXTERNAL=OFF
|
||||
-DSPDLOG_FMT_EXTERNAL_HO=OFF
|
||||
|
@@ -2,7 +2,7 @@ if(PROJECT_ENABLE_SQLITE)
|
||||
if(PROJECT_BUILD)
|
||||
add_definitions(-DPROJECT_ENABLE_SQLITE)
|
||||
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})
|
||||
link_libraries(${SQLITE3_LIBRARIES})
|
||||
else()
|
||||
|
@@ -16,6 +16,7 @@ if(PROJECT_ENABLE_STDUUID)
|
||||
CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
|
||||
-DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
|
||||
-DBUILD_STATIC_LIBS=ON
|
||||
-DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
|
||||
-DUUID_BUILD_TESTS=OFF
|
||||
-DUUID_ENABLE_INSTALL=ON
|
||||
-DUUID_USING_CXX20_SPAN=ON
|
||||
|
@@ -10,6 +10,7 @@ if (PROJECT_ENABLE_TESTING)
|
||||
CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
|
||||
-DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
|
||||
-DBUILD_STATIC_LIBS=ON
|
||||
-DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
|
||||
)
|
||||
|
||||
list(APPEND PROJECT_DEPENDENCIES gtest_project)
|
||||
|
@@ -2,9 +2,9 @@ if(PROJECT_ENABLE_WINFSP AND PROJECT_IS_MINGW)
|
||||
if(PROJECT_BUILD)
|
||||
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)
|
||||
link_libraries(winfsp-a64)
|
||||
|
@@ -2,10 +2,6 @@ if(MSVC)
|
||||
message(FATAL_ERROR "MSVC will not be supported")
|
||||
endif()
|
||||
|
||||
if(UNIX AND APPLE)
|
||||
message(FATAL_ERROR "Apple is not currently supported")
|
||||
endif()
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
|
||||
message(FATAL_ERROR "FreeBSD is not currently supported")
|
||||
endif()
|
||||
@@ -13,3 +9,15 @@ endif()
|
||||
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")
|
||||
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 88)
|
||||
set(BOOST_PATCH_VERSION 0)
|
||||
set(BOOST2_MAJOR_VERSION 1)
|
||||
set(BOOST2_MINOR_VERSION 76)
|
||||
set(BOOST2_PATCH_VERSION 0)
|
||||
set(BOOST_MAJOR_VERSION 1)
|
||||
set(BOOST_MINOR_VERSION 87)
|
||||
set(BOOST_PATCH_VERSION 0)
|
||||
set(CPP_HTTPLIB_VERSION 0.18.1)
|
||||
set(CURL2_VERSION 8_11_0)
|
||||
set(CURL_VERSION 8.11.0)
|
||||
set(EXPAT2_VERSION 2_6_4)
|
||||
set(EXPAT_VERSION 2.6.4)
|
||||
set(GCC_VERSION 14.2.0)
|
||||
set(GTEST_VERSION 1.15.2)
|
||||
set(ICU_VERSION 75-1)
|
||||
set(JSON_VERSION 3.11.3)
|
||||
set(CPP_HTTPLIB_VERSION 0.23.1)
|
||||
set(CURL_VERSION 8.15.0)
|
||||
set(CURL2_VERSION 8_15_0)
|
||||
set(EXPAT_VERSION 2.7.1)
|
||||
set(EXPAT2_VERSION 2_7_1)
|
||||
set(GCC_VERSION 15.1.0)
|
||||
set(GTEST_VERSION 1.17.0)
|
||||
set(ICU_VERSION 76-1)
|
||||
set(INNOSETUP_VERSION 6.4.3)
|
||||
set(JSON_VERSION 3.12.0)
|
||||
set(LIBSODIUM_VERSION 1.0.20)
|
||||
set(MESA_VERSION 23.3.3)
|
||||
set(MINGW_VERSION 11.0.1)
|
||||
set(OPENSSL_VERSION 3.4.0)
|
||||
set(MINGW_VERSION 13.0.0)
|
||||
set(OPENSSL_VERSION 3.5.1)
|
||||
set(PKG_CONFIG_VERSION 0.29.2)
|
||||
set(PUGIXML_VERSION 1.14)
|
||||
set(ROCKSDB_VERSION 9.7.4)
|
||||
set(SPDLOG_VERSION 1.15.0)
|
||||
set(SQLITE2_VERSION 3.46.1)
|
||||
set(SQLITE_VERSION 3460100)
|
||||
set(PUGIXML_VERSION 1.15)
|
||||
set(ROCKSDB_VERSION 10.4.2)
|
||||
set(SPDLOG_VERSION 1.15.3)
|
||||
set(SQLITE_VERSION 3500300)
|
||||
set(SQLITE2_VERSION 3.50.3)
|
||||
set(STDUUID_VERSION 1.2.3)
|
||||
set(WINFSP_VERSION 2.1.25156)
|
||||
set(WINFSP2_VERSION 2.1)
|
||||
set(ZLIB_VERSION 1.3.1)
|
||||
|
12
config.sh
@@ -5,12 +5,15 @@ PROJECT_NAME="repertory"
|
||||
PROJECT_COMPANY_NAME="https://git.fifthgrid.com/blockstorage"
|
||||
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_MACOS_BUNDLE_ID="com.fifthgrid.blockstorage.repertory"
|
||||
PROJECT_MACOS_ICNS_NAME="icon.icns"
|
||||
|
||||
PROJECT_MAJOR_VERSION=2
|
||||
PROJECT_MINOR_VERSION=0
|
||||
PROJECT_REVISION_VERSION=2
|
||||
PROJECT_MINOR_VERSION=1
|
||||
PROJECT_REVISION_VERSION=0
|
||||
PROJECT_RELEASE_NUM=0
|
||||
PROJECT_RELEASE_ITER=rc
|
||||
|
||||
@@ -19,6 +22,9 @@ PROJECT_APP_LIST=(${PROJECT_NAME})
|
||||
PROJECT_PRIVATE_KEY=${DEVELOPER_PRIVATE_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_BACKWARD_CPP=OFF
|
||||
|
@@ -1,4 +1,5 @@
|
||||
FROM arm64v8/alpine:3.20.3
|
||||
#comment
|
||||
FROM arm64v8/alpine:3.21.4
|
||||
MAINTAINER Scott E. Graves <scott.e.graves@protonmail.com>
|
||||
CMD bash
|
||||
|
||||
@@ -30,7 +31,7 @@ RUN apk add \
|
||||
gflags \
|
||||
gflags-dev \
|
||||
git \
|
||||
gtkmm3-dev \
|
||||
git-lfs \
|
||||
icu-dev \
|
||||
icu-libs \
|
||||
icu-static \
|
||||
@@ -69,7 +70,6 @@ RUN apk add \
|
||||
tcl \
|
||||
tcl-dev \
|
||||
texinfo \
|
||||
vlc-dev \
|
||||
wget \
|
||||
xz \
|
||||
xz-dev \
|
||||
@@ -82,3 +82,6 @@ RUN apk add \
|
||||
zstd-libs \
|
||||
zstd-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.21.4
|
||||
MAINTAINER Scott E. Graves <scott.e.graves@protonmail.com>
|
||||
CMD bash
|
||||
|
||||
@@ -30,6 +31,7 @@ RUN apk add \
|
||||
gflags \
|
||||
gflags-dev \
|
||||
git \
|
||||
git-lfs \
|
||||
icu-dev \
|
||||
icu-libs \
|
||||
icu-static \
|
||||
@@ -80,3 +82,6 @@ RUN apk add \
|
||||
zstd-libs \
|
||||
zstd-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
|
||||
FROM alpine:3.20.3
|
||||
FROM alpine:3.21.4
|
||||
|
||||
RUN apk update
|
||||
RUN apk upgrade
|
||||
@@ -12,12 +12,14 @@ RUN apk add \
|
||||
bzip2 \
|
||||
clang17-extra-tools \
|
||||
cmake \
|
||||
curl \
|
||||
file \
|
||||
flex \
|
||||
g++ \
|
||||
gcc \
|
||||
gettext \
|
||||
git \
|
||||
git-lfs \
|
||||
gmp \
|
||||
gmp-dev \
|
||||
gperf \
|
||||
@@ -42,6 +44,7 @@ RUN apk add \
|
||||
ruby \
|
||||
texinfo \
|
||||
unzip \
|
||||
xvfb \
|
||||
wget \
|
||||
wine \
|
||||
xz \
|
||||
@@ -101,6 +104,39 @@ RUN echo -e \
|
||||
"system = 'windows'\n"\
|
||||
> ${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" ]
|
||||
|
||||
RUN mkdir -p \
|
||||
@@ -350,9 +386,9 @@ RUN cd /3rd_party/mingw64 && sha256sum -c ./expat-${MY_EXPAT_VERSION}.tar.gz.sha
|
||||
|
||||
ARG FONTCONFIG_VERSION
|
||||
ENV MY_FONTCONFIG_VERSION=${FONTCONFIG_VERSION}
|
||||
RUN if [ -f "/3rd_party/fontconfig-${MY_FONTCONFIG_VERSION}.tar.gz" ]; then \
|
||||
cd /3rd_party && sha256sum -c ./fontconfig-${MY_FONTCONFIG_VERSION}.tar.gz.sha256 && cd - \
|
||||
&& tar xvzf /3rd_party/fontconfig-${MY_FONTCONFIG_VERSION}.tar.gz \
|
||||
RUN if [ -f "/3rd_party/fontconfig-${MY_FONTCONFIG_VERSION}.tar.xz" ]; then \
|
||||
cd /3rd_party && sha256sum -c ./fontconfig-${MY_FONTCONFIG_VERSION}.tar.xz.sha256 && cd - \
|
||||
&& tar xvJf /3rd_party/fontconfig-${MY_FONTCONFIG_VERSION}.tar.xz \
|
||||
&& cd fontconfig-${MY_FONTCONFIG_VERSION} \
|
||||
&& meson setup \
|
||||
--cross-file ${MY_TOOLCHAIN_FILE_MESON} \
|
||||
@@ -671,12 +707,15 @@ RUN if [ -f "/3rd_party/curl-${MY_CURL_VERSION}.tar.gz" ]; then \
|
||||
&& cd build \
|
||||
&& cmake .. \
|
||||
-DBUILD_CURL_EXE=ON \
|
||||
-DBUILD_LIBCURL_DOCS=OFF \
|
||||
-DBUILD_MISC_DOCS=OFF \
|
||||
-DBUILD_SHARED_LIBS=OFF \
|
||||
-DBUILD_STATIC_LIBS=ON \
|
||||
-DBUILD_TESTING=OFF \
|
||||
-DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
|
||||
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
|
||||
-DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
|
||||
-DCURL_BROTLI=OFF \
|
||||
-DCURL_CA_BUNDLE=./cacert.pem \
|
||||
-DCURL_CA_FALLBACK=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_OPENSSL=ON \
|
||||
-DCURL_ZLIB=ON \
|
||||
-DENABLE_CURL_MANUAL=OFF \
|
||||
-DENABLE_THREADED_RESOLVER=ON \
|
||||
-DOPENSSL_USE_STATIC_LIBS=ON \
|
||||
-DUSE_LIBIDN2=OFF \
|
||||
@@ -711,6 +751,9 @@ RUN if [ -f "/3rd_party/cpp-httplib-${MY_CPP_HTTPLIB_VERSION}.tar.gz" ]; then \
|
||||
-DHTTPLIB_REQUIRE_OPENSSL=ON \
|
||||
-DHTTPLIB_REQUIRE_ZLIB=ON \
|
||||
-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 install \
|
||||
&& cd ${MY_WORKDIR} \
|
||||
@@ -791,6 +834,7 @@ RUN if [ -f "/3rd_party/libevent-${MY_LIBEVENT_VERSION}-stable.tar.gz" ]; then \
|
||||
&& cmake .. \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-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_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
|
||||
-DEVENT__DISABLE_OPENSSL=ON \
|
||||
@@ -880,6 +924,7 @@ RUN if [ -f "/3rd_party/rocksdb-${MY_ROCKSDB_VERSION}.tar.gz" ]; then \
|
||||
-DROCKSDB_INSTALL_ON_WINDOWS=ON \
|
||||
-DWITH_BENCHMARK=OFF \
|
||||
-DWITH_BENCHMARK_TOOLS=OFF \
|
||||
-DWITH_BZ2=OFF \
|
||||
-DWITH_CORE_TOOLS=OFF \
|
||||
-DWITH_EXAMPLES=OFF \
|
||||
-DWITH_GFLAGS=OFF \
|
||||
@@ -1111,6 +1156,33 @@ RUN if [ -f "/3rd_party/libdsm-${MY_LIBDSM_VERSION}.tar.gz" ]; then \
|
||||
&& rm -r libdsm-${MY_LIBDSM_VERSION} \
|
||||
; 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} \
|
||||
&& 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/ \
|
||||
${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
|
||||
|
@@ -1,7 +1,20 @@
|
||||
set(CMAKE_CXX_FLAGS "-include common.hpp ${CMAKE_CXX_FLAGS}")
|
||||
|
||||
if (PROJECT_IS_DARWIN)
|
||||
configure_file(
|
||||
${CMAKE_SOURCE_DIR}/${PROJECT_NAME}/Info.plist.in
|
||||
${CMAKE_SOURCE_DIR}/${PROJECT_NAME}/Info.plist
|
||||
@ONLY
|
||||
)
|
||||
endif()
|
||||
|
||||
add_project_library(lib${PROJECT_NAME} "" "" "${PROJECT_ADDITIONAL_SOURCES}")
|
||||
|
||||
add_project_executable(${PROJECT_NAME} lib${PROJECT_NAME} lib${PROJECT_NAME})
|
||||
if (PROJECT_IS_DARWIN)
|
||||
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})
|
||||
|
171
repertory.iss.in
Normal file
@@ -0,0 +1,171 @@
|
||||
; Script generated by the Inno Setup Script Wizard.
|
||||
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
|
||||
|
||||
#define MyAppName "repertory"
|
||||
#define MyAppVersion "@PROJECT_MAJOR_VERSION@.@PROJECT_MINOR_VERSION@.@PROJECT_REVISION_VERSION@-@PROJECT_RELEASE_ITER@_@PROJECT_GIT_REV@"
|
||||
#define MyAppPublisher "BlockStorage"
|
||||
#define MyAppURL "https://git.fifthgrid.com/BlockStorage/repertory"
|
||||
#define MyAppExeName "repertory.exe"
|
||||
|
||||
[Setup]
|
||||
; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
|
||||
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
|
||||
AppId={{BD165823-1DEF-4D23-87DC-3D7A9BB73A00}
|
||||
AppName={#MyAppName}
|
||||
AppPublisher={#MyAppPublisher}
|
||||
AppPublisherURL={#MyAppURL}
|
||||
AppSupportURL={#MyAppURL}
|
||||
AppUpdatesURL={#MyAppURL}
|
||||
AppVersion={#MyAppVersion}
|
||||
ArchitecturesAllowed=x64compatible
|
||||
ArchitecturesInstallIn64BitMode=x64compatible
|
||||
DefaultDirName={autopf}\{#MyAppName}
|
||||
DefaultGroupName={#MyAppName}
|
||||
DisableProgramGroupPage=yes
|
||||
LicenseFile=repertory\LICENSE.md
|
||||
OutputBaseFilename=repertory_{#MyAppVersion}_windows_@PROJECT_MARCH@_setup
|
||||
PrivilegesRequired=admin
|
||||
SolidCompression=yes
|
||||
SetupIconFile=repertory\icon.ico
|
||||
UninstallDisplayIcon={app}\icon.ico
|
||||
WizardStyle=modern
|
||||
|
||||
[code]
|
||||
const
|
||||
SMTO_ABORTIFHUNG = $0002;
|
||||
WM_SETTINGCHANGE = $001A;
|
||||
|
||||
type
|
||||
LPARAM = LongWord;
|
||||
LRESULT = LongWord;
|
||||
WPARAM = LongWord;
|
||||
|
||||
function SendMessageTimeout(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: AnsiString;
|
||||
fuFlags: UINT; uTimeout: UINT; out lpdwResult: DWORD): LRESULT;
|
||||
external 'SendMessageTimeoutA@user32.dll stdcall';
|
||||
|
||||
procedure RefreshEnvironment();
|
||||
var
|
||||
EnvStr: AnsiString;
|
||||
R: DWORD;
|
||||
begin
|
||||
EnvStr := 'Environment' + #0;
|
||||
|
||||
SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0,
|
||||
EnvStr, SMTO_ABORTIFHUNG, 5000, R);
|
||||
end;
|
||||
|
||||
function NormalizeSemicolons(S: string): string;
|
||||
begin
|
||||
while Pos(';;', S) > 0 do
|
||||
StringChange(S, ';;', ';');
|
||||
Result := S;
|
||||
end;
|
||||
|
||||
procedure AddAppToPath();
|
||||
var
|
||||
OldPath, NewPath, FinalPath: string;
|
||||
begin
|
||||
if not RegQueryStringValue(HKLM,
|
||||
'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
|
||||
'Path', OldPath)
|
||||
then
|
||||
OldPath := '';
|
||||
|
||||
NewPath := ExpandConstant('{app}');
|
||||
if Pos(LowerCase(NewPath), LowerCase(OldPath)) = 0 then
|
||||
begin
|
||||
if (OldPath <> '') and (Copy(OldPath, Length(OldPath), 1) <> ';') then
|
||||
OldPath := OldPath + ';';
|
||||
|
||||
FinalPath := NormalizeSemicolons(OldPath + NewPath + ';');
|
||||
RegWriteExpandStringValue(HKLM,
|
||||
'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
|
||||
'Path', FinalPath);
|
||||
|
||||
RefreshEnvironment();
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure RemoveAppFromPath();
|
||||
var
|
||||
OldPath, NewPath, Token, Remainder, FinalPath: string;
|
||||
p: Integer;
|
||||
begin
|
||||
if not RegQueryStringValue(HKLM,
|
||||
'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
|
||||
'Path', OldPath) then
|
||||
Exit;
|
||||
|
||||
NewPath := ExpandConstant('{app}');
|
||||
Remainder := OldPath;
|
||||
FinalPath := '';
|
||||
|
||||
while Length(Remainder) > 0 do
|
||||
begin
|
||||
p := Pos(';', Remainder);
|
||||
if p = 0 then
|
||||
begin
|
||||
Token := Remainder;
|
||||
Remainder := '';
|
||||
end
|
||||
else
|
||||
begin
|
||||
Token := Copy(Remainder, 1, p - 1);
|
||||
Delete(Remainder, 1, p);
|
||||
end;
|
||||
|
||||
Token := Trim(Token);
|
||||
if (Token <> '') and (CompareText(Token, NewPath) <> 0) then
|
||||
begin
|
||||
if (FinalPath <> '') and (FinalPath[Length(FinalPath)] <> ';') then
|
||||
FinalPath := FinalPath + ';';
|
||||
FinalPath := FinalPath + Token;
|
||||
end;
|
||||
end;
|
||||
|
||||
while Pos(';;', FinalPath) > 0 do
|
||||
StringChange(FinalPath, ';;', ';');
|
||||
if (FinalPath <> '') and (FinalPath[Length(FinalPath)] = ';') then
|
||||
Delete(FinalPath, Length(FinalPath), 1);
|
||||
|
||||
RegWriteExpandStringValue(HKLM,
|
||||
'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
|
||||
'Path', FinalPath);
|
||||
|
||||
RefreshEnvironment();
|
||||
end;
|
||||
|
||||
procedure CurStepChanged(CurStep: TSetupStep);
|
||||
begin
|
||||
if CurStep = ssPostInstall then
|
||||
begin
|
||||
AddAppToPath();
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure DeinitializeUninstall();
|
||||
begin
|
||||
RemoveAppFromPath();
|
||||
end;
|
||||
|
||||
[Languages]
|
||||
Name: "english"; MessagesFile: "compiler:Default.isl"
|
||||
|
||||
[Components]
|
||||
Name: "main"; Description: "Repertory Core"; Types: full compact custom; Flags: fixed
|
||||
Name: "winfsp"; Description: "WinFSP v@WINFSP_VERSION@"; Types: full custom
|
||||
|
||||
[Files]
|
||||
Source: "repertory\*.*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs; Components: main
|
||||
Source: "3rd_party\winfsp-@WINFSP_VERSION@.msi"; DestDir: "{app}"; Flags: ignoreversion; Components: winfsp
|
||||
|
||||
[Icons]
|
||||
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Parameters: "-ui --hidden"; IconFilename: "{app}\assets\icon.ico"
|
||||
|
||||
[Run]
|
||||
Filename: "msiexec.exe"; WorkingDir: "{app}"; Parameters: "/i winfsp-@WINFSP_VERSION@.msi /norestart"; \
|
||||
Flags: 64bit hidewizard waituntilterminated skipifsilent; Components: winfsp
|
||||
Filename: "{app}\repertory.exe"; WorkingDir: "{app}"; Parameters: "-ui --hidden"; \
|
||||
Description: "Launch Repertory Management Portal"; \
|
||||
Flags: 64bit runhidden nowait postinstall skipifsilent; Components: main
|
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>
|
376
repertory/Install repertory.command
Normal file
@@ -0,0 +1,376 @@
|
||||
#!/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; }
|
||||
|
||||
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
|
||||
if [[ -d "$user_agents" ]]; then
|
||||
/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
|
||||
local label
|
||||
label="$(get_plist_label "$plist")"
|
||||
[[ -n "$label" && "$label" == "${LABEL_PREFIX}"* ]] || continue
|
||||
printf "%s\t%s\n" "$plist" "$label" >>"$snapfile"
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
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
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,36 +22,42 @@
|
||||
#ifndef REPERTORY_INCLUDE_APP_CONFIG_HPP_
|
||||
#define REPERTORY_INCLUDE_APP_CONFIG_HPP_
|
||||
|
||||
#include "events/event.hpp"
|
||||
#include "types/remote.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class app_config final {
|
||||
public:
|
||||
[[nodiscard]] static auto
|
||||
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;
|
||||
private:
|
||||
static stop_type stop_requested;
|
||||
|
||||
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(app_config &&) = delete;
|
||||
@@ -64,9 +70,9 @@ public:
|
||||
|
||||
private:
|
||||
provider_type prov_;
|
||||
atomic<std::string> api_auth_;
|
||||
utils::atomic<std::string> api_password_;
|
||||
std::atomic<std::uint16_t> api_port_;
|
||||
atomic<std::string> api_user_;
|
||||
utils::atomic<std::string> api_user_;
|
||||
std::atomic<bool> config_changed_;
|
||||
std::atomic<database_type> db_type_{database_type::rocksdb};
|
||||
std::atomic<std::uint8_t> download_timeout_secs_;
|
||||
@@ -84,7 +90,6 @@ private:
|
||||
std::atomic<std::uint8_t> max_upload_count_;
|
||||
std::atomic<std::uint16_t> med_freq_interval_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<std::uint16_t> retry_read_count_;
|
||||
std::atomic<std::uint16_t> ring_buffer_file_size_;
|
||||
@@ -93,14 +98,14 @@ private:
|
||||
private:
|
||||
std::string cache_directory_;
|
||||
std::string data_directory_;
|
||||
atomic<encrypt_config> encrypt_config_;
|
||||
atomic<host_config> host_config_;
|
||||
utils::atomic<encrypt_config> encrypt_config_;
|
||||
utils::atomic<host_config> host_config_;
|
||||
std::string log_directory_;
|
||||
mutable std::recursive_mutex read_write_mutex_;
|
||||
atomic<remote::remote_config> remote_config_;
|
||||
atomic<remote::remote_mount> remote_mount_;
|
||||
atomic<s3_config> s3_config_;
|
||||
atomic<sia_config> sia_config_;
|
||||
utils::atomic<remote::remote_config> remote_config_;
|
||||
utils::atomic<remote::remote_mount> remote_mount_;
|
||||
utils::atomic<s3_config> s3_config_;
|
||||
utils::atomic<sia_config> sia_config_;
|
||||
std::unordered_map<std::string, std::function<std::string()>>
|
||||
value_get_lookup_;
|
||||
std::unordered_map<std::string,
|
||||
@@ -115,7 +120,7 @@ private:
|
||||
auto set_value(dest &dst, const source &src) -> bool;
|
||||
|
||||
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;
|
||||
|
||||
@@ -165,8 +170,6 @@ public:
|
||||
|
||||
[[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_provider_type() const -> provider_type;
|
||||
@@ -185,14 +188,17 @@ public:
|
||||
|
||||
[[nodiscard]] auto get_task_wait_ms() const -> std::uint16_t;
|
||||
|
||||
[[nodiscard]] auto
|
||||
get_value_by_name(const std::string &name) const -> std::string;
|
||||
[[nodiscard]] auto get_value_by_name(const std::string &name) const
|
||||
-> std::string;
|
||||
|
||||
[[nodiscard]] auto get_raw_value_by_name(const std::string &name) const
|
||||
-> std::string;
|
||||
|
||||
[[nodiscard]] auto get_version() const -> std::uint64_t;
|
||||
|
||||
void save();
|
||||
|
||||
void set_api_auth(const std::string &value);
|
||||
void set_api_password(const std::string &value);
|
||||
|
||||
void set_api_port(std::uint16_t value);
|
||||
|
||||
@@ -232,8 +238,6 @@ public:
|
||||
|
||||
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_remote_config(remote::remote_config value);
|
||||
|
@@ -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
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,10 +22,12 @@
|
||||
#ifndef 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/i_http_comm.hpp"
|
||||
#include "events/event_system.hpp"
|
||||
#include "events/events.hpp"
|
||||
#include "events/types/curl_error.hpp"
|
||||
#include "utils/encryption.hpp"
|
||||
|
||||
namespace repertory {
|
||||
@@ -41,33 +43,31 @@ private:
|
||||
using write_callback = size_t (*)(char *, size_t, size_t, void *);
|
||||
|
||||
struct read_write_info final {
|
||||
data_buffer data{};
|
||||
stop_type &stop_requested;
|
||||
data_buffer data;
|
||||
stop_type_callback stop_requested_cb;
|
||||
};
|
||||
|
||||
static const write_callback write_data;
|
||||
static const write_callback write_headers;
|
||||
static constexpr std::uint8_t retry_request_count{5U};
|
||||
|
||||
private:
|
||||
std::optional<host_config> host_config_;
|
||||
std::optional<s3_config> s3_config_;
|
||||
|
||||
private:
|
||||
bool use_s3_path_style_{false};
|
||||
|
||||
public:
|
||||
[[nodiscard]] static auto create_curl() -> CURL *;
|
||||
|
||||
[[nodiscard]] static auto reset_curl(CURL *curl_handle) -> CURL *;
|
||||
|
||||
public:
|
||||
[[nodiscard]] static auto
|
||||
construct_url(CURL *curl, const std::string &relative_path,
|
||||
const host_config &cfg) -> std::string;
|
||||
[[nodiscard]] static auto construct_url(CURL *curl,
|
||||
const std::string &relative_path,
|
||||
const host_config &cfg)
|
||||
-> std::string;
|
||||
|
||||
[[nodiscard]] static auto
|
||||
create_host_config(const s3_config &cfg,
|
||||
bool use_s3_path_style) -> host_config;
|
||||
[[nodiscard]] static auto create_host_config(const s3_config &cfg)
|
||||
-> host_config;
|
||||
|
||||
[[nodiscard]] static auto url_encode(CURL *curl, const std::string &data,
|
||||
bool allow_slash) -> std::string;
|
||||
@@ -75,8 +75,8 @@ public:
|
||||
template <typename request_type>
|
||||
[[nodiscard]] static auto
|
||||
make_encrypted_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 {
|
||||
response_code = 0;
|
||||
|
||||
if (not request.decryption_token.has_value() ||
|
||||
@@ -93,9 +93,8 @@ public:
|
||||
}
|
||||
|
||||
data_buffer data{};
|
||||
const auto key =
|
||||
utils::encryption::generate_key<utils::encryption::hash_256_t>(
|
||||
request.decryption_token.value());
|
||||
const auto key = utils::encryption::generate_key<utils::hash::hash_256_t>(
|
||||
request.decryption_token.value());
|
||||
if (not utils::encryption::read_encrypted_range(
|
||||
request.range.value(), key,
|
||||
[&](data_buffer &ct, std::uint64_t start_offset,
|
||||
@@ -114,7 +113,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (response_code != 200) {
|
||||
if (response_code != http_error_codes::ok) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -135,106 +134,154 @@ public:
|
||||
[[nodiscard]] static auto
|
||||
make_request(const host_config &cfg, const request_type &request,
|
||||
long &response_code, stop_type &stop_requested) -> bool {
|
||||
if (request.decryption_token.has_value() &&
|
||||
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);
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
CURLcode curl_code{};
|
||||
curl_request.get_result(curl_code, response_code);
|
||||
if (curl_code != CURLE_OK) {
|
||||
event_system::instance().raise<curl_error>(url, curl_code);
|
||||
return false;
|
||||
const auto do_request = [&]() -> bool {
|
||||
if (request.decryption_token.has_value() &&
|
||||
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]() -> 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()) {
|
||||
request.response_handler.value()(write_info.data, response_code);
|
||||
}
|
||||
|
||||
return true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
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
|
||||
make_request(const curl::requests::http_delete &del, long &response_code,
|
||||
stop_type &stop_requested) const -> bool override;
|
||||
[[nodiscard]] auto make_request(const curl::requests::http_get &get,
|
||||
long &response_code,
|
||||
stop_type &stop_requested) const
|
||||
-> bool override;
|
||||
|
||||
[[nodiscard]] auto
|
||||
make_request(const curl::requests::http_get &get, long &response_code,
|
||||
stop_type &stop_requested) const -> bool override;
|
||||
[[nodiscard]] auto make_request(const curl::requests::http_head &head,
|
||||
long &response_code,
|
||||
stop_type &stop_requested) const
|
||||
-> bool override;
|
||||
|
||||
[[nodiscard]] auto
|
||||
make_request(const curl::requests::http_head &head, long &response_code,
|
||||
stop_type &stop_requested) const -> bool override;
|
||||
[[nodiscard]] auto make_request(const curl::requests::http_post &post_file,
|
||||
long &response_code,
|
||||
stop_type &stop_requested) const
|
||||
-> bool override;
|
||||
|
||||
[[nodiscard]] auto
|
||||
make_request(const curl::requests::http_post &post_file, long &response_code,
|
||||
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;
|
||||
[[nodiscard]] auto make_request(const curl::requests::http_put_file &put_file,
|
||||
long &response_code,
|
||||
stop_type &stop_requested) const
|
||||
-> bool override;
|
||||
};
|
||||
} // 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
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -36,6 +36,9 @@ private:
|
||||
stop_type &stop_requested_;
|
||||
CURLM *multi_handle_;
|
||||
|
||||
private:
|
||||
[[nodiscard]] auto get_stop_requested() const -> bool;
|
||||
|
||||
public:
|
||||
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
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -26,11 +26,13 @@
|
||||
|
||||
namespace repertory::curl::requests {
|
||||
struct http_delete final : http_request_base {
|
||||
~http_delete() override = default;
|
||||
[[nodiscard]] auto get_type() const -> std::string override {
|
||||
return "delete";
|
||||
}
|
||||
|
||||
[[nodiscard]] auto
|
||||
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_CUSTOMREQUEST, "DELETE");
|
||||
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
|
||||
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;
|
||||
~http_get() override = default;
|
||||
|
||||
[[nodiscard]] auto
|
||||
set_method(CURL *curl,
|
||||
stop_type & /*stop_requested*/) const -> bool override {
|
||||
[[nodiscard]] auto get_type() const -> std::string override { return "get"; }
|
||||
|
||||
[[nodiscard]] auto set_method(CURL *curl,
|
||||
stop_type & /*stop_requested*/) const
|
||||
-> bool override {
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
|
||||
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
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -26,11 +26,11 @@
|
||||
|
||||
namespace repertory::curl::requests {
|
||||
struct http_head final : http_request_base {
|
||||
~http_head() override = default;
|
||||
[[nodiscard]] auto get_type() const -> std::string override { return "head"; }
|
||||
|
||||
[[nodiscard]] auto
|
||||
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_CUSTOMREQUEST, "HEAD");
|
||||
curl_easy_setopt(curl, CURLOPT_NOBODY, 1L);
|
||||
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
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -26,21 +26,15 @@
|
||||
|
||||
namespace repertory::curl::requests {
|
||||
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;
|
||||
|
||||
[[nodiscard]] auto
|
||||
set_method(CURL *curl, stop_type & /*stop_requested*/) const -> bool override;
|
||||
[[nodiscard]] auto get_type() const -> std::string override { return "post"; }
|
||||
|
||||
[[nodiscard]] auto set_method(CURL *curl,
|
||||
stop_type & /*stop_requested*/) const
|
||||
-> bool override;
|
||||
|
||||
private:
|
||||
mutable curl_slist *headers{nullptr};
|
||||
mutable std::optional<std::string> json_str;
|
||||
};
|
||||
} // 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
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -27,18 +27,11 @@
|
||||
|
||||
namespace repertory::curl::requests {
|
||||
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::string source_path;
|
||||
|
||||
[[nodiscard]] auto get_type() const -> std::string override { return "put"; }
|
||||
|
||||
[[nodiscard]] auto set_method(CURL *curl, stop_type &stop_requested) const
|
||||
-> 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
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -51,7 +51,7 @@ struct http_request_base {
|
||||
bool allow_timeout{};
|
||||
std::optional<std::string> aws_service;
|
||||
std::optional<std::string> decryption_token{};
|
||||
http_headers headers{};
|
||||
mutable http_headers headers{};
|
||||
std::string path{};
|
||||
http_query_parameters query{};
|
||||
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_type() const -> std::string = 0;
|
||||
|
||||
[[nodiscard]] virtual auto set_method(CURL *curl,
|
||||
stop_type &stop_requested) const
|
||||
-> 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
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -34,28 +34,29 @@ struct i_http_comm {
|
||||
INTERFACE_SETUP(i_http_comm);
|
||||
|
||||
public:
|
||||
virtual void enable_s3_path_style(bool enable) = 0;
|
||||
|
||||
[[nodiscard]] virtual auto
|
||||
make_request(const curl::requests::http_delete &del, long &response_code,
|
||||
stop_type &stop_requested) const -> bool = 0;
|
||||
|
||||
[[nodiscard]] virtual auto
|
||||
make_request(const curl::requests::http_get &get, long &response_code,
|
||||
stop_type &stop_requested) const -> bool = 0;
|
||||
[[nodiscard]] virtual auto make_request(const curl::requests::http_get &get,
|
||||
long &response_code,
|
||||
stop_type &stop_requested) const
|
||||
-> bool = 0;
|
||||
|
||||
[[nodiscard]] virtual auto
|
||||
make_request(const curl::requests::http_head &head, long &response_code,
|
||||
stop_type &stop_requested) const -> bool = 0;
|
||||
[[nodiscard]] virtual auto make_request(const curl::requests::http_head &head,
|
||||
long &response_code,
|
||||
stop_type &stop_requested) const
|
||||
-> bool = 0;
|
||||
|
||||
[[nodiscard]] virtual auto
|
||||
make_request(const curl::requests::http_post &post, long &response_code,
|
||||
stop_type &stop_requested) const -> bool = 0;
|
||||
[[nodiscard]] virtual auto make_request(const curl::requests::http_post &post,
|
||||
long &response_code,
|
||||
stop_type &stop_requested) const
|
||||
-> bool = 0;
|
||||
|
||||
[[nodiscard]] virtual auto
|
||||
make_request(const curl::requests::http_put_file &put_file,
|
||||
long &response_code,
|
||||
stop_type &stop_requested) const -> bool = 0;
|
||||
long &response_code, stop_type &stop_requested) const
|
||||
-> bool = 0;
|
||||
};
|
||||
} // 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
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -94,7 +94,7 @@ private:
|
||||
bool shutdown_ = false;
|
||||
|
||||
private:
|
||||
static constexpr const auto min_pool_size = 10U;
|
||||
static constexpr auto min_pool_size = 10U;
|
||||
|
||||
public:
|
||||
void execute(const std::string &client_id, std::uint64_t thread_id,
|
||||
|
@@ -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
|
||||
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
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -69,21 +69,21 @@ private:
|
||||
|
||||
void put_client(std::shared_ptr<client> &cli);
|
||||
|
||||
[[nodiscard]] auto read_packet(client &cli, packet &response)
|
||||
-> packet::error_type;
|
||||
[[nodiscard]] auto read_packet(client &cli,
|
||||
packet &response) const -> packet::error_type;
|
||||
|
||||
void resolve();
|
||||
|
||||
public:
|
||||
[[nodiscard]] auto send(std::string_view method, std::uint32_t &service_flags)
|
||||
-> packet::error_type;
|
||||
[[nodiscard]] auto send(std::string_view method,
|
||||
std::uint32_t &service_flags) -> packet::error_type;
|
||||
|
||||
[[nodiscard]] auto send(std::string_view method, packet &request,
|
||||
std::uint32_t &service_flags) -> packet::error_type;
|
||||
|
||||
[[nodiscard]] auto send(std::string_view method, packet &request,
|
||||
packet &response, std::uint32_t &service_flags)
|
||||
-> packet::error_type;
|
||||
packet &response,
|
||||
std::uint32_t &service_flags) -> packet::error_type;
|
||||
};
|
||||
} // 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
|
||||
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
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,7 +22,7 @@
|
||||
#ifndef REPERTORY_INCLUDE_COMMON_HPP_
|
||||
#define REPERTORY_INCLUDE_COMMON_HPP_
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#if defined(__GNUC__) && !defined(PROJECT_IS_DARWIN)
|
||||
// clang-format off
|
||||
#define REPERTORY_IGNORE_WARNINGS_ENABLE() \
|
||||
_Pragma("GCC diagnostic push") \
|
||||
@@ -54,12 +54,13 @@ REPERTORY_IGNORE_WARNINGS_DISABLE()
|
||||
using namespace std::chrono_literals;
|
||||
using json = nlohmann::json;
|
||||
|
||||
inline constexpr const std::string_view REPERTORY = "repertory";
|
||||
inline constexpr const std::wstring_view REPERTORY_W = L"repertory";
|
||||
inline constexpr std::string_view REPERTORY{"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 const std::string_view REPERTORY_DATA_NAME = "repertory2";
|
||||
inline constexpr const std::string_view REPERTORY_MIN_REMOTE_VERSION = "2.0.0";
|
||||
inline constexpr std::uint64_t REPERTORY_CONFIG_VERSION{2ULL};
|
||||
inline constexpr std::string_view REPERTORY_MIN_REMOTE_VERSION{"2.1.0"};
|
||||
inline constexpr std::string_view RENTERD_MIN_VERSION{"2.0.0"};
|
||||
|
||||
#define REPERTORY_INVALID_HANDLE INVALID_HANDLE_VALUE
|
||||
|
||||
@@ -221,11 +222,11 @@ using WCHAR = wchar_t;
|
||||
|
||||
#define MAX_PATH 260
|
||||
|
||||
#define STATUS_SUCCESS std::uint32_t{0U}
|
||||
#define STATUS_ACCESS_DENIED std::uint32_t{0xC0000022L}
|
||||
#define STATUS_DEVICE_BUSY std::uint32_t{0x80000011L}
|
||||
#define STATUS_DEVICE_INSUFFICIENT_RESOURCES std::uint32_t{0xC0000468L}
|
||||
#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_TOO_LARGE std::uint32_t{0xC0000904L}
|
||||
#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_IMAGE_FORMAT std::uint32_t{0xC000007BL}
|
||||
#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_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_NOT_FOUND std::uint32_t{0xC0000034L}
|
||||
#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 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
|
||||
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
|
||||
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
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -29,9 +29,16 @@ class i_file_db {
|
||||
INTERFACE_SETUP(i_file_db);
|
||||
|
||||
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 {
|
||||
std::string api_path;
|
||||
bool directory;
|
||||
bool directory{};
|
||||
std::string source_path;
|
||||
};
|
||||
|
||||
@@ -40,13 +47,14 @@ public:
|
||||
std::uint64_t file_size{};
|
||||
std::vector<
|
||||
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;
|
||||
};
|
||||
|
||||
public:
|
||||
[[nodiscard]] virtual auto add_directory(const std::string &api_path,
|
||||
const std::string &source_path)
|
||||
[[nodiscard]] virtual auto add_or_update_directory(const directory_data &data)
|
||||
-> api_error = 0;
|
||||
|
||||
[[nodiscard]] virtual auto add_or_update_file(const file_data &data)
|
||||
@@ -56,6 +64,10 @@ public:
|
||||
|
||||
[[nodiscard]] virtual auto count() const -> std::uint64_t = 0;
|
||||
|
||||
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(const std::string &source_path,
|
||||
std::string &api_path) const
|
||||
-> api_error = 0;
|
||||
@@ -64,6 +76,10 @@ public:
|
||||
get_directory_api_path(const std::string &source_path,
|
||||
std::string &api_path) const -> api_error = 0;
|
||||
|
||||
[[nodiscard]] virtual auto get_directory_data(const std::string &api_path,
|
||||
directory_data &data) const
|
||||
-> api_error = 0;
|
||||
|
||||
[[nodiscard]] virtual auto
|
||||
get_directory_source_path(const std::string &api_path,
|
||||
std::string &source_path) const -> api_error = 0;
|
||||
@@ -80,7 +96,8 @@ public:
|
||||
get_file_source_path(const std::string &api_path,
|
||||
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;
|
||||
|
||||
[[nodiscard]] virtual auto get_source_path(const std::string &api_path,
|
||||
|