diff --git a/mmime/src/mailimf/mod.rs b/mmime/src/mailimf/mod.rs index 17cb7b04d..32ade65d9 100644 --- a/mmime/src/mailimf/mod.rs +++ b/mmime/src/mailimf/mod.rs @@ -3833,26 +3833,21 @@ pub unsafe fn mailimf_references_parse( } else { r = mailimf_unstrict_crlf_parse(message, length, &mut cur_token); if r != MAILIMF_NO_ERROR as libc::c_int { - res = r - } else { - // references = mailimf_references_new(msg_id_list); - panic!("implement me correctly"); - if references.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - *result = references; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - } + res = r; - for el in &msg_id_list { - mailimf_msg_id_free(*el); + for el in &msg_id_list { + mailimf_msg_id_free(*el); + } + } else { + references = mailimf_references_new(msg_id_list); + *result = references; + *indx = cur_token; + return MAILIMF_NO_ERROR as libc::c_int; } } } } - return res; + res } pub unsafe fn mailimf_msg_id_list_parse( @@ -4233,15 +4228,9 @@ unsafe fn mailimf_in_reply_to_parse( if r != MAILIMF_NO_ERROR as libc::c_int { res = r } else { - // in_reply_to = mailimf_in_reply_to_new(msg_id_list); - panic!("implement me correctly"); - if in_reply_to.is_null() { - res = MAILIMF_ERROR_MEMORY as libc::c_int - } else { - *result = in_reply_to; - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } + *result = mailimf_in_reply_to_new(msg_id_list); + *indx = cur_token; + return MAILIMF_NO_ERROR as libc::c_int; } for el in &msg_id_list { mailimf_msg_id_free(*el); @@ -4883,18 +4872,16 @@ pub unsafe fn mailimf_envelope_fields_parse( current_block = 894413572976700158; break; } - match current_block { - 2719512138335094285 => { - *result = mailimf_fields_new(list); - *indx = cur_token; - return MAILIMF_NO_ERROR as libc::c_int; - } - _ => {} - } } } } + if current_block == 2719512138335094285 { + *result = mailimf_fields_new(list); + *indx = cur_token; + return MAILIMF_NO_ERROR as libc::c_int; + } + res } diff --git a/mmime/src/mailimf/types.rs b/mmime/src/mailimf/types.rs index fed2aa26e..129a99f62 100644 --- a/mmime/src/mailimf/types.rs +++ b/mmime/src/mailimf/types.rs @@ -165,6 +165,15 @@ pub enum mailimf_field { OptionalField(*mut mailimf_optional_field), } +impl mailimf_field { + pub fn is_optional_field(&self) -> bool { + match self { + mailimf_field::OptionalField(_) => true, + _ => false, + } + } +} + impl Drop for mailimf_field { fn drop(&mut self) { use mailimf_field::*; @@ -192,7 +201,6 @@ impl Drop for mailimf_field { Comments(c) => mailimf_comments_free(*c), Keywords(k) => mailimf_keywords_free(*k), OptionalField(o) => mailimf_optional_field_free(*o), - _ => {} } } } @@ -241,26 +249,31 @@ pub struct mailimf_comments { pub struct mailimf_subject { pub sbj_value: *mut libc::c_char, } -/* - mailimf_references is the parsed References field - - msg_id_list is the list of message identifiers -*/ -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailimf_references { - pub mid_list: *mut clist, -} -/* - mailimf_in_reply_to is the parsed In-Reply-To field +/// List of parsed references. +#[derive(Debug, Clone)] +pub struct mailimf_references(pub Vec<*mut libc::c_char>); - - mid_list is the list of message identifers -*/ -#[derive(Copy, Clone)] -#[repr(C)] -pub struct mailimf_in_reply_to { - pub mid_list: *mut clist, +impl Drop for mailimf_references { + fn drop(&mut self) { + for el in &self.0 { + unsafe { mailimf_msg_id_free(*el) }; + } + } } + +/// The parsed In-Reply-To field. +#[derive(Debug, Clone)] +pub struct mailimf_in_reply_to(pub Vec<*mut libc::c_char>); + +impl Drop for mailimf_in_reply_to { + fn drop(&mut self) { + for el in &self.0 { + unsafe { mailimf_msg_id_free(*el) }; + } + } +} + /* mailimf_message_id is the parsed Message-ID field @@ -649,34 +662,25 @@ pub unsafe fn mailimf_subject_free(mut subject: *mut mailimf_subject) { mailimf_unstructured_free((*subject).sbj_value); free(subject as *mut libc::c_void); } -#[no_mangle] -pub unsafe fn mailimf_references_free(mut references: *mut mailimf_references) { - clist_foreach( - (*references).mid_list, - ::std::mem::transmute:: ()>, clist_func>(Some( - mailimf_msg_id_free, - )), - 0 as *mut libc::c_void, - ); - clist_free((*references).mid_list); - free(references as *mut libc::c_void); + +pub unsafe fn mailimf_references_free(references: *mut mailimf_references) { + if references.is_null() { + return; + } + let _ = Box::from_raw(references); } + #[no_mangle] pub unsafe fn mailimf_msg_id_free(mut msg_id: *mut libc::c_char) { free(msg_id as *mut libc::c_void); } -#[no_mangle] -pub unsafe fn mailimf_in_reply_to_free(mut in_reply_to: *mut mailimf_in_reply_to) { - clist_foreach( - (*in_reply_to).mid_list, - ::std::mem::transmute:: ()>, clist_func>(Some( - mailimf_msg_id_free, - )), - 0 as *mut libc::c_void, - ); - clist_free((*in_reply_to).mid_list); - free(in_reply_to as *mut libc::c_void); + +pub unsafe fn mailimf_in_reply_to_free(in_reply_to: *mut mailimf_in_reply_to) { + if in_reply_to.is_null() { + return; + } } + #[no_mangle] pub unsafe fn mailimf_message_id_free(mut message_id: *mut mailimf_message_id) { if !(*message_id).mid_value.is_null() { @@ -839,29 +843,17 @@ pub unsafe fn mailimf_message_id_new(mut mid_value: *mut libc::c_char) -> *mut m (*message_id).mid_value = mid_value; return message_id; } -#[no_mangle] -pub unsafe fn mailimf_in_reply_to_new(mut mid_list: *mut clist) -> *mut mailimf_in_reply_to { - let mut in_reply_to: *mut mailimf_in_reply_to = 0 as *mut mailimf_in_reply_to; - in_reply_to = malloc(::std::mem::size_of::() as libc::size_t) - as *mut mailimf_in_reply_to; - if in_reply_to.is_null() { - return 0 as *mut mailimf_in_reply_to; - } - (*in_reply_to).mid_list = mid_list; - return in_reply_to; + +pub unsafe fn mailimf_in_reply_to_new(ids: Vec<*mut libc::c_char>) -> *mut mailimf_in_reply_to { + let irt = mailimf_in_reply_to(ids); + Box::into_raw(Box::new(irt)) } -/* != NULL */ -#[no_mangle] -pub unsafe fn mailimf_references_new(mid_list: *mut clist) -> *mut mailimf_references { - let mut ref_0: *mut mailimf_references = 0 as *mut mailimf_references; - ref_0 = malloc(::std::mem::size_of::() as libc::size_t) - as *mut mailimf_references; - if ref_0.is_null() { - return 0 as *mut mailimf_references; - } - (*ref_0).mid_list = mid_list; - return ref_0; + +pub unsafe fn mailimf_references_new(ids: Vec<*mut libc::c_char>) -> *mut mailimf_references { + let list = mailimf_references(ids); + Box::into_raw(Box::new(list)) } + #[no_mangle] pub unsafe fn mailimf_subject_new(mut sbj_value: *mut libc::c_char) -> *mut mailimf_subject { let mut subject: *mut mailimf_subject = 0 as *mut mailimf_subject; diff --git a/mmime/src/mailimf/write_generic.rs b/mmime/src/mailimf/write_generic.rs index f0ed1cc94..bde128b05 100644 --- a/mmime/src/mailimf/write_generic.rs +++ b/mmime/src/mailimf/write_generic.rs @@ -588,7 +588,7 @@ unsafe fn mailimf_references_write_driver( if r != MAILIMF_NO_ERROR as libc::c_int { return r; } - r = mailimf_msg_id_list_write_driver(do_write, data, col, (*references).mid_list); + r = mailimf_msg_id_list_write_driver(do_write, data, col, &(*references).0); if r != MAILIMF_NO_ERROR as libc::c_int { return r; } @@ -605,28 +605,19 @@ unsafe fn mailimf_references_write_driver( return MAILIMF_NO_ERROR as libc::c_int; } unsafe fn mailimf_msg_id_list_write_driver( - mut do_write: Option< + do_write: Option< unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, >, - mut data: *mut libc::c_void, - mut col: *mut libc::c_int, - mut mid_list: *mut clist, + data: *mut libc::c_void, + col: *mut libc::c_int, + mid_list: &Vec<*mut libc::c_char>, ) -> libc::c_int { - let mut cur: *mut clistiter = 0 as *mut clistiter; - let mut r: libc::c_int = 0; - let mut first: libc::c_int = 0; - first = 1i32; - cur = (*mid_list).first; - while !cur.is_null() { - let mut msgid: *mut libc::c_char = 0 as *mut libc::c_char; - let mut len: size_t = 0; - msgid = (if !cur.is_null() { - (*cur).data - } else { - 0 as *mut libc::c_void - }) as *mut libc::c_char; - len = strlen(msgid); - if 0 == first { + let mut r = 0; + let mut first = true; + + for msgid in mid_list { + let len = strlen(*msgid); + if !first { if *col > 1i32 { if (*col as libc::size_t).wrapping_add(len) >= 72i32 as libc::size_t { r = mailimf_string_write_driver( @@ -639,11 +630,11 @@ unsafe fn mailimf_msg_id_list_write_driver( if r != MAILIMF_NO_ERROR as libc::c_int { return r; } - first = 1i32 + first = true; } } } - if 0 == first { + if !first { r = mailimf_string_write_driver( do_write, data, @@ -655,7 +646,7 @@ unsafe fn mailimf_msg_id_list_write_driver( return r; } } else { - first = 0i32 + first = false; } r = mailimf_string_write_driver( do_write, @@ -667,7 +658,7 @@ unsafe fn mailimf_msg_id_list_write_driver( if r != MAILIMF_NO_ERROR as libc::c_int { return r; } - r = mailimf_string_write_driver(do_write, data, col, msgid, len); + r = mailimf_string_write_driver(do_write, data, col, *msgid, len); if r != MAILIMF_NO_ERROR as libc::c_int { return r; } @@ -681,14 +672,11 @@ unsafe fn mailimf_msg_id_list_write_driver( if r != MAILIMF_NO_ERROR as libc::c_int { return r; } - cur = if !cur.is_null() { - (*cur).next - } else { - 0 as *mut clistcell - } } - return MAILIMF_NO_ERROR as libc::c_int; + + MAILIMF_NO_ERROR as libc::c_int } + unsafe fn mailimf_in_reply_to_write_driver( mut do_write: Option< unsafe fn(_: *mut libc::c_void, _: *const libc::c_char, _: size_t) -> libc::c_int, @@ -708,7 +696,7 @@ unsafe fn mailimf_in_reply_to_write_driver( if r != MAILIMF_NO_ERROR as libc::c_int { return r; } - r = mailimf_msg_id_list_write_driver(do_write, data, col, (*in_reply_to).mid_list); + r = mailimf_msg_id_list_write_driver(do_write, data, col, &(*in_reply_to).0); if r != MAILIMF_NO_ERROR as libc::c_int { return r; } diff --git a/mmime/src/other.rs b/mmime/src/other.rs index 9509c39a5..6d98ef0e1 100644 --- a/mmime/src/other.rs +++ b/mmime/src/other.rs @@ -349,17 +349,17 @@ pub unsafe fn mailimf_address_list_add( other code will be returned otherwise */ pub unsafe fn mailimf_fields_new_with_data_all( - mut date: *mut mailimf_date_time, - mut from: *mut mailimf_mailbox_list, - mut sender: *mut mailimf_mailbox, - mut reply_to: *mut mailimf_address_list, - mut to: *mut mailimf_address_list, - mut cc: *mut mailimf_address_list, - mut bcc: *mut mailimf_address_list, - mut message_id: *mut libc::c_char, - mut in_reply_to: *mut clist, - mut references: *mut clist, - mut subject: *mut libc::c_char, + date: *mut mailimf_date_time, + from: *mut mailimf_mailbox_list, + sender: *mut mailimf_mailbox, + reply_to: *mut mailimf_address_list, + to: *mut mailimf_address_list, + cc: *mut mailimf_address_list, + bcc: *mut mailimf_address_list, + message_id: *mut libc::c_char, + in_reply_to: Vec<*mut libc::c_char>, + references: Vec<*mut libc::c_char>, + subject: *mut libc::c_char, ) -> *mut mailimf_fields { let mut fields: *mut mailimf_fields = 0 as *mut mailimf_fields; let mut r: libc::c_int = 0; @@ -406,18 +406,18 @@ pub unsafe fn mailimf_fields_new_with_data_all( other code will be returned otherwise */ pub unsafe fn mailimf_fields_add_data( - mut fields: *mut mailimf_fields, - mut date: *mut mailimf_date_time, - mut from: *mut mailimf_mailbox_list, - mut sender: *mut mailimf_mailbox, - mut reply_to: *mut mailimf_address_list, - mut to: *mut mailimf_address_list, - mut cc: *mut mailimf_address_list, - mut bcc: *mut mailimf_address_list, - mut msg_id: *mut libc::c_char, - mut in_reply_to: *mut clist, - mut references: *mut clist, - mut subject: *mut libc::c_char, + fields: *mut mailimf_fields, + date: *mut mailimf_date_time, + from: *mut mailimf_mailbox_list, + sender: *mut mailimf_mailbox, + reply_to: *mut mailimf_address_list, + to: *mut mailimf_address_list, + cc: *mut mailimf_address_list, + bcc: *mut mailimf_address_list, + msg_id: *mut libc::c_char, + in_reply_to: Vec<*mut libc::c_char>, + references: Vec<*mut libc::c_char>, + subject: *mut libc::c_char, ) -> libc::c_int { let mut current_block: u64; let mut imf_date: *mut mailimf_orig_date = 0 as *mut mailimf_orig_date; @@ -579,63 +579,35 @@ pub unsafe fn mailimf_fields_add_data( 13813460800808168376 => {} 16539016819803454162 => {} _ => { - if !in_reply_to.is_null() { - imf_in_reply_to = - mailimf_in_reply_to_new( - in_reply_to, - ); - if imf_in_reply_to.is_null() - { - current_block - = - 16539016819803454162; - } else { - let field - = - mailimf_field::InReplyTo( - imf_in_reply_to, - ); - mailimf_fields_add( - fields, field, - ); - current_block - = - 15587532755333643506; - } - } else { - current_block = - 15587532755333643506; - } + imf_in_reply_to = + mailimf_in_reply_to_new( + in_reply_to, + ); + let field = + mailimf_field::InReplyTo( + imf_in_reply_to, + ); + mailimf_fields_add( + fields, field, + ); + current_block = + 15587532755333643506; match current_block { 13813460800808168376 => {} 16539016819803454162 => {} _ => { - if !references.is_null() - { - imf_references - = - mailimf_references_new(references); - if imf_references - .is_null() - { - current_block - = - 16539016819803454162; - } else { - let field - = - mailimf_field::References( - imf_references); - mailimf_fields_add(fields, field); - current_block - = - 7301440000599063274; - } - } else { - current_block - = - 7301440000599063274; - } + imf_references + = + mailimf_references_new(references); + let field + = + mailimf_field::References( + imf_references); + mailimf_fields_add( + fields, field, + ); + current_block = + 7301440000599063274; match current_block { 13813460800808168376 @@ -746,11 +718,9 @@ unsafe fn detach_free_fields( mailimf_reply_to_free(reply_to); } if !in_reply_to.is_null() { - (*in_reply_to).mid_list = 0 as *mut clist; mailimf_in_reply_to_free(in_reply_to); } if !references.is_null() { - (*references).mid_list = 0 as *mut clist; mailimf_references_free(references); } if !subject.is_null() { diff --git a/src/aheader.rs b/src/aheader.rs index a5966a33b..986d73d6b 100644 --- a/src/aheader.rs +++ b/src/aheader.rs @@ -69,14 +69,8 @@ impl Aheader { } let mut fine_header = None; - let mut cur = unsafe { (*(*header).fld_list).first }; - - while !cur.is_null() { - let field = unsafe { (*cur).data as *mut mailimf_field }; - if !field.is_null() - && unsafe { (*field).fld_type } == MAILIMF_FIELD_OPTIONAL_FIELD as libc::c_int - { - let optional_field = unsafe { (*field).fld_data.fld_optional_field }; + for field in unsafe { &(*header).0 } { + if let mailimf_field::OptionalField(optional_field) = *field { if !optional_field.is_null() && unsafe { !(*optional_field).fld_name.is_null() } && unsafe { CStr::from_ptr((*optional_field).fld_name).to_str().unwrap() } @@ -103,8 +97,6 @@ impl Aheader { } } } - - cur = unsafe { (*cur).next }; } fine_header diff --git a/src/dc_mimeparser.rs b/src/dc_mimeparser.rs index bc5afbddd..8ab52f37c 100644 --- a/src/dc_mimeparser.rs +++ b/src/dc_mimeparser.rs @@ -31,7 +31,7 @@ pub struct MimeParser<'a> { pub context: &'a Context, pub parts: Vec, pub mimeroot: *mut Mailmime, - pub header: HashMap, + pub header: HashMap, pub header_root: *mut mailimf_fields, pub header_protected: *mut mailimf_fields, pub subject: Option, @@ -124,8 +124,8 @@ impl<'a> MimeParser<'a> { self.parse_mime_recursive(self.mimeroot); if let Some(field) = self.lookup_field("Subject") { - if (*field).fld_type == MAILIMF_FIELD_SUBJECT as libc::c_int { - let subj = (*(*field).fld_data.fld_subject).sbj_value; + if let mailimf_field::Subject(subject) = *field { + let subj = (*subject).sbj_value; self.subject = as_opt_str(subj).map(dc_decode_header_words_safe); } @@ -289,12 +289,9 @@ impl<'a> MimeParser<'a> { { if let Some(dn_to_addr) = mailimf_find_first_addr(mb_list) { if let Some(from_field) = self.lookup_field("From") { - if (*from_field).fld_type == MAILIMF_FIELD_FROM as libc::c_int - && !(*from_field).fld_data.fld_from.is_null() - { - let from_addr = mailimf_find_first_addr( - (*(*from_field).fld_data.fld_from).frm_mb_list, - ); + if let mailimf_field::From(from) = *from_field { + let from_addr = + mailimf_find_first_addr((*from).frm_mb_list); if let Some(from_addr) = from_addr { if from_addr == dn_to_addr { if let Some(part_4) = self.get_last_nonmeta() { @@ -333,44 +330,24 @@ impl<'a> MimeParser<'a> { /* the following functions can be used only after a call to parse() */ - pub fn lookup_field(&self, field_name: &str) -> Option<*mut mailimf_field> { - match self.header.get(field_name) { - Some(v) => { - if v.is_null() { - None - } else { - Some(*v) - } - } - None => None, - } + pub fn lookup_field(&self, field_name: &str) -> Option<&mailimf_field> { + self.header.get(field_name) } pub fn lookup_optional_field(&self, field_name: &str) -> Option { - if let Some(field) = self.lookup_field_typ(field_name, MAILIMF_FIELD_OPTIONAL_FIELD) { - let val = unsafe { (*field).fld_data.fld_optional_field }; - if val.is_null() { - return None; - } else { - return Some(unsafe { to_string_lossy((*val).fld_value) }); + if let Some(field) = self.lookup_field(field_name) { + if let mailimf_field::OptionalField(val) = *field { + if val.is_null() { + return None; + } else { + return Some(unsafe { to_string_lossy((*val).fld_value) }); + } } } None } - pub fn lookup_field_typ(&self, name: &str, typ: u32) -> Option<*const mailimf_field> { - if let Some(field) = self.lookup_field(name) { - if unsafe { (*field).fld_type } == typ as libc::c_int { - Some(field) - } else { - None - } - } else { - None - } - } - unsafe fn parse_mime_recursive(&mut self, mime: *mut Mailmime) -> bool { if mime.is_null() { return false; @@ -829,29 +806,22 @@ impl<'a> MimeParser<'a> { } let mut sender_equals_recipient = false; - let mut fld_from: *const mailimf_from = ptr::null(); /* get From: and check there is exactly one sender */ - let fld = mailimf_find_field(self.header_root, MAILIMF_FIELD_FROM as libc::c_int); - if !(fld.is_null() - || { - fld_from = (*fld).fld_data.fld_from; - fld_from.is_null() - } - || (*fld_from).frm_mb_list.is_null() - || (*(*(*fld_from).frm_mb_list).0).len() != 1) - { - let mb = (*(*(*fld_from).frm_mb_list).0) - .first() - .map(|v| *v) - .unwrap_or_else(|| ptr::null_mut()); + if let Some(fld_from) = mailimf_find_from_field(self.header_root) { + if (*fld_from).frm_mb_list.is_null() || (*(*(*fld_from).frm_mb_list).0).len() != 1 { + let mb = (*(*(*fld_from).frm_mb_list).0) + .first() + .map(|v| *v) + .unwrap_or_else(|| ptr::null_mut()); - if !mb.is_null() { - let from_addr_norm = addr_normalize(as_str((*mb).addr_spec)); - let recipients = mailimf_get_recipients(self.header_root); - if recipients.len() == 1 { - if recipients.contains(from_addr_norm) { - sender_equals_recipient = true; + if !mb.is_null() { + let from_addr_norm = addr_normalize(as_str((*mb).addr_spec)); + let recipients = mailimf_get_recipients(self.header_root); + if recipients.len() == 1 { + if recipients.contains(from_addr_norm) { + sender_equals_recipient = true; + } } } } @@ -875,11 +845,10 @@ impl<'a> MimeParser<'a> { pub fn get_rfc724_mid(&mut self) -> Option { // get Message-ID from header - if let Some(field) = self.lookup_field_typ("Message-ID", MAILIMF_FIELD_MESSAGE_ID) { - unsafe { - let fld_message_id = (*field).fld_data.fld_message_id; - if !fld_message_id.is_null() { - return Some(to_string((*fld_message_id).mid_value)); + if let Some(field) = self.lookup_field("Message-ID") { + if let mailimf_field::MessageId(id) = *field { + if !id.is_null() { + return Some(unsafe { to_string((*id).mid_value) }); } } } @@ -925,31 +894,28 @@ pub fn mailimf_find_first_addr(mb_list: *const mailimf_mailbox_list) -> Option, in_0: *const mailimf_fields) { +unsafe fn hash_header(out: &mut HashMap, in_0: *const mailimf_fields) { if in_0.is_null() { return; } - for cur in (*(*in_0).fld_list).into_iter() { - let field = cur as *mut mailimf_field; - // TODO match on enums /rtn - - let key = match (*field).fld_type as libc::c_uint { - MAILIMF_FIELD_RETURN_PATH => Some("Return-Path".to_string()), - MAILIMF_FIELD_ORIG_DATE => Some("Date".to_string()), - MAILIMF_FIELD_FROM => Some("From".to_string()), - MAILIMF_FIELD_SENDER => Some("Sender".to_string()), - MAILIMF_FIELD_REPLY_TO => Some("Reply-To".to_string()), - MAILIMF_FIELD_TO => Some("To".to_string()), - MAILIMF_FIELD_CC => Some("Cc".to_string()), - MAILIMF_FIELD_BCC => Some("Bcc".to_string()), - MAILIMF_FIELD_MESSAGE_ID => Some("Message-ID".to_string()), - MAILIMF_FIELD_IN_REPLY_TO => Some("In-Reply-To".to_string()), - MAILIMF_FIELD_REFERENCES => Some("References".to_string()), - MAILIMF_FIELD_SUBJECT => Some("Subject".to_string()), - MAILIMF_FIELD_OPTIONAL_FIELD => { + for field in &(*in_0).0 { + use mailimf_field::*; + let key = match *field { + ReturnPath(_) => Some("Return-Path".to_string()), + OrigDate(_) => Some("Date".to_string()), + From(_) => Some("From".to_string()), + Sender(_) => Some("Sender".to_string()), + ReplyTo(_) => Some("Reply-To".to_string()), + To(_) => Some("To".to_string()), + Cc(_) => Some("Cc".to_string()), + Bcc(_) => Some("Bcc".to_string()), + MessageId(_) => Some("Message-ID".to_string()), + InReplyTo(_) => Some("In-Reply-To".to_string()), + References(_) => Some("References".to_string()), + Subject(_) => Some("Subject".to_string()), + OptionalField(optional_field) => { // MAILIMF_FIELD_OPTIONAL_FIELD - let optional_field = (*field).fld_data.fld_optional_field; // XXX the optional field sometimes contains invalid UTF8 // which should not happen (according to the mime standard). // This might point to a bug in our mime parsing/processing @@ -966,9 +932,9 @@ unsafe fn hash_header(out: &mut HashMap, in_0: *cons }; if let Some(key) = key { if !out.contains_key(&key) || // key already exists, only overwrite known types (protected headers) - (*field).fld_type != MAILIMF_FIELD_OPTIONAL_FIELD as i32 || key.starts_with("Chat-") + field.is_optional_field() || key.starts_with("Chat-") { - out.insert(key, field); + out.insert(key, field.clone()); } } } @@ -1213,29 +1179,16 @@ pub fn mailimf_get_recipients(imffields: *mut mailimf_fields) -> HashSet /* returned addresses are normalized. */ let mut recipients: HashSet = Default::default(); - for cur in unsafe { (*(*imffields).fld_list).into_iter() } { - let fld = cur as *mut mailimf_field; - - let fld_to: *mut mailimf_to; - let fld_cc: *mut mailimf_cc; - + for fld in unsafe { &(*imffields).0 } { let mut addr_list: *mut mailimf_address_list = ptr::null_mut(); - if fld.is_null() { - continue; - } - let fld = unsafe { *fld }; - - // TODO match on enums /rtn - match fld.fld_type { - 13 => { - fld_to = unsafe { fld.fld_data.fld_to }; + match *fld { + mailimf_field::To(fld_to) => { if !fld_to.is_null() { addr_list = unsafe { (*fld_to).to_addr_list }; } } - 14 => { - fld_cc = unsafe { fld.fld_data.fld_cc }; + mailimf_field::Cc(fld_cc) => { if !fld_cc.is_null() { addr_list = unsafe { (*fld_cc).cc_addr_list }; } @@ -1275,30 +1228,32 @@ fn mailimf_get_recipients_add_addr(recipients: &mut HashSet, mb: *mut ma } } -/*the result is a pointer to mime, must not be freed*/ -pub fn mailimf_find_field( - header: *mut mailimf_fields, - wanted_fld_type: libc::c_int, -) -> *mut mailimf_field { +pub fn mailimf_find_from_field(header: *mut mailimf_fields) -> Option<*mut mailimf_from> { if header.is_null() { - return ptr::null_mut(); + return None; } - let header = unsafe { (*header) }; - if header.fld_list.is_null() { - return ptr::null_mut(); - } - - for cur in unsafe { &(*header.fld_list) } { - let field = cur as *mut mailimf_field; - if !field.is_null() { - if unsafe { (*field).fld_type } == wanted_fld_type { - return field; - } + unsafe { (*header).0.iter() }.find_map(|field| { + if let mailimf_field::From(f) = field { + Some(*f) + } else { + None } + }) +} + +pub fn mailimf_find_orig_date_field(header: *mut mailimf_fields) -> Option<*mut mailimf_orig_date> { + if header.is_null() { + return None; } - ptr::null_mut() + unsafe { (*header).0.iter() }.find_map(|field| { + if let mailimf_field::OrigDate(d) = field { + Some(*d) + } else { + None + } + }) } /*the result is a pointer to mime, must not be freed*/ @@ -1327,14 +1282,11 @@ pub unsafe fn mailimf_find_optional_field( header: *mut mailimf_fields, wanted_fld_name: *const libc::c_char, ) -> *mut mailimf_optional_field { - if header.is_null() || (*header).fld_list.is_null() { + if header.is_null() { return ptr::null_mut(); } - for cur_data in (*(*header).fld_list).into_iter() { - let field: *mut mailimf_field = cur_data as *mut _; - - if (*field).fld_type == MAILIMF_FIELD_OPTIONAL_FIELD as libc::c_int { - let optional_field: *mut mailimf_optional_field = (*field).fld_data.fld_optional_field; + for field in &(*header).0 { + if let mailimf_field::OptionalField(optional_field) = *field { if !optional_field.is_null() && !(*optional_field).fld_name.is_null() && !(*optional_field).fld_value.is_null() diff --git a/src/dc_receive_imf.rs b/src/dc_receive_imf.rs index 76daf2745..ba439f452 100644 --- a/src/dc_receive_imf.rs +++ b/src/dc_receive_imf.rs @@ -3,7 +3,6 @@ use std::ptr; use itertools::join; use libc::{free, strcmp, strlen}; -use mmime::clist::*; use mmime::mailimf::types::*; use mmime::mailimf::*; use mmime::mailmime::content::*; @@ -119,61 +118,65 @@ pub unsafe fn dc_receive_imf( } }; - if let Some(field) = mime_parser.lookup_field_typ("Date", MAILIMF_FIELD_ORIG_DATE) { - let orig_date = (*field).fld_data.fld_orig_date; - if !orig_date.is_null() { - // is not yet checked against bad times! we do this later if we have the database information. - sent_timestamp = dc_timestamp_from_date((*orig_date).dt_date_time) + if let Some(field) = mime_parser.lookup_field("Date") { + if let mailimf_field::OrigDate(orig_date) = *field { + if !orig_date.is_null() { + // is not yet checked against bad times! we do this later if we have the database information. + sent_timestamp = dc_timestamp_from_date((*orig_date).dt_date_time) + } } } // get From: and check if it is known (for known From:'s we add the other To:/Cc: in the 3rd pass) // or if From: is equal to SELF (in this case, it is any outgoing messages, // we do not check Return-Path any more as this is unreliable, see issue #150 - if let Some(field) = mime_parser.lookup_field_typ("From", MAILIMF_FIELD_FROM) { - let fld_from = (*field).fld_data.fld_from; - if !fld_from.is_null() { - let mut check_self = 0; - let mut from_list = Vec::with_capacity(16); - dc_add_or_lookup_contacts_by_mailbox_list( - context, - (*fld_from).frm_mb_list, - Origin::IncomingUnknownFrom, - &mut from_list, - &mut check_self, - ); - if 0 != check_self { - incoming = 0; - if mime_parser.sender_equals_recipient() { - from_id = DC_CONTACT_ID_SELF; + if let Some(field) = mime_parser.lookup_field("From") { + if let mailimf_field::From(fld_from) = *field { + if !fld_from.is_null() { + let mut check_self = 0; + let mut from_list = Vec::with_capacity(16); + dc_add_or_lookup_contacts_by_mailbox_list( + context, + (*fld_from).frm_mb_list, + Origin::IncomingUnknownFrom, + &mut from_list, + &mut check_self, + ); + if 0 != check_self { + incoming = 0; + if mime_parser.sender_equals_recipient() { + from_id = DC_CONTACT_ID_SELF; + } + } else if from_list.len() >= 1 { + // if there is no from given, from_id stays 0 which is just fine. These messages + // are very rare, however, we have to add them to the database (they go to the + // "deaddrop" chat) to avoid a re-download from the server. See also [**] + from_id = from_list[0]; + incoming_origin = + Contact::get_origin_by_id(context, from_id, &mut from_id_blocked) } - } else if from_list.len() >= 1 { - // if there is no from given, from_id stays 0 which is just fine. These messages - // are very rare, however, we have to add them to the database (they go to the - // "deaddrop" chat) to avoid a re-download from the server. See also [**] - from_id = from_list[0]; - incoming_origin = Contact::get_origin_by_id(context, from_id, &mut from_id_blocked) } } } // Make sure, to_ids starts with the first To:-address (Cc: is added in the loop below pass) - if let Some(field) = mime_parser.lookup_field_typ("To", MAILIMF_FIELD_TO) { - let fld_to = (*field).fld_data.fld_to; - if !fld_to.is_null() { - dc_add_or_lookup_contacts_by_address_list( - context, - (*fld_to).to_addr_list, - if 0 == incoming { - Origin::OutgoingTo - } else if incoming_origin.is_verified() { - Origin::IncomingTo - } else { - Origin::IncomingUnknownTo - }, - &mut to_ids, - &mut to_self, - ); + if let Some(field) = mime_parser.lookup_field("To") { + if let mailimf_field::To(fld_to) = *field { + if !fld_to.is_null() { + dc_add_or_lookup_contacts_by_address_list( + context, + (*fld_to).to_addr_list, + if 0 == incoming { + Origin::OutgoingTo + } else if incoming_origin.is_verified() { + Origin::IncomingTo + } else { + Origin::IncomingUnknownTo + }, + &mut to_ids, + &mut to_self, + ); + } } } @@ -327,22 +330,23 @@ unsafe fn add_parts( // collect the rest information, CC: is added to the to-list, BCC: is ignored // (we should not add BCC to groups as this would split groups. We could add them as "known contacts", // however, the benefit is very small and this may leak data that is expected to be hidden) - if let Some(field) = mime_parser.lookup_field_typ("Cc", MAILIMF_FIELD_CC) { - let fld_cc = (*field).fld_data.fld_cc; - if !fld_cc.is_null() { - dc_add_or_lookup_contacts_by_address_list( - context, - (*fld_cc).cc_addr_list, - if 0 == incoming { - Origin::OutgoingCc - } else if incoming_origin.is_verified() { - Origin::IncomingCc - } else { - Origin::IncomingUnknownCc - }, - to_ids, - std::ptr::null_mut(), - ); + if let Some(field) = mime_parser.lookup_field("Cc") { + if let mailimf_field::Cc(fld_cc) = *field { + if !fld_cc.is_null() { + dc_add_or_lookup_contacts_by_address_list( + context, + (*fld_cc).cc_addr_list, + if 0 == incoming { + Origin::OutgoingCc + } else if incoming_origin.is_verified() { + Origin::IncomingCc + } else { + Origin::IncomingUnknownCc + }, + to_ids, + std::ptr::null_mut(), + ); + } } } @@ -583,23 +587,25 @@ unsafe fn add_parts( // if the mime-headers should be saved, find out its size // (the mime-header ends with an empty line) let save_mime_headers = context.sql.get_config_bool(context, "save_mime_headers"); - if let Some(field) = mime_parser.lookup_field_typ("In-Reply-To", MAILIMF_FIELD_IN_REPLY_TO) { - let fld_in_reply_to = (*field).fld_data.fld_in_reply_to; - if !fld_in_reply_to.is_null() { - mime_in_reply_to = dc_str_from_clist( - (*(*field).fld_data.fld_in_reply_to).mid_list, - b" \x00" as *const u8 as *const libc::c_char, - ) + if let Some(field) = mime_parser.lookup_field("In-Reply-To") { + if let mailimf_field::InReplyTo(fld_in_reply_to) = *field { + if !fld_in_reply_to.is_null() { + mime_in_reply_to = dc_str_from_vec( + &(*fld_in_reply_to).0, + b" \x00" as *const u8 as *const libc::c_char, + ); + } } } - if let Some(field) = mime_parser.lookup_field_typ("References", MAILIMF_FIELD_REFERENCES) { - let fld_references = (*field).fld_data.fld_references; - if !fld_references.is_null() { - mime_references = dc_str_from_clist( - (*(*field).fld_data.fld_references).mid_list, - b" \x00" as *const u8 as *const libc::c_char, - ) + if let Some(field) = mime_parser.lookup_field("References") { + if let mailimf_field::References(fld_references) = *field { + if !fld_references.is_null() { + mime_references = dc_str_from_vec( + &(*fld_references).0, + b" \x00" as *const u8 as *const libc::c_char, + ) + } } } @@ -1022,38 +1028,36 @@ unsafe fn create_or_lookup_group( } if grpid.is_empty() { - if let Some(field) = mime_parser.lookup_field_typ("Message-ID", MAILIMF_FIELD_MESSAGE_ID) { - let fld_message_id = (*field).fld_data.fld_message_id; - if !fld_message_id.is_null() { - if let Some(extracted_grpid) = - dc_extract_grpid_from_rfc724_mid(as_str((*fld_message_id).mid_value)) - { - grpid = extracted_grpid.to_string(); - } else { - grpid = "".to_string(); + if let Some(field) = mime_parser.lookup_field("Message-ID") { + if let mailimf_field::MessageId(fld_message_id) = *field { + if !fld_message_id.is_null() { + if let Some(extracted_grpid) = + dc_extract_grpid_from_rfc724_mid(as_str((*fld_message_id).mid_value)) + { + grpid = extracted_grpid.to_string(); + } else { + grpid = "".to_string(); + } } } } if grpid.is_empty() { - if let Some(field) = - mime_parser.lookup_field_typ("In-Reply-To", MAILIMF_FIELD_IN_REPLY_TO) - { - let fld_in_reply_to = (*field).fld_data.fld_in_reply_to; - if !fld_in_reply_to.is_null() { - grpid = to_string(dc_extract_grpid_from_rfc724_mid_list( - (*fld_in_reply_to).mid_list, - )); + if let Some(field) = mime_parser.lookup_field("In-Reply-To") { + if let mailimf_field::InReplyTo(fld_in_reply_to) = *field { + if !fld_in_reply_to.is_null() { + grpid = + to_string(dc_extract_grpid_from_rfc724_mid_list(&(*fld_in_reply_to).0)); + } } } if grpid.is_empty() { - if let Some(field) = - mime_parser.lookup_field_typ("References", MAILIMF_FIELD_REFERENCES) - { - let fld_references = (*field).fld_data.fld_references; - if !fld_references.is_null() { - grpid = to_string(dc_extract_grpid_from_rfc724_mid_list( - (*fld_references).mid_list, - )); + if let Some(field) = mime_parser.lookup_field("References") { + if let mailimf_field::References(fld_references) = *field { + if !fld_references.is_null() { + grpid = to_string(dc_extract_grpid_from_rfc724_mid_list( + &(*fld_references).0, + )); + } } } @@ -1706,13 +1710,9 @@ unsafe fn dc_is_reply_to_known_message(context: &Context, mime_parser: &MimePars } if let Some(field) = mime_parser.lookup_field("In-Reply-To") { - if (*field).fld_type == MAILIMF_FIELD_IN_REPLY_TO as libc::c_int { - let fld_in_reply_to = (*field).fld_data.fld_in_reply_to; + if let mailimf_field::InReplyTo(fld_in_reply_to) = *field { if !fld_in_reply_to.is_null() { - if is_known_rfc724_mid_in_list( - context, - (*(*field).fld_data.fld_in_reply_to).mid_list, - ) { + if is_known_rfc724_mid_in_list(context, &(*fld_in_reply_to).0) { return 1; } } @@ -1720,13 +1720,9 @@ unsafe fn dc_is_reply_to_known_message(context: &Context, mime_parser: &MimePars } if let Some(field) = mime_parser.lookup_field("References") { - if (*field).fld_type == MAILIMF_FIELD_REFERENCES as libc::c_int { - let fld_references = (*field).fld_data.fld_references; + if let mailimf_field::References(fld_references) = *field { if !fld_references.is_null() { - if is_known_rfc724_mid_in_list( - context, - (*(*field).fld_data.fld_references).mid_list, - ) { + if is_known_rfc724_mid_in_list(context, &(*fld_references).0) { return 1; } } @@ -1736,13 +1732,12 @@ unsafe fn dc_is_reply_to_known_message(context: &Context, mime_parser: &MimePars 0 } -unsafe fn is_known_rfc724_mid_in_list(context: &Context, mid_list: *const clist) -> bool { - if mid_list.is_null() { - return false; - } - - for data in &*mid_list { - if 0 != is_known_rfc724_mid(context, data.cast()) { +unsafe fn is_known_rfc724_mid_in_list( + context: &Context, + mid_list: &Vec<*mut libc::c_char>, +) -> bool { + for data in mid_list { + if 0 != is_known_rfc724_mid(context, *data) { return true; } } @@ -1778,13 +1773,9 @@ unsafe fn dc_is_reply_to_messenger_message( - no check for the Chat-* headers (function is only called if it is no messenger message itself) */ if let Some(field) = mime_parser.lookup_field("In-Reply-To") { - if (*field).fld_type == MAILIMF_FIELD_IN_REPLY_TO as libc::c_int { - let fld_in_reply_to = (*field).fld_data.fld_in_reply_to; + if let mailimf_field::InReplyTo(fld_in_reply_to) = *field { if !fld_in_reply_to.is_null() { - if 0 != is_msgrmsg_rfc724_mid_in_list( - context, - (*(*field).fld_data.fld_in_reply_to).mid_list, - ) { + if 0 != is_msgrmsg_rfc724_mid_in_list(context, &(*fld_in_reply_to).0) { return 1; } } @@ -1792,13 +1783,9 @@ unsafe fn dc_is_reply_to_messenger_message( } if let Some(field) = mime_parser.lookup_field("References") { - if (*field).fld_type == MAILIMF_FIELD_REFERENCES as libc::c_int { - let fld_references: *mut mailimf_references = (*field).fld_data.fld_references; + if let mailimf_field::References(fld_references) = *field { if !fld_references.is_null() { - if 0 != is_msgrmsg_rfc724_mid_in_list( - context, - (*(*field).fld_data.fld_references).mid_list, - ) { + if 0 != is_msgrmsg_rfc724_mid_in_list(context, &(*fld_references).0) { return 1; } } @@ -1808,25 +1795,13 @@ unsafe fn dc_is_reply_to_messenger_message( 0 } -unsafe fn is_msgrmsg_rfc724_mid_in_list(context: &Context, mid_list: *const clist) -> libc::c_int { - if !mid_list.is_null() { - let mut cur: *mut clistiter = (*mid_list).first; - while !cur.is_null() { - if 0 != is_msgrmsg_rfc724_mid( - context, - if !cur.is_null() { - as_str((*cur).data as *const libc::c_char) - } else { - "" - }, - ) { - return 1; - } - cur = if !cur.is_null() { - (*cur).next - } else { - ptr::null_mut() - } +unsafe fn is_msgrmsg_rfc724_mid_in_list( + context: &Context, + mid_list: &Vec<*mut libc::c_char>, +) -> libc::c_int { + for cur in mid_list { + if 0 != is_msgrmsg_rfc724_mid(context, if !cur.is_null() { as_str(*cur) } else { "" }) { + return 1; } } 0 diff --git a/src/dc_tools.rs b/src/dc_tools.rs index 7bb3796e7..2e330b9ed 100644 --- a/src/dc_tools.rs +++ b/src/dc_tools.rs @@ -10,7 +10,6 @@ use std::{fmt, fs, ptr}; use chrono::{Local, TimeZone}; use libc::{memcpy, strlen}; -use mmime::clist::*; use mmime::mailimf::types::*; use rand::{thread_rng, Rng}; @@ -149,46 +148,26 @@ pub(crate) fn dc_truncate(buf: &str, approx_chars: usize, do_unwrap: bool) -> Co } } -pub(crate) unsafe fn dc_str_from_clist( - list: *const clist, +pub(crate) unsafe fn dc_str_from_vec( + list: &Vec<*mut libc::c_char>, delimiter: *const libc::c_char, ) -> *mut libc::c_char { let mut res = String::new(); - if !list.is_null() { - let mut cur: *mut clistiter = (*list).first; - while !cur.is_null() { - let rfc724_mid = (if !cur.is_null() { - (*cur).data - } else { - ptr::null_mut() - }) as *const libc::c_char; - - if !rfc724_mid.is_null() { - if !res.is_empty() && !delimiter.is_null() { - res += as_str(delimiter); - } - res += as_str(rfc724_mid); - } - cur = if !cur.is_null() { - (*cur).next - } else { - ptr::null_mut() + for val in list { + if !val.is_null() { + if !res.is_empty() && !delimiter.is_null() { + res += as_str(delimiter); } + res += as_str(*val); } } res.strdup() } -pub(crate) fn dc_str_to_clist(str: &str, delimiter: &str) -> *mut clist { - unsafe { - let list: *mut clist = clist_new(); - for cur in str.split(&delimiter) { - clist_insert_after(list, (*list).last, cur.strdup().cast()); - } - list - } +pub(crate) fn dc_str_to_vec(s: &str, delimiter: &str) -> Vec<*mut libc::c_char> { + s.split(&delimiter).map(|s| unsafe { s.strdup() }).collect() } /* the colors must fulfill some criterions as: @@ -392,15 +371,15 @@ pub(crate) fn dc_extract_grpid_from_rfc724_mid(mid: &str) -> Option<&str> { None } -pub(crate) fn dc_extract_grpid_from_rfc724_mid_list(list: *const clist) -> *mut libc::c_char { - if !list.is_null() { - unsafe { - for cur in (*list).into_iter() { - let mid = as_str(cur as *const libc::c_char); +pub(crate) fn dc_extract_grpid_from_rfc724_mid_list( + list: &Vec<*mut libc::c_char>, +) -> *mut libc::c_char { + unsafe { + for cur in list { + let mid = as_str(*cur); - if let Some(grpid) = dc_extract_grpid_from_rfc724_mid(mid) { - return grpid.strdup(); - } + if let Some(grpid) = dc_extract_grpid_from_rfc724_mid(mid) { + return grpid.strdup(); } } } @@ -1129,21 +1108,6 @@ mod tests { ); } - /* calls free() for each item content */ - unsafe fn clist_free_content(haystack: *const clist) { - let mut iter = (*haystack).first; - - while !iter.is_null() { - free((*iter).data); - (*iter).data = ptr::null_mut(); - iter = if !iter.is_null() { - (*iter).next - } else { - ptr::null_mut() - } - } - } - fn strndup(s: *const libc::c_char, n: libc::c_ulong) -> *mut libc::c_char { if s.is_null() { return std::ptr::null_mut(); @@ -1159,35 +1123,6 @@ mod tests { } } - #[test] - fn test_dc_str_to_clist_1() { - unsafe { - let list = dc_str_to_clist("", " "); - assert_eq!((*list).count, 1); - clist_free_content(list); - clist_free(list); - } - } - - #[test] - fn test_dc_str_to_clist_4() { - unsafe { - let list: *mut clist = dc_str_to_clist("foo bar test", " "); - assert_eq!((*list).count, 3); - let str: *mut libc::c_char = - dc_str_from_clist(list, b" \x00" as *const u8 as *const libc::c_char); - - assert_eq!( - CStr::from_ptr(str as *const libc::c_char).to_str().unwrap(), - "foo bar test" - ); - - clist_free_content(list); - clist_free(list); - free(str as *mut libc::c_void); - } - } - #[test] fn test_dc_create_id() { let buf = dc_create_id(); diff --git a/src/e2ee.rs b/src/e2ee.rs index 1e7ae3820..2f5887ab6 100644 --- a/src/e2ee.rs +++ b/src/e2ee.rs @@ -5,7 +5,6 @@ use std::ptr; use std::str::FromStr; use libc::strlen; -use mmime::clist::*; use mmime::mailimf::types::*; use mmime::mailimf::types_helper::*; use mmime::mailimf::*; @@ -167,17 +166,14 @@ impl EncryptHelper { } // memoryhole headers: move some headers into encrypted part - // XXX note we can't use clist's into_iter() because the loop body also removes items - let mut cur = (*(*imffields_unprotected).fld_list).first; - while !cur.is_null() { - let field = (*cur).data as *mut mailimf_field; + (*imffields_unprotected).0.retain(|field| { let mut move_to_encrypted = false; - if !field.is_null() { - if (*field).fld_type == MAILIMF_FIELD_SUBJECT as libc::c_int { + match *field { + mailimf_field::Subject(_) => { move_to_encrypted = true; - } else if (*field).fld_type == MAILIMF_FIELD_OPTIONAL_FIELD as libc::c_int { - let opt_field = (*field).fld_data.fld_optional_field; + } + mailimf_field::OptionalField(opt_field) => { if !opt_field.is_null() && !(*opt_field).fld_name.is_null() { let fld_name = to_string_lossy((*opt_field).fld_name); if fld_name.starts_with("Secure-Join") @@ -187,18 +183,19 @@ impl EncryptHelper { } } } + _ => {} } if move_to_encrypted { - mailimf_fields_add(imffields_encrypted, field); - cur = clist_delete((*imffields_unprotected).fld_list, cur); + mailimf_fields_add(imffields_encrypted, field.clone()); + false } else { - cur = (*cur).next; + true } - } + }); let subject = mailimf_subject_new("...".strdup()); - mailimf_fields_add(imffields_unprotected, mailimf_field_new_subject(subject)); + mailimf_fields_add(imffields_unprotected, mailimf_field::Subject(subject)); wrapmime::append_ct_param( (*part_to_encrypt).mm_content_type, @@ -280,17 +277,12 @@ pub fn try_decrypt( // XXX do wrapmime:: helper for the next block if !(in_out_message.is_null() || imffields.is_null()) { - let mut field = mailimf_find_field(imffields, MAILIMF_FIELD_FROM as libc::c_int); - - if !field.is_null() && unsafe { !(*field).fld_data.fld_from.is_null() } { - let mb_list = unsafe { (*(*field).fld_data.fld_from).frm_mb_list }; + if let Some(field) = mailimf_find_from_field(imffields) { + let mb_list = unsafe { (*field).frm_mb_list }; from = mailimf_find_first_addr(mb_list); } - field = mailimf_find_field(imffields, MAILIMF_FIELD_ORIG_DATE as libc::c_int); - if !field.is_null() && unsafe { !(*field).fld_data.fld_orig_date.is_null() } { - let orig_date = unsafe { (*field).fld_data.fld_orig_date }; - + if let Some(orig_date) = mailimf_find_orig_date_field(imffields) { if !orig_date.is_null() { let dt = unsafe { (*orig_date).dt_date_time }; message_time = dc_timestamp_from_date(dt); @@ -460,16 +452,8 @@ fn update_gossip_peerstates( let mut recipients: Option> = None; let mut gossipped_addr: HashSet = Default::default(); - for cur_data in unsafe { (*(*gossip_headers).fld_list).into_iter() } { - let field = cur_data as *mut mailimf_field; - if field.is_null() { - continue; - } - - let field = unsafe { *field }; - - if field.fld_type == MAILIMF_FIELD_OPTIONAL_FIELD as libc::c_int { - let optional_field = unsafe { field.fld_data.fld_optional_field }; + for field in unsafe { &(*gossip_headers).0 } { + if let mailimf_field::OptionalField(optional_field) = *field { if optional_field.is_null() { continue; } diff --git a/src/mimefactory.rs b/src/mimefactory.rs index bd7c7b2cb..06d36821f 100644 --- a/src/mimefactory.rs +++ b/src/mimefactory.rs @@ -184,16 +184,10 @@ impl<'a> MimeFactory<'a> { ); } } - let references_list = if !self.references.is_empty() { - dc_str_to_clist(&self.references, " ") - } else { - ptr::null_mut() - }; - let in_reply_to_list = if !self.in_reply_to.is_empty() { - dc_str_to_clist(&self.in_reply_to, " ") - } else { - ptr::null_mut() - }; + let references_list = dc_str_to_vec(&self.references, " "); + + let in_reply_to_list = dc_str_to_vec(&self.in_reply_to, " "); + let imf_fields = mailimf_fields_new_with_data_all( mailimf_get_date(self.timestamp as i64), from, @@ -613,31 +607,9 @@ impl<'a> MimeFactory<'a> { mailimf_fields_add( imf_fields, - mailimf_field_new( - MAILIMF_FIELD_SUBJECT as libc::c_int, - ptr::null_mut(), - ptr::null_mut(), - ptr::null_mut(), - ptr::null_mut(), - ptr::null_mut(), - ptr::null_mut(), - ptr::null_mut(), - ptr::null_mut(), - ptr::null_mut(), - ptr::null_mut(), - ptr::null_mut(), - ptr::null_mut(), - ptr::null_mut(), - ptr::null_mut(), - ptr::null_mut(), - ptr::null_mut(), - ptr::null_mut(), - ptr::null_mut(), - mailimf_subject_new(dc_encode_header_words(subject_str).strdup()), - ptr::null_mut(), - ptr::null_mut(), - ptr::null_mut(), - ), + mailimf_field::Subject(mailimf_subject_new( + dc_encode_header_words(subject_str).strdup(), + )), ); /*just a pointer into mailmime structure, must not be freed*/ diff --git a/src/wrapmime.rs b/src/wrapmime.rs index fa1f900e0..f7c69f74e 100644 --- a/src/wrapmime.rs +++ b/src/wrapmime.rs @@ -180,11 +180,7 @@ pub fn add_filename_part( pub fn new_custom_field(fields: *mut mailimf_fields, name: &str, value: &str) { unsafe { let field = mailimf_field_new_custom(name.strdup(), value.strdup()); - let res = mailimf_fields_add(fields, field); - assert!( - res as u32 == MAILIMF_NO_ERROR, - "could not create mailimf field" - ); + mailimf_fields_add(fields, field); } }