use base64::prelude::BASE64_STANDARD; use base64::Engine; use crate::cmd::{open_submaildir, MailStorage}; use crate::de_jmhoffmann_jwebmail_mailstorage::MIMEHeader_content_dispo as CD; use crate::de_jmhoffmann_jwebmail_mailstorage::{Call_Raw, MIMEHeader, MIMEHeader_mime_type}; use crate::rfc822::parse_mail_content; pub fn raw( ms: &MailStorage, call: &mut dyn Call_Raw, folder: String, mid: String, path: Option, ) -> varlink::Result<()> { if let Some(p) = ms.maildir_path.read().unwrap().clone() { let md = open_submaildir(p, &folder); if let Some(mut mail) = md.find(&mid) { match path.as_deref() { Some("") | None => call.reply( MIMEHeader { mime_type: MIMEHeader_mime_type { main_type: "message".to_owned(), sub_type: "rfc822".to_owned(), }, file_name: Some(mail.id().to_owned()), content_dispo: CD::none, }, BASE64_STANDARD .encode(std::fs::read(mail.path()).map_err(varlink::map_context!())?), ), Some(mime_path) => { if let Ok(path) = mime_path .split('.') .map(|x| x.parse()) .collect::, std::num::ParseIntError>>() { let mut m = mail.parsed().unwrap(); if path[0] != 0 { return call.reply_invalid_path_in_mail( folder, mid, mime_path.to_owned(), ); } for i in &path[1..] { match &m.ctype.mimetype { x if x.starts_with("message/") => { if *i != 0 { return call.reply_invalid_path_in_mail( folder, mid, mime_path.to_owned(), ); } let s: &'static _ = m.get_body_raw().unwrap().leak(); m = mailparse::parse_mail(s).unwrap(); } x if x.starts_with("multipart/") => { if *i >= m.subparts.len() { return call.reply_invalid_path_in_mail( folder, mid, mime_path.to_owned(), ); } m = m.subparts.swap_remove(*i); } _ => { return call.reply_invalid_path_in_mail( folder, mid, mime_path.to_owned(), ); } } } if m.ctype.mimetype.starts_with("multipart/") { return call.reply_invalid_path_in_mail( folder, mid, mime_path.to_owned(), ); } let mime_part = parse_mail_content(&m); let content = if m.ctype.mimetype.starts_with("text/") { m.get_body().unwrap().into_bytes() } else { m.get_body_raw().unwrap() }; call.reply(mime_part, BASE64_STANDARD.encode(content)) } else { call.reply_invalid_path_in_mail(folder, mid, mime_path.to_owned()) } } } } else { call.reply_invalid_mid(folder, mid) } } else { call.reply_not_initialized() } }