use crate::constants::Event; use crate::context::Context; use crate::dc_e2ee::*; use crate::dc_job::*; use crate::dc_log::*; use crate::dc_loginparam::*; use crate::dc_saxparser::*; use crate::dc_sqlite3::*; use crate::dc_strencode::*; use crate::dc_tools::*; use crate::imap::*; use crate::oauth2::*; use crate::types::*; use crate::x::*; /* ****************************************************************************** * Configure folders ******************************************************************************/ #[derive(Copy, Clone)] #[repr(C)] pub struct dc_imapfolder_t { pub name_to_select: *mut libc::c_char, pub name_utf8: *mut libc::c_char, pub meaning: libc::c_int, } /* ****************************************************************************** * Thunderbird's Autoconfigure ******************************************************************************/ /* documentation: https://developer.mozilla.org/en-US/docs/Mozilla/Thunderbird/Autoconfiguration */ #[derive(Copy, Clone)] #[repr(C)] pub struct moz_autoconfigure_t { pub in_0: *const dc_loginparam_t, pub in_emaildomain: *mut libc::c_char, pub in_emaillocalpart: *mut libc::c_char, pub out: *mut dc_loginparam_t, pub out_imap_set: libc::c_int, pub out_smtp_set: libc::c_int, pub tag_server: libc::c_int, pub tag_config: libc::c_int, } /* ****************************************************************************** * Outlook's Autodiscover ******************************************************************************/ #[derive(Copy, Clone)] #[repr(C)] pub struct outlk_autodiscover_t { pub in_0: *const dc_loginparam_t, pub out: *mut dc_loginparam_t, pub out_imap_set: libc::c_int, pub out_smtp_set: libc::c_int, pub tag_config: libc::c_int, pub config: [*mut libc::c_char; 6], pub redirect: *mut libc::c_char, } // connect pub unsafe fn dc_configure(context: &Context) { if 0 != dc_has_ongoing(context) { dc_log_warning( context, 0i32, b"There is already another ongoing process running.\x00" as *const u8 as *const libc::c_char, ); return; } dc_job_kill_action(context, 900i32); dc_job_add(context, 900i32, 0i32, 0 as *const libc::c_char, 0i32); } pub unsafe fn dc_has_ongoing(context: &Context) -> libc::c_int { let s_a = context.running_state.clone(); let s = s_a.read().unwrap(); if s.ongoing_running || !s.shall_stop_ongoing { 1 } else { 0 } } pub unsafe fn dc_is_configured(context: &Context) -> libc::c_int { return if 0 != dc_sqlite3_get_config_int( context, &context.sql.clone().read().unwrap(), b"configured\x00" as *const u8 as *const libc::c_char, 0i32, ) { 1i32 } else { 0i32 }; } pub unsafe fn dc_stop_ongoing_process(context: &Context) { let s_a = context.running_state.clone(); let mut s = s_a.write().unwrap(); if s.ongoing_running && !s.shall_stop_ongoing { dc_log_info( context, 0i32, b"Signaling the ongoing process to stop ASAP.\x00" as *const u8 as *const libc::c_char, ); s.shall_stop_ongoing = true; } else { dc_log_info( context, 0i32, b"No ongoing process to stop.\x00" as *const u8 as *const libc::c_char, ); }; } // the other dc_job_do_DC_JOB_*() functions are declared static in the c-file pub unsafe fn dc_job_do_DC_JOB_CONFIGURE_IMAP(context: &Context, _job: *mut dc_job_t) { let flags: libc::c_int; let mut current_block: u64; let mut success: libc::c_int = 0i32; let mut imap_connected_here: libc::c_int = 0i32; let mut smtp_connected_here: libc::c_int = 0i32; let mut ongoing_allocated_here: libc::c_int = 0i32; let mvbox_folder: *mut libc::c_char = 0 as *mut libc::c_char; let mut param: *mut dc_loginparam_t = 0 as *mut dc_loginparam_t; /* just a pointer inside param, must not be freed! */ let mut param_domain: *mut libc::c_char; let mut param_addr_urlencoded: *mut libc::c_char = 0 as *mut libc::c_char; let mut param_autoconfig: *mut dc_loginparam_t = 0 as *mut dc_loginparam_t; if !(0 == dc_alloc_ongoing(context)) { ongoing_allocated_here = 1i32; if 0 == dc_sqlite3_is_open(&context.sql.clone().read().unwrap()) { dc_log_error( context, 0i32, b"Cannot configure, database not opened.\x00" as *const u8 as *const libc::c_char, ); } else { context.inbox.read().unwrap().disconnect(context); context .sentbox_thread .read() .unwrap() .imap .disconnect(context); context .mvbox_thread .read() .unwrap() .imap .disconnect(context); context.smtp.clone().lock().unwrap().disconnect(); dc_log_info( context, 0i32, b"Configure ...\x00" as *const u8 as *const libc::c_char, ); let s_a = context.running_state.clone(); let s = s_a.read().unwrap(); if !s.shall_stop_ongoing { (context.cb)( context, Event::CONFIGURE_PROGRESS, (if 0i32 < 1i32 { 1i32 } else if 0i32 > 999i32 { 999i32 } else { 0i32 }) as uintptr_t, 0i32 as uintptr_t, ); param = dc_loginparam_new(); dc_loginparam_read( context, param, &context.sql.clone().read().unwrap(), b"\x00" as *const u8 as *const libc::c_char, ); if (*param).addr.is_null() { dc_log_error( context, 0i32, b"Please enter the email address.\x00" as *const u8 as *const libc::c_char, ); } else { dc_trim((*param).addr); if 0 != (*param).server_flags & 0x2i32 { // 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. if s.shall_stop_ongoing { current_block = 2927484062889439186; } else { (context.cb)( context, Event::CONFIGURE_PROGRESS, (if 10i32 < 1i32 { 1i32 } else if 10i32 > 999i32 { 999i32 } else { 10i32 }) as uintptr_t, 0i32 as uintptr_t, ); let oauth2_addr = dc_get_oauth2_addr( context, to_str((*param).addr), to_str((*param).mail_pw), ); if oauth2_addr.is_some() { free((*param).addr as *mut libc::c_void); (*param).addr = strdup(to_cstring(oauth2_addr.unwrap()).as_ptr()); dc_sqlite3_set_config( context, &context.sql.clone().read().unwrap(), b"addr\x00" as *const u8 as *const libc::c_char, (*param).addr, ); } if s.shall_stop_ongoing { current_block = 2927484062889439186; } else { (context.cb)( context, Event::CONFIGURE_PROGRESS, (if 20i32 < 1i32 { 1i32 } else if 20i32 > 999i32 { 999i32 } else { 20i32 }) as uintptr_t, 0i32 as uintptr_t, ); current_block = 7746103178988627676; } } } else { current_block = 7746103178988627676; } match current_block { 2927484062889439186 => {} _ => { param_domain = strchr((*param).addr, '@' as i32); if param_domain.is_null() || *param_domain.offset(0isize) as libc::c_int == 0i32 { dc_log_error( context, 0i32, b"Bad email-address.\x00" as *const u8 as *const libc::c_char, ); } else { param_domain = param_domain.offset(1isize); param_addr_urlencoded = dc_urlencode((*param).addr); if (*param).mail_pw.is_null() { (*param).mail_pw = dc_strdup(0 as *const libc::c_char) } if !s.shall_stop_ongoing { (context.cb)( context, Event::CONFIGURE_PROGRESS, (if 200i32 < 1i32 { 1i32 } else if 200i32 > 999i32 { 999i32 } else { 200i32 }) as uintptr_t, 0i32 as uintptr_t, ); /* 2. Autoconfig **************************************************************************/ if (*param).mail_server.is_null() && (*param).mail_port == 0i32 && (*param).send_server.is_null() && (*param).send_port == 0i32 && (*param).send_user.is_null() && (*param).server_flags & !0x2i32 == 0i32 { /*&¶m->mail_user ==NULL -- the user can enter a loginname which is used by autoconfig then */ /*&¶m->send_pw ==NULL -- the password cannot be auto-configured and is no criterion for autoconfig or not */ /* flags but OAuth2 avoid autoconfig */ let keep_flags: libc::c_int = (*param).server_flags & 0x2i32; /* A. Search configurations from the domain used in the email-address, prefer encrypted */ if param_autoconfig.is_null() { let url: *mut libc::c_char = dc_mprintf(b"https://autoconfig.%s/mail/config-v1.1.xml?emailaddress=%s\x00" as *const u8 as *const libc::c_char, param_domain, param_addr_urlencoded); param_autoconfig = moz_autoconfigure(context, url, param); free(url as *mut libc::c_void); if s.shall_stop_ongoing { current_block = 2927484062889439186; } else { (context.cb)( context, Event::CONFIGURE_PROGRESS, (if 300i32 < 1i32 { 1i32 } else if 300i32 > 999i32 { 999i32 } else { 300i32 }) as uintptr_t, 0i32 as uintptr_t, ); current_block = 13325891313334703151; } } else { current_block = 13325891313334703151; } match current_block { 2927484062889439186 => {} _ => { if param_autoconfig.is_null() { // the doc does not mention `emailaddress=`, however, Thunderbird adds it, see https://releases.mozilla.org/pub/thunderbird/ , which makes some sense let url_0: *mut libc::c_char = dc_mprintf(b"https://%s/.well-known/autoconfig/mail/config-v1.1.xml?emailaddress=%s\x00" as *const u8 as *const libc::c_char, param_domain, param_addr_urlencoded); param_autoconfig = moz_autoconfigure(context, url_0, param); free(url_0 as *mut libc::c_void); if s.shall_stop_ongoing { current_block = 2927484062889439186; } else { (context.cb)( context, Event::CONFIGURE_PROGRESS, (if 310i32 < 1i32 { 1i32 } else if 310i32 > 999i32 { 999i32 } else { 310i32 }) as uintptr_t, 0i32 as uintptr_t, ); current_block = 5597585068398118923; } } else { current_block = 5597585068398118923; } match current_block { 2927484062889439186 => {} _ => { let mut i: libc::c_int = 0i32; loop { if !(i <= 1i32) { current_block = 12961834331865314435; break; } if param_autoconfig.is_null() { /* Outlook uses always SSL but different domains */ let url_1: *mut libc::c_char = dc_mprintf(b"https://%s%s/autodiscover/autodiscover.xml\x00" as *const u8 as *const libc::c_char, if i == 0i32 { b"\x00" as *const u8 as *const libc::c_char } else { b"autodiscover.\x00" as *const u8 as *const libc::c_char }, param_domain); param_autoconfig = outlk_autodiscover( context, url_1, param, ); free(url_1 as *mut libc::c_void); if s.shall_stop_ongoing { current_block = 2927484062889439186; break; } (context.cb)( context, Event::CONFIGURE_PROGRESS, (if 320i32 + i * 10i32 < 1i32 { 1i32 } else if 320i32 + i * 10i32 > 999i32 { 999i32 } else { 320i32 + i * 10i32 }) as uintptr_t, 0i32 as uintptr_t, ); } i += 1 } match current_block { 2927484062889439186 => {} _ => { if param_autoconfig.is_null() { let url_2: *mut libc::c_char = dc_mprintf(b"http://autoconfig.%s/mail/config-v1.1.xml?emailaddress=%s\x00" as *const u8 as *const libc::c_char, param_domain, param_addr_urlencoded); param_autoconfig = moz_autoconfigure( context, url_2, param, ); free( url_2 as *mut libc::c_void, ); if s.shall_stop_ongoing { current_block = 2927484062889439186; } else { (context.cb)( context, Event::CONFIGURE_PROGRESS, (if 340i32 < 1i32 { 1i32 } else if 340i32 > 999i32 { 999i32 } else { 340i32 }) as uintptr_t, 0i32 as uintptr_t ); current_block = 10778260831612459202; } } else { current_block = 10778260831612459202; } match current_block { 2927484062889439186 => {} _ => { if param_autoconfig .is_null() { // do not transfer the email-address unencrypted let url_3: *mut libc::c_char = dc_mprintf(b"http://%s/.well-known/autoconfig/mail/config-v1.1.xml\x00" as *const u8 as *const libc::c_char, param_domain); param_autoconfig = moz_autoconfigure( context, url_3, param, ); free(url_3 as *mut libc::c_void); if s.shall_stop_ongoing { current_block = 2927484062889439186; } else { (context.cb)(context, Event::CONFIGURE_PROGRESS, (if 350i32 < 1i32 { 1i32 } else if 350i32 > 999i32 { 999i32 } else { 350i32 }) as uintptr_t, 0i32 as uintptr_t); current_block = 5207889489643863322; } } else { current_block = 5207889489643863322; } match current_block { 2927484062889439186 => { } _ => { /* B. If we have no configuration yet, search configuration in Thunderbird's centeral database */ if param_autoconfig .is_null() { /* always SSL for Thunderbird's database */ let url_4: *mut libc::c_char = dc_mprintf(b"https://autoconfig.thunderbird.net/v1.1/%s\x00" as *const u8 as *const libc::c_char, param_domain); param_autoconfig = moz_autoconfigure(context, url_4, param); free(url_4 as *mut libc::c_void); if s.shall_stop_ongoing { current_block = 2927484062889439186; } else { (context.cb)(context, Event::CONFIGURE_PROGRESS, (if 500i32 < 1i32 { 1i32 } else if 500i32 > 999i32 { 999i32 } else { 500i32 }) as uintptr_t, 0i32 as uintptr_t); current_block = 2798392256336243897; } } else { current_block = 2798392256336243897; } match current_block { 2927484062889439186 => { } _ => { if !param_autoconfig.is_null() { let r: *mut libc::c_char = dc_loginparam_get_readable(param_autoconfig); dc_log_info(context, 0i32, b"Got autoconfig: %s\x00" as *const u8 as *const libc::c_char, r); free(r as *mut libc::c_void); if !(*param_autoconfig).mail_user.is_null() { free((*param).mail_user as *mut libc::c_void); (*param).mail_user = dc_strdup_keep_null((*param_autoconfig).mail_user) } (*param).mail_server = dc_strdup_keep_null((*param_autoconfig).mail_server); (*param).mail_port = (*param_autoconfig).mail_port; (*param).send_server = dc_strdup_keep_null((*param_autoconfig).send_server); (*param).send_port = (*param_autoconfig).send_port; (*param).send_user = dc_strdup_keep_null((*param_autoconfig).send_user); (*param).server_flags = (*param_autoconfig).server_flags } (*param).server_flags |= keep_flags; current_block = 3024367268842933116; } } } } } } } } } } } } } else { current_block = 3024367268842933116; } match current_block { 2927484062889439186 => {} _ => { if (*param).mail_server.is_null() { (*param).mail_server = dc_mprintf( b"imap.%s\x00" as *const u8 as *const libc::c_char, param_domain, ) } if (*param).mail_port == 0i32 { (*param).mail_port = if 0 != (*param).server_flags & (0x100i32 | 0x400i32) { 143i32 } else { 993i32 } } if (*param).mail_user.is_null() { (*param).mail_user = dc_strdup((*param).addr) } if (*param).send_server.is_null() && !(*param).mail_server.is_null() { (*param).send_server = dc_strdup((*param).mail_server); if strncmp( (*param).send_server, b"imap.\x00" as *const u8 as *const libc::c_char, 5, ) == 0i32 { memcpy( (*param).send_server as *mut libc::c_void, b"smtp\x00" as *const u8 as *const libc::c_char as *const libc::c_void, 4, ); } } if (*param).send_port == 0i32 { (*param).send_port = if 0 != (*param).server_flags & 0x10000i32 { 587i32 } else if 0 != (*param).server_flags & 0x40000i32 { 25i32 } else { 465i32 } } if (*param).send_user.is_null() && !(*param).mail_user.is_null() { (*param).send_user = dc_strdup((*param).mail_user) } if (*param).send_pw.is_null() && !(*param).mail_pw.is_null() { (*param).send_pw = dc_strdup((*param).mail_pw) } if 0 == dc_exactly_one_bit_set( (*param).server_flags & (0x2i32 | 0x4i32), ) { (*param).server_flags &= !(0x2i32 | 0x4i32); (*param).server_flags |= 0x4i32 } if 0 == dc_exactly_one_bit_set( (*param).server_flags & (0x100i32 | 0x200i32 | 0x400i32), ) { (*param).server_flags &= !(0x100i32 | 0x200i32 | 0x400i32); (*param).server_flags |= if (*param).send_port == 143i32 { 0x100i32 } else { 0x200i32 } } if 0 == dc_exactly_one_bit_set( (*param).server_flags & (0x10000i32 | 0x20000i32 | 0x40000i32), ) { (*param).server_flags &= !(0x10000i32 | 0x20000i32 | 0x40000i32); (*param).server_flags |= if (*param).send_port == 587i32 { 0x10000i32 } else if (*param).send_port == 25i32 { 0x40000i32 } else { 0x20000i32 } } /* do we have a complete configuration? */ if (*param).addr.is_null() || (*param).mail_server.is_null() || (*param).mail_port == 0i32 || (*param).mail_user.is_null() || (*param).mail_pw.is_null() || (*param).send_server.is_null() || (*param).send_port == 0i32 || (*param).send_user.is_null() || (*param).send_pw.is_null() || (*param).server_flags == 0i32 { dc_log_error( context, 0i32, b"Account settings incomplete.\x00" as *const u8 as *const libc::c_char, ); } else if !s.shall_stop_ongoing { (context.cb)( context, Event::CONFIGURE_PROGRESS, (if 600i32 < 1i32 { 1i32 } else if 600i32 > 999i32 { 999i32 } else { 600i32 }) as uintptr_t, 0i32 as uintptr_t, ); /* try to connect to IMAP - if we did not got an autoconfig, do some further tries with different settings and username variations */ let mut username_variation: libc::c_int = 0i32; loop { if !(username_variation <= 1i32) { current_block = 14187386403465544025; break; } let r_0: *mut libc::c_char = dc_loginparam_get_readable(param); dc_log_info( context, 0i32, b"Trying: %s\x00" as *const u8 as *const libc::c_char, r_0, ); free(r_0 as *mut libc::c_void); if 0 != context .inbox .read() .unwrap() .connect(context, param) { current_block = 14187386403465544025; break; } if !param_autoconfig.is_null() { current_block = 2927484062889439186; break; } // probe STARTTLS/993 if s.shall_stop_ongoing { current_block = 2927484062889439186; break; } (context.cb)( context, Event::CONFIGURE_PROGRESS, (if 650i32 + username_variation * 30i32 < 1i32 { 1i32 } else if 650i32 + username_variation * 30i32 > 999i32 { 999i32 } else { 650i32 + username_variation * 30i32 }) as uintptr_t, 0i32 as uintptr_t, ); (*param).server_flags &= !(0x100i32 | 0x200i32 | 0x400i32); (*param).server_flags |= 0x100i32; let r_1: *mut libc::c_char = dc_loginparam_get_readable(param); dc_log_info( context, 0i32, b"Trying: %s\x00" as *const u8 as *const libc::c_char, r_1, ); free(r_1 as *mut libc::c_void); if 0 != context .inbox .read() .unwrap() .connect(context, param) { current_block = 14187386403465544025; break; } // probe STARTTLS/143 if s.shall_stop_ongoing { current_block = 2927484062889439186; break; } (context.cb)( context, Event::CONFIGURE_PROGRESS, (if 660i32 + username_variation * 30i32 < 1i32 { 1i32 } else if 660i32 + username_variation * 30i32 > 999i32 { 999i32 } else { 660i32 + username_variation * 30i32 }) as uintptr_t, 0i32 as uintptr_t, ); (*param).mail_port = 143i32; let r_2: *mut libc::c_char = dc_loginparam_get_readable(param); dc_log_info( context, 0i32, b"Trying: %s\x00" as *const u8 as *const libc::c_char, r_2, ); free(r_2 as *mut libc::c_void); if 0 != context .inbox .read() .unwrap() .connect(context, param) { current_block = 14187386403465544025; break; } if 0 != username_variation { current_block = 2927484062889439186; break; } // next probe round with only the localpart of the email-address as the loginname if s.shall_stop_ongoing { current_block = 2927484062889439186; break; } (context.cb)( context, Event::CONFIGURE_PROGRESS, (if 670i32 + username_variation * 30i32 < 1i32 { 1i32 } else if 670i32 + username_variation * 30i32 > 999i32 { 999i32 } else { 670i32 + username_variation * 30i32 }) as uintptr_t, 0i32 as uintptr_t, ); (*param).server_flags &= !(0x100i32 | 0x200i32 | 0x400i32); (*param).server_flags |= 0x200i32; (*param).mail_port = 993i32; let mut at: *mut libc::c_char = strchr((*param).mail_user, '@' as i32); if !at.is_null() { *at = 0i32 as libc::c_char } at = strchr((*param).send_user, '@' as i32); if !at.is_null() { *at = 0i32 as libc::c_char } username_variation += 1 } match current_block { 2927484062889439186 => {} _ => { imap_connected_here = 1i32; if !s.shall_stop_ongoing { (context.cb)( context, Event::CONFIGURE_PROGRESS, (if 800i32 < 1i32 { 1i32 } else if 800i32 > 999i32 { 999i32 } else { 800i32 }) as uintptr_t, 0i32 as uintptr_t, ); /* try to connect to SMTP - if we did not got an autoconfig, the first try was SSL-465 and we do a second try with STARTTLS-587 */ if 0 == context .smtp .clone() .lock() .unwrap() .connect(context, param) { if !param_autoconfig.is_null() { current_block = 2927484062889439186; } else if s.shall_stop_ongoing { current_block = 2927484062889439186; } else { (context.cb)( context, Event::CONFIGURE_PROGRESS, (if 850i32 < 1i32 { 1i32 } else if 850i32 > 999i32 { 999i32 } else { 850i32 }) as uintptr_t, 0i32 as uintptr_t, ); (*param).server_flags &= !(0x10000i32 | 0x20000i32 | 0x40000i32); (*param).server_flags |= 0x10000i32; (*param).send_port = 587i32; let r_3: *mut libc::c_char = dc_loginparam_get_readable( param, ); dc_log_info( context, 0i32, b"Trying: %s\x00" as *const u8 as *const libc::c_char, r_3, ); free(r_3 as *mut libc::c_void); if 0 == context .smtp .clone() .lock() .unwrap() .connect(context, param) { if s.shall_stop_ongoing { current_block = 2927484062889439186; } else { (context.cb)(context, Event::CONFIGURE_PROGRESS, (if 860i32 < 1i32 { 1i32 } else if 860i32 > 999i32 { 999i32 } else { 860i32 }) as uintptr_t, 0i32 as uintptr_t); (*param) .server_flags &= !(0x10000i32 | 0x20000i32 | 0x40000i32); (*param) .server_flags |= 0x10000i32; (*param).send_port = 25i32; let r_4: *mut libc::c_char = dc_loginparam_get_readable(param); dc_log_info(context, 0i32, b"Trying: %s\x00" as *const u8 as *const libc::c_char, r_4); free(r_4 as *mut libc::c_void); if 0 == context .smtp .clone() .lock() .unwrap() .connect( context, param, ) { current_block = 2927484062889439186; } else { current_block = 5083741289379115417; } } } else { current_block = 5083741289379115417; } } } else { current_block = 5083741289379115417; } match current_block { 2927484062889439186 => {} _ => { smtp_connected_here = 1i32; if !s.shall_stop_ongoing { (context.cb)(context, Event::CONFIGURE_PROGRESS, (if 900i32 < 1i32 { 1i32 } else if 900i32 > 999i32 { 999i32 } else { 900i32 }) as uintptr_t, 0i32 as uintptr_t); flags = if 0 != dc_sqlite3_get_config_int(context, &context.sql.clone().read().unwrap(), b"mvbox_watch\x00" as *const u8 as *const libc::c_char, 1i32) || 0 != dc_sqlite3_get_config_int(context, &context.sql.clone().read().unwrap(), b"mvbox_move\x00" as *const u8 as *const libc::c_char, 1i32) { 0x1i32 } else { 0i32 }; context .inbox .read() .unwrap() .configure_folders( context, flags, ); if !s.shall_stop_ongoing { (context.cb)(context, Event::CONFIGURE_PROGRESS, (if 910i32 < 1i32 { 1i32 } else if 910i32 > 999i32 { 999i32 } else { 910i32 }) as uintptr_t, 0i32 as uintptr_t); dc_loginparam_write(context, param, &context.sql.clone().read().unwrap(), b"configured_\x00" as *const u8 as *const libc::c_char); dc_sqlite3_set_config_int(context, &context.sql.clone().read().unwrap(), b"configured\x00" as *const u8 as *const libc::c_char, 1i32); if !s.shall_stop_ongoing { (context.cb)(context, Event::CONFIGURE_PROGRESS, (if 920i32 < 1i32 { 1i32 } else if 920i32 > 999i32 { 999i32 } else { 920i32 }) as uintptr_t, 0i32 as uintptr_t); dc_ensure_secret_key_exists(context); success = 1i32; dc_log_info(context, 0i32, b"Configure completed.\x00" as *const u8 as *const libc::c_char); if !s.shall_stop_ongoing { (context.cb)(context, Event::CONFIGURE_PROGRESS, (if 940i32 < 1i32 { 1i32 } else if 940i32 > 999i32 { 999i32 } else { 940i32 }) as uintptr_t, 0i32 as uintptr_t); } } } } } } } } } } } } } } } } } } } } if 0 != imap_connected_here { context.inbox.read().unwrap().disconnect(context); } if 0 != smtp_connected_here { context.smtp.clone().lock().unwrap().disconnect(); } dc_loginparam_unref(param); dc_loginparam_unref(param_autoconfig); free(param_addr_urlencoded as *mut libc::c_void); if 0 != ongoing_allocated_here { dc_free_ongoing(context); } free(mvbox_folder as *mut libc::c_void); (context.cb)( context, Event::CONFIGURE_PROGRESS, (if 0 != success { 1000i32 } else { 0i32 }) as uintptr_t, 0i32 as uintptr_t, ); } pub unsafe fn dc_free_ongoing(context: &Context) { let s_a = context.running_state.clone(); let mut s = s_a.write().unwrap(); s.ongoing_running = false; s.shall_stop_ongoing = true; } unsafe fn moz_autoconfigure( context: &Context, url: *const libc::c_char, param_in: *const dc_loginparam_t, ) -> *mut dc_loginparam_t { let p: *mut libc::c_char; let mut saxparser: dc_saxparser_t; let xml_raw: *mut libc::c_char; let mut moz_ac: moz_autoconfigure_t = moz_autoconfigure_t { in_0: 0 as *const dc_loginparam_t, in_emaildomain: 0 as *mut libc::c_char, in_emaillocalpart: 0 as *mut libc::c_char, out: 0 as *mut dc_loginparam_t, out_imap_set: 0, out_smtp_set: 0, tag_server: 0, tag_config: 0, }; memset( &mut moz_ac as *mut moz_autoconfigure_t as *mut libc::c_void, 0i32, ::std::mem::size_of::(), ); xml_raw = read_autoconf_file(context, url); if !xml_raw.is_null() { moz_ac.in_0 = param_in; moz_ac.in_emaillocalpart = dc_strdup((*param_in).addr); p = strchr(moz_ac.in_emaillocalpart, '@' as i32); if !p.is_null() { *p = 0i32 as libc::c_char; moz_ac.in_emaildomain = dc_strdup(p.offset(1isize)); moz_ac.out = dc_loginparam_new(); saxparser = dc_saxparser_t { starttag_cb: None, endtag_cb: None, text_cb: None, userdata: 0 as *mut libc::c_void, }; dc_saxparser_init( &mut saxparser, &mut moz_ac as *mut moz_autoconfigure_t as *mut libc::c_void, ); dc_saxparser_set_tag_handler( &mut saxparser, Some(moz_autoconfigure_starttag_cb), Some(moz_autoconfigure_endtag_cb), ); dc_saxparser_set_text_handler(&mut saxparser, Some(moz_autoconfigure_text_cb)); dc_saxparser_parse(&mut saxparser, xml_raw); if (*moz_ac.out).mail_server.is_null() || (*moz_ac.out).mail_port == 0i32 || (*moz_ac.out).send_server.is_null() || (*moz_ac.out).send_port == 0i32 { let r: *mut libc::c_char = dc_loginparam_get_readable(moz_ac.out); dc_log_warning( context, 0i32, b"Bad or incomplete autoconfig: %s\x00" as *const u8 as *const libc::c_char, r, ); free(r as *mut libc::c_void); dc_loginparam_unref(moz_ac.out); moz_ac.out = 0 as *mut dc_loginparam_t } } } free(xml_raw as *mut libc::c_void); free(moz_ac.in_emaildomain as *mut libc::c_void); free(moz_ac.in_emaillocalpart as *mut libc::c_void); return moz_ac.out; } unsafe fn moz_autoconfigure_text_cb( userdata: *mut libc::c_void, text: *const libc::c_char, _len: libc::c_int, ) { let mut moz_ac: *mut moz_autoconfigure_t = userdata as *mut moz_autoconfigure_t; let mut val: *mut libc::c_char = dc_strdup(text); dc_trim(val); dc_str_replace( &mut val, b"%EMAILADDRESS%\x00" as *const u8 as *const libc::c_char, (*(*moz_ac).in_0).addr, ); dc_str_replace( &mut val, b"%EMAILLOCALPART%\x00" as *const u8 as *const libc::c_char, (*moz_ac).in_emaillocalpart, ); dc_str_replace( &mut val, b"%EMAILDOMAIN%\x00" as *const u8 as *const libc::c_char, (*moz_ac).in_emaildomain, ); if (*moz_ac).tag_server == 1i32 { match (*moz_ac).tag_config { 10 => { free((*(*moz_ac).out).mail_server as *mut libc::c_void); (*(*moz_ac).out).mail_server = val; val = 0 as *mut libc::c_char } 11 => (*(*moz_ac).out).mail_port = dc_atoi_null_is_0(val), 12 => { free((*(*moz_ac).out).mail_user as *mut libc::c_void); (*(*moz_ac).out).mail_user = val; val = 0 as *mut libc::c_char } 13 => { if strcasecmp(val, b"ssl\x00" as *const u8 as *const libc::c_char) == 0i32 { (*(*moz_ac).out).server_flags |= 0x200i32 } if strcasecmp(val, b"starttls\x00" as *const u8 as *const libc::c_char) == 0i32 { (*(*moz_ac).out).server_flags |= 0x100i32 } if strcasecmp(val, b"plain\x00" as *const u8 as *const libc::c_char) == 0i32 { (*(*moz_ac).out).server_flags |= 0x400i32 } } _ => {} } } else if (*moz_ac).tag_server == 2i32 { match (*moz_ac).tag_config { 10 => { free((*(*moz_ac).out).send_server as *mut libc::c_void); (*(*moz_ac).out).send_server = val; val = 0 as *mut libc::c_char } 11 => (*(*moz_ac).out).send_port = to_str(val).parse().unwrap_or_default(), 12 => { free((*(*moz_ac).out).send_user as *mut libc::c_void); (*(*moz_ac).out).send_user = val; val = 0 as *mut libc::c_char } 13 => { if strcasecmp(val, b"ssl\x00" as *const u8 as *const libc::c_char) == 0i32 { (*(*moz_ac).out).server_flags |= 0x20000i32 } if strcasecmp(val, b"starttls\x00" as *const u8 as *const libc::c_char) == 0i32 { (*(*moz_ac).out).server_flags |= 0x10000i32 } if strcasecmp(val, b"plain\x00" as *const u8 as *const libc::c_char) == 0i32 { (*(*moz_ac).out).server_flags |= 0x40000i32 } } _ => {} } } free(val as *mut libc::c_void); } unsafe fn moz_autoconfigure_endtag_cb(userdata: *mut libc::c_void, tag: *const libc::c_char) { let mut moz_ac: *mut moz_autoconfigure_t = userdata as *mut moz_autoconfigure_t; if strcmp( tag, b"incomingserver\x00" as *const u8 as *const libc::c_char, ) == 0i32 { (*moz_ac).tag_server = 0i32; (*moz_ac).tag_config = 0i32; (*moz_ac).out_imap_set = 1i32 } else if strcmp( tag, b"outgoingserver\x00" as *const u8 as *const libc::c_char, ) == 0i32 { (*moz_ac).tag_server = 0i32; (*moz_ac).tag_config = 0i32; (*moz_ac).out_smtp_set = 1i32 } else { (*moz_ac).tag_config = 0i32 }; } unsafe fn moz_autoconfigure_starttag_cb( userdata: *mut libc::c_void, tag: *const libc::c_char, attr: *mut *mut libc::c_char, ) { let mut moz_ac: *mut moz_autoconfigure_t = userdata as *mut moz_autoconfigure_t; let mut p1: *const libc::c_char = 0 as *const libc::c_char; if strcmp( tag, b"incomingserver\x00" as *const u8 as *const libc::c_char, ) == 0i32 { (*moz_ac).tag_server = if (*moz_ac).out_imap_set == 0i32 && { p1 = dc_attr_find(attr, b"type\x00" as *const u8 as *const libc::c_char); !p1.is_null() } && strcasecmp(p1, b"imap\x00" as *const u8 as *const libc::c_char) == 0i32 { 1i32 } else { 0i32 }; (*moz_ac).tag_config = 0i32 } else if strcmp( tag, b"outgoingserver\x00" as *const u8 as *const libc::c_char, ) == 0i32 { (*moz_ac).tag_server = if (*moz_ac).out_smtp_set == 0i32 { 2i32 } else { 0i32 }; (*moz_ac).tag_config = 0i32 } else if strcmp(tag, b"hostname\x00" as *const u8 as *const libc::c_char) == 0i32 { (*moz_ac).tag_config = 10i32 } else if strcmp(tag, b"port\x00" as *const u8 as *const libc::c_char) == 0i32 { (*moz_ac).tag_config = 11i32 } else if strcmp(tag, b"sockettype\x00" as *const u8 as *const libc::c_char) == 0i32 { (*moz_ac).tag_config = 13i32 } else if strcmp(tag, b"username\x00" as *const u8 as *const libc::c_char) == 0i32 { (*moz_ac).tag_config = 12i32 }; } fn read_autoconf_file(context: &Context, url: *const libc::c_char) -> *mut libc::c_char { info!(context, 0, "Testing {} ...", to_string(url)); match reqwest::Client::new() .get(to_str(url)) .send() .and_then(|mut res| res.text()) { Ok(res) => unsafe { libc::strdup(to_cstring(res).as_ptr()) }, Err(_err) => { info!(context, 0, "Can\'t read file.",); std::ptr::null_mut() } } } unsafe fn outlk_autodiscover( context: &Context, url__: *const libc::c_char, param_in: *const dc_loginparam_t, ) -> *mut dc_loginparam_t { let current_block: u64; let mut xml_raw: *mut libc::c_char = 0 as *mut libc::c_char; let mut url: *mut libc::c_char = dc_strdup(url__); let mut outlk_ad: outlk_autodiscover_t = outlk_autodiscover_t { in_0: 0 as *const dc_loginparam_t, out: 0 as *mut dc_loginparam_t, out_imap_set: 0, out_smtp_set: 0, tag_config: 0, config: [0 as *mut libc::c_char; 6], redirect: 0 as *mut libc::c_char, }; let mut i: libc::c_int = 0; loop { if !(i < 10i32) { current_block = 11584701595673473500; break; } memset( &mut outlk_ad as *mut outlk_autodiscover_t as *mut libc::c_void, 0i32, ::std::mem::size_of::(), ); xml_raw = read_autoconf_file(context, url); if xml_raw.is_null() { current_block = 3070887585260837332; break; } outlk_ad.in_0 = param_in; outlk_ad.out = dc_loginparam_new(); let mut saxparser: dc_saxparser_t = dc_saxparser_t { starttag_cb: None, endtag_cb: None, text_cb: None, userdata: 0 as *mut libc::c_void, }; dc_saxparser_init( &mut saxparser, &mut outlk_ad as *mut outlk_autodiscover_t as *mut libc::c_void, ); dc_saxparser_set_tag_handler( &mut saxparser, Some(outlk_autodiscover_starttag_cb), Some(outlk_autodiscover_endtag_cb), ); dc_saxparser_set_text_handler(&mut saxparser, Some(outlk_autodiscover_text_cb)); dc_saxparser_parse(&mut saxparser, xml_raw); if !(!outlk_ad.config[5usize].is_null() && 0 != *outlk_ad.config[5usize].offset(0isize) as libc::c_int) { current_block = 11584701595673473500; break; } free(url as *mut libc::c_void); url = dc_strdup(outlk_ad.config[5usize]); dc_loginparam_unref(outlk_ad.out); outlk_clean_config(&mut outlk_ad); free(xml_raw as *mut libc::c_void); xml_raw = 0 as *mut libc::c_char; i += 1 } match current_block { 11584701595673473500 => { if (*outlk_ad.out).mail_server.is_null() || (*outlk_ad.out).mail_port == 0i32 || (*outlk_ad.out).send_server.is_null() || (*outlk_ad.out).send_port == 0i32 { let r: *mut libc::c_char = dc_loginparam_get_readable(outlk_ad.out); dc_log_warning( context, 0i32, b"Bad or incomplete autoconfig: %s\x00" as *const u8 as *const libc::c_char, r, ); free(r as *mut libc::c_void); dc_loginparam_unref(outlk_ad.out); outlk_ad.out = 0 as *mut dc_loginparam_t } } _ => {} } free(url as *mut libc::c_void); free(xml_raw as *mut libc::c_void); outlk_clean_config(&mut outlk_ad); return outlk_ad.out; } unsafe fn outlk_clean_config(mut outlk_ad: *mut outlk_autodiscover_t) { let mut i: libc::c_int = 0; while i < 6i32 { free((*outlk_ad).config[i as usize] as *mut libc::c_void); (*outlk_ad).config[i as usize] = 0 as *mut libc::c_char; i += 1 } } unsafe fn outlk_autodiscover_text_cb( userdata: *mut libc::c_void, text: *const libc::c_char, _len: libc::c_int, ) { let mut outlk_ad: *mut outlk_autodiscover_t = userdata as *mut outlk_autodiscover_t; let val: *mut libc::c_char = dc_strdup(text); dc_trim(val); free((*outlk_ad).config[(*outlk_ad).tag_config as usize] as *mut libc::c_void); (*outlk_ad).config[(*outlk_ad).tag_config as usize] = val; } unsafe fn outlk_autodiscover_endtag_cb(userdata: *mut libc::c_void, tag: *const libc::c_char) { let mut outlk_ad: *mut outlk_autodiscover_t = userdata as *mut outlk_autodiscover_t; if strcmp(tag, b"protocol\x00" as *const u8 as *const libc::c_char) == 0i32 { if !(*outlk_ad).config[1usize].is_null() { let port: libc::c_int = dc_atoi_null_is_0((*outlk_ad).config[3usize]); let ssl_on: libc::c_int = (!(*outlk_ad).config[4usize].is_null() && strcasecmp( (*outlk_ad).config[4usize], b"on\x00" as *const u8 as *const libc::c_char, ) == 0i32) as libc::c_int; let ssl_off: libc::c_int = (!(*outlk_ad).config[4usize].is_null() && strcasecmp( (*outlk_ad).config[4usize], b"off\x00" as *const u8 as *const libc::c_char, ) == 0i32) as libc::c_int; if strcasecmp( (*outlk_ad).config[1usize], b"imap\x00" as *const u8 as *const libc::c_char, ) == 0i32 && (*outlk_ad).out_imap_set == 0i32 { (*(*outlk_ad).out).mail_server = dc_strdup_keep_null((*outlk_ad).config[2usize]); (*(*outlk_ad).out).mail_port = port; if 0 != ssl_on { (*(*outlk_ad).out).server_flags |= 0x200i32 } else if 0 != ssl_off { (*(*outlk_ad).out).server_flags |= 0x400i32 } (*outlk_ad).out_imap_set = 1i32 } else if strcasecmp( (*outlk_ad).config[1usize], b"smtp\x00" as *const u8 as *const libc::c_char, ) == 0i32 && (*outlk_ad).out_smtp_set == 0i32 { (*(*outlk_ad).out).send_server = dc_strdup_keep_null((*outlk_ad).config[2usize]); (*(*outlk_ad).out).send_port = port; if 0 != ssl_on { (*(*outlk_ad).out).server_flags |= 0x20000i32 } else if 0 != ssl_off { (*(*outlk_ad).out).server_flags |= 0x40000i32 } (*outlk_ad).out_smtp_set = 1i32 } } outlk_clean_config(outlk_ad); } (*outlk_ad).tag_config = 0i32; } unsafe fn outlk_autodiscover_starttag_cb( userdata: *mut libc::c_void, tag: *const libc::c_char, _attr: *mut *mut libc::c_char, ) { let mut outlk_ad: *mut outlk_autodiscover_t = userdata as *mut outlk_autodiscover_t; if strcmp(tag, b"protocol\x00" as *const u8 as *const libc::c_char) == 0i32 { outlk_clean_config(outlk_ad); } else if strcmp(tag, b"type\x00" as *const u8 as *const libc::c_char) == 0i32 { (*outlk_ad).tag_config = 1i32 } else if strcmp(tag, b"server\x00" as *const u8 as *const libc::c_char) == 0i32 { (*outlk_ad).tag_config = 2i32 } else if strcmp(tag, b"port\x00" as *const u8 as *const libc::c_char) == 0i32 { (*outlk_ad).tag_config = 3i32 } else if strcmp(tag, b"ssl\x00" as *const u8 as *const libc::c_char) == 0i32 { (*outlk_ad).tag_config = 4i32 } else if strcmp(tag, b"redirecturl\x00" as *const u8 as *const libc::c_char) == 0i32 { (*outlk_ad).tag_config = 5i32 }; } pub unsafe fn dc_alloc_ongoing(context: &Context) -> libc::c_int { if 0 != dc_has_ongoing(context) { dc_log_warning( context, 0i32, b"There is already another ongoing process running.\x00" as *const u8 as *const libc::c_char, ); return 0i32; } let s_a = context.running_state.clone(); let mut s = s_a.write().unwrap(); s.ongoing_running = true; s.shall_stop_ongoing = false; 1 } pub unsafe fn dc_connect_to_configured_imap(context: &Context, imap: &Imap) -> libc::c_int { let mut ret_connected: libc::c_int = 0i32; let param: *mut dc_loginparam_t = dc_loginparam_new(); if imap.is_connected() { ret_connected = 1i32 } else if dc_sqlite3_get_config_int( context, &context.sql.clone().read().unwrap(), b"configured\x00" as *const u8 as *const libc::c_char, 0i32, ) == 0i32 { dc_log_warning( context, 0i32, b"Not configured, cannot connect.\x00" as *const u8 as *const libc::c_char, ); } else { dc_loginparam_read( context, param, &context.sql.clone().read().unwrap(), b"configured_\x00" as *const u8 as *const libc::c_char, ); /*the trailing underscore is correct*/ if !(0 == imap.connect(context, param)) { ret_connected = 2i32; } } dc_loginparam_unref(param); ret_connected }