profile
viewpoint
Friedel Ziegelmayer dignifiedquire Germany

async-rs/async-std 2290

Async version of the Rust standard library

deltachat/deltachat-core 308

Delta.Chat C-Library with e2e chat-over-email functionality & Python bindings

deltachat/deltachat-core-rust 149

Delta Chat Rust Core library, used by Android/iOS/desktop apps and bindings

deltachat/deltachat-ios 121

Email-based instant messaging for iOS.

async-rs/async-tls 73

A TLS implementation over AsyncRead and AsyncWrite

browserify/browserify-zlib 43

Full zlib module for browserify

async-email/async-imap 36

Async IMAP implementation in Rust

dignifiedquire/async-tar 29

A tar archive reading/writing library for async Rust.

daviddias/js-ethereum-libp2p 22

⛓ Process the ethereum blockchain in the Browser ou Node.js with ♦libp2p 🎉

issue openedalexcrichton/socket2-rs

SO_NOSIGPIPE not set on ios

I am experiencing trouble with sigpipes using socket2 on ios. The code already sets nosigpipe by default for macos, is there a reason this is not done for ios as well?

created time in 2 hours

pull request commentdeltachat/deltachat-core-rust

just print events

the main reason for this is, is that it gives you timestamps when printing On 1. Jun 2020, 16:43 +0200, bjoern notifications@github.com, wrote:

Closed #1547. — You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe.

r10s

comment created time in 19 hours

pull request commentdeltachat/deltachat-core-rust

just print events

this works already if you set the rust_log env variable?

r10s

comment created time in 20 hours

issue commentstjepang/smol

smol fails to build on OpenBSD (nix crate related issue)

nix was replaced with custom syscalls on master, should male this easier to work with

nickpelone

comment created time in 21 hours

Pull request review commentfilecoin-project/neptune

Make tag and first non-linear layer using it constant.

 fn quintic_s_box_pre_add<CS: ConstraintSystem<E>, E: Engine>(     } } +/// Compute l^5 and enforce constraint. If round_key is supplied, add it to l first.+fn constant_quintic_s_box_pre_add_tag<CS: ConstraintSystem<E>, E: Engine>(+    tag: &Elt<E>,+    pre_round_key: Option<E::Fr>,+    post_round_key: Option<E::Fr>,+) -> Result<Elt<E>, SynthesisError> {+    if let (Some(_), Some(_)) = (pre_round_key, post_round_key) {+        let mut tag = tag.val().unwrap();

should use expect with a little more descriptive error message

porcuquine

comment created time in 4 days

Pull request review commentfilecoin-project/neptune

Make tag and first non-linear layer using it constant.

 fn quintic_s_box_pre_add<CS: ConstraintSystem<E>, E: Engine>(     } } +/// Compute l^5 and enforce constraint. If round_key is supplied, add it to l first.+fn constant_quintic_s_box_pre_add_tag<CS: ConstraintSystem<E>, E: Engine>(+    tag: &Elt<E>,+    pre_round_key: Option<E::Fr>,+    post_round_key: Option<E::Fr>,+) -> Result<Elt<E>, SynthesisError> {

why does this return a Result, I dont think it actually can error

porcuquine

comment created time in 4 days

Pull request review commentfilecoin-project/neptune

Make tag and first non-linear layer using it constant.

 fn quintic_s_box_pre_add<CS: ConstraintSystem<E>, E: Engine>(     } } +/// Compute l^5 and enforce constraint. If round_key is supplied, add it to l first.+fn constant_quintic_s_box_pre_add_tag<CS: ConstraintSystem<E>, E: Engine>(+    tag: &Elt<E>,+    pre_round_key: Option<E::Fr>,+    post_round_key: Option<E::Fr>,+) -> Result<Elt<E>, SynthesisError> {+    if let (Some(_), Some(_)) = (pre_round_key, post_round_key) {+        let mut tag = tag.val().unwrap();+        crate::quintic_s_box::<E>(&mut tag, pre_round_key.as_ref(), post_round_key.as_ref());+        Ok(Elt::num_from_fr::<CS>(tag))+    } else {+        panic!("pre_round_key and post_round_key must both be provided.");

instead of this panic, why not just expect on the two Option values?

porcuquine

comment created time in 4 days

push eventdeltachat/deltachat-core-rust

dignifiedquire

commit sha 43f49f89174316267fd7d143c1478d49686162f9

refactor(configure): remove step-counter

view details

dignifiedquire

commit sha 408e9946af42d05d9d75eb7e85a0af5052855e6a

refactor(configure): cleanup logic

view details

B. Petersen

commit sha 84963e198e2726fed36df959019010037c497ac3

do autoconfig only when no advanced options are entered the advanced options are not used anyway later, but prevent imap/smtp connections from being altered. nb: we want to stop altering when some advanced options are entered, however, we want to do this probaby not depending on autoconfig.

view details

dignifiedquire

commit sha 6d8b4a7ec0254c64f32dd5a20381db459937c6a9

simplify further and apply CR

view details

Friedel Ziegelmayer

commit sha 419b7d1d5cb483328fa2ad9809f31535233ff983

Merge pull request #1539 from deltachat/sane-configure refactor(configure): simplify logic and code

view details

push time in 4 days

delete branch deltachat/deltachat-core-rust

delete branch : sane-configure

delete time in 4 days

PR merged deltachat/deltachat-core-rust

refactor(configure): simplify logic and code

Not quite as nice as the C code yet, but at least there is no step counter anymore.

+303 -389

0 comment

1 changed file

dignifiedquire

pr closed time in 4 days

Pull request review commentdeltachat/deltachat-core-rust

refactor(configure): simplify logic and code

 impl Context {             }         } -        if success {-            progress!(self, 1000);-            Ok(())-        } else {-            progress!(self, 0);-            Err(format_err!("Configure failed"))+        match success {+            Ok(_) => {+                progress!(self, 1000);+                Ok(())+            }+            Err(err) => {+                error!(self, "Configure Failed: {}", err);+                progress!(self, 0);+                Err(err)+            }         }     } }  #[allow(clippy::too_many_arguments)]-async fn exec_step(-    ctx: &Context,-    imap: &mut Imap,-    param: &mut LoginParam,-    param_domain: &mut String,-    param_autoconfig: &mut Option<LoginParam>,-    param_addr_urlencoded: &mut String,-    keep_flags: &mut i32,-    step_counter: &mut u8,-) -> Result<Step> {-    const STEP_12_USE_AUTOCONFIG: u8 = 12;-    const STEP_13_AFTER_AUTOCONFIG: u8 = 13;--    match *step_counter {-        // Read login parameters from the database-        1 => {-            progress!(ctx, 1);-            ensure!(!param.addr.is_empty(), "Please enter an email address.");-        }-        // Step 1: Load the parameters and check email-address and password-        2 => {-            if 0 != param.server_flags & DC_LP_AUTH_OAUTH2 {-                // the used oauth2 addr may differ, check this.-                // if dc_get_oauth2_addr() is not available in the oauth2 implementation,-                // just use the given one.-                progress!(ctx, 10);-                if let Some(oauth2_addr) = dc_get_oauth2_addr(ctx, &param.addr, &param.mail_pw)-                    .await-                    .and_then(|e| e.parse().ok())-                {-                    info!(ctx, "Authorized address is {}", oauth2_addr);-                    param.addr = oauth2_addr;-                    ctx.sql-                        .set_raw_config(ctx, "addr", Some(param.addr.as_str()))-                        .await?;-                }-                progress!(ctx, 20);-            }-            // no oauth? - just continue it's no error-        }-        3 => {-            if let Ok(parsed) = param.addr.parse() {-                let parsed: EmailAddress = parsed;-                *param_domain = parsed.domain;-                *param_addr_urlencoded =-                    utf8_percent_encode(&param.addr, NON_ALPHANUMERIC).to_string();-            } else {-                bail!("Bad email-address.");-            }-        }-        // Step 2: Autoconfig-        4 => {-            progress!(ctx, 200);--            if param.mail_server.is_empty()-                && param.mail_port == 0-            /* && param.mail_user.is_empty() -- the user can enter a loginname which is used by autoconfig then */-                && param.send_server.is_empty()-                && param.send_port == 0-                && param.send_user.is_empty()-            /* && param.send_pw.is_empty() -- the password cannot be auto-configured and is no criterion for autoconfig or not */-                && (param.server_flags & !DC_LP_AUTH_OAUTH2) == 0-            {-                // no advanced parameters entered by the user: query provider-database or do Autoconfig-                *keep_flags = param.server_flags & DC_LP_AUTH_OAUTH2;-                if let Some(new_param) = get_offline_autoconfig(ctx, &param) {-                    // got parameters from our provider-database, skip Autoconfig, preserve the OAuth2 setting-                    *param_autoconfig = Some(new_param);-                    *step_counter = STEP_12_USE_AUTOCONFIG - 1; // minus one as step_counter is increased on next loop-                }-            } else {-                // advanced parameters entered by the user: skip Autoconfig-                *step_counter = STEP_13_AFTER_AUTOCONFIG - 1; // minus one as step_counter is increased on next loop-            }-        }-        /* A.  Search configurations from the domain used in the email-address, prefer encrypted */-        5 => {-            if param_autoconfig.is_none() {-                let url = format!(-                    "https://autoconfig.{}/mail/config-v1.1.xml?emailaddress={}",-                    param_domain, param_addr_urlencoded-                );-                *param_autoconfig = moz_autoconfigure(ctx, &url, &param).await.ok();-            }-        }-        6 => {-            progress!(ctx, 300);-            if param_autoconfig.is_none() {-                // the doc does not mention `emailaddress=`, however, Thunderbird adds it, see https://releases.mozilla.org/pub/thunderbird/ ,  which makes some sense-                let url = format!(-                    "https://{}/.well-known/autoconfig/mail/config-v1.1.xml?emailaddress={}",-                    param_domain, param_addr_urlencoded-                );-                *param_autoconfig = moz_autoconfigure(ctx, &url, &param).await.ok();-            }-        }-        /* Outlook section start ------------- */-        /* Outlook uses always SSL but different domains (this comment describes the next two steps) */-        7 => {-            progress!(ctx, 310);-            if param_autoconfig.is_none() {-                let url = format!("https://{}/autodiscover/autodiscover.xml", param_domain);-                *param_autoconfig = outlk_autodiscover(ctx, &url, &param).await.ok();-            }-        }-        8 => {-            progress!(ctx, 320);-            if param_autoconfig.is_none() {-                let url = format!(-                    "https://{}{}/autodiscover/autodiscover.xml",-                    "autodiscover.", param_domain-                );-                *param_autoconfig = outlk_autodiscover(ctx, &url, &param).await.ok();-            }+async fn configure(ctx: &Context, imap: &mut Imap, param: &mut LoginParam) -> Result<()> {+    let mut param_autoconfig: Option<LoginParam> = None;+    let mut keep_flags = 0;+    let mut use_autoconfig = true;++    // Read login parameters from the database+    progress!(ctx, 1);+    ensure!(!param.addr.is_empty(), "Please enter an email address.");++    // Step 1: Load the parameters and check email-address and password++    if 0 != param.server_flags & DC_LP_AUTH_OAUTH2 {+        // the used oauth2 addr may differ, check this.+        // if dc_get_oauth2_addr() is not available in the oauth2 implementation,+        // just use the given one.+        progress!(ctx, 10);+        if let Some(oauth2_addr) = dc_get_oauth2_addr(ctx, &param.addr, &param.mail_pw)+            .await+            .and_then(|e| e.parse().ok())+        {+            info!(ctx, "Authorized address is {}", oauth2_addr);+            param.addr = oauth2_addr;+            ctx.sql+                .set_raw_config(ctx, "addr", Some(param.addr.as_str()))+                .await?;         }-        /* ----------- Outlook section end */-        9 => {-            progress!(ctx, 330);-            if param_autoconfig.is_none() {-                let url = format!(-                    "http://autoconfig.{}/mail/config-v1.1.xml?emailaddress={}",-                    param_domain, param_addr_urlencoded-                );-                *param_autoconfig = moz_autoconfigure(ctx, &url, &param).await.ok();-            }+        progress!(ctx, 20);+    }+    // no oauth? - just continue it's no error++    let parsed: EmailAddress = param.addr.parse().context("Bad email-address")?;+    let param_domain = parsed.domain;+    let param_addr_urlencoded = utf8_percent_encode(&param.addr, NON_ALPHANUMERIC).to_string();++    // Step 2: Autoconfig+    progress!(ctx, 200);++    // param.mail_user.is_empty() -- the user can enter a loginname which is used by autoconfig then+    // param.send_pw.is_empty() -- the password cannot be auto-configured and is no criterion for autoconfig or not+    if param.mail_server.is_empty()+        && param.mail_port == 0+        && param.send_server.is_empty()+        && param.send_port == 0+        && param.send_user.is_empty()+        && (param.server_flags & !DC_LP_AUTH_OAUTH2) == 0+    {+        // no advanced parameters entered by the user: query provider-database or do Autoconfig+        keep_flags = param.server_flags & DC_LP_AUTH_OAUTH2;+        if let Some(new_param) = get_offline_autoconfig(ctx, &param) {+            // got parameters from our provider-database, skip Autoconfig, preserve the OAuth2 setting+            param_autoconfig = Some(new_param);         }-        10 => {-            progress!(ctx, 340);-            if param_autoconfig.is_none() {-                // do not transfer the email-address unencrypted-                let url = format!(-                    "http://{}/.well-known/autoconfig/mail/config-v1.1.xml",-                    param_domain-                );-                *param_autoconfig = moz_autoconfigure(ctx, &url, &param).await.ok();+    } else {+        // advanced parameters entered by the user: skip Autoconfig+        use_autoconfig = false;+    }++    if param_autoconfig.is_none() {+        param_autoconfig = get_autoconfig(ctx, param, &param_domain, &param_addr_urlencoded).await;+    }++    // C.  Do we have any autoconfig result?+    progress!(ctx, 500);+    if use_autoconfig {+        if let Some(ref cfg) = param_autoconfig {+            info!(ctx, "Got autoconfig: {}", &cfg);+            if !cfg.mail_user.is_empty() {+                param.mail_user = cfg.mail_user.clone();             }+            // all other values are always NULL when entering autoconfig+            param.mail_server = cfg.mail_server.clone();+            param.mail_port = cfg.mail_port;+            param.send_server = cfg.send_server.clone();+            param.send_port = cfg.send_port;+            param.send_user = cfg.send_user.clone();+            param.server_flags = cfg.server_flags;+            // although param_autoconfig's data are no longer needed from,+            // it is used to later to prevent trying variations of port/server/logins         }-        /* B.  If we have no configuration yet, search configuration in Thunderbird's centeral database */-        11 => {-            progress!(ctx, 350);-            if param_autoconfig.is_none() {-                /* always SSL for Thunderbird's database */-                let url = format!("https://autoconfig.thunderbird.net/v1.1/{}", param_domain);-                *param_autoconfig = moz_autoconfigure(ctx, &url, &param).await.ok();-            }+        param.server_flags |= keep_flags;+    }++    // Step 3: Fill missing fields with defaults+    if param.mail_server.is_empty() {+        param.mail_server = format!("imap.{}", param_domain,)+    }+    if param.mail_port == 0 {+        param.mail_port = if 0 != param.server_flags & (0x100 | 0x400) {+            143+        } else {+            993         }-        /* C.  Do we have any autoconfig result?-           If you change the match-number here, also update STEP_12_COPY_AUTOCONFIG above-        */-        STEP_12_USE_AUTOCONFIG => {-            progress!(ctx, 500);-            if let Some(ref cfg) = param_autoconfig {-                info!(ctx, "Got autoconfig: {}", &cfg);-                if !cfg.mail_user.is_empty() {-                    param.mail_user = cfg.mail_user.clone();-                }-                param.mail_server = cfg.mail_server.clone(); /* all other values are always NULL when entering autoconfig */-                param.mail_port = cfg.mail_port;-                param.send_server = cfg.send_server.clone();-                param.send_port = cfg.send_port;-                param.send_user = cfg.send_user.clone();-                param.server_flags = cfg.server_flags;-                /* although param_autoconfig's data are no longer needed from,-                it is used to later to prevent trying variations of port/server/logins */-            }-            param.server_flags |= *keep_flags;+    }+    if param.mail_user.is_empty() {+        param.mail_user = param.addr.clone();+    }+    if param.send_server.is_empty() && !param.mail_server.is_empty() {+        param.send_server = param.mail_server.clone();+        if param.send_server.starts_with("imap.") {+            param.send_server = param.send_server.replacen("imap", "smtp", 1);         }-        // Step 3: Fill missing fields with defaults-        // If you change the match-number here, also update STEP_13_AFTER_AUTOCONFIG above-        STEP_13_AFTER_AUTOCONFIG => {-            if param.mail_server.is_empty() {-                param.mail_server = format!("imap.{}", param_domain,)-            }-            if param.mail_port == 0 {-                param.mail_port = if 0 != param.server_flags & (0x100 | 0x400) {-                    143-                } else {-                    993-                }-            }-            if param.mail_user.is_empty() {-                param.mail_user = param.addr.clone();-            }-            if param.send_server.is_empty() && !param.mail_server.is_empty() {-                param.send_server = param.mail_server.clone();-                if param.send_server.starts_with("imap.") {-                    param.send_server = param.send_server.replacen("imap", "smtp", 1);-                }-            }-            if param.send_port == 0 {-                param.send_port = if 0 != param.server_flags & DC_LP_SMTP_SOCKET_STARTTLS as i32 {-                    587-                } else if 0 != param.server_flags & DC_LP_SMTP_SOCKET_PLAIN as i32 {-                    25-                } else {-                    465-                }-            }-            if param.send_user.is_empty() && !param.mail_user.is_empty() {-                param.send_user = param.mail_user.clone();-            }-            if param.send_pw.is_empty() && !param.mail_pw.is_empty() {-                param.send_pw = param.mail_pw.clone()-            }-            if !dc_exactly_one_bit_set(param.server_flags & DC_LP_AUTH_FLAGS as i32) {-                param.server_flags &= !(DC_LP_AUTH_FLAGS as i32);-                param.server_flags |= DC_LP_AUTH_NORMAL as i32-            }-            if !dc_exactly_one_bit_set(param.server_flags & DC_LP_IMAP_SOCKET_FLAGS as i32) {-                param.server_flags &= !(DC_LP_IMAP_SOCKET_FLAGS as i32);-                param.server_flags |= if param.send_port == 143 {-                    DC_LP_IMAP_SOCKET_STARTTLS as i32-                } else {-                    DC_LP_IMAP_SOCKET_SSL as i32-                }-            }-            if !dc_exactly_one_bit_set(param.server_flags & (DC_LP_SMTP_SOCKET_FLAGS as i32)) {-                param.server_flags &= !(DC_LP_SMTP_SOCKET_FLAGS as i32);-                param.server_flags |= if param.send_port == 587 {-                    DC_LP_SMTP_SOCKET_STARTTLS as i32-                } else if param.send_port == 25 {-                    DC_LP_SMTP_SOCKET_PLAIN as i32-                } else {-                    DC_LP_SMTP_SOCKET_SSL as i32-                }-            }-            /* do we have a complete configuration? */-            if param.mail_server.is_empty()-                || param.mail_port == 0-                || param.mail_user.is_empty()-                || param.mail_pw.is_empty()-                || param.send_server.is_empty()-                || param.send_port == 0-                || param.send_user.is_empty()-                || param.send_pw.is_empty()-                || param.server_flags == 0-            {-                bail!("Account settings incomplete.");-            }+    }+    if param.send_port == 0 {+        param.send_port = if 0 != param.server_flags & DC_LP_SMTP_SOCKET_STARTTLS as i32 {+            587+        } else if 0 != param.server_flags & DC_LP_SMTP_SOCKET_PLAIN as i32 {+            25+        } else {+            465         }-        14 => {-            progress!(ctx, 600);-            /* try to connect to IMAP - if we did not got an autoconfig,-            do some further tries with different settings and username variations */-            try_imap_connections(ctx, param, param_autoconfig.is_some(), imap).await?;+    }+    if param.send_user.is_empty() && !param.mail_user.is_empty() {+        param.send_user = param.mail_user.clone();+    }+    if param.send_pw.is_empty() && !param.mail_pw.is_empty() {+        param.send_pw = param.mail_pw.clone()+    }+    if !dc_exactly_one_bit_set(param.server_flags & DC_LP_AUTH_FLAGS as i32) {+        param.server_flags &= !(DC_LP_AUTH_FLAGS as i32);+        param.server_flags |= DC_LP_AUTH_NORMAL as i32+    }+    if !dc_exactly_one_bit_set(param.server_flags & DC_LP_IMAP_SOCKET_FLAGS as i32) {+        param.server_flags &= !(DC_LP_IMAP_SOCKET_FLAGS as i32);+        param.server_flags |= if param.send_port == 143 {+            DC_LP_IMAP_SOCKET_STARTTLS as i32+        } else {+            DC_LP_IMAP_SOCKET_SSL as i32         }-        15 => {-            progress!(ctx, 800);-            try_smtp_connections(ctx, param, param_autoconfig.is_some()).await?;+    }+    if !dc_exactly_one_bit_set(param.server_flags & (DC_LP_SMTP_SOCKET_FLAGS as i32)) {+        param.server_flags &= !(DC_LP_SMTP_SOCKET_FLAGS as i32);+        param.server_flags |= if param.send_port == 587 {+            DC_LP_SMTP_SOCKET_STARTTLS as i32+        } else if param.send_port == 25 {+            DC_LP_SMTP_SOCKET_PLAIN as i32+        } else {+            DC_LP_SMTP_SOCKET_SSL as i32         }-        16 => {-            progress!(ctx, 900);+    } -            let create_mvbox = ctx.get_config_bool(Config::MvboxWatch).await-                || ctx.get_config_bool(Config::MvboxMove).await;+    // do we have a complete configuration?+    if param.mail_server.is_empty()+        || param.mail_port == 0+        || param.mail_user.is_empty()+        || param.mail_pw.is_empty()+        || param.send_server.is_empty()+        || param.send_port == 0+        || param.send_user.is_empty()+        || param.send_pw.is_empty()+        || param.server_flags == 0+    {+        bail!("Account settings incomplete.");+    } -            if let Err(err) = imap.configure_folders(ctx, create_mvbox).await {-                bail!("configuring folders failed: {:?}", err);-            }+    progress!(ctx, 600);+    // try to connect to IMAP - if we did not got an autoconfig,+    // do some further tries with different settings and username variations+    try_imap_connections(ctx, param, param_autoconfig.is_some(), imap).await?; -            if let Err(err) = imap.select_with_uidvalidity(ctx, "INBOX").await {-                bail!("could not read INBOX status: {:?}", err);-            }-        }-        17 => {-            progress!(ctx, 910);-            // configuration success - write back the configured parameters with the-            // "configured_" prefix; also write the "configured"-flag */-            // the trailing underscore is correct-            param.save_to_database(ctx, "configured_").await?;-            ctx.sql.set_raw_config_bool(ctx, "configured", true).await?;-        }-        18 => {-            progress!(ctx, 920);-            // we generate the keypair just now - we could also postpone this until the first message is sent, however,-            // this may result in a unexpected and annoying delay when the user sends his very first message-            // (~30 seconds on a Moto G4 play) and might looks as if message sending is always that slow.-            e2ee::ensure_secret_key_exists(ctx).await?;-            info!(ctx, "key generation completed");-            progress!(ctx, 940);-            return Ok(Step::Done);-        }-        _ => {-            bail!("Internal error: step counter out of bound");-        }+    progress!(ctx, 800);+    try_smtp_connections(ctx, param, param_autoconfig.is_some()).await?;++    progress!(ctx, 900);++    let create_mvbox = ctx.get_config_bool(Config::MvboxWatch).await+        || ctx.get_config_bool(Config::MvboxMove).await;++    if let Err(err) = imap.configure_folders(ctx, create_mvbox).await {+        bail!("configuring folders failed: {:?}", err);     } -    Ok(Step::Continue)+    if let Err(err) = imap.select_with_uidvalidity(ctx, "INBOX").await {+        bail!("could not read INBOX status: {:?}", err);+    }++    progress!(ctx, 910);+    // configuration success - write back the configured parameters with the+    // "configured_" prefix; also write the "configured"-flag */+    // the trailing underscore is correct+    param.save_to_database(ctx, "configured_").await?;+    ctx.sql.set_raw_config_bool(ctx, "configured", true).await?;++    progress!(ctx, 920);+    // we generate the keypair just now - we could also postpone this until the first message is sent, however,+    // this may result in a unexpected and annoying delay when the user sends his very first message+    // (~30 seconds on a Moto G4 play) and might looks as if message sending is always that slow.

