diff --git a/src/context.rs b/src/context.rs index 45f3c5de4..d9fcec7a5 100644 --- a/src/context.rs +++ b/src/context.rs @@ -193,43 +193,47 @@ unsafe fn cb_precheck_imf( server_folder: &str, server_uid: uint32_t, ) -> libc::c_int { - let mut rfc724_mid_exists: libc::c_int = 0i32; - let msg_id: uint32_t; - let mut old_server_folder: *mut libc::c_char = ptr::null_mut(); - let mut old_server_uid: uint32_t = 0i32 as uint32_t; - let mut mark_seen: libc::c_int = 0i32; - msg_id = dc_rfc724_mid_exists( + let rfc724_mid = as_str(rfc724_mid) + .trim_start_matches("<") + .trim_end_matches(">"); + + let mut mark_seen = false; + info!( context, + 0, + "cb_precheck_imf rfc724_mid={:?}, server_folder={}, server_uid={}", rfc724_mid, - &mut old_server_folder, - &mut old_server_uid, + server_folder, + server_uid ); - if msg_id != 0i32 as libc::c_uint { - rfc724_mid_exists = 1i32; - if *old_server_folder.offset(0isize) as libc::c_int == 0i32 - && old_server_uid == 0i32 as libc::c_uint - { - info!( - context, - 0, - "[move] detected bbc-self {}", - as_str(rfc724_mid), - ); - mark_seen = 1i32 - } else if as_str(old_server_folder) != server_folder { - info!( - context, - 0, - "[move] detected moved message {}", - as_str(rfc724_mid), - ); + if let Some(res) = dc_rfc724_mid_exists_with_msg_state(context, rfc724_mid) { + let (msg_id, msg_state, old_server_folder, old_server_uid) = res; + if msg_id != 0 { + if old_server_folder.is_empty() { + info!(context, 0, "[move] detected bbc-self {}", rfc724_mid,); + mark_seen = true; + } else if old_server_folder != server_folder { + info!(context, 0, "[move] detected moved message {}", rfc724_mid,); + } dc_update_msg_move_state(context, rfc724_mid, MoveState::Stay); + if msg_state == MessageState::InSeen { + // Message is maybe moved from another folder. + // trigger MDN receipts + info!( + context, + 0, + "InSeen msgid={} server_uid={} server_folder={}", + msg_id, + server_uid, + server_folder, + ); + } } - if as_str(old_server_folder) != server_folder || old_server_uid != server_uid { + if old_server_folder != server_folder || old_server_uid != server_uid { dc_update_server_uid(context, rfc724_mid, server_folder, server_uid); } dc_do_heuristics_moves(context, server_folder, msg_id); - if 0 != mark_seen { + if mark_seen { job_add( context, Action::MarkseenMsgOnImap, @@ -238,9 +242,9 @@ unsafe fn cb_precheck_imf( 0, ); } + return msg_id as i32; } - free(old_server_folder as *mut libc::c_void); - rfc724_mid_exists + 0 } fn cb_set_config(context: &Context, key: &str, value: Option<&str>) { diff --git a/src/dc_move.rs b/src/dc_move.rs index 0116f1570..47fc4a2a5 100644 --- a/src/dc_move.rs +++ b/src/dc_move.rs @@ -1,5 +1,6 @@ use crate::constants::*; use crate::context::*; +use crate::dc_tools::as_str; use crate::job::*; use crate::message::*; use crate::param::Params; @@ -26,7 +27,7 @@ pub unsafe fn dc_do_heuristics_moves(context: &Context, folder: &str, msg_id: u3 } if dc_is_mvbox(context, folder) { - dc_update_msg_move_state(context, msg.rfc724_mid, MoveState::Stay); + dc_update_msg_move_state(context, as_str(msg.rfc724_mid), MoveState::Stay); } // 1 = dc message, 2 = reply to dc message @@ -38,7 +39,7 @@ pub unsafe fn dc_do_heuristics_moves(context: &Context, folder: &str, msg_id: u3 Params::new(), 0, ); - dc_update_msg_move_state(context, msg.rfc724_mid, MoveState::Moving); + dc_update_msg_move_state(context, as_str(msg.rfc724_mid), MoveState::Moving); } } } diff --git a/src/dc_receive_imf.rs b/src/dc_receive_imf.rs index 1b834de02..faab0d0d6 100644 --- a/src/dc_receive_imf.rs +++ b/src/dc_receive_imf.rs @@ -343,23 +343,7 @@ unsafe fn add_parts( // check, if the mail is already in our database - if so, just update the folder/uid // (if the mail was moved around) and finish. (we may get a mail twice eg. if it is // moved between folders. make sure, this check is done eg. before securejoin-processing) */ - let mut old_server_folder = std::ptr::null_mut(); - let mut old_server_uid = 0; - - if 0 != dc_rfc724_mid_exists( - context, - rfc724_mid, - &mut old_server_folder, - &mut old_server_uid, - ) { - if as_str(old_server_folder) != server_folder.as_ref() || old_server_uid != server_uid { - dc_update_server_uid(context, rfc724_mid, server_folder.as_ref(), server_uid); - } - - free(old_server_folder.cast()); - cleanup(mime_in_reply_to, mime_references, txt_raw); - bail!("Message already in DB"); - } + // XXX call precheck? // 1 or 0 for yes/no msgrmsg = mime_parser.is_send_by_messenger; diff --git a/src/imap.rs b/src/imap.rs index fb3b23023..35c1ada93 100644 --- a/src/imap.rs +++ b/src/imap.rs @@ -638,6 +638,7 @@ impl Imap { } fn select_folder>(&self, context: &Context, folder: Option) -> bool { + info!(context, 0, "select_folder0"); if self.session.lock().unwrap().is_none() { // we are in termination, noting useful to be done anymore let mut cfg = self.config.write().unwrap(); @@ -645,7 +646,7 @@ impl Imap { cfg.selected_folder_needs_expunge = false; return false; } - + info!(context, 0, "select_folder1"); // if there is a new folder and the new folder is equal to the selected one, there's nothing to do. // if there is _no_ new folder, we continue as we might want to expunge below. if let Some(ref folder) = folder { @@ -655,9 +656,11 @@ impl Imap { } } } + info!(context, 0, "select_folder2"); // deselect existing folder, if needed (it's also done implicitly by SELECT, however, without EXPUNGE then) if self.config.read().unwrap().selected_folder_needs_expunge { + info!(context, 0, "select_folder3"); if let Some(ref folder) = self.config.read().unwrap().selected_folder { info!(context, 0, "Expunge messages in \"{}\".", folder); @@ -676,17 +679,21 @@ impl Imap { self.config.write().unwrap().selected_folder_needs_expunge = false; } } + info!(context, 0, "select_folder4"); // select new folder if let Some(ref folder) = folder { if let Some(ref mut session) = &mut *self.session.lock().unwrap() { + info!(context, 0, "select_folder5"); match session.select(folder) { Ok(mailbox) => { + info!(context, 0, "select_folder6"); let mut config = self.config.write().unwrap(); config.selected_folder = Some(folder.as_ref().to_string()); config.selected_mailbox = Some(mailbox); } Err(err) => { + info!(context, 0, "select_folder7"); info!( context, 0, @@ -1039,14 +1046,17 @@ impl Imap { // if needed, the ui can call dc_imap_interrupt_idle() to trigger a reconnect. idle.set_keepalive(Duration::from_secs(23 * 60)); let res = idle.wait_keepalive(); + eprintln!("idle wait_keepalive returned"); // Ignoring the error, as this happens when we try sending after the drop let _send_res = sender.send(res); + eprintln!("idle sending result"); // Trigger condvar let mut watch = lock.lock().unwrap(); *watch = true; cvar.notify_one(); + eprintln!("idle spawn thread ending"); } }); receiver @@ -1209,7 +1219,7 @@ impl Imap { if let Some(ref mut session) = &mut *self.session.lock().unwrap() { match session.uid_mv(&set, &dest_folder) { Ok(_) => { - // XXX set dest_uid properly (like it was done in C) + *dest_uid = 0; return ImapResult::Success; } Err(err) => { @@ -1273,6 +1283,13 @@ impl Imap { pub fn set_seen>(&self, context: &Context, folder: S, uid: u32) -> ImapResult { if uid == 0 { + info!( + context, + 0, + "set_seen folder={} uid={}", + folder.as_ref(), + uid + ); return ImapResult::Failed; } if self.is_connected() { @@ -1294,6 +1311,13 @@ impl Imap { } else if !self.add_flag(context, uid, "\\Seen") { warn!(context, 0, "Cannot mark message as seen.",); } else { + info!( + context, + 0, + "success marking message {}/{} as seen...", + folder.as_ref(), + uid, + ); return ImapResult::Success; } } diff --git a/src/job.rs b/src/job.rs index c607f0d9b..88d1cab1c 100644 --- a/src/job.rs +++ b/src/job.rs @@ -228,7 +228,12 @@ impl Job { } 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, + as_str(msg.rfc724_mid), + &dest_folder, + dest_uid, + ); } _ => {} } @@ -281,21 +286,37 @@ impl Job { } if let Ok(msg) = dc_msg_load_from_db(context, self.foreign_id) { let server_folder = msg.server_folder.as_ref().unwrap(); + info!(context, 0, "job_markseen_msg db id={}", self.foreign_id); match inbox.set_seen(context, server_folder, msg.server_uid) { ImapResult::Failed => { + info!(context, 0, "job_markseen_msg failed"); return; } ImapResult::RetryLater => { + info!(context, 0, "job_markseen_msg retry-later"); self.try_again_later(Delay::Standard, None); return; } _ => {} }; + info!( + context, + 0, + "set_mdnsent wantsmdn={} mdns_enabled={}", + msg.param.get_int(Param::WantsMdn).unwrap_or_default(), + context + .sql + .get_config_int(context, "mdns_enabled") + .unwrap_or_else(|| 1) + ); + + /* if 0 != msg.param.get_int(Param::WantsMdn).unwrap_or_default() && 0 != context .sql .get_config_int(context, "mdns_enabled") .unwrap_or_else(|| 1) + */ { let folder = msg.server_folder.as_ref().unwrap(); diff --git a/src/lot.rs b/src/lot.rs index 85a11f4f1..ad7b80ba9 100644 --- a/src/lot.rs +++ b/src/lot.rs @@ -94,6 +94,7 @@ pub enum LotState { MsgInFresh = 10, MsgInNoticed = 13, MsgInSeen = 16, + MsgInMDNSent = 17, MsgOutPreparing = 18, MsgOutDraft = 19, MsgOutPending = 20, diff --git a/src/message.rs b/src/message.rs index 771612117..b59a321b0 100644 --- a/src/message.rs +++ b/src/message.rs @@ -30,6 +30,7 @@ pub enum MessageState { InFresh = 10, InNoticed = 13, InSeen = 16, + InMDNSent = 17, OutPreparing = 18, OutDraft = 19, OutPending = 20, @@ -46,6 +47,7 @@ impl From for LotState { InFresh => LotState::MsgInFresh, InNoticed => LotState::MsgInNoticed, InSeen => LotState::MsgInSeen, + InMDNSent => LotState::MsgInMDNSent, OutPreparing => LotState::MsgOutPreparing, OutDraft => LotState::MsgOutDraft, OutPending => LotState::MsgOutPending, @@ -1051,18 +1053,14 @@ pub fn dc_msg_exists(context: &Context, msg_id: u32) -> bool { false } -pub fn dc_update_msg_move_state( - context: &Context, - rfc724_mid: *const libc::c_char, - state: MoveState, -) -> bool { +pub fn dc_update_msg_move_state(context: &Context, rfc724_mid: &str, state: MoveState) -> bool { // we update the move_state for all messages belonging to a given Message-ID // so that the state stay intact when parts are deleted sql::execute( context, &context.sql, "UPDATE msgs SET move_state=? WHERE rfc724_mid=?;", - params![state as i32, as_str(rfc724_mid)], + params![state as i32, rfc724_mid], ) .is_ok() } @@ -1240,6 +1238,29 @@ pub fn dc_rfc724_mid_cnt(context: &Context, rfc724_mid: *const libc::c_char) -> } } +pub fn dc_rfc724_mid_exists_with_msg_state( + context: &Context, + rfc724_mid: &str, +) -> Option<(u32, MessageState, String, u32)> { + if rfc724_mid.is_empty() { + return None; + } + match context.sql.query_row( + "SELECT id, state, server_folder, server_uid FROM msgs WHERE rfc724_mid=?", + &[rfc724_mid], + |row| Ok((row.get(0)?, row.get(1)?, row.get(2)?, row.get(3)?)), + ) { + Ok(res) => Some(res), + Err(_err) => { + info!( + context, + 0, "dc_rfc724_mid_exists_with_msg_state ERR={:?}", _err + ); + None + } + } +} + pub fn dc_rfc724_mid_exists( context: &Context, rfc724_mid: *const libc::c_char, @@ -1278,13 +1299,13 @@ pub fn dc_rfc724_mid_exists( pub fn dc_update_server_uid( context: &Context, - rfc724_mid: *const libc::c_char, + rfc724_mid: &str, server_folder: impl AsRef, server_uid: u32, ) { match context.sql.execute( "UPDATE msgs SET server_folder=?, server_uid=? WHERE rfc724_mid=?;", - params![server_folder.as_ref(), server_uid, as_str(rfc724_mid)], + params![server_folder.as_ref(), server_uid, rfc724_mid], ) { Ok(_) => {} Err(err) => {