summaryrefslogtreecommitdiffstats
path: root/sys/boot/common/interp.c
diff options
context:
space:
mode:
authormsmith <msmith@FreeBSD.org>1998-10-07 02:38:26 +0000
committermsmith <msmith@FreeBSD.org>1998-10-07 02:38:26 +0000
commit387d0e8c2b336bf34a8b434f0f090fd31e4e3d7f (patch)
treef649378e8cb57ba1e3a2d3e85e6ba1f68a44bd51 /sys/boot/common/interp.c
parent436333e172727c23d47b79a4e1e45dbc916b5dec (diff)
downloadFreeBSD-src-387d0e8c2b336bf34a8b434f0f090fd31e4e3d7f.zip
FreeBSD-src-387d0e8c2b336bf34a8b434f0f090fd31e4e3d7f.tar.gz
- VERBOSE_LS is obsolete, as the heap is much better behaved now.
- Don't whine about nodes we can't stat(); these are usually symlinks that lead out of the filesystem. - Autoboot is now controlled by $autoboot_delay, which is a value in seconds or NO to disable autoboot. - Don't autoboot at the end of boot.conf if we have already tried. - Add a 'read' command to complement 'echo'. Both are still hidden. - Improve the 'source' command/function so that it is possible to source scripts off removable media. The entire script is read and saved before beginning execution. Script lines beginning with '@' will not be echoed when being executed. Script execution will normally terminate at the first error, however if the script line begins with '-' this behaviour is overriden for that command.
Diffstat (limited to 'sys/boot/common/interp.c')
-rw-r--r--sys/boot/common/interp.c131
1 files changed, 100 insertions, 31 deletions
diff --git a/sys/boot/common/interp.c b/sys/boot/common/interp.c
index 69a2fc3..5c4aa51 100644
--- a/sys/boot/common/interp.c
+++ b/sys/boot/common/interp.c
@@ -23,12 +23,12 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: interp.c,v 1.3 1998/09/03 02:10:07 msmith Exp $
+ * $Id: interp.c,v 1.4 1998/09/14 18:27:04 msmith Exp $
*/
/*
* Simple commandline interpreter, toplevel and misc.
*
- * XXX may be obsoleted by BootFORTH
+ * XXX may be obsoleted by BootFORTH or some other, better, interpreter.
*/
#include <stand.h>
@@ -87,11 +87,10 @@ interact(void)
source("/boot/boot.conf");
printf("\n");
/*
- * Before interacting, we might want to autoboot
+ * Before interacting, we might want to autoboot.
*/
- if (getenv("no_autoboot") == NULL)
- autoboot(10, NULL); /* try to boot automatically */
-
+ autoboot_maybe();
+
/*
* Not autobooting, go manual
*/
@@ -114,7 +113,13 @@ interact(void)
}
/*
- * Read command from a file
+ * Read commands from a file, then execute them.
+ *
+ * We store the commands in memory and close the source file so that the media
+ * holding it can safely go away while we are executing.
+ *
+ * Commands may be prefixed with '@' (so they aren't displayed) or '-' (so
+ * that the script won't stop if they fail).
*/
COMMAND_SET(source, "source", "read commands from a file", command_source);
@@ -128,39 +133,103 @@ command_source(int argc, char *argv[])
return(CMD_OK);
}
+struct sourceline
+{
+ char *text;
+ int flags;
+ int line;
+#define SL_QUIET (1<<0)
+#define SL_IGNOREERR (1<<1)
+ struct sourceline *next;
+};
+
void
source(char *filename)
{
- char input[256]; /* big enough? */
- int argc;
- char **argv, *cp;
- int fd;
+ struct sourceline *script, *se, *sp;
+ char input[256]; /* big enough? */
+ int argc;
+ char **argv, *cp;
+ int fd, flags, line;
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);
- }
+ return;
+ }
- if (!parse(&argc, &argv, cp)) {
- if ((argc > 0) &&
- (perform(argc, argv) != 0))
- printf("%s: %s\n", argv[0], command_errmsg);
- free(argv);
+ /*
+ * Read the script into memory.
+ */
+ script = se = NULL;
+ line = 0;
+
+ while (fgetstr(input, sizeof(input), fd) > 0) {
+ line++;
+ flags = 0;
+ /* Discard comments */
+ if (input[0] == '#')
+ continue;
+ cp = input;
+ /* Echo? */
+ if (input[0] == '@') {
+ cp++;
+ flags |= SL_QUIET;
+ }
+ /* Error OK? */
+ if (input[0] == '-') {
+ cp++;
+ flags |= SL_IGNOREERR;
+ }
+ /* Allocate script line structure and copy line, flags */
+ sp = malloc(sizeof(struct sourceline) + strlen(input) + 1);
+ sp->text = (char *)sp + sizeof(struct sourceline);
+ strcpy(sp->text, input);
+ sp->flags = flags;
+ sp->line = line;
+ sp->next = NULL;
+
+ if (script == NULL) {
+ script = sp;
+ } else {
+ se->next = sp;
+ }
+ se = sp;
+ }
+ close(fd);
+
+ /*
+ * Execute the script
+ */
+ argv = NULL;
+ for (sp = script; sp != NULL; sp = sp->next) {
+
+ /* print if not being quiet */
+ if (!(sp->flags & SL_QUIET)) {
+ prompt();
+ printf("%s\n", sp->text);
+ }
+
+ /* Parse the command */
+ if (!parse(&argc, &argv, sp->text)) {
+ if ((argc > 1) && (perform(argc, argv) != 0)) {
+ /* normal command */
+ printf("%s: %s\n", argv[0], command_errmsg);
+ if (!(sp->flags & SL_IGNOREERR))
+ break;
}
+ free(argv);
+ argv = NULL;
+ } else {
+ printf("%s line %d: parse error\n", filename, sp->line);
+ break;
}
- close(fd);
+ }
+ if (argv != NULL)
+ free(argv);
+ while(script != NULL) {
+ se = script;
+ script = script->next;
+ free(se);
}
}
OpenPOWER on IntegriCloud