Skip to content

Commit 8045334

Browse files
halt: add support for wtmp
This implements -w and -d. Also add -B to create boot-time wtmp entries.
1 parent 0566391 commit 8045334

2 files changed

Lines changed: 60 additions & 10 deletions

File tree

halt.8

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.Dd July 29, 2014
1+
.Dd September 5, 2019
22
.Dt HALT 8
33
.Os Linux
44
.Sh NAME
@@ -10,6 +10,9 @@
1010
.Nm halt
1111
.Op Fl n
1212
.Op Fl f
13+
.Op Fl d
14+
.Op Fl w
15+
.Op Fl B
1316
.Nm reboot
1417
.Op Fl n
1518
.Op Fl f
@@ -40,6 +43,12 @@ Force halt or reboot, don't call
4043
.Xr init 8 .
4144
This is
4245
.Sy dangerous !
46+
.It Fl d
47+
Do not write the wtmp record.
48+
.It Fl w
49+
Just write the wtmp record.
50+
.It Fl B
51+
Just write the wtmp record, but for a boot.
4352
.El
4453
.Sh UNSUPPORTED OPTIONS
4554
This version of
@@ -50,10 +59,6 @@ the following features are
5059
.Sy not
5160
supported and silently ignored:
5261
.Bl -tag -width indent
53-
.It Fl w
54-
to just write the wtmp record.
55-
.It Fl d
56-
to not write the wtmp record.
5762
.It Fl h
5863
to put hard drives in standby mode.
5964
.It Fl i

halt.c

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,53 @@
1-
#include <errno.h>
2-
#include <unistd.h>
1+
#include <sys/reboot.h>
2+
#include <sys/stat.h>
3+
#include <sys/types.h>
4+
#include <sys/utsname.h>
5+
36
#include <err.h>
7+
#include <errno.h>
8+
#include <fcntl.h>
49
#include <string.h>
5-
#include <sys/reboot.h>
10+
#include <unistd.h>
11+
#include <utmp.h>
612

713
extern char *__progname;
814

915
typedef enum {NOOP, HALT, REBOOT, POWEROFF} action_type;
1016

17+
#ifndef OUR_WTMP
18+
#define OUR_WTMP "/var/log/wtmp"
19+
#endif
20+
21+
void write_wtmp(int boot) {
22+
int fd;
23+
24+
if ((fd = open(OUR_WTMP, O_WRONLY|O_APPEND)) < 0)
25+
return;
26+
27+
struct utmp utmp = {0};
28+
struct utsname uname_buf;
29+
struct timeval tv;
30+
31+
gettimeofday(&tv, 0);
32+
utmp.ut_tv.tv_sec = tv.tv_sec;
33+
utmp.ut_tv.tv_usec = tv.tv_usec;
34+
35+
utmp.ut_type = boot ? BOOT_TIME : RUN_LVL;
36+
37+
strncpy(utmp.ut_name, boot ? "reboot" : "shutdown", sizeof(utmp.ut_name));
38+
strncpy(utmp.ut_id , "~~", sizeof(utmp.ut_id));
39+
strncpy(utmp.ut_line, boot ? "~" : "~~", sizeof(utmp.ut_line));
40+
if (uname(&uname_buf) == 0)
41+
strncpy(utmp.ut_host, uname_buf.release, sizeof(utmp.ut_host));
42+
43+
write(fd, (char *)&utmp, sizeof(utmp));
44+
close(fd);
45+
}
46+
1147
int main(int argc, char *argv[]) {
1248
int do_sync = 1;
1349
int do_force = 0;
50+
int do_wtmp = 1;
1451
int opt;
1552
action_type action = NOOP;
1653

@@ -23,7 +60,7 @@ int main(int argc, char *argv[]) {
2360
else
2461
warnx("no default behavior, needs to be called as halt/reboot/poweroff.");
2562

26-
while ((opt = getopt(argc, argv, "dfhinw")) != -1)
63+
while ((opt = getopt(argc, argv, "dfhinwB")) != -1)
2764
switch (opt) {
2865
case 'n':
2966
do_sync = 0;
@@ -33,17 +70,25 @@ int main(int argc, char *argv[]) {
3370
do_sync = 0;
3471
break;
3572
case 'd':
73+
do_wtmp = 0;
74+
break;
3675
case 'h':
3776
case 'i':
3877
/* silently ignored. */
3978
break;
4079
case 'f':
4180
do_force = 1;
4281
break;
82+
case 'B':
83+
write_wtmp(1);
84+
return 0;
4385
default:
44-
errx(1, "Usage: %s [-n] [-f]", __progname);
86+
errx(1, "Usage: %s [-n] [-f] [-d] [-w] [-B]", __progname);
4587
}
4688

89+
if (do_wtmp)
90+
write_wtmp(0);
91+
4792
if (do_sync)
4893
sync();
4994

0 commit comments

Comments
 (0)