mirror of
https://github.com/chatmail/core.git
synced 2026-04-27 10:26:29 +03:00
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:
committed by
GitHub
parent
760332262d
commit
ea6972118a
10
Cargo.lock
generated
10
Cargo.lock
generated
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.");
|
||||
|
||||
@@ -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());
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
1093
src/contact.rs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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")
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
1137
src/dc_contact.rs
1137
src/dc_contact.rs
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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());
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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());
|
||||
|
||||
59
src/dc_qr.rs
59
src/dc_qr.rs
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
91
src/stock.rs
91
src/stock.rs
@@ -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)."
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user