# HG changeset patch # User Paul Boddie # Date 1644713188 -3600 # Node ID f3ae5c354fe42309ef0f2e748094efff9d99fe25 # Parent ffd7b371fcfd639212b7f253c848db596efd8cfc Added uid, gid, umask options and tidied up argument processing. diff -r ffd7b371fcfd -r f3ae5c354fe4 libe2access/host/e2access.c --- a/libe2access/host/e2access.c Thu Feb 10 17:55:05 2022 +0100 +++ b/libe2access/host/e2access.c Sun Feb 13 01:46:28 2022 +0100 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -41,6 +42,55 @@ +/* Alternative metadata set by options. */ + +struct metadata +{ + uid_t uid; + gid_t gid; + mode_t mask; + int have_uid, have_gid; +}; + +struct metadata md; + +static int parse_options(int argc, char *argv[]) +{ + int opt; + + md.have_uid = 0; + md.have_gid = 0; + md.mask = 0000; + + while ((opt = getopt(argc, argv, "g:m:u:")) != -1) + { + switch (opt) + { + case 'g': + md.gid = atoi(optarg); + md.have_gid = 1; + break; + + case 'm': + md.mask = strtol(optarg, NULL, 0); + break; + + case 'u': + md.uid = atoi(optarg); + md.have_uid = 1; + break; + + default: + fprintf(stderr, "Option %s not recognised.\n", argv[optind]); + return -1; + } + } + + return 0; +} + + + /* Show directory entries when iterating. */ static int image_list_dir_proc(struct ext2_dir_entry *dirent, int offset, @@ -267,8 +317,11 @@ if (lstat(argv[i], &st)) return 1; - retval = image_make_dir(fs, ino_target, basename, st.st_mode, - st.st_uid, st.st_gid, &ino_file); + retval = image_make_dir(fs, ino_target, basename, + st.st_mode & ~md.mask, + md.have_uid ? md.uid : st.st_uid, + md.have_gid ? md.gid : st.st_gid, + &ino_file); if (retval) { @@ -292,8 +345,11 @@ if (lstat(argv[i], &st)) return 1; - retval = image_create_file(fs, ino_target, basename, st.st_mode, - st.st_uid, st.st_gid, &ino_file); + retval = image_create_file(fs, ino_target, basename, + st.st_mode & ~md.mask, + md.have_uid ? md.uid : st.st_uid, + md.have_gid ? md.gid : st.st_gid, + &ino_file); if (retval) { printf("Failed to create file %s (%d).\n", argv[i], retval); @@ -439,30 +495,58 @@ /* From the first unrecognised component, make the remaining directories. */ - if (image_make_dirs(fs, &path, ino, 0777, 0, 0)) + if (image_make_dirs(fs, &path, ino, 0777 & ~md.mask, 0, 0)) return 1; } return 0; } +/* Help message and main program. */ + +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\ +"; + int main(int argc, char *argv[]) { int flags = EXT2_FLAG_RW; // | EXT2_FLAG_SOFTSUPP_FEATURES | EXT2_FLAG_64BITS; - char *fsname, *operation, *filename; ext2_filsys fs = NULL; errcode_t retval; int exitcode = 0; - if (argc < 4) + /* Program argument details. */ + + char **args; + char *fsname, *operation, *filename; + int num_args; + + /* 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 < 3) { - printf("Usage: %s ...\n", argv[0]); + printf(help_text, argv[0]); return 1; } - fsname = argv[1]; + /* Open the filesystem image using the POSIX file access mechanism. */ - /* Open the filesystem image using the POSIX file access mechanism. */ + fsname = args[0]; retval = ext2fs_open(fsname, flags, 0, 0, unix_io_manager, &fs); if (retval) @@ -482,23 +566,25 @@ /* Perform the requested operation. */ - operation = argv[2]; + operation = args[1]; + args = &args[2]; + num_args -= 2; - if (!strcmp(operation, "--copy-out")) + if (!strcmp(operation, "copy-out")) { - exitcode = copy_out(fs, argc - 3, &argv[3]); + exitcode = copy_out(fs, num_args, args); } - else if (!strcmp(operation, "--copy-in")) + else if (!strcmp(operation, "copy-in")) { - exitcode = copy_in(fs, argc - 3, &argv[3]); + exitcode = copy_in(fs, num_args, args); } - else if (!strcmp(operation, "--list-dirs")) + else if (!strcmp(operation, "list-dirs")) { - exitcode = list_dirs(fs, argc - 3, &argv[3]); + exitcode = list_dirs(fs, num_args, args); } - else if (!strcmp(operation, "--make-dirs")) + else if (!strcmp(operation, "make-dirs")) { - exitcode = make_dirs(fs, argc - 3, &argv[3]); + exitcode = make_dirs(fs, num_args, args); } else { @@ -525,3 +611,6 @@ ext2fs_free(fs); return exitcode; } + +/* vim: tabstop=4 expandtab shiftwidth=4 +*/ diff -r ffd7b371fcfd -r f3ae5c354fe4 test_files/mk_e2test.sh --- a/test_files/mk_e2test.sh Thu Feb 10 17:55:05 2022 +0100 +++ b/test_files/mk_e2test.sh Sun Feb 13 01:46:28 2022 +0100 @@ -1,8 +1,5 @@ #!/bin/sh -# NOTE: There should be a stable user identifier defined, not that of the user -# NOTE: running this script. - PROGNAME=$(basename "$0") if [ "$1" = '-q' ] ; then @@ -32,6 +29,13 @@ E2ACCESS="$E2ACCESS_DIR"/e2access export LD_LIBRARY_PATH="$E2ACCESS_DIR" +OPTIONS='-u 1000 -g 1000' + +e2access() +{ + "$E2ACCESS" $OPTIONS $* +} + # Make a filesystem for the example. mkdir tmp_e2test @@ -98,8 +102,8 @@ # Add the directories and files to the image. for DIR in home/paulb/private home/paulb/public home/paulb/shared home/paulb/many home/paulb ; do - "$E2ACCESS" "$TARGET" --make-dirs "$DIR" - "$E2ACCESS" "$TARGET" --copy-in $(find "$DIR" -maxdepth 1 -type f | sort) "$DIR" + e2access "$TARGET" make-dirs "$DIR" + e2access "$TARGET" copy-in $(find "$DIR" -maxdepth 1 -type f | sort) "$DIR" done # Leave the root of the filesystem. @@ -107,13 +111,13 @@ cd .. if [ ! "$QUIET" ] ; then - "$E2ACCESS" "$TARGET" --list-dirs '' - "$E2ACCESS" "$TARGET" --list-dirs 'home' - "$E2ACCESS" "$TARGET" --list-dirs 'home/paulb' - "$E2ACCESS" "$TARGET" --list-dirs 'home/paulb/many' - "$E2ACCESS" "$TARGET" --list-dirs 'home/paulb/private' - "$E2ACCESS" "$TARGET" --list-dirs 'home/paulb/public' - "$E2ACCESS" "$TARGET" --list-dirs 'home/paulb/shared' + e2access "$TARGET" list-dirs '' + e2access "$TARGET" list-dirs 'home' + e2access "$TARGET" list-dirs 'home/paulb' + e2access "$TARGET" list-dirs 'home/paulb/many' + e2access "$TARGET" list-dirs 'home/paulb/private' + e2access "$TARGET" list-dirs 'home/paulb/public' + e2access "$TARGET" list-dirs 'home/paulb/shared' fi rm -r tmp_e2test