mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-14 09:14:40 +00:00
Split out the console handling to a new module
This simplifies a lot of confusion.
This commit is contained in:
parent
b25e0f3a28
commit
caaeb1ea16
@ -8,11 +8,11 @@ plugins/tpm/fu-tpm-eventlog.c
|
||||
plugins/uefi-capsule/fu-uefi-capsule-plugin.c
|
||||
plugins/uefi-capsule/fu-uefi-tool.c
|
||||
plugins/uefi-dbx/fu-dbxtool.c
|
||||
src/fu-console.c
|
||||
src/fu-debug.c
|
||||
src/fu-engine-helper.c
|
||||
src/fu-main.c
|
||||
src/fu-offline.c
|
||||
src/fu-progressbar.c
|
||||
src/fu-remote-list.c
|
||||
src/fu-security-attr-common.c
|
||||
src/fu-tool.c
|
||||
|
779
src/fu-console.c
Normal file
779
src/fu-console.c
Normal file
@ -0,0 +1,779 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#define G_LOG_DOMAIN "FuProgressBar"
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "fu-console.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <wchar.h>
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
struct _FuConsole {
|
||||
GObject parent_instance;
|
||||
GMainContext *main_ctx;
|
||||
FwupdStatus status;
|
||||
gboolean spinner_count_up; /* width in visible chars */
|
||||
guint spinner_idx; /* width in visible chars */
|
||||
guint length_percentage; /* width in visible chars */
|
||||
guint length_status; /* width in visible chars */
|
||||
guint percentage;
|
||||
GSource *timer_source;
|
||||
gint64 last_animated; /* monotonic */
|
||||
GTimer *time_elapsed;
|
||||
gdouble last_estimate;
|
||||
gboolean interactive;
|
||||
gboolean contents_to_clear;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(FuConsole, fu_console, G_TYPE_OBJECT)
|
||||
|
||||
gboolean
|
||||
fu_console_setup(FuConsole *self, GError **error)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
HANDLE hOut;
|
||||
DWORD dwMode = 0;
|
||||
|
||||
/* enable VT sequences */
|
||||
hOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
if (hOut == INVALID_HANDLE_VALUE) {
|
||||
g_set_error(error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_SUPPORTED,
|
||||
"failed to get stdout [%u]",
|
||||
(guint)GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
if (!GetConsoleMode(hOut, &dwMode)) {
|
||||
g_set_error(error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_SUPPORTED,
|
||||
"failed to get mode [%u]",
|
||||
(guint)GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
|
||||
if (!SetConsoleMode(hOut, dwMode)) {
|
||||
g_set_error(error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_SUPPORTED,
|
||||
"failed to set mode [%u]",
|
||||
(guint)GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
if (!SetConsoleOutputCP(CP_UTF8)) {
|
||||
g_set_error(error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_SUPPORTED,
|
||||
"failed to set output UTF-8 [%u]",
|
||||
(guint)GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
if (!SetConsoleCP(CP_UTF8)) {
|
||||
g_set_error(error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_SUPPORTED,
|
||||
"failed to set UTF-8 [%u]",
|
||||
(guint)GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
#else
|
||||
if (isatty(fileno(stdout)) == 0) {
|
||||
g_set_error_literal(error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "not a TTY");
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
/* success */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_console_erase_line(FuConsole *self)
|
||||
{
|
||||
if (!self->interactive)
|
||||
return;
|
||||
g_print("\033[G");
|
||||
}
|
||||
|
||||
static void
|
||||
fu_console_reset_line(FuConsole *self)
|
||||
{
|
||||
if (self->contents_to_clear) {
|
||||
fu_console_erase_line(self);
|
||||
g_print("\n");
|
||||
self->contents_to_clear = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fu_console_print_kv(FuConsole *self, const gchar *title, const gchar *msg)
|
||||
{
|
||||
gsize title_len;
|
||||
g_auto(GStrv) lines = NULL;
|
||||
|
||||
if (msg == NULL)
|
||||
return;
|
||||
fu_console_reset_line(self);
|
||||
g_print("%s:", title);
|
||||
|
||||
/* pad */
|
||||
title_len = fu_strwidth(title) + 1;
|
||||
lines = g_strsplit(msg, "\n", -1);
|
||||
for (guint j = 0; lines[j] != NULL; j++) {
|
||||
for (gsize i = title_len; i < 25; i++)
|
||||
g_print(" ");
|
||||
g_print("%s\n", lines[j]);
|
||||
title_len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
guint
|
||||
fu_console_input_uint(FuConsole *self, guint maxnum)
|
||||
{
|
||||
gint retval;
|
||||
guint answer = 0;
|
||||
|
||||
do {
|
||||
char buffer[64];
|
||||
|
||||
/* swallow the \n at end of line too */
|
||||
if (!fgets(buffer, sizeof(buffer), stdin))
|
||||
break;
|
||||
if (strlen(buffer) == sizeof(buffer) - 1)
|
||||
continue;
|
||||
|
||||
/* get a number */
|
||||
retval = sscanf(buffer, "%u", &answer);
|
||||
|
||||
/* positive */
|
||||
if (retval == 1 && answer <= maxnum)
|
||||
break;
|
||||
|
||||
/* TRANSLATORS: the user isn't reading the question */
|
||||
fu_console_print_full(self,
|
||||
FU_CONSOLE_PRINT_FLAG_NONE,
|
||||
_("Please enter a number from 0 to %u: "),
|
||||
maxnum);
|
||||
} while (TRUE);
|
||||
return answer;
|
||||
}
|
||||
|
||||
gboolean
|
||||
fu_console_input_bool(FuConsole *self, gboolean def, const gchar *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
g_autofree gchar *tmp = NULL;
|
||||
g_autoptr(GString) str = g_string_new(NULL);
|
||||
|
||||
va_start(args, format);
|
||||
tmp = g_strdup_vprintf(format, args);
|
||||
va_end(args);
|
||||
|
||||
g_string_append_printf(str, "%s [%s]: ", tmp, def ? "Y|n" : "y|N");
|
||||
fu_console_print_literal(self, str->str);
|
||||
|
||||
do {
|
||||
char buffer[4];
|
||||
if (!fgets(buffer, sizeof(buffer), stdin))
|
||||
continue;
|
||||
if (strlen(buffer) == sizeof(buffer) - 1)
|
||||
continue;
|
||||
if (g_strcmp0(buffer, "\n") == 0)
|
||||
return def;
|
||||
buffer[0] = g_ascii_toupper(buffer[0]);
|
||||
if (g_strcmp0(buffer, "Y\n") == 0)
|
||||
return TRUE;
|
||||
if (g_strcmp0(buffer, "N\n") == 0)
|
||||
return FALSE;
|
||||
} while (TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static GPtrArray *
|
||||
fu_console_strsplit_words(const gchar *text, guint line_len)
|
||||
{
|
||||
g_auto(GStrv) tokens = NULL;
|
||||
g_autoptr(GPtrArray) lines = g_ptr_array_new_with_free_func(g_free);
|
||||
g_autoptr(GString) curline = g_string_new(NULL);
|
||||
|
||||
/* sanity check */
|
||||
if (text == NULL || text[0] == '\0')
|
||||
return NULL;
|
||||
if (line_len == 0)
|
||||
return NULL;
|
||||
|
||||
/* tokenize the string */
|
||||
tokens = g_strsplit(text, " ", -1);
|
||||
for (guint i = 0; tokens[i] != NULL; i++) {
|
||||
/* current line plus new token is okay */
|
||||
if (curline->len + fu_strwidth(tokens[i]) < line_len) {
|
||||
g_string_append_printf(curline, "%s ", tokens[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* too long, so remove space, add newline and dump */
|
||||
if (curline->len > 0)
|
||||
g_string_truncate(curline, curline->len - 1);
|
||||
g_ptr_array_add(lines, g_strdup(curline->str));
|
||||
g_string_truncate(curline, 0);
|
||||
g_string_append_printf(curline, "%s ", tokens[i]);
|
||||
}
|
||||
|
||||
/* any incomplete line? */
|
||||
if (curline->len > 0) {
|
||||
g_string_truncate(curline, curline->len - 1);
|
||||
g_ptr_array_add(lines, g_strdup(curline->str));
|
||||
}
|
||||
return g_steal_pointer(&lines);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_console_box_line(const gchar *start,
|
||||
const gchar *text,
|
||||
const gchar *end,
|
||||
const gchar *padding,
|
||||
guint width)
|
||||
{
|
||||
guint offset = 0;
|
||||
if (start != NULL) {
|
||||
offset += fu_strwidth(start);
|
||||
g_print("%s", start);
|
||||
}
|
||||
if (text != NULL) {
|
||||
offset += fu_strwidth(text);
|
||||
g_print("%s", text);
|
||||
}
|
||||
if (end != NULL)
|
||||
offset += fu_strwidth(end);
|
||||
for (guint i = offset; i < width; i++)
|
||||
g_print("%s", padding);
|
||||
if (end != NULL)
|
||||
g_print("%s\n", end);
|
||||
}
|
||||
|
||||
void
|
||||
fu_console_line(FuConsole *self, guint width)
|
||||
{
|
||||
g_autoptr(GString) str = g_string_new_len(NULL, width);
|
||||
for (guint i = 0; i < width; i++)
|
||||
g_string_append(str, "─");
|
||||
fu_console_print_literal(self, str->str);
|
||||
}
|
||||
|
||||
void
|
||||
fu_console_box(FuConsole *self, const gchar *title, const gchar *body, guint width)
|
||||
{
|
||||
/* nothing to do */
|
||||
if (title == NULL && body == NULL)
|
||||
return;
|
||||
|
||||
/* header */
|
||||
fu_console_reset_line(self);
|
||||
fu_console_box_line("╔", NULL, "╗", "═", width);
|
||||
|
||||
/* optional title */
|
||||
if (title != NULL) {
|
||||
g_autoptr(GPtrArray) lines = fu_console_strsplit_words(title, width - 4);
|
||||
for (guint j = 0; j < lines->len; j++) {
|
||||
const gchar *line = g_ptr_array_index(lines, j);
|
||||
fu_console_box_line("║ ", line, " ║", " ", width);
|
||||
}
|
||||
}
|
||||
|
||||
/* join */
|
||||
if (title != NULL && body != NULL)
|
||||
fu_console_box_line("╠", NULL, "╣", "═", width);
|
||||
|
||||
/* optional body */
|
||||
if (body != NULL) {
|
||||
gboolean has_nonempty = FALSE;
|
||||
g_auto(GStrv) split = g_strsplit(body, "\n", -1);
|
||||
for (guint i = 0; split[i] != NULL; i++) {
|
||||
g_autoptr(GPtrArray) lines = fu_console_strsplit_words(split[i], width - 4);
|
||||
if (lines == NULL) {
|
||||
if (has_nonempty) {
|
||||
fu_console_box_line("║ ", NULL, " ║", " ", width);
|
||||
has_nonempty = FALSE;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
for (guint j = 0; j < lines->len; j++) {
|
||||
const gchar *line = g_ptr_array_index(lines, j);
|
||||
fu_console_box_line("║ ", line, " ║", " ", width);
|
||||
}
|
||||
has_nonempty = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* footer */
|
||||
fu_console_box_line("╚", NULL, "╝", "═", width);
|
||||
}
|
||||
|
||||
static const gchar *
|
||||
fu_console_status_to_string(FwupdStatus status)
|
||||
{
|
||||
switch (status) {
|
||||
case FWUPD_STATUS_IDLE:
|
||||
/* TRANSLATORS: daemon is inactive */
|
||||
return _("Idle…");
|
||||
break;
|
||||
case FWUPD_STATUS_DECOMPRESSING:
|
||||
/* TRANSLATORS: decompressing the firmware file */
|
||||
return _("Decompressing…");
|
||||
break;
|
||||
case FWUPD_STATUS_LOADING:
|
||||
/* TRANSLATORS: parsing the firmware information */
|
||||
return _("Loading…");
|
||||
break;
|
||||
case FWUPD_STATUS_DEVICE_RESTART:
|
||||
/* TRANSLATORS: restarting the device to pick up new F/W */
|
||||
return _("Restarting device…");
|
||||
break;
|
||||
case FWUPD_STATUS_DEVICE_READ:
|
||||
/* TRANSLATORS: reading from the flash chips */
|
||||
return _("Reading…");
|
||||
break;
|
||||
case FWUPD_STATUS_DEVICE_WRITE:
|
||||
/* TRANSLATORS: writing to the flash chips */
|
||||
return _("Writing…");
|
||||
break;
|
||||
case FWUPD_STATUS_DEVICE_ERASE:
|
||||
/* TRANSLATORS: erasing contents of the flash chips */
|
||||
return _("Erasing…");
|
||||
break;
|
||||
case FWUPD_STATUS_DEVICE_VERIFY:
|
||||
/* TRANSLATORS: verifying we wrote the firmware correctly */
|
||||
return _("Verifying…");
|
||||
break;
|
||||
case FWUPD_STATUS_SCHEDULING:
|
||||
/* TRANSLATORS: scheduling an update to be done on the next boot */
|
||||
return _("Scheduling…");
|
||||
break;
|
||||
case FWUPD_STATUS_DOWNLOADING:
|
||||
/* TRANSLATORS: downloading from a remote server */
|
||||
return _("Downloading…");
|
||||
break;
|
||||
case FWUPD_STATUS_WAITING_FOR_AUTH:
|
||||
/* TRANSLATORS: waiting for user to authenticate */
|
||||
return _("Authenticating…");
|
||||
break;
|
||||
case FWUPD_STATUS_DEVICE_BUSY:
|
||||
/* TRANSLATORS: waiting for device to do something */
|
||||
return _("Waiting…");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* TRANSLATORS: current daemon status is unknown */
|
||||
return _("Unknown");
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_fu_status_is_predictable(FwupdStatus status)
|
||||
{
|
||||
if (status == FWUPD_STATUS_DEVICE_ERASE)
|
||||
return TRUE;
|
||||
if (status == FWUPD_STATUS_DEVICE_VERIFY)
|
||||
return TRUE;
|
||||
if (status == FWUPD_STATUS_DEVICE_READ)
|
||||
return TRUE;
|
||||
if (status == FWUPD_STATUS_DEVICE_WRITE)
|
||||
return TRUE;
|
||||
if (status == FWUPD_STATUS_DOWNLOADING)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_console_estimate_ready(FuConsole *self, guint percentage)
|
||||
{
|
||||
gdouble old;
|
||||
gdouble elapsed;
|
||||
|
||||
/* now invalid */
|
||||
if (percentage == 0 || percentage == 100) {
|
||||
g_timer_start(self->time_elapsed);
|
||||
self->last_estimate = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* allow-list things that make sense... */
|
||||
if (!_fu_status_is_predictable(self->status))
|
||||
return FALSE;
|
||||
|
||||
old = self->last_estimate;
|
||||
elapsed = g_timer_elapsed(self->time_elapsed, NULL);
|
||||
self->last_estimate = elapsed / percentage * (100 - percentage);
|
||||
|
||||
/* estimate is ready if we have decreased */
|
||||
return old > self->last_estimate;
|
||||
}
|
||||
|
||||
static gchar *
|
||||
fu_console_time_remaining_str(FuConsole *self)
|
||||
{
|
||||
/* less than 5 seconds remaining */
|
||||
if (self->last_estimate < 5)
|
||||
return NULL;
|
||||
|
||||
/* less than 60 seconds remaining */
|
||||
if (self->last_estimate < 60) {
|
||||
/* TRANSLATORS: time remaining for completing firmware flash */
|
||||
return g_strdup(_("Less than one minute remaining"));
|
||||
}
|
||||
|
||||
return g_strdup_printf(
|
||||
/* TRANSLATORS: more than a minute */
|
||||
ngettext("%.0f minute remaining", "%.0f minutes remaining", self->last_estimate / 60),
|
||||
self->last_estimate / 60);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_console_refresh(FuConsole *self)
|
||||
{
|
||||
const gchar *title;
|
||||
guint i;
|
||||
g_autoptr(GString) str = g_string_new(NULL);
|
||||
|
||||
/* sanity check */
|
||||
if (self->status == FWUPD_STATUS_IDLE || self->status == FWUPD_STATUS_UNKNOWN)
|
||||
return;
|
||||
|
||||
/* erase previous line */
|
||||
fu_console_erase_line(self);
|
||||
|
||||
/* add status */
|
||||
title = fu_console_status_to_string(self->status);
|
||||
g_string_append(str, title);
|
||||
for (i = fu_strwidth(str->str); i < self->length_status; i++)
|
||||
g_string_append_c(str, ' ');
|
||||
|
||||
/* add console */
|
||||
g_string_append(str, "[");
|
||||
if (self->percentage > 0) {
|
||||
for (i = 0; i < (self->length_percentage - 1) * self->percentage / 100; i++)
|
||||
g_string_append_c(str, '*');
|
||||
for (i = i + 1; i < self->length_percentage; i++)
|
||||
g_string_append_c(str, ' ');
|
||||
} else {
|
||||
const gchar chars[] = {
|
||||
'-',
|
||||
'\\',
|
||||
'|',
|
||||
'/',
|
||||
};
|
||||
for (i = 0; i < self->spinner_idx; i++)
|
||||
g_string_append_c(str, ' ');
|
||||
g_string_append_c(str, chars[i / 4 % G_N_ELEMENTS(chars)]);
|
||||
for (i = i + 1; i < self->length_percentage - 1; i++)
|
||||
g_string_append_c(str, ' ');
|
||||
}
|
||||
g_string_append_c(str, ']');
|
||||
|
||||
/* once we have good data show an estimate of time remaining */
|
||||
if (fu_console_estimate_ready(self, self->percentage)) {
|
||||
g_autofree gchar *remaining = fu_console_time_remaining_str(self);
|
||||
if (remaining != NULL)
|
||||
g_string_append_printf(str, " %s…", remaining);
|
||||
}
|
||||
|
||||
/* dump to screen */
|
||||
g_print("%s", str->str);
|
||||
self->contents_to_clear = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_console_print_full:
|
||||
* @self: a #FuConsole
|
||||
* @flags; a #FuConsolePrintFlags, e.g. %FU_CONSOLE_PRINT_FLAG_STDERR
|
||||
* @text: string
|
||||
*
|
||||
* Clears the console, and prints the text.
|
||||
**/
|
||||
void
|
||||
fu_console_print_full(FuConsole *self, FuConsolePrintFlags flags, const gchar *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
g_autoptr(GString) str = g_string_new(NULL);
|
||||
|
||||
va_start(args, format);
|
||||
g_string_append_vprintf(str, format, args);
|
||||
va_end(args);
|
||||
|
||||
if (flags & FU_CONSOLE_PRINT_FLAG_WARNING) {
|
||||
/* TRANSLATORS: this is a prefix on the console */
|
||||
g_autofree gchar *fmt = fu_console_color_format(_("WARNING"), FU_CONSOLE_COLOR_RED);
|
||||
g_string_prepend(str, ": ");
|
||||
g_string_prepend(str, fmt);
|
||||
flags |= FU_CONSOLE_PRINT_FLAG_STDERR;
|
||||
}
|
||||
|
||||
fu_console_reset_line(self);
|
||||
if (flags & FU_CONSOLE_PRINT_FLAG_STDERR) {
|
||||
g_printerr("%s", str->str);
|
||||
} else {
|
||||
g_print("%s", str->str);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fu_console_print_literal(FuConsole *self, const gchar *text)
|
||||
{
|
||||
fu_console_reset_line(self);
|
||||
g_print("%s\n", text);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_console_print:
|
||||
* @self: a #FuConsole
|
||||
* @text: string
|
||||
*
|
||||
* Clears the console, prints the text and prints a newline.
|
||||
**/
|
||||
void
|
||||
fu_console_print(FuConsole *self, const gchar *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
g_autofree gchar *tmp = NULL;
|
||||
|
||||
va_start(args, format);
|
||||
tmp = g_strdup_vprintf(format, args);
|
||||
va_end(args);
|
||||
fu_console_print_literal(self, tmp);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_console_set_progress_title:
|
||||
* @self: A #FuConsole
|
||||
* @title: A string
|
||||
*
|
||||
* Sets console title
|
||||
**/
|
||||
void
|
||||
fu_console_set_progress_title(FuConsole *self, const gchar *title)
|
||||
{
|
||||
fu_console_erase_line(self);
|
||||
g_print("%s\n", title);
|
||||
fu_console_refresh(self);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_console_set_main_context:
|
||||
* @self: A #FuConsole
|
||||
* @main_ctx: (nullable): main context
|
||||
*
|
||||
* Sets console main context to use for animations.
|
||||
**/
|
||||
void
|
||||
fu_console_set_main_context(FuConsole *self, GMainContext *main_ctx)
|
||||
{
|
||||
self->main_ctx = g_main_context_ref(main_ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_console_spin_inc(FuConsole *self)
|
||||
{
|
||||
/* reset */
|
||||
self->last_animated = g_get_monotonic_time();
|
||||
|
||||
/* up to down */
|
||||
if (self->spinner_count_up) {
|
||||
if (++self->spinner_idx > self->length_percentage - 3)
|
||||
self->spinner_count_up = FALSE;
|
||||
} else {
|
||||
if (--self->spinner_idx == 0)
|
||||
self->spinner_count_up = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_console_spin_cb(gpointer user_data)
|
||||
{
|
||||
FuConsole *self = FU_CONSOLE(user_data);
|
||||
|
||||
/* move the spinner index up to down */
|
||||
fu_console_spin_inc(self);
|
||||
|
||||
/* update the terminal */
|
||||
fu_console_refresh(self);
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_console_spin_end(FuConsole *self)
|
||||
{
|
||||
if (self->timer_source != NULL) {
|
||||
g_source_destroy(self->timer_source);
|
||||
self->timer_source = NULL;
|
||||
|
||||
/* reset when the spinner has been stopped */
|
||||
g_timer_start(self->time_elapsed);
|
||||
}
|
||||
|
||||
/* go back to the start when we next go into unknown percentage mode */
|
||||
self->spinner_idx = 0;
|
||||
self->spinner_count_up = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_console_spin_start(FuConsole *self)
|
||||
{
|
||||
if (self->timer_source != NULL)
|
||||
g_source_destroy(self->timer_source);
|
||||
self->timer_source = g_timeout_source_new(40);
|
||||
g_source_set_callback(self->timer_source, fu_console_spin_cb, self, NULL);
|
||||
g_source_attach(self->timer_source, self->main_ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_console_set_progress:
|
||||
* @self: A #FuConsole
|
||||
* @status: A #FwupdStatus
|
||||
* @percentage: unsigned integer
|
||||
*
|
||||
* Refreshes the progress bar with the new percentage and status.
|
||||
**/
|
||||
void
|
||||
fu_console_set_progress(FuConsole *self, FwupdStatus status, guint percentage)
|
||||
{
|
||||
g_return_if_fail(FU_IS_CONSOLE(self));
|
||||
|
||||
/* not useful */
|
||||
if (status == FWUPD_STATUS_UNKNOWN)
|
||||
return;
|
||||
|
||||
/* ignore duplicates */
|
||||
if (self->status == status && self->percentage == percentage)
|
||||
return;
|
||||
|
||||
/* cache */
|
||||
self->status = status;
|
||||
self->percentage = percentage;
|
||||
|
||||
/* dumb */
|
||||
if (!self->interactive) {
|
||||
g_printerr("%s: %u%%\n", fu_console_status_to_string(status), percentage);
|
||||
return;
|
||||
}
|
||||
|
||||
/* if the main loop isn't spinning and we've not had a chance to
|
||||
* execute the callback just do the refresh now manually */
|
||||
if (percentage == 0 && status != FWUPD_STATUS_IDLE &&
|
||||
self->status != FWUPD_STATUS_UNKNOWN) {
|
||||
if ((g_get_monotonic_time() - self->last_animated) / 1000 > 40) {
|
||||
fu_console_spin_inc(self);
|
||||
fu_console_refresh(self);
|
||||
}
|
||||
}
|
||||
|
||||
/* enable or disable the spinner timeout */
|
||||
if (percentage > 0) {
|
||||
fu_console_spin_end(self);
|
||||
} else {
|
||||
fu_console_spin_start(self);
|
||||
}
|
||||
|
||||
/* update the terminal */
|
||||
fu_console_refresh(self);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_console_set_interactive:
|
||||
* @self: A #FuConsole
|
||||
* @interactive: #gboolean
|
||||
*
|
||||
* Marks the console as interactive or not
|
||||
**/
|
||||
void
|
||||
fu_console_set_interactive(FuConsole *self, gboolean interactive)
|
||||
{
|
||||
g_return_if_fail(FU_IS_CONSOLE(self));
|
||||
self->interactive = interactive;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_console_set_status_length:
|
||||
* @self: A #FuConsole
|
||||
* @len: unsigned integer
|
||||
*
|
||||
* Sets the width of the progressbar status, which must be greater that 3.
|
||||
**/
|
||||
void
|
||||
fu_console_set_status_length(FuConsole *self, guint len)
|
||||
{
|
||||
g_return_if_fail(FU_IS_CONSOLE(self));
|
||||
g_return_if_fail(len > 3);
|
||||
self->length_status = len;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_console_set_percentage_length:
|
||||
* @self: A #FuConsole
|
||||
* @len: unsigned integer
|
||||
*
|
||||
* Sets the width of the progressbar percentage, which must be greater that 3.
|
||||
**/
|
||||
void
|
||||
fu_console_set_percentage_length(FuConsole *self, guint len)
|
||||
{
|
||||
g_return_if_fail(FU_IS_CONSOLE(self));
|
||||
g_return_if_fail(len > 3);
|
||||
self->length_percentage = len;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_console_init(FuConsole *self)
|
||||
{
|
||||
self->length_percentage = 40;
|
||||
self->length_status = 25;
|
||||
self->spinner_count_up = TRUE;
|
||||
self->time_elapsed = g_timer_new();
|
||||
self->interactive = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_console_finalize(GObject *obj)
|
||||
{
|
||||
FuConsole *self = FU_CONSOLE(obj);
|
||||
|
||||
fu_console_reset_line(self);
|
||||
if (self->timer_source != 0)
|
||||
g_source_destroy(self->timer_source);
|
||||
if (self->main_ctx != NULL)
|
||||
g_main_context_unref(self->main_ctx);
|
||||
g_timer_destroy(self->time_elapsed);
|
||||
|
||||
G_OBJECT_CLASS(fu_console_parent_class)->finalize(obj);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_console_class_init(FuConsoleClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS(klass);
|
||||
object_class->finalize = fu_console_finalize;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_console_new:
|
||||
*
|
||||
* Creates a new #FuConsole
|
||||
**/
|
||||
FuConsole *
|
||||
fu_console_new(void)
|
||||
{
|
||||
FuConsole *self;
|
||||
self = g_object_new(FU_TYPE_CONSOLE, NULL);
|
||||
return FU_CONSOLE(self);
|
||||
}
|
69
src/fu-console.h
Normal file
69
src/fu-console.h
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <fwupdplugin.h>
|
||||
|
||||
#define FU_TYPE_CONSOLE (fu_console_get_type())
|
||||
G_DECLARE_FINAL_TYPE(FuConsole, fu_console, FU, CONSOLE, GObject)
|
||||
|
||||
typedef enum {
|
||||
FU_CONSOLE_COLOR_BLACK = 30,
|
||||
FU_CONSOLE_COLOR_RED = 31,
|
||||
FU_CONSOLE_COLOR_GREEN = 32,
|
||||
FU_CONSOLE_COLOR_YELLOW = 33,
|
||||
FU_CONSOLE_COLOR_BLUE = 34,
|
||||
FU_CONSOLE_COLOR_MAGENTA = 35,
|
||||
FU_CONSOLE_COLOR_CYAN = 36,
|
||||
FU_CONSOLE_COLOR_WHITE = 37,
|
||||
} FuConsoleColor;
|
||||
|
||||
typedef enum {
|
||||
FU_CONSOLE_PRINT_FLAG_NONE = 0,
|
||||
FU_CONSOLE_PRINT_FLAG_STDERR = 1 << 0,
|
||||
FU_CONSOLE_PRINT_FLAG_WARNING = 1 << 1,
|
||||
} FuConsolePrintFlags;
|
||||
|
||||
gchar *
|
||||
fu_console_color_format(const gchar *text, FuConsoleColor fg_color);
|
||||
|
||||
FuConsole *
|
||||
fu_console_new(void);
|
||||
gboolean
|
||||
fu_console_setup(FuConsole *self, GError **error);
|
||||
|
||||
guint
|
||||
fu_console_input_uint(FuConsole *self, guint maxnum);
|
||||
gboolean
|
||||
fu_console_input_bool(FuConsole *self, gboolean def, const gchar *format, ...) G_GNUC_PRINTF(3, 4);
|
||||
|
||||
void
|
||||
fu_console_print_full(FuConsole *self, FuConsolePrintFlags flags, const gchar *format, ...)
|
||||
G_GNUC_PRINTF(3, 4);
|
||||
void
|
||||
fu_console_print(FuConsole *self, const gchar *format, ...) G_GNUC_PRINTF(2, 3);
|
||||
void
|
||||
fu_console_print_literal(FuConsole *self, const gchar *text);
|
||||
void
|
||||
fu_console_print_kv(FuConsole *self, const gchar *title, const gchar *msg);
|
||||
void
|
||||
fu_console_line(FuConsole *self, guint width);
|
||||
void
|
||||
fu_console_box(FuConsole *self, const gchar *title, const gchar *body, guint width);
|
||||
|
||||
void
|
||||
fu_console_set_progress(FuConsole *self, FwupdStatus status, guint percentage);
|
||||
void
|
||||
fu_console_set_status_length(FuConsole *self, guint len);
|
||||
void
|
||||
fu_console_set_percentage_length(FuConsole *self, guint len);
|
||||
void
|
||||
fu_console_set_progress_title(FuConsole *self, const gchar *title);
|
||||
void
|
||||
fu_console_set_interactive(FuConsole *self, gboolean interactive);
|
||||
void
|
||||
fu_console_set_main_context(FuConsole *self, GMainContext *main_ctx);
|
@ -1,475 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#define G_LOG_DOMAIN "FuProgressBar"
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include "fu-progressbar.h"
|
||||
|
||||
static void
|
||||
fu_progressbar_finalize(GObject *obj);
|
||||
|
||||
struct _FuProgressbar {
|
||||
GObject parent_instance;
|
||||
GMainContext *main_ctx;
|
||||
FwupdStatus status;
|
||||
gboolean spinner_count_up; /* chars */
|
||||
guint spinner_idx; /* chars */
|
||||
guint length_percentage; /* chars */
|
||||
guint length_status; /* chars */
|
||||
guint percentage;
|
||||
GSource *timer_source;
|
||||
gint64 last_animated; /* monotonic */
|
||||
GTimer *time_elapsed;
|
||||
gdouble last_estimate;
|
||||
gboolean interactive;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(FuProgressbar, fu_progressbar, G_TYPE_OBJECT)
|
||||
|
||||
static const gchar *
|
||||
fu_progressbar_status_to_string(FwupdStatus status)
|
||||
{
|
||||
switch (status) {
|
||||
case FWUPD_STATUS_IDLE:
|
||||
/* TRANSLATORS: daemon is inactive */
|
||||
return _("Idle…");
|
||||
break;
|
||||
case FWUPD_STATUS_DECOMPRESSING:
|
||||
/* TRANSLATORS: decompressing the firmware file */
|
||||
return _("Decompressing…");
|
||||
break;
|
||||
case FWUPD_STATUS_LOADING:
|
||||
/* TRANSLATORS: parsing the firmware information */
|
||||
return _("Loading…");
|
||||
break;
|
||||
case FWUPD_STATUS_DEVICE_RESTART:
|
||||
/* TRANSLATORS: restarting the device to pick up new F/W */
|
||||
return _("Restarting device…");
|
||||
break;
|
||||
case FWUPD_STATUS_DEVICE_READ:
|
||||
/* TRANSLATORS: reading from the flash chips */
|
||||
return _("Reading…");
|
||||
break;
|
||||
case FWUPD_STATUS_DEVICE_WRITE:
|
||||
/* TRANSLATORS: writing to the flash chips */
|
||||
return _("Writing…");
|
||||
break;
|
||||
case FWUPD_STATUS_DEVICE_ERASE:
|
||||
/* TRANSLATORS: erasing contents of the flash chips */
|
||||
return _("Erasing…");
|
||||
break;
|
||||
case FWUPD_STATUS_DEVICE_VERIFY:
|
||||
/* TRANSLATORS: verifying we wrote the firmware correctly */
|
||||
return _("Verifying…");
|
||||
break;
|
||||
case FWUPD_STATUS_SCHEDULING:
|
||||
/* TRANSLATORS: scheduling an update to be done on the next boot */
|
||||
return _("Scheduling…");
|
||||
break;
|
||||
case FWUPD_STATUS_DOWNLOADING:
|
||||
/* TRANSLATORS: downloading from a remote server */
|
||||
return _("Downloading…");
|
||||
break;
|
||||
case FWUPD_STATUS_WAITING_FOR_AUTH:
|
||||
/* TRANSLATORS: waiting for user to authenticate */
|
||||
return _("Authenticating…");
|
||||
break;
|
||||
case FWUPD_STATUS_DEVICE_BUSY:
|
||||
/* TRANSLATORS: waiting for device to do something */
|
||||
return _("Waiting…");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* TRANSLATORS: current daemon status is unknown */
|
||||
return _("Unknown");
|
||||
}
|
||||
|
||||
static void
|
||||
fu_progressbar_erase_line(FuProgressbar *self)
|
||||
{
|
||||
if (!self->interactive)
|
||||
return;
|
||||
g_print("\033[G");
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_fu_status_is_predictable(FwupdStatus status)
|
||||
{
|
||||
if (status == FWUPD_STATUS_DEVICE_ERASE)
|
||||
return TRUE;
|
||||
if (status == FWUPD_STATUS_DEVICE_VERIFY)
|
||||
return TRUE;
|
||||
if (status == FWUPD_STATUS_DEVICE_READ)
|
||||
return TRUE;
|
||||
if (status == FWUPD_STATUS_DEVICE_WRITE)
|
||||
return TRUE;
|
||||
if (status == FWUPD_STATUS_DOWNLOADING)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_progressbar_estimate_ready(FuProgressbar *self, guint percentage)
|
||||
{
|
||||
gdouble old;
|
||||
gdouble elapsed;
|
||||
|
||||
/* now invalid */
|
||||
if (percentage == 0 || percentage == 100) {
|
||||
g_timer_start(self->time_elapsed);
|
||||
self->last_estimate = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* allow-list things that make sense... */
|
||||
if (!_fu_status_is_predictable(self->status))
|
||||
return FALSE;
|
||||
|
||||
old = self->last_estimate;
|
||||
elapsed = g_timer_elapsed(self->time_elapsed, NULL);
|
||||
self->last_estimate = elapsed / percentage * (100 - percentage);
|
||||
|
||||
/* estimate is ready if we have decreased */
|
||||
return old > self->last_estimate;
|
||||
}
|
||||
|
||||
static gchar *
|
||||
fu_progressbar_time_remaining_str(FuProgressbar *self)
|
||||
{
|
||||
/* less than 5 seconds remaining */
|
||||
if (self->last_estimate < 5)
|
||||
return NULL;
|
||||
|
||||
/* less than 60 seconds remaining */
|
||||
if (self->last_estimate < 60) {
|
||||
/* TRANSLATORS: time remaining for completing firmware flash */
|
||||
return g_strdup(_("Less than one minute remaining"));
|
||||
}
|
||||
|
||||
return g_strdup_printf(
|
||||
/* TRANSLATORS: more than a minute */
|
||||
ngettext("%.0f minute remaining", "%.0f minutes remaining", self->last_estimate / 60),
|
||||
self->last_estimate / 60);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_progressbar_refresh(FuProgressbar *self, FwupdStatus status, guint percentage)
|
||||
{
|
||||
const gchar *title;
|
||||
guint i;
|
||||
gboolean is_idle_newline = FALSE;
|
||||
g_autoptr(GString) str = g_string_new(NULL);
|
||||
|
||||
g_return_if_fail(percentage <= 100);
|
||||
|
||||
/* erase previous line */
|
||||
fu_progressbar_erase_line(self);
|
||||
|
||||
/* add status */
|
||||
if (status == FWUPD_STATUS_IDLE || status == FWUPD_STATUS_UNKNOWN) {
|
||||
status = self->status;
|
||||
is_idle_newline = TRUE;
|
||||
}
|
||||
if (percentage == 100)
|
||||
is_idle_newline = TRUE;
|
||||
title = fu_progressbar_status_to_string(status);
|
||||
g_string_append(str, title);
|
||||
for (i = fu_strwidth(str->str); i < self->length_status; i++)
|
||||
g_string_append_c(str, ' ');
|
||||
|
||||
/* add progressbar */
|
||||
g_string_append(str, "[");
|
||||
if (percentage > 0) {
|
||||
for (i = 0; i < (self->length_percentage - 1) * percentage / 100; i++)
|
||||
g_string_append_c(str, '*');
|
||||
for (i = i + 1; i < self->length_percentage; i++)
|
||||
g_string_append_c(str, ' ');
|
||||
} else {
|
||||
const gchar chars[] = {
|
||||
'-',
|
||||
'\\',
|
||||
'|',
|
||||
'/',
|
||||
};
|
||||
for (i = 0; i < self->spinner_idx; i++)
|
||||
g_string_append_c(str, ' ');
|
||||
g_string_append_c(str, chars[i / 4 % G_N_ELEMENTS(chars)]);
|
||||
for (i = i + 1; i < self->length_percentage - 1; i++)
|
||||
g_string_append_c(str, ' ');
|
||||
}
|
||||
g_string_append_c(str, ']');
|
||||
|
||||
/* once we have good data show an estimate of time remaining */
|
||||
if (fu_progressbar_estimate_ready(self, percentage)) {
|
||||
g_autofree gchar *remaining = fu_progressbar_time_remaining_str(self);
|
||||
if (remaining != NULL)
|
||||
g_string_append_printf(str, " %s…", remaining);
|
||||
}
|
||||
|
||||
/* dump to screen */
|
||||
g_print("%s", str->str);
|
||||
|
||||
/* done */
|
||||
if (is_idle_newline) {
|
||||
g_print("\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_progressbar_set_title:
|
||||
* @self: A #FuProgressbar
|
||||
* @title: A string
|
||||
*
|
||||
* Sets progressbar title
|
||||
*
|
||||
* Since: 0.9.7
|
||||
**/
|
||||
void
|
||||
fu_progressbar_set_title(FuProgressbar *self, const gchar *title)
|
||||
{
|
||||
fu_progressbar_erase_line(self);
|
||||
g_print("%s\n", title);
|
||||
fu_progressbar_refresh(self, self->status, self->percentage);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_progressbar_set_main_context:
|
||||
* @self: A #FuProgressbar
|
||||
* @main_ctx: (nullable): main context
|
||||
*
|
||||
* Sets progressbar main context to use for animations.
|
||||
*
|
||||
* Since: 1.6.2
|
||||
**/
|
||||
void
|
||||
fu_progressbar_set_main_context(FuProgressbar *self, GMainContext *main_ctx)
|
||||
{
|
||||
self->main_ctx = g_main_context_ref(main_ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_progressbar_spin_inc(FuProgressbar *self)
|
||||
{
|
||||
/* reset */
|
||||
self->last_animated = g_get_monotonic_time();
|
||||
|
||||
/* up to down */
|
||||
if (self->spinner_count_up) {
|
||||
if (++self->spinner_idx > self->length_percentage - 3)
|
||||
self->spinner_count_up = FALSE;
|
||||
} else {
|
||||
if (--self->spinner_idx == 0)
|
||||
self->spinner_count_up = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_progressbar_spin_cb(gpointer user_data)
|
||||
{
|
||||
FuProgressbar *self = FU_PROGRESSBAR(user_data);
|
||||
|
||||
/* ignore */
|
||||
if (self->status == FWUPD_STATUS_IDLE || self->status == FWUPD_STATUS_UNKNOWN)
|
||||
return G_SOURCE_CONTINUE;
|
||||
|
||||
/* move the spinner index up to down */
|
||||
fu_progressbar_spin_inc(self);
|
||||
|
||||
/* update the terminal */
|
||||
fu_progressbar_refresh(self, self->status, self->percentage);
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_progressbar_spin_end(FuProgressbar *self)
|
||||
{
|
||||
if (self->timer_source != NULL) {
|
||||
g_source_destroy(self->timer_source);
|
||||
self->timer_source = NULL;
|
||||
|
||||
/* reset when the spinner has been stopped */
|
||||
g_timer_start(self->time_elapsed);
|
||||
}
|
||||
|
||||
/* go back to the start when we next go into unknown percentage mode */
|
||||
self->spinner_idx = 0;
|
||||
self->spinner_count_up = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_progressbar_spin_start(FuProgressbar *self)
|
||||
{
|
||||
if (self->timer_source != NULL)
|
||||
g_source_destroy(self->timer_source);
|
||||
self->timer_source = g_timeout_source_new(40);
|
||||
g_source_set_callback(self->timer_source, fu_progressbar_spin_cb, self, NULL);
|
||||
g_source_attach(self->timer_source, self->main_ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_progressbar_update:
|
||||
* @self: A #FuProgressbar
|
||||
* @status: A #FwupdStatus
|
||||
* @percentage: unsigned integer
|
||||
*
|
||||
* Refreshes a progressbar
|
||||
*
|
||||
* Since: 0.9.7
|
||||
**/
|
||||
void
|
||||
fu_progressbar_update(FuProgressbar *self, FwupdStatus status, guint percentage)
|
||||
{
|
||||
g_return_if_fail(FU_IS_PROGRESSBAR(self));
|
||||
|
||||
/* not useful */
|
||||
if (status == FWUPD_STATUS_UNKNOWN)
|
||||
return;
|
||||
|
||||
/* ignore initial client connection */
|
||||
if (self->status == FWUPD_STATUS_UNKNOWN && status == FWUPD_STATUS_IDLE) {
|
||||
self->status = status;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!self->interactive) {
|
||||
g_print("%s: %u%%\n", fu_progressbar_status_to_string(status), percentage);
|
||||
self->status = status;
|
||||
self->percentage = percentage;
|
||||
return;
|
||||
}
|
||||
|
||||
/* if the main loop isn't spinning and we've not had a chance to
|
||||
* execute the callback just do the refresh now manually */
|
||||
if (percentage == 0 && status != FWUPD_STATUS_IDLE &&
|
||||
self->status != FWUPD_STATUS_UNKNOWN) {
|
||||
if ((g_get_monotonic_time() - self->last_animated) / 1000 > 40) {
|
||||
fu_progressbar_spin_inc(self);
|
||||
fu_progressbar_refresh(self, status, percentage);
|
||||
}
|
||||
}
|
||||
|
||||
/* ignore duplicates */
|
||||
if (self->status == status && self->percentage == percentage)
|
||||
return;
|
||||
|
||||
/* enable or disable the spinner timeout */
|
||||
if (percentage > 0) {
|
||||
fu_progressbar_spin_end(self);
|
||||
} else {
|
||||
fu_progressbar_spin_start(self);
|
||||
}
|
||||
|
||||
/* update the terminal */
|
||||
fu_progressbar_refresh(self, status, percentage);
|
||||
|
||||
/* cache */
|
||||
self->status = status;
|
||||
self->percentage = percentage;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_progressbar_set_interactive:
|
||||
* @self: A #FuProgressbar
|
||||
* @interactive: #gboolean
|
||||
*
|
||||
* Marks the progressbar as interactive or not
|
||||
*
|
||||
* Since: 0.9.7
|
||||
**/
|
||||
void
|
||||
fu_progressbar_set_interactive(FuProgressbar *self, gboolean interactive)
|
||||
{
|
||||
g_return_if_fail(FU_IS_PROGRESSBAR(self));
|
||||
self->interactive = interactive;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_progressbar_set_length_status:
|
||||
* @self: A #FuProgressbar
|
||||
* @len: unsigned integer
|
||||
*
|
||||
* Sets the length of the progressbar status
|
||||
*
|
||||
* Since: 0.9.7
|
||||
**/
|
||||
void
|
||||
fu_progressbar_set_length_status(FuProgressbar *self, guint len)
|
||||
{
|
||||
g_return_if_fail(FU_IS_PROGRESSBAR(self));
|
||||
g_return_if_fail(len > 3);
|
||||
self->length_status = len;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_progressbar_set_length_percentage:
|
||||
* @self: A #FuProgressbar
|
||||
* @len: unsigned integer
|
||||
*
|
||||
* Sets the length of the progressba percentage
|
||||
*
|
||||
* Since: 0.9.7
|
||||
**/
|
||||
void
|
||||
fu_progressbar_set_length_percentage(FuProgressbar *self, guint len)
|
||||
{
|
||||
g_return_if_fail(FU_IS_PROGRESSBAR(self));
|
||||
g_return_if_fail(len > 3);
|
||||
self->length_percentage = len;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_progressbar_class_init(FuProgressbarClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS(klass);
|
||||
object_class->finalize = fu_progressbar_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_progressbar_init(FuProgressbar *self)
|
||||
{
|
||||
self->length_percentage = 40;
|
||||
self->length_status = 25;
|
||||
self->spinner_count_up = TRUE;
|
||||
self->time_elapsed = g_timer_new();
|
||||
self->interactive = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_progressbar_finalize(GObject *obj)
|
||||
{
|
||||
FuProgressbar *self = FU_PROGRESSBAR(obj);
|
||||
|
||||
if (self->timer_source != 0)
|
||||
g_source_destroy(self->timer_source);
|
||||
if (self->main_ctx != NULL)
|
||||
g_main_context_unref(self->main_ctx);
|
||||
g_timer_destroy(self->time_elapsed);
|
||||
|
||||
G_OBJECT_CLASS(fu_progressbar_parent_class)->finalize(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_progressbar_new:
|
||||
*
|
||||
* Creates a new #FuProgressbar
|
||||
*
|
||||
* Since: 0.9.7
|
||||
**/
|
||||
FuProgressbar *
|
||||
fu_progressbar_new(void)
|
||||
{
|
||||
FuProgressbar *self;
|
||||
self = g_object_new(FU_TYPE_PROGRESSBAR, NULL);
|
||||
return FU_PROGRESSBAR(self);
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <fwupdplugin.h>
|
||||
|
||||
#define FU_TYPE_PROGRESSBAR (fu_progressbar_get_type())
|
||||
G_DECLARE_FINAL_TYPE(FuProgressbar, fu_progressbar, FU, PROGRESSBAR, GObject)
|
||||
|
||||
FuProgressbar *
|
||||
fu_progressbar_new(void);
|
||||
void
|
||||
fu_progressbar_update(FuProgressbar *self, FwupdStatus status, guint percentage);
|
||||
void
|
||||
fu_progressbar_set_length_status(FuProgressbar *self, guint len);
|
||||
void
|
||||
fu_progressbar_set_length_percentage(FuProgressbar *self, guint len);
|
||||
void
|
||||
fu_progressbar_set_title(FuProgressbar *self, const gchar *title);
|
||||
void
|
||||
fu_progressbar_set_interactive(FuProgressbar *self, gboolean interactive);
|
||||
void
|
||||
fu_progressbar_set_main_context(FuProgressbar *self, GMainContext *main_ctx);
|
@ -21,6 +21,7 @@
|
||||
#include "fu-bios-settings-private.h"
|
||||
#include "fu-cabinet-common.h"
|
||||
#include "fu-config.h"
|
||||
#include "fu-console.h"
|
||||
#include "fu-context-private.h"
|
||||
#include "fu-device-list.h"
|
||||
#include "fu-device-private.h"
|
||||
@ -28,7 +29,6 @@
|
||||
#include "fu-history.h"
|
||||
#include "fu-plugin-list.h"
|
||||
#include "fu-plugin-private.h"
|
||||
#include "fu-progressbar.h"
|
||||
#include "fu-release-common.h"
|
||||
#include "fu-security-attr-common.h"
|
||||
#include "fu-smbios-private.h"
|
||||
@ -4089,31 +4089,31 @@ fu_memcpy_func(gconstpointer user_data)
|
||||
}
|
||||
|
||||
static void
|
||||
fu_progressbar_func(gconstpointer user_data)
|
||||
fu_console_func(gconstpointer user_data)
|
||||
{
|
||||
g_autoptr(FuProgressbar) progressbar = fu_progressbar_new();
|
||||
g_autoptr(FuConsole) console = fu_console_new();
|
||||
|
||||
fu_progressbar_set_length_status(progressbar, 20);
|
||||
fu_progressbar_set_length_percentage(progressbar, 50);
|
||||
fu_console_set_status_length(console, 20);
|
||||
fu_console_set_percentage_length(console, 50);
|
||||
|
||||
g_print("\n");
|
||||
for (guint i = 0; i < 100; i++) {
|
||||
fu_progressbar_update(progressbar, FWUPD_STATUS_DECOMPRESSING, i);
|
||||
fu_console_set_progress(console, FWUPD_STATUS_DECOMPRESSING, i);
|
||||
g_usleep(10000);
|
||||
}
|
||||
fu_progressbar_update(progressbar, FWUPD_STATUS_IDLE, 0);
|
||||
fu_console_set_progress(console, FWUPD_STATUS_IDLE, 0);
|
||||
for (guint i = 0; i < 100; i++) {
|
||||
guint pc = (i > 25 && i < 75) ? 0 : i;
|
||||
fu_progressbar_update(progressbar, FWUPD_STATUS_LOADING, pc);
|
||||
fu_console_set_progress(console, FWUPD_STATUS_LOADING, pc);
|
||||
g_usleep(10000);
|
||||
}
|
||||
fu_progressbar_update(progressbar, FWUPD_STATUS_IDLE, 0);
|
||||
fu_console_set_progress(console, FWUPD_STATUS_IDLE, 0);
|
||||
|
||||
for (guint i = 0; i < 5000; i++) {
|
||||
fu_progressbar_update(progressbar, FWUPD_STATUS_LOADING, 0);
|
||||
fu_console_set_progress(console, FWUPD_STATUS_LOADING, 0);
|
||||
g_usleep(1000);
|
||||
}
|
||||
fu_progressbar_update(progressbar, FWUPD_STATUS_IDLE, 0);
|
||||
fu_console_set_progress(console, FWUPD_STATUS_IDLE, 0);
|
||||
}
|
||||
|
||||
static gint
|
||||
@ -4889,7 +4889,7 @@ main(int argc, char **argv)
|
||||
|
||||
/* tests go here */
|
||||
if (g_test_slow()) {
|
||||
g_test_add_data_func("/fwupd/progressbar", self, fu_progressbar_func);
|
||||
g_test_add_data_func("/fwupd/console", self, fu_console_func);
|
||||
}
|
||||
g_test_add_data_func("/fwupd/backend{usb}", self, fu_backend_usb_func);
|
||||
g_test_add_data_func("/fwupd/backend{usb-invalid}", self, fu_backend_usb_invalid_func);
|
||||
|
325
src/fu-tool.c
325
src/fu-tool.c
@ -30,13 +30,13 @@
|
||||
|
||||
#include "fu-bios-settings-private.h"
|
||||
#include "fu-cabinet.h"
|
||||
#include "fu-console.h"
|
||||
#include "fu-context-private.h"
|
||||
#include "fu-debug.h"
|
||||
#include "fu-device-private.h"
|
||||
#include "fu-engine.h"
|
||||
#include "fu-history.h"
|
||||
#include "fu-plugin-private.h"
|
||||
#include "fu-progressbar.h"
|
||||
#include "fu-security-attr-common.h"
|
||||
#include "fu-security-attrs-private.h"
|
||||
#include "fu-smbios-private.h"
|
||||
@ -66,7 +66,7 @@ struct FuUtilPrivate {
|
||||
FuEngine *engine;
|
||||
FuEngineRequest *request;
|
||||
FuProgress *progress;
|
||||
FuProgressbar *progressbar;
|
||||
FuConsole *console;
|
||||
FwupdClient *client;
|
||||
gboolean as_json;
|
||||
gboolean no_reboot_check;
|
||||
@ -94,9 +94,9 @@ fu_util_client_notify_cb(GObject *object, GParamSpec *pspec, FuUtilPrivate *priv
|
||||
{
|
||||
if (priv->as_json)
|
||||
return;
|
||||
fu_progressbar_update(priv->progressbar,
|
||||
fwupd_client_get_status(priv->client),
|
||||
fwupd_client_get_percentage(priv->client));
|
||||
fu_console_set_progress(priv->console,
|
||||
fwupd_client_get_status(priv->client),
|
||||
fwupd_client_get_percentage(priv->client));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -125,7 +125,6 @@ fu_util_show_plugin_warnings(FuUtilPrivate *priv)
|
||||
for (guint i = 0; i < 64; i++) {
|
||||
FwupdPluginFlags flag = (guint64)1 << i;
|
||||
const gchar *tmp;
|
||||
g_autofree gchar *fmt = NULL;
|
||||
g_autofree gchar *url = NULL;
|
||||
g_autoptr(GString) str = g_string_new(NULL);
|
||||
if ((flags & flag) == 0)
|
||||
@ -133,17 +132,11 @@ fu_util_show_plugin_warnings(FuUtilPrivate *priv)
|
||||
tmp = fu_util_plugin_flag_to_string((guint64)1 << i);
|
||||
if (tmp == NULL)
|
||||
continue;
|
||||
/* TRANSLATORS: this is a prefix on the console */
|
||||
fmt = fu_util_term_format(_("WARNING:"), FU_UTIL_TERM_COLOR_RED);
|
||||
g_string_append_printf(str, "%s %s\n", fmt, tmp);
|
||||
|
||||
fu_console_print_full(priv->console, FU_CONSOLE_PRINT_FLAG_WARNING, "%s\n", tmp);
|
||||
url = g_strdup_printf("https://github.com/fwupd/fwupd/wiki/PluginFlag:%s",
|
||||
fwupd_plugin_flag_to_string(flag));
|
||||
g_string_append(str, " ");
|
||||
/* TRANSLATORS: %s is a link to a website */
|
||||
g_string_append_printf(str, _("See %s for more information."), url);
|
||||
g_string_append(str, "\n");
|
||||
g_printerr("%s", str->str);
|
||||
fu_console_print(priv->console, _("See %s for more information."), url);
|
||||
}
|
||||
}
|
||||
|
||||
@ -234,7 +227,7 @@ fu_util_start_engine(FuUtilPrivate *priv,
|
||||
if (!fu_engine_load(priv->engine, flags, progress, error))
|
||||
return FALSE;
|
||||
fu_util_show_plugin_warnings(priv);
|
||||
fu_util_show_unsupported_warn();
|
||||
fu_util_show_unsupported_warning(priv->console);
|
||||
|
||||
/* copy properties from engine to client */
|
||||
g_object_set(priv->client,
|
||||
@ -270,7 +263,7 @@ fu_util_cancelled_cb(GCancellable *cancellable, gpointer user_data)
|
||||
{
|
||||
FuUtilPrivate *priv = (FuUtilPrivate *)user_data;
|
||||
/* TRANSLATORS: this is when a device ctrl+c's a watch */
|
||||
g_print("%s\n", _("Cancelled"));
|
||||
fu_console_print_literal(priv->console, _("Cancelled"));
|
||||
g_main_loop_quit(priv->loop);
|
||||
}
|
||||
|
||||
@ -290,7 +283,7 @@ fu_util_smbios_dump(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
if (!fu_smbios_setup_from_file(smbios, values[0], error))
|
||||
return FALSE;
|
||||
tmp = fu_firmware_to_string(FU_FIRMWARE(smbios));
|
||||
g_print("%s\n", tmp);
|
||||
fu_console_print_literal(priv->console, tmp);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -332,8 +325,8 @@ fu_util_private_free(FuUtilPrivate *priv)
|
||||
g_main_loop_unref(priv->loop);
|
||||
if (priv->cancellable != NULL)
|
||||
g_object_unref(priv->cancellable);
|
||||
if (priv->progressbar != NULL)
|
||||
g_object_unref(priv->progressbar);
|
||||
if (priv->console != NULL)
|
||||
g_object_unref(priv->console);
|
||||
if (priv->progress != NULL)
|
||||
g_object_unref(priv->progress);
|
||||
if (priv->context != NULL)
|
||||
@ -366,9 +359,9 @@ fu_util_update_device_request_cb(FwupdClient *client, FwupdRequest *request, FuU
|
||||
g_autofree gchar *tmp = NULL;
|
||||
|
||||
/* TRANSLATORS: the user needs to do something, e.g. remove the device */
|
||||
fmt = fu_util_term_format(_("Action Required:"), FU_UTIL_TERM_COLOR_RED);
|
||||
fmt = fu_console_color_format(_("Action Required:"), FU_CONSOLE_COLOR_RED);
|
||||
tmp = g_strdup_printf("%s %s", fmt, fwupd_request_get_message(request));
|
||||
fu_progressbar_set_title(priv->progressbar, tmp);
|
||||
fu_console_set_progress_title(priv->console, tmp);
|
||||
}
|
||||
|
||||
/* save for later */
|
||||
@ -395,7 +388,7 @@ fu_main_engine_status_changed_cb(FuEngine *engine, FwupdStatus status, FuUtilPri
|
||||
{
|
||||
if (priv->as_json)
|
||||
return;
|
||||
fu_progressbar_update(priv->progressbar, status, 0);
|
||||
fu_console_set_progress(priv->console, status, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -403,7 +396,7 @@ fu_util_progress_percentage_changed_cb(FuProgress *progress, guint percentage, F
|
||||
{
|
||||
if (priv->as_json)
|
||||
return;
|
||||
fu_progressbar_update(priv->progressbar, fu_progress_get_status(progress), percentage);
|
||||
fu_console_set_progress(priv->console, fu_progress_get_status(progress), percentage);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -411,7 +404,7 @@ fu_util_progress_status_changed_cb(FuProgress *progress, FwupdStatus status, FuU
|
||||
{
|
||||
if (priv->as_json)
|
||||
return;
|
||||
fu_progressbar_update(priv->progressbar, status, fu_progress_get_percentage(progress));
|
||||
fu_console_set_progress(priv->console, status, fu_progress_get_percentage(progress));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -445,7 +438,7 @@ fu_util_get_plugins_as_json(FuUtilPrivate *priv, GPtrArray *plugins, GError **er
|
||||
}
|
||||
json_builder_end_array(builder);
|
||||
json_builder_end_object(builder);
|
||||
return fu_util_print_builder(builder, error);
|
||||
return fu_util_print_builder(priv->console, builder, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -467,11 +460,11 @@ fu_util_get_plugins(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
for (guint i = 0; i < plugins->len; i++) {
|
||||
FuPlugin *plugin = g_ptr_array_index(plugins, i);
|
||||
g_autofree gchar *str = fu_util_plugin_to_string(FWUPD_PLUGIN(plugin), 0);
|
||||
g_print("%s\n", str);
|
||||
fu_console_print_literal(priv->console, str);
|
||||
}
|
||||
if (plugins->len == 0) {
|
||||
/* TRANSLATORS: nothing found */
|
||||
g_print("%s\n", _("No plugins found"));
|
||||
fu_console_print_literal(priv->console, _("No plugins found"));
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@ -531,8 +524,12 @@ fu_util_prompt_for_device(FuUtilPrivate *priv, GPtrArray *devices_opt, GError **
|
||||
if (devices_filtered->len == 1) {
|
||||
dev = g_ptr_array_index(devices_filtered, 0);
|
||||
if (!priv->as_json) {
|
||||
/* TRANSLATORS: device has been chosen by the daemon for the user */
|
||||
g_print("%s: %s\n", _("Selected device"), fu_device_get_name(dev));
|
||||
fu_console_print(
|
||||
priv->console,
|
||||
"%s: %s",
|
||||
/* TRANSLATORS: device has been chosen by the daemon for the user */
|
||||
_("Selected device"),
|
||||
fu_device_get_name(dev));
|
||||
}
|
||||
return g_object_ref(dev);
|
||||
}
|
||||
@ -547,14 +544,18 @@ fu_util_prompt_for_device(FuUtilPrivate *priv, GPtrArray *devices_opt, GError **
|
||||
}
|
||||
|
||||
/* TRANSLATORS: get interactive prompt */
|
||||
g_print("%s\n", _("Choose a device:"));
|
||||
fu_console_print_literal(priv->console, _("Choose a device:"));
|
||||
/* TRANSLATORS: this is to abort the interactive prompt */
|
||||
g_print("0.\t%s\n", _("Cancel"));
|
||||
fu_console_print(priv->console, "0.\t%s", _("Cancel"));
|
||||
for (guint i = 0; i < devices_filtered->len; i++) {
|
||||
dev = g_ptr_array_index(devices_filtered, i);
|
||||
g_print("%u.\t%s (%s)\n", i + 1, fu_device_get_id(dev), fu_device_get_name(dev));
|
||||
fu_console_print(priv->console,
|
||||
"%u.\t%s (%s)",
|
||||
i + 1,
|
||||
fu_device_get_id(dev),
|
||||
fu_device_get_name(dev));
|
||||
}
|
||||
idx = fu_util_prompt_for_number(devices_filtered->len);
|
||||
idx = fu_console_input_uint(priv->console, devices_filtered->len);
|
||||
if (idx == 0) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
@ -666,20 +667,23 @@ fu_util_get_updates(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
|
||||
/* devices that have no updates available for whatever reason */
|
||||
if (devices_no_support->len > 0) {
|
||||
/* TRANSLATORS: message letting the user know no device upgrade
|
||||
* available due to missing on LVFS */
|
||||
g_printerr("%s\n", _("Devices with no available firmware updates: "));
|
||||
fu_console_print_literal(priv->console,
|
||||
/* TRANSLATORS: message letting the user know no device
|
||||
* upgrade available due to missing on LVFS */
|
||||
_("Devices with no available firmware updates: "));
|
||||
for (guint i = 0; i < devices_no_support->len; i++) {
|
||||
FwupdDevice *dev = g_ptr_array_index(devices_no_support, i);
|
||||
g_printerr(" • %s\n", fwupd_device_get_name(dev));
|
||||
fu_console_print(priv->console, " • %s", fwupd_device_get_name(dev));
|
||||
}
|
||||
}
|
||||
if (devices_no_upgrades->len > 0) {
|
||||
/* TRANSLATORS: message letting the user know no device upgrade available */
|
||||
g_printerr("%s\n", _("Devices with the latest available firmware version:"));
|
||||
fu_console_print_literal(
|
||||
priv->console,
|
||||
/* TRANSLATORS: message letting the user know no device upgrade available */
|
||||
_("Devices with the latest available firmware version:"));
|
||||
for (guint i = 0; i < devices_no_upgrades->len; i++) {
|
||||
FwupdDevice *dev = g_ptr_array_index(devices_no_upgrades, i);
|
||||
g_printerr(" • %s\n", fwupd_device_get_name(dev));
|
||||
fu_console_print(priv->console, " • %s", fwupd_device_get_name(dev));
|
||||
}
|
||||
}
|
||||
|
||||
@ -692,7 +696,7 @@ fu_util_get_updates(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fu_util_print_tree(priv->client, root);
|
||||
fu_util_print_tree(priv->console, priv->client, root);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -750,7 +754,7 @@ fu_util_get_details(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
if (rel != NULL)
|
||||
g_node_append_data(child, rel);
|
||||
}
|
||||
fu_util_print_tree(priv->client, root);
|
||||
fu_util_print_tree(priv->console, priv->client, root);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -771,7 +775,7 @@ fu_util_get_device_flags(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
g_string_append(str, " ~");
|
||||
g_string_append(str, tmp);
|
||||
}
|
||||
g_print("%s\n", str->str);
|
||||
fu_console_print_literal(priv->console, str->str);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -817,11 +821,12 @@ fu_util_get_devices(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
|
||||
/* print */
|
||||
if (g_node_n_children(root) == 0) {
|
||||
/* TRANSLATORS: nothing attached that can be upgraded */
|
||||
g_print("%s\n", _("No hardware detected with firmware update capability"));
|
||||
fu_console_print_literal(priv->console,
|
||||
/* TRANSLATORS: nothing attached that can be upgraded */
|
||||
_("No hardware detected with firmware update capability"));
|
||||
return TRUE;
|
||||
}
|
||||
fu_util_print_tree(priv->client, root);
|
||||
fu_util_print_tree(priv->console, priv->client, root);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -854,19 +859,19 @@ fu_util_update_device_changed_cb(FwupdClient *client, FwupdDevice *device, FuUti
|
||||
return;
|
||||
}
|
||||
|
||||
/* show message in progressbar */
|
||||
/* show message in console */
|
||||
if (priv->current_operation == FU_UTIL_OPERATION_UPDATE) {
|
||||
/* TRANSLATORS: %1 is a device name */
|
||||
str = g_strdup_printf(_("Updating %s…"), fwupd_device_get_name(device));
|
||||
fu_progressbar_set_title(priv->progressbar, str);
|
||||
fu_console_set_progress_title(priv->console, str);
|
||||
} else if (priv->current_operation == FU_UTIL_OPERATION_INSTALL) {
|
||||
/* TRANSLATORS: %1 is a device name */
|
||||
str = g_strdup_printf(_("Installing on %s…"), fwupd_device_get_name(device));
|
||||
fu_progressbar_set_title(priv->progressbar, str);
|
||||
fu_console_set_progress_title(priv->console, str);
|
||||
} else if (priv->current_operation == FU_UTIL_OPERATION_READ) {
|
||||
/* TRANSLATORS: %1 is a device name */
|
||||
str = g_strdup_printf(_("Reading from %s…"), fwupd_device_get_name(device));
|
||||
fu_progressbar_set_title(priv->progressbar, str);
|
||||
fu_console_set_progress_title(priv->console, str);
|
||||
} else {
|
||||
g_warning("no FuUtilOperation set");
|
||||
}
|
||||
@ -879,7 +884,7 @@ fu_util_display_current_message(FuUtilPrivate *priv)
|
||||
/* print all POST requests */
|
||||
for (guint i = 0; i < priv->post_requests->len; i++) {
|
||||
FwupdRequest *request = g_ptr_array_index(priv->post_requests, i);
|
||||
g_print("%s\n", fu_util_request_get_message(request));
|
||||
fu_console_print_literal(priv->console, fu_util_request_get_message(request));
|
||||
}
|
||||
}
|
||||
|
||||
@ -984,7 +989,7 @@ fu_util_install_blob(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
fu_util_display_current_message(priv);
|
||||
|
||||
/* success */
|
||||
return fu_util_prompt_complete(priv->completion_flags, TRUE, error);
|
||||
return fu_util_prompt_complete(priv->console, priv->completion_flags, TRUE, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -1251,7 +1256,7 @@ fu_util_install(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
if (device == NULL)
|
||||
return FALSE;
|
||||
if (!priv->no_safety_check) {
|
||||
if (!fu_util_prompt_warning_fde(FWUPD_DEVICE(device), error))
|
||||
if (!fu_util_prompt_warning_fde(priv->console, FWUPD_DEVICE(device), error))
|
||||
return FALSE;
|
||||
}
|
||||
devices_possible =
|
||||
@ -1381,7 +1386,7 @@ fu_util_install(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
}
|
||||
|
||||
/* success */
|
||||
return fu_util_prompt_complete(priv->completion_flags, TRUE, error);
|
||||
return fu_util_prompt_complete(priv->console, priv->completion_flags, TRUE, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -1510,13 +1515,14 @@ fu_util_update(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
continue;
|
||||
if (!fwupd_device_has_flag(dev, FWUPD_DEVICE_FLAG_SUPPORTED)) {
|
||||
if (!no_updates_header) {
|
||||
g_printerr("%s\n",
|
||||
/* TRANSLATORS: message letting the user know no device
|
||||
* upgrade available due to missing on LVFS */
|
||||
_("Devices with no available firmware updates: "));
|
||||
fu_console_print_literal(
|
||||
priv->console,
|
||||
/* TRANSLATORS: message letting the user know no
|
||||
* device upgrade available due to missing on LVFS */
|
||||
_("Devices with no available firmware updates: "));
|
||||
no_updates_header = TRUE;
|
||||
}
|
||||
g_printerr(" • %s\n", fwupd_device_get_name(dev));
|
||||
fu_console_print(priv->console, " • %s", fwupd_device_get_name(dev));
|
||||
continue;
|
||||
}
|
||||
if (!fu_util_filter_device(priv, dev))
|
||||
@ -1525,14 +1531,14 @@ fu_util_update(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
rels = fu_engine_get_upgrades(priv->engine, priv->request, device_id, &error_local);
|
||||
if (rels == NULL) {
|
||||
if (!latest_header) {
|
||||
g_printerr(
|
||||
"%s\n",
|
||||
fu_console_print_literal(
|
||||
priv->console,
|
||||
/* TRANSLATORS: message letting the user know no device upgrade
|
||||
* available */
|
||||
_("Devices with the latest available firmware version:"));
|
||||
latest_header = TRUE;
|
||||
}
|
||||
g_printerr(" • %s\n", fwupd_device_get_name(dev));
|
||||
fu_console_print(priv->console, " • %s", fwupd_device_get_name(dev));
|
||||
/* discard the actual reason from user, but leave for debugging */
|
||||
g_debug("%s", error_local->message);
|
||||
continue;
|
||||
@ -1544,14 +1550,14 @@ fu_util_update(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
g_strdup_printf("%s %s",
|
||||
fu_engine_get_host_vendor(priv->engine),
|
||||
fu_engine_get_host_product(priv->engine));
|
||||
if (!fu_util_prompt_warning(dev, rel, title, error))
|
||||
if (!fu_util_prompt_warning(priv->console, dev, rel, title, error))
|
||||
return FALSE;
|
||||
if (!fu_util_prompt_warning_fde(dev, error))
|
||||
if (!fu_util_prompt_warning_fde(priv->console, dev, error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!fu_util_install_release(priv, rel, &error_local)) {
|
||||
g_printerr("%s\n", error_local->message);
|
||||
fu_console_print_literal(priv->console, error_local->message);
|
||||
continue;
|
||||
}
|
||||
fu_util_display_current_message(priv);
|
||||
@ -1563,7 +1569,7 @@ fu_util_update(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return fu_util_prompt_complete(priv->completion_flags, TRUE, error);
|
||||
return fu_util_prompt_complete(priv->console, priv->completion_flags, TRUE, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -1633,7 +1639,7 @@ fu_util_reinstall(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return fu_util_prompt_complete(priv->completion_flags, TRUE, error);
|
||||
return fu_util_prompt_complete(priv->console, priv->completion_flags, TRUE, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -1861,7 +1867,7 @@ fu_util_get_report_metadata(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
fu_progress_step_done(priv->progress);
|
||||
|
||||
/* display */
|
||||
g_print("\n%s", str->str);
|
||||
fu_console_print_literal(priv->console, str->str);
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
@ -1951,8 +1957,12 @@ fu_util_activate(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
if (!fu_device_has_flag(device, FWUPD_DEVICE_FLAG_NEEDS_ACTIVATION))
|
||||
continue;
|
||||
has_pending = TRUE;
|
||||
/* TRANSLATORS: shown when shutting down to switch to the new version */
|
||||
g_print("%s %s…\n", _("Activating firmware update"), fu_device_get_name(device));
|
||||
fu_console_print(
|
||||
priv->console,
|
||||
"%s %s…",
|
||||
/* TRANSLATORS: shown when shutting down to switch to the new version */
|
||||
_("Activating firmware update"),
|
||||
fu_device_get_name(device));
|
||||
if (!fu_engine_activate(priv->engine,
|
||||
fu_device_get_id(device),
|
||||
fu_progress_get_child(priv->progress),
|
||||
@ -2030,8 +2040,8 @@ fu_util_hwids(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
return FALSE;
|
||||
|
||||
/* show debug output */
|
||||
g_print("Computer Information\n");
|
||||
g_print("--------------------\n");
|
||||
fu_console_print_literal(priv->console, "Computer Information");
|
||||
fu_console_print_literal(priv->console, "--------------------");
|
||||
for (guint i = 0; i < hwid_keys->len; i++) {
|
||||
const gchar *hwid_key = g_ptr_array_index(hwid_keys, i);
|
||||
const gchar *value = fu_hwids_get_value(hwids, hwid_key);
|
||||
@ -2040,15 +2050,15 @@ fu_util_hwids(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
if (g_strcmp0(hwid_key, FU_HWIDS_KEY_BIOS_MAJOR_RELEASE) == 0 ||
|
||||
g_strcmp0(hwid_key, FU_HWIDS_KEY_BIOS_MINOR_RELEASE) == 0) {
|
||||
guint64 val = g_ascii_strtoull(value, NULL, 16);
|
||||
g_print("%s: %" G_GUINT64_FORMAT "\n", hwid_key, val);
|
||||
fu_console_print(priv->console, "%s: %" G_GUINT64_FORMAT, hwid_key, val);
|
||||
} else {
|
||||
g_print("%s: %s\n", hwid_key, value);
|
||||
fu_console_print(priv->console, "%s: %s", hwid_key, value);
|
||||
}
|
||||
}
|
||||
|
||||
/* show GUIDs */
|
||||
g_print("\nHardware IDs\n");
|
||||
g_print("------------\n");
|
||||
fu_console_print_literal(priv->console, "Hardware IDs");
|
||||
fu_console_print_literal(priv->console, "------------");
|
||||
for (guint i = 0; i < 15; i++) {
|
||||
const gchar *keys = NULL;
|
||||
g_autofree gchar *guid = NULL;
|
||||
@ -2062,14 +2072,14 @@ fu_util_hwids(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
keys = fu_hwids_get_replace_keys(hwids, key);
|
||||
guid = fu_hwids_get_guid(hwids, key, &error_local);
|
||||
if (guid == NULL) {
|
||||
g_print("%s\n", error_local->message);
|
||||
fu_console_print_literal(priv->console, error_local->message);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* show what makes up the GUID */
|
||||
keysv = g_strsplit(keys, "&", -1);
|
||||
keys_str = g_strjoinv(" + ", keysv);
|
||||
g_print("{%s} <- %s\n", guid, keys_str);
|
||||
fu_console_print(priv->console, "{%s} <- %s", guid, keys_str);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@ -2098,7 +2108,7 @@ fu_util_self_sign(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
error);
|
||||
if (sig == NULL)
|
||||
return FALSE;
|
||||
g_print("%s\n", sig);
|
||||
fu_console_print_literal(priv->console, sig);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -2108,7 +2118,7 @@ fu_util_device_added_cb(FwupdClient *client, FwupdDevice *device, gpointer user_
|
||||
FuUtilPrivate *priv = (FuUtilPrivate *)user_data;
|
||||
g_autofree gchar *tmp = fu_util_device_to_string(priv->client, device, 0);
|
||||
/* TRANSLATORS: this is when a device is hotplugged */
|
||||
g_print("%s\n%s", _("Device added:"), tmp);
|
||||
fu_console_print(priv->console, "%s\n%s", _("Device added:"), tmp);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2117,7 +2127,7 @@ fu_util_device_removed_cb(FwupdClient *client, FwupdDevice *device, gpointer use
|
||||
FuUtilPrivate *priv = (FuUtilPrivate *)user_data;
|
||||
g_autofree gchar *tmp = fu_util_device_to_string(priv->client, device, 0);
|
||||
/* TRANSLATORS: this is when a device is hotplugged */
|
||||
g_print("%s\n%s", _("Device removed:"), tmp);
|
||||
fu_console_print(priv->console, "%s\n%s", _("Device removed:"), tmp);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2126,14 +2136,15 @@ fu_util_device_changed_cb(FwupdClient *client, FwupdDevice *device, gpointer use
|
||||
FuUtilPrivate *priv = (FuUtilPrivate *)user_data;
|
||||
g_autofree gchar *tmp = fu_util_device_to_string(priv->client, device, 0);
|
||||
/* TRANSLATORS: this is when a device has been updated */
|
||||
g_print("%s\n%s", _("Device changed:"), tmp);
|
||||
fu_console_print(priv->console, "%s\n%s", _("Device changed:"), tmp);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_util_changed_cb(FwupdClient *client, gpointer user_data)
|
||||
{
|
||||
FuUtilPrivate *priv = (FuUtilPrivate *)user_data;
|
||||
/* TRANSLATORS: this is when the daemon state changes */
|
||||
g_print("%s\n", _("Changed"));
|
||||
fu_console_print_literal(priv->console, _("Changed"));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -2183,11 +2194,11 @@ fu_util_get_firmware_types(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
firmware_types = fu_context_get_firmware_gtype_ids(fu_engine_get_context(priv->engine));
|
||||
for (guint i = 0; i < firmware_types->len; i++) {
|
||||
const gchar *id = g_ptr_array_index(firmware_types, i);
|
||||
g_print("%s\n", id);
|
||||
fu_console_print_literal(priv->console, id);
|
||||
}
|
||||
if (firmware_types->len == 0) {
|
||||
/* TRANSLATORS: nothing found */
|
||||
g_print("%s\n", _("No firmware IDs found"));
|
||||
fu_console_print_literal(priv->console, _("No firmware IDs found"));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -2202,14 +2213,14 @@ fu_util_prompt_for_firmware_type(FuUtilPrivate *priv, GError **error)
|
||||
firmware_types = fu_context_get_firmware_gtype_ids(fu_engine_get_context(priv->engine));
|
||||
|
||||
/* TRANSLATORS: get interactive prompt */
|
||||
g_print("%s\n", _("Choose a firmware type:"));
|
||||
fu_console_print_literal(priv->console, _("Choose a firmware type:"));
|
||||
/* TRANSLATORS: this is to abort the interactive prompt */
|
||||
g_print("0.\t%s\n", _("Cancel"));
|
||||
fu_console_print(priv->console, "0.\t%s", _("Cancel"));
|
||||
for (guint i = 0; i < firmware_types->len; i++) {
|
||||
const gchar *id = g_ptr_array_index(firmware_types, i);
|
||||
g_print("%u.\t%s\n", i + 1, id);
|
||||
fu_console_print(priv->console, "%u.\t%s", i + 1, id);
|
||||
}
|
||||
idx = fu_util_prompt_for_number(firmware_types->len);
|
||||
idx = fu_console_input_uint(priv->console, firmware_types->len);
|
||||
if (idx == 0) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
@ -2289,7 +2300,7 @@ fu_util_firmware_parse(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
}
|
||||
|
||||
str = fu_firmware_to_string(firmware);
|
||||
g_print("%s", str);
|
||||
fu_console_print_literal(priv->console, str);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -2350,7 +2361,7 @@ fu_util_firmware_export(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
str = fu_firmware_export_to_xml(firmware, flags, error);
|
||||
if (str == NULL)
|
||||
return FALSE;
|
||||
g_print("%s", str);
|
||||
fu_console_print_literal(priv->console, str);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -2406,7 +2417,7 @@ fu_util_firmware_extract(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
if (!fu_firmware_parse(firmware, blob, priv->flags, error))
|
||||
return FALSE;
|
||||
str = fu_firmware_to_string(firmware);
|
||||
g_print("%s", str);
|
||||
fu_console_print_literal(priv->console, str);
|
||||
images = fu_firmware_get_images(firmware);
|
||||
for (guint i = 0; i < images->len; i++) {
|
||||
FuFirmware *img = g_ptr_array_index(images, i);
|
||||
@ -2431,7 +2442,7 @@ fu_util_firmware_extract(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
fn = g_strdup_printf("img-0x%x.fw", i);
|
||||
}
|
||||
/* TRANSLATORS: decompressing images from a container firmware */
|
||||
g_print("%s : %s\n", _("Writing file:"), fn);
|
||||
fu_console_print(priv->console, "%s : %s", _("Writing file:"), fn);
|
||||
if (!fu_bytes_set_contents(fn, blob_img, error))
|
||||
return FALSE;
|
||||
}
|
||||
@ -2531,7 +2542,7 @@ fu_util_firmware_build(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
if (!fu_firmware_parse(firmware_dst, blob_dst, priv->flags, error))
|
||||
return FALSE;
|
||||
str = fu_firmware_to_string(firmware_dst);
|
||||
g_print("%s", str);
|
||||
fu_console_print_literal(priv->console, str);
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
@ -2611,7 +2622,7 @@ fu_util_firmware_convert(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
return FALSE;
|
||||
}
|
||||
str_src = fu_firmware_to_string(firmware_src);
|
||||
g_print("%s", str_src);
|
||||
fu_console_print_literal(priv->console, str_src);
|
||||
|
||||
/* copy images */
|
||||
firmware_dst = g_object_new(gtype_dst, NULL);
|
||||
@ -2642,7 +2653,7 @@ fu_util_firmware_convert(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
if (!fu_bytes_set_contents(values[1], blob_dst, error))
|
||||
return FALSE;
|
||||
str_dst = fu_firmware_to_string(firmware_dst);
|
||||
g_print("%s", str_dst);
|
||||
fu_console_print_literal(priv->console, str_dst);
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
@ -2753,7 +2764,7 @@ fu_util_firmware_patch(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
if (!fu_bytes_set_contents(values[0], blob_dst, error))
|
||||
return FALSE;
|
||||
str = fu_firmware_to_string(firmware);
|
||||
g_print("%s", str);
|
||||
fu_console_print_literal(priv->console, str);
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
@ -2801,7 +2812,7 @@ fu_util_verify_update(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
|
||||
/* show checksums */
|
||||
str = fu_device_to_string(dev);
|
||||
g_print("%s\n", str);
|
||||
fu_console_print_literal(priv->console, str);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -2874,7 +2885,7 @@ fu_util_get_history(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
fu_util_print_tree(priv->client, root);
|
||||
fu_util_print_tree(priv->console, priv->client, root);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -2987,7 +2998,7 @@ fu_util_get_remotes(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
FwupdRemote *remote_tmp = g_ptr_array_index(remotes, i);
|
||||
g_node_append_data(root, remote_tmp);
|
||||
}
|
||||
fu_util_print_tree(priv->client, root);
|
||||
fu_util_print_tree(priv->console, priv->client, root);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -3051,17 +3062,18 @@ fu_util_security(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
str = fu_security_attrs_to_json_string(attrs, error);
|
||||
if (str == NULL)
|
||||
return FALSE;
|
||||
g_print("%s\n", str);
|
||||
fu_console_print_literal(priv->console, str);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
g_print("%s \033[1m%s\033[0m\n",
|
||||
/* TRANSLATORS: this is a string like 'HSI:2-U' */
|
||||
_("Host Security ID:"),
|
||||
fu_engine_get_host_security_id(priv->engine));
|
||||
fu_console_print(priv->console,
|
||||
"%s \033[1m%s\033[0m",
|
||||
/* TRANSLATORS: this is a string like 'HSI:2-U' */
|
||||
_("Host Security ID:"),
|
||||
fu_engine_get_host_security_id(priv->engine));
|
||||
|
||||
str = fu_util_security_attrs_to_string(items, flags);
|
||||
g_print("%s\n", str);
|
||||
fu_console_print_literal(priv->console, str);
|
||||
|
||||
/* print the "when" */
|
||||
events = fu_engine_get_host_security_events(priv->engine, 10, error);
|
||||
@ -3071,7 +3083,7 @@ fu_util_security(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
if (events_array->len > 0) {
|
||||
g_autofree gchar *estr = fu_util_security_events_to_string(events_array, flags);
|
||||
if (estr != NULL)
|
||||
g_print("%s\n", estr);
|
||||
fu_console_print_literal(priv->console, estr);
|
||||
}
|
||||
|
||||
/* print the "also" */
|
||||
@ -3081,7 +3093,7 @@ fu_util_security(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
if (devices->len > 0) {
|
||||
g_autofree gchar *estr = fu_util_security_issues_to_string(devices);
|
||||
if (estr != NULL)
|
||||
g_print("%s\n", estr);
|
||||
fu_console_print_literal(priv->console, estr);
|
||||
}
|
||||
|
||||
/* success */
|
||||
@ -3102,20 +3114,23 @@ fu_util_prompt_for_volume(FuUtilPrivate *priv, GError **error)
|
||||
return NULL;
|
||||
if (volumes->len == 1) {
|
||||
volume = g_ptr_array_index(volumes, 0);
|
||||
/* TRANSLATORS: Volume has been chosen by the user */
|
||||
g_print("%s: %s\n", _("Selected volume"), fu_volume_get_id(volume));
|
||||
fu_console_print(priv->console,
|
||||
"%s: %s",
|
||||
/* TRANSLATORS: Volume has been chosen by the user */
|
||||
_("Selected volume"),
|
||||
fu_volume_get_id(volume));
|
||||
return g_object_ref(volume);
|
||||
}
|
||||
|
||||
/* TRANSLATORS: get interactive prompt */
|
||||
g_print("%s\n", _("Choose a volume:"));
|
||||
fu_console_print_literal(priv->console, _("Choose a volume:"));
|
||||
/* TRANSLATORS: this is to abort the interactive prompt */
|
||||
g_print("0.\t%s\n", _("Cancel"));
|
||||
fu_console_print(priv->console, "0.\t%s", _("Cancel"));
|
||||
for (guint i = 0; i < volumes->len; i++) {
|
||||
volume = g_ptr_array_index(volumes, i);
|
||||
g_print("%u.\t%s\n", i + 1, fu_volume_get_id(volume));
|
||||
fu_console_print(priv->console, "%u.\t%s", i + 1, fu_volume_get_id(volume));
|
||||
}
|
||||
idx = fu_util_prompt_for_number(volumes->len);
|
||||
idx = fu_console_input_uint(priv->console, volumes->len);
|
||||
if (idx == 0) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
@ -3167,7 +3182,7 @@ fu_util_esp_list(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
return FALSE;
|
||||
for (guint i = 0; i < files->len; i++) {
|
||||
const gchar *fn = g_ptr_array_index(files, i);
|
||||
g_print("%s\n", fn);
|
||||
fu_console_print_literal(priv->console, fn);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@ -3238,14 +3253,17 @@ fu_util_switch_branch(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
|
||||
/* TRANSLATORS: get interactive prompt, where branch is the
|
||||
* supplier of the firmware, e.g. "non-free" or "free" */
|
||||
g_print("%s\n", _("Choose a branch:"));
|
||||
fu_console_print_literal(priv->console, _("Choose a branch:"));
|
||||
/* TRANSLATORS: this is to abort the interactive prompt */
|
||||
g_print("0.\t%s\n", _("Cancel"));
|
||||
fu_console_print(priv->console, "0.\t%s", _("Cancel"));
|
||||
for (guint i = 0; i < branches->len; i++) {
|
||||
const gchar *branch_tmp = g_ptr_array_index(branches, i);
|
||||
g_print("%u.\t%s\n", i + 1, fu_util_branch_for_display(branch_tmp));
|
||||
fu_console_print(priv->console,
|
||||
"%u.\t%s",
|
||||
i + 1,
|
||||
fu_util_branch_for_display(branch_tmp));
|
||||
}
|
||||
idx = fu_util_prompt_for_number(branches->len);
|
||||
idx = fu_console_input_uint(priv->console, branches->len);
|
||||
if (idx == 0) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
@ -3285,7 +3303,7 @@ fu_util_switch_branch(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
}
|
||||
|
||||
/* we're switching branch */
|
||||
if (!fu_util_switch_branch_warning(FWUPD_DEVICE(dev), rel, FALSE, error))
|
||||
if (!fu_util_switch_branch_warning(priv->console, FWUPD_DEVICE(dev), rel, FALSE, error))
|
||||
return FALSE;
|
||||
|
||||
/* update the console if composite devices are also updated */
|
||||
@ -3306,7 +3324,7 @@ fu_util_switch_branch(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return fu_util_prompt_complete(priv->completion_flags, TRUE, error);
|
||||
return fu_util_prompt_complete(priv->console, priv->completion_flags, TRUE, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -3340,7 +3358,7 @@ fu_util_set_bios_setting(FuUtilPrivate *priv, gchar **input, GError **error)
|
||||
g_strdup_printf(_("Set BIOS setting '%s' using '%s'."),
|
||||
(const gchar *)key,
|
||||
(const gchar *)value);
|
||||
g_print("\n%s\n", msg);
|
||||
fu_console_print_literal(priv->console, msg);
|
||||
}
|
||||
}
|
||||
priv->completion_flags |= FWUPD_DEVICE_FLAG_NEEDS_REBOOT;
|
||||
@ -3350,7 +3368,7 @@ fu_util_set_bios_setting(FuUtilPrivate *priv, gchar **input, GError **error)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return fu_util_prompt_complete(priv->completion_flags, TRUE, error);
|
||||
return fu_util_prompt_complete(priv->console, priv->completion_flags, TRUE, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -3371,13 +3389,13 @@ fu_util_get_bios_setting(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
attrs = fu_context_get_bios_settings(ctx);
|
||||
items = fu_bios_settings_get_all(attrs);
|
||||
if (priv->as_json)
|
||||
return fu_util_get_bios_setting_as_json(values, items, error);
|
||||
return fu_util_get_bios_setting_as_json(priv->console, values, items, error);
|
||||
|
||||
for (guint i = 0; i < items->len; i++) {
|
||||
FwupdBiosSetting *attr = g_ptr_array_index(items, i);
|
||||
if (fu_util_bios_setting_matches_args(attr, values)) {
|
||||
g_autofree gchar *tmp = fu_util_bios_setting_to_string(attr, 0);
|
||||
g_print("%s\n", tmp);
|
||||
fu_console_print_literal(priv->console, tmp);
|
||||
found = TRUE;
|
||||
}
|
||||
}
|
||||
@ -3393,8 +3411,9 @@ fu_util_get_bios_setting(FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
g_set_error(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INVALID_ARGS,
|
||||
"%s: '%s'",
|
||||
/* TRANSLATORS: error message */
|
||||
"Unable to find attribute '%s'",
|
||||
_("Unable to find attribute"),
|
||||
values[0]);
|
||||
return FALSE;
|
||||
}
|
||||
@ -3422,9 +3441,9 @@ fu_util_version(FuUtilPrivate *priv, GError **error)
|
||||
|
||||
/* dump to the screen in the most appropriate format */
|
||||
if (priv->as_json)
|
||||
return fu_util_project_versions_as_json(metadata, error);
|
||||
return fu_util_project_versions_as_json(priv->console, metadata, error);
|
||||
str = fu_util_project_versions_to_string(metadata);
|
||||
g_print("%s", str);
|
||||
fu_console_print_literal(priv->console, str);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -3442,17 +3461,17 @@ fu_util_setup_interactive(FuUtilPrivate *priv, GError **error)
|
||||
g_set_error_literal(error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "using --json");
|
||||
return FALSE;
|
||||
}
|
||||
return fu_util_setup_interactive_console(error);
|
||||
return fu_console_setup(priv->console, error);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_util_print_error(FuUtilPrivate *priv, const GError *error)
|
||||
{
|
||||
if (priv->as_json) {
|
||||
fu_util_print_error_as_json(error);
|
||||
fu_util_print_error_as_json(priv->console, error);
|
||||
return;
|
||||
}
|
||||
g_printerr("%s\n", error->message);
|
||||
fu_console_print_full(priv->console, FU_CONSOLE_PRINT_FLAG_STDERR, "%s\n", error->message);
|
||||
}
|
||||
|
||||
int
|
||||
@ -3652,9 +3671,9 @@ main(int argc, char *argv[])
|
||||
/* create helper object */
|
||||
priv->main_ctx = g_main_context_new();
|
||||
priv->loop = g_main_loop_new(priv->main_ctx, FALSE);
|
||||
priv->progressbar = fu_progressbar_new();
|
||||
priv->console = fu_console_new();
|
||||
priv->post_requests = g_ptr_array_new_with_free_func((GDestroyNotify)g_object_unref);
|
||||
fu_progressbar_set_main_context(priv->progressbar, priv->main_ctx);
|
||||
fu_console_set_main_context(priv->console, priv->main_ctx);
|
||||
priv->request = fu_engine_request_new(FU_ENGINE_REQUEST_KIND_ACTIVE);
|
||||
|
||||
/* used for monitoring and downloading */
|
||||
@ -4001,7 +4020,7 @@ main(int argc, char *argv[])
|
||||
FWUPD_FEATURE_FLAG_COMMUNITY_TEXT | FWUPD_FEATURE_FLAG_SHOW_PROBLEMS |
|
||||
FWUPD_FEATURE_FLAG_REQUESTS);
|
||||
}
|
||||
fu_progressbar_set_interactive(priv->progressbar, priv->interactive);
|
||||
fu_console_set_interactive(priv->console, priv->interactive);
|
||||
|
||||
/* get a list of the commands */
|
||||
priv->context = g_option_context_new(NULL);
|
||||
@ -4019,23 +4038,24 @@ main(int argc, char *argv[])
|
||||
g_option_context_add_group(priv->context, fu_debug_get_option_group());
|
||||
ret = g_option_context_parse(priv->context, &argc, &argv, &error);
|
||||
if (!ret) {
|
||||
/* TRANSLATORS: the user didn't read the man page */
|
||||
g_print("%s: %s\n", _("Failed to parse arguments"), error->message);
|
||||
fu_console_print(priv->console,
|
||||
"%s: %s",
|
||||
/* TRANSLATORS: the user didn't read the man page */
|
||||
_("Failed to parse arguments"),
|
||||
error->message);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
fu_progress_set_profile(priv->progress, g_getenv("FWUPD_VERBOSE") != NULL);
|
||||
|
||||
/* allow disabling SSL strict mode for broken corporate proxies */
|
||||
if (priv->disable_ssl_strict) {
|
||||
g_autofree gchar *fmt = NULL;
|
||||
/* TRANSLATORS: this is a prefix on the console */
|
||||
fmt = fu_util_term_format(_("WARNING:"), FU_UTIL_TERM_COLOR_RED);
|
||||
g_printerr("%s %s\n",
|
||||
fmt,
|
||||
/* TRANSLATORS: try to help */
|
||||
_("Ignoring SSL strict checks, "
|
||||
"to do this automatically in the future "
|
||||
"export DISABLE_SSL_STRICT in your environment"));
|
||||
fu_console_print_full(priv->console,
|
||||
FU_CONSOLE_PRINT_FLAG_WARNING,
|
||||
"%s\n",
|
||||
/* TRANSLATORS: try to help */
|
||||
_("Ignoring SSL strict checks, "
|
||||
"to do this automatically in the future "
|
||||
"export DISABLE_SSL_STRICT in your environment"));
|
||||
(void)g_setenv("DISABLE_SSL_STRICT", "1", TRUE);
|
||||
}
|
||||
|
||||
@ -4112,8 +4132,9 @@ main(int argc, char *argv[])
|
||||
#endif
|
||||
fu_util_print_error(priv, error);
|
||||
if (g_error_matches(error, FWUPD_ERROR, FWUPD_ERROR_INVALID_ARGS)) {
|
||||
/* TRANSLATORS: error message explaining command on how to get help */
|
||||
g_printerr("\n%s\n", _("Use fwupdtool --help for help"));
|
||||
fu_console_print_literal(priv->console,
|
||||
/* TRANSLATORS: explain how to get help */
|
||||
_("Use fwupdtool --help for help"));
|
||||
} else if (g_error_matches(error, FWUPD_ERROR, FWUPD_ERROR_NOTHING_TO_DO)) {
|
||||
g_debug("%s\n", error->message);
|
||||
return EXIT_NOTHING_TO_DO;
|
||||
@ -4121,8 +4142,12 @@ main(int argc, char *argv[])
|
||||
#ifdef HAVE_GETUID
|
||||
/* if not root, then notify users on the error path */
|
||||
if (priv->interactive && (getuid() != 0 || geteuid() != 0)) {
|
||||
/* TRANSLATORS: we're poking around as a power user */
|
||||
g_printerr("%s\n", _("NOTE: This program may only work correctly as root"));
|
||||
fu_console_print_full(priv->console,
|
||||
FU_CONSOLE_PRINT_FLAG_STDERR |
|
||||
FU_CONSOLE_PRINT_FLAG_WARNING,
|
||||
"%s\n",
|
||||
/* TRANSLATORS: we're poking around as a power user */
|
||||
_("This program may only work correctly as root"));
|
||||
}
|
||||
#endif
|
||||
return EXIT_FAILURE;
|
||||
@ -4132,7 +4157,7 @@ main(int argc, char *argv[])
|
||||
if (fu_progress_get_profile(priv->progress)) {
|
||||
g_autofree gchar *str = fu_progress_traceback(priv->progress);
|
||||
if (str != NULL)
|
||||
g_print("\n%s\n", str);
|
||||
fu_console_print_literal(priv->console, str);
|
||||
}
|
||||
|
||||
/* success */
|
||||
|
@ -62,7 +62,10 @@ fu_util_bios_setting_matches_args(FwupdBiosSetting *setting, gchar **values)
|
||||
}
|
||||
|
||||
gboolean
|
||||
fu_util_get_bios_setting_as_json(gchar **values, GPtrArray *settings, GError **error)
|
||||
fu_util_get_bios_setting_as_json(FuConsole *console,
|
||||
gchar **values,
|
||||
GPtrArray *settings,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(JsonBuilder) builder = json_builder_new();
|
||||
json_builder_begin_object(builder);
|
||||
@ -80,7 +83,7 @@ fu_util_get_bios_setting_as_json(gchar **values, GPtrArray *settings, GError **e
|
||||
}
|
||||
json_builder_end_array(builder);
|
||||
json_builder_end_object(builder);
|
||||
return fu_util_print_builder(builder, error);
|
||||
return fu_util_print_builder(console, builder, error);
|
||||
}
|
||||
|
||||
gchar *
|
||||
|
@ -10,11 +10,16 @@
|
||||
|
||||
#include "fwupd-bios-setting-private.h"
|
||||
|
||||
#include "fu-console.h"
|
||||
|
||||
gchar *
|
||||
fu_util_bios_setting_to_string(FwupdBiosSetting *setting, guint idt);
|
||||
gboolean
|
||||
fu_util_bios_setting_matches_args(FwupdBiosSetting *setting, gchar **values);
|
||||
gboolean
|
||||
fu_util_get_bios_setting_as_json(gchar **values, GPtrArray *settings, GError **error);
|
||||
fu_util_get_bios_setting_as_json(FuConsole *console,
|
||||
gchar **values,
|
||||
GPtrArray *settings,
|
||||
GError **error);
|
||||
GHashTable *
|
||||
fu_util_bios_settings_parse_argv(gchar **input, GError **error);
|
||||
|
@ -20,11 +20,7 @@
|
||||
#include <curl/curl.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <wchar.h>
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "fu-console.h"
|
||||
#include "fu-device-private.h"
|
||||
#include "fu-security-attr-common.h"
|
||||
#include "fu-util-common.h"
|
||||
@ -45,7 +41,7 @@ fu_util_get_systemd_unit(void)
|
||||
}
|
||||
|
||||
gchar *
|
||||
fu_util_term_format(const gchar *text, FuUtilTermColor fg_color)
|
||||
fu_console_color_format(const gchar *text, FuConsoleColor fg_color)
|
||||
{
|
||||
if (g_getenv("NO_COLOR") != NULL)
|
||||
return g_strdup(text);
|
||||
@ -94,79 +90,15 @@ fu_util_using_correct_daemon(GError **error)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
fu_util_print_data(const gchar *title, const gchar *msg)
|
||||
{
|
||||
gsize title_len;
|
||||
g_auto(GStrv) lines = NULL;
|
||||
|
||||
if (msg == NULL)
|
||||
return;
|
||||
g_print("%s:", title);
|
||||
|
||||
/* pad */
|
||||
title_len = fu_strwidth(title) + 1;
|
||||
lines = g_strsplit(msg, "\n", -1);
|
||||
for (guint j = 0; lines[j] != NULL; j++) {
|
||||
for (gsize i = title_len; i < 25; i++)
|
||||
g_print(" ");
|
||||
g_print("%s\n", lines[j]);
|
||||
title_len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
guint
|
||||
fu_util_prompt_for_number(guint maxnum)
|
||||
{
|
||||
gint retval;
|
||||
guint answer = 0;
|
||||
|
||||
do {
|
||||
char buffer[64];
|
||||
|
||||
/* swallow the \n at end of line too */
|
||||
if (!fgets(buffer, sizeof(buffer), stdin))
|
||||
break;
|
||||
if (strlen(buffer) == sizeof(buffer) - 1)
|
||||
continue;
|
||||
|
||||
/* get a number */
|
||||
retval = sscanf(buffer, "%u", &answer);
|
||||
|
||||
/* positive */
|
||||
if (retval == 1 && answer <= maxnum)
|
||||
break;
|
||||
|
||||
/* TRANSLATORS: the user isn't reading the question */
|
||||
g_print(_("Please enter a number from 0 to %u: "), maxnum);
|
||||
} while (TRUE);
|
||||
return answer;
|
||||
}
|
||||
|
||||
gboolean
|
||||
fu_util_prompt_for_boolean(gboolean def)
|
||||
{
|
||||
do {
|
||||
char buffer[4];
|
||||
if (!fgets(buffer, sizeof(buffer), stdin))
|
||||
continue;
|
||||
if (strlen(buffer) == sizeof(buffer) - 1)
|
||||
continue;
|
||||
if (g_strcmp0(buffer, "\n") == 0)
|
||||
return def;
|
||||
buffer[0] = g_ascii_toupper(buffer[0]);
|
||||
if (g_strcmp0(buffer, "Y\n") == 0)
|
||||
return TRUE;
|
||||
if (g_strcmp0(buffer, "N\n") == 0)
|
||||
return FALSE;
|
||||
} while (TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
typedef struct {
|
||||
FwupdClient *client;
|
||||
FuConsole *console;
|
||||
} FuUtilPrintTreeHelper;
|
||||
|
||||
static gboolean
|
||||
fu_util_traverse_tree(GNode *n, gpointer data)
|
||||
{
|
||||
FwupdClient *client = FWUPD_CLIENT(data);
|
||||
FuUtilPrintTreeHelper *helper = (FuUtilPrintTreeHelper *)data;
|
||||
guint idx = g_node_depth(n) - 1;
|
||||
g_autofree gchar *tmp = NULL;
|
||||
g_auto(GStrv) split = NULL;
|
||||
@ -174,7 +106,7 @@ fu_util_traverse_tree(GNode *n, gpointer data)
|
||||
/* get split lines */
|
||||
if (FWUPD_IS_DEVICE(n->data)) {
|
||||
FwupdDevice *dev = FWUPD_DEVICE(n->data);
|
||||
tmp = fu_util_device_to_string(client, dev, idx);
|
||||
tmp = fu_util_device_to_string(helper->client, dev, idx);
|
||||
} else if (FWUPD_IS_REMOTE(n->data)) {
|
||||
FwupdRemote *remote = FWUPD_REMOTE(n->data);
|
||||
tmp = fu_util_remote_to_string(remote, idx);
|
||||
@ -186,9 +118,10 @@ fu_util_traverse_tree(GNode *n, gpointer data)
|
||||
|
||||
/* root node */
|
||||
if (n->data == NULL && g_getenv("FWUPD_VERBOSE") == NULL) {
|
||||
g_autofree gchar *str = g_strdup_printf("%s %s",
|
||||
fwupd_client_get_host_vendor(client),
|
||||
fwupd_client_get_host_product(client));
|
||||
g_autofree gchar *str =
|
||||
g_strdup_printf("%s %s",
|
||||
fwupd_client_get_host_vendor(helper->client),
|
||||
fwupd_client_get_host_product(helper->client));
|
||||
g_print("%s\n│\n", str);
|
||||
return FALSE;
|
||||
}
|
||||
@ -227,22 +160,23 @@ fu_util_traverse_tree(GNode *n, gpointer data)
|
||||
|
||||
/* empty line */
|
||||
if (split[i][0] == '\0') {
|
||||
g_print("%s\n", str->str);
|
||||
fu_console_print_literal(helper->console, str->str);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* dump to the console */
|
||||
g_string_append(str, split[i] + (idx * 2));
|
||||
g_print("%s\n", str->str);
|
||||
fu_console_print_literal(helper->console, str->str);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
fu_util_print_tree(FwupdClient *client, GNode *n)
|
||||
fu_util_print_tree(FuConsole *console, FwupdClient *client, GNode *n)
|
||||
{
|
||||
g_node_traverse(n, G_PRE_ORDER, G_TRAVERSE_ALL, -1, fu_util_traverse_tree, client);
|
||||
FuUtilPrintTreeHelper helper = {.client = client, .console = console};
|
||||
g_node_traverse(n, G_PRE_ORDER, G_TRAVERSE_ALL, -1, fu_util_traverse_tree, &helper);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -420,7 +354,8 @@ fu_util_get_release_description_with_fallback(FwupdRelease *rel)
|
||||
}
|
||||
|
||||
gboolean
|
||||
fu_util_prompt_warning(FwupdDevice *device,
|
||||
fu_util_prompt_warning(FuConsole *console,
|
||||
FwupdDevice *device,
|
||||
FwupdRelease *release,
|
||||
const gchar *machine,
|
||||
GError **error)
|
||||
@ -507,13 +442,10 @@ fu_util_prompt_warning(FwupdDevice *device,
|
||||
}
|
||||
}
|
||||
}
|
||||
fu_util_warning_box(title->str, str->str, 80);
|
||||
fu_console_box(console, title->str, str->str, 80);
|
||||
|
||||
/* ask for confirmation */
|
||||
g_print("\n%s [Y|n]: ",
|
||||
/* TRANSLATORS: prompt to apply the update */
|
||||
_("Perform operation?"));
|
||||
if (!fu_util_prompt_for_boolean(TRUE)) {
|
||||
/* TRANSLATORS: prompt to apply the update */
|
||||
if (!fu_console_input_bool(console, TRUE, "%s", _("Perform operation?"))) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOTHING_TO_DO,
|
||||
@ -526,28 +458,31 @@ fu_util_prompt_warning(FwupdDevice *device,
|
||||
}
|
||||
|
||||
gboolean
|
||||
fu_util_prompt_complete(FwupdDeviceFlags flags, gboolean prompt, GError **error)
|
||||
fu_util_prompt_complete(FuConsole *console, FwupdDeviceFlags flags, gboolean prompt, GError **error)
|
||||
{
|
||||
if (flags & FWUPD_DEVICE_FLAG_NEEDS_SHUTDOWN) {
|
||||
if (prompt) {
|
||||
g_print("\n%s %s [y|N]: ",
|
||||
/* TRANSLATORS: explain why we want to shutdown */
|
||||
_("An update requires the system to shutdown to complete."),
|
||||
/* TRANSLATORS: shutdown to apply the update */
|
||||
_("Shutdown now?"));
|
||||
if (!fu_util_prompt_for_boolean(FALSE))
|
||||
if (!fu_console_input_bool(console,
|
||||
FALSE,
|
||||
"%s %s",
|
||||
/* TRANSLATORS: explain why */
|
||||
_("An update requires the system to shutdown "
|
||||
"to complete."),
|
||||
/* TRANSLATORS: shutdown to apply the update */
|
||||
_("Shutdown now?")))
|
||||
return TRUE;
|
||||
}
|
||||
return fu_util_update_shutdown(error);
|
||||
}
|
||||
if (flags & FWUPD_DEVICE_FLAG_NEEDS_REBOOT) {
|
||||
if (prompt) {
|
||||
g_print("\n%s %s [y|N]: ",
|
||||
/* TRANSLATORS: explain why we want to reboot */
|
||||
_("An update requires a reboot to complete."),
|
||||
/* TRANSLATORS: reboot to apply the update */
|
||||
_("Restart now?"));
|
||||
if (!fu_util_prompt_for_boolean(FALSE))
|
||||
if (!fu_console_input_bool(console,
|
||||
FALSE,
|
||||
"%s %s",
|
||||
/* TRANSLATORS: explain why we want to reboot */
|
||||
_("An update requires a reboot to complete."),
|
||||
/* TRANSLATORS: reboot to apply the update */
|
||||
_("Restart now?")))
|
||||
return TRUE;
|
||||
}
|
||||
return fu_util_update_reboot(error);
|
||||
@ -849,116 +784,6 @@ fu_util_release_get_name(FwupdRelease *release)
|
||||
return g_strdup_printf(_("%s Update"), name);
|
||||
}
|
||||
|
||||
static GPtrArray *
|
||||
fu_util_strsplit_words(const gchar *text, guint line_len)
|
||||
{
|
||||
g_auto(GStrv) tokens = NULL;
|
||||
g_autoptr(GPtrArray) lines = g_ptr_array_new_with_free_func(g_free);
|
||||
g_autoptr(GString) curline = g_string_new(NULL);
|
||||
|
||||
/* sanity check */
|
||||
if (text == NULL || text[0] == '\0')
|
||||
return NULL;
|
||||
if (line_len == 0)
|
||||
return NULL;
|
||||
|
||||
/* tokenize the string */
|
||||
tokens = g_strsplit(text, " ", -1);
|
||||
for (guint i = 0; tokens[i] != NULL; i++) {
|
||||
/* current line plus new token is okay */
|
||||
if (curline->len + fu_strwidth(tokens[i]) < line_len) {
|
||||
g_string_append_printf(curline, "%s ", tokens[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* too long, so remove space, add newline and dump */
|
||||
if (curline->len > 0)
|
||||
g_string_truncate(curline, curline->len - 1);
|
||||
g_ptr_array_add(lines, g_strdup(curline->str));
|
||||
g_string_truncate(curline, 0);
|
||||
g_string_append_printf(curline, "%s ", tokens[i]);
|
||||
}
|
||||
|
||||
/* any incomplete line? */
|
||||
if (curline->len > 0) {
|
||||
g_string_truncate(curline, curline->len - 1);
|
||||
g_ptr_array_add(lines, g_strdup(curline->str));
|
||||
}
|
||||
return g_steal_pointer(&lines);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_util_warning_box_line(const gchar *start,
|
||||
const gchar *text,
|
||||
const gchar *end,
|
||||
const gchar *padding,
|
||||
guint width)
|
||||
{
|
||||
guint offset = 0;
|
||||
if (start != NULL) {
|
||||
offset += fu_strwidth(start);
|
||||
g_print("%s", start);
|
||||
}
|
||||
if (text != NULL) {
|
||||
offset += fu_strwidth(text);
|
||||
g_print("%s", text);
|
||||
}
|
||||
if (end != NULL)
|
||||
offset += fu_strwidth(end);
|
||||
for (guint i = offset; i < width; i++)
|
||||
g_print("%s", padding);
|
||||
if (end != NULL)
|
||||
g_print("%s\n", end);
|
||||
}
|
||||
|
||||
void
|
||||
fu_util_warning_box(const gchar *title, const gchar *body, guint width)
|
||||
{
|
||||
/* nothing to do */
|
||||
if (title == NULL && body == NULL)
|
||||
return;
|
||||
|
||||
/* header */
|
||||
fu_util_warning_box_line("╔", NULL, "╗", "═", width);
|
||||
|
||||
/* optional title */
|
||||
if (title != NULL) {
|
||||
g_autoptr(GPtrArray) lines = fu_util_strsplit_words(title, width - 4);
|
||||
for (guint j = 0; j < lines->len; j++) {
|
||||
const gchar *line = g_ptr_array_index(lines, j);
|
||||
fu_util_warning_box_line("║ ", line, " ║", " ", width);
|
||||
}
|
||||
}
|
||||
|
||||
/* join */
|
||||
if (title != NULL && body != NULL)
|
||||
fu_util_warning_box_line("╠", NULL, "╣", "═", width);
|
||||
|
||||
/* optional body */
|
||||
if (body != NULL) {
|
||||
gboolean has_nonempty = FALSE;
|
||||
g_auto(GStrv) split = g_strsplit(body, "\n", -1);
|
||||
for (guint i = 0; split[i] != NULL; i++) {
|
||||
g_autoptr(GPtrArray) lines = fu_util_strsplit_words(split[i], width - 4);
|
||||
if (lines == NULL) {
|
||||
if (has_nonempty) {
|
||||
fu_util_warning_box_line("║ ", NULL, " ║", " ", width);
|
||||
has_nonempty = FALSE;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
for (guint j = 0; j < lines->len; j++) {
|
||||
const gchar *line = g_ptr_array_index(lines, j);
|
||||
fu_util_warning_box_line("║ ", line, " ║", " ", width);
|
||||
}
|
||||
has_nonempty = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* footer */
|
||||
fu_util_warning_box_line("╚", NULL, "╝", "═", width);
|
||||
}
|
||||
|
||||
gboolean
|
||||
fu_util_parse_filter_flags(const gchar *filter,
|
||||
FwupdDeviceFlags *include,
|
||||
@ -1561,7 +1386,7 @@ fu_util_device_to_string(FwupdClient *client, FwupdDevice *dev, guint idt)
|
||||
tmp = fwupd_device_get_update_message(dev);
|
||||
if (tmp != NULL) {
|
||||
g_autofree gchar *color =
|
||||
fu_util_term_format(tmp, FU_UTIL_TERM_COLOR_BLUE);
|
||||
fu_console_color_format(tmp, FU_CONSOLE_COLOR_BLUE);
|
||||
fu_string_append(
|
||||
str,
|
||||
idt + 1,
|
||||
@ -1596,7 +1421,8 @@ fu_util_device_to_string(FwupdClient *client, FwupdDevice *dev, guint idt)
|
||||
if (fwupd_device_get_problems(dev) == FWUPD_DEVICE_PROBLEM_NONE) {
|
||||
tmp = fwupd_device_get_update_error(dev);
|
||||
if (tmp != NULL) {
|
||||
g_autofree gchar *color = fu_util_term_format(tmp, FU_UTIL_TERM_COLOR_RED);
|
||||
g_autofree gchar *color =
|
||||
fu_console_color_format(tmp, FU_CONSOLE_COLOR_RED);
|
||||
/* TRANSLATORS: error message from last update attempt */
|
||||
fu_string_append(str, idt + 1, _("Update Error"), color);
|
||||
}
|
||||
@ -1615,7 +1441,7 @@ fu_util_device_to_string(FwupdClient *client, FwupdDevice *dev, guint idt)
|
||||
if (desc == NULL)
|
||||
continue;
|
||||
bullet = g_strdup_printf("• %s", desc);
|
||||
color = fu_util_term_format(bullet, FU_UTIL_TERM_COLOR_RED);
|
||||
color = fu_console_color_format(bullet, FU_CONSOLE_COLOR_RED);
|
||||
fu_string_append(str, idt + 1, tmp, color);
|
||||
tmp = NULL;
|
||||
}
|
||||
@ -1780,12 +1606,12 @@ fu_util_plugin_flag_to_cli_text(FwupdPluginFlags plugin_flag)
|
||||
case FWUPD_PLUGIN_FLAG_MODULAR:
|
||||
case FWUPD_PLUGIN_FLAG_MEASURE_SYSTEM_INTEGRITY:
|
||||
case FWUPD_PLUGIN_FLAG_SECURE_CONFIG:
|
||||
return fu_util_term_format(fu_util_plugin_flag_to_string(plugin_flag),
|
||||
FU_UTIL_TERM_COLOR_GREEN);
|
||||
return fu_console_color_format(fu_util_plugin_flag_to_string(plugin_flag),
|
||||
FU_CONSOLE_COLOR_GREEN);
|
||||
case FWUPD_PLUGIN_FLAG_DISABLED:
|
||||
case FWUPD_PLUGIN_FLAG_NO_HARDWARE:
|
||||
return fu_util_term_format(fu_util_plugin_flag_to_string(plugin_flag),
|
||||
FU_UTIL_TERM_COLOR_BLACK);
|
||||
return fu_console_color_format(fu_util_plugin_flag_to_string(plugin_flag),
|
||||
FU_CONSOLE_COLOR_BLACK);
|
||||
case FWUPD_PLUGIN_FLAG_LEGACY_BIOS:
|
||||
case FWUPD_PLUGIN_FLAG_CAPSULES_UNSUPPORTED:
|
||||
case FWUPD_PLUGIN_FLAG_UNLOCK_REQUIRED:
|
||||
@ -1793,8 +1619,8 @@ fu_util_plugin_flag_to_cli_text(FwupdPluginFlags plugin_flag)
|
||||
case FWUPD_PLUGIN_FLAG_EFIVAR_NOT_MOUNTED:
|
||||
case FWUPD_PLUGIN_FLAG_ESP_NOT_FOUND:
|
||||
case FWUPD_PLUGIN_FLAG_KERNEL_TOO_OLD:
|
||||
return fu_util_term_format(fu_util_plugin_flag_to_string(plugin_flag),
|
||||
FU_UTIL_TERM_COLOR_RED);
|
||||
return fu_console_color_format(fu_util_plugin_flag_to_string(plugin_flag),
|
||||
FU_CONSOLE_COLOR_RED);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -2334,16 +2160,16 @@ fu_security_attr_append_str(FwupdSecurityAttr *attr,
|
||||
for (guint i = fu_strwidth(name); i < 30; i++)
|
||||
g_string_append(str, " ");
|
||||
if (fwupd_security_attr_has_flag(attr, FWUPD_SECURITY_ATTR_FLAG_OBSOLETED)) {
|
||||
g_autofree gchar *fmt = fu_util_term_format(fu_security_attr_get_result(attr),
|
||||
FU_UTIL_TERM_COLOR_YELLOW);
|
||||
g_autofree gchar *fmt = fu_console_color_format(fu_security_attr_get_result(attr),
|
||||
FU_CONSOLE_COLOR_YELLOW);
|
||||
g_string_append(str, fmt);
|
||||
} else if (fwupd_security_attr_has_flag(attr, FWUPD_SECURITY_ATTR_FLAG_SUCCESS)) {
|
||||
g_autofree gchar *fmt = fu_util_term_format(fu_security_attr_get_result(attr),
|
||||
FU_UTIL_TERM_COLOR_GREEN);
|
||||
g_autofree gchar *fmt = fu_console_color_format(fu_security_attr_get_result(attr),
|
||||
FU_CONSOLE_COLOR_GREEN);
|
||||
g_string_append(str, fmt);
|
||||
} else {
|
||||
g_autofree gchar *fmt =
|
||||
fu_util_term_format(fu_security_attr_get_result(attr), FU_UTIL_TERM_COLOR_RED);
|
||||
g_autofree gchar *fmt = fu_console_color_format(fu_security_attr_get_result(attr),
|
||||
FU_CONSOLE_COLOR_RED);
|
||||
g_string_append(str, fmt);
|
||||
}
|
||||
if ((flags & FU_SECURITY_ATTR_TO_STRING_FLAG_SHOW_URLS) > 0 &&
|
||||
@ -2545,9 +2371,9 @@ fu_util_security_events_to_string(GPtrArray *events, FuSecurityAttrToStringFlags
|
||||
if (eventstr == NULL)
|
||||
continue;
|
||||
if (fwupd_security_attr_has_flag(attr, FWUPD_SECURITY_ATTR_FLAG_SUCCESS)) {
|
||||
check = fu_util_term_format("✔", FU_UTIL_TERM_COLOR_GREEN);
|
||||
check = fu_console_color_format("✔", FU_CONSOLE_COLOR_GREEN);
|
||||
} else {
|
||||
check = fu_util_term_format("✘", FU_UTIL_TERM_COLOR_RED);
|
||||
check = fu_console_color_format("✘", FU_CONSOLE_COLOR_RED);
|
||||
}
|
||||
if (str->len == 0) {
|
||||
/* TRANSLATORS: title for host security events */
|
||||
@ -2820,7 +2646,8 @@ fu_util_device_order_sort_cb(gconstpointer a, gconstpointer b)
|
||||
}
|
||||
|
||||
gboolean
|
||||
fu_util_switch_branch_warning(FwupdDevice *dev,
|
||||
fu_util_switch_branch_warning(FuConsole *console,
|
||||
FwupdDevice *dev,
|
||||
FwupdRelease *rel,
|
||||
gboolean assume_yes,
|
||||
GError **error)
|
||||
@ -2863,13 +2690,14 @@ fu_util_switch_branch_warning(FwupdDevice *dev,
|
||||
title = g_strdup_printf(_("Switch branch from %s to %s?"),
|
||||
fu_util_branch_for_display(fwupd_device_get_branch(dev)),
|
||||
fu_util_branch_for_display(fwupd_release_get_branch(rel)));
|
||||
fu_util_warning_box(title, desc_full->str, 80);
|
||||
fu_console_box(console, title, desc_full->str, 80);
|
||||
if (!assume_yes) {
|
||||
/* ask for permission */
|
||||
g_print("\n%s [y|N]: ",
|
||||
/* TRANSLATORS: should the branch be changed */
|
||||
_("Do you understand the consequences of changing the firmware branch?"));
|
||||
if (!fu_util_prompt_for_boolean(FALSE)) {
|
||||
if (!fu_console_input_bool(console,
|
||||
FALSE,
|
||||
"%s",
|
||||
/* TRANSLATORS: should the branch be changed */
|
||||
_("Do you understand the consequences "
|
||||
"of changing the firmware branch?"))) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOTHING_TO_DO,
|
||||
@ -2881,7 +2709,7 @@ fu_util_switch_branch_warning(FwupdDevice *dev,
|
||||
}
|
||||
|
||||
gboolean
|
||||
fu_util_prompt_warning_fde(FwupdDevice *dev, GError **error)
|
||||
fu_util_prompt_warning_fde(FuConsole *console, FwupdDevice *dev, GError **error)
|
||||
{
|
||||
const gchar *url = "https://github.com/fwupd/fwupd/wiki/Full-Disk-Encryption-Detected";
|
||||
g_autoptr(GString) str = g_string_new(NULL);
|
||||
@ -2904,13 +2732,10 @@ fu_util_prompt_warning_fde(FwupdDevice *dev, GError **error)
|
||||
_("See %s for more details."),
|
||||
url);
|
||||
/* TRANSLATORS: title text, shown as a warning */
|
||||
fu_util_warning_box(_("Full Disk Encryption Detected"), str->str, 80);
|
||||
fu_console_box(console, _("Full Disk Encryption Detected"), str->str, 80);
|
||||
|
||||
/* ask for confirmation */
|
||||
g_print("\n%s [Y|n]: ",
|
||||
/* TRANSLATORS: prompt to apply the update */
|
||||
_("Perform operation?"));
|
||||
if (!fu_util_prompt_for_boolean(TRUE)) {
|
||||
/* TRANSLATORS: prompt to apply the update */
|
||||
if (!fu_console_input_bool(console, TRUE, "%s", _("Perform operation?"))) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOTHING_TO_DO,
|
||||
@ -2921,19 +2746,17 @@ fu_util_prompt_warning_fde(FwupdDevice *dev, GError **error)
|
||||
}
|
||||
|
||||
void
|
||||
fu_util_show_unsupported_warn(void)
|
||||
fu_util_show_unsupported_warning(FuConsole *console)
|
||||
{
|
||||
#ifndef SUPPORTED_BUILD
|
||||
g_autofree gchar *fmt = NULL;
|
||||
|
||||
if (g_getenv("FWUPD_SUPPORTED") != NULL)
|
||||
return;
|
||||
/* TRANSLATORS: this is a prefix on the console */
|
||||
fmt = fu_util_term_format(_("WARNING:"), FU_UTIL_TERM_COLOR_YELLOW);
|
||||
g_printerr("%s %s\n",
|
||||
fmt,
|
||||
/* TRANSLATORS: unsupported build of the package */
|
||||
_("This package has not been validated, it may not work properly."));
|
||||
fu_console_print_full(console,
|
||||
FU_CONSOLE_PRINT_FLAG_WARNING | FU_CONSOLE_PRINT_FLAG_STDERR,
|
||||
"%s\n",
|
||||
/* TRANSLATORS: unsupported build of the package */
|
||||
_("This package has not been validated, it may not work properly."));
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -2954,67 +2777,7 @@ fu_util_is_url(const gchar *perhaps_url)
|
||||
}
|
||||
|
||||
gboolean
|
||||
fu_util_setup_interactive_console(GError **error)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
HANDLE hOut;
|
||||
DWORD dwMode = 0;
|
||||
|
||||
/* enable VT sequences */
|
||||
hOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
if (hOut == INVALID_HANDLE_VALUE) {
|
||||
g_set_error(error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_SUPPORTED,
|
||||
"failed to get stdout [%u]",
|
||||
(guint)GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
if (!GetConsoleMode(hOut, &dwMode)) {
|
||||
g_set_error(error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_SUPPORTED,
|
||||
"failed to get mode [%u]",
|
||||
(guint)GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
|
||||
if (!SetConsoleMode(hOut, dwMode)) {
|
||||
g_set_error(error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_SUPPORTED,
|
||||
"failed to set mode [%u]",
|
||||
(guint)GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
if (!SetConsoleOutputCP(CP_UTF8)) {
|
||||
g_set_error(error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_SUPPORTED,
|
||||
"failed to set output UTF-8 [%u]",
|
||||
(guint)GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
if (!SetConsoleCP(CP_UTF8)) {
|
||||
g_set_error(error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_SUPPORTED,
|
||||
"failed to set UTF-8 [%u]",
|
||||
(guint)GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
#else
|
||||
if (isatty(fileno(stdout)) == 0) {
|
||||
g_set_error_literal(error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "not a TTY");
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
/* success */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
fu_util_print_builder(JsonBuilder *builder, GError **error)
|
||||
fu_util_print_builder(FuConsole *console, JsonBuilder *builder, GError **error)
|
||||
{
|
||||
g_autofree gchar *data = NULL;
|
||||
g_autoptr(JsonGenerator) json_generator = NULL;
|
||||
@ -3035,12 +2798,12 @@ fu_util_print_builder(JsonBuilder *builder, GError **error)
|
||||
}
|
||||
|
||||
/* just print */
|
||||
g_print("%s\n", data);
|
||||
fu_console_print_literal(console, data);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
fu_util_print_error_as_json(const GError *error)
|
||||
fu_util_print_error_as_json(FuConsole *console, const GError *error)
|
||||
{
|
||||
g_autoptr(JsonBuilder) builder = json_builder_new();
|
||||
json_builder_begin_object(builder);
|
||||
@ -3054,7 +2817,7 @@ fu_util_print_error_as_json(const GError *error)
|
||||
json_builder_add_string_value(builder, error->message);
|
||||
json_builder_end_object(builder);
|
||||
json_builder_end_object(builder);
|
||||
fu_util_print_builder(builder, NULL);
|
||||
fu_util_print_builder(console, builder, NULL);
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
@ -3104,7 +2867,7 @@ fu_util_print_version_key_valid(const gchar *key)
|
||||
}
|
||||
|
||||
gboolean
|
||||
fu_util_project_versions_as_json(GHashTable *metadata, GError **error)
|
||||
fu_util_project_versions_as_json(FuConsole *console, GHashTable *metadata, GError **error)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
const gchar *key;
|
||||
@ -3138,7 +2901,7 @@ fu_util_project_versions_as_json(GHashTable *metadata, GError **error)
|
||||
}
|
||||
json_builder_end_array(builder);
|
||||
json_builder_end_object(builder);
|
||||
return fu_util_print_builder(builder, error);
|
||||
return fu_util_print_builder(console, builder, error);
|
||||
}
|
||||
|
||||
gchar *
|
||||
|
@ -13,6 +13,8 @@
|
||||
#include "fwupd-bios-setting-private.h"
|
||||
#include "fwupd-security-attr-private.h"
|
||||
|
||||
#include "fu-console.h"
|
||||
|
||||
/* this is only valid for tools */
|
||||
#define FWUPD_ERROR_INVALID_ARGS (FWUPD_ERROR_LAST + 1)
|
||||
|
||||
@ -33,44 +35,26 @@ typedef enum {
|
||||
FU_SECURITY_ATTR_TO_STRING_FLAG_LAST
|
||||
} FuSecurityAttrToStringFlags;
|
||||
|
||||
typedef enum {
|
||||
FU_UTIL_TERM_COLOR_BLACK = 30,
|
||||
FU_UTIL_TERM_COLOR_RED = 31,
|
||||
FU_UTIL_TERM_COLOR_GREEN = 32,
|
||||
FU_UTIL_TERM_COLOR_YELLOW = 33,
|
||||
FU_UTIL_TERM_COLOR_BLUE = 34,
|
||||
FU_UTIL_TERM_COLOR_MAGENTA = 35,
|
||||
FU_UTIL_TERM_COLOR_CYAN = 36,
|
||||
FU_UTIL_TERM_COLOR_WHITE = 37,
|
||||
} FuUtilTermColor;
|
||||
|
||||
void
|
||||
fu_util_print_data(const gchar *title, const gchar *msg);
|
||||
gchar *
|
||||
fu_util_term_format(const gchar *text, FuUtilTermColor fg_color);
|
||||
guint
|
||||
fu_util_prompt_for_number(guint maxnum);
|
||||
gboolean
|
||||
fu_util_prompt_for_boolean(gboolean def);
|
||||
|
||||
void
|
||||
fu_util_print_tree(FwupdClient *client, GNode *n);
|
||||
fu_util_print_tree(FuConsole *console, FwupdClient *client, GNode *n);
|
||||
gboolean
|
||||
fu_util_is_interesting_device(FwupdDevice *dev);
|
||||
gchar *
|
||||
fu_util_get_user_cache_path(const gchar *fn);
|
||||
|
||||
void
|
||||
fu_util_warning_box(const gchar *title, const gchar *body, guint width);
|
||||
gboolean
|
||||
fu_util_prompt_warning(FwupdDevice *device,
|
||||
fu_util_prompt_warning(FuConsole *console,
|
||||
FwupdDevice *device,
|
||||
FwupdRelease *release,
|
||||
const gchar *machine,
|
||||
GError **error);
|
||||
gboolean
|
||||
fu_util_prompt_warning_fde(FwupdDevice *dev, GError **error);
|
||||
fu_util_prompt_warning_fde(FuConsole *console, FwupdDevice *dev, GError **error);
|
||||
gboolean
|
||||
fu_util_prompt_complete(FwupdDeviceFlags flags, gboolean prompt, GError **error);
|
||||
fu_util_prompt_complete(FuConsole *console,
|
||||
FwupdDeviceFlags flags,
|
||||
gboolean prompt,
|
||||
GError **error);
|
||||
gboolean
|
||||
fu_util_update_reboot(GError **error);
|
||||
|
||||
@ -145,21 +129,20 @@ gint
|
||||
fu_util_device_order_sort_cb(gconstpointer a, gconstpointer b);
|
||||
|
||||
gboolean
|
||||
fu_util_switch_branch_warning(FwupdDevice *dev,
|
||||
fu_util_switch_branch_warning(FuConsole *console,
|
||||
FwupdDevice *dev,
|
||||
FwupdRelease *rel,
|
||||
gboolean assume_yes,
|
||||
GError **error);
|
||||
void
|
||||
fu_util_show_unsupported_warn(void);
|
||||
fu_util_show_unsupported_warning(FuConsole *console);
|
||||
gboolean
|
||||
fu_util_is_url(const gchar *perhaps_url);
|
||||
gboolean
|
||||
fu_util_setup_interactive_console(GError **error);
|
||||
gboolean
|
||||
fu_util_print_builder(JsonBuilder *builder, GError **error);
|
||||
fu_util_print_builder(FuConsole *console, JsonBuilder *builder, GError **error);
|
||||
void
|
||||
fu_util_print_error_as_json(const GError *error);
|
||||
fu_util_print_error_as_json(FuConsole *console, const GError *error);
|
||||
gchar *
|
||||
fu_util_project_versions_to_string(GHashTable *metadata);
|
||||
gboolean
|
||||
fu_util_project_versions_as_json(GHashTable *metadata, GError **error);
|
||||
fu_util_project_versions_as_json(FuConsole *console, GHashTable *metadata, GError **error);
|
||||
|
641
src/fu-util.c
641
src/fu-util.c
File diff suppressed because it is too large
Load Diff
@ -80,7 +80,7 @@ endif
|
||||
fwupdutil = library(
|
||||
'fwupdutil',
|
||||
sources: [
|
||||
'fu-progressbar.c',
|
||||
'fu-console.c',
|
||||
'fu-security-attr-common.c',
|
||||
'fu-util-bios-setting.c',
|
||||
'fu-util-common.c',
|
||||
|
Loading…
Reference in New Issue
Block a user