aboutsummaryrefslogtreecommitdiff
path: root/src/utmp.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2013-01-05 11:56:51 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2013-01-05 11:56:51 +0200
commit4f7c28158308563dcad912d87a0031d095d4690a (patch)
treef8badf11119135268fb58b77e86667b12d0f090c /src/utmp.c
parentd8221ce9bdd2d7ae6162bed0e1c85e9f7a3ff8f2 (diff)
downloadpies-4f7c28158308563dcad912d87a0031d095d4690a.tar.gz
pies-4f7c28158308563dcad912d87a0031d095d4690a.tar.bz2
Write utmp/wtmp records in sysvinit mode.
* configure.ac: Check for utmp.h, utmpx.h * src/utmp.c: New file. * src/Makefile.am: Add utmp.c * src/pies.h (sysvinit_acct): New proto. * src/progman.c (prog_start, progman_cleanup): Call sysvinit_acct. * src/sysvinit.c (inittrans): Call sysvinit_acct. Set proctitle.
Diffstat (limited to 'src/utmp.c')
-rw-r--r--src/utmp.c179
1 files changed, 179 insertions, 0 deletions
diff --git a/src/utmp.c b/src/utmp.c
new file mode 100644
index 0000000..d4452bc
--- /dev/null
+++ b/src/utmp.c
@@ -0,0 +1,179 @@
+/* This file is part of GNU Pies.
+ Copyright (C) 2013 Sergey Poznyakoff
+
+ GNU Pies is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GNU Pies is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU Pies. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "pies.h"
+#include <fcntl.h>
+#include <sys/utsname.h>
+#include <paths.h>
+
+#ifdef HAVE_UTMPX_H
+# include <utmpx.h>
+typedef struct utmpx UTMPX;
+# if HAVE_UPDWTMPX
+# define pies_updwtmpx updwtmpx
+# endif
+# define GETUTXID getutxid
+# undef UTMP_FILE
+# define UTMP_FILE UTMPX_FILE
+# undef WTMP_FILE
+# define WTMP_FILE WTMPX_FILE
+# if defined HAVE_STRUCT_UTMPX_UT_NAME
+# define UT_NAME(u) ((u)->ut_name)
+# elif defined HAVE_STRUCT_UTMPX_UT_USER
+# define UT_NAME(u) ((u)->ut_user)
+# endif
+#else
+# include <utmp.h>
+typedef struct utmp UTMPX;
+# if defined HAVE_STRUCT_UTMP_UT_NAME
+# define UT_NAME(u) ((u)->ut_name)
+# elif defined HAVE_STRUCT_UTMP_UT_USER
+# define UT_NAME(u) ((u)->ut_user)
+# endif
+# if HAVE_UPDWTMP
+# define pies_updwtmpx updwtmp
+# endif
+# define GETUTXID getutid
+# define setutxent setutent
+# define pututxline pututline
+# define endutxent endutent
+#endif
+
+
+#ifndef pies_updwtmpx
+static void
+pies_updwtmpx (const char *wtmp_file, const UTMPX *ut)
+{
+ int fd = open (wtmp_file, O_WRONLY|O_APPEND);
+ if (fd == -1)
+ return;
+ write (fd, ut, sizeof (*ut));
+ close (fd);
+}
+#endif
+
+static UTMPX *
+pies_getutxid (const UTMPX *ut)
+{
+ static UTMPX tmp;
+ memcpy (&tmp, ut, sizeof (*ut));
+ return GETUTXID (&tmp);
+}
+
+void
+fill_utmp (UTMPX *utmp,
+ int type, const char *user, const char *id, pid_t pid,
+ const char *line)
+{
+#if defined HAVE_STRUCT_UTMP_UT_HOST
+ struct utsname uts;
+#endif
+#if defined HAVE_STRUCT_UTMP_UT_TV
+ struct timeval tv;
+#endif
+
+ memset (utmp, 0, sizeof (*utmp));
+#if defined(HAVE_STRUCT_UTMP_UT_TV) || defined(HAVE_STRUCT_UTMPX_UT_TV)
+ gettimeofday (&tv, 0);
+ utmp->ut_tv.tv_sec = tv.tv_sec;
+ utmp->ut_tv.tv_usec = tv.tv_usec;
+#elif defined(HAVE_STRUCT_UTMP_UT_TIME) || defined(HAVE_STRUCT_UTMPX_UT_TIME)
+ time (&utmp->ut_time);
+#endif
+ utmp->ut_type = type;
+ strncpy (UT_NAME (utmp), user, sizeof (UT_NAME (utmp)));
+ strncpy (utmp->ut_id, id, sizeof (utmp->ut_id));
+ utmp->ut_pid = pid;
+ strncpy (utmp->ut_line, line, sizeof(utmp->ut_line));
+#if defined(HAVE_STRUCT_UTMP_UT_HOST) || defined(HAVE_STRUCT_UTMPX_UT_HOST)
+ if (uname (&uts) == 0)
+ strncpy (utmp->ut_host, uts.release, sizeof(utmp->ut_host));
+#endif
+}
+
+
+int wtmpxreboot = 0;
+
+void
+write_wtmpx (int type, const char *user, const char *id, pid_t pid,
+ const char *line)
+{
+ UTMPX utmp;
+
+ if (access (WTMP_FILE, W_OK))
+ {
+ logmsg (LOG_NOTICE, _("cannot open %s for writing"), WTMP_FILE);
+ if (type == BOOT_TIME)
+ wtmpxreboot++;
+ return;
+ }
+
+ if (wtmpxreboot)
+ {
+ write_wtmpx (BOOT_TIME, "reboot", "~~", 0, "~");
+ --wtmpxreboot;
+ }
+ fill_utmp (&utmp, type, user, id, pid, line);
+ pies_updwtmpx (WTMP_FILE, &utmp);
+}
+
+int utmpreboot = 0;
+
+void
+write_utmpx (int type, const char *user, const char *id, pid_t pid,
+ const char *line)
+{
+ UTMPX utmp;
+
+ if (access (UTMP_FILE, W_OK))
+ {
+ logmsg (LOG_NOTICE, _("cannot open %s for writing"), UTMP_FILE);
+ if (type == BOOT_TIME)
+ utmpreboot++;
+ return;
+ }
+
+ if (utmpreboot)
+ {
+ write_utmpx (BOOT_TIME, "reboot", "~~", 0, "~");
+ --utmpreboot;
+ }
+ fill_utmp (&utmp, type, user, id, pid, line);
+
+ if (type == DEAD_PROCESS)
+ {
+ UTMPX *p = pies_getutxid (&utmp);
+ if (p)
+ strncpy (utmp.ut_line, p->ut_line, sizeof (utmp.ut_line));
+ }
+ setutxent ();
+ pututxline (&utmp);
+ endutxent ();
+}
+
+void
+sysvinit_acct (int what, const char *user, const char *id, pid_t pid,
+ const char *line)
+{
+ static int types[] = {
+ BOOT_TIME,
+ RUN_LVL,
+ INIT_PROCESS,
+ DEAD_PROCESS
+ };
+ write_utmpx (types[what], user, id, pid, line);
+ write_wtmpx (types[what], user, id, pid, line);
+}

Return to:

Send suggestions and report system problems to the System administrator.