mirror of
https://github.com/chatmail/core.git
synced 2026-05-08 17:36:29 +03:00
most prep done
This commit is contained in:
287
src/dc_chat.rs
287
src/dc_chat.rs
@@ -119,14 +119,14 @@ pub fn dc_chat_load_from_db(chat: *mut Chat, chat_id: u32) -> bool {
|
|||||||
|
|
||||||
let context = unsafe { (*chat).context };
|
let context = unsafe { (*chat).context };
|
||||||
|
|
||||||
if let Some(mut stmt) = dc_sqlite3_prepare(
|
context
|
||||||
context,
|
.sql
|
||||||
&context.sql,
|
.query_row(
|
||||||
"SELECT c.id,c.type,c.name, c.grpid,c.param,c.archived, \
|
"SELECT c.id,c.type,c.name, c.grpid,c.param,c.archived, \
|
||||||
c.blocked, c.gossiped_timestamp, c.locations_send_until \
|
c.blocked, c.gossiped_timestamp, c.locations_send_until \
|
||||||
FROM chats c WHERE c.id=?;",
|
FROM chats c WHERE c.id=?;",
|
||||||
) {
|
params![chat_id as i32],
|
||||||
stmt.query_row(params![chat_id as i32], |row| {
|
|row| {
|
||||||
let c = unsafe { &mut *chat };
|
let c = unsafe { &mut *chat };
|
||||||
|
|
||||||
c.id = row.get(0)?;
|
c.id = row.get(0)?;
|
||||||
@@ -176,11 +176,9 @@ pub fn dc_chat_load_from_db(chat: *mut Chat, chat_id: u32) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
},
|
||||||
|
)
|
||||||
.is_ok()
|
.is_ok()
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn dc_create_chat_by_contact_id(context: &Context, contact_id: uint32_t) -> uint32_t {
|
pub unsafe fn dc_create_chat_by_contact_id(context: &Context, contact_id: uint32_t) -> uint32_t {
|
||||||
@@ -318,12 +316,8 @@ pub fn dc_lookup_real_nchat_by_contact_id(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(mut stmt) = dc_sqlite3_prepare(
|
context.sql.query_row(
|
||||||
context,
|
|
||||||
&context.sql,
|
|
||||||
"SELECT c.id, c.blocked FROM chats c INNER JOIN chats_contacts j ON c.id=j.chat_id WHERE c.type=100 AND c.id>9 AND j.contact_id=?;",
|
"SELECT c.id, c.blocked FROM chats c INNER JOIN chats_contacts j ON c.id=j.chat_id WHERE c.type=100 AND c.id>9 AND j.contact_id=?;",
|
||||||
) {
|
|
||||||
stmt.query_row(
|
|
||||||
params![contact_id as i32],
|
params![contact_id as i32],
|
||||||
|row| {
|
|row| {
|
||||||
unsafe { *ret_chat_id = row.get(0)? };
|
unsafe { *ret_chat_id = row.get(0)? };
|
||||||
@@ -331,7 +325,6 @@ pub fn dc_lookup_real_nchat_by_contact_id(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
).unwrap();
|
).unwrap();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn dc_get_chat_id_by_contact_id(context: &Context, contact_id: uint32_t) -> uint32_t {
|
pub unsafe fn dc_get_chat_id_by_contact_id(context: &Context, contact_id: uint32_t) -> uint32_t {
|
||||||
@@ -560,16 +553,13 @@ unsafe fn prepare_msg_raw(
|
|||||||
let mut can_encrypt: libc::c_int = 1;
|
let mut can_encrypt: libc::c_int = 1;
|
||||||
let mut all_mutual: libc::c_int = 1;
|
let mut all_mutual: libc::c_int = 1;
|
||||||
|
|
||||||
if let Some(mut stmt) = dc_sqlite3_prepare(
|
context.sql.query_row(
|
||||||
context,
|
|
||||||
&context.sql,
|
|
||||||
"SELECT ps.prefer_encrypted, c.addr \
|
"SELECT ps.prefer_encrypted, c.addr \
|
||||||
FROM chats_contacts cc \
|
FROM chats_contacts cc \
|
||||||
LEFT JOIN contacts c ON cc.contact_id=c.id \
|
LEFT JOIN contacts c ON cc.contact_id=c.id \
|
||||||
LEFT JOIN acpeerstates ps ON c.addr=ps.addr \
|
LEFT JOIN acpeerstates ps ON c.addr=ps.addr \
|
||||||
WHERE cc.chat_id=? AND cc.contact_id>9;",
|
WHERE cc.chat_id=? AND cc.contact_id>9;",
|
||||||
) {
|
params![(*chat).id], |row| {
|
||||||
stmt.query_row(params![(*chat).id], |row| {
|
|
||||||
let state: String = row.get(1)?;
|
let state: String = row.get(1)?;
|
||||||
|
|
||||||
if let Some(prefer_encrypted) = row.get::<_, Option<i32>>(0)? {
|
if let Some(prefer_encrypted) = row.get::<_, Option<i32>>(0)? {
|
||||||
@@ -593,9 +583,8 @@ unsafe fn prepare_msg_raw(
|
|||||||
all_mutual = 0;
|
all_mutual = 0;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
|
).unwrap();
|
||||||
|
|
||||||
if 0 != can_encrypt {
|
if 0 != can_encrypt {
|
||||||
if 0 != all_mutual {
|
if 0 != all_mutual {
|
||||||
@@ -765,33 +754,33 @@ unsafe fn get_parent_mime_headers(
|
|||||||
|| parent_in_reply_to.is_null()
|
|| parent_in_reply_to.is_null()
|
||||||
|| parent_references.is_null())
|
|| parent_references.is_null())
|
||||||
{
|
{
|
||||||
if let Some(mut stmt) = dc_sqlite3_prepare(
|
success = (*chat)
|
||||||
(*chat).context,
|
.context
|
||||||
&(*chat).context.sql,
|
.sql
|
||||||
|
.query_row(
|
||||||
"SELECT rfc724_mid, mime_in_reply_to, mime_references \
|
"SELECT rfc724_mid, mime_in_reply_to, mime_references \
|
||||||
FROM msgs WHERE timestamp=(SELECT max(timestamp) \
|
FROM msgs WHERE timestamp=(SELECT max(timestamp) \
|
||||||
FROM msgs WHERE chat_id=? AND from_id!=?);",
|
FROM msgs WHERE chat_id=? AND from_id!=?);",
|
||||||
) {
|
params![(*chat).id as i32, 1],
|
||||||
success = stmt
|
|row| {
|
||||||
.query_row(params![(*chat).id as i32, 1], |row| {
|
|
||||||
*parent_rfc724_mid = dc_strdup(to_cstring(row.get::<_, String>(0)?).as_ptr());
|
*parent_rfc724_mid = dc_strdup(to_cstring(row.get::<_, String>(0)?).as_ptr());
|
||||||
*parent_in_reply_to = dc_strdup(to_cstring(row.get::<_, String>(1)?).as_ptr());
|
*parent_in_reply_to = dc_strdup(to_cstring(row.get::<_, String>(1)?).as_ptr());
|
||||||
*parent_references = dc_strdup(to_cstring(row.get::<_, String>(2)?).as_ptr());
|
*parent_references = dc_strdup(to_cstring(row.get::<_, String>(2)?).as_ptr());
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
},
|
||||||
|
)
|
||||||
.is_ok() as libc::c_int;
|
.is_ok() as libc::c_int;
|
||||||
}
|
|
||||||
|
|
||||||
if 0 == success {
|
if 0 == success {
|
||||||
if let Some(mut stmt) = dc_sqlite3_prepare(
|
success = (*chat)
|
||||||
(*chat).context,
|
.context
|
||||||
&(*chat).context.sql,
|
.sql
|
||||||
|
.query_row(
|
||||||
"SELECT rfc724_mid, mime_in_reply_to, mime_references \
|
"SELECT rfc724_mid, mime_in_reply_to, mime_references \
|
||||||
FROM msgs WHERE timestamp=(SELECT min(timestamp) \
|
FROM msgs WHERE timestamp=(SELECT min(timestamp) \
|
||||||
FROM msgs WHERE chat_id=? AND from_id==?);",
|
FROM msgs WHERE chat_id=? AND from_id==?);",
|
||||||
) {
|
params![(*chat).id as i32, 1],
|
||||||
success = stmt
|
|row| {
|
||||||
.query_row(params![(*chat).id as i32, 1], |row| {
|
|
||||||
*parent_rfc724_mid =
|
*parent_rfc724_mid =
|
||||||
dc_strdup(to_cstring(row.get::<_, String>(0)?).as_ptr());
|
dc_strdup(to_cstring(row.get::<_, String>(0)?).as_ptr());
|
||||||
*parent_in_reply_to =
|
*parent_in_reply_to =
|
||||||
@@ -799,11 +788,11 @@ unsafe fn get_parent_mime_headers(
|
|||||||
*parent_references =
|
*parent_references =
|
||||||
dc_strdup(to_cstring(row.get::<_, String>(2)?).as_ptr());
|
dc_strdup(to_cstring(row.get::<_, String>(2)?).as_ptr());
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
},
|
||||||
|
)
|
||||||
.is_ok() as libc::c_int;
|
.is_ok() as libc::c_int;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
success
|
success
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1074,75 +1063,16 @@ pub unsafe fn dc_get_chat_msgs(
|
|||||||
flags: uint32_t,
|
flags: uint32_t,
|
||||||
marker1before: uint32_t,
|
marker1before: uint32_t,
|
||||||
) -> *mut dc_array_t {
|
) -> *mut dc_array_t {
|
||||||
//clock_t start = clock();
|
let ret = dc_array_new(512);
|
||||||
let mut success: libc::c_int = 0i32;
|
assert!(!ret.is_null());
|
||||||
let ret = dc_array_new(512i32 as size_t);
|
|
||||||
|
|
||||||
let mut last_day = 0;
|
let mut last_day = 0;
|
||||||
let cnv_to_local = dc_gm2local_offset();
|
let cnv_to_local = dc_gm2local_offset();
|
||||||
|
|
||||||
if ret.is_null() {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
let process_row = |row: &rusqlite::Row| Ok((row.get::<_, i32>(0)?, row.get::<_, i64>(1)?));
|
let process_row = |row: &rusqlite::Row| Ok((row.get::<_, i32>(0)?, row.get::<_, i64>(1)?));
|
||||||
|
let process_rows = |rows: rusqlite::MappedRows<_>| {
|
||||||
let rows = if chat_id == 1 {
|
for row in rows {
|
||||||
let show_emails = dc_sqlite3_get_config_int(context, &context.sql, "show_emails", 0);
|
let (curr_id, ts) = row?;
|
||||||
if let Some(mut stmt) = dc_sqlite3_prepare(
|
|
||||||
context,
|
|
||||||
&context.sql,
|
|
||||||
"SELECT m.id, m.timestamp FROM msgs m \
|
|
||||||
LEFT JOIN chats ON m.chat_id=chats.id \
|
|
||||||
LEFT JOIN contacts ON m.from_id=contacts.id WHERE m.from_id!=1 \
|
|
||||||
AND m.from_id!=2 \
|
|
||||||
AND m.hidden=0 \
|
|
||||||
AND chats.blocked=2 \
|
|
||||||
AND contacts.blocked=0 \
|
|
||||||
AND m.msgrmsg>=? \
|
|
||||||
ORDER BY m.timestamp,m.id;",
|
|
||||||
) {
|
|
||||||
stmt.query_map(params![if show_emails == 2 { 0 } else { 1 }], process_row)
|
|
||||||
.and_then(|res| res.collect::<rusqlite::Result<Vec<_>>>())
|
|
||||||
} else {
|
|
||||||
dc_array_unref(ret);
|
|
||||||
return std::ptr::null_mut();
|
|
||||||
}
|
|
||||||
} else if chat_id == 5 {
|
|
||||||
if let Some(mut stmt) = dc_sqlite3_prepare(
|
|
||||||
context,
|
|
||||||
&context.sql,
|
|
||||||
"SELECT m.id, m.timestamp FROM msgs m \
|
|
||||||
LEFT JOIN contacts ct ON m.from_id=ct.id WHERE m.starred=1 \
|
|
||||||
AND m.hidden=0 \
|
|
||||||
AND ct.blocked=0 \
|
|
||||||
ORDER BY m.timestamp,m.id;",
|
|
||||||
) {
|
|
||||||
stmt.query_map(params![], process_row)
|
|
||||||
.and_then(|res| res.collect::<rusqlite::Result<Vec<_>>>())
|
|
||||||
} else {
|
|
||||||
dc_array_unref(ret);
|
|
||||||
return std::ptr::null_mut();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if let Some(mut stmt) = dc_sqlite3_prepare(
|
|
||||||
context,
|
|
||||||
&context.sql,
|
|
||||||
"SELECT m.id, m.timestamp FROM msgs m \
|
|
||||||
WHERE m.chat_id=? \
|
|
||||||
AND m.hidden=0 \
|
|
||||||
ORDER BY m.timestamp,m.id;",
|
|
||||||
) {
|
|
||||||
stmt.query_map(params![chat_id as i32], process_row)
|
|
||||||
.and_then(|res| res.collect::<rusqlite::Result<Vec<_>>>())
|
|
||||||
} else {
|
|
||||||
dc_array_unref(ret);
|
|
||||||
return std::ptr::null_mut();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Ok(rows) = rows {
|
|
||||||
for (curr_id, ts) in rows {
|
|
||||||
if curr_id as u32 == marker1before {
|
if curr_id as u32 == marker1before {
|
||||||
dc_array_add_id(ret, 1);
|
dc_array_add_id(ret, 1);
|
||||||
}
|
}
|
||||||
@@ -1156,10 +1086,49 @@ pub unsafe fn dc_get_chat_msgs(
|
|||||||
}
|
}
|
||||||
dc_array_add_id(ret, curr_id as u32);
|
dc_array_add_id(ret, curr_id as u32);
|
||||||
}
|
}
|
||||||
success = 1;
|
Ok(())
|
||||||
}
|
};
|
||||||
|
|
||||||
if 0 != success {
|
let success = if chat_id == 1 {
|
||||||
|
let show_emails = dc_sqlite3_get_config_int(context, &context.sql, "show_emails", 0);
|
||||||
|
context.sql.query_map(
|
||||||
|
"SELECT m.id, m.timestamp FROM msgs m \
|
||||||
|
LEFT JOIN chats ON m.chat_id=chats.id \
|
||||||
|
LEFT JOIN contacts ON m.from_id=contacts.id WHERE m.from_id!=1 \
|
||||||
|
AND m.from_id!=2 \
|
||||||
|
AND m.hidden=0 \
|
||||||
|
AND chats.blocked=2 \
|
||||||
|
AND contacts.blocked=0 \
|
||||||
|
AND m.msgrmsg>=? \
|
||||||
|
ORDER BY m.timestamp,m.id;",
|
||||||
|
params![if show_emails == 2 { 0 } else { 1 }],
|
||||||
|
process_row,
|
||||||
|
process_rows,
|
||||||
|
)
|
||||||
|
} else if chat_id == 5 {
|
||||||
|
context.sql.query_map(
|
||||||
|
"SELECT m.id, m.timestamp FROM msgs m \
|
||||||
|
LEFT JOIN contacts ct ON m.from_id=ct.id WHERE m.starred=1 \
|
||||||
|
AND m.hidden=0 \
|
||||||
|
AND ct.blocked=0 \
|
||||||
|
ORDER BY m.timestamp,m.id;",
|
||||||
|
params![],
|
||||||
|
process_row,
|
||||||
|
process_rows,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
context.sql.query_map(
|
||||||
|
"SELECT m.id, m.timestamp FROM msgs m \
|
||||||
|
WHERE m.chat_id=? \
|
||||||
|
AND m.hidden=0 \
|
||||||
|
ORDER BY m.timestamp,m.id;",
|
||||||
|
params![chat_id as i32],
|
||||||
|
process_row,
|
||||||
|
process_rows,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
if success.is_ok() {
|
||||||
ret
|
ret
|
||||||
} else {
|
} else {
|
||||||
if !ret.is_null() {
|
if !ret.is_null() {
|
||||||
@@ -1249,14 +1218,8 @@ pub fn dc_get_chat_media(
|
|||||||
msg_type2: libc::c_int,
|
msg_type2: libc::c_int,
|
||||||
msg_type3: libc::c_int,
|
msg_type3: libc::c_int,
|
||||||
) -> *mut dc_array_t {
|
) -> *mut dc_array_t {
|
||||||
let ret = unsafe { dc_array_new(100) };
|
context.sql.query_map(
|
||||||
|
"SELECT id FROM msgs WHERE chat_id=? AND (type=? OR type=? OR type=?) ORDER BY timestamp, id;",
|
||||||
if let Some(mut stmt) = dc_sqlite3_prepare(
|
|
||||||
context,
|
|
||||||
&context.sql,
|
|
||||||
"SELECT id FROM msgs WHERE chat_id=? AND (type=? OR type=? OR type=?) ORDER BY timestamp, id;"
|
|
||||||
) {
|
|
||||||
let rows = stmt.query_map(
|
|
||||||
params![
|
params![
|
||||||
chat_id as i32,
|
chat_id as i32,
|
||||||
msg_type,
|
msg_type,
|
||||||
@@ -1270,21 +1233,15 @@ pub fn dc_get_chat_media(
|
|||||||
msg_type
|
msg_type
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|row| row.get::<_, i32>(0)
|
|row| row.get::<_, i32>(0),
|
||||||
);
|
|ids| {
|
||||||
|
let ret = unsafe { dc_array_new(100) };
|
||||||
if let Ok(ids) = rows {
|
|
||||||
for id in ids {
|
for id in ids {
|
||||||
if let Ok(id) = id {
|
unsafe { dc_array_add_id(ret, id? as u32) };
|
||||||
unsafe { dc_array_add_id(ret, id as u32) };
|
|
||||||
}
|
}
|
||||||
|
Ok(ret)
|
||||||
}
|
}
|
||||||
return ret;
|
).unwrap_or_else(|_| std::ptr::null_mut())
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe { dc_array_unref(ret) };
|
|
||||||
std::ptr::null_mut()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn dc_get_next_media(
|
pub unsafe fn dc_get_next_media(
|
||||||
@@ -1425,31 +1382,28 @@ pub fn dc_get_chat_contacts(context: &Context, chat_id: u32) -> *mut dc_array_t
|
|||||||
return std::ptr::null_mut();
|
return std::ptr::null_mut();
|
||||||
}
|
}
|
||||||
|
|
||||||
let ret = unsafe { dc_array_new(100) };
|
|
||||||
// we could also create a list for all contacts in the deaddrop by searching contacts belonging to chats with
|
// we could also create a list for all contacts in the deaddrop by searching contacts belonging to chats with
|
||||||
// chats.blocked=2, however, currently this is not needed
|
// chats.blocked=2, however, currently this is not needed
|
||||||
|
|
||||||
if let Some(mut stmt) = dc_sqlite3_prepare(
|
context
|
||||||
context,
|
.sql
|
||||||
&context.sql,
|
.query_map(
|
||||||
"SELECT cc.contact_id FROM chats_contacts cc \
|
"SELECT cc.contact_id FROM chats_contacts cc \
|
||||||
LEFT JOIN contacts c ON c.id=cc.contact_id WHERE cc.chat_id=? \
|
LEFT JOIN contacts c ON c.id=cc.contact_id WHERE cc.chat_id=? \
|
||||||
ORDER BY c.id=1, LOWER(c.name||c.addr), c.id;",
|
ORDER BY c.id=1, LOWER(c.name||c.addr), c.id;",
|
||||||
) {
|
params![chat_id as i32],
|
||||||
let rows = stmt.query_map(params![chat_id as i32], |row| row.get::<_, i32>(0));
|
|row| row.get::<_, i32>(0),
|
||||||
if let Ok(ids) = rows {
|
|ids| {
|
||||||
|
let ret = unsafe { dc_array_new(100) };
|
||||||
|
|
||||||
for id in ids {
|
for id in ids {
|
||||||
if let Ok(id) = id {
|
unsafe { dc_array_add_id(ret, id? as u32) };
|
||||||
unsafe { dc_array_add_id(ret, id as u32) };
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
Ok(ret)
|
||||||
}
|
},
|
||||||
}
|
)
|
||||||
|
.unwrap_or_else(|_| std::ptr::null_mut())
|
||||||
unsafe { dc_array_unref(ret) }
|
|
||||||
std::ptr::null_mut()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn dc_get_chat(context: &Context, chat_id: uint32_t) -> *mut Chat {
|
pub unsafe fn dc_get_chat(context: &Context, chat_id: uint32_t) -> *mut Chat {
|
||||||
@@ -1962,9 +1916,9 @@ pub unsafe fn dc_forward_msgs(
|
|||||||
|
|
||||||
let msg = dc_msg_new_untyped(context);
|
let msg = dc_msg_new_untyped(context);
|
||||||
let chat = dc_chat_new(context);
|
let chat = dc_chat_new(context);
|
||||||
let contact: *mut dc_contact_t = dc_contact_new(context);
|
let contact = dc_contact_new(context);
|
||||||
let created_db_entries: *mut carray = carray_new(16i32 as libc::c_uint);
|
let created_db_entries = carray_new(16);
|
||||||
let mut idsstr: *mut libc::c_char = 0 as *mut libc::c_char;
|
let mut idsstr = 0 as *mut libc::c_char;
|
||||||
let mut curr_timestamp: i64;
|
let mut curr_timestamp: i64;
|
||||||
|
|
||||||
let original_param: *mut dc_param_t = dc_param_new();
|
let original_param: *mut dc_param_t = dc_param_new();
|
||||||
@@ -1973,16 +1927,15 @@ pub unsafe fn dc_forward_msgs(
|
|||||||
curr_timestamp = dc_create_smeared_timestamps(context, msg_cnt);
|
curr_timestamp = dc_create_smeared_timestamps(context, msg_cnt);
|
||||||
idsstr = dc_arr_to_string(msg_ids, msg_cnt);
|
idsstr = dc_arr_to_string(msg_ids, msg_cnt);
|
||||||
|
|
||||||
if let Some(mut stmt) = dc_sqlite3_prepare(
|
context
|
||||||
context,
|
.sql
|
||||||
&context.sql,
|
.query_map(
|
||||||
"SELECT id FROM msgs WHERE id IN(?) ORDER BY timestamp,id",
|
"SELECT id FROM msgs WHERE id IN(?) ORDER BY timestamp,id",
|
||||||
) {
|
params![as_str(idsstr)],
|
||||||
let rows = stmt.query_map(params![as_str(idsstr)], |row| row.get::<_, i32>(0));
|
|row| row.get::<_, i32>(0),
|
||||||
|
|ids| {
|
||||||
if let Ok(ids) = rows {
|
|
||||||
for id in ids {
|
for id in ids {
|
||||||
if let Ok(src_msg_id) = id {
|
let src_msg_id = id?;
|
||||||
if !dc_msg_load_from_db(msg, context, src_msg_id as u32) {
|
if !dc_msg_load_from_db(msg, context, src_msg_id as u32) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2034,9 +1987,10 @@ pub unsafe fn dc_forward_msgs(
|
|||||||
0 as *mut libc::c_uint,
|
0 as *mut libc::c_uint,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
Ok(())
|
||||||
}
|
},
|
||||||
}
|
)
|
||||||
|
.unwrap(); // TODO: better error handling
|
||||||
}
|
}
|
||||||
|
|
||||||
if !created_db_entries.is_null() {
|
if !created_db_entries.is_null() {
|
||||||
@@ -2241,13 +2195,12 @@ pub unsafe fn dc_get_chat_id_by_grpid(
|
|||||||
*ret_verified = 0;
|
*ret_verified = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
dc_sqlite3_prepare(
|
context
|
||||||
context,
|
.sql
|
||||||
&context.sql,
|
.query_row(
|
||||||
"SELECT id, blocked, type FROM chats WHERE grpid=?;",
|
"SELECT id, blocked, type FROM chats WHERE grpid=?;",
|
||||||
)
|
params![as_str(grpid)],
|
||||||
.and_then(|mut stmt| {
|
|row| {
|
||||||
stmt.query_row(params![as_str(grpid)], |row| {
|
|
||||||
let chat_id = row.get(0)?;
|
let chat_id = row.get(0)?;
|
||||||
if !ret_blocked.is_null() {
|
if !ret_blocked.is_null() {
|
||||||
*ret_blocked = row.get(1)?;
|
*ret_blocked = row.get(1)?;
|
||||||
@@ -2257,9 +2210,8 @@ pub unsafe fn dc_get_chat_id_by_grpid(
|
|||||||
*ret_verified = (v == 130) as libc::c_int;
|
*ret_verified = (v == 130) as libc::c_int;
|
||||||
}
|
}
|
||||||
Ok(chat_id)
|
Ok(chat_id)
|
||||||
})
|
},
|
||||||
.ok()
|
)
|
||||||
})
|
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2274,9 +2226,7 @@ pub fn dc_add_device_msg(context: &Context, chat_id: uint32_t, text: *const libc
|
|||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
if !dc_sqlite3_execute(
|
if context.sql.execute(
|
||||||
context,
|
|
||||||
&context.sql,
|
|
||||||
"INSERT INTO msgs (chat_id,from_id,to_id, timestamp,type,state, txt,rfc724_mid) VALUES (?,?,?, ?,?,?, ?,?);",
|
"INSERT INTO msgs (chat_id,from_id,to_id, timestamp,type,state, txt,rfc724_mid) VALUES (?,?,?, ?,?,?, ?,?);",
|
||||||
params![
|
params![
|
||||||
chat_id as i32,
|
chat_id as i32,
|
||||||
@@ -2288,7 +2238,8 @@ pub fn dc_add_device_msg(context: &Context, chat_id: uint32_t, text: *const libc
|
|||||||
as_str(text),
|
as_str(text),
|
||||||
as_str(rfc724_mid),
|
as_str(rfc724_mid),
|
||||||
]
|
]
|
||||||
) {
|
).is_err() {
|
||||||
|
unsafe { free(rfc724_mid as *mut libc::c_void) };
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -604,27 +604,23 @@ pub fn dc_get_blocked_cnt(context: &Context) -> libc::c_int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn dc_get_blocked_contacts(context: &Context) -> *mut dc_array_t {
|
pub fn dc_get_blocked_contacts(context: &Context) -> *mut dc_array_t {
|
||||||
|
context
|
||||||
|
.sql
|
||||||
|
.query_map(
|
||||||
|
"SELECT id FROM contacts WHERE id>? AND blocked!=0 ORDER BY LOWER(name||addr),id;",
|
||||||
|
params![9],
|
||||||
|
|row| row.get::<_, i32>(0),
|
||||||
|
|ids| {
|
||||||
let ret = unsafe { dc_array_new(100) };
|
let ret = unsafe { dc_array_new(100) };
|
||||||
|
|
||||||
if let Some(mut stmt) = dc_sqlite3_prepare(
|
|
||||||
context,
|
|
||||||
&context.sql,
|
|
||||||
"SELECT id FROM contacts WHERE id>? AND blocked!=0 ORDER BY LOWER(name||addr),id;",
|
|
||||||
) {
|
|
||||||
let rows = stmt.query_map(params![9], |row| row.get::<_, i32>(0));
|
|
||||||
if let Ok(ids) = rows {
|
|
||||||
for id in ids {
|
for id in ids {
|
||||||
if let Ok(id) = id {
|
unsafe { dc_array_add_id(ret, id? as u32) };
|
||||||
unsafe { dc_array_add_id(ret, id as u32) };
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
Ok(ret)
|
||||||
}
|
},
|
||||||
}
|
)
|
||||||
|
.unwrap_or_else(|_| std::ptr::null_mut())
|
||||||
unsafe { dc_array_unref(ret) };
|
|
||||||
std::ptr::null_mut()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn dc_get_contact_encrinfo(
|
pub unsafe fn dc_get_contact_encrinfo(
|
||||||
@@ -1057,18 +1053,23 @@ pub fn dc_real_contact_exists(context: &Context, contact_id: u32) -> bool {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
dc_sqlite3_prepare(context, &context.sql, "SELECT id FROM contacts WHERE id=?;")
|
context
|
||||||
.map(|mut stmt| stmt.exists(params![contact_id as i32]).unwrap_or_default())
|
.sql
|
||||||
|
.exists(
|
||||||
|
"SELECT id FROM contacts WHERE id=?;",
|
||||||
|
params![contact_id as i32],
|
||||||
|
)
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dc_scaleup_contact_origin(context: &Context, contact_id: u32, origin: libc::c_int) -> bool {
|
pub fn dc_scaleup_contact_origin(context: &Context, contact_id: u32, origin: libc::c_int) -> bool {
|
||||||
dc_sqlite3_execute(
|
context
|
||||||
context,
|
.sql
|
||||||
&context.sql,
|
.execute(
|
||||||
"UPDATE contacts SET origin=? WHERE id=? AND origin<?;",
|
"UPDATE contacts SET origin=? WHERE id=? AND origin<?;",
|
||||||
params![origin, contact_id as i32, origin],
|
params![origin, contact_id as i32, origin],
|
||||||
)
|
)
|
||||||
|
.is_ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ use crate::context::Context;
|
|||||||
use crate::dc_configure::*;
|
use crate::dc_configure::*;
|
||||||
use crate::dc_sqlite3::*;
|
use crate::dc_sqlite3::*;
|
||||||
use crate::imap::Imap;
|
use crate::imap::Imap;
|
||||||
use crate::types::*;
|
|
||||||
use crate::x::*;
|
use crate::x::*;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
|||||||
@@ -118,19 +118,12 @@ unsafe fn schedule_MAYBE_SEND_LOCATIONS(context: &Context, flags: libc::c_int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn dc_is_sending_locations_to_chat(context: &Context, chat_id: u32) -> bool {
|
pub fn dc_is_sending_locations_to_chat(context: &Context, chat_id: u32) -> bool {
|
||||||
dc_sqlite3_prepare(
|
context
|
||||||
context,
|
.sql
|
||||||
&context.sql,
|
.exists(
|
||||||
"SELECT id FROM chats WHERE (? OR id=?) AND locations_send_until>?;",
|
"SELECT id FROM chats WHERE (? OR id=?) AND locations_send_until>?;",
|
||||||
|
params![if chat_id == 0 { 1 } else { 0 }, chat_id as i32, time()],
|
||||||
)
|
)
|
||||||
.and_then(|mut stmt| {
|
|
||||||
stmt.exists(params![
|
|
||||||
if chat_id == 0 { 1 } else { 0 },
|
|
||||||
chat_id as i32,
|
|
||||||
time()
|
|
||||||
])
|
|
||||||
.ok()
|
|
||||||
})
|
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,25 +137,17 @@ pub fn dc_set_location(
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut continue_streaming = false;
|
context.sql.query_map(
|
||||||
let rows = if let Some(mut stmt) = dc_sqlite3_prepare(
|
|
||||||
context,
|
|
||||||
&context.sql,
|
|
||||||
"SELECT id FROM chats WHERE locations_send_until>?;",
|
"SELECT id FROM chats WHERE locations_send_until>?;",
|
||||||
) {
|
params![time()], |row| row.get::<_, i32>(0),
|
||||||
stmt.query_map(params![time()], |row| row.get::<_, i32>(0))
|
|chats| {
|
||||||
.and_then(|res| res.collect::<rusqlite::Result<Vec<_>>>())
|
let mut continue_streaming = false;
|
||||||
.ok()
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(chats) = rows {
|
for chat in chats {
|
||||||
for chat_id in chats {
|
let chat_id = chat?;
|
||||||
dc_sqlite3_execute(
|
context.sql.execute(
|
||||||
context,
|
"INSERT INTO locations \
|
||||||
&context.sql,
|
(latitude, longitude, accuracy, timestamp, chat_id, from_id) VALUES (?,?,?,?,?,?);",
|
||||||
"INSERT INTO locations (latitude, longitude, accuracy, timestamp, chat_id, from_id) VALUES (?,?,?,?,?,?);",
|
|
||||||
params![
|
params![
|
||||||
latitude,
|
latitude,
|
||||||
longitude,
|
longitude,
|
||||||
@@ -171,16 +156,16 @@ pub fn dc_set_location(
|
|||||||
chat_id,
|
chat_id,
|
||||||
1,
|
1,
|
||||||
]
|
]
|
||||||
);
|
)?;
|
||||||
continue_streaming = true;
|
continue_streaming = true;
|
||||||
}
|
}
|
||||||
if continue_streaming {
|
if continue_streaming {
|
||||||
context.call_cb(Event::LOCATION_CHANGED, 1, 0);
|
context.call_cb(Event::LOCATION_CHANGED, 1, 0);
|
||||||
};
|
};
|
||||||
unsafe { schedule_MAYBE_SEND_LOCATIONS(context, 0) };
|
unsafe { schedule_MAYBE_SEND_LOCATIONS(context, 0) };
|
||||||
|
Ok(continue_streaming as libc::c_int)
|
||||||
}
|
}
|
||||||
|
).unwrap_or_default()
|
||||||
continue_streaming as libc::c_int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dc_get_locations(
|
pub fn dc_get_locations(
|
||||||
@@ -194,19 +179,15 @@ pub fn dc_get_locations(
|
|||||||
timestamp_to = time() + 10;
|
timestamp_to = time() + 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
let ret = unsafe { dc_array_new_typed(1, 500) };
|
context
|
||||||
|
.sql
|
||||||
let locations = if let Some(mut stmt) = dc_sqlite3_prepare(
|
.query_map(
|
||||||
context,
|
|
||||||
&context.sql,
|
|
||||||
"SELECT l.id, l.latitude, l.longitude, l.accuracy, l.timestamp, l.independent, \
|
"SELECT l.id, l.latitude, l.longitude, l.accuracy, l.timestamp, l.independent, \
|
||||||
m.id, l.from_id, l.chat_id, m.txt \
|
m.id, l.from_id, l.chat_id, m.txt \
|
||||||
FROM locations l LEFT JOIN msgs m ON l.id=m.location_id WHERE (? OR l.chat_id=?) \
|
FROM locations l LEFT JOIN msgs m ON l.id=m.location_id WHERE (? OR l.chat_id=?) \
|
||||||
AND (? OR l.from_id=?) \
|
AND (? OR l.from_id=?) \
|
||||||
AND (l.independent=1 OR (l.timestamp>=? AND l.timestamp<=?)) \
|
AND (l.independent=1 OR (l.timestamp>=? AND l.timestamp<=?)) \
|
||||||
ORDER BY l.timestamp DESC, l.id DESC, m.id DESC;",
|
ORDER BY l.timestamp DESC, l.id DESC, m.id DESC;",
|
||||||
) {
|
|
||||||
stmt.query_map(
|
|
||||||
params![
|
params![
|
||||||
if chat_id == 0 { 1 } else { 0 },
|
if chat_id == 0 { 1 } else { 0 },
|
||||||
chat_id as i32,
|
chat_id as i32,
|
||||||
@@ -239,22 +220,16 @@ pub fn dc_get_locations(
|
|||||||
}
|
}
|
||||||
Ok(loc)
|
Ok(loc)
|
||||||
},
|
},
|
||||||
)
|
|locations| {
|
||||||
.and_then(|res| res.collect::<rusqlite::Result<Vec<_>>>())
|
let ret = unsafe { dc_array_new_typed(1, 500) };
|
||||||
.ok()
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(locations) = locations {
|
|
||||||
for location in locations {
|
for location in locations {
|
||||||
unsafe { dc_array_add_ptr(ret, location as *mut libc::c_void) };
|
unsafe { dc_array_add_ptr(ret, location? as *mut libc::c_void) };
|
||||||
}
|
|
||||||
ret
|
|
||||||
} else {
|
|
||||||
unsafe { dc_array_unref(ret) }
|
|
||||||
std::ptr::null_mut()
|
|
||||||
}
|
}
|
||||||
|
Ok(ret)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.unwrap_or_else(|_| std::ptr::null_mut())
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO should be bool /rtn
|
// TODO should be bool /rtn
|
||||||
@@ -295,29 +270,23 @@ pub fn dc_get_location_kml(
|
|||||||
|
|
||||||
let self_addr = self_addr.unwrap();
|
let self_addr = self_addr.unwrap();
|
||||||
|
|
||||||
if let Some((locations_send_begin, locations_send_until, locations_last_sent)) = dc_sqlite3_prepare(
|
if let Ok((locations_send_begin, locations_send_until, locations_last_sent)) = context.sql.query_row(
|
||||||
context,
|
|
||||||
&context.sql,
|
|
||||||
"SELECT locations_send_begin, locations_send_until, locations_last_sent FROM chats WHERE id=?;",
|
"SELECT locations_send_begin, locations_send_until, locations_last_sent FROM chats WHERE id=?;",
|
||||||
|
params![chat_id as i32], |row| {
|
||||||
).and_then(|mut stmt| {
|
|
||||||
stmt.query_row(params![chat_id as i32], |row| {
|
|
||||||
let send_begin: i64 = row.get(0)?;
|
let send_begin: i64 = row.get(0)?;
|
||||||
let send_until: i64 = row.get(1)?;
|
let send_until: i64 = row.get(1)?;
|
||||||
let last_sent: i64 = row.get(2)?;
|
let last_sent: i64 = row.get(2)?;
|
||||||
|
|
||||||
Ok((send_begin, send_until, last_sent))
|
Ok((send_begin, send_until, last_sent))
|
||||||
}).ok()
|
}
|
||||||
}) {
|
) {
|
||||||
if !(locations_send_begin == 0 || now > locations_send_until) {
|
if !(locations_send_begin == 0 || now > locations_send_until) {
|
||||||
ret += &format!(
|
ret += &format!(
|
||||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<kml xmlns=\"http://www.opengis.net/kml/2.2\">\n<Document addr=\"{}\">\n",
|
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<kml xmlns=\"http://www.opengis.net/kml/2.2\">\n<Document addr=\"{}\">\n",
|
||||||
self_addr,
|
self_addr,
|
||||||
);
|
);
|
||||||
|
|
||||||
let rows = if let Some(mut stmt) = dc_sqlite3_prepare(
|
context.sql.query_map(
|
||||||
context,
|
|
||||||
&context.sql,
|
|
||||||
"SELECT id, latitude, longitude, accuracy, timestamp\
|
"SELECT id, latitude, longitude, accuracy, timestamp\
|
||||||
FROM locations WHERE from_id=? \
|
FROM locations WHERE from_id=? \
|
||||||
AND timestamp>=? \
|
AND timestamp>=? \
|
||||||
@@ -325,8 +294,6 @@ pub fn dc_get_location_kml(
|
|||||||
AND independent=0 \
|
AND independent=0 \
|
||||||
GROUP BY timestamp \
|
GROUP BY timestamp \
|
||||||
ORDER BY timestamp;",
|
ORDER BY timestamp;",
|
||||||
){
|
|
||||||
stmt.query_map(
|
|
||||||
params![1, locations_send_begin, locations_last_sent, 1],
|
params![1, locations_send_begin, locations_last_sent, 1],
|
||||||
|row| {
|
|row| {
|
||||||
let location_id: i32 = row.get(0)?;
|
let location_id: i32 = row.get(0)?;
|
||||||
@@ -336,13 +303,10 @@ pub fn dc_get_location_kml(
|
|||||||
let timestamp = unsafe { get_kml_timestamp(row.get(4)?) };
|
let timestamp = unsafe { get_kml_timestamp(row.get(4)?) };
|
||||||
|
|
||||||
Ok((location_id, latitude, longitude, accuracy, timestamp))
|
Ok((location_id, latitude, longitude, accuracy, timestamp))
|
||||||
}).and_then(|res| res.collect::<rusqlite::Result<Vec<_>>>()).ok()
|
},
|
||||||
} else {
|
|rows| {
|
||||||
None
|
for row in rows {
|
||||||
};
|
let (location_id, latitude, longitude, accuracy, timestamp) = row?;
|
||||||
|
|
||||||
if let Some(rows) = rows {
|
|
||||||
for (location_id, latitude, longitude, accuracy, timestamp) in rows {
|
|
||||||
ret += &format!(
|
ret += &format!(
|
||||||
"<Placemark><Timestamp><when>{}</when></Timestamp><Point><coordinates accuracy=\"{}\">{},{}</coordinates></Point></Placemark>\n\x00",
|
"<Placemark><Timestamp><when>{}</when></Timestamp><Point><coordinates accuracy=\"{}\">{},{}</coordinates></Point></Placemark>\n\x00",
|
||||||
as_str(timestamp),
|
as_str(timestamp),
|
||||||
@@ -356,7 +320,9 @@ pub fn dc_get_location_kml(
|
|||||||
}
|
}
|
||||||
unsafe { free(timestamp as *mut libc::c_void) };
|
unsafe { free(timestamp as *mut libc::c_void) };
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
).unwrap(); // TODO: better error handling
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -690,14 +656,14 @@ pub unsafe fn dc_job_do_DC_JOB_MAYBE_SEND_LOCATIONS(context: &Context, _job: *mu
|
|||||||
as *const libc::c_char,
|
as *const libc::c_char,
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(mut stmt) = dc_sqlite3_prepare(
|
context
|
||||||
context,
|
.sql
|
||||||
&context.sql,
|
.query_map(
|
||||||
"SELECT id, locations_send_begin, locations_last_sent \
|
"SELECT id, locations_send_begin, locations_last_sent \
|
||||||
FROM chats \
|
FROM chats \
|
||||||
WHERE locations_send_until>?;",
|
WHERE locations_send_until>?;",
|
||||||
) {
|
params![now],
|
||||||
if let Ok(rows) = stmt.query_map(params![now], |row| {
|
|row| {
|
||||||
let chat_id: i32 = row.get(0)?;
|
let chat_id: i32 = row.get(0)?;
|
||||||
let locations_send_begin: i64 = row.get(1)?;
|
let locations_send_begin: i64 = row.get(1)?;
|
||||||
let locations_last_sent: i64 = row.get(2)?;
|
let locations_last_sent: i64 = row.get(2)?;
|
||||||
@@ -709,7 +675,8 @@ pub unsafe fn dc_job_do_DC_JOB_MAYBE_SEND_LOCATIONS(context: &Context, _job: *mu
|
|||||||
} else {
|
} else {
|
||||||
Ok(Some((chat_id, locations_send_begin, locations_last_sent)))
|
Ok(Some((chat_id, locations_send_begin, locations_last_sent)))
|
||||||
}
|
}
|
||||||
}) {
|
},
|
||||||
|
|rows| {
|
||||||
let stmt_locations = dc_sqlite3_prepare(
|
let stmt_locations = dc_sqlite3_prepare(
|
||||||
context,
|
context,
|
||||||
&context.sql,
|
&context.sql,
|
||||||
@@ -723,15 +690,16 @@ pub unsafe fn dc_job_do_DC_JOB_MAYBE_SEND_LOCATIONS(context: &Context, _job: *mu
|
|||||||
);
|
);
|
||||||
if stmt_locations.is_none() {
|
if stmt_locations.is_none() {
|
||||||
// TODO: handle error
|
// TODO: handle error
|
||||||
return;
|
return Ok(());
|
||||||
}
|
}
|
||||||
let mut stmt_locations = stmt_locations.unwrap();
|
let mut stmt_locations = stmt_locations.unwrap();
|
||||||
|
|
||||||
for (chat_id, locations_send_begin, locations_last_sent) in rows.filter_map(|r| match r
|
for (chat_id, locations_send_begin, locations_last_sent) in
|
||||||
{
|
rows.filter_map(|r| match r {
|
||||||
Ok(Some(v)) => Some(v),
|
Ok(Some(v)) => Some(v),
|
||||||
_ => None,
|
_ => None,
|
||||||
}) {
|
})
|
||||||
|
{
|
||||||
// TODO: do I need to reset?
|
// TODO: do I need to reset?
|
||||||
if !stmt_locations
|
if !stmt_locations
|
||||||
.exists(params![1, locations_send_begin, locations_last_sent,])
|
.exists(params![1, locations_send_begin, locations_last_sent,])
|
||||||
@@ -756,8 +724,10 @@ pub unsafe fn dc_job_do_DC_JOB_MAYBE_SEND_LOCATIONS(context: &Context, _job: *mu
|
|||||||
dc_send_msg(context, chat_id as u32, msg);
|
dc_send_msg(context, chat_id as u32, msg);
|
||||||
dc_msg_unref(msg);
|
dc_msg_unref(msg);
|
||||||
}
|
}
|
||||||
}
|
Ok(())
|
||||||
}
|
},
|
||||||
|
)
|
||||||
|
.unwrap(); // TODO: Better error handling
|
||||||
|
|
||||||
if 0 != continue_streaming {
|
if 0 != continue_streaming {
|
||||||
schedule_MAYBE_SEND_LOCATIONS(context, 0x1);
|
schedule_MAYBE_SEND_LOCATIONS(context, 0x1);
|
||||||
@@ -772,29 +742,21 @@ pub unsafe fn dc_job_do_DC_JOB_MAYBE_SEND_LOC_ENDED(context: &Context, job: &mut
|
|||||||
let chat_id = (*job).foreign_id;
|
let chat_id = (*job).foreign_id;
|
||||||
let mut stock_str = 0 as *mut libc::c_char;
|
let mut stock_str = 0 as *mut libc::c_char;
|
||||||
|
|
||||||
if let Some((send_begin, send_until)) = dc_sqlite3_prepare(
|
if let Ok((send_begin, send_until)) = context.sql.query_row(
|
||||||
context,
|
|
||||||
&context.sql,
|
|
||||||
"SELECT locations_send_begin, locations_send_until FROM chats WHERE id=?",
|
"SELECT locations_send_begin, locations_send_until FROM chats WHERE id=?",
|
||||||
)
|
params![chat_id as i32],
|
||||||
.and_then(|mut stmt| {
|
|row| Ok((row.get::<_, i64>(0)?, row.get::<_, i64>(1)?)),
|
||||||
stmt.query_row(params![chat_id as i32], |row| {
|
) {
|
||||||
Ok((row.get::<_, i64>(0)?, row.get::<_, i64>(1)?))
|
|
||||||
})
|
|
||||||
.ok()
|
|
||||||
}) {
|
|
||||||
if !(send_begin != 0 && time() <= send_until) {
|
if !(send_begin != 0 && time() <= send_until) {
|
||||||
// still streaming -
|
// still streaming -
|
||||||
// may happen as several calls to dc_send_locations_to_chat()
|
// may happen as several calls to dc_send_locations_to_chat()
|
||||||
// do not un-schedule pending DC_MAYBE_SEND_LOC_ENDED jobs
|
// do not un-schedule pending DC_MAYBE_SEND_LOC_ENDED jobs
|
||||||
if !(send_begin == 0 && send_until == 0) {
|
if !(send_begin == 0 && send_until == 0) {
|
||||||
// not streaming, device-message already sent
|
// not streaming, device-message already sent
|
||||||
if dc_sqlite3_execute(
|
if context.sql.execute(
|
||||||
context,
|
|
||||||
&context.sql,
|
|
||||||
"UPDATE chats SET locations_send_begin=0, locations_send_until=0 WHERE id=?",
|
"UPDATE chats SET locations_send_begin=0, locations_send_until=0 WHERE id=?",
|
||||||
params![chat_id as i32],
|
params![chat_id as i32],
|
||||||
) {
|
).is_ok() {
|
||||||
stock_str = dc_stock_system_msg(
|
stock_str = dc_stock_system_msg(
|
||||||
context,
|
context,
|
||||||
65,
|
65,
|
||||||
|
|||||||
@@ -1492,16 +1492,16 @@ unsafe fn create_or_lookup_adhoc_group(
|
|||||||
chat_ids = search_chat_ids_by_contact_ids(context, member_ids);
|
chat_ids = search_chat_ids_by_contact_ids(context, member_ids);
|
||||||
if dc_array_get_cnt(chat_ids) > 0 {
|
if dc_array_get_cnt(chat_ids) > 0 {
|
||||||
chat_ids_str = dc_array_get_string(chat_ids, b",\x00" as *const u8 as *const _);
|
chat_ids_str = dc_array_get_string(chat_ids, b",\x00" as *const u8 as *const _);
|
||||||
let res = dc_sqlite3_prepare(
|
let res = context.sql.query_row(
|
||||||
context,
|
|
||||||
&context.sql,
|
|
||||||
"SELECT c.id, c.blocked FROM chats c \
|
"SELECT c.id, c.blocked FROM chats c \
|
||||||
LEFT JOIN msgs m ON m.chat_id=c.id WHERE c.id IN(?) ORDER BY m.timestamp DESC, m.id DESC LIMIT 1;",
|
LEFT JOIN msgs m ON m.chat_id=c.id WHERE c.id IN(?) ORDER BY m.timestamp DESC, m.id DESC LIMIT 1;",
|
||||||
).and_then(|mut stmt| stmt.query_row(params![as_str(chat_ids_str)], |row| {
|
params![as_str(chat_ids_str)],
|
||||||
|
|row| {
|
||||||
Ok((row.get::<_, i32>(0)?, row.get::<_, i32>(1)?))
|
Ok((row.get::<_, i32>(0)?, row.get::<_, i32>(1)?))
|
||||||
}).ok());
|
}
|
||||||
|
);
|
||||||
|
|
||||||
if let Some((id, id_blocked)) = res {
|
if let Ok((id, id_blocked)) = res {
|
||||||
chat_id = id as u32;
|
chat_id = id as u32;
|
||||||
chat_id_blocked = id_blocked;
|
chat_id_blocked = id_blocked;
|
||||||
/* success, chat found */
|
/* success, chat found */
|
||||||
@@ -1607,31 +1607,25 @@ unsafe fn create_adhoc_grp_id(context: &Context, member_ids: *mut dc_array_t) ->
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.to_lowercase();
|
.to_lowercase();
|
||||||
|
|
||||||
let rows = if let Some(mut stmt) = dc_sqlite3_prepare(
|
let members = context
|
||||||
context,
|
.sql
|
||||||
&context.sql,
|
.query_map(
|
||||||
"SELECT addr FROM contacts WHERE id IN(?) AND id!=1",
|
"SELECT addr FROM contacts WHERE id IN(?) AND id!=1",
|
||||||
) {
|
params![as_str(member_ids_str)],
|
||||||
stmt.query_map(params![as_str(member_ids_str)], |row| {
|
|row| row.get::<_, String>(0),
|
||||||
row.get::<_, String>(0)
|
|rows| {
|
||||||
})
|
let mut addrs = rows.collect::<Result<Vec<_>, _>>()?;
|
||||||
.and_then(|res| res.collect::<rusqlite::Result<Vec<_>>>())
|
|
||||||
.ok()
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
free(member_ids_str as *mut libc::c_void);
|
|
||||||
|
|
||||||
let members = rows
|
|
||||||
.map(|mut addrs| {
|
|
||||||
addrs.sort();
|
addrs.sort();
|
||||||
addrs.iter().fold(member_cs.clone(), |mut acc, addr| {
|
let mut acc = member_cs.clone();
|
||||||
|
for addr in &addrs {
|
||||||
acc += ",";
|
acc += ",";
|
||||||
acc += &addr.to_lowercase();
|
acc += &addr.to_lowercase();
|
||||||
acc
|
}
|
||||||
})
|
Ok(acc)
|
||||||
})
|
},
|
||||||
.unwrap_or_else(|| member_cs);
|
)
|
||||||
|
.unwrap_or_else(|_| member_cs);
|
||||||
|
free(member_ids_str as *mut libc::c_void);
|
||||||
|
|
||||||
hex_hash(&members) as *mut _
|
hex_hash(&members) as *mut _
|
||||||
}
|
}
|
||||||
@@ -1673,25 +1667,17 @@ unsafe fn search_chat_ids_by_contact_ids(
|
|||||||
contact_ids_str =
|
contact_ids_str =
|
||||||
dc_array_get_string(contact_ids, b",\x00" as *const u8 as *const libc::c_char);
|
dc_array_get_string(contact_ids, b",\x00" as *const u8 as *const libc::c_char);
|
||||||
|
|
||||||
let rows = if let Some(mut stmt) = dc_sqlite3_prepare(
|
context.sql.query_map(
|
||||||
context,
|
|
||||||
&context.sql,
|
|
||||||
"SELECT DISTINCT cc.chat_id, cc.contact_id FROM chats_contacts cc LEFT JOIN chats c ON c.id=cc.chat_id WHERE cc.chat_id IN(SELECT chat_id FROM chats_contacts WHERE contact_id IN(?)) AND c.type=120 AND cc.contact_id!=1 ORDER BY cc.chat_id, cc.contact_id;",
|
"SELECT DISTINCT cc.chat_id, cc.contact_id FROM chats_contacts cc LEFT JOIN chats c ON c.id=cc.chat_id WHERE cc.chat_id IN(SELECT chat_id FROM chats_contacts WHERE contact_id IN(?)) AND c.type=120 AND cc.contact_id!=1 ORDER BY cc.chat_id, cc.contact_id;",
|
||||||
) {
|
|
||||||
stmt.query_map(
|
|
||||||
params![as_str(contact_ids_str)],
|
params![as_str(contact_ids_str)],
|
||||||
|row| Ok((row.get::<_, i32>(0)?, row.get::<_, i32>(1)?))
|
|row| Ok((row.get::<_, i32>(0)?, row.get::<_, i32>(1)?)),
|
||||||
).and_then(|res| res.collect::<rusqlite::Result<Vec<_>>>()).ok()
|
|rows| {
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(rows) = rows {
|
|
||||||
let mut last_chat_id = 0;
|
let mut last_chat_id = 0;
|
||||||
let mut matches = 0;
|
let mut matches = 0;
|
||||||
let mut mismatches = 0;
|
let mut mismatches = 0;
|
||||||
|
|
||||||
for (chat_id, contact_id) in rows {
|
for row in rows {
|
||||||
|
let (chat_id, contact_id) = row?;
|
||||||
if chat_id as u32 != last_chat_id {
|
if chat_id as u32 != last_chat_id {
|
||||||
if matches == dc_array_get_cnt(contact_ids) && mismatches == 0 {
|
if matches == dc_array_get_cnt(contact_ids) && mismatches == 0 {
|
||||||
dc_array_add_id(chat_ids, last_chat_id);
|
dc_array_add_id(chat_ids, last_chat_id);
|
||||||
@@ -1710,10 +1696,11 @@ unsafe fn search_chat_ids_by_contact_ids(
|
|||||||
if matches == dc_array_get_cnt(contact_ids) && mismatches == 0 {
|
if matches == dc_array_get_cnt(contact_ids) && mismatches == 0 {
|
||||||
dc_array_add_id(chat_ids, last_chat_id);
|
dc_array_add_id(chat_ids, last_chat_id);
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
).unwrap(); // TODO: better error handling
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
free(contact_ids_str as *mut libc::c_void);
|
free(contact_ids_str as *mut libc::c_void);
|
||||||
dc_array_unref(contact_ids);
|
dc_array_unref(contact_ids);
|
||||||
|
|
||||||
@@ -1727,10 +1714,9 @@ unsafe fn check_verified_properties(
|
|||||||
to_ids: *const dc_array_t,
|
to_ids: *const dc_array_t,
|
||||||
failure_reason: *mut *mut libc::c_char,
|
failure_reason: *mut *mut libc::c_char,
|
||||||
) -> libc::c_int {
|
) -> libc::c_int {
|
||||||
let mut everythings_okay: libc::c_int = 0;
|
let contact = dc_contact_new(context);
|
||||||
let contact: *mut dc_contact_t = dc_contact_new(context);
|
|
||||||
|
|
||||||
let verify_fail = |reason| {
|
let verify_fail = |reason: String| {
|
||||||
*failure_reason =
|
*failure_reason =
|
||||||
strdup(to_cstring(format!("{}. See \"Info\" for details.", reason)).as_ptr());
|
strdup(to_cstring(format!("{}. See \"Info\" for details.", reason)).as_ptr());
|
||||||
warn!(context, 0, "{}", reason);
|
warn!(context, 0, "{}", reason);
|
||||||
@@ -1741,13 +1727,13 @@ unsafe fn check_verified_properties(
|
|||||||
};
|
};
|
||||||
|
|
||||||
if !dc_contact_load_from_db(contact, &context.sql, from_id) {
|
if !dc_contact_load_from_db(contact, &context.sql, from_id) {
|
||||||
verify_fail("Internal Error; cannot load contact");
|
verify_fail("Internal Error; cannot load contact".into());
|
||||||
cleanup();
|
cleanup();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if 0 == mimeparser.e2ee_helper.encrypted {
|
if 0 == mimeparser.e2ee_helper.encrypted {
|
||||||
verify_fail("This message is not encrypted");
|
verify_fail("This message is not encrypted".into());
|
||||||
cleanup();
|
cleanup();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1760,14 +1746,14 @@ unsafe fn check_verified_properties(
|
|||||||
let peerstate = Peerstate::from_addr(context, &context.sql, as_str((*contact).addr));
|
let peerstate = Peerstate::from_addr(context, &context.sql, as_str((*contact).addr));
|
||||||
|
|
||||||
if peerstate.is_none() || dc_contact_is_verified_ex(contact, peerstate.as_ref()) != 2 {
|
if peerstate.is_none() || dc_contact_is_verified_ex(contact, peerstate.as_ref()) != 2 {
|
||||||
verify_fail("The sender of this message is not verified.");
|
verify_fail("The sender of this message is not verified.".into());
|
||||||
cleanup();
|
cleanup();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(peerstate) = peerstate {
|
if let Some(peerstate) = peerstate {
|
||||||
if !peerstate.has_verified_key(&mimeparser.e2ee_helper.signatures) {
|
if !peerstate.has_verified_key(&mimeparser.e2ee_helper.signatures) {
|
||||||
verify_fail("The message was sent with non-verified encryption.");
|
verify_fail("The message was sent with non-verified encryption.".into());
|
||||||
cleanup();
|
cleanup();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1778,25 +1764,20 @@ unsafe fn check_verified_properties(
|
|||||||
let to_ids_str = to_string(to_ids_str_c);
|
let to_ids_str = to_string(to_ids_str_c);
|
||||||
free(to_ids_str_c as *mut libc::c_void);
|
free(to_ids_str_c as *mut libc::c_void);
|
||||||
|
|
||||||
let rows = if let Some(mut stmt) = dc_sqlite3_prepare(
|
let ok = context
|
||||||
context,
|
.sql
|
||||||
&context.sql,
|
.query_map(
|
||||||
"SELECT c.addr, LENGTH(ps.verified_key_fingerprint) FROM contacts c \
|
"SELECT c.addr, LENGTH(ps.verified_key_fingerprint) FROM contacts c \
|
||||||
LEFT JOIN acpeerstates ps ON c.addr=ps.addr WHERE c.id IN(?) ",
|
LEFT JOIN acpeerstates ps ON c.addr=ps.addr WHERE c.id IN(?) ",
|
||||||
) {
|
params![&to_ids_str],
|
||||||
stmt.query_map(params![&to_ids_str], |row| {
|
|row| Ok((row.get::<_, String>(0)?, row.get::<_, i32>(1)?)),
|
||||||
Ok((row.get::<_, String>(0)?, row.get::<_, i32>(1)?))
|
|rows| {
|
||||||
})
|
for row in rows {
|
||||||
.and_then(|res| res.collect::<rusqlite::Result<Vec<_>>>())
|
let (to_addr, mut is_verified) = row?;
|
||||||
.ok()
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(rows) = rows {
|
|
||||||
for (to_addr, mut is_verified) in rows {
|
|
||||||
let mut peerstate = Peerstate::from_addr(context, &context.sql, &to_addr);
|
let mut peerstate = Peerstate::from_addr(context, &context.sql, &to_addr);
|
||||||
if mimeparser.e2ee_helper.gossipped_addr.contains(&to_addr) && peerstate.is_some() {
|
if mimeparser.e2ee_helper.gossipped_addr.contains(&to_addr)
|
||||||
|
&& peerstate.is_some()
|
||||||
|
{
|
||||||
let peerstate = peerstate.as_mut().unwrap();
|
let peerstate = peerstate.as_mut().unwrap();
|
||||||
|
|
||||||
// if we're here, we know the gossip key is verified:
|
// if we're here, we know the gossip key is verified:
|
||||||
@@ -1805,8 +1786,10 @@ unsafe fn check_verified_properties(
|
|||||||
// (otherwise a verified key can _only_ be updated through QR scan which might be annoying,
|
// (otherwise a verified key can _only_ be updated through QR scan which might be annoying,
|
||||||
// see https://github.com/nextleap-project/countermitm/issues/46 for a discussion about this point)
|
// see https://github.com/nextleap-project/countermitm/issues/46 for a discussion about this point)
|
||||||
if 0 == is_verified
|
if 0 == is_verified
|
||||||
|| peerstate.verified_key_fingerprint != peerstate.public_key_fingerprint
|
|| peerstate.verified_key_fingerprint
|
||||||
&& peerstate.verified_key_fingerprint != peerstate.gossip_key_fingerprint
|
!= peerstate.public_key_fingerprint
|
||||||
|
&& peerstate.verified_key_fingerprint
|
||||||
|
!= peerstate.gossip_key_fingerprint
|
||||||
{
|
{
|
||||||
info!(
|
info!(
|
||||||
context,
|
context,
|
||||||
@@ -1824,19 +1807,22 @@ unsafe fn check_verified_properties(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if 0 == is_verified {
|
if 0 == is_verified {
|
||||||
verify_fail(&format!(
|
verify_fail(format!(
|
||||||
"{} is not a member of this verified group",
|
"{} is not a member of this verified group",
|
||||||
to_addr
|
to_addr
|
||||||
));
|
));
|
||||||
cleanup();
|
cleanup();
|
||||||
return 0;
|
return Err(failure::format_err!("not a valid memember").into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
everythings_okay = 1;
|
Ok(())
|
||||||
}
|
},
|
||||||
|
)
|
||||||
|
.is_ok(); // TODO: Better default
|
||||||
|
|
||||||
cleanup();
|
cleanup();
|
||||||
everythings_okay
|
|
||||||
|
ok as libc::c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn set_better_msg(mime_parser: &dc_mimeparser_t, better_msg: *mut *mut libc::c_char) {
|
unsafe fn set_better_msg(mime_parser: &dc_mimeparser_t, better_msg: *mut *mut libc::c_char) {
|
||||||
@@ -1932,10 +1918,16 @@ fn is_known_rfc724_mid(context: &Context, rfc724_mid: *const libc::c_char) -> li
|
|||||||
if rfc724_mid.is_null() {
|
if rfc724_mid.is_null() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
dc_sqlite3_prepare(
|
context
|
||||||
context, &context.sql,
|
.sql
|
||||||
"SELECT m.id FROM msgs m LEFT JOIN chats c ON m.chat_id=c.id WHERE m.rfc724_mid=? AND m.chat_id>9 AND c.blocked=0;"
|
.exists(
|
||||||
).and_then(|mut stmt| stmt.exists(params![as_str(rfc724_mid)]).ok()).unwrap_or_default() as libc::c_int
|
"SELECT m.id FROM msgs m \
|
||||||
|
LEFT JOIN chats c ON m.chat_id=c.id \
|
||||||
|
WHERE m.rfc724_mid=? \
|
||||||
|
AND m.chat_id>9 AND c.blocked=0;",
|
||||||
|
params![as_str(rfc724_mid)],
|
||||||
|
)
|
||||||
|
.unwrap_or_default() as libc::c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn dc_is_reply_to_messenger_message(
|
unsafe fn dc_is_reply_to_messenger_message(
|
||||||
@@ -2010,12 +2002,12 @@ fn is_msgrmsg_rfc724_mid(context: &Context, rfc724_mid: *const libc::c_char) ->
|
|||||||
if rfc724_mid.is_null() {
|
if rfc724_mid.is_null() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
dc_sqlite3_prepare(
|
context
|
||||||
context,
|
.sql
|
||||||
&context.sql,
|
.exists(
|
||||||
"SELECT id FROM msgs WHERE rfc724_mid=? AND msgrmsg!=0 AND chat_id>9;",
|
"SELECT id FROM msgs WHERE rfc724_mid=? AND msgrmsg!=0 AND chat_id>9;",
|
||||||
|
params![as_str(rfc724_mid)],
|
||||||
)
|
)
|
||||||
.and_then(|mut stmt| stmt.exists(params![as_str(rfc724_mid)]).ok())
|
|
||||||
.unwrap_or_default() as libc::c_int
|
.unwrap_or_default() as libc::c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user