xref: /netbsd-src/sys/arch/ews4800mips/stand/common/prompt.c (revision aaf4ece63a859a04e37cf3a7229b5fab0157cc06)
1 /*	$NetBSD: prompt.c,v 1.1 2005/12/29 15:20:09 tsutsui Exp $	*/
2 
3 /*-
4  * Copyright (c) 2004 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by UCHIYAMA Yasushi.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *        This product includes software developed by the NetBSD
21  *        Foundation, Inc. and its contributors.
22  * 4. Neither the name of The NetBSD Foundation nor the names of its
23  *    contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  */
38 
39 #include <lib/libsa/stand.h>
40 #include <lib/libkern/libkern.h>
41 
42 #include <machine/param.h>
43 #include <machine/bfs.h>
44 
45 #include "cmd.h"
46 #include "local.h"
47 
48 #define	LOG_SIZE	2048
49 #define	LOG_MASK	(LOG_SIZE - 1)
50 uint8_t __log[LOG_SIZE];
51 int __log_cnt;
52 
53 #define	CMDBUF_HISTORY_MAX	8
54 #define	PROMPT			">> "
55 
56 struct cmd_buf {
57 	char buf[CMDBUF_SIZE];
58 	int cur, min, max;
59 } __cmd_buf[CMDBUF_HISTORY_MAX];
60 
61 struct cmd_buf *__cmd;
62 int __cur_cmd;
63 
64 void prompt_reset(void);
65 void prompt_input(int);
66 extern void __putchar(int);
67 
68 void
69 prompt(void)
70 {
71 	int c;
72 
73 	prompt_reset();
74 	while (/*CONSTCOND*/1)
75 		if ((c = getchar()) != 0)
76 			prompt_input(c);
77 	/* NOTREACHED */
78 }
79 
80 void
81 prompt_input(int c)
82 {
83 	int i;
84 
85 	switch (c) {
86 	case 32 ... 127:
87 		__cmd->buf[__cmd->cur] = c;
88 		__cmd->cur = (__cmd->cur >= CMDBUF_SIZE - 1) ? __cmd->cur :
89 		    __cmd->cur + 1;
90 		if (__cmd->cur >= __cmd->max)
91 			__cmd->max = __cmd->cur;
92 		putchar(c);
93 		break;
94 	case '\r':
95 		putchar('\n');
96 		if (__cmd->max > 0) {
97 			cmd_exec(__cmd->buf);
98 			prompt_reset();
99 		} else {
100 			printf(PROMPT);
101 		}
102 		break;
103 	case '\b':
104 		if (__cmd->cur > 0) {
105 			__cmd->buf[--__cmd->cur] = 0;
106 			putchar(c);
107 		}
108 		break;
109 	case 1:		/* Ctrl a */
110 		__cmd->cur = __cmd->min;
111 		putchar('\r');
112 		printf("%s", PROMPT);
113 		break;
114 	case 5:		/* Ctrl e */
115 		__cmd->cur = __cmd->max;
116 		goto redraw;
117 	case 2:		/* Ctrl b */
118 		if (__cmd->cur == __cmd->min)
119 			return;
120 		__cmd->cur--;
121 		putchar(c);
122 		break;
123 	case 6:		/* Ctrl f */
124 		if (__cmd->cur == __cmd->max)
125 			return;
126 		__cmd->cur++;
127 		putchar(c);
128 		break;
129 	case 4:		/* Ctrl d */
130 		if (__cmd->cur == __cmd->max)
131 			return;
132 		for (i = __cmd->cur; i < __cmd->max; i++)
133 			__cmd->buf[i] = __cmd->buf[i + 1];
134 		__cmd->buf[i] = '\0';
135 		__cmd->max--;
136 		goto redraw;
137 	case 11:	/* Ctrl k */
138 		for (i = __cmd->cur; i < __cmd->max; i++) {
139 			__cmd->buf[i] = 0;
140 			__cmd->max = __cmd->cur;
141 		}
142 		putchar(c);
143 		break;
144 	case 14:	/* Ctrl n */
145 		__cur_cmd = (__cur_cmd + 1) & 0x7;
146 		goto history_redraw;
147 	case 16:	/* Ctrl p */
148 		__cur_cmd = (__cur_cmd - 1) & 0x7;
149 	history_redraw:
150 		__cmd = &__cmd_buf[__cur_cmd];
151 		__cmd->cur = __cmd->max;
152 	case 12:	/* Ctrl l */
153 	redraw:
154 		putchar('\r');
155 		putchar(11);
156 		printf("%s%s", PROMPT, __cmd->buf);
157 		break;
158 	}
159 }
160 
161 void
162 prompt_reset(void)
163 {
164 
165 	__cur_cmd = (__cur_cmd + 1) & 0x7;
166 	__cmd = &__cmd_buf[__cur_cmd];
167 	memset(__cmd, 0, sizeof *__cmd);
168 	printf(PROMPT);
169 }
170 
171 boolean_t
172 prompt_yesno(int interactive)
173 {
174 	int i;
175 
176 	if (!interactive)
177 		return TRUE;
178 	/* block until user input */
179 	while (/*CONSTCOND*/1) {
180 		if ((i = getchar()) == 0)
181 			continue;
182 		if (i == 'N' || i == 'n')
183 			return FALSE;
184 		if (i == 'Y' || i == 'y')
185 			return TRUE;
186 	}
187 }
188 
189 void
190 putchar(int c)
191 {
192 
193 	__putchar(c);
194 
195 	__log[__log_cnt++] = c;
196 	__log_cnt &= LOG_MASK;
197 }
198 
199 int
200 cmd_log_save(int argc, char *argp[], int interactive)
201 {
202 	struct bfs *bfs;
203 
204 	if (bfs_init(&bfs) != 0) {
205 		printf("no BFS partition.\n");
206 		return 1;
207 	}
208 
209 	if (bfs_file_write(bfs, "boot.log", __log, LOG_SIZE) != 0)
210 		printf("BFS write failed.\n");
211 
212 	bfs_fini(bfs);
213 
214 	return 0;
215 }
216