freebsd-src/sys/boot/common/commands.c
Mike Smith 06b57b0e09 Bootstrap updates.
- Move some startup code from MD to MI sections
 - Add a 'copyout' and some copyout-related functions.  These will be
   obsoleted when BTX is available for the 386 and the kernel load
   area becomes directly addressable.
 - Add the ability load an arbitrary file as a module, associating
   and arbitrary type string with it.  This can be used eg. for loading
   splash-screen images etc.
 - Add KLD module dependancy infrastructure.  We know how to look for
   dependancies inside KLD modules, how to resolve these dependancies
   and what to do if things go wrong.  Only works for a.out at the
   moment, due to lack of an MI ELF loader.  Attach KLD module information
   to loaded modules as metadata, but don't pass it to the kernel (it
   can find it itself).
 - Load a.out KLD modules on a page boundary.  Only pad the a.out BSS
   for the kernel, as it may want to throw symbols away.  (We might want
   to do this for KLD modules too.)
 - Allow commands to be hidden from the '?' display, to avoid cluttering
   it with things like 'echo'.  Add 'echo'.
 - Bring the 'prompt' command into line with the parser syntax.
 - Fix the verbose 'ls'; it was using an uninitialised stack variable.
 - Add a '-v' flag to 'lsmod' to have it display module metadata as well
   (not terribly useful for the average user)
 - Support a 'module searchpath' for required modules.
 - The bootstrap file on i386 is now called 'loader' to permit the
   /boot directory to use that name.
 - Discard the old i386 pread() function, as it's replaced by
   arch_readin()
1998-09-03 02:10:09 +00:00

191 lines
4.6 KiB
C

/*-
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: commands.c,v 1.1.1.1 1998/08/21 03:17:41 msmith Exp $
*/
#include <stand.h>
#include <string.h>
#include <sys/reboot.h>
#include "bootstrap.h"
char *command_errmsg;
char command_errbuf[256]; /* XXX should have procedural interface for setting, size limit? */
COMMAND_SET(help, "help", "detailed help", command_help);
static int
command_help(int argc, char *argv[])
{
char helppath[80]; /* XXX buffer size? */
/* page the help text from our load path */
sprintf(helppath, "%s/boot.help", getenv("loaddev"));
printf("%s\n", helppath);
if (pager_file(helppath) == -1)
printf("Verbose help not available, use '?' to list commands\n");
return(CMD_OK);
}
COMMAND_SET(commandlist, "?", "list commands", command_commandlist);
static int
command_commandlist(int argc, char *argv[])
{
struct bootblk_command **cmdp;
int i;
printf("Available commands:\n");
cmdp = (struct bootblk_command **)Xcommand_set.ls_items;
for (i = 0; i < Xcommand_set.ls_length; i++)
if ((cmdp[i]->c_name != NULL) && (cmdp[i]->c_desc != NULL))
printf(" %-15s %s\n", cmdp[i]->c_name, cmdp[i]->c_desc);
return(CMD_OK);
}
/*
* XXX set/show should become set/echo if we have variable
* substitution happening.
*/
COMMAND_SET(show, "show", "show variable(s)", command_show);
static int
command_show(int argc, char *argv[])
{
struct env_var *ev;
char *cp;
if (argc < 2) {
/*
* With no arguments, print everything.
*/
pager_open();
for (ev = environ; ev != NULL; ev = ev->ev_next) {
pager_output(ev->ev_name);
cp = getenv(ev->ev_name);
if (cp != NULL) {
pager_output("=");
pager_output(cp);
}
pager_output("\n");
}
pager_close();
} else {
if ((cp = getenv(argv[1])) != NULL) {
printf("%s\n", cp);
} else {
sprintf(command_errbuf, "variable '%s' not found", argv[1]);
return(CMD_ERROR);
}
}
return(CMD_OK);
}
COMMAND_SET(set, "set", "set a variable", command_set);
static int
command_set(int argc, char *argv[])
{
int err;
if (argc != 2) {
command_errmsg = "wrong number of arguments";
return(CMD_ERROR);
} else {
if ((err = putenv(argv[1])) != 0) {
command_errmsg = strerror(err);
return(CMD_ERROR);
}
}
return(CMD_OK);
}
COMMAND_SET(unset, "unset", "unset a variable", command_unset);
static int
command_unset(int argc, char *argv[])
{
int err;
if (argc != 2) {
command_errmsg = "wrong number of arguments";
return(CMD_ERROR);
} else {
if ((err = unsetenv(argv[1])) != 0) {
command_errmsg = strerror(err);
return(CMD_ERROR);
}
}
return(CMD_OK);
}
COMMAND_SET(panic, "panic", "test panic", command_panic);
static int
command_panic(int argc, char *argv[])
{
char *cp;
cp = unargv(argc - 1, argv + 1);
panic(cp);
}
COMMAND_SET(echo, "echo", NULL, command_echo);
static int
command_echo(int argc, char *argv[])
{
char *s;
int nl, ch;
nl = 0;
optind = 1;
while ((ch = getopt(argc, argv, "n")) != -1) {
switch(ch) {
case 'n':
nl = 1;
break;
case '?':
default:
/* getopt has already reported an error */
return(CMD_OK);
}
}
argv += (optind);
argc -= (optind);
s = unargv(argc, argv);
if (s != NULL) {
printf(s);
free(s);
}
if (!nl)
printf("\n");
return(CMD_OK);
}