Skip to content

Commit

Permalink
read more attributes from tar archive
Browse files Browse the repository at this point in the history
  • Loading branch information
taminob committed Jan 24, 2024
1 parent 8800a69 commit 2a461ab
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 10 deletions.
92 changes: 85 additions & 7 deletions src/fs/archive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,21 @@ pub trait Directory: Sized {
fn join(&self, child: &Path) -> PathBuf;
}

pub struct Owner {
id: u64,
name: Option<String>,
}

pub struct ArchiveEntry {
// name: String,
pub path: String,
pub path: PathBuf,
pub size: u64,
// permissions
// owner
// file type
// mtime
pub user: Option<Owner>,
pub group: Option<Owner>,
pub is_directory: bool,
pub is_symlink: bool,
pub mtime: u64,
}

pub enum ArchiveFormat {
Expand All @@ -58,6 +65,60 @@ trait ArchiveReader {

struct TarReader {}

impl TarReader {
/// Get size of entry; the size written in the header field takes precedence
pub fn size<R: std::io::Read>(entry: &tar::Entry<'_, R>) -> u64 {
entry.header().size().unwrap_or(entry.size())
}

pub fn path<R: std::io::Read>(entry: &tar::Entry<'_, R>) -> io::Result<PathBuf> {
let mut path = entry.header().path();
if path.is_err() {
path = entry.path();
}
path.map(|p| p.to_path_buf())
}

pub fn is_directory<R: std::io::Read>(entry: &tar::Entry<'_, R>) -> bool {
entry.header().entry_type().is_dir()
}

pub fn is_link<R: std::io::Read>(entry: &tar::Entry<'_, R>) -> bool {
entry.header().entry_type().is_symlink()
}

pub fn link_target<R: std::io::Read>(entry: &tar::Entry<'_, R>) -> io::Result<Option<PathBuf>> {
entry
.header()
.link_name()
.map(|o| o.map(|p| p.to_path_buf()))
}

pub fn uid<R: std::io::Read>(entry: &tar::Entry<'_, R>) -> io::Result<u64> {
entry.header().uid()
}

pub fn gid<R: std::io::Read>(entry: &tar::Entry<'_, R>) -> io::Result<u64> {
entry.header().gid()
}

pub fn username<R: std::io::Read>(
entry: &tar::Entry<'_, R>,
) -> Result<Option<String>, std::str::Utf8Error> {
entry.header().username().map(|o| o.map(|s| s.to_owned()))
}

pub fn groupname<R: std::io::Read>(
entry: &tar::Entry<'_, R>,
) -> Result<Option<String>, std::str::Utf8Error> {
entry.header().groupname().map(|o| o.map(|s| s.to_owned()))
}

pub fn mtime<R: std::io::Read>(entry: &tar::Entry<'_, R>) -> io::Result<u64> {
entry.header().mtime()
}
}

impl ArchiveReader for TarReader {
fn read_dir(path: &PathBuf) -> io::Result<Vec<Result<ArchiveEntry, Error>>> {
let mut result = Vec::new();
Expand All @@ -66,9 +127,26 @@ impl ArchiveReader for TarReader {
for entry in entries {
match entry {
Ok(e) => {
let path = e.path().expect("TODO").to_string_lossy().to_string();
let size = e.size();
result.push(Ok(ArchiveEntry { path, size }));
let path = TarReader::path(&e);
if let Ok(p) = path {
result.push(Ok(ArchiveEntry {
path: p,
size: TarReader::size(&e),
user: Some(Owner {
id: TarReader::uid(&e).expect("TODO"),
name: TarReader::username(&e).expect("TODO"),
}),
group: Some(Owner {
id: TarReader::gid(&e).expect("TODO"),
name: TarReader::groupname(&e).expect("TODO"),
}),
mtime: TarReader::mtime(&e).expect("TODO"),
is_symlink: TarReader::is_link(&e),
is_directory: TarReader::is_directory(&e),
}));
} else {
result.push(Err(Error {}));
}
}
Err(_) => result.push(Err(Error {})),
}
Expand Down
8 changes: 5 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,9 +309,11 @@ impl<'args> Exa<'args> {
let is_only_dir = dirs.len() == 1 && no_files && no_archives;

self.options.filter.filter_argument_files(&mut files);
self.print_files(None, files)?;
if !is_only_archive {
self.print_files(None, files)?;
}

self.print_archives(archives, no_files, is_only_archive)?;
self.print_archives(archives, is_only_archive, is_only_archive)?;
self.print_dirs(dirs, no_files && no_archives, is_only_dir, exit_status)
}

Expand Down Expand Up @@ -531,7 +533,7 @@ impl<'args> Exa<'args> {

for entry in archive.files() {
match entry {
Ok(e) => writeln!(self.writer, "{}", e.path),
Ok(e) => writeln!(self.writer, "{}", e.path.display()),
Err(_) => writeln!(self.writer, "Error - TODO"),
}?;
}
Expand Down

0 comments on commit 2a461ab

Please sign in to comment.