Fix several logic issues causing failure during archive extraction
This commit is contained in:
parent
b070a129f8
commit
377b4bbb05
@ -8,6 +8,7 @@ pub enum Error {
|
|||||||
Io(io::Error),
|
Io(io::Error),
|
||||||
Utf8(FromUtf8Error),
|
Utf8(FromUtf8Error),
|
||||||
Slice(TryFromSliceError),
|
Slice(TryFromSliceError),
|
||||||
|
BadPath,
|
||||||
InvalidChecksum,
|
InvalidChecksum,
|
||||||
InvalidAlgorithm,
|
InvalidAlgorithm,
|
||||||
InvalidMagic,
|
InvalidMagic,
|
||||||
@ -27,6 +28,7 @@ impl fmt::Display for Error {
|
|||||||
Self::Utf8(e) => write!(f, "{e}"),
|
Self::Utf8(e) => write!(f, "{e}"),
|
||||||
Self::Slice(e) => write!(f, "{e}"),
|
Self::Slice(e) => write!(f, "{e}"),
|
||||||
Self::Io(e) => write!(f, "{e}"),
|
Self::Io(e) => write!(f, "{e}"),
|
||||||
|
Self::BadPath => write!(f, "bad path"),
|
||||||
Self::InvalidAlgorithm => write!(f, "invalid algorithm"),
|
Self::InvalidAlgorithm => write!(f, "invalid algorithm"),
|
||||||
Self::InvalidChecksum => write!(f, "invalid checksum"),
|
Self::InvalidChecksum => write!(f, "invalid checksum"),
|
||||||
Self::InvalidMagic => write!(f, "invalid magic"),
|
Self::InvalidMagic => write!(f, "invalid magic"),
|
||||||
|
41
src/node.rs
41
src/node.rs
@ -5,9 +5,9 @@ use {
|
|||||||
sha2::Sha256,
|
sha2::Sha256,
|
||||||
std::{
|
std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
fs,
|
env, fs,
|
||||||
io::{BufReader, BufWriter, Read, Write},
|
io::{BufReader, BufWriter, Read, Write},
|
||||||
os::unix::fs::{symlink, DirBuilderExt, MetadataExt},
|
os::unix::fs::{symlink, MetadataExt},
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
sync::Mutex,
|
sync::Mutex,
|
||||||
},
|
},
|
||||||
@ -215,18 +215,29 @@ impl Node {
|
|||||||
if let Some(prefix) = prefix {
|
if let Some(prefix) = prefix {
|
||||||
if self.name.starts_with('/') {
|
if self.name.starts_with('/') {
|
||||||
break 'blk format!("{prefix}{}", self.name);
|
break 'blk format!("{prefix}{}", self.name);
|
||||||
|
} else {
|
||||||
|
break 'blk format!("{prefix}/{}", self.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.name.clone()
|
self.name.clone()
|
||||||
};
|
};
|
||||||
let p = PathBuf::from(&path);
|
let n_path = if path.starts_with('/') {
|
||||||
if let Some(parent) = p.parent() {
|
PathBuf::from(&path)
|
||||||
if !parent.exists() {
|
} else {
|
||||||
self.mkdir(&parent)?;
|
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 {
|
match self.filetype {
|
||||||
FileType::Eof => {}
|
FileType::Eof => {},
|
||||||
FileType::Fifo => {
|
FileType::Fifo => {
|
||||||
nix::mkfifo(&path, self.mode)?;
|
nix::mkfifo(&path, self.mode)?;
|
||||||
if euid == 0 {
|
if euid == 0 {
|
||||||
@ -244,12 +255,6 @@ impl Node {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
FileType::Normal(ref n) => {
|
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()
|
let fd = fs::OpenOptions::new()
|
||||||
.create(true)
|
.create(true)
|
||||||
@ -279,21 +284,17 @@ impl Node {
|
|||||||
self.mkdir(&PathBuf::from(&path))?;
|
self.mkdir(&PathBuf::from(&path))?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
todo!()
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mkdir(&self, dir: &Path) -> Result<(), Error> {
|
fn mkdir(&self, dir: &Path) -> Result<(), Error> {
|
||||||
if let Some(p) = dir.parent() {
|
|
||||||
if !p.exists() {
|
|
||||||
self.mkdir(&p)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !dir.exists() {
|
if !dir.exists() {
|
||||||
fs::DirBuilder::new().mode(self.mode).create(dir)?;
|
fs::create_dir_all(dir)?;
|
||||||
}
|
}
|
||||||
if nix::geteuid() == 0 {
|
if nix::geteuid() == 0 {
|
||||||
nix::chown(dir.to_str().ok_or(Error::NulError)?, self.uid, self.gid)?;
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::MAGIC;
|
use crate::MAGIC;
|
||||||
|
|
||||||
use {
|
use {
|
||||||
crate::{Error, FileType, Node},
|
crate::{Error, Node},
|
||||||
std::{
|
std::{
|
||||||
io::{ErrorKind, Read},
|
io::{ErrorKind, Read},
|
||||||
iter::Iterator,
|
iter::Iterator,
|
||||||
@ -9,8 +9,9 @@ use {
|
|||||||
};
|
};
|
||||||
#[cfg(feature = "parallel")]
|
#[cfg(feature = "parallel")]
|
||||||
use {
|
use {
|
||||||
|
crate::FileType,
|
||||||
rayon::{iter::ParallelBridge, prelude::ParallelIterator},
|
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
|
/// 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>(())
|
Ok::<(), Error>(())
|
||||||
})?;
|
})?;
|
||||||
|
sender.send(Message::Eof).map_err(|_| Error::SenderError)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user