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