1.1 --- a/libe2access/host/e2access.c Thu Feb 10 17:55:05 2022 +0100
1.2 +++ b/libe2access/host/e2access.c Sun Feb 13 01:46:28 2022 +0100
1.3 @@ -22,6 +22,7 @@
1.4 #include <stdio.h>
1.5 #include <stdlib.h>
1.6 #include <string.h>
1.7 +#include <unistd.h>
1.8
1.9 #include <sys/types.h>
1.10 #include <sys/stat.h>
1.11 @@ -41,6 +42,55 @@
1.12
1.13
1.14
1.15 +/* Alternative metadata set by options. */
1.16 +
1.17 +struct metadata
1.18 +{
1.19 + uid_t uid;
1.20 + gid_t gid;
1.21 + mode_t mask;
1.22 + int have_uid, have_gid;
1.23 +};
1.24 +
1.25 +struct metadata md;
1.26 +
1.27 +static int parse_options(int argc, char *argv[])
1.28 +{
1.29 + int opt;
1.30 +
1.31 + md.have_uid = 0;
1.32 + md.have_gid = 0;
1.33 + md.mask = 0000;
1.34 +
1.35 + while ((opt = getopt(argc, argv, "g:m:u:")) != -1)
1.36 + {
1.37 + switch (opt)
1.38 + {
1.39 + case 'g':
1.40 + md.gid = atoi(optarg);
1.41 + md.have_gid = 1;
1.42 + break;
1.43 +
1.44 + case 'm':
1.45 + md.mask = strtol(optarg, NULL, 0);
1.46 + break;
1.47 +
1.48 + case 'u':
1.49 + md.uid = atoi(optarg);
1.50 + md.have_uid = 1;
1.51 + break;
1.52 +
1.53 + default:
1.54 + fprintf(stderr, "Option %s not recognised.\n", argv[optind]);
1.55 + return -1;
1.56 + }
1.57 + }
1.58 +
1.59 + return 0;
1.60 +}
1.61 +
1.62 +
1.63 +
1.64 /* Show directory entries when iterating. */
1.65
1.66 static int image_list_dir_proc(struct ext2_dir_entry *dirent, int offset,
1.67 @@ -267,8 +317,11 @@
1.68 if (lstat(argv[i], &st))
1.69 return 1;
1.70
1.71 - retval = image_make_dir(fs, ino_target, basename, st.st_mode,
1.72 - st.st_uid, st.st_gid, &ino_file);
1.73 + retval = image_make_dir(fs, ino_target, basename,
1.74 + st.st_mode & ~md.mask,
1.75 + md.have_uid ? md.uid : st.st_uid,
1.76 + md.have_gid ? md.gid : st.st_gid,
1.77 + &ino_file);
1.78
1.79 if (retval)
1.80 {
1.81 @@ -292,8 +345,11 @@
1.82 if (lstat(argv[i], &st))
1.83 return 1;
1.84
1.85 - retval = image_create_file(fs, ino_target, basename, st.st_mode,
1.86 - st.st_uid, st.st_gid, &ino_file);
1.87 + retval = image_create_file(fs, ino_target, basename,
1.88 + st.st_mode & ~md.mask,
1.89 + md.have_uid ? md.uid : st.st_uid,
1.90 + md.have_gid ? md.gid : st.st_gid,
1.91 + &ino_file);
1.92 if (retval)
1.93 {
1.94 printf("Failed to create file %s (%d).\n", argv[i], retval);
1.95 @@ -439,30 +495,58 @@
1.96 /* From the first unrecognised component, make the remaining
1.97 directories. */
1.98
1.99 - if (image_make_dirs(fs, &path, ino, 0777, 0, 0))
1.100 + if (image_make_dirs(fs, &path, ino, 0777 & ~md.mask, 0, 0))
1.101 return 1;
1.102 }
1.103
1.104 return 0;
1.105 }
1.106
1.107 +/* Help message and main program. */
1.108 +
1.109 +char help_text[] = "\
1.110 +Usage: %s [ <options> ] <image file> <operation> <filename>...\n\
1.111 +\n\
1.112 +File ownership options:\n\
1.113 +\n\
1.114 + -g GID Set group identifier for new files\n\
1.115 + -u UID Set user identifier for new files\n\
1.116 +\n\
1.117 +File permission options:\n\
1.118 +\n\
1.119 + -m MASK Set mode/permissions mask for new directories\n\
1.120 +";
1.121 +
1.122 int main(int argc, char *argv[])
1.123 {
1.124 int flags = EXT2_FLAG_RW; // | EXT2_FLAG_SOFTSUPP_FEATURES | EXT2_FLAG_64BITS;
1.125 - char *fsname, *operation, *filename;
1.126 ext2_filsys fs = NULL;
1.127 errcode_t retval;
1.128 int exitcode = 0;
1.129
1.130 - if (argc < 4)
1.131 + /* Program argument details. */
1.132 +
1.133 + char **args;
1.134 + char *fsname, *operation, *filename;
1.135 + int num_args;
1.136 +
1.137 + /* Parse program options and initialise the argument details. */
1.138 +
1.139 + if (parse_options(argc, argv))
1.140 + return 1;
1.141 +
1.142 + args = &argv[optind];
1.143 + num_args = argc - optind;
1.144 +
1.145 + if (num_args < 3)
1.146 {
1.147 - printf("Usage: %s <device or image file> <operation> <filename>...\n", argv[0]);
1.148 + printf(help_text, argv[0]);
1.149 return 1;
1.150 }
1.151
1.152 - fsname = argv[1];
1.153 + /* Open the filesystem image using the POSIX file access mechanism. */
1.154
1.155 - /* Open the filesystem image using the POSIX file access mechanism. */
1.156 + fsname = args[0];
1.157
1.158 retval = ext2fs_open(fsname, flags, 0, 0, unix_io_manager, &fs);
1.159 if (retval)
1.160 @@ -482,23 +566,25 @@
1.161
1.162 /* Perform the requested operation. */
1.163
1.164 - operation = argv[2];
1.165 + operation = args[1];
1.166 + args = &args[2];
1.167 + num_args -= 2;
1.168
1.169 - if (!strcmp(operation, "--copy-out"))
1.170 + if (!strcmp(operation, "copy-out"))
1.171 {
1.172 - exitcode = copy_out(fs, argc - 3, &argv[3]);
1.173 + exitcode = copy_out(fs, num_args, args);
1.174 }
1.175 - else if (!strcmp(operation, "--copy-in"))
1.176 + else if (!strcmp(operation, "copy-in"))
1.177 {
1.178 - exitcode = copy_in(fs, argc - 3, &argv[3]);
1.179 + exitcode = copy_in(fs, num_args, args);
1.180 }
1.181 - else if (!strcmp(operation, "--list-dirs"))
1.182 + else if (!strcmp(operation, "list-dirs"))
1.183 {
1.184 - exitcode = list_dirs(fs, argc - 3, &argv[3]);
1.185 + exitcode = list_dirs(fs, num_args, args);
1.186 }
1.187 - else if (!strcmp(operation, "--make-dirs"))
1.188 + else if (!strcmp(operation, "make-dirs"))
1.189 {
1.190 - exitcode = make_dirs(fs, argc - 3, &argv[3]);
1.191 + exitcode = make_dirs(fs, num_args, args);
1.192 }
1.193 else
1.194 {
1.195 @@ -525,3 +611,6 @@
1.196 ext2fs_free(fs);
1.197 return exitcode;
1.198 }
1.199 +
1.200 +/* vim: tabstop=4 expandtab shiftwidth=4
1.201 +*/