removed

dignifiedquire

comment created time in 4 days

Pull request review commentdeltachat/deltachat-core-rust

refactor(configure): simplify logic and code

 impl Context {             }         } -        if success {-            progress!(self, 1000);-            Ok(())-        } else {-            progress!(self, 0);-            Err(format_err!("Configure failed"))+        match success {+            Ok(_) => {+                progress!(self, 1000);+                Ok(())+            }+            Err(err) => {+                error!(self, "Configure Failed: {}", err);+                progress!(self, 0);+                Err(err)+            }         }     } }  #[allow(clippy::too_many_arguments)]-async fn exec_step(-    ctx: &Context,-    imap: &mut Imap,-    param: &mut LoginParam,-    param_domain: &mut String,-    param_autoconfig: &mut Option<LoginParam>,-    param_addr_urlencoded: &mut String,-    keep_flags: &mut i32,-    step_counter: &mut u8,-) -> Result<Step> {-    const STEP_12_USE_AUTOCONFIG: u8 = 12;-    const STEP_13_AFTER_AUTOCONFIG: u8 = 13;--    match *step_counter {-        // Read login parameters from the database-        1 => {-            progress!(ctx, 1);-            ensure!(!param.addr.is_empty(), "Please enter an email address.");-        }-        // Step 1: Load the parameters and check email-address and password-        2 => {-            if 0 != param.server_flags & DC_LP_AUTH_OAUTH2 {-                // the used oauth2 addr may differ, check this.-                // if dc_get_oauth2_addr() is not available in the oauth2 implementation,-                // just use the given one.-                progress!(ctx, 10);-                if let Some(oauth2_addr) = dc_get_oauth2_addr(ctx, &param.addr, &param.mail_pw)-                    .await-                    .and_then(|e| e.parse().ok())-                {-                    info!(ctx, "Authorized address is {}", oauth2_addr);-                    param.addr = oauth2_addr;-                    ctx.sql-                        .set_raw_config(ctx, "addr", Some(param.addr.as_str()))-                        .await?;-                }-                progress!(ctx, 20);-            }-            // no oauth? - just continue it's no error-        }-        3 => {-            if let Ok(parsed) = param.addr.parse() {-                let parsed: EmailAddress = parsed;-                *param_domain = parsed.domain;-                *param_addr_urlencoded =-                    utf8_percent_encode(&param.addr, NON_ALPHANUMERIC).to_string();-            } else {-                bail!("Bad email-address.");-            }-        }-        // Step 2: Autoconfig-        4 => {-            progress!(ctx, 200);--            if param.mail_server.is_empty()-                && param.mail_port == 0-            /* && param.mail_user.is_empty() -- the user can enter a loginname which is used by autoconfig then */-                && param.send_server.is_empty()-                && param.send_port == 0-                && param.send_user.is_empty()-            /* && param.send_pw.is_empty() -- the password cannot be auto-configured and is no criterion for autoconfig or not */-                && (param.server_flags & !DC_LP_AUTH_OAUTH2) == 0-            {-                // no advanced parameters entered by the user: query provider-database or do Autoconfig-                *keep_flags = param.server_flags & DC_LP_AUTH_OAUTH2;-                if let Some(new_param) = get_offline_autoconfig(ctx, &param) {-                    // got parameters from our provider-database, skip Autoconfig, preserve the OAuth2 setting-                    *param_autoconfig = Some(new_param);-                    *step_counter = STEP_12_USE_AUTOCONFIG - 1; // minus one as step_counter is increased on next loop-                }-            } else {-                // advanced parameters entered by the user: skip Autoconfig-                *step_counter = STEP_13_AFTER_AUTOCONFIG - 1; // minus one as step_counter is increased on next loop-            }-        }-        /* A.  Search configurations from the domain used in the email-address, prefer encrypted */-        5 => {-            if param_autoconfig.is_none() {-                let url = format!(-                    "https://autoconfig.{}/mail/config-v1.1.xml?emailaddress={}",-                    param_domain, param_addr_urlencoded-                );-                *param_autoconfig = moz_autoconfigure(ctx, &url, &param).await.ok();-            }-        }-        6 => {-            progress!(ctx, 300);-            if param_autoconfig.is_none() {-                // the doc does not mention `emailaddress=`, however, Thunderbird adds it, see https://releases.mozilla.org/pub/thunderbird/ ,  which makes some sense-                let url = format!(-                    "https://{}/.well-known/autoconfig/mail/config-v1.1.xml?emailaddress={}",-                    param_domain, param_addr_urlencoded-                );-                *param_autoconfig = moz_autoconfigure(ctx, &url, &param).await.ok();-            }-        }-        /* Outlook section start ------------- */-        /* Outlook uses always SSL but different domains (this comment describes the next two steps) */-        7 => {-            progress!(ctx, 310);-            if param_autoconfig.is_none() {-                let url = format!("https://{}/autodiscover/autodiscover.xml", param_domain);-                *param_autoconfig = outlk_autodiscover(ctx, &url, &param).await.ok();-            }-        }-        8 => {-            progress!(ctx, 320);-            if param_autoconfig.is_none() {-                let url = format!(-                    "https://{}{}/autodiscover/autodiscover.xml",-                    "autodiscover.", param_domain-                );-                *param_autoconfig = outlk_autodiscover(ctx, &url, &param).await.ok();-            }+async fn configure(ctx: &Context, imap: &mut Imap, param: &mut LoginParam) -> Result<()> {+    let mut param_autoconfig: Option<LoginParam> = None;+    let mut keep_flags = 0;+    let mut use_autoconfig = true;++    // Read login parameters from the database+    progress!(ctx, 1);+    ensure!(!param.addr.is_empty(), "Please enter an email address.");++    // Step 1: Load the parameters and check email-address and password++    if 0 != param.server_flags & DC_LP_AUTH_OAUTH2 {+        // the used oauth2 addr may differ, check this.+        // if dc_get_oauth2_addr() is not available in the oauth2 implementation,+        // just use the given one.+        progress!(ctx, 10);+        if let Some(oauth2_addr) = dc_get_oauth2_addr(ctx, &param.addr, &param.mail_pw)+            .await+            .and_then(|e| e.parse().ok())+        {+            info!(ctx, "Authorized address is {}", oauth2_addr);+            param.addr = oauth2_addr;+            ctx.sql+                .set_raw_config(ctx, "addr", Some(param.addr.as_str()))+                .await?;         }-        /* ----------- Outlook section end */-        9 => {-            progress!(ctx, 330);-            if param_autoconfig.is_none() {-                let url = format!(-                    "http://autoconfig.{}/mail/config-v1.1.xml?emailaddress={}",-                    param_domain, param_addr_urlencoded-                );-                *param_autoconfig = moz_autoconfigure(ctx, &url, &param).await.ok();-            }+        progress!(ctx, 20);+    }+    // no oauth? - just continue it's no error++    let parsed: EmailAddress = param.addr.parse().context("Bad email-address")?;+    let param_domain = parsed.domain;+    let param_addr_urlencoded = utf8_percent_encode(&param.addr, NON_ALPHANUMERIC).to_string();++    // Step 2: Autoconfig+    progress!(ctx, 200);++    // param.mail_user.is_empty() -- the user can enter a loginname which is used by autoconfig then+    // param.send_pw.is_empty() -- the password cannot be auto-configured and is no criterion for autoconfig or not+    if param.mail_server.is_empty()+        && param.mail_port == 0+        && param.send_server.is_empty()+        && param.send_port == 0+        && param.send_user.is_empty()+        && (param.server_flags & !DC_LP_AUTH_OAUTH2) == 0+    {+        // no advanced parameters entered by the user: query provider-database or do Autoconfig+        keep_flags = param.server_flags & DC_LP_AUTH_OAUTH2;+        if let Some(new_param) = get_offline_autoconfig(ctx, &param) {+            // got parameters from our provider-database, skip Autoconfig, preserve the OAuth2 setting+            param_autoconfig = Some(new_param);         }-        10 => {-            progress!(ctx, 340);-            if param_autoconfig.is_none() {-                // do not transfer the email-address unencrypted-                let url = format!(-                    "http://{}/.well-known/autoconfig/mail/config-v1.1.xml",-                    param_domain-                );-                *param_autoconfig = moz_autoconfigure(ctx, &url, &param).await.ok();+    } else {+        // advanced parameters entered by the user: skip Autoconfig+        use_autoconfig = false;+    }++    if param_autoconfig.is_none() {+        param_autoconfig = get_autoconfig(ctx, param, &param_domain, &param_addr_urlencoded).await;+    }++    // C.  Do we have any autoconfig result?+    progress!(ctx, 500);+    if use_autoconfig {+        if let Some(ref cfg) = param_autoconfig {+            info!(ctx, "Got autoconfig: {}", &cfg);+            if !cfg.mail_user.is_empty() {+                param.mail_user = cfg.mail_user.clone();             }+            // all other values are always NULL when entering autoconfig+            param.mail_server = cfg.mail_server.clone();+            param.mail_port = cfg.mail_port;+            param.send_server = cfg.send_server.clone();+            param.send_port = cfg.send_port;+            param.send_user = cfg.send_user.clone();+            param.server_flags = cfg.server_flags;+            // although param_autoconfig's data are no longer needed from,+            // it is used to later to prevent trying variations of port/server/logins         }-        /* B.  If we have no configuration yet, search configuration in Thunderbird's centeral database */-        11 => {-            progress!(ctx, 350);-            if param_autoconfig.is_none() {-                /* always SSL for Thunderbird's database */-                let url = format!("https://autoconfig.thunderbird.net/v1.1/{}", param_domain);-                *param_autoconfig = moz_autoconfigure(ctx, &url, &param).await.ok();-            }+        param.server_flags |= keep_flags;+    }++    // Step 3: Fill missing fields with defaults+    if param.mail_server.is_empty() {+        param.mail_server = format!("imap.{}", param_domain,)+    }+    if param.mail_port == 0 {+        param.mail_port = if 0 != param.server_flags & (0x100 | 0x400) {+            143+        } else {+            993         }-        /* C.  Do we have any autoconfig result?-           If you change the match-number here, also update STEP_12_COPY_AUTOCONFIG above-        */-        STEP_12_USE_AUTOCONFIG => {-            progress!(ctx, 500);-            if let Some(ref cfg) = param_autoconfig {-                info!(ctx, "Got autoconfig: {}", &cfg);-                if !cfg.mail_user.is_empty() {-                    param.mail_user = cfg.mail_user.clone();-                }-                param.mail_server = cfg.mail_server.clone(); /* all other values are always NULL when entering autoconfig */-                param.mail_port = cfg.mail_port;-                param.send_server = cfg.send_server.clone();-                param.send_port = cfg.send_port;-                param.send_user = cfg.send_user.clone();-                param.server_flags = cfg.server_flags;-                /* although param_autoconfig's data are no longer needed from,-                it is used to later to prevent trying variations of port/server/logins */-            }-            param.server_flags |= *keep_flags;+    }+    if param.mail_user.is_empty() {+        param.mail_user = param.addr.clone();+    }+    if param.send_server.is_empty() && !param.mail_server.is_empty() {+        param.send_server = param.mail_server.clone();+        if param.send_server.starts_with("imap.") {+            param.send_server = param.send_server.replacen("imap", "smtp", 1);         }-        // Step 3: Fill missing fields with defaults-        // If you change the match-number here, also update STEP_13_AFTER_AUTOCONFIG above-        STEP_13_AFTER_AUTOCONFIG => {-            if param.mail_server.is_empty() {-                param.mail_server = format!("imap.{}", param_domain,)-            }-            if param.mail_port == 0 {-                param.mail_port = if 0 != param.server_flags & (0x100 | 0x400) {-                    143-                } else {-                    993-                }-            }-            if param.mail_user.is_empty() {-                param.mail_user = param.addr.clone();-            }-            if param.send_server.is_empty() && !param.mail_server.is_empty() {-                param.send_server = param.mail_server.clone();-                if param.send_server.starts_with("imap.") {-                    param.send_server = param.send_server.replacen("imap", "smtp", 1);-                }-            }-            if param.send_port == 0 {-                param.send_port = if 0 != param.server_flags & DC_LP_SMTP_SOCKET_STARTTLS as i32 {-                    587-                } else if 0 != param.server_flags & DC_LP_SMTP_SOCKET_PLAIN as i32 {-                    25-                } else {-                    465-                }-            }-            if param.send_user.is_empty() && !param.mail_user.is_empty() {-                param.send_user = param.mail_user.clone();-            }-            if param.send_pw.is_empty() && !param.mail_pw.is_empty() {-                param.send_pw = param.mail_pw.clone()-            }-            if !dc_exactly_one_bit_set(param.server_flags & DC_LP_AUTH_FLAGS as i32) {-                param.server_flags &= !(DC_LP_AUTH_FLAGS as i32);-                param.server_flags |= DC_LP_AUTH_NORMAL as i32-            }-            if !dc_exactly_one_bit_set(param.server_flags & DC_LP_IMAP_SOCKET_FLAGS as i32) {-                param.server_flags &= !(DC_LP_IMAP_SOCKET_FLAGS as i32);-                param.server_flags |= if param.send_port == 143 {-                    DC_LP_IMAP_SOCKET_STARTTLS as i32-                } else {-                    DC_LP_IMAP_SOCKET_SSL as i32-                }-            }-            if !dc_exactly_one_bit_set(param.server_flags & (DC_LP_SMTP_SOCKET_FLAGS as i32)) {-                param.server_flags &= !(DC_LP_SMTP_SOCKET_FLAGS as i32);-                param.server_flags |= if param.send_port == 587 {-                    DC_LP_SMTP_SOCKET_STARTTLS as i32-                } else if param.send_port == 25 {-                    DC_LP_SMTP_SOCKET_PLAIN as i32-                } else {-                    DC_LP_SMTP_SOCKET_SSL as i32-                }-            }-            /* do we have a complete configuration? */-            if param.mail_server.is_empty()-                || param.mail_port == 0-                || param.mail_user.is_empty()-                || param.mail_pw.is_empty()-                || param.send_server.is_empty()-                || param.send_port == 0-                || param.send_user.is_empty()-                || param.send_pw.is_empty()-                || param.server_flags == 0-            {-                bail!("Account settings incomplete.");-            }+    }+    if param.send_port == 0 {+        param.send_port = if 0 != param.server_flags & DC_LP_SMTP_SOCKET_STARTTLS as i32 {+            587+        } else if 0 != param.server_flags & DC_LP_SMTP_SOCKET_PLAIN as i32 {+            25+        } else {+            465         }-        14 => {-            progress!(ctx, 600);-            /* try to connect to IMAP - if we did not got an autoconfig,-            do some further tries with different settings and username variations */-            try_imap_connections(ctx, param, param_autoconfig.is_some(), imap).await?;+    }+    if param.send_user.is_empty() && !param.mail_user.is_empty() {+        param.send_user = param.mail_user.clone();+    }+    if param.send_pw.is_empty() && !param.mail_pw.is_empty() {+        param.send_pw = param.mail_pw.clone()+    }+    if !dc_exactly_one_bit_set(param.server_flags & DC_LP_AUTH_FLAGS as i32) {+        param.server_flags &= !(DC_LP_AUTH_FLAGS as i32);+        param.server_flags |= DC_LP_AUTH_NORMAL as i32+    }+    if !dc_exactly_one_bit_set(param.server_flags & DC_LP_IMAP_SOCKET_FLAGS as i32) {+        param.server_flags &= !(DC_LP_IMAP_SOCKET_FLAGS as i32);+        param.server_flags |= if param.send_port == 143 {+            DC_LP_IMAP_SOCKET_STARTTLS as i32+        } else {+            DC_LP_IMAP_SOCKET_SSL as i32         }-        15 => {-            progress!(ctx, 800);-            try_smtp_connections(ctx, param, param_autoconfig.is_some()).await?;+    }+    if !dc_exactly_one_bit_set(param.server_flags & (DC_LP_SMTP_SOCKET_FLAGS as i32)) {+        param.server_flags &= !(DC_LP_SMTP_SOCKET_FLAGS as i32);+        param.server_flags |= if param.send_port == 587 {+            DC_LP_SMTP_SOCKET_STARTTLS as i32+        } else if param.send_port == 25 {+            DC_LP_SMTP_SOCKET_PLAIN as i32+        } else {+            DC_LP_SMTP_SOCKET_SSL as i32         }-        16 => {-            progress!(ctx, 900);+    } -            let create_mvbox = ctx.get_config_bool(Config::MvboxWatch).await-                || ctx.get_config_bool(Config::MvboxMove).await;+    // do we have a complete configuration?+    if param.mail_server.is_empty()+        || param.mail_port == 0+        || param.mail_user.is_empty()+        || param.mail_pw.is_empty()+        || param.send_server.is_empty()+        || param.send_port == 0+        || param.send_user.is_empty()+        || param.send_pw.is_empty()+        || param.server_flags == 0+    {+        bail!("Account settings incomplete.");+    } -            if let Err(err) = imap.configure_folders(ctx, create_mvbox).await {-                bail!("configuring folders failed: {:?}", err);-            }+    progress!(ctx, 600);+    // try to connect to IMAP - if we did not got an autoconfig,+    // do some further tries with different settings and username variations+    try_imap_connections(ctx, param, param_autoconfig.is_some(), imap).await?; -            if let Err(err) = imap.select_with_uidvalidity(ctx, "INBOX").await {-                bail!("could not read INBOX status: {:?}", err);-            }-        }-        17 => {-            progress!(ctx, 910);-            // configuration success - write back the configured parameters with the-            // "configured_" prefix; also write the "configured"-flag */-            // the trailing underscore is correct-            param.save_to_database(ctx, "configured_").await?;-            ctx.sql.set_raw_config_bool(ctx, "configured", true).await?;-        }-        18 => {-            progress!(ctx, 920);-            // we generate the keypair just now - we could also postpone this until the first message is sent, however,-            // this may result in a unexpected and annoying delay when the user sends his very first message-            // (~30 seconds on a Moto G4 play) and might looks as if message sending is always that slow.-            e2ee::ensure_secret_key_exists(ctx).await?;-            info!(ctx, "key generation completed");-            progress!(ctx, 940);-            return Ok(Step::Done);-        }-        _ => {-            bail!("Internal error: step counter out of bound");-        }+    progress!(ctx, 800);+    try_smtp_connections(ctx, param, param_autoconfig.is_some()).await?;++    progress!(ctx, 900);++    let create_mvbox = ctx.get_config_bool(Config::MvboxWatch).await+        || ctx.get_config_bool(Config::MvboxMove).await;++    if let Err(err) = imap.configure_folders(ctx, create_mvbox).await {+        bail!("configuring folders failed: {:?}", err);     } -    Ok(Step::Continue)+    if let Err(err) = imap.select_with_uidvalidity(ctx, "INBOX").await {+        bail!("could not read INBOX status: {:?}", err);+    }++    progress!(ctx, 910);+    // configuration success - write back the configured parameters with the+    // "configured_" prefix; also write the "configured"-flag */+    // the trailing underscore is correct+    param.save_to_database(ctx, "configured_").await?;+    ctx.sql.set_raw_config_bool(ctx, "configured", true).await?;++    progress!(ctx, 920);+    // we generate the keypair just now - we could also postpone this until the first message is sent, however,+    // this may result in a unexpected and annoying delay when the user sends his very first message+    // (~30 seconds on a Moto G4 play) and might looks as if message sending is always that slow.+    e2ee::ensure_secret_key_exists(ctx).await?;+    info!(ctx, "key generation completed");++    progress!(ctx, 940);++    Ok(())+}++#[derive(Debug, PartialEq, Eq)]+enum AutoconfigProvider {+    Mozilla,+    Outlook,+}++#[derive(Debug, PartialEq, Eq)]+struct AutconfigSource {+    provider: AutoconfigProvider,+    url: String,+}++impl AutconfigSource {+    async fn fetch(&self, ctx: &Context, param: &LoginParam) -> Result<LoginParam> {+        let params = match self.provider {+            AutoconfigProvider::Mozilla => moz_autoconfigure(ctx, &self.url, &param).await?,+            AutoconfigProvider::Outlook => outlk_autodiscover(ctx, &self.url, &param).await?,+        };++        Ok(params)+    } } -#[derive(Debug)]-enum Step {-    Done,-    Continue,+/// Retrieve available autoconfigurations.+///+/// A Search configurations from the domain used in the email-address, prefer encrypted+/// B. If we have no configuration yet, search configuration in Thunderbird's centeral database+async fn get_autoconfig(+    ctx: &Context,+    param: &LoginParam,+    param_domain: &str,+    param_addr_urlencoded: &str,+) -> Option<LoginParam> {+    let mut param_autoconfig = None;++    let urls = [+        AutconfigSource {+            provider: AutoconfigProvider::Mozilla,+            url: format!(+                "https://autoconfig.{}/mail/config-v1.1.xml?emailaddress={}",+                param_domain, param_addr_urlencoded+            ),+        },+        // the doc does not mention `emailaddress=`, however, Thunderbird adds it, see https://releases.mozilla.org/pub/thunderbird/ ,  which makes some sense+        AutconfigSource {+            provider: AutoconfigProvider::Mozilla,+            url: format!(+                "https://{}/.well-known/autoconfig/mail/config-v1.1.xml?emailaddress={}",+                param_domain, param_addr_urlencoded+            ),+        },+        AutconfigSource {+            provider: AutoconfigProvider::Outlook,+            url: format!("https://{}/autodiscover/autodiscover.xml", param_domain),+        },+        // Outlook uses always SSL but different domains (this comment describes the next two steps)+        AutconfigSource {+            provider: AutoconfigProvider::Outlook,+            url: format!(+                "https://{}{}/autodiscover/autodiscover.xml",+                "autodiscover.", param_domain+            ),+        },+        AutconfigSource {+            provider: AutoconfigProvider::Mozilla,+            url: format!(+                "http://autoconfig.{}/mail/config-v1.1.xml?emailaddress={}",+                param_domain, param_addr_urlencoded+            ),+        }, // do not transfer the email-address unencrypted+        AutconfigSource {+            provider: AutoconfigProvider::Mozilla,+            url: format!(+                "http://{}/.well-known/autoconfig/mail/config-v1.1.xml",+                param_domain+            ),+        },

