diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/client.rs | 16 | ||||
-rw-r--r-- | src/common.rs | 16 | ||||
-rw-r--r-- | src/main.rs | 95 | ||||
-rw-r--r-- | src/server.rs | 86 |
4 files changed, 137 insertions, 76 deletions
diff --git a/src/client.rs b/src/client.rs new file mode 100644 index 0000000..75329f3 --- /dev/null +++ b/src/client.rs @@ -0,0 +1,16 @@ + +extern crate utp; + +use std::str; +use std::env; +use std::process::exit; +use getopts::Options; +use utp::{UtpSocket, UtpListener}; + +pub fn run_client(host: &str, local_file: &str, remote_file: &str, is_recv: bool) { + println!("host: {}", host); + println!("local_file: {}", local_file); + println!("remote_file: {}", remote_file); + println!("is_recv: {}", is_recv); +} + diff --git a/src/common.rs b/src/common.rs new file mode 100644 index 0000000..5830ab6 --- /dev/null +++ b/src/common.rs @@ -0,0 +1,16 @@ + +extern crate utp; + +use std::str; +use std::env; +use std::process::exit; +use utp::{UtpSocket, UtpListener}; + + +fn send_files(socket: UtpSocket, file_path: &str, recursive: bool) { + unimplemented!(); +} + +fn receive_files(socket: UtpSocket, file_path: &str) { + unimplemented!(); +} diff --git a/src/main.rs b/src/main.rs index 6d9a395..683c2bf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,61 +2,17 @@ extern crate getopts; extern crate utp; +mod client; +mod server; + use std::str; use std::env; use std::process::exit; use getopts::Options; use utp::{UtpSocket, UtpListener}; - -fn run_server(path: &str, is_receive: bool) { - // Connect to an hypothetical local server running on port 3540 - let addr = "127.0.0.1:3540"; - // Accept connection from anybody - let listener = UtpListener::bind(addr).expect("Error binding to local port"); - - for connection in listener.incoming() { - - let (mut socket, _src) = connection.unwrap(); - println!("Got connection from {}", socket.peer_addr().unwrap()); - - loop { - - let mut buf = [0; 1000]; - let (amt, _src) = socket.recv_from(&mut buf).ok().unwrap(); - if amt <= 0 { - break; - } - let buf = &buf[..amt]; - let s = str::from_utf8(buf).unwrap(); - println!("\tgot: {}", s); - - } - } -} - -fn run_client(path: &str, is_receive: bool) { - // Bind to port 3540 - let addr = "127.0.0.1:3540"; - let mut socket = UtpSocket::connect(addr).expect("Error connecting to remote peer"); - - // Send a string - socket.send_to("Hi there!".as_bytes()).expect("Write failed"); - - // Close the socket - socket.close().expect("Error closing connection"); -} - -fn send_files(socket: UtpSocket, file_path: &str, recursive: bool) { - unimplemented!(); -} - -fn receive_files(socket: UtpSocket, file_path: &str) { - unimplemented!(); -} - -fn usage(program: &str, opts: Options) { - let brief = "usage:\tucp [-h] [-v] [[user@]host1:]srcfile [[user@]host2:]destfile"; +fn usage(prog_name: &str, opts: Options) { + let brief = format!("usage:\t{} [-h] [-v] [[user@]host1:]srcfile [[user@]host2:]destfile", prog_name); print!("{}", opts.usage(&brief)); } @@ -65,14 +21,16 @@ fn main() { let args: Vec<String> = env::args().collect(); let prog_name = args[0].clone(); + // First check for "hidden" server mode + if args.len() > 1 && args[1] == "server" { + server::main_server(); + 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"); - opts.optopt("f", "", "file or dir to read from (server side)", "FILE"); - opts.optopt("t", "", "file or dir to write to (server side)", "FILE"); - opts.optopt("d", "", "read/write a dir instead of file (server side)", "FILE"); - opts.optopt("l", "", "", "FILE"); + opts.optflag("r", "recursive", "whether to recursively transfer files (directory)"); let matches = match opts.parse(&args[1..]) { Ok(m) => { m } @@ -86,22 +44,6 @@ fn main() { return; } - // First handle the server-side cases - if matches.opt_present("f") && matches.opt_present("t") { - println!("Can't be both server modes at the same time!"); - exit(-1); - } - - if matches.opt_present("f") { - unimplemented!(); - //serve(&matches.opt_str("f").unwrap(), false); - } - if matches.opt_present("t") { - unimplemented!(); - //serve(&matches.opt_str("t").unwrap(), true); - } - - // Then the user-driven (local) side if matches.free.len() != 2 { println!("Expected a single source and single destination"); println!(""); @@ -115,28 +57,29 @@ fn main() { for fname in vec![&srcfile, &destfile] { if fname.match_indices(":").count() > 2 { println!("Invalid host/file identifier: {}", fname); + exit(-1); } } match (srcfile.contains(":"), destfile.contains(":")) { - (true, true) => { println!("Can't have src and dest both be remote!"); return; }, - (false, false) => { println!("One of src or dest should be remote!"); return; }, + (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 local_file = &destfile; let spl: Vec<&str> = srcfile.split(":").collect(); let host = spl[0]; let remote_file = spl[1]; - println!("host: {}", host); + client::run_client(host, local_file, remote_file, is_recv); }, (false, true) => { let is_recv = false; - let remote_file = srcfile; + let remote_file = &srcfile; let spl: Vec<&str> = destfile.split(":").collect(); let host = spl[0]; let local_file = spl[1]; - println!("host: {}", host); + client::run_client(host, local_file, remote_file, is_recv); }, } } diff --git a/src/server.rs b/src/server.rs new file mode 100644 index 0000000..1cdba76 --- /dev/null +++ b/src/server.rs @@ -0,0 +1,86 @@ + +extern crate getopts; +extern crate utp; + +use std::str; +use std::env; +use std::process::exit; +use getopts::Options; +use utp::{UtpSocket, UtpListener}; + + +fn run_server(path: &str, is_receive: bool) { + + // Connect to an hypothetical local server running on port 3540 + let addr = "127.0.0.1:3540"; + + // Accept connection from anybody + let listener = UtpListener::bind(addr).expect("Error binding to local port"); + + for connection in listener.incoming() { + + let (mut socket, _src) = connection.unwrap(); + println!("Got connection from {}", socket.peer_addr().unwrap()); + + loop { + + let mut buf = [0; 1000]; + let (amt, _src) = socket.recv_from(&mut buf).ok().unwrap(); + if amt <= 0 { + break; + } + let buf = &buf[..amt]; + let s = str::from_utf8(buf).unwrap(); + println!("\tgot: {}", s); + + } + } +} + +fn usage(prog_name: &str, opts: Options) { + let brief = format!("usage:\t{} server ...", prog_name); // XXX: + print!("{}", opts.usage(&brief)); +} + +pub fn main_server() { + + let args: Vec<String> = env::args().collect(); + let prog_name = args[0].clone(); + + let mut opts = Options::new(); + opts.optflag("h", "help", "print this help menu"); + opts.optflag("v", "verbose", "more debugging messages"); + opts.optflag("d", "dir-mode", "read/write a dir instead of file (server side)"); + opts.optopt("f", "from", "file or dir to read from (server side)", "FILE"); + opts.optopt("t", "to", "file or dir to write to (server side)", "FILE"); + + assert!(args.len() >= 2 && args[1] == "server"); + let matches = match opts.parse(&args[2..]) { + Ok(m) => { m } + Err(f) => { println!("Error parsing args!"); usage(&prog_name, opts); exit(-1); } + }; + + if matches.opt_present("h") { + usage(&prog_name, opts); + return; + } + + let verbose: bool = matches.opt_present("v"); + let dir_mode: bool = matches.opt_present("d"); + + match (matches.opt_present("f"), matches.opt_present("t")) { + (true, true) | (false, false) => { + println!("Must be either 'from' or 'to', but not both"); + exit(-1); + }, + _ => {}, + } + + if matches.opt_present("f") { + run_server(&matches.opt_str("f").unwrap(), false); + } + if matches.opt_present("t") { + unimplemented!(); + run_server(&matches.opt_str("t").unwrap(), true); + } +} |