Compare commits
	
		
			11 Commits
		
	
	
		
			138044e52f
			...
			941f931f8b
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 941f931f8b | |||
| f4bd4de2e4 | |||
| 6d7173e438 | |||
| 958f08bd9e | |||
| 02b5edae05 | |||
| 0819eeb75d | |||
| 0f12dcc552 | |||
| b9c4b49603 | |||
| 2c4349872c | |||
| 59fa3ed3d2 | |||
| 71655a8559 | 
							
								
								
									
										14
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								Makefile
									
									
									
									
									
								
							@ -1,4 +1,4 @@
 | 
				
			|||||||
# Copyright (c) 2023–2024 Emma Tebibyte <emma@tebibyte.media>
 | 
					# Copyright (c) 2023–2025 Emma Tebibyte <emma@tebibyte.media>
 | 
				
			||||||
# Copyright (c) 2023–2024 DTB <trinity@trinity.moe>
 | 
					# Copyright (c) 2023–2024 DTB <trinity@trinity.moe>
 | 
				
			||||||
# Copyright (c) 2023 Sasha Koshka <sashakoshka@tebibyte.media>
 | 
					# Copyright (c) 2023 Sasha Koshka <sashakoshka@tebibyte.media>
 | 
				
			||||||
# Copyright (c) 2024 Aaditya Aryal <aryalaadi123@gmail.com>
 | 
					# Copyright (c) 2024 Aaditya Aryal <aryalaadi123@gmail.com>
 | 
				
			||||||
@ -42,7 +42,7 @@ BIN = build/bin
 | 
				
			|||||||
default: all test
 | 
					default: all test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.PHONY: all
 | 
					.PHONY: all
 | 
				
			||||||
all: dj false fop hru intcmp mm npc peek rpn scrut str strcmp swab true
 | 
					all: dj false fileis fop hru intcmp mm npc peek rpn str strcmp swab true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# keep build/include until bindgen(1) has stdin support
 | 
					# keep build/include until bindgen(1) has stdin support
 | 
				
			||||||
# https://github.com/rust-lang/rust-bindgen/issues/2703
 | 
					# https://github.com/rust-lang/rust-bindgen/issues/2703
 | 
				
			||||||
@ -112,6 +112,11 @@ false: build/bin/false
 | 
				
			|||||||
build/bin/false: src/false.c build
 | 
					build/bin/false: src/false.c build
 | 
				
			||||||
	$(CC) $(CFLAGS) -o $@ src/false.c
 | 
						$(CC) $(CFLAGS) -o $@ src/false.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.PHONY: fileis
 | 
				
			||||||
 | 
					fileis: build/bin/fileis
 | 
				
			||||||
 | 
					build/bin/fileis: src/fileis.rs build
 | 
				
			||||||
 | 
						$(RUSTC) $(RUSTFLAGS) $(RUSTLIBS) -o $@ src/fileis.rs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.PHONY: fop
 | 
					.PHONY: fop
 | 
				
			||||||
fop: build/bin/fop
 | 
					fop: build/bin/fop
 | 
				
			||||||
build/bin/fop: src/fop.rs build rustlibs
 | 
					build/bin/fop: src/fop.rs build rustlibs
 | 
				
			||||||
@ -147,11 +152,6 @@ rpn: build/bin/rpn
 | 
				
			|||||||
build/bin/rpn: src/rpn.rs build rustlibs
 | 
					build/bin/rpn: src/rpn.rs build rustlibs
 | 
				
			||||||
	$(RUSTC) $(RUSTFLAGS) -o $@ src/rpn.rs
 | 
						$(RUSTC) $(RUSTFLAGS) -o $@ src/rpn.rs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.PHONY: scrut
 | 
					 | 
				
			||||||
scrut: build/bin/scrut
 | 
					 | 
				
			||||||
build/bin/scrut: src/scrut.c build
 | 
					 | 
				
			||||||
	$(CC) $(CFLAGS) -o $@ src/scrut.c
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.PHONY: str
 | 
					.PHONY: str
 | 
				
			||||||
str: build/bin/str
 | 
					str: build/bin/str
 | 
				
			||||||
build/bin/str: src/str.c build
 | 
					build/bin/str: src/str.c build
 | 
				
			||||||
 | 
				
			|||||||
@ -1,15 +1,15 @@
 | 
				
			|||||||
.\" Copyright (c) 2024 DTB <trinity@trinity.moe>
 | 
					.\" Copyright (c) 2024 DTB <trinity@trinity.moe>
 | 
				
			||||||
.\" Copyright (c) 2024 Emma Tebibyte <emma@tebibyte.media>
 | 
					.\" Copyright (c) 2024–2025 Emma Tebibyte <emma@tebibyte.media>
 | 
				
			||||||
.\"
 | 
					.\"
 | 
				
			||||||
