diff options
Diffstat (limited to 'src/cmd/folders.rs')
-rw-r--r-- | src/cmd/folders.rs | 55 |
1 files changed, 27 insertions, 28 deletions
diff --git a/src/cmd/folders.rs b/src/cmd/folders.rs index b50daa9..417203c 100644 --- a/src/cmd/folders.rs +++ b/src/cmd/folders.rs @@ -1,50 +1,49 @@ -use std::collections::BTreeSet; -use std::ffi::{OsStr, OsString}; use std::path::{Path, PathBuf}; -use std::sync::LazyLock; use protobuf::Message as _; use crate::error::Result; use crate::pb3::jwebmail::{FoldersReq, FoldersResp}; -static REQUIRED_MAILDIR_DIRS: LazyLock<BTreeSet<OsString>> = LazyLock::new(|| { - [ - OsString::from("cur"), - "new".into(), - "tmp".into(), - "maildirfolder".into(), - ] - .into() -}); - fn is_mailsubdir(p: &Path) -> bool { - p.is_dir() - && p.file_name() - .map_or(false, |fname| fname.to_string_lossy().starts_with('.')) - && p.read_dir() - .map(|dir| { - dir.filter_map(|child| { - child - .ok() - .and_then(|dir_entry| dir_entry.path().file_name().map(OsStr::to_owned)) - }) - .collect::<BTreeSet<_>>() - .is_superset(&*REQUIRED_MAILDIR_DIRS) - }) - .unwrap_or_default() + if !p.is_dir() { + return false; + } + if !p.file_name().map_or(false, |fname| { + fname.len() > 1 && fname.to_string_lossy().starts_with('.') + }) { + return false; + } + let mut buf = p.to_owned(); + buf.push("cur"); + if !buf.is_dir() { + return false; + } + buf.pop(); + buf.push("new"); + if !buf.is_dir() { + return false; + } + buf.pop(); + buf.push("tmp"); + if !buf.is_dir() { + return false; + } + true } pub fn folders(path: PathBuf, req: &[u8]) -> Result<Vec<u8>> { let _ = FoldersReq::parse_from_bytes(req)?; - let subdirs = path + let mut subdirs: Vec<_> = path .read_dir()? .filter_map(|d| d.ok()) .filter(|d| is_mailsubdir(&d.path())) .filter_map(|d| Some(d.path().file_name()?.to_string_lossy()[1..].to_owned())) .collect(); + subdirs.sort(); + let mut res = FoldersResp::new(); res.folders = subdirs; res.write_to_bytes().map_err(|e| e.into()) |