refactor(params): rustify

This commit is contained in:
Friedel Ziegelmayer
2019-07-29 01:49:53 +02:00
committed by GitHub
parent 669ed0e0df
commit 188da2a020
23 changed files with 912 additions and 1191 deletions

8
Cargo.lock generated
View File

@@ -477,7 +477,7 @@ dependencies = [
"native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"num-derive 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "num-derive 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"pgp 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "pgp 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1424,6 +1424,11 @@ name = "percent-encoding"
version = "1.0.1" version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "percent-encoding"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "pgp" name = "pgp"
version = "0.2.1" version = "0.2.1"
@@ -2815,6 +2820,7 @@ dependencies = [
"checksum parking_lot_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cb88cb1cb3790baa6776844f968fea3be44956cf184fa1be5a03341f5491278c" "checksum parking_lot_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cb88cb1cb3790baa6776844f968fea3be44956cf184fa1be5a03341f5491278c"
"checksum parking_lot_core 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1a7bbaa05312363e0480e1efee133fff1a09ef4a6406b65e226b9a793c223a32" "checksum parking_lot_core 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1a7bbaa05312363e0480e1efee133fff1a09ef4a6406b65e226b9a793c223a32"
"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
"checksum percent-encoding 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba4f28a6faf4ffea762ba8f4baef48c61a6db348647c73095034041fc79dd954"
"checksum pgp 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bb80b37b7debf9a98dc0caca3ed40ddf1d383691208763d0458df0b91521020f" "checksum pgp 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bb80b37b7debf9a98dc0caca3ed40ddf1d383691208763d0458df0b91521020f"
"checksum phf 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "b3da44b85f8e8dfaec21adae67f95d93244b2ecf6ad2a692320598dcc8e6dd18" "checksum phf 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "b3da44b85f8e8dfaec21adae67f95d93244b2ecf6ad2a692320598dcc8e6dd18"
"checksum phf_codegen 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "b03e85129e324ad4166b06b2c7491ae27fe3ec353af72e72cd1654c7225d517e" "checksum phf_codegen 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "b03e85129e324ad4166b06b2c7491ae27fe3ec353af72e72cd1654c7225d517e"

View File

@@ -25,7 +25,7 @@ imap = "1.0.1"
mmime = "0.1.0" mmime = "0.1.0"
base64 = "0.10" base64 = "0.10"
charset = "0.1" charset = "0.1"
percent-encoding = "1.0" percent-encoding = "2.0"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0" serde_json = "1.0"
chrono = "0.4.6" chrono = "0.4.6"

View File

@@ -1322,9 +1322,9 @@ pub unsafe extern "C" fn dc_msg_get_showpadlock(msg: *mut dc_msg::dc_msg_t) -> l
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn dc_msg_get_summary( pub unsafe extern "C" fn dc_msg_get_summary<'a>(
msg: *mut dc_msg::dc_msg_t, msg: *mut dc_msg::dc_msg_t<'a>,
chat: *mut dc_chat_t, chat: *mut dc_chat_t<'a>,
) -> *mut dc_lot::dc_lot_t { ) -> *mut dc_lot::dc_lot_t {
dc_msg::dc_msg_get_summary(msg, chat) dc_msg::dc_msg_get_summary(msg, chat)
} }

View File

@@ -14,6 +14,7 @@ use crate::dc_receive_imf::*;
use crate::dc_tools::*; use crate::dc_tools::*;
use crate::imap::*; use crate::imap::*;
use crate::key::*; use crate::key::*;
use crate::param::Params;
use crate::smtp::*; use crate::smtp::*;
use crate::sql::Sql; use crate::sql::Sql;
use crate::types::*; use crate::types::*;
@@ -225,13 +226,7 @@ unsafe fn cb_precheck_imf(
} }
dc_do_heuristics_moves(context, server_folder, msg_id); dc_do_heuristics_moves(context, server_folder, msg_id);
if 0 != mark_seen { if 0 != mark_seen {
dc_job_add( dc_job_add(context, 130, msg_id as libc::c_int, Params::new(), 0);
context,
130i32,
msg_id as libc::c_int,
0 as *const libc::c_char,
0i32,
);
} }
} }
free(old_server_folder as *mut libc::c_void); free(old_server_folder as *mut libc::c_void);

View File

