diff --git a/src/error.rs b/src/error.rs index f753cca..8132dba 100644 --- a/src/error.rs +++ b/src/error.rs @@ -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"), diff --git a/src/node.rs b/src/node.rs index 4356ca7..50e2ca1 100644 --- a/src/node.rs +++ b/src/node.rs @@ -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(()) } } diff --git a/src/stream.rs b/src/stream.rs index bfc41ca..317989a 100644 --- a/src/stream.rs +++ b/src/stream.rs @@ -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 Stream { } Ok::<(), Error>(()) })?; + sender.send(Message::Eof).map_err(|_| Error::SenderError)?; Ok(()) } }