]> Savannah Git Hosting - gnulib.git/commitdiff
readutmp: Return a boot time also on OpenBSD.
authorBruno Haible <bruno@clisp.org>
Wed, 9 Aug 2023 20:52:22 +0000 (22:52 +0200)
committerBruno Haible <bruno@clisp.org>
Wed, 9 Aug 2023 20:52:22 +0000 (22:52 +0200)
* lib/readutmp.h (BOOT_TIME, USER_PROCESS): Provide fallback
definitions.
* lib/readutmp.c (read_utmp_from_file) [__OpenBSD__]: Fake a BOOT_TIME
entry by looking at the time stamp of a specific file.

ChangeLog
lib/readutmp.c
lib/readutmp.h

index c6e700185977ebfd88c7a279c2245e517336c7cd..6fde91a679ac15e6d7b14aeaf5791171de418a51 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2023-08-09  Bruno Haible  <bruno@clisp.org>
 
+       readutmp: Return a boot time also on OpenBSD.
+       * lib/readutmp.h (BOOT_TIME, USER_PROCESS): Provide fallback
+       definitions.
+       * lib/readutmp.c (read_utmp_from_file) [__OpenBSD__]: Fake a BOOT_TIME
+       entry by looking at the time stamp of a specific file.
+
        readutmp: Return a boot time also on Alpine Linux.
        * lib/readutmp.c: Include stat-time.h.
        (SIZEOF): New macro.
index 2eb3395e0c436b34dd7e1f422ebce2a3890e8b87..537846c1446b6ab5eb6043a5df1841247517bfae 100644 (file)
@@ -496,6 +496,42 @@ read_utmp_from_file (char const *file, idx_t *n_entries, STRUCT_UTMP **utmp_buf,
       return -1;
     }
 
+#  if defined __OpenBSD__
+  /* On OpenBSD, UTMP_FILE is not filled.  It contains only dummy entries.
+     So, fake a BOOT_TIME entry, by getting the time stamp of a file that
+     gets touched only during the boot process.  */
+  if ((options & (READ_UTMP_USER_PROCESS | READ_UTMP_NO_BOOT_TIME)) == 0
+      && strcmp (file, UTMP_FILE) == 0)
+    {
+      /* OpenBSD's 'struct utmp' does not have an ut_type field.  */
+      bool have_boot_time = false;
+      if (!have_boot_time)
+        {
+          const char * const boot_touched_files[] =
+            {
+              "/var/db/host.random",
+              "/var/run/utmp"
+            };
+          for (idx_t i = 0; i < SIZEOF (boot_touched_files); i++)
+            {
+              const char *filename = boot_touched_files[i];
+              struct stat statbuf;
+              if (stat (filename, &statbuf) >= 0)
+                {
+                  struct timespec boot_time = get_stat_mtime (&statbuf);
+                  a = add_utmp (a, options,
+                                "reboot", strlen ("reboot"),
+                                "", 0,
+                                "", strlen (""),
+                                "", 0,
+                                0, BOOT_TIME, boot_time, 0, 0, 0);
+                  break;
+                }
+            }
+        }
+    }
+#  endif
+
 # endif
 
   a = finish_utmp (a);
index 88c0d943036fe48485d0f481a169582b7d890f35..b74d37cde391bcf60d002d053d689bd15eb722ca 100644 (file)
@@ -211,6 +211,14 @@ enum { UT_HOST_SIZE = -1 };
 # define WTMP_FILE "/etc/wtmp"
 #endif
 
+/* Some platforms, such as OpenBSD, don't have an ut_type field and don't have
+   the BOOT_TIME and USER_PROCESS macros.  But we want to support them in
+   'struct gl_utmp'.  */
+#if !(HAVE_UTMPX_H ? HAVE_STRUCT_UTMPX_UT_TYPE : HAVE_STRUCT_UTMP_UT_TYPE)
+# define BOOT_TIME 2
+# define USER_PROCESS 0
+#endif
+
 /* Macros that test (UT)->ut_type.  */
 #ifdef BOOT_TIME
 # define UT_TYPE_BOOT_TIME(UT) UT_TYPE_EQ (UT, BOOT_TIME)