removed

dignifiedquire

comment created time in 4 days

push eventdeltachat/deltachat-core-rust

Hocuri

commit sha b6161c431b886f6a76248260a34169e286d0058b

Fix #1474 "Sending message to contact with < or > in Recipient gets treated as "Sent" but is not received" (#1476) Fix #1474 "Sending message to contact with < or > in Recipient gets treated as "Sent" but is not received". As I was at it, I also extracted the correct name and address from addresses like Mueller, Dave <dave@domain.com>.

view details

dignifiedquire

commit sha 43f49f89174316267fd7d143c1478d49686162f9

refactor(configure): remove step-counter

view details

dignifiedquire

commit sha 408e9946af42d05d9d75eb7e85a0af5052855e6a

refactor(configure): cleanup logic

view details

B. Petersen

commit sha 84963e198e2726fed36df959019010037c497ac3

do autoconfig only when no advanced options are entered the advanced options are not used anyway later, but prevent imap/smtp connections from being altered. nb: we want to stop altering when some advanced options are entered, however, we want to do this probaby not depending on autoconfig.

view details

dignifiedquire

commit sha 6d8b4a7ec0254c64f32dd5a20381db459937c6a9

simplify further and apply CR

view details

push time in 4 days

Pull request review commentfilecoin-project/bls-signatures

