refactor: rusty contact

* refactor(contact): rename and rusty memory allocations
* refactor(contact): use enum to indidcate origin
* refactor(contact): safe blocking and unblocking api
* refactor(contact): only safe and no more cstrings
This commit is contained in:
Friedel Ziegelmayer
2019-08-07 22:20:48 +02:00
committed by GitHub
parent 760332262d
commit ea6972118a
22 changed files with 1566 additions and 1631 deletions

10
Cargo.lock generated
View File

@@ -471,6 +471,7 @@ dependencies = [
"failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"imap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lettre 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -927,6 +928,14 @@ dependencies = [
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "itertools"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "itoa"
version = "0.4.4"
@@ -2762,6 +2771,7 @@ dependencies = [
"checksum imap-proto 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c4e77b1d61faf028893531b071cc5584cdd02b6186cebe7f7168ffd8d591339a"
"checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d"
"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08"
"checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358"
"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f"
"checksum keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"

View File

@@ -44,6 +44,7 @@ strum_macros = "0.15.0"
thread-local-object = "0.1.0"
backtrace = "0.3.33"
byteorder = "1.3.1"
itertools = "0.8.0"
[dev-dependencies]
tempfile = "3.0"

View File

@@ -14,7 +14,8 @@ extern crate num_traits;
use num_traits::{FromPrimitive, ToPrimitive};
use std::str::FromStr;
use deltachat::dc_tools::StrExt;
use deltachat::contact::Contact;
use deltachat::dc_tools::{as_str, StrExt};
use deltachat::*;
// TODO: constants
@@ -701,7 +702,7 @@ pub unsafe extern "C" fn dc_marknoticed_contact(context: *mut dc_context_t, cont
assert!(!context.is_null());
let context = &*context;
dc_contact::dc_marknoticed_contact(context, contact_id)
Contact::mark_noticed(context, contact_id)
}
#[no_mangle]
@@ -748,7 +749,7 @@ pub unsafe extern "C" fn dc_get_msg<'a>(
#[no_mangle]
pub unsafe extern "C" fn dc_may_be_valid_addr(addr: *mut libc::c_char) -> libc::c_int {
assert!(!addr.is_null());
dc_contact::dc_may_be_valid_addr(addr) as libc::c_int
contact::may_be_valid_addr(as_str(addr)) as libc::c_int
}
#[no_mangle]
@@ -760,7 +761,7 @@ pub unsafe extern "C" fn dc_lookup_contact_id_by_addr(
assert!(!addr.is_null());
let context = &*context;
dc_contact::dc_lookup_contact_id_by_addr(context, addr)
Contact::lookup_id_by_addr(context, as_str(addr))
}
#[no_mangle]
@@ -771,9 +772,15 @@ pub unsafe extern "C" fn dc_create_contact(
) -> u32 {
assert!(!context.is_null());
assert!(!addr.is_null());
let context = &*context;
dc_contact::dc_create_contact(context, name, addr)
let name = if name.is_null() { "" } else { as_str(name) };
match Contact::create(context, name, as_str(addr)) {
Ok(id) => id,
Err(_) => 0,
}
}
#[no_mangle]
@@ -785,7 +792,10 @@ pub unsafe extern "C" fn dc_add_address_book(
assert!(!addr_book.is_null());
let context = &*context;
dc_contact::dc_add_address_book(context, addr_book)
match Contact::add_address_book(context, as_str(addr_book)) {
Ok(cnt) => cnt as libc::c_int,
Err(_) => 0,
}
}
#[no_mangle]
@@ -797,7 +807,16 @@ pub unsafe extern "C" fn dc_get_contacts(
assert!(!context.is_null());
let context = &*context;
dc_contact::dc_get_contacts(context, flags, query)
let query = if query.is_null() {
None
} else {
Some(as_str(query))
};
match Contact::get_all(context, flags, query) {
Ok(contacts) => contacts,
Err(_) => std::ptr::null_mut(),
}
}
#[no_mangle]
@@ -805,7 +824,7 @@ pub unsafe extern "C" fn dc_get_blocked_cnt(context: *mut dc_context_t) -> libc:
assert!(!context.is_null());
let context = &*context;
dc_contact::dc_get_blocked_cnt(context)
Contact::get_blocked_cnt(context) as libc::c_int
}
#[no_mangle]
@@ -815,7 +834,7 @@ pub unsafe extern "C" fn dc_get_blocked_contacts(
assert!(!context.is_null());
let context = &*context;
dc_contact::dc_get_blocked_contacts(context)
Contact::get_all_blocked(context)
}
#[no_mangle]
@@ -827,7 +846,11 @@ pub unsafe extern "C" fn dc_block_contact(
assert!(!context.is_null());
let context = &*context;
dc_contact::dc_block_contact(context, contact_id, block)
if block == 0 {
Contact::unblock(context, contact_id);
} else {
Contact::block(context, contact_id);
}
}
#[no_mangle]
@@ -838,7 +861,7 @@ pub unsafe extern "C" fn dc_get_contact_encrinfo(
assert!(!context.is_null());
let context = &*context;
dc_contact::dc_get_contact_encrinfo(context, contact_id)
Contact::get_encrinfo(context, contact_id).strdup()
}
#[no_mangle]
@@ -849,18 +872,23 @@ pub unsafe extern "C" fn dc_delete_contact(
assert!(!context.is_null());
let context = &*context;
dc_contact::dc_delete_contact(context, contact_id) as libc::c_int
match Contact::delete(context, contact_id) {
Ok(_) => 1,
Err(_) => 0,
}
}
#[no_mangle]
pub unsafe extern "C" fn dc_get_contact<'a>(
context: *mut dc_context_t,
contact_id: u32,
) -> *mut dc_contact::dc_contact_t<'a> {
) -> *mut dc_contact_t<'a> {
assert!(!context.is_null());
let context = &*context;
dc_contact::dc_get_contact(context, contact_id)
Contact::get_by_id(context, contact_id)
.map(|contact| Box::into_raw(Box::new(contact)))
.unwrap_or_else(|_| std::ptr::null_mut())
}
#[no_mangle]
@@ -1634,99 +1662,103 @@ pub unsafe extern "C" fn dc_msg_latefiling_mediasize(
// dc_contact_t
#[no_mangle]
pub type dc_contact_t<'a> = dc_contact::dc_contact_t<'a>;
pub type dc_contact_t<'a> = contact::Contact<'a>;
#[no_mangle]
pub unsafe extern "C" fn dc_contact_unref(contact: *mut dc_contact::dc_contact_t) {
pub unsafe extern "C" fn dc_contact_unref(contact: *mut dc_contact_t) {
assert!(!contact.is_null());
dc_contact::dc_contact_unref(contact)
Box::from_raw(contact);
}
#[no_mangle]
pub unsafe extern "C" fn dc_contact_get_id(contact: *mut dc_contact::dc_contact_t) -> u32 {
pub unsafe extern "C" fn dc_contact_get_id(contact: *mut dc_contact_t) -> u32 {
assert!(!contact.is_null());
let contact = &*contact;
dc_contact::dc_contact_get_id(contact)
contact.get_id()
}
#[no_mangle]
pub unsafe extern "C" fn dc_contact_get_addr(
contact: *mut dc_contact::dc_contact_t,
) -> *mut libc::c_char {
pub unsafe extern "C" fn dc_contact_get_addr(contact: *mut dc_contact_t) -> *mut libc::c_char {
assert!(!contact.is_null());
let contact = &*contact;
dc_contact::dc_contact_get_addr(contact)
contact.get_addr().strdup()
}
#[no_mangle]
pub unsafe extern "C" fn dc_contact_get_name(
contact: *mut dc_contact::dc_contact_t,
) -> *mut libc::c_char {
pub unsafe extern "C" fn dc_contact_get_name(contact: *mut dc_contact_t) -> *mut libc::c_char {
assert!(!contact.is_null());
let contact = &*contact;
dc_contact::dc_contact_get_name(contact)
contact.get_name().strdup()
}
#[no_mangle]
pub unsafe extern "C" fn dc_contact_get_display_name(
contact: *mut dc_contact::dc_contact_t,
contact: *mut dc_contact_t,
) -> *mut libc::c_char {
assert!(!contact.is_null());
let contact = &*contact;
dc_contact::dc_contact_get_display_name(contact)
contact.get_display_name().strdup()
}
#[no_mangle]
pub unsafe extern "C" fn dc_contact_get_name_n_addr(
contact: *mut dc_contact::dc_contact_t,
contact: *mut dc_contact_t,
) -> *mut libc::c_char {
assert!(!contact.is_null());
let contact = &*contact;
dc_contact::dc_contact_get_name_n_addr(contact)
contact.get_name_n_addr().strdup()
}
#[no_mangle]
pub unsafe extern "C" fn dc_contact_get_first_name(
contact: *mut dc_contact::dc_contact_t,
contact: *mut dc_contact_t,
) -> *mut libc::c_char {
assert!(!contact.is_null());
let contact = &*contact;
dc_contact::dc_contact_get_first_name(contact)
contact.get_first_name().strdup()
}
#[no_mangle]
pub unsafe extern "C" fn dc_contact_get_profile_image(
contact: *mut dc_contact::dc_contact_t,
contact: *mut dc_contact_t,
) -> *mut libc::c_char {
assert!(!contact.is_null());
let contact = &*contact;
dc_contact::dc_contact_get_profile_image(contact)
contact
.get_profile_image()
.map(|s| s.strdup())
.unwrap_or_else(|| std::ptr::null_mut())
}
#[no_mangle]
pub unsafe extern "C" fn dc_contact_get_color(contact: *mut dc_contact::dc_contact_t) -> u32 {
pub unsafe extern "C" fn dc_contact_get_color(contact: *mut dc_contact_t) -> u32 {
assert!(!contact.is_null());
let contact = &*contact;
dc_contact::dc_contact_get_color(contact)
contact.get_color()
}
#[no_mangle]
pub unsafe extern "C" fn dc_contact_is_blocked(
contact: *mut dc_contact::dc_contact_t,
) -> libc::c_int {
pub unsafe extern "C" fn dc_contact_is_blocked(contact: *mut dc_contact_t) -> libc::c_int {
assert!(!contact.is_null());
let contact = &*contact;
dc_contact::dc_contact_is_blocked(contact)
contact.is_blocked() as libc::c_int
}
#[no_mangle]
pub unsafe extern "C" fn dc_contact_is_verified(
contact: *mut dc_contact::dc_contact_t,
) -> libc::c_int {
pub unsafe extern "C" fn dc_contact_is_verified(contact: *mut dc_contact_t) -> libc::c_int {
assert!(!contact.is_null());
let contact = &*contact;
dc_contact::dc_contact_is_verified(contact)
contact.is_verified() as libc::c_int
}
// dc_lot_t

View File

@@ -4,11 +4,11 @@ use std::str::FromStr;
use deltachat::chatlist::*;
use deltachat::config;
use deltachat::constants::*;
use deltachat::contact::*;
use deltachat::context::*;
use deltachat::dc_array::*;
use deltachat::dc_chat::*;
use deltachat::dc_configure::*;
use deltachat::dc_contact::*;
use deltachat::dc_imex::*;
use deltachat::dc_job::*;
use deltachat::dc_location::*;
@@ -218,9 +218,10 @@ unsafe fn poke_spec(context: &Context, spec: *const libc::c_char) -> libc::c_int
}
unsafe fn log_msg(context: &Context, prefix: impl AsRef<str>, msg: *mut dc_msg_t) {
let contact: *mut dc_contact_t = dc_get_contact(context, dc_msg_get_from_id(msg));
let contact_name: *mut libc::c_char = dc_contact_get_name(contact);
let contact_id: libc::c_int = dc_contact_get_id(contact) as libc::c_int;
let contact = Contact::get_by_id(context, dc_msg_get_from_id(msg)).expect("invalid contact");
let contact_name = contact.get_name();
let contact_id = contact.get_id();
let statestr = match dc_msg_get_state(msg) {
DC_STATE_OUT_PENDING => " o",
DC_STATE_OUT_DELIVERED => "",
@@ -229,7 +230,7 @@ unsafe fn log_msg(context: &Context, prefix: impl AsRef<str>, msg: *mut dc_msg_t
_ => "",
};
let temp2 = dc_timestamp_to_str(dc_msg_get_timestamp(msg));
let msgtext: *mut libc::c_char = dc_msg_get_text(msg);
let msgtext = dc_msg_get_text(msg);
info!(
context,
0,
@@ -242,7 +243,7 @@ unsafe fn log_msg(context: &Context, prefix: impl AsRef<str>, msg: *mut dc_msg_t
""
},
if dc_msg_has_location(msg) { "📍" } else { "" },
as_str(contact_name),
&contact_name,
contact_id,
as_str(msgtext),
if dc_msg_is_starred(msg) { "" } else { "" },
@@ -264,8 +265,6 @@ unsafe fn log_msg(context: &Context, prefix: impl AsRef<str>, msg: *mut dc_msg_t
&temp2,
);
free(msgtext as *mut libc::c_void);
free(contact_name as *mut libc::c_void);
dc_contact_unref(contact);
}
unsafe fn log_msglist(context: &Context, msglist: *mut dc_array_t) {
@@ -303,7 +302,6 @@ unsafe fn log_msglist(context: &Context, msglist: *mut dc_array_t) {
}
unsafe fn log_contactlist(context: &Context, contacts: *mut dc_array_t) {
let mut contact: *mut dc_contact_t;
if !dc_array_search_id(contacts, 1 as uint32_t, 0 as *mut size_t) {
dc_array_add_id(contacts, 1 as uint32_t);
}
@@ -312,13 +310,12 @@ unsafe fn log_contactlist(context: &Context, contacts: *mut dc_array_t) {
let contact_id = dc_array_get_id(contacts, i as size_t);
let line;
let mut line2 = "".to_string();
contact = dc_get_contact(context, contact_id);
if !contact.is_null() {
let name: *mut libc::c_char = dc_contact_get_name(contact);
let addr: *mut libc::c_char = dc_contact_get_addr(contact);
let verified_state: libc::c_int = dc_contact_is_verified(contact);
let verified_str = if 0 != verified_state {
if verified_state == 2 {
if let Ok(contact) = Contact::get_by_id(context, contact_id) {
let name = contact.get_name();
let addr = contact.get_addr();
let verified_state = contact.is_verified();
let verified_str = if VerifiedStatus::Unverified != verified_state {
if verified_state == VerifiedStatus::BidirectVerified {
" √√"
} else {
""
@@ -328,28 +325,26 @@ unsafe fn log_contactlist(context: &Context, contacts: *mut dc_array_t) {
};
line = format!(
"{}{} <{}>",
if !name.is_null() && 0 != *name.offset(0isize) as libc::c_int {
as_str(name)
if !name.is_empty() {
&name
} else {
"<name unset>"
},
verified_str,
if !addr.is_null() && 0 != *addr.offset(0isize) as libc::c_int {
as_str(addr)
if !addr.is_empty() {
&addr
} else {
"addr unset"
}
);
let peerstate = Peerstate::from_addr(context, &context.sql, as_str(addr));
let peerstate = Peerstate::from_addr(context, &context.sql, &addr);
if peerstate.is_some() && contact_id != 1 as libc::c_uint {
line2 = format!(
", prefer-encrypt={}",
peerstate.as_ref().unwrap().prefer_encrypt
);
}
dc_contact_unref(contact);
free(name as *mut libc::c_void);
free(addr as *mut libc::c_void);
info!(context, 0, "Contact#{}: {}{}", contact_id, line, line2);
}
}
@@ -1060,15 +1055,15 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
dc_delete_msgs(context, ids.as_mut_ptr(), 1);
}
"listcontacts" | "contacts" | "listverified" => {
let contacts = dc_get_contacts(
let contacts = Contact::get_all(
context,
if arg0 == "listverified" {
0x1 | 0x2
} else {
0x2
},
arg1_c,
);
Some(arg1),
)?;
if !contacts.is_null() {
log_contactlist(context, contacts);
println!("{} contacts.", dc_array_get_cnt(contacts) as libc::c_int,);
@@ -1081,33 +1076,22 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
ensure!(!arg1.is_empty(), "Arguments [<name>] <addr> expected.");
if !arg2.is_empty() {
let book = dc_mprintf(
b"%s\n%s\x00" as *const u8 as *const libc::c_char,
arg1_c,
arg2_c,
);
dc_add_address_book(context, book);
free(book as *mut libc::c_void);
let book = format!("{}\n{}", arg1, arg2);
Contact::add_address_book(context, book)?;
} else {
if 0 == dc_create_contact(context, 0 as *const libc::c_char, arg1_c) {
bail!("Failed to create contact");
}
Contact::create(context, "", arg1)?;
}
}
"contactinfo" => {
ensure!(!arg1.is_empty(), "Argument <contact-id> missing.");
let contact_id = arg1.parse()?;
let contact = dc_get_contact(context, contact_id);
let name_n_addr = dc_contact_get_name_n_addr(contact);
let contact = Contact::get_by_id(context, contact_id)?;
let name_n_addr = contact.get_name_n_addr();
let mut res = format!("Contact info for: {}:\n\n", as_str(name_n_addr),);
free(name_n_addr as *mut libc::c_void);
dc_contact_unref(contact);
let mut res = format!("Contact info for: {}:\n\n", name_n_addr);
let encrinfo = dc_get_contact_encrinfo(context, contact_id);
res += as_str(encrinfo);
free(encrinfo as *mut libc::c_void);
res += &Contact::get_encrinfo(context, contact_id);
let chatlist = Chatlist::try_load(context, 0, None, Some(contact_id))?;
let chatlist_cnt = chatlist.len();
@@ -1130,9 +1114,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
}
"delcontact" => {
ensure!(!arg1.is_empty(), "Argument <contact-id> missing.");
if !dc_delete_contact(context, arg1.parse()?) {
bail!("Failed to delete contact");
}
Contact::delete(context, arg1.parse()?)?;
}
"checkqr" => {
ensure!(!arg1.is_empty(), "Argument <qr-content> missing.");

View File

@@ -1,6 +1,6 @@
extern crate deltachat;
use std::ffi::{CStr, CString};
use std::ffi::CStr;
use std::sync::{Arc, RwLock};
use std::{thread, time};
use tempfile::tempdir;
@@ -8,10 +8,10 @@ use tempfile::tempdir;
use deltachat::chatlist::*;
use deltachat::config;
use deltachat::constants::Event;
use deltachat::contact::*;
use deltachat::context::*;
use deltachat::dc_chat::*;
use deltachat::dc_configure::*;
use deltachat::dc_contact::*;
use deltachat::dc_job::{
dc_perform_imap_fetch, dc_perform_imap_idle, dc_perform_imap_jobs, dc_perform_smtp_idle,
dc_perform_smtp_jobs,
@@ -93,9 +93,9 @@ fn main() {
thread::sleep(duration);
let email = CString::new("dignifiedquire@gmail.com").unwrap();
println!("sending a message");
let contact_id = dc_create_contact(&ctx, std::ptr::null(), email.as_ptr());
let contact_id =
Contact::create(&ctx, "dignifiedquire", "dignifiedquire@gmail.com").unwrap();
let chat_id = dc_create_chat_by_contact_id(&ctx, contact_id);
dc_send_text_msg(&ctx, chat_id, "Hi, here is my first message!".into());

View File

@@ -6,7 +6,7 @@ use std::{fmt, str};
use mmime::mailimf_types::*;
use crate::constants::*;
use crate::dc_contact::*;
use crate::contact::*;
use crate::dc_tools::as_str;
use crate::key::*;
@@ -94,7 +94,7 @@ impl Aheader {
match Self::from_str(value) {
Ok(test) => {
if dc_addr_cmp(&test.addr, as_str(wanted_from)) {
if addr_cmp(&test.addr, as_str(wanted_from)) {
if fine_header.is_none() {
fine_header = Some(test);
} else {

View File

@@ -1,7 +1,7 @@
use crate::constants::*;
use crate::contact::*;
use crate::context::*;
use crate::dc_chat::*;
use crate::dc_contact::*;
use crate::dc_lot::*;
use crate::dc_msg::*;
use crate::dc_tools::*;
@@ -261,7 +261,7 @@ impl<'a> Chatlist<'a> {
}
let lastmsg_id = self.ids[index].1;
let mut lastcontact = 0 as *mut dc_contact_t;
let mut lastcontact = None;
if chat.is_null() {
chat = dc_chat_new(self.context);
@@ -282,8 +282,7 @@ impl<'a> Chatlist<'a> {
&& ((*chat).type_0 == DC_CHAT_TYPE_GROUP
|| (*chat).type_0 == DC_CHAT_TYPE_VERIFIED_GROUP)
{
lastcontact = dc_contact_new(self.context);
dc_contact_load_from_db(lastcontact, &self.context.sql, (*lastmsg).from_id);
lastcontact = Contact::load_from_db(self.context, (*lastmsg).from_id).ok();
}
lastmsg
} else {
@@ -295,11 +294,10 @@ impl<'a> Chatlist<'a> {
} else if lastmsg.is_null() || (*lastmsg).from_id == DC_CONTACT_ID_SELF as u32 {
(*ret).text2 = self.context.stock_str(StockMessage::NoMessages).strdup();
} else {
dc_lot_fill(ret, lastmsg, chat, lastcontact, self.context);
dc_lot_fill(ret, lastmsg, chat, lastcontact.as_ref(), self.context);
}
dc_msg_unref(lastmsg);
dc_contact_unref(lastcontact);
ret
}

1093
src/contact.rs Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,9 @@
use std::sync::{Arc, Condvar, Mutex, RwLock};
use crate::constants::*;
use crate::contact::*;
use crate::dc_array::*;
use crate::dc_chat::*;
use crate::dc_contact::*;
use crate::dc_job::*;
use crate::dc_jobthread::*;
use crate::dc_loginparam::*;
@@ -346,7 +346,7 @@ pub unsafe fn dc_get_info(context: &Context) -> *mut libc::c_char {
let chats = dc_get_chat_cnt(context) as usize;
let real_msgs = dc_get_real_msg_cnt(context) as usize;
let deaddrop_msgs = dc_get_deaddrop_msg_cnt(context) as usize;
let contacts = dc_get_real_contact_cnt(context) as usize;
let contacts = Contact::get_real_cnt(context) as usize;
let is_configured = context
.sql
.get_config_int(context, "configured")

View File

@@ -2,9 +2,9 @@ use std::ffi::CString;
use crate::chatlist::*;
use crate::constants::*;
use crate::contact::*;
use crate::context::Context;
use crate::dc_array::*;
use crate::dc_contact::*;
use crate::dc_job::*;
use crate::dc_msg::*;
use crate::dc_tools::*;
@@ -52,7 +52,7 @@ pub unsafe fn dc_create_chat_by_msg_id(context: &Context, msg_id: uint32_t) -> u
dc_unblock_chat(context, (*chat).id);
send_event = 1i32
}
dc_scaleup_contact_origin(context, (*msg).from_id, 0x800i32);
Contact::scaleup_origin_by_id(context, (*msg).from_id, Origin::CreateChat);
}
dc_msg_unref(msg);
@@ -206,7 +206,9 @@ pub unsafe fn dc_create_chat_by_contact_id(context: &Context, contact_id: uint32
dc_unblock_chat(context, chat_id);
send_event = 1i32
}
} else if !dc_real_contact_exists(context, contact_id) && contact_id != 1i32 as libc::c_uint {
} else if !Contact::real_exists_by_id(context, contact_id)
&& contact_id != DC_CONTACT_ID_SELF as u32
{
warn!(
context,
0, "Cannot create chat, contact {} does not exist.", contact_id as libc::c_int,
@@ -222,7 +224,7 @@ pub unsafe fn dc_create_chat_by_contact_id(context: &Context, contact_id: uint32
if 0 != chat_id {
send_event = 1;
}
dc_scaleup_contact_origin(context, contact_id, 0x800i32);
Contact::scaleup_origin_by_id(context, contact_id, Origin::CreateChat);
}
if 0 != send_event {
context.call_cb(Event::MSGS_CHANGED, 0i32 as uintptr_t, 0i32 as uintptr_t);
@@ -239,8 +241,6 @@ pub unsafe fn dc_create_or_lookup_nchat_by_contact_id(
) {
let mut chat_id = 0;
let mut chat_blocked = 0;
let contact: *mut dc_contact_t;
let chat_name: *mut libc::c_char;
if !ret_chat_id.is_null() {
*ret_chat_id = 0;
@@ -264,14 +264,8 @@ pub unsafe fn dc_create_or_lookup_nchat_by_contact_id(
}
return;
}
contact = dc_contact_new(context);
if dc_contact_load_from_db(contact, &context.sql, contact_id) {
chat_name =
if !(*contact).name.is_null() && 0 != *(*contact).name.offset(0isize) as libc::c_int {
(*contact).name
} else {
(*contact).addr
};
if let Ok(contact) = Contact::load_from_db(context, contact_id) {
let chat_name = contact.get_display_name();
if sql::execute(
context,
@@ -279,10 +273,10 @@ pub unsafe fn dc_create_or_lookup_nchat_by_contact_id(
format!(
"INSERT INTO chats (type, name, param, blocked, grpid) VALUES({}, '{}', '{}', {}, '{}')",
100,
as_str(chat_name),
if contact_id == 1 { "K=1" } else { "" },
chat_name,
if contact_id == DC_CONTACT_ID_SELF as u32 { "K=1" } else { "" },
create_blocked,
as_str((*contact).addr),
contact.get_addr(),
),
params![],
).is_ok() {
@@ -291,7 +285,7 @@ pub unsafe fn dc_create_or_lookup_nchat_by_contact_id(
&context.sql,
"chats",
"grpid",
as_str((*contact).addr),
contact.get_addr(),
);
sql::execute(
@@ -303,7 +297,6 @@ pub unsafe fn dc_create_or_lookup_nchat_by_contact_id(
}
}
dc_contact_unref(contact);
if !ret_chat_id.is_null() {
*ret_chat_id = chat_id
}
@@ -1542,15 +1535,18 @@ pub unsafe fn dc_add_contact_to_chat_ex(
) -> libc::c_int {
let mut OK_TO_CONTINUE = true;
let mut success: libc::c_int = 0;
let contact: *mut dc_contact_t = dc_get_contact(context, contact_id);
let contact = Contact::get_by_id(context, contact_id);
let chat: *mut Chat = dc_chat_new(context);
let mut msg: *mut dc_msg_t = dc_msg_new_untyped(context);
if !(contact.is_null() || chat_id <= 9 as libc::c_uint) {
if !(contact.is_err() || chat_id <= 9 as libc::c_uint) {
dc_reset_gossiped_timestamp(context, chat_id);
let contact = contact.unwrap();
/*this also makes sure, not contacts are added to special or normal chats*/
if !(0 == real_group_exists(context, chat_id)
|| !dc_real_contact_exists(context, contact_id) && contact_id != 1 as libc::c_uint
|| !Contact::real_exists_by_id(context, contact_id)
&& contact_id != DC_CONTACT_ID_SELF as u32
|| !dc_chat_load_from_db(chat, chat_id))
{
if !(dc_is_contact_in_chat(context, chat_id, 1 as uint32_t) == 1) {
@@ -1572,7 +1568,7 @@ pub unsafe fn dc_add_contact_to_chat_ex(
.sql
.get_config(context, "configured_addr")
.unwrap_or_default();
if as_str((*contact).addr) != &self_addr {
if contact.get_addr() != &self_addr {
// ourself is added using DC_CONTACT_ID_SELF, do not add it explicitly.
// if SELF is not in the group, members cannot be added at all.
@@ -1584,7 +1580,7 @@ pub unsafe fn dc_add_contact_to_chat_ex(
} else {
// else continue and send status mail
if (*chat).type_0 == 130 {
if dc_contact_is_verified(contact) != 2 {
if contact.is_verified() != VerifiedStatus::BidirectVerified {
error!(
context, 0,
"Only bidirectional verified contacts can be added to verified groups."
@@ -1603,14 +1599,12 @@ pub unsafe fn dc_add_contact_to_chat_ex(
(*msg).type_0 = Viewtype::Text;
(*msg).text = Some(context.stock_system_msg(
StockMessage::MsgAddMember,
as_str((*contact).addr),
contact.get_addr(),
"",
DC_CONTACT_ID_SELF as uint32_t,
));
(*msg).param.set_int(Param::Cmd, 4);
if !(*contact).addr.is_null() {
(*msg).param.set(Param::Arg, as_str((*contact).addr));
}
(*msg).param.set(Param::Arg, contact.get_addr());
(*msg).param.set_int(Param::Arg2, flags);
(*msg).id = dc_send_msg(context, chat_id, msg);
context.call_cb(
@@ -1627,7 +1621,6 @@ pub unsafe fn dc_add_contact_to_chat_ex(
}
}
dc_chat_unref(chat);
dc_contact_unref(contact);
dc_msg_unref(msg);
success
@@ -1689,13 +1682,12 @@ pub unsafe fn dc_remove_contact_from_chat(
chat_id: u32,
contact_id: u32,
) -> libc::c_int {
let mut success: libc::c_int = 0;
let contact: *mut dc_contact_t = dc_get_contact(context, contact_id);
let mut success = 0;
let chat: *mut Chat = dc_chat_new(context);
let mut msg: *mut dc_msg_t = dc_msg_new_untyped(context);
if !(chat_id <= 9 as libc::c_uint
|| contact_id <= 9 as libc::c_uint && contact_id != 1 as libc::c_uint)
|| contact_id <= 9 as libc::c_uint && contact_id != DC_CONTACT_ID_SELF as u32)
{
/* we do not check if "contact_id" exists but just delete all records with the id from chats_contacts */
/* this allows to delete pending references to deleted contacts. Of course, this should _not_ happen. */
@@ -1709,10 +1701,10 @@ pub unsafe fn dc_remove_contact_from_chat(
);
} else {
/* we should respect this - whatever we send to the group, it gets discarded anyway! */
if !contact.is_null() {
if let Ok(contact) = Contact::get_by_id(context, contact_id) {
if (*chat).param.get_int(Param::Unpromoted).unwrap_or_default() == 0 {
(*msg).type_0 = Viewtype::Text;
if (*contact).id == 1 as libc::c_uint {
if contact.id == DC_CONTACT_ID_SELF as u32 {
dc_set_group_explicitly_left(context, (*chat).grpid);
(*msg).text = Some(context.stock_system_msg(
StockMessage::MsgGroupLeft,
@@ -1723,15 +1715,13 @@ pub unsafe fn dc_remove_contact_from_chat(
} else {
(*msg).text = Some(context.stock_system_msg(
StockMessage::MsgDelMember,
as_str((*contact).addr),
contact.get_addr(),
"",
DC_CONTACT_ID_SELF as u32,
));
}
(*msg).param.set_int(Param::Cmd, 5);
if !(*contact).addr.is_null() {
(*msg).param.set(Param::Arg, as_str((*contact).addr));
}
(*msg).param.set(Param::Arg, contact.get_addr());
(*msg).id = dc_send_msg(context, chat_id, msg);
context.call_cb(
Event::MSGS_CHANGED,
@@ -1756,7 +1746,6 @@ pub unsafe fn dc_remove_contact_from_chat(
}
dc_chat_unref(chat);
dc_contact_unref(contact);
dc_msg_unref(msg);
success
@@ -1947,7 +1936,6 @@ pub unsafe fn dc_forward_msgs(
let msg = dc_msg_new_untyped(context);
let chat = dc_chat_new(context);
let contact = dc_contact_new(context);
let mut created_db_entries = Vec::new();
let mut curr_timestamp: i64;
@@ -1981,7 +1969,7 @@ pub unsafe fn dc_forward_msgs(
break;
}
let original_param = (*msg).param.clone();
if (*msg).from_id != 1 {
if (*msg).from_id != DC_CONTACT_ID_SELF as u32 {
(*msg).param.set_int(Param::Forwarded, 1);
}
(*msg).param.remove(Param::GuranteeE2ee);
@@ -2027,7 +2015,6 @@ pub unsafe fn dc_forward_msgs(
created_db_entries[i + 1] as uintptr_t,
);
}
dc_contact_unref(contact);
dc_msg_unref(msg);
dc_chat_unref(chat);
}
@@ -2113,7 +2100,7 @@ pub unsafe fn dc_chat_get_profile_image(chat: *const Chat) -> *mut libc::c_char
let mut image_rel: *mut libc::c_char = 0 as *mut libc::c_char;
let mut image_abs: *mut libc::c_char = 0 as *mut libc::c_char;
let mut contacts: *mut dc_array_t = 0 as *mut dc_array_t;
let mut contact: *mut dc_contact_t = 0 as *mut dc_contact_t;
if !(chat.is_null() || (*chat).magic != 0xc4a7c4a7u32) {
image_rel = (*chat)
.param
@@ -2125,15 +2112,17 @@ pub unsafe fn dc_chat_get_profile_image(chat: *const Chat) -> *mut libc::c_char
} else if (*chat).type_0 == 100i32 {
contacts = dc_get_chat_contacts((*chat).context, (*chat).id);
if !(*contacts).is_empty() {
contact = dc_get_contact((*chat).context, (*contacts).get_id(0));
image_abs = dc_contact_get_profile_image(contact)
if let Ok(contact) = Contact::get_by_id((*chat).context, (*contacts).get_id(0)) {
if let Some(img) = contact.get_profile_image() {
image_abs = img.strdup();
}
}
}
}
}
free(image_rel as *mut libc::c_void);
dc_array_unref(contacts);
dc_contact_unref(contact);
image_abs
}
@@ -2141,13 +2130,14 @@ pub unsafe fn dc_chat_get_profile_image(chat: *const Chat) -> *mut libc::c_char
pub unsafe fn dc_chat_get_color(chat: *const Chat) -> uint32_t {
let mut color: uint32_t = 0i32 as uint32_t;
let mut contacts: *mut dc_array_t = 0 as *mut dc_array_t;
let mut contact: *mut dc_contact_t = 0 as *mut dc_contact_t;
if !(chat.is_null() || (*chat).magic != 0xc4a7c4a7u32) {
if (*chat).type_0 == 100i32 {
contacts = dc_get_chat_contacts((*chat).context, (*chat).id);
if !(*contacts).is_empty() {
contact = dc_get_contact((*chat).context, (*contacts).get_id(0));
color = dc_str_to_color((*contact).addr) as uint32_t
if let Ok(contact) = Contact::get_by_id((*chat).context, (*contacts).get_id(0)) {
color = contact.get_color();
}
}
} else {
color = dc_str_to_color((*chat).name) as uint32_t
@@ -2155,7 +2145,6 @@ pub unsafe fn dc_chat_get_color(chat: *const Chat) -> uint32_t {
}
dc_array_unref(contacts);
dc_contact_unref(contact);
color
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
use crate::contact::*;
use crate::context::Context;
use crate::dc_chat::*;
use crate::dc_contact::*;
use crate::dc_msg::*;
use crate::dc_tools::*;
use crate::stock::StockMessage;
@@ -129,7 +129,7 @@ pub unsafe fn dc_lot_fill(
mut lot: *mut dc_lot_t,
msg: *mut dc_msg_t,
chat: *const Chat,
contact: *const dc_contact_t,
contact: Option<&Contact>,
context: &Context,
) {
if lot.is_null() || (*lot).magic != 0x107107i32 as libc::c_uint || msg.is_null() {
@@ -150,16 +150,24 @@ pub unsafe fn dc_lot_fill(
(*lot).text1 = 0 as *mut libc::c_char;
(*lot).text1_meaning = 0i32
} else if (*chat).type_0 == 120i32 || (*chat).type_0 == 130i32 {
if 0 != dc_msg_is_info(msg) || contact.is_null() {
if 0 != dc_msg_is_info(msg) || contact.is_none() {
(*lot).text1 = 0 as *mut libc::c_char;
(*lot).text1_meaning = 0i32
} else {
if !chat.is_null() && (*chat).id == 1i32 as libc::c_uint {
(*lot).text1 = dc_contact_get_display_name(contact)
if let Some(contact) = contact {
(*lot).text1 = contact.get_display_name().strdup();
} else {
(*lot).text1 = std::ptr::null_mut();
}
} else {
(*lot).text1 = dc_contact_get_first_name(contact)
if let Some(contact) = contact {
(*lot).text1 = contact.get_first_name().strdup();
} else {
(*lot).text1 = std::ptr::null_mut();
}
}
(*lot).text1_meaning = 2i32
(*lot).text1_meaning = 2i32;
}
}

View File

@@ -12,9 +12,9 @@ use mmime::other::*;
use std::ptr;
use crate::constants::*;
use crate::contact::*;
use crate::context::Context;
use crate::dc_chat::*;
use crate::dc_contact::*;
use crate::dc_e2ee::*;
use crate::dc_location::*;
use crate::dc_msg::*;
@@ -294,7 +294,6 @@ pub unsafe fn dc_mimefactory_load_mdn(
}
let mut success = 0;
let mut contact = 0 as *mut dc_contact_t;
(*factory).recipients_names = clist_new();
(*factory).recipients_addr = clist_new();
@@ -306,24 +305,19 @@ pub unsafe fn dc_mimefactory_load_mdn(
.unwrap_or_else(|| 1)
{
// MDNs not enabled - check this is late, in the job. the use may have changed its choice while offline ...
contact = dc_contact_new((*factory).context);
if !(!dc_msg_load_from_db((*factory).msg, (*factory).context, msg_id)
|| !dc_contact_load_from_db(
contact,
&(*factory).context.sql,
(*(*factory).msg).from_id,
))
{
if !(0 != (*contact).blocked || (*(*factory).msg).chat_id <= 9 as libc::c_uint) {
if !dc_msg_load_from_db((*factory).msg, (*factory).context, msg_id) {
return success;
}
if let Ok(contact) = Contact::load_from_db((*factory).context, (*(*factory).msg).from_id) {
if !(contact.is_blocked() || (*(*factory).msg).chat_id <= 9 as libc::c_uint) {
// Do not send MDNs trash etc.; chats.blocked is already checked by the caller in dc_markseen_msgs()
if !((*(*factory).msg).from_id <= 9 as libc::c_uint) {
clist_insert_after(
(*factory).recipients_names,
(*(*factory).recipients_names).last,
(if !(*contact).authname.is_null()
&& 0 != *(*contact).authname.offset(0isize) as libc::c_int
{
dc_strdup((*contact).authname)
(if !contact.get_authname().is_empty() {
contact.get_authname().strdup()
} else {
0 as *mut libc::c_char
}) as *mut libc::c_void,
@@ -331,7 +325,7 @@ pub unsafe fn dc_mimefactory_load_mdn(
clist_insert_after(
(*factory).recipients_addr,
(*(*factory).recipients_addr).last,
dc_strdup((*contact).addr) as *mut libc::c_void,
contact.get_addr().strdup() as *mut libc::c_void,
);
load_from(factory);
(*factory).timestamp = dc_create_smeared_timestamp((*factory).context);
@@ -346,8 +340,6 @@ pub unsafe fn dc_mimefactory_load_mdn(
}
}
dc_contact_unref(contact);
success
}

View File

@@ -11,8 +11,8 @@ use mmime::mailmime_types::*;
use mmime::mmapstring::*;
use mmime::other::*;
use crate::contact::*;
use crate::context::Context;
use crate::dc_contact::*;
use crate::dc_e2ee::*;
use crate::dc_location::*;
use crate::dc_simplify::*;
@@ -422,7 +422,7 @@ pub unsafe fn mailimf_find_first_addr(mb_list: *const mailimf_mailbox_list) -> *
0 as *mut libc::c_void
}) as *mut mailimf_mailbox;
if !mb.is_null() && !(*mb).mb_addr_spec.is_null() {
return dc_addr_normalize((*mb).mb_addr_spec);
return addr_normalize(as_str((*mb).mb_addr_spec)).strdup();
}
cur = if !cur.is_null() {
(*cur).next
@@ -1565,7 +1565,7 @@ pub unsafe fn dc_mimeparser_sender_equals_recipient(mimeparser: &dc_mimeparser_t
let fld: *const mailimf_field;
let mut fld_from: *const mailimf_from = 0 as *const mailimf_from;
let mb: *mut mailimf_mailbox;
let mut from_addr_norm: *mut libc::c_char = 0 as *mut libc::c_char;
if !(*mimeparser).header_root.is_null() {
/* get From: and check there is exactly one sender */
fld = mailimf_find_field(mimeparser.header_root, MAILIMF_FIELD_FROM as libc::c_int);
@@ -1584,17 +1584,16 @@ pub unsafe fn dc_mimeparser_sender_equals_recipient(mimeparser: &dc_mimeparser_t
0 as *mut libc::c_void
}) as *mut mailimf_mailbox;
if !mb.is_null() {
from_addr_norm = dc_addr_normalize((*mb).mb_addr_spec);
let from_addr_norm = addr_normalize(as_str((*mb).mb_addr_spec));
let recipients = mailimf_get_recipients(mimeparser.header_root);
if recipients.len() == 1 {
if recipients.contains(as_str(from_addr_norm)) {
if recipients.contains(from_addr_norm) {
sender_equals_recipient = 1i32;
}
}
}
}
}
free(from_addr_norm as *mut libc::c_void);
sender_equals_recipient
}
@@ -1691,15 +1690,15 @@ pub unsafe fn mailimf_get_recipients(imffields: *mut mailimf_fields) -> HashSet<
/* ******************************************************************************
* low-level-tools for getting a list of all recipients
******************************************************************************/
#[allow(non_snake_case)]
unsafe fn mailimf_get_recipients__add_addr(
recipients: &mut HashSet<String>,
mb: *mut mailimf_mailbox,
) {
if !mb.is_null() {
let addr_norm: *mut libc::c_char = dc_addr_normalize((*mb).mb_addr_spec);
recipients.insert(to_string(addr_norm));
free(addr_norm as *mut libc::c_void);
let addr_norm = addr_normalize(as_str((*mb).mb_addr_spec));
recipients.insert(addr_norm.into());
};
}

View File

@@ -1,9 +1,9 @@
use std::ffi::CString;
use crate::constants::*;
use crate::contact::*;
use crate::context::*;
use crate::dc_chat::*;
use crate::dc_contact::*;
use crate::dc_job::*;
use crate::dc_lot::dc_lot_t;
use crate::dc_lot::*;
@@ -48,12 +48,10 @@ pub struct dc_msg_t<'a> {
// handle messages
pub unsafe fn dc_get_msg_info(context: &Context, msg_id: u32) -> *mut libc::c_char {
let msg = dc_msg_new_untyped(context);
let contact_from = dc_contact_new(context);
let mut p: *mut libc::c_char;
let mut ret = String::new();
dc_msg_load_from_db(msg, context, msg_id);
dc_contact_load_from_db(contact_from, &context.sql, (*msg).from_id);
let rawtxt: Option<String> = context.sql.query_row_col(
context,
@@ -65,7 +63,6 @@ pub unsafe fn dc_get_msg_info(context: &Context, msg_id: u32) -> *mut libc::c_ch
if rawtxt.is_none() {
ret += &format!("Cannot load message #{}.", msg_id as usize);
dc_msg_unref(msg);
dc_contact_unref(contact_from);
return ret.strdup();
}
let rawtxt = rawtxt.unwrap();
@@ -74,12 +71,14 @@ pub unsafe fn dc_get_msg_info(context: &Context, msg_id: u32) -> *mut libc::c_ch
let fts = dc_timestamp_to_str(dc_msg_get_timestamp(msg));
ret += &format!("Sent: {}", fts);
p = dc_contact_get_name_n_addr(contact_from);
ret += &format!(" by {}", to_string(p));
free(p as *mut libc::c_void);
let name = Contact::load_from_db(context, (*msg).from_id)
.map(|contact| contact.get_name_n_addr())
.unwrap_or_default();
ret += &format!(" by {}", name);
ret += "\n";
if (*msg).from_id != 1 as libc::c_uint {
if (*msg).from_id != DC_CONTACT_ID_SELF as libc::c_uint {
let s = dc_timestamp_to_str(if 0 != (*msg).timestamp_rcvd {
(*msg).timestamp_rcvd
} else {
@@ -92,7 +91,6 @@ pub unsafe fn dc_get_msg_info(context: &Context, msg_id: u32) -> *mut libc::c_ch
if (*msg).from_id == 2 || (*msg).to_id == 2 {
// device-internal message, no further details needed
dc_msg_unref(msg);
dc_contact_unref(contact_from);
return ret.strdup();
}
@@ -112,14 +110,11 @@ pub unsafe fn dc_get_msg_info(context: &Context, msg_id: u32) -> *mut libc::c_ch
let fts = dc_timestamp_to_str(ts);
ret += &format!("Read: {}", fts);
let contact = dc_contact_new(context);
dc_contact_load_from_db(contact, &context.sql, contact_id as u32);
p = dc_contact_get_name_n_addr(contact);
ret += &format!(" by {}", as_str(p));
free(p as *mut libc::c_void);
dc_contact_unref(contact);
let name = Contact::load_from_db(context, contact_id as u32)
.map(|contact| contact.get_name_n_addr())
.unwrap_or_default();
ret += &format!(" by {}", name);
ret += "\n";
}
Ok(())
@@ -210,7 +205,6 @@ pub unsafe fn dc_get_msg_info(context: &Context, msg_id: u32) -> *mut libc::c_ch
}
dc_msg_unref(msg);
dc_contact_unref(contact_from);
ret.strdup()
}
@@ -794,8 +788,8 @@ pub unsafe fn dc_msg_get_summary<'a>(
) -> *mut dc_lot_t {
let current_block: u64;
let ret: *mut dc_lot_t = dc_lot_new();
let mut contact: *mut dc_contact_t = 0 as *mut dc_contact_t;
let mut chat_to_delete: *mut Chat = 0 as *mut Chat;
if !(msg.is_null() || (*msg).magic != 0x11561156 as libc::c_uint) {
if chat.is_null() {
chat_to_delete = dc_get_chat((*msg).context, (*msg).chat_id);
@@ -811,16 +805,19 @@ pub unsafe fn dc_msg_get_summary<'a>(
match current_block {
15204159476013091401 => {}
_ => {
if (*msg).from_id != 1 as libc::c_uint
let contact = if (*msg).from_id != DC_CONTACT_ID_SELF as libc::c_uint
&& ((*chat).type_0 == 120 || (*chat).type_0 == 130)
{
contact = dc_get_contact((*chat).context, (*msg).from_id)
}
dc_lot_fill(ret, msg, chat, contact, (*msg).context);
Contact::get_by_id((*chat).context, (*msg).from_id).ok()
} else {
None
};
dc_lot_fill(ret, msg, chat, contact.as_ref(), (*msg).context);
}
}
}
dc_contact_unref(contact);
dc_chat_unref(chat_to_delete);
ret
@@ -1572,12 +1569,8 @@ mod tests {
let d = test::dummy_context();
let ctx = &d.ctx;
let contact = dc_create_contact(
ctx,
b"\x00".as_ptr().cast(),
b"dest@example.com\x00".as_ptr().cast(),
);
assert!(contact != 0);
let contact =
Contact::create(ctx, "", "dest@example.com").expect("failed to create contact");
let res = ctx.set_config(Config::ConfiguredAddr, Some("self@example.com"));
assert!(res.is_ok());

View File

@@ -1,8 +1,8 @@
use percent_encoding::percent_decode_str;
use crate::contact::*;
use crate::context::Context;
use crate::dc_chat::*;
use crate::dc_contact::*;
use crate::dc_lot::*;
use crate::dc_strencode::*;
use crate::dc_tools::*;
@@ -66,8 +66,7 @@ pub unsafe fn dc_check_qr(context: &Context, qr: *const libc::c_char) -> *mut dc
let name_r = percent_decode_str(name_enc)
.decode_utf8()
.expect("invalid name");
name = name_r.strdup();
dc_normalize_name(name);
name = normalize_name(name_r).strdup();
}
invitenumber = param
.get(Param::ProfileImage)
@@ -186,7 +185,7 @@ pub unsafe fn dc_check_qr(context: &Context, qr: *const libc::c_char) -> *mut dc
b";\x00" as *const u8 as *const libc::c_char,
b",\x00" as *const u8 as *const libc::c_char,
);
dc_normalize_name(name);
name = normalize_name(as_str(name)).strdup();
}
}
}
@@ -204,10 +203,10 @@ pub unsafe fn dc_check_qr(context: &Context, qr: *const libc::c_char) -> *mut dc
let mut temp: *mut libc::c_char = dc_urldecode(addr);
free(addr as *mut libc::c_void);
addr = temp;
temp = dc_addr_normalize(addr);
temp = addr_normalize(as_str(addr)).strdup();
free(addr as *mut libc::c_void);
addr = temp;
if !dc_may_be_valid_addr(addr) {
if !may_be_valid_addr(as_str(addr)) {
(*qr_parsed).state = 400i32;
(*qr_parsed).text1 = dc_strdup(
b"Bad e-mail address.\x00" as *const u8 as *const libc::c_char,
@@ -248,19 +247,19 @@ pub unsafe fn dc_check_qr(context: &Context, qr: *const libc::c_char) -> *mut dc
if addr.is_null() || invitenumber.is_null() || auth.is_null() {
if let Some(peerstate) = peerstate {
(*qr_parsed).state = 210i32;
let addr_ptr = if let Some(ref addr) = peerstate.addr {
addr.strdup()
} else {
std::ptr::null()
};
(*qr_parsed).id = dc_add_or_lookup_contact(
let addr = peerstate
.addr
.as_ref()
.map(|s| s.as_str())
.unwrap_or_else(|| "");
(*qr_parsed).id = Contact::add_or_lookup(
context,
0 as *const libc::c_char,
addr_ptr,
0x80i32,
0 as *mut libc::c_int,
);
free(addr_ptr as *mut _);
"",
addr,
Origin::UnhandledQrScan,
)
.map(|(id, _)| id)
.unwrap_or_default();
dc_create_or_lookup_nchat_by_contact_id(
context,
(*qr_parsed).id,
@@ -286,26 +285,28 @@ pub unsafe fn dc_check_qr(context: &Context, qr: *const libc::c_char) -> *mut dc
} else {
(*qr_parsed).state = 200i32
}
(*qr_parsed).id = dc_add_or_lookup_contact(
(*qr_parsed).id = Contact::add_or_lookup(
context,
name,
addr,
0x80i32,
0 as *mut libc::c_int,
);
as_str(name),
as_str(addr),
Origin::UnhandledQrScan,
)
.map(|(id, _)| id)
.unwrap_or_default();
(*qr_parsed).fingerprint = dc_strdup(fingerprint);
(*qr_parsed).invitenumber = dc_strdup(invitenumber);
(*qr_parsed).auth = dc_strdup(auth)
}
} else if !addr.is_null() {
(*qr_parsed).state = 320i32;
(*qr_parsed).id = dc_add_or_lookup_contact(
(*qr_parsed).id = Contact::add_or_lookup(
context,
name,
addr,
0x80i32,
0 as *mut libc::c_int,
as_str(name),
as_str(addr),
Origin::UnhandledQrScan,
)
.map(|(id, _)| id)
.unwrap_or_default();
} else if strstr(
qr,
b"http://\x00" as *const u8 as *const libc::c_char,

View File

@@ -8,10 +8,10 @@ use mmime::other::*;
use sha2::{Digest, Sha256};
use crate::constants::*;
use crate::contact::*;
use crate::context::Context;
use crate::dc_array::*;
use crate::dc_chat::*;
use crate::dc_contact::*;
use crate::dc_job::*;
use crate::dc_location::*;
use crate::dc_mimeparser::*;
@@ -38,7 +38,7 @@ pub unsafe fn dc_receive_imf(
let mut current_block: u64;
/* the function returns the number of created messages in the database */
let mut incoming: libc::c_int = 1;
let mut incoming_origin: libc::c_int = 0;
let mut incoming_origin = Origin::Unknown;
let mut to_self: libc::c_int = 0;
let mut from_id: uint32_t = 0 as uint32_t;
let mut from_id_blocked: libc::c_int = 0;
@@ -103,7 +103,7 @@ pub unsafe fn dc_receive_imf(
dc_add_or_lookup_contacts_by_mailbox_list(
context,
(*fld_from).frm_mb_list,
0x10,
Origin::IncomingUnknownFrom,
from_list,
&mut check_self,
);
@@ -114,7 +114,8 @@ pub unsafe fn dc_receive_imf(
}
} else if dc_array_get_cnt(from_list) >= 1 {
from_id = dc_array_get_id(from_list, 0 as size_t);
incoming_origin = dc_get_contact_origin(context, from_id, &mut from_id_blocked)
incoming_origin =
Contact::get_origin_by_id(context, from_id, &mut from_id_blocked)
}
dc_array_unref(from_list);
}
@@ -127,11 +128,11 @@ pub unsafe fn dc_receive_imf(
context,
(*fld_to).to_addr_list,
if 0 == incoming {
0x4000
} else if incoming_origin >= 0x100 {
0x400
Origin::OutgoingTo
} else if incoming_origin.is_verified() {
Origin::IncomingTo
} else {
0x40
Origin::IncomingUnknownTo
},
to_ids,
&mut to_self,
@@ -147,11 +148,11 @@ pub unsafe fn dc_receive_imf(
context,
(*fld_cc).cc_addr_list,
if 0 == incoming {
0x2000
} else if incoming_origin >= 0x100 {
0x200
Origin::OutgoingCc
} else if incoming_origin.is_verified() {
Origin::IncomingCc
} else {
0x20
Origin::IncomingUnknownCc
},
to_ids,
0 as *mut libc::c_int,
@@ -253,7 +254,7 @@ pub unsafe fn dc_receive_imf(
if chat_id == 0 as libc::c_uint {
let create_blocked: libc::c_int = if 0 != test_normal_chat_id
&& test_normal_chat_id_blocked == 0
|| incoming_origin >= 0x7fffffff
|| incoming_origin.is_start_new_chat()
{
0
} else {
@@ -285,7 +286,7 @@ pub unsafe fn dc_receive_imf(
}
if chat_id == 0 as libc::c_uint {
let create_blocked_0: libc::c_int =
if incoming_origin >= 0x7fffffff || from_id == to_id {
if incoming_origin.is_start_new_chat() || from_id == to_id {
0
} else {
2
@@ -309,16 +310,20 @@ pub unsafe fn dc_receive_imf(
} else if 0
!= dc_is_reply_to_known_message(context, &mime_parser)
{
dc_scaleup_contact_origin(context, from_id, 0x100);
Contact::scaleup_origin_by_id(
context,
from_id,
Origin::IncomingReplyTo,
);
info!(
context,
0,
"Message is a reply to a known message, mark sender as known.",
);
incoming_origin = if incoming_origin > 0x100 {
incoming_origin = if incoming_origin.is_verified() {
incoming_origin
} else {
0x100
Origin::IncomingReplyTo
}
}
}
@@ -327,8 +332,8 @@ pub unsafe fn dc_receive_imf(
chat_id = 3 as uint32_t
}
if 0 != chat_id_blocked && state == 10 {
if incoming_origin < 0x100 && msgrmsg == 0 {
state = 13
if !incoming_origin.is_verified() && msgrmsg == 0 {
state = 13;
}
}
} else {
@@ -353,12 +358,13 @@ pub unsafe fn dc_receive_imf(
}
}
if chat_id == 0 as libc::c_uint && 0 != allow_creation {
let create_blocked_1: libc::c_int =
if 0 != msgrmsg && !dc_is_contact_blocked(context, to_id) {
0
} else {
2
};
let create_blocked_1: libc::c_int = if 0 != msgrmsg
&& !Contact::is_blocked_load(context, to_id)
{
0
} else {
2
};
dc_create_or_lookup_nchat_by_contact_id(
context,
to_id,
@@ -777,28 +783,34 @@ pub unsafe fn dc_receive_imf(
if !mime_parser.location_kml.is_none()
&& chat_id > DC_CHAT_ID_LAST_SPECIAL as libc::c_uint
{
let contact = dc_get_contact(context, from_id);
if !mime_parser.location_kml.as_ref().unwrap().addr.is_null()
&& !contact.is_null()
&& !(*contact).addr.is_null()
&& strcasecmp(
(*contact).addr,
mime_parser.location_kml.as_ref().unwrap().addr,
) == 0
{
let newest_location_id = dc_save_locations(
context,
chat_id,
from_id,
&mime_parser.location_kml.as_ref().unwrap().locations,
0,
);
if newest_location_id != 0 && hidden == 0 && !location_id_written {
dc_set_msg_location_id(context, insert_msg_id, newest_location_id);
if !mime_parser.location_kml.as_ref().unwrap().addr.is_null() {
if let Ok(contact) = Contact::get_by_id(context, from_id) {
if !contact.get_addr().is_empty()
&& contact.get_addr().to_lowercase()
== as_str(mime_parser.location_kml.as_ref().unwrap().addr)
.to_lowercase()
{
let newest_location_id = dc_save_locations(
context,
chat_id,
from_id,
&mime_parser.location_kml.as_ref().unwrap().locations,
0,
);
if newest_location_id != 0
&& hidden == 0
&& !location_id_written
{
dc_set_msg_location_id(
context,
insert_msg_id,
newest_location_id,
);
}
send_event = true;
}
}
send_event = true;
}
dc_contact_unref(contact);
}
if send_event {
context.call_cb(
@@ -1014,9 +1026,8 @@ unsafe fn create_or_lookup_group(
if !optional_field.is_null() {
X_MrRemoveFromGrp = (*optional_field).fld_value;
mime_parser.is_system_message = 5;
let left_group: libc::c_int =
(dc_lookup_contact_id_by_addr(context, X_MrRemoveFromGrp)
== from_id as libc::c_uint) as libc::c_int;
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(
if 0 != left_group {
StockMessage::MsgGroupLeft
@@ -1125,7 +1136,7 @@ unsafe fn create_or_lookup_group(
&& !grpname.is_null()
&& X_MrRemoveFromGrp.is_null()
&& (0 == group_explicitly_left
|| !X_MrAddToGrp.is_null() && dc_addr_cmp(&self_addr, as_str(X_MrAddToGrp)))
|| !X_MrAddToGrp.is_null() && addr_cmp(&self_addr, as_str(X_MrAddToGrp)))
{
/*otherwise, a pending "quit" message may pop up*/
/*re-create explicitly left groups only if ourself is re-added*/
@@ -1255,17 +1266,20 @@ unsafe fn create_or_lookup_group(
params![chat_id as i32],
)
.ok();
if skip.is_null() || !dc_addr_cmp(&self_addr, as_str(skip)) {
if skip.is_null() || !addr_cmp(&self_addr, as_str(skip)) {
dc_add_to_chat_contacts_table(context, chat_id, 1);
}
if from_id > 9 {
if !dc_addr_equals_contact(context, &self_addr, from_id as u32)
&& (skip.is_null()
|| !dc_addr_equals_contact(
context,
to_string(skip),
from_id as u32,
))
if !Contact::addr_equals_contact(
context,
&self_addr,
from_id as u32,
) && (skip.is_null()
|| !Contact::addr_equals_contact(
context,
to_string(skip),
from_id as u32,
))
{
dc_add_to_chat_contacts_table(
context,
@@ -1277,9 +1291,13 @@ unsafe fn create_or_lookup_group(
i = 0;
while i < to_ids_cnt {
let to_id = dc_array_get_id(to_ids, i as size_t);
if !dc_addr_equals_contact(context, &self_addr, to_id)
if !Contact::addr_equals_contact(context, &self_addr, to_id)
&& (skip.is_null()
|| !dc_addr_equals_contact(context, to_string(skip), to_id))
|| !Contact::addr_equals_contact(
context,
to_string(skip),
to_id,
))
{
dc_add_to_chat_contacts_table(context, chat_id, to_id);
}
@@ -1604,26 +1622,21 @@ unsafe fn check_verified_properties(
to_ids: *const dc_array_t,
failure_reason: *mut *mut libc::c_char,
) -> libc::c_int {
let contact = dc_contact_new(context);
let verify_fail = |reason: String| {
*failure_reason = format!("{}. See \"Info\" for details.", reason).strdup();
warn!(context, 0, "{}", reason);
};
let cleanup = || {
dc_contact_unref(contact);
let contact = match Contact::load_from_db(context, from_id) {
Ok(contact) => contact,
Err(_err) => {
verify_fail("Internal Error; cannot load contact".into());
return 0;
}
};
if !dc_contact_load_from_db(contact, &context.sql, from_id) {
verify_fail("Internal Error; cannot load contact".into());
cleanup();
return 0;
}
if 0 == mimeparser.e2ee_helper.encrypted {
verify_fail("This message is not encrypted".into());
cleanup();
return 0;
}
@@ -1632,18 +1645,18 @@ unsafe fn check_verified_properties(
// this check is skipped for SELF as there is no proper SELF-peerstate
// and results in group-splits otherwise.
if from_id != 1 {
let peerstate = Peerstate::from_addr(context, &context.sql, as_str((*contact).addr));
let peerstate = Peerstate::from_addr(context, &context.sql, contact.get_addr());
if peerstate.is_none() || dc_contact_is_verified_ex(contact, peerstate.as_ref()) != 2 {
if peerstate.is_none()
|| contact.is_verified_ex(peerstate.as_ref()) != VerifiedStatus::BidirectVerified
{
verify_fail("The sender of this message is not verified.".into());
cleanup();
return 0;
}
if let Some(peerstate) = peerstate {
if !peerstate.has_verified_key(&mimeparser.e2ee_helper.signatures) {
verify_fail("The message was sent with non-verified encryption.".into());
cleanup();
return 0;
}
}
@@ -1665,7 +1678,6 @@ unsafe fn check_verified_properties(
);
if rows.is_err() {
cleanup();
return 0;
}
for (to_addr, mut is_verified) in rows.unwrap().into_iter() {
@@ -1686,7 +1698,7 @@ unsafe fn check_verified_properties(
context,
0,
"{} has verfied {}.",
as_str((*contact).addr),
contact.get_addr(),
to_addr,
);
let fp = peerstate.gossip_key_fingerprint.clone();
@@ -1702,7 +1714,6 @@ unsafe fn check_verified_properties(
"{} is not a member of this verified group",
to_addr
));
cleanup();
return 0;
}
}
@@ -1883,7 +1894,7 @@ fn is_msgrmsg_rfc724_mid(context: &Context, rfc724_mid: *const libc::c_char) ->
unsafe fn dc_add_or_lookup_contacts_by_address_list(
context: &Context,
adr_list: *const mailimf_address_list,
origin: libc::c_int,
origin: Origin,
ids: *mut dc_array_t,
check_self: *mut libc::c_int,
) {
@@ -1933,7 +1944,7 @@ unsafe fn dc_add_or_lookup_contacts_by_address_list(
unsafe fn dc_add_or_lookup_contacts_by_mailbox_list(
context: &Context,
mb_list: *const mailimf_mailbox_list,
origin: libc::c_int,
origin: Origin,
ids: *mut dc_array_t,
check_self: *mut libc::c_int,
) {
@@ -1971,7 +1982,7 @@ unsafe fn add_or_lookup_contact_by_addr(
context: &Context,
display_name_enc: *const libc::c_char,
addr_spec: *const libc::c_char,
origin: libc::c_int,
origin: Origin,
ids: *mut dc_array_t,
mut check_self: *mut libc::c_int,
) {
@@ -1989,7 +2000,7 @@ unsafe fn add_or_lookup_contact_by_addr(
.get_config(context, "configured_addr")
.unwrap_or_default();
if dc_addr_cmp(self_addr, as_str(addr_spec)) {
if addr_cmp(self_addr, as_str(addr_spec)) {
*check_self = 1;
}
@@ -1997,20 +2008,15 @@ unsafe fn add_or_lookup_contact_by_addr(
return;
}
/* add addr_spec if missing, update otherwise */
let mut display_name_dec = 0 as *mut libc::c_char;
let mut display_name_dec = "".to_string();
if !display_name_enc.is_null() {
display_name_dec = dc_decode_header_words(display_name_enc);
dc_normalize_name(display_name_dec);
let tmp = as_str(dc_decode_header_words(display_name_enc));
display_name_dec = normalize_name(&tmp);
}
/*can be NULL*/
let row_id = dc_add_or_lookup_contact(
context,
display_name_dec,
addr_spec,
origin,
0 as *mut libc::c_int,
);
free(display_name_dec as *mut libc::c_void);
let row_id = Contact::add_or_lookup(context, display_name_dec, as_str(addr_spec), origin)
.map(|(id, _)| id)
.unwrap_or_default();
if 0 != row_id {
if !dc_array_search_id(ids, row_id, 0 as *mut size_t) {
dc_array_add_id(ids, row_id);

View File

@@ -5,11 +5,11 @@ use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC};
use crate::aheader::EncryptPreference;
use crate::constants::*;
use crate::contact::*;
use crate::context::Context;
use crate::dc_array::*;
use crate::dc_chat::*;
use crate::dc_configure::*;
use crate::dc_contact::*;
use crate::dc_e2ee::*;
use crate::dc_lot::*;
use crate::dc_mimeparser::*;
@@ -315,30 +315,23 @@ unsafe fn fingerprint_equals_sender(
return 0;
}
let mut fingerprint_equal: libc::c_int = 0i32;
let contacts: *mut dc_array_t = dc_get_chat_contacts(context, contact_chat_id);
let contact: *mut dc_contact_t = dc_contact_new(context);
let contacts = dc_get_chat_contacts(context, contact_chat_id);
if !(dc_array_get_cnt(contacts) != 1) {
if !dc_contact_load_from_db(
contact,
&context.sql,
dc_array_get_id(contacts, 0i32 as size_t),
) {
if let Ok(contact) = Contact::load_from_db(context, dc_array_get_id(contacts, 0)) {
if let Some(peerstate) = Peerstate::from_addr(context, &context.sql, contact.get_addr())
{
let fingerprint_normalized = dc_normalize_fingerprint(as_str(fingerprint));
if peerstate.public_key_fingerprint.is_some()
&& &fingerprint_normalized == peerstate.public_key_fingerprint.as_ref().unwrap()
{
fingerprint_equal = 1;
}
}
} else {
return 0;
}
if let Some(peerstate) =
Peerstate::from_addr(context, &context.sql, as_str((*contact).addr))
{
let fingerprint_normalized = dc_normalize_fingerprint(as_str(fingerprint));
if peerstate.public_key_fingerprint.is_some()
&& &fingerprint_normalized == peerstate.public_key_fingerprint.as_ref().unwrap()
{
fingerprint_equal = 1;
}
}
}
dc_contact_unref(contact);
dc_array_unref(contacts);
fingerprint_equal
@@ -360,7 +353,7 @@ pub unsafe fn dc_handle_securejoin_handshake(
let mut contact_chat_id_blocked: libc::c_int = 0i32;
let mut grpid: *mut libc::c_char = 0 as *mut libc::c_char;
let mut ret: libc::c_int = 0i32;
let mut contact: *mut dc_contact_t = 0 as *mut dc_contact_t;
if !(contact_id <= 9i32 as libc::c_uint) {
step = lookup_field(mimeparser, "Secure-Join");
if !step.is_null() {
@@ -572,7 +565,11 @@ pub unsafe fn dc_handle_securejoin_handshake(
);
current_block = 4378276786830486580;
} else {
dc_scaleup_contact_origin(context, contact_id, 0x1000000i32);
Contact::scaleup_origin_by_id(
context,
contact_id,
Origin::SecurejoinInvited,
);
info!(context, 0, "Auth verified.",);
secure_connection_established(context, contact_chat_id);
context.call_cb(
@@ -699,16 +696,23 @@ pub unsafe fn dc_handle_securejoin_handshake(
);
current_block = 4378276786830486580;
} else {
dc_scaleup_contact_origin(context, contact_id, 0x2000000i32);
Contact::scaleup_origin_by_id(
context,
contact_id,
Origin::SecurejoinJoined,
);
context.call_cb(
Event::CONTACTS_CHANGED,
0i32 as uintptr_t,
0i32 as uintptr_t,
);
if 0 != join_vg {
if 0 == dc_addr_equals_self(
if !addr_equals_self(
context,
lookup_field(mimeparser, "Chat-Group-Member-Added"),
as_str(lookup_field(
mimeparser,
"Chat-Group-Member-Added",
)),
) {
info!(
context,
@@ -756,22 +760,26 @@ pub unsafe fn dc_handle_securejoin_handshake(
==== Alice - the inviter side ====
==== Step 8 in "Out-of-band verified groups" protocol ====
============================================================ */
contact = dc_get_contact(context, contact_id);
if contact.is_null() || 0 == dc_contact_is_verified(contact) {
if let Ok(contact) = Contact::get_by_id(context, contact_id) {
if contact.is_verified() == VerifiedStatus::Unverified {
warn!(context, 0, "vg-member-added-received invalid.",);
current_block = 4378276786830486580;
} else {
context.call_cb(
Event::SECUREJOIN_INVITER_PROGRESS,
contact_id as uintptr_t,
800i32 as uintptr_t,
);
context.call_cb(
Event::SECUREJOIN_INVITER_PROGRESS,
contact_id as uintptr_t,
1000i32 as uintptr_t,
);
current_block = 10256747982273457880;
}
} else {
warn!(context, 0, "vg-member-added-received invalid.",);
current_block = 4378276786830486580;
} else {
context.call_cb(
Event::SECUREJOIN_INVITER_PROGRESS,
contact_id as uintptr_t,
800i32 as uintptr_t,
);
context.call_cb(
Event::SECUREJOIN_INVITER_PROGRESS,
contact_id as uintptr_t,
1000i32 as uintptr_t,
);
current_block = 10256747982273457880;
}
} else {
current_block = 10256747982273457880;
@@ -786,7 +794,7 @@ pub unsafe fn dc_handle_securejoin_handshake(
}
}
}
dc_contact_unref(contact);
free(scanned_fingerprint_of_alice as *mut libc::c_void);
free(auth as *mut libc::c_void);
free(own_fingerprint as *mut libc::c_void);
@@ -802,23 +810,20 @@ unsafe fn end_bobs_joining(context: &Context, status: libc::c_int) {
unsafe fn secure_connection_established(context: &Context, contact_chat_id: uint32_t) {
let contact_id: uint32_t = chat_id_2_contact_id(context, contact_chat_id);
let contact: *mut dc_contact_t = dc_get_contact(context, contact_id);
let msg = CString::new(context.stock_string_repl_str(
StockMessage::ContactVerified,
if !contact.is_null() {
as_str((*contact).addr)
} else {
"?"
},
))
.unwrap();
let contact = Contact::get_by_id(context, contact_id);
let addr = if let Ok(ref contact) = contact {
contact.get_addr()
} else {
"?"
};
let msg =
CString::new(context.stock_string_repl_str(StockMessage::ContactVerified, addr)).unwrap();
dc_add_device_msg(context, contact_chat_id, msg.as_ptr());
context.call_cb(
Event::CHAT_MODIFIED,
contact_chat_id as uintptr_t,
0i32 as uintptr_t,
);
dc_contact_unref(contact);
}
unsafe fn lookup_field(mimeparser: &dc_mimeparser_t, key: &str) -> *const libc::c_char {
@@ -844,11 +849,11 @@ unsafe fn could_not_establish_secure_connection(
details: *const libc::c_char,
) {
let contact_id: uint32_t = chat_id_2_contact_id(context, contact_chat_id);
let contact = dc_get_contact(context, contact_id);
let contact = Contact::get_by_id(context, contact_id);
let msg = context.stock_string_repl_str(
StockMessage::ContactNotVerified,
if !contact.is_null() {
as_str((*contact).addr)
if let Ok(ref contact) = contact {
contact.get_addr()
} else {
"?"
},
@@ -856,7 +861,6 @@ unsafe fn could_not_establish_secure_connection(
let msg_c = CString::new(msg.as_str()).unwrap();
dc_add_device_msg(context, contact_chat_id, msg_c.as_ptr());
error!(context, 0, "{} ({})", msg, as_str(details));
dc_contact_unref(contact);
}
unsafe fn mark_peer_as_verified(

View File

@@ -539,32 +539,32 @@ pub unsafe fn dc_str_to_clist(
list
}
/* the colors must fulfill some criterions as:
- contrast to black and to white
- work as a text-color
- being noticeable on a typical map
- harmonize together while being different enough
(therefore, we cannot just use random rgb colors :) */
const COLORS: [u32; 16] = [
0xe56555, 0xf28c48, 0x8e85ee, 0x76c84d, 0x5bb6cc, 0x549cdd, 0xd25c99, 0xb37800, 0xf23030,
0x39b249, 0xbb243b, 0x964078, 0x66874f, 0x308ab9, 0x127ed0, 0xbe450c,
];
pub fn dc_str_to_color_safe(s: impl AsRef<str>) -> u32 {
let str_lower = s.as_ref().to_lowercase();
let mut checksum = 0;
let bytes = str_lower.as_bytes();
for i in 0..str_lower.len() {
checksum += (i + 1) * bytes[i] as usize;
checksum %= 0xffffff;
}
let color_index = checksum % COLORS.len();
COLORS[color_index]
}
pub unsafe fn dc_str_to_color(str: *const libc::c_char) -> libc::c_int {
let str_lower: *mut libc::c_char = dc_strlower(str);
/* the colors must fulfill some criterions as:
- contrast to black and to white
- work as a text-color
- being noticeable on a typical map
- harmonize together while being different enough
(therefore, we cannot just use random rgb colors :) */
static mut COLORS: [uint32_t; 16] = [
0xe56555i32 as uint32_t,
0xf28c48i32 as uint32_t,
0x8e85eei32 as uint32_t,
0x76c84di32 as uint32_t,
0x5bb6cci32 as uint32_t,
0x549cddi32 as uint32_t,
0xd25c99i32 as uint32_t,
0xb37800i32 as uint32_t,
0xf23030i32 as uint32_t,
0x39b249i32 as uint32_t,
0xbb243bi32 as uint32_t,
0x964078i32 as uint32_t,
0x66874fi32 as uint32_t,
0x308ab9i32 as uint32_t,
0x127ed0i32 as uint32_t,
0xbe450ci32 as uint32_t,
];
let mut checksum: libc::c_int = 0i32;
let str_len: libc::c_int = strlen(str_lower) as libc::c_int;
let mut i: libc::c_int = 0i32;

View File

@@ -21,6 +21,7 @@ pub mod aheader;
pub mod chatlist;
pub mod config;
pub mod constants;
pub mod contact;
pub mod context;
pub mod imap;
pub mod key;
@@ -39,7 +40,6 @@ pub mod x;
pub mod dc_array;
pub mod dc_chat;
pub mod dc_configure;
pub mod dc_contact;
pub mod dc_dehtml;
pub mod dc_e2ee;
pub mod dc_imex;

View File

@@ -1,12 +1,11 @@
use std::borrow::Cow;
use std::ffi::CString;
use strum::EnumProperty;
use strum_macros::EnumProperty;
use crate::constants::Event;
use crate::contact::*;
use crate::context::Context;
use crate::dc_contact::*;
use crate::dc_tools::*;
use libc::free;
@@ -200,40 +199,30 @@ impl Context {
from_id: u32,
) -> String {
let insert1 = if id == StockMessage::MsgAddMember || id == StockMessage::MsgDelMember {
unsafe {
let param1_c = CString::new(param1.as_ref()).unwrap();
let contact_id = dc_lookup_contact_id_by_addr(self, param1_c.as_ptr());
if contact_id != 0 {
let contact = dc_get_contact(self, contact_id);
let displayname = dc_contact_get_name_n_addr(contact);
let ret = to_string(displayname);
free(contact as *mut libc::c_void);
free(displayname as *mut libc::c_void);
ret
} else {
param1.as_ref().to_string()
}
let contact_id = Contact::lookup_id_by_addr(self, param1.as_ref());
if contact_id != 0 {
Contact::get_by_id(self, contact_id)
.map(|contact| contact.get_name_n_addr())
.unwrap_or_default()
} else {
param1.as_ref().to_string()
}
} else {
param1.as_ref().to_string()
};
let action = self.stock_string_repl_str2(id, insert1, param2.as_ref().to_string());
let action1 = action.trim_end_matches('.');
match from_id {
0 => action,
1 => self.stock_string_repl_str(StockMessage::MsgActionByMe, action1), // DC_CONTACT_ID_SELF
_ => unsafe {
let contact = dc_get_contact(self, from_id);
let displayname = dc_contact_get_display_name(contact);
let ret = self.stock_string_repl_str2(
StockMessage::MsgActionByUser,
action1,
as_str(displayname),
);
free(contact as *mut libc::c_void);
free(displayname as *mut libc::c_void);
ret
},
_ => {
let displayname = Contact::get_by_id(self, from_id)
.map(|contact| contact.get_name_n_addr())
.unwrap_or_default();
self.stock_string_repl_str2(StockMessage::MsgActionByUser, action1, &displayname)
}
}
}
}
@@ -343,11 +332,7 @@ mod tests {
#[test]
fn test_stock_system_msg_add_member_by_me_with_displayname() {
let t = dummy_context();
unsafe {
let name = CString::new("Alice").unwrap();
let addr = CString::new("alice@example.com").unwrap();
assert!(dc_create_contact(&t.ctx, name.as_ptr(), addr.as_ptr()) > 0);
}
Contact::create(&t.ctx, "Alice", "alice@example.com").expect("failed to create contact");
assert_eq!(
t.ctx.stock_system_msg(
StockMessage::MsgAddMember,
@@ -356,23 +341,17 @@ mod tests {
DC_CONTACT_ID_SELF as u32
),
"Member Alice (alice@example.com) added by me."
)
);
}
#[test]
fn test_stock_system_msg_add_member_by_other_with_displayname() {
let t = dummy_context();
let contact_id = unsafe {
let name = CString::new("Alice").unwrap();
let addr = CString::new("alice@example.com").unwrap();
assert!(
dc_create_contact(&t.ctx, name.as_ptr(), addr.as_ptr()) > 0,
"Failed to create contact Alice"
);
let name = CString::new("Bob").unwrap();
let addr = CString::new("bob@example.com").unwrap();
let id = dc_create_contact(&t.ctx, name.as_ptr(), addr.as_ptr());
assert!(id > 0, "Failed to create contact Bob");
let contact_id = {
Contact::create(&t.ctx, "Alice", "alice@example.com")
.expect("Failed to create contact Alice");
let id =
Contact::create(&t.ctx, "Bob", "bob@example.com").expect("failed to create bob");
id
};
assert_eq!(
@@ -382,8 +361,8 @@ mod tests {
"",
contact_id,
),
"Member Alice (alice@example.com) added by Bob."
)
"Member Alice (alice@example.com) added by Bob (bob@example.com)."
);
}
#[test]
@@ -403,21 +382,13 @@ mod tests {
#[test]
fn test_stock_system_msg_grp_name_other() {
let t = dummy_context();
let contact_id = unsafe {
let name = CString::new("Alice").unwrap();
let addr = CString::new("alice@example.com").unwrap();
let id = dc_create_contact(&t.ctx, name.as_ptr(), addr.as_ptr());
assert!(id > 0, "Failed to create contact Alice");
id
};
let id = Contact::create(&t.ctx, "Alice", "alice@example.com")
.expect("failed to create contact");
assert_eq!(
t.ctx.stock_system_msg(
StockMessage::MsgGrpName,
"Some chat",
"Other chat",
contact_id
),
"Group name changed from \"Some chat\" to \"Other chat\" by Alice."
t.ctx
.stock_system_msg(StockMessage::MsgGrpName, "Some chat", "Other chat", id,),
"Group name changed from \"Some chat\" to \"Other chat\" by Alice (alice@example.com)."
)
}
}

View File

@@ -8,11 +8,11 @@ use tempfile::{tempdir, TempDir};
use deltachat::config;
use deltachat::constants::*;
use deltachat::contact::*;
use deltachat::context::*;
use deltachat::dc_array::*;
use deltachat::dc_chat::*;
use deltachat::dc_configure::*;
use deltachat::dc_contact::*;
use deltachat::dc_imex::*;
use deltachat::dc_location::*;
use deltachat::dc_lot::*;
@@ -890,22 +890,18 @@ fn test_stress_tests() {
fn test_get_contacts() {
unsafe {
let context = create_test_context();
let name = CString::yolo("some2");
let contacts = dc_get_contacts(&context.ctx, 0, name.as_ptr());
let contacts = Contact::get_all(&context.ctx, 0, Some("some2")).unwrap();
assert_eq!(dc_array_get_cnt(contacts), 0);
dc_array_unref(contacts);
let name = CString::yolo("bob");
let email = CString::yolo("bob@mail.de");
let id = dc_create_contact(&context.ctx, name.as_ptr(), email.as_ptr());
let id = Contact::create(&context.ctx, "bob", "bob@mail.de").unwrap();
assert_ne!(id, 0);
let contacts = dc_get_contacts(&context.ctx, 0, name.as_ptr());
let contacts = Contact::get_all(&context.ctx, 0, Some("bob")).unwrap();
assert_eq!(dc_array_get_cnt(contacts), 1);
dc_array_unref(contacts);
let name2 = CString::yolo("alice");
let contacts = dc_get_contacts(&context.ctx, 0, name2.as_ptr());
let contacts = Contact::get_all(&context.ctx, 0, Some("alice")).unwrap();
assert_eq!(dc_array_get_cnt(contacts), 0);
dc_array_unref(contacts);
}
@@ -915,10 +911,7 @@ fn test_get_contacts() {
fn test_chat() {
unsafe {
let context = create_test_context();
let name = CString::yolo("bob");
let email = CString::yolo("bob@mail.de");
let contact1 = dc_create_contact(&context.ctx, name.as_ptr(), email.as_ptr());
let contact1 = Contact::create(&context.ctx, "bob", "bob@mail.de").unwrap();
assert_ne!(contact1, 0);
let chat_id = dc_create_chat_by_contact_id(&context.ctx, contact1);