# HG changeset patch # User Paul Boddie # Date 1647558847 -3600 # Node ID 600f688dc4495291b4d0bd8f32c657935a5824a8 # Parent fc8ebfa6ba5d4c3871903d210ccaaebb29c626cc Added support for mkdir and script operations in fsaccess, changing the example to use a script exercising the various supported operations. diff -r fc8ebfa6ba5d -r 600f688dc449 conf/dstest_fsaccess.cfg --- a/conf/dstest_fsaccess.cfg Wed Mar 16 22:44:46 2022 +0100 +++ b/conf/dstest_fsaccess.cfg Fri Mar 18 00:14:07 2022 +0100 @@ -47,5 +47,5 @@ }, log = { "client", "g" }, }, - -- program, directory to read - "rom/dstest_fsaccess", "ls", "home/paulb/many"); + -- program, options, operation involving a script file + "rom/dstest_fsaccess", "-m", "0022", "script", "rom/fsaccess.txt"); diff -r fc8ebfa6ba5d -r 600f688dc449 conf/dstest_fsaccess.list --- a/conf/dstest_fsaccess.list Wed Mar 16 22:44:46 2022 +0100 +++ b/conf/dstest_fsaccess.list Fri Mar 18 00:14:07 2022 +0100 @@ -2,6 +2,7 @@ roottask moe rom/dstest_fsaccess.cfg module dstest_fsaccess.cfg module e2test.fs +module fsaccess.txt module l4re module ned module dstest_fsaccess diff -r fc8ebfa6ba5d -r 600f688dc449 conf/fsaccess.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/conf/fsaccess.txt Fri Mar 18 00:14:07 2022 +0100 @@ -0,0 +1,5 @@ +ls home/paulb/many +ls home/paulb +mkdir home/paulb/newdir +ls home/paulb +ls home/paulb/newdir diff -r fc8ebfa6ba5d -r 600f688dc449 fsaccess/Makefile --- a/fsaccess/Makefile Wed Mar 16 22:44:46 2022 +0100 +++ b/fsaccess/Makefile Fri Mar 18 00:14:07 2022 +0100 @@ -5,7 +5,9 @@ MODE = static -SRC_C = fsaccess.c ops.c op_list_objects.c +SRC_C = \ + fsaccess.c input.c session.c \ + ops.c op_list_objects.c op_make_dirs.c op_script.c REQUIRES_LIBS = l4re_c-util libfsclient libmem libipc libsystypes libe2access_blockserver diff -r fc8ebfa6ba5d -r 600f688dc449 fsaccess/fsaccess.c --- a/fsaccess/fsaccess.c Wed Mar 16 22:44:46 2022 +0100 +++ b/fsaccess/fsaccess.c Fri Mar 18 00:14:07 2022 +0100 @@ -20,8 +20,10 @@ */ #include +#include #include "ops.h" +#include "session.h" @@ -30,11 +32,6 @@ char help_text[] = "\ Usage: %s [ ] ...\n\ \n\ -File ownership options:\n\ -\n\ - -g GID Set group identifier for new files\n\ - -u UID Set user identifier for new files\n\ -\n\ File permission options:\n\ \n\ -m MASK Set mode/permissions mask for new directories\n\ @@ -65,11 +62,13 @@ {"copy-out", copy_out}, #endif {"ls", list_objects}, + {"mkdir", make_dirs}, #if 0 - {"mkdir", make_dirs}, {"rm", remove_non_dirs}, {"rmdir", remove_dirs}, +#endif {"script", run_script}, +#if 0 {"stat", stat_objects}, #endif {NULL, NULL}, @@ -85,8 +84,13 @@ int num_args; enum op_results op_result; - args = &argv[1]; - num_args = argc - 1; + /* Parse program options and initialise the argument details. */ + + if (parse_options(argc, argv)) + return 1; + + args = &argv[optind]; + num_args = argc - optind; if (num_args < 2) { diff -r fc8ebfa6ba5d -r 600f688dc449 fsaccess/input.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fsaccess/input.c Fri Mar 18 00:14:07 2022 +0100 @@ -0,0 +1,118 @@ +/* + * Elementary input utilities. + * + * Copyright (C) 2022 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 + * published by the Free Software Foundation; either version 2 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA + */ + +#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. */ + + 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. */ + + if (!nread) + { + if (state->end > state->start) + return state->end; + else + return NULL; + } + + /* Zero-terminate the string for searching. */ + + *(state->end + nread) = '\0'; + + /* Advance the end of string and subtract remaining space. */ + + state->end += nread; + state->remaining -= nread; + } + while (state->remaining); + + /* Copy the remaining text to the start of the buffer. */ + + 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; +} + +/* Parse the text in the given region, returning details of arguments. */ + +void parse_line(char *start, char *end, int *num_args, char *args[], const int max_args) +{ + *num_args = 0; + + while ((start != NULL) && (start < end) && (*num_args < max_args)) + { + args[*num_args] = start; + (*num_args)++; + + /* NOTE: Only handling spaces as delimiters. */ + + start = strchr(start, ' '); + + if (start != NULL) + { + *start = '\0'; + + if (start < end) + start++; + } + } +} + +/* vim: tabstop=4 expandtab shiftwidth=4 +*/ diff -r fc8ebfa6ba5d -r 600f688dc449 fsaccess/input.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fsaccess/input.h Fri Mar 18 00:14:07 2022 +0100 @@ -0,0 +1,38 @@ +/* + * Elementary input utilities. + * + * Copyright (C) 2022 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 + * published by the Free Software Foundation; either version 2 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA + */ + +#pragma once + +#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); + +/* vim: tabstop=4 expandtab shiftwidth=4 +*/ diff -r fc8ebfa6ba5d -r 600f688dc449 fsaccess/op_make_dirs.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fsaccess/op_make_dirs.c Fri Mar 18 00:14:07 2022 +0100 @@ -0,0 +1,108 @@ +/* + * Make a directory in the filesystem using the client library. + * + * Copyright (C) 2019, 2022 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 + * published by the Free Software Foundation; either version 2 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA + */ + +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "ops.h" +#include "session.h" + + + +/* Alternative metadata set by options. */ + +extern struct metadata md; + + + +static int _make_dir(const char *path) +{ + char parent[strlen(path) + 1]; + + /* Attempt to create the directory and return if successful. */ + + long err = client_mkdir(path, 0777 & ~md.mask); + + if (!err) + return 0; + + /* Without a usable parent directory, attempt to create the parent, and then + attempt to create the directory again. */ + + if (err == -L4_ENOENT) + { + strcpy(parent, path); + path_split(parent); + + if (_make_dir(parent)) + return 1; + + return _make_dir(path); + } + + fprintf(stderr, "Could not create directory: %s\n", path); + return 1; +} + +static int _make_dirs(const char *path) +{ + struct stat st; + + /* Search for the remaining components. */ + + long err = client_stat(path, &st); + + if (!err) + { + fprintf(stderr, "Path exists: %s\n", path); + return 1; + } + + /* Try and make the directory. */ + + return _make_dir(path); +} + +/* Make directories in the filesystem. */ + +int make_dirs(int argc, char *argv[]) +{ + int i; + + /* Make each directory component in the given pathname. */ + + for (i = 0; i < argc; i++) + if (_make_dirs(argv[i])) + return 1; + + return 0; +} + +/* vim: tabstop=4 expandtab shiftwidth=4 +*/ diff -r fc8ebfa6ba5d -r 600f688dc449 fsaccess/op_script.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fsaccess/op_script.c Fri Mar 18 00:14:07 2022 +0100 @@ -0,0 +1,84 @@ +/* + * Run a script accessing a filesystem. + * + * Copyright (C) 2022 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 + * published by the Free Software Foundation; either version 2 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA + */ + +#include +#include + +#include "input.h" +#include "ops.h" + + + +/* Line buffer size. */ + +static int BUFSIZE = 4096; + +/* Maximum number of arguments in scripts. */ + +const int MAX_ARGS = 32; + + + +/* Read operations from a script file. */ + +int run_script(int argc, char *argv[]) +{ + FILE *fp; + char buffer[BUFSIZE]; + struct read_line_state state; + enum op_results op_result; + int num_args; + char *args[MAX_ARGS]; + int i; + + for (i = 0; i < argc; i++) + { + fp = fopen(argv[i], "r"); + + state.buffer = buffer; + state.start = buffer; + state.end = buffer; + state.buffer_size = BUFSIZE; + state.remaining = BUFSIZE - 1; + + while (read_line(fp, &state) != NULL) + { + parse_line(state.start, state.eolp, &num_args, args, MAX_ARGS); + + if (num_args > 1) + { + op_result = run_operation(args[0], num_args - 1, &args[1]); + + if (handle_op_result(args[0], op_result)) + return 1; + } + + state.start = state.eolp + 1; + } + + fclose(fp); + } + + return 0; +} + +/* vim: tabstop=4 expandtab shiftwidth=4 +*/ diff -r fc8ebfa6ba5d -r 600f688dc449 fsaccess/session.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fsaccess/session.c Fri Mar 18 00:14:07 2022 +0100 @@ -0,0 +1,63 @@ +/* + * Session utilities. + * + * Copyright (C) 2022 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 + * published by the Free Software Foundation; either version 2 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA + */ + +#include +#include +#include +#include + +#include "session.h" + + + +/* Alternative metadata set by options. */ + +struct metadata md; + + + +/* Parse program options. */ + +int parse_options(int argc, char *argv[]) +{ + int opt; + + md.mask = 0000; + + while ((opt = getopt(argc, argv, "m:")) != -1) + { + switch (opt) + { + case 'm': + md.mask = strtol(optarg, NULL, 0); + break; + + default: + fprintf(stderr, "Option not recognised: %s\n", argv[optind]); + return -1; + } + } + + return 0; +} + +/* vim: tabstop=4 expandtab shiftwidth=4 +*/ diff -r fc8ebfa6ba5d -r 600f688dc449 fsaccess/session.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fsaccess/session.h Fri Mar 18 00:14:07 2022 +0100 @@ -0,0 +1,36 @@ +/* + * Common session details. + * + * Copyright (C) 2022 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 + * published by the Free Software Foundation; either version 2 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA + */ + +#pragma once + +#include + +/* Alternative metadata set by options. */ + +struct metadata +{ + mode_t mask; +}; + +int parse_options(int argc, char *argv[]); + +/* vim: tabstop=4 expandtab shiftwidth=4 +*/