#include "glyph-util.h"
#include "log.h"
#include "memory-util.h"
+#include "plymouth-util.h"
#include "strv.h"
#include "unistd.h"
}
}
+static void plymouth_start_interaction(const char *text, bool *ret_displayed) {
+ assert(ret_displayed);
+
+ if (plymouth_send_msg(text, /* pause_spinner= */ true) < 0)
+ return;
+
+ *ret_displayed = true;
+}
+
+static void plymouth_end_interaction(bool *displayed) {
+ assert(displayed);
+
+ if (!*displayed)
+ return;
+
+ /* In theory 'm' should hide a message, but it doesn't work (long standing issue).
+ * As a workaround, sending a single NUL byte hides the previous messages. */
+ (void) plymouth_send_msg("", /* pause_spinner= */ false);
+}
+
static int fido2_use_hmac_hash_specific_token(
const char *path,
const char *rp_id,
void **ret_hmac,
size_t *ret_hmac_size) {
+ _cleanup_(plymouth_end_interaction) bool plymouth_displayed = false;
_cleanup_(fido_assert_free_wrapper) fido_assert_t *a = NULL;
_cleanup_(fido_dev_free_wrapper) fido_dev_t *d = NULL;
_cleanup_(erase_and_freep) void *hmac_copy = NULL;
enable_disable(FLAGS_SET(required, FIDO2ENROLL_UP)),
sym_fido_strerr(r));
- if (FLAGS_SET(required, FIDO2ENROLL_UP))
+ if (FLAGS_SET(required, FIDO2ENROLL_UP)) {
log_notice("%s%sPlease confirm presence on security token to unlock.",
emoji_enabled() ? glyph(GLYPH_TOUCH) : "",
emoji_enabled() ? " " : "");
+ plymouth_start_interaction("Please confirm presence on security token to unlock.", &plymouth_displayed);
+ }
}
if (has_uv && !FLAGS_SET(required, FIDO2ENROLL_UV_OMIT)) {
enable_disable(FLAGS_SET(required, FIDO2ENROLL_UV)),
sym_fido_strerr(r));
- if (FLAGS_SET(required, FIDO2ENROLL_UV))
+ if (FLAGS_SET(required, FIDO2ENROLL_UV)) {
log_notice("%s%sPlease verify user on security token to unlock.",
emoji_enabled() ? glyph(GLYPH_TOUCH) : "",
emoji_enabled() ? " " : "");
+ plymouth_start_interaction("Please verify user on security token to unlock.", &plymouth_displayed);
+ }
}
for (;;) {
log_notice("%s%sPlease confirm presence on security to unlock.",
emoji_enabled() ? glyph(GLYPH_TOUCH) : "",
emoji_enabled() ? " " : "");
+ plymouth_start_interaction("Please confirm presence on security token to unlock.", &plymouth_displayed);
retry_with_up = true;
}
return loop_write(fd, raw, size);
}
+
+int plymouth_send_msg(const char *text, bool pause_spinner) {
+ _cleanup_free_ char *plymouth_message = NULL;
+ int c, r;
+
+ assert(text);
+ assert(strlen(text) < UCHAR_MAX);
+
+ c = asprintf(&plymouth_message,
+ "M\x02%c%s%c"
+ "%c%c", /* pause/resume spinner */
+ (int) strlen(text) + 1, text, '\x00',
+ pause_spinner ? 'A' : 'a', '\x00');
+ if (c < 0)
+ return log_oom();
+
+ r = plymouth_send_raw(plymouth_message, c, SOCK_NONBLOCK);
+ if (r < 0)
+ return log_full_errno(ERRNO_IS_NO_PLYMOUTH(r) ? LOG_DEBUG : LOG_WARNING, r,
+ "Failed to communicate with plymouth, ignoring: %m");
+
+ return 0;
+}
int plymouth_connect(int flags);
int plymouth_send_raw(const void *raw, size_t size, int flags);
+int plymouth_send_msg(const char *text, bool pause_spinner);
static inline bool ERRNO_IS_NO_PLYMOUTH(int r) {
return IN_SET(abs(r), EAGAIN, ENOENT) || ERRNO_IS_DISCONNECT(r);
return 0;
}
-static int plymouth_send_text(const char *text) {
- _cleanup_free_ char *plymouth_message = NULL;
- int c, r;
-
- assert(text);
-
- c = asprintf(&plymouth_message,
- "M\x02%c%s%c"
- "A%c", /* pause spinner */
- (int) strlen(text) + 1, text, '\x00',
- '\x00');
- if (c < 0)
- return log_oom();
-
- r = plymouth_send_raw(plymouth_message, c, SOCK_NONBLOCK);
- if (r < 0)
- return log_full_errno(ERRNO_IS_NO_PLYMOUTH(r) ? LOG_DEBUG : LOG_WARNING, r,
- "Failed to communicate with plymouth, ignoring: %m");
-
- return 0;
-}
-
static int plymouth_notify_port(NvmePort *port, struct local_address *a) {
_cleanup_free_ char *m = NULL;
if (asprintf(&m, "nvme connect-all -t tcp -a %s -s %" PRIu16, IN_ADDR_TO_STRING(a->family, &a->address), port->portnr) < 0)
return log_oom();
- return plymouth_send_text(m);
+ return plymouth_send_msg(m, /* pause_spinner= */ true);
}
static int nvme_port_report(NvmePort *port, bool *plymouth_done) {
(void) nvme_port_report(c->ipv6_port, &plymouth_done);
if (!plymouth_done)
- (void) plymouth_send_text("Network disconnected.");
+ (void) plymouth_send_msg("Network disconnected.", /* pause_spinner= */ true);
NvmeSubsystem *i;
HASHMAP_FOREACH(i, c->subsystems)
}
if (!plymouth_done)
- (void) plymouth_send_text("Network disconnected.");
+ (void) plymouth_send_msg("Network disconnected.", /* pause_spinner= */ true);
NvmeSubsystem *i;
HASHMAP_FOREACH(i, context.subsystems) {