use byteorder::{ReadBytesExt, WriteBytesExt, LittleEndian};
use std::os::unix::net::UnixStream;
use std::io::prelude::*;
use std::io::Cursor;
use std::io::Error;
pub struct RsudoSocket {
socket: UnixStream
}
impl RsudoSocket {
pub fn new(path: &str) -> RsudoSocket {
let socket = match UnixStream::connect(&path) {
Ok(socket) => socket,
Err(error) => {
panic!("There was a problem opening the socket: {:?}", error)
},
};
socket.set_read_timeout(None).expect("Couldn't set read timeout");
return RsudoSocket { socket: socket };
}
pub fn read(&mut self) -> (i32, String) {
let socket = &mut self.socket;
let mut size_le = vec![0u8; 4];
let mut retry;
while {
match socket.read(&mut size_le) {
Ok(_) => {
match Cursor::new(&size_le).read_u32::<LittleEndian>() {
Err(err) => {
println!("{:?}", err);
retry = true;
},
Ok(0) => {
retry = true;
},
_ => {
retry = false;
}
}
},
Err(error) => {
println!("There was a problem reading from the socket: {:?}", error);
retry = true;
}
};
retry
} { }
let size = Cursor::new(&size_le).read_u32::<LittleEndian>().unwrap();
let mut op_le = vec![0u8; 4];
socket.read_exact(&mut op_le).expect("error while reading op");
let op = Cursor::new(&op_le).read_i32::<LittleEndian>().unwrap();
let mut payload_bytes = vec![0u8; size as usize];
socket.read_exact(&mut payload_bytes).expect("error while reading payload");
let payload = String::from_utf8(payload_bytes).unwrap();
(op, payload)
}
pub fn write(&mut self, op: i32, payload: &str) -> Result<(), Error> {
let socket = &mut self.socket;
let mut op_le = vec![];
op_le.write_i32::<LittleEndian>(op).unwrap();
let payload_bytes = payload.as_bytes();
let mut size = vec![];
size.write_u32::<LittleEndian>(payload_bytes.len() as u32).unwrap();
let mut data = vec![];
data.append(&mut size);
data.append(&mut op_le);
data.append(&mut payload_bytes.to_vec());
socket.write_all(&data)
}
}