# HG changeset patch # User Paul Boddie # Date 1646693688 -3600 # Node ID 554479097a5b86fe5b3faafc3cf1a3f6f8bfd0a5 # Parent c331ad9ca91f95d59226dcb8ce1a5ed571e86a8d Added fsaccess: an equivalent program to e2access. diff -r c331ad9ca91f -r 554479097a5b conf/dstest_fsaccess.cfg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/conf/dstest_fsaccess.cfg Mon Mar 07 23:54:48 2022 +0100 @@ -0,0 +1,51 @@ +-- vim:set ft=lua: + +local L4 = require("L4"); + +local l = L4.default_loader; + +local pipe_server = l:new_channel(); + +l:startv({ + caps = { + server = pipe_server:svr(), + }, + log = { "pipes", "r" }, + }, + "rom/dstest_pipe_server", "10"); + +local block_server = l:new_channel(); + +l:startv({ + caps = { + server = block_server:svr(), + }, + log = { "blocksvr", "r" }, + }, + "rom/dstest_block_server", "10"); + +local ext2svr = l:new_channel(); + +l:startv({ + caps = { + blocksvr = block_server, + pipes = pipe_server, + ext2svr = ext2svr:svr(), + }, + log = { "ext2svr", "y" }, + }, + "rom/dstest_ext2_server", "blocksvr", "rom/e2test.fs", "10", "ext2svr"); + +-- Obtain user filesystems with umask 0022 (18). + +local open_for_user = 6; +local ext2svr_paulb = L4.cast(L4.Proto.Factory, ext2svr):create(open_for_user, 1000, 1000, 18); + +l:startv({ + caps = { + server = ext2svr_paulb, + }, + log = { "client", "g" }, + }, + -- program, directory to read + "rom/dstest_fsaccess", "ls", "home/paulb/many"); diff -r c331ad9ca91f -r 554479097a5b conf/dstest_fsaccess.list --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/conf/dstest_fsaccess.list Mon Mar 07 23:54:48 2022 +0100 @@ -0,0 +1,28 @@ +entry dstest_fsaccess +roottask moe rom/dstest_fsaccess.cfg +module dstest_fsaccess.cfg +module e2test.fs +module l4re +module ned +module dstest_fsaccess +module dstest_ext2_server +module dstest_block_server +module dstest_pipe_server +module lib4re-c.so +module lib4re-c-util.so +module lib4re.so +module lib4re-util.so +module libc_be_l4refile.so +module libc_be_l4re.so +module libc_be_socket_noop.so +module libc_support_misc.so +module libdl.so +module libipc.so +module libl4sys-direct.so +module libl4sys.so +module libl4util.so +module libld-l4.so +module libpthread.so +module libstdc++.so +module libsupc++.so +module libuc_c.so diff -r c331ad9ca91f -r 554479097a5b fsaccess/Control --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fsaccess/Control Mon Mar 07 23:54:48 2022 +0100 @@ -0,0 +1,3 @@ +requires: libc libipc libfsclient libmem libext2fs libext2fs_blockserver libe2access_blockserver +provides: fsaccess +maintainer: paul@boddie.org.uk diff -r c331ad9ca91f -r 554479097a5b fsaccess/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fsaccess/Makefile Mon Mar 07 23:54:48 2022 +0100 @@ -0,0 +1,12 @@ +PKGDIR ?= . +L4DIR ?= $(PKGDIR)/../../.. + +TARGET = dstest_fsaccess + +MODE = static + +SRC_C = fsaccess.c ops.c op_list_objects.c + +REQUIRES_LIBS = l4re_c-util libfsclient libmem libipc libsystypes libe2access_blockserver + +include $(L4DIR)/mk/prog.mk diff -r c331ad9ca91f -r 554479097a5b fsaccess/fsaccess.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fsaccess/fsaccess.c Mon Mar 07 23:54:48 2022 +0100 @@ -0,0 +1,104 @@ +/* + * Access a filesystem. + * + * 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 "ops.h" + + + +/* Help message. */ + +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\ +\n\ +Transfer operations:\n\ +\n\ + copy-in Copy files into a directory within the image\n\ + copy-out Copy files from the image into a directory\n\ +\n\ +Image operations:\n\ +\n\ + ls List files and directories within the image\n\ + mkdir Make directories within the image\n\ + rm Remove non-directory objects from the image\n\ + rmdir Remove directories from the image\n\ + stat Show statistics for files and directories\n\ +\n\ +Script operations:\n\ +\n\ + script Read operations from a script file\n\ +"; + +/* Operations exposed by the program. */ + +struct operation operations[] = { +#if 0 + {"copy-in", copy_in}, + {"copy-out", copy_out}, +#endif + {"ls", list_objects}, +#if 0 + {"mkdir", make_dirs}, + {"rm", remove_non_dirs}, + {"rmdir", remove_dirs}, + {"script", run_script}, + {"stat", stat_objects}, +#endif + {NULL, NULL}, + }; + +/* Main program. */ + +int main(int argc, char *argv[]) +{ + /* Program argument details. */ + + char **args; + int num_args; + enum op_results op_result; + + args = &argv[1]; + num_args = argc - 1; + + if (num_args < 2) + { + fprintf(stderr, help_text, argv[0]); + return 1; + } + + /* Perform the requested operation. */ + + op_result = run_operation(args[0], num_args - 1, &args[1]); + return handle_op_result(args[0], op_result); +} + +/* vim: tabstop=4 expandtab shiftwidth=4 +*/ diff -r c331ad9ca91f -r 554479097a5b fsaccess/op_list_objects.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fsaccess/op_list_objects.c Mon Mar 07 23:54:48 2022 +0100 @@ -0,0 +1,133 @@ +/* + * List filesystem objects 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 /* get_permission_string */ +#include +#include + +#include "ops.h" + + + +/* Show object details. */ + +static void _show_object(const char *basename, struct stat *st) +{ + printf("%s%s %5d %5d %6ld %6ld %s\n", + S_ISDIR(st->st_mode) ? "d" : "-", + get_permission_string(st->st_mode), + st->st_uid, + st->st_gid, + st->st_size, + st->st_nlink, + basename); +} + +/* Show an object in a directory. */ + +static int _show_dirent(const char *dirname, struct dirent *dirent) +{ + struct stat st; + char path[strlen(dirname) + 1 + strlen(dirent->d_name) + 1]; + + sprintf(path, "%s/%s", dirname, dirent->d_name); + + if (client_stat(path, &st)) + return 1; + + _show_object(dirent->d_name, &st); + + return 0; +} + +/* List a directory or file. */ + +static int _list_object(const char *path) +{ + struct stat st; + file_t *reader; + struct dirent *dirent; + + if (client_stat(path, &st)) + return 1; + + if (S_ISDIR(st.st_mode)) + { + reader = client_opendir(path); + + if (reader == NULL) + return 1; + + /* Show the directory entries. */ + + while ((dirent = client_readdir(reader)) != NULL) + { + if (_show_dirent(path, dirent)) + { + free(dirent); + return 1; + } + + free(dirent); + } + } + else + _show_object(path_basename(path), &st); + + return 0; +} + +/* List objects in the filesystem image. */ + +int list_objects(int argc, char *argv[]) +{ + int i; + char *path; + + 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); + return 1; + } + } + + return 0; +} + +/* vim: tabstop=4 expandtab shiftwidth=4 +*/ diff -r c331ad9ca91f -r 554479097a5b fsaccess/ops.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fsaccess/ops.c Mon Mar 07 23:54:48 2022 +0100 @@ -0,0 +1,78 @@ +/* + * Operation invocation. + * + * 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 "ops.h" + + + +/* Operations exposed by the program. */ + +extern struct operation operations[]; + + + +/* Produce a general result condition from the invocation of an operation. */ + +int handle_op_result(const char *operation, enum op_results op_result) +{ + if (op_result == OP_UNKNOWN) + { + fprintf(stderr, "Operation not recognised: %s\n", operation); + return 1; + } + else if (op_result == OP_FAILED) + { + fprintf(stderr, "Operation failed: %s\n", operation); + return 1; + } + else + return 0; +} + +/* Invocation of operations. */ + +enum op_results run_operation(const char *operation, int argc, char *argv[]) +{ + struct operation *op; + int exitcode; + + for (op = &operations[0]; op->name != NULL; op++) + { + if (!strcmp(operation, op->name)) + { + exitcode = op->fn(argc, argv); + if (exitcode) + return OP_FAILED; + break; + } + } + + if (op->name == NULL) + return OP_UNKNOWN; + + return OP_SUCCESS; +} + +/* vim: tabstop=4 expandtab shiftwidth=4 +*/ diff -r c331ad9ca91f -r 554479097a5b fsaccess/ops.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fsaccess/ops.h Mon Mar 07 23:54:48 2022 +0100 @@ -0,0 +1,56 @@ +/* + * Operations and their invocation. + * + * 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 + +/* Invocation support. */ + +enum op_results +{ + OP_SUCCESS = 0, + OP_FAILED = 1, + OP_UNKNOWN = 2, +}; + +int handle_op_result(const char *operation, enum op_results op_result); +enum op_results run_operation(const char *operation, int argc, char *argv[]); + +/* Operations exposed by the program. */ + +typedef int (*op_sig)(int, char *[]); + +struct operation +{ + const char *name; + op_sig fn; +}; + +int copy_in(int argc, char *argv[]); +int copy_out(int argc, char *argv[]); +int list_objects(int argc, char *argv[]); +int make_dirs(int argc, char *argv[]); +int remove_dirs(int argc, char *argv[]); +int remove_non_dirs(int argc, char *argv[]); +int run_script(int argc, char *argv[]); +int stat_objects(int argc, char *argv[]); + +/* vim: tabstop=4 expandtab shiftwidth=4 +*/