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