xref: /netbsd-src/sys/stand/efiboot/prompt.c (revision 82112b6031a9f320c87e325077d16143352ab488)
1*82112b60Sjmcneill /*	$NetBSD: prompt.c,v 1.6 2020/01/25 10:09:46 jmcneill Exp $	*/
236105be2Sjmcneill 
336105be2Sjmcneill /*
436105be2Sjmcneill  * Copyright (c) 1996, 1997
536105be2Sjmcneill  * 	Matthias Drochner.  All rights reserved.
636105be2Sjmcneill  * Copyright (c) 1996, 1997
736105be2Sjmcneill  * 	Perry E. Metzger.  All rights reserved.
836105be2Sjmcneill  * Copyright (c) 1997
936105be2Sjmcneill  *	Jason R. Thorpe.  All rights reserved
1036105be2Sjmcneill  *
1136105be2Sjmcneill  * Redistribution and use in source and binary forms, with or without
1236105be2Sjmcneill  * modification, are permitted provided that the following conditions
1336105be2Sjmcneill  * are met:
1436105be2Sjmcneill  * 1. Redistributions of source code must retain the above copyright
1536105be2Sjmcneill  *    notice, this list of conditions and the following disclaimer.
1636105be2Sjmcneill  * 2. Redistributions in binary form must reproduce the above copyright
1736105be2Sjmcneill  *    notice, this list of conditions and the following disclaimer in the
1836105be2Sjmcneill  *    documentation and/or other materials provided with the distribution.
1936105be2Sjmcneill  * 3. All advertising materials mentioning features or use of this software
2036105be2Sjmcneill  *    must display the following acknowledgements:
2136105be2Sjmcneill  *	This product includes software developed for the NetBSD Project
2236105be2Sjmcneill  *	by Matthias Drochner.
2336105be2Sjmcneill  *	This product includes software developed for the NetBSD Project
2436105be2Sjmcneill  *	by Perry E. Metzger.
2536105be2Sjmcneill  * 4. The names of the authors may not be used to endorse or promote products
2636105be2Sjmcneill  *    derived from this software without specific prior written permission.
2736105be2Sjmcneill  *
2836105be2Sjmcneill  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
2936105be2Sjmcneill  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
3036105be2Sjmcneill  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
3136105be2Sjmcneill  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
3236105be2Sjmcneill  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
3336105be2Sjmcneill  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3436105be2Sjmcneill  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3536105be2Sjmcneill  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3636105be2Sjmcneill  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
3736105be2Sjmcneill  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3836105be2Sjmcneill  */
3936105be2Sjmcneill 
4036105be2Sjmcneill #include "efiboot.h"
4136105be2Sjmcneill 
4236105be2Sjmcneill #include <lib/libsa/net.h>
432bd73405Sjakllsch #include <sys/syslimits.h>
4436105be2Sjmcneill 
4536105be2Sjmcneill #define	POLL_FREQ	10
4636105be2Sjmcneill 
4736105be2Sjmcneill char *
gettrailer(char * arg)4836105be2Sjmcneill gettrailer(char *arg)
4936105be2Sjmcneill {
5036105be2Sjmcneill 	char *options;
5136105be2Sjmcneill 
5236105be2Sjmcneill 	for (options = arg; *options; options++) {
5336105be2Sjmcneill 		switch (*options) {
5436105be2Sjmcneill 		case ' ':
5536105be2Sjmcneill 		case '\t':
5636105be2Sjmcneill 			*options++ = '\0';
5736105be2Sjmcneill 			break;
5836105be2Sjmcneill 		default:
5936105be2Sjmcneill 			continue;
6036105be2Sjmcneill 		}
6136105be2Sjmcneill 		break;
6236105be2Sjmcneill 	}
6336105be2Sjmcneill 	if (*options == '\0')
6436105be2Sjmcneill 		return options;
6536105be2Sjmcneill 
6636105be2Sjmcneill 	/* trim leading blanks/tabs */
6736105be2Sjmcneill 	while (*options == ' ' || *options == '\t')
6836105be2Sjmcneill 		options++;
6936105be2Sjmcneill 
7036105be2Sjmcneill 	return options;
7136105be2Sjmcneill }
7236105be2Sjmcneill 
7336105be2Sjmcneill char
awaitkey(int timeout,int tell)7436105be2Sjmcneill awaitkey(int timeout, int tell)
7536105be2Sjmcneill {
7636105be2Sjmcneill 	int i = timeout * POLL_FREQ;
77be34f078Sjmcneill 	int last_secs = -1, secs;
78*82112b60Sjmcneill 	int last_len = -1, n;
79*82112b60Sjmcneill 	char buf[32];
8036105be2Sjmcneill 	char c = 0;
8136105be2Sjmcneill 
8236105be2Sjmcneill 	for (;;) {
8336105be2Sjmcneill 		if (tell) {
8436105be2Sjmcneill 			int len;
8536105be2Sjmcneill 
86be34f078Sjmcneill 			secs = (i + POLL_FREQ - 1) / POLL_FREQ;
87be34f078Sjmcneill 			if (secs != last_secs) {
88*82112b60Sjmcneill 				if (last_len != -1) {
8936105be2Sjmcneill 					char *p = buf;
90*82112b60Sjmcneill 					for (n = 0; n < last_len; n++)
9136105be2Sjmcneill 						*p++ = '\b';
92*82112b60Sjmcneill 					*p = '\0';
9336105be2Sjmcneill 					printf("%s", buf);
9436105be2Sjmcneill 				}
95*82112b60Sjmcneill 				len = snprintf(buf, sizeof(buf), "%d seconds. ", (i + POLL_FREQ - 1) / POLL_FREQ);
96*82112b60Sjmcneill 				if (len > 0 && len < sizeof(buf))
97*82112b60Sjmcneill 					printf("%s", buf);
98*82112b60Sjmcneill 				last_len = len;
99be34f078Sjmcneill 				last_secs = secs;
100be34f078Sjmcneill 			}
10136105be2Sjmcneill 		}
10236105be2Sjmcneill 		if (ischar()) {
10336105be2Sjmcneill 			c = getchar();
10436105be2Sjmcneill 			if (c == 0)
10536105be2Sjmcneill 				c = -1;
10636105be2Sjmcneill 			goto out;
10736105be2Sjmcneill 		}
10836105be2Sjmcneill 		if (--i > 0) {
10936105be2Sjmcneill 			efi_delay(1000000 / POLL_FREQ);
11036105be2Sjmcneill 		} else {
11136105be2Sjmcneill 			break;
11236105be2Sjmcneill 		}
11336105be2Sjmcneill 	}
11436105be2Sjmcneill 
11536105be2Sjmcneill out:
116*82112b60Sjmcneill 	if (tell) {
117*82112b60Sjmcneill 		if (last_len != -1) {
118*82112b60Sjmcneill 			char *p = buf;
119*82112b60Sjmcneill 			for (n = 0; n < last_len; n++)
120*82112b60Sjmcneill 				*p++ = '\b';
121*82112b60Sjmcneill 			*p = '\0';
122*82112b60Sjmcneill 			printf("%s", buf);
123*82112b60Sjmcneill 		}
12436105be2Sjmcneill 		printf("0 seconds.     \n");
125*82112b60Sjmcneill 	}
12636105be2Sjmcneill 
12736105be2Sjmcneill 	return c;
12836105be2Sjmcneill }
12936105be2Sjmcneill 
13036105be2Sjmcneill void
docommand(char * arg)13136105be2Sjmcneill docommand(char *arg)
13236105be2Sjmcneill {
13336105be2Sjmcneill 	char *options;
13436105be2Sjmcneill 	int i;
13536105be2Sjmcneill 
13636105be2Sjmcneill 	options = gettrailer(arg);
13736105be2Sjmcneill 
13836105be2Sjmcneill 	for (i = 0; commands[i].c_name != NULL; i++) {
13936105be2Sjmcneill 		if (strcmp(arg, commands[i].c_name) == 0) {
14036105be2Sjmcneill 			(*commands[i].c_fn)(options);
14136105be2Sjmcneill 			return;
14236105be2Sjmcneill 		}
14336105be2Sjmcneill 	}
14436105be2Sjmcneill 
14536105be2Sjmcneill 	printf("unknown command\n");
14636105be2Sjmcneill 	command_help(NULL);
14736105be2Sjmcneill }
14836105be2Sjmcneill 
14936105be2Sjmcneill __dead void
bootprompt(void)15036105be2Sjmcneill bootprompt(void)
15136105be2Sjmcneill {
1522bd73405Sjakllsch 	char input[LINE_MAX];
15336105be2Sjmcneill 
15436105be2Sjmcneill 	for (;;) {
15536105be2Sjmcneill 		char *c = input;
15636105be2Sjmcneill 
15736105be2Sjmcneill 		input[0] = '\0';
15836105be2Sjmcneill 		printf("> ");
15936105be2Sjmcneill 		kgets(input, sizeof(input));
16036105be2Sjmcneill 
16136105be2Sjmcneill 		/*
16236105be2Sjmcneill 		 * Skip leading whitespace.
16336105be2Sjmcneill 		 */
16436105be2Sjmcneill 		while (*c == ' ')
16536105be2Sjmcneill 			c++;
16636105be2Sjmcneill 		if (*c)
16736105be2Sjmcneill 			docommand(c);
16836105be2Sjmcneill 	}
16936105be2Sjmcneill }
170