diff options
author | Eelco Dolstra <edolstra@gmail.com> | 2019-03-27 14:12:20 +0100 |
---|---|---|
committer | Eelco Dolstra <edolstra@gmail.com> | 2019-11-26 22:07:28 +0100 |
commit | 11da5b2816e11b081d8ff38db4330addd2014f7e (patch) | |
tree | feeffda49248279c72805048bcebf1839a869015 /nix-rust/src/lib.rs | |
parent | abb8ef619ba2fab3ae16fb5b5430215905bac723 (diff) |
Add some Rust code
Diffstat (limited to 'nix-rust/src/lib.rs')
-rw-r--r-- | nix-rust/src/lib.rs | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/nix-rust/src/lib.rs b/nix-rust/src/lib.rs new file mode 100644 index 000000000..abcb89055 --- /dev/null +++ b/nix-rust/src/lib.rs @@ -0,0 +1,48 @@ +extern crate libc; +extern crate tar; + +use std::fs; +use std::io; +use std::os::unix::fs::OpenOptionsExt; +use std::path::Path; +use tar::Archive; + +#[no_mangle] +pub extern "C" fn unpack_tarfile(data: &[u8], dest_dir: &str) -> bool { + // FIXME: handle errors. + + let dest_dir = Path::new(dest_dir); + + let mut tar = Archive::new(data); + + for file in tar.entries().unwrap() { + let mut file = file.unwrap(); + + let dest_file = dest_dir.join(file.header().path().unwrap()); + + fs::create_dir_all(dest_file.parent().unwrap()).unwrap(); + + match file.header().entry_type() { + tar::EntryType::Directory => { + fs::create_dir(dest_file).unwrap(); + } + tar::EntryType::Regular => { + let mode = if file.header().mode().unwrap() & libc::S_IXUSR == 0 { + 0o666 + } else { + 0o777 + }; + let mut f = fs::OpenOptions::new() + .create(true) + .write(true) + .mode(mode) + .open(dest_file) + .unwrap(); + io::copy(&mut file, &mut f).unwrap(); + } + t => panic!("Unsupported tar entry type '{:?}'.", t), + } + } + + true +} |