use clap::Subcommand; #[derive(Subcommand)] pub enum SmbServerCommand { #[command(name = "smb-start")] Start { #[arg(short, long, default_value = "4445")] port: u16, #[arg(short, long, default_value = "/Users/accusys/momentry/var/sftpgo/data/demo")] root: String, #[arg(short, long, default_value = "markbase")] share_name: String, #[arg(long)] read_only: bool, }, } pub async fn handle_smb_server_command(cmd: SmbServerCommand) -> anyhow::Result<()> { #[cfg(feature = "smb-server")] { match cmd { SmbServerCommand::Start { port, root, share_name, read_only } => { use std::path::PathBuf; use smb_server::{Access, Share, SmbServer}; use tracing_subscriber::EnvFilter; let _ = tracing_subscriber::fmt() .with_env_filter( EnvFilter::try_from_default_env() .unwrap_or_else(|_| EnvFilter::new("info")), ) .try_init(); let addr: std::net::SocketAddr = format!("0.0.0.0:{}", port).parse()?; let root_path = PathBuf::from(&root); let vfs = Box::new(crate::vfs::local_fs::LocalFs::new()); let backend = crate::vfs::smb_server_backend::VfsShareBackend::new(vfs, root_path) .read_only(read_only); let share = Share::new(&share_name, backend) .user("demo", Access::ReadWrite); let server = SmbServer::builder() .listen(addr) .user("demo", "demo123") .share(share) .build()?; log::info!("SMB server listening on {}", addr); log::info!("Share '{}' at root: {}", share_name, root); log::info!("User: demo / demo123"); server.serve().await?; } } } #[cfg(not(feature = "smb-server"))] { let _ = cmd; anyhow::bail!("SMB server support not enabled. Build with --features smb-server"); } Ok(()) }