chmod: show human-friendly permissions when --changes or --verbose is used.

Like GNU chmod.
This commit is contained in:
Valentin Lorentz 2018-05-02 23:23:05 +02:00
parent 5f9bb70422
commit 43aafd2f1c
4 changed files with 87 additions and 62 deletions

View file

@ -22,6 +22,7 @@ use std::path::Path;
use walker::Walker;
#[cfg(not(windows))]
use uucore::mode;
use uucore::fs::display_permissions_unix;
const NAME: &'static str = "chmod";
static SUMMARY: &'static str = "Change the mode of each FILE to MODE.
@ -226,10 +227,11 @@ impl Chmoder {
Ok(())
}
#[cfg(unix)]
fn change_file(&self, fperm: u32, mode: u32, file: &Path, path: &str) -> Result<(), i32> {
if fperm == mode {
if self.verbose && !self.changes {
show_info!("mode of '{}' retained as {:o}", file.display(), fperm);
show_info!("mode of '{}' retained as {:o} ({})", file.display(), fperm, display_permissions_unix(fperm));
}
Ok(())
} else if let Err(err) =
@ -240,20 +242,24 @@ impl Chmoder {
}
if self.verbose {
show_info!(
"failed to change mode of file '{}' from {:o} to {:o}",
"failed to change mode of file '{}' from {:o} ({}) to {:o} ({})",
file.display(),
fperm,
mode
display_permissions_unix(fperm),
mode,
display_permissions_unix(mode)
);
}
Err(1)
} else {
if self.verbose || self.changes {
show_info!(
"mode of '{}' changed from {:o} to {:o}",
"mode of '{}' changed from {:o} ({}) to {:o} ({})",
file.display(),
fperm,
mode
display_permissions_unix(fperm),
mode,
display_permissions_unix(mode)
);
}
Ok(())

View file

@ -19,7 +19,7 @@ unicode-width = "0.1.4"
[dependencies.uucore]
path = "../uucore"
features = ["entries"]
features = ["entries", "fs"]
[[bin]]
name = "ls"

View file

@ -24,8 +24,8 @@ extern crate lazy_static;
#[macro_use]
extern crate uucore;
#[cfg(unix)]
use uucore::libc::{mode_t, S_IRGRP, S_IROTH, S_IRUSR, S_ISGID, S_ISUID, S_ISVTX, S_IWGRP, S_IWOTH,
S_IWUSR, S_IXGRP, S_IXOTH, S_IXUSR};
use uucore::libc::{mode_t, S_ISGID, S_ISUID, S_ISVTX, S_IWOTH,
S_IXGRP, S_IXOTH, S_IXUSR};
use std::fs;
use std::fs::{DirEntry, FileType, Metadata};
@ -395,6 +395,8 @@ fn display_items(items: &Vec<PathBuf>, strip: Option<&Path>, options: &getopts::
}
}
use uucore::fs::display_permissions;
fn display_item_long(
item: &PathBuf,
strip: Option<&Path>,
@ -697,57 +699,3 @@ fn display_symlink_count(metadata: &Metadata) -> String {
metadata.nlink().to_string()
}
#[cfg(not(unix))]
#[allow(unused_variables)]
fn display_permissions(metadata: &Metadata) -> String {
String::from("---------")
}
#[cfg(unix)]
fn display_permissions(metadata: &Metadata) -> String {
let mode = metadata.mode() as mode_t;
let mut result = String::with_capacity(9);
result.push(if has!(mode, S_IRUSR) { 'r' } else { '-' });
result.push(if has!(mode, S_IWUSR) { 'w' } else { '-' });
result.push(if has!(mode, S_ISUID) {
if has!(mode, S_IXUSR) {
's'
} else {
'S'
}
} else if has!(mode, S_IXUSR) {
'x'
} else {
'-'
});
result.push(if has!(mode, S_IRGRP) { 'r' } else { '-' });
result.push(if has!(mode, S_IWGRP) { 'w' } else { '-' });
result.push(if has!(mode, S_ISGID) {
if has!(mode, S_IXGRP) {
's'
} else {
'S'
}
} else if has!(mode, S_IXGRP) {
'x'
} else {
'-'
});
result.push(if has!(mode, S_IROTH) { 'r' } else { '-' });
result.push(if has!(mode, S_IWOTH) { 'w' } else { '-' });
result.push(if has!(mode, S_ISVTX) {
if has!(mode, S_IXOTH) {
't'
} else {
'T'
}
} else if has!(mode, S_IXOTH) {
'x'
} else {
'-'
});
result
}

View file

@ -11,8 +11,13 @@ extern crate termion;
#[cfg(unix)]
use super::libc;
#[cfg(unix)]
use super::libc::{mode_t, S_IRGRP, S_IROTH, S_IRUSR, S_ISGID, S_ISUID, S_ISVTX, S_IWGRP, S_IWOTH,
S_IWUSR, S_IXGRP, S_IXOTH, S_IXUSR};
use std::env;
use std::fs;
#[cfg(any(unix, target_os = "redox"))]
use std::os::unix::fs::MetadataExt;
#[cfg(target_os = "redox")]
use std::io;
use std::io::{Error, ErrorKind};
@ -20,6 +25,12 @@ use std::io::Result as IOResult;
use std::path::{Component, Path, PathBuf};
use std::borrow::Cow;
macro_rules! has {
($mode:expr, $perm:expr) => (
$mode & ($perm as u32) != 0
)
}
pub fn resolve_relative_path<'a>(path: &'a Path) -> Cow<'a, Path> {
if path.components().all(|e| e != Component::ParentDir) {
return path.into();
@ -195,3 +206,63 @@ pub fn is_stderr_interactive() -> bool {
pub fn is_stderr_interactive() -> bool {
termion::is_tty(&io::stderr())
}
#[cfg(not(unix))]
#[allow(unused_variables)]
pub fn display_permissions(metadata: &fs::Metadata) -> String {
String::from("---------")
}
#[cfg(unix)]
pub fn display_permissions(metadata: &fs::Metadata) -> String {
let mode: mode_t = metadata.mode() as mode_t;
display_permissions_unix(mode as u32)
}
#[cfg(unix)]
pub fn display_permissions_unix(mode: u32) -> String {
let mut result = String::with_capacity(9);
result.push(if has!(mode, S_IRUSR) { 'r' } else { '-' });
result.push(if has!(mode, S_IWUSR) { 'w' } else { '-' });
result.push(if has!(mode, S_ISUID) {
if has!(mode, S_IXUSR) {
's'
} else {
'S'
}
} else if has!(mode, S_IXUSR) {
'x'
} else {
'-'
});
result.push(if has!(mode, S_IRGRP) { 'r' } else { '-' });
result.push(if has!(mode, S_IWGRP) { 'w' } else { '-' });
result.push(if has!(mode, S_ISGID) {
if has!(mode, S_IXGRP) {
's'
} else {
'S'
}
} else if has!(mode, S_IXGRP) {
'x'
} else {
'-'
});
result.push(if has!(mode, S_IROTH) { 'r' } else { '-' });
result.push(if has!(mode, S_IWOTH) { 'w' } else { '-' });
result.push(if has!(mode, S_ISVTX) {
if has!(mode, S_IXOTH) {
't'
} else {
'T'
}
} else if has!(mode, S_IXOTH) {
'x'
} else {
'-'
});
result
}