diff options
author | Eelco Dolstra <edolstra@gmail.com> | 2019-09-15 23:09:30 +0200 |
---|---|---|
committer | Eelco Dolstra <edolstra@gmail.com> | 2019-12-10 13:37:23 +0100 |
commit | a1ff43045b3f1d075c67c262ff6f623b2b5d569e (patch) | |
tree | 08f2b7ef16ff519bad627e98a34034c937cef09e /nix-rust/src/util | |
parent | ce3c41aef0797954412719a8c4597efe8276dcd2 (diff) |
Move stuff around
Diffstat (limited to 'nix-rust/src/util')
-rw-r--r-- | nix-rust/src/util/mod.rs | 1 | ||||
-rw-r--r-- | nix-rust/src/util/tarfile.rs | 46 |
2 files changed, 47 insertions, 0 deletions
diff --git a/nix-rust/src/util/mod.rs b/nix-rust/src/util/mod.rs new file mode 100644 index 000000000..209627893 --- /dev/null +++ b/nix-rust/src/util/mod.rs @@ -0,0 +1 @@ +pub mod tarfile; diff --git a/nix-rust/src/util/tarfile.rs b/nix-rust/src/util/tarfile.rs new file mode 100644 index 000000000..379d9098f --- /dev/null +++ b/nix-rust/src/util/tarfile.rs @@ -0,0 +1,46 @@ +use crate::{foreign::Source, Error}; +use std::fs; +use std::io; +use std::os::unix::fs::OpenOptionsExt; +use std::path::Path; +use tar::Archive; + +pub fn unpack_tarfile(source: Source, dest_dir: &str) -> Result<(), Error> { + let dest_dir = Path::new(dest_dir); + + let mut tar = Archive::new(source); + + for file in tar.entries()? { + let mut file = file?; + + let dest_file = dest_dir.join(file.path()?); + + fs::create_dir_all(dest_file.parent().unwrap())?; + + match file.header().entry_type() { + tar::EntryType::Directory => { + fs::create_dir(dest_file)?; + } + tar::EntryType::Regular => { + let mode = if file.header().mode()? & (libc::S_IXUSR as u32) == 0 { + 0o666 + } else { + 0o777 + }; + let mut f = fs::OpenOptions::new() + .create(true) + .write(true) + .mode(mode) + .open(dest_file)?; + io::copy(&mut file, &mut f)?; + } + tar::EntryType::Symlink => { + std::os::unix::fs::symlink(file.header().link_name()?.unwrap(), dest_file)?; + } + tar::EntryType::XGlobalHeader | tar::EntryType::XHeader => {} + t => return Err(Error::Misc(format!("unsupported tar entry type '{:?}'", t))), + } + } + + Ok(()) +} |