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