mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 19:47:45 +00:00
refactor(chgrp): move chgrp perms function into the uucore to reuse it into install
Will move chown later
This commit is contained in:
parent
431a4e9f2f
commit
763de90fda
6 changed files with 114 additions and 81 deletions
|
@ -15,7 +15,7 @@ edition = "2018"
|
||||||
path = "src/chgrp.rs"
|
path = "src/chgrp.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
uucore = { version=">=0.0.4", package="uucore", path="../../uucore", features=["entries", "fs"] }
|
uucore = { version=">=0.0.4", package="uucore", path="../../uucore", features=["entries", "fs", "perms"] }
|
||||||
uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" }
|
uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" }
|
||||||
walkdir = "2.2"
|
walkdir = "2.2"
|
||||||
|
|
||||||
|
|
|
@ -11,23 +11,18 @@
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
pub use uucore::entries;
|
pub use uucore::entries;
|
||||||
use uucore::fs::resolve_relative_path;
|
use uucore::fs::resolve_relative_path;
|
||||||
use uucore::libc::{self, gid_t, lchown};
|
use uucore::libc::gid_t;
|
||||||
|
use uucore::perms::{wrap_chgrp, Verbosity};
|
||||||
|
|
||||||
extern crate walkdir;
|
extern crate walkdir;
|
||||||
use walkdir::WalkDir;
|
use walkdir::WalkDir;
|
||||||
|
|
||||||
use std::io::Error as IOError;
|
|
||||||
use std::io::Result as IOResult;
|
|
||||||
|
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::fs::Metadata;
|
use std::fs::Metadata;
|
||||||
use std::os::unix::fs::MetadataExt;
|
use std::os::unix::fs::MetadataExt;
|
||||||
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use std::ffi::CString;
|
|
||||||
use std::os::unix::ffi::OsStrExt;
|
|
||||||
|
|
||||||
static SYNTAX: &str =
|
static SYNTAX: &str =
|
||||||
"chgrp [OPTION]... GROUP FILE...\n or : chgrp [OPTION]... --reference=RFILE FILE...";
|
"chgrp [OPTION]... GROUP FILE...\n or : chgrp [OPTION]... --reference=RFILE FILE...";
|
||||||
static SUMMARY: &str = "Change the group of each FILE to GROUP.";
|
static SUMMARY: &str = "Change the group of each FILE to GROUP.";
|
||||||
|
@ -165,14 +160,6 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
executor.exec()
|
executor.exec()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
|
||||||
enum Verbosity {
|
|
||||||
Silent,
|
|
||||||
Changes,
|
|
||||||
Verbose,
|
|
||||||
Normal,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Chgrper {
|
struct Chgrper {
|
||||||
dest_gid: gid_t,
|
dest_gid: gid_t,
|
||||||
bit_flag: u8,
|
bit_flag: u8,
|
||||||
|
@ -201,23 +188,6 @@ impl Chgrper {
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
fn chgrp<P: AsRef<Path>>(&self, path: P, dgid: gid_t, follow: bool) -> IOResult<()> {
|
|
||||||
let path = path.as_ref();
|
|
||||||
let s = CString::new(path.as_os_str().as_bytes()).unwrap();
|
|
||||||
let ret = unsafe {
|
|
||||||
if follow {
|
|
||||||
libc::chown(s.as_ptr(), (0 as gid_t).wrapping_sub(1), dgid)
|
|
||||||
} else {
|
|
||||||
lchown(s.as_ptr(), (0 as gid_t).wrapping_sub(1), dgid)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if ret == 0 {
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err(IOError::last_os_error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
fn is_bind_root<P: AsRef<Path>>(&self, root: P) -> bool {
|
fn is_bind_root<P: AsRef<Path>>(&self, root: P) -> bool {
|
||||||
// TODO: is there an equivalent on Windows?
|
// TODO: is there an equivalent on Windows?
|
||||||
|
@ -269,7 +239,13 @@ impl Chgrper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let ret = self.wrap_chgrp(path, &meta, follow_arg);
|
let ret = wrap_chgrp(
|
||||||
|
path,
|
||||||
|
&meta,
|
||||||
|
self.dest_gid,
|
||||||
|
follow_arg,
|
||||||
|
self.verbosity.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
if !self.recursive {
|
if !self.recursive {
|
||||||
ret
|
ret
|
||||||
|
@ -297,7 +273,7 @@ impl Chgrper {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ret = self.wrap_chgrp(path, &meta, follow);
|
ret = wrap_chgrp(path, &meta, self.dest_gid, follow, self.verbosity.clone());
|
||||||
}
|
}
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
@ -324,50 +300,4 @@ impl Chgrper {
|
||||||
};
|
};
|
||||||
Some(meta)
|
Some(meta)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wrap_chgrp<P: AsRef<Path>>(&self, path: P, meta: &Metadata, follow: bool) -> i32 {
|
|
||||||
use self::Verbosity::*;
|
|
||||||
let mut ret = 0;
|
|
||||||
let dest_gid = self.dest_gid;
|
|
||||||
let path = path.as_ref();
|
|
||||||
if let Err(e) = self.chgrp(path, dest_gid, follow) {
|
|
||||||
match self.verbosity {
|
|
||||||
Silent => (),
|
|
||||||
_ => {
|
|
||||||
show_info!("changing group of '{}': {}", path.display(), e);
|
|
||||||
if self.verbosity == Verbose {
|
|
||||||
println!(
|
|
||||||
"failed to change group of {} from {} to {}",
|
|
||||||
path.display(),
|
|
||||||
entries::gid2grp(meta.gid()).unwrap(),
|
|
||||||
entries::gid2grp(dest_gid).unwrap()
|
|
||||||
);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ret = 1;
|
|
||||||
} else {
|
|
||||||
let changed = dest_gid != meta.gid();
|
|
||||||
if changed {
|
|
||||||
match self.verbosity {
|
|
||||||
Changes | Verbose => {
|
|
||||||
println!(
|
|
||||||
"changed group of {} from {} to {}",
|
|
||||||
path.display(),
|
|
||||||
entries::gid2grp(meta.gid()).unwrap(),
|
|
||||||
entries::gid2grp(dest_gid).unwrap()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
_ => (),
|
|
||||||
};
|
|
||||||
} else if self.verbosity == Verbose {
|
|
||||||
println!(
|
|
||||||
"group of {} retained as {}",
|
|
||||||
path.display(),
|
|
||||||
entries::gid2grp(dest_gid).unwrap()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ret
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,7 @@ entries = ["libc"]
|
||||||
fs = ["libc"]
|
fs = ["libc"]
|
||||||
mode = ["libc"]
|
mode = ["libc"]
|
||||||
parse_time = []
|
parse_time = []
|
||||||
|
perms = ["libc"]
|
||||||
process = ["libc"]
|
process = ["libc"]
|
||||||
signals = []
|
signals = []
|
||||||
utf8 = []
|
utf8 = []
|
||||||
|
|
|
@ -13,11 +13,15 @@ pub mod zero_copy;
|
||||||
// ** non-windows
|
// ** non-windows
|
||||||
#[cfg(all(not(windows), feature = "mode"))]
|
#[cfg(all(not(windows), feature = "mode"))]
|
||||||
pub mod mode;
|
pub mod mode;
|
||||||
|
|
||||||
// ** unix-only
|
// ** unix-only
|
||||||
#[cfg(all(unix, feature = "entries"))]
|
#[cfg(all(unix, feature = "entries"))]
|
||||||
pub mod entries;
|
pub mod entries;
|
||||||
|
#[cfg(all(unix, feature = "perms"))]
|
||||||
|
pub mod perms;
|
||||||
#[cfg(all(unix, feature = "process"))]
|
#[cfg(all(unix, feature = "process"))]
|
||||||
pub mod process;
|
pub mod process;
|
||||||
|
|
||||||
#[cfg(all(unix, not(target_os = "fuchsia"), feature = "signals"))]
|
#[cfg(all(unix, not(target_os = "fuchsia"), feature = "signals"))]
|
||||||
pub mod signals;
|
pub mod signals;
|
||||||
#[cfg(all(
|
#[cfg(all(
|
||||||
|
|
96
src/uucore/src/lib/features/perms.rs
Normal file
96
src/uucore/src/lib/features/perms.rs
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
// This file is part of the uutils coreutils package.
|
||||||
|
//
|
||||||
|
// For the full copyright and license information, please view the LICENSE
|
||||||
|
// file that was distributed with this source code.
|
||||||
|
|
||||||
|
pub use crate::features::entries;
|
||||||
|
use libc::{self, gid_t, lchown};
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
pub use crate::*;
|
||||||
|
|
||||||
|
use std::io::Error as IOError;
|
||||||
|
use std::io::Result as IOResult;
|
||||||
|
|
||||||
|
use std::ffi::CString;
|
||||||
|
use std::fs::Metadata;
|
||||||
|
use std::os::unix::fs::MetadataExt;
|
||||||
|
|
||||||
|
use std::os::unix::ffi::OsStrExt;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
#[derive(PartialEq, Clone, Debug)]
|
||||||
|
pub enum Verbosity {
|
||||||
|
Silent,
|
||||||
|
Changes,
|
||||||
|
Verbose,
|
||||||
|
Normal,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn chgrp<P: AsRef<Path>>(path: P, dgid: gid_t, follow: bool) -> IOResult<()> {
|
||||||
|
let path = path.as_ref();
|
||||||
|
let s = CString::new(path.as_os_str().as_bytes()).unwrap();
|
||||||
|
let ret = unsafe {
|
||||||
|
if follow {
|
||||||
|
libc::chown(s.as_ptr(), (0 as gid_t).wrapping_sub(1), dgid)
|
||||||
|
} else {
|
||||||
|
lchown(s.as_ptr(), (0 as gid_t).wrapping_sub(1), dgid)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if ret == 0 {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(IOError::last_os_error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn wrap_chgrp<P: AsRef<Path>>(
|
||||||
|
path: P,
|
||||||
|
meta: &Metadata,
|
||||||
|
dest_gid: gid_t,
|
||||||
|
follow: bool,
|
||||||
|
verbosity: Verbosity,
|
||||||
|
) -> i32 {
|
||||||
|
use self::Verbosity::*;
|
||||||
|
let mut ret = 0;
|
||||||
|
let path = path.as_ref();
|
||||||
|
if let Err(e) = chgrp(path, dest_gid, follow) {
|
||||||
|
match verbosity {
|
||||||
|
Silent => (),
|
||||||
|
_ => {
|
||||||
|
show_info!("changing group of '{}': {}", path.display(), e);
|
||||||
|
if verbosity == Verbose {
|
||||||
|
println!(
|
||||||
|
"failed to change group of {} from {} to {}",
|
||||||
|
path.display(),
|
||||||
|
entries::gid2grp(meta.gid()).unwrap(),
|
||||||
|
entries::gid2grp(dest_gid).unwrap()
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret = 1;
|
||||||
|
} else {
|
||||||
|
let changed = dest_gid != meta.gid();
|
||||||
|
if changed {
|
||||||
|
match verbosity {
|
||||||
|
Changes | Verbose => {
|
||||||
|
println!(
|
||||||
|
"changed group of {} from {} to {}",
|
||||||
|
path.display(),
|
||||||
|
entries::gid2grp(meta.gid()).unwrap(),
|
||||||
|
entries::gid2grp(dest_gid).unwrap()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
};
|
||||||
|
} else if verbosity == Verbose {
|
||||||
|
println!(
|
||||||
|
"group of {} retained as {}",
|
||||||
|
path.display(),
|
||||||
|
entries::gid2grp(dest_gid).unwrap()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret
|
||||||
|
}
|
|
@ -53,6 +53,8 @@ pub use crate::features::mode;
|
||||||
// ** unix-only
|
// ** unix-only
|
||||||
#[cfg(all(unix, feature = "entries"))]
|
#[cfg(all(unix, feature = "entries"))]
|
||||||
pub use crate::features::entries;
|
pub use crate::features::entries;
|
||||||
|
#[cfg(all(unix, feature = "perms"))]
|
||||||
|
pub use crate::features::perms;
|
||||||
#[cfg(all(unix, feature = "process"))]
|
#[cfg(all(unix, feature = "process"))]
|
||||||
pub use crate::features::process;
|
pub use crate::features::process;
|
||||||
#[cfg(all(unix, not(target_os = "fuchsia"), feature = "signals"))]
|
#[cfg(all(unix, not(target_os = "fuchsia"), feature = "signals"))]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue