feat(linux): add --mount-point CLI option and platform-aware mount messages
Sanctum Release / Build & Release (Windows x86_64) (push) Canceled after 0s

This commit is contained in:
2026-09-12 14:36:43 +02:00
parent 4ef0c414fa
commit 34378998c4
2 changed files with 82 additions and 16 deletions
+14 -1
View File
@@ -68,10 +68,14 @@ enum Commands {
#[arg(short, long)] #[arg(short, long)]
path: PathBuf, path: PathBuf,
/// Laufwerksbuchstabe (z. B. 'S' oder 'S:', optional; wählt standardmäßig automatisch das nächste freie Laufwerk) /// Laufwerksbuchstabe (z. B. 'S' oder 'S:', optional; wählt unter Windows standardmäßig das nächste freie Laufwerk)
#[arg(short, long)] #[arg(short, long)]
drive: Option<String>, drive: Option<String>,
/// Optionaler lokaler Mount-Pfad unter Linux/macOS (z. B. '/mnt/sanctum' oder '~/vault')
#[arg(short = 'm', long = "mount-point", value_name = "DIR")]
mount_point: Option<PathBuf>,
/// Optionaler TCP-Port für den lokalen WebDAV-Server (Standard: 8443) /// Optionaler TCP-Port für den lokalen WebDAV-Server (Standard: 8443)
#[arg(long)] #[arg(long)]
port: Option<u16>, port: Option<u16>,
@@ -904,6 +908,7 @@ async fn run() -> Result<()> {
Commands::Mount { Commands::Mount {
path, path,
drive, drive,
mount_point,
port, port,
recovery_key, recovery_key,
no_open, no_open,
@@ -916,6 +921,8 @@ async fn run() -> Result<()> {
let drive_char = match drive { let drive_char = match drive {
Some(ref d) => parse_drive_letter(d)?, Some(ref d) => parse_drive_letter(d)?,
None => { None => {
#[cfg(windows)]
{
let auto_drive = sanctum::windows::find_next_available_drive()?; let auto_drive = sanctum::windows::find_next_available_drive()?;
if !stealth { if !stealth {
println!( println!(
@@ -926,6 +933,11 @@ async fn run() -> Result<()> {
} }
auto_drive auto_drive
} }
#[cfg(not(windows))]
{
'Z'
}
}
}; };
let auth = if let Some(key) = recovery_key { let auth = if let Some(key) = recovery_key {
let actual_key = if key.trim().is_empty() { let actual_key = if key.trim().is_empty() {
@@ -953,6 +965,7 @@ async fn run() -> Result<()> {
mount_container( mount_container(
&path, &path,
drive_char, drive_char,
mount_point.as_deref(),
port, port,
auth, auth,
open_explorer, open_explorer,
+54 -1
View File
@@ -140,10 +140,11 @@ fn run_mount_command(drive_str: &str, port: u16, session_token: &str) -> Result<
} }
} }
/// Startet den WebDAV-Server für den Sanctum-Container und bindet ihn als Netzlaufwerk ein. /// Startet den WebDAV-Server für den Sanctum-Container und bindet ihn als Netzlaufwerk (Windows) bzw. VFS (Linux) ein.
pub async fn mount_container( pub async fn mount_container(
container_path: &Path, container_path: &Path,
drive_letter: char, drive_letter: char,
mount_point: Option<&Path>,
requested_port: Option<u16>, requested_port: Option<u16>,
auth: ContainerAuth, auth: ContainerAuth,
open_explorer: bool, open_explorer: bool,
@@ -154,6 +155,8 @@ pub async fn mount_container(
stealth: bool, stealth: bool,
) -> Result<()> { ) -> Result<()> {
let drive_str = format_drive(drive_letter); let drive_str = format_drive(drive_letter);
let _ = mount_point;
let _ = enable_tray;
if !container_path.exists() { if !container_path.exists() {
bail!( bail!(
@@ -255,6 +258,7 @@ pub async fn mount_container(
let bound_port = bound_addr.port(); let bound_port = bound_addr.port();
if !stealth { if !stealth {
#[cfg(windows)]
ui::step( ui::step(
4, 4,
4, 4,
@@ -264,6 +268,16 @@ pub async fn mount_container(
bound_port, drive_str bound_port, drive_str
), ),
); );
#[cfg(not(windows))]
ui::step(
4,
4,
"🌐",
&format!(
"Starte WebDAV-Server auf Port {} & initialisiere VFS...",
bound_port
),
);
} }
let (shutdown_tx, shutdown_rx) = watch::channel(false); let (shutdown_tx, shutdown_rx) = watch::channel(false);
@@ -363,7 +377,10 @@ pub async fn mount_container(
}; };
if stealth { if stealth {
#[cfg(windows)]
println!("Sanctum: Netzlaufwerk {} bereit.", drive_str); println!("Sanctum: Netzlaufwerk {} bereit.", drive_str);
#[cfg(not(windows))]
println!("Sanctum: WebDAV-Server auf Port {} bereit.", bound_port);
} else { } else {
println!(); println!();
println!("┌─────────────────────────────────────────────────────────────┐"); println!("┌─────────────────────────────────────────────────────────────┐");
@@ -371,22 +388,46 @@ pub async fn mount_container(
println!("└─────────────────────────────────────────────────────────────┘"); println!("└─────────────────────────────────────────────────────────────┘");
println!(); println!();
println!(" • Container: {}", container_path.display()); println!(" • Container: {}", container_path.display());
#[cfg(windows)]
println!(" • Netzlaufwerk: {} (im Windows Explorer bereit)", ui::cyan(&drive_str)); println!(" • Netzlaufwerk: {} (im Windows Explorer bereit)", ui::cyan(&drive_str));
#[cfg(not(windows))]
{
if let Some(mp) = mount_point {
println!(" • Mountpoint: {}", ui::cyan(&mp.display().to_string()));
} else {
println!(" • Modus: WebDAV Userland-VFS");
}
}
println!(" • WebDAV-URL: http://127.0.0.1:{}/{}/ (Session-Token geschützt)", bound_port, session_token); println!(" • WebDAV-URL: http://127.0.0.1:{}/{}/ (Session-Token geschützt)", bound_port, session_token);
#[cfg(not(windows))]
{
println!(" • gio Befehl: gio mount dav://127.0.0.1:{}/{}/", bound_port, session_token);
if let Some(mp) = mount_point {
println!(" • davfs2: mount -t davfs http://127.0.0.1:{}/{}/ {}", bound_port, session_token, mp.display());
}
}
if let Some(secs) = idle_timeout { if let Some(secs) = idle_timeout {
println!(" • Auto-Lock: Inaktivität nach {}s", secs); println!(" • Auto-Lock: Inaktivität nach {}s", secs);
} }
#[cfg(windows)]
if lock_on_screen_lock { if lock_on_screen_lock {
println!(" • Sitzung: Automatisches Sperren bei Win + L aktiv"); println!(" • Sitzung: Automatisches Sperren bei Win + L aktiv");
} }
if anti_leak { if anti_leak {
#[cfg(windows)]
println!(" • Anti-Leak: Explorer-Metadatenfilter aktiv (Thumbs.db, desktop.ini blockiert)"); println!(" • Anti-Leak: Explorer-Metadatenfilter aktiv (Thumbs.db, desktop.ini blockiert)");
#[cfg(not(windows))]
println!(" • Anti-Leak: VFS-Metadatenfilter aktiv (.directory, .Trash, desktop.ini blockiert)");
} }
#[cfg(windows)]
if enable_tray { if enable_tray {
println!(" • System-Tray: Icon aktiv (Rechtsklick für Explorer/Trennen)"); println!(" • System-Tray: Icon aktiv (Rechtsklick für Explorer/Trennen)");
} }
println!(); println!();
#[cfg(windows)]
println!(" [{}] Drücke [Ctrl+C] oder nutze das Tray-Icon zum Beenden.", ui::yellow("Tipp")); println!(" [{}] Drücke [Ctrl+C] oder nutze das Tray-Icon zum Beenden.", ui::yellow("Tipp"));
#[cfg(not(windows))]
println!(" [{}] Drücke [Ctrl+C] zum sicheren Beenden.", ui::yellow("Tipp"));
println!(); println!();
} }
@@ -439,8 +480,13 @@ pub async fn mount_container(
} }
} }
let _ = db.checkpoint(); let _ = db.checkpoint();
#[cfg(windows)]
println!("Sanctum: Laufwerk {} getrennt und geschlossen.", drive_str); println!("Sanctum: Laufwerk {} getrennt und geschlossen.", drive_str);
#[cfg(not(windows))]
println!("Sanctum: Container geschlossen und WebDAV-Server beendet.");
} else { } else {
#[cfg(windows)]
{
print!(" {} Trenne Windows-Netzlaufwerk {} ... ", ui::dim("[-]"), drive_str); print!(" {} Trenne Windows-Netzlaufwerk {} ... ", ui::dim("[-]"), drive_str);
let _ = std::io::Write::flush(&mut std::io::stdout()); let _ = std::io::Write::flush(&mut std::io::stdout());
@@ -450,6 +496,13 @@ pub async fn mount_container(
} else { } else {
println!("{}", ui::green("OK")); println!("{}", ui::green("OK"));
} }
}
#[cfg(not(windows))]
{
print!(" {} Beende WebDAV-Server ... ", ui::dim("[-]"));
let _ = std::io::Write::flush(&mut std::io::stdout());
println!("{}", ui::green("OK"));
}
// HTTP Server beenden // HTTP Server beenden
let _ = shutdown_tx.send(true); let _ = shutdown_tx.send(true);