diff --git a/sbin/reboot/reboot.c b/sbin/reboot/reboot.c --- a/sbin/reboot/reboot.c +++ b/sbin/reboot/reboot.c @@ -56,6 +56,7 @@ static uint64_t get_pageins(void); static bool dohalt; +static bool donextboot; #define E(...) do { \ if (force) { \ @@ -163,6 +164,12 @@ free(oldenv); } +/* + * Different options are valid for different programs. + */ +#define GETOPT_REBOOT "cDde:k:lNno:pqr" +#define GETOPT_NEXTBOOT "De:k:o:" + int main(int argc, char *argv[]) { @@ -171,16 +178,20 @@ int ch, howto, i, sverrno; bool Dflag, fflag, lflag, Nflag, nflag, qflag; uint64_t pageins; - const char *user, *kernel = NULL; + const char *user, *kernel = NULL, *getopts = GETOPT_REBOOT; char *env = NULL, *v; if (strstr(getprogname(), "halt") != NULL) { dohalt = true; howto = RB_HALT; - } else + } else if (strcmp(getprogname(), "nextboot") == 0) { + donextboot = true; + getopts = GETOPT_NEXTBOOT; /* Note: reboot's extra opts return '?' */ + } else { howto = 0; + } Dflag = fflag = lflag = Nflag = nflag = qflag = false; - while ((ch = getopt(argc, argv, "cDde:k:lNno:pqr")) != -1) + while ((ch = getopt(argc, argv, getopts)) != -1) { switch(ch) { case 'c': howto |= RB_POWERCYCLE; @@ -228,6 +239,8 @@ default: usage(); } + } + argc -= optind; argv += optind; if (argc != 0) @@ -245,10 +258,6 @@ errx(1, "-r cannot be used with -c, -d, -n, or -p"); if ((howto & RB_REROOT) != 0 && kernel != NULL) errx(1, "-r and -k cannot be used together, there is no next kernel"); - if (geteuid()) { - errno = EPERM; - err(1, NULL); - } if (Dflag) { if (unlink(PATH_NEXTBOOT) != 0) @@ -256,6 +265,11 @@ exit(0); } + if (!donextboot && geteuid() != 0) { + errno = EPERM; + err(1, NULL); + } + if (qflag) { reboot(howto); err(1, NULL); @@ -278,7 +292,11 @@ add_env(&env, "kernel", kernel); } - write_nextboot(PATH_NEXTBOOT, env, fflag); + if (env != NULL) + write_nextboot(PATH_NEXTBOOT, env, fflag); + if (donextboot) + exit (0); + /* Log the reboot. */ if (!lflag) { if ((user = getlogin()) == NULL)