From cad7822c16f9e03883b64c45b91cff547bd11cbd Mon Sep 17 00:00:00 2001 From: Franz Dietrich Date: Sat, 20 Jan 2024 16:01:36 +0100 Subject: [PATCH] create a first list_scripts command --- src/lib.rs | 88 ++++++++++++++++++++++++++---------------------------- 1 file changed, 43 insertions(+), 45 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 991ed9f..845feb1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,9 +1,10 @@ use std::{sync::Arc, time::Duration}; +use anyhow::Context; use managesieve::Capabilities; use thiserror::Error; use tokio::{ - io::{split, AsyncBufReadExt, BufReader, WriteHalf}, + io::{split, AsyncBufReadExt, AsyncWriteExt, BufReader, WriteHalf}, net::TcpStream, sync::Mutex, }; @@ -93,7 +94,7 @@ impl ConnectionInfo { trace!("Capabilities read: {:#?}", &caps); Ok(ConnectionConnected { info: self, - writer: Arc::new(writer), + writer: Arc::new(Mutex::new(writer)), buffer, server_settings: caps, }) @@ -104,7 +105,7 @@ impl ConnectionInfo { pub struct ConnectionConnected { info: ConnectionInfo, //reader: Arc>>, - writer: Arc>>, + writer: Arc>>>, buffer: Arc>, //pub join_handle: Arc>, server_settings: Capabilities, @@ -130,54 +131,51 @@ impl ConnectionConnected { pub async fn log_server_settings(&self) { info!("Serversettings:\n{:?}", self.server_settings) } - #[tracing::instrument(name = "gettin the intro")] - pub async fn read_introduction(self) -> Result, anyhow::Error> { + + pub async fn list_scripts(self) -> anyhow::Result<(Vec<(String, bool)>, Self)> { let Self { - info, - //reader: Arc>>, writer, buffer, + info, server_settings, } = self; - tokio::time::sleep(Duration::from_millis(50)).await; - let mut bf = buffer.lock().await; - let response = match managesieve::response_capability(&bf.to_string()) { - Ok((rest, capability, response)) => { - info!("Successfully read the introduction {:?}", response); - bf.clear(); - bf.push_str(rest); - drop(bf); - Ok(IsComplete::Yes(Self { - info, - writer: writer.clone(), - buffer: buffer.clone(), - server_settings: capability, - })) - } - Err(managesieve::Error::IncompleteResponse) => { - trace!("incomplete introduction"); - Ok(IsComplete::No(Self { - info, - writer, - buffer: buffer.clone(), - server_settings, - })) - } - Err(managesieve::Error::InvalidResponse) => { - error!("invalid response"); - Err(managesieve::Error::InvalidResponse)? - } - Err(managesieve::Error::InvalidInput) => { - error!("invalid input"); - Err(managesieve::Error::InvalidResponse)? - } - Err(managesieve::Error::MissingLine(line)) => { - error!("a capability line was missing: {:?}", line); - Err(managesieve::Error::InvalidResponse)? - } - }; + let command = managesieve::Command::list_scripts(); + writer + .lock() + .await + .write_all(command.to_string().as_bytes()) + .await + .context("Failed to write LISTSCRIPTS command")?; - response + let scriptslist = loop { + let mut buf = buffer.lock().await; + trace!("reading new input:\n{}", buf); + match managesieve::response_listscripts(&buf.to_string()) { + Ok((rest, scriptslist, resp)) => match resp.tag { + managesieve::OkNoBye::Ok => { + buf.clear(); + buf.push_str(rest); + info!("Read the introduction"); + break scriptslist; + } + managesieve::OkNoBye::No | managesieve::OkNoBye::Bye => { + trace!("Connection closed!"); + //panic!("Invalid Response") + } + }, + Err(e) => trace!("(temporary) error: {}", e), + } + tokio::time::sleep(Duration::from_millis(50)).await; + }; + Ok(( + scriptslist, + Self { + writer, + buffer, + info, + server_settings, + }, + )) } pub fn get_greeting(&self) -> String {