[ownership] depend on users 0.10.0 on unix; parse user and group names

This commit is contained in:
Alexandru Macovei 2018-06-30 22:57:20 +03:00 committed by David Peter
parent 4f9a02400a
commit d7cc34e36f
4 changed files with 57 additions and 2 deletions

11
Cargo.lock generated
View File

@ -137,6 +137,7 @@ dependencies = [
"regex 1.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)",
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"users 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -410,6 +411,15 @@ name = "unicode-width"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "users"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "vec_map"
version = "0.8.1"
@ -522,6 +532,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
"checksum thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
"checksum unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479"
"checksum users 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aa4227e95324a443c9fcb06e03d4d85e91aabe9a5a02aa818688b6918b6af486"
"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
"checksum version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce"
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"

View File

@ -51,6 +51,9 @@ anyhow = "1.0"
version = "2.31.2"
features = ["suggestions", "color", "wrap_help"]
[target.'cfg(unix)'.dependencies]
users = "0.10.0"
[target.'cfg(all(unix, not(target_os = "redox")))'.dependencies]
libc = "0.2"

View File

@ -1,4 +1,5 @@
use anyhow::{anyhow, Result};
use std::fs;
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct OwnerFilter {
@ -13,11 +14,29 @@ impl OwnerFilter {
let uid = match fst {
Some("") | None => None,
Some(s) => Some(s.parse()?),
Some(s) => {
let maybe_uid = s
.parse()
.ok()
.or_else(|| users::get_user_by_name(s).map(|user| user.uid()));
match maybe_uid {
Some(uid) => Some(uid),
_ => return Err(anyhow!("'{}' is not a recognized user name", s)),
}
}
};
let gid = match snd {
Some("") | None => None,
Some(s) => Some(s.parse()?),
Some(s) => {
let maybe_gid = s
.parse()
.ok()
.or_else(|| users::get_group_by_name(s).map(|group| group.gid()));
match maybe_gid {
Some(gid) => Some(gid),
_ => return Err(anyhow!("'{}' is not a recognized group name", s)),
}
}
};
if uid.is_none() && gid.is_none() {
@ -29,6 +48,15 @@ impl OwnerFilter {
Ok(OwnerFilter { uid, gid })
}
}
pub fn matches(&self, md: &fs::Metadata) -> bool {
use std::os::unix::fs::MetadataExt;
let uid_ok = self.uid.map(|u| u == md.uid()).unwrap_or(true);
let gid_ok = self.gid.map(|g| g == md.gid()).unwrap_or(true);
uid_ok && gid_ok
}
}
#[cfg(test)]

View File

@ -411,6 +411,19 @@ fn spawn_senders(
}
}
#[cfg(unix)]
{
if let Some(ref owner_constraint) = config.owner_constraint {
if let Ok(ref metadata) = entry_path.metadata() {
if !owner_constraint.matches(&metadata) {
return ignore::WalkState::Continue;
}
} else {
return ignore::WalkState::Continue;
}
}
}
// Filter out unwanted sizes if it is a file and we have been given size constraints.
if !config.size_constraints.is_empty() {
if entry_path.is_file() {