aboutsummaryrefslogtreecommitdiffstats
path: root/src/main.rs
blob: 6d9a395f3951836015275a5f663717819b83636e (plain)
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142

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 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";
    print!("{}", opts.usage(&brief));
}

fn main() {

    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("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");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => { m }
        Err(f) => { println!("Error parsing args!"); usage(&prog_name, opts); exit(-1); }
    };

    let verbose: bool = matches.opt_present("v");

    if matches.opt_present("h") {
        usage(&prog_name, opts);
        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!("");
        usage(&prog_name, 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);
        }
    }


    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 , 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];
            println!("host: {}", host);
            },
        (false, true)   => {
            let is_recv = false;
            let remote_file = srcfile;
            let spl: Vec<&str> = destfile.split(":").collect();
            let host = spl[0];
            let local_file = spl[1];
            println!("host: {}", host);
            },
    }
}