// rsync Receiver Handler实现(ssh2辅助模块) // 支持完整的rsync receiver流程 use anyhow::{Result, anyhow}; use ssh2::Channel; use std::path::{Path, PathBuf}; use std::fs::File; use std::io::{Read, Write, BufReader, BufWriter}; use log::{info, warn, debug}; /// rsync Receiver Handler pub struct RsyncReceiverHandler { base_path: PathBuf, user_id: String, } impl RsyncReceiverHandler { pub fn new(base_path: PathBuf, user_id: String) -> Self { Self { base_path, user_id } } /// 处理rsync receiver命令 pub fn handle_rsync_receiver(&self, channel: &mut Channel, command: &str) -> Result<()> { info!("rsync receiver command: {}", command); // 解析rsync命令 // rsync --server --receiver . /path/to/file let parts: Vec<&str> = command.split_whitespace().collect(); if parts.len() < 4 { return Err(anyhow!("Invalid rsync command: {}", command)); } // 获取目标路径 let dest_path = parts.last().unwrap_or("."); let full_path = self.base_path.join(&self.user_id).join(dest_path); info!("rsync receiver target: {}", full_path.display()); // rsync receiver流程: // 1. 接收客户端checksum // 2. 发送文件列表 // 3. 接收delta数据 // 4. 应用delta到目标文件 // Phase 1:接收客户端checksum self.receive_checksums(channel)?; // Phase 2:发送文件列表(空列表,因为这是receiver) channel.write_all(b"\0\0\0\0")?; // 空文件列表 // Phase 3:接收delta数据并应用 self.receive_delta_data(channel, &full_path)?; info!("rsync receiver completed"); Ok(()) } /// 接收客户端checksum fn receive_checksums(&self, channel: &mut Channel) -> Result<()> { debug!("Receiving client checksums"); let mut buf = vec![0u8; 4096]; let len = channel.read(&mut buf)?; if len == 0 { warn!("No checksum data received"); return Ok(()); } debug!("Received {} bytes of checksum data", len); // 解析checksum数据(简化处理) // 实际rsync checksum格式:block_size + weak_checksum + strong_checksum Ok(()) } /// 接收delta数据并应用到文件 fn receive_delta_data(&self, channel: &mut Channel, dest_path: &Path) -> Result<()> { debug!("Receiving delta data for: {}", dest_path.display()); // 创建目标文件 let mut file = BufWriter::new(File::create(dest_path)?); let mut buf = vec![0u8; 8192]; let mut received = 0; // 读取delta数据直到EOF loop { let len = channel.read(&mut buf)?; if len == 0 { break; } // 简化处理:直接写入数据(实际应解析delta指令) file.write_all(&buf[..len])?; received += len; // 发送进度确认 channel.write_all(&[0x00])?; } file.flush()?; info!("Received {} bytes of delta data", received); Ok(()) } }