xref: /openbsd-src/sys/stand/boot/vars.c (revision 91f110e064cd7c194e59e019b83bb7496c1c84d4)
1 /*	$OpenBSD: vars.c,v 1.14 2009/04/30 01:12:44 dlg Exp $	*/
2 
3 /*
4  * Copyright (c) 1998-2000 Michael Shalayeff
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  *
28  */
29 
30 #include <sys/param.h>
31 #include <libsa.h>
32 #include <sys/reboot.h>
33 #include <lib/libkern/funcs.h>
34 #include "cmd.h"
35 
36 extern char prog_ident[];
37 extern int debug;
38 int db_console = -1;
39 
40 static int Xaddr(void);
41 static int Xdevice(void);
42 #ifdef DEBUG
43 static int Xdebug(void);
44 #endif
45 static int Xdb_console(void);
46 static int Ximage(void);
47 static int Xhowto(void);
48 static int Xtty(void);
49 static int Xtimeout(void);
50 int Xset(void);
51 int Xenv(void);
52 
53 const struct cmd_table cmd_set[] = {
54 	{"addr",   CMDT_VAR, Xaddr},
55 	{"howto",  CMDT_VAR, Xhowto},
56 #ifdef DEBUG
57 	{"debug",  CMDT_VAR, Xdebug},
58 #endif
59 	{"device", CMDT_VAR, Xdevice},
60 	{"tty",    CMDT_VAR, Xtty},
61 	{"image",  CMDT_VAR, Ximage},
62 	{"timeout",CMDT_VAR, Xtimeout},
63 	{"db_console", CMDT_VAR, Xdb_console},
64 	{NULL,0}
65 };
66 
67 #ifdef DEBUG
68 static int
69 Xdebug(void)
70 {
71 	if (cmd.argc != 2)
72 		printf( "o%s\n", debug? "n": "ff" );
73 	else
74 		debug = (cmd.argv[1][0] == '0' ||
75 			 (cmd.argv[1][0] == 'o' && cmd.argv[1][1] == 'f'))?
76 			 0: 1;
77 	return 0;
78 }
79 #endif
80 
81 int
82 Xdb_console(void)
83 {
84 	if (cmd.argc != 2) {
85 		switch (db_console) {
86 		case 0:
87 			printf("off\n");
88 			break;
89 		case 1:
90 			printf("on\n");
91 			break;
92 		default:
93 			printf("unset\n");
94 			break;
95 		}
96 	} else {
97 		if (strcmp(cmd.argv[1], "0") == 0 ||
98 		    strcmp(cmd.argv[1], "off") == 0)
99 			db_console = 0;
100 		else if (strcmp(cmd.argv[1], "1") == 0 ||
101 		    strcmp(cmd.argv[1], "on") == 0)
102 			db_console = 1;
103 	}
104 
105 	return (0);
106 }
107 
108 static int
109 Xtimeout(void)
110 {
111 	if (cmd.argc != 2)
112 		printf( "%d\n", cmd.timeout );
113 	else
114 		cmd.timeout = (int)strtol( cmd.argv[1], (char **)NULL, 0 );
115 	return 0;
116 }
117 
118 /* called only w/ no arguments */
119 int
120 Xset(void)
121 {
122 	const struct cmd_table *ct;
123 
124 	printf("%s\n", prog_ident);
125 	for (ct = cmd_set; ct->cmd_name != NULL; ct++) {
126 		printf("%s\t ", ct->cmd_name);
127 		(*ct->cmd_exec)();
128 	}
129 	return 0;
130 }
131 
132 static int
133 Xdevice(void)
134 {
135 	if (cmd.argc != 2)
136 		printf("%s\n", cmd.bootdev);
137 	else
138 		strlcpy(cmd.bootdev, cmd.argv[1], sizeof(cmd.bootdev));
139 	return 0;
140 }
141 
142 static int
143 Ximage(void)
144 {
145 	if (cmd.argc != 2)
146 		printf("%s\n", cmd.image);
147 	else
148 		strlcpy(cmd.image, cmd.argv[1], sizeof(cmd.image));
149 	return 0;
150 }
151 
152 static int
153 Xaddr(void)
154 {
155 	if (cmd.argc != 2)
156 		printf("%p\n", cmd.addr);
157 	else
158 		cmd.addr = (void *)strtol(cmd.argv[1], NULL, 0);
159 	return 0;
160 }
161 
162 static int
163 Xtty(void)
164 {
165 	dev_t dev;
166 
167 	if (cmd.argc != 2)
168 		printf("%s\n", ttyname(0));
169 	else {
170 		dev = ttydev(cmd.argv[1]);
171 		if (dev == NODEV)
172 			printf("%s not a console device\n", cmd.argv[1]);
173 		else {
174 			printf("switching console to %s\n", cmd.argv[1]);
175 			if (cnset(dev))
176 				printf("%s console not present\n",
177 				    cmd.argv[1]);
178 			else
179 				printf("%s\n", prog_ident);
180 		}
181 	}
182 	return 0;
183 }
184 
185 static int
186 Xhowto(void)
187 {
188 	if (cmd.argc == 1) {
189 		if (cmd.boothowto) {
190 			putchar('-');
191 			if (cmd.boothowto & RB_ASKNAME)
192 				putchar('a');
193 #ifdef notused
194 			if (cmd.boothowto & RB_HALT)
195 				putchar('b');
196 #endif
197 			if (cmd.boothowto & RB_CONFIG)
198 				putchar('c');
199 			if (cmd.boothowto & RB_SINGLE)
200 				putchar('s');
201 			if (cmd.boothowto & RB_KDB)
202 				putchar('d');
203 		}
204 		putchar('\n');
205 	} else
206 		bootparse(1);
207 	return 0;
208 }
209 
210 int
211 bootparse(int i)
212 {
213 	char *cp;
214 	int howto = cmd.boothowto;
215 
216 	for (; i < cmd.argc; i++) {
217 		cp = cmd.argv[i];
218 		if (*cp == '-') {
219 			while (*++cp) {
220 				switch (*cp) {
221 				case 'a':
222 					howto |= RB_ASKNAME;
223 					break;
224 #ifdef notused
225 	/*
226 	 * one day i get the same nice drink i was having
227 	 * and figure out what is it supposed to be used for
228 	 */
229 				case 'b':
230 					howto |= RB_HALT;
231 					break;
232 #endif
233 				case 'c':
234 					howto |= RB_CONFIG;
235 					break;
236 				case 's':
237 					howto |= RB_SINGLE;
238 					break;
239 				case 'd':
240 					howto |= RB_KDB;
241 					break;
242 				default:
243 					printf("howto: bad option: %c\n", *cp);
244 					return 1;
245 				}
246 			}
247 		} else {
248 			printf("boot: illegal argument %s\n", cmd.argv[i]);
249 			return 1;
250 		}
251 	}
252 	cmd.boothowto = howto;
253 	return 0;
254 }
255 
256 /*
257  * maintain environment as a sequence of '\n' separated
258  * variable definitions in the form <name>=[<value>]
259  * terminated by the usual '\0'
260  */
261 char *environ;
262 
263 int
264 Xenv(void)
265 {
266 	if (cmd.argc == 1) {
267 		if (environ)
268 			printf("%s", environ);
269 		else
270 			printf("empty\n");
271 	} else {
272 		char *p, *q;
273 		int l;
274 
275 		for (p = environ; p && *p; p = q) {
276 			l = strlen(cmd.argv[1]);
277 			for (q = p; *q != '='; q++)
278 				;
279 			l = max(l, q - p) + 1;
280 			for (q = p; *q != '\n'; q++)
281 				;
282 			if (*q)
283 				q++;
284 			if (!strncmp(p, cmd.argv[1], l)) {
285 				while((*p++ = *q++))
286 					;
287 				p--;
288 			}
289 		}
290 		if (!p)
291 			p = environ = alloc(4096);
292 		snprintf(p, environ + 4096 - p, "%s=%s\n",
293 		    cmd.argv[1], (cmd.argc==3?cmd.argv[2]:""));
294 	}
295 
296 	return 0;
297 }
298