From 0819eeb75db26deff1beb443eb150318d50bd202 Mon Sep 17 00:00:00 2001 From: DTB Date: Thu, 18 Jul 2024 19:11:22 -0600 Subject: [PATCH] fileis(1): scrap libfileis(3), work on rewriting scrut(1) in Rust --- Makefile | 17 ++++------ src/fileis.rs | 80 ++++++++++++++++++++++++++++++++++++++++++++++ src/libfileis.c | 27 ---------------- src/scrut.c | 84 ------------------------------------------------- 4 files changed, 86 insertions(+), 122 deletions(-) create mode 100644 src/fileis.rs delete mode 100644 src/libfileis.c delete mode 100644 src/scrut.c diff --git a/Makefile b/Makefile index 69df551..e354c31 100644 --- a/Makefile +++ b/Makefile @@ -32,7 +32,7 @@ RUSTLIBS = --extern getopt=build/o/libgetopt.rlib \ CFLAGS += -I$(SYSEXITS) -Iinclude .PHONY: all -all: dj false fop hru intcmp mm npc rpn scrut str strcmp swab true +all: dj false fileis fop hru intcmp mm npc rpn scrut str strcmp swab true # keep build/include until bindgen(1) has stdin support # https://github.com/rust-lang/rust-bindgen/issues/2703 @@ -87,11 +87,6 @@ build/o/libsysexits.rlib: build/include/sysexits.h build/include/sysexits.h: build $(SYSEXITS)sysexits.h printf '\043define EXIT_FAILURE 1\n' | cat - $(SYSEXITS)sysexits.h > $@ -.PHONY: libfileis -libfileis: build/o/libfileis.o -build/o/libfileis.o: build src/libfileis.c - $(CC) $(CFLAGS) -c -o $@ src/libfileis.c - .PHONY: dj dj: build/bin/dj build/bin/dj: src/dj.c build @@ -102,6 +97,11 @@ false: build/bin/false build/bin/false: src/false.c build $(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 fop: build/bin/fop build/bin/fop: src/fop.rs build rustlibs @@ -132,11 +132,6 @@ rpn: build/bin/rpn build/bin/rpn: src/rpn.rs build rustlibs $(RUSTC) $(RUSTFLAGS) $(RUSTLIBS) -o $@ src/rpn.rs -.PHONY: scrut -scrut: build/bin/scrut -build/bin/scrut: src/scrut.c build libfileis - $(CC) $(CFLAGS) -o $@ src/scrut.c build/o/libfileis.o - .PHONY: str str: build/bin/str build/bin/str: src/str.c build diff --git a/src/fileis.rs b/src/fileis.rs new file mode 100644 index 0000000..70f62f6 --- /dev/null +++ b/src/fileis.rs @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2024 DTB + * 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, + process::ExitCode, +}; + +extern crate getopt; +use getopt::GetOpt; + +extern crate sysexits; +use sysexits::EX_USAGE; + +fn usage(s: &str) -> ExitCode { + eprintln!("Usage: {} [-bcdefgkprsuwxLS] file...", s); + ExitCode::from(EX_USAGE as u8) +} + +fn main() -> ExitCode { + let argv = args().collect::>(); + + let mut sel: String; // 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); } + else { return usage(&argv[0]); } + + optind = opt.ind(); + } + + if optind == argv.len() { return usage(&argv[0]); } + + for arg in argv.iter().skip(optind) { + } + +// 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; + + ExitCode::SUCCESS +} diff --git a/src/libfileis.c b/src/libfileis.c deleted file mode 100644 index 09a16b4..0000000 --- a/src/libfileis.c +++ /dev/null @@ -1,27 +0,0 @@ -#include /* NULL */ -#include /* lstat(3), stat struct, S_ISBLK, S_ISCHR, S_ISDIR, - * S_ISFIFO, S_ISGID, S_ISREG, S_ISLNK, S_ISSOCK, - * S_ISUID, S_ISVTX */ -static char *ofn = NULL; -static struct stat s; - -int -fileis_exists(char *fn){ - if (fn == NULL || fn == ofn) { return ofn != NULL; } - if (lstat(fn, &s) == -1) { return 0; } - ofn = fn; return 1; -} - -int fileis_block(char *fn) { return fileis_exists(fn) && S_ISBLK(s.st_mode); } -int fileis_char(char *fn) { return fileis_exists(fn) && S_ISCHR(s.st_mode); } -int fileis_dir(char *fn) { return fileis_exists(fn) && S_ISDIR(s.st_mode); } -/* fileis_exec(char *fn) { return fileis_exists(fn) && } */ -int fileis_fifo(char *fn) { return fileis_exists(fn) && S_ISFIFO(s.st_mode); } -int fileis_setgid(char *fn) { return fileis_exists(fn) && (s.st_mode & S_ISGID); } -int fileis_link(char *fn) { return fileis_exists(fn) && S_ISLNK(s.st_mode); } -/* fileis_read(char *fn) { return fileis_exists(fn) && } */ -int fileis_regular(char *fn){ return fileis_exists(fn) && S_ISREG(s.st_mode); } -int fileis_socket(char *fn) { return fileis_exists(fn) && S_ISSOCK(s.st_mode); } -int fileis_setuid(char *fn) { return fileis_exists(fn) && (s.st_mode & S_ISUID); } -int fileis_vtx(char *fn) { return fileis_exists(fn) && (s.st_mode & S_ISVTX); } -/* fileis_write(char *fn) { return fileis_exists(fn) && } */ diff --git a/src/scrut.c b/src/scrut.c deleted file mode 100644 index 139d83e..0000000 --- a/src/scrut.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2023–2024 DTB - * Copyright (c) 2024 Emma Tebibyte - * 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/. - */ - -#include /* assert(3) */ -#include /* fprintf(3), stderr, NULL */ -#include /* EXIT_FAILURE, EXIT_SUCCESS */ -#include /* memset(3), strchr(3) */ -#include /* EX_USAGE */ -#include /* access(3), getopt(3), R_OK, W_OK, X_OK */ -#include - -char *program_name = "scrut"; -static char opts[] = "bcdefgkprsuwxLS"; - -static int usage(char *s){ - fprintf(stderr, "Usage: %s [-%s] file...\n", s, opts); - return EX_USAGE; -} - -int main(int argc, char *argv[]){ - char sel[(sizeof opts) / (sizeof *opts)]; - - if (argc > 0) { program_name = argv[0]; } - if (argc < 2) { return usage(program_name); } - - memset(sel, '\0', sizeof sel); - - { - int c; - char *p = sel; - - while ((c = getopt(argc, argv, opts)) != -1) { - if ((strchr(opts, c)) == NULL) { return usage(program_name); } - else if ((strchr(sel, c)) == NULL) { *p++ = c; } - - assert(p - sel < (sizeof opts) / (sizeof *opts)); - } - } - - if (optind == argc) { return usage(program_name); } - - argv += optind; - - 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; -}