mirror of
https://github.com/chatmail/core.git
synced 2026-09-22 04:58:47 +03:00
Compare commits
21 Commits
v2.53.0
...
feat/async
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9396a09505 | ||
|
|
cfba76d600 | ||
|
|
0e953d18d0 | ||
|
|
50aa68e047 | ||
|
|
0bf32dada8 | ||
|
|
b5075a7122 | ||
|
|
3dc589788c | ||
|
|
ba2b66d07a | ||
|
|
a5a12d1f72 | ||
|
|
131f54fbf1 | ||
|
|
01fe782fa0 | ||
|
|
1077cf5e99 | ||
|
|
ca698f9164 | ||
|
|
99201027e2 | ||
|
|
d607d35abc | ||
|
|
3d790cbfca | ||
|
|
68b2707d12 | ||
|
|
6066821b50 | ||
|
|
fe695c0f95 | ||
|
|
7bf13f3f89 | ||
|
|
3b3992daed |
@@ -15,7 +15,7 @@ restore-workspace: &restore-workspace
|
|||||||
restore-cache: &restore-cache
|
restore-cache: &restore-cache
|
||||||
restore_cache:
|
restore_cache:
|
||||||
keys:
|
keys:
|
||||||
- cargo-v2-{{ checksum "rust-toolchain" }}-{{ checksum "Cargo.toml" }}-{{ checksum "Cargo.lock" }}-{{ arch }}
|
- cargo-v3-{{ checksum "rust-toolchain" }}-{{ checksum "Cargo.toml" }}-{{ checksum "Cargo.lock" }}-{{ arch }}
|
||||||
- repo-source-{{ .Branch }}-{{ .Revision }}
|
- repo-source-{{ .Branch }}-{{ .Revision }}
|
||||||
|
|
||||||
commands:
|
commands:
|
||||||
@@ -44,7 +44,7 @@ jobs:
|
|||||||
command: cargo generate-lockfile
|
command: cargo generate-lockfile
|
||||||
- restore_cache:
|
- restore_cache:
|
||||||
keys:
|
keys:
|
||||||
- cargo-v2-{{ checksum "rust-toolchain" }}-{{ checksum "Cargo.toml" }}-{{ checksum "Cargo.lock" }}-{{ arch }}
|
- cargo-v3-{{ checksum "rust-toolchain" }}-{{ checksum "Cargo.toml" }}-{{ checksum "Cargo.lock" }}-{{ arch }}
|
||||||
- run: rustup install $(cat rust-toolchain)
|
- run: rustup install $(cat rust-toolchain)
|
||||||
- run: rustup default $(cat rust-toolchain)
|
- run: rustup default $(cat rust-toolchain)
|
||||||
- run: rustup component add --toolchain $(cat rust-toolchain) rustfmt
|
- run: rustup component add --toolchain $(cat rust-toolchain) rustfmt
|
||||||
@@ -60,7 +60,7 @@ jobs:
|
|||||||
paths:
|
paths:
|
||||||
- crate
|
- crate
|
||||||
- save_cache:
|
- save_cache:
|
||||||
key: cargo-v2-{{ checksum "rust-toolchain" }}-{{ checksum "Cargo.toml" }}-{{ checksum "Cargo.lock" }}-{{ arch }}
|
key: cargo-v3-{{ checksum "rust-toolchain" }}-{{ checksum "Cargo.toml" }}-{{ checksum "Cargo.lock" }}-{{ arch }}
|
||||||
paths:
|
paths:
|
||||||
- "~/.cargo"
|
- "~/.cargo"
|
||||||
- "~/.rustup"
|
- "~/.rustup"
|
||||||
@@ -121,7 +121,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
- run: bash ci_scripts/run-doxygen.sh
|
- run: bash ci_scripts/run-doxygen.sh
|
||||||
- run: mkdir -p workspace/c-docs
|
- run: mkdir -p workspace/c-docs
|
||||||
- run: cp -av deltachat-ffi/{html,xml} workspace/c-docs/
|
- run: cp -av deltachat-ffi/{html,xml} workspace/c-docs/
|
||||||
- persist_to_workspace:
|
- persist_to_workspace:
|
||||||
root: workspace
|
root: workspace
|
||||||
@@ -189,7 +189,7 @@ workflows:
|
|||||||
- upload_docs_wheels:
|
- upload_docs_wheels:
|
||||||
requires:
|
requires:
|
||||||
- build_test_docs_wheel
|
- build_test_docs_wheel
|
||||||
- build_doxygen
|
- build_doxygen
|
||||||
- rustfmt:
|
- rustfmt:
|
||||||
requires:
|
requires:
|
||||||
- cargo_fetch
|
- cargo_fetch
|
||||||
|
|||||||
953
Cargo.lock
generated
953
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
14
Cargo.toml
14
Cargo.toml
@@ -15,12 +15,13 @@ hex = "0.3.2"
|
|||||||
sha2 = "0.8.0"
|
sha2 = "0.8.0"
|
||||||
rand = "0.6.5"
|
rand = "0.6.5"
|
||||||
smallvec = "0.6.9"
|
smallvec = "0.6.9"
|
||||||
reqwest = "0.9.15"
|
reqwest = { version = "0.9.15", default-features = false, features = ["rustls-tls"] }
|
||||||
num-derive = "0.2.5"
|
num-derive = "0.2.5"
|
||||||
num-traits = "0.2.6"
|
num-traits = "0.2.6"
|
||||||
native-tls = "0.2.3"
|
lettre = { git = "https://github.com/deltachat/lettre", branch = "feat/rustls" }
|
||||||
lettre = { git = "https://github.com/deltachat/lettre", branch = "master" }
|
async-imap = "0.1"
|
||||||
imap = { git = "https://github.com/deltachat/rust-imap", branch = "master" }
|
async-tls = "0.6"
|
||||||
|
async-std = { version = "1.0", features = ["unstable"] }
|
||||||
base64 = "0.10"
|
base64 = "0.10"
|
||||||
charset = "0.1"
|
charset = "0.1"
|
||||||
percent-encoding = "2.0"
|
percent-encoding = "2.0"
|
||||||
@@ -49,6 +50,9 @@ bitflags = "1.1.0"
|
|||||||
jetscii = "0.4.4"
|
jetscii = "0.4.4"
|
||||||
debug_stub_derive = "0.3.0"
|
debug_stub_derive = "0.3.0"
|
||||||
sanitize-filename = "0.2.1"
|
sanitize-filename = "0.2.1"
|
||||||
|
stop-token = { version = "0.1.1", features = ["unstable"] }
|
||||||
|
rustls = "0.16.0"
|
||||||
|
webpki-roots = "0.18.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tempfile = "3.0"
|
tempfile = "3.0"
|
||||||
@@ -74,6 +78,6 @@ path = "examples/repl/main.rs"
|
|||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["nightly", "ringbuf"]
|
default = ["nightly", "ringbuf"]
|
||||||
vendored = ["native-tls/vendored", "reqwest/default-tls-vendored"]
|
vendored = []
|
||||||
nightly = ["pgp/nightly"]
|
nightly = ["pgp/nightly"]
|
||||||
ringbuf = ["pgp/ringbuf"]
|
ringbuf = ["pgp/ringbuf"]
|
||||||
|
|||||||
@@ -5,16 +5,6 @@ RUN echo /usr/local/lib64 > /etc/ld.so.conf.d/local.conf && \
|
|||||||
echo /usr/local/lib >> /etc/ld.so.conf.d/local.conf
|
echo /usr/local/lib >> /etc/ld.so.conf.d/local.conf
|
||||||
ENV PKG_CONFIG_PATH /usr/local/lib64/pkgconfig:/usr/local/lib/pkgconfig
|
ENV PKG_CONFIG_PATH /usr/local/lib64/pkgconfig:/usr/local/lib/pkgconfig
|
||||||
|
|
||||||
ENV PIP_DISABLE_PIP_VERSION_CHECK 1
|
|
||||||
|
|
||||||
# Install python tools (auditwheels,tox, ...)
|
|
||||||
ADD deps/build_python.sh /builder/build_python.sh
|
|
||||||
RUN mkdir tmp1 && cd tmp1 && bash /builder/build_python.sh && cd .. && rm -r tmp1
|
|
||||||
|
|
||||||
# Install Rust nightly
|
|
||||||
ADD deps/build_rust.sh /builder/build_rust.sh
|
|
||||||
RUN mkdir tmp1 && cd tmp1 && bash /builder/build_rust.sh && cd .. && rm -r tmp1
|
|
||||||
|
|
||||||
# Install a recent Perl, needed to install OpenSSL
|
# Install a recent Perl, needed to install OpenSSL
|
||||||
ADD deps/build_perl.sh /builder/build_perl.sh
|
ADD deps/build_perl.sh /builder/build_perl.sh
|
||||||
RUN mkdir tmp1 && cd tmp1 && bash /builder/build_perl.sh && cd .. && rm -r tmp1
|
RUN mkdir tmp1 && cd tmp1 && bash /builder/build_perl.sh && cd .. && rm -r tmp1
|
||||||
@@ -23,3 +13,12 @@ RUN mkdir tmp1 && cd tmp1 && bash /builder/build_perl.sh && cd .. && rm -r tmp1
|
|||||||
ADD deps/build_openssl.sh /builder/build_openssl.sh
|
ADD deps/build_openssl.sh /builder/build_openssl.sh
|
||||||
RUN mkdir tmp1 && cd tmp1 && bash /builder/build_openssl.sh && cd .. && rm -r tmp1
|
RUN mkdir tmp1 && cd tmp1 && bash /builder/build_openssl.sh && cd .. && rm -r tmp1
|
||||||
|
|
||||||
|
ENV PIP_DISABLE_PIP_VERSION_CHECK 1
|
||||||
|
|
||||||
|
# Install python tools (auditwheels,tox, ...)
|
||||||
|
ADD deps/build_python.sh /builder/build_python.sh
|
||||||
|
RUN mkdir tmp1 && cd tmp1 && bash /builder/build_python.sh && cd .. && rm -r tmp1
|
||||||
|
|
||||||
|
# Install Rust nightly
|
||||||
|
ADD deps/build_rust.sh /builder/build_rust.sh
|
||||||
|
RUN mkdir tmp1 && cd tmp1 && bash /builder/build_rust.sh && cd .. && rm -r tmp1
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
PERL_VERSION=5.28.0
|
PERL_VERSION=5.30.0
|
||||||
PERL_SHA256=7e929f64d4cb0e9d1159d4a59fc89394e27fa1f7004d0836ca0d514685406ea8
|
# PERL_SHA256=7e929f64d4cb0e9d1159d4a59fc89394e27fa1f7004d0836ca0d514685406ea8
|
||||||
curl -O https://www.cpan.org/src/5.0/perl-${PERL_VERSION}.tar.gz
|
curl -O https://www.cpan.org/src/5.0/perl-${PERL_VERSION}.tar.gz
|
||||||
echo "${PERL_SHA256} perl-${PERL_VERSION}.tar.gz" | sha256sum -c -
|
# echo "${PERL_SHA256} perl-${PERL_VERSION}.tar.gz" | sha256sum -c -
|
||||||
tar xzf perl-${PERL_VERSION}.tar.gz
|
tar -xzf perl-${PERL_VERSION}.tar.gz
|
||||||
cd perl-${PERL_VERSION}
|
cd perl-${PERL_VERSION}
|
||||||
|
|
||||||
./Configure -de
|
./Configure -de
|
||||||
make
|
make
|
||||||
|
|||||||
@@ -1,11 +1,8 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
set -e -x
|
set -e -x
|
||||||
|
|
||||||
# Install Rust
|
# Install Rust
|
||||||
curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain nightly-2019-07-10 -y
|
curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain nightly-2019-09-12 -y
|
||||||
export PATH=/root/.cargo/bin:$PATH
|
export PATH=/root/.cargo/bin:$PATH
|
||||||
rustc --version
|
rustc --version
|
||||||
|
|
||||||
# remove some 300-400 MB that we don't need for automated builds
|
|
||||||
rm -rf /root/.rustup/toolchains/nightly-2019-07-10-x86_64-unknown-linux-gnu/share/
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use deltachat::chat::{self, Chat};
|
use deltachat::chat::{self, Chat};
|
||||||
use deltachat::chatlist::*;
|
use deltachat::chatlist::*;
|
||||||
@@ -10,6 +11,7 @@ use deltachat::context::*;
|
|||||||
use deltachat::dc_receive_imf::*;
|
use deltachat::dc_receive_imf::*;
|
||||||
use deltachat::dc_tools::*;
|
use deltachat::dc_tools::*;
|
||||||
use deltachat::error::Error;
|
use deltachat::error::Error;
|
||||||
|
use deltachat::imap::Imap;
|
||||||
use deltachat::imex::*;
|
use deltachat::imex::*;
|
||||||
use deltachat::job::*;
|
use deltachat::job::*;
|
||||||
use deltachat::location;
|
use deltachat::location;
|
||||||
@@ -304,7 +306,11 @@ fn chat_prefix(chat: &Chat) -> &'static str {
|
|||||||
chat.typ.into()
|
chat.typ.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::Error> {
|
pub unsafe fn dc_cmdline(
|
||||||
|
context: &Context,
|
||||||
|
inbox: Arc<Mutex<Imap>>,
|
||||||
|
line: &str,
|
||||||
|
) -> Result<(), failure::Error> {
|
||||||
let chat_id = *context.cmdline_sel_chat_id.read().unwrap();
|
let chat_id = *context.cmdline_sel_chat_id.read().unwrap();
|
||||||
let mut sel_chat = if chat_id > 0 {
|
let mut sel_chat = if chat_id > 0 {
|
||||||
Chat::load_from_db(context, chat_id).ok()
|
Chat::load_from_db(context, chat_id).ok()
|
||||||
@@ -496,10 +502,12 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
|
|||||||
println!("{:#?}", context.get_info());
|
println!("{:#?}", context.get_info());
|
||||||
}
|
}
|
||||||
"interrupt" => {
|
"interrupt" => {
|
||||||
interrupt_imap_idle(context);
|
interrupt_imap_idle(context, &mut inbox.lock().unwrap());
|
||||||
|
unimplemented!()
|
||||||
}
|
}
|
||||||
"maybenetwork" => {
|
"maybenetwork" => {
|
||||||
maybe_network(context);
|
// maybe_network(context);
|
||||||
|
unimplemented!()
|
||||||
}
|
}
|
||||||
"housekeeping" => {
|
"housekeeping" => {
|
||||||
sql::housekeeping(context);
|
sql::housekeeping(context);
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ use std::sync::{Arc, Mutex, RwLock};
|
|||||||
use deltachat::config;
|
use deltachat::config;
|
||||||
use deltachat::configure::*;
|
use deltachat::configure::*;
|
||||||
use deltachat::context::*;
|
use deltachat::context::*;
|
||||||
|
use deltachat::imap::Imap;
|
||||||
use deltachat::job::*;
|
use deltachat::job::*;
|
||||||
use deltachat::oauth2::*;
|
use deltachat::oauth2::*;
|
||||||
use deltachat::securejoin::*;
|
use deltachat::securejoin::*;
|
||||||
@@ -139,42 +140,51 @@ macro_rules! while_running {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start_threads(c: Arc<RwLock<Context>>) {
|
fn start_threads(c: Arc<RwLock<Context>>) -> Option<Arc<Mutex<Imap>>> {
|
||||||
if HANDLE.clone().lock().unwrap().is_some() {
|
if HANDLE.clone().lock().unwrap().is_some() {
|
||||||
return;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("Starting threads");
|
println!("Starting threads");
|
||||||
IS_RUNNING.store(true, Ordering::Relaxed);
|
IS_RUNNING.store(true, Ordering::Relaxed);
|
||||||
|
let inbox = Arc::new(Mutex::new(c.read().unwrap().create_inbox()));
|
||||||
|
let inbox2 = inbox.clone();
|
||||||
let ctx = c.clone();
|
let ctx = c.clone();
|
||||||
let handle_imap = std::thread::spawn(move || loop {
|
let handle_imap = std::thread::spawn(move || {
|
||||||
while_running!({
|
let inbox = inbox2;
|
||||||
perform_imap_jobs(&ctx.read().unwrap());
|
|
||||||
perform_imap_fetch(&ctx.read().unwrap());
|
loop {
|
||||||
while_running!({
|
while_running!({
|
||||||
let context = ctx.read().unwrap();
|
perform_imap_jobs(&ctx.read().unwrap(), &mut inbox.lock().unwrap());
|
||||||
perform_imap_idle(&context);
|
perform_imap_fetch(&ctx.read().unwrap(), &mut inbox.lock().unwrap());
|
||||||
});
|
while_running!({
|
||||||
});
|
let context = ctx.read().unwrap();
|
||||||
|
perform_imap_idle(&context, &mut inbox.lock().unwrap());
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let ctx = c.clone();
|
let ctx = c.clone();
|
||||||
let handle_mvbox = std::thread::spawn(move || loop {
|
let handle_mvbox = std::thread::spawn(move || loop {
|
||||||
|
let mut mvbox = ctx.read().unwrap().create_inbox();
|
||||||
|
|
||||||
while_running!({
|
while_running!({
|
||||||
perform_mvbox_fetch(&ctx.read().unwrap());
|
perform_mvbox_fetch(&ctx.read().unwrap(), &mut mvbox);
|
||||||
while_running!({
|
while_running!({
|
||||||
perform_mvbox_idle(&ctx.read().unwrap());
|
perform_mvbox_idle(&ctx.read().unwrap(), &mut mvbox);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
let ctx = c.clone();
|
let ctx = c.clone();
|
||||||
let handle_sentbox = std::thread::spawn(move || loop {
|
let handle_sentbox = std::thread::spawn(move || loop {
|
||||||
|
let mut sentbox = ctx.read().unwrap().create_inbox();
|
||||||
|
|
||||||
while_running!({
|
while_running!({
|
||||||
perform_sentbox_fetch(&ctx.read().unwrap());
|
perform_sentbox_fetch(&ctx.read().unwrap(), &mut sentbox);
|
||||||
while_running!({
|
while_running!({
|
||||||
perform_sentbox_idle(&ctx.read().unwrap());
|
perform_sentbox_idle(&ctx.read().unwrap(), &mut sentbox);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -195,18 +205,15 @@ fn start_threads(c: Arc<RwLock<Context>>) {
|
|||||||
handle_sentbox: Some(handle_sentbox),
|
handle_sentbox: Some(handle_sentbox),
|
||||||
handle_smtp: Some(handle_smtp),
|
handle_smtp: Some(handle_smtp),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Some(inbox)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stop_threads(context: &Context) {
|
fn stop_threads(_context: &Context) {
|
||||||
if let Some(ref mut handle) = *HANDLE.clone().lock().unwrap() {
|
if let Some(ref mut handle) = *HANDLE.clone().lock().unwrap() {
|
||||||
println!("Stopping threads");
|
println!("Stopping threads");
|
||||||
IS_RUNNING.store(false, Ordering::Relaxed);
|
IS_RUNNING.store(false, Ordering::Relaxed);
|
||||||
|
|
||||||
interrupt_imap_idle(context);
|
|
||||||
interrupt_mvbox_idle(context);
|
|
||||||
interrupt_sentbox_idle(context);
|
|
||||||
interrupt_smtp_idle(context);
|
|
||||||
|
|
||||||
handle.handle_imap.take().unwrap().join().unwrap();
|
handle.handle_imap.take().unwrap().join().unwrap();
|
||||||
handle.handle_mvbox.take().unwrap().join().unwrap();
|
handle.handle_mvbox.take().unwrap().join().unwrap();
|
||||||
handle.handle_sentbox.take().unwrap().join().unwrap();
|
handle.handle_sentbox.take().unwrap().join().unwrap();
|
||||||
@@ -439,11 +446,16 @@ unsafe fn handle_cmd(line: &str, ctx: Arc<RwLock<Context>>) -> Result<ExitResult
|
|||||||
let arg0 = args.next().unwrap_or_default();
|
let arg0 = args.next().unwrap_or_default();
|
||||||
let arg1 = args.next().unwrap_or_default();
|
let arg1 = args.next().unwrap_or_default();
|
||||||
|
|
||||||
|
let mut inbox = None;
|
||||||
|
|
||||||
match arg0 {
|
match arg0 {
|
||||||
"connect" => {
|
"connect" => {
|
||||||
start_threads(ctx);
|
if let Some(i) = start_threads(ctx.clone()) {
|
||||||
|
inbox = Some(i);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
"disconnect" => {
|
"disconnect" => {
|
||||||
|
let _ = inbox.take();
|
||||||
stop_threads(&ctx.read().unwrap());
|
stop_threads(&ctx.read().unwrap());
|
||||||
}
|
}
|
||||||
"smtp-jobs" => {
|
"smtp-jobs" => {
|
||||||
@@ -457,11 +469,16 @@ unsafe fn handle_cmd(line: &str, ctx: Arc<RwLock<Context>>) -> Result<ExitResult
|
|||||||
if HANDLE.clone().lock().unwrap().is_some() {
|
if HANDLE.clone().lock().unwrap().is_some() {
|
||||||
println!("imap-jobs are already running in a thread.");
|
println!("imap-jobs are already running in a thread.");
|
||||||
} else {
|
} else {
|
||||||
perform_imap_jobs(&ctx.read().unwrap());
|
perform_imap_jobs(
|
||||||
|
&ctx.read().unwrap(),
|
||||||
|
&mut inbox.expect("not connected").lock().unwrap(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"configure" => {
|
"configure" => {
|
||||||
start_threads(ctx.clone());
|
if let Some(i) = start_threads(ctx.clone()) {
|
||||||
|
inbox = Some(i);
|
||||||
|
};
|
||||||
configure(&ctx.read().unwrap());
|
configure(&ctx.read().unwrap());
|
||||||
}
|
}
|
||||||
"oauth2" => {
|
"oauth2" => {
|
||||||
@@ -485,7 +502,9 @@ unsafe fn handle_cmd(line: &str, ctx: Arc<RwLock<Context>>) -> Result<ExitResult
|
|||||||
print!("\x1b[1;1H\x1b[2J");
|
print!("\x1b[1;1H\x1b[2J");
|
||||||
}
|
}
|
||||||
"getqr" | "getbadqr" => {
|
"getqr" | "getbadqr" => {
|
||||||
start_threads(ctx.clone());
|
if let Some(i) = start_threads(ctx.clone()) {
|
||||||
|
inbox = Some(i);
|
||||||
|
};
|
||||||
if let Some(mut qr) =
|
if let Some(mut qr) =
|
||||||
dc_get_securejoin_qr(&ctx.read().unwrap(), arg1.parse().unwrap_or_default())
|
dc_get_securejoin_qr(&ctx.read().unwrap(), arg1.parse().unwrap_or_default())
|
||||||
{
|
{
|
||||||
@@ -504,13 +523,19 @@ unsafe fn handle_cmd(line: &str, ctx: Arc<RwLock<Context>>) -> Result<ExitResult
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
"joinqr" => {
|
"joinqr" => {
|
||||||
start_threads(ctx.clone());
|
if let Some(i) = start_threads(ctx.clone()) {
|
||||||
|
inbox = Some(i);
|
||||||
|
};
|
||||||
if !arg0.is_empty() {
|
if !arg0.is_empty() {
|
||||||
dc_join_securejoin(&ctx.read().unwrap(), arg1);
|
dc_join_securejoin(&ctx.read().unwrap(), arg1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"exit" | "quit" => return Ok(ExitResult::Exit),
|
"exit" | "quit" => return Ok(ExitResult::Exit),
|
||||||
_ => dc_cmdline(&ctx.read().unwrap(), line)?,
|
_ => dc_cmdline(
|
||||||
|
&ctx.read().unwrap(),
|
||||||
|
inbox.expect("not started").clone(),
|
||||||
|
line,
|
||||||
|
)?,
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(ExitResult::Continue)
|
Ok(ExitResult::Continue)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
extern crate deltachat;
|
extern crate deltachat;
|
||||||
|
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, Mutex, RwLock};
|
||||||
use std::{thread, time};
|
use std::{thread, time};
|
||||||
use tempfile::tempdir;
|
use tempfile::tempdir;
|
||||||
|
|
||||||
@@ -11,7 +11,8 @@ use deltachat::configure::*;
|
|||||||
use deltachat::contact::*;
|
use deltachat::contact::*;
|
||||||
use deltachat::context::*;
|
use deltachat::context::*;
|
||||||
use deltachat::job::{
|
use deltachat::job::{
|
||||||
perform_imap_fetch, perform_imap_idle, perform_imap_jobs, perform_smtp_idle, perform_smtp_jobs,
|
interrupt_imap_idle, perform_imap_fetch, perform_imap_idle, perform_imap_jobs,
|
||||||
|
perform_smtp_idle, perform_smtp_jobs,
|
||||||
};
|
};
|
||||||
use deltachat::Event;
|
use deltachat::Event;
|
||||||
|
|
||||||
@@ -45,17 +46,22 @@ fn main() {
|
|||||||
let duration = time::Duration::from_millis(4000);
|
let duration = time::Duration::from_millis(4000);
|
||||||
println!("info: {:#?}", info);
|
println!("info: {:#?}", info);
|
||||||
|
|
||||||
|
let inbox = Arc::new(Mutex::new(ctx.create_inbox()));
|
||||||
|
let inbox2 = inbox.clone();
|
||||||
let ctx = Arc::new(ctx);
|
let ctx = Arc::new(ctx);
|
||||||
let ctx1 = ctx.clone();
|
let ctx1 = ctx.clone();
|
||||||
|
|
||||||
let r1 = running.clone();
|
let r1 = running.clone();
|
||||||
let t1 = thread::spawn(move || {
|
let t1 = thread::spawn(move || {
|
||||||
|
let inbox = inbox2;
|
||||||
|
|
||||||
while *r1.read().unwrap() {
|
while *r1.read().unwrap() {
|
||||||
perform_imap_jobs(&ctx1);
|
perform_imap_jobs(&ctx1, &mut inbox.lock().unwrap());
|
||||||
if *r1.read().unwrap() {
|
if *r1.read().unwrap() {
|
||||||
perform_imap_fetch(&ctx1);
|
perform_imap_fetch(&ctx1, &mut inbox.lock().unwrap());
|
||||||
|
|
||||||
if *r1.read().unwrap() {
|
if *r1.read().unwrap() {
|
||||||
perform_imap_idle(&ctx1);
|
perform_imap_idle(&ctx1, &mut inbox.lock().unwrap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -79,6 +85,8 @@ fn main() {
|
|||||||
ctx.set_config(config::Config::Addr, Some("d@testrun.org"))
|
ctx.set_config(config::Config::Addr, Some("d@testrun.org"))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
ctx.set_config(config::Config::MailPw, Some(&pw)).unwrap();
|
ctx.set_config(config::Config::MailPw, Some(&pw)).unwrap();
|
||||||
|
|
||||||
|
interrupt_imap_idle(&ctx, &mut inbox.lock().unwrap());
|
||||||
configure(&ctx);
|
configure(&ctx);
|
||||||
|
|
||||||
thread::sleep(duration);
|
thread::sleep(duration);
|
||||||
@@ -113,7 +121,7 @@ fn main() {
|
|||||||
println!("stopping threads");
|
println!("stopping threads");
|
||||||
|
|
||||||
*running.clone().write().unwrap() = false;
|
*running.clone().write().unwrap() = false;
|
||||||
deltachat::job::interrupt_imap_idle(&ctx);
|
// not needed anymore I believe. deltachat::job::interrupt_imap_idle(&ctx);
|
||||||
deltachat::job::interrupt_smtp_idle(&ctx);
|
deltachat::job::interrupt_smtp_idle(&ctx);
|
||||||
|
|
||||||
println!("joining");
|
println!("joining");
|
||||||
|
|||||||
@@ -675,7 +675,6 @@ class TestOnlineAccount:
|
|||||||
assert len(messages) == 1
|
assert len(messages) == 1
|
||||||
assert messages[0].text == "msg1"
|
assert messages[0].text == "msg1"
|
||||||
|
|
||||||
pytest.xfail("cannot export twice yet, probably due to interrupt_idle failing")
|
|
||||||
# wait until a second passed since last backup
|
# wait until a second passed since last backup
|
||||||
# because get_latest_backupfile() shall return the latest backup
|
# because get_latest_backupfile() shall return the latest backup
|
||||||
# from a UI it's unlikely anyone manages to export two
|
# from a UI it's unlikely anyone manages to export two
|
||||||
@@ -896,7 +895,7 @@ class TestOnlineConfigureFails:
|
|||||||
ac1.start_threads()
|
ac1.start_threads()
|
||||||
wait_configuration_progress(ac1, 500)
|
wait_configuration_progress(ac1, 500)
|
||||||
ev1 = ac1._evlogger.get_matching("DC_EVENT_ERROR_NETWORK")
|
ev1 = ac1._evlogger.get_matching("DC_EVENT_ERROR_NETWORK")
|
||||||
assert "authentication failed" in ev1[2].lower()
|
assert "cannot login" in ev1[2].lower()
|
||||||
wait_configuration_progress(ac1, 0, 0)
|
wait_configuration_progress(ac1, 0, 0)
|
||||||
|
|
||||||
def test_invalid_user(self, acfactory):
|
def test_invalid_user(self, acfactory):
|
||||||
@@ -905,7 +904,7 @@ class TestOnlineConfigureFails:
|
|||||||
ac1.start_threads()
|
ac1.start_threads()
|
||||||
wait_configuration_progress(ac1, 500)
|
wait_configuration_progress(ac1, 500)
|
||||||
ev1 = ac1._evlogger.get_matching("DC_EVENT_ERROR_NETWORK")
|
ev1 = ac1._evlogger.get_matching("DC_EVENT_ERROR_NETWORK")
|
||||||
assert "authentication failed" in ev1[2].lower()
|
assert "cannot login" in ev1[2].lower()
|
||||||
wait_configuration_progress(ac1, 0, 0)
|
wait_configuration_progress(ac1, 0, 0)
|
||||||
|
|
||||||
def test_invalid_domain(self, acfactory):
|
def test_invalid_domain(self, acfactory):
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
nightly-2019-08-13
|
nightly-2019-11-06
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use crate::constants::DC_VERSION_STR;
|
|||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
use crate::dc_tools::*;
|
use crate::dc_tools::*;
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::job::*;
|
// use crate::job::*;
|
||||||
use crate::stock::StockMessage;
|
use crate::stock::StockMessage;
|
||||||
|
|
||||||
/// The available configuration keys.
|
/// The available configuration keys.
|
||||||
@@ -119,17 +119,17 @@ impl Context {
|
|||||||
}
|
}
|
||||||
Config::InboxWatch => {
|
Config::InboxWatch => {
|
||||||
let ret = self.sql.set_raw_config(self, key, value);
|
let ret = self.sql.set_raw_config(self, key, value);
|
||||||
interrupt_imap_idle(self);
|
// interrupt_imap_idle(self);
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
Config::SentboxWatch => {
|
Config::SentboxWatch => {
|
||||||
let ret = self.sql.set_raw_config(self, key, value);
|
let ret = self.sql.set_raw_config(self, key, value);
|
||||||
interrupt_sentbox_idle(self);
|
// interrupt_sentbox_idle(self);
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
Config::MvboxWatch => {
|
Config::MvboxWatch => {
|
||||||
let ret = self.sql.set_raw_config(self, key, value);
|
let ret = self.sql.set_raw_config(self, key, value);
|
||||||
interrupt_mvbox_idle(self);
|
// interrupt_mvbox_idle(self);
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
Config::Selfstatus => {
|
Config::Selfstatus => {
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ pub fn dc_is_configured(context: &Context) -> bool {
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
// the other dc_job_do_DC_JOB_*() functions are declared static in the c-file
|
// the other dc_job_do_DC_JOB_*() functions are declared static in the c-file
|
||||||
#[allow(non_snake_case, unused_must_use)]
|
#[allow(non_snake_case, unused_must_use)]
|
||||||
pub fn dc_job_do_DC_JOB_CONFIGURE_IMAP(context: &Context) {
|
pub fn dc_job_do_DC_JOB_CONFIGURE_IMAP(context: &Context, inbox: &mut Imap) {
|
||||||
if !context.sql.is_open() {
|
if !context.sql.is_open() {
|
||||||
error!(context, "Cannot configure, database not opened.",);
|
error!(context, "Cannot configure, database not opened.",);
|
||||||
progress!(context, 0);
|
progress!(context, 0);
|
||||||
@@ -62,19 +62,11 @@ pub fn dc_job_do_DC_JOB_CONFIGURE_IMAP(context: &Context) {
|
|||||||
|
|
||||||
let mut param_autoconfig: Option<LoginParam> = None;
|
let mut param_autoconfig: Option<LoginParam> = None;
|
||||||
|
|
||||||
context.inbox.read().unwrap().disconnect(context);
|
// TODO: these need to be disconnected manually now, before starting configure
|
||||||
context
|
// inbox.disconnect();
|
||||||
.sentbox_thread
|
// context.sentbox_thread.write().unwrap().imap.disconnect();
|
||||||
.read()
|
// context.mvbox_thread.write().unwrap().imap.disconnect();
|
||||||
.unwrap()
|
|
||||||
.imap
|
|
||||||
.disconnect(context);
|
|
||||||
context
|
|
||||||
.mvbox_thread
|
|
||||||
.read()
|
|
||||||
.unwrap()
|
|
||||||
.imap
|
|
||||||
.disconnect(context);
|
|
||||||
context.smtp.clone().lock().unwrap().disconnect();
|
context.smtp.clone().lock().unwrap().disconnect();
|
||||||
info!(context, "Configure ...",);
|
info!(context, "Configure ...",);
|
||||||
|
|
||||||
@@ -337,7 +329,7 @@ pub fn dc_job_do_DC_JOB_CONFIGURE_IMAP(context: &Context) {
|
|||||||
/* try to connect to IMAP - if we did not got an autoconfig,
|
/* try to connect to IMAP - if we did not got an autoconfig,
|
||||||
do some further tries with different settings and username variations */
|
do some further tries with different settings and username variations */
|
||||||
imap_connected_here =
|
imap_connected_here =
|
||||||
try_imap_connections(context, &mut param, param_autoconfig.is_some());
|
try_imap_connections(context, &mut param, param_autoconfig.is_some(), inbox);
|
||||||
imap_connected_here
|
imap_connected_here
|
||||||
}
|
}
|
||||||
15 => {
|
15 => {
|
||||||
@@ -355,11 +347,7 @@ pub fn dc_job_do_DC_JOB_CONFIGURE_IMAP(context: &Context) {
|
|||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
context
|
inbox.configure_folders(context, flags);
|
||||||
.inbox
|
|
||||||
.read()
|
|
||||||
.unwrap()
|
|
||||||
.configure_folders(context, flags);
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
17 => {
|
17 => {
|
||||||
@@ -398,7 +386,7 @@ pub fn dc_job_do_DC_JOB_CONFIGURE_IMAP(context: &Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if imap_connected_here {
|
if imap_connected_here {
|
||||||
context.inbox.read().unwrap().disconnect(context);
|
inbox.disconnect();
|
||||||
}
|
}
|
||||||
if smtp_connected_here {
|
if smtp_connected_here {
|
||||||
context.smtp.clone().lock().unwrap().disconnect();
|
context.smtp.clone().lock().unwrap().disconnect();
|
||||||
@@ -439,9 +427,10 @@ fn try_imap_connections(
|
|||||||
context: &Context,
|
context: &Context,
|
||||||
mut param: &mut LoginParam,
|
mut param: &mut LoginParam,
|
||||||
was_autoconfig: bool,
|
was_autoconfig: bool,
|
||||||
|
inbox: &mut Imap,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
// progress 650 and 660
|
// progress 650 and 660
|
||||||
if let Some(res) = try_imap_connection(context, &mut param, was_autoconfig, 0) {
|
if let Some(res) = try_imap_connection(context, &mut param, was_autoconfig, 0, inbox) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
progress!(context, 670);
|
progress!(context, 670);
|
||||||
@@ -456,7 +445,7 @@ fn try_imap_connections(
|
|||||||
param.send_user = param.send_user.split_at(at).0.to_string();
|
param.send_user = param.send_user.split_at(at).0.to_string();
|
||||||
}
|
}
|
||||||
// progress 680 and 690
|
// progress 680 and 690
|
||||||
if let Some(res) = try_imap_connection(context, &mut param, was_autoconfig, 1) {
|
if let Some(res) = try_imap_connection(context, &mut param, was_autoconfig, 1, inbox) {
|
||||||
res
|
res
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
@@ -468,8 +457,9 @@ fn try_imap_connection(
|
|||||||
param: &mut LoginParam,
|
param: &mut LoginParam,
|
||||||
was_autoconfig: bool,
|
was_autoconfig: bool,
|
||||||
variation: usize,
|
variation: usize,
|
||||||
|
inbox: &mut Imap,
|
||||||
) -> Option<bool> {
|
) -> Option<bool> {
|
||||||
if let Some(res) = try_imap_one_param(context, ¶m) {
|
if let Some(res) = try_imap_one_param(context, ¶m, inbox) {
|
||||||
return Some(res);
|
return Some(res);
|
||||||
}
|
}
|
||||||
if was_autoconfig {
|
if was_autoconfig {
|
||||||
@@ -478,23 +468,23 @@ fn try_imap_connection(
|
|||||||
progress!(context, 650 + variation * 30);
|
progress!(context, 650 + variation * 30);
|
||||||
param.server_flags &= !(DC_LP_IMAP_SOCKET_FLAGS);
|
param.server_flags &= !(DC_LP_IMAP_SOCKET_FLAGS);
|
||||||
param.server_flags |= DC_LP_IMAP_SOCKET_STARTTLS;
|
param.server_flags |= DC_LP_IMAP_SOCKET_STARTTLS;
|
||||||
if let Some(res) = try_imap_one_param(context, ¶m) {
|
if let Some(res) = try_imap_one_param(context, ¶m, inbox) {
|
||||||
return Some(res);
|
return Some(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
progress!(context, 660 + variation * 30);
|
progress!(context, 660 + variation * 30);
|
||||||
param.mail_port = 143;
|
param.mail_port = 143;
|
||||||
|
|
||||||
try_imap_one_param(context, ¶m)
|
try_imap_one_param(context, ¶m, inbox)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_imap_one_param(context: &Context, param: &LoginParam) -> Option<bool> {
|
fn try_imap_one_param(context: &Context, param: &LoginParam, inbox: &mut Imap) -> Option<bool> {
|
||||||
let inf = format!(
|
let inf = format!(
|
||||||
"imap: {}@{}:{} flags=0x{:x}",
|
"imap: {}@{}:{} flags=0x{:x}",
|
||||||
param.mail_user, param.mail_server, param.mail_port, param.server_flags
|
param.mail_user, param.mail_server, param.mail_port, param.server_flags
|
||||||
);
|
);
|
||||||
info!(context, "Trying: {}", inf);
|
info!(context, "Trying: {}", inf);
|
||||||
if context.inbox.read().unwrap().connect(context, ¶m) {
|
if inbox.connect(context, ¶m) {
|
||||||
info!(context, "success: {}", inf);
|
info!(context, "success: {}", inf);
|
||||||
return Some(true);
|
return Some(true);
|
||||||
}
|
}
|
||||||
@@ -566,23 +556,25 @@ fn try_smtp_one_param(context: &Context, param: &LoginParam) -> Option<bool> {
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Connect to configured account
|
* Connect to configured account
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
pub fn dc_connect_to_configured_imap(context: &Context, imap: &Imap) -> libc::c_int {
|
pub fn dc_connect_to_configured_imap(context: &Context, imap: &mut Imap) -> libc::c_int {
|
||||||
let mut ret_connected = 0;
|
async_std::task::block_on(async move {
|
||||||
|
let mut ret_connected = 0;
|
||||||
|
|
||||||
if imap.is_connected() {
|
if imap.is_connected().await {
|
||||||
ret_connected = 1
|
ret_connected = 1
|
||||||
} else if !context.sql.get_raw_config_bool(context, "configured") {
|
} else if !context.sql.get_raw_config_bool(context, "configured") {
|
||||||
warn!(context, "Not configured, cannot connect.",);
|
warn!(context, "Not configured, cannot connect.",);
|
||||||
} else {
|
} else {
|
||||||
let param = LoginParam::from_database(context, "configured_");
|
let param = LoginParam::from_database(context, "configured_");
|
||||||
// the trailing underscore is correct
|
// the trailing underscore is correct
|
||||||
|
|
||||||
if imap.connect(context, ¶m) {
|
if imap.connect(context, ¶m) {
|
||||||
ret_connected = 2;
|
ret_connected = 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ret_connected
|
ret_connected
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@@ -620,6 +612,8 @@ mod tests {
|
|||||||
.set_config(Config::Addr, Some("probably@unexistant.addr"))
|
.set_config(Config::Addr, Some("probably@unexistant.addr"))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
t.ctx.set_config(Config::MailPw, Some("123456")).unwrap();
|
t.ctx.set_config(Config::MailPw, Some("123456")).unwrap();
|
||||||
dc_job_do_DC_JOB_CONFIGURE_IMAP(&t.ctx);
|
|
||||||
|
let mut inbox = t.ctx.create_inbox();
|
||||||
|
dc_job_do_DC_JOB_CONFIGURE_IMAP(&t.ctx, &mut inbox);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ pub struct Context {
|
|||||||
dbfile: PathBuf,
|
dbfile: PathBuf,
|
||||||
blobdir: PathBuf,
|
blobdir: PathBuf,
|
||||||
pub sql: Sql,
|
pub sql: Sql,
|
||||||
pub inbox: Arc<RwLock<Imap>>,
|
|
||||||
pub perform_inbox_jobs_needed: Arc<RwLock<bool>>,
|
pub perform_inbox_jobs_needed: Arc<RwLock<bool>>,
|
||||||
pub probe_imap_network: Arc<RwLock<bool>>,
|
pub probe_imap_network: Arc<RwLock<bool>>,
|
||||||
pub sentbox_thread: Arc<RwLock<JobThread>>,
|
pub sentbox_thread: Arc<RwLock<JobThread>>,
|
||||||
@@ -118,7 +117,6 @@ impl Context {
|
|||||||
let ctx = Context {
|
let ctx = Context {
|
||||||
blobdir,
|
blobdir,
|
||||||
dbfile,
|
dbfile,
|
||||||
inbox: Arc::new(RwLock::new(Imap::new())),
|
|
||||||
cb,
|
cb,
|
||||||
os_name: Some(os_name),
|
os_name: Some(os_name),
|
||||||
running_state: Arc::new(RwLock::new(Default::default())),
|
running_state: Arc::new(RwLock::new(Default::default())),
|
||||||
@@ -132,12 +130,10 @@ impl Context {
|
|||||||
sentbox_thread: Arc::new(RwLock::new(JobThread::new(
|
sentbox_thread: Arc::new(RwLock::new(JobThread::new(
|
||||||
"SENTBOX",
|
"SENTBOX",
|
||||||
"configured_sentbox_folder",
|
"configured_sentbox_folder",
|
||||||
Imap::new(),
|
|
||||||
))),
|
))),
|
||||||
mvbox_thread: Arc::new(RwLock::new(JobThread::new(
|
mvbox_thread: Arc::new(RwLock::new(JobThread::new(
|
||||||
"MVBOX",
|
"MVBOX",
|
||||||
"configured_mvbox_folder",
|
"configured_mvbox_folder",
|
||||||
Imap::new(),
|
|
||||||
))),
|
))),
|
||||||
probe_imap_network: Arc::new(RwLock::new(false)),
|
probe_imap_network: Arc::new(RwLock::new(false)),
|
||||||
perform_inbox_jobs_needed: Arc::new(RwLock::new(false)),
|
perform_inbox_jobs_needed: Arc::new(RwLock::new(false)),
|
||||||
@@ -153,6 +149,18 @@ impl Context {
|
|||||||
Ok(ctx)
|
Ok(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn create_inbox(&self) -> Imap {
|
||||||
|
Imap::new()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_mvbox(&self) -> Imap {
|
||||||
|
Imap::new()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_sentbox(&self) -> Imap {
|
||||||
|
Imap::new()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_dbfile(&self) -> &Path {
|
pub fn get_dbfile(&self) -> &Path {
|
||||||
self.dbfile.as_path()
|
self.dbfile.as_path()
|
||||||
}
|
}
|
||||||
@@ -458,12 +466,6 @@ impl Context {
|
|||||||
|
|
||||||
impl Drop for Context {
|
impl Drop for Context {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
info!(self, "disconnecting INBOX-watch",);
|
|
||||||
self.inbox.read().unwrap().disconnect(self);
|
|
||||||
info!(self, "disconnecting sentbox-thread",);
|
|
||||||
self.sentbox_thread.read().unwrap().imap.disconnect(self);
|
|
||||||
info!(self, "disconnecting mvbox-thread",);
|
|
||||||
self.mvbox_thread.read().unwrap().imap.disconnect(self);
|
|
||||||
info!(self, "disconnecting SMTP");
|
info!(self, "disconnecting SMTP");
|
||||||
self.smtp.clone().lock().unwrap().disconnect();
|
self.smtp.clone().lock().unwrap().disconnect();
|
||||||
self.sql.close(self);
|
self.sql.close(self);
|
||||||
|
|||||||
@@ -498,7 +498,7 @@ fn decrypt_if_autocrypt_message(
|
|||||||
public_keyring_for_validate: &Keyring,
|
public_keyring_for_validate: &Keyring,
|
||||||
ret_valid_signatures: &mut HashSet<String>,
|
ret_valid_signatures: &mut HashSet<String>,
|
||||||
ret_gossip_headers: *mut *mut mailimf_fields,
|
ret_gossip_headers: *mut *mut mailimf_fields,
|
||||||
) -> Result<(bool)> {
|
) -> Result<bool> {
|
||||||
/* The returned bool is true if we detected an Autocrypt-encrypted
|
/* The returned bool is true if we detected an Autocrypt-encrypted
|
||||||
message and successfully decrypted it. Decryption then modifies the
|
message and successfully decrypted it. Decryption then modifies the
|
||||||
passed in mime structure in place. The returned bool is false
|
passed in mime structure in place. The returned bool is false
|
||||||
|
|||||||
1750
src/imap.rs
1750
src/imap.rs
File diff suppressed because it is too large
Load Diff
294
src/imap_client.rs
Normal file
294
src/imap_client.rs
Normal file
@@ -0,0 +1,294 @@
|
|||||||
|
use async_imap::{
|
||||||
|
error::{Error as ImapError, Result as ImapResult},
|
||||||
|
extensions::idle::Handle as ImapIdleHandle,
|
||||||
|
types::{Capabilities, Fetch, Mailbox, Name},
|
||||||
|
Client as ImapClient, Session as ImapSession,
|
||||||
|
};
|
||||||
|
use async_std::net::{self, TcpStream};
|
||||||
|
use async_std::prelude::*;
|
||||||
|
use async_tls::client::TlsStream;
|
||||||
|
|
||||||
|
use crate::login_param::CertificateChecks;
|
||||||
|
|
||||||
|
const DCC_IMAP_DEBUG: &str = "DCC_IMAP_DEBUG";
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub(crate) enum Client {
|
||||||
|
Secure(ImapClient<TlsStream<TcpStream>>),
|
||||||
|
Insecure(ImapClient<TcpStream>),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub(crate) enum Session {
|
||||||
|
Secure(ImapSession<TlsStream<TcpStream>>),
|
||||||
|
Insecure(ImapSession<TcpStream>),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub(crate) enum IdleHandle {
|
||||||
|
Secure(ImapIdleHandle<TlsStream<TcpStream>>),
|
||||||
|
Insecure(ImapIdleHandle<TcpStream>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Client {
|
||||||
|
pub async fn connect_secure<A: net::ToSocketAddrs, S: AsRef<str>>(
|
||||||
|
addr: A,
|
||||||
|
domain: S,
|
||||||
|
_certificate_checks: CertificateChecks,
|
||||||
|
) -> ImapResult<Self> {
|
||||||
|
let stream = TcpStream::connect(addr).await?;
|
||||||
|
let tls = async_tls::TlsConnector::new();
|
||||||
|
|
||||||
|
let tls_stream = tls.connect(domain.as_ref(), stream)?.await?;
|
||||||
|
|
||||||
|
let mut client = ImapClient::new(tls_stream);
|
||||||
|
if std::env::var(DCC_IMAP_DEBUG).is_ok() {
|
||||||
|
client.debug = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
let _greeting = client
|
||||||
|
.read_response()
|
||||||
|
.await
|
||||||
|
.expect("failed to read greeting");
|
||||||
|
|
||||||
|
Ok(Client::Secure(client))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn connect_insecure<A: net::ToSocketAddrs>(addr: A) -> ImapResult<Self> {
|
||||||
|
let stream = TcpStream::connect(addr).await?;
|
||||||
|
|
||||||
|
let mut client = ImapClient::new(stream);
|
||||||
|
if std::env::var(DCC_IMAP_DEBUG).is_ok() {
|
||||||
|
client.debug = true;
|
||||||
|
}
|
||||||
|
let _greeting = client
|
||||||
|
.read_response()
|
||||||
|
.await
|
||||||
|
.expect("failed to read greeting");
|
||||||
|
|
||||||
|
Ok(Client::Insecure(client))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn secure<S: AsRef<str>>(
|
||||||
|
self,
|
||||||
|
domain: S,
|
||||||
|
_certificate_checks: CertificateChecks,
|
||||||
|
) -> ImapResult<Client> {
|
||||||
|
match self {
|
||||||
|
Client::Insecure(client) => {
|
||||||
|
let tls = async_tls::TlsConnector::new();
|
||||||
|
|
||||||
|
let client_sec = client.secure(domain, &tls).await?;
|
||||||
|
|
||||||
|
Ok(Client::Secure(client_sec))
|
||||||
|
}
|
||||||
|
// Nothing to do
|
||||||
|
Client::Secure(_) => Ok(self),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn authenticate<A: async_imap::Authenticator, S: AsRef<str>>(
|
||||||
|
self,
|
||||||
|
auth_type: S,
|
||||||
|
authenticator: &A,
|
||||||
|
) -> Result<Session, (ImapError, Client)> {
|
||||||
|
match self {
|
||||||
|
Client::Secure(i) => match i.authenticate(auth_type, authenticator).await {
|
||||||
|
Ok(session) => Ok(Session::Secure(session)),
|
||||||
|
Err((err, c)) => Err((err, Client::Secure(c))),
|
||||||
|
},
|
||||||
|
Client::Insecure(i) => match i.authenticate(auth_type, authenticator).await {
|
||||||
|
Ok(session) => Ok(Session::Insecure(session)),
|
||||||
|
Err((err, c)) => Err((err, Client::Insecure(c))),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn login<U: AsRef<str>, P: AsRef<str>>(
|
||||||
|
self,
|
||||||
|
username: U,
|
||||||
|
password: P,
|
||||||
|
) -> Result<Session, (ImapError, Client)> {
|
||||||
|
match self {
|
||||||
|
Client::Secure(i) => match i.login(username, password).await {
|
||||||
|
Ok(session) => Ok(Session::Secure(session)),
|
||||||
|
Err((err, c)) => Err((err, Client::Secure(c))),
|
||||||
|
},
|
||||||
|
Client::Insecure(i) => match i.login(username, password).await {
|
||||||
|
Ok(session) => Ok(Session::Insecure(session)),
|
||||||
|
Err((err, c)) => Err((err, Client::Insecure(c))),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Session {
|
||||||
|
pub async fn capabilities(&mut self) -> ImapResult<Capabilities> {
|
||||||
|
let res = match self {
|
||||||
|
Session::Secure(i) => i.capabilities().await?,
|
||||||
|
Session::Insecure(i) => i.capabilities().await?,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn list(
|
||||||
|
&mut self,
|
||||||
|
reference_name: Option<&str>,
|
||||||
|
mailbox_pattern: Option<&str>,
|
||||||
|
) -> ImapResult<Vec<Name>> {
|
||||||
|
let res = match self {
|
||||||
|
Session::Secure(i) => {
|
||||||
|
i.list(reference_name, mailbox_pattern)
|
||||||
|
.await?
|
||||||
|
.collect::<ImapResult<_>>()
|
||||||
|
.await?
|
||||||
|
}
|
||||||
|
Session::Insecure(i) => {
|
||||||
|
i.list(reference_name, mailbox_pattern)
|
||||||
|
.await?
|
||||||
|
.collect::<ImapResult<_>>()
|
||||||
|
.await?
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn create<S: AsRef<str>>(&mut self, mailbox_name: S) -> ImapResult<()> {
|
||||||
|
match self {
|
||||||
|
Session::Secure(i) => i.create(mailbox_name).await?,
|
||||||
|
Session::Insecure(i) => i.create(mailbox_name).await?,
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn subscribe<S: AsRef<str>>(&mut self, mailbox: S) -> ImapResult<()> {
|
||||||
|
match self {
|
||||||
|
Session::Secure(i) => i.subscribe(mailbox).await?,
|
||||||
|
Session::Insecure(i) => i.subscribe(mailbox).await?,
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn close(&mut self) -> ImapResult<()> {
|
||||||
|
match self {
|
||||||
|
Session::Secure(i) => i.close().await?,
|
||||||
|
Session::Insecure(i) => i.close().await?,
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn select<S: AsRef<str>>(&mut self, mailbox_name: S) -> ImapResult<Mailbox> {
|
||||||
|
let mbox = match self {
|
||||||
|
Session::Secure(i) => i.select(mailbox_name).await?,
|
||||||
|
Session::Insecure(i) => i.select(mailbox_name).await?,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(mbox)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn fetch<S1, S2>(&mut self, sequence_set: S1, query: S2) -> ImapResult<Vec<Fetch>>
|
||||||
|
where
|
||||||
|
S1: AsRef<str>,
|
||||||
|
S2: AsRef<str>,
|
||||||
|
{
|
||||||
|
let res = match self {
|
||||||
|
Session::Secure(i) => {
|
||||||
|
i.fetch(sequence_set, query)
|
||||||
|
.await?
|
||||||
|
.collect::<ImapResult<_>>()
|
||||||
|
.await?
|
||||||
|
}
|
||||||
|
Session::Insecure(i) => {
|
||||||
|
i.fetch(sequence_set, query)
|
||||||
|
.await?
|
||||||
|
.collect::<ImapResult<_>>()
|
||||||
|
.await?
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn uid_fetch<S1, S2>(&mut self, uid_set: S1, query: S2) -> ImapResult<Vec<Fetch>>
|
||||||
|
where
|
||||||
|
S1: AsRef<str>,
|
||||||
|
S2: AsRef<str>,
|
||||||
|
{
|
||||||
|
let res = match self {
|
||||||
|
Session::Secure(i) => {
|
||||||
|
i.uid_fetch(uid_set, query)
|
||||||
|
.await?
|
||||||
|
.collect::<ImapResult<_>>()
|
||||||
|
.await?
|
||||||
|
}
|
||||||
|
Session::Insecure(i) => {
|
||||||
|
i.uid_fetch(uid_set, query)
|
||||||
|
.await?
|
||||||
|
.collect::<ImapResult<_>>()
|
||||||
|
.await?
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn idle(self) -> IdleHandle {
|
||||||
|
match self {
|
||||||
|
Session::Secure(i) => {
|
||||||
|
let h = i.idle();
|
||||||
|
IdleHandle::Secure(h)
|
||||||
|
}
|
||||||
|
Session::Insecure(i) => {
|
||||||
|
let h = i.idle();
|
||||||
|
IdleHandle::Insecure(h)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn uid_store<S1, S2>(&mut self, uid_set: S1, query: S2) -> ImapResult<Vec<Fetch>>
|
||||||
|
where
|
||||||
|
S1: AsRef<str>,
|
||||||
|
S2: AsRef<str>,
|
||||||
|
{
|
||||||
|
let res = match self {
|
||||||
|
Session::Secure(i) => {
|
||||||
|
i.uid_store(uid_set, query)
|
||||||
|
.await?
|
||||||
|
.collect::<ImapResult<_>>()
|
||||||
|
.await?
|
||||||
|
}
|
||||||
|
Session::Insecure(i) => {
|
||||||
|
i.uid_store(uid_set, query)
|
||||||
|
.await?
|
||||||
|
.collect::<ImapResult<_>>()
|
||||||
|
.await?
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn uid_mv<S1: AsRef<str>, S2: AsRef<str>>(
|
||||||
|
&mut self,
|
||||||
|
uid_set: S1,
|
||||||
|
mailbox_name: S2,
|
||||||
|
) -> ImapResult<()> {
|
||||||
|
match self {
|
||||||
|
Session::Secure(i) => i.uid_mv(uid_set, mailbox_name).await?,
|
||||||
|
Session::Insecure(i) => i.uid_mv(uid_set, mailbox_name).await?,
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn uid_copy<S1: AsRef<str>, S2: AsRef<str>>(
|
||||||
|
&mut self,
|
||||||
|
uid_set: S1,
|
||||||
|
mailbox_name: S2,
|
||||||
|
) -> ImapResult<()> {
|
||||||
|
match self {
|
||||||
|
Session::Secure(i) => i.uid_copy(uid_set, mailbox_name).await?,
|
||||||
|
Session::Insecure(i) => i.uid_copy(uid_set, mailbox_name).await?,
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
167
src/job.rs
167
src/job.rs
@@ -218,9 +218,7 @@ impl Job {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
fn do_DC_JOB_MOVE_MSG(&mut self, context: &Context) {
|
fn do_DC_JOB_MOVE_MSG(&mut self, context: &Context, inbox: &mut Imap) {
|
||||||
let inbox = context.inbox.read().unwrap();
|
|
||||||
|
|
||||||
if let Ok(msg) = Message::load_from_db(context, MsgId::new(self.foreign_id)) {
|
if let Ok(msg) = Message::load_from_db(context, MsgId::new(self.foreign_id)) {
|
||||||
if context
|
if context
|
||||||
.sql
|
.sql
|
||||||
@@ -245,10 +243,10 @@ impl Job {
|
|||||||
&dest_folder,
|
&dest_folder,
|
||||||
&mut dest_uid,
|
&mut dest_uid,
|
||||||
) {
|
) {
|
||||||
ImapResult::RetryLater => {
|
ImapActionResult::RetryLater => {
|
||||||
self.try_again_later(3i32, None);
|
self.try_again_later(3i32, None);
|
||||||
}
|
}
|
||||||
ImapResult::Success => {
|
ImapActionResult::Success => {
|
||||||
message::update_server_uid(
|
message::update_server_uid(
|
||||||
context,
|
context,
|
||||||
&msg.rfc724_mid,
|
&msg.rfc724_mid,
|
||||||
@@ -256,16 +254,14 @@ impl Job {
|
|||||||
dest_uid,
|
dest_uid,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
ImapResult::Failed | ImapResult::AlreadyDone => {}
|
ImapActionResult::Failed | ImapActionResult::AlreadyDone => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
fn do_DC_JOB_DELETE_MSG_ON_IMAP(&mut self, context: &Context) {
|
fn do_DC_JOB_DELETE_MSG_ON_IMAP(&mut self, context: &Context, inbox: &mut Imap) {
|
||||||
let inbox = context.inbox.read().unwrap();
|
|
||||||
|
|
||||||
if let Ok(mut msg) = Message::load_from_db(context, MsgId::new(self.foreign_id)) {
|
if let Ok(mut msg) = Message::load_from_db(context, MsgId::new(self.foreign_id)) {
|
||||||
if !msg.rfc724_mid.is_empty() {
|
if !msg.rfc724_mid.is_empty() {
|
||||||
/* eg. device messages have no Message-ID */
|
/* eg. device messages have no Message-ID */
|
||||||
@@ -280,7 +276,7 @@ impl Job {
|
|||||||
let mid = msg.rfc724_mid;
|
let mid = msg.rfc724_mid;
|
||||||
let server_folder = msg.server_folder.as_ref().unwrap();
|
let server_folder = msg.server_folder.as_ref().unwrap();
|
||||||
let res = inbox.delete_msg(context, &mid, server_folder, &mut msg.server_uid);
|
let res = inbox.delete_msg(context, &mid, server_folder, &mut msg.server_uid);
|
||||||
if res == ImapResult::RetryLater {
|
if res == ImapActionResult::RetryLater {
|
||||||
self.try_again_later(-1i32, None);
|
self.try_again_later(-1i32, None);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -291,8 +287,7 @@ impl Job {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
fn do_DC_JOB_EMPTY_SERVER(&mut self, context: &Context) {
|
fn do_DC_JOB_EMPTY_SERVER(&mut self, context: &Context, inbox: &mut Imap) {
|
||||||
let inbox = context.inbox.read().unwrap();
|
|
||||||
if self.foreign_id & DC_EMPTY_MVBOX > 0 {
|
if self.foreign_id & DC_EMPTY_MVBOX > 0 {
|
||||||
if let Some(mvbox_folder) = context
|
if let Some(mvbox_folder) = context
|
||||||
.sql
|
.sql
|
||||||
@@ -307,17 +302,15 @@ impl Job {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
fn do_DC_JOB_MARKSEEN_MSG_ON_IMAP(&mut self, context: &Context) {
|
fn do_DC_JOB_MARKSEEN_MSG_ON_IMAP(&mut self, context: &Context, inbox: &mut Imap) {
|
||||||
let inbox = context.inbox.read().unwrap();
|
|
||||||
|
|
||||||
if let Ok(msg) = Message::load_from_db(context, MsgId::new(self.foreign_id)) {
|
if let Ok(msg) = Message::load_from_db(context, MsgId::new(self.foreign_id)) {
|
||||||
let folder = msg.server_folder.as_ref().unwrap();
|
let folder = msg.server_folder.as_ref().unwrap();
|
||||||
match inbox.set_seen(context, folder, msg.server_uid) {
|
match inbox.set_seen(context, folder, msg.server_uid) {
|
||||||
ImapResult::RetryLater => {
|
ImapActionResult::RetryLater => {
|
||||||
self.try_again_later(3i32, None);
|
self.try_again_later(3i32, None);
|
||||||
}
|
}
|
||||||
ImapResult::AlreadyDone => {}
|
ImapActionResult::AlreadyDone => {}
|
||||||
ImapResult::Success | ImapResult::Failed => {
|
ImapActionResult::Success | ImapActionResult::Failed => {
|
||||||
// XXX the message might just have been moved
|
// XXX the message might just have been moved
|
||||||
// we want to send out an MDN anyway
|
// we want to send out an MDN anyway
|
||||||
// The job will not be retried so locally
|
// The job will not be retried so locally
|
||||||
@@ -335,15 +328,14 @@ impl Job {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
fn do_DC_JOB_MARKSEEN_MDN_ON_IMAP(&mut self, context: &Context) {
|
fn do_DC_JOB_MARKSEEN_MDN_ON_IMAP(&mut self, context: &Context, inbox: &mut Imap) {
|
||||||
let folder = self
|
let folder = self
|
||||||
.param
|
.param
|
||||||
.get(Param::ServerFolder)
|
.get(Param::ServerFolder)
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.to_string();
|
.to_string();
|
||||||
let uid = self.param.get_int(Param::ServerUid).unwrap_or_default() as u32;
|
let uid = self.param.get_int(Param::ServerUid).unwrap_or_default() as u32;
|
||||||
let inbox = context.inbox.read().unwrap();
|
if inbox.set_seen(context, &folder, uid) == ImapActionResult::RetryLater {
|
||||||
if inbox.set_seen(context, &folder, uid) == ImapResult::RetryLater {
|
|
||||||
self.try_again_later(3i32, None);
|
self.try_again_later(3i32, None);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -361,7 +353,7 @@ impl Job {
|
|||||||
.get_raw_config(context, "configured_mvbox_folder");
|
.get_raw_config(context, "configured_mvbox_folder");
|
||||||
if let Some(dest_folder) = dest_folder {
|
if let Some(dest_folder) = dest_folder {
|
||||||
let mut dest_uid = 0;
|
let mut dest_uid = 0;
|
||||||
if ImapResult::RetryLater
|
if ImapActionResult::RetryLater
|
||||||
== inbox.mv(context, &folder, uid, &dest_folder, &mut dest_uid)
|
== inbox.mv(context, &folder, uid, &dest_folder, &mut dest_uid)
|
||||||
{
|
{
|
||||||
self.try_again_later(3, None);
|
self.try_again_later(3, None);
|
||||||
@@ -382,11 +374,10 @@ pub fn job_kill_action(context: &Context, action: Action) -> bool {
|
|||||||
.is_ok()
|
.is_ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn perform_imap_fetch(context: &Context) {
|
pub fn perform_imap_fetch(context: &Context, inbox: &mut Imap) {
|
||||||
let inbox = context.inbox.read().unwrap();
|
|
||||||
let start = std::time::Instant::now();
|
let start = std::time::Instant::now();
|
||||||
|
|
||||||
if 0 == connect_to_inbox(context, &inbox) {
|
if 0 == connect_to_inbox(context, inbox) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if !context.get_config_bool(Config::InboxWatch) {
|
if !context.get_config_bool(Config::InboxWatch) {
|
||||||
@@ -406,10 +397,8 @@ pub fn perform_imap_fetch(context: &Context) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn perform_imap_idle(context: &Context) {
|
pub fn perform_imap_idle(context: &Context, inbox: &mut Imap) {
|
||||||
let inbox = context.inbox.read().unwrap();
|
connect_to_inbox(context, inbox);
|
||||||
|
|
||||||
connect_to_inbox(context, &inbox);
|
|
||||||
|
|
||||||
if *context.perform_inbox_jobs_needed.clone().read().unwrap() {
|
if *context.perform_inbox_jobs_needed.clone().read().unwrap() {
|
||||||
info!(
|
info!(
|
||||||
@@ -423,56 +412,60 @@ pub fn perform_imap_idle(context: &Context) {
|
|||||||
info!(context, "INBOX-IDLE ended.");
|
info!(context, "INBOX-IDLE ended.");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn perform_mvbox_fetch(context: &Context) {
|
pub fn perform_mvbox_fetch(context: &Context, imap: &mut Imap) {
|
||||||
let use_network = context.get_config_bool(Config::MvboxWatch);
|
|
||||||
|
|
||||||
context
|
|
||||||
.mvbox_thread
|
|
||||||
.write()
|
|
||||||
.unwrap()
|
|
||||||
.fetch(context, use_network);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn perform_mvbox_idle(context: &Context) {
|
|
||||||
let use_network = context.get_config_bool(Config::MvboxWatch);
|
let use_network = context.get_config_bool(Config::MvboxWatch);
|
||||||
|
|
||||||
context
|
context
|
||||||
.mvbox_thread
|
.mvbox_thread
|
||||||
.read()
|
.read()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.idle(context, use_network);
|
.fetch(context, use_network, imap);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn interrupt_mvbox_idle(context: &Context) {
|
pub fn perform_mvbox_idle(context: &Context, imap: &mut Imap) {
|
||||||
context.mvbox_thread.read().unwrap().interrupt_idle(context);
|
let use_network = context.get_config_bool(Config::MvboxWatch);
|
||||||
}
|
|
||||||
|
|
||||||
pub fn perform_sentbox_fetch(context: &Context) {
|
|
||||||
let use_network = context.get_config_bool(Config::SentboxWatch);
|
|
||||||
|
|
||||||
context
|
context
|
||||||
.sentbox_thread
|
.mvbox_thread
|
||||||
.write()
|
.read()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.fetch(context, use_network);
|
.idle(context, use_network, imap);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn perform_sentbox_idle(context: &Context) {
|
pub fn interrupt_mvbox_idle(context: &Context, imap: &mut Imap) {
|
||||||
|
context
|
||||||
|
.mvbox_thread
|
||||||
|
.read()
|
||||||
|
.unwrap()
|
||||||
|
.interrupt_idle(context, imap);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn perform_sentbox_fetch(context: &Context, imap: &mut Imap) {
|
||||||
let use_network = context.get_config_bool(Config::SentboxWatch);
|
let use_network = context.get_config_bool(Config::SentboxWatch);
|
||||||
|
|
||||||
context
|
context
|
||||||
.sentbox_thread
|
.sentbox_thread
|
||||||
.read()
|
.read()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.idle(context, use_network);
|
.fetch(context, use_network, imap);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn interrupt_sentbox_idle(context: &Context) {
|
pub fn perform_sentbox_idle(context: &Context, imap: &mut Imap) {
|
||||||
|
let use_network = context.get_config_bool(Config::SentboxWatch);
|
||||||
|
|
||||||
context
|
context
|
||||||
.sentbox_thread
|
.sentbox_thread
|
||||||
.read()
|
.read()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.interrupt_idle(context);
|
.idle(context, use_network, imap);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn interrupt_sentbox_idle(context: &Context, imap: &mut Imap) {
|
||||||
|
context
|
||||||
|
.sentbox_thread
|
||||||
|
.read()
|
||||||
|
.unwrap()
|
||||||
|
.interrupt_idle(context, imap);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn perform_smtp_jobs(context: &Context) {
|
pub fn perform_smtp_jobs(context: &Context) {
|
||||||
@@ -493,7 +486,7 @@ pub fn perform_smtp_jobs(context: &Context) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
info!(context, "SMTP-jobs started...",);
|
info!(context, "SMTP-jobs started...",);
|
||||||
job_perform(context, Thread::Smtp, probe_smtp_network);
|
job_perform(context, Thread::Smtp, probe_smtp_network, None);
|
||||||
info!(context, "SMTP-jobs ended.");
|
info!(context, "SMTP-jobs ended.");
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -557,7 +550,7 @@ fn get_next_wakeup_time(context: &Context, thread: Thread) -> Duration {
|
|||||||
wakeup_time
|
wakeup_time
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn maybe_network(context: &Context) {
|
pub fn maybe_network(context: &Context, _inbox: &mut Imap) {
|
||||||
{
|
{
|
||||||
let &(ref lock, _) = &*context.smtp_state.clone();
|
let &(ref lock, _) = &*context.smtp_state.clone();
|
||||||
let mut state = lock.lock().unwrap();
|
let mut state = lock.lock().unwrap();
|
||||||
@@ -567,9 +560,10 @@ pub fn maybe_network(context: &Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interrupt_smtp_idle(context);
|
interrupt_smtp_idle(context);
|
||||||
interrupt_imap_idle(context);
|
// TODO: manually
|
||||||
interrupt_mvbox_idle(context);
|
// interrupt_imap_idle(context, inbox);
|
||||||
interrupt_sentbox_idle(context);
|
// interrupt_mvbox_idle(context);
|
||||||
|
// interrupt_sentbox_idle(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn job_action_exists(context: &Context, action: Action) -> bool {
|
pub fn job_action_exists(context: &Context, action: Action) -> bool {
|
||||||
@@ -681,14 +675,14 @@ pub fn job_send_msg(context: &Context, msg_id: MsgId) -> Result<(), Error> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn perform_imap_jobs(context: &Context) {
|
pub fn perform_imap_jobs(context: &Context, inbox: &mut Imap) {
|
||||||
info!(context, "dc_perform_imap_jobs starting.",);
|
info!(context, "dc_perform_imap_jobs starting.",);
|
||||||
|
|
||||||
let probe_imap_network = *context.probe_imap_network.clone().read().unwrap();
|
let probe_imap_network = *context.probe_imap_network.clone().read().unwrap();
|
||||||
*context.probe_imap_network.write().unwrap() = false;
|
*context.probe_imap_network.write().unwrap() = false;
|
||||||
*context.perform_inbox_jobs_needed.write().unwrap() = false;
|
*context.perform_inbox_jobs_needed.write().unwrap() = false;
|
||||||
|
|
||||||
job_perform(context, Thread::Imap, probe_imap_network);
|
job_perform(context, Thread::Imap, probe_imap_network, Some(inbox));
|
||||||
info!(context, "dc_perform_imap_jobs ended.",);
|
info!(context, "dc_perform_imap_jobs ended.",);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -700,7 +694,12 @@ pub fn perform_sentbox_jobs(context: &Context) {
|
|||||||
info!(context, "dc_perform_sentbox_jobs EMPTY (for now).",);
|
info!(context, "dc_perform_sentbox_jobs EMPTY (for now).",);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn job_perform(context: &Context, thread: Thread, probe_network: bool) {
|
fn job_perform(
|
||||||
|
context: &Context,
|
||||||
|
thread: Thread,
|
||||||
|
probe_network: bool,
|
||||||
|
mut inbox: Option<&mut Imap>,
|
||||||
|
) {
|
||||||
let query = if !probe_network {
|
let query = if !probe_network {
|
||||||
// processing for first-try and after backoff-timeouts:
|
// processing for first-try and after backoff-timeouts:
|
||||||
// process jobs in the order they were added.
|
// process jobs in the order they were added.
|
||||||
@@ -768,18 +767,9 @@ fn job_perform(context: &Context, thread: Thread, probe_network: bool) {
|
|||||||
// - they can be re-executed one time AT_ONCE, but they are not save in the database for later execution
|
// - they can be re-executed one time AT_ONCE, but they are not save in the database for later execution
|
||||||
if Action::ConfigureImap == job.action || Action::ImexImap == job.action {
|
if Action::ConfigureImap == job.action || Action::ImexImap == job.action {
|
||||||
job_kill_action(context, job.action);
|
job_kill_action(context, job.action);
|
||||||
context
|
// TODO: figure out better way
|
||||||
.sentbox_thread
|
// context.sentbox_thread.write().unwrap().suspend(context);
|
||||||
.clone()
|
// context.mvbox_thread.write().unwrap().suspend(context);
|
||||||
.read()
|
|
||||||
.unwrap()
|
|
||||||
.suspend(context);
|
|
||||||
context
|
|
||||||
.mvbox_thread
|
|
||||||
.clone()
|
|
||||||
.read()
|
|
||||||
.unwrap()
|
|
||||||
.suspend(context);
|
|
||||||
suspend_smtp_thread(context, true);
|
suspend_smtp_thread(context, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -793,13 +783,21 @@ fn job_perform(context: &Context, thread: Thread, probe_network: bool) {
|
|||||||
warn!(context, "Unknown job id found");
|
warn!(context, "Unknown job id found");
|
||||||
}
|
}
|
||||||
Action::SendMsgToSmtp => job.do_DC_JOB_SEND(context),
|
Action::SendMsgToSmtp => job.do_DC_JOB_SEND(context),
|
||||||
Action::EmptyServer => job.do_DC_JOB_EMPTY_SERVER(context),
|
Action::EmptyServer => job.do_DC_JOB_EMPTY_SERVER(context, inbox.as_mut().unwrap()),
|
||||||
Action::DeleteMsgOnImap => job.do_DC_JOB_DELETE_MSG_ON_IMAP(context),
|
Action::DeleteMsgOnImap => {
|
||||||
Action::MarkseenMsgOnImap => job.do_DC_JOB_MARKSEEN_MSG_ON_IMAP(context),
|
job.do_DC_JOB_DELETE_MSG_ON_IMAP(context, inbox.as_mut().unwrap())
|
||||||
Action::MarkseenMdnOnImap => job.do_DC_JOB_MARKSEEN_MDN_ON_IMAP(context),
|
}
|
||||||
Action::MoveMsg => job.do_DC_JOB_MOVE_MSG(context),
|
Action::MarkseenMsgOnImap => {
|
||||||
|
job.do_DC_JOB_MARKSEEN_MSG_ON_IMAP(context, inbox.as_mut().unwrap())
|
||||||
|
}
|
||||||
|
Action::MarkseenMdnOnImap => {
|
||||||
|
job.do_DC_JOB_MARKSEEN_MDN_ON_IMAP(context, inbox.as_mut().unwrap())
|
||||||
|
}
|
||||||
|
Action::MoveMsg => job.do_DC_JOB_MOVE_MSG(context, inbox.as_mut().unwrap()),
|
||||||
Action::SendMdn => job.do_DC_JOB_SEND(context),
|
Action::SendMdn => job.do_DC_JOB_SEND(context),
|
||||||
Action::ConfigureImap => dc_job_do_DC_JOB_CONFIGURE_IMAP(context),
|
Action::ConfigureImap => {
|
||||||
|
dc_job_do_DC_JOB_CONFIGURE_IMAP(context, inbox.as_mut().unwrap())
|
||||||
|
}
|
||||||
Action::ImexImap => match job_do_DC_JOB_IMEX_IMAP(context, &job) {
|
Action::ImexImap => match job_do_DC_JOB_IMEX_IMAP(context, &job) {
|
||||||
Ok(()) => {}
|
Ok(()) => {}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
@@ -926,7 +924,7 @@ fn suspend_smtp_thread(context: &Context, suspend: bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn connect_to_inbox(context: &Context, inbox: &Imap) -> libc::c_int {
|
pub fn connect_to_inbox(context: &Context, inbox: &mut Imap) -> libc::c_int {
|
||||||
let ret_connected = dc_connect_to_configured_imap(context, inbox);
|
let ret_connected = dc_connect_to_configured_imap(context, inbox);
|
||||||
if 0 != ret_connected {
|
if 0 != ret_connected {
|
||||||
inbox.set_watch_folder("INBOX".into());
|
inbox.set_watch_folder("INBOX".into());
|
||||||
@@ -1004,7 +1002,7 @@ pub fn job_add(
|
|||||||
).ok();
|
).ok();
|
||||||
|
|
||||||
match thread {
|
match thread {
|
||||||
Thread::Imap => interrupt_imap_idle(context),
|
Thread::Imap => {} //FIXME interrupt_imap_idle(context),
|
||||||
Thread::Smtp => interrupt_smtp_idle(context),
|
Thread::Smtp => interrupt_smtp_idle(context),
|
||||||
Thread::Unknown => {}
|
Thread::Unknown => {}
|
||||||
}
|
}
|
||||||
@@ -1021,10 +1019,9 @@ pub fn interrupt_smtp_idle(context: &Context) {
|
|||||||
cvar.notify_one();
|
cvar.notify_one();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn interrupt_imap_idle(context: &Context) {
|
pub fn interrupt_imap_idle(context: &Context, inbox: &mut Imap) {
|
||||||
info!(context, "Interrupting INBOX-IDLE...",);
|
info!(context, "Interrupting INBOX-IDLE...",);
|
||||||
|
|
||||||
*context.perform_inbox_jobs_needed.write().unwrap() = true;
|
*context.perform_inbox_jobs_needed.write().unwrap() = true;
|
||||||
|
inbox.interrupt_idle();
|
||||||
context.inbox.read().unwrap().interrupt_idle();
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ use crate::imap::Imap;
|
|||||||
pub struct JobThread {
|
pub struct JobThread {
|
||||||
pub name: &'static str,
|
pub name: &'static str,
|
||||||
pub folder_config_name: &'static str,
|
pub folder_config_name: &'static str,
|
||||||
pub imap: Imap,
|
|
||||||
pub state: Arc<(Mutex<JobState>, Condvar)>,
|
pub state: Arc<(Mutex<JobState>, Condvar)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -21,21 +20,20 @@ pub struct JobState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl JobThread {
|
impl JobThread {
|
||||||
pub fn new(name: &'static str, folder_config_name: &'static str, imap: Imap) -> Self {
|
pub fn new(name: &'static str, folder_config_name: &'static str) -> Self {
|
||||||
JobThread {
|
JobThread {
|
||||||
name,
|
name,
|
||||||
folder_config_name,
|
folder_config_name,
|
||||||
imap,
|
|
||||||
state: Arc::new((Mutex::new(Default::default()), Condvar::new())),
|
state: Arc::new((Mutex::new(Default::default()), Condvar::new())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn suspend(&self, context: &Context) {
|
pub fn suspend(&self, context: &Context, imap: &mut Imap) {
|
||||||
info!(context, "Suspending {}-thread.", self.name,);
|
info!(context, "Suspending {}-thread.", self.name,);
|
||||||
{
|
{
|
||||||
self.state.0.lock().unwrap().suspended = true;
|
self.state.0.lock().unwrap().suspended = true;
|
||||||
}
|
}
|
||||||
self.interrupt_idle(context);
|
self.interrupt_idle(context, imap);
|
||||||
loop {
|
loop {
|
||||||
let using_handle = self.state.0.lock().unwrap().using_handle;
|
let using_handle = self.state.0.lock().unwrap().using_handle;
|
||||||
if !using_handle {
|
if !using_handle {
|
||||||
@@ -56,14 +54,14 @@ impl JobThread {
|
|||||||
cvar.notify_one();
|
cvar.notify_one();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn interrupt_idle(&self, context: &Context) {
|
pub fn interrupt_idle(&self, context: &Context, imap: &mut Imap) {
|
||||||
{
|
{
|
||||||
self.state.0.lock().unwrap().jobs_needed = true;
|
self.state.0.lock().unwrap().jobs_needed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
info!(context, "Interrupting {}-IDLE...", self.name);
|
info!(context, "Interrupting {}-IDLE...", self.name);
|
||||||
|
|
||||||
self.imap.interrupt_idle();
|
imap.interrupt_idle();
|
||||||
|
|
||||||
let &(ref lock, ref cvar) = &*self.state.clone();
|
let &(ref lock, ref cvar) = &*self.state.clone();
|
||||||
let mut state = lock.lock().unwrap();
|
let mut state = lock.lock().unwrap();
|
||||||
@@ -72,7 +70,7 @@ impl JobThread {
|
|||||||
cvar.notify_one();
|
cvar.notify_one();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fetch(&mut self, context: &Context, use_network: bool) {
|
pub fn fetch(&self, context: &Context, use_network: bool, imap: &mut Imap) {
|
||||||
{
|
{
|
||||||
let &(ref lock, _) = &*self.state.clone();
|
let &(ref lock, _) = &*self.state.clone();
|
||||||
let mut state = lock.lock().unwrap();
|
let mut state = lock.lock().unwrap();
|
||||||
@@ -86,13 +84,13 @@ impl JobThread {
|
|||||||
|
|
||||||
if use_network {
|
if use_network {
|
||||||
let start = std::time::Instant::now();
|
let start = std::time::Instant::now();
|
||||||
if self.connect_to_imap(context) {
|
if self.connect_to_imap(context, imap) {
|
||||||
info!(context, "{}-fetch started...", self.name);
|
info!(context, "{}-fetch started...", self.name);
|
||||||
self.imap.fetch(context);
|
imap.fetch(context);
|
||||||
|
|
||||||
if self.imap.should_reconnect() {
|
if imap.should_reconnect() {
|
||||||
info!(context, "{}-fetch aborted, starting over...", self.name,);
|
info!(context, "{}-fetch aborted, starting over...", self.name,);
|
||||||
self.imap.fetch(context);
|
imap.fetch(context);
|
||||||
}
|
}
|
||||||
info!(
|
info!(
|
||||||
context,
|
context,
|
||||||
@@ -106,35 +104,39 @@ impl JobThread {
|
|||||||
self.state.0.lock().unwrap().using_handle = false;
|
self.state.0.lock().unwrap().using_handle = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn connect_to_imap(&self, context: &Context) -> bool {
|
fn connect_to_imap(&self, context: &Context, imap: &mut Imap) -> bool {
|
||||||
if self.imap.is_connected() {
|
async_std::task::block_on(async move {
|
||||||
return true;
|
if imap.is_connected().await {
|
||||||
}
|
return true;
|
||||||
|
|
||||||
let mut ret_connected = dc_connect_to_configured_imap(context, &self.imap) != 0;
|
|
||||||
|
|
||||||
if ret_connected {
|
|
||||||
if context
|
|
||||||
.sql
|
|
||||||
.get_raw_config_int(context, "folders_configured")
|
|
||||||
.unwrap_or_default()
|
|
||||||
< 3
|
|
||||||
{
|
|
||||||
self.imap.configure_folders(context, 0x1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(mvbox_name) = context.sql.get_raw_config(context, self.folder_config_name) {
|
let mut ret_connected = dc_connect_to_configured_imap(context, imap) != 0;
|
||||||
self.imap.set_watch_folder(mvbox_name);
|
|
||||||
} else {
|
|
||||||
self.imap.disconnect(context);
|
|
||||||
ret_connected = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret_connected
|
if ret_connected {
|
||||||
|
if context
|
||||||
|
.sql
|
||||||
|
.get_raw_config_int(context, "folders_configured")
|
||||||
|
.unwrap_or_default()
|
||||||
|
< 3
|
||||||
|
{
|
||||||
|
imap.configure_folders(context, 0x1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(mvbox_name) =
|
||||||
|
context.sql.get_raw_config(context, self.folder_config_name)
|
||||||
|
{
|
||||||
|
imap.set_watch_folder(mvbox_name);
|
||||||
|
} else {
|
||||||
|
imap.disconnect();
|
||||||
|
ret_connected = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret_connected
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn idle(&self, context: &Context, use_network: bool) {
|
pub fn idle(&self, context: &Context, use_network: bool, imap: &mut Imap) {
|
||||||
{
|
{
|
||||||
let &(ref lock, ref cvar) = &*self.state.clone();
|
let &(ref lock, ref cvar) = &*self.state.clone();
|
||||||
let mut state = lock.lock().unwrap();
|
let mut state = lock.lock().unwrap();
|
||||||
@@ -170,9 +172,9 @@ impl JobThread {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.connect_to_imap(context);
|
self.connect_to_imap(context, imap);
|
||||||
info!(context, "{}-IDLE started...", self.name,);
|
info!(context, "{}-IDLE started...", self.name);
|
||||||
self.imap.idle(context);
|
imap.idle(context);
|
||||||
info!(context, "{}-IDLE ended.", self.name);
|
info!(context, "{}-IDLE ended.", self.name);
|
||||||
|
|
||||||
self.state.0.lock().unwrap().using_handle = false;
|
self.state.0.lock().unwrap().using_handle = false;
|
||||||
|
|||||||
@@ -39,7 +39,8 @@ pub mod constants;
|
|||||||
pub mod contact;
|
pub mod contact;
|
||||||
pub mod context;
|
pub mod context;
|
||||||
mod e2ee;
|
mod e2ee;
|
||||||
mod imap;
|
pub mod imap;
|
||||||
|
mod imap_client;
|
||||||
pub mod imex;
|
pub mod imex;
|
||||||
pub mod job;
|
pub mod job;
|
||||||
mod job_thread;
|
mod job_thread;
|
||||||
|
|||||||
@@ -251,28 +251,28 @@ fn get_readable_flags(flags: i32) -> String {
|
|||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dc_build_tls(
|
// pub fn dc_build_tls(
|
||||||
certificate_checks: CertificateChecks,
|
// certificate_checks: CertificateChecks,
|
||||||
) -> Result<native_tls::TlsConnector, native_tls::Error> {
|
// ) -> Result<native_tls::TlsConnector, native_tls::Error> {
|
||||||
let mut tls_builder = native_tls::TlsConnector::builder();
|
// let mut tls_builder = native_tls::TlsConnector::builder();
|
||||||
match certificate_checks {
|
// match certificate_checks {
|
||||||
CertificateChecks::Automatic => {
|
// CertificateChecks::Automatic => {
|
||||||
// Same as AcceptInvalidCertificates for now.
|
// // Same as AcceptInvalidCertificates for now.
|
||||||
// TODO: use provider database when it becomes available
|
// // TODO: use provider database when it becomes available
|
||||||
tls_builder
|
// tls_builder
|
||||||
.danger_accept_invalid_hostnames(true)
|
// .danger_accept_invalid_hostnames(true)
|
||||||
.danger_accept_invalid_certs(true)
|
// .danger_accept_invalid_certs(true)
|
||||||
}
|
// }
|
||||||
CertificateChecks::Strict => &mut tls_builder,
|
// CertificateChecks::Strict => &mut tls_builder,
|
||||||
CertificateChecks::AcceptInvalidHostnames => {
|
// CertificateChecks::AcceptInvalidHostnames => {
|
||||||
tls_builder.danger_accept_invalid_hostnames(true)
|
// tls_builder.danger_accept_invalid_hostnames(true)
|
||||||
}
|
// }
|
||||||
CertificateChecks::AcceptInvalidCertificates => tls_builder
|
// CertificateChecks::AcceptInvalidCertificates => tls_builder
|
||||||
.danger_accept_invalid_hostnames(true)
|
// .danger_accept_invalid_hostnames(true)
|
||||||
.danger_accept_invalid_certs(true),
|
// .danger_accept_invalid_certs(true),
|
||||||
}
|
// }
|
||||||
.build()
|
// .build()
|
||||||
}
|
// }
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use crate::constants::*;
|
|||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::events::Event;
|
use crate::events::Event;
|
||||||
use crate::login_param::{dc_build_tls, LoginParam};
|
use crate::login_param::LoginParam;
|
||||||
use crate::oauth2::*;
|
use crate::oauth2::*;
|
||||||
|
|
||||||
#[derive(DebugStub)]
|
#[derive(DebugStub)]
|
||||||
@@ -65,8 +65,11 @@ impl Smtp {
|
|||||||
let domain = &lp.send_server;
|
let domain = &lp.send_server;
|
||||||
let port = lp.send_port as u16;
|
let port = lp.send_port as u16;
|
||||||
|
|
||||||
let tls = dc_build_tls(lp.smtp_certificate_checks).unwrap();
|
let mut tls_config = rustls::ClientConfig::new();
|
||||||
let tls_parameters = ClientTlsParameters::new(domain.to_string(), tls);
|
tls_config
|
||||||
|
.root_store
|
||||||
|
.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
|
||||||
|
let tls_parameters = ClientTlsParameters::new(domain.to_string(), tls_config);
|
||||||
|
|
||||||
let (creds, mechanism) = if 0 != lp.server_flags & (DC_LP_AUTH_OAUTH2 as i32) {
|
let (creds, mechanism) = if 0 != lp.server_flags & (DC_LP_AUTH_OAUTH2 as i32) {
|
||||||
// oauth2
|
// oauth2
|
||||||
|
|||||||
Reference in New Issue
Block a user