util-linux/0015-wall-always-use-utmp-as-fallback.patch
Karel Zak f6ae65c1f8 lscpu: Add NVIDIA Olympus arm64 core
- libfdisk: improve collision reporting
- libfdisk: (dos) ignore incomplete EBR for non-wholedisk
- wall: always use utmp as fallback

Resolves: RHEL-84815 RHEL-59867 RHEL-82162 RHEL-113639
2025-09-29 10:55:25 +02:00

138 lines
3.7 KiB
Diff

From 4184803d9a04643ed9235bafb29e926b11714f52 Mon Sep 17 00:00:00 2001
From: Karel Zak <kzak@redhat.com>
Date: Mon, 3 Jun 2024 14:32:18 +0200
Subject: wall: always use utmp as fallback
Wall(1) can be compiled with systemd support to read the names of ttys
from the systemd session list. However, this may not work on all systems.
In case of failure, the best option is to use the traditional
utmp method as a fallback.
This commit uses strv (string vector) to collect tty names from both
sources (systemd and utmp) and then sends a message to all ttys.
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=2283049
Signed-off-by: Karel Zak <kzak@redhat.com>
(cherry picked from commit 0af497c6688b53a3a176176bfbcdca821bd856ec)
---
term-utils/wall.c | 57 ++++++++++++++++++++++++++++++++---------------
1 file changed, 39 insertions(+), 18 deletions(-)
diff --git a/term-utils/wall.c b/term-utils/wall.c
index 125fde438..22c3918bb 100644
--- a/term-utils/wall.c
+++ b/term-utils/wall.c
@@ -78,6 +78,7 @@
#include "closestream.h"
#include "timeutils.h"
#include "pwdutils.h"
+#include "strv.h"
#define TERM_WIDTH 79
#define WRITE_TIME_OUT 300 /* in seconds */
@@ -190,19 +191,30 @@ static int is_gr_member(const char *login, const struct group_workspace *buf)
return 0;
}
+static int has_tty(char **ttys, char *name)
+{
+ char **str;
+
+ STRV_FOREACH(str, ttys) {
+ if (strcmp(*str, name) == 0)
+ return 1;
+ }
+
+ return 0;
+}
+
int main(int argc, char **argv)
{
int ch;
struct iovec iov;
struct utmpx *utmpptr;
- char *p;
char line[sizeof(utmpptr->ut_line) + 1];
int print_banner = TRUE;
struct group_workspace *group_buf = NULL;
char *mbuf, *fname = NULL;
size_t mbufsize;
unsigned timeout = WRITE_TIME_OUT;
- char **mvec = NULL;
+ char **mvec = NULL, **ttys = NULL, **str;
int mvecsz = 0;
static const struct option longopts[] = {
@@ -265,30 +277,30 @@ int main(int argc, char **argv)
int sessions;
sessions = sd_get_sessions(&sessions_list);
- if (sessions < 0)
- errx(EXIT_FAILURE, _("error getting sessions: %s"),
- strerror(-sessions));
+ if (sessions < 0) {
+ warnx(_("error getting sessions: %s"), strerror(-sessions));
+ goto utmp;
+ }
for (int i = 0; i < sessions; i++) {
char *name, *tty;
int r;
- if ((r = sd_session_get_username(sessions_list[i], &name)) < 0)
- errx(EXIT_FAILURE, _("get user name failed: %s"), strerror (-r));
-
- if (!(group_buf && !is_gr_member(name, group_buf))) {
- if (sd_session_get_tty(sessions_list[i], &tty) >= 0) {
- if ((p = ttymsg(&iov, 1, tty, timeout)) != NULL)
- warnx("%s", p);
-
- free(tty);
- }
+ if ((r = sd_session_get_username(sessions_list[i], &name)) < 0) {
+ warnx(_("get user name failed: %s"), strerror (-r));
+ goto utmp;
}
+ if (!(group_buf && !is_gr_member(name, group_buf))
+ && sd_session_get_tty(sessions_list[i], &tty) >= 0
+ && strv_consume(&ttys, tty) < 0)
+ err(EXIT_FAILURE, _("failed to allocate lines list"));
+
free(name);
free(sessions_list[i]);
}
free(sessions_list);
- } else
+ }
+utmp:
#endif
{
while ((utmpptr = getutxent())) {
@@ -310,12 +322,21 @@ int main(int argc, char **argv)
continue;
mem2strcpy(line, utmpptr->ut_line, sizeof(utmpptr->ut_line), sizeof(line));
- if ((p = ttymsg(&iov, 1, line, timeout)) != NULL)
- warnx("%s", p);
+ if (has_tty(ttys, line))
+ continue;
+ if (strv_extend(&ttys, line) < 0)
+ err(EXIT_FAILURE, _("failed to allocate lines list"));
}
endutxent();
}
+ STRV_FOREACH(str, ttys) {
+ char *er = ttymsg(&iov, 1, *str, timeout);
+ if (er)
+ warnx("%s", er);
+ }
+
+ strv_free(ttys);
free(mbuf);
free_group_workspace(group_buf);
exit(EXIT_SUCCESS);
--
2.50.1