.\" This work is licensed under CC BY-SA 4.0. To see a copy of this license,
 | 
					.\" This work is licensed under CC BY-SA 4.0. To see a copy of this license,
 | 
				
			||||||
.\" visit <http://creativecommons.org/licenses/by-sa/4.0/>.
 | 
					.\" visit <http://creativecommons.org/licenses/by-sa/4.0/>.
 | 
				
			||||||
.\"
 | 
					.\"
 | 
				
			||||||
.TH SCRUT 1 2024-06-06 "Harakit X.X.X"
 | 
					.TH FILEIS 1 2025-02-24 "Harakit X.X.X"
 | 
				
			||||||
.SH NAME
 | 
					.SH NAME
 | 
				
			||||||
scrut \(en scrutinize file properties
 | 
					fileis \(en scrutinize file properties
 | 
				
			||||||
.SH SYNOPSIS
 | 
					.SH SYNOPSIS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
scrut
 | 
					fileis
 | 
				
			||||||
.RB [ -LSbcdefgkprsuwx ]
 | 
					.RB [ -LSbcdefgkprsuwx ]
 | 
				
			||||||
.B file...
 | 
					.B file...
 | 
				
			||||||
.\"
 | 
					.\"
 | 
				
			||||||
@ -82,5 +82,6 @@ Copyright \(co 2024 DTB. License AGPLv3+: GNU AGPL version 3 or later
 | 
				
			|||||||
.\"
 | 
					.\"
 | 
				
			||||||
.SH SEE ALSO
 | 
					.SH SEE ALSO
 | 
				
			||||||
.BR access (3p),
 | 
					.BR access (3p),
 | 
				
			||||||
 | 
					.BR chown (1p),
 | 
				
			||||||
.BR lstat (3p),
 | 
					.BR lstat (3p),
 | 
				
			||||||
.BR test (1p)
 | 
					.BR test (1p)
 | 
				
			||||||
							
								
								
									
										91
									
								
								src/fileis.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								src/fileis.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,91 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2024 DTB <trinity@trinity.moe>
 | 
				
			||||||
 | 
					 * Copyright (c) 2024 Emma Tebibyte <emma@tebibyte.media>
 | 
				
			||||||
 | 
					 * SPDX-License-Identifier: AGPL-3.0-or-later
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software: you can redistribute it and/or modify it under
 | 
				
			||||||
 | 
					 * the terms of the GNU Affero General Public License as published by the Free
 | 
				
			||||||
 | 
					 * Software Foundation, either version 3 of the License, or (at your option) any
 | 
				
			||||||
 | 
					 * later version.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful, but WITHOUT
 | 
				
			||||||
 | 
					 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
				
			||||||
 | 
					 * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
 | 
				
			||||||
 | 
					 * details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU Affero General Public License
 | 
				
			||||||
 | 
					 * along with this program. If not, see https://www.gnu.org/licenses/.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use std::{
 | 
				
			||||||
 | 
						env::args,
 | 
				
			||||||
 | 
						fs::metadata,
 | 
				
			||||||
 | 
						os::unix::fs::{ FileTypeExt, MetadataExt },
 | 
				
			||||||
 | 
						process::ExitCode,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern crate getopt;
 | 
				
			||||||
 | 
					extern crate strerror;
 | 
				
			||||||
 | 
					extern crate sysexits;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use getopt::GetOpt;
 | 
				
			||||||
 | 
					use strerror::StrError;
 | 
				
			||||||
 | 
					use sysexits::EX_USAGE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const OPTS: &str = "bcdefgkprsuwxLS";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn usage(argv0: &str) -> ExitCode {
 | 
				
			||||||
 | 
						eprintln!("Usage: {} [-{}] file...", argv0, OPTS);
 | 
				
			||||||
 | 
						ExitCode::from(EX_USAGE)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn main() -> ExitCode {
 | 
				
			||||||
 | 
						let argv = args().collect::<Vec<_>>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						let mut sel = String::with_capacity(OPTS.len()); // selected options
 | 
				
			||||||
 | 
						let mut optind: usize = 1; // argv[0]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while let Some(opt) = argv.getopt(OPTS) {
 | 
				
			||||||
 | 
							if let Ok(optchr) = opt.opt() { sel.push_str(optchr); }
 | 
				
			||||||
 | 
							else { return usage(&argv[0]); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							optind = opt.ind();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if optind == argv.len() { return usage(&argv[0]); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for arg in argv.iter().skip(optind) {
 | 
				
			||||||
 | 
							let fmeta = match metadata(arg) {
 | 
				
			||||||
 | 
								Ok(m) => m,
 | 
				
			||||||
 | 
								Err(e) => { // no perms or nonexistent
 | 
				
			||||||
 | 
									eprintln!("{}: {}: {}", argv[0], arg, e.strerror());
 | 
				
			||||||
 | 
									return ExitCode::FAILURE;
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							let fmode = fmeta.mode();
 | 
				
			||||||
 | 
							let 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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user