From 7fc064a441e3ebb42e1d6c7aaaf13cf8e04205ee Mon Sep 17 00:00:00 2001 From: Nathan Fisher Date: Wed, 18 Jan 2023 21:45:18 -0500 Subject: [PATCH] chown - Removed several clones --- src/cmd/chown/mod.rs | 96 ++++++++++++++++++++++++++++++++------------ 1 file changed, 71 insertions(+), 25 deletions(-) diff --git a/src/cmd/chown/mod.rs b/src/cmd/chown/mod.rs index c738fd9..025e3ee 100644 --- a/src/cmd/chown/mod.rs +++ b/src/cmd/chown/mod.rs @@ -1,7 +1,13 @@ use super::Cmd; use crate::{fs::FileType, pw}; use clap::{Arg, ArgAction, ArgGroup, Command, ValueHint}; -use std::{error::Error, fs::{File, self}, io, path::PathBuf, os::{unix::prelude::MetadataExt, fd::AsRawFd}}; +use std::{ + error::Error, + fs::{self, File}, + io, + os::{fd::AsRawFd, unix::prelude::MetadataExt}, + path::PathBuf, +}; use walkdir::{DirEntry, WalkDir}; #[derive(Debug, Default)] @@ -78,17 +84,17 @@ impl Cmd for Chown { if matches.get_flag("full-traverse") { Some(Recurse { traversal: Traversal::FullLinks, - same_filesystem: matches.get_flag("same-filesystem") + 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") + same_filesystem: matches.get_flag("same-filesystem"), }) } else { Some(Recurse { traversal: Traversal::NoLinks, - same_filesystem: matches.get_flag("same-filesystem") + same_filesystem: matches.get_flag("same-filesystem"), }) } } else { @@ -103,12 +109,30 @@ impl Cmd for Chown { }; let (user, group) = if let Some(who) = matches.get_one::("user") { if let Some((u, g)) = who.split_once(':') { - let uid = pw::get_uid_for_name(u).ok_or(io::Error::new(io::ErrorKind::Other, "cannot get uid"))?; - let gid = pw::get_gid_for_groupname(g).ok_or(io::Error::new(io::ErrorKind::Other, "cannot get gid"))?; - (User { name: u.to_string(), uid }, Some(Group { name: g.to_string(), gid })) + let uid = pw::get_uid_for_name(u) + .ok_or(io::Error::new(io::ErrorKind::Other, "cannot get uid"))?; + let gid = pw::get_gid_for_groupname(g) + .ok_or(io::Error::new(io::ErrorKind::Other, "cannot get gid"))?; + ( + User { + name: u.to_string(), + uid, + }, + Some(Group { + name: g.to_string(), + gid, + }), + ) } else { - let uid = pw::get_uid_for_name(who).ok_or(io::Error::new(io::ErrorKind::Other, "cannot get uid"))?; - (User { name: who.to_string(), uid }, None) + let uid = pw::get_uid_for_name(who) + .ok_or(io::Error::new(io::ErrorKind::Other, "cannot get uid"))?; + ( + User { + name: who.to_string(), + uid, + }, + None, + ) } } else { return Err(Box::new(io::Error::new( @@ -201,13 +225,18 @@ impl Action { let uid = meta.uid(); let gid = meta.gid(); unsafe { - if libc::fchown(fd.as_raw_fd(), self.user.uid, self.group.clone().map(|x| x.gid).unwrap_or(gid)) != 0 { + if libc::fchown( + fd.as_raw_fd(), + self.user.uid, + self.group.as_ref().map(|x| x.gid).unwrap_or(gid), + ) != 0 + { return Err(io::Error::last_os_error().into()); } } let ft = FileType::from(meta); match ft { - FileType::File => {}, + FileType::File => {} FileType::Symlink => { let tgt = fs::read_link(&self.path)?; if tgt.is_dir() { @@ -217,41 +246,56 @@ impl Action { } } } - }, + } FileType::Dir => { if let Some(r) = self.recurse { if r.traversal != Traversal::NoLinks { self.recurse()?; } } - }, + } } if let Some(feedback) = self.feedback { match feedback { Feedback::Full => { - if self.user.uid != uid || self.group.clone().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 { - println!("{} changed to {}:{}", &self.path.display(), &self.user.name, &g.name); + println!( + "{} changed to {}:{}", + &self.path.display(), + &self.user.name, + &g.name + ); } else { println!("{} changed to {}", &self.path.display(), &self.user.name); } } else { if let Some(g) = &self.group { - println!("{} retained as {}:{}", &self.path.display(), &self.user.name, &g.name); + println!( + "{} retained as {}:{}", + &self.path.display(), + &self.user.name, + &g.name + ); } else { println!("{} retained as {}", &self.path.display(), &self.user.name); } } } Feedback::Changes => { - if self.user.uid != uid || self.group.clone().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 { - println!("{} changed to {}:{}", self.path.display(), &self.user.name, &g.name); + println!( + "{} changed to {}:{}", + self.path.display(), + &self.user.name, + &g.name + ); } else { println!("{}, changed to {}", self.path.display(), &self.user.name); } } - }, + } } } Ok(()) @@ -259,7 +303,11 @@ impl Action { fn into_child(&self, entry: DirEntry) -> Result> { let path = entry.path().to_path_buf(); - let recurse = if let Some(r) = self.recurse { Some(r.increment()) } else { None }; + let recurse = if let Some(r) = self.recurse { + Some(r.increment()) + } else { + None + }; Ok(Self { path, user: self.user.clone(), @@ -272,11 +320,9 @@ impl Action { fn recurse(&self) -> Result<(), Box> { let walker = WalkDir::new(&self.path) .same_file_system(self.recurse.map_or(false, |x| !x.same_filesystem)) - .follow_links(self.recurse.map_or(false, |x| { - match x.traversal { - Traversal::NoLinks | Traversal::CliLinks => false, - _ => true, - } + .follow_links(self.recurse.map_or(false, |x| match x.traversal { + Traversal::NoLinks | Traversal::CliLinks => false, + _ => true, })); for entry in walker { let entry = entry?;