diff --git a/deltachat-ffi/src/lib.rs b/deltachat-ffi/src/lib.rs index deaa39840..3db4874ca 100644 --- a/deltachat-ffi/src/lib.rs +++ b/deltachat-ffi/src/lib.rs @@ -1320,12 +1320,11 @@ pub unsafe extern "C" fn dc_get_securejoin_qr( ) -> *mut libc::c_char { if context.is_null() { eprintln!("ignoring careless call to dc_get_securejoin_qr()"); - return dc_strdup(ptr::null()); + "".strdup() } let context = &*context; - - dc_securejoin::dc_get_securejoin_qr(context, chat_id) + dc_securejoin::dc_get_securejoin_qr(context, chat_id).unwrap_or("").strdup() } #[no_mangle] diff --git a/examples/repl/main.rs b/examples/repl/main.rs index f6a19f0e7..4371f90a8 100644 --- a/examples/repl/main.rs +++ b/examples/repl/main.rs @@ -17,6 +17,8 @@ use std::borrow::Cow::{self, Borrowed, Owned}; use std::ptr; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, Mutex, RwLock}; +use std::process::Command; +use std::io::{self, Write}; use deltachat::config; use deltachat::configure::*; @@ -516,25 +518,20 @@ unsafe fn handle_cmd(line: &str, ctx: Arc>) -> Result { start_threads(ctx.clone()); - let qrstr = - dc_get_securejoin_qr(&ctx.read().unwrap(), arg1.parse().unwrap_or_default()); - if !qrstr.is_null() && 0 != *qrstr.offset(0isize) as libc::c_int { - if arg0 == "getbadqr" && strlen(qrstr) > 40 { - let mut i: libc::c_int = 12i32; - while i < 22i32 { - *qrstr.offset(i as isize) = '0' as i32 as libc::c_char; - i += 1 + if let Some(mut qr) = dc_get_securejoin_qr(&ctx.read().unwrap(), arg1.parse().unwrap_or_default()) { + if !qr.is_empty() { + if arg0 == "getbadqr" && qr.len() > 40 { + qr.replace_range(12..22, "0000000000") } + println!("{}", qr); + let output = Command::new("qrencode") + .args(&["-t", "ansiutf8", format!("\"{}\"", qr.as_str()).as_str(), "-o", "-"]) + .output() + .expect("failed to execute process"); + io::stdout().write_all(&output.stdout).unwrap(); + io::stderr().write_all(&output.stderr).unwrap(); } - println!("{}", to_string(qrstr as *const _)); - let syscmd = dc_mprintf( - b"qrencode -t ansiutf8 \"%s\" -o -\x00" as *const u8 as *const libc::c_char, - qrstr, - ); - system(syscmd); - free(syscmd as *mut libc::c_void); } - free(qrstr as *mut libc::c_void); } "joinqr" => { start_threads(ctx.clone()); diff --git a/src/dc_securejoin.rs b/src/dc_securejoin.rs index 91ded8271..ba7044863 100644 --- a/src/dc_securejoin.rs +++ b/src/dc_securejoin.rs @@ -25,12 +25,17 @@ use crate::x::*; pub unsafe fn dc_get_securejoin_qr( context: &Context, group_chat_id: uint32_t, -) -> *mut libc::c_char { +) -> Option { /* ========================================================= ==== Alice - the inviter side ==== ==== Step 1 in "Setup verified contact" protocol ==== ========================================================= */ + let cleanup = |fingerprint, qr: Option| { + free(fingerprint as *mut libc::c_void); + qr + }; + let mut fingerprint = ptr::null_mut(); let mut qr: Option = None; @@ -53,19 +58,10 @@ pub unsafe fn dc_get_securejoin_qr( }); let self_addr = context.sql.get_config(context, "configured_addr"); - let cleanup = |fingerprint| { - free(fingerprint as *mut libc::c_void); - - if let Some(qr) = qr { - qr.strdup() - } else { - std::ptr::null_mut() - } - }; if self_addr.is_none() { error!(context, 0, "Not configured, cannot generate QR code.",); - return cleanup(fingerprint); + return cleanup(fingerprint, qr); } let self_addr = self_addr.unwrap(); @@ -77,7 +73,7 @@ pub unsafe fn dc_get_securejoin_qr( fingerprint = get_self_fingerprint(context); if fingerprint.is_null() { - return cleanup(fingerprint); + return cleanup(fingerprint, qr); } let self_addr_urlencoded = utf8_percent_encode(&self_addr, NON_ALPHANUMERIC).to_string(); @@ -103,7 +99,7 @@ pub unsafe fn dc_get_securejoin_qr( context, 0, "Cannot get QR-code for chat-id {}", group_chat_id, ); - return cleanup(fingerprint); + return cleanup(fingerprint, qr); } } else { Some(format!( @@ -118,7 +114,7 @@ pub unsafe fn dc_get_securejoin_qr( info!(context, 0, "Generated QR code: {}", qr.as_ref().unwrap()); - cleanup(fingerprint) + cleanup(fingerprint, qr) } fn get_self_fingerprint(context: &Context) -> *mut libc::c_char {