diff options
author | metamuffin <metamuffin@disroot.org> | 2024-06-14 04:48:14 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2024-06-14 04:48:14 +0200 |
commit | e4499d44e931d2ee7c70e7610bbfca3fefd00fea (patch) | |
tree | 470e44d4ca22de6404aeb4330784dd568751908b /src/client.rs | |
parent | e34da6ca957ec813a361cbcaf0dc89e953af6db1 (diff) | |
download | online-offsite-backup-e4499d44e931d2ee7c70e7610bbfca3fefd00fea.tar online-offsite-backup-e4499d44e931d2ee7c70e7610bbfca3fefd00fea.tar.bz2 online-offsite-backup-e4499d44e931d2ee7c70e7610bbfca3fefd00fea.tar.zst |
implement upload and download
Diffstat (limited to 'src/client.rs')
-rw-r--r-- | src/client.rs | 58 |
1 files changed, 55 insertions, 3 deletions
diff --git a/src/client.rs b/src/client.rs index 492008a..0f86712 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1,6 +1,7 @@ use anyhow::{anyhow, bail, Result}; +use log::debug; use std::{ - io::{BufRead, BufReader, BufWriter, Write}, + io::{copy, BufRead, BufReader, BufWriter, Read, Write}, net::{TcpStream, ToSocketAddrs}, }; @@ -25,8 +26,9 @@ impl Client { let mut line = String::new(); let mut out = Vec::new(); loop { + line.clear(); self.rsock.read_line(&mut line)?; - if line.trim().is_empty() || line.ends_with("\n\n") { + if line.trim().is_empty() { break Ok(out); } check_error(&line)?; @@ -35,6 +37,56 @@ impl Client { out.push((mtime.parse()?, size.parse()?, serial.parse()?)); } } + pub fn upload(&mut self, size: u64, mut reader: impl Read) -> Result<()> { + debug!("announcing upload of {size} bytes"); + writeln!(self.wsock, "upload,{size}")?; + self.wsock.flush()?; + + let mut line = String::new(); + self.rsock.read_line(&mut line)?; + check_error(&line)?; + if line.trim() != "ready" { + bail!("invalid response, not ready"); + } + debug!("server ready"); + + copy(&mut reader, &mut self.wsock)?; + + line.clear(); + self.rsock.read_line(&mut line)?; + check_error(&line)?; + if line.trim() != "done" { + bail!("invalid response, not done"); + } + debug!("server done"); + Ok(()) + } + pub fn download(&mut self, serial: Serial, mut writer: impl Write) -> Result<()> { + debug!("requesting download for serial={serial}"); + writeln!(self.wsock, "download,{serial}")?; + self.wsock.flush()?; + + let mut line = String::new(); + self.rsock.read_line(&mut line)?; + check_error(&line)?; + let Some(size) = line.trim().strip_prefix("ready,") else { + bail!("server not ready") + }; + eprintln!("{size:?}"); + let size = size.parse()?; + debug!("server ready"); + + copy(&mut self.rsock.by_ref().take(size), &mut writer)?; + + line.clear(); + self.rsock.read_line(&mut line)?; + check_error(&line)?; + if line.trim() != "done" { + bail!("invalid response, not done"); + } + debug!("server done"); + Ok(()) + } pub fn quit(mut self) -> Result<()> { writeln!(self.wsock, "quit")?; self.wsock.flush()?; @@ -43,7 +95,7 @@ impl Client { } fn check_error(line: &str) -> Result<()> { - if let Some(message) = line.trim().strip_prefix("error") { + if let Some(message) = line.trim().strip_prefix("error,") { bail!("server error: {message}") } Ok(()) |