1: /*
2: * Copyright (c) 1980,1986 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: */
6:
7: #if defined(DOSCCS) && !defined(lint)
8: char copyright[] =
9: "@(#) Copyright (c) 1980,1986 Regents of the University of California.\n\
10: All rights reserved.\n";
11:
12: static char sccsid[] = "@(#)reboot.c 5.5.4 (2.11BSD) 1997/10/3";
13: #endif
14:
15: /*
16: * Reboot ...
17: */
18:
19: #include <stdio.h>
20: #include <errno.h>
21: #include <pwd.h>
22: #include <sysexits.h>
23: #include <unistd.h>
24: #include <sys/syslog.h>
25: #include <sys/file.h>
26: #include <sys/reboot.h>
27: #include <sys/signal.h>
28:
29: #define OPTS "lqnhdarsfRD"
30:
31: main(argc, argv)
32: int argc;
33: char **argv;
34: {
35: int howto; /* reboot options argument */
36: int needlog = 1; /* tell syslog what's happening */
37: int quickly = 0; /* go down quickly & ungracefully */
38: char *myname; /* name we were invoked as */
39: char args[20], *ap; /* collected arguments for syslog */
40: int i;
41: char *rindex();
42:
43: if (myname = rindex(argv[0], '/'))
44: myname++;
45: else
46: myname = argv[0];
47: if (strcmp(myname, "halt") == 0)
48: howto = RB_HALT;
49: else if (strcmp(myname, "fasthalt") == 0)
50: howto = RB_HALT|RB_NOFSCK;
51: else if (strcmp(myname, "fastboot") == 0)
52: howto = RB_NOFSCK;
53: else
54: howto = 0;
55:
56: ap = args;
57: *ap++ = '-';
58: *ap = '\0';
59: while ((i = getopt(argc, argv, OPTS)) != EOF) {
60: switch((char)i) {
61: case 'l': needlog = 0; break;
62: case 'q': quickly++; break;
63: case 'n': howto |= RB_NOSYNC; break;
64: case 'h': howto |= RB_HALT; break;
65: case 'd': howto |= RB_DUMP; break;
66: case 'a': howto |= RB_ASKNAME; break;
67: case 'r': howto |= RB_RDONLY; break;
68: case 's': howto |= RB_SINGLE; break;
69: case 'f': howto |= RB_NOFSCK; break;
70: case 'R': howto |= RB_DFLTROOT; break;
71: case 'D': howto |= RB_AUTODEBUG; break;
72: case '?':
73: fprintf(stderr,
74: "usage: %s [-%s]\n", myname, OPTS);
75: exit(EX_USAGE);
76: /*NOTREACHED*/
77: }
78: if (index(args+1, (char)i) == 0) {
79: *ap++ = (char)i;
80: *ap = '\0';
81: }
82: }
83:
84: if ((howto & (RB_NOSYNC|RB_NOFSCK)) == (RB_NOSYNC|RB_NOFSCK)
85: && !(howto & RB_HALT)) {
86: fprintf(stderr,
87: "%s: no sync and no fsck are a dangerous combination; no fsck ignored.\n",
88: myname);
89: howto &= ~RB_NOFSCK;
90: }
91: if (needlog) {
92: char *user;
93: struct passwd *pw;
94:
95: user = getlogin();
96: if (user == (char *)0 && (pw = getpwuid(getuid())))
97: user = pw->pw_name;
98: if (user == (char *)0)
99: user = "root";
100: openlog(myname, 0, LOG_AUTH);
101: syslog(LOG_CRIT, "%s; %s by %s",
102: args, (howto&RB_HALT)?"halted":"rebooted", user);
103: }
104: /*
105: * Do a sync early on so disks start transfers while we're killing
106: * processes.
107: */
108: if (!(howto & RB_NOSYNC))
109: sync();
110:
111: (void) signal(SIGHUP, SIG_IGN); /* for remote connections */
112: if (kill(1, SIGTSTP) == -1) {
113: fprintf(stderr, "%s: can\'t idle init\n", myname);
114: exit(EX_NOPERM);
115: }
116: sleep(1);
117: (void) kill(-1, SIGTERM); /* one chance to catch it */
118:
119: /*
120: * After the processes receive the TERM signal start the rest of the
121: * buffers out to disk. Wait five seconds between SIGTERM and SIGKILL so
122: * the processes have a chance to clean up and exit nicely.
123: */
124: sleep(2);
125: if (!(howto & RB_NOSYNC))
126: sync();
127: sleep(3);
128:
129: if (!quickly)
130: for (i = 1; ; i++) {
131: if (kill(-1, SIGKILL) == -1) {
132: if (errno == ESRCH)
133: break;
134: perror(myname);
135: kill(1, SIGHUP);
136: exit(EX_OSERR);
137: }
138: if (i > 5) {
139: fprintf(stderr,
140: "CAUTION: some process(es) wouldn't die\n");
141: break;
142: }
143: sleep(2 * i);
144: }
145:
146: if (!quickly && (howto & RB_NOSYNC) == 0) {
147: markdown();
148: sync();
149: sleep(5);
150: }
151: reboot(howto);
152: perror(myname);
153: kill(1, SIGHUP);
154: exit(EX_OSERR);
155: }
156:
157:
158: /*
159: * Make shutdown entry in /usr/adm/utmp.
160: */
161: #include <utmp.h>
162:
163: #define SCPYN(a, b) strncpy(a, b, sizeof(a))
164: #define WTMPF "/usr/adm/wtmp"
165:
166: markdown()
167: {
168: struct utmp wtmp;
169: register int f = open(WTMPF, O_WRONLY|O_APPEND);
170:
171: if (f >= 0) {
172: bzero((char *)&wtmp, sizeof(wtmp));
173: SCPYN(wtmp.ut_line, "~");
174: SCPYN(wtmp.ut_name, "shutdown");
175: SCPYN(wtmp.ut_host, "");
176: (void) time(&wtmp.ut_time);
177: write(f, (char *)&wtmp, sizeof(wtmp));
178: close(f);
179: }
180: }
Defined functions
main
defined in line
31;
never used
Defined variables
Defined macros
OPTS
defined in line
29; used 2 times