Improve security checks

 impl Serialize for PrivateKey {     }      fn from_bytes(raw: &[u8]) -> Result<Self, Error> {+        const FR_SIZE: usize = (Fr::NUM_BITS as usize + 8 - 1) / 8;

ceil(size/8) without using floats

dignifiedquire

comment created time in 4 days

push eventdeltachat/deltachat-core-rust

B. Petersen

commit sha c0857e516e4b81494bb5765314372d262b685e2c

do autoconfig only when no advanced options are entered the advanced options are not used anyway later, but prevent imap/smtp connections from being altered. nb: we want to stop altering when some advanced options are entered, however, we want to do this probaby not depending on autoconfig.

view details

Friedel Ziegelmayer

commit sha df9ba4b1ae0633bcb6c74a746ddf267e42c67f4d

Merge pull request #1541 from deltachat/tweak-sane-configure do autoconfig only when no advanced options are entered

view details

push time in 4 days

delete branch deltachat/deltachat-core-rust

delete branch : tweak-sane-configure

delete time in 4 days

PR merged deltachat/deltachat-core-rust

do autoconfig only when no advanced options are entered

the advanced options are not used anyway later, but prevent imap/smtp connections from being altered.

nb: we want to stop altering when some advanced options are entered, however, we want to do this probaby not depending on autoconfig.

+19 -24

0 comment

1 changed file

r10s

pr closed time in 4 days

issue commentrust-analyzer/rust-analyzer

100 CPU load and infinite loop

Running into this as well. I was able to attach lldb to it and gather the following traces

git commit: 190a0595a478d059fdd95a179fe38d59cb6379be

Executable module set to "/Users/dignifiedquire/.cargo/bin/rust-analyzer".
Architecture set to: x86_64h-apple-macosx.
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
  * frame #0: 0x00007fff7f00b86a libsystem_kernel.dylib`__psynch_cvwait + 10
    frame #1: 0x00007fff7f0ca56e libsystem_pthread.dylib`_pthread_cond_wait + 722
    frame #2: 0x0000000107269f12 rust-analyzer`std::thread::park::hde008ae05bf6ce2e [inlined] std::sys::unix::condvar::Condvar::wait::haf711209224495da at condvar.rs:73:17 [opt]
    frame #3: 0x0000000107269f0d rust-analyzer`std::thread::park::hde008ae05bf6ce2e [inlined] std::sys_common::condvar::Condvar::wait::hbda63240707accba at condvar.rs:50 [opt]
    frame #4: 0x0000000107269f0d rust-analyzer`std::thread::park::hde008ae05bf6ce2e [inlined] std::sync::condvar::Condvar::wait::h176016a76bad0c38 at condvar.rs:200 [opt]
    frame #5: 0x0000000107269ef3 rust-analyzer`std::thread::park::hde008ae05bf6ce2e at mod.rs:919 [opt]
    frame #6: 0x0000000107260785 rust-analyzer`crossbeam_channel::context::Context::wait_until::h4c4da7e476636502 + 325
    frame #7: 0x0000000107260415 rust-analyzer`crossbeam_channel::context::Context::with::_$u7b$$u7b$closure$u7d$$u7d$::h6657e7b32116da97 + 485
    frame #8: 0x0000000107260998 rust-analyzer`crossbeam_channel::select::run_select::h58f57381a0cf5b86 + 408
    frame #9: 0x00000001062caba8 rust-analyzer`rust_analyzer::main_loop::main_loop::h86d8e7a76e6b731a + 5096
    frame #10: 0x000000010614d881 rust-analyzer`rust_analyzer::main::hb300eef24b10a083 + 5921
    frame #11: 0x0000000106177326 rust-analyzer`std::rt::lang_start::_$u7b$$u7b$closure$u7d$$u7d$::h44458d503897e783 + 6
    frame #12: 0x000000010727a2d9 rust-analyzer`std::rt::lang_start_internal::h2d2d7c5f224149f7 [inlined] std::rt::lang_start_internal::_$u7b$$u7b$closure$u7d$$u7d$::hc4eba503b68bbb2b at rt.rs:52:13 [opt]
    frame #13: 0x000000010727a2ce rust-analyzer`std::rt::lang_start_internal::h2d2d7c5f224149f7 [inlined] std::panicking::try::do_call::h55672a70972b9078 at panicking.rs:297 [opt]
    frame #14: 0x000000010727a2ce rust-analyzer`std::rt::lang_start_internal::h2d2d7c5f224149f7 [inlined] std::panicking::try::h6d9221801de1cfe0 at panicking.rs:274 [opt]
    frame #15: 0x000000010727a2ce rust-analyzer`std::rt::lang_start_internal::h2d2d7c5f224149f7 [inlined] std::panic::catch_unwind::h382eeb03b10b2ef0 at panic.rs:394 [opt]
    frame #16: 0x000000010727a2ce rust-analyzer`std::rt::lang_start_internal::h2d2d7c5f224149f7 at rt.rs:51 [opt]
    frame #17: 0x000000010614e0f9 rust-analyzer`main + 41
    frame #18: 0x00007fff7eed33d5 libdyld.dylib`start + 1
(lldb) thread backtrace
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
  * frame #0: 0x00007fff7f00b86a libsystem_kernel.dylib`__psynch_cvwait + 10
    frame #1: 0x00007fff7f0ca56e libsystem_pthread.dylib`_pthread_cond_wait + 722
    frame #2: 0x0000000107269f12 rust-analyzer`std::thread::park::hde008ae05bf6ce2e [inlined] std::sys::unix::condvar::Condvar::wait::haf711209224495da at condvar.rs:73:17 [opt]
    frame #3: 0x0000000107269f0d rust-analyzer`std::thread::park::hde008ae05bf6ce2e [inlined] std::sys_common::condvar::Condvar::wait::hbda63240707accba at condvar.rs:50 [opt]
    frame #4: 0x0000000107269f0d rust-analyzer`std::thread::park::hde008ae05bf6ce2e [inlined] std::sync::condvar::Condvar::wait::h176016a76bad0c38 at condvar.rs:200 [opt]
    frame #5: 0x0000000107269ef3 rust-analyzer`std::thread::park::hde008ae05bf6ce2e at mod.rs:919 [opt]
    frame #6: 0x0000000107260785 rust-analyzer`crossbeam_channel::context::Context::wait_until::h4c4da7e476636502 + 325
    frame #7: 0x0000000107260415 rust-analyzer`crossbeam_channel::context::Context::with::_$u7b$$u7b$closure$u7d$$u7d$::h6657e7b32116da97 + 485
    frame #8: 0x0000000107260998 rust-analyzer`crossbeam_channel::select::run_select::h58f57381a0cf5b86 + 408
    frame #9: 0x00000001062caba8 rust-analyzer`rust_analyzer::main_loop::main_loop::h86d8e7a76e6b731a + 5096
    frame #10: 0x000000010614d881 rust-analyzer`rust_analyzer::main::hb300eef24b10a083 + 5921
    frame #11: 0x0000000106177326 rust-analyzer`std::rt::lang_start::_$u7b$$u7b$closure$u7d$$u7d$::h44458d503897e783 + 6
    frame #12: 0x000000010727a2d9 rust-analyzer`std::rt::lang_start_internal::h2d2d7c5f224149f7 [inlined] std::rt::lang_start_internal::_$u7b$$u7b$closure$u7d$$u7d$::hc4eba503b68bbb2b at rt.rs:52:13 [opt]
    frame #13: 0x000000010727a2ce rust-analyzer`std::rt::lang_start_internal::h2d2d7c5f224149f7 [inlined] std::panicking::try::do_call::h55672a70972b9078 at panicking.rs:297 [opt]
    frame #14: 0x000000010727a2ce rust-analyzer`std::rt::lang_start_internal::h2d2d7c5f224149f7 [inlined] std::panicking::try::h6d9221801de1cfe0 at panicking.rs:274 [opt]
    frame #15: 0x000000010727a2ce rust-analyzer`std::rt::lang_start_internal::h2d2d7c5f224149f7 [inlined] std::panic::catch_unwind::h382eeb03b10b2ef0 at panic.rs:394 [opt]
    frame #16: 0x000000010727a2ce rust-analyzer`std::rt::lang_start_internal::h2d2d7c5f224149f7 at rt.rs:51 [opt]
    frame #17: 0x000000010614e0f9 rust-analyzer`main + 41
    frame #18: 0x00007fff7eed33d5 libdyld.dylib`start + 1
(lldb) threads
error: 'threads' is not a valid command.
(lldb) threads list
error: 'threads' is not a valid command.
(lldb) thread list
Process 18697 stopped
* thread #1: tid = 0x3a7c35, 0x00007fff7f00b86a libsystem_kernel.dylib`__psynch_cvwait + 10, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
  thread #2: tid = 0x3a7c36, 0x00007fff7f00b86a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #3: tid = 0x3a7c37, 0x00007fff7f009ef2 libsystem_kernel.dylib`read + 10
  thread #4: tid = 0x3a7c5a, 0x00007fff7f00b86a libsystem_kernel.dylib`__psynch_cvwait + 10, name = 'vfs'
  thread #5: tid = 0x3a7c5b, 0x00007fff7f00b86a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #6: tid = 0x3a7c5c, 0x00007fff7f00b86a libsystem_kernel.dylib`__psynch_cvwait + 10, name = 'notify-convertor'
  thread #7: tid = 0x3a7c6b, 0x00007fff7f009bfe libsystem_kernel.dylib`__workq_kernreturn + 10
  thread #8: tid = 0x3a7d33, 0x00007fff7f00b86a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #9: tid = 0x3a7d34, 0x00007fff7f00af06 libsystem_kernel.dylib`__psynch_mutexwait + 10
  thread #10: tid = 0x3a7d35, 0x00007fff7f00b86a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #11: tid = 0x3a7d36, 0x00007fff7f00af06 libsystem_kernel.dylib`__psynch_mutexwait + 10
  thread #12: tid = 0x3a7d37, 0x00007fff7f00af06 libsystem_kernel.dylib`__psynch_mutexwait + 10
  thread #13: tid = 0x3a7d38, 0x00007fff7f00af06 libsystem_kernel.dylib`__psynch_mutexwait + 10
  thread #14: tid = 0x3a7d39, 0x00007fff7f00af06 libsystem_kernel.dylib`__psynch_mutexwait + 10
  thread #15: tid = 0x3a7d3a, 0x0000000107255e09 rust-analyzer`rowan::cursor::SyntaxNode::next_sibling_or_token::h7819dbb68e04663a + 25
  thread #16: tid = 0x3a7d3b, 0x00007fff7f00b86a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #17: tid = 0x3a7d3c, 0x00007fff7f00af06 libsystem_kernel.dylib`__psynch_mutexwait + 10
  thread #18: tid = 0x3a7d3d, 0x00007fff7f00af06 libsystem_kernel.dylib`__psynch_mutexwait + 10
  thread #19: tid = 0x3a7d3e, 0x00007fff7f00b86a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #20: tid = 0x3a7d3f, 0x00007fff7f00af06 libsystem_kernel.dylib`__psynch_mutexwait + 10
  thread #21: tid = 0x3a7d40, 0x00007fff7f00af06 libsystem_kernel.dylib`__psynch_mutexwait + 10
  thread #22: tid = 0x3a7d41, 0x00007fff7f00af06 libsystem_kernel.dylib`__psynch_mutexwait + 10
  thread #23: tid = 0x3a7d42, 0x00007fff7f00b86a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #24: tid = 0x3a7d43, 0x00007fff7f00b86a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #25: tid = 0x3a7d44, 0x00007fff7f00b86a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #26: tid = 0x3a7d45, 0x00007fff7f00b86a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #27: tid = 0x3a7d46, 0x00007fff7f00b86a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #28: tid = 0x3a7d47, 0x00007fff7f00b86a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #29: tid = 0x3a7d48, 0x00007fff7f00b86a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #30: tid = 0x3a7d49, 0x00007fff7f00b86a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #31: tid = 0x3a7d4a, 0x00007fff7f00b86a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #32: tid = 0x3a7d4b, 0x00007fff7f00b86a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #33: tid = 0x3a7d4d, 0x00007fff7f00b86a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #34: tid = 0x3a7d4e, 0x00007fff7f00b86a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #35: tid = 0x3a7d4f, 0x00007fff7f00b86a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #36: tid = 0x3a7d50, 0x00007fff7f00b86a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #37: tid = 0x3a7d51, 0x00007fff7f00b86a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #38: tid = 0x3a7d52, 0x00007fff7f00b86a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #39: tid = 0x3a7d53, 0x00007fff7f00b86a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #40: tid = 0x3a7d54, 0x00007fff7f00b86a libsystem_kernel.dylib`__psynch_cvwait + 10
  thread #41: tid = 0x3abb60, 0x00007fff7f00822a libsystem_kernel.dylib`mach_msg_trap + 10
giftal

comment created time in 4 days

Pull request review commentdeltachat/deltachat-core-rust

Fix #880 Don't vary advanced login settings if a user set a particular setting

 async fn try_smtp_one_param(context: &Context, param: &LoginParam, smtp: &mut Sm         bail!("could not connect: {}", err);     } +    if context.shall_stop_ongoing().await {

this check is not needed anymore with the async construction, if this gets triggered we drop the future in the outer configure call, which aborts everything.

Hocuri

comment created time in 4 days

Pull request review commentdeltachat/deltachat-core-rust

refactor(configure): simplify logic and code

 impl Context {             }         } -        if success {-            progress!(self, 1000);-            Ok(())-        } else {-            progress!(self, 0);-            Err(format_err!("Configure failed"))+        match success {+            Ok(_) => {+                progress!(self, 1000);+                Ok(())+            }+            Err(err) => {+                error!(self, "Configure Failed: {}", err);+                progress!(self, 0);+                Err(err)+            }         }     } }  #[allow(clippy::too_many_arguments)]-async fn exec_step(-    ctx: &Context,-    imap: &mut Imap,-    param: &mut LoginParam,-    param_domain: &mut String,-    param_autoconfig: &mut Option<LoginParam>,-    param_addr_urlencoded: &mut String,-    keep_flags: &mut i32,-    step_counter: &mut u8,-) -> Result<Step> {-    const STEP_12_USE_AUTOCONFIG: u8 = 12;-    const STEP_13_AFTER_AUTOCONFIG: u8 = 13;--    match *step_counter {-        // Read login parameters from the database-        1 => {-            progress!(ctx, 1);-            ensure!(!param.addr.is_empty(), "Please enter an email address.");-        }-        // Step 1: Load the parameters and check email-address and password-        2 => {-            if 0 != param.server_flags & DC_LP_AUTH_OAUTH2 {-                // the used oauth2 addr may differ, check this.-                // if dc_get_oauth2_addr() is not available in the oauth2 implementation,-                // just use the given one.-                progress!(ctx, 10);-                if let Some(oauth2_addr) = dc_get_oauth2_addr(ctx, &param.addr, &param.mail_pw)-                    .await-                    .and_then(|e| e.parse().ok())-                {-                    info!(ctx, "Authorized address is {}", oauth2_addr);-                    param.addr = oauth2_addr;-                    ctx.sql-                        .set_raw_config(ctx, "addr", Some(param.addr.as_str()))-                        .await?;-                }-                progress!(ctx, 20);-            }-            // no oauth? - just continue it's no error-        }-        3 => {-            if let Ok(parsed) = param.addr.parse() {-                let parsed: EmailAddress = parsed;-                *param_domain = parsed.domain;-                *param_addr_urlencoded =-                    utf8_percent_encode(&param.addr, NON_ALPHANUMERIC).to_string();-            } else {-                bail!("Bad email-address.");-            }-        }-        // Step 2: Autoconfig-        4 => {-            progress!(ctx, 200);--            if param.mail_server.is_empty()-                && param.mail_port == 0-            /* && param.mail_user.is_empty() -- the user can enter a loginname which is used by autoconfig then */-                && param.send_server.is_empty()-                && param.send_port == 0-                && param.send_user.is_empty()-            /* && param.send_pw.is_empty() -- the password cannot be auto-configured and is no criterion for autoconfig or not */-                && (param.server_flags & !DC_LP_AUTH_OAUTH2) == 0-            {-                // no advanced parameters entered by the user: query provider-database or do Autoconfig-                *keep_flags = param.server_flags & DC_LP_AUTH_OAUTH2;-                if let Some(new_param) = get_offline_autoconfig(ctx, &param) {-                    // got parameters from our provider-database, skip Autoconfig, preserve the OAuth2 setting-                    *param_autoconfig = Some(new_param);-                    *step_counter = STEP_12_USE_AUTOCONFIG - 1; // minus one as step_counter is increased on next loop-                }-            } else {-                // advanced parameters entered by the user: skip Autoconfig-                *step_counter = STEP_13_AFTER_AUTOCONFIG - 1; // minus one as step_counter is increased on next loop-            }-        }-        /* A.  Search configurations from the domain used in the email-address, prefer encrypted */-        5 => {-            if param_autoconfig.is_none() {-                let url = format!(-                    "https://autoconfig.{}/mail/config-v1.1.xml?emailaddress={}",-                    param_domain, param_addr_urlencoded-                );-                *param_autoconfig = moz_autoconfigure(ctx, &url, &param).await.ok();-            }-        }-        6 => {-            progress!(ctx, 300);-            if param_autoconfig.is_none() {-                // the doc does not mention `emailaddress=`, however, Thunderbird adds it, see https://releases.mozilla.org/pub/thunderbird/ ,  which makes some sense-                let url = format!(-                    "https://{}/.well-known/autoconfig/mail/config-v1.1.xml?emailaddress={}",-                    param_domain, param_addr_urlencoded-                );-                *param_autoconfig = moz_autoconfigure(ctx, &url, &param).await.ok();-            }-        }-        /* Outlook section start ------------- */-        /* Outlook uses always SSL but different domains (this comment describes the next two steps) */-        7 => {-            progress!(ctx, 310);-            if param_autoconfig.is_none() {-                let url = format!("https://{}/autodiscover/autodiscover.xml", param_domain);-                *param_autoconfig = outlk_autodiscover(ctx, &url, &param).await.ok();-            }-        }-        8 => {-            progress!(ctx, 320);-            if param_autoconfig.is_none() {-                let url = format!(-                    "https://{}{}/autodiscover/autodiscover.xml",-                    "autodiscover.", param_domain-                );-                *param_autoconfig = outlk_autodiscover(ctx, &url, &param).await.ok();-            }+async fn configure(ctx: &Context, imap: &mut Imap, param: &mut LoginParam) -> Result<()> {+    let mut param_autoconfig: Option<LoginParam> = None;+    let mut keep_flags = 0;+    let mut use_autoconfig = true;++    // Read login parameters from the database+    progress!(ctx, 1);+    ensure!(!param.addr.is_empty(), "Please enter an email address.");++    // Step 1: Load the parameters and check email-address and password++    if 0 != param.server_flags & DC_LP_AUTH_OAUTH2 {+        // the used oauth2 addr may differ, check this.+        // if dc_get_oauth2_addr() is not available in the oauth2 implementation,+        // just use the given one.+        progress!(ctx, 10);+        if let Some(oauth2_addr) = dc_get_oauth2_addr(ctx, &param.addr, &param.mail_pw)+            .await+            .and_then(|e| e.parse().ok())+        {+            info!(ctx, "Authorized address is {}", oauth2_addr);+            param.addr = oauth2_addr;+            ctx.sql+                .set_raw_config(ctx, "addr", Some(param.addr.as_str()))+                .await?;         }-        /* ----------- Outlook section end */-        9 => {-            progress!(ctx, 330);-            if param_autoconfig.is_none() {-                let url = format!(-                    "http://autoconfig.{}/mail/config-v1.1.xml?emailaddress={}",-                    param_domain, param_addr_urlencoded-                );-                *param_autoconfig = moz_autoconfigure(ctx, &url, &param).await.ok();-            }+        progress!(ctx, 20);+    }+    // no oauth? - just continue it's no error++    let parsed: EmailAddress = param.addr.parse().context("Bad email-address")?;+    let param_domain = parsed.domain;+    let param_addr_urlencoded = utf8_percent_encode(&param.addr, NON_ALPHANUMERIC).to_string();++    // Step 2: Autoconfig+    progress!(ctx, 200);++    // param.mail_user.is_empty() -- the user can enter a loginname which is used by autoconfig then+    // param.send_pw.is_empty() -- the password cannot be auto-configured and is no criterion for autoconfig or not+    if param.mail_server.is_empty()+        && param.mail_port == 0+        && param.send_server.is_empty()+        && param.send_port == 0+        && param.send_user.is_empty()+        && (param.server_flags & !DC_LP_AUTH_OAUTH2) == 0+    {+        // no advanced parameters entered by the user: query provider-database or do Autoconfig+        keep_flags = param.server_flags & DC_LP_AUTH_OAUTH2;+        if let Some(new_param) = get_offline_autoconfig(ctx, &param) {+            // got parameters from our provider-database, skip Autoconfig, preserve the OAuth2 setting+            param_autoconfig = Some(new_param);         }-        10 => {-            progress!(ctx, 340);-            if param_autoconfig.is_none() {-                // do not transfer the email-address unencrypted-                let url = format!(-                    "http://{}/.well-known/autoconfig/mail/config-v1.1.xml",-                    param_domain-                );-                *param_autoconfig = moz_autoconfigure(ctx, &url, &param).await.ok();+    } else {+        // advanced parameters entered by the user: skip Autoconfig+        use_autoconfig = false;+    }++    if param_autoconfig.is_none() {+        param_autoconfig = get_autoconfig(ctx, param, &param_domain, &param_addr_urlencoded).await;+    }++    // C.  Do we have any autoconfig result?+    progress!(ctx, 500);+    if use_autoconfig {+        if let Some(ref cfg) = param_autoconfig {+            info!(ctx, "Got autoconfig: {}", &cfg);+            if !cfg.mail_user.is_empty() {+                param.mail_user = cfg.mail_user.clone();             }+            // all other values are always NULL when entering autoconfig+            param.mail_server = cfg.mail_server.clone();+            param.mail_port = cfg.mail_port;+            param.send_server = cfg.send_server.clone();+            param.send_port = cfg.send_port;+            param.send_user = cfg.send_user.clone();+            param.server_flags = cfg.server_flags;+            // although param_autoconfig's data are no longer needed from,+            // it is used to later to prevent trying variations of port/server/logins         }-        /* B.  If we have no configuration yet, search configuration in Thunderbird's centeral database */-        11 => {-            progress!(ctx, 350);-            if param_autoconfig.is_none() {-                /* always SSL for Thunderbird's database */-                let url = format!("https://autoconfig.thunderbird.net/v1.1/{}", param_domain);-                *param_autoconfig = moz_autoconfigure(ctx, &url, &param).await.ok();-            }+        param.server_flags |= keep_flags;+    }++    // Step 3: Fill missing fields with defaults+    if param.mail_server.is_empty() {+        param.mail_server = format!("imap.{}", param_domain,)+    }+    if param.mail_port == 0 {+        param.mail_port = if 0 != param.server_flags & (0x100 | 0x400) {+            143+        } else {+            993         }-        /* C.  Do we have any autoconfig result?-           If you change the match-number here, also update STEP_12_COPY_AUTOCONFIG above-        */-        STEP_12_USE_AUTOCONFIG => {-            progress!(ctx, 500);-            if let Some(ref cfg) = param_autoconfig {-                info!(ctx, "Got autoconfig: {}", &cfg);-                if !cfg.mail_user.is_empty() {-                    param.mail_user = cfg.mail_user.clone();-                }-                param.mail_server = cfg.mail_server.clone(); /* all other values are always NULL when entering autoconfig */-                param.mail_port = cfg.mail_port;-                param.send_server = cfg.send_server.clone();-                param.send_port = cfg.send_port;-                param.send_user = cfg.send_user.clone();-                param.server_flags = cfg.server_flags;-                /* although param_autoconfig's data are no longer needed from,-                it is used to later to prevent trying variations of port/server/logins */-            }-            param.server_flags |= *keep_flags;+    }+    if param.mail_user.is_empty() {+        param.mail_user = param.addr.clone();+    }+    if param.send_server.is_empty() && !param.mail_server.is_empty() {+        param.send_server = param.mail_server.clone();+        if param.send_server.starts_with("imap.") {+            param.send_server = param.send_server.replacen("imap", "smtp", 1);         }-        // Step 3: Fill missing fields with defaults-        // If you change the match-number here, also update STEP_13_AFTER_AUTOCONFIG above-        STEP_13_AFTER_AUTOCONFIG => {-            if param.mail_server.is_empty() {-                param.mail_server = format!("imap.{}", param_domain,)-            }-            if param.mail_port == 0 {-                param.mail_port = if 0 != param.server_flags & (0x100 | 0x400) {-                    143-                } else {-                    993-                }-            }-            if param.mail_user.is_empty() {-                param.mail_user = param.addr.clone();-            }-            if param.send_server.is_empty() && !param.mail_server.is_empty() {-                param.send_server = param.mail_server.clone();-                if param.send_server.starts_with("imap.") {-                    param.send_server = param.send_server.replacen("imap", "smtp", 1);-                }-            }-            if param.send_port == 0 {-                param.send_port = if 0 != param.server_flags & DC_LP_SMTP_SOCKET_STARTTLS as i32 {-                    587-                } else if 0 != param.server_flags & DC_LP_SMTP_SOCKET_PLAIN as i32 {-                    25-                } else {-                    465-                }-            }-            if param.send_user.is_empty() && !param.mail_user.is_empty() {-                param.send_user = param.mail_user.clone();-            }-            if param.send_pw.is_empty() && !param.mail_pw.is_empty() {-                param.send_pw = param.mail_pw.clone()-            }-            if !dc_exactly_one_bit_set(param.server_flags & DC_LP_AUTH_FLAGS as i32) {-                param.server_flags &= !(DC_LP_AUTH_FLAGS as i32);-                param.server_flags |= DC_LP_AUTH_NORMAL as i32-            }-            if !dc_exactly_one_bit_set(param.server_flags & DC_LP_IMAP_SOCKET_FLAGS as i32) {-                param.server_flags &= !(DC_LP_IMAP_SOCKET_FLAGS as i32);-                param.server_flags |= if param.send_port == 143 {-                    DC_LP_IMAP_SOCKET_STARTTLS as i32-                } else {-                    DC_LP_IMAP_SOCKET_SSL as i32-                }-            }-            if !dc_exactly_one_bit_set(param.server_flags & (DC_LP_SMTP_SOCKET_FLAGS as i32)) {-                param.server_flags &= !(DC_LP_SMTP_SOCKET_FLAGS as i32);-                param.server_flags |= if param.send_port == 587 {-                    DC_LP_SMTP_SOCKET_STARTTLS as i32-                } else if param.send_port == 25 {-                    DC_LP_SMTP_SOCKET_PLAIN as i32-                } else {-                    DC_LP_SMTP_SOCKET_SSL as i32-                }-            }-            /* do we have a complete configuration? */-            if param.mail_server.is_empty()-                || param.mail_port == 0-                || param.mail_user.is_empty()-                || param.mail_pw.is_empty()-                || param.send_server.is_empty()-                || param.send_port == 0-                || param.send_user.is_empty()-                || param.send_pw.is_empty()-                || param.server_flags == 0-            {-                bail!("Account settings incomplete.");-            }+    }+    if param.send_port == 0 {+        param.send_port = if 0 != param.server_flags & DC_LP_SMTP_SOCKET_STARTTLS as i32 {+            587+        } else if 0 != param.server_flags & DC_LP_SMTP_SOCKET_PLAIN as i32 {+            25+        } else {+            465         }-        14 => {-            progress!(ctx, 600);-            /* try to connect to IMAP - if we did not got an autoconfig,-            do some further tries with different settings and username variations */-            try_imap_connections(ctx, param, param_autoconfig.is_some(), imap).await?;+    }+    if param.send_user.is_empty() && !param.mail_user.is_empty() {+        param.send_user = param.mail_user.clone();+    }+    if param.send_pw.is_empty() && !param.mail_pw.is_empty() {+        param.send_pw = param.mail_pw.clone()+    }+    if !dc_exactly_one_bit_set(param.server_flags & DC_LP_AUTH_FLAGS as i32) {+        param.server_flags &= !(DC_LP_AUTH_FLAGS as i32);+        param.server_flags |= DC_LP_AUTH_NORMAL as i32+    }+    if !dc_exactly_one_bit_set(param.server_flags & DC_LP_IMAP_SOCKET_FLAGS as i32) {+        param.server_flags &= !(DC_LP_IMAP_SOCKET_FLAGS as i32);+        param.server_flags |= if param.send_port == 143 {+            DC_LP_IMAP_SOCKET_STARTTLS as i32+        } else {+            DC_LP_IMAP_SOCKET_SSL as i32         }-        15 => {-            progress!(ctx, 800);-            try_smtp_connections(ctx, param, param_autoconfig.is_some()).await?;+    }+    if !dc_exactly_one_bit_set(param.server_flags & (DC_LP_SMTP_SOCKET_FLAGS as i32)) {+        param.server_flags &= !(DC_LP_SMTP_SOCKET_FLAGS as i32);+        param.server_flags |= if param.send_port == 587 {+            DC_LP_SMTP_SOCKET_STARTTLS as i32+        } else if param.send_port == 25 {+            DC_LP_SMTP_SOCKET_PLAIN as i32+        } else {+            DC_LP_SMTP_SOCKET_SSL as i32         }-        16 => {-            progress!(ctx, 900);+    } -            let create_mvbox = ctx.get_config_bool(Config::MvboxWatch).await-                || ctx.get_config_bool(Config::MvboxMove).await;+    // do we have a complete configuration?+    if param.mail_server.is_empty()+        || param.mail_port == 0+        || param.mail_user.is_empty()+        || param.mail_pw.is_empty()+        || param.send_server.is_empty()+        || param.send_port == 0+        || param.send_user.is_empty()+        || param.send_pw.is_empty()+        || param.server_flags == 0+    {+        bail!("Account settings incomplete.");+    } -            if let Err(err) = imap.configure_folders(ctx, create_mvbox).await {-                bail!("configuring folders failed: {:?}", err);-            }+    progress!(ctx, 600);+    // try to connect to IMAP - if we did not got an autoconfig,+    // do some further tries with different settings and username variations+    try_imap_connections(ctx, param, param_autoconfig.is_some(), imap).await?; -            if let Err(err) = imap.select_with_uidvalidity(ctx, "INBOX").await {-                bail!("could not read INBOX status: {:?}", err);-            }-        }-        17 => {-            progress!(ctx, 910);-            // configuration success - write back the configured parameters with the-            // "configured_" prefix; also write the "configured"-flag */-            // the trailing underscore is correct-            param.save_to_database(ctx, "configured_").await?;-            ctx.sql.set_raw_config_bool(ctx, "configured", true).await?;-        }-        18 => {-            progress!(ctx, 920);-            // we generate the keypair just now - we could also postpone this until the first message is sent, however,-            // this may result in a unexpected and annoying delay when the user sends his very first message-            // (~30 seconds on a Moto G4 play) and might looks as if message sending is always that slow.-            e2ee::ensure_secret_key_exists(ctx).await?;-            info!(ctx, "key generation completed");-            progress!(ctx, 940);-            return Ok(Step::Done);-        }-        _ => {-            bail!("Internal error: step counter out of bound");-        }+    progress!(ctx, 800);+    try_smtp_connections(ctx, param, param_autoconfig.is_some()).await?;++    progress!(ctx, 900);++    let create_mvbox = ctx.get_config_bool(Config::MvboxWatch).await+        || ctx.get_config_bool(Config::MvboxMove).await;++    if let Err(err) = imap.configure_folders(ctx, create_mvbox).await {+        bail!("configuring folders failed: {:?}", err);     } -    Ok(Step::Continue)+    if let Err(err) = imap.select_with_uidvalidity(ctx, "INBOX").await {+        bail!("could not read INBOX status: {:?}", err);+    }++    progress!(ctx, 910);+    // configuration success - write back the configured parameters with the+    // "configured_" prefix; also write the "configured"-flag */+    // the trailing underscore is correct+    param.save_to_database(ctx, "configured_").await?;+    ctx.sql.set_raw_config_bool(ctx, "configured", true).await?;++    progress!(ctx, 920);+    // we generate the keypair just now - we could also postpone this until the first message is sent, however,+    // this may result in a unexpected and annoying delay when the user sends his very first message+    // (~30 seconds on a Moto G4 play) and might looks as if message sending is always that slow.

