mirror of
https://github.com/chatmail/core.git
synced 2026-04-26 01:46:34 +03:00
setting some flags
This commit is contained in:
@@ -1311,29 +1311,6 @@ pub unsafe fn dc_free_ongoing(context: &dc_context_t) {
|
||||
s.shall_stop_ongoing = true;
|
||||
}
|
||||
|
||||
unsafe fn free_folders(mut folders: *mut clist) {
|
||||
if !folders.is_null() {
|
||||
let mut iter1: *mut clistiter;
|
||||
iter1 = (*folders).first;
|
||||
while !iter1.is_null() {
|
||||
let mut ret_folder: *mut dc_imapfolder_t = (if !iter1.is_null() {
|
||||
(*iter1).data
|
||||
} else {
|
||||
0 as *mut libc::c_void
|
||||
}) as *mut dc_imapfolder_t;
|
||||
free((*ret_folder).name_to_select as *mut libc::c_void);
|
||||
free((*ret_folder).name_utf8 as *mut libc::c_void);
|
||||
free(ret_folder as *mut libc::c_void);
|
||||
iter1 = if !iter1.is_null() {
|
||||
(*iter1).next
|
||||
} else {
|
||||
0 as *mut clistcell_s
|
||||
}
|
||||
}
|
||||
clist_free(folders);
|
||||
};
|
||||
}
|
||||
|
||||
unsafe fn moz_autoconfigure(
|
||||
mut context: &dc_context_t,
|
||||
mut url: *const libc::c_char,
|
||||
|
||||
381
src/dc_imap.rs
381
src/dc_imap.rs
@@ -13,6 +13,15 @@ use crate::types::*;
|
||||
|
||||
pub const DC_IMAP_SEEN: usize = 0x0001;
|
||||
|
||||
pub const DC_SUCCESS: usize = 3;
|
||||
pub const DC_ALREADY_DONE: usize = 2;
|
||||
pub const DC_RETRY_LATER: usize = 1;
|
||||
pub const DC_FAILED: usize = 0;
|
||||
|
||||
const PREFETCH_FLAGS: &'static str = "(UID ENVELOPE)";
|
||||
const BODY_FLAGS: &'static str = "(FLAGS BODY.PEEK[])";
|
||||
const FETCH_FLAGS: &'static str = "(FLAGS)";
|
||||
|
||||
#[repr(C)]
|
||||
pub struct dc_imap_t {
|
||||
config: Arc<RwLock<ImapConfig>>,
|
||||
@@ -226,6 +235,21 @@ impl Session {
|
||||
Session::Insecure(i) => i.idle().map(Into::into),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn uid_store<S1, S2>(
|
||||
&mut self,
|
||||
uid_set: S1,
|
||||
query: S2,
|
||||
) -> imap::error::Result<imap::types::ZeroCopy<Vec<imap::types::Fetch>>>
|
||||
where
|
||||
S1: AsRef<str>,
|
||||
S2: AsRef<str>,
|
||||
{
|
||||
match self {
|
||||
Session::Secure(i) => i.uid_store(uid_set, query),
|
||||
Session::Insecure(i) => i.uid_store(uid_set, query),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ImapConfig {
|
||||
@@ -264,10 +288,6 @@ impl Default for ImapConfig {
|
||||
watch_folder: None,
|
||||
};
|
||||
|
||||
// prefetch: UID, ENVELOPE,
|
||||
// new: FLAGS BODY.PEEK[]
|
||||
// flags: FLAGS
|
||||
|
||||
cfg
|
||||
}
|
||||
}
|
||||
@@ -652,9 +672,7 @@ impl dc_imap_t {
|
||||
let list = if let Some(ref mut session) = *self.session.lock().unwrap() {
|
||||
// `FETCH <message sequence number> (UID)`
|
||||
let set = format!("{}", mailbox.exists);
|
||||
let query = "(UID ENVELOPE)";
|
||||
println!("fetching: {} {}", set, query);
|
||||
match session.fetch(set, query) {
|
||||
match session.fetch(set, PREFETCH_FLAGS) {
|
||||
Ok(list) => list,
|
||||
Err(err) => {
|
||||
eprintln!("fetch error: {:?}", err);
|
||||
@@ -705,9 +723,7 @@ impl dc_imap_t {
|
||||
// fetch messages with larger UID than the last one seen
|
||||
// (`UID FETCH lastseenuid+1:*)`, see RFC 4549
|
||||
let set = format!("{}:*", last_seen_uid + 1);
|
||||
let query = "(UID ENVELOPE)";
|
||||
println!("fetching: {} {}", set, query);
|
||||
match session.uid_fetch(set, query) {
|
||||
match session.uid_fetch(set, PREFETCH_FLAGS) {
|
||||
Ok(list) => list,
|
||||
Err(err) => {
|
||||
eprintln!("fetch err: {:?}", err);
|
||||
@@ -840,8 +856,7 @@ impl dc_imap_t {
|
||||
|
||||
let msgs = if let Some(ref mut session) = *self.session.lock().unwrap() {
|
||||
let set = format!("{}", server_uid);
|
||||
let query = "(FLAGS BODY.PEEK[])";
|
||||
match session.uid_fetch(set, query) {
|
||||
match session.uid_fetch(set, BODY_FLAGS) {
|
||||
Ok(msgs) => msgs,
|
||||
Err(err) => {
|
||||
eprintln!("error fetch single: {:?}", err);
|
||||
@@ -999,6 +1014,7 @@ impl dc_imap_t {
|
||||
|
||||
println!("imap idle waiting");
|
||||
// TODO: proper logging of different states
|
||||
// TODO: reconnect if we timed out
|
||||
match idle.wait_keepalive() {
|
||||
Ok(_) => {
|
||||
println!("imap done");
|
||||
@@ -1087,10 +1103,10 @@ impl dc_imap_t {
|
||||
uid: uint32_t,
|
||||
dest_folder: *const libc::c_char,
|
||||
dest_uid: *mut uint32_t,
|
||||
) -> dc_imap_res {
|
||||
) -> usize {
|
||||
unimplemented!()
|
||||
// let mut current_block: u64;
|
||||
// let mut res: dc_imap_res = DC_RETRY_LATER;
|
||||
// let mut res: usize = DC_RETRY_LATER;
|
||||
// let mut r: libc::c_int = 0;
|
||||
// let mut set: *mut mailimap_set = mailimap_set_new_single(uid);
|
||||
// let mut res_uid: uint32_t = 0 as uint32_t;
|
||||
@@ -1228,32 +1244,26 @@ impl dc_imap_t {
|
||||
// }) as libc::c_uint
|
||||
// } else {
|
||||
// res as libc::c_uint
|
||||
// }) as dc_imap_res;
|
||||
// }) as usize;
|
||||
}
|
||||
|
||||
fn add_flag(&self, server_uid: uint32_t, flag: *mut mailimap_flag) -> usize {
|
||||
unimplemented!()
|
||||
// let mut flag_list: *mut mailimap_flag_list = 0 as *mut mailimap_flag_list;
|
||||
// let mut store_att_flags: *mut mailimap_store_att_flags = 0 as *mut mailimap_store_att_flags;
|
||||
// let mut set: *mut mailimap_set = mailimap_set_new_single(server_uid);
|
||||
// if !(imap.etpan.is_null()) {
|
||||
// flag_list = mailimap_flag_list_new_empty();
|
||||
// mailimap_flag_list_add(flag_list, flag);
|
||||
// store_att_flags = mailimap_store_att_flags_new_add_flags(flag_list);
|
||||
// mailimap_uid_store(imap.etpan, set, store_att_flags);
|
||||
// }
|
||||
// if !store_att_flags.is_null() {
|
||||
// mailimap_store_att_flags_free(store_att_flags);
|
||||
// }
|
||||
// if !set.is_null() {
|
||||
// mailimap_set_free(set);
|
||||
// set = 0 as *mut mailimap_set
|
||||
// }
|
||||
// if 0 != imap.should_reconnect {
|
||||
// 0
|
||||
// } else {
|
||||
// 1
|
||||
// }
|
||||
fn add_flag<S: AsRef<str>>(&self, server_uid: u32, flag: S) -> usize {
|
||||
if let Some(ref mut session) = *self.session.lock().unwrap() {
|
||||
let set = format!("{}", server_uid);
|
||||
let query = format!("+ FLAGS ({})", flag.as_ref());
|
||||
match session.uid_store(set, query) {
|
||||
Ok(_) => {}
|
||||
Err(err) => {
|
||||
eprintln!("imap store error {:?}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if self.should_reconnect() {
|
||||
0
|
||||
} else {
|
||||
1
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_seen(
|
||||
@@ -1261,9 +1271,9 @@ impl dc_imap_t {
|
||||
context: &dc_context_t,
|
||||
folder: *const libc::c_char,
|
||||
uid: uint32_t,
|
||||
) -> dc_imap_res {
|
||||
) -> usize {
|
||||
unimplemented!()
|
||||
// let mut res: dc_imap_res = DC_RETRY_LATER;
|
||||
// let mut res: usize = DC_RETRY_LATER;
|
||||
// if folder.is_null() || uid == 0 as libc::c_uint {
|
||||
// res = DC_FAILED
|
||||
// } else if !imap.etpan.is_null() {
|
||||
@@ -1300,172 +1310,137 @@ impl dc_imap_t {
|
||||
// }) as libc::c_uint
|
||||
// } else {
|
||||
// res as libc::c_uint
|
||||
// }) as dc_imap_res;
|
||||
// }) as usize;
|
||||
}
|
||||
|
||||
pub fn set_mdnsent(
|
||||
&self,
|
||||
context: &dc_context_t,
|
||||
folder: *const libc::c_char,
|
||||
uid: uint32_t,
|
||||
) -> dc_imap_res {
|
||||
unimplemented!();
|
||||
// let mut can_create_flag: libc::c_int = 0;
|
||||
// let mut current_block: u64;
|
||||
// // returns 0=job should be retried later, 1=job done, 2=job done and flag just set
|
||||
// let mut res: dc_imap_res = DC_RETRY_LATER;
|
||||
// let mut set: *mut mailimap_set = mailimap_set_new_single(uid);
|
||||
// let mut fetch_result: *mut clist = 0 as *mut clist;
|
||||
// if folder.is_null() || uid == 0 as libc::c_uint || set.is_null() {
|
||||
// res = DC_FAILED
|
||||
// } else if !imap.etpan.is_null() {
|
||||
// dc_log_info(
|
||||
// context,
|
||||
// 0,
|
||||
// b"Marking message %s/%i as $MDNSent...\x00" as *const u8 as *const libc::c_char,
|
||||
// folder,
|
||||
// uid as libc::c_int,
|
||||
// );
|
||||
// if select_folder(context, imap, folder) == 0 {
|
||||
// dc_log_warning(
|
||||
// context,
|
||||
// 0,
|
||||
// b"Cannot select folder %s for setting $MDNSent flag.\x00" as *const u8
|
||||
// as *const libc::c_char,
|
||||
// folder,
|
||||
// );
|
||||
// } else {
|
||||
// /* Check if the folder can handle the `$MDNSent` flag (see RFC 3503). If so, and not set: set the flags and return this information.
|
||||
// If the folder cannot handle the `$MDNSent` flag, we risk duplicated MDNs; it's up to the receiving MUA to handle this then (eg. Delta Chat has no problem with this). */
|
||||
// can_create_flag = 0;
|
||||
// if !(*imap.etpan).imap_selection_info.is_null()
|
||||
// && !(*(*imap.etpan).imap_selection_info)
|
||||
// .sel_perm_flags
|
||||
// .is_null()
|
||||
// {
|
||||
// let mut iter: *mut clistiter = 0 as *mut clistiter;
|
||||
// iter = (*(*(*imap.etpan).imap_selection_info).sel_perm_flags).first;
|
||||
// while !iter.is_null() {
|
||||
// let mut fp: *mut mailimap_flag_perm = (if !iter.is_null() {
|
||||
// (*iter).data
|
||||
// } else {
|
||||
// 0 as *mut libc::c_void
|
||||
// })
|
||||
// as *mut mailimap_flag_perm;
|
||||
// if !fp.is_null() {
|
||||
// if (*fp).fl_type == MAILIMAP_FLAG_PERM_ALL as libc::c_int {
|
||||
// can_create_flag = 1;
|
||||
// break;
|
||||
// } else if (*fp).fl_type == MAILIMAP_FLAG_PERM_FLAG as libc::c_int
|
||||
// && !(*fp).fl_flag.is_null()
|
||||
// {
|
||||
// let mut fl: *mut mailimap_flag =
|
||||
// (*fp).fl_flag as *mut mailimap_flag;
|
||||
// if (*fl).fl_type == MAILIMAP_FLAG_KEYWORD as libc::c_int
|
||||
// && !(*fl).fl_data.fl_keyword.is_null()
|
||||
// && strcmp(
|
||||
// (*fl).fl_data.fl_keyword,
|
||||
// b"$MDNSent\x00" as *const u8 as *const libc::c_char,
|
||||
// ) == 0
|
||||
// {
|
||||
// can_create_flag = 1;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// iter = if !iter.is_null() {
|
||||
// (*iter).next
|
||||
// } else {
|
||||
// 0 as *mut clistcell_s
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if 0 != can_create_flag {
|
||||
// let mut r: libc::c_int = mailimap_uid_fetch(
|
||||
// imap.etpan,
|
||||
// set,
|
||||
// imap.fetch_type_flags,
|
||||
// &mut fetch_result,
|
||||
// );
|
||||
// if 0 != dc_imap_is_error(context, imap, r) || fetch_result.is_null() {
|
||||
// fetch_result = 0 as *mut clist
|
||||
// } else {
|
||||
// let mut cur: *mut clistiter = (*fetch_result).first;
|
||||
// if !cur.is_null() {
|
||||
// if 0 != peek_flag_keyword(
|
||||
// (if !cur.is_null() {
|
||||
// (*cur).data
|
||||
// } else {
|
||||
// 0 as *mut libc::c_void
|
||||
// }) as *mut mailimap_msg_att,
|
||||
// b"$MDNSent\x00" as *const u8 as *const libc::c_char,
|
||||
// ) {
|
||||
// res = DC_ALREADY_DONE;
|
||||
// current_block = 14832935472441733737;
|
||||
// } else if add_flag(
|
||||
// imap,
|
||||
// uid,
|
||||
// mailimap_flag_new_flag_keyword(dc_strdup(
|
||||
// b"$MDNSent\x00" as *const u8 as *const libc::c_char,
|
||||
// )),
|
||||
// ) == 0
|
||||
// {
|
||||
// current_block = 17044610252497760460;
|
||||
// } else {
|
||||
// res = DC_SUCCESS;
|
||||
// current_block = 14832935472441733737;
|
||||
// }
|
||||
// match current_block {
|
||||
// 17044610252497760460 => {}
|
||||
// _ => {
|
||||
// dc_log_info(
|
||||
// context,
|
||||
// 0,
|
||||
// if res as libc::c_uint
|
||||
// == DC_SUCCESS as libc::c_int as libc::c_uint
|
||||
// {
|
||||
// b"$MDNSent just set and MDN will be sent.\x00"
|
||||
// as *const u8
|
||||
// as *const libc::c_char
|
||||
// } else {
|
||||
// b"$MDNSent already set and MDN already sent.\x00"
|
||||
// as *const u8
|
||||
// as *const libc::c_char
|
||||
// },
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// res = DC_SUCCESS;
|
||||
// dc_log_info(
|
||||
// context,
|
||||
// 0,
|
||||
// b"Cannot store $MDNSent flags, risk sending duplicate MDN.\x00" as *const u8
|
||||
// as *const libc::c_char,
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if !set.is_null() {
|
||||
// mailimap_set_free(set);
|
||||
// set = 0 as *mut mailimap_set
|
||||
// }
|
||||
// if !fetch_result.is_null() {
|
||||
// mailimap_fetch_list_free(fetch_result);
|
||||
// fetch_result = 0 as *mut clist
|
||||
// }
|
||||
pub fn set_mdnsent<S: AsRef<str>>(&self, context: &dc_context_t, folder: S, uid: u32) -> usize {
|
||||
// returns 0=job should be retried later, 1=job done, 2=job done and flag just set
|
||||
let mut res = DC_RETRY_LATER;
|
||||
let mut set = format!("{}", uid);
|
||||
|
||||
// (if res as libc::c_uint == DC_RETRY_LATER as libc::c_int as libc::c_uint {
|
||||
// (if 0 != imap.should_reconnect {
|
||||
// DC_RETRY_LATER as libc::c_int
|
||||
// } else {
|
||||
// DC_FAILED as libc::c_int
|
||||
// }) as libc::c_uint
|
||||
// } else {
|
||||
// res as libc::c_uint
|
||||
// }) as dc_imap_res
|
||||
if uid == 0 {
|
||||
res = DC_FAILED;
|
||||
} else if self.is_connected() {
|
||||
let folder_c = CString::new(folder.as_ref().to_owned()).unwrap();
|
||||
unsafe {
|
||||
dc_log_info(
|
||||
context,
|
||||
0,
|
||||
b"Marking message %s/%i as $MDNSent...\x00" as *const u8 as *const libc::c_char,
|
||||
folder_c.as_ptr(),
|
||||
uid as libc::c_int,
|
||||
)
|
||||
};
|
||||
|
||||
if self.select_folder(context, Some(folder)) == 0 {
|
||||
unsafe {
|
||||
dc_log_warning(
|
||||
context,
|
||||
0,
|
||||
b"Cannot select folder %s for setting $MDNSent flag.\x00" as *const u8
|
||||
as *const libc::c_char,
|
||||
folder_c.as_ptr(),
|
||||
)
|
||||
};
|
||||
} else {
|
||||
// Check if the folder can handle the `$MDNSent` flag (see RFC 3503). If so, and not
|
||||
// set: set the flags and return this information.
|
||||
// If the folder cannot handle the `$MDNSent` flag, we risk duplicated MDNs; it's up
|
||||
// to the receiving MUA to handle this then (eg. Delta Chat has no problem with this).
|
||||
|
||||
let can_create_flag = self
|
||||
.config
|
||||
.read()
|
||||
.unwrap()
|
||||
.selected_mailbox
|
||||
.as_ref()
|
||||
.map(|mbox| {
|
||||
// empty means, everything can be stored
|
||||
mbox.permanent_flags.is_empty()
|
||||
|| mbox
|
||||
.permanent_flags
|
||||
.iter()
|
||||
.find(|flag| match flag {
|
||||
imap::types::Flag::Custom(s) => s == "$MDNSent",
|
||||
_ => false,
|
||||
})
|
||||
.is_some()
|
||||
})
|
||||
.expect("just selected folder");
|
||||
|
||||
if can_create_flag {
|
||||
let fetched_msgs = if let Some(ref mut session) = *self.session.lock().unwrap()
|
||||
{
|
||||
match session.uid_fetch(set, FETCH_FLAGS) {
|
||||
Ok(res) => Some(res),
|
||||
Err(err) => {
|
||||
eprintln!("fetch error: {:?}", err);
|
||||
None
|
||||
}
|
||||
}
|
||||
} else {
|
||||
unreachable!();
|
||||
};
|
||||
|
||||
if let Some(msgs) = fetched_msgs {
|
||||
let flag_set = msgs
|
||||
.first()
|
||||
.map(|msg| {
|
||||
msg.flags()
|
||||
.iter()
|
||||
.find(|flag| match flag {
|
||||
imap::types::Flag::Custom(s) => s == "$MDNSent",
|
||||
_ => false,
|
||||
})
|
||||
.is_some()
|
||||
})
|
||||
.unwrap_or_else(|| false);
|
||||
|
||||
res = if flag_set {
|
||||
DC_ALREADY_DONE
|
||||
} else if self.add_flag(uid, "$MDNSent") != 0 {
|
||||
DC_SUCCESS
|
||||
} else {
|
||||
res
|
||||
};
|
||||
|
||||
unsafe {
|
||||
dc_log_info(
|
||||
context,
|
||||
0,
|
||||
if res == DC_SUCCESS {
|
||||
b"$MDNSent just set and MDN will be sent.\x00" as *const u8
|
||||
as *const libc::c_char
|
||||
} else {
|
||||
b"$MDNSent already set and MDN already sent.\x00" as *const u8
|
||||
as *const libc::c_char
|
||||
},
|
||||
)
|
||||
};
|
||||
}
|
||||
} else {
|
||||
res = DC_SUCCESS;
|
||||
unsafe {
|
||||
dc_log_info(
|
||||
context,
|
||||
0,
|
||||
b"Cannot store $MDNSent flags, risk sending duplicate MDN.\x00"
|
||||
as *const u8 as *const libc::c_char,
|
||||
)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if res == DC_RETRY_LATER {
|
||||
if self.should_reconnect() {
|
||||
DC_RETRY_LATER
|
||||
} else {
|
||||
DC_FAILED
|
||||
}
|
||||
} else {
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
// only returns 0 on connection problems; we should try later again in this case *
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
use std::ffi::CStr;
|
||||
use std::time::{Duration, SystemTime};
|
||||
|
||||
use libc;
|
||||
use rand::{thread_rng, Rng};
|
||||
use std::time::{Duration, SystemTime};
|
||||
|
||||
use crate::constants::Event;
|
||||
use crate::dc_chat::*;
|
||||
@@ -660,11 +662,10 @@ unsafe fn dc_job_do_DC_JOB_MARKSEEN_MSG_ON_IMAP(
|
||||
1i32,
|
||||
)
|
||||
{
|
||||
match inbox.set_mdnsent(
|
||||
context,
|
||||
(*msg).server_folder,
|
||||
(*msg).server_uid,
|
||||
) as libc::c_uint
|
||||
let folder =
|
||||
CStr::from_ptr((*msg).server_folder).to_str().unwrap();
|
||||
match inbox.set_mdnsent(context, folder, (*msg).server_uid)
|
||||
as libc::c_uint
|
||||
{
|
||||
1 => {
|
||||
current_block = 4016212065805849280;
|
||||
@@ -717,11 +718,11 @@ unsafe fn dc_job_do_DC_JOB_MARKSEEN_MSG_ON_IMAP(
|
||||
1i32,
|
||||
)
|
||||
{
|
||||
match inbox.set_mdnsent(
|
||||
context,
|
||||
(*msg).server_folder,
|
||||
(*msg).server_uid,
|
||||
) as libc::c_uint
|
||||
let folder =
|
||||
CStr::from_ptr((*msg).server_folder).to_str().unwrap();
|
||||
|
||||
match inbox.set_mdnsent(context, folder, (*msg).server_uid)
|
||||
as libc::c_uint
|
||||
{
|
||||
1 => {
|
||||
current_block = 4016212065805849280;
|
||||
|
||||
@@ -5,7 +5,6 @@ use libc;
|
||||
use crate::dc_configure::*;
|
||||
use crate::dc_context::dc_context_t;
|
||||
use crate::dc_imap::dc_imap_t;
|
||||
use crate::dc_imap::*;
|
||||
use crate::dc_log::*;
|
||||
use crate::dc_sqlite3::*;
|
||||
use crate::dc_tools::*;
|
||||
|
||||
@@ -1283,12 +1283,6 @@ pub const MAILSMTP_AUTH_CRAM_MD5: libc::c_uint = 2;
|
||||
pub const MAILSMTP_AUTH_CHECKED: libc::c_uint = 1;
|
||||
pub const MAILSMTP_AUTH_NOT_CHECKED: libc::c_uint = 0;
|
||||
|
||||
pub type dc_imap_res = libc::c_uint;
|
||||
pub const DC_SUCCESS: dc_imap_res = 3;
|
||||
pub const DC_ALREADY_DONE: dc_imap_res = 2;
|
||||
pub const DC_RETRY_LATER: dc_imap_res = 1;
|
||||
pub const DC_FAILED: dc_imap_res = 0;
|
||||
|
||||
pub type dc_move_state_t = libc::c_uint;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
|
||||
Reference in New Issue
Block a user