diff options
author | Mike Yuan <me@yhndnzj.com> | 2023-09-08 13:16:46 +0200 |
---|---|---|
committer | Mike Yuan <me@yhndnzj.com> | 2023-09-08 21:19:22 +0200 |
commit | 056aff96b929803705ff946618810986e13ff49a (patch) | |
tree | f30747dee994db72f1e1c0d83be22fb05e89e16e /src | |
parent | utmp-wtmp: remove unneeded include (diff) | |
download | systemd-056aff96b929803705ff946618810986e13ff49a.tar.xz systemd-056aff96b929803705ff946618810986e13ff49a.zip |
shared/wall: several cleanups
Follow-up for 53c0397b1dbc95f144d9a551c2086d132933e8ce
* Split do_wall into wall_utmp and wall_logind
* Don't pass unused arguments
* Add missing asserts
* Modernize error handling
* Don't do anything if neither utmp nor logind is enabled
Diffstat (limited to 'src')
-rw-r--r-- | src/shared/wall.c | 106 | ||||
-rw-r--r-- | src/shared/wall.h | 16 |
2 files changed, 73 insertions, 49 deletions
diff --git a/src/shared/wall.c b/src/shared/wall.c index e2efd96d37..9fdde59eda 100644 --- a/src/shared/wall.c +++ b/src/shared/wall.c @@ -17,6 +17,8 @@ #include "utmp-wtmp.h" #include "wall.h" +#if ENABLE_UTMP || ENABLE_LOGIND + #define TIMEOUT_USEC (50 * USEC_PER_MSEC) static int write_to_terminal(const char *tty, const char *message) { @@ -35,95 +37,90 @@ static int write_to_terminal(const char *tty, const char *message) { } #if ENABLE_UTMP -static int do_wall( +static int wall_utmp( const char *message, - const char *username, - const char *origin_tty, bool (*match_tty)(const char *tty, bool is_local, void *userdata), void *userdata) { _unused_ _cleanup_(utxent_cleanup) bool utmpx = false; struct utmpx *u; - int r; + int r = 0; - utmpx = utxent_start(); + assert(message); - r = 0; + utmpx = utxent_start(); while ((u = getutxent())) { - _cleanup_free_ char *buf = NULL; - const char *path; - int q; + _cleanup_free_ char *p = NULL; + const char *tty_path; + bool is_local; - if (u->ut_type != USER_PROCESS || u->ut_user[0] == 0) + if (u->ut_type != USER_PROCESS || isempty(u->ut_user)) continue; /* This access is fine, because strlen("/dev/") < 32 (UT_LINESIZE) */ if (path_startswith(u->ut_line, "/dev/")) - path = u->ut_line; + tty_path = u->ut_line; else { - if (asprintf(&buf, "/dev/%.*s", (int) sizeof(u->ut_line), u->ut_line) < 0) + if (asprintf(&p, "/dev/%.*s", (int) sizeof(u->ut_line), u->ut_line) < 0) return -ENOMEM; - path = buf; + + tty_path = p; } - /* It seems that the address field is always set for remote logins. - * For local logins and other local entries, we get [0,0,0,0]. */ - bool is_local = memeqzero(u->ut_addr_v6, sizeof(u->ut_addr_v6)); + /* It seems that the address field is always set for remote logins. For local logins and + * other local entries, we get [0,0,0,0]. */ + is_local = eqzero(u->ut_addr_v6); - if (!match_tty || match_tty(path, is_local, userdata)) { - q = write_to_terminal(path, message); - if (q < 0) - r = q; - } + if (!match_tty || match_tty(tty_path, is_local, userdata)) + RET_GATHER(r, write_to_terminal(tty_path, message)); } return r; } +#endif -#else - -static int do_wall( +#if ENABLE_LOGIND +static int wall_logind( const char *message, - const char *username, - const char *origin_tty, bool (*match_tty)(const char *tty, bool is_local, void *userdata), void *userdata) { - int r; _cleanup_strv_free_ char **sessions = NULL; + int r; + + assert(message); r = sd_get_sessions(&sessions); - if (r < 0) + if (r <= 0) return r; + r = 0; + STRV_FOREACH(s, sessions) { - _cleanup_free_ char *path = NULL, *tty = NULL, *rhost = NULL; + _cleanup_free_ char *tty_path = NULL, *tty = NULL, *rhost = NULL; + bool is_local; int q; q = sd_session_get_tty(*s, &tty); - if (q < 0) { - if (q != -ENXIO && q != -ENODATA) - r = q; + if (IN_SET(q, -ENXIO, -ENODATA)) continue; - } + if (q < 0) + return RET_GATHER(r, q); - path = strjoin("/dev/", tty); - if (!path) + tty_path = strjoin("/dev/", tty); + if (!tty_path) return -ENOMEM; (void) sd_session_get_remote_host(*s, &rhost); - bool is_local = !rhost; + is_local = !rhost; - if (!match_tty || match_tty(path, is_local, userdata)) { - q = write_to_terminal(path, message); - if (q < 0) - r = q; - } + if (!match_tty || match_tty(tty_path, is_local, userdata)) + RET_GATHER(r, write_to_terminal(tty_path, message)); } + return r; } - #endif int wall( @@ -133,15 +130,20 @@ int wall( bool (*match_tty)(const char *tty, bool is_local, void *userdata), void *userdata) { - _cleanup_free_ char *text = NULL, *hn = NULL, *un = NULL, *stdin_tty = NULL; + _cleanup_free_ char *text = NULL, *hostname = NULL, *username_alloc = NULL, *stdin_tty = NULL; - hn = gethostname_malloc(); - if (!hn) + assert(message); + + hostname = gethostname_malloc(); + if (!hostname) return -ENOMEM; + if (!username) { - un = getlogname_malloc(); - if (!un) + username_alloc = getlogname_malloc(); + if (!username_alloc) return -ENOMEM; + + username = username_alloc; } if (!origin_tty) { @@ -153,11 +155,17 @@ int wall( "\r\n" "Broadcast message from %s@%s%s%s (%s):\r\n\r\n" "%s\r\n\r\n", - un ?: username, hn, + username, hostname, origin_tty ? " on " : "", strempty(origin_tty), FORMAT_TIMESTAMP(now(CLOCK_REALTIME)), message) < 0) return -ENOMEM; - return do_wall(text, username, origin_tty, match_tty, userdata); +#if ENABLE_UTMP + return wall_utmp(text, match_tty, userdata); +#elif ENABLE_LOGIND + return wall_logind(text, match_tty, userdata); +#endif } + +#endif diff --git a/src/shared/wall.h b/src/shared/wall.h index 4423c39404..29642778c7 100644 --- a/src/shared/wall.h +++ b/src/shared/wall.h @@ -3,9 +3,25 @@ #include <stdbool.h> +#if ENABLE_UTMP || ENABLE_LOGIND + int wall( const char *message, const char *username, const char *origin_tty, bool (*match_tty)(const char *tty, bool is_local, void *userdata), void *userdata); + +#else + +static inline int wall( + const char *message, + const char *username, + const char *origin_tty, + bool (*match_tty)(const char *tty, bool is_local, void *userdata), + void *userdata) { + + return 0; +} + +#endif |