diff options
Diffstat (limited to 'term-utils/wall.c')
-rw-r--r-- | term-utils/wall.c | 84 |
1 files changed, 62 insertions, 22 deletions
diff --git a/term-utils/wall.c b/term-utils/wall.c index 377db45..588d3a9 100644 --- a/term-utils/wall.c +++ b/term-utils/wall.c @@ -61,6 +61,11 @@ #include <sys/types.h> #include <grp.h> +#if defined(USE_SYSTEMD) && HAVE_DECL_SD_SESSION_GET_USERNAME == 1 +# include <systemd/sd-login.h> +# include <systemd/sd-daemon.h> +#endif + #include "nls.h" #include "xalloc.h" #include "strutils.h" @@ -96,8 +101,8 @@ static void __attribute__((__noreturn__)) usage(void) fputs(_(" -n, --nobanner do not print banner, works only for root\n"), out); fputs(_(" -t, --timeout <timeout> write timeout in seconds\n"), out); fputs(USAGE_SEPARATOR, out); - printf(USAGE_HELP_OPTIONS(25)); - printf(USAGE_MAN_TAIL("wall(1)")); + fprintf(out, USAGE_HELP_OPTIONS(25)); + fprintf(out, USAGE_MAN_TAIL("wall(1)")); exit(EXIT_SUCCESS); } @@ -135,7 +140,7 @@ static struct group_workspace *init_group_workspace(const char *group) buf->requested_group = get_group_gid(group); buf->ngroups = sysconf(_SC_NGROUPS_MAX) + 1; /* room for the primary gid */ - buf->groups = xcalloc(sizeof(*buf->groups), buf->ngroups); + buf->groups = xcalloc(buf->ngroups, sizeof(*buf->groups)); return buf; } @@ -246,29 +251,64 @@ int main(int argc, char **argv) iov.iov_base = mbuf; iov.iov_len = mbufsize; - while((utmpptr = getutxent())) { - if (!utmpptr->ut_user[0]) - continue; + +#if defined(USE_SYSTEMD) && HAVE_DECL_SD_SESSION_GET_USERNAME == 1 + if (sd_booted() > 0) { + char **sessions_list; + int sessions; + + sessions = sd_get_sessions(&sessions_list); + if (sessions < 0) + errx(EXIT_FAILURE, _("error getting sessions: %s"), + strerror(-sessions)); + + 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); + } + } + free(name); + free(sessions_list[i]); + } + free(sessions_list); + } else +#endif + { + while ((utmpptr = getutxent())) { + if (!utmpptr->ut_user[0]) + continue; #ifdef USER_PROCESS - if (utmpptr->ut_type != USER_PROCESS) - continue; + if (utmpptr->ut_type != USER_PROCESS) + continue; #endif - /* Joey Hess reports that use-sessreg in /etc/X11/wdm/ produces - * ut_line entries like :0, and a write to /dev/:0 fails. - * - * It also seems that some login manager may produce empty ut_line. - */ - if (!*utmpptr->ut_line || *utmpptr->ut_line == ':') - continue; + /* Joey Hess reports that use-sessreg in /etc/X11/wdm/ produces + * ut_line entries like :0, and a write to /dev/:0 fails. + * + * It also seems that some login manager may produce empty ut_line. + */ + if (!*utmpptr->ut_line || *utmpptr->ut_line == ':') + continue; - if (group_buf && !is_gr_member(utmpptr->ut_user, group_buf)) - continue; + if (group_buf && !is_gr_member(utmpptr->ut_user, group_buf)) + continue; - mem2strcpy(line, utmpptr->ut_line, sizeof(utmpptr->ut_line), sizeof(line)); - if ((p = ttymsg(&iov, 1, line, timeout)) != NULL) - warnx("%s", p); + mem2strcpy(line, utmpptr->ut_line, sizeof(utmpptr->ut_line), sizeof(line)); + if ((p = ttymsg(&iov, 1, line, timeout)) != NULL) + warnx("%s", p); + } + endutxent(); } - endutxent(); + free(mbuf); free_group_workspace(group_buf); exit(EXIT_SUCCESS); @@ -328,7 +368,7 @@ static char *makemsg(char *fname, char **mvec, int mvecsz, int i; for (i = 0; i < mvecsz; i++) { - fputs(mvec[i], fs); + fputs_careful(mvec[i], fs, '^', true, TERM_WIDTH); if (i < mvecsz - 1) fputc(' ', fs); } |