mirror of
https://github.com/chatmail/core.git
synced 2026-05-16 13:26:38 +03:00
imap: fetch_from_folder
This commit is contained in:
committed by
Lars-Magnus Skog
parent
424e9db112
commit
2fd38cd533
@@ -72,8 +72,8 @@ fn main() {
|
|||||||
|
|
||||||
let ctx1 = ctx.clone();
|
let ctx1 = ctx.clone();
|
||||||
let t2 = std::thread::spawn(move || loop {
|
let t2 = std::thread::spawn(move || loop {
|
||||||
// dc_perform_smtp_jobs(&ctx1);
|
dc_perform_smtp_jobs(&ctx1);
|
||||||
// dc_perform_smtp_idle(&ctx1);
|
dc_perform_smtp_idle(&ctx1);
|
||||||
});
|
});
|
||||||
|
|
||||||
let dir = tempdir().unwrap();
|
let dir = tempdir().unwrap();
|
||||||
|
|||||||
@@ -134,10 +134,10 @@ pub fn dc_context_new(
|
|||||||
dbfile: Arc::new(RwLock::new(std::ptr::null_mut())),
|
dbfile: Arc::new(RwLock::new(std::ptr::null_mut())),
|
||||||
inbox: Arc::new(RwLock::new({
|
inbox: Arc::new(RwLock::new({
|
||||||
dc_imap_new(
|
dc_imap_new(
|
||||||
Some(cb_get_config),
|
cb_get_config,
|
||||||
Some(cb_set_config),
|
cb_set_config,
|
||||||
Some(cb_precheck_imf),
|
cb_precheck_imf,
|
||||||
Some(cb_receive_imf),
|
cb_receive_imf,
|
||||||
)
|
)
|
||||||
})),
|
})),
|
||||||
userdata,
|
userdata,
|
||||||
@@ -156,10 +156,10 @@ pub fn dc_context_new(
|
|||||||
b"SENTBOX\x00" as *const u8 as *const libc::c_char,
|
b"SENTBOX\x00" as *const u8 as *const libc::c_char,
|
||||||
b"configured_sentbox_folder\x00" as *const u8 as *const libc::c_char,
|
b"configured_sentbox_folder\x00" as *const u8 as *const libc::c_char,
|
||||||
dc_imap_new(
|
dc_imap_new(
|
||||||
Some(cb_get_config),
|
cb_get_config,
|
||||||
Some(cb_set_config),
|
cb_set_config,
|
||||||
Some(cb_precheck_imf),
|
cb_precheck_imf,
|
||||||
Some(cb_receive_imf),
|
cb_receive_imf,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
})),
|
})),
|
||||||
@@ -168,10 +168,10 @@ pub fn dc_context_new(
|
|||||||
b"MVBOX\x00" as *const u8 as *const libc::c_char,
|
b"MVBOX\x00" as *const u8 as *const libc::c_char,
|
||||||
b"configured_mvbox_folder\x00" as *const u8 as *const libc::c_char,
|
b"configured_mvbox_folder\x00" as *const u8 as *const libc::c_char,
|
||||||
dc_imap_new(
|
dc_imap_new(
|
||||||
Some(cb_get_config),
|
cb_get_config,
|
||||||
Some(cb_set_config),
|
cb_set_config,
|
||||||
Some(cb_precheck_imf),
|
cb_precheck_imf,
|
||||||
Some(cb_receive_imf),
|
cb_receive_imf,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
})),
|
})),
|
||||||
|
|||||||
268
src/dc_imap.rs
268
src/dc_imap.rs
@@ -152,6 +152,21 @@ impl Session {
|
|||||||
Session::Insecure(i) => i.fetch(sequence_set, query),
|
Session::Insecure(i) => i.fetch(sequence_set, query),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn uid_fetch<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_fetch(uid_set, query),
|
||||||
|
Session::Insecure(i) => i.uid_fetch(uid_set, query),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ImapConfig {
|
pub struct ImapConfig {
|
||||||
@@ -238,7 +253,8 @@ impl dc_imap_t {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn should_reconnect(&self) -> bool {
|
pub fn should_reconnect(&self) -> bool {
|
||||||
unimplemented!();
|
// TODO: figuer out proper handling
|
||||||
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn connect(&self, context: &dc_context_t, lp: *const dc_loginparam_t) -> libc::c_int {
|
pub fn connect(&self, context: &dc_context_t, lp: *const dc_loginparam_t) -> libc::c_int {
|
||||||
@@ -455,7 +471,7 @@ impl dc_imap_t {
|
|||||||
) -> (u32, u32) {
|
) -> (u32, u32) {
|
||||||
let key = format!("imap.mailbox.{}", folder.as_ref());
|
let key = format!("imap.mailbox.{}", folder.as_ref());
|
||||||
let val1 = unsafe {
|
let val1 = unsafe {
|
||||||
self.get_config.expect("non-null function pointer")(
|
(self.get_config)(
|
||||||
context,
|
context,
|
||||||
CString::new(key).unwrap().as_ptr(),
|
CString::new(key).unwrap().as_ptr(),
|
||||||
0 as *const libc::c_char,
|
0 as *const libc::c_char,
|
||||||
@@ -542,8 +558,7 @@ impl dc_imap_t {
|
|||||||
// id we do not do this here, we'll miss the first message
|
// id we do not do this here, we'll miss the first message
|
||||||
// as we will get in here again and fetch from lastseenuid+1 then
|
// as we will get in here again and fetch from lastseenuid+1 then
|
||||||
|
|
||||||
// TODO.
|
self.set_config_last_seen_uid(context, &folder, mailbox.uid_validity.unwrap(), 0);
|
||||||
// self.set_config_last_seen_uid(context, &folder, mailbox.exists, 0);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -593,124 +608,117 @@ impl dc_imap_t {
|
|||||||
CString::new(folder.as_ref().to_owned()).unwrap().as_ptr(),
|
CString::new(folder.as_ref().to_owned()).unwrap().as_ptr(),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut read_cnt = 0;
|
let mut read_cnt = 0;
|
||||||
|
let mut read_errors = 0;
|
||||||
|
let mut new_last_seen_uid = 0;
|
||||||
|
|
||||||
// match current_block {
|
if let Some(ref mut session) = *self.session.lock().unwrap() {
|
||||||
// 17288151659885296046 => {}
|
// fetch messages with larger UID than the last one seen
|
||||||
// _ => {
|
// (`UID FETCH lastseenuid+1:*)`, see RFC 4549
|
||||||
// set = mailimap_set_new_interval(
|
let set = format!("{}:*", last_seen_uid + 1);
|
||||||
// lastseenuid.wrapping_add(1 as libc::c_uint),
|
let query = "(UID ENVELOPE)";
|
||||||
// 0 as uint32_t,
|
println!("fetching: {} {}", set, query);
|
||||||
// );
|
let list = match session.uid_fetch(set, query) {
|
||||||
// r = mailimap_uid_fetch(
|
Ok(list) => list,
|
||||||
// imap.etpan,
|
Err(err) => {
|
||||||
// set,
|
eprintln!("fetch err: {:?}", err);
|
||||||
// imap.fetch_type_prefetch,
|
return 0;
|
||||||
// &mut fetch_result,
|
}
|
||||||
// );
|
};
|
||||||
// if !set.is_null() {
|
println!("fetched {} messages", list.len());
|
||||||
// mailimap_set_free(set);
|
// go through all mails in folder (this is typically _fast_ as we already have the whole list)
|
||||||
// set = 0 as *mut mailimap_set
|
|
||||||
// }
|
|
||||||
// if 0 != dc_imap_is_error(context, imap, r) || fetch_result.is_null() {
|
|
||||||
// fetch_result = 0 as *mut clist;
|
|
||||||
// if r == MAILIMAP_ERROR_PROTOCOL as libc::c_int {
|
|
||||||
// dc_log_info(
|
|
||||||
// context,
|
|
||||||
// 0,
|
|
||||||
// b"Folder \"%s\" is empty\x00" as *const u8 as *const libc::c_char,
|
|
||||||
// folder,
|
|
||||||
// );
|
|
||||||
// } else {
|
|
||||||
// /* the folder is simply empty, this is no error */
|
|
||||||
// dc_log_warning(
|
|
||||||
// context,
|
|
||||||
// 0,
|
|
||||||
// b"Cannot fetch message list from folder \"%s\".\x00" as *const u8
|
|
||||||
// as *const libc::c_char,
|
|
||||||
// folder,
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// cur = (*fetch_result).first;
|
|
||||||
// while !cur.is_null() {
|
|
||||||
// let mut msg_att_0: *mut mailimap_msg_att = (if !cur.is_null() {
|
|
||||||
// (*cur).data
|
|
||||||
// } else {
|
|
||||||
// 0 as *mut libc::c_void
|
|
||||||
// })
|
|
||||||
// as *mut mailimap_msg_att;
|
|
||||||
// let mut cur_uid: uint32_t = peek_uid(msg_att_0);
|
|
||||||
// if cur_uid > lastseenuid {
|
|
||||||
// let mut rfc724_mid: *mut libc::c_char =
|
|
||||||
// unquote_rfc724_mid(peek_rfc724_mid(msg_att_0));
|
|
||||||
// read_cnt = read_cnt.wrapping_add(1);
|
|
||||||
// if 0 == imap.precheck_imf.expect("non-null function pointer")(
|
|
||||||
// context, rfc724_mid, folder, cur_uid,
|
|
||||||
// ) {
|
|
||||||
// if fetch_single_msg(context, imap, folder, cur_uid) == 0 {
|
|
||||||
// dc_log_info(context, 0,
|
|
||||||
// b"Read error for message %s from \"%s\", trying over later.\x00"
|
|
||||||
// as *const u8 as
|
|
||||||
// *const libc::c_char,
|
|
||||||
// rfc724_mid, folder);
|
|
||||||
// read_errors = read_errors.wrapping_add(1)
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// dc_log_info(
|
|
||||||
// context,
|
|
||||||
// 0,
|
|
||||||
// b"Skipping message %s from \"%s\" by precheck.\x00"
|
|
||||||
// as *const u8
|
|
||||||
// as *const libc::c_char,
|
|
||||||
// rfc724_mid,
|
|
||||||
// folder,
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// if cur_uid > new_lastseenuid {
|
|
||||||
// new_lastseenuid = cur_uid
|
|
||||||
// }
|
|
||||||
// free(rfc724_mid as *mut libc::c_void);
|
|
||||||
// }
|
|
||||||
// cur = if !cur.is_null() {
|
|
||||||
// (*cur).next
|
|
||||||
// } else {
|
|
||||||
// 0 as *mut clistcell_s
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if 0 == read_errors && new_lastseenuid > 0 as libc::c_uint {
|
|
||||||
// set_config_lastseenuid(
|
|
||||||
// context,
|
|
||||||
// imap,
|
|
||||||
// folder,
|
|
||||||
// uidvalidity,
|
|
||||||
// new_lastseenuid,
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
unsafe {
|
for msg in &list {
|
||||||
dc_log_info(
|
let cur_uid = msg.uid.unwrap_or_else(|| 0);
|
||||||
context,
|
if cur_uid > last_seen_uid {
|
||||||
0i32,
|
read_cnt += 1;
|
||||||
b"%i mails read from \"%s\".\x00" as *const u8 as *const libc::c_char,
|
|
||||||
read_cnt as libc::c_int,
|
let message_id = msg
|
||||||
folder,
|
.envelope()
|
||||||
)
|
.expect("missing envelope")
|
||||||
};
|
.message_id
|
||||||
// }
|
.expect("missing message id");
|
||||||
// if !fetch_result.is_null() {
|
|
||||||
// mailimap_fetch_list_free(fetch_result);
|
let message_id_c = CString::new(message_id).unwrap();
|
||||||
// fetch_result = 0 as *mut clist
|
let folder_c = CString::new(folder.as_ref().to_owned()).unwrap();
|
||||||
// }
|
if 0 == unsafe {
|
||||||
|
(self.precheck_imf)(
|
||||||
|
context,
|
||||||
|
message_id_c.as_ptr(),
|
||||||
|
folder_c.as_ptr(),
|
||||||
|
cur_uid,
|
||||||
|
)
|
||||||
|
} {
|
||||||
|
// check passed, go fetch the rest
|
||||||
|
if self.fetch_single_msg(context, &folder, cur_uid) == 0 {
|
||||||
|
unsafe {
|
||||||
|
dc_log_info(
|
||||||
|
context,
|
||||||
|
0,
|
||||||
|
b"Read error for message %s from \"%s\", trying over later.\x00"
|
||||||
|
as *const u8
|
||||||
|
as *const libc::c_char,
|
||||||
|
message_id_c.as_ptr(),
|
||||||
|
folder_c.as_ptr(),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
read_errors += 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// check failed
|
||||||
|
unsafe {
|
||||||
|
dc_log_info(
|
||||||
|
context,
|
||||||
|
0,
|
||||||
|
b"Skipping message %s from \"%s\" by precheck.\x00" as *const u8
|
||||||
|
as *const libc::c_char,
|
||||||
|
message_id_c.as_ptr(),
|
||||||
|
folder_c.as_ptr(),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if cur_uid > new_last_seen_uid {
|
||||||
|
new_last_seen_uid = cur_uid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if 0 == read_errors && new_last_seen_uid > 0 {
|
||||||
|
// TODO: it might be better to increase the lastseenuid also on partial errors.
|
||||||
|
// however, this requires to sort the list before going through it above.
|
||||||
|
self.set_config_last_seen_uid(context, &folder, uid_validity, new_last_seen_uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
if read_errors > 0 {
|
||||||
|
unsafe {
|
||||||
|
dc_log_warning(
|
||||||
|
context,
|
||||||
|
0i32,
|
||||||
|
b"%i mails read from \"%s\" with %i errors.\x00" as *const u8
|
||||||
|
as *const libc::c_char,
|
||||||
|
read_cnt as libc::c_int,
|
||||||
|
CString::new(folder.as_ref().to_owned()).unwrap().as_ptr(),
|
||||||
|
read_errors as libc::c_int,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
unsafe {
|
||||||
|
dc_log_info(
|
||||||
|
context,
|
||||||
|
0i32,
|
||||||
|
b"%i mails read from \"%s\".\x00" as *const u8 as *const libc::c_char,
|
||||||
|
read_cnt as libc::c_int,
|
||||||
|
CString::new(folder.as_ref().to_owned()).unwrap().as_ptr(),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
read_cnt
|
read_cnt
|
||||||
}
|
}
|
||||||
@@ -722,27 +730,23 @@ impl dc_imap_t {
|
|||||||
uidvalidity: u32,
|
uidvalidity: u32,
|
||||||
lastseenuid: u32,
|
lastseenuid: u32,
|
||||||
) {
|
) {
|
||||||
unimplemented!()
|
let key = format!("imap.mailbox.{}", folder.as_ref());
|
||||||
}
|
let val = format!("{}:{}", uidvalidity, lastseenuid);
|
||||||
// let mut key: *mut libc::c_char = dc_mprintf(
|
|
||||||
// b"imap.mailbox.%s\x00" as *const u8 as *const libc::c_char,
|
|
||||||
// folder,
|
|
||||||
// );
|
|
||||||
// let mut val: *mut libc::c_char = dc_mprintf(
|
|
||||||
// b"%lu:%lu\x00" as *const u8 as *const libc::c_char,
|
|
||||||
// uidvalidity,
|
|
||||||
// lastseenuid,
|
|
||||||
// );
|
|
||||||
// imap.set_config.expect("non-null function pointer")(context, key, val);
|
|
||||||
// free(val as *mut libc::c_void);
|
|
||||||
// free(key as *mut libc::c_void);
|
|
||||||
// }
|
|
||||||
|
|
||||||
fn fetch_single_msg(
|
unsafe {
|
||||||
|
(self.set_config)(
|
||||||
|
context,
|
||||||
|
CString::new(key).unwrap().as_ptr(),
|
||||||
|
CString::new(val).unwrap().as_ptr(),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fetch_single_msg<S: AsRef<str>>(
|
||||||
&self,
|
&self,
|
||||||
context: &dc_context_t,
|
context: &dc_context_t,
|
||||||
folder: *const libc::c_char,
|
folder: S,
|
||||||
server_uid: uint32_t,
|
server_uid: u32,
|
||||||
) -> usize {
|
) -> usize {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
|
|||||||
46
src/types.rs
46
src/types.rs
@@ -1167,38 +1167,32 @@ pub type blkcnt_t = libc::blkcnt_t;
|
|||||||
pub type blksize_t = libc::blksize_t;
|
pub type blksize_t = libc::blksize_t;
|
||||||
pub type nlink_t = __uint16_t;
|
pub type nlink_t = __uint16_t;
|
||||||
|
|
||||||
pub type dc_receive_imf_t = Option<
|
pub type dc_receive_imf_t = unsafe fn(
|
||||||
unsafe fn(
|
_: &dc_context_t,
|
||||||
_: &dc_context_t,
|
_: *const libc::c_char,
|
||||||
_: *const libc::c_char,
|
_: size_t,
|
||||||
_: size_t,
|
_: *const libc::c_char,
|
||||||
_: *const libc::c_char,
|
_: uint32_t,
|
||||||
_: uint32_t,
|
_: uint32_t,
|
||||||
_: uint32_t,
|
) -> ();
|
||||||
) -> (),
|
|
||||||
>;
|
|
||||||
|
|
||||||
/* Purpose: Reading from IMAP servers with no dependencies to the database.
|
/* Purpose: Reading from IMAP servers with no dependencies to the database.
|
||||||
dc_context_t is only used for logging and to get information about
|
dc_context_t is only used for logging and to get information about
|
||||||
the online state. */
|
the online state. */
|
||||||
|
|
||||||
pub type dc_precheck_imf_t = Option<
|
pub type dc_precheck_imf_t = unsafe fn(
|
||||||
unsafe fn(
|
_: &dc_context_t,
|
||||||
_: &dc_context_t,
|
_: *const libc::c_char,
|
||||||
_: *const libc::c_char,
|
_: *const libc::c_char,
|
||||||
_: *const libc::c_char,
|
_: u32,
|
||||||
_: uint32_t,
|
) -> libc::c_int;
|
||||||
) -> libc::c_int,
|
|
||||||
>;
|
|
||||||
pub type dc_set_config_t =
|
pub type dc_set_config_t =
|
||||||
Option<unsafe fn(_: &dc_context_t, _: *const libc::c_char, _: *const libc::c_char) -> ()>;
|
unsafe fn(_: &dc_context_t, _: *const libc::c_char, _: *const libc::c_char) -> ();
|
||||||
pub type dc_get_config_t = Option<
|
pub type dc_get_config_t = unsafe fn(
|
||||||
unsafe fn(
|
_: &dc_context_t,
|
||||||
_: &dc_context_t,
|
_: *const libc::c_char,
|
||||||
_: *const libc::c_char,
|
_: *const libc::c_char,
|
||||||
_: *const libc::c_char,
|
) -> *mut libc::c_char;
|
||||||
) -> *mut libc::c_char,
|
|
||||||
>;
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn isascii(mut _c: libc::c_int) -> libc::c_int {
|
pub unsafe fn isascii(mut _c: libc::c_int) -> libc::c_int {
|
||||||
|
|||||||
Reference in New Issue
Block a user