aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/rc/rc.c54
1 files changed, 33 insertions, 21 deletions
diff --git a/src/rc/rc.c b/src/rc/rc.c
index 183d0a1d..65d3a560 100644
--- a/src/rc/rc.c
+++ b/src/rc/rc.c
@@ -383,13 +383,13 @@ get_krunlevel(char *buffer, int buffer_len)
return 0;
if (!(fp = fopen(RC_KRUNLEVEL, "r"))) {
eerror("fopen `%s': %s", RC_KRUNLEVEL, strerror(errno));
- return -1;
+ return 0;
}
if (fgets(buffer, buffer_len, fp)) {
- i = strlen(buffer) - 1;
- if (buffer[i] == '\n')
- buffer[i] = 0;
+ i = strlen(buffer);
+ if (buffer[i - 1] == '\n')
+ buffer[i - 1] = 0;
}
fclose(fp);
return i;
@@ -810,8 +810,14 @@ main(int argc, char **argv)
case 'o':
if (*optarg == '\0')
optarg = NULL;
- exit(set_krunlevel(optarg) ?
- EXIT_SUCCESS : EXIT_FAILURE);
+ if (!rc_runlevel_exists(optarg)) {
+ eerror("runlevel `%s' does not exist", optarg);
+ exit(EXIT_FAILURE);
+ }
+ if (!set_krunlevel(optarg))
+ exit(EXIT_FAILURE);
+ einfo("Overriding next runlevel to %s", optarg);
+ exit(EXIT_SUCCESS);
/* NOTREACHED */
case 's':
newlevel = rc_service_resolve(optarg);
@@ -872,29 +878,35 @@ main(int argc, char **argv)
/* Now we start handling our children */
signal_setup(SIGCHLD, handle_signal);
- /* We should only use krunlevel if we were in single user mode
- * If not, we need to erase krunlevel now. */
- if (strcmp(runlevel, RC_LEVEL_SINGLE) == 0) {
- /* Try not to join boot and krunlevels together */
- if (!newlevel ||
- (strcmp(newlevel, RC_LEVEL_SINGLE) != 0 &&
- strcmp(newlevel, getenv("RC_BOOTLEVEL")) != 0 &&
- strcmp(newlevel, RC_LEVEL_SYSINIT) != 0))
- if (get_krunlevel(krunlevel, sizeof(krunlevel)))
- newlevel = krunlevel;
- } else
- set_krunlevel(NULL);
-
if (newlevel &&
(strcmp(newlevel, RC_LEVEL_SHUTDOWN) == 0 ||
strcmp(newlevel, RC_LEVEL_SINGLE) == 0))
{
going_down = true;
- set_krunlevel(runlevel);
+ if (!exists(RC_KRUNLEVEL))
+ set_krunlevel(runlevel);
rc_runlevel_set(newlevel);
setenv("RC_RUNLEVEL", newlevel, 1);
setenv("RC_GOINGDOWN", "YES", 1);
+ } else {
+ /* We should not use krunevel in sysinit or the boot runlevel */
+ if (!newlevel ||
+ strcmp(newlevel, RC_LEVEL_SYSINIT) != 0 ||
+ strcmp(newlevel, getenv("RC_BOOTLEVEL")) != 0)
+ {
+ if (get_krunlevel(krunlevel, sizeof(krunlevel))) {
+ newlevel = krunlevel;
+ set_krunlevel(NULL);
+ }
+ }
+
+ if (newlevel &&
+ strcmp(runlevel, newlevel) != 0 &&
+ !rc_runlevel_exists(newlevel))
+ eerrorx("%s: is not a valid runlevel", newlevel);
+ }
+ if (going_down) {
#ifdef __FreeBSD__
/* FIXME: we shouldn't have todo this */
/* For some reason, wait_for_services waits for the logger
@@ -963,7 +975,7 @@ main(int argc, char **argv)
tmplist = rc_services_in_runlevel(RC_LEVEL_SYSINIT);
TAILQ_CONCAT(start_services, tmplist, entries);
free(tmplist);
- if (strcmp(newlevel ? runlevel : runlevel,
+ if (strcmp(newlevel ? newlevel : runlevel,
RC_LEVEL_SINGLE) != 0)
{
if (strcmp(newlevel ? newlevel : runlevel,