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