quick_file_transfer/
run.rs

1use anyhow::bail;
2
3use crate::config::{Command, Config};
4
5pub fn run(_cfg: &Config) -> anyhow::Result<()> {
6    if let Some(ref cmd) = _cfg.command {
7        match cmd {
8            Command::Listen(ref args) => crate::server::listen(_cfg, args),
9            Command::Send(ref cmd) => crate::send::handle_send_cmd(cmd, _cfg),
10            Command::GetFreePort(ref a) => crate::get_free_port::handle_get_free_port(a),
11
12            #[cfg(feature = "mdns")]
13            Command::Mdns(ref cmd) => crate::mdns::handle_mdns_command(&cmd.subcmd),
14
15            #[cfg(feature = "evaluate-compression")]
16            Command::EvaluateCompression(ref args) => {
17                crate::evaluate_compression::evaluate_compression(args.clone())
18            }
19
20            #[cfg(feature = "ssh")]
21            Command::Ssh(ref args) => {
22                use crate::{
23                    config::{
24                        ssh::parse_scp_style_uri,
25                        transfer::util::{PollAbortCondition, TcpConnectMode},
26                    },
27                    ssh::remote_info::RemoteInfo,
28                };
29                use std::{path::PathBuf, time::Duration};
30
31                // Determine if the operation is local to remote or remote to local
32                let is_local_to_remote = args.is_sending();
33                let is_remote_to_local = !args.is_sending();
34
35                let remote_uri_components = if is_local_to_remote {
36                    parse_scp_style_uri(&args.destination)
37                } else {
38                    parse_scp_style_uri(args.sources.first().unwrap())
39                }?;
40                tracing::trace!("URI: {remote_uri_components:?}");
41
42                tracing::trace!("Sources: {:?}", args.sources);
43                tracing::trace!("Destination: {}", args.destination);
44                //println!("Recursive: {}", args.recursive);
45                //println!("Preserve Times: {}", args.preserve_times);
46                //println!("Verbose: {}", args.verbose);
47                tracing::trace!(
48                    "Operation: {}",
49                    if is_remote_to_local {
50                        "Remote to Local"
51                    } else {
52                        "Local to Remote"
53                    }
54                );
55
56                let input_files: Vec<PathBuf> = args
57                    .sources
58                    .clone()
59                    .into_iter()
60                    .map(PathBuf::from)
61                    .collect();
62
63                let remote_info = RemoteInfo::from_args(args, &remote_uri_components);
64
65                crate::ssh::run_ssh(
66                    _cfg,
67                    &remote_info,
68                    args.ssh_private_key_path.as_deref(),
69                    args.ssh_key_dir.as_deref(),
70                    args.tcp_port,
71                    args.mmap,
72                    &input_files,
73                    true,
74                    &args.compression,
75                    args.start_port,
76                    args.end_port,
77                    args.ssh_timeout_ms,
78                    TcpConnectMode::poll_from_ms(
79                        20_u8,
80                        PollAbortCondition::Timeout(Duration::from_secs(10)),
81                    ),
82                )?;
83
84                Ok(())
85            }
86        }
87    } else {
88        bail!("No subcommand specified")
89    }
90}