diff --git a/deltachat-ffi/src/lib.rs b/deltachat-ffi/src/lib.rs index bdb89109e..abcffa8fd 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] @@ -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/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 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 e230ce9c0..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); @@ -45,17 +42,8 @@ pub unsafe fn configure(context: &Context) { } /// Check if the context is already configured. -pub fn dc_is_configured(context: &Context) -> libc::c_int { - if context - .sql - .get_config_int(context, "configured") - .unwrap_or_default() - > 0 - { - 1 - } else { - 0 - } +pub fn dc_is_configured(context: &Context) -> bool { + context.sql.get_config_bool(context, "configured") } /******************************************************************************* @@ -73,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 @@ -89,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(); @@ -113,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() } @@ -146,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 } } @@ -256,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(); } @@ -340,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 @@ -357,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; @@ -375,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; @@ -388,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; @@ -443,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 @@ -459,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 @@ -518,7 +506,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 => { @@ -528,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; } }; @@ -582,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 { @@ -628,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 @@ -651,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) @@ -668,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 50aa9780f..d819ccdd8 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; } } @@ -208,12 +207,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", @@ -279,44 +274,46 @@ 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()) { - 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, 0, "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, 0, "Cannot read Autocrypt Setup Message file.",); + 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.",); + } 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, 0, "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.",); - } 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); free(filename as *mut libc::c_void); @@ -338,7 +335,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; } @@ -368,13 +365,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; } @@ -386,7 +383,7 @@ fn set_self_key( set_default, &context.sql, ) { - error!(context, 0, "Cannot save keypair."); + error!(context, "Cannot save keypair."); return false; } @@ -445,7 +442,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(); @@ -507,19 +504,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; @@ -531,25 +527,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 } } @@ -576,7 +572,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 @@ -585,8 +580,8 @@ 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) { - error!(context, 0, "Cannot import backups to accounts in use."); + if dc_is_configured(context) { + error!(context, "Cannot import backups to accounts in use."); return 0; } &context.sql.close(&context); @@ -594,7 +589,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; } @@ -621,7 +616,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( @@ -669,7 +664,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(), @@ -716,7 +710,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; } @@ -728,7 +722,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() @@ -772,7 +765,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) { @@ -818,7 +811,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()), @@ -834,7 +827,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, ); @@ -854,13 +846,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 { @@ -879,7 +870,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()) ); @@ -944,7 +934,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( @@ -988,7 +978,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), ); @@ -1002,7 +991,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), ); @@ -1010,7 +998,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), ); @@ -1110,10 +1097,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 a7b698c25..8ae6a9269 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_lossy(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 @@ -460,7 +454,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 +468,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 +479,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 +660,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 +1064,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 +1077,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 e4f896263..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; @@ -642,7 +637,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 @@ -723,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 @@ -961,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; @@ -1316,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, @@ -1331,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(); @@ -1345,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); @@ -1740,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) { @@ -1811,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_strencode.rs b/src/dc_strencode.rs index e1f4d1526..d0e07e435 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(); @@ -224,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(); diff --git a/src/dc_tools.rs b/src/dc_tools.rs index 60f9b648d..225c32cbe 100644 --- a/src/dc_tools.rs +++ b/src/dc_tools.rs @@ -843,16 +843,19 @@ 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, 0, "Cannot delete \"{}\".", path.as_ref().display()); + warn!(context, "Cannot delete \"{}\".", path.as_ref().display()); false } } @@ -870,7 +873,6 @@ pub fn dc_copy_file( Err(_) => { error!( context, - 0, "Cannot copy \"{}\" to \"{}\".", src.as_ref().display(), dest.as_ref().display(), @@ -888,7 +890,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 +922,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 +959,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..3ccddc8e5 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, @@ -245,7 +235,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 @@ -449,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/src/location.rs b/src/location.rs index 11569e223..31be5ab27 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 @@ -266,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![ @@ -286,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( @@ -546,76 +548,81 @@ 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 - .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, - }) - { - // TODO: do I need to reset? + // 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) + }, + ) { + let msgs = context + .sql + .prepare( + "SELECT id \ + FROM locations \ + WHERE from_id=? \ + AND timestamp>=? \ + AND timestamp>? \ + AND independent=0 \ + ORDER BY timestamp;", + |mut stmt_locations, _| { + 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 - continue; + 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)) } - // 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 + }) + .collect::>(); + Ok(msgs) + }, + ) + .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); } diff --git a/src/log.rs b/src/log.rs index dabffd14f..e542172b5 100644 --- a/src/log.rs +++ b/src/log.rs @@ -1,46 +1,31 @@ #[macro_export] macro_rules! info { - ($ctx:expr, $data1:expr, $msg:expr) => { - info!($ctx, $data1, $msg,) + ($ctx:expr, $msg:expr) => { + info!($ctx, $msg,) + }; + ($ctx:expr, $msg:expr, $($args:expr),* $(,)?) => { + log_event!($ctx, $crate::constants::Event::INFO, 0, $msg, $($args),*); }; - ($ctx: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($crate::constants::Event::INFO, $data1 as libc::uintptr_t, - 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, $msg:expr, $($args:expr),* $(,)?) => { + log_event!($ctx, $crate::constants::Event::WARNING, 0, $msg, $($args),*); }; - ($ctx: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($crate::constants::Event::WARNING, $data1 as libc::uintptr_t, - 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, $msg:expr, $($args:expr),* $(,)?) => { + log_event!($ctx, $crate::constants::Event::ERROR, 0, $msg, $($args),*); }; - ($ctx: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($crate::constants::Event::ERROR, $data1 as libc::uintptr_t, - formatted_c.as_ptr() as libc::uintptr_t); - }}; } #[macro_export] @@ -49,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] 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/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") }) 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 62515b9f4..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()) } } @@ -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, @@ -303,7 +317,6 @@ fn open( if sql.is_open() { error!( context, - 0, "Cannot open, database \"{:?}\" already opened.", dbfile.as_ref(), ); @@ -337,7 +350,6 @@ fn open( if !sql.table_exists("config") { info!( context, - 0, "First time init: creating tables in {:?}.", dbfile.as_ref(), ); @@ -453,7 +465,6 @@ fn open( { error!( context, - 0, "Cannot create tables in new database \"{:?}\".", dbfile.as_ref(), ); @@ -674,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![], @@ -683,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![], @@ -693,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![], @@ -702,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)?; } @@ -710,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![] @@ -743,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![], @@ -783,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") @@ -810,7 +821,7 @@ fn open( } } - info!(context, 0, "Opened {:?}.", dbfile.as_ref(),); + info!(context, "Opened {:?}.", dbfile.as_ref(),); Ok(()) } @@ -825,7 +836,6 @@ where Err(err) => { error!( context, - 0, "execute failed: {:?} for {}", &err, querystr.as_ref() @@ -842,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, @@ -886,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 } @@ -933,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 } } @@ -943,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, @@ -983,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) { @@ -1025,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(), @@ -1037,7 +1045,6 @@ pub fn housekeeping(context: &Context) { } info!( context, - 0, "Housekeeping: Deleting unreferenced file #{}: {:?}", unreferenced_count, entry.file_name() @@ -1049,7 +1056,6 @@ pub fn housekeeping(context: &Context) { Err(err) => { warn!( context, - 0, "Housekeeping: Cannot open {}. ({})", as_str(context.get_blobdir()), err @@ -1057,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 { @@ -1105,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); }); } diff --git a/src/top_evil_rs.py b/src/top_evil_rs.py index a64c3f4b7..2976b0de1 100755 --- a/src/top_evil_rs.py +++ b/src/top_evil_rs.py @@ -6,13 +6,15 @@ 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() 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 diff --git a/tests/stress.rs b/tests/stress.rs index bf60a1961..6a307955a 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::*; @@ -91,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, @@ -461,136 +460,111 @@ 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 (public_key, private_key) = dc_pgp_create_keypair("foo@bar.de").unwrap(); - 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, - if 0 != j & 1 { - KeyType::Public - } else { - KeyType::Private - }, - ); + private_key.split_key().unwrap(); - assert!(bad_key.is_none()); - j += 1 - } + let (public_key2, private_key2) = dc_pgp_create_keypair("two@zwo.de").unwrap(); - let (public_key, private_key) = dc_pgp_create_keypair("foo@bar.de").unwrap(); + assert_ne!(public_key, public_key2); - private_key.split_key().unwrap(); + 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 (public_key2, private_key2) = dc_pgp_create_keypair("two@zwo.de").unwrap(); + 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-----")); - assert_ne!(public_key, public_key2); + 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 original_text = b"This is a test"; - let mut keyring = Keyring::default(); - keyring.add_owned(public_key.clone()); - keyring.add_ref(&public_key2); + let mut keyring = Keyring::default(); + keyring.add_owned(private_key); - 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 mut public_keyring = Keyring::default(); + public_keyring.add_ref(&public_key); - 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 public_keyring2 = Keyring::default(); + public_keyring2.add_owned(public_key2.clone()); - let mut keyring = Keyring::default(); - keyring.add_owned(private_key); + let mut valid_signatures: HashSet = Default::default(); - 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, + Some(&mut valid_signatures), + ) + .unwrap(); - let mut public_keyring2 = Keyring::default(); - public_keyring2.add_owned(public_key2.clone()); + assert_eq!(plain, original_text,); + assert_eq!(valid_signatures.len(), 1); - let mut valid_signatures: HashSet = Default::default(); + valid_signatures.clear(); - let plain = dc_pgp_pk_decrypt( - ctext_signed.as_bytes(), - &keyring, - &public_keyring, - Some(&mut valid_signatures), - ) - .unwrap(); + 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); - assert_eq!(plain, original_text,); - assert_eq!(valid_signatures.len(), 1); + 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 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(); + 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(), 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(), 1); - valid_signatures.clear(); + valid_signatures.clear(); - public_keyring2.add_ref(&public_key); + 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_signed.as_bytes(), - &keyring, - &public_keyring2, - Some(&mut valid_signatures), - ) - .unwrap(); - assert_eq!(plain, original_text); - assert_eq!(valid_signatures.len(), 1); + assert_eq!(plain, original_text); - 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 mut keyring = Keyring::default(); + keyring.add_ref(&private_key2); + let mut public_keyring = Keyring::default(); + public_keyring.add_ref(&public_key); - assert_eq!(plain, original_text); + let plain = + dc_pgp_pk_decrypt(ctext_signed.as_bytes(), &keyring, &public_keyring, None).unwrap(); - 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 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(