1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
// XXX: re-enable these warnings
#![allow(unused_imports, unused_variables, unused_mut)]
#[macro_use] extern crate log;
extern crate env_logger;
extern crate getopts;
extern crate udt;
extern crate sodiumoxide;
extern crate rustc_serialize;
mod client;
mod server;
mod common;
mod udt_extras;
mod crypto;
use std::io::Write;
use std::str;
use std::env;
use std::process::exit;
use getopts::Options;
use udt::{UdtSocket};
fn usage(opts: Options) {
let brief = "usage:\tucp [-h] [-v] [[user@]host1:]srcfile [[user@]host2:]destfile";
print!("{}", opts.usage(&brief));
}
fn main() {
let args: Vec<String> = env::args().collect();
sodiumoxide::init();
// First check for "hidden" server and client modes
if args.len() > 1 && args[1] == "server" {
server::main_server();
return;
} else if args.len() > 1 && args[1] == "client" {
client::main_client();
return;
}
let mut opts = Options::new();
opts.optflag("h", "help", "print this help menu");
opts.optflag("v", "verbose", "more debugging messages");
opts.optflag("r", "recursive", "whether to recursively transfer files (directory)");
opts.optflag("", "no-crypto", "sends data in the clear (no crypto or verification)");
let matches = match opts.parse(&args[1..]) {
Ok(m) => { m }
Err(f) => { println!("{}", f.to_string()); usage(opts); exit(-1); }
};
let verbose: bool = matches.opt_present("v");
let recursive: bool = matches.opt_present("r");
let no_crypto: bool = matches.opt_present("no-crypto");
if matches.opt_present("h") {
usage(opts);
return;
}
if matches.free.len() != 2 {
println!("Expected a single source and single destination");
println!("");
usage(opts);
return;
}
let srcfile = matches.free[0].clone();
let destfile = matches.free[1].clone();
for fname in vec![&srcfile, &destfile] {
if fname.match_indices(":").count() > 2 {
println!("Invalid host/file identifier: {}", fname);
exit(-1);
}
}
let mut ret: Result<(), String>;
match (srcfile.contains(":"), destfile.contains(":")) {
(true, true) => { println!("Can't have src and dest both be remote!"); exit(-1); },
(false, false) => { println!("One of src or dest should be remote!"); exit(-1); },
(true , false) => {
let is_recv = true;
let local_file = &destfile;
let spl: Vec<&str> = srcfile.split(":").collect();
let host = spl[0];
let remote_file = spl[1];
ret = client::run_client(host, local_file, remote_file, recursive, is_recv, no_crypto, verbose);
},
(false, true) => {
let is_recv = false;
let local_file = &srcfile;
let spl: Vec<&str> = destfile.split(":").collect();
let host = spl[0];
let remote_file = spl[1];
ret = client::run_client(host, local_file, remote_file, recursive, is_recv, no_crypto, verbose);
},
}
match ret {
Ok(_) => { exit(0); },
Err(msg) => {
writeln!(&mut ::std::io::stderr(), "{}", msg).unwrap();
exit(-1);
}
}
}
|