aerogramme/src/server.rs

107 lines
3.2 KiB
Rust
Raw Normal View History

2023-12-14 14:36:54 +00:00
use std::io::Write;
2023-12-27 13:58:28 +00:00
use std::path::PathBuf;
use std::sync::Arc;
2022-05-19 12:33:49 +00:00
2023-12-06 19:57:25 +00:00
use anyhow::Result;
2022-07-13 09:19:08 +00:00
use futures::try_join;
2022-05-31 15:07:34 +00:00
use log::*;
use tokio::sync::watch;
2022-05-19 12:33:49 +00:00
2022-06-15 16:40:39 +00:00
use crate::config::*;
2022-06-17 16:39:36 +00:00
use crate::imap;
2022-06-22 15:26:52 +00:00
use crate::lmtp::*;
2022-06-20 16:09:20 +00:00
use crate::login::ArcLoginProvider;
2023-12-27 17:33:06 +00:00
use crate::login::{ldap_provider::*, static_provider::*, demo_provider::*};
2022-05-19 12:33:49 +00:00
2022-06-03 09:38:01 +00:00
pub struct Server {
2022-06-15 16:40:39 +00:00
lmtp_server: Option<Arc<LmtpServer>>,
2022-06-17 16:39:36 +00:00
imap_server: Option<imap::Server>,
2023-12-14 14:36:54 +00:00
pid_file: Option<PathBuf>,
2022-06-03 09:38:01 +00:00
}
2022-05-19 12:33:49 +00:00
2022-06-03 09:38:01 +00:00
impl Server {
2023-12-06 19:57:25 +00:00
pub async fn from_companion_config(config: CompanionConfig) -> Result<Self> {
2023-12-14 14:36:54 +00:00
tracing::info!("Init as companion");
2023-12-14 12:03:04 +00:00
let login = Arc::new(StaticLoginProvider::new(config.users).await?);
2022-06-15 16:40:39 +00:00
2023-12-06 19:57:25 +00:00
let lmtp_server = None;
2023-12-14 12:03:04 +00:00
let imap_server = Some(imap::new(config.imap, login.clone()).await?);
2023-12-27 13:58:28 +00:00
Ok(Self {
lmtp_server,
imap_server,
pid_file: config.pid,
})
2023-12-06 19:57:25 +00:00
}
pub async fn from_provider_config(config: ProviderConfig) -> Result<Self> {
2023-12-14 14:36:54 +00:00
tracing::info!("Init as provider");
2023-12-06 19:57:25 +00:00
let login: ArcLoginProvider = match config.users {
2023-12-27 17:33:06 +00:00
UserManagement::Demo => Arc::new(DemoLoginProvider::new()),
2023-12-14 12:03:04 +00:00
UserManagement::Static(x) => Arc::new(StaticLoginProvider::new(x).await?),
2023-12-06 19:57:25 +00:00
UserManagement::Ldap(x) => Arc::new(LdapLoginProvider::new(x)?),
2022-06-22 12:58:57 +00:00
};
2022-06-15 16:40:39 +00:00
2023-12-06 19:57:25 +00:00
let lmtp_server = Some(LmtpServer::new(config.lmtp, login.clone()));
2023-12-14 12:03:04 +00:00
let imap_server = Some(imap::new(config.imap, login.clone()).await?);
2023-12-06 19:57:25 +00:00
2023-12-27 13:58:28 +00:00
Ok(Self {
lmtp_server,
imap_server,
pid_file: config.pid,
})
2022-06-03 09:38:01 +00:00
}
2022-06-01 16:00:56 +00:00
2022-06-15 16:40:39 +00:00
pub async fn run(self) -> Result<()> {
2023-12-14 14:36:54 +00:00
let pid = std::process::id();
2023-12-27 13:58:28 +00:00
tracing::info!(pid = pid, "Starting main loops");
2023-12-14 14:36:54 +00:00
// write the pid file
if let Some(pid_file) = self.pid_file {
let mut file = std::fs::OpenOptions::new()
.write(true)
.create(true)
.truncate(true)
.open(pid_file)?;
file.write_all(pid.to_string().as_bytes())?;
drop(file);
}
2022-05-31 15:07:34 +00:00
let (exit_signal, provoke_exit) = watch_ctrl_c();
2022-06-29 10:52:58 +00:00
let _exit_on_err = move |err: anyhow::Error| {
2022-05-31 15:07:34 +00:00
error!("Error: {}", err);
let _ = provoke_exit.send(true);
2022-05-19 12:33:49 +00:00
};
2022-05-31 15:07:34 +00:00
2022-06-17 08:42:02 +00:00
try_join!(
async {
match self.lmtp_server.as_ref() {
None => Ok(()),
Some(s) => s.run(exit_signal.clone()).await,
}
},
async {
2022-06-22 12:58:57 +00:00
match self.imap_server {
2022-06-17 16:39:36 +00:00
None => Ok(()),
Some(s) => s.run(exit_signal.clone()).await,
2022-06-17 08:42:02 +00:00
}
2022-05-31 15:07:34 +00:00
}
2022-06-15 16:40:39 +00:00
)?;
2022-06-03 12:11:00 +00:00
2022-05-19 12:33:49 +00:00
Ok(())
}
}
2022-05-31 15:07:34 +00:00
pub fn watch_ctrl_c() -> (watch::Receiver<bool>, Arc<watch::Sender<bool>>) {
let (send_cancel, watch_cancel) = watch::channel(false);
let send_cancel = Arc::new(send_cancel);
let send_cancel_2 = send_cancel.clone();
tokio::spawn(async move {
tokio::signal::ctrl_c()
.await
.expect("failed to install CTRL+C signal handler");
info!("Received CTRL+C, shutting down.");
send_cancel.send(true).unwrap();
});
(watch_cancel, send_cancel_2)
}