Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/stand/common/interp_simple.c
34677 views
1
/*-
2
* Copyright (c) 1998 Michael Smith <[email protected]>
3
* All rights reserved.
4
*
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
7
* are met:
8
* 1. Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
10
* 2. Redistributions in binary form must reproduce the above copyright
11
* notice, this list of conditions and the following disclaimer in the
12
* documentation and/or other materials provided with the distribution.
13
*
14
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24
* SUCH DAMAGE.
25
*/
26
27
/*
28
* Simple commandline interpreter, toplevel and misc.
29
*/
30
31
#include <stand.h>
32
#include <string.h>
33
#include "bootstrap.h"
34
35
INTERP_DEFINE("simp");
36
37
void
38
interp_preinit(void)
39
{
40
}
41
42
void
43
interp_init(void)
44
{
45
46
setenv("script.lang", "simple", 1);
47
/* Read our default configuration. */
48
interp_include("/boot/loader.rc");
49
}
50
51
int
52
interp_run(const char *input)
53
{
54
int argc;
55
char **argv;
56
57
if (parse(&argc, &argv, input)) {
58
printf("parse error\n");
59
return CMD_ERROR;
60
}
61
62
if (interp_builtin_cmd(argc, argv)) {
63
printf("%s: %s\n", argv[0], command_errmsg);
64
free(argv);
65
return CMD_ERROR;
66
}
67
free(argv);
68
return CMD_OK;
69
}
70
71
/*
72
* Header prepended to each line. The text immediately follows the header.
73
* We try to make this short in order to save memory -- the loader has
74
* limited memory available, and some of the forth files are very long.
75
*/
76
struct includeline
77
{
78
struct includeline *next;
79
int flags;
80
int line;
81
#define SL_QUIET (1<<0)
82
#define SL_IGNOREERR (1<<1)
83
char text[0];
84
};
85
86
int
87
interp_include(const char *filename)
88
{
89
struct includeline *script, *se, *sp;
90
char input[256]; /* big enough? */
91
int argc,res;
92
char **argv, *cp;
93
int fd, flags, line;
94
95
if (((fd = open(filename, O_RDONLY)) == -1)) {
96
snprintf(command_errbuf, sizeof(command_errbuf),
97
"can't open '%s': %s", filename, strerror(errno));
98
return(CMD_ERROR);
99
}
100
101
#ifdef LOADER_VERIEXEC
102
if (verify_file(fd, filename, 0, VE_GUESS, __func__) < 0) {
103
close(fd);
104
sprintf(command_errbuf,"can't verify '%s'", filename);
105
return(CMD_ERROR);
106
}
107
#endif
108
109
/*
110
* Read the script into memory.
111
*/
112
script = se = NULL;
113
line = 0;
114
115
while (fgetstr(input, sizeof(input), fd) >= 0) {
116
line++;
117
flags = 0;
118
/* Discard comments */
119
if (strncmp(input+strspn(input, " "), "\\", 1) == 0)
120
continue;
121
cp = input;
122
/* Echo? */
123
if (input[0] == '@') {
124
cp++;
125
flags |= SL_QUIET;
126
}
127
/* Error OK? */
128
if (input[0] == '-') {
129
cp++;
130
flags |= SL_IGNOREERR;
131
}
132
133
/* Allocate script line structure and copy line, flags */
134
if (*cp == '\0')
135
continue; /* ignore empty line, save memory */
136
sp = malloc(sizeof(struct includeline) + strlen(cp) + 1);
137
/* On malloc failure (it happens!), free as much as possible and exit */
138
if (sp == NULL) {
139
while (script != NULL) {
140
se = script;
141
script = script->next;
142
free(se);
143
}
144
snprintf(command_errbuf, sizeof(command_errbuf),
145
"file '%s' line %d: memory allocation failure - aborting",
146
filename, line);
147
close(fd);
148
return (CMD_ERROR);
149
}
150
strcpy(sp->text, cp);
151
sp->flags = flags;
152
sp->line = line;
153
sp->next = NULL;
154
155
if (script == NULL) {
156
script = sp;
157
} else {
158
se->next = sp;
159
}
160
se = sp;
161
}
162
close(fd);
163
164
/*
165
* Execute the script
166
*/
167
argv = NULL;
168
res = CMD_OK;
169
for (sp = script; sp != NULL; sp = sp->next) {
170
171
/* print if not being quiet */
172
if (!(sp->flags & SL_QUIET)) {
173
interp_emit_prompt();
174
printf("%s\n", sp->text);
175
}
176
177
/* Parse the command */
178
if (!parse(&argc, &argv, sp->text)) {
179
if ((argc > 0) && (interp_builtin_cmd(argc, argv) != 0)) {
180
/* normal command */
181
printf("%s: %s\n", argv[0], command_errmsg);
182
if (!(sp->flags & SL_IGNOREERR)) {
183
res=CMD_ERROR;
184
break;
185
}
186
}
187
free(argv);
188
argv = NULL;
189
} else {
190
printf("%s line %d: parse error\n", filename, sp->line);
191
res=CMD_ERROR;
192
break;
193
}
194
}
195
if (argv != NULL)
196
free(argv);
197
198
while (script != NULL) {
199
se = script;
200
script = script->next;
201
free(se);
202
}
203
return(res);
204
}
205
206
/*
207
* There's no graphics commands for the simple interpreter.
208
*/
209
void
210
gfx_interp_ref(void)
211
{
212
}
213
214