1 | /* halt / reboot - halt or reboot system (depends on name)
|
---|
2 |
|
---|
3 | halt - calling reboot() with RBT_HALT
|
---|
4 | reboot - calling reboot() with RBT_REBOOT
|
---|
5 |
|
---|
6 | author: Edvard Tuinder v892231@si.hhs.NL
|
---|
7 |
|
---|
8 | This program calls the library function reboot(2) which performs
|
---|
9 | the system-call do_reboot.
|
---|
10 |
|
---|
11 | */
|
---|
12 |
|
---|
13 | #define _POSIX_SOURCE 1
|
---|
14 | #include <sys/types.h>
|
---|
15 | #include <fcntl.h>
|
---|
16 | #include <stdio.h>
|
---|
17 | #include <stdlib.h>
|
---|
18 | #include <signal.h>
|
---|
19 | #include <string.h>
|
---|
20 | #include <errno.h>
|
---|
21 | #include <unistd.h>
|
---|
22 | #include <sys/stat.h>
|
---|
23 | #include <sys/wait.h>
|
---|
24 |
|
---|
25 | void write_log _ARGS(( void ));
|
---|
26 | void usage _ARGS(( void ));
|
---|
27 | int main _ARGS(( int argc, char *argv[] ));
|
---|
28 |
|
---|
29 | char *prog;
|
---|
30 | char *reboot_code = "delay; boot";
|
---|
31 |
|
---|
32 | void
|
---|
33 | usage()
|
---|
34 | {
|
---|
35 | fprintf(stderr, "Usage: %s [-hrRf] [-x reboot-code]\n", prog);
|
---|
36 | exit(1);
|
---|
37 | }
|
---|
38 |
|
---|
39 | int
|
---|
40 | main(argc,argv)
|
---|
41 | int argc;
|
---|
42 | char **argv;
|
---|
43 | {
|
---|
44 | int flag = -1; /* default action unknown */
|
---|
45 | int fast = 0; /* fast halt/reboot, don't bother being nice. */
|
---|
46 | int i;
|
---|
47 | struct stat dummy;
|
---|
48 | char *monitor_code = "";
|
---|
49 | pid_t pid;
|
---|
50 |
|
---|
51 | if ((prog = strrchr(argv[0],'/')) == NULL) prog = argv[0]; else prog++;
|
---|
52 |
|
---|
53 | if (strcmp(prog, "halt") == 0) flag = RBT_HALT;
|
---|
54 | if (strcmp(prog, "reboot") == 0) flag = RBT_REBOOT;
|
---|
55 |
|
---|
56 | i = 1;
|
---|
57 | while (i < argc && argv[i][0] == '-') {
|
---|
58 | char *opt = argv[i++] + 1;
|
---|
59 |
|
---|
60 | if (*opt == '-' && opt[1] == 0) break; /* -- */
|
---|
61 |
|
---|
62 | while (*opt != 0) switch (*opt++) {
|
---|
63 | case 'h': flag = RBT_HALT; break;
|
---|
64 | case 'r': flag = RBT_REBOOT; break;
|
---|
65 | case 'R': flag = RBT_RESET; break;
|
---|
66 | case 'f': fast = 1; break;
|
---|
67 | case 'x':
|
---|
68 | flag = RBT_MONITOR;
|
---|
69 | if (*opt == 0) {
|
---|
70 | if (i == argc) usage();
|
---|
71 | opt = argv[i++];
|
---|
72 | }
|
---|
73 | monitor_code = opt;
|
---|
74 | opt = "";
|
---|
75 | break;
|
---|
76 | default:
|
---|
77 | usage();
|
---|
78 | }
|
---|
79 | }
|
---|
80 |
|
---|
81 | if (i != argc) usage();
|
---|
82 |
|
---|
83 | if (flag == -1) {
|
---|
84 | fprintf(stderr, "Don't know what to do when named '%s'\n", prog);
|
---|
85 | exit(1);
|
---|
86 | }
|
---|
87 |
|
---|
88 | if (flag == RBT_REBOOT) {
|
---|
89 | flag = RBT_MONITOR; /* set monitor code for reboot */
|
---|
90 | monitor_code = reboot_code;
|
---|
91 | }
|
---|
92 |
|
---|
93 | if (stat("/usr/bin", &dummy) < 0) {
|
---|
94 | /* It seems that /usr isn't present, let's assume "-f." */
|
---|
95 | fast = 1;
|
---|
96 | }
|
---|
97 |
|
---|
98 | signal(SIGHUP, SIG_IGN);
|
---|
99 | signal(SIGTERM, SIG_IGN);
|
---|
100 |
|
---|
101 | /* Skip this part for fast shut down. */
|
---|
102 | if (! fast) {
|
---|
103 | /* Run the shutdown scripts. */
|
---|
104 | switch ((pid = fork())) {
|
---|
105 | case -1:
|
---|
106 | fprintf(stderr, "%s: can't fork(): %s\n", prog, strerror(errno));
|
---|
107 | exit(1);
|
---|
108 | case 0:
|
---|
109 | execl("/bin/sh", "sh", "/etc/rc", "down", (char *) NULL);
|
---|
110 | fprintf(stderr, "%s: can't execute: /bin/sh: %s\n",
|
---|
111 | prog, strerror(errno));
|
---|
112 | exit(1);
|
---|
113 | default:
|
---|
114 | while (waitpid(pid, NULL, 0) != pid) {}
|
---|
115 | }
|
---|
116 | }
|
---|
117 |
|
---|
118 | /* Tell init to stop spawning getty's. */
|
---|
119 | kill(1, SIGTERM);
|
---|
120 |
|
---|
121 | /* Give everybody a chance to die peacefully. */
|
---|
122 | printf("Sending SIGTERM to all processes ...\n");
|
---|
123 | kill(-1, SIGTERM);
|
---|
124 | sleep(1);
|
---|
125 |
|
---|
126 | write_log();
|
---|
127 |
|
---|
128 | sync();
|
---|
129 |
|
---|
130 | reboot(flag, monitor_code, strlen(monitor_code));
|
---|
131 | fprintf(stderr, "%s: reboot(): %s\n", strerror(errno));
|
---|
132 | return 1;
|
---|
133 | }
|
---|