mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 11:37: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:
parent
195f827cd4
commit
a4fca2d4fc
2 changed files with 30 additions and 27 deletions
|
@ -160,6 +160,7 @@ pub fn uu_app() -> App<'static, 'static> {
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name(options::verbosity::VERBOSE)
|
Arg::with_name(options::verbosity::VERBOSE)
|
||||||
.long(options::verbosity::VERBOSE)
|
.long(options::verbosity::VERBOSE)
|
||||||
|
.short("v")
|
||||||
.help("output a diagnostic for every file processed"),
|
.help("output a diagnostic for every file processed"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -165,22 +165,26 @@ pub enum IfFrom {
|
||||||
UserGroup(u32, u32),
|
UserGroup(u32, u32),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq)]
|
||||||
|
pub enum TraverseSymlinks {
|
||||||
|
None,
|
||||||
|
First,
|
||||||
|
All,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct ChownExecutor {
|
pub struct ChownExecutor {
|
||||||
pub dest_uid: Option<u32>,
|
pub dest_uid: Option<u32>,
|
||||||
pub dest_gid: Option<u32>,
|
pub dest_gid: Option<u32>,
|
||||||
pub bit_flag: u8,
|
pub traverse_symlinks: TraverseSymlinks,
|
||||||
pub verbosity: Verbosity,
|
pub verbosity: Verbosity,
|
||||||
pub filter: IfFrom,
|
pub filter: IfFrom,
|
||||||
pub files: Vec<String>,
|
pub files: Vec<String>,
|
||||||
pub recursive: bool,
|
pub recursive: bool,
|
||||||
pub preserve_root: bool,
|
pub preserve_root: bool,
|
||||||
|
// Must be true if traverse_symlinks is not None
|
||||||
pub dereference: bool,
|
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 {
|
impl ChownExecutor {
|
||||||
pub fn exec(&self) -> UResult<()> {
|
pub fn exec(&self) -> UResult<()> {
|
||||||
let mut ret = 0;
|
let mut ret = 0;
|
||||||
|
@ -194,9 +198,8 @@ impl ChownExecutor {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn traverse<P: AsRef<Path>>(&self, root: P) -> i32 {
|
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 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,
|
Some(m) => m,
|
||||||
_ => return 1,
|
_ => return 1,
|
||||||
};
|
};
|
||||||
|
@ -208,7 +211,7 @@ impl ChownExecutor {
|
||||||
// (argument is symlink && should follow argument && resolved to be '/')
|
// (argument is symlink && should follow argument && resolved to be '/')
|
||||||
// )
|
// )
|
||||||
if self.recursive && self.preserve_root {
|
if self.recursive && self.preserve_root {
|
||||||
let may_exist = if follow_arg {
|
let may_exist = if self.dereference {
|
||||||
path.canonicalize().ok()
|
path.canonicalize().ok()
|
||||||
} else {
|
} else {
|
||||||
let real = resolve_relative_path(path);
|
let real = resolve_relative_path(path);
|
||||||
|
@ -234,7 +237,7 @@ impl ChownExecutor {
|
||||||
&meta,
|
&meta,
|
||||||
self.dest_uid,
|
self.dest_uid,
|
||||||
self.dest_gid,
|
self.dest_gid,
|
||||||
follow_arg,
|
self.dereference,
|
||||||
self.verbosity.clone(),
|
self.verbosity.clone(),
|
||||||
) {
|
) {
|
||||||
Ok(n) => {
|
Ok(n) => {
|
||||||
|
@ -264,9 +267,8 @@ impl ChownExecutor {
|
||||||
fn dive_into<P: AsRef<Path>>(&self, root: P) -> i32 {
|
fn dive_into<P: AsRef<Path>>(&self, root: P) -> i32 {
|
||||||
let mut ret = 0;
|
let mut ret = 0;
|
||||||
let root = root.as_ref();
|
let root = root.as_ref();
|
||||||
let follow = self.dereference || self.bit_flag & FTS_LOGICAL != 0;
|
|
||||||
let mut iterator = WalkDir::new(root)
|
let mut iterator = WalkDir::new(root)
|
||||||
.follow_links(follow)
|
.follow_links(self.dereference)
|
||||||
.min_depth(1)
|
.min_depth(1)
|
||||||
.into_iter();
|
.into_iter();
|
||||||
// We can't use a for loop because we need to manipulate the iterator inside the loop.
|
// 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,
|
Ok(entry) => entry,
|
||||||
};
|
};
|
||||||
let path = entry.path();
|
let path = entry.path();
|
||||||
let meta = match self.obtain_meta(path, follow) {
|
let meta = match self.obtain_meta(path, self.dereference) {
|
||||||
Some(m) => m,
|
Some(m) => m,
|
||||||
_ => {
|
_ => {
|
||||||
ret = 1;
|
ret = 1;
|
||||||
|
@ -314,7 +316,7 @@ impl ChownExecutor {
|
||||||
&meta,
|
&meta,
|
||||||
self.dest_uid,
|
self.dest_uid,
|
||||||
self.dest_gid,
|
self.dest_gid,
|
||||||
follow,
|
self.dereference,
|
||||||
self.verbosity.clone(),
|
self.verbosity.clone(),
|
||||||
) {
|
) {
|
||||||
Ok(n) => {
|
Ok(n) => {
|
||||||
|
@ -452,31 +454,31 @@ pub fn chown_base<'a>(
|
||||||
let preserve_root = matches.is_present(options::preserve_root::PRESERVE);
|
let preserve_root = matches.is_present(options::preserve_root::PRESERVE);
|
||||||
|
|
||||||
let mut dereference = if matches.is_present(options::dereference::DEREFERENCE) {
|
let mut dereference = if matches.is_present(options::dereference::DEREFERENCE) {
|
||||||
1
|
Some(true)
|
||||||
} else if matches.is_present(options::dereference::NO_DEREFERENCE) {
|
} else if matches.is_present(options::dereference::NO_DEREFERENCE) {
|
||||||
0
|
Some(false)
|
||||||
} else {
|
} else {
|
||||||
-1
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut bit_flag = if matches.is_present(options::traverse::TRAVERSE) {
|
let mut traverse_symlinks = if matches.is_present(options::traverse::TRAVERSE) {
|
||||||
FTS_COMFOLLOW | FTS_PHYSICAL
|
TraverseSymlinks::First
|
||||||
} else if matches.is_present(options::traverse::EVERY) {
|
} else if matches.is_present(options::traverse::EVERY) {
|
||||||
FTS_LOGICAL
|
TraverseSymlinks::All
|
||||||
} else {
|
} else {
|
||||||
FTS_PHYSICAL
|
TraverseSymlinks::None
|
||||||
};
|
};
|
||||||
|
|
||||||
let recursive = matches.is_present(options::RECURSIVE);
|
let recursive = matches.is_present(options::RECURSIVE);
|
||||||
if recursive {
|
if recursive {
|
||||||
if bit_flag == FTS_PHYSICAL {
|
if traverse_symlinks == TraverseSymlinks::None {
|
||||||
if dereference == 1 {
|
if dereference == Some(true) {
|
||||||
return Err(USimpleError::new(1, "-R --dereference requires -H or -L"));
|
return Err(USimpleError::new(1, "-R --dereference requires -H or -L"));
|
||||||
}
|
}
|
||||||
dereference = 0;
|
dereference = Some(false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
bit_flag = FTS_PHYSICAL;
|
traverse_symlinks = TraverseSymlinks::None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let verbosity_level = if matches.is_present(options::verbosity::CHANGES) {
|
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 (dest_gid, dest_uid, filter) = parse_gid_uid_and_filter(&matches)?;
|
||||||
|
|
||||||
let executor = ChownExecutor {
|
let executor = ChownExecutor {
|
||||||
bit_flag,
|
traverse_symlinks,
|
||||||
dest_gid,
|
dest_gid,
|
||||||
dest_uid,
|
dest_uid,
|
||||||
verbosity: Verbosity {
|
verbosity: Verbosity {
|
||||||
groups_only: true,
|
groups_only,
|
||||||
level: verbosity_level,
|
level: verbosity_level,
|
||||||
},
|
},
|
||||||
recursive,
|
recursive,
|
||||||
dereference: dereference != 0,
|
dereference: dereference.unwrap_or(true),
|
||||||
preserve_root,
|
preserve_root,
|
||||||
files,
|
files,
|
||||||
filter,
|
filter,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue