1 /* $OpenBSD: cmd.c,v 1.13 2004/06/08 20:59:28 mcbride Exp $ */
2
3 /*
4 * Copyright © 2013
5 * Thorsten “mirabilos” Glaser <tg@mirbsd.org>
6 * Copyright (c) 1999-2001 Mats O Jansson. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <sys/param.h>
30 #include <sys/device.h>
31 #include <sys/time.h>
32 #include <ctype.h>
33 #include <stdio.h>
34 #include <limits.h>
35 #include <nlist.h>
36 #include <string.h>
37 #include "misc.h"
38 #define CMD_NOEXTERN
39 #include "cmd.h"
40 #include "ukc.h"
41 #include "exec.h"
42
43 __RCSID("$MirOS: src/usr.sbin/config/cmd.c,v 1.6 2013/10/31 20:07:18 tg Exp $");
44
45 extern int ukc_mod_kernel;
46 static void int_variable_adjust(const cmd_t *, int, const char *);
47
48 /* Our command table */
49 cmd_table_t cmd_table[] = {
50 {"help", Xhelp, "", "Command help list"},
51 {"add", Xadd, "dev", "Add a device"},
52 {"base", Xbase, "8|10|16", "Base on large numbers"},
53 {"change", Xchange, "devno|dev", "Change device"},
54 {"disable",Xdisable, "attr val|devno|dev", "Disable device"},
55 {"enable", Xenable, "attr val|devno|dev", "Enable device"},
56 {"find", Xfind, "devno|dev", "Find device"},
57 {"list", Xlist, "", "List configuration"},
58 {"lines", Xlines, "count", "# of lines per page"},
59 {"show", Xshow, "[attr [val]]", "Show attribute"},
60 {"exit", Xexit, "", "Exit, without saving changes"},
61 {"quit", Xquit, "", "Quit, saving current changes"},
62 {"timezone", Xtimezone, "[mins [dst]]", "Show/change timezone"},
63 {"cachepct", Xbufcachepct, "[number]", "Show/change BUFCACHEPERCENT"},
64 {"nkmempg", Xnkmempg, "[number]", "Show/change NKMEMPAGES"},
65 {"shmseg", Xshmseg, "[number]", "Show/change SHMSEG"},
66 {"shmmaxpgs", Xshmmaxpgs,"[number]", "Show/change SHMMAXPGS"},
67 {"rootdev",Xrootdev, "[maj min]", "Show/change root device"},
68 {NULL, NULL, NULL, NULL}
69 };
70
71 int
Xhelp(cmd_t * cmd)72 Xhelp(cmd_t *cmd)
73 {
74 cmd_table_t *cmd_tablep = cmd->table;
75 int i;
76
77 /* Hmm, print out cmd_table here... */
78 for (i = 0; cmd_tablep[i].cmd != NULL; i++)
79 printf("\t%-12s%-20s%s\n", cmd_tablep[i].cmd,
80 cmd_tablep[i].opt, cmd_tablep[i].help);
81 return (CMD_CONT);
82 }
83
84 int
Xadd(cmd_t * cmd)85 Xadd(cmd_t *cmd)
86 {
87 short unit, state;
88 int a;
89
90 if (strlen(cmd->args) == 0)
91 printf("Dev expected\n");
92 else if (device(cmd->args, &a, &unit, &state) == 0)
93 add(cmd->args, a, unit, state);
94 else
95 printf("Unknown argument\n");
96 return (CMD_CONT);
97 }
98
99 int
Xbase(cmd_t * cmd)100 Xbase(cmd_t *cmd)
101 {
102 int a;
103
104 if (strlen(cmd->args) == 0)
105 printf("8|10|16 expected\n");
106 else if (number(&cmd->args[0], &a) == 0) {
107 if (a == 8 || a == 10 || a == 16) {
108 base = a;
109 } else {
110 printf("8|10|16 expected\n");
111 }
112 } else
113 printf("Unknown argument\n");
114 return (CMD_CONT);
115 }
116
117 int
Xchange(cmd_t * cmd)118 Xchange(cmd_t *cmd)
119 {
120 short unit, state;
121 int a;
122
123 if (strlen(cmd->args) == 0)
124 printf("DevNo or Dev expected\n");
125 else if (number(cmd->args, &a) == 0)
126 change(a);
127 else if (device(cmd->args, &a, &unit, &state) == 0)
128 common_dev(cmd->args, a, unit, state, UC_CHANGE);
129 else
130 printf("Unknown argument\n");
131 return (CMD_CONT);
132 }
133
134 int
Xdisable(cmd_t * cmd)135 Xdisable(cmd_t *cmd)
136 {
137 short unit, state;
138 int a;
139
140 if (strlen(cmd->args) == 0)
141 printf("Attr, DevNo or Dev expected\n");
142 else if (attr(cmd->args, &a) == 0)
143 common_attr(cmd->args, a, UC_DISABLE);
144 else if (number(cmd->args, &a) == 0)
145 disable(a);
146 else if (device(cmd->args, &a, &unit, &state) == 0)
147 common_dev(cmd->args, a, unit, state, UC_DISABLE);
148 else
149 printf("Unknown argument\n");
150 return (CMD_CONT);
151 }
152
153 int
Xenable(cmd_t * cmd)154 Xenable(cmd_t *cmd)
155 {
156 short unit, state;
157 int a;
158
159 if (strlen(cmd->args) == 0)
160 printf("Attr, DevNo or Dev expected\n");
161 else if (attr(cmd->args, &a) == 0)
162 common_attr(cmd->args, a, UC_DISABLE);
163 else if (number(cmd->args, &a) == 0)
164 enable(a);
165 else if (device(cmd->args, &a, &unit, &state) == 0)
166 common_dev(cmd->args, a, unit, state, UC_ENABLE);
167 else
168 printf("Unknown argument\n");
169 return (CMD_CONT);
170 }
171
172 int
Xfind(cmd_t * cmd)173 Xfind(cmd_t *cmd)
174 {
175 short unit, state;
176 int a;
177
178 if (strlen(cmd->args) == 0)
179 printf("DevNo or Dev expected\n");
180 else if (number(cmd->args, &a) == 0)
181 pdev(a);
182 else if (device(cmd->args, &a, &unit, &state) == 0)
183 common_dev(cmd->args, a, unit, state, UC_FIND);
184 else
185 printf("Unknown argument\n");
186 return (CMD_CONT);
187 }
188
189 int
Xlines(cmd_t * cmd)190 Xlines(cmd_t *cmd)
191 {
192 int a;
193
194 if (strlen(cmd->args) == 0)
195 printf("Argument expected\n");
196 else if (number(cmd->args, &a) == 0)
197 lines = a;
198 else
199 printf("Unknown argument\n");
200 return (CMD_CONT);
201 }
202
203 int
Xlist(cmd_t * cmd)204 Xlist(cmd_t *cmd __attribute__((__unused__)))
205 {
206 struct cfdata *cd;
207 int i = 0;
208
209 cnt = 0;
210 cd = get_cfdata(0);
211
212 while (cd->cf_attach != 0) {
213 if (more())
214 break;
215 pdev(i++);
216 cd++;
217 }
218
219 if (nopdev == 0) {
220 while (i <= (totdev+maxpseudo)) {
221 if (more())
222 break;
223 pdev(i++);
224 }
225 }
226 cnt = -1;
227 return (CMD_CONT);
228 }
229
230 int
Xshow(cmd_t * cmd)231 Xshow(cmd_t *cmd)
232 {
233 if (strlen(cmd->args) == 0)
234 show();
235 else
236 show_attr(&cmd->args[0]);
237 return (CMD_CONT);
238 }
239
240 int
Xquit(cmd_t * cmd)241 Xquit(cmd_t *cmd __attribute__((__unused__)))
242 {
243 /* Nothing to do here */
244 return (CMD_SAVE);
245 }
246
247 int
Xexit(cmd_t * cmd)248 Xexit(cmd_t *cmd __attribute__((__unused__)))
249 {
250 /* Nothing to do here */
251 return (CMD_EXIT);
252 }
253
254 int
Xtimezone(cmd_t * cmd)255 Xtimezone(cmd_t *cmd)
256 {
257 struct timezone *tz;
258 int num;
259 char *c;
260
261 ukc_mod_kernel = 1;
262 tz = (struct timezone *)adjust((caddr_t)(nl[TZ_TZ].n_value));
263
264 if (strlen(cmd->args) == 0) {
265 printf("timezone = %d, dst = %d\n",
266 tz->tz_minuteswest, tz->tz_dsttime);
267 } else {
268 if (number(cmd->args, &num) == 0) {
269 tz->tz_minuteswest = num;
270 c = cmd->args;
271 while ((*c != '\0') && !isspace(*c))
272 c++;
273 while ((*c != '\0') && isspace(*c))
274 c++;
275 if (strlen(c) != 0 && number(c, &num) == 0)
276 tz->tz_dsttime = num;
277 printf("timezone = %d, dst = %d\n",
278 tz->tz_minuteswest, tz->tz_dsttime);
279 } else
280 printf("Unknown argument\n");
281 }
282 return (CMD_CONT);
283 }
284
285 void
int_variable_adjust(const cmd_t * cmd,int idx,const char * name)286 int_variable_adjust(const cmd_t *cmd, int idx, const char *name)
287 {
288 int *v, num;
289
290 if (nl[idx].n_type != 0) {
291 ukc_mod_kernel = 1;
292
293 v = (int *)adjust((caddr_t)(nl[idx].n_value));
294
295 if (strlen(cmd->args) == 0) {
296 printf("%s = %d\n", name, *v);
297 } else {
298 if (number(cmd->args, &num) == 0) {
299 *v = num;
300 printf("%s = %d\n", name, *v);
301 } else
302 printf("Unknown argument\n");
303 }
304 } else
305 printf("This kernel does not support modification of %s.\n",
306 name);
307 }
308
309 int
Xbufcachepct(cmd_t * cmd)310 Xbufcachepct(cmd_t *cmd)
311 {
312 int_variable_adjust(cmd, I_BUFCACHEPCT, "bufcachepercent");
313 return (CMD_CONT);
314 }
315
316 int
Xnkmempg(cmd_t * cmd)317 Xnkmempg(cmd_t *cmd)
318 {
319 int_variable_adjust(cmd, I_NKMEMPG, "nkmempages");
320 return (CMD_CONT);
321 }
322
323 int
Xshmseg(cmd_t * cmd)324 Xshmseg(cmd_t *cmd)
325 {
326 int_variable_adjust(cmd, I_SHMSEG, "shmseg");
327 return (CMD_CONT);
328 }
329
330 int
Xshmmaxpgs(cmd_t * cmd)331 Xshmmaxpgs(cmd_t *cmd)
332 {
333 int_variable_adjust(cmd, I_SHMMAXPGS, "shmmaxpgs");
334 return (CMD_CONT);
335 }
336
337 int
Xrootdev(cmd_t * cmd)338 Xrootdev(cmd_t *cmd)
339 {
340 int maj, min;
341 dev_t *dt;
342 int *override = NULL;
343
344 ukc_mod_kernel = 1;
345
346 dt = (dev_t *)adjust((caddr_t)(nl[I_ROOTDEV].n_value));
347 if (nl[I_ROOTDEV_OV].n_type != 0)
348 override = (int *)adjust((caddr_t)(nl[I_ROOTDEV_OV].n_value));
349
350 if (strlen(cmd->args) == 0) {
351 if (*dt == NODEV)
352 printf("rootdev = NODEV\n");
353 else
354 printf("rootdev = %d, %d\n", major(*dt), minor(*dt));
355 } else {
356 if (number(cmd->args, &maj) == 0) {
357 char *c = cmd->args;
358 while ((*c != '\0') && !isspace(*c))
359 c++;
360 while ((*c != '\0') && isspace(*c))
361 c++;
362 if (strlen(c) != 0 && number(c, &min) == 0) {
363 *dt = makedev(maj, min);
364 if (*dt == NODEV)
365 printf("rootdev = NODEV\n");
366 else
367 printf("rootdev = %d, %d\n",
368 major(*dt), minor(*dt));
369 if (override)
370 *override = (*dt == NODEV) ? 0 : 1;
371 } else
372 printf("Unknown argument\n");
373 } else if (!strcmp(cmd->args, "NODEV")) {
374 *dt = NODEV;
375 printf("rootdev = NODEV\n");
376 } else
377 printf("Unknown argument\n");
378 }
379 return (CMD_CONT);
380 }
381