#include <util.h>
#include <bsm/libbsm.h>
#include <bsm/audit_uevents.h>
+#include <vproc.h>
+#include <vproc_priv.h>
#include "kextmanager.h"
#include <IOKit/kext/kextmanager_types.h>
#include <mach/mach_port.h> // allocate
#include <mach/mach.h> // task_self, etc
#include <servers/bootstrap.h> // bootstrap
+#include <bootstrap_priv.h>
#include <reboot2.h>
+#include <utmpx.h>
+#include <sys/sysctl.h>
#include "pathnames.h"
#endif /* __APPLE__ */
static time_t offset, shuttime;
#ifdef __APPLE__
-static int dohalt, doreboot, doups, killflg, mbuflen, oflag;
+static int dohalt, doreboot, doups, killflg, oflag;
+static size_t mbuflen;
#else
static int dohalt, dopower, doreboot, killflg, mbuflen, oflag;
#endif
void loop(void);
void nolog(void);
void timeout(int);
-void timewarn(int);
+void timewarn(time_t);
void usage(const char *);
#ifdef __APPLE__
int audit_shutdown(int);
{
char *p, *endp;
struct passwd *pw;
- int arglen, ch, len, readstdin;
+ size_t arglen;
+ int ch, len, readstdin;
#ifndef DEBUG
if (geteuid())
if (!(dohalt || doreboot || dosleep || killflg))
usage("-h, -r, -s, or -k is required");
-
+
if (doups && !dohalt)
usage("-u requires -h");
#endif /* !__APPLE__ */
p = mbuf;
endp = mbuf + sizeof(mbuf) - 2;
for (;;) {
- if (!fgets(p, endp - p + 1, stdin))
+ if (!fgets(p, (int)(endp - p + 1), stdin))
break;
for (; *p && p < endp; ++p);
if (p == endp) {
}
if (forkpid)
errx(0, "[pid %d]", forkpid);
+#ifdef __APPLE__
+ /* 5863185: reboot2() needs to talk to launchd. */
+ if (_vprocmgr_detach_from_console(0) != NULL)
+ warnx("can't detach from console");
+#endif /* __APPLE__ */
}
audit_shutdown(0);
setsid();
}
void
-loop()
+loop(void)
{
struct interval *tp;
u_int sltime;
* Warn now, if going to sleep more than a fifth of
* the next wait time.
*/
- if ((sltime = offset - tp->timeleft)) {
- if (sltime > (u_int)(tp->timetowait / 5))
+ if ((sltime = (u_int)(offset - tp->timeleft))) {
+ if (sltime > (tp->timetowait / 5))
timewarn(offset);
(void)sleep(sltime);
}
};
void
-timewarn(int timeleft)
+timewarn(time_t timeleft)
{
static int first;
static char hostname[MAXHOSTNAMELEN + 1];
(void)fprintf(pf, "System going down at %5.5s\n\n",
ctime(&shuttime) + 11);
else if (timeleft > 59)
- (void)fprintf(pf, "System going down in %d minute%s\n\n",
+ (void)fprintf(pf, "System going down in %ld minute%s\n\n",
timeleft / 60, (timeleft > 60) ? "s" : "");
else if (timeleft)
(void)fprintf(pf, "System going down in 30 seconds\n\n");
#ifndef __APPLE__
char *empty_environ[] = { NULL };
#else
- if ((errno = reserve_reboot()))
- err(1, "couldn't lock for reboot");
+ if ((errno = reserve_reboot())) {
+ warn("couldn't lock for reboot");
+ finish(0);
+ }
#endif
syslog(LOG_NOTICE, "%s%s by %s: %s",
#ifndef __APPLE__
- doreboot ? "reboot" : dohalt ? "halt" : dopower ? "power-down" :
+ doreboot ? "reboot" : dohalt ? "halt" : dopower ? "power-down" :
#else
doreboot ? "reboot" : dohalt ? "halt" : dosleep ? "sleep" :
#endif
}
}
}
- exit((kr == kIOReturnSuccess) ? 0 : 1);
} else {
int howto = 0;
+#if defined(__APPLE__)
+ {
+ struct utmpx utx;
+ bzero(&utx, sizeof(utx));
+ utx.ut_type = SHUTDOWN_TIME;
+ gettimeofday(&utx.ut_tv, NULL);
+ pututxline(&utx);
+
+ int newvalue = 1;
+ sysctlbyname("kern.willshutdown", NULL, NULL, &newvalue, sizeof(newvalue));
+ }
+#else
logwtmp("~", "shutdown", "");
+#endif
if (dohalt) howto |= RB_HALT;
if (doups) howto |= RB_UPSDELAY;
if (nosync) howto |= RB_NOSYNC;
// launchd(8) handles reboot. This call returns NULL on success.
- exit(reboot2(howto) == NULL ? EXIT_SUCCESS : EXIT_FAILURE);
+ if (reboot3(howto)) {
+ syslog(LOG_ERR, "shutdown: launchd reboot failed.");
+ }
}
- /* NOT-REACHED */
-
#else /* __APPLE__ */
if (!oflag) {
(void)kill(1, doreboot ? SIGINT : /* reboot */
SIGTERM); /* single-user */
} else {
if (doreboot) {
- execle(_PATH_REBOOT, "reboot", "-l", nosync,
+ execle(_PATH_REBOOT, "reboot", "-l", nosync,
(char *)NULL, empty_environ);
syslog(LOG_ERR, "shutdown: can't exec %s: %m.",
_PATH_REBOOT);
#define NOMSG "\n\nNO LOGINS: System going down at "
void
-nolog()
+nolog(void)
{
-#ifndef __APPLE__
int logfd;
char *ct;
(void)write(logfd, mbuf, strlen(mbuf));
(void)close(logfd);
}
-#endif /* !__APPLE__ */
}
void
finish(int signo __unused)
{
-#ifndef __APPLE__
if (!killflg)
(void)unlink(_PATH_NOLOGIN);
-#endif
exit(0);
}
void
-badtime()
+badtime(void)
{
errx(1, "bad time format");
}
* header
* subject
* return
- */
-int audit_shutdown(int exitstatus)
+ */
+int
+audit_shutdown(int exitstatus)
{
int aufd;
token_t *tok;
if((aufd = au_open()) == -1) {
fprintf(stderr, "shutdown: Audit Error: au_open() failed\n");
- exit(1);
+ exit(1);
}
/* The subject that performed the operation */
* contact kextd to lock for reboot
*/
int
-reserve_reboot()
+reserve_reboot(void)
{
int rval = ELAST + 1;
kern_return_t macherr = KERN_FAILURE;
int busyStatus = ELAST + 1;
mountpoint_t busyVol;
- macherr = bootstrap_look_up(bootstrap_port, KEXTD_SERVER_NAME, &kxport);
+ macherr = bootstrap_look_up2(bootstrap_port, KEXTD_SERVER_NAME, &kxport, 0, BOOTSTRAP_PRIVILEGED_SERVER);
if (macherr) goto finish;
// allocate a port to pass to kextd (in case we die)
return rval;
}
#endif /* __APPLE__ */
-