Key is not generated in parallel, we block here, waiting for the key to be generated. We could opportunistically start the key gen at the start of configure, and wait here for it to finish if we want to.

dignifiedquire

comment created time in 4 days

Pull request review commentdeltachat/deltachat-core-rust

refactor(configure): simplify logic and code

 impl Context {             }         } -        if success {-            progress!(self, 1000);-            Ok(())-        } else {-            progress!(self, 0);-            Err(format_err!("Configure failed"))+        match success {+            Ok(_) => {+                progress!(self, 1000);+                Ok(())+            }+            Err(err) => {+                error!(self, "Configure Failed: {}", err);+                progress!(self, 0);+                Err(err)+            }         }     } }  #[allow(clippy::too_many_arguments)]-async fn exec_step(-    ctx: &Context,-    imap: &mut Imap,-    param: &mut LoginParam,-    param_domain: &mut String,-    param_autoconfig: &mut Option<LoginParam>,-    param_addr_urlencoded: &mut String,-    keep_flags: &mut i32,-    step_counter: &mut u8,-) -> Result<Step> {-    const STEP_12_USE_AUTOCONFIG: u8 = 12;-    const STEP_13_AFTER_AUTOCONFIG: u8 = 13;--    match *step_counter {-        // Read login parameters from the database-        1 => {-            progress!(ctx, 1);-            ensure!(!param.addr.is_empty(), "Please enter an email address.");-        }-        // Step 1: Load the parameters and check email-address and password-        2 => {-            if 0 != param.server_flags & DC_LP_AUTH_OAUTH2 {-                // the used oauth2 addr may differ, check this.-                // if dc_get_oauth2_addr() is not available in the oauth2 implementation,-                // just use the given one.-                progress!(ctx, 10);-                if let Some(oauth2_addr) = dc_get_oauth2_addr(ctx, &param.addr, &param.mail_pw)-                    .await-                    .and_then(|e| e.parse().ok())-                {-                    info!(ctx, "Authorized address is {}", oauth2_addr);-                    param.addr = oauth2_addr;-                    ctx.sql-                        .set_raw_config(ctx, "addr", Some(param.addr.as_str()))-                        .await?;-                }-                progress!(ctx, 20);-            }-            // no oauth? - just continue it's no error-        }-        3 => {-            if let Ok(parsed) = param.addr.parse() {-                let parsed: EmailAddress = parsed;-                *param_domain = parsed.domain;-                *param_addr_urlencoded =-                    utf8_percent_encode(&param.addr, NON_ALPHANUMERIC).to_string();-            } else {-                bail!("Bad email-address.");-            }-        }-        // Step 2: Autoconfig-        4 => {-            progress!(ctx, 200);--            if param.mail_server.is_empty()-                && param.mail_port == 0-            /* && param.mail_user.is_empty() -- the user can enter a loginname which is used by autoconfig then */-                && param.send_server.is_empty()-                && param.send_port == 0-                && param.send_user.is_empty()-            /* && param.send_pw.is_empty() -- the password cannot be auto-configured and is no criterion for autoconfig or not */-                && (param.server_flags & !DC_LP_AUTH_OAUTH2) == 0-            {-                // no advanced parameters entered by the user: query provider-database or do Autoconfig-                *keep_flags = param.server_flags & DC_LP_AUTH_OAUTH2;-                if let Some(new_param) = get_offline_autoconfig(ctx, &param) {-                    // got parameters from our provider-database, skip Autoconfig, preserve the OAuth2 setting-                    *param_autoconfig = Some(new_param);-                    *step_counter = STEP_12_USE_AUTOCONFIG - 1; // minus one as step_counter is increased on next loop-                }-            } else {-                // advanced parameters entered by the user: skip Autoconfig-                *step_counter = STEP_13_AFTER_AUTOCONFIG - 1; // minus one as step_counter is increased on next loop-            }-        }-        /* A.  Search configurations from the domain used in the email-address, prefer encrypted */-        5 => {-            if param_autoconfig.is_none() {-                let url = format!(-                    "https://autoconfig.{}/mail/config-v1.1.xml?emailaddress={}",-                    param_domain, param_addr_urlencoded-                );-                *param_autoconfig = moz_autoconfigure(ctx, &url, &param).await.ok();-            }-        }-        6 => {-            progress!(ctx, 300);-            if param_autoconfig.is_none() {-                // the doc does not mention `emailaddress=`, however, Thunderbird adds it, see https://releases.mozilla.org/pub/thunderbird/ ,  which makes some sense-                let url = format!(-                    "https://{}/.well-known/autoconfig/mail/config-v1.1.xml?emailaddress={}",-                    param_domain, param_addr_urlencoded-                );-                *param_autoconfig = moz_autoconfigure(ctx, &url, &param).await.ok();-            }-        }-        /* Outlook section start ------------- */-        /* Outlook uses always SSL but different domains (this comment describes the next two steps) */-        7 => {-            progress!(ctx, 310);-            if param_autoconfig.is_none() {-                let url = format!("https://{}/autodiscover/autodiscover.xml", param_domain);-                *param_autoconfig = outlk_autodiscover(ctx, &url, &param).await.ok();-            }-        }-        8 => {-            progress!(ctx, 320);-            if param_autoconfig.is_none() {-                let url = format!(-                    "https://{}{}/autodiscover/autodiscover.xml",-                    "autodiscover.", param_domain-                );-                *param_autoconfig = outlk_autodiscover(ctx, &url, &param).await.ok();-            }+async fn configure(ctx: &Context, imap: &mut Imap, param: &mut LoginParam) -> Result<()> {+    let mut param_autoconfig: Option<LoginParam> = None;+    let mut keep_flags = 0;+    let mut use_autoconfig = true;++    // Read login parameters from the database+    progress!(ctx, 1);+    ensure!(!param.addr.is_empty(), "Please enter an email address.");++    // Step 1: Load the parameters and check email-address and password++    if 0 != param.server_flags & DC_LP_AUTH_OAUTH2 {+        // the used oauth2 addr may differ, check this.+        // if dc_get_oauth2_addr() is not available in the oauth2 implementation,+        // just use the given one.+        progress!(ctx, 10);+        if let Some(oauth2_addr) = dc_get_oauth2_addr(ctx, &param.addr, &param.mail_pw)+            .await+            .and_then(|e| e.parse().ok())+        {+            info!(ctx, "Authorized address is {}", oauth2_addr);+            param.addr = oauth2_addr;+            ctx.sql+                .set_raw_config(ctx, "addr", Some(param.addr.as_str()))+                .await?;         }-        /* ----------- Outlook section end */-        9 => {-            progress!(ctx, 330);-            if param_autoconfig.is_none() {-                let url = format!(-                    "http://autoconfig.{}/mail/config-v1.1.xml?emailaddress={}",-                    param_domain, param_addr_urlencoded-                );-                *param_autoconfig = moz_autoconfigure(ctx, &url, &param).await.ok();-            }+        progress!(ctx, 20);+    }+    // no oauth? - just continue it's no error++    let parsed: EmailAddress = param.addr.parse().context("Bad email-address")?;+    let param_domain = parsed.domain;+    let param_addr_urlencoded = utf8_percent_encode(&param.addr, NON_ALPHANUMERIC).to_string();++    // Step 2: Autoconfig+    progress!(ctx, 200);++    // param.mail_user.is_empty() -- the user can enter a loginname which is used by autoconfig then+    // param.send_pw.is_empty() -- the password cannot be auto-configured and is no criterion for autoconfig or not+    if param.mail_server.is_empty()+        && param.mail_port == 0+        && param.send_server.is_empty()+        && param.send_port == 0+        && param.send_user.is_empty()+        && (param.server_flags & !DC_LP_AUTH_OAUTH2) == 0+    {+        // no advanced parameters entered by the user: query provider-database or do Autoconfig+        keep_flags = param.server_flags & DC_LP_AUTH_OAUTH2;+        if let Some(new_param) = get_offline_autoconfig(ctx, &param) {+            // got parameters from our provider-database, skip Autoconfig, preserve the OAuth2 setting+            param_autoconfig = Some(new_param);         }-        10 => {-            progress!(ctx, 340);-            if param_autoconfig.is_none() {-                // do not transfer the email-address unencrypted-                let url = format!(-                    "http://{}/.well-known/autoconfig/mail/config-v1.1.xml",-                    param_domain-                );-                *param_autoconfig = moz_autoconfigure(ctx, &url, &param).await.ok();+    } else {+        // advanced parameters entered by the user: skip Autoconfig+        use_autoconfig = false;+    }++    if param_autoconfig.is_none() {+        param_autoconfig = get_autoconfig(ctx, param, &param_domain, &param_addr_urlencoded).await;+    }++    // C.  Do we have any autoconfig result?+    progress!(ctx, 500);+    if use_autoconfig {+        if let Some(ref cfg) = param_autoconfig {+            info!(ctx, "Got autoconfig: {}", &cfg);+            if !cfg.mail_user.is_empty() {+                param.mail_user = cfg.mail_user.clone();             }+            // all other values are always NULL when entering autoconfig+            param.mail_server = cfg.mail_server.clone();+            param.mail_port = cfg.mail_port;+            param.send_server = cfg.send_server.clone();+            param.send_port = cfg.send_port;+            param.send_user = cfg.send_user.clone();+            param.server_flags = cfg.server_flags;+            // although param_autoconfig's data are no longer needed from,+            // it is used to later to prevent trying variations of port/server/logins         }-        /* B.  If we have no configuration yet, search configuration in Thunderbird's centeral database */-        11 => {-            progress!(ctx, 350);-            if param_autoconfig.is_none() {-                /* always SSL for Thunderbird's database */-                let url = format!("https://autoconfig.thunderbird.net/v1.1/{}", param_domain);-                *param_autoconfig = moz_autoconfigure(ctx, &url, &param).await.ok();-            }+        param.server_flags |= keep_flags;+    }++    // Step 3: Fill missing fields with defaults+    if param.mail_server.is_empty() {+        param.mail_server = format!("imap.{}", param_domain,)+    }+    if param.mail_port == 0 {+        param.mail_port = if 0 != param.server_flags & (0x100 | 0x400) {+            143+        } else {+            993         }-        /* C.  Do we have any autoconfig result?-           If you change the match-number here, also update STEP_12_COPY_AUTOCONFIG above-        */-        STEP_12_USE_AUTOCONFIG => {-            progress!(ctx, 500);-            if let Some(ref cfg) = param_autoconfig {-                info!(ctx, "Got autoconfig: {}", &cfg);-                if !cfg.mail_user.is_empty() {-                    param.mail_user = cfg.mail_user.clone();-                }-                param.mail_server = cfg.mail_server.clone(); /* all other values are always NULL when entering autoconfig */-                param.mail_port = cfg.mail_port;-                param.send_server = cfg.send_server.clone();-                param.send_port = cfg.send_port;-                param.send_user = cfg.send_user.clone();-                param.server_flags = cfg.server_flags;-                /* although param_autoconfig's data are no longer needed from,-                it is used to later to prevent trying variations of port/server/logins */-            }-            param.server_flags |= *keep_flags;+    }+    if param.mail_user.is_empty() {+        param.mail_user = param.addr.clone();+    }+    if param.send_server.is_empty() && !param.mail_server.is_empty() {+        param.send_server = param.mail_server.clone();+        if param.send_server.starts_with("imap.") {+            param.send_server = param.send_server.replacen("imap", "smtp", 1);         }-        // Step 3: Fill missing fields with defaults-        // If you change the match-number here, also update STEP_13_AFTER_AUTOCONFIG above-        STEP_13_AFTER_AUTOCONFIG => {-            if param.mail_server.is_empty() {-                param.mail_server = format!("imap.{}", param_domain,)-            }-            if param.mail_port == 0 {-                param.mail_port = if 0 != param.server_flags & (0x100 | 0x400) {-                    143-                } else {-                    993-                }-            }-            if param.mail_user.is_empty() {-                param.mail_user = param.addr.clone();-            }-            if param.send_server.is_empty() && !param.mail_server.is_empty() {-                param.send_server = param.mail_server.clone();-                if param.send_server.starts_with("imap.") {-                    param.send_server = param.send_server.replacen("imap", "smtp", 1);-                }-            }-            if param.send_port == 0 {-                param.send_port = if 0 != param.server_flags & DC_LP_SMTP_SOCKET_STARTTLS as i32 {-                    587-                } else if 0 != param.server_flags & DC_LP_SMTP_SOCKET_PLAIN as i32 {-                    25-                } else {-                    465-                }-            }-            if param.send_user.is_empty() && !param.mail_user.is_empty() {-                param.send_user = param.mail_user.clone();-            }-            if param.send_pw.is_empty() && !param.mail_pw.is_empty() {-                param.send_pw = param.mail_pw.clone()-            }-            if !dc_exactly_one_bit_set(param.server_flags & DC_LP_AUTH_FLAGS as i32) {-                param.server_flags &= !(DC_LP_AUTH_FLAGS as i32);-                param.server_flags |= DC_LP_AUTH_NORMAL as i32-            }-            if !dc_exactly_one_bit_set(param.server_flags & DC_LP_IMAP_SOCKET_FLAGS as i32) {-                param.server_flags &= !(DC_LP_IMAP_SOCKET_FLAGS as i32);-                param.server_flags |= if param.send_port == 143 {-                    DC_LP_IMAP_SOCKET_STARTTLS as i32-                } else {-                    DC_LP_IMAP_SOCKET_SSL as i32-                }-            }-            if !dc_exactly_one_bit_set(param.server_flags & (DC_LP_SMTP_SOCKET_FLAGS as i32)) {-                param.server_flags &= !(DC_LP_SMTP_SOCKET_FLAGS as i32);-                param.server_flags |= if param.send_port == 587 {-                    DC_LP_SMTP_SOCKET_STARTTLS as i32-                } else if param.send_port == 25 {-                    DC_LP_SMTP_SOCKET_PLAIN as i32-                } else {-                    DC_LP_SMTP_SOCKET_SSL as i32-                }-            }-            /* do we have a complete configuration? */-            if param.mail_server.is_empty()-                || param.mail_port == 0-                || param.mail_user.is_empty()-                || param.mail_pw.is_empty()-                || param.send_server.is_empty()-                || param.send_port == 0-                || param.send_user.is_empty()-                || param.send_pw.is_empty()-                || param.server_flags == 0-            {-                bail!("Account settings incomplete.");-            }+    }+    if param.send_port == 0 {+        param.send_port = if 0 != param.server_flags & DC_LP_SMTP_SOCKET_STARTTLS as i32 {+            587+        } else if 0 != param.server_flags & DC_LP_SMTP_SOCKET_PLAIN as i32 {+            25+        } else {+            465         }-        14 => {-            progress!(ctx, 600);-            /* try to connect to IMAP - if we did not got an autoconfig,-            do some further tries with different settings and username variations */-            try_imap_connections(ctx, param, param_autoconfig.is_some(), imap).await?;+    }+    if param.send_user.is_empty() && !param.mail_user.is_empty() {+        param.send_user = param.mail_user.clone();+    }+    if param.send_pw.is_empty() && !param.mail_pw.is_empty() {+        param.send_pw = param.mail_pw.clone()+    }+    if !dc_exactly_one_bit_set(param.server_flags & DC_LP_AUTH_FLAGS as i32) {+        param.server_flags &= !(DC_LP_AUTH_FLAGS as i32);+        param.server_flags |= DC_LP_AUTH_NORMAL as i32+    }+    if !dc_exactly_one_bit_set(param.server_flags & DC_LP_IMAP_SOCKET_FLAGS as i32) {+        param.server_flags &= !(DC_LP_IMAP_SOCKET_FLAGS as i32);+        param.server_flags |= if param.send_port == 143 {+            DC_LP_IMAP_SOCKET_STARTTLS as i32+        } else {+            DC_LP_IMAP_SOCKET_SSL as i32         }-        15 => {-            progress!(ctx, 800);-            try_smtp_connections(ctx, param, param_autoconfig.is_some()).await?;+    }+    if !dc_exactly_one_bit_set(param.server_flags & (DC_LP_SMTP_SOCKET_FLAGS as i32)) {+        param.server_flags &= !(DC_LP_SMTP_SOCKET_FLAGS as i32);+        param.server_flags |= if param.send_port == 587 {+            DC_LP_SMTP_SOCKET_STARTTLS as i32+        } else if param.send_port == 25 {+            DC_LP_SMTP_SOCKET_PLAIN as i32+        } else {+            DC_LP_SMTP_SOCKET_SSL as i32         }-        16 => {-            progress!(ctx, 900);+    } -            let create_mvbox = ctx.get_config_bool(Config::MvboxWatch).await-                || ctx.get_config_bool(Config::MvboxMove).await;+    // do we have a complete configuration?+    if param.mail_server.is_empty()+        || param.mail_port == 0+        || param.mail_user.is_empty()+        || param.mail_pw.is_empty()+        || param.send_server.is_empty()+        || param.send_port == 0+        || param.send_user.is_empty()+        || param.send_pw.is_empty()+        || param.server_flags == 0+    {+        bail!("Account settings incomplete.");+    } -            if let Err(err) = imap.configure_folders(ctx, create_mvbox).await {-                bail!("configuring folders failed: {:?}", err);-            }+    progress!(ctx, 600);+    // try to connect to IMAP - if we did not got an autoconfig,+    // do some further tries with different settings and username variations+    try_imap_connections(ctx, param, param_autoconfig.is_some(), imap).await?; -            if let Err(err) = imap.select_with_uidvalidity(ctx, "INBOX").await {-                bail!("could not read INBOX status: {:?}", err);-            }-        }-        17 => {-            progress!(ctx, 910);-            // configuration success - write back the configured parameters with the-            // "configured_" prefix; also write the "configured"-flag */-            // the trailing underscore is correct-            param.save_to_database(ctx, "configured_").await?;-            ctx.sql.set_raw_config_bool(ctx, "configured", true).await?;-        }-        18 => {-            progress!(ctx, 920);-            // we generate the keypair just now - we could also postpone this until the first message is sent, however,-            // this may result in a unexpected and annoying delay when the user sends his very first message-            // (~30 seconds on a Moto G4 play) and might looks as if message sending is always that slow.-            e2ee::ensure_secret_key_exists(ctx).await?;-            info!(ctx, "key generation completed");-            progress!(ctx, 940);-            return Ok(Step::Done);-        }-        _ => {-            bail!("Internal error: step counter out of bound");-        }+    progress!(ctx, 800);+    try_smtp_connections(ctx, param, param_autoconfig.is_some()).await?;++    progress!(ctx, 900);++    let create_mvbox = ctx.get_config_bool(Config::MvboxWatch).await+        || ctx.get_config_bool(Config::MvboxMove).await;++    if let Err(err) = imap.configure_folders(ctx, create_mvbox).await {+        bail!("configuring folders failed: {:?}", err);     } -    Ok(Step::Continue)+    if let Err(err) = imap.select_with_uidvalidity(ctx, "INBOX").await {+        bail!("could not read INBOX status: {:?}", err);+    }++    progress!(ctx, 910);+    // configuration success - write back the configured parameters with the+    // "configured_" prefix; also write the "configured"-flag */+    // the trailing underscore is correct+    param.save_to_database(ctx, "configured_").await?;+    ctx.sql.set_raw_config_bool(ctx, "configured", true).await?;++    progress!(ctx, 920);+    // we generate the keypair just now - we could also postpone this until the first message is sent, however,+    // this may result in a unexpected and annoying delay when the user sends his very first message+    // (~30 seconds on a Moto G4 play) and might looks as if message sending is always that slow.+    e2ee::ensure_secret_key_exists(ctx).await?;+    info!(ctx, "key generation completed");++    progress!(ctx, 940);++    Ok(())+}++#[derive(Debug, PartialEq, Eq)]+enum AutoconfigProvider {+    Mozilla,+    Outlook,+}++#[derive(Debug, PartialEq, Eq)]+struct AutconfigSource {+    provider: AutoconfigProvider,+    url: String,+}++impl AutconfigSource {+    async fn fetch(&self, ctx: &Context, param: &LoginParam) -> Result<LoginParam> {+        let params = match self.provider {+            AutoconfigProvider::Mozilla => moz_autoconfigure(ctx, &self.url, &param).await?,+            AutoconfigProvider::Outlook => outlk_autodiscover(ctx, &self.url, &param).await?,+        };++        Ok(params)+    } } -#[derive(Debug)]-enum Step {-    Done,-    Continue,+/// Retrieve available autoconfigurations.+///+/// A Search configurations from the domain used in the email-address, prefer encrypted+/// B. If we have no configuration yet, search configuration in Thunderbird's centeral database+async fn get_autoconfig(+    ctx: &Context,+    param: &LoginParam,+    param_domain: &str,+    param_addr_urlencoded: &str,+) -> Option<LoginParam> {+    let mut param_autoconfig = None;++    let urls = [+        AutconfigSource {+            provider: AutoconfigProvider::Mozilla,+            url: format!(+                "https://autoconfig.{}/mail/config-v1.1.xml?emailaddress={}",+                param_domain, param_addr_urlencoded+            ),+        },+        // the doc does not mention `emailaddress=`, however, Thunderbird adds it, see https://releases.mozilla.org/pub/thunderbird/ ,  which makes some sense+        AutconfigSource {+            provider: AutoconfigProvider::Mozilla,+            url: format!(+                "https://{}/.well-known/autoconfig/mail/config-v1.1.xml?emailaddress={}",+                param_domain, param_addr_urlencoded+            ),+        },+        AutconfigSource {+            provider: AutoconfigProvider::Outlook,+            url: format!("https://{}/autodiscover/autodiscover.xml", param_domain),+        },+        // Outlook uses always SSL but different domains (this comment describes the next two steps)+        AutconfigSource {+            provider: AutoconfigProvider::Outlook,+            url: format!(+                "https://{}{}/autodiscover/autodiscover.xml",+                "autodiscover.", param_domain+            ),+        },+        AutconfigSource {+            provider: AutoconfigProvider::Mozilla,+            url: format!(+                "http://autoconfig.{}/mail/config-v1.1.xml?emailaddress={}",+                param_domain, param_addr_urlencoded+            ),+        }, // do not transfer the email-address unencrypted+        AutconfigSource {+            provider: AutoconfigProvider::Mozilla,+            url: format!(+                "http://{}/.well-known/autoconfig/mail/config-v1.1.xml",+                param_domain+            ),+        },

