aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac14
-rw-r--r--src/Makefile.am1
-rw-r--r--src/pies.h11
-rw-r--r--src/progman.c7
-rw-r--r--src/sysvinit.c5
-rw-r--r--src/utmp.c179
6 files changed, 214 insertions, 3 deletions
diff --git a/configure.ac b/configure.ac
index 0c1d2b9..5a42270 100644
--- a/configure.ac
+++ b/configure.ac
@@ -35,7 +35,7 @@ AC_PROG_LEX
35# Checks for libraries. 35# Checks for libraries.
36 36
37# Checks for header files. 37# Checks for header files.
38AC_CHECK_HEADERS([arpa/inet.h fcntl.h netdb.h netinet/in.h stdint.h stdlib.h string.h sys/socket.h sys/time.h syslog.h unistd.h]) 38AC_CHECK_HEADERS([arpa/inet.h fcntl.h netdb.h netinet/in.h stdint.h stdlib.h string.h sys/socket.h sys/time.h syslog.h unistd.h utmp.h utmpx.h])
39 39
40# Checks for typedefs, structures, and compiler characteristics. 40# Checks for typedefs, structures, and compiler characteristics.
41AC_TYPE_UID_T 41AC_TYPE_UID_T
@@ -48,6 +48,18 @@ IU_CHECK_MEMBERS([struct msghdr.msg_control, struct msghdr.msg_accrights], , ,
48 [#include <sys/types.h> 48 [#include <sys/types.h>
49 #include <sys/socket.h>]) 49 #include <sys/socket.h>])
50 50
51IU_CHECK_MEMBERS([struct utmp.ut_tv, struct utmp.ut_name,
52 struct utmp.ut_user, struct utmp.ut_time,
53 struct utmp.ut_host], , ,
54 [#include <utmp.h>])
55
56if test "$ac_cv_header_utmpx_h" = yes; then
57 IU_CHECK_MEMBERS([struct utmpx.ut_tv, struct utmpx.ut_name,
58 struct utmpx.ut_user, struct utmpx.ut_time,
59 struct utmpx.ut_host], , ,
60 [#include <utmpx.h>])
61fi
62
51# Checks for library functions. 63# Checks for library functions.
52AC_FUNC_CHOWN 64AC_FUNC_CHOWN
53AC_FUNC_FORK 65AC_FUNC_FORK
diff --git a/src/Makefile.am b/src/Makefile.am
index 0fca105..3752eae 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -32,6 +32,7 @@ pies_SOURCES = \
32 socket.c\ 32 socket.c\
33 sysvinit.c\ 33 sysvinit.c\
34 url.c\ 34 url.c\
35 utmp.c\
35 userprivs.c 36 userprivs.c
36 37
37noinst_HEADERS = \ 38noinst_HEADERS = \
diff --git a/src/pies.h b/src/pies.h
index fc4f59c..e7ad1c6 100644
--- a/src/pies.h
+++ b/src/pies.h
@@ -456,6 +456,13 @@ struct inetd_builtin *inetd_builtin_lookup (const char *service, int socktype);
456void sysvinit_begin (void); 456void sysvinit_begin (void);
457int inittrans (void); 457int inittrans (void);
458int is_comp_wait (struct component *comp); 458int is_comp_wait (struct component *comp);
459 459
460 460/* utmp.c */
461#define SYSV_ACCT_BOOT 0
462#define SYSV_ACCT_RUNLEVEL 1
463#define SYSV_ACCT_PROC_START 2
464#define SYSV_ACCT_PROC_STOP 3
465
466void sysvinit_acct (int what, const char *user, const char *id, pid_t pid,
467 const char *line);
461 468
diff --git a/src/progman.c b/src/progman.c
index 15b8c44..97216b8 100644
--- a/src/progman.c
+++ b/src/progman.c
@@ -1392,6 +1392,9 @@ prog_start (struct prog *prog)
1392 prog->v.p.comp->mode == pies_comp_inetd || 1392 prog->v.p.comp->mode == pies_comp_inetd ||
1393 prog->v.p.comp->mode == pies_comp_pass_fd) 1393 prog->v.p.comp->mode == pies_comp_pass_fd)
1394 close (prog->v.p.socket); 1394 close (prog->v.p.socket);
1395 else if (is_sysvinit (prog->v.p.comp))
1396 sysvinit_acct (SYSV_ACCT_PROC_START, "", prog->tag, pid, "");
1397
1395 prog->pid = pid; 1398 prog->pid = pid;
1396 prog->v.p.status = status_enabled; 1399 prog->v.p.status = status_enabled;
1397 debug (1, (_("%s started, pid=%lu"), prog->tag, (unsigned long) pid)); 1400 debug (1, (_("%s started, pid=%lu"), prog->tag, (unsigned long) pid));
@@ -2492,10 +2495,14 @@ progman_cleanup (int expect_term)
2492 } 2495 }
2493 else if (prog->v.p.comp->mode >= pies_mark_sysvinit) 2496 else if (prog->v.p.comp->mode >= pies_mark_sysvinit)
2494 { 2497 {
2498 sysvinit_acct (SYSV_ACCT_PROC_STOP, "", prog->tag, pid, "");
2495 prog->v.p.status = status_finished; 2499 prog->v.p.status = status_finished;
2496 } 2500 }
2497 else 2501 else
2498 { 2502 {
2503 if (is_sysvinit (prog->v.p.comp))
2504 sysvinit_acct (SYSV_ACCT_PROC_STOP, "", prog->tag, pid, "");
2505
2499 prog->v.p.status = status_enabled; 2506 prog->v.p.status = status_enabled;
2500 prog_stop_dependents (prog); 2507 prog_stop_dependents (prog);
2501 if (!expect_term) 2508 if (!expect_term)
diff --git a/src/sysvinit.c b/src/sysvinit.c
index 5a0d98a..ef765a1 100644
--- a/src/sysvinit.c
+++ b/src/sysvinit.c
@@ -165,7 +165,9 @@ inittrans ()
165 switch (boot_state) 165 switch (boot_state)
166 { 166 {
167 case sysinit: 167 case sysinit:
168 break;
168 case boot: 169 case boot:
170 sysvinit_acct (SYSV_ACCT_BOOT, "reboot", "~~", 0, "~");
169 break; 171 break;
170 case single0: 172 case single0:
171 case single1: 173 case single1:
@@ -178,6 +180,9 @@ inittrans ()
178 if (newlevel && newlevel != runlevel) 180 if (newlevel && newlevel != runlevel)
179 { 181 {
180 debug (1, ("RL TRANS: %c -> %c", runlevel, newlevel)); 182 debug (1, ("RL TRANS: %c -> %c", runlevel, newlevel));
183 sysvinit_acct (SYSV_ACCT_RUNLEVEL, "runlevel", "~~",
184 newlevel + 256 * runlevel, "~");
185 mf_proctitle_format ("init [%c]", newlevel);
181 runlevel = newlevel; 186 runlevel = newlevel;
182 trans = 1; 187 trans = 1;
183 wait = 0; 188 wait = 0;
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.