#include "mkdir.h"
#include "mount-util.h"
#include "namespace-util.h"
+#include "parse-argument.h"
#include "parse-util.h"
#include "path-util.h"
#include "pretty-print.h"
static const char *arg_target = NULL;
static DissectImageFlags arg_flags = DISSECT_IMAGE_REQUIRE_ROOT|DISSECT_IMAGE_DISCARD_ON_LOOP|DISSECT_IMAGE_RELAX_VAR_CHECK|DISSECT_IMAGE_FSCK;
static VeritySettings arg_verity_settings = VERITY_SETTINGS_DEFAULT;
-static bool arg_json = false;
-static JsonFormatFlags arg_json_format_flags = 0;
+static JsonFormatFlags arg_json_format_flags = JSON_FORMAT_OFF;
+static PagerFlags arg_pager_flags = 0;
+static bool arg_legend = true;
STATIC_DESTRUCTOR_REGISTER(arg_verity_settings, verity_settings_done);
"%1$s [OPTIONS...] --copy-to IMAGE [SOURCE] PATH\n\n"
"%5$sDissect a file system OS image.%6$s\n\n"
"%3$sOptions:%4$s\n"
+ " --no-pager Do not pipe output into a pager\n"
+ " --no-legend Do not show the headers and footers\n"
" -r --read-only Mount read-only\n"
" --fsck=BOOL Run fsck before mounting\n"
" --mkdir Make mount directory before mounting, if missing\n"
" -M Shortcut for --mount --mkdir\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"
- , program_invocation_short_name
- , link
- , ansi_underline(), ansi_normal()
- , ansi_highlight(), ansi_normal());
+ "\nSee the %2$s for details.\n",
+ program_invocation_short_name,
+ link,
+ ansi_underline(),
+ ansi_normal(),
+ ansi_highlight(),
+ ansi_normal());
return 0;
}
enum {
ARG_VERSION = 0x100,
+ ARG_NO_PAGER,
+ ARG_NO_LEGEND,
ARG_DISCARD,
ARG_FSCK,
ARG_ROOT_HASH,
static const struct option options[] = {
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, ARG_VERSION },
+ { "no-pager", no_argument, NULL, ARG_NO_PAGER },
+ { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
{ "mount", no_argument, NULL, 'm' },
{ "read-only", no_argument, NULL, 'r' },
{ "discard", required_argument, NULL, ARG_DISCARD },
case ARG_VERSION:
return version();
+ case ARG_NO_PAGER:
+ arg_pager_flags |= PAGER_DISABLE;
+ break;
+
+ case ARG_NO_LEGEND:
+ arg_legend = false;
+ break;
+
case 'm':
arg_action = ACTION_MOUNT;
break;
}
case ARG_VERITY_DATA:
- r = parse_path_argument_and_warn(optarg, false, &arg_verity_settings.data_path);
+ r = parse_path_argument(optarg, false, &arg_verity_settings.data_path);
if (r < 0)
return r;
break;
break;
case ARG_JSON:
- if (streq(optarg, "pretty")) {
- arg_json = true;
- arg_json_format_flags = JSON_FORMAT_PRETTY|JSON_FORMAT_COLOR_AUTO;
- } else if (streq(optarg, "short")) {
- arg_json = true;
- arg_json_format_flags = JSON_FORMAT_NEWLINE;
- } else if (streq(optarg, "off")) {
- arg_json = false;
- arg_json_format_flags = 0;
- } else if (streq(optarg, "help")) {
- puts("pretty\n"
- "short\n"
- "off");
- return 0;
- } else
- return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown argument to --json=: %s", optarg);
+ r = parse_json_argument(optarg, &arg_json_format_flags);
+ if (r <= 0)
+ return r;
break;
assert(m);
assert(d);
- if (!arg_json)
+ if (arg_json_format_flags & (JSON_FORMAT_OFF|JSON_FORMAT_PRETTY|JSON_FORMAT_PRETTY_AUTO))
+ (void) pager_open(arg_pager_flags);
+
+ if (arg_json_format_flags & JSON_FORMAT_OFF)
printf(" Name: %s\n", basename(arg_image));
if (ioctl(d->fd, BLKGETSIZE64, &size) < 0)
log_debug_errno(errno, "Failed to query size of loopback device: %m");
- else if (!arg_json) {
+ else if (arg_json_format_flags & JSON_FORMAT_OFF) {
char s[FORMAT_BYTES_MAX];
printf(" Size: %s\n", format_bytes(s, sizeof(s), size));
}
- if (!arg_json)
+ if (arg_json_format_flags & JSON_FORMAT_OFF)
putc('\n', stdout);
r = dissected_image_acquire_metadata(m);
log_warning_errno(r, "OS image is currently in use, proceeding without showing OS image metadata.");
else if (r < 0)
return log_error_errno(r, "Failed to acquire image metadata: %m");
- else if (!arg_json) {
+ else if (arg_json_format_flags & JSON_FORMAT_OFF) {
if (m->hostname)
printf(" Hostname: %s\n", m->hostname);
*p, *q);
}
+ if (!strv_isempty(m->extension_release)) {
+ char **p, **q;
+
+ STRV_FOREACH_PAIR(p, q, m->extension_release)
+ printf("%s %s=%s\n",
+ p == m->extension_release ? "Extension Release:" : " ",
+ *p, *q);
+ }
+
if (m->hostname ||
!sd_id128_is_null(m->machine_id) ||
!strv_isempty(m->machine_info) ||
+ !strv_isempty(m->extension_release) ||
!strv_isempty(m->os_release))
putc('\n', stdout);
} else {
- _cleanup_(json_variant_unrefp) JsonVariant *mi = NULL, *osr = NULL;
+ _cleanup_(json_variant_unrefp) JsonVariant *mi = NULL, *osr = NULL, *exr = NULL;
if (!strv_isempty(m->machine_info)) {
r = strv_pair_to_json(m->machine_info, &mi);
return log_oom();
}
+ if (!strv_isempty(m->extension_release)) {
+ r = strv_pair_to_json(m->extension_release, &exr);
+ if (r < 0)
+ return log_oom();
+ }
+
r = json_build(&v, JSON_BUILD_OBJECT(
JSON_BUILD_PAIR("name", JSON_BUILD_STRING(basename(arg_image))),
JSON_BUILD_PAIR("size", JSON_BUILD_INTEGER(size)),
JSON_BUILD_PAIR_CONDITION(m->hostname, "hostname", JSON_BUILD_STRING(m->hostname)),
JSON_BUILD_PAIR_CONDITION(!sd_id128_is_null(m->machine_id), "machineId", JSON_BUILD_ID128(m->machine_id)),
JSON_BUILD_PAIR_CONDITION(mi, "machineInfo", JSON_BUILD_VARIANT(mi)),
- JSON_BUILD_PAIR_CONDITION(osr, "osRelease", JSON_BUILD_VARIANT(osr))));
+ JSON_BUILD_PAIR_CONDITION(osr, "osRelease", JSON_BUILD_VARIANT(osr)),
+ JSON_BUILD_PAIR_CONDITION(exr, "extensionRelease", JSON_BUILD_VARIANT(exr))));
if (r < 0)
return log_oom();
}
return table_log_add_error(r);
}
- if (arg_json) {
+ if (arg_json_format_flags & JSON_FORMAT_OFF) {
+ (void) table_set_header(t, arg_legend);
+
+ r = table_print(t, NULL);
+ if (r < 0)
+ return table_log_print_error(r);
+ } else {
_cleanup_(json_variant_unrefp) JsonVariant *jt = NULL;
r = table_to_json(t, &jt);
return log_oom();
json_variant_dump(v, arg_json_format_flags, stdout, NULL);
- } else {
- r = table_print(t, stdout);
- if (r < 0)
- return log_error_errno(r, "Failed to dump table: %m");
}
return 0;
/* Copying to stdout? */
if (streq(arg_target, "-")) {
- r = copy_bytes(source_fd, STDOUT_FILENO, (uint64_t) -1, COPY_REFLINK);
+ r = copy_bytes(source_fd, STDOUT_FILENO, UINT64_MAX, COPY_REFLINK);
if (r < 0)
return log_error_errno(r, "Failed to copy bytes from %s in mage '%s' to stdout: %m", arg_source, arg_image);
if (target_fd < 0)
return log_error_errno(errno, "Failed to create regular file at target path '%s': %m", arg_target);
- r = copy_bytes(source_fd, target_fd, (uint64_t) -1, COPY_REFLINK);
+ r = copy_bytes(source_fd, target_fd, UINT64_MAX, COPY_REFLINK);
if (r < 0)
return log_error_errno(r, "Failed to copy bytes from %s in mage '%s' to '%s': %m", arg_source, arg_image, arg_target);
if (target_fd < 0)
return log_error_errno(errno, "Failed to open target file '%s': %m", arg_target);
- r = copy_bytes(STDIN_FILENO, target_fd, (uint64_t) -1, COPY_REFLINK);
+ r = copy_bytes(STDIN_FILENO, target_fd, UINT64_MAX, COPY_REFLINK);
if (r < 0)
return log_error_errno(r, "Failed to copy bytes from stdin to '%s' in image '%s': %m", arg_target, arg_image);
if (target_fd < 0)
return log_error_errno(errno, "Failed to open target file '%s': %m", arg_target);
- r = copy_bytes(source_fd, target_fd, (uint64_t) -1, COPY_REFLINK);
+ r = copy_bytes(source_fd, target_fd, UINT64_MAX, COPY_REFLINK);
if (r < 0)
return log_error_errno(r, "Failed to copy bytes from '%s' to '%s' in image '%s': %m", arg_source, arg_target, arg_image);