mirror of
https://github.com/chatmail/core.git
synced 2026-04-17 13:36:30 +03:00
Compare commits
44 Commits
1.0.0-alph
...
imap-locks
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c8290de628 | ||
|
|
cdfc8c6fa7 | ||
|
|
668c647fdd | ||
|
|
6e73b3728d | ||
|
|
127e2193af | ||
|
|
1bf1baa409 | ||
|
|
03a9b62a8a | ||
|
|
0742bb222d | ||
|
|
e700bc3a81 | ||
|
|
ab48745cc9 | ||
|
|
45a3bed3ad | ||
|
|
f3663aab1f | ||
|
|
157c847c85 | ||
|
|
c5252c9313 | ||
|
|
d19d3985e8 | ||
|
|
8714599655 | ||
|
|
f3884e30ac | ||
|
|
b5f4c263e5 | ||
|
|
98fb79f172 | ||
|
|
753cc4d6dc | ||
|
|
9d2ee5c0f7 | ||
|
|
08d8eebc37 | ||
|
|
ef31412d9e | ||
|
|
ecbd6fb154 | ||
|
|
b6392ee582 | ||
|
|
3366eb147d | ||
|
|
3b27dd28b6 | ||
|
|
45f7eba1f4 | ||
|
|
a0acfca255 | ||
|
|
9dda90dd5d | ||
|
|
808a0f2890 | ||
|
|
5b04dc8fa6 | ||
|
|
8c14924964 | ||
|
|
39b92687d3 | ||
|
|
0ff09e55c7 | ||
|
|
180bc926b6 | ||
|
|
8790a2dc52 | ||
|
|
d3e521ded0 | ||
|
|
813aae08a3 | ||
|
|
078c8859f4 | ||
|
|
34414b6059 | ||
|
|
ceb2b49be5 | ||
|
|
a791af2d90 | ||
|
|
ab41679855 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,5 +1,6 @@
|
||||
/target
|
||||
**/*.rs.bk
|
||||
Cargo.lock
|
||||
|
||||
# ignore vi temporaries
|
||||
*~
|
||||
@@ -16,5 +17,3 @@ python/.tox
|
||||
*.egg-info
|
||||
__pycache__
|
||||
python/src/deltachat/capi*.so
|
||||
|
||||
python/liveconfig*
|
||||
|
||||
2918
Cargo.lock
generated
2918
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "deltachat"
|
||||
version = "1.0.0-alpha.3"
|
||||
version = "1.0.0-alpha.2"
|
||||
authors = ["dignifiedquire <dignifiedquire@gmail.com>"]
|
||||
edition = "2018"
|
||||
license = "MPL"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "deltachat_ffi"
|
||||
version = "1.0.0-alpha.3"
|
||||
version = "1.0.0-alpha.1"
|
||||
description = "Deltachat FFI"
|
||||
authors = ["dignifiedquire <dignifiedquire@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
#[macro_use]
|
||||
extern crate human_panic;
|
||||
|
||||
use std::str::FromStr;
|
||||
|
||||
use deltachat::*;
|
||||
|
||||
// TODO: constants
|
||||
@@ -93,10 +91,7 @@ pub unsafe extern "C" fn dc_set_config(
|
||||
assert!(!key.is_null(), "invalid key");
|
||||
let context = &*context;
|
||||
|
||||
match config::Config::from_str(dc_tools::as_str(key)) {
|
||||
Ok(key) => context.set_config(key, as_opt_str(value)).is_ok() as libc::c_int,
|
||||
Err(_) => 0,
|
||||
}
|
||||
config::set(context, dc_tools::as_str(key), as_opt_str(value))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@@ -108,13 +103,7 @@ pub unsafe extern "C" fn dc_get_config(
|
||||
assert!(!key.is_null(), "invalid key");
|
||||
let context = &*context;
|
||||
|
||||
match config::Config::from_str(dc_tools::as_str(key)) {
|
||||
Ok(key) => {
|
||||
let value = context.get_config(key).unwrap_or_default();
|
||||
into_cstring(value)
|
||||
}
|
||||
Err(_) => std::ptr::null_mut(),
|
||||
}
|
||||
into_cstring(config::get(context, dc_tools::as_str(key)))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
use deltachat::config;
|
||||
use deltachat::constants::*;
|
||||
use deltachat::context::*;
|
||||
@@ -72,7 +70,7 @@ pub unsafe fn dc_reset_tables(context: &Context, bits: i32) -> i32 {
|
||||
sql::execute(
|
||||
context,
|
||||
&context.sql,
|
||||
"DELETE FROM config WHERE keyname LIKE 'imap.%' OR keyname LIKE 'configured%';",
|
||||
"DELETE FROM config WHERE keyname LIKE \'imap.%\' OR keyname LIKE \'configured%\';",
|
||||
params![],
|
||||
);
|
||||
sql::execute(context, &context.sql, "DELETE FROM leftgrps;", params![]);
|
||||
@@ -132,7 +130,7 @@ unsafe fn poke_spec(context: &Context, spec: *const libc::c_char) -> libc::c_int
|
||||
.set_config(context, "import_spec", Some(as_str(real_spec)));
|
||||
current_block = 7149356873433890176;
|
||||
} else {
|
||||
let rs = context.sql.get_config(context, "import_spec");
|
||||
let rs = context.sql.get_config(context, "import_spec", None);
|
||||
if rs.is_none() {
|
||||
error!(context, 0, "Import: No file or folder given.");
|
||||
current_block = 8522321847195001863;
|
||||
@@ -481,9 +479,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
|
||||
},
|
||||
"auth" => {
|
||||
if 0 == S_IS_AUTH {
|
||||
let is_pw = context
|
||||
.get_config(config::Config::MailPw)
|
||||
.unwrap_or_default();
|
||||
let is_pw = config::get(context, "mail_pw");
|
||||
if arg1 == is_pw {
|
||||
S_IS_AUTH = 1;
|
||||
} else {
|
||||
@@ -603,15 +599,15 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
|
||||
}
|
||||
"set" => {
|
||||
ensure!(!arg1.is_empty(), "Argument <key> missing.");
|
||||
let key = config::Config::from_str(&arg1)?;
|
||||
let value = if arg2.is_empty() { None } else { Some(arg2) };
|
||||
context.set_config(key, value)?;
|
||||
ensure!(
|
||||
0 != config::set(context, &arg1, Some(&arg2)),
|
||||
"Set config failed"
|
||||
);
|
||||
}
|
||||
"get" => {
|
||||
ensure!(!arg1.is_empty(), "Argument <key> missing.");
|
||||
let key = config::Config::from_str(&arg1)?;
|
||||
let val = context.get_config(key);
|
||||
println!("{}={:?}", key, val);
|
||||
let val = config::get(context, &arg1);
|
||||
println!("{}={}", arg1, val);
|
||||
}
|
||||
"info" => {
|
||||
println!("{}", to_string(dc_get_info(context)));
|
||||
@@ -911,7 +907,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
|
||||
|
||||
let seconds = arg1.parse().unwrap();
|
||||
dc_send_locations_to_chat(context, dc_chat_get_id(sel_chat), seconds);
|
||||
println!("Locations will be sent to Chat#{} for {} seconds. Use 'setlocation <lat> <lng>' to play around.", dc_chat_get_id(sel_chat), seconds);
|
||||
println!("Locations will be sent to Chat#{} for {} seconds. Use \'setlocation <lat> <lng>\' to play around.", dc_chat_get_id(sel_chat), seconds);
|
||||
}
|
||||
"setlocation" => {
|
||||
ensure!(
|
||||
|
||||
@@ -515,7 +515,10 @@ unsafe fn handle_cmd(line: &str, ctx: Arc<RwLock<Context>>) -> Result<ExitResult
|
||||
dc_configure(&ctx.read().unwrap());
|
||||
}
|
||||
"oauth2" => {
|
||||
if let Some(addr) = ctx.read().unwrap().get_config(config::Config::Addr) {
|
||||
let addr = config::get(&ctx.read().unwrap(), "addr");
|
||||
if addr.is_empty() {
|
||||
println!("oauth2: set addr first.");
|
||||
} else {
|
||||
let oauth2_url = dc_get_oauth2_url(
|
||||
&ctx.read().unwrap(),
|
||||
&addr,
|
||||
@@ -526,8 +529,6 @@ unsafe fn handle_cmd(line: &str, ctx: Arc<RwLock<Context>>) -> Result<ExitResult
|
||||
} else {
|
||||
println!("Open the following url, set mail_pw to the generated token and server_flags to 2:\n{}", oauth2_url.unwrap());
|
||||
}
|
||||
} else {
|
||||
println!("oauth2: set addr first.");
|
||||
}
|
||||
}
|
||||
"clear" => {
|
||||
|
||||
@@ -86,8 +86,8 @@ fn main() {
|
||||
let args = std::env::args().collect::<Vec<String>>();
|
||||
assert_eq!(args.len(), 2, "missing password");
|
||||
let pw = args[1].clone();
|
||||
ctx.set_config(config::Config::Addr, Some("d@testrun.org"));
|
||||
ctx.set_config(config::Config::MailPw, Some(&pw));
|
||||
config::set(&ctx, "addr", Some("d@testrun.org"));
|
||||
config::set(&ctx, "mail_pw", Some(&pw));
|
||||
dc_configure(&ctx);
|
||||
|
||||
thread::sleep(duration);
|
||||
|
||||
2
python/liveconfig3
Normal file
2
python/liveconfig3
Normal file
@@ -0,0 +1,2 @@
|
||||
addr=digtest1@testrun.org mail_pw=diggydug
|
||||
addr=digtest2@testrun.org mail_pw=diggydug
|
||||
@@ -1,3 +0,0 @@
|
||||
pre-release-commit-message = "chore({{crate_name}}): release {{version}}"
|
||||
pro-release-commit-message = "chore({{crate_name}}): starting development cycle for {{next_version}}"
|
||||
no-dev-version = true
|
||||
190
src/config.rs
190
src/config.rs
@@ -1,3 +1,5 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
use strum::{EnumProperty, IntoEnumIterator};
|
||||
use strum_macros::{AsRefStr, Display, EnumIter, EnumProperty, EnumString};
|
||||
|
||||
@@ -6,7 +8,6 @@ use crate::context::Context;
|
||||
use crate::dc_job::*;
|
||||
use crate::dc_stock::*;
|
||||
use crate::dc_tools::*;
|
||||
use crate::error::Error;
|
||||
use crate::x::*;
|
||||
|
||||
/// The available configuration keys.
|
||||
@@ -55,100 +56,133 @@ pub enum Config {
|
||||
ConfiguredSendPort,
|
||||
ConfiguredServerFlags,
|
||||
Configured,
|
||||
// Deprecated
|
||||
}
|
||||
|
||||
// deprecated
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Display, EnumString, AsRefStr, EnumIter)]
|
||||
pub enum SysConfig {
|
||||
#[strum(serialize = "sys.version")]
|
||||
SysVersion,
|
||||
Version,
|
||||
#[strum(serialize = "sys.msgsize_max_recommended")]
|
||||
SysMsgsizeMaxRecommended,
|
||||
MsgsizeMaxRecommended,
|
||||
#[strum(serialize = "sys.config_keys")]
|
||||
SysConfigKeys,
|
||||
ConfigKeys,
|
||||
}
|
||||
|
||||
impl Context {
|
||||
/// Get a configuration key. Returns `None` if no value is set, and no default value found.
|
||||
pub fn get_config(&self, key: Config) -> Option<String> {
|
||||
let value = match key {
|
||||
Config::Selfavatar => {
|
||||
let rel_path = self.sql.get_config(self, key);
|
||||
rel_path.map(|p| {
|
||||
let v = unsafe { dc_get_abs_path(self, to_cstring(p).as_ptr()) };
|
||||
let r = to_string(v);
|
||||
unsafe { free(v as *mut _) };
|
||||
r
|
||||
})
|
||||
}
|
||||
Config::SysVersion => Some(std::str::from_utf8(DC_VERSION_STR).unwrap().into()),
|
||||
Config::SysMsgsizeMaxRecommended => Some(format!("{}", 24 * 1024 * 1024 / 4 * 3)),
|
||||
Config::SysConfigKeys => Some(get_config_keys_string()),
|
||||
_ => self.sql.get_config(self, key),
|
||||
};
|
||||
/// Get a configuration key.
|
||||
/// Returns "" when the key is invalid, or no default was found.
|
||||
pub fn get(context: &Context, key: impl AsRef<str>) -> String {
|
||||
let key = key.as_ref();
|
||||
|
||||
if value.is_some() {
|
||||
return value;
|
||||
}
|
||||
|
||||
// Default values
|
||||
match key {
|
||||
Config::Selfstatus => {
|
||||
let s = unsafe { dc_stock_str(self, 13) };
|
||||
let res = to_string(s);
|
||||
unsafe { free(s as *mut _) };
|
||||
Some(res)
|
||||
}
|
||||
_ => key.get_str("default").map(|s| s.to_string()),
|
||||
}
|
||||
if key.starts_with("sys.") {
|
||||
return get_sys_config_str(key);
|
||||
}
|
||||
|
||||
/// Set the given config key.
|
||||
/// If `None` is passed as a value the value is cleared and set to the deafult if there is one.
|
||||
pub fn set_config(&self, key: Config, value: Option<&str>) -> Result<(), Error> {
|
||||
match key {
|
||||
Config::Selfavatar if value.is_some() => {
|
||||
let rel_path = std::fs::canonicalize(value.unwrap())?;
|
||||
self.sql
|
||||
.set_config(self, key, Some(&rel_path.to_string_lossy()))
|
||||
}
|
||||
Config::InboxWatch => {
|
||||
let ret = self.sql.set_config(self, key, value);
|
||||
unsafe { dc_interrupt_imap_idle(self) };
|
||||
ret
|
||||
}
|
||||
Config::SentboxWatch => {
|
||||
let ret = self.sql.set_config(self, key, value);
|
||||
unsafe { dc_interrupt_sentbox_idle(self) };
|
||||
ret
|
||||
}
|
||||
Config::MvboxWatch => {
|
||||
let ret = self.sql.set_config(self, key, value);
|
||||
unsafe { dc_interrupt_mvbox_idle(self) };
|
||||
ret
|
||||
}
|
||||
Config::Selfstatus => {
|
||||
let def = unsafe { dc_stock_str(self, 13) };
|
||||
let val = if value.is_none() || value.unwrap() == as_str(def) {
|
||||
None
|
||||
} else {
|
||||
value
|
||||
};
|
||||
match Config::from_str(key) {
|
||||
Ok(config_key) => {
|
||||
let value = match config_key {
|
||||
Config::Selfavatar => {
|
||||
let rel_path = context.sql.get_config(context, key, None);
|
||||
rel_path.map(|p| {
|
||||
let v = unsafe { dc_get_abs_path(context, to_cstring(p).as_ptr()) };
|
||||
let r = to_string(v);
|
||||
unsafe { free(v as *mut _) };
|
||||
r
|
||||
})
|
||||
}
|
||||
_ => context.sql.get_config(context, key, None),
|
||||
};
|
||||
|
||||
let ret = self.sql.set_config(self, key, val);
|
||||
unsafe { free(def as *mut libc::c_void) };
|
||||
ret
|
||||
if value.is_some() {
|
||||
return value.unwrap();
|
||||
}
|
||||
|
||||
// Default values
|
||||
match config_key {
|
||||
Config::Selfstatus => {
|
||||
let s = unsafe { dc_stock_str(context, 13) };
|
||||
let res = to_string(s);
|
||||
unsafe { free(s as *mut _) };
|
||||
res
|
||||
}
|
||||
_ => config_key
|
||||
.get_str("default")
|
||||
.unwrap_or_default()
|
||||
.to_string(),
|
||||
}
|
||||
_ => self.sql.set_config(self, key, value),
|
||||
}
|
||||
Err(_) => "".into(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns all available configuration keys concated together.
|
||||
fn get_config_keys_string() -> String {
|
||||
fn get_sys_config_str(key: impl AsRef<str>) -> String {
|
||||
match SysConfig::from_str(key.as_ref()) {
|
||||
Ok(SysConfig::Version) => std::str::from_utf8(DC_VERSION_STR).unwrap().into(),
|
||||
Ok(SysConfig::MsgsizeMaxRecommended) => format!("{}", 24 * 1024 * 1024 / 4 * 3),
|
||||
Ok(SysConfig::ConfigKeys) => get_config_keys_str(),
|
||||
Err(_) => "".into(),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_config_keys_str() -> String {
|
||||
let keys = Config::iter().fold(String::new(), |mut acc, key| {
|
||||
acc += key.as_ref();
|
||||
acc += " ";
|
||||
acc
|
||||
});
|
||||
|
||||
format!(" {} ", keys)
|
||||
let sys_keys = SysConfig::iter().fold(String::new(), |mut acc, key| {
|
||||
acc += key.as_ref();
|
||||
acc += " ";
|
||||
acc
|
||||
});
|
||||
|
||||
format!(" {} {} ", keys, sys_keys)
|
||||
}
|
||||
|
||||
/// Set the given config key.
|
||||
/// Returns `1` on success and `0` on failure.
|
||||
pub fn set(context: &Context, key: impl AsRef<str>, value: Option<&str>) -> libc::c_int {
|
||||
let mut ret = 0;
|
||||
|
||||
// regular keys
|
||||
match Config::from_str(key.as_ref()) {
|
||||
Ok(Config::Selfavatar) if value.is_some() => {
|
||||
let mut rel_path = unsafe { dc_strdup(to_cstring(value.unwrap()).as_ptr()) };
|
||||
if 0 != unsafe { dc_make_rel_and_copy(context, &mut rel_path) } {
|
||||
ret = context.sql.set_config(context, key, Some(as_str(rel_path)));
|
||||
}
|
||||
unsafe { free(rel_path as *mut libc::c_void) };
|
||||
}
|
||||
Ok(Config::InboxWatch) => {
|
||||
ret = context.sql.set_config(context, key, value);
|
||||
unsafe { dc_interrupt_imap_idle(context) };
|
||||
}
|
||||
Ok(Config::SentboxWatch) => {
|
||||
ret = context.sql.set_config(context, key, value);
|
||||
unsafe { dc_interrupt_sentbox_idle(context) };
|
||||
}
|
||||
Ok(Config::MvboxWatch) => {
|
||||
ret = context.sql.set_config(context, key, value);
|
||||
unsafe { dc_interrupt_mvbox_idle(context) };
|
||||
}
|
||||
Ok(Config::Selfstatus) => {
|
||||
let def = unsafe { dc_stock_str(context, 13) };
|
||||
let val = if value.is_none() || value.unwrap() == as_str(def) {
|
||||
None
|
||||
} else {
|
||||
value
|
||||
};
|
||||
|
||||
ret = context.sql.set_config(context, key, val);
|
||||
unsafe { free(def as *mut libc::c_void) };
|
||||
}
|
||||
Ok(_) => {
|
||||
ret = context.sql.set_config(context, key, value);
|
||||
}
|
||||
Err(_) => {}
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -163,10 +197,10 @@ mod tests {
|
||||
assert_eq!(Config::MailServer.to_string(), "mail_server");
|
||||
assert_eq!(Config::from_str("mail_server"), Ok(Config::MailServer));
|
||||
|
||||
assert_eq!(Config::SysConfigKeys.to_string(), "sys.config_keys");
|
||||
assert_eq!(SysConfig::ConfigKeys.to_string(), "sys.config_keys");
|
||||
assert_eq!(
|
||||
Config::from_str("sys.config_keys"),
|
||||
Ok(Config::SysConfigKeys)
|
||||
SysConfig::from_str("sys.config_keys"),
|
||||
Ok(SysConfig::ConfigKeys)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//! Constants
|
||||
|
||||
pub const DC_VERSION_STR: &'static [u8; 14] = b"1.0.0-alpha.3\x00";
|
||||
pub const DC_VERSION_STR: &'static [u8; 14] = b"1.0.0-alpha.1\x00";
|
||||
|
||||
pub const DC_MOVE_STATE_MOVING: u32 = 3;
|
||||
pub const DC_MOVE_STATE_STAY: u32 = 2;
|
||||
|
||||
@@ -275,11 +275,17 @@ unsafe fn cb_get_config(
|
||||
key: *const libc::c_char,
|
||||
def: *const libc::c_char,
|
||||
) -> *mut libc::c_char {
|
||||
let res = context
|
||||
.sql
|
||||
.get_config(context, as_str(key))
|
||||
.unwrap_or_else(|| to_string(def));
|
||||
strdup(to_cstring(res).as_ptr())
|
||||
let d = if def.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(as_str(def))
|
||||
};
|
||||
let res = context.sql.get_config(context, as_str(key), d);
|
||||
if let Some(res) = res {
|
||||
strdup(to_cstring(res).as_ptr())
|
||||
} else {
|
||||
std::ptr::null_mut()
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn dc_context_unref(context: &mut Context) {
|
||||
@@ -370,27 +376,15 @@ pub unsafe fn dc_get_info(context: &Context) -> *mut libc::c_char {
|
||||
let unset = "0";
|
||||
let l = dc_loginparam_read(context, &context.sql, "");
|
||||
let l2 = dc_loginparam_read(context, &context.sql, "configured_");
|
||||
let displayname = context.sql.get_config(context, "displayname");
|
||||
let displayname = context.sql.get_config(context, "displayname", None);
|
||||
let chats = dc_get_chat_cnt(context) as usize;
|
||||
let real_msgs = dc_get_real_msg_cnt(context) as usize;
|
||||
let deaddrop_msgs = dc_get_deaddrop_msg_cnt(context) as usize;
|
||||
let contacts = dc_get_real_contact_cnt(context) as usize;
|
||||
let is_configured = context
|
||||
.sql
|
||||
.get_config_int(context, "configured")
|
||||
.unwrap_or_default();
|
||||
let dbversion = context
|
||||
.sql
|
||||
.get_config_int(context, "dbversion")
|
||||
.unwrap_or_default();
|
||||
let e2ee_enabled = context
|
||||
.sql
|
||||
.get_config_int(context, "e2ee_enabled")
|
||||
.unwrap_or_else(|| 1);
|
||||
let mdns_enabled = context
|
||||
.sql
|
||||
.get_config_int(context, "mdns_enabled")
|
||||
.unwrap_or_else(|| 1);
|
||||
let is_configured = context.sql.get_config_int(context, "configured", 0);
|
||||
let dbversion = context.sql.get_config_int(context, "dbversion", 0);
|
||||
let e2ee_enabled = context.sql.get_config_int(context, "e2ee_enabled", 1);
|
||||
let mdns_enabled = context.sql.get_config_int(context, "mdns_enabled", 1);
|
||||
|
||||
let prv_key_cnt: Option<isize> = context.sql.query_row_col(
|
||||
context,
|
||||
@@ -415,34 +409,19 @@ pub unsafe fn dc_get_info(context: &Context) -> *mut libc::c_char {
|
||||
|
||||
let l_readable_str = dc_loginparam_get_readable(&l);
|
||||
let l2_readable_str = dc_loginparam_get_readable(&l2);
|
||||
let inbox_watch = context
|
||||
.sql
|
||||
.get_config_int(context, "inbox_watch")
|
||||
.unwrap_or_else(|| 1);
|
||||
let sentbox_watch = context
|
||||
.sql
|
||||
.get_config_int(context, "sentbox_watch")
|
||||
.unwrap_or_else(|| 1);
|
||||
let mvbox_watch = context
|
||||
.sql
|
||||
.get_config_int(context, "mvbox_watch")
|
||||
.unwrap_or_else(|| 1);
|
||||
let mvbox_move = context
|
||||
.sql
|
||||
.get_config_int(context, "mvbox_move")
|
||||
.unwrap_or_else(|| 1);
|
||||
let folders_configured = context
|
||||
.sql
|
||||
.get_config_int(context, "folders_configured")
|
||||
.unwrap_or_default();
|
||||
let configured_sentbox_folder = context
|
||||
.sql
|
||||
.get_config(context, "configured_sentbox_folder")
|
||||
.unwrap_or_else(|| "<unset>".to_string());
|
||||
let configured_mvbox_folder = context
|
||||
.sql
|
||||
.get_config(context, "configured_mvbox_folder")
|
||||
.unwrap_or_else(|| "<unset>".to_string());
|
||||
let inbox_watch = context.sql.get_config_int(context, "inbox_watch", 1);
|
||||
let sentbox_watch = context.sql.get_config_int(context, "sentbox_watch", 1);
|
||||
let mvbox_watch = context.sql.get_config_int(context, "mvbox_watch", 1);
|
||||
let mvbox_move = context.sql.get_config_int(context, "mvbox_move", 1);
|
||||
let folders_configured = context.sql.get_config_int(context, "folders_configured", 0);
|
||||
let configured_sentbox_folder =
|
||||
context
|
||||
.sql
|
||||
.get_config(context, "configured_sentbox_folder", Some("<unset>"));
|
||||
let configured_mvbox_folder =
|
||||
context
|
||||
.sql
|
||||
.get_config(context, "configured_mvbox_folder", Some("<unset>"));
|
||||
|
||||
let res = format!(
|
||||
"deltachat_core_version=v{}\n\
|
||||
@@ -502,8 +481,8 @@ pub unsafe fn dc_get_info(context: &Context) -> *mut libc::c_char {
|
||||
mvbox_watch,
|
||||
mvbox_move,
|
||||
folders_configured,
|
||||
configured_sentbox_folder,
|
||||
configured_mvbox_folder,
|
||||
configured_sentbox_folder.unwrap_or_default(),
|
||||
configured_mvbox_folder.unwrap_or_default(),
|
||||
mdns_enabled,
|
||||
e2ee_enabled,
|
||||
prv_key_cnt.unwrap_or_default(),
|
||||
@@ -604,7 +583,9 @@ pub fn dc_is_inbox(_context: &Context, folder_name: impl AsRef<str>) -> bool {
|
||||
}
|
||||
|
||||
pub fn dc_is_sentbox(context: &Context, folder_name: impl AsRef<str>) -> bool {
|
||||
let sentbox_name = context.sql.get_config(context, "configured_sentbox_folder");
|
||||
let sentbox_name = context
|
||||
.sql
|
||||
.get_config(context, "configured_sentbox_folder", None);
|
||||
if let Some(name) = sentbox_name {
|
||||
name == folder_name.as_ref()
|
||||
} else {
|
||||
@@ -613,7 +594,9 @@ pub fn dc_is_sentbox(context: &Context, folder_name: impl AsRef<str>) -> bool {
|
||||
}
|
||||
|
||||
pub fn dc_is_mvbox(context: &Context, folder_name: impl AsRef<str>) -> bool {
|
||||
let mvbox_name = context.sql.get_config(context, "configured_mvbox_folder");
|
||||
let mvbox_name = context
|
||||
.sql
|
||||
.get_config(context, "configured_mvbox_folder", None);
|
||||
|
||||
if let Some(name) = mvbox_name {
|
||||
name == folder_name.as_ref()
|
||||
|
||||
108
src/dc_chat.rs
108
src/dc_chat.rs
@@ -107,7 +107,6 @@ pub fn dc_block_chat(context: &Context, chat_id: u32, new_blocking: libc::c_int)
|
||||
"UPDATE chats SET blocked=? WHERE id=?;",
|
||||
params![new_blocking, chat_id as i32],
|
||||
)
|
||||
.is_ok()
|
||||
}
|
||||
|
||||
pub fn dc_chat_load_from_db(chat: *mut Chat, chat_id: u32) -> bool {
|
||||
@@ -277,7 +276,7 @@ pub unsafe fn dc_create_or_lookup_nchat_by_contact_id(
|
||||
as_str((*contact).addr),
|
||||
),
|
||||
params![],
|
||||
).is_ok() {
|
||||
) {
|
||||
chat_id = sql::get_rowid(
|
||||
context,
|
||||
&context.sql,
|
||||
@@ -485,7 +484,7 @@ unsafe fn prepare_msg_raw(
|
||||
"Cannot send message; self not in group.",
|
||||
);
|
||||
} else {
|
||||
let from = context.sql.get_config(context, "configured_addr");
|
||||
let from = context.sql.get_config(context, "configured_addr", None);
|
||||
if from.is_none() {
|
||||
error!(context, 0, "Cannot send message, not configured.",);
|
||||
} else {
|
||||
@@ -534,22 +533,18 @@ unsafe fn prepare_msg_raw(
|
||||
so that E2EE is no longer available at a later point (reset, changed settings),
|
||||
we do not send the message out at all */
|
||||
do_guarantee_e2ee = 0;
|
||||
e2ee_enabled = context
|
||||
.sql
|
||||
.get_config_int(context, "e2ee_enabled")
|
||||
.unwrap_or_else(|| 1);
|
||||
e2ee_enabled = context.sql.get_config_int(context, "e2ee_enabled", 1);
|
||||
if 0 != e2ee_enabled && dc_param_get_int((*msg).param, 'u' as i32, 0) == 0 {
|
||||
let mut can_encrypt = 1;
|
||||
let mut all_mutual = 1;
|
||||
let mut can_encrypt: libc::c_int = 1;
|
||||
let mut all_mutual: libc::c_int = 1;
|
||||
|
||||
let res = context.sql.query_row(
|
||||
context.sql.query_row(
|
||||
"SELECT ps.prefer_encrypted, c.addr \
|
||||
FROM chats_contacts cc \
|
||||
LEFT JOIN contacts c ON cc.contact_id=c.id \
|
||||
LEFT JOIN acpeerstates ps ON c.addr=ps.addr \
|
||||
WHERE cc.chat_id=? AND cc.contact_id>9;",
|
||||
params![(*chat).id],
|
||||
|row| {
|
||||
params![(*chat).id], |row| {
|
||||
let state: String = row.get(1)?;
|
||||
|
||||
if let Some(prefer_encrypted) = row.get::<_, Option<i32>>(0)? {
|
||||
@@ -573,14 +568,8 @@ unsafe fn prepare_msg_raw(
|
||||
all_mutual = 0;
|
||||
}
|
||||
Ok(())
|
||||
},
|
||||
);
|
||||
match res {
|
||||
Ok(_) => {}
|
||||
Err(err) => {
|
||||
warn!(context, 0, "chat: failed to load peerstates: {:?}", err);
|
||||
}
|
||||
}
|
||||
).unwrap();
|
||||
|
||||
if 0 != can_encrypt {
|
||||
if 0 != all_mutual {
|
||||
@@ -671,9 +660,7 @@ unsafe fn prepare_msg_raw(
|
||||
0.0,
|
||||
),
|
||||
],
|
||||
)
|
||||
.is_ok()
|
||||
{
|
||||
) {
|
||||
location_id = sql::get_rowid2(
|
||||
context,
|
||||
&context.sql,
|
||||
@@ -707,7 +694,7 @@ unsafe fn prepare_msg_raw(
|
||||
to_string(new_references),
|
||||
location_id as i32,
|
||||
]
|
||||
).is_ok() {
|
||||
) {
|
||||
msg_id = sql::get_rowid(
|
||||
context,
|
||||
&context.sql,
|
||||
@@ -841,8 +828,7 @@ pub unsafe fn dc_chat_update_param(chat: *mut Chat) -> libc::c_int {
|
||||
&(*chat).context.sql,
|
||||
"UPDATE chats SET param=? WHERE id=?",
|
||||
params![to_string((*(*chat).param).packed), (*chat).id as i32],
|
||||
)
|
||||
.is_ok() as libc::c_int
|
||||
) as libc::c_int
|
||||
}
|
||||
|
||||
pub unsafe fn dc_is_contact_in_chat(
|
||||
@@ -1013,7 +999,7 @@ unsafe fn set_draft_raw(context: &Context, chat_id: uint32_t, msg: *mut dc_msg_t
|
||||
to_string((*(*msg).param).packed),
|
||||
1,
|
||||
]
|
||||
).is_ok() {
|
||||
) {
|
||||
sth_changed = 1;
|
||||
}
|
||||
}
|
||||
@@ -1089,10 +1075,7 @@ pub unsafe fn dc_get_chat_msgs(
|
||||
};
|
||||
|
||||
let success = if chat_id == 1 {
|
||||
let show_emails = context
|
||||
.sql
|
||||
.get_config_int(context, "show_emails")
|
||||
.unwrap_or_default();
|
||||
let show_emails = context.sql.get_config_int(context, "show_emails", 0);
|
||||
context.sql.query_map(
|
||||
"SELECT m.id, m.timestamp FROM msgs m \
|
||||
LEFT JOIN chats ON m.chat_id=chats.id \
|
||||
@@ -1178,15 +1161,13 @@ pub fn dc_marknoticed_chat(context: &Context, chat_id: u32) -> bool {
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if sql::execute(
|
||||
if !sql::execute(
|
||||
context,
|
||||
&context.sql,
|
||||
"UPDATE msgs \
|
||||
SET state=13 WHERE chat_id=? AND state=10;",
|
||||
params![chat_id as i32],
|
||||
)
|
||||
.is_err()
|
||||
{
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
context.call_cb(Event::MSGS_CHANGED, 0 as uintptr_t, 0 as uintptr_t);
|
||||
@@ -1206,15 +1187,13 @@ pub fn dc_marknoticed_all_chats(context: &Context) -> bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
if sql::execute(
|
||||
if !sql::execute(
|
||||
context,
|
||||
&context.sql,
|
||||
"UPDATE msgs \
|
||||
SET state=13 WHERE state=10;",
|
||||
params![],
|
||||
)
|
||||
.is_err()
|
||||
{
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1314,25 +1293,21 @@ pub fn dc_archive_chat(context: &Context, chat_id: u32, archive: libc::c_int) ->
|
||||
return true;
|
||||
}
|
||||
if 0 != archive {
|
||||
if sql::execute(
|
||||
if !sql::execute(
|
||||
context,
|
||||
&context.sql,
|
||||
"UPDATE msgs SET state=13 WHERE chat_id=? AND state=10;",
|
||||
params![chat_id as i32],
|
||||
)
|
||||
.is_err()
|
||||
{
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if sql::execute(
|
||||
if !sql::execute(
|
||||
context,
|
||||
&context.sql,
|
||||
"UPDATE chats SET archived=? WHERE id=?;",
|
||||
params![archive, chat_id as i32],
|
||||
)
|
||||
.is_err()
|
||||
{
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
context.call_cb(Event::MSGS_CHANGED, 0 as uintptr_t, 0 as uintptr_t);
|
||||
@@ -1351,44 +1326,36 @@ pub fn dc_delete_chat(context: &Context, chat_id: u32) -> bool {
|
||||
}
|
||||
unsafe { dc_chat_unref(obj) };
|
||||
|
||||
if sql::execute(
|
||||
if !sql::execute(
|
||||
context,
|
||||
&context.sql,
|
||||
"DELETE FROM msgs_mdns WHERE msg_id IN (SELECT id FROM msgs WHERE chat_id=?);",
|
||||
params![chat_id as i32],
|
||||
)
|
||||
.is_err()
|
||||
{
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
if sql::execute(
|
||||
if !sql::execute(
|
||||
context,
|
||||
&context.sql,
|
||||
"DELETE FROM msgs WHERE chat_id=?;",
|
||||
params![chat_id as i32],
|
||||
)
|
||||
.is_err()
|
||||
{
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
if sql::execute(
|
||||
if !sql::execute(
|
||||
context,
|
||||
&context.sql,
|
||||
"DELETE FROM chats_contacts WHERE chat_id=?;",
|
||||
params![chat_id as i32],
|
||||
)
|
||||
.is_err()
|
||||
{
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
if sql::execute(
|
||||
if !sql::execute(
|
||||
context,
|
||||
&context.sql,
|
||||
"DELETE FROM chats WHERE id=?;",
|
||||
params![chat_id as i32],
|
||||
)
|
||||
.is_err()
|
||||
{
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1472,9 +1439,7 @@ pub unsafe fn dc_create_group_chat(
|
||||
as_str(chat_name),
|
||||
grpid
|
||||
],
|
||||
)
|
||||
.is_ok()
|
||||
{
|
||||
) {
|
||||
chat_id = sql::get_rowid(context, &context.sql, "chats", "grpid", grpid);
|
||||
if chat_id != 0 {
|
||||
if 0 != dc_add_to_chat_contacts_table(context, chat_id, 1) {
|
||||
@@ -1510,8 +1475,7 @@ pub fn dc_add_to_chat_contacts_table(
|
||||
&context.sql,
|
||||
"INSERT INTO chats_contacts (chat_id, contact_id) VALUES(?, ?)",
|
||||
params![chat_id as i32, contact_id as i32],
|
||||
)
|
||||
.is_ok() as libc::c_int
|
||||
) as libc::c_int
|
||||
}
|
||||
|
||||
pub unsafe fn dc_add_contact_to_chat(
|
||||
@@ -1557,7 +1521,7 @@ pub unsafe fn dc_add_contact_to_chat_ex(
|
||||
}
|
||||
let self_addr = context
|
||||
.sql
|
||||
.get_config(context, "configured_addr")
|
||||
.get_config(context, "configured_addr", Some(""))
|
||||
.unwrap_or_default();
|
||||
if as_str((*contact).addr) != &self_addr {
|
||||
// ourself is added using DC_CONTACT_ID_SELF, do not add it explicitly.
|
||||
@@ -1747,9 +1711,7 @@ pub unsafe fn dc_remove_contact_from_chat(
|
||||
&context.sql,
|
||||
"DELETE FROM chats_contacts WHERE chat_id=? AND contact_id=?;",
|
||||
params![chat_id as i32, contact_id as i32],
|
||||
)
|
||||
.is_ok()
|
||||
{
|
||||
) {
|
||||
context.call_cb(Event::CHAT_MODIFIED, chat_id as uintptr_t, 0 as uintptr_t);
|
||||
success = 1;
|
||||
}
|
||||
@@ -1822,9 +1784,7 @@ pub unsafe fn dc_set_chat_name(
|
||||
chat_id as i32
|
||||
),
|
||||
params![],
|
||||
)
|
||||
.is_ok()
|
||||
{
|
||||
) {
|
||||
if dc_param_get_int((*chat).param, 'U' as i32, 0i32) == 0i32 {
|
||||
(*msg).type_0 = 10i32;
|
||||
(*msg).text = dc_stock_system_msg(
|
||||
|
||||
@@ -74,12 +74,7 @@ pub unsafe fn dc_has_ongoing(context: &Context) -> libc::c_int {
|
||||
}
|
||||
}
|
||||
pub fn dc_is_configured(context: &Context) -> libc::c_int {
|
||||
if context
|
||||
.sql
|
||||
.get_config_int(context, "configured")
|
||||
.unwrap_or_default()
|
||||
> 0
|
||||
{
|
||||
if context.sql.get_config_int(context, "configured", 0) > 0 {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
@@ -907,18 +902,14 @@ pub unsafe fn dc_job_do_DC_JOB_CONFIGURE_IMAP(context: &Context, _job: *mut dc_j
|
||||
.get_config_int(
|
||||
context,
|
||||
"mvbox_watch",
|
||||
)
|
||||
.unwrap_or_else(
|
||||
|| 1,
|
||||
1,
|
||||
)
|
||||
|| 0 != context
|
||||
.sql
|
||||
.get_config_int(
|
||||
context,
|
||||
"mvbox_move",
|
||||
)
|
||||
.unwrap_or_else(
|
||||
|| 1,
|
||||
1,
|
||||
) {
|
||||
0x1
|
||||
} else {
|
||||
@@ -1491,12 +1482,7 @@ pub fn dc_connect_to_configured_imap(context: &Context, imap: &Imap) -> libc::c_
|
||||
|
||||
if imap.is_connected() {
|
||||
ret_connected = 1
|
||||
} else if context
|
||||
.sql
|
||||
.get_config_int(context, "configured")
|
||||
.unwrap_or_default()
|
||||
== 0
|
||||
{
|
||||
} else if context.sql.get_config_int(context, "configured", 0) == 0 {
|
||||
warn!(context, 0, "Not configured, cannot connect.",);
|
||||
} else {
|
||||
let param = dc_loginparam_read(context, &context.sql, "configured_");
|
||||
|
||||
@@ -34,9 +34,7 @@ pub fn dc_marknoticed_contact(context: &Context, contact_id: u32) {
|
||||
&context.sql,
|
||||
"UPDATE msgs SET state=13 WHERE from_id=? AND state=10;",
|
||||
params![contact_id as i32],
|
||||
)
|
||||
.is_ok()
|
||||
{
|
||||
) {
|
||||
context.call_cb(Event::MSGS_CHANGED, 0, 0);
|
||||
}
|
||||
}
|
||||
@@ -74,7 +72,7 @@ pub unsafe fn dc_lookup_contact_id_by_addr(
|
||||
let addr_normalized = as_str(addr_normalized_c);
|
||||
let addr_self = context
|
||||
.sql
|
||||
.get_config(context, "configured_addr")
|
||||
.get_config(context, "configured_addr", None)
|
||||
.unwrap_or_default();
|
||||
|
||||
let contact_id = if addr_normalized == addr_self {
|
||||
@@ -163,9 +161,7 @@ pub unsafe fn dc_block_contact(context: &Context, contact_id: uint32_t, new_bloc
|
||||
&context.sql,
|
||||
"UPDATE contacts SET blocked=? WHERE id=?;",
|
||||
params![new_blocking, contact_id as i32],
|
||||
)
|
||||
.is_ok()
|
||||
{
|
||||
) {
|
||||
// also (un)block all chats with _only_ this contact - we do not delete them to allow a
|
||||
// non-destructive blocking->unblocking.
|
||||
// (Maybe, beside normal chats (type=100) we should also block group chats with only this user.
|
||||
@@ -176,7 +172,7 @@ pub unsafe fn dc_block_contact(context: &Context, contact_id: uint32_t, new_bloc
|
||||
&context.sql,
|
||||
"UPDATE chats SET blocked=? WHERE type=? AND id IN (SELECT chat_id FROM chats_contacts WHERE contact_id=?);",
|
||||
params![new_blocking, 100, contact_id as i32],
|
||||
).is_ok() {
|
||||
) {
|
||||
dc_marknoticed_contact(context, contact_id);
|
||||
context.call_cb(
|
||||
Event::CONTACTS_CHANGED,
|
||||
@@ -282,7 +278,7 @@ pub unsafe fn dc_contact_load_from_db(
|
||||
(*contact)
|
||||
.context
|
||||
.sql
|
||||
.get_config((*contact).context, "configured_addr")
|
||||
.get_config((*contact).context, "configured_addr", Some(""))
|
||||
.unwrap_or_default(),
|
||||
)
|
||||
.as_ptr(),
|
||||
@@ -341,7 +337,7 @@ pub fn dc_add_or_lookup_contact(
|
||||
let addr = as_str(addr_c);
|
||||
let addr_self = context
|
||||
.sql
|
||||
.get_config(context, "configured_addr")
|
||||
.get_config(context, "configured_addr", Some(""))
|
||||
.unwrap_or_default();
|
||||
|
||||
if addr == addr_self {
|
||||
@@ -439,9 +435,7 @@ pub fn dc_add_or_lookup_contact(
|
||||
&context.sql,
|
||||
"INSERT INTO contacts (name, addr, origin) VALUES(?, ?, ?);",
|
||||
params![to_string(name), addr, origin,],
|
||||
)
|
||||
.is_ok()
|
||||
{
|
||||
) {
|
||||
row_id = sql::get_rowid(context, &context.sql, "contacts", "addr", addr);
|
||||
unsafe { *sth_modified = 2 };
|
||||
} else {
|
||||
@@ -533,7 +527,7 @@ pub fn dc_get_contacts(
|
||||
) -> *mut dc_array_t {
|
||||
let self_addr = context
|
||||
.sql
|
||||
.get_config(context, "configured_addr")
|
||||
.get_config(context, "configured_addr", Some(""))
|
||||
.unwrap_or_default();
|
||||
|
||||
let mut add_self = false;
|
||||
@@ -574,7 +568,7 @@ pub fn dc_get_contacts(
|
||||
|
||||
let self_name = context
|
||||
.sql
|
||||
.get_config(context, "displayname")
|
||||
.get_config(context, "displayname", Some(""))
|
||||
.unwrap_or_default();
|
||||
|
||||
let self_name2 = unsafe { dc_stock_str(context, 2) };
|
||||
@@ -804,9 +798,7 @@ pub fn dc_delete_contact(context: &Context, contact_id: u32) -> bool {
|
||||
&context.sql,
|
||||
"DELETE FROM contacts WHERE id=?;",
|
||||
params![contact_id as i32],
|
||||
)
|
||||
.is_ok()
|
||||
{
|
||||
) {
|
||||
context.call_cb(Event::CONTACTS_CHANGED, 0, 0);
|
||||
true
|
||||
} else {
|
||||
@@ -903,8 +895,8 @@ pub fn dc_contact_get_profile_image(contact: *const dc_contact_t) -> *mut libc::
|
||||
}
|
||||
|
||||
if unsafe { (*contact).id } == 1 {
|
||||
let context = unsafe { (*contact) }.context;
|
||||
if let Some(avatar) = context.get_config(config::Config::Selfavatar) {
|
||||
let avatar = config::get(unsafe { (*contact).context }, "selfavatar");
|
||||
if !avatar.is_empty() {
|
||||
image_abs = unsafe { dc_strdup(to_cstring(avatar).as_ptr()) };
|
||||
}
|
||||
}
|
||||
@@ -995,7 +987,7 @@ pub fn dc_addr_equals_self(context: &Context, addr: *const libc::c_char) -> libc
|
||||
|
||||
if !addr.is_null() {
|
||||
let normalized_addr = unsafe { dc_addr_normalize(addr) };
|
||||
if let Some(self_addr) = context.sql.get_config(context, "configured_addr") {
|
||||
if let Some(self_addr) = context.sql.get_config(context, "configured_addr", None) {
|
||||
ret = (as_str(normalized_addr) == self_addr) as libc::c_int;
|
||||
}
|
||||
unsafe { free(normalized_addr as *mut libc::c_void) };
|
||||
|
||||
@@ -80,18 +80,13 @@ pub unsafe fn dc_e2ee_encrypt(
|
||||
|| plain.is_null())
|
||||
{
|
||||
/* libEtPan's pgp_encrypt_mime() takes the parent as the new root. We just expect the root as being given to this function. */
|
||||
let prefer_encrypt = if 0
|
||||
!= context
|
||||
.sql
|
||||
.get_config_int(context, "e2ee_enabled")
|
||||
.unwrap_or_default()
|
||||
{
|
||||
let prefer_encrypt = if 0 != context.sql.get_config_int(context, "e2ee_enabled", 1) {
|
||||
EncryptPreference::Mutual
|
||||
} else {
|
||||
EncryptPreference::NoPreference
|
||||
};
|
||||
|
||||
let addr = context.sql.get_config(context, "configured_addr");
|
||||
let addr = context.sql.get_config(context, "configured_addr", None);
|
||||
|
||||
if let Some(addr) = addr {
|
||||
if let Some(public_key) =
|
||||
@@ -601,7 +596,7 @@ pub unsafe fn dc_e2ee_decrypt(
|
||||
}
|
||||
}
|
||||
/* load private key for decryption */
|
||||
let self_addr = context.sql.get_config(context, "configured_addr");
|
||||
let self_addr = context.sql.get_config(context, "configured_addr", None);
|
||||
if let Some(self_addr) = self_addr {
|
||||
if private_keyring.load_self_private_for_decrypting(context, self_addr, &context.sql) {
|
||||
if peerstate.as_ref().map(|p| p.last_seen).unwrap_or_else(|| 0) == 0 {
|
||||
@@ -1070,7 +1065,7 @@ pub unsafe fn dc_ensure_secret_key_exists(context: &Context) -> libc::c_int {
|
||||
(this is to gain some extra-random-seed by the message content and the timespan between program start and message sending) */
|
||||
let mut success: libc::c_int = 0i32;
|
||||
|
||||
let self_addr = context.sql.get_config(context, "configured_addr");
|
||||
let self_addr = context.sql.get_config(context, "configured_addr", None);
|
||||
if self_addr.is_none() {
|
||||
warn!(
|
||||
context,
|
||||
|
||||
@@ -69,9 +69,7 @@ pub unsafe fn dc_imex_has_backup(
|
||||
if name.starts_with("delta-chat") && name.ends_with(".bak") {
|
||||
let sql = Sql::new();
|
||||
if sql.open(context, &path, 0x1) {
|
||||
let curr_backup_time =
|
||||
sql.get_config_int(context, "backup_time")
|
||||
.unwrap_or_default() as u64;
|
||||
let curr_backup_time = sql.get_config_int(context, "backup_time", 0) as u64;
|
||||
if curr_backup_time > newest_backup_time {
|
||||
newest_backup_path = Some(path);
|
||||
newest_backup_time = curr_backup_time;
|
||||
@@ -226,13 +224,10 @@ pub unsafe extern "C" fn dc_render_setup_file(
|
||||
if !(0 == dc_ensure_secret_key_exists(context)) {
|
||||
let self_addr = context
|
||||
.sql
|
||||
.get_config(context, "configured_addr")
|
||||
.get_config(context, "configured_addr", None)
|
||||
.unwrap_or_default();
|
||||
let curr_private_key = Key::from_self_private(context, self_addr, &context.sql);
|
||||
let e2ee_enabled = context
|
||||
.sql
|
||||
.get_config_int(context, "e2ee_enabled")
|
||||
.unwrap_or_else(|| 1);
|
||||
let e2ee_enabled = context.sql.get_config_int(context, "e2ee_enabled", 1);
|
||||
|
||||
let headers = if 0 != e2ee_enabled {
|
||||
Some(("Autocrypt-Prefer-Encrypt", "mutual"))
|
||||
@@ -393,33 +388,29 @@ fn set_self_key(
|
||||
let (private_key, public_key, header) = keys.unwrap();
|
||||
let preferencrypt = header.get("Autocrypt-Prefer-Encrypt");
|
||||
|
||||
if sql::execute(
|
||||
if !sql::execute(
|
||||
context,
|
||||
&context.sql,
|
||||
"DELETE FROM keypairs WHERE public_key=? OR private_key=?;",
|
||||
params![public_key.to_bytes(), private_key.to_bytes()],
|
||||
)
|
||||
.is_err()
|
||||
{
|
||||
) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if 0 != set_default {
|
||||
if sql::execute(
|
||||
if !sql::execute(
|
||||
context,
|
||||
&context.sql,
|
||||
"UPDATE keypairs SET is_default=0;",
|
||||
params![],
|
||||
)
|
||||
.is_err()
|
||||
{
|
||||
) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
error!(context, 0, "File does not contain a private key.",);
|
||||
}
|
||||
|
||||
let self_addr = context.sql.get_config(context, "configured_addr");
|
||||
let self_addr = context.sql.get_config(context, "configured_addr", None);
|
||||
|
||||
if self_addr.is_none() {
|
||||
error!(context, 0, "Missing self addr");
|
||||
@@ -440,14 +431,8 @@ fn set_self_key(
|
||||
|
||||
match preferencrypt.map(|s| s.as_str()) {
|
||||
Some("") => 0,
|
||||
Some("nopreference") => context
|
||||
.sql
|
||||
.set_config_int(context, "e2ee_enabled", 0)
|
||||
.is_ok() as libc::c_int,
|
||||
Some("mutual") => context
|
||||
.sql
|
||||
.set_config_int(context, "e2ee_enabled", 1)
|
||||
.is_ok() as libc::c_int,
|
||||
Some("nopreference") => context.sql.set_config_int(context, "e2ee_enabled", 0),
|
||||
Some("mutual") => context.sql.set_config_int(context, "e2ee_enabled", 1),
|
||||
_ => 1,
|
||||
}
|
||||
}
|
||||
@@ -871,7 +856,7 @@ unsafe fn import_backup(context: &Context, backup_to_import: *const libc::c_char
|
||||
if !loop_success {
|
||||
return Err(format_err!("fail").into());
|
||||
}
|
||||
sql::execute(context, &context.sql, "DROP TABLE backup_blobs;", params![])?;
|
||||
sql::execute(context, &context.sql, "DROP TABLE backup_blobs;", params![]);
|
||||
sql::try_execute(context, &context.sql, "VACUUM;");
|
||||
Ok(())
|
||||
},
|
||||
@@ -924,14 +909,12 @@ unsafe fn export_backup(context: &Context, dir: *const libc::c_char) -> libc::c_
|
||||
let sql = Sql::new();
|
||||
if sql.open(context, as_path(dest_pathNfilename), 0) {
|
||||
if !sql.table_exists("backup_blobs") {
|
||||
if sql::execute(
|
||||
if !sql::execute(
|
||||
context,
|
||||
&sql,
|
||||
"CREATE TABLE backup_blobs (id INTEGER PRIMARY KEY, file_name, file_content);",
|
||||
params![],
|
||||
)
|
||||
.is_err()
|
||||
{
|
||||
) {
|
||||
/* error already logged */
|
||||
current_block = 11487273724841241105;
|
||||
} else {
|
||||
@@ -1054,10 +1037,7 @@ unsafe fn export_backup(context: &Context, dir: *const libc::c_char) -> libc::c_
|
||||
match current_block {
|
||||
11487273724841241105 => {}
|
||||
_ => {
|
||||
if sql
|
||||
.set_config_int(context, "backup_time", now as i32)
|
||||
.is_ok()
|
||||
{
|
||||
if 0 != sql.set_config_int(context, "backup_time", now as i32) {
|
||||
context.call_cb(
|
||||
Event::IMEX_FILE_WRITTEN,
|
||||
dest_pathNfilename as uintptr_t,
|
||||
|
||||
@@ -259,7 +259,6 @@ fn dc_job_update(context: &Context, job: &dc_job_t) -> bool {
|
||||
job.job_id as i32,
|
||||
],
|
||||
)
|
||||
.is_ok()
|
||||
}
|
||||
|
||||
unsafe fn dc_suspend_smtp_thread(context: &Context, suspend: libc::c_int) {
|
||||
@@ -416,15 +415,12 @@ unsafe fn dc_job_do_DC_JOB_MOVE_MSG(context: &Context, job: &mut dc_job_t) {
|
||||
match current_block {
|
||||
2473556513754201174 => {
|
||||
if dc_msg_load_from_db(msg, context, job.foreign_id) {
|
||||
if context
|
||||
.sql
|
||||
.get_config_int(context, "folders_configured")
|
||||
.unwrap_or_default()
|
||||
< 3
|
||||
{
|
||||
if context.sql.get_config_int(context, "folders_configured", 0) < 3 {
|
||||
inbox.configure_folders(context, 0x1i32);
|
||||
}
|
||||
let dest_folder = context.sql.get_config(context, "configured_mvbox_folder");
|
||||
let dest_folder = context
|
||||
.sql
|
||||
.get_config(context, "configured_mvbox_folder", None);
|
||||
|
||||
if let Some(dest_folder) = dest_folder {
|
||||
let server_folder = as_str((*msg).server_folder);
|
||||
@@ -516,15 +512,12 @@ unsafe fn dc_job_do_DC_JOB_MARKSEEN_MDN_ON_IMAP(context: &Context, job: &mut dc_
|
||||
dc_job_try_again_later(job, 3i32, 0 as *const libc::c_char);
|
||||
}
|
||||
if 0 != dc_param_get_int(job.param, 'M' as i32, 0i32) {
|
||||
if context
|
||||
.sql
|
||||
.get_config_int(context, "folders_configured")
|
||||
.unwrap_or_default()
|
||||
< 3
|
||||
{
|
||||
if context.sql.get_config_int(context, "folders_configured", 0) < 3 {
|
||||
inbox.configure_folders(context, 0x1i32);
|
||||
}
|
||||
let dest_folder = context.sql.get_config(context, "configured_mvbox_folder");
|
||||
let dest_folder = context
|
||||
.sql
|
||||
.get_config(context, "configured_mvbox_folder", None);
|
||||
if let Some(dest_folder) = dest_folder {
|
||||
if 1 == inbox.mv(context, folder, uid, dest_folder, &mut dest_uid)
|
||||
as libc::c_uint
|
||||
@@ -569,10 +562,7 @@ unsafe fn dc_job_do_DC_JOB_MARKSEEN_MSG_ON_IMAP(context: &Context, job: &mut dc_
|
||||
}
|
||||
_ => {
|
||||
if 0 != dc_param_get_int((*msg).param, 'r' as i32, 0i32)
|
||||
&& 0 != context
|
||||
.sql
|
||||
.get_config_int(context, "mdns_enabled")
|
||||
.unwrap_or_else(|| 1)
|
||||
&& 0 != context.sql.get_config_int(context, "mdns_enabled", 1)
|
||||
{
|
||||
let folder =
|
||||
CStr::from_ptr((*msg).server_folder).to_str().unwrap();
|
||||
@@ -623,10 +613,7 @@ unsafe fn dc_job_do_DC_JOB_MARKSEEN_MSG_ON_IMAP(context: &Context, job: &mut dc_
|
||||
}
|
||||
_ => {
|
||||
if 0 != dc_param_get_int((*msg).param, 'r' as i32, 0i32)
|
||||
&& 0 != context
|
||||
.sql
|
||||
.get_config_int(context, "mdns_enabled")
|
||||
.unwrap_or_else(|| 1)
|
||||
&& 0 != context.sql.get_config_int(context, "mdns_enabled", 1)
|
||||
{
|
||||
let folder =
|
||||
CStr::from_ptr((*msg).server_folder).to_str().unwrap();
|
||||
@@ -906,7 +893,6 @@ pub fn dc_job_kill_action(context: &Context, action: libc::c_int) -> bool {
|
||||
"DELETE FROM jobs WHERE action=?;",
|
||||
params![action],
|
||||
)
|
||||
.is_ok()
|
||||
}
|
||||
|
||||
pub unsafe fn dc_perform_imap_fetch(context: &Context) {
|
||||
@@ -916,12 +902,7 @@ pub unsafe fn dc_perform_imap_fetch(context: &Context) {
|
||||
if 0 == connect_to_inbox(context, &inbox) {
|
||||
return;
|
||||
}
|
||||
if context
|
||||
.sql
|
||||
.get_config_int(context, "inbox_watch")
|
||||
.unwrap_or_else(|| 1)
|
||||
== 0
|
||||
{
|
||||
if context.sql.get_config_int(context, "inbox_watch", 1) == 0 {
|
||||
info!(context, 0, "INBOX-watch disabled.",);
|
||||
return;
|
||||
}
|
||||
@@ -957,10 +938,7 @@ pub fn dc_perform_imap_idle(context: &Context) {
|
||||
}
|
||||
|
||||
pub unsafe fn dc_perform_mvbox_fetch(context: &Context) {
|
||||
let use_network = context
|
||||
.sql
|
||||
.get_config_int(context, "mvbox_watch")
|
||||
.unwrap_or_else(|| 1);
|
||||
let use_network = context.sql.get_config_int(context, "mvbox_watch", 1);
|
||||
dc_jobthread_fetch(
|
||||
context,
|
||||
&mut context.mvbox_thread.clone().write().unwrap(),
|
||||
@@ -969,10 +947,7 @@ pub unsafe fn dc_perform_mvbox_fetch(context: &Context) {
|
||||
}
|
||||
|
||||
pub unsafe fn dc_perform_mvbox_idle(context: &Context) {
|
||||
let use_network = context
|
||||
.sql
|
||||
.get_config_int(context, "mvbox_watch")
|
||||
.unwrap_or_else(|| 1);
|
||||
let use_network = context.sql.get_config_int(context, "mvbox_watch", 1);
|
||||
|
||||
dc_jobthread_idle(
|
||||
context,
|
||||
@@ -986,10 +961,7 @@ pub unsafe fn dc_interrupt_mvbox_idle(context: &Context) {
|
||||
}
|
||||
|
||||
pub unsafe fn dc_perform_sentbox_fetch(context: &Context) {
|
||||
let use_network = context
|
||||
.sql
|
||||
.get_config_int(context, "sentbox_watch")
|
||||
.unwrap_or_else(|| 1);
|
||||
let use_network = context.sql.get_config_int(context, "sentbox_watch", 1);
|
||||
dc_jobthread_fetch(
|
||||
context,
|
||||
&mut context.sentbox_thread.clone().write().unwrap(),
|
||||
@@ -998,10 +970,7 @@ pub unsafe fn dc_perform_sentbox_fetch(context: &Context) {
|
||||
}
|
||||
|
||||
pub unsafe fn dc_perform_sentbox_idle(context: &Context) {
|
||||
let use_network = context
|
||||
.sql
|
||||
.get_config_int(context, "sentbox_watch")
|
||||
.unwrap_or_else(|| 1);
|
||||
let use_network = context.sql.get_config_int(context, "sentbox_watch", 1);
|
||||
dc_jobthread_idle(
|
||||
context,
|
||||
&context.sentbox_thread.clone().read().unwrap(),
|
||||
|
||||
@@ -136,18 +136,14 @@ unsafe fn connect_to_imap(context: &Context, jobthread: &dc_jobthread_t) -> libc
|
||||
let mut ret_connected = dc_connect_to_configured_imap(context, &jobthread.imap);
|
||||
|
||||
if !(0 == ret_connected) {
|
||||
if context
|
||||
.sql
|
||||
.get_config_int(context, "folders_configured")
|
||||
.unwrap_or_default()
|
||||
< 3
|
||||
{
|
||||
if context.sql.get_config_int(context, "folders_configured", 0) < 3 {
|
||||
jobthread.imap.configure_folders(context, 0x1);
|
||||
}
|
||||
|
||||
if let Some(mvbox_name) = context
|
||||
.sql
|
||||
.get_config(context, jobthread.folder_config_name)
|
||||
if let Some(mvbox_name) =
|
||||
context
|
||||
.sql
|
||||
.get_config(context, jobthread.folder_config_name, None)
|
||||
{
|
||||
jobthread.imap.set_watch_folder(mvbox_name);
|
||||
} else {
|
||||
|
||||
@@ -64,9 +64,7 @@ pub unsafe fn dc_send_locations_to_chat(
|
||||
},
|
||||
chat_id as i32,
|
||||
],
|
||||
)
|
||||
.is_ok()
|
||||
{
|
||||
) {
|
||||
if 0 != seconds && !is_sending_locations_before {
|
||||
msg = dc_msg_new(context, 10i32);
|
||||
(*msg).text = dc_stock_system_msg(
|
||||
@@ -246,7 +244,7 @@ unsafe fn is_marker(txt: *const libc::c_char) -> libc::c_int {
|
||||
}
|
||||
|
||||
pub fn dc_delete_all_locations(context: &Context) -> bool {
|
||||
if sql::execute(context, &context.sql, "DELETE FROM locations;", params![]).is_err() {
|
||||
if !sql::execute(context, &context.sql, "DELETE FROM locations;", params![]) {
|
||||
return false;
|
||||
}
|
||||
context.call_cb(Event::LOCATION_CHANGED, 0, 0);
|
||||
@@ -263,10 +261,13 @@ pub fn dc_get_location_kml(
|
||||
let mut location_count: libc::c_int = 0;
|
||||
let mut ret = String::new();
|
||||
|
||||
let self_addr = context
|
||||
.sql
|
||||
.get_config(context, "configured_addr")
|
||||
.unwrap_or_default();
|
||||
let self_addr = context.sql.get_config(context, "configured_addr", Some(""));
|
||||
|
||||
if self_addr.is_none() {
|
||||
return std::ptr::null_mut();
|
||||
}
|
||||
|
||||
let self_addr = self_addr.unwrap();
|
||||
|
||||
if let Ok((locations_send_begin, locations_send_until, locations_last_sent)) = context.sql.query_row(
|
||||
"SELECT locations_send_begin, locations_send_until, locations_last_sent FROM chats WHERE id=?;",
|
||||
@@ -385,7 +386,6 @@ pub fn dc_set_kml_sent_timestamp(context: &Context, chat_id: u32, timestamp: i64
|
||||
"UPDATE chats SET locations_last_sent=? WHERE id=?;",
|
||||
params![timestamp, chat_id as i32],
|
||||
)
|
||||
.is_ok()
|
||||
}
|
||||
|
||||
pub fn dc_set_msg_location_id(context: &Context, msg_id: u32, location_id: u32) -> bool {
|
||||
@@ -395,7 +395,6 @@ pub fn dc_set_msg_location_id(context: &Context, msg_id: u32, location_id: u32)
|
||||
"UPDATE msgs SET location_id=? WHERE id=?;",
|
||||
params![location_id, msg_id as i32],
|
||||
)
|
||||
.is_ok()
|
||||
}
|
||||
|
||||
pub unsafe fn dc_save_locations(
|
||||
|
||||
@@ -36,37 +36,37 @@ pub fn dc_loginparam_read(
|
||||
|
||||
let key = format!("{}addr", prefix);
|
||||
let addr = sql
|
||||
.get_config(context, key)
|
||||
.get_config(context, key, None)
|
||||
.unwrap_or_default()
|
||||
.trim()
|
||||
.to_string();
|
||||
|
||||
let key = format!("{}mail_server", prefix);
|
||||
let mail_server = sql.get_config(context, key).unwrap_or_default();
|
||||
let mail_server = sql.get_config(context, key, None).unwrap_or_default();
|
||||
|
||||
let key = format!("{}mail_port", prefix);
|
||||
let mail_port = sql.get_config_int(context, key).unwrap_or_default();
|
||||
let mail_port = sql.get_config_int(context, key, 0);
|
||||
|
||||
let key = format!("{}mail_user", prefix);
|
||||
let mail_user = sql.get_config(context, key).unwrap_or_default();
|
||||
let mail_user = sql.get_config(context, key, None).unwrap_or_default();
|
||||
|
||||
let key = format!("{}mail_pw", prefix);
|
||||
let mail_pw = sql.get_config(context, key).unwrap_or_default();
|
||||
let mail_pw = sql.get_config(context, key, None).unwrap_or_default();
|
||||
|
||||
let key = format!("{}send_server", prefix);
|
||||
let send_server = sql.get_config(context, key).unwrap_or_default();
|
||||
let send_server = sql.get_config(context, key, None).unwrap_or_default();
|
||||
|
||||
let key = format!("{}send_port", prefix);
|
||||
let send_port = sql.get_config_int(context, key).unwrap_or_default();
|
||||
let send_port = sql.get_config_int(context, key, 0);
|
||||
|
||||
let key = format!("{}send_user", prefix);
|
||||
let send_user = sql.get_config(context, key).unwrap_or_default();
|
||||
let send_user = sql.get_config(context, key, None).unwrap_or_default();
|
||||
|
||||
let key = format!("{}send_pw", prefix);
|
||||
let send_pw = sql.get_config(context, key).unwrap_or_default();
|
||||
let send_pw = sql.get_config(context, key, None).unwrap_or_default();
|
||||
|
||||
let key = format!("{}server_flags", prefix);
|
||||
let server_flags = sql.get_config_int(context, key).unwrap_or_default();
|
||||
let server_flags = sql.get_config_int(context, key, 0);
|
||||
|
||||
dc_loginparam_t {
|
||||
addr: addr.to_string(),
|
||||
|
||||
@@ -197,7 +197,7 @@ pub unsafe fn dc_mimefactory_load_msg(
|
||||
let email_to_remove = to_string(email_to_remove_c);
|
||||
let self_addr = context
|
||||
.sql
|
||||
.get_config(context, "configured_addr")
|
||||
.get_config(context, "configured_addr", Some(""))
|
||||
.unwrap_or_default();
|
||||
|
||||
if !email_to_remove.is_empty() && email_to_remove != self_addr {
|
||||
@@ -219,10 +219,7 @@ pub unsafe fn dc_mimefactory_load_msg(
|
||||
}
|
||||
if command != 6
|
||||
&& command != 7
|
||||
&& 0 != context
|
||||
.sql
|
||||
.get_config_int(context, "mdns_enabled")
|
||||
.unwrap_or_else(|| 1)
|
||||
&& 0 != context.sql.get_config_int(context, "mdns_enabled", 1)
|
||||
{
|
||||
(*factory).req_mdn = 1
|
||||
}
|
||||
@@ -270,7 +267,7 @@ unsafe fn load_from(mut factory: *mut dc_mimefactory_t) {
|
||||
to_cstring(
|
||||
context
|
||||
.sql
|
||||
.get_config(context, "configured_addr")
|
||||
.get_config(context, "configured_addr", None)
|
||||
.unwrap_or_default(),
|
||||
)
|
||||
.as_ptr(),
|
||||
@@ -279,7 +276,7 @@ unsafe fn load_from(mut factory: *mut dc_mimefactory_t) {
|
||||
to_cstring(
|
||||
context
|
||||
.sql
|
||||
.get_config(context, "displayname")
|
||||
.get_config(context, "displayname", None)
|
||||
.unwrap_or_default(),
|
||||
)
|
||||
.as_ptr(),
|
||||
@@ -288,7 +285,7 @@ unsafe fn load_from(mut factory: *mut dc_mimefactory_t) {
|
||||
to_cstring(
|
||||
context
|
||||
.sql
|
||||
.get_config(context, "selfstatus")
|
||||
.get_config(context, "selfstatus", None)
|
||||
.unwrap_or_default(),
|
||||
)
|
||||
.as_ptr(),
|
||||
@@ -315,8 +312,7 @@ pub unsafe fn dc_mimefactory_load_mdn(
|
||||
if 0 != (*factory)
|
||||
.context
|
||||
.sql
|
||||
.get_config_int((*factory).context, "mdns_enabled")
|
||||
.unwrap_or_else(|| 1)
|
||||
.get_config_int((*factory).context, "mdns_enabled", 1)
|
||||
{
|
||||
// MDNs not enabled - check this is late, in the job. the use may have changed its choice while offline ...
|
||||
contact = dc_contact_new((*factory).context);
|
||||
|
||||
@@ -4,12 +4,7 @@ use crate::dc_job::*;
|
||||
use crate::dc_msg::*;
|
||||
|
||||
pub unsafe fn dc_do_heuristics_moves(context: &Context, folder: &str, msg_id: u32) {
|
||||
if context
|
||||
.sql
|
||||
.get_config_int(context, "mvbox_move")
|
||||
.unwrap_or_else(|| 1)
|
||||
== 0
|
||||
{
|
||||
if context.sql.get_config_int(context, "mvbox_move", 1) == 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -531,7 +531,6 @@ pub fn dc_update_msg_chat_id(context: &Context, msg_id: u32, chat_id: u32) -> bo
|
||||
"UPDATE msgs SET chat_id=? WHERE id=?;",
|
||||
params![chat_id as i32, msg_id as i32],
|
||||
)
|
||||
.is_ok()
|
||||
}
|
||||
|
||||
pub fn dc_markseen_msgs(context: &Context, msg_ids: *const u32, msg_cnt: usize) -> bool {
|
||||
@@ -587,7 +586,6 @@ pub fn dc_update_msg_state(context: &Context, msg_id: uint32_t, state: libc::c_i
|
||||
"UPDATE msgs SET state=? WHERE id=?;",
|
||||
params![state, msg_id as i32],
|
||||
)
|
||||
.is_ok()
|
||||
}
|
||||
|
||||
pub fn dc_star_msgs(
|
||||
@@ -1093,7 +1091,6 @@ pub unsafe fn dc_msg_save_param_to_disk(msg: *mut dc_msg_t) -> bool {
|
||||
"UPDATE msgs SET param=? WHERE id=?;",
|
||||
params![as_str((*(*msg).param).packed), (*msg).id as i32],
|
||||
)
|
||||
.is_ok()
|
||||
}
|
||||
|
||||
pub unsafe fn dc_msg_new_load<'a>(context: &'a Context, msg_id: uint32_t) -> *mut dc_msg_t<'a> {
|
||||
@@ -1162,7 +1159,6 @@ pub fn dc_update_msg_move_state(
|
||||
"UPDATE msgs SET move_state=? WHERE rfc724_mid=?;",
|
||||
params![state as i32, as_str(rfc724_mid)],
|
||||
)
|
||||
.is_ok()
|
||||
}
|
||||
|
||||
pub unsafe fn dc_set_msg_failed(context: &Context, msg_id: uint32_t, error: *const libc::c_char) {
|
||||
@@ -1182,9 +1178,7 @@ pub unsafe fn dc_set_msg_failed(context: &Context, msg_id: uint32_t, error: *con
|
||||
&context.sql,
|
||||
"UPDATE msgs SET state=?, param=? WHERE id=?;",
|
||||
params![(*msg).state, as_str((*(*msg).param).packed), msg_id as i32],
|
||||
)
|
||||
.is_ok()
|
||||
{
|
||||
) {
|
||||
context.call_cb(
|
||||
Event::MSG_FAILED,
|
||||
(*msg).chat_id as uintptr_t,
|
||||
|
||||
@@ -216,12 +216,10 @@ pub unsafe fn dc_receive_imf(
|
||||
by checking the state before the message body is downloaded */
|
||||
let mut allow_creation: libc::c_int = 1;
|
||||
if msgrmsg == 0 {
|
||||
let show_emails = context
|
||||
.sql
|
||||
.get_config_int(context, "show_emails")
|
||||
.unwrap_or_default();
|
||||
let show_emails: libc::c_int =
|
||||
context.sql.get_config_int(context, "show_emails", 0);
|
||||
if show_emails == 0 {
|
||||
chat_id = 3;
|
||||
chat_id = 3 as uint32_t;
|
||||
allow_creation = 0
|
||||
} else if show_emails == 1 {
|
||||
allow_creation = 0
|
||||
@@ -405,10 +403,8 @@ pub unsafe fn dc_receive_imf(
|
||||
dc_unarchive_chat(context, chat_id);
|
||||
// if the mime-headers should be saved, find out its size
|
||||
// (the mime-header ends with an empty line)
|
||||
let save_mime_headers = context
|
||||
.sql
|
||||
.get_config_int(context, "save_mime_headers")
|
||||
.unwrap_or_default();
|
||||
let save_mime_headers =
|
||||
context.sql.get_config_int(context, "save_mime_headers", 0);
|
||||
field = dc_mimeparser_lookup_field(&mime_parser, "In-Reply-To");
|
||||
if !field.is_null()
|
||||
&& (*field).fld_type == MAILIMF_FIELD_IN_REPLY_TO as libc::c_int
|
||||
@@ -585,10 +581,7 @@ pub unsafe fn dc_receive_imf(
|
||||
16282941964262048061 => {}
|
||||
_ => {
|
||||
if carray_count(mime_parser.reports) > 0 as libc::c_uint {
|
||||
let mdns_enabled = context
|
||||
.sql
|
||||
.get_config_int(context, "mdns_enabled")
|
||||
.unwrap_or_else(|| 1);
|
||||
let mdns_enabled = context.sql.get_config_int(context, "mdns_enabled", 1);
|
||||
icnt = carray_count(mime_parser.reports) as size_t;
|
||||
i = 0 as size_t;
|
||||
while i < icnt {
|
||||
@@ -746,10 +739,7 @@ pub unsafe fn dc_receive_imf(
|
||||
);
|
||||
dc_param_set_int(param, 'z' as i32, server_uid as i32);
|
||||
if 0 != mime_parser.is_send_by_messenger
|
||||
&& 0 != context
|
||||
.sql
|
||||
.get_config_int(context, "mvbox_move")
|
||||
.unwrap_or_else(|| 1)
|
||||
&& 0 != context.sql.get_config_int(context, "mvbox_move", 1)
|
||||
{
|
||||
dc_param_set_int(param, 'M' as i32, 1);
|
||||
}
|
||||
@@ -1112,7 +1102,7 @@ unsafe fn create_or_lookup_group(
|
||||
group_explicitly_left = dc_is_group_explicitly_left(context, grpid);
|
||||
let self_addr = context
|
||||
.sql
|
||||
.get_config(context, "configured_addr")
|
||||
.get_config(context, "configured_addr", Some(""))
|
||||
.unwrap_or_default();
|
||||
if chat_id == 0 as libc::c_uint
|
||||
&& 0 == dc_mimeparser_is_mailinglist_message(mime_parser)
|
||||
@@ -1186,9 +1176,7 @@ unsafe fn create_or_lookup_group(
|
||||
&context.sql,
|
||||
"UPDATE chats SET name=? WHERE id=?;",
|
||||
params![as_str(grpname), chat_id as i32],
|
||||
)
|
||||
.is_ok()
|
||||
{
|
||||
) {
|
||||
context.call_cb(Event::CHAT_MODIFIED, chat_id as uintptr_t, 0);
|
||||
}
|
||||
}
|
||||
@@ -1455,7 +1443,7 @@ fn create_group_record(
|
||||
create_blocked: libc::c_int,
|
||||
create_verified: libc::c_int,
|
||||
) -> u32 {
|
||||
if sql::execute(
|
||||
if !sql::execute(
|
||||
context,
|
||||
&context.sql,
|
||||
"INSERT INTO chats (type, name, grpid, blocked) VALUES(?, ?, ?, ?);",
|
||||
@@ -1465,9 +1453,7 @@ fn create_group_record(
|
||||
as_str(grpid),
|
||||
create_blocked,
|
||||
],
|
||||
)
|
||||
.is_err()
|
||||
{
|
||||
) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1484,8 +1470,8 @@ unsafe fn create_adhoc_grp_id(context: &Context, member_ids: *mut dc_array_t) ->
|
||||
let member_ids_str = dc_array_get_string(member_ids, b",\x00" as *const u8 as *const _);
|
||||
let member_cs = context
|
||||
.sql
|
||||
.get_config(context, "configured_addr")
|
||||
.unwrap_or_else(|| "no-self".to_string())
|
||||
.get_config(context, "configured_addr", Some("no-self"))
|
||||
.unwrap()
|
||||
.to_lowercase();
|
||||
|
||||
let members = context
|
||||
@@ -1992,8 +1978,8 @@ unsafe fn add_or_lookup_contact_by_addr(
|
||||
*check_self = 0;
|
||||
let self_addr = context
|
||||
.sql
|
||||
.get_config(context, "configured_addr")
|
||||
.unwrap_or_default();
|
||||
.get_config(context, "configured_addr", Some(""))
|
||||
.unwrap();
|
||||
|
||||
if dc_addr_cmp(self_addr, as_str(addr_spec)) {
|
||||
*check_self = 1;
|
||||
|
||||
@@ -51,7 +51,7 @@ pub unsafe fn dc_get_securejoin_qr(
|
||||
auth = dc_create_id();
|
||||
dc_token_save(context, DC_TOKEN_AUTH, group_chat_id, auth);
|
||||
}
|
||||
let self_addr = context.sql.get_config(context, "configured_addr");
|
||||
let self_addr = context.sql.get_config(context, "configured_addr", None);
|
||||
|
||||
let cleanup = |fingerprint, chat, group_name, group_name_urlencoded| {
|
||||
free(fingerprint as *mut libc::c_void);
|
||||
@@ -76,9 +76,8 @@ pub unsafe fn dc_get_securejoin_qr(
|
||||
let self_addr = self_addr.unwrap();
|
||||
let self_name = context
|
||||
.sql
|
||||
.get_config(context, "displayname")
|
||||
.unwrap_or_default();
|
||||
|
||||
.get_config(context, "displayname", Some(""))
|
||||
.unwrap();
|
||||
fingerprint = get_self_fingerprint(context);
|
||||
|
||||
if fingerprint.is_null() {
|
||||
@@ -127,7 +126,7 @@ pub unsafe fn dc_get_securejoin_qr(
|
||||
}
|
||||
|
||||
fn get_self_fingerprint(context: &Context) -> *mut libc::c_char {
|
||||
if let Some(self_addr) = context.sql.get_config(context, "configured_addr") {
|
||||
if let Some(self_addr) = context.sql.get_config(context, "configured_addr", None) {
|
||||
if let Some(key) = Key::from_self_public(context, self_addr, &context.sql) {
|
||||
return key.fingerprint_c();
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ pub fn dc_token_save(
|
||||
"INSERT INTO tokens (namespc, foreign_id, token, timestamp) VALUES (?, ?, ?, ?);",
|
||||
params![namespc as i32, foreign_id as i32, as_str(token), time()],
|
||||
)
|
||||
.is_ok()
|
||||
}
|
||||
|
||||
pub fn dc_token_lookup(
|
||||
|
||||
@@ -14,8 +14,6 @@ pub enum Error {
|
||||
SqlAlreadyOpen,
|
||||
#[fail(display = "Sqlite: Failed to open")]
|
||||
SqlFailedToOpen,
|
||||
#[fail(display = "{:?}", _0)]
|
||||
Io(std::io::Error),
|
||||
}
|
||||
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
@@ -37,9 +35,3 @@ impl From<r2d2::Error> for Error {
|
||||
Error::ConnectionPool(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for Error {
|
||||
fn from(err: std::io::Error) -> Error {
|
||||
Error::Io(err)
|
||||
}
|
||||
}
|
||||
|
||||
65
src/imap.rs
65
src/imap.rs
@@ -32,7 +32,8 @@ pub struct Imap {
|
||||
precheck_imf: dc_precheck_imf_t,
|
||||
receive_imf: dc_receive_imf_t,
|
||||
|
||||
session: Arc<Mutex<(Option<Session>, Option<net::TcpStream>)>>,
|
||||
session: Arc<Mutex<Option<Session>>>,
|
||||
stream: Arc<RwLock<Option<net::TcpStream>>>,
|
||||
connected: Arc<Mutex<bool>>,
|
||||
}
|
||||
|
||||
@@ -350,7 +351,8 @@ impl Imap {
|
||||
receive_imf: dc_receive_imf_t,
|
||||
) -> Self {
|
||||
Imap {
|
||||
session: Arc::new(Mutex::new((None, None))),
|
||||
session: Arc::new(Mutex::new(None)),
|
||||
stream: Arc::new(RwLock::new(None)),
|
||||
config: Arc::new(RwLock::new(ImapConfig::default())),
|
||||
watch: Arc::new((Mutex::new(false), Condvar::new())),
|
||||
get_config,
|
||||
@@ -378,7 +380,7 @@ impl Imap {
|
||||
self.unsetup_handle(context);
|
||||
}
|
||||
|
||||
if self.is_connected() && self.session.lock().unwrap().1.is_some() {
|
||||
if self.is_connected() && self.stream.read().unwrap().is_some() {
|
||||
self.config.write().unwrap().should_reconnect = false;
|
||||
return 1;
|
||||
}
|
||||
@@ -453,7 +455,8 @@ impl Imap {
|
||||
|
||||
match login_res {
|
||||
Ok((session, stream)) => {
|
||||
*self.session.lock().unwrap() = (Some(session), Some(stream));
|
||||
*self.session.lock().unwrap() = Some(session);
|
||||
*self.stream.write().unwrap() = Some(stream);
|
||||
1
|
||||
}
|
||||
Err((err, _)) => {
|
||||
@@ -466,7 +469,7 @@ impl Imap {
|
||||
}
|
||||
|
||||
fn unsetup_handle(&self, context: &Context) {
|
||||
let session = self.session.lock().unwrap().0.take();
|
||||
let session = self.session.lock().unwrap().take();
|
||||
if session.is_some() {
|
||||
match session.unwrap().close() {
|
||||
Ok(_) => {}
|
||||
@@ -475,7 +478,7 @@ impl Imap {
|
||||
}
|
||||
}
|
||||
}
|
||||
let stream = self.session.lock().unwrap().1.take();
|
||||
let stream = self.stream.write().unwrap().take();
|
||||
if stream.is_some() {
|
||||
match stream.unwrap().shutdown(net::Shutdown::Both) {
|
||||
Ok(_) => {}
|
||||
@@ -537,7 +540,7 @@ impl Imap {
|
||||
return 0;
|
||||
}
|
||||
|
||||
match self.session.lock().unwrap().0 {
|
||||
match &mut *self.session.lock().unwrap() {
|
||||
Some(ref mut session) => {
|
||||
if let Ok(caps) = session.capabilities() {
|
||||
let can_idle = caps.has("IDLE");
|
||||
@@ -615,7 +618,7 @@ impl Imap {
|
||||
}
|
||||
|
||||
fn select_folder<S: AsRef<str>>(&self, context: &Context, folder: Option<S>) -> usize {
|
||||
if self.session.lock().unwrap().0.is_none() {
|
||||
if self.session.lock().unwrap().is_none() {
|
||||
let mut cfg = self.config.write().unwrap();
|
||||
cfg.selected_folder = None;
|
||||
cfg.selected_folder_needs_expunge = false;
|
||||
@@ -639,7 +642,7 @@ impl Imap {
|
||||
|
||||
// A CLOSE-SELECT is considerably faster than an EXPUNGE-SELECT, see
|
||||
// https://tools.ietf.org/html/rfc3501#section-6.4.2
|
||||
if let Some(ref mut session) = self.session.lock().unwrap().0 {
|
||||
if let Some(ref mut session) = &mut *self.session.lock().unwrap() {
|
||||
match session.close() {
|
||||
Ok(_) => {}
|
||||
Err(err) => {
|
||||
@@ -655,7 +658,7 @@ impl Imap {
|
||||
|
||||
// select new folder
|
||||
if let Some(ref folder) = folder {
|
||||
if let Some(ref mut session) = self.session.lock().unwrap().0 {
|
||||
if let Some(ref mut session) = &mut *self.session.lock().unwrap() {
|
||||
match session.select(folder) {
|
||||
Ok(mailbox) => {
|
||||
let mut config = self.config.write().unwrap();
|
||||
@@ -761,7 +764,7 @@ impl Imap {
|
||||
return 0;
|
||||
}
|
||||
|
||||
let list = if let Some(ref mut session) = self.session.lock().unwrap().0 {
|
||||
let list = if let Some(ref mut session) = &mut *self.session.lock().unwrap() {
|
||||
// `FETCH <message sequence number> (UID)`
|
||||
let set = format!("{}", mailbox.exists);
|
||||
match session.fetch(set, PREFETCH_FLAGS) {
|
||||
@@ -805,7 +808,7 @@ impl Imap {
|
||||
let mut read_errors = 0;
|
||||
let mut new_last_seen_uid = 0;
|
||||
|
||||
let list = if let Some(ref mut session) = self.session.lock().unwrap().0 {
|
||||
let list = if let Some(ref mut session) = &mut *self.session.lock().unwrap() {
|
||||
// fetch messages with larger UID than the last one seen
|
||||
// (`UID FETCH lastseenuid+1:*)`, see RFC 4549
|
||||
let set = format!("{}:*", last_seen_uid + 1);
|
||||
@@ -928,7 +931,7 @@ impl Imap {
|
||||
|
||||
let set = format!("{}", server_uid);
|
||||
|
||||
let msgs = if let Some(ref mut session) = self.session.lock().unwrap().0 {
|
||||
let msgs = if let Some(ref mut session) = &mut *self.session.lock().unwrap() {
|
||||
match session.uid_fetch(set, BODY_FLAGS) {
|
||||
Ok(msgs) => msgs,
|
||||
Err(err) => {
|
||||
@@ -1027,7 +1030,7 @@ impl Imap {
|
||||
|
||||
std::thread::spawn(move || {
|
||||
let &(ref lock, ref cvar) = &*v;
|
||||
if let Some(ref mut session) = session.lock().unwrap().0 {
|
||||
if let Some(ref mut session) = &mut *session.lock().unwrap() {
|
||||
let mut idle = match session.idle() {
|
||||
Ok(idle) => idle,
|
||||
Err(err) => {
|
||||
@@ -1205,7 +1208,7 @@ impl Imap {
|
||||
folder.as_ref()
|
||||
);
|
||||
} else {
|
||||
let moved = if let Some(ref mut session) = self.session.lock().unwrap().0 {
|
||||
let moved = if let Some(ref mut session) = &mut *self.session.lock().unwrap() {
|
||||
match session.uid_mv(&set, &dest_folder) {
|
||||
Ok(_) => {
|
||||
res = DC_SUCCESS;
|
||||
@@ -1230,7 +1233,7 @@ impl Imap {
|
||||
};
|
||||
|
||||
if !moved {
|
||||
let copied = if let Some(ref mut session) = self.session.lock().unwrap().0 {
|
||||
let copied = if let Some(ref mut session) = &mut *self.session.lock().unwrap() {
|
||||
match session.uid_copy(&set, &dest_folder) {
|
||||
Ok(_) => true,
|
||||
Err(err) => {
|
||||
@@ -1275,7 +1278,7 @@ impl Imap {
|
||||
if server_uid == 0 {
|
||||
return 0;
|
||||
}
|
||||
if let Some(ref mut session) = self.session.lock().unwrap().0 {
|
||||
if let Some(ref mut session) = &mut *self.session.lock().unwrap() {
|
||||
let set = format!("{}", server_uid);
|
||||
let query = format!("+FLAGS ({})", flag.as_ref());
|
||||
match session.uid_store(&set, &query) {
|
||||
@@ -1387,18 +1390,18 @@ impl Imap {
|
||||
.expect("just selected folder");
|
||||
|
||||
if can_create_flag {
|
||||
let fetched_msgs = if let Some(ref mut session) = self.session.lock().unwrap().0
|
||||
{
|
||||
match session.uid_fetch(set, FETCH_FLAGS) {
|
||||
Ok(res) => Some(res),
|
||||
Err(err) => {
|
||||
eprintln!("fetch error: {:?}", err);
|
||||
None
|
||||
let fetched_msgs =
|
||||
if let Some(ref mut session) = &mut *self.session.lock().unwrap() {
|
||||
match session.uid_fetch(set, FETCH_FLAGS) {
|
||||
Ok(res) => Some(res),
|
||||
Err(err) => {
|
||||
eprintln!("fetch error: {:?}", err);
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
unreachable!();
|
||||
};
|
||||
} else {
|
||||
unreachable!();
|
||||
};
|
||||
|
||||
if let Some(msgs) = fetched_msgs {
|
||||
let flag_set = msgs
|
||||
@@ -1479,7 +1482,7 @@ impl Imap {
|
||||
);
|
||||
} else {
|
||||
let set = format!("{}", server_uid);
|
||||
if let Some(ref mut session) = self.session.lock().unwrap().0 {
|
||||
if let Some(ref mut session) = &mut *self.session.lock().unwrap() {
|
||||
match session.uid_fetch(set, PREFETCH_FLAGS) {
|
||||
Ok(msgs) => {
|
||||
if msgs.is_empty()
|
||||
@@ -1561,7 +1564,7 @@ impl Imap {
|
||||
if mvbox_folder.is_none() && 0 != (flags as usize & DC_CREATE_MVBOX) {
|
||||
info!(context, 0, "Creating MVBOX-folder \"DeltaChat\"...",);
|
||||
|
||||
if let Some(ref mut session) = self.session.lock().unwrap().0 {
|
||||
if let Some(ref mut session) = &mut *self.session.lock().unwrap() {
|
||||
match session.create("DeltaChat") {
|
||||
Ok(_) => {
|
||||
mvbox_folder = Some("DeltaChat".into());
|
||||
@@ -1616,7 +1619,7 @@ impl Imap {
|
||||
&self,
|
||||
context: &Context,
|
||||
) -> Option<imap::types::ZeroCopy<Vec<imap::types::Name>>> {
|
||||
if let Some(ref mut session) = self.session.lock().unwrap().0 {
|
||||
if let Some(ref mut session) = &mut *self.session.lock().unwrap() {
|
||||
// TODO: use xlist when available
|
||||
match session.list(Some(""), Some("*")) {
|
||||
Ok(list) => {
|
||||
|
||||
@@ -306,7 +306,7 @@ pub fn dc_key_save_self_keypair(
|
||||
sql,
|
||||
"INSERT INTO keypairs (addr, is_default, public_key, private_key, created) VALUES (?,?,?,?,?);",
|
||||
params![addr.as_ref(), is_default, public_key.to_bytes(), private_key.to_bytes(), time()],
|
||||
).is_ok()
|
||||
)
|
||||
}
|
||||
|
||||
/// Make a fingerprint human-readable, in hex format.
|
||||
|
||||
@@ -76,17 +76,19 @@ pub fn dc_get_oauth2_access_token(
|
||||
|
||||
// read generated token
|
||||
if 0 == flags & 0x1 && !is_expired(context) {
|
||||
let access_token = context.sql.get_config(context, "oauth2_access_token");
|
||||
let access_token = context.sql.get_config(context, "oauth2_access_token", None);
|
||||
if access_token.is_some() {
|
||||
// success
|
||||
return access_token;
|
||||
}
|
||||
}
|
||||
|
||||
let refresh_token = context.sql.get_config(context, "oauth2_refresh_token");
|
||||
let refresh_token = context
|
||||
.sql
|
||||
.get_config(context, "oauth2_refresh_token", None);
|
||||
let refresh_token_for = context
|
||||
.sql
|
||||
.get_config(context, "oauth2_refresh_token_for")
|
||||
.get_config(context, "oauth2_refresh_token_for", None)
|
||||
.unwrap_or_else(|| "unset".into());
|
||||
|
||||
let (redirect_uri, token_url, update_redirect_uri_on_success) =
|
||||
@@ -98,7 +100,7 @@ pub fn dc_get_oauth2_access_token(
|
||||
(
|
||||
context
|
||||
.sql
|
||||
.get_config(context, "oauth2_pending_redirect_uri")
|
||||
.get_config(context, "oauth2_pending_redirect_uri", None)
|
||||
.unwrap_or_else(|| "unset".into()),
|
||||
oauth2.init_token,
|
||||
true,
|
||||
@@ -111,7 +113,7 @@ pub fn dc_get_oauth2_access_token(
|
||||
(
|
||||
context
|
||||
.sql
|
||||
.get_config(context, "oauth2_redirect_uri")
|
||||
.get_config(context, "oauth2_redirect_uri", None)
|
||||
.unwrap_or_else(|| "unset".into()),
|
||||
oauth2.refresh_token,
|
||||
false,
|
||||
@@ -294,10 +296,10 @@ impl Oauth2 {
|
||||
}
|
||||
|
||||
fn is_expired(context: &Context) -> bool {
|
||||
let expire_timestamp = context
|
||||
.sql
|
||||
.get_config_int64(context, "oauth2_timestamp_expires")
|
||||
.unwrap_or_default();
|
||||
let expire_timestamp =
|
||||
context
|
||||
.sql
|
||||
.get_config_int64(context, "oauth2_timestamp_expires", Some(0));
|
||||
|
||||
if expire_timestamp <= 0 {
|
||||
return false;
|
||||
|
||||
@@ -387,14 +387,12 @@ impl<'a> Peerstate<'a> {
|
||||
}
|
||||
|
||||
if create {
|
||||
if sql::execute(
|
||||
if !sql::execute(
|
||||
self.context,
|
||||
sql,
|
||||
"INSERT INTO acpeerstates (addr) VALUES(?);",
|
||||
params![self.addr.as_ref().unwrap()],
|
||||
)
|
||||
.is_err()
|
||||
{
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -421,7 +419,7 @@ impl<'a> Peerstate<'a> {
|
||||
&self.verified_key_fingerprint,
|
||||
&self.addr,
|
||||
],
|
||||
).is_ok();
|
||||
);
|
||||
} else if self.to_save == Some(ToSave::Timestamps) {
|
||||
success = sql::execute(
|
||||
self.context,
|
||||
@@ -434,8 +432,7 @@ impl<'a> Peerstate<'a> {
|
||||
self.gossip_timestamp,
|
||||
&self.addr
|
||||
],
|
||||
)
|
||||
.is_ok();
|
||||
);
|
||||
}
|
||||
|
||||
if self.to_save == Some(ToSave::All) || create {
|
||||
|
||||
101
src/sql.rs
101
src/sql.rs
@@ -30,9 +30,11 @@ impl Sql {
|
||||
}
|
||||
|
||||
pub fn close(&self, context: &Context) {
|
||||
let _ = self.pool.write().unwrap().take();
|
||||
// drop closes the connection
|
||||
|
||||
let mut pool = self.pool.write().unwrap();
|
||||
if pool.is_some() {
|
||||
pool.take();
|
||||
// drop closes the connection
|
||||
}
|
||||
info!(context, 0, "Database closed.");
|
||||
}
|
||||
|
||||
@@ -173,56 +175,63 @@ impl Sql {
|
||||
}
|
||||
|
||||
/// Set private configuration options.
|
||||
/// Setting `None` deletes the value.
|
||||
pub fn set_config(
|
||||
&self,
|
||||
context: &Context,
|
||||
key: impl AsRef<str>,
|
||||
value: Option<&str>,
|
||||
) -> Result<()> {
|
||||
) -> libc::c_int {
|
||||
if !self.is_open() {
|
||||
error!(context, 0, "set_config(): Database not ready.");
|
||||
return Err(Error::SqlNoConnection);
|
||||
return 0;
|
||||
}
|
||||
|
||||
let key = key.as_ref();
|
||||
let res = if let Some(ref value) = value {
|
||||
let exists = self.exists("SELECT value FROM config WHERE keyname=?;", params![key])?;
|
||||
let good;
|
||||
|
||||
if let Some(ref value) = value {
|
||||
let exists = self
|
||||
.exists("SELECT value FROM config WHERE keyname=?;", params![key])
|
||||
.unwrap_or_default();
|
||||
if exists {
|
||||
execute(
|
||||
good = execute(
|
||||
context,
|
||||
self,
|
||||
"UPDATE config SET value=? WHERE keyname=?;",
|
||||
params![value, key],
|
||||
)
|
||||
);
|
||||
} else {
|
||||
execute(
|
||||
good = execute(
|
||||
context,
|
||||
self,
|
||||
"INSERT INTO config (keyname, value) VALUES (?, ?);",
|
||||
params![key, value],
|
||||
)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
execute(
|
||||
good = execute(
|
||||
context,
|
||||
self,
|
||||
"DELETE FROM config WHERE keyname=?;",
|
||||
params![key],
|
||||
)
|
||||
};
|
||||
|
||||
match res {
|
||||
Ok(_) => Ok(()),
|
||||
Err(err) => {
|
||||
error!(context, 0, "set_config(): Cannot change value. {:?}", &err);
|
||||
Err(err.into())
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if !good {
|
||||
error!(context, 0, "set_config(): Cannot change value.",);
|
||||
return 0;
|
||||
}
|
||||
|
||||
1
|
||||
}
|
||||
|
||||
/// Get configuration options from the database.
|
||||
pub fn get_config(&self, context: &Context, key: impl AsRef<str>) -> Option<String> {
|
||||
pub fn get_config(
|
||||
&self,
|
||||
context: &Context,
|
||||
key: impl AsRef<str>,
|
||||
def: Option<&str>,
|
||||
) -> Option<String> {
|
||||
if !self.is_open() || key.as_ref().is_empty() {
|
||||
return None;
|
||||
}
|
||||
@@ -232,6 +241,7 @@ impl Sql {
|
||||
params![key.as_ref()],
|
||||
0,
|
||||
)
|
||||
.or_else(|| def.map(|s| s.to_string()))
|
||||
}
|
||||
|
||||
pub fn set_config_int(
|
||||
@@ -239,12 +249,14 @@ impl Sql {
|
||||
context: &Context,
|
||||
key: impl AsRef<str>,
|
||||
value: i32,
|
||||
) -> Result<()> {
|
||||
) -> libc::c_int {
|
||||
self.set_config(context, key, Some(&format!("{}", value)))
|
||||
}
|
||||
|
||||
pub fn get_config_int(&self, context: &Context, key: impl AsRef<str>) -> Option<i32> {
|
||||
self.get_config(context, key).and_then(|s| s.parse().ok())
|
||||
pub fn get_config_int(&self, context: &Context, key: impl AsRef<str>, def: i32) -> i32 {
|
||||
self.get_config(context, key, None)
|
||||
.and_then(|s| s.parse().ok())
|
||||
.unwrap_or_else(|| def)
|
||||
}
|
||||
|
||||
pub fn set_config_int64(
|
||||
@@ -252,12 +264,19 @@ impl Sql {
|
||||
context: &Context,
|
||||
key: impl AsRef<str>,
|
||||
value: i64,
|
||||
) -> Result<()> {
|
||||
) -> libc::c_int {
|
||||
self.set_config(context, key, Some(&format!("{}", value)))
|
||||
}
|
||||
|
||||
pub fn get_config_int64(&self, context: &Context, key: impl AsRef<str>) -> Option<i64> {
|
||||
self.get_config(context, key).and_then(|r| r.parse().ok())
|
||||
pub fn get_config_int64(
|
||||
&self,
|
||||
context: &Context,
|
||||
key: impl AsRef<str>,
|
||||
def: Option<i64>,
|
||||
) -> i64 {
|
||||
let ret = self.get_config(context, key, None);
|
||||
ret.map(|r| r.parse().unwrap_or_default())
|
||||
.unwrap_or_else(|| def.unwrap_or_default())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,6 +292,8 @@ fn table_exists(conn: &Connection, name: impl AsRef<str>) -> bool {
|
||||
exists
|
||||
}
|
||||
|
||||
// Return 1 -> success
|
||||
// Return 0 -> failure
|
||||
fn open(
|
||||
context: &Context,
|
||||
sql: &Sql,
|
||||
@@ -443,7 +464,7 @@ fn open(
|
||||
}
|
||||
} else {
|
||||
exists_before_update = 1;
|
||||
dbversion_before_update = sql.get_config_int(context, "dbversion").unwrap_or_default();
|
||||
dbversion_before_update = sql.get_config_int(context, "dbversion", 0);
|
||||
}
|
||||
|
||||
// (1) update low-level database structure.
|
||||
@@ -769,8 +790,8 @@ fn open(
|
||||
info!(context, 0, "[open] update file paths");
|
||||
|
||||
let repl_from = sql
|
||||
.get_config(context, "backup_for")
|
||||
.unwrap_or_else(|| to_string(context.get_blobdir()));
|
||||
.get_config(context, "backup_for", Some(as_str(context.get_blobdir())))
|
||||
.unwrap();
|
||||
|
||||
let repl_from = dc_ensure_no_slash_safe(&repl_from);
|
||||
sql.execute(
|
||||
@@ -798,39 +819,39 @@ fn open(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn execute<P>(context: &Context, sql: &Sql, querystr: impl AsRef<str>, params: P) -> Result<()>
|
||||
pub fn execute<P>(context: &Context, sql: &Sql, querystr: impl AsRef<str>, params: P) -> bool
|
||||
where
|
||||
P: IntoIterator,
|
||||
P::Item: rusqlite::ToSql,
|
||||
{
|
||||
match sql.execute(querystr.as_ref(), params) {
|
||||
Ok(_) => Ok(()),
|
||||
Ok(_) => true,
|
||||
Err(err) => {
|
||||
error!(
|
||||
context,
|
||||
0,
|
||||
"execute failed: {:?} for {}",
|
||||
&err,
|
||||
err,
|
||||
querystr.as_ref()
|
||||
);
|
||||
Err(err.into())
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn try_execute(context: &Context, sql: &Sql, querystr: impl AsRef<str>) -> Result<()> {
|
||||
pub fn try_execute(context: &Context, sql: &Sql, querystr: impl AsRef<str>) -> libc::c_int {
|
||||
// same as execute() but does not pass error to ui
|
||||
match sql.execute(querystr.as_ref(), params![]) {
|
||||
Ok(_) => Ok(()),
|
||||
Ok(_) => 1,
|
||||
Err(err) => {
|
||||
warn!(
|
||||
context,
|
||||
0,
|
||||
"Try-execute for \"{}\" failed: {}",
|
||||
querystr.as_ref(),
|
||||
&err,
|
||||
err,
|
||||
);
|
||||
Err(err)
|
||||
0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,7 +248,7 @@ unsafe fn stress_functions(context: &Context) {
|
||||
free(fn1 as *mut libc::c_void);
|
||||
}
|
||||
|
||||
let res = context.get_config(config::Config::SysConfigKeys).unwrap();
|
||||
let res = config::get(context, "sys.config_keys");
|
||||
|
||||
assert!(!res.contains(" probably_never_a_key "));
|
||||
assert!(res.contains(" addr "));
|
||||
|
||||
Reference in New Issue
Block a user