1
Fork 0
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:
Sylvestre Ledru 2022-08-29 17:03:24 +02:00 committed by GitHub
commit 282774a3ef
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 63 additions and 2 deletions

View file

@ -14,6 +14,8 @@ use clap::{crate_version, Arg, Command};
use remove_dir_all::remove_dir_all;
use std::collections::VecDeque;
use std::fs;
use std::fs::File;
use std::io::ErrorKind;
use std::io::{stderr, stdin, BufRead, Write};
use std::ops::BitOr;
use std::path::{Path, PathBuf};
@ -27,6 +29,7 @@ enum InteractiveMode {
Never,
Once,
Always,
PromptProtected,
}
struct Options {
@ -112,7 +115,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
}
}
} else {
InteractiveMode::Never
InteractiveMode::PromptProtected
}
},
one_fs: matches.contains_id(OPT_ONE_FILE_SYSTEM),
@ -384,7 +387,7 @@ fn remove_file(path: &Path, options: &Options) -> bool {
} else {
true
};
if response {
if response && prompt_write_protected(path, false, options) {
match fs::remove_file(path) {
Ok(_) => {
if options.verbose {
@ -406,6 +409,34 @@ fn remove_file(path: &Path, options: &Options) -> bool {
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 {
if is_dir {
prompt(&(format!("rm: remove directory {}? ", path.quote())))

View file

@ -363,3 +363,33 @@ fn test_rm_directory_rights_rm1() {
assert!(!at.dir_exists("b/c"));
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));
}