mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-31 13:07:46 +00:00
Merge pull request #792 from Arcterus/master
chmod: implement --verbose, --changes, and --quiet
This commit is contained in:
commit
5270761907
2 changed files with 44 additions and 31 deletions
|
@ -150,7 +150,6 @@ To do
|
||||||
|
|
||||||
- chcon
|
- chcon
|
||||||
- chgrp
|
- chgrp
|
||||||
- chmod (mostly done, just needs verbosity options)
|
|
||||||
- chown
|
- chown
|
||||||
- copy
|
- copy
|
||||||
- cp (not much done)
|
- cp (not much done)
|
||||||
|
|
|
@ -9,8 +9,6 @@
|
||||||
* file that was distributed with this source code.
|
* file that was distributed with this source code.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#![allow(unused_variables)] // only necessary while the TODOs still exist
|
|
||||||
|
|
||||||
extern crate aho_corasick;
|
extern crate aho_corasick;
|
||||||
extern crate getopts;
|
extern crate getopts;
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
|
@ -125,7 +123,7 @@ fn chmod(files: Vec<String>, changes: bool, quiet: bool, verbose: bool, preserve
|
||||||
Some(s) => Some(s.to_string()),
|
Some(s) => Some(s.to_string()),
|
||||||
None => None,
|
None => None,
|
||||||
},
|
},
|
||||||
Err(e) => None,
|
Err(_) => None,
|
||||||
}).collect(),
|
}).collect(),
|
||||||
changes, quiet, verbose, preserve_root, recursive, fmode, cmode).and(r);
|
changes, quiet, verbose, preserve_root, recursive, fmode, cmode).and(r);
|
||||||
r = chmod_file(&file, filename, changes, quiet, verbose, fmode, cmode).and(r);
|
r = chmod_file(&file, filename, changes, quiet, verbose, fmode, cmode).and(r);
|
||||||
|
@ -157,25 +155,20 @@ fn chmod_file(file: &Path, name: &str, changes: bool, quiet: bool, verbose: bool
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
fn chmod_file(file: &Path, name: &str, changes: bool, quiet: bool, verbose: bool, fmode: Option<libc::mode_t>, cmode: Option<&String>) -> Result<(), i32> {
|
fn chmod_file(file: &Path, name: &str, changes: bool, quiet: bool, verbose: bool, fmode: Option<libc::mode_t>, cmode: Option<&String>) -> Result<(), i32> {
|
||||||
let path = CString::new(name).unwrap_or_else(|e| panic!("{}", e));
|
let path = CString::new(name).unwrap_or_else(|e| panic!("{}", e));
|
||||||
match fmode {
|
|
||||||
Some(mode) => {
|
|
||||||
if unsafe { libc::chmod(path.as_ptr(), mode) } == 0 {
|
|
||||||
// TODO: handle changes, quiet, and verbose
|
|
||||||
} else {
|
|
||||||
show_error!("{}", io::Error::last_os_error());
|
|
||||||
return Err(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
let mut stat: libc::stat = unsafe { mem::uninitialized() };
|
let mut stat: libc::stat = unsafe { mem::uninitialized() };
|
||||||
let statres = unsafe { libc::stat(path.as_ptr(), &mut stat as *mut libc::stat) };
|
let statres = unsafe { libc::stat(path.as_ptr(), &mut stat as *mut libc::stat) };
|
||||||
let mut fperm =
|
let mut fperm =
|
||||||
if statres == 0 {
|
if statres == 0 {
|
||||||
stat.st_mode
|
stat.st_mode & 0o7777
|
||||||
} else {
|
} else {
|
||||||
|
if !quiet {
|
||||||
show_error!("{}", io::Error::last_os_error());
|
show_error!("{}", io::Error::last_os_error());
|
||||||
|
}
|
||||||
return Err(1);
|
return Err(1);
|
||||||
};
|
};
|
||||||
|
match fmode {
|
||||||
|
Some(mode) => try!(change_file(fperm, mode, file, &path, verbose, changes, quiet)),
|
||||||
|
None => {
|
||||||
for mode in cmode.unwrap().split(',') { // cmode is guaranteed to be Some in this case
|
for mode in cmode.unwrap().split(',') { // cmode is guaranteed to be Some in this case
|
||||||
let arr: &[char] = &['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
|
let arr: &[char] = &['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
|
||||||
let result =
|
let result =
|
||||||
|
@ -185,21 +178,20 @@ fn chmod_file(file: &Path, name: &str, changes: bool, quiet: bool, verbose: bool
|
||||||
parse_symbolic(fperm, mode, file)
|
parse_symbolic(fperm, mode, file)
|
||||||
};
|
};
|
||||||
match result {
|
match result {
|
||||||
Ok(m) => fperm = m,
|
Ok(mode) => {
|
||||||
Err(f) => {
|
try!(change_file(fperm, mode, file, &path, verbose, changes, quiet));
|
||||||
show_error!("{}", f);
|
fperm = mode;
|
||||||
return Err(1)
|
}
|
||||||
|
Err(f) => {
|
||||||
|
if !quiet {
|
||||||
|
show_error!("{}", f);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
if unsafe { libc::chmod(path.as_ptr(), fperm) } == 0 {
|
|
||||||
// TODO: see above
|
|
||||||
} else {
|
|
||||||
show_error!("{}", io::Error::last_os_error());
|
|
||||||
return Err(1);
|
return Err(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -280,7 +272,7 @@ fn parse_op(mode: &str, default: Option<char>) -> Result<(char, usize), String>
|
||||||
fn parse_change(mode: &str, fperm: libc::mode_t, file: &Path) -> (libc::mode_t, usize) {
|
fn parse_change(mode: &str, fperm: libc::mode_t, file: &Path) -> (libc::mode_t, usize) {
|
||||||
let mut srwx = fperm & 0o7000;
|
let mut srwx = fperm & 0o7000;
|
||||||
let mut pos = 0;
|
let mut pos = 0;
|
||||||
for (i, ch) in mode.chars().enumerate() {
|
for ch in mode.chars() {
|
||||||
match ch {
|
match ch {
|
||||||
'r' => srwx |= 0o444,
|
'r' => srwx |= 0o444,
|
||||||
'w' => srwx |= 0o222,
|
'w' => srwx |= 0o222,
|
||||||
|
@ -304,3 +296,25 @@ fn parse_change(mode: &str, fperm: libc::mode_t, file: &Path) -> (libc::mode_t,
|
||||||
}
|
}
|
||||||
(srwx, pos)
|
(srwx, pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn change_file(fperm: libc::mode_t, mode: libc::mode_t, file: &Path, path: &CString, verbose: bool, changes: bool, quiet: bool) -> Result<(), i32> {
|
||||||
|
if fperm == mode {
|
||||||
|
if verbose && !changes {
|
||||||
|
show_info!("mode of \"{}\" retained as {:o}", file.display(), fperm);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
} else if unsafe { libc::chmod(path.as_ptr(), mode) } == 0 {
|
||||||
|
if verbose || changes {
|
||||||
|
show_info!("mode of \"{}\" changed from {:o} to {:o}", file.display(), fperm, mode);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
if !quiet {
|
||||||
|
show_error!("{}", io::Error::last_os_error());
|
||||||
|
}
|
||||||
|
if verbose {
|
||||||
|
show_info!("failed to change mode of file \"{}\" from {:o} to {:o}", file.display(), fperm, mode);
|
||||||
|
}
|
||||||
|
return Err(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue