mirror of
https://github.com/chatmail/core.git
synced 2026-05-08 09:26:29 +03:00
Merge pull request #496 from KAction/safe
Make dc_msg_get_file return PathBuf, not char*
This commit is contained in:
@@ -17,7 +17,7 @@ use std::ptr;
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use deltachat::contact::Contact;
|
use deltachat::contact::Contact;
|
||||||
use deltachat::dc_tools::{as_str, dc_strdup, StrExt};
|
use deltachat::dc_tools::{as_str, dc_strdup, OsStrExt, StrExt};
|
||||||
use deltachat::*;
|
use deltachat::*;
|
||||||
|
|
||||||
// as C lacks a good and portable error handling,
|
// as C lacks a good and portable error handling,
|
||||||
@@ -2013,6 +2013,9 @@ pub unsafe extern "C" fn dc_msg_get_file(msg: *mut dc_msg_t) -> *mut libc::c_cha
|
|||||||
}
|
}
|
||||||
let ffi_msg = &*msg;
|
let ffi_msg = &*msg;
|
||||||
message::dc_msg_get_file(&*ffi_msg.context, &ffi_msg.message)
|
message::dc_msg_get_file(&*ffi_msg.context, &ffi_msg.message)
|
||||||
|
.and_then(|p| p.to_c_string().ok())
|
||||||
|
.map(|cs| dc_strdup(cs.as_ptr()))
|
||||||
|
.unwrap_or_else(|| dc_strdup(ptr::null()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ use mmime::mailimf_types::*;
|
|||||||
|
|
||||||
use crate::constants::*;
|
use crate::constants::*;
|
||||||
use crate::contact::*;
|
use crate::contact::*;
|
||||||
use crate::dc_tools::as_str;
|
|
||||||
use crate::key::*;
|
use crate::key::*;
|
||||||
|
|
||||||
/// Possible values for encryption preference
|
/// Possible values for encryption preference
|
||||||
@@ -64,11 +63,8 @@ impl Aheader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_imffields(
|
pub fn from_imffields(wanted_from: &str, header: *const mailimf_fields) -> Option<Self> {
|
||||||
wanted_from: *const libc::c_char,
|
if header.is_null() {
|
||||||
header: *const mailimf_fields,
|
|
||||||
) -> Option<Self> {
|
|
||||||
if wanted_from.is_null() || header.is_null() {
|
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,7 +90,7 @@ impl Aheader {
|
|||||||
|
|
||||||
match Self::from_str(value) {
|
match Self::from_str(value) {
|
||||||
Ok(test) => {
|
Ok(test) => {
|
||||||
if addr_cmp(&test.addr, as_str(wanted_from)) {
|
if addr_cmp(&test.addr, wanted_from) {
|
||||||
if fine_header.is_none() {
|
if fine_header.is_none() {
|
||||||
fine_header = Some(test);
|
fine_header = Some(test);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
45
src/chat.rs
45
src/chat.rs
@@ -2,6 +2,7 @@ use std::ffi::CString;
|
|||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use crate::chatlist::*;
|
use crate::chatlist::*;
|
||||||
|
use crate::config::*;
|
||||||
use crate::constants::*;
|
use crate::constants::*;
|
||||||
use crate::contact::*;
|
use crate::contact::*;
|
||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
@@ -59,15 +60,13 @@ impl Chat {
|
|||||||
|
|
||||||
match res {
|
match res {
|
||||||
Err(err @ crate::error::Error::Sql(rusqlite::Error::QueryReturnedNoRows)) => Err(err),
|
Err(err @ crate::error::Error::Sql(rusqlite::Error::QueryReturnedNoRows)) => Err(err),
|
||||||
Err(err) => match err {
|
Err(err) => {
|
||||||
_ => {
|
error!(
|
||||||
error!(
|
context,
|
||||||
context,
|
"chat: failed to load from db {}: {:?}", chat_id, err
|
||||||
"chat: failed to load from db {}: {:?}", chat_id, err
|
);
|
||||||
);
|
Err(err)
|
||||||
Err(err)
|
}
|
||||||
}
|
|
||||||
},
|
|
||||||
Ok(mut chat) => {
|
Ok(mut chat) => {
|
||||||
match chat.id {
|
match chat.id {
|
||||||
DC_CHAT_ID_DEADDROP => {
|
DC_CHAT_ID_DEADDROP => {
|
||||||
@@ -140,13 +139,12 @@ impl Chat {
|
|||||||
if self.typ == Chattype::Single {
|
if self.typ == Chattype::Single {
|
||||||
return context
|
return context
|
||||||
.sql
|
.sql
|
||||||
.query_row_col(
|
.query_get_value(
|
||||||
context,
|
context,
|
||||||
"SELECT c.addr FROM chats_contacts cc \
|
"SELECT c.addr FROM chats_contacts cc \
|
||||||
LEFT JOIN contacts c ON c.id=cc.contact_id \
|
LEFT JOIN contacts c ON c.id=cc.contact_id \
|
||||||
WHERE cc.chat_id=?;",
|
WHERE cc.chat_id=?;",
|
||||||
params![self.id as i32],
|
params![self.id as i32],
|
||||||
0,
|
|
||||||
)
|
)
|
||||||
.unwrap_or_else(|| "Err".into());
|
.unwrap_or_else(|| "Err".into());
|
||||||
}
|
}
|
||||||
@@ -183,7 +181,7 @@ impl Chat {
|
|||||||
pub fn get_profile_image(&self, context: &Context) -> Option<PathBuf> {
|
pub fn get_profile_image(&self, context: &Context) -> Option<PathBuf> {
|
||||||
if let Some(image_rel) = self.param.get(Param::ProfileImage) {
|
if let Some(image_rel) = self.param.get(Param::ProfileImage) {
|
||||||
if !image_rel.is_empty() {
|
if !image_rel.is_empty() {
|
||||||
return Some(dc_get_abs_path_safe(context, image_rel));
|
return Some(dc_get_abs_path(context, image_rel));
|
||||||
}
|
}
|
||||||
} else if self.typ == Chattype::Single {
|
} else if self.typ == Chattype::Single {
|
||||||
let contacts = get_chat_contacts(context, self.id);
|
let contacts = get_chat_contacts(context, self.id);
|
||||||
@@ -269,7 +267,7 @@ impl Chat {
|
|||||||
return Ok(0);
|
return Ok(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(from) = context.sql.get_config(context, "configured_addr") {
|
if let Some(from) = context.get_config(Config::ConfiguredAddr) {
|
||||||
let new_rfc724_mid = {
|
let new_rfc724_mid = {
|
||||||
let grpid = match self.typ {
|
let grpid = match self.typ {
|
||||||
Chattype::Group | Chattype::VerifiedGroup => Some(self.grpid.as_str()),
|
Chattype::Group | Chattype::VerifiedGroup => Some(self.grpid.as_str()),
|
||||||
@@ -279,11 +277,10 @@ impl Chat {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if self.typ == Chattype::Single {
|
if self.typ == Chattype::Single {
|
||||||
if let Some(id) = context.sql.query_row_col(
|
if let Some(id) = context.sql.query_get_value(
|
||||||
context,
|
context,
|
||||||
"SELECT contact_id FROM chats_contacts WHERE chat_id=?;",
|
"SELECT contact_id FROM chats_contacts WHERE chat_id=?;",
|
||||||
params![self.id as i32],
|
params![self.id as i32],
|
||||||
0,
|
|
||||||
) {
|
) {
|
||||||
to_id = id;
|
to_id = id;
|
||||||
} else {
|
} else {
|
||||||
@@ -724,13 +721,12 @@ fn prepare_msg_common(context: &Context, chat_id: u32, msg: &mut Message) -> Res
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn last_msg_in_chat_encrypted(context: &Context, sql: &Sql, chat_id: u32) -> bool {
|
fn last_msg_in_chat_encrypted(context: &Context, sql: &Sql, chat_id: u32) -> bool {
|
||||||
let packed: Option<String> = sql.query_row_col(
|
let packed: Option<String> = sql.query_get_value(
|
||||||
context,
|
context,
|
||||||
"SELECT param \
|
"SELECT param \
|
||||||
FROM msgs WHERE timestamp=(SELECT MAX(timestamp) FROM msgs WHERE chat_id=?) \
|
FROM msgs WHERE timestamp=(SELECT MAX(timestamp) FROM msgs WHERE chat_id=?) \
|
||||||
ORDER BY id DESC;",
|
ORDER BY id DESC;",
|
||||||
params![chat_id as i32],
|
params![chat_id as i32],
|
||||||
0,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(ref packed) = packed {
|
if let Some(ref packed) = packed {
|
||||||
@@ -912,11 +908,10 @@ unsafe fn set_draft_raw(context: &Context, chat_id: u32, mut msg: Option<&mut Me
|
|||||||
fn get_draft_msg_id(context: &Context, chat_id: u32) -> u32 {
|
fn get_draft_msg_id(context: &Context, chat_id: u32) -> u32 {
|
||||||
context
|
context
|
||||||
.sql
|
.sql
|
||||||
.query_row_col::<_, i32>(
|
.query_get_value::<_, i32>(
|
||||||
context,
|
context,
|
||||||
"SELECT id FROM msgs WHERE chat_id=? AND state=?;",
|
"SELECT id FROM msgs WHERE chat_id=? AND state=?;",
|
||||||
params![chat_id as i32, MessageState::OutDraft],
|
params![chat_id as i32, MessageState::OutDraft],
|
||||||
0,
|
|
||||||
)
|
)
|
||||||
.unwrap_or_default() as u32
|
.unwrap_or_default() as u32
|
||||||
}
|
}
|
||||||
@@ -1007,11 +1002,10 @@ pub fn get_chat_msgs(context: &Context, chat_id: u32, flags: u32, marker1before:
|
|||||||
pub fn get_msg_cnt(context: &Context, chat_id: u32) -> usize {
|
pub fn get_msg_cnt(context: &Context, chat_id: u32) -> usize {
|
||||||
context
|
context
|
||||||
.sql
|
.sql
|
||||||
.query_row_col::<_, i32>(
|
.query_get_value::<_, i32>(
|
||||||
context,
|
context,
|
||||||
"SELECT COUNT(*) FROM msgs WHERE chat_id=?;",
|
"SELECT COUNT(*) FROM msgs WHERE chat_id=?;",
|
||||||
params![chat_id as i32],
|
params![chat_id as i32],
|
||||||
0,
|
|
||||||
)
|
)
|
||||||
.unwrap_or_default() as usize
|
.unwrap_or_default() as usize
|
||||||
}
|
}
|
||||||
@@ -1019,14 +1013,13 @@ pub fn get_msg_cnt(context: &Context, chat_id: u32) -> usize {
|
|||||||
pub fn get_fresh_msg_cnt(context: &Context, chat_id: u32) -> usize {
|
pub fn get_fresh_msg_cnt(context: &Context, chat_id: u32) -> usize {
|
||||||
context
|
context
|
||||||
.sql
|
.sql
|
||||||
.query_row_col::<_, i32>(
|
.query_get_value::<_, i32>(
|
||||||
context,
|
context,
|
||||||
"SELECT COUNT(*) FROM msgs \
|
"SELECT COUNT(*) FROM msgs \
|
||||||
WHERE state=10 \
|
WHERE state=10 \
|
||||||
AND hidden=0 \
|
AND hidden=0 \
|
||||||
AND chat_id=?;",
|
AND chat_id=?;",
|
||||||
params![chat_id as i32],
|
params![chat_id as i32],
|
||||||
0,
|
|
||||||
)
|
)
|
||||||
.unwrap_or_default() as usize
|
.unwrap_or_default() as usize
|
||||||
}
|
}
|
||||||
@@ -1791,11 +1784,10 @@ pub unsafe fn forward_msgs(
|
|||||||
pub fn get_chat_contact_cnt(context: &Context, chat_id: u32) -> libc::c_int {
|
pub fn get_chat_contact_cnt(context: &Context, chat_id: u32) -> libc::c_int {
|
||||||
context
|
context
|
||||||
.sql
|
.sql
|
||||||
.query_row_col(
|
.query_get_value(
|
||||||
context,
|
context,
|
||||||
"SELECT COUNT(*) FROM chats_contacts WHERE chat_id=?;",
|
"SELECT COUNT(*) FROM chats_contacts WHERE chat_id=?;",
|
||||||
params![chat_id as i32],
|
params![chat_id as i32],
|
||||||
0,
|
|
||||||
)
|
)
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
@@ -1805,11 +1797,10 @@ pub fn get_chat_cnt(context: &Context) -> usize {
|
|||||||
/* no database, no chats - this is no error (needed eg. for information) */
|
/* no database, no chats - this is no error (needed eg. for information) */
|
||||||
context
|
context
|
||||||
.sql
|
.sql
|
||||||
.query_row_col::<_, isize>(
|
.query_get_value::<_, isize>(
|
||||||
context,
|
context,
|
||||||
"SELECT COUNT(*) FROM chats WHERE id>9 AND blocked=0;",
|
"SELECT COUNT(*) FROM chats WHERE id>9 AND blocked=0;",
|
||||||
params![],
|
params![],
|
||||||
0,
|
|
||||||
)
|
)
|
||||||
.unwrap_or_default() as usize
|
.unwrap_or_default() as usize
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -301,11 +301,10 @@ impl Chatlist {
|
|||||||
pub fn dc_get_archived_cnt(context: &Context) -> u32 {
|
pub fn dc_get_archived_cnt(context: &Context) -> u32 {
|
||||||
context
|
context
|
||||||
.sql
|
.sql
|
||||||
.query_row_col(
|
.query_get_value(
|
||||||
context,
|
context,
|
||||||
"SELECT COUNT(*) FROM chats WHERE blocked=0 AND archived=1;",
|
"SELECT COUNT(*) FROM chats WHERE blocked=0 AND archived=1;",
|
||||||
params![],
|
params![],
|
||||||
0,
|
|
||||||
)
|
)
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
@@ -315,7 +314,7 @@ fn get_last_deaddrop_fresh_msg(context: &Context) -> u32 {
|
|||||||
// only few fresh messages.
|
// only few fresh messages.
|
||||||
context
|
context
|
||||||
.sql
|
.sql
|
||||||
.query_row_col(
|
.query_get_value(
|
||||||
context,
|
context,
|
||||||
"SELECT m.id FROM msgs m LEFT JOIN chats c ON c.id=m.chat_id \
|
"SELECT m.id FROM msgs m LEFT JOIN chats c ON c.id=m.chat_id \
|
||||||
WHERE m.state=10 \
|
WHERE m.state=10 \
|
||||||
@@ -323,7 +322,6 @@ fn get_last_deaddrop_fresh_msg(context: &Context) -> u32 {
|
|||||||
AND c.blocked=2 \
|
AND c.blocked=2 \
|
||||||
ORDER BY m.timestamp DESC, m.id DESC;",
|
ORDER BY m.timestamp DESC, m.id DESC;",
|
||||||
params![],
|
params![],
|
||||||
0,
|
|
||||||
)
|
)
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ impl Context {
|
|||||||
let value = match key {
|
let value = match key {
|
||||||
Config::Selfavatar => {
|
Config::Selfavatar => {
|
||||||
let rel_path = self.sql.get_config(self, key);
|
let rel_path = self.sql.get_config(self, key);
|
||||||
rel_path.map(|p| dc_get_abs_path_safe(self, &p).to_str().unwrap().to_string())
|
rel_path.map(|p| dc_get_abs_path(self, &p).to_str().unwrap().to_string())
|
||||||
}
|
}
|
||||||
Config::SysVersion => Some((&*DC_VERSION_STR).clone()),
|
Config::SysVersion => Some((&*DC_VERSION_STR).clone()),
|
||||||
Config::SysMsgsizeMaxRecommended => Some(format!("{}", 24 * 1024 * 1024 / 4 * 3)),
|
Config::SysMsgsizeMaxRecommended => Some(format!("{}", 24 * 1024 * 1024 / 4 * 3)),
|
||||||
|
|||||||
@@ -264,7 +264,7 @@ impl Contact {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
context.sql.query_row_col(
|
context.sql.query_get_value(
|
||||||
context,
|
context,
|
||||||
"SELECT id FROM contacts WHERE addr=?1 COLLATE NOCASE AND id>?2 AND origin>=?3 AND blocked=0;",
|
"SELECT id FROM contacts WHERE addr=?1 COLLATE NOCASE AND id>?2 AND origin>=?3 AND blocked=0;",
|
||||||
params![
|
params![
|
||||||
@@ -272,7 +272,6 @@ impl Contact {
|
|||||||
DC_CONTACT_ID_LAST_SPECIAL as i32,
|
DC_CONTACT_ID_LAST_SPECIAL as i32,
|
||||||
DC_ORIGIN_MIN_CONTACT_LIST,
|
DC_ORIGIN_MIN_CONTACT_LIST,
|
||||||
],
|
],
|
||||||
0
|
|
||||||
).unwrap_or_default()
|
).unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -538,11 +537,10 @@ impl Contact {
|
|||||||
pub fn get_blocked_cnt(context: &Context) -> usize {
|
pub fn get_blocked_cnt(context: &Context) -> usize {
|
||||||
context
|
context
|
||||||
.sql
|
.sql
|
||||||
.query_row_col::<_, isize>(
|
.query_get_value::<_, isize>(
|
||||||
context,
|
context,
|
||||||
"SELECT COUNT(*) FROM contacts WHERE id>? AND blocked!=0",
|
"SELECT COUNT(*) FROM contacts WHERE id>? AND blocked!=0",
|
||||||
params![DC_CONTACT_ID_LAST_SPECIAL as i32],
|
params![DC_CONTACT_ID_LAST_SPECIAL as i32],
|
||||||
0,
|
|
||||||
)
|
)
|
||||||
.unwrap_or_default() as usize
|
.unwrap_or_default() as usize
|
||||||
}
|
}
|
||||||
@@ -645,22 +643,20 @@ impl Contact {
|
|||||||
|
|
||||||
let count_contacts: i32 = context
|
let count_contacts: i32 = context
|
||||||
.sql
|
.sql
|
||||||
.query_row_col(
|
.query_get_value(
|
||||||
context,
|
context,
|
||||||
"SELECT COUNT(*) FROM chats_contacts WHERE contact_id=?;",
|
"SELECT COUNT(*) FROM chats_contacts WHERE contact_id=?;",
|
||||||
params![contact_id as i32],
|
params![contact_id as i32],
|
||||||
0,
|
|
||||||
)
|
)
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
let count_msgs: i32 = if count_contacts > 0 {
|
let count_msgs: i32 = if count_contacts > 0 {
|
||||||
context
|
context
|
||||||
.sql
|
.sql
|
||||||
.query_row_col(
|
.query_get_value(
|
||||||
context,
|
context,
|
||||||
"SELECT COUNT(*) FROM msgs WHERE from_id=? OR to_id=?;",
|
"SELECT COUNT(*) FROM msgs WHERE from_id=? OR to_id=?;",
|
||||||
params![contact_id as i32, contact_id as i32],
|
params![contact_id as i32, contact_id as i32],
|
||||||
0,
|
|
||||||
)
|
)
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
} else {
|
} else {
|
||||||
@@ -844,11 +840,10 @@ impl Contact {
|
|||||||
|
|
||||||
context
|
context
|
||||||
.sql
|
.sql
|
||||||
.query_row_col::<_, isize>(
|
.query_get_value::<_, isize>(
|
||||||
context,
|
context,
|
||||||
"SELECT COUNT(*) FROM contacts WHERE id>?;",
|
"SELECT COUNT(*) FROM contacts WHERE id>?;",
|
||||||
params![DC_CONTACT_ID_LAST_SPECIAL as i32],
|
params![DC_CONTACT_ID_LAST_SPECIAL as i32],
|
||||||
0,
|
|
||||||
)
|
)
|
||||||
.unwrap_or_default() as usize
|
.unwrap_or_default() as usize
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -349,18 +349,16 @@ pub unsafe fn dc_get_info(context: &Context) -> *mut libc::c_char {
|
|||||||
.get_config_int(context, "mdns_enabled")
|
.get_config_int(context, "mdns_enabled")
|
||||||
.unwrap_or_else(|| 1);
|
.unwrap_or_else(|| 1);
|
||||||
|
|
||||||
let prv_key_cnt: Option<isize> = context.sql.query_row_col(
|
let prv_key_cnt: Option<isize> = context.sql.query_get_value(
|
||||||
context,
|
context,
|
||||||
"SELECT COUNT(*) FROM keypairs;",
|
"SELECT COUNT(*) FROM keypairs;",
|
||||||
rusqlite::NO_PARAMS,
|
rusqlite::NO_PARAMS,
|
||||||
0,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let pub_key_cnt: Option<isize> = context.sql.query_row_col(
|
let pub_key_cnt: Option<isize> = context.sql.query_get_value(
|
||||||
context,
|
context,
|
||||||
"SELECT COUNT(*) FROM acpeerstates;",
|
"SELECT COUNT(*) FROM acpeerstates;",
|
||||||
rusqlite::NO_PARAMS,
|
rusqlite::NO_PARAMS,
|
||||||
0,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let fingerprint_str = if let Some(key) = Key::from_self_public(context, &l2.addr, &context.sql)
|
let fingerprint_str = if let Some(key) = Key::from_self_public(context, &l2.addr, &context.sql)
|
||||||
@@ -508,12 +506,12 @@ pub fn dc_search_msgs(
|
|||||||
return Vec::new();
|
return Vec::new();
|
||||||
}
|
}
|
||||||
|
|
||||||
let real_query = to_string(query).trim().to_string();
|
let real_query = as_str(query).trim();
|
||||||
if real_query.is_empty() {
|
if real_query.is_empty() {
|
||||||
return Vec::new();
|
return Vec::new();
|
||||||
}
|
}
|
||||||
let strLikeInText = format!("%{}%", &real_query);
|
let strLikeInText = format!("%{}%", real_query);
|
||||||
let strLikeBeg = format!("{}%", &real_query);
|
let strLikeBeg = format!("{}%", real_query);
|
||||||
|
|
||||||
let query = if 0 != chat_id {
|
let query = if 0 != chat_id {
|
||||||
"SELECT m.id, m.timestamp FROM msgs m LEFT JOIN contacts ct ON m.from_id=ct.id WHERE m.chat_id=? \
|
"SELECT m.id, m.timestamp FROM msgs m LEFT JOIN contacts ct ON m.from_id=ct.id WHERE m.chat_id=? \
|
||||||
|
|||||||
@@ -269,54 +269,48 @@ pub unsafe fn dc_continue_key_transfer(
|
|||||||
setup_code: *const libc::c_char,
|
setup_code: *const libc::c_char,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let mut success = false;
|
let mut success = false;
|
||||||
let mut filename: *mut libc::c_char = ptr::null_mut();
|
|
||||||
let mut filecontent: *mut libc::c_char = ptr::null_mut();
|
|
||||||
let mut filebytes: size_t = 0i32 as size_t;
|
|
||||||
let mut armored_key: *mut libc::c_char = ptr::null_mut();
|
let mut armored_key: *mut libc::c_char = ptr::null_mut();
|
||||||
let mut norm_sc: *mut libc::c_char = ptr::null_mut();
|
let norm_sc;
|
||||||
if msg_id <= 9i32 as libc::c_uint || setup_code.is_null() {
|
if msg_id <= 9i32 as libc::c_uint || setup_code.is_null() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let msg = dc_get_msg(context, msg_id);
|
let msg = dc_get_msg(context, msg_id);
|
||||||
if msg.is_err()
|
if msg.is_err() {
|
||||||
|| !dc_msg_is_setupmessage(msg.as_ref().unwrap())
|
error!(context, "Message is no Autocrypt Setup Message.");
|
||||||
|| {
|
return false;
|
||||||
filename = dc_msg_get_file(context, msg.as_ref().unwrap());
|
}
|
||||||
filename.is_null()
|
let msg = msg.unwrap();
|
||||||
}
|
if !dc_msg_is_setupmessage(&msg) {
|
||||||
|| *filename.offset(0isize) as libc::c_int == 0i32
|
error!(context, "Message is no Autocrypt Setup Message.");
|
||||||
{
|
return false;
|
||||||
error!(context, "Message is no Autocrypt Setup Message.",);
|
}
|
||||||
} else if 0
|
|
||||||
== dc_read_file(
|
if let Some(filename) = dc_msg_get_file(context, &msg) {
|
||||||
context,
|
if let Some(buf) = dc_read_file_safe(context, filename) {
|
||||||
filename,
|
norm_sc = dc_normalize_setup_code(context, setup_code);
|
||||||
&mut filecontent as *mut *mut libc::c_char as *mut *mut libc::c_void,
|
if norm_sc.is_null() {
|
||||||
&mut filebytes,
|
warn!(context, "Cannot normalize Setup Code.",);
|
||||||
)
|
} else {
|
||||||
|| filecontent.is_null()
|
armored_key = dc_decrypt_setup_file(context, norm_sc, buf.as_ptr().cast());
|
||||||
|| filebytes <= 0
|
if armored_key.is_null() {
|
||||||
{
|
warn!(context, "Cannot decrypt Autocrypt Setup Message.",);
|
||||||
error!(context, "Cannot read Autocrypt Setup Message file.",);
|
} else if set_self_key(context, armored_key, 1) {
|
||||||
} else {
|
/*set default*/
|
||||||
norm_sc = dc_normalize_setup_code(context, setup_code);
|
/* error already logged */
|
||||||
if norm_sc.is_null() {
|
success = true
|
||||||
warn!(context, "Cannot normalize Setup Code.",);
|
}
|
||||||
} else {
|
|
||||||
armored_key = dc_decrypt_setup_file(context, norm_sc, filecontent);
|
|
||||||
if armored_key.is_null() {
|
|
||||||
warn!(context, "Cannot decrypt Autocrypt Setup Message.",);
|
|
||||||
} else if set_self_key(context, armored_key, 1) {
|
|
||||||
/*set default*/
|
|
||||||
/* error already logged */
|
|
||||||
success = true
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
error!(context, "Cannot read Autocrypt Setup Message file.",);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
error!(context, "Message is no Autocrypt Setup Message.");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(armored_key as *mut libc::c_void);
|
free(armored_key as *mut libc::c_void);
|
||||||
free(filecontent as *mut libc::c_void);
|
|
||||||
free(filename as *mut libc::c_void);
|
|
||||||
free(norm_sc as *mut libc::c_void);
|
free(norm_sc as *mut libc::c_void);
|
||||||
|
|
||||||
success
|
success
|
||||||
@@ -368,7 +362,7 @@ fn set_self_key(
|
|||||||
error!(context, "File does not contain a private key.",);
|
error!(context, "File does not contain a private key.",);
|
||||||
}
|
}
|
||||||
|
|
||||||
let self_addr = context.sql.get_config(context, "configured_addr");
|
let self_addr = context.get_config(Config::ConfiguredAddr);
|
||||||
|
|
||||||
if self_addr.is_none() {
|
if self_addr.is_none() {
|
||||||
error!(context, "Missing self addr");
|
error!(context, "Missing self addr");
|
||||||
@@ -612,7 +606,7 @@ unsafe fn import_backup(context: &Context, backup_to_import: *const libc::c_char
|
|||||||
|
|
||||||
let total_files_cnt = context
|
let total_files_cnt = context
|
||||||
.sql
|
.sql
|
||||||
.query_row_col::<_, isize>(context, "SELECT COUNT(*) FROM backup_blobs;", params![], 0)
|
.query_get_value::<_, isize>(context, "SELECT COUNT(*) FROM backup_blobs;", params![])
|
||||||
.unwrap_or_default() as usize;
|
.unwrap_or_default() as usize;
|
||||||
info!(
|
info!(
|
||||||
context,
|
context,
|
||||||
@@ -1099,7 +1093,7 @@ unsafe fn export_key_to_asc_file(
|
|||||||
}
|
}
|
||||||
info!(context, "Exporting key {}", as_str(file_name),);
|
info!(context, "Exporting key {}", as_str(file_name),);
|
||||||
dc_delete_file(context, as_path(file_name));
|
dc_delete_file(context, as_path(file_name));
|
||||||
if !key.write_asc_to_file(file_name, context) {
|
if !key.write_asc_to_file(as_path(file_name), context) {
|
||||||
error!(context, "Cannot write key to {}", as_str(file_name),);
|
error!(context, "Cannot write key to {}", as_str(file_name),);
|
||||||
} else {
|
} else {
|
||||||
context.call_cb(
|
context.call_cb(
|
||||||
|
|||||||
@@ -1289,7 +1289,10 @@ unsafe fn build_body_file(
|
|||||||
) as *mut libc::c_void,
|
) as *mut libc::c_void,
|
||||||
);
|
);
|
||||||
mime_sub = mailmime_new_empty(content, mime_fields);
|
mime_sub = mailmime_new_empty(content, mime_fields);
|
||||||
mailmime_set_body_file(mime_sub, dc_get_abs_path(context, path_filename));
|
let abs_path = dc_get_abs_path(context, path_filename)
|
||||||
|
.to_c_string()
|
||||||
|
.unwrap();
|
||||||
|
mailmime_set_body_file(mime_sub, dc_strdup(abs_path.as_ptr()));
|
||||||
if !ret_file_name_as_sent.is_null() {
|
if !ret_file_name_as_sent.is_null() {
|
||||||
*ret_file_name_as_sent = dc_strdup(filename_to_send)
|
*ret_file_name_as_sent = dc_strdup(filename_to_send)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -991,11 +991,10 @@ unsafe fn calc_timestamps(
|
|||||||
}
|
}
|
||||||
*sort_timestamp = message_timestamp;
|
*sort_timestamp = message_timestamp;
|
||||||
if 0 != is_fresh_msg {
|
if 0 != is_fresh_msg {
|
||||||
let last_msg_time: Option<i64> = context.sql.query_row_col(
|
let last_msg_time: Option<i64> = context.sql.query_get_value(
|
||||||
context,
|
context,
|
||||||
"SELECT MAX(timestamp) FROM msgs WHERE chat_id=? and from_id!=? AND timestamp>=?",
|
"SELECT MAX(timestamp) FROM msgs WHERE chat_id=? and from_id!=? AND timestamp>=?",
|
||||||
params![chat_id as i32, from_id as i32, *sort_timestamp],
|
params![chat_id as i32, from_id as i32, *sort_timestamp],
|
||||||
0,
|
|
||||||
);
|
);
|
||||||
if let Some(last_msg_time) = last_msg_time {
|
if let Some(last_msg_time) = last_msg_time {
|
||||||
if last_msg_time > 0 {
|
if last_msg_time > 0 {
|
||||||
|
|||||||
@@ -792,7 +792,7 @@ pub fn dc_get_filemeta(buf: &[u8]) -> Result<(u32, u32), Error> {
|
|||||||
///
|
///
|
||||||
/// If `path` starts with "$BLOBDIR", replaces it with the blobdir path.
|
/// If `path` starts with "$BLOBDIR", replaces it with the blobdir path.
|
||||||
/// Otherwise, returns path as is.
|
/// Otherwise, returns path as is.
|
||||||
pub fn dc_get_abs_path_safe<P: AsRef<std::path::Path>>(
|
pub fn dc_get_abs_path<P: AsRef<std::path::Path>>(
|
||||||
context: &Context,
|
context: &Context,
|
||||||
path: P,
|
path: P,
|
||||||
) -> std::path::PathBuf {
|
) -> std::path::PathBuf {
|
||||||
@@ -808,33 +808,12 @@ pub fn dc_get_abs_path_safe<P: AsRef<std::path::Path>>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn dc_get_abs_path(
|
|
||||||
context: &Context,
|
|
||||||
path_filename: impl AsRef<str>,
|
|
||||||
) -> *mut libc::c_char {
|
|
||||||
let starts = path_filename.as_ref().starts_with("$BLOBDIR");
|
|
||||||
|
|
||||||
if starts && !context.has_blobdir() {
|
|
||||||
return ptr::null_mut();
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut path_filename_abs = path_filename.as_ref().strdup();
|
|
||||||
if starts && context.has_blobdir() {
|
|
||||||
dc_str_replace(
|
|
||||||
&mut path_filename_abs,
|
|
||||||
b"$BLOBDIR\x00" as *const u8 as *const libc::c_char,
|
|
||||||
context.get_blobdir(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
path_filename_abs
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn dc_file_exist(context: &Context, path: impl AsRef<std::path::Path>) -> bool {
|
pub fn dc_file_exist(context: &Context, path: impl AsRef<std::path::Path>) -> bool {
|
||||||
dc_get_abs_path_safe(context, &path).exists()
|
dc_get_abs_path(context, &path).exists()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dc_get_filebytes(context: &Context, path: impl AsRef<std::path::Path>) -> uint64_t {
|
pub fn dc_get_filebytes(context: &Context, path: impl AsRef<std::path::Path>) -> uint64_t {
|
||||||
let path_abs = dc_get_abs_path_safe(context, &path);
|
let path_abs = dc_get_abs_path(context, &path);
|
||||||
match fs::metadata(&path_abs) {
|
match fs::metadata(&path_abs) {
|
||||||
Ok(meta) => meta.len() as uint64_t,
|
Ok(meta) => meta.len() as uint64_t,
|
||||||
Err(_err) => 0,
|
Err(_err) => 0,
|
||||||
@@ -842,7 +821,7 @@ pub fn dc_get_filebytes(context: &Context, path: impl AsRef<std::path::Path>) ->
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn dc_delete_file(context: &Context, path: impl AsRef<std::path::Path>) -> bool {
|
pub fn dc_delete_file(context: &Context, path: impl AsRef<std::path::Path>) -> bool {
|
||||||
let path_abs = dc_get_abs_path_safe(context, &path);
|
let path_abs = dc_get_abs_path(context, &path);
|
||||||
if !path_abs.is_file() {
|
if !path_abs.is_file() {
|
||||||
warn!(
|
warn!(
|
||||||
context,
|
context,
|
||||||
@@ -866,8 +845,8 @@ pub fn dc_copy_file(
|
|||||||
src: impl AsRef<std::path::Path>,
|
src: impl AsRef<std::path::Path>,
|
||||||
dest: impl AsRef<std::path::Path>,
|
dest: impl AsRef<std::path::Path>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let src_abs = dc_get_abs_path_safe(context, &src);
|
let src_abs = dc_get_abs_path(context, &src);
|
||||||
let dest_abs = dc_get_abs_path_safe(context, &dest);
|
let dest_abs = dc_get_abs_path(context, &dest);
|
||||||
match fs::copy(&src_abs, &dest_abs) {
|
match fs::copy(&src_abs, &dest_abs) {
|
||||||
Ok(_) => true,
|
Ok(_) => true,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
@@ -883,7 +862,7 @@ pub fn dc_copy_file(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn dc_create_folder(context: &Context, path: impl AsRef<std::path::Path>) -> bool {
|
pub fn dc_create_folder(context: &Context, path: impl AsRef<std::path::Path>) -> bool {
|
||||||
let path_abs = dc_get_abs_path_safe(context, &path);
|
let path_abs = dc_get_abs_path(context, &path);
|
||||||
if !path_abs.exists() {
|
if !path_abs.exists() {
|
||||||
match fs::create_dir_all(path_abs) {
|
match fs::create_dir_all(path_abs) {
|
||||||
Ok(_) => true,
|
Ok(_) => true,
|
||||||
@@ -918,7 +897,7 @@ pub fn dc_write_file_safe<P: AsRef<std::path::Path>>(
|
|||||||
path: P,
|
path: P,
|
||||||
buf: &[u8],
|
buf: &[u8],
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let path_abs = dc_get_abs_path_safe(context, &path);
|
let path_abs = dc_get_abs_path(context, &path);
|
||||||
if let Err(_err) = fs::write(&path_abs, buf) {
|
if let Err(_err) = fs::write(&path_abs, buf) {
|
||||||
warn!(
|
warn!(
|
||||||
context,
|
context,
|
||||||
@@ -953,7 +932,7 @@ pub unsafe fn dc_read_file(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn dc_read_file_safe<P: AsRef<std::path::Path>>(context: &Context, path: P) -> Option<Vec<u8>> {
|
pub fn dc_read_file_safe<P: AsRef<std::path::Path>>(context: &Context, path: P) -> Option<Vec<u8>> {
|
||||||
let path_abs = dc_get_abs_path_safe(context, &path);
|
let path_abs = dc_get_abs_path(context, &path);
|
||||||
match fs::read(&path_abs) {
|
match fs::read(&path_abs) {
|
||||||
Ok(bytes) => Some(bytes),
|
Ok(bytes) => Some(bytes),
|
||||||
Err(_err) => {
|
Err(_err) => {
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ impl E2eeHelper {
|
|||||||
EncryptPreference::NoPreference
|
EncryptPreference::NoPreference
|
||||||
};
|
};
|
||||||
|
|
||||||
let addr = context.sql.get_config(context, "configured_addr");
|
let addr = context.get_config(Config::ConfiguredAddr);
|
||||||
|
|
||||||
if let Some(addr) = addr {
|
if let Some(addr) = addr {
|
||||||
let pubkey_ret = load_or_generate_self_public_key(context, &addr).map_err(|err| {
|
let pubkey_ret = load_or_generate_self_public_key(context, &addr).map_err(|err| {
|
||||||
@@ -408,7 +408,8 @@ impl E2eeHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut peerstate = None;
|
let mut peerstate = None;
|
||||||
let autocryptheader = Aheader::from_imffields(from, imffields);
|
let autocryptheader =
|
||||||
|
as_opt_str(from).and_then(|from| Aheader::from_imffields(from, imffields));
|
||||||
if message_time > 0 && !from.is_null() {
|
if message_time > 0 && !from.is_null() {
|
||||||
peerstate = Peerstate::from_addr(context, &context.sql, as_str(from));
|
peerstate = Peerstate::from_addr(context, &context.sql, as_str(from));
|
||||||
|
|
||||||
@@ -429,7 +430,7 @@ impl E2eeHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* load private key for decryption */
|
/* load private key for decryption */
|
||||||
let self_addr = context.sql.get_config(context, "configured_addr");
|
let self_addr = context.get_config(Config::ConfiguredAddr);
|
||||||
if let Some(self_addr) = self_addr {
|
if let Some(self_addr) = self_addr {
|
||||||
if private_keyring.load_self_private_for_decrypting(
|
if private_keyring.load_self_private_for_decrypting(
|
||||||
context,
|
context,
|
||||||
|
|||||||
@@ -182,11 +182,10 @@ impl Job {
|
|||||||
);
|
);
|
||||||
let chat_id: i32 = context
|
let chat_id: i32 = context
|
||||||
.sql
|
.sql
|
||||||
.query_row_col(
|
.query_get_value(
|
||||||
context,
|
context,
|
||||||
"SELECT chat_id FROM msgs WHERE id=?",
|
"SELECT chat_id FROM msgs WHERE id=?",
|
||||||
params![self.foreign_id as i32],
|
params![self.foreign_id as i32],
|
||||||
0,
|
|
||||||
)
|
)
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
context.call_cb(
|
context.call_cb(
|
||||||
@@ -599,11 +598,10 @@ pub fn perform_smtp_idle(context: &Context) {
|
|||||||
fn get_next_wakeup_time(context: &Context, thread: Thread) -> Duration {
|
fn get_next_wakeup_time(context: &Context, thread: Thread) -> Duration {
|
||||||
let t: i64 = context
|
let t: i64 = context
|
||||||
.sql
|
.sql
|
||||||
.query_row_col(
|
.query_get_value(
|
||||||
context,
|
context,
|
||||||
"SELECT MIN(desired_timestamp) FROM jobs WHERE thread=?;",
|
"SELECT MIN(desired_timestamp) FROM jobs WHERE thread=?;",
|
||||||
params![thread],
|
params![thread],
|
||||||
0,
|
|
||||||
)
|
)
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
|||||||
36
src/key.rs
36
src/key.rs
@@ -1,6 +1,7 @@
|
|||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::ffi::{CStr, CString};
|
use std::ffi::{CStr, CString};
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
use libc;
|
use libc;
|
||||||
use pgp::composed::{Deserializable, SignedPublicKey, SignedSecretKey};
|
use pgp::composed::{Deserializable, SignedPublicKey, SignedSecretKey};
|
||||||
@@ -142,11 +143,10 @@ impl Key {
|
|||||||
) -> Option<Self> {
|
) -> Option<Self> {
|
||||||
let addr = self_addr.as_ref();
|
let addr = self_addr.as_ref();
|
||||||
|
|
||||||
sql.query_row_col(
|
sql.query_get_value(
|
||||||
context,
|
context,
|
||||||
"SELECT public_key FROM keypairs WHERE addr=? AND is_default=1;",
|
"SELECT public_key FROM keypairs WHERE addr=? AND is_default=1;",
|
||||||
&[addr],
|
&[addr],
|
||||||
0,
|
|
||||||
)
|
)
|
||||||
.and_then(|blob: Vec<u8>| Self::from_slice(&blob, KeyType::Public))
|
.and_then(|blob: Vec<u8>| Self::from_slice(&blob, KeyType::Public))
|
||||||
}
|
}
|
||||||
@@ -156,11 +156,10 @@ impl Key {
|
|||||||
self_addr: impl AsRef<str>,
|
self_addr: impl AsRef<str>,
|
||||||
sql: &Sql,
|
sql: &Sql,
|
||||||
) -> Option<Self> {
|
) -> Option<Self> {
|
||||||
sql.query_row_col(
|
sql.query_get_value(
|
||||||
context,
|
context,
|
||||||
"SELECT private_key FROM keypairs WHERE addr=? AND is_default=1;",
|
"SELECT private_key FROM keypairs WHERE addr=? AND is_default=1;",
|
||||||
&[self_addr.as_ref()],
|
&[self_addr.as_ref()],
|
||||||
0,
|
|
||||||
)
|
)
|
||||||
.and_then(|blob: Vec<u8>| Self::from_slice(&blob, KeyType::Private))
|
.and_then(|blob: Vec<u8>| Self::from_slice(&blob, KeyType::Private))
|
||||||
}
|
}
|
||||||
@@ -218,30 +217,15 @@ impl Key {
|
|||||||
.expect("failed to serialize key")
|
.expect("failed to serialize key")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_asc_to_file(&self, file: *const libc::c_char, context: &Context) -> bool {
|
pub fn write_asc_to_file(&self, file: impl AsRef<Path>, context: &Context) -> bool {
|
||||||
if file.is_null() {
|
let file_content = self.to_asc(None).into_bytes();
|
||||||
|
|
||||||
|
if dc_write_file_safe(context, &file, &file_content) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
error!(context, "Cannot write key to {}", file.as_ref().display());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let file_content = self.to_asc(None);
|
|
||||||
let file_content_c = CString::new(file_content).unwrap();
|
|
||||||
|
|
||||||
let success = if 0
|
|
||||||
== unsafe {
|
|
||||||
dc_write_file(
|
|
||||||
context,
|
|
||||||
file,
|
|
||||||
file_content_c.as_ptr() as *const libc::c_void,
|
|
||||||
file_content_c.as_bytes().len(),
|
|
||||||
)
|
|
||||||
} {
|
|
||||||
error!(context, "Cannot write key to {}", to_string(file));
|
|
||||||
false
|
|
||||||
} else {
|
|
||||||
true
|
|
||||||
};
|
|
||||||
|
|
||||||
success
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fingerprint(&self) -> String {
|
pub fn fingerprint(&self) -> String {
|
||||||
|
|||||||
@@ -33,11 +33,10 @@ impl<'a> Keyring<'a> {
|
|||||||
self_addr: impl AsRef<str>,
|
self_addr: impl AsRef<str>,
|
||||||
sql: &Sql,
|
sql: &Sql,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
sql.query_row_col(
|
sql.query_get_value(
|
||||||
context,
|
context,
|
||||||
"SELECT private_key FROM keypairs ORDER BY addr=? DESC, is_default DESC;",
|
"SELECT private_key FROM keypairs ORDER BY addr=? DESC, is_default DESC;",
|
||||||
&[self_addr.as_ref()],
|
&[self_addr.as_ref()],
|
||||||
0,
|
|
||||||
)
|
)
|
||||||
.and_then(|blob: Vec<u8>| Key::from_slice(&blob, KeyType::Private))
|
.and_then(|blob: Vec<u8>| Key::from_slice(&blob, KeyType::Private))
|
||||||
.map(|key| self.add_owned(key))
|
.map(|key| self.add_owned(key))
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::path::Path;
|
use std::path::{Path, PathBuf};
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
|
||||||
use deltachat_derive::{FromSql, ToSql};
|
use deltachat_derive::{FromSql, ToSql};
|
||||||
@@ -173,11 +173,10 @@ pub unsafe fn dc_get_msg_info(context: &Context, msg_id: u32) -> *mut libc::c_ch
|
|||||||
|
|
||||||
let msg = msg.unwrap();
|
let msg = msg.unwrap();
|
||||||
|
|
||||||
let rawtxt: Option<String> = context.sql.query_row_col(
|
let rawtxt: Option<String> = context.sql.query_get_value(
|
||||||
context,
|
context,
|
||||||
"SELECT txt_raw FROM msgs WHERE id=?;",
|
"SELECT txt_raw FROM msgs WHERE id=?;",
|
||||||
params![msg_id as i32],
|
params![msg_id as i32],
|
||||||
0,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if rawtxt.is_none() {
|
if rawtxt.is_none() {
|
||||||
@@ -269,15 +268,10 @@ pub unsafe fn dc_get_msg_info(context: &Context, msg_id: u32) -> *mut libc::c_ch
|
|||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
let p = dc_msg_get_file(context, &msg);
|
if let Some(path) = dc_msg_get_file(context, &msg) {
|
||||||
if !p.is_null() && 0 != *p.offset(0isize) as libc::c_int {
|
let bytes = dc_get_filebytes(context, &path);
|
||||||
ret += &format!(
|
ret += &format!("\nFile: {}, {}, bytes\n", path.display(), bytes);
|
||||||
"\nFile: {}, {}, bytes\n",
|
|
||||||
as_str(p),
|
|
||||||
dc_get_filebytes(context, as_path(p)) as libc::c_int,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
free(p as *mut libc::c_void);
|
|
||||||
|
|
||||||
if msg.type_0 != Viewtype::Text {
|
if msg.type_0 != Viewtype::Text {
|
||||||
ret += "Type: ";
|
ret += "Type: ";
|
||||||
@@ -378,17 +372,10 @@ pub fn dc_msg_guess_msgtype_from_suffix(path: &Path) -> Option<(Viewtype, &str)>
|
|||||||
KNOWN.get(extension).map(|x| *x)
|
KNOWN.get(extension).map(|x| *x)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn dc_msg_get_file(context: &Context, msg: &Message) -> *mut libc::c_char {
|
pub unsafe fn dc_msg_get_file(context: &Context, msg: &Message) -> Option<PathBuf> {
|
||||||
let mut file_abs = ptr::null_mut();
|
msg.param
|
||||||
|
.get(Param::File)
|
||||||
if let Some(file_rel) = msg.param.get(Param::File) {
|
.map(|f| dc_get_abs_path(context, f))
|
||||||
file_abs = dc_get_abs_path(context, file_rel);
|
|
||||||
}
|
|
||||||
if !file_abs.is_null() {
|
|
||||||
file_abs
|
|
||||||
} else {
|
|
||||||
dc_strdup(0 as *const libc::c_char)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -503,11 +490,10 @@ pub fn dc_msg_load_from_db(context: &Context, id: u32) -> Result<Message, Error>
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn dc_get_mime_headers(context: &Context, msg_id: u32) -> *mut libc::c_char {
|
pub unsafe fn dc_get_mime_headers(context: &Context, msg_id: u32) -> *mut libc::c_char {
|
||||||
let headers: Option<String> = context.sql.query_row_col(
|
let headers: Option<String> = context.sql.query_get_value(
|
||||||
context,
|
context,
|
||||||
"SELECT mime_headers FROM msgs WHERE id=?;",
|
"SELECT mime_headers FROM msgs WHERE id=?;",
|
||||||
params![msg_id as i32],
|
params![msg_id as i32],
|
||||||
0,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(headers) = headers {
|
if let Some(headers) = headers {
|
||||||
@@ -896,29 +882,16 @@ pub fn dc_msg_is_setupmessage(msg: &Message) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn dc_msg_get_setupcodebegin(context: &Context, msg: &Message) -> *mut libc::c_char {
|
pub unsafe fn dc_msg_get_setupcodebegin(context: &Context, msg: &Message) -> *mut libc::c_char {
|
||||||
let mut filename: *mut libc::c_char = ptr::null_mut();
|
|
||||||
let mut buf: *mut libc::c_char = ptr::null_mut();
|
|
||||||
let mut buf_bytes: size_t = 0i32 as size_t;
|
|
||||||
// just a pointer inside buf, MUST NOT be free()'d
|
// just a pointer inside buf, MUST NOT be free()'d
|
||||||
let mut buf_headerline: *const libc::c_char = ptr::null();
|
let mut buf_headerline: *const libc::c_char = ptr::null();
|
||||||
// just a pointer inside buf, MUST NOT be free()'d
|
// just a pointer inside buf, MUST NOT be free()'d
|
||||||
let mut buf_setupcodebegin: *const libc::c_char = ptr::null();
|
let mut buf_setupcodebegin: *const libc::c_char = ptr::null();
|
||||||
let mut ret: *mut libc::c_char = ptr::null_mut();
|
let mut ret: *mut libc::c_char = ptr::null_mut();
|
||||||
if dc_msg_is_setupmessage(msg) {
|
if dc_msg_is_setupmessage(msg) {
|
||||||
filename = dc_msg_get_file(context, msg);
|
if let Some(filename) = dc_msg_get_file(context, msg) {
|
||||||
if !(filename.is_null() || *filename.offset(0isize) as libc::c_int == 0i32) {
|
if let Some(mut buf) = dc_read_file_safe(context, filename) {
|
||||||
if !(0
|
|
||||||
== dc_read_file(
|
|
||||||
context,
|
|
||||||
filename,
|
|
||||||
&mut buf as *mut *mut libc::c_char as *mut *mut libc::c_void,
|
|
||||||
&mut buf_bytes,
|
|
||||||
)
|
|
||||||
|| buf.is_null()
|
|
||||||
|| buf_bytes <= 0)
|
|
||||||
{
|
|
||||||
if dc_split_armored_data(
|
if dc_split_armored_data(
|
||||||
buf,
|
buf.as_mut_ptr().cast(),
|
||||||
&mut buf_headerline,
|
&mut buf_headerline,
|
||||||
&mut buf_setupcodebegin,
|
&mut buf_setupcodebegin,
|
||||||
ptr::null_mut(),
|
ptr::null_mut(),
|
||||||
@@ -934,8 +907,6 @@ pub unsafe fn dc_msg_get_setupcodebegin(context: &Context, msg: &Message) -> *mu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(filename as *mut libc::c_void);
|
|
||||||
free(buf as *mut libc::c_void);
|
|
||||||
if !ret.is_null() {
|
if !ret.is_null() {
|
||||||
ret
|
ret
|
||||||
} else {
|
} else {
|
||||||
@@ -1035,11 +1006,10 @@ pub fn dc_msg_exists(context: &Context, msg_id: u32) -> bool {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let chat_id: Option<u32> = context.sql.query_row_col(
|
let chat_id: Option<u32> = context.sql.query_get_value(
|
||||||
context,
|
context,
|
||||||
"SELECT chat_id FROM msgs WHERE id=?;",
|
"SELECT chat_id FROM msgs WHERE id=?;",
|
||||||
params![msg_id],
|
params![msg_id],
|
||||||
0,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(chat_id) = chat_id {
|
if let Some(chat_id) = chat_id {
|
||||||
@@ -1158,11 +1128,10 @@ pub unsafe fn dc_mdn_from_ext(
|
|||||||
/* send event about new state */
|
/* send event about new state */
|
||||||
let ist_cnt: i32 = context
|
let ist_cnt: i32 = context
|
||||||
.sql
|
.sql
|
||||||
.query_row_col(
|
.query_get_value(
|
||||||
context,
|
context,
|
||||||
"SELECT COUNT(*) FROM msgs_mdns WHERE msg_id=?;",
|
"SELECT COUNT(*) FROM msgs_mdns WHERE msg_id=?;",
|
||||||
params![*ret_msg_id as i32],
|
params![*ret_msg_id as i32],
|
||||||
0,
|
|
||||||
)
|
)
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ use std::ptr;
|
|||||||
|
|
||||||
use crate::aheader::EncryptPreference;
|
use crate::aheader::EncryptPreference;
|
||||||
use crate::chat::{self, Chat};
|
use crate::chat::{self, Chat};
|
||||||
|
use crate::config::*;
|
||||||
use crate::configure::*;
|
use crate::configure::*;
|
||||||
use crate::constants::*;
|
use crate::constants::*;
|
||||||
use crate::contact::*;
|
use crate::contact::*;
|
||||||
@@ -82,7 +83,7 @@ pub fn dc_get_securejoin_qr(context: &Context, group_chat_id: uint32_t) -> Optio
|
|||||||
ensure_secret_key_exists(context).ok();
|
ensure_secret_key_exists(context).ok();
|
||||||
let invitenumber = token::lookup_or_new(context, token::Namespace::InviteNumber, group_chat_id);
|
let invitenumber = token::lookup_or_new(context, token::Namespace::InviteNumber, group_chat_id);
|
||||||
let auth = token::lookup_or_new(context, token::Namespace::Auth, group_chat_id);
|
let auth = token::lookup_or_new(context, token::Namespace::Auth, group_chat_id);
|
||||||
let self_addr = match context.sql.get_config(context, "configured_addr") {
|
let self_addr = match context.get_config(Config::ConfiguredAddr) {
|
||||||
Some(addr) => addr,
|
Some(addr) => addr,
|
||||||
None => {
|
None => {
|
||||||
error!(context, "Not configured, cannot generate QR code.",);
|
error!(context, "Not configured, cannot generate QR code.",);
|
||||||
@@ -139,7 +140,7 @@ pub fn dc_get_securejoin_qr(context: &Context, group_chat_id: uint32_t) -> Optio
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_self_fingerprint(context: &Context) -> Option<String> {
|
fn get_self_fingerprint(context: &Context) -> Option<String> {
|
||||||
if let Some(self_addr) = context.sql.get_config(context, "configured_addr") {
|
if let Some(self_addr) = context.get_config(Config::ConfiguredAddr) {
|
||||||
if let Some(key) = Key::from_self_public(context, self_addr, &context.sql) {
|
if let Some(key) = Key::from_self_public(context, self_addr, &context.sql) {
|
||||||
return Some(key.fingerprint());
|
return Some(key.fingerprint());
|
||||||
}
|
}
|
||||||
@@ -753,11 +754,10 @@ pub fn handle_degrade_event(context: &Context, peerstate: &Peerstate) {
|
|||||||
if Some(DegradeEvent::FingerprintChanged) == peerstate.degrade_event {
|
if Some(DegradeEvent::FingerprintChanged) == peerstate.degrade_event {
|
||||||
let contact_id: i32 = context
|
let contact_id: i32 = context
|
||||||
.sql
|
.sql
|
||||||
.query_row_col(
|
.query_get_value(
|
||||||
context,
|
context,
|
||||||
"SELECT id FROM contacts WHERE addr=?;",
|
"SELECT id FROM contacts WHERE addr=?;",
|
||||||
params![&peerstate.addr],
|
params![&peerstate.addr],
|
||||||
0,
|
|
||||||
)
|
)
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
if contact_id > 0 {
|
if contact_id > 0 {
|
||||||
|
|||||||
13
src/sql.rs
13
src/sql.rs
@@ -155,19 +155,13 @@ impl Sql {
|
|||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn query_row_col<P, T>(
|
pub fn query_get_value<P, T>(&self, context: &Context, query: &str, params: P) -> Option<T>
|
||||||
&self,
|
|
||||||
context: &Context,
|
|
||||||
query: &str,
|
|
||||||
params: P,
|
|
||||||
column: usize,
|
|
||||||
) -> Option<T>
|
|
||||||
where
|
where
|
||||||
P: IntoIterator,
|
P: IntoIterator,
|
||||||
P::Item: rusqlite::ToSql,
|
P::Item: rusqlite::ToSql,
|
||||||
T: rusqlite::types::FromSql,
|
T: rusqlite::types::FromSql,
|
||||||
{
|
{
|
||||||
match self.query_row(query, params, |row| row.get::<_, T>(column)) {
|
match self.query_row(query, params, |row| row.get::<_, T>(0)) {
|
||||||
Ok(res) => Some(res),
|
Ok(res) => Some(res),
|
||||||
Err(Error::Sql(rusqlite::Error::QueryReturnedNoRows)) => None,
|
Err(Error::Sql(rusqlite::Error::QueryReturnedNoRows)) => None,
|
||||||
Err(Error::Sql(rusqlite::Error::InvalidColumnType(
|
Err(Error::Sql(rusqlite::Error::InvalidColumnType(
|
||||||
@@ -238,11 +232,10 @@ impl Sql {
|
|||||||
if !self.is_open() || key.as_ref().is_empty() {
|
if !self.is_open() || key.as_ref().is_empty() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
self.query_row_col(
|
self.query_get_value(
|
||||||
context,
|
context,
|
||||||
"SELECT value FROM config WHERE keyname=?;",
|
"SELECT value FROM config WHERE keyname=?;",
|
||||||
params![key.as_ref()],
|
params![key.as_ref()],
|
||||||
0,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,11 +35,10 @@ pub fn save(context: &Context, namespace: Namespace, foreign_id: u32) -> String
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn lookup(context: &Context, namespace: Namespace, foreign_id: u32) -> Option<String> {
|
pub fn lookup(context: &Context, namespace: Namespace, foreign_id: u32) -> Option<String> {
|
||||||
context.sql.query_row_col::<_, String>(
|
context.sql.query_get_value::<_, String>(
|
||||||
context,
|
context,
|
||||||
"SELECT token FROM tokens WHERE namespc=? AND foreign_id=?;",
|
"SELECT token FROM tokens WHERE namespc=? AND foreign_id=?;",
|
||||||
params![namespace, foreign_id as i32],
|
params![namespace, foreign_id as i32],
|
||||||
0,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user