aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorbnewbold <bnewbold@robocracy.org>2016-06-02 21:02:11 -0400
committerbnewbold <bnewbold@robocracy.org>2016-06-02 21:02:11 -0400
commit5ca100e6f085bad332df16580e6b292b24e01317 (patch)
tree2b5d09097fabe8ba1c8823ed7003c6a872cf31a6 /src
parent220e7ccb16311a390504a10f42ba1a1290b0630b (diff)
downloaducp-5ca100e6f085bad332df16580e6b292b24e01317.tar.gz
ucp-5ca100e6f085bad332df16580e6b292b24e01317.zip
start cleaning up error conditions
Diffstat (limited to 'src')
-rw-r--r--src/client.rs36
-rw-r--r--src/common.rs6
-rw-r--r--src/main.rs16
-rw-r--r--src/server.rs36
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);
+ }
}
}