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