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 /*      $NetBSD: subr_userconf.c,v 1.18 2005/12/11 12:24:30 christos 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  *      OpenBSD: subr_userconf.c,v 1.19 2000/01/08 23:23:37 d Exp
   35  */
   36 
   37 #include <sys/cdefs.h>
   38 __KERNEL_RCSID(0, "$NetBSD: subr_userconf.c,v 1.18 2005/12/11 12:24:30 christos Exp $");
   39 
   40 #include "opt_userconf.h"
   41 
   42 #include <sys/param.h>
   43 #include <sys/systm.h>
   44 #include <sys/device.h>
   45 #include <sys/malloc.h>
   46 #include <sys/time.h>
   47 
   48 #include <dev/cons.h>
   49 
   50 extern struct cfdata cfdata[];
   51 
   52 static int userconf_base = 16;                  /* Base for "large" numbers */
   53 static int userconf_maxdev = -1;                /* # of used device slots   */
   54 static int userconf_totdev = -1;                /* # of device slots        */
   55 #if 0
   56 static int userconf_maxlocnames = -1;           /* # of locnames            */
   57 #endif
   58 static int userconf_cnt = -1;                   /* Line counter for ...     */
   59 static int userconf_lines = 12;                 /* ... # of lines per page  */
   60 static int userconf_histlen = 0;
   61 static int userconf_histcur = 0;
   62 static char userconf_history[1024];
   63 static int userconf_histsz = sizeof(userconf_history);
   64 static char userconf_argbuf[40];                /* Additional input         */
   65 static char userconf_cmdbuf[40];                /* Command line             */
   66 static char userconf_histbuf[40];
   67 
   68 static int getsn(char *, int);
   69 
   70 #define UC_CHANGE 'c'
   71 #define UC_DISABLE 'd'
   72 #define UC_ENABLE 'e'
   73 #define UC_FIND 'f'
   74 #define UC_SHOW 's'
   75 
   76 static const char *userconf_cmds[] = {
   77         "base",         "b",
   78         "change",       "c",
   79         "disable",      "d",
   80         "enable",       "e",
   81         "exit",         "q",
   82         "find",         "f",
   83         "help",         "h",
   84         "list",         "l",
   85         "lines",        "L",
   86         "quit",         "q",
   87         "?",            "h",
   88         "",              "",
   89 };
   90 
   91 static void
   92 userconf_init(void)
   93 {
   94         int i;
   95         struct cfdata *cf;
   96 
   97         i = 0;
   98         for (cf = cfdata; cf->cf_name; cf++)
   99                 i++;
  100 
  101         userconf_maxdev = i - 1;
  102         userconf_totdev = i - 1;
  103 }
  104 
  105 static int
  106 userconf_more(void)
  107 {
  108         int quit = 0;
  109         char c = '\0';
  110 
  111         if (userconf_cnt != -1) {
  112                 if (userconf_cnt == userconf_lines) {
  113                         printf("-- more --");
  114                         c = cngetc();
  115                         userconf_cnt = 0;
  116                         printf("\r            \r");
  117                 }
  118                 userconf_cnt++;
  119                 if (c == 'q' || c == 'Q')
  120                         quit = 1;
  121         }
  122         return (quit);
  123 }
  124 
  125 static void
  126 userconf_hist_cmd(char cmd)
  127 {
  128         userconf_histcur = userconf_histlen;
  129         if (userconf_histcur < userconf_histsz) {
  130                 userconf_history[userconf_histcur] = cmd;
  131                 userconf_histcur++;
  132         }
  133 }
  134 
  135 static void
  136 userconf_hist_int(int val)
  137 {
  138         snprintf(userconf_histbuf, sizeof(userconf_histbuf), " %d", val);
  139         if ((userconf_histcur + strlen(userconf_histbuf)) < userconf_histsz) {
  140                 memcpy(&userconf_history[userconf_histcur],
  141                       userconf_histbuf,
  142                       strlen(userconf_histbuf));
  143                 userconf_histcur = userconf_histcur + strlen(userconf_histbuf);
  144         }
  145 }
  146 
  147 static void
  148 userconf_hist_eoc(void)
  149 {
  150         if (userconf_histcur < userconf_histsz) {
  151                 userconf_history[userconf_histcur] = '\n';
  152                 userconf_histcur++;
  153                 userconf_histlen = userconf_histcur;
  154         }
  155 }
  156 
  157 static void
  158 userconf_pnum(int val)
  159 {
  160         if (val > -2 && val < 16) {
  161                 printf("%d",val);
  162         } else {
  163                 switch (userconf_base) {
  164                 case 8:
  165                         printf("0%o",val);
  166                         break;
  167                 case 10:
  168                         printf("%d",val);
  169                         break;
  170                 case 16:
  171                 default:
  172                         printf("0x%x",val);
  173                         break;
  174                 }
  175         }
  176 }
  177 
  178 static void
  179 userconf_pdevnam(short dev)
  180 {
  181         struct cfdata *cd;
  182 
  183         cd = &cfdata[dev];
  184         printf("%s", cd->cf_name);
  185         switch (cd->cf_fstate) {
  186         case FSTATE_NOTFOUND:
  187         case FSTATE_DNOTFOUND:
  188                 printf("%d", cd->cf_unit);
  189                 break;
  190         case FSTATE_FOUND:
  191                 printf("*FOUND*");
  192                 break;
  193         case FSTATE_STAR:
  194         case FSTATE_DSTAR:
  195                 printf("*");
  196                 break;
  197         default:
  198                 printf("*UNKNOWN*");
  199                 break;
  200         }
  201 }
  202 
  203 static void
  204 userconf_pdev(short devno)
  205 {
  206         struct cfdata *cd;
  207         const struct cfparent *cfp;
  208         int   *l;
  209         const struct cfiattrdata *ia;
  210         const struct cflocdesc *ld;
  211         int nld, i;
  212 
  213         if (devno > userconf_maxdev) {
  214                 printf("Unknown devno (max is %d)\n", userconf_maxdev);
  215                 return;
  216         }
  217 
  218         cd = &cfdata[devno];
  219 
  220         printf("[%3d] ", devno);
  221         userconf_pdevnam(devno);
  222         printf(" at");
  223         cfp = cd->cf_pspec;
  224         if (cfp == NULL)
  225                 printf(" root");
  226         else if (cfp->cfp_parent != NULL && cfp->cfp_unit != -1)
  227                 printf(" %s%d", cfp->cfp_parent, cfp->cfp_unit);
  228         else
  229                 printf(" %s?", cfp->cfp_parent != NULL ? cfp->cfp_parent
  230                                                        : cfp->cfp_iattr);
  231         switch (cd->cf_fstate) {
  232         case FSTATE_NOTFOUND:
  233         case FSTATE_FOUND:
  234         case FSTATE_STAR:
  235                 break;
  236         case FSTATE_DNOTFOUND:
  237         case FSTATE_DSTAR:
  238                 printf(" disable");
  239                 break;
  240         default:
  241                 printf(" ???");
  242                 break;
  243         }
  244         if (cfp) {
  245                 l = cd->cf_loc;
  246                 ia = cfiattr_lookup(cfp->cfp_iattr, 0);
  247                 KASSERT(ia);
  248                 ld = ia->ci_locdesc;
  249                 nld = ia->ci_loclen;
  250                 for (i = 0; i < nld; i++) {
  251                         printf(" %s ", ld[i].cld_name);
  252                         if (!ld[i].cld_defaultstr
  253                             || (l[i] != ld[i].cld_default))
  254                                 userconf_pnum(l[i]);
  255                         else
  256                                 printf("?");
  257                 }
  258         }
  259         printf("\n");
  260 }
  261 
  262 static int
  263 userconf_number(char *c, int *val)
  264 {
  265         u_int num = 0;
  266         int neg = 0;
  267         int base = 10;
  268 
  269         if (*c == '-') {
  270                 neg = 1;
  271                 c++;
  272         }
  273         if (*c == '') {
  274                 base = 8;
  275                 c++;
  276                 if (*c == 'x' || *c == 'X') {
  277                         base = 16;
  278                         c++;
  279                 }
  280         }
  281         while (*c != '\n' && *c != '\t' && *c != ' ' && *c != '\0') {
  282                 u_char cc = *c;
  283 
  284                 if (cc >= '' && cc <= '9')
  285                         cc = cc - '';
  286                 else if (cc >= 'a' && cc <= 'f')
  287                         cc = cc - 'a' + 10;
  288                 else if (cc >= 'A' && cc <= 'F')
  289                         cc = cc - 'A' + 10;
  290                 else
  291                         return (-1);
  292 
  293                 if (cc > base)
  294                         return (-1);
  295                 num = num * base + cc;
  296                 c++;
  297         }
  298 
  299         if (neg && num > INT_MAX)       /* overflow */
  300                 return (1);
  301         *val = neg ? - num : num;
  302         return (0);
  303 }
  304 
  305 static int
  306 userconf_device(char *cmd, int *len, short *unit, short *state)
  307 {
  308         short u = 0, s = FSTATE_FOUND;
  309         int l = 0;
  310         char *c;
  311 
  312         c = cmd;
  313         while (*c >= 'a' && *c <= 'z') {
  314                 l++;
  315                 c++;
  316         }
  317         if (*c == '*') {
  318                 s = FSTATE_STAR;
  319                 c++;
  320         } else {
  321                 while (*c >= '' && *c <= '9') {
  322                         s = FSTATE_NOTFOUND;
  323                         u = u*10 + *c - '';
  324                         c++;
  325                 }
  326         }
  327         while (*c == ' ' || *c == '\t' || *c == '\n')
  328                 c++;
  329 
  330         if (*c == '\0') {
  331                 *len = l;
  332                 *unit = u;
  333                 *state = s;
  334                 return(0);
  335         }
  336 
  337         return(-1);
  338 }
  339 
  340 static void
  341 userconf_modify(const struct cflocdesc *item, int *val)
  342 {
  343         int ok = 0;
  344         int a;
  345         char *c;
  346 
  347         while (!ok) {
  348                 printf("%s [", item->cld_name);
  349                 if (item->cld_defaultstr && (*val == item->cld_default))
  350                         printf("?");
  351                 else
  352                         userconf_pnum(*val);
  353                 printf("] ? ");
  354 
  355                 getsn(userconf_argbuf, sizeof(userconf_argbuf));
  356 
  357                 c = userconf_argbuf;
  358                 while (*c == ' ' || *c == '\t' || *c == '\n') c++;
  359 
  360                 if (*c != '\0') {
  361                         if (*c == '?') {
  362                                 if (item->cld_defaultstr) {
  363                                         *val = item->cld_default;
  364                                         ok = 1;
  365                                 } else
  366                                         printf("No default\n");
  367                         } else if (userconf_number(c, &a) == 0) {
  368                                 *val = a;
  369                                 ok = 1;
  370                         } else {
  371                                 printf("Unknown argument\n");
  372                         }
  373                 } else {
  374                         ok = 1;
  375                 }
  376         }
  377 }
  378 
  379 static void
  380 userconf_change(int devno)
  381 {
  382         struct cfdata *cd;
  383         char c = '\0';
  384         int   *l;
  385         int   ln;
  386         const struct cfiattrdata *ia;
  387         const struct cflocdesc *ld;
  388         int nld;
  389 
  390         if (devno <=  userconf_maxdev) {
  391 
  392                 userconf_pdev(devno);
  393 
  394                 while (c != 'y' && c != 'Y' && c != 'n' && c != 'N') {
  395                         printf("change (y/n) ?");
  396                         c = cngetc();
  397                         printf("\n");
  398                 }
  399 
  400                 if (c == 'y' || c == 'Y') {
  401 
  402                         /* XXX add cmd 'c' <devno> */
  403                         userconf_hist_cmd('c');
  404                         userconf_hist_int(devno);
  405 
  406                         cd = &cfdata[devno];
  407                         l = cd->cf_loc;
  408                         ia = cfiattr_lookup(cd->cf_pspec->cfp_iattr, 0);
  409                         KASSERT(ia);
  410                         ld = ia->ci_locdesc;
  411                         nld = ia->ci_loclen;
  412 
  413                         for (ln = 0; ln < nld; ln++)
  414                         {
  415                                 userconf_modify(&ld[ln], l);
  416 
  417                                 /* XXX add *l */
  418                                 userconf_hist_int(*l);
  419 
  420                                 l++;
  421                         }
  422 
  423                         printf("[%3d] ", devno);
  424                         userconf_pdevnam(devno);
  425                         printf(" changed\n");
  426                         userconf_pdev(devno);
  427 
  428                         /* XXX add eoc */
  429                         userconf_hist_eoc();
  430 
  431                 }
  432         } else {
  433                 printf("Unknown devno (max is %d)\n", userconf_maxdev);
  434         }
  435 }
  436 
  437 static void
  438 userconf_disable(int devno)
  439 {
  440         int done = 0;
  441 
  442         if (devno <= userconf_maxdev) {
  443                 switch (cfdata[devno].cf_fstate) {
  444                 case FSTATE_NOTFOUND:
  445                         cfdata[devno].cf_fstate = FSTATE_DNOTFOUND;
  446                         break;
  447                 case FSTATE_STAR:
  448                         cfdata[devno].cf_fstate = FSTATE_DSTAR;
  449                         break;
  450                 case FSTATE_DNOTFOUND:
  451                 case FSTATE_DSTAR:
  452                         done = 1;
  453                         break;
  454                 default:
  455                         printf("Error unknown state\n");
  456                         break;
  457                 }
  458 
  459                 printf("[%3d] ", devno);
  460                 userconf_pdevnam(devno);
  461                 if (done) {
  462                         printf(" already");
  463                 } else {
  464                         /* XXX add cmd 'd' <devno> eoc */
  465                         userconf_hist_cmd('d');
  466                         userconf_hist_int(devno);
  467                         userconf_hist_eoc();
  468                 }
  469                 printf(" disabled\n");
  470         } else {
  471                 printf("Unknown devno (max is %d)\n", userconf_maxdev);
  472         }
  473 }
  474 
  475 static void
  476 userconf_enable(int devno)
  477 {
  478         int done = 0;
  479 
  480         if (devno <= userconf_maxdev) {
  481                 switch (cfdata[devno].cf_fstate) {
  482                 case FSTATE_DNOTFOUND:
  483                         cfdata[devno].cf_fstate = FSTATE_NOTFOUND;
  484                         break;
  485                 case FSTATE_DSTAR:
  486                         cfdata[devno].cf_fstate = FSTATE_STAR;
  487                         break;
  488                 case FSTATE_NOTFOUND:
  489                 case FSTATE_STAR:
  490                         done = 1;
  491                         break;
  492                 default:
  493                         printf("Error unknown state\n");
  494                         break;
  495                 }
  496 
  497                 printf("[%3d] ", devno);
  498                 userconf_pdevnam(devno);
  499                 if (done) {
  500                         printf(" already");
  501                 } else {
  502                         /* XXX add cmd 'e' <devno> eoc */
  503                         userconf_hist_cmd('d');
  504                         userconf_hist_int(devno);
  505                         userconf_hist_eoc();
  506                 }
  507                 printf(" enabled\n");
  508         } else {
  509                 printf("Unknown devno (max is %d)\n", userconf_maxdev);
  510         }
  511 }
  512 
  513 static void
  514 userconf_help(void)
  515 {
  516         int j = 0, k;
  517 
  518         printf("command   args                description\n");
  519         while (*userconf_cmds[j] != '\0') {
  520                 printf(userconf_cmds[j]);
  521                 k = strlen(userconf_cmds[j]);
  522                 while (k < 10) {
  523                         printf(" ");
  524                         k++;
  525                 }
  526                 switch (*userconf_cmds[j+1]) {
  527                 case 'L':
  528                         printf("[count]             number of lines before more");
  529                         break;
  530                 case 'b':
  531                         printf("8|10|16             base on large numbers");
  532                         break;
  533                 case 'c':
  534                         printf("devno|dev           change devices");
  535                         break;
  536                 case 'd':
  537                         printf("devno|dev           disable devices");
  538                         break;
  539                 case 'e':
  540                         printf("devno|dev           enable devices");
  541                         break;
  542                 case 'f':
  543                         printf("devno|dev           find devices");
  544                         break;
  545                 case 'h':
  546                         printf("                    this message");
  547                         break;
  548                 case 'l':
  549                         printf("                    list configuration");
  550                         break;
  551                 case 'q':
  552                         printf("                    leave userconf");
  553                         break;
  554                 default:
  555                         printf("                    don't know");
  556                         break;
  557                 }
  558                 printf("\n");
  559                 j += 2;
  560         }
  561 }
  562 
  563 static void
  564 userconf_list(void)
  565 {
  566         int i = 0;
  567 
  568         userconf_cnt = 0;
  569 
  570         while (cfdata[i].cf_name != NULL) {
  571                 if (userconf_more())
  572                         break;
  573                 userconf_pdev(i++);
  574         }
  575 
  576         userconf_cnt = -1;
  577 }
  578 
  579 static void
  580 userconf_common_dev(char *dev, int len, short unit, short state, char routine)
  581 {
  582         int i = 0;
  583 
  584         switch (routine) {
  585         case UC_CHANGE:
  586                 break;
  587         default:
  588                 userconf_cnt = 0;
  589                 break;
  590         }
  591 
  592         while (cfdata[i].cf_name != NULL) {
  593                 if (strlen(cfdata[i].cf_name) == len) {
  594 
  595                         /*
  596                          * Ok, if device name is correct
  597                          *  If state == FSTATE_FOUND, look for "dev"
  598                          *  If state == FSTATE_STAR, look for "dev*"
  599                          *  If state == FSTATE_NOTFOUND, look for "dev0"
  600                          */
  601                         if (strncasecmp(dev, cfdata[i].cf_name,
  602                                         len) == 0 &&
  603                             (state == FSTATE_FOUND ||
  604                              (state == FSTATE_STAR &&
  605                               (cfdata[i].cf_fstate == FSTATE_STAR ||
  606                                cfdata[i].cf_fstate == FSTATE_DSTAR)) ||
  607                              (state == FSTATE_NOTFOUND &&
  608                               cfdata[i].cf_unit == unit &&
  609                               (cfdata[i].cf_fstate == FSTATE_NOTFOUND ||
  610                                cfdata[i].cf_fstate == FSTATE_DNOTFOUND)))) {
  611                                 if (userconf_more())
  612                                         break;
  613                                 switch (routine) {
  614                                 case UC_CHANGE:
  615                                         userconf_change(i);
  616                                         break;
  617                                 case UC_ENABLE:
  618                                         userconf_enable(i);
  619                                         break;
  620                                 case UC_DISABLE:
  621                                         userconf_disable(i);
  622                                         break;
  623                                 case UC_FIND:
  624                                         userconf_pdev(i);
  625                                         break;
  626                                 default:
  627                                         printf("Unknown routine /%c/\n",
  628                                             routine);
  629                                         break;
  630                                 }
  631                         }
  632                 }
  633                 i++;
  634         }
  635 
  636         switch (routine) {
  637         case UC_CHANGE:
  638                 break;
  639         default:
  640                 userconf_cnt = -1;
  641                 break;
  642         }
  643 }
  644 
  645 #if 0
  646 static void
  647 userconf_add_read(char *prompt, char field, char *dev, int len, int *val)
  648 {
  649         int ok = 0;
  650         int a;
  651         char *c;
  652 
  653         *val = -1;
  654 
  655         while (!ok) {
  656                 printf("%s ? ", prompt);
  657 
  658                 getsn(userconf_argbuf, sizeof(userconf_argbuf));
  659 
  660                 c = userconf_argbuf;
  661                 while (*c == ' ' || *c == '\t' || *c == '\n') c++;
  662 
  663                 if (*c != '\0') {
  664                         if (userconf_number(c, &a) == 0) {
  665                                 if (a > userconf_maxdev) {
  666                                         printf("Unknown devno (max is %d)\n",
  667                                             userconf_maxdev);
  668                                 } else if (strncasecmp(dev,
  669                                     cfdata[a].cf_name, len) != 0 &&
  670                                         field == 'a') {
  671                                         printf("Not same device type\n");
  672                                 } else {
  673                                         *val = a;
  674                                         ok = 1;
  675                                 }
  676                         } else if (*c == '?') {
  677                                 userconf_common_dev(dev, len, 0,
  678                                     FSTATE_FOUND, UC_FIND);
  679                         } else if (*c == 'q' || *c == 'Q') {
  680                                 ok = 1;
  681                         } else {
  682                                 printf("Unknown argument\n");
  683                         }
  684                 } else {
  685                         ok = 1;
  686                 }
  687         }
  688 }
  689 #endif /* 0 */
  690 
  691 static int
  692 userconf_parse(char *cmd)
  693 {
  694         char *c, *v;
  695         int i = 0, j = 0, k, a;
  696         short unit, state;
  697 
  698         c = cmd;
  699         while (*c == ' ' || *c == '\t')
  700                 c++;
  701         v = c;
  702         while (*c != ' ' && *c != '\t' && *c != '\n' && *c != '\0') {
  703                 c++;
  704                 i++;
  705         }
  706 
  707         k = -1;
  708         while (*userconf_cmds[j] != '\0') {
  709                 if (strlen(userconf_cmds[j]) == i) {
  710                         if (strncasecmp(v, userconf_cmds[j], i) == 0)
  711                                 k = j;
  712                 }
  713                 j += 2;
  714         }
  715 
  716         while (*c == ' ' || *c == '\t' || *c == '\n')
  717                 c++;
  718 
  719         if (k == -1) {
  720                 if (*v != '\n')
  721                         printf("Unknown command, try help\n");
  722         } else {
  723                 switch (*userconf_cmds[k+1]) {
  724                 case 'L':
  725                         if (*c == '\0')
  726                                 printf("Argument expected\n");
  727                         else if (userconf_number(c, &a) == 0)
  728                                 userconf_lines = a;
  729                         else
  730                                 printf("Unknown argument\n");
  731                         break;
  732                 case 'b':
  733                         if (*c == '\0')
  734                                 printf("8|10|16 expected\n");
  735                         else if (userconf_number(c, &a) == 0) {
  736                                 if (a == 8 || a == 10 || a == 16) {
  737                                         userconf_base = a;
  738                                 } else {
  739                                         printf("8|10|16 expected\n");
  740                                 }
  741                         } else
  742                                 printf("Unknown argument\n");
  743                         break;
  744                 case 'c':
  745                         if (*c == '\0')
  746                                 printf("DevNo or Dev expected\n");
  747                         else if (userconf_number(c, &a) == 0)
  748                                 userconf_change(a);
  749                         else if (userconf_device(c, &a, &unit, &state) == 0)
  750                                 userconf_common_dev(c, a, unit, state, UC_CHANGE);
  751                         else
  752                                 printf("Unknown argument\n");
  753                         break;
  754                 case 'd':
  755                         if (*c == '\0')
  756                                 printf("Attr, DevNo or Dev expected\n");
  757                         else if (userconf_number(c, &a) == 0)
  758                                 userconf_disable(a);
  759                         else if (userconf_device(c, &a, &unit, &state) == 0)
  760                                 userconf_common_dev(c, a, unit, state, UC_DISABLE);
  761                         else
  762                                 printf("Unknown argument\n");
  763                         break;
  764                 case 'e':
  765                         if (*c == '\0')
  766                                 printf("Attr, DevNo or Dev expected\n");
  767                         else if (userconf_number(c, &a) == 0)
  768                                 userconf_enable(a);
  769                         else if (userconf_device(c, &a, &unit, &state) == 0)
  770                                 userconf_common_dev(c, a, unit, state, UC_ENABLE);
  771                         else
  772                                 printf("Unknown argument\n");
  773                         break;
  774                 case 'f':
  775                         if (*c == '\0')
  776                                 printf("DevNo or Dev expected\n");
  777                         else if (userconf_number(c, &a) == 0)
  778                                 userconf_pdev(a);
  779                         else if (userconf_device(c, &a, &unit, &state) == 0)
  780                                 userconf_common_dev(c, a, unit, state, UC_FIND);
  781                         else
  782                                 printf("Unknown argument\n");
  783                         break;
  784                 case 'h':
  785                         userconf_help();
  786                         break;
  787                 case 'l':
  788                         if (*c == '\0')
  789                                 userconf_list();
  790                         else
  791                                 printf("Unknown argument\n");
  792                         break;
  793                 case 'q':
  794                         /* XXX add cmd 'q' eoc */
  795                         userconf_hist_cmd('q');
  796                         userconf_hist_eoc();
  797                         return(-1);
  798                 case 's':
  799                 default:
  800                         printf("Unknown command\n");
  801                         break;
  802                 }
  803         }
  804         return(0);
  805 }
  806 
  807 extern void user_config(void);
  808 
  809 void
  810 user_config(void)
  811 {
  812         char prompt[] = "uc> ";
  813 
  814         userconf_init();
  815         printf("userconf: configure system autoconfiguration:\n");
  816 
  817         while (1) {
  818                 printf(prompt);
  819                 if (getsn(userconf_cmdbuf, sizeof(userconf_cmdbuf)) > 0 &&
  820                     userconf_parse(userconf_cmdbuf))
  821                         break;
  822         }
  823         printf("Continuing...\n");
  824 }
  825 
  826 /*
  827  * XXX shouldn't this be a common function?
  828  */
  829 static int
  830 getsn(char *cp, int size)
  831 {
  832         char *lp;
  833         int c, len;
  834 
  835         cnpollc(1);
  836 
  837         lp = cp;
  838         len = 0;
  839         for (;;) {
  840                 c = cngetc();
  841                 switch (c) {
  842                 case '\n':
  843                 case '\r':
  844                         printf("\n");
  845                         *lp++ = '\0';
  846                         cnpollc(0);
  847                         return (len);
  848                 case '\b':
  849                 case '\177':
  850                 case '#':
  851                         if (len) {
  852                                 --len;
  853                                 --lp;
  854                                 printf("\b \b");
  855                         }
  856                         continue;
  857                 case '@':
  858                 case 'u'&037:
  859                         len = 0;
  860                         lp = cp;
  861                         printf("\n");
  862                         continue;
  863                 default:
  864                         if (len + 1 >= size || c < ' ') {
  865                                 printf("\007");
  866                                 continue;
  867                         }
  868                         printf("%c", c);
  869                         ++len;
  870                         *lp++ = c;
  871                 }
  872         }
  873 }

Cache object: f7407c9356e6eaccd33a3994ff5aee75


[ 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.