mirror of
https://git.proxmox.com/git/pxar
synced 2025-08-13 16:13:51 +00:00
examples/pxarcmd: acreate archives recursively
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
parent
749855a4dc
commit
21e2b2fa9b
@ -7,7 +7,7 @@ use std::path::Path;
|
|||||||
use failure::{bail, format_err, Error};
|
use failure::{bail, format_err, Error};
|
||||||
|
|
||||||
use pxar::accessor::Accessor;
|
use pxar::accessor::Accessor;
|
||||||
use pxar::encoder::Encoder;
|
use pxar::encoder::{Encoder, SeqWrite};
|
||||||
use pxar::{Metadata, Stat};
|
use pxar::{Metadata, Stat};
|
||||||
|
|
||||||
fn main() -> Result<(), Error> {
|
fn main() -> Result<(), Error> {
|
||||||
@ -64,21 +64,20 @@ fn cmd_create(mut args: std::env::ArgsOs) -> Result<(), Error> {
|
|||||||
.next()
|
.next()
|
||||||
.ok_or_else(|| format_err!("expected a file name"))?;
|
.ok_or_else(|| format_err!("expected a file name"))?;
|
||||||
|
|
||||||
let mut encoder = Encoder::create(
|
let dir_path = args
|
||||||
file,
|
.next()
|
||||||
&Stat::default()
|
.ok_or_else(|| format_err!("expected a directory"))?;
|
||||||
.mode(0o644)
|
|
||||||
.set_dir()
|
|
||||||
.uid(1000)
|
|
||||||
.gid(1000)
|
|
||||||
.into(),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
for path in args {
|
if args.next().is_some() {
|
||||||
let (mut file, file_size, meta) = open_file(&path)?;
|
bail!("too many parameters, there can only be a single root directory in a pxar archive");
|
||||||
encoder.add_file(&meta, &path, file_size, &mut file)?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// we use "simple" directory traversal without `openat()`
|
||||||
|
let meta = Metadata::from(std::fs::metadata(&dir_path)?);
|
||||||
|
let dir = std::fs::read_dir(dir_path)?;
|
||||||
|
|
||||||
|
let mut encoder = Encoder::create(file, &meta)?;
|
||||||
|
add_directory(&mut encoder, dir)?;
|
||||||
encoder.finish();
|
encoder.finish();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -90,3 +89,39 @@ fn open_file<P: AsRef<Path>>(path: P) -> io::Result<(File, u64, Metadata)> {
|
|||||||
let file_size = meta.len();
|
let file_size = meta.len();
|
||||||
Ok((file, file_size, meta.into()))
|
Ok((file, file_size, meta.into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn add_directory<'a, T: SeqWrite + 'a>(
|
||||||
|
encoder: &mut Encoder<T>,
|
||||||
|
dir: std::fs::ReadDir,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
for file in dir {
|
||||||
|
let file = file?;
|
||||||
|
let file_name = file.file_name();
|
||||||
|
if file_name == "." || file_name == ".." {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("{:?}", file.path());
|
||||||
|
|
||||||
|
let file_type = file.file_type()?;
|
||||||
|
let file_meta = file.metadata()?;
|
||||||
|
let meta = Metadata::from(&file_meta);
|
||||||
|
if file_type.is_dir() {
|
||||||
|
let mut dir = encoder.create_directory(file_name, &meta)?;
|
||||||
|
add_directory(&mut dir, std::fs::read_dir(file.path())?)?;
|
||||||
|
dir.finish();
|
||||||
|
} else if file_type.is_symlink() {
|
||||||
|
todo!("symlink handling");
|
||||||
|
} else if file_type.is_file() {
|
||||||
|
encoder.add_file(
|
||||||
|
&meta,
|
||||||
|
file_name,
|
||||||
|
file_meta.len(),
|
||||||
|
&mut File::open(file.path())?,
|
||||||
|
)?;
|
||||||
|
} else {
|
||||||
|
todo!("special file handling");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user