summaryrefslogtreecommitdiff
path: root/src/cmd/folders.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/folders.rs')
-rw-r--r--src/cmd/folders.rs55
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())