mirror of
https://github.com/chatmail/core.git
synced 2026-05-05 14:26:30 +03:00
more imap functionality
This commit is contained in:
committed by
Lars-Magnus Skog
parent
e7d72dfdd4
commit
f559c92008
@@ -88,6 +88,8 @@ pub const DC_TEXT1_DRAFT: usize = 1;
|
|||||||
pub const DC_TEXT1_USERNAME: usize = 2;
|
pub const DC_TEXT1_USERNAME: usize = 2;
|
||||||
pub const DC_TEXT1_SELF: usize = 3;
|
pub const DC_TEXT1_SELF: usize = 3;
|
||||||
|
|
||||||
|
pub const DC_CREATE_MVBOX: usize = 1;
|
||||||
|
|
||||||
/// Text message.
|
/// Text message.
|
||||||
/// The text of the message is set using dc_msg_set_text()
|
/// The text of the message is set using dc_msg_set_text()
|
||||||
/// and retrieved with dc_msg_get_text().
|
/// and retrieved with dc_msg_get_text().
|
||||||
|
|||||||
545
src/dc_imap.rs
545
src/dc_imap.rs
@@ -1,4 +1,4 @@
|
|||||||
use std::ffi::CStr;
|
use std::ffi::{CStr, CString};
|
||||||
use std::sync::{Arc, Condvar, Mutex, RwLock};
|
use std::sync::{Arc, Condvar, Mutex, RwLock};
|
||||||
use std::time::{Duration, SystemTime};
|
use std::time::{Duration, SystemTime};
|
||||||
|
|
||||||
@@ -8,6 +8,7 @@ use crate::constants::*;
|
|||||||
use crate::dc_context::dc_context_t;
|
use crate::dc_context::dc_context_t;
|
||||||
use crate::dc_log::*;
|
use crate::dc_log::*;
|
||||||
use crate::dc_loginparam::*;
|
use crate::dc_loginparam::*;
|
||||||
|
use crate::dc_sqlite3::*;
|
||||||
use crate::dc_tools::*;
|
use crate::dc_tools::*;
|
||||||
use crate::types::*;
|
use crate::types::*;
|
||||||
use crate::x::*;
|
use crate::x::*;
|
||||||
@@ -105,6 +106,37 @@ impl Session {
|
|||||||
Session::Insecure(i) => i.list(reference_name, mailbox_pattern),
|
Session::Insecure(i) => i.list(reference_name, mailbox_pattern),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn create<S: AsRef<str>>(&mut self, mailbox_name: S) -> imap::error::Result<()> {
|
||||||
|
match self {
|
||||||
|
Session::Secure(i) => i.subscribe(mailbox_name),
|
||||||
|
Session::Insecure(i) => i.subscribe(mailbox_name),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn subscribe<S: AsRef<str>>(&mut self, mailbox: S) -> imap::error::Result<()> {
|
||||||
|
match self {
|
||||||
|
Session::Secure(i) => i.subscribe(mailbox),
|
||||||
|
Session::Insecure(i) => i.subscribe(mailbox),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn close(&mut self) -> imap::error::Result<()> {
|
||||||
|
match self {
|
||||||
|
Session::Secure(i) => i.close(),
|
||||||
|
Session::Insecure(i) => i.close(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn select<S: AsRef<str>>(
|
||||||
|
&mut self,
|
||||||
|
mailbox_name: S,
|
||||||
|
) -> imap::error::Result<imap::types::Mailbox> {
|
||||||
|
match self {
|
||||||
|
Session::Secure(i) => i.select(mailbox_name),
|
||||||
|
Session::Insecure(i) => i.select(mailbox_name),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ImapConfig {
|
pub struct ImapConfig {
|
||||||
@@ -116,13 +148,13 @@ pub struct ImapConfig {
|
|||||||
pub server_flags: Option<usize>,
|
pub server_flags: Option<usize>,
|
||||||
pub connected: i32,
|
pub connected: i32,
|
||||||
pub idle_set_up: i32,
|
pub idle_set_up: i32,
|
||||||
pub selected_folder: *mut libc::c_char,
|
pub selected_folder: Option<String>,
|
||||||
pub selected_folder_needs_expunge: i32,
|
pub selected_folder_needs_expunge: bool,
|
||||||
pub should_reconnect: i32,
|
pub should_reconnect: i32,
|
||||||
pub can_idle: i32,
|
pub can_idle: i32,
|
||||||
pub has_xlist: i32,
|
pub has_xlist: i32,
|
||||||
pub imap_delimiter: libc::c_char,
|
pub imap_delimiter: char,
|
||||||
pub watch_folder: *mut libc::c_char,
|
pub watch_folder: Option<String>,
|
||||||
pub fetch_type_prefetch: *mut mailimap_fetch_type,
|
pub fetch_type_prefetch: *mut mailimap_fetch_type,
|
||||||
pub fetch_type_body: *mut mailimap_fetch_type,
|
pub fetch_type_body: *mut mailimap_fetch_type,
|
||||||
pub fetch_type_flags: *mut mailimap_fetch_type,
|
pub fetch_type_flags: *mut mailimap_fetch_type,
|
||||||
@@ -141,13 +173,13 @@ impl Default for ImapConfig {
|
|||||||
server_flags: None,
|
server_flags: None,
|
||||||
connected: 0,
|
connected: 0,
|
||||||
idle_set_up: 0,
|
idle_set_up: 0,
|
||||||
selected_folder: unsafe { calloc(1, 1) as *mut libc::c_char },
|
selected_folder: None,
|
||||||
selected_folder_needs_expunge: 0,
|
selected_folder_needs_expunge: false,
|
||||||
should_reconnect: 0,
|
should_reconnect: 0,
|
||||||
can_idle: 0,
|
can_idle: 0,
|
||||||
has_xlist: 0,
|
has_xlist: 0,
|
||||||
imap_delimiter: 0 as libc::c_char,
|
imap_delimiter: '.',
|
||||||
watch_folder: unsafe { calloc(1, 1) as *mut libc::c_char },
|
watch_folder: None,
|
||||||
fetch_type_prefetch: unsafe { mailimap_fetch_type_new_fetch_att_list_empty() },
|
fetch_type_prefetch: unsafe { mailimap_fetch_type_new_fetch_att_list_empty() },
|
||||||
fetch_type_body: unsafe { mailimap_fetch_type_new_fetch_att_list_empty() },
|
fetch_type_body: unsafe { mailimap_fetch_type_new_fetch_att_list_empty() },
|
||||||
fetch_type_flags: unsafe { mailimap_fetch_type_new_fetch_att_list_empty() },
|
fetch_type_flags: unsafe { mailimap_fetch_type_new_fetch_att_list_empty() },
|
||||||
@@ -406,76 +438,155 @@ impl dc_imap_t {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
pub fn set_watch_folder(&self, watch_folder: *const libc::c_char) {
|
pub fn set_watch_folder(&self, watch_folder: *const libc::c_char) {
|
||||||
unimplemented!()
|
self.config.write().unwrap().watch_folder = Some(to_string(watch_folder));
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub unsafe extern "C" fn dc_imap_set_watch_folder(
|
|
||||||
// imap: &dc_imap_t,
|
|
||||||
// watch_folder: *const libc::c_char,
|
|
||||||
// ) {
|
|
||||||
// if watch_folder.is_null() {
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// free(imap.watch_folder as *mut libc::c_void);
|
|
||||||
// imap.watch_folder = dc_strdup(watch_folder);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// pub unsafe fn dc_imap_is_connected(imap: &dc_imap_t) -> libc::c_int {
|
|
||||||
// (0 != imap.connected) as libc::c_int
|
|
||||||
// }
|
|
||||||
|
|
||||||
pub fn fetch(&self, context: &dc_context_t) -> libc::c_int {
|
pub fn fetch(&self, context: &dc_context_t) -> libc::c_int {
|
||||||
unimplemented!()
|
println!("dc_imap_fetch");
|
||||||
|
let mut success = 0;
|
||||||
|
|
||||||
|
let watch_folder = self.config.read().unwrap().watch_folder.to_owned();
|
||||||
|
if self.is_connected() && watch_folder.is_some() {
|
||||||
|
let watch_folder = watch_folder.unwrap();
|
||||||
|
loop {
|
||||||
|
let cnt = self.fetch_from_single_folder(context, &watch_folder);
|
||||||
|
if cnt == 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
success = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub unsafe fn dc_imap_fetch(context: &dc_context_t, imap: &dc_imap_t) -> libc::c_int {
|
println!("dc_imap_fetch done {}", success);
|
||||||
// println!("dc_imap_fetch");
|
success
|
||||||
// let mut success = 0;
|
}
|
||||||
// if 0 != imap.connected {
|
|
||||||
// setup_handle_if_needed(context, imap);
|
|
||||||
// let mut cnt = fetch_from_single_folder(context, imap, imap.watch_folder);
|
|
||||||
// while cnt > 0 {
|
|
||||||
// println!(" -- fetching {}", cnt);
|
|
||||||
// cnt = fetch_from_single_folder(context, imap, imap.watch_folder);
|
|
||||||
// }
|
|
||||||
// success = 1;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// println!("dc_imap_fetch done {}", success);
|
fn select_folder<S: AsRef<str>>(&self, context: &dc_context_t, folder: Option<S>) -> usize {
|
||||||
// success
|
if !self.is_connected() {
|
||||||
// }
|
let mut cfg = self.config.write().unwrap();
|
||||||
|
cfg.selected_folder = None;
|
||||||
|
cfg.selected_folder_needs_expunge = false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn fetch_from_single_folder(
|
// 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 {
|
||||||
|
if let Some(ref selected_folder) = self.config.read().unwrap().selected_folder {
|
||||||
|
if folder.as_ref() == selected_folder {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 {
|
||||||
|
if let Some(ref folder) = self.config.read().unwrap().selected_folder {
|
||||||
|
unsafe {
|
||||||
|
dc_log_info(
|
||||||
|
context,
|
||||||
|
0,
|
||||||
|
b"Expunge messages in \"%s\".\x00" as *const u8 as *const libc::c_char,
|
||||||
|
CString::new(folder.to_owned()).unwrap().as_ptr(),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
// a CLOSE-SELECT is considerably faster than an EXPUNGE-SELECT, see https://tools.ietf.org/html/rfc3501#section-6.4.2
|
||||||
|
if let Some(ref mut session) = *self.session.lock().unwrap() {
|
||||||
|
session.close().expect("failed to expunge");
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// select new folder
|
||||||
|
if let Some(folder) = folder {
|
||||||
|
if let Some(ref mut session) = *self.session.lock().unwrap() {
|
||||||
|
match session.select(folder) {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(err) => {
|
||||||
|
eprintln!("select error: {:?}", err);
|
||||||
|
unsafe {
|
||||||
|
dc_log_info(
|
||||||
|
context,
|
||||||
|
0,
|
||||||
|
b"Cannot select folder.\x00" as *const u8 as *const libc::c_char,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
self.config.write().unwrap().selected_folder = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
1
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_config_last_seen_uid<S: AsRef<str>>(
|
||||||
&self,
|
&self,
|
||||||
context: &dc_context_t,
|
context: &dc_context_t,
|
||||||
folder: *const libc::c_char,
|
folder: S,
|
||||||
) -> libc::c_int {
|
) -> (usize, usize) {
|
||||||
unimplemented!()
|
let key = format!("imap.mailbox.{}", folder.as_ref());
|
||||||
|
let val1 = unsafe {
|
||||||
|
self.get_config.expect("non-null function pointer")(
|
||||||
|
context,
|
||||||
|
CString::new(key).unwrap().as_ptr(),
|
||||||
|
0 as *const libc::c_char,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
if val1.is_null() {
|
||||||
|
return (0, 0);
|
||||||
|
}
|
||||||
|
let entry = to_str(val1);
|
||||||
|
|
||||||
|
// the entry has the format `imap.mailbox.<folder>=<uidvalidity>:<lastseenuid>`
|
||||||
|
let mut parts = entry.split(':');
|
||||||
|
(
|
||||||
|
parts.next().unwrap().parse().unwrap_or_else(|_| 0),
|
||||||
|
parts.next().unwrap().parse().unwrap_or_else(|_| 0),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// unsafe fn fetch_from_single_folder(
|
fn fetch_from_single_folder<S: AsRef<str>>(&self, context: &dc_context_t, folder: S) -> usize {
|
||||||
// context: &dc_context_t,
|
println!("fetching from single folder");
|
||||||
// imap: &dc_imap_t,
|
if !self.is_connected() {
|
||||||
// folder: *const libc::c_char,
|
unsafe {
|
||||||
// ) -> libc::c_int {
|
dc_log_info(
|
||||||
// let mut current_block: u64;
|
context,
|
||||||
// let mut r: libc::c_int = 0;
|
0,
|
||||||
// let mut uidvalidity: uint32_t = 0 as uint32_t;
|
b"Cannot fetch from \"%s\" - not connected.\x00" as *const u8
|
||||||
// let mut lastseenuid: uint32_t = 0 as uint32_t;
|
as *const libc::c_char,
|
||||||
// let mut new_lastseenuid: uint32_t = 0 as uint32_t;
|
CString::new(folder.as_ref().to_owned()).unwrap().as_ptr(),
|
||||||
// let mut fetch_result: *mut clist = 0 as *mut clist;
|
)
|
||||||
// let mut read_cnt: size_t = 0 as size_t;
|
};
|
||||||
// let mut read_errors: size_t = 0 as size_t;
|
|
||||||
// let mut cur: *mut clistiter = 0 as *mut clistiter;
|
return 0;
|
||||||
// let mut set: *mut mailimap_set = 0 as *mut mailimap_set;
|
}
|
||||||
// if imap.etpan.is_null() {
|
|
||||||
// dc_log_info(
|
if self.select_folder(context, Some(&folder)) == 0 {
|
||||||
// context,
|
unsafe {
|
||||||
// 0,
|
dc_log_info(
|
||||||
// b"Cannot fetch from \"%s\" - not connected.\x00" as *const u8
|
context,
|
||||||
// as *const libc::c_char,
|
0,
|
||||||
// folder,
|
b"Cannot select folder \"%s\" for fetching.\x00" as *const u8
|
||||||
// );
|
as *const libc::c_char,
|
||||||
|
CString::new(folder.as_ref().to_owned()).unwrap().as_ptr(),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("selected folder {}", folder.as_ref());
|
||||||
|
|
||||||
|
let (uid_validity, last_seen_uid) = self.get_config_last_seen_uid(context, &folder);
|
||||||
|
|
||||||
|
println!("got validity: {} - {}", uid_validity, last_seen_uid);
|
||||||
|
|
||||||
|
0
|
||||||
// } else if select_folder(context, imap, folder) == 0 {
|
// } else if select_folder(context, imap, folder) == 0 {
|
||||||
// dc_log_warning(
|
// dc_log_warning(
|
||||||
// context,
|
// context,
|
||||||
@@ -756,7 +867,7 @@ impl dc_imap_t {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
// read_cnt as libc::c_int
|
// read_cnt as libc::c_int
|
||||||
// }
|
}
|
||||||
|
|
||||||
// unsafe fn set_config_lastseenuid(
|
// unsafe fn set_config_lastseenuid(
|
||||||
// context: &dc_context_t,
|
// context: &dc_context_t,
|
||||||
@@ -1024,100 +1135,6 @@ impl dc_imap_t {
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// unsafe fn get_config_lastseenuid(
|
|
||||||
// context: &dc_context_t,
|
|
||||||
// imap: &dc_imap_t,
|
|
||||||
// folder: *const libc::c_char,
|
|
||||||
// uidvalidity: *mut uint32_t,
|
|
||||||
// lastseenuid: *mut uint32_t,
|
|
||||||
// ) {
|
|
||||||
// *uidvalidity = 0 as uint32_t;
|
|
||||||
// *lastseenuid = 0 as uint32_t;
|
|
||||||
// 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 val1: *mut libc::c_char = imap.get_config.expect("non-null function pointer")(
|
|
||||||
// context,
|
|
||||||
// key,
|
|
||||||
// 0 as *const libc::c_char,
|
|
||||||
// );
|
|
||||||
// let mut val2: *mut libc::c_char = 0 as *mut libc::c_char;
|
|
||||||
// let mut val3: *mut libc::c_char = 0 as *mut libc::c_char;
|
|
||||||
// if !val1.is_null() {
|
|
||||||
// val2 = strchr(val1, ':' as i32);
|
|
||||||
// if !val2.is_null() {
|
|
||||||
// *val2 = 0 as libc::c_char;
|
|
||||||
// val2 = val2.offset(1isize);
|
|
||||||
// val3 = strchr(val2, ':' as i32);
|
|
||||||
// if !val3.is_null() {
|
|
||||||
// *val3 = 0 as libc::c_char
|
|
||||||
// }
|
|
||||||
// *uidvalidity = atol(val1) as uint32_t;
|
|
||||||
// *lastseenuid = atol(val2) as uint32_t
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// free(val1 as *mut libc::c_void);
|
|
||||||
// free(key as *mut libc::c_void);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /* ******************************************************************************
|
|
||||||
// * Handle folders
|
|
||||||
// ******************************************************************************/
|
|
||||||
// unsafe fn select_folder(
|
|
||||||
// context: &dc_context_t,
|
|
||||||
// imap: &dc_imap_t,
|
|
||||||
// folder: *const libc::c_char,
|
|
||||||
// ) -> libc::c_int {
|
|
||||||
// if imap.etpan.is_null() {
|
|
||||||
// *imap.selected_folder.offset(0isize) = 0 as libc::c_char;
|
|
||||||
// imap.selected_folder_needs_expunge = 0;
|
|
||||||
// return 0;
|
|
||||||
// }
|
|
||||||
// if !folder.is_null()
|
|
||||||
// && 0 != *folder.offset(0isize) as libc::c_int
|
|
||||||
// && strcmp(imap.selected_folder, folder) == 0
|
|
||||||
// {
|
|
||||||
// return 1;
|
|
||||||
// }
|
|
||||||
// if 0 != imap.selected_folder_needs_expunge {
|
|
||||||
// if 0 != *imap.selected_folder.offset(0isize) {
|
|
||||||
// dc_log_info(
|
|
||||||
// context,
|
|
||||||
// 0,
|
|
||||||
// b"Expunge messages in \"%s\".\x00" as *const u8 as *const libc::c_char,
|
|
||||||
// imap.selected_folder,
|
|
||||||
// );
|
|
||||||
// mailimap_close(imap.etpan);
|
|
||||||
// }
|
|
||||||
// imap.selected_folder_needs_expunge = 0
|
|
||||||
// }
|
|
||||||
// if !folder.is_null() {
|
|
||||||
// let mut r: libc::c_int = mailimap_select(imap.etpan, folder);
|
|
||||||
// if 0 != dc_imap_is_error(context, imap, r)
|
|
||||||
// || (*imap.etpan).imap_selection_info.is_null()
|
|
||||||
// {
|
|
||||||
// dc_log_info(
|
|
||||||
// context,
|
|
||||||
// 0,
|
|
||||||
// b"Cannot select folder; code=%i, imap_response=%s\x00" as *const u8
|
|
||||||
// as *const libc::c_char,
|
|
||||||
// r,
|
|
||||||
// if !(*imap.etpan).imap_response.is_null() {
|
|
||||||
// (*imap.etpan).imap_response
|
|
||||||
// } else {
|
|
||||||
// b"<none>\x00" as *const u8 as *const libc::c_char
|
|
||||||
// },
|
|
||||||
// );
|
|
||||||
// *imap.selected_folder.offset(0isize) = 0 as libc::c_char;
|
|
||||||
// return 0;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// free(imap.selected_folder as *mut libc::c_void);
|
|
||||||
// imap.selected_folder = dc_strdup(folder);
|
|
||||||
// 1
|
|
||||||
// }
|
|
||||||
|
|
||||||
pub fn idle(&self, context: &dc_context_t) {
|
pub fn idle(&self, context: &dc_context_t) {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
println!("starting to idle");
|
println!("starting to idle");
|
||||||
@@ -1880,100 +1897,115 @@ impl dc_imap_t {
|
|||||||
let delimiter = self.config.read().unwrap().imap_delimiter;
|
let delimiter = self.config.read().unwrap().imap_delimiter;
|
||||||
let fallback_folder = format!("INBOX{}DeltaChat", delimiter);
|
let fallback_folder = format!("INBOX{}DeltaChat", delimiter);
|
||||||
|
|
||||||
for folder in folders.iter() {
|
let mut mvbox_folder = folders
|
||||||
let meaning = get_folder_meaning(folder);
|
.iter()
|
||||||
println!("{} - {:?}", folder.name(), meaning);
|
.find(|folder| folder.name() == "DeltaChat" || folder.name() == fallback_folder)
|
||||||
|
.map(|n| n.name().to_string());
|
||||||
|
|
||||||
|
let mut sentbox_folder = folders
|
||||||
|
.iter()
|
||||||
|
.find(|folder| match get_folder_meaning(folder) {
|
||||||
|
FolderMeaning::SentObjects => true,
|
||||||
|
_ => false,
|
||||||
|
});
|
||||||
|
|
||||||
|
println!("folders: {:?} - {:?}", mvbox_folder, sentbox_folder);
|
||||||
|
|
||||||
|
if mvbox_folder.is_none() && 0 != (flags as usize & DC_CREATE_MVBOX) {
|
||||||
|
unsafe {
|
||||||
|
dc_log_info(
|
||||||
|
context,
|
||||||
|
0i32,
|
||||||
|
b"Creating MVBOX-folder \"%s\"...\x00" as *const u8 as *const libc::c_char,
|
||||||
|
b"DeltaChat\x00" as *const u8 as *const libc::c_char,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(ref mut session) = *self.session.lock().unwrap() {
|
||||||
|
match session.create("DeltaChat") {
|
||||||
|
Ok(_) => {
|
||||||
|
mvbox_folder = Some("DeltaChat".into());
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
dc_log_info(
|
||||||
|
context,
|
||||||
|
0i32,
|
||||||
|
b"MVBOX-folder created.\x00" as *const u8 as *const libc::c_char,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
eprintln!("create error: {:?}", err);
|
||||||
|
unsafe {
|
||||||
|
dc_log_warning(
|
||||||
|
context,
|
||||||
|
0,
|
||||||
|
b"Cannot create MVBOX-folder, using trying INBOX subfolder.\x00"
|
||||||
|
as *const u8
|
||||||
|
as *const libc::c_char,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
match session.create(&fallback_folder) {
|
||||||
|
Ok(_) => {
|
||||||
|
mvbox_folder = Some(fallback_folder);
|
||||||
|
unsafe {
|
||||||
|
dc_log_info(
|
||||||
|
context,
|
||||||
|
0,
|
||||||
|
b"MVBOX-folder created as INBOX subfolder.\x00" as *const u8
|
||||||
|
as *const libc::c_char,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
eprintln!("create error: {:?}", err);
|
||||||
|
unsafe {
|
||||||
|
dc_log_warning(
|
||||||
|
context,
|
||||||
|
0i32,
|
||||||
|
b"Cannot create MVBOX-folder.\x00" as *const u8
|
||||||
|
as *const libc::c_char,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// SUBSCRIBE is needed to make the folder visible to the LSUB command
|
||||||
|
// that may be used by other MUAs to list folders.
|
||||||
|
// for the LIST command, the folder is always visible.
|
||||||
|
if let Some(ref mvbox) = mvbox_folder {
|
||||||
|
// TODO: better error handling
|
||||||
|
session.subscribe(mvbox).expect("failed to subscribe");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
dc_sqlite3_set_config_int(
|
||||||
|
context,
|
||||||
|
&context.sql.read().unwrap(),
|
||||||
|
b"folders_configured\x00" as *const u8 as *const libc::c_char,
|
||||||
|
3,
|
||||||
|
);
|
||||||
|
if let Some(ref mvbox_folder) = mvbox_folder {
|
||||||
|
dc_sqlite3_set_config(
|
||||||
|
context,
|
||||||
|
&context.sql.read().unwrap(),
|
||||||
|
b"configured_mvbox_folder\x00" as *const u8 as *const libc::c_char,
|
||||||
|
CString::new(mvbox_folder.clone()).unwrap().as_ptr(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if let Some(ref sentbox_folder) = sentbox_folder {
|
||||||
|
dc_sqlite3_set_config(
|
||||||
|
context,
|
||||||
|
&context.sql.read().unwrap(),
|
||||||
|
b"configured_sentbox_folder\x00" as *const u8 as *const libc::c_char,
|
||||||
|
CString::new(sentbox_folder.name()).unwrap().as_ptr(),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// let iter = (*folder_list).first;
|
|
||||||
// while !iter.is_null() {
|
|
||||||
// let mut folder: *mut dc_imapfolder_t = (if !iter.is_null() {
|
|
||||||
// (*iter).data
|
|
||||||
// } else {
|
|
||||||
// 0 as *mut libc::c_void
|
|
||||||
// }) as *mut dc_imapfolder_t;
|
|
||||||
// if strcmp(
|
|
||||||
// (*folder).name_utf8,
|
|
||||||
// b"DeltaChat\x00" as *const u8 as *const libc::c_char,
|
|
||||||
// ) == 0i32
|
|
||||||
// || strcmp((*folder).name_utf8, fallback_folder) == 0i32
|
|
||||||
// {
|
|
||||||
// if mvbox_folder.is_null() {
|
|
||||||
// mvbox_folder = dc_strdup((*folder).name_to_select)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if (*folder).meaning == 1i32 {
|
|
||||||
// if sentbox_folder.is_null() {
|
|
||||||
// sentbox_folder = dc_strdup((*folder).name_to_select)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// iter = if !iter.is_null() {
|
|
||||||
// (*iter).next
|
|
||||||
// } else {
|
|
||||||
// 0 as *mut clistcell_s
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if mvbox_folder.is_null() && 0 != flags & 0x1i32 {
|
|
||||||
// dc_log_info(
|
|
||||||
// context,
|
|
||||||
// 0i32,
|
|
||||||
// b"Creating MVBOX-folder \"%s\"...\x00" as *const u8 as *const libc::c_char,
|
|
||||||
// b"DeltaChat\x00" as *const u8 as *const libc::c_char,
|
|
||||||
// );
|
|
||||||
// let mut r: libc::c_int = mailimap_create(
|
|
||||||
// (*imap).etpan,
|
|
||||||
// b"DeltaChat\x00" as *const u8 as *const libc::c_char,
|
|
||||||
// );
|
|
||||||
// if 0 != dc_imap_is_error(context, imap, r) {
|
|
||||||
// dc_log_warning(
|
|
||||||
// context,
|
|
||||||
// 0i32,
|
|
||||||
// b"Cannot create MVBOX-folder, using trying INBOX subfolder.\x00" as *const u8
|
|
||||||
// as *const libc::c_char,
|
|
||||||
// );
|
|
||||||
// r = mailimap_create((*imap).etpan, fallback_folder);
|
|
||||||
// if 0 != dc_imap_is_error(context, imap, r) {
|
|
||||||
// dc_log_warning(
|
|
||||||
// context,
|
|
||||||
// 0i32,
|
|
||||||
// b"Cannot create MVBOX-folder.\x00" as *const u8 as *const libc::c_char,
|
|
||||||
// );
|
|
||||||
// } else {
|
|
||||||
// mvbox_folder = dc_strdup(fallback_folder);
|
|
||||||
// dc_log_info(
|
|
||||||
// context,
|
|
||||||
// 0i32,
|
|
||||||
// b"MVBOX-folder created as INBOX subfolder.\x00" as *const u8
|
|
||||||
// as *const libc::c_char,
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// mvbox_folder = dc_strdup(b"DeltaChat\x00" as *const u8 as *const libc::c_char);
|
|
||||||
// dc_log_info(
|
|
||||||
// context,
|
|
||||||
// 0i32,
|
|
||||||
// b"MVBOX-folder created.\x00" as *const u8 as *const libc::c_char,
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// mailimap_subscribe((*imap).etpan, mvbox_folder);
|
|
||||||
// }
|
|
||||||
// dc_sqlite3_set_config_int(
|
|
||||||
// context,
|
|
||||||
// &context.sql.clone().read().unwrap(),
|
|
||||||
// b"folders_configured\x00" as *const u8 as *const libc::c_char,
|
|
||||||
// 3i32,
|
|
||||||
// );
|
|
||||||
// dc_sqlite3_set_config(
|
|
||||||
// context,
|
|
||||||
// &context.sql.clone().read().unwrap(),
|
|
||||||
// b"configured_mvbox_folder\x00" as *const u8 as *const libc::c_char,
|
|
||||||
// mvbox_folder,
|
|
||||||
// );
|
|
||||||
// dc_sqlite3_set_config(
|
|
||||||
// context,
|
|
||||||
// &context.sql.clone().read().unwrap(),
|
|
||||||
// b"configured_sentbox_folder\x00" as *const u8 as *const libc::c_char,
|
|
||||||
// sentbox_folder,
|
|
||||||
// );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn list_folders(
|
fn list_folders(
|
||||||
@@ -2047,7 +2079,6 @@ fn get_folder_meaning(folder_name: &imap::types::Name) -> FolderMeaning {
|
|||||||
let special_names = vec!["\\Spam", "\\Trash", "\\Drafts", "\\Junk"];
|
let special_names = vec!["\\Spam", "\\Trash", "\\Drafts", "\\Junk"];
|
||||||
|
|
||||||
for attr in folder_name.attributes() {
|
for attr in folder_name.attributes() {
|
||||||
println!("attr: {:?} - {}", attr, folder_name.name());
|
|
||||||
match attr {
|
match attr {
|
||||||
imap::types::NameAttribute::Custom(ref label) => {
|
imap::types::NameAttribute::Custom(ref label) => {
|
||||||
if special_names.iter().find(|s| *s == label).is_some() {
|
if special_names.iter().find(|s| *s == label).is_some() {
|
||||||
|
|||||||
Reference in New Issue
Block a user