xref: /netbsd-src/sys/arch/zaurus/stand/zboot/bootmenu.c (revision bf8938557c3419b143f0c430a95bf7d172d67553)
1*bf893855Sdholland /*	$NetBSD: bootmenu.c,v 1.5 2016/06/11 06:58:42 dholland Exp $	*/
2af901e68Snonaka 
3af901e68Snonaka /*-
4af901e68Snonaka  * Copyright (c) 2008 The NetBSD Foundation, Inc.
5af901e68Snonaka  * All rights reserved.
6af901e68Snonaka  *
7af901e68Snonaka  * Redistribution and use in source and binary forms, with or without
8af901e68Snonaka  * modification, are permitted provided that the following conditions
9af901e68Snonaka  * are met:
10af901e68Snonaka  * 1. Redistributions of source code must retain the above copyright
11af901e68Snonaka  *    notice, this list of conditions and the following disclaimer.
12af901e68Snonaka  * 2. Redistributions in binary form must reproduce the above copyright
13af901e68Snonaka  *    notice, this list of conditions and the following disclaimer in the
14af901e68Snonaka  *    documentation and/or other materials provided with the distribution.
15af901e68Snonaka  *
16af901e68Snonaka  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17af901e68Snonaka  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18af901e68Snonaka  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19af901e68Snonaka  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20af901e68Snonaka  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21af901e68Snonaka  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22af901e68Snonaka  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23af901e68Snonaka  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24af901e68Snonaka  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25af901e68Snonaka  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26af901e68Snonaka  * POSSIBILITY OF SUCH DAMAGE.
27af901e68Snonaka  */
28af901e68Snonaka 
29af901e68Snonaka #include <sys/types.h>
30af901e68Snonaka #include <sys/reboot.h>
31af901e68Snonaka #include <sys/bootblock.h>
32af901e68Snonaka 
33af901e68Snonaka #include "boot.h"
34af901e68Snonaka #include "unixdev.h"
35af901e68Snonaka #include "bootmenu.h"
36af901e68Snonaka #include "pathnames.h"
37af901e68Snonaka 
38af901e68Snonaka #define MENUFORMAT_AUTO	  0
39af901e68Snonaka #define MENUFORMAT_NUMBER 1
40af901e68Snonaka #define MENUFORMAT_LETTER 2
41af901e68Snonaka 
42af901e68Snonaka void
parsebootconf(const char * conf)43af901e68Snonaka parsebootconf(const char *conf)
44af901e68Snonaka {
45e9c95bf5Srtr 	perform_bootcfg(conf, &bootcfg_do_noop, 0);
46af901e68Snonaka }
47af901e68Snonaka 
48af901e68Snonaka /*
49af901e68Snonaka  * doboottypemenu will render the menu and parse any user input
50af901e68Snonaka  */
51af901e68Snonaka static int
getchoicefrominput(char * input,int def)52af901e68Snonaka getchoicefrominput(char *input, int def)
53af901e68Snonaka {
54af901e68Snonaka 	int choice = -1;
55af901e68Snonaka 
56af901e68Snonaka 	if (*input == '\0' || *input == '\r' || *input == '\n')
57af901e68Snonaka 		choice = def;
58e9c95bf5Srtr 	else if (*input >= 'A' && *input < bootcfg_info.nummenu + 'A')
59af901e68Snonaka 		choice = (*input) - 'A';
60e9c95bf5Srtr 	else if (*input >= 'a' && *input < bootcfg_info.nummenu + 'a')
61af901e68Snonaka 		choice = (*input) - 'a';
627b2cf765Sisaki 	else if (isdigit(*input)) {
63af901e68Snonaka 		choice = atoi(input) - 1;
64e9c95bf5Srtr 		if (choice < 0 || choice >= bootcfg_info.nummenu)
65af901e68Snonaka 			choice = -1;
66af901e68Snonaka 	}
67af901e68Snonaka 	return choice;
68af901e68Snonaka }
69af901e68Snonaka 
70af901e68Snonaka void
doboottypemenu(void)71af901e68Snonaka doboottypemenu(void)
72af901e68Snonaka {
73af901e68Snonaka 	char input[80], *ic, *oc;
74af901e68Snonaka 	int choice;
75af901e68Snonaka 
76af901e68Snonaka 	printf("\n");
77af901e68Snonaka 	/* Display menu */
78e9c95bf5Srtr 	if (bootcfg_info.menuformat == MENUFORMAT_LETTER) {
79e9c95bf5Srtr 		for (choice = 0; choice < bootcfg_info.nummenu; choice++)
80af901e68Snonaka 			printf("    %c. %s\n", choice + 'A',
81e9c95bf5Srtr 			    bootcfg_info.desc[choice]);
82af901e68Snonaka 	} else {
83af901e68Snonaka 		/* Can't use %2d format string with libsa */
84e9c95bf5Srtr 		for (choice = 0; choice < bootcfg_info.nummenu; choice++)
85af901e68Snonaka 			printf("    %s%d. %s\n",
86af901e68Snonaka 			    (choice < 9) ?  " " : "",
87af901e68Snonaka 			    choice + 1,
88e9c95bf5Srtr 			    bootcfg_info.desc[choice]);
89af901e68Snonaka 	}
90af901e68Snonaka 	choice = -1;
91af901e68Snonaka 	for (;;) {
92af901e68Snonaka 		input[0] = '\0';
93af901e68Snonaka 
94e9c95bf5Srtr 		if (bootcfg_info.timeout < 0) {
95e9c95bf5Srtr 			if (bootcfg_info.menuformat == MENUFORMAT_LETTER)
96af901e68Snonaka 				printf("\nOption: [%c]:",
97e9c95bf5Srtr 				    bootcfg_info.def + 'A');
98af901e68Snonaka 			else
99af901e68Snonaka 				printf("\nOption: [%d]:",
100e9c95bf5Srtr 				    bootcfg_info.def + 1);
101af901e68Snonaka 
102*bf893855Sdholland 			kgets(input, sizeof(input));
103e9c95bf5Srtr 			choice = getchoicefrominput(input, bootcfg_info.def);
104e9c95bf5Srtr 		} else if (bootcfg_info.timeout == 0)
105e9c95bf5Srtr 			choice = bootcfg_info.def;
106af901e68Snonaka 		else  {
107af901e68Snonaka 			printf("\nChoose an option; RETURN for default; "
108af901e68Snonaka 			       "SPACE to stop countdown.\n");
109e9c95bf5Srtr 			if (bootcfg_info.menuformat == MENUFORMAT_LETTER)
110af901e68Snonaka 				printf("Option %c will be chosen in ",
111e9c95bf5Srtr 				    bootcfg_info.def + 'A');
112af901e68Snonaka 			else
113af901e68Snonaka 				printf("Option %d will be chosen in ",
114e9c95bf5Srtr 				    bootcfg_info.def + 1);
115e9c95bf5Srtr 			input[0] = awaitkey(bootcfg_info.timeout, 1);
116af901e68Snonaka 			input[1] = '\0';
117e9c95bf5Srtr 			choice = getchoicefrominput(input, bootcfg_info.def);
118af901e68Snonaka 			/* If invalid key pressed, drop to menu */
119af901e68Snonaka 			if (choice == -1)
120e9c95bf5Srtr 				bootcfg_info.timeout = -1;
121af901e68Snonaka 		}
122af901e68Snonaka 		if (choice < 0)
123af901e68Snonaka 			continue;
124e9c95bf5Srtr 		if (!strcmp(bootcfg_info.command[choice], "prompt")) {
125af901e68Snonaka 			printf("type \"?\" or \"help\" for help.\n");
126af901e68Snonaka 			bootmenu(); /* does not return */
127af901e68Snonaka 		} else {
128e9c95bf5Srtr 			ic = bootcfg_info.command[choice];
129af901e68Snonaka 			/* Split command string at ; into separate commands */
130af901e68Snonaka 			do {
131af901e68Snonaka 				oc = input;
132af901e68Snonaka 				/* Look for ; separator */
133af901e68Snonaka 				for (; *ic && *ic != COMMAND_SEPARATOR; ic++)
134af901e68Snonaka 					*oc++ = *ic;
135af901e68Snonaka 				if (*input == '\0')
136af901e68Snonaka 					continue;
137af901e68Snonaka 				/* Strip out any trailing spaces */
138af901e68Snonaka 				oc--;
139af901e68Snonaka 				for (; *oc == ' ' && oc > input; oc--);
140af901e68Snonaka 				*++oc = '\0';
141af901e68Snonaka 				if (*ic == COMMAND_SEPARATOR)
142af901e68Snonaka 					ic++;
143af901e68Snonaka 				/* Stop silly command strings like ;;; */
144af901e68Snonaka 				if (*input != '\0')
145af901e68Snonaka 					docommand(input);
146af901e68Snonaka 				/* Skip leading spaces */
147af901e68Snonaka 				for (; *ic == ' '; ic++);
148af901e68Snonaka 			} while (*ic);
149af901e68Snonaka 		}
150af901e68Snonaka 	}
151af901e68Snonaka }
152