diff --git a/src/chat.rs b/src/chat.rs index ff157df56..078e164dd 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -7,6 +7,7 @@ use crate::config::*; use crate::constants::*; use crate::contact::*; use crate::context::Context; +use crate::dc_mimeparser::SystemMessage; use crate::dc_tools::*; use crate::error::Error; use crate::events::Event; @@ -1669,7 +1670,8 @@ pub fn set_chat_profile_image( if chat.update_param(context).is_ok() { if chat.is_promoted() { let mut msg = dc_msg_new_untyped(); - msg.param.set_int(Param::Cmd, DC_CMD_GROUPIMAGE_CHANGED); + msg.param + .set_int(Param::Cmd, SystemMessage::GroupImageChanged as i32); msg.type_0 = Viewtype::Text; msg.text = Some(context.stock_system_msg( if new_image_rel == "" { diff --git a/src/constants.rs b/src/constants.rs index caaf8bde5..aa6a11a9d 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -314,12 +314,3 @@ pub enum KeyType { Public = 0, Private = 1, } - -pub const DC_CMD_GROUPNAME_CHANGED: libc::c_int = 2; -pub const DC_CMD_GROUPIMAGE_CHANGED: libc::c_int = 3; -pub const DC_CMD_MEMBER_ADDED_TO_GROUP: libc::c_int = 4; -pub const DC_CMD_MEMBER_REMOVED_FROM_GROUP: libc::c_int = 5; -pub const DC_CMD_AUTOCRYPT_SETUP_MESSAGE: libc::c_int = 6; -pub const DC_CMD_SECUREJOIN_MESSAGE: libc::c_int = 7; -pub const DC_CMD_LOCATION_STREAMING_ENABLED: libc::c_int = 8; -pub const DC_CMD_LOCATION_ONLY: libc::c_int = 9; diff --git a/src/dc_mimefactory.rs b/src/dc_mimefactory.rs index 69627708e..b0bd84468 100644 --- a/src/dc_mimefactory.rs +++ b/src/dc_mimefactory.rs @@ -11,11 +11,13 @@ 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::*; use crate::contact::*; use crate::context::{get_version_str, Context}; +use crate::dc_mimeparser::SystemMessage; use crate::dc_strencode::*; use crate::dc_tools::*; use crate::e2ee::*; @@ -529,7 +531,12 @@ pub unsafe fn dc_mimefactory_render(context: &Context, factory: &mut dc_mimefact } /* build header etc. */ - let command = factory.msg.param.get_int(Param::Cmd).unwrap_or_default(); + let command = factory + .msg + .param + .get_int(Param::Cmd) + .and_then(SystemMessage::from_i32) + .unwrap_or_default(); if chat.typ == Chattype::Group || chat.typ == Chattype::VerifiedGroup { mailimf_fields_add( imf_fields, @@ -546,181 +553,202 @@ pub unsafe fn dc_mimefactory_render(context: &Context, factory: &mut dc_mimefact dc_encode_header_words(name.as_ptr()), ), ); - if command == DC_CMD_MEMBER_REMOVED_FROM_GROUP { - 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, - ), - ); - } - } else if command == DC_CMD_MEMBER_ADDED_TO_GROUP { - 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, - ), - ); - 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), - ), - ); - } - } else if command == DC_CMD_GROUPNAME_CHANGED { - let msg = &factory.msg; - 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 == DC_CMD_GROUPIMAGE_CHANGED { - 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), - ), - ); - } - } - } - if command == DC_CMD_LOCATION_STREAMING_ENABLED { - 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 == DC_CMD_AUTOCRYPT_SETUP_MESSAGE { - 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 == DC_CMD_SECUREJOIN_MESSAGE { - 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( - 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 - { + 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"Secure-Join-Auth\x00" as *const u8 as *const libc::c_char, - ) - } else { - strdup( - b"Secure-Join-Invitenumber\x00" as *const u8 + b"Chat-Group-Member-Removed\x00" as *const u8 as *const libc::c_char, - ) - }, - param2, - ), - ); + ), + email_to_remove, + ), + ); + } } - let fingerprint = msg.param.get(Param::Arg3).unwrap_or_default().strdup(); - if strlen(fingerprint) > 0 { + 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, + ), + ); + 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, + ), + ), + ); + } + } + SystemMessage::GroupNameChanged => { + let msg = &factory.msg; + + let value_to_add = msg.param.get(Param::Arg).unwrap_or_default().strdup(); mailimf_fields_add( imf_fields, mailimf_field_new_custom( strdup( - b"Secure-Join-Fingerprint\x00" as *const u8 + b"Chat-Group-Name-Changed\x00" as *const u8 as *const libc::c_char, ), - fingerprint, + value_to_add, ), ); } - let grpid = match msg.param.get(Param::Arg4) { - Some(id) => id.strdup(), - None => std::ptr::null_mut(), - }; - if !grpid.is_null() { + 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 => { + 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"Secure-Join-Group\x00" as *const u8 as *const libc::c_char, + b"Autocrypt-Setup-Message\x00" as *const u8 + as *const libc::c_char, ), - grpid, + 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), + 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( + 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, + ), + ); + } + } } } } + if let Some(grpimage) = grpimage { info!(factory.context, "setting group image '{}'", grpimage); let mut meta = dc_msg_new_untyped(); @@ -1079,7 +1107,13 @@ unsafe fn get_subject( } else { b"\x00" as *const u8 as *const libc::c_char }; - if msg.param.get_int(Param::Cmd).unwrap_or_default() == DC_CMD_AUTOCRYPT_SETUP_MESSAGE { + if msg + .param + .get_int(Param::Cmd) + .and_then(SystemMessage::from_i32) + .unwrap_or_default() + == 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 2c01e5b69..6791d3888 100644 --- a/src/dc_mimeparser.rs +++ b/src/dc_mimeparser.rs @@ -3,6 +3,7 @@ use std::ffi::{CStr, CString}; use std::ptr; use charset::Charset; +use deltachat_derive::{FromSql, ToSql}; use mmime::clist::*; use mmime::mailimf::*; use mmime::mailimf_types::*; @@ -39,11 +40,31 @@ pub struct MimeParser<'a> { pub e2ee_helper: E2eeHelper, pub is_forwarded: bool, pub reports: Vec<*mut mailmime>, - pub is_system_message: libc::c_int, + pub is_system_message: SystemMessage, pub location_kml: Option, pub message_kml: Option, } +#[derive(Debug, Display, Clone, Copy, PartialEq, Eq, FromPrimitive, ToPrimitive, ToSql, FromSql)] +#[repr(i32)] +pub enum SystemMessage { + Unknown = 0, + GroupNameChanged = 2, + GroupImageChanged = 3, + MemberAddedToGroup = 4, + MemberRemovedFromGroup = 5, + AutocryptSetupMessage = 6, + SecurejoinMessage = 7, + LocationStreamingEnabled = 8, + LocationOnly = 9, +} + +impl Default for SystemMessage { + fn default() -> Self { + SystemMessage::Unknown + } +} + impl<'a> MimeParser<'a> { pub fn new(context: &'a Context) -> Self { MimeParser { @@ -59,7 +80,7 @@ impl<'a> MimeParser<'a> { is_forwarded: false, context, reports: Vec::new(), - is_system_message: 0, + is_system_message: SystemMessage::Unknown, location_kml: None, message_kml: None, } @@ -97,7 +118,7 @@ impl<'a> MimeParser<'a> { .any(|p| p.mimetype == DC_MIMETYPE_AC_SETUP_FILE); if has_setup_file { - self.is_system_message = 6i32; + self.is_system_message = SystemMessage::AutocryptSetupMessage; // TODO: replace the following code with this // once drain_filter stabilizes. @@ -127,7 +148,7 @@ impl<'a> MimeParser<'a> { b"location-streaming-enabled\x00" as *const u8 as *const libc::c_char, ) == 0i32 { - self.is_system_message = 8i32; + self.is_system_message = SystemMessage::LocationStreamingEnabled; } } } diff --git a/src/dc_receive_imf.rs b/src/dc_receive_imf.rs index 1920e0cec..70794257b 100644 --- a/src/dc_receive_imf.rs +++ b/src/dc_receive_imf.rs @@ -389,7 +389,7 @@ unsafe fn add_parts( // incoming non-chat messages may be discarded; // maybe this can be optimized later, by checking the state before the message body is downloaded let mut allow_creation = 1; - if mime_parser.is_system_message != DC_CMD_AUTOCRYPT_SETUP_MESSAGE && msgrmsg == 0 { + if mime_parser.is_system_message != SystemMessage::AutocryptSetupMessage && msgrmsg == 0 { let show_emails = context .sql .get_config_int(context, "show_emails") @@ -673,9 +673,9 @@ unsafe fn add_parts( msg_raw.as_ptr(), ) } - if 0 != mime_parser.is_system_message { + if mime_parser.is_system_message != SystemMessage::Unknown { part.param - .set_int(Param::Cmd, mime_parser.is_system_message); + .set_int(Param::Cmd, mime_parser.is_system_message as i32); } stmt.execute(params![ @@ -1080,7 +1080,7 @@ unsafe fn create_or_lookup_group( }; }; - if mime_parser.is_system_message == DC_CMD_LOCATION_STREAMING_ENABLED { + if mime_parser.is_system_message == SystemMessage::LocationStreamingEnabled { better_msg = context.stock_system_msg(StockMessage::MsgLocationEnabled, "", "", from_id as u32) } @@ -1154,7 +1154,7 @@ unsafe fn create_or_lookup_group( } if let Some(optional_field) = mime_parser.lookup_optional_field("Chat-Group-Member-Removed") { X_MrRemoveFromGrp = (*optional_field).fld_value; - mime_parser.is_system_message = DC_CMD_MEMBER_REMOVED_FROM_GROUP; + mime_parser.is_system_message = SystemMessage::MemberRemovedFromGroup; let left_group = (Contact::lookup_id_by_addr(context, as_str(X_MrRemoveFromGrp)) == from_id as u32) as libc::c_int; better_msg = context.stock_system_msg( @@ -1170,7 +1170,7 @@ unsafe fn create_or_lookup_group( } else { if let Some(optional_field) = mime_parser.lookup_optional_field("Chat-Group-Member-Added") { X_MrAddToGrp = (*optional_field).fld_value; - mime_parser.is_system_message = DC_CMD_MEMBER_ADDED_TO_GROUP; + mime_parser.is_system_message = SystemMessage::MemberAddedToGroup; if let Some(optional_field) = mime_parser.lookup_optional_field("Chat-Group-Image") { // fld_value is a pointer somewhere into mime_parser, must not be freed X_MrGrpImageChanged = as_str((*optional_field).fld_value).to_string(); @@ -1186,7 +1186,7 @@ unsafe fn create_or_lookup_group( mime_parser.lookup_optional_field("Chat-Group-Name-Changed") { X_MrGrpNameChanged = 1; - mime_parser.is_system_message = DC_CMD_GROUPNAME_CHANGED; + mime_parser.is_system_message = SystemMessage::GroupNameChanged; better_msg = context.stock_system_msg( StockMessage::MsgGrpName, as_str((*optional_field).fld_value), @@ -1198,7 +1198,7 @@ unsafe fn create_or_lookup_group( { // fld_value is a pointer somewhere into mime_parser, must not be freed X_MrGrpImageChanged = as_str((*optional_field).fld_value).to_string(); - mime_parser.is_system_message = DC_CMD_GROUPIMAGE_CHANGED; + mime_parser.is_system_message = SystemMessage::GroupImageChanged; better_msg = context.stock_system_msg( if X_MrGrpImageChanged == "0" { StockMessage::MsgGrpImgDeleted