Add ability to override uid/gid when creating an archive
This commit is contained in:
parent
1740dcb79c
commit
3269da7fe8
@ -36,6 +36,6 @@ to see Haggis implemented in other languages.
|
|||||||
## Roadmap
|
## Roadmap
|
||||||
- [x] Create and extract archives
|
- [x] Create and extract archives
|
||||||
- [x] List archive nodes
|
- [x] List archive nodes
|
||||||
- [ ] Override user/group when creating archives
|
- [x] Override user/group when creating archives
|
||||||
- [x] Override user/group when extracting archives
|
- [x] Override user/group when extracting archives
|
||||||
- [ ] Automatically detect zstd compressed archives
|
- [ ] Automatically detect zstd compressed archives
|
||||||
|
34
src/lib.rs
34
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
|
/// Creates a haggis archive from a list of files
|
||||||
/// # Errors
|
/// # Errors
|
||||||
/// Returns `crate::Error` if io fails or several other error conditions
|
/// 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<u32>,
|
||||||
|
gid: Option<u32>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
let fd = fs::OpenOptions::new()
|
let fd = fs::OpenOptions::new()
|
||||||
.create(true)
|
.create(true)
|
||||||
.truncate(true)
|
.truncate(true)
|
||||||
.open(path)?;
|
.open(path)?;
|
||||||
let mut writer = BufWriter::new(fd);
|
let mut writer = BufWriter::new(fd);
|
||||||
stream_archive(&mut writer, files, algorithm)?;
|
stream_archive(&mut writer, files, algorithm, uid, gid)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,13 +67,21 @@ pub fn stream_archive<W: Write>(
|
|||||||
mut writer: W,
|
mut writer: W,
|
||||||
files: &[String],
|
files: &[String],
|
||||||
algorithm: Algorithm,
|
algorithm: Algorithm,
|
||||||
|
uid: Option<u32>,
|
||||||
|
gid: Option<u32>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
writer.write_all(&MAGIC)?;
|
writer.write_all(&MAGIC)?;
|
||||||
let len = u32::try_from(files.len())?;
|
let len = u32::try_from(files.len())?;
|
||||||
writer.write_all(&len.to_le_bytes())?;
|
writer.write_all(&len.to_le_bytes())?;
|
||||||
let links = Mutex::new(HashMap::new());
|
let links = Mutex::new(HashMap::new());
|
||||||
for f in files {
|
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)?;
|
node.write(&mut writer)?;
|
||||||
}
|
}
|
||||||
writer.write_all(&[0; 8])?;
|
writer.write_all(&[0; 8])?;
|
||||||
@ -95,10 +109,12 @@ pub fn par_create_archive(
|
|||||||
files: &[String],
|
files: &[String],
|
||||||
algorithm: Algorithm,
|
algorithm: Algorithm,
|
||||||
sender: &Sender<Message>,
|
sender: &Sender<Message>,
|
||||||
|
uid: Option<u32>,
|
||||||
|
gid: Option<u32>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let fd = fs::File::create(path)?;
|
let fd = fs::File::create(path)?;
|
||||||
let writer = BufWriter::new(fd);
|
let writer = BufWriter::new(fd);
|
||||||
par_stream_archive(writer, files, algorithm, sender)?;
|
par_stream_archive(writer, files, algorithm, sender, uid, gid)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,6 +127,8 @@ pub fn par_stream_archive<W: Write + Send>(
|
|||||||
files: &[String],
|
files: &[String],
|
||||||
algorithm: Algorithm,
|
algorithm: Algorithm,
|
||||||
sender: &Sender<Message>,
|
sender: &Sender<Message>,
|
||||||
|
uid: Option<u32>,
|
||||||
|
gid: Option<u32>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
writer.write_all(&MAGIC)?;
|
writer.write_all(&MAGIC)?;
|
||||||
let len = u32::try_from(files.len())?;
|
let len = u32::try_from(files.len())?;
|
||||||
@ -119,13 +137,19 @@ pub fn par_stream_archive<W: Write + Send>(
|
|||||||
let writer = Mutex::new(writer);
|
let writer = Mutex::new(writer);
|
||||||
let s = sender.clone();
|
let s = sender.clone();
|
||||||
files.par_iter().try_for_each_with(s, |s, f| {
|
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,
|
Ok(n) => n,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
s.send(Message::Err(e)).map_err(|_| Error::SenderError)?;
|
s.send(Message::Err(e)).map_err(|_| Error::SenderError)?;
|
||||||
return Ok(());
|
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() {
|
if let Ok(mut writer) = writer.lock() {
|
||||||
let mut writer = &mut *writer;
|
let mut writer = &mut *writer;
|
||||||
if let Err(e) = node.write(&mut writer) {
|
if let Err(e) = node.write(&mut writer) {
|
||||||
|
Loading…
Reference in New Issue
Block a user