mirror of
https://github.com/chatmail/core.git
synced 2026-04-17 21:46:35 +03:00
rustify several things around the precheck function
This commit is contained in:
@@ -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>) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
28
src/imap.rs
28
src/imap.rs
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
23
src/job.rs
23
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();
|
||||
|
||||
|
||||
@@ -94,6 +94,7 @@ pub enum LotState {
|
||||
MsgInFresh = 10,
|
||||
MsgInNoticed = 13,
|
||||
MsgInSeen = 16,
|
||||
MsgInMDNSent = 17,
|
||||
MsgOutPreparing = 18,
|
||||
MsgOutDraft = 19,
|
||||
MsgOutPending = 20,
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
Reference in New Issue
Block a user