diff options
author | msmith <msmith@FreeBSD.org> | 1998-10-07 02:38:26 +0000 |
---|---|---|
committer | msmith <msmith@FreeBSD.org> | 1998-10-07 02:38:26 +0000 |
commit | 387d0e8c2b336bf34a8b434f0f090fd31e4e3d7f (patch) | |
tree | f649378e8cb57ba1e3a2d3e85e6ba1f68a44bd51 /sys/boot/common/interp.c | |
parent | 436333e172727c23d47b79a4e1e45dbc916b5dec (diff) | |
download | FreeBSD-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.c | 131 |
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); } } |