use libarchive2::{ArchiveFormat, CompressionFormat, ReadDisk, SymlinkMode, WriteArchive};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let args: Vec<String> = std::env::args().collect();
if args.len() < 3 {
eprintln!("Usage: {} <source_directory> <output_archive>", args[0]);
eprintln!("\nExample: {} /path/to/dir output.tar.gz", args[0]);
std::process::exit(1);
}
let source_dir = &args[1];
let output_archive = &args[2];
println!("Creating archive from directory: {}", source_dir);
println!("Output archive: {}", output_archive);
println!();
let mut archive = WriteArchive::new()
.format(ArchiveFormat::TarPax)
.compression(CompressionFormat::Gzip)
.open_file(output_archive)?;
let mut disk = ReadDisk::new()?;
disk.set_symlink_mode(SymlinkMode::Physical)?;
disk.set_standard_lookup()?;
disk.open(source_dir)?;
let mut file_count = 0;
while let Some(entry_mut) = disk.next_entry()? {
let entry = entry_mut.as_entry();
let pathname = entry.pathname().unwrap_or_else(|| "<unknown>".to_string());
println!("Adding: {}", pathname);
archive.write_header(&entry_mut)?;
if entry.file_type() == libarchive2::FileType::RegularFile {
let size = entry.size();
if size > 0 {
println!(
" (File has {} bytes - would need to read from filesystem)",
size
);
}
}
file_count += 1;
if disk.can_descend() {
disk.descend()?;
}
}
archive.finish()?;
println!();
println!("Archive created successfully!");
println!("Total files added: {}", file_count);
Ok(())
}