1
2
3
4
5#include <unistd.h>
6#include <stdio.h>
7#include <time.h>
8#include <errno.h>
9#include <stdlib.h>
10#include <string.h>
11
12
13
14
15
16#define LINUX_REBOOT_MAGIC1 0xfee1dead
17#define LINUX_REBOOT_MAGIC2 672274793
18#define LINUX_REBOOT_MAGIC2A 85072278
19#define LINUX_REBOOT_MAGIC2B 369367448
20
21
22
23
24
25
26
27
28
29
30#define LINUX_REBOOT_CMD_RESTART 0x01234567
31#define LINUX_REBOOT_CMD_HALT 0xCDEF0123
32#define LINUX_REBOOT_CMD_CAD_ON 0x89ABCDEF
33#define LINUX_REBOOT_CMD_CAD_OFF 0x00000000
34#define LINUX_REBOOT_CMD_POWER_OFF 0x4321FEDC
35#define LINUX_REBOOT_CMD_RESTART2 0xA1B2C3D4
36
37
38#define USE_LIBC
39
40#ifdef USE_LIBC
41
42
43#if defined __GLIBC__ && __GLIBC__ >= 2
44# include <sys/reboot.h>
45# define REBOOT(cmd) reboot(cmd)
46#else
47extern int reboot(int, int, int);
48# define REBOOT(cmd) reboot(LINUX_REBOOT_MAGIC1,LINUX_REBOOT_MAGIC2,(cmd))
49#endif
50
51static int my_reboot(int cmd)
52{
53 return REBOOT(cmd);
54}
55
56#else
57
58
59#include <linux/unistd.h>
60
61#ifdef _syscall3
62_syscall3(int, reboot, int, magic, int, magic_too, int, cmd);
63#else
64
65extern int reboot(int, int, int);
66#endif
67
68static int my_reboot(int cmd)
69{
70 return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd);
71}
72
73#endif
74
75
76static void do_reboot(void)
77{
78 my_reboot(LINUX_REBOOT_CMD_RESTART);
79}
80static void do_poweroff(void)
81{
82 my_reboot(LINUX_REBOOT_CMD_POWER_OFF);
83}
84static void do_halt(void)
85{
86 my_reboot(LINUX_REBOOT_CMD_HALT);
87}
88
89static void usage(void)
90{
91 puts(
92 "Usage: hardshutdown -h|-r|-p [NN]\n"
93 " NN - seconds to sleep before requested action"
94 );
95 exit(1);
96}
97
98enum action_t {
99 SHUTDOWN,
100 HALT,
101 POWEROFF,
102 REBOOT
103};
104
105int main(int argc, char *argv[])
106{
107 struct timespec t = {0,0};
108 enum action_t action = SHUTDOWN;
109 int c, i;
110 char *prog, *ptr;
111
112
113 prog = argv[0];
114 ptr = strrchr(prog,'/');
115 if (ptr)
116 prog = ptr+1;
117
118 for (c=1; c < argc; c++) {
119 if (argv[c][0] >= '0' && argv[c][0] <= '9') {
120 t.tv_sec = strtol(argv[c], NULL, 10);
121 continue;
122 }
123 if (argv[c][0] != '-') {
124 usage();
125 return 1;
126 }
127 for (i=1; argv[c][i]; i++) {
128 switch (argv[c][i]) {
129 case 'h':
130 action = HALT;
131 break;
132 case 'p':
133 action = POWEROFF;
134 break;
135 case 'r':
136 action = REBOOT;
137 break;
138 default:
139 usage();
140 return 1;
141 }
142 }
143 }
144
145 if (action==SHUTDOWN) {
146 usage();
147 return 1;
148 }
149
150 chdir("/");
151 while (nanosleep(&t,&t)<0)
152 if (errno!=EINTR) break;
153
154 switch (action) {
155 case HALT:
156 do_halt();
157 break;
158 case POWEROFF:
159 do_poweroff();
160 break;
161 case REBOOT:
162 do_reboot();
163 break;
164 default:
165 break;
166 }
167 return 1;
168}
169