melib/imap: impl UNSELECT via nonexistent mailbox

master
Manos Pitsidianakis 2020-08-24 12:01:28 +03:00
parent 876e1bc510
commit 0f3bf858a3
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
2 changed files with 48 additions and 25 deletions

View File

@ -589,6 +589,14 @@ impl ImapConnection {
ret.push_str(&response);
return r.into();
}
ImapResponse::No(ref response_code)
if required_responses.intersects(RequiredResponses::NO_REQUIRED) =>
{
debug!(
"Received expected NO response: {:?} {:?}",
response_code, response
);
}
ImapResponse::No(ref response_code) => {
//FIXME return error
debug!("Received NO response: {:?} {:?}", response_code, response);
@ -731,31 +739,45 @@ impl ImapConnection {
pub async fn unselect(&mut self) -> Result<()> {
match self.stream.as_mut()?.current_mailbox.take() {
MailboxSelection::Examine(mailbox_hash) |
MailboxSelection::Select(mailbox_hash) =>{
let mut response = String::with_capacity(8 * 1024);
if self
.uid_store
.capabilities
.lock()
.unwrap()
.iter()
.any(|cap| cap.eq_ignore_ascii_case(b"UNSELECT"))
{
self.send_command(b"UNSELECT").await?;
self.read_response(&mut response, RequiredResponses::empty())
.await?;
} else {
/* `RFC3691 - UNSELECT Command` states: "[..] IMAP4 provides this
* functionality (via a SELECT command with a nonexistent mailbox name or
* reselecting the same mailbox with EXAMINE command)[..]
*/
self.select_mailbox(mailbox_hash, &mut response, true).await?;
self.examine_mailbox(mailbox_hash, &mut response, true).await?;
}
},
MailboxSelection::None => {},
MailboxSelection::Examine(_) |
MailboxSelection::Select(_) => {
let mut response = String::with_capacity(8 * 1024);
if self
.uid_store
.capabilities
.lock()
.unwrap()
.iter()
.any(|cap| cap.eq_ignore_ascii_case(b"UNSELECT"))
{
self.send_command(b"UNSELECT").await?;
self.read_response(&mut response, RequiredResponses::empty())
.await?;
} else {
/* `RFC3691 - UNSELECT Command` states: "[..] IMAP4 provides this
* functionality (via a SELECT command with a nonexistent mailbox name or
* reselecting the same mailbox with EXAMINE command)[..]
*/
let mut nonexistent = "blurdybloop".to_string();
{
let mailboxes = self.uid_store.mailboxes.lock().await;
while mailboxes.values().any(|m| m.imap_path() == &nonexistent) {
nonexistent.push('p');
}
}
self.send_command(
format!(
"SELECT \"{}\"",
nonexistent
)
.as_bytes(),
)
.await?;
self.read_response(&mut response, RequiredResponses::NO_REQUIRED)
.await?;
}
}
MailboxSelection::None => {},
}
Ok(())
}

View File

@ -53,6 +53,7 @@ bitflags! {
const EXPUNGE = 0b0001_0000_0000_0000;
const SEARCH = 0b0010_0000_0000_0000;
const FETCH = 0b0100_0000_0000_0000;
const NO_REQUIRED = 0b1000_0000_0000_0000;
const CAPABILITY_REQUIRED = Self::CAPABILITY.bits;
const LOGOUT_REQUIRED = Self::BYE.bits;
const SELECT_REQUIRED = Self::FLAGS.bits | Self::EXISTS.bits | Self::RECENT.bits | Self::UNSEEN.bits | Self::PERMANENTFLAGS.bits | Self::UIDNEXT.bits | Self::UIDVALIDITY.bits;