-/* $OpenBSD: boot.c,v 1.6 1997/04/14 10:48:04 deraadt Exp $ */
+/* $OpenBSD: boot.c,v 1.7 1997/04/21 20:03:30 mickey Exp $ */
/*
* Copyright (c) 1997 Michael Shalayeff
extern const char version[];
int boothowto;
u_int cnvmem, extmem;
+struct cmd_state cmd = {
+ "", "", "/", (void *)0x100000, 50, ""
+};
void
boot(bootdev)
dev_t bootdev;
{
register char *bootfile = kernels[0];
- register struct cmd_state *cmd;
register int i = 0;
#ifdef DEBUG
printf(">> OpenBSD BOOT: %u/%u k [%s]\n", cnvmem, extmem, version);
- /* XXX init cmd here to cut on .data !!! */
- cmd = (struct cmd_state *)alloc(sizeof(*cmd));
- devboot(bootdev, cmd->bootdev);
- cmd->image[0] = '\0';
- cmd->cwd[0] = '/';
- cmd->cwd[1] = '\0';
- cmd->addr = (void *)0x100000;
- cmd->timeout = 50;
-
+ devboot(bootdev, cmd.bootdev);
while (1) {
- strncpy(cmd->image, bootfile, sizeof(cmd->image));
+ strncpy(cmd.image, bootfile, sizeof(cmd.image));
do {
printf("boot> ");
- } while(!getcmd(cmd) && !execmd(cmd));
-
- if (cmd->rc < 0)
- break;
+ } while(!getcmd(&cmd));
- printf("booting %s: ", cmd->path);
- exec(cmd->path, cmd->addr, boothowto);
+ printf("booting %s: ", cmd.path);
+ exec(cmd.path, cmd.addr, boothowto);
if (kernels[++i] == NULL)
bootfile = kernels[i=0];
else
bootfile = kernels[i];
- cmd->timeout += 20;
+ cmd.timeout += 20;
printf(" failed(%d). will try %s\n", errno, bootfile);
}
}
-/* $OpenBSD: cmd.c,v 1.9 1997/04/17 21:47:37 deraadt Exp $ */
+/* $OpenBSD: cmd.c,v 1.10 1997/04/21 20:03:30 mickey Exp $ */
/*
* Copyright (c) 1997 Michael Shalayeff
#define CTRL(c) ((c)&0x1f)
-const struct cmd_table {
+static int Xaddr __P((struct cmd_state *));
+static int Xboot __P((struct cmd_state *));
+static int Xcd __P((struct cmd_state *));
+static int Xcp __P((struct cmd_state *));
+static int Xdevice __P((struct cmd_state *));
+#ifdef DEBUG
+static int Xdebug __P((struct cmd_state *));
+#endif
+static int Xhelp __P((struct cmd_state *));
+static int Ximage __P((struct cmd_state *));
+static int Xls __P((struct cmd_state *));
+static int Xnope __P((struct cmd_state *));
+static int Xreboot __P((struct cmd_state *));
+static int Xregs __P((struct cmd_state *));
+static int Xset __P((struct cmd_state *));
+static int Xhowto __P((struct cmd_state *));
+
+struct cmd_table {
char *cmd_name;
- int cmd_id;
-} cmd_table[] = {
- {"addr", CMD_ADDR},
- {"boot", CMD_BOOT},
- {"cd", CMD_CD},
- {"device", CMD_DEVICE},
+ int (*cmd_exec)(struct cmd_state *);
+ const struct cmd_table *cmd_table;
+};
+
+const struct cmd_table cmd_set[] = {
+ {"addr", Xaddr},
+ {"boothowto", Xhowto},
#ifdef DEBUG
- {"debug", CMD_DEBUG},
+ {"debug", Xdebug},
#endif
- {"help", CMD_HELP},
- {"image", CMD_IMAGE},
- {"ls", CMD_LS},
- {"nope", CMD_NOPE},
- {"reboot", CMD_REBOOT},
- {"regs", CMD_REGS},
- {"set", CMD_SET},
+ {"device", Xdevice},
+ {"image", Ximage},
+ {NULL,0}
+};
+
+const struct cmd_table cmd_table[] = {
+ {"boot", Xboot}, /* XXX must be first */
+ {"cd", Xcd},
+ {"cp", Xcp},
+ {"help", Xhelp},
+ {"ls", Xls},
+ {"nope", Xnope},
+ {"reboot", Xreboot},
+ {"regs", Xregs},
+ {"set", Xset, cmd_set},
{NULL, 0},
};
static void ls __P((char *, register struct stat *));
static int readline __P((register char *, int));
char *nextword __P((register char *));
-int bootparse __P((struct cmd_state *));
-
-char *cmd_buf = NULL;
+static int bootparse __P((struct cmd_state *, int));
+static char *whatcmd
+ __P((register const struct cmd_table **, register char *));
+char cmd_buf[133];
int
getcmd(cmd)
struct cmd_state *cmd;
{
- register const struct cmd_table *ct = cmd_table;
- register char *p, *q;
- int l;
-
- if (cmd_buf == NULL)
- cmd_buf = alloc(133);
+ const struct cmd_table *ct;
+ register char *p;
- cmd->rc = 0;
cmd->argc = 1;
if (!readline(cmd_buf, cmd->timeout)) {
- printf("\n");
- cmd->cmd = CMD_BOOT;
- cmd->argv[0] = cmd_table[CMD_BOOT].cmd_name;
- cmd->argv[1] = NULL;
- cmd->rc = 1;
- return 0;
- }
-
- /* command */
- for (q = cmd_buf; *q && (*q == ' ' || *q == '\t'); q++)
- ;
- p = nextword(q);
+ cmd->cmd = cmd_table;
+ p = NULL;
+ } else {
- for (l = 0; q[l]; l++)
- ;
- while (ct->cmd_name != NULL && strncmp(q, ct->cmd_name, l))
- ct++;
-
- if (ct->cmd_name == NULL) {
- cmd->cmd = CMD_BOOT;
- cmd->argv[0] = cmd_table[CMD_BOOT].cmd_name;
- if (q && *q) {
- if (*q == '-')
- cmd->argv[cmd->argc++] = NULL; /* XXX */
- cmd->argv[cmd->argc++] = q;
+ /* command */
+ for (p = cmd_buf; *p && (*p == ' ' || *p == '\t'); p++)
+ ;
+ ct = cmd_table;
+ cmd->argv[cmd->argc] = p; /* in case it's shortcut boot */
+ p = whatcmd(&ct, p);
+ if (ct == NULL) {
+ cmd->argc++;
+ ct = cmd_table;
+ } else if (ct->cmd_table != NULL && p != NULL) {
+ const struct cmd_table *cs = ct->cmd_table;
+ p = whatcmd(&cs, p);
+ if (cs == NULL) {
+ printf("%s: syntax error\n", ct->cmd_name);
+ return 0;
+ }
+ ct = cs;
}
- } else {
- cmd->cmd = ct->cmd_id;
- cmd->argv[0] = ct->cmd_name;
+ cmd->cmd = ct;
}
+
+ cmd->argv[0] = ct->cmd_name;
while (p && cmd->argc+1 < sizeof(cmd->argv) / sizeof(cmd->argv[0])) {
cmd->argv[cmd->argc++] = p;
p = nextword(p);
}
cmd->argv[cmd->argc] = NULL;
- return bootparse(cmd);
+
+ return (*cmd->cmd->cmd_exec)(cmd);
+}
+
+static char *
+whatcmd(ct, p)
+ register const struct cmd_table **ct;
+ register char *p;
+{
+ register char *q;
+ register int l;
+
+ q = nextword(p);
+
+ for (l = 0; p[l]; l++)
+ ;
+
+ while ((*ct)->cmd_name != NULL && strncmp(p, (*ct)->cmd_name, l))
+ (*ct)++;
+
+ if ((*ct)->cmd_name == NULL)
+ *ct = NULL;
+
+ return q;
}
static int
return p;
}
-int
-execmd(cmd)
+#ifdef DEBUG
+static int
+Xdebug(cmd)
struct cmd_state *cmd;
{
- struct stat sb;
- int fd;
- register char *p, *q;
- register const struct cmd_table *ct;
-
- cmd->rc = 0;
- switch (cmd->cmd) {
-
-#ifdef DEBUG
- case CMD_DEBUG:
- debug = !debug;
- printf("debug is %s\n", debug? "on": "off");
- break;
+ if (cmd->argc !=2)
+ printf("debug=%s\n", (debug? "on": "off"));
+ else
+ debug = (cmd->argv[1][0] == '0' ||
+ (cmd->argv[1][0] == 'o' && cmd->argv[1][1] == 'f'))?
+ 0: 1;
+ return 0;
+}
#endif
- case CMD_HELP:
- printf("commands: ");
- for (ct = cmd_table; ct->cmd_name != NULL; ct++)
- printf(" %s", ct->cmd_name);
- putchar('\n');
- break;
-
- case CMD_DEVICE:
- if (cmd->argc != 2)
- printf("device: device name required\n");
- else {
- strncpy(cmd->bootdev, cmd->argv[1],
- sizeof(cmd->bootdev));
- }
- break;
-
- case CMD_IMAGE:
- if (cmd->argc != 2)
- printf("image: pathname required\n");
- else {
- strncpy(cmd->image, cmd->argv[1],
- sizeof(cmd->image));
- }
- break;
-
- case CMD_ADDR:
- if (cmd->argc != 2)
- printf("addr: address required\n");
- else {
- register u_long a;
-
- p = cmd->argv[1];
- if (p[0] == '0' && p[1] == 'x')
- p += 2;
- for (a = 0; *p != '\0'; p++) {
- a <<= 4;
- a |= (isdigit(*p)? *p - '0':
- 10 + tolower(*p) - 'a') & 0xf;
- }
+static int
+Xhelp(cmd)
+ struct cmd_state *cmd;
+{
+ register const struct cmd_table *ct;
- cmd->addr = (void *)a;
- }
- break;
+ printf("commands: ");
+ for (ct = cmd_table; ct->cmd_name != NULL; ct++)
+ printf(" %s", ct->cmd_name);
+ putchar('\n');
- case CMD_LS:
- {
- if (cmd->argv[1] != NULL)
- strncpy (cmd->path, cmd->argv[1],
- sizeof(cmd->path));
- else
- sprintf(cmd->path, "%s:%s/.",
- cmd->bootdev, cmd->cwd);
+ return 0;
+}
- if (stat(cmd->path, &sb) < 0) {
- printf("stat(%s): %d\n", cmd->path, errno);
- break;
- }
+/* called only w/ no arguments */
+static int
+Xset(cmd)
+ struct cmd_state *cmd;
+{
+ register const struct cmd_table *ct;
- if ((sb.st_mode & S_IFMT) != S_IFDIR)
- ls(cmd->path, &sb);
- else {
- if ((fd = opendir(cmd->path)) < 0) {
- printf ("opendir(%s): %d\n",
- cmd->path, errno);
- break;
- }
+ printf("OpenBSD boot[%s]\n", version);
+ printf("cwd=%s\n", cmd->cwd);
+ for (ct = cmd_set; ct->cmd_name != NULL; ct++)
+ (*ct->cmd_exec)(cmd);
+ return 0;
+}
- /* no strlen in lib !!! */
- for (p = cmd->path; *p; p++);
- *p++ = '/';
- *p = '\0';
+static int
+Xdevice(cmd)
+ struct cmd_state *cmd;
+{
+ if (cmd->argc != 2)
+ printf("device=%s\n", cmd->bootdev);
+ else
+ strncpy(cmd->bootdev, cmd->argv[1], sizeof(cmd->bootdev));
+ return 0;
+}
- while(readdir(fd, p) >= 0) {
+static int
+Ximage(cmd)
+ struct cmd_state *cmd;
+{
+ if (cmd->argc != 2)
+ printf("image=%s\n", cmd->image);
+ else
+ strncpy(cmd->image, cmd->argv[1], sizeof(cmd->image));
+ return 0;
+}
- if (stat(cmd->path, &sb) < 0)
- printf("stat(%s): %d\n",
- cmd->path, errno);
- else
- ls(p, &sb);
- }
+static int
+Xaddr(cmd)
+ struct cmd_state *cmd;
+{
+ register char *p;
- closedir (fd);
- }
+ if (cmd->argc != 2)
+ printf("addr=%p\n", cmd->addr);
+ else {
+ register u_long a;
+
+ p = cmd->argv[1];
+ if (p[0] == '0' && p[1] == 'x')
+ p += 2;
+ for (a = 0; *p != '\0'; p++) {
+ a <<= 4;
+ a |= (isdigit(*p)? *p - '0':
+ 10 + tolower(*p) - 'a') & 0xf;
}
- break;
+ cmd->addr = (void *)a;
+ }
+ return 0;
+}
- case CMD_CD:
- if (cmd->argc == 1) {
- cmd->cwd[0] = '/';
- cmd->cwd[1] = '\0';
- break;
- }
+static int
+Xls(cmd)
+ struct cmd_state *cmd;
+{
+ struct stat sb;
+ register char *p;
+ int fd;
- if (cmd->argv[1][0] == '.' && cmd->argv[1][1] == '\0')
- break;
+ if (cmd->argv[1] != NULL)
+ strncpy (cmd->path, cmd->argv[1], sizeof(cmd->path));
+ else
+ sprintf(cmd->path, "%s:%s/.", cmd->bootdev, cmd->cwd);
- if (cmd->argv[1][0] == '.' && cmd->argv[1][1] == '.'
- && cmd->argv[1][2] == '\0') {
- /* strrchr(cmd->cwd, '/'); */
- for (p = cmd->cwd; *++p;);
- for (p--; *--p != '/';);
- p[1] = '\0';
- break;
- }
+ if (stat(cmd->path, &sb) < 0) {
+ printf("stat(%s): %s\n", cmd->path, strerror(errno));
+ return 0;
+ }
- sprintf(cmd->path, "%s:%s%s",
- cmd->bootdev, cmd->cwd, cmd->argv[1]);
- if (stat(cmd->path, &sb) < 0) {
- printf("stat(%s): %d\n", cmd->argv[1], errno);
- break;
+ if ((sb.st_mode & S_IFMT) != S_IFDIR)
+ ls(cmd->path, &sb);
+ else {
+ if ((fd = opendir(cmd->path)) < 0) {
+ printf ("opendir(%s): %s\n", cmd->path,
+ strerror(errno));
+ return 0;
}
- if (!S_ISDIR(sb.st_mode)) {
- printf("boot: %s: not a dir\n", cmd->argv[1]);
- break;
- }
+ /* no strlen in lib !!! */
+ for (p = cmd->path; *p; p++);
+ *p++ = '/';
+ *p = '\0';
- /* change dir */
- for (p = cmd->cwd; *p; p++);
- for (q = cmd->argv[1]; (*p++ = *q++) != '\0';);
- if (p[-2] != '/') {
- p[-1] = '/';
- p[0] = '\0';
+ while(readdir(fd, p) >= 0) {
+ if (stat(cmd->path, &sb) < 0)
+ printf("stat(%s): %s\n", cmd->path,
+ strerror(errno));
+ else
+ ls(p, &sb);
}
- break;
-
- case CMD_SET:
- printf("OpenBSD/i386 boot version %s(debug is %s)\n"
- "device:\t%s\n"
- "cwd:\t%s\n"
- "image:\t%s\n"
- "load at:\t%p\n"
- "timeout:\t%d\n",
- version,
-#ifdef DEBUG
- (debug? "on": "off"),
-#else
- "not present",
-#endif
- cmd->bootdev, cmd->cwd, cmd->image,
- cmd->addr, cmd->timeout);
- break;
-
- case CMD_REBOOT:
- printf("Rebooting...\n");
- cmd->rc = -1;
- break;
-
- case CMD_REGS:
- DUMP_REGS;
- break;
-
- case CMD_BOOT:
- /* XXX "boot -s" will not work as this is written */
- if (cmd->argc > 1 && cmd->argv[1]) {
- char *p;
-
- for (p = cmd->argv[1]; *p; p++)
- if (*p == ':')
- break;
- if (*p == ':')
- sprintf(cmd->path, "%s", cmd->argv[1]);
- else
- sprintf(cmd->path, "%s:%s", cmd->bootdev,
- cmd->argv[1]);
- } else
- sprintf(cmd->path, "%s:%s%s", cmd->bootdev,
- cmd->cwd, cmd->image);
- cmd->rc = !bootparse(cmd);
- break;
-
- case CMD_ERROR:
- default:
- printf ("%s: invalid command\n", cmd->argv[0]);
- case CMD_NOPE:
- break;
+ closedir (fd);
}
-
- return cmd->rc;
+ return 0;
}
#define lsrwx(mode,s) \
printf (" %u,%u\t%lu\t%s\n", sb->st_uid, sb->st_gid,
(u_long)sb->st_size, name);
}
+#undef lsrwx
-int
-bootparse(cmd)
+static int
+Xhowto(cmd)
struct cmd_state *cmd;
{
- char *cp;
+ if (cmd->argc < 2) {
+ printf("boothowto=");
+ if (boothowto) {
+ putchar('-');
+ if (boothowto & RB_ASKNAME)
+ putchar('a');
+ if (boothowto & RB_HALT)
+ putchar('b');
+ if (boothowto & RB_CONFIG)
+ putchar('c');
+ if (boothowto & RB_SINGLE)
+ putchar('s');
+ if (boothowto & RB_KDB)
+ putchar('d');
+ }
+ putchar('\n');
+ } else
+ bootparse(cmd, 1);
+ return 0;
+}
+
+static int
+Xboot(cmd)
+ struct cmd_state *cmd;
+{
+ if (cmd->argc > 1 && cmd->argv[1][0] != '-') {
+ register char *p;
+
+ for (p = cmd->argv[1]; *p; p++)
+ if (*p == ':')
+ break;
+ if (*p == ':')
+ sprintf(cmd->path, "%s", cmd->argv[1]);
+ else if (cmd->argv[1][0] == '/')
+ sprintf(cmd->path, "%s:%s", cmd->bootdev,
+ cmd->argv[1]);
+ else
+ sprintf(cmd->path, "%s:%s%s", cmd->bootdev,
+ cmd->cwd, cmd->argv[1]);
+
+ if (bootparse(cmd, 2))
+ return 0;
+ } else {
+ if (bootparse(cmd, 1))
+ return 0;
+ sprintf(cmd->path, "%s:%s%s", cmd->bootdev,
+ cmd->cwd, cmd->image);
+ }
+
+ return 1;
+}
+
+static int
+bootparse(cmd, i)
+ struct cmd_state *cmd;
int i;
+{
+ register char *cp;
+ int howto = boothowto;
- for (i = 2; i < cmd->argc; i++) {
+ for (; i < cmd->argc; i++) {
cp = cmd->argv[i];
if (*cp == '-') {
while (*++cp) {
switch (*cp) {
case 'a':
- boothowto |= RB_ASKNAME;
+ howto |= RB_ASKNAME;
break;
case 'b':
- boothowto |= RB_HALT;
+ howto |= RB_HALT;
break;
case 'c':
- boothowto |= RB_CONFIG;
+ howto |= RB_CONFIG;
break;
case 's':
- boothowto |= RB_SINGLE;
+ howto |= RB_SINGLE;
break;
case 'd':
- boothowto |= RB_KDB;
+ howto |= RB_KDB;
break;
+ default:
+ printf("howto: bad option: %c\n", *cp);
+ return 1;
}
}
} else {
return 1;
}
}
+ boothowto = howto;
return 0;
}
+
+static int
+Xcd(cmd)
+ struct cmd_state *cmd;
+{
+ register char *p, *q;
+ struct stat sb;
+
+ /* cd home */
+ if (cmd->argc == 1) {
+ cmd->cwd[0] = '/';
+ cmd->cwd[1] = '\0';
+ return 0;
+ }
+
+ /* cd '.' */
+ if (cmd->argv[1][0] == '.' && cmd->argv[1][1] == '\0')
+ return 0;
+
+ /* cd '..' */
+ if (cmd->argv[1][0] == '.' && cmd->argv[1][1] == '.'
+ && cmd->argv[1][2] == '\0') {
+ /* strrchr(cmd->cwd, '/'); */
+ for (p = cmd->cwd; *++p;);
+ for (p--; *--p != '/';);
+ p[1] = '\0';
+ return 0;
+ }
+
+ /* cd dir */
+ sprintf(cmd->path, "%s:%s%s",
+ cmd->bootdev, cmd->cwd, cmd->argv[1]);
+
+ if (stat(cmd->path, &sb) < 0) {
+ printf("stat(%s): %s\n", cmd->argv[1], strerror(errno));
+ return 0;
+ }
+
+ if (!S_ISDIR(sb.st_mode)) {
+ printf("boot: %s: not a dir\n", cmd->argv[1]);
+ return 0;
+ }
+
+ /* change dir */
+ for (p = cmd->cwd; *p; p++);
+ for (q = cmd->argv[1]; (*p++ = *q++) != '\0';);
+ if (p[-2] != '/') {
+ p[-1] = '/';
+ p[0] = '\0';
+ }
+
+ return 0;
+}
+
+static int
+Xreboot(cmd)
+ struct cmd_state *cmd;
+{
+ printf("Rebooting...\n");
+ exit();
+ return 0; /* just in case */
+}
+
+static int
+Xregs(cmd)
+ struct cmd_state *cmd;
+{
+ DUMP_REGS;
+ return 0;
+}
+
+static int
+Xnope(cmd)
+ struct cmd_state *cmd;
+{
+ return 0;
+}
+
+static int
+Xcp(cmd)
+ struct cmd_state *cmd;
+{
+ printf("cp: no writable filesystems\n");
+ return 0;
+}
+
-/* $OpenBSD: cmd.h,v 1.3 1997/04/01 04:50:33 mickey Exp $ */
+/* $OpenBSD: cmd.h,v 1.4 1997/04/21 20:03:31 mickey Exp $ */
/*
* Copyright (c) 1997 Michael Shalayeff
*
*/
+struct cmd_table;
struct cmd_state {
char bootdev[16]; /* device */
char image[32]; /* image */
int timeout;
char path[MAXPATHLEN]; /* buffer for pathname compose */
- enum { CMD_ADDR, CMD_BOOT, CMD_CD, CMD_DEVICE, CMD_DEBUG, CMD_HELP,
- CMD_IMAGE, CMD_LS, CMD_NOPE, CMD_REBOOT, CMD_SET,
- CMD_REGS,
- CMD_ERROR /* last !!! */
- } cmd;
+ const struct cmd_table *cmd;
int argc;
char *argv[8]; /* XXX i hope this is enough */
- int rc;
};
int getcmd __P((register struct cmd_state *));
-int execmd __P((register struct cmd_state *));
-/* $OpenBSD: boot.c,v 1.6 1997/04/14 10:48:04 deraadt Exp $ */
+/* $OpenBSD: boot.c,v 1.7 1997/04/21 20:03:30 mickey Exp $ */
/*
* Copyright (c) 1997 Michael Shalayeff
extern const char version[];
int boothowto;
u_int cnvmem, extmem;
+struct cmd_state cmd = {
+ "", "", "/", (void *)0x100000, 50, ""
+};
void
boot(bootdev)
dev_t bootdev;
{
register char *bootfile = kernels[0];
- register struct cmd_state *cmd;
register int i = 0;
#ifdef DEBUG
printf(">> OpenBSD BOOT: %u/%u k [%s]\n", cnvmem, extmem, version);
- /* XXX init cmd here to cut on .data !!! */
- cmd = (struct cmd_state *)alloc(sizeof(*cmd));
- devboot(bootdev, cmd->bootdev);
- cmd->image[0] = '\0';
- cmd->cwd[0] = '/';
- cmd->cwd[1] = '\0';
- cmd->addr = (void *)0x100000;
- cmd->timeout = 50;
-
+ devboot(bootdev, cmd.bootdev);
while (1) {
- strncpy(cmd->image, bootfile, sizeof(cmd->image));
+ strncpy(cmd.image, bootfile, sizeof(cmd.image));
do {
printf("boot> ");
- } while(!getcmd(cmd) && !execmd(cmd));
-
- if (cmd->rc < 0)
- break;
+ } while(!getcmd(&cmd));
- printf("booting %s: ", cmd->path);
- exec(cmd->path, cmd->addr, boothowto);
+ printf("booting %s: ", cmd.path);
+ exec(cmd.path, cmd.addr, boothowto);
if (kernels[++i] == NULL)
bootfile = kernels[i=0];
else
bootfile = kernels[i];
- cmd->timeout += 20;
+ cmd.timeout += 20;
printf(" failed(%d). will try %s\n", errno, bootfile);
}
}
-/* $OpenBSD: cmd.c,v 1.9 1997/04/17 21:47:37 deraadt Exp $ */
+/* $OpenBSD: cmd.c,v 1.10 1997/04/21 20:03:30 mickey Exp $ */
/*
* Copyright (c) 1997 Michael Shalayeff
#define CTRL(c) ((c)&0x1f)
-const struct cmd_table {
+static int Xaddr __P((struct cmd_state *));
+static int Xboot __P((struct cmd_state *));
+static int Xcd __P((struct cmd_state *));
+static int Xcp __P((struct cmd_state *));
+static int Xdevice __P((struct cmd_state *));
+#ifdef DEBUG
+static int Xdebug __P((struct cmd_state *));
+#endif
+static int Xhelp __P((struct cmd_state *));
+static int Ximage __P((struct cmd_state *));
+static int Xls __P((struct cmd_state *));
+static int Xnope __P((struct cmd_state *));
+static int Xreboot __P((struct cmd_state *));
+static int Xregs __P((struct cmd_state *));
+static int Xset __P((struct cmd_state *));
+static int Xhowto __P((struct cmd_state *));
+
+struct cmd_table {
char *cmd_name;
- int cmd_id;
-} cmd_table[] = {
- {"addr", CMD_ADDR},
- {"boot", CMD_BOOT},
- {"cd", CMD_CD},
- {"device", CMD_DEVICE},
+ int (*cmd_exec)(struct cmd_state *);
+ const struct cmd_table *cmd_table;
+};
+
+const struct cmd_table cmd_set[] = {
+ {"addr", Xaddr},
+ {"boothowto", Xhowto},
#ifdef DEBUG
- {"debug", CMD_DEBUG},
+ {"debug", Xdebug},
#endif
- {"help", CMD_HELP},
- {"image", CMD_IMAGE},
- {"ls", CMD_LS},
- {"nope", CMD_NOPE},
- {"reboot", CMD_REBOOT},
- {"regs", CMD_REGS},
- {"set", CMD_SET},
+ {"device", Xdevice},
+ {"image", Ximage},
+ {NULL,0}
+};
+
+const struct cmd_table cmd_table[] = {
+ {"boot", Xboot}, /* XXX must be first */
+ {"cd", Xcd},
+ {"cp", Xcp},
+ {"help", Xhelp},
+ {"ls", Xls},
+ {"nope", Xnope},
+ {"reboot", Xreboot},
+ {"regs", Xregs},
+ {"set", Xset, cmd_set},
{NULL, 0},
};
static void ls __P((char *, register struct stat *));
static int readline __P((register char *, int));
char *nextword __P((register char *));
-int bootparse __P((struct cmd_state *));
-
-char *cmd_buf = NULL;
+static int bootparse __P((struct cmd_state *, int));
+static char *whatcmd
+ __P((register const struct cmd_table **, register char *));
+char cmd_buf[133];
int
getcmd(cmd)
struct cmd_state *cmd;
{
- register const struct cmd_table *ct = cmd_table;
- register char *p, *q;
- int l;
-
- if (cmd_buf == NULL)
- cmd_buf = alloc(133);
+ const struct cmd_table *ct;
+ register char *p;
- cmd->rc = 0;
cmd->argc = 1;
if (!readline(cmd_buf, cmd->timeout)) {
- printf("\n");
- cmd->cmd = CMD_BOOT;
- cmd->argv[0] = cmd_table[CMD_BOOT].cmd_name;
- cmd->argv[1] = NULL;
- cmd->rc = 1;
- return 0;
- }
-
- /* command */
- for (q = cmd_buf; *q && (*q == ' ' || *q == '\t'); q++)
- ;
- p = nextword(q);
+ cmd->cmd = cmd_table;
+ p = NULL;
+ } else {
- for (l = 0; q[l]; l++)
- ;
- while (ct->cmd_name != NULL && strncmp(q, ct->cmd_name, l))
- ct++;
-
- if (ct->cmd_name == NULL) {
- cmd->cmd = CMD_BOOT;
- cmd->argv[0] = cmd_table[CMD_BOOT].cmd_name;
- if (q && *q) {
- if (*q == '-')
- cmd->argv[cmd->argc++] = NULL; /* XXX */
- cmd->argv[cmd->argc++] = q;
+ /* command */
+ for (p = cmd_buf; *p && (*p == ' ' || *p == '\t'); p++)
+ ;
+ ct = cmd_table;
+ cmd->argv[cmd->argc] = p; /* in case it's shortcut boot */
+ p = whatcmd(&ct, p);
+ if (ct == NULL) {
+ cmd->argc++;
+ ct = cmd_table;
+ } else if (ct->cmd_table != NULL && p != NULL) {
+ const struct cmd_table *cs = ct->cmd_table;
+ p = whatcmd(&cs, p);
+ if (cs == NULL) {
+ printf("%s: syntax error\n", ct->cmd_name);
+ return 0;
+ }
+ ct = cs;
}
- } else {
- cmd->cmd = ct->cmd_id;
- cmd->argv[0] = ct->cmd_name;
+ cmd->cmd = ct;
}
+
+ cmd->argv[0] = ct->cmd_name;
while (p && cmd->argc+1 < sizeof(cmd->argv) / sizeof(cmd->argv[0])) {
cmd->argv[cmd->argc++] = p;
p = nextword(p);
}
cmd->argv[cmd->argc] = NULL;
- return bootparse(cmd);
+
+ return (*cmd->cmd->cmd_exec)(cmd);
+}
+
+static char *
+whatcmd(ct, p)
+ register const struct cmd_table **ct;
+ register char *p;
+{
+ register char *q;
+ register int l;
+
+ q = nextword(p);
+
+ for (l = 0; p[l]; l++)
+ ;
+
+ while ((*ct)->cmd_name != NULL && strncmp(p, (*ct)->cmd_name, l))
+ (*ct)++;
+
+ if ((*ct)->cmd_name == NULL)
+ *ct = NULL;
+
+ return q;
}
static int
return p;
}
-int
-execmd(cmd)
+#ifdef DEBUG
+static int
+Xdebug(cmd)
struct cmd_state *cmd;
{
- struct stat sb;
- int fd;
- register char *p, *q;
- register const struct cmd_table *ct;
-
- cmd->rc = 0;
- switch (cmd->cmd) {
-
-#ifdef DEBUG
- case CMD_DEBUG:
- debug = !debug;
- printf("debug is %s\n", debug? "on": "off");
- break;
+ if (cmd->argc !=2)
+ printf("debug=%s\n", (debug? "on": "off"));
+ else
+ debug = (cmd->argv[1][0] == '0' ||
+ (cmd->argv[1][0] == 'o' && cmd->argv[1][1] == 'f'))?
+ 0: 1;
+ return 0;
+}
#endif
- case CMD_HELP:
- printf("commands: ");
- for (ct = cmd_table; ct->cmd_name != NULL; ct++)
- printf(" %s", ct->cmd_name);
- putchar('\n');
- break;
-
- case CMD_DEVICE:
- if (cmd->argc != 2)
- printf("device: device name required\n");
- else {
- strncpy(cmd->bootdev, cmd->argv[1],
- sizeof(cmd->bootdev));
- }
- break;
-
- case CMD_IMAGE:
- if (cmd->argc != 2)
- printf("image: pathname required\n");
- else {
- strncpy(cmd->image, cmd->argv[1],
- sizeof(cmd->image));
- }
- break;
-
- case CMD_ADDR:
- if (cmd->argc != 2)
- printf("addr: address required\n");
- else {
- register u_long a;
-
- p = cmd->argv[1];
- if (p[0] == '0' && p[1] == 'x')
- p += 2;
- for (a = 0; *p != '\0'; p++) {
- a <<= 4;
- a |= (isdigit(*p)? *p - '0':
- 10 + tolower(*p) - 'a') & 0xf;
- }
+static int
+Xhelp(cmd)
+ struct cmd_state *cmd;
+{
+ register const struct cmd_table *ct;
- cmd->addr = (void *)a;
- }
- break;
+ printf("commands: ");
+ for (ct = cmd_table; ct->cmd_name != NULL; ct++)
+ printf(" %s", ct->cmd_name);
+ putchar('\n');
- case CMD_LS:
- {
- if (cmd->argv[1] != NULL)
- strncpy (cmd->path, cmd->argv[1],
- sizeof(cmd->path));
- else
- sprintf(cmd->path, "%s:%s/.",
- cmd->bootdev, cmd->cwd);
+ return 0;
+}
- if (stat(cmd->path, &sb) < 0) {
- printf("stat(%s): %d\n", cmd->path, errno);
- break;
- }
+/* called only w/ no arguments */
+static int
+Xset(cmd)
+ struct cmd_state *cmd;
+{
+ register const struct cmd_table *ct;
- if ((sb.st_mode & S_IFMT) != S_IFDIR)
- ls(cmd->path, &sb);
- else {
- if ((fd = opendir(cmd->path)) < 0) {
- printf ("opendir(%s): %d\n",
- cmd->path, errno);
- break;
- }
+ printf("OpenBSD boot[%s]\n", version);
+ printf("cwd=%s\n", cmd->cwd);
+ for (ct = cmd_set; ct->cmd_name != NULL; ct++)
+ (*ct->cmd_exec)(cmd);
+ return 0;
+}
- /* no strlen in lib !!! */
- for (p = cmd->path; *p; p++);
- *p++ = '/';
- *p = '\0';
+static int
+Xdevice(cmd)
+ struct cmd_state *cmd;
+{
+ if (cmd->argc != 2)
+ printf("device=%s\n", cmd->bootdev);
+ else
+ strncpy(cmd->bootdev, cmd->argv[1], sizeof(cmd->bootdev));
+ return 0;
+}
- while(readdir(fd, p) >= 0) {
+static int
+Ximage(cmd)
+ struct cmd_state *cmd;
+{
+ if (cmd->argc != 2)
+ printf("image=%s\n", cmd->image);
+ else
+ strncpy(cmd->image, cmd->argv[1], sizeof(cmd->image));
+ return 0;
+}
- if (stat(cmd->path, &sb) < 0)
- printf("stat(%s): %d\n",
- cmd->path, errno);
- else
- ls(p, &sb);
- }
+static int
+Xaddr(cmd)
+ struct cmd_state *cmd;
+{
+ register char *p;
- closedir (fd);
- }
+ if (cmd->argc != 2)
+ printf("addr=%p\n", cmd->addr);
+ else {
+ register u_long a;
+
+ p = cmd->argv[1];
+ if (p[0] == '0' && p[1] == 'x')
+ p += 2;
+ for (a = 0; *p != '\0'; p++) {
+ a <<= 4;
+ a |= (isdigit(*p)? *p - '0':
+ 10 + tolower(*p) - 'a') & 0xf;
}
- break;
+ cmd->addr = (void *)a;
+ }
+ return 0;
+}
- case CMD_CD:
- if (cmd->argc == 1) {
- cmd->cwd[0] = '/';
- cmd->cwd[1] = '\0';
- break;
- }
+static int
+Xls(cmd)
+ struct cmd_state *cmd;
+{
+ struct stat sb;
+ register char *p;
+ int fd;
- if (cmd->argv[1][0] == '.' && cmd->argv[1][1] == '\0')
- break;
+ if (cmd->argv[1] != NULL)
+ strncpy (cmd->path, cmd->argv[1], sizeof(cmd->path));
+ else
+ sprintf(cmd->path, "%s:%s/.", cmd->bootdev, cmd->cwd);
- if (cmd->argv[1][0] == '.' && cmd->argv[1][1] == '.'
- && cmd->argv[1][2] == '\0') {
- /* strrchr(cmd->cwd, '/'); */
- for (p = cmd->cwd; *++p;);
- for (p--; *--p != '/';);
- p[1] = '\0';
- break;
- }
+ if (stat(cmd->path, &sb) < 0) {
+ printf("stat(%s): %s\n", cmd->path, strerror(errno));
+ return 0;
+ }
- sprintf(cmd->path, "%s:%s%s",
- cmd->bootdev, cmd->cwd, cmd->argv[1]);
- if (stat(cmd->path, &sb) < 0) {
- printf("stat(%s): %d\n", cmd->argv[1], errno);
- break;
+ if ((sb.st_mode & S_IFMT) != S_IFDIR)
+ ls(cmd->path, &sb);
+ else {
+ if ((fd = opendir(cmd->path)) < 0) {
+ printf ("opendir(%s): %s\n", cmd->path,
+ strerror(errno));
+ return 0;
}
- if (!S_ISDIR(sb.st_mode)) {
- printf("boot: %s: not a dir\n", cmd->argv[1]);
- break;
- }
+ /* no strlen in lib !!! */
+ for (p = cmd->path; *p; p++);
+ *p++ = '/';
+ *p = '\0';
- /* change dir */
- for (p = cmd->cwd; *p; p++);
- for (q = cmd->argv[1]; (*p++ = *q++) != '\0';);
- if (p[-2] != '/') {
- p[-1] = '/';
- p[0] = '\0';
+ while(readdir(fd, p) >= 0) {
+ if (stat(cmd->path, &sb) < 0)
+ printf("stat(%s): %s\n", cmd->path,
+ strerror(errno));
+ else
+ ls(p, &sb);
}
- break;
-
- case CMD_SET:
- printf("OpenBSD/i386 boot version %s(debug is %s)\n"
- "device:\t%s\n"
- "cwd:\t%s\n"
- "image:\t%s\n"
- "load at:\t%p\n"
- "timeout:\t%d\n",
- version,
-#ifdef DEBUG
- (debug? "on": "off"),
-#else
- "not present",
-#endif
- cmd->bootdev, cmd->cwd, cmd->image,
- cmd->addr, cmd->timeout);
- break;
-
- case CMD_REBOOT:
- printf("Rebooting...\n");
- cmd->rc = -1;
- break;
-
- case CMD_REGS:
- DUMP_REGS;
- break;
-
- case CMD_BOOT:
- /* XXX "boot -s" will not work as this is written */
- if (cmd->argc > 1 && cmd->argv[1]) {
- char *p;
-
- for (p = cmd->argv[1]; *p; p++)
- if (*p == ':')
- break;
- if (*p == ':')
- sprintf(cmd->path, "%s", cmd->argv[1]);
- else
- sprintf(cmd->path, "%s:%s", cmd->bootdev,
- cmd->argv[1]);
- } else
- sprintf(cmd->path, "%s:%s%s", cmd->bootdev,
- cmd->cwd, cmd->image);
- cmd->rc = !bootparse(cmd);
- break;
-
- case CMD_ERROR:
- default:
- printf ("%s: invalid command\n", cmd->argv[0]);
- case CMD_NOPE:
- break;
+ closedir (fd);
}
-
- return cmd->rc;
+ return 0;
}
#define lsrwx(mode,s) \
printf (" %u,%u\t%lu\t%s\n", sb->st_uid, sb->st_gid,
(u_long)sb->st_size, name);
}
+#undef lsrwx
-int
-bootparse(cmd)
+static int
+Xhowto(cmd)
struct cmd_state *cmd;
{
- char *cp;
+ if (cmd->argc < 2) {
+ printf("boothowto=");
+ if (boothowto) {
+ putchar('-');
+ if (boothowto & RB_ASKNAME)
+ putchar('a');
+ if (boothowto & RB_HALT)
+ putchar('b');
+ if (boothowto & RB_CONFIG)
+ putchar('c');
+ if (boothowto & RB_SINGLE)
+ putchar('s');
+ if (boothowto & RB_KDB)
+ putchar('d');
+ }
+ putchar('\n');
+ } else
+ bootparse(cmd, 1);
+ return 0;
+}
+
+static int
+Xboot(cmd)
+ struct cmd_state *cmd;
+{
+ if (cmd->argc > 1 && cmd->argv[1][0] != '-') {
+ register char *p;
+
+ for (p = cmd->argv[1]; *p; p++)
+ if (*p == ':')
+ break;
+ if (*p == ':')
+ sprintf(cmd->path, "%s", cmd->argv[1]);
+ else if (cmd->argv[1][0] == '/')
+ sprintf(cmd->path, "%s:%s", cmd->bootdev,
+ cmd->argv[1]);
+ else
+ sprintf(cmd->path, "%s:%s%s", cmd->bootdev,
+ cmd->cwd, cmd->argv[1]);
+
+ if (bootparse(cmd, 2))
+ return 0;
+ } else {
+ if (bootparse(cmd, 1))
+ return 0;
+ sprintf(cmd->path, "%s:%s%s", cmd->bootdev,
+ cmd->cwd, cmd->image);
+ }
+
+ return 1;
+}
+
+static int
+bootparse(cmd, i)
+ struct cmd_state *cmd;
int i;
+{
+ register char *cp;
+ int howto = boothowto;
- for (i = 2; i < cmd->argc; i++) {
+ for (; i < cmd->argc; i++) {
cp = cmd->argv[i];
if (*cp == '-') {
while (*++cp) {
switch (*cp) {
case 'a':
- boothowto |= RB_ASKNAME;
+ howto |= RB_ASKNAME;
break;
case 'b':
- boothowto |= RB_HALT;
+ howto |= RB_HALT;
break;
case 'c':
- boothowto |= RB_CONFIG;
+ howto |= RB_CONFIG;
break;
case 's':
- boothowto |= RB_SINGLE;
+ howto |= RB_SINGLE;
break;
case 'd':
- boothowto |= RB_KDB;
+ howto |= RB_KDB;
break;
+ default:
+ printf("howto: bad option: %c\n", *cp);
+ return 1;
}
}
} else {
return 1;
}
}
+ boothowto = howto;
return 0;
}
+
+static int
+Xcd(cmd)
+ struct cmd_state *cmd;
+{
+ register char *p, *q;
+ struct stat sb;
+
+ /* cd home */
+ if (cmd->argc == 1) {
+ cmd->cwd[0] = '/';
+ cmd->cwd[1] = '\0';
+ return 0;
+ }
+
+ /* cd '.' */
+ if (cmd->argv[1][0] == '.' && cmd->argv[1][1] == '\0')
+ return 0;
+
+ /* cd '..' */
+ if (cmd->argv[1][0] == '.' && cmd->argv[1][1] == '.'
+ && cmd->argv[1][2] == '\0') {
+ /* strrchr(cmd->cwd, '/'); */
+ for (p = cmd->cwd; *++p;);
+ for (p--; *--p != '/';);
+ p[1] = '\0';
+ return 0;
+ }
+
+ /* cd dir */
+ sprintf(cmd->path, "%s:%s%s",
+ cmd->bootdev, cmd->cwd, cmd->argv[1]);
+
+ if (stat(cmd->path, &sb) < 0) {
+ printf("stat(%s): %s\n", cmd->argv[1], strerror(errno));
+ return 0;
+ }
+
+ if (!S_ISDIR(sb.st_mode)) {
+ printf("boot: %s: not a dir\n", cmd->argv[1]);
+ return 0;
+ }
+
+ /* change dir */
+ for (p = cmd->cwd; *p; p++);
+ for (q = cmd->argv[1]; (*p++ = *q++) != '\0';);
+ if (p[-2] != '/') {
+ p[-1] = '/';
+ p[0] = '\0';
+ }
+
+ return 0;
+}
+
+static int
+Xreboot(cmd)
+ struct cmd_state *cmd;
+{
+ printf("Rebooting...\n");
+ exit();
+ return 0; /* just in case */
+}
+
+static int
+Xregs(cmd)
+ struct cmd_state *cmd;
+{
+ DUMP_REGS;
+ return 0;
+}
+
+static int
+Xnope(cmd)
+ struct cmd_state *cmd;
+{
+ return 0;
+}
+
+static int
+Xcp(cmd)
+ struct cmd_state *cmd;
+{
+ printf("cp: no writable filesystems\n");
+ return 0;
+}
+
-/* $OpenBSD: cmd.h,v 1.3 1997/04/01 04:50:33 mickey Exp $ */
+/* $OpenBSD: cmd.h,v 1.4 1997/04/21 20:03:31 mickey Exp $ */
/*
* Copyright (c) 1997 Michael Shalayeff
*
*/
+struct cmd_table;
struct cmd_state {
char bootdev[16]; /* device */
char image[32]; /* image */
int timeout;
char path[MAXPATHLEN]; /* buffer for pathname compose */
- enum { CMD_ADDR, CMD_BOOT, CMD_CD, CMD_DEVICE, CMD_DEBUG, CMD_HELP,
- CMD_IMAGE, CMD_LS, CMD_NOPE, CMD_REBOOT, CMD_SET,
- CMD_REGS,
- CMD_ERROR /* last !!! */
- } cmd;
+ const struct cmd_table *cmd;
int argc;
char *argv[8]; /* XXX i hope this is enough */
- int rc;
};
int getcmd __P((register struct cmd_state *));
-int execmd __P((register struct cmd_state *));