mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-27 11:07:44 +00:00
Merge pull request #3853 from stefins/rm-write-protected
rm: added write-protected check for files
This commit is contained in:
commit
282774a3ef
2 changed files with 63 additions and 2 deletions
|
@ -14,6 +14,8 @@ use clap::{crate_version, Arg, Command};
|
||||||
use remove_dir_all::remove_dir_all;
|
use remove_dir_all::remove_dir_all;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::ErrorKind;
|
||||||
use std::io::{stderr, stdin, BufRead, Write};
|
use std::io::{stderr, stdin, BufRead, Write};
|
||||||
use std::ops::BitOr;
|
use std::ops::BitOr;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
@ -27,6 +29,7 @@ enum InteractiveMode {
|
||||||
Never,
|
Never,
|
||||||
Once,
|
Once,
|
||||||
Always,
|
Always,
|
||||||
|
PromptProtected,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Options {
|
struct Options {
|
||||||
|
@ -112,7 +115,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
InteractiveMode::Never
|
InteractiveMode::PromptProtected
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
one_fs: matches.contains_id(OPT_ONE_FILE_SYSTEM),
|
one_fs: matches.contains_id(OPT_ONE_FILE_SYSTEM),
|
||||||
|
@ -384,7 +387,7 @@ fn remove_file(path: &Path, options: &Options) -> bool {
|
||||||
} else {
|
} else {
|
||||||
true
|
true
|
||||||
};
|
};
|
||||||
if response {
|
if response && prompt_write_protected(path, false, options) {
|
||||||
match fs::remove_file(path) {
|
match fs::remove_file(path) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
if options.verbose {
|
if options.verbose {
|
||||||
|
@ -406,6 +409,34 @@ fn remove_file(path: &Path, options: &Options) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn prompt_write_protected(path: &Path, is_dir: bool, options: &Options) -> bool {
|
||||||
|
if options.interactive == InteractiveMode::Never {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
match File::open(path) {
|
||||||
|
Ok(_) => true,
|
||||||
|
Err(err) => {
|
||||||
|
if err.kind() == ErrorKind::PermissionDenied {
|
||||||
|
if is_dir {
|
||||||
|
prompt(&(format!("rm: remove write-protected directory {}? ", path.quote())))
|
||||||
|
} else {
|
||||||
|
if fs::metadata(path).unwrap().len() == 0 {
|
||||||
|
return prompt(
|
||||||
|
&(format!(
|
||||||
|
"rm: remove write-protected regular empty file {}? ",
|
||||||
|
path.quote()
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
prompt(&(format!("rm: remove write-protected regular file {}? ", path.quote())))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn prompt_file(path: &Path, is_dir: bool) -> bool {
|
fn prompt_file(path: &Path, is_dir: bool) -> bool {
|
||||||
if is_dir {
|
if is_dir {
|
||||||
prompt(&(format!("rm: remove directory {}? ", path.quote())))
|
prompt(&(format!("rm: remove directory {}? ", path.quote())))
|
||||||
|
|
|
@ -363,3 +363,33 @@ fn test_rm_directory_rights_rm1() {
|
||||||
assert!(!at.dir_exists("b/c"));
|
assert!(!at.dir_exists("b/c"));
|
||||||
assert!(!at.dir_exists("b/d"));
|
assert!(!at.dir_exists("b/d"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "chmod")]
|
||||||
|
#[test]
|
||||||
|
fn test_prompt_write_protected_yes() {
|
||||||
|
let scene = TestScenario::new(util_name!());
|
||||||
|
let at = &scene.fixtures;
|
||||||
|
let file_1 = "test_rm_prompt_write_protected_1";
|
||||||
|
|
||||||
|
at.touch(file_1);
|
||||||
|
|
||||||
|
scene.ccmd("chmod").arg("0").arg(file_1).succeeds();
|
||||||
|
|
||||||
|
scene.ucmd().arg(file_1).pipe_in("y").succeeds();
|
||||||
|
assert!(!at.file_exists(file_1));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "chmod")]
|
||||||
|
#[test]
|
||||||
|
fn test_prompt_write_protected_no() {
|
||||||
|
let scene = TestScenario::new(util_name!());
|
||||||
|
let at = &scene.fixtures;
|
||||||
|
let file_2 = "test_rm_prompt_write_protected_2";
|
||||||
|
|
||||||
|
at.touch(file_2);
|
||||||
|
|
||||||
|
scene.ccmd("chmod").arg("0").arg(file_2).succeeds();
|
||||||
|
|
||||||
|
scene.ucmd().arg(file_2).pipe_in("n").succeeds();
|
||||||
|
assert!(at.file_exists(file_2));
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue