xref: /openbsd-src/sys/stand/boot/vars.c (revision a28daedfc357b214be5c701aa8ba8adb29a7f1c2)
1 /*	$OpenBSD: vars.c,v 1.13 2005/05/24 20:48:35 uwe 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 
39 static int Xaddr(void);
40 static int Xdevice(void);
41 #ifdef DEBUG
42 static int Xdebug(void);
43 #endif
44 static int Ximage(void);
45 static int Xhowto(void);
46 static int Xtty(void);
47 static int Xtimeout(void);
48 int Xset(void);
49 int Xenv(void);
50 
51 const struct cmd_table cmd_set[] = {
52 	{"addr",   CMDT_VAR, Xaddr},
53 	{"howto",  CMDT_VAR, Xhowto},
54 #ifdef DEBUG
55 	{"debug",  CMDT_VAR, Xdebug},
56 #endif
57 	{"device", CMDT_VAR, Xdevice},
58 	{"tty",    CMDT_VAR, Xtty},
59 	{"image",  CMDT_VAR, Ximage},
60 	{"timeout",CMDT_VAR, Xtimeout},
61 	{NULL,0}
62 };
63 
64 #ifdef DEBUG
65 static int
66 Xdebug(void)
67 {
68 	if (cmd.argc != 2)
69 		printf( "o%s\n", debug? "n": "ff" );
70 	else
71 		debug = (cmd.argv[1][0] == '0' ||
72 			 (cmd.argv[1][0] == 'o' && cmd.argv[1][1] == 'f'))?
73 			 0: 1;
74 	return 0;
75 }
76 #endif
77 
78 static int
79 Xtimeout(void)
80 {
81 	if (cmd.argc != 2)
82 		printf( "%d\n", cmd.timeout );
83 	else
84 		cmd.timeout = (int)strtol( cmd.argv[1], (char **)NULL, 0 );
85 	return 0;
86 }
87 
88 /* called only w/ no arguments */
89 int
90 Xset(void)
91 {
92 	const struct cmd_table *ct;
93 
94 	printf("%s\n", prog_ident);
95 	for (ct = cmd_set; ct->cmd_name != NULL; ct++) {
96 		printf("%s\t ", ct->cmd_name);
97 		(*ct->cmd_exec)();
98 	}
99 	return 0;
100 }
101 
102 static int
103 Xdevice(void)
104 {
105 	if (cmd.argc != 2)
106 		printf("%s\n", cmd.bootdev);
107 	else
108 		strlcpy(cmd.bootdev, cmd.argv[1], sizeof(cmd.bootdev));
109 	return 0;
110 }
111 
112 static int
113 Ximage(void)
114 {
115 	if (cmd.argc != 2)
116 		printf("%s\n", cmd.image);
117 	else
118 		strlcpy(cmd.image, cmd.argv[1], sizeof(cmd.image));
119 	return 0;
120 }
121 
122 static int
123 Xaddr(void)
124 {
125 	if (cmd.argc != 2)
126 		printf("%p\n", cmd.addr);
127 	else
128 		cmd.addr = (void *)strtol(cmd.argv[1], NULL, 0);
129 	return 0;
130 }
131 
132 static int
133 Xtty(void)
134 {
135 	dev_t dev;
136 
137 	if (cmd.argc != 2)
138 		printf("%s\n", ttyname(0));
139 	else {
140 		dev = ttydev(cmd.argv[1]);
141 		if (dev == NODEV)
142 			printf("%s not a console device\n", cmd.argv[1]);
143 		else {
144 			printf("switching console to %s\n", cmd.argv[1]);
145 			if (cnset(dev))
146 				printf("%s console not present\n",
147 				    cmd.argv[1]);
148 			else
149 				printf("%s\n", prog_ident);
150 		}
151 	}
152 	return 0;
153 }
154 
155 static int
156 Xhowto(void)
157 {
158 	if (cmd.argc == 1) {
159 		if (cmd.boothowto) {
160 			putchar('-');
161 			if (cmd.boothowto & RB_ASKNAME)
162 				putchar('a');
163 #ifdef notused
164 			if (cmd.boothowto & RB_HALT)
165 				putchar('b');
166 #endif
167 			if (cmd.boothowto & RB_CONFIG)
168 				putchar('c');
169 			if (cmd.boothowto & RB_SINGLE)
170 				putchar('s');
171 			if (cmd.boothowto & RB_KDB)
172 				putchar('d');
173 		}
174 		putchar('\n');
175 	} else
176 		bootparse(1);
177 	return 0;
178 }
179 
180 int
181 bootparse(int i)
182 {
183 	char *cp;
184 	int howto = cmd.boothowto;
185 
186 	for (; i < cmd.argc; i++) {
187 		cp = cmd.argv[i];
188 		if (*cp == '-') {
189 			while (*++cp) {
190 				switch (*cp) {
191 				case 'a':
192 					howto |= RB_ASKNAME;
193 					break;
194 #ifdef notused
195 	/*
196 	 * one day i get the same nice drink i was having
197 	 * and figure out what is it supposed to be used for
198 	 */
199 				case 'b':
200 					howto |= RB_HALT;
201 					break;
202 #endif
203 				case 'c':
204 					howto |= RB_CONFIG;
205 					break;
206 				case 's':
207 					howto |= RB_SINGLE;
208 					break;
209 				case 'd':
210 					howto |= RB_KDB;
211 					break;
212 				default:
213 					printf("howto: bad option: %c\n", *cp);
214 					return 1;
215 				}
216 			}
217 		} else {
218 			printf("boot: illegal argument %s\n", cmd.argv[i]);
219 			return 1;
220 		}
221 	}
222 	cmd.boothowto = howto;
223 	return 0;
224 }
225 
226 /*
227  * maintain environment as a sequence of '\n' separated
228  * variable definitions in the form <name>=[<value>]
229  * terminated by the usual '\0'
230  */
231 char *environ;
232 
233 int
234 Xenv(void)
235 {
236 	if (cmd.argc == 1) {
237 		if (environ)
238 			printf("%s", environ);
239 		else
240 			printf("empty\n");
241 	} else {
242 		char *p, *q;
243 		int l;
244 
245 		for (p = environ; p && *p; p = q) {
246 			l = strlen(cmd.argv[1]);
247 			for (q = p; *q != '='; q++)
248 				;
249 			l = max(l, q - p) + 1;
250 			for (q = p; *q != '\n'; q++)
251 				;
252 			if (*q)
253 				q++;
254 			if (!strncmp(p, cmd.argv[1], l)) {
255 				while((*p++ = *q++))
256 					;
257 				p--;
258 			}
259 		}
260 		if (!p)
261 			p = environ = alloc(4096);
262 		snprintf(p, environ + 4096 - p, "%s=%s\n",
263 		    cmd.argv[1], (cmd.argc==3?cmd.argv[2]:""));
264 	}
265 
266 	return 0;
267 }
268