1 /* $NetBSD: prompt.c,v 1.6 2020/01/25 10:09:46 jmcneill Exp $ */ 2 3 /* 4 * Copyright (c) 1996, 1997 5 * Matthias Drochner. All rights reserved. 6 * Copyright (c) 1996, 1997 7 * Perry E. Metzger. All rights reserved. 8 * Copyright (c) 1997 9 * Jason R. Thorpe. All rights reserved 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgements: 21 * This product includes software developed for the NetBSD Project 22 * by Matthias Drochner. 23 * This product includes software developed for the NetBSD Project 24 * by Perry E. Metzger. 25 * 4. The names of the authors may not be used to endorse or promote products 26 * derived from this software without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 29 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 30 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 31 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 32 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 33 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 34 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 35 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 36 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 37 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 */ 39 40 #include "efiboot.h" 41 42 #include <lib/libsa/net.h> 43 #include <sys/syslimits.h> 44 45 #define POLL_FREQ 10 46 47 char * 48 gettrailer(char *arg) 49 { 50 char *options; 51 52 for (options = arg; *options; options++) { 53 switch (*options) { 54 case ' ': 55 case '\t': 56 *options++ = '\0'; 57 break; 58 default: 59 continue; 60 } 61 break; 62 } 63 if (*options == '\0') 64 return options; 65 66 /* trim leading blanks/tabs */ 67 while (*options == ' ' || *options == '\t') 68 options++; 69 70 return options; 71 } 72 73 char 74 awaitkey(int timeout, int tell) 75 { 76 int i = timeout * POLL_FREQ; 77 int last_secs = -1, secs; 78 int last_len = -1, n; 79 char buf[32]; 80 char c = 0; 81 82 for (;;) { 83 if (tell) { 84 int len; 85 86 secs = (i + POLL_FREQ - 1) / POLL_FREQ; 87 if (secs != last_secs) { 88 if (last_len != -1) { 89 char *p = buf; 90 for (n = 0; n < last_len; n++) 91 *p++ = '\b'; 92 *p = '\0'; 93 printf("%s", buf); 94 } 95 len = snprintf(buf, sizeof(buf), "%d seconds. ", (i + POLL_FREQ - 1) / POLL_FREQ); 96 if (len > 0 && len < sizeof(buf)) 97 printf("%s", buf); 98 last_len = len; 99 last_secs = secs; 100 } 101 } 102 if (ischar()) { 103 c = getchar(); 104 if (c == 0) 105 c = -1; 106 goto out; 107 } 108 if (--i > 0) { 109 efi_delay(1000000 / POLL_FREQ); 110 } else { 111 break; 112 } 113 } 114 115 out: 116 if (tell) { 117 if (last_len != -1) { 118 char *p = buf; 119 for (n = 0; n < last_len; n++) 120 *p++ = '\b'; 121 *p = '\0'; 122 printf("%s", buf); 123 } 124 printf("0 seconds. \n"); 125 } 126 127 return c; 128 } 129 130 void 131 docommand(char *arg) 132 { 133 char *options; 134 int i; 135 136 options = gettrailer(arg); 137 138 for (i = 0; commands[i].c_name != NULL; i++) { 139 if (strcmp(arg, commands[i].c_name) == 0) { 140 (*commands[i].c_fn)(options); 141 return; 142 } 143 } 144 145 printf("unknown command\n"); 146 command_help(NULL); 147 } 148 149 __dead void 150 bootprompt(void) 151 { 152 char input[LINE_MAX]; 153 154 for (;;) { 155 char *c = input; 156 157 input[0] = '\0'; 158 printf("> "); 159 kgets(input, sizeof(input)); 160 161 /* 162 * Skip leading whitespace. 163 */ 164 while (*c == ' ') 165 c++; 166 if (*c) 167 docommand(c); 168 } 169 } 170