179a6a17aSWarner Losh /*-
279a6a17aSWarner Losh * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
379a6a17aSWarner Losh * All rights reserved.
479a6a17aSWarner Losh *
579a6a17aSWarner Losh * Redistribution and use in source and binary forms, with or without
679a6a17aSWarner Losh * modification, are permitted provided that the following conditions
779a6a17aSWarner Losh * are met:
879a6a17aSWarner Losh * 1. Redistributions of source code must retain the above copyright
979a6a17aSWarner Losh * notice, this list of conditions and the following disclaimer.
1079a6a17aSWarner Losh * 2. Redistributions in binary form must reproduce the above copyright
1179a6a17aSWarner Losh * notice, this list of conditions and the following disclaimer in the
1279a6a17aSWarner Losh * documentation and/or other materials provided with the distribution.
1379a6a17aSWarner Losh *
1479a6a17aSWarner Losh * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1579a6a17aSWarner Losh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1679a6a17aSWarner Losh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1779a6a17aSWarner Losh * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1879a6a17aSWarner Losh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1979a6a17aSWarner Losh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2079a6a17aSWarner Losh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2179a6a17aSWarner Losh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2279a6a17aSWarner Losh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2379a6a17aSWarner Losh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2479a6a17aSWarner Losh * SUCH DAMAGE.
2579a6a17aSWarner Losh */
2679a6a17aSWarner Losh
2779a6a17aSWarner Losh /*
2879a6a17aSWarner Losh * Simple commandline interpreter, toplevel and misc.
2979a6a17aSWarner Losh */
3079a6a17aSWarner Losh
3179a6a17aSWarner Losh #include <stand.h>
3279a6a17aSWarner Losh #include <string.h>
3379a6a17aSWarner Losh #include "bootstrap.h"
3479a6a17aSWarner Losh
35d3d381b2SKyle Evans INTERP_DEFINE("simp");
36d3d381b2SKyle Evans
3779a6a17aSWarner Losh void
interp_preinit(void)38*68344c9cSWarner Losh interp_preinit(void)
39*68344c9cSWarner Losh {
40*68344c9cSWarner Losh }
41*68344c9cSWarner Losh
42*68344c9cSWarner Losh void
interp_init(void)4379a6a17aSWarner Losh interp_init(void)
4479a6a17aSWarner Losh {
4579a6a17aSWarner Losh
4686411ec1SWarner Losh setenv("script.lang", "simple", 1);
4779a6a17aSWarner Losh /* Read our default configuration. */
4879a6a17aSWarner Losh interp_include("/boot/loader.rc");
4979a6a17aSWarner Losh }
5079a6a17aSWarner Losh
5179a6a17aSWarner Losh int
interp_run(const char * input)5279a6a17aSWarner Losh interp_run(const char *input)
5379a6a17aSWarner Losh {
5479a6a17aSWarner Losh int argc;
5579a6a17aSWarner Losh char **argv;
5679a6a17aSWarner Losh
5779a6a17aSWarner Losh if (parse(&argc, &argv, input)) {
5879a6a17aSWarner Losh printf("parse error\n");
5979a6a17aSWarner Losh return CMD_ERROR;
6079a6a17aSWarner Losh }
6179a6a17aSWarner Losh
623a4a3639SWarner Losh if (interp_builtin_cmd(argc, argv)) {
6379a6a17aSWarner Losh printf("%s: %s\n", argv[0], command_errmsg);
6479a6a17aSWarner Losh free(argv);
6579a6a17aSWarner Losh return CMD_ERROR;
6679a6a17aSWarner Losh }
6779a6a17aSWarner Losh free(argv);
6879a6a17aSWarner Losh return CMD_OK;
6979a6a17aSWarner Losh }
7079a6a17aSWarner Losh
7179a6a17aSWarner Losh /*
7279a6a17aSWarner Losh * Header prepended to each line. The text immediately follows the header.
7379a6a17aSWarner Losh * We try to make this short in order to save memory -- the loader has
7479a6a17aSWarner Losh * limited memory available, and some of the forth files are very long.
7579a6a17aSWarner Losh */
7679a6a17aSWarner Losh struct includeline
7779a6a17aSWarner Losh {
7879a6a17aSWarner Losh struct includeline *next;
7979a6a17aSWarner Losh int flags;
8079a6a17aSWarner Losh int line;
8179a6a17aSWarner Losh #define SL_QUIET (1<<0)
8279a6a17aSWarner Losh #define SL_IGNOREERR (1<<1)
8379a6a17aSWarner Losh char text[0];
8479a6a17aSWarner Losh };
8579a6a17aSWarner Losh
8679a6a17aSWarner Losh int
interp_include(const char * filename)8779a6a17aSWarner Losh interp_include(const char *filename)
8879a6a17aSWarner Losh {
8979a6a17aSWarner Losh struct includeline *script, *se, *sp;
9079a6a17aSWarner Losh char input[256]; /* big enough? */
9179a6a17aSWarner Losh int argc,res;
9279a6a17aSWarner Losh char **argv, *cp;
9379a6a17aSWarner Losh int fd, flags, line;
9479a6a17aSWarner Losh
9579a6a17aSWarner Losh if (((fd = open(filename, O_RDONLY)) == -1)) {
9679a6a17aSWarner Losh snprintf(command_errbuf, sizeof(command_errbuf),
9779a6a17aSWarner Losh "can't open '%s': %s", filename, strerror(errno));
9879a6a17aSWarner Losh return(CMD_ERROR);
9979a6a17aSWarner Losh }
10079a6a17aSWarner Losh
1018df8b2d3SSimon J. Gerraty #ifdef LOADER_VERIEXEC
102afc571b1SSimon J. Gerraty if (verify_file(fd, filename, 0, VE_GUESS, __func__) < 0) {
1038df8b2d3SSimon J. Gerraty close(fd);
1048df8b2d3SSimon J. Gerraty sprintf(command_errbuf,"can't verify '%s'", filename);
1058df8b2d3SSimon J. Gerraty return(CMD_ERROR);
1068df8b2d3SSimon J. Gerraty }
1078df8b2d3SSimon J. Gerraty #endif
1088df8b2d3SSimon J. Gerraty
10979a6a17aSWarner Losh /*
11079a6a17aSWarner Losh * Read the script into memory.
11179a6a17aSWarner Losh */
11279a6a17aSWarner Losh script = se = NULL;
11379a6a17aSWarner Losh line = 0;
11479a6a17aSWarner Losh
11579a6a17aSWarner Losh while (fgetstr(input, sizeof(input), fd) >= 0) {
11679a6a17aSWarner Losh line++;
11779a6a17aSWarner Losh flags = 0;
11879a6a17aSWarner Losh /* Discard comments */
119ea13a931SRebecca Cran if (strncmp(input+strspn(input, " "), "\\", 1) == 0)
12079a6a17aSWarner Losh continue;
12179a6a17aSWarner Losh cp = input;
12279a6a17aSWarner Losh /* Echo? */
12379a6a17aSWarner Losh if (input[0] == '@') {
12479a6a17aSWarner Losh cp++;
12579a6a17aSWarner Losh flags |= SL_QUIET;
12679a6a17aSWarner Losh }
12779a6a17aSWarner Losh /* Error OK? */
12879a6a17aSWarner Losh if (input[0] == '-') {
12979a6a17aSWarner Losh cp++;
13079a6a17aSWarner Losh flags |= SL_IGNOREERR;
13179a6a17aSWarner Losh }
13279a6a17aSWarner Losh
13379a6a17aSWarner Losh /* Allocate script line structure and copy line, flags */
13479a6a17aSWarner Losh if (*cp == '\0')
13579a6a17aSWarner Losh continue; /* ignore empty line, save memory */
13679a6a17aSWarner Losh sp = malloc(sizeof(struct includeline) + strlen(cp) + 1);
13779a6a17aSWarner Losh /* On malloc failure (it happens!), free as much as possible and exit */
13879a6a17aSWarner Losh if (sp == NULL) {
13979a6a17aSWarner Losh while (script != NULL) {
14079a6a17aSWarner Losh se = script;
14179a6a17aSWarner Losh script = script->next;
14279a6a17aSWarner Losh free(se);
14379a6a17aSWarner Losh }
14479a6a17aSWarner Losh snprintf(command_errbuf, sizeof(command_errbuf),
14579a6a17aSWarner Losh "file '%s' line %d: memory allocation failure - aborting",
14679a6a17aSWarner Losh filename, line);
14779a6a17aSWarner Losh close(fd);
14879a6a17aSWarner Losh return (CMD_ERROR);
14979a6a17aSWarner Losh }
15079a6a17aSWarner Losh strcpy(sp->text, cp);
15179a6a17aSWarner Losh sp->flags = flags;
15279a6a17aSWarner Losh sp->line = line;
15379a6a17aSWarner Losh sp->next = NULL;
15479a6a17aSWarner Losh
15579a6a17aSWarner Losh if (script == NULL) {
15679a6a17aSWarner Losh script = sp;
15779a6a17aSWarner Losh } else {
15879a6a17aSWarner Losh se->next = sp;
15979a6a17aSWarner Losh }
16079a6a17aSWarner Losh se = sp;
16179a6a17aSWarner Losh }
16279a6a17aSWarner Losh close(fd);
16379a6a17aSWarner Losh
16479a6a17aSWarner Losh /*
16579a6a17aSWarner Losh * Execute the script
16679a6a17aSWarner Losh */
16779a6a17aSWarner Losh argv = NULL;
16879a6a17aSWarner Losh res = CMD_OK;
16979a6a17aSWarner Losh for (sp = script; sp != NULL; sp = sp->next) {
17079a6a17aSWarner Losh
17179a6a17aSWarner Losh /* print if not being quiet */
17279a6a17aSWarner Losh if (!(sp->flags & SL_QUIET)) {
17379a6a17aSWarner Losh interp_emit_prompt();
17479a6a17aSWarner Losh printf("%s\n", sp->text);
17579a6a17aSWarner Losh }
17679a6a17aSWarner Losh
17779a6a17aSWarner Losh /* Parse the command */
17879a6a17aSWarner Losh if (!parse(&argc, &argv, sp->text)) {
1793a4a3639SWarner Losh if ((argc > 0) && (interp_builtin_cmd(argc, argv) != 0)) {
18079a6a17aSWarner Losh /* normal command */
18179a6a17aSWarner Losh printf("%s: %s\n", argv[0], command_errmsg);
18279a6a17aSWarner Losh if (!(sp->flags & SL_IGNOREERR)) {
18379a6a17aSWarner Losh res=CMD_ERROR;
18479a6a17aSWarner Losh break;
18579a6a17aSWarner Losh }
18679a6a17aSWarner Losh }
18779a6a17aSWarner Losh free(argv);
18879a6a17aSWarner Losh argv = NULL;
18979a6a17aSWarner Losh } else {
19079a6a17aSWarner Losh printf("%s line %d: parse error\n", filename, sp->line);
19179a6a17aSWarner Losh res=CMD_ERROR;
19279a6a17aSWarner Losh break;
19379a6a17aSWarner Losh }
19479a6a17aSWarner Losh }
19579a6a17aSWarner Losh if (argv != NULL)
19679a6a17aSWarner Losh free(argv);
19779a6a17aSWarner Losh
19879a6a17aSWarner Losh while (script != NULL) {
19979a6a17aSWarner Losh se = script;
20079a6a17aSWarner Losh script = script->next;
20179a6a17aSWarner Losh free(se);
20279a6a17aSWarner Losh }
20379a6a17aSWarner Losh return(res);
20479a6a17aSWarner Losh }
20560e199d9SWarner Losh
20660e199d9SWarner Losh /*
20760e199d9SWarner Losh * There's no graphics commands for the simple interpreter.
20860e199d9SWarner Losh */
20960e199d9SWarner Losh void
gfx_interp_ref(void)2106faf55c8SWarner Losh gfx_interp_ref(void)
21160e199d9SWarner Losh {
21260e199d9SWarner Losh }
213