2025-11-19 02:14:37 +08:00
|
|
|
//
|
2026-03-10 01:32:57 +08:00
|
|
|
// Copyright (c) 2025-2026 rustmailer.com (https://rustmailer.com)
|
2025-11-19 02:14:37 +08:00
|
|
|
//
|
|
|
|
|
// This file is part of the Bichon Email Archiving Project
|
|
|
|
|
//
|
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
|
// it under the terms of the GNU Affero General Public License as published by
|
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
// (at your option) any later version.
|
|
|
|
|
//
|
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
// GNU Affero General Public License for more details.
|
|
|
|
|
//
|
|
|
|
|
// 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/>.
|
|
|
|
|
|
2026-04-17 00:29:05 +08:00
|
|
|
use std::sync::LazyLock;
|
|
|
|
|
|
2026-04-23 21:45:34 +08:00
|
|
|
use bichon_core::{
|
2026-05-08 16:28:11 +08:00
|
|
|
bichon_version,
|
|
|
|
|
cache::imap::task::SYNC_TASKS,
|
|
|
|
|
common::rustls::BichonTls,
|
|
|
|
|
context::{executors::BichonContext, Initialize},
|
|
|
|
|
error::{code::ErrorCode, BichonResult},
|
|
|
|
|
logger,
|
2026-05-12 01:56:24 +08:00
|
|
|
migrate::check_data_status,
|
2026-05-08 16:28:11 +08:00
|
|
|
raise_error,
|
|
|
|
|
settings::cli::SETTINGS,
|
|
|
|
|
store::{
|
2026-05-12 01:56:24 +08:00
|
|
|
blob::BLOB_MANAGER,
|
2026-05-08 16:28:11 +08:00
|
|
|
tantivy::{attachment::ATTACHMENT_MANAGER, envelope::ENVELOPE_MANAGER},
|
2026-01-01 20:28:23 +08:00
|
|
|
},
|
2026-05-08 16:28:11 +08:00
|
|
|
tasks::PeriodicTasks,
|
2025-11-19 02:14:37 +08:00
|
|
|
};
|
2026-04-23 21:45:34 +08:00
|
|
|
use bichon_smtp::server::{start_smtp_server, SmtpServer};
|
2026-01-01 20:28:23 +08:00
|
|
|
use mimalloc::MiMalloc;
|
2026-03-10 01:25:02 +08:00
|
|
|
use tracing::{error, info};
|
2025-11-19 02:14:37 +08:00
|
|
|
|
2026-04-23 21:45:34 +08:00
|
|
|
use bichon_core::{
|
2025-12-26 14:17:34 +08:00
|
|
|
common::signal::SignalManager, settings::dir::DataDirManager, users::manager::UserManager,
|
|
|
|
|
};
|
2025-11-19 02:14:37 +08:00
|
|
|
|
2026-04-23 21:45:34 +08:00
|
|
|
use crate::rest::start_http_server;
|
|
|
|
|
|
|
|
|
|
pub mod common;
|
|
|
|
|
pub mod error;
|
|
|
|
|
pub mod rest;
|
|
|
|
|
|
2025-11-19 02:14:37 +08:00
|
|
|
#[global_allocator]
|
|
|
|
|
static GLOBAL: MiMalloc = MiMalloc;
|
|
|
|
|
|
|
|
|
|
static LOGO: &str = r#"
|
|
|
|
|
_ _ _
|
|
|
|
|
| | (_) | |
|
|
|
|
|
| |__ _ ___ | |__ ___ _ __
|
|
|
|
|
| '_ \ | | / __|| '_ \ / _ \ | '_ \
|
|
|
|
|
| |_) || || (__ | | | || (_) || | | |
|
|
|
|
|
|_.__/ |_| \___||_| |_| \___/ |_| |_|
|
|
|
|
|
|
|
|
|
|
"#;
|
|
|
|
|
#[tokio::main]
|
|
|
|
|
async fn main() -> BichonResult<()> {
|
|
|
|
|
logger::initialize_logging();
|
|
|
|
|
info!("{}", LOGO);
|
|
|
|
|
info!("Starting bichon-server");
|
|
|
|
|
info!("Version: {}", bichon_version!());
|
|
|
|
|
info!("Git: [{}]", env!("GIT_HASH"));
|
|
|
|
|
info!("GitHub: https://github.com/rustmailer/bichon");
|
|
|
|
|
|
2026-05-12 01:56:24 +08:00
|
|
|
match check_data_status() {
|
|
|
|
|
Ok(false) => {
|
2026-05-08 16:28:11 +08:00
|
|
|
error!("Incompatible data format detected.");
|
|
|
|
|
error!("Your data was created by an older version of Bichon and must be migrated before use.");
|
2026-05-12 01:56:24 +08:00
|
|
|
error!("Please run: bichon-admin");
|
2026-05-08 16:28:11 +08:00
|
|
|
error!("Documentation: https://github.com/rustmailer/bichon/wiki/migration");
|
|
|
|
|
return Err(raise_error!(
|
|
|
|
|
"Legacy data layout detected".into(),
|
|
|
|
|
ErrorCode::InternalError
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
Err(e) => {
|
|
|
|
|
error!("Failed to check data layout: {:#?}", e);
|
|
|
|
|
return Err(raise_error!(format!("{:#?}", e), ErrorCode::InternalError));
|
|
|
|
|
}
|
2026-05-12 01:56:24 +08:00
|
|
|
Ok(true) => {}
|
2026-05-08 16:28:11 +08:00
|
|
|
}
|
|
|
|
|
|
2025-11-19 02:14:37 +08:00
|
|
|
if let Err(error) = initialize().await {
|
|
|
|
|
eprintln!("{:?}", error);
|
|
|
|
|
return Err(error);
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-01 04:49:18 +08:00
|
|
|
let periodic_tasks = PeriodicTasks::setup();
|
2026-03-10 01:25:02 +08:00
|
|
|
let mut smtp_service: Option<SmtpServer> = None;
|
|
|
|
|
if SETTINGS.bichon_enable_smtp {
|
|
|
|
|
info!("SMTP service is enabled, starting...");
|
|
|
|
|
match start_smtp_server().await {
|
|
|
|
|
Ok(server) => {
|
|
|
|
|
info!("SMTP server listening on: {}", server.smtp_addr);
|
|
|
|
|
smtp_service = Some(server);
|
|
|
|
|
}
|
|
|
|
|
Err(e) => {
|
|
|
|
|
error!("Failed to start SMTP server: {}", e);
|
|
|
|
|
return Err(raise_error!(format!("{:#?}", e), ErrorCode::InternalError));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
info!("SMTP service is disabled by configuration.");
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-19 02:14:37 +08:00
|
|
|
start_http_server().await?;
|
2026-04-01 04:49:18 +08:00
|
|
|
periodic_tasks.shutdown().await;
|
2026-03-10 01:25:02 +08:00
|
|
|
|
|
|
|
|
if let Some(server) = smtp_service {
|
|
|
|
|
info!("Shutting down SMTP server...");
|
|
|
|
|
server.stop().await;
|
|
|
|
|
info!("SMTP server stopped.");
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-01 04:49:18 +08:00
|
|
|
SYNC_TASKS.shutdown().await;
|
2026-04-19 01:01:46 +08:00
|
|
|
ENVELOPE_MANAGER.shutdown().await;
|
|
|
|
|
ATTACHMENT_MANAGER.shutdown().await;
|
2026-04-01 04:49:18 +08:00
|
|
|
BLOB_MANAGER.shutdown().await;
|
2026-03-10 01:25:02 +08:00
|
|
|
info!("Bichon server stopped.");
|
2025-11-19 02:14:37 +08:00
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Initialize the system by validating settings and starting necessary tasks.
|
|
|
|
|
async fn initialize() -> BichonResult<()> {
|
|
|
|
|
SignalManager::initialize().await?;
|
|
|
|
|
DataDirManager::initialize().await?;
|
2025-12-26 14:17:34 +08:00
|
|
|
UserManager::initialize().await?;
|
2026-04-01 04:49:18 +08:00
|
|
|
BichonTls::initialize().await?;
|
2026-01-28 20:41:17 +08:00
|
|
|
BichonContext::initialize().await?;
|
2026-04-17 00:29:05 +08:00
|
|
|
LazyLock::force(&BLOB_MANAGER);
|
2026-05-05 03:49:20 +08:00
|
|
|
LazyLock::force(&ENVELOPE_MANAGER);
|
|
|
|
|
LazyLock::force(&ATTACHMENT_MANAGER);
|
2025-11-19 02:14:37 +08:00
|
|
|
Ok(())
|
|
|
|
|
}
|