1 /* $OpenBSD: subr_userconf.c,v 1.15 1998/03/03 05:43:03 deraadt Exp $ */ 2 3 /* 4 * Copyright (c) 1996 Mats O Jansson <moj@stacken.kth.se> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Mats O Jansson. 18 * 4. The name of the author may not be used to endorse or promote 19 * products derived from this software without specific prior written 20 * permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 23 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 24 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 26 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35 #include <sys/param.h> 36 #include <sys/systm.h> 37 #include <sys/device.h> 38 #include <sys/malloc.h> 39 40 #include <dev/cons.h> 41 42 extern char *locnames[]; 43 extern short locnamp[]; 44 extern short cfroots[]; 45 extern int cfroots_size; 46 extern int pv_size; 47 extern short pv[]; 48 49 int userconf_base = 16; /* Base for "large" numbers */ 50 int userconf_maxdev = -1; /* # of used device slots */ 51 int userconf_totdev = -1; /* # of device slots */ 52 int userconf_maxlocnames = -1; /* # of locnames */ 53 int userconf_cnt = -1; /* Line counter for ... */ 54 int userconf_lines = 12; /* ... # of lines per page */ 55 char userconf_argbuf[40]; /* Additional input */ 56 char userconf_cmdbuf[40]; /* Command line */ 57 58 void userconf_init __P((void)); 59 int userconf_more __P((void)); 60 void userconf_modify __P((char *, int*)); 61 void userconf_pnum __P((int)); 62 void userconf_pdevnam __P((short)); 63 void userconf_pdev __P((short)); 64 int userconf_number __P((char *, int *)); 65 int userconf_device __P((char *, int *, short *, short *)); 66 int userconf_attr __P((char *, int *)); 67 void userconf_modify __P((char *, int *)); 68 void userconf_change __P((int)); 69 void userconf_disable __P((int)); 70 void userconf_enable __P((int)); 71 void userconf_help __P((void)); 72 void userconf_list __P((void)); 73 void userconf_show __P((void)); 74 void userconf_common_attr_val __P((short, int *, char)); 75 void userconf_show_attr __P((char *)); 76 void userconf_common_dev __P((char *, int, short, short, char)); 77 void userconf_common_attr __P((char *, int, char)); 78 void userconf_add_read __P((char *, char, char *, int, int *)); 79 void userconf_add __P((char *, int, short, short)); 80 int userconf_parse __P((char *)); 81 82 #define UC_CHANGE 'c' 83 #define UC_DISABLE 'd' 84 #define UC_ENABLE 'e' 85 #define UC_FIND 'f' 86 #define UC_SHOW 's' 87 88 char *userconf_cmds[] = { 89 "add", "a", 90 "base", "b", 91 "change", "c", 92 "disable", "d", 93 "enable", "e", 94 "exit", "q", 95 "find", "f", 96 "help", "h", 97 "list", "l", 98 "lines", "L", 99 "quit", "q", 100 "show", "s", 101 "?", "h", 102 "", "", 103 }; 104 105 void 106 userconf_init() 107 { 108 int i = 0; 109 struct cfdata *cd; 110 int ln; 111 112 while (cfdata[i].cf_attach != 0) { 113 userconf_maxdev = i; 114 userconf_totdev = i; 115 116 cd = &cfdata[i]; 117 ln = cd->cf_locnames; 118 while (locnamp[ln] != -1) { 119 if (locnamp[ln] > userconf_maxlocnames) 120 userconf_maxlocnames = locnamp[ln]; 121 ln++; 122 } 123 i++; 124 } 125 126 while (cfdata[i].cf_attach == 0) { 127 userconf_totdev = i; 128 i++; 129 } 130 userconf_totdev = userconf_totdev - 1; 131 } 132 133 int 134 userconf_more() 135 { 136 int quit = 0; 137 char c; 138 139 if (userconf_cnt != -1) { 140 if (userconf_cnt == userconf_lines) { 141 printf("--- more ---"); 142 c = cngetc(); 143 userconf_cnt = 0; 144 printf("\r \r"); 145 } 146 userconf_cnt++; 147 if (c == 'q' || c == 'Q') 148 quit = 1; 149 } 150 return (quit); 151 } 152 153 void 154 userconf_pnum(val) 155 int val; 156 { 157 if (val > -2 && val < 16) { 158 printf("%d",val); 159 } else { 160 switch (userconf_base) { 161 case 8: 162 printf("0%o",val); 163 break; 164 case 10: 165 printf("%d",val); 166 break; 167 case 16: 168 default: 169 printf("0x%x",val); 170 break; 171 } 172 } 173 } 174 175 void 176 userconf_pdevnam(dev) 177 short dev; 178 { 179 struct cfdata *cd; 180 181 cd = &cfdata[dev]; 182 printf("%s", cd->cf_driver->cd_name); 183 switch (cd->cf_fstate) { 184 case FSTATE_NOTFOUND: 185 case FSTATE_DNOTFOUND: 186 printf("%d", cd->cf_unit); 187 break; 188 case FSTATE_FOUND: 189 printf("*FOUND*"); 190 break; 191 case FSTATE_STAR: 192 case FSTATE_DSTAR: 193 printf("*"); 194 break; 195 default: 196 printf("*UNKNOWN*"); 197 break; 198 } 199 } 200 201 void 202 userconf_pdev(devno) 203 short devno; 204 { 205 struct cfdata *cd; 206 short *p; 207 int *l; 208 int ln; 209 char c; 210 211 if (devno > userconf_maxdev) { 212 printf("Unknown devno (max is %d)\n", userconf_maxdev); 213 return; 214 } 215 216 cd = &cfdata[devno]; 217 218 printf("%3d ", devno); 219 userconf_pdevnam(devno); 220 printf(" at"); 221 c = ' '; 222 p = cd->cf_parents; 223 if (*p == -1) 224 printf(" root"); 225 while (*p != -1) { 226 printf("%c", c); 227 userconf_pdevnam(*p++); 228 c = '|'; 229 } 230 switch (cd->cf_fstate) { 231 case FSTATE_NOTFOUND: 232 case FSTATE_FOUND: 233 case FSTATE_STAR: 234 break; 235 case FSTATE_DNOTFOUND: 236 case FSTATE_DSTAR: 237 printf(" disable"); 238 break; 239 default: 240 printf(" ???"); 241 break; 242 } 243 l = cd->cf_loc; 244 ln = cd->cf_locnames; 245 while (locnamp[ln] != -1) { 246 printf(" %s ", locnames[locnamp[ln]]); 247 ln++; 248 userconf_pnum(*l++); 249 } 250 printf("\n"); 251 } 252 253 int 254 userconf_number(c, val) 255 char *c; 256 int *val; 257 { 258 u_int num = 0; 259 int neg = 0; 260 int base = 10; 261 262 if (*c == '-') { 263 neg = 1; 264 c++; 265 } 266 if (*c == '0') { 267 base = 8; 268 c++; 269 if (*c == 'x' || *c == 'X') { 270 base = 16; 271 c++; 272 } 273 } 274 while (*c != '\n' && *c != '\t' && *c != ' ' && *c != '\0') { 275 u_char cc = *c; 276 277 if (cc >= '0' && cc <= '9') 278 cc = cc - '0'; 279 else if (cc >= 'a' && cc <= 'f') 280 cc = cc - 'a' + 10; 281 else if (cc >= 'A' && cc <= 'F') 282 cc = cc - 'A' + 10; 283 else 284 return (-1); 285 286 if (cc > base) 287 return (-1); 288 num = num * base + cc; 289 c++; 290 } 291 292 if (neg && num > INT_MAX) /* overflow */ 293 return (1); 294 *val = neg ? - num : num; 295 return (0); 296 } 297 298 int 299 userconf_device(cmd, len, unit, state) 300 char *cmd; 301 int *len; 302 short *unit, *state; 303 { 304 short u = 0, s = FSTATE_FOUND; 305 int l = 0; 306 char *c; 307 308 c = cmd; 309 while (*c >= 'a' && *c <= 'z') { 310 l++; 311 c++; 312 } 313 if (*c == '*') { 314 s = FSTATE_STAR; 315 c++; 316 } else { 317 while (*c >= '0' && *c <= '9') { 318 s = FSTATE_NOTFOUND; 319 u = u*10 + *c - '0'; 320 c++; 321 } 322 } 323 while (*c == ' ' || *c == '\t' || *c == '\n') 324 c++; 325 326 if (*c == '\0') { 327 *len = l; 328 *unit = u; 329 *state = s; 330 return(0); 331 } 332 333 return(-1); 334 } 335 336 int 337 userconf_attr(cmd, val) 338 char *cmd; 339 int *val; 340 { 341 char *c; 342 short attr = -1, i = 0, l = 0; 343 344 c = cmd; 345 while (*c != ' ' && *c != '\t' && *c != '\n' && *c != '\0') { 346 c++; 347 l++; 348 } 349 350 while (i <= userconf_maxlocnames) { 351 if (strlen(locnames[i]) == l) { 352 if (strncasecmp(cmd, locnames[i], l) == 0) 353 attr = i; 354 } 355 i++; 356 } 357 358 if (attr == -1) { 359 return (-1); 360 } 361 362 *val = attr; 363 364 return(0); 365 } 366 367 void 368 userconf_modify(item, val) 369 char *item; 370 int *val; 371 { 372 int ok = 0; 373 int a; 374 char *c; 375 int i; 376 377 while (!ok) { 378 printf("%s [", item); 379 userconf_pnum(*val); 380 printf("] ? "); 381 382 i = getsn(userconf_argbuf, sizeof(userconf_argbuf)); 383 384 c = userconf_argbuf; 385 while (*c == ' ' || *c == '\t' || *c == '\n') c++; 386 387 if (*c != '\0') { 388 if (userconf_number(c, &a) == 0) { 389 *val = a; 390 ok = 1; 391 } else { 392 printf("Unknown argument\n"); 393 } 394 } else { 395 ok = 1; 396 } 397 } 398 } 399 400 void 401 userconf_change(devno) 402 int devno; 403 { 404 struct cfdata *cd; 405 char c = '\0'; 406 int *l; 407 int ln; 408 409 if (devno <= userconf_maxdev) { 410 411 userconf_pdev(devno); 412 413 while (c != 'y' && c != 'Y' && c != 'n' && c != 'N') { 414 printf("change (y/n) ?"); 415 c = cngetc(); 416 printf("\n"); 417 } 418 419 if (c == 'y' || c == 'Y') { 420 int share = 0, i, *lk; 421 422 cd = &cfdata[devno]; 423 l = cd->cf_loc; 424 ln = cd->cf_locnames; 425 426 /* 427 * Search for some other driver sharing this 428 * locator table. if one does, we may need to 429 * replace the locators with a malloc'd copy. 430 */ 431 for (i = 0; cfdata[i].cf_driver; i++) 432 if (i != devno && cfdata[i].cf_loc == l) 433 share = 1; 434 if (share) { 435 for (i = 0; locnamp[ln+i] != -1 ; i++) 436 ; 437 lk = l = (int *)malloc(sizeof(int) * i, 438 M_TEMP, M_NOWAIT); 439 bcopy(cd->cf_loc, l, sizeof(int) * i); 440 } 441 442 while (locnamp[ln] != -1) { 443 userconf_modify(locnames[locnamp[ln]], 444 l); 445 ln++; 446 l++; 447 } 448 449 if (share) { 450 if (bcmp(cd->cf_loc, lk, sizeof(int) * i)) 451 cd->cf_loc = lk; 452 else 453 free(lk, M_TEMP); 454 } 455 456 printf("%3d ", devno); 457 userconf_pdevnam(devno); 458 printf(" changed\n"); 459 userconf_pdev(devno); 460 } 461 } else { 462 printf("Unknown devno (max is %d)\n", userconf_maxdev); 463 } 464 } 465 466 void 467 userconf_disable(devno) 468 int devno; 469 { 470 int done = 0; 471 472 if (devno <= userconf_maxdev) { 473 switch (cfdata[devno].cf_fstate) { 474 case FSTATE_NOTFOUND: 475 cfdata[devno].cf_fstate = FSTATE_DNOTFOUND; 476 break; 477 case FSTATE_STAR: 478 cfdata[devno].cf_fstate = FSTATE_DSTAR; 479 break; 480 case FSTATE_DNOTFOUND: 481 case FSTATE_DSTAR: 482 done = 1; 483 break; 484 default: 485 printf("Error unknown state\n"); 486 break; 487 } 488 489 printf("%3d ", devno); 490 userconf_pdevnam(devno); 491 if (done) 492 printf(" already"); 493 printf(" disabled\n"); 494 } else { 495 printf("Unknown devno (max is %d)\n", userconf_maxdev); 496 } 497 } 498 499 void 500 userconf_enable(devno) 501 int devno; 502 { 503 int done = 0; 504 505 if (devno <= userconf_maxdev) { 506 switch (cfdata[devno].cf_fstate) { 507 case FSTATE_DNOTFOUND: 508 cfdata[devno].cf_fstate = FSTATE_NOTFOUND; 509 break; 510 case FSTATE_DSTAR: 511 cfdata[devno].cf_fstate = FSTATE_STAR; 512 break; 513 case FSTATE_NOTFOUND: 514 case FSTATE_STAR: 515 done = 1; 516 break; 517 default: 518 printf("Error unknown state\n"); 519 break; 520 } 521 522 printf("%3d ", devno); 523 userconf_pdevnam(devno); 524 if (done) 525 printf(" already"); 526 printf(" enabled\n"); 527 } else { 528 printf("Unknown devno (max is %d)\n", userconf_maxdev); 529 } 530 } 531 532 void 533 userconf_help() 534 { 535 int j = 0, k; 536 537 printf("command args description\n"); 538 while (*userconf_cmds[j] != '\0') { 539 printf(userconf_cmds[j]); 540 k=strlen(userconf_cmds[j]); 541 while (k < 10) { 542 printf(" "); 543 k++; 544 } 545 switch (*userconf_cmds[j+1]) { 546 case 'L': 547 printf("[count] number of lines before more"); 548 break; 549 case 'a': 550 printf("dev add a device"); 551 break; 552 case 'b': 553 printf("8|10|16 base on large numbers"); 554 break; 555 case 'c': 556 printf("devno|dev change devices"); 557 break; 558 case 'd': 559 printf("attr val|devno|dev disable devices"); 560 break; 561 case 'e': 562 printf("attr val|devno|dev enable devices"); 563 break; 564 case 'f': 565 printf("devno|dev find devices"); 566 break; 567 case 'h': 568 printf(" this message"); 569 break; 570 case 'l': 571 printf(" list configuration"); 572 break; 573 case 'q': 574 printf(" leave UKC"); 575 break; 576 case 's': 577 printf("[attr [val]] %s", 578 "show attributes (or devices with an attribute)"); 579 break; 580 default: 581 printf(" don't know"); 582 break; 583 } 584 printf("\n"); 585 j += 2; 586 } 587 } 588 589 void 590 userconf_list() 591 { 592 int i = 0; 593 594 userconf_cnt = 0; 595 596 while (cfdata[i].cf_attach != 0) { 597 if (userconf_more()) 598 break; 599 userconf_pdev(i++); 600 } 601 602 userconf_cnt = -1; 603 } 604 605 void 606 userconf_show() 607 { 608 int i = 0; 609 610 userconf_cnt = 0; 611 612 while (i <= userconf_maxlocnames) { 613 if (userconf_more()) 614 break; 615 printf("%s\n", locnames[i++]); 616 } 617 618 userconf_cnt = -1; 619 } 620 621 void 622 userconf_common_attr_val(attr, val, routine) 623 short attr; 624 int *val; 625 char routine; 626 { 627 struct cfdata *cd; 628 int *l; 629 int ln; 630 int i = 0, quit = 0; 631 632 userconf_cnt = 0; 633 634 while (i <= userconf_maxdev) { 635 cd = &cfdata[i]; 636 l = cd->cf_loc; 637 ln = cd->cf_locnames; 638 while (locnamp[ln] != -1) { 639 if (locnamp[ln] == attr) { 640 if (val == NULL) { 641 quit = userconf_more(); 642 userconf_pdev(i); 643 } else { 644 if (*val == *l) { 645 quit = userconf_more(); 646 switch (routine) { 647 case UC_ENABLE: 648 userconf_enable(i); 649 break; 650 case UC_DISABLE: 651 userconf_disable(i); 652 break; 653 case UC_SHOW: 654 userconf_pdev(i); 655 break; 656 default: 657 printf("Unknown routine /%c/\n", 658 routine); 659 break; 660 } 661 } 662 } 663 } 664 if (quit) 665 break; 666 ln++; 667 l++; 668 } 669 if (quit) 670 break; 671 i++; 672 } 673 674 userconf_cnt = -1; 675 } 676 677 void 678 userconf_show_attr(cmd) 679 char *cmd; 680 { 681 char *c; 682 short attr = -1, i = 0, l = 0; 683 int a; 684 685 c = cmd; 686 while (*c != ' ' && *c != '\t' && *c != '\n' && *c != '\0') { 687 c++; 688 l++; 689 } 690 while (*c == ' ' || *c == '\t' || *c == '\n') { 691 c++; 692 } 693 while (i <= userconf_maxlocnames) { 694 if (strlen(locnames[i]) == l) { 695 if (strncasecmp(cmd, locnames[i], l) == 0) { 696 attr = i; 697 } 698 } 699 i++; 700 } 701 702 if (attr == -1) { 703 printf("Unknown attribute\n"); 704 return; 705 } 706 707 if (*c == '\0') { 708 userconf_common_attr_val(attr, NULL, UC_SHOW); 709 } else { 710 if (userconf_number(c, &a) == 0) { 711 userconf_common_attr_val(attr, &a, UC_SHOW); 712 } else { 713 printf("Unknown argument\n"); 714 } 715 } 716 } 717 718 void 719 userconf_common_dev(dev, len, unit, state, routine) 720 char *dev; 721 int len; 722 short unit, state; 723 char routine; 724 { 725 int i = 0; 726 727 switch (routine) { 728 case UC_CHANGE: 729 break; 730 default: 731 userconf_cnt = 0; 732 break; 733 } 734 735 while (cfdata[i].cf_attach != 0) { 736 if (strlen(cfdata[i].cf_driver->cd_name) == len) { 737 738 /* 739 * Ok, if device name is correct 740 * If state == FSTATE_FOUND, look for "dev" 741 * If state == FSTATE_STAR, look for "dev*" 742 * If state == FSTATE_NOTFOUND, look for "dev0" 743 */ 744 if (strncasecmp(dev, cfdata[i].cf_driver->cd_name, 745 len) == 0 && 746 (state == FSTATE_FOUND || 747 (state == FSTATE_STAR && 748 (cfdata[i].cf_fstate == FSTATE_STAR || 749 cfdata[i].cf_fstate == FSTATE_DSTAR)) || 750 (state == FSTATE_NOTFOUND && 751 cfdata[i].cf_unit == unit && 752 (cfdata[i].cf_fstate == FSTATE_NOTFOUND || 753 cfdata[i].cf_fstate == FSTATE_DNOTFOUND)))) { 754 if (userconf_more()) 755 break; 756 switch (routine) { 757 case UC_CHANGE: 758 userconf_change(i); 759 break; 760 case UC_ENABLE: 761 userconf_enable(i); 762 break; 763 case UC_DISABLE: 764 userconf_disable(i); 765 break; 766 case UC_FIND: 767 userconf_pdev(i); 768 break; 769 default: 770 printf("Unknown routine /%c/\n", 771 routine); 772 break; 773 } 774 } 775 } 776 i++; 777 } 778 779 switch (routine) { 780 case UC_CHANGE: 781 break; 782 default: 783 userconf_cnt = -1; 784 break; 785 } 786 } 787 788 void 789 userconf_common_attr(cmd, attr, routine) 790 char *cmd; 791 int attr; 792 char routine; 793 { 794 char *c; 795 short l = 0; 796 int a; 797 798 c = cmd; 799 while (*c != ' ' && *c != '\t' && *c != '\n' && *c != '\0') { 800 c++; 801 l++; 802 } 803 while (*c == ' ' || *c == '\t' || *c == '\n') { 804 c++; 805 } 806 if (*c == '\0') { 807 printf("Value missing for attribute\n"); 808 return; 809 } 810 811 if (userconf_number(c, &a) == 0) { 812 userconf_common_attr_val(attr, &a, routine); 813 } else { 814 printf("Unknown argument\n"); 815 } 816 } 817 818 void 819 userconf_add_read(prompt, field, dev, len, val) 820 char *prompt; 821 char field; 822 char *dev; 823 int len; 824 int *val; 825 { 826 int ok = 0; 827 int a; 828 char *c; 829 int i; 830 831 *val = -1; 832 833 while (!ok) { 834 printf("%s ? ", prompt); 835 836 i = getsn(userconf_argbuf, sizeof(userconf_argbuf)); 837 838 c = userconf_argbuf; 839 while (*c == ' ' || *c == '\t' || *c == '\n') c++; 840 841 if (*c != '\0') { 842 if (userconf_number(c, &a) == 0) { 843 if (a > userconf_maxdev) { 844 printf("Unknown devno (max is %d)\n", 845 userconf_maxdev); 846 } else if (strncasecmp(dev, 847 cfdata[a].cf_driver->cd_name, len) != 0) { 848 printf("Not same device type\n"); 849 } else { 850 *val = a; 851 ok = 1; 852 } 853 } else if (*c == '?') { 854 userconf_common_dev(dev, len, 0, 855 FSTATE_FOUND, UC_FIND); 856 } else if (*c == 'q' || *c == 'Q') { 857 ok = 1; 858 } else { 859 printf("Unknown argument\n"); 860 } 861 } else { 862 ok = 1; 863 } 864 } 865 } 866 867 void 868 userconf_add(dev, len, unit, state) 869 char *dev; 870 int len; 871 short unit, state; 872 { 873 int i = 0, found = 0; 874 struct cfdata new; 875 int val, max_unit; 876 877 bzero(&new, sizeof(struct cfdata)); 878 879 if (userconf_maxdev == userconf_totdev) { 880 printf("No more space for new devices.\n"); 881 return; 882 } 883 884 if (state == FSTATE_FOUND) { 885 printf("Device not complete number or * is missing/n"); 886 return; 887 } 888 889 for (i = 0; cfdata[i].cf_driver; i++) 890 if (strlen(cfdata[i].cf_driver->cd_name) == len && 891 strncasecmp(dev, cfdata[i].cf_driver->cd_name, len) == 0) 892 found = 1; 893 894 if (!found) { 895 printf("No device of this type exists.\n"); 896 return; 897 } 898 899 userconf_add_read("Clone Device (DevNo, 'q' or '?')", 900 'a', dev, len, &val); 901 902 if (val != -1) { 903 new = cfdata[val]; 904 new.cf_unit = unit; 905 new.cf_fstate = state; 906 userconf_add_read("Insert before Device (DevNo, 'q' or '?')", 907 'i', dev, len, &val); 908 } 909 910 if (val != -1) { 911 912 /* Insert the new record */ 913 for (i = userconf_maxdev; val <= i; i--) 914 cfdata[i+1] = cfdata[i]; 915 cfdata[val] = new; 916 917 /* Fix indexs in pv */ 918 for (i = 0; i < pv_size; i++) { 919 if ((pv[i] != -1) && (pv[i] >= val)) 920 pv[i] = pv[i]++; 921 } 922 923 /* Fix indexs in cfroots */ 924 for (i = 0; i < cfroots_size; i++) { 925 if ((cfroots[i] != -1) && (cfroots[i] >= val)) 926 cfroots[i] = cfroots[i]++; 927 } 928 929 userconf_maxdev++; 930 931 max_unit = -1; 932 933 /* Find max unit number of the device type */ 934 935 i = 0; 936 while (cfdata[i].cf_attach != 0) { 937 if (strlen(cfdata[i].cf_driver->cd_name) == len && 938 strncasecmp(dev, cfdata[i].cf_driver->cd_name, 939 len) == 0) { 940 switch (cfdata[i].cf_fstate) { 941 case FSTATE_NOTFOUND: 942 case FSTATE_DNOTFOUND: 943 if (cfdata[i].cf_unit > max_unit) 944 max_unit = cfdata[i].cf_unit; 945 break; 946 default: 947 break; 948 } 949 } 950 i++; 951 } 952 953 /* For all * entries set unit number to max+1 */ 954 955 max_unit++; 956 957 i = 0; 958 while (cfdata[i].cf_attach != 0) { 959 if (strlen(cfdata[i].cf_driver->cd_name) == len && 960 strncasecmp(dev, cfdata[i].cf_driver->cd_name, 961 len) == 0) { 962 switch (cfdata[i].cf_fstate) { 963 case FSTATE_STAR: 964 case FSTATE_DSTAR: 965 cfdata[i].cf_unit = max_unit; 966 break; 967 default: 968 break; 969 } 970 } 971 i++; 972 } 973 userconf_pdev(val); 974 } 975 976 /* cf_attach, cf_driver, cf_unit, cf_state, cf_loc, cf_flags, 977 cf_parents, cf_locnames, cf_locnames and cf_ivstubs */ 978 } 979 980 int 981 userconf_parse(cmd) 982 char *cmd; 983 { 984 char *c, *v; 985 int i = 0, j = 0, k, a; 986 short unit, state; 987 988 c = cmd; 989 while (*c == ' ' || *c == '\t') 990 c++; 991 v = c; 992 while (*c != ' ' && *c != '\t' && *c != '\n' && *c != '\0') { 993 c++; 994 i++; 995 } 996 997 k = -1; 998 while (*userconf_cmds[j] != '\0') { 999 if (strlen(userconf_cmds[j]) == i) { 1000 if (strncasecmp(v, userconf_cmds[j], i) == 0) 1001 k = j; 1002 } 1003 j += 2; 1004 } 1005 1006 while (*c == ' ' || *c == '\t' || *c == '\n') 1007 c++; 1008 1009 if (k == -1) { 1010 if (*v != '\n') 1011 printf("Unknown command, try help\n"); 1012 } else { 1013 switch (*userconf_cmds[k+1]) { 1014 case 'L': 1015 if (*c == '\0') 1016 printf("Argument expected\n"); 1017 else if (userconf_number(c, &a) == 0) 1018 userconf_lines = a; 1019 else 1020 printf("Unknown argument\n"); 1021 break; 1022 case 'a': 1023 if (*c == '\0') 1024 printf("Dev expected\n"); 1025 else if (userconf_device(c, &a, &unit, &state) == 0) 1026 userconf_add(c, a, unit, state); 1027 else 1028 printf("Unknown argument\n"); 1029 break; 1030 case 'b': 1031 if (*c == '\0') 1032 printf("8|10|16 expected\n"); 1033 else if (userconf_number(c, &a) == 0) { 1034 if (a == 8 || a == 10 || a == 16) { 1035 userconf_base = a; 1036 } else { 1037 printf("8|10|16 expected\n"); 1038 } 1039 } else 1040 printf("Unknown argument\n"); 1041 break; 1042 case 'c': 1043 if (*c == '\0') 1044 printf("DevNo or Dev expected\n"); 1045 else if (userconf_number(c, &a) == 0) 1046 userconf_change(a); 1047 else if (userconf_device(c, &a, &unit, &state) == 0) 1048 userconf_common_dev(c, a, unit, state, UC_CHANGE); 1049 else 1050 printf("Unknown argument\n"); 1051 break; 1052 case 'd': 1053 if (*c == '\0') 1054 printf("Attr, DevNo or Dev expected\n"); 1055 else if (userconf_attr(c, &a) == 0) 1056 userconf_common_attr(c, a, UC_DISABLE); 1057 else if (userconf_number(c, &a) == 0) 1058 userconf_disable(a); 1059 else if (userconf_device(c, &a, &unit, &state) == 0) 1060 userconf_common_dev(c, a, unit, state, UC_DISABLE); 1061 else 1062 printf("Unknown argument\n"); 1063 break; 1064 case 'e': 1065 if (*c == '\0') 1066 printf("Attr, DevNo or Dev expected\n"); 1067 else if (userconf_attr(c, &a) == 0) 1068 userconf_common_attr(c, a, UC_ENABLE); 1069 else if (userconf_number(c, &a) == 0) 1070 userconf_enable(a); 1071 else if (userconf_device(c, &a, &unit, &state) == 0) 1072 userconf_common_dev(c, a, unit, state, UC_ENABLE); 1073 else 1074 printf("Unknown argument\n"); 1075 break; 1076 case 'f': 1077 if (*c == '\0') 1078 printf("DevNo or Dev expected\n"); 1079 else if (userconf_number(c, &a) == 0) 1080 userconf_pdev(a); 1081 else if (userconf_device(c, &a, &unit, &state) == 0) 1082 userconf_common_dev(c, a, unit, state, UC_FIND); 1083 else 1084 printf("Unknown argument\n"); 1085 break; 1086 case 'h': 1087 userconf_help(); 1088 break; 1089 case 'l': 1090 if (*c == '\0') 1091 userconf_list(); 1092 else 1093 printf("Unknown argument\n"); 1094 break; 1095 case 'q': 1096 return(-1); 1097 break; 1098 case 's': 1099 if (*c == '\0') 1100 userconf_show(); 1101 else 1102 userconf_show_attr(c); 1103 break; 1104 default: 1105 printf("Unknown command\n"); 1106 break; 1107 } 1108 } 1109 return(0); 1110 } 1111 1112 void 1113 user_config() 1114 { 1115 char prompt[] = "UKC> "; 1116 1117 userconf_init(); 1118 printf("User Kernel Config\n"); 1119 1120 while (1) { 1121 printf(prompt); 1122 if (getsn(userconf_cmdbuf, sizeof(userconf_cmdbuf)) > 0 && 1123 userconf_parse(userconf_cmdbuf)) 1124 break; 1125 } 1126 printf("Continuing...\n"); 1127 } 1128