ouais
This commit is contained in:
parent
5b3bf5dd3c
commit
523e6eaf7a
8 changed files with 68 additions and 14 deletions
|
@ -22,7 +22,6 @@ format-bytes = "0.2.0"
|
|||
futures = "0.3.13"
|
||||
inotify = { version = "0.9.2", features = ["stream"] }
|
||||
log = "0.4.14"
|
||||
panorama-imap = { path = "imap", version = "0" }
|
||||
parking_lot = "0.11.1"
|
||||
pgp = "0.7.1"
|
||||
pin-project = "1.0.5"
|
||||
|
@ -37,5 +36,10 @@ toml = "0.5.8"
|
|||
webpki-roots = "0.21.0"
|
||||
xdg = "2.2.0"
|
||||
|
||||
[dependencies.panorama-imap]
|
||||
path = "imap"
|
||||
version = "0"
|
||||
features = ["rfc2177-idle"]
|
||||
|
||||
[features]
|
||||
clippy = []
|
||||
|
|
|
@ -28,3 +28,7 @@ webpki-roots = "0.21.0"
|
|||
|
||||
[dev-dependencies]
|
||||
assert_matches = "1.3"
|
||||
|
||||
[features]
|
||||
default = ["rfc2177-idle"]
|
||||
rfc2177-idle = []
|
||||
|
|
|
@ -100,10 +100,10 @@ where
|
|||
}
|
||||
|
||||
let cmd_str = format!("{}{} {}\r\n", TAG_PREFIX, id, cmd);
|
||||
debug!("[{}] writing to socket: {:?}", id, cmd_str);
|
||||
// debug!("[{}] writing to socket: {:?}", id, cmd_str);
|
||||
self.conn.write_all(cmd_str.as_bytes()).await?;
|
||||
self.conn.flush().await?;
|
||||
debug!("[{}] written.", id);
|
||||
// debug!("[{}] written.", id);
|
||||
|
||||
let resp = ExecWaiter(self, id, false).await;
|
||||
// let resp = {
|
||||
|
@ -252,7 +252,7 @@ async fn listen<C>(
|
|||
where
|
||||
C: AsyncRead + Unpin,
|
||||
{
|
||||
debug!("amogus");
|
||||
// debug!("amogus");
|
||||
let mut reader = BufReader::new(conn);
|
||||
let mut greeting = Some(greeting);
|
||||
|
||||
|
|
|
@ -166,4 +166,13 @@ impl ClientAuthenticated {
|
|||
debug!("select response: {:?}", resp);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Runs the SELECT command
|
||||
#[cfg(feature = "rfc2177-idle")]
|
||||
pub async fn idle(&mut self) -> Result<()> {
|
||||
let cmd = Command::Idle;
|
||||
let resp = self.execute(cmd).await?;
|
||||
debug!("idle response: {:?}", resp);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,9 +5,20 @@ use std::fmt;
|
|||
pub enum Command {
|
||||
Capability,
|
||||
Starttls,
|
||||
Login { username: String, password: String },
|
||||
Select { mailbox: String },
|
||||
List { reference: String, mailbox: String },
|
||||
Login {
|
||||
username: String,
|
||||
password: String,
|
||||
},
|
||||
Select {
|
||||
mailbox: String,
|
||||
},
|
||||
List {
|
||||
reference: String,
|
||||
mailbox: String,
|
||||
},
|
||||
|
||||
#[cfg(feature = "rfc2177-idle")]
|
||||
Idle,
|
||||
}
|
||||
|
||||
impl fmt::Display for Command {
|
||||
|
@ -19,6 +30,9 @@ impl fmt::Display for Command {
|
|||
Login { username, password } => write!(f, "LOGIN {} {}", username, password),
|
||||
Select { mailbox } => write!(f, "SELECT {}", mailbox),
|
||||
List { reference, mailbox } => write!(f, "LIST {:?} {:?}", reference, mailbox),
|
||||
|
||||
#[cfg(feature = "rfc2177-idle")]
|
||||
Idle => write!(f, "IDLE"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,13 +15,15 @@ use crate::response::*;
|
|||
#[grammar = "parser/rfc3501.pest"]
|
||||
struct Rfc3501;
|
||||
|
||||
pub fn parse_capability(s: impl AsRef<str>) -> Result<Capability, Error<Rule>> {
|
||||
pub type ParseResult<T, E = Error<Rule>> = Result<T, E>;
|
||||
|
||||
pub fn parse_capability(s: impl AsRef<str>) -> ParseResult<Capability> {
|
||||
let mut pairs = Rfc3501::parse(Rule::capability, s.as_ref())?;
|
||||
let pair = pairs.next().unwrap();
|
||||
Ok(build_capability(pair))
|
||||
}
|
||||
|
||||
pub fn parse_response(s: impl AsRef<str>) -> Result<Response, Error<Rule>> {
|
||||
pub fn parse_response(s: impl AsRef<str>) -> ParseResult<Response> {
|
||||
let mut pairs = Rfc3501::parse(Rule::response, s.as_ref())?;
|
||||
let pair = pairs.next().unwrap();
|
||||
Ok(build_response(pair))
|
||||
|
@ -90,10 +92,31 @@ fn build_response(pair: Pair<Rule>) -> Response {
|
|||
_ => unreachable!("{:#?}", pair),
|
||||
}
|
||||
}
|
||||
Rule::continue_req => {
|
||||
let (code, s) = build_resp_text(unwrap1(pair));
|
||||
Response::Continue {
|
||||
code,
|
||||
information: Some(s),
|
||||
}
|
||||
}
|
||||
_ => unreachable!("{:#?}", pair),
|
||||
}
|
||||
}
|
||||
|
||||
fn build_resp_text(pair: Pair<Rule>) -> (Option<ResponseCode>, String) {
|
||||
assert!(matches!(pair.as_rule(), Rule::resp_text));
|
||||
let mut pairs = pair.into_inner();
|
||||
let mut pair = pairs.next().unwrap();
|
||||
let mut resp_code = None;
|
||||
if let Rule::resp_text_code = pair.as_rule() {
|
||||
resp_code = build_resp_text_code(pair);
|
||||
pair = pairs.next().unwrap();
|
||||
}
|
||||
assert!(matches!(pair.as_rule(), Rule::text));
|
||||
let s = pair.as_str().to_owned();
|
||||
(resp_code, s)
|
||||
}
|
||||
|
||||
fn build_msg_att(pair: Pair<Rule>) -> AttributeValue {
|
||||
if !matches!(pair.as_rule(), Rule::msg_att_dyn_or_stat) {
|
||||
unreachable!("{:#?}", pair);
|
||||
|
@ -153,7 +176,7 @@ fn build_resp_cond_state(pair: Pair<Rule>) -> (Status, Option<ResponseCode>, Opt
|
|||
let pairs = pair.into_inner();
|
||||
for pair in pairs {
|
||||
match pair.as_rule() {
|
||||
Rule::resp_text_code => code = build_resp_code(pair),
|
||||
Rule::resp_text_code => code = build_resp_text_code(pair),
|
||||
Rule::text => information = Some(pair.as_str().to_owned()),
|
||||
_ => unreachable!("{:#?}", pair),
|
||||
}
|
||||
|
@ -162,7 +185,7 @@ fn build_resp_cond_state(pair: Pair<Rule>) -> (Status, Option<ResponseCode>, Opt
|
|||
(status, code, information)
|
||||
}
|
||||
|
||||
fn build_resp_code(pair: Pair<Rule>) -> Option<ResponseCode> {
|
||||
fn build_resp_text_code(pair: Pair<Rule>) -> Option<ResponseCode> {
|
||||
if !matches!(pair.as_rule(), Rule::resp_text_code) {
|
||||
unreachable!("{:#?}", pair);
|
||||
}
|
||||
|
|
|
@ -135,11 +135,11 @@ zone = @{ ("+" | "-") ~ digit{4} }
|
|||
// core rules from https://tools.ietf.org/html/rfc2234#section-6.1
|
||||
alpha = @{ '\x41'..'\x5a' | '\x61'..'\x7a' }
|
||||
char = @{ '\x01'..'\x7f' }
|
||||
cr = @{ "\x0d" }
|
||||
cr = _{ "\x0d" }
|
||||
crlf = _{ cr ~ lf }
|
||||
ctl = @{ '\x00'..'\x1f' | "\x7f" }
|
||||
digit = @{ '\x30'..'\x39' }
|
||||
dquote = @{ "\"" }
|
||||
lf = @{ "\x0a" }
|
||||
lf = _{ "\x0a" }
|
||||
sp = _{ " " }
|
||||
|
||||
|
|
|
@ -110,7 +110,7 @@ async fn imap_main(acct: MailAccountConfig) -> Result<()> {
|
|||
debug!("listing all emails...");
|
||||
let folder_tree = authed.list().await?;
|
||||
|
||||
tokio::time::sleep(std::time::Duration::from_secs(60)).await;
|
||||
let idle = authed.idle().await?;
|
||||
debug!("heartbeat");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue