diff options
-rw-r--r-- | src/client.rs | 36 | ||||
-rw-r--r-- | src/common.rs | 6 | ||||
-rw-r--r-- | src/main.rs | 16 | ||||
-rw-r--r-- | src/server.rs | 36 |
4 files changed, 64 insertions, 30 deletions
diff --git a/src/client.rs b/src/client.rs index 4749c51..eb5205a 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1,6 +1,7 @@ use super::common; +use std::io::Write; use std::string::String; use std::str::{self, FromStr}; use std::env; @@ -14,7 +15,7 @@ use udt_extras::{UdtStream}; use crypto::{SecretStream, key2string, string2key, nonce2string, string2nonce}; use sodiumoxide::crypto::secretbox; -pub fn run_client(host: &str, local_file: &str, remote_file: &str, remote_is_dir: bool, is_recv: bool, no_crypto: bool) { +pub fn run_client(host: &str, local_file: &str, remote_file: &str, remote_is_dir: bool, is_recv: bool, no_crypto: bool) -> Result<(), String> { println!("\thost: {}", host); println!("\tlocal_file: {}", local_file); println!("\tremote_file: {}", remote_file); @@ -72,15 +73,15 @@ pub fn run_client(host: &str, local_file: &str, remote_file: &str, remote_is_dir stream.read_nonce = string2nonce(remote_write_nonce).unwrap(); stream.write_nonce = string2nonce(remote_read_nonce).unwrap(); if is_recv { - common::sink_files(&mut stream, local_file, remote_is_dir); + common::sink_files(&mut stream, local_file, remote_is_dir) } else { - common::source_files(&mut stream, local_file, remote_is_dir); + common::source_files(&mut stream, local_file, remote_is_dir) } } else { if is_recv { - common::sink_files(&mut stream, local_file, remote_is_dir); + common::sink_files(&mut stream, local_file, remote_is_dir) } else { - common::source_files(&mut stream, local_file, remote_is_dir); + common::source_files(&mut stream, local_file, remote_is_dir) } } // XXX: does Drop do this well enough? @@ -152,23 +153,34 @@ pub fn main_client() { let mut stream: UdtStream = UdtStream::new(socket); println!("opened socket"); + let mut ret: Result<(), String>; if !no_crypto { let mut stream = SecretStream::new(stream); stream.key = string2key(&matches.opt_str("key").unwrap()).unwrap(); stream.read_nonce = string2nonce(&matches.opt_str("read-nonce").unwrap()).unwrap(); stream.write_nonce = string2nonce(&matches.opt_str("write-nonce").unwrap()).unwrap(); if matches.opt_present("f") { - common::source_files(&mut stream, &matches.opt_str("f").unwrap(), dir_mode); - } - if matches.opt_present("t") { - common::sink_files(&mut stream, &matches.opt_str("t").unwrap(), dir_mode); + ret = common::source_files(&mut stream, &matches.opt_str("f").unwrap(), dir_mode); + } else if matches.opt_present("t") { + ret = common::sink_files(&mut stream, &matches.opt_str("t").unwrap(), dir_mode); + } else { + ret = Err("Didn't Run".to_string()); } } else { if matches.opt_present("f") { - common::source_files(&mut stream, &matches.opt_str("f").unwrap(), dir_mode); + ret = common::source_files(&mut stream, &matches.opt_str("f").unwrap(), dir_mode); + } else if matches.opt_present("t") { + ret = common::sink_files(&mut stream, &matches.opt_str("t").unwrap(), dir_mode); + } else { + ret = Err("Didn't Run".to_string()); } - if matches.opt_present("t") { - common::sink_files(&mut stream, &matches.opt_str("t").unwrap(), dir_mode); + } + + match ret { + Ok(_) => { exit(0); }, + Err(msg) => { + writeln!(&mut ::std::io::stderr(), "{}", msg).unwrap(); + exit(-1); } } diff --git a/src/common.rs b/src/common.rs index bf3910e..77b28ce 100644 --- a/src/common.rs +++ b/src/common.rs @@ -9,7 +9,7 @@ use std::io::{Read, Write, BufRead, BufReader}; use std::process::exit; use std::net; -pub fn source_files<S: Read + Write>(stream: &mut S, file_path: &str, recursive: bool) { +pub fn source_files<S: Read + Write>(stream: &mut S, file_path: &str, recursive: bool) -> Result<(), String> { println!("SOURCE FILE: {}", file_path); if recursive { unimplemented!(); } let mut f = File::open(file_path).unwrap(); @@ -54,6 +54,7 @@ pub fn source_files<S: Read + Write>(stream: &mut S, file_path: &str, recursive: }, _ => { panic!("Unexpected status char!") }, }; + Ok(()) } fn raw_read_line<S: Read + Write>(stream: &mut S) -> io::Result<String> { @@ -72,7 +73,7 @@ fn raw_read_line<S: Read + Write>(stream: &mut S) -> io::Result<String> { // TODO: it would be nice to be able to do BufReader/BufWriter on stream. This would require // implementations of Read and Write on immutable references to stream (a la TcpStream, File, et // al) -pub fn sink_files<S: Read + Write>(stream: &mut S, file_path: &str, recursive: bool) { +pub fn sink_files<S: Read + Write>(stream: &mut S, file_path: &str, recursive: bool) -> Result<(), String> { println!("SINK FILE: {}", file_path); if recursive { unimplemented!(); } let mut f = File::create(file_path).unwrap(); @@ -115,4 +116,5 @@ pub fn sink_files<S: Read + Write>(stream: &mut S, file_path: &str, recursive: b f.sync_all().unwrap(); // f.close(); XXX: closes automatically? stream.write(&[0]).unwrap(); + Ok(()) } diff --git a/src/main.rs b/src/main.rs index 1077034..95e2dd0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,7 +12,7 @@ mod server; mod common; mod udt_extras; mod crypto; - +use std::io::Write; use std::str; use std::env; use std::process::exit; @@ -75,7 +75,7 @@ fn main() { } } - + 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); }, @@ -85,7 +85,7 @@ fn main() { let spl: Vec<&str> = srcfile.split(":").collect(); let host = spl[0]; let remote_file = spl[1]; - client::run_client(host, local_file, remote_file, recursive, is_recv, no_crypto); + ret = client::run_client(host, local_file, remote_file, recursive, is_recv, no_crypto); }, (false, true) => { let is_recv = false; @@ -93,7 +93,15 @@ fn main() { let spl: Vec<&str> = destfile.split(":").collect(); let host = spl[0]; let remote_file = spl[1]; - client::run_client(host, local_file, remote_file, recursive, is_recv, no_crypto); + ret = client::run_client(host, local_file, remote_file, recursive, is_recv, no_crypto); }, } + + match ret { + Ok(_) => { exit(0); }, + Err(msg) => { + writeln!(&mut ::std::io::stderr(), "{}", msg).unwrap(); + exit(-1); + } + } } diff --git a/src/server.rs b/src/server.rs index dee6e62..b749fcb 100644 --- a/src/server.rs +++ b/src/server.rs @@ -3,6 +3,7 @@ extern crate daemonize; use super::common; +use std::io::Write; use std::str::{self, FromStr}; use std::env; use std::net; @@ -43,7 +44,7 @@ pub fn get_local_ip() -> Result<net::IpAddr, String> { } -fn run_server(path: &str, is_recv: bool, recursive: bool, daemonize: bool, no_crypto: bool) { +fn run_server(path: &str, is_recv: bool, recursive: bool, daemonize: bool, no_crypto: bool) -> Result<(), String> { // Connect to an hypothetical local server running on port 61000 let listen_addr = get_local_ip().unwrap(); @@ -56,13 +57,18 @@ fn run_server(path: &str, is_recv: bool, recursive: bool, daemonize: bool, no_cr for port in 61000..62000 { match listener.bind(net::SocketAddr::new(all_addr, port)) { Ok(_) => { break; }, - Err(e) => (), + Err(e) => { + if e.err_code != 1003 { + // Code 1003 is "can't get port", meaning it's taken + return Err(format!("Error binding {}: {}: {}", port, e.err_code, e.err_msg)); + }; + } } } if listener.getstate() != UdtStatus::OPENED { println!("{:?}", listener.getstate()); - println!("Couldn't bind to *any* valid port"); + return Err("Couldn't bind to *any* valid port".to_string()); } listener.listen(1).unwrap(); @@ -118,15 +124,15 @@ fn run_server(path: &str, is_recv: bool, recursive: bool, daemonize: bool, no_cr stream.read_nonce = read_nonce; stream.write_nonce = write_nonce; if is_recv { - common::sink_files(&mut stream, path, recursive); + common::sink_files(&mut stream, path, recursive) } else { - common::source_files(&mut stream, path, recursive); + common::source_files(&mut stream, path, recursive) } } else { if is_recv { - common::sink_files(&mut stream, path, recursive); + common::sink_files(&mut stream, path, recursive) } else { - common::source_files(&mut stream, path, recursive); + common::source_files(&mut stream, path, recursive) } } // XXX: does Drop do this well enough? @@ -177,10 +183,16 @@ pub fn main_server() { _ => {}, } - if matches.opt_present("f") { - run_server(&matches.opt_str("f").unwrap(), false, dir_mode, daemonize, no_crypto); - } - if matches.opt_present("t") { - run_server(&matches.opt_str("t").unwrap(), true, dir_mode, daemonize, no_crypto); + let (file_name, is_recv) = if matches.opt_present("f") { + (matches.opt_str("f").unwrap(), false) + } else { + (matches.opt_str("t").unwrap(), true) + }; + match run_server(&file_name, is_recv, dir_mode, daemonize, no_crypto) { + Ok(_) => { exit(0); }, + Err(msg) => { + writeln!(&mut ::std::io::stderr(), "{}", msg).unwrap(); + exit(-1); + } } } |