summaryrefslogtreecommitdiffstats
path: root/sys/boot/common/interp.c
diff options
context:
space:
mode:
authormsmith <msmith@FreeBSD.org>1998-08-21 03:17:42 +0000
committermsmith <msmith@FreeBSD.org>1998-08-21 03:17:42 +0000
commit8adeb775c43d4c2ae76cce40837a3953af6abc83 (patch)
treeec778e5f3903abe2dbb59959c0fd8398c99c145b /sys/boot/common/interp.c
parent335c4be5b17816baac6b70d4d0b3132925de858d (diff)
downloadFreeBSD-src-8adeb775c43d4c2ae76cce40837a3953af6abc83.zip
FreeBSD-src-8adeb775c43d4c2ae76cce40837a3953af6abc83.tar.gz
This is the new unified bootstrap, sometimes known previously as the
'three-stage' bootstrap. There are a number of caveats with the code in its current state: - The i386 bootstrap only supports booting from a floppy. - The kernel and kld do not yet know how to deal with the extended information and module summary passed in. - PnP-based autodetection and demand loading of modules is not implemented. - i386 ELF kernel loading is not ready yet. - The i386 bootstrap is loaded via an ugly blockmap. On the alpha, both net- and disk-booting (SRM console machines only) is supported. No blockmaps are used by this code. Obtained from: Parts from the NetBSD/i386 standalone bootstrap.
Diffstat (limited to 'sys/boot/common/interp.c')
-rw-r--r--sys/boot/common/interp.c207
1 files changed, 207 insertions, 0 deletions
diff --git a/sys/boot/common/interp.c b/sys/boot/common/interp.c
new file mode 100644
index 0000000..2bd75f4
--- /dev/null
+++ b/sys/boot/common/interp.c
@@ -0,0 +1,207 @@
+/*-
+ * 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$
+ */
+/*
+ * Simple commandline interpreter.
+ *
+ * XXX may be obsoleted by BootFORTH
+ */
+
+#include <stand.h>
+#include <string.h>
+#include "bootstrap.h"
+
+#define MAXARGS 20 /* maximum number of arguments allowed */
+
+static int parse(char *buf, int *argcp, char **argvp[]);
+static void prompt(void);
+/*
+ * Parse the supplied text into argv/argc form.
+ * XXX should perhaps learn about quotes, etc?
+ * XXX can also do alias expansion, variable substitution, etc. here
+ */
+static int
+parse(char *buf, int *argcp, char **argvp[])
+{
+ static int argc;
+ static char *argv[MAXARGS], *cp;
+
+ argc = 0;
+ cp = buf;
+ while ((*cp != 0) && (argc < MAXARGS)) {
+ if (isspace(*cp)) {
+ *(cp++) = 0;
+ } else {
+ argv[argc++] = cp++;
+ while ((*cp != 0) && !isspace(*cp))
+ cp++;
+ }
+ }
+ argv[argc] = NULL;
+ /* command too complex */
+ if (argc >= MAXARGS) {
+ printf("too many arguments\n");
+ return(1);
+ }
+ *argcp = argc;
+ *argvp = argv;
+ return(0);
+}
+
+/*
+ * Perform the command
+ */
+static int
+perform(int argc, char *argv[])
+{
+ int i, result;
+ struct bootblk_command **cmdp;
+ bootblk_cmd_t *cmd;
+
+ if (argc < 1)
+ return(CMD_OK);
+
+ /* set return defaults; a successful command will override these */
+ command_errmsg = command_errbuf;
+ strcpy(command_errbuf, "no error message");
+ cmd = NULL;
+ result = CMD_ERROR;
+
+ cmdp = (struct bootblk_command **)Xcommand_set.ls_items;
+ for (i = 0; i < Xcommand_set.ls_length; i++) {
+ if ((cmdp[i]->c_name != NULL) && !strcmp(argv[0], cmdp[i]->c_name))
+ cmd = cmdp[i]->c_fn;
+ }
+ if (cmd != NULL) {
+ result = (cmd)(argc, argv);
+ } else {
+ command_errmsg = "unknown command";
+ }
+ return(result);
+}
+
+/*
+ * Interactive mode
+ */
+void
+interact(void)
+{
+ char input[256]; /* big enough? */
+ int argc;
+ char **argv;
+
+ for (;;) {
+ input[0] = '\0';
+ prompt();
+ ngets(input, sizeof(input));
+ if (!parse(input, &argc, &argv) &&
+ (perform(argc, argv) != 0))
+ printf("%s: %s\n", argv[0], command_errmsg);
+ }
+}
+
+/*
+ * Read command from a file
+ */
+COMMAND_SET(source, "source", "read commands from a file", command_source);
+
+static int
+command_source(int argc, char *argv[])
+{
+ int i;
+
+ for (i = 1; i < argc; i++)
+ source(argv[i]);
+ return(CMD_OK);
+}
+
+void
+source(char *filename)
+{
+ char input[256]; /* big enough? */
+ int argc;
+ char **argv, *cp;
+ int fd;
+
+ if (((fd = open(filename, O_RDONLY)) == -1)) {
+ printf("can't open '%s': %s\n", filename, strerror(errno));
+ } else {
+ while (fgetstr(input, sizeof(input), fd) > 0) {
+
+ /* Discard comments */
+ if (input[0] == '#')
+ continue;
+ cp = input;
+ /* Echo? */
+ if (input[0] == '@') {
+ cp++;
+ } else {
+ prompt();
+ printf("%s\n", input);
+ }
+
+ if (!parse(cp, &argc, &argv) &&
+ (argc > 0) &&
+ (perform(argc, argv) != 0))
+ printf("%s: %s\n", argv[0], command_errmsg);
+ }
+ close(fd);
+ }
+}
+
+/*
+ * Emit the current prompt; support primitive embedding of
+ * environment variables.
+ * We're a little rude here, modifying the return from getenv().
+ */
+static void
+prompt(void)
+{
+ char *p, *cp, *ev, c;
+
+ if ((p = getenv("prompt")) == NULL)
+ p = ">";
+
+ while (*p != 0) {
+ if (*p == '$') {
+ for (cp = p + 1; (*cp != 0) && isalpha(*cp); cp++)
+ ;
+ c = *cp;
+ *cp = 0;
+ ev = getenv(p + 1);
+ *cp = c;
+
+ if (ev != NULL) {
+ printf(ev);
+ p = cp;
+ continue;
+ }
+ }
+ putchar(*p++);
+ }
+ putchar(' ');
+}
OpenPOWER on IntegriCloud