Compare commits

...

2 Commits

Author SHA1 Message Date
Florian Stecker 002393b18e clarify readme 2023-02-20 18:59:01 -05:00
Florian Stecker 26cdccee3c only look up hostname once in the beginning 2023-02-20 18:51:38 -05:00
2 changed files with 28 additions and 11 deletions

View File

@ -6,7 +6,7 @@ Although this is quite minimal and only implements a tiny subset of the IMAP pro
## Installation ##
Get [rust] and run
Get [Rust] and run
cargo build --release
@ -33,13 +33,15 @@ The output of `imapidle --help` does a good job at explaining how to use it:
Note that it only supports TLS encrypted IMAP and plain password authentication. Also, it currently reads the password from the command line, which isn't a great thing to do. I might change that eventually.
## Why? ##
## Goals ##
Rust might not be the canonical programming language to do something like this in. And also, this probably already exists somewhere in a more complete and polished form. So this might not useful for anyone else. But I had three goals in making this:
I made this for the following reasons:
1. I wanted my emails to arrive faster and without having to manually hit the refresh button.
2. I wanted to find out how IMAP works and why it's often so slow (I'm still not sure about the latter).
3. I wanted to try using rust for something practical and see how well it works. The result is it worked, and I would do it again.
2. I wanted to find out how IMAP works and why it's often so slow (I'm still not really sure).
3. I wanted to try using Rust for something practical and see how well it works. It worked pretty well.
In terms of actual usability, this works fine for me, but I'm sure there are better alternatives out there.
[Rust]: https://www.rust-lang.org/
[IMAP]: https://en.wikipedia.org/wiki/Internet_Message_Access_Protocol

View File

@ -2,12 +2,13 @@
use rustls::{OwnedTrustAnchor, ClientConfig, RootCertStore, ClientConnection};
use anyhow::{Result as AResult, bail};
use std::net::{TcpStream, ToSocketAddrs};
use std::net::{TcpStream, ToSocketAddrs, SocketAddr};
use std::io::{self, ErrorKind, Read, Write, Error as IOError};
use std::process::Command;
use std::time::{Duration, SystemTime};
use std::path::PathBuf;
use std::sync::{Arc, Mutex};
use std::cell::RefCell;
use std::thread;
use clap::Parser;
@ -22,6 +23,10 @@ pub struct Cli {
#[arg(long, default_value_t = 993)]
port: u16,
// the resolved address(es)
#[arg(skip)]
addrs: RefCell<Vec<SocketAddr>>,
/// IMAP user name
#[arg(short, long)]
username: String,
@ -46,7 +51,7 @@ pub struct Cli {
#[derive(Debug)]
struct Status {
connected: bool,
last_run: SystemTime
last_run: SystemTime,
}
const CONNECTION_LOST_ERRORS: &[ErrorKind] = &[
@ -162,7 +167,11 @@ pub fn run() -> AResult<()> {
time_to_reconnect = u64::min(time_to_reconnect*2, 1800);
if cli.verbose > 0 {
println!("Error: {:?}", err);
}
println!("Cannot connect currently, retrying in {time_to_reconnect} seconds");
thread::sleep(Duration::from_secs(time_to_reconnect));
continue;
@ -203,10 +212,16 @@ pub fn connect_and_idle<F: Fn(), G: Fn()>(cli: &Cli, connected_callback: F, mail
let mut tls_client = ClientConnection::new(
Arc::new(tls_config),
cli.server.as_str().try_into().unwrap())?;
let addrs = (cli.server.as_str(), cli.port)
.to_socket_addrs()
.map_err(|e|io::Error::new(ErrorKind::NotConnected, e.to_string()))?
.collect::<Vec<_>>();
let mut addrs = cli.addrs.borrow_mut();
if addrs.is_empty() {
addrs.extend(
(cli.server.as_str(), cli.port)
.to_socket_addrs()
.map_err(|e|io::Error::new(ErrorKind::NotConnected, e.to_string()))?
);
}
let mut socket = TcpStream::connect(addrs.as_slice())?;
let mut state = ImapState::Unauthenticated;