quick_file_transfer/config/
ssh.rs1use std::path::PathBuf;
2
3use anyhow::bail;
4use clap::{arg, ArgAction, Args};
5
6use super::Compression;
7
8#[derive(Debug, Args)]
9#[command(flatten_help = true)]
10#[cfg(feature = "ssh")]
11pub struct SendSshArgs {
12 #[arg(required(true),
14 value_hint = clap::ValueHint::AnyPath)]
15 pub sources: Vec<String>,
16
17 #[arg(required(true))]
19 pub destination: String,
20
21 #[arg(long)]
23 pub tcp_port: Option<u16>,
24
25 #[arg(long, default_value_t = 5000)]
27 pub mdns_resolve_timeout_ms: u64,
28
29 #[arg(long, default_value_t = 10000)]
31 pub ssh_timeout_ms: u64,
32
33 #[cfg(feature = "mdns")]
35 #[arg(long, default_value_t = crate::config::misc::IpVersion::V4)]
36 pub ip_version: crate::config::misc::IpVersion,
37
38 #[arg(short('p'), long, default_value_t = 22)]
40 pub ssh_port: u16,
41
42 #[command(subcommand)]
44 pub compression: Option<Compression>,
45
46 #[arg(long, env(crate::ssh::ENV_SSH_PRIVATE_KEY))]
48 pub ssh_private_key_path: Option<PathBuf>,
49
50 #[arg(long, env(crate::ssh::ENV_SSH_KEY_DIR))]
52 pub ssh_key_dir: Option<PathBuf>,
53
54 #[arg(short, long, default_value_t = 49152)]
56 pub start_port: u16,
57
58 #[arg(short, long, requires("start_port"), default_value_t = u16::MAX)]
60 pub end_port: u16,
61
62 #[arg(long, action = ArgAction::SetTrue, global(true))]
64 pub mmap: bool,
65}
66
67#[derive(Debug, Clone)]
69pub struct TargetComponents {
70 pub user: String,
71 pub host: String,
72 pub destination: PathBuf,
73}
74
75pub fn parse_scp_style_uri(input: &str) -> anyhow::Result<TargetComponents> {
76 let parts: Vec<&str> = input.split('@').collect();
77 if parts.len() != 2 {
78 bail!("Invalid SSH argument format: {input}")
79 }
80 let user = parts[0].to_string();
81 let host_and_dest: Vec<&str> = parts[1].split(':').collect();
82 if host_and_dest.len() != 2 {
83 bail!("Invalid SSH argument format: {input}")
84 }
85 let host = host_and_dest[0].to_string();
86 let destination = PathBuf::from(host_and_dest[1]);
87
88 Ok(TargetComponents {
89 user,
90 host,
91 destination,
92 })
93}
94
95impl SendSshArgs {
96 pub fn is_sending(&self) -> bool {
98 self.destination.contains('@')
100 }
101}