From 69f89733392a5278e262f897ec48c3346902aeb6 Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Tue, 10 Sep 2019 16:23:38 +0300 Subject: [PATCH 01/25] test_encryption_decryption: use safe from_slice instead of from_binary --- tests/stress.rs | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/tests/stress.rs b/tests/stress.rs index bf60a1961..e7a4ac460 100644 --- a/tests/stress.rs +++ b/tests/stress.rs @@ -461,28 +461,22 @@ unsafe fn stress_functions(context: &Context) { #[test] #[ignore] // is too expensive fn test_encryption_decryption() { - unsafe { - let mut bad_data: [libc::c_uchar; 4096] = [0; 4096]; - let mut i_0: libc::c_int = 0i32; - while i_0 < 4096i32 { - bad_data[i_0 as usize] = (i_0 & 0xffi32) as libc::c_uchar; - i_0 += 1 - } - let mut j: libc::c_int = 0i32; + let mut bad_data: [u8; 4096] = [0; 4096]; - while j < 4096 / 40 { - let bad_key = Key::from_binary( - &mut *bad_data.as_mut_ptr().offset(j as isize) as *const u8, - 4096 / 2 + j, + for i in 0..4096 { + bad_data[i] = (i & 0xff) as u8; + } + + for j in 0..(4096 / 40) { + let bad_key = Key::from_slice( + &bad_data[j..j + 4096 / 2 + j], if 0 != j & 1 { KeyType::Public } else { KeyType::Private }, ); - assert!(bad_key.is_none()); - j += 1 } let (public_key, private_key) = dc_pgp_create_keypair("foo@bar.de").unwrap(); @@ -590,7 +584,6 @@ fn test_encryption_decryption() { dc_pgp_pk_decrypt(ctext_signed.as_bytes(), &keyring, &public_keyring, None).unwrap(); assert_eq!(plain, original_text); - } } unsafe extern "C" fn cb( From 971960a2421b1a4e7cb0c1e443bbbf7b89fdc470 Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Tue, 10 Sep 2019 16:23:56 +0300 Subject: [PATCH 02/25] key.rs: remove unsafe Key.from_binary --- src/key.rs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/key.rs b/src/key.rs index bb7ac3115..434a3b039 100644 --- a/src/key.rs +++ b/src/key.rs @@ -1,7 +1,6 @@ use std::collections::BTreeMap; use std::ffi::{CStr, CString}; use std::io::Cursor; -use std::slice; use libc; use pgp::composed::{Deserializable, SignedPublicKey, SignedSecretKey}; @@ -106,15 +105,6 @@ impl Key { } } - pub fn from_binary(data: *const u8, len: libc::c_int, key_type: KeyType) -> Option { - if data.is_null() || len == 0 { - return None; - } - - let bytes = unsafe { slice::from_raw_parts(data, len as usize) }; - Self::from_slice(bytes, key_type) - } - pub fn from_armored_string( data: &str, key_type: KeyType, From 22c1ee1f552a86d7fed91e99f00ee04132dbc710 Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Tue, 10 Sep 2019 16:29:41 +0300 Subject: [PATCH 03/25] cargo fmt --- tests/stress.rs | 188 ++++++++++++++++++++++++------------------------ 1 file changed, 94 insertions(+), 94 deletions(-) diff --git a/tests/stress.rs b/tests/stress.rs index e7a4ac460..d993c1334 100644 --- a/tests/stress.rs +++ b/tests/stress.rs @@ -461,129 +461,129 @@ unsafe fn stress_functions(context: &Context) { #[test] #[ignore] // is too expensive fn test_encryption_decryption() { - let mut bad_data: [u8; 4096] = [0; 4096]; + let mut bad_data: [u8; 4096] = [0; 4096]; - for i in 0..4096 { - bad_data[i] = (i & 0xff) as u8; - } + for i in 0..4096 { + bad_data[i] = (i & 0xff) as u8; + } - for j in 0..(4096 / 40) { - let bad_key = Key::from_slice( - &bad_data[j..j + 4096 / 2 + j], - if 0 != j & 1 { - KeyType::Public - } else { - KeyType::Private - }, - ); - assert!(bad_key.is_none()); - } + for j in 0..(4096 / 40) { + let bad_key = Key::from_slice( + &bad_data[j..j + 4096 / 2 + j], + if 0 != j & 1 { + KeyType::Public + } else { + KeyType::Private + }, + ); + assert!(bad_key.is_none()); + } - let (public_key, private_key) = dc_pgp_create_keypair("foo@bar.de").unwrap(); + let (public_key, private_key) = dc_pgp_create_keypair("foo@bar.de").unwrap(); - private_key.split_key().unwrap(); + private_key.split_key().unwrap(); - let (public_key2, private_key2) = dc_pgp_create_keypair("two@zwo.de").unwrap(); + let (public_key2, private_key2) = dc_pgp_create_keypair("two@zwo.de").unwrap(); - assert_ne!(public_key, public_key2); + assert_ne!(public_key, public_key2); - let original_text = b"This is a test"; - let mut keyring = Keyring::default(); - keyring.add_owned(public_key.clone()); - keyring.add_ref(&public_key2); + let original_text = b"This is a test"; + let mut keyring = Keyring::default(); + keyring.add_owned(public_key.clone()); + keyring.add_ref(&public_key2); - let ctext_signed = dc_pgp_pk_encrypt(original_text, &keyring, Some(&private_key)).unwrap(); - assert!(!ctext_signed.is_empty()); - assert!(ctext_signed.starts_with("-----BEGIN PGP MESSAGE-----")); + let ctext_signed = dc_pgp_pk_encrypt(original_text, &keyring, Some(&private_key)).unwrap(); + assert!(!ctext_signed.is_empty()); + assert!(ctext_signed.starts_with("-----BEGIN PGP MESSAGE-----")); - let ctext_unsigned = dc_pgp_pk_encrypt(original_text, &keyring, None).unwrap(); - assert!(!ctext_unsigned.is_empty()); - assert!(ctext_unsigned.starts_with("-----BEGIN PGP MESSAGE-----")); + let ctext_unsigned = dc_pgp_pk_encrypt(original_text, &keyring, None).unwrap(); + assert!(!ctext_unsigned.is_empty()); + assert!(ctext_unsigned.starts_with("-----BEGIN PGP MESSAGE-----")); - let mut keyring = Keyring::default(); - keyring.add_owned(private_key); + let mut keyring = Keyring::default(); + keyring.add_owned(private_key); - let mut public_keyring = Keyring::default(); - public_keyring.add_ref(&public_key); + let mut public_keyring = Keyring::default(); + public_keyring.add_ref(&public_key); - let mut public_keyring2 = Keyring::default(); - public_keyring2.add_owned(public_key2.clone()); + let mut public_keyring2 = Keyring::default(); + public_keyring2.add_owned(public_key2.clone()); - let mut valid_signatures: HashSet = Default::default(); + let mut valid_signatures: HashSet = Default::default(); - let plain = dc_pgp_pk_decrypt( - ctext_signed.as_bytes(), - &keyring, - &public_keyring, - Some(&mut valid_signatures), - ) - .unwrap(); + let plain = dc_pgp_pk_decrypt( + ctext_signed.as_bytes(), + &keyring, + &public_keyring, + Some(&mut valid_signatures), + ) + .unwrap(); - assert_eq!(plain, original_text,); - assert_eq!(valid_signatures.len(), 1); + assert_eq!(plain, original_text,); + assert_eq!(valid_signatures.len(), 1); - valid_signatures.clear(); + valid_signatures.clear(); - let empty_keyring = Keyring::default(); - let plain = dc_pgp_pk_decrypt( - ctext_signed.as_bytes(), - &keyring, - &empty_keyring, - Some(&mut valid_signatures), - ) - .unwrap(); - assert_eq!(plain, original_text); - assert_eq!(valid_signatures.len(), 0); + let empty_keyring = Keyring::default(); + let plain = dc_pgp_pk_decrypt( + ctext_signed.as_bytes(), + &keyring, + &empty_keyring, + Some(&mut valid_signatures), + ) + .unwrap(); + assert_eq!(plain, original_text); + assert_eq!(valid_signatures.len(), 0); - valid_signatures.clear(); + valid_signatures.clear(); - let plain = dc_pgp_pk_decrypt( - ctext_signed.as_bytes(), - &keyring, - &public_keyring2, - Some(&mut valid_signatures), - ) - .unwrap(); - assert_eq!(plain, original_text); - assert_eq!(valid_signatures.len(), 0); + let plain = dc_pgp_pk_decrypt( + ctext_signed.as_bytes(), + &keyring, + &public_keyring2, + Some(&mut valid_signatures), + ) + .unwrap(); + assert_eq!(plain, original_text); + assert_eq!(valid_signatures.len(), 0); - valid_signatures.clear(); + valid_signatures.clear(); - public_keyring2.add_ref(&public_key); + public_keyring2.add_ref(&public_key); - let plain = dc_pgp_pk_decrypt( - ctext_signed.as_bytes(), - &keyring, - &public_keyring2, - Some(&mut valid_signatures), - ) - .unwrap(); - assert_eq!(plain, original_text); - assert_eq!(valid_signatures.len(), 1); + let plain = dc_pgp_pk_decrypt( + ctext_signed.as_bytes(), + &keyring, + &public_keyring2, + Some(&mut valid_signatures), + ) + .unwrap(); + assert_eq!(plain, original_text); + assert_eq!(valid_signatures.len(), 1); - valid_signatures.clear(); + valid_signatures.clear(); - let plain = dc_pgp_pk_decrypt( - ctext_unsigned.as_bytes(), - &keyring, - &public_keyring, - Some(&mut valid_signatures), - ) - .unwrap(); + let plain = dc_pgp_pk_decrypt( + ctext_unsigned.as_bytes(), + &keyring, + &public_keyring, + Some(&mut valid_signatures), + ) + .unwrap(); - assert_eq!(plain, original_text); + assert_eq!(plain, original_text); - valid_signatures.clear(); + valid_signatures.clear(); - let mut keyring = Keyring::default(); - keyring.add_ref(&private_key2); - let mut public_keyring = Keyring::default(); - public_keyring.add_ref(&public_key); + let mut keyring = Keyring::default(); + keyring.add_ref(&private_key2); + let mut public_keyring = Keyring::default(); + public_keyring.add_ref(&public_key); - let plain = - dc_pgp_pk_decrypt(ctext_signed.as_bytes(), &keyring, &public_keyring, None).unwrap(); + let plain = + dc_pgp_pk_decrypt(ctext_signed.as_bytes(), &keyring, &public_keyring, None).unwrap(); - assert_eq!(plain, original_text); + assert_eq!(plain, original_text); } unsafe extern "C" fn cb( From f1c026c5eccd7068fed42298a19b9af0dfda5a59 Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Tue, 10 Sep 2019 13:49:34 +0300 Subject: [PATCH 04/25] Pass passphrase to dc_pgp_symm_{en,de}crypt as &str --- src/dc_imex.rs | 10 +++------- src/pgp.rs | 18 +++++------------- 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/src/dc_imex.rs b/src/dc_imex.rs index 50aa9780f..d9d785ba5 100644 --- a/src/dc_imex.rs +++ b/src/dc_imex.rs @@ -208,12 +208,8 @@ pub fn dc_render_setup_file(context: &Context, passphrase: &str) -> Result Some(("Autocrypt-Prefer-Encrypt", "mutual")), }; let private_key_asc = private_key.to_asc(ac_headers); - let encr = { - let private_key_asc_c = CString::yolo(private_key_asc); - let passphrase_c = CString::yolo(passphrase); - dc_pgp_symm_encrypt(passphrase_c.as_ptr(), private_key_asc_c.as_bytes()) - .ok_or(format_err!("Failed to encrypt private key."))? - }; + let encr = dc_pgp_symm_encrypt(&passphrase, private_key_asc.as_bytes()) + .ok_or(format_err!("Failed to encrypt private key."))?; let replacement = format!( concat!( "-----BEGIN PGP MESSAGE-----\r\n", @@ -445,7 +441,7 @@ pub unsafe fn dc_decrypt_setup_file( { /* decrypt symmetrically */ if let Some(plain) = dc_pgp_symm_decrypt( - passphrase, + as_str(passphrase), std::slice::from_raw_parts(binary as *const u8, binary_bytes), ) { let payload_c = CString::new(plain).unwrap(); diff --git a/src/pgp.rs b/src/pgp.rs index 46d1fc8b0..5adf95c51 100644 --- a/src/pgp.rs +++ b/src/pgp.rs @@ -1,6 +1,5 @@ use std::collections::HashSet; use std::convert::TryInto; -use std::ffi::CStr; use std::io::Cursor; use std::ptr; @@ -274,32 +273,25 @@ pub fn dc_pgp_pk_decrypt( } /// Symmetric encryption. -pub fn dc_pgp_symm_encrypt(passphrase: *const libc::c_char, plain: &[u8]) -> Option { - assert!(!passphrase.is_null(), "invalid passphrase"); - - let pw = unsafe { CStr::from_ptr(passphrase).to_str().unwrap() }; - +pub fn dc_pgp_symm_encrypt(passphrase: &str, plain: &[u8]) -> Option { let mut rng = thread_rng(); let lit_msg = Message::new_literal_bytes("", plain); let s2k = StringToKey::new_default(&mut rng); - let msg = lit_msg.encrypt_with_password(&mut rng, s2k, Default::default(), || pw.into()); + let msg = + lit_msg.encrypt_with_password(&mut rng, s2k, Default::default(), || passphrase.into()); msg.and_then(|msg| msg.to_armored_string(None)).ok() } /// Symmetric decryption. -pub fn dc_pgp_symm_decrypt(passphrase: *const libc::c_char, ctext: &[u8]) -> Option> { - assert!(!passphrase.is_null(), "invalid passphrase"); - - let pw = unsafe { CStr::from_ptr(passphrase).to_str().unwrap() }; - +pub fn dc_pgp_symm_decrypt(passphrase: &str, ctext: &[u8]) -> Option> { let enc_msg = Message::from_bytes(Cursor::new(ctext)); enc_msg .and_then(|msg| { let mut decryptor = msg - .decrypt_with_password(|| pw.into()) + .decrypt_with_password(|| passphrase.into()) .expect("failed decryption"); decryptor.next().expect("no message") }) From e9da21a02e037c9b0b46fd199231525110f21285 Mon Sep 17 00:00:00 2001 From: "B. Petersen" Date: Tue, 10 Sep 2019 17:27:28 +0200 Subject: [PATCH 05/25] cargo fmt --- src/dc_receive_imf.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dc_receive_imf.rs b/src/dc_receive_imf.rs index e4f896263..7924033a4 100644 --- a/src/dc_receive_imf.rs +++ b/src/dc_receive_imf.rs @@ -642,7 +642,8 @@ unsafe fn add_parts( } } if part.type_0 == Viewtype::Text { - let msg_raw = CString::yolo(part.msg_raw.as_ref().cloned().unwrap_or_default()); + let msg_raw = + CString::yolo(part.msg_raw.as_ref().cloned().unwrap_or_default()); let subject_c = CString::yolo( mime_parser .subject From 4fbb5fbb255761c006b876b26c24c9e1dbee7a51 Mon Sep 17 00:00:00 2001 From: Dmitry Bogatov Date: Tue, 10 Sep 2019 15:48:08 +0000 Subject: [PATCH 06/25] Make it easier to run src/top_evil_rs.py from git root Currently, `src/top_evil_rs.py' script recursively scans current directory for Rust sources and print statistics about them. When run from git root, it also scans target/ directory, which is useless. This commit add cludge that checks if script is run from git root directory, and `chdir' into `src/' before performing actions. Unprincipled, but convenient. --- src/top_evil_rs.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/top_evil_rs.py b/src/top_evil_rs.py index a64c3f4b7..278d7f354 100755 --- a/src/top_evil_rs.py +++ b/src/top_evil_rs.py @@ -6,6 +6,8 @@ import os import re if __name__ == "__main__": + if Path('src/top_evil_rs.py').exists(): + os.chdir('src') filestats = [] for fn in Path(".").glob("**/*.rs"): s = fn.read_text() From 1576dc1d13d54fb9a9def3e04996adbecc1d327e Mon Sep 17 00:00:00 2001 From: Dmitry Bogatov Date: Tue, 10 Sep 2019 15:54:36 +0000 Subject: [PATCH 07/25] top_evil_rs: check for all-caps version of ok_to_continue pattern --- src/top_evil_rs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/top_evil_rs.py b/src/top_evil_rs.py index 278d7f354..2976b0de1 100755 --- a/src/top_evil_rs.py +++ b/src/top_evil_rs.py @@ -14,7 +14,7 @@ if __name__ == "__main__": s = re.sub(r"(?m)///.*$", "", s) # remove comments unsafe = s.count("unsafe") free = s.count("free(") - gotoblocks = s.count("ok_to_continue") + gotoblocks = s.count("ok_to_continue") + s.count('OK_TO_CONTINUE') filestats.append((fn, unsafe, free, gotoblocks)) sum_unsafe, sum_free, sum_gotoblocks = 0, 0, 0 From ffc525af9ef33cab0b268d712d517d6b2aaf860b Mon Sep 17 00:00:00 2001 From: holger krekel Date: Tue, 10 Sep 2019 12:07:03 +0200 Subject: [PATCH 08/25] pragmatismatic: run flaky tests three times to see if we can get more "green" CI runs this way ... thanks to @the-compiler also modernize plugin usage --- python/README.rst | 2 +- python/tox.ini | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/python/README.rst b/python/README.rst index 22de2bb9b..49c86cd4a 100644 --- a/python/README.rst +++ b/python/README.rst @@ -65,7 +65,7 @@ Afterwards ``which python`` tells you that it comes out of the "venv" directory that contains all python install artifacts. Let's first install test tools:: - pip install pytest pytest-timeout requests + pip install pytest pytest-timeout pytest-rerunfailures requests then cargo-build and install the deltachat bindings:: diff --git a/python/tox.ini b/python/tox.ini index c0776790a..51392338d 100644 --- a/python/tox.ini +++ b/python/tox.ini @@ -16,7 +16,10 @@ passenv = DCC_PY_LIVECONFIG deps = pytest - pytest-faulthandler + pytest-rerunfailures + pytest-timeout + pytest-xdist + auditwheel pdbpp requests @@ -51,11 +54,12 @@ commands = [pytest] -addopts = -v -rs +addopts = -v -rs --reruns 3 --reruns-delay 2 python_files = tests/test_*.py norecursedirs = .tox xfail_strict=true -timeout = 60 +timeout = 60 +timeout_method = thread [flake8] max-line-length = 120 From 1cdb9c733a15e03a6b9580b2afab279485d40b05 Mon Sep 17 00:00:00 2001 From: Dmitry Bogatov Date: Tue, 10 Sep 2019 16:09:34 +0000 Subject: [PATCH 09/25] Change return type of `dc_is_configured' to bool --- deltachat-ffi/src/lib.rs | 2 +- src/configure/mod.rs | 6 +++--- src/dc_imex.rs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/deltachat-ffi/src/lib.rs b/deltachat-ffi/src/lib.rs index bdb89109e..0022b70fc 100644 --- a/deltachat-ffi/src/lib.rs +++ b/deltachat-ffi/src/lib.rs @@ -233,7 +233,7 @@ pub unsafe extern "C" fn dc_is_configured(context: *mut dc_context_t) -> libc::c let context = &*context; - configure::dc_is_configured(context) + configure::dc_is_configured(context) as libc::c_int } #[no_mangle] diff --git a/src/configure/mod.rs b/src/configure/mod.rs index e230ce9c0..86b5274fd 100644 --- a/src/configure/mod.rs +++ b/src/configure/mod.rs @@ -45,16 +45,16 @@ pub unsafe fn configure(context: &Context) { } /// Check if the context is already configured. -pub fn dc_is_configured(context: &Context) -> libc::c_int { +pub fn dc_is_configured(context: &Context) -> bool { if context .sql .get_config_int(context, "configured") .unwrap_or_default() > 0 { - 1 + true } else { - 0 + false } } diff --git a/src/dc_imex.rs b/src/dc_imex.rs index d9d785ba5..2222d0a4b 100644 --- a/src/dc_imex.rs +++ b/src/dc_imex.rs @@ -581,7 +581,7 @@ unsafe fn import_backup(context: &Context, backup_to_import: *const libc::c_char .map_or("<>", |p| p.to_str().unwrap()) ); - if 0 != dc_is_configured(context) { + if dc_is_configured(context) { error!(context, 0, "Cannot import backups to accounts in use."); return 0; } From 706a97b0138101b6311bd8f484eee519b0efc46e Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Wed, 11 Sep 2019 00:40:40 +0300 Subject: [PATCH 10/25] Move part of test_encryption_decryption to key.rs --- src/key.rs | 21 +++++++++++++++++++++ tests/stress.rs | 19 ------------------- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/key.rs b/src/key.rs index 434a3b039..2c5d6566e 100644 --- a/src/key.rs +++ b/src/key.rs @@ -439,6 +439,27 @@ i8pcjGO+IZffvyZJVRWfVooBJmWWbPB1pueo3tx8w3+fcuzpxz+RLFKaPyqXO+dD assert_eq!(private_key, private_key2); } + #[test] + fn test_from_slice_bad_data() { + let mut bad_data: [u8; 4096] = [0; 4096]; + + for i in 0..4096 { + bad_data[i] = (i & 0xff) as u8; + } + + for j in 0..(4096 / 40) { + let bad_key = Key::from_slice( + &bad_data[j..j + 4096 / 2 + j], + if 0 != j & 1 { + KeyType::Public + } else { + KeyType::Private + }, + ); + assert!(bad_key.is_none()); + } + } + #[test] #[ignore] // is too expensive fn test_ascii_roundtrip() { diff --git a/tests/stress.rs b/tests/stress.rs index d993c1334..1202392ab 100644 --- a/tests/stress.rs +++ b/tests/stress.rs @@ -12,7 +12,6 @@ use deltachat::contact::*; use deltachat::context::*; use deltachat::dc_imex::*; use deltachat::dc_tools::*; -use deltachat::key::*; use deltachat::keyring::*; use deltachat::oauth2::*; use deltachat::pgp::*; @@ -461,24 +460,6 @@ unsafe fn stress_functions(context: &Context) { #[test] #[ignore] // is too expensive fn test_encryption_decryption() { - let mut bad_data: [u8; 4096] = [0; 4096]; - - for i in 0..4096 { - bad_data[i] = (i & 0xff) as u8; - } - - for j in 0..(4096 / 40) { - let bad_key = Key::from_slice( - &bad_data[j..j + 4096 / 2 + j], - if 0 != j & 1 { - KeyType::Public - } else { - KeyType::Private - }, - ); - assert!(bad_key.is_none()); - } - let (public_key, private_key) = dc_pgp_create_keypair("foo@bar.de").unwrap(); private_key.split_key().unwrap(); From bb12488200d9eacbfc795a469fc67ecb53e7e4db Mon Sep 17 00:00:00 2001 From: Dmitry Bogatov Date: Tue, 10 Sep 2019 17:29:50 +0000 Subject: [PATCH 11/25] Add Sql.{set,get}_config_bool methods Previously, boolean configurations were implemented on top of i32 (get_config_int, set_config_it) at call sites. Having one canonical location, containing boolean <-> database conversion may help to avoid serialization issues. --- src/sql.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/sql.rs b/src/sql.rs index 62515b9f4..477feb5e9 100644 --- a/src/sql.rs +++ b/src/sql.rs @@ -259,6 +259,20 @@ impl Sql { self.get_config(context, key).and_then(|s| s.parse().ok()) } + pub fn get_config_bool(&self, context: &Context, key: impl AsRef) -> bool { + // Not the most obvious way to encode bool as string, but it is matter + // of backward compatibility. + self.get_config_int(context, key).unwrap_or_default() > 0 + } + + pub fn set_config_bool(&self, context: &Context, key: T, value: bool) -> Result<()> + where + T: AsRef, + { + let value = if value { Some("1") } else { None }; + self.set_config(context, key, value) + } + pub fn set_config_int64( &self, context: &Context, From b97b618b4bb1f3f4ad35bd96f05fd099f8fb6ecb Mon Sep 17 00:00:00 2001 From: Dmitry Bogatov Date: Tue, 10 Sep 2019 17:32:44 +0000 Subject: [PATCH 12/25] Use sql.get_config_bool to simplify `dc_is_configured` --- src/configure/mod.rs | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/configure/mod.rs b/src/configure/mod.rs index 86b5274fd..e8abb925d 100644 --- a/src/configure/mod.rs +++ b/src/configure/mod.rs @@ -46,16 +46,7 @@ pub unsafe fn configure(context: &Context) { /// Check if the context is already configured. pub fn dc_is_configured(context: &Context) -> bool { - if context - .sql - .get_config_int(context, "configured") - .unwrap_or_default() - > 0 - { - true - } else { - false - } + context.sql.get_config_bool(context, "configured") } /******************************************************************************* From 2dd3f169dbadff3ec8603d4a5ebee34c94fd5371 Mon Sep 17 00:00:00 2001 From: Dmitry Bogatov Date: Tue, 10 Sep 2019 17:40:33 +0000 Subject: [PATCH 13/25] Use set_config_bool instead of set_config_int in boolean context --- src/configure/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/configure/mod.rs b/src/configure/mod.rs index e8abb925d..c3d137677 100644 --- a/src/configure/mod.rs +++ b/src/configure/mod.rs @@ -509,7 +509,7 @@ pub unsafe fn dc_job_do_DC_JOB_CONFIGURE_IMAP(context: &Context, _job: &Job) { ) .ok(); - context.sql.set_config_int(context, "configured", 1).ok(); + context.sql.set_config_bool(context, "configured", true); true } 18 => { From 57daa0f7f0ae8535ba4fb838205d6a29f48267da Mon Sep 17 00:00:00 2001 From: Dmitry Bogatov Date: Tue, 10 Sep 2019 19:04:21 +0000 Subject: [PATCH 14/25] Remove useless argument of logging macros Previously, logging macros (info! warn! error!) accepted integer argument (data1), that was passed to callback function verbatim. In all call sites this argument was 0. With this change, that data1 argument is no longer part of macro interface, 0 is always passed to callback in internals of these macros. --- deltachat-ffi/src/lib.rs | 6 +-- examples/repl/cmdline.rs | 40 ++++++-------- src/chat.rs | 26 +++++----- src/configure/auto_mozilla.rs | 3 +- src/configure/auto_outlook.rs | 3 +- src/configure/mod.rs | 46 +++++++--------- src/contact.rs | 7 ++- src/context.rs | 16 ++---- src/dc_imex.rs | 67 ++++++++++-------------- src/dc_mimefactory.rs | 6 +-- src/dc_mimeparser.rs | 9 ++-- src/dc_receive_imf.rs | 35 +++++-------- src/dc_tools.rs | 6 +-- src/e2ee.rs | 9 ++-- src/imap.rs | 98 ++++++++++++----------------------- src/job.rs | 57 +++++++++----------- src/job_thread.rs | 16 +++--- src/key.rs | 2 +- src/location.rs | 3 +- src/log.rs | 24 ++++----- src/message.rs | 16 +++--- src/oauth2.rs | 31 ++++------- src/qr.rs | 2 +- src/securejoin.rs | 56 ++++++++++---------- src/smtp.rs | 6 +-- src/sql.rs | 46 +++++++--------- 26 files changed, 257 insertions(+), 379 deletions(-) diff --git a/deltachat-ffi/src/lib.rs b/deltachat-ffi/src/lib.rs index 0022b70fc..abcffa8fd 100644 --- a/deltachat-ffi/src/lib.rs +++ b/deltachat-ffi/src/lib.rs @@ -1188,7 +1188,7 @@ pub unsafe extern "C" fn dc_get_contact_encrinfo( Contact::get_encrinfo(context, contact_id) .map(|s| s.strdup()) .unwrap_or_else(|e| { - error!(context, 0, "{}", e); + error!(context, "{}", e); std::ptr::null_mut() }) } @@ -2547,7 +2547,7 @@ impl ResultExt for Result { match self { Ok(t) => t, Err(err) => { - error!(context, 0, "{}: {}", message, err); + error!(context, "{}: {}", message, err); Default::default() } } @@ -2555,7 +2555,7 @@ impl ResultExt for Result { fn log_err(&self, context: &context::Context, message: &str) { if let Err(err) = self { - error!(context, 0, "{}: {}", message, err); + error!(context, "{}: {}", message, err); } } } diff --git a/examples/repl/cmdline.rs b/examples/repl/cmdline.rs index e8edb49cd..e4809a0c6 100644 --- a/examples/repl/cmdline.rs +++ b/examples/repl/cmdline.rs @@ -28,10 +28,10 @@ use num_traits::FromPrimitive; /// Argument is a bitmask, executing single or multiple actions in one call. /// e.g. bitmask 7 triggers actions definded with bits 1, 2 and 4. pub unsafe fn dc_reset_tables(context: &Context, bits: i32) -> i32 { - info!(context, 0, "Resetting tables ({})...", bits); + info!(context, "Resetting tables ({})...", bits); if 0 != bits & 1 { sql::execute(context, &context.sql, "DELETE FROM jobs;", params![]).unwrap(); - info!(context, 0, "(1) Jobs reset."); + info!(context, "(1) Jobs reset."); } if 0 != bits & 2 { sql::execute( @@ -41,11 +41,11 @@ pub unsafe fn dc_reset_tables(context: &Context, bits: i32) -> i32 { params![], ) .unwrap(); - info!(context, 0, "(2) Peerstates reset."); + info!(context, "(2) Peerstates reset."); } if 0 != bits & 4 { sql::execute(context, &context.sql, "DELETE FROM keypairs;", params![]).unwrap(); - info!(context, 0, "(4) Private keypairs reset."); + info!(context, "(4) Private keypairs reset."); } if 0 != bits & 8 { sql::execute( @@ -84,7 +84,7 @@ pub unsafe fn dc_reset_tables(context: &Context, bits: i32) -> i32 { ) .unwrap(); sql::execute(context, &context.sql, "DELETE FROM leftgrps;", params![]).unwrap(); - info!(context, 0, "(8) Rest but server config reset."); + info!(context, "(8) Rest but server config reset."); } context.call_cb(Event::MSGS_CHANGED, 0, 0); @@ -122,7 +122,7 @@ unsafe fn dc_poke_eml_file(context: &Context, filename: *const libc::c_char) -> /// @return 1=success, 0=error. unsafe fn poke_spec(context: &Context, spec: *const libc::c_char) -> libc::c_int { if !context.sql.is_open() { - error!(context, 0, "Import: Database not opened."); + error!(context, "Import: Database not opened."); return 0; } @@ -143,7 +143,7 @@ unsafe fn poke_spec(context: &Context, spec: *const libc::c_char) -> libc::c_int } else { let rs = context.sql.get_config(context, "import_spec"); if rs.is_none() { - error!(context, 0, "Import: No file or folder given."); + error!(context, "Import: No file or folder given."); ok_to_continue = false; } else { ok_to_continue = true; @@ -166,7 +166,6 @@ unsafe fn poke_spec(context: &Context, spec: *const libc::c_char) -> libc::c_int if dir.is_err() { error!( context, - 0, "Import: Cannot open directory \"{}\".", as_str(real_spec), ); @@ -182,7 +181,7 @@ unsafe fn poke_spec(context: &Context, spec: *const libc::c_char) -> libc::c_int let name = name_f.to_string_lossy(); if name.ends_with(".eml") { let path_plus_name = format!("{}/{}", as_str(real_spec), name); - info!(context, 0, "Import: {}", path_plus_name); + info!(context, "Import: {}", path_plus_name); let path_plus_name_c = CString::yolo(path_plus_name); if 0 != dc_poke_eml_file(context, path_plus_name_c.as_ptr()) { read_cnt += 1 @@ -195,7 +194,6 @@ unsafe fn poke_spec(context: &Context, spec: *const libc::c_char) -> libc::c_int if ok_to_continue2 { info!( context, - 0, "Import: {} items read from \"{}\".", read_cnt, as_str(real_spec) @@ -228,7 +226,6 @@ unsafe fn log_msg(context: &Context, prefix: impl AsRef, msg: &Message) { let msgtext = dc_msg_get_text(msg); info!( context, - 0, "{}#{}{}{}: {} (Contact#{}): {} {}{}{}{} [{}]", prefix.as_ref(), dc_msg_get_id(msg) as libc::c_int, @@ -268,7 +265,6 @@ unsafe fn log_msglist(context: &Context, msglist: &Vec) -> Result<(), Error if msg_id == 9 as libc::c_uint { info!( context, - 0, "--------------------------------------------------------------------------------" ); @@ -276,7 +272,7 @@ unsafe fn log_msglist(context: &Context, msglist: &Vec) -> Result<(), Error } else if msg_id > 0 { if lines_out == 0 { info!( - context, 0, + context, "--------------------------------------------------------------------------------", ); lines_out += 1 @@ -288,7 +284,7 @@ unsafe fn log_msglist(context: &Context, msglist: &Vec) -> Result<(), Error if lines_out > 0 { info!( context, - 0, "--------------------------------------------------------------------------------" + "--------------------------------------------------------------------------------" ); } Ok(()) @@ -337,7 +333,7 @@ unsafe fn log_contactlist(context: &Context, contacts: &Vec) { ); } - info!(context, 0, "Contact#{}: {}{}", contact_id, line, line2); + info!(context, "Contact#{}: {}{}", contact_id, line, line2); } } } @@ -579,7 +575,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E let cnt = chatlist.len(); if cnt > 0 { info!( - context, 0, + context, "================================================================================" ); @@ -589,7 +585,6 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E let temp_name = chat.get_name(); info!( context, - 0, "{}#{}: {} [{}] [{} fresh]", chat_prefix(&chat), chat.get_id(), @@ -614,7 +609,6 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E let text2 = lot.get_text2(); info!( context, - 0, "{}{}{}{} [{}]{}", text1.unwrap_or(""), if text1.is_some() { ": " } else { "" }, @@ -628,13 +622,13 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E }, ); info!( - context, 0, + context, "================================================================================" ); } } if location::is_sending_locations_to_chat(context, 0 as uint32_t) { - info!(context, 0, "Location streaming enabled."); + info!(context, "Location streaming enabled."); } println!("{} chats", cnt); } @@ -657,7 +651,6 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E let temp_name = sel_chat.get_name(); info!( context, - 0, "{}#{}: {} [{}]{}", chat_prefix(sel_chat), sel_chat.get_id(), @@ -753,7 +746,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E ensure!(sel_chat.is_some(), "No chat selected."); let contacts = chat::get_chat_contacts(context, sel_chat.as_ref().unwrap().get_id()); - info!(context, 0, "Memberlist:"); + info!(context, "Memberlist:"); log_contactlist(context, &contacts); println!( @@ -781,7 +774,6 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E let marker = location.marker.as_ref().unwrap_or(&default_marker); info!( context, - 0, "Loc#{}: {}: lat={} lng={} acc={} Chat#{} Contact#{} Msg#{} {}", location.location_id, dc_timestamp_to_str(location.timestamp), @@ -795,7 +787,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E ); } if locations.is_empty() { - info!(context, 0, "No locations."); + info!(context, "No locations."); } } "sendlocations" => { diff --git a/src/chat.rs b/src/chat.rs index b409b15a1..d08592df4 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -65,7 +65,7 @@ impl<'a> Chat<'a> { _ => { error!( context, - 0, "chat: failed to load from db {}: {:?}", chat_id, err + "chat: failed to load from db {}: {:?}", chat_id, err ); Err(err) } @@ -260,7 +260,7 @@ impl<'a> Chat<'a> { || self.typ == Chattype::Group || self.typ == Chattype::VerifiedGroup) { - error!(context, 0, "Cannot send to chat type #{}.", self.typ,); + error!(context, "Cannot send to chat type #{}.", self.typ,); return Ok(0); } @@ -296,7 +296,7 @@ impl<'a> Chat<'a> { } else { error!( context, - 0, "Cannot send message, contact for chat #{} not found.", self.id, + "Cannot send message, contact for chat #{} not found.", self.id, ); return Ok(0); } @@ -338,7 +338,6 @@ impl<'a> Chat<'a> { if prefer_encrypted != 1 { info!( context, - 0, "[autocrypt] peerstate for {} is {}", state, if prefer_encrypted == 0 { @@ -350,7 +349,7 @@ impl<'a> Chat<'a> { all_mutual = 0; } } else { - info!(context, 0, "[autocrypt] no peerstate for {}", state,); + info!(context, "[autocrypt] no peerstate for {}", state,); can_encrypt = 0; all_mutual = 0; } @@ -360,7 +359,7 @@ impl<'a> Chat<'a> { match res { Ok(_) => {} Err(err) => { - warn!(context, 0, "chat: failed to load peerstates: {:?}", err); + warn!(context, "chat: failed to load peerstates: {:?}", err); } } @@ -464,13 +463,12 @@ impl<'a> Chat<'a> { } else { error!( context, - 0, "Cannot send message, cannot insert to database (chat #{}).", self.id, ); } } else { - error!(context, 0, "Cannot send message, not configured.",); + error!(context, "Cannot send message, not configured.",); } Ok(msg_id) @@ -541,7 +539,7 @@ pub fn create_by_contact_id(context: &Context, contact_id: u32) -> Result( } info!( context, - 0, "Attaching \"{}\" for message type #{}.", &path_filename, msg.type_0 + "Attaching \"{}\" for message type #{}.", &path_filename, msg.type_0 ); } else { bail!("Cannot send messages of type #{}.", msg.type_0); @@ -751,7 +749,7 @@ fn last_msg_in_chat_encrypted(context: &Context, sql: &Sql, chat_id: u32) -> boo match packed.parse::() { Ok(param) => param.exists(Param::GuranteeE2ee), Err(err) => { - error!(context, 0, "invalid params stored: '{}', {:?}", packed, err); + error!(context, "invalid params stored: '{}', {:?}", packed, err); false } } @@ -1385,7 +1383,7 @@ pub fn add_contact_to_chat_ex( if chat.typ == Chattype::VerifiedGroup { if contact.is_verified() != VerifiedStatus::BidirectVerified { error!( - context, 0, + context, "Only bidirectional verified contacts can be added to verified groups." ); OK_TO_CONTINUE = false; @@ -1451,7 +1449,7 @@ pub fn set_gossiped_timestamp(context: &Context, chat_id: u32, timestamp: i64) { if 0 != chat_id { info!( context, - 0, "set gossiped_timestamp for chat #{} to {}.", chat_id, timestamp, + "set gossiped_timestamp for chat #{} to {}.", chat_id, timestamp, ); sql::execute( @@ -1464,7 +1462,7 @@ pub fn set_gossiped_timestamp(context: &Context, chat_id: u32, timestamp: i64) { } else { info!( context, - 0, "set gossiped_timestamp for all chats to {}.", timestamp, + "set gossiped_timestamp for all chats to {}.", timestamp, ); sql::execute( context, diff --git a/src/configure/auto_mozilla.rs b/src/configure/auto_mozilla.rs index 11d7ed678..c03c43a85 100644 --- a/src/configure/auto_mozilla.rs +++ b/src/configure/auto_mozilla.rs @@ -69,7 +69,6 @@ pub unsafe fn moz_autoconfigure( Err(e) => { error!( context, - 0, "Configure xml: Error at position {}: {:?}", reader.buffer_position(), e @@ -87,7 +86,7 @@ pub unsafe fn moz_autoconfigure( || moz_ac.out.send_port == 0 { let r = moz_ac.out.to_string(); - warn!(context, 0, "Bad or incomplete autoconfig: {}", r,); + warn!(context, "Bad or incomplete autoconfig: {}", r,); free(xml_raw as *mut libc::c_void); return None; } diff --git a/src/configure/auto_outlook.rs b/src/configure/auto_outlook.rs index 1a3ea33bc..95b0f2c35 100644 --- a/src/configure/auto_outlook.rs +++ b/src/configure/auto_outlook.rs @@ -75,7 +75,6 @@ pub unsafe fn outlk_autodiscover( Err(e) => { error!( context, - 0, "Configure xml: Error at position {}: {:?}", reader.buffer_position(), e @@ -109,7 +108,7 @@ pub unsafe fn outlk_autodiscover( || outlk_ad.out.send_port == 0 { let r = outlk_ad.out.to_string(); - warn!(context, 0, "Bad or incomplete autoconfig: {}", r,); + warn!(context, "Bad or incomplete autoconfig: {}", r,); free(url as *mut libc::c_void); free(xml_raw as *mut libc::c_void); outlk_clean_config(&mut outlk_ad); diff --git a/src/configure/mod.rs b/src/configure/mod.rs index c3d137677..ccd549e5b 100644 --- a/src/configure/mod.rs +++ b/src/configure/mod.rs @@ -34,10 +34,7 @@ macro_rules! progress { // connect pub unsafe fn configure(context: &Context) { if dc_has_ongoing(context) { - warn!( - context, - 0, "There is already another ongoing process running.", - ); + warn!(context, "There is already another ongoing process running.",); return; } job_kill_action(context, Action::ConfigureImap); @@ -64,7 +61,7 @@ pub unsafe fn dc_job_do_DC_JOB_CONFIGURE_IMAP(context: &Context, _job: &Job) { if dc_alloc_ongoing(context) { ongoing_allocated_here = true; if !context.sql.is_open() { - error!(context, 0, "Cannot configure, database not opened.",); + error!(context, "Cannot configure, database not opened.",); } else { context.inbox.read().unwrap().disconnect(context); context @@ -80,7 +77,7 @@ pub unsafe fn dc_job_do_DC_JOB_CONFIGURE_IMAP(context: &Context, _job: &Job) { .imap .disconnect(context); context.smtp.clone().lock().unwrap().disconnect(); - info!(context, 0, "Configure ...",); + info!(context, "Configure ...",); let s_a = context.running_state.clone(); let s = s_a.read().unwrap(); @@ -104,7 +101,7 @@ pub unsafe fn dc_job_do_DC_JOB_CONFIGURE_IMAP(context: &Context, _job: &Job) { 1 => { progress!(context, 1); if param.addr.is_empty() { - error!(context, 0, "Please enter an email address.",); + error!(context, "Please enter an email address.",); } !param.addr.is_empty() } @@ -137,7 +134,7 @@ pub unsafe fn dc_job_do_DC_JOB_CONFIGURE_IMAP(context: &Context, _job: &Job) { utf8_percent_encode(¶m.addr, NON_ALPHANUMERIC).to_string(); true } else { - error!(context, 0, "Bad email-address."); + error!(context, "Bad email-address."); false } } @@ -247,7 +244,7 @@ pub unsafe fn dc_job_do_DC_JOB_CONFIGURE_IMAP(context: &Context, _job: &Job) { 12 => { progress!(context, 500); if let Some(ref cfg) = param_autoconfig { - info!(context, 0, "Got autoconfig: {}", &cfg); + info!(context, "Got autoconfig: {}", &cfg); if !cfg.mail_user.is_empty() { param.mail_user = cfg.mail_user.clone(); } @@ -331,7 +328,7 @@ pub unsafe fn dc_job_do_DC_JOB_CONFIGURE_IMAP(context: &Context, _job: &Job) { || param.send_pw.is_empty() || param.server_flags == 0 { - error!(context, 0, "Account settings incomplete."); + error!(context, "Account settings incomplete."); false } else { true @@ -348,7 +345,7 @@ pub unsafe fn dc_job_do_DC_JOB_CONFIGURE_IMAP(context: &Context, _job: &Job) { ok_to_continue8 = true; break; } - info!(context, 0, "Trying: {}", ¶m); + info!(context, "Trying: {}", ¶m); if context.inbox.read().unwrap().connect(context, ¶m) { ok_to_continue8 = true; @@ -366,7 +363,7 @@ pub unsafe fn dc_job_do_DC_JOB_CONFIGURE_IMAP(context: &Context, _job: &Job) { progress!(context, 650 + username_variation * 30); param.server_flags &= !(0x100 | 0x200 | 0x400); param.server_flags |= 0x100; - info!(context, 0, "Trying: {}", ¶m); + info!(context, "Trying: {}", ¶m); if context.inbox.read().unwrap().connect(context, ¶m) { ok_to_continue8 = true; @@ -379,7 +376,7 @@ pub unsafe fn dc_job_do_DC_JOB_CONFIGURE_IMAP(context: &Context, _job: &Job) { } progress!(context, 660 + username_variation * 30); param.mail_port = 143; - info!(context, 0, "Trying: {}", ¶m); + info!(context, "Trying: {}", ¶m); if context.inbox.read().unwrap().connect(context, ¶m) { ok_to_continue8 = true; @@ -434,7 +431,7 @@ pub unsafe fn dc_job_do_DC_JOB_CONFIGURE_IMAP(context: &Context, _job: &Job) { param.server_flags &= !(0x10000 | 0x20000 | 0x40000); param.server_flags |= 0x10000; param.send_port = 587; - info!(context, 0, "Trying: {}", ¶m); + info!(context, "Trying: {}", ¶m); if !context .smtp @@ -450,7 +447,7 @@ pub unsafe fn dc_job_do_DC_JOB_CONFIGURE_IMAP(context: &Context, _job: &Job) { param.server_flags &= !(0x10000 | 0x20000 | 0x40000); param.server_flags |= 0x10000; param.send_port = 25; - info!(context, 0, "Trying: {}", ¶m); + info!(context, "Trying: {}", ¶m); if !context .smtp @@ -519,13 +516,13 @@ pub unsafe fn dc_job_do_DC_JOB_CONFIGURE_IMAP(context: &Context, _job: &Job) { // (~30 seconds on a Moto G4 play) and might looks as if message sending is always that slow. e2ee::ensure_secret_key_exists(context); success = true; - info!(context, 0, "Configure completed."); + info!(context, "Configure completed."); progress!(context, 940); break; // We are done here } _ => { - error!(context, 0, "Internal error: step counter out of bound",); + error!(context, "Internal error: step counter out of bound",); break; } }; @@ -573,10 +570,7 @@ pub unsafe fn dc_job_do_DC_JOB_CONFIGURE_IMAP(context: &Context, _job: &Job) { pub fn dc_alloc_ongoing(context: &Context) -> bool { if dc_has_ongoing(context) { - warn!( - context, - 0, "There is already another ongoing process running.", - ); + warn!(context, "There is already another ongoing process running.",); false } else { @@ -619,7 +613,7 @@ pub fn dc_connect_to_configured_imap(context: &Context, imap: &Imap) -> libc::c_ .unwrap_or_default() == 0 { - warn!(context, 0, "Not configured, cannot connect.",); + warn!(context, "Not configured, cannot connect.",); } else { let param = LoginParam::from_database(context, "configured_"); // the trailing underscore is correct @@ -642,15 +636,15 @@ pub fn dc_stop_ongoing_process(context: &Context) { let mut s = s_a.write().unwrap(); if s.ongoing_running && !s.shall_stop_ongoing { - info!(context, 0, "Signaling the ongoing process to stop ASAP.",); + info!(context, "Signaling the ongoing process to stop ASAP.",); s.shall_stop_ongoing = true; } else { - info!(context, 0, "No ongoing process to stop.",); + info!(context, "No ongoing process to stop.",); }; } pub fn read_autoconf_file(context: &Context, url: &str) -> *mut libc::c_char { - info!(context, 0, "Testing {} ...", url); + info!(context, "Testing {} ...", url); match reqwest::Client::new() .get(url) @@ -659,7 +653,7 @@ pub fn read_autoconf_file(context: &Context, url: &str) -> *mut libc::c_char { { Ok(res) => unsafe { res.strdup() }, Err(_err) => { - info!(context, 0, "Can\'t read file.",); + info!(context, "Can\'t read file.",); std::ptr::null_mut() } diff --git a/src/contact.rs b/src/contact.rs index 606fa8a34..d483e7044 100644 --- a/src/contact.rs +++ b/src/contact.rs @@ -308,7 +308,6 @@ impl<'a> Contact<'a> { if !may_be_valid_addr(&addr) { warn!( context, - 0, "Bad address \"{}\" for contact \"{}\".", addr, if !name.as_ref().is_empty() { @@ -404,7 +403,7 @@ impl<'a> Contact<'a> { row_id = sql::get_rowid(context, &context.sql, "contacts", "addr", addr); sth_modified = Modifier::Created; } else { - error!(context, 0, "Cannot add contact."); + error!(context, "Cannot add contact."); } } @@ -683,7 +682,7 @@ impl<'a> Contact<'a> { return Ok(()); } Err(err) => { - error!(context, 0, "delete_contact {} failed ({})", contact_id, err); + error!(context, "delete_contact {} failed ({})", contact_id, err); return Err(err); } } @@ -691,7 +690,7 @@ impl<'a> Contact<'a> { info!( context, - 0, "could not delete contact {}, there are {} messages with it", contact_id, count_msgs + "could not delete contact {}, there are {} messages with it", contact_id, count_msgs ); bail!("Could not delete contact with messages in it"); } diff --git a/src/context.rs b/src/context.rs index 92b4ba6d9..255282f95 100644 --- a/src/context.rs +++ b/src/context.rs @@ -208,17 +208,11 @@ unsafe fn cb_precheck_imf( if *old_server_folder.offset(0isize) as libc::c_int == 0i32 && old_server_uid == 0i32 as libc::c_uint { - info!( - context, - 0, - "[move] detected bbc-self {}", - as_str(rfc724_mid), - ); + info!(context, "[move] detected bbc-self {}", as_str(rfc724_mid),); mark_seen = 1i32 } else if as_str(old_server_folder) != server_folder { info!( context, - 0, "[move] detected moved message {}", as_str(rfc724_mid), ); @@ -258,16 +252,16 @@ fn cb_get_config(context: &Context, key: &str) -> Option { } pub unsafe fn dc_close(context: &Context) { - info!(context, 0, "disconnecting INBOX-watch",); + info!(context, "disconnecting INBOX-watch",); context.inbox.read().unwrap().disconnect(context); - info!(context, 0, "disconnecting sentbox-thread",); + info!(context, "disconnecting sentbox-thread",); context .sentbox_thread .read() .unwrap() .imap .disconnect(context); - info!(context, 0, "disconnecting mvbox-thread",); + info!(context, "disconnecting mvbox-thread",); context .mvbox_thread .read() @@ -275,7 +269,7 @@ pub unsafe fn dc_close(context: &Context) { .imap .disconnect(context); - info!(context, 0, "disconnecting SMTP"); + info!(context, "disconnecting SMTP"); context.smtp.clone().lock().unwrap().disconnect(); context.sql.close(context); diff --git a/src/dc_imex.rs b/src/dc_imex.rs index 2222d0a4b..48d822e38 100644 --- a/src/dc_imex.rs +++ b/src/dc_imex.rs @@ -58,7 +58,6 @@ pub unsafe fn dc_imex_has_backup( if dir_iter.is_err() { info!( context, - 0, "Backup check: Cannot open directory \"{}\".\x00", dir_name.display(), ); @@ -92,7 +91,7 @@ pub unsafe fn dc_imex_has_backup( Some(path) => match path.to_c_string() { Ok(cstr) => dc_strdup(cstr.as_ptr()), Err(err) => { - error!(context, 0, "Invalid backup filename: {}", err); + error!(context, "Invalid backup filename: {}", err); std::ptr::null_mut() } }, @@ -156,7 +155,7 @@ pub unsafe fn dc_initiate_key_transfer(context: &Context) -> *mut libc::c_char { .shall_stop_ongoing { if let Ok(msg_id) = chat::send_msg(context, chat_id, &mut msg) { - info!(context, 0, "Wait for setup message being sent ...",); + info!(context, "Wait for setup message being sent ...",); loop { if context .running_state @@ -170,7 +169,7 @@ pub unsafe fn dc_initiate_key_transfer(context: &Context) -> *mut libc::c_char { std::thread::sleep(std::time::Duration::from_secs(1)); if let Ok(msg) = dc_get_msg(context, msg_id) { if 0 != dc_msg_is_sent(&msg) { - info!(context, 0, "... setup message sent.",); + info!(context, "... setup message sent.",); break; } } @@ -285,7 +284,7 @@ pub unsafe fn dc_continue_key_transfer( } || *filename.offset(0isize) as libc::c_int == 0i32 { - error!(context, 0, "Message is no Autocrypt Setup Message.",); + error!(context, "Message is no Autocrypt Setup Message.",); } else if 0 == dc_read_file( context, @@ -296,15 +295,15 @@ pub unsafe fn dc_continue_key_transfer( || filecontent.is_null() || filebytes <= 0 { - error!(context, 0, "Cannot read Autocrypt Setup Message file.",); + error!(context, "Cannot read Autocrypt Setup Message file.",); } else { norm_sc = dc_normalize_setup_code(context, setup_code); if norm_sc.is_null() { - warn!(context, 0, "Cannot normalize Setup Code.",); + warn!(context, "Cannot normalize Setup Code.",); } else { armored_key = dc_decrypt_setup_file(context, norm_sc, filecontent); if armored_key.is_null() { - warn!(context, 0, "Cannot decrypt Autocrypt Setup Message.",); + warn!(context, "Cannot decrypt Autocrypt Setup Message.",); } else if set_self_key(context, armored_key, 1) { /*set default*/ /* error already logged */ @@ -334,7 +333,7 @@ fn set_self_key( .and_then(|(k, h)| k.split_key().map(|pub_key| (k, pub_key, h))); if keys.is_none() { - error!(context, 0, "File does not contain a valid private key.",); + error!(context, "File does not contain a valid private key.",); return false; } @@ -364,13 +363,13 @@ fn set_self_key( return false; } } else { - error!(context, 0, "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"); if self_addr.is_none() { - error!(context, 0, "Missing self addr"); + error!(context, "Missing self addr"); return false; } @@ -382,7 +381,7 @@ fn set_self_key( set_default, &context.sql, ) { - error!(context, 0, "Cannot save keypair."); + error!(context, "Cannot save keypair."); return false; } @@ -503,19 +502,18 @@ pub unsafe fn dc_job_do_DC_JOB_IMEX_IMAP(context: &Context, job: &Job) { let _param2 = CString::yolo(job.param.get(Param::Arg2).unwrap_or_default()); if strlen(param1.as_ptr()) == 0 { - error!(context, 0, "No Import/export dir/file given.",); + error!(context, "No Import/export dir/file given.",); } else { - info!(context, 0, "Import/export process started.",); + info!(context, "Import/export process started.",); context.call_cb(Event::IMEX_PROGRESS, 10 as uintptr_t, 0 as uintptr_t); if !context.sql.is_open() { - error!(context, 0, "Import/export: Database not opened.",); + error!(context, "Import/export: Database not opened.",); } else { if what == 1 || what == 11 { /* before we export anything, make sure the private key exists */ if e2ee::ensure_secret_key_exists(context).is_err() { error!( context, - 0, "Import/export: Cannot create private key or private key not available.", ); ok_to_continue = false; @@ -527,25 +525,25 @@ pub unsafe fn dc_job_do_DC_JOB_IMEX_IMAP(context: &Context, job: &Job) { match what { 1 => { if 0 != export_self_keys(context, param1.as_ptr()) { - info!(context, 0, "Import/export completed.",); + info!(context, "Import/export completed.",); success = 1 } } 2 => { if 0 != import_self_keys(context, param1.as_ptr()) { - info!(context, 0, "Import/export completed.",); + info!(context, "Import/export completed.",); success = 1 } } 11 => { if 0 != export_backup(context, param1.as_ptr()) { - info!(context, 0, "Import/export completed.",); + info!(context, "Import/export completed.",); success = 1 } } 12 => { if 0 != import_backup(context, param1.as_ptr()) { - info!(context, 0, "Import/export completed.",); + info!(context, "Import/export completed.",); success = 1 } } @@ -572,7 +570,6 @@ pub unsafe fn dc_job_do_DC_JOB_IMEX_IMAP(context: &Context, job: &Job) { unsafe fn import_backup(context: &Context, backup_to_import: *const libc::c_char) -> libc::c_int { info!( context, - 0, "Import \"{}\" to \"{}\".", as_str(backup_to_import), context @@ -582,7 +579,7 @@ unsafe fn import_backup(context: &Context, backup_to_import: *const libc::c_char ); if dc_is_configured(context) { - error!(context, 0, "Cannot import backups to accounts in use."); + error!(context, "Cannot import backups to accounts in use."); return 0; } &context.sql.close(&context); @@ -590,7 +587,7 @@ unsafe fn import_backup(context: &Context, backup_to_import: *const libc::c_char if dc_file_exist(context, context.get_dbfile().unwrap()) { error!( context, - 0, "Cannot import backups: Cannot delete the old file.", + "Cannot import backups: Cannot delete the old file.", ); return 0; } @@ -617,7 +614,7 @@ unsafe fn import_backup(context: &Context, backup_to_import: *const libc::c_char .unwrap_or_default() as usize; info!( context, - 0, "***IMPORT-in-progress: total_files_cnt={:?}", total_files_cnt, + "***IMPORT-in-progress: total_files_cnt={:?}", total_files_cnt, ); let res = context.sql.query_map( @@ -665,7 +662,6 @@ unsafe fn import_backup(context: &Context, backup_to_import: *const libc::c_char } error!( context, - 0, "Storage full? Cannot write file {} with {} bytes.", &pathNfilename, file_blob.len(), @@ -712,7 +708,7 @@ unsafe fn export_backup(context: &Context, dir: *const libc::c_char) -> libc::c_ let buffer = CString::yolo(res); let dest_pathNfilename = dc_get_fine_pathNfilename(context, dir, buffer.as_ptr()); if dest_pathNfilename.is_null() { - error!(context, 0, "Cannot get backup file name.",); + error!(context, "Cannot get backup file name.",); return success; } @@ -724,7 +720,6 @@ unsafe fn export_backup(context: &Context, dir: *const libc::c_char) -> libc::c_ let mut closed = true; info!( context, - 0, "Backup \"{}\" to \"{}\".", context .get_dbfile() @@ -768,7 +763,7 @@ unsafe fn export_backup(context: &Context, dir: *const libc::c_char) -> libc::c_ if let Ok(dir_handle) = std::fs::read_dir(dir) { total_files_cnt += dir_handle.filter(|r| r.is_ok()).count(); - info!(context, 0, "EXPORT: total_files_cnt={}", total_files_cnt); + info!(context, "EXPORT: total_files_cnt={}", total_files_cnt); if total_files_cnt > 0 { // scan directory, pass 2: copy files if let Ok(dir_handle) = std::fs::read_dir(dir) { @@ -814,7 +809,7 @@ unsafe fn export_backup(context: &Context, dir: *const libc::c_char) -> libc::c_ { continue; } else { - info!(context, 0, "EXPORTing filename={}", name); + info!(context, "EXPORTing filename={}", name); let curr_pathNfilename = format!( "{}/{}", as_str(context.get_blobdir()), @@ -830,7 +825,6 @@ unsafe fn export_backup(context: &Context, dir: *const libc::c_char) -> libc::c_ if stmt.execute(params![name, buf]).is_err() { error!( context, - 0, "Disk full? Cannot add file \"{}\" to backup.", &curr_pathNfilename, ); @@ -850,13 +844,12 @@ unsafe fn export_backup(context: &Context, dir: *const libc::c_char) -> libc::c_ } else { error!( context, - 0, "Backup: Cannot copy from blob-directory \"{}\".", as_str(context.get_blobdir()), ); } } else { - info!(context, 0, "Backup: No files to copy.",); + info!(context, "Backup: No files to copy.",); ok_to_continue = true; } if ok_to_continue { @@ -875,7 +868,6 @@ unsafe fn export_backup(context: &Context, dir: *const libc::c_char) -> libc::c_ } else { error!( context, - 0, "Backup: Cannot get info for blob-directory \"{}\".", as_str(context.get_blobdir()) ); @@ -940,7 +932,7 @@ unsafe fn import_self_keys(context: &Context, dir_name: *const libc::c_char) -> dir_name, name_c.as_ptr(), ); - info!(context, 0, "Checking: {}", as_str(path_plus_name)); + info!(context, "Checking: {}", as_str(path_plus_name)); free(buf as *mut libc::c_void); buf = ptr::null_mut(); if 0 == dc_read_file( @@ -984,7 +976,6 @@ unsafe fn import_self_keys(context: &Context, dir_name: *const libc::c_char) -> { info!( context, - 0, "Treating \"{}\" as a legacy private key.", as_str(path_plus_name), ); @@ -998,7 +989,6 @@ unsafe fn import_self_keys(context: &Context, dir_name: *const libc::c_char) -> if imported_cnt == 0i32 { error!( context, - 0, "No private keys found in \"{}\".", as_str(dir_name), ); @@ -1006,7 +996,6 @@ unsafe fn import_self_keys(context: &Context, dir_name: *const libc::c_char) -> } else { error!( context, - 0, "Import: Cannot open directory \"{}\".", as_str(dir_name), ); @@ -1106,10 +1095,10 @@ unsafe fn export_key_to_asc_file( id, ) } - info!(context, 0, "Exporting key {}", as_str(file_name),); + info!(context, "Exporting key {}", as_str(file_name),); dc_delete_file(context, as_path(file_name)); if !key.write_asc_to_file(file_name, context) { - error!(context, 0, "Cannot write key to {}", as_str(file_name),); + error!(context, "Cannot write key to {}", as_str(file_name),); } else { context.call_cb( Event::IMEX_FILE_WRITTEN, diff --git a/src/dc_mimefactory.rs b/src/dc_mimefactory.rs index 6b58a1444..68d7d6129 100644 --- a/src/dc_mimefactory.rs +++ b/src/dc_mimefactory.rs @@ -225,7 +225,7 @@ pub unsafe fn dc_mimefactory_load_msg( Err(err) => { error!( context, - 0, "mimefactory: failed to load mime_in_reply_to: {:?}", err + "mimefactory: failed to load mime_in_reply_to: {:?}", err ); } } @@ -587,7 +587,6 @@ pub unsafe fn dc_mimefactory_render(factory: &mut dc_mimefactory_t) -> libc::c_i if 0 != msg.param.get_int(Param::Arg2).unwrap_or_default() & 0x1 { info!( msg.context, - 0, "sending secure-join message \'{}\' >>>>>>>>>>>>>>>>>>>>>>>>>", "vg-member-added", ); @@ -656,7 +655,6 @@ pub unsafe fn dc_mimefactory_render(factory: &mut dc_mimefactory_t) -> libc::c_i if strlen(step) > 0 { info!( msg.context, - 0, "sending secure-join message \'{}\' >>>>>>>>>>>>>>>>>>>>>>>>>", as_str(step), ); @@ -726,7 +724,7 @@ pub unsafe fn dc_mimefactory_render(factory: &mut dc_mimefactory_t) -> libc::c_i } } if let Some(grpimage) = grpimage { - info!(factory.context, 0, "setting group image '{}'", grpimage); + info!(factory.context, "setting group image '{}'", grpimage); let mut meta = dc_msg_new_untyped(factory.context); meta.type_0 = Viewtype::Image; meta.param.set(Param::File, grpimage); diff --git a/src/dc_mimeparser.rs b/src/dc_mimeparser.rs index 5d68547fc..467725570 100644 --- a/src/dc_mimeparser.rs +++ b/src/dc_mimeparser.rs @@ -460,7 +460,7 @@ unsafe fn dc_mimeparser_parse_mime_recursive( { info!( mimeparser.context, - 0, "Protected headers found in text/rfc822-headers attachment: Will be ignored.", + "Protected headers found in text/rfc822-headers attachment: Will be ignored.", ); return 0i32; } @@ -474,7 +474,7 @@ unsafe fn dc_mimeparser_parse_mime_recursive( ) != MAILIMF_NO_ERROR as libc::c_int || mimeparser.header_protected.is_null() { - warn!(mimeparser.context, 0, "Protected headers parsing error.",); + warn!(mimeparser.context, "Protected headers parsing error.",); } else { hash_header( &mut mimeparser.header, @@ -485,7 +485,6 @@ unsafe fn dc_mimeparser_parse_mime_recursive( } else { info!( mimeparser.context, - 0, "Protected headers found in MIME header: Will be ignored as we already found an outer one." ); } @@ -667,7 +666,6 @@ unsafe fn dc_mimeparser_parse_mime_recursive( if plain_cnt == 1i32 && html_cnt == 1i32 { warn!( mimeparser.context, - 0i32, "HACK: multipart/mixed message found with PLAIN and HTML, we\'ll skip the HTML part as this seems to be unwanted." ); skip_part = html_part @@ -1072,7 +1070,7 @@ unsafe fn dc_mimeparser_add_single_part_if_known( ); let (res, _, _) = encoding.decode(data); - info!(mimeparser.context, 0, "decoded message: '{}'", res); + info!(mimeparser.context, "decoded message: '{}'", res); if res.is_empty() { /* no error - but nothing to add */ ok_to_continue = false; @@ -1085,7 +1083,6 @@ unsafe fn dc_mimeparser_add_single_part_if_known( } else { warn!( mimeparser.context, - 0, "Cannot convert {} bytes from \"{}\" to \"utf-8\".", decoded_data_bytes as libc::c_int, as_str(charset), diff --git a/src/dc_receive_imf.rs b/src/dc_receive_imf.rs index 7924033a4..805a4c2db 100644 --- a/src/dc_receive_imf.rs +++ b/src/dc_receive_imf.rs @@ -41,7 +41,6 @@ pub unsafe fn dc_receive_imf( ) { info!( context, - 0, "Receiving message {}/{}...", if !server_folder.as_ref().is_empty() { server_folder.as_ref() @@ -61,7 +60,7 @@ pub unsafe fn dc_receive_imf( if mime_parser.header.is_empty() { // Error - even adding an empty record won't help as we do not know the message ID - info!(context, 0, "No header."); + info!(context, "No header."); return; } @@ -189,7 +188,7 @@ pub unsafe fn dc_receive_imf( &mut created_db_entries, &mut create_event_to_send, ) { - info!(context, 0, "{}", err); + info!(context, "{}", err); cleanup( context, @@ -243,7 +242,6 @@ pub unsafe fn dc_receive_imf( info!( context, - 0, "received message {} has Message-Id: {}", server_uid, to_string(rfc724_mid) @@ -447,10 +445,7 @@ unsafe fn add_parts( // check if the message belongs to a mailing list if dc_mimeparser_is_mailinglist_message(mime_parser) { *chat_id = 3; - info!( - context, - 0, "Message belongs to a mailing list and is ignored.", - ); + info!(context, "Message belongs to a mailing list and is ignored.",); } } @@ -482,7 +477,7 @@ unsafe fn add_parts( Contact::scaleup_origin_by_id(context, *from_id, Origin::IncomingReplyTo); info!( context, - 0, "Message is a reply to a known message, mark sender as known.", + "Message is a reply to a known message, mark sender as known.", ); if !incoming_origin.is_verified() { *incoming_origin = Origin::IncomingReplyTo; @@ -724,7 +719,7 @@ unsafe fn add_parts( info!( context, - 0, "Message has {} parts and is assigned to chat #{}.", icnt, *chat_id, + "Message has {} parts and is assigned to chat #{}.", icnt, *chat_id, ); // check event to send @@ -962,7 +957,7 @@ fn save_locations( insert_msg_id, newest_location_id, ) { - error!(context, 0, "Failed to set msg_location_id: {:?}", err); + error!(context, "Failed to set msg_location_id: {:?}", err); } } send_event = true; @@ -1317,7 +1312,7 @@ unsafe fn create_or_lookup_group( if !X_MrAddToGrp.is_null() || !X_MrRemoveFromGrp.is_null() { recreate_member_list = 1; } else if 0 != X_MrGrpNameChanged && !grpname.is_null() && strlen(grpname) < 200 { - info!(context, 0, "updating grpname for chat {}", chat_id); + info!(context, "updating grpname for chat {}", chat_id); if sql::execute( context, &context.sql, @@ -1332,7 +1327,7 @@ unsafe fn create_or_lookup_group( if !X_MrGrpImageChanged.is_empty() { info!( context, - 0, "grp-image-change {} chat {}", X_MrGrpImageChanged, chat_id + "grp-image-change {} chat {}", X_MrGrpImageChanged, chat_id ); let mut changed = false; let mut grpimage = "".to_string(); @@ -1346,13 +1341,13 @@ unsafe fn create_or_lookup_group( .get(Param::File) .map(|s| s.to_string()) .unwrap_or_else(|| "".to_string()); - info!(context, 0, "found image {:?}", grpimage); + info!(context, "found image {:?}", grpimage); changed = true; } } } if changed { - info!(context, 0, "New group image set to '{}'.", grpimage); + info!(context, "New group image set to '{}'.", grpimage); if let Ok(mut chat) = Chat::load_from_db(context, chat_id) { if grpimage.is_empty() { chat.param.remove(Param::ProfileImage); @@ -1741,7 +1736,7 @@ unsafe fn check_verified_properties( ) -> libc::c_int { let verify_fail = |reason: String| { *failure_reason = format!("{}. See \"Info\" for details.", reason).strdup(); - warn!(context, 0, "{}", reason); + warn!(context, "{}", reason); }; let contact = match Contact::load_from_db(context, from_id) { @@ -1812,13 +1807,7 @@ unsafe fn check_verified_properties( || peerstate.verified_key_fingerprint != peerstate.public_key_fingerprint && peerstate.verified_key_fingerprint != peerstate.gossip_key_fingerprint { - info!( - context, - 0, - "{} has verfied {}.", - contact.get_addr(), - to_addr, - ); + info!(context, "{} has verfied {}.", contact.get_addr(), to_addr,); let fp = peerstate.gossip_key_fingerprint.clone(); if let Some(fp) = fp { peerstate.set_verified(0, &fp, 2); diff --git a/src/dc_tools.rs b/src/dc_tools.rs index 60f9b648d..ed6f442d8 100644 --- a/src/dc_tools.rs +++ b/src/dc_tools.rs @@ -852,7 +852,7 @@ pub fn dc_delete_file(context: &Context, path: impl AsRef) -> b match res { Ok(_) => true, Err(_err) => { - warn!(context, 0, "Cannot delete \"{}\".", path.as_ref().display()); + warn!(context, "Cannot delete \"{}\".", path.as_ref().display()); false } } @@ -870,7 +870,6 @@ pub fn dc_copy_file( Err(_) => { error!( context, - 0, "Cannot copy \"{}\" to \"{}\".", src.as_ref().display(), dest.as_ref().display(), @@ -888,7 +887,6 @@ pub fn dc_create_folder(context: &Context, path: impl AsRef) -> Err(_err) => { warn!( context, - 0, "Cannot create directory \"{}\".", path.as_ref().display(), ); @@ -921,7 +919,6 @@ pub fn dc_write_file_safe>( if let Err(_err) = fs::write(&path_abs, buf) { warn!( context, - 0, "Cannot write {} bytes to \"{}\".", buf.len(), path.as_ref().display(), @@ -959,7 +956,6 @@ pub fn dc_read_file_safe>(context: &Context, path: P) Err(_err) => { warn!( context, - 0, "Cannot read \"{}\" or file is empty.", path.as_ref().display() ); diff --git a/src/e2ee.rs b/src/e2ee.rs index 9a84ce17a..d752ed78f 100644 --- a/src/e2ee.rs +++ b/src/e2ee.rs @@ -91,7 +91,7 @@ impl E2eeHelper { if let Some(addr) = addr { let pubkey_ret = load_or_generate_self_public_key(context, &addr).map_err(|err| { - error!(context, 0, "Failed to load public key: {}", err); + error!(context, "Failed to load public key: {}", err); err }); if let Ok(public_key) = pubkey_ret { @@ -113,7 +113,7 @@ impl E2eeHelper { let peerstate = peerstate.unwrap(); info!( context, - 0, "dc_e2ee_encrypt {} has peerstate", recipient_addr + "dc_e2ee_encrypt {} has peerstate", recipient_addr ); if let Some(key) = peerstate.peek_key(min_verified as usize) { keyring.add_owned(key.clone()); @@ -122,7 +122,6 @@ impl E2eeHelper { } else { info!( context, - 0, "dc_e2ee_encrypt {} HAS NO peerstate {}", recipient_addr, peerstate.is_some() @@ -608,7 +607,7 @@ fn load_or_generate_self_public_key(context: &Context, self_addr: impl AsRef { @@ -623,7 +622,6 @@ fn load_or_generate_self_public_key(context: &Context, self_addr: impl AsRef { info!( context, - 0, "Keypair generated in {:.3}s.", start.elapsed().as_secs() ); @@ -691,7 +689,6 @@ unsafe fn update_gossip_peerstates( } else { info!( context, - 0, "Ignoring gossipped \"{}\" as the address is not in To/Cc list.", &header.addr, ); diff --git a/src/imap.rs b/src/imap.rs index ba57005b9..d245612d1 100644 --- a/src/imap.rs +++ b/src/imap.rs @@ -472,12 +472,9 @@ impl Imap { } fn unsetup_handle(&self, context: &Context) { - info!(context, 0, "IMAP unsetup_handle starts"); + info!(context, "IMAP unsetup_handle starts"); - info!( - context, - 0, "IMAP unsetup_handle step 1 (closing down stream)." - ); + info!(context, "IMAP unsetup_handle step 1 (closing down stream)."); let stream = self.stream.write().unwrap().take(); if let Some(stream) = stream { if let Err(err) = stream.shutdown(net::Shutdown::Both) { @@ -487,7 +484,7 @@ impl Imap { info!( context, - 0, "IMAP unsetup_handle step 2 (acquiring session.lock)" + "IMAP unsetup_handle step 2 (acquiring session.lock)" ); if let Some(mut session) = self.session.lock().unwrap().take() { if let Err(err) = session.close() { @@ -495,10 +492,10 @@ impl Imap { } } - info!(context, 0, "IMAP unsetup_handle step 3 (clearing config)."); + info!(context, "IMAP unsetup_handle step 3 (clearing config)."); self.config.write().unwrap().selected_folder = None; self.config.write().unwrap().selected_mailbox = None; - info!(context, 0, "IMAP unsetup_handle step 4 (disconnected).",); + info!(context, "IMAP unsetup_handle step 4 (disconnected).",); } fn free_connect_params(&self) { @@ -551,7 +548,7 @@ impl Imap { Some(ref mut session) => match session.capabilities() { Ok(caps) => { if !context.sql.is_open() { - warn!(context, 0, "IMAP-LOGIN as {} ok but ABORTING", lp.mail_user,); + warn!(context, "IMAP-LOGIN as {} ok but ABORTING", lp.mail_user,); (true, false, false) } else { let can_idle = caps.has_str("IDLE"); @@ -571,7 +568,7 @@ impl Imap { } } Err(err) => { - info!(context, 0, "CAPABILITY command error: {}", err); + info!(context, "CAPABILITY command error: {}", err); (true, false, false) } }, @@ -647,7 +644,7 @@ impl Imap { // deselect existing folder, if needed (it's also done implicitly by SELECT, however, without EXPUNGE then) if self.config.read().unwrap().selected_folder_needs_expunge { if let Some(ref folder) = self.config.read().unwrap().selected_folder { - info!(context, 0, "Expunge messages in \"{}\".", folder); + info!(context, "Expunge messages in \"{}\".", folder); // A CLOSE-SELECT is considerably faster than an EXPUNGE-SELECT, see // https://tools.ietf.org/html/rfc3501#section-6.4.2 @@ -677,7 +674,6 @@ impl Imap { Err(err) => { info!( context, - 0, "Cannot select folder: {}; {:?}.", folder.as_ref(), err @@ -714,7 +710,6 @@ impl Imap { if !self.is_connected() { info!( context, - 0, "Cannot fetch from \"{}\" - not connected.", folder.as_ref() ); @@ -725,7 +720,6 @@ impl Imap { if self.select_folder(context, Some(&folder)) == 0 { info!( context, - 0, "Cannot select folder \"{}\" for fetching.", folder.as_ref() ); @@ -742,7 +736,6 @@ impl Imap { if mailbox.uid_validity.is_none() { error!( context, - 0, "Cannot get UIDVALIDITY for folder \"{}\".", folder.as_ref(), ); @@ -754,7 +747,7 @@ impl Imap { // first time this folder is selected or UIDVALIDITY has changed, init lastseenuid and save it to config if mailbox.exists == 0 { - info!(context, 0, "Folder \"{}\" is empty.", folder.as_ref()); + info!(context, "Folder \"{}\" is empty.", folder.as_ref()); // set lastseenuid=0 for empty folders. // id we do not do this here, we'll miss the first message @@ -773,7 +766,6 @@ impl Imap { self.should_reconnect.store(true, Ordering::Relaxed); info!( context, - 0, "No result returned for folder \"{}\".", folder.as_ref() ); @@ -796,7 +788,6 @@ impl Imap { self.set_config_last_seen_uid(context, &folder, uid_validity, last_seen_uid); info!( context, - 0, "lastseenuid initialized to {} for {}@{}", last_seen_uid, folder.as_ref(), @@ -815,7 +806,7 @@ impl Imap { match session.uid_fetch(set, PREFETCH_FLAGS) { Ok(list) => list, Err(err) => { - warn!(context, 0, "failed to fetch uids: {}", err); + warn!(context, "failed to fetch uids: {}", err); return 0; } } @@ -843,7 +834,6 @@ impl Imap { if self.fetch_single_msg(context, &folder, cur_uid) == 0 { info!( context, - 0, "Read error for message {} from \"{}\", trying over later.", message_id, folder.as_ref() @@ -855,7 +845,6 @@ impl Imap { // check failed info!( context, - 0, "Skipping message {} from \"{}\" by precheck.", message_id, folder.as_ref(), @@ -876,7 +865,6 @@ impl Imap { if read_errors > 0 { warn!( context, - 0, "{} mails read from \"{}\" with {} errors.", read_cnt, folder.as_ref(), @@ -885,7 +873,6 @@ impl Imap { } else { info!( context, - 0, "{} mails read from \"{}\".", read_cnt, folder.as_ref() @@ -930,7 +917,6 @@ impl Imap { self.should_reconnect.store(true, Ordering::Relaxed); warn!( context, - 0, "Error on fetching message #{} from folder \"{}\"; retry={}; error={}.", server_uid, folder.as_ref(), @@ -947,7 +933,6 @@ impl Imap { if msgs.is_empty() { warn!( context, - 0, "Message #{} does not exist in folder \"{}\".", server_uid, folder.as_ref() @@ -1001,7 +986,7 @@ impl Imap { let watch_folder = self.config.read().unwrap().watch_folder.clone(); if self.select_folder(context, watch_folder.as_ref()) == 0 { - warn!(context, 0, "IMAP-IDLE not setup.",); + warn!(context, "IMAP-IDLE not setup.",); return self.fake_idle(context); } @@ -1011,7 +996,7 @@ impl Imap { let (sender, receiver) = std::sync::mpsc::channel(); let v = self.watch.clone(); - info!(context, 0, "IMAP-IDLE SPAWNING"); + info!(context, "IMAP-IDLE SPAWNING"); std::thread::spawn(move || { let &(ref lock, ref cvar) = &*v; if let Some(ref mut session) = &mut *session.lock().unwrap() { @@ -1046,18 +1031,15 @@ impl Imap { let handle_res = |res| match res { Ok(()) => { - info!(context, 0, "IMAP-IDLE has data."); + info!(context, "IMAP-IDLE has data."); } Err(err) => match err { imap::error::Error::ConnectionLost => { - info!( - context, - 0, "IMAP-IDLE wait cancelled, we will reconnect soon." - ); + info!(context, "IMAP-IDLE wait cancelled, we will reconnect soon."); self.should_reconnect.store(true, Ordering::Relaxed); } _ => { - warn!(context, 0, "IMAP-IDLE returns unknown value: {}", err); + warn!(context, "IMAP-IDLE returns unknown value: {}", err); } }, }; @@ -1073,7 +1055,7 @@ impl Imap { if let Ok(res) = worker.as_ref().unwrap().try_recv() { handle_res(res); } else { - info!(context, 0, "IMAP-IDLE interrupted"); + info!(context, "IMAP-IDLE interrupted"); } drop(worker.take()); @@ -1091,7 +1073,7 @@ impl Imap { let fake_idle_start_time = SystemTime::now(); let mut wait_long = false; - info!(context, 0, "IMAP-fake-IDLEing..."); + info!(context, "IMAP-fake-IDLEing..."); let mut do_fake_idle = true; while do_fake_idle { @@ -1167,7 +1149,6 @@ impl Imap { } else if folder.as_ref() == dest_folder.as_ref() { info!( context, - 0, "Skip moving message; message {}/{} is already in {}...", folder.as_ref(), uid, @@ -1178,7 +1159,6 @@ impl Imap { } else { info!( context, - 0, "Moving message {}/{} to {}...", folder.as_ref(), uid, @@ -1188,7 +1168,6 @@ impl Imap { if self.select_folder(context, Some(folder.as_ref())) == 0 { warn!( context, - 0, "Cannot select folder {} for moving message.", folder.as_ref() ); @@ -1202,7 +1181,6 @@ impl Imap { Err(err) => { info!( context, - 0, "Cannot move message, fallback to COPY/DELETE {}/{} to {}: {}", folder.as_ref(), uid, @@ -1223,7 +1201,7 @@ impl Imap { Ok(_) => true, Err(err) => { eprintln!("error copy: {:?}", err); - info!(context, 0, "Cannot copy message.",); + info!(context, "Cannot copy message.",); false } @@ -1234,7 +1212,7 @@ impl Imap { if copied { if self.add_flag(context, uid, "\\Deleted") == 0 { - warn!(context, 0, "Cannot mark message as \"Deleted\".",); + warn!(context, "Cannot mark message as \"Deleted\".",); } self.config.write().unwrap().selected_folder_needs_expunge = true; res = DC_SUCCESS; @@ -1271,7 +1249,7 @@ impl Imap { Err(err) => { warn!( context, - 0, "IMAP failed to store: ({}, {}) {:?}", set, query, err + "IMAP failed to store: ({}, {}) {:?}", set, query, err ); } } @@ -1294,7 +1272,6 @@ impl Imap { } else if self.is_connected() { info!( context, - 0, "Marking message {}/{} as seen...", folder.as_ref(), uid, @@ -1303,12 +1280,11 @@ impl Imap { if self.select_folder(context, Some(folder.as_ref())) == 0 { warn!( context, - 0, "Cannot select folder {} for setting SEEN flag.", folder.as_ref(), ); } else if self.add_flag(context, uid, "\\Seen") == 0 { - warn!(context, 0, "Cannot mark message as seen.",); + warn!(context, "Cannot mark message as seen.",); } else { res = DC_SUCCESS } @@ -1335,7 +1311,6 @@ impl Imap { } else if self.is_connected() { info!( context, - 0, "Marking message {}/{} as $MDNSent...", folder.as_ref(), uid, @@ -1344,7 +1319,6 @@ impl Imap { if self.select_folder(context, Some(folder.as_ref())) == 0 { warn!( context, - 0, "Cannot select folder {} for setting $MDNSent flag.", folder.as_ref() ); @@ -1411,16 +1385,16 @@ impl Imap { }; if res == DC_SUCCESS { - info!(context, 0, "$MDNSent just set and MDN will be sent."); + info!(context, "$MDNSent just set and MDN will be sent."); } else { - info!(context, 0, "$MDNSent already set and MDN already sent."); + info!(context, "$MDNSent already set and MDN already sent."); } } } else { res = DC_SUCCESS; info!( context, - 0, "Cannot store $MDNSent flags, risk sending duplicate MDN.", + "Cannot store $MDNSent flags, risk sending duplicate MDN.", ); } } @@ -1451,7 +1425,6 @@ impl Imap { } else { info!( context, - 0, "Marking message \"{}\", {}/{} for deletion...", message_id.as_ref(), folder.as_ref(), @@ -1461,7 +1434,6 @@ impl Imap { if self.select_folder(context, Some(&folder)) == 0 { warn!( context, - 0, "Cannot select folder {} for deleting message.", folder.as_ref() ); @@ -1482,7 +1454,6 @@ impl Imap { { warn!( context, - 0, "Cannot delete on IMAP, {}/{} does not match {}.", folder.as_ref(), server_uid, @@ -1496,7 +1467,6 @@ impl Imap { warn!( context, - 0, "Cannot delete on IMAP, {}/{} not found.", folder.as_ref(), server_uid, @@ -1508,7 +1478,7 @@ impl Imap { // mark the message for deletion if self.add_flag(context, *server_uid, "\\Deleted") == 0 { - warn!(context, 0, "Cannot mark message as \"Deleted\"."); + warn!(context, "Cannot mark message as \"Deleted\"."); } else { self.config.write().unwrap().selected_folder_needs_expunge = true; success = true @@ -1528,7 +1498,7 @@ impl Imap { return; } - info!(context, 0, "Configuring IMAP-folders."); + info!(context, "Configuring IMAP-folders."); let folders = self.list_folders(context).unwrap(); let delimiter = self.config.read().unwrap().imap_delimiter; @@ -1547,21 +1517,19 @@ impl Imap { }); if mvbox_folder.is_none() && 0 != (flags as usize & DC_CREATE_MVBOX) { - info!(context, 0, "Creating MVBOX-folder \"DeltaChat\"...",); + info!(context, "Creating MVBOX-folder \"DeltaChat\"...",); if let Some(ref mut session) = &mut *self.session.lock().unwrap() { match session.create("DeltaChat") { Ok(_) => { mvbox_folder = Some("DeltaChat".into()); - info!(context, 0, "MVBOX-folder created.",); + info!(context, "MVBOX-folder created.",); } Err(err) => { warn!( context, - 0, - "Cannot create MVBOX-folder, using trying INBOX subfolder. ({})", - err + "Cannot create MVBOX-folder, using trying INBOX subfolder. ({})", err ); match session.create(&fallback_folder) { @@ -1569,11 +1537,11 @@ impl Imap { mvbox_folder = Some(fallback_folder); info!( context, - 0, "MVBOX-folder created as INBOX subfolder. ({})", err + "MVBOX-folder created as INBOX subfolder. ({})", err ); } Err(err) => { - warn!(context, 0, "Cannot create MVBOX-folder. ({})", err); + warn!(context, "Cannot create MVBOX-folder. ({})", err); } } } @@ -1619,13 +1587,13 @@ impl Imap { match session.list(Some(""), Some("*")) { Ok(list) => { if list.is_empty() { - warn!(context, 0, "Folder list is empty.",); + warn!(context, "Folder list is empty.",); } Some(list) } Err(err) => { eprintln!("list error: {:?}", err); - warn!(context, 0, "Cannot get folder list.",); + warn!(context, "Cannot get folder list.",); None } diff --git a/src/job.rs b/src/job.rs index 38e17cce8..491eb714f 100644 --- a/src/job.rs +++ b/src/job.rs @@ -159,7 +159,7 @@ impl Job { if 0 != self.foreign_id && !dc_msg_exists(context, self.foreign_id) { warn!( context, - 0, "Message {} for job {} does not exist", self.foreign_id, self.job_id, + "Message {} for job {} does not exist", self.foreign_id, self.job_id, ); return; }; @@ -197,7 +197,7 @@ impl Job { } } } else { - warn!(context, 0, "Missing recipients for job {}", self.job_id,); + warn!(context, "Missing recipients for job {}", self.job_id,); } } } @@ -277,7 +277,7 @@ impl Job { if dc_rfc724_mid_cnt(context, msg.rfc724_mid) != 1 { info!( context, - 0, "The message is deleted from the server when all parts are deleted.", + "The message is deleted from the server when all parts are deleted.", ); delete_from_server = 0i32 } @@ -440,18 +440,17 @@ pub fn perform_imap_fetch(context: &Context) { .unwrap_or_else(|| 1) == 0 { - info!(context, 0, "INBOX-watch disabled.",); + info!(context, "INBOX-watch disabled.",); return; } - info!(context, 0, "INBOX-fetch started...",); + info!(context, "INBOX-fetch started...",); inbox.fetch(context); if inbox.should_reconnect() { - info!(context, 0, "INBOX-fetch aborted, starting over...",); + info!(context, "INBOX-fetch aborted, starting over...",); inbox.fetch(context); } info!( context, - 0, "INBOX-fetch done in {:.4} ms.", start.elapsed().as_nanos() as f64 / 1000.0, ); @@ -465,13 +464,13 @@ pub fn perform_imap_idle(context: &Context) { if *context.perform_inbox_jobs_needed.clone().read().unwrap() { info!( context, - 0, "INBOX-IDLE will not be started because of waiting jobs." + "INBOX-IDLE will not be started because of waiting jobs." ); return; } - info!(context, 0, "INBOX-IDLE started..."); + info!(context, "INBOX-IDLE started..."); inbox.idle(context); - info!(context, 0, "INBOX-IDLE ended."); + info!(context, "INBOX-IDLE ended."); } pub fn perform_mvbox_fetch(context: &Context) { @@ -548,16 +547,16 @@ pub fn perform_smtp_jobs(context: &Context) { state.perform_jobs_needed = 0; if state.suspended { - info!(context, 0, "SMTP-jobs suspended.",); + info!(context, "SMTP-jobs suspended.",); return; } state.doing_jobs = true; probe_smtp_network }; - info!(context, 0, "SMTP-jobs started...",); + info!(context, "SMTP-jobs started...",); job_perform(context, Thread::Smtp, probe_smtp_network); - info!(context, 0, "SMTP-jobs ended."); + info!(context, "SMTP-jobs ended."); { let &(ref lock, _) = &*context.smtp_state.clone(); @@ -568,7 +567,7 @@ pub fn perform_smtp_jobs(context: &Context) { } pub fn perform_smtp_idle(context: &Context) { - info!(context, 0, "SMTP-idle started...",); + info!(context, "SMTP-idle started...",); { let &(ref lock, ref cvar) = &*context.smtp_state.clone(); let mut state = lock.lock().unwrap(); @@ -576,7 +575,7 @@ pub fn perform_smtp_idle(context: &Context) { if state.perform_jobs_needed == 1 { info!( context, - 0, "SMTP-idle will not be started because of waiting jobs.", + "SMTP-idle will not be started because of waiting jobs.", ); } else { let dur = get_next_wakeup_time(context, Thread::Smtp); @@ -594,7 +593,7 @@ pub fn perform_smtp_idle(context: &Context) { } } - info!(context, 0, "SMTP-idle ended.",); + info!(context, "SMTP-idle ended.",); } fn get_next_wakeup_time(context: &Context, thread: Thread) -> Duration { @@ -653,7 +652,7 @@ pub unsafe fn job_send_msg(context: &Context, msg_id: uint32_t) -> libc::c_int { if mimefactory.is_err() || mimefactory.as_ref().unwrap().from_addr.is_null() { warn!( context, - 0, "Cannot load data to send, maybe the message is deleted in between.", + "Cannot load data to send, maybe the message is deleted in between.", ); } else { let mut mimefactory = mimefactory.unwrap(); @@ -695,7 +694,6 @@ pub unsafe fn job_send_msg(context: &Context, msg_id: uint32_t) -> libc::c_int { { warn!( context, - 0, "e2e encryption unavailable {} - {:?}", msg_id, mimefactory.msg.param.get_int(Param::GuranteeE2ee), @@ -726,7 +724,7 @@ pub unsafe fn job_send_msg(context: &Context, msg_id: uint32_t) -> libc::c_int { if let Err(err) = location::set_kml_sent_timestamp(context, mimefactory.msg.chat_id, time()) { - error!(context, 0, "Failed to set kml sent_timestamp: {:?}", err); + error!(context, "Failed to set kml sent_timestamp: {:?}", err); } if !mimefactory.msg.hidden { if let Err(err) = location::set_msg_location_id( @@ -734,7 +732,7 @@ pub unsafe fn job_send_msg(context: &Context, msg_id: uint32_t) -> libc::c_int { mimefactory.msg.id, mimefactory.out_last_added_location_id, ) { - error!(context, 0, "Failed to set msg_location_id: {:?}", err); + error!(context, "Failed to set msg_location_id: {:?}", err); } } } @@ -757,14 +755,14 @@ pub unsafe fn job_send_msg(context: &Context, msg_id: uint32_t) -> libc::c_int { } pub fn perform_imap_jobs(context: &Context) { - info!(context, 0, "dc_perform_imap_jobs starting.",); + info!(context, "dc_perform_imap_jobs starting.",); let probe_imap_network = *context.probe_imap_network.clone().read().unwrap(); *context.probe_imap_network.write().unwrap() = false; *context.perform_inbox_jobs_needed.write().unwrap() = false; job_perform(context, Thread::Imap, probe_imap_network); - info!(context, 0, "dc_perform_imap_jobs ended.",); + info!(context, "dc_perform_imap_jobs ended.",); } fn job_perform(context: &Context, thread: Thread, probe_network: bool) { @@ -812,14 +810,13 @@ fn job_perform(context: &Context, thread: Thread, probe_network: bool) { match jobs { Ok(ref _res) => {} Err(ref err) => { - info!(context, 0, "query failed: {:?}", err); + info!(context, "query failed: {:?}", err); } } for mut job in jobs.unwrap_or_default() { info!( context, - 0, "{}-job #{}, action {} started...", if thread == Thread::Imap { "INBOX" @@ -858,7 +855,7 @@ fn job_perform(context: &Context, thread: Thread, probe_network: bool) { match job.action { Action::Unknown => { - warn!(context, 0, "Unknown job id found"); + warn!(context, "Unknown job id found"); } Action::SendMsgToSmtp => job.do_DC_JOB_SEND(context), Action::DeleteMsgOnImap => job.do_DC_JOB_DELETE_MSG_ON_IMAP(context), @@ -902,7 +899,6 @@ fn job_perform(context: &Context, thread: Thread, probe_network: bool) { // just try over next loop unconditionally, the ui typically interrupts idle when the file (video) is ready info!( context, - 0, "{}-job #{} not yet ready and will be delayed.", if thread == Thread::Imap { "INBOX" @@ -920,7 +916,6 @@ fn job_perform(context: &Context, thread: Thread, probe_network: bool) { job.update(context); info!( context, - 0, "{}-job #{} not succeeded on try #{}, retry in ADD_TIME+{} (in {} seconds).", if thread == Thread::Imap { "INBOX" @@ -1019,7 +1014,6 @@ fn add_smtp_job(context: &Context, action: Action, mimefactory: &dc_mimefactory_ if pathNfilename.is_null() { error!( context, - 0, "Could not find free file name for message with ID <{}>.", to_string(mimefactory.rfc724_mid), ); @@ -1035,7 +1029,6 @@ fn add_smtp_job(context: &Context, action: Action, mimefactory: &dc_mimefactory_ { error!( context, - 0, "Could not write message <{}> to \"{}\".", to_string(mimefactory.rfc724_mid), as_str(pathNfilename), @@ -1079,7 +1072,7 @@ pub fn job_add( delay_seconds: i64, ) { if action == Action::Unknown { - error!(context, 0, "Invalid action passed to job_add"); + error!(context, "Invalid action passed to job_add"); return; } @@ -1108,7 +1101,7 @@ pub fn job_add( } pub fn interrupt_smtp_idle(context: &Context) { - info!(context, 0, "Interrupting SMTP-idle...",); + info!(context, "Interrupting SMTP-idle...",); let &(ref lock, ref cvar) = &*context.smtp_state.clone(); let mut state = lock.lock().unwrap(); @@ -1119,7 +1112,7 @@ pub fn interrupt_smtp_idle(context: &Context) { } pub fn interrupt_imap_idle(context: &Context) { - info!(context, 0, "Interrupting IMAP-IDLE...",); + info!(context, "Interrupting IMAP-IDLE...",); *context.perform_inbox_jobs_needed.write().unwrap() = true; context.inbox.read().unwrap().interrupt_idle(); diff --git a/src/job_thread.rs b/src/job_thread.rs index d1059fd53..39384c159 100644 --- a/src/job_thread.rs +++ b/src/job_thread.rs @@ -30,7 +30,7 @@ impl JobThread { } pub fn suspend(&self, context: &Context) { - info!(context, 0, "Suspending {}-thread.", self.name,); + info!(context, "Suspending {}-thread.", self.name,); { self.state.0.lock().unwrap().suspended = true; } @@ -45,7 +45,7 @@ impl JobThread { } pub fn unsuspend(&self, context: &Context) { - info!(context, 0, "Unsuspending {}-thread.", self.name); + info!(context, "Unsuspending {}-thread.", self.name); let &(ref lock, ref cvar) = &*self.state.clone(); let mut state = lock.lock().unwrap(); @@ -60,7 +60,7 @@ impl JobThread { self.state.0.lock().unwrap().jobs_needed = 1; } - info!(context, 0, "Interrupting {}-IDLE...", self.name); + info!(context, "Interrupting {}-IDLE...", self.name); self.imap.interrupt_idle(); @@ -86,16 +86,15 @@ impl JobThread { if use_network { let start = std::time::Instant::now(); if self.connect_to_imap(context) { - info!(context, 0, "{}-fetch started...", self.name); + info!(context, "{}-fetch started...", self.name); self.imap.fetch(context); if self.imap.should_reconnect() { - info!(context, 0, "{}-fetch aborted, starting over...", self.name,); + info!(context, "{}-fetch aborted, starting over...", self.name,); self.imap.fetch(context); } info!( context, - 0, "{}-fetch done in {:.3} ms.", self.name, start.elapsed().as_millis(), @@ -142,7 +141,6 @@ impl JobThread { if 0 != state.jobs_needed { info!( context, - 0, "{}-IDLE will not be started as it was interrupted while not ideling.", self.name, ); @@ -172,9 +170,9 @@ impl JobThread { } self.connect_to_imap(context); - info!(context, 0, "{}-IDLE started...", self.name,); + info!(context, "{}-IDLE started...", self.name,); self.imap.idle(context); - info!(context, 0, "{}-IDLE ended.", self.name); + info!(context, "{}-IDLE ended.", self.name); self.state.0.lock().unwrap().using_handle = false; } diff --git a/src/key.rs b/src/key.rs index bb7ac3115..f6e0b2f83 100644 --- a/src/key.rs +++ b/src/key.rs @@ -245,7 +245,7 @@ impl Key { file_content_c.as_bytes().len(), ) } { - error!(context, 0, "Cannot write key to {}", to_string(file)); + error!(context, "Cannot write key to {}", to_string(file)); false } else { true diff --git a/src/location.rs b/src/location.rs index 11569e223..504276086 100644 --- a/src/location.rs +++ b/src/location.rs @@ -84,7 +84,6 @@ impl Kml { Err(e) => { error!( context, - 0, "Location parsing: Error at position {}: {:?}", reader.buffer_position(), e @@ -546,7 +545,7 @@ pub fn job_do_DC_JOB_MAYBE_SEND_LOCATIONS(context: &Context, _job: &Job) { let mut continue_streaming: libc::c_int = 1; info!( context, - 0, " ----------------- MAYBE_SEND_LOCATIONS -------------- ", + " ----------------- MAYBE_SEND_LOCATIONS -------------- ", ); context diff --git a/src/log.rs b/src/log.rs index dabffd14f..43491ed53 100644 --- a/src/log.rs +++ b/src/log.rs @@ -1,44 +1,44 @@ #[macro_export] macro_rules! info { - ($ctx:expr, $data1:expr, $msg:expr) => { - info!($ctx, $data1, $msg,) + ($ctx:expr, $msg:expr) => { + info!($ctx, $msg,) }; - ($ctx:expr, $data1:expr, $msg:expr, $($args:expr),* $(,)?) => { + ($ctx:expr, $msg:expr, $($args:expr),* $(,)?) => { #[allow(unused_unsafe)] unsafe { let formatted = format!($msg, $($args),*); let formatted_c = std::ffi::CString::new(formatted).unwrap(); - $ctx.call_cb($crate::constants::Event::INFO, $data1 as libc::uintptr_t, + $ctx.call_cb($crate::constants::Event::INFO, 0, formatted_c.as_ptr() as libc::uintptr_t); }}; } #[macro_export] macro_rules! warn { - ($ctx:expr, $data1:expr, $msg:expr) => { - warn!($ctx, $data1, $msg,) + ($ctx:expr, $msg:expr) => { + warn!($ctx, $msg,) }; - ($ctx:expr, $data1:expr, $msg:expr, $($args:expr),* $(,)?) => { + ($ctx:expr, $msg:expr, $($args:expr),* $(,)?) => { #[allow(unused_unsafe)] unsafe { let formatted = format!($msg, $($args),*); let formatted_c = std::ffi::CString::new(formatted).unwrap(); - $ctx.call_cb($crate::constants::Event::WARNING, $data1 as libc::uintptr_t, + $ctx.call_cb($crate::constants::Event::WARNING, 0, formatted_c.as_ptr() as libc::uintptr_t); }}; } #[macro_export] macro_rules! error { - ($ctx:expr, $data1:expr, $msg:expr) => { - error!($ctx, $data1, $msg,) + ($ctx:expr, $msg:expr) => { + error!($ctx, $msg,) }; - ($ctx:expr, $data1:expr, $msg:expr, $($args:expr),* $(,)?) => { + ($ctx:expr, $msg:expr, $($args:expr),* $(,)?) => { #[allow(unused_unsafe)] unsafe { let formatted = format!($msg, $($args),*); let formatted_c = std::ffi::CString::new(formatted).unwrap(); - $ctx.call_cb($crate::constants::Event::ERROR, $data1 as libc::uintptr_t, + $ctx.call_cb($crate::constants::Event::ERROR, 0, formatted_c.as_ptr() as libc::uintptr_t); }}; } diff --git a/src/message.rs b/src/message.rs index b0e9a3251..8b828b199 100644 --- a/src/message.rs +++ b/src/message.rs @@ -477,7 +477,7 @@ pub fn dc_msg_load_from_db<'a>(context: &'a Context, id: u32) -> Result libc::c_int { ) { Ok(res) => res, Err(err) => { - error!(context, 0, "dc_get_real_msg_cnt() failed. {}", err); + error!(context, "dc_get_real_msg_cnt() failed. {}", err); 0 } } @@ -1219,7 +1219,7 @@ pub fn dc_get_deaddrop_msg_cnt(context: &Context) -> size_t { ) { Ok(res) => res as size_t, Err(err) => { - error!(context, 0, "dc_get_deaddrop_msg_cnt() failed. {}", err); + error!(context, "dc_get_deaddrop_msg_cnt() failed. {}", err); 0 } } @@ -1234,7 +1234,7 @@ pub fn dc_rfc724_mid_cnt(context: &Context, rfc724_mid: *const libc::c_char) -> ) { Ok(res) => res, Err(err) => { - error!(context, 0, "dc_get_rfc724_mid_cnt() failed. {}", err); + error!(context, "dc_get_rfc724_mid_cnt() failed. {}", err); 0 } } @@ -1288,7 +1288,7 @@ pub fn dc_update_server_uid( ) { Ok(_) => {} Err(err) => { - warn!(context, 0, "msg: failed to update server_uid: {}", err); + warn!(context, "msg: failed to update server_uid: {}", err); } } } diff --git a/src/oauth2.rs b/src/oauth2.rs index 0cd1cad71..89c94446f 100644 --- a/src/oauth2.rs +++ b/src/oauth2.rs @@ -97,10 +97,7 @@ pub fn dc_get_oauth2_access_token( let (redirect_uri, token_url, update_redirect_uri_on_success) = if refresh_token.is_none() || refresh_token_for != code.as_ref() { - info!( - context, - 0, "Generate OAuth2 refresh_token and access_token...", - ); + info!(context, "Generate OAuth2 refresh_token and access_token...",); ( context .sql @@ -112,7 +109,7 @@ pub fn dc_get_oauth2_access_token( } else { info!( context, - 0, "Regenerate OAuth2 access_token by refresh_token...", + "Regenerate OAuth2 access_token by refresh_token...", ); ( context @@ -134,7 +131,7 @@ pub fn dc_get_oauth2_access_token( if response.is_err() { warn!( context, - 0, "Error calling OAuth2 at {}: {:?}", token_url, response + "Error calling OAuth2 at {}: {:?}", token_url, response ); return None; } @@ -142,7 +139,6 @@ pub fn dc_get_oauth2_access_token( if !response.status().is_success() { warn!( context, - 0, "Error calling OAuth2 at {}: {:?}", token_url, response.status() @@ -154,7 +150,7 @@ pub fn dc_get_oauth2_access_token( if parsed.is_err() { warn!( context, - 0, "Failed to parse OAuth2 JSON response from {}: error: {:?}", token_url, parsed + "Failed to parse OAuth2 JSON response from {}: error: {:?}", token_url, parsed ); return None; } @@ -195,12 +191,12 @@ pub fn dc_get_oauth2_access_token( .ok(); } } else { - warn!(context, 0, "Failed to find OAuth2 access token"); + warn!(context, "Failed to find OAuth2 access token"); } response.access_token } else { - warn!(context, 0, "Internal OAuth2 error: 2"); + warn!(context, "Internal OAuth2 error: 2"); None } @@ -268,17 +264,12 @@ impl Oauth2 { // } let response = reqwest::Client::new().get(&userinfo_url).send(); if response.is_err() { - warn!(context, 0, "Error getting userinfo: {:?}", response); + warn!(context, "Error getting userinfo: {:?}", response); return None; } let mut response = response.unwrap(); if !response.status().is_success() { - warn!( - context, - 0, - "Error getting userinfo: {:?}", - response.status() - ); + warn!(context, "Error getting userinfo: {:?}", response.status()); return None; } @@ -286,19 +277,19 @@ impl Oauth2 { if parsed.is_err() { warn!( context, - 0, "Failed to parse userinfo JSON response: {:?}", parsed + "Failed to parse userinfo JSON response: {:?}", parsed ); return None; } if let Ok(response) = parsed { let addr = response.get("email"); if addr.is_none() { - warn!(context, 0, "E-mail missing in userinfo."); + warn!(context, "E-mail missing in userinfo."); } addr.map(|addr| addr.to_string()) } else { - warn!(context, 0, "Failed to parse userinfo."); + warn!(context, "Failed to parse userinfo."); None } } diff --git a/src/qr.rs b/src/qr.rs index 29da393e5..31b2a428c 100644 --- a/src/qr.rs +++ b/src/qr.rs @@ -37,7 +37,7 @@ impl Into for Error { pub fn check_qr(context: &Context, qr: impl AsRef) -> Lot { let qr = qr.as_ref(); - info!(context, 0, "Scanned QR code: {}", qr); + info!(context, "Scanned QR code: {}", qr); if qr.starts_with(OPENPGP4FPR_SCHEME) { decode_openpgp(context, qr) diff --git a/src/securejoin.rs b/src/securejoin.rs index 35944d0ca..143d4a40a 100644 --- a/src/securejoin.rs +++ b/src/securejoin.rs @@ -85,7 +85,7 @@ pub fn dc_get_securejoin_qr(context: &Context, group_chat_id: uint32_t) -> Optio let self_addr = match context.sql.get_config(context, "configured_addr") { Some(addr) => addr, None => { - error!(context, 0, "Not configured, cannot generate QR code.",); + error!(context, "Not configured, cannot generate QR code.",); return None; } }; @@ -123,10 +123,7 @@ pub fn dc_get_securejoin_qr(context: &Context, group_chat_id: uint32_t) -> Optio &auth, )) } else { - error!( - context, - 0, "Cannot get QR-code for chat-id {}", group_chat_id, - ); + error!(context, "Cannot get QR-code for chat-id {}", group_chat_id,); return None; } } else { @@ -136,7 +133,7 @@ pub fn dc_get_securejoin_qr(context: &Context, group_chat_id: uint32_t) -> Optio )) }; - info!(context, 0, "Generated QR code: {}", qr.as_ref().unwrap()); + info!(context, "Generated QR code: {}", qr.as_ref().unwrap()); qr } @@ -182,7 +179,7 @@ pub fn dc_join_securejoin(context: &Context, qr: &str) -> uint32_t { let mut contact_chat_id: uint32_t = 0; let mut join_vg: bool = false; - info!(context, 0, "Requesting secure-join ...",); + info!(context, "Requesting secure-join ...",); ensure_secret_key_exists(context).ok(); if !dc_alloc_ongoing(context) { return cleanup(&context, contact_chat_id, false, join_vg); @@ -190,12 +187,12 @@ pub fn dc_join_securejoin(context: &Context, qr: &str) -> uint32_t { let qr_scan = check_qr(context, &qr); if qr_scan.state != LotState::QrAskVerifyContact && qr_scan.state != LotState::QrAskVerifyGroup { - error!(context, 0, "Unknown QR code.",); + error!(context, "Unknown QR code.",); return cleanup(&context, contact_chat_id, true, join_vg); } contact_chat_id = chat::create_by_contact_id(context, qr_scan.id).unwrap_or_default(); if contact_chat_id == 0 { - error!(context, 0, "Unknown contact.",); + error!(context, "Unknown contact.",); return cleanup(&context, contact_chat_id, true, join_vg); } if check_exit(context) { @@ -221,7 +218,7 @@ pub fn dc_join_securejoin(context: &Context, qr: &str) -> uint32_t { .unwrap(), contact_chat_id, ) { - info!(context, 0, "Taking protocol shortcut."); + info!(context, "Taking protocol shortcut."); context.bob.write().unwrap().expects = DC_VC_CONTACT_CONFIRM; joiner_progress!(context, chat_id_2_contact_id(context, contact_chat_id), 400); let own_fingerprint = get_self_fingerprint(context).unwrap(); @@ -359,7 +356,7 @@ pub fn handle_securejoin_handshake( }; info!( context, - 0, ">>>>>>>>>>>>>>>>>>>>>>>>> secure-join message \'{}\' received", step, + ">>>>>>>>>>>>>>>>>>>>>>>>> secure-join message \'{}\' received", step, ); let (contact_chat_id, contact_chat_id_blocked) = chat::create_or_lookup_by_contact_id(context, contact_id, Blocked::Not).unwrap_or_default(); @@ -383,15 +380,15 @@ pub fn handle_securejoin_handshake( let invitenumber = match lookup_field(mimeparser, "Secure-Join-Invitenumber") { Some(n) => n, None => { - warn!(context, 0, "Secure-join denied (invitenumber missing).",); + warn!(context, "Secure-join denied (invitenumber missing).",); return ret; } }; if !token::exists(context, token::Namespace::InviteNumber, &invitenumber) { - warn!(context, 0, "Secure-join denied (bad invitenumber).",); + warn!(context, "Secure-join denied (bad invitenumber).",); return ret; } - info!(context, 0, "Secure-join requested.",); + info!(context, "Secure-join requested.",); inviter_progress!(context, contact_id, 300); send_handshake_msg( @@ -413,7 +410,7 @@ pub fn handle_securejoin_handshake( }; if cond { - warn!(context, 0, "auth-required message out of sync.",); + warn!(context, "auth-required message out of sync.",); // no error, just aborted somehow or a mail from another handshake return ret; } @@ -442,7 +439,7 @@ pub fn handle_securejoin_handshake( end_bobs_joining(context, DC_BOB_ERROR); return ret; } - info!(context, 0, "Fingerprint verified.",); + info!(context, "Fingerprint verified.",); own_fingerprint = get_self_fingerprint(context).unwrap(); joiner_progress!(context, contact_id, 400); context.bob.write().unwrap().expects = DC_VC_CONTACT_CONFIRM; @@ -494,7 +491,7 @@ pub fn handle_securejoin_handshake( ); return ret; } - info!(context, 0, "Fingerprint verified.",); + info!(context, "Fingerprint verified.",); // verify that the `Secure-Join-Auth:`-header matches the secret written to the QR code let auth_0 = match lookup_field(mimeparser, "Secure-Join-Auth") { Some(auth) => auth, @@ -520,7 +517,7 @@ pub fn handle_securejoin_handshake( return ret; } Contact::scaleup_origin_by_id(context, contact_id, Origin::SecurejoinInvited); - info!(context, 0, "Auth verified.",); + info!(context, "Auth verified.",); secure_connection_established(context, contact_chat_id); emit_event!(context, Event::CONTACTS_CHANGED, contact_id, 0); inviter_progress!(context, contact_id, 600); @@ -528,7 +525,7 @@ pub fn handle_securejoin_handshake( let field_grpid = lookup_field(mimeparser, "Secure-Join-Group").unwrap_or_default(); let (group_chat_id, _, _) = chat::get_chat_id_by_grpid(context, &field_grpid); if group_chat_id == 0 { - error!(context, 0, "Chat {} not found.", &field_grpid); + error!(context, "Chat {} not found.", &field_grpid); return ret; } else { chat::add_contact_to_chat_ex(context, group_chat_id, contact_id, 0x1i32); @@ -543,7 +540,7 @@ pub fn handle_securejoin_handshake( ret = DC_HANDSHAKE_CONTINUE_NORMAL_PROCESSING; } if context.bob.read().unwrap().expects != DC_VC_CONTACT_CONFIRM { - info!(context, 0, "Message belongs to a different handshake.",); + info!(context, "Message belongs to a different handshake.",); return ret; } let cond = { @@ -554,7 +551,7 @@ pub fn handle_securejoin_handshake( if cond { warn!( context, - 0, "Message out of sync or belongs to a different handshake.", + "Message out of sync or belongs to a different handshake.", ); return ret; } @@ -597,7 +594,7 @@ pub fn handle_securejoin_handshake( let cg_member_added = lookup_field(mimeparser, "Chat-Group-Member-Added").unwrap_or_default(); if join_vg && !addr_equals_self(context, cg_member_added) { - info!(context, 0, "Message belongs to a different handshake (scaled up contact anyway to allow creation of group)."); + info!(context, "Message belongs to a different handshake (scaled up contact anyway to allow creation of group)."); return ret; } secure_connection_established(context, contact_chat_id); @@ -621,18 +618,18 @@ pub fn handle_securejoin_handshake( ============================================================ */ if let Ok(contact) = Contact::get_by_id(context, contact_id) { if contact.is_verified() == VerifiedStatus::Unverified { - warn!(context, 0, "vg-member-added-received invalid.",); + warn!(context, "vg-member-added-received invalid.",); return ret; } inviter_progress!(context, contact_id, 800); inviter_progress!(context, contact_id, 1000); } else { - warn!(context, 0, "vg-member-added-received invalid.",); + warn!(context, "vg-member-added-received invalid.",); return ret; } } _ => { - warn!(context, 0, "invalid step: {}", step); + warn!(context, "invalid step: {}", step); } } if ret == DC_HANDSHAKE_STOP_NORMAL_PROCESSING { @@ -694,7 +691,7 @@ fn could_not_establish_secure_connection( ); chat::add_device_msg(context, contact_chat_id, &msg); - error!(context, 0, "{} ({})", &msg, details); + error!(context, "{} ({})", &msg, details); } fn mark_peer_as_verified(context: &Context, fingerprint: impl AsRef) -> Result<(), Error> { @@ -723,13 +720,13 @@ fn encrypted_and_signed( expected_fingerprint: impl AsRef, ) -> bool { if !mimeparser.e2ee_helper.encrypted { - warn!(mimeparser.context, 0, "Message not encrypted.",); + warn!(mimeparser.context, "Message not encrypted.",); false } else if mimeparser.e2ee_helper.signatures.len() <= 0 { - warn!(mimeparser.context, 0, "Message not signed.",); + warn!(mimeparser.context, "Message not signed.",); false } else if expected_fingerprint.as_ref().is_empty() { - warn!(mimeparser.context, 0, "Fingerprint for comparison missing.",); + warn!(mimeparser.context, "Fingerprint for comparison missing.",); false } else if !mimeparser .e2ee_helper @@ -738,7 +735,6 @@ fn encrypted_and_signed( { warn!( mimeparser.context, - 0, "Message does not match expected fingerprint {}.", expected_fingerprint.as_ref(), ); diff --git a/src/smtp.rs b/src/smtp.rs index 291d5cd6c..e9c815a01 100644 --- a/src/smtp.rs +++ b/src/smtp.rs @@ -45,7 +45,7 @@ impl Smtp { /// Connect using the provided login params pub fn connect(&mut self, context: &Context, lp: &LoginParam) -> bool { if self.is_connected() { - warn!(context, 0, "SMTP already connected."); + warn!(context, "SMTP already connected."); return true; } @@ -119,7 +119,7 @@ impl Smtp { true } Err(err) => { - warn!(context, 0, "SMTP: failed to establish connection {:?}", err); + warn!(context, "SMTP: failed to establish connection {:?}", err); false } } @@ -151,7 +151,7 @@ impl Smtp { 1 } Err(err) => { - warn!(context, 0, "SMTP failed to send message: {}", err); + warn!(context, "SMTP failed to send message: {}", err); self.error = Some(format!("{}", err)); 0 } diff --git a/src/sql.rs b/src/sql.rs index 477feb5e9..29e8d5e07 100644 --- a/src/sql.rs +++ b/src/sql.rs @@ -35,7 +35,7 @@ impl Sql { self.in_use.remove(); // drop closes the connection - info!(context, 0, "Database closed."); + info!(context, "Database closed."); } // return true on success, false on failure @@ -176,7 +176,7 @@ impl Sql { rusqlite::types::Type::Null, ))) => None, Err(err) => { - error!(context, 0, "sql: Failed query_row: {}", err); + error!(context, "sql: Failed query_row: {}", err); None } } @@ -193,7 +193,7 @@ impl Sql { value: Option<&str>, ) -> Result<()> { if !self.is_open() { - error!(context, 0, "set_config(): Database not ready."); + error!(context, "set_config(): Database not ready."); return Err(Error::SqlNoConnection); } @@ -227,7 +227,7 @@ impl Sql { match res { Ok(_) => Ok(()), Err(err) => { - error!(context, 0, "set_config(): Cannot change value. {:?}", &err); + error!(context, "set_config(): Cannot change value. {:?}", &err); Err(err.into()) } } @@ -317,7 +317,6 @@ fn open( if sql.is_open() { error!( context, - 0, "Cannot open, database \"{:?}\" already opened.", dbfile.as_ref(), ); @@ -351,7 +350,6 @@ fn open( if !sql.table_exists("config") { info!( context, - 0, "First time init: creating tables in {:?}.", dbfile.as_ref(), ); @@ -467,7 +465,6 @@ fn open( { error!( context, - 0, "Cannot create tables in new database \"{:?}\".", dbfile.as_ref(), ); @@ -688,7 +685,7 @@ fn open( sql.set_config_int(context, "dbversion", 46)?; } if dbversion < 47 { - info!(context, 0, "[migration] v47"); + info!(context, "[migration] v47"); sql.execute( "ALTER TABLE jobs ADD COLUMN tries INTEGER DEFAULT 0;", params![], @@ -697,7 +694,7 @@ fn open( sql.set_config_int(context, "dbversion", 47)?; } if dbversion < 48 { - info!(context, 0, "[migration] v48"); + info!(context, "[migration] v48"); sql.execute( "ALTER TABLE msgs ADD COLUMN move_state INTEGER DEFAULT 1;", params![], @@ -707,7 +704,7 @@ fn open( sql.set_config_int(context, "dbversion", 48)?; } if dbversion < 49 { - info!(context, 0, "[migration] v49"); + info!(context, "[migration] v49"); sql.execute( "ALTER TABLE chats ADD COLUMN gossiped_timestamp INTEGER DEFAULT 0;", params![], @@ -716,7 +713,7 @@ fn open( sql.set_config_int(context, "dbversion", 49)?; } if dbversion < 50 { - info!(context, 0, "[migration] v50"); + info!(context, "[migration] v50"); if 0 != exists_before_update { sql.set_config_int(context, "show_emails", 2)?; } @@ -724,7 +721,7 @@ fn open( sql.set_config_int(context, "dbversion", 50)?; } if dbversion < 53 { - info!(context, 0, "[migration] v53"); + info!(context, "[migration] v53"); sql.execute( "CREATE TABLE locations ( id INTEGER PRIMARY KEY AUTOINCREMENT, latitude REAL DEFAULT 0.0, longitude REAL DEFAULT 0.0, accuracy REAL DEFAULT 0.0, timestamp INTEGER DEFAULT 0, chat_id INTEGER DEFAULT 0, from_id INTEGER DEFAULT 0);", params![] @@ -757,7 +754,7 @@ fn open( sql.set_config_int(context, "dbversion", 53)?; } if dbversion < 54 { - info!(context, 0, "[migration] v54"); + info!(context, "[migration] v54"); sql.execute( "ALTER TABLE msgs ADD COLUMN location_id INTEGER DEFAULT 0;", params![], @@ -797,7 +794,7 @@ fn open( // for newer versions, we copy files always to the blob directory and store relative paths. // this snippet converts older databases and can be removed after some time. - info!(context, 0, "[open] update file paths"); + info!(context, "[open] update file paths"); let repl_from = sql .get_config(context, "backup_for") @@ -824,7 +821,7 @@ fn open( } } - info!(context, 0, "Opened {:?}.", dbfile.as_ref(),); + info!(context, "Opened {:?}.", dbfile.as_ref(),); Ok(()) } @@ -839,7 +836,6 @@ where Err(err) => { error!( context, - 0, "execute failed: {:?} for {}", &err, querystr.as_ref() @@ -856,7 +852,6 @@ pub fn try_execute(context: &Context, sql: &Sql, querystr: impl AsRef) -> R Err(err) => { warn!( context, - 0, "Try-execute for \"{}\" failed: {}", querystr.as_ref(), &err, @@ -900,7 +895,7 @@ pub fn get_rowid_with_conn( Err(err) => { error!( context, - 0, "sql: Failed to retrieve rowid: {} in {}", err, query + "sql: Failed to retrieve rowid: {} in {}", err, query ); 0 } @@ -947,7 +942,7 @@ pub fn get_rowid2_with_conn( ) { Ok(id) => id, Err(err) => { - error!(context, 0, "sql: Failed to retrieve rowid2: {}", err); + error!(context, "sql: Failed to retrieve rowid2: {}", err); 0 } } @@ -957,7 +952,7 @@ pub fn housekeeping(context: &Context) { let mut files_in_use = HashSet::new(); let mut unreferenced_count = 0; - info!(context, 0, "Start housekeeping..."); + info!(context, "Start housekeeping..."); maybe_add_from_param( context, &mut files_in_use, @@ -997,10 +992,10 @@ pub fn housekeeping(context: &Context) { }, ) .unwrap_or_else(|err| { - warn!(context, 0, "sql: failed query: {}", err); + warn!(context, "sql: failed query: {}", err); }); - info!(context, 0, "{} files in use.", files_in_use.len(),); + info!(context, "{} files in use.", files_in_use.len(),); /* go through directory and delete unused files */ let p = std::path::Path::new(as_str(context.get_blobdir())); match std::fs::read_dir(p) { @@ -1039,7 +1034,6 @@ pub fn housekeeping(context: &Context) { if recently_created || recently_modified || recently_accessed { info!( context, - 0, "Housekeeping: Keeping new unreferenced file #{}: {:?}", unreferenced_count, entry.file_name(), @@ -1051,7 +1045,6 @@ pub fn housekeeping(context: &Context) { } info!( context, - 0, "Housekeeping: Deleting unreferenced file #{}: {:?}", unreferenced_count, entry.file_name() @@ -1063,7 +1056,6 @@ pub fn housekeeping(context: &Context) { Err(err) => { warn!( context, - 0, "Housekeeping: Cannot open {}. ({})", as_str(context.get_blobdir()), err @@ -1071,7 +1063,7 @@ pub fn housekeeping(context: &Context) { } } - info!(context, 0, "Housekeeping done.",); + info!(context, "Housekeeping done.",); } fn is_file_in_use(files_in_use: &HashSet, namespc_opt: Option<&str>, name: &str) -> bool { @@ -1119,7 +1111,7 @@ fn maybe_add_from_param( }, ) .unwrap_or_else(|err| { - warn!(context, 0, "sql: failed to add_from_param: {}", err); + warn!(context, "sql: failed to add_from_param: {}", err); }); } From 7ed5a8e72fae335d855461bf3a82ba4f8570a679 Mon Sep 17 00:00:00 2001 From: Dmitry Bogatov Date: Tue, 10 Sep 2019 21:42:53 +0000 Subject: [PATCH 15/25] Reimplement logging macros in terms of `log_event!` Avoid copy-paste message formatting code in src/log.rs, forwarding all arguments of info! warn! error! macros to generic log_event! macro. --- src/log.rs | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/src/log.rs b/src/log.rs index 43491ed53..0782ba60a 100644 --- a/src/log.rs +++ b/src/log.rs @@ -4,13 +4,8 @@ macro_rules! info { info!($ctx, $msg,) }; ($ctx:expr, $msg:expr, $($args:expr),* $(,)?) => { - #[allow(unused_unsafe)] - unsafe { - let formatted = format!($msg, $($args),*); - let formatted_c = std::ffi::CString::new(formatted).unwrap(); - $ctx.call_cb($crate::constants::Event::INFO, 0, - formatted_c.as_ptr() as libc::uintptr_t); - }}; + log_event!($ctx, $crate::constants::Event::INFO, 0, $msg, $($args),*); + }; } #[macro_export] @@ -19,13 +14,8 @@ macro_rules! warn { warn!($ctx, $msg,) }; ($ctx:expr, $msg:expr, $($args:expr),* $(,)?) => { - #[allow(unused_unsafe)] - unsafe { - let formatted = format!($msg, $($args),*); - let formatted_c = std::ffi::CString::new(formatted).unwrap(); - $ctx.call_cb($crate::constants::Event::WARNING, 0, - formatted_c.as_ptr() as libc::uintptr_t); - }}; + log_event!($ctx, $crate::constants::Event::WARNING, 0, $msg, $($args),*); + }; } #[macro_export] @@ -34,13 +24,8 @@ macro_rules! error { error!($ctx, $msg,) }; ($ctx:expr, $msg:expr, $($args:expr),* $(,)?) => { - #[allow(unused_unsafe)] - unsafe { - let formatted = format!($msg, $($args),*); - let formatted_c = std::ffi::CString::new(formatted).unwrap(); - $ctx.call_cb($crate::constants::Event::ERROR, 0, - formatted_c.as_ptr() as libc::uintptr_t); - }}; + log_event!($ctx, $crate::constants::Event::ERROR, 0, $msg, $($args),*); + }; } #[macro_export] From 3ab0d74af21f379cf8350e54645ccc0eea442e14 Mon Sep 17 00:00:00 2001 From: Dmitry Bogatov Date: Tue, 10 Sep 2019 22:35:54 +0000 Subject: [PATCH 16/25] Remove unused `unsafe' block in log_event! macro --- src/log.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/log.rs b/src/log.rs index 0782ba60a..e542172b5 100644 --- a/src/log.rs +++ b/src/log.rs @@ -34,13 +34,11 @@ macro_rules! log_event { log_event!($ctx, $data1, $msg,) }; ($ctx:expr, $event:expr, $data1:expr, $msg:expr, $($args:expr),* $(,)?) => { - #[allow(unused_unsafe)] - unsafe { - let formatted = format!($msg, $($args),*); - let formatted_c = std::ffi::CString::new(formatted).unwrap(); - $ctx.call_cb($event, $data1 as libc::uintptr_t, - formatted_c.as_ptr() as libc::uintptr_t); - }}; + let formatted = format!($msg, $($args),*); + let formatted_c = std::ffi::CString::new(formatted).unwrap(); + $ctx.call_cb($event, $data1 as libc::uintptr_t, + formatted_c.as_ptr() as libc::uintptr_t); + }; } #[macro_export] From e7b198849d3a29449fc20fe1dc57f72250d90b35 Mon Sep 17 00:00:00 2001 From: Dmitry Bogatov Date: Tue, 10 Sep 2019 22:49:53 +0000 Subject: [PATCH 17/25] Copy comment for dc_encode_headers_words from C code --- src/dc_strencode.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/dc_strencode.rs b/src/dc_strencode.rs index e1f4d1526..2dc51cce4 100644 --- a/src/dc_strencode.rs +++ b/src/dc_strencode.rs @@ -12,6 +12,20 @@ use crate::dc_tools::*; use crate::types::*; use crate::x::*; +/** + * Encode non-ascii-strings as `=?UTF-8?Q?Bj=c3=b6rn_Petersen?=`. + * Belongs to RFC 2047: https://tools.ietf.org/html/rfc2047 + * + * We do not fold at position 72; this would result in empty words as `=?utf-8?Q??=` which are correct, + * but cannot be displayed by some mail programs (eg. Android Stock Mail). + * however, this is not needed, as long as _one_ word is not longer than 72 characters. + * _if_ it is, the display may get weird. This affects the subject only. + * the best solution wor all this would be if libetpan encodes the line as only libetpan knowns when a header line is full. + * + * @param to_encode Null-terminated UTF-8-string to encode. + * @return Returns the encoded string which must be free()'d when no longed needed. + * On errors, NULL is returned. + */ pub unsafe fn dc_encode_header_words(to_encode: *const libc::c_char) -> *mut libc::c_char { let mut ok_to_continue = true; let mut ret_str: *mut libc::c_char = ptr::null_mut(); From 5bd46068546440bd653480dfee367411fd727058 Mon Sep 17 00:00:00 2001 From: Dmitry Bogatov Date: Tue, 10 Sep 2019 23:26:08 +0000 Subject: [PATCH 18/25] Implement safe version of `dc_decode_header_words' --- src/dc_strencode.rs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/dc_strencode.rs b/src/dc_strencode.rs index 2dc51cce4..d0e07e435 100644 --- a/src/dc_strencode.rs +++ b/src/dc_strencode.rs @@ -238,6 +238,31 @@ pub unsafe fn dc_decode_header_words(in_0: *const libc::c_char) -> *mut libc::c_ out } +pub fn dc_decode_header_words_safe(input: &str) -> String { + static FROM_ENCODING: &[u8] = b"iso-8859-1\x00"; + static TO_ENCODING: &[u8] = b"utf-8\x00"; + let mut out = ptr::null_mut(); + let mut cur_token = 0; + let input_c = CString::yolo(input); + unsafe { + let r = mailmime_encoded_phrase_parse( + FROM_ENCODING.as_ptr().cast(), + input_c.as_ptr(), + input.len(), + &mut cur_token, + TO_ENCODING.as_ptr().cast(), + &mut out, + ); + if r as u32 != MAILIMF_NO_ERROR || out.is_null() { + input.to_string() + } else { + let res = to_string(out); + free(out.cast()); + res + } + } +} + pub fn dc_needs_ext_header(to_check: impl AsRef) -> bool { let to_check = to_check.as_ref(); From c20e8f7613658f5cd7f06b27b0665f14072db998 Mon Sep 17 00:00:00 2001 From: Dmitry Bogatov Date: Tue, 10 Sep 2019 23:31:29 +0000 Subject: [PATCH 19/25] Use safe version of dc_decode_header_words on one call site --- src/dc_mimeparser.rs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/dc_mimeparser.rs b/src/dc_mimeparser.rs index 467725570..ee439a133 100644 --- a/src/dc_mimeparser.rs +++ b/src/dc_mimeparser.rs @@ -132,15 +132,9 @@ pub unsafe fn dc_mimeparser_parse<'a>(context: &'a Context, body: &[u8]) -> dc_m dc_mimeparser_parse_mime_recursive(mimeparser_ref, mimeparser_ref.mimeroot); let field: *mut mailimf_field = dc_mimeparser_lookup_field(&mimeparser, "Subject"); if !field.is_null() && (*field).fld_type == MAILIMF_FIELD_SUBJECT as libc::c_int { - let decoded = dc_decode_header_words((*(*field).fld_data.fld_subject).sbj_value); - if decoded.is_null() - /* XXX: can it happen? */ - { - mimeparser.subject = None - } else { - mimeparser.subject = Some(to_string(decoded)); - free(decoded.cast()); - } + let subj = (*(*field).fld_data.fld_subject).sbj_value; + + mimeparser.subject = as_opt_str(subj).map(dc_decode_header_words_safe); } if !dc_mimeparser_lookup_optional_field(&mut mimeparser, "Chat-Version").is_null() { mimeparser.is_send_by_messenger = true From 71a01d3002db940185e77b5e50dd7fcf1e80e2e4 Mon Sep 17 00:00:00 2001 From: Dmitry Bogatov Date: Wed, 11 Sep 2019 02:12:35 +0000 Subject: [PATCH 20/25] Reduce indentation in dc_continue_key_transfer Replace `if (ok) { }` pattern with `if (!ok) return` to reduce indentation level. Note: This commit fails CI due incorrect formatting. It is done deliberately to simplify review process. --- src/dc_imex.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/dc_imex.rs b/src/dc_imex.rs index 48d822e38..954f8b66e 100644 --- a/src/dc_imex.rs +++ b/src/dc_imex.rs @@ -274,7 +274,9 @@ pub unsafe fn dc_continue_key_transfer( let mut filebytes: size_t = 0i32 as size_t; let mut armored_key: *mut libc::c_char = ptr::null_mut(); let mut norm_sc: *mut libc::c_char = ptr::null_mut(); - 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; + } let msg = dc_get_msg(context, msg_id); if msg.is_err() || !dc_msg_is_setupmessage(msg.as_ref().unwrap()) @@ -311,7 +313,7 @@ pub unsafe fn dc_continue_key_transfer( } } } - } + free(armored_key as *mut libc::c_void); free(filecontent as *mut libc::c_void); free(filename as *mut libc::c_void); From 2eda839303e1b53c8bf8a94e78ccc701f77196a4 Mon Sep 17 00:00:00 2001 From: Dmitry Bogatov Date: Wed, 11 Sep 2019 02:19:48 +0000 Subject: [PATCH 21/25] cargo-fmt --- src/dc_imex.rs | 66 +++++++++++++++++++++++++------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/src/dc_imex.rs b/src/dc_imex.rs index 954f8b66e..d819ccdd8 100644 --- a/src/dc_imex.rs +++ b/src/dc_imex.rs @@ -277,42 +277,42 @@ pub unsafe fn dc_continue_key_transfer( if msg_id <= 9i32 as libc::c_uint || setup_code.is_null() { return false; } - let msg = dc_get_msg(context, msg_id); - if msg.is_err() - || !dc_msg_is_setupmessage(msg.as_ref().unwrap()) - || { - filename = dc_msg_get_file(msg.as_ref().unwrap()); - filename.is_null() - } - || *filename.offset(0isize) as libc::c_int == 0i32 - { - error!(context, "Message is no Autocrypt Setup Message.",); - } else if 0 - == dc_read_file( - context, - filename, - &mut filecontent as *mut *mut libc::c_char as *mut *mut libc::c_void, - &mut filebytes, - ) - || filecontent.is_null() - || filebytes <= 0 - { - error!(context, "Cannot read Autocrypt Setup Message file.",); + let msg = dc_get_msg(context, msg_id); + if msg.is_err() + || !dc_msg_is_setupmessage(msg.as_ref().unwrap()) + || { + filename = dc_msg_get_file(msg.as_ref().unwrap()); + filename.is_null() + } + || *filename.offset(0isize) as libc::c_int == 0i32 + { + error!(context, "Message is no Autocrypt Setup Message.",); + } else if 0 + == dc_read_file( + context, + filename, + &mut filecontent as *mut *mut libc::c_char as *mut *mut libc::c_void, + &mut filebytes, + ) + || filecontent.is_null() + || filebytes <= 0 + { + error!(context, "Cannot read Autocrypt Setup Message file.",); + } else { + norm_sc = dc_normalize_setup_code(context, setup_code); + if norm_sc.is_null() { + warn!(context, "Cannot normalize Setup Code.",); } else { - norm_sc = dc_normalize_setup_code(context, setup_code); - if norm_sc.is_null() { - 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 - } + 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 } } + } free(armored_key as *mut libc::c_void); free(filecontent as *mut libc::c_void); From 177ab0229a49389fda04bbc2af7d43ee1916baa2 Mon Sep 17 00:00:00 2001 From: "B. Petersen" Date: Wed, 11 Sep 2019 17:02:27 +0200 Subject: [PATCH 22/25] do not call fs::remove_dir_all() implicitly on non-files; deleting folders is not needed and calling remove_dir_all() is considered harmful --- src/dc_tools.rs | 15 +++++++++------ tests/stress.rs | 2 +- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/dc_tools.rs b/src/dc_tools.rs index ed6f442d8..225c32cbe 100644 --- a/src/dc_tools.rs +++ b/src/dc_tools.rs @@ -843,13 +843,16 @@ pub fn dc_get_filebytes(context: &Context, path: impl AsRef) -> pub fn dc_delete_file(context: &Context, path: impl AsRef) -> bool { let path_abs = dc_get_abs_path_safe(context, &path); - let res = if path_abs.is_file() { - fs::remove_file(path_abs) - } else { - fs::remove_dir_all(path_abs) - }; + if !path_abs.is_file() { + warn!( + context, + "Will not delete directory \"{}\".", + path.as_ref().display() + ); + return false; + } - match res { + match fs::remove_file(path_abs) { Ok(_) => true, Err(_err) => { warn!(context, "Cannot delete \"{}\".", path.as_ref().display()); diff --git a/tests/stress.rs b/tests/stress.rs index 1202392ab..6a307955a 100644 --- a/tests/stress.rs +++ b/tests/stress.rs @@ -90,7 +90,7 @@ unsafe fn stress_functions(context: &Context) { assert!(dc_delete_file(context, "$BLOBDIR/dada")); assert!(dc_create_folder(context, "$BLOBDIR/foobar-folder")); assert!(dc_file_exist(context, "$BLOBDIR/foobar-folder",)); - assert!(dc_delete_file(context, "$BLOBDIR/foobar-folder")); + assert!(!dc_delete_file(context, "$BLOBDIR/foobar-folder")); let fn0: *mut libc::c_char = dc_get_fine_pathNfilename( context, b"$BLOBDIR\x00" as *const u8 as *const libc::c_char, From 64b00fce7de035c759adf9e569d3af638b8c1553 Mon Sep 17 00:00:00 2001 From: dignifiedquire Date: Wed, 11 Sep 2019 17:46:05 +0200 Subject: [PATCH 23/25] fix(location): do not sql recurse in location sending --- src/location.rs | 125 +++++++++++++++++++++++------------------------- 1 file changed, 61 insertions(+), 64 deletions(-) diff --git a/src/location.rs b/src/location.rs index 504276086..44f122e7e 100644 --- a/src/location.rs +++ b/src/location.rs @@ -548,73 +548,70 @@ pub fn job_do_DC_JOB_MAYBE_SEND_LOCATIONS(context: &Context, _job: &Job) { " ----------------- MAYBE_SEND_LOCATIONS -------------- ", ); - context - .sql - .query_map( - "SELECT id, locations_send_begin, locations_last_sent \ - FROM chats \ - WHERE locations_send_until>?;", - params![now], - |row| { - let chat_id: i32 = row.get(0)?; - let locations_send_begin: i64 = row.get(1)?; - let locations_last_sent: i64 = row.get(2)?; - continue_streaming = 1; + if let Ok(rows) = context.sql.query_map( + "SELECT id, locations_send_begin, locations_last_sent \ + FROM chats \ + WHERE locations_send_until>?;", + params![now], + |row| { + let chat_id: i32 = row.get(0)?; + let locations_send_begin: i64 = row.get(1)?; + let locations_last_sent: i64 = row.get(2)?; + continue_streaming = 1; - // be a bit tolerant as the timer may not align exactly with time(NULL) - if now - locations_last_sent < (60 - 3) { - Ok(None) - } else { - Ok(Some((chat_id, locations_send_begin, locations_last_sent))) - } - }, - |rows| { - context.sql.prepare( - "SELECT id \ - FROM locations \ - WHERE from_id=? \ - AND timestamp>=? \ - AND timestamp>? \ - AND independent=0 \ - ORDER BY timestamp;", - |mut stmt_locations, _| { - for (chat_id, locations_send_begin, locations_last_sent) in - rows.filter_map(|r| match r { - Ok(Some(v)) => Some(v), - _ => None, - }) + // be a bit tolerant as the timer may not align exactly with time(NULL) + if now - locations_last_sent < (60 - 3) { + Ok(None) + } else { + Ok(Some((chat_id, locations_send_begin, locations_last_sent))) + } + }, + |rows| { + rows.filter_map(|v| v.transpose()) + .collect::, _>>() + .map_err(Into::into) + }, + ) { + context + .sql + .prepare( + "SELECT id \ + FROM locations \ + WHERE from_id=? \ + AND timestamp>=? \ + AND timestamp>? \ + AND independent=0 \ + ORDER BY timestamp;", + |mut stmt_locations, _| { + for (chat_id, locations_send_begin, locations_last_sent) in rows { + if !stmt_locations + .exists(params![1, locations_send_begin, locations_last_sent,]) + .unwrap_or_default() { - // TODO: do I need to reset? - if !stmt_locations - .exists(params![1, locations_send_begin, locations_last_sent,]) - .unwrap_or_default() - { - // if there is no new location, there's nothing to send. - // however, maybe we want to bypass this test eg. 15 minutes - continue; - } - // pending locations are attached automatically to every message, - // so also to this empty text message. - // DC_CMD_LOCATION is only needed to create a nicer subject. - // - // for optimisation and to avoid flooding the sending queue, - // we could sending these messages only if we're really online. - // the easiest way to determine this, is to check for an empty message queue. - // (might not be 100%, however, as positions are sent combined later - // and dc_set_location() is typically called periodically, this is ok) - let mut msg = dc_msg_new(context, Viewtype::Text); - msg.hidden = true; - msg.param.set_int(Param::Cmd, 9); - // TODO: handle cleanup on error - chat::send_msg(context, chat_id as u32, &mut msg).unwrap(); + // if there is no new location, there's nothing to send. + // however, maybe we want to bypass this test eg. 15 minutes + continue; } - Ok(()) - }, - ) - }, - ) - .unwrap(); // TODO: Better error handling - + // pending locations are attached automatically to every message, + // so also to this empty text message. + // DC_CMD_LOCATION is only needed to create a nicer subject. + // + // for optimisation and to avoid flooding the sending queue, + // we could sending these messages only if we're really online. + // the easiest way to determine this, is to check for an empty message queue. + // (might not be 100%, however, as positions are sent combined later + // and dc_set_location() is typically called periodically, this is ok) + let mut msg = dc_msg_new(context, Viewtype::Text); + msg.hidden = true; + msg.param.set_int(Param::Cmd, 9); + // TODO: handle cleanup on error + chat::send_msg(context, chat_id as u32, &mut msg).unwrap(); + } + Ok(()) + }, + ) + .unwrap(); // TODO: Better error handling + } if 0 != continue_streaming { schedule_MAYBE_SEND_LOCATIONS(context, 0x1); } From ca9dccfcd7cd111caf4f3ffc1b2a4cd79c279361 Mon Sep 17 00:00:00 2001 From: dignifiedquire Date: Wed, 11 Sep 2019 17:57:59 +0200 Subject: [PATCH 24/25] fix(location): another nested sql --- src/location.rs | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/src/location.rs b/src/location.rs index 44f122e7e..aae7c39c5 100644 --- a/src/location.rs +++ b/src/location.rs @@ -265,16 +265,16 @@ pub fn set(context: &Context, latitude: f64, longitude: f64, accuracy: f64) -> l if latitude == 0.0 && longitude == 0.0 { return 1; } + let mut continue_streaming = false; - context.sql.query_map( + if let Ok(chats) = context.sql.query_map( "SELECT id FROM chats WHERE locations_send_until>?;", - params![time()], |row| row.get::<_, i32>(0), - |chats| { - let mut continue_streaming = false; - - for chat in chats { - let chat_id = chat?; - context.sql.execute( + params![time()], + |row| row.get::<_, i32>(0), + |chats| chats.collect::, _>>().map_err(Into::into), + ) { + for chat_id in chats { + if let Err(err) = context.sql.execute( "INSERT INTO locations \ (latitude, longitude, accuracy, timestamp, chat_id, from_id) VALUES (?,?,?,?,?,?);", params![ @@ -285,16 +285,19 @@ pub fn set(context: &Context, latitude: f64, longitude: f64, accuracy: f64) -> l chat_id, 1, ] - )?; + ) { + warn!(context, "failed to store location {:?}", err); + } else { continue_streaming = true; } - if continue_streaming { - context.call_cb(Event::LOCATION_CHANGED, 1, 0); - }; - schedule_MAYBE_SEND_LOCATIONS(context, 0); - Ok(continue_streaming as libc::c_int) } - ).unwrap_or_default() + if continue_streaming { + context.call_cb(Event::LOCATION_CHANGED, 1, 0); + }; + schedule_MAYBE_SEND_LOCATIONS(context, 0); + } + + continue_streaming as libc::c_int } pub fn get_range( From dd2e3d35fd866b5ef7300a3bd9e78935bf5ab3e1 Mon Sep 17 00:00:00 2001 From: dignifiedquire Date: Wed, 11 Sep 2019 18:13:21 +0200 Subject: [PATCH 25/25] fix(location): another nesting --- src/location.rs | 62 ++++++++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/src/location.rs b/src/location.rs index aae7c39c5..31be5ab27 100644 --- a/src/location.rs +++ b/src/location.rs @@ -575,7 +575,7 @@ pub fn job_do_DC_JOB_MAYBE_SEND_LOCATIONS(context: &Context, _job: &Job) { .map_err(Into::into) }, ) { - context + let msgs = context .sql .prepare( "SELECT id \ @@ -586,34 +586,42 @@ pub fn job_do_DC_JOB_MAYBE_SEND_LOCATIONS(context: &Context, _job: &Job) { AND independent=0 \ ORDER BY timestamp;", |mut stmt_locations, _| { - for (chat_id, locations_send_begin, locations_last_sent) in rows { - if !stmt_locations - .exists(params![1, locations_send_begin, locations_last_sent,]) - .unwrap_or_default() - { - // if there is no new location, there's nothing to send. - // however, maybe we want to bypass this test eg. 15 minutes - continue; - } - // pending locations are attached automatically to every message, - // so also to this empty text message. - // DC_CMD_LOCATION is only needed to create a nicer subject. - // - // for optimisation and to avoid flooding the sending queue, - // we could sending these messages only if we're really online. - // the easiest way to determine this, is to check for an empty message queue. - // (might not be 100%, however, as positions are sent combined later - // and dc_set_location() is typically called periodically, this is ok) - let mut msg = dc_msg_new(context, Viewtype::Text); - msg.hidden = true; - msg.param.set_int(Param::Cmd, 9); - // TODO: handle cleanup on error - chat::send_msg(context, chat_id as u32, &mut msg).unwrap(); - } - Ok(()) + let msgs = rows + .into_iter() + .filter_map(|(chat_id, locations_send_begin, locations_last_sent)| { + if !stmt_locations + .exists(params![1, locations_send_begin, locations_last_sent,]) + .unwrap_or_default() + { + // if there is no new location, there's nothing to send. + // however, maybe we want to bypass this test eg. 15 minutes + None + } else { + // pending locations are attached automatically to every message, + // so also to this empty text message. + // DC_CMD_LOCATION is only needed to create a nicer subject. + // + // for optimisation and to avoid flooding the sending queue, + // we could sending these messages only if we're really online. + // the easiest way to determine this, is to check for an empty message queue. + // (might not be 100%, however, as positions are sent combined later + // and dc_set_location() is typically called periodically, this is ok) + let mut msg = dc_msg_new(context, Viewtype::Text); + msg.hidden = true; + msg.param.set_int(Param::Cmd, 9); + Some((chat_id, msg)) + } + }) + .collect::>(); + Ok(msgs) }, ) - .unwrap(); // TODO: Better error handling + .unwrap_or_default(); // TODO: Better error handling + + for (chat_id, mut msg) in msgs.into_iter() { + // TODO: better error handling + chat::send_msg(context, chat_id as u32, &mut msg).unwrap(); + } } if 0 != continue_streaming { schedule_MAYBE_SEND_LOCATIONS(context, 0x1);