# HG changeset patch # User Paul Boddie # Date 1646433689 -3600 # Node ID 55e4cd2dd48fb1bc07d55367c69381a154416358 # Parent 01efe5404c4ba3ec49f411e562ecaeb834e3f988 Reorganised the copy out operation, also supporting directory copying. diff -r 01efe5404c4b -r 55e4cd2dd48f libe2access/host/e2access.c --- a/libe2access/host/e2access.c Fri Mar 04 00:07:50 2022 +0100 +++ b/libe2access/host/e2access.c Fri Mar 04 23:41:29 2022 +0100 @@ -206,6 +206,25 @@ +/* Make a new directory in the external environment. */ + +static int _make_directory(const char *target, const char *basename, + ext2_filsys fs, ext2_ino_t ino) +{ + errcode_t retval; + struct ext2_inode inode; + char target_path[strlen(target) + strlen(basename) + 2]; + + sprintf(target_path, "%s/%s", target, basename); + + retval = ext2fs_read_inode(fs, ino, &inode); + + if (retval) + return retval; + + return mkdir(target_path, inode.i_mode); +} + /* Make a new object using the given function. */ static int _make_object(ext2_filsys fs, const char *filename, @@ -378,25 +397,60 @@ return 0; } +/* Copy a file from the filesystem into the external environment. */ + +static int _copy_out(ext2_filsys fs, const char *source, const char *target, + int target_is_file) +{ + ext2_ino_t ino_source; + + if (image_find_by_path(fs, source, &ino_source)) + { + fprintf(stderr, "Failed to find file: %s\n", source); + return 1; + } + + /* Test whether the filename references a file. */ + + if (image_isdir_by_path(fs, source)) + { + if (_make_directory(target, path_basename(source), fs, ino_source)) + { + fprintf(stderr, "Failed to make directory: %s/%s\n", target, + path_basename(source)); + return 1; + } + } + else if (image_isfile_by_path(fs, source)) + { + if (copy_file_out(target, source, target_is_file, fs, ino_source)) + { + fprintf(stderr, "Failed to read from file: %s\n", source); + return 1; + } + } + else + { + fprintf(stderr, "Object type not supported: %s\n", source); + return 1; + } + + /* NOTE: Overwrite/update metadata where appropriate. */ + + return 0; +} + /* Copy source files out of the filesystem image into the external environment. */ int copy_out(ext2_filsys fs, int argc, char *argv[]) { + int i; + /* Target filename details. */ char *target = argv[argc - 1]; int target_is_file; - /* Target file and directory details. */ - - ext2_file_t file; - ext2_ino_t ino_file; - - /* Source file details. */ - - const char *path; - int i; - /* Locate the target and test whether it is a directory. */ if (!isdir(target)) @@ -422,37 +476,11 @@ else target_is_file = 0; - /* For each source filename, test whether it references a file. */ - - for (i = 0; i < argc - 1; i++) - { - if (!image_isfile_by_path(fs, argv[i])) - { - fprintf(stderr, "Source is not a file: %s\n", argv[i]); - return 1; - } - } - /* Copy each source file to the target directory. */ for (i = 0; i < argc - 1; i++) - { - path = argv[i]; - - if (image_find_by_path(fs, path, &ino_file)) - { - fprintf(stderr, "Failed to find file: %s\n", argv[i]); + if (_copy_out(fs, argv[i], target, target_is_file)) return 1; - } - - if (copy_file_out(target, argv[i], target_is_file, fs, ino_file)) - { - fprintf(stderr, "Failed to read from file: %s\n", argv[i]); - return 1; - } - - /* NOTE: Overwrite/update metadata where appropriate. */ - } return 0; }