mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-31 21:17:46 +00:00
chmod: update for latest Rust
This commit is contained in:
parent
a5d70763bc
commit
a672f5c768
1 changed files with 29 additions and 24 deletions
|
@ -21,6 +21,8 @@ extern crate regex;
|
||||||
|
|
||||||
use std::io::fs;
|
use std::io::fs;
|
||||||
use std::io::fs::PathExtensions;
|
use std::io::fs::PathExtensions;
|
||||||
|
use std::io::IoError;
|
||||||
|
use std::mem;
|
||||||
use std::num::from_str_radix;
|
use std::num::from_str_radix;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
|
||||||
|
@ -78,9 +80,12 @@ Each MODE is of the form '[ugoa]*([-+=]([rwxXst]*|[ugo]))+|[-+=]?[0-7]+'.",
|
||||||
let preserve_root = matches.opt_present("preserve-root");
|
let preserve_root = matches.opt_present("preserve-root");
|
||||||
let recursive = matches.opt_present("recursive");
|
let recursive = matches.opt_present("recursive");
|
||||||
let fmode = matches.opt_str("reference").and_then(|fref| {
|
let fmode = matches.opt_str("reference").and_then(|fref| {
|
||||||
match native::io::file::stat(&fref.to_c_str()) {
|
let mut stat = unsafe { mem::uninitialized() };
|
||||||
Ok(stat) => Some(stat.perm),
|
let statres = unsafe { libc::stat(fref.as_slice().as_ptr() as *const i8, &mut stat as *mut libc::stat) };
|
||||||
Err(f) => crash!(1, "{}", f)
|
if statres == 0 {
|
||||||
|
Some(stat.st_mode)
|
||||||
|
} else {
|
||||||
|
crash!(1, "{}", IoError::last_error())
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let cmode =
|
let cmode =
|
||||||
|
@ -140,7 +145,7 @@ fn verify_mode(mode: &str) -> Result<(), String> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn chmod(files: Vec<String>, changes: bool, quiet: bool, verbose: bool, preserve_root: bool, recursive: bool, fmode: Option<u64>, cmode: Option<&String>) -> Result<(), int> {
|
fn chmod(files: Vec<String>, changes: bool, quiet: bool, verbose: bool, preserve_root: bool, recursive: bool, fmode: Option<u32>, cmode: Option<&String>) -> Result<(), int> {
|
||||||
let mut r = Ok(());
|
let mut r = Ok(());
|
||||||
|
|
||||||
for filename in files.iter() {
|
for filename in files.iter() {
|
||||||
|
@ -176,28 +181,29 @@ fn chmod(files: Vec<String>, changes: bool, quiet: bool, verbose: bool, preserve
|
||||||
r
|
r
|
||||||
}
|
}
|
||||||
|
|
||||||
fn chmod_file(file: &Path, name: &str, changes: bool, quiet: bool, verbose: bool, fmode: Option<u64>, cmode: Option<&String>) -> Result<(), int> {
|
fn chmod_file(file: &Path, name: &str, changes: bool, quiet: bool, verbose: bool, fmode: Option<u32>, cmode: Option<&String>) -> Result<(), int> {
|
||||||
let path = name.to_c_str();
|
let path = name.to_c_str();
|
||||||
match fmode {
|
match fmode {
|
||||||
Some(mode) => {
|
Some(mode) => {
|
||||||
match native::io::file::chmod(&path, mode as uint) {
|
if unsafe { libc::chmod(path.as_ptr(), mode) } == 0 {
|
||||||
Ok(_) => { /* TODO: handle changes, quiet, and verbose */ }
|
// TODO: handle changes, quiet, and verbose
|
||||||
Err(f) => {
|
} else {
|
||||||
show_error!("{}", f);
|
show_error!("{}", IoError::last_error());
|
||||||
return Err(1);
|
return Err(1);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// TODO: make the regex processing occur earlier (i.e. once in the main function)
|
// TODO: make the regex processing occur earlier (i.e. once in the main function)
|
||||||
static REGEXP: regex::Regex = regex!(r"^(([ugoa]*)((?:[-+=](?:[rwxXst]*|[ugo]))+))|([-+=]?[0-7]+)$");
|
static REGEXP: regex::Regex = regex!(r"^(([ugoa]*)((?:[-+=](?:[rwxXst]*|[ugo]))+))|([-+=]?[0-7]+)$");
|
||||||
let mut fperm = match native::io::file::stat(&path) {
|
let mut stat = unsafe { mem::uninitialized() };
|
||||||
Ok(stat) => stat.perm,
|
let statres = unsafe { libc::stat(path.as_ptr(), &mut stat as *mut libc::stat) };
|
||||||
Err(f) => {
|
let mut fperm =
|
||||||
show_error!("{}", f);
|
if statres == 0 {
|
||||||
|
stat.st_mode
|
||||||
|
} else {
|
||||||
|
show_error!("{}", IoError::last_error());
|
||||||
return Err(1);
|
return Err(1);
|
||||||
}
|
};
|
||||||
};
|
|
||||||
for mode in cmode.unwrap().as_slice().split(',') { // cmode is guaranteed to be Some in this case
|
for mode in cmode.unwrap().as_slice().split(',') { // cmode is guaranteed to be Some in this case
|
||||||
let cap = REGEXP.captures(mode).unwrap(); // mode was verified earlier, so this is safe
|
let cap = REGEXP.captures(mode).unwrap(); // mode was verified earlier, so this is safe
|
||||||
if cap.at(1) != "" {
|
if cap.at(1) != "" {
|
||||||
|
@ -273,7 +279,7 @@ fn chmod_file(file: &Path, name: &str, changes: bool, quiet: bool, verbose: bool
|
||||||
'+' | '-' | '=' => (ch, change.slice_from(1)),
|
'+' | '-' | '=' => (ch, change.slice_from(1)),
|
||||||
_ => ('=', change)
|
_ => ('=', change)
|
||||||
};
|
};
|
||||||
let mode = from_str_radix::<u64>(slice, 8).unwrap(); // already verified
|
let mode = from_str_radix::<u32>(slice, 8).unwrap(); // already verified
|
||||||
match action {
|
match action {
|
||||||
'+' => fperm |= mode,
|
'+' => fperm |= mode,
|
||||||
'-' => fperm &= !mode,
|
'-' => fperm &= !mode,
|
||||||
|
@ -281,12 +287,11 @@ fn chmod_file(file: &Path, name: &str, changes: bool, quiet: bool, verbose: bool
|
||||||
_ => unreachable!()
|
_ => unreachable!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
match native::io::file::chmod(&path, fperm as uint) {
|
if unsafe { libc::chmod(path.as_ptr(), fperm) } == 0 {
|
||||||
Ok(_) => { /* TODO: see above */ }
|
// TODO: see above
|
||||||
Err(f) => {
|
} else {
|
||||||
show_error!("{}", f);
|
show_error!("{}", IoError::last_error());
|
||||||
return Err(1);
|
return Err(1);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue