rustify several things around the precheck function

This commit is contained in:
holger krekel
2019-08-22 21:49:47 +02:00
parent 157d68246f
commit 2fd4b09cbc
7 changed files with 117 additions and 61 deletions

View File

@@ -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>) {

View File

@@ -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);
}
}
}

View File

@@ -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;

View File

@@ -638,6 +638,7 @@ impl Imap {
}
fn select_folder<S: AsRef<str>>(&self, context: &Context, folder: Option<S>) -> 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<S: AsRef<str>>(&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;
}
}

View File

@@ -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();

View File

@@ -94,6 +94,7 @@ pub enum LotState {
MsgInFresh = 10,
MsgInNoticed = 13,
MsgInSeen = 16,
MsgInMDNSent = 17,
MsgOutPreparing = 18,
MsgOutDraft = 19,
MsgOutPending = 20,

View File

@@ -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<MessageState> 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<str>,
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) => {