90 lines
2.3 KiB
Rust
90 lines
2.3 KiB
Rust
use std::env;
|
|
use std::error::Error;
|
|
use std::fs::File;
|
|
use std::io::prelude::*;
|
|
use std::process::exit;
|
|
use std::slice::Iter;
|
|
|
|
use mailparse::dateparse;
|
|
use mailparse::MailHeaderMap;
|
|
|
|
fn newline(b: &u8) -> bool {
|
|
*b == b'\n'
|
|
}
|
|
|
|
fn index_of(it: &mut Iter<u8>, needle: &[u8]) -> Option<usize> {
|
|
let mut needle_ix = 0;
|
|
it.position(move |&b| {
|
|
if b == needle[needle_ix] {
|
|
needle_ix += 1;
|
|
if needle_ix == needle.len() {
|
|
return true;
|
|
}
|
|
} else if b == needle[0] {
|
|
needle_ix = 1;
|
|
} else {
|
|
needle_ix = 0;
|
|
}
|
|
false
|
|
})
|
|
}
|
|
|
|
fn parse_mbox(mbox_bytes: &Vec<u8>) -> Result<(), Box<dyn Error>> {
|
|
let mut it = mbox_bytes.iter();
|
|
let mut ix = 0;
|
|
|
|
loop {
|
|
let mail_start = it.position(newline);
|
|
if mail_start.is_none() {
|
|
return Ok(());
|
|
}
|
|
ix += mail_start.unwrap() + 1;
|
|
let start = ix;
|
|
|
|
let delim = b"\nFrom ";
|
|
let next_mail_start = index_of(&mut it, delim);
|
|
|
|
let end = match next_mail_start {
|
|
Some(x) => {
|
|
ix += x + 1;
|
|
ix - delim.len()
|
|
}
|
|
None => mbox_bytes.len(),
|
|
};
|
|
|
|
let mail_bytes = &mbox_bytes[start..end];
|
|
|
|
let mail = mailparse::parse_mail(mail_bytes).unwrap();
|
|
println!(
|
|
"{:?} {:?} from {:?}",
|
|
match mail.headers.get_first_value("Date")? {
|
|
Some(date) => date,
|
|
None => "NO DATE".to_string(),
|
|
},
|
|
match mail.headers.get_first_value("Subject")? {
|
|
Some(subject) => subject,
|
|
None => "NO SUBJECT".to_string(),
|
|
},
|
|
match mail.headers.get_first_value("From")? {
|
|
Some(from) => from,
|
|
None => "NO FROM".to_string(),
|
|
},
|
|
);
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
if env::args().count() <= 1 {
|
|
println!("Provide mbox files as arguments");
|
|
exit(1);
|
|
}
|
|
let mut args = env::args();
|
|
args.next(); // drop executable name
|
|
args.for_each(|mbox_path| {
|
|
let mut mbox = File::open(mbox_path).unwrap();
|
|
let mut mails = Vec::new();
|
|
mbox.read_to_end(&mut mails).unwrap();
|
|
parse_mbox(&mails);
|
|
});
|
|
}
|