I would be more than happy to remove them, but didn't want to make that call by myself cc @r10s

dignifiedquire

comment created time in 4 days

Pull request review commentfilecoin-project/neptune

Feat/default to strengthened

 pub(crate) const TEST_SEED: [u8; 16] = [     0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc, 0xe5, ]; +#[derive(Copy, Clone)]+pub enum Strength {+    Standard,+    Strengthened,

missing Strength::Over9000?

porcuquine

comment created time in 4 days

Pull request review commentfilecoin-project/neptune

Feat/default to strengthened

 pub(crate) const TEST_SEED: [u8; 16] = [     0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc, 0xe5, ]; +#[derive(Copy, Clone)]+pub enum Strength {

please add Debug that makes life easier for everyone

porcuquine

comment created time in 4 days

PR merged async-rs/async-std

Fix wrong slice index when reading a file

As the title, it fixes the wrong slice index of an internal buffer when reading a File.

+1 -1

0 comment

1 changed file

jerry73204

pr closed time in 4 days

push eventasync-rs/async-std

jerry73204

commit sha d60e7cc27dffc57905e69c1a328cfba10b5eeddc

Fix wrong slice index when reading a file

view details

Friedel Ziegelmayer

commit sha 0ec027dbff1176c6a74ba35ac18b4262ead66424

Merge pull request #802 from jerry73204/fix-reading-buf-bug

view details

push time in 4 days

pull request commentasync-rs/async-std

fix: allow for recursive block-on calls

CI seems to be failing independently, unclear as to why atm

dignifiedquire

comment created time in 4 days

pull request commentasync-rs/async-std

fix: allow for recursive block-on calls

Awesome! Now that stjepang/smol#147 is merged, can we update this and merge this as well?

still need to wait for a new release

dignifiedquire

comment created time in 4 days

push eventfilecoin-project/bls-signatures

dignifiedquire

commit sha 62a1aa39d652bbb0ecd72882ae46a5a3e3a4530e

refactor: apply improvements from @drpetervannostrand

view details

push time in 4 days

push eventfilecoin-project/bls-signatures

dignifiedquire

commit sha c022393e50366d89cc106b7a40656cab0de0f623

fix: update key generation to match the spec-02 draft Now matches https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-02#section-2.3

view details

push time in 4 days

push eventfilecoin-project/bls-signatures

dignifiedquire

commit sha d1a42231828831de72847f0c50e3aa79760367c9

fix: do not allow for empty inputs in aggregate and verify

view details

push time in 4 days

push eventfilecoin-project/bls-signatures

dignifiedquire

commit sha 350663af6b9cc56ccacd6ecd5b0b3ae0187aaf61

fix: use CryptoRng and try_fill_btytes for key gen

view details

push time in 4 days

push eventdeltachat/deltachat-core-rust

Floris Bruynooghe

commit sha 8efc880b7758d85c1a487d8435b635bcd0e0b6d0

Move Keyring and fingerprint to DcKey trait This moves both the Keyring and the fingerprints to the DcKey trait, unfortunately I was not able to disentangle these two changes. The Keyring now ensures only the right kind of key is added to it. The keyring now uses the DcKey::load_self method rather than re-implement the SQL to load keys from the database. This vastly simpliefies the use and fixes an error where a failed key load or unconfigured would result in the message being treated as plain text and benefits from the in-line key generation path. For the fingerprint a new type representing it is introduced. The aim is to replace more fingerpring uses with this type as now there are various string representations being passed around and converted between. The Display trait is used for the space-separated and multiline format, which is perhaps not the most obvious but seems right together with FromStr etc.

view details

Floris Bruynooghe

commit sha cdbd3d7d84223fea2bd27f829f3f37139f92045d

Move ascii-armored stuff from Key to DcKey This means all key conversions/serialisation/deserialisation can be done with DcKey rather than Key. Also migrate all key conversion tests to DcKey rather than Key.

view details

Floris Bruynooghe

commit sha a236a619adebc7718493a525a1038fd7c1cb6476

Finish Key->DcKey refactoring Migrates .verify() and .split_key() to DcKey. Removes all remaining uses of Key.

view details

dignifiedquire

commit sha 72285e0d7ffebb85429604a97248d0ed63428b24

refactor(configure): remove step-counter

view details

dignifiedquire

commit sha 8e9bd01814eb2e56d013900173427b1a7e9e10c3

refactor(configure): cleanup logic

view details

push time in 4 days

Pull request review commentdeltachat/deltachat-core-rust

[WIP] switch to sqlx

 use quote::quote; // data.  If this assumption is violated, compiler error will point to // generated code, which is not very user-friendly. -#[proc_macro_derive(ToSql)]-pub fn to_sql_derive(input: TokenStream) -> TokenStream {+#[proc_macro_derive(Sqlx)]

Maybe

dignifiedquire

comment created time in 4 days

Pull request review commentdeltachat/deltachat-core-rust

[WIP] switch to sqlx

 use quote::quote; // data.  If this assumption is violated, compiler error will point to // generated code, which is not very user-friendly. -#[proc_macro_derive(ToSql)]-pub fn to_sql_derive(input: TokenStream) -> TokenStream {+#[proc_macro_derive(Sqlx)]+pub fn sqlx_derive(input: TokenStream) -> TokenStream {     let ast: syn::DeriveInput = syn::parse(input).unwrap();     let name = &ast.ident;      let gen = quote! {-        impl rusqlite::types::ToSql for #name {-            fn to_sql(&self) -> rusqlite::Result<rusqlite::types::ToSqlOutput> {-                let num = *self as i64;-                let value = rusqlite::types::Value::Integer(num);-                let output = rusqlite::types::ToSqlOutput::Owned(value);-                std::result::Result::Ok(output)+        impl sqlx::encode::Encode<sqlx::sqlite::Sqlite> for #name {+            fn encode(&self, buf: &mut Vec<sqlx::sqlite::SqliteArgumentValue>) {+                num_traits::ToPrimitive::to_i64(self).expect("invalid type").encode(buf)             }         }-    };-    gen.into()-} -#[proc_macro_derive(FromSql)]-pub fn from_sql_derive(input: TokenStream) -> TokenStream {-    let ast: syn::DeriveInput = syn::parse(input).unwrap();-    let name = &ast.ident; -    let gen = quote! {-        impl rusqlite::types::FromSql for #name {-            fn column_result(col: rusqlite::types::ValueRef) -> rusqlite::types::FromSqlResult<Self> {-                let inner = rusqlite::types::FromSql::column_result(col)?;-                Ok(num_traits::FromPrimitive::from_i64(inner).unwrap_or_default())+        impl<'de> sqlx::decode::Decode<'de, sqlx::sqlite::Sqlite> for #name {+            fn decode(value: sqlx::sqlite::SqliteValue<'de>) -> sqlx::Result<Self> {+                let raw: i64 = sqlx::decode::Decode::decode(value)?;++                Ok(num_traits::FromPrimitive::from_i64(raw).unwrap_or_default())

We rely on this logic quite heavily atm, this is trying to match was there before.

dignifiedquire

comment created time in 4 days

Pull request review commentdeltachat/deltachat-core-rust

[WIP] switch to sqlx

 use quote::quote; // data.  If this assumption is violated, compiler error will point to // generated code, which is not very user-friendly. -#[proc_macro_derive(ToSql)]-pub fn to_sql_derive(input: TokenStream) -> TokenStream {+#[proc_macro_derive(Sqlx)]+pub fn sqlx_derive(input: TokenStream) -> TokenStream {     let ast: syn::DeriveInput = syn::parse(input).unwrap();     let name = &ast.ident;      let gen = quote! {-        impl rusqlite::types::ToSql for #name {-            fn to_sql(&self) -> rusqlite::Result<rusqlite::types::ToSqlOutput> {-                let num = *self as i64;-                let value = rusqlite::types::Value::Integer(num);-                let output = rusqlite::types::ToSqlOutput::Owned(value);-                std::result::Result::Ok(output)+        impl sqlx::encode::Encode<sqlx::sqlite::Sqlite> for #name {+            fn encode(&self, buf: &mut Vec<sqlx::sqlite::SqliteArgumentValue>) {+                num_traits::ToPrimitive::to_i64(self).expect("invalid type").encode(buf)

Design issue in the library, it will be solved eventually.

dignifiedquire

comment created time in 4 days

PR opened deltachat/deltachat-core-rust

refactor(configure): simplify logic and code

Not quite as nice as the C code yet, but at least there is no step counter anymore.

+293 -346

0 comment

1 changed file

pr created time in 4 days

push eventdeltachat/deltachat-core-rust

dignifiedquire

commit sha 50e6f6bfab5290b8a37bec60a656bfb57fb81656

refactor(configure): cleanup logic

view details

push time in 4 days

create barnchdeltachat/deltachat-core-rust

branch : sane-configure

created branch time in 5 days

push eventdeltachat/deltachat-core-rust

dignifiedquire

commit sha 0ba9078ce6cf7cc70615378f1110af38d562b208

wip

view details

push time in 5 days

push eventfilecoin-project/bls-signatures

dignifiedquire

commit sha 885e4cc7377c7b50389a6b8a5cc498c0ebf3530c

chore: do not track Cargo.lock

view details

push time in 5 days

push eventfilecoin-project/bls-signatures

dignifiedquire

commit sha 73881b8b3284fd84d5ac74d25c17ce04789351b0

fix: validate input data size for private keys

view details

push time in 5 days

create barnchfilecoin-project/bls-signatures

branch : fix-checks

created branch time in 5 days

pull request commentdeltachat/deltachat-core-rust

Fix #1495 "Delta chat not marking messages read on server"

The CI now fails because of my newly added test

Seems green now?

Hocuri

comment created time in 5 days

push eventdignifiedquire/smol-1

Stjepan Glavina

commit sha a37c1ee8ea85860fdaa963ee3f50b86b3585b01d

Drop locks before waking tasks

view details

dignifiedquire

commit sha 3e16c34504f132a1a0c44106068354a8e6c44cc5

feat: allow recursive block_on calls

view details

Stjepan Glavina

commit sha ee25d12cace4af424fd043583143630d2f332145

Merge pull request #147 from dignifiedquire/feat/recursive-block-on feat: allow recursive block_on calls

view details

Stjepan Glavina

commit sha b1b5986ef74168bbd91443545fd0a88af114a427

Merge pull request #143 from stjepang/unlock-before-wake Drop locks before waking tasks

view details

dignifiedquire

commit sha 1743bc4d32b89cca7da2525cb4976e6019f91bf2

refactor: isolate nix crate to a single file

view details

dignifiedquire

commit sha 49f3eb56c1b0024e2ee57eec87d0c8d5a8f65ab4

flatten

view details

dignifiedquire

commit sha b3358ef2751c5e31666848068cef8ef7416cc817

refactor: use libc instead of nix for fcntl

view details

dignifiedquire

commit sha b500e5ce2becc8594b2ff970df938243ba427d06

refactor: use libc for unistd

view details

dignifiedquire

commit sha f647532400fe374f08381eaa0cde2f04efee99fd

refactor: use libc for eventfd

view details

dignifiedquire

commit sha 63ffbc575c8fb9ffd29a9bed6735bb4c9d016cce

refactor: use libc for kqueue

view details

dignifiedquire

commit sha a56aa12de8ddcffe9db36ea6be043000144ad270

refactor: use libc for epoll

view details

dignifiedquire

commit sha 47f047c052089fc75e39643d76f6b89e87d9b8de

fix compiles for winodws

view details

dignifiedquire

commit sha 1ba84935e4e48be927c7f8f4a9cb5c05614135c3

fix: support systems without epoll_create1

view details

push time in 5 days

issue commentlaunchbadge/sqlx

SqliteError 262 database table is locked

Still getting this error with poolsize 1 :/

apexys

comment created time in 5 days

issue commentstjepang/smol

Regression introduced after smol 0.1.8

Still hangs in a project of mine, trying to switch to sqlx and getting these hangs with smol. Tested with and without the unlock-before-wake branch.

almetica

comment created time in 5 days

push eventdeltachat/deltachat-core-rust

dignifiedquire

commit sha 689d4e408aaecd078e96870e83d23d8fce97fadf

python tests start and shutdown again

view details

push time in 5 days

push eventdeltachat/deltachat-core-rust

dignifiedquire

commit sha b0164efc7c0ca1f8e06013def2e7d71e406739b0

rust tests passing

view details

dignifiedquire

commit sha 9bae0df660782816947df8f3160d697db355753e

fix bindings and example

view details

push time in 5 days

push eventdeltachat/deltachat-core-rust

dignifiedquire

commit sha 0156433fc04cfd0789a0783aa1de46ac15c711a8

remove rusqlite and r2d2

view details

push time in 5 days

push eventdeltachat/deltachat-core-rust

dignifiedquire

commit sha 2990c9d382f1d83e587cf657b3d330f8ec8e4f03

fixup repl

view details

push time in 5 days

push eventdeltachat/deltachat-core-rust

dignifiedquire

commit sha a3ba24c817ff25dfef42b1a07ef4ebf18d04a482

finish removal of query_map

view details

push time in 5 days

push eventdeltachat/deltachat-core-rust

dignifiedquire

commit sha 414bcf001866da84f1689b4a2f6c38fc82dff3b3

convert more query_maps

view details

push time in 5 days

push eventdeltachat/deltachat-core-rust

dignifiedquire

commit sha f65e8f05da8f05acf8913c5f1850fbe3f389d154

remove db files

view details

push time in 5 days

push eventdeltachat/deltachat-core-rust

dignifiedquire

commit sha 6c0b504a4cb92f2ba2019a52d7a44c6bd0894efc

first pass at translating quuery_map calls

view details

push time in 5 days

push eventdeltachat/deltachat-core-rust

dignifiedquire

commit sha 5c2bc18551a8512daeb8683c28341eb9db8514e8

refactor: update exists and get_rowid

view details

push time in 5 days

Pull request review commentdeltachat/deltachat-core-rust

