diff --git a/src/dc_imex.rs b/src/dc_imex.rs index a2dc5df0e..cd8236bb6 100644 --- a/src/dc_imex.rs +++ b/src/dc_imex.rs @@ -490,10 +490,9 @@ pub unsafe fn dc_normalize_setup_code( pub unsafe fn dc_job_do_DC_JOB_IMEX_IMAP(context: &Context, job: &Job) { let mut ok_to_continue = true; let mut success: libc::c_int = 0; - let what: libc::c_int; if dc_alloc_ongoing(context) { - what = job.param.get_int(Param::Cmd).unwrap_or_default(); + let what = job.param.get_int(Param::Cmd).unwrap_or_default(); let param1_s = job.param.get(Param::Arg).unwrap_or_default(); let param1 = CString::yolo(param1_s); let _param2 = CString::yolo(job.param.get(Param::Arg2).unwrap_or_default()); diff --git a/src/dc_mimefactory.rs b/src/dc_mimefactory.rs index b0bd84468..8418b468d 100644 --- a/src/dc_mimefactory.rs +++ b/src/dc_mimefactory.rs @@ -11,7 +11,6 @@ use mmime::mailmime_types_helper::*; use mmime::mailmime_write_mem::*; use mmime::mmapstring::*; use mmime::other::*; -use num_traits::FromPrimitive; use crate::chat::{self, Chat}; use crate::constants::*; @@ -172,10 +171,10 @@ pub unsafe fn dc_mimefactory_load_msg( ) .unwrap(); - let command = factory.msg.param.get_int(Param::Cmd).unwrap_or_default(); + let command = factory.msg.param.get_cmd(); let msg = &factory.msg; - if command == 5 { + if command == SystemMessage::MemberRemovedFromGroup { let email_to_remove = msg.param.get(Param::Arg).unwrap_or_default(); let email_to_remove_c = email_to_remove.strdup(); @@ -199,8 +198,8 @@ pub unsafe fn dc_mimefactory_load_msg( } } } - if command != 6 - && command != 7 + if command != SystemMessage::AutocryptSetupMessage + && command != SystemMessage::SecurejoinMessage && 0 != context .sql .get_config_int(context, "mdns_enabled") @@ -531,12 +530,7 @@ pub unsafe fn dc_mimefactory_render(context: &Context, factory: &mut dc_mimefact } /* build header etc. */ - let command = factory - .msg - .param - .get_int(Param::Cmd) - .and_then(SystemMessage::from_i32) - .unwrap_or_default(); + let command = factory.msg.param.get_cmd(); if chat.typ == Chattype::Group || chat.typ == Chattype::VerifiedGroup { mailimf_fields_add( imf_fields, @@ -554,197 +548,179 @@ pub unsafe fn dc_mimefactory_render(context: &Context, factory: &mut dc_mimefact ), ); - match command { - SystemMessage::Unknown | SystemMessage::LocationOnly => {} - SystemMessage::MemberRemovedFromGroup => { - let email_to_remove = factory - .msg - .param - .get(Param::Arg) - .unwrap_or_default() - .strdup(); - if strlen(email_to_remove) > 0 { - mailimf_fields_add( - imf_fields, - mailimf_field_new_custom( - strdup( - b"Chat-Group-Member-Removed\x00" as *const u8 - as *const libc::c_char, - ), - email_to_remove, + if command == SystemMessage::MemberRemovedFromGroup { + let email_to_remove = factory + .msg + .param + .get(Param::Arg) + .unwrap_or_default() + .strdup(); + if strlen(email_to_remove) > 0 { + mailimf_fields_add( + imf_fields, + mailimf_field_new_custom( + strdup( + b"Chat-Group-Member-Removed\x00" as *const u8 + as *const libc::c_char, ), - ); - } + email_to_remove, + ), + ); } - SystemMessage::MemberAddedToGroup => { - let msg = &factory.msg; - do_gossip = 1; - let email_to_add = msg.param.get(Param::Arg).unwrap_or_default().strdup(); - if strlen(email_to_add) > 0 { - mailimf_fields_add( - imf_fields, - mailimf_field_new_custom( - strdup( - b"Chat-Group-Member-Added\x00" as *const u8 - as *const libc::c_char, - ), - email_to_add, + } else if command == SystemMessage::MemberAddedToGroup { + let msg = &factory.msg; + do_gossip = 1; + let email_to_add = msg.param.get(Param::Arg).unwrap_or_default().strdup(); + if strlen(email_to_add) > 0 { + mailimf_fields_add( + imf_fields, + mailimf_field_new_custom( + strdup( + b"Chat-Group-Member-Added\x00" as *const u8 + as *const libc::c_char, ), - ); - grpimage = chat.param.get(Param::ProfileImage); - } - if 0 != msg.param.get_int(Param::Arg2).unwrap_or_default() & 0x1 { - info!( - context, - "sending secure-join message \'{}\' >>>>>>>>>>>>>>>>>>>>>>>>>", - "vg-member-added", - ); - mailimf_fields_add( - imf_fields, - mailimf_field_new_custom( - strdup(b"Secure-Join\x00" as *const u8 as *const libc::c_char), - strdup( - b"vg-member-added\x00" as *const u8 as *const libc::c_char, - ), - ), - ); - } + email_to_add, + ), + ); + grpimage = chat.param.get(Param::ProfileImage); } - SystemMessage::GroupNameChanged => { - let msg = &factory.msg; + if 0 != msg.param.get_int(Param::Arg2).unwrap_or_default() & 0x1 { + info!( + context, + "sending secure-join message \'{}\' >>>>>>>>>>>>>>>>>>>>>>>>>", + "vg-member-added", + ); + mailimf_fields_add( + imf_fields, + mailimf_field_new_custom( + strdup(b"Secure-Join\x00" as *const u8 as *const libc::c_char), + strdup(b"vg-member-added\x00" as *const u8 as *const libc::c_char), + ), + ); + } + } else if command == SystemMessage::GroupNameChanged { + let msg = &factory.msg; - let value_to_add = msg.param.get(Param::Arg).unwrap_or_default().strdup(); + let value_to_add = msg.param.get(Param::Arg).unwrap_or_default().strdup(); + mailimf_fields_add( + imf_fields, + mailimf_field_new_custom( + strdup( + b"Chat-Group-Name-Changed\x00" as *const u8 as *const libc::c_char, + ), + value_to_add, + ), + ); + } else if command == SystemMessage::GroupImageChanged { + let msg = &factory.msg; + grpimage = msg.param.get(Param::Arg); + if grpimage.is_none() { mailimf_fields_add( imf_fields, mailimf_field_new_custom( - strdup( - b"Chat-Group-Name-Changed\x00" as *const u8 - as *const libc::c_char, - ), - value_to_add, + strdup(b"Chat-Group-Image\x00" as *const u8 as *const libc::c_char), + dc_strdup(b"0\x00" as *const u8 as *const libc::c_char), ), ); } - SystemMessage::GroupImageChanged => { - let msg = &factory.msg; - grpimage = msg.param.get(Param::Arg); - if grpimage.is_none() { - mailimf_fields_add( - imf_fields, - mailimf_field_new_custom( - strdup( - b"Chat-Group-Image\x00" as *const u8 as *const libc::c_char, - ), - dc_strdup(b"0\x00" as *const u8 as *const libc::c_char), - ), - ); - } - } - SystemMessage::LocationStreamingEnabled => { + } + } + + if command == SystemMessage::LocationStreamingEnabled { + mailimf_fields_add( + imf_fields, + mailimf_field_new_custom( + strdup(b"Chat-Content\x00" as *const u8 as *const libc::c_char), + strdup( + b"location-streaming-enabled\x00" as *const u8 as *const libc::c_char, + ), + ), + ); + } + if command == SystemMessage::AutocryptSetupMessage { + mailimf_fields_add( + imf_fields, + mailimf_field_new_custom( + strdup(b"Autocrypt-Setup-Message\x00" as *const u8 as *const libc::c_char), + strdup(b"v1\x00" as *const u8 as *const libc::c_char), + ), + ); + placeholdertext = factory + .context + .stock_str(StockMessage::AcSetupMsgBody) + .strdup(); + } + if command == SystemMessage::SecurejoinMessage { + let msg = &factory.msg; + let step = msg.param.get(Param::Arg).unwrap_or_default().strdup(); + if strlen(step) > 0 { + info!( + context, + "sending secure-join message \'{}\' >>>>>>>>>>>>>>>>>>>>>>>>>", + as_str(step), + ); + mailimf_fields_add( + imf_fields, + mailimf_field_new_custom( + strdup(b"Secure-Join\x00" as *const u8 as *const libc::c_char), + step, + ), + ); + let param2 = msg.param.get(Param::Arg2).unwrap_or_default().strdup(); + if strlen(param2) > 0 { mailimf_fields_add( imf_fields, mailimf_field_new_custom( - strdup(b"Chat-Content\x00" as *const u8 as *const libc::c_char), - strdup( - b"location-streaming-enabled\x00" as *const u8 - as *const libc::c_char, - ), - ), - ); - } - SystemMessage::AutocryptSetupMessage => { - mailimf_fields_add( - imf_fields, - mailimf_field_new_custom( - strdup( - b"Autocrypt-Setup-Message\x00" as *const u8 - as *const libc::c_char, - ), - strdup(b"v1\x00" as *const u8 as *const libc::c_char), - ), - ); - placeholdertext = factory - .context - .stock_str(StockMessage::AcSetupMsgBody) - .strdup(); - } - SystemMessage::SecurejoinMessage => { - let msg = &factory.msg; - let step = msg.param.get(Param::Arg).unwrap_or_default().strdup(); - if strlen(step) > 0 { - info!( - context, - "sending secure-join message \'{}\' >>>>>>>>>>>>>>>>>>>>>>>>>", - as_str(step), - ); - mailimf_fields_add( - imf_fields, - mailimf_field_new_custom( - strdup(b"Secure-Join\x00" as *const u8 as *const libc::c_char), + if strcmp( step, + b"vg-request-with-auth\x00" as *const u8 as *const libc::c_char, + ) == 0 + || strcmp( + step, + b"vc-request-with-auth\x00" as *const u8 + as *const libc::c_char, + ) == 0 + { + strdup( + b"Secure-Join-Auth\x00" as *const u8 as *const libc::c_char, + ) + } else { + strdup( + b"Secure-Join-Invitenumber\x00" as *const u8 + as *const libc::c_char, + ) + }, + param2, + ), + ); + } + let fingerprint = msg.param.get(Param::Arg3).unwrap_or_default().strdup(); + if strlen(fingerprint) > 0 { + mailimf_fields_add( + imf_fields, + mailimf_field_new_custom( + strdup( + b"Secure-Join-Fingerprint\x00" as *const u8 + as *const libc::c_char, ), - ); - let param2 = msg.param.get(Param::Arg2).unwrap_or_default().strdup(); - if strlen(param2) > 0 { - mailimf_fields_add( - imf_fields, - mailimf_field_new_custom( - if strcmp( - step, - b"vg-request-with-auth\x00" as *const u8 - as *const libc::c_char, - ) == 0 - || strcmp( - step, - b"vc-request-with-auth\x00" as *const u8 - as *const libc::c_char, - ) == 0 - { - strdup( - b"Secure-Join-Auth\x00" as *const u8 - as *const libc::c_char, - ) - } else { - strdup( - b"Secure-Join-Invitenumber\x00" as *const u8 - as *const libc::c_char, - ) - }, - param2, - ), - ); - } - let fingerprint = - msg.param.get(Param::Arg3).unwrap_or_default().strdup(); - if strlen(fingerprint) > 0 { - mailimf_fields_add( - imf_fields, - mailimf_field_new_custom( - strdup( - b"Secure-Join-Fingerprint\x00" as *const u8 - as *const libc::c_char, - ), - fingerprint, - ), - ); - } - let grpid = match msg.param.get(Param::Arg4) { - Some(id) => id.strdup(), - None => std::ptr::null_mut(), - }; - if !grpid.is_null() { - mailimf_fields_add( - imf_fields, - mailimf_field_new_custom( - strdup( - b"Secure-Join-Group\x00" as *const u8 - as *const libc::c_char, - ), - grpid, - ), - ); - } - } + fingerprint, + ), + ); + } + let grpid = match msg.param.get(Param::Arg4) { + Some(id) => id.strdup(), + None => std::ptr::null_mut(), + }; + if !grpid.is_null() { + mailimf_fields_add( + imf_fields, + mailimf_field_new_custom( + strdup( + b"Secure-Join-Group\x00" as *const u8 as *const libc::c_char, + ), + grpid, + ), + ); } } } @@ -1107,13 +1083,7 @@ unsafe fn get_subject( } else { b"\x00" as *const u8 as *const libc::c_char }; - if msg - .param - .get_int(Param::Cmd) - .and_then(SystemMessage::from_i32) - .unwrap_or_default() - == SystemMessage::AutocryptSetupMessage - { + if msg.param.get_cmd() == SystemMessage::AutocryptSetupMessage { ret = context.stock_str(StockMessage::AcSetupMsgSubject).strdup() } else if chat.typ == Chattype::Group || chat.typ == Chattype::VerifiedGroup { ret = format!( diff --git a/src/dc_mimeparser.rs b/src/dc_mimeparser.rs index 32c4cbf86..0247f340a 100644 --- a/src/dc_mimeparser.rs +++ b/src/dc_mimeparser.rs @@ -111,6 +111,7 @@ impl<'a> MimeParser<'a> { if self.lookup_optional_field("Chat-Version").is_some() { self.is_send_by_messenger = true } + if self.lookup_field("Autocrypt-Setup-Message").is_some() { let has_setup_file = self .parts @@ -326,14 +327,12 @@ impl<'a> MimeParser<'a> { } pub fn lookup_optional_field(&self, field_name: &str) -> Option { - if let Some(field) = self.lookup_field(field_name) { - if unsafe { (*field).fld_type } == MAILIMF_FIELD_OPTIONAL_FIELD as libc::c_int { - 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_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) }); } } @@ -1063,22 +1062,28 @@ unsafe fn hash_header(out: &mut HashMap, in_0: *cons let field = cur as *mut mailimf_field; // TODO match on enums /rtn - let key = match (*field).fld_type { - 1 => Some("Return-Path".to_string()), - 9 => Some("Date".to_string()), - 10 => Some("From".to_string()), - 11 => Some("Sender".to_string()), - 12 => Some("Reply-To".to_string()), - 13 => Some("To".to_string()), - 14 => Some("Cc".to_string()), - 15 => Some("Bcc".to_string()), - 16 => Some("Message-ID".to_string()), - 17 => Some("In-Reply-To".to_string()), - 18 => Some("References".to_string()), - 19 => Some("Subject".to_string()), - 22 => { + 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 => { // 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 + // logic. As mmime/dc_mimeparser is scheduled fore replacement + // anyway we just use a lossy conversion. + if !optional_field.is_null() { Some(to_string_lossy((*optional_field).fld_name)) } else { @@ -1088,12 +1093,6 @@ unsafe fn hash_header(out: &mut HashMap, in_0: *cons _ => None, }; if let Some(key) = key { - // 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 - // logic. As mmime/dc_mimeparser is scheduled fore replacement - // anyway we just use a lossy conversion. - 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-") { diff --git a/src/message.rs b/src/message.rs index 021bdbf3e..cc07d9c8d 100644 --- a/src/message.rs +++ b/src/message.rs @@ -9,6 +9,7 @@ use crate::chat::{self, Chat}; use crate::constants::*; use crate::contact::*; use crate::context::*; +use crate::dc_mimeparser::SystemMessage; use crate::dc_tools::*; use crate::error::Error; use crate::events::Event; @@ -767,7 +768,7 @@ pub fn dc_msg_get_summarytext_by_raw( Viewtype::Video => context.stock_str(StockMessage::Video).into_owned(), Viewtype::Voice => context.stock_str(StockMessage::VoiceMessage).into_owned(), Viewtype::Audio | Viewtype::File => { - if param.get_int(Param::Cmd) == Some(6) { + if param.get_cmd() == SystemMessage::AutocryptSetupMessage { append_text = false; context .stock_str(StockMessage::AcSetupMsgSubject) @@ -793,7 +794,7 @@ pub fn dc_msg_get_summarytext_by_raw( } } _ => { - if param.get_int(Param::Cmd) != Some(9) { + if param.get_cmd() != SystemMessage::LocationOnly { "".to_string() } else { append_text = false; @@ -839,10 +840,10 @@ pub fn dc_msg_is_forwarded(msg: &Message) -> bool { } pub fn dc_msg_is_info(msg: &Message) -> bool { - let cmd = msg.param.get_int(Param::Cmd).unwrap_or_default(); + let cmd = msg.param.get_cmd(); msg.from_id == 2i32 as libc::c_uint || msg.to_id == 2i32 as libc::c_uint - || 0 != cmd && cmd != 6i32 + || cmd != SystemMessage::Unknown && cmd != SystemMessage::AutocryptSetupMessage } pub fn dc_msg_is_increation(msg: &Message) -> bool { @@ -854,7 +855,7 @@ pub fn dc_msg_is_setupmessage(msg: &Message) -> bool { return false; } - msg.param.get_int(Param::Cmd) == Some(6) + msg.param.get_cmd() == SystemMessage::AutocryptSetupMessage } pub unsafe fn dc_msg_get_setupcodebegin(context: &Context, msg: &Message) -> *mut libc::c_char { diff --git a/src/param.rs b/src/param.rs index 101aa3549..5b45fec11 100644 --- a/src/param.rs +++ b/src/param.rs @@ -4,6 +4,7 @@ use std::str; use num_traits::FromPrimitive; +use crate::dc_mimeparser::SystemMessage; use crate::error; /// Available param keys. @@ -178,6 +179,13 @@ impl Params { self.get(key).and_then(|s| s.parse().ok()) } + /// Get the parameter behind `Param::Cmd` interpreted as `SystemMessage`. + pub fn get_cmd(&self) -> SystemMessage { + self.get_int(Param::Cmd) + .and_then(SystemMessage::from_i32) + .unwrap_or_default() + } + /// Get the given parameter and parse as `f64`. pub fn get_float(&self, key: Param) -> Option { self.get(key).and_then(|s| s.parse().ok())