1.1 --- a/libe2access/host/e2access.c Mon Feb 14 00:44:19 2022 +0100
1.2 +++ b/libe2access/host/e2access.c Mon Feb 14 00:46:57 2022 +0100
1.3 @@ -93,12 +93,24 @@
1.4
1.5 /* Show directory entries when iterating. */
1.6
1.7 -static int image_list_dir_proc(struct ext2_dir_entry *dirent, int offset,
1.8 - int blocksize, char *buf, void *priv_data)
1.9 +struct _list_dir_data
1.10 +{
1.11 + ext2_filsys fs;
1.12 + char *filename;
1.13 +};
1.14 +
1.15 +static int _list_dir_proc(struct ext2_dir_entry *dirent, int offset,
1.16 + int blocksize, char *buf, void *priv_data)
1.17 {
1.18 - ext2_filsys fs = (ext2_filsys) priv_data;
1.19 + struct _list_dir_data *data = (struct _list_dir_data *) priv_data;
1.20 + ext2_filsys fs = data->fs;
1.21 struct ext2_inode inode;
1.22
1.23 + /* Select any indicated filename. */
1.24 +
1.25 + if ((data->filename != NULL) && (strcmp(dirent->name, data->filename)))
1.26 + return 0;
1.27 +
1.28 /* Obtain the inode details for metadata. */
1.29
1.30 if (ext2fs_read_inode(fs, dirent->inode, &inode))
1.31 @@ -448,22 +460,32 @@
1.32 return 0;
1.33 }
1.34
1.35 -/* List directories in the filesystem image. */
1.36 +/* List objects in the filesystem image. */
1.37
1.38 -int list_dirs(ext2_filsys fs, int argc, char *argv[])
1.39 +int list(ext2_filsys fs, int argc, char *argv[])
1.40 {
1.41 int i;
1.42 - const char *path;
1.43 + char *path;
1.44 + struct _list_dir_data data;
1.45
1.46 for (i = 0; i < argc; i++)
1.47 {
1.48 path = argv[i];
1.49
1.50 - /* List the directory contents. */
1.51 + /* Emit each object. */
1.52
1.53 puts(path);
1.54
1.55 - if (image_list_dir(fs, path, image_list_dir_proc, fs))
1.56 + /* List individual files or directories. */
1.57 +
1.58 + if (image_isfile(fs, path))
1.59 + data.filename = path_split(path);
1.60 + else
1.61 + data.filename = NULL;
1.62 +
1.63 + data.fs = fs;
1.64 +
1.65 + if (image_list_dir(fs, path, _list_dir_proc, &data))
1.66 return 1;
1.67 }
1.68
1.69 @@ -475,7 +497,6 @@
1.70 int make_dirs(ext2_filsys fs, int argc, char *argv[])
1.71 {
1.72 int i;
1.73 - char *path_end;
1.74 const char *path;
1.75 ext2_ino_t ino;
1.76
1.77 @@ -495,14 +516,59 @@
1.78 /* From the first unrecognised component, make the remaining
1.79 directories. */
1.80
1.81 - if (image_make_dirs(fs, &path, ino, 0777 & ~md.mask, 0, 0))
1.82 + if (image_make_dirs(fs, &path, ino,
1.83 + 0777 & ~md.mask,
1.84 + md.have_uid ? md.uid : 0,
1.85 + md.have_gid ? md.gid : 0))
1.86 return 1;
1.87 }
1.88
1.89 return 0;
1.90 }
1.91
1.92 -/* Help message and main program. */
1.93 +/* Remove directories from the filesystem image. */
1.94 +
1.95 +int remove_dirs(ext2_filsys fs, int argc, char *argv[])
1.96 +{
1.97 + int i;
1.98 + const char *path;
1.99 + ext2_ino_t ino;
1.100 +
1.101 + /* Remove each directory with the given pathname. */
1.102 +
1.103 + for (i = 0; i < argc; i++)
1.104 + {
1.105 + path = argv[i];
1.106 + if (!*path)
1.107 + continue;
1.108 +
1.109 + /* Ignore missing objects. */
1.110 +
1.111 + if (!image_exists(fs, path))
1.112 + continue;
1.113 +
1.114 + /* Insist on a directory. */
1.115 +
1.116 + if (!image_isdir(fs, path))
1.117 + return 1;
1.118 +
1.119 + /* Remove the directory. */
1.120 +
1.121 + if (image_remove_by_path(fs, path))
1.122 + return 1;
1.123 +
1.124 + /* Unlink the directory. */
1.125 +
1.126 + if (image_unlink_by_path(fs, path))
1.127 + return 1;
1.128 + }
1.129 +
1.130 + return 0;
1.131 +}
1.132 +
1.133 +
1.134 +
1.135 +/* Help message. */
1.136
1.137 char help_text[] = "\
1.138 Usage: %s [ <options> ] <image file> <operation> <filename>...\n\
1.139 @@ -515,8 +581,35 @@
1.140 File permission options:\n\
1.141 \n\
1.142 -m MASK Set mode/permissions mask for new directories\n\
1.143 +\n\
1.144 +Operations:\n\
1.145 +\n\
1.146 + copy-in Copy files into a directory within the image\n\
1.147 + copy-out Copy files from the image into a directory\n\
1.148 + ls List files and directories within the image\n\
1.149 + mkdir Make directories within the image\n\
1.150 + rmdir Remove directories from the image\n\
1.151 ";
1.152
1.153 +/* Operations exposed by the program. */
1.154 +
1.155 +struct operation
1.156 +{
1.157 + const char *name;
1.158 + int (*fn)(ext2_filsys, int, char *[]);
1.159 +};
1.160 +
1.161 +static struct operation operations[] = {
1.162 + {"copy-in", copy_in},
1.163 + {"copy-out", copy_out},
1.164 + {"ls", list},
1.165 + {"mkdir", make_dirs},
1.166 + {"rmdir", remove_dirs},
1.167 + {NULL, NULL},
1.168 + };
1.169 +
1.170 +/* Main program. */
1.171 +
1.172 int main(int argc, char *argv[])
1.173 {
1.174 int flags = EXT2_FLAG_RW; // | EXT2_FLAG_SOFTSUPP_FEATURES | EXT2_FLAG_64BITS;
1.175 @@ -529,6 +622,7 @@
1.176 char **args;
1.177 char *fsname, *operation, *filename;
1.178 int num_args;
1.179 + struct operation *op;
1.180
1.181 /* Parse program options and initialise the argument details. */
1.182
1.183 @@ -570,23 +664,16 @@
1.184 args = &args[2];
1.185 num_args -= 2;
1.186
1.187 - if (!strcmp(operation, "copy-out"))
1.188 + for (op = &operations[0]; op->name != NULL; op++)
1.189 {
1.190 - exitcode = copy_out(fs, num_args, args);
1.191 - }
1.192 - else if (!strcmp(operation, "copy-in"))
1.193 - {
1.194 - exitcode = copy_in(fs, num_args, args);
1.195 + if (!strcmp(operation, op->name))
1.196 + {
1.197 + exitcode = op->fn(fs, num_args, args);
1.198 + break;
1.199 + }
1.200 }
1.201 - else if (!strcmp(operation, "list-dirs"))
1.202 - {
1.203 - exitcode = list_dirs(fs, num_args, args);
1.204 - }
1.205 - else if (!strcmp(operation, "make-dirs"))
1.206 - {
1.207 - exitcode = make_dirs(fs, num_args, args);
1.208 - }
1.209 - else
1.210 +
1.211 + if (op->name == NULL)
1.212 {
1.213 printf("Operation %s is not recognised.\n", operation);
1.214 exitcode = 1;
2.1 --- a/test_files/mk_e2test.sh Mon Feb 14 00:44:19 2022 +0100
2.2 +++ b/test_files/mk_e2test.sh Mon Feb 14 00:46:57 2022 +0100
2.3 @@ -1,7 +1,28 @@
2.4 #!/bin/sh
2.5
2.6 +# Make a test filesystem.
2.7 +#
2.8 +# Copyright (C) 2021, 2022 Paul Boddie <paul@boddie.org.uk>
2.9 +#
2.10 +# This program is free software; you can redistribute it and/or
2.11 +# modify it under the terms of the GNU General Public License as
2.12 +# published by the Free Software Foundation; either version 2 of
2.13 +# the License, or (at your option) any later version.
2.14 +#
2.15 +# This program is distributed in the hope that it will be useful,
2.16 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
2.17 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2.18 +# GNU General Public License for more details.
2.19 +#
2.20 +# You should have received a copy of the GNU General Public License
2.21 +# along with this program; if not, write to the Free Software
2.22 +# Foundation, Inc., 51 Franklin Street, Fifth Floor,
2.23 +# Boston, MA 02110-1301, USA
2.24 +
2.25 PROGNAME=$(basename "$0")
2.26
2.27 +# Handle program options.
2.28 +
2.29 if [ "$1" = '-q' ] ; then
2.30 QUIET=$1
2.31 shift 1
2.32 @@ -31,9 +52,11 @@
2.33
2.34 OPTIONS='-u 1000 -g 1000'
2.35
2.36 +# Define a convenience function for e2access invocation.
2.37 +
2.38 e2access()
2.39 {
2.40 - "$E2ACCESS" $OPTIONS $*
2.41 + "$E2ACCESS" $OPTIONS "$TARGET" $*
2.42 }
2.43
2.44 # Make a filesystem for the example.
2.45 @@ -102,8 +125,8 @@
2.46 # Add the directories and files to the image.
2.47
2.48 for DIR in home/paulb/private home/paulb/public home/paulb/shared home/paulb/many home/paulb ; do
2.49 - e2access "$TARGET" make-dirs "$DIR"
2.50 - e2access "$TARGET" copy-in $(find "$DIR" -maxdepth 1 -type f | sort) "$DIR"
2.51 + e2access mkdir "$DIR"
2.52 + e2access copy-in $(find "$DIR" -maxdepth 1 -type f | sort) "$DIR"
2.53 done
2.54
2.55 # Leave the root of the filesystem.
2.56 @@ -111,13 +134,13 @@
2.57 cd ..
2.58
2.59 if [ ! "$QUIET" ] ; then
2.60 - e2access "$TARGET" list-dirs ''
2.61 - e2access "$TARGET" list-dirs 'home'
2.62 - e2access "$TARGET" list-dirs 'home/paulb'
2.63 - e2access "$TARGET" list-dirs 'home/paulb/many'
2.64 - e2access "$TARGET" list-dirs 'home/paulb/private'
2.65 - e2access "$TARGET" list-dirs 'home/paulb/public'
2.66 - e2access "$TARGET" list-dirs 'home/paulb/shared'
2.67 + e2access ls ''
2.68 + e2access ls 'home'
2.69 + e2access ls 'home/paulb'
2.70 + e2access ls 'home/paulb/many'
2.71 + e2access ls 'home/paulb/private'
2.72 + e2access ls 'home/paulb/public'
2.73 + e2access ls 'home/paulb/shared'
2.74 fi
2.75
2.76 rm -r tmp_e2test