freebsd-nq/sys/i386/boot/netboot/bootmenu.c
Jordan K. Hubbard 9b1096e759 From: wpaul@ctr.columbia.edu (Bill Paul)
Subject: Mea culpa -- small fix for netboot fixes

In accordance with the unavoidable principle sof Murphy's Law, I discovered
that the fixes I recently contributed for the netboot code had some small
flaws in them. Two of them were just typos and had no effect on how the
program functioned. The other one was a missing line from the rootopts and
swapopts functions I created in bootmenu.c, which was supposed to initialize
the NFS sotype flag. It defaults to UDP, and you can change it to TCP with
the rootopts or swapopts commands, but then you can't change it back again.
I originally had a line at the top of each function to reinitialize this
flag, but somehow it got lost in the shuffle, probably because I don't
actually have a need for that flag yet.

Submitted by:	wpaul
1994-11-18 16:29:50 +00:00

356 lines
10 KiB
C

/**************************************************************************
NETBOOT - BOOTP/TFTP Bootstrap Program
Author: Martin Renters
Date: Dec/93
**************************************************************************/
#include "netboot.h"
extern struct nfs_diskless nfsdiskless;
extern int hostnamelen;
extern unsigned long netmask;
int cmd_ip(), cmd_server(), cmd_kernel(), cmd_help(), exit();
int cmd_rootfs(), cmd_swapfs(), cmd_interface(), cmd_hostname();
int cmd_netmask(), cmd_swapsize(), cmd_swapopts(), cmd_rootopts();
#ifdef INCLUDE_3COM
int cmd_aui();
#endif
#ifdef SMALL_ROM
struct bootcmds_t {
char *name;
int (*func)();
} bootcmds[] = {
{"ip", cmd_ip},
{"server", cmd_server},
{"bootfile", cmd_bootfile},
{"diskboot", exit},
{"autoboot", NULL},
#ifdef INCLUDE_3COM
{"trans", cmd_aui},
#endif
{NULL, NULL}
};
#else /* !SMALL ROM */
struct bootcmds_t {
char *name;
int (*func)();
char *help;
} bootcmds[] = {
{"?", cmd_help, " this list"},
{"help", cmd_help, " this list"},
{"ip", cmd_ip, "<addr> set my IP addr"},
{"server", cmd_server, "<addr> set TFTP server IP addr"},
{"netmask", cmd_netmask, "<addr> set network mask"},
{"hostname", cmd_hostname, "<name> set hostname"},
{"kernel", cmd_kernel, "<file> set boot filename"},
{"rootfs", cmd_rootfs, "ip:/fs set root filesystem"},
{"swapfs", cmd_swapfs, "ip:/fs set swap filesystem"},
{"swapsize", cmd_swapsize, "<nblks> set swap size"},
{"swapopts", cmd_swapopts, "<options> swap mount options"},
{"rootopts", cmd_rootopts, "<options> root mount options"},
{"diskboot", exit, " boot from disk"},
{"autoboot", NULL, " continue"},
#ifdef INCLUDE_3COM
{"trans", cmd_aui, "<on|off> turn transceiver on|off"},
#endif
{NULL, NULL, NULL}
};
/**************************************************************************
CMD_HELP - Display help screen - NOT FOR SMALL ROMS
**************************************************************************/
cmd_help()
{
struct bootcmds_t *cmd = bootcmds;
printf("\r\n");
while (cmd->name) {
printf("%s %s\n\r",cmd->name,cmd->help);
cmd++;
}
}
#endif /* SMALL ROM */
/**************************************************************************
CMD_IP - Set my IP address
**************************************************************************/
cmd_ip(p)
char *p;
{
int i;
if (!setip(p, &arptable[ARP_CLIENT].ipaddr)) {
printf("IP address is %I\r\n",
arptable[ARP_CLIENT].ipaddr);
} else default_netmask();
}
#ifdef INCLUDE_3COM
extern short aui;
extern eth_reset();
/**************************************************************************
CMD_AUI - Turn on-board transceiver on or off
**************************************************************************/
cmd_aui(p)
char *p;
{
if (*(p+1) == 'f') {
aui = 1;
eth_reset();
return(0);
}
if (*(p+1) == 'n') {
aui = 0;
eth_reset();
return(0);
}
printf ("Transceiver is %s\r\n",aui ? "off" : "on");
}
#endif
/**************************************************************************
CMD_SERVER - Set server's IP address
**************************************************************************/
cmd_server(p)
char *p;
{
int i;
if (!setip(p, &arptable[ARP_SERVER].ipaddr)) {
printf("Server IP address is %I\r\n",
arptable[ARP_SERVER].ipaddr);
} else /* Need to clear arp entry if we change IP address */
for (i=0; i<6; i++) arptable[ARP_SERVER].node[i] = 0;
}
/**************************************************************************
CMD_NETMASK - Set network mask
**************************************************************************/
cmd_netmask(p)
char *p;
{
int i;
if (!setip(p, &netmask)) {
netmask = ntohl(netmask);
printf("netmask is %I\r\n", netmask);
}
netmask = htonl(netmask);
}
/**************************************************************************
CMD_SWAPSIZE - Set number of blocks for swap
**************************************************************************/
cmd_swapsize(p)
char *p;
{
int blks = getdec(&p);
if (blks > 0) nfsdiskless.swap_nblks = blks;
else printf("Swap size is: %d blocks\r\n",nfsdiskless.swap_nblks);
}
extern char kernel_buf[], *kernel;
/**************************************************************************
CMD_KERNEL - set kernel filename
**************************************************************************/
cmd_kernel(p)
char *p;
{
if (*p) sprintf(kernel = kernel_buf,"%s",p);
printf("Bootfile is: %s\r\n", kernel);
}
/**************************************************************************
CMD_ROOTFS - Set root filesystem name
**************************************************************************/
cmd_rootfs(p)
char *p;
{
if (!setip(p, &arptable[ARP_ROOTSERVER].ipaddr)) {
printf("Root filesystem is %I:%s\r\n",
nfsdiskless.root_saddr.sin_addr,
nfsdiskless.root_hostnam);
} else {
bcopy(&arptable[ARP_ROOTSERVER].ipaddr,
&nfsdiskless.root_saddr.sin_addr, 4);
while (*p && (*p != ':')) p++;
if (*p == ':') p++;
sprintf(&nfsdiskless.root_hostnam, "%s", p);
}
}
/**************************************************************************
CMD_SWAPFS - Set swap filesystem name
**************************************************************************/
cmd_swapfs(p)
char *p;
{
if (!setip(p, &arptable[ARP_SWAPSERVER].ipaddr)) {
printf("Swap filesystem is %I:%s\r\n",
nfsdiskless.swap_saddr.sin_addr,
nfsdiskless.swap_hostnam);
} else {
bcopy(&arptable[ARP_SWAPSERVER].ipaddr,
&nfsdiskless.swap_saddr.sin_addr, 4);
while (*p && (*p != ':')) p++;
if (*p == ':') p++;
sprintf(&nfsdiskless.swap_hostnam, "%s", p);
}
}
/**************************************************************************
CMD_HOSTNAME - Set my hostname
**************************************************************************/
cmd_hostname(p)
char *p;
{
if (*p)
hostnamelen = ((sprintf(&nfsdiskless.my_hostnam,"%s",p) -
(char*)&nfsdiskless.my_hostnam) + 3) & ~3;
else printf("Hostname is: %s\r\n",nfsdiskless.my_hostnam);
}
/**************************************************************************
CMD_ROOTOPTS - Set root mount options
**************************************************************************/
cmd_rootopts(p)
char *p;
{
char *tmp;
if (*p) {
nfsdiskless.root_args.flags = NFSMNT_RSIZE | NFSMNT_WSIZE;
nfsdiskless.root_args.sotype = SOCK_DGRAM;
if ((tmp = (char *)substr(p,"rsize=")))
nfsdiskless.root_args.rsize=getdec(&tmp);
if ((tmp = (char *)substr(p,"wsize=")))
nfsdiskless.root_args.wsize=getdec(&tmp);
if ((tmp = (char *)substr(p,"resvport")))
nfsdiskless.root_args.flags |= NFSMNT_RESVPORT;
if ((tmp = (char *)substr(p,"intr")))
nfsdiskless.root_args.flags |= NFSMNT_INT;
if ((tmp = (char *)substr(p,"soft")))
nfsdiskless.root_args.flags |= NFSMNT_SOFT;
if ((tmp = (char *)substr(p, "tcp")))
nfsdiskless.root_args.sotype = SOCK_STREAM;
} else {
printf("Rootfs mount options: rsize=%d,wsize=%d",
nfsdiskless.root_args.rsize,
nfsdiskless.root_args.wsize);
if (nfsdiskless.root_args.flags & NFSMNT_RESVPORT)
printf (",resvport");
if (nfsdiskless.root_args.flags & NFSMNT_SOFT)
printf (",soft");
if (nfsdiskless.root_args.flags & NFSMNT_INT)
printf (",intr");
if (nfsdiskless.root_args.sotype == SOCK_STREAM)
printf (",tcp");
else
printf (",udp");
printf ("\r\n");
}
}
/**************************************************************************
CMD_SWAPOPTS - Set swap mount options
**************************************************************************/
cmd_swapopts(p)
char *p;
{
char *tmp;
if (*p) {
nfsdiskless.swap_args.flags = NFSMNT_RSIZE | NFSMNT_WSIZE;
nfsdiskless.swap_args.sotype = SOCK_DGRAM;
if ((tmp = (char *)substr(p,"rsize=")))
nfsdiskless.swap_args.rsize=getdec(&tmp);
if ((tmp = (char *)substr(p,"wsize=")))
nfsdiskless.swap_args.wsize=getdec(&tmp);
if ((tmp = (char *)substr(p,"resvport")))
nfsdiskless.swap_args.flags |= NFSMNT_RESVPORT;
if ((tmp = (char *)substr(p,"intr")))
nfsdiskless.swap_args.flags |= NFSMNT_INT;
if ((tmp = (char *)substr(p,"soft")))
nfsdiskless.swap_args.flags |= NFSMNT_SOFT;
if ((tmp = (char *)substr(p, "tcp")))
nfsdiskless.swap_args.sotype = SOCK_STREAM;
} else {
printf("Swapfs mount options: rsize=%d,wsize=%d",
nfsdiskless.swap_args.rsize,
nfsdiskless.swap_args.wsize);
if (nfsdiskless.swap_args.flags & NFSMNT_RESVPORT)
printf (",resvport");
if (nfsdiskless.swap_args.flags & NFSMNT_SOFT)
printf (",soft");
if (nfsdiskless.swap_args.flags & NFSMNT_INT)
printf (",intr");
if (nfsdiskless.swap_args.sotype == SOCK_STREAM)
printf (",tcp");
else
printf (",udp");
printf ("\r\n");
}
}
/**************************************************************************
EXECUTE - Decode command
**************************************************************************/
execute(buf)
char *buf;
{
char *p, *q;
struct bootcmds_t *cmd = bootcmds;
if ((!(*buf)) || (*buf == '#')) return(0);
while(cmd->name) {
p = buf;
q = cmd->name;
while (*q && (*(q++) == *(p++))) ;
if ((!(*q)) && ((*p == ' ') || (!(*p)))) {
if (!cmd->func) return(1);
while (*p == ' ') p++;
(cmd->func)(p);
return(0);
} else
cmd++;
}
#ifdef SMALL_ROM
printf("invalid command\n\r");
#else
printf("bad command - type 'help' for list\n\r");
#endif
return(0);
}
/**************************************************************************
BOOTMENU - Present boot options
**************************************************************************/
bootmenu()
{
char cmd[80];
int ptr, c;
printf("\r\n");
while (1) {
ptr = 0;
printf("boot> ");
while (ptr < 80) {
c = getchar();
if (c == '\r')
break;
else if (c == '\b') {
if (ptr > 0) {
ptr--;
printf("\b \b");
}
} else {
cmd[ptr++] = c;
putchar(c);
}
}
cmd[ptr] = 0;
printf("\r\n");
if (execute(cmd)) break;
}
eth_reset();
}