config.y revision 163638
118334Speter%union {
252284Sobrien	char	*str;
318334Speter	int	val;
418334Speter	struct	file_list *file;
518334Speter}
618334Speter
718334Speter%token	ARCH
818334Speter%token	COMMA
918334Speter%token	CONFIG
1018334Speter%token	CPU
1118334Speter%token	NOCPU
1218334Speter%token	DEVICE
1318334Speter%token	NODEVICE
1418334Speter%token	ENV
1518334Speter%token	EQUALS
1618334Speter%token	HINTS
1718334Speter%token	IDENT
1818334Speter%token	MAXUSERS
1918334Speter%token	PROFILE
2018334Speter%token	OPTIONS
2118334Speter%token	NOOPTION
2218334Speter%token	MAKEOPTIONS
2350397Sobrien%token	NOMAKEOPTION
2418334Speter%token	SEMICOLON
2518334Speter%token	INCLUDE
2618334Speter%token	FILES
2718334Speter
2818334Speter%token	<str>	ID
2918334Speter%token	<val>	NUMBER
3018334Speter
3118334Speter%type	<str>	Save_id
3218334Speter%type	<str>	Opt_value
3352284Sobrien%type	<str>	Dev
3452284Sobrien
3552284Sobrien%{
3618334Speter
3718334Speter/*
3818334Speter * Copyright (c) 1988, 1993
3918334Speter *	The Regents of the University of California.  All rights reserved.
4018334Speter *
4118334Speter * Redistribution and use in source and binary forms, with or without
4218334Speter * modification, are permitted provided that the following conditions
4318334Speter * are met:
4418334Speter * 1. Redistributions of source code must retain the above copyright
4518334Speter *    notice, this list of conditions and the following disclaimer.
4618334Speter * 2. Redistributions in binary form must reproduce the above copyright
4718334Speter *    notice, this list of conditions and the following disclaimer in the
4818334Speter *    documentation and/or other materials provided with the distribution.
4918334Speter * 3. All advertising materials mentioning features or use of this software
5018334Speter *    must display the following acknowledgement:
5118334Speter *	This product includes software developed by the University of
5218334Speter *	California, Berkeley and its contributors.
5318334Speter * 4. Neither the name of the University nor the names of its contributors
5418334Speter *    may be used to endorse or promote products derived from this software
5518334Speter *    without specific prior written permission.
5618334Speter *
5718334Speter * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
5818334Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
5918334Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
6018334Speter * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
6118334Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
6218334Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
6318334Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
6418334Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
6518334Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
6652284Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
6718334Speter * SUCH DAMAGE.
6818334Speter *
6918334Speter *	@(#)config.y	8.1 (Berkeley) 6/6/93
7018334Speter * $FreeBSD: head/usr.sbin/config/config.y 163638 2006-10-24 00:31:59Z imp $
7118334Speter */
7218334Speter
7318334Speter#include <ctype.h>
7418334Speter#include <err.h>
7518334Speter#include <stdio.h>
7618334Speter#include <string.h>
7718334Speter
7818334Speter#include "config.h"
7918334Speter
8018334Speterstruct	device_head dtab;
8118334Speterchar	*ident;
8218334Speterchar	*env;
8318334Speterint	envmode;
8418334Speterint	hintmode;
8518334Speterint	yyline;
8618334Speterconst	char *yyfile;
8718334Speterstruct  file_list_head ftab;
8818334Speterstruct  files_name_head fntab;
8918334Speterchar	errbuf[80];
9018334Speterint	maxusers;
9118334Speter
9218334Speter#define ns(s)	strdup(s)
9318334Speterint include(const char *, int);
9418334Spetervoid yyerror(const char *s);
9518334Speterint yywrap(void);
9618334Speter
9718334Speterstatic char *
9818334Speterdevopt(char *dev)
9918334Speter{
10018334Speter	char *ret = malloc(strlen(dev) + 5);
10118334Speter
10218334Speter	sprintf(ret, "DEV_%s", dev);
10318334Speter	raisestr(ret);
10418334Speter	return ret;
10518334Speter}
10618334Speter
10718334Speter%}
10818334Speter%%
10918334SpeterConfiguration:
11018334Speter	Many_specs
11118334Speter		;
11218334Speter
11318334SpeterMany_specs:
11418334Speter	Many_specs Spec
11518334Speter		|
11618334Speter	/* lambda */
11718334Speter		;
11818334Speter
11918334SpeterSpec:
12018334Speter	Device_spec SEMICOLON
12150397Sobrien		|
12250397Sobrien	Config_spec SEMICOLON
12318334Speter		|
12418334Speter	INCLUDE ID SEMICOLON
12518334Speter	      = { include($2, 0); };
12618334Speter		|
12750397Sobrien	FILES ID SEMICOLON
12850397Sobrien	      = { newfile($2); };
12918334Speter	        |
13018334Speter	SEMICOLON
13118334Speter		|
13218334Speter	error SEMICOLON
13318334Speter		;
13418334Speter
13550397SobrienConfig_spec:
13618334Speter	ARCH Save_id
13752284Sobrien	    = {
13818334Speter		if (machinename != NULL && !eq($2, machinename))
13918334Speter		    errx(1, "%s:%d: only one machine directive is allowed",
14018334Speter			yyfile, yyline);
14118334Speter		machinename = $2;
14218334Speter		machinearch = $2;
14318334Speter	      } |
14418334Speter	ARCH Save_id Save_id
14518334Speter	    = {
14618334Speter		if (machinename != NULL &&
14718334Speter		    !(eq($2, machinename) && eq($3, machinearch)))
14818334Speter		    errx(1, "%s:%d: only one machine directive is allowed",
14918334Speter			yyfile, yyline);
15018334Speter		machinename = $2;
15118334Speter		machinearch = $3;
15218334Speter	      } |
15318334Speter	CPU Save_id
15418334Speter	      = {
15518334Speter		struct cputype *cp =
15618334Speter		    (struct cputype *)calloc(1, sizeof (struct cputype));
15718334Speter		cp->cpu_name = $2;
15818334Speter		SLIST_INSERT_HEAD(&cputype, cp, cpu_next);
15918334Speter	      } |
16018334Speter	NOCPU Save_id
16118334Speter	      = {
16218334Speter		struct cputype *cp, *cp2;
16318334Speter		SLIST_FOREACH_SAFE(cp, &cputype, cpu_next, cp2) {
16418334Speter			if (eq(cp->cpu_name, $2)) {
16518334Speter				SLIST_REMOVE(&cputype, cp, cputype, cpu_next);
16618334Speter				free(cp);
16718334Speter			}
16818334Speter		}
16918334Speter	      } |
17018334Speter	OPTIONS Opt_list
17118334Speter		|
17218334Speter	NOOPTION Save_id
17318334Speter	      = { rmopt(&opt, $2); } |
17418334Speter	MAKEOPTIONS Mkopt_list
17518334Speter		|
17618334Speter	NOMAKEOPTION Save_id
17718334Speter	      = { rmopt(&mkopt, $2); } |
17818334Speter	IDENT ID
17918334Speter	      = { ident = $2; } |
18018334Speter	System_spec
18118334Speter		|
18218334Speter	MAXUSERS NUMBER
18318334Speter	      = { maxusers = $2; } |
18418334Speter	PROFILE NUMBER
18550397Sobrien	      = { profiling = $2; } |
18618334Speter	ENV ID
18718334Speter	      = {
18818334Speter		env = $2;
18918334Speter		envmode = 1;
19018334Speter		} |
19118334Speter	HINTS ID
19218334Speter	      = {
19318334Speter		struct hint *hint;
19418334Speter
19518334Speter		hint = (struct hint *)calloc(1, sizeof (struct hint));
19618334Speter		hint->hint_name = $2;
19750397Sobrien		STAILQ_INSERT_TAIL(&hints, hint, hint_next);
19850397Sobrien		hintmode = 1;
19950397Sobrien	        }
20050397Sobrien
20150397SobrienSystem_spec:
20218334Speter	CONFIG System_id System_parameter_list
20318334Speter	  = { errx(1, "%s:%d: root/dump/swap specifications obsolete",
20452284Sobrien	      yyfile, yyline);}
20518334Speter	  |
20618334Speter	CONFIG System_id
20718334Speter	  ;
20818334Speter
20918334SpeterSystem_id:
21018334Speter	Save_id
21118334Speter	      = { newopt(&mkopt, ns("KERNEL"), $1); };
21218334Speter
21350397SobrienSystem_parameter_list:
21418334Speter	  System_parameter_list ID
21518334Speter	| ID
21618334Speter	;
21718334Speter
21818334SpeterOpt_list:
21918334Speter	Opt_list COMMA Option
22018334Speter		|
22118334Speter	Option
22218334Speter		;
22318334Speter
22418334SpeterOption:
22518334Speter	Save_id
22618334Speter	      = {
22718334Speter		newopt(&opt, $1, NULL);
22818334Speter		if (strchr($1, '=') != NULL)
22918334Speter			errx(1, "%s:%d: The `=' in options should not be "
23018334Speter			    "quoted", yyfile, yyline);
23118334Speter	      } |
23218334Speter	Save_id EQUALS Opt_value
23318334Speter	      = {
23418334Speter		newopt(&opt, $1, $3);
23518334Speter	      } ;
23618334Speter
23718334SpeterOpt_value:
23818334Speter	ID
23918334Speter		= { $$ = $1; } |
24018334Speter	NUMBER
24118334Speter		= {
24218334Speter			char buf[80];
24318334Speter
24418334Speter			(void) snprintf(buf, sizeof(buf), "%d", $1);
24518334Speter			$$ = ns(buf);
24618334Speter		} ;
24718334Speter
24818334SpeterSave_id:
24918334Speter	ID
25018334Speter	      = { $$ = $1; }
25118334Speter	;
25218334Speter
25318334SpeterMkopt_list:
25418334Speter	Mkopt_list COMMA Mkoption
25518334Speter		|
25618334Speter	Mkoption
25718334Speter		;
25852284Sobrien
25918334SpeterMkoption:
26018334Speter	Save_id
26118334Speter	      = { newopt(&mkopt, $1, ns("")); } |
26252284Sobrien	Save_id EQUALS Opt_value
26318334Speter	      = { newopt(&mkopt, $1, $3); } ;
26418334Speter
26518334SpeterDev:
26618334Speter	ID
26718334Speter	      = { $$ = $1; }
26818334Speter	;
26918334Speter
27018334SpeterDevice_spec:
27118334Speter	DEVICE Dev_list
27218334Speter		|
27318334Speter	NODEVICE NoDev_list
27418334Speter		;
27552284Sobrien
27618334SpeterDev_list:
27718334Speter	Dev_list COMMA Device
27818334Speter		|
27918334Speter	Device
28018334Speter		;
28118334Speter
28218334SpeterNoDev_list:
28352284Sobrien	NoDev_list COMMA NoDevice
28418334Speter		|
28552284Sobrien	NoDevice
28618334Speter		;
28752284Sobrien
28818334SpeterDevice:
28918334Speter	Dev
29018334Speter	      = {
29118334Speter		newopt(&opt, devopt($1), ns("1"));
29218334Speter		/* and the device part */
29318334Speter		newdev($1);
29418334Speter		}
29552284Sobrien
29652284SobrienNoDevice:
29752284Sobrien	Dev
29852284Sobrien	      = {
29918334Speter		char *s = devopt($1);
30052284Sobrien
30152284Sobrien		rmopt(&opt, s);
30252284Sobrien		free(s);
30352284Sobrien		/* and the device part */
30452284Sobrien		rmdev($1);
30552284Sobrien		} ;
30618334Speter
30752284Sobrien%%
30818334Speter
30918334Spetervoid
31052284Sobrienyyerror(const char *s)
31152284Sobrien{
31218334Speter
31352284Sobrien	errx(1, "%s:%d: %s", yyfile, yyline + 1, s);
31452284Sobrien}
31550397Sobrien
31650397Sobrienint
31750397Sobrienyywrap(void)
31850397Sobrien{
31950397Sobrien
32052284Sobrien	if (found_defaults) {
32152284Sobrien		if (freopen(PREFIX, "r", stdin) == NULL)
32250397Sobrien			err(2, "%s", PREFIX);
32350397Sobrien		yyfile = PREFIX;
32418334Speter		yyline = 0;
32550397Sobrien		found_defaults = 0;
32650397Sobrien		return 0;
32718334Speter	}
32818334Speter	return 1;
32918334Speter}
33018334Speter
33118334Speter/*
33218334Speter * Add a new file to the list of files.
33318334Speter */
33418334Speterstatic void
33518334Speternewfile(char *name)
33618334Speter{
33718334Speter	struct files_name *nl;
33818334Speter
33918334Speter	nl = (struct files_name *) calloc(1, sizeof *nl);
34018334Speter	nl->f_name = name;
34118334Speter	STAILQ_INSERT_TAIL(&fntab, nl, f_next);
34218334Speter}
34318334Speter
34418334Speter/*
34518334Speter * Find a device in the list of devices.
34618334Speter */
34718334Speterstatic struct device *
34818334Speterfinddev(char *name)
34918334Speter{
35018334Speter	struct device *dp;
35118334Speter
35218334Speter	STAILQ_FOREACH(dp, &dtab, d_next)
35318334Speter		if (eq(dp->d_name, name))
35418334Speter			return (dp);
35518334Speter
35618334Speter	return (NULL);
35718334Speter}
35818334Speter
35918334Speter/*
36018334Speter * Add a device to the list of devices.
36118334Speter */
36218334Speterstatic void
36318334Speternewdev(char *name)
36418334Speter{
36518334Speter	struct device *np;
36618334Speter
36750397Sobrien	if (finddev(name)) {
36818334Speter		printf("WARNING: duplicate device `%s' encountered.\n", name);
36918334Speter		return;
37018334Speter	}
37118334Speter
37218334Speter	np = (struct device *) calloc(1, sizeof *np);
37318334Speter	np->d_name = name;
37418334Speter	STAILQ_INSERT_TAIL(&dtab, np, d_next);
37518334Speter}
37618334Speter
37718334Speter/*
37818334Speter * Remove a device from the list of devices.
37918334Speter */
38018334Speterstatic void
38118334Speterrmdev(char *name)
38218334Speter{
38318334Speter	struct device *dp;
38418334Speter
38518334Speter	dp = finddev(name);
38618334Speter	if (dp != NULL) {
38718334Speter		STAILQ_REMOVE(&dtab, dp, device, d_next);
38818334Speter		free(dp->d_name);
38918334Speter		free(dp);
39018334Speter	}
39118334Speter}
39218334Speter
39318334Speter/*
39418334Speter * Find an option in the list of options.
39518334Speter */
39618334Speterstatic struct opt *
39718334Speterfindopt(struct opt_head *list, char *name)
39818334Speter{
39918334Speter	struct opt *op;
400
401	SLIST_FOREACH(op, list, op_next)
402		if (eq(op->op_name, name))
403			return (op);
404
405	return (NULL);
406}
407
408/*
409 * Add an option to the list of options.
410 */
411static void
412newopt(struct opt_head *list, char *name, char *value)
413{
414	struct opt *op;
415
416	if (findopt(list, name)) {
417		printf("WARNING: duplicate option `%s' encountered.\n", name);
418		return;
419	}
420
421	op = (struct opt *)calloc(1, sizeof (struct opt));
422	op->op_name = name;
423	op->op_ownfile = 0;
424	op->op_value = value;
425	SLIST_INSERT_HEAD(list, op, op_next);
426}
427
428/*
429 * Remove an option from the list of options.
430 */
431static void
432rmopt(struct opt_head *list, char *name)
433{
434	struct opt *op;
435
436	op = findopt(list, name);
437	if (op != NULL) {
438		SLIST_REMOVE(list, op, opt, op_next);
439		free(op->op_name);
440		if (op->op_value != NULL)
441			free(op->op_value);
442		free(op);
443	}
444}
445