chiark / gitweb /
Fix service file to match installed elogind binary location
[elogind.git] / src / shared / utmp-wtmp.c
index 7fb6fe3a6751602718039b2a8da55772cbaca2e7..9750dcd81722f0ba25843e520784b7374f61d398 100644 (file)
@@ -1,5 +1,3 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
 /***
   This file is part of systemd.
 
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
-#include <utmpx.h>
 #include <errno.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
+#include <sys/time.h>
 #include <sys/utsname.h>
-#include <fcntl.h>
 #include <unistd.h>
-#include <poll.h>
+#include <utmpx.h>
 
+#include "alloc-util.h"
+#include "fd-util.h"
+#include "hostname-util.h"
 #include "macro.h"
 #include "path-util.h"
+#include "string-util.h"
+#include "terminal-util.h"
+#include "time-util.h"
+#include "user-util.h"
+#include "util.h"
 #include "utmp-wtmp.h"
 
 int utmp_get_runlevel(int *runlevel, int *previous) {
@@ -202,12 +212,13 @@ _pure_ static const char *sanitize_id(const char *id) {
         return id + l - sizeof(((struct utmpx*) NULL)->ut_id);
 }
 
-int utmp_put_init_process(const char *id, pid_t pid, pid_t sid, const char *line) {
+int utmp_put_init_process(const char *id, pid_t pid, pid_t sid, const char *line, int ut_type, const char *user) {
         struct utmpx store = {
                 .ut_type = INIT_PROCESS,
                 .ut_pid = pid,
                 .ut_session = sid,
         };
+        int r;
 
         assert(id);
 
@@ -219,7 +230,26 @@ int utmp_put_init_process(const char *id, pid_t pid, pid_t sid, const char *line
         if (line)
                 strncpy(store.ut_line, basename(line), sizeof(store.ut_line));
 
-        return write_entry_both(&store);
+        r = write_entry_both(&store);
+        if (r < 0)
+                return r;
+
+        if (ut_type == LOGIN_PROCESS || ut_type == USER_PROCESS) {
+                store.ut_type = LOGIN_PROCESS;
+                r = write_entry_both(&store);
+                if (r < 0)
+                        return r;
+        }
+
+        if (ut_type == USER_PROCESS) {
+                store.ut_type = USER_PROCESS;
+                strncpy(store.ut_user, user, sizeof(store.ut_user)-1);
+                r = write_entry_both(&store);
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
 }
 
 int utmp_put_dead_process(const char *id, pid_t pid, int code, int status) {
@@ -346,8 +376,14 @@ static int write_to_terminal(const char *tty, const char *message) {
         return 0;
 }
 
-int utmp_wall(const char *message, const char *username, bool (*match_tty)(const char *tty)) {
-        _cleanup_free_ char *text = NULL, *hn = NULL, *un = NULL, *tty = NULL;
+int utmp_wall(
+        const char *message,
+        const char *username,
+        const char *origin_tty,
+        bool (*match_tty)(const char *tty, void *userdata),
+        void *userdata) {
+
+        _cleanup_free_ char *text = NULL, *hn = NULL, *un = NULL, *stdin_tty = NULL;
         char date[FORMAT_TIMESTAMP_MAX];
         struct utmpx *u;
         int r;
@@ -361,14 +397,17 @@ int utmp_wall(const char *message, const char *username, bool (*match_tty)(const
                         return -ENOMEM;
         }
 
-        getttyname_harder(STDIN_FILENO, &tty);
+        if (!origin_tty) {
+                getttyname_harder(STDIN_FILENO, &stdin_tty);
+                origin_tty = stdin_tty;
+        }
 
         if (asprintf(&text,
                      "\a\r\n"
                      "Broadcast message from %s@%s%s%s (%s):\r\n\r\n"
                      "%s\r\n\r\n",
                      un ?: username, hn,
-                     tty ? " on " : "", strempty(tty),
+                     origin_tty ? " on " : "", strempty(origin_tty),
                      format_timestamp(date, sizeof(date), now(CLOCK_REALTIME)),
                      message) < 0)
                 return -ENOMEM;
@@ -395,7 +434,7 @@ int utmp_wall(const char *message, const char *username, bool (*match_tty)(const
                         path = buf;
                 }
 
-                if (!match_tty || match_tty(path)) {
+                if (!match_tty || match_tty(path, userdata)) {
                         q = write_to_terminal(path, text);
                         if (q < 0)
                                 r = q;