@@ -7,8 +7,8 @@ use crate::dc_array::*;
use crate::dc_contact::*; use crate::dc_contact::*;
use crate::dc_job::*; use crate::dc_job::*;
use crate::dc_msg::*; use crate::dc_msg::*;
use crate::dc_param::*;
use crate::dc_tools::*; use crate::dc_tools::*;
use crate::param::*;
use crate::sql::{self, Sql}; use crate::sql::{self, Sql};
use crate::stock::StockMessage; use crate::stock::StockMessage;
use crate::types::*; use crate::types::*;
@@ -22,7 +22,7 @@ use crate::x::*;
* and are not updated on database changes; * and are not updated on database changes;
* if you want an update, you have to recreate the object. * if you want an update, you have to recreate the object.
*/ */
#[derive(Copy, Clone)] #[derive(Clone)]
pub struct Chat<'a> { pub struct Chat<'a> {
magic: uint32_t, magic: uint32_t,
pub id: uint32_t, pub id: uint32_t,
@@ -32,7 +32,7 @@ pub struct Chat<'a> {
pub context: &'a Context, pub context: &'a Context,
pub grpid: *mut libc::c_char, pub grpid: *mut libc::c_char,
blocked: libc::c_int, blocked: libc::c_int,
pub param: *mut dc_param_t, pub param: Params,
pub gossiped_timestamp: i64, pub gossiped_timestamp: i64,
is_sending_locations: libc::c_int, is_sending_locations: libc::c_int,
} }
@@ -64,13 +64,21 @@ pub unsafe fn dc_create_chat_by_msg_id(context: &Context, msg_id: uint32_t) -> u
} }
pub unsafe fn dc_chat_new<'a>(context: &'a Context) -> *mut Chat<'a> { pub unsafe fn dc_chat_new<'a>(context: &'a Context) -> *mut Chat<'a> {
let mut chat: *mut Chat; let chat = Chat {
chat = calloc(1, ::std::mem::size_of::<Chat>()) as *mut Chat; magic: 0xc4a7c4a7,
(*chat).magic = 0xc4a7c4a7u32; id: 0,
(*chat).context = context; type_0: 0,
(*chat).type_0 = 0i32; name: std::ptr::null_mut(),
(*chat).param = dc_param_new(); archived: 0,
chat context,
grpid: std::ptr::null_mut(),
blocked: 0,
param: Params::new(),
gossiped_timestamp: 0,
is_sending_locations: 0,
};
Box::into_raw(Box::new(chat))
} }
pub unsafe fn dc_chat_unref(mut chat: *mut Chat) { pub unsafe fn dc_chat_unref(mut chat: *mut Chat) {
@@ -78,9 +86,8 @@ pub unsafe fn dc_chat_unref(mut chat: *mut Chat) {
return; return;
} }
dc_chat_empty(chat); dc_chat_empty(chat);
dc_param_unref((*chat).param); (*chat).magic = 0;
(*chat).magic = 0i32 as uint32_t; Box::from_raw(chat);
free(chat as *mut libc::c_void);
} }
pub unsafe fn dc_chat_empty(mut chat: *mut Chat) { pub unsafe fn dc_chat_empty(mut chat: *mut Chat) {
@@ -95,7 +102,7 @@ pub unsafe fn dc_chat_empty(mut chat: *mut Chat) {
(*chat).grpid = 0 as *mut libc::c_char; (*chat).grpid = 0 as *mut libc::c_char;
(*chat).blocked = 0i32; (*chat).blocked = 0i32;
(*chat).gossiped_timestamp = 0; (*chat).gossiped_timestamp = 0;
dc_param_set_packed((*chat).param, 0 as *const libc::c_char); (*chat).param = Params::new();
} }
pub unsafe fn dc_unblock_chat(context: &Context, chat_id: uint32_t) { pub unsafe fn dc_unblock_chat(context: &Context, chat_id: uint32_t) {
@@ -139,16 +146,12 @@ pub fn dc_chat_load_from_db(chat: *mut Chat, chat_id: u32) -> bool {
unsafe { to_cstring(raw) } unsafe { to_cstring(raw) }
}; };
let packed: String = row.get(4)?; c.param = row.get::<_, String>(4)?.parse().unwrap_or_default();
unsafe {
let p = to_cstring(&packed);
dc_param_set_packed((*chat).param, p);
free(p as *mut _);
};
c.archived = row.get(5)?; c.archived = row.get(5)?;
c.blocked = row.get::<_, Option<i32>>(6)?.unwrap_or_default(); c.blocked = row.get::<_, Option<i32>>(6)?.unwrap_or_default();
c.gossiped_timestamp = row.get(7)?; c.gossiped_timestamp = row.get(7)?;
c.is_sending_locations = row.get(8)?; c.is_sending_locations = row.get(8)?;
Ok(()) Ok(())
}, },
); );
@@ -182,7 +185,7 @@ pub fn dc_chat_load_from_db(chat: *mut Chat, chat_id: u32) -> bool {
(*chat).name = to_cstring((*chat).context.stock_str(StockMessage::StarredMsgs)); (*chat).name = to_cstring((*chat).context.stock_str(StockMessage::StarredMsgs));
}, },
_ => { _ => {
if 0 != unsafe { dc_param_exists((*chat).param, DC_PARAM_SELFTALK as i32) } { if unsafe { &(*chat).param }.exists(Param::Selftalk) {
unsafe { unsafe {
free((*chat).name as *mut libc::c_void); free((*chat).name as *mut libc::c_void);
(*chat).name = (*chat).name =
@@ -387,13 +390,16 @@ unsafe fn prepare_msg_common<'a>(
mut msg: *mut dc_msg_t<'a>, mut msg: *mut dc_msg_t<'a>,
) -> uint32_t { ) -> uint32_t {
let mut OK_TO_CONTINUE = true; let mut OK_TO_CONTINUE = true;
let mut pathNfilename: *mut libc::c_char = 0 as *mut libc::c_char;
(*msg).id = 0i32 as uint32_t; (*msg).id = 0i32 as uint32_t;
(*msg).context = context; (*msg).context = context;
if (*msg).type_0 == DC_MSG_TEXT { if (*msg).type_0 == DC_MSG_TEXT {
/* the caller should check if the message text is empty */ /* the caller should check if the message text is empty */
} else if msgtype_has_file((*msg).type_0) { } else if msgtype_has_file((*msg).type_0) {
pathNfilename = dc_param_get((*msg).param, DC_PARAM_FILE as i32, 0 as *const libc::c_char); let mut pathNfilename = (*msg)
.param
.get(Param::File)
.map(|s| to_cstring(s))
.unwrap_or_else(|| std::ptr::null_mut());
if pathNfilename.is_null() { if pathNfilename.is_null() {
error!( error!(
context, context,
@@ -410,29 +416,34 @@ unsafe fn prepare_msg_common<'a>(
} else if !dc_make_rel_and_copy(context, &mut pathNfilename) { } else if !dc_make_rel_and_copy(context, &mut pathNfilename) {
OK_TO_CONTINUE = false; OK_TO_CONTINUE = false;
} else { } else {
dc_param_set((*msg).param, DC_PARAM_FILE as i32, pathNfilename); (*msg).param.set(Param::File, as_str(pathNfilename));
if (*msg).type_0 == DC_MSG_FILE || (*msg).type_0 == DC_MSG_IMAGE { if (*msg).type_0 == DC_MSG_FILE || (*msg).type_0 == DC_MSG_IMAGE {
/* Correct the type, take care not to correct already very special formats as GIF or VOICE. /* Correct the type, take care not to correct already very special formats as GIF or VOICE.
Typical conversions: Typical conversions:
- from FILE to AUDIO/VIDEO/IMAGE - from FILE to AUDIO/VIDEO/IMAGE
- from FILE/IMAGE to GIF */ - from FILE/IMAGE to GIF */
let mut better_type: libc::c_int = 0i32; let mut better_type = 0;
let mut better_mime: *mut libc::c_char = 0 as *mut libc::c_char; let mut better_mime = std::ptr::null_mut();
dc_msg_guess_msgtype_from_suffix(pathNfilename, &mut better_type, &mut better_mime); dc_msg_guess_msgtype_from_suffix(pathNfilename, &mut better_type, &mut better_mime);
if 0 != better_type { if 0 != better_type && !better_mime.is_null() {
(*msg).type_0 = better_type; (*msg).type_0 = better_type;
dc_param_set((*msg).param, DC_PARAM_MIMETYPE as i32, better_mime); (*msg).param.set(Param::MimeType, as_str(better_mime));
} }
free(better_mime as *mut libc::c_void); free(better_mime as *mut libc::c_void);
} else if 0 == dc_param_exists((*msg).param, DC_PARAM_MIMETYPE as i32) { } else if !(*msg).param.exists(Param::MimeType) {
let mut better_mime_0: *mut libc::c_char = 0 as *mut libc::c_char; let mut better_mime = std::ptr::null_mut();
dc_msg_guess_msgtype_from_suffix( dc_msg_guess_msgtype_from_suffix(
pathNfilename, pathNfilename,
0 as *mut libc::c_int, 0 as *mut libc::c_int,
&mut better_mime_0, &mut better_mime,
); );
dc_param_set((*msg).param, DC_PARAM_MIMETYPE as i32, better_mime_0);
free(better_mime_0 as *mut libc::c_void); if !better_mime.is_null() {
(*msg).param.set(Param::MimeType, as_str(better_mime));
}
free(better_mime as *mut _);
} }
info!( info!(
context, context,
@@ -441,6 +452,8 @@ unsafe fn prepare_msg_common<'a>(
as_str(pathNfilename), as_str(pathNfilename),
(*msg).type_0 (*msg).type_0
); );
free(pathNfilename as *mut _);
} }
} else { } else {
error!( error!(
@@ -463,8 +476,6 @@ unsafe fn prepare_msg_common<'a>(
} }
dc_chat_unref(chat); dc_chat_unref(chat);
} }
/* potential error already logged */
free(pathNfilename as *mut libc::c_void);
(*msg).id (*msg).id
} }
@@ -473,7 +484,7 @@ unsafe fn prepare_msg_common<'a>(
unsafe fn prepare_msg_raw( unsafe fn prepare_msg_raw(
context: &Context, context: &Context,
chat: *mut Chat, chat: *mut Chat,
msg: *const dc_msg_t, msg: *mut dc_msg_t,
timestamp: i64, timestamp: i64,
) -> uint32_t { ) -> uint32_t {
let mut do_guarantee_e2ee: libc::c_int; let mut do_guarantee_e2ee: libc::c_int;
@@ -537,12 +548,8 @@ unsafe fn prepare_msg_raw(
if (*chat).type_0 == DC_CHAT_TYPE_GROUP if (*chat).type_0 == DC_CHAT_TYPE_GROUP
|| (*chat).type_0 == DC_CHAT_TYPE_VERIFIED_GROUP || (*chat).type_0 == DC_CHAT_TYPE_VERIFIED_GROUP
{ {
if dc_param_get_int((*chat).param, DC_PARAM_UNPROMOTED as i32, 0) == 1 { if (*chat).param.get_int(Param::Unpromoted).unwrap_or_default() == 1 {
dc_param_set( (*chat).param.remove(Param::Unpromoted);
(*chat).param,
DC_PARAM_UNPROMOTED as i32,
0 as *const libc::c_char,
);
dc_chat_update_param(chat); dc_chat_update_param(chat);
} }
} }
@@ -558,7 +565,11 @@ unsafe fn prepare_msg_raw(
.get_config_int(context, "e2ee_enabled") .get_config_int(context, "e2ee_enabled")
.unwrap_or_else(|| 1); .unwrap_or_else(|| 1);
if 0 != e2ee_enabled if 0 != e2ee_enabled
&& dc_param_get_int((*msg).param, DC_PARAM_FORCE_PLAINTEXT as i32, 0) == 0 && (*msg)
.param
.get_int(Param::ForcePlaintext)
.unwrap_or_default()
== 0
{ {
let mut can_encrypt = 1; let mut can_encrypt = 1;
let mut all_mutual = 1; let mut all_mutual = 1;
@@ -613,13 +624,9 @@ unsafe fn prepare_msg_raw(
} }
} }
if 0 != do_guarantee_e2ee { if 0 != do_guarantee_e2ee {
dc_param_set_int((*msg).param, DC_PARAM_GUARANTEE_E2EE as i32, 1); (*msg).param.set_int(Param::GuranteeE2ee, 1);
} }
dc_param_set( (*msg).param.remove(Param::ErroneousE2ee);
(*msg).param,
DC_PARAM_ERRONEOUS_E2EE as i32,
0 as *const libc::c_char,
);
if 0 == dc_chat_is_self_talk(chat) if 0 == dc_chat_is_self_talk(chat)
&& 0 != get_parent_mime_headers( && 0 != get_parent_mime_headers(
chat, chat,
@@ -673,7 +680,7 @@ unsafe fn prepare_msg_raw(
// add independent location to database // add independent location to database
if 0 != dc_param_exists((*msg).param, DC_PARAM_SET_LATITUDE as libc::c_int) { if (*msg).param.exists(Param::SetLatitude) {
if sql::execute( if sql::execute(
context, context,
&context.sql, &context.sql,
@@ -684,16 +691,14 @@ unsafe fn prepare_msg_raw(
timestamp, timestamp,
DC_CONTACT_ID_SELF as i32, DC_CONTACT_ID_SELF as i32,
(*chat).id as i32, (*chat).id as i32,
dc_param_get_float( (*msg)
(*msg).param, .param
DC_PARAM_SET_LATITUDE as libc::c_int, .get_float(Param::SetLatitude)
0.0, .unwrap_or_default(),
), (*msg)
dc_param_get_float( .param
(*msg).param, .get_float(Param::SetLongitude)
DC_PARAM_SET_LONGITUDE as libc::c_int, .unwrap_or_default(),
0.0,
),
], ],
) )
.is_ok() .is_ok()
@@ -725,7 +730,7 @@ unsafe fn prepare_msg_raw(
(*msg).type_0, (*msg).type_0,
(*msg).state, (*msg).state,
if !(*msg).text.is_null() { Some(as_str((*msg).text)) } else { None }, if !(*msg).text.is_null() { Some(as_str((*msg).text)) } else { None },
if (*(*msg).param).packed.is_null() { None } else { Some(as_str((*(*msg).param).packed)) }, (*msg).param.to_string(),
(*msg).hidden, (*msg).hidden,
to_string(new_in_reply_to), to_string(new_in_reply_to),
to_string(new_references), to_string(new_references),
@@ -816,9 +821,9 @@ unsafe fn get_parent_mime_headers(
pub unsafe fn dc_chat_is_self_talk(chat: *const Chat) -> libc::c_int { pub unsafe fn dc_chat_is_self_talk(chat: *const Chat) -> libc::c_int {
if chat.is_null() || (*chat).magic != 0xc4a7c4a7u32 { if chat.is_null() || (*chat).magic != 0xc4a7c4a7u32 {
return 0i32; return 0;
} }
dc_param_exists((*chat).param, DC_PARAM_SELFTALK as i32) (*chat).param.exists(Param::Selftalk) as libc::c_int
} }
/******************************************************************************* /*******************************************************************************
@@ -830,7 +835,6 @@ unsafe fn last_msg_in_chat_encrypted(
sql: &Sql, sql: &Sql,
chat_id: uint32_t, chat_id: uint32_t,
) -> libc::c_int { ) -> libc::c_int {
let mut last_is_encrypted: libc::c_int = 0i32;
let packed: Option<String> = sql.query_row_col( let packed: Option<String> = sql.query_row_col(
context, context,
"SELECT param \ "SELECT param \
@@ -840,19 +844,17 @@ unsafe fn last_msg_in_chat_encrypted(
0, 0,
); );
if let Some(packed) = packed { if let Some(ref packed) = packed {
let msg_param = dc_param_new(); match packed.parse::<Params>() {
let packed_c = to_cstring(packed); Ok(param) => param.exists(Param::GuranteeE2ee) as libc::c_int,
dc_param_set_packed(msg_param, packed_c); Err(err) => {
free(packed_c as *mut _); error!(context, 0, "invalid params stored: '{}', {:?}", packed, err);
0
if 0 != dc_param_exists(msg_param, DC_PARAM_GUARANTEE_E2EE as i32) { }
last_is_encrypted = 1;
} }
dc_param_unref(msg_param); } else {
0
} }
last_is_encrypted
} }
// TODO should return bool /rtn // TODO should return bool /rtn
@@ -861,7 +863,7 @@ pub unsafe fn dc_chat_update_param(chat: *mut Chat) -> libc::c_int {
(*chat).context, (*chat).context,
&(*chat).context.sql, &(*chat).context.sql,
"UPDATE chats SET param=? WHERE id=?", "UPDATE chats SET param=? WHERE id=?",
params![to_string((*(*chat).param).packed), (*chat).id as i32], params![(*chat).param.to_string(), (*chat).id as i32],
) )
.is_ok() as libc::c_int .is_ok() as libc::c_int
} }
@@ -921,39 +923,29 @@ pub unsafe fn dc_send_msg<'a>(
(*msg).id as uintptr_t, (*msg).id as uintptr_t,
); );
if 0 != dc_param_exists((*msg).param, DC_PARAM_SET_LATITUDE as libc::c_int) { if (*msg).param.exists(Param::SetLatitude) {
context.call_cb(Event::LOCATION_CHANGED, DC_CONTACT_ID_SELF, 0); context.call_cb(Event::LOCATION_CHANGED, DC_CONTACT_ID_SELF, 0);
} }
if 0 == chat_id { if 0 == chat_id {
let forwards = dc_param_get( let forwards = (*msg).param.get(Param::PrepForwards);
(*msg).param, if let Some(forwards) = forwards {
DC_PARAM_PREP_FORWARDS as i32, for forward in forwards.split(' ') {
0 as *const libc::c_char, let id: i32 = forward.parse().unwrap_or_default();
);
if !forwards.is_null() {
let mut p = forwards;
while 0 != *p {
let id = strtol(p, &mut p, 10) as int32_t;
if 0 == id { if 0 == id {
// avoid hanging if user tampers with db // avoid hanging if user tampers with db
break; break;
} else { } else {
let copy = dc_get_msg(context, id as uint32_t); let copy = dc_get_msg(context, id as u32);
if !copy.is_null() { if !copy.is_null() {
dc_send_msg(context, 0 as uint32_t, copy); dc_send_msg(context, 0, copy);
} }
dc_msg_unref(copy); dc_msg_unref(copy);
} }
} }
dc_param_set( (*msg).param.remove(Param::PrepForwards);
(*msg).param,
DC_PARAM_PREP_FORWARDS as i32,
0 as *const libc::c_char,
);
dc_msg_save_param_to_disk(msg); dc_msg_save_param_to_disk(msg);
} }
free(forwards as *mut libc::c_void);
} }
(*msg).id (*msg).id
@@ -1003,7 +995,6 @@ pub unsafe fn dc_set_draft(context: &Context, chat_id: uint32_t, msg: *mut dc_ms
unsafe fn set_draft_raw(context: &Context, chat_id: uint32_t, msg: *mut dc_msg_t) -> libc::c_int { unsafe fn set_draft_raw(context: &Context, chat_id: uint32_t, msg: *mut dc_msg_t) -> libc::c_int {
let mut OK_TO_CONTINUE = true; let mut OK_TO_CONTINUE = true;
// similar to as dc_set_draft() but does not emit an event // similar to as dc_set_draft() but does not emit an event
let mut pathNfilename: *mut libc::c_char = 0 as *mut libc::c_char;
let prev_draft_msg_id: uint32_t; let prev_draft_msg_id: uint32_t;
let mut sth_changed: libc::c_int = 0i32; let mut sth_changed: libc::c_int = 0i32;
prev_draft_msg_id = get_draft_msg_id(context, chat_id); prev_draft_msg_id = get_draft_msg_id(context, chat_id);
@@ -1018,8 +1009,11 @@ unsafe fn set_draft_raw(context: &Context, chat_id: uint32_t, msg: *mut dc_msg_t
OK_TO_CONTINUE = false; OK_TO_CONTINUE = false;
} }
} else if msgtype_has_file((*msg).type_0) { } else if msgtype_has_file((*msg).type_0) {
pathNfilename = let mut pathNfilename = (*msg)
dc_param_get((*msg).param, DC_PARAM_FILE as i32, 0 as *const libc::c_char); .param
.get(Param::File)
.map(|s| to_cstring(s))
.unwrap_or_else(|| std::ptr::null_mut());
if pathNfilename.is_null() { if pathNfilename.is_null() {
OK_TO_CONTINUE = false; OK_TO_CONTINUE = false;
} else if 0 != dc_msg_is_increation(msg) && !dc_is_blobdir_path(context, pathNfilename) } else if 0 != dc_msg_is_increation(msg) && !dc_is_blobdir_path(context, pathNfilename)
@@ -1028,8 +1022,9 @@ unsafe fn set_draft_raw(context: &Context, chat_id: uint32_t, msg: *mut dc_msg_t
} else if !dc_make_rel_and_copy(context, &mut pathNfilename) { } else if !dc_make_rel_and_copy(context, &mut pathNfilename) {
OK_TO_CONTINUE = false; OK_TO_CONTINUE = false;
} else { } else {
dc_param_set((*msg).param, DC_PARAM_FILE as i32, pathNfilename); (*msg).param.set(Param::File, as_str(pathNfilename));
} }
free(pathNfilename as *mut _);
} else { } else {
OK_TO_CONTINUE = false; OK_TO_CONTINUE = false;
} }
@@ -1050,7 +1045,7 @@ unsafe fn set_draft_raw(context: &Context, chat_id: uint32_t, msg: *mut dc_msg_t
} else { } else {
"" ""
}, },
to_string((*(*msg).param).packed), (*msg).param.to_string(),
1, 1,
], ],
) )
@@ -1060,7 +1055,7 @@ unsafe fn set_draft_raw(context: &Context, chat_id: uint32_t, msg: *mut dc_msg_t
} }
} }
} }
free(pathNfilename as *mut libc::c_void);
sth_changed sth_changed
} }
@@ -1432,7 +1427,7 @@ pub fn dc_delete_chat(context: &Context, chat_id: u32) -> bool {
context.call_cb(Event::MSGS_CHANGED, 0 as uintptr_t, 0 as uintptr_t); context.call_cb(Event::MSGS_CHANGED, 0 as uintptr_t, 0 as uintptr_t);
dc_job_kill_action(context, 105); dc_job_kill_action(context, 105);
unsafe { dc_job_add(context, 105, 0, 0 as *const libc::c_char, 10) }; unsafe { dc_job_add(context, 105, 0, Params::new(), 10) };
true true
} }
@@ -1587,13 +1582,9 @@ pub unsafe fn dc_add_contact_to_chat_ex(
} else { } else {
/* we should respect this - whatever we send to the group, it gets discarded anyway! */ /* we should respect this - whatever we send to the group, it gets discarded anyway! */
if 0 != flags & 0x1 if 0 != flags & 0x1
&& dc_param_get_int((*chat).param, DC_PARAM_UNPROMOTED as i32, 0) == 1 && (*chat).param.get_int(Param::Unpromoted).unwrap_or_default() == 1
{ {
dc_param_set( (*chat).param.remove(Param::Unpromoted);
(*chat).param,
DC_PARAM_UNPROMOTED as i32,
0 as *const libc::c_char,
);
dc_chat_update_param(chat); dc_chat_update_param(chat);
} }
let self_addr = context let self_addr = context
@@ -1627,7 +1618,7 @@ pub unsafe fn dc_add_contact_to_chat_ex(
} }
} }
if OK_TO_CONTINUE { if OK_TO_CONTINUE {
if dc_param_get_int((*chat).param, DC_PARAM_UNPROMOTED as i32, 0) == 0 { if (*chat).param.get_int(Param::Unpromoted).unwrap_or_default() == 0 {
(*msg).type_0 = DC_MSG_TEXT; (*msg).type_0 = DC_MSG_TEXT;
(*msg).text = to_cstring(context.stock_system_msg( (*msg).text = to_cstring(context.stock_system_msg(
StockMessage::MsgAddMember, StockMessage::MsgAddMember,
@@ -1635,9 +1626,11 @@ pub unsafe fn dc_add_contact_to_chat_ex(
"", "",
DC_CONTACT_ID_SELF as uint32_t, DC_CONTACT_ID_SELF as uint32_t,
)); ));
dc_param_set_int((*msg).param, DC_PARAM_CMD as i32, 4); (*msg).param.set_int(Param::Cmd, 4);
dc_param_set((*msg).param, DC_PARAM_CMD_ARG as i32, (*contact).addr); if !(*contact).addr.is_null() {
dc_param_set_int((*msg).param, DC_PARAM_CMD_ARG2 as i32, flags); (*msg).param.set(Param::Arg, as_str((*contact).addr));
}
(*msg).param.set_int(Param::Arg2, flags);
(*msg).id = dc_send_msg(context, chat_id, msg); (*msg).id = dc_send_msg(context, chat_id, msg);
context.call_cb( context.call_cb(
Event::MSGS_CHANGED, Event::MSGS_CHANGED,
@@ -1736,7 +1729,7 @@ pub unsafe fn dc_remove_contact_from_chat(
} else { } else {
/* we should respect this - whatever we send to the group, it gets discarded anyway! */ /* we should respect this - whatever we send to the group, it gets discarded anyway! */
if !contact.is_null() { if !contact.is_null() {
if dc_param_get_int((*chat).param, DC_PARAM_UNPROMOTED as i32, 0) == 0 { if (*chat).param.get_int(Param::Unpromoted).unwrap_or_default() == 0 {
(*msg).type_0 = DC_MSG_TEXT; (*msg).type_0 = DC_MSG_TEXT;
if (*contact).id == 1 as libc::c_uint { if (*contact).id == 1 as libc::c_uint {
dc_set_group_explicitly_left(context, (*chat).grpid); dc_set_group_explicitly_left(context, (*chat).grpid);
@@ -1754,8 +1747,10 @@ pub unsafe fn dc_remove_contact_from_chat(
DC_CONTACT_ID_SELF as u32, DC_CONTACT_ID_SELF as u32,
)); ));
} }
dc_param_set_int((*msg).param, DC_PARAM_CMD as i32, 5); (*msg).param.set_int(Param::Cmd, 5);
dc_param_set((*msg).param, DC_PARAM_CMD_ARG as i32, (*contact).addr); if !(*contact).addr.is_null() {
(*msg).param.set(Param::Arg, as_str((*contact).addr));
}
(*msg).id = dc_send_msg(context, chat_id, msg); (*msg).id = dc_send_msg(context, chat_id, msg);
context.call_cb( context.call_cb(
Event::MSGS_CHANGED, Event::MSGS_CHANGED,
@@ -1849,7 +1844,7 @@ pub unsafe fn dc_set_chat_name(
) )
.is_ok() .is_ok()
{ {
if dc_param_get_int((*chat).param, DC_PARAM_UNPROMOTED as i32, 0i32) == 0i32 { if (*chat).param.get_int(Param::Unpromoted).unwrap_or_default() == 0 {
(*msg).type_0 = DC_MSG_TEXT; (*msg).type_0 = DC_MSG_TEXT;
(*msg).text = to_cstring(context.stock_system_msg( (*msg).text = to_cstring(context.stock_system_msg(
StockMessage::MsgGrpName, StockMessage::MsgGrpName,
@@ -1857,8 +1852,10 @@ pub unsafe fn dc_set_chat_name(
as_str(new_name), as_str(new_name),
DC_CONTACT_ID_SELF as u32, DC_CONTACT_ID_SELF as u32,
)); ));
dc_param_set_int((*msg).param, DC_PARAM_CMD as i32, 2); (*msg).param.set_int(Param::Cmd, 2);
dc_param_set((*msg).param, DC_PARAM_CMD_ARG as i32, (*chat).name); if !(*chat).name.is_null() {
(*msg).param.set(Param::Arg, as_str((*chat).name));
}
(*msg).id = dc_send_msg(context, chat_id, msg); (*msg).id = dc_send_msg(context, chat_id, msg);
context.call_cb( context.call_cb(
Event::MSGS_CHANGED, Event::MSGS_CHANGED,
@@ -1913,12 +1910,13 @@ pub unsafe fn dc_set_chat_profile_image(
} }
} }
if OK_TO_CONTINUE { if OK_TO_CONTINUE {
dc_param_set((*chat).param, DC_PARAM_PROFILE_IMAGE as i32, new_image_rel); (*chat)
.param
.set(Param::ProfileImage, as_str(new_image_rel));
if !(0 == dc_chat_update_param(chat)) { if !(0 == dc_chat_update_param(chat)) {
if dc_param_get_int((*chat).param, DC_PARAM_UNPROMOTED as i32, 0i32) == 0i32 if (*chat).param.get_int(Param::Unpromoted).unwrap_or_default() == 0 {
{ (*msg).param.set_int(Param::Cmd, 3);
dc_param_set_int((*msg).param, DC_PARAM_CMD as i32, 3i32); (*msg).param.set(Param::Arg, as_str(new_image_rel));
dc_param_set((*msg).param, DC_PARAM_CMD_ARG as i32, new_image_rel);
(*msg).type_0 = DC_MSG_TEXT; (*msg).type_0 = DC_MSG_TEXT;
(*msg).text = to_cstring(context.stock_system_msg( (*msg).text = to_cstring(context.stock_system_msg(
if !new_image_rel.is_null() { if !new_image_rel.is_null() {
@@ -1972,7 +1970,6 @@ pub unsafe fn dc_forward_msgs(
let created_db_entries = carray_new(16); let created_db_entries = carray_new(16);
let mut curr_timestamp: i64; let mut curr_timestamp: i64;
let original_param: *mut dc_param_t = dc_param_new();
dc_unarchive_chat(context, chat_id); dc_unarchive_chat(context, chat_id);
if dc_chat_load_from_db(chat, chat_id) { if dc_chat_load_from_db(chat, chat_id) {
curr_timestamp = dc_create_smeared_timestamps(context, msg_cnt); curr_timestamp = dc_create_smeared_timestamps(context, msg_cnt);
@@ -2002,44 +1999,34 @@ pub unsafe fn dc_forward_msgs(
if !dc_msg_load_from_db(msg, context, src_msg_id as u32) { if !dc_msg_load_from_db(msg, context, src_msg_id as u32) {
break; break;
} }
dc_param_set_packed(original_param, (*(*msg).param).packed); let original_param = (*msg).param.clone();
if (*msg).from_id != 1i32 as libc::c_uint { if (*msg).from_id != 1 {
dc_param_set_int((*msg).param, DC_PARAM_FORWARDED as i32, 1i32); (*msg).param.set_int(Param::Forwarded, 1);
} }
dc_param_set( (*msg).param.remove(Param::GuranteeE2ee);
(*msg).param, (*msg).param.remove(Param::ForcePlaintext);
DC_PARAM_GUARANTEE_E2EE as i32, (*msg).param.remove(Param::Cmd);
0 as *const libc::c_char,
);
dc_param_set(
(*msg).param,
DC_PARAM_FORCE_PLAINTEXT as i32,
0 as *const libc::c_char,
);
dc_param_set((*msg).param, DC_PARAM_CMD as i32, 0 as *const libc::c_char);
let new_msg_id: uint32_t; let new_msg_id: uint32_t;
if (*msg).state == DC_STATE_OUT_PREPARING { if (*msg).state == DC_STATE_OUT_PREPARING {
let fresh9 = curr_timestamp; let fresh9 = curr_timestamp;
curr_timestamp = curr_timestamp + 1; curr_timestamp = curr_timestamp + 1;
new_msg_id = prepare_msg_raw(context, chat, msg, fresh9); new_msg_id = prepare_msg_raw(context, chat, msg, fresh9);
let save_param: *mut dc_param_t = (*msg).param; let save_param = (*msg).param.clone();
(*msg).param = original_param; (*msg).param = original_param;
(*msg).id = src_msg_id as uint32_t; (*msg).id = src_msg_id as uint32_t;
let old_fwd: *mut libc::c_char = dc_param_get(
(*msg).param, if let Some(old_fwd) = (*msg).param.get(Param::PrepForwards) {
DC_PARAM_PREP_FORWARDS as i32, let new_fwd = format!("{} {}", old_fwd, new_msg_id);
b"\x00" as *const u8 as *const libc::c_char, (*msg).param.set(Param::PrepForwards, new_fwd);
); } else {
let new_fwd: *mut libc::c_char = dc_mprintf( (*msg)
b"%s %d\x00" as *const u8 as *const libc::c_char, .param
old_fwd, .set(Param::PrepForwards, new_msg_id.to_string());
new_msg_id, }
);
dc_param_set((*msg).param, DC_PARAM_PREP_FORWARDS as i32, new_fwd);
dc_msg_save_param_to_disk(msg); dc_msg_save_param_to_disk(msg);
free(new_fwd as *mut libc::c_void); (*msg).param = save_param;
free(old_fwd as *mut libc::c_void);
(*msg).param = save_param
} else { } else {
(*msg).state = DC_STATE_OUT_PENDING; (*msg).state = DC_STATE_OUT_PENDING;
let fresh10 = curr_timestamp; let fresh10 = curr_timestamp;
@@ -2076,7 +2063,6 @@ pub unsafe fn dc_forward_msgs(
dc_contact_unref(contact); dc_contact_unref(contact);
dc_msg_unref(msg); dc_msg_unref(msg);
dc_chat_unref(chat); dc_chat_unref(chat);
dc_param_unref(original_param);
} }
pub unsafe fn dc_chat_get_id(chat: *const Chat) -> uint32_t { pub unsafe fn dc_chat_get_id(chat: *const Chat) -> uint32_t {
@@ -2107,7 +2093,7 @@ pub unsafe fn dc_chat_get_subtitle(chat: *const Chat) -> *mut libc::c_char {
} }
let mut ret: *mut libc::c_char = std::ptr::null_mut(); let mut ret: *mut libc::c_char = std::ptr::null_mut();
if (*chat).type_0 == 100 && 0 != dc_param_exists((*chat).param, DC_PARAM_SELFTALK as i32) { if (*chat).type_0 == 100 && (*chat).param.exists(Param::Selftalk) {
ret = to_cstring((*chat).context.stock_str(StockMessage::SelfTalkSubTitle)); ret = to_cstring((*chat).context.stock_str(StockMessage::SelfTalkSubTitle));
} else if (*chat).type_0 == 100 { } else if (*chat).type_0 == 100 {
let ret_raw: String = (*chat) let ret_raw: String = (*chat)
@@ -2160,11 +2146,7 @@ pub unsafe fn dc_chat_get_profile_image(chat: *const Chat) -> *mut libc::c_char
let mut contacts: *mut dc_array_t = 0 as *mut dc_array_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; let mut contact: *mut dc_contact_t = 0 as *mut dc_contact_t;
if !(chat.is_null() || (*chat).magic != 0xc4a7c4a7u32) { if !(chat.is_null() || (*chat).magic != 0xc4a7c4a7u32) {
image_rel = dc_param_get( image_rel = to_cstring((*chat).param.get(Param::ProfileImage).unwrap_or_default());
(*chat).param,
DC_PARAM_PROFILE_IMAGE as i32,
0 as *const libc::c_char,
);
if !image_rel.is_null() && 0 != *image_rel.offset(0isize) as libc::c_int { if !image_rel.is_null() && 0 != *image_rel.offset(0isize) as libc::c_int {
image_abs = dc_get_abs_path((*chat).context, image_rel) image_abs = dc_get_abs_path((*chat).context, image_rel)
} else if (*chat).type_0 == 100i32 { } else if (*chat).type_0 == 100i32 {
@@ -2216,9 +2198,9 @@ pub unsafe fn dc_chat_get_archived(chat: *const Chat) -> libc::c_int {
// TODO should return bool /rtn // TODO should return bool /rtn
pub unsafe fn dc_chat_is_unpromoted(chat: *const Chat) -> libc::c_int { pub unsafe fn dc_chat_is_unpromoted(chat: *const Chat) -> libc::c_int {
if chat.is_null() || (*chat).magic != 0xc4a7c4a7u32 { if chat.is_null() || (*chat).magic != 0xc4a7c4a7u32 {
return 0i32; return 0;
} }
dc_param_get_int((*chat).param, DC_PARAM_UNPROMOTED as i32, 0i32) (*chat).param.get_int(Param::Unpromoted).unwrap_or_default() as libc::c_int
} }
// TODO should return bool /rtn // TODO should return bool /rtn

View File

@@ -1,4 +1,4 @@
use percent_encoding::{utf8_percent_encode, DEFAULT_ENCODE_SET}; use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC};
use crate::constants::Event; use crate::constants::Event;
use crate::context::Context; use crate::context::Context;
@@ -9,6 +9,7 @@ use crate::dc_saxparser::*;
use crate::dc_tools::*; use crate::dc_tools::*;
use crate::imap::*; use crate::imap::*;
use crate::oauth2::*; use crate::oauth2::*;
use crate::param::Params;
use crate::types::*; use crate::types::*;
use crate::x::*; use crate::x::*;
@@ -60,9 +61,10 @@ pub unsafe fn dc_configure(context: &Context) {
); );
return; return;
} }
dc_job_kill_action(context, 900i32); dc_job_kill_action(context, 900);
dc_job_add(context, 900i32, 0i32, 0 as *const libc::c_char, 0i32); dc_job_add(context, 900, 0, Params::new(), 0);
} }
pub unsafe fn dc_has_ongoing(context: &Context) -> libc::c_int { pub unsafe fn dc_has_ongoing(context: &Context) -> libc::c_int {
let s_a = context.running_state.clone(); let s_a = context.running_state.clone();
let s = s_a.read().unwrap(); let s = s_a.read().unwrap();
@@ -208,8 +210,7 @@ pub unsafe fn dc_job_do_DC_JOB_CONFIGURE_IMAP(context: &Context, _job: *mut dc_j
let parsed = parsed.unwrap(); let parsed = parsed.unwrap();
let param_domain = parsed.host(); let param_domain = parsed.host();
let param_addr_urlencoded = let param_addr_urlencoded =
utf8_percent_encode(&param.addr, DEFAULT_ENCODE_SET) utf8_percent_encode(&param.addr, NON_ALPHANUMERIC).to_string();
.to_string();
if !s.shall_stop_ongoing { if !s.shall_stop_ongoing {
context.call_cb( context.call_cb(

View File

@@ -12,9 +12,9 @@ use crate::dc_configure::*;
use crate::dc_e2ee::*; use crate::dc_e2ee::*;
use crate::dc_job::*; use crate::dc_job::*;
use crate::dc_msg::*; use crate::dc_msg::*;
use crate::dc_param::*;
use crate::dc_tools::*; use crate::dc_tools::*;
use crate::key::*; use crate::key::*;
use crate::param::*;
use crate::pgp::*; use crate::pgp::*;
use crate::sql::{self, Sql}; use crate::sql::{self, Sql};
use crate::stock::StockMessage; use crate::stock::StockMessage;
@@ -32,13 +32,17 @@ pub unsafe fn dc_imex(
param1: *const libc::c_char, param1: *const libc::c_char,
param2: *const libc::c_char, param2: *const libc::c_char,
) { ) {
let param: *mut dc_param_t = dc_param_new(); let mut param = Params::new();
dc_param_set_int(param, DC_PARAM_CMD as i32, what); param.set_int(Param::Cmd, what as i32);
dc_param_set(param, DC_PARAM_CMD_ARG as i32, param1); if !param1.is_null() {
dc_param_set(param, DC_PARAM_CMD_ARG2 as i32, param2); param.set(Param::Arg, as_str(param1));
dc_job_kill_action(context, 910i32); }
dc_job_add(context, 910i32, 0i32, (*param).packed, 0i32); if !param2.is_null() {
dc_param_unref(param); param.set(Param::Arg2, as_str(param2));
}
dc_job_kill_action(context, 910);
dc_job_add(context, 910, 0, param, 0);
} }
/// Returns the filename of the backup if found, nullptr otherwise. /// Returns the filename of the backup if found, nullptr otherwise.
@@ -142,15 +146,14 @@ pub unsafe fn dc_initiate_key_transfer(context: &Context) -> *mut libc::c_char {
if !(chat_id == 0i32 as libc::c_uint) { if !(chat_id == 0i32 as libc::c_uint) {
msg = dc_msg_new_untyped(context); msg = dc_msg_new_untyped(context);
(*msg).type_0 = DC_MSG_FILE; (*msg).type_0 = DC_MSG_FILE;
dc_param_set((*msg).param, DC_PARAM_FILE as i32, setup_file_name); (*msg).param.set(Param::File, as_str(setup_file_name));
dc_param_set(
(*msg).param, (*msg)
DC_PARAM_MIMETYPE as i32, .param
b"application/autocrypt-setup\x00" as *const u8 .set(Param::MimeType, "application/autocrypt-setup");
as *const libc::c_char, (*msg).param.set_int(Param::Cmd, 6);
); (*msg).param.set_int(Param::ForcePlaintext, 2);
dc_param_set_int((*msg).param, DC_PARAM_CMD as i32, 6);
dc_param_set_int((*msg).param, DC_PARAM_FORCE_PLAINTEXT as i32, 2);
if !context if !context
.running_state .running_state
.clone() .clone()
@@ -539,33 +542,27 @@ pub unsafe fn dc_normalize_setup_code(
#[allow(non_snake_case)] #[allow(non_snake_case)]
pub unsafe fn dc_job_do_DC_JOB_IMEX_IMAP(context: &Context, job: *mut dc_job_t) { pub unsafe fn dc_job_do_DC_JOB_IMEX_IMAP(context: &Context, job: *mut dc_job_t) {
let mut current_block: u64; let mut current_block: u64;
let mut success: libc::c_int = 0i32; let mut success: libc::c_int = 0;
let mut ongoing_allocated_here: libc::c_int = 0i32; let mut ongoing_allocated_here: libc::c_int = 0;
let what: libc::c_int; let what: libc::c_int;
let mut param1: *mut libc::c_char = 0 as *mut libc::c_char; let mut param1 = 0 as *mut libc::c_char;
let mut param2: *mut libc::c_char = 0 as *mut libc::c_char; let mut param2 = 0 as *mut libc::c_char;
if !(0 == dc_alloc_ongoing(context)) { if !(0 == dc_alloc_ongoing(context)) {
ongoing_allocated_here = 1i32; ongoing_allocated_here = 1;
what = dc_param_get_int((*job).param, DC_PARAM_CMD as i32, 0); what = (*job).param.get_int(Param::Cmd).unwrap_or_default();
param1 = dc_param_get( param1 = to_cstring((*job).param.get(Param::Arg).unwrap_or_default());
(*job).param, param2 = to_cstring((*job).param.get(Param::Arg2).unwrap_or_default());
DC_PARAM_CMD_ARG as i32,
0 as *const libc::c_char, if strlen(param1) == 0 {
);
param2 = dc_param_get(
(*job).param,
DC_PARAM_CMD_ARG2 as i32,
0 as *const libc::c_char,
);
if param1.is_null() {
error!(context, 0, "No Import/export dir/file given.",); error!(context, 0, "No Import/export dir/file given.",);
} else { } else {
info!(context, 0, "Import/export process started.",); info!(context, 0, "Import/export process started.",);
context.call_cb(Event::IMEX_PROGRESS, 10i32 as uintptr_t, 0i32 as uintptr_t); context.call_cb(Event::IMEX_PROGRESS, 10 as uintptr_t, 0 as uintptr_t);
if !context.sql.is_open() { if !context.sql.is_open() {
error!(context, 0, "Import/export: Database not opened.",); error!(context, 0, "Import/export: Database not opened.",);
} else { } else {
if what == 1i32 || what == 11i32 { if what == 1 || what == 11 {
/* before we export anything, make sure the private key exists */ /* before we export anything, make sure the private key exists */
if 0 == dc_ensure_secret_key_exists(context) { if 0 == dc_ensure_secret_key_exists(context) {
error!( error!(
@@ -620,7 +617,7 @@ pub unsafe fn dc_job_do_DC_JOB_IMEX_IMAP(context: &Context, job: *mut dc_job_t)
3568988166330621280 => {} 3568988166330621280 => {}
_ => { _ => {
info!(context, 0, "Import/export completed.",); info!(context, 0, "Import/export completed.",);
success = 1i32 success = 1
} }
} }
} }
@@ -660,7 +657,7 @@ pub unsafe fn dc_job_do_DC_JOB_IMEX_IMAP(context: &Context, job: *mut dc_job_t)
3568988166330621280 => {} 3568988166330621280 => {}
_ => { _ => {
info!(context, 0, "Import/export completed.",); info!(context, 0, "Import/export completed.",);
success = 1i32 success = 1
} }
} }
} }
@@ -700,7 +697,7 @@ pub unsafe fn dc_job_do_DC_JOB_IMEX_IMAP(context: &Context, job: *mut dc_job_t)
3568988166330621280 => {} 3568988166330621280 => {}
_ => { _ => {
info!(context, 0, "Import/export completed.",); info!(context, 0, "Import/export completed.",);
success = 1i32 success = 1
} }
} }
} }
@@ -740,7 +737,7 @@ pub unsafe fn dc_job_do_DC_JOB_IMEX_IMAP(context: &Context, job: *mut dc_job_t)
3568988166330621280 => {} 3568988166330621280 => {}
_ => { _ => {
info!(context, 0, "Import/export completed.",); info!(context, 0, "Import/export completed.",);
success = 1i32 success = 1
} }
} }
} }
@@ -758,8 +755,8 @@ pub unsafe fn dc_job_do_DC_JOB_IMEX_IMAP(context: &Context, job: *mut dc_job_t)
} }
context.call_cb( context.call_cb(
Event::IMEX_PROGRESS, Event::IMEX_PROGRESS,
(if 0 != success { 1000i32 } else { 0i32 }) as uintptr_t, (if 0 != success { 1000 } else { 0 }) as uintptr_t,
0i32 as uintptr_t, 0 as uintptr_t,
); );
} }

View File

@@ -15,10 +15,10 @@ use crate::dc_location::*;
use crate::dc_loginparam::*; use crate::dc_loginparam::*;
use crate::dc_mimefactory::*; use crate::dc_mimefactory::*;
use crate::dc_msg::*; use crate::dc_msg::*;
use crate::dc_param::*;
use crate::dc_tools::*; use crate::dc_tools::*;
use crate::imap::*; use crate::imap::*;
use crate::keyhistory::*; use crate::keyhistory::*;
use crate::param::*;
use crate::sql; use crate::sql;
use crate::types::*; use crate::types::*;
use crate::x::*; use crate::x::*;
@@ -33,7 +33,7 @@ use crate::x::*;
// timeouts until actions are aborted. // timeouts until actions are aborted.
// this may also affects IDLE to return, so a re-connect may take this time. // this may also affects IDLE to return, so a re-connect may take this time.
// mailcore2 uses 30 seconds, k-9 uses 10 seconds // mailcore2 uses 30 seconds, k-9 uses 10 seconds
#[derive(Copy, Clone)] #[derive(Clone)]
#[repr(C)] #[repr(C)]
pub struct dc_job_t { pub struct dc_job_t {
pub job_id: uint32_t, pub job_id: uint32_t,
@@ -42,7 +42,7 @@ pub struct dc_job_t {
pub desired_timestamp: i64, pub desired_timestamp: i64,
pub added_timestamp: i64, pub added_timestamp: i64,
pub tries: libc::c_int, pub tries: libc::c_int,
pub param: *mut dc_param_t, pub param: Params,
pub try_again: libc::c_int, pub try_again: libc::c_int,
pub pending_error: *mut libc::c_char, pub pending_error: *mut libc::c_char,
} }
@@ -91,15 +91,11 @@ unsafe fn dc_job_perform(context: &Context, thread: libc::c_int, probe_network:
desired_timestamp: row.get(5)?, desired_timestamp: row.get(5)?,
added_timestamp: row.get(4)?, added_timestamp: row.get(4)?,
tries: row.get(6)?, tries: row.get(6)?,
param: dc_param_new(), param: row.get::<_, String>(3)?.parse().unwrap_or_default(),
try_again: 0, try_again: 0,
pending_error: 0 as *mut libc::c_char, pending_error: 0 as *mut libc::c_char,
}; };
let packed: String = row.get(3)?;
let packed_c = to_cstring(packed);
dc_param_set_packed(job.param, packed_c);
free(packed_c as *mut _);
Ok(job) Ok(job)
}, },
|jobs| { |jobs| {
@@ -225,7 +221,6 @@ unsafe fn dc_job_perform(context: &Context, thread: libc::c_int, probe_network:
} else { } else {
dc_job_delete(context, &mut job); dc_job_delete(context, &mut job);
} }
dc_param_unref(job.param);
free(job.pending_error as *mut libc::c_void); free(job.pending_error as *mut libc::c_void);
} }
} }
@@ -262,7 +257,7 @@ fn dc_job_update(context: &Context, job: &dc_job_t) -> bool {
params![ params![
job.desired_timestamp, job.desired_timestamp,
job.tries as i64, job.tries as i64,
as_str(unsafe { (*job.param).packed }), job.param.to_string(),
job.job_id as i32, job.job_id as i32,
], ],
) )
@@ -287,7 +282,6 @@ unsafe fn dc_job_do_DC_JOB_SEND(context: &Context, job: &mut dc_job_t) {
let mut filename: *mut libc::c_char = 0 as *mut libc::c_char; let mut filename: *mut libc::c_char = 0 as *mut libc::c_char;
let mut buf: *mut libc::c_void = 0 as *mut libc::c_void; let mut buf: *mut libc::c_void = 0 as *mut libc::c_void;
let mut buf_bytes: size_t = 0i32 as size_t; let mut buf_bytes: size_t = 0i32 as size_t;
let mut recipients: *mut libc::c_char = 0 as *mut libc::c_char;
/* connect to SMTP server, if not yet done */ /* connect to SMTP server, if not yet done */
if !context.smtp.lock().unwrap().is_connected() { if !context.smtp.lock().unwrap().is_connected() {
@@ -305,20 +299,15 @@ unsafe fn dc_job_do_DC_JOB_SEND(context: &Context, job: &mut dc_job_t) {
} }
match current_block { match current_block {
13109137661213826276 => { 13109137661213826276 => {
filename = dc_param_get(job.param, DC_PARAM_FILE as i32, 0 as *const libc::c_char); filename = to_cstring(job.param.get(Param::File).unwrap_or_default());
if filename.is_null() { if strlen(filename) == 0 {
warn!(context, 0, "Missing file name for job {}", job.job_id,); warn!(context, 0, "Missing file name for job {}", job.job_id,);
} else if !(0 == dc_read_file(context, filename, &mut buf, &mut buf_bytes)) { } else if !(0 == dc_read_file(context, filename, &mut buf, &mut buf_bytes)) {
recipients = dc_param_get( let recipients = job.param.get(Param::Recipients);
job.param, if recipients.is_none() {
DC_PARAM_RECIPIENTS as i32,
0 as *const libc::c_char,
);
if recipients.is_null() {
warn!(context, 0, "Missing recipients for job {}", job.job_id,); warn!(context, 0, "Missing recipients for job {}", job.job_id,);
} else { } else {
let recipients_list = std::ffi::CStr::from_ptr(recipients) let recipients_list = recipients
.to_str()
.unwrap() .unwrap()
.split("\x1e") .split("\x1e")
.filter_map(|addr| match lettre::EmailAddress::new(addr.to_string()) { .filter_map(|addr| match lettre::EmailAddress::new(addr.to_string()) {
@@ -396,7 +385,6 @@ unsafe fn dc_job_do_DC_JOB_SEND(context: &Context, job: &mut dc_job_t) {
} }
_ => {} _ => {}
} }
free(recipients as *mut libc::c_void);
free(buf); free(buf);
free(filename as *mut libc::c_void); free(filename as *mut libc::c_void);
} }
@@ -512,19 +500,19 @@ fn connect_to_inbox(context: &Context, inbox: &Imap) -> libc::c_int {
#[allow(non_snake_case)] #[allow(non_snake_case)]
unsafe fn dc_job_do_DC_JOB_MARKSEEN_MDN_ON_IMAP(context: &Context, job: &mut dc_job_t) { unsafe fn dc_job_do_DC_JOB_MARKSEEN_MDN_ON_IMAP(context: &Context, job: &mut dc_job_t) {
let current_block: u64; let current_block: u64;
let folder: *mut libc::c_char = dc_param_get( let folder = job
job.param, .param
DC_PARAM_SERVER_FOLDER as i32, .get(Param::ServerFolder)
0 as *const libc::c_char, .unwrap_or_default()
); .to_string();
let uid: uint32_t = dc_param_get_int(job.param, DC_PARAM_SERVER_UID as i32, 0) as uint32_t; let uid = job.param.get_int(Param::ServerUid).unwrap_or_default() as u32;
let mut dest_uid: uint32_t = 0i32 as uint32_t; let mut dest_uid = 0;
let inbox = context.inbox.read().unwrap(); let inbox = context.inbox.read().unwrap();
if !inbox.is_connected() { if !inbox.is_connected() {
connect_to_inbox(context, &inbox); connect_to_inbox(context, &inbox);
if !inbox.is_connected() { if !inbox.is_connected() {
dc_job_try_again_later(job, 3i32, 0 as *const libc::c_char); dc_job_try_again_later(job, 3, 0 as *const libc::c_char);
current_block = 2670689566614003383; current_block = 2670689566614003383;
} else { } else {
current_block = 11006700562992250127; current_block = 11006700562992250127;
@@ -534,11 +522,10 @@ unsafe fn dc_job_do_DC_JOB_MARKSEEN_MDN_ON_IMAP(context: &Context, job: &mut dc_
} }
match current_block { match current_block {
11006700562992250127 => { 11006700562992250127 => {
let folder = CStr::from_ptr(folder).to_str().unwrap(); if inbox.set_seen(context, &folder, uid) == 0 {
if inbox.set_seen(context, folder, uid) as libc::c_uint == 0i32 as libc::c_uint {
dc_job_try_again_later(job, 3i32, 0 as *const libc::c_char); dc_job_try_again_later(job, 3i32, 0 as *const libc::c_char);
} }
if 0 != dc_param_get_int(job.param, DC_PARAM_ALSO_MOVE as i32, 0i32) { if 0 != job.param.get_int(Param::AlsoMove).unwrap_or_default() {
if context if context
.sql .sql
.get_config_int(context, "folders_configured") .get_config_int(context, "folders_configured")
@@ -559,7 +546,6 @@ unsafe fn dc_job_do_DC_JOB_MARKSEEN_MDN_ON_IMAP(context: &Context, job: &mut dc_
} }
_ => {} _ => {}
} }
free(folder as *mut libc::c_void);
} }
#[allow(non_snake_case)] #[allow(non_snake_case)]
@@ -592,12 +578,8 @@ unsafe fn dc_job_do_DC_JOB_MARKSEEN_MSG_ON_IMAP(context: &Context, job: &mut dc_
dc_job_try_again_later(job, 3i32, 0 as *const libc::c_char); dc_job_try_again_later(job, 3i32, 0 as *const libc::c_char);
} }
_ => { _ => {
if 0 != dc_param_get_int( if 0 != (*msg).param.get_int(Param::WantsMdn).unwrap_or_default()
(*msg).param, && 0 != context
DC_PARAM_WANTS_MDN as i32,
0i32,
) && 0
!= context
.sql .sql
.get_config_int(context, "mdns_enabled") .get_config_int(context, "mdns_enabled")
.unwrap_or_else(|| 1) .unwrap_or_else(|| 1)
@@ -650,7 +632,7 @@ unsafe fn dc_job_do_DC_JOB_MARKSEEN_MSG_ON_IMAP(context: &Context, job: &mut dc_
dc_job_try_again_later(job, 3i32, 0 as *const libc::c_char); dc_job_try_again_later(job, 3i32, 0 as *const libc::c_char);
} }
_ => { _ => {
if 0 != dc_param_get_int((*msg).param, DC_PARAM_WANTS_MDN as i32, 0) if 0 != (*msg).param.get_int(Param::WantsMdn).unwrap_or_default()
&& 0 != context && 0 != context
.sql .sql
.get_config_int(context, "mdns_enabled") .get_config_int(context, "mdns_enabled")
@@ -756,7 +738,7 @@ unsafe fn dc_add_smtp_job(
let pathNfilename: *mut libc::c_char; let pathNfilename: *mut libc::c_char;
let mut success: libc::c_int = 0i32; let mut success: libc::c_int = 0i32;
let mut recipients: *mut libc::c_char = 0 as *mut libc::c_char; let mut recipients: *mut libc::c_char = 0 as *mut libc::c_char;
let param: *mut dc_param_t = dc_param_new(); let mut param = Params::new();
pathNfilename = dc_get_fine_pathNfilename( pathNfilename = dc_get_fine_pathNfilename(
context, context,
b"$BLOBDIR\x00" as *const u8 as *const libc::c_char, b"$BLOBDIR\x00" as *const u8 as *const libc::c_char,
@@ -789,8 +771,8 @@ unsafe fn dc_add_smtp_job(
(*mimefactory).recipients_addr, (*mimefactory).recipients_addr,
b"\x1e\x00" as *const u8 as *const libc::c_char, b"\x1e\x00" as *const u8 as *const libc::c_char,
); );
dc_param_set(param, DC_PARAM_FILE as i32, pathNfilename); param.set(Param::File, as_str(pathNfilename));
dc_param_set(param, DC_PARAM_RECIPIENTS as i32, recipients); param.set(Param::File, as_str(recipients));
dc_job_add( dc_job_add(
context, context,
action, action,
@@ -799,23 +781,23 @@ unsafe fn dc_add_smtp_job(
{ {
(*(*mimefactory).msg).id (*(*mimefactory).msg).id
} else { } else {
0i32 as libc::c_uint 0
}) as libc::c_int, }) as libc::c_int,
(*param).packed, param,
0i32, 0,
); );
success = 1i32 success = 1i32
} }
dc_param_unref(param);
free(recipients as *mut libc::c_void); free(recipients as *mut libc::c_void);
free(pathNfilename as *mut libc::c_void); free(pathNfilename as *mut libc::c_void);
return success; return success;
} }
pub unsafe fn dc_job_add( pub unsafe fn dc_job_add(
context: &Context, context: &Context,
action: libc::c_int, action: libc::c_int,
foreign_id: libc::c_int, foreign_id: libc::c_int,
param: *const libc::c_char, param: Params,
delay_seconds: libc::c_int, delay_seconds: libc::c_int,
) { ) {
let timestamp = time(); let timestamp = time();
@@ -836,11 +818,7 @@ pub unsafe fn dc_job_add(
thread, thread,
action, action,
foreign_id, foreign_id,
if !param.is_null() { param.to_string(),
as_str(param)
} else {
""
},
(timestamp + delay_seconds as i64) (timestamp + delay_seconds as i64)
] ]
).ok(); ).ok();
@@ -1184,22 +1162,23 @@ pub unsafe fn dc_job_send_msg(context: &Context, msg_id: uint32_t) -> libc::c_in
} else { } else {
// no redo, no IMAP. moreover, as the data does not exist, there is no need in calling dc_set_msg_failed() // no redo, no IMAP. moreover, as the data does not exist, there is no need in calling dc_set_msg_failed()
if msgtype_has_file((*mimefactory.msg).type_0) { if msgtype_has_file((*mimefactory.msg).type_0) {
let pathNfilename = dc_param_get( let pathNfilename = to_cstring(
(*mimefactory.msg).param, (*mimefactory.msg)
DC_PARAM_FILE as i32, .param
0 as *const libc::c_char, .get(Param::File)
.unwrap_or_default(),
); );
if !pathNfilename.is_null() { if strlen(pathNfilename) > 0 {
if ((*mimefactory.msg).type_0 == DC_MSG_IMAGE if ((*mimefactory.msg).type_0 == DC_MSG_IMAGE
|| (*mimefactory.msg).type_0 == DC_MSG_GIF) || (*mimefactory.msg).type_0 == DC_MSG_GIF)
&& 0 == dc_param_exists((*mimefactory.msg).param, DC_PARAM_WIDTH as i32) && !(*mimefactory.msg).param.exists(Param::Width)
{ {
let mut buf: *mut libc::c_uchar = 0 as *mut libc::c_uchar; let mut buf = 0 as *mut libc::c_uchar;
let mut buf_bytes: size_t = 0; let mut buf_bytes: size_t = 0;
let mut w: uint32_t = 0; let mut w = 0;
let mut h: uint32_t = 0; let mut h = 0;
dc_param_set_int((*mimefactory.msg).param, DC_PARAM_WIDTH as i32, 0); (*mimefactory.msg).param.set_int(Param::Width, 0);
dc_param_set_int((*mimefactory.msg).param, DC_PARAM_HEIGHT as i32, 0); (*mimefactory.msg).param.set_int(Param::Height, 0);
if 0 != dc_read_file( if 0 != dc_read_file(
context, context,
pathNfilename, pathNfilename,
@@ -1212,16 +1191,8 @@ pub unsafe fn dc_job_send_msg(context: &Context, msg_id: uint32_t) -> libc::c_in
&mut w, &mut w,
&mut h, &mut h,
) { ) {
dc_param_set_int( (*mimefactory.msg).param.set_int(Param::Width, w as i32);
(*mimefactory.msg).param, (*mimefactory.msg).param.set_int(Param::Height, h as i32);
DC_PARAM_WIDTH as i32,
w as int32_t,
);
dc_param_set_int(
(*mimefactory.msg).param,
DC_PARAM_HEIGHT as i32,
h as int32_t,
);
} }
} }
free(buf as *mut libc::c_void); free(buf as *mut libc::c_void);
@@ -1233,15 +1204,19 @@ pub unsafe fn dc_job_send_msg(context: &Context, msg_id: uint32_t) -> libc::c_in
/* create message */ /* create message */
if 0 == dc_mimefactory_render(&mut mimefactory) { if 0 == dc_mimefactory_render(&mut mimefactory) {
dc_set_msg_failed(context, msg_id, mimefactory.error); dc_set_msg_failed(context, msg_id, mimefactory.error);
} else if 0 != dc_param_get_int((*mimefactory.msg).param, DC_PARAM_GUARANTEE_E2EE as i32, 0) } else if 0
!= (*mimefactory.msg)
.param
.get_int(Param::GuranteeE2ee)
.unwrap_or_default()
&& 0 == mimefactory.out_encrypted && 0 == mimefactory.out_encrypted
{ {
warn!( warn!(
context, context,
0, 0,
"e2e encryption unavailable {} - {}", "e2e encryption unavailable {} - {:?}",
msg_id, msg_id,
dc_param_get_int((*mimefactory.msg).param, DC_PARAM_GUARANTEE_E2EE as i32, 0), (*mimefactory.msg).param.get_int(Param::GuranteeE2ee),
); );
dc_set_msg_failed( dc_set_msg_failed(
context, context,
@@ -1279,10 +1254,13 @@ pub unsafe fn dc_job_send_msg(context: &Context, msg_id: uint32_t) -> libc::c_in
} }
} }
if 0 != mimefactory.out_encrypted if 0 != mimefactory.out_encrypted
&& dc_param_get_int((*mimefactory.msg).param, DC_PARAM_GUARANTEE_E2EE as i32, 0) && (*mimefactory.msg)
.param
.get_int(Param::GuranteeE2ee)
.unwrap_or_default()
== 0 == 0
{ {
dc_param_set_int((*mimefactory.msg).param, DC_PARAM_GUARANTEE_E2EE as i32, 1); (*mimefactory.msg).param.set_int(Param::GuranteeE2ee, 1);
dc_msg_save_param_to_disk(mimefactory.msg); dc_msg_save_param_to_disk(mimefactory.msg);
} }
dc_add_to_keyhistory( dc_add_to_keyhistory(

View File

@@ -6,9 +6,9 @@ use crate::dc_array::*;
use crate::dc_chat::*; use crate::dc_chat::*;
use crate::dc_job::*; use crate::dc_job::*;
use crate::dc_msg::*; use crate::dc_msg::*;
use crate::dc_param::*;
use crate::dc_saxparser::*; use crate::dc_saxparser::*;
use crate::dc_tools::*; use crate::dc_tools::*;
use crate::param::*;
use crate::sql; use crate::sql;
use crate::stock::StockMessage; use crate::stock::StockMessage;
use crate::types::*; use crate::types::*;
@@ -105,7 +105,7 @@ pub unsafe fn dc_send_locations_to_chat(
"", "",
0, 0,
)); ));
dc_param_set_int((*msg).param, DC_PARAM_CMD as i32, 8); (*msg).param.set_int(Param::Cmd, 8);
dc_send_msg(context, chat_id, msg); dc_send_msg(context, chat_id, msg);
} else if 0 == seconds && is_sending_locations_before { } else if 0 == seconds && is_sending_locations_before {
let stock_str = CString::new(context.stock_system_msg( let stock_str = CString::new(context.stock_system_msg(
@@ -128,7 +128,7 @@ pub unsafe fn dc_send_locations_to_chat(
context, context,
5007i32, 5007i32,
chat_id as libc::c_int, chat_id as libc::c_int,
0 as *const libc::c_char, Params::new(),
seconds + 1i32, seconds + 1i32,
); );
} }
@@ -143,7 +143,7 @@ pub unsafe fn dc_send_locations_to_chat(
#[allow(non_snake_case)] #[allow(non_snake_case)]
unsafe fn schedule_MAYBE_SEND_LOCATIONS(context: &Context, flags: libc::c_int) { unsafe fn schedule_MAYBE_SEND_LOCATIONS(context: &Context, flags: libc::c_int) {
if 0 != flags & 0x1 || !dc_job_action_exists(context, 5005) { if 0 != flags & 0x1 || !dc_job_action_exists(context, 5005) {
dc_job_add(context, 5005, 0, 0 as *const libc::c_char, 60); dc_job_add(context, 5005, 0, Params::new(), 60);
}; };
} }
@@ -709,7 +709,7 @@ pub unsafe fn dc_job_do_DC_JOB_MAYBE_SEND_LOCATIONS(context: &Context, _job: *mu
// and dc_set_location() is typically called periodically, this is ok) // and dc_set_location() is typically called periodically, this is ok)
let mut msg = dc_msg_new(context, 10); let mut msg = dc_msg_new(context, 10);
(*msg).hidden = 1; (*msg).hidden = 1;
dc_param_set_int((*msg).param, DC_PARAM_CMD as i32, 9); (*msg).param.set_int(Param::Cmd, 9);
dc_send_msg(context, chat_id as u32, msg); dc_send_msg(context, chat_id as u32, msg);
dc_msg_unref(msg); dc_msg_unref(msg);
} }

View File

@@ -125,7 +125,7 @@ pub unsafe fn dc_lot_get_timestamp(lot: *const dc_lot_t) -> i64 {
/* in practice, the user additionally cuts the string himself pixel-accurate */ /* in practice, the user additionally cuts the string himself pixel-accurate */
pub unsafe fn dc_lot_fill( pub unsafe fn dc_lot_fill(
mut lot: *mut dc_lot_t, mut lot: *mut dc_lot_t,
msg: *const dc_msg_t, msg: *mut dc_msg_t,
chat: *const Chat, chat: *const Chat,
contact: *const dc_contact_t, contact: *const dc_contact_t,
context: &Context, context: &Context,
@@ -161,7 +161,7 @@ pub unsafe fn dc_lot_fill(
} }
} }
(*lot).text2 = (*lot).text2 =
dc_msg_get_summarytext_by_raw((*msg).type_0, (*msg).text, (*msg).param, 160i32, context); dc_msg_get_summarytext_by_raw((*msg).type_0, (*msg).text, &mut (*msg).param, 160, context);
(*lot).timestamp = dc_msg_get_timestamp(msg); (*lot).timestamp = dc_msg_get_timestamp(msg);
(*lot).state = (*msg).state; (*lot).state = (*msg).state;
} }

View File

@@ -17,9 +17,9 @@ use crate::dc_contact::*;
use crate::dc_e2ee::*; use crate::dc_e2ee::*;
use crate::dc_location::*; use crate::dc_location::*;
use crate::dc_msg::*; use crate::dc_msg::*;
use crate::dc_param::*;
use crate::dc_strencode::*; use crate::dc_strencode::*;
use crate::dc_tools::*; use crate::dc_tools::*;
use crate::param::*;
use crate::stock::StockMessage; use crate::stock::StockMessage;
use crate::types::*; use crate::types::*;
use crate::x::*; use crate::x::*;
@@ -114,7 +114,6 @@ pub unsafe fn dc_mimefactory_load_msg(
msg_id: uint32_t, msg_id: uint32_t,
) -> libc::c_int { ) -> libc::c_int {
if factory.is_null() || msg_id <= 9 || !(*factory).msg.is_null() { if factory.is_null() || msg_id <= 9 || !(*factory).msg.is_null() {
info!((*factory).context, 0, "mimefactory: null");
return 0; return 0;
} }
@@ -129,12 +128,9 @@ pub unsafe fn dc_mimefactory_load_msg(
if dc_msg_load_from_db((*factory).msg, context, msg_id) if dc_msg_load_from_db((*factory).msg, context, msg_id)
&& dc_chat_load_from_db((*factory).chat, (*(*factory).msg).chat_id) && dc_chat_load_from_db((*factory).chat, (*(*factory).msg).chat_id)
{ {
info!(context, 0, "mimefactory: loaded msg and chat",);
load_from(factory); load_from(factory);
(*factory).req_mdn = 0; (*factory).req_mdn = 0;
if 0 != dc_chat_is_self_talk((*factory).chat) { if 0 != dc_chat_is_self_talk((*factory).chat) {
info!(context, 0, "mimefactory: selftalk");
clist_insert_after( clist_insert_after(
(*factory).recipients_names, (*factory).recipients_names,
(*(*factory).recipients_names).last, (*(*factory).recipients_names).last,
@@ -146,7 +142,6 @@ pub unsafe fn dc_mimefactory_load_msg(
dc_strdup((*factory).from_addr) as *mut libc::c_void, dc_strdup((*factory).from_addr) as *mut libc::c_void,
); );
} else { } else {
info!(context, 0, "mimefactory: query map");
context context
.sql .sql
.query_map( .query_map(
@@ -161,7 +156,6 @@ pub unsafe fn dc_mimefactory_load_msg(
Ok((authname, addr)) Ok((authname, addr))
}, },
|rows| { |rows| {
info!(context, 0, "mimefactory: processing rows");
for row in rows { for row in rows {
let (authname, addr) = row?; let (authname, addr) = row?;
let addr_c = to_cstring(addr); let addr_c = to_cstring(addr);
@@ -187,14 +181,15 @@ pub unsafe fn dc_mimefactory_load_msg(
) )
.unwrap(); .unwrap();
let command = dc_param_get_int((*(*factory).msg).param, DC_PARAM_CMD as i32, 0); let command = (*(*factory).msg)
.param
.get_int(Param::Cmd)
.unwrap_or_default();
if command == 5 { if command == 5 {
let email_to_remove_c = dc_param_get( let email_to_remove = (*(*factory).msg).param.get(Param::Arg).unwrap_or_default();
(*(*factory).msg).param, let email_to_remove_c = to_cstring(email_to_remove);
DC_PARAM_CMD_ARG as i32,
0 as *const libc::c_char,
);
let email_to_remove = to_string(email_to_remove_c);
let self_addr = context let self_addr = context
.sql .sql
.get_config(context, "configured_addr") .get_config(context, "configured_addr")
@@ -227,8 +222,6 @@ pub unsafe fn dc_mimefactory_load_msg(
(*factory).req_mdn = 1 (*factory).req_mdn = 1
} }
} }
info!(context, 0, "mimefactory: loading in reply to");
let row = context.sql.query_row( let row = context.sql.query_row(
"SELECT mime_in_reply_to, mime_references FROM msgs WHERE id=?", "SELECT mime_in_reply_to, mime_references FROM msgs WHERE id=?",
params![(*(*factory).msg).id as i32], params![(*(*factory).msg).id as i32],
@@ -374,7 +367,7 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc:
// 1=add Autocrypt-header (needed eg. for handshaking), 2=no Autocrypte-header (used for MDN) // 1=add Autocrypt-header (needed eg. for handshaking), 2=no Autocrypte-header (used for MDN)
let mut force_plaintext: libc::c_int = 0; let mut force_plaintext: libc::c_int = 0;
let mut do_gossip: libc::c_int = 0; let mut do_gossip: libc::c_int = 0;
let mut grpimage: *mut libc::c_char = 0 as *mut libc::c_char; let mut grpimage = None;
let mut e2ee_helper = dc_e2ee_helper_t { let mut e2ee_helper = dc_e2ee_helper_t {
encryption_successfull: 0, encryption_successfull: 0,
cdata_to_free: 0 as *mut libc::c_void, cdata_to_free: 0 as *mut libc::c_void,
@@ -543,11 +536,15 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc:
e2ee_guaranteed = 1; e2ee_guaranteed = 1;
min_verified = 2 min_verified = 2
} else { } else {
force_plaintext = force_plaintext = (*(*factory).msg)
dc_param_get_int((*(*factory).msg).param, DC_PARAM_FORCE_PLAINTEXT as i32, 0); .param
.get_int(Param::ForcePlaintext)
.unwrap_or_default();
if force_plaintext == 0 { if force_plaintext == 0 {
e2ee_guaranteed = e2ee_guaranteed = (*(*factory).msg)
dc_param_get_int((*(*factory).msg).param, DC_PARAM_GUARANTEE_E2EE as i32, 0) .param
.get_int(Param::GuranteeE2ee)
.unwrap_or_default()
} }
} }
if (*chat).gossiped_timestamp == 0 if (*chat).gossiped_timestamp == 0
@@ -555,8 +552,9 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc:
{ {
do_gossip = 1 do_gossip = 1
} }
/* build header etc. */ /* build header etc. */
let command: libc::c_int = dc_param_get_int((*msg).param, DC_PARAM_CMD as i32, 0); let command = (*msg).param.get_int(Param::Cmd).unwrap_or_default();
if (*chat).type_0 == DC_CHAT_TYPE_GROUP as libc::c_int if (*chat).type_0 == DC_CHAT_TYPE_GROUP as libc::c_int
|| (*chat).type_0 == DC_CHAT_TYPE_VERIFIED_GROUP as libc::c_int || (*chat).type_0 == DC_CHAT_TYPE_VERIFIED_GROUP as libc::c_int
{ {
@@ -575,12 +573,9 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc:
), ),
); );
if command == 5 { if command == 5 {
let email_to_remove: *mut libc::c_char = dc_param_get( let email_to_remove =
(*msg).param, to_cstring((*msg).param.get(Param::Arg).unwrap_or_default());
DC_PARAM_CMD_ARG as i32, if strlen(email_to_remove) > 0 {
0 as *const libc::c_char,
);
if !email_to_remove.is_null() {
mailimf_fields_add( mailimf_fields_add(
imf_fields, imf_fields,
mailimf_field_new_custom( mailimf_field_new_custom(
@@ -594,12 +589,8 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc:
} }
} else if command == 4 { } else if command == 4 {
do_gossip = 1; do_gossip = 1;
let email_to_add: *mut libc::c_char = dc_param_get( let email_to_add = to_cstring((*msg).param.get(Param::Arg).unwrap_or_default());
(*msg).param, if strlen(email_to_add) > 0 {
DC_PARAM_CMD_ARG as i32,
0 as *const libc::c_char,
);
if !email_to_add.is_null() {
mailimf_fields_add( mailimf_fields_add(
imf_fields, imf_fields,
mailimf_field_new_custom( mailimf_field_new_custom(
@@ -610,13 +601,9 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc:
email_to_add, email_to_add,
), ),
); );
grpimage = dc_param_get( grpimage = (*chat).param.get(Param::ProfileImage);
(*chat).param,
DC_PARAM_PROFILE_IMAGE as i32,
0 as *const libc::c_char,
)
} }
if 0 != dc_param_get_int((*msg).param, DC_PARAM_CMD_ARG2 as i32, 0) & 0x1 { if 0 != (*msg).param.get_int(Param::Arg2).unwrap_or_default() & 0x1 {
info!( info!(
(*msg).context, (*msg).context,
0, 0,
@@ -632,26 +619,19 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc:
); );
} }
} else if command == 2 { } else if command == 2 {
let value_to_add = to_cstring((*msg).param.get(Param::Arg).unwrap_or_default());
mailimf_fields_add( mailimf_fields_add(
imf_fields, imf_fields,
mailimf_field_new_custom( mailimf_field_new_custom(
strdup( strdup(
b"Chat-Group-Name-Changed\x00" as *const u8 as *const libc::c_char, b"Chat-Group-Name-Changed\x00" as *const u8 as *const libc::c_char,
), ),
dc_param_get( value_to_add,
(*msg).param,
DC_PARAM_CMD_ARG as i32,
b"\x00" as *const u8 as *const libc::c_char,
),
), ),
); );
} else if command == 3 { } else if command == 3 {
grpimage = dc_param_get( grpimage = (*msg).param.get(Param::Arg);
(*msg).param, if grpimage.is_none() {
DC_PARAM_CMD_ARG as i32,
0 as *const libc::c_char,
);
if grpimage.is_null() {
mailimf_fields_add( mailimf_fields_add(
imf_fields, imf_fields,
mailimf_field_new_custom( mailimf_field_new_custom(
@@ -685,12 +665,8 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc:
to_cstring((*factory).context.stock_str(StockMessage::AcSetupMsgBody)); to_cstring((*factory).context.stock_str(StockMessage::AcSetupMsgBody));
} }
if command == 7 { if command == 7 {
let step: *mut libc::c_char = dc_param_get( let step = to_cstring((*msg).param.get(Param::Arg).unwrap_or_default());
(*msg).param, if strlen(step) > 0 {
DC_PARAM_CMD_ARG as i32,
0 as *const libc::c_char,
);
if !step.is_null() {
info!( info!(
(*msg).context, (*msg).context,
0, 0,
@@ -704,12 +680,8 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc:
step, step,
), ),
); );
let param2: *mut libc::c_char = dc_param_get( let param2 = to_cstring((*msg).param.get(Param::Arg2).unwrap_or_default());
(*msg).param, if strlen(param2) > 0 {
DC_PARAM_CMD_ARG2 as i32,
0 as *const libc::c_char,
);
if !param2.is_null() {
mailimf_fields_add( mailimf_fields_add(
imf_fields, imf_fields,
mailimf_field_new_custom( mailimf_field_new_custom(
@@ -736,12 +708,8 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc:
), ),
); );
} }
let fingerprint: *mut libc::c_char = dc_param_get( let fingerprint = to_cstring((*msg).param.get(Param::Arg3).unwrap_or_default());
(*msg).param, if strlen(fingerprint) > 0 {
DC_PARAM_CMD_ARG3 as i32,
0 as *const libc::c_char,
);
if !fingerprint.is_null() {
mailimf_fields_add( mailimf_fields_add(
imf_fields, imf_fields,
mailimf_field_new_custom( mailimf_field_new_custom(
@@ -753,11 +721,10 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc:
), ),
); );
} }
let grpid: *mut libc::c_char = dc_param_get( let grpid = match (*msg).param.get(Param::Arg4) {
(*msg).param, Some(id) => to_cstring(id),
DC_PARAM_CMD_ARG4 as i32, None => std::ptr::null_mut(),
0 as *const libc::c_char, };
);
if !grpid.is_null() { if !grpid.is_null() {
mailimf_fields_add( mailimf_fields_add(
imf_fields, imf_fields,
@@ -771,11 +738,13 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc:
} }
} }
} }
if !grpimage.is_null() {
let mut meta: *mut dc_msg_t = dc_msg_new_untyped((*factory).context); if let Some(grpimage) = grpimage {
let mut meta = dc_msg_new_untyped((*factory).context);
(*meta).type_0 = DC_MSG_IMAGE as libc::c_int; (*meta).type_0 = DC_MSG_IMAGE as libc::c_int;
dc_param_set((*meta).param, DC_PARAM_FILE as i32, grpimage); (*meta).param.set(Param::File, grpimage);
let mut filename_as_sent: *mut libc::c_char = 0 as *mut libc::c_char;
let mut filename_as_sent = 0 as *mut libc::c_char;
meta_part = build_body_file( meta_part = build_body_file(
meta, meta,
b"group-image\x00" as *const u8 as *const libc::c_char, b"group-image\x00" as *const u8 as *const libc::c_char,
@@ -792,6 +761,7 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc:
} }
dc_msg_unref(meta); dc_msg_unref(meta);
} }
if (*msg).type_0 == DC_MSG_VOICE if (*msg).type_0 == DC_MSG_VOICE
|| (*msg).type_0 == DC_MSG_AUDIO || (*msg).type_0 == DC_MSG_AUDIO
|| (*msg).type_0 == DC_MSG_VIDEO || (*msg).type_0 == DC_MSG_VIDEO
@@ -805,8 +775,7 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc:
), ),
); );
} }
let duration_ms: libc::c_int = let duration_ms = (*msg).param.get_int(Param::Duration).unwrap_or_default();
dc_param_get_int((*msg).param, DC_PARAM_DURATION as i32, 0);
if duration_ms > 0 { if duration_ms > 0 {
mailimf_fields_add( mailimf_fields_add(
imf_fields, imf_fields,
@@ -820,14 +789,15 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc:
); );
} }
} }
afwd_email = dc_param_exists((*msg).param, DC_PARAM_FORWARDED as i32); afwd_email = (*msg).param.exists(Param::Forwarded) as libc::c_int;
let mut fwdhint: *mut libc::c_char = 0 as *mut libc::c_char; let mut fwdhint = 0 as *mut libc::c_char;
if 0 != afwd_email { if 0 != afwd_email {
fwdhint = dc_strdup( fwdhint = dc_strdup(
b"---------- Forwarded message ----------\r\nFrom: Delta Chat\r\n\r\n\x00" b"---------- Forwarded message ----------\r\nFrom: Delta Chat\r\n\r\n\x00"
as *const u8 as *const libc::c_char, as *const u8 as *const libc::c_char,
) )
} }
let mut final_text: *const libc::c_char = 0 as *const libc::c_char; let mut final_text: *const libc::c_char = 0 as *const libc::c_char;
if !placeholdertext.is_null() { if !placeholdertext.is_null() {
final_text = placeholdertext final_text = placeholdertext
@@ -871,6 +841,7 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc:
parts += 1; parts += 1;
free(fwdhint as *mut libc::c_void); free(fwdhint as *mut libc::c_void);
free(placeholdertext as *mut libc::c_void); free(placeholdertext as *mut libc::c_void);
/* add attachment part */ /* add attachment part */
if msgtype_has_file((*msg).type_0) { if msgtype_has_file((*msg).type_0) {
if 0 == is_file_size_okay(msg) { if 0 == is_file_size_okay(msg) {
@@ -907,18 +878,15 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc:
if !meta_part.is_null() { if !meta_part.is_null() {
mailmime_smart_add_part(message, meta_part); mailmime_smart_add_part(message, meta_part);
} }
if 0 != dc_param_exists((*msg).param, DC_PARAM_SET_LATITUDE as libc::c_int) if (*msg).param.exists(Param::SetLatitude) {
{ let latitude = (*msg)
let latitude = dc_param_get_float( .param
(*msg).param, .get_float(Param::SetLatitude)
DC_PARAM_SET_LATITUDE as libc::c_int, .unwrap_or_default();
0.0, let longitude = (*msg)
); .param
let longitude = dc_param_get_float( .get_float(Param::SetLongitude)
(*msg).param, .unwrap_or_default();
DC_PARAM_SET_LONGITUDE as libc::c_int,
0.0,
);
let kml_file = let kml_file =
dc_get_message_kml((*msg).timestamp_sort, latitude, longitude); dc_get_message_kml((*msg).timestamp_sort, latitude, longitude);
if !kml_file.is_null() { if !kml_file.is_null() {
@@ -965,10 +933,7 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc:
mailmime_new_empty(content_type, mime_fields); mailmime_new_empty(content_type, mime_fields);
mailmime_set_body_text(kml_mime_part, kml_file, strlen(kml_file)); mailmime_set_body_text(kml_mime_part, kml_file, strlen(kml_file));
mailmime_smart_add_part(message, kml_mime_part); mailmime_smart_add_part(message, kml_mime_part);
if 0 == dc_param_exists( if !(*msg).param.exists(Param::SetLatitude) {
(*msg).param,
DC_PARAM_SET_LATITUDE as libc::c_int,
) {
// otherwise, the independent location is already filed // otherwise, the independent location is already filed
(*factory).out_last_added_location_id = last_added_location_id; (*factory).out_last_added_location_id = last_added_location_id;
} }
@@ -996,7 +961,11 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc:
mailmime_add_part(message, multipart); mailmime_add_part(message, multipart);
let p1: *mut libc::c_char; let p1: *mut libc::c_char;
let p2: *mut libc::c_char; let p2: *mut libc::c_char;
if 0 != dc_param_get_int((*(*factory).msg).param, DC_PARAM_GUARANTEE_E2EE as i32, 0) { if 0 != (*(*factory).msg)
.param
.get_int(Param::GuranteeE2ee)
.unwrap_or_default()
{
p1 = to_cstring((*factory).context.stock_str(StockMessage::EncryptedMsg)); p1 = to_cstring((*factory).context.stock_str(StockMessage::EncryptedMsg));
} else { } else {
p1 = dc_msg_get_summarytext((*factory).msg, 32) p1 = dc_msg_get_summarytext((*factory).msg, 32)
@@ -1034,6 +1003,7 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc:
); );
current_block = 11328123142868406523; current_block = 11328123142868406523;
} }
match current_block { match current_block {
11328123142868406523 => {} 11328123142868406523 => {}
_ => { _ => {
@@ -1114,26 +1084,25 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc:
free(message_text as *mut libc::c_void); free(message_text as *mut libc::c_void);
free(message_text2 as *mut libc::c_void); free(message_text2 as *mut libc::c_void);
free(subject_str as *mut libc::c_void); free(subject_str as *mut libc::c_void);
free(grpimage as *mut libc::c_void);
success success
} }
unsafe fn get_subject( unsafe fn get_subject(
chat: *const Chat, chat: *const Chat,
msg: *const dc_msg_t, msg: *mut dc_msg_t,
afwd_email: libc::c_int, afwd_email: libc::c_int,
) -> *mut libc::c_char { ) -> *mut libc::c_char {
let context = (*chat).context; let context = (*chat).context;
let ret: *mut libc::c_char; let ret: *mut libc::c_char;
let raw_subject: *mut libc::c_char = let raw_subject =
dc_msg_get_summarytext_by_raw((*msg).type_0, (*msg).text, (*msg).param, 32, context); dc_msg_get_summarytext_by_raw((*msg).type_0, (*msg).text, &mut (*msg).param, 32, context);
let fwd: *const libc::c_char = if 0 != afwd_email { let fwd = if 0 != afwd_email {
b"Fwd: \x00" as *const u8 as *const libc::c_char b"Fwd: \x00" as *const u8 as *const libc::c_char
} else { } else {
b"\x00" as *const u8 as *const libc::c_char b"\x00" as *const u8 as *const libc::c_char
}; };
if dc_param_get_int((*msg).param, DC_PARAM_CMD as i32, 0) == 6 { if (*msg).param.get_int(Param::Cmd).unwrap_or_default() == 6 {
ret = to_cstring(context.stock_str(StockMessage::AcSetupMsgSubject)) ret = to_cstring(context.stock_str(StockMessage::AcSetupMsgSubject))
} else if (*chat).type_0 == DC_CHAT_TYPE_GROUP as libc::c_int } else if (*chat).type_0 == DC_CHAT_TYPE_GROUP as libc::c_int
|| (*chat).type_0 == DC_CHAT_TYPE_VERIFIED_GROUP as libc::c_int || (*chat).type_0 == DC_CHAT_TYPE_VERIFIED_GROUP as libc::c_int
@@ -1194,16 +1163,21 @@ unsafe fn build_body_file(
let mime_fields: *mut mailmime_fields; let mime_fields: *mut mailmime_fields;
let mut mime_sub: *mut mailmime = 0 as *mut mailmime; let mut mime_sub: *mut mailmime = 0 as *mut mailmime;
let content: *mut mailmime_content; let content: *mut mailmime_content;
let pathNfilename: *mut libc::c_char = let pathNfilename = (*msg)
dc_param_get((*msg).param, DC_PARAM_FILE as i32, 0 as *const libc::c_char); .param
let mut mimetype: *mut libc::c_char = dc_param_get( .get(Param::File)
(*msg).param, .map(|s| to_cstring(s))
DC_PARAM_MIMETYPE as i32, .unwrap_or_else(|| std::ptr::null_mut());
0 as *const libc::c_char, let mut mimetype = (*msg)
); .param
let suffix: *mut libc::c_char = dc_get_filesuffix_lc(pathNfilename); .get(Param::MimeType)
let mut filename_to_send: *mut libc::c_char = 0 as *mut libc::c_char; .map(|s| to_cstring(s))
let mut filename_encoded: *mut libc::c_char = 0 as *mut libc::c_char; .unwrap_or_else(|| std::ptr::null_mut());
let suffix = dc_get_filesuffix_lc(pathNfilename);
let mut filename_to_send = 0 as *mut libc::c_char;
let mut filename_encoded = 0 as *mut libc::c_char;
if !pathNfilename.is_null() { if !pathNfilename.is_null() {
if (*msg).type_0 == DC_MSG_VOICE { if (*msg).type_0 == DC_MSG_VOICE {
let ts = chrono::Utc.timestamp((*msg).timestamp_sort as i64, 0); let ts = chrono::Utc.timestamp((*msg).timestamp_sort as i64, 0);
@@ -1355,14 +1329,14 @@ unsafe fn build_body_file(
******************************************************************************/ ******************************************************************************/
#[allow(non_snake_case)] #[allow(non_snake_case)]
unsafe fn is_file_size_okay(msg: *const dc_msg_t) -> libc::c_int { unsafe fn is_file_size_okay(msg: *const dc_msg_t) -> libc::c_int {
let mut file_size_okay: libc::c_int = 1; let mut file_size_okay = 1;
let pathNfilename: *mut libc::c_char = let pathNfilename = to_cstring((*msg).param.get(Param::File).unwrap_or_default());
dc_param_get((*msg).param, DC_PARAM_FILE as i32, 0 as *const libc::c_char); let bytes = dc_get_filebytes((*msg).context, pathNfilename);
let bytes: uint64_t = dc_get_filebytes((*msg).context, pathNfilename);
if bytes > (49 * 1024 * 1024 / 4 * 3) as libc::c_ulonglong { if bytes > (49 * 1024 * 1024 / 4 * 3) {
file_size_okay = 0; file_size_okay = 0;
} }
free(pathNfilename as *mut libc::c_void); free(pathNfilename as *mut _);
file_size_okay file_size_okay
} }

View File

@@ -15,10 +15,10 @@ use crate::context::Context;
use crate::dc_contact::*; use crate::dc_contact::*;
use crate::dc_e2ee::*; use crate::dc_e2ee::*;
use crate::dc_location::*; use crate::dc_location::*;
use crate::dc_param::*;
use crate::dc_simplify::*; use crate::dc_simplify::*;
use crate::dc_strencode::*; use crate::dc_strencode::*;
use crate::dc_tools::*; use crate::dc_tools::*;
use crate::param::*;
use crate::stock::StockMessage; use crate::stock::StockMessage;
use crate::types::*; use crate::types::*;
use crate::x::*; use crate::x::*;
@@ -26,7 +26,7 @@ use crate::x::*;
/* Parse MIME body; this is the text part of an IMF, see https://tools.ietf.org/html/rfc5322 /* Parse MIME body; this is the text part of an IMF, see https://tools.ietf.org/html/rfc5322
dc_mimeparser_t has no deep dependencies to Context or to the database dc_mimeparser_t has no deep dependencies to Context or to the database
(Context is used for logging only). */ (Context is used for logging only). */
#[derive(Copy, Clone)] #[derive(Clone)]
#[repr(C)] #[repr(C)]
pub struct dc_mimepart_t { pub struct dc_mimepart_t {
pub type_0: libc::c_int, pub type_0: libc::c_int,
@@ -35,7 +35,7 @@ pub struct dc_mimepart_t {
pub msg: *mut libc::c_char, pub msg: *mut libc::c_char,
pub msg_raw: *mut libc::c_char, pub msg_raw: *mut libc::c_char,
pub bytes: libc::c_int, pub bytes: libc::c_int,
pub param: *mut dc_param_t, pub param: Params,
} }
/* * /* *
@@ -105,10 +105,9 @@ pub unsafe fn dc_mimeparser_empty(mimeparser: &mut dc_mimeparser_t) {
let cnt: libc::c_int = carray_count((*mimeparser).parts) as libc::c_int; let cnt: libc::c_int = carray_count((*mimeparser).parts) as libc::c_int;
i = 0i32; i = 0i32;
while i < cnt { while i < cnt {
let part: *mut dc_mimepart_t = let part = carray_get((*mimeparser).parts, i as libc::c_uint) as *mut dc_mimepart_t;
carray_get((*mimeparser).parts, i as libc::c_uint) as *mut dc_mimepart_t;
if !part.is_null() { if !part.is_null() {
dc_mimepart_unref(part); dc_mimepart_unref(*Box::from_raw(part));
} }
i += 1 i += 1
} }
@@ -146,16 +145,11 @@ pub unsafe fn dc_mimeparser_empty(mimeparser: &mut dc_mimeparser_t) {
(*mimeparser).message_kml = None; (*mimeparser).message_kml = None;
} }
unsafe fn dc_mimepart_unref(mut mimepart: *mut dc_mimepart_t) { unsafe fn dc_mimepart_unref(mut mimepart: dc_mimepart_t) {
if mimepart.is_null() { free(mimepart.msg as *mut libc::c_void);
return; mimepart.msg = 0 as *mut libc::c_char;
} free(mimepart.msg_raw as *mut libc::c_void);
free((*mimepart).msg as *mut libc::c_void); mimepart.msg_raw = 0 as *mut libc::c_char;
(*mimepart).msg = 0 as *mut libc::c_char;
free((*mimepart).msg_raw as *mut libc::c_void);
(*mimepart).msg_raw = 0 as *mut libc::c_char;
dc_param_unref((*mimepart).param);
free(mimepart as *mut libc::c_void);
} }
pub unsafe fn dc_mimeparser_parse( pub unsafe fn dc_mimeparser_parse(
@@ -209,10 +203,10 @@ pub unsafe fn dc_mimeparser_parse(
(*mimeparser).is_system_message = 6i32; (*mimeparser).is_system_message = 6i32;
i = 0i32; i = 0i32;
while (i as libc::c_uint) < carray_count((*mimeparser).parts) { while (i as libc::c_uint) < carray_count((*mimeparser).parts) {
let part_0: *mut dc_mimepart_t = let part_0 =
carray_get((*mimeparser).parts, i as libc::c_uint) as *mut dc_mimepart_t; carray_get((*mimeparser).parts, i as libc::c_uint) as *mut dc_mimepart_t;
if (*part_0).int_mimetype != 111i32 { if (*part_0).int_mimetype != 111i32 {
dc_mimepart_unref(part_0); dc_mimepart_unref(*Box::from_raw(part_0));
carray_delete_slow((*mimeparser).parts, i as libc::c_uint); carray_delete_slow((*mimeparser).parts, i as libc::c_uint);
i -= 1 i -= 1
} }
@@ -253,10 +247,8 @@ pub unsafe fn dc_mimeparser_parse(
&& 0 != S_GENERATE_COMPOUND_MSGS && 0 != S_GENERATE_COMPOUND_MSGS
&& carray_count((*mimeparser).parts) == 2i32 as libc::c_uint && carray_count((*mimeparser).parts) == 2i32 as libc::c_uint
{ {
let mut textpart_0: *mut dc_mimepart_t = let mut textpart_0 = carray_get((*mimeparser).parts, 0) as *mut dc_mimepart_t;
carray_get((*mimeparser).parts, 0i32 as libc::c_uint) as *mut dc_mimepart_t; let mut filepart = carray_get((*mimeparser).parts, 1) as *mut dc_mimepart_t;
let mut filepart: *mut dc_mimepart_t =
carray_get((*mimeparser).parts, 1i32 as libc::c_uint) as *mut dc_mimepart_t;
if (*textpart_0).type_0 == 10i32 if (*textpart_0).type_0 == 10i32
&& ((*filepart).type_0 == 20i32 && ((*filepart).type_0 == 20i32
|| (*filepart).type_0 == 21i32 || (*filepart).type_0 == 21i32
@@ -269,7 +261,7 @@ pub unsafe fn dc_mimeparser_parse(
free((*filepart).msg as *mut libc::c_void); free((*filepart).msg as *mut libc::c_void);
(*filepart).msg = (*textpart_0).msg; (*filepart).msg = (*textpart_0).msg;
(*textpart_0).msg = 0 as *mut libc::c_char; (*textpart_0).msg = 0 as *mut libc::c_char;
dc_mimepart_unref(textpart_0); dc_mimepart_unref(*Box::from_raw(textpart_0));
carray_delete_slow((*mimeparser).parts, 0i32 as libc::c_uint); carray_delete_slow((*mimeparser).parts, 0i32 as libc::c_uint);
} }
} }
@@ -326,9 +318,9 @@ pub unsafe fn dc_mimeparser_parse(
let icnt_0: libc::c_int = carray_count((*mimeparser).parts) as libc::c_int; let icnt_0: libc::c_int = carray_count((*mimeparser).parts) as libc::c_int;
i_1 = 0i32; i_1 = 0i32;
while i_1 < icnt_0 { while i_1 < icnt_0 {
let part_2: *mut dc_mimepart_t = let part_2 =
carray_get((*mimeparser).parts, i_1 as libc::c_uint) as *mut dc_mimepart_t; carray_get((*mimeparser).parts, i_1 as libc::c_uint) as *mut dc_mimepart_t;
dc_param_set_int((*part_2).param, DC_PARAM_FORWARDED as i32, 1); (*part_2).param.set_int(Param::Forwarded, 1);
i_1 += 1 i_1 += 1
} }
} }
@@ -346,14 +338,14 @@ pub unsafe fn dc_mimeparser_parse(
} }
} }
if (*part_3).type_0 == 40i32 || (*part_3).type_0 == 41i32 || (*part_3).type_0 == 50i32 { if (*part_3).type_0 == 40i32 || (*part_3).type_0 == 41i32 || (*part_3).type_0 == 50i32 {
let field_0: *const mailimf_optional_field = dc_mimeparser_lookup_optional_field( let field_0 = dc_mimeparser_lookup_optional_field(
mimeparser, mimeparser,
b"Chat-Duration\x00" as *const u8 as *const libc::c_char, b"Chat-Duration\x00" as *const u8 as *const libc::c_char,
); );
if !field_0.is_null() { if !field_0.is_null() {
let duration_ms: libc::c_int = dc_atoi_null_is_0((*field_0).fld_value); let duration_ms: libc::c_int = dc_atoi_null_is_0((*field_0).fld_value);
if duration_ms > 0i32 && duration_ms < 24i32 * 60i32 * 60i32 * 1000i32 { if duration_ms > 0i32 && duration_ms < 24i32 * 60i32 * 60i32 * 1000i32 {
dc_param_set_int((*part_3).param, DC_PARAM_DURATION as i32, duration_ms); (*part_3).param.set_int(Param::Duration, duration_ms);
} }
} }
} }
@@ -390,11 +382,7 @@ pub unsafe fn dc_mimeparser_parse(
let part_4: *mut dc_mimepart_t = let part_4: *mut dc_mimepart_t =
dc_mimeparser_get_last_nonmeta(mimeparser); dc_mimeparser_get_last_nonmeta(mimeparser);
if !part_4.is_null() { if !part_4.is_null() {
dc_param_set_int( (*part_4).param.set_int(Param::WantsMdn, 1);
(*part_4).param,
DC_PARAM_WANTS_MDN as i32,
1,
);
} }
} }
free(from_addr as *mut libc::c_void); free(from_addr as *mut libc::c_void);
@@ -411,16 +399,16 @@ pub unsafe fn dc_mimeparser_parse(
if dc_mimeparser_get_last_nonmeta(mimeparser).is_null() if dc_mimeparser_get_last_nonmeta(mimeparser).is_null()
&& carray_count((*mimeparser).reports) == 0i32 as libc::c_uint && carray_count((*mimeparser).reports) == 0i32 as libc::c_uint
{ {
let mut part_5: *mut dc_mimepart_t = dc_mimepart_new(); let mut part_5 = dc_mimepart_new();
(*part_5).type_0 = 10i32; part_5.type_0 = 10i32;
if !(*mimeparser).subject.is_null() && 0 == (*mimeparser).is_send_by_messenger { if !(*mimeparser).subject.is_null() && 0 == (*mimeparser).is_send_by_messenger {
(*part_5).msg = dc_strdup((*mimeparser).subject) part_5.msg = dc_strdup((*mimeparser).subject)
} else { } else {
(*part_5).msg = dc_strdup(b"\x00" as *const u8 as *const libc::c_char) part_5.msg = dc_strdup(b"\x00" as *const u8 as *const libc::c_char)
} }
carray_add( carray_add(
(*mimeparser).parts, (*mimeparser).parts,
part_5 as *mut libc::c_void, Box::into_raw(Box::new(part_5)) as *mut libc::c_void,
0 as *mut libc::c_uint, 0 as *mut libc::c_uint,
); );
}; };
@@ -429,13 +417,16 @@ pub unsafe fn dc_mimeparser_parse(
/******************************************************************************* /*******************************************************************************
* a MIME part * a MIME part
******************************************************************************/ ******************************************************************************/
unsafe fn dc_mimepart_new() -> *mut dc_mimepart_t { unsafe fn dc_mimepart_new() -> dc_mimepart_t {
let mut mimepart: *mut dc_mimepart_t; dc_mimepart_t {
mimepart = calloc(1, ::std::mem::size_of::<dc_mimepart_t>()) as *mut dc_mimepart_t; type_0: 0,
assert!(!mimepart.is_null()); is_meta: 0,
(*mimepart).type_0 = 0i32; int_mimetype: 0,
(*mimepart).param = dc_param_new(); msg: std::ptr::null_mut(),
mimepart msg_raw: std::ptr::null_mut(),
bytes: 0,
param: Params::new(),
}
} }
pub unsafe fn dc_mimeparser_get_last_nonmeta(mimeparser: &dc_mimeparser_t) -> *mut dc_mimepart_t { pub unsafe fn dc_mimeparser_get_last_nonmeta(mimeparser: &dc_mimeparser_t) -> *mut dc_mimepart_t {
@@ -666,8 +657,8 @@ unsafe fn dc_mimeparser_parse_mime_recursive(
} }
} }
40 => { 40 => {
let mut part: *mut dc_mimepart_t = dc_mimepart_new(); let mut part = dc_mimepart_new();
(*part).type_0 = 10i32; part.type_0 = 10i32;
let msg_body = CString::new( let msg_body = CString::new(
(*mimeparser) (*mimeparser)
.context .context
@@ -675,14 +666,14 @@ unsafe fn dc_mimeparser_parse_mime_recursive(
.as_ref(), .as_ref(),
) )
.unwrap(); .unwrap();
(*part).msg = dc_mprintf( part.msg = dc_mprintf(
b"[%s]\x00" as *const u8 as *const libc::c_char, b"[%s]\x00" as *const u8 as *const libc::c_char,
msg_body.as_ptr(), msg_body.as_ptr(),
); );
(*part).msg_raw = dc_strdup((*part).msg); part.msg_raw = dc_strdup(part.msg);
carray_add( carray_add(
(*mimeparser).parts, (*mimeparser).parts,
part as *mut libc::c_void, Box::into_raw(Box::new(part)) as *mut libc::c_void,
0 as *mut libc::c_uint, 0 as *mut libc::c_uint,
); );
any_part_added = 1i32; any_part_added = 1i32;
@@ -1145,7 +1136,6 @@ unsafe fn dc_mimeparser_add_single_part_if_known(
mime: *mut mailmime, mime: *mut mailmime,
) -> libc::c_int { ) -> libc::c_int {
let mut current_block: u64; let mut current_block: u64;
let mut part: *mut dc_mimepart_t = 0 as *mut dc_mimepart_t;
let old_part_count: libc::c_int = carray_count(mimeparser.parts) as libc::c_int; let old_part_count: libc::c_int = carray_count(mimeparser.parts) as libc::c_int;
let mime_type: libc::c_int; let mime_type: libc::c_int;
let mime_data: *mut mailmime_data; let mime_data: *mut mailmime_data;
@@ -1241,14 +1231,13 @@ unsafe fn dc_mimeparser_add_single_part_if_known(
if !simplified_txt.is_null() if !simplified_txt.is_null()
&& 0 != *simplified_txt.offset(0isize) as libc::c_int && 0 != *simplified_txt.offset(0isize) as libc::c_int
{ {
part = dc_mimepart_new(); let mut part = dc_mimepart_new();
(*part).type_0 = 10i32; part.type_0 = 10i32;
(*part).int_mimetype = mime_type; part.int_mimetype = mime_type;
(*part).msg = simplified_txt; part.msg = simplified_txt;
(*part).msg_raw = part.msg_raw =
strndup(decoded_data, decoded_data_bytes as libc::c_ulong); strndup(decoded_data, decoded_data_bytes as libc::c_ulong);
do_add_single_part(mimeparser, part); do_add_single_part(mimeparser, part);
part = 0 as *mut dc_mimepart_t
} else { } else {
free(simplified_txt as *mut libc::c_void); free(simplified_txt as *mut libc::c_void);
} }
@@ -1440,7 +1429,6 @@ unsafe fn dc_mimeparser_add_single_part_if_known(
} }
free(file_suffix as *mut libc::c_void); free(file_suffix as *mut libc::c_void);
free(desired_filename as *mut libc::c_void); free(desired_filename as *mut libc::c_void);
dc_mimepart_unref(part);
free(raw_mime as *mut libc::c_void); free(raw_mime as *mut libc::c_void);
return if carray_count((*mimeparser).parts) > old_part_count as libc::c_uint { return if carray_count((*mimeparser).parts) > old_part_count as libc::c_uint {
1i32 1i32
@@ -1459,7 +1447,6 @@ unsafe fn do_add_single_file_part(
decoded_data_bytes: size_t, decoded_data_bytes: size_t,
desired_filename: *const libc::c_char, desired_filename: *const libc::c_char,
) { ) {
let mut part: *mut dc_mimepart_t = 0 as *mut dc_mimepart_t;
let pathNfilename: *mut libc::c_char; let pathNfilename: *mut libc::c_char;
/* create a free file name to use */ /* create a free file name to use */
pathNfilename = dc_get_fine_pathNfilename( pathNfilename = dc_get_fine_pathNfilename(
@@ -1476,42 +1463,40 @@ unsafe fn do_add_single_file_part(
decoded_data_bytes, decoded_data_bytes,
) == 0i32) ) == 0i32)
{ {
part = dc_mimepart_new(); let mut part = dc_mimepart_new();
(*part).type_0 = msg_type; part.type_0 = msg_type;
(*part).int_mimetype = mime_type; part.int_mimetype = mime_type;
(*part).bytes = decoded_data_bytes as libc::c_int; part.bytes = decoded_data_bytes as libc::c_int;
dc_param_set((*part).param, DC_PARAM_FILE as i32, pathNfilename); part.param.set(Param::File, as_str(pathNfilename));
dc_param_set((*part).param, DC_PARAM_MIMETYPE as i32, raw_mime); part.param.set(Param::MimeType, as_str(raw_mime));
if mime_type == 80i32 { if mime_type == 80 {
let mut w: uint32_t = 0i32 as uint32_t; let mut w = 0;
let mut h: uint32_t = 0i32 as uint32_t; let mut h = 0;
if 0 != dc_get_filemeta( if 0 != dc_get_filemeta(
decoded_data as *const libc::c_void, decoded_data as *const libc::c_void,
decoded_data_bytes, decoded_data_bytes,
&mut w, &mut w,
&mut h, &mut h,
) { ) {
dc_param_set_int((*part).param, DC_PARAM_WIDTH as i32, w as int32_t); part.param.set_int(Param::Width, w as i32);
dc_param_set_int((*part).param, DC_PARAM_HEIGHT as i32, h as int32_t); part.param.set_int(Param::Height, h as i32);
} }
} }
do_add_single_part(parser, part); do_add_single_part(parser, part);
part = 0 as *mut dc_mimepart_t
} }
} }
free(pathNfilename as *mut libc::c_void); free(pathNfilename as *mut libc::c_void);
dc_mimepart_unref(part);
} }
unsafe fn do_add_single_part(parser: &dc_mimeparser_t, part: *mut dc_mimepart_t) { unsafe fn do_add_single_part(parser: &dc_mimeparser_t, mut part: dc_mimepart_t) {
if 0 != (*parser).e2ee_helper.encrypted && (*parser).e2ee_helper.signatures.len() > 0 { if 0 != (*parser).e2ee_helper.encrypted && (*parser).e2ee_helper.signatures.len() > 0 {
dc_param_set_int((*part).param, DC_PARAM_GUARANTEE_E2EE as i32, 1); part.param.set_int(Param::GuranteeE2ee, 1);
} else if 0 != (*parser).e2ee_helper.encrypted { } else if 0 != (*parser).e2ee_helper.encrypted {
dc_param_set_int((*part).param, DC_PARAM_ERRONEOUS_E2EE as i32, 0x2); part.param.set_int(Param::ErroneousE2ee, 0x2);
} }
carray_add( carray_add(
(*parser).parts, (*parser).parts,
part as *mut libc::c_void, Box::into_raw(Box::new(part)) as *mut libc::c_void,
0 as *mut libc::c_uint, 0 as *mut libc::c_uint,
); );
} }
@@ -1816,7 +1801,7 @@ pub unsafe fn dc_mimeparser_repl_msg_by_error(
while (i as libc::c_uint) < carray_count((*mimeparser).parts) { while (i as libc::c_uint) < carray_count((*mimeparser).parts) {
part = carray_get((*mimeparser).parts, i as libc::c_uint) as *mut dc_mimepart_t; part = carray_get((*mimeparser).parts, i as libc::c_uint) as *mut dc_mimepart_t;
if !part.is_null() { if !part.is_null() {
dc_mimepart_unref(part); dc_mimepart_unref(*Box::from_raw(part));
} }
i += 1 i += 1
} }

View File

@@ -2,6 +2,7 @@ use crate::constants::*;
use crate::context::*; use crate::context::*;
use crate::dc_job::*; use crate::dc_job::*;
use crate::dc_msg::*; use crate::dc_msg::*;
use crate::param::Params;
pub unsafe fn dc_do_heuristics_moves(context: &Context, folder: &str, msg_id: u32) { pub unsafe fn dc_do_heuristics_moves(context: &Context, folder: &str, msg_id: u32) {
if context if context
@@ -31,13 +32,7 @@ pub unsafe fn dc_do_heuristics_moves(context: &Context, folder: &str, msg_id: u3
// 1 = dc message, 2 = reply to dc message // 1 = dc message, 2 = reply to dc message
if 0 != (*msg).is_dc_message { if 0 != (*msg).is_dc_message {
dc_job_add( dc_job_add(context, 200, (*msg).id as libc::c_int, Params::new(), 0);
context,
200,
(*msg).id as libc::c_int,
0 as *const libc::c_char,
0,
);
dc_update_msg_move_state(context, (*msg).rfc724_mid, DC_MOVE_STATE_MOVING); dc_update_msg_move_state(context, (*msg).rfc724_mid, DC_MOVE_STATE_MOVING);
} }

View File

@@ -7,8 +7,8 @@ use crate::dc_contact::*;
use crate::dc_job::*; use crate::dc_job::*;
use crate::dc_lot::dc_lot_t; use crate::dc_lot::dc_lot_t;
use crate::dc_lot::*; use crate::dc_lot::*;
use crate::dc_param::*;
use crate::dc_tools::*; use crate::dc_tools::*;
use crate::param::*;
use crate::pgp::*; use crate::pgp::*;
use crate::sql; use crate::sql;
use crate::stock::StockMessage; use crate::stock::StockMessage;
@@ -16,7 +16,7 @@ use crate::types::*;
use crate::x::*; use crate::x::*;
/* * the structure behind dc_msg_t */ /* * the structure behind dc_msg_t */
#[derive(Copy, Clone)] #[derive(Clone)]
#[repr(C)] #[repr(C)]
pub struct dc_msg_t<'a> { pub struct dc_msg_t<'a> {
pub magic: uint32_t, pub magic: uint32_t,
@@ -41,7 +41,7 @@ pub struct dc_msg_t<'a> {
pub starred: libc::c_int, pub starred: libc::c_int,
pub chat_blocked: libc::c_int, pub chat_blocked: libc::c_int,
pub location_id: uint32_t, pub location_id: uint32_t,
pub param: *mut dc_param_t, pub param: Params,
} }
// handle messages // handle messages
@@ -144,26 +144,30 @@ pub unsafe fn dc_get_msg_info(context: &Context, msg_id: u32) -> *mut libc::c_ch
ret += ", Location sent"; ret += ", Location sent";
} }
let e2ee_errors = dc_param_get_int((*msg).param, DC_PARAM_ERRONEOUS_E2EE as i32, 0); let e2ee_errors = (*msg)
.param
.get_int(Param::ErroneousE2ee)
.unwrap_or_default();
if 0 != e2ee_errors { if 0 != e2ee_errors {
if 0 != e2ee_errors & 0x2 { if 0 != e2ee_errors & 0x2 {
ret += ", Encrypted, no valid signature"; ret += ", Encrypted, no valid signature";
} }
} else if 0 != dc_param_get_int((*msg).param, DC_PARAM_GUARANTEE_E2EE as i32, 0) { } else if 0
!= (*msg)
.param
.get_int(Param::GuranteeE2ee)
.unwrap_or_default()
{
ret += ", Encrypted"; ret += ", Encrypted";
} }
ret += "\n"; ret += "\n";
p = dc_param_get( match (*msg).param.get(Param::Error) {
(*msg).param, Some(err) => ret += &format!("Error: {}", err),
DC_PARAM_ERROR as i32, _ => {}
0 as *const libc::c_char,
);
if !p.is_null() {
ret += &format!("Error: {}", as_str(p));
free(p as *mut libc::c_void);
} }
p = dc_msg_get_file(msg); p = dc_msg_get_file(msg);
if !p.is_null() && 0 != *p.offset(0isize) as libc::c_int { if !p.is_null() && 0 != *p.offset(0isize) as libc::c_int {
ret += &format!( ret += &format!(
@@ -190,12 +194,12 @@ pub unsafe fn dc_get_msg_info(context: &Context, msg_id: u32) -> *mut libc::c_ch
ret += &format!("Mimetype: {}\n", as_str(p)); ret += &format!("Mimetype: {}\n", as_str(p));
free(p as *mut libc::c_void); free(p as *mut libc::c_void);
} }
let w = dc_param_get_int((*msg).param, DC_PARAM_WIDTH as i32, 0); let w = (*msg).param.get_int(Param::Width).unwrap_or_default();
let h = dc_param_get_int((*msg).param, DC_PARAM_HEIGHT as i32, 0); let h = (*msg).param.get_int(Param::Height).unwrap_or_default();
if w != 0 || h != 0 { if w != 0 || h != 0 {
ret += &format!("Dimension: {} x {}\n", w, h,); ret += &format!("Dimension: {} x {}\n", w, h,);
} }
let duration = dc_param_get_int((*msg).param, DC_PARAM_DURATION as i32, 0); let duration = (*msg).param.get_int(Param::Duration).unwrap_or_default();
if duration != 0 { if duration != 0 {
ret += &format!("Duration: {} ms\n", duration,); ret += &format!("Duration: {} ms\n", duration,);
} }
@@ -233,16 +237,33 @@ pub unsafe fn dc_msg_new_untyped<'a>(context: &'a Context) -> *mut dc_msg_t<'a>
// approx. max. length returned by dc_msg_get_text() // approx. max. length returned by dc_msg_get_text()
// approx. max. length returned by dc_get_msg_info() // approx. max. length returned by dc_get_msg_info()
pub unsafe fn dc_msg_new<'a>(context: &'a Context, viewtype: libc::c_int) -> *mut dc_msg_t<'a> { pub unsafe fn dc_msg_new<'a>(context: &'a Context, viewtype: libc::c_int) -> *mut dc_msg_t<'a> {
let mut msg: *mut dc_msg_t; let msg = dc_msg_t {
msg = calloc(1, ::std::mem::size_of::<dc_msg_t>()) as *mut dc_msg_t; magic: 0x11561156,
assert!(!msg.is_null()); id: 0,
(*msg).context = context; from_id: 0,
(*msg).magic = 0x11561156i32 as uint32_t; to_id: 0,
(*msg).type_0 = viewtype; chat_id: 0,
(*msg).state = 0; move_state: 0,
(*msg).param = dc_param_new(); type_0: viewtype,
state: 0,
hidden: 0,
timestamp_sort: 0,
timestamp_sent: 0,
timestamp_rcvd: 0,
text: std::ptr::null_mut(),
context,
rfc724_mid: std::ptr::null_mut(),
in_reply_to: std::ptr::null_mut(),
server_folder: std::ptr::null_mut(),
server_uid: 0,
is_dc_message: 0,
starred: 0,
chat_blocked: 0,
location_id: 0,
param: Params::new(),
};
msg Box::into_raw(Box::new(msg))
} }
pub unsafe fn dc_msg_unref(mut msg: *mut dc_msg_t) { pub unsafe fn dc_msg_unref(mut msg: *mut dc_msg_t) {
@@ -250,9 +271,8 @@ pub unsafe fn dc_msg_unref(mut msg: *mut dc_msg_t) {
return; return;
} }
dc_msg_empty(msg); dc_msg_empty(msg);
dc_param_unref((*msg).param);
(*msg).magic = 0i32 as uint32_t; (*msg).magic = 0i32 as uint32_t;
free(msg as *mut libc::c_void); Box::from_raw(msg);
} }
pub unsafe fn dc_msg_empty(mut msg: *mut dc_msg_t) { pub unsafe fn dc_msg_empty(mut msg: *mut dc_msg_t) {
@@ -267,37 +287,38 @@ pub unsafe fn dc_msg_empty(mut msg: *mut dc_msg_t) {
(*msg).in_reply_to = 0 as *mut libc::c_char; (*msg).in_reply_to = 0 as *mut libc::c_char;
free((*msg).server_folder as *mut libc::c_void); free((*msg).server_folder as *mut libc::c_void);
(*msg).server_folder = 0 as *mut libc::c_char; (*msg).server_folder = 0 as *mut libc::c_char;
dc_param_set_packed((*msg).param, 0 as *const libc::c_char); (*msg).param = Params::new();
(*msg).hidden = 0i32; (*msg).hidden = 0i32;
} }
pub unsafe fn dc_msg_get_filemime(msg: *const dc_msg_t) -> *mut libc::c_char { pub unsafe fn dc_msg_get_filemime(msg: *const dc_msg_t) -> *mut libc::c_char {
let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; let mut ret = 0 as *mut libc::c_char;
let mut file: *mut libc::c_char = 0 as *mut libc::c_char;
if !(msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint) { if !(msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint) {
ret = dc_param_get( match (*msg).param.get(Param::MimeType) {
(*msg).param, Some(m) => {
DC_PARAM_MIMETYPE as i32, ret = to_cstring(m);
0 as *const libc::c_char, }
); None => {
if ret.is_null() { if let Some(file) = (*msg).param.get(Param::File) {
file = dc_param_get((*msg).param, DC_PARAM_FILE as i32, 0 as *const libc::c_char); let file_c = to_cstring(file);
if !file.is_null() { dc_msg_guess_msgtype_from_suffix(file_c, 0 as *mut libc::c_int, &mut ret);
dc_msg_guess_msgtype_from_suffix(file, 0 as *mut libc::c_int, &mut ret); if ret.is_null() {
if ret.is_null() { ret = dc_strdup(
ret = dc_strdup( b"application/octet-stream\x00" as *const u8 as *const libc::c_char,
b"application/octet-stream\x00" as *const u8 as *const libc::c_char, )
) }
free(file_c as *mut _);
} }
} }
} }
} }
free(file as *mut libc::c_void);
return if !ret.is_null() { if !ret.is_null() {
ret return ret;
} else { }
dc_strdup(0 as *const libc::c_char)
}; dc_strdup(0 as *const libc::c_char)
} }
#[allow(non_snake_case)] #[allow(non_snake_case)]
@@ -356,20 +377,20 @@ pub unsafe fn dc_msg_guess_msgtype_from_suffix(
} }
pub unsafe fn dc_msg_get_file(msg: *const dc_msg_t) -> *mut libc::c_char { pub unsafe fn dc_msg_get_file(msg: *const dc_msg_t) -> *mut libc::c_char {
let mut file_rel: *mut libc::c_char = 0 as *mut libc::c_char; let mut file_abs = 0 as *mut libc::c_char;
let mut file_abs: *mut libc::c_char = 0 as *mut libc::c_char;
if !(msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint) { if !(msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint) {
file_rel = dc_param_get((*msg).param, DC_PARAM_FILE as i32, 0 as *const libc::c_char); if let Some(file_rel) = (*msg).param.get(Param::File) {
if !file_rel.is_null() { let file_rel_c = to_cstring(file_rel);
file_abs = dc_get_abs_path((*msg).context, file_rel) file_abs = dc_get_abs_path((*msg).context, file_rel_c);
free(file_rel_c as *mut _);
} }
} }
free(file_rel as *mut libc::c_void); if !file_abs.is_null() {
return if !file_abs.is_null() {
file_abs file_abs
} else { } else {
dc_strdup(0 as *const libc::c_char) dc_strdup(0 as *const libc::c_char)
}; }
} }
/** /**
@@ -407,7 +428,7 @@ pub unsafe fn dc_msg_has_location(msg: *const dc_msg_t) -> bool {
* @return None. * @return None.
*/ */
pub unsafe fn dc_msg_set_location( pub unsafe fn dc_msg_set_location(
msg: *const dc_msg_t, msg: *mut dc_msg_t,
latitude: libc::c_double, latitude: libc::c_double,
longitude: libc::c_double, longitude: libc::c_double,
) { ) {
@@ -418,12 +439,8 @@ pub unsafe fn dc_msg_set_location(
return; return;
} }
dc_param_set_float((*msg).param, DC_PARAM_SET_LATITUDE as libc::c_int, latitude); (*msg).param.set_float(Param::SetLatitude, latitude);
dc_param_set_float( (*msg).param.set_float(Param::SetLongitude, longitude);
(*msg).param,
DC_PARAM_SET_LONGITUDE as libc::c_int,
longitude,
);
} }
pub unsafe fn dc_msg_get_timestamp(msg: *const dc_msg_t) -> i64 { pub unsafe fn dc_msg_get_timestamp(msg: *const dc_msg_t) -> i64 {
@@ -474,10 +491,7 @@ pub fn dc_msg_load_from_db<'a>(msg: *mut dc_msg_t<'a>, context: &'a Context, id:
(*msg).state = row.get(13)?; (*msg).state = row.get(13)?;
(*msg).is_dc_message = row.get(14)?; (*msg).is_dc_message = row.get(14)?;
(*msg).text = to_cstring(row.get::<_, String>(15).unwrap_or_default()); (*msg).text = to_cstring(row.get::<_, String>(15).unwrap_or_default());
dc_param_set_packed( (*msg).param = row.get::<_, String>(16)?.parse().unwrap_or_default();
(*msg).param,
to_cstring(row.get::<_, String>(16)?)
);
(*msg).starred = row.get(17)?; (*msg).starred = row.get(17)?;
(*msg).hidden = row.get(18)?; (*msg).hidden = row.get(18)?;
(*msg).location_id = row.get(19)?; (*msg).location_id = row.get(19)?;
@@ -520,18 +534,18 @@ pub unsafe fn dc_delete_msgs(context: &Context, msg_ids: *const uint32_t, msg_cn
dc_update_msg_chat_id(context, *msg_ids.offset(i as isize), 3i32 as uint32_t); dc_update_msg_chat_id(context, *msg_ids.offset(i as isize), 3i32 as uint32_t);
dc_job_add( dc_job_add(
context, context,
110i32, 110,
*msg_ids.offset(i as isize) as libc::c_int, *msg_ids.offset(i as isize) as libc::c_int,
0 as *const libc::c_char, Params::new(),
0i32, 0,
); );
i += 1 i += 1
} }
if 0 != msg_cnt { if 0 != msg_cnt {
context.call_cb(Event::MSGS_CHANGED, 0i32 as uintptr_t, 0i32 as uintptr_t); context.call_cb(Event::MSGS_CHANGED, 0 as uintptr_t, 0 as uintptr_t);
dc_job_kill_action(context, 105i32); dc_job_kill_action(context, 105);
dc_job_add(context, 105i32, 0i32, 0 as *const libc::c_char, 10i32); dc_job_add(context, 105, 0, Params::new(), 10);
}; };
} }
@@ -581,7 +595,7 @@ pub fn dc_markseen_msgs(context: &Context, msg_ids: *const u32, msg_cnt: usize)
dc_update_msg_state(context, id, DC_STATE_IN_SEEN); dc_update_msg_state(context, id, DC_STATE_IN_SEEN);
info!(context, 0, "Seen message #{}.", id); info!(context, 0, "Seen message #{}.", id);
unsafe { dc_job_add(context, 130, id as i32, 0 as *const libc::c_char, 0) }; unsafe { dc_job_add(context, 130, id as i32, Params::new(), 0) };
send_event = true; send_event = true;
} }
} else if curr_state == DC_STATE_IN_FRESH { } else if curr_state == DC_STATE_IN_FRESH {
@@ -711,81 +725,86 @@ pub unsafe fn dc_msg_get_text(msg: *const dc_msg_t) -> *mut libc::c_char {
#[allow(non_snake_case)] #[allow(non_snake_case)]
pub unsafe fn dc_msg_get_filename(msg: *const dc_msg_t) -> *mut libc::c_char { pub unsafe fn dc_msg_get_filename(msg: *const dc_msg_t) -> *mut libc::c_char {
let mut ret: *mut libc::c_char = 0 as *mut libc::c_char; let mut ret = 0 as *mut libc::c_char;
let mut pathNfilename: *mut libc::c_char = 0 as *mut libc::c_char;
if !(msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint) { if !(msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint) {
pathNfilename = dc_param_get((*msg).param, DC_PARAM_FILE as i32, 0 as *const libc::c_char); if let Some(file) = (*msg).param.get(Param::File) {
if !pathNfilename.is_null() { let file_c = to_cstring(file);
ret = dc_get_filename(pathNfilename) ret = dc_get_filename(file_c);
free(file_c as *mut _);
} }
} }
free(pathNfilename as *mut libc::c_void); if !ret.is_null() {
return if !ret.is_null() {
ret ret
} else { } else {
dc_strdup(0 as *const libc::c_char) dc_strdup(0 as *const libc::c_char)
}; }
} }
pub unsafe fn dc_msg_get_filebytes(msg: *const dc_msg_t) -> uint64_t { pub unsafe fn dc_msg_get_filebytes(msg: *const dc_msg_t) -> uint64_t {
let mut ret: uint64_t = 0i32 as uint64_t; let mut ret = 0;
let mut file: *mut libc::c_char = 0 as *mut libc::c_char;
if !(msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint) { if !(msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint) {
file = dc_param_get((*msg).param, DC_PARAM_FILE as i32, 0 as *const libc::c_char); if let Some(file) = (*msg).param.get(Param::File) {
if !file.is_null() { let file_c = to_cstring(file);
ret = dc_get_filebytes((*msg).context, file) ret = dc_get_filebytes((*msg).context, file_c);
free(file_c as *mut _);
} }
} }
free(file as *mut libc::c_void);
ret ret
} }
pub unsafe fn dc_msg_get_width(msg: *const dc_msg_t) -> libc::c_int { pub unsafe fn dc_msg_get_width(msg: *const dc_msg_t) -> libc::c_int {
if msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint {
return 0i32;
}
dc_param_get_int((*msg).param, DC_PARAM_WIDTH as i32, 0)
}
pub unsafe fn dc_msg_get_height(msg: *const dc_msg_t) -> libc::c_int {
if msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint {
return 0i32;
}
dc_param_get_int((*msg).param, DC_PARAM_HEIGHT as i32, 0)
}
pub unsafe fn dc_msg_get_duration(msg: *const dc_msg_t) -> libc::c_int {
if msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint { if msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint {
return 0; return 0;
} }
dc_param_get_int((*msg).param, DC_PARAM_DURATION as i32, 0) (*msg).param.get_int(Param::Width).unwrap_or_default()
}
pub unsafe fn dc_msg_get_height(msg: *const dc_msg_t) -> libc::c_int {
if msg.is_null() || (*msg).magic != 0x11561156 as libc::c_uint {
return 0;
}
(*msg).param.get_int(Param::Height).unwrap_or_default()
}
pub unsafe fn dc_msg_get_duration(msg: *const dc_msg_t) -> libc::c_int {
if msg.is_null() || (*msg).magic != 0x11561156 as libc::c_uint {
return 0;
}
(*msg).param.get_int(Param::Duration).unwrap_or_default()
} }
// TODO should return bool /rtn // TODO should return bool /rtn
pub unsafe fn dc_msg_get_showpadlock(msg: *const dc_msg_t) -> libc::c_int { pub unsafe fn dc_msg_get_showpadlock(msg: *const dc_msg_t) -> libc::c_int {
if msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint { if msg.is_null() || (*msg).magic != 0x11561156 as libc::c_uint {
return 0i32; return 0;
} }
if dc_param_get_int((*msg).param, DC_PARAM_GUARANTEE_E2EE as i32, 0) != 0i32 { if (*msg)
return 1i32; .param
.get_int(Param::GuranteeE2ee)
.unwrap_or_default()
!= 0
{
return 1;
} }
0 0
} }
pub unsafe fn dc_msg_get_summary<'a>( pub unsafe fn dc_msg_get_summary<'a>(
msg: *const dc_msg_t<'a>, msg: *mut dc_msg_t<'a>,
mut chat: *const Chat<'a>, mut chat: *const Chat<'a>,
) -> *mut dc_lot_t { ) -> *mut dc_lot_t {
let current_block: u64; let current_block: u64;
let ret: *mut dc_lot_t = dc_lot_new(); let ret: *mut dc_lot_t = dc_lot_new();
let mut contact: *mut dc_contact_t = 0 as *mut dc_contact_t; let mut contact: *mut dc_contact_t = 0 as *mut dc_contact_t;
let mut chat_to_delete: *mut Chat = 0 as *mut Chat; let mut chat_to_delete: *mut Chat = 0 as *mut Chat;
if !(msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint) { if !(msg.is_null() || (*msg).magic != 0x11561156 as libc::c_uint) {
if chat.is_null() { if chat.is_null() {
chat_to_delete = dc_get_chat((*msg).context, (*msg).chat_id); chat_to_delete = dc_get_chat((*msg).context, (*msg).chat_id);
if chat_to_delete.is_null() { if chat_to_delete.is_null() {
@@ -800,8 +819,8 @@ pub unsafe fn dc_msg_get_summary<'a>(
match current_block { match current_block {
15204159476013091401 => {} 15204159476013091401 => {}
_ => { _ => {
if (*msg).from_id != 1i32 as libc::c_uint if (*msg).from_id != 1 as libc::c_uint
&& ((*chat).type_0 == 120i32 || (*chat).type_0 == 130i32) && ((*chat).type_0 == 120 || (*chat).type_0 == 130)
{ {
contact = dc_get_contact((*chat).context, (*msg).from_id) contact = dc_get_contact((*chat).context, (*msg).from_id)
} }
@@ -816,7 +835,7 @@ pub unsafe fn dc_msg_get_summary<'a>(
} }
pub unsafe fn dc_msg_get_summarytext( pub unsafe fn dc_msg_get_summarytext(
msg: *const dc_msg_t, msg: *mut dc_msg_t,
approx_characters: libc::c_int, approx_characters: libc::c_int,
) -> *mut libc::c_char { ) -> *mut libc::c_char {
if msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint { if msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint {
@@ -826,7 +845,7 @@ pub unsafe fn dc_msg_get_summarytext(
dc_msg_get_summarytext_by_raw( dc_msg_get_summarytext_by_raw(
(*msg).type_0, (*msg).type_0,
(*msg).text, (*msg).text,
(*msg).param, &mut (*msg).param,
approx_characters, approx_characters,
(*msg).context, (*msg).context,
) )
@@ -837,7 +856,7 @@ pub unsafe fn dc_msg_get_summarytext(
pub unsafe fn dc_msg_get_summarytext_by_raw( pub unsafe fn dc_msg_get_summarytext_by_raw(
type_0: libc::c_int, type_0: libc::c_int,
text: *const libc::c_char, text: *const libc::c_char,
param: *mut dc_param_t, param: &mut Params,
approx_characters: libc::c_int, approx_characters: libc::c_int,
context: &Context, context: &Context,
) -> *mut libc::c_char { ) -> *mut libc::c_char {
@@ -853,15 +872,11 @@ pub unsafe fn dc_msg_get_summarytext_by_raw(
50 => prefix = to_cstring(context.stock_str(StockMessage::Video)), 50 => prefix = to_cstring(context.stock_str(StockMessage::Video)),
41 => prefix = to_cstring(context.stock_str(StockMessage::VoiceMessage)), 41 => prefix = to_cstring(context.stock_str(StockMessage::VoiceMessage)),
40 | 60 => { 40 | 60 => {
if dc_param_get_int(param, DC_PARAM_CMD as i32, 0) == 6 { if param.get_int(Param::Cmd) == Some(6) {
prefix = to_cstring(context.stock_str(StockMessage::AcSetupMsgSubject)); prefix = to_cstring(context.stock_str(StockMessage::AcSetupMsgSubject));
append_text = 0i32 append_text = 0i32
} else { } else {
pathNfilename = dc_param_get( pathNfilename = to_cstring(param.get(Param::File).unwrap_or_else(|| "ErrFilename"));
param,
DC_PARAM_FILE as i32,
b"ErrFilename\x00" as *const u8 as *const libc::c_char,
);
value = dc_get_filename(pathNfilename); value = dc_get_filename(pathNfilename);
let label = CString::new( let label = CString::new(
context context
@@ -881,9 +896,9 @@ pub unsafe fn dc_msg_get_summarytext_by_raw(
} }
} }
_ => { _ => {
if dc_param_get_int(param, DC_PARAM_CMD as i32, 0) == 9i32 { if param.get_int(Param::Cmd) == Some(9) {
prefix = to_cstring(context.stock_str(StockMessage::Location)); prefix = to_cstring(context.stock_str(StockMessage::Location));
append_text = 0i32 append_text = 0;
} }
} }
} }
@@ -946,26 +961,26 @@ pub unsafe fn dc_msg_is_starred(msg: *const dc_msg_t) -> libc::c_int {
// TODO should return bool /rtn // TODO should return bool /rtn
pub unsafe fn dc_msg_is_forwarded(msg: *const dc_msg_t) -> libc::c_int { pub unsafe fn dc_msg_is_forwarded(msg: *const dc_msg_t) -> libc::c_int {
if msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint { if msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint {
return 0i32; return 0;
} }
return if 0 != dc_param_get_int((*msg).param, DC_PARAM_FORWARDED as i32, 0) { if 0 != (*msg).param.get_int(Param::Forwarded).unwrap_or_default() {
1i32 1
} else { } else {
0i32 0
}; }
} }
// TODO should return bool /rtn // TODO should return bool /rtn
pub unsafe fn dc_msg_is_info(msg: *const dc_msg_t) -> libc::c_int { pub unsafe fn dc_msg_is_info(msg: *const dc_msg_t) -> libc::c_int {
if msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint { if msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint {
return 0i32; return 0;
} }
let cmd: libc::c_int = dc_param_get_int((*msg).param, DC_PARAM_CMD as i32, 0); let cmd = (*msg).param.get_int(Param::Cmd).unwrap_or_default();
if (*msg).from_id == 2i32 as libc::c_uint if (*msg).from_id == 2i32 as libc::c_uint
|| (*msg).to_id == 2i32 as libc::c_uint || (*msg).to_id == 2i32 as libc::c_uint
|| 0 != cmd && cmd != 6i32 || 0 != cmd && cmd != 6i32
{ {
return 1i32; return 1;
} }
0 0
@@ -992,7 +1007,7 @@ pub unsafe fn dc_msg_is_setupmessage(msg: *const dc_msg_t) -> bool {
return false; return false;
} }
dc_param_get_int((*msg).param, DC_PARAM_CMD as i32, 0) == 6 (*msg).param.get_int(Param::Cmd) == Some(6)
} }
pub unsafe fn dc_msg_get_setupcodebegin(msg: *const dc_msg_t) -> *mut libc::c_char { pub unsafe fn dc_msg_get_setupcodebegin(msg: *const dc_msg_t) -> *mut libc::c_char {
@@ -1061,23 +1076,27 @@ pub unsafe fn dc_msg_set_file(
if msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint { if msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint {
return; return;
} }
dc_param_set((*msg).param, DC_PARAM_FILE as i32, file); if !file.is_null() {
dc_param_set((*msg).param, DC_PARAM_MIMETYPE as i32, filemime); (*msg).param.set(Param::File, as_str(file));
}
if !filemime.is_null() {
(*msg).param.set(Param::MimeType, as_str(filemime));
}
} }
pub unsafe fn dc_msg_set_dimension(msg: *mut dc_msg_t, width: libc::c_int, height: libc::c_int) { pub unsafe fn dc_msg_set_dimension(msg: *mut dc_msg_t, width: libc::c_int, height: libc::c_int) {
if msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint { if msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint {
return; return;
} }
dc_param_set_int((*msg).param, DC_PARAM_WIDTH as i32, width); (*msg).param.set_int(Param::Width, width);
dc_param_set_int((*msg).param, DC_PARAM_HEIGHT as i32, height); (*msg).param.set_int(Param::Height, height);
} }
pub unsafe fn dc_msg_set_duration(msg: *mut dc_msg_t, duration: libc::c_int) { pub unsafe fn dc_msg_set_duration(msg: *mut dc_msg_t, duration: libc::c_int) {
if msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint { if msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint {
return; return;
} }
dc_param_set_int((*msg).param, DC_PARAM_DURATION as i32, duration); (*msg).param.set_int(Param::Duration, duration);
} }
pub unsafe fn dc_msg_latefiling_mediasize( pub unsafe fn dc_msg_latefiling_mediasize(
@@ -1087,12 +1106,12 @@ pub unsafe fn dc_msg_latefiling_mediasize(
duration: libc::c_int, duration: libc::c_int,
) { ) {
if !(msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint) { if !(msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint) {
if width > 0i32 && height > 0i32 { if width > 0 && height > 0 {
dc_param_set_int((*msg).param, DC_PARAM_WIDTH as i32, width); (*msg).param.set_int(Param::Width, width);
dc_param_set_int((*msg).param, DC_PARAM_HEIGHT as i32, height); (*msg).param.set_int(Param::Height, height);
} }
if duration > 0i32 { if duration > 0 {
dc_param_set_int((*msg).param, DC_PARAM_DURATION as i32, duration); (*msg).param.set_int(Param::Duration, duration);
} }
dc_msg_save_param_to_disk(msg); dc_msg_save_param_to_disk(msg);
}; };
@@ -1107,7 +1126,7 @@ pub unsafe fn dc_msg_save_param_to_disk(msg: *mut dc_msg_t) -> bool {
(*msg).context, (*msg).context,
&(*msg).context.sql, &(*msg).context.sql,
"UPDATE msgs SET param=? WHERE id=?;", "UPDATE msgs SET param=? WHERE id=?;",
params![as_str((*(*msg).param).packed), (*msg).id as i32], params![(*msg).param.to_string(), (*msg).id as i32],
) )
.is_ok() .is_ok()
} }
@@ -1197,7 +1216,7 @@ pub unsafe fn dc_set_msg_failed(context: &Context, msg_id: uint32_t, error: *con
(*msg).state = DC_STATE_OUT_FAILED; (*msg).state = DC_STATE_OUT_FAILED;
} }
if !error.is_null() { if !error.is_null() {
dc_param_set((*msg).param, DC_PARAM_ERROR as i32, error); (*msg).param.set(Param::Error, as_str(error));
error!(context, 0, "{}", as_str(error),); error!(context, 0, "{}", as_str(error),);
} }
@@ -1205,7 +1224,7 @@ pub unsafe fn dc_set_msg_failed(context: &Context, msg_id: uint32_t, error: *con
context, context,
&context.sql, &context.sql,
"UPDATE msgs SET state=?, param=? WHERE id=?;", "UPDATE msgs SET state=?, param=? WHERE id=?;",
params![(*msg).state, as_str((*(*msg).param).packed), msg_id as i32], params![(*msg).state, (*msg).param.to_string(), msg_id as i32],
) )
.is_ok() .is_ok()
{ {

View File

@@ -1,439 +0,0 @@
use crate::dc_tools::*;
use crate::types::*;
use crate::x::*;
/// for msgs and jobs
pub const DC_PARAM_FILE: char = 'f'; // string
/// for msgs
pub const DC_PARAM_WIDTH: char = 'w'; // int
/// for msgs
pub const DC_PARAM_HEIGHT: char = 'h'; // int
/// for msgs
pub const DC_PARAM_DURATION: char = 'd'; // int
/// for msgs
pub const DC_PARAM_MIMETYPE: char = 'm'; // string
/// for msgs: incoming: message is encryoted, outgoing: guarantee E2EE or the message is not send
pub const DC_PARAM_GUARANTEE_E2EE: char = 'c'; // int (bool?)
/// for msgs: decrypted with validation errors or without mutual set, if neither 'c' nor 'e' are preset, the messages is only transport encrypted
pub const DC_PARAM_ERRONEOUS_E2EE: char = 'e'; // int
/// for msgs: force unencrypted message, either DC_FP_ADD_AUTOCRYPT_HEADER (1), DC_FP_NO_AUTOCRYPT_HEADER (2) or 0
pub const DC_PARAM_FORCE_PLAINTEXT: char = 'u'; // int (bool?)
/// for msgs: an incoming message which requests a MDN (aka read receipt)
pub const DC_PARAM_WANTS_MDN: char = 'r'; // int (bool?)
/// for msgs
pub const DC_PARAM_FORWARDED: char = 'a'; // int (bool?)
/// for msgs
pub const DC_PARAM_CMD: char = 'S'; // int
/// for msgs
pub const DC_PARAM_CMD_ARG: char = 'E'; // string
/// for msgs
pub const DC_PARAM_CMD_ARG2: char = 'F'; // string
/// for msgs
pub const DC_PARAM_CMD_ARG3: char = 'G'; // string
/// for msgs
pub const DC_PARAM_CMD_ARG4: char = 'H'; // string
/// for msgs
pub const DC_PARAM_ERROR: char = 'L'; // string
/// for msgs in PREPARING: space-separated list of message IDs of forwarded copies
pub const DC_PARAM_PREP_FORWARDS: char = 'P'; // string
/// for msgs
pub const DC_PARAM_SET_LATITUDE: char = 'l'; // float
/// for msgs
pub const DC_PARAM_SET_LONGITUDE: char = 'n'; // float
/// for jobs
pub const DC_PARAM_SERVER_FOLDER: char = 'Z'; // string
/// for jobs
pub const DC_PARAM_SERVER_UID: char = 'z'; // int
/// for jobs
pub const DC_PARAM_ALSO_MOVE: char = 'M'; // int (bool?)
/// for jobs: space-separated list of message recipients
pub const DC_PARAM_RECIPIENTS: char = 'R'; // stringap
/// for groups
pub const DC_PARAM_UNPROMOTED: char = 'U'; // int (bool?)
/// for groups and contacts
pub const DC_PARAM_PROFILE_IMAGE: char = 'i'; // string (bytes?)
/// for chats
pub const DC_PARAM_SELFTALK: char = 'K';
// missing: 's', 'x', 'g'
// values for DC_PARAM_FORCE_PLAINTEXT
pub const DC_FP_ADD_AUTOCRYPT_HEADER: u8 = 1;
pub const DC_FP_NO_AUTOCRYPT_HEADER: u8 = 2;
/// An object for handling key=value parameter lists; for the key, currently only
/// a single character is allowed.
///
/// The object is used eg. by Chat or dc_msg_t, for readable parameter names,
/// these classes define some DC_PARAM_* constantats.
///
/// Only for library-internal use.
#[derive(Copy, Clone)]
#[repr(C)]
pub struct dc_param_t {
pub packed: *mut libc::c_char,
}
// values for DC_PARAM_FORCE_PLAINTEXT
/* user functions */
pub unsafe fn dc_param_exists(param: *mut dc_param_t, key: libc::c_int) -> libc::c_int {
let mut p2: *mut libc::c_char = 0 as *mut libc::c_char;
if param.is_null() || key == 0i32 {
return 0i32;
}
return if !find_param((*param).packed, key, &mut p2).is_null() {
1i32
} else {
0i32
};
}
unsafe extern "C" fn find_param(
haystack: *mut libc::c_char,
key: libc::c_int,
ret_p2: *mut *mut libc::c_char,
) -> *mut libc::c_char {
let mut p1: *mut libc::c_char;
let mut p2: *mut libc::c_char;
p1 = haystack;
loop {
if p1.is_null() || *p1 as libc::c_int == 0i32 {
return 0 as *mut libc::c_char;
} else {
if *p1 as libc::c_int == key && *p1.offset(1isize) as libc::c_int == '=' as i32 {
break;
}
p1 = strchr(p1, '\n' as i32);
if !p1.is_null() {
p1 = p1.offset(1isize)
}
}
}
p2 = strchr(p1, '\n' as i32);
if p2.is_null() {
p2 = &mut *p1.offset(strlen(p1) as isize) as *mut libc::c_char
}
*ret_p2 = p2;
p1
}
/* the value may be an empty string, "def" is returned only if the value unset. The result must be free()'d in any case. */
pub unsafe fn dc_param_get(
param: *const dc_param_t,
key: libc::c_int,
def: *const libc::c_char,
) -> *mut libc::c_char {
let mut p1: *mut libc::c_char;
let mut p2: *mut libc::c_char = 0 as *mut libc::c_char;
let bak: libc::c_char;
let ret: *mut libc::c_char;
if param.is_null() || key == 0i32 {
return if !def.is_null() {
dc_strdup(def)
} else {
0 as *mut libc::c_char
};
}
p1 = find_param((*param).packed, key, &mut p2);
if p1.is_null() {
return if !def.is_null() {
dc_strdup(def)
} else {
0 as *mut libc::c_char
};
}
p1 = p1.offset(2isize);
bak = *p2;
*p2 = 0i32 as libc::c_char;
ret = dc_strdup(p1);
dc_rtrim(ret);
*p2 = bak;
ret
}
pub unsafe fn dc_param_get_int(
param: *const dc_param_t,
key: libc::c_int,
def: int32_t,
) -> int32_t {
if param.is_null() || key == 0i32 {
return def;
}
let s = dc_param_get(param, key, 0 as *const libc::c_char);
if s.is_null() {
return def;
}
let ret = as_str(s).parse().unwrap_or_default();
free(s as *mut libc::c_void);
ret
}
/**
* Get value of a parameter.
*
* @memberof dc_param_t
* @param param Parameter object to query.
* @param key Key of the parameter to get, one of the DC_PARAM_* constants.
* @param def Value to return if the parameter is not set.
* @return The stored value or the default value.
*/
pub unsafe fn dc_param_get_float(
param: *const dc_param_t,
key: libc::c_int,
def: libc::c_double,
) -> libc::c_double {
if param.is_null() || key == 0 {
return def;
}
let str = dc_param_get(param, key, std::ptr::null());
if str.is_null() {
return def;
}
let ret = dc_atof(str) as libc::c_double;
free(str as *mut libc::c_void);
ret
}
pub unsafe fn dc_param_set(
mut param: *mut dc_param_t,
key: libc::c_int,
value: *const libc::c_char,
) {
let mut old1: *mut libc::c_char;
let mut old2: *mut libc::c_char;
let new1: *mut libc::c_char;
if param.is_null() || key == 0i32 {
return;
}
old1 = (*param).packed;
old2 = 0 as *mut libc::c_char;
if !old1.is_null() {
let p1: *mut libc::c_char;
let mut p2: *mut libc::c_char = 0 as *mut libc::c_char;
p1 = find_param(old1, key, &mut p2);
if !p1.is_null() {
*p1 = 0i32 as libc::c_char;
old2 = p2
} else if value.is_null() {
return;
}
}
dc_rtrim(old1);
dc_ltrim(old2);
if !old1.is_null() && *old1.offset(0isize) as libc::c_int == 0i32 {
old1 = 0 as *mut libc::c_char
}
if !old2.is_null() && *old2.offset(0isize) as libc::c_int == 0i32 {
old2 = 0 as *mut libc::c_char
}
if !value.is_null() {
new1 = dc_mprintf(
b"%s%s%c=%s%s%s\x00" as *const u8 as *const libc::c_char,
if !old1.is_null() {
old1
} else {
b"\x00" as *const u8 as *const libc::c_char
},
if !old1.is_null() {
b"\n\x00" as *const u8 as *const libc::c_char
} else {
b"\x00" as *const u8 as *const libc::c_char
},
key,
value,
if !old2.is_null() {
b"\n\x00" as *const u8 as *const libc::c_char
} else {
b"\x00" as *const u8 as *const libc::c_char
},
if !old2.is_null() {
old2
} else {
b"\x00" as *const u8 as *const libc::c_char
},
)
} else {
new1 = dc_mprintf(
b"%s%s%s\x00" as *const u8 as *const libc::c_char,
if !old1.is_null() {
old1
} else {
b"\x00" as *const u8 as *const libc::c_char
},
if !old1.is_null() && !old2.is_null() {
b"\n\x00" as *const u8 as *const libc::c_char
} else {
b"\x00" as *const u8 as *const libc::c_char
},
if !old2.is_null() {
old2
} else {
b"\x00" as *const u8 as *const libc::c_char
},
)
}
free((*param).packed as *mut libc::c_void);
(*param).packed = new1;
}
pub unsafe fn dc_param_set_int(param: *mut dc_param_t, key: libc::c_int, value: int32_t) {
if param.is_null() || key == 0i32 {
return;
}
let value_str: *mut libc::c_char = dc_mprintf(
b"%i\x00" as *const u8 as *const libc::c_char,
value as libc::c_int,
);
if value_str.is_null() {
return;
}
dc_param_set(param, key, value_str);
free(value_str as *mut libc::c_void);
}
/* library-private */
pub unsafe fn dc_param_new() -> *mut dc_param_t {
let mut param: *mut dc_param_t;
param = calloc(1, ::std::mem::size_of::<dc_param_t>()) as *mut dc_param_t;
assert!(!param.is_null());
(*param).packed = calloc(1, 1) as *mut libc::c_char;
param
}
pub unsafe fn dc_param_empty(param: *mut dc_param_t) {
if param.is_null() {
return;
}
*(*param).packed.offset(0isize) = 0i32 as libc::c_char;
}
pub unsafe fn dc_param_unref(param: *mut dc_param_t) {
if param.is_null() {
return;
}
dc_param_empty(param);
free((*param).packed as *mut libc::c_void);
free(param as *mut libc::c_void);
}
pub unsafe fn dc_param_set_packed(mut param: *mut dc_param_t, packed: *const libc::c_char) {
if param.is_null() {
return;
}
dc_param_empty(param);
if !packed.is_null() {
free((*param).packed as *mut libc::c_void);
(*param).packed = dc_strdup(packed)
};
}
pub unsafe fn dc_param_set_urlencoded(mut param: *mut dc_param_t, urlencoded: *const libc::c_char) {
if param.is_null() {
return;
}
dc_param_empty(param);
if !urlencoded.is_null() {
free((*param).packed as *mut libc::c_void);
(*param).packed = dc_strdup(urlencoded);
dc_str_replace(
&mut (*param).packed,
b"&\x00" as *const u8 as *const libc::c_char,
b"\n\x00" as *const u8 as *const libc::c_char,
);
};
}
/**
* Set parameter to a float.
*
* @memberof dc_param_t
* @param param Parameter object to modify.
* @param key Key of the parameter to modify, one of the DC_PARAM_* constants.
* @param value Value to store for key.
* @return None.
*/
pub unsafe fn dc_param_set_float(param: *mut dc_param_t, key: libc::c_int, value: libc::c_double) {
if param.is_null() || key == 0 {
return;
}
let value_str = dc_ftoa(value);
if value_str.is_null() {
return;
}
dc_param_set(param, key, value_str);
free(value_str as *mut libc::c_void);
}
#[cfg(test)]
mod tests {
use super::*;
use std::ffi::CStr;
#[test]
fn test_dc_param() {
unsafe {
let p1: *mut dc_param_t = dc_param_new();
dc_param_set_packed(
p1,
b"\r\n\r\na=1\nb=2\n\nc = 3 \x00" as *const u8 as *const libc::c_char,
);
assert_eq!(dc_param_get_int(p1, 'a' as i32, 0), 1);
assert_eq!(dc_param_get_int(p1, 'b' as i32, 0), 2);
assert_eq!(dc_param_get_int(p1, 'c' as i32, 0), 0);
assert_eq!(dc_param_exists(p1, 'c' as i32), 0);
dc_param_set_int(p1, 'd' as i32, 4i32);
assert_eq!(dc_param_get_int(p1, 'd' as i32, 0), 4);
dc_param_empty(p1);
dc_param_set(
p1,
'a' as i32,
b"foo\x00" as *const u8 as *const libc::c_char,
);
dc_param_set_int(p1, 'b' as i32, 2i32);
dc_param_set(p1, 'c' as i32, 0 as *const libc::c_char);
dc_param_set_int(p1, 'd' as i32, 4i32);
assert_eq!(
CStr::from_ptr((*p1).packed as *const libc::c_char)
.to_str()
.unwrap(),
"a=foo\nb=2\nd=4"
);
dc_param_set(p1, 'b' as i32, 0 as *const libc::c_char);
assert_eq!(
CStr::from_ptr((*p1).packed as *const libc::c_char)
.to_str()
.unwrap(),
"a=foo\nd=4",
);
dc_param_set(p1, 'a' as i32, 0 as *const libc::c_char);
dc_param_set(p1, 'd' as i32, 0 as *const libc::c_char);
assert_eq!(
CStr::from_ptr((*p1).packed as *const libc::c_char)
.to_str()
.unwrap(),
"",
);
dc_param_unref(p1);
}
}
}

View File

@@ -1,11 +1,13 @@
use percent_encoding::percent_decode_str;
use crate::context::Context; use crate::context::Context;
use crate::dc_chat::*; use crate::dc_chat::*;
use crate::dc_contact::*; use crate::dc_contact::*;
use crate::dc_lot::*; use crate::dc_lot::*;
use crate::dc_param::*;
use crate::dc_strencode::*; use crate::dc_strencode::*;
use crate::dc_tools::*; use crate::dc_tools::*;
use crate::key::*; use crate::key::*;
use crate::param::*;
use crate::peerstate::*; use crate::peerstate::*;
use crate::types::*; use crate::types::*;
use crate::x::*; use crate::x::*;
@@ -54,36 +56,40 @@ pub unsafe fn dc_check_qr(context: &Context, qr: *const libc::c_char) -> *mut dc
if !fragment.is_null() { if !fragment.is_null() {
*fragment = 0i32 as libc::c_char; *fragment = 0i32 as libc::c_char;
fragment = fragment.offset(1isize); fragment = fragment.offset(1isize);
let param: *mut dc_param_t = dc_param_new(); let param: Params = as_str(fragment).parse().expect("invalid params");
dc_param_set_urlencoded(param, fragment); addr = param
addr = dc_param_get(param, DC_PARAM_FORWARDED as i32, 0 as *const libc::c_char); .get(Param::Forwarded)
.map(|s| to_cstring(s))
.unwrap_or_else(|| std::ptr::null_mut());
if !addr.is_null() { if !addr.is_null() {
let mut urlencoded: *mut libc::c_char = dc_param_get( if let Some(ref name_enc) = param.get(Param::SetLongitude) {
param, let name_r = percent_decode_str(name_enc)
DC_PARAM_SET_LONGITUDE as i32, .decode_utf8()
0 as *const libc::c_char, .expect("invalid name");
); name = to_cstring(name_r);
if !urlencoded.is_null() {
name = dc_urldecode(urlencoded);
dc_normalize_name(name); dc_normalize_name(name);
free(urlencoded as *mut libc::c_void);
} }
invitenumber = dc_param_get( invitenumber = param
param, .get(Param::ProfileImage)
DC_PARAM_PROFILE_IMAGE as i32, .map(|s| to_cstring(s))
0 as *const libc::c_char, .unwrap_or_else(|| std::ptr::null_mut());
); auth = param
auth = dc_param_get(param, 's' as i32, 0 as *const libc::c_char); .get(Param::Auth)
grpid = dc_param_get(param, 'x' as i32, 0 as *const libc::c_char); .map(|s| to_cstring(s))
.unwrap_or_else(|| std::ptr::null_mut());
grpid = param
.get(Param::GroupId)
.map(|s| to_cstring(s))
.unwrap_or_else(|| std::ptr::null_mut());
if !grpid.is_null() { if !grpid.is_null() {
urlencoded = dc_param_get(param, 'g' as i32, 0 as *const libc::c_char); if let Some(grpname_enc) = param.get(Param::GroupName) {
if !urlencoded.is_null() { let grpname_r = percent_decode_str(grpname_enc)
grpname = dc_urldecode(urlencoded); .decode_utf8()
free(urlencoded as *mut libc::c_void); .expect("invalid groupname");
grpname = to_cstring(grpname_r);
} }
} }
} }
dc_param_unref(param);
} }
fingerprint = dc_normalize_fingerprint_c(payload); fingerprint = dc_normalize_fingerprint_c(payload);
current_block = 5023038348526654800; current_block = 5023038348526654800;

View File

@@ -17,10 +17,10 @@ use crate::dc_location::*;
use crate::dc_mimeparser::*; use crate::dc_mimeparser::*;
use crate::dc_move::*; use crate::dc_move::*;
use crate::dc_msg::*; use crate::dc_msg::*;
use crate::dc_param::*;
use crate::dc_securejoin::*; use crate::dc_securejoin::*;
use crate::dc_strencode::*; use crate::dc_strencode::*;
use crate::dc_tools::*; use crate::dc_tools::*;
use crate::param::*;
use crate::peerstate::*; use crate::peerstate::*;
use crate::sql; use crate::sql;
use crate::stock::StockMessage; use crate::stock::StockMessage;
@@ -480,9 +480,8 @@ pub unsafe fn dc_receive_imf(
) )
} }
if 0 != mime_parser.is_system_message { if 0 != mime_parser.is_system_message {
dc_param_set_int(
(*part).param, (*part).param.set_int( Param::Cmd,
'S' as i32,
mime_parser.is_system_message, mime_parser.is_system_message,
); );
} }
@@ -511,7 +510,7 @@ pub unsafe fn dc_receive_imf(
} else { } else {
String::new() String::new()
}, },
as_str((*(*part).param).packed), (*part).param.to_string(),
(*part).bytes, (*part).bytes,
hidden, hidden,
if 0 != save_mime_headers { if 0 != save_mime_headers {
@@ -743,29 +742,18 @@ pub unsafe fn dc_receive_imf(
} }
} }
if 0 != mime_parser.is_send_by_messenger || 0 != mdn_consumed { if 0 != mime_parser.is_send_by_messenger || 0 != mdn_consumed {
let param = dc_param_new(); let mut param = Params::new();
let server_folder_c = to_cstring(server_folder.as_ref()); param.set(Param::ServerFolder, server_folder.as_ref());
dc_param_set( param.set_int(Param::ServerUid, server_uid as i32);
param,
DC_PARAM_SERVER_FOLDER as i32,
server_folder_c,
);
free(server_folder_c as *mut _);
dc_param_set_int(
param,
DC_PARAM_SERVER_UID as i32,
server_uid as i32,
);
if 0 != mime_parser.is_send_by_messenger if 0 != mime_parser.is_send_by_messenger
&& 0 != context && 0 != context
.sql .sql
.get_config_int(context, "mvbox_move") .get_config_int(context, "mvbox_move")
.unwrap_or_else(|| 1) .unwrap_or_else(|| 1)
{ {
dc_param_set_int(param, DC_PARAM_ALSO_MOVE as i32, 1); param.set_int(Param::AlsoMove, 1);
} }
dc_job_add(context, 120, 0, (*param).packed, 0); dc_job_add(context, 120, 0, param, 0);
dc_param_unref(param);
} }
} }
} }
@@ -833,7 +821,7 @@ pub unsafe fn dc_receive_imf(
context, context,
DC_JOB_DELETE_MSG_ON_IMAP, DC_JOB_DELETE_MSG_ON_IMAP,
created_db_entries[0].1 as i32, created_db_entries[0].1 as i32,
0 as *const libc::c_char, Params::new(),
0, 0,
); );
} }
@@ -1226,18 +1214,18 @@ unsafe fn create_or_lookup_group(
carray_get(mime_parser.parts, i_0 as libc::c_uint) carray_get(mime_parser.parts, i_0 as libc::c_uint)
as *mut dc_mimepart_t; as *mut dc_mimepart_t;
if (*part).type_0 == 20 { if (*part).type_0 == 20 {
grpimage = dc_param_get( grpimage = (*part)
(*part).param, .param
DC_PARAM_FILE as i32, .get(Param::File)
0 as *const libc::c_char, .map(|s| to_cstring(s))
); .unwrap_or_else(|| std::ptr::null_mut());
ok = 1 ok = 1
} }
i_0 += 1 i_0 += 1
} }
} }
if 0 != ok { if 0 != ok {
let chat: *mut Chat = dc_chat_new(context); let chat = dc_chat_new(context);
info!( info!(
context, context,
0, 0,
@@ -1249,11 +1237,11 @@ unsafe fn create_or_lookup_group(
}, },
); );
dc_chat_load_from_db(chat, chat_id); dc_chat_load_from_db(chat, chat_id);
dc_param_set( if grpimage.is_null() {
(*chat).param, (*chat).param.remove(Param::ProfileImage);
DC_PARAM_PROFILE_IMAGE as i32, } else {
grpimage, (*chat).param.set(Param::ProfileImage, as_str(grpimage));
); }
dc_chat_update_param(chat); dc_chat_update_param(chat);
dc_chat_unref(chat); dc_chat_unref(chat);
free(grpimage as *mut libc::c_void); free(grpimage as *mut libc::c_void);

View File

@@ -1,7 +1,7 @@
use std::ffi::CString; use std::ffi::CString;
use mmime::mailimf_types::*; use mmime::mailimf_types::*;
use percent_encoding::{utf8_percent_encode, DEFAULT_ENCODE_SET}; use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC};
use crate::aheader::EncryptPreference; use crate::aheader::EncryptPreference;
use crate::constants::*; use crate::constants::*;
@@ -14,12 +14,12 @@ use crate::dc_e2ee::*;
use crate::dc_lot::*; use crate::dc_lot::*;
use crate::dc_mimeparser::*; use crate::dc_mimeparser::*;
use crate::dc_msg::*; use crate::dc_msg::*;
use crate::dc_param::*;
use crate::dc_qr::*; use crate::dc_qr::*;
use crate::dc_strencode::*; use crate::dc_strencode::*;
use crate::dc_token::*; use crate::dc_token::*;
use crate::dc_tools::*; use crate::dc_tools::*;
use crate::key::*; use crate::key::*;
use crate::param::*;
use crate::peerstate::*; use crate::peerstate::*;
use crate::stock::StockMessage; use crate::stock::StockMessage;
use crate::types::*; use crate::types::*;
@@ -87,8 +87,8 @@ pub unsafe fn dc_get_securejoin_qr(
return cleanup(fingerprint, chat, group_name, group_name_urlencoded); return cleanup(fingerprint, chat, group_name, group_name_urlencoded);
} }
let self_addr_urlencoded = utf8_percent_encode(&self_addr, DEFAULT_ENCODE_SET).to_string(); let self_addr_urlencoded = utf8_percent_encode(&self_addr, NON_ALPHANUMERIC).to_string();
let self_name_urlencoded = utf8_percent_encode(&self_name, DEFAULT_ENCODE_SET).to_string(); let self_name_urlencoded = utf8_percent_encode(&self_name, NON_ALPHANUMERIC).to_string();
qr = if 0 != group_chat_id { qr = if 0 != group_chat_id {
chat = dc_get_chat(context, group_chat_id); chat = dc_get_chat(context, group_chat_id);
@@ -268,24 +268,31 @@ unsafe fn send_handshake_msg(
b"Secure-Join: %s\x00" as *const u8 as *const libc::c_char, b"Secure-Join: %s\x00" as *const u8 as *const libc::c_char,
step, step,
); );
(*msg).hidden = 1i32; (*msg).hidden = 1;
dc_param_set_int((*msg).param, DC_PARAM_CMD as i32, 7); (*msg).param.set_int(Param::Cmd, 7);
dc_param_set((*msg).param, DC_PARAM_CMD_ARG as i32, step); if step.is_null() {
(*msg).param.remove(Param::Arg);
} else {
(*msg).param.set(Param::Arg, as_str(step));
}
if !param2.is_null() { if !param2.is_null() {
dc_param_set((*msg).param, DC_PARAM_CMD_ARG2 as i32, param2); (*msg).param.set(Param::Arg2, as_str(param2));
} }
if !fingerprint.is_null() { if !fingerprint.is_null() {
dc_param_set((*msg).param, DC_PARAM_CMD_ARG3 as i32, fingerprint); (*msg).param.set(Param::Arg3, as_str(fingerprint));
} }
if !grpid.is_null() { if !grpid.is_null() {
dc_param_set((*msg).param, DC_PARAM_CMD_ARG4 as i32, grpid); (*msg).param.set(Param::Arg4, as_str(grpid));
} }
if strcmp(step, b"vg-request\x00" as *const u8 as *const libc::c_char) == 0i32 if strcmp(step, b"vg-request\x00" as *const u8 as *const libc::c_char) == 0i32
|| strcmp(step, b"vc-request\x00" as *const u8 as *const libc::c_char) == 0i32 || strcmp(step, b"vc-request\x00" as *const u8 as *const libc::c_char) == 0i32
{ {
dc_param_set_int((*msg).param, DC_PARAM_FORCE_PLAINTEXT as i32, 1); (*msg).param.set_int(
Param::ForcePlaintext,
ForcePlaintext::AddAutocryptHeader as i32,
);
} else { } else {
dc_param_set_int((*msg).param, DC_PARAM_GUARANTEE_E2EE as i32, 1); (*msg).param.set_int(Param::GuranteeE2ee, 1);
} }
dc_send_msg(context, contact_chat_id, msg); dc_send_msg(context, contact_chat_id, msg);
dc_msg_unref(msg); dc_msg_unref(msg);

View File

@@ -24,6 +24,7 @@ pub mod key;
pub mod keyhistory; pub mod keyhistory;
pub mod keyring; pub mod keyring;
pub mod oauth2; pub mod oauth2;
pub mod param;
pub mod peerstate; pub mod peerstate;
pub mod pgp; pub mod pgp;
pub mod smtp; pub mod smtp;
@@ -48,7 +49,6 @@ pub mod dc_mimefactory;
pub mod dc_mimeparser; pub mod dc_mimeparser;
pub mod dc_move; pub mod dc_move;
pub mod dc_msg; pub mod dc_msg;
pub mod dc_param;
pub mod dc_qr; pub mod dc_qr;
pub mod dc_receive_imf; pub mod dc_receive_imf;
pub mod dc_saxparser; pub mod dc_saxparser;

View File

@@ -1,6 +1,6 @@
use std::collections::HashMap; use std::collections::HashMap;
use percent_encoding::{utf8_percent_encode, DEFAULT_ENCODE_SET}; use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC};
use serde::Deserialize; use serde::Deserialize;
use crate::context::Context; use crate::context::Context;
@@ -321,7 +321,7 @@ fn is_expired(context: &Context) -> bool {
} }
fn replace_in_uri(uri: impl AsRef<str>, key: impl AsRef<str>, value: impl AsRef<str>) -> String { fn replace_in_uri(uri: impl AsRef<str>, key: impl AsRef<str>, value: impl AsRef<str>) -> String {
let value_urlencoded = utf8_percent_encode(value.as_ref(), DEFAULT_ENCODE_SET).to_string(); let value_urlencoded = utf8_percent_encode(value.as_ref(), NON_ALPHANUMERIC).to_string();
uri.as_ref().replace(key.as_ref(), &value_urlencoded) uri.as_ref().replace(key.as_ref(), &value_urlencoded)
} }
@@ -344,7 +344,7 @@ mod tests {
fn test_replace_in_uri() { fn test_replace_in_uri() {
assert_eq!( assert_eq!(
replace_in_uri("helloworld", "world", "a-b c"), replace_in_uri("helloworld", "world", "a-b c"),
"helloa-b%20c" "helloa%2Db%20c"
); );
} }

238
src/param.rs Normal file
View File

@@ -0,0 +1,238 @@
use std::collections::BTreeMap;
use std::fmt;
use std::str;
use num_traits::FromPrimitive;
use crate::error;
/// Available param keys.
#[derive(PartialEq, Eq, Debug, Clone, Copy, Hash, PartialOrd, Ord, FromPrimitive)]
#[repr(u8)]
pub enum Param {
/// For messages and jobs
File = 'f' as u8,
/// For Messages
Width = 'w' as u8,
/// For Messages
Height = 'h' as u8,
/// For Messages
Duration = 'd' as u8,
/// For Messages
MimeType = 'm' as u8,
/// For Messages: message is encryoted, outgoing: guarantee E2EE or the message is not send
GuranteeE2ee = 'c' as u8,
/// For Messages: decrypted with validation errors or without mutual set, if neither
/// 'c' nor 'e' are preset, the messages is only transport encrypted.
ErroneousE2ee = 'e' as u8,
/// For Messages: force unencrypted message, either `ForcePlaintext::AddAutocryptHeader` (1),
/// `ForcePlaintext::NoAutocryptHeader` (2) or 0.
ForcePlaintext = 'u' as u8,
/// For Messages
WantsMdn = 'r' as u8,
/// For Messages
Forwarded = 'a' as u8,
/// For Messages
Cmd = 'S' as u8,
/// For Messages
Arg = 'E' as u8,
/// For Messages
Arg2 = 'F' as u8,
/// For Messages
Arg3 = 'G' as u8,
/// For Messages
Arg4 = 'H' as u8,
/// For Messages
Error = 'L' as u8,
/// For Messages: space-separated list of messaged IDs of forwarded copies.
PrepForwards = 'P' as u8,
/// For Jobs
SetLatitude = 'l' as u8,
/// For Jobs
SetLongitude = 'n' as u8,
/// For Jobs
ServerFolder = 'Z' as u8,
/// For Jobs
ServerUid = 'z' as u8,
/// For Jobs
AlsoMove = 'M' as u8,
/// For Jobs: space-separated list of message recipients
Recipients = 'R' as u8,
// For Groups
Unpromoted = 'U' as u8,
// For Groups and Contacts
ProfileImage = 'i' as u8,
// For Chats
Selftalk = 'K' as u8,
// For QR
Auth = 's' as u8,
// For QR
GroupId = 'x' as u8,
// For QR
GroupName = 'g' as u8,
}
/// Possible values for `Param::ForcePlaintext`.
#[derive(PartialEq, Eq, Debug, Clone, Copy, FromPrimitive)]
#[repr(u8)]
pub enum ForcePlaintext {
AddAutocryptHeader = 1,
NoAutocryptHeader = 2,
}
/// An object for handling key=value parameter lists.
///
/// The structure is serialized by calling `to_string()` on it.
///
/// Only for library-internal use.
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct Params {
inner: BTreeMap<Param, String>,
}
impl fmt::Display for Params {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for (i, (key, value)) in self.inner.iter().enumerate() {
if i > 0 {
write!(f, "\n")?;
}
write!(f, "{}={}", *key as u8 as char, value)?;
}
Ok(())
}
}
impl str::FromStr for Params {
type Err = error::Error;
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
let mut inner = BTreeMap::new();
for pair in s.trim().lines() {
let pair = pair.trim();
if pair.is_empty() {
continue;
}
// TODO: probably nicer using a regex
ensure!(pair.len() > 2, "Invalid key pair: '{}'", pair);
let mut split = pair.splitn(2, '=');
let key = split.next();
let value = split.next();
ensure!(key.is_some(), "Missing key");
ensure!(value.is_some(), "Missing value");
let key = key.unwrap().trim();
let value = value.unwrap().trim();
if let Some(key) = Param::from_u8(key.as_bytes()[0]) {
inner.insert(key, value.to_string());
} else {
bail!("Unknown key: {}", key);
}
}
Ok(Params { inner })
}
}
impl Params {
/// Create new empty params.
pub fn new() -> Self {
Default::default()
}
/// Get the value of the given key, return `None` if no value is set.
pub fn get(&self, key: Param) -> Option<&str> {
self.inner.get(&key).map(|s| s.as_str())
}
/// Check if the given key is set.
pub fn exists(&self, key: Param) -> bool {
self.inner.contains_key(&key)
}
/// Set the given key to the passed in value.
pub fn set(&mut self, key: Param, value: impl AsRef<str>) -> &mut Self {
self.inner.insert(key, value.as_ref().to_string());
self
}
/// Removes the given key, if it exists.
pub fn remove(&mut self, key: Param) -> &mut Self {
self.inner.remove(&key);
self
}
/// Check if there are any values in this.
pub fn is_empty(&self) -> bool {
self.inner.is_empty()
}
/// Returns how many key-value pairs are set.
pub fn len(&self) -> usize {
self.inner.len()
}
/// Get the given parameter and parse as `i32`.
pub fn get_int(&self, key: Param) -> Option<i32> {
self.get(key).and_then(|s| s.parse().ok())
}
/// Get the given parameter and parse as `f64`.
pub fn get_float(&self, key: Param) -> Option<f64> {
self.get(key).and_then(|s| s.parse().ok())
}
/// Set the given paramter to the passed in `i32`.
pub fn set_int(&mut self, key: Param, value: i32) -> &mut Self {
self.set(key, format!("{}", value));
self
}
/// Set the given parameter to the passed in `f64` .
pub fn set_float(&mut self, key: Param, value: f64) -> &mut Self {
self.set(key, format!("{}", value));
self
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_dc_param() {
let mut p1: Params = "\r\n\r\na=1\nf=2\n\nc = 3 ".parse().unwrap();
assert_eq!(p1.get_int(Param::Forwarded), Some(1));
assert_eq!(p1.get_int(Param::File), Some(2));
assert_eq!(p1.get_int(Param::Height), None);
assert!(!p1.exists(Param::Height));
p1.set_int(Param::Duration, 4);
assert_eq!(p1.get_int(Param::Duration), Some(4));
let mut p1 = Params::new();
p1.set(Param::Forwarded, "foo")
.set_int(Param::File, 2)
.remove(Param::GuranteeE2ee)
.set_int(Param::Duration, 4);
assert_eq!(p1.to_string(), "a=foo\nd=4\nf=2");
p1.remove(Param::File);
assert_eq!(p1.to_string(), "a=foo\nd=4",);
assert_eq!(p1.len(), 2);
p1.remove(Param::Forwarded);
p1.remove(Param::Duration);
assert_eq!(p1.to_string(), "",);
assert!(p1.is_empty());
assert_eq!(p1.len(), 0)
}
}

View File

@@ -6,9 +6,9 @@ use thread_local_object::ThreadLocal;
use crate::constants::*; use crate::constants::*;
use crate::context::Context; use crate::context::Context;
use crate::dc_param::*;
use crate::dc_tools::*; use crate::dc_tools::*;
use crate::error::{Error, Result}; use crate::error::{Error, Result};
use crate::param::*;
use crate::peerstate::*; use crate::peerstate::*;
use crate::x::*; use crate::x::*;
@@ -954,25 +954,25 @@ pub fn housekeeping(context: &Context) {
context, context,
&mut files_in_use, &mut files_in_use,
"SELECT param FROM msgs WHERE chat_id!=3 AND type!=10;", "SELECT param FROM msgs WHERE chat_id!=3 AND type!=10;",
'f' as i32, Param::File,
); );
maybe_add_from_param( maybe_add_from_param(
context, context,
&mut files_in_use, &mut files_in_use,
"SELECT param FROM jobs;", "SELECT param FROM jobs;",
'f' as i32, Param::File,
); );
maybe_add_from_param( maybe_add_from_param(
context, context,
&mut files_in_use, &mut files_in_use,
"SELECT param FROM chats;", "SELECT param FROM chats;",
'i' as i32, Param::ProfileImage,
); );
maybe_add_from_param( maybe_add_from_param(
context, context,
&mut files_in_use, &mut files_in_use,
"SELECT param FROM contacts;", "SELECT param FROM contacts;",
'i' as i32, Param::ProfileImage,
); );
context context
@@ -1123,31 +1123,20 @@ fn maybe_add_from_param(
context: &Context, context: &Context,
files_in_use: &mut HashSet<String>, files_in_use: &mut HashSet<String>,
query: &str, query: &str,
param_id: libc::c_int, param_id: Param,
) { ) {
let param = unsafe { dc_param_new() };
context context
.sql .sql
.query_row(query, NO_PARAMS, |row| { .query_row(query, NO_PARAMS, |row| {
unsafe { let param: Params = row.get::<_, String>(0)?.parse().unwrap_or_default();
let v = to_cstring(row.get::<_, String>(0)?); if let Some(file) = param.get(param_id) {
dc_param_set_packed(param, v as *const _); maybe_add_file(files_in_use, file);
let file = dc_param_get(param, param_id, 0 as *const _);
if !file.is_null() {
maybe_add_file(files_in_use, as_str(file));
free(file as *mut libc::c_void);
}
free(v as *mut _);
} }
Ok(()) Ok(())
}) })
.unwrap_or_else(|err| { .unwrap_or_else(|err| {
warn!(context, 0, "sql: failed to add_from_param: {}", err); warn!(context, 0, "sql: failed to add_from_param: {}", err);
}); });
unsafe { dc_param_unref(param) };
} }
#[cfg(test)] #[cfg(test)]

View File

@@ -911,7 +911,7 @@ fn test_dc_get_oauth2_url() {
let redirect_uri = "chat.delta:/com.b44t.messenger"; let redirect_uri = "chat.delta:/com.b44t.messenger";
let res = dc_get_oauth2_url(&ctx.ctx, addr, redirect_uri); let res = dc_get_oauth2_url(&ctx.ctx, addr, redirect_uri);
assert_eq!(res, Some("https://accounts.google.com/o/oauth2/auth?client_id=959970109878-4mvtgf6feshskf7695nfln6002mom908.apps.googleusercontent.com&redirect_uri=chat.delta:/com.b44t.messenger&response_type=code&scope=https%3A%2F%2Fmail.google.com%2F%20email&access_type=offline".into())); assert_eq!(res, Some("https://accounts.google.com/o/oauth2/auth?client_id=959970109878%2D4mvtgf6feshskf7695nfln6002mom908%2Eapps%2Egoogleusercontent%2Ecom&redirect_uri=chat%2Edelta%3A%2Fcom%2Eb44t%2Emessenger&response_type=code&scope=https%3A%2F%2Fmail.google.com%2F%20email&access_type=offline".into()));
} }
#[test] #[test]