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 progress: bool,
180 pub progress_delay: Option<String>,
181 pub remote_copy_conn_timeout_sec: u64,
182 pub master_cert_fingerprint: Vec<u8>,
185}
186
187impl RcpdConfig {
188 pub fn to_args(&self) -> Vec<String> {
189 let mut args = vec![
190 format!("--max-workers={}", self.max_workers),
191 format!("--max-blocking-threads={}", self.max_blocking_threads),
192 format!("--ops-throttle={}", self.ops_throttle),
193 format!("--iops-throttle={}", self.iops_throttle),
194 format!("--chunk-size={}", self.chunk_size),
195 format!("--overwrite-compare={}", self.overwrite_compare),
196 ];
197 if self.verbose > 0 {
198 args.push(format!("-{}", "v".repeat(self.verbose as usize)));
199 }
200 if self.fail_early {
201 args.push("--fail-early".to_string());
202 }
203 if let Some(v) = self.max_open_files {
204 args.push(format!("--max-open-files={v}"));
205 }
206 if self.dereference {
207 args.push("--dereference".to_string());
208 }
209 if self.overwrite {
210 args.push("--overwrite".to_string());
211 }
212 if let Some(ref prefix) = self.debug_log_prefix {
213 args.push(format!("--debug-log-prefix={prefix}"));
214 }
215 if let Some(ref ranges) = self.quic_port_ranges {
216 args.push(format!("--quic-port-ranges={ranges}"));
217 }
218 if self.progress {
219 args.push("--progress".to_string());
220 }
221 if let Some(ref delay) = self.progress_delay {
222 args.push(format!("--progress-delay={delay}"));
223 }
224 args.push(format!(
225 "--remote-copy-conn-timeout-sec={}",
226 self.remote_copy_conn_timeout_sec
227 ));
228 args.push(format!(
230 "--master-cert-fingerprint={}",
231 hex::encode(&self.master_cert_fingerprint)
232 ));
233 args
234 }
235}
236
237#[derive(Clone, Debug, Deserialize, Serialize)]
238pub struct TracingHello {}
239
240#[derive(Clone, Debug, Deserialize, Serialize)]
241pub enum MasterHello {
242 Source {
243 src: std::path::PathBuf,
244 dst: std::path::PathBuf,
245 },
246 Destination {
247 source_addr: std::net::SocketAddr,
248 server_name: String,
249 source_cert_fingerprint: Vec<u8>,
252 preserve: common::preserve::Settings,
253 },
254}
255
256#[derive(Clone, Debug, Deserialize, Serialize)]
257pub struct SourceMasterHello {
258 pub source_addr: std::net::SocketAddr,
259 pub server_name: String,
260 pub cert_fingerprint: Vec<u8>,
263}
264
265#[derive(Clone, Debug, Deserialize, Serialize)]
266pub enum RcpdResult {
267 Success {
268 message: String,
269 summary: common::copy::Summary,
270 },
271 Failure {
272 error: String,
273 summary: common::copy::Summary,
274 },
275}