mirror of
https://github.com/rustmailer/bichon.git
synced 2026-08-03 07:48:34 +02:00
@@ -76,6 +76,7 @@ use tokio::{
|
|||||||
sync::{mpsc, Mutex},
|
sync::{mpsc, Mutex},
|
||||||
task,
|
task,
|
||||||
};
|
};
|
||||||
|
use tracing::info;
|
||||||
|
|
||||||
pub static ENVELOPE_INDEX_MANAGER: LazyLock<EnvelopeIndexManager> =
|
pub static ENVELOPE_INDEX_MANAGER: LazyLock<EnvelopeIndexManager> =
|
||||||
LazyLock::new(EnvelopeIndexManager::new);
|
LazyLock::new(EnvelopeIndexManager::new);
|
||||||
@@ -188,13 +189,23 @@ impl EnvelopeIndexManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn open_or_create_index(index_dir: &PathBuf) -> Index {
|
fn open_or_create_index(index_dir: &PathBuf) -> Index {
|
||||||
if !index_dir.exists() {
|
let need_create = !index_dir.exists()
|
||||||
|
|| index_dir
|
||||||
|
.read_dir()
|
||||||
|
.map(|mut d| d.next().is_none())
|
||||||
|
.unwrap_or(true);
|
||||||
|
if need_create {
|
||||||
|
info!(
|
||||||
|
"Email index not found or empty, creating new index at {}",
|
||||||
|
index_dir.display()
|
||||||
|
);
|
||||||
std::fs::create_dir_all(&index_dir).unwrap_or_else(|e| {
|
std::fs::create_dir_all(&index_dir).unwrap_or_else(|e| {
|
||||||
panic!("Failed to create index directory {:?}: {}", index_dir, e)
|
panic!("Failed to create index directory {:?}: {}", index_dir, e)
|
||||||
});
|
});
|
||||||
Index::create_in_dir(&index_dir, SchemaTools::envelope_schema())
|
Index::create_in_dir(&index_dir, SchemaTools::envelope_schema())
|
||||||
.unwrap_or_else(|e| panic!("Failed to create index in {:?}: {}", index_dir, e))
|
.unwrap_or_else(|e| panic!("Failed to create index in {:?}: {}", index_dir, e))
|
||||||
} else {
|
} else {
|
||||||
|
info!("Opening existing email index at {}", index_dir.display());
|
||||||
open(&index_dir)
|
open(&index_dir)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1331,7 +1342,17 @@ impl EmlIndexManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn open_or_create_index(index_dir: &PathBuf) -> Index {
|
fn open_or_create_index(index_dir: &PathBuf) -> Index {
|
||||||
if !index_dir.exists() {
|
let need_create = !index_dir.exists()
|
||||||
|
|| index_dir
|
||||||
|
.read_dir()
|
||||||
|
.map(|mut d| d.next().is_none())
|
||||||
|
.unwrap_or(true);
|
||||||
|
|
||||||
|
if need_create {
|
||||||
|
info!(
|
||||||
|
"Email data storage not found or empty, creating new mail storage at {}",
|
||||||
|
index_dir.display()
|
||||||
|
);
|
||||||
std::fs::create_dir_all(&index_dir).unwrap_or_else(|e| {
|
std::fs::create_dir_all(&index_dir).unwrap_or_else(|e| {
|
||||||
panic!("Failed to create index directory {:?}: {}", index_dir, e)
|
panic!("Failed to create index directory {:?}: {}", index_dir, e)
|
||||||
});
|
});
|
||||||
@@ -1347,6 +1368,10 @@ impl EmlIndexManager {
|
|||||||
.create_in_dir(&index_dir)
|
.create_in_dir(&index_dir)
|
||||||
.unwrap_or_else(|e| panic!("Failed to create index in {:?}: {}", index_dir, e))
|
.unwrap_or_else(|e| panic!("Failed to create index in {:?}: {}", index_dir, e))
|
||||||
} else {
|
} else {
|
||||||
|
info!(
|
||||||
|
"Opening existing email data storage at {}",
|
||||||
|
index_dir.display()
|
||||||
|
);
|
||||||
open(&index_dir)
|
open(&index_dir)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-22
@@ -16,6 +16,7 @@
|
|||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
use crate::modules::settings::io::check_dir_read_write;
|
||||||
use clap::{builder::ValueParser, Parser, ValueEnum};
|
use clap::{builder::ValueParser, Parser, ValueEnum};
|
||||||
use std::{collections::HashSet, env, fmt, path::PathBuf, sync::LazyLock};
|
use std::{collections::HashSet, env, fmt, path::PathBuf, sync::LazyLock};
|
||||||
|
|
||||||
@@ -64,7 +65,7 @@ pub struct Settings {
|
|||||||
)]
|
)]
|
||||||
pub bichon_bind_ip: Option<String>,
|
pub bichon_bind_ip: Option<String>,
|
||||||
|
|
||||||
/// RustMail public URL (default: "http://localhost:15630")
|
/// bichon public URL (default: "http://localhost:15630")
|
||||||
#[clap(
|
#[clap(
|
||||||
long,
|
long,
|
||||||
default_value = "http://localhost:15630",
|
default_value = "http://localhost:15630",
|
||||||
@@ -160,15 +161,12 @@ pub struct Settings {
|
|||||||
help = "Set the file path for bichon database",
|
help = "Set the file path for bichon database",
|
||||||
value_parser = ValueParser::new(|s: &str| {
|
value_parser = ValueParser::new(|s: &str| {
|
||||||
let path = PathBuf::from(s);
|
let path = PathBuf::from(s);
|
||||||
|
|
||||||
if !path.is_absolute() {
|
if !path.is_absolute() {
|
||||||
return Err("Path must be an absolute directory path".to_string());
|
return Err("'bichon_root_dir' must be an absolute directory path".to_string());
|
||||||
}
|
|
||||||
if !path.exists() {
|
|
||||||
return Err(format!("Path {:?} does not exist", path));
|
|
||||||
}
|
|
||||||
if !path.is_dir() {
|
|
||||||
return Err(format!("Path {:?} is not a directory", path));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
check_dir_read_write(&path)?;
|
||||||
Ok(s.to_string())
|
Ok(s.to_string())
|
||||||
})
|
})
|
||||||
)]
|
)]
|
||||||
@@ -179,15 +177,12 @@ pub struct Settings {
|
|||||||
help = "Set the file path for email index directory",
|
help = "Set the file path for email index directory",
|
||||||
value_parser = ValueParser::new(|s: &str| {
|
value_parser = ValueParser::new(|s: &str| {
|
||||||
let path = PathBuf::from(s);
|
let path = PathBuf::from(s);
|
||||||
|
|
||||||
if !path.is_absolute() {
|
if !path.is_absolute() {
|
||||||
return Err("Path must be an absolute directory path".to_string());
|
return Err("'bichon_index_dir' must be an absolute directory path".to_string());
|
||||||
}
|
|
||||||
if !path.exists() {
|
|
||||||
return Err(format!("Path {:?} does not exist", path));
|
|
||||||
}
|
|
||||||
if !path.is_dir() {
|
|
||||||
return Err(format!("Path {:?} is not a directory", path));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
check_dir_read_write(&path)?;
|
||||||
Ok(s.to_string())
|
Ok(s.to_string())
|
||||||
})
|
})
|
||||||
)]
|
)]
|
||||||
@@ -198,15 +193,12 @@ pub struct Settings {
|
|||||||
help = "Set the file path for email data directory",
|
help = "Set the file path for email data directory",
|
||||||
value_parser = ValueParser::new(|s: &str| {
|
value_parser = ValueParser::new(|s: &str| {
|
||||||
let path = PathBuf::from(s);
|
let path = PathBuf::from(s);
|
||||||
|
|
||||||
if !path.is_absolute() {
|
if !path.is_absolute() {
|
||||||
return Err("Path must be an absolute directory path".to_string());
|
return Err("'bichon_data_dir' must be an absolute directory path".to_string());
|
||||||
}
|
|
||||||
if !path.exists() {
|
|
||||||
return Err(format!("Path {:?} does not exist", path));
|
|
||||||
}
|
|
||||||
if !path.is_dir() {
|
|
||||||
return Err(format!("Path {:?} is not a directory", path));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
check_dir_read_write(&path)?;
|
||||||
Ok(s.to_string())
|
Ok(s.to_string())
|
||||||
})
|
})
|
||||||
)]
|
)]
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
use std::fs::{self, OpenOptions};
|
||||||
|
use std::io::{Read, Write};
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
pub fn check_dir_read_write(path: &Path) -> Result<(), String> {
|
||||||
|
if !path.exists() {
|
||||||
|
fs::create_dir_all(path)
|
||||||
|
.map_err(|e| format!("Cannot create directory {:?}: {}", path, e))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if !path.is_dir() {
|
||||||
|
return Err(format!("{:?} is not a directory", path));
|
||||||
|
}
|
||||||
|
|
||||||
|
let test_file = path.join(".bichon_perm_test");
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut f = OpenOptions::new()
|
||||||
|
.create(true)
|
||||||
|
.write(true)
|
||||||
|
.open(&test_file)
|
||||||
|
.map_err(|e| format!("Directory {:?} is not writable: {}", path, e))?;
|
||||||
|
|
||||||
|
f.write_all(b"test")
|
||||||
|
.map_err(|e| format!("Directory {:?} is not writable: {}", path, e))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut buf = Vec::new();
|
||||||
|
let mut f = OpenOptions::new()
|
||||||
|
.read(true)
|
||||||
|
.open(&test_file)
|
||||||
|
.map_err(|e| format!("Directory {:?} is not readable: {}", path, e))?;
|
||||||
|
|
||||||
|
f.read_to_end(&mut buf)
|
||||||
|
.map_err(|e| format!("Directory {:?} is not readable: {}", path, e))?;
|
||||||
|
}
|
||||||
|
let _ = fs::remove_file(&test_file);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
@@ -23,6 +23,7 @@ use crate::modules::settings::cli::Settings;
|
|||||||
|
|
||||||
pub mod cli;
|
pub mod cli;
|
||||||
pub mod dir;
|
pub mod dir;
|
||||||
|
pub mod io;
|
||||||
pub mod proxy;
|
pub mod proxy;
|
||||||
pub mod system;
|
pub mod system;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user