Compare commits
	
		
			81 Commits
		
	
	
		
			v2.1.0-rc.
			...
			fb89cc08ae
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| fb89cc08ae | |||
| f08870b03c | |||
| 711e3f73cf | |||
| ebb620fdb2 | |||
| fbf9c85d48 | |||
| d5e0252ed3 | |||
| 06b79ffd2d | |||
| 690902b31d | |||
| 0bfe1e1ccd | |||
| a8723a6b02 | |||
| 1d88d26d0a | |||
| 757c880616 | |||
| d65bd6af35 | |||
| b285478cc5 | |||
| 31cd5acaee | |||
| 65036f2957 | |||
| 2362300bba | |||
| f61f3d5fa4 | |||
| a2b8998f4a | |||
| a4d53c1011 | |||
| 4b925c15c2 | |||
| bbd82e3f0f | |||
| 37f2cbc78d | |||
| 1ad3704fa0 | |||
| a6e70d93cb | |||
| 967324a368 | |||
| 69b31bfde8 | |||
| 8b4724a9c1 | |||
| 6a0d50bc66 | |||
| 69910bef4c | |||
| 8c298c84c5 | |||
| 47dea2cc38 | |||
| d8b476e80a | |||
| c86c6e2ec6 | |||
| c397497eb7 | |||
| f8803dfbf0 | |||
| 5d5cacc482 | |||
| 3ce4210d56 | |||
| d109344544 | |||
| ff746a7bec | |||
| a613ec77ff | |||
| 00d3dd95a8 | |||
| 28d1789f04 | |||
| 0603463885 | |||
| 88398485e1 | |||
| 908e75c696 | |||
| dab8c61f87 | |||
| e0cf58b01e | |||
| 281d3758e0 | |||
| dfa170022a | |||
| 52c2780283 | |||
| c2dbfc970a | |||
| 6f9b1f8f08 | |||
| 078d603be9 | |||
| 983e47103b | |||
| 8d2024d34b | |||
| 4f2ee2ad99 | |||
| 533938bcef | |||
| 98edf33be4 | |||
| a080c9ff86 | |||
| e6cdcd74a1 | |||
| 573ae549be | |||
| fca149f998 | |||
| 76e375c488 | |||
| 3f9322f659 | |||
| c286d496c3 | |||
| 56ba0fcb83 | |||
| dcafb104ea | |||
| ab757dfd36 | |||
| eec2d2e9a9 | |||
| 8c1c91e02b | |||
| bb85015733 | |||
| 883de836c6 | |||
| bf2bdd1b5d | |||
| f1e82d8f9f | |||
| f5c4aebdac | |||
| f2f9e8fd15 | |||
| 2a673915af | |||
| df3db38ae7 | |||
| b0b69c6dd4 | |||
| 11b118a30f | 
@@ -5,7 +5,6 @@ _sh_denyrd
 | 
				
			|||||||
_sh_denyrw
 | 
					_sh_denyrw
 | 
				
			||||||
_spawnv
 | 
					_spawnv
 | 
				
			||||||
aarch64
 | 
					aarch64
 | 
				
			||||||
abcdefgh
 | 
					 | 
				
			||||||
advapi32
 | 
					advapi32
 | 
				
			||||||
armv8
 | 
					armv8
 | 
				
			||||||
autogen
 | 
					autogen
 | 
				
			||||||
@@ -17,12 +16,8 @@ boost_asio_has_std_string_view
 | 
				
			|||||||
bugprone
 | 
					bugprone
 | 
				
			||||||
cflags
 | 
					cflags
 | 
				
			||||||
chrono
 | 
					chrono
 | 
				
			||||||
clsid
 | 
					 | 
				
			||||||
cmake_current_source_dir
 | 
					cmake_current_source_dir
 | 
				
			||||||
cmdc
 | 
					 | 
				
			||||||
coinit_apartmentthreaded
 | 
					 | 
				
			||||||
comdlg32
 | 
					comdlg32
 | 
				
			||||||
conin$
 | 
					 | 
				
			||||||
cppcoreguidelines
 | 
					cppcoreguidelines
 | 
				
			||||||
cppdbg
 | 
					cppdbg
 | 
				
			||||||
cppflags
 | 
					cppflags
 | 
				
			||||||
@@ -31,10 +26,7 @@ cpptrace
 | 
				
			|||||||
cppvsdbg
 | 
					cppvsdbg
 | 
				
			||||||
create_notraverse
 | 
					create_notraverse
 | 
				
			||||||
crypto_aead_xchacha20poly1305_ietf_npubbytes
 | 
					crypto_aead_xchacha20poly1305_ietf_npubbytes
 | 
				
			||||||
cspan
 | 
					 | 
				
			||||||
cstdint
 | 
					cstdint
 | 
				
			||||||
curl_zstd
 | 
					 | 
				
			||||||
curle_couldnt_resolve_host
 | 
					 | 
				
			||||||
curlopt_aws_sigv4
 | 
					curlopt_aws_sigv4
 | 
				
			||||||
cxxflags
 | 
					cxxflags
 | 
				
			||||||
cxxstd
 | 
					cxxstd
 | 
				
			||||||
@@ -60,7 +52,6 @@ dcurl_staticlib
 | 
				
			|||||||
dcurl_use_libpsl
 | 
					dcurl_use_libpsl
 | 
				
			||||||
dcurl_use_libssh2
 | 
					dcurl_use_libssh2
 | 
				
			||||||
dcurl_zlib
 | 
					dcurl_zlib
 | 
				
			||||||
dcurl_zstd
 | 
					 | 
				
			||||||
ddebug
 | 
					ddebug
 | 
				
			||||||
decmult_gen_prec_bits
 | 
					decmult_gen_prec_bits
 | 
				
			||||||
decmult_window_size
 | 
					decmult_window_size
 | 
				
			||||||
@@ -93,7 +84,6 @@ dspdlog_fmt_external
 | 
				
			|||||||
dthreads_prefer_pthread_flag
 | 
					dthreads_prefer_pthread_flag
 | 
				
			||||||
dunw_local_only
 | 
					dunw_local_only
 | 
				
			||||||
duse_libidn2
 | 
					duse_libidn2
 | 
				
			||||||
duse_nghttp2
 | 
					 | 
				
			||||||
duuid_build_tests
 | 
					duuid_build_tests
 | 
				
			||||||
dwith_benchmark
 | 
					dwith_benchmark
 | 
				
			||||||
dwith_gflags
 | 
					dwith_gflags
 | 
				
			||||||
@@ -105,9 +95,6 @@ endforeach
 | 
				
			|||||||
endfunction
 | 
					endfunction
 | 
				
			||||||
eventlib
 | 
					eventlib
 | 
				
			||||||
expect_streq
 | 
					expect_streq
 | 
				
			||||||
expect_strne
 | 
					 | 
				
			||||||
falloc_fl_keep_size
 | 
					 | 
				
			||||||
fallocate
 | 
					 | 
				
			||||||
fallocate_impl
 | 
					fallocate_impl
 | 
				
			||||||
fext
 | 
					fext
 | 
				
			||||||
fgetattr
 | 
					fgetattr
 | 
				
			||||||
@@ -116,10 +103,7 @@ filebase
 | 
				
			|||||||
flac_version
 | 
					flac_version
 | 
				
			||||||
flag_nopath
 | 
					flag_nopath
 | 
				
			||||||
flarge
 | 
					flarge
 | 
				
			||||||
folderid
 | 
					 | 
				
			||||||
fontconfig_version
 | 
					fontconfig_version
 | 
				
			||||||
foob
 | 
					 | 
				
			||||||
fooba
 | 
					 | 
				
			||||||
freetype2_version
 | 
					freetype2_version
 | 
				
			||||||
fsetattr_x
 | 
					fsetattr_x
 | 
				
			||||||
fusermount
 | 
					fusermount
 | 
				
			||||||
@@ -132,14 +116,11 @@ gpath
 | 
				
			|||||||
gtest_version
 | 
					gtest_version
 | 
				
			||||||
has_setxattr
 | 
					has_setxattr
 | 
				
			||||||
hkey
 | 
					hkey
 | 
				
			||||||
hresult
 | 
					 | 
				
			||||||
httpapi
 | 
					httpapi
 | 
				
			||||||
httplib
 | 
					httplib
 | 
				
			||||||
hwnd
 | 
					 | 
				
			||||||
icudata
 | 
					icudata
 | 
				
			||||||
icui18n
 | 
					icui18n
 | 
				
			||||||
icuuc
 | 
					icuuc
 | 
				
			||||||
inproc
 | 
					 | 
				
			||||||
iostreams
 | 
					iostreams
 | 
				
			||||||
iphlpapi
 | 
					iphlpapi
 | 
				
			||||||
ipstream
 | 
					ipstream
 | 
				
			||||||
@@ -163,10 +144,8 @@ libuuid
 | 
				
			|||||||
libuuid_include_dirs
 | 
					libuuid_include_dirs
 | 
				
			||||||
libvlc
 | 
					libvlc
 | 
				
			||||||
linkflags
 | 
					linkflags
 | 
				
			||||||
llabsll
 | 
					 | 
				
			||||||
localappdata
 | 
					localappdata
 | 
				
			||||||
lpbyte
 | 
					lpbyte
 | 
				
			||||||
lpthread
 | 
					 | 
				
			||||||
lptr
 | 
					lptr
 | 
				
			||||||
lpwstr
 | 
					lpwstr
 | 
				
			||||||
markdownlint
 | 
					markdownlint
 | 
				
			||||||
@@ -177,13 +156,11 @@ msvcr120
 | 
				
			|||||||
msys2
 | 
					msys2
 | 
				
			||||||
mtune
 | 
					mtune
 | 
				
			||||||
musl-libc
 | 
					musl-libc
 | 
				
			||||||
mwindows
 | 
					 | 
				
			||||||
nana
 | 
					nana
 | 
				
			||||||
ncrypt
 | 
					ncrypt
 | 
				
			||||||
nlohmann
 | 
					nlohmann
 | 
				
			||||||
nlohmann_json
 | 
					nlohmann_json
 | 
				
			||||||
nmakeprg
 | 
					nmakeprg
 | 
				
			||||||
noappledouble
 | 
					 | 
				
			||||||
nohup
 | 
					nohup
 | 
				
			||||||
nominmax
 | 
					nominmax
 | 
				
			||||||
ntstatus
 | 
					ntstatus
 | 
				
			||||||
@@ -192,27 +169,21 @@ nuspell_version
 | 
				
			|||||||
oleaut32
 | 
					oleaut32
 | 
				
			||||||
openal_version
 | 
					openal_version
 | 
				
			||||||
openssldir
 | 
					openssldir
 | 
				
			||||||
osascript
 | 
					 | 
				
			||||||
osxfuse
 | 
					 | 
				
			||||||
pistream
 | 
					pistream
 | 
				
			||||||
pkgconfig
 | 
					pkgconfig
 | 
				
			||||||
plarge_integer
 | 
					plarge_integer
 | 
				
			||||||
plex
 | 
					plex
 | 
				
			||||||
posix
 | 
					 | 
				
			||||||
println
 | 
					println
 | 
				
			||||||
project_enable_fontconfig
 | 
					project_enable_fontconfig
 | 
				
			||||||
project_enable_gtkmm
 | 
					project_enable_gtkmm
 | 
				
			||||||
project_enable_libdsm
 | 
					project_enable_libdsm
 | 
				
			||||||
project_enable_nana
 | 
					project_enable_nana
 | 
				
			||||||
project_macos_icns_name
 | 
					 | 
				
			||||||
propgrid
 | 
					propgrid
 | 
				
			||||||
psecurity_descriptor
 | 
					psecurity_descriptor
 | 
				
			||||||
pthreads
 | 
					 | 
				
			||||||
pugi
 | 
					pugi
 | 
				
			||||||
pugixml_project
 | 
					pugixml_project
 | 
				
			||||||
puint32
 | 
					puint32
 | 
				
			||||||
pvoid
 | 
					pvoid
 | 
				
			||||||
pwhash
 | 
					 | 
				
			||||||
pwstr
 | 
					pwstr
 | 
				
			||||||
rdrw
 | 
					rdrw
 | 
				
			||||||
remote_winfsp
 | 
					remote_winfsp
 | 
				
			||||||
@@ -220,31 +191,24 @@ renterd
 | 
				
			|||||||
richtext
 | 
					richtext
 | 
				
			||||||
rocksdb_library
 | 
					rocksdb_library
 | 
				
			||||||
rpcrt4
 | 
					rpcrt4
 | 
				
			||||||
runas
 | 
					 | 
				
			||||||
s_igid
 | 
					s_igid
 | 
				
			||||||
s_isvtx
 | 
					s_isvtx
 | 
				
			||||||
s_iuid
 | 
					s_iuid
 | 
				
			||||||
sddl_revision_1
 | 
					sddl_revision_1
 | 
				
			||||||
secp256k1
 | 
					secp256k1
 | 
				
			||||||
secur32
 | 
					secur32
 | 
				
			||||||
see_mask_nocloseprocess
 | 
					 | 
				
			||||||
sfml_project
 | 
					sfml_project
 | 
				
			||||||
shellexecuteinfoa
 | 
					 | 
				
			||||||
shlwapi
 | 
					shlwapi
 | 
				
			||||||
sigchld
 | 
					 | 
				
			||||||
skynet
 | 
					skynet
 | 
				
			||||||
source_subdir
 | 
					source_subdir
 | 
				
			||||||
spdlog
 | 
					spdlog
 | 
				
			||||||
spdlog_project
 | 
					spdlog_project
 | 
				
			||||||
st_ctim
 | 
					st_ctim
 | 
				
			||||||
startf_useshowwindow
 | 
					 | 
				
			||||||
startupinfoa
 | 
					 | 
				
			||||||
static-libgcc
 | 
					static-libgcc
 | 
				
			||||||
static-libstdc++
 | 
					static-libstdc++
 | 
				
			||||||
stbuf
 | 
					stbuf
 | 
				
			||||||
stduuid_project
 | 
					stduuid_project
 | 
				
			||||||
strequal
 | 
					strequal
 | 
				
			||||||
sw_shownoactivate
 | 
					 | 
				
			||||||
ularge_integer
 | 
					ularge_integer
 | 
				
			||||||
uring
 | 
					uring
 | 
				
			||||||
url
 | 
					url
 | 
				
			||||||
@@ -263,7 +227,6 @@ wextra
 | 
				
			|||||||
wfloat
 | 
					wfloat
 | 
				
			||||||
wformat=2
 | 
					wformat=2
 | 
				
			||||||
winfsp
 | 
					winfsp
 | 
				
			||||||
winfsp_drive
 | 
					 | 
				
			||||||
winhttp
 | 
					winhttp
 | 
				
			||||||
wininet
 | 
					wininet
 | 
				
			||||||
winspool
 | 
					winspool
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										3
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
								
							
							
						
						@@ -1,5 +1,4 @@
 | 
				
			|||||||
*.msi filter=lfs diff=lfs merge=lfs -text
 | 
					*.tgz filter=lfs diff=lfs merge=lfs -text
 | 
				
			||||||
*.tar.gz 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
 | 
					*.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
 | 
					*.zip filter=lfs diff=lfs merge=lfs -text
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										13
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						@@ -1,16 +1,13 @@
 | 
				
			|||||||
.DS_Store
 | 
					 | 
				
			||||||
.cache/
 | 
					.cache/
 | 
				
			||||||
.vs/
 | 
					 | 
				
			||||||
Info.plist
 | 
					 | 
				
			||||||
build*/
 | 
					build*/
 | 
				
			||||||
compile_commands.json
 | 
					compile_commands.json
 | 
				
			||||||
cspell.json
 | 
					cspell.json
 | 
				
			||||||
deps/
 | 
					.vs/
 | 
				
			||||||
 | 
					support/Dockerfile
 | 
				
			||||||
dist/
 | 
					dist/
 | 
				
			||||||
override.sh
 | 
					deps/
 | 
				
			||||||
repertory.iss
 | 
					 | 
				
			||||||
scripts/cleanup.cmd
 | 
					scripts/cleanup.cmd
 | 
				
			||||||
scripts/cleanup.sh
 | 
					scripts/cleanup.sh
 | 
				
			||||||
support/Dockerfile
 | 
					 | 
				
			||||||
version.cpp
 | 
					 | 
				
			||||||
