1.1 --- a/libe2access/host/Makefile Sun Mar 06 01:06:30 2022 +0100 1.2 +++ b/libe2access/host/Makefile Sun Mar 06 01:30:32 2022 +0100 1.3 @@ -42,7 +42,7 @@ 1.4 1.5 # Sources and objects. 1.6 1.7 -E2ACCESS_SRC = e2access.c file.c input.c 1.8 +E2ACCESS_SRC = e2access.c file.c input.c session.c $(wildcard op_*.c) 1.9 E2ACCESS_OBJ = $(E2ACCESS_SRC:.c=.o) 1.10 1.11 TEST_LISTING_SRC = test_listing.c
2.1 --- a/libe2access/host/e2access.c Sun Mar 06 01:06:30 2022 +0100 2.2 +++ b/libe2access/host/e2access.c Sun Mar 06 01:30:32 2022 +0100 2.3 @@ -20,28 +20,20 @@ 2.4 */ 2.5 2.6 #include <stdio.h> 2.7 -#include <stdlib.h> 2.8 #include <string.h> 2.9 #include <unistd.h> 2.10 2.11 -#include <sys/types.h> 2.12 -#include <sys/stat.h> 2.13 -#include <sys/sysmacros.h> /* major, minor */ 2.14 - 2.15 #include <ext2fs/ext2fs.h> 2.16 2.17 -#include "file.h" 2.18 -#include "format.h" 2.19 -#include "image.h" 2.20 #include "input.h" 2.21 -#include "path.h" 2.22 -#include "utils.h" 2.23 +#include "ops.h" 2.24 +#include "session.h" 2.25 2.26 2.27 2.28 /* Copy buffer size. */ 2.29 2.30 -const int BUFSIZE = 4096; 2.31 +extern int BUFSIZE; 2.32 2.33 /* Maximum number of arguments in scripts. */ 2.34 2.35 @@ -49,590 +41,6 @@ 2.36 2.37 2.38 2.39 -/* Alternative metadata set by options. */ 2.40 - 2.41 -struct metadata 2.42 -{ 2.43 - uid_t uid; 2.44 - gid_t gid; 2.45 - mode_t mask; 2.46 - int have_uid, have_gid; 2.47 -}; 2.48 - 2.49 -struct metadata md; 2.50 - 2.51 -/* Parse program options. */ 2.52 - 2.53 -static int parse_options(int argc, char *argv[]) 2.54 -{ 2.55 - int opt; 2.56 - 2.57 - md.have_uid = 0; 2.58 - md.have_gid = 0; 2.59 - md.mask = 0000; 2.60 - 2.61 - while ((opt = getopt(argc, argv, "g:m:u:")) != -1) 2.62 - { 2.63 - switch (opt) 2.64 - { 2.65 - case 'g': 2.66 - md.gid = atoi(optarg); 2.67 - md.have_gid = 1; 2.68 - break; 2.69 - 2.70 - case 'm': 2.71 - md.mask = strtol(optarg, NULL, 0); 2.72 - break; 2.73 - 2.74 - case 'u': 2.75 - md.uid = atoi(optarg); 2.76 - md.have_uid = 1; 2.77 - break; 2.78 - 2.79 - default: 2.80 - fprintf(stderr, "Option not recognised: %s\n", argv[optind]); 2.81 - return -1; 2.82 - } 2.83 - } 2.84 - 2.85 - return 0; 2.86 -} 2.87 - 2.88 - 2.89 - 2.90 -/* Copy a file into the filesystem image. */ 2.91 - 2.92 -int copy_file_in(const char *filename, ext2_filsys fs, ext2_ino_t ino_file, int flags) 2.93 -{ 2.94 - int retval = 0; 2.95 - ext2_file_t file; 2.96 - 2.97 - /* Copying details. */ 2.98 - 2.99 - FILE *fp; 2.100 - char buf[BUFSIZE]; 2.101 - size_t got; 2.102 - unsigned int written; 2.103 - 2.104 - /* Open a file in the target directory. */ 2.105 - 2.106 - if (ext2fs_file_open(fs, ino_file, flags, &file)) 2.107 - return 1; 2.108 - 2.109 - /* Open the file in the source directory. */ 2.110 - 2.111 - fp = fopen(filename, "r"); 2.112 - 2.113 - /* Copy the file content. */ 2.114 - 2.115 - if (fp != NULL) 2.116 - { 2.117 - while (got = fread(buf, sizeof(char), BUFSIZE, fp)) 2.118 - { 2.119 - while (got) 2.120 - { 2.121 - if (ext2fs_file_write(file, buf, got, &written)) 2.122 - { 2.123 - retval = 1; 2.124 - goto close_files; 2.125 - } 2.126 - got -= written; 2.127 - } 2.128 - } 2.129 - } 2.130 - 2.131 -close_files: 2.132 - fclose(fp); 2.133 - ext2fs_file_flush(file); 2.134 - ext2fs_file_close(file); 2.135 - 2.136 - return retval; 2.137 -} 2.138 - 2.139 -/* Copy a file out of the filesystem image. */ 2.140 - 2.141 -int copy_file_out(const char *target, const char *filename, int target_is_file, 2.142 - ext2_filsys fs, ext2_ino_t ino_file) 2.143 -{ 2.144 - int retval = 0; 2.145 - ext2_file_t file; 2.146 - 2.147 - /* Copying details. */ 2.148 - 2.149 - FILE *fp; 2.150 - char buf[BUFSIZE]; 2.151 - unsigned int got; 2.152 - size_t written; 2.153 - 2.154 - /* Open the file in the source directory. */ 2.155 - 2.156 - if (ext2fs_file_open(fs, ino_file, 0, &file)) 2.157 - return 1; 2.158 - 2.159 - /* Open a file in the target directory. */ 2.160 - 2.161 - if (target_is_file) 2.162 - fp = fopen(target, "w"); 2.163 - else 2.164 - fp = open_file_in_dir(target, path_basename(filename), "w"); 2.165 - 2.166 - /* Copy the file content. */ 2.167 - 2.168 - if (fp != NULL) 2.169 - { 2.170 - do 2.171 - { 2.172 - if (ext2fs_file_read(file, buf, BUFSIZE, &got)) 2.173 - { 2.174 - retval = 1; 2.175 - goto close_files; 2.176 - } 2.177 - 2.178 - while (got) 2.179 - { 2.180 - written = fwrite(buf, sizeof(char), got, fp); 2.181 - got -= written; 2.182 - } 2.183 - 2.184 - } while (got); 2.185 - } 2.186 - 2.187 -close_files: 2.188 - fclose(fp); 2.189 - ext2fs_file_close(file); 2.190 - 2.191 - return retval; 2.192 -} 2.193 - 2.194 - 2.195 - 2.196 -/* Make a new directory in the external environment. */ 2.197 - 2.198 -static int _make_directory(const char *target, const char *basename, 2.199 - ext2_filsys fs, ext2_ino_t ino) 2.200 -{ 2.201 - errcode_t retval; 2.202 - struct ext2_inode inode; 2.203 - char target_path[strlen(target) + strlen(basename) + 2]; 2.204 - 2.205 - sprintf(target_path, "%s/%s", target, basename); 2.206 - 2.207 - retval = ext2fs_read_inode(fs, ino, &inode); 2.208 - 2.209 - if (retval) 2.210 - return retval; 2.211 - 2.212 - return mkdir(target_path, inode.i_mode); 2.213 -} 2.214 - 2.215 -/* Make a new object using the given function. */ 2.216 - 2.217 -static int _make_object(ext2_filsys fs, const char *filename, 2.218 - ext2_ino_t ino_parent, const char *basename, 2.219 - ext2_ino_t *ino_target, 2.220 - errcode_t (*fn)(ext2_filsys, ext2_ino_t, const char *, 2.221 - __u16, __u16, __u16, ext2_ino_t *)) 2.222 -{ 2.223 - errcode_t retval; 2.224 - struct stat st; 2.225 - 2.226 - /* Obtain the metadata. */ 2.227 - 2.228 - if (lstat(filename, &st)) 2.229 - { 2.230 - fprintf(stderr, "Failed to read object metadata: %s\n", filename); 2.231 - return 1; 2.232 - } 2.233 - 2.234 - retval = fn(fs, ino_parent, basename, st.st_mode & ~md.mask, 2.235 - md.have_uid ? md.uid : st.st_uid, 2.236 - md.have_gid ? md.gid : st.st_gid, 2.237 - ino_target); 2.238 - 2.239 - if (retval) 2.240 - { 2.241 - fprintf(stderr, "Failed to create object: %s\n", filename); 2.242 - return 1; 2.243 - } 2.244 - 2.245 - return 0; 2.246 -} 2.247 - 2.248 -/* Copy a source file from the external environment into the filesystem. */ 2.249 - 2.250 -static int _copy_in(ext2_filsys fs, const char *filename, ext2_ino_t ino_target, 2.251 - const char *basename) 2.252 -{ 2.253 - errcode_t retval; 2.254 - int flags; 2.255 - 2.256 - /* By default, treat the target as a new object. */ 2.257 - 2.258 - ext2_ino_t ino_parent = ino_target; 2.259 - int target_is_new = 1; 2.260 - 2.261 - /* Source file details. */ 2.262 - 2.263 - struct stat st; 2.264 - 2.265 - /* Without a basename, the target exists and is either a directory, into 2.266 - which the source file shall be copied, or it is a file that shall be 2.267 - overwritten. */ 2.268 - 2.269 - if (basename == NULL) 2.270 - { 2.271 - basename = path_basename(filename); 2.272 - target_is_new = image_isdir_by_inode(fs, ino_target); 2.273 - } 2.274 - 2.275 - /* Directories are created with the same metadata. */ 2.276 - 2.277 - if (isdir(filename)) 2.278 - { 2.279 - if (!target_is_new) 2.280 - { 2.281 - fprintf(stderr, "Directory cannot be copied as it already exists: %s\n", filename); 2.282 - return 1; 2.283 - } 2.284 - 2.285 - if (_make_object(fs, filename, ino_parent, basename, &ino_target, 2.286 - image_make_dir)) 2.287 - return 1; 2.288 - } 2.289 - 2.290 - /* Files are copied. */ 2.291 - 2.292 - else if (isfile(filename)) 2.293 - { 2.294 - flags = EXT2_FILE_WRITE; 2.295 - 2.296 - /* Obtain the inode for the target file. */ 2.297 - 2.298 - if (target_is_new) 2.299 - { 2.300 - if (_make_object(fs, filename, ino_parent, basename, &ino_target, 2.301 - image_create_file)) 2.302 - return 1; 2.303 - 2.304 - flags |= EXT2_FILE_CREATE; 2.305 - } 2.306 - 2.307 - /* NOTE: Overwrite/update metadata where appropriate. */ 2.308 - 2.309 - if (copy_file_in(filename, fs, ino_target, flags)) 2.310 - { 2.311 - fprintf(stderr, "Failed to copy file: %s\n", filename); 2.312 - return 1; 2.313 - } 2.314 - } 2.315 -} 2.316 - 2.317 -/* Copy source files from the external environment into the filesystem image. */ 2.318 - 2.319 -int copy_in(ext2_filsys fs, int argc, char *argv[]) 2.320 -{ 2.321 - errcode_t retval; 2.322 - int i; 2.323 - 2.324 - /* Target filename details. */ 2.325 - 2.326 - const char *target = argv[argc - 1]; 2.327 - const char *target_remaining = target; 2.328 - const char *basename; 2.329 - 2.330 - /* Target file and directory details. */ 2.331 - 2.332 - int target_is_file; 2.333 - ext2_ino_t ino_target; 2.334 - 2.335 - /* Locate the target and test whether it is a file or a directory. */ 2.336 - 2.337 - if (image_resolve_by_path(fs, &target_remaining, &ino_target)) 2.338 - { 2.339 - /* Only a non-existent file in an existing directory is permitted. */ 2.340 - 2.341 - if (!image_isdir_by_inode(fs, ino_target) || !path_is_leafname(target_remaining)) 2.342 - { 2.343 - fprintf(stderr, "Target not found: %s\n", target); 2.344 - return 1; 2.345 - } 2.346 - 2.347 - /* Any absent target leaves the basename remaining. 2.348 - The resolved target is the parent directory. */ 2.349 - 2.350 - target_is_file = 0; 2.351 - basename = target_remaining; 2.352 - } 2.353 - else 2.354 - { 2.355 - /* Any present target can be a file or directory. 2.356 - The resolved target is the actual target. */ 2.357 - 2.358 - target_is_file = image_isfile_by_inode(fs, ino_target); 2.359 - basename = NULL; 2.360 - } 2.361 - 2.362 - /* Only permit a target file when one source file is given. */ 2.363 - 2.364 - if (target_is_file) 2.365 - { 2.366 - if (argc > 2) 2.367 - { 2.368 - fprintf(stderr, "Target can only be a file when copying a single file: %s\n", target); 2.369 - return 1; 2.370 - } 2.371 - } 2.372 - else if (!image_isdir_by_inode(fs, ino_target)) 2.373 - { 2.374 - fprintf(stderr, "Target is not a directory: %s\n", target); 2.375 - return 1; 2.376 - } 2.377 - 2.378 - /* Copy each source object to the target directory. */ 2.379 - 2.380 - for (i = 0; i < argc - 1; i++) 2.381 - if (_copy_in(fs, argv[i], ino_target, basename)) 2.382 - return 1; 2.383 - 2.384 - return 0; 2.385 -} 2.386 - 2.387 -/* Copy a file from the filesystem into the external environment. */ 2.388 - 2.389 -static int _copy_out(ext2_filsys fs, const char *source, const char *target, 2.390 - int target_is_file) 2.391 -{ 2.392 - ext2_ino_t ino_source; 2.393 - 2.394 - if (image_find_by_path(fs, source, &ino_source)) 2.395 - { 2.396 - fprintf(stderr, "Failed to find file: %s\n", source); 2.397 - return 1; 2.398 - } 2.399 - 2.400 - /* Test whether the filename references a file. */ 2.401 - 2.402 - if (image_isdir_by_path(fs, source)) 2.403 - { 2.404 - if (_make_directory(target, path_basename(source), fs, ino_source)) 2.405 - { 2.406 - fprintf(stderr, "Failed to make directory: %s/%s\n", target, 2.407 - path_basename(source)); 2.408 - return 1; 2.409 - } 2.410 - } 2.411 - else if (image_isfile_by_path(fs, source)) 2.412 - { 2.413 - if (copy_file_out(target, source, target_is_file, fs, ino_source)) 2.414 - { 2.415 - fprintf(stderr, "Failed to read from file: %s\n", source); 2.416 - return 1; 2.417 - } 2.418 - } 2.419 - else 2.420 - { 2.421 - fprintf(stderr, "Object type not supported: %s\n", source); 2.422 - return 1; 2.423 - } 2.424 - 2.425 - /* NOTE: Overwrite/update metadata where appropriate. */ 2.426 - 2.427 - return 0; 2.428 -} 2.429 - 2.430 -/* Copy source files out of the filesystem image into the external environment. */ 2.431 - 2.432 -int copy_out(ext2_filsys fs, int argc, char *argv[]) 2.433 -{ 2.434 - int i; 2.435 - 2.436 - /* Target filename details. */ 2.437 - 2.438 - char *target = argv[argc - 1]; 2.439 - int target_is_file; 2.440 - 2.441 - /* Locate the target and test whether it is a directory. */ 2.442 - 2.443 - if (!isdir(target)) 2.444 - { 2.445 - /* Only a new or existing file in an existing directory is permitted. */ 2.446 - 2.447 - if (isfile(target) || isdir_dirname(target)) 2.448 - target_is_file = 1; 2.449 - else 2.450 - { 2.451 - fprintf(stderr, "Target is not a directory: %s\n", target); 2.452 - return 1; 2.453 - } 2.454 - 2.455 - /* Only permit a target file when one source file is given. */ 2.456 - 2.457 - if (argc > 2) 2.458 - { 2.459 - fprintf(stderr, "Target can only be a file when copying a single file: %s\n", target); 2.460 - return 1; 2.461 - } 2.462 - } 2.463 - else 2.464 - target_is_file = 0; 2.465 - 2.466 - /* Copy each source file to the target directory. */ 2.467 - 2.468 - for (i = 0; i < argc - 1; i++) 2.469 - if (_copy_out(fs, argv[i], target, target_is_file)) 2.470 - return 1; 2.471 - 2.472 - return 0; 2.473 -} 2.474 - 2.475 -/* List objects in the filesystem image. */ 2.476 - 2.477 -int list(ext2_filsys fs, int argc, char *argv[]) 2.478 -{ 2.479 - int i; 2.480 - char *path; 2.481 - 2.482 - for (i = 0; i < argc; i++) 2.483 - { 2.484 - path = argv[i]; 2.485 - 2.486 - /* Emit each object. */ 2.487 - 2.488 - puts(path); 2.489 - 2.490 - /* List individual files or directories. */ 2.491 - 2.492 - if (utils_list_dir(fs, path)) 2.493 - { 2.494 - fprintf(stderr, "Failed to list object: %s\n", path); 2.495 - return 1; 2.496 - } 2.497 - } 2.498 - 2.499 - return 0; 2.500 -} 2.501 - 2.502 -/* Make directories in the filesystem image. */ 2.503 - 2.504 -int make_dirs(ext2_filsys fs, int argc, char *argv[]) 2.505 -{ 2.506 - int i; 2.507 - const char *path; 2.508 - ext2_ino_t ino; 2.509 - 2.510 - /* Make each directory component in the given pathname. */ 2.511 - 2.512 - for (i = 0; i < argc; i++) 2.513 - { 2.514 - path = argv[i]; 2.515 - 2.516 - /* Search for the remaining components. */ 2.517 - 2.518 - if ((!*path) || !image_resolve_by_path(fs, &path, &ino)) 2.519 - { 2.520 - fprintf(stderr, "Path exists: %s\n", argv[i]); 2.521 - return 1; 2.522 - } 2.523 - 2.524 - /* From the first unrecognised component, make the remaining 2.525 - directories. */ 2.526 - 2.527 - if (image_make_dirs(fs, &path, ino, 2.528 - 0777 & ~md.mask, 2.529 - md.have_uid ? md.uid : 0, 2.530 - md.have_gid ? md.gid : 0)) 2.531 - { 2.532 - fprintf(stderr, "Failed to make directory: %s\n", argv[i]); 2.533 - return 1; 2.534 - } 2.535 - } 2.536 - 2.537 - return 0; 2.538 -} 2.539 - 2.540 -/* Remove objects from the filesystem image. */ 2.541 - 2.542 -int _remove(ext2_filsys fs, int argc, char *argv[], int dir_only) 2.543 -{ 2.544 - int i; 2.545 - const char *path; 2.546 - ext2_ino_t ino; 2.547 - 2.548 - /* Remove each directory with the given pathname. */ 2.549 - 2.550 - for (i = 0; i < argc; i++) 2.551 - { 2.552 - path = argv[i]; 2.553 - 2.554 - /* Detect missing objects. */ 2.555 - 2.556 - if ((!*path) || image_find_by_path(fs, path, &ino)) 2.557 - { 2.558 - fprintf(stderr, "Not found: %s\n", path); 2.559 - return 1; 2.560 - } 2.561 - 2.562 - /* Insist on a directory if specified. */ 2.563 - 2.564 - if (dir_only) 2.565 - { 2.566 - if (!image_isdir_by_inode(fs, ino)) 2.567 - { 2.568 - fprintf(stderr, "Not a directory: %s\n", path); 2.569 - return 1; 2.570 - } 2.571 - 2.572 - /* Test for an empty directory. */ 2.573 - 2.574 - if (image_dir_empty_by_inode(fs, ino)) 2.575 - { 2.576 - fprintf(stderr, "Directory not empty: %s\n", path); 2.577 - return 1; 2.578 - } 2.579 - } 2.580 - 2.581 - /* Otherwise, insist on a non-directory. */ 2.582 - 2.583 - else if (image_isdir_by_inode(fs, ino)) 2.584 - { 2.585 - fprintf(stderr, "Cannot remove a directory: %s\n", path); 2.586 - return 1; 2.587 - } 2.588 - 2.589 - /* Unlink the object. */ 2.590 - 2.591 - if (image_unlink_by_path(fs, path)) 2.592 - { 2.593 - fprintf(stderr, "Could not unlink object: %s\n", path); 2.594 - return 1; 2.595 - } 2.596 - 2.597 - /* Remove the object. */ 2.598 - 2.599 - if (image_remove_by_inode(fs, ino)) 2.600 - { 2.601 - fprintf(stderr, "Could not remove object: %s\n", path); 2.602 - return 1; 2.603 - } 2.604 - } 2.605 - 2.606 - return 0; 2.607 -} 2.608 - 2.609 -/* Remove directories from the filesystem image. */ 2.610 - 2.611 -int remove_dirs(ext2_filsys fs, int argc, char *argv[]) 2.612 -{ 2.613 - return _remove(fs, argc, argv, 1); 2.614 -} 2.615 - 2.616 -/* Remove non-directories from the filesystem image. */ 2.617 - 2.618 -int remove_non_dirs(ext2_filsys fs, int argc, char *argv[]) 2.619 -{ 2.620 - return _remove(fs, argc, argv, 0); 2.621 -} 2.622 - 2.623 /* Read operations from a script file. */ 2.624 2.625 enum op_results 2.626 @@ -701,61 +109,6 @@ 2.627 return 0; 2.628 } 2.629 2.630 -/* Show statistics for files and directories. */ 2.631 - 2.632 -int stat_objects(ext2_filsys fs, int argc, char *argv[]) 2.633 -{ 2.634 - int i; 2.635 - const char *path; 2.636 - ext2_ino_t ino; 2.637 - struct stat st; 2.638 - 2.639 - for (i = 0; i < argc; i++) 2.640 - { 2.641 - path = argv[i]; 2.642 - 2.643 - /* Detect missing objects. */ 2.644 - 2.645 - if (image_find_by_path(fs, path, &ino)) 2.646 - { 2.647 - fprintf(stderr, "Not found: %s\n", path); 2.648 - return 1; 2.649 - } 2.650 - 2.651 - /* Even though the statistics could be read directly out of ext2 data 2.652 - structures, it is convenient to use the standard stat structure. */ 2.653 - 2.654 - if (image_stat_inode(fs, ino, &st)) 2.655 - { 2.656 - fprintf(stderr, "Cannot stat object: %s\n", path); 2.657 - return 1; 2.658 - } 2.659 - 2.660 - /* Terse stat output: 2.661 - %n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %W %o %C */ 2.662 - 2.663 - printf("%s %ld %ld %x %d %d ", 2.664 - path, st.st_size, st.st_blocks, st.st_mode, st.st_uid, st.st_gid); 2.665 - 2.666 - printf("%d %d %d %x %x ", 2.667 - st.st_dev, st.st_ino, st.st_nlink, 2.668 - major(st.st_rdev), minor(st.st_rdev)); 2.669 - 2.670 - printf("%d %d %d ", 2.671 - st.st_atim, st.st_mtim, st.st_ctim); 2.672 - 2.673 - /* NOTE: Arbitrary values: 2.674 - %W (creation time) given as 0 2.675 - %o (I/O transfer size hint) given as 0 2.676 - %C (SELinux security context) given as empty string */ 2.677 - 2.678 - printf("%d %d %s\n", 2.679 - 0, 0, ""); 2.680 - } 2.681 - 2.682 - return 0; 2.683 -} 2.684 - 2.685 2.686 2.687 /* Help message. */
3.1 --- a/libe2access/host/file.c Sun Mar 06 01:06:30 2022 +0100 3.2 +++ b/libe2access/host/file.c Sun Mar 06 01:30:32 2022 +0100 3.3 @@ -1,7 +1,7 @@ 3.4 /* 3.5 - * File access functions. 3.6 + * Generic file access functions. 3.7 * 3.8 - * Copyright (C) 2019 Paul Boddie <paul@boddie.org.uk> 3.9 + * Copyright (C) 2019, 2022 Paul Boddie <paul@boddie.org.uk> 3.10 * 3.11 * This program is free software; you can redistribute it and/or 3.12 * modify it under the terms of the GNU General Public License as 3.13 @@ -21,8 +21,8 @@ 3.14 3.15 #include <stdio.h> 3.16 #include <string.h> 3.17 +#include <sys/stat.h> 3.18 #include <sys/types.h> 3.19 -#include <sys/stat.h> 3.20 3.21 3.22 3.23 @@ -75,3 +75,6 @@ 3.24 3.25 return fopen(pathname, mode); 3.26 } 3.27 + 3.28 +/* vim: tabstop=4 expandtab shiftwidth=4 3.29 +*/
4.1 --- a/libe2access/host/file.h Sun Mar 06 01:06:30 2022 +0100 4.2 +++ b/libe2access/host/file.h Sun Mar 06 01:30:32 2022 +0100 4.3 @@ -19,8 +19,7 @@ 4.4 * Boston, MA 02110-1301, USA 4.5 */ 4.6 4.7 -#ifndef __FILE_H__ 4.8 -#define __FILE_H__ 4.9 +#pragma once 4.10 4.11 #include <stdio.h> 4.12 4.13 @@ -31,4 +30,5 @@ 4.14 FILE *open_file_in_dir(const char *dirname, const char *basename, 4.15 const char *mode); 4.16 4.17 -#endif /* __FILE_H__ */ 4.18 +/* vim: tabstop=4 expandtab shiftwidth=4 4.19 +*/
5.1 --- a/libe2access/host/input.h Sun Mar 06 01:06:30 2022 +0100 5.2 +++ b/libe2access/host/input.h Sun Mar 06 01:30:32 2022 +0100 5.3 @@ -19,9 +19,7 @@ 5.4 * Boston, MA 02110-1301, USA 5.5 */ 5.6 5.7 -#ifndef __INPUT_H__ 5.8 - 5.9 - 5.10 +#pragma once 5.11 5.12 #include <stdio.h> 5.13 5.14 @@ -31,22 +29,10 @@ 5.15 size_t buffer_size, remaining; 5.16 }; 5.17 5.18 -#ifdef __cplusplus 5.19 -extern "C" { 5.20 -#endif 5.21 - 5.22 void parse_line(char *start, char *end, int *num_args, char *args[], 5.23 const int max_args); 5.24 5.25 char *read_line(FILE *fp, struct read_line_state *state); 5.26 5.27 -#ifdef __cplusplus 5.28 -} 5.29 -#endif 5.30 - 5.31 - 5.32 - 5.33 -#endif /* __INPUT_H__ */ 5.34 - 5.35 /* vim: tabstop=4 expandtab shiftwidth=4 5.36 */
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/libe2access/host/op_copy_in.c Sun Mar 06 01:30:32 2022 +0100 6.3 @@ -0,0 +1,270 @@ 6.4 +/* 6.5 + * Access a filesystem. 6.6 + * 6.7 + * Copyright (C) 2019, 2022 Paul Boddie <paul@boddie.org.uk> 6.8 + * 6.9 + * This program is free software; you can redistribute it and/or 6.10 + * modify it under the terms of the GNU General Public License as 6.11 + * published by the Free Software Foundation; either version 2 of 6.12 + * the License, or (at your option) any later version. 6.13 + * 6.14 + * This program is distributed in the hope that it will be useful, 6.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 6.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 6.17 + * GNU General Public License for more details. 6.18 + * 6.19 + * You should have received a copy of the GNU General Public License 6.20 + * along with this program; if not, write to the Free Software 6.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 6.22 + * Boston, MA 02110-1301, USA 6.23 + */ 6.24 + 6.25 +#include <stdio.h> 6.26 + 6.27 +#include <sys/stat.h> 6.28 + 6.29 +#include <ext2fs/ext2fs.h> 6.30 + 6.31 +#include "file.h" 6.32 +#include "image.h" 6.33 +#include "path.h" 6.34 +#include "session.h" 6.35 + 6.36 + 6.37 + 6.38 +/* Copy buffer size. */ 6.39 + 6.40 +extern int BUFSIZE; 6.41 + 6.42 + 6.43 + 6.44 +/* Alternative metadata set by options. */ 6.45 + 6.46 +extern struct metadata md; 6.47 + 6.48 + 6.49 + 6.50 +/* Copy a file into the filesystem image. */ 6.51 + 6.52 +static int _copy_file_in(const char *filename, ext2_filsys fs, 6.53 + ext2_ino_t ino_file, int flags) 6.54 +{ 6.55 + int retval = 0; 6.56 + ext2_file_t file; 6.57 + 6.58 + /* Copying details. */ 6.59 + 6.60 + FILE *fp; 6.61 + char buf[BUFSIZE]; 6.62 + size_t got; 6.63 + unsigned int written; 6.64 + 6.65 + /* Open a file in the target directory. */ 6.66 + 6.67 + if (ext2fs_file_open(fs, ino_file, flags, &file)) 6.68 + return 1; 6.69 + 6.70 + /* Open the file in the source directory. */ 6.71 + 6.72 + fp = fopen(filename, "r"); 6.73 + 6.74 + /* Copy the file content. */ 6.75 + 6.76 + if (fp != NULL) 6.77 + { 6.78 + while (got = fread(buf, sizeof(char), BUFSIZE, fp)) 6.79 + { 6.80 + while (got) 6.81 + { 6.82 + if (ext2fs_file_write(file, buf, got, &written)) 6.83 + { 6.84 + retval = 1; 6.85 + goto close_files; 6.86 + } 6.87 + got -= written; 6.88 + } 6.89 + } 6.90 + } 6.91 + 6.92 +close_files: 6.93 + fclose(fp); 6.94 + ext2fs_file_flush(file); 6.95 + ext2fs_file_close(file); 6.96 + 6.97 + return retval; 6.98 +} 6.99 + 6.100 +/* Make a new object using the given function. */ 6.101 + 6.102 +static int _make_object(ext2_filsys fs, const char *filename, 6.103 + ext2_ino_t ino_parent, const char *basename, 6.104 + ext2_ino_t *ino_target, 6.105 + errcode_t (*fn)(ext2_filsys, ext2_ino_t, const char *, 6.106 + __u16, __u16, __u16, ext2_ino_t *)) 6.107 +{ 6.108 + errcode_t retval; 6.109 + struct stat st; 6.110 + 6.111 + /* Obtain the metadata. */ 6.112 + 6.113 + if (lstat(filename, &st)) 6.114 + { 6.115 + fprintf(stderr, "Failed to read object metadata: %s\n", filename); 6.116 + return 1; 6.117 + } 6.118 + 6.119 + retval = fn(fs, ino_parent, basename, st.st_mode & ~md.mask, 6.120 + md.have_uid ? md.uid : st.st_uid, 6.121 + md.have_gid ? md.gid : st.st_gid, 6.122 + ino_target); 6.123 + 6.124 + if (retval) 6.125 + { 6.126 + fprintf(stderr, "Failed to create object: %s\n", filename); 6.127 + return 1; 6.128 + } 6.129 + 6.130 + return 0; 6.131 +} 6.132 + 6.133 +/* Copy a source file from the external environment into the filesystem. */ 6.134 + 6.135 +static int _copy_in(ext2_filsys fs, const char *filename, ext2_ino_t ino_target, 6.136 + const char *basename) 6.137 +{ 6.138 + errcode_t retval; 6.139 + int flags; 6.140 + 6.141 + /* By default, treat the target as a new object. */ 6.142 + 6.143 + ext2_ino_t ino_parent = ino_target; 6.144 + int target_is_new = 1; 6.145 + 6.146 + /* Source file details. */ 6.147 + 6.148 + struct stat st; 6.149 + 6.150 + /* Without a basename, the target exists and is either a directory, into 6.151 + which the source file shall be copied, or it is a file that shall be 6.152 + overwritten. */ 6.153 + 6.154 + if (basename == NULL) 6.155 + { 6.156 + basename = path_basename(filename); 6.157 + target_is_new = image_isdir_by_inode(fs, ino_target); 6.158 + } 6.159 + 6.160 + /* Directories are created with the same metadata. */ 6.161 + 6.162 + if (isdir(filename)) 6.163 + { 6.164 + if (!target_is_new) 6.165 + { 6.166 + fprintf(stderr, "Directory cannot be copied as it already exists: %s\n", filename); 6.167 + return 1; 6.168 + } 6.169 + 6.170 + if (_make_object(fs, filename, ino_parent, basename, &ino_target, 6.171 + image_make_dir)) 6.172 + return 1; 6.173 + } 6.174 + 6.175 + /* Files are copied. */ 6.176 + 6.177 + else if (isfile(filename)) 6.178 + { 6.179 + flags = EXT2_FILE_WRITE; 6.180 + 6.181 + /* Obtain the inode for the target file. */ 6.182 + 6.183 + if (target_is_new) 6.184 + { 6.185 + if (_make_object(fs, filename, ino_parent, basename, &ino_target, 6.186 + image_create_file)) 6.187 + return 1; 6.188 + 6.189 + flags |= EXT2_FILE_CREATE; 6.190 + } 6.191 + 6.192 + /* NOTE: Overwrite/update metadata where appropriate. */ 6.193 + 6.194 + if (_copy_file_in(filename, fs, ino_target, flags)) 6.195 + { 6.196 + fprintf(stderr, "Failed to copy file: %s\n", filename); 6.197 + return 1; 6.198 + } 6.199 + } 6.200 +} 6.201 + 6.202 +/* Copy source files from the external environment into the filesystem image. */ 6.203 + 6.204 +int copy_in(ext2_filsys fs, int argc, char *argv[]) 6.205 +{ 6.206 + errcode_t retval; 6.207 + int i; 6.208 + 6.209 + /* Target filename details. */ 6.210 + 6.211 + const char *target = argv[argc - 1]; 6.212 + const char *target_remaining = target; 6.213 + const char *basename; 6.214 + 6.215 + /* Target file and directory details. */ 6.216 + 6.217 + int target_is_file; 6.218 + ext2_ino_t ino_target; 6.219 + 6.220 + /* Locate the target and test whether it is a file or a directory. */ 6.221 + 6.222 + if (image_resolve_by_path(fs, &target_remaining, &ino_target)) 6.223 + { 6.224 + /* Only a non-existent file in an existing directory is permitted. */ 6.225 + 6.226 + if (!image_isdir_by_inode(fs, ino_target) || !path_is_leafname(target_remaining)) 6.227 + { 6.228 + fprintf(stderr, "Target not found: %s\n", target); 6.229 + return 1; 6.230 + } 6.231 + 6.232 + /* Any absent target leaves the basename remaining. 6.233 + The resolved target is the parent directory. */ 6.234 + 6.235 + target_is_file = 0; 6.236 + basename = target_remaining; 6.237 + } 6.238 + else 6.239 + { 6.240 + /* Any present target can be a file or directory. 6.241 + The resolved target is the actual target. */ 6.242 + 6.243 + target_is_file = image_isfile_by_inode(fs, ino_target); 6.244 + basename = NULL; 6.245 + } 6.246 + 6.247 + /* Only permit a target file when one source file is given. */ 6.248 + 6.249 + if (target_is_file) 6.250 + { 6.251 + if (argc > 2) 6.252 + { 6.253 + fprintf(stderr, "Target can only be a file when copying a single file: %s\n", target); 6.254 + return 1; 6.255 + } 6.256 + } 6.257 + else if (!image_isdir_by_inode(fs, ino_target)) 6.258 + { 6.259 + fprintf(stderr, "Target is not a directory: %s\n", target); 6.260 + return 1; 6.261 + } 6.262 + 6.263 + /* Copy each source object to the target directory. */ 6.264 + 6.265 + for (i = 0; i < argc - 1; i++) 6.266 + if (_copy_in(fs, argv[i], ino_target, basename)) 6.267 + return 1; 6.268 + 6.269 + return 0; 6.270 +} 6.271 + 6.272 +/* vim: tabstop=4 expandtab shiftwidth=4 6.273 +*/
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/libe2access/host/op_copy_out.c Sun Mar 06 01:30:32 2022 +0100 7.3 @@ -0,0 +1,214 @@ 7.4 +/* 7.5 + * Access a filesystem. 7.6 + * 7.7 + * Copyright (C) 2019, 2022 Paul Boddie <paul@boddie.org.uk> 7.8 + * 7.9 + * This program is free software; you can redistribute it and/or 7.10 + * modify it under the terms of the GNU General Public License as 7.11 + * published by the Free Software Foundation; either version 2 of 7.12 + * the License, or (at your option) any later version. 7.13 + * 7.14 + * This program is distributed in the hope that it will be useful, 7.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 7.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 7.17 + * GNU General Public License for more details. 7.18 + * 7.19 + * You should have received a copy of the GNU General Public License 7.20 + * along with this program; if not, write to the Free Software 7.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 7.22 + * Boston, MA 02110-1301, USA 7.23 + */ 7.24 + 7.25 +#include <stdio.h> 7.26 +#include <string.h> 7.27 + 7.28 +#include <sys/stat.h> 7.29 + 7.30 +#include <ext2fs/ext2fs.h> 7.31 + 7.32 +#include "file.h" 7.33 +#include "image.h" 7.34 +#include "path.h" 7.35 +#include "session.h" 7.36 + 7.37 + 7.38 + 7.39 +/* Copy buffer size. */ 7.40 + 7.41 +extern int BUFSIZE; 7.42 + 7.43 + 7.44 + 7.45 +/* Alternative metadata set by options. */ 7.46 + 7.47 +extern struct metadata md; 7.48 + 7.49 + 7.50 + 7.51 +/* Copy a file out of the filesystem image. */ 7.52 + 7.53 +static int _copy_file_out(const char *target, const char *filename, 7.54 + int target_is_file, ext2_filsys fs, 7.55 + ext2_ino_t ino_file) 7.56 +{ 7.57 + int retval = 0; 7.58 + ext2_file_t file; 7.59 + 7.60 + /* Copying details. */ 7.61 + 7.62 + FILE *fp; 7.63 + char buf[BUFSIZE]; 7.64 + unsigned int got; 7.65 + size_t written; 7.66 + 7.67 + /* Open the file in the source directory. */ 7.68 + 7.69 + if (ext2fs_file_open(fs, ino_file, 0, &file)) 7.70 + return 1; 7.71 + 7.72 + /* Open a file in the target directory. */ 7.73 + 7.74 + if (target_is_file) 7.75 + fp = fopen(target, "w"); 7.76 + else 7.77 + fp = open_file_in_dir(target, path_basename(filename), "w"); 7.78 + 7.79 + /* Copy the file content. */ 7.80 + 7.81 + if (fp != NULL) 7.82 + { 7.83 + do 7.84 + { 7.85 + if (ext2fs_file_read(file, buf, BUFSIZE, &got)) 7.86 + { 7.87 + retval = 1; 7.88 + goto close_files; 7.89 + } 7.90 + 7.91 + while (got) 7.92 + { 7.93 + written = fwrite(buf, sizeof(char), got, fp); 7.94 + got -= written; 7.95 + } 7.96 + 7.97 + } while (got); 7.98 + } 7.99 + 7.100 +close_files: 7.101 + fclose(fp); 7.102 + ext2fs_file_close(file); 7.103 + 7.104 + return retval; 7.105 +} 7.106 + 7.107 + 7.108 + 7.109 +/* Make a new directory in the external environment. */ 7.110 + 7.111 +static int _make_directory(const char *target, const char *basename, 7.112 + ext2_filsys fs, ext2_ino_t ino) 7.113 +{ 7.114 + errcode_t retval; 7.115 + struct ext2_inode inode; 7.116 + char target_path[strlen(target) + strlen(basename) + 2]; 7.117 + 7.118 + sprintf(target_path, "%s/%s", target, basename); 7.119 + 7.120 + retval = ext2fs_read_inode(fs, ino, &inode); 7.121 + 7.122 + if (retval) 7.123 + return retval; 7.124 + 7.125 + return mkdir(target_path, inode.i_mode); 7.126 +} 7.127 + 7.128 +/* Copy a file from the filesystem into the external environment. */ 7.129 + 7.130 +static int _copy_out(ext2_filsys fs, const char *source, const char *target, 7.131 + int target_is_file) 7.132 +{ 7.133 + ext2_ino_t ino_source; 7.134 + 7.135 + if (image_find_by_path(fs, source, &ino_source)) 7.136 + { 7.137 + fprintf(stderr, "Failed to find file: %s\n", source); 7.138 + return 1; 7.139 + } 7.140 + 7.141 + /* Test whether the filename references a file. */ 7.142 + 7.143 + if (image_isdir_by_path(fs, source)) 7.144 + { 7.145 + if (_make_directory(target, path_basename(source), fs, ino_source)) 7.146 + { 7.147 + fprintf(stderr, "Failed to make directory: %s/%s\n", target, 7.148 + path_basename(source)); 7.149 + return 1; 7.150 + } 7.151 + } 7.152 + else if (image_isfile_by_path(fs, source)) 7.153 + { 7.154 + if (_copy_file_out(target, source, target_is_file, fs, ino_source)) 7.155 + { 7.156 + fprintf(stderr, "Failed to read from file: %s\n", source); 7.157 + return 1; 7.158 + } 7.159 + } 7.160 + else 7.161 + { 7.162 + fprintf(stderr, "Object type not supported: %s\n", source); 7.163 + return 1; 7.164 + } 7.165 + 7.166 + /* NOTE: Overwrite/update metadata where appropriate. */ 7.167 + 7.168 + return 0; 7.169 +} 7.170 + 7.171 +/* Copy source files out of the filesystem image into the external environment. */ 7.172 + 7.173 +int copy_out(ext2_filsys fs, int argc, char *argv[]) 7.174 +{ 7.175 + int i; 7.176 + 7.177 + /* Target filename details. */ 7.178 + 7.179 + char *target = argv[argc - 1]; 7.180 + int target_is_file; 7.181 + 7.182 + /* Locate the target and test whether it is a directory. */ 7.183 + 7.184 + if (!isdir(target)) 7.185 + { 7.186 + /* Only a new or existing file in an existing directory is permitted. */ 7.187 + 7.188 + if (isfile(target) || isdir_dirname(target)) 7.189 + target_is_file = 1; 7.190 + else 7.191 + { 7.192 + fprintf(stderr, "Target is not a directory: %s\n", target); 7.193 + return 1; 7.194 + } 7.195 + 7.196 + /* Only permit a target file when one source file is given. */ 7.197 + 7.198 + if (argc > 2) 7.199 + { 7.200 + fprintf(stderr, "Target can only be a file when copying a single file: %s\n", target); 7.201 + return 1; 7.202 + } 7.203 + } 7.204 + else 7.205 + target_is_file = 0; 7.206 + 7.207 + /* Copy each source file to the target directory. */ 7.208 + 7.209 + for (i = 0; i < argc - 1; i++) 7.210 + if (_copy_out(fs, argv[i], target, target_is_file)) 7.211 + return 1; 7.212 + 7.213 + return 0; 7.214 +} 7.215 + 7.216 +/* vim: tabstop=4 expandtab shiftwidth=4 7.217 +*/
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/libe2access/host/op_list_objects.c Sun Mar 06 01:30:32 2022 +0100 8.3 @@ -0,0 +1,67 @@ 8.4 +/* 8.5 + * List objects in a filesystem. 8.6 + * 8.7 + * Copyright (C) 2019, 2022 Paul Boddie <paul@boddie.org.uk> 8.8 + * 8.9 + * This program is free software; you can redistribute it and/or 8.10 + * modify it under the terms of the GNU General Public License as 8.11 + * published by the Free Software Foundation; either version 2 of 8.12 + * the License, or (at your option) any later version. 8.13 + * 8.14 + * This program is distributed in the hope that it will be useful, 8.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 8.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 8.17 + * GNU General Public License for more details. 8.18 + * 8.19 + * You should have received a copy of the GNU General Public License 8.20 + * along with this program; if not, write to the Free Software 8.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 8.22 + * Boston, MA 02110-1301, USA 8.23 + */ 8.24 + 8.25 +#include <stdio.h> 8.26 + 8.27 +#include <ext2fs/ext2fs.h> 8.28 + 8.29 +#include "format.h" 8.30 +#include "image.h" 8.31 +#include "session.h" 8.32 +#include "utils.h" 8.33 + 8.34 + 8.35 + 8.36 +/* Alternative metadata set by options. */ 8.37 + 8.38 +extern struct metadata md; 8.39 + 8.40 + 8.41 + 8.42 +/* List objects in the filesystem image. */ 8.43 + 8.44 +int list(ext2_filsys fs, int argc, char *argv[]) 8.45 +{ 8.46 + int i; 8.47 + char *path; 8.48 + 8.49 + for (i = 0; i < argc; i++) 8.50 + { 8.51 + path = argv[i]; 8.52 + 8.53 + /* Emit each object. */ 8.54 + 8.55 + puts(path); 8.56 + 8.57 + /* List individual files or directories. */ 8.58 + 8.59 + if (utils_list_dir(fs, path)) 8.60 + { 8.61 + fprintf(stderr, "Failed to list object: %s\n", path); 8.62 + return 1; 8.63 + } 8.64 + } 8.65 + 8.66 + return 0; 8.67 +} 8.68 + 8.69 +/* vim: tabstop=4 expandtab shiftwidth=4 8.70 +*/
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/libe2access/host/op_make_dirs.c Sun Mar 06 01:30:32 2022 +0100 9.3 @@ -0,0 +1,76 @@ 9.4 +/* 9.5 + * Make directories in a filesystem. 9.6 + * 9.7 + * Copyright (C) 2019, 2022 Paul Boddie <paul@boddie.org.uk> 9.8 + * 9.9 + * This program is free software; you can redistribute it and/or 9.10 + * modify it under the terms of the GNU General Public License as 9.11 + * published by the Free Software Foundation; either version 2 of 9.12 + * the License, or (at your option) any later version. 9.13 + * 9.14 + * This program is distributed in the hope that it will be useful, 9.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 9.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9.17 + * GNU General Public License for more details. 9.18 + * 9.19 + * You should have received a copy of the GNU General Public License 9.20 + * along with this program; if not, write to the Free Software 9.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 9.22 + * Boston, MA 02110-1301, USA 9.23 + */ 9.24 + 9.25 +#include <stdio.h> 9.26 + 9.27 +#include <ext2fs/ext2fs.h> 9.28 + 9.29 +#include "image.h" 9.30 +#include "session.h" 9.31 + 9.32 + 9.33 + 9.34 +/* Alternative metadata set by options. */ 9.35 + 9.36 +extern struct metadata md; 9.37 + 9.38 + 9.39 + 9.40 +/* Make directories in the filesystem image. */ 9.41 + 9.42 +int make_dirs(ext2_filsys fs, int argc, char *argv[]) 9.43 +{ 9.44 + int i; 9.45 + const char *path; 9.46 + ext2_ino_t ino; 9.47 + 9.48 + /* Make each directory component in the given pathname. */ 9.49 + 9.50 + for (i = 0; i < argc; i++) 9.51 + { 9.52 + path = argv[i]; 9.53 + 9.54 + /* Search for the remaining components. */ 9.55 + 9.56 + if ((!*path) || !image_resolve_by_path(fs, &path, &ino)) 9.57 + { 9.58 + fprintf(stderr, "Path exists: %s\n", argv[i]); 9.59 + return 1; 9.60 + } 9.61 + 9.62 + /* From the first unrecognised component, make the remaining 9.63 + directories. */ 9.64 + 9.65 + if (image_make_dirs(fs, &path, ino, 9.66 + 0777 & ~md.mask, 9.67 + md.have_uid ? md.uid : 0, 9.68 + md.have_gid ? md.gid : 0)) 9.69 + { 9.70 + fprintf(stderr, "Failed to make directory: %s\n", argv[i]); 9.71 + return 1; 9.72 + } 9.73 + } 9.74 + 9.75 + return 0; 9.76 +} 9.77 + 9.78 +/* vim: tabstop=4 expandtab shiftwidth=4 9.79 +*/
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/libe2access/host/op_remove.c Sun Mar 06 01:30:32 2022 +0100 10.3 @@ -0,0 +1,121 @@ 10.4 +/* 10.5 + * Remove objects from a filesystem. 10.6 + * 10.7 + * Copyright (C) 2019, 2022 Paul Boddie <paul@boddie.org.uk> 10.8 + * 10.9 + * This program is free software; you can redistribute it and/or 10.10 + * modify it under the terms of the GNU General Public License as 10.11 + * published by the Free Software Foundation; either version 2 of 10.12 + * the License, or (at your option) any later version. 10.13 + * 10.14 + * This program is distributed in the hope that it will be useful, 10.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 10.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10.17 + * GNU General Public License for more details. 10.18 + * 10.19 + * You should have received a copy of the GNU General Public License 10.20 + * along with this program; if not, write to the Free Software 10.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 10.22 + * Boston, MA 02110-1301, USA 10.23 + */ 10.24 + 10.25 +#include <stdio.h> 10.26 + 10.27 +#include <ext2fs/ext2fs.h> 10.28 + 10.29 +#include "image.h" 10.30 +#include "session.h" 10.31 + 10.32 + 10.33 + 10.34 +/* Alternative metadata set by options. */ 10.35 + 10.36 +extern struct metadata md; 10.37 + 10.38 + 10.39 + 10.40 +/* Remove objects from the filesystem image. */ 10.41 + 10.42 +int _remove(ext2_filsys fs, int argc, char *argv[], int dir_only) 10.43 +{ 10.44 + int i; 10.45 + const char *path; 10.46 + ext2_ino_t ino; 10.47 + 10.48 + /* Remove each directory with the given pathname. */ 10.49 + 10.50 + for (i = 0; i < argc; i++) 10.51 + { 10.52 + path = argv[i]; 10.53 + 10.54 + /* Detect missing objects. */ 10.55 + 10.56 + if ((!*path) || image_find_by_path(fs, path, &ino)) 10.57 + { 10.58 + fprintf(stderr, "Not found: %s\n", path); 10.59 + return 1; 10.60 + } 10.61 + 10.62 + /* Insist on a directory if specified. */ 10.63 + 10.64 + if (dir_only) 10.65 + { 10.66 + if (!image_isdir_by_inode(fs, ino)) 10.67 + { 10.68 + fprintf(stderr, "Not a directory: %s\n", path); 10.69 + return 1; 10.70 + } 10.71 + 10.72 + /* Test for an empty directory. */ 10.73 + 10.74 + if (image_dir_empty_by_inode(fs, ino)) 10.75 + { 10.76 + fprintf(stderr, "Directory not empty: %s\n", path); 10.77 + return 1; 10.78 + } 10.79 + } 10.80 + 10.81 + /* Otherwise, insist on a non-directory. */ 10.82 + 10.83 + else if (image_isdir_by_inode(fs, ino)) 10.84 + { 10.85 + fprintf(stderr, "Cannot remove a directory: %s\n", path); 10.86 + return 1; 10.87 + } 10.88 + 10.89 + /* Unlink the object. */ 10.90 + 10.91 + if (image_unlink_by_path(fs, path)) 10.92 + { 10.93 + fprintf(stderr, "Could not unlink object: %s\n", path); 10.94 + return 1; 10.95 + } 10.96 + 10.97 + /* Remove the object. */ 10.98 + 10.99 + if (image_remove_by_inode(fs, ino)) 10.100 + { 10.101 + fprintf(stderr, "Could not remove object: %s\n", path); 10.102 + return 1; 10.103 + } 10.104 + } 10.105 + 10.106 + return 0; 10.107 +} 10.108 + 10.109 +/* Remove directories from the filesystem image. */ 10.110 + 10.111 +int remove_dirs(ext2_filsys fs, int argc, char *argv[]) 10.112 +{ 10.113 + return _remove(fs, argc, argv, 1); 10.114 +} 10.115 + 10.116 +/* Remove non-directories from the filesystem image. */ 10.117 + 10.118 +int remove_non_dirs(ext2_filsys fs, int argc, char *argv[]) 10.119 +{ 10.120 + return _remove(fs, argc, argv, 0); 10.121 +} 10.122 + 10.123 +/* vim: tabstop=4 expandtab shiftwidth=4 10.124 +*/
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/libe2access/host/op_stat_objects.c Sun Mar 06 01:30:32 2022 +0100 11.3 @@ -0,0 +1,90 @@ 11.4 +/* 11.5 + * Obtain object statistics from a filesystem. 11.6 + * 11.7 + * Copyright (C) 2019, 2022 Paul Boddie <paul@boddie.org.uk> 11.8 + * 11.9 + * This program is free software; you can redistribute it and/or 11.10 + * modify it under the terms of the GNU General Public License as 11.11 + * published by the Free Software Foundation; either version 2 of 11.12 + * the License, or (at your option) any later version. 11.13 + * 11.14 + * This program is distributed in the hope that it will be useful, 11.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 11.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11.17 + * GNU General Public License for more details. 11.18 + * 11.19 + * You should have received a copy of the GNU General Public License 11.20 + * along with this program; if not, write to the Free Software 11.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 11.22 + * Boston, MA 02110-1301, USA 11.23 + */ 11.24 + 11.25 +#include <stdio.h> 11.26 + 11.27 +#include <sys/stat.h> 11.28 +#include <sys/sysmacros.h> /* major, minor */ 11.29 +#include <sys/types.h> 11.30 + 11.31 +#include <ext2fs/ext2fs.h> 11.32 + 11.33 +#include "image.h" 11.34 + 11.35 + 11.36 + 11.37 +/* Show statistics for files and directories. */ 11.38 + 11.39 +int stat_objects(ext2_filsys fs, int argc, char *argv[]) 11.40 +{ 11.41 + int i; 11.42 + const char *path; 11.43 + ext2_ino_t ino; 11.44 + struct stat st; 11.45 + 11.46 + for (i = 0; i < argc; i++) 11.47 + { 11.48 + path = argv[i]; 11.49 + 11.50 + /* Detect missing objects. */ 11.51 + 11.52 + if (image_find_by_path(fs, path, &ino)) 11.53 + { 11.54 + fprintf(stderr, "Not found: %s\n", path); 11.55 + return 1; 11.56 + } 11.57 + 11.58 + /* Even though the statistics could be read directly out of ext2 data 11.59 + structures, it is convenient to use the standard stat structure. */ 11.60 + 11.61 + if (image_stat_inode(fs, ino, &st)) 11.62 + { 11.63 + fprintf(stderr, "Cannot stat object: %s\n", path); 11.64 + return 1; 11.65 + } 11.66 + 11.67 + /* Terse stat output: 11.68 + %n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %W %o %C */ 11.69 + 11.70 + printf("%s %ld %ld %x %d %d ", 11.71 + path, st.st_size, st.st_blocks, st.st_mode, st.st_uid, st.st_gid); 11.72 + 11.73 + printf("%d %d %d %x %x ", 11.74 + st.st_dev, st.st_ino, st.st_nlink, 11.75 + major(st.st_rdev), minor(st.st_rdev)); 11.76 + 11.77 + printf("%d %d %d ", 11.78 + st.st_atim, st.st_mtim, st.st_ctim); 11.79 + 11.80 + /* NOTE: Arbitrary values: 11.81 + %W (creation time) given as 0 11.82 + %o (I/O transfer size hint) given as 0 11.83 + %C (SELinux security context) given as empty string */ 11.84 + 11.85 + printf("%d %d %s\n", 11.86 + 0, 0, ""); 11.87 + } 11.88 + 11.89 + return 0; 11.90 +} 11.91 + 11.92 +/* vim: tabstop=4 expandtab shiftwidth=4 11.93 +*/
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/libe2access/host/ops.h Sun Mar 06 01:30:32 2022 +0100 12.3 @@ -0,0 +1,33 @@ 12.4 +/* 12.5 + * Operations. 12.6 + * 12.7 + * Copyright (C) 2022 Paul Boddie <paul@boddie.org.uk> 12.8 + * 12.9 + * This program is free software; you can redistribute it and/or 12.10 + * modify it under the terms of the GNU General Public License as 12.11 + * published by the Free Software Foundation; either version 2 of 12.12 + * the License, or (at your option) any later version. 12.13 + * 12.14 + * This program is distributed in the hope that it will be useful, 12.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12.17 + * GNU General Public License for more details. 12.18 + * 12.19 + * You should have received a copy of the GNU General Public License 12.20 + * along with this program; if not, write to the Free Software 12.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 12.22 + * Boston, MA 02110-1301, USA 12.23 + */ 12.24 + 12.25 +#pragma once 12.26 + 12.27 +int copy_in(ext2_filsys fs, int argc, char *argv[]); 12.28 +int copy_out(ext2_filsys fs, int argc, char *argv[]); 12.29 +int list(ext2_filsys fs, int argc, char *argv[]); 12.30 +int make_dirs(ext2_filsys fs, int argc, char *argv[]); 12.31 +int remove_dirs(ext2_filsys fs, int argc, char *argv[]); 12.32 +int remove_non_dirs(ext2_filsys fs, int argc, char *argv[]); 12.33 +int stat_objects(ext2_filsys fs, int argc, char *argv[]); 12.34 + 12.35 +/* vim: tabstop=4 expandtab shiftwidth=4 12.36 +*/
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 13.2 +++ b/libe2access/host/session.c Sun Mar 06 01:30:32 2022 +0100 13.3 @@ -0,0 +1,79 @@ 13.4 +/* 13.5 + * Session utilities. 13.6 + * 13.7 + * Copyright (C) 2022 Paul Boddie <paul@boddie.org.uk> 13.8 + * 13.9 + * This program is free software; you can redistribute it and/or 13.10 + * modify it under the terms of the GNU General Public License as 13.11 + * published by the Free Software Foundation; either version 2 of 13.12 + * the License, or (at your option) any later version. 13.13 + * 13.14 + * This program is distributed in the hope that it will be useful, 13.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13.17 + * GNU General Public License for more details. 13.18 + * 13.19 + * You should have received a copy of the GNU General Public License 13.20 + * along with this program; if not, write to the Free Software 13.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 13.22 + * Boston, MA 02110-1301, USA 13.23 + */ 13.24 + 13.25 +#include <stdio.h> 13.26 +#include <stdlib.h> 13.27 +#include <string.h> 13.28 +#include <unistd.h> 13.29 + 13.30 +#include "session.h" 13.31 + 13.32 + 13.33 + 13.34 +/* Alternative metadata set by options. */ 13.35 + 13.36 +struct metadata md; 13.37 + 13.38 +/* Common buffer properties. */ 13.39 + 13.40 +const int BUFSIZE = 4096; 13.41 + 13.42 + 13.43 + 13.44 +/* Parse program options. */ 13.45 + 13.46 +int parse_options(int argc, char *argv[]) 13.47 +{ 13.48 + int opt; 13.49 + 13.50 + md.have_uid = 0; 13.51 + md.have_gid = 0; 13.52 + md.mask = 0000; 13.53 + 13.54 + while ((opt = getopt(argc, argv, "g:m:u:")) != -1) 13.55 + { 13.56 + switch (opt) 13.57 + { 13.58 + case 'g': 13.59 + md.gid = atoi(optarg); 13.60 + md.have_gid = 1; 13.61 + break; 13.62 + 13.63 + case 'm': 13.64 + md.mask = strtol(optarg, NULL, 0); 13.65 + break; 13.66 + 13.67 + case 'u': 13.68 + md.uid = atoi(optarg); 13.69 + md.have_uid = 1; 13.70 + break; 13.71 + 13.72 + default: 13.73 + fprintf(stderr, "Option not recognised: %s\n", argv[optind]); 13.74 + return -1; 13.75 + } 13.76 + } 13.77 + 13.78 + return 0; 13.79 +} 13.80 + 13.81 +/* vim: tabstop=4 expandtab shiftwidth=4 13.82 +*/
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 14.2 +++ b/libe2access/host/session.h Sun Mar 06 01:30:32 2022 +0100 14.3 @@ -0,0 +1,39 @@ 14.4 +/* 14.5 + * Common session details. 14.6 + * 14.7 + * Copyright (C) 2022 Paul Boddie <paul@boddie.org.uk> 14.8 + * 14.9 + * This program is free software; you can redistribute it and/or 14.10 + * modify it under the terms of the GNU General Public License as 14.11 + * published by the Free Software Foundation; either version 2 of 14.12 + * the License, or (at your option) any later version. 14.13 + * 14.14 + * This program is distributed in the hope that it will be useful, 14.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14.17 + * GNU General Public License for more details. 14.18 + * 14.19 + * You should have received a copy of the GNU General Public License 14.20 + * along with this program; if not, write to the Free Software 14.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 14.22 + * Boston, MA 02110-1301, USA 14.23 + */ 14.24 + 14.25 +#pragma once 14.26 + 14.27 +#include <sys/types.h> 14.28 + 14.29 +/* Alternative metadata set by options. */ 14.30 + 14.31 +struct metadata 14.32 +{ 14.33 + uid_t uid; 14.34 + gid_t gid; 14.35 + mode_t mask; 14.36 + int have_uid, have_gid; 14.37 +}; 14.38 + 14.39 +int parse_options(int argc, char *argv[]); 14.40 + 14.41 +/* vim: tabstop=4 expandtab shiftwidth=4 14.42 +*/