diff --git a/src/main.rs b/src/main.rs index c1c368a..4c9452c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -68,10 +68,14 @@ enum Commands { #[arg(short, long)] 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)] drive: Option, + /// 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, + /// Optionaler TCP-Port für den lokalen WebDAV-Server (Standard: 8443) #[arg(long)] port: Option, @@ -904,6 +908,7 @@ async fn run() -> Result<()> { Commands::Mount { path, drive, + mount_point, port, recovery_key, no_open, @@ -916,15 +921,22 @@ async fn run() -> Result<()> { let drive_char = match drive { Some(ref d) => parse_drive_letter(d)?, None => { - let auto_drive = sanctum::windows::find_next_available_drive()?; - if !stealth { - println!( - " {} Kein Laufwerksbuchstabe angegeben. Wähle automatisch freien Buchstaben {}:", - ui::cyan("ℹ"), - auto_drive - ); + #[cfg(windows)] + { + let auto_drive = sanctum::windows::find_next_available_drive()?; + if !stealth { + println!( + " {} Kein Laufwerksbuchstabe angegeben. Wähle automatisch freien Buchstaben {}:", + ui::cyan("ℹ"), + auto_drive + ); + } + auto_drive + } + #[cfg(not(windows))] + { + 'Z' } - auto_drive } }; let auth = if let Some(key) = recovery_key { @@ -953,6 +965,7 @@ async fn run() -> Result<()> { mount_container( &path, drive_char, + mount_point.as_deref(), port, auth, open_explorer, diff --git a/src/mount.rs b/src/mount.rs index 6fb51a5..0c3bf1c 100644 --- a/src/mount.rs +++ b/src/mount.rs @@ -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( container_path: &Path, drive_letter: char, + mount_point: Option<&Path>, requested_port: Option, auth: ContainerAuth, open_explorer: bool, @@ -154,6 +155,8 @@ pub async fn mount_container( stealth: bool, ) -> Result<()> { let drive_str = format_drive(drive_letter); + let _ = mount_point; + let _ = enable_tray; if !container_path.exists() { bail!( @@ -255,6 +258,7 @@ pub async fn mount_container( let bound_port = bound_addr.port(); if !stealth { + #[cfg(windows)] ui::step( 4, 4, @@ -264,6 +268,16 @@ pub async fn mount_container( 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); @@ -363,7 +377,10 @@ pub async fn mount_container( }; if stealth { + #[cfg(windows)] println!("Sanctum: Netzlaufwerk {} bereit.", drive_str); + #[cfg(not(windows))] + println!("Sanctum: WebDAV-Server auf Port {} bereit.", bound_port); } else { println!(); println!("┌─────────────────────────────────────────────────────────────┐"); @@ -371,22 +388,46 @@ pub async fn mount_container( println!("└─────────────────────────────────────────────────────────────┘"); println!(); println!(" • Container: {}", container_path.display()); + #[cfg(windows)] 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); + #[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 { println!(" • Auto-Lock: Inaktivität nach {}s", secs); } + #[cfg(windows)] if lock_on_screen_lock { println!(" • Sitzung: Automatisches Sperren bei Win + L aktiv"); } if anti_leak { + #[cfg(windows)] 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 { println!(" • System-Tray: Icon aktiv (Rechtsklick für Explorer/Trennen)"); } println!(); + #[cfg(windows)] 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!(); } @@ -439,15 +480,27 @@ pub async fn mount_container( } } let _ = db.checkpoint(); + #[cfg(windows)] println!("Sanctum: Laufwerk {} getrennt und geschlossen.", drive_str); + #[cfg(not(windows))] + println!("Sanctum: Container geschlossen und WebDAV-Server beendet."); } else { - print!(" {} Trenne Windows-Netzlaufwerk {} ... ", ui::dim("[-]"), drive_str); - let _ = std::io::Write::flush(&mut std::io::stdout()); + #[cfg(windows)] + { + print!(" {} Trenne Windows-Netzlaufwerk {} ... ", ui::dim("[-]"), drive_str); + let _ = std::io::Write::flush(&mut std::io::stdout()); - // Automatisches Unmount - if let Err(e) = unmount_drive(drive_letter) { - println!("{}", ui::yellow(&format!("Warnung ({e})"))); - } else { + // Automatisches Unmount + if let Err(e) = unmount_drive(drive_letter) { + println!("{}", ui::yellow(&format!("Warnung ({e})"))); + } else { + 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")); }