diff options
Diffstat (limited to 'src/common.rs')
-rw-r--r-- | src/common.rs | 64 |
1 files changed, 37 insertions, 27 deletions
diff --git a/src/common.rs b/src/common.rs index 9aa477f..facd527 100644 --- a/src/common.rs +++ b/src/common.rs @@ -9,50 +9,54 @@ 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) -> Result<(), String> { +fn fake_io_error(msg: &str) -> io::Result<()> { + Err(io::Error::new(io::ErrorKind::Other, msg)) +} + +pub fn source_files<S: Read + Write>(stream: &mut S, file_path: &str, recursive: bool) -> io::Result<()> { println!("SOURCE FILE: {}", file_path); if recursive { unimplemented!(); } - let mut f = File::open(file_path).unwrap(); - let metadata = f.metadata().unwrap(); + let mut f = try!(File::open(file_path)); + let metadata = try!(f.metadata()); assert!(metadata.is_file()); let fmode: u32 = metadata.permissions().mode(); let flen: usize = metadata.len() as usize; // Format as 4 digits octal, left-padding with zero let line = format!("C{:0>4o} {} {}\n", fmode, flen, file_path); - stream.write_all(line.as_bytes()).unwrap(); + try!(stream.write_all(line.as_bytes())); println!("{}", line); let mut byte_buf = [0; 1]; - stream.read_exact(&mut byte_buf).unwrap(); + try!(stream.read_exact(&mut byte_buf)); let reply = byte_buf[0]; match reply { 0 => {}, // Success, pass 1 | 2 => { // Warning unimplemented!(); }, - _ => { return Err("Unexpected status char!".to_string()); }, + _ => { return fake_io_error("Unexpected status char!"); }, }; let mut buf = [0; 4096]; let mut sent: usize = 0; while sent < flen { - let rlen = f.read(&mut buf).unwrap(); + let rlen = try!(f.read(&mut buf)); assert!(rlen > 0); let mut wbuf = &mut buf[..rlen]; - stream.write_all(&wbuf).unwrap(); + try!(stream.write_all(&wbuf)); sent += rlen; //println!("sent: {}", sent); } // f.close(); XXX: - stream.read_exact(&mut byte_buf).unwrap(); + try!(stream.read_exact(&mut byte_buf)); let reply = byte_buf[0]; match reply { 0 => {}, // Success, pass 1 | 2 => { // Warning unimplemented!(); }, - _ => { return Err("Unexpected status char!".to_string()) }, + _ => { return fake_io_error("Unexpected status char!"); }, }; Ok(()) } @@ -62,7 +66,7 @@ fn raw_read_line<S: Read + Write>(stream: &mut S) -> io::Result<String> { let mut s = String::new(); let mut byte_buf = [0]; loop { - stream.read_exact(&mut byte_buf).unwrap(); + try!(stream.read_exact(&mut byte_buf)); if byte_buf[0] == '\n' as u8 { return Ok(s); } @@ -73,48 +77,54 @@ 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) -> Result<(), String> { - println!("SINK FILE: {}", file_path); +pub fn sink_files<S: Read + Write>(stream: &mut S, file_path: &str, recursive: bool) -> io::Result<()> { + info!("SINK FILE: {}", file_path); if recursive { unimplemented!(); } - let mut f = File::create(file_path).unwrap(); + let mut f = try!(File::create(file_path)); let mut byte_buf = [0; 1]; let mut buf = [0; 4096]; - stream.read_exact(&mut byte_buf).unwrap(); + try!(stream.read_exact(&mut byte_buf)); let msg_type = byte_buf[0]; match msg_type as char { 'C' => { - println!("Going to create!"); + info!("Going to create!"); }, 'D' => { unimplemented!(); }, 'E' => { unimplemented!(); }, 'T' => { unimplemented!(); }, - _ => { return Err(format!("Unexpected message type: {}", msg_type)); }, + _ => { return fake_io_error(&format!("Unexpected message type: {}", msg_type)); }, }; - let line = raw_read_line(stream).unwrap(); + let line = try!(raw_read_line(stream)); println!("got msg: {}", line); - stream.write(&[0]).unwrap(); + try!(stream.write(&[0])); let line: Vec<&str> = line.split_whitespace().collect(); assert!(line.len() == 3); - let fmode: u32 = u32::from_str_radix(line[0], 8).unwrap(); - let flen: usize = line[1].parse::<usize>().unwrap(); + let fmode: u32 = match u32::from_str_radix(line[0], 8) { + Ok(x) => x, + Err(_) => { return fake_io_error("unparsable file mode in ucp 'C' message"); }, + }; + let flen: usize = match line[1].parse::<usize>() { + Ok(x) => x, + Err(_) => { return fake_io_error("unparsable file length in ucp 'C' message"); }, + }; let fpath = Path::new(line[2]); // TODO: I've disabled set_len; is this best practice? scp doesn't do it. - //f.set_len(flen as u64).unwrap(); - fs::set_permissions(file_path, PermissionsExt::from_mode(fmode)).unwrap(); + //try!(f.set_len(flen as u64)); + try!(fs::set_permissions(file_path, PermissionsExt::from_mode(fmode))); let mut received: usize = 0; while received < flen { - let rlen = stream.read(&mut buf).unwrap(); + let rlen = try!(stream.read(&mut buf)); //println!("recieved: {}", rlen); assert!(rlen > 0); let mut wbuf = &mut buf[..rlen]; - f.write_all(&wbuf).unwrap(); + try!(f.write_all(&wbuf)); received += rlen; } - f.sync_all().unwrap(); + try!(f.sync_all()); // f.close(); XXX: closes automatically? - stream.write(&[0]).unwrap(); + try!(stream.write(&[0])); Ok(()) } |