Compare commits
604 Commits
86e5f0359d
...
v2.1.0-rc-
Author | SHA1 | Date | |
---|---|---|---|
53a911f207 | |||
06ede16148 | |||
4a2f6658e2 | |||
7dbd367178 | |||
a969546a05 | |||
112f573283 | |||
a1b094a6d1 | |||
b78782875d | |||
f09ec24092 | |||
163c443d8e | |||
46ab10b92f | |||
97a74e5233 | |||
72a9005aeb | |||
b5116732d4 | |||
b0e790c5aa | |||
9913d6f8b4 | |||
1ca93d52d7 | |||
756f701fdb | |||
744a7406d9 | |||
71b87ebbfa | |||
81559a7b7e | |||
f3e46f4419 | |||
05b12ece89 | |||
445f0481b9 | |||
de2ca33e83 | |||
7d5d049e07 | |||
02ec672a6d | |||
c338d35c4f | |||
d02ce43fd1 | |||
cb092d124e | |||
ac97afe46c | |||
04307e0424 | |||
1a3b969713 | |||
71bf6e107b | |||
04518d7b8c | |||
4bee40228d | |||
8dbb0d9fd9 | |||
f83c4954af | |||
4a360fa1e0 | |||
8049fa103a | |||
937f24f3e0 | |||
f45c027f66 | |||
6b92989f81 | |||
4e6beed219 | |||
f3719ea361 | |||
6ceb687e78 | |||
ab99ae48e7 | |||
f8f5ccfd2c | |||
3535c147e4 | |||
d6b38b9df0 | |||
3da80fcf69 | |||
f9822c8bb2 | |||
ecb4cc2e80 | |||
e4fe7f06a0 | |||
cf62cf4ff8 | |||
e69285d6fb | |||
771f4a05de | |||
e67ac1dc13 | |||
0f6ca91faa | |||
ef4afe5ca0 | |||
691a9e3d0a | |||
132e0b73be | |||
a407f8d15b | |||
1f5b171295 | |||
cf5b3a074e | |||
4f24a1bc1d | |||
3997dbff79 | |||
caa42e45f1 | |||
0edd53f5f8 | |||
4c65410e7f | |||
e44a42f445 | |||
d06ac9f2c3 | |||
5d7036052b | |||
3d625da889 | |||
272bc39def | |||
5a042c09e5 | |||
cf68a7effe | |||
ae0ceb7040 | |||
7c191552be | |||
f16cf499cd | |||
b3624427d5 | |||
8a9394591b | |||
826c3a9008 | |||
7dfa0f7183 | |||
ce13149776 | |||
3fbf922575 | |||
3a3e73f776 | |||
eda5e6c2fc | |||
99800ec34e | |||
1fe61f2d5e | |||
8f742da3a0 | |||
144708a604 | |||
94a04cd718 | |||
b58314c6d3 | |||
ed01f3de12 | |||
6b592f8859 | |||
d51bb9ab42 | |||
ea510e9cdc | |||
06c50dbcf8 | |||
d9af430f13 | |||
1f775dd6f7 | |||
7d6356cbdc | |||
2db7449370 | |||
29a803e46e | |||
ec4d3022ac | |||
23f869f464 | |||
87c539628d | |||
0cd8d59fda | |||
37b014e9b4 | |||
efc8955944 | |||
3476724454 | |||
1a61ec693e | |||
06f169293d | |||
63701e105a | |||
ac6a435c32 | |||
44bd4fce20 | |||
018bbe626e | |||
1c180d3de5 | |||
450e0a9603 | |||
067a1d26b3 | |||
beff363507 | |||
9c8e96bc5e | |||
ee03167e43 | |||
b68a392d22 | |||
79e9e9e312 | |||
f070aa6964 | |||
8c838380db | |||
40b02dce5a | |||
1bdb8cb381 | |||
660cbb44e6 | |||
b0e74a30a2 | |||
b339ee435c | |||
4f5a347d2c | |||
8aa7cf40d3 | |||
41ecd3339c | |||
8e3c7d4eeb | |||
bee018a563 | |||
5cfa87df5d | |||
8c31589e5d | |||
cef993cf06 | |||
75093c2b81 | |||
d4aba93051 | |||
52e673a9ee | |||
0c7532e28b | |||
1bc57976c9 | |||
8df54749a5 | |||
5f4a2703dc | |||
cfe06ff304 | |||
38e928811e | |||
e9df198cbd | |||
0158b88807 | |||
a837ee6bc9 | |||
29648af9ba | |||
f7d4fe00ba | |||
6b1891741b | |||
415b28c7fe | |||
740cb467df | |||
7c6a8cad7b | |||
d219b961a5 | |||
7116ea84fd | |||
c4ce61ba20 | |||
cd82118a20 | |||
5aa0558a80 | |||
17b7d011db | |||
3cd22af906 | |||
9c79f15139 | |||
2cae947d22 | |||
1fbdf19269 | |||
37c036a2d7 | |||
6948f27309 | |||
2d6f6a5dc7 | |||
769f1621ca | |||
0809e61290 | |||
26830963c4 | |||
b0fab07527 | |||
3d798ca17e | |||
17bc1b41c6 | |||
3cc25bc482 | |||
d9e70ad81d | |||
4c1e9360fb | |||
faa1f5fa3b | |||
e5df094da4 | |||
a848795b25 | |||
73595a17b7 | |||
10d030de48 | |||
acfe692528 | |||
f3e6a401cf | |||
3f27736e2d | |||
c5ec37e0d8 | |||
3f163315b6 | |||
1d004eeccf | |||
52e84f95fb | |||
3a83a5fd5e | |||
2d43f84112 | |||
9875701f96 | |||
1214e777d5 | |||
891070146e | |||
af929064a9 | |||
db3c50538a | |||
b73cba45d6 | |||
ee666a8376 | |||
8f3e06cd17 | |||
865d9f5ba6 | |||
a1a9c916a1 | |||
72495c891b | |||
816d242234 | |||
66b3a0595d | |||
e511cd747a | |||
9f956aedf3 | |||
06485e0307 | |||
cbfa64556a | |||
5583d3f493 | |||
bbd0445a44 | |||
e57f950f82 | |||
8f2968d695 | |||
643b5fbe7e | |||
3be1cec393 | |||
91cac73e40 | |||
20d6eee1f8 | |||
94abee27f9 | |||
a241cd16ef | |||
a43a778b46 | |||
290bdb5fda | |||
6b2bf3ab67 | |||
f2f28cea59 | |||
c82ec168a1 | |||
a54f928455 | |||
1f01a43dd5 | |||
75ac2199e9 | |||
5e8bce5d63 | |||
bc9e4fc95a | |||
f722dd4b84 | |||
53b8c70c80 | |||
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 | |||
8dd46b8ad8 |
@@ -3,7 +3,9 @@ _mkgmtime
|
||||
_sh_denyno
|
||||
_sh_denyrd
|
||||
_sh_denyrw
|
||||
_spawnv
|
||||
aarch64
|
||||
abcdefgh
|
||||
advapi32
|
||||
armv8
|
||||
autogen
|
||||
@@ -15,8 +17,12 @@ boost_asio_has_std_string_view
|
||||
bugprone
|
||||
cflags
|
||||
chrono
|
||||
clsid
|
||||
cmake_current_source_dir
|
||||
cmdc
|
||||
coinit_apartmentthreaded
|
||||
comdlg32
|
||||
conin$
|
||||
cppcoreguidelines
|
||||
cppdbg
|
||||
cppflags
|
||||
@@ -25,7 +31,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 +60,7 @@ dcurl_staticlib
|
||||
dcurl_use_libpsl
|
||||
dcurl_use_libssh2
|
||||
dcurl_zlib
|
||||
dcurl_zstd
|
||||
ddebug
|
||||
decmult_gen_prec_bits
|
||||
decmult_window_size
|
||||
@@ -82,6 +93,7 @@ dspdlog_fmt_external
|
||||
dthreads_prefer_pthread_flag
|
||||
dunw_local_only
|
||||
duse_libidn2
|
||||
duse_nghttp2
|
||||
duuid_build_tests
|
||||
dwith_benchmark
|
||||
dwith_gflags
|
||||
@@ -93,6 +105,9 @@ endforeach
|
||||
endfunction
|
||||
eventlib
|
||||
expect_streq
|
||||
expect_strne
|
||||
falloc_fl_keep_size
|
||||
fallocate
|
||||
fallocate_impl
|
||||
fext
|
||||
fgetattr
|
||||
@@ -101,7 +116,10 @@ filebase
|
||||
flac_version
|
||||
flag_nopath
|
||||
flarge
|
||||
folderid
|
||||
fontconfig_version
|
||||
foob
|
||||
fooba
|
||||
freetype2_version
|
||||
fsetattr_x
|
||||
fusermount
|
||||
@@ -113,13 +131,18 @@ googletest
|
||||
gpath
|
||||
gtest_version
|
||||
has_setxattr
|
||||
hkey
|
||||
hresult
|
||||
httpapi
|
||||
httplib
|
||||
hwnd
|
||||
icudata
|
||||
icui18n
|
||||
icuuc
|
||||
inproc
|
||||
iostreams
|
||||
iphlpapi
|
||||
ipstream
|
||||
jthread
|
||||
libbitcoin
|
||||
libbitcoinsystem
|
||||
@@ -127,6 +150,7 @@ libcurl
|
||||
libdsm
|
||||
libevent
|
||||
libexample
|
||||
libexpat
|
||||
libfuse3
|
||||
libgmock
|
||||
libgtest
|
||||
@@ -139,38 +163,56 @@ libuuid
|
||||
libuuid_include_dirs
|
||||
libvlc
|
||||
linkflags
|
||||
llabsll
|
||||
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
|
||||
posix
|
||||
println
|
||||
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
|
||||
@@ -178,25 +220,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
|
||||
@@ -212,6 +263,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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
153
CHANGELOG.md
@@ -1,10 +1,152 @@
|
||||
# Changelog
|
||||
|
||||
## v2.0.2-rc
|
||||
## v2.1.0-rc
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
* Mount state has been moved into the configuration directory
|
||||
* Unmount all active mounts prior to upgrade
|
||||
* Remote mounts must be upgraded to v2.1.0+ to support new authentication scheme
|
||||
* Protocol handshake added for DoS protection
|
||||
|
||||
### Issues
|
||||
|
||||
* \#12 \[Unit Test\] Complete all providers unit tests
|
||||
* \#12 [unit test] Complete all providers unit tests
|
||||
* \#22 [unit test] Complete FUSE unit tests
|
||||
* \#33 Complete initial v2.0 documentation
|
||||
* \#34 Add macOS support
|
||||
* \#38 Pinning a file should automatically initiate a download to cache
|
||||
* \#51 [ui] UI console window should close after launch
|
||||
* \#52 [ui] Add auto-mount on first launch functionality
|
||||
* \#53 Create Windows installer
|
||||
* \#54 Remove 'default' as initial bucket name for Sia
|
||||
* \#58 Create macOS bundle for simplified installation
|
||||
* \#59 [bug] [ui] UI is hanging after launching repertory mount in background
|
||||
* \#60 Implement secure key via KDF for transparent data encryption/decryption
|
||||
* \#61 [ui] UI theme should match repertory blue
|
||||
|
||||
### Changes from v2.0.7-release
|
||||
|
||||
* Added check version support to remote mounts
|
||||
* Fixed directory item count bug on S3 provider
|
||||
* Fixed handling of `FALLOC_FL_KEEP_SIZE` on Linux
|
||||
* Fixed intermittent client hang on remote mount server disconnect
|
||||
* Implemented POSIX-compliant `unlink()` with FUSE `hard_remove`
|
||||
* Open handles remain valid after `unlink()`
|
||||
* Refactored CLI messages and error handling to use common methods
|
||||
* Enhanced remote mount client thread mapping
|
||||
* Threads are now mapped 1-1 from client to server instead of being tied to a fixed-size thread pool
|
||||
|
||||
## v2.0.7-release
|
||||
|
||||
<!-- markdownlint-disable-next-line -->
|
||||
### Issues
|
||||
|
||||
* \#55 [bug] UI is unable to launch `repertory.exe` on Windows when absolute path contains spaces
|
||||
* \#57 [bug] Directory entries . and .. are incorrectly being reported as files in Linux remote mounts
|
||||
|
||||
## v2.0.6-release
|
||||
|
||||
<!-- markdownlint-disable-next-line -->
|
||||
### Issues
|
||||
|
||||
* \#42 [bug] Remote mount directory listing on Windows connected to Linux is failing
|
||||
* \#43 [bug] Directories are not importing properly for Sia
|
||||
* \#44 [bug] Windows-to-Linux remote mount ignores `CREATE_NEW`
|
||||
* \#45 [bug] Windows-to-Linux remote mount is not handling attempts to remove a non-empty directory properly
|
||||
* \#46 [bug] Changes to maximum cache size should be updated live
|
||||
* \#47 [bug] Windows-to-Linux remote mount is allowing directory rename when directory is not empty
|
||||
* \#48 [bug] Windows-to-Linux remote mount overlapped I/O is not detecting EOF for read operations
|
||||
* \#49 [ui] Implement provider test button
|
||||
|
||||
### Changes from v2.0.5-rc
|
||||
|
||||
* Added request retry on `libcurl` error code `CURLE_COULDNT_RESOLVE_HOST`
|
||||
* Added `libcurl` DNS caching
|
||||
* Drive letters in UI should always be lowercase
|
||||
* Fixed WinFSP directory rename for non-empty directories
|
||||
* Fixed segfault in UI due to incorrect `SIGCHLD` handling
|
||||
* Migrated to v2 error handling
|
||||
* Upgraded WinFSP to v2.1 (2025)
|
||||
|
||||
## v2.0.5-rc
|
||||
|
||||
<!-- markdownlint-disable-next-line -->
|
||||
### Issues
|
||||
|
||||
* \#39 Create management portal in Flutter
|
||||
|
||||
### Changes from v2.0.4-rc
|
||||
|
||||
* Continue documentation updates
|
||||
* Fixed `-status` command erasing active mount information
|
||||
* Fixed overlapping HTTP REST API port's
|
||||
* Refactored/fixed instance locking
|
||||
* Removed passwords and secret key values from API calls
|
||||
* Renamed setting `ApiAuth` to `ApiPassword`
|
||||
* Require `--name,-na` option for encryption provider
|
||||
|
||||
## v2.0.4-rc
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
* `renterd` v2.0.0+ is now required. Prior versions will fail to mount.
|
||||
|
||||
<!-- markdownlint-disable-next-line -->
|
||||
### Issues
|
||||
|
||||
* \#35 [bug] Low frequency check is set to '0' instead of 1 hour by default
|
||||
* \#36 [bug] Max cache size bytes is set to '0' by default
|
||||
|
||||
### Changes from v2.0.3-rc
|
||||
|
||||
* Added Sia API version check prior to mounting
|
||||
* Added back `-cv` (check version) CLI option
|
||||
* Continue documentation updates
|
||||
* Fixed setting `ApiAuth` via `set_value_by_name`
|
||||
* Fixed setting `HostConfig.ApiUser` via `set_value_by_name`
|
||||
* Fixed setting `HostConfig.Path` via `set_value_by_name`
|
||||
* Fixed setting `HostConfig.Protocol` via `set_value_by_name`
|
||||
* Improved ring buffer read-ahead
|
||||
* Integrated `renterd` version 2.0.0
|
||||
* Prefer using local cache file when opening files
|
||||
* Refactored `app_config` unit tests
|
||||
* Refactored polling to be more accurate on scheduling tasks
|
||||
|
||||
## v2.0.3-rc
|
||||
|
||||
<!-- markdownlint-disable-next-line -->
|
||||
### Issues
|
||||
|
||||
* \#28 \[bug\] Address slow directory responses in S3 mounts for deeply nested directories
|
||||
* \#29 \[bug\] S3 error responses are not being logged
|
||||
* \#30 \[bug\] Sia provider error responses are not logged
|
||||
* \#31 \[bug\] S3 provider should limit max key size to 1024
|
||||
|
||||
### Changes from v2.0.2-rc
|
||||
|
||||
* Always use direct for read-only providers
|
||||
* Fixed externally removed files not being processed during cleanup
|
||||
* Fixed http headers not being added for requests
|
||||
* Fixed incorrect `stat` values for remote mounts
|
||||
* Fixed invalid directory nullptr error on remote mounts
|
||||
* Fixed memory leak in event system
|
||||
* Refactored application shutdown
|
||||
* Refactored event system
|
||||
* Updated build system to Alpine 3.21.0
|
||||
* Updated build system to MinGW-w64 12.0.0
|
||||
* Updated copyright to 2018-2025
|
||||
|
||||
## v2.0.2-rc
|
||||
|
||||
<!-- markdownlint-disable-next-line -->
|
||||
### BREAKING CHANGES
|
||||
|
||||
* Refactored `config.json` - will need to verify configuration settings prior to mounting
|
||||
|
||||
<!-- markdownlint-disable-next-line -->
|
||||
### Issues
|
||||
|
||||
* \#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
|
||||
@@ -14,13 +156,18 @@
|
||||
* MSYS2 is required for building Windows binaries on Windows
|
||||
* OS X support is temporarily disabled
|
||||
* \#19 \[bug\] Rename file is broken for files that are existing
|
||||
* \#23 \[bug\] Incorrect file size displayed while upload is pending
|
||||
* \#24 RocksDB implementations should be transactional
|
||||
* \#25 Writes should block when maximum cache size is reached
|
||||
* \#26 Complete ring buffer and direct download support
|
||||
|
||||
### Changes from v2.0.1-rc
|
||||
|
||||
* Ability to choose between RocksDB and SQLite databases
|
||||
* Added direct reads and implemented download fallback
|
||||
* Corrected file times on S3 and Sia providers
|
||||
* Corrected handling of `chown()` and `chmod()`
|
||||
* Fixed erroneous download of chunks after resize
|
||||
* Comprehensive WinFSP and FUSE unit tests, including remote testing
|
||||
|
||||
## v2.0.1-rc
|
||||
|
||||
|
@@ -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}/${PROJECT_NAME}.iss.in")
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${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}
|
||||
@@ -148,6 +172,7 @@ endif()
|
||||
-DPROJECT_ENABLE_LIBSODIUM=${PROJECT_ENABLE_LIBSODIUM}
|
||||
-DPROJECT_ENABLE_OPENSSL=${PROJECT_ENABLE_OPENSSL}
|
||||
-DPROJECT_ENABLE_PUGIXML=${PROJECT_ENABLE_PUGIXML}
|
||||
-DPROJECT_ENABLE_ROCKSDB=${PROJECT_ENABLE_ROCKSDB}
|
||||
-DPROJECT_ENABLE_SPDLOG=${PROJECT_ENABLE_SPDLOG}
|
||||
-DPROJECT_ENABLE_SQLITE=${PROJECT_ENABLE_SQLITE}
|
||||
-DPROJECT_ENABLE_STDUUID=${PROJECT_ENABLE_STDUUID}
|
||||
@@ -157,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,19 +1,22 @@
|
||||
set(BINUTILS_HASH ae9a5789e23459e59606e6714723f2d3ffc31c03174191ef0d015bdf06007450)
|
||||
set(BINUTILS_HASH ce2017e059d63e67ddb9240e9d4ec49c2893605035cd60e92ad53177f4377237)
|
||||
set(BOOST2_HASH 7bd7ddceec1a1dfdcbdb3e609b60d01739c38390a5f956385a12f3122049f0ca)
|
||||
set(BOOST_HASH be0d91732d5b0cc6fbb275c7939974457e79b54d6f07ce2e3dfdd68bef883b0b)
|
||||
set(CPP_HTTPLIB_HASH c1742fc7179aaae2a67ad9bba0740b7e9ffaf4f5e62feef53101ecdef1478716)
|
||||
set(CURL_HASH d714818f6ac41ae9154850158fed44b7a87650a6d52f83d3bcb9aa527be354d7)
|
||||
set(EXPAT_HASH fbd032683370d761ba68dba2566d3280a154f5290634172d60a79b24d366d9dc)
|
||||
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 777cd596284c883375a2a7a11bf5d2786fc5413255efab20c50d6ffe6d020b7e)
|
||||
set(MINGW_HASH 5afe822af5c4edbf67daaf45eec61d538f49eef6b19524de64897c6b95828caf)
|
||||
set(OPENSSL_HASH 529043b15cffa5f36077a4d0af83f3de399807181d607441d734196d889b641f)
|
||||
set(PKG_CONFIG_HASH 6fc69c01688c9458a57eb9a1664c9aba372ccda420a02bf4429fe610e7e7d591)
|
||||
set(PUGIXML_HASH 2f10e276870c64b1db6809050a75e11a897a8d7456c4be5c6b2e35a11168a015)
|
||||
set(SPDLOG_HASH 1586508029a7d0670dfcb2d97575dcdc242d3868a259742b69f100801ab4e16b)
|
||||
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,19 +4,24 @@ 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)
|
||||
include(cmake/libraries/json.cmake)
|
||||
include(cmake/libraries/libsodium.cmake)
|
||||
include(cmake/libraries/pugixml.cmake)
|
||||
include(cmake/libraries/rocksdb.cmake)
|
||||
include(cmake/libraries/spdlog.cmake)
|
||||
include(cmake/libraries/sqlite.cmake)
|
||||
include(cmake/libraries/stduuid.cmake)
|
||||
@@ -58,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)
|
||||
|
38
cmake/libraries/rocksdb.cmake
Normal file
@@ -0,0 +1,38 @@
|
||||
if(PROJECT_ENABLE_ROCKSDB)
|
||||
if(PROJECT_BUILD)
|
||||
add_definitions(-DPROJECT_ENABLE_ROCKSDB)
|
||||
find_library(ROCKSDB_LIBRARY NAMES librocksdb.a REQUIRED)
|
||||
link_libraries(${ROCKSDB_LIBRARY})
|
||||
elseif(NOT PROJECT_IS_MINGW OR CMAKE_HOST_WIN32)
|
||||
ExternalProject_Add(rocksdb_project
|
||||
PREFIX external
|
||||
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
|
||||
-DWITH_IOSTATS_CONTEXT=OFF
|
||||
-DWITH_PERF_CONTEXT=OFF
|
||||
-DWITH_TESTS=OFF
|
||||
-DWITH_TOOLS=OFF
|
||||
-DWITH_TRACE_TOOLS=OFF
|
||||
-DWITH_ZLIB=ON
|
||||
)
|
||||
|
||||
list(APPEND PROJECT_DEPENDENCIES rocksdb_project)
|
||||
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)
|
||||
|
@@ -6,6 +6,7 @@ option(PROJECT_ENABLE_JSON "Enable JSON for Modern C++ library" ON)
|
||||
option(PROJECT_ENABLE_LIBSODIUM "Enable libsodium library" ON)
|
||||
option(PROJECT_ENABLE_OPENSSL "Enable OpenSSL library" ON)
|
||||
option(PROJECT_ENABLE_PUGIXML "Enable PugiXML library" ON)
|
||||
option(PROJECT_ENABLE_ROCKSDB "Enable RocksDB library" ON)
|
||||
option(PROJECT_ENABLE_SPDLOG "Enable spdlog library" ON)
|
||||
option(PROJECT_ENABLE_SQLITE "Enable SQLite" ON)
|
||||
option(PROJECT_ENABLE_STDUUID "Enable stduuid library" ON)
|
||||
|
@@ -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,27 +1,30 @@
|
||||
set(BINUTILS_VERSION 2.41)
|
||||
set(BINUTILS_VERSION 2.44)
|
||||
set(BOOST2_MAJOR_VERSION 1)
|
||||
set(BOOST2_MINOR_VERSION 76)
|
||||
set(BOOST2_PATCH_VERSION 0)
|
||||
set(BOOST_MAJOR_VERSION 1)
|
||||
set(BOOST_MINOR_VERSION 85)
|
||||
set(BOOST_MINOR_VERSION 88)
|
||||
set(BOOST_PATCH_VERSION 0)
|
||||
set(CPP_HTTPLIB_VERSION 0.16.3)
|
||||
set(CURL2_VERSION 8_9_1)
|
||||
set(CURL_VERSION 8.9.1)
|
||||
set(EXPAT2_VERSION 2_6_2)
|
||||
set(EXPAT_VERSION 2.6.2)
|
||||
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(CURL2_VERSION 8_15_0)
|
||||
set(CURL_VERSION 8.15.0)
|
||||
set(EXPAT2_VERSION 2_7_1)
|
||||
set(EXPAT_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.3.1)
|
||||
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(SPDLOG_VERSION 1.14.1)
|
||||
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(SQLITE2_VERSION 3.50.3)
|
||||
set(SQLITE_VERSION 3500300)
|
||||
set(STDUUID_VERSION 1.2.3)
|
||||
set(WINFSP2_VERSION 2.1)
|
||||
set(WINFSP_VERSION 2.1.25156)
|
||||
set(ZLIB_VERSION 1.3.1)
|
||||
|
13
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
|
||||
@@ -30,6 +36,7 @@ PROJECT_ENABLE_JSON=ON
|
||||
PROJECT_ENABLE_LIBSODIUM=ON
|
||||
PROJECT_ENABLE_OPENSSL=ON
|
||||
PROJECT_ENABLE_PUGIXML=ON
|
||||
PROJECT_ENABLE_ROCKSDB=ON
|
||||
PROJECT_ENABLE_SPDLOG=ON
|
||||
PROJECT_ENABLE_SQLITE=ON
|
||||
PROJECT_ENABLE_STDUUID=ON
|
||||
|
@@ -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} \
|
||||
@@ -604,6 +640,7 @@ RUN if [ -f "/3rd_party/SFML-${MY_SFML_VERSION}.tar.gz" ]; then \
|
||||
-DBUILD_STATIC_LIBS=ON \
|
||||
-DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
|
||||
-DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
|
||||
-DCMAKE_SYSTEM_PROCESSOR=AMD64 \
|
||||
-DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
|
||||
&& make -j${MY_NUM_JOBS} \
|
||||
&& make install \
|
||||
@@ -670,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 \
|
||||
@@ -683,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 \
|
||||
@@ -710,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} \
|
||||
@@ -790,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 \
|
||||
@@ -879,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 \
|
||||
@@ -1110,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})
|
||||
|
23
repertory/Info.plist.in
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
|
||||
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>@PROJECT_NAME@</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>@PROJECT_MACOS_BUNDLE_ID@</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>@PROJECT_NAME@</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>@PROJECT_MAJOR_VERSION@.@PROJECT_MINOR_VERSION@.@PROJECT_REVISION_VERSION@-@PROJECT_RELEASE_ITER@_@PROJECT_GIT_REV@</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>@PROJECT_MAJOR_VERSION@.@PROJECT_MINOR_VERSION@.@PROJECT_REVISION_VERSION@.@PROJECT_RELEASE_NUM@</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>LSUIElement</key>
|
||||
<true />
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>@PROJECT_MACOS_ICNS_NAME@</string>
|
||||
</dict>
|
||||
</plist>
|
421
repertory/Install repertory.command
Normal file
@@ -0,0 +1,421 @@
|
||||
#!/usr/bin/env bash
|
||||
# No `-e` (we tolerate benign non-zero returns); keep -Euo
|
||||
set -Euo pipefail
|
||||
|
||||
LOG_DIR="/tmp"
|
||||
LOG_FILE="${LOG_DIR}/Install-$(date +%Y%m%d-%H%M%S).log"
|
||||
exec > >(tee -a "$LOG_FILE") 2>&1
|
||||
echo "Logging to: $LOG_FILE"
|
||||
|
||||
TARGET_DIR="/Applications"
|
||||
APP_NAME="repertory.app"
|
||||
|
||||
# Embedded at pack time (from CFBundleIdentifier prefix)
|
||||
LABEL_PREFIX="__LABEL_PREFIX__"
|
||||
UI_LABEL="${LABEL_PREFIX}.ui"
|
||||
|
||||
staged=""
|
||||
backup=""
|
||||
snapfile=""
|
||||
skip_ui_launch=0
|
||||
|
||||
log() { printf "[%(%H:%M:%S)T] %s\n" -1 "$*"; }
|
||||
warn() { log "WARN: $*"; }
|
||||
die() {
|
||||
log "ERROR: $*"
|
||||
exit 2
|
||||
}
|
||||
|
||||
here="$(cd "$(dirname "$0")" && pwd)"
|
||||
|
||||
# Locate source app on the DMG (supports hidden payload dirs)
|
||||
src_app="${here}/${APP_NAME}"
|
||||
if [[ ! -d "$src_app" ]]; then
|
||||
src_app="$(/usr/bin/find "$here" -type d -name "$APP_NAME" -print -quit 2>/dev/null || true)"
|
||||
fi
|
||||
[[ -d "$src_app" ]] || die "Could not find ${APP_NAME} on this disk image."
|
||||
|
||||
app_basename="$(basename "$src_app")"
|
||||
dest_app="${TARGET_DIR}/${APP_NAME}"
|
||||
|
||||
bundle_id_of() { /usr/bin/defaults read "$1/Contents/Info" CFBundleIdentifier 2>/dev/null || true; }
|
||||
bundle_exec_of() { /usr/bin/defaults read "$1/Contents/Info" CFBundleExecutable 2>/dev/null || echo "${app_basename%.app}"; }
|
||||
bundle_version_of() {
|
||||
/usr/libexec/PlistBuddy -c 'Print :CFBundleShortVersionString' "$1/Contents/Info.plist" 2>/dev/null ||
|
||||
/usr/bin/defaults read "$1/Contents/Info" CFBundleShortVersionString 2>/dev/null || echo "(unknown)"
|
||||
}
|
||||
bundle_build_of() {
|
||||
/usr/libexec/PlistBuddy -c 'Print :CFBundleVersion' "$1/Contents/Info.plist" 2>/dev/null ||
|
||||
/usr/bin/defaults read "$1/Contents/Info" CFBundleVersion 2>/dev/null || echo "(unknown)"
|
||||
}
|
||||
|
||||
# Require /Applications; prompt for sudo if needed; abort if cannot elevate
|
||||
USE_SUDO=0
|
||||
SUDO=""
|
||||
ensure_target_writable() {
|
||||
if mkdir -p "${TARGET_DIR}/.repertory_install_test.$$" 2>/dev/null; then
|
||||
rmdir "${TARGET_DIR}/.repertory_install_test.$$" 2>/dev/null || true
|
||||
USE_SUDO=0
|
||||
SUDO=""
|
||||
return 0
|
||||
fi
|
||||
if command -v sudo >/dev/null 2>&1; then
|
||||
log "Elevating privileges to write to ${TARGET_DIR}…"
|
||||
sudo -v || die "Administrator privileges required to install into ${TARGET_DIR}."
|
||||
USE_SUDO=1
|
||||
SUDO="sudo"
|
||||
return 0
|
||||
fi
|
||||
die "Cannot write to ${TARGET_DIR} and sudo is unavailable."
|
||||
}
|
||||
|
||||
# ----- STRICT LABEL PREFIX GATE (fail if invalid) -----
|
||||
_is_valid_label_prefix() {
|
||||
local p="${1:-}"
|
||||
[[ -n "$p" ]] && [[ "$p" != "__LABEL_PREFIX__" ]] && [[ "$p" =~ ^[A-Za-z0-9._-]+$ ]] && [[ "$p" == *.* ]]
|
||||
}
|
||||
if ! _is_valid_label_prefix "${LABEL_PREFIX:-}"; then
|
||||
die "Invalid LABEL_PREFIX in installer (value: \"${LABEL_PREFIX:-}\"). Rebuild the DMG so the installer contains a valid reverse-DNS prefix."
|
||||
fi
|
||||
|
||||
# ----- LaunchServices helpers -----
|
||||
ls_prune_bundle_id() {
|
||||
local bundle_id="$1" keep_path="$2"
|
||||
[[ -z "$bundle_id" ]] && return 0
|
||||
local search_roots=("/Applications" "$HOME/Applications" "/Volumes")
|
||||
if [[ -n "${here:-}" && "$here" == /Volumes/* ]]; then search_roots+=("$here"); fi
|
||||
local candidates=""
|
||||
for root in "${search_roots[@]}"; do
|
||||
[[ -d "$root" ]] || continue
|
||||
candidates+=$'\n'"$(/usr/bin/mdfind -onlyin "$root" "kMDItemCFBundleIdentifier == '${bundle_id}'" 2>/dev/null || true)"
|
||||
done
|
||||
# Include backups adjacent to keep_path (quote-safe)
|
||||
local parent_dir="${keep_path%/*.app}"
|
||||
candidates+=$'\n'$(/bin/ls -1d "${parent_dir}/"*.bak 2>/dev/null || true)
|
||||
local LSREG="/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister"
|
||||
printf "%s\n" "$candidates" | /usr/bin/awk 'NF' | /usr/bin/sort -u | while IFS= read -r p; do
|
||||
[[ -z "$p" || ! -d "$p" || "$p" == "$keep_path" ]] && continue
|
||||
log "Unregistering older LS entry for ${bundle_id}: $p"
|
||||
"$LSREG" -u "$p" >/dev/null 2>&1 || true
|
||||
done
|
||||
}
|
||||
|
||||
# ----- FUSE unmount (no process killing here) -----
|
||||
is_mounted() { /sbin/mount | /usr/bin/awk '{print $3}' | /usr/bin/grep -Fx "${1:-}" >/dev/null 2>&1; }
|
||||
_list_repertory_fuse_mounts() { /sbin/mount | /usr/bin/grep -Ei 'macfuse|osxfuse' | /usr/bin/awk '{print $3}' | /usr/bin/grep -i "repertory" || true; }
|
||||
_unmount_one() {
|
||||
local mnt="${1:-}"
|
||||
[[ -n "$mnt" ]] || return 0
|
||||
/usr/sbin/diskutil unmount "$mnt" >/dev/null 2>&1 || /sbin/umount "$mnt" >/dev/null 2>&1 || true
|
||||
if is_mounted "$mnt"; then
|
||||
/usr/sbin/diskutil unmount force "$mnt" >/dev/null 2>&1 || /sbin/umount -f "$mnt" >/dev/null 2>&1 || true
|
||||
fi
|
||||
for _ in {1..20}; do
|
||||
is_mounted "$mnt" || return 0
|
||||
sleep 0.25
|
||||
done
|
||||
return 1
|
||||
}
|
||||
unmount_existing_repertory_volumes() {
|
||||
# Hard-fail on the first unmount problem.
|
||||
while IFS= read -r mnt; do
|
||||
[[ -z "$mnt" ]] && continue
|
||||
log "Unmounting FUSE mount: $mnt"
|
||||
if ! _unmount_one "$mnt"; then
|
||||
warn "Failed to unmount $mnt"
|
||||
return 1
|
||||
fi
|
||||
done < <(_list_repertory_fuse_mounts)
|
||||
sync || true
|
||||
sleep 0.3
|
||||
return 0
|
||||
}
|
||||
|
||||
# ----- user LaunchAgents (by LABEL_PREFIX only) -----
|
||||
get_plist_label() { /usr/bin/defaults read "$1" Label 2>/dev/null || /usr/libexec/PlistBuddy -c "Print :Label" "$1" 2>/dev/null || basename "$1" .plist; }
|
||||
|
||||
# Return the executable path a LaunchAgent runs (ProgramArguments[0] or Program).
|
||||
# Echoes empty string if neither is present.
|
||||
get_plist_exec_path() {
|
||||
local plist="$1" arg0=""
|
||||
# Prefer ProgramArguments[0]
|
||||
arg0="$(/usr/libexec/PlistBuddy -c 'Print :ProgramArguments:0' "$plist" 2>/dev/null || true)"
|
||||
if [[ -z "$arg0" ]]; then
|
||||
# Fallback to Program (older style)
|
||||
arg0="$(/usr/libexec/PlistBuddy -c 'Print :Program' "$plist" 2>/dev/null || true)"
|
||||
fi
|
||||
printf '%s\n' "$arg0"
|
||||
}
|
||||
|
||||
snapshot_launchagents_user() {
|
||||
local user_agents="$HOME/Library/LaunchAgents"
|
||||
snapfile="$(/usr/bin/mktemp "/tmp/repertory_launchagents.XXXXXX")" || snapfile=""
|
||||
if [[ -z "$snapfile" ]]; then
|
||||
warn "Could not create temporary snapshot file; skipping LaunchAgent restart snapshot."
|
||||
return 0
|
||||
fi
|
||||
[[ -d "$user_agents" ]] || return 0
|
||||
|
||||
# We collect non-UI first, then UI last, to preserve restart order later.
|
||||
local tmp_nonui tmp_ui
|
||||
tmp_nonui="$(/usr/bin/mktemp "/tmp/repertory_launchagents.nonui.XXXXXX")" || tmp_nonui=""
|
||||
tmp_ui="$(/usr/bin/mktemp "/tmp/repertory_launchagents.ui.XXXXXX")" || tmp_ui=""
|
||||
|
||||
/usr/bin/find "$user_agents" -maxdepth 1 -type f -name "${LABEL_PREFIX}"'*.plist' -print 2>/dev/null |
|
||||
while IFS= read -r plist; do
|
||||
[[ -z "$plist" ]] && continue
|
||||
|
||||
# Label must match the prefix
|
||||
local label
|
||||
label="$(get_plist_label "$plist")"
|
||||
[[ -n "$label" && "$label" == "${LABEL_PREFIX}"* ]] || continue
|
||||
|
||||
# Executable must point into the *installed* app path
|
||||
local exec_path
|
||||
exec_path="$(get_plist_exec_path "$plist")"
|
||||
[[ -n "$exec_path" ]] || continue
|
||||
# Normalize: only accept absolute paths under $dest_app (e.g. .../repertory.app/Contents/...)
|
||||
if [[ "$exec_path" != "$dest_app/"* ]]; then
|
||||
# Not one of ours; skip
|
||||
continue
|
||||
fi
|
||||
|
||||
# Defer UI label to the end
|
||||
if [[ "$label" == "$UI_LABEL" ]]; then
|
||||
[[ -n "$tmp_ui" ]] && printf "%s\t%s\n" "$plist" "$label" >>"$tmp_ui"
|
||||
else
|
||||
[[ -n "$tmp_nonui" ]] && printf "%s\t%s\n" "$plist" "$label" >>"$tmp_nonui"
|
||||
fi
|
||||
done
|
||||
|
||||
# Stitch together: non-UI first, then UI
|
||||
[[ -s "$tmp_nonui" ]] && /bin/cat "$tmp_nonui" >>"$snapfile"
|
||||
[[ -s "$tmp_ui" ]] && /bin/cat "$tmp_ui" >>"$snapfile"
|
||||
|
||||
[[ -n "$tmp_nonui" ]] && /bin/rm -f "$tmp_nonui" 2>/dev/null || true
|
||||
[[ -n "$tmp_ui" ]] && /bin/rm -f "$tmp_ui" 2>/dev/null || true
|
||||
|
||||
log "Snapshot contains $(/usr/bin/wc -l <"$snapfile" 2>/dev/null || echo 0) LaunchAgent(s)."
|
||||
}
|
||||
|
||||
unload_launchd_helpers_user() {
|
||||
local uid user_agents
|
||||
uid="$(id -u)"
|
||||
user_agents="$HOME/Library/LaunchAgents"
|
||||
[[ -d "$user_agents" ]] || return 0
|
||||
|
||||
while IFS= read -r plist; do
|
||||
[[ -z "$plist" ]] && continue
|
||||
local base label
|
||||
base="$(basename "$plist")"
|
||||
[[ "$base" == "${LABEL_PREFIX}"* ]] || continue
|
||||
label="$(get_plist_label "$plist")"
|
||||
[[ -n "$label" && "$label" == "${LABEL_PREFIX}"* ]] || continue
|
||||
log "Booting out user label ${label} (${plist})"
|
||||
/bin/launchctl bootout "gui/${uid}" "$plist" 2>/dev/null ||
|
||||
/bin/launchctl bootout "gui/${uid}" "$label" 2>/dev/null ||
|
||||
/bin/launchctl remove "$label" 2>/dev/null || true
|
||||
done < <(/usr/bin/find "$user_agents" -maxdepth 1 -type f -name "${LABEL_PREFIX}"'*.plist' -print 2>/dev/null)
|
||||
|
||||
/bin/launchctl list 2>/dev/null | /usr/bin/awk -v pre="$LABEL_PREFIX" 'NF>=3 && index($3, pre)==1 {print $3}' |
|
||||
while read -r lbl; do
|
||||
[[ -z "$lbl" ]] && continue
|
||||
log "Booting out leftover user label: $lbl"
|
||||
/bin/launchctl bootout "gui/${uid}" "$lbl" 2>/dev/null || /bin/launchctl remove "$lbl" 2>/dev/null || true
|
||||
done
|
||||
}
|
||||
|
||||
restart_launchagents_from_snapshot() {
|
||||
[[ -n "${snapfile:-}" && -f "${snapfile}" ]] || return 0
|
||||
|
||||
local uid count=0 ui_seen=0
|
||||
uid="$(id -u)"
|
||||
|
||||
# Pass 1: restart all non-UI agents first
|
||||
while IFS=$'\t' read -r plist label; do
|
||||
[[ -n "$plist" && -n "$label" ]] || continue
|
||||
[[ -f "$plist" ]] || continue
|
||||
[[ "$label" == "$UI_LABEL" ]] && continue
|
||||
|
||||
log "Re-starting LaunchAgent: ${label}"
|
||||
/bin/launchctl bootstrap "gui/${uid}" "$plist" 2>/dev/null || true
|
||||
/bin/launchctl kickstart -k "gui/${uid}/${label}" 2>/dev/null || true
|
||||
((count++)) || true
|
||||
done <"$snapfile"
|
||||
|
||||
# Give helpers a moment to settle (e.g., automounts)
|
||||
sleep 0.3
|
||||
|
||||
# Pass 2: restart the UI agent last (if present in the snapshot)
|
||||
while IFS=$'\t' read -r plist label; do
|
||||
[[ -n "$plist" && -n "$label" ]] || continue
|
||||
[[ -f "$plist" ]] || continue
|
||||
[[ "$label" == "$UI_LABEL" ]] || continue
|
||||
|
||||
log "Re-starting UI LaunchAgent last: ${label}"
|
||||
/bin/launchctl bootstrap "gui/${uid}" "$plist" 2>/dev/null || true
|
||||
/bin/launchctl kickstart -k "gui/${uid}/${label}" 2>/dev/null || true
|
||||
ui_seen=1
|
||||
((count++)) || true
|
||||
done <"$snapfile"
|
||||
|
||||
log "Re-started ${count} LaunchAgent(s) with prefix ${LABEL_PREFIX}." || true
|
||||
|
||||
if ((ui_seen)); then
|
||||
# If the UI label is active, skip manual open(1).
|
||||
if /bin/launchctl list | /usr/bin/awk '{print $3}' | /usr/bin/grep -Fxq "$UI_LABEL"; then
|
||||
log "UI LaunchAgent (${UI_LABEL}) active after restart; skipping manual UI launch."
|
||||
skip_ui_launch=1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# ----- quarantine helper -----
|
||||
remove_quarantine() {
|
||||
local path="${1:-}"
|
||||
if [[ "${USE_SUDO:-0}" == "1" ]]; then
|
||||
sudo /usr/bin/xattr -dr com.apple.quarantine "$path" 2>/dev/null || true
|
||||
else
|
||||
/usr/bin/xattr -dr com.apple.quarantine "$path" 2>/dev/null || true
|
||||
fi
|
||||
}
|
||||
|
||||
# ----- process helpers -----
|
||||
kill_repertory_processes() {
|
||||
local exec_name="$1"
|
||||
/usr/bin/pkill -TERM -f "$dest_app" >/dev/null 2>&1 || true
|
||||
/usr/bin/pkill -TERM -x "$exec_name" >/dev/null 2>&1 || true
|
||||
for _ in {1..20}; do
|
||||
/usr/bin/pgrep -af "$dest_app" >/dev/null 2>&1 || /usr/bin/pgrep -x "$exec_name" >/dev/null 2>&1 || break
|
||||
sleep 0.1
|
||||
done
|
||||
/usr/bin/pkill -KILL -f "$dest_app" >/dev/null 2>&1 || true
|
||||
/usr/bin/pkill -KILL -x "$exec_name" >/dev/null 2>&1 || true
|
||||
}
|
||||
|
||||
# ----- visibility helper -----
|
||||
unhide_path() {
|
||||
local path="$1"
|
||||
/usr/bin/chflags -R nohidden "$path" 2>/dev/null || true
|
||||
/usr/bin/xattr -d -r com.apple.FinderInfo "$path" 2>/dev/null || true
|
||||
}
|
||||
|
||||
# ----- stage / validate / activate / post-activate -----
|
||||
stage_new_app() {
|
||||
staged="${dest_app}.new-$$"
|
||||
log "Staging new app → $staged"
|
||||
$SUDO /usr/bin/ditto "$src_app" "$staged" || die "ditto to stage failed"
|
||||
remove_quarantine "$staged"
|
||||
}
|
||||
|
||||
validate_staged_app() {
|
||||
[[ -f "$staged/Contents/Info.plist" ]] || {
|
||||
$SUDO /bin/rm -rf "$staged"
|
||||
die "staged app missing Info.plist"
|
||||
}
|
||||
local exe_name_staged
|
||||
exe_name_staged="$(/usr/bin/defaults read "$staged/Contents/Info" CFBundleExecutable 2>/dev/null || echo "${app_basename%.app}")"
|
||||
[[ -x "$staged/Contents/MacOS/$exe_name_staged" ]] || {
|
||||
$SUDO /bin/rm -rf "$staged"
|
||||
die "staged app missing main executable"
|
||||
}
|
||||
}
|
||||
|
||||
activate_staged_app() {
|
||||
if [[ -d "$dest_app" ]]; then
|
||||
backup="${dest_app}.$(date +%Y%m%d%H%M%S).bak"
|
||||
log "Moving existing app to backup: $backup"
|
||||
$SUDO /bin/mv "$dest_app" "$backup" || {
|
||||
$SUDO /bin/rm -rf "$staged"
|
||||
die "failed to move existing app out of the way"
|
||||
}
|
||||
fi
|
||||
log "Activating new app → $dest_app"
|
||||
if ! $SUDO /bin/mv "$staged" "$dest_app"; then
|
||||
warn "Activation failed; attempting rollback…"
|
||||
[[ -n "$backup" && -d "$backup" ]] && $SUDO /bin/mv "$backup" "$dest_app" || true
|
||||
$SUDO /bin/rm -rf "$staged" || true
|
||||
die "install activation failed"
|
||||
fi
|
||||
}
|
||||
|
||||
post_activate_cleanup() {
|
||||
log "Clearing quarantine on installed app…"
|
||||
remove_quarantine "$dest_app"
|
||||
log "Clearing hidden flags on installed app…"
|
||||
unhide_path "$dest_app"
|
||||
|
||||
local LSREG="/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister"
|
||||
[[ -x "$LSREG" ]] && "$LSREG" -f "$dest_app" >/dev/null 2>&1 || true
|
||||
local BID
|
||||
BID="$(bundle_id_of "$dest_app")"
|
||||
ls_prune_bundle_id "$BID" "$dest_app"
|
||||
|
||||
log "Installed ${app_basename}: version=$(bundle_version_of "$dest_app") build=$(bundle_build_of "$dest_app")"
|
||||
}
|
||||
|
||||
launch_ui() {
|
||||
log "Launching the new app…"
|
||||
/usr/bin/open -n "$dest_app" || warn "open -n by path failed; not falling back to -b to avoid launching a stale copy."
|
||||
}
|
||||
|
||||
remove_backup() {
|
||||
[[ -n "$backup" && -d "$backup" ]] && {
|
||||
log "Removing backup: $backup"
|
||||
$SUDO /bin/rm -rf "$backup" || warn "Could not remove backup (safe to delete manually): $backup"
|
||||
}
|
||||
log "Done."
|
||||
}
|
||||
|
||||
cleanup_staged() {
|
||||
if [[ -n "${staged:-}" && -d "${staged}" ]]; then
|
||||
log "Cleaning up staged folder: ${staged}"
|
||||
if [[ "${USE_SUDO:-0}" == "1" ]]; then
|
||||
sudo /bin/rm -rf "${staged}" 2>/dev/null || true
|
||||
else
|
||||
/bin/rm -rf "${staged}" 2>/dev/null || true
|
||||
fi
|
||||
fi
|
||||
if [[ -n "${snapfile:-}" && -f "${snapfile}" ]]; then
|
||||
/bin/rm -f "${snapfile}" 2>/dev/null || true
|
||||
fi
|
||||
}
|
||||
|
||||
main() {
|
||||
ensure_target_writable
|
||||
|
||||
local exec_name
|
||||
exec_name="$(bundle_exec_of "$src_app")"
|
||||
|
||||
# 1) Snapshot agents we'll restart later
|
||||
snapshot_launchagents_user
|
||||
|
||||
# 2) Hard-fail if any FUSE unmount fails
|
||||
unmount_existing_repertory_volumes || die "One or more FUSE mounts resisted unmount."
|
||||
|
||||
# 3) Stop user LaunchAgents (do NOT delete plists)
|
||||
unload_launchd_helpers_user
|
||||
|
||||
# 4) Kill any remaining repertory processes
|
||||
kill_repertory_processes "$exec_name"
|
||||
|
||||
# 5) Stage → validate → activate → post-activate
|
||||
stage_new_app
|
||||
validate_staged_app
|
||||
activate_staged_app
|
||||
post_activate_cleanup
|
||||
|
||||
# 6) Re-start previously-running LaunchAgents (so automount helpers come up)
|
||||
restart_launchagents_from_snapshot
|
||||
|
||||
# 7) If UI LaunchAgent came back, skip manual launch
|
||||
if ((!skip_ui_launch)); then
|
||||
launch_ui
|
||||
fi
|
||||
|
||||
# 8) Remove backup now that everything is good
|
||||
remove_backup
|
||||
}
|
||||
|
||||
trap 'rc=$?; cleanup_staged; if (( rc != 0 )); then echo "Installer failed with code $rc. See $LOG_FILE"; fi' EXIT
|
||||
main "$@"
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
||||
Copyright <2018-2025> <scott.e.graves@protonmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,441 +22,241 @@
|
||||
#ifndef REPERTORY_INCLUDE_APP_CONFIG_HPP_
|
||||
#define REPERTORY_INCLUDE_APP_CONFIG_HPP_
|
||||
|
||||
#include "events/event_system.hpp"
|
||||
#include "events/events.hpp"
|
||||
#include "types/remote.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
#include "utils/error_utils.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_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;
|
||||
app_config(const app_config &) = delete;
|
||||
|
||||
~app_config() { save(); }
|
||||
|
||||
auto operator=(const app_config &) -> app_config & = delete;
|
||||
auto operator=(app_config &&) -> app_config & = delete;
|
||||
|
||||
private:
|
||||
provider_type prov_;
|
||||
std::string api_auth_;
|
||||
std::uint16_t api_port_;
|
||||
std::string api_user_;
|
||||
bool config_changed_;
|
||||
std::string data_directory_;
|
||||
std::uint8_t download_timeout_secs_;
|
||||
bool enable_chunk_downloader_timeout_;
|
||||
bool enable_comm_duration_events_;
|
||||
bool enable_drive_events_;
|
||||
bool enable_max_cache_size_;
|
||||
#if defined(_WIN32)
|
||||
bool enable_mount_manager_;
|
||||
#endif // defined(_WIN32)
|
||||
bool enable_remote_mount_;
|
||||
encrypt_config encrypt_config_;
|
||||
event_level event_level_;
|
||||
std::uint32_t eviction_delay_mins_;
|
||||
bool eviction_uses_accessed_time_;
|
||||
std::uint8_t high_freq_interval_secs_;
|
||||
bool is_remote_mount_;
|
||||
std::uint32_t low_freq_interval_secs_;
|
||||
std::uint64_t max_cache_size_bytes_;
|
||||
std::uint8_t max_upload_count_;
|
||||
std::uint8_t min_download_timeout_secs_;
|
||||
std::uint16_t online_check_retry_secs_;
|
||||
std::uint16_t orphaned_file_retention_days_;
|
||||
std::string preferred_download_type_;
|
||||
std::uint8_t read_ahead_count_;
|
||||
std::uint8_t remote_client_pool_size_;
|
||||
std::string remote_host_name_or_ip_;
|
||||
std::uint8_t remote_max_connections_;
|
||||
std::uint16_t remote_port_;
|
||||
std::uint16_t remote_receive_timeout_secs_;
|
||||
std::uint16_t remote_send_timeout_secs_;
|
||||
std::string remote_token_;
|
||||
std::uint16_t retry_read_count_;
|
||||
std::uint16_t ring_buffer_file_size_;
|
||||
utils::atomic<std::string> api_password_;
|
||||
std::atomic<std::uint16_t> api_port_;
|
||||
utils::atomic<std::string> api_user_;
|
||||
std::string cache_directory_;
|
||||
host_config hc_;
|
||||
s3_config s3_config_;
|
||||
sia_config sia_config_{};
|
||||
std::uint64_t version_{REPERTORY_CONFIG_VERSION};
|
||||
std::atomic<bool> config_changed_;
|
||||
std::string data_directory_;
|
||||
std::atomic<database_type> db_type_{database_type::rocksdb};
|
||||
std::atomic<std::uint8_t> download_timeout_secs_;
|
||||
std::atomic<bool> enable_download_timeout_;
|
||||
std::atomic<bool> enable_drive_events_;
|
||||
#if defined(_WIN32)
|
||||
std::atomic<bool> enable_mount_manager_;
|
||||
#endif // defined(_WIN32)
|
||||
std::atomic<event_level> event_level_;
|
||||
std::atomic<std::uint32_t> eviction_delay_mins_;
|
||||
std::atomic<bool> eviction_uses_accessed_time_;
|
||||
std::atomic<std::uint16_t> high_freq_interval_secs_;
|
||||
std::string log_directory_;
|
||||
std::atomic<std::uint16_t> low_freq_interval_secs_;
|
||||
std::atomic<std::uint64_t> max_cache_size_bytes_;
|
||||
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<download_type> preferred_download_type_;
|
||||
std::atomic<std::uint16_t> retry_read_count_;
|
||||
std::atomic<std::uint16_t> ring_buffer_file_size_;
|
||||
std::atomic<std::uint16_t> task_wait_ms_;
|
||||
|
||||
private:
|
||||
utils::atomic<encrypt_config> encrypt_config_;
|
||||
utils::atomic<host_config> host_config_;
|
||||
mutable std::recursive_mutex read_write_mutex_;
|
||||
mutable std::recursive_mutex remote_mount_mutex_;
|
||||
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, std::function<std::string(std::string_view)>>
|
||||
value_set_lookup_;
|
||||
std::uint64_t version_{REPERTORY_CONFIG_VERSION};
|
||||
|
||||
private:
|
||||
[[nodiscard]] auto load() -> bool;
|
||||
|
||||
template <typename dest>
|
||||
auto get_value(const json &json_document, const std::string &name, dest &dst,
|
||||
bool &success_flag) -> bool {
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
auto ret{false};
|
||||
try {
|
||||
if (json_document.find(name) != json_document.end()) {
|
||||
dst = json_document[name].get<dest>();
|
||||
ret = true;
|
||||
} else {
|
||||
success_flag = false;
|
||||
}
|
||||
} catch (const json::exception &ex) {
|
||||
utils::error::raise_error(function_name, ex, "exception occurred");
|
||||
success_flag = false;
|
||||
ret = false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename dest, typename source>
|
||||
auto set_value(dest &dst, const source &src) -> bool {
|
||||
auto ret{false};
|
||||
recur_mutex_lock lock(read_write_mutex_);
|
||||
if (dst != src) {
|
||||
dst = src;
|
||||
config_changed_ = true;
|
||||
save();
|
||||
ret = true;
|
||||
}
|
||||
auto set_value(dest &dst, const source &src) -> bool;
|
||||
|
||||
return ret;
|
||||
}
|
||||
auto set_value(utils::atomic<std::string> &dst, std::string_view src) -> bool;
|
||||
|
||||
public:
|
||||
[[nodiscard]] auto get_api_auth() const -> std::string { return api_auth_; }
|
||||
[[nodiscard]] auto get_api_password() const -> std::string;
|
||||
|
||||
[[nodiscard]] auto get_api_port() const -> std::uint16_t { return api_port_; }
|
||||
[[nodiscard]] auto get_api_port() const -> std::uint16_t;
|
||||
|
||||
[[nodiscard]] auto get_api_user() const -> std::string { return api_user_; }
|
||||
[[nodiscard]] auto get_api_user() const -> std::string;
|
||||
|
||||
[[nodiscard]] auto get_cache_directory() const -> std::string {
|
||||
return cache_directory_;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto get_chunk_downloader_timeout_secs() const -> std::uint8_t {
|
||||
return std::max(min_download_timeout_secs_, download_timeout_secs_);
|
||||
}
|
||||
[[nodiscard]] auto get_cache_directory() const -> std::string;
|
||||
|
||||
[[nodiscard]] auto get_config_file_path() const -> std::string;
|
||||
|
||||
[[nodiscard]] auto get_data_directory() const -> std::string {
|
||||
return data_directory_;
|
||||
}
|
||||
[[nodiscard]] auto get_database_type() const -> database_type;
|
||||
|
||||
[[nodiscard]] auto get_enable_chunk_download_timeout() const -> bool {
|
||||
return enable_chunk_downloader_timeout_;
|
||||
}
|
||||
[[nodiscard]] auto get_data_directory() const -> std::string;
|
||||
|
||||
[[nodiscard]] auto get_enable_comm_duration_events() const -> bool {
|
||||
return enable_comm_duration_events_;
|
||||
}
|
||||
[[nodiscard]] auto get_download_timeout_secs() const -> std::uint8_t;
|
||||
|
||||
[[nodiscard]] auto get_enable_drive_events() const -> bool {
|
||||
return enable_drive_events_;
|
||||
}
|
||||
[[nodiscard]] auto get_enable_download_timeout() const -> bool;
|
||||
|
||||
[[nodiscard]] auto get_encrypt_config() const -> encrypt_config {
|
||||
return encrypt_config_;
|
||||
}
|
||||
[[nodiscard]] auto get_enable_drive_events() const -> bool;
|
||||
|
||||
[[nodiscard]] auto get_encrypt_config() const -> encrypt_config;
|
||||
|
||||
#if defined(_WIN32)
|
||||
[[nodiscard]] auto get_enable_mount_manager() const -> bool {
|
||||
return enable_mount_manager_;
|
||||
}
|
||||
#endif
|
||||
[[nodiscard]] auto get_enable_mount_manager() const -> bool;
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
[[nodiscard]] auto get_enable_max_cache_size() const -> bool {
|
||||
return enable_max_cache_size_;
|
||||
}
|
||||
[[nodiscard]] auto get_event_level() const -> event_level;
|
||||
|
||||
[[nodiscard]] auto get_enable_remote_mount() const -> bool {
|
||||
return enable_remote_mount_;
|
||||
}
|
||||
[[nodiscard]] auto get_eviction_delay_mins() const -> std::uint32_t;
|
||||
|
||||
[[nodiscard]] auto get_event_level() const -> event_level {
|
||||
return event_level_;
|
||||
}
|
||||
[[nodiscard]] auto get_eviction_uses_accessed_time() const -> bool;
|
||||
|
||||
[[nodiscard]] auto get_eviction_delay_mins() const -> std::uint32_t {
|
||||
return eviction_delay_mins_;
|
||||
}
|
||||
[[nodiscard]] auto get_high_frequency_interval_secs() const -> std::uint16_t;
|
||||
|
||||
[[nodiscard]] auto get_eviction_uses_accessed_time() const -> bool {
|
||||
return eviction_uses_accessed_time_;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto get_high_frequency_interval_secs() const -> std::uint8_t {
|
||||
return std::max(static_cast<std::uint8_t>(1U), high_freq_interval_secs_);
|
||||
}
|
||||
|
||||
[[nodiscard]] auto get_host_config() const -> host_config { return hc_; }
|
||||
|
||||
[[nodiscard]] auto get_is_remote_mount() const -> bool {
|
||||
return is_remote_mount_;
|
||||
}
|
||||
[[nodiscard]] auto get_host_config() const -> host_config;
|
||||
|
||||
[[nodiscard]] auto get_json() const -> json;
|
||||
|
||||
[[nodiscard]] auto get_log_directory() const -> std::string {
|
||||
return log_directory_;
|
||||
}
|
||||
[[nodiscard]] auto get_log_directory() const -> std::string;
|
||||
|
||||
[[nodiscard]] auto get_low_frequency_interval_secs() const -> std::uint32_t {
|
||||
return std::max(1U, low_freq_interval_secs_);
|
||||
}
|
||||
[[nodiscard]] auto get_low_frequency_interval_secs() const -> std::uint16_t;
|
||||
|
||||
[[nodiscard]] auto get_max_cache_size_bytes() const -> std::uint64_t;
|
||||
|
||||
[[nodiscard]] auto get_max_upload_count() const -> std::uint8_t {
|
||||
return std::max(std::uint8_t(1U), max_upload_count_);
|
||||
}
|
||||
[[nodiscard]] auto get_max_upload_count() const -> std::uint8_t;
|
||||
|
||||
[[nodiscard]] auto get_online_check_retry_secs() const -> std::uint16_t {
|
||||
return std::max(std::uint16_t(15U), online_check_retry_secs_);
|
||||
}
|
||||
[[nodiscard]] auto get_med_frequency_interval_secs() const -> std::uint16_t;
|
||||
|
||||
[[nodiscard]] auto get_orphaned_file_retention_days() const -> std::uint16_t {
|
||||
return std::min(static_cast<std::uint16_t>(31U),
|
||||
std::max(static_cast<std::uint16_t>(1U),
|
||||
orphaned_file_retention_days_));
|
||||
}
|
||||
[[nodiscard]] auto get_online_check_retry_secs() const -> std::uint16_t;
|
||||
|
||||
[[nodiscard]] auto get_preferred_download_type() const -> download_type {
|
||||
return download_type_from_string(preferred_download_type_,
|
||||
download_type::fallback);
|
||||
}
|
||||
[[nodiscard]] auto get_preferred_download_type() const -> download_type;
|
||||
|
||||
[[nodiscard]] auto get_provider_type() const -> provider_type {
|
||||
return prov_;
|
||||
}
|
||||
[[nodiscard]] auto get_provider_type() const -> provider_type;
|
||||
|
||||
[[nodiscard]] auto get_read_ahead_count() const -> std::uint8_t {
|
||||
return std::max(static_cast<std::uint8_t>(1U), read_ahead_count_);
|
||||
}
|
||||
[[nodiscard]] auto get_remote_config() const -> remote::remote_config;
|
||||
|
||||
[[nodiscard]] auto get_remote_client_pool_size() const -> std::uint8_t {
|
||||
return std::max(static_cast<std::uint8_t>(5U), remote_client_pool_size_);
|
||||
}
|
||||
[[nodiscard]] auto get_remote_mount() const -> remote::remote_mount;
|
||||
|
||||
[[nodiscard]] auto get_remote_host_name_or_ip() const -> std::string {
|
||||
return remote_host_name_or_ip_;
|
||||
}
|
||||
[[nodiscard]] auto get_retry_read_count() const -> std::uint16_t;
|
||||
|
||||
[[nodiscard]] auto get_remote_max_connections() const -> std::uint8_t {
|
||||
return std::max(static_cast<std::uint8_t>(1U), remote_max_connections_);
|
||||
}
|
||||
[[nodiscard]] auto get_ring_buffer_file_size() const -> std::uint16_t;
|
||||
|
||||
[[nodiscard]] auto get_remote_port() const -> std::uint16_t {
|
||||
return remote_port_;
|
||||
}
|
||||
[[nodiscard]] auto get_s3_config() const -> s3_config;
|
||||
|
||||
[[nodiscard]] auto get_remote_receive_timeout_secs() const -> std::uint16_t {
|
||||
return remote_receive_timeout_secs_;
|
||||
}
|
||||
[[nodiscard]] auto get_sia_config() const -> sia_config;
|
||||
|
||||
[[nodiscard]] auto get_remote_send_timeout_secs() const -> std::uint16_t {
|
||||
return remote_send_timeout_secs_;
|
||||
}
|
||||
[[nodiscard]] auto get_task_wait_ms() const -> std::uint16_t;
|
||||
|
||||
[[nodiscard]] auto get_remote_token() const -> std::string {
|
||||
return remote_token_;
|
||||
}
|
||||
[[nodiscard]] auto get_value_by_name(std::string_view name) const
|
||||
-> std::string;
|
||||
|
||||
[[nodiscard]] auto get_retry_read_count() const -> std::uint16_t {
|
||||
return std::max(std::uint16_t(2), retry_read_count_);
|
||||
}
|
||||
[[nodiscard]] auto get_raw_value_by_name(std::string_view name) const
|
||||
-> std::string;
|
||||
|
||||
[[nodiscard]] auto get_ring_buffer_file_size() const -> std::uint16_t {
|
||||
return std::max(
|
||||
static_cast<std::uint16_t>(64U),
|
||||
std::min(static_cast<std::uint16_t>(1024U), ring_buffer_file_size_));
|
||||
}
|
||||
|
||||
[[nodiscard]] auto get_s3_config() const -> s3_config { return s3_config_; }
|
||||
|
||||
[[nodiscard]] auto get_sia_config() const -> sia_config {
|
||||
return sia_config_;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto get_value_by_name(const std::string &name) -> std::string;
|
||||
|
||||
[[nodiscard]] auto get_version() const -> std::uint64_t { return version_; }
|
||||
[[nodiscard]] auto get_version() const -> std::uint64_t;
|
||||
|
||||
void save();
|
||||
|
||||
void set_api_auth(const std::string &api_auth) {
|
||||
set_value(api_auth_, api_auth);
|
||||
}
|
||||
void set_api_password(std::string_view value);
|
||||
|
||||
void set_api_port(std::uint16_t api_port) { set_value(api_port_, api_port); }
|
||||
void set_api_port(std::uint16_t value);
|
||||
|
||||
void set_api_user(const std::string &api_user) {
|
||||
set_value(api_user_, api_user);
|
||||
}
|
||||
void set_api_user(std::string_view value);
|
||||
|
||||
void set_chunk_downloader_timeout_secs(
|
||||
std::uint8_t chunk_downloader_timeout_secs) {
|
||||
set_value(download_timeout_secs_, chunk_downloader_timeout_secs);
|
||||
}
|
||||
void set_download_timeout_secs(std::uint8_t value);
|
||||
|
||||
void
|
||||
set_enable_chunk_downloader_timeout(bool enable_chunk_downloader_timeout) {
|
||||
set_value(enable_chunk_downloader_timeout_,
|
||||
enable_chunk_downloader_timeout);
|
||||
}
|
||||
void set_database_type(const database_type &value);
|
||||
|
||||
void set_enable_comm_duration_events(bool enable_comm_duration_events) {
|
||||
set_value(enable_comm_duration_events_, enable_comm_duration_events);
|
||||
}
|
||||
void set_enable_download_timeout(bool value);
|
||||
|
||||
void set_enable_drive_events(bool enable_drive_events) {
|
||||
set_value(enable_drive_events_, enable_drive_events);
|
||||
}
|
||||
|
||||
void set_enable_max_cache_size(bool enable_max_cache_size) {
|
||||
set_value(enable_max_cache_size_, enable_max_cache_size);
|
||||
}
|
||||
void set_enable_drive_events(bool value);
|
||||
|
||||
#if defined(_WIN32)
|
||||
void set_enable_mount_manager(bool enable_mount_manager) {
|
||||
set_value(enable_mount_manager_, enable_mount_manager);
|
||||
}
|
||||
#endif
|
||||
void set_enable_mount_manager(bool value);
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
void set_enable_remote_mount(bool enable_remote_mount);
|
||||
void set_event_level(const event_level &value);
|
||||
|
||||
void set_event_level(const event_level &level) {
|
||||
if (set_value(event_level_, level)) {
|
||||
event_system::instance().raise<event_level_changed>(
|
||||
event_level_to_string(level));
|
||||
}
|
||||
}
|
||||
void set_encrypt_config(encrypt_config value);
|
||||
|
||||
void set_eviction_delay_mins(std::uint32_t eviction_delay_mins) {
|
||||
set_value(eviction_delay_mins_, eviction_delay_mins);
|
||||
}
|
||||
void set_eviction_delay_mins(std::uint32_t value);
|
||||
|
||||
void set_eviction_uses_accessed_time(bool eviction_uses_accessed_time) {
|
||||
set_value(eviction_uses_accessed_time_, eviction_uses_accessed_time);
|
||||
}
|
||||
void set_eviction_uses_accessed_time(bool value);
|
||||
|
||||
void
|
||||
set_high_frequency_interval_secs(std::uint8_t high_frequency_interval_secs) {
|
||||
set_value(high_freq_interval_secs_, high_frequency_interval_secs);
|
||||
}
|
||||
void set_high_frequency_interval_secs(std::uint16_t value);
|
||||
|
||||
#if defined(PROJECT_TESTING)
|
||||
void set_host_config(host_config hc) {
|
||||
config_changed_ = true;
|
||||
hc_ = std::move(hc);
|
||||
save();
|
||||
}
|
||||
void set_host_config(host_config value);
|
||||
|
||||
void set_s3_config(s3_config s3) {
|
||||
config_changed_ = true;
|
||||
s3_config_ = std::move(s3);
|
||||
save();
|
||||
}
|
||||
void set_low_frequency_interval_secs(std::uint16_t value);
|
||||
|
||||
void set_sia_config(sia_config sia) {
|
||||
config_changed_ = true;
|
||||
sia_config_ = std::move(sia);
|
||||
save();
|
||||
}
|
||||
#endif // defined(PROJECT_TESTING)
|
||||
void set_max_cache_size_bytes(std::uint64_t value);
|
||||
|
||||
void set_is_remote_mount(bool is_remote_mount);
|
||||
void set_max_upload_count(std::uint8_t value);
|
||||
|
||||
void
|
||||
set_low_frequency_interval_secs(std::uint32_t low_frequency_interval_secs) {
|
||||
set_value(low_freq_interval_secs_, low_frequency_interval_secs);
|
||||
}
|
||||
void set_med_frequency_interval_secs(std::uint16_t value);
|
||||
|
||||
void set_max_cache_size_bytes(std::uint64_t max_cache_size_bytes) {
|
||||
set_value(max_cache_size_bytes_, max_cache_size_bytes);
|
||||
}
|
||||
void set_online_check_retry_secs(std::uint16_t value);
|
||||
|
||||
void set_max_upload_count(std::uint8_t max_upload_count) {
|
||||
set_value(max_upload_count_, max_upload_count);
|
||||
}
|
||||
void set_preferred_download_type(const download_type &value);
|
||||
|
||||
void set_online_check_retry_secs(std::uint16_t online_check_retry_secs) {
|
||||
set_value(online_check_retry_secs_, online_check_retry_secs);
|
||||
}
|
||||
void set_remote_config(remote::remote_config value);
|
||||
|
||||
void
|
||||
set_orphaned_file_retention_days(std::uint16_t orphaned_file_retention_days) {
|
||||
set_value(orphaned_file_retention_days_, orphaned_file_retention_days);
|
||||
}
|
||||
void set_remote_mount(remote::remote_mount value);
|
||||
|
||||
void set_preferred_download_type(const download_type &dt) {
|
||||
set_value(preferred_download_type_, download_type_to_string(dt));
|
||||
}
|
||||
void set_retry_read_count(std::uint16_t value);
|
||||
|
||||
void set_read_ahead_count(std::uint8_t read_ahead_count) {
|
||||
set_value(read_ahead_count_, read_ahead_count);
|
||||
}
|
||||
void set_ring_buffer_file_size(std::uint16_t value);
|
||||
|
||||
void set_remote_client_pool_size(std::uint8_t remote_client_pool_size) {
|
||||
set_value(remote_client_pool_size_, remote_client_pool_size);
|
||||
}
|
||||
void set_s3_config(s3_config value);
|
||||
|
||||
void set_ring_buffer_file_size(std::uint16_t ring_buffer_file_size) {
|
||||
set_value(ring_buffer_file_size_, ring_buffer_file_size);
|
||||
}
|
||||
void set_sia_config(sia_config value);
|
||||
|
||||
void set_remote_host_name_or_ip(const std::string &remote_host_name_or_ip) {
|
||||
set_value(remote_host_name_or_ip_, remote_host_name_or_ip);
|
||||
}
|
||||
void set_task_wait_ms(std::uint16_t value);
|
||||
|
||||
void set_remote_max_connections(std::uint8_t remote_max_connections) {
|
||||
set_value(remote_max_connections_, remote_max_connections);
|
||||
}
|
||||
|
||||
void set_remote_port(std::uint16_t remote_port) {
|
||||
set_value(remote_port_, remote_port);
|
||||
}
|
||||
|
||||
void
|
||||
set_remote_receive_timeout_secs(std::uint16_t remote_receive_timeout_secs) {
|
||||
set_value(remote_receive_timeout_secs_, remote_receive_timeout_secs);
|
||||
}
|
||||
|
||||
void set_remote_send_timeout_secs(std::uint16_t remote_send_timeout_secs) {
|
||||
set_value(remote_send_timeout_secs_, remote_send_timeout_secs);
|
||||
}
|
||||
|
||||
void set_remote_token(const std::string &remote_token) {
|
||||
set_value(remote_token_, remote_token);
|
||||
}
|
||||
|
||||
void set_retry_read_count(std::uint16_t retry_read_count) {
|
||||
set_value(retry_read_count_, retry_read_count);
|
||||
}
|
||||
|
||||
[[nodiscard]] auto set_value_by_name(const std::string &name,
|
||||
const std::string &value) -> std::string;
|
||||
[[nodiscard]] auto set_value_by_name(std::string_view name,
|
||||
std::string_view value) -> std::string;
|
||||
};
|
||||
} // 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
|
||||
@@ -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,42 +43,40 @@ 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,
|
||||
std::string_view 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,
|
||||
[[nodiscard]] static auto url_encode(CURL *curl, std::string_view data,
|
||||
bool allow_slash) -> std::string;
|
||||
|
||||
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,19 +93,19 @@ 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,
|
||||
[&](data_buffer &buffer, std::uint64_t start_offset,
|
||||
std::uint64_t end_offset) -> bool {
|
||||
auto encrypted_request = request;
|
||||
encrypted_request.decryption_token = std::nullopt;
|
||||
encrypted_request.range = {{start_offset, end_offset}};
|
||||
encrypted_request.response_handler =
|
||||
[&ct](const auto &encrypted_data, long /*response_code*/) {
|
||||
ct = encrypted_data;
|
||||
[&buffer](const auto &encrypted_data,
|
||||
long /*response_code*/) {
|
||||
buffer = encrypted_data;
|
||||
};
|
||||
encrypted_request.total_size = std::nullopt;
|
||||
|
||||
@@ -114,7 +114,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (response_code != 200) {
|
||||
if (response_code != http_error_codes::ok) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -135,106 +135,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
|
||||
@@ -23,10 +23,13 @@
|
||||
#define REPERTORY_INCLUDE_COMM_PACKET_CLIENT_POOL_HPP_
|
||||
|
||||
#include "comm/packet/packet.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class client_pool final {
|
||||
public:
|
||||
static constexpr const std::uint16_t default_expired_seconds{120U};
|
||||
static constexpr const std::uint16_t min_expired_seconds{5U};
|
||||
|
||||
public:
|
||||
using worker_callback = std::function<packet::error_type()>;
|
||||
using worker_complete_callback =
|
||||
@@ -46,15 +49,32 @@ private:
|
||||
};
|
||||
|
||||
struct work_queue final {
|
||||
work_queue();
|
||||
~work_queue();
|
||||
|
||||
work_queue(const work_queue &) = delete;
|
||||
work_queue(work_queue &&) = delete;
|
||||
|
||||
std::deque<std::shared_ptr<work_item>> actions;
|
||||
std::atomic<std::chrono::steady_clock::time_point> modified{
|
||||
std::chrono::steady_clock::now(),
|
||||
};
|
||||
std::mutex mutex;
|
||||
std::condition_variable notify;
|
||||
std::deque<std::shared_ptr<work_item>> queue;
|
||||
stop_type shutdown{false};
|
||||
std::unique_ptr<std::thread> thread;
|
||||
|
||||
auto operator=(const work_queue &) -> work_queue & = delete;
|
||||
auto operator=(work_queue &&) -> work_queue & = delete;
|
||||
|
||||
private:
|
||||
void work_thread();
|
||||
};
|
||||
|
||||
public:
|
||||
explicit pool(std::uint8_t pool_size);
|
||||
pool() noexcept = default;
|
||||
|
||||
~pool() { shutdown(); }
|
||||
~pool();
|
||||
|
||||
public:
|
||||
pool(const pool &) = delete;
|
||||
@@ -63,21 +83,20 @@ private:
|
||||
auto operator=(pool &&) -> pool & = delete;
|
||||
|
||||
private:
|
||||
std::vector<std::unique_ptr<work_queue>> pool_queues_;
|
||||
std::vector<std::thread> pool_threads_;
|
||||
bool shutdown_{false};
|
||||
std::atomic<std::uint8_t> thread_index_{};
|
||||
std::mutex pool_mtx_;
|
||||
std::unordered_map<std::uint64_t, std::shared_ptr<work_queue>> pool_queues_;
|
||||
|
||||
public:
|
||||
void execute(std::uint64_t thread_id, const worker_callback &worker,
|
||||
const worker_complete_callback &worker_complete);
|
||||
void execute(std::uint64_t thread_id, worker_callback worker,
|
||||
worker_complete_callback worker_complete);
|
||||
|
||||
void remove_expired(std::uint16_t seconds);
|
||||
|
||||
void shutdown();
|
||||
};
|
||||
|
||||
public:
|
||||
explicit client_pool(std::uint8_t pool_size = min_pool_size)
|
||||
: pool_size_(pool_size == 0U ? min_pool_size : pool_size) {}
|
||||
client_pool() noexcept;
|
||||
|
||||
~client_pool() { shutdown(); }
|
||||
|
||||
@@ -88,20 +107,23 @@ public:
|
||||
auto operator=(client_pool &&) -> client_pool & = delete;
|
||||
|
||||
private:
|
||||
std::uint8_t pool_size_;
|
||||
std::unordered_map<std::string, std::shared_ptr<pool>> pool_lookup_;
|
||||
std::unordered_map<std::string, std::unique_ptr<pool>> pool_lookup_;
|
||||
std::mutex pool_mutex_;
|
||||
bool shutdown_ = false;
|
||||
|
||||
private:
|
||||
static constexpr const auto min_pool_size = 10U;
|
||||
stop_type shutdown_{false};
|
||||
std::atomic<std::uint16_t> expired_seconds_{default_expired_seconds};
|
||||
|
||||
public:
|
||||
void execute(const std::string &client_id, std::uint64_t thread_id,
|
||||
const worker_callback &worker,
|
||||
const worker_complete_callback &worker_complete);
|
||||
[[nodiscard]] auto get_expired_seconds() const -> std::uint16_t;
|
||||
|
||||
void remove_client(const std::string &client_id);
|
||||
void execute(std::string client_id, std::uint64_t thread_id,
|
||||
worker_callback worker,
|
||||
worker_complete_callback worker_complete);
|
||||
|
||||
void remove_client(std::string client_id);
|
||||
|
||||
void remove_expired();
|
||||
|
||||
void set_expired_seconds(std::uint16_t seconds);
|
||||
|
||||
void shutdown();
|
||||
};
|
||||
|
54
repertory/librepertory/include/comm/packet/common.hpp
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
Copyright <2018-2025> <scott.e.graves@protonmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#ifndef REPERTORY_INCLUDE_COMM_PACKET_COMMON_HPP_
|
||||
#define REPERTORY_INCLUDE_COMM_PACKET_COMMON_HPP_
|
||||
|
||||
namespace repertory::comm {
|
||||
inline static constexpr std::uint32_t max_packet_bytes{32U * 1024U * 1024U};
|
||||
inline constexpr const std::uint8_t max_read_attempts{2U};
|
||||
inline constexpr const std::uint16_t packet_nonce_size{256U};
|
||||
inline constexpr const std::size_t read_write_size{131072U};
|
||||
inline constexpr const std::uint16_t server_handshake_timeout_ms{3000U};
|
||||
|
||||
struct non_blocking_guard final {
|
||||
non_blocking_guard(const non_blocking_guard &) = delete;
|
||||
non_blocking_guard(non_blocking_guard &&) = delete;
|
||||
|
||||
auto operator=(const non_blocking_guard &) -> non_blocking_guard & = delete;
|
||||
auto operator=(non_blocking_guard &&) -> non_blocking_guard & = delete;
|
||||
|
||||
explicit non_blocking_guard(boost::asio::ip::tcp::socket &sock_);
|
||||
|
||||
~non_blocking_guard();
|
||||
|
||||
private:
|
||||
bool non_blocking;
|
||||
boost::asio::ip::tcp::socket &sock;
|
||||
};
|
||||
|
||||
void apply_common_socket_properties(boost::asio::ip::tcp::socket &sock);
|
||||
|
||||
[[nodiscard]] auto is_socket_still_alive(boost::asio::ip::tcp::socket &sock)
|
||||
-> bool;
|
||||
} // namespace repertory::comm
|
||||
|
||||
#endif // REPERTORY_INCLUDE_COMM_PACKET_COMMON_HPP_
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
||||
Copyright <2018-2025> <scott.e.graves@protonmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -52,23 +52,23 @@ public:
|
||||
~packet() = default;
|
||||
|
||||
private:
|
||||
data_buffer buffer_;
|
||||
std::size_t decode_offset_ = 0U;
|
||||
data_buffer buffer_{};
|
||||
std::size_t decode_offset_{0U};
|
||||
|
||||
public:
|
||||
[[nodiscard]] static auto decode_json(packet &response,
|
||||
json &json_data) -> int;
|
||||
[[nodiscard]] static auto decode_json(packet &response, json &json_data)
|
||||
-> int;
|
||||
|
||||
public:
|
||||
void clear();
|
||||
|
||||
[[nodiscard]] auto current_pointer() -> unsigned char * {
|
||||
return (decode_offset_ < buffer_.size()) ? &buffer_[decode_offset_]
|
||||
return (decode_offset_ < buffer_.size()) ? &buffer_.at(decode_offset_)
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto current_pointer() const -> const unsigned char * {
|
||||
return (decode_offset_ < buffer_.size()) ? &buffer_[decode_offset_]
|
||||
return (decode_offset_ < buffer_.size()) ? &buffer_.at(decode_offset_)
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
@@ -200,13 +200,13 @@ public:
|
||||
|
||||
void encode_top(remote::file_info val);
|
||||
|
||||
void encrypt(std::string_view token);
|
||||
void encrypt(std::string_view token, bool include_size = true);
|
||||
|
||||
[[nodiscard]] auto get_size() const -> std::uint32_t {
|
||||
return static_cast<std::uint32_t>(buffer_.size());
|
||||
}
|
||||
|
||||
void transfer_into(data_buffer &buffer);
|
||||
void to_buffer(data_buffer &buffer);
|
||||
|
||||
public:
|
||||
auto operator=(const data_buffer &buffer) noexcept -> packet &;
|
||||
@@ -226,8 +226,6 @@ public:
|
||||
return buffer_.at(index);
|
||||
}
|
||||
};
|
||||
|
||||
using packet = packet;
|
||||
} // namespace repertory
|
||||
|
||||
#endif // REPERTORY_INCLUDE_COMM_PACKET_PACKET_HPP_
|
||||
|
@@ -1,17 +1,13 @@
|
||||
/*
|
||||
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
||||
|
||||
Copyright <2018-2025> <scott.e.graves@protonmail.com>
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
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
|
||||
copies of the Software, and to permit persons 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
|
||||
@@ -23,6 +19,8 @@
|
||||
#define REPERTORY_INCLUDE_COMM_PACKET_PACKET_CLIENT_HPP_
|
||||
|
||||
#include "comm/packet/packet.hpp"
|
||||
#include "types/remote.hpp"
|
||||
#include "utils/atomic.hpp"
|
||||
|
||||
using boost::asio::ip::tcp;
|
||||
|
||||
@@ -36,9 +34,7 @@ private:
|
||||
};
|
||||
|
||||
public:
|
||||
packet_client(std::string host_name_or_ip, std::uint8_t max_connections,
|
||||
std::uint16_t port, std::uint16_t receive_timeout,
|
||||
std::uint16_t send_timeout, std::string encryption_token);
|
||||
packet_client(remote::remote_config cfg);
|
||||
|
||||
~packet_client();
|
||||
|
||||
@@ -48,48 +44,55 @@ public:
|
||||
auto operator=(packet_client &&) -> packet_client & = delete;
|
||||
|
||||
private:
|
||||
boost::asio::io_context io_context_;
|
||||
std::string host_name_or_ip_;
|
||||
std::uint8_t max_connections_;
|
||||
std::uint16_t port_;
|
||||
std::uint16_t receive_timeout_;
|
||||
std::uint16_t send_timeout_;
|
||||
std::string encryption_token_;
|
||||
std::string unique_id_;
|
||||
remote::remote_config cfg_;
|
||||
mutable boost::asio::io_context io_context_;
|
||||
utils::atomic<std::string> unique_id_;
|
||||
|
||||
private:
|
||||
bool allow_connections_{true};
|
||||
boost::asio::ip::basic_resolver<boost::asio::ip::tcp>::results_type
|
||||
std::atomic<bool> allow_connections_{true};
|
||||
utils::atomic<
|
||||
boost::asio::ip::basic_resolver<boost::asio::ip::tcp>::results_type>
|
||||
resolve_results_;
|
||||
std::mutex clients_mutex_;
|
||||
std::vector<std::shared_ptr<client>> clients_;
|
||||
std::vector<std::thread> service_threads_;
|
||||
|
||||
private:
|
||||
static void close(client &cli);
|
||||
static void close(client &cli) noexcept;
|
||||
|
||||
void close_all();
|
||||
|
||||
void connect(client &cli);
|
||||
[[nodiscard]] auto connect(client &cli) -> bool;
|
||||
|
||||
[[nodiscard]] auto get_client() -> std::shared_ptr<client>;
|
||||
|
||||
[[nodiscard]] auto handshake(client &cli, std::uint32_t &min_version) const
|
||||
-> bool;
|
||||
|
||||
void put_client(std::shared_ptr<client> &cli);
|
||||
|
||||
[[nodiscard]] auto read_packet(client &cli,
|
||||
packet &response) -> packet::error_type;
|
||||
void read_data(client &cli, data_buffer &buffer) const;
|
||||
|
||||
[[nodiscard]] auto read_packet(client &cli, packet &response) const
|
||||
-> packet::error_type;
|
||||
|
||||
void resolve();
|
||||
|
||||
void write_data(client &cli, const packet &request) const;
|
||||
|
||||
public:
|
||||
[[nodiscard]] auto send(std::string_view method,
|
||||
std::uint32_t &service_flags) -> packet::error_type;
|
||||
[[nodiscard]] auto check_version(std::uint32_t client_version,
|
||||
std::uint32_t &min_version) -> api_error;
|
||||
|
||||
[[nodiscard]] auto send(std::string_view method, std::uint32_t &service_flags)
|
||||
-> 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
|
||||
@@ -23,6 +23,7 @@
|
||||
#define REPERTORY_INCLUDE_COMM_PACKET_PACKET_SERVER_HPP_
|
||||
|
||||
#include "comm/packet/client_pool.hpp"
|
||||
#include "comm/packet/common.hpp"
|
||||
#include "utils/common.hpp"
|
||||
|
||||
using namespace boost::asio;
|
||||
@@ -31,11 +32,11 @@ using boost::asio::ip::tcp;
|
||||
namespace repertory {
|
||||
class packet_server final {
|
||||
public:
|
||||
using closed_callback = std::function<void(const std::string &)>;
|
||||
using closed_callback = std::function<void(std::string)>;
|
||||
using message_complete_callback = client_pool::worker_complete_callback;
|
||||
using message_handler_callback = std::function<void(
|
||||
std::uint32_t, const std::string &, std::uint64_t, const std::string &,
|
||||
packet *, packet &, message_complete_callback)>;
|
||||
using message_handler_callback =
|
||||
std::function<void(std::uint32_t, std::string, std::uint64_t, std::string,
|
||||
packet *, packet &, message_complete_callback)>;
|
||||
|
||||
public:
|
||||
packet_server(std::uint16_t port, std::string token, std::uint8_t pool_size,
|
||||
@@ -52,8 +53,8 @@ public:
|
||||
|
||||
private:
|
||||
struct connection {
|
||||
connection(boost::asio::io_service &io_service, tcp::acceptor &acceptor_)
|
||||
: socket(io_service), acceptor(acceptor_) {}
|
||||
connection(io_context &ctx, tcp::acceptor &acceptor_)
|
||||
: socket(ctx), acceptor(acceptor_) {}
|
||||
|
||||
tcp::socket socket;
|
||||
tcp::acceptor &acceptor;
|
||||
@@ -61,21 +62,25 @@ private:
|
||||
std::string client_id;
|
||||
std::string nonce;
|
||||
|
||||
void generate_nonce() { nonce = utils::generate_random_string(256U); }
|
||||
void generate_nonce() {
|
||||
nonce = utils::generate_random_string(comm::packet_nonce_size);
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
std::string encryption_token_;
|
||||
closed_callback closed_;
|
||||
message_handler_callback message_handler_;
|
||||
boost::asio::io_context io_context_;
|
||||
mutable io_context io_context_;
|
||||
std::unique_ptr<std::thread> server_thread_;
|
||||
std::vector<std::thread> service_threads_;
|
||||
std::recursive_mutex connection_mutex_;
|
||||
std::unordered_map<std::string, std::uint32_t> connection_lookup_;
|
||||
|
||||
private:
|
||||
void add_client(connection &conn, const std::string &client_id);
|
||||
void add_client(connection &conn, std::string client_id);
|
||||
|
||||
[[nodiscard]] auto handshake(std::shared_ptr<connection> conn) const -> bool;
|
||||
|
||||
void initialize(const uint16_t &port, uint8_t pool_size);
|
||||
|
||||
|
@@ -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{5ULL};
|
||||
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,36 +1,34 @@
|
||||
/*
|
||||
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include "events/t_event_system.hpp"
|
||||
|
||||
#include "events/event.hpp"
|
||||
|
||||
namespace repertory {
|
||||
template <typename event_type>
|
||||
auto t_event_system<event_type>::instance() -> t_event_system<event_type> & {
|
||||
return event_system_;
|
||||
}
|
||||
|
||||
template <typename event_type>
|
||||
t_event_system<event_type> t_event_system<event_type>::event_system_;
|
||||
|
||||
template class t_event_system<event>;
|
||||
} // namespace repertory
|
||||
/*
|
||||
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_DB_FILE_DB_HPP_
|
||||
#define REPERTORY_INCLUDE_DB_FILE_DB_HPP_
|
||||
|
||||
#include "db/i_file_db.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class app_config;
|
||||
|
||||
[[nodiscard]] auto create_file_db(const app_config &cfg)
|
||||
-> std::unique_ptr<i_file_db>;
|
||||
} // namespace repertory
|
||||
|
||||
#endif // REPERTORY_INCLUDE_DB_FILE_DB_HPP_
|
@@ -1,41 +1,34 @@
|
||||
/*
|
||||
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#ifndef REPERTORY_INCLUDE_DRIVES_FUSE_EVENTS_HPP_
|
||||
#define REPERTORY_INCLUDE_DRIVES_FUSE_EVENTS_HPP_
|
||||
|
||||
#include "events/event_system.hpp"
|
||||
|
||||
namespace repertory {
|
||||
// clang-format off
|
||||
E_SIMPLE3(fuse_event, debug, true,
|
||||
std::string, function, func, E_FROM_STRING,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
int, result, res, E_FROM_INT32
|
||||
);
|
||||
|
||||
E_SIMPLE1(fuse_args_parsed, info, true,
|
||||
std::string, arguments, args, E_FROM_STRING
|
||||
);
|
||||
// clang-format on
|
||||
} // namespace repertory
|
||||
|
||||
#endif // REPERTORY_INCLUDE_DRIVES_FUSE_EVENTS_HPP_
|
||||
/*
|
||||
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_DB_FILE_MGR_DB_HPP_
|
||||
#define REPERTORY_INCLUDE_DB_FILE_MGR_DB_HPP_
|
||||
|
||||
#include "db/i_file_mgr_db.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class app_config;
|
||||
|
||||
[[nodiscard]] auto
|
||||
create_file_mgr_db(const app_config &cfg) -> std::unique_ptr<i_file_mgr_db>;
|
||||
} // namespace repertory
|
||||
|
||||
#endif // REPERTORY_INCLUDE_DB_FILE_MGR_DB_HPP_
|