aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/client.rs16
-rw-r--r--src/common.rs16
-rw-r--r--src/main.rs95
-rw-r--r--src/server.rs86
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);
+ }
+}