version.rc
 | 
					version.rc
 | 
				
			||||||
 | 
					version.cpp
 | 
				
			||||||
 | 
					override.sh
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,88 +5,57 @@ pipeline {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  environment {
 | 
					  environment {
 | 
				
			||||||
    DEVELOPER_PRIVATE_KEY = "/.ci/repertory/cert/developer.priv"
 | 
					    DEVELOPER_PRIVATE_KEY = "/.ci/repertory/cert/developer.priv"
 | 
				
			||||||
    DEVELOPER_PUBLIC_KEY  = "/.ci/repertory/cert/developer.pub"
 | 
					    DEVELOPER_PUBLIC_KEY = "/.ci/repertory/cert/developer.pub"
 | 
				
			||||||
    PROJECT_TEST_CONFIG_DIR = "/.ci/repertory/test"
 | 
					    PROJECT_TEST_CONFIG_DIR = "/.ci/repertory/test_config"
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  options {
 | 
					  options {
 | 
				
			||||||
    disableConcurrentBuilds()
 | 
					    disableConcurrentBuilds()
 | 
				
			||||||
    skipDefaultCheckout()
 | 
					    retry(2)
 | 
				
			||||||
    timestamps()
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  stages {
 | 
					  stages {
 | 
				
			||||||
    stage('Build • Test • Deliver') {
 | 
					    stage('linux_x86_64') {
 | 
				
			||||||
      agent any
 | 
					      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('linux_x86_64') {
 | 
					      steps {
 | 
				
			||||||
          steps {
 | 
					        retry(2) {
 | 
				
			||||||
            script { retryWithBackoff(2, 5) { sh 'scripts/make_unix.sh' } }
 | 
					          sleep time: 5, unit: 'SECONDS'
 | 
				
			||||||
          }
 | 
					          sh 'scripts/make_unix.sh'
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        stage('mingw64') {
 | 
					    stage('mingw64') {
 | 
				
			||||||
          steps {
 | 
					      agent any
 | 
				
			||||||
            script { retryWithBackoff(2, 5) { sh 'scripts/make_win32.sh' } }
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        stage('linux_aarch64') {
 | 
					      steps {
 | 
				
			||||||
          steps {
 | 
					        retry(2) {
 | 
				
			||||||
            script { retryWithBackoff(2, 5) { sh 'scripts/make_unix.sh aarch64' } }
 | 
					          sleep time: 5, unit: 'SECONDS'
 | 
				
			||||||
          }
 | 
					          sh 'scripts/make_win32.sh'
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        stage('linux_x86_64_test') {
 | 
					    stage('linux_aarch64') {
 | 
				
			||||||
          steps {
 | 
					      agent any
 | 
				
			||||||
            script { retryWithBackoff(2, 5) { sh 'scripts/run_tests.sh' } }
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        stage('deliver') {
 | 
					      steps {
 | 
				
			||||||
          steps {
 | 
					        retry(2) {
 | 
				
			||||||
            script {
 | 
					          sleep time: 5, unit: 'SECONDS'
 | 
				
			||||||
              retryWithBackoff(3, 10) { sh 'scripts/deliver.sh /mnt/repertory "" "" "" "" 1 1' }
 | 
					          sh 'scripts/make_unix.sh aarch64'
 | 
				
			||||||
              retryWithBackoff(3, 10) { sh 'scripts/deliver.sh /mnt/repertory "" aarch64' }
 | 
					 | 
				
			||||||
              retryWithBackoff(3, 10) { sh 'scripts/deliver.sh /mnt/repertory' }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    stage('deliver') {
 | 
				
			||||||
 | 
					      agent any
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      steps {
 | 
				
			||||||
 | 
					        sh 'scripts/deliver.sh /mnt/repertory "" "" "" "" 1 1'
 | 
				
			||||||
 | 
					        sh 'scripts/deliver.sh /mnt/repertory "" aarch64'
 | 
				
			||||||
 | 
					        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'
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,79 +0,0 @@
 | 
				
			|||||||
#!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'
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,68 +0,0 @@
 | 
				
			|||||||
#!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'
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										89
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						@@ -1,93 +1,24 @@
 | 
				
			|||||||
# Changelog
 | 
					# Changelog
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## v2.1.0-rc.2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Issues
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* \#21 [unit test] Complete WinFSP unit tests
 | 
					 | 
				
			||||||
* \#65 [bug] Mount state is not being removed after unmount on Windows
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Changes from v2.0.7-release
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
* Fixed Windows setup icon location
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## v2.1.0-rc
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### BREAKING CHANGES
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Mount state has been moved into the configuration directory
 | 
					 | 
				
			||||||
  * Unmount all active mounts prior to upgrade
 | 
					 | 
				
			||||||
* Remote mounts must be upgraded to v2.1.0+ to support new authentication scheme
 | 
					 | 
				
			||||||
  * Protocol handshake added for DoS protection
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<!-- markdownlint-disable-next-line -->
 | 
					 | 
				
			||||||
### Issues
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* \#12 [unit test] Complete all providers unit tests
 | 
					 | 
				
			||||||
* \#22 [unit test] Complete FUSE unit tests
 | 
					 | 
				
			||||||
* \#33 Complete initial v2.0 documentation
 | 
					 | 
				
			||||||
* \#34 Add macOS support
 | 
					 | 
				
			||||||
* \#38 Pinning a file should automatically initiate a download to cache
 | 
					 | 
				
			||||||
* \#51 [ui] UI console window should close after launch
 | 
					 | 
				
			||||||
* \#52 [ui] Add auto-mount on first launch functionality
 | 
					 | 
				
			||||||
* \#53 Create Windows installer
 | 
					 | 
				
			||||||
* \#54 Remove 'default' as initial bucket name for Sia
 | 
					 | 
				
			||||||
* \#58 Create macOS bundle for simplified installation
 | 
					 | 
				
			||||||
* \#59 [bug] [ui] UI is hanging after launching repertory mount in background
 | 
					 | 
				
			||||||
* \#60 Implement secure key via KDF for transparent data encryption/decryption
 | 
					 | 
				
			||||||
* \#61 [ui] UI theme should match repertory blue
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Changes from v2.0.7-release
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Added check version support to remote mounts
 | 
					 | 
				
			||||||
* Fixed directory item count bug on S3 provider
 | 
					 | 
				
			||||||
* Fixed handling of `FALLOC_FL_KEEP_SIZE` on Linux
 | 
					 | 
				
			||||||
* Fixed intermittent client hang on remote mount server disconnect
 | 
					 | 
				
			||||||
* Implemented POSIX-compliant `unlink()` with FUSE `hard_remove`
 | 
					 | 
				
			||||||
  * Open handles remain valid after `unlink()`
 | 
					 | 
				
			||||||
* Refactored CLI messages and error handling to use common methods
 | 
					 | 
				
			||||||
* Enhanced remote mount client thread mapping
 | 
					 | 
				
			||||||
  * Threads are now mapped 1-1 from client to server instead of being tied to a fixed-size thread pool
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## v2.0.7-release
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<!-- markdownlint-disable-next-line -->
 | 
					 | 
				
			||||||
### Issues
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* \#55 [bug] UI is unable to launch `repertory.exe` on Windows when absolute path contains spaces
 | 
					 | 
				
			||||||
* \#57 [bug] Directory entries . and .. are incorrectly being reported as files in Linux remote mounts
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## v2.0.6-release
 | 
					## v2.0.6-release
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<!-- markdownlint-disable-next-line -->
 | 
					 | 
				
			||||||
### Issues
 | 
					### Issues
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* ~~\#12 [Unit Test] Complete all providers unit tests~~
 | 
				
			||||||
 | 
					* ~~\#21 [Unit Test] Complete WinFSP unit tests~~
 | 
				
			||||||
 | 
					* ~~\#22 [Unit Test] Complete FUSE unit tests~~
 | 
				
			||||||
 | 
					* ~~\#33 Complete initial v2.0 documentation~~
 | 
				
			||||||
* \#42 [bug] Remote mount directory listing on Windows connected to Linux is failing
 | 
					* \#42 [bug] Remote mount directory listing on Windows connected to Linux is failing
 | 
				
			||||||
* \#43 [bug] Directories are not importing properly for Sia
 | 
					* \#43 [bug] Directories are not importing properly for Sia
 | 
				
			||||||
* \#44 [bug] Windows-to-Linux remote mount ignores `CREATE_NEW`
 | 
					* \#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
 | 
					* \#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
 | 
					* \#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
 | 
					* \#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
 | 
					### 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
 | 
					* 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
 | 
					* Migrated to v2 error handling
 | 
				
			||||||
* Upgraded WinFSP to v2.1 (2025)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
## v2.0.5-rc
 | 
					## v2.0.5-rc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -106,8 +37,6 @@
 | 
				
			|||||||
* Renamed setting `ApiAuth` to `ApiPassword`
 | 
					* Renamed setting `ApiAuth` to `ApiPassword`
 | 
				
			||||||
* Require `--name,-na` option for encryption provider
 | 
					* Require `--name,-na` option for encryption provider
 | 
				
			||||||
 | 
					
 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## v2.0.4-rc
 | 
					## v2.0.4-rc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### BREAKING CHANGES
 | 
					### BREAKING CHANGES
 | 
				
			||||||
@@ -135,8 +64,6 @@
 | 
				
			|||||||
* Refactored `app_config` unit tests
 | 
					* Refactored `app_config` unit tests
 | 
				
			||||||
* Refactored polling to be more accurate on scheduling tasks
 | 
					* Refactored polling to be more accurate on scheduling tasks
 | 
				
			||||||
 | 
					
 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## v2.0.3-rc
 | 
					## v2.0.3-rc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<!-- markdownlint-disable-next-line -->
 | 
					<!-- markdownlint-disable-next-line -->
 | 
				
			||||||
@@ -161,8 +88,6 @@
 | 
				
			|||||||
* Updated build system to MinGW-w64 12.0.0
 | 
					* Updated build system to MinGW-w64 12.0.0
 | 
				
			||||||
* Updated copyright to 2018-2025
 | 
					* Updated copyright to 2018-2025
 | 
				
			||||||
 | 
					
 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## v2.0.2-rc
 | 
					## v2.0.2-rc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<!-- markdownlint-disable-next-line -->
 | 
					<!-- markdownlint-disable-next-line -->
 | 
				
			||||||
@@ -195,8 +120,6 @@
 | 
				
			|||||||
* Corrected handling of `chown()` and `chmod()`
 | 
					* Corrected handling of `chown()` and `chmod()`
 | 
				
			||||||
* Fixed erroneous download of chunks after resize
 | 
					* Fixed erroneous download of chunks after resize
 | 
				
			||||||
 | 
					
 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## v2.0.1-rc
 | 
					## v2.0.1-rc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<!-- markdownlint-disable-next-line -->
 | 
					<!-- markdownlint-disable-next-line -->
 | 
				
			||||||
@@ -219,8 +142,6 @@
 | 
				
			|||||||
* Updated `curl` to v8.4.0
 | 
					* Updated `curl` to v8.4.0
 | 
				
			||||||
* Updated `libsodium` to v1.0.19
 | 
					* Updated `libsodium` to v1.0.19
 | 
				
			||||||
 | 
					
 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## v2.0.0-rc
 | 
					## v2.0.0-rc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<!-- markdownlint-disable-next-line -->
 | 
					<!-- markdownlint-disable-next-line -->
 | 
				
			||||||
@@ -265,5 +186,3 @@
 | 
				
			|||||||
  * Supports re-upload after mount restart for incomplete uploads
 | 
					  * Supports re-upload after mount restart for incomplete uploads
 | 
				
			||||||
  * NOTE: Uploads for all providers are full file (no resume support)
 | 
					  * NOTE: Uploads for all providers are full file (no resume support)
 | 
				
			||||||
    * Multipart upload support is planned for S3
 | 
					    * Multipart upload support is planned for S3
 | 
				
			||||||
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -51,10 +51,6 @@ if(PROJECT_IS_ARM64)
 | 
				
			|||||||
  add_definitions(-DPROJECT_IS_ARM64)
 | 
					  add_definitions(-DPROJECT_IS_ARM64)
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if(PROJECT_IS_DARWIN)
 | 
					 | 
				
			||||||
  add_definitions(-DPROJECT_IS_DARWIN)
 | 
					 | 
				
			||||||
endif()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if(PROJECT_IS_MINGW)
 | 
					if(PROJECT_IS_MINGW)
 | 
				
			||||||
  option(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES "Enable path sizes of 32767 characters on Windows" OFF)
 | 
					  option(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES "Enable path sizes of 32767 characters on Windows" OFF)
 | 
				
			||||||
  if(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
 | 
					  if(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
 | 
				
			||||||
@@ -119,24 +115,6 @@ if(PROJECT_BUILD)
 | 
				
			|||||||
    ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/version.cpp
 | 
					    ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/version.cpp
 | 
				
			||||||
    @ONLY
 | 
					    @ONLY
 | 
				
			||||||
  )
 | 
					  )
 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (PROJECT_IS_MINGW AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${PROJECT_NAME}.iss.in")
 | 
					 | 
				
			||||||
    configure_file(
 | 
					 | 
				
			||||||
      ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${PROJECT_NAME}.iss.in 
 | 
					 | 
				
			||||||
      ${PROJECT_DIST_DIR}/../${PROJECT_NAME}.iss
 | 
					 | 
				
			||||||
      @ONLY
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
  endif()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (PROJECT_IS_DARWIN AND EXISTS "${CMAKE_SOURCE_DIR}/${PROJECT_NAME}/Info.plist.in")
 | 
					 | 
				
			||||||
    configure_file(
 | 
					 | 
				
			||||||
      ${CMAKE_SOURCE_DIR}/${PROJECT_NAME}/Info.plist.in
 | 
					 | 
				
			||||||
      ${CMAKE_SOURCE_DIR}/${PROJECT_NAME}/Info.plist
 | 
					 | 
				
			||||||
      @ONLY
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
  endif()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  find_package(ICU REQUIRED COMPONENTS data i18n io uc)
 | 
					 | 
				
			||||||
else()
 | 
					else()
 | 
				
			||||||
  message(STATUS "-=[CMake Settings]=-")
 | 
					  message(STATUS "-=[CMake Settings]=-")
 | 
				
			||||||
  message(STATUS "  C standard: ${CMAKE_C_STANDARD}")
 | 
					  message(STATUS "  C standard: ${CMAKE_C_STANDARD}")
 | 
				
			||||||
@@ -192,12 +170,9 @@ endif()
 | 
				
			|||||||
      -DPROJECT_INTERFACE=1
 | 
					      -DPROJECT_INTERFACE=1
 | 
				
			||||||
      -DPROJECT_IS_ALPINE=${PROJECT_IS_ALPINE}
 | 
					      -DPROJECT_IS_ALPINE=${PROJECT_IS_ALPINE}
 | 
				
			||||||
      -DPROJECT_IS_ARM64=${PROJECT_IS_ARM64}
 | 
					      -DPROJECT_IS_ARM64=${PROJECT_IS_ARM64}
 | 
				
			||||||
      -DPROJECT_IS_DARWIN=${PROJECT_IS_DARWIN}
 | 
					 | 
				
			||||||
      -DPROJECT_IS_MINGW=${PROJECT_IS_MINGW}
 | 
					      -DPROJECT_IS_MINGW=${PROJECT_IS_MINGW}
 | 
				
			||||||
      -DPROJECT_IS_MINGW_UNIX=${PROJECT_IS_MINGW_UNIX}
 | 
					      -DPROJECT_IS_MINGW_UNIX=${PROJECT_IS_MINGW_UNIX}
 | 
				
			||||||
      -DPROJECT_MAJOR_VERSION=${PROJECT_MAJOR_VERSION}
 | 
					      -DPROJECT_MAJOR_VERSION=${PROJECT_MAJOR_VERSION}
 | 
				
			||||||
      -DPROJECT_MACOS_BUNDLE_ID=${PROJECT_MACOS_BUNDLE_ID}
 | 
					 | 
				
			||||||
      -DPROJECT_MACOS_ICNS_NAME=${PROJECT_MACOS_ICNS_NAME}
 | 
					 | 
				
			||||||
      -DPROJECT_MINOR_VERSION=${PROJECT_MINOR_VERSION}
 | 
					      -DPROJECT_MINOR_VERSION=${PROJECT_MINOR_VERSION}
 | 
				
			||||||
      -DPROJECT_NAME=${PROJECT_NAME}
 | 
					      -DPROJECT_NAME=${PROJECT_NAME}
 | 
				
			||||||
      -DPROJECT_RELEASE_ITER=${PROJECT_RELEASE_ITER}
 | 
					      -DPROJECT_RELEASE_ITER=${PROJECT_RELEASE_ITER}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										873
									
								
								README.md
									
									
									
									
									
								
							
							
						
						@@ -1,375 +1,153 @@
 | 
				
			|||||||
# Repertory
 | 
					# Repertory
 | 
				
			||||||
> /rĕp′ər-tôr″ē/  
 | 
					 | 
				
			||||||
> noun  
 | 
					 | 
				
			||||||
> *A place, such as a storehouse, where a stock of things is kept; a repository*
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Repertory allows you to mount **S3** and **Sia** storage as local drives using:
 | 
					Repertory allows you to mount S3 and Sia via FUSE on Linux or via WinFSP
 | 
				
			||||||
 | 
					on Windows.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- **FUSE** (Linux/macOS)
 | 
					## Contents
 | 
				
			||||||
- **WinFSP** (Windows)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
It supports:
 | 
					1. [Details and Features](#details-and-features)
 | 
				
			||||||
 | 
					2. [Minimum Requirements](#minimum-requirements)
 | 
				
			||||||
 | 
					   1. [Supported Operating Systems](#supported-operating-systems)
 | 
				
			||||||
 | 
					3. [GUI](#gui)
 | 
				
			||||||
 | 
					4. [Usage](#usage)
 | 
				
			||||||
 | 
					   1. [Important Options](#important-options)
 | 
				
			||||||
 | 
					   2. [Sia](#sia)
 | 
				
			||||||
 | 
					      * [Sia Initial Configuration](#sia-initial-configuration)
 | 
				
			||||||
 | 
					      * [Sia Mounting](#sia-mounting)
 | 
				
			||||||
 | 
					      * [Sia Configuration File](#sia-configuration-file)
 | 
				
			||||||
 | 
					   3. [S3](#s3)
 | 
				
			||||||
 | 
					      * [S3 Initial Configuration](#s3-initial-configuration)
 | 
				
			||||||
 | 
					      * [S3 Mounting](#s3-mounting)
 | 
				
			||||||
 | 
					      * [S3 Configuration File](#s3-configuration-file)
 | 
				
			||||||
 | 
					5. [Data Directories](#data-directories)
 | 
				
			||||||
 | 
					   1. [Linux Directories](#linux-directories)
 | 
				
			||||||
 | 
					   2. [Windows Directories](#windows-directories)
 | 
				
			||||||
 | 
					6. [Remote Mounting](#remote-mounting)
 | 
				
			||||||
 | 
					   1. [Server Setup](#server-setup)
 | 
				
			||||||
 | 
					      * [Remote Mount Configuration File Section](#remote-mount-configuration-file-section)
 | 
				
			||||||
 | 
					   2. [Client Setup](#client-setup)
 | 
				
			||||||
 | 
					      * [Client Remote Mounting](#client-remote-mounting)
 | 
				
			||||||
 | 
					      * [Remote Mount Configuration File](#remote-mount-configuration-file)
 | 
				
			||||||
 | 
					7. [Compiling](#compiling)
 | 
				
			||||||
 | 
					   1. [Linux Compilation](#linux-compilation)
 | 
				
			||||||
 | 
					   2. [Windows Setup](#windows-compilation)
 | 
				
			||||||
 | 
					8. [Credits](#credits)
 | 
				
			||||||
 | 
					9. [Developer Public Key](#developer-public-key)
 | 
				
			||||||
 | 
					10. [Consult the Wiki for additional information](https://git.fifthgrid.com/BlockStorage/repertory/wiki)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- Local mounts
 | 
					## Details and Features
 | 
				
			||||||
- Remote encrypted mounts between systems
 | 
					 | 
				
			||||||
- Optional file name and data encryption using `XChaCha20-Poly1305` and `Argon2id` for key generation
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
---
 | 
					* Optimized for [Plex Media Server](https://www.plex.tv/)
 | 
				
			||||||
 | 
					* Remote mounting of `repertory` instances on Linux and 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 64-bit, Linux arm64/aarch64, Windows 64-bit)
 | 
				
			||||||
 | 
					* Optionally encrypt file names and file data via `XChaCha20-Poly1305` in S3 mounts
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## 📖 Contents
 | 
					## Minimum Requirements
 | 
				
			||||||
 | 
					
 | 
				
			||||||
1. [Quick Start (Sia Example)](#-quick-start-sia-example)
 | 
					* [Sia renterd](https://github.com/SiaFoundation/renterd/releases) v2.0.0+ for Sia support
 | 
				
			||||||
2. [Details & Features](#-details-and-features)
 | 
					* Linux requires `fusermount3`; otherwise, `repertory` must be manually compiled with `libfuse2` support
 | 
				
			||||||
3. [Minimum Requirements](#-minimum-requirements)
 | 
					* Windows requires the following dependencies to be installed:
 | 
				
			||||||
   - [Supported Operating Systems](#supported-operating-systems)
 | 
					  * [WinFSP 2023](https://github.com/winfsp/winfsp/releases/download/v2.0/winfsp-2.0.23075.msi)
 | 
				
			||||||
4. [Data Directories](#-data-directories)
 | 
					 | 
				
			||||||
5. [GUI](#-gui)
 | 
					 | 
				
			||||||
6. [Usage](#-usage)
 | 
					 | 
				
			||||||
   - [Important Options](#important-options)
 | 
					 | 
				
			||||||
   - [Unmounting](#unmounting)
 | 
					 | 
				
			||||||
7. [Sia Setup](#-sia-setup)
 | 
					 | 
				
			||||||
   - [Sia Initial Configuration](#sia-initial-configuration)
 | 
					 | 
				
			||||||
   - [Sia Mounting](#sia-mounting)
 | 
					 | 
				
			||||||
   - [Sia Configuration File](#sia-configuration-file)
 | 
					 | 
				
			||||||
8. [S3 Setup](#-s3-setup)
 | 
					 | 
				
			||||||
   - [S3 Initial Configuration](#s3-initial-configuration)
 | 
					 | 
				
			||||||
   - [S3 Mounting](#s3-mounting)
 | 
					 | 
				
			||||||
   - [S3 Configuration File](#s3-configuration-file)
 | 
					 | 
				
			||||||
9. [Remote Mounting](#-remote-mounting)
 | 
					 | 
				
			||||||
   - [Server Setup](#server-setup)
 | 
					 | 
				
			||||||
   - [Client Setup](#client-setup)
 | 
					 | 
				
			||||||
   - [Remote Mount Configuration File](#remote-mount-configuration-file)
 | 
					 | 
				
			||||||
10. [Compiling from Source](#-compiling)
 | 
					 | 
				
			||||||
    - [Linux Compilation](#linux-compilation)
 | 
					 | 
				
			||||||
    - [macOS Compilation](#macos-compilation)
 | 
					 | 
				
			||||||
    - [Windows Compilation](#windows-compilation)
 | 
					 | 
				
			||||||
11. [Credits](#-credits)
 | 
					 | 
				
			||||||
12. [Developer Public Key](#-developer-public-key)
 | 
					 | 
				
			||||||
13. [Consult the Wiki for additional information](https://git.fifthgrid.com/BlockStorage/repertory/wiki)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## 🚀 Quick Start (Sia Example)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
> 💡 Want to mount S3 instead?  
 | 
					 | 
				
			||||||
> Skip ahead to [S3 Setup](#-s3-setup) — the process is almost identical.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This example mounts a Sia bucket from a running [renterd](https://github.com/SiaFoundation/renterd) instance.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### 1. Install dependencies
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#### Linux
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
``` shell
 | 
					 | 
				
			||||||
sudo apt install fuse3   # Debian/Ubuntu
 | 
					 | 
				
			||||||
# or
 | 
					 | 
				
			||||||
sudo dnf install fuse3   # Fedora
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#### macOS
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- Install [macFUSE 5.0.7](https://github.com/macfuse/macfuse/releases/download/macfuse-5.0.7/macfuse-5.0.7.dmg)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#### Windows
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- Install [WinFSP 2025](https://github.com/winfsp/winfsp/releases/download/v2.1/winfsp-2.1.25156.msi)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### 2. Configure
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Replace placeholders with your actual values:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
``` shell
 | 
					 | 
				
			||||||
repertory --name mybucket -set HostConfig.ApiPassword "<renterd api password>"
 | 
					 | 
				
			||||||
repertory --name mybucket -set SiaConfig.Bucket "<bucket name>"
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Optional:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
``` shell
 | 
					 | 
				
			||||||
# If renterd is not running locally
 | 
					 | 
				
			||||||
repertory --name mybucket -set HostConfig.HostNameOrIp "<hostname or IP>"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# If renterd uses a non-default port (default 9980)
 | 
					 | 
				
			||||||
repertory --name mybucket -set HostConfig.ApiPort <port>
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### 3. Mount
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<!-- markdownlint-disable-next-line -->
 | 
					 | 
				
			||||||
#### Linux
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
``` shell
 | 
					 | 
				
			||||||
repertory --name mybucket /mnt/mybucket
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<!-- markdownlint-disable-next-line -->
 | 
					 | 
				
			||||||
#### macOS
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
``` shell
 | 
					 | 
				
			||||||
repertory --name mybucket /Volumes/mybucket
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<!-- markdownlint-disable-next-line -->
 | 
					 | 
				
			||||||
#### Windows
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
``` shell
 | 
					 | 
				
			||||||
repertory --name mybucket t:
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### 4. Unmount
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
``` shell
 | 
					 | 
				
			||||||
repertory --name mybucket --unmount
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## ✨ Details and Features
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- **Optimized for [Plex Media Server](https://www.plex.tv/).**
 | 
					 | 
				
			||||||
- Remote mounting of `repertory` instances between Linux, macOS, and/or Windows.
 | 
					 | 
				
			||||||
  - Securely share your mounts over TCP/IP via `XChaCha20-Poly1305` with other systems on your network or over the internet.
 | 
					 | 
				
			||||||
- Cross-platform support (Linux, macOS, and Windows).
 | 
					 | 
				
			||||||
- Optionally encrypt file names and file data via `XChaCha20-Poly1305` in S3 mounts.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## 📋 Minimum Requirements
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- **Sia:** [renterd](https://github.com/SiaFoundation/renterd/releases) v2.0.0+ for Sia support
 | 
					 | 
				
			||||||
- **Linux:** requires `fusermount3`; otherwise, `repertory` must be manually compiled with `libfuse2` support
 | 
					 | 
				
			||||||
- **macOS:** requires:
 | 
					 | 
				
			||||||
  - [macFUSE 5.0.7](https://github.com/macfuse/macfuse/releases/download/macfuse-5.0.7/macfuse-5.0.7.dmg)
 | 
					 | 
				
			||||||
- **Windows:** requires:
 | 
					 | 
				
			||||||
  - [WinFSP 2025](https://github.com/winfsp/winfsp/releases/download/v2.1/winfsp-2.1.25156.msi)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Supported Operating Systems
 | 
					### Supported Operating Systems
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Only **64-bit operating systems** are supported:
 | 
					Only 64-bit operating systems are supported
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- Linux `arm64/aarch64`
 | 
					* Linux `arm64/aarch64`
 | 
				
			||||||
- Linux `x86_64`
 | 
					* Linux `amd64`
 | 
				
			||||||
- macOS `arm64/aarch64`
 | 
					* Windows 64-bit 10, 11
 | 
				
			||||||
- macOS `x86_64`
 | 
					 | 
				
			||||||
- Windows `x86_64` 10, 11
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
---
 | 
					## GUI
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## 📂 Data Directories
 | 
					As of `v2.0.5-rc`, mounts can be managed using the `Repertory Management Portal`.
 | 
				
			||||||
 | 
					To launch the portal, execute the following command:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<!-- markdownlint-disable-next-line -->
 | 
					* `repertory -ui`
 | 
				
			||||||
### Linux
 | 
					  * The default username is `repertory`
 | 
				
			||||||
 | 
					  * The default password is `repertory`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
``` shell
 | 
					After first launch, `ui.json` will be created in the appropriate data directory.
 | 
				
			||||||
# Mounts
 | 
					See [Data Directories](#data-directories).
 | 
				
			||||||
~/.local/repertory2/encrypt
 | 
					You should modify this file directly or use the portal to change the default
 | 
				
			||||||
~/.local/repertory2/s3
 | 
					username and password.
 | 
				
			||||||
~/.local/repertory2/sia
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
# UI
 | 
					### Screenshot
 | 
				
			||||||
~/.local/repertory2
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
### macOS
 | 
					<a href="https://ibb.co/fVyJqnbF"><img src="https://i.ibb.co/fVyJqnbF/repertory-portal.png" alt="repertory-portal" border="0"></a>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
``` shell
 | 
					## Usage
 | 
				
			||||||
# Mounts
 | 
					 | 
				
			||||||
~/Library/Application Support/repertory2/encrypt
 | 
					 | 
				
			||||||
~/Library/Application Support/repertory2/s3
 | 
					 | 
				
			||||||
~/Library/Application Support/repertory2/sia
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# UI
 | 
					 | 
				
			||||||
~/Library/Application Support/repertory2
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
<!-- markdownlint-disable-next-line -->
 | 
					 | 
				
			||||||
### Windows
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
``` cmd
 | 
					 | 
				
			||||||
:: Mounts
 | 
					 | 
				
			||||||
%LOCALAPPDATA%\repertory2\encrypt
 | 
					 | 
				
			||||||
%LOCALAPPDATA%\repertory2\s3
 | 
					 | 
				
			||||||
%LOCALAPPDATA%\repertory2\sia
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
:: UI
 | 
					 | 
				
			||||||
%LOCALAPPDATA%\repertory2
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
**IMPORTANT:**  
 | 
					 | 
				
			||||||
It is highly recommended to **exclude** these folders from any anti-virus/anti-malware applications as severe performance issues may arise. Excluding the mounted drive letter is also highly recommended.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## 🖥 GUI
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
As of `v2.0.6-release`, mounts can be managed using the **Repertory Management Portal**.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Launch the portal:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
``` shell
 | 
					 | 
				
			||||||
repertory -ui
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### ⚠️ Security tip
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- Change the default UI credentials on first launch (`ui.json`) or via the portal
 | 
					 | 
				
			||||||
- Default username: `repertory`
 | 
					 | 
				
			||||||
- Default password: `repertory`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
After first launch, `ui.json` will be created in the appropriate data directory (see [Data Directories](#-data-directories)). Modify this file directly or use the portal to change the default credentials.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Screenshots
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#### Login screen
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||

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

 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## 🛠 Usage
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Important Options
 | 
					### Important Options
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- `--help`  
 | 
					* `--help`
 | 
				
			||||||
  Display all mount utility options.
 | 
					  * Display all mount utility options
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- `-f`  
 | 
					* `-f`
 | 
				
			||||||
  Keep process in foreground on Linux.
 | 
					  * Keep process in foreground on Linux.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- `--name, -na [name]`  
 | 
					* `--name, -na [name]`
 | 
				
			||||||
  Identifies a unique configuration name to support multiple mounts.  
 | 
					  * 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 can be set to any valid value allowed as a file name for your filesystem.
 | 
				
			||||||
  **The `--name` option is required.**
 | 
					  * 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.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- `-dc`  
 | 
					* `-dc`
 | 
				
			||||||
  Display mount configuration.  
 | 
					  * Display mount configuration
 | 
				
			||||||
  For Sia, the `--name` option is required.  
 | 
					  * For Sia, `--name` is optional
 | 
				
			||||||
  For S3, the `-s3` and `--name` options are required.
 | 
					  * For S3, the `-s3` option is required along with `--name`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Unmounting
 | 
					### Sia
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#### Remote
 | 
					#### Sia Initial Configuration
 | 
				
			||||||
 | 
					
 | 
				
			||||||
``` shell
 | 
					* Required steps:
 | 
				
			||||||
repertory -rm 192.168.0.1:20000 --unmount
 | 
					  * Set the appropriate bucket name and `renterd` API password in `repertory` configuration:
 | 
				
			||||||
```
 | 
					    * To use `default` as the bucket name and configuration name, you only need to set the `renterd` API password:
 | 
				
			||||||
 | 
					      * `repertory -set HostConfig.ApiPassword '<my password>'`
 | 
				
			||||||
 | 
					    * To specify a different bucket name while using `default` as the configuration name:
 | 
				
			||||||
 | 
					      * `repertory -set HostConfig.ApiPassword '<my password>'`
 | 
				
			||||||
 | 
					      * `repertory -set SiaConfig.Bucket '<my bucket>'`
 | 
				
			||||||
 | 
					    * For all other configurations:
 | 
				
			||||||
 | 
					      * `repertory --name '<my config name>' -set HostConfig.ApiPassword '<my password>'`
 | 
				
			||||||
 | 
					      * `repertory --name '<my config name>' -set SiaConfig.Bucket '<my bucket name>'`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#### S3
 | 
					* Optional steps:
 | 
				
			||||||
 | 
					  * Set a user name used during `renterd` basic authentication:
 | 
				
			||||||
 | 
					    * `repertory -set HostConfig.ApiUser '<my user>'`
 | 
				
			||||||
 | 
					    * `repertory --name '<my config name>' -set HostConfig.ApiUser '<my user>'`
 | 
				
			||||||
 | 
					  * Set a custom agent string (default `Sia-Agent`):
 | 
				
			||||||
 | 
					    * `repertory -set HostConfig.AgentString '<my agent>'`
 | 
				
			||||||
 | 
					    * `repertory --name '<my config name>' -set HostConfig.AgentString '<my agent>'`
 | 
				
			||||||
 | 
					  * Set the host name or IP of the `renterd` instance (default `localhost`):
 | 
				
			||||||
 | 
					    * `repertory -set HostConfig.HostNameOrIp '<my host name>'`
 | 
				
			||||||
 | 
					    * `repertory --name '<my config name>' -set HostConfig.HostNameOrIp '<my host name>'`
 | 
				
			||||||
 | 
					  * Set the `renterd` API port (default `9980`):
 | 
				
			||||||
 | 
					    * `repertory -set HostConfig.ApiPort 9981`
 | 
				
			||||||
 | 
					    * `repertory --name '<my config name>' -set HostConfig.ApiPort 9981`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
``` shell
 | 
					* To verify/view all configuration options:
 | 
				
			||||||
repertory -s3 --name '<my config name>' --unmount
 | 
					  * `repertory -dc`
 | 
				
			||||||
```
 | 
					  * `repertory --name '<my config name>' -dc`
 | 
				
			||||||
 | 
					    * Example:
 | 
				
			||||||
 | 
					      * `repertory --name default -dc`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#### Sia
 | 
					#### Sia Mounting
 | 
				
			||||||
 | 
					
 | 
				
			||||||
``` shell
 | 
					* Linux:
 | 
				
			||||||
repertory --name '<my config name>' --unmount
 | 
					  * `repertory /mnt/location`
 | 
				
			||||||
```
 | 
					  * `repertory --name '<my config name>' /mnt/location`
 | 
				
			||||||
 | 
					    * Example:
 | 
				
			||||||
 | 
					      * `repertory --name default /mnt/location`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
---
 | 
					* Windows:
 | 
				
			||||||
 | 
					  * `repertory t:`
 | 
				
			||||||
 | 
					  * `repertory --name '<my config name>' t:`
 | 
				
			||||||
 | 
					    * Example:
 | 
				
			||||||
 | 
					      * `repertory --name default t:`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## 🔒 Security Best Practices
 | 
					#### Sia Configuration File
 | 
				
			||||||
 | 
					 | 
				
			||||||
When enabling **encryption tokens** for S3 or remote mounts:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- Use a **long, random string**.
 | 
					 | 
				
			||||||
- Store it **offline** (password manager and an offline backup).
 | 
					 | 
				
			||||||
- Losing it means **permanent data loss**.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<!-- markdownlint-disable-next-line -->
 | 
					 | 
				
			||||||
<a id="sia-setup"></a>
 | 
					 | 
				
			||||||
<!-- markdownlint-disable-next-line -->
 | 
					 | 
				
			||||||
<a id="-sia-setup"></a>
 | 
					 | 
				
			||||||
## ☁️ Sia Setup
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Sia Initial Configuration
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
**Required steps:**
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- Set the appropriate bucket name and `renterd` API password in `repertory` configuration:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
``` shell
 | 
					 | 
				
			||||||
repertory --name '<my config name>' -set HostConfig.ApiPassword '<my password>'
 | 
					 | 
				
			||||||
repertory --name '<my config name>' -set SiaConfig.Bucket '<my bucket name>'
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
**Optional steps:**
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- Set a user name used during `renterd` basic authentication:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
``` shell
 | 
					 | 
				
			||||||
repertory --name '<my config name>' -set HostConfig.ApiUser '<my user>'
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- Set a custom agent string (default `Sia-Agent`):
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
``` shell
 | 
					 | 
				
			||||||
repertory --name '<my config name>' -set HostConfig.AgentString '<my agent>'
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- Set the host name or IP of the `renterd` instance (default `localhost`):
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
``` shell
 | 
					 | 
				
			||||||
repertory --name '<my config name>' -set HostConfig.HostNameOrIp '<my host name>'
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- Set the `renterd` API port (default `9980`):
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
``` shell
 | 
					 | 
				
			||||||
repertory --name '<my config name>' -set HostConfig.ApiPort 9981
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
**Verify/view all configuration options:**
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
``` shell
 | 
					 | 
				
			||||||
repertory --name '<my config name>' -dc
 | 
					 | 
				
			||||||
# Example:
 | 
					 | 
				
			||||||
repertory --name my_bucket -dc
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Sia Mounting
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<!-- markdownlint-disable-next-line -->
 | 
					 | 
				
			||||||
#### Linux
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
``` shell
 | 
					 | 
				
			||||||
repertory --name '<my config name>' /mnt/location
 | 
					 | 
				
			||||||
# Example:
 | 
					 | 
				
			||||||
repertory --name my_bucket /mnt/location
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<!-- markdownlint-disable-next-line -->
 | 
					 | 
				
			||||||
#### macOS
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
``` shell
 | 
					 | 
				
			||||||
repertory --name '<my config name>' /Volumes/mybucket
 | 
					 | 
				
			||||||
# Example:
 | 
					 | 
				
			||||||
repertory --name my_bucket /Volumes/mybucket
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<!-- markdownlint-disable-next-line -->
 | 
					 | 
				
			||||||
#### Windows
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
``` shell
 | 
					 | 
				
			||||||
repertory --name '<my config name>' t:
 | 
					 | 
				
			||||||
# Example:
 | 
					 | 
				
			||||||
repertory --name my_bucket t:
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Sia Configuration File
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
```json
 | 
					```json
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -409,105 +187,55 @@ repertory --name my_bucket t:
 | 
				
			|||||||
  "RetryReadCount": 6,
 | 
					  "RetryReadCount": 6,
 | 
				
			||||||
  "RingBufferFileSize": 512,
 | 
					  "RingBufferFileSize": 512,
 | 
				
			||||||
  "SiaConfig": {
 | 
					  "SiaConfig": {
 | 
				
			||||||
    "Bucket": "my_bucket"
 | 
					    "Bucket": "default"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "TaskWaitMs": 100,
 | 
					  "TaskWaitMs": 100,
 | 
				
			||||||
  "Version": 1
 | 
					  "Version": 1
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
---
 | 
					### S3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## 🪣 S3 Setup
 | 
					#### S3 Initial Configuration
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### S3 Initial Configuration
 | 
					* Required steps:
 | 
				
			||||||
 | 
					  * Set the appropriate base URL:
 | 
				
			||||||
 | 
					    * `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:
 | 
				
			||||||
 | 
					    * `repertory -s3 --name '<my config name>' -set S3Config.Bucket '<my bucket name>'`
 | 
				
			||||||
 | 
					  * Set the appropriate access key:
 | 
				
			||||||
 | 
					    * `repertory -s3 --name '<my config name>' -set S3Config.AccessKey '<my access key>'`
 | 
				
			||||||
 | 
					  * Set the appropriate secret key:
 | 
				
			||||||
 | 
					    * `repertory -s3 --name '<my config name>' -set S3Config.SecretKey '<my secret key>'`
 | 
				
			||||||
 | 
					  * For Sia and most local S3 gateway instances, enable path style URL's:
 | 
				
			||||||
 | 
					    * `repertory -s3 --name '<my config name>' -set S3Config.UsePathStyle true`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
**Required steps:**
 | 
					* Optional steps:
 | 
				
			||||||
 | 
					  * Set an appropriate region. Default is set to `any`:
 | 
				
			||||||
 | 
					    * `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 be sure to store it in a secure backup location:
 | 
				
			||||||
 | 
					    * `repertory -s3 --name '<my config name>' -set S3Config.EncryptionToken '<my strong password>'`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- Set the appropriate base URL:
 | 
					* To verify/view all configuration options:
 | 
				
			||||||
 | 
					  * `repertory -s3 --name '<my config name>' -dc`
 | 
				
			||||||
 | 
					    * Example:
 | 
				
			||||||
 | 
					      * `repertory -s3 --name minio -dc`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
``` shell
 | 
					#### S3 Mounting
 | 
				
			||||||
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:
 | 
					* Linux:
 | 
				
			||||||
 | 
					  * `repertory -s3 --name '<my config name>' /mnt/location`
 | 
				
			||||||
 | 
					    * Example:
 | 
				
			||||||
 | 
					      * `repertory -s3 --name minio /mnt/location`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
``` shell
 | 
					* Windows:
 | 
				
			||||||
repertory -s3 --name '<my config name>' -set S3Config.Bucket '<my bucket name>'
 | 
					  * `repertory -s3 --name '<my config name>' t:`
 | 
				
			||||||
```
 | 
					    * Example:
 | 
				
			||||||
 | 
					      * `repertory -s3 --name minio t:`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- Set the appropriate access key:
 | 
					#### S3 Configuration File
 | 
				
			||||||
 | 
					 | 
				
			||||||
``` 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
 | 
					```json
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -552,128 +280,100 @@ repertory -s3 --name minio t:
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
---
 | 
					### Data Directories
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## 🌐 Remote Mounting
 | 
					#### Linux Directories
 | 
				
			||||||
 | 
					
 | 
				
			||||||
`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**.
 | 
					* `~/.local/repertory2/s3`
 | 
				
			||||||
 | 
					* `~/.local/repertory2/sia`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Windows Directories
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* `%LOCALAPPDATA%\repertory2\s3`
 | 
				
			||||||
 | 
					* `%LOCALAPPDATA%\repertory2\sia`
 | 
				
			||||||
 | 
					  * Examples:
 | 
				
			||||||
 | 
					    * `C:\Users\Tom\AppData\Local\repertory2\s3`
 | 
				
			||||||
 | 
					    * `C:\Users\Tom\AppData\Local\repertory2\sia`
 | 
				
			||||||
 | 
					* IMPORTANT:
 | 
				
			||||||
 | 
					  * It is highly recommended to exclude this folder from any anti-virus/anti-malware applications as severe performance issues may arise.
 | 
				
			||||||
 | 
					  * Excluding the mounted drive letter is also highly recommended.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 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
 | 
					### 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.
 | 
					The following steps must be performed on the mount you wish to share with
 | 
				
			||||||
 | 
					other systems. Changes to configuration will not take affect while a mount is
 | 
				
			||||||
 | 
					active, so it is recommended to unmount beforehand.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
**Required steps:**
 | 
					* Required steps:
 | 
				
			||||||
 | 
					  * Enable remote mount:
 | 
				
			||||||
 | 
					    * Sia
 | 
				
			||||||
 | 
					      * `repertory -set RemoteMount.Enable true`
 | 
				
			||||||
 | 
					      * `repertory --name '<my config name>' -set RemoteMount.Enable true`
 | 
				
			||||||
 | 
					    * S3:
 | 
				
			||||||
 | 
					      * `repertory -s3 --name '<my config name>' -set RemoteMount.Enable true`
 | 
				
			||||||
 | 
					  * Set a secure encryption token:
 | 
				
			||||||
 | 
					    * Sia:
 | 
				
			||||||
 | 
					      * `repertory -set RemoteMount.EncryptionToken '<my secure password>'`
 | 
				
			||||||
 | 
					      * `repertory --name '<my config name>' -set RemoteMount.EncryptionToken '<my secure password>'`
 | 
				
			||||||
 | 
					    * S3:
 | 
				
			||||||
 | 
					      * `repertory -s3 --name '<my config name>' -set RemoteMount.EncryptionToken '<my secure password>'`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- Enable remote mount:
 | 
					* Optional steps:
 | 
				
			||||||
 | 
					  * Change the port clients will use to connect to your mount:
 | 
				
			||||||
 | 
					    * Sia:
 | 
				
			||||||
 | 
					      * `repertory -set RemoteMount.ApiPort 20000`
 | 
				
			||||||
 | 
					      * `repertory --name '<my config name>' -set RemoteMount.ApiPort 20000`
 | 
				
			||||||
 | 
					    * S3:
 | 
				
			||||||
 | 
					      * `repertory -s3 --name '<my config name>' -set RemoteMount.ApiPort 20000`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  - **Sia**
 | 
					* IMPORTANT:
 | 
				
			||||||
 | 
					  * Be sure to configure your firewall to allow incoming TCP connections on the port configured in `RemoteMount.ApiPort`.
 | 
				
			||||||
    ``` 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
 | 
					#### Remote Mount Configuration File Section
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```json
 | 
					```json
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					  ...
 | 
				
			||||||
  "RemoteMount": {
 | 
					  "RemoteMount": {
 | 
				
			||||||
    "ApiPort": 20000,
 | 
					    "ApiPort": 20000,
 | 
				
			||||||
    "ClientPoolSize": 20,
 | 
					    "ClientPoolSize": 20,
 | 
				
			||||||
    "Enable": true,
 | 
					    "Enable": true,
 | 
				
			||||||
    "EncryptionToken": "<my secure password>"
 | 
					    "EncryptionToken": "<my secure password>"
 | 
				
			||||||
  }
 | 
					  },
 | 
				
			||||||
 | 
					  ...
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Client Setup
 | 
					### Client Setup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Client configuration is provider agnostic, so there's no need to specify `-s3` for S3 providers.
 | 
					Client configuration is provider agnostic, so there's no need to specify `-s3`
 | 
				
			||||||
 | 
					for S3 providers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
**Required steps:**
 | 
					* Required steps:
 | 
				
			||||||
 | 
					  * Set the encryption token to the same value configured during server setup:
 | 
				
			||||||
- Set the encryption token to the same value configured during server setup:
 | 
					    * `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
 | 
				
			||||||
``` shell
 | 
					      * Replace `<port>` with the value of `RemoteMount.ApiPort` used in the server configuration
 | 
				
			||||||
repertory -rm <host name or IP>:<port> -set RemoteConfig.EncryptionToken '<my secure password>'
 | 
					    * Example:
 | 
				
			||||||
# Replace <host name or IP> with the host name or IP of the server
 | 
					      * `repertory -rm 192.168.1.10:20000 -set RemoteConfig.EncryptionToken '<my secure password>'`
 | 
				
			||||||
# Replace <port> with the value of RemoteMount.ApiPort used in the server configuration
 | 
					      * `repertory -rm my.host.com:20000 -set RemoteConfig.EncryptionToken '<my secure password>'`
 | 
				
			||||||
# 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
 | 
					#### Client Remote Mounting
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<!-- markdownlint-disable-next-line -->
 | 
					* Linux:
 | 
				
			||||||
##### Linux
 | 
					  * `repertory -rm <host name or IP>:<port> /mnt/location`
 | 
				
			||||||
 | 
					    * Example:
 | 
				
			||||||
 | 
					      * `repertory -rm 192.168.1.10:20000 /mnt/location`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
``` shell
 | 
					* Windows:
 | 
				
			||||||
repertory -rm <host name or IP>:<port> /mnt/location
 | 
					  * `repertory -rm <host name or IP>:<port> t:`
 | 
				
			||||||
# Example:
 | 
					    * Example:
 | 
				
			||||||
repertory -rm 192.168.1.10:20000 /mnt/location
 | 
					      * `repertory -rm 192.168.1.10:20000 t:`
 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<!-- 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
 | 
					#### Remote Mount Configuration File
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -697,108 +397,67 @@ repertory -rm 192.168.1.10:20000 t:
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
---
 | 
					## Compiling
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## 🧰 Compiling
 | 
					Successful compilation will result in all files required for execution to be placed
 | 
				
			||||||
 | 
					in the `dist/` directory
 | 
				
			||||||
Successful compilation will place all required files for execution in the `dist/` directory.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Linux Compilation
 | 
					### Linux Compilation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- Ensure `docker` is installed
 | 
					* 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 `x86_64`:
 | 
					  * For aarch64:
 | 
				
			||||||
 | 
					    * RelWithDebInfo: `scripts/make_unix.sh aarch64`
 | 
				
			||||||
  ``` shell
 | 
					    * Release: `scripts/make_unix.sh aarch64 Release`
 | 
				
			||||||
  scripts/make_unix.sh x86_64
 | 
					    * Debug: `scripts/make_unix.sh aarch64 Debug`
 | 
				
			||||||
  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
 | 
					### Windows Compilation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- **OFFICIAL: Cross-compiling on Linux**
 | 
					* 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`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  - Ensure `docker` is installed
 | 
					* 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`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ``` shell
 | 
					## Credits
 | 
				
			||||||
    scripts/make_win32.sh x86_64
 | 
					 | 
				
			||||||
    scripts/make_win32.sh x86_64 Release
 | 
					 | 
				
			||||||
    scripts/make_win32.sh x86_64 Debug
 | 
					 | 
				
			||||||
    ```
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
- **UNOFFICIAL: Compiling on Windows**
 | 
					* [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/)
 | 
				
			||||||
 | 
					* [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://storj.io/)
 | 
				
			||||||
 | 
					* [WinFSP - FUSE for Windows](https://github.com/billziss-gh/winfsp)
 | 
				
			||||||
 | 
					* [zlib](https://zlib.net/)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  - Ensure latest [MSYS2](https://www.msys2.org/) is installed
 | 
					## Developer Public Key
 | 
				
			||||||
 | 
					 | 
				
			||||||
    ``` cmd
 | 
					 | 
				
			||||||
    scripts\make_win32.cmd x86_64
 | 
					 | 
				
			||||||
    scripts\make_win32.cmd x86_64 Release
 | 
					 | 
				
			||||||
    scripts\make_win32.cmd x86_64 Debug
 | 
					 | 
				
			||||||
    ```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## 📜 Credits
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- [binutils](https://www.gnu.org/software/binutils/)
 | 
					 | 
				
			||||||
- [boost c++ libraries](https://www.boost.org/)
 | 
					 | 
				
			||||||
- [cpp-httplib](https://github.com/yhirose/cpp-httplib)
 | 
					 | 
				
			||||||
- [curl](https://curl.haxx.se/)
 | 
					 | 
				
			||||||
- [docker](https://www.docker.com/)
 | 
					 | 
				
			||||||
- [Google Test](https://github.com/google/googletest)
 | 
					 | 
				
			||||||
- [ICU](https://icu.unicode.org/)
 | 
					 | 
				
			||||||
- [JSON for Modern C++](https://github.com/nlohmann/json)
 | 
					 | 
				
			||||||
- [libexpat](https://github.com/libexpat/libexpat)
 | 
					 | 
				
			||||||
- [libfuse](https://github.com/libfuse/libfuse)
 | 
					 | 
				
			||||||
- [libsodium](https://doc.libsodium.org/)
 | 
					 | 
				
			||||||
- [macFUSE](https://macfuse.github.io/)
 | 
					 | 
				
			||||||
- [mingw-w64](https://www.mingw-w64.org/)
 | 
					 | 
				
			||||||
- [MSYS2](https://www.msys2.org)
 | 
					 | 
				
			||||||
- [OpenSSL](https://www.openssl.org/)
 | 
					 | 
				
			||||||
- [pkg-config](https://www.freedesktop.org/wiki/Software/pkg-config/)
 | 
					 | 
				
			||||||
- [pugixml](https://pugixml.org/)
 | 
					 | 
				
			||||||
- [RocksDB](https://rocksdb.org)
 | 
					 | 
				
			||||||
- [ScPrime](https://scpri.me/)
 | 
					 | 
				
			||||||
- [Sia Decentralized Cloud Storage](https://sia.tech/)
 | 
					 | 
				
			||||||
- [spdlog](https://github.com/gabime/spdlog)
 | 
					 | 
				
			||||||
- [SQLite](https://www.sqlite.org)
 | 
					 | 
				
			||||||
- [stduuid](https://github.com/mariusbancila/stduuid)
 | 
					 | 
				
			||||||
- [Storj](https://www.storj.io/)
 | 
					 | 
				
			||||||
- [WinFSP - FUSE for Windows](https://github.com/billziss-gh/winfsp)
 | 
					 | 
				
			||||||
- [zlib](https://zlib.net/)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## 🔑 Developer Public Key
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
```text
 | 
					```text
 | 
				
			||||||
-----BEGIN PUBLIC KEY-----
 | 
					-----BEGIN PUBLIC KEY-----
 | 
				
			||||||
 
 | 
				
			|||||||
| 
		 Before Width: | Height: | Size: 262 B  | 
| 
		 Before Width: | Height: | Size: 298 B  | 
| 
		 Before Width: | Height: | Size: 315 B  | 
| 
		 Before Width: | Height: | Size: 552 B  | 
| 
		 Before Width: | Height: | Size: 820 B  | 
| 
		 Before Width: | Height: | Size: 202 B  | 
| 
		 Before Width: | Height: | Size: 281 B  | 
| 
		 Before Width: | Height: | Size: 820 B  | 
| 
		 Before Width: | Height: | Size: 7.5 KiB  | 
| 
		 Before Width: | Height: | Size: 281 B  | 
| 
		 Before Width: | Height: | Size: 361 B  | 
| 
		 Before Width: | Height: | Size: 7.5 KiB  | 
| 
		 Before Width: | Height: | Size: 25 KiB  | 
| 
		 Before Width: | Height: | Size: 361 B  | 
| 
		 Before Width: | Height: | Size: 552 B  | 
| 
		 Before Width: | Height: | Size: 25 KiB  | 
| 
		 Before Width: | Height: | Size: 3.3 KiB  | 
| 
		 Before Width: | Height: | Size: 3.3 KiB  | 
| 
		 Before Width: | Height: | Size: 3.9 KiB  | 
| 
		 Before Width: | Height: | Size: 4.1 KiB  | 
| 
		 Before Width: | Height: | Size: 3.9 KiB  | 
| 
		 Before Width: | Height: | Size: 1.1 KiB  | 
| 
		 Before Width: | Height: | Size: 1.8 KiB  | 
| 
		 Before Width: | Height: | Size: 3.9 KiB  | 
| 
		 Before Width: | Height: | Size: 4.5 KiB  | 
| 
		 Before Width: | Height: | Size: 1.8 KiB  | 
| 
		 Before Width: | Height: | Size: 3.0 KiB  | 
| 
		 Before Width: | Height: | Size: 4.5 KiB  | 
| 
		 Before Width: | Height: | Size: 8.4 KiB  | 
| 
		 Before Width: | Height: | Size: 3.0 KiB  | 
| 
		 Before Width: | Height: | Size: 4.1 KiB  | 
| 
		 Before Width: | Height: | Size: 8.4 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								assets/home.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 165 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								assets/icon.icns
									
									
									
									
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								assets/icon.ico
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 370 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								assets/login.png
									
									
									
									
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 221 KiB  | 
@@ -35,9 +35,13 @@ list(APPEND PROJECT_CXXFLAGS_LIST
 | 
				
			|||||||
  -Wcast-align
 | 
					  -Wcast-align
 | 
				
			||||||
  -Wconversion
 | 
					  -Wconversion
 | 
				
			||||||
  -Wdouble-promotion
 | 
					  -Wdouble-promotion
 | 
				
			||||||
 | 
					  -Wduplicated-branches
 | 
				
			||||||
 | 
					  -Wduplicated-cond
 | 
				
			||||||
  -Wextra
 | 
					  -Wextra
 | 
				
			||||||
  -Wformat=2
 | 
					  -Wformat=2
 | 
				
			||||||
 | 
					  -Wlogical-op
 | 
				
			||||||
  -Wmisleading-indentation
 | 
					  -Wmisleading-indentation
 | 
				
			||||||
 | 
					  -Wno-useless-cast
 | 
				
			||||||
  -Wnon-virtual-dtor
 | 
					  -Wnon-virtual-dtor
 | 
				
			||||||
  -Wnull-dereference
 | 
					  -Wnull-dereference
 | 
				
			||||||
  -Wold-style-cast
 | 
					  -Wold-style-cast
 | 
				
			||||||
@@ -48,15 +52,6 @@ list(APPEND PROJECT_CXXFLAGS_LIST
 | 
				
			|||||||
  -Wunused
 | 
					  -Wunused
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if (NOT PROJECT_IS_DARWIN)
 | 
					 | 
				
			||||||
  list(APPEND PROJECT_CXXFLAGS_LIST 
 | 
					 | 
				
			||||||
    -Wduplicated-branches
 | 
					 | 
				
			||||||
    -Wduplicated-cond
 | 
					 | 
				
			||||||
    -Wlogical-op
 | 
					 | 
				
			||||||
    -Wno-useless-cast
 | 
					 | 
				
			||||||
  )
 | 
					 | 
				
			||||||
endif()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
list(APPEND PROJECT_CFLAGS_LIST
 | 
					list(APPEND PROJECT_CFLAGS_LIST
 | 
				
			||||||
  ${PROJECT_COMMON_FLAG_LIST}
 | 
					  ${PROJECT_COMMON_FLAG_LIST}
 | 
				
			||||||
  -std=c${CMAKE_C_STANDARD}
 | 
					  -std=c${CMAKE_C_STANDARD}
 | 
				
			||||||
@@ -67,7 +62,7 @@ list(APPEND PROJECT_CXXFLAGS_LIST
 | 
				
			|||||||
  -std=gnu++${CMAKE_CXX_STANDARD}
 | 
					  -std=gnu++${CMAKE_CXX_STANDARD}
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if(NOT PROJECT_IS_DARWIN AND PROJECT_STATIC_LINK)
 | 
					if(PROJECT_STATIC_LINK)
 | 
				
			||||||
  list(APPEND PROJECT_CMAKE_EXE_LINKER_FLAGS
 | 
					  list(APPEND PROJECT_CMAKE_EXE_LINKER_FLAGS
 | 
				
			||||||
    -static-libgcc
 | 
					    -static-libgcc
 | 
				
			||||||
    -static-libstdc++
 | 
					    -static-libstdc++
 | 
				
			||||||
@@ -94,11 +89,7 @@ set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${PROJECT_RELEASE_FLAG_L
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
set(CMAKE_EXE_LINKER_FLAGS "${PROJECT_CMAKE_EXE_LINKER_FLAGS}")
 | 
					set(CMAKE_EXE_LINKER_FLAGS "${PROJECT_CMAKE_EXE_LINKER_FLAGS}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
set(EXTERNAL_CMAKE_CXX_FLAGS "-include cstdint -include utility ${PROJECT_COMMON_FLAG_LIST}")
 | 
					set(EXTERNAL_CMAKE_CXX_FLAGS "-include cstdint -include utility -fext-numeric-literals ${PROJECT_COMMON_FLAG_LIST}")
 | 
				
			||||||
if (NOT PROJECT_IS_DARWIN)
 | 
					 | 
				
			||||||
  set(EXTERNAL_CMAKE_CXX_FLAGS "-fext-numeric-literals ${EXTERNAL_CMAKE_CXX_FLAGS}")
 | 
					 | 
				
			||||||
endif()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
list(APPEND PROJECT_EXTERNAL_CMAKE_FLAGS
 | 
					list(APPEND PROJECT_EXTERNAL_CMAKE_FLAGS
 | 
				
			||||||
  -DCMAKE_BUILD_TYPE=${PROJECT_CMAKE_BUILD_TYPE}
 | 
					  -DCMAKE_BUILD_TYPE=${PROJECT_CMAKE_BUILD_TYPE}
 | 
				
			||||||
  -DCMAKE_COLOR_MAKEFILE=${CMAKE_COLOR_MAKEFILE}
 | 
					  -DCMAKE_COLOR_MAKEFILE=${CMAKE_COLOR_MAKEFILE}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,3 @@
 | 
				
			|||||||
if (PROJECT_MACOS_ICNS_NAME)
 | 
					 | 
				
			||||||
  set(PROJECT_MACOS_ICNS_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/assets/${PROJECT_MACOS_ICNS_NAME}")
 | 
					 | 
				
			||||||
endif()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function(set_common_target_options name)
 | 
					function(set_common_target_options name)
 | 
				
			||||||
  target_compile_definitions(${name} PUBLIC 
 | 
					  target_compile_definitions(${name} PUBLIC 
 | 
				
			||||||
    ${PROJECT_DEFINITIONS}
 | 
					    ${PROJECT_DEFINITIONS}
 | 
				
			||||||
@@ -16,17 +12,6 @@ function(set_common_target_options name)
 | 
				
			|||||||
    ${PROJECT_EXTERNAL_BUILD_ROOT}/lib
 | 
					    ${PROJECT_EXTERNAL_BUILD_ROOT}/lib
 | 
				
			||||||
  )
 | 
					  )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (PROJECT_STATIC_LINK)
 | 
					 | 
				
			||||||
    target_compile_definitions(${name} PRIVATE U_STATIC_IMPLEMENTATION)
 | 
					 | 
				
			||||||
  endif()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  target_link_libraries(${name} PRIVATE 
 | 
					 | 
				
			||||||
    ICU::io
 | 
					 | 
				
			||||||
    ICU::i18n
 | 
					 | 
				
			||||||
    ICU::uc
 | 
					 | 
				
			||||||
    ICU::data
 | 
					 | 
				
			||||||
  )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  target_include_directories(${name} AFTER PUBLIC 
 | 
					  target_include_directories(${name} AFTER PUBLIC 
 | 
				
			||||||
    ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/include
 | 
					    ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/include
 | 
				
			||||||
    ${name}_INCLUDES
 | 
					    ${name}_INCLUDES
 | 
				
			||||||
@@ -46,31 +31,11 @@ function(add_project_executable2 name dependencies libraries headers sources is_
 | 
				
			|||||||
    list(APPEND sources ${PROJECT_WINDOWS_VERSION_RC})
 | 
					    list(APPEND sources ${PROJECT_WINDOWS_VERSION_RC})
 | 
				
			||||||
  endif()
 | 
					  endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (PROJECT_IS_DARWIN AND PROJECT_MACOS_ICNS_SOURCE AND "${name}" STREQUAL "${PROJECT_NAME}")
 | 
					  add_executable(${name}
 | 
				
			||||||
    set_source_files_properties(${PROJECT_MACOS_ICNS_SOURCE} PROPERTIES
 | 
					    ${headers}
 | 
				
			||||||
      MACOSX_PACKAGE_LOCATION "Resources"
 | 
					    ${sources}
 | 
				
			||||||
    )
 | 
					    ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/main.cpp
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
    add_executable(${name}
 | 
					 | 
				
			||||||
      MACOSX_BUNDLE
 | 
					 | 
				
			||||||
      ${headers}
 | 
					 | 
				
			||||||
      ${sources}
 | 
					 | 
				
			||||||
      ${PROJECT_MACOS_ICNS_SOURCE}
 | 
					 | 
				
			||||||
      ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/main.cpp
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    set_target_properties(${name} PROPERTIES
 | 
					 | 
				
			||||||
      MACOSX_BUNDLE TRUE
 | 
					 | 
				
			||||||
      MACOSX_BUNDLE_ICON_FILE "${PROJECT_MACOS_ICNS_NAME}"
 | 
					 | 
				
			||||||
      RESOURCE "${PROJECT_MACOS_ICNS_SOURCE}"
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
  else()
 | 
					 | 
				
			||||||
    add_executable(${name}
 | 
					 | 
				
			||||||
      ${headers}
 | 
					 | 
				
			||||||
      ${sources}
 | 
					 | 
				
			||||||
      ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/main.cpp
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
  endif()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  foreach(dependency ${dependencies})
 | 
					  foreach(dependency ${dependencies})
 | 
				
			||||||
    set_common_target_options(${dependency})
 | 
					    set_common_target_options(${dependency})
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,22 +1,20 @@
 | 
				
			|||||||
set(BINUTILS_HASH ce2017e059d63e67ddb9240e9d4ec49c2893605035cd60e92ad53177f4377237)
 | 
					set(BINUTILS_HASH ce2017e059d63e67ddb9240e9d4ec49c2893605035cd60e92ad53177f4377237)
 | 
				
			||||||
set(BOOST2_HASH 7bd7ddceec1a1dfdcbdb3e609b60d01739c38390a5f956385a12f3122049f0ca)
 | 
					set(BOOST2_HASH 7bd7ddceec1a1dfdcbdb3e609b60d01739c38390a5f956385a12f3122049f0ca)
 | 
				
			||||||
set(BOOST_HASH 9de758db755e8330a01d995b0a24d09798048400ac25c03fc5ea9be364b13c93)
 | 
					set(BOOST_HASH 3621533e820dcab1e8012afd583c0c73cf0f77694952b81352bf38c1488f9cb4)
 | 
				
			||||||
set(CPP_HTTPLIB_HASH a66f908f50ccb119769adce44fe1eac75f81b6ffab7c4ac0211bb663ffeb2688)
 | 
					set(CPP_HTTPLIB_HASH 18064587e0cc6a0d5d56d619f4cbbcaba47aa5d84d86013abbd45d95c6653866)
 | 
				
			||||||
set(CURL_HASH d4d9a5001b491f5726efe9b50bc4aad03029506e73c9261272e809c64b05e814)
 | 
					set(CURL_HASH ccc5ba45d9f5320c70ffb24e5411b66ba55ea1f333bf78be0963ed90a9328699)
 | 
				
			||||||
set(EXPAT_HASH 85372797ff0673a8fc4a6be16466bb5a0ca28c0dcf3c6f7ac1686b4a3ba2aabb)
 | 
					set(EXPAT_HASH 85372797ff0673a8fc4a6be16466bb5a0ca28c0dcf3c6f7ac1686b4a3ba2aabb)
 | 
				
			||||||
set(GCC_HASH 7294d65cc1a0558cb815af0ca8c7763d86f7a31199794ede3f630c0d1b0a5723)
 | 
					set(GCC_HASH 7d376d445f93126dc545e2c0086d0f647c3094aae081cdb78f42ce2bc25e7293)
 | 
				
			||||||
set(GTEST_HASH 65fab701d9829d38cb77c14acdc431d2108bfdbf8979e40eb8ae567edf10b27c)
 | 
					set(GTEST_HASH 78c676fc63881529bf97bf9d45948d905a66833fbfa5318ea2cd7478cb98f399)
 | 
				
			||||||
set(ICU_HASH a2c443404f00098e9e90acf29dc318e049d2dc78d9ae5f46efb261934a730ce2)
 | 
					set(ICU_HASH a2c443404f00098e9e90acf29dc318e049d2dc78d9ae5f46efb261934a730ce2)
 | 
				
			||||||
set(INNOSETUP_HASH fa73bf47a4da250d185d07561c2bfda387e5e20db77e4570004cf6a133cc10b1)
 | 
					 | 
				
			||||||
set(JSON_HASH 4b92eb0c06d10683f7447ce9406cb97cd4b453be18d7279320f7b2f025c10187)
 | 
					set(JSON_HASH 4b92eb0c06d10683f7447ce9406cb97cd4b453be18d7279320f7b2f025c10187)
 | 
				
			||||||
set(LIBSODIUM_HASH 8e5aeca07a723a27bbecc3beef14b0068d37e7fc0e97f51b3f1c82d2a58005c1)
 | 
					set(LIBSODIUM_HASH 8e5aeca07a723a27bbecc3beef14b0068d37e7fc0e97f51b3f1c82d2a58005c1)
 | 
				
			||||||
set(MINGW_HASH 5afe822af5c4edbf67daaf45eec61d538f49eef6b19524de64897c6b95828caf)
 | 
					set(MINGW_HASH cc41898aac4b6e8dd5cffd7331b9d9515b912df4420a3a612b5ea2955bbeed2f)
 | 
				
			||||||
set(OPENSSL_HASH b6a5f44b7eb69e3fa35dbf15524405b44837a481d43d81daddde3ff21fcbb8e9)
 | 
					set(OPENSSL_HASH 344d0a79f1a9b08029b0744e2cc401a43f9c90acd1044d09a530b4885a8e9fc0)
 | 
				
			||||||
set(PKG_CONFIG_HASH 6fc69c01688c9458a57eb9a1664c9aba372ccda420a02bf4429fe610e7e7d591)
 | 
					set(PKG_CONFIG_HASH 6fc69c01688c9458a57eb9a1664c9aba372ccda420a02bf4429fe610e7e7d591)
 | 
				
			||||||
set(PUGIXML_HASH 655ade57fa703fb421c2eb9a0113b5064bddb145d415dd1f88c79353d90d511a)
 | 
					set(PUGIXML_HASH 655ade57fa703fb421c2eb9a0113b5064bddb145d415dd1f88c79353d90d511a)
 | 
				
			||||||
set(ROCKSDB_HASH 7ec942baab802b2845188d02bc5d4e42c29236e61bcbc08f5b3a6bdd92290c22)
 | 
					set(ROCKSDB_HASH 3fdc9ca996971c4c039959866382c4a3a6c8ade4abf888f3b2ff77153e07bf28)
 | 
				
			||||||
set(SPDLOG_HASH 15a04e69c222eb6c01094b5c7ff8a249b36bb22788d72519646fb85feb267e67)
 | 
					set(SPDLOG_HASH 7a80896357f3e8e920e85e92633b14ba0f229c506e6f978578bdc35ba09e9a5d)
 | 
				
			||||||
set(SQLITE_HASH 1d3049dd0f830a025a53105fc79fd2ab9431aea99e137809d064d8ee8356b032)
 | 
					set(SQLITE_HASH 6cebd1d8403fc58c30e93939b246f3e6e58d0765a5cd50546f16c00fd805d2c3)
 | 
				
			||||||
set(STDUUID_HASH b1176597e789531c38481acbbed2a6894ad419aab0979c10410d59eb0ebf40d3)
 | 
					set(STDUUID_HASH b1176597e789531c38481acbbed2a6894ad419aab0979c10410d59eb0ebf40d3)
 | 
				
			||||||
set(WINFSP_HASH 073a70e00f77423e34bed98b86e600def93393ba5822204fac57a29324db9f7a)
 | 
					 | 
				
			||||||
set(ZLIB_HASH 17e88863f3600672ab49182f217281b6fc4d3c762bde361935e436a95214d05c)
 | 
					set(ZLIB_HASH 17e88863f3600672ab49182f217281b6fc4d3c762bde361935e436a95214d05c)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,17 +4,13 @@ set(Boost_USE_STATIC_LIBS ${PROJECT_STATIC_LINK})
 | 
				
			|||||||
set(CURL_USE_STATIC_LIBS ${PROJECT_STATIC_LINK})
 | 
					set(CURL_USE_STATIC_LIBS ${PROJECT_STATIC_LINK})
 | 
				
			||||||
set(OPENSSL_USE_STATIC_LIBS ${PROJECT_STATIC_LINK})
 | 
					set(OPENSSL_USE_STATIC_LIBS ${PROJECT_STATIC_LINK})
 | 
				
			||||||
set(SFML_STATIC_LIBRARIES ${PROJECT_STATIC_LINK})
 | 
					set(SFML_STATIC_LIBRARIES ${PROJECT_STATIC_LINK})
 | 
				
			||||||
if (PROJECT_IS_DARWIN)
 | 
					set(ZLIB_USE_STATIC_LIBS ${PROJECT_STATIC_LINK})
 | 
				
			||||||
  set(ZLIB_USE_STATIC_LIBS OFF)
 | 
					 | 
				
			||||||
else()
 | 
					 | 
				
			||||||
  set(ZLIB_USE_STATIC_LIBS ${PROJECT_STATIC_LINK})
 | 
					 | 
				
			||||||
endif()
 | 
					 | 
				
			||||||
set(wxWidgets_USE_STATIC ${PROJECT_STATIC_LINK})
 | 
					set(wxWidgets_USE_STATIC ${PROJECT_STATIC_LINK})
 | 
				
			||||||
set(ICU_USE_STATIC_LIBS ${PROJECT_STATIC_LINK})
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
include(cmake/libraries/icu.cmake)
 | 
					 | 
				
			||||||
include(cmake/libraries/openssl.cmake)
 | 
					include(cmake/libraries/openssl.cmake)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
include(cmake/libraries/boost.cmake)
 | 
					include(cmake/libraries/boost.cmake)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
include(cmake/libraries/cpp_httplib.cmake)
 | 
					include(cmake/libraries/cpp_httplib.cmake)
 | 
				
			||||||
include(cmake/libraries/curl.cmake)
 | 
					include(cmake/libraries/curl.cmake)
 | 
				
			||||||
include(cmake/libraries/fuse.cmake)
 | 
					include(cmake/libraries/fuse.cmake)
 | 
				
			||||||
@@ -63,7 +59,7 @@ if(PROJECT_BUILD)
 | 
				
			|||||||
      winspool
 | 
					      winspool
 | 
				
			||||||
      ws2_32
 | 
					      ws2_32
 | 
				
			||||||
  )
 | 
					  )
 | 
				
			||||||
  elseif(NOT PROJECT_IS_DARWIN)
 | 
					  else()
 | 
				
			||||||
    link_libraries(
 | 
					    link_libraries(
 | 
				
			||||||
      uring
 | 
					      uring
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -39,14 +39,6 @@ if(PROJECT_ENABLE_BOOST)
 | 
				
			|||||||
          wserialization
 | 
					          wserialization
 | 
				
			||||||
      )
 | 
					      )
 | 
				
			||||||
    else()
 | 
					    else()
 | 
				
			||||||
      if(PROJECT_IS_DARWIN)
 | 
					 | 
				
			||||||
        set(CMAKE_HAVE_THREADS_LIBRARY 1)
 | 
					 | 
				
			||||||
        set(CMAKE_THREAD_LIBS_INIT "-lpthread")
 | 
					 | 
				
			||||||
        set(CMAKE_USE_PTHREADS_INIT 1)
 | 
					 | 
				
			||||||
        set(CMAKE_USE_WIN32_THREADS_INIT 0)
 | 
					 | 
				
			||||||
        set(THREADS_PREFER_PTHREAD_FLAG ON)
 | 
					 | 
				
			||||||
      endif()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      find_package(Boost ${BOOST_MAJOR_VERSION}.${BOOST_MINOR_VERSION}.${BOOST_PATCH_VERSION}
 | 
					      find_package(Boost ${BOOST_MAJOR_VERSION}.${BOOST_MINOR_VERSION}.${BOOST_PATCH_VERSION}
 | 
				
			||||||
        REQUIRED
 | 
					        REQUIRED
 | 
				
			||||||
        COMPONENTS
 | 
					        COMPONENTS
 | 
				
			||||||
@@ -62,6 +54,7 @@ if(PROJECT_ENABLE_BOOST)
 | 
				
			|||||||
          random
 | 
					          random
 | 
				
			||||||
          regex
 | 
					          regex
 | 
				
			||||||
          serialization
 | 
					          serialization
 | 
				
			||||||
 | 
					          system
 | 
				
			||||||
          thread
 | 
					          thread
 | 
				
			||||||
          wserialization
 | 
					          wserialization
 | 
				
			||||||
      )
 | 
					      )
 | 
				
			||||||
@@ -127,12 +120,10 @@ if(PROJECT_ENABLE_BOOST)
 | 
				
			|||||||
          --with-libraries=atomic,chrono,date_time,filesystem,iostreams,locale,log,program_options,random,regex,serialization,system,test,thread
 | 
					          --with-libraries=atomic,chrono,date_time,filesystem,iostreams,locale,log,program_options,random,regex,serialization,system,test,thread
 | 
				
			||||||
        BUILD_COMMAND
 | 
					        BUILD_COMMAND
 | 
				
			||||||
          ./b2
 | 
					          ./b2
 | 
				
			||||||
          -sNO_BZIP2=1
 | 
					 | 
				
			||||||
          -j$ENV{CMAKE_BUILD_PARALLEL_LEVEL}
 | 
					          -j$ENV{CMAKE_BUILD_PARALLEL_LEVEL}
 | 
				
			||||||
          ${BOOST_BUILD_ARGS}
 | 
					          ${BOOST_BUILD_ARGS}
 | 
				
			||||||
        INSTALL_COMMAND
 | 
					        INSTALL_COMMAND
 | 
				
			||||||
          ./b2
 | 
					          ./b2
 | 
				
			||||||
          -sNO_BZIP2=1
 | 
					 | 
				
			||||||
          -j$ENV{CMAKE_BUILD_PARALLEL_LEVEL}
 | 
					          -j$ENV{CMAKE_BUILD_PARALLEL_LEVEL}
 | 
				
			||||||
          ${BOOST_BUILD_ARGS}
 | 
					          ${BOOST_BUILD_ARGS}
 | 
				
			||||||
          install
 | 
					          install
 | 
				
			||||||
@@ -140,10 +131,6 @@ if(PROJECT_ENABLE_BOOST)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      list(APPEND PROJECT_DEPENDENCIES boost_project)
 | 
					      list(APPEND PROJECT_DEPENDENCIES boost_project)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
     if(PROJECT_IS_DARWIN OR PROJECT_REQUIRE_ALPINE)
 | 
					 | 
				
			||||||
        add_dependencies(boost_project icu_project)
 | 
					 | 
				
			||||||
      endif()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      if (NOT CMAKE_HOST_WIN32)
 | 
					      if (NOT CMAKE_HOST_WIN32)
 | 
				
			||||||
        add_dependencies(boost_project openssl_project)
 | 
					        add_dependencies(boost_project openssl_project)
 | 
				
			||||||
      endif()
 | 
					      endif()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,6 @@ if(PROJECT_ENABLE_CPP_HTTPLIB)
 | 
				
			|||||||
      CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
 | 
					      CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
 | 
				
			||||||
        -DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
 | 
					        -DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
 | 
				
			||||||
        -DBUILD_STATIC_LIBS=ON
 | 
					        -DBUILD_STATIC_LIBS=ON
 | 
				
			||||||
        -DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
 | 
					 | 
				
			||||||
        -DHTTPLIB_REQUIRE_BROTLI=OFF
 | 
					        -DHTTPLIB_REQUIRE_BROTLI=OFF
 | 
				
			||||||
        -DHTTPLIB_REQUIRE_OPENSSL=ON
 | 
					        -DHTTPLIB_REQUIRE_OPENSSL=ON
 | 
				
			||||||
        -DHTTPLIB_REQUIRE_ZLIB=ON
 | 
					        -DHTTPLIB_REQUIRE_ZLIB=ON
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,8 +27,8 @@ if(PROJECT_ENABLE_CURL)
 | 
				
			|||||||
        -DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
 | 
					        -DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
 | 
				
			||||||
        -DBUILD_STATIC_CURL=ON
 | 
					        -DBUILD_STATIC_CURL=ON
 | 
				
			||||||
        -DBUILD_STATIC_LIBS=ON
 | 
					        -DBUILD_STATIC_LIBS=ON
 | 
				
			||||||
 | 
					        -DBUILD_STATIC_LIBS=ON
 | 
				
			||||||
        -DBUILD_TESTING=OFF
 | 
					        -DBUILD_TESTING=OFF
 | 
				
			||||||
        -DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
 | 
					 | 
				
			||||||
        -DCURL_BROTLI=OFF
 | 
					        -DCURL_BROTLI=OFF
 | 
				
			||||||
        -DCURL_CA_BUNDLE=./cacert.pem
 | 
					        -DCURL_CA_BUNDLE=./cacert.pem
 | 
				
			||||||
        -DCURL_CA_FALLBACK=ON
 | 
					        -DCURL_CA_FALLBACK=ON
 | 
				
			||||||
@@ -37,13 +37,11 @@ if(PROJECT_ENABLE_CURL)
 | 
				
			|||||||
        -DCURL_USE_LIBSSH2=OFF
 | 
					        -DCURL_USE_LIBSSH2=OFF
 | 
				
			||||||
        -DCURL_USE_OPENSSL=${PROJECT_ENABLE_OPENSSL}
 | 
					        -DCURL_USE_OPENSSL=${PROJECT_ENABLE_OPENSSL}
 | 
				
			||||||
        -DCURL_ZLIB=ON
 | 
					        -DCURL_ZLIB=ON
 | 
				
			||||||
        -DCURL_ZSTD=OFF
 | 
					 | 
				
			||||||
        -DENABLE_CURL_MANUAL=OFF
 | 
					        -DENABLE_CURL_MANUAL=OFF
 | 
				
			||||||
        -DENABLE_THREADED_RESOLVER=ON
 | 
					        -DENABLE_THREADED_RESOLVER=ON
 | 
				
			||||||
        -DOPENSSL_ROOT_DIR=${OPENSSL_ROOT_DIR}
 | 
					        -DOPENSSL_ROOT_DIR=${OPENSSL_ROOT_DIR}
 | 
				
			||||||
        -DOPENSSL_USE_STATIC_LIBS=${OPENSSL_USE_STATIC_LIBS}
 | 
					        -DOPENSSL_USE_STATIC_LIBS=${OPENSSL_USE_STATIC_LIBS}
 | 
				
			||||||
        -DUSE_LIBIDN2=OFF
 | 
					        -DUSE_LIBIDN2=OFF
 | 
				
			||||||
        -DUSE_NGHTTP2=OFF
 | 
					 | 
				
			||||||
        -DZLIB_USE_STATIC_LIBS=${ZLIB_USE_STATIC_LIBS}
 | 
					        -DZLIB_USE_STATIC_LIBS=${ZLIB_USE_STATIC_LIBS}
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,25 +20,17 @@ if(PROJECT_ENABLE_FUSE AND NOT PROJECT_IS_MINGW)
 | 
				
			|||||||
      endif()
 | 
					      endif()
 | 
				
			||||||
    endif()
 | 
					    endif()
 | 
				
			||||||
  else()
 | 
					  else()
 | 
				
			||||||
    if (PROJECT_IS_DARWIN)
 | 
					    pkg_check_modules(LIBFUSE3 fuse3>=3.0.0)
 | 
				
			||||||
      find_library(OSXFUSE NO_CACHE NAMES OSXFUSE)
 | 
					    if(LIBFUSE3_FOUND)
 | 
				
			||||||
      if (NOT OSXFUSE)
 | 
					      set(PROJECT_FUSE fuse3)
 | 
				
			||||||
        message(FATAL_ERROR "FUSE for macOS not found (https://macfuse.github.io)")
 | 
					      set(PROJECT_FUSE_INCLUDE_DIRS ${LIBFUSE3_INCLUDE_DIRS})
 | 
				
			||||||
      endif ()
 | 
					 | 
				
			||||||
      set(PROJECT_FUSE fuse2)
 | 
					 | 
				
			||||||
    else()
 | 
					    else()
 | 
				
			||||||
      pkg_check_modules(LIBFUSE3 fuse3>=3.0.0)
 | 
					      pkg_check_modules(LIBFUSE2 fuse>=2.9.0)
 | 
				
			||||||
      if(LIBFUSE3_FOUND)
 | 
					      if(LIBFUSE2_FOUND)
 | 
				
			||||||
        set(PROJECT_FUSE fuse3)
 | 
					        set(PROJECT_FUSE fuse2)
 | 
				
			||||||
        set(PROJECT_FUSE_INCLUDE_DIRS ${LIBFUSE3_INCLUDE_DIRS})
 | 
					        set(PROJECT_FUSE_INCLUDE_DIRS ${LIBFUSE2_INCLUDE_DIRS})
 | 
				
			||||||
      else()
 | 
					      else()
 | 
				
			||||||
        pkg_check_modules(LIBFUSE2 fuse>=2.9.0)
 | 
					        message(FATAL_ERROR "fuse library not found")
 | 
				
			||||||
        if(LIBFUSE2_FOUND)
 | 
					 | 
				
			||||||
          set(PROJECT_FUSE fuse2)
 | 
					 | 
				
			||||||
          set(PROJECT_FUSE_INCLUDE_DIRS ${LIBFUSE2_INCLUDE_DIRS})
 | 
					 | 
				
			||||||
        else()
 | 
					 | 
				
			||||||
          message(FATAL_ERROR "fuse library not found")
 | 
					 | 
				
			||||||
        endif()
 | 
					 | 
				
			||||||
      endif()
 | 
					      endif()
 | 
				
			||||||
    endif()
 | 
					    endif()
 | 
				
			||||||
  endif()
 | 
					  endif()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,24 +0,0 @@
 | 
				
			|||||||
if((PROJECT_IS_DARWIN OR PROJECT_REQUIRE_ALPINE) AND NOT PROJECT_IS_MINGW AND NOT PROJECT_BUILD)
 | 
					 | 
				
			||||||
  if(PROJECT_BUILD_SHARED_LIBS)
 | 
					 | 
				
			||||||
    set(ICU_ENABLE_SHARED yes)
 | 
					 | 
				
			||||||
  else()
 | 
					 | 
				
			||||||
    set(ICU_ENABLE_SHARED no)
 | 
					 | 
				
			||||||
  endif()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  ExternalProject_Add(icu_project
 | 
					 | 
				
			||||||
    PREFIX external
 | 
					 | 
				
			||||||
    URL ${PROJECT_3RD_PARTY_DIR}/mingw64/icu-release-${ICU_VERSION}.tar.gz
 | 
					 | 
				
			||||||
    URL_HASH SHA256=${ICU_HASH}
 | 
					 | 
				
			||||||
    BUILD_IN_SOURCE 1
 | 
					 | 
				
			||||||
    LIST_SEPARATOR |
 | 
					 | 
				
			||||||
    PATCH_COMMAND chmod +x ${PROJECT_3RD_PARTY_DIR}/icu_configure.sh
 | 
					 | 
				
			||||||
    CONFIGURE_COMMAND cd icu4c/source && ${PROJECT_3RD_PARTY_DIR}/icu_configure.sh
 | 
					 | 
				
			||||||
      ${PROJECT_MARCH}
 | 
					 | 
				
			||||||
      ${PROJECT_EXTERNAL_BUILD_ROOT}
 | 
					 | 
				
			||||||
      ${ICU_ENABLE_SHARED}
 | 
					 | 
				
			||||||
    BUILD_COMMAND cd icu4c/source && make -j$ENV{CMAKE_BUILD_PARALLEL_LEVEL}
 | 
					 | 
				
			||||||
    INSTALL_COMMAND cd icu4c/source && make install
 | 
					 | 
				
			||||||
  )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  list(APPEND PROJECT_DEPENDENCIES icu_project)
 | 
					 | 
				
			||||||
endif()
 | 
					 | 
				
			||||||
@@ -18,7 +18,6 @@ if(PROJECT_ENABLE_JSON)
 | 
				
			|||||||
      CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
 | 
					      CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
 | 
				
			||||||
        -DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
 | 
					        -DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
 | 
				
			||||||
        -DBUILD_STATIC_LIBS=ON
 | 
					        -DBUILD_STATIC_LIBS=ON
 | 
				
			||||||
        -DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
 | 
					 | 
				
			||||||
        -DJSON_BuildTests=OFF
 | 
					        -DJSON_BuildTests=OFF
 | 
				
			||||||
        -DJSON_Install=ON
 | 
					        -DJSON_Install=ON
 | 
				
			||||||
        -DJSON_MultipleHeaders=OFF
 | 
					        -DJSON_MultipleHeaders=OFF
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,12 +15,6 @@ if(PROJECT_ENABLE_OPENSSL)
 | 
				
			|||||||
  elseif(NOT PROJECT_IS_MINGW)
 | 
					  elseif(NOT PROJECT_IS_MINGW)
 | 
				
			||||||
    if(PROJECT_IS_MINGW)
 | 
					    if(PROJECT_IS_MINGW)
 | 
				
			||||||
      set(OPENSSL_COMPILE_TYPE mingw64)
 | 
					      set(OPENSSL_COMPILE_TYPE mingw64)
 | 
				
			||||||
    elseif(PROJECT_IS_DARWIN)
 | 
					 | 
				
			||||||
      if(PROJECT_IS_ARM64)
 | 
					 | 
				
			||||||
        set(OPENSSL_COMPILE_TYPE darwin64-arm64)
 | 
					 | 
				
			||||||
      else()
 | 
					 | 
				
			||||||
        set(OPENSSL_COMPILE_TYPE darwin64-x86_64)
 | 
					 | 
				
			||||||
      endif()
 | 
					 | 
				
			||||||
    elseif(PROJECT_IS_ARM64)
 | 
					    elseif(PROJECT_IS_ARM64)
 | 
				
			||||||
      set(OPENSSL_COMPILE_TYPE linux-aarch64)
 | 
					      set(OPENSSL_COMPILE_TYPE linux-aarch64)
 | 
				
			||||||
    else()
 | 
					    else()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,7 +20,6 @@ if(PROJECT_ENABLE_PUGIXML)
 | 
				
			|||||||
      CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
 | 
					      CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
 | 
				
			||||||
        -DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
 | 
					        -DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
 | 
				
			||||||
        -DBUILD_STATIC_LIBS=ON
 | 
					        -DBUILD_STATIC_LIBS=ON
 | 
				
			||||||
        -DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
 | 
					 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    list(APPEND PROJECT_DEPENDENCIES pugixml_project)
 | 
					    list(APPEND PROJECT_DEPENDENCIES pugixml_project)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,14 +14,12 @@ if(PROJECT_ENABLE_ROCKSDB)
 | 
				
			|||||||
      CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
 | 
					      CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
 | 
				
			||||||
        -DBUILD_SHARED_LIBS=OFF
 | 
					        -DBUILD_SHARED_LIBS=OFF
 | 
				
			||||||
        -DBUILD_STATIC_LIBS=ON
 | 
					        -DBUILD_STATIC_LIBS=ON
 | 
				
			||||||
        -DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
 | 
					 | 
				
			||||||
        -DFAIL_ON_WARNINGS=OFF
 | 
					        -DFAIL_ON_WARNINGS=OFF
 | 
				
			||||||
        -DPORTABLE=1
 | 
					        -DPORTABLE=1
 | 
				
			||||||
        -DROCKSDB_BUILD_SHARED=OFF
 | 
					        -DROCKSDB_BUILD_SHARED=OFF
 | 
				
			||||||
        -DROCKSDB_INSTALL_ON_WINDOWS=ON
 | 
					        -DROCKSDB_INSTALL_ON_WINDOWS=ON
 | 
				
			||||||
        -DWITH_BENCHMARK=OFF
 | 
					        -DWITH_BENCHMARK=OFF
 | 
				
			||||||
        -DWITH_BENCHMARK_TOOLS=OFF
 | 
					        -DWITH_BENCHMARK_TOOLS=OFF
 | 
				
			||||||
        -DWITH_BZ2=OFF
 | 
					 | 
				
			||||||
        -DWITH_CORE_TOOLS=OFF
 | 
					        -DWITH_CORE_TOOLS=OFF
 | 
				
			||||||
        -DWITH_EXAMPLES=OFF
 | 
					        -DWITH_EXAMPLES=OFF
 | 
				
			||||||
        -DWITH_GFLAGS=OFF
 | 
					        -DWITH_GFLAGS=OFF
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,6 @@ if(PROJECT_ENABLE_SPDLOG)
 | 
				
			|||||||
      LIST_SEPARATOR |
 | 
					      LIST_SEPARATOR |
 | 
				
			||||||
      CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
 | 
					      CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
 | 
				
			||||||
        -DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
 | 
					        -DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
 | 
				
			||||||
        -DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
 | 
					 | 
				
			||||||
        -DSPDLOG_BUILD_EXAMPLE=OFF
 | 
					        -DSPDLOG_BUILD_EXAMPLE=OFF
 | 
				
			||||||
        -DSPDLOG_FMT_EXTERNAL=OFF
 | 
					        -DSPDLOG_FMT_EXTERNAL=OFF
 | 
				
			||||||
        -DSPDLOG_FMT_EXTERNAL_HO=OFF
 | 
					        -DSPDLOG_FMT_EXTERNAL_HO=OFF
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,7 +16,6 @@ if(PROJECT_ENABLE_STDUUID)
 | 
				
			|||||||
      CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
 | 
					      CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
 | 
				
			||||||
        -DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
 | 
					        -DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
 | 
				
			||||||
        -DBUILD_STATIC_LIBS=ON
 | 
					        -DBUILD_STATIC_LIBS=ON
 | 
				
			||||||
        -DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
 | 
					 | 
				
			||||||
        -DUUID_BUILD_TESTS=OFF
 | 
					        -DUUID_BUILD_TESTS=OFF
 | 
				
			||||||
        -DUUID_ENABLE_INSTALL=ON
 | 
					        -DUUID_ENABLE_INSTALL=ON
 | 
				
			||||||
        -DUUID_USING_CXX20_SPAN=ON
 | 
					        -DUUID_USING_CXX20_SPAN=ON
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,7 +10,6 @@ if (PROJECT_ENABLE_TESTING)
 | 
				
			|||||||
      CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
 | 
					      CMAKE_ARGS ${PROJECT_EXTERNAL_CMAKE_FLAGS}
 | 
				
			||||||
        -DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
 | 
					        -DBUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS}
 | 
				
			||||||
        -DBUILD_STATIC_LIBS=ON
 | 
					        -DBUILD_STATIC_LIBS=ON
 | 
				
			||||||
        -DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
 | 
					 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    list(APPEND PROJECT_DEPENDENCIES gtest_project)
 | 
					    list(APPEND PROJECT_DEPENDENCIES gtest_project)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,9 +2,9 @@ if(PROJECT_ENABLE_WINFSP AND PROJECT_IS_MINGW)
 | 
				
			|||||||
  if(PROJECT_BUILD) 
 | 
					  if(PROJECT_BUILD) 
 | 
				
			||||||
    add_definitions(-DPROJECT_ENABLE_WINFSP)
 | 
					    add_definitions(-DPROJECT_ENABLE_WINFSP)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    include_directories(BEFORE SYSTEM ${PROJECT_3RD_PARTY_DIR}/winfsp-2.1/inc)
 | 
					    include_directories(BEFORE SYSTEM ${PROJECT_3RD_PARTY_DIR}/winfsp-2.0/inc)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    link_directories(BEFORE ${PROJECT_3RD_PARTY_DIR}/winfsp-2.1/lib)
 | 
					    link_directories(BEFORE ${PROJECT_3RD_PARTY_DIR}/winfsp-2.0/lib)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if(PROJECT_IS_ARM64)
 | 
					    if(PROJECT_IS_ARM64)
 | 
				
			||||||
      link_libraries(winfsp-a64)
 | 
					      link_libraries(winfsp-a64)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,6 +2,10 @@ if(MSVC)
 | 
				
			|||||||
  message(FATAL_ERROR "MSVC will not be supported")
 | 
					  message(FATAL_ERROR "MSVC will not be supported")
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if(UNIX AND APPLE)
 | 
				
			||||||
 | 
					  message(FATAL_ERROR "Apple is not currently supported")
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
 | 
					if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
 | 
				
			||||||
  message(FATAL_ERROR "FreeBSD is not currently supported")
 | 
					  message(FATAL_ERROR "FreeBSD is not currently supported")
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
@@ -9,15 +13,3 @@ endif()
 | 
				
			|||||||
if(PROJECT_REQUIRE_ALPINE AND NOT PROJECT_IS_ALPINE AND PROJECT_IS_MINGW AND PROJECT_IS_MINGW_UNIX)
 | 
					if(PROJECT_REQUIRE_ALPINE AND NOT PROJECT_IS_ALPINE AND PROJECT_IS_MINGW AND PROJECT_IS_MINGW_UNIX)
 | 
				
			||||||
  message(FATAL_ERROR "Project requires Alpine Linux to build")
 | 
					  message(FATAL_ERROR "Project requires Alpine Linux to build")
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
 | 
					 | 
				
			||||||
if (PROJECT_IS_DARWIN)
 | 
					 | 
				
			||||||
  if (PROJECT_IS_ARM64)
 | 
					 | 
				
			||||||
    set(CMAKE_OSX_ARCHITECTURES "arm64")
 | 
					 | 
				
			||||||
  else()
 | 
					 | 
				
			||||||
    set(CMAKE_OSX_ARCHITECTURES "x86_64")
 | 
					 | 
				
			||||||
  endif()
 | 
					 | 
				
			||||||
endif()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if (PROJECT_IS_DARWIN AND NOT PROJECT_MACOS_BUNDLE_ID)
 | 
					 | 
				
			||||||
  message(FATAL_ERROR "'PROJECT_MACOS_BUNDLE_ID' is not set in 'config.sh'")
 | 
					 | 
				
			||||||
endif()
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,30 +1,28 @@
 | 
				
			|||||||
set(BINUTILS_VERSION 2.44)
 | 
					set(BINUTILS_VERSION 2.44)
 | 
				
			||||||
set(BOOST_MAJOR_VERSION 1)
 | 
					 | 
				
			||||||
set(BOOST_MINOR_VERSION 89)
 | 
					 | 
				
			||||||
set(BOOST_PATCH_VERSION 0)
 | 
					 | 
				
			||||||
set(BOOST2_MAJOR_VERSION 1)
 | 
					set(BOOST2_MAJOR_VERSION 1)
 | 
				
			||||||
set(BOOST2_MINOR_VERSION 76)
 | 
					set(BOOST2_MINOR_VERSION 76)
 | 
				
			||||||
set(BOOST2_PATCH_VERSION 0)
 | 
					set(BOOST2_PATCH_VERSION 0)
 | 
				
			||||||
set(CPP_HTTPLIB_VERSION 0.26.0)
 | 
					set(BOOST_MAJOR_VERSION 1)
 | 
				
			||||||
set(CURL_VERSION 8.16.0)
 | 
					set(BOOST_MINOR_VERSION 88)
 | 
				
			||||||
set(CURL2_VERSION 8_16_0)
 | 
					set(BOOST_PATCH_VERSION 0)
 | 
				
			||||||
set(EXPAT_VERSION 2.7.1)
 | 
					set(CPP_HTTPLIB_VERSION 0.20.0)
 | 
				
			||||||
 | 
					set(CURL2_VERSION 8_13_0)
 | 
				
			||||||
 | 
					set(CURL_VERSION 8.13.0)
 | 
				
			||||||
set(EXPAT2_VERSION 2_7_1)
 | 
					set(EXPAT2_VERSION 2_7_1)
 | 
				
			||||||
set(GCC_VERSION 15.2.0)
 | 
					set(EXPAT_VERSION 2.7.1)
 | 
				
			||||||
set(GTEST_VERSION 1.17.0)
 | 
					set(GCC_VERSION 14.2.0)
 | 
				
			||||||
 | 
					set(GTEST_VERSION 1.16.0)
 | 
				
			||||||
set(ICU_VERSION 76-1)
 | 
					set(ICU_VERSION 76-1)
 | 
				
			||||||
set(INNOSETUP_VERSION 6.5.4)
 | 
					 | 
				
			||||||
set(JSON_VERSION 3.12.0)
 | 
					set(JSON_VERSION 3.12.0)
 | 
				
			||||||
set(LIBSODIUM_VERSION 1.0.20)
 | 
					set(LIBSODIUM_VERSION 1.0.20)
 | 
				
			||||||
set(MINGW_VERSION 13.0.0)
 | 
					set(MESA_VERSION 23.3.3)
 | 
				
			||||||
set(OPENSSL_VERSION 3.6.0)
 | 
					set(MINGW_VERSION 12.0.0)
 | 
				
			||||||
 | 
					set(OPENSSL_VERSION 3.5.0)
 | 
				
			||||||
set(PKG_CONFIG_VERSION 0.29.2)
 | 
					set(PKG_CONFIG_VERSION 0.29.2)
 | 
				
			||||||
set(PUGIXML_VERSION 1.15)
 | 
					set(PUGIXML_VERSION 1.15)
 | 
				
			||||||
set(ROCKSDB_VERSION 10.5.1)
 | 
					set(ROCKSDB_VERSION 10.0.1)
 | 
				
			||||||
set(SPDLOG_VERSION 1.15.3)
 | 
					set(SPDLOG_VERSION 1.15.2)
 | 
				
			||||||
set(SQLITE_VERSION 3500400)
 | 
					set(SQLITE2_VERSION 3.49.1)
 | 
				
			||||||
set(SQLITE2_VERSION 3.50.4)
 | 
					set(SQLITE_VERSION 3490100)
 | 
				
			||||||
set(STDUUID_VERSION 1.2.3)
 | 
					set(STDUUID_VERSION 1.2.3)
 | 
				
			||||||
set(WINFSP_VERSION 2.1.25156)
 | 
					 | 
				
			||||||
set(WINFSP2_VERSION 2.1)
 | 
					 | 
				
			||||||
set(ZLIB_VERSION 1.3.1)
 | 
					set(ZLIB_VERSION 1.3.1)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										11
									
								
								config.sh
									
									
									
									
									
								
							
							
						
						@@ -8,14 +8,11 @@ PROJECT_URL="${PROJECT_COMPANY_NAME}/repertory"
 | 
				
			|||||||
PROJECT_COPYRIGHT="Copyright <2018-2025> <MIT License> <${PROJECT_URL}>"
 | 
					PROJECT_COPYRIGHT="Copyright <2018-2025> <MIT License> <${PROJECT_URL}>"
 | 
				
			||||||
PROJECT_DESC="Mount utility for Sia and S3"
 | 
					PROJECT_DESC="Mount utility for Sia and S3"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PROJECT_MACOS_BUNDLE_ID="com.fifthgrid.blockstorage.repertory"
 | 
					 | 
				
			||||||
PROJECT_MACOS_ICNS_NAME="icon.icns"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
PROJECT_MAJOR_VERSION=2
 | 
					PROJECT_MAJOR_VERSION=2
 | 
				
			||||||
PROJECT_MINOR_VERSION=1
 | 
					PROJECT_MINOR_VERSION=0
 | 
				
			||||||
PROJECT_REVISION_VERSION=0
 | 
					PROJECT_REVISION_VERSION=6
 | 
				
			||||||
PROJECT_RELEASE_NUM=1
 | 
					PROJECT_RELEASE_NUM=0
 | 
				
			||||||
PROJECT_RELEASE_ITER=rc.2
 | 
					PROJECT_RELEASE_ITER=rc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PROJECT_APP_LIST=(${PROJECT_NAME})
 | 
					PROJECT_APP_LIST=(${PROJECT_NAME})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
#comment
 | 
					#comment
 | 
				
			||||||
FROM         arm64v8/alpine:3.22.2
 | 
					FROM         arm64v8/alpine:3.21.3
 | 
				
			||||||
MAINTAINER   Scott E. Graves <scott.e.graves@protonmail.com>
 | 
					MAINTAINER   Scott E. Graves <scott.e.graves@protonmail.com>
 | 
				
			||||||
CMD          bash
 | 
					CMD          bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -32,6 +32,9 @@ RUN apk add \
 | 
				
			|||||||
  gflags-dev \
 | 
					  gflags-dev \
 | 
				
			||||||
  git \
 | 
					  git \
 | 
				
			||||||
  git-lfs \
 | 
					  git-lfs \
 | 
				
			||||||
 | 
					  icu-dev \
 | 
				
			||||||
 | 
					  icu-libs \
 | 
				
			||||||
 | 
					  icu-static \
 | 
				
			||||||
  libogg-dev \
 | 
					  libogg-dev \
 | 
				
			||||||
  libogg-static \
 | 
					  libogg-static \
 | 
				
			||||||
  libtool \
 | 
					  libtool \
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
#comment
 | 
					#comment
 | 
				
			||||||
FROM         alpine:3.22.2
 | 
					FROM         alpine:3.21.3
 | 
				
			||||||
MAINTAINER   Scott E. Graves <scott.e.graves@protonmail.com>
 | 
					MAINTAINER   Scott E. Graves <scott.e.graves@protonmail.com>
 | 
				
			||||||
CMD          bash
 | 
					CMD          bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -32,6 +32,9 @@ RUN apk add \
 | 
				
			|||||||
  gflags-dev \
 | 
					  gflags-dev \
 | 
				
			||||||
  git \
 | 
					  git \
 | 
				
			||||||
  git-lfs \
 | 
					  git-lfs \
 | 
				
			||||||
 | 
					  icu-dev \
 | 
				
			||||||
 | 
					  icu-libs \
 | 
				
			||||||
 | 
					  icu-static \
 | 
				
			||||||
  libogg-dev \
 | 
					  libogg-dev \
 | 
				
			||||||
  libogg-static \
 | 
					  libogg-static \
 | 
				
			||||||
  libtool \
 | 
					  libtool \
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,6 +11,7 @@ RUN apt-get install -y \
 | 
				
			|||||||
  gdb \
 | 
					  gdb \
 | 
				
			||||||
  git \
 | 
					  git \
 | 
				
			||||||
  lib32stdc++6 \
 | 
					  lib32stdc++6 \
 | 
				
			||||||
 | 
					  libgconf-2-4 \
 | 
				
			||||||
  libglu1-mesa \
 | 
					  libglu1-mesa \
 | 
				
			||||||
  libstdc++6 \
 | 
					  libstdc++6 \
 | 
				
			||||||
  python3 \
 | 
					  python3 \
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
#comment
 | 
					#comment
 | 
				
			||||||
FROM alpine:3.22.2
 | 
					FROM alpine:3.21.3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RUN apk update
 | 
					RUN apk update
 | 
				
			||||||
RUN apk upgrade
 | 
					RUN apk upgrade
 | 
				
			||||||
@@ -12,7 +12,6 @@ RUN apk add \
 | 
				
			|||||||
  bzip2 \
 | 
					  bzip2 \
 | 
				
			||||||
  clang17-extra-tools \
 | 
					  clang17-extra-tools \
 | 
				
			||||||
  cmake \
 | 
					  cmake \
 | 
				
			||||||
  curl \
 | 
					 | 
				
			||||||
  file \
 | 
					  file \
 | 
				
			||||||
  flex \
 | 
					  flex \
 | 
				
			||||||
  g++ \
 | 
					  g++ \
 | 
				
			||||||
@@ -44,7 +43,6 @@ RUN apk add \
 | 
				
			|||||||
  ruby \
 | 
					  ruby \
 | 
				
			||||||
  texinfo \
 | 
					  texinfo \
 | 
				
			||||||
  unzip \
 | 
					  unzip \
 | 
				
			||||||
  xvfb \
 | 
					 | 
				
			||||||
  wget \
 | 
					  wget \
 | 
				
			||||||
  wine \
 | 
					  wine \
 | 
				
			||||||
  xz \
 | 
					  xz \
 | 
				
			||||||
@@ -104,39 +102,6 @@ RUN echo -e \
 | 
				
			|||||||
  "system = 'windows'\n"\
 | 
					  "system = 'windows'\n"\
 | 
				
			||||||
    > ${MY_TOOLCHAIN_FILE_MESON}
 | 
					    > ${MY_TOOLCHAIN_FILE_MESON}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RUN mkdir -p /opt/bin;echo -e \
 | 
					 | 
				
			||||||
  "#!/bin/sh\n"\
 | 
					 | 
				
			||||||
  "COUNT=0\n"\
 | 
					 | 
				
			||||||
  "echo \"Start waiting on \$@\"\n"\
 | 
					 | 
				
			||||||
  "while pgrep \"\$@\" > /dev/null; do \n"\
 | 
					 | 
				
			||||||
  "  echo \"waiting ...\"\n"\
 | 
					 | 
				
			||||||
  "  sleep 1;\n"\
 | 
					 | 
				
			||||||
  "  COUNT=\$((COUNT+1))\n"\
 | 
					 | 
				
			||||||
  "  if [ \$COUNT -eq 60 ]; then\n"\
 | 
					 | 
				
			||||||
  "    exit 3;\n"\
 | 
					 | 
				
			||||||
  "  fi\n"\
 | 
					 | 
				
			||||||
  "done\n"\
 | 
					 | 
				
			||||||
  "echo \"\$@ completed\"\n"\
 | 
					 | 
				
			||||||
      > /opt/bin/waitonprocess && \
 | 
					 | 
				
			||||||
      chmod +x /opt/bin/waitonprocess && \
 | 
					 | 
				
			||||||
      cat /opt/bin/waitonprocess
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
RUN echo -e \
 | 
					 | 
				
			||||||
  "#!/bin/sh\n"\
 | 
					 | 
				
			||||||
  "Xvfb \$DISPLAY &\n"\
 | 
					 | 
				
			||||||
  "tokill=\$!\n"\
 | 
					 | 
				
			||||||
  "wine wineboot --init\n"\
 | 
					 | 
				
			||||||
  "waitonprocess wineserver\n"\
 | 
					 | 
				
			||||||
  "\"\$@\"\n"\
 | 
					 | 
				
			||||||
  "retval=\$?\n"\
 | 
					 | 
				
			||||||
  "kill -15 \$tokill\n"\
 | 
					 | 
				
			||||||
  "wine wineboot --shutdown\n"\
 | 
					 | 
				
			||||||
  "return \$retval\n"\
 | 
					 | 
				
			||||||
        > /opt/bin/wine-x11-run && \
 | 
					 | 
				
			||||||
        chmod +x /opt/bin/wine-x11-run && \
 | 
					 | 
				
			||||||
        cat /opt/bin/wine-x11-run
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ENV PATH="/opt/bin:${PATH}"
 | 
					 | 
				
			||||||
SHELL [ "/bin/bash", "-c" ]
 | 
					SHELL [ "/bin/bash", "-c" ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RUN mkdir -p \
 | 
					RUN mkdir -p \
 | 
				
			||||||
@@ -746,7 +711,6 @@ RUN if [ -f "/3rd_party/cpp-httplib-${MY_CPP_HTTPLIB_VERSION}.tar.gz" ]; then \
 | 
				
			|||||||
        -DCMAKE_BUILD_TYPE=Release \
 | 
					        -DCMAKE_BUILD_TYPE=Release \
 | 
				
			||||||
        -DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
 | 
					        -DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
 | 
				
			||||||
        -DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
 | 
					        -DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
 | 
				
			||||||
        -DCMAKE_SYSTEM_VERSION="10.0.0" \
 | 
					 | 
				
			||||||
        -DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
 | 
					        -DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
 | 
				
			||||||
        -DHTTPLIB_REQUIRE_BROTLI=OFF \
 | 
					        -DHTTPLIB_REQUIRE_BROTLI=OFF \
 | 
				
			||||||
        -DHTTPLIB_REQUIRE_OPENSSL=ON \
 | 
					        -DHTTPLIB_REQUIRE_OPENSSL=ON \
 | 
				
			||||||
@@ -835,7 +799,6 @@ RUN if [ -f "/3rd_party/libevent-${MY_LIBEVENT_VERSION}-stable.tar.gz" ]; then \
 | 
				
			|||||||
      && cmake .. \
 | 
					      && cmake .. \
 | 
				
			||||||
        -DCMAKE_BUILD_TYPE=Release \
 | 
					        -DCMAKE_BUILD_TYPE=Release \
 | 
				
			||||||
        -DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
 | 
					        -DCMAKE_CXX_STANDARD=${MY_CXX_STANDARD} \
 | 
				
			||||||
        -DCMAKE_C_FLAGS="-include winsock2.h -include ws2tcpip.h -include iphlpapi.h" \
 | 
					 | 
				
			||||||
        -DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
 | 
					        -DCMAKE_INSTALL_PREFIX=${MY_MINGW_DIR} \
 | 
				
			||||||
        -DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
 | 
					        -DCMAKE_TOOLCHAIN_FILE=${MY_TOOLCHAIN_FILE_CMAKE} \
 | 
				
			||||||
        -DEVENT__DISABLE_OPENSSL=ON \
 | 
					        -DEVENT__DISABLE_OPENSSL=ON \
 | 
				
			||||||
@@ -925,7 +888,6 @@ RUN if [ -f "/3rd_party/rocksdb-${MY_ROCKSDB_VERSION}.tar.gz" ]; then \
 | 
				
			|||||||
        -DROCKSDB_INSTALL_ON_WINDOWS=ON \
 | 
					        -DROCKSDB_INSTALL_ON_WINDOWS=ON \
 | 
				
			||||||
        -DWITH_BENCHMARK=OFF \
 | 
					        -DWITH_BENCHMARK=OFF \
 | 
				
			||||||
        -DWITH_BENCHMARK_TOOLS=OFF \
 | 
					        -DWITH_BENCHMARK_TOOLS=OFF \
 | 
				
			||||||
        -DWITH_BZ2=OFF \
 | 
					 | 
				
			||||||
        -DWITH_CORE_TOOLS=OFF \
 | 
					        -DWITH_CORE_TOOLS=OFF \
 | 
				
			||||||
        -DWITH_EXAMPLES=OFF \
 | 
					        -DWITH_EXAMPLES=OFF \
 | 
				
			||||||
        -DWITH_GFLAGS=OFF \
 | 
					        -DWITH_GFLAGS=OFF \
 | 
				
			||||||
@@ -1157,33 +1119,6 @@ RUN if [ -f "/3rd_party/libdsm-${MY_LIBDSM_VERSION}.tar.gz" ]; then \
 | 
				
			|||||||
      && rm -r libdsm-${MY_LIBDSM_VERSION} \
 | 
					      && rm -r libdsm-${MY_LIBDSM_VERSION} \
 | 
				
			||||||
    ; fi
 | 
					    ; fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ENV DISPLAY=:90
 | 
					RUN (mv ${MY_MINGW_DIR}/lib/*.dll ${MY_MINGW_DIR}/bin || echo "no dll's found") \
 | 
				
			||||||
ENV WINEDEBUG=-all,err+all
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ARG INNOSETUP_VERSION
 | 
					 | 
				
			||||||
ENV MY_INNOSETUP_VERSION=${INNOSETUP_VERSION}
 | 
					 | 
				
			||||||
RUN rm -rf /root/.wine; \
 | 
					 | 
				
			||||||
  wine64 reg add 'HKEY_CURRENT_USER\Software\Wine' /v ShowDotFiles /d Y \
 | 
					 | 
				
			||||||
  && while [ ! -f /root/.wine/user.reg ]; do sleep 1; done; \
 | 
					 | 
				
			||||||
  wine-x11-run wine64 /3rd_party/mingw64/innosetup-${MY_INNOSETUP_VERSION}.exe /SP- /VERYSILENT /ALLUSERS /SUPPRESSMSGBOXES /DOWNLOADISCRYPT=1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ARG UID=1000
 | 
					 | 
				
			||||||
ARG GID=1000
 | 
					 | 
				
			||||||
ARG USERNAME=myuser
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
RUN delgroup scanner || echo "no scanner group found"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
RUN addgroup -g $GID $USERNAME && \
 | 
					 | 
				
			||||||
    adduser -D -u $UID -G $USERNAME -h /home/$USERNAME $USERNAME
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
RUN rsync -av --progress /root/.wine/ /home/$USERNAME/.wine/ && \
 | 
					 | 
				
			||||||
  chown -R $UID:$GID -R /home/$USERNAME/.wine/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
RUN (cp ${MY_MINGW_DIR}/lib/*.dll ${MY_MINGW_DIR}/bin || echo "no dll's found") \
 | 
					 | 
				
			||||||
    && chmod 0777 -R ${MY_MINGW_DIR} \
 | 
					    && chmod 0777 -R ${MY_MINGW_DIR} \
 | 
				
			||||||
    && rm -rf /3rd_party \
 | 
					    && rm -rf /3rd_party
 | 
				
			||||||
    && rm -rf /root/.wine
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
USER $USERNAME
 | 
					 | 
				
			||||||
WORKDIR /home/$USERNAME
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,7 +8,3 @@ rsync -av --progress ${CURRENT_DIR}/${PROJECT_NAME}/${PROJECT_NAME}_test/test_in
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
rsync -av --progress ${CURRENT_DIR}/${PROJECT_NAME}/${PROJECT_NAME}_test/test_input/ \
 | 
					rsync -av --progress ${CURRENT_DIR}/${PROJECT_NAME}/${PROJECT_NAME}_test/test_input/ \
 | 
				
			||||||
  ${PROJECT_DIST_DIR}/test_input/
 | 
					  ${PROJECT_DIST_DIR}/test_input/
 | 
				
			||||||
 | 
					 | 
				
			||||||
rsync -av --progress ${CURRENT_DIR}/assets/icon.ico ${PROJECT_DIST_DIR}/icon.ico
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
rsync -av --progress ${CURRENT_DIR}/assets/blue/logo.iconset/icon_128x128.png ${PROJECT_DIST_DIR}/repertory.png
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,10 +3,5 @@ set(CMAKE_CXX_FLAGS "-include common.hpp ${CMAKE_CXX_FLAGS}")
 | 
				
			|||||||
add_project_library(lib${PROJECT_NAME} "" "" "${PROJECT_ADDITIONAL_SOURCES}")
 | 
					add_project_library(lib${PROJECT_NAME} "" "" "${PROJECT_ADDITIONAL_SOURCES}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
add_project_executable(${PROJECT_NAME} lib${PROJECT_NAME} lib${PROJECT_NAME})
 | 
					add_project_executable(${PROJECT_NAME} lib${PROJECT_NAME} lib${PROJECT_NAME})
 | 
				
			||||||
if (PROJECT_IS_DARWIN AND EXISTS "${CMAKE_SOURCE_DIR}/${PROJECT_NAME}/Info.plist")
 | 
					 | 
				
			||||||
  set_target_properties(${PROJECT_NAME} PROPERTIES
 | 
					 | 
				
			||||||
    MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/Info.plist
 | 
					 | 
				
			||||||
  )
 | 
					 | 
				
			||||||
endif()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
add_project_test_executable(${PROJECT_NAME}_test lib${PROJECT_NAME} lib${PROJECT_NAME})
 | 
					add_project_test_executable(${PROJECT_NAME}_test lib${PROJECT_NAME} lib${PROJECT_NAME})
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,23 +0,0 @@
 | 
				
			|||||||
<?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>
 | 
					 | 
				
			||||||
@@ -1,421 +0,0 @@
 | 
				
			|||||||
#!/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 "$@"
 | 
					 | 
				
			||||||
@@ -31,22 +31,24 @@ private:
 | 
				
			|||||||
  static stop_type stop_requested;
 | 
					  static stop_type stop_requested;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  [[nodiscard]] static auto default_agent_name(provider_type prov)
 | 
					  [[nodiscard]] static auto default_agent_name(const provider_type &prov)
 | 
				
			||||||
      -> std::string;
 | 
					      -> std::string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] static auto default_api_port(provider_type prov)
 | 
					  [[nodiscard]] static auto default_api_port(const provider_type &prov)
 | 
				
			||||||
      -> std::uint16_t;
 | 
					      -> std::uint16_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] static auto default_data_directory(provider_type prov)
 | 
					  [[nodiscard]] static auto default_data_directory(const provider_type &prov)
 | 
				
			||||||
      -> std::string;
 | 
					      -> std::string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] static auto default_remote_api_port(provider_type prov)
 | 
					  [[nodiscard]] static auto default_remote_api_port(const provider_type &prov)
 | 
				
			||||||
      -> std::uint16_t;
 | 
					      -> std::uint16_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] static auto get_provider_display_name(provider_type prov)
 | 
					  [[nodiscard]] static auto default_rpc_port() -> std::uint16_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [[nodiscard]] static auto get_provider_display_name(const provider_type &prov)
 | 
				
			||||||
      -> std::string;
 | 
					      -> std::string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] static auto get_provider_name(provider_type prov)
 | 
					  [[nodiscard]] static auto get_provider_name(const provider_type &prov)
 | 
				
			||||||
      -> std::string;
 | 
					      -> std::string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] static auto get_root_data_directory() -> std::string;
 | 
					  [[nodiscard]] static auto get_root_data_directory() -> std::string;
 | 
				
			||||||
@@ -57,7 +59,7 @@ public:
 | 
				
			|||||||
  static void set_stop_requested();
 | 
					  static void set_stop_requested();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  app_config(provider_type prov, std::string_view data_directory);
 | 
					  app_config(const provider_type &prov, std::string_view data_directory = "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  app_config() = delete;
 | 
					  app_config() = delete;
 | 
				
			||||||
  app_config(app_config &&) = delete;
 | 
					  app_config(app_config &&) = delete;
 | 
				
			||||||
@@ -70,12 +72,10 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
  provider_type prov_;
 | 
					  provider_type prov_;
 | 
				
			||||||
  utils::atomic<std::string> api_password_;
 | 
					  atomic<std::string> api_password_;
 | 
				
			||||||
  std::atomic<std::uint16_t> api_port_;
 | 
					  std::atomic<std::uint16_t> api_port_;
 | 
				
			||||||
  utils::atomic<std::string> api_user_;
 | 
					  atomic<std::string> api_user_;
 | 
				
			||||||
  std::string cache_directory_;
 | 
					 | 
				
			||||||
  std::atomic<bool> config_changed_;
 | 
					  std::atomic<bool> config_changed_;
 | 
				
			||||||
  std::string data_directory_;
 | 
					 | 
				
			||||||
  std::atomic<database_type> db_type_{database_type::rocksdb};
 | 
					  std::atomic<database_type> db_type_{database_type::rocksdb};
 | 
				
			||||||
  std::atomic<std::uint8_t> download_timeout_secs_;
 | 
					  std::atomic<std::uint8_t> download_timeout_secs_;
 | 
				
			||||||
  std::atomic<bool> enable_download_timeout_;
 | 
					  std::atomic<bool> enable_download_timeout_;
 | 
				
			||||||
@@ -87,7 +87,6 @@ private:
 | 
				
			|||||||
  std::atomic<std::uint32_t> eviction_delay_mins_;
 | 
					  std::atomic<std::uint32_t> eviction_delay_mins_;
 | 
				
			||||||
  std::atomic<bool> eviction_uses_accessed_time_;
 | 
					  std::atomic<bool> eviction_uses_accessed_time_;
 | 
				
			||||||
  std::atomic<std::uint16_t> high_freq_interval_secs_;
 | 
					  std::atomic<std::uint16_t> high_freq_interval_secs_;
 | 
				
			||||||
  std::string log_directory_;
 | 
					 | 
				
			||||||
  std::atomic<std::uint16_t> low_freq_interval_secs_;
 | 
					  std::atomic<std::uint16_t> low_freq_interval_secs_;
 | 
				
			||||||
  std::atomic<std::uint64_t> max_cache_size_bytes_;
 | 
					  std::atomic<std::uint64_t> max_cache_size_bytes_;
 | 
				
			||||||
  std::atomic<std::uint8_t> max_upload_count_;
 | 
					  std::atomic<std::uint8_t> max_upload_count_;
 | 
				
			||||||
@@ -99,16 +98,20 @@ private:
 | 
				
			|||||||
  std::atomic<std::uint16_t> task_wait_ms_;
 | 
					  std::atomic<std::uint16_t> task_wait_ms_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
  utils::atomic<encrypt_config> encrypt_config_;
 | 
					  std::string cache_directory_;
 | 
				
			||||||
  utils::atomic<host_config> host_config_;
 | 
					  std::string data_directory_;
 | 
				
			||||||
 | 
					  atomic<encrypt_config> encrypt_config_;
 | 
				
			||||||
 | 
					  atomic<host_config> host_config_;
 | 
				
			||||||
 | 
					  std::string log_directory_;
 | 
				
			||||||
  mutable std::recursive_mutex read_write_mutex_;
 | 
					  mutable std::recursive_mutex read_write_mutex_;
 | 
				
			||||||
  utils::atomic<remote::remote_config> remote_config_;
 | 
					  atomic<remote::remote_config> remote_config_;
 | 
				
			||||||
  utils::atomic<remote::remote_mount> remote_mount_;
 | 
					  atomic<remote::remote_mount> remote_mount_;
 | 
				
			||||||
  utils::atomic<s3_config> s3_config_;
 | 
					  atomic<s3_config> s3_config_;
 | 
				
			||||||
  utils::atomic<sia_config> sia_config_;
 | 
					  atomic<sia_config> sia_config_;
 | 
				
			||||||
  std::unordered_map<std::string, std::function<std::string()>>
 | 
					  std::unordered_map<std::string, std::function<std::string()>>
 | 
				
			||||||
      value_get_lookup_;
 | 
					      value_get_lookup_;
 | 
				
			||||||
  std::unordered_map<std::string, std::function<std::string(std::string_view)>>
 | 
					  std::unordered_map<std::string,
 | 
				
			||||||
 | 
					                     std::function<std::string(const std::string &)>>
 | 
				
			||||||
      value_set_lookup_;
 | 
					      value_set_lookup_;
 | 
				
			||||||
  std::uint64_t version_{REPERTORY_CONFIG_VERSION};
 | 
					  std::uint64_t version_{REPERTORY_CONFIG_VERSION};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -118,8 +121,6 @@ private:
 | 
				
			|||||||
  template <typename dest, typename source>
 | 
					  template <typename dest, typename source>
 | 
				
			||||||
  auto set_value(dest &dst, const source &src) -> bool;
 | 
					  auto set_value(dest &dst, const source &src) -> bool;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  auto set_value(utils::atomic<std::string> &dst, std::string_view src) -> bool;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  [[nodiscard]] auto get_api_password() const -> std::string;
 | 
					  [[nodiscard]] auto get_api_password() const -> std::string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -189,21 +190,21 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto get_task_wait_ms() const -> std::uint16_t;
 | 
					  [[nodiscard]] auto get_task_wait_ms() const -> std::uint16_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto get_value_by_name(std::string_view name) const
 | 
					  [[nodiscard]] auto get_value_by_name(const std::string &name) const
 | 
				
			||||||
      -> std::string;
 | 
					      -> std::string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto get_raw_value_by_name(std::string_view name) const
 | 
					  [[nodiscard]] auto get_raw_value_by_name(const std::string &name) const
 | 
				
			||||||
      -> std::string;
 | 
					      -> std::string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto get_version() const -> std::uint64_t;
 | 
					  [[nodiscard]] auto get_version() const -> std::uint64_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void save();
 | 
					  void save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void set_api_password(std::string_view value);
 | 
					  void set_api_password(const std::string &value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void set_api_port(std::uint16_t value);
 | 
					  void set_api_port(std::uint16_t value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void set_api_user(std::string_view value);
 | 
					  void set_api_user(const std::string &value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void set_download_timeout_secs(std::uint8_t value);
 | 
					  void set_download_timeout_secs(std::uint8_t value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -255,8 +256,8 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  void set_task_wait_ms(std::uint16_t value);
 | 
					  void set_task_wait_ms(std::uint16_t value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto set_value_by_name(std::string_view name,
 | 
					  [[nodiscard]] auto set_value_by_name(const std::string &name,
 | 
				
			||||||
                                       std::string_view value) -> std::string;
 | 
					                                       const std::string &value) -> std::string;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
} // namespace repertory
 | 
					} // namespace repertory
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,7 +23,6 @@
 | 
				
			|||||||
#define REPERTORY_INCLUDE_COMM_CURL_CURL_COMM_HPP_
 | 
					#define REPERTORY_INCLUDE_COMM_CURL_CURL_COMM_HPP_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "app_config.hpp"
 | 
					#include "app_config.hpp"
 | 
				
			||||||
#include "comm/curl/curl_shared.hpp"
 | 
					 | 
				
			||||||
#include "comm/curl/multi_request.hpp"
 | 
					#include "comm/curl/multi_request.hpp"
 | 
				
			||||||
#include "comm/i_http_comm.hpp"
 | 
					#include "comm/i_http_comm.hpp"
 | 
				
			||||||
#include "events/event_system.hpp"
 | 
					#include "events/event_system.hpp"
 | 
				
			||||||
@@ -43,18 +42,20 @@ private:
 | 
				
			|||||||
  using write_callback = size_t (*)(char *, size_t, size_t, void *);
 | 
					  using write_callback = size_t (*)(char *, size_t, size_t, void *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  struct read_write_info final {
 | 
					  struct read_write_info final {
 | 
				
			||||||
    data_buffer data;
 | 
					    data_buffer data{};
 | 
				
			||||||
    stop_type_callback stop_requested_cb;
 | 
					    stop_type_callback stop_requested_cb;
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static const write_callback write_data;
 | 
					  static const write_callback write_data;
 | 
				
			||||||
  static const write_callback write_headers;
 | 
					  static const write_callback write_headers;
 | 
				
			||||||
  static constexpr std::uint8_t retry_request_count{5U};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
  std::optional<host_config> host_config_;
 | 
					  std::optional<host_config> host_config_;
 | 
				
			||||||
  std::optional<s3_config> s3_config_;
 | 
					  std::optional<s3_config> s3_config_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					  bool use_s3_path_style_{false};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  [[nodiscard]] static auto create_curl() -> CURL *;
 | 
					  [[nodiscard]] static auto create_curl() -> CURL *;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -62,14 +63,15 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  [[nodiscard]] static auto construct_url(CURL *curl,
 | 
					  [[nodiscard]] static auto construct_url(CURL *curl,
 | 
				
			||||||
                                          std::string_view relative_path,
 | 
					                                          const std::string &relative_path,
 | 
				
			||||||
                                          const host_config &cfg)
 | 
					                                          const host_config &cfg)
 | 
				
			||||||
      -> std::string;
 | 
					      -> std::string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] static auto create_host_config(const s3_config &cfg)
 | 
					  [[nodiscard]] static auto create_host_config(const s3_config &cfg,
 | 
				
			||||||
 | 
					                                               bool use_s3_path_style)
 | 
				
			||||||
      -> host_config;
 | 
					      -> host_config;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] static auto url_encode(CURL *curl, std::string_view data,
 | 
					  [[nodiscard]] static auto url_encode(CURL *curl, const std::string &data,
 | 
				
			||||||
                                       bool allow_slash) -> std::string;
 | 
					                                       bool allow_slash) -> std::string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  template <typename request_type>
 | 
					  template <typename request_type>
 | 
				
			||||||
@@ -93,19 +95,19 @@ public:
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    data_buffer data{};
 | 
					    data_buffer data{};
 | 
				
			||||||
    const auto key = utils::encryption::generate_key<utils::hash::hash_256_t>(
 | 
					    const auto key =
 | 
				
			||||||
        request.decryption_token.value());
 | 
					        utils::encryption::generate_key<utils::encryption::hash_256_t>(
 | 
				
			||||||
 | 
					            request.decryption_token.value());
 | 
				
			||||||
    if (not utils::encryption::read_encrypted_range(
 | 
					    if (not utils::encryption::read_encrypted_range(
 | 
				
			||||||
            request.range.value(), key,
 | 
					            request.range.value(), key,
 | 
				
			||||||
            [&](data_buffer &buffer, std::uint64_t start_offset,
 | 
					            [&](data_buffer &ct, std::uint64_t start_offset,
 | 
				
			||||||
                std::uint64_t end_offset) -> bool {
 | 
					                std::uint64_t end_offset) -> bool {
 | 
				
			||||||
              auto encrypted_request = request;
 | 
					              auto encrypted_request = request;
 | 
				
			||||||
              encrypted_request.decryption_token = std::nullopt;
 | 
					              encrypted_request.decryption_token = std::nullopt;
 | 
				
			||||||
              encrypted_request.range = {{start_offset, end_offset}};
 | 
					              encrypted_request.range = {{start_offset, end_offset}};
 | 
				
			||||||
              encrypted_request.response_handler =
 | 
					              encrypted_request.response_handler =
 | 
				
			||||||
                  [&buffer](const auto &encrypted_data,
 | 
					                  [&ct](const auto &encrypted_data, long /*response_code*/) {
 | 
				
			||||||
                            long /*response_code*/) {
 | 
					                    ct = encrypted_data;
 | 
				
			||||||
                    buffer = encrypted_data;
 | 
					 | 
				
			||||||
                  };
 | 
					                  };
 | 
				
			||||||
              encrypted_request.total_size = std::nullopt;
 | 
					              encrypted_request.total_size = std::nullopt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -137,128 +139,106 @@ public:
 | 
				
			|||||||
               long &response_code, stop_type &stop_requested) -> bool {
 | 
					               long &response_code, stop_type &stop_requested) -> bool {
 | 
				
			||||||
    REPERTORY_USES_FUNCTION_NAME();
 | 
					    REPERTORY_USES_FUNCTION_NAME();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    CURLcode curl_code{};
 | 
					    if (request.decryption_token.has_value() &&
 | 
				
			||||||
    const auto do_request = [&]() -> bool {
 | 
					        not request.decryption_token.value().empty()) {
 | 
				
			||||||
      if (request.decryption_token.has_value() &&
 | 
					      return make_encrypted_request(cfg, request, response_code,
 | 
				
			||||||
          not request.decryption_token.value().empty()) {
 | 
					                                    stop_requested);
 | 
				
			||||||
        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;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return ret;
 | 
					    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);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    auto url = construct_url(curl, request.get_path(), cfg) + parameters;
 | 
				
			||||||
 | 
					    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    multi_request curl_request(curl, stop_requested);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    CURLcode curl_code{};
 | 
				
			||||||
 | 
					    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, url);
 | 
				
			||||||
 | 
					      return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (request.response_handler.has_value()) {
 | 
				
			||||||
 | 
					      request.response_handler.value()(write_info.data, response_code);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
					  void enable_s3_path_style(bool enable) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto make_request(const curl::requests::http_delete &del,
 | 
					  [[nodiscard]] auto make_request(const curl::requests::http_delete &del,
 | 
				
			||||||
                                  long &response_code,
 | 
					                                  long &response_code,
 | 
				
			||||||
                                  stop_type &stop_requested) const
 | 
					                                  stop_type &stop_requested) const
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,67 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
  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_
 | 
					 | 
				
			||||||
@@ -26,13 +26,11 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace repertory::curl::requests {
 | 
					namespace repertory::curl::requests {
 | 
				
			||||||
struct http_delete final : http_request_base {
 | 
					struct http_delete final : http_request_base {
 | 
				
			||||||
  [[nodiscard]] auto get_type() const -> std::string override {
 | 
					  ~http_delete() override = default;
 | 
				
			||||||
    return "delete";
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto set_method(CURL *curl,
 | 
					  [[nodiscard]] auto
 | 
				
			||||||
                                stop_type & /* stop_requested */) const
 | 
					  set_method(CURL *curl,
 | 
				
			||||||
      -> bool override {
 | 
					             stop_type & /* stop_requested */) const -> bool override {
 | 
				
			||||||
    curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE");
 | 
					    curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE");
 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -33,11 +33,9 @@ struct http_get final : http_request_base {
 | 
				
			|||||||
  auto operator=(http_get &&) -> http_get & = default;
 | 
					  auto operator=(http_get &&) -> http_get & = default;
 | 
				
			||||||
  ~http_get() override = default;
 | 
					  ~http_get() override = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto get_type() const -> std::string override { return "get"; }
 | 
					  [[nodiscard]] auto
 | 
				
			||||||
 | 
					  set_method(CURL *curl,
 | 
				
			||||||
  [[nodiscard]] auto set_method(CURL *curl,
 | 
					             stop_type & /*stop_requested*/) const -> bool override {
 | 
				
			||||||
                                stop_type & /*stop_requested*/) const
 | 
					 | 
				
			||||||
      -> bool override {
 | 
					 | 
				
			||||||
    curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
 | 
					    curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,11 +26,11 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace repertory::curl::requests {
 | 
					namespace repertory::curl::requests {
 | 
				
			||||||
struct http_head final : http_request_base {
 | 
					struct http_head final : http_request_base {
 | 
				
			||||||
  [[nodiscard]] auto get_type() const -> std::string override { return "head"; }
 | 
					  ~http_head() override = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto set_method(CURL *curl,
 | 
					  [[nodiscard]] auto
 | 
				
			||||||
                                stop_type & /* stop_requested */) const
 | 
					  set_method(CURL *curl,
 | 
				
			||||||
      -> bool override {
 | 
					             stop_type & /* stop_requested */) const -> bool override {
 | 
				
			||||||
    curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "HEAD");
 | 
					    curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "HEAD");
 | 
				
			||||||
    curl_easy_setopt(curl, CURLOPT_NOBODY, 1L);
 | 
					    curl_easy_setopt(curl, CURLOPT_NOBODY, 1L);
 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,9 +26,15 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace repertory::curl::requests {
 | 
					namespace repertory::curl::requests {
 | 
				
			||||||
struct http_post final : http_request_base {
 | 
					struct http_post final : http_request_base {
 | 
				
			||||||
  std::optional<nlohmann::json> json;
 | 
					  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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto get_type() const -> std::string override { return "post"; }
 | 
					  ~http_post() override = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::optional<nlohmann::json> json;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto set_method(CURL *curl,
 | 
					  [[nodiscard]] auto set_method(CURL *curl,
 | 
				
			||||||
                                stop_type & /*stop_requested*/) const
 | 
					                                stop_type & /*stop_requested*/) const
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,11 +27,18 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace repertory::curl::requests {
 | 
					namespace repertory::curl::requests {
 | 
				
			||||||
struct http_put_file final : http_request_base {
 | 
					struct http_put_file final : http_request_base {
 | 
				
			||||||
 | 
					  http_put_file() = default;
 | 
				
			||||||
 | 
					  http_put_file(const http_put_file &) = default;
 | 
				
			||||||
 | 
					  http_put_file(http_put_file &&) = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  auto operator=(const http_put_file &) -> http_put_file & = default;
 | 
				
			||||||
 | 
					  auto operator=(http_put_file &&) -> http_put_file & = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ~http_put_file() override = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  std::shared_ptr<utils::encryption::encrypting_reader> reader;
 | 
					  std::shared_ptr<utils::encryption::encrypting_reader> reader;
 | 
				
			||||||
  std::string source_path;
 | 
					  std::string source_path;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto get_type() const -> std::string override { return "put"; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  [[nodiscard]] auto set_method(CURL *curl, stop_type &stop_requested) const
 | 
					  [[nodiscard]] auto set_method(CURL *curl, stop_type &stop_requested) const
 | 
				
			||||||
      -> bool override;
 | 
					      -> bool override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -61,8 +61,6 @@ struct http_request_base {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] virtual auto get_path() const -> std::string { return path; }
 | 
					  [[nodiscard]] virtual auto get_path() const -> std::string { return path; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] virtual auto get_type() const -> std::string = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  [[nodiscard]] virtual auto set_method(CURL *curl,
 | 
					  [[nodiscard]] virtual auto set_method(CURL *curl,
 | 
				
			||||||
                                        stop_type &stop_requested) const
 | 
					                                        stop_type &stop_requested) const
 | 
				
			||||||
      -> bool = 0;
 | 
					      -> bool = 0;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -34,29 +34,28 @@ struct i_http_comm {
 | 
				
			|||||||
  INTERFACE_SETUP(i_http_comm);
 | 
					  INTERFACE_SETUP(i_http_comm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
					  virtual void enable_s3_path_style(bool enable) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] virtual auto
 | 
					  [[nodiscard]] virtual auto
 | 
				
			||||||
  make_request(const curl::requests::http_delete &del, long &response_code,
 | 
					  make_request(const curl::requests::http_delete &del, long &response_code,
 | 
				
			||||||
               stop_type &stop_requested) const -> bool = 0;
 | 
					               stop_type &stop_requested) const -> bool = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] virtual auto make_request(const curl::requests::http_get &get,
 | 
					  [[nodiscard]] virtual auto
 | 
				
			||||||
                                          long &response_code,
 | 
					  make_request(const curl::requests::http_get &get, long &response_code,
 | 
				
			||||||
                                          stop_type &stop_requested) const
 | 
					               stop_type &stop_requested) const -> bool = 0;
 | 
				
			||||||
      -> bool = 0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] virtual auto make_request(const curl::requests::http_head &head,
 | 
					  [[nodiscard]] virtual auto
 | 
				
			||||||
                                          long &response_code,
 | 
					  make_request(const curl::requests::http_head &head, long &response_code,
 | 
				
			||||||
                                          stop_type &stop_requested) const
 | 
					               stop_type &stop_requested) const -> bool = 0;
 | 
				
			||||||
      -> bool = 0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] virtual auto make_request(const curl::requests::http_post &post,
 | 
					  [[nodiscard]] virtual auto
 | 
				
			||||||
                                          long &response_code,
 | 
					  make_request(const curl::requests::http_post &post, long &response_code,
 | 
				
			||||||
                                          stop_type &stop_requested) const
 | 
					               stop_type &stop_requested) const -> bool = 0;
 | 
				
			||||||
      -> bool = 0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] virtual auto
 | 
					  [[nodiscard]] virtual auto
 | 
				
			||||||
  make_request(const curl::requests::http_put_file &put_file,
 | 
					  make_request(const curl::requests::http_put_file &put_file,
 | 
				
			||||||
               long &response_code, stop_type &stop_requested) const
 | 
					               long &response_code,
 | 
				
			||||||
      -> bool = 0;
 | 
					               stop_type &stop_requested) const -> bool = 0;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
} // namespace repertory
 | 
					} // namespace repertory
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,13 +23,10 @@
 | 
				
			|||||||
#define REPERTORY_INCLUDE_COMM_PACKET_CLIENT_POOL_HPP_
 | 
					#define REPERTORY_INCLUDE_COMM_PACKET_CLIENT_POOL_HPP_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "comm/packet/packet.hpp"
 | 
					#include "comm/packet/packet.hpp"
 | 
				
			||||||
 | 
					#include "types/repertory.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace repertory {
 | 
					namespace repertory {
 | 
				
			||||||
class client_pool final {
 | 
					class client_pool final {
 | 
				
			||||||
public:
 | 
					 | 
				
			||||||
  static constexpr const std::uint16_t default_expired_seconds{120U};
 | 
					 | 
				
			||||||
  static constexpr const std::uint16_t min_expired_seconds{5U};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  using worker_callback = std::function<packet::error_type()>;
 | 
					  using worker_callback = std::function<packet::error_type()>;
 | 
				
			||||||
  using worker_complete_callback =
 | 
					  using worker_complete_callback =
 | 
				
			||||||
@@ -49,32 +46,15 @@ private:
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    struct work_queue final {
 | 
					    struct work_queue final {
 | 
				
			||||||
      work_queue();
 | 
					 | 
				
			||||||
      ~work_queue();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      work_queue(const work_queue &) = delete;
 | 
					 | 
				
			||||||
      work_queue(work_queue &&) = delete;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      std::deque<std::shared_ptr<work_item>> actions;
 | 
					 | 
				
			||||||
      std::atomic<std::chrono::steady_clock::time_point> modified{
 | 
					 | 
				
			||||||
          std::chrono::steady_clock::now(),
 | 
					 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
      std::mutex mutex;
 | 
					      std::mutex mutex;
 | 
				
			||||||
      std::condition_variable notify;
 | 
					      std::condition_variable notify;
 | 
				
			||||||
      stop_type shutdown{false};
 | 
					      std::deque<std::shared_ptr<work_item>> queue;
 | 
				
			||||||
      std::unique_ptr<std::thread> thread;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      auto operator=(const work_queue &) -> work_queue & = delete;
 | 
					 | 
				
			||||||
      auto operator=(work_queue &&) -> work_queue & = delete;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private:
 | 
					 | 
				
			||||||
      void work_thread();
 | 
					 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public:
 | 
					  public:
 | 
				
			||||||
    pool() noexcept = default;
 | 
					    explicit pool(std::uint8_t pool_size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ~pool();
 | 
					    ~pool() { shutdown(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public:
 | 
					  public:
 | 
				
			||||||
    pool(const pool &) = delete;
 | 
					    pool(const pool &) = delete;
 | 
				
			||||||
@@ -83,20 +63,21 @@ private:
 | 
				
			|||||||
    auto operator=(pool &&) -> pool & = delete;
 | 
					    auto operator=(pool &&) -> pool & = delete;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private:
 | 
					  private:
 | 
				
			||||||
    std::mutex pool_mtx_;
 | 
					    std::vector<std::unique_ptr<work_queue>> pool_queues_;
 | 
				
			||||||
    std::unordered_map<std::uint64_t, std::shared_ptr<work_queue>> pool_queues_;
 | 
					    std::vector<std::thread> pool_threads_;
 | 
				
			||||||
 | 
					    bool shutdown_{false};
 | 
				
			||||||
 | 
					    std::atomic<std::uint8_t> thread_index_{};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public:
 | 
					  public:
 | 
				
			||||||
    void execute(std::uint64_t thread_id, worker_callback worker,
 | 
					    void execute(std::uint64_t thread_id, const worker_callback &worker,
 | 
				
			||||||
                 worker_complete_callback worker_complete);
 | 
					                 const worker_complete_callback &worker_complete);
 | 
				
			||||||
 | 
					 | 
				
			||||||
    void remove_expired(std::uint16_t seconds);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void shutdown();
 | 
					    void shutdown();
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  client_pool() noexcept;
 | 
					  explicit client_pool(std::uint8_t pool_size = min_pool_size)
 | 
				
			||||||
 | 
					      : pool_size_(pool_size == 0U ? min_pool_size : pool_size) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ~client_pool() { shutdown(); }
 | 
					  ~client_pool() { shutdown(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -107,23 +88,20 @@ public:
 | 
				
			|||||||
  auto operator=(client_pool &&) -> client_pool & = delete;
 | 
					  auto operator=(client_pool &&) -> client_pool & = delete;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
  std::unordered_map<std::string, std::unique_ptr<pool>> pool_lookup_;
 | 
					  std::uint8_t pool_size_;
 | 
				
			||||||
 | 
					  std::unordered_map<std::string, std::shared_ptr<pool>> pool_lookup_;
 | 
				
			||||||
  std::mutex pool_mutex_;
 | 
					  std::mutex pool_mutex_;
 | 
				
			||||||
  stop_type shutdown_{false};
 | 
					  bool shutdown_ = false;
 | 
				
			||||||
  std::atomic<std::uint16_t> expired_seconds_{default_expired_seconds};
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					  static constexpr const auto min_pool_size = 10U;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  [[nodiscard]] auto get_expired_seconds() const -> std::uint16_t;
 | 
					  void execute(const std::string &client_id, std::uint64_t thread_id,
 | 
				
			||||||
 | 
					               const worker_callback &worker,
 | 
				
			||||||
 | 
					               const worker_complete_callback &worker_complete);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void execute(std::string client_id, std::uint64_t thread_id,
 | 
					  void remove_client(const std::string &client_id);
 | 
				
			||||||
               worker_callback worker,
 | 
					 | 
				
			||||||
               worker_complete_callback worker_complete);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  void remove_client(std::string client_id);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  void remove_expired();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  void set_expired_seconds(std::uint16_t seconds);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void shutdown();
 | 
					  void shutdown();
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,54 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
  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_
 | 
					 | 
				
			||||||
@@ -200,7 +200,7 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  void encode_top(remote::file_info val);
 | 
					  void encode_top(remote::file_info val);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void encrypt(std::string_view token, bool include_size = true);
 | 
					  void encrypt(std::string_view token);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto get_size() const -> std::uint32_t {
 | 
					  [[nodiscard]] auto get_size() const -> std::uint32_t {
 | 
				
			||||||
    return static_cast<std::uint32_t>(buffer_.size());
 | 
					    return static_cast<std::uint32_t>(buffer_.size());
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,13 +1,17 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
  Copyright <2018-2025> <scott.e.graves@protonmail.com>
 | 
					  Copyright <2018-2025> <scott.e.graves@protonmail.com>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
					  Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
				
			||||||
  of this software and associated documentation files (the "Software"), to deal
 | 
					  of this software and associated documentation files (the "Software"), to deal
 | 
				
			||||||
  in the Software without restriction, including without limitation the rights
 | 
					  in the Software without restriction, including without limitation the rights
 | 
				
			||||||
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
					  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
				
			||||||
  copies of the Software, and to permit persons to do so, subject to the
 | 
					  copies of the Software, and to permit persons to whom the Software is
 | 
				
			||||||
  following conditions: The above copyright notice and this permission notice
 | 
					  furnished to do so, subject to the following conditions:
 | 
				
			||||||
  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
 | 
					  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,
 | 
					  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
				
			||||||
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
					  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
				
			||||||
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
					  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
				
			||||||
@@ -20,7 +24,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "comm/packet/packet.hpp"
 | 
					#include "comm/packet/packet.hpp"
 | 
				
			||||||
#include "types/remote.hpp"
 | 
					#include "types/remote.hpp"
 | 
				
			||||||
#include "utils/atomic.hpp"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
using boost::asio::ip::tcp;
 | 
					using boost::asio::ip::tcp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -44,55 +47,43 @@ public:
 | 
				
			|||||||
  auto operator=(packet_client &&) -> packet_client & = delete;
 | 
					  auto operator=(packet_client &&) -> packet_client & = delete;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
 | 
					  boost::asio::io_context io_context_;
 | 
				
			||||||
  remote::remote_config cfg_;
 | 
					  remote::remote_config cfg_;
 | 
				
			||||||
  mutable boost::asio::io_context io_context_;
 | 
					  std::string unique_id_;
 | 
				
			||||||
  utils::atomic<std::string> unique_id_;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
  std::atomic<bool> allow_connections_{true};
 | 
					  bool allow_connections_{true};
 | 
				
			||||||
  utils::atomic<
 | 
					  boost::asio::ip::basic_resolver<boost::asio::ip::tcp>::results_type
 | 
				
			||||||
      boost::asio::ip::basic_resolver<boost::asio::ip::tcp>::results_type>
 | 
					 | 
				
			||||||
      resolve_results_;
 | 
					      resolve_results_;
 | 
				
			||||||
  std::mutex clients_mutex_;
 | 
					  std::mutex clients_mutex_;
 | 
				
			||||||
  std::vector<std::shared_ptr<client>> clients_;
 | 
					  std::vector<std::shared_ptr<client>> clients_;
 | 
				
			||||||
  std::vector<std::thread> service_threads_;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
  static void close(client &cli) noexcept;
 | 
					  static void close(client &cli);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void close_all();
 | 
					  void close_all();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto connect(client &cli) -> bool;
 | 
					  void connect(client &cli);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto get_client() -> std::shared_ptr<client>;
 | 
					  [[nodiscard]] auto get_client() -> std::shared_ptr<client>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto handshake(client &cli, std::uint32_t &min_version) const
 | 
					 | 
				
			||||||
      -> bool;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  void put_client(std::shared_ptr<client> &cli);
 | 
					  void put_client(std::shared_ptr<client> &cli);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void read_data(client &cli, data_buffer &buffer) const;
 | 
					  [[nodiscard]] auto read_packet(client &cli,
 | 
				
			||||||
 | 
					                                 packet &response) const -> packet::error_type;
 | 
				
			||||||
  [[nodiscard]] auto read_packet(client &cli, packet &response) const
 | 
					 | 
				
			||||||
      -> packet::error_type;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void resolve();
 | 
					  void resolve();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void write_data(client &cli, const packet &request) const;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  [[nodiscard]] auto check_version(std::uint32_t client_version,
 | 
					  [[nodiscard]] auto send(std::string_view method,
 | 
				
			||||||
                                   std::uint32_t &min_version) -> api_error;
 | 
					                          std::uint32_t &service_flags) -> packet::error_type;
 | 
				
			||||||
 | 
					 | 
				
			||||||
  [[nodiscard]] auto send(std::string_view method, std::uint32_t &service_flags)
 | 
					 | 
				
			||||||
      -> packet::error_type;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto send(std::string_view method, packet &request,
 | 
					  [[nodiscard]] auto send(std::string_view method, packet &request,
 | 
				
			||||||
                          std::uint32_t &service_flags) -> packet::error_type;
 | 
					                          std::uint32_t &service_flags) -> packet::error_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto send(std::string_view method, packet &request,
 | 
					  [[nodiscard]] auto send(std::string_view method, packet &request,
 | 
				
			||||||
                          packet &response, std::uint32_t &service_flags)
 | 
					                          packet &response,
 | 
				
			||||||
      -> packet::error_type;
 | 
					                          std::uint32_t &service_flags) -> packet::error_type;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
} // namespace repertory
 | 
					} // namespace repertory
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,7 +23,6 @@
 | 
				
			|||||||
#define REPERTORY_INCLUDE_COMM_PACKET_PACKET_SERVER_HPP_
 | 
					#define REPERTORY_INCLUDE_COMM_PACKET_PACKET_SERVER_HPP_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "comm/packet/client_pool.hpp"
 | 
					#include "comm/packet/client_pool.hpp"
 | 
				
			||||||
#include "comm/packet/common.hpp"
 | 
					 | 
				
			||||||
#include "utils/common.hpp"
 | 
					#include "utils/common.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using namespace boost::asio;
 | 
					using namespace boost::asio;
 | 
				
			||||||
@@ -32,11 +31,11 @@ using boost::asio::ip::tcp;
 | 
				
			|||||||
namespace repertory {
 | 
					namespace repertory {
 | 
				
			||||||
class packet_server final {
 | 
					class packet_server final {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  using closed_callback = std::function<void(std::string)>;
 | 
					  using closed_callback = std::function<void(const std::string &)>;
 | 
				
			||||||
  using message_complete_callback = client_pool::worker_complete_callback;
 | 
					  using message_complete_callback = client_pool::worker_complete_callback;
 | 
				
			||||||
  using message_handler_callback =
 | 
					  using message_handler_callback = std::function<void(
 | 
				
			||||||
      std::function<void(std::uint32_t, std::string, std::uint64_t, std::string,
 | 
					      std::uint32_t, const std::string &, std::uint64_t, const std::string &,
 | 
				
			||||||
                         packet *, packet &, message_complete_callback)>;
 | 
					      packet *, packet &, message_complete_callback)>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  packet_server(std::uint16_t port, std::string token, std::uint8_t pool_size,
 | 
					  packet_server(std::uint16_t port, std::string token, std::uint8_t pool_size,
 | 
				
			||||||
@@ -62,25 +61,21 @@ private:
 | 
				
			|||||||
    std::string client_id;
 | 
					    std::string client_id;
 | 
				
			||||||
    std::string nonce;
 | 
					    std::string nonce;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void generate_nonce() {
 | 
					    void generate_nonce() { nonce = utils::generate_random_string(256U); }
 | 
				
			||||||
      nonce = utils::generate_random_string(comm::packet_nonce_size);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
  std::string encryption_token_;
 | 
					  std::string encryption_token_;
 | 
				
			||||||
  closed_callback closed_;
 | 
					  closed_callback closed_;
 | 
				
			||||||
  message_handler_callback message_handler_;
 | 
					  message_handler_callback message_handler_;
 | 
				
			||||||
  mutable io_context io_context_;
 | 
					  io_context io_context_;
 | 
				
			||||||
  std::unique_ptr<std::thread> server_thread_;
 | 
					  std::unique_ptr<std::thread> server_thread_;
 | 
				
			||||||
  std::vector<std::thread> service_threads_;
 | 
					  std::vector<std::thread> service_threads_;
 | 
				
			||||||
  std::recursive_mutex connection_mutex_;
 | 
					  std::recursive_mutex connection_mutex_;
 | 
				
			||||||
  std::unordered_map<std::string, std::uint32_t> connection_lookup_;
 | 
					  std::unordered_map<std::string, std::uint32_t> connection_lookup_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
  void add_client(connection &conn, std::string client_id);
 | 
					  void add_client(connection &conn, const std::string &client_id);
 | 
				
			||||||
 | 
					 | 
				
			||||||
  [[nodiscard]] auto handshake(std::shared_ptr<connection> conn) const -> bool;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void initialize(const uint16_t &port, uint8_t pool_size);
 | 
					  void initialize(const uint16_t &port, uint8_t pool_size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,7 +22,7 @@
 | 
				
			|||||||
#ifndef REPERTORY_INCLUDE_COMMON_HPP_
 | 
					#ifndef REPERTORY_INCLUDE_COMMON_HPP_
 | 
				
			||||||
#define REPERTORY_INCLUDE_COMMON_HPP_
 | 
					#define REPERTORY_INCLUDE_COMMON_HPP_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(__GNUC__) && !defined(PROJECT_IS_DARWIN)
 | 
					#if defined(__GNUC__)
 | 
				
			||||||
// clang-format off
 | 
					// clang-format off
 | 
				
			||||||
#define REPERTORY_IGNORE_WARNINGS_ENABLE()                                     \
 | 
					#define REPERTORY_IGNORE_WARNINGS_ENABLE()                                     \
 | 
				
			||||||
  _Pragma("GCC diagnostic push")                                               \
 | 
					  _Pragma("GCC diagnostic push")                                               \
 | 
				
			||||||
@@ -54,13 +54,13 @@ REPERTORY_IGNORE_WARNINGS_DISABLE()
 | 
				
			|||||||
using namespace std::chrono_literals;
 | 
					using namespace std::chrono_literals;
 | 
				
			||||||
using json = nlohmann::json;
 | 
					using json = nlohmann::json;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
inline constexpr std::string_view REPERTORY{"repertory"};
 | 
					inline constexpr const std::string_view REPERTORY{"repertory"};
 | 
				
			||||||
inline constexpr std::string_view REPERTORY_DATA_NAME{"repertory2"};
 | 
					inline constexpr const std::string_view REPERTORY_DATA_NAME{"repertory2"};
 | 
				
			||||||
inline constexpr std::wstring_view REPERTORY_W{L"repertory"};
 | 
					inline constexpr const std::wstring_view REPERTORY_W{L"repertory"};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
inline constexpr std::uint64_t REPERTORY_CONFIG_VERSION{5ULL};
 | 
					inline constexpr const std::uint64_t REPERTORY_CONFIG_VERSION{2ULL};
 | 
				
			||||||
inline constexpr std::string_view REPERTORY_MIN_REMOTE_VERSION{"2.1.0"};
 | 
					inline constexpr const std::string_view REPERTORY_MIN_REMOTE_VERSION{"2.0.0"};
 | 
				
			||||||
inline constexpr std::string_view RENTERD_MIN_VERSION{"2.0.0"};
 | 
					inline constexpr const std::string_view RENTERD_MIN_VERSION{"2.0.0"};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define REPERTORY_INVALID_HANDLE INVALID_HANDLE_VALUE
 | 
					#define REPERTORY_INVALID_HANDLE INVALID_HANDLE_VALUE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -226,7 +226,6 @@ using WCHAR = wchar_t;
 | 
				
			|||||||
#define STATUS_DEVICE_BUSY std::uint32_t{0x80000011L}
 | 
					#define STATUS_DEVICE_BUSY std::uint32_t{0x80000011L}
 | 
				
			||||||
#define STATUS_DEVICE_INSUFFICIENT_RESOURCES std::uint32_t{0xC0000468L}
 | 
					#define STATUS_DEVICE_INSUFFICIENT_RESOURCES std::uint32_t{0xC0000468L}
 | 
				
			||||||
#define STATUS_DIRECTORY_NOT_EMPTY std::uint32_t{0xC0000101L}
 | 
					#define STATUS_DIRECTORY_NOT_EMPTY std::uint32_t{0xC0000101L}
 | 
				
			||||||
#define STATUS_END_OF_FILE std::uint32_t{0xC0000011L}
 | 
					 | 
				
			||||||
#define STATUS_FILE_IS_A_DIRECTORY std::uint32_t{0xC00000BAL}
 | 
					#define STATUS_FILE_IS_A_DIRECTORY std::uint32_t{0xC00000BAL}
 | 
				
			||||||
#define STATUS_FILE_TOO_LARGE std::uint32_t{0xC0000904L}
 | 
					#define STATUS_FILE_TOO_LARGE std::uint32_t{0xC0000904L}
 | 
				
			||||||
#define STATUS_INSUFFICIENT_RESOURCES std::uint32_t{0xC000009AL}
 | 
					#define STATUS_INSUFFICIENT_RESOURCES std::uint32_t{0xC000009AL}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,13 +29,6 @@ class i_file_db {
 | 
				
			|||||||
  INTERFACE_SETUP(i_file_db);
 | 
					  INTERFACE_SETUP(i_file_db);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  struct directory_data final {
 | 
					 | 
				
			||||||
    std::string api_path;
 | 
					 | 
				
			||||||
    std::pair<utils::encryption::kdf_config, utils::encryption::kdf_config>
 | 
					 | 
				
			||||||
        kdf_configs;
 | 
					 | 
				
			||||||
    std::string source_path;
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  struct file_info final {
 | 
					  struct file_info final {
 | 
				
			||||||
    std::string api_path;
 | 
					    std::string api_path;
 | 
				
			||||||
    bool directory{};
 | 
					    bool directory{};
 | 
				
			||||||
@@ -47,14 +40,13 @@ public:
 | 
				
			|||||||
    std::uint64_t file_size{};
 | 
					    std::uint64_t file_size{};
 | 
				
			||||||
    std::vector<
 | 
					    std::vector<
 | 
				
			||||||
        std::array<unsigned char, crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>>
 | 
					        std::array<unsigned char, crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>>
 | 
				
			||||||
        iv_list;
 | 
					        iv_list{};
 | 
				
			||||||
    std::pair<utils::encryption::kdf_config, utils::encryption::kdf_config>
 | 
					 | 
				
			||||||
        kdf_configs;
 | 
					 | 
				
			||||||
    std::string source_path;
 | 
					    std::string source_path;
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  [[nodiscard]] virtual auto add_or_update_directory(const directory_data &data)
 | 
					  [[nodiscard]] virtual auto add_directory(const std::string &api_path,
 | 
				
			||||||
 | 
					                                           const std::string &source_path)
 | 
				
			||||||
      -> api_error = 0;
 | 
					      -> api_error = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] virtual auto add_or_update_file(const file_data &data)
 | 
					  [[nodiscard]] virtual auto add_or_update_file(const file_data &data)
 | 
				
			||||||
@@ -68,43 +60,39 @@ public:
 | 
				
			|||||||
      std::function<void(const std::vector<i_file_db::file_info> &)> callback,
 | 
					      std::function<void(const std::vector<i_file_db::file_info> &)> callback,
 | 
				
			||||||
      stop_type_callback stop_requested_cb) const = 0;
 | 
					      stop_type_callback stop_requested_cb) const = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] virtual auto get_api_path(std::string_view source_path,
 | 
					  [[nodiscard]] virtual auto get_api_path(const std::string &source_path,
 | 
				
			||||||
                                          std::string &api_path) const
 | 
					                                          std::string &api_path) const
 | 
				
			||||||
      -> api_error = 0;
 | 
					      -> api_error = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] virtual auto
 | 
					  [[nodiscard]] virtual auto
 | 
				
			||||||
  get_directory_api_path(std::string_view source_path,
 | 
					  get_directory_api_path(const std::string &source_path,
 | 
				
			||||||
                         std::string &api_path) const -> api_error = 0;
 | 
					                         std::string &api_path) const -> api_error = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] virtual auto get_directory_data(std::string_view api_path,
 | 
					 | 
				
			||||||
                                                directory_data &data) const
 | 
					 | 
				
			||||||
      -> api_error = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  [[nodiscard]] virtual auto
 | 
					  [[nodiscard]] virtual auto
 | 
				
			||||||
  get_directory_source_path(std::string_view api_path,
 | 
					  get_directory_source_path(const std::string &api_path,
 | 
				
			||||||
                            std::string &source_path) const -> api_error = 0;
 | 
					                            std::string &source_path) const -> api_error = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] virtual auto get_file_api_path(std::string_view source_path,
 | 
					  [[nodiscard]] virtual auto get_file_api_path(const std::string &source_path,
 | 
				
			||||||
                                               std::string &api_path) const
 | 
					                                               std::string &api_path) const
 | 
				
			||||||
      -> api_error = 0;
 | 
					      -> api_error = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] virtual auto get_file_data(std::string_view api_path,
 | 
					  [[nodiscard]] virtual auto get_file_data(const std::string &api_path,
 | 
				
			||||||
                                           file_data &data) const
 | 
					                                           file_data &data) const
 | 
				
			||||||
      -> api_error = 0;
 | 
					      -> api_error = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] virtual auto
 | 
					  [[nodiscard]] virtual auto
 | 
				
			||||||
  get_file_source_path(std::string_view api_path,
 | 
					  get_file_source_path(const std::string &api_path,
 | 
				
			||||||
                       std::string &source_path) const -> api_error = 0;
 | 
					                       std::string &source_path) const -> api_error = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] virtual auto
 | 
					  [[nodiscard]] virtual auto
 | 
				
			||||||
  get_item_list(stop_type_callback stop_requested_cb) const
 | 
					  get_item_list(stop_type_callback stop_requested_cb) const
 | 
				
			||||||
      -> std::vector<file_info> = 0;
 | 
					      -> std::vector<file_info> = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] virtual auto get_source_path(std::string_view api_path,
 | 
					  [[nodiscard]] virtual auto get_source_path(const std::string &api_path,
 | 
				
			||||||
                                             std::string &source_path) const
 | 
					                                             std::string &source_path) const
 | 
				
			||||||
      -> api_error = 0;
 | 
					      -> api_error = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] virtual auto remove_item(std::string_view api_path)
 | 
					  [[nodiscard]] virtual auto remove_item(const std::string &api_path)
 | 
				
			||||||
      -> api_error = 0;
 | 
					      -> api_error = 0;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
} // namespace repertory
 | 
					} // namespace repertory
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -59,23 +59,23 @@ public:
 | 
				
			|||||||
  [[nodiscard]] virtual auto get_resume_list() const
 | 
					  [[nodiscard]] virtual auto get_resume_list() const
 | 
				
			||||||
      -> std::vector<resume_entry> = 0;
 | 
					      -> std::vector<resume_entry> = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] virtual auto get_upload(std::string_view api_path) const
 | 
					  [[nodiscard]] virtual auto get_upload(const std::string &api_path) const
 | 
				
			||||||
      -> std::optional<upload_entry> = 0;
 | 
					      -> std::optional<upload_entry> = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] virtual auto get_upload_active_list() const
 | 
					  [[nodiscard]] virtual auto get_upload_active_list() const
 | 
				
			||||||
      -> std::vector<upload_active_entry> = 0;
 | 
					      -> std::vector<upload_active_entry> = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] virtual auto remove_resume(std::string_view api_path)
 | 
					  [[nodiscard]] virtual auto remove_resume(const std::string &api_path)
 | 
				
			||||||
      -> bool = 0;
 | 
					      -> bool = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] virtual auto remove_upload(std::string_view api_path)
 | 
					  [[nodiscard]] virtual auto remove_upload(const std::string &api_path)
 | 
				
			||||||
      -> bool = 0;
 | 
					      -> bool = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] virtual auto remove_upload_active(std::string_view api_path)
 | 
					  [[nodiscard]] virtual auto remove_upload_active(const std::string &api_path)
 | 
				
			||||||
      -> bool = 0;
 | 
					      -> bool = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] virtual auto rename_resume(std::string_view from_api_path,
 | 
					  [[nodiscard]] virtual auto rename_resume(const std::string &from_api_path,
 | 
				
			||||||
                                           std::string_view to_api_path)
 | 
					                                           const std::string &to_api_path)
 | 
				
			||||||
      -> bool = 0;
 | 
					      -> bool = 0;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
} // namespace repertory
 | 
					} // namespace repertory
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,19 +35,19 @@ public:
 | 
				
			|||||||
      std::function<void(const std::vector<std::string> &)> callback,
 | 
					      std::function<void(const std::vector<std::string> &)> callback,
 | 
				
			||||||
      stop_type_callback stop_requested_cb) const = 0;
 | 
					      stop_type_callback stop_requested_cb) const = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] virtual auto get_api_path(std::string_view source_path,
 | 
					  [[nodiscard]] virtual auto get_api_path(const std::string &source_path,
 | 
				
			||||||
                                          std::string &api_path) const
 | 
					                                          std::string &api_path) const
 | 
				
			||||||
      -> api_error = 0;
 | 
					      -> api_error = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] virtual auto get_api_path_list() const
 | 
					  [[nodiscard]] virtual auto get_api_path_list() const
 | 
				
			||||||
      -> std::vector<std::string> = 0;
 | 
					      -> std::vector<std::string> = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] virtual auto get_item_meta(std::string_view api_path,
 | 
					  [[nodiscard]] virtual auto get_item_meta(const std::string &api_path,
 | 
				
			||||||
                                           api_meta_map &meta) const
 | 
					                                           api_meta_map &meta) const
 | 
				
			||||||
      -> api_error = 0;
 | 
					      -> api_error = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] virtual auto get_item_meta(std::string_view api_path,
 | 
					  [[nodiscard]] virtual auto get_item_meta(const std::string &api_path,
 | 
				
			||||||
                                           std::string_view key,
 | 
					                                           const std::string &key,
 | 
				
			||||||
                                           std::string &value) const
 | 
					                                           std::string &value) const
 | 
				
			||||||
      -> api_error = 0;
 | 
					      -> api_error = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -58,22 +58,22 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] virtual auto get_total_size() const -> std::uint64_t = 0;
 | 
					  [[nodiscard]] virtual auto get_total_size() const -> std::uint64_t = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  virtual void remove_api_path(std::string_view api_path) = 0;
 | 
					  virtual void remove_api_path(const std::string &api_path) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] virtual auto remove_item_meta(std::string_view api_path,
 | 
					  [[nodiscard]] virtual auto remove_item_meta(const std::string &api_path,
 | 
				
			||||||
                                              std::string_view key)
 | 
					                                              const std::string &key)
 | 
				
			||||||
      -> api_error = 0;
 | 
					      -> api_error = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] virtual auto rename_item_meta(std::string_view from_api_path,
 | 
					  [[nodiscard]] virtual auto rename_item_meta(const std::string &from_api_path,
 | 
				
			||||||
                                              std::string_view to_api_path)
 | 
					                                              const std::string &to_api_path)
 | 
				
			||||||
      -> api_error = 0;
 | 
					      -> api_error = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] virtual auto set_item_meta(std::string_view api_path,
 | 
					  [[nodiscard]] virtual auto set_item_meta(const std::string &api_path,
 | 
				
			||||||
                                           std::string_view key,
 | 
					                                           const std::string &key,
 | 
				
			||||||
                                           std::string_view value)
 | 
					                                           const std::string &value)
 | 
				
			||||||
      -> api_error = 0;
 | 
					      -> api_error = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] virtual auto set_item_meta(std::string_view api_path,
 | 
					  [[nodiscard]] virtual auto set_item_meta(const std::string &api_path,
 | 
				
			||||||
                                           const api_meta_map &meta)
 | 
					                                           const api_meta_map &meta)
 | 
				
			||||||
      -> api_error = 0;
 | 
					      -> api_error = 0;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -62,12 +62,13 @@ private:
 | 
				
			|||||||
      std::function<rocksdb::Status(rocksdb::Transaction *txn)> action)
 | 
					      std::function<rocksdb::Status(rocksdb::Transaction *txn)> action)
 | 
				
			||||||
      -> api_error;
 | 
					      -> api_error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto remove_item(std::string_view api_path,
 | 
					  [[nodiscard]] auto remove_item(const std::string &api_path,
 | 
				
			||||||
                                 std::string_view source_path,
 | 
					                                 const std::string &source_path,
 | 
				
			||||||
                                 rocksdb::Transaction *txn) -> rocksdb::Status;
 | 
					                                 rocksdb::Transaction *txn) -> rocksdb::Status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  [[nodiscard]] auto add_or_update_directory(const directory_data &data)
 | 
					  [[nodiscard]] auto add_directory(const std::string &api_path,
 | 
				
			||||||
 | 
					                                   const std::string &source_path)
 | 
				
			||||||
      -> api_error override;
 | 
					      -> api_error override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto add_or_update_file(const i_file_db::file_data &data)
 | 
					  [[nodiscard]] auto add_or_update_file(const i_file_db::file_data &data)
 | 
				
			||||||
@@ -81,42 +82,38 @@ public:
 | 
				
			|||||||
      std::function<void(const std::vector<i_file_db::file_info> &)> callback,
 | 
					      std::function<void(const std::vector<i_file_db::file_info> &)> callback,
 | 
				
			||||||
      stop_type_callback stop_requested_cb) const override;
 | 
					      stop_type_callback stop_requested_cb) const override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto get_api_path(std::string_view source_path,
 | 
					  [[nodiscard]] auto get_api_path(const std::string &source_path,
 | 
				
			||||||
                                  std::string &api_path) const
 | 
					                                  std::string &api_path) const
 | 
				
			||||||
      -> api_error override;
 | 
					      -> api_error override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto get_directory_api_path(std::string_view source_path,
 | 
					  [[nodiscard]] auto get_directory_api_path(const std::string &source_path,
 | 
				
			||||||
                                            std::string &api_path) const
 | 
					                                            std::string &api_path) const
 | 
				
			||||||
      -> api_error override;
 | 
					      -> api_error override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto get_directory_data(std::string_view api_path,
 | 
					  [[nodiscard]] auto get_directory_source_path(const std::string &api_path,
 | 
				
			||||||
                                        i_file_db::directory_data &data) const
 | 
					 | 
				
			||||||
      -> api_error override;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  [[nodiscard]] auto get_directory_source_path(std::string_view api_path,
 | 
					 | 
				
			||||||
                                               std::string &source_path) const
 | 
					                                               std::string &source_path) const
 | 
				
			||||||
      -> api_error override;
 | 
					      -> api_error override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto get_file_api_path(std::string_view source_path,
 | 
					  [[nodiscard]] auto get_file_api_path(const std::string &source_path,
 | 
				
			||||||
                                       std::string &api_path) const
 | 
					                                       std::string &api_path) const
 | 
				
			||||||
      -> api_error override;
 | 
					      -> api_error override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto get_file_data(std::string_view api_path,
 | 
					  [[nodiscard]] auto get_file_data(const std::string &api_path,
 | 
				
			||||||
                                   i_file_db::file_data &data) const
 | 
					                                   i_file_db::file_data &data) const
 | 
				
			||||||
      -> api_error override;
 | 
					      -> api_error override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto get_file_source_path(std::string_view api_path,
 | 
					  [[nodiscard]] auto get_file_source_path(const std::string &api_path,
 | 
				
			||||||
                                          std::string &source_path) const
 | 
					                                          std::string &source_path) const
 | 
				
			||||||
      -> api_error override;
 | 
					      -> api_error override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto get_item_list(stop_type_callback stop_requested_cb) const
 | 
					  [[nodiscard]] auto get_item_list(stop_type_callback stop_requested_cb) const
 | 
				
			||||||
      -> std::vector<i_file_db::file_info> override;
 | 
					      -> std::vector<i_file_db::file_info> override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto get_source_path(std::string_view api_path,
 | 
					  [[nodiscard]] auto get_source_path(const std::string &api_path,
 | 
				
			||||||
                                     std::string &source_path) const
 | 
					                                     std::string &source_path) const
 | 
				
			||||||
      -> api_error override;
 | 
					      -> api_error override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto remove_item(std::string_view api_path)
 | 
					  [[nodiscard]] auto remove_item(const std::string &api_path)
 | 
				
			||||||
      -> api_error override;
 | 
					      -> api_error override;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
} // namespace repertory
 | 
					} // namespace repertory
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -61,7 +61,7 @@ private:
 | 
				
			|||||||
      std::string_view function_name,
 | 
					      std::string_view function_name,
 | 
				
			||||||
      std::function<rocksdb::Status(rocksdb::Transaction *txn)> action) -> bool;
 | 
					      std::function<rocksdb::Status(rocksdb::Transaction *txn)> action) -> bool;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto remove_resume(std::string_view api_path,
 | 
					  [[nodiscard]] auto remove_resume(const std::string &api_path,
 | 
				
			||||||
                                   rocksdb::Transaction *txn)
 | 
					                                   rocksdb::Transaction *txn)
 | 
				
			||||||
      -> rocksdb::Status;
 | 
					      -> rocksdb::Status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -84,21 +84,23 @@ public:
 | 
				
			|||||||
  [[nodiscard]] auto get_resume_list() const
 | 
					  [[nodiscard]] auto get_resume_list() const
 | 
				
			||||||
      -> std::vector<resume_entry> override;
 | 
					      -> std::vector<resume_entry> override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto get_upload(std::string_view api_path) const
 | 
					  [[nodiscard]] auto get_upload(const std::string &api_path) const
 | 
				
			||||||
      -> std::optional<upload_entry> override;
 | 
					      -> std::optional<upload_entry> override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto get_upload_active_list() const
 | 
					  [[nodiscard]] auto get_upload_active_list() const
 | 
				
			||||||
      -> std::vector<upload_active_entry> override;
 | 
					      -> std::vector<upload_active_entry> override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto remove_resume(std::string_view api_path) -> bool override;
 | 
					  [[nodiscard]] auto remove_resume(const std::string &api_path)
 | 
				
			||||||
 | 
					 | 
				
			||||||
  [[nodiscard]] auto remove_upload(std::string_view api_path) -> bool override;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  [[nodiscard]] auto remove_upload_active(std::string_view api_path)
 | 
					 | 
				
			||||||
      -> bool override;
 | 
					      -> bool override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto rename_resume(std::string_view from_api_path,
 | 
					  [[nodiscard]] auto remove_upload(const std::string &api_path)
 | 
				
			||||||
                                   std::string_view to_api_path)
 | 
					      -> bool override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [[nodiscard]] auto remove_upload_active(const std::string &api_path)
 | 
				
			||||||
 | 
					      -> bool override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [[nodiscard]] auto rename_resume(const std::string &from_api_path,
 | 
				
			||||||
 | 
					                                   const std::string &to_api_path)
 | 
				
			||||||
      -> bool override;
 | 
					      -> bool override;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -54,7 +54,7 @@ private:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  void create_or_open(bool clear);
 | 
					  void create_or_open(bool clear);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto get_item_meta_json(std::string_view api_path,
 | 
					  [[nodiscard]] auto get_item_meta_json(const std::string &api_path,
 | 
				
			||||||
                                        json &json_data) const -> api_error;
 | 
					                                        json &json_data) const -> api_error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] static auto
 | 
					  [[nodiscard]] static auto
 | 
				
			||||||
@@ -66,12 +66,13 @@ private:
 | 
				
			|||||||
      std::function<rocksdb::Status(rocksdb::Transaction *txn)> action)
 | 
					      std::function<rocksdb::Status(rocksdb::Transaction *txn)> action)
 | 
				
			||||||
      -> api_error;
 | 
					      -> api_error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto remove_api_path(std::string_view api_path,
 | 
					  [[nodiscard]] auto remove_api_path(const std::string &api_path,
 | 
				
			||||||
                                     std::string_view source_path,
 | 
					                                     const std::string &source_path,
 | 
				
			||||||
                                     rocksdb::Transaction *txn)
 | 
					                                     rocksdb::Transaction *txn)
 | 
				
			||||||
      -> rocksdb::Status;
 | 
					      -> rocksdb::Status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto update_item_meta(std::string_view api_path, json json_data,
 | 
					  [[nodiscard]] auto update_item_meta(const std::string &api_path,
 | 
				
			||||||
 | 
					                                      json json_data,
 | 
				
			||||||
                                      rocksdb::Transaction *base_txn = nullptr,
 | 
					                                      rocksdb::Transaction *base_txn = nullptr,
 | 
				
			||||||
                                      rocksdb::Status *status = nullptr)
 | 
					                                      rocksdb::Status *status = nullptr)
 | 
				
			||||||
      -> api_error;
 | 
					      -> api_error;
 | 
				
			||||||
@@ -83,19 +84,19 @@ public:
 | 
				
			|||||||
      std::function<void(const std::vector<std::string> &)> callback,
 | 
					      std::function<void(const std::vector<std::string> &)> callback,
 | 
				
			||||||
      stop_type_callback stop_requested_cb) const override;
 | 
					      stop_type_callback stop_requested_cb) const override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto get_api_path(std::string_view source_path,
 | 
					  [[nodiscard]] auto get_api_path(const std::string &source_path,
 | 
				
			||||||
                                  std::string &api_path) const
 | 
					                                  std::string &api_path) const
 | 
				
			||||||
      -> api_error override;
 | 
					      -> api_error override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto get_api_path_list() const
 | 
					  [[nodiscard]] auto get_api_path_list() const
 | 
				
			||||||
      -> std::vector<std::string> override;
 | 
					      -> std::vector<std::string> override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto get_item_meta(std::string_view api_path,
 | 
					  [[nodiscard]] auto get_item_meta(const std::string &api_path,
 | 
				
			||||||
                                   api_meta_map &meta) const
 | 
					                                   api_meta_map &meta) const
 | 
				
			||||||
      -> api_error override;
 | 
					      -> api_error override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto get_item_meta(std::string_view api_path,
 | 
					  [[nodiscard]] auto get_item_meta(const std::string &api_path,
 | 
				
			||||||
                                   std::string_view key,
 | 
					                                   const std::string &key,
 | 
				
			||||||
                                   std::string &value) const
 | 
					                                   std::string &value) const
 | 
				
			||||||
      -> api_error override;
 | 
					      -> api_error override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -106,21 +107,22 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto get_total_size() const -> std::uint64_t override;
 | 
					  [[nodiscard]] auto get_total_size() const -> std::uint64_t override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void remove_api_path(std::string_view api_path) override;
 | 
					  void remove_api_path(const std::string &api_path) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto remove_item_meta(std::string_view api_path,
 | 
					  [[nodiscard]] auto remove_item_meta(const std::string &api_path,
 | 
				
			||||||
                                      std::string_view key)
 | 
					                                      const std::string &key)
 | 
				
			||||||
      -> api_error override;
 | 
					      -> api_error override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto rename_item_meta(std::string_view from_api_path,
 | 
					  [[nodiscard]] auto rename_item_meta(const std::string &from_api_path,
 | 
				
			||||||
                                      std::string_view to_api_path)
 | 
					                                      const std::string &to_api_path)
 | 
				
			||||||
      -> api_error override;
 | 
					      -> api_error override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto set_item_meta(std::string_view api_path,
 | 
					  [[nodiscard]] auto set_item_meta(const std::string &api_path,
 | 
				
			||||||
                                   std::string_view key, std::string_view value)
 | 
					                                   const std::string &key,
 | 
				
			||||||
 | 
					                                   const std::string &value)
 | 
				
			||||||
      -> api_error override;
 | 
					      -> api_error override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto set_item_meta(std::string_view api_path,
 | 
					  [[nodiscard]] auto set_item_meta(const std::string &api_path,
 | 
				
			||||||
                                   const api_meta_map &meta)
 | 
					                                   const api_meta_map &meta)
 | 
				
			||||||
      -> api_error override;
 | 
					      -> api_error override;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -42,8 +42,8 @@ private:
 | 
				
			|||||||
  utils::db::sqlite::db3_t db_;
 | 
					  utils::db::sqlite::db3_t db_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  [[nodiscard]] auto
 | 
					  [[nodiscard]] auto add_directory(const std::string &api_path,
 | 
				
			||||||
  add_or_update_directory(const i_file_db::directory_data &data)
 | 
					                                   const std::string &source_path)
 | 
				
			||||||
      -> api_error override;
 | 
					      -> api_error override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto add_or_update_file(const i_file_db::file_data &data)
 | 
					  [[nodiscard]] auto add_or_update_file(const i_file_db::file_data &data)
 | 
				
			||||||
@@ -57,42 +57,38 @@ public:
 | 
				
			|||||||
      std::function<void(const std::vector<i_file_db::file_info> &)> callback,
 | 
					      std::function<void(const std::vector<i_file_db::file_info> &)> callback,
 | 
				
			||||||
      stop_type_callback stop_requested_cb) const override;
 | 
					      stop_type_callback stop_requested_cb) const override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto get_api_path(std::string_view source_path,
 | 
					  [[nodiscard]] auto get_api_path(const std::string &source_path,
 | 
				
			||||||
                                  std::string &api_path) const
 | 
					                                  std::string &api_path) const
 | 
				
			||||||
      -> api_error override;
 | 
					      -> api_error override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto get_directory_api_path(std::string_view source_path,
 | 
					  [[nodiscard]] auto get_directory_api_path(const std::string &source_path,
 | 
				
			||||||
                                            std::string &api_path) const
 | 
					                                            std::string &api_path) const
 | 
				
			||||||
      -> api_error override;
 | 
					      -> api_error override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto get_directory_data(std::string_view api_path,
 | 
					  [[nodiscard]] auto get_directory_source_path(const std::string &api_path,
 | 
				
			||||||
                                        i_file_db::directory_data &data) const
 | 
					 | 
				
			||||||
      -> api_error override;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  [[nodiscard]] auto get_directory_source_path(std::string_view api_path,
 | 
					 | 
				
			||||||
                                               std::string &source_path) const
 | 
					                                               std::string &source_path) const
 | 
				
			||||||
      -> api_error override;
 | 
					      -> api_error override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto get_file_api_path(std::string_view source_path,
 | 
					  [[nodiscard]] auto get_file_api_path(const std::string &source_path,
 | 
				
			||||||
                                       std::string &api_path) const
 | 
					                                       std::string &api_path) const
 | 
				
			||||||
      -> api_error override;
 | 
					      -> api_error override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto get_file_data(std::string_view api_path,
 | 
					  [[nodiscard]] auto get_file_data(const std::string &api_path,
 | 
				
			||||||
                                   i_file_db::file_data &data) const
 | 
					                                   i_file_db::file_data &data) const
 | 
				
			||||||
      -> api_error override;
 | 
					      -> api_error override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto get_file_source_path(std::string_view api_path,
 | 
					  [[nodiscard]] auto get_file_source_path(const std::string &api_path,
 | 
				
			||||||
                                          std::string &source_path) const
 | 
					                                          std::string &source_path) const
 | 
				
			||||||
      -> api_error override;
 | 
					      -> api_error override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto get_item_list(stop_type_callback stop_requested_cb) const
 | 
					  [[nodiscard]] auto get_item_list(stop_type_callback stop_requested_cb) const
 | 
				
			||||||
      -> std::vector<i_file_db::file_info> override;
 | 
					      -> std::vector<i_file_db::file_info> override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto get_source_path(std::string_view api_path,
 | 
					  [[nodiscard]] auto get_source_path(const std::string &api_path,
 | 
				
			||||||
                                     std::string &source_path) const
 | 
					                                     std::string &source_path) const
 | 
				
			||||||
      -> api_error override;
 | 
					      -> api_error override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [[nodiscard]] auto remove_item(std::string_view api_path)
 | 
					  [[nodiscard]] auto remove_item(const std::string &api_path)
 | 
				
			||||||
      -> api_error override;
 | 
					      -> api_error override;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
} // namespace repertory
 | 
					} // namespace repertory
 | 
				
			||||||
 
 | 
				
			|||||||