Move ascii-armored stuff from Key to DcKey

 fn export_self_keys(context: &Context, dir: impl AsRef<Path>) -> Result<()> { /*******************************************************************************  * Classic key export  ******************************************************************************/-fn export_key_to_asc_file(+fn export_key_to_asc_file<T>(     context: &Context,     dir: impl AsRef<Path>,     id: Option<i64>,-    key: &Key,-) -> std::io::Result<()> {+    key: &T,+) -> std::io::Result<()>+where+    T: DcKey + Any,+{     let file_name = {-        let kind = if key.is_public() { "public" } else { "private" };+        let any_key = key as &dyn Any;+        let kind = match any_key.downcast_ref::<SignedPublicKey>() {+            Some(_pubkey) => "public",+            None => "private",+        };

instead of assuming that we only ever have two implementors, I would do sth like this

let kind = if any_key.downcast_ref::<SignedPublicKey>().is_some() {
  "public"
} else if any_key.downcast_ref::<SignedSecretKey>().is_some() {
  "private"
} else {
  "unknown"
}
flub

comment created time in 6 days

Pull request review commentdeltachat/deltachat-core-rust

Finish Key->DcKey refactoring

 impl DcKey for SignedSecretKey {     } } +/// Deltachat extension trait for secret keys.+///+/// Provides some convenience wrappers only applicable to [SignedSecretKey].+pub trait DcSecKey {

can we call this DcSecretKey please, makes it a bit easier to read in combination with the other names

flub

comment created time in 6 days

Pull request review commentdeltachat/deltachat-core-rust

Move Keyring and fingerprint to DcKey trait

 impl Keyring {         self.keys.is_empty()     } -    pub fn keys(&self) -> &[Key] {-        &self.keys+    /// A vector with reference to all the keys in the keyring.+    ///+    /// All current uses only need references to keys, so provide this directly.+    pub fn keys(&self) -> Vec<&T> {+        self.keys.iter().collect()

BLOCKING: this shouldn't allocate, but still return a slice

flub

comment created time in 6 days

Pull request review commentdeltachat/deltachat-core-rust

Move Keyring and fingerprint to DcKey trait

+//! Keyring to perform rpgp operations with.+ use anyhow::Result; -use crate::constants::KeyType; use crate::context::Context;-use crate::key::Key;+use crate::key::{self, DcKey}; -#[derive(Default, Clone, Debug)]-pub struct Keyring {-    keys: Vec<Key>,+/// An in-memory keyring.+///+/// The keyring can contain both owned and borrowed keys to avoid unnecessary+/// copies as most keyring are constructed just for the rpgp operation and

it only contains owned values now, could you update the description, I forgot about that

flub

comment created time in 6 days

Pull request review commentdeltachat/deltachat-core-rust

Move Keyring and fingerprint to DcKey trait

 pub async fn store_self_keypair(     Ok(()) } +/// A key fingerprint+#[derive(Debug, Clone, Eq, PartialEq)]+pub struct Fingerprint(Vec<u8>);++impl Fingerprint {+    pub fn new(v: Vec<u8>) -> Fingerprint {+        Fingerprint(v)+    }++    /// Make a hex string from the fingerprint.+    ///+    /// Use [std::fmt::Display] or [ToString::to_string] to get a+    /// human-readable formatted string.+    pub fn hex(&self) -> String {+        hex::encode_upper(&self.0)+    }+}++/// Make a human-readable fingerprint.+impl fmt::Display for Fingerprint {+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {+        // Split key into chunks of 4 with space and newline at 20 chars+        for (i, c) in self.hex().chars().enumerate() {+            if i > 0 && i % 20 == 0 {+                writeln!(f)?;+            } else if i > 0 && i % 4 == 0 {+                write!(f, " ")?;+            }+            write!(f, "{}", c)?;+        }+        Ok(())+    }+}++/// Parse a human-readable or otherwise formatted fingerprint.+impl std::str::FromStr for Fingerprint {+    type Err = hex::FromHexError;++    fn from_str(input: &str) -> std::result::Result<Self, Self::Err> {+        let hex_repr: String = input+            .chars()+            .filter(|&c| c >= '0' && c <= '9' || c >= 'A' && c <= 'F')+            .collect();+        let v: Vec<u8> = hex::decode(hex_repr)?;+        Ok(Fingerprint(v))+    }+}++/// Bring a human-readable or otherwise formatted fingerprint back to the 40-characters-uppercase-hex format.+pub fn dc_normalize_fingerprint(fp: &str) -> String {

lets drop the dc_ prefix while we are here

flub

comment created time in 6 days

push eventdeltachat/deltachat-core-rust

B. Petersen

commit sha 8640bd5ee61ae8fecb012a0d54a95e28965e408a

update changelog

view details

B. Petersen

commit sha 0a4d6fe09b4041c52439c231cd383884b2987db0

bump version to 1.34.0

view details

bjoern

commit sha 4f477ec6d21e62ce7fa5af6eea612b836e5216be

Merge pull request #1536 from deltachat/prep-1.34 Prep 1.34

view details

dignifiedquire

commit sha 37a1ae0dcb9341a2634e58d16651693b83ec8c13

feat: start preparations for sqlx, split out migrations

view details

dignifiedquire

commit sha b9bd7bdc22b3d3865aace25c6795f9d30a81cbc1

refactor(sql): move migration 0 to migrations

view details

dignifiedquire

commit sha a5f5b409631e9e0a330157eebb8aa3c215bb5b22

sql: execute migrations using sqlx

view details

dignifiedquire

commit sha dd588b14289a6e568cd33d1872ee319dbc3917f2

refactor(sql): switch execute to sqlx

view details

dignifiedquire

commit sha 3aa28e678a9537daf922b2352de2588972bb85b7

implement most of query_value

view details

dignifiedquire

commit sha 8563b36cb1435b6b28deed16393702dbb98fce64

compiles again, and some cleanup

view details

dignifiedquire

commit sha 50f09def46787fb5d789371c9c9ac27ac3571100

replace with_conn with sqlx

view details

push time in 6 days

push eventdeltachat/deltachat-core-rust

dignifiedquire

commit sha 9e506dfe545de20f93248db9c19d6d1340bdf342

replace with_conn with sqlx

view details

push time in 6 days

MemberEvent
MemberEvent
MemberEvent

push eventdeltachat/deltachat-core-rust

dignifiedquire

commit sha de8677e90068a1153582691836a50ccbc444c788

compiles again, and some cleanup

view details

push time in 6 days

push eventdignifiedquire/dc-next

dignifiedquire

commit sha 3ea2d899d67b7eb9765fa436dec14e3a930f3677

finish migration to async-rust

view details

push time in 6 days

PR opened deltachat/deltachat-core-rust

[WIP] switch to sqlx
+2239 -2010

0 comment

25 changed files

pr created time in 6 days

push eventdeltachat/deltachat-core-rust

bjoern

commit sha 19a6a30fe28c575d4b2cca6fa79681ec4169b0c2

Merge pull request #1356 from deltachat/feat/async-jobs asyncify core & remove manual thread handling

view details

dignifiedquire

commit sha 5ad1f363b04d5ff6c19658189314b1f2ea9edf5c

feat: start preparations for sqlx, split out migrations

view details

dignifiedquire

commit sha 2e99e38fcaf8d040c598ec9e2c508936f4bb9e91

refactor(sql): move migration 0 to migrations

view details

dignifiedquire

commit sha c3295bcca21233bd0ba9267a15d708c09a60eb2d

sql: execute migrations using sqlx

view details

dignifiedquire

commit sha d1ad5332ed5096564c7f371eada0e816dd27167d

refactor(sql): switch execute to sqlx

view details

dignifiedquire

commit sha 3d34dc0285e8d75bfda9267e3a96837065833f78

implement most of query_value

view details

push time in 6 days

push eventdeltachat/deltachat-core-rust

Hocuri

commit sha 26b0c43cc49cad3732a15e22cae5c05b4a729f5b

Remove help for nonexisting open and close commands. See #1496

view details

Nick Thomas

commit sha 1ab6186eaa6726d8c166101b4021473135a0be44

Add telepathy-padfoot to the README

view details

bjoern

commit sha 177cd52039a5b9a093df2962b6e3afe7dfa1918c

Merge pull request #1524 from lupine/add-padfoot Add telepathy-padfoot to the README

view details

B. Petersen

commit sha 4330da232c86d8c12241e523d2c1b716626592da

tweak async ffi-docs

view details

B. Petersen

commit sha 3db6d5a458bc70aad80809c75c4b9ba68e15abf0

allow calls to start_io when already running and to stop_io when not running, only log a message in these cases

view details

dignifiedquire

commit sha bd903d8e8fa400dcdb78e001dbebc65925331801

fix: avoid short smtp interruptions

view details

dignifiedquire

commit sha 307357df70e8dcc36b0cd2c93725582f1b6529b7

update simple exaple

view details

dignifiedquire

commit sha 9f7f387540515ccc7c1d1712b620ad61bccedb92

examples: fix blocking the scheduler in the repl

view details

dignifiedquire

commit sha 6100a23e80c7d7cdf48a0f279ca3e88184db852c

fix: avoid lock for probe_network, avoiding deadlock on startup Closes #1532

view details

Friedel Ziegelmayer

commit sha 103ee966f4dfeeb3b6c59aa063b26b1bc91383c9

Merge pull request #1531 from deltachat/forgiving-start-io

view details

dignifiedquire

commit sha 23b697438661cc07badd631f29b03c02cbc5cf84

Merge master

view details

dignifiedquire

commit sha d40d9dd1d7a864f6f331eabe8c38de0e4896e943

feat: start preparations for sqlx, split out migrations

view details

dignifiedquire

commit sha 095e3c576affd45d98144dd8e4073d3d6d64d614

refactor(sql): move migration 0 to migrations

view details

dignifiedquire

commit sha e304ddf93b75cc2952c768728a6d7a3bb386acac

sql: execute migrations using sqlx

view details

dignifiedquire

commit sha 1e286bb1940b30b3fc73d52edbd1c71a7fb1efe4

refactor(sql): switch execute to sqlx

view details

dignifiedquire

commit sha efa0f2d661c1cf6a1d514411e3ad2543adb5178e

implement most of query_value

view details

push time in 6 days

push eventdeltachat/deltachat-core-rust

Hocuri

commit sha 26b0c43cc49cad3732a15e22cae5c05b4a729f5b

Remove help for nonexisting open and close commands. See #1496

view details

Nick Thomas

commit sha 1ab6186eaa6726d8c166101b4021473135a0be44

Add telepathy-padfoot to the README

view details

bjoern

commit sha 177cd52039a5b9a093df2962b6e3afe7dfa1918c

Merge pull request #1524 from lupine/add-padfoot Add telepathy-padfoot to the README

view details

dignifiedquire

commit sha 23b697438661cc07badd631f29b03c02cbc5cf84

Merge master

view details

push time in 6 days

delete branch deltachat/deltachat-core-rust

delete branch : forgiving-start-io

delete time in 6 days

push eventdeltachat/deltachat-core-rust

B. Petersen

commit sha 3db6d5a458bc70aad80809c75c4b9ba68e15abf0

allow calls to start_io when already running and to stop_io when not running, only log a message in these cases

view details

Friedel Ziegelmayer

commit sha 103ee966f4dfeeb3b6c59aa063b26b1bc91383c9

Merge pull request #1531 from deltachat/forgiving-start-io

view details

push time in 6 days

PR merged deltachat/deltachat-core-rust

forgiving start_io() and stop_io()

this pr removes the condition to check is_io_running() before start_io() can be called; same for stop_io(), successor of https://github.com/deltachat/deltachat-core-rust/pull/1529#pullrequestreview-417998214

i am not yet deep into async, so not sure, if the calling is correct - or maybe i've overseen sth. :)

also, if this does not fit well into some internal concepts or thinkings, i would also be fine with this being closed again, it is only a tiny detail that can also be handled by the ui - otoh, of course, it is great if there is one thing less the ui has to take care about :)

+13 -3

0 comment

2 changed files

r10s

pr closed time in 6 days

PR opened async-rs/async-std

fix: allow for recursive block-on calls

Depends on https://github.com/stjepang/smol/pull/147

Fixes #798,#795,#760

+99 -2

0 comment

3 changed files

pr created time in 6 days

issue closedasync-rs/async-std

async-std@1.6-beta.1: panicked at `async fn` resumed after completion

I have some code that automatically attempts to reconnect on connection failure. It runs ok in 1.5.0, but panics on 1.6-beta.

Issue seems to be on my side, I wrap a Future which after a failed reconnect resolves to a Poll:Ready(Err).. and then when I poll it again, it panics... however, the prior runtime (and tokio) seem to be ok with it.

Here are parts of a trace that might be of interest:

thread 'main' panicked at '`async fn` resumed after completion', <... snip ...>
stack backtrace:
   0: backtrace::backtrace::libunwind::trace
             at /Users/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.44/src/backtrace/libunwind.rs:86
...
  15: <std::future::GenFuture<T> as core::future::future::Future>::poll
             at /rustc/4fb7144ed159f94491249e86d5bbd033b5d60550/src/libstd/future.rs:44
  16: <core::pin::Pin<P> as core::future::future::Future>::poll
             at /rustc/4fb7144ed159f94491249e86d5bbd033b5d60550/src/libcore/future/future.rs:118
  17: futures_util::future::future::FutureExt::poll_unpin
             at /Users/a/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-util-0.3.4/src/future/future/mod.rs:507
... snip user code ...
  19: <futures_util::stream::stream::split::SplitStream<S> as futures_core::stream::Stream>::poll_next
             at /Users/a/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-util-0.3.4/src/stream/stream/split.rs:31
  20: <futures_util::stream::stream::filter_map::FilterMap<St,Fut,F> as futures_core::stream::Stream>::poll_next
             at /Users/a/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-util-0.3.4/src/stream/stream/filter_map.rs:106
  21: <S as futures_core::stream::TryStream>::try_poll_next
             at /Users/a/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-core-0.3.4/src/stream.rs:193
  22: <futures_util::stream::try_stream::map_err::MapErr<St,F> as futures_core::stream::Stream>::poll_next
             at /Users/a/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-util-0.3.4/src/stream/try_stream/map_err.rs:92
  23: <core::pin::Pin<P> as futures_core::stream::Stream>::poll_next
             at /Users/a/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-core-0.3.4/src/stream.rs:121
  24: futures_core::stream::if_alloc::<impl futures_core::stream::Stream for alloc::boxed::Box<S>>::poll_next
             at /Users/a/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-core-0.3.4/src/stream.rs:209
  25: futures_util::stream::stream::StreamExt::poll_next_unpin
             at /Users/a/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-util-0.3.4/src/stream/stream/mod.rs:1184
  26: <futures_util::stream::stream::next::Next<St> as core::future::future::Future>::poll
             at /Users/a/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-util-0.3.4/src/stream/stream/next.rs:35
  27: std::future::poll_with_tls_context
             at /rustc/4fb7144ed159f94491249e86d5bbd033b5d60550/src/libstd/future.rs:102
... snip user code ...
  29: <std::future::GenFuture<T> as core::future::future::Future>::poll
             at /rustc/4fb7144ed159f94491249e86d5bbd033b5d60550/src/libstd/future.rs:44
  30: <async_std::task::builder::SupportTaskLocals<F> as core::future::future::Future>::poll::{{closure}}
             at /Users/a/.cargo/registry/src/github.com-1ecc6299db9ec823/async-std-1.6.0-beta.1/src/task/builder.rs:174
  31: async_std::task::task_locals_wrapper::TaskLocalsWrapper::set_current::{{closure}}
             at /Users/a/.cargo/registry/src/github.com-1ecc6299db9ec823/async-std-1.6.0-beta.1/src/task/task_locals_wrapper.rs:60
  32: std::thread::local::LocalKey<T>::try_with
             at /rustc/4fb7144ed159f94491249e86d5bbd033b5d60550/src/libstd/thread/local.rs:262
  33: std::thread::local::LocalKey<T>::with
             at /rustc/4fb7144ed159f94491249e86d5bbd033b5d60550/src/libstd/thread/local.rs:239
  34: async_std::task::task_locals_wrapper::TaskLocalsWrapper::set_current
             at /Users/a/.cargo/registry/src/github.com-1ecc6299db9ec823/async-std-1.6.0-beta.1/src/task/task_locals_wrapper.rs:55
  35: <async_std::task::builder::SupportTaskLocals<F> as core::future::future::Future>::poll
             at /Users/a/.cargo/registry/src/github.com-1ecc6299db9ec823/async-std-1.6.0-beta.1/src/task/builder.rs:172
  36: smol::run::run::{{closure}}::{{closure}}
             at /Users/a/.cargo/registry/src/github.com-1ecc6299db9ec823/smol-0.1.4/src/run.rs:143
  37: scoped_tls_hkt::ScopedKey<T>::set
             at /Users/a/.cargo/registry/src/github.com-1ecc6299db9ec823/scoped-tls-hkt-0.1.2/src/lib.rs:488
  38: smol::throttle::setup
             at /Users/a/.cargo/registry/src/github.com-1ecc6299db9ec823/smol-0.1.4/src/throttle.rs:31

closed time in 6 days

arbfranklin

PR opened stjepang/smol

feat: allow recursive block_on calls

It turns out it is really useful to not be so strict about nested block_on calls. We have had a lot of reports about this being an issue with existing code in async-std.

+56 -2

0 comment

3 changed files

pr created time in 6 days

create barnchasync-rs/async-std

branch : feat/recursive-block-on

created branch time in 6 days

create barnchdignifiedquire/smol-1

branch : feat/recursive-block-on

created branch time in 6 days

push eventdeltachat/deltachat-core-rust

dignifiedquire

commit sha 9f7f387540515ccc7c1d1712b620ad61bccedb92

examples: fix blocking the scheduler in the repl

view details

dignifiedquire

commit sha 6100a23e80c7d7cdf48a0f279ca3e88184db852c

fix: avoid lock for probe_network, avoiding deadlock on startup Closes #1532

view details

push time in 6 days

push eventdeltachat/deltachat-core-rust

dignifiedquire

commit sha bd903d8e8fa400dcdb78e001dbebc65925331801

fix: avoid short smtp interruptions

view details

dignifiedquire

commit sha 307357df70e8dcc36b0cd2c93725582f1b6529b7

update simple exaple

view details

push time in 7 days

push eventdeltachat/deltachat-core-rust

dignifiedquire

commit sha 8b223ac178f8d656ec1d89eed09abf88f1f1efc1

implement most of query_value

view details

push time in 7 days

create barnchdignifiedquire/sqlx

branch : from-row-tuple-16

created branch time in 7 days

fork dignifiedquire/sqlx

🧰 The Rust SQL Toolkit. An async, pure Rust SQL crate featuring compile-time checked queries without a DSL. Supports PostgreSQL, MySQL, and SQLite.

fork in 7 days

push eventdeltachat/deltachat-core-rust

dignifiedquire

commit sha 8af9699084ce76dfd66aacd81995fb64a9af4b8f

refactor(sql): switch execute to sqlx

view details

push time in 7 days

create barnchdeltachat/deltachat-core-rust

branch : sq

created branch time in 7 days

push eventdeltachat/deltachat-core-rust

dignifiedquire

commit sha e112d73b1e7a54a9e222e79d59727cc1c7c6294d

sql: execute migrations using sqlx

view details

push time in 8 days

push eventdeltachat/deltachat-core-rust

dignifiedquire

commit sha aa0b78e04c186deb7bbdad8dc94fd31bf741c9da

refactor(sql): move migration 0 to migrations

view details

push time in 8 days

create barnchdeltachat/deltachat-core-rust

branch : sqlx

created branch time in 8 days

push eventdeltachat/deltachat-core-rust

dignifiedquire

commit sha 157dd44df045558d4822eb0010fce3e3f2ff4049

refactor: improve structure of fetch_messages also fixes updating last_seen_uid to the correct value

view details

push time in 8 days

issue commentstjepang/smol

Cross compiling on x86_64-w64-mingw32-gcc fails with undefined epoll errors

very likely it would be, the main issue I see is with maintenance after having done it, and support for c2rust on windows is still experimental. but I think it is likely the best option for longterm support

hu55a1n1

comment created time in 8 days

Pull request review commentstjepang/smol

refactor: replace nix with libc

+#[cfg(target_os = "linux")]+pub mod eventfd {+    use super::check_err;+    use std::os::unix::io::RawFd;++    pub type EfdFlags = libc::c_int;++    pub fn eventfd(initval: libc::c_uint, flags: EfdFlags) -> Result<RawFd, std::io::Error> {+        let res = unsafe { libc::eventfd(initval, flags) };++        check_err(res).map(|r| r as RawFd)+    }+}++#[cfg(target_os = "linux")]+pub mod unistd {+    use super::check_err;+    use std::os::unix::io::RawFd;++    pub fn close(fd: RawFd) -> Result<(), std::io::Error> {+        let res = unsafe { libc::close(fd) };++        check_err(res).map(drop)+    }++    pub fn dup(oldfd: RawFd) -> Result<RawFd, std::io::Error> {+        let res = unsafe { libc::dup(oldfd) };+        check_err(res)+    }++    pub fn read(fd: RawFd, buf: &mut [u8]) -> Result<usize, std::io::Error> {+        let res = unsafe {+            libc::read(+                fd,+                buf.as_mut_ptr() as *mut libc::c_void,+                buf.len() as libc::size_t,+            )+        };++        check_err(res as _).map(|r| r as usize)+    }++    pub fn write(fd: RawFd, buf: &[u8]) -> Result<usize, std::io::Error> {+        let res = unsafe {+            libc::write(+                fd,+                buf.as_ptr() as *const libc::c_void,+                buf.len() as libc::size_t,+            )+        };++        check_err(res as _).map(|r| r as usize)+    }+}++#[cfg(unix)]+pub mod fcntl {+    use super::check_err;+    use std::os::unix::io::RawFd;++    pub type OFlag = libc::c_int;+    pub type FdFlag = libc::c_int;++    #[allow(non_camel_case_types)]+    #[allow(dead_code)]+    /// Arguments passed to `fcntl`.+    pub enum FcntlArg {+        F_GETFL,+        F_SETFL(OFlag),+        F_SETFD(FdFlag),+    }++    /// Thin wrapper around `libc::fcntl`.+    ///+    /// See [`fcntl(2)`](http://man7.org/linux/man-pages/man2/fcntl.2.html) for details.+    pub fn fcntl(fd: RawFd, arg: FcntlArg) -> Result<libc::c_int, std::io::Error> {+        let res = unsafe {+            match arg {+                FcntlArg::F_GETFL => libc::fcntl(fd, libc::F_GETFL),+                FcntlArg::F_SETFL(flag) => libc::fcntl(fd, libc::F_SETFL, flag),+                FcntlArg::F_SETFD(flag) => libc::fcntl(fd, libc::F_SETFD, flag),+            }+        };+        check_err(res)+    }+}++#[cfg(unix)]+fn check_err(res: libc::c_int) -> Result<libc::c_int, std::io::Error> {+    if res == -1 {+        return Err(std::io::Error::last_os_error());+    }++    Ok(res)+}++#[cfg(any(+    target_os = "macos",+    target_os = "ios",+    target_os = "freebsd",+    target_os = "netbsd",+    target_os = "openbsd",+    target_os = "dragonfly",+))]+/// Kqueue.+pub mod event {+    use super::check_err;+    use std::os::unix::io::RawFd;++    #[cfg(any(+        target_os = "macos",+        target_os = "ios",+        target_os = "freebsd",+        target_os = "dragonfly",+        target_os = "openbsd"+    ))]+    #[allow(non_camel_case_types)]+    type type_of_nchanges = libc::c_int;+    #[cfg(target_os = "netbsd")]+    #[allow(non_camel_case_types)]+    type type_of_nchanges = libc::size_t;++    #[cfg(target_os = "netbsd")]+    #[allow(non_camel_case_types)]+    type type_of_event_filter = u32;+    #[cfg(not(target_os = "netbsd"))]+    #[allow(non_camel_case_types)]+    type type_of_event_filter = i16;++    #[cfg(any(+        target_os = "dragonfly",+        target_os = "freebsd",+        target_os = "ios",+        target_os = "macos",+        target_os = "openbsd"+    ))]+    #[allow(non_camel_case_types)]+    type type_of_udata = *mut libc::c_void;+    #[cfg(any(+        target_os = "dragonfly",+        target_os = "freebsd",+        target_os = "ios",+        target_os = "macos"+    ))]+    #[allow(non_camel_case_types)]+    type type_of_data = libc::intptr_t;+    #[cfg(any(target_os = "netbsd"))]+    #[allow(non_camel_case_types)]+    type type_of_udata = libc::intptr_t;+    #[cfg(any(target_os = "netbsd", target_os = "openbsd"))]+    #[allow(non_camel_case_types)]+    type type_of_data = libc::int64_t;++    #[derive(Clone, Copy)]+    #[repr(C)]+    pub struct KEvent(libc::kevent);++    unsafe impl Send for KEvent {}++    impl KEvent {+        pub fn new(+            ident: libc::uintptr_t,+            filter: EventFilter,+            flags: EventFlag,+            fflags: FilterFlag,+            data: libc::intptr_t,+            udata: libc::intptr_t,+        ) -> KEvent {+            KEvent(libc::kevent {+                ident,+                filter: filter as type_of_event_filter,+                flags,+                fflags,+                data: data as type_of_data,+                udata: udata as type_of_udata,+            })+        }++        pub fn filter(&self) -> EventFilter {+            unsafe { std::mem::transmute(self.0.filter as type_of_event_filter) }+        }++        pub fn flags(&self) -> EventFlag {+            self.0.flags+        }++        pub fn data(&self) -> libc::intptr_t {+            self.0.data as libc::intptr_t+        }++        pub fn udata(&self) -> libc::intptr_t {+            self.0.udata as libc::intptr_t+        }+    }++    #[cfg(any(+        target_os = "dragonfly",+        target_os = "freebsd",+        target_os = "ios",+        target_os = "macos",+        target_os = "openbsd"+    ))]+    pub type EventFlag = u16;+    #[cfg(any(target_os = "netbsd"))]+    pub type EventFlag = u32;++    pub type FilterFlag = u32;++    #[cfg(target_os = "netbsd")]+    pub type EventFilter = u32;+    #[cfg(not(target_os = "netbsd"))]+    pub type EventFilter = i16;++    pub fn kqueue() -> Result<RawFd, std::io::Error> {+        let res = unsafe { libc::kqueue() };++        check_err(res)+    }++    pub fn kevent_ts(+        kq: RawFd,+        changelist: &[KEvent],+        eventlist: &mut [KEvent],+        timeout_opt: Option<libc::timespec>,+    ) -> Result<usize, std::io::Error> {+        let res = unsafe {+            libc::kevent(+                kq,+                changelist.as_ptr() as *const libc::kevent,+                changelist.len() as type_of_nchanges,+                eventlist.as_mut_ptr() as *mut libc::kevent,+                eventlist.len() as type_of_nchanges,+                if let Some(ref timeout) = timeout_opt {+                    timeout as *const libc::timespec+                } else {+                    std::ptr::null()+                },+            )+        };++        check_err(res).map(|r| r as usize)+    }+}++#[cfg(any(target_os = "linux", target_os = "android", target_os = "illumos"))]+/// Epoll.+pub mod epoll {+    use super::check_err;+    use std::os::unix::io::RawFd;++    #[macro_use]+    mod dlsym {+        // Based on https://github.com/tokio-rs/mio/blob/v0.6.x/src/sys/unix/dlsym.rs+        // I feel very sad including this code, but I have not found a better way+        // to check for the existence of a symbol in Rust.++        use std::marker;+        use std::mem;+        use std::sync::atomic::{AtomicUsize, Ordering};++        macro_rules! dlsym {+            (fn $name:ident($($t:ty),*) -> $ret:ty) => (+                #[allow(bad_style)]+                static $name: $crate::sys::epoll::dlsym::DlSym<unsafe extern fn($($t),*) -> $ret> =+                    $crate::sys::epoll::dlsym::DlSym {+                        name: concat!(stringify!($name), "\0"),+                        addr: std::sync::atomic::AtomicUsize::new(0),+                        _marker: std::marker::PhantomData,+                    };+            )+        }++        pub struct DlSym<F> {+            pub name: &'static str,+            pub addr: AtomicUsize,+            pub _marker: marker::PhantomData<F>,+        }++        impl<F> DlSym<F> {+            pub fn get(&self) -> Option<&F> {+                assert_eq!(mem::size_of::<F>(), mem::size_of::<usize>());+                unsafe {+                    if self.addr.load(Ordering::SeqCst) == 0 {+                        self.addr.store(fetch(self.name), Ordering::SeqCst);+                    }+                    if self.addr.load(Ordering::SeqCst) == 1 {+                        None+                    } else {+                        mem::transmute::<&AtomicUsize, Option<&F>>(&self.addr)+                    }+                }+            }+        }++        unsafe fn fetch(name: &str) -> usize {+            assert_eq!(name.as_bytes()[name.len() - 1], 0);+            match libc::dlsym(libc::RTLD_DEFAULT, name.as_ptr() as *const _) as usize {+                0 => 1,+                n => n,+            }+        }+    }++    #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]+    #[repr(i32)]+    pub enum EpollOp {+        EpollCtlAdd = libc::EPOLL_CTL_ADD,+        EpollCtlDel = libc::EPOLL_CTL_DEL,+        EpollCtlMod = libc::EPOLL_CTL_MOD,+    }++    pub type EpollFlags = libc::c_int;++    pub fn epoll_create1() -> Result<RawFd, std::io::Error> {+        // According to libuv, `EPOLL_CLOEXEC` is not defined on Android API <+        // 21. But `EPOLL_CLOEXEC` is an alias for `O_CLOEXEC` on that platform,+        // so we use it instead.+        #[cfg(target_os = "android")]+        const CLOEXEC: libc::c_int = libc::O_CLOEXEC;+        #[cfg(not(target_os = "android"))]+        const CLOEXEC: libc::c_int = libc::EPOLL_CLOEXEC;++        let fd = unsafe {+            // Emulate epoll_create1 if not available.++            dlsym!(fn epoll_create1(libc::c_int) -> libc::c_int);

which means I could never upgrade to mio 0.7

dignifiedquire

comment created time in 8 days

Pull request review commentstjepang/smol

refactor: replace nix with libc

+#[cfg(target_os = "linux")]+pub mod eventfd {+    use super::check_err;+    use std::os::unix::io::RawFd;++    pub type EfdFlags = libc::c_int;++    pub fn eventfd(initval: libc::c_uint, flags: EfdFlags) -> Result<RawFd, std::io::Error> {+        let res = unsafe { libc::eventfd(initval, flags) };++        check_err(res).map(|r| r as RawFd)+    }+}++#[cfg(target_os = "linux")]+pub mod unistd {+    use super::check_err;+    use std::os::unix::io::RawFd;++    pub fn close(fd: RawFd) -> Result<(), std::io::Error> {+        let res = unsafe { libc::close(fd) };++        check_err(res).map(drop)+    }++    pub fn dup(oldfd: RawFd) -> Result<RawFd, std::io::Error> {+        let res = unsafe { libc::dup(oldfd) };+        check_err(res)+    }++    pub fn read(fd: RawFd, buf: &mut [u8]) -> Result<usize, std::io::Error> {+        let res = unsafe {+            libc::read(+                fd,+                buf.as_mut_ptr() as *mut libc::c_void,+                buf.len() as libc::size_t,+            )+        };++        check_err(res as _).map(|r| r as usize)+    }++    pub fn write(fd: RawFd, buf: &[u8]) -> Result<usize, std::io::Error> {+        let res = unsafe {+            libc::write(+                fd,+                buf.as_ptr() as *const libc::c_void,+                buf.len() as libc::size_t,+            )+        };++        check_err(res as _).map(|r| r as usize)+    }+}++#[cfg(unix)]+pub mod fcntl {+    use super::check_err;+    use std::os::unix::io::RawFd;++    pub type OFlag = libc::c_int;+    pub type FdFlag = libc::c_int;++    #[allow(non_camel_case_types)]+    #[allow(dead_code)]+    /// Arguments passed to `fcntl`.+    pub enum FcntlArg {+        F_GETFL,+        F_SETFL(OFlag),+        F_SETFD(FdFlag),+    }++    /// Thin wrapper around `libc::fcntl`.+    ///+    /// See [`fcntl(2)`](http://man7.org/linux/man-pages/man2/fcntl.2.html) for details.+    pub fn fcntl(fd: RawFd, arg: FcntlArg) -> Result<libc::c_int, std::io::Error> {+        let res = unsafe {+            match arg {+                FcntlArg::F_GETFL => libc::fcntl(fd, libc::F_GETFL),+                FcntlArg::F_SETFL(flag) => libc::fcntl(fd, libc::F_SETFL, flag),+                FcntlArg::F_SETFD(flag) => libc::fcntl(fd, libc::F_SETFD, flag),+            }+        };+        check_err(res)+    }+}++#[cfg(unix)]+fn check_err(res: libc::c_int) -> Result<libc::c_int, std::io::Error> {+    if res == -1 {+        return Err(std::io::Error::last_os_error());+    }++    Ok(res)+}++#[cfg(any(+    target_os = "macos",+    target_os = "ios",+    target_os = "freebsd",+    target_os = "netbsd",+    target_os = "openbsd",+    target_os = "dragonfly",+))]+/// Kqueue.+pub mod event {+    use super::check_err;+    use std::os::unix::io::RawFd;++    #[cfg(any(+        target_os = "macos",+        target_os = "ios",+        target_os = "freebsd",+        target_os = "dragonfly",+        target_os = "openbsd"+    ))]+    #[allow(non_camel_case_types)]+    type type_of_nchanges = libc::c_int;+    #[cfg(target_os = "netbsd")]+    #[allow(non_camel_case_types)]+    type type_of_nchanges = libc::size_t;++    #[cfg(target_os = "netbsd")]+    #[allow(non_camel_case_types)]+    type type_of_event_filter = u32;+    #[cfg(not(target_os = "netbsd"))]+    #[allow(non_camel_case_types)]+    type type_of_event_filter = i16;++    #[cfg(any(+        target_os = "dragonfly",+        target_os = "freebsd",+        target_os = "ios",+        target_os = "macos",+        target_os = "openbsd"+    ))]+    #[allow(non_camel_case_types)]+    type type_of_udata = *mut libc::c_void;+    #[cfg(any(+        target_os = "dragonfly",+        target_os = "freebsd",+        target_os = "ios",+        target_os = "macos"+    ))]+    #[allow(non_camel_case_types)]+    type type_of_data = libc::intptr_t;+    #[cfg(any(target_os = "netbsd"))]+    #[allow(non_camel_case_types)]+    type type_of_udata = libc::intptr_t;+    #[cfg(any(target_os = "netbsd", target_os = "openbsd"))]+    #[allow(non_camel_case_types)]+    type type_of_data = libc::int64_t;++    #[derive(Clone, Copy)]+    #[repr(C)]+    pub struct KEvent(libc::kevent);++    unsafe impl Send for KEvent {}++    impl KEvent {+        pub fn new(+            ident: libc::uintptr_t,+            filter: EventFilter,+            flags: EventFlag,+            fflags: FilterFlag,+            data: libc::intptr_t,+            udata: libc::intptr_t,+        ) -> KEvent {+            KEvent(libc::kevent {+                ident,+                filter: filter as type_of_event_filter,+                flags,+                fflags,+                data: data as type_of_data,+                udata: udata as type_of_udata,+            })+        }++        pub fn filter(&self) -> EventFilter {+            unsafe { std::mem::transmute(self.0.filter as type_of_event_filter) }+        }++        pub fn flags(&self) -> EventFlag {+            self.0.flags+        }++        pub fn data(&self) -> libc::intptr_t {+            self.0.data as libc::intptr_t+        }++        pub fn udata(&self) -> libc::intptr_t {+            self.0.udata as libc::intptr_t+        }+    }++    #[cfg(any(+        target_os = "dragonfly",+        target_os = "freebsd",+        target_os = "ios",+        target_os = "macos",+        target_os = "openbsd"+    ))]+    pub type EventFlag = u16;+    #[cfg(any(target_os = "netbsd"))]+    pub type EventFlag = u32;++    pub type FilterFlag = u32;++    #[cfg(target_os = "netbsd")]+    pub type EventFilter = u32;+    #[cfg(not(target_os = "netbsd"))]+    pub type EventFilter = i16;++    pub fn kqueue() -> Result<RawFd, std::io::Error> {+        let res = unsafe { libc::kqueue() };++        check_err(res)+    }++    pub fn kevent_ts(+        kq: RawFd,+        changelist: &[KEvent],+        eventlist: &mut [KEvent],+        timeout_opt: Option<libc::timespec>,+    ) -> Result<usize, std::io::Error> {+        let res = unsafe {+            libc::kevent(+                kq,+                changelist.as_ptr() as *const libc::kevent,+                changelist.len() as type_of_nchanges,+                eventlist.as_mut_ptr() as *mut libc::kevent,+                eventlist.len() as type_of_nchanges,+                if let Some(ref timeout) = timeout_opt {+                    timeout as *const libc::timespec+                } else {+                    std::ptr::null()+                },+            )+        };++        check_err(res).map(|r| r as usize)+    }+}++#[cfg(any(target_os = "linux", target_os = "android", target_os = "illumos"))]+/// Epoll.+pub mod epoll {+    use super::check_err;+    use std::os::unix::io::RawFd;++    #[macro_use]+    mod dlsym {+        // Based on https://github.com/tokio-rs/mio/blob/v0.6.x/src/sys/unix/dlsym.rs+        // I feel very sad including this code, but I have not found a better way+        // to check for the existence of a symbol in Rust.++        use std::marker;+        use std::mem;+        use std::sync::atomic::{AtomicUsize, Ordering};++        macro_rules! dlsym {+            (fn $name:ident($($t:ty),*) -> $ret:ty) => (+                #[allow(bad_style)]+                static $name: $crate::sys::epoll::dlsym::DlSym<unsafe extern fn($($t),*) -> $ret> =+                    $crate::sys::epoll::dlsym::DlSym {+                        name: concat!(stringify!($name), "\0"),+                        addr: std::sync::atomic::AtomicUsize::new(0),+                        _marker: std::marker::PhantomData,+                    };+            )+        }++        pub struct DlSym<F> {+            pub name: &'static str,+            pub addr: AtomicUsize,+            pub _marker: marker::PhantomData<F>,+        }++        impl<F> DlSym<F> {+            pub fn get(&self) -> Option<&F> {+                assert_eq!(mem::size_of::<F>(), mem::size_of::<usize>());+                unsafe {+                    if self.addr.load(Ordering::SeqCst) == 0 {+                        self.addr.store(fetch(self.name), Ordering::SeqCst);+                    }+                    if self.addr.load(Ordering::SeqCst) == 1 {+                        None+                    } else {+                        mem::transmute::<&AtomicUsize, Option<&F>>(&self.addr)+                    }+                }+            }+        }++        unsafe fn fetch(name: &str) -> usize {+            assert_eq!(name.as_bytes()[name.len() - 1], 0);+            match libc::dlsym(libc::RTLD_DEFAULT, name.as_ptr() as *const _) as usize {+                0 => 1,+                n => n,+            }+        }+    }++    #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]+    #[repr(i32)]+    pub enum EpollOp {+        EpollCtlAdd = libc::EPOLL_CTL_ADD,+        EpollCtlDel = libc::EPOLL_CTL_DEL,+        EpollCtlMod = libc::EPOLL_CTL_MOD,+    }++    pub type EpollFlags = libc::c_int;++    pub fn epoll_create1() -> Result<RawFd, std::io::Error> {+        // According to libuv, `EPOLL_CLOEXEC` is not defined on Android API <+        // 21. But `EPOLL_CLOEXEC` is an alias for `O_CLOEXEC` on that platform,+        // so we use it instead.+        #[cfg(target_os = "android")]+        const CLOEXEC: libc::c_int = libc::O_CLOEXEC;+        #[cfg(not(target_os = "android"))]+        const CLOEXEC: libc::c_int = libc::EPOLL_CLOEXEC;++        let fd = unsafe {+            // Emulate epoll_create1 if not available.++            dlsym!(fn epoll_create1(libc::c_int) -> libc::c_int);

I need to support android api 16-21 which does not have epoll_create1, only epoll_create

dignifiedquire

comment created time in 8 days

issue commentlibp2p/rust-libp2p

CI failing because of async-std 1.6

please let me know if there is anything that needs fixing on the async-std side, 1.6 was a big change but trying hard not to break codes

tomaka

comment created time in 8 days

push eventdeltachat/deltachat-core-rust

dignifiedquire

commit sha 13811c06ee0972a627cf04cd86796ada191c849b

mark generate_key as blocking

view details

push time in 8 days

push eventjbr/surf

dignifiedquire

commit sha 9f463a3b09296ba230a668018a03d42e3dd8de28

docs: update features list

view details

push time in 8 days

push eventKeruspe/async-sse

dignifiedquire

commit sha c37ba88d3823cb76dd0757ef927815d0b06c260a

update to latest

view details

push time in 8 days

more