Gentoo Archives: gentoo-commits

From: William Hubbs <williamh@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/openrc:master commit in: src/rc/, src/includes/
Date: Mon, 05 Jun 2017 17:18:20
Message-Id: 1496627763.7689106aa10f7852b707b4c21ec080ccb2767280.williamh@OpenRC
1 commit: 7689106aa10f7852b707b4c21ec080ccb2767280
2 Author: William Hubbs <w.d.hubbs <AT> gmail <DOT> com>
3 AuthorDate: Fri Jun 2 19:07:40 2017 +0000
4 Commit: William Hubbs <williamh <AT> gentoo <DOT> org>
5 CommitDate: Mon Jun 5 01:56:03 2017 +0000
6 URL: https://gitweb.gentoo.org/proj/openrc.git/commit/?id=7689106a
7
8 add support for writing reboot and shutdown records to wtmp
9
10 src/includes/rc-wtmp.h | 26 +++++++++++++++++++++
11 src/rc/Makefile | 6 ++---
12 src/rc/openrc-init.c | 2 ++
13 src/rc/openrc-shutdown.c | 61 +++++++++++++++++++++++++++++++-----------------
14 src/rc/rc-wtmp.c | 50 +++++++++++++++++++++++++++++++++++++++
15 5 files changed, 121 insertions(+), 24 deletions(-)
16
17 diff --git a/src/includes/rc-wtmp.h b/src/includes/rc-wtmp.h
18 new file mode 100644
19 index 00000000..6645774b
20 --- /dev/null
21 +++ b/src/includes/rc-wtmp.h
22 @@ -0,0 +1,26 @@
23 +/*
24 + * rc-wtmp.h
25 + * This is private to us and not for user consumption
26 +*/
27 +
28 +/*
29 + * Copyright (c) 2017 The OpenRC Authors.
30 + * See the Authors file at the top-level directory of this distribution and
31 + * https://github.com/OpenRC/openrc/blob/master/AUTHORS
32 + *
33 + * This file is part of OpenRC. It is subject to the license terms in
34 + * the LICENSE file found in the top-level directory of this
35 + * distribution and at https://github.com/OpenRC/openrc/blob/master/LICENSE
36 + * This file may not be copied, modified, propagated, or distributed
37 + * except according to the terms contained in the LICENSE file.
38 + */
39 +
40 +#ifndef __RC_WTMP_H__
41 +#define __RC_WTMP_H__
42 +
43 +#include <utmp.h>
44 +
45 +void log_wtmp(const char *user, const char *id, pid_t pid, int type,
46 + const char *line);
47 +
48 +#endif
49
50 diff --git a/src/rc/Makefile b/src/rc/Makefile
51 index 5874ed17..19adcafb 100644
52 --- a/src/rc/Makefile
53 +++ b/src/rc/Makefile
54 @@ -14,7 +14,7 @@ SRCS+= rc-selinux.c
55 endif
56
57 ifeq (${OS},Linux)
58 -SRCS+= kill_all.c openrc-init.c openrc-shutdown.c
59 +SRCS+= kill_all.c openrc-init.c openrc-shutdown.c rc-wtmp.c
60 endif
61
62 CLEANFILES= version.h rc-selinux.o
63 @@ -111,7 +111,7 @@ veinfo vewarn vebegin veend vewend veindent veoutdent: do_e.o rc-misc.o
64 fstabinfo: fstabinfo.o _usage.o rc-misc.o
65 ${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
66
67 -openrc-init: openrc-init.o
68 +openrc-init: openrc-init.o rc-wtmp.o
69 ${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
70
71 is_newer_than: is_newer_than.o rc-misc.o
72 @@ -132,7 +132,7 @@ mountinfo: mountinfo.o _usage.o rc-misc.o
73 openrc rc: rc.o rc-logger.o rc-misc.o rc-plugin.o _usage.o
74 ${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
75
76 -openrc-shutdown: openrc-shutdown.o _usage.o
77 +openrc-shutdown: openrc-shutdown.o _usage.o rc-wtmp.o
78 ${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
79
80 openrc-run runscript: openrc-run.o _usage.o rc-misc.o rc-plugin.o
81
82 diff --git a/src/rc/openrc-init.c b/src/rc/openrc-init.c
83 index 003ce31f..eb346f59 100644
84 --- a/src/rc/openrc-init.c
85 +++ b/src/rc/openrc-init.c
86 @@ -32,6 +32,7 @@
87
88 #include "helpers.h"
89 #include "rc.h"
90 +#include "rc-wtmp.h"
91 #include "version.h"
92
93 static const char *rc_default_runlevel = "default";
94 @@ -82,6 +83,7 @@ static void init(const char *default_runlevel)
95 }
96 pid = do_openrc(runlevel);
97 waitpid(pid, NULL, 0);
98 + log_wtmp("reboot", "~~", 0, RUN_LVL, "~~");
99 }
100
101 static void handle_reexec(char *my_name)
102
103 diff --git a/src/rc/openrc-shutdown.c b/src/rc/openrc-shutdown.c
104 index ecb251a8..4ba619c5 100644
105 --- a/src/rc/openrc-shutdown.c
106 +++ b/src/rc/openrc-shutdown.c
107 @@ -27,46 +27,63 @@
108 #include <string.h>
109 #include <unistd.h>
110 #include <sys/types.h>
111 +#include <sys/utsname.h>
112
113 #include "einfo.h"
114 #include "rc.h"
115 #include "helpers.h"
116 #include "_usage.h"
117 +#include "rc-wtmp.h"
118
119 const char *applet = NULL;
120 const char *extraopts = NULL;
121 -const char *getoptstring = "dHkpRr" getoptstring_COMMON;
122 +const char *getoptstring = "dDHKpRrw" getoptstring_COMMON;
123 const struct option longopts[] = {
124 - { "dry-run", no_argument, NULL, 'd'},
125 + { "no-write", no_argument, NULL, 'd'},
126 + { "dry-run", no_argument, NULL, 'D'},
127 { "halt", no_argument, NULL, 'H'},
128 - { "kexec", no_argument, NULL, 'k'},
129 + { "kexec", no_argument, NULL, 'K'},
130 { "poweroff", no_argument, NULL, 'p'},
131 { "reexec", no_argument, NULL, 'R'},
132 { "reboot", no_argument, NULL, 'r'},
133 + { "write-only", no_argument, NULL, 'w'},
134 longopts_COMMON
135 };
136 const char * const longopts_help[] = {
137 + "do not write wtmp record",
138 "print actions instead of executing them",
139 "halt the system",
140 "reboot the system using kexec",
141 "power off the system",
142 "re-execute init (use after upgrading)",
143 "reboot the system",
144 + "write wtmp boot record and exit",
145 longopts_help_COMMON
146 };
147 const char *usagestring = NULL;
148 const char *exclusive = "Select one of "
149 "--halt, --kexec, --poweroff, --reexec or --reboot";
150
151 -static void send_cmd(const char *cmd, bool dryrun)
152 +static bool do_dryrun = false;
153 +static bool do_halt = false;
154 +static bool do_kexec = false;
155 +static bool do_poweroff = false;
156 +static bool do_reboot = false;
157 +static bool do_reexec = false;
158 +static bool do_wtmp = true;
159 +static bool do_wtmp_only = false;
160 +
161 +static void send_cmd(const char *cmd)
162 {
163 FILE *fifo;
164 size_t ignored;
165
166 - if (dryrun) {
167 + if (do_dryrun) {
168 einfo("Would send %s to init", cmd);
169 return;
170 }
171 + if (do_wtmp && (do_halt || do_kexec || do_reboot || do_poweroff))
172 + log_wtmp("shutdown", "~~", 0, RUN_LVL, "~~");
173 fifo = fopen(RC_INIT_FIFO, "w");
174 if (!fifo) {
175 perror("fopen");
176 @@ -83,26 +100,23 @@ int main(int argc, char **argv)
177 {
178 int opt;
179 int cmd_count = 0;
180 - bool do_dryrun = false;
181 - bool do_halt = false;
182 - bool do_kexec = false;
183 - bool do_poweroff = false;
184 - bool do_reboot = false;
185 - bool do_reexec = false;
186
187 applet = basename_c(argv[0]);
188 while ((opt = getopt_long(argc, argv, getoptstring,
189 longopts, (int *) 0)) != -1)
190 {
191 switch (opt) {
192 - case 'd':
193 + case 'd':
194 + do_wtmp = false;
195 + break;
196 + case 'D':
197 do_dryrun = true;
198 break;
199 case 'H':
200 do_halt = true;
201 cmd_count++;
202 break;
203 - case 'k':
204 + case 'K':
205 do_kexec = true;
206 cmd_count++;
207 break;
208 @@ -118,26 +132,31 @@ int main(int argc, char **argv)
209 do_reboot = true;
210 cmd_count++;
211 break;
212 + case 'w':
213 + do_wtmp_only = true;
214 + break;
215 case_RC_COMMON_GETOPT
216 }
217 }
218 -if (geteuid() != 0 && ! do_dryrun)
219 - eerrorx("%s: you must be root\n", applet);
220 + if (geteuid() != 0 && ! do_dryrun)
221 + eerrorx("%s: you must be root\n", applet);
222 if (cmd_count > 1) {
223 eerror("%s: %s\n", applet, exclusive);
224 usage(EXIT_FAILURE);
225 }
226 if (do_halt)
227 - send_cmd("halt", do_dryrun);
228 + send_cmd("halt");
229 else if (do_kexec)
230 - send_cmd("kexec", do_dryrun);
231 + send_cmd("kexec");
232 else if (do_poweroff)
233 - send_cmd("poweroff", do_dryrun);
234 + send_cmd("poweroff");
235 else if (do_reboot)
236 - send_cmd("reboot", do_dryrun);
237 + send_cmd("reboot");
238 else if (do_reexec)
239 - send_cmd("reexec", do_dryrun);
240 + send_cmd("reexec");
241 + else if (do_wtmp_only)
242 + log_wtmp("shutdown", "~~", 0, RUN_LVL, "~~");
243 else
244 - send_cmd("single", do_dryrun);
245 + send_cmd("single");
246 return 0;
247 }
248
249 diff --git a/src/rc/rc-wtmp.c b/src/rc/rc-wtmp.c
250 new file mode 100644
251 index 00000000..913fa06b
252 --- /dev/null
253 +++ b/src/rc/rc-wtmp.c
254 @@ -0,0 +1,50 @@
255 +/*
256 + * rc-wtmp.c
257 + * This file contains routines to deal with the wtmp file.
258 + */
259 +
260 +/*
261 + * Copyright 2017 The OpenRC Authors.
262 + * See the Authors file at the top-level directory of this distribution and
263 + * https://github.com/OpenRC/openrc/blob/master/AUTHORS
264 + *
265 + * This file is part of OpenRC. It is subject to the license terms in
266 + * the LICENSE file found in the top-level directory of this
267 + * distribution and at https://github.com/OpenRC/openrc/blob/master/LICENSE
268 + * This file may not be copied, modified, propagated, or distributed
269 + * except according to the terms contained in the LICENSE file.
270 + */
271 +
272 +#include <stdbool.h>
273 +#include <stdio.h>
274 +#include <stdlib.h>
275 +#include <string.h>
276 +#include <unistd.h>
277 +#include <sys/types.h>
278 +#include <sys/utsname.h>
279 +
280 +#include "rc-wtmp.h"
281 +
282 +void log_wtmp(const char *user, const char *id, pid_t pid, int type,
283 + const char *line)
284 +{
285 + struct timeval tv;
286 + struct utmp utmp;
287 + struct utsname uname_buf;
288 +
289 + memset(&utmp, 0, sizeof(utmp));
290 + gettimeofday(&tv, NULL);
291 + utmp.ut_tv.tv_sec = tv.tv_sec;
292 + utmp.ut_tv.tv_usec = tv.tv_usec;
293 + utmp.ut_pid = pid;
294 + utmp.ut_type = type;
295 + strncpy(utmp.ut_name, user, sizeof(utmp.ut_name));
296 + strncpy(utmp.ut_id , id , sizeof(utmp.ut_id ));
297 + strncpy(utmp.ut_line, line, sizeof(utmp.ut_line));
298 +
299 + /* Put the OS version in place of the hostname */
300 + if (uname(&uname_buf) == 0)
301 + strncpy(utmp.ut_host, uname_buf.release, sizeof(utmp.ut_host));
302 +
303 + updwtmp(WTMP_FILE, &utmp);
304 +}