streamline imap mv() wrt to return codes, follow C more closely and add comments about missing dest_uid setting from imap

This commit is contained in:
holger krekel
2019-08-20 08:26:01 +02:00
parent 7641bb4d9a
commit 6441ceeedc
2 changed files with 37 additions and 52 deletions

View File

@@ -639,6 +639,7 @@ impl Imap {
fn select_folder<S: AsRef<str>>(&self, context: &Context, folder: Option<S>) -> usize { fn select_folder<S: AsRef<str>>(&self, context: &Context, folder: Option<S>) -> usize {
if self.session.lock().unwrap().is_none() { if self.session.lock().unwrap().is_none() {
// we are in termination, noting useful to be done anymore
let mut cfg = self.config.write().unwrap(); let mut cfg = self.config.write().unwrap();
cfg.selected_folder = None; cfg.selected_folder = None;
cfg.selected_folder_needs_expunge = false; cfg.selected_folder_needs_expunge = false;
@@ -670,7 +671,7 @@ impl Imap {
} }
} }
} else { } else {
return 0; unreachable!();
} }
self.config.write().unwrap().selected_folder_needs_expunge = true; self.config.write().unwrap().selected_folder_needs_expunge = true;
} }
@@ -1170,11 +1171,8 @@ impl Imap {
dest_folder: S2, dest_folder: S2,
dest_uid: &mut u32, dest_uid: &mut u32,
) -> ImapResult { ) -> ImapResult {
let mut res = ImapResult::RetryLater;
let set = format!("{}", uid);
if uid == 0 { if uid == 0 {
res = ImapResult::Failed; return ImapResult::Failed;
} else if folder.as_ref() == dest_folder.as_ref() { } else if folder.as_ref() == dest_folder.as_ref() {
info!( info!(
context, context,
@@ -1184,9 +1182,8 @@ impl Imap {
uid, uid,
dest_folder.as_ref() dest_folder.as_ref()
); );
return ImapResult::AlreadyDone;
res = ImapResult::AlreadyDone; }
} else {
info!( info!(
context, context,
0, 0,
@@ -1203,12 +1200,18 @@ impl Imap {
"Cannot select folder {} for moving message.", "Cannot select folder {} for moving message.",
folder.as_ref() folder.as_ref()
); );
} else { return if !self.should_reconnect() {
let moved = if let Some(ref mut session) = &mut *self.session.lock().unwrap() { ImapResult::Failed
} else {
ImapResult::RetryLater
}
}
let set = format!("{}", uid);
if let Some(ref mut session) = &mut *self.session.lock().unwrap() {
match session.uid_mv(&set, &dest_folder) { match session.uid_mv(&set, &dest_folder) {
Ok(_) => { Ok(_) => {
res = ImapResult::Success; // XXX set dest_uid properly (like it was done in C)
true return ImapResult::Success;
} }
Err(err) => { Err(err) => {
info!( info!(
@@ -1220,49 +1223,31 @@ impl Imap {
dest_folder.as_ref(), dest_folder.as_ref(),
err err
); );
false
} }
} }
} else { } else {
unreachable!(); unreachable!();
}; };
if !moved { // message was NOT moved, let's try copy
let copied = if let Some(ref mut session) = &mut *self.session.lock().unwrap() { if let Some(ref mut session) = &mut *self.session.lock().unwrap() {
match session.uid_copy(&set, &dest_folder) { match session.uid_copy(&set, &dest_folder) {
Ok(_) => true, Ok(_) => {},
Err(err) => { Err(err) => {
eprintln!("error copy: {:?}", err); info!(context, 0, "Cannot copy message. {:?}", err);
info!(context, 0, "Cannot copy message.",); return ImapResult::Failed;
false
} }
} }
} else { } else {
unreachable!(); unreachable!();
}; };
if copied { if self.add_flag(context, uid, "\\Deleted") {
if !self.add_flag(context, uid, "\\Deleted") {
warn!(context, 0, "Cannot mark message as \"Deleted\".",);
}
self.config.write().unwrap().selected_folder_needs_expunge = true; self.config.write().unwrap().selected_folder_needs_expunge = true;
res = ImapResult::Success; return ImapResult::Success;
} }
} warn!(context, 0, "Cannot mark message as \"Deleted\".",);
} return ImapResult::Failed;
}
if res == ImapResult::Success {
// TODO: is this correct?
*dest_uid = uid;
}
if res == ImapResult::RetryLater && !self.should_reconnect() {
res = ImapResult::Failed;
}
res
} }
fn add_flag<S: AsRef<str>>(&self, context: &Context, server_uid: u32, flag: S) -> bool { fn add_flag<S: AsRef<str>>(&self, context: &Context, server_uid: u32, flag: S) -> bool {
@@ -1430,7 +1415,10 @@ impl Imap {
server_uid: &mut u32, server_uid: &mut u32,
) -> ImapResult { ) -> ImapResult {
if *server_uid == 0 { if *server_uid == 0 {
return ImapResult::Success; return ImapResult::Failed
}
if !self.is_connected() {
return ImapResult::RetryLater
} }
{ {
info!( info!(
@@ -1449,7 +1437,9 @@ impl Imap {
"Cannot select folder {} for deleting message.", "Cannot select folder {} for deleting message.",
folder.as_ref() folder.as_ref()
); );
} else { return ImapResult::RetryLater
}
{
let set = format!("{}", server_uid); let set = format!("{}", server_uid);
if let Some(ref mut session) = &mut *self.session.lock().unwrap() { if let Some(ref mut session) = &mut *self.session.lock().unwrap() {
match session.uid_fetch(set, PREFETCH_FLAGS) { match session.uid_fetch(set, PREFETCH_FLAGS) {
@@ -1473,6 +1463,7 @@ impl Imap {
message_id.as_ref(), message_id.as_ref(),
); );
*server_uid = 0; *server_uid = 0;
return ImapResult::Failed;
} }
} }
Err(err) => { Err(err) => {
@@ -1486,26 +1477,20 @@ impl Imap {
server_uid, server_uid,
); );
*server_uid = 0; *server_uid = 0;
return ImapResult::Failed;
} }
} }
} }
// mark the message for deletion // mark the message for deletion
if !self.add_flag(context, *server_uid, "\\Deleted") { if !self.add_flag(context, *server_uid, "\\Deleted") {
warn!(context, 0, "Cannot mark message as \"Deleted\"."); warn!(context, 0, "Cannot mark message as \"Deleted\".");
return ImapResult::Failed;
} else { } else {
self.config.write().unwrap().selected_folder_needs_expunge = true; self.config.write().unwrap().selected_folder_needs_expunge = true;
return ImapResult::Success; return ImapResult::Success;
} }
} }
} }
// deletion was not successful or message was deleted already
return if self.is_connected() {
ImapResult::Failed
} else {
// we are not connected so the caller may retry
ImapResult::RetryLater
};
} }
pub fn configure_folders(&self, context: &Context, flags: libc::c_int) { pub fn configure_folders(&self, context: &Context, flags: libc::c_int) {

View File

@@ -195,8 +195,6 @@ impl Job {
#[allow(non_snake_case)] #[allow(non_snake_case)]
fn do_DC_JOB_MOVE_MSG(&mut self, context: &Context) { fn do_DC_JOB_MOVE_MSG(&mut self, context: &Context) {
let mut dest_uid = 0;
let inbox = context.inbox.read().unwrap(); let inbox = context.inbox.read().unwrap();
if !inbox.is_connected() { if !inbox.is_connected() {
@@ -219,6 +217,7 @@ impl Job {
if let Some(dest_folder) = dest_folder { if let Some(dest_folder) = dest_folder {
let server_folder = msg.server_folder.as_ref().unwrap(); let server_folder = msg.server_folder.as_ref().unwrap();
let mut dest_uid = 0;
match inbox.mv( match inbox.mv(
context, context,
@@ -231,6 +230,7 @@ impl Job {
self.try_again_later(Delay::Standard, None); self.try_again_later(Delay::Standard, None);
} }
ImapResult::Success => { ImapResult::Success => {
// TODO: dest_uid is not (yet) set by mv() so remains 0
dc_update_server_uid(context, msg.rfc724_mid, &dest_folder, dest_uid); dc_update_server_uid(context, msg.rfc724_mid, &dest_folder, dest_uid);
} }
_ => {} _ => {}