From ab87f167f1d46fa6745fb2504221d7197017a643 Mon Sep 17 00:00:00 2001 From: Christian Ebner Date: Mon, 27 May 2019 13:59:17 +0200 Subject: [PATCH] src/pxar/encoder.rs: Refactor file stat Introduce helper functions to check file stats Signed-off-by: Christian Ebner --- src/pxar.rs | 2 ++ src/pxar/encoder.rs | 23 +++++++++++------------ src/pxar/helper.rs | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 12 deletions(-) create mode 100644 src/pxar/helper.rs diff --git a/src/pxar.rs b/src/pxar.rs index 803f59b3..481c0480 100644 --- a/src/pxar.rs +++ b/src/pxar.rs @@ -61,3 +61,5 @@ pub use sequential_decoder::*; mod decoder; pub use decoder::*; + +mod helper; diff --git a/src/pxar/encoder.rs b/src/pxar/encoder.rs index 38e3d055..b8552399 100644 --- a/src/pxar/encoder.rs +++ b/src/pxar/encoder.rs @@ -8,6 +8,7 @@ use std::collections::HashMap; use super::format_definition::*; use super::binary_search_tree::*; +use super::helper::*; use crate::tools::acl; use crate::tools::xattr; @@ -82,7 +83,7 @@ impl <'a, W: Write> Encoder<'a, W> { Err(err) => bail!("fstat {:?} failed - {}", path, err), }; - if (stat.st_mode & libc::S_IFMT) != libc::S_IFDIR { + if !is_directory(&stat) { bail!("got unexpected file type {:?} (not a directory)", path); } @@ -158,7 +159,7 @@ impl <'a, W: Write> Encoder<'a, W> { fn create_entry(&self, stat: &FileStat) -> Result { - let mode = if (stat.st_mode & libc::S_IFMT) == libc::S_IFLNK { + let mode = if is_symlink(&stat) { (libc::S_IFLNK | 0o777) as u64 } else { (stat.st_mode & (libc::S_IFMT | 0o7777)) as u64 @@ -232,7 +233,7 @@ impl <'a, W: Write> Encoder<'a, W> { return Ok((xattrs, fcaps)); } // Should never be called on symlinks, just in case check anyway - if (stat.st_mode & libc::S_IFMT) == libc::S_IFLNK { + if is_symlink(&stat) { return Ok((xattrs, fcaps)); } @@ -286,10 +287,10 @@ impl <'a, W: Write> Encoder<'a, W> { if !self.has_features(CA_FORMAT_WITH_ACL) { return Ok(ret); } - if (stat.st_mode & libc::S_IFMT) == libc::S_IFLNK { + if is_symlink(&stat) { return Ok(ret); } - if acl_type == acl::ACL_TYPE_DEFAULT && (stat.st_mode & libc::S_IFMT) != libc::S_IFDIR { + if acl_type == acl::ACL_TYPE_DEFAULT && !is_directory(&stat) { bail!("ACL_TYPE_DEFAULT only defined for directories."); } @@ -594,9 +595,7 @@ impl <'a, W: Write> Encoder<'a, W> { let start_pos = self.writer_pos; - let ifmt = stat.st_mode & libc::S_IFMT; - - if ifmt == libc::S_IFDIR { + if is_directory(&stat) { let mut dir = match nix::dir::Dir::openat(rawfd, filename.as_ref(), OFlag::O_DIRECTORY|OFlag::O_NOFOLLOW, Mode::empty()) { Ok(dir) => dir, @@ -616,7 +615,7 @@ impl <'a, W: Write> Encoder<'a, W> { self.write_filename(&filename)?; self.encode_dir(&mut dir, &stat, child_magic)?; - } else if ifmt == libc::S_IFREG { + } else if is_reg_file(&stat) { let mut hardlink_target = None; @@ -660,7 +659,7 @@ impl <'a, W: Write> Encoder<'a, W> { res?; } - } else if ifmt == libc::S_IFLNK { + } else if is_symlink(&stat) { let mut buffer = vec::undefined(libc::PATH_MAX as usize); let res = filename.with_nix_path(|cstr| { @@ -679,10 +678,10 @@ impl <'a, W: Write> Encoder<'a, W> { } Err(err) => bail!("readlink {:?} failed - {}", self.full_path(), err), } - } else if (ifmt == libc::S_IFBLK) || (ifmt == libc::S_IFCHR) { + } else if is_block_dev(&stat) || is_char_dev(&stat) { self.write_filename(&filename)?; self.encode_device(&stat)?; - } else if (ifmt == libc::S_IFIFO) || (ifmt == libc::S_IFSOCK) { + } else if is_fifo(&stat) || is_socket(&stat) { self.write_filename(&filename)?; self.encode_special(&stat)?; } else { diff --git a/src/pxar/helper.rs b/src/pxar/helper.rs new file mode 100644 index 00000000..982d3812 --- /dev/null +++ b/src/pxar/helper.rs @@ -0,0 +1,36 @@ +use libc; +use nix::sys::stat::FileStat; + +#[inline(always)] +pub fn is_directory(stat: &FileStat) -> bool { + (stat.st_mode & libc::S_IFMT) == libc::S_IFDIR +} + +#[inline(always)] +pub fn is_symlink(stat: &FileStat) -> bool { + (stat.st_mode & libc::S_IFMT) == libc::S_IFLNK +} + +#[inline(always)] +pub fn is_reg_file(stat: &FileStat) -> bool { + (stat.st_mode & libc::S_IFMT) == libc::S_IFREG +} + +#[inline(always)] +pub fn is_block_dev(stat: &FileStat) -> bool { + (stat.st_mode & libc::S_IFMT) == libc::S_IFBLK +} + +#[inline(always)] +pub fn is_char_dev(stat: &FileStat) -> bool { + (stat.st_mode & libc::S_IFMT) == libc::S_IFCHR +} + +#[inline(always)] +pub fn is_fifo(stat: &FileStat) -> bool { + (stat.st_mode & libc::S_IFMT) == libc::S_IFIFO +} +#[inline(always)] +pub fn is_socket(stat: &FileStat) -> bool { + (stat.st_mode & libc::S_IFMT) == libc::S_IFSOCK +}