+//! # olden-mail
+//!
+//! `olden-mail` is an IMAP & SMTP proxy that allows you to connect to SSL
+//! enabled mail servers using insecure plaintext connections.
+//!
+//! This is of course very insecure, but it's intended to allow vintage
+//! computers that don't have SSL capability or ther right ciphers to still
+//! be used for e-mail.
+//!
+//! ## Installation
+//!
+//! ### Pre-built binaries and packages
+//!
+//! Binaries are available for macos and linux, for both aarch64 and `x86_64`
+//! from <https://build.r.bdr.sh/olden-mail>, including `.deb` and `.rpm`
+//! packages.
+//!
+//! ### Homebrew
+//!
+//! You can also install this on macos via homebrew.
+//!
+//! ```
+//! % brew tap rbdr/apps git@git.sr.ht:~rbdr/homebrew-apps
+//! % brew install rbdr/apps/olden-mail
+//! ```
+//!
+//! ### From source
+//!
+//! You can run `make` for a debug build, or `make -e profile=release` for a
+//! release build.
+//!
+//! ## Usage
+//!
+//! The proxy requires you to set environment variables, but otherwise takes
+//! no options.
+//!
+//! * `LOCAL_IMAP_PORT` u16, the port in which the server will listen for
+//! IMAP clients. Defaults to 143.
+//! * `LOCAL_IMAP_BIND_ADDRESS` String, the address on which to listen for
+//! IMAP clients. Defaults to 0.0.0.0.
+//! * `REMOTE_IMAP_PORT` u16, the port to which the server will forward the
+//! IMAP messages. Defaults to 993.
+//! * `REMOTE_IMAP_HOST` String, the host to which the server will forward the
+//! IMAP messages. Required.
+//!
+//! * `LOCAL_SMTP_PORT` u16, the port in which the server will listen for
+//! SMTP clients. Defaults to 25.
+//! * `LOCAL_SMTP_BIND_ADDRESS` String, the address on which to listen for
+//! SMTP clients. Defaults to 0.0.0.0.
+//! * `REMOTE_SMTP_PORT` u16, the port to which the server will forward the
+//! SMTP messages. Defaults to 465.
+//! * `REMOTE_SMTP_HOST` String, the host to which the server will forward the
+//! SMTP messages. Required.
+//!
+//! This means the minimum invocation is this (Shown here with inline
+//! environment variables)
+//!
+//! ```
+//! % REMOTE_IMAP_HOST=imap.coolmailsite.example REMOTE_SMTP_HOST=smtp.coolmailsite.example olden-mail
+//! ```
+//!
+//! ## Debugging
+//!
+//! You can control how much it prints by setting `RUST_LOG`. Setting it to
+//! `debug` will output the whole protocol stream. The default level is
+//! `info`.
+
+use env_logger::{Builder, Env};
+use log::{error, info};
+use std::process::exit;
+use std::sync::mpsc;
+
mod configuration;
mod proxy;
use configuration::Configuration;
-use proxy::create_proxy;
+use proxy::Server;
fn main() {
- let configuration = Configuration::new();
+ Builder::from_env(Env::default().default_filter_or("info"))
+ .format_timestamp_millis()
+ .init();
+
+ let configuration = Configuration::new().unwrap_or_else(|error| {
+ error!("{error}");
+ exit(1);
+ });
+
+ let (tx, rx) = mpsc::channel();
+
+ let mut imap_proxy = Server::new(configuration.imap_configuration);
+ let mut smtp_proxy = Server::new(configuration.smtp_configuration);
- let imap_proxy = create_proxy(configuration.imap_configuration);
- let smtp_proxy = create_proxy(configuration.smtp_configuration);
+ ctrlc::set_handler(move || {
+ info!("Shutting down...");
+ imap_proxy.shutdown();
+ smtp_proxy.shutdown();
+ let _ = tx.send(());
+ })
+ .unwrap_or_else(|e| {
+ error!("Error setting Ctrl-C handler: {e}");
+ std::process::exit(1);
+ });
- imap_proxy.join().unwrap();
- smtp_proxy.join().unwrap();
+ // Block until we get a shutdown
+ rx.recv().unwrap_or(());
}