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