mirror of
https://github.com/chatmail/core.git
synced 2026-06-15 04:06:37 +03:00
Compare commits
1 Commits
less_job_i
...
no_format_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ed790879cd |
6
Cargo.lock
generated
6
Cargo.lock
generated
@@ -85,7 +85,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "async-imap"
|
||||
version = "0.1.1"
|
||||
source = "git+https://github.com/async-email/async-imap#d7836416766b55d8d03587ea5326eecf501c2030"
|
||||
source = "git+https://github.com/async-email/async-imap?branch=native_tls#3dc3681a9b158504a0cf11656854db5096476e2f"
|
||||
dependencies = [
|
||||
"async-attributes 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"async-native-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -637,7 +637,7 @@ dependencies = [
|
||||
name = "deltachat"
|
||||
version = "1.0.0-beta.16"
|
||||
dependencies = [
|
||||
"async-imap 0.1.1 (git+https://github.com/async-email/async-imap)",
|
||||
"async-imap 0.1.1 (git+https://github.com/async-email/async-imap?branch=native_tls)",
|
||||
"async-native-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"async-smtp 0.1.0 (git+https://github.com/async-email/async-smtp)",
|
||||
"async-std 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -3320,7 +3320,7 @@ dependencies = [
|
||||
"checksum arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8"
|
||||
"checksum ascii_utils 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "71938f30533e4d95a6d17aa530939da3842c2ab6f4f84b9dae68447e4129f74a"
|
||||
"checksum async-attributes 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "efd3d156917d94862e779f356c5acae312b08fd3121e792c857d7928c8088423"
|
||||
"checksum async-imap 0.1.1 (git+https://github.com/async-email/async-imap)" = "<none>"
|
||||
"checksum async-imap 0.1.1 (git+https://github.com/async-email/async-imap?branch=native_tls)" = "<none>"
|
||||
"checksum async-macros 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "644a5a8de80f2085a1e7e57cd1544a2a7438f6e003c0790999bd43b92a77cdb2"
|
||||
"checksum async-native-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a29e9e4ed87f4070dd6099d0bd5edfc7692c94442c80d656b50a802c6fde23b7"
|
||||
"checksum async-smtp 0.1.0 (git+https://github.com/async-email/async-smtp)" = "<none>"
|
||||
|
||||
@@ -20,7 +20,7 @@ num-traits = "0.2.6"
|
||||
async-smtp = { git = "https://github.com/async-email/async-smtp", branch = "master" }
|
||||
email = { git = "https://github.com/deltachat/rust-email", branch = "master" }
|
||||
lettre_email = { git = "https://github.com/deltachat/lettre", branch = "native_tls" }
|
||||
async-imap = { git = "https://github.com/async-email/async-imap" }
|
||||
async-imap = { git = "https://github.com/async-email/async-imap", branch="native_tls", default-features = false, features = ["tls_native"] }
|
||||
async-native-tls = "0.1.1"
|
||||
async-std = { version = "1.0", features = ["unstable"] }
|
||||
base64 = "0.11"
|
||||
|
||||
@@ -509,7 +509,7 @@ pub unsafe extern "C" fn dc_interrupt_imap_idle(context: *mut dc_context_t) {
|
||||
}
|
||||
let ffi_context = &*context;
|
||||
ffi_context
|
||||
.with_inner(|ctx| job::interrupt_inbox_idle(ctx))
|
||||
.with_inner(|ctx| job::interrupt_inbox_idle(ctx, true))
|
||||
.unwrap_or(())
|
||||
}
|
||||
|
||||
|
||||
@@ -491,7 +491,7 @@ pub fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::Error> {
|
||||
println!("{:#?}", context.get_info());
|
||||
}
|
||||
"interrupt" => {
|
||||
interrupt_inbox_idle(context);
|
||||
interrupt_inbox_idle(context, true);
|
||||
}
|
||||
"maybenetwork" => {
|
||||
maybe_network(context);
|
||||
|
||||
@@ -202,7 +202,7 @@ fn stop_threads(context: &Context) {
|
||||
println!("Stopping threads");
|
||||
IS_RUNNING.store(false, Ordering::Relaxed);
|
||||
|
||||
interrupt_inbox_idle(context);
|
||||
interrupt_inbox_idle(context, true);
|
||||
interrupt_mvbox_idle(context);
|
||||
interrupt_sentbox_idle(context);
|
||||
interrupt_smtp_idle(context);
|
||||
|
||||
@@ -104,7 +104,7 @@ fn main() {
|
||||
println!("stopping threads");
|
||||
|
||||
*running.write().unwrap() = false;
|
||||
deltachat::job::interrupt_inbox_idle(&ctx);
|
||||
deltachat::job::interrupt_inbox_idle(&ctx, true);
|
||||
deltachat::job::interrupt_smtp_idle(&ctx);
|
||||
|
||||
println!("joining");
|
||||
|
||||
23
src/chat.rs
23
src/chat.rs
@@ -646,8 +646,8 @@ pub fn create_or_lookup_by_contact_id(
|
||||
sql::execute(
|
||||
context,
|
||||
&context.sql,
|
||||
"INSERT INTO chats (type, name, param, blocked, grpid, created_timestamp) VALUES(?, ?, ?, ?, ?, ?)",
|
||||
params![
|
||||
format!(
|
||||
"INSERT INTO chats (type, name, param, blocked, grpid, created_timestamp) VALUES({}, '{}', '{}', {}, '{}', {})",
|
||||
100,
|
||||
chat_name,
|
||||
match contact_id {
|
||||
@@ -658,7 +658,8 @@ pub fn create_or_lookup_by_contact_id(
|
||||
create_blocked as u8,
|
||||
contact.get_addr(),
|
||||
time(),
|
||||
]
|
||||
),
|
||||
params![],
|
||||
)?;
|
||||
|
||||
let chat_id = sql::get_rowid(context, &context.sql, "chats", "grpid", contact.get_addr());
|
||||
@@ -666,8 +667,11 @@ pub fn create_or_lookup_by_contact_id(
|
||||
sql::execute(
|
||||
context,
|
||||
&context.sql,
|
||||
"INSERT INTO chats_contacts (chat_id, contact_id) VALUES(?, ?)",
|
||||
params![chat_id, contact_id],
|
||||
format!(
|
||||
"INSERT INTO chats_contacts (chat_id, contact_id) VALUES({}, {})",
|
||||
chat_id, contact_id
|
||||
),
|
||||
params![],
|
||||
)?;
|
||||
|
||||
if contact_id == DC_CONTACT_ID_SELF {
|
||||
@@ -1352,7 +1356,7 @@ pub fn delete(context: &Context, chat_id: u32) -> Result<(), Error> {
|
||||
});
|
||||
|
||||
job_kill_action(context, Action::Housekeeping);
|
||||
add_job_with_interrupt(context, Action::Housekeeping, 0, Params::new(), 10);
|
||||
job_add(context, Action::Housekeeping, 0, Params::new(), 10);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -1911,11 +1915,8 @@ pub fn forward_msgs(context: &Context, msg_ids: &[MsgId], chat_id: u32) -> Resul
|
||||
ensure!(chat.can_send(), "cannot send to chat #{}", chat_id);
|
||||
curr_timestamp = dc_create_smeared_timestamps(context, msg_ids.len());
|
||||
let ids = context.sql.query_map(
|
||||
format!(
|
||||
"SELECT id FROM msgs WHERE id IN({}) ORDER BY timestamp,id",
|
||||
msg_ids.iter().map(|_| "?").join(",")
|
||||
),
|
||||
msg_ids,
|
||||
"SELECT id FROM msgs WHERE id IN({}) ORDER BY timestamp,id",
|
||||
params![msg_ids.iter().map(|_| "?").join(",")],
|
||||
|row| row.get::<_, MsgId>(0),
|
||||
|ids| ids.collect::<Result<Vec<_>, _>>().map_err(Into::into),
|
||||
)?;
|
||||
|
||||
@@ -143,7 +143,7 @@ impl Context {
|
||||
}
|
||||
Config::InboxWatch => {
|
||||
let ret = self.sql.set_raw_config(self, key, value);
|
||||
interrupt_inbox_idle(self);
|
||||
interrupt_inbox_idle(self, true);
|
||||
ret
|
||||
}
|
||||
Config::SentboxWatch => {
|
||||
|
||||
@@ -6,8 +6,6 @@ mod read_url;
|
||||
|
||||
use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC};
|
||||
|
||||
use async_std::task;
|
||||
|
||||
use crate::config::Config;
|
||||
use crate::constants::*;
|
||||
use crate::context::Context;
|
||||
@@ -38,7 +36,7 @@ pub fn configure(context: &Context) {
|
||||
return;
|
||||
}
|
||||
job_kill_action(context, Action::ConfigureImap);
|
||||
add_job_with_interrupt(context, Action::ConfigureImap, 0, Params::new(), 0);
|
||||
job_add(context, Action::ConfigureImap, 0, Params::new(), 0);
|
||||
}
|
||||
|
||||
/// Check if the context is already configured.
|
||||
@@ -542,14 +540,13 @@ fn try_imap_one_param(context: &Context, param: &LoginParam) -> Option<bool> {
|
||||
param.imap_certificate_checks
|
||||
);
|
||||
info!(context, "Trying: {}", inf);
|
||||
if task::block_on(
|
||||
context
|
||||
.inbox_thread
|
||||
.read()
|
||||
.unwrap()
|
||||
.imap
|
||||
.connect(context, ¶m),
|
||||
) {
|
||||
if context
|
||||
.inbox_thread
|
||||
.read()
|
||||
.unwrap()
|
||||
.imap
|
||||
.connect(context, ¶m)
|
||||
{
|
||||
info!(context, "success: {}", inf);
|
||||
return Some(true);
|
||||
}
|
||||
|
||||
@@ -14,11 +14,13 @@ use crate::contact::*;
|
||||
use crate::error::*;
|
||||
use crate::events::Event;
|
||||
use crate::imap::*;
|
||||
use crate::job::*;
|
||||
use crate::job_thread::JobThread;
|
||||
use crate::key::*;
|
||||
use crate::login_param::LoginParam;
|
||||
use crate::lot::Lot;
|
||||
use crate::message::{self, MsgId};
|
||||
use crate::message::{self, Message, MsgId};
|
||||
use crate::param::Params;
|
||||
use crate::smtp::Smtp;
|
||||
use crate::sql::Sql;
|
||||
|
||||
@@ -44,6 +46,7 @@ pub struct Context {
|
||||
/// Blob directory path
|
||||
blobdir: PathBuf,
|
||||
pub sql: Sql,
|
||||
pub perform_inbox_jobs_needed: Arc<RwLock<bool>>,
|
||||
pub probe_imap_network: Arc<RwLock<bool>>,
|
||||
pub inbox_thread: Arc<RwLock<JobThread>>,
|
||||
pub sentbox_thread: Arc<RwLock<JobThread>>,
|
||||
@@ -146,6 +149,7 @@ impl Context {
|
||||
Imap::new(),
|
||||
))),
|
||||
probe_imap_network: Arc::new(RwLock::new(false)),
|
||||
perform_inbox_jobs_needed: Arc::new(RwLock::new(false)),
|
||||
generating_key_mutex: Mutex::new(()),
|
||||
translated_stockstrings: RwLock::new(HashMap::new()),
|
||||
};
|
||||
@@ -432,6 +436,34 @@ impl Context {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn do_heuristics_moves(&self, folder: &str, msg_id: MsgId) {
|
||||
if !self.get_config_bool(Config::MvboxMove) {
|
||||
return;
|
||||
}
|
||||
|
||||
if self.is_mvbox(folder) {
|
||||
return;
|
||||
}
|
||||
if let Ok(msg) = Message::load_from_db(self, msg_id) {
|
||||
if msg.is_setupmessage() {
|
||||
// do not move setup messages;
|
||||
// there may be a non-delta device that wants to handle it
|
||||
return;
|
||||
}
|
||||
|
||||
// 1 = dc message, 2 = reply to dc message
|
||||
if 0 != msg.is_dc_message {
|
||||
job_add(
|
||||
self,
|
||||
Action::MoveMsg,
|
||||
msg.id.to_u32() as i32,
|
||||
Params::new(),
|
||||
0,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Context {
|
||||
|
||||
@@ -250,7 +250,7 @@ pub fn dc_receive_imf(
|
||||
|
||||
// if we delete we don't need to try moving messages
|
||||
if needs_delete_job && !created_db_entries.is_empty() {
|
||||
add_job_no_interrupt(
|
||||
job_add(
|
||||
context,
|
||||
Action::DeleteMsgOnImap,
|
||||
created_db_entries[0].1.to_u32() as i32,
|
||||
@@ -258,7 +258,7 @@ pub fn dc_receive_imf(
|
||||
0,
|
||||
);
|
||||
} else {
|
||||
crate::imap::do_heuristics_moves(context, server_folder.as_ref(), insert_msg_id);
|
||||
context.do_heuristics_moves(server_folder.as_ref(), insert_msg_id);
|
||||
}
|
||||
|
||||
info!(
|
||||
@@ -1148,12 +1148,9 @@ fn create_or_lookup_adhoc_group(
|
||||
if !chat_ids.is_empty() {
|
||||
let chat_ids_str = join(chat_ids.iter().map(|x| x.to_string()), ",");
|
||||
let res = context.sql.query_row(
|
||||
format!(
|
||||
"SELECT c.id, c.blocked FROM chats c \
|
||||
LEFT JOIN msgs m ON m.chat_id=c.id WHERE c.id IN({}) ORDER BY m.timestamp DESC, m.id DESC LIMIT 1;",
|
||||
chat_ids_str
|
||||
),
|
||||
params![],
|
||||
"SELECT c.id, c.blocked FROM chats c \
|
||||
LEFT JOIN msgs m ON m.chat_id=c.id WHERE c.id IN({}) ORDER BY m.timestamp DESC, m.id DESC LIMIT 1;",
|
||||
params!(chat_ids_str),
|
||||
|row| {
|
||||
Ok((row.get::<_, i32>(0)?, row.get::<_, Option<Blocked>>(1)?.unwrap_or_default()))
|
||||
}
|
||||
@@ -1252,11 +1249,8 @@ fn create_adhoc_grp_id(context: &Context, member_ids: &[u32]) -> String {
|
||||
let members = context
|
||||
.sql
|
||||
.query_map(
|
||||
format!(
|
||||
"SELECT addr FROM contacts WHERE id IN({}) AND id!=1", // 1=DC_CONTACT_ID_SELF
|
||||
member_ids_str
|
||||
),
|
||||
params![],
|
||||
"SELECT addr FROM contacts WHERE id IN({}) AND id!=1", // 1=DC_CONTACT_ID_SELF
|
||||
params![member_ids_str],
|
||||
|row| row.get::<_, String>(0),
|
||||
|rows| {
|
||||
let mut addrs = rows.collect::<std::result::Result<Vec<_>, _>>()?;
|
||||
@@ -1300,17 +1294,14 @@ fn search_chat_ids_by_contact_ids(
|
||||
contact_ids.sort();
|
||||
let contact_ids_str = join(contact_ids.iter().map(|x| x.to_string()), ",");
|
||||
context.sql.query_map(
|
||||
format!(
|
||||
"SELECT DISTINCT cc.chat_id, cc.contact_id \
|
||||
FROM chats_contacts cc \
|
||||
LEFT JOIN chats c ON c.id=cc.chat_id \
|
||||
WHERE cc.chat_id IN(SELECT chat_id FROM chats_contacts WHERE contact_id IN({})) \
|
||||
AND c.type=120 \
|
||||
AND cc.contact_id!=1 \
|
||||
ORDER BY cc.chat_id, cc.contact_id;", // 1=DC_CONTACT_ID_SELF
|
||||
contact_ids_str
|
||||
),
|
||||
params![],
|
||||
"SELECT DISTINCT cc.chat_id, cc.contact_id \
|
||||
FROM chats_contacts cc \
|
||||
LEFT JOIN chats c ON c.id=cc.chat_id \
|
||||
WHERE cc.chat_id IN(SELECT chat_id FROM chats_contacts WHERE contact_id IN({})) \
|
||||
AND c.type=120 \
|
||||
AND cc.contact_id!=1 \
|
||||
ORDER BY cc.chat_id, cc.contact_id;", // 1=DC_CONTACT_ID_SELF
|
||||
params![contact_ids_str],
|
||||
|row| Ok((row.get::<_, u32>(0)?, row.get::<_, u32>(1)?)),
|
||||
|rows| {
|
||||
let mut last_chat_id = 0;
|
||||
@@ -1337,8 +1328,8 @@ fn search_chat_ids_by_contact_ids(
|
||||
if matches == contact_ids.len() && mismatches == 0 {
|
||||
chat_ids.push(last_chat_id);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
Ok(())
|
||||
},
|
||||
)?;
|
||||
}
|
||||
}
|
||||
@@ -1391,12 +1382,9 @@ fn check_verified_properties(
|
||||
let to_ids_str = join(to_ids.iter().map(|x| x.to_string()), ",");
|
||||
|
||||
let rows = context.sql.query_map(
|
||||
format!(
|
||||
"SELECT c.addr, LENGTH(ps.verified_key_fingerprint) FROM contacts c \
|
||||
LEFT JOIN acpeerstates ps ON c.addr=ps.addr WHERE c.id IN({}) ",
|
||||
to_ids_str
|
||||
),
|
||||
params![],
|
||||
"SELECT c.addr, LENGTH(ps.verified_key_fingerprint) FROM contacts c \
|
||||
LEFT JOIN acpeerstates ps ON c.addr=ps.addr WHERE c.id IN({}) ",
|
||||
params![to_ids_str],
|
||||
|row| Ok((row.get::<_, String>(0)?, row.get::<_, i32>(1).unwrap_or(0))),
|
||||
|rows| {
|
||||
rows.collect::<std::result::Result<Vec<_>, _>>()
|
||||
|
||||
@@ -3,7 +3,6 @@ use super::Imap;
|
||||
use async_imap::extensions::idle::IdleResponse;
|
||||
use async_std::prelude::*;
|
||||
use async_std::task;
|
||||
use core::cmp::min;
|
||||
use std::sync::atomic::Ordering;
|
||||
use std::time::{Duration, SystemTime};
|
||||
|
||||
@@ -46,12 +45,7 @@ impl Imap {
|
||||
task::block_on(async move { self.config.read().await.can_idle })
|
||||
}
|
||||
|
||||
pub fn idle(
|
||||
&self,
|
||||
context: &Context,
|
||||
watch_folder: Option<String>,
|
||||
until: SystemTime,
|
||||
) -> Result<()> {
|
||||
pub fn idle(&self, context: &Context, watch_folder: Option<String>) -> Result<()> {
|
||||
task::block_on(async move {
|
||||
if !self.can_idle() {
|
||||
return Err(Error::IdleAbilityMissing);
|
||||
@@ -63,18 +57,8 @@ impl Imap {
|
||||
|
||||
self.select_folder(context, watch_folder.clone()).await?;
|
||||
|
||||
let timeout = match until.duration_since(SystemTime::now()) {
|
||||
Ok(timeout) => timeout,
|
||||
Err(_) => {
|
||||
info!(context, "idle called with negative timeout");
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
let timeout = min(timeout, Duration::from_secs(23 * 60));
|
||||
info!(context, "idle-timeout is {:?}", timeout);
|
||||
|
||||
let session = self.session.lock().await.take();
|
||||
|
||||
let timeout = Duration::from_secs(23 * 60);
|
||||
if let Some(session) = session {
|
||||
match session.idle() {
|
||||
// BEWARE: If you change the Secure branch you
|
||||
@@ -83,6 +67,7 @@ impl Imap {
|
||||
if let Err(err) = handle.init().await {
|
||||
return Err(Error::IdleProtocolFailed(err));
|
||||
}
|
||||
|
||||
let (idle_wait, interrupt) = handle.wait_with_timeout(timeout);
|
||||
*self.interrupt.lock().await = Some(interrupt);
|
||||
|
||||
@@ -193,12 +178,7 @@ impl Imap {
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn fake_idle(
|
||||
&self,
|
||||
context: &Context,
|
||||
watch_folder: Option<String>,
|
||||
until: SystemTime,
|
||||
) {
|
||||
pub(crate) fn fake_idle(&self, context: &Context, watch_folder: Option<String>) {
|
||||
// Idle using polling. This is also needed if we're not yet configured -
|
||||
// in this case, we're waiting for a configure job (and an interrupt).
|
||||
task::block_on(async move {
|
||||
@@ -233,11 +213,6 @@ impl Imap {
|
||||
break;
|
||||
}
|
||||
info!(context, "fake_idle is connected");
|
||||
|
||||
if SystemTime::now() > until {
|
||||
info!(context, "fake_idle stopping as jobs need running");
|
||||
break;
|
||||
}
|
||||
// we are connected, let's see if fetching messages results
|
||||
// in anything. If so, we behave as if IDLE had data but
|
||||
// will have already fetched the messages so perform_*_fetch
|
||||
|
||||
173
src/imap/mod.rs
173
src/imap/mod.rs
@@ -17,9 +17,9 @@ use crate::context::Context;
|
||||
use crate::dc_receive_imf::dc_receive_imf;
|
||||
use crate::events::Event;
|
||||
use crate::imap_client::*;
|
||||
use crate::job::{add_job_no_interrupt, Action};
|
||||
use crate::job::{job_add, Action};
|
||||
use crate::login_param::{CertificateChecks, LoginParam};
|
||||
use crate::message::{self, update_server_uid, Message, MsgId};
|
||||
use crate::message::{self, update_server_uid};
|
||||
use crate::oauth2::dc_get_oauth2_access_token;
|
||||
use crate::param::Params;
|
||||
use crate::stock::StockMessage;
|
||||
@@ -339,7 +339,7 @@ impl Imap {
|
||||
let param = LoginParam::from_database(context, "configured_");
|
||||
// the trailing underscore is correct
|
||||
|
||||
if task::block_on(self.connect(context, ¶m)) {
|
||||
if self.connect(context, ¶m) {
|
||||
self.ensure_configured_folders(context, true)
|
||||
} else {
|
||||
Err(Error::ConnectionFailed(format!("{}", param)))
|
||||
@@ -348,80 +348,82 @@ impl Imap {
|
||||
|
||||
/// tries connecting to imap account using the specific login
|
||||
/// parameters
|
||||
pub async fn connect(&self, context: &Context, lp: &LoginParam) -> bool {
|
||||
if lp.mail_server.is_empty() || lp.mail_user.is_empty() || lp.mail_pw.is_empty() {
|
||||
return false;
|
||||
}
|
||||
pub fn connect(&self, context: &Context, lp: &LoginParam) -> bool {
|
||||
task::block_on(async move {
|
||||
if lp.mail_server.is_empty() || lp.mail_user.is_empty() || lp.mail_pw.is_empty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
let addr = &lp.addr;
|
||||
let imap_server = &lp.mail_server;
|
||||
let imap_port = lp.mail_port as u16;
|
||||
let imap_user = &lp.mail_user;
|
||||
let imap_pw = &lp.mail_pw;
|
||||
let server_flags = lp.server_flags as usize;
|
||||
{
|
||||
let addr = &lp.addr;
|
||||
let imap_server = &lp.mail_server;
|
||||
let imap_port = lp.mail_port as u16;
|
||||
let imap_user = &lp.mail_user;
|
||||
let imap_pw = &lp.mail_pw;
|
||||
let server_flags = lp.server_flags as usize;
|
||||
|
||||
let mut config = self.config.write().await;
|
||||
config.addr = addr.to_string();
|
||||
config.imap_server = imap_server.to_string();
|
||||
config.imap_port = imap_port;
|
||||
config.imap_user = imap_user.to_string();
|
||||
config.imap_pw = imap_pw.to_string();
|
||||
config.certificate_checks = lp.imap_certificate_checks;
|
||||
config.server_flags = server_flags;
|
||||
}
|
||||
let mut config = self.config.write().await;
|
||||
config.addr = addr.to_string();
|
||||
config.imap_server = imap_server.to_string();
|
||||
config.imap_port = imap_port;
|
||||
config.imap_user = imap_user.to_string();
|
||||
config.imap_pw = imap_pw.to_string();
|
||||
config.certificate_checks = lp.imap_certificate_checks;
|
||||
config.server_flags = server_flags;
|
||||
}
|
||||
|
||||
if let Err(err) = self.setup_handle_if_needed(context).await {
|
||||
warn!(context, "failed to setup imap handle: {}", err);
|
||||
self.free_connect_params().await;
|
||||
return false;
|
||||
}
|
||||
if let Err(err) = self.setup_handle_if_needed(context).await {
|
||||
warn!(context, "failed to setup imap handle: {}", err);
|
||||
self.free_connect_params().await;
|
||||
return false;
|
||||
}
|
||||
|
||||
let teardown = match &mut *self.session.lock().await {
|
||||
Some(ref mut session) => match session.capabilities().await {
|
||||
Ok(caps) => {
|
||||
if !context.sql.is_open() {
|
||||
warn!(context, "IMAP-LOGIN as {} ok but ABORTING", lp.mail_user,);
|
||||
true
|
||||
} else {
|
||||
let can_idle = caps.has_str("IDLE");
|
||||
let has_xlist = caps.has_str("XLIST");
|
||||
let caps_list = caps.iter().fold(String::new(), |s, c| {
|
||||
if let Capability::Atom(x) = c {
|
||||
s + &format!(" {}", x)
|
||||
} else {
|
||||
s + &format!(" {:?}", c)
|
||||
}
|
||||
});
|
||||
let teardown = match &mut *self.session.lock().await {
|
||||
Some(ref mut session) => match session.capabilities().await {
|
||||
Ok(caps) => {
|
||||
if !context.sql.is_open() {
|
||||
warn!(context, "IMAP-LOGIN as {} ok but ABORTING", lp.mail_user,);
|
||||
true
|
||||
} else {
|
||||
let can_idle = caps.has_str("IDLE");
|
||||
let has_xlist = caps.has_str("XLIST");
|
||||
let caps_list = caps.iter().fold(String::new(), |s, c| {
|
||||
if let Capability::Atom(x) = c {
|
||||
s + &format!(" {}", x)
|
||||
} else {
|
||||
s + &format!(" {:?}", c)
|
||||
}
|
||||
});
|
||||
|
||||
self.config.write().await.can_idle = can_idle;
|
||||
self.config.write().await.has_xlist = has_xlist;
|
||||
*self.connected.lock().await = true;
|
||||
emit_event!(
|
||||
context,
|
||||
Event::ImapConnected(format!(
|
||||
"IMAP-LOGIN as {}, capabilities: {}",
|
||||
lp.mail_user, caps_list,
|
||||
))
|
||||
);
|
||||
false
|
||||
self.config.write().await.can_idle = can_idle;
|
||||
self.config.write().await.has_xlist = has_xlist;
|
||||
*self.connected.lock().await = true;
|
||||
emit_event!(
|
||||
context,
|
||||
Event::ImapConnected(format!(
|
||||
"IMAP-LOGIN as {}, capabilities: {}",
|
||||
lp.mail_user, caps_list,
|
||||
))
|
||||
);
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
info!(context, "CAPABILITY command error: {}", err);
|
||||
true
|
||||
}
|
||||
},
|
||||
None => true,
|
||||
};
|
||||
Err(err) => {
|
||||
info!(context, "CAPABILITY command error: {}", err);
|
||||
true
|
||||
}
|
||||
},
|
||||
None => true,
|
||||
};
|
||||
|
||||
if teardown {
|
||||
self.disconnect(context);
|
||||
if teardown {
|
||||
self.disconnect(context);
|
||||
|
||||
false
|
||||
} else {
|
||||
true
|
||||
}
|
||||
false
|
||||
} else {
|
||||
true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn disconnect(&self, context: &Context) {
|
||||
@@ -1202,8 +1204,8 @@ fn precheck_imf(context: &Context, rfc724_mid: &str, server_folder: &str, server
|
||||
{
|
||||
if old_server_folder.is_empty() && old_server_uid == 0 {
|
||||
info!(context, "[move] detected bbc-self {}", rfc724_mid,);
|
||||
do_heuristics_moves(context, server_folder, msg_id);
|
||||
add_job_no_interrupt(
|
||||
context.do_heuristics_moves(server_folder.as_ref(), msg_id);
|
||||
job_add(
|
||||
context,
|
||||
Action::MarkseenMsgOnImap,
|
||||
msg_id.to_u32() as i32,
|
||||
@@ -1237,32 +1239,3 @@ fn prefetch_get_message_id(prefetch_msg: &Fetch) -> Result<String> {
|
||||
|
||||
wrapmime::parse_message_id(&message_id.unwrap()).map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn do_heuristics_moves(context: &Context, folder: &str, msg_id: MsgId) {
|
||||
if !context.get_config_bool(crate::config::Config::MvboxMove) {
|
||||
return;
|
||||
}
|
||||
|
||||
if context.is_mvbox(folder) {
|
||||
return;
|
||||
}
|
||||
if let Ok(msg) = Message::load_from_db(context, msg_id) {
|
||||
if msg.is_setupmessage() {
|
||||
// do not move setup messages;
|
||||
// there may be a non-delta device that wants to handle it
|
||||
return;
|
||||
}
|
||||
|
||||
// 1 = dc message, 2 = reply to dc message
|
||||
if 0 != msg.is_dc_message {
|
||||
// we are called from receive_imf so there is no idle running
|
||||
add_job_no_interrupt(
|
||||
context,
|
||||
Action::MoveMsg,
|
||||
msg.id.to_u32() as i32,
|
||||
Params::new(),
|
||||
0,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ pub fn imex(context: &Context, what: ImexMode, param1: Option<impl AsRef<Path>>)
|
||||
}
|
||||
|
||||
job_kill_action(context, Action::ImexImap);
|
||||
add_job_with_interrupt(context, Action::ImexImap, 0, param, 0);
|
||||
job_add(context, Action::ImexImap, 0, param, 0);
|
||||
}
|
||||
|
||||
/// Returns the filename of the backup found (otherwise an error)
|
||||
|
||||
63
src/job.rs
63
src/job.rs
@@ -35,7 +35,7 @@ const JOB_RETRIES: u32 = 17;
|
||||
/// Thread IDs
|
||||
#[derive(Debug, Display, Copy, Clone, PartialEq, Eq, FromPrimitive, ToPrimitive, FromSql, ToSql)]
|
||||
#[repr(i32)]
|
||||
pub enum Thread {
|
||||
enum Thread {
|
||||
Unknown = 0,
|
||||
Imap = 100,
|
||||
Smtp = 5000,
|
||||
@@ -134,7 +134,7 @@ impl Job {
|
||||
|
||||
/// Updates the job already stored in the database.
|
||||
///
|
||||
/// To add a new job, use [add_job_*].
|
||||
/// To add a new job, use [job_add].
|
||||
fn update(&self, context: &Context) -> bool {
|
||||
sql::execute(
|
||||
context,
|
||||
@@ -436,6 +436,13 @@ pub fn perform_sentbox_fetch(context: &Context) {
|
||||
}
|
||||
|
||||
pub fn perform_inbox_idle(context: &Context) {
|
||||
if *context.perform_inbox_jobs_needed.clone().read().unwrap() {
|
||||
info!(
|
||||
context,
|
||||
"INBOX-IDLE will not be started because of waiting jobs."
|
||||
);
|
||||
return;
|
||||
}
|
||||
let use_network = context.get_config_bool(Config::InboxWatch);
|
||||
|
||||
context
|
||||
@@ -465,8 +472,21 @@ pub fn perform_sentbox_idle(context: &Context) {
|
||||
.idle(context, use_network);
|
||||
}
|
||||
|
||||
pub fn interrupt_inbox_idle(context: &Context) {
|
||||
context.inbox_thread.read().unwrap().interrupt_idle(context);
|
||||
pub fn interrupt_inbox_idle(context: &Context, block: bool) {
|
||||
info!(context, "interrupt_inbox_idle called blocking={}", block);
|
||||
if block {
|
||||
context.inbox_thread.read().unwrap().interrupt_idle(context);
|
||||
} else {
|
||||
match context.inbox_thread.try_read() {
|
||||
Ok(inbox_thread) => {
|
||||
inbox_thread.interrupt_idle(context);
|
||||
}
|
||||
Err(err) => {
|
||||
*context.perform_inbox_jobs_needed.write().unwrap() = true;
|
||||
warn!(context, "could not interrupt idle: {}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn interrupt_mvbox_idle(context: &Context) {
|
||||
@@ -543,7 +563,7 @@ pub fn perform_smtp_idle(context: &Context) {
|
||||
info!(context, "SMTP-idle ended.",);
|
||||
}
|
||||
|
||||
pub(crate) fn get_next_wakeup_time(context: &Context, thread: Thread) -> Duration {
|
||||
fn get_next_wakeup_time(context: &Context, thread: Thread) -> Duration {
|
||||
let t: i64 = context
|
||||
.sql
|
||||
.query_get_value(
|
||||
@@ -553,16 +573,17 @@ pub(crate) fn get_next_wakeup_time(context: &Context, thread: Thread) -> Duratio
|
||||
)
|
||||
.unwrap_or_default();
|
||||
|
||||
let mut wakeup_time = Duration::new(10 * 60, 0);
|
||||
let now = time();
|
||||
if t > 0 {
|
||||
let now = time();
|
||||
if t > now {
|
||||
Duration::new((t - now) as u64, 0)
|
||||
wakeup_time = Duration::new((t - now) as u64, 0);
|
||||
} else {
|
||||
Duration::new(0, 0)
|
||||
wakeup_time = Duration::new(0, 0);
|
||||
}
|
||||
} else {
|
||||
Duration::new(30 * 60, 0)
|
||||
}
|
||||
|
||||
wakeup_time
|
||||
}
|
||||
|
||||
pub fn maybe_network(context: &Context) {
|
||||
@@ -575,7 +596,7 @@ pub fn maybe_network(context: &Context) {
|
||||
}
|
||||
|
||||
interrupt_smtp_idle(context);
|
||||
interrupt_inbox_idle(context);
|
||||
interrupt_inbox_idle(context, true);
|
||||
interrupt_mvbox_idle(context);
|
||||
interrupt_sentbox_idle(context);
|
||||
}
|
||||
@@ -694,6 +715,7 @@ pub fn perform_inbox_jobs(context: &Context) {
|
||||
|
||||
let probe_imap_network = *context.probe_imap_network.clone().read().unwrap();
|
||||
*context.probe_imap_network.write().unwrap() = false;
|
||||
*context.perform_inbox_jobs_needed.write().unwrap() = false;
|
||||
|
||||
job_perform(context, Thread::Imap, probe_imap_network);
|
||||
info!(context, "dc_perform_inbox_jobs ended.",);
|
||||
@@ -896,7 +918,7 @@ fn add_smtp_job(
|
||||
param.set(Param::File, blob.as_name());
|
||||
param.set(Param::Recipients, &recipients);
|
||||
|
||||
add_job_with_interrupt(
|
||||
job_add(
|
||||
context,
|
||||
action,
|
||||
rendered_msg
|
||||
@@ -912,7 +934,7 @@ fn add_smtp_job(
|
||||
|
||||
/// Adds a job to the database, scheduling it `delay_seconds`
|
||||
/// after the current time.
|
||||
pub fn add_job_no_interrupt(
|
||||
pub fn job_add(
|
||||
context: &Context,
|
||||
action: Action,
|
||||
foreign_id: i32,
|
||||
@@ -920,7 +942,7 @@ pub fn add_job_no_interrupt(
|
||||
delay_seconds: i64,
|
||||
) {
|
||||
if action == Action::Unknown {
|
||||
error!(context, "Invalid action passed to add_job_no_interrupt");
|
||||
error!(context, "Invalid action passed to job_add");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -940,20 +962,9 @@ pub fn add_job_no_interrupt(
|
||||
(timestamp + delay_seconds as i64)
|
||||
]
|
||||
).ok();
|
||||
}
|
||||
|
||||
pub fn add_job_with_interrupt(
|
||||
context: &Context,
|
||||
action: Action,
|
||||
foreign_id: i32,
|
||||
param: Params,
|
||||
delay_seconds: i64,
|
||||
) {
|
||||
let thread: Thread = action.into();
|
||||
add_job_no_interrupt(context, action, foreign_id, param, delay_seconds);
|
||||
|
||||
match thread {
|
||||
Thread::Imap => interrupt_inbox_idle(context),
|
||||
Thread::Imap => interrupt_inbox_idle(context, false),
|
||||
Thread::Smtp => interrupt_smtp_idle(context),
|
||||
Thread::Unknown => {}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,6 @@ use std::sync::{Arc, Condvar, Mutex};
|
||||
use crate::context::Context;
|
||||
use crate::error::{Error, Result};
|
||||
use crate::imap::Imap;
|
||||
use crate::job::{get_next_wakeup_time, Thread};
|
||||
use std::time::{Duration, SystemTime};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct JobThread {
|
||||
@@ -59,6 +57,10 @@ impl JobThread {
|
||||
}
|
||||
|
||||
pub fn interrupt_idle(&self, context: &Context) {
|
||||
{
|
||||
self.state.0.lock().unwrap().jobs_needed = true;
|
||||
}
|
||||
|
||||
info!(context, "Interrupting {}-IDLE...", self.name);
|
||||
|
||||
self.imap.interrupt_idle(context);
|
||||
@@ -134,23 +136,18 @@ impl JobThread {
|
||||
}
|
||||
|
||||
pub fn idle(&self, context: &Context, use_network: bool) {
|
||||
// standard idle wait timeout
|
||||
let mut timeout = Duration::from_secs(23 * 60);
|
||||
{
|
||||
let &(ref lock, ref cvar) = &*self.state.clone();
|
||||
let mut state = lock.lock().unwrap();
|
||||
|
||||
// if we are in the inbox (job) thread we only want to wait
|
||||
// until the next job is due.
|
||||
if self.folder_config_name == "configured_inbox_folder" {
|
||||
timeout = get_next_wakeup_time(context, Thread::Imap);
|
||||
if timeout <= Duration::from_millis(20) {
|
||||
info!(
|
||||
context,
|
||||
"INBOX-IDLE will not be started because of waiting jobs."
|
||||
);
|
||||
return;
|
||||
}
|
||||
if state.jobs_needed {
|
||||
info!(
|
||||
context,
|
||||
"{}-IDLE will not be started as it was interrupted while not ideling.",
|
||||
self.name,
|
||||
);
|
||||
state.jobs_needed = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if state.suspended {
|
||||
@@ -174,8 +171,6 @@ impl JobThread {
|
||||
}
|
||||
}
|
||||
|
||||
let until = SystemTime::now() + timeout;
|
||||
|
||||
let prefix = format!("{}-IDLE", self.name);
|
||||
let do_fake_idle = match self.imap.connect_configured(context) {
|
||||
Ok(()) => {
|
||||
@@ -184,7 +179,7 @@ impl JobThread {
|
||||
} else {
|
||||
let watch_folder = self.get_watch_folder(context);
|
||||
info!(context, "{} started...", prefix);
|
||||
let res = self.imap.idle(context, watch_folder, until);
|
||||
let res = self.imap.idle(context, watch_folder);
|
||||
info!(context, "{} ended...", prefix);
|
||||
if let Err(err) = res {
|
||||
warn!(context, "{} failed: {} -> reconnecting", prefix, err);
|
||||
@@ -204,7 +199,7 @@ impl JobThread {
|
||||
};
|
||||
if do_fake_idle {
|
||||
let watch_folder = self.get_watch_folder(context);
|
||||
self.imap.fake_idle(context, watch_folder, until);
|
||||
self.imap.fake_idle(context, watch_folder);
|
||||
}
|
||||
|
||||
self.state.0.lock().unwrap().using_handle = false;
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
#![deny(clippy::correctness, missing_debug_implementations, clippy::all)]
|
||||
// for now we hide warnings to not clutter/hide errors during "cargo clippy"
|
||||
#![allow(clippy::cognitive_complexity, clippy::too_many_arguments)]
|
||||
#![allow(
|
||||
clippy::type_complexity,
|
||||
clippy::cognitive_complexity,
|
||||
clippy::too_many_arguments
|
||||
)]
|
||||
#![allow(clippy::unreadable_literal, clippy::match_bool)]
|
||||
#![feature(ptr_wrapping_offset_from)]
|
||||
#![feature(drain_filter)]
|
||||
|
||||
@@ -226,7 +226,7 @@ pub fn send_locations_to_chat(context: &Context, chat_id: u32, seconds: i64) {
|
||||
context.call_cb(Event::ChatModified(chat_id));
|
||||
if 0 != seconds {
|
||||
schedule_MAYBE_SEND_LOCATIONS(context, false);
|
||||
add_job_with_interrupt(
|
||||
job_add(
|
||||
context,
|
||||
Action::MaybeSendLocationsEnded,
|
||||
chat_id as i32,
|
||||
@@ -241,8 +241,7 @@ pub fn send_locations_to_chat(context: &Context, chat_id: u32, seconds: i64) {
|
||||
#[allow(non_snake_case)]
|
||||
fn schedule_MAYBE_SEND_LOCATIONS(context: &Context, force_schedule: bool) {
|
||||
if force_schedule || !job_action_exists(context, Action::MaybeSendLocations) {
|
||||
// XXX questionable to interrupt but set a +60secs target
|
||||
add_job_with_interrupt(context, Action::MaybeSendLocations, 0, Params::new(), 60);
|
||||
job_add(context, Action::MaybeSendLocations, 0, Params::new(), 60);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -875,7 +875,7 @@ pub fn delete_msgs(context: &Context, msg_ids: &[MsgId]) {
|
||||
}
|
||||
}
|
||||
update_msg_chat_id(context, *msg_id, DC_CHAT_ID_TRASH);
|
||||
add_job_with_interrupt(
|
||||
job_add(
|
||||
context,
|
||||
Action::DeleteMsgOnImap,
|
||||
msg_id.to_u32() as i32,
|
||||
@@ -890,7 +890,7 @@ pub fn delete_msgs(context: &Context, msg_ids: &[MsgId]) {
|
||||
msg_id: MsgId::new(0),
|
||||
});
|
||||
job_kill_action(context, Action::Housekeeping);
|
||||
add_job_with_interrupt(context, Action::Housekeeping, 0, Params::new(), 10);
|
||||
job_add(context, Action::Housekeeping, 0, Params::new(), 10);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -961,7 +961,7 @@ pub fn markseen_msgs(context: &Context, msg_ids: &[MsgId]) -> bool {
|
||||
update_msg_state(context, *id, MessageState::InSeen);
|
||||
info!(context, "Seen message {}.", id);
|
||||
|
||||
add_job_with_interrupt(
|
||||
job_add(
|
||||
context,
|
||||
Action::MarkseenMsgOnImap,
|
||||
id.to_u32() as i32,
|
||||
@@ -1319,7 +1319,7 @@ pub fn update_server_uid(
|
||||
#[allow(dead_code)]
|
||||
pub fn dc_empty_server(context: &Context, flags: u32) {
|
||||
job_kill_action(context, Action::EmptyServer);
|
||||
add_job_with_interrupt(context, Action::EmptyServer, flags as i32, Params::new(), 0);
|
||||
job_add(context, Action::EmptyServer, flags as i32, Params::new(), 0);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -15,7 +15,7 @@ use crate::dc_tools::*;
|
||||
use crate::e2ee;
|
||||
use crate::error::Result;
|
||||
use crate::headerdef::HeaderDef;
|
||||
use crate::job::{add_job_no_interrupt, Action};
|
||||
use crate::job::{job_add, Action};
|
||||
use crate::location;
|
||||
use crate::message;
|
||||
use crate::message::MsgId;
|
||||
@@ -782,7 +782,7 @@ impl<'a> MimeParser<'a> {
|
||||
if self.has_chat_version() && self.context.get_config_bool(Config::MvboxMove) {
|
||||
param.set_int(Param::AlsoMove, 1);
|
||||
}
|
||||
add_job_no_interrupt(self.context, Action::MarkseenMdnOnImap, 0, param, 0);
|
||||
job_add(self.context, Action::MarkseenMdnOnImap, 0, param, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
18
src/pgp.rs
18
src/pgp.rs
@@ -16,7 +16,7 @@ use pgp::types::{
|
||||
};
|
||||
use rand::{thread_rng, CryptoRng, Rng};
|
||||
|
||||
use crate::error::Result;
|
||||
use crate::error::Error;
|
||||
use crate::key::*;
|
||||
use crate::keyring::*;
|
||||
|
||||
@@ -88,7 +88,9 @@ impl<'a> PublicKeyTrait for SignedPublicKeyOrSubkey<'a> {
|
||||
/// Split data from PGP Armored Data as defined in https://tools.ietf.org/html/rfc4880#section-6.2.
|
||||
///
|
||||
/// Returns (type, headers, base64 encoded body).
|
||||
pub fn split_armored_data(buf: &[u8]) -> Result<(BlockType, BTreeMap<String, String>, Vec<u8>)> {
|
||||
pub fn split_armored_data(
|
||||
buf: &[u8],
|
||||
) -> Result<(BlockType, BTreeMap<String, String>, Vec<u8>), Error> {
|
||||
use std::io::Read;
|
||||
|
||||
let cursor = Cursor::new(buf);
|
||||
@@ -192,7 +194,7 @@ pub fn pk_encrypt(
|
||||
plain: &[u8],
|
||||
public_keys_for_encryption: &Keyring,
|
||||
private_key_for_signing: Option<&Key>,
|
||||
) -> Result<String> {
|
||||
) -> Result<String, Error> {
|
||||
let lit_msg = Message::new_literal_bytes("", plain);
|
||||
let pkeys: Vec<SignedPublicKeyOrSubkey> = public_keys_for_encryption
|
||||
.keys()
|
||||
@@ -234,7 +236,7 @@ pub fn pk_decrypt(
|
||||
private_keys_for_decryption: &Keyring,
|
||||
public_keys_for_validation: &Keyring,
|
||||
ret_signature_fingerprints: Option<&mut HashSet<String>>,
|
||||
) -> Result<Vec<u8>> {
|
||||
) -> Result<Vec<u8>, Error> {
|
||||
let (msg, _) = Message::from_armor_single(Cursor::new(ctext))?;
|
||||
let skeys: Vec<&SignedSecretKey> = private_keys_for_decryption
|
||||
.keys()
|
||||
@@ -246,7 +248,7 @@ pub fn pk_decrypt(
|
||||
.collect();
|
||||
|
||||
let (decryptor, _) = msg.decrypt(|| "".into(), || "".into(), &skeys[..])?;
|
||||
let msgs = decryptor.collect::<pgp::errors::Result<Vec<_>>>()?;
|
||||
let msgs = decryptor.collect::<Result<Vec<_>, _>>()?;
|
||||
ensure!(!msgs.is_empty(), "No valid messages found");
|
||||
|
||||
let dec_msg = &msgs[0];
|
||||
@@ -278,7 +280,7 @@ pub fn pk_decrypt(
|
||||
}
|
||||
|
||||
/// Symmetric encryption.
|
||||
pub fn symm_encrypt(passphrase: &str, plain: &[u8]) -> Result<String> {
|
||||
pub fn symm_encrypt(passphrase: &str, plain: &[u8]) -> Result<String, Error> {
|
||||
let mut rng = thread_rng();
|
||||
let lit_msg = Message::new_literal_bytes("", plain);
|
||||
|
||||
@@ -295,11 +297,11 @@ pub fn symm_encrypt(passphrase: &str, plain: &[u8]) -> Result<String> {
|
||||
pub fn symm_decrypt<T: std::io::Read + std::io::Seek>(
|
||||
passphrase: &str,
|
||||
ctext: T,
|
||||
) -> Result<Vec<u8>> {
|
||||
) -> Result<Vec<u8>, Error> {
|
||||
let (enc_msg, _) = Message::from_armor_single(ctext)?;
|
||||
let decryptor = enc_msg.decrypt_with_password(|| passphrase.into())?;
|
||||
|
||||
let msgs = decryptor.collect::<pgp::errors::Result<Vec<_>>>()?;
|
||||
let msgs = decryptor.collect::<Result<Vec<_>, _>>()?;
|
||||
ensure!(!msgs.is_empty(), "No valid messages found");
|
||||
|
||||
match msgs[0].get_content()? {
|
||||
|
||||
Reference in New Issue
Block a user