find: Allow -user UID / -group GID

POSIX says

> -user uname
>   The primary shall evaluate as true if the file belongs to the user
>   uname. If uname is a decimal integer and the getpwnam() (or
>   equivalent) function does not return a valid user name, uname shall
>   be interpreted as a user ID.

and similarly for -group.

Link: https://pubs.opengroup.org/onlinepubs/9799919799/utilities/find.html
This commit is contained in:
Tavian Barnes
2025-04-04 09:51:19 +02:00
committed by Sylvestre Ledru
parent 81c39aad7d
commit 6d264dbbcf
2 changed files with 40 additions and 38 deletions
+24 -16
View File
@@ -717,16 +717,20 @@ fn build_matcher_tree(
}
i += 1;
let matcher = UserMatcher::from_user_name(user);
match matcher.uid() {
Some(_) => Some(matcher.into_box()),
None => {
return Err(From::from(format!(
"{} is not the name of a known user",
user
)))
let mut matcher = UserMatcher::from_user_name(user);
if matcher.uid().is_none() {
// If it's not a valid user name, it may be a UID
match user.parse::<u32>() {
Ok(uid) => matcher = UserMatcher::from_uid(uid),
_ => {
return Err(From::from(format!(
"{} is not the name of a known user",
user
)))
}
}
}
Some(matcher.into_box())
}
"-nouser" => Some(NoUserMatcher {}.into_box()),
"-uid" => {
@@ -755,16 +759,20 @@ fn build_matcher_tree(
}
i += 1;
let matcher = GroupMatcher::from_group_name(group);
match matcher.gid() {
Some(_) => Some(matcher.into_box()),
None => {
return Err(From::from(format!(
"{} is not the name of an existing group",
group
)))
let mut matcher = GroupMatcher::from_group_name(group);
if matcher.gid().is_none() {
// If it's not a valid group name, it may be a GID
match group.parse::<u32>() {
Ok(gid) => matcher = GroupMatcher::from_gid(gid),
_ => {
return Err(From::from(format!(
"{} is not the name of an existing group",
group
)))
}
}
}
Some(matcher.into_box())
}
"-nogroup" => Some(NoGroupMatcher {}.into_box()),
"-gid" => {
+16 -22
View File
@@ -1163,17 +1163,14 @@ mod tests {
);
// test uid
let deps = FakeDependencies::new();
let rc = find_main(
&[
"find",
"./test_data/simple/subdir",
"-uid",
&uid.to_string(),
],
&deps,
);
assert_eq!(rc, 0);
for arg in ["-uid", "-user"] {
let deps = FakeDependencies::new();
let rc = find_main(
&["find", "./test_data/simple/subdir", arg, &uid.to_string()],
&deps,
);
assert_eq!(rc, 0);
}
// test empty uid
let deps = FakeDependencies::new();
@@ -1233,17 +1230,14 @@ mod tests {
);
// test gid
let deps = FakeDependencies::new();
let rc = find_main(
&[
"find",
"./test_data/simple/subdir",
"-gid",
gid.to_string().as_str(),
],
&deps,
);
assert_eq!(rc, 0);
for arg in ["-gid", "-group"] {
let deps = FakeDependencies::new();
let rc = find_main(
&["find", "./test_data/simple/subdir", arg, &gid.to_string()],
&deps,
);
assert_eq!(rc, 0);
}
// test empty gid
let deps = FakeDependencies::new();