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

View File

@@ -14,6 +14,7 @@ use crate::dc_receive_imf::*;
use crate::dc_tools::*;
use crate::imap::*;
use crate::key::*;
use crate::param::Params;
use crate::smtp::*;
use crate::sql::Sql;
use crate::types::*;
@@ -225,13 +226,7 @@ unsafe fn cb_precheck_imf(
}
dc_do_heuristics_moves(context, server_folder, msg_id);
if 0 != mark_seen {
dc_job_add(
context,
130i32,
msg_id as libc::c_int,
0 as *const libc::c_char,
0i32,
);
dc_job_add(context, 130, msg_id as libc::c_int, Params::new(), 0);
}
}
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_job::*;
use crate::dc_msg::*;
use crate::dc_param::*;
use crate::dc_tools::*;
use crate::param::*;
use crate::sql::{self, Sql};
use crate::stock::StockMessage;
use crate::types::*;
@@ -22,7 +22,7 @@ use crate::x::*;
* and are not updated on database changes;
* if you want an update, you have to recreate the object.
*/
#[derive(Copy, Clone)]
#[derive(Clone)]
pub struct Chat<'a> {
magic: uint32_t,
pub id: uint32_t,
@@ -32,7 +32,7 @@ pub struct Chat<'a> {
pub context: &'a Context,
pub grpid: *mut libc::c_char,
blocked: libc::c_int,
pub param: *mut dc_param_t,
pub param: Params,
pub gossiped_timestamp: i64,
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> {
let mut chat: *mut Chat;
chat = calloc(1, ::std::mem::size_of::<Chat>()) as *mut Chat;
(*chat).magic = 0xc4a7c4a7u32;
(*chat).context = context;
(*chat).type_0 = 0i32;
(*chat).param = dc_param_new();
chat
let chat = Chat {
magic: 0xc4a7c4a7,
id: 0,
type_0: 0,
name: std::ptr::null_mut(),
archived: 0,
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) {
@@ -78,9 +86,8 @@ pub unsafe fn dc_chat_unref(mut chat: *mut Chat) {
return;
}
dc_chat_empty(chat);
dc_param_unref((*chat).param);
(*chat).magic = 0i32 as uint32_t;
free(chat as *mut libc::c_void);
(*chat).magic = 0;
Box::from_raw(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).blocked = 0i32;
(*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) {
@@ -139,16 +146,12 @@ pub fn dc_chat_load_from_db(chat: *mut Chat, chat_id: u32) -> bool {
unsafe { to_cstring(raw) }
};
let packed: String = row.get(4)?;
unsafe {
let p = to_cstring(&packed);
dc_param_set_packed((*chat).param, p);
free(p as *mut _);
};
c.param = row.get::<_, String>(4)?.parse().unwrap_or_default();
c.archived = row.get(5)?;
c.blocked = row.get::<_, Option<i32>>(6)?.unwrap_or_default();
c.gossiped_timestamp = row.get(7)?;
c.is_sending_locations = row.get(8)?;
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));
},
_ => {
if 0 != unsafe { dc_param_exists((*chat).param, DC_PARAM_SELFTALK as i32) } {
if unsafe { &(*chat).param }.exists(Param::Selftalk) {
unsafe {
free((*chat).name as *mut libc::c_void);
(*chat).name =
@@ -387,13 +390,16 @@ unsafe fn prepare_msg_common<'a>(
mut msg: *mut dc_msg_t<'a>,
) -> uint32_t {
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).context = context;
if (*msg).type_0 == DC_MSG_TEXT {
/* the caller should check if the message text is empty */
} 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() {
error!(
context,
@@ -410,29 +416,34 @@ unsafe fn prepare_msg_common<'a>(
} else if !dc_make_rel_and_copy(context, &mut pathNfilename) {
OK_TO_CONTINUE = false;
} 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 {
/* Correct the type, take care not to correct already very special formats as GIF or VOICE.
Typical conversions:
- from FILE to AUDIO/VIDEO/IMAGE
- from FILE/IMAGE to GIF */
let mut better_type: libc::c_int = 0i32;
let mut better_mime: *mut libc::c_char = 0 as *mut libc::c_char;
let mut better_type = 0;
let mut better_mime = std::ptr::null_mut();
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;
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);
} else if 0 == dc_param_exists((*msg).param, DC_PARAM_MIMETYPE as i32) {
let mut better_mime_0: *mut libc::c_char = 0 as *mut libc::c_char;
} else if !(*msg).param.exists(Param::MimeType) {
let mut better_mime = std::ptr::null_mut();
dc_msg_guess_msgtype_from_suffix(
pathNfilename,
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!(
context,
@@ -441,6 +452,8 @@ unsafe fn prepare_msg_common<'a>(
as_str(pathNfilename),
(*msg).type_0
);
free(pathNfilename as *mut _);
}
} else {
error!(
@@ -463,8 +476,6 @@ unsafe fn prepare_msg_common<'a>(
}
dc_chat_unref(chat);
}
/* potential error already logged */
free(pathNfilename as *mut libc::c_void);
(*msg).id
}
@@ -473,7 +484,7 @@ unsafe fn prepare_msg_common<'a>(
unsafe fn prepare_msg_raw(
context: &Context,
chat: *mut Chat,
msg: *const dc_msg_t,
msg: *mut dc_msg_t,
timestamp: i64,
) -> uint32_t {
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
|| (*chat).type_0 == DC_CHAT_TYPE_VERIFIED_GROUP
{
if dc_param_get_int((*chat).param, DC_PARAM_UNPROMOTED as i32, 0) == 1 {
dc_param_set(
(*chat).param,
DC_PARAM_UNPROMOTED as i32,
0 as *const libc::c_char,
);
if (*chat).param.get_int(Param::Unpromoted).unwrap_or_default() == 1 {
(*chat).param.remove(Param::Unpromoted);
dc_chat_update_param(chat);
}
}
@@ -558,7 +565,11 @@ unsafe fn prepare_msg_raw(
.get_config_int(context, "e2ee_enabled")
.unwrap_or_else(|| 1);
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 all_mutual = 1;
@@ -613,13 +624,9 @@ unsafe fn prepare_msg_raw(
}
}
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,
DC_PARAM_ERRONEOUS_E2EE as i32,
0 as *const libc::c_char,
);
(*msg).param.remove(Param::ErroneousE2ee);
if 0 == dc_chat_is_self_talk(chat)
&& 0 != get_parent_mime_headers(
chat,
@@ -673,7 +680,7 @@ unsafe fn prepare_msg_raw(
// 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(
context,
&context.sql,
@@ -684,16 +691,14 @@ unsafe fn prepare_msg_raw(
timestamp,
DC_CONTACT_ID_SELF as i32,
(*chat).id as i32,
dc_param_get_float(
(*msg).param,
DC_PARAM_SET_LATITUDE as libc::c_int,
0.0,
),
dc_param_get_float(
(*msg).param,
DC_PARAM_SET_LONGITUDE as libc::c_int,
0.0,
),
(*msg)
.param
.get_float(Param::SetLatitude)
.unwrap_or_default(),
(*msg)
.param
.get_float(Param::SetLongitude)
.unwrap_or_default(),
],
)
.is_ok()
@@ -725,7 +730,7 @@ unsafe fn prepare_msg_raw(
(*msg).type_0,
(*msg).state,
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,
to_string(new_in_reply_to),
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 {
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,
chat_id: uint32_t,
) -> libc::c_int {
let mut last_is_encrypted: libc::c_int = 0i32;
let packed: Option<String> = sql.query_row_col(
context,
"SELECT param \
@@ -840,19 +844,17 @@ unsafe fn last_msg_in_chat_encrypted(
0,
);
if let Some(packed) = packed {
let msg_param = dc_param_new();
let packed_c = to_cstring(packed);
dc_param_set_packed(msg_param, packed_c);
free(packed_c as *mut _);
if 0 != dc_param_exists(msg_param, DC_PARAM_GUARANTEE_E2EE as i32) {
last_is_encrypted = 1;
if let Some(ref packed) = packed {
match packed.parse::<Params>() {
Ok(param) => param.exists(Param::GuranteeE2ee) as libc::c_int,
Err(err) => {
error!(context, 0, "invalid params stored: '{}', {:?}", packed, err);
0
}
}
dc_param_unref(msg_param);
} else {
0
}
last_is_encrypted
}
// 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.sql,
"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
}
@@ -921,39 +923,29 @@ pub unsafe fn dc_send_msg<'a>(
(*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);
}
if 0 == chat_id {
let forwards = dc_param_get(
(*msg).param,
DC_PARAM_PREP_FORWARDS as i32,
0 as *const libc::c_char,
);
if !forwards.is_null() {
let mut p = forwards;
while 0 != *p {
let id = strtol(p, &mut p, 10) as int32_t;
let forwards = (*msg).param.get(Param::PrepForwards);
if let Some(forwards) = forwards {
for forward in forwards.split(' ') {
let id: i32 = forward.parse().unwrap_or_default();
if 0 == id {
// avoid hanging if user tampers with db
break;
} else {
let copy = dc_get_msg(context, id as uint32_t);
let copy = dc_get_msg(context, id as u32);
if !copy.is_null() {
dc_send_msg(context, 0 as uint32_t, copy);
dc_send_msg(context, 0, copy);
}
dc_msg_unref(copy);
}
}
dc_param_set(
(*msg).param,
DC_PARAM_PREP_FORWARDS as i32,
0 as *const libc::c_char,
);
(*msg).param.remove(Param::PrepForwards);
dc_msg_save_param_to_disk(msg);
}
free(forwards as *mut libc::c_void);
}
(*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 {
let mut OK_TO_CONTINUE = true;
// 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 mut sth_changed: libc::c_int = 0i32;
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;
}
} 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() {
OK_TO_CONTINUE = false;
} 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) {
OK_TO_CONTINUE = false;
} 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 {
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 {
""
},
to_string((*(*msg).param).packed),
(*msg).param.to_string(),
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
}
@@ -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);
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
}
@@ -1587,13 +1582,9 @@ pub unsafe fn dc_add_contact_to_chat_ex(
} else {
/* we should respect this - whatever we send to the group, it gets discarded anyway! */
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,
DC_PARAM_UNPROMOTED as i32,
0 as *const libc::c_char,
);
(*chat).param.remove(Param::Unpromoted);
dc_chat_update_param(chat);
}
let self_addr = context
@@ -1627,7 +1618,7 @@ pub unsafe fn dc_add_contact_to_chat_ex(
}
}
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).text = to_cstring(context.stock_system_msg(
StockMessage::MsgAddMember,
@@ -1635,9 +1626,11 @@ pub unsafe fn dc_add_contact_to_chat_ex(
"",
DC_CONTACT_ID_SELF as uint32_t,
));
dc_param_set_int((*msg).param, DC_PARAM_CMD as i32, 4);
dc_param_set((*msg).param, DC_PARAM_CMD_ARG as i32, (*contact).addr);
dc_param_set_int((*msg).param, DC_PARAM_CMD_ARG2 as i32, flags);
(*msg).param.set_int(Param::Cmd, 4);
if !(*contact).addr.is_null() {
(*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);
context.call_cb(
Event::MSGS_CHANGED,
@@ -1736,7 +1729,7 @@ pub unsafe fn dc_remove_contact_from_chat(
} else {
/* we should respect this - whatever we send to the group, it gets discarded anyway! */
if !contact.is_null() {
if 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;
if (*contact).id == 1 as libc::c_uint {
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_param_set_int((*msg).param, DC_PARAM_CMD as i32, 5);
dc_param_set((*msg).param, DC_PARAM_CMD_ARG as i32, (*contact).addr);
(*msg).param.set_int(Param::Cmd, 5);
if !(*contact).addr.is_null() {
(*msg).param.set(Param::Arg, as_str((*contact).addr));
}
(*msg).id = dc_send_msg(context, chat_id, msg);
context.call_cb(
Event::MSGS_CHANGED,
@@ -1849,7 +1844,7 @@ pub unsafe fn dc_set_chat_name(
)
.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).text = to_cstring(context.stock_system_msg(
StockMessage::MsgGrpName,
@@ -1857,8 +1852,10 @@ pub unsafe fn dc_set_chat_name(
as_str(new_name),
DC_CONTACT_ID_SELF as u32,
));
dc_param_set_int((*msg).param, DC_PARAM_CMD as i32, 2);
dc_param_set((*msg).param, DC_PARAM_CMD_ARG as i32, (*chat).name);
(*msg).param.set_int(Param::Cmd, 2);
if !(*chat).name.is_null() {
(*msg).param.set(Param::Arg, as_str((*chat).name));
}
(*msg).id = dc_send_msg(context, chat_id, msg);
context.call_cb(
Event::MSGS_CHANGED,
@@ -1913,12 +1910,13 @@ pub unsafe fn dc_set_chat_profile_image(
}
}
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 dc_param_get_int((*chat).param, DC_PARAM_UNPROMOTED as i32, 0i32) == 0i32
{
dc_param_set_int((*msg).param, DC_PARAM_CMD as i32, 3i32);
dc_param_set((*msg).param, DC_PARAM_CMD_ARG as i32, new_image_rel);
if (*chat).param.get_int(Param::Unpromoted).unwrap_or_default() == 0 {
(*msg).param.set_int(Param::Cmd, 3);
(*msg).param.set(Param::Arg, as_str(new_image_rel));
(*msg).type_0 = DC_MSG_TEXT;
(*msg).text = to_cstring(context.stock_system_msg(
if !new_image_rel.is_null() {
@@ -1972,7 +1970,6 @@ pub unsafe fn dc_forward_msgs(
let created_db_entries = carray_new(16);
let mut curr_timestamp: i64;
let original_param: *mut dc_param_t = dc_param_new();
dc_unarchive_chat(context, chat_id);
if dc_chat_load_from_db(chat, chat_id) {
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) {
break;
}
dc_param_set_packed(original_param, (*(*msg).param).packed);
if (*msg).from_id != 1i32 as libc::c_uint {
dc_param_set_int((*msg).param, DC_PARAM_FORWARDED as i32, 1i32);
let original_param = (*msg).param.clone();
if (*msg).from_id != 1 {
(*msg).param.set_int(Param::Forwarded, 1);
}
dc_param_set(
(*msg).param,
DC_PARAM_GUARANTEE_E2EE as i32,
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);
(*msg).param.remove(Param::GuranteeE2ee);
(*msg).param.remove(Param::ForcePlaintext);
(*msg).param.remove(Param::Cmd);
let new_msg_id: uint32_t;
if (*msg).state == DC_STATE_OUT_PREPARING {
let fresh9 = curr_timestamp;
curr_timestamp = curr_timestamp + 1;
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).id = src_msg_id as uint32_t;
let old_fwd: *mut libc::c_char = dc_param_get(
(*msg).param,
DC_PARAM_PREP_FORWARDS as i32,
b"\x00" as *const u8 as *const libc::c_char,
);
let new_fwd: *mut libc::c_char = dc_mprintf(
b"%s %d\x00" as *const u8 as *const libc::c_char,
old_fwd,
new_msg_id,
);
dc_param_set((*msg).param, DC_PARAM_PREP_FORWARDS as i32, new_fwd);
if let Some(old_fwd) = (*msg).param.get(Param::PrepForwards) {
let new_fwd = format!("{} {}", old_fwd, new_msg_id);
(*msg).param.set(Param::PrepForwards, new_fwd);
} else {
(*msg)
.param
.set(Param::PrepForwards, new_msg_id.to_string());
}
dc_msg_save_param_to_disk(msg);
free(new_fwd as *mut libc::c_void);
free(old_fwd as *mut libc::c_void);
(*msg).param = save_param
(*msg).param = save_param;
} else {
(*msg).state = DC_STATE_OUT_PENDING;
let fresh10 = curr_timestamp;
@@ -2076,7 +2063,6 @@ pub unsafe fn dc_forward_msgs(
dc_contact_unref(contact);
dc_msg_unref(msg);
dc_chat_unref(chat);
dc_param_unref(original_param);
}
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();
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));
} else if (*chat).type_0 == 100 {
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 contact: *mut dc_contact_t = 0 as *mut dc_contact_t;
if !(chat.is_null() || (*chat).magic != 0xc4a7c4a7u32) {
image_rel = dc_param_get(
(*chat).param,
DC_PARAM_PROFILE_IMAGE as i32,
0 as *const libc::c_char,
);
image_rel = to_cstring((*chat).param.get(Param::ProfileImage).unwrap_or_default());
if !image_rel.is_null() && 0 != *image_rel.offset(0isize) as libc::c_int {
image_abs = dc_get_abs_path((*chat).context, image_rel)
} 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
pub unsafe fn dc_chat_is_unpromoted(chat: *const Chat) -> libc::c_int {
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

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::context::Context;
@@ -9,6 +9,7 @@ use crate::dc_saxparser::*;
use crate::dc_tools::*;
use crate::imap::*;
use crate::oauth2::*;
use crate::param::Params;
use crate::types::*;
use crate::x::*;
@@ -60,9 +61,10 @@ pub unsafe fn dc_configure(context: &Context) {
);
return;
}
dc_job_kill_action(context, 900i32);
dc_job_add(context, 900i32, 0i32, 0 as *const libc::c_char, 0i32);
dc_job_kill_action(context, 900);
dc_job_add(context, 900, 0, Params::new(), 0);
}
pub unsafe fn dc_has_ongoing(context: &Context) -> libc::c_int {
let s_a = context.running_state.clone();
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 param_domain = parsed.host();
let param_addr_urlencoded =
utf8_percent_encode(&param.addr, DEFAULT_ENCODE_SET)
.to_string();
utf8_percent_encode(&param.addr, NON_ALPHANUMERIC).to_string();
if !s.shall_stop_ongoing {
context.call_cb(

View File

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

View File

@@ -15,10 +15,10 @@ use crate::dc_location::*;
use crate::dc_loginparam::*;
use crate::dc_mimefactory::*;
use crate::dc_msg::*;
use crate::dc_param::*;
use crate::dc_tools::*;
use crate::imap::*;
use crate::keyhistory::*;
use crate::param::*;
use crate::sql;
use crate::types::*;
use crate::x::*;
@@ -33,7 +33,7 @@ use crate::x::*;
// timeouts until actions are aborted.
// this may also affects IDLE to return, so a re-connect may take this time.
// mailcore2 uses 30 seconds, k-9 uses 10 seconds
#[derive(Copy, Clone)]
#[derive(Clone)]
#[repr(C)]
pub struct dc_job_t {
pub job_id: uint32_t,
@@ -42,7 +42,7 @@ pub struct dc_job_t {
pub desired_timestamp: i64,
pub added_timestamp: i64,
pub tries: libc::c_int,
pub param: *mut dc_param_t,
pub param: Params,
pub try_again: libc::c_int,
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)?,
added_timestamp: row.get(4)?,
tries: row.get(6)?,
param: dc_param_new(),
param: row.get::<_, String>(3)?.parse().unwrap_or_default(),
try_again: 0,
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)
},
|jobs| {
@@ -225,7 +221,6 @@ unsafe fn dc_job_perform(context: &Context, thread: libc::c_int, probe_network:
} else {
dc_job_delete(context, &mut job);
}
dc_param_unref(job.param);
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![
job.desired_timestamp,
job.tries as i64,
as_str(unsafe { (*job.param).packed }),
job.param.to_string(),
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 buf: *mut libc::c_void = 0 as *mut libc::c_void;
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 */
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 {
13109137661213826276 => {
filename = dc_param_get(job.param, DC_PARAM_FILE as i32, 0 as *const libc::c_char);
if filename.is_null() {
filename = to_cstring(job.param.get(Param::File).unwrap_or_default());
if strlen(filename) == 0 {
warn!(context, 0, "Missing file name for job {}", job.job_id,);
} else if !(0 == dc_read_file(context, filename, &mut buf, &mut buf_bytes)) {
recipients = dc_param_get(
job.param,
DC_PARAM_RECIPIENTS as i32,
0 as *const libc::c_char,
);
if recipients.is_null() {
let recipients = job.param.get(Param::Recipients);
if recipients.is_none() {
warn!(context, 0, "Missing recipients for job {}", job.job_id,);
} else {
let recipients_list = std::ffi::CStr::from_ptr(recipients)
.to_str()
let recipients_list = recipients
.unwrap()
.split("\x1e")
.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(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)]
unsafe fn dc_job_do_DC_JOB_MARKSEEN_MDN_ON_IMAP(context: &Context, job: &mut dc_job_t) {
let current_block: u64;
let folder: *mut libc::c_char = dc_param_get(
job.param,
DC_PARAM_SERVER_FOLDER as i32,
0 as *const libc::c_char,
);
let uid: uint32_t = dc_param_get_int(job.param, DC_PARAM_SERVER_UID as i32, 0) as uint32_t;
let mut dest_uid: uint32_t = 0i32 as uint32_t;
let folder = job
.param
.get(Param::ServerFolder)
.unwrap_or_default()
.to_string();
let uid = job.param.get_int(Param::ServerUid).unwrap_or_default() as u32;
let mut dest_uid = 0;
let inbox = context.inbox.read().unwrap();
if !inbox.is_connected() {
connect_to_inbox(context, &inbox);
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;
} else {
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 {
11006700562992250127 => {
let folder = CStr::from_ptr(folder).to_str().unwrap();
if inbox.set_seen(context, folder, uid) as libc::c_uint == 0i32 as libc::c_uint {
if inbox.set_seen(context, &folder, uid) == 0 {
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
.sql
.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)]
@@ -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);
}
_ => {
if 0 != dc_param_get_int(
(*msg).param,
DC_PARAM_WANTS_MDN as i32,
0i32,
) && 0
!= context
if 0 != (*msg).param.get_int(Param::WantsMdn).unwrap_or_default()
&& 0 != context
.sql
.get_config_int(context, "mdns_enabled")
.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);
}
_ => {
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
.sql
.get_config_int(context, "mdns_enabled")
@@ -756,7 +738,7 @@ unsafe fn dc_add_smtp_job(
let pathNfilename: *mut libc::c_char;
let mut success: libc::c_int = 0i32;
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(
context,
b"$BLOBDIR\x00" as *const u8 as *const libc::c_char,
@@ -789,8 +771,8 @@ unsafe fn dc_add_smtp_job(
(*mimefactory).recipients_addr,
b"\x1e\x00" as *const u8 as *const libc::c_char,
);
dc_param_set(param, DC_PARAM_FILE as i32, pathNfilename);
dc_param_set(param, DC_PARAM_RECIPIENTS as i32, recipients);
param.set(Param::File, as_str(pathNfilename));
param.set(Param::File, as_str(recipients));
dc_job_add(
context,
action,
@@ -799,23 +781,23 @@ unsafe fn dc_add_smtp_job(
{
(*(*mimefactory).msg).id
} else {
0i32 as libc::c_uint
0
}) as libc::c_int,
(*param).packed,
0i32,
param,
0,
);
success = 1i32
}
dc_param_unref(param);
free(recipients as *mut libc::c_void);
free(pathNfilename as *mut libc::c_void);
return success;
}
pub unsafe fn dc_job_add(
context: &Context,
action: libc::c_int,
foreign_id: libc::c_int,
param: *const libc::c_char,
param: Params,
delay_seconds: libc::c_int,
) {
let timestamp = time();
@@ -836,11 +818,7 @@ pub unsafe fn dc_job_add(
thread,
action,
foreign_id,
if !param.is_null() {
as_str(param)
} else {
""
},
param.to_string(),
(timestamp + delay_seconds as i64)
]
).ok();
@@ -1184,22 +1162,23 @@ pub unsafe fn dc_job_send_msg(context: &Context, msg_id: uint32_t) -> libc::c_in
} else {
// 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) {
let pathNfilename = dc_param_get(
(*mimefactory.msg).param,
DC_PARAM_FILE as i32,
0 as *const libc::c_char,
let pathNfilename = to_cstring(
(*mimefactory.msg)
.param
.get(Param::File)
.unwrap_or_default(),
);
if !pathNfilename.is_null() {
if strlen(pathNfilename) > 0 {
if ((*mimefactory.msg).type_0 == DC_MSG_IMAGE
|| (*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 w: uint32_t = 0;
let mut h: uint32_t = 0;
dc_param_set_int((*mimefactory.msg).param, DC_PARAM_WIDTH as i32, 0);
dc_param_set_int((*mimefactory.msg).param, DC_PARAM_HEIGHT as i32, 0);
let mut w = 0;
let mut h = 0;
(*mimefactory.msg).param.set_int(Param::Width, 0);
(*mimefactory.msg).param.set_int(Param::Height, 0);
if 0 != dc_read_file(
context,
pathNfilename,
@@ -1212,16 +1191,8 @@ pub unsafe fn dc_job_send_msg(context: &Context, msg_id: uint32_t) -> libc::c_in
&mut w,
&mut h,
) {
dc_param_set_int(
(*mimefactory.msg).param,
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,
);
(*mimefactory.msg).param.set_int(Param::Width, w as i32);
(*mimefactory.msg).param.set_int(Param::Height, h as i32);
}
}
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 */
if 0 == dc_mimefactory_render(&mut mimefactory) {
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
{
warn!(
context,
0,
"e2e encryption unavailable {} - {}",
"e2e encryption unavailable {} - {:?}",
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(
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
&& 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
{
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_add_to_keyhistory(

View File

@@ -6,9 +6,9 @@ use crate::dc_array::*;
use crate::dc_chat::*;
use crate::dc_job::*;
use crate::dc_msg::*;
use crate::dc_param::*;
use crate::dc_saxparser::*;
use crate::dc_tools::*;
use crate::param::*;
use crate::sql;
use crate::stock::StockMessage;
use crate::types::*;
@@ -105,7 +105,7 @@ pub unsafe fn dc_send_locations_to_chat(
"",
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);
} else if 0 == seconds && is_sending_locations_before {
let stock_str = CString::new(context.stock_system_msg(
@@ -128,7 +128,7 @@ pub unsafe fn dc_send_locations_to_chat(
context,
5007i32,
chat_id as libc::c_int,
0 as *const libc::c_char,
Params::new(),
seconds + 1i32,
);
}
@@ -143,7 +143,7 @@ pub unsafe fn dc_send_locations_to_chat(
#[allow(non_snake_case)]
unsafe fn schedule_MAYBE_SEND_LOCATIONS(context: &Context, flags: libc::c_int) {
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)
let mut msg = dc_msg_new(context, 10);
(*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_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 */
pub unsafe fn dc_lot_fill(
mut lot: *mut dc_lot_t,
msg: *const dc_msg_t,
msg: *mut dc_msg_t,
chat: *const Chat,
contact: *const dc_contact_t,
context: &Context,
@@ -161,7 +161,7 @@ pub unsafe fn dc_lot_fill(
}
}
(*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).state = (*msg).state;
}

View File

@@ -17,9 +17,9 @@ use crate::dc_contact::*;
use crate::dc_e2ee::*;
use crate::dc_location::*;
use crate::dc_msg::*;
use crate::dc_param::*;
use crate::dc_strencode::*;
use crate::dc_tools::*;
use crate::param::*;
use crate::stock::StockMessage;
use crate::types::*;
use crate::x::*;
@@ -114,7 +114,6 @@ pub unsafe fn dc_mimefactory_load_msg(
msg_id: uint32_t,
) -> libc::c_int {
if factory.is_null() || msg_id <= 9 || !(*factory).msg.is_null() {
info!((*factory).context, 0, "mimefactory: null");
return 0;
}
@@ -129,12 +128,9 @@ pub unsafe fn dc_mimefactory_load_msg(
if dc_msg_load_from_db((*factory).msg, context, msg_id)
&& dc_chat_load_from_db((*factory).chat, (*(*factory).msg).chat_id)
{
info!(context, 0, "mimefactory: loaded msg and chat",);
load_from(factory);
(*factory).req_mdn = 0;
if 0 != dc_chat_is_self_talk((*factory).chat) {
info!(context, 0, "mimefactory: selftalk");
clist_insert_after(
(*factory).recipients_names,
(*(*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,
);
} else {
info!(context, 0, "mimefactory: query map");
context
.sql
.query_map(
@@ -161,7 +156,6 @@ pub unsafe fn dc_mimefactory_load_msg(
Ok((authname, addr))
},
|rows| {
info!(context, 0, "mimefactory: processing rows");
for row in rows {
let (authname, addr) = row?;
let addr_c = to_cstring(addr);
@@ -187,14 +181,15 @@ pub unsafe fn dc_mimefactory_load_msg(
)
.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 {
let email_to_remove_c = dc_param_get(
(*(*factory).msg).param,
DC_PARAM_CMD_ARG as i32,
0 as *const libc::c_char,
);
let email_to_remove = to_string(email_to_remove_c);
let email_to_remove = (*(*factory).msg).param.get(Param::Arg).unwrap_or_default();
let email_to_remove_c = to_cstring(email_to_remove);
let self_addr = context
.sql
.get_config(context, "configured_addr")
@@ -227,8 +222,6 @@ pub unsafe fn dc_mimefactory_load_msg(
(*factory).req_mdn = 1
}
}
info!(context, 0, "mimefactory: loading in reply to");
let row = context.sql.query_row(
"SELECT mime_in_reply_to, mime_references FROM msgs WHERE id=?",
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)
let mut force_plaintext: 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 {
encryption_successfull: 0,
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;
min_verified = 2
} else {
force_plaintext =
dc_param_get_int((*(*factory).msg).param, DC_PARAM_FORCE_PLAINTEXT as i32, 0);
force_plaintext = (*(*factory).msg)
.param
.get_int(Param::ForcePlaintext)
.unwrap_or_default();
if force_plaintext == 0 {
e2ee_guaranteed =
dc_param_get_int((*(*factory).msg).param, DC_PARAM_GUARANTEE_E2EE as i32, 0)
e2ee_guaranteed = (*(*factory).msg)
.param
.get_int(Param::GuranteeE2ee)
.unwrap_or_default()
}
}
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
}
/* 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
|| (*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 {
let email_to_remove: *mut libc::c_char = dc_param_get(
(*msg).param,
DC_PARAM_CMD_ARG as i32,
0 as *const libc::c_char,
);
if !email_to_remove.is_null() {
let email_to_remove =
to_cstring((*msg).param.get(Param::Arg).unwrap_or_default());
if strlen(email_to_remove) > 0 {
mailimf_fields_add(
imf_fields,
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 {
do_gossip = 1;
let email_to_add: *mut libc::c_char = dc_param_get(
(*msg).param,
DC_PARAM_CMD_ARG as i32,
0 as *const libc::c_char,
);
if !email_to_add.is_null() {
let email_to_add = to_cstring((*msg).param.get(Param::Arg).unwrap_or_default());
if strlen(email_to_add) > 0 {
mailimf_fields_add(
imf_fields,
mailimf_field_new_custom(
@@ -610,13 +601,9 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc:
email_to_add,
),
);
grpimage = dc_param_get(
(*chat).param,
DC_PARAM_PROFILE_IMAGE as i32,
0 as *const libc::c_char,
)
grpimage = (*chat).param.get(Param::ProfileImage);
}
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!(
(*msg).context,
0,
@@ -632,26 +619,19 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc:
);
}
} else if command == 2 {
let value_to_add = to_cstring((*msg).param.get(Param::Arg).unwrap_or_default());
mailimf_fields_add(
imf_fields,
mailimf_field_new_custom(
strdup(
b"Chat-Group-Name-Changed\x00" as *const u8 as *const libc::c_char,
),
dc_param_get(
(*msg).param,
DC_PARAM_CMD_ARG as i32,
b"\x00" as *const u8 as *const libc::c_char,
),
value_to_add,
),
);
} else if command == 3 {
grpimage = dc_param_get(
(*msg).param,
DC_PARAM_CMD_ARG as i32,
0 as *const libc::c_char,
);
if grpimage.is_null() {
grpimage = (*msg).param.get(Param::Arg);
if grpimage.is_none() {
mailimf_fields_add(
imf_fields,
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));
}
if command == 7 {
let step: *mut libc::c_char = dc_param_get(
(*msg).param,
DC_PARAM_CMD_ARG as i32,
0 as *const libc::c_char,
);
if !step.is_null() {
let step = to_cstring((*msg).param.get(Param::Arg).unwrap_or_default());
if strlen(step) > 0 {
info!(
(*msg).context,
0,
@@ -704,12 +680,8 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc:
step,
),
);
let param2: *mut libc::c_char = dc_param_get(
(*msg).param,
DC_PARAM_CMD_ARG2 as i32,
0 as *const libc::c_char,
);
if !param2.is_null() {
let param2 = to_cstring((*msg).param.get(Param::Arg2).unwrap_or_default());
if strlen(param2) > 0 {
mailimf_fields_add(
imf_fields,
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(
(*msg).param,
DC_PARAM_CMD_ARG3 as i32,
0 as *const libc::c_char,
);
if !fingerprint.is_null() {
let fingerprint = to_cstring((*msg).param.get(Param::Arg3).unwrap_or_default());
if strlen(fingerprint) > 0 {
mailimf_fields_add(
imf_fields,
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(
(*msg).param,
DC_PARAM_CMD_ARG4 as i32,
0 as *const libc::c_char,
);
let grpid = match (*msg).param.get(Param::Arg4) {
Some(id) => to_cstring(id),
None => std::ptr::null_mut(),
};
if !grpid.is_null() {
mailimf_fields_add(
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;
dc_param_set((*meta).param, DC_PARAM_FILE as i32, grpimage);
let mut filename_as_sent: *mut libc::c_char = 0 as *mut libc::c_char;
(*meta).param.set(Param::File, grpimage);
let mut filename_as_sent = 0 as *mut libc::c_char;
meta_part = build_body_file(
meta,
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);
}
if (*msg).type_0 == DC_MSG_VOICE
|| (*msg).type_0 == DC_MSG_AUDIO
|| (*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 =
dc_param_get_int((*msg).param, DC_PARAM_DURATION as i32, 0);
let duration_ms = (*msg).param.get_int(Param::Duration).unwrap_or_default();
if duration_ms > 0 {
mailimf_fields_add(
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);
let mut fwdhint: *mut libc::c_char = 0 as *mut libc::c_char;
afwd_email = (*msg).param.exists(Param::Forwarded) as libc::c_int;
let mut fwdhint = 0 as *mut libc::c_char;
if 0 != afwd_email {
fwdhint = dc_strdup(
b"---------- Forwarded message ----------\r\nFrom: Delta Chat\r\n\r\n\x00"
as *const u8 as *const libc::c_char,
)
}
let mut final_text: *const libc::c_char = 0 as *const libc::c_char;
if !placeholdertext.is_null() {
final_text = placeholdertext
@@ -871,6 +841,7 @@ pub unsafe fn dc_mimefactory_render(mut factory: *mut dc_mimefactory_t) -> libc:
parts += 1;
free(fwdhint as *mut libc::c_void);
free(placeholdertext as *mut libc::c_void);
/* add attachment part */
if msgtype_has_file((*msg).type_0) {
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() {
mailmime_smart_add_part(message, meta_part);
}
if 0 != dc_param_exists((*msg).param, DC_PARAM_SET_LATITUDE as libc::c_int)
{
let latitude = dc_param_get_float(
(*msg).param,
DC_PARAM_SET_LATITUDE as libc::c_int,
0.0,
);
let longitude = dc_param_get_float(
(*msg).param,
DC_PARAM_SET_LONGITUDE as libc::c_int,
0.0,
);
if (*msg).param.exists(Param::SetLatitude) {
let latitude = (*msg)
.param
.get_float(Param::SetLatitude)
.unwrap_or_default();
let longitude = (*msg)
.param
.get_float(Param::SetLongitude)
.unwrap_or_default();
let kml_file =
dc_get_message_kml((*msg).timestamp_sort, latitude, longitude);
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_set_body_text(kml_mime_part, kml_file, strlen(kml_file));
mailmime_smart_add_part(message, kml_mime_part);
if 0 == dc_param_exists(
(*msg).param,
DC_PARAM_SET_LATITUDE as libc::c_int,
) {
if !(*msg).param.exists(Param::SetLatitude) {
// otherwise, the independent location is already filed
(*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);
let p1: *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));
} else {
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;
}
match current_block {
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_text2 as *mut libc::c_void);
free(subject_str as *mut libc::c_void);
free(grpimage as *mut libc::c_void);
success
}
unsafe fn get_subject(
chat: *const Chat,
msg: *const dc_msg_t,
msg: *mut dc_msg_t,
afwd_email: libc::c_int,
) -> *mut libc::c_char {
let context = (*chat).context;
let ret: *mut libc::c_char;
let raw_subject: *mut libc::c_char =
dc_msg_get_summarytext_by_raw((*msg).type_0, (*msg).text, (*msg).param, 32, context);
let fwd: *const libc::c_char = if 0 != afwd_email {
let raw_subject =
dc_msg_get_summarytext_by_raw((*msg).type_0, (*msg).text, &mut (*msg).param, 32, context);
let fwd = if 0 != afwd_email {
b"Fwd: \x00" as *const u8 as *const libc::c_char
} else {
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))
} 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
@@ -1194,16 +1163,21 @@ unsafe fn build_body_file(
let mime_fields: *mut mailmime_fields;
let mut mime_sub: *mut mailmime = 0 as *mut mailmime;
let content: *mut mailmime_content;
let pathNfilename: *mut libc::c_char =
dc_param_get((*msg).param, DC_PARAM_FILE as i32, 0 as *const libc::c_char);
let mut mimetype: *mut libc::c_char = dc_param_get(
(*msg).param,
DC_PARAM_MIMETYPE as i32,
0 as *const libc::c_char,
);
let suffix: *mut libc::c_char = dc_get_filesuffix_lc(pathNfilename);
let mut filename_to_send: *mut libc::c_char = 0 as *mut libc::c_char;
let mut filename_encoded: *mut libc::c_char = 0 as *mut libc::c_char;
let pathNfilename = (*msg)
.param
.get(Param::File)
.map(|s| to_cstring(s))
.unwrap_or_else(|| std::ptr::null_mut());
let mut mimetype = (*msg)
.param
.get(Param::MimeType)
.map(|s| to_cstring(s))
.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 (*msg).type_0 == DC_MSG_VOICE {
let ts = chrono::Utc.timestamp((*msg).timestamp_sort as i64, 0);
@@ -1355,14 +1329,14 @@ unsafe fn build_body_file(
******************************************************************************/
#[allow(non_snake_case)]
unsafe fn is_file_size_okay(msg: *const dc_msg_t) -> libc::c_int {
let mut file_size_okay: libc::c_int = 1;
let pathNfilename: *mut libc::c_char =
dc_param_get((*msg).param, DC_PARAM_FILE as i32, 0 as *const libc::c_char);
let bytes: uint64_t = dc_get_filebytes((*msg).context, pathNfilename);
if bytes > (49 * 1024 * 1024 / 4 * 3) as libc::c_ulonglong {
let mut file_size_okay = 1;
let pathNfilename = to_cstring((*msg).param.get(Param::File).unwrap_or_default());
let bytes = dc_get_filebytes((*msg).context, pathNfilename);
if bytes > (49 * 1024 * 1024 / 4 * 3) {
file_size_okay = 0;
}
free(pathNfilename as *mut libc::c_void);
free(pathNfilename as *mut _);
file_size_okay
}

View File

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

View File

@@ -2,6 +2,7 @@ use crate::constants::*;
use crate::context::*;
use crate::dc_job::*;
use crate::dc_msg::*;
use crate::param::Params;
pub unsafe fn dc_do_heuristics_moves(context: &Context, folder: &str, msg_id: u32) {
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
if 0 != (*msg).is_dc_message {
dc_job_add(
context,
200,
(*msg).id as libc::c_int,
0 as *const libc::c_char,
0,
);
dc_job_add(context, 200, (*msg).id as libc::c_int, Params::new(), 0);
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_lot::dc_lot_t;
use crate::dc_lot::*;
use crate::dc_param::*;
use crate::dc_tools::*;
use crate::param::*;
use crate::pgp::*;
use crate::sql;
use crate::stock::StockMessage;
@@ -16,7 +16,7 @@ use crate::types::*;
use crate::x::*;
/* * the structure behind dc_msg_t */
#[derive(Copy, Clone)]
#[derive(Clone)]
#[repr(C)]
pub struct dc_msg_t<'a> {
pub magic: uint32_t,
@@ -41,7 +41,7 @@ pub struct dc_msg_t<'a> {
pub starred: libc::c_int,
pub chat_blocked: libc::c_int,
pub location_id: uint32_t,
pub param: *mut dc_param_t,
pub param: Params,
}
// 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";
}
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 & 0x2 {
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 += "\n";
p = dc_param_get(
(*msg).param,
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);
match (*msg).param.get(Param::Error) {
Some(err) => ret += &format!("Error: {}", err),
_ => {}
}
p = dc_msg_get_file(msg);
if !p.is_null() && 0 != *p.offset(0isize) as libc::c_int {
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));
free(p as *mut libc::c_void);
}
let w = dc_param_get_int((*msg).param, DC_PARAM_WIDTH as i32, 0);
let h = dc_param_get_int((*msg).param, DC_PARAM_HEIGHT as i32, 0);
let w = (*msg).param.get_int(Param::Width).unwrap_or_default();
let h = (*msg).param.get_int(Param::Height).unwrap_or_default();
if w != 0 || h != 0 {
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 {
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_get_msg_info()
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;
msg = calloc(1, ::std::mem::size_of::<dc_msg_t>()) as *mut dc_msg_t;
assert!(!msg.is_null());
(*msg).context = context;
(*msg).magic = 0x11561156i32 as uint32_t;
(*msg).type_0 = viewtype;
(*msg).state = 0;
(*msg).param = dc_param_new();
let msg = dc_msg_t {
magic: 0x11561156,
id: 0,
from_id: 0,
to_id: 0,
chat_id: 0,
move_state: 0,
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) {
@@ -250,9 +271,8 @@ pub unsafe fn dc_msg_unref(mut msg: *mut dc_msg_t) {
return;
}
dc_msg_empty(msg);
dc_param_unref((*msg).param);
(*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) {
@@ -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;
free((*msg).server_folder as *mut libc::c_void);
(*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;
}
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 file: *mut libc::c_char = 0 as *mut libc::c_char;
let mut ret = 0 as *mut libc::c_char;
if !(msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint) {
ret = dc_param_get(
(*msg).param,
DC_PARAM_MIMETYPE as i32,
0 as *const libc::c_char,
);
if ret.is_null() {
file = dc_param_get((*msg).param, DC_PARAM_FILE as i32, 0 as *const libc::c_char);
if !file.is_null() {
dc_msg_guess_msgtype_from_suffix(file, 0 as *mut libc::c_int, &mut ret);
if ret.is_null() {
ret = dc_strdup(
b"application/octet-stream\x00" as *const u8 as *const libc::c_char,
)
match (*msg).param.get(Param::MimeType) {
Some(m) => {
ret = to_cstring(m);
}
None => {
if let Some(file) = (*msg).param.get(Param::File) {
let file_c = to_cstring(file);
dc_msg_guess_msgtype_from_suffix(file_c, 0 as *mut libc::c_int, &mut ret);
if ret.is_null() {
ret = dc_strdup(
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() {
ret
} else {
dc_strdup(0 as *const libc::c_char)
};
if !ret.is_null() {
return ret;
}
dc_strdup(0 as *const libc::c_char)
}
#[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 {
let mut file_rel: *mut libc::c_char = 0 as *mut libc::c_char;
let mut file_abs: *mut libc::c_char = 0 as *mut libc::c_char;
let mut file_abs = 0 as *mut libc::c_char;
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 !file_rel.is_null() {
file_abs = dc_get_abs_path((*msg).context, file_rel)
if let Some(file_rel) = (*msg).param.get(Param::File) {
let file_rel_c = to_cstring(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);
return if !file_abs.is_null() {
if !file_abs.is_null() {
file_abs
} else {
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.
*/
pub unsafe fn dc_msg_set_location(
msg: *const dc_msg_t,
msg: *mut dc_msg_t,
latitude: libc::c_double,
longitude: libc::c_double,
) {
@@ -418,12 +439,8 @@ pub unsafe fn dc_msg_set_location(
return;
}
dc_param_set_float((*msg).param, DC_PARAM_SET_LATITUDE as libc::c_int, latitude);
dc_param_set_float(
(*msg).param,
DC_PARAM_SET_LONGITUDE as libc::c_int,
longitude,
);
(*msg).param.set_float(Param::SetLatitude, latitude);
(*msg).param.set_float(Param::SetLongitude, longitude);
}
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).is_dc_message = row.get(14)?;
(*msg).text = to_cstring(row.get::<_, String>(15).unwrap_or_default());
dc_param_set_packed(
(*msg).param,
to_cstring(row.get::<_, String>(16)?)
);
(*msg).param = row.get::<_, String>(16)?.parse().unwrap_or_default();
(*msg).starred = row.get(17)?;
(*msg).hidden = row.get(18)?;
(*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_job_add(
context,
110i32,
110,
*msg_ids.offset(i as isize) as libc::c_int,
0 as *const libc::c_char,
0i32,
Params::new(),
0,
);
i += 1
}
if 0 != msg_cnt {
context.call_cb(Event::MSGS_CHANGED, 0i32 as uintptr_t, 0i32 as uintptr_t);
dc_job_kill_action(context, 105i32);
dc_job_add(context, 105i32, 0i32, 0 as *const libc::c_char, 10i32);
context.call_cb(Event::MSGS_CHANGED, 0 as uintptr_t, 0 as uintptr_t);
dc_job_kill_action(context, 105);
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);
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;
}
} 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)]
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 pathNfilename: *mut libc::c_char = 0 as *mut libc::c_char;
let mut ret = 0 as *mut libc::c_char;
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 !pathNfilename.is_null() {
ret = dc_get_filename(pathNfilename)
if let Some(file) = (*msg).param.get(Param::File) {
let file_c = to_cstring(file);
ret = dc_get_filename(file_c);
free(file_c as *mut _);
}
}
free(pathNfilename as *mut libc::c_void);
return if !ret.is_null() {
if !ret.is_null() {
ret
} else {
dc_strdup(0 as *const libc::c_char)
};
}
}
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 file: *mut libc::c_char = 0 as *mut libc::c_char;
let mut ret = 0;
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 !file.is_null() {
ret = dc_get_filebytes((*msg).context, file)
if let Some(file) = (*msg).param.get(Param::File) {
let file_c = to_cstring(file);
ret = dc_get_filebytes((*msg).context, file_c);
free(file_c as *mut _);
}
}
free(file as *mut libc::c_void);
ret
}
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 {
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
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 {
return 0i32;
if msg.is_null() || (*msg).magic != 0x11561156 as libc::c_uint {
return 0;
}
if dc_param_get_int((*msg).param, DC_PARAM_GUARANTEE_E2EE as i32, 0) != 0i32 {
return 1i32;
if (*msg)
.param
.get_int(Param::GuranteeE2ee)
.unwrap_or_default()
!= 0
{
return 1;
}
0
}
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 dc_lot_t {
let current_block: u64;
let ret: *mut dc_lot_t = dc_lot_new();
let mut contact: *mut dc_contact_t = 0 as *mut dc_contact_t;
let mut chat_to_delete: *mut Chat = 0 as *mut Chat;
if !(msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint) {
if !(msg.is_null() || (*msg).magic != 0x11561156 as libc::c_uint) {
if chat.is_null() {
chat_to_delete = dc_get_chat((*msg).context, (*msg).chat_id);
if chat_to_delete.is_null() {
@@ -800,8 +819,8 @@ pub unsafe fn dc_msg_get_summary<'a>(
match current_block {
15204159476013091401 => {}
_ => {
if (*msg).from_id != 1i32 as libc::c_uint
&& ((*chat).type_0 == 120i32 || (*chat).type_0 == 130i32)
if (*msg).from_id != 1 as libc::c_uint
&& ((*chat).type_0 == 120 || (*chat).type_0 == 130)
{
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(
msg: *const dc_msg_t,
msg: *mut dc_msg_t,
approx_characters: libc::c_int,
) -> *mut libc::c_char {
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(
(*msg).type_0,
(*msg).text,
(*msg).param,
&mut (*msg).param,
approx_characters,
(*msg).context,
)
@@ -837,7 +856,7 @@ pub unsafe fn dc_msg_get_summarytext(
pub unsafe fn dc_msg_get_summarytext_by_raw(
type_0: libc::c_int,
text: *const libc::c_char,
param: *mut dc_param_t,
param: &mut Params,
approx_characters: libc::c_int,
context: &Context,
) -> *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)),
41 => prefix = to_cstring(context.stock_str(StockMessage::VoiceMessage)),
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));
append_text = 0i32
} else {
pathNfilename = dc_param_get(
param,
DC_PARAM_FILE as i32,
b"ErrFilename\x00" as *const u8 as *const libc::c_char,
);
pathNfilename = to_cstring(param.get(Param::File).unwrap_or_else(|| "ErrFilename"));
value = dc_get_filename(pathNfilename);
let label = CString::new(
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));
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
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 {
return 0i32;
return 0;
}
return if 0 != dc_param_get_int((*msg).param, DC_PARAM_FORWARDED as i32, 0) {
1i32
if 0 != (*msg).param.get_int(Param::Forwarded).unwrap_or_default() {
1
} else {
0i32
};
0
}
}
// TODO should return bool /rtn
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 {
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
|| (*msg).to_id == 2i32 as libc::c_uint
|| 0 != cmd && cmd != 6i32
{
return 1i32;
return 1;
}
0
@@ -992,7 +1007,7 @@ pub unsafe fn dc_msg_is_setupmessage(msg: *const dc_msg_t) -> bool {
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 {
@@ -1061,23 +1076,27 @@ pub unsafe fn dc_msg_set_file(
if msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint {
return;
}
dc_param_set((*msg).param, DC_PARAM_FILE as i32, file);
dc_param_set((*msg).param, DC_PARAM_MIMETYPE as i32, filemime);
if !file.is_null() {
(*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) {
if msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint {
return;
}
dc_param_set_int((*msg).param, DC_PARAM_WIDTH as i32, width);
dc_param_set_int((*msg).param, DC_PARAM_HEIGHT as i32, height);
(*msg).param.set_int(Param::Width, width);
(*msg).param.set_int(Param::Height, height);
}
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 {
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(
@@ -1087,12 +1106,12 @@ pub unsafe fn dc_msg_latefiling_mediasize(
duration: libc::c_int,
) {
if !(msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint) {
if width > 0i32 && height > 0i32 {
dc_param_set_int((*msg).param, DC_PARAM_WIDTH as i32, width);
dc_param_set_int((*msg).param, DC_PARAM_HEIGHT as i32, height);
if width > 0 && height > 0 {
(*msg).param.set_int(Param::Width, width);
(*msg).param.set_int(Param::Height, height);
}
if duration > 0i32 {
dc_param_set_int((*msg).param, DC_PARAM_DURATION as i32, duration);
if duration > 0 {
(*msg).param.set_int(Param::Duration, duration);
}
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.sql,
"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()
}
@@ -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;
}
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),);
}
@@ -1205,7 +1224,7 @@ pub unsafe fn dc_set_msg_failed(context: &Context, msg_id: uint32_t, error: *con
context,
&context.sql,
"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()
{

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

View File

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

View File

@@ -1,7 +1,7 @@
use std::ffi::CString;
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::constants::*;
@@ -14,12 +14,12 @@ use crate::dc_e2ee::*;
use crate::dc_lot::*;
use crate::dc_mimeparser::*;
use crate::dc_msg::*;
use crate::dc_param::*;
use crate::dc_qr::*;
use crate::dc_strencode::*;
use crate::dc_token::*;
use crate::dc_tools::*;
use crate::key::*;
use crate::param::*;
use crate::peerstate::*;
use crate::stock::StockMessage;
use crate::types::*;
@@ -87,8 +87,8 @@ pub unsafe fn dc_get_securejoin_qr(
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_name_urlencoded = utf8_percent_encode(&self_name, 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, NON_ALPHANUMERIC).to_string();
qr = if 0 != 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,
step,
);
(*msg).hidden = 1i32;
dc_param_set_int((*msg).param, DC_PARAM_CMD as i32, 7);
dc_param_set((*msg).param, DC_PARAM_CMD_ARG as i32, step);
(*msg).hidden = 1;
(*msg).param.set_int(Param::Cmd, 7);
if step.is_null() {
(*msg).param.remove(Param::Arg);
} else {
(*msg).param.set(Param::Arg, as_str(step));
}
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() {
dc_param_set((*msg).param, DC_PARAM_CMD_ARG3 as i32, fingerprint);
(*msg).param.set(Param::Arg3, as_str(fingerprint));
}
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
|| 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 {
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_msg_unref(msg);

View File

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

View File

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