xref: /netbsd/sys/stand/efiboot/prompt.c (revision 8ec21077)
1*8ec21077Sjmcneill /*	$NetBSD: prompt.c,v 1.6 2020/01/25 10:09:46 jmcneill Exp $	*/
2442fe6a5Sjmcneill 
3442fe6a5Sjmcneill /*
4442fe6a5Sjmcneill  * Copyright (c) 1996, 1997
5442fe6a5Sjmcneill  * 	Matthias Drochner.  All rights reserved.
6442fe6a5Sjmcneill  * Copyright (c) 1996, 1997
7442fe6a5Sjmcneill  * 	Perry E. Metzger.  All rights reserved.
8442fe6a5Sjmcneill  * Copyright (c) 1997
9442fe6a5Sjmcneill  *	Jason R. Thorpe.  All rights reserved
10442fe6a5Sjmcneill  *
11442fe6a5Sjmcneill  * Redistribution and use in source and binary forms, with or without
12442fe6a5Sjmcneill  * modification, are permitted provided that the following conditions
13442fe6a5Sjmcneill  * are met:
14442fe6a5Sjmcneill  * 1. Redistributions of source code must retain the above copyright
15442fe6a5Sjmcneill  *    notice, this list of conditions and the following disclaimer.
16442fe6a5Sjmcneill  * 2. Redistributions in binary form must reproduce the above copyright
17442fe6a5Sjmcneill  *    notice, this list of conditions and the following disclaimer in the
18442fe6a5Sjmcneill  *    documentation and/or other materials provided with the distribution.
19442fe6a5Sjmcneill  * 3. All advertising materials mentioning features or use of this software
20442fe6a5Sjmcneill  *    must display the following acknowledgements:
21442fe6a5Sjmcneill  *	This product includes software developed for the NetBSD Project
22442fe6a5Sjmcneill  *	by Matthias Drochner.
23442fe6a5Sjmcneill  *	This product includes software developed for the NetBSD Project
24442fe6a5Sjmcneill  *	by Perry E. Metzger.
25442fe6a5Sjmcneill  * 4. The names of the authors may not be used to endorse or promote products
26442fe6a5Sjmcneill  *    derived from this software without specific prior written permission.
27442fe6a5Sjmcneill  *
28442fe6a5Sjmcneill  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
29442fe6a5Sjmcneill  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
30442fe6a5Sjmcneill  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
31442fe6a5Sjmcneill  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
32442fe6a5Sjmcneill  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
33442fe6a5Sjmcneill  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34442fe6a5Sjmcneill  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35442fe6a5Sjmcneill  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36442fe6a5Sjmcneill  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
37442fe6a5Sjmcneill  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38442fe6a5Sjmcneill  */
39442fe6a5Sjmcneill 
40442fe6a5Sjmcneill #include "efiboot.h"
41442fe6a5Sjmcneill 
42442fe6a5Sjmcneill #include <lib/libsa/net.h>
4331b16a23Sjakllsch #include <sys/syslimits.h>
44442fe6a5Sjmcneill 
45442fe6a5Sjmcneill #define	POLL_FREQ	10
46442fe6a5Sjmcneill 
47442fe6a5Sjmcneill char *
gettrailer(char * arg)48442fe6a5Sjmcneill gettrailer(char *arg)
49442fe6a5Sjmcneill {
50442fe6a5Sjmcneill 	char *options;
51442fe6a5Sjmcneill 
52442fe6a5Sjmcneill 	for (options = arg; *options; options++) {
53442fe6a5Sjmcneill 		switch (*options) {
54442fe6a5Sjmcneill 		case ' ':
55442fe6a5Sjmcneill 		case '\t':
56442fe6a5Sjmcneill 			*options++ = '\0';
57442fe6a5Sjmcneill 			break;
58442fe6a5Sjmcneill 		default:
59442fe6a5Sjmcneill 			continue;
60442fe6a5Sjmcneill 		}
61442fe6a5Sjmcneill 		break;
62442fe6a5Sjmcneill 	}
63442fe6a5Sjmcneill 	if (*options == '\0')
64442fe6a5Sjmcneill 		return options;
65442fe6a5Sjmcneill 
66442fe6a5Sjmcneill 	/* trim leading blanks/tabs */
67442fe6a5Sjmcneill 	while (*options == ' ' || *options == '\t')
68442fe6a5Sjmcneill 		options++;
69442fe6a5Sjmcneill 
70442fe6a5Sjmcneill 	return options;
71442fe6a5Sjmcneill }
72442fe6a5Sjmcneill 
73442fe6a5Sjmcneill char
awaitkey(int timeout,int tell)74442fe6a5Sjmcneill awaitkey(int timeout, int tell)
75442fe6a5Sjmcneill {
76442fe6a5Sjmcneill 	int i = timeout * POLL_FREQ;
77a7346c2fSjmcneill 	int last_secs = -1, secs;
78*8ec21077Sjmcneill 	int last_len = -1, n;
79*8ec21077Sjmcneill 	char buf[32];
80442fe6a5Sjmcneill 	char c = 0;
81442fe6a5Sjmcneill 
82442fe6a5Sjmcneill 	for (;;) {
83442fe6a5Sjmcneill 		if (tell) {
84442fe6a5Sjmcneill 			int len;
85442fe6a5Sjmcneill 
86a7346c2fSjmcneill 			secs = (i + POLL_FREQ - 1) / POLL_FREQ;
87a7346c2fSjmcneill 			if (secs != last_secs) {
88*8ec21077Sjmcneill 				if (last_len != -1) {
89442fe6a5Sjmcneill 					char *p = buf;
90*8ec21077Sjmcneill 					for (n = 0; n < last_len; n++)
91442fe6a5Sjmcneill 						*p++ = '\b';
92*8ec21077Sjmcneill 					*p = '\0';
93442fe6a5Sjmcneill 					printf("%s", buf);
94442fe6a5Sjmcneill 				}
95*8ec21077Sjmcneill 				len = snprintf(buf, sizeof(buf), "%d seconds. ", (i + POLL_FREQ - 1) / POLL_FREQ);
96*8ec21077Sjmcneill 				if (len > 0 && len < sizeof(buf))
97*8ec21077Sjmcneill 					printf("%s", buf);
98*8ec21077Sjmcneill 				last_len = len;
99a7346c2fSjmcneill 				last_secs = secs;
100a7346c2fSjmcneill 			}
101442fe6a5Sjmcneill 		}
102442fe6a5Sjmcneill 		if (ischar()) {
103442fe6a5Sjmcneill 			c = getchar();
104442fe6a5Sjmcneill 			if (c == 0)
105442fe6a5Sjmcneill 				c = -1;
106442fe6a5Sjmcneill 			goto out;
107442fe6a5Sjmcneill 		}
108442fe6a5Sjmcneill 		if (--i > 0) {
109442fe6a5Sjmcneill 			efi_delay(1000000 / POLL_FREQ);
110442fe6a5Sjmcneill 		} else {
111442fe6a5Sjmcneill 			break;
112442fe6a5Sjmcneill 		}
113442fe6a5Sjmcneill 	}
114442fe6a5Sjmcneill 
115442fe6a5Sjmcneill out:
116*8ec21077Sjmcneill 	if (tell) {
117*8ec21077Sjmcneill 		if (last_len != -1) {
118*8ec21077Sjmcneill 			char *p = buf;
119*8ec21077Sjmcneill 			for (n = 0; n < last_len; n++)
120*8ec21077Sjmcneill 				*p++ = '\b';
121*8ec21077Sjmcneill 			*p = '\0';
122*8ec21077Sjmcneill 			printf("%s", buf);
123*8ec21077Sjmcneill 		}
124442fe6a5Sjmcneill 		printf("0 seconds.     \n");
125*8ec21077Sjmcneill 	}
126442fe6a5Sjmcneill 
127442fe6a5Sjmcneill 	return c;
128442fe6a5Sjmcneill }
129442fe6a5Sjmcneill 
130442fe6a5Sjmcneill void
docommand(char * arg)131442fe6a5Sjmcneill docommand(char *arg)
132442fe6a5Sjmcneill {
133442fe6a5Sjmcneill 	char *options;
134442fe6a5Sjmcneill 	int i;
135442fe6a5Sjmcneill 
136442fe6a5Sjmcneill 	options = gettrailer(arg);
137442fe6a5Sjmcneill 
138442fe6a5Sjmcneill 	for (i = 0; commands[i].c_name != NULL; i++) {
139442fe6a5Sjmcneill 		if (strcmp(arg, commands[i].c_name) == 0) {
140442fe6a5Sjmcneill 			(*commands[i].c_fn)(options);
141442fe6a5Sjmcneill 			return;
142442fe6a5Sjmcneill 		}
143442fe6a5Sjmcneill 	}
144442fe6a5Sjmcneill 
145442fe6a5Sjmcneill 	printf("unknown command\n");
146442fe6a5Sjmcneill 	command_help(NULL);
147442fe6a5Sjmcneill }
148442fe6a5Sjmcneill 
149442fe6a5Sjmcneill __dead void
bootprompt(void)150442fe6a5Sjmcneill bootprompt(void)
151442fe6a5Sjmcneill {
15231b16a23Sjakllsch 	char input[LINE_MAX];
153442fe6a5Sjmcneill 
154442fe6a5Sjmcneill 	for (;;) {
155442fe6a5Sjmcneill 		char *c = input;
156442fe6a5Sjmcneill 
157442fe6a5Sjmcneill 		input[0] = '\0';
158442fe6a5Sjmcneill 		printf("> ");
159442fe6a5Sjmcneill 		kgets(input, sizeof(input));
160442fe6a5Sjmcneill 
161442fe6a5Sjmcneill 		/*
162442fe6a5Sjmcneill 		 * Skip leading whitespace.
163442fe6a5Sjmcneill 		 */
164442fe6a5Sjmcneill 		while (*c == ' ')
165442fe6a5Sjmcneill 			c++;
166442fe6a5Sjmcneill 		if (*c)
167442fe6a5Sjmcneill 			docommand(c);
168442fe6a5Sjmcneill 	}
169442fe6a5Sjmcneill }
170