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