1 | /* $NetBSD: subr_userconf.c,v 1.26 2013/12/23 15:34:16 skrll Exp $ */ |
2 | |
3 | /* |
4 | * Copyright (c) 1996 Mats O Jansson <moj@stacken.kth.se> |
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 |
17 | * OR 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 AUTHOR BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
21 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
22 | * OR SERVICES; LOSS OF 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 | * OpenBSD: subr_userconf.c,v 1.19 2000/01/08 23:23:37 d Exp |
29 | */ |
30 | |
31 | #include <sys/cdefs.h> |
32 | __KERNEL_RCSID(0, "$NetBSD: subr_userconf.c,v 1.26 2013/12/23 15:34:16 skrll Exp $" ); |
33 | |
34 | #include <sys/param.h> |
35 | #include <sys/systm.h> |
36 | #include <sys/device.h> |
37 | #include <sys/time.h> |
38 | #include <sys/userconf.h> |
39 | |
40 | #include <dev/cons.h> |
41 | |
42 | extern struct cfdata cfdata[]; |
43 | |
44 | static int userconf_base = 16; /* Base for "large" numbers */ |
45 | static int userconf_maxdev = -1; /* # of used device slots */ |
46 | static int userconf_totdev = -1; /* # of device slots */ |
47 | #if 0 |
48 | static int userconf_maxlocnames = -1; /* # of locnames */ |
49 | #endif |
50 | static int userconf_cnt = -1; /* Line counter for ... */ |
51 | static int userconf_lines = 12; /* ... # of lines per page */ |
52 | static int userconf_histlen = 0; |
53 | static int userconf_histcur = 0; |
54 | static char userconf_history[1024]; |
55 | static int userconf_histsz = sizeof(userconf_history); |
56 | static char userconf_argbuf[40]; /* Additional input */ |
57 | static char userconf_cmdbuf[40]; /* Command line */ |
58 | static char userconf_histbuf[40]; |
59 | |
60 | #define UC_CHANGE 'c' |
61 | #define UC_DISABLE 'd' |
62 | #define UC_ENABLE 'e' |
63 | #define UC_FIND 'f' |
64 | #define UC_SHOW 's' |
65 | |
66 | static const char *userconf_cmds[] = { |
67 | "base" , "b" , |
68 | "change" , "c" , |
69 | "disable" , "d" , |
70 | "enable" , "e" , |
71 | "exit" , "q" , |
72 | "find" , "f" , |
73 | "help" , "h" , |
74 | "list" , "l" , |
75 | "lines" , "L" , |
76 | "quit" , "q" , |
77 | "?" , "h" , |
78 | "" , "" , |
79 | }; |
80 | |
81 | void |
82 | userconf_init(void) |
83 | { |
84 | int i; |
85 | struct cfdata *cf; |
86 | |
87 | i = 0; |
88 | for (cf = cfdata; cf->cf_name; cf++) |
89 | i++; |
90 | |
91 | userconf_maxdev = i - 1; |
92 | userconf_totdev = i - 1; |
93 | |
94 | userconf_bootinfo(); |
95 | } |
96 | |
97 | static int |
98 | userconf_more(void) |
99 | { |
100 | int quit = 0; |
101 | char c = '\0'; |
102 | |
103 | if (userconf_cnt != -1) { |
104 | if (userconf_cnt == userconf_lines) { |
105 | printf("-- more --" ); |
106 | c = cngetc(); |
107 | userconf_cnt = 0; |
108 | printf("\r \r" ); |
109 | } |
110 | userconf_cnt++; |
111 | if (c == 'q' || c == 'Q') |
112 | quit = 1; |
113 | } |
114 | return (quit); |
115 | } |
116 | |
117 | static void |
118 | userconf_hist_cmd(char cmd) |
119 | { |
120 | userconf_histcur = userconf_histlen; |
121 | if (userconf_histcur < userconf_histsz) { |
122 | userconf_history[userconf_histcur] = cmd; |
123 | userconf_histcur++; |
124 | } |
125 | } |
126 | |
127 | static void |
128 | userconf_hist_int(int val) |
129 | { |
130 | snprintf(userconf_histbuf, sizeof(userconf_histbuf), " %d" , val); |
131 | if ((userconf_histcur + strlen(userconf_histbuf)) < userconf_histsz) { |
132 | memcpy(&userconf_history[userconf_histcur], |
133 | userconf_histbuf, |
134 | strlen(userconf_histbuf)); |
135 | userconf_histcur = userconf_histcur + strlen(userconf_histbuf); |
136 | } |
137 | } |
138 | |
139 | static void |
140 | userconf_hist_eoc(void) |
141 | { |
142 | if (userconf_histcur < userconf_histsz) { |
143 | userconf_history[userconf_histcur] = '\n'; |
144 | userconf_histcur++; |
145 | userconf_histlen = userconf_histcur; |
146 | } |
147 | } |
148 | |
149 | static void |
150 | userconf_pnum(int val) |
151 | { |
152 | if (val > -2 && val < 16) { |
153 | printf("%d" ,val); |
154 | } else { |
155 | switch (userconf_base) { |
156 | case 8: |
157 | printf("0%o" ,val); |
158 | break; |
159 | case 10: |
160 | printf("%d" ,val); |
161 | break; |
162 | case 16: |
163 | default: |
164 | printf("0x%x" ,val); |
165 | break; |
166 | } |
167 | } |
168 | } |
169 | |
170 | static void |
171 | userconf_pdevnam(short dev) |
172 | { |
173 | struct cfdata *cd; |
174 | |
175 | cd = &cfdata[dev]; |
176 | printf("%s" , cd->cf_name); |
177 | switch (cd->cf_fstate) { |
178 | case FSTATE_NOTFOUND: |
179 | case FSTATE_DNOTFOUND: |
180 | printf("%d" , cd->cf_unit); |
181 | break; |
182 | case FSTATE_FOUND: |
183 | printf("*FOUND*" ); |
184 | break; |
185 | case FSTATE_STAR: |
186 | case FSTATE_DSTAR: |
187 | printf("*" ); |
188 | break; |
189 | default: |
190 | printf("*UNKNOWN*" ); |
191 | break; |
192 | } |
193 | } |
194 | |
195 | static void |
196 | userconf_pdev(short devno) |
197 | { |
198 | struct cfdata *cd; |
199 | const struct cfparent *cfp; |
200 | int *l; |
201 | const struct cfiattrdata *ia; |
202 | const struct cflocdesc *ld; |
203 | int nld, i; |
204 | |
205 | if (devno > userconf_maxdev) { |
206 | printf("Unknown devno (max is %d)\n" , userconf_maxdev); |
207 | return; |
208 | } |
209 | |
210 | cd = &cfdata[devno]; |
211 | |
212 | printf("[%3d] " , devno); |
213 | userconf_pdevnam(devno); |
214 | printf(" at" ); |
215 | cfp = cd->cf_pspec; |
216 | if (cfp == NULL) |
217 | printf(" root" ); |
218 | else if (cfp->cfp_parent != NULL && cfp->cfp_unit != -1) |
219 | printf(" %s%d" , cfp->cfp_parent, cfp->cfp_unit); |
220 | else |
221 | printf(" %s?" , cfp->cfp_parent != NULL ? cfp->cfp_parent |
222 | : cfp->cfp_iattr); |
223 | switch (cd->cf_fstate) { |
224 | case FSTATE_NOTFOUND: |
225 | case FSTATE_FOUND: |
226 | case FSTATE_STAR: |
227 | break; |
228 | case FSTATE_DNOTFOUND: |
229 | case FSTATE_DSTAR: |
230 | printf(" disable" ); |
231 | break; |
232 | default: |
233 | printf(" ???" ); |
234 | break; |
235 | } |
236 | if (cfp) { |
237 | l = cd->cf_loc; |
238 | ia = cfiattr_lookup(cfp->cfp_iattr, 0); |
239 | KASSERT(ia); |
240 | ld = ia->ci_locdesc; |
241 | nld = ia->ci_loclen; |
242 | for (i = 0; i < nld; i++) { |
243 | printf(" %s " , ld[i].cld_name); |
244 | if (!ld[i].cld_defaultstr |
245 | || (l[i] != ld[i].cld_default)) |
246 | userconf_pnum(l[i]); |
247 | else |
248 | printf("?" ); |
249 | } |
250 | } |
251 | printf("\n" ); |
252 | } |
253 | |
254 | static int |
255 | userconf_number(char *c, int *val) |
256 | { |
257 | u_int num = 0; |
258 | int neg = 0; |
259 | int base = 10; |
260 | |
261 | if (*c == '-') { |
262 | neg = 1; |
263 | c++; |
264 | } |
265 | if (*c == '0') { |
266 | base = 8; |
267 | c++; |
268 | if (*c == 'x' || *c == 'X') { |
269 | base = 16; |
270 | c++; |
271 | } |
272 | } |
273 | while (*c != '\n' && *c != '\t' && *c != ' ' && *c != '\0') { |
274 | u_char cc = *c; |
275 | |
276 | if (cc >= '0' && cc <= '9') |
277 | cc = cc - '0'; |
278 | else if (cc >= 'a' && cc <= 'f') |
279 | cc = cc - 'a' + 10; |
280 | else if (cc >= 'A' && cc <= 'F') |
281 | cc = cc - 'A' + 10; |
282 | else |
283 | return (-1); |
284 | |
285 | if (cc > base) |
286 | return (-1); |
287 | num = num * base + cc; |
288 | c++; |
289 | } |
290 | |
291 | if (neg && num > INT_MAX) /* overflow */ |
292 | return (1); |
293 | *val = neg ? - num : num; |
294 | return (0); |
295 | } |
296 | |
297 | static int |
298 | userconf_device(char *cmd, int *len, short *unit, short *state) |
299 | { |
300 | short u = 0, s = FSTATE_FOUND; |
301 | int l = 0; |
302 | char *c; |
303 | |
304 | c = cmd; |
305 | while (!(!*c || *c == ' ' || *c == '\t' || *c == '\n')) |
306 | c++; |
307 | while (c > cmd) { |
308 | c--; |
309 | if (!((*c >= '0' && *c <= '9') || *c == '*')) { |
310 | c++; |
311 | break; |
312 | } |
313 | } |
314 | l = c - cmd; |
315 | if (*c == '*') { |
316 | s = FSTATE_STAR; |
317 | c++; |
318 | } else { |
319 | while (*c >= '0' && *c <= '9') { |
320 | s = FSTATE_NOTFOUND; |
321 | u = u*10 + *c - '0'; |
322 | c++; |
323 | } |
324 | } |
325 | while (*c == ' ' || *c == '\t' || *c == '\n') |
326 | c++; |
327 | |
328 | if (*c == '\0') { |
329 | *len = l; |
330 | *unit = u; |
331 | *state = s; |
332 | return(0); |
333 | } |
334 | |
335 | return(-1); |
336 | } |
337 | |
338 | static void |
339 | userconf_modify(const struct cflocdesc *item, int *val) |
340 | { |
341 | int ok = 0; |
342 | int a; |
343 | char *c; |
344 | |
345 | while (!ok) { |
346 | printf("%s [" , item->cld_name); |
347 | if (item->cld_defaultstr && (*val == item->cld_default)) |
348 | printf("?" ); |
349 | else |
350 | userconf_pnum(*val); |
351 | printf("] ? " ); |
352 | |
353 | cngetsn(userconf_argbuf, sizeof(userconf_argbuf)); |
354 | |
355 | c = userconf_argbuf; |
356 | while (*c == ' ' || *c == '\t' || *c == '\n') c++; |
357 | |
358 | if (*c != '\0') { |
359 | if (*c == '?') { |
360 | if (item->cld_defaultstr) { |
361 | *val = item->cld_default; |
362 | ok = 1; |
363 | } else |
364 | printf("No default\n" ); |
365 | } else if (userconf_number(c, &a) == 0) { |
366 | *val = a; |
367 | ok = 1; |
368 | } else { |
369 | printf("Unknown argument\n" ); |
370 | } |
371 | } else { |
372 | ok = 1; |
373 | } |
374 | } |
375 | } |
376 | |
377 | static void |
378 | userconf_change(int devno) |
379 | { |
380 | struct cfdata *cd; |
381 | char c = '\0'; |
382 | int *l; |
383 | int ln; |
384 | const struct cfiattrdata *ia; |
385 | const struct cflocdesc *ld; |
386 | int nld; |
387 | |
388 | if (devno <= userconf_maxdev) { |
389 | |
390 | userconf_pdev(devno); |
391 | |
392 | while (c != 'y' && c != 'Y' && c != 'n' && c != 'N') { |
393 | printf("change (y/n) ?" ); |
394 | c = cngetc(); |
395 | printf("\n" ); |
396 | } |
397 | |
398 | if (c == 'y' || c == 'Y') { |
399 | |
400 | /* XXX add cmd 'c' <devno> */ |
401 | userconf_hist_cmd('c'); |
402 | userconf_hist_int(devno); |
403 | |
404 | cd = &cfdata[devno]; |
405 | l = cd->cf_loc; |
406 | ia = cfiattr_lookup(cd->cf_pspec->cfp_iattr, 0); |
407 | KASSERT(ia); |
408 | ld = ia->ci_locdesc; |
409 | nld = ia->ci_loclen; |
410 | |
411 | for (ln = 0; ln < nld; ln++) |
412 | { |
413 | userconf_modify(&ld[ln], l); |
414 | |
415 | /* XXX add *l */ |
416 | userconf_hist_int(*l); |
417 | |
418 | l++; |
419 | } |
420 | |
421 | printf("[%3d] " , devno); |
422 | userconf_pdevnam(devno); |
423 | printf(" changed\n" ); |
424 | userconf_pdev(devno); |
425 | |
426 | /* XXX add eoc */ |
427 | userconf_hist_eoc(); |
428 | |
429 | } |
430 | } else { |
431 | printf("Unknown devno (max is %d)\n" , userconf_maxdev); |
432 | } |
433 | } |
434 | |
435 | static void |
436 | userconf_disable(int devno) |
437 | { |
438 | int done = 0; |
439 | |
440 | if (devno <= userconf_maxdev) { |
441 | switch (cfdata[devno].cf_fstate) { |
442 | case FSTATE_NOTFOUND: |
443 | cfdata[devno].cf_fstate = FSTATE_DNOTFOUND; |
444 | break; |
445 | case FSTATE_STAR: |
446 | cfdata[devno].cf_fstate = FSTATE_DSTAR; |
447 | break; |
448 | case FSTATE_DNOTFOUND: |
449 | case FSTATE_DSTAR: |
450 | done = 1; |
451 | break; |
452 | default: |
453 | printf("Error unknown state\n" ); |
454 | break; |
455 | } |
456 | |
457 | printf("[%3d] " , devno); |
458 | userconf_pdevnam(devno); |
459 | if (done) { |
460 | printf(" already" ); |
461 | } else { |
462 | /* XXX add cmd 'd' <devno> eoc */ |
463 | userconf_hist_cmd('d'); |
464 | userconf_hist_int(devno); |
465 | userconf_hist_eoc(); |
466 | } |
467 | printf(" disabled\n" ); |
468 | } else { |
469 | printf("Unknown devno (max is %d)\n" , userconf_maxdev); |
470 | } |
471 | } |
472 | |
473 | static void |
474 | userconf_enable(int devno) |
475 | { |
476 | int done = 0; |
477 | |
478 | if (devno <= userconf_maxdev) { |
479 | switch (cfdata[devno].cf_fstate) { |
480 | case FSTATE_DNOTFOUND: |
481 | cfdata[devno].cf_fstate = FSTATE_NOTFOUND; |
482 | break; |
483 | case FSTATE_DSTAR: |
484 | cfdata[devno].cf_fstate = FSTATE_STAR; |
485 | break; |
486 | case FSTATE_NOTFOUND: |
487 | case FSTATE_STAR: |
488 | done = 1; |
489 | break; |
490 | default: |
491 | printf("Error unknown state\n" ); |
492 | break; |
493 | } |
494 | |
495 | printf("[%3d] " , devno); |
496 | userconf_pdevnam(devno); |
497 | if (done) { |
498 | printf(" already" ); |
499 | } else { |
500 | /* XXX add cmd 'e' <devno> eoc */ |
501 | userconf_hist_cmd('d'); |
502 | userconf_hist_int(devno); |
503 | userconf_hist_eoc(); |
504 | } |
505 | printf(" enabled\n" ); |
506 | } else { |
507 | printf("Unknown devno (max is %d)\n" , userconf_maxdev); |
508 | } |
509 | } |
510 | |
511 | static void |
512 | userconf_help(void) |
513 | { |
514 | int j = 0, k; |
515 | |
516 | printf("command args description\n" ); |
517 | while (*userconf_cmds[j] != '\0') { |
518 | printf("%s" , userconf_cmds[j]); |
519 | k = strlen(userconf_cmds[j]); |
520 | while (k < 10) { |
521 | printf(" " ); |
522 | k++; |
523 | } |
524 | switch (*userconf_cmds[j+1]) { |
525 | case 'L': |
526 | printf("[count] number of lines before more" ); |
527 | break; |
528 | case 'b': |
529 | printf("8|10|16 base on large numbers" ); |
530 | break; |
531 | case 'c': |
532 | printf("devno|dev change devices" ); |
533 | break; |
534 | case 'd': |
535 | printf("devno|dev disable devices" ); |
536 | break; |
537 | case 'e': |
538 | printf("devno|dev enable devices" ); |
539 | break; |
540 | case 'f': |
541 | printf("devno|dev find devices" ); |
542 | break; |
543 | case 'h': |
544 | printf(" this message" ); |
545 | break; |
546 | case 'l': |
547 | printf(" list configuration" ); |
548 | break; |
549 | case 'q': |
550 | printf(" leave userconf" ); |
551 | break; |
552 | default: |
553 | printf(" don't know" ); |
554 | break; |
555 | } |
556 | printf("\n" ); |
557 | j += 2; |
558 | } |
559 | } |
560 | |
561 | static void |
562 | userconf_list(void) |
563 | { |
564 | int i = 0; |
565 | |
566 | userconf_cnt = 0; |
567 | |
568 | while (cfdata[i].cf_name != NULL) { |
569 | if (userconf_more()) |
570 | break; |
571 | userconf_pdev(i++); |
572 | } |
573 | |
574 | userconf_cnt = -1; |
575 | } |
576 | |
577 | static void |
578 | userconf_common_dev(char *dev, int len, short unit, short state, char routine) |
579 | { |
580 | int i = 0; |
581 | |
582 | switch (routine) { |
583 | case UC_CHANGE: |
584 | break; |
585 | default: |
586 | userconf_cnt = 0; |
587 | break; |
588 | } |
589 | |
590 | while (cfdata[i].cf_name != NULL) { |
591 | if (strlen(cfdata[i].cf_name) == len) { |
592 | |
593 | /* |
594 | * Ok, if device name is correct |
595 | * If state == FSTATE_FOUND, look for "dev" |
596 | * If state == FSTATE_STAR, look for "dev*" |
597 | * If state == FSTATE_NOTFOUND, look for "dev0" |
598 | */ |
599 | if (strncasecmp(dev, cfdata[i].cf_name, |
600 | len) == 0 && |
601 | (state == FSTATE_FOUND || |
602 | (state == FSTATE_STAR && |
603 | (cfdata[i].cf_fstate == FSTATE_STAR || |
604 | cfdata[i].cf_fstate == FSTATE_DSTAR)) || |
605 | (state == FSTATE_NOTFOUND && |
606 | cfdata[i].cf_unit == unit && |
607 | (cfdata[i].cf_fstate == FSTATE_NOTFOUND || |
608 | cfdata[i].cf_fstate == FSTATE_DNOTFOUND)))) { |
609 | if (userconf_more()) |
610 | break; |
611 | switch (routine) { |
612 | case UC_CHANGE: |
613 | userconf_change(i); |
614 | break; |
615 | case UC_ENABLE: |
616 | userconf_enable(i); |
617 | break; |
618 | case UC_DISABLE: |
619 | userconf_disable(i); |
620 | break; |
621 | case UC_FIND: |
622 | userconf_pdev(i); |
623 | break; |
624 | default: |
625 | printf("Unknown routine /%c/\n" , |
626 | routine); |
627 | break; |
628 | } |
629 | } |
630 | } |
631 | i++; |
632 | } |
633 | |
634 | switch (routine) { |
635 | case UC_CHANGE: |
636 | break; |
637 | default: |
638 | userconf_cnt = -1; |
639 | break; |
640 | } |
641 | } |
642 | |
643 | #if 0 |
644 | static void |
645 | userconf_add_read(char *prompt, char field, char *dev, int len, int *val) |
646 | { |
647 | int ok = 0; |
648 | int a; |
649 | char *c; |
650 | |
651 | *val = -1; |
652 | |
653 | while (!ok) { |
654 | printf("%s ? " , prompt); |
655 | |
656 | getsn(userconf_argbuf, sizeof(userconf_argbuf)); |
657 | |
658 | c = userconf_argbuf; |
659 | while (*c == ' ' || *c == '\t' || *c == '\n') c++; |
660 | |
661 | if (*c != '\0') { |
662 | if (userconf_number(c, &a) == 0) { |
663 | if (a > userconf_maxdev) { |
664 | printf("Unknown devno (max is %d)\n" , |
665 | userconf_maxdev); |
666 | } else if (strncasecmp(dev, |
667 | cfdata[a].cf_name, len) != 0 && |
668 | field == 'a') { |
669 | printf("Not same device type\n" ); |
670 | } else { |
671 | *val = a; |
672 | ok = 1; |
673 | } |
674 | } else if (*c == '?') { |
675 | userconf_common_dev(dev, len, 0, |
676 | FSTATE_FOUND, UC_FIND); |
677 | } else if (*c == 'q' || *c == 'Q') { |
678 | ok = 1; |
679 | } else { |
680 | printf("Unknown argument\n" ); |
681 | } |
682 | } else { |
683 | ok = 1; |
684 | } |
685 | } |
686 | } |
687 | #endif /* 0 */ |
688 | |
689 | int |
690 | userconf_parse(char *cmd) |
691 | { |
692 | char *c, *v; |
693 | int i = 0, j = 0, k, a; |
694 | short unit, state; |
695 | |
696 | c = cmd; |
697 | while (*c == ' ' || *c == '\t') |
698 | c++; |
699 | v = c; |
700 | while (*c != ' ' && *c != '\t' && *c != '\n' && *c != '\0') { |
701 | c++; |
702 | i++; |
703 | } |
704 | |
705 | k = -1; |
706 | while (*userconf_cmds[j] != '\0') { |
707 | if (strlen(userconf_cmds[j]) == i) { |
708 | if (strncasecmp(v, userconf_cmds[j], i) == 0) |
709 | k = j; |
710 | } |
711 | j += 2; |
712 | } |
713 | |
714 | while (*c == ' ' || *c == '\t' || *c == '\n') |
715 | c++; |
716 | |
717 | if (k == -1) { |
718 | if (*v != '\n') |
719 | printf("Unknown command, try help\n" ); |
720 | } else { |
721 | switch (*userconf_cmds[k+1]) { |
722 | case 'L': |
723 | if (*c == '\0') |
724 | printf("Argument expected\n" ); |
725 | else if (userconf_number(c, &a) == 0) |
726 | userconf_lines = a; |
727 | else |
728 | printf("Unknown argument\n" ); |
729 | break; |
730 | case 'b': |
731 | if (*c == '\0') |
732 | printf("8|10|16 expected\n" ); |
733 | else if (userconf_number(c, &a) == 0) { |
734 | if (a == 8 || a == 10 || a == 16) { |
735 | userconf_base = a; |
736 | } else { |
737 | printf("8|10|16 expected\n" ); |
738 | } |
739 | } else |
740 | printf("Unknown argument\n" ); |
741 | break; |
742 | case 'c': |
743 | if (*c == '\0') |
744 | printf("DevNo or Dev expected\n" ); |
745 | else if (userconf_number(c, &a) == 0) |
746 | userconf_change(a); |
747 | else if (userconf_device(c, &a, &unit, &state) == 0) |
748 | userconf_common_dev(c, a, unit, state, UC_CHANGE); |
749 | else |
750 | printf("Unknown argument\n" ); |
751 | break; |
752 | case 'd': |
753 | if (*c == '\0') |
754 | printf("Attr, DevNo or Dev expected\n" ); |
755 | else if (userconf_number(c, &a) == 0) |
756 | userconf_disable(a); |
757 | else if (userconf_device(c, &a, &unit, &state) == 0) |
758 | userconf_common_dev(c, a, unit, state, UC_DISABLE); |
759 | else |
760 | printf("Unknown argument\n" ); |
761 | break; |
762 | case 'e': |
763 | if (*c == '\0') |
764 | printf("Attr, DevNo or Dev expected\n" ); |
765 | else if (userconf_number(c, &a) == 0) |
766 | userconf_enable(a); |
767 | else if (userconf_device(c, &a, &unit, &state) == 0) |
768 | userconf_common_dev(c, a, unit, state, UC_ENABLE); |
769 | else |
770 | printf("Unknown argument\n" ); |
771 | break; |
772 | case 'f': |
773 | if (*c == '\0') |
774 | printf("DevNo or Dev expected\n" ); |
775 | else if (userconf_number(c, &a) == 0) |
776 | userconf_pdev(a); |
777 | else if (userconf_device(c, &a, &unit, &state) == 0) |
778 | userconf_common_dev(c, a, unit, state, UC_FIND); |
779 | else |
780 | printf("Unknown argument\n" ); |
781 | break; |
782 | case 'h': |
783 | userconf_help(); |
784 | break; |
785 | case 'l': |
786 | if (*c == '\0') |
787 | userconf_list(); |
788 | else |
789 | printf("Unknown argument\n" ); |
790 | break; |
791 | case 'q': |
792 | /* XXX add cmd 'q' eoc */ |
793 | userconf_hist_cmd('q'); |
794 | userconf_hist_eoc(); |
795 | return(-1); |
796 | case 's': |
797 | default: |
798 | printf("Unknown command\n" ); |
799 | break; |
800 | } |
801 | } |
802 | return(0); |
803 | } |
804 | |
805 | void |
806 | userconf_prompt(void) |
807 | { |
808 | const char prompt[] = "uc> " ; |
809 | |
810 | printf("userconf: configure system autoconfiguration:\n" ); |
811 | |
812 | while (1) { |
813 | printf(prompt); |
814 | if (cngetsn(userconf_cmdbuf, sizeof(userconf_cmdbuf)) > 0 && |
815 | userconf_parse(userconf_cmdbuf)) |
816 | break; |
817 | } |
818 | printf("Continuing...\n" ); |
819 | } |
820 | |