aboutsummaryrefslogtreecommitdiff
path: root/src/utmp.c
diff options
context:
space:
mode:
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 @@
1/* This file is part of GNU Pies.
2 Copyright (C) 2013 Sergey Poznyakoff
3
4 GNU Pies is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
8
9 GNU Pies is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with GNU Pies. If not, see <http://www.gnu.org/licenses/>. */
16
17#include "pies.h"
18#include <fcntl.h>
19#include <sys/utsname.h>
20#include <paths.h>
21
22#ifdef HAVE_UTMPX_H
23# include <utmpx.h>
24typedef struct utmpx UTMPX;
25# if HAVE_UPDWTMPX
26# define pies_updwtmpx updwtmpx
27# endif
28# define GETUTXID getutxid
29# undef UTMP_FILE
30# define UTMP_FILE UTMPX_FILE
31# undef WTMP_FILE
32# define WTMP_FILE WTMPX_FILE
33# if defined HAVE_STRUCT_UTMPX_UT_NAME
34# define UT_NAME(u) ((u)->ut_name)
35# elif defined HAVE_STRUCT_UTMPX_UT_USER
36# define UT_NAME(u) ((u)->ut_user)
37# endif
38#else
39# include <utmp.h>
40typedef struct utmp UTMPX;
41# if defined HAVE_STRUCT_UTMP_UT_NAME
42# define UT_NAME(u) ((u)->ut_name)
43# elif defined HAVE_STRUCT_UTMP_UT_USER
44# define UT_NAME(u) ((u)->ut_user)
45# endif
46# if HAVE_UPDWTMP
47# define pies_updwtmpx updwtmp
48# endif
49# define GETUTXID getutid
50# define setutxent setutent
51# define pututxline pututline
52# define endutxent endutent
53#endif
54
55
56#ifndef pies_updwtmpx
57static void
58pies_updwtmpx (const char *wtmp_file, const UTMPX *ut)
59{
60 int fd = open (wtmp_file, O_WRONLY|O_APPEND);
61 if (fd == -1)
62 return;
63 write (fd, ut, sizeof (*ut));
64 close (fd);
65}
66#endif
67
68static UTMPX *
69pies_getutxid (const UTMPX *ut)
70{
71 static UTMPX tmp;
72 memcpy (&tmp, ut, sizeof (*ut));
73 return GETUTXID (&tmp);
74}
75
76void
77fill_utmp (UTMPX *utmp,
78 int type, const char *user, const char *id, pid_t pid,
79 const char *line)
80{
81#if defined HAVE_STRUCT_UTMP_UT_HOST
82 struct utsname uts;
83#endif
84#if defined HAVE_STRUCT_UTMP_UT_TV
85 struct timeval tv;
86#endif
87
88 memset (utmp, 0, sizeof (*utmp));
89#if defined(HAVE_STRUCT_UTMP_UT_TV) || defined(HAVE_STRUCT_UTMPX_UT_TV)
90 gettimeofday (&tv, 0);
91 utmp->ut_tv.tv_sec = tv.tv_sec;
92 utmp->ut_tv.tv_usec = tv.tv_usec;
93#elif defined(HAVE_STRUCT_UTMP_UT_TIME) || defined(HAVE_STRUCT_UTMPX_UT_TIME)
94 time (&utmp->ut_time);
95#endif
96 utmp->ut_type = type;
97 strncpy (UT_NAME (utmp), user, sizeof (UT_NAME (utmp)));
98 strncpy (utmp->ut_id, id, sizeof (utmp->ut_id));
99 utmp->ut_pid = pid;
100 strncpy (utmp->ut_line, line, sizeof(utmp->ut_line));
101#if defined(HAVE_STRUCT_UTMP_UT_HOST) || defined(HAVE_STRUCT_UTMPX_UT_HOST)
102 if (uname (&uts) == 0)
103 strncpy (utmp->ut_host, uts.release, sizeof(utmp->ut_host));
104#endif
105}
106
107
108int wtmpxreboot = 0;
109
110void
111write_wtmpx (int type, const char *user, const char *id, pid_t pid,
112 const char *line)
113{
114 UTMPX utmp;
115
116 if (access (WTMP_FILE, W_OK))
117 {
118 logmsg (LOG_NOTICE, _("cannot open %s for writing"), WTMP_FILE);
119 if (type == BOOT_TIME)
120 wtmpxreboot++;
121 return;
122 }
123
124 if (wtmpxreboot)
125 {
126 write_wtmpx (BOOT_TIME, "reboot", "~~", 0, "~");
127 --wtmpxreboot;
128 }
129 fill_utmp (&utmp, type, user, id, pid, line);
130 pies_updwtmpx (WTMP_FILE, &utmp);
131}
132
133int utmpreboot = 0;
134
135void
136write_utmpx (int type, const char *user, const char *id, pid_t pid,
137 const char *line)
138{
139 UTMPX utmp;
140
141 if (access (UTMP_FILE, W_OK))
142 {
143 logmsg (LOG_NOTICE, _("cannot open %s for writing"), UTMP_FILE);
144 if (type == BOOT_TIME)
145 utmpreboot++;
146 return;
147 }
148
149 if (utmpreboot)
150 {
151 write_utmpx (BOOT_TIME, "reboot", "~~", 0, "~");
152 --utmpreboot;
153 }
154 fill_utmp (&utmp, type, user, id, pid, line);
155
156 if (type == DEAD_PROCESS)
157 {
158 UTMPX *p = pies_getutxid (&utmp);
159 if (p)
160 strncpy (utmp.ut_line, p->ut_line, sizeof (utmp.ut_line));
161 }
162 setutxent ();
163 pututxline (&utmp);
164 endutxent ();
165}
166
167void
168sysvinit_acct (int what, const char *user, const char *id, pid_t pid,
169 const char *line)
170{
171 static int types[] = {
172 BOOT_TIME,
173 RUN_LVL,
174 INIT_PROCESS,
175 DEAD_PROCESS
176 };
177 write_utmpx (types[what], user, id, pid, line);
178 write_wtmpx (types[what], user, id, pid, line);
179}

Return to:

Send suggestions and report system problems to the System administrator.