From 0f12dcc5524fc9e82dd661e6484fa1e2f367ea9a Mon Sep 17 00:00:00 2001 From: DTB Date: Mon, 15 Jul 2024 14:28:00 -0600 Subject: [PATCH] scrut(1): fix ugly opt parsing --- src/scrut.c | 73 +++++++++++++++++++++++++---------------------------- 1 file changed, 35 insertions(+), 38 deletions(-) diff --git a/src/scrut.c b/src/scrut.c index 06ab451..139d83e 100644 --- a/src/scrut.c +++ b/src/scrut.c @@ -17,70 +17,67 @@ * 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), F_OK, R_OK, W_OK, X_OK */ +#include /* access(3), getopt(3), R_OK, W_OK, X_OK */ #include -static char args[] = "bcdefgkprsuwxLS"; -static char ops[(sizeof args) / (sizeof *args)]; - char *program_name = "scrut"; +static char opts[] = "bcdefgkprsuwxLS"; -int usage(char *s){ - fprintf(stderr, "Usage: %s [-%s] file...\n", s, args); +static int usage(char *s){ + fprintf(stderr, "Usage: %s [-%s] file...\n", s, opts); return EX_USAGE; } int main(int argc, char *argv[]){ - int c; - size_t i; - char *p; + char sel[(sizeof opts) / (sizeof *opts)]; if (argc > 0) { program_name = argv[0]; } if (argc < 2) { return usage(program_name); } - memset(ops, '\0', sizeof ops); + memset(sel, '\0', sizeof sel); - while ((c = getopt(argc, argv, args)) != -1) - if ((p = strchr(args, c)) == NULL) { return usage(program_name); } - else { ops[p - args] = c; } + { + 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; - /* straighten out ops */ - for(i = 0, p = ops; i < (sizeof ops) / (sizeof *ops); ++i) - if(ops[i] != '\0'){ - *p = ops[i]; - if(&ops[i] != p++) - ops[i] = '\0'; - } - do{ if (!fileis_exists(*argv)) - return EXIT_FAILURE; /* doesn't exist or isn't stattable */ + return EXIT_FAILURE; - for (i = 0; ops[i] != '\0'; ++i) - if (ops[i] == 'e') - continue; - else if ((ops[i] == 'b' && !fileis_block(*argv)) - || (ops[i] == 'c' && !fileis_char(*argv)) - || (ops[i] == 'd' && !fileis_dir(*argv)) - || (ops[i] == 'f' && !fileis_regular(*argv)) - || (ops[i] == 'g' && !fileis_setgid(*argv)) - || (ops[i] == 'k' && !fileis_vtx(*argv)) - || (ops[i] == 'p' && !fileis_fifo(*argv)) - || (ops[i] == 'r' && access(*argv, R_OK) != 0) - || (ops[i] == 'u' && !fileis_setuid(*argv)) - || (ops[i] == 'w' && access(*argv, W_OK) != 0) - || (ops[i] == 'x' && access(*argv, X_OK) != 0) - || (ops[i] == 'L' && !fileis_link(*argv)) - || (ops[i] == 'S' && !fileis_socket(*argv)) + 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;