summaryrefslogtreecommitdiffstats
path: root/sys/boot/common
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
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')
-rw-r--r--sys/boot/common/boot.c38
-rw-r--r--sys/boot/common/bootstrap.h3
-rw-r--r--sys/boot/common/commands.c63
-rw-r--r--sys/boot/common/interp.c131
-rw-r--r--sys/boot/common/ls.c16
5 files changed, 197 insertions, 54 deletions
diff --git a/sys/boot/common/boot.c b/sys/boot/common/boot.c
index e0ea678..d54201c 100644
--- a/sys/boot/common/boot.c
+++ b/sys/boot/common/boot.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: boot.c,v 1.3 1998/09/28 22:03:01 peter Exp $
+ * $Id: boot.c,v 1.4 1998/10/02 16:22:26 msmith Exp $
*/
/*
@@ -40,6 +40,8 @@ static char *getbootfile(int try);
/* List of kernel names to try (may be overwritten by boot.config) XXX should move from here? */
static char *default_bootfiles = "kernel,kernel.old";
+static int autoboot_tried;
+
/*
* The user wants us to boot.
*/
@@ -119,9 +121,6 @@ command_boot(int argc, char *argv[])
COMMAND_SET(autoboot, "autoboot", "boot automatically after a delay", command_autoboot);
-/*
- * XXX note the 'prompt' argument is not really useful until quoting is implemented
- */
static int
command_autoboot(int argc, char *argv[])
{
@@ -149,15 +148,39 @@ command_autoboot(int argc, char *argv[])
return(CMD_ERROR);
}
+/*
+ * Called before we go interactive. If we think we can autoboot, and
+ * we haven't tried already, try now.
+ */
+void
+autoboot_maybe()
+{
+ char *cp;
+
+ cp = getenv("autoboot_delay");
+ if ((autoboot_tried == 0) && ((cp == NULL) || strcasecmp(cp, "NO")))
+ autoboot(-1, NULL); /* try to boot automatically */
+}
+
int
autoboot(int delay, char *prompt)
{
time_t when, otime, ntime;
int c, yes;
- char *argv[2];
+ char *argv[2], *cp, *ep;
- if (delay == -1)
- delay = 5; /* env var? compile-time define? */
+ autoboot_tried = 1;
+
+ if (delay == -1) {
+ /* try to get a delay from the environment */
+ if ((cp = getenv("autoboot_delay"))) {
+ delay = strtol(cp, &ep, 0);
+ if (cp == ep)
+ delay = -1;
+ }
+ }
+ if (delay == -1) /* all else fails */
+ delay = 10;
otime = time(NULL);
when = otime + delay; /* when to boot */
@@ -183,7 +206,6 @@ autoboot(int delay, char *prompt)
otime = ntime;
}
}
- printf("\n");
if (yes) {
argv[0] = "boot";
argv[1] = NULL;
diff --git a/sys/boot/common/bootstrap.h b/sys/boot/common/bootstrap.h
index 1c4d00f..bf3874b 100644
--- a/sys/boot/common/bootstrap.h
+++ b/sys/boot/common/bootstrap.h
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: bootstrap.h,v 1.9 1998/09/30 19:25:26 peter Exp $
+ * $Id: bootstrap.h,v 1.10 1998/10/02 08:04:56 peter Exp $
*/
#include <sys/types.h>
@@ -62,6 +62,7 @@ extern int parse(int *argc, char ***argv, char *str);
/* boot.c */
extern int autoboot(int delay, char *prompt);
+extern void autoboot_maybe(void);
/* misc.c */
extern char *unargv(int argc, char *argv[]);
diff --git a/sys/boot/common/commands.c b/sys/boot/common/commands.c
index e7b6725..b0d0518 100644
--- a/sys/boot/common/commands.c
+++ b/sys/boot/common/commands.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: commands.c,v 1.2 1998/09/03 02:10:07 msmith Exp $
+ * $Id: commands.c,v 1.3 1998/09/18 02:01:38 msmith Exp $
*/
#include <stand.h>
@@ -43,7 +43,7 @@ command_help(int argc, char *argv[])
char helppath[80]; /* XXX buffer size? */
/* page the help text from our load path */
- sprintf(helppath, "%s/boot.help", getenv("loaddev"));
+ sprintf(helppath, "%s/boot/boot.help", getenv("loaddev"));
printf("%s\n", helppath);
if (pager_file(helppath) == -1)
printf("Verbose help not available, use '?' to list commands\n");
@@ -177,3 +177,62 @@ command_echo(int argc, char *argv[])
return(CMD_OK);
}
+/*
+ * A passable emulation of the sh(1) command of the same name.
+ */
+
+COMMAND_SET(read, "read", NULL, command_read);
+
+static int
+command_read(int argc, char *argv[])
+{
+ char *prompt;
+ int timeout;
+ time_t when;
+ char *cp;
+ char *name;
+ char buf[256]; /* XXX size? */
+ int c;
+
+ timeout = -1;
+ prompt = NULL;
+ optind = 1;
+ while ((c = getopt(argc, argv, "p:t:")) != -1) {
+ switch(c) {
+
+ case 'p':
+ prompt = optarg;
+ break;
+ case 't':
+ timeout = strtol(optarg, &cp, 0);
+ if (cp == optarg) {
+ sprintf(command_errbuf, "bad timeout '%s'", optarg);
+ return(CMD_ERROR);
+ }
+ break;
+ default:
+ return(CMD_OK);
+ }
+ }
+
+ argv += (optind);
+ argc -= (optind);
+ name = (argc > 0) ? argv[0]: NULL;
+
+ if (prompt != NULL)
+ printf(prompt);
+ if (timeout >= 0) {
+ when = time(NULL) + timeout;
+ while (!ischar())
+ if (time(NULL) >= when)
+ return(CMD_OK); /* is timeout an error? */
+ }
+
+ ngets(buf, sizeof(buf));
+
+ printf("read name '%s' value '%s'\n", name, buf);
+
+ if (name != NULL)
+ setenv(name, buf, 1);
+ return(CMD_OK);
+}
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);
}
}
diff --git a/sys/boot/common/ls.c b/sys/boot/common/ls.c
index 1596a3a..2cce8ad 100644
--- a/sys/boot/common/ls.c
+++ b/sys/boot/common/ls.c
@@ -1,5 +1,5 @@
/*
- * $Id: ls.c,v 1.2 1998/09/03 02:10:07 msmith Exp $
+ * $Id: ls.c,v 1.3 1998/09/26 01:29:13 msmith Exp $
* From: $NetBSD: ls.c,v 1.3 1997/06/13 13:48:47 drochner Exp $
*/
@@ -61,7 +61,6 @@ command_ls(int argc, char *argv[])
static char buf[128]; /* must be long enough for full pathname */
char *path;
int result, ch;
-#ifdef VERBOSE_LS
int verbose;
verbose = 0;
@@ -79,7 +78,6 @@ command_ls(int argc, char *argv[])
}
argv += (optind - 1);
argc -= (optind - 1);
-#endif
if (argc < 2) {
path = "/";
@@ -107,11 +105,9 @@ command_ls(int argc, char *argv[])
result = CMD_ERROR;
goto out;
}
-#ifdef VERBOSE_LS
/* fixup path for stat()ing files */
if (!strcmp(path, "/"))
path = "";
-#endif
while ((size = read(fd, dirbuf, DIRBLKSIZ)) == DIRBLKSIZ) {
struct direct *dp, *edp;
@@ -139,18 +135,14 @@ command_ls(int argc, char *argv[])
}
if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, "..")) {
-#ifdef VERBOSE_LS /* too much UFS activity blows the heap out */
if (verbose) {
/* stat the file, if possible */
sb.st_size = 0;
sprintf(buf, "%s/%s", path, dp->d_name);
- /* ignore return */
- if (stat(buf, &sb)) {
- printf("stat(%s) failed: %s\n", buf, strerror(errno));
- sb.st_size = -1;
- }
+ /* ignore return, could be symlink, etc. */
+ if (stat(buf, &sb))
+ sb.st_size = 0;
sprintf(buf, " %c %8d %s\n", typestr[dp->d_type], (int)sb.st_size, dp->d_name);
-#endif
} else
sprintf(buf, " %c %s\n", typestr[dp->d_type], dp->d_name);
if (pager_output(buf))
OpenPOWER on IntegriCloud