dissect: add --list option

New option to print the paths of all the files and directories in the image to
stdout.
This commit is contained in:
Antonio Alvarez Feijoo 2022-10-20 08:07:37 +02:00 committed by Luca Boccassi
parent fad1ce5c58
commit 0cf1692493
3 changed files with 71 additions and 7 deletions

View file

@ -31,6 +31,9 @@
<cmdsynopsis>
<command>systemd-dissect <arg choice="opt" rep="repeat">OPTIONS</arg> <option>--umount</option> <arg choice="plain"><replaceable>PATH</replaceable></arg></command>
</cmdsynopsis>
<cmdsynopsis>
<command>systemd-dissect <arg choice="opt" rep="repeat">OPTIONS</arg> <option>--list</option> <arg choice="plain"><replaceable>IMAGE</replaceable></arg></command>
</cmdsynopsis>
<cmdsynopsis>
<command>systemd-dissect <arg choice="opt" rep="repeat">OPTIONS</arg> <option>--copy-from</option> <arg choice="plain"><replaceable>IMAGE</replaceable></arg> <arg choice="plain"><replaceable>PATH</replaceable></arg> <arg choice="opt"><replaceable>TARGET</replaceable></arg></command>
</cmdsynopsis>
@ -149,6 +152,14 @@
<listitem><para>This is a shortcut for <option>--umount --rmdir</option>.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--list</option></term>
<term><option>-l</option></term>
<listitem><para>Prints the paths of all the files and directories in the specified OS image to
standard output.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--copy-from</option></term>
<term><option>-x</option></term>

View file

@ -35,6 +35,7 @@ _systemd_dissect() {
--rmdir'
[ARG]='-m --mount -M
-u --umount -U
-l --list
-x --copy-from
-a --copy-to
--fsck
@ -50,7 +51,7 @@ _systemd_dissect() {
if __contains_word "$prev_1" ${OPTS[ARG]}; then
case $prev_1 in
-m|--mount|-M|-x|--copy-from|-a|--copy-to|--verity-data)
-l|--list|-m|--mount|-M|-x|--copy-from|-a|--copy-to|--verity-data)
comps=$(compgen -A file -- "$cur")
compopt -o filenames
;;

View file

@ -35,6 +35,7 @@
#include "parse-util.h"
#include "path-util.h"
#include "pretty-print.h"
#include "recurse-dir.h"
#include "stat-util.h"
#include "string-util.h"
#include "strv.h"
@ -47,6 +48,7 @@ static enum {
ACTION_DISSECT,
ACTION_MOUNT,
ACTION_UMOUNT,
ACTION_LIST,
ACTION_COPY_FROM,
ACTION_COPY_TO,
} arg_action = ACTION_DISSECT;
@ -80,6 +82,7 @@ static int help(void) {
printf("%1$s [OPTIONS...] IMAGE\n"
"%1$s [OPTIONS...] --mount IMAGE PATH\n"
"%1$s [OPTIONS...] --umount PATH\n"
"%1$s [OPTIONS...] --list IMAGE\n"
"%1$s [OPTIONS...] --copy-from IMAGE PATH [TARGET]\n"
"%1$s [OPTIONS...] --copy-to IMAGE [SOURCE] PATH\n\n"
"%5$sDissect a Discoverable Disk Image (DDI).%6$s\n\n"
@ -108,6 +111,8 @@ static int help(void) {
" -M Shortcut for --mount --mkdir\n"
" -u --umount Unmount the image from the specified directory\n"
" -U Shortcut for --umount --rmdir\n"
" -l --list List all the files and directories of the specified\n"
" OS image\n"
" -x --copy-from Copy files from image to host\n"
" -a --copy-to Copy files from host to image\n"
"\nSee the %2$s for details.\n",
@ -154,6 +159,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "verity-data", required_argument, NULL, ARG_VERITY_DATA },
{ "mkdir", no_argument, NULL, ARG_MKDIR },
{ "rmdir", no_argument, NULL, ARG_RMDIR },
{ "list", no_argument, NULL, 'l' },
{ "copy-from", no_argument, NULL, 'x' },
{ "copy-to", no_argument, NULL, 'a' },
{ "json", required_argument, NULL, ARG_JSON },
@ -165,7 +171,7 @@ static int parse_argv(int argc, char *argv[]) {
assert(argc >= 0);
assert(argv);
while ((c = getopt_long(argc, argv, "hmurMUxa", options, NULL)) >= 0) {
while ((c = getopt_long(argc, argv, "hmurMUlxa", options, NULL)) >= 0) {
switch (c) {
@ -211,6 +217,11 @@ static int parse_argv(int argc, char *argv[]) {
arg_rmdir = true;
break;
case 'l':
arg_action = ACTION_LIST;
arg_flags |= DISSECT_IMAGE_READ_ONLY;
break;
case 'x':
arg_action = ACTION_COPY_FROM;
arg_flags |= DISSECT_IMAGE_READ_ONLY;
@ -353,6 +364,15 @@ static int parse_argv(int argc, char *argv[]) {
arg_path = argv[optind];
break;
case ACTION_LIST:
if (optind + 1 != argc)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Expected an image file path as only argument.");
arg_image = argv[optind];
arg_flags |= DISSECT_IMAGE_READ_ONLY | DISSECT_IMAGE_REQUIRE_ROOT;
break;
case ACTION_COPY_FROM:
if (argc < optind + 2 || argc > optind + 3)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
@ -685,7 +705,26 @@ static int action_mount(DissectedImage *m, LoopDevice *d) {
return 0;
}
static int action_copy(DissectedImage *m, LoopDevice *d) {
static int list_print_item(
RecurseDirEvent event,
const char *path,
int dir_fd,
int inode_fd,
const struct dirent *de,
const struct statx *sx,
void *userdata) {
assert_se(path);
if (event == RECURSE_DIR_ENTER)
printf("%s/\n", path);
else if (event == RECURSE_DIR_ENTRY)
printf("%s\n", path);
return RECURSE_DIR_CONTINUE;
}
static int action_list_or_copy(DissectedImage *m, LoopDevice *d) {
_cleanup_(umount_and_rmdir_and_freep) char *mounted_dir = NULL;
_cleanup_(rmdir_and_freep) char *created_dir = NULL;
_cleanup_free_ char *temp = NULL;
@ -774,13 +813,11 @@ static int action_copy(DissectedImage *m, LoopDevice *d) {
/* When this is a regular file we don't copy ownership! */
} else {
} else if (arg_action == ACTION_COPY_TO) {
_cleanup_close_ int source_fd = -1, target_fd = -1;
_cleanup_close_ int dfd = -1;
_cleanup_free_ char *dn = NULL;
assert(arg_action == ACTION_COPY_TO);
r = path_extract_directory(arg_target, &dn);
if (r < 0)
return log_error_errno(r, "Failed to extract directory name from target path '%s': %m", arg_target);
@ -842,6 +879,20 @@ static int action_copy(DissectedImage *m, LoopDevice *d) {
(void) copy_times(source_fd, target_fd, 0);
/* When this is a regular file we don't copy ownership! */
} else {
_cleanup_close_ int dfd = -1;
_cleanup_strv_free_ char **list_dir = NULL;
assert(arg_action == ACTION_LIST);
dfd = open(mounted_dir, O_DIRECTORY|O_CLOEXEC|O_RDONLY);
if (dfd < 0)
return log_error_errno(errno, "Failed to open mount directory: %m");
r = recurse_dir(dfd, NULL, 0, UINT_MAX, RECURSE_DIR_SORT|RECURSE_DIR_ENSURE_TYPE|RECURSE_DIR_SAME_MOUNT, list_print_item, &list_dir);
if (r < 0)
return log_error_errno(r, "Failed to list image: %m");
}
return 0;
@ -961,9 +1012,10 @@ static int run(int argc, char *argv[]) {
r = action_mount(m, d);
break;
case ACTION_LIST:
case ACTION_COPY_FROM:
case ACTION_COPY_TO:
r = action_copy(m, d);
r = action_list_or_copy(m, d);
break;
default: