The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/subr_userconf.c

Version: -  FREEBSD  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

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

Cache object: f91a2b2e52799d520d15e1cb4b387633


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.