diff --git a/proxmox-compression/src/tar.rs b/proxmox-compression/src/tar.rs index 2521d344..64197722 100644 --- a/proxmox-compression/src/tar.rs +++ b/proxmox-compression/src/tar.rs @@ -178,102 +178,103 @@ where let mut hardlinks: HashMap> = HashMap::new(); // dev -> inode -> first path for entry in WalkDir::new(&source).into_iter() { - match entry { - Ok(entry) => { - let entry_path = entry.path().to_owned(); - let encoder = &mut encoder; - let hardlinks = &mut hardlinks; - - if let Err(err) = async move { - let entry_path_no_base = entry.path().strip_prefix(base_path)?; - let metadata = entry.metadata()?; - let mut header = Header::new_gnu(); - header.set_mode(metadata.mode()); - header.set_mtime(metadata.mtime() as u64); - header.set_uid(metadata.uid() as u64); - header.set_gid(metadata.gid() as u64); - header.set_size(0); - let dev = metadata.dev(); - - let file_type = entry.file_type(); - - if file_type.is_file() { - if metadata.nlink() > 1 { - let ino = metadata.ino(); - if let Some(map) = hardlinks.get_mut(&dev) { - if let Some(target) = map.get(&ino) { - header.set_entry_type(tar::EntryType::Link); - encoder - .add_link(&mut header, entry_path_no_base, target) - .await?; - return Ok(()); - } else { - map.insert(ino, entry_path_no_base.to_path_buf()); - } - } else { - let mut map = HashMap::new(); - map.insert(ino, entry_path_no_base.to_path_buf()); - hardlinks.insert(dev, map); - } - } - let file = tokio::fs::File::open(entry.path()).await?; - header.set_size(metadata.size()); - header.set_cksum(); - encoder - .add_entry(&mut header, entry_path_no_base, file) - .await?; - } else if file_type.is_dir() { - header.set_entry_type(EntryType::Directory); - header.set_cksum(); - encoder - .add_entry(&mut header, entry_path_no_base, tokio::io::empty()) - .await?; - } else if file_type.is_symlink() { - let target = std::fs::read_link(entry.path())?; - header.set_entry_type(EntryType::Symlink); - encoder - .add_link(&mut header, entry_path_no_base, target) - .await?; - } else if file_type.is_block_device() { - header.set_entry_type(EntryType::Block); - header.set_device_major(unsafe { libc::major(dev) })?; - header.set_device_minor(unsafe { libc::minor(dev) })?; - header.set_cksum(); - encoder - .add_entry(&mut header, entry_path_no_base, tokio::io::empty()) - .await?; - } else if file_type.is_char_device() { - header.set_entry_type(EntryType::Char); - header.set_device_major(unsafe { libc::major(dev) })?; - header.set_device_minor(unsafe { libc::minor(dev) })?; - header.set_cksum(); - encoder - .add_entry(&mut header, entry_path_no_base, tokio::io::empty()) - .await?; - } else if file_type.is_fifo() { - header.set_entry_type(EntryType::Fifo); - header.set_device_major(0)?; - header.set_device_minor(0)?; - header.set_cksum(); - encoder - .add_entry(&mut header, entry_path_no_base, tokio::io::empty()) - .await?; - } - // ignore other file_types - Ok::<_, Error>(()) - } - .await - { - eprintln!( - "zip: error encoding file or directory '{}': {}", - entry_path.display(), - err - ); - } - } + let entry = match entry { + Ok(entry) => entry, Err(err) => { eprintln!("zip: error reading directory entry: {}", err); + continue; } + }; + + let entry_path = entry.path().to_owned(); + let encoder = &mut encoder; + let hardlinks = &mut hardlinks; + + if let Err(err) = async move { + let entry_path_no_base = entry.path().strip_prefix(base_path)?; + let metadata = entry.metadata()?; + let mut header = Header::new_gnu(); + header.set_mode(metadata.mode()); + header.set_mtime(metadata.mtime() as u64); + header.set_uid(metadata.uid() as u64); + header.set_gid(metadata.gid() as u64); + header.set_size(0); + let dev = metadata.dev(); + + let file_type = entry.file_type(); + + if file_type.is_file() { + if metadata.nlink() > 1 { + let ino = metadata.ino(); + if let Some(map) = hardlinks.get_mut(&dev) { + if let Some(target) = map.get(&ino) { + header.set_entry_type(tar::EntryType::Link); + encoder + .add_link(&mut header, entry_path_no_base, target) + .await?; + return Ok(()); + } else { + map.insert(ino, entry_path_no_base.to_path_buf()); + } + } else { + let mut map = HashMap::new(); + map.insert(ino, entry_path_no_base.to_path_buf()); + hardlinks.insert(dev, map); + } + } + let file = tokio::fs::File::open(entry.path()).await?; + header.set_size(metadata.size()); + header.set_cksum(); + encoder + .add_entry(&mut header, entry_path_no_base, file) + .await?; + } else if file_type.is_dir() { + header.set_entry_type(EntryType::Directory); + header.set_cksum(); + encoder + .add_entry(&mut header, entry_path_no_base, tokio::io::empty()) + .await?; + } else if file_type.is_symlink() { + let target = std::fs::read_link(entry.path())?; + header.set_entry_type(EntryType::Symlink); + encoder + .add_link(&mut header, entry_path_no_base, target) + .await?; + } else if file_type.is_block_device() { + header.set_entry_type(EntryType::Block); + header.set_device_major(unsafe { libc::major(dev) })?; + header.set_device_minor(unsafe { libc::minor(dev) })?; + header.set_cksum(); + encoder + .add_entry(&mut header, entry_path_no_base, tokio::io::empty()) + .await?; + } else if file_type.is_char_device() { + header.set_entry_type(EntryType::Char); + header.set_device_major(unsafe { libc::major(dev) })?; + header.set_device_minor(unsafe { libc::minor(dev) })?; + header.set_cksum(); + encoder + .add_entry(&mut header, entry_path_no_base, tokio::io::empty()) + .await?; + } else if file_type.is_fifo() { + header.set_entry_type(EntryType::Fifo); + header.set_device_major(0)?; + header.set_device_minor(0)?; + header.set_cksum(); + encoder + .add_entry(&mut header, entry_path_no_base, tokio::io::empty()) + .await?; + } + // ignore other file_types + Ok::<_, Error>(()) + } + .await + { + eprintln!( + "zip: error encoding file or directory '{}': {}", + entry_path.display(), + err + ); } } Ok(()) diff --git a/proxmox-compression/src/zip.rs b/proxmox-compression/src/zip.rs index ac59b14d..fb110d13 100644 --- a/proxmox-compression/src/zip.rs +++ b/proxmox-compression/src/zip.rs @@ -632,49 +632,50 @@ where let mut encoder = ZipEncoder::new(target); for entry in WalkDir::new(&source).into_iter() { - match entry { - Ok(entry) => { - let entry_path = entry.path().to_owned(); - let encoder = &mut encoder; - - if let Err(err) = async move { - let entry_path_no_base = entry.path().strip_prefix(base_path)?; - let metadata = entry.metadata()?; - let mtime = match metadata - .modified() - .unwrap_or_else(|_| SystemTime::now()) - .duration_since(SystemTime::UNIX_EPOCH) - { - Ok(dur) => dur.as_secs() as i64, - Err(time_error) => -(time_error.duration().as_secs() as i64), - }; - let mode = metadata.mode() as u16; - - if entry.file_type().is_file() { - let file = tokio::fs::File::open(entry.path()).await?; - let ze = ZipEntry::new(&entry_path_no_base, mtime, mode, true); - encoder.add_entry(ze, Some(file)).await?; - } else if entry.file_type().is_dir() { - let ze = ZipEntry::new(&entry_path_no_base, mtime, mode, false); - let content: Option = None; - encoder.add_entry(ze, content).await?; - } - // ignore other file types - let ok: Result<(), Error> = Ok(()); - ok - } - .await - { - eprintln!( - "zip: error encoding file or directory '{}': {}", - entry_path.display(), - err - ); - } - } + let entry = match entry { + Ok(entry) => entry, Err(err) => { eprintln!("zip: error reading directory entry: {}", err); + continue; } + }; + + let entry_path = entry.path().to_owned(); + let encoder = &mut encoder; + + if let Err(err) = async move { + let entry_path_no_base = entry.path().strip_prefix(base_path)?; + let metadata = entry.metadata()?; + let mtime = match metadata + .modified() + .unwrap_or_else(|_| SystemTime::now()) + .duration_since(SystemTime::UNIX_EPOCH) + { + Ok(dur) => dur.as_secs() as i64, + Err(time_error) => -(time_error.duration().as_secs() as i64), + }; + let mode = metadata.mode() as u16; + + if entry.file_type().is_file() { + let file = tokio::fs::File::open(entry.path()).await?; + let ze = ZipEntry::new(&entry_path_no_base, mtime, mode, true); + encoder.add_entry(ze, Some(file)).await?; + } else if entry.file_type().is_dir() { + let ze = ZipEntry::new(&entry_path_no_base, mtime, mode, false); + let content: Option = None; + encoder.add_entry(ze, content).await?; + } + // ignore other file types + let ok: Result<(), Error> = Ok(()); + ok + } + .await + { + eprintln!( + "zip: error encoding file or directory '{}': {}", + entry_path.display(), + err + ); } }