Fix several logic issues causing failure during archive extraction

This commit is contained in:
Nathan Fisher 2023-07-11 00:57:22 -04:00
parent b070a129f8
commit 377b4bbb05
3 changed files with 27 additions and 22 deletions

View File

@ -8,6 +8,7 @@ pub enum Error {
Io(io::Error),
Utf8(FromUtf8Error),
Slice(TryFromSliceError),
BadPath,
InvalidChecksum,
InvalidAlgorithm,
InvalidMagic,
@ -27,6 +28,7 @@ impl fmt::Display for Error {
Self::Utf8(e) => write!(f, "{e}"),
Self::Slice(e) => write!(f, "{e}"),
Self::Io(e) => write!(f, "{e}"),
Self::BadPath => write!(f, "bad path"),
Self::InvalidAlgorithm => write!(f, "invalid algorithm"),
Self::InvalidChecksum => write!(f, "invalid checksum"),
Self::InvalidMagic => write!(f, "invalid magic"),

View File

@ -5,9 +5,9 @@ use {
sha2::Sha256,
std::{
collections::HashMap,
fs,
env, fs,
io::{BufReader, BufWriter, Read, Write},
os::unix::fs::{symlink, DirBuilderExt, MetadataExt},
os::unix::fs::{symlink, MetadataExt},
path::{Path, PathBuf},
sync::Mutex,
},
@ -215,18 +215,29 @@ impl Node {
if let Some(prefix) = prefix {
if self.name.starts_with('/') {
break 'blk format!("{prefix}{}", self.name);
} else {
break 'blk format!("{prefix}/{}", self.name);
}
}
self.name.clone()
};
let p = PathBuf::from(&path);
if let Some(parent) = p.parent() {
if !parent.exists() {
self.mkdir(&parent)?;
let n_path = if path.starts_with('/') {
PathBuf::from(&path)
} else {
if let Ok(mut p) = env::current_dir() {
p.push(&path);
p
} else {
PathBuf::from(&format!("./{path}"))
}
};
if let Some(p) = n_path.parent() {
if !p.exists() {
self.mkdir(&p)?;
}
}
match self.filetype {
FileType::Eof => {}
FileType::Eof => {},
FileType::Fifo => {
nix::mkfifo(&path, self.mode)?;
if euid == 0 {
@ -244,12 +255,6 @@ impl Node {
}
}
FileType::Normal(ref n) => {
let n_path = PathBuf::from(&path);
if let Some(p) = n_path.parent() {
if !p.exists() {
self.mkdir(&p)?;
}
}
{
let fd = fs::OpenOptions::new()
.create(true)
@ -279,21 +284,17 @@ impl Node {
self.mkdir(&PathBuf::from(&path))?;
}
}
todo!()
Ok(())
}
fn mkdir(&self, dir: &Path) -> Result<(), Error> {
if let Some(p) = dir.parent() {
if !p.exists() {
self.mkdir(&p)?;
}
}
if !dir.exists() {
fs::DirBuilder::new().mode(self.mode).create(dir)?;
fs::create_dir_all(dir)?;
}
if nix::geteuid() == 0 {
nix::chown(dir.to_str().ok_or(Error::NulError)?, self.uid, self.gid)?;
}
nix::chmod(dir.to_str().ok_or(Error::BadPath)?, self.mode & 0o7777)?;
Ok(())
}
}

View File

@ -1,7 +1,7 @@
use crate::MAGIC;
use {
crate::{Error, FileType, Node},
crate::{Error, Node},
std::{
io::{ErrorKind, Read},
iter::Iterator,
@ -9,8 +9,9 @@ use {
};
#[cfg(feature = "parallel")]
use {
crate::FileType,
rayon::{iter::ParallelBridge, prelude::ParallelIterator},
std::{ops::DerefMut, sync::mpsc::Sender},
std::sync::mpsc::Sender,
};
/// An iterator over a series of archive `Node`'s. This struct is generic over any
@ -99,6 +100,7 @@ impl<R: Read + Send> Stream<R> {
}
Ok::<(), Error>(())
})?;
sender.send(Message::Eof).map_err(|_| Error::SenderError)?;
Ok(())
}
}