diff --git a/README.md b/README.md index d07d09d..deb3885 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,6 @@ to see Haggis implemented in other languages. ## Roadmap - [x] Create and extract archives - [x] List archive nodes -- [ ] Override user/group when creating archives +- [x] Override user/group when creating archives - [x] Override user/group when extracting archives - [ ] Automatically detect zstd compressed archives diff --git a/src/lib.rs b/src/lib.rs index 37a623e..cc91538 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -44,13 +44,19 @@ pub static MAGIC: [u8; 7] = [0x89, b'h', b'a', b'g', b'g', b'i', b's']; /// Creates a haggis archive from a list of files /// # Errors /// Returns `crate::Error` if io fails or several other error conditions -pub fn create_archive(path: &str, files: &[String], algorithm: Algorithm) -> Result<(), Error> { +pub fn create_archive( + path: &str, + files: &[String], + algorithm: Algorithm, + uid: Option, + gid: Option, +) -> Result<(), Error> { let fd = fs::OpenOptions::new() .create(true) .truncate(true) .open(path)?; let mut writer = BufWriter::new(fd); - stream_archive(&mut writer, files, algorithm)?; + stream_archive(&mut writer, files, algorithm, uid, gid)?; Ok(()) } @@ -61,13 +67,21 @@ pub fn stream_archive( mut writer: W, files: &[String], algorithm: Algorithm, + uid: Option, + gid: Option, ) -> Result<(), Error> { writer.write_all(&MAGIC)?; let len = u32::try_from(files.len())?; writer.write_all(&len.to_le_bytes())?; let links = Mutex::new(HashMap::new()); for f in files { - let node = Node::from_path(f, algorithm, &links)?; + let mut node = Node::from_path(f, algorithm, &links)?; + if let Some(n) = uid { + node.uid = n; + } + if let Some(n) = gid { + node.gid = n; + } node.write(&mut writer)?; } writer.write_all(&[0; 8])?; @@ -95,10 +109,12 @@ pub fn par_create_archive( files: &[String], algorithm: Algorithm, sender: &Sender, + uid: Option, + gid: Option, ) -> Result<(), Error> { let fd = fs::File::create(path)?; let writer = BufWriter::new(fd); - par_stream_archive(writer, files, algorithm, sender)?; + par_stream_archive(writer, files, algorithm, sender, uid, gid)?; Ok(()) } @@ -111,6 +127,8 @@ pub fn par_stream_archive( files: &[String], algorithm: Algorithm, sender: &Sender, + uid: Option, + gid: Option, ) -> Result<(), Error> { writer.write_all(&MAGIC)?; let len = u32::try_from(files.len())?; @@ -119,13 +137,19 @@ pub fn par_stream_archive( let writer = Mutex::new(writer); let s = sender.clone(); files.par_iter().try_for_each_with(s, |s, f| { - let node = match Node::from_path(f, algorithm, &links) { + let mut node = match Node::from_path(f, algorithm, &links) { Ok(n) => n, Err(e) => { s.send(Message::Err(e)).map_err(|_| Error::SenderError)?; return Ok(()); } }; + if let Some(n) = uid { + node.uid = n; + } + if let Some(n) = gid { + node.gid = n; + } if let Ok(mut writer) = writer.lock() { let mut writer = &mut *writer; if let Err(e) = node.write(&mut writer) {