]> git.proxmox.com Git - proxmox-backup.git/blob - src/client/pxar_decode_writer.rs
src/api2/admin/datastore/backup.rs: use separate api entry points for chunk upload
[proxmox-backup.git] / src / client / pxar_decode_writer.rs
1 use failure::*;
2
3 use std::thread;
4 use std::os::unix::io::FromRawFd;
5 use std::path::{Path, PathBuf};
6 use std::io::Write;
7
8 use crate::pxar;
9
10 /// Writer implementation to deccode a .pxar archive (download).
11
12 pub struct PxarDecodeWriter {
13 pipe: Option<std::fs::File>,
14 child: Option<thread::JoinHandle<()>>,
15 }
16
17 impl Drop for PxarDecodeWriter {
18
19 fn drop(&mut self) {
20 drop(self.pipe.take());
21 self.child.take().unwrap().join().unwrap();
22 }
23 }
24
25 impl PxarDecodeWriter {
26
27 pub fn new(base: &Path, verbose: bool) -> Result<Self, Error> {
28 let (rx, tx) = nix::unistd::pipe()?;
29
30 let base = PathBuf::from(base);
31
32 let child = thread::spawn(move|| {
33 let mut reader = unsafe { std::fs::File::from_raw_fd(rx) };
34 let mut decoder = pxar::SequentialDecoder::new(&mut reader, pxar::CA_FORMAT_DEFAULT);
35
36 if let Err(err) = decoder.restore(&base, & |path| {
37 if verbose {
38 println!("{:?}", path);
39 }
40 Ok(())
41 }) {
42 eprintln!("pxar decode failed - {}", err);
43 }
44 });
45
46 let pipe = unsafe { std::fs::File::from_raw_fd(tx) };
47
48 Ok(Self { pipe: Some(pipe), child: Some(child) })
49 }
50 }
51
52 impl Write for PxarDecodeWriter {
53
54 fn write(&mut self, buffer: &[u8]) -> Result<usize, std::io::Error> {
55 let pipe = match self.pipe {
56 Some(ref mut pipe) => pipe,
57 None => unreachable!(),
58 };
59 pipe.write(buffer)
60 }
61
62 fn flush(&mut self) -> Result<(), std::io::Error> {
63 let pipe = match self.pipe {
64 Some(ref mut pipe) => pipe,
65 None => unreachable!(),
66 };
67 pipe.flush()
68 }
69 }