# HG changeset patch # User Paul Boddie # Date 1704997529 -3600 # Node ID e78da10df4b81f717b490a05101207cc7f56ad03 # Parent 30ec30848a3909f8f4148fc402bd48f62b80d42f Added a stdin mode for the fsaccess tool. diff -r 30ec30848a39 -r e78da10df4b8 fsaccess/fsaccess.c --- a/fsaccess/fsaccess.c Thu Jan 11 19:24:44 2024 +0100 +++ b/fsaccess/fsaccess.c Thu Jan 11 19:25:29 2024 +0100 @@ -1,7 +1,7 @@ /* * Access a filesystem. * - * Copyright (C) 2019, 2022 Paul Boddie + * Copyright (C) 2019, 2022, 2024 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -50,7 +50,7 @@ \n\ Script operations:\n\ \n\ - script Read operations from a script file\n\ + script Read operations from a script file (or stdin)\n\ "; /* Operations exposed by the program. */ diff -r 30ec30848a39 -r e78da10df4b8 fsaccess/input.c --- a/fsaccess/input.c Thu Jan 11 19:24:44 2024 +0100 +++ b/fsaccess/input.c Thu Jan 11 19:25:29 2024 +0100 @@ -1,7 +1,7 @@ /* * Elementary input utilities. * - * Copyright (C) 2022 Paul Boddie + * Copyright (C) 2022, 2024 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -19,74 +19,28 @@ * Boston, MA 02110-1301, USA */ +#include #include #include "input.h" -/* Read a line from a file into the given buffer. */ - -char *read_line(FILE *fp, struct read_line_state *state) -{ - size_t nread; - - do - { - do - { - /* Search for a newline character in any available text. */ +/* Read a line from a file into the given buffer, removing any newline. */ - if (state->end > state->start) - { - state->eolp = strchr(state->start, '\n'); - - if (state->eolp != NULL) - { - *(state->eolp) = '\0'; - return state->eolp; - } - } - - /* Obtain more text if necessary. */ - - nread = fread(state->end, sizeof(char), state->remaining, fp); - - /* Handle end of file condition. */ +char *read_line(FILE *fp, char *buffer, size_t bufsize) +{ + char *last; - if (!nread) - { - if (state->end > state->start) - return state->end; - else - return NULL; - } + if (fgets(buffer, bufsize, fp) == NULL) + return NULL; - /* Zero-terminate the string for searching. */ - - *(state->end + nread) = '\0'; - - /* Advance the end of string and subtract remaining space. */ + last = buffer + strlen(buffer) - 1; - state->end += nread; - state->remaining -= nread; - } - while (state->remaining); - - /* Copy the remaining text to the start of the buffer. */ + if ((last >= buffer) && (*last == '\n')) + *last = '\0'; - if (state->start > state->buffer) - { - strcpy(state->buffer, state->start); - - state->end -= (state->start - state->buffer); - state->start = state->buffer; - state->remaining = state->buffer_size - 1 - (state->end - state->buffer); - } - } - while (state->remaining); - - return NULL; + return buffer; } /* Parse the text in the given region, returning details of arguments. */ diff -r 30ec30848a39 -r e78da10df4b8 fsaccess/input.h --- a/fsaccess/input.h Thu Jan 11 19:24:44 2024 +0100 +++ b/fsaccess/input.h Thu Jan 11 19:25:29 2024 +0100 @@ -1,7 +1,7 @@ /* * Elementary input utilities. * - * Copyright (C) 2022 Paul Boddie + * Copyright (C) 2022, 2024 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -23,16 +23,10 @@ #include -struct read_line_state -{ - char *buffer, *start, *end, *eolp; - size_t buffer_size, remaining; -}; - void parse_line(char *start, char *end, int *num_args, char *args[], const int max_args); -char *read_line(FILE *fp, struct read_line_state *state); +char *read_line(FILE *fp, char *buffer, size_t bufsize); /* vim: tabstop=4 expandtab shiftwidth=4 */ diff -r 30ec30848a39 -r e78da10df4b8 fsaccess/op_list_objects.c --- a/fsaccess/op_list_objects.c Thu Jan 11 19:24:44 2024 +0100 +++ b/fsaccess/op_list_objects.c Thu Jan 11 19:25:29 2024 +0100 @@ -107,28 +107,42 @@ return 0; } +/* List an object in the filesystem image. */ + +static int list_object(const char *path) +{ + /* Emit each object's name. */ + + puts(path); + + /* List individual files or directories. */ + + if (_list_object(path)) + { + fprintf(stderr, "Failed to list object: %s\n", path); + return 1; + } + + return 0; +} + /* List objects in the filesystem image. */ int list_objects(int argc, char *argv[]) { int i; - char *path; + + /* List the top level without any argument. */ + + if (!argc) + return list_object(""); + + /* Otherwise, list all specified objects. */ for (i = 0; i < argc; i++) { - path = argv[i]; - - /* Emit each object. */ - - puts(path); - - /* List individual files or directories. */ - - if (_list_object(path)) - { - fprintf(stderr, "Failed to list object: %s\n", path); + if (list_object(argv[i])) return 1; - } } return 0; diff -r 30ec30848a39 -r e78da10df4b8 fsaccess/op_script.c --- a/fsaccess/op_script.c Thu Jan 11 19:24:44 2024 +0100 +++ b/fsaccess/op_script.c Thu Jan 11 19:25:29 2024 +0100 @@ -1,7 +1,7 @@ /* * Run a script accessing a filesystem. * - * Copyright (C) 2022 Paul Boddie + * Copyright (C) 2022, 2024 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -43,38 +43,51 @@ { FILE *fp; char buffer[BUFSIZE]; - struct read_line_state state; enum op_results op_result; int num_args; char *args[MAX_ARGS]; - int i; + int i, use_stdin; for (i = 0; i < argc; i++) { - fp = fopen(argv[i], "r"); + /* Test for standard input as a special filename. */ + + use_stdin = !strcmp(argv[i], "-"); + + if (use_stdin) + fp = stdin; + else + fp = fopen(argv[i], "r"); + + while (1) + { + /* Show a prompt if employing standard input. */ - state.buffer = buffer; - state.start = buffer; - state.end = buffer; - state.buffer_size = BUFSIZE; - state.remaining = BUFSIZE - 1; + if (use_stdin) + printf("> "); + + /* Read and parse the input line, running any specified command. */ - while (read_line(fp, &state) != NULL) - { - parse_line(state.start, state.eolp, &num_args, args, MAX_ARGS); + if (read_line(fp, buffer, BUFSIZE) == NULL) + break; - if (num_args > 1) + parse_line(buffer, buffer + strlen(buffer), &num_args, args, MAX_ARGS); + + /* Permit commands with and without arguments. */ + + if (num_args >= 1) { op_result = run_operation(args[0], num_args - 1, &args[1]); - if (handle_op_result(args[0], op_result)) + if (handle_op_result(args[0], op_result) && !use_stdin) return 1; } - - state.start = state.eolp + 1; } - fclose(fp); + /* Close normal files. */ + + if (!use_stdin) + fclose(fp); } return 0;