1use serde::{Deserialize, Serialize};
2use std::os::unix::fs::MetadataExt;
3use std::os::unix::prelude::PermissionsExt;
4
5#[derive(Debug, Deserialize, Serialize)]
6pub struct Metadata {
7 pub mode: u32,
8 pub uid: u32,
9 pub gid: u32,
10 pub atime: i64,
11 pub mtime: i64,
12 pub atime_nsec: i64,
13 pub mtime_nsec: i64,
14}
15
16impl common::preserve::Metadata for Metadata {
17 fn uid(&self) -> u32 {
18 self.uid
19 }
20 fn gid(&self) -> u32 {
21 self.gid
22 }
23 fn atime(&self) -> i64 {
24 self.atime
25 }
26 fn atime_nsec(&self) -> i64 {
27 self.atime_nsec
28 }
29 fn mtime(&self) -> i64 {
30 self.mtime
31 }
32 fn mtime_nsec(&self) -> i64 {
33 self.mtime_nsec
34 }
35 fn permissions(&self) -> std::fs::Permissions {
36 std::fs::Permissions::from_mode(self.mode)
37 }
38}
39
40impl common::preserve::Metadata for &Metadata {
41 fn uid(&self) -> u32 {
42 (*self).uid()
43 }
44 fn gid(&self) -> u32 {
45 (*self).gid()
46 }
47 fn atime(&self) -> i64 {
48 (*self).atime()
49 }
50 fn atime_nsec(&self) -> i64 {
51 (*self).atime_nsec()
52 }
53 fn mtime(&self) -> i64 {
54 (*self).mtime()
55 }
56 fn mtime_nsec(&self) -> i64 {
57 (*self).mtime_nsec()
58 }
59 fn permissions(&self) -> std::fs::Permissions {
60 (*self).permissions()
61 }
62}
63
64impl From<&std::fs::Metadata> for Metadata {
65 fn from(metadata: &std::fs::Metadata) -> Self {
66 Metadata {
67 mode: metadata.mode(),
68 uid: metadata.uid(),
69 gid: metadata.gid(),
70 atime: metadata.atime(),
71 mtime: metadata.mtime(),
72 atime_nsec: metadata.atime_nsec(),
73 mtime_nsec: metadata.mtime_nsec(),
74 }
75 }
76}
77
78#[derive(Debug, Deserialize, Serialize)]
80pub struct File {
81 pub src: std::path::PathBuf,
82 pub dst: std::path::PathBuf,
83 pub size: u64,
84 pub metadata: Metadata,
85 pub is_root: bool,
86}
87
88#[derive(Debug)]
90pub struct FileMetadata<'a> {
91 pub metadata: &'a Metadata,
92 pub size: u64,
93}
94
95impl<'a> common::preserve::Metadata for FileMetadata<'a> {
96 fn uid(&self) -> u32 {
97 self.metadata.uid()
98 }
99 fn gid(&self) -> u32 {
100 self.metadata.gid()
101 }
102 fn atime(&self) -> i64 {
103 self.metadata.atime()
104 }
105 fn atime_nsec(&self) -> i64 {
106 self.metadata.atime_nsec()
107 }
108 fn mtime(&self) -> i64 {
109 self.metadata.mtime()
110 }
111 fn mtime_nsec(&self) -> i64 {
112 self.metadata.mtime_nsec()
113 }
114 fn permissions(&self) -> std::fs::Permissions {
115 self.metadata.permissions()
116 }
117 fn size(&self) -> u64 {
118 self.size
119 }
120}
121
122#[derive(Debug, Deserialize, Serialize)]
123pub enum SourceMessage {
124 DirStub {
125 src: std::path::PathBuf,
126 dst: std::path::PathBuf,
127 num_entries: usize,
128 },
129 Directory {
130 src: std::path::PathBuf,
131 dst: std::path::PathBuf,
132 metadata: Metadata,
133 is_root: bool,
134 },
135 DirStructureComplete,
137 Symlink {
138 src: std::path::PathBuf,
139 dst: std::path::PathBuf,
140 target: std::path::PathBuf,
141 metadata: Metadata,
142 is_root: bool,
143 },
144 FileSkipped(SrcDst), SymlinkSkipped(SrcDst), SourceDone, }
148
149#[derive(Clone, Debug, Deserialize, Serialize)]
150pub struct SrcDst {
151 pub src: std::path::PathBuf,
152 pub dst: std::path::PathBuf,
153}
154
155#[derive(Clone, Debug, Deserialize, Serialize)]
156pub enum DestinationMessage {
157 DirectoryCreated(SrcDst),
158 DirectoryComplete(SrcDst),
159 DirectoryFailed(SrcDst), DestinationDone, }
162
163#[derive(Clone, Debug, Deserialize, Serialize)]
164pub struct RcpdConfig {
165 pub verbose: u8,
166 pub fail_early: bool,
167 pub max_workers: usize,
168 pub max_blocking_threads: usize,
169 pub max_open_files: Option<usize>,
170 pub ops_throttle: usize,
171 pub iops_throttle: usize,
172 pub chunk_size: usize,
173 pub dereference: bool,
175 pub overwrite: bool,
176 pub overwrite_compare: String,
177 pub debug_log_prefix: Option<String>,
178 pub quic_port_ranges: Option<String>,
179 pub quic_idle_timeout_sec: u64,
180 pub quic_keep_alive_interval_sec: u64,
181 pub progress: bool,
182 pub progress_delay: Option<String>,
183 pub remote_copy_conn_timeout_sec: u64,
184 pub master_cert_fingerprint: Vec<u8>,
187}
188
189impl RcpdConfig {
190 pub fn to_args(&self) -> Vec<String> {
191 let mut args = vec![
192 format!("--max-workers={}", self.max_workers),
193 format!("--max-blocking-threads={}", self.max_blocking_threads),
194 format!("--ops-throttle={}", self.ops_throttle),
195 format!("--iops-throttle={}", self.iops_throttle),
196 format!("--chunk-size={}", self.chunk_size),
197 format!("--overwrite-compare={}", self.overwrite_compare),
198 ];
199 if self.verbose > 0 {
200 args.push(format!("-{}", "v".repeat(self.verbose as usize)));
201 }
202 if self.fail_early {
203 args.push("--fail-early".to_string());
204 }
205 if let Some(v) = self.max_open_files {
206 args.push(format!("--max-open-files={v}"));
207 }
208 if self.dereference {
209 args.push("--dereference".to_string());
210 }
211 if self.overwrite {
212 args.push("--overwrite".to_string());
213 }
214 if let Some(ref prefix) = self.debug_log_prefix {
215 args.push(format!("--debug-log-prefix={prefix}"));
216 }
217 if let Some(ref ranges) = self.quic_port_ranges {
218 args.push(format!("--quic-port-ranges={ranges}"));
219 }
220 args.push(format!(
221 "--quic-idle-timeout-sec={}",
222 self.quic_idle_timeout_sec
223 ));
224 args.push(format!(
225 "--quic-keep-alive-interval-sec={}",
226 self.quic_keep_alive_interval_sec
227 ));
228 if self.progress {
229 args.push("--progress".to_string());
230 }
231 if let Some(ref delay) = self.progress_delay {
232 args.push(format!("--progress-delay={delay}"));
233 }
234 args.push(format!(
235 "--remote-copy-conn-timeout-sec={}",
236 self.remote_copy_conn_timeout_sec
237 ));
238 args.push(format!(
240 "--master-cert-fingerprint={}",
241 hex::encode(&self.master_cert_fingerprint)
242 ));
243 args
244 }
245}
246
247#[derive(Clone, Debug, Deserialize, Serialize)]
248pub struct TracingHello {}
249
250#[derive(Clone, Debug, Deserialize, Serialize)]
251pub enum MasterHello {
252 Source {
253 src: std::path::PathBuf,
254 dst: std::path::PathBuf,
255 },
256 Destination {
257 source_addr: std::net::SocketAddr,
258 server_name: String,
259 source_cert_fingerprint: Vec<u8>,
262 preserve: common::preserve::Settings,
263 },
264}
265
266#[derive(Clone, Debug, Deserialize, Serialize)]
267pub struct SourceMasterHello {
268 pub source_addr: std::net::SocketAddr,
269 pub server_name: String,
270 pub cert_fingerprint: Vec<u8>,
273}
274
275#[derive(Clone, Debug, Deserialize, Serialize)]
276pub enum RcpdResult {
277 Success {
278 message: String,
279 summary: common::copy::Summary,
280 },
281 Failure {
282 error: String,
283 summary: common::copy::Summary,
284 },
285}