diff options
-rw-r--r-- | configure.ac | 14 | ||||
-rw-r--r-- | src/Makefile.am | 1 | ||||
-rw-r--r-- | src/pies.h | 9 | ||||
-rw-r--r-- | src/progman.c | 7 | ||||
-rw-r--r-- | src/sysvinit.c | 5 | ||||
-rw-r--r-- | src/utmp.c | 179 |
6 files changed, 213 insertions, 2 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. |
38 | AC_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]) | 38 | AC_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. |
41 | AC_TYPE_UID_T | 41 | AC_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 | ||
51 | IU_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 | |||
56 | if 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>]) | ||
61 | fi | ||
62 | |||
51 | # Checks for library functions. | 63 | # Checks for library functions. |
52 | AC_FUNC_CHOWN | 64 | AC_FUNC_CHOWN |
53 | AC_FUNC_FORK | 65 | AC_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 | ||
37 | noinst_HEADERS = \ | 38 | noinst_HEADERS = \ |
@@ -457,5 +457,12 @@ void sysvinit_begin (void); | |||
457 | int inittrans (void); | 457 | int inittrans (void); |
458 | int is_comp_wait (struct component *comp); | 458 | int 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 | |||
466 | void 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> | ||
24 | typedef 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> | ||
40 | typedef 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 | ||
57 | static void | ||
58 | pies_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 | |||
68 | static UTMPX * | ||
69 | pies_getutxid (const UTMPX *ut) | ||
70 | { | ||
71 | static UTMPX tmp; | ||
72 | memcpy (&tmp, ut, sizeof (*ut)); | ||
73 | return GETUTXID (&tmp); | ||
74 | } | ||
75 | |||
76 | void | ||
77 | fill_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 | |||
108 | int wtmpxreboot = 0; | ||
109 | |||
110 | void | ||
111 | write_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 |