L4Re/departure

Change of libe2access/host/e2access.c

241:f3ae5c354fe4
libe2access/host/e2access.c
     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 +*/