fileis(1): feature parity with C scrut(1)

This commit is contained in:
dtb 2024-07-18 20:43:39 -06:00
parent 0819eeb75d
commit 02b5edae05
Signed by: trinity
GPG Key ID: 34C0543BBB6AF81B

View File

@ -19,6 +19,7 @@
use std::{
env::args,
fs::metadata,
os::unix::fs::{ FileTypeExt, MetadataExt },
process::ExitCode,
};
@ -36,11 +37,11 @@ fn usage(s: &str) -> ExitCode {
fn main() -> ExitCode {
let argv = args().collect::<Vec<String>>();
let mut sel: String; // selected options
let mut sel = String::from(""); // selected options
let mut optind: usize = 1; // argv[0]
while let Some(opt) = argv.getopt("bcdefgkprsuwxLS") {
if let Ok(optchr) = opt.opt() { sel.push(optchr); }
if let Ok(optchr) = opt.opt() { sel.push_str(optchr); }
else { return usage(&argv[0]); }
optind = opt.ind();
@ -49,32 +50,38 @@ fn main() -> ExitCode {
if optind == argv.len() { return usage(&argv[0]); }
for arg in argv.iter().skip(optind) {
}
let fmeta; // file metadata
let fmode; // file mode; see chmod(1p)
let ftype; // file type
// do{
// if (!fileis_exists(*argv))
// return EXIT_FAILURE;
//
// for (size_t i = 0; sel[i] != '\0'; ++i) {
// if ((sel[i] == 'b' && !fileis_block(*argv))
// || (sel[i] == 'c' && !fileis_char(*argv))
// || (sel[i] == 'd' && !fileis_dir(*argv))
// || (sel[i] != 'e')
// || (sel[i] == 'f' && !fileis_regular(*argv))
// || (sel[i] == 'g' && !fileis_setgid(*argv))
// || (sel[i] == 'k' && !fileis_vtx(*argv))
// || (sel[i] == 'p' && !fileis_fifo(*argv))
// || (sel[i] == 'r' && access(*argv, R_OK) != 0)
// || (sel[i] == 'u' && !fileis_setuid(*argv))
// || (sel[i] == 'w' && access(*argv, W_OK) != 0)
// || (sel[i] == 'x' && access(*argv, X_OK) != 0)
// || (sel[i] == 'L' && !fileis_link(*argv))
// || (sel[i] == 'S' && !fileis_socket(*argv))
// ) { return EXIT_FAILURE; }
// }
// } while (*++argv != NULL);
//
// return EXIT_SUCCESS;
match metadata(arg) {
Ok(m) => fmeta = m,
_ => { return ExitCode::FAILURE; } // no perms or nonexistent
}
fmode = fmeta.mode();
ftype = fmeta.file_type();
for selection in sel.chars() { // run all selected tests
match selection {
'b' if ftype.is_block_device() => (),
'c' if ftype.is_char_device() => (),
'e' => (), // exists or metadata would have errored
'd' if fmeta.is_dir() => (),
'f' if fmeta.is_file() => (),
'g' if fmode & 0o2000 /* S_ISGID */ != 0 => (), // setgid
'k' if fmode & 0o1000 /* S_ISVTX */ != 0 => (), // setvtx
'p' if ftype.is_fifo() => (),
'r' if fmode & 0o0400 /* S_IRUSR */ != 0 => (), // read access
'u' if fmode & 0o4000 /* S_ISUID */ != 0 => (), // setuid
'w' if fmode & 0o0200 /* S_IWUSR */ != 0 => (), // write access
'x' if fmode & 0o0100 /* S_IXUSR */ != 0 => (), // exec access
'L' if fmeta.is_symlink() => (),
'S' if ftype.is_socket() => (),
_ => { return ExitCode::FAILURE; }
}
}
}
ExitCode::SUCCESS
}