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