Annotation of sys/kern/subr_userconf.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: subr_userconf.c,v 1.34 2005/12/09 09:09:52 jsg Exp $ */
! 2:
! 3: /*
! 4: * Copyright (c) 1996-2001 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:
! 29: #include <sys/param.h>
! 30: #include <sys/systm.h>
! 31: #include <sys/device.h>
! 32: #include <sys/malloc.h>
! 33: #include <sys/time.h>
! 34:
! 35: #include <dev/cons.h>
! 36:
! 37: extern char *locnames[];
! 38: extern short locnamp[];
! 39: extern short cfroots[];
! 40: extern int cfroots_size;
! 41: extern int pv_size;
! 42: extern short pv[];
! 43: extern struct timezone tz;
! 44: extern char *pdevnames[];
! 45: extern int pdevnames_size;
! 46: extern struct pdevinit pdevinit[];
! 47:
! 48: int userconf_base = 16; /* Base for "large" numbers */
! 49: int userconf_maxdev = -1; /* # of used device slots */
! 50: int userconf_totdev = -1; /* # of device slots */
! 51: int userconf_maxlocnames = -1; /* # of locnames */
! 52: int userconf_cnt = -1; /* Line counter for ... */
! 53: int userconf_lines = 12; /* ... # of lines per page */
! 54: int userconf_histlen = 0;
! 55: int userconf_histcur = 0;
! 56: char userconf_history[1024];
! 57: int userconf_histsz = sizeof(userconf_history);
! 58: char userconf_argbuf[40]; /* Additional input */
! 59: char userconf_cmdbuf[40]; /* Command line */
! 60: char userconf_histbuf[40];
! 61:
! 62: void userconf_init(void);
! 63: int userconf_more(void);
! 64: void userconf_modify(char *, int *);
! 65: void userconf_hist_cmd(char);
! 66: void userconf_hist_int(int);
! 67: void userconf_hist_eoc(void);
! 68: void userconf_pnum(int);
! 69: void userconf_pdevnam(short);
! 70: void userconf_pdev(short);
! 71: int userconf_number(char *, int *);
! 72: int userconf_device(char *, int *, short *, short *);
! 73: int userconf_attr(char *, int *);
! 74: void userconf_modify(char *, int *);
! 75: void userconf_change(int);
! 76: void userconf_disable(int);
! 77: void userconf_enable(int);
! 78: void userconf_help(void);
! 79: void userconf_list(void);
! 80: void userconf_show(void);
! 81: void userconf_common_attr_val(short, int *, char);
! 82: void userconf_show_attr(char *);
! 83: void userconf_common_dev(char *, int, short, short, char);
! 84: void userconf_common_attr(char *, int, char);
! 85: void userconf_add_read(char *, char, char *, int, int *);
! 86: void userconf_add(char *, int, short, short);
! 87: int userconf_parse(char *);
! 88:
! 89: #define UC_CHANGE 'c'
! 90: #define UC_DISABLE 'd'
! 91: #define UC_ENABLE 'e'
! 92: #define UC_FIND 'f'
! 93: #define UC_SHOW 's'
! 94:
! 95: char *userconf_cmds[] = {
! 96: "add", "a",
! 97: "base", "b",
! 98: "change", "c",
! 99: #if defined(DDB)
! 100: "ddb", "D",
! 101: #endif
! 102: "disable", "d",
! 103: "enable", "e",
! 104: "exit", "q",
! 105: "find", "f",
! 106: "help", "h",
! 107: "list", "l",
! 108: "lines", "L",
! 109: "quit", "q",
! 110: "show", "s",
! 111: "timezone", "t",
! 112: "verbose", "v",
! 113: "?", "h",
! 114: "", "",
! 115: };
! 116:
! 117: void
! 118: userconf_init(void)
! 119: {
! 120: int i = 0;
! 121: struct cfdata *cd;
! 122: int ln;
! 123:
! 124: while (cfdata[i].cf_attach != 0) {
! 125: userconf_maxdev = i;
! 126: userconf_totdev = i;
! 127:
! 128: cd = &cfdata[i];
! 129: ln = cd->cf_locnames;
! 130: while (locnamp[ln] != -1) {
! 131: if (locnamp[ln] > userconf_maxlocnames)
! 132: userconf_maxlocnames = locnamp[ln];
! 133: ln++;
! 134: }
! 135: i++;
! 136: }
! 137:
! 138: while (cfdata[i].cf_attach == 0) {
! 139: userconf_totdev = i;
! 140: i++;
! 141: }
! 142: userconf_totdev = userconf_totdev - 1;
! 143: }
! 144:
! 145: int
! 146: userconf_more(void)
! 147: {
! 148: int quit = 0;
! 149: char c = '\0';
! 150:
! 151: if (userconf_cnt != -1) {
! 152: if (userconf_cnt == userconf_lines) {
! 153: printf("--- more ---");
! 154: c = cngetc();
! 155: userconf_cnt = 0;
! 156: printf("\r \r");
! 157: }
! 158: userconf_cnt++;
! 159: if (c == 'q' || c == 'Q')
! 160: quit = 1;
! 161: }
! 162: return (quit);
! 163: }
! 164:
! 165: void
! 166: userconf_hist_cmd(char cmd)
! 167: {
! 168: userconf_histcur = userconf_histlen;
! 169: if (userconf_histcur < userconf_histsz) {
! 170: userconf_history[userconf_histcur] = cmd;
! 171: userconf_histcur++;
! 172: }
! 173: }
! 174:
! 175: void
! 176: userconf_hist_int(int val)
! 177: {
! 178: snprintf(userconf_histbuf, sizeof userconf_histbuf, " %d",val);
! 179: if (userconf_histcur + strlen(userconf_histbuf) < userconf_histsz) {
! 180: bcopy(userconf_histbuf,
! 181: &userconf_history[userconf_histcur],
! 182: strlen(userconf_histbuf));
! 183: userconf_histcur = userconf_histcur + strlen(userconf_histbuf);
! 184: }
! 185: }
! 186:
! 187: void
! 188: userconf_hist_eoc(void)
! 189: {
! 190: if (userconf_histcur < userconf_histsz) {
! 191: userconf_history[userconf_histcur] = '\n';
! 192: userconf_histcur++;
! 193: userconf_histlen = userconf_histcur;
! 194: }
! 195: }
! 196:
! 197: void
! 198: userconf_pnum(int val)
! 199: {
! 200: if (val > -2 && val < 16) {
! 201: printf("%d",val);
! 202: return;
! 203: }
! 204:
! 205: switch (userconf_base) {
! 206: case 8:
! 207: printf("0%o",val);
! 208: break;
! 209: case 10:
! 210: printf("%d",val);
! 211: break;
! 212: case 16:
! 213: default:
! 214: printf("0x%x",val);
! 215: break;
! 216: }
! 217: }
! 218:
! 219: void
! 220: userconf_pdevnam(short dev)
! 221: {
! 222: struct cfdata *cd;
! 223:
! 224: cd = &cfdata[dev];
! 225: printf("%s", cd->cf_driver->cd_name);
! 226: switch (cd->cf_fstate) {
! 227: case FSTATE_NOTFOUND:
! 228: case FSTATE_DNOTFOUND:
! 229: printf("%d", cd->cf_unit);
! 230: break;
! 231: case FSTATE_FOUND:
! 232: printf("*FOUND*");
! 233: break;
! 234: case FSTATE_STAR:
! 235: case FSTATE_DSTAR:
! 236: printf("*");
! 237: break;
! 238: default:
! 239: printf("*UNKNOWN*");
! 240: break;
! 241: }
! 242: }
! 243:
! 244: void
! 245: userconf_pdev(short devno)
! 246: {
! 247: struct cfdata *cd;
! 248: short *p;
! 249: int *l;
! 250: int ln;
! 251: char c;
! 252:
! 253: if (devno > userconf_maxdev && devno <= userconf_totdev) {
! 254: printf("%3d free slot (for add)\n", devno);
! 255: return;
! 256: }
! 257:
! 258: if (devno > userconf_totdev &&
! 259: devno <= userconf_totdev+pdevnames_size) {
! 260: printf("%3d %s count %d (pseudo device)\n", devno,
! 261: pdevnames[devno-userconf_totdev-1],
! 262: pdevinit[devno-userconf_totdev-1].pdev_count);
! 263: return;
! 264: }
! 265:
! 266: if (devno > userconf_maxdev) {
! 267: printf("Unknown devno (max is %d)\n", userconf_maxdev);
! 268: return;
! 269: }
! 270:
! 271: cd = &cfdata[devno];
! 272:
! 273: printf("%3d ", devno);
! 274: userconf_pdevnam(devno);
! 275: printf(" at");
! 276: c = ' ';
! 277: p = cd->cf_parents;
! 278: if (*p == -1)
! 279: printf(" root");
! 280: while (*p != -1) {
! 281: printf("%c", c);
! 282: userconf_pdevnam(*p++);
! 283: c = '|';
! 284: }
! 285: switch (cd->cf_fstate) {
! 286: case FSTATE_NOTFOUND:
! 287: case FSTATE_FOUND:
! 288: case FSTATE_STAR:
! 289: break;
! 290: case FSTATE_DNOTFOUND:
! 291: case FSTATE_DSTAR:
! 292: printf(" disable");
! 293: break;
! 294: default:
! 295: printf(" ???");
! 296: break;
! 297: }
! 298: l = cd->cf_loc;
! 299: ln = cd->cf_locnames;
! 300: while (locnamp[ln] != -1) {
! 301: printf(" %s ", locnames[locnamp[ln]]);
! 302: ln++;
! 303: userconf_pnum(*l++);
! 304: }
! 305: printf(" flags 0x%x\n", cd->cf_flags);
! 306: }
! 307:
! 308: int
! 309: userconf_number(char *c, int *val)
! 310: {
! 311: u_int num = 0;
! 312: int neg = 0;
! 313: int base = 10;
! 314:
! 315: if (*c == '-') {
! 316: neg = 1;
! 317: c++;
! 318: }
! 319: if (*c == '0') {
! 320: base = 8;
! 321: c++;
! 322: if (*c == 'x' || *c == 'X') {
! 323: base = 16;
! 324: c++;
! 325: }
! 326: }
! 327: while (*c != '\n' && *c != '\t' && *c != ' ' && *c != '\0') {
! 328: u_char cc = *c;
! 329:
! 330: if (cc >= '0' && cc <= '9')
! 331: cc = cc - '0';
! 332: else if (cc >= 'a' && cc <= 'f')
! 333: cc = cc - 'a' + 10;
! 334: else if (cc >= 'A' && cc <= 'F')
! 335: cc = cc - 'A' + 10;
! 336: else
! 337: return (-1);
! 338:
! 339: if (cc > base)
! 340: return (-1);
! 341: num = num * base + cc;
! 342: c++;
! 343: }
! 344:
! 345: if (neg && num > INT_MAX) /* overflow */
! 346: return (1);
! 347: *val = neg ? - num : num;
! 348: return (0);
! 349: }
! 350:
! 351: int
! 352: userconf_device(char *cmd, int *len, short *unit, short *state)
! 353: {
! 354: short u = 0, s = FSTATE_FOUND;
! 355: int l = 0;
! 356: char *c;
! 357:
! 358: c = cmd;
! 359: while (*c >= 'a' && *c <= 'z') {
! 360: l++;
! 361: c++;
! 362: }
! 363: if (*c == '*') {
! 364: s = FSTATE_STAR;
! 365: c++;
! 366: } else {
! 367: while (*c >= '0' && *c <= '9') {
! 368: s = FSTATE_NOTFOUND;
! 369: u = u*10 + *c - '0';
! 370: c++;
! 371: }
! 372: }
! 373: while (*c == ' ' || *c == '\t' || *c == '\n')
! 374: c++;
! 375:
! 376: if (*c == '\0') {
! 377: *len = l;
! 378: *unit = u;
! 379: *state = s;
! 380: return(0);
! 381: }
! 382:
! 383: return(-1);
! 384: }
! 385:
! 386: int
! 387: userconf_attr(char *cmd, int *val)
! 388: {
! 389: char *c;
! 390: short attr = -1, i = 0, l = 0;
! 391:
! 392: c = cmd;
! 393: while (*c != ' ' && *c != '\t' && *c != '\n' && *c != '\0') {
! 394: c++;
! 395: l++;
! 396: }
! 397:
! 398: while (i <= userconf_maxlocnames) {
! 399: if (strlen(locnames[i]) == l) {
! 400: if (strncasecmp(cmd, locnames[i], l) == 0)
! 401: attr = i;
! 402: }
! 403: i++;
! 404: }
! 405:
! 406: if (attr == -1) {
! 407: return (-1);
! 408: }
! 409:
! 410: *val = attr;
! 411:
! 412: return(0);
! 413: }
! 414:
! 415: void
! 416: userconf_modify(char *item, int *val)
! 417: {
! 418: int ok = 0;
! 419: int a;
! 420: char *c;
! 421: int i;
! 422:
! 423: while (!ok) {
! 424: printf("%s [", item);
! 425: userconf_pnum(*val);
! 426: printf("] ? ");
! 427:
! 428: i = getsn(userconf_argbuf, sizeof(userconf_argbuf));
! 429:
! 430: c = userconf_argbuf;
! 431: while (*c == ' ' || *c == '\t' || *c == '\n') c++;
! 432:
! 433: if (*c != '\0') {
! 434: if (userconf_number(c, &a) == 0) {
! 435: *val = a;
! 436: ok = 1;
! 437: } else {
! 438: printf("Unknown argument\n");
! 439: }
! 440: } else {
! 441: ok = 1;
! 442: }
! 443: }
! 444: }
! 445:
! 446: void
! 447: userconf_change(int devno)
! 448: {
! 449: struct cfdata *cd;
! 450: char c = '\0';
! 451: int *l;
! 452: int ln;
! 453:
! 454: if (devno <= userconf_maxdev) {
! 455: userconf_pdev(devno);
! 456:
! 457: while (c != 'y' && c != 'Y' && c != 'n' && c != 'N') {
! 458: printf("change (y/n) ?");
! 459: c = cngetc();
! 460: printf("\n");
! 461: }
! 462:
! 463: if (c == 'y' || c == 'Y') {
! 464: int share = 0, i, *lk;
! 465:
! 466: /* XXX add cmd 'c' <devno> */
! 467: userconf_hist_cmd('c');
! 468: userconf_hist_int(devno);
! 469:
! 470: cd = &cfdata[devno];
! 471: l = cd->cf_loc;
! 472: ln = cd->cf_locnames;
! 473:
! 474: /*
! 475: * Search for some other driver sharing this
! 476: * locator table. if one does, we may need to
! 477: * replace the locators with a malloc'd copy.
! 478: */
! 479: for (i = 0; cfdata[i].cf_driver; i++)
! 480: if (i != devno && cfdata[i].cf_loc == l)
! 481: share = 1;
! 482: if (share) {
! 483: for (i = 0; locnamp[ln+i] != -1 ; i++)
! 484: ;
! 485: lk = l = (int *)malloc(sizeof(int) * i,
! 486: M_TEMP, M_NOWAIT);
! 487: if (lk == NULL) {
! 488: printf("out of memory.\n");
! 489: return;
! 490: }
! 491: bcopy(cd->cf_loc, l, sizeof(int) * i);
! 492: }
! 493:
! 494: while (locnamp[ln] != -1) {
! 495: userconf_modify(locnames[locnamp[ln]], l);
! 496:
! 497: /* XXX add *l */
! 498: userconf_hist_int(*l);
! 499:
! 500: ln++;
! 501: l++;
! 502: }
! 503: userconf_modify("flags", &cd->cf_flags);
! 504: userconf_hist_int(cd->cf_flags);
! 505:
! 506: if (share) {
! 507: if (bcmp(cd->cf_loc, lk, sizeof(int) * i))
! 508: cd->cf_loc = lk;
! 509: else
! 510: free(lk, M_TEMP);
! 511: }
! 512:
! 513: printf("%3d ", devno);
! 514: userconf_pdevnam(devno);
! 515: printf(" changed\n");
! 516: userconf_pdev(devno);
! 517: }
! 518: return;
! 519: }
! 520:
! 521: if (devno > userconf_maxdev && devno <= userconf_totdev) {
! 522: printf("%3d can't change free slot\n", devno);
! 523: return;
! 524: }
! 525:
! 526: if (devno > userconf_totdev &&
! 527: devno <= userconf_totdev+pdevnames_size) {
! 528: userconf_pdev(devno);
! 529: while (c != 'y' && c != 'Y' && c != 'n' && c != 'N') {
! 530: printf("change (y/n) ?");
! 531: c = cngetc();
! 532: printf("\n");
! 533: }
! 534:
! 535: if (c == 'y' || c == 'Y') {
! 536: /* XXX add cmd 'c' <devno> */
! 537: userconf_hist_cmd('c');
! 538: userconf_hist_int(devno);
! 539:
! 540: userconf_modify("count",
! 541: &pdevinit[devno-userconf_totdev-1].pdev_count);
! 542: userconf_hist_int(pdevinit[devno-userconf_totdev-1].pdev_count);
! 543:
! 544: printf("%3d %s changed\n", devno,
! 545: pdevnames[devno-userconf_totdev-1]);
! 546: userconf_pdev(devno);
! 547:
! 548: /* XXX add eoc */
! 549: userconf_hist_eoc();
! 550: }
! 551: return;
! 552: }
! 553:
! 554: printf("Unknown devno (max is %d)\n", userconf_totdev+pdevnames_size);
! 555: }
! 556:
! 557: void
! 558: userconf_disable(int devno)
! 559: {
! 560: int done = 0;
! 561:
! 562: if (devno <= userconf_maxdev) {
! 563: switch (cfdata[devno].cf_fstate) {
! 564: case FSTATE_NOTFOUND:
! 565: cfdata[devno].cf_fstate = FSTATE_DNOTFOUND;
! 566: break;
! 567: case FSTATE_STAR:
! 568: cfdata[devno].cf_fstate = FSTATE_DSTAR;
! 569: break;
! 570: case FSTATE_DNOTFOUND:
! 571: case FSTATE_DSTAR:
! 572: done = 1;
! 573: break;
! 574: default:
! 575: printf("Error unknown state\n");
! 576: break;
! 577: }
! 578:
! 579: printf("%3d ", devno);
! 580: userconf_pdevnam(devno);
! 581: if (done) {
! 582: printf(" already");
! 583: } else {
! 584: /* XXX add cmd 'd' <devno> eoc */
! 585: userconf_hist_cmd('d');
! 586: userconf_hist_int(devno);
! 587: userconf_hist_eoc();
! 588: }
! 589: printf(" disabled\n");
! 590:
! 591: return;
! 592: }
! 593:
! 594: if (devno > userconf_maxdev && devno <= userconf_totdev) {
! 595: printf("%3d can't disable free slot\n", devno);
! 596: return;
! 597: }
! 598:
! 599: if (devno > userconf_totdev &&
! 600: devno <= userconf_totdev+pdevnames_size) {
! 601: printf("%3d %s can't disable pseudo device\n", devno,
! 602: pdevnames[devno-userconf_totdev-1]);
! 603: return;
! 604: }
! 605:
! 606: printf("Unknown devno (max is %d)\n", userconf_totdev+pdevnames_size);
! 607: }
! 608:
! 609: void
! 610: userconf_enable(int devno)
! 611: {
! 612: int done = 0;
! 613:
! 614: if (devno <= userconf_maxdev) {
! 615: switch (cfdata[devno].cf_fstate) {
! 616: case FSTATE_DNOTFOUND:
! 617: cfdata[devno].cf_fstate = FSTATE_NOTFOUND;
! 618: break;
! 619: case FSTATE_DSTAR:
! 620: cfdata[devno].cf_fstate = FSTATE_STAR;
! 621: break;
! 622: case FSTATE_NOTFOUND:
! 623: case FSTATE_STAR:
! 624: done = 1;
! 625: break;
! 626: default:
! 627: printf("Error unknown state\n");
! 628: break;
! 629: }
! 630:
! 631: printf("%3d ", devno);
! 632: userconf_pdevnam(devno);
! 633: if (done) {
! 634: printf(" already");
! 635: } else {
! 636: /* XXX add cmd 'e' <devno> eoc */
! 637: userconf_hist_cmd('e');
! 638: userconf_hist_int(devno);
! 639: userconf_hist_eoc();
! 640: }
! 641: printf(" enabled\n");
! 642: return;
! 643: }
! 644:
! 645: if (devno > userconf_maxdev && devno <= userconf_totdev) {
! 646: printf("%3d can't enable free slot\n", devno);
! 647: return;
! 648: }
! 649:
! 650: if (devno > userconf_totdev &&
! 651: devno <= userconf_totdev+pdevnames_size) {
! 652: printf("%3d %s can't enable pseudo device\n", devno,
! 653: pdevnames[devno-userconf_totdev-1]);
! 654: return;
! 655: }
! 656:
! 657: printf("Unknown devno (max is %d)\n", userconf_totdev+pdevnames_size);
! 658: }
! 659:
! 660: void
! 661: userconf_help(void)
! 662: {
! 663: int j = 0, k;
! 664:
! 665: printf("command args description\n");
! 666: while (*userconf_cmds[j] != '\0') {
! 667: printf(userconf_cmds[j]);
! 668: k = strlen(userconf_cmds[j]);
! 669: while (k < 10) {
! 670: printf(" ");
! 671: k++;
! 672: }
! 673: switch (*userconf_cmds[j+1]) {
! 674: case 'L':
! 675: printf("[count] number of lines before more");
! 676: break;
! 677: case 'a':
! 678: printf("dev add a device");
! 679: break;
! 680: case 'b':
! 681: printf("8|10|16 base on large numbers");
! 682: break;
! 683: case 'c':
! 684: printf("devno|dev change devices");
! 685: break;
! 686: #if defined(DDB)
! 687: case 'D':
! 688: printf(" enter ddb");
! 689: break;
! 690: #endif
! 691: case 'd':
! 692: printf("attr val|devno|dev disable devices");
! 693: break;
! 694: case 'e':
! 695: printf("attr val|devno|dev enable devices");
! 696: break;
! 697: case 'f':
! 698: printf("devno|dev find devices");
! 699: break;
! 700: case 'h':
! 701: printf(" this message");
! 702: break;
! 703: case 'l':
! 704: printf(" list configuration");
! 705: break;
! 706: case 'q':
! 707: printf(" leave UKC");
! 708: break;
! 709: case 's':
! 710: printf("[attr [val]] "
! 711: "show attributes (or devices with an attribute)");
! 712: break;
! 713: case 't':
! 714: printf("[mins [dst]] set timezone/dst");
! 715: break;
! 716: case 'v':
! 717: printf(" toggle verbose booting");
! 718: break;
! 719: default:
! 720: printf(" don't know");
! 721: break;
! 722: }
! 723: printf("\n");
! 724: j += 2;
! 725: }
! 726: }
! 727:
! 728: void
! 729: userconf_list(void)
! 730: {
! 731: int i = 0;
! 732:
! 733: userconf_cnt = 0;
! 734:
! 735: while (i <= (userconf_totdev+pdevnames_size)) {
! 736: if (userconf_more())
! 737: break;
! 738: userconf_pdev(i++);
! 739: }
! 740:
! 741: userconf_cnt = -1;
! 742: }
! 743:
! 744: void
! 745: userconf_show(void)
! 746: {
! 747: int i = 0;
! 748:
! 749: userconf_cnt = 0;
! 750:
! 751: while (i <= userconf_maxlocnames) {
! 752: if (userconf_more())
! 753: break;
! 754: printf("%s\n", locnames[i++]);
! 755: }
! 756:
! 757: userconf_cnt = -1;
! 758: }
! 759:
! 760: void
! 761: userconf_common_attr_val(short attr, int *val, char routine)
! 762: {
! 763: struct cfdata *cd;
! 764: int *l;
! 765: int ln;
! 766: int i = 0, quit = 0;
! 767:
! 768: userconf_cnt = 0;
! 769:
! 770: while (i <= userconf_maxdev) {
! 771: cd = &cfdata[i];
! 772: l = cd->cf_loc;
! 773: ln = cd->cf_locnames;
! 774: while (locnamp[ln] != -1) {
! 775: if (locnamp[ln] == attr) {
! 776: if (val == NULL) {
! 777: quit = userconf_more();
! 778: userconf_pdev(i);
! 779: } else {
! 780: if (*val == *l) {
! 781: quit = userconf_more();
! 782: switch (routine) {
! 783: case UC_ENABLE:
! 784: userconf_enable(i);
! 785: break;
! 786: case UC_DISABLE:
! 787: userconf_disable(i);
! 788: break;
! 789: case UC_SHOW:
! 790: userconf_pdev(i);
! 791: break;
! 792: default:
! 793: printf("Unknown routine /%c/\n",
! 794: routine);
! 795: break;
! 796: }
! 797: }
! 798: }
! 799: }
! 800: if (quit)
! 801: break;
! 802: ln++;
! 803: l++;
! 804: }
! 805: if (quit)
! 806: break;
! 807: i++;
! 808: }
! 809:
! 810: userconf_cnt = -1;
! 811: }
! 812:
! 813: void
! 814: userconf_show_attr(char *cmd)
! 815: {
! 816: char *c;
! 817: short attr = -1, i = 0, l = 0;
! 818: int a;
! 819:
! 820: c = cmd;
! 821: while (*c != ' ' && *c != '\t' && *c != '\n' && *c != '\0') {
! 822: c++;
! 823: l++;
! 824: }
! 825: while (*c == ' ' || *c == '\t' || *c == '\n') {
! 826: c++;
! 827: }
! 828: while (i <= userconf_maxlocnames) {
! 829: if (strlen(locnames[i]) == l) {
! 830: if (strncasecmp(cmd, locnames[i], l) == 0) {
! 831: attr = i;
! 832: }
! 833: }
! 834: i++;
! 835: }
! 836:
! 837: if (attr == -1) {
! 838: printf("Unknown attribute\n");
! 839: return;
! 840: }
! 841:
! 842: if (*c == '\0') {
! 843: userconf_common_attr_val(attr, NULL, UC_SHOW);
! 844: } else {
! 845: if (userconf_number(c, &a) == 0) {
! 846: userconf_common_attr_val(attr, &a, UC_SHOW);
! 847: } else {
! 848: printf("Unknown argument\n");
! 849: }
! 850: }
! 851: }
! 852:
! 853: void
! 854: userconf_common_dev(char *dev, int len, short unit, short state, char routine)
! 855: {
! 856: int i = 0;
! 857:
! 858: switch (routine) {
! 859: case UC_CHANGE:
! 860: break;
! 861: default:
! 862: userconf_cnt = 0;
! 863: break;
! 864: }
! 865:
! 866: while (cfdata[i].cf_attach != 0) {
! 867: if (strlen(cfdata[i].cf_driver->cd_name) == len) {
! 868:
! 869: /*
! 870: * Ok, if device name is correct
! 871: * If state == FSTATE_FOUND, look for "dev"
! 872: * If state == FSTATE_STAR, look for "dev*"
! 873: * If state == FSTATE_NOTFOUND, look for "dev0"
! 874: */
! 875: if (strncasecmp(dev, cfdata[i].cf_driver->cd_name,
! 876: len) == 0 &&
! 877: (state == FSTATE_FOUND ||
! 878: (state == FSTATE_STAR &&
! 879: (cfdata[i].cf_fstate == FSTATE_STAR ||
! 880: cfdata[i].cf_fstate == FSTATE_DSTAR)) ||
! 881: (state == FSTATE_NOTFOUND &&
! 882: cfdata[i].cf_unit == unit &&
! 883: (cfdata[i].cf_fstate == FSTATE_NOTFOUND ||
! 884: cfdata[i].cf_fstate == FSTATE_DNOTFOUND)))) {
! 885: if (userconf_more())
! 886: break;
! 887: switch (routine) {
! 888: case UC_CHANGE:
! 889: userconf_change(i);
! 890: break;
! 891: case UC_ENABLE:
! 892: userconf_enable(i);
! 893: break;
! 894: case UC_DISABLE:
! 895: userconf_disable(i);
! 896: break;
! 897: case UC_FIND:
! 898: userconf_pdev(i);
! 899: break;
! 900: default:
! 901: printf("Unknown routine /%c/\n",
! 902: routine);
! 903: break;
! 904: }
! 905: }
! 906: }
! 907: i++;
! 908: }
! 909:
! 910: for (i = 0; i < pdevnames_size; i++) {
! 911: if (strncasecmp(dev, pdevnames[i], len) == 0 &&
! 912: state == FSTATE_FOUND) {
! 913: switch(routine) {
! 914: case UC_CHANGE:
! 915: userconf_change(userconf_totdev+1+i);
! 916: break;
! 917: case UC_ENABLE:
! 918: userconf_enable(userconf_totdev+1+i);
! 919: break;
! 920: case UC_DISABLE:
! 921: userconf_disable(userconf_totdev+1+i);
! 922: break;
! 923: case UC_FIND:
! 924: userconf_pdev(userconf_totdev+1+i);
! 925: break;
! 926: default:
! 927: printf("Unknown pseudo routine /%c/\n",routine);
! 928: break;
! 929: }
! 930: }
! 931: }
! 932:
! 933: switch (routine) {
! 934: case UC_CHANGE:
! 935: break;
! 936: default:
! 937: userconf_cnt = -1;
! 938: break;
! 939: }
! 940: }
! 941:
! 942: void
! 943: userconf_common_attr(char *cmd, int attr, char routine)
! 944: {
! 945: char *c;
! 946: short l = 0;
! 947: int a;
! 948:
! 949: c = cmd;
! 950: while (*c != ' ' && *c != '\t' && *c != '\n' && *c != '\0') {
! 951: c++;
! 952: l++;
! 953: }
! 954: while (*c == ' ' || *c == '\t' || *c == '\n')
! 955: c++;
! 956:
! 957: if (*c == '\0') {
! 958: printf("Value missing for attribute\n");
! 959: return;
! 960: }
! 961:
! 962: if (userconf_number(c, &a) == 0) {
! 963: userconf_common_attr_val(attr, &a, routine);
! 964: } else {
! 965: printf("Unknown argument\n");
! 966: }
! 967: }
! 968:
! 969: void
! 970: userconf_add_read(char *prompt, char field, char *dev, int len, int *val)
! 971: {
! 972: int ok = 0;
! 973: int a;
! 974: char *c;
! 975: int i;
! 976:
! 977: *val = -1;
! 978:
! 979: while (!ok) {
! 980: printf("%s ? ", prompt);
! 981:
! 982: i = getsn(userconf_argbuf, sizeof(userconf_argbuf));
! 983:
! 984: c = userconf_argbuf;
! 985: while (*c == ' ' || *c == '\t' || *c == '\n')
! 986: c++;
! 987:
! 988: if (*c != '\0') {
! 989: if (userconf_number(c, &a) == 0) {
! 990: if (a > userconf_maxdev) {
! 991: printf("Unknown devno (max is %d)\n",
! 992: userconf_maxdev);
! 993: } else if (strncasecmp(dev,
! 994: cfdata[a].cf_driver->cd_name, len) != 0 &&
! 995: field == 'a') {
! 996: printf("Not same device type\n");
! 997: } else {
! 998: *val = a;
! 999: ok = 1;
! 1000: }
! 1001: } else if (*c == '?') {
! 1002: userconf_common_dev(dev, len, 0,
! 1003: FSTATE_FOUND, UC_FIND);
! 1004: } else if (*c == 'q' || *c == 'Q') {
! 1005: ok = 1;
! 1006: } else {
! 1007: printf("Unknown argument\n");
! 1008: }
! 1009: } else {
! 1010: ok = 1;
! 1011: }
! 1012: }
! 1013: }
! 1014:
! 1015: void
! 1016: userconf_add(char *dev, int len, short unit, short state)
! 1017: {
! 1018: int i = 0, found = 0;
! 1019: struct cfdata new;
! 1020: int val, max_unit, star_unit, orig;
! 1021:
! 1022: bzero(&new, sizeof(struct cfdata));
! 1023:
! 1024: if (userconf_maxdev == userconf_totdev) {
! 1025: printf("No more space for new devices.\n");
! 1026: return;
! 1027: }
! 1028:
! 1029: if (state == FSTATE_FOUND) {
! 1030: printf("Device not complete number or * is missing\n");
! 1031: return;
! 1032: }
! 1033:
! 1034: for (i = 0; cfdata[i].cf_driver; i++)
! 1035: if (strlen(cfdata[i].cf_driver->cd_name) == len &&
! 1036: strncasecmp(dev, cfdata[i].cf_driver->cd_name, len) == 0)
! 1037: found = 1;
! 1038:
! 1039: if (!found) {
! 1040: printf("No device of this type exists.\n");
! 1041: return;
! 1042: }
! 1043:
! 1044: userconf_add_read("Clone Device (DevNo, 'q' or '?')",
! 1045: 'a', dev, len, &val);
! 1046:
! 1047: if (val != -1) {
! 1048: orig = val;
! 1049: new = cfdata[val];
! 1050: new.cf_unit = unit;
! 1051: new.cf_fstate = state;
! 1052: userconf_add_read("Insert before Device (DevNo, 'q' or '?')",
! 1053: 'i', dev, len, &val);
! 1054: }
! 1055:
! 1056: if (val != -1) {
! 1057: /* XXX add cmd 'a' <orig> <val> eoc */
! 1058: userconf_hist_cmd('a');
! 1059: userconf_hist_int(orig);
! 1060: userconf_hist_int(unit);
! 1061: userconf_hist_int(state);
! 1062: userconf_hist_int(val);
! 1063: userconf_hist_eoc();
! 1064:
! 1065: /* Insert the new record */
! 1066: for (i = userconf_maxdev; val <= i; i--)
! 1067: cfdata[i+1] = cfdata[i];
! 1068: cfdata[val] = new;
! 1069:
! 1070: /* Fix indexs in pv */
! 1071: for (i = 0; i < pv_size; i++) {
! 1072: if (pv[i] != -1 && pv[i] >= val)
! 1073: pv[i]++;
! 1074: }
! 1075:
! 1076: /* Fix indexs in cfroots */
! 1077: for (i = 0; i < cfroots_size; i++) {
! 1078: if (cfroots[i] != -1 && cfroots[i] >= val)
! 1079: cfroots[i]++;
! 1080: }
! 1081:
! 1082: userconf_maxdev++;
! 1083:
! 1084: max_unit = -1;
! 1085:
! 1086: /* Find max unit number of the device type */
! 1087:
! 1088: i = 0;
! 1089: while (cfdata[i].cf_attach != 0) {
! 1090: if (strlen(cfdata[i].cf_driver->cd_name) == len &&
! 1091: strncasecmp(dev, cfdata[i].cf_driver->cd_name,
! 1092: len) == 0) {
! 1093: switch (cfdata[i].cf_fstate) {
! 1094: case FSTATE_NOTFOUND:
! 1095: case FSTATE_DNOTFOUND:
! 1096: if (cfdata[i].cf_unit > max_unit)
! 1097: max_unit = cfdata[i].cf_unit;
! 1098: break;
! 1099: default:
! 1100: break;
! 1101: }
! 1102: }
! 1103: i++;
! 1104: }
! 1105:
! 1106: /*
! 1107: * For all * entries set unit number to max+1, and update
! 1108: * cf_starunit1 if necessary.
! 1109: */
! 1110: max_unit++;
! 1111: star_unit = -1;
! 1112:
! 1113: i = 0;
! 1114: while (cfdata[i].cf_attach != 0) {
! 1115: if (strlen(cfdata[i].cf_driver->cd_name) == len &&
! 1116: strncasecmp(dev, cfdata[i].cf_driver->cd_name,
! 1117: len) == 0) {
! 1118: switch (cfdata[i].cf_fstate) {
! 1119: case FSTATE_NOTFOUND:
! 1120: case FSTATE_DNOTFOUND:
! 1121: if (cfdata[i].cf_unit > star_unit)
! 1122: star_unit = cfdata[i].cf_unit;
! 1123: break;
! 1124: default:
! 1125: break;
! 1126: }
! 1127: }
! 1128: i++;
! 1129: }
! 1130: star_unit++;
! 1131:
! 1132: i = 0;
! 1133: while (cfdata[i].cf_attach != 0) {
! 1134: if (strlen(cfdata[i].cf_driver->cd_name) == len &&
! 1135: strncasecmp(dev, cfdata[i].cf_driver->cd_name,
! 1136: len) == 0) {
! 1137: switch (cfdata[i].cf_fstate) {
! 1138: case FSTATE_STAR:
! 1139: case FSTATE_DSTAR:
! 1140: cfdata[i].cf_unit = max_unit;
! 1141: if (cfdata[i].cf_starunit1 < star_unit)
! 1142: cfdata[i].cf_starunit1 =
! 1143: star_unit;
! 1144: break;
! 1145: default:
! 1146: break;
! 1147: }
! 1148: }
! 1149: i++;
! 1150: }
! 1151: userconf_pdev(val);
! 1152: }
! 1153:
! 1154: /* cf_attach, cf_driver, cf_unit, cf_fstate, cf_loc, cf_flags,
! 1155: cf_parents, cf_locnames, cf_locnames and cf_ivstubs */
! 1156: }
! 1157:
! 1158: int
! 1159: userconf_parse(char *cmd)
! 1160: {
! 1161: char *c, *v;
! 1162: int i = 0, j = 0, k, a;
! 1163: short unit, state;
! 1164:
! 1165: c = cmd;
! 1166: while (*c == ' ' || *c == '\t')
! 1167: c++;
! 1168: v = c;
! 1169: while (*c != ' ' && *c != '\t' && *c != '\n' && *c != '\0') {
! 1170: c++;
! 1171: i++;
! 1172: }
! 1173:
! 1174: k = -1;
! 1175: while (*userconf_cmds[j] != '\0') {
! 1176: if (strlen(userconf_cmds[j]) == i) {
! 1177: if (strncasecmp(v, userconf_cmds[j], i) == 0)
! 1178: k = j;
! 1179: }
! 1180: j += 2;
! 1181: }
! 1182:
! 1183: while (*c == ' ' || *c == '\t' || *c == '\n')
! 1184: c++;
! 1185:
! 1186: if (k == -1) {
! 1187: if (*v != '\n')
! 1188: printf("Unknown command, try help\n");
! 1189: } else {
! 1190: switch (*userconf_cmds[k+1]) {
! 1191: case 'L':
! 1192: if (*c == '\0')
! 1193: printf("Argument expected\n");
! 1194: else if (userconf_number(c, &a) == 0)
! 1195: userconf_lines = a;
! 1196: else
! 1197: printf("Unknown argument\n");
! 1198: break;
! 1199: case 'a':
! 1200: if (*c == '\0')
! 1201: printf("Dev expected\n");
! 1202: else if (userconf_device(c, &a, &unit, &state) == 0)
! 1203: userconf_add(c, a, unit, state);
! 1204: else
! 1205: printf("Unknown argument\n");
! 1206: break;
! 1207: case 'b':
! 1208: if (*c == '\0')
! 1209: printf("8|10|16 expected\n");
! 1210: else if (userconf_number(c, &a) == 0) {
! 1211: if (a == 8 || a == 10 || a == 16) {
! 1212: userconf_base = a;
! 1213: } else {
! 1214: printf("8|10|16 expected\n");
! 1215: }
! 1216: } else
! 1217: printf("Unknown argument\n");
! 1218: break;
! 1219: case 'c':
! 1220: if (*c == '\0')
! 1221: printf("DevNo or Dev expected\n");
! 1222: else if (userconf_number(c, &a) == 0)
! 1223: userconf_change(a);
! 1224: else if (userconf_device(c, &a, &unit, &state) == 0)
! 1225: userconf_common_dev(c, a, unit, state, UC_CHANGE);
! 1226: else
! 1227: printf("Unknown argument\n");
! 1228: break;
! 1229: #if defined(DDB)
! 1230: case 'D':
! 1231: Debugger();
! 1232: break;
! 1233: #endif
! 1234: case 'd':
! 1235: if (*c == '\0')
! 1236: printf("Attr, DevNo or Dev expected\n");
! 1237: else if (userconf_attr(c, &a) == 0)
! 1238: userconf_common_attr(c, a, UC_DISABLE);
! 1239: else if (userconf_number(c, &a) == 0)
! 1240: userconf_disable(a);
! 1241: else if (userconf_device(c, &a, &unit, &state) == 0)
! 1242: userconf_common_dev(c, a, unit, state, UC_DISABLE);
! 1243: else
! 1244: printf("Unknown argument\n");
! 1245: break;
! 1246: case 'e':
! 1247: if (*c == '\0')
! 1248: printf("Attr, DevNo or Dev expected\n");
! 1249: else if (userconf_attr(c, &a) == 0)
! 1250: userconf_common_attr(c, a, UC_ENABLE);
! 1251: else if (userconf_number(c, &a) == 0)
! 1252: userconf_enable(a);
! 1253: else if (userconf_device(c, &a, &unit, &state) == 0)
! 1254: userconf_common_dev(c, a, unit, state, UC_ENABLE);
! 1255: else
! 1256: printf("Unknown argument\n");
! 1257: break;
! 1258: case 'f':
! 1259: if (*c == '\0')
! 1260: printf("DevNo or Dev expected\n");
! 1261: else if (userconf_number(c, &a) == 0)
! 1262: userconf_pdev(a);
! 1263: else if (userconf_device(c, &a, &unit, &state) == 0)
! 1264: userconf_common_dev(c, a, unit, state, UC_FIND);
! 1265: else
! 1266: printf("Unknown argument\n");
! 1267: break;
! 1268: case 'h':
! 1269: userconf_help();
! 1270: break;
! 1271: case 'l':
! 1272: if (*c == '\0')
! 1273: userconf_list();
! 1274: else
! 1275: printf("Unknown argument\n");
! 1276: break;
! 1277: case 'q':
! 1278: /* XXX add cmd 'q' eoc */
! 1279: userconf_hist_cmd('q');
! 1280: userconf_hist_eoc();
! 1281: return(-1);
! 1282: break;
! 1283: case 's':
! 1284: if (*c == '\0')
! 1285: userconf_show();
! 1286: else
! 1287: userconf_show_attr(c);
! 1288: break;
! 1289: case 't':
! 1290: if (*c == '\0' || userconf_number(c, &a) == 0) {
! 1291: if (*c != '\0') {
! 1292: tz.tz_minuteswest = a;
! 1293: while (*c != '\n' && *c != '\t' &&
! 1294: *c != ' ' && *c != '\0')
! 1295: c++;
! 1296: while (*c == '\t' || *c == ' ')
! 1297: c++;
! 1298: if (*c != '\0' &&
! 1299: userconf_number(c, &a) == 0)
! 1300: tz.tz_dsttime = a;
! 1301: userconf_hist_cmd('t');
! 1302: userconf_hist_int(tz.tz_minuteswest);
! 1303: userconf_hist_int(tz.tz_dsttime);
! 1304: userconf_hist_eoc();
! 1305: }
! 1306: printf("timezone = %d, dst = %d\n",
! 1307: tz.tz_minuteswest, tz.tz_dsttime);
! 1308: } else
! 1309: printf("Unknown argument\n");
! 1310: break;
! 1311: case 'v':
! 1312: autoconf_verbose = !autoconf_verbose;
! 1313: printf("autoconf verbose %sabled\n",
! 1314: autoconf_verbose ? "en" : "dis");
! 1315: break;
! 1316: default:
! 1317: printf("Unknown command\n");
! 1318: break;
! 1319: }
! 1320: }
! 1321: return(0);
! 1322: }
! 1323:
! 1324: void
! 1325: user_config(void)
! 1326: {
! 1327: userconf_init();
! 1328: printf("User Kernel Config\n");
! 1329:
! 1330: while (1) {
! 1331: printf("UKC> ");
! 1332: if (getsn(userconf_cmdbuf, sizeof(userconf_cmdbuf)) > 0 &&
! 1333: userconf_parse(userconf_cmdbuf))
! 1334: break;
! 1335: }
! 1336: printf("Continuing...\n");
! 1337: }
CVSweb