1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 03:27:44 +00:00

uucore/perms: remove flags in favor of enums

Part of the code was transliterated from GNU's implementation in C,
and used flags to store settings. Instead, we can use enums to avoid
magic values or binary operations to extract flags.
This commit is contained in:
Michael Debertol 2021-09-02 18:27:01 +02:00
parent 195f827cd4
commit a4fca2d4fc
2 changed files with 30 additions and 27 deletions

View file

@ -160,6 +160,7 @@ pub fn uu_app() -> App<'static, 'static> {
.arg(
Arg::with_name(options::verbosity::VERBOSE)
.long(options::verbosity::VERBOSE)
.short("v")
.help("output a diagnostic for every file processed"),
)
}

View file

@ -165,22 +165,26 @@ pub enum IfFrom {
UserGroup(u32, u32),
}
#[derive(PartialEq, Eq)]
pub enum TraverseSymlinks {
None,
First,
All,
}
pub struct ChownExecutor {
pub dest_uid: Option<u32>,
pub dest_gid: Option<u32>,
pub bit_flag: u8,
pub traverse_symlinks: TraverseSymlinks,
pub verbosity: Verbosity,
pub filter: IfFrom,
pub files: Vec<String>,
pub recursive: bool,
pub preserve_root: bool,
// Must be true if traverse_symlinks is not None
pub dereference: bool,
}
pub const FTS_COMFOLLOW: u8 = 1;
pub const FTS_PHYSICAL: u8 = 1 << 1;
pub const FTS_LOGICAL: u8 = 1 << 2;
impl ChownExecutor {
pub fn exec(&self) -> UResult<()> {
let mut ret = 0;
@ -194,9 +198,8 @@ impl ChownExecutor {
}
fn traverse<P: AsRef<Path>>(&self, root: P) -> i32 {
let follow_arg = self.dereference || self.bit_flag != FTS_PHYSICAL;
let path = root.as_ref();
let meta = match self.obtain_meta(path, follow_arg) {
let meta = match self.obtain_meta(path, self.dereference) {
Some(m) => m,
_ => return 1,
};
@ -208,7 +211,7 @@ impl ChownExecutor {
// (argument is symlink && should follow argument && resolved to be '/')
// )
if self.recursive && self.preserve_root {
let may_exist = if follow_arg {
let may_exist = if self.dereference {
path.canonicalize().ok()
} else {
let real = resolve_relative_path(path);
@ -234,7 +237,7 @@ impl ChownExecutor {
&meta,
self.dest_uid,
self.dest_gid,
follow_arg,
self.dereference,
self.verbosity.clone(),
) {
Ok(n) => {
@ -264,9 +267,8 @@ impl ChownExecutor {
fn dive_into<P: AsRef<Path>>(&self, root: P) -> i32 {
let mut ret = 0;
let root = root.as_ref();
let follow = self.dereference || self.bit_flag & FTS_LOGICAL != 0;
let mut iterator = WalkDir::new(root)
.follow_links(follow)
.follow_links(self.dereference)
.min_depth(1)
.into_iter();
// We can't use a for loop because we need to manipulate the iterator inside the loop.
@ -292,7 +294,7 @@ impl ChownExecutor {
Ok(entry) => entry,
};
let path = entry.path();
let meta = match self.obtain_meta(path, follow) {
let meta = match self.obtain_meta(path, self.dereference) {
Some(m) => m,
_ => {
ret = 1;
@ -314,7 +316,7 @@ impl ChownExecutor {
&meta,
self.dest_uid,
self.dest_gid,
follow,
self.dereference,
self.verbosity.clone(),
) {
Ok(n) => {
@ -452,31 +454,31 @@ pub fn chown_base<'a>(
let preserve_root = matches.is_present(options::preserve_root::PRESERVE);
let mut dereference = if matches.is_present(options::dereference::DEREFERENCE) {
1
Some(true)
} else if matches.is_present(options::dereference::NO_DEREFERENCE) {
0
Some(false)
} else {
-1
None
};
let mut bit_flag = if matches.is_present(options::traverse::TRAVERSE) {
FTS_COMFOLLOW | FTS_PHYSICAL
let mut traverse_symlinks = if matches.is_present(options::traverse::TRAVERSE) {
TraverseSymlinks::First
} else if matches.is_present(options::traverse::EVERY) {
FTS_LOGICAL
TraverseSymlinks::All
} else {
FTS_PHYSICAL
TraverseSymlinks::None
};
let recursive = matches.is_present(options::RECURSIVE);
if recursive {
if bit_flag == FTS_PHYSICAL {
if dereference == 1 {
if traverse_symlinks == TraverseSymlinks::None {
if dereference == Some(true) {
return Err(USimpleError::new(1, "-R --dereference requires -H or -L"));
}
dereference = 0;
dereference = Some(false);
}
} else {
bit_flag = FTS_PHYSICAL;
traverse_symlinks = TraverseSymlinks::None;
}
let verbosity_level = if matches.is_present(options::verbosity::CHANGES) {
@ -493,15 +495,15 @@ pub fn chown_base<'a>(
let (dest_gid, dest_uid, filter) = parse_gid_uid_and_filter(&matches)?;
let executor = ChownExecutor {
bit_flag,
traverse_symlinks,
dest_gid,
dest_uid,
verbosity: Verbosity {
groups_only: true,
groups_only,
level: verbosity_level,
},
recursive,
dereference: dereference != 0,
dereference: dereference.unwrap_or(true),
preserve_root,
files,
filter,