199767f8919635c4928607450d9e0abb932109ceToomas Soome/*-
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
199767f8919635c4928607450d9e0abb932109ceToomas Soome * All rights reserved.
199767f8919635c4928607450d9e0abb932109ceToomas Soome *
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Redistribution and use in source and binary forms, with or without
199767f8919635c4928607450d9e0abb932109ceToomas Soome * modification, are permitted provided that the following conditions
199767f8919635c4928607450d9e0abb932109ceToomas Soome * are met:
199767f8919635c4928607450d9e0abb932109ceToomas Soome * 1. Redistributions of source code must retain the above copyright
199767f8919635c4928607450d9e0abb932109ceToomas Soome * notice, this list of conditions and the following disclaimer.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * 2. Redistributions in binary form must reproduce the above copyright
199767f8919635c4928607450d9e0abb932109ceToomas Soome * notice, this list of conditions and the following disclaimer in the
199767f8919635c4928607450d9e0abb932109ceToomas Soome * documentation and/or other materials provided with the distribution.
199767f8919635c4928607450d9e0abb932109ceToomas Soome *
199767f8919635c4928607450d9e0abb932109ceToomas Soome * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
199767f8919635c4928607450d9e0abb932109ceToomas Soome * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
199767f8919635c4928607450d9e0abb932109ceToomas Soome * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
199767f8919635c4928607450d9e0abb932109ceToomas Soome * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
199767f8919635c4928607450d9e0abb932109ceToomas Soome * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
199767f8919635c4928607450d9e0abb932109ceToomas Soome * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
199767f8919635c4928607450d9e0abb932109ceToomas Soome * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
199767f8919635c4928607450d9e0abb932109ceToomas Soome * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
199767f8919635c4928607450d9e0abb932109ceToomas Soome * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
199767f8919635c4928607450d9e0abb932109ceToomas Soome * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
199767f8919635c4928607450d9e0abb932109ceToomas Soome * SUCH DAMAGE.
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include <sys/cdefs.h>
199767f8919635c4928607450d9e0abb932109ceToomas Soome__FBSDID("$FreeBSD$");
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include <stand.h>
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include <string.h>
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include "bootstrap.h"
199767f8919635c4928607450d9e0abb932109ceToomas Soome/*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Core console support
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic int cons_set(struct env_var *ev, int flags, const void *value);
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic int cons_find(const char *name);
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic int cons_check(const char *string);
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic int cons_change(const char *string);
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic int twiddle_set(struct env_var *ev, int flags, const void *value);
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Detect possible console(s) to use. If preferred console(s) have been
199767f8919635c4928607450d9e0abb932109ceToomas Soome * specified, mark them as active. Else, mark the first probed console
199767f8919635c4928607450d9e0abb932109ceToomas Soome * as active. Also create the console variable.
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soomevoid
199767f8919635c4928607450d9e0abb932109ceToomas Soomecons_probe(void)
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome int cons;
199767f8919635c4928607450d9e0abb932109ceToomas Soome int active;
199767f8919635c4928607450d9e0abb932109ceToomas Soome char *prefconsole;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* We want a callback to install the new value when this var changes. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome env_setenv("twiddle_divisor", EV_VOLATILE, "1", twiddle_set, env_nounset);
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* Do all console probes */
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (cons = 0; consoles[cons] != NULL; cons++) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome consoles[cons]->c_flags = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome consoles[cons]->c_probe(consoles[cons]);
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* Now find the first working one */
199767f8919635c4928607450d9e0abb932109ceToomas Soome active = -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (cons = 0; consoles[cons] != NULL && active == -1; cons++) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome consoles[cons]->c_flags = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome consoles[cons]->c_probe(consoles[cons]);
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (consoles[cons]->c_flags == (C_PRESENTIN | C_PRESENTOUT))
199767f8919635c4928607450d9e0abb932109ceToomas Soome active = cons;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* Force a console even if all probes failed */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (active == -1)
199767f8919635c4928607450d9e0abb932109ceToomas Soome active = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* Check to see if a console preference has already been registered */
199767f8919635c4928607450d9e0abb932109ceToomas Soome prefconsole = getenv("console");
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (prefconsole != NULL)
199767f8919635c4928607450d9e0abb932109ceToomas Soome prefconsole = strdup(prefconsole);
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (prefconsole != NULL) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome unsetenv("console"); /* we want to replace this */
199767f8919635c4928607450d9e0abb932109ceToomas Soome cons_change(prefconsole);
199767f8919635c4928607450d9e0abb932109ceToomas Soome } else {
199767f8919635c4928607450d9e0abb932109ceToomas Soome consoles[active]->c_flags |= C_ACTIVEIN | C_ACTIVEOUT;
199767f8919635c4928607450d9e0abb932109ceToomas Soome consoles[active]->c_init(consoles[active], 0);
199767f8919635c4928607450d9e0abb932109ceToomas Soome prefconsole = strdup(consoles[active]->c_name);
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome printf("Consoles: ");
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (cons = 0; consoles[cons] != NULL; cons++)
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (consoles[cons]->c_flags & (C_ACTIVEIN | C_ACTIVEOUT))
199767f8919635c4928607450d9e0abb932109ceToomas Soome printf("%s ", consoles[cons]->c_desc);
199767f8919635c4928607450d9e0abb932109ceToomas Soome printf("\n");
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (prefconsole != NULL) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome env_setenv("console", EV_VOLATILE, prefconsole, cons_set,
199767f8919635c4928607450d9e0abb932109ceToomas Soome env_nounset);
199767f8919635c4928607450d9e0abb932109ceToomas Soome free(prefconsole);
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soomevoid
199767f8919635c4928607450d9e0abb932109ceToomas Soomecons_mode(int raw)
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome int cons;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (cons = 0; consoles[cons] != NULL; cons++) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (raw == 0)
199767f8919635c4928607450d9e0abb932109ceToomas Soome consoles[cons]->c_flags &= ~C_MODERAW;
199767f8919635c4928607450d9e0abb932109ceToomas Soome else
199767f8919635c4928607450d9e0abb932109ceToomas Soome consoles[cons]->c_flags |= C_MODERAW;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soomeint
199767f8919635c4928607450d9e0abb932109ceToomas Soomegetchar(void)
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome int cons;
199767f8919635c4928607450d9e0abb932109ceToomas Soome int rv;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* Loop forever polling all active consoles */
199767f8919635c4928607450d9e0abb932109ceToomas Soome for(;;)
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (cons = 0; consoles[cons] != NULL; cons++)
199767f8919635c4928607450d9e0abb932109ceToomas Soome if ((consoles[cons]->c_flags & (C_PRESENTIN | C_ACTIVEIN)) ==
199767f8919635c4928607450d9e0abb932109ceToomas Soome (C_PRESENTIN | C_ACTIVEIN) &&
199767f8919635c4928607450d9e0abb932109ceToomas Soome ((rv = consoles[cons]->c_in(consoles[cons])) != -1))
199767f8919635c4928607450d9e0abb932109ceToomas Soome return(rv);
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soomeint
199767f8919635c4928607450d9e0abb932109ceToomas Soomeischar(void)
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome int cons;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (cons = 0; consoles[cons] != NULL; cons++)
199767f8919635c4928607450d9e0abb932109ceToomas Soome if ((consoles[cons]->c_flags & (C_PRESENTIN | C_ACTIVEIN)) ==
199767f8919635c4928607450d9e0abb932109ceToomas Soome (C_PRESENTIN | C_ACTIVEIN) &&
199767f8919635c4928607450d9e0abb932109ceToomas Soome (consoles[cons]->c_ready(consoles[cons]) != 0))
199767f8919635c4928607450d9e0abb932109ceToomas Soome return(1);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return(0);
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soomevoid
199767f8919635c4928607450d9e0abb932109ceToomas Soomeputchar(int c)
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome int cons;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* Expand newlines if not in raw mode */
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (cons = 0; consoles[cons] != NULL; cons++)
199767f8919635c4928607450d9e0abb932109ceToomas Soome if ((consoles[cons]->c_flags & (C_PRESENTOUT | C_ACTIVEOUT)) ==
199767f8919635c4928607450d9e0abb932109ceToomas Soome (C_PRESENTOUT | C_ACTIVEOUT)) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (c == '\n' && (consoles[cons]->c_flags & C_MODERAW) == 0)
199767f8919635c4928607450d9e0abb932109ceToomas Soome consoles[cons]->c_out(consoles[cons], '\r');
199767f8919635c4928607450d9e0abb932109ceToomas Soome consoles[cons]->c_out(consoles[cons], c);
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Find the console with the specified name.
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic int
199767f8919635c4928607450d9e0abb932109ceToomas Soomecons_find(const char *name)
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome int cons;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (cons = 0; consoles[cons] != NULL; cons++)
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (!strcmp(consoles[cons]->c_name, name))
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (cons);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (-1);
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Select one or more consoles.
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic int
199767f8919635c4928607450d9e0abb932109ceToomas Soomecons_set(struct env_var *ev, int flags, const void *value)
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome int ret;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome if ((value == NULL) || (cons_check(value) == 0)) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome /*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Return CMD_OK instead of CMD_ERROR to prevent forth syntax error,
199767f8919635c4928607450d9e0abb932109ceToomas Soome * which would prevent it processing any further loader.conf entries.
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (CMD_OK);
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome ret = cons_change(value);
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (ret != CMD_OK)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (ret);
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (CMD_OK);
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Check that at least one the consoles listed in *string is valid
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic int
199767f8919635c4928607450d9e0abb932109ceToomas Soomecons_check(const char *string)
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome int cons, found, failed;
199767f8919635c4928607450d9e0abb932109ceToomas Soome char *curpos, *dup, *next;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome dup = next = strdup(string);
199767f8919635c4928607450d9e0abb932109ceToomas Soome found = failed = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome while (next != NULL) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome curpos = strsep(&next, " ,");
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (*curpos != '\0') {
199767f8919635c4928607450d9e0abb932109ceToomas Soome cons = cons_find(curpos);
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (cons == -1) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome printf("console %s is invalid!\n", curpos);
199767f8919635c4928607450d9e0abb932109ceToomas Soome failed++;
199767f8919635c4928607450d9e0abb932109ceToomas Soome } else {
199767f8919635c4928607450d9e0abb932109ceToomas Soome found++;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome free(dup);
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (found == 0)
199767f8919635c4928607450d9e0abb932109ceToomas Soome printf("no valid consoles!\n");
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (found == 0 || failed != 0) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome printf("Available consoles:\n");
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (cons = 0; consoles[cons] != NULL; cons++)
199767f8919635c4928607450d9e0abb932109ceToomas Soome printf(" %s\n", consoles[cons]->c_name);
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (found);
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Activate all the valid consoles listed in *string and disable all others.
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic int
199767f8919635c4928607450d9e0abb932109ceToomas Soomecons_change(const char *string)
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome int cons, active;
199767f8919635c4928607450d9e0abb932109ceToomas Soome char *curpos, *dup, *next;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* Disable all consoles */
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (cons = 0; consoles[cons] != NULL; cons++) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome consoles[cons]->c_flags &= ~(C_ACTIVEIN | C_ACTIVEOUT);
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* Enable selected consoles */
199767f8919635c4928607450d9e0abb932109ceToomas Soome dup = next = strdup(string);
199767f8919635c4928607450d9e0abb932109ceToomas Soome active = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome while (next != NULL) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome curpos = strsep(&next, " ,");
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (*curpos == '\0')
199767f8919635c4928607450d9e0abb932109ceToomas Soome continue;
199767f8919635c4928607450d9e0abb932109ceToomas Soome cons = cons_find(curpos);
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (cons >= 0) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome consoles[cons]->c_flags |= C_ACTIVEIN | C_ACTIVEOUT;
199767f8919635c4928607450d9e0abb932109ceToomas Soome consoles[cons]->c_init(consoles[cons], 0);
199767f8919635c4928607450d9e0abb932109ceToomas Soome if ((consoles[cons]->c_flags & (C_PRESENTIN | C_PRESENTOUT)) ==
199767f8919635c4928607450d9e0abb932109ceToomas Soome (C_PRESENTIN | C_PRESENTOUT)) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome active++;
199767f8919635c4928607450d9e0abb932109ceToomas Soome continue;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (active != 0) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* If no consoles have initialised we wouldn't see this. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome printf("console %s failed to initialize\n", consoles[cons]->c_name);
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome free(dup);
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (active == 0) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* All requested consoles failed to initialise, try to recover. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (cons = 0; consoles[cons] != NULL; cons++) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome consoles[cons]->c_flags |= C_ACTIVEIN | C_ACTIVEOUT;
199767f8919635c4928607450d9e0abb932109ceToomas Soome consoles[cons]->c_init(consoles[cons], 0);
199767f8919635c4928607450d9e0abb932109ceToomas Soome if ((consoles[cons]->c_flags &
199767f8919635c4928607450d9e0abb932109ceToomas Soome (C_PRESENTIN | C_PRESENTOUT)) ==
199767f8919635c4928607450d9e0abb932109ceToomas Soome (C_PRESENTIN | C_PRESENTOUT))
199767f8919635c4928607450d9e0abb932109ceToomas Soome active++;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (active == 0)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (CMD_ERROR); /* Recovery failed. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (CMD_OK);
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Change the twiddle divisor.
199767f8919635c4928607450d9e0abb932109ceToomas Soome *
199767f8919635c4928607450d9e0abb932109ceToomas Soome * The user can set the twiddle_divisor variable to directly control how fast
199767f8919635c4928607450d9e0abb932109ceToomas Soome * the progress twiddle spins, useful for folks with slow serial consoles. The
199767f8919635c4928607450d9e0abb932109ceToomas Soome * code to monitor changes to the variable and propagate them to the twiddle
199767f8919635c4928607450d9e0abb932109ceToomas Soome * routines has to live somewhere. Twiddling is console-related so it's here.
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic int
199767f8919635c4928607450d9e0abb932109ceToomas Soometwiddle_set(struct env_var *ev, int flags, const void *value)
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome u_long tdiv;
199767f8919635c4928607450d9e0abb932109ceToomas Soome char * eptr;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome tdiv = strtoul(value, &eptr, 0);
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (*(const char *)value == 0 || *eptr != 0) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome printf("invalid twiddle_divisor '%s'\n", (const char *)value);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (CMD_ERROR);
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome twiddle_divisor((u_int)tdiv);
199767f8919635c4928607450d9e0abb932109ceToomas Soome env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome return(CMD_OK);
199767f8919635c4928607450d9e0abb932109ceToomas Soome}