[9] | 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 | }
|
---|