Cleanup chown
applet
This commit is contained in:
parent
7fc064a441
commit
e648a8a83a
99
Cargo.lock
generated
99
Cargo.lock
generated
@ -13,12 +13,6 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "autocfg"
|
|
||||||
version = "1.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "1.3.2"
|
version = "1.3.2"
|
||||||
@ -31,12 +25,6 @@ version = "1.0.78"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d"
|
checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cfg-if"
|
|
||||||
version = "1.0.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "4.1.1"
|
version = "4.1.1"
|
||||||
@ -88,61 +76,12 @@ dependencies = [
|
|||||||
"roff",
|
"roff",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "crossbeam-channel"
|
|
||||||
version = "0.5.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"crossbeam-utils",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "crossbeam-deque"
|
|
||||||
version = "0.8.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"crossbeam-epoch",
|
|
||||||
"crossbeam-utils",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "crossbeam-epoch"
|
|
||||||
version = "0.9.13"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg",
|
|
||||||
"cfg-if",
|
|
||||||
"crossbeam-utils",
|
|
||||||
"memoffset",
|
|
||||||
"scopeguard",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "crossbeam-utils"
|
|
||||||
version = "0.8.14"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "data-encoding"
|
name = "data-encoding"
|
||||||
version = "2.3.3"
|
version = "2.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "23d8666cb01533c39dde32bcbab8e227b4ed6679b2c925eba05feabea39508fb"
|
checksum = "23d8666cb01533c39dde32bcbab8e227b4ed6679b2c925eba05feabea39508fb"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "either"
|
|
||||||
version = "1.8.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "errno"
|
name = "errno"
|
||||||
version = "0.2.8"
|
version = "0.2.8"
|
||||||
@ -233,15 +172,6 @@ version = "0.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4"
|
checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "memoffset"
|
|
||||||
version = "0.7.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num_cpus"
|
name = "num_cpus"
|
||||||
version = "1.15.0"
|
version = "1.15.0"
|
||||||
@ -258,28 +188,6 @@ version = "6.4.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee"
|
checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rayon"
|
|
||||||
version = "1.6.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7"
|
|
||||||
dependencies = [
|
|
||||||
"either",
|
|
||||||
"rayon-core",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rayon-core"
|
|
||||||
version = "1.10.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3"
|
|
||||||
dependencies = [
|
|
||||||
"crossbeam-channel",
|
|
||||||
"crossbeam-deque",
|
|
||||||
"crossbeam-utils",
|
|
||||||
"num_cpus",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "roff"
|
name = "roff"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
@ -309,12 +217,6 @@ dependencies = [
|
|||||||
"winapi-util",
|
"winapi-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "scopeguard"
|
|
||||||
version = "1.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "shitbox"
|
name = "shitbox"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@ -328,7 +230,6 @@ dependencies = [
|
|||||||
"hostname",
|
"hostname",
|
||||||
"libc",
|
"libc",
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
"rayon",
|
|
||||||
"termcolor",
|
"termcolor",
|
||||||
"textwrap",
|
"textwrap",
|
||||||
"walkdir",
|
"walkdir",
|
||||||
|
@ -15,7 +15,6 @@ data-encoding = "2.3"
|
|||||||
hostname = { version = "0.3", features = ["set"] }
|
hostname = { version = "0.3", features = ["set"] }
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
num_cpus = "1.15"
|
num_cpus = "1.15"
|
||||||
rayon = "1.6.1"
|
|
||||||
termcolor = "1.1"
|
termcolor = "1.1"
|
||||||
textwrap = { version = "0.16", default-features = false, features = ["smawk"] }
|
textwrap = { version = "0.16", default-features = false, features = ["smawk"] }
|
||||||
walkdir = "2.3.2"
|
walkdir = "2.3.2"
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
use super::Cmd;
|
use super::Cmd;
|
||||||
use crate::{fs::FileType, pw};
|
use crate::pw;
|
||||||
use clap::{Arg, ArgAction, ArgGroup, Command, ValueHint};
|
use clap::{Arg, ArgAction, ArgGroup, ArgMatches, Command, ValueHint};
|
||||||
use std::{
|
use std::{
|
||||||
error::Error,
|
error::Error,
|
||||||
fs::{self, File},
|
fs::File,
|
||||||
io,
|
io,
|
||||||
os::{fd::AsRawFd, unix::prelude::MetadataExt},
|
os::{fd::AsRawFd, unix::prelude::MetadataExt},
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
@ -40,7 +40,6 @@ impl Cmd for Chown {
|
|||||||
.help("operate on files and directories recursively")
|
.help("operate on files and directories recursively")
|
||||||
.short('R')
|
.short('R')
|
||||||
.long("recursive")
|
.long("recursive")
|
||||||
.requires("links")
|
|
||||||
.action(ArgAction::SetTrue),
|
.action(ArgAction::SetTrue),
|
||||||
Arg::new("cli-traverse")
|
Arg::new("cli-traverse")
|
||||||
.help(
|
.help(
|
||||||
@ -80,59 +79,19 @@ impl Cmd for Chown {
|
|||||||
let Some(matches) = matches else {
|
let Some(matches) = matches else {
|
||||||
return Err(Box::new(io::Error::new(io::ErrorKind::Other, "no input")));
|
return Err(Box::new(io::Error::new(io::ErrorKind::Other, "no input")));
|
||||||
};
|
};
|
||||||
let recurse = if matches.get_flag("recursive") {
|
let recurse = Recurse::from_matches(matches);
|
||||||
if matches.get_flag("full-traverse") {
|
let feedback = Feedback::from_matches(matches);
|
||||||
Some(Recurse {
|
|
||||||
traversal: Traversal::FullLinks,
|
|
||||||
same_filesystem: matches.get_flag("same-filesystem"),
|
|
||||||
})
|
|
||||||
} else if matches.get_flag("cli-traverse") {
|
|
||||||
Some(Recurse {
|
|
||||||
traversal: Traversal::CliLinks,
|
|
||||||
same_filesystem: matches.get_flag("same-filesystem"),
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
Some(Recurse {
|
|
||||||
traversal: Traversal::NoLinks,
|
|
||||||
same_filesystem: matches.get_flag("same-filesystem"),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
let feedback = if matches.get_flag("verbose") {
|
|
||||||
Some(Feedback::Full)
|
|
||||||
} else if matches.get_flag("changes") {
|
|
||||||
Some(Feedback::Changes)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
let (user, group) = if let Some(who) = matches.get_one::<String>("user") {
|
let (user, group) = if let Some(who) = matches.get_one::<String>("user") {
|
||||||
if let Some((u, g)) = who.split_once(':') {
|
if let Some((u, g)) = who.split_once(':') {
|
||||||
let uid = pw::get_uid_for_name(u)
|
let uid = pw::get_uid_for_name(u)
|
||||||
.ok_or(io::Error::new(io::ErrorKind::Other, "cannot get uid"))?;
|
.ok_or(io::Error::new(io::ErrorKind::Other, "cannot get uid"))?;
|
||||||
let gid = pw::get_gid_for_groupname(g)
|
let gid = pw::get_gid_for_groupname(g)
|
||||||
.ok_or(io::Error::new(io::ErrorKind::Other, "cannot get gid"))?;
|
.ok_or(io::Error::new(io::ErrorKind::Other, "cannot get gid"))?;
|
||||||
(
|
(User { name: u, uid }, Some(Group { name: g, gid }))
|
||||||
User {
|
|
||||||
name: u.to_string(),
|
|
||||||
uid,
|
|
||||||
},
|
|
||||||
Some(Group {
|
|
||||||
name: g.to_string(),
|
|
||||||
gid,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
let uid = pw::get_uid_for_name(who)
|
let uid = pw::get_uid_for_name(who)
|
||||||
.ok_or(io::Error::new(io::ErrorKind::Other, "cannot get uid"))?;
|
.ok_or(io::Error::new(io::ErrorKind::Other, "cannot get uid"))?;
|
||||||
(
|
(User { name: who, uid }, None)
|
||||||
User {
|
|
||||||
name: who.to_string(),
|
|
||||||
uid,
|
|
||||||
},
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Err(Box::new(io::Error::new(
|
return Err(Box::new(io::Error::new(
|
||||||
@ -146,9 +105,17 @@ impl Cmd for Chown {
|
|||||||
path: PathBuf::from(f),
|
path: PathBuf::from(f),
|
||||||
user: user.clone(),
|
user: user.clone(),
|
||||||
group: group.clone(),
|
group: group.clone(),
|
||||||
recurse,
|
|
||||||
feedback,
|
feedback,
|
||||||
};
|
};
|
||||||
|
if let Some(r) = recurse {
|
||||||
|
if action.path.is_dir() {
|
||||||
|
action.recurse(recurse)?;
|
||||||
|
} else if action.path.is_symlink() {
|
||||||
|
if r.traversal != Traversal::NoLinks {
|
||||||
|
action.recurse(recurse)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
action.apply()?;
|
action.apply()?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -168,10 +135,13 @@ enum Traversal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Traversal {
|
impl Traversal {
|
||||||
fn increment(&self) -> Self {
|
fn from_matches(matches: &ArgMatches) -> Self {
|
||||||
match self {
|
if matches.get_flag("full-traverse") {
|
||||||
Self::CliLinks => Self::NoLinks,
|
Traversal::FullLinks
|
||||||
_ => *self,
|
} else if matches.get_flag("cli-traverse") {
|
||||||
|
Self::CliLinks
|
||||||
|
} else {
|
||||||
|
Self::NoLinks
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -183,10 +153,14 @@ struct Recurse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Recurse {
|
impl Recurse {
|
||||||
fn increment(&self) -> Self {
|
fn from_matches(matches: &ArgMatches) -> Option<Self> {
|
||||||
Self {
|
if matches.get_flag("recursive") {
|
||||||
traversal: self.traversal.increment(),
|
Some(Self {
|
||||||
same_filesystem: self.same_filesystem,
|
traversal: Traversal::from_matches(matches),
|
||||||
|
same_filesystem: matches.get_flag("same-filesystem"),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -197,28 +171,39 @@ enum Feedback {
|
|||||||
Changes,
|
Changes,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Feedback {
|
||||||
|
fn from_matches(matches: &ArgMatches) -> Option<Self> {
|
||||||
|
if matches.get_flag("verbose") {
|
||||||
|
Some(Feedback::Full)
|
||||||
|
} else if matches.get_flag("changes") {
|
||||||
|
Some(Feedback::Changes)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
struct User {
|
struct User<'a> {
|
||||||
name: String,
|
name: &'a str,
|
||||||
uid: u32,
|
uid: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
struct Group {
|
struct Group<'a> {
|
||||||
name: String,
|
name: &'a str,
|
||||||
gid: u32,
|
gid: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Action {
|
struct Action<'a> {
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
user: User,
|
user: User<'a>,
|
||||||
group: Option<Group>,
|
group: Option<Group<'a>>,
|
||||||
recurse: Option<Recurse>,
|
|
||||||
feedback: Option<Feedback>,
|
feedback: Option<Feedback>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Action {
|
impl Action<'_> {
|
||||||
fn apply(&self) -> Result<(), Box<dyn Error>> {
|
fn apply(&self) -> Result<(), Box<dyn Error>> {
|
||||||
let fd = File::open(&self.path)?;
|
let fd = File::open(&self.path)?;
|
||||||
let meta = fd.metadata()?;
|
let meta = fd.metadata()?;
|
||||||
@ -234,66 +219,19 @@ impl Action {
|
|||||||
return Err(io::Error::last_os_error().into());
|
return Err(io::Error::last_os_error().into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let ft = FileType::from(meta);
|
drop(fd);
|
||||||
match ft {
|
|
||||||
FileType::File => {}
|
|
||||||
FileType::Symlink => {
|
|
||||||
let tgt = fs::read_link(&self.path)?;
|
|
||||||
if tgt.is_dir() {
|
|
||||||
if let Some(r) = self.recurse {
|
|
||||||
if r.traversal != Traversal::NoLinks {
|
|
||||||
self.recurse()?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FileType::Dir => {
|
|
||||||
if let Some(r) = self.recurse {
|
|
||||||
if r.traversal != Traversal::NoLinks {
|
|
||||||
self.recurse()?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let Some(feedback) = self.feedback {
|
if let Some(feedback) = self.feedback {
|
||||||
match feedback {
|
match feedback {
|
||||||
Feedback::Full => {
|
Feedback::Full => {
|
||||||
if self.user.uid != uid || self.group.as_ref().map(|x| x.gid) != Some(gid) {
|
if self.user.uid != uid || self.group.as_ref().map(|x| x.gid) != Some(gid) {
|
||||||
if let Some(g) = &self.group {
|
self.display_changes(uid, gid)?;
|
||||||
println!(
|
|
||||||
"{} changed to {}:{}",
|
|
||||||
&self.path.display(),
|
|
||||||
&self.user.name,
|
|
||||||
&g.name
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
println!("{} changed to {}", &self.path.display(), &self.user.name);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if let Some(g) = &self.group {
|
self.display_retained();
|
||||||
println!(
|
|
||||||
"{} retained as {}:{}",
|
|
||||||
&self.path.display(),
|
|
||||||
&self.user.name,
|
|
||||||
&g.name
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
println!("{} retained as {}", &self.path.display(), &self.user.name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Feedback::Changes => {
|
Feedback::Changes => {
|
||||||
if self.user.uid != uid || self.group.as_ref().map(|x| x.gid) != Some(gid) {
|
if self.user.uid != uid || self.group.as_ref().map(|x| x.gid) != Some(gid) {
|
||||||
if let Some(g) = &self.group {
|
self.display_changes(uid, gid)?;
|
||||||
println!(
|
|
||||||
"{} changed to {}:{}",
|
|
||||||
self.path.display(),
|
|
||||||
&self.user.name,
|
|
||||||
&g.name
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
println!("{}, changed to {}", self.path.display(), &self.user.name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -301,28 +239,56 @@ impl Action {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn display_changes(&self, uid: u32, gid: u32) -> Result<(), std::str::Utf8Error> {
|
||||||
|
let username = pw::get_username_for_uid(uid)?;
|
||||||
|
let groupname = pw::get_groupname_for_gid(gid)?;
|
||||||
|
if let Some(g) = &self.group {
|
||||||
|
println!(
|
||||||
|
"{} changed from {username}:{groupname} to {}:{}",
|
||||||
|
&self.path.display(),
|
||||||
|
&self.user.name,
|
||||||
|
&g.name
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
println!(
|
||||||
|
"{} changed from {username} to {}",
|
||||||
|
&self.path.display(),
|
||||||
|
&self.user.name
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn display_retained(&self) {
|
||||||
|
if let Some(g) = &self.group {
|
||||||
|
println!(
|
||||||
|
"{} retained as {}:{}",
|
||||||
|
&self.path.display(),
|
||||||
|
&self.user.name,
|
||||||
|
&g.name
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
println!("{} retained as {}", &self.path.display(), &self.user.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn into_child(&self, entry: DirEntry) -> Result<Self, Box<dyn Error>> {
|
fn into_child(&self, entry: DirEntry) -> Result<Self, Box<dyn Error>> {
|
||||||
let path = entry.path().to_path_buf();
|
let path = entry.path().to_path_buf();
|
||||||
let recurse = if let Some(r) = self.recurse {
|
|
||||||
Some(r.increment())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
path,
|
path,
|
||||||
user: self.user.clone(),
|
user: self.user.clone(),
|
||||||
group: self.group.clone(),
|
group: self.group.clone(),
|
||||||
recurse,
|
|
||||||
feedback: self.feedback,
|
feedback: self.feedback,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn recurse(&self) -> Result<(), Box<dyn Error>> {
|
fn recurse(&self, recurse: Option<Recurse>) -> Result<(), Box<dyn Error>> {
|
||||||
let walker = WalkDir::new(&self.path)
|
let walker = WalkDir::new(&self.path)
|
||||||
.same_file_system(self.recurse.map_or(false, |x| !x.same_filesystem))
|
.max_open(1)
|
||||||
.follow_links(self.recurse.map_or(false, |x| match x.traversal {
|
.same_file_system(recurse.map_or(false, |x| x.same_filesystem))
|
||||||
Traversal::NoLinks | Traversal::CliLinks => false,
|
.follow_links(recurse.map_or(false, |x| match x.traversal {
|
||||||
_ => true,
|
Traversal::FullLinks => true,
|
||||||
|
_ => false,
|
||||||
}));
|
}));
|
||||||
for entry in walker {
|
for entry in walker {
|
||||||
let entry = entry?;
|
let entry = entry?;
|
||||||
|
Loading…
Reference in New Issue
Block a user