xref: /freebsd/usr.sbin/config/config.y (revision 9e2b87207ba1949f402e169416f63ab5cdbf3dd4)
1dea673e9SRodney W. Grimes %union {
2dea673e9SRodney W. Grimes 	char	*str;
3dea673e9SRodney W. Grimes 	int	val;
4dea673e9SRodney W. Grimes 	struct	file_list *file;
5dea673e9SRodney W. Grimes }
6dea673e9SRodney W. Grimes 
7c1454d67SMarcel Moolenaar %token	ARCH
8dea673e9SRodney W. Grimes %token	COMMA
9ef354ff7SPeter Wemm %token	CONFIG
10dea673e9SRodney W. Grimes %token	CPU
11acd58322SRuslan Ermilov %token	NOCPU
12dea673e9SRodney W. Grimes %token	DEVICE
1382401849SRuslan Ermilov %token	NODEVICE
1476cb0cadSPeter Wemm %token	ENV
153b31596dSKyle Evans %token	ENVVAR
16dea673e9SRodney W. Grimes %token	EQUALS
172880daebSAndrew Thompson %token	PLUSEQUALS
18f71c01ccSPeter Wemm %token	HINTS
19dea673e9SRodney W. Grimes %token	IDENT
20dea673e9SRodney W. Grimes %token	MAXUSERS
21dea673e9SRodney W. Grimes %token	OPTIONS
2282401849SRuslan Ermilov %token	NOOPTION
23dea673e9SRodney W. Grimes %token	MAKEOPTIONS
2482401849SRuslan Ermilov %token	NOMAKEOPTION
25dea673e9SRodney W. Grimes %token	SEMICOLON
265e06480cSDima Dorfman %token	INCLUDE
27*9e2b8720SStephen J. Kiernan %token	INCLUDEOPTIONS
2843a903c0SOlivier Houchard %token	FILES
29dea673e9SRodney W. Grimes 
303b31596dSKyle Evans %token	<str>	ENVLINE
31dea673e9SRodney W. Grimes %token	<str>	ID
32dea673e9SRodney W. Grimes %token	<val>	NUMBER
33dea673e9SRodney W. Grimes 
34dea673e9SRodney W. Grimes %type	<str>	Save_id
35e07fcb3eSLuoqi Chen %type	<str>	Opt_value
36dea673e9SRodney W. Grimes %type	<str>	Dev
37eb432404SDavid E. O'Brien %token	<str>	PATH
38dea673e9SRodney W. Grimes 
39dea673e9SRodney W. Grimes %{
40dea673e9SRodney W. Grimes 
418a16b7a1SPedro F. Giffuni /*-
428a16b7a1SPedro F. Giffuni  * SPDX-License-Identifier: BSD-3-Clause
438a16b7a1SPedro F. Giffuni  *
44dea673e9SRodney W. Grimes  * Copyright (c) 1988, 1993
45dea673e9SRodney W. Grimes  *	The Regents of the University of California.  All rights reserved.
46dea673e9SRodney W. Grimes  *
47dea673e9SRodney W. Grimes  * Redistribution and use in source and binary forms, with or without
48dea673e9SRodney W. Grimes  * modification, are permitted provided that the following conditions
49dea673e9SRodney W. Grimes  * are met:
50dea673e9SRodney W. Grimes  * 1. Redistributions of source code must retain the above copyright
51dea673e9SRodney W. Grimes  *    notice, this list of conditions and the following disclaimer.
52dea673e9SRodney W. Grimes  * 2. Redistributions in binary form must reproduce the above copyright
53dea673e9SRodney W. Grimes  *    notice, this list of conditions and the following disclaimer in the
54dea673e9SRodney W. Grimes  *    documentation and/or other materials provided with the distribution.
55fbbd9655SWarner Losh  * 3. Neither the name of the University nor the names of its contributors
56dea673e9SRodney W. Grimes  *    may be used to endorse or promote products derived from this software
57dea673e9SRodney W. Grimes  *    without specific prior written permission.
58dea673e9SRodney W. Grimes  *
59dea673e9SRodney W. Grimes  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
60dea673e9SRodney W. Grimes  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
61dea673e9SRodney W. Grimes  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
62dea673e9SRodney W. Grimes  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
63dea673e9SRodney W. Grimes  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
64dea673e9SRodney W. Grimes  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
65dea673e9SRodney W. Grimes  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
66dea673e9SRodney W. Grimes  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
67dea673e9SRodney W. Grimes  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
68dea673e9SRodney W. Grimes  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
69dea673e9SRodney W. Grimes  * SUCH DAMAGE.
70dea673e9SRodney W. Grimes  */
71dea673e9SRodney W. Grimes 
72744b947eSWojciech A. Koszek #include <assert.h>
73dea673e9SRodney W. Grimes #include <ctype.h>
748a7c811aSGarrett Wollman #include <err.h>
75d5831691SPhilippe Charnier #include <stdio.h>
766d41b96fSPeter Wemm #include <string.h>
77dea673e9SRodney W. Grimes 
78e6fbbbe4SPeter Wemm #include "config.h"
79e6fbbbe4SPeter Wemm 
80c1f4dd93SWarner Losh struct	device_head dtab;
81188334f6SPeter Wemm char	*ident;
8239d44f7fSKyle Evans char	*env;
83188334f6SPeter Wemm int	yyline;
845e06480cSDima Dorfman const	char *yyfile;
85292dd8a8SRuslan Ermilov struct  file_list_head ftab;
8643a903c0SOlivier Houchard struct  files_name_head fntab;
87*9e2b8720SStephen J. Kiernan struct	options_files_name_head optfntab;
88188334f6SPeter Wemm char	errbuf[80];
89188334f6SPeter Wemm int	maxusers;
90188334f6SPeter Wemm 
915bd7b809SJoerg Wunsch #define ns(s)	strdup(s)
925e06480cSDima Dorfman int include(const char *, int);
935dda778dSDapeng Gao int yyerror(const char *s);
94dfdbf9beSJohn Baldwin int yywrap(void);
95e6fbbbe4SPeter Wemm 
9691998fc5SWarner Losh static void newdev(char *name);
9791998fc5SWarner Losh static void newfile(char *name);
98*9e2b8720SStephen J. Kiernan static void newoptionsfile(char *name);
994edfa908SKyle Evans static void newenvvar(char *name, bool is_file);
10091998fc5SWarner Losh static void rmdev_schedule(struct device_head *dh, char *name);
101993e5c4fSKyle Evans static void newopt(struct opt_head *list, char *name, char *value, int append, int dupe);
10291998fc5SWarner Losh static void rmopt_schedule(struct opt_head *list, char *name);
10391998fc5SWarner Losh 
10410ca19cfSPeter Wemm static char *
devopt(char * dev)10510ca19cfSPeter Wemm devopt(char *dev)
10610ca19cfSPeter Wemm {
10710ca19cfSPeter Wemm 	char *ret = malloc(strlen(dev) + 5);
10810ca19cfSPeter Wemm 
10910ca19cfSPeter Wemm 	sprintf(ret, "DEV_%s", dev);
11010ca19cfSPeter Wemm 	raisestr(ret);
11110ca19cfSPeter Wemm 	return ret;
11210ca19cfSPeter Wemm }
113d5831691SPhilippe Charnier 
114dea673e9SRodney W. Grimes %}
115dea673e9SRodney W. Grimes %%
116dea673e9SRodney W. Grimes Configuration:
117dea673e9SRodney W. Grimes 	Many_specs
118dea673e9SRodney W. Grimes 		;
119dea673e9SRodney W. Grimes 
120dea673e9SRodney W. Grimes Many_specs:
121dea673e9SRodney W. Grimes 	Many_specs Spec
122dea673e9SRodney W. Grimes 		|
123dea673e9SRodney W. Grimes 	/* lambda */
124dea673e9SRodney W. Grimes 		;
125dea673e9SRodney W. Grimes 
126dea673e9SRodney W. Grimes Spec:
127dea673e9SRodney W. Grimes 	Device_spec SEMICOLON
1282db1cff1SPeter Wemm 		|
129dea673e9SRodney W. Grimes 	Config_spec SEMICOLON
130dea673e9SRodney W. Grimes 		|
131eb432404SDavid E. O'Brien 	INCLUDE PATH SEMICOLON {
132eb432404SDavid E. O'Brien 		if (incignore == 0)
133eb432404SDavid E. O'Brien 			include($2, 0);
134eb432404SDavid E. O'Brien 		};
135eb432404SDavid E. O'Brien 		|
13691998fc5SWarner Losh 	INCLUDE ID SEMICOLON {
137744b947eSWojciech A. Koszek 	          if (incignore == 0)
138744b947eSWojciech A. Koszek 		  	include($2, 0);
139744b947eSWojciech A. Koszek 		};
140e3937b62SBruce Evans 		|
141*9e2b8720SStephen J. Kiernan 	INCLUDEOPTIONS PATH SEMICOLON { newoptionsfile($2); };
142*9e2b8720SStephen J. Kiernan 		|
143*9e2b8720SStephen J. Kiernan 	INCLUDEOPTIONS ID SEMICOLON { newoptionsfile($2); };
144*9e2b8720SStephen J. Kiernan 		|
14591998fc5SWarner Losh 	FILES ID SEMICOLON { newfile($2); };
14643a903c0SOlivier Houchard 	        |
147dea673e9SRodney W. Grimes 	SEMICOLON
148dea673e9SRodney W. Grimes 		|
149dea673e9SRodney W. Grimes 	error SEMICOLON
150dea673e9SRodney W. Grimes 		;
151dea673e9SRodney W. Grimes 
152dea673e9SRodney W. Grimes Config_spec:
15391998fc5SWarner Losh 	ARCH Save_id {
1546646524fSRuslan Ermilov 		if (machinename != NULL && !eq($2, machinename))
1551949e955SJoseph Koshy 		    errx(1, "%s:%d: only one machine directive is allowed",
1561949e955SJoseph Koshy 			yyfile, yyline);
1573b10a240SPeter Wemm 		machinename = $2;
15851c1297aSWarner Losh 		machinearch = $2;
15951c1297aSWarner Losh 	      } |
16091998fc5SWarner Losh 	ARCH Save_id Save_id {
1619bcb7418SWarner Losh 		/*
1629bcb7418SWarner Losh 		 * Allow the machinearch to change with a second machine directive,
1639bcb7418SWarner Losh 		 * but still enforce no changes to the machinename.
1649bcb7418SWarner Losh 		 */
1659bcb7418SWarner Losh 		if (machinename != NULL && !eq($2, machinename))
16651c1297aSWarner Losh 		    errx(1, "%s:%d: only one machine directive is allowed",
16751c1297aSWarner Losh 			yyfile, yyline);
16851c1297aSWarner Losh 		machinename = $2;
16951c1297aSWarner Losh 		machinearch = $3;
170dea673e9SRodney W. Grimes 	      } |
17191998fc5SWarner Losh 	CPU Save_id {
172dea673e9SRodney W. Grimes 		struct cputype *cp =
1735f17c1e2SXin LI 		    (struct cputype *)calloc(1, sizeof (struct cputype));
17453d55e97SRuslan Ermilov 		if (cp == NULL)
17553d55e97SRuslan Ermilov 			err(EXIT_FAILURE, "calloc");
1765bd7b809SJoerg Wunsch 		cp->cpu_name = $2;
177292dd8a8SRuslan Ermilov 		SLIST_INSERT_HEAD(&cputype, cp, cpu_next);
178dea673e9SRodney W. Grimes 	      } |
17991998fc5SWarner Losh 	NOCPU Save_id {
180acd58322SRuslan Ermilov 		struct cputype *cp, *cp2;
181acd58322SRuslan Ermilov 		SLIST_FOREACH_SAFE(cp, &cputype, cpu_next, cp2) {
182d3e15dbaSRuslan Ermilov 			if (eq(cp->cpu_name, $2)) {
183acd58322SRuslan Ermilov 				SLIST_REMOVE(&cputype, cp, cputype, cpu_next);
184acd58322SRuslan Ermilov 				free(cp);
185d3e15dbaSRuslan Ermilov 			}
186acd58322SRuslan Ermilov 		}
187acd58322SRuslan Ermilov 	      } |
188dea673e9SRodney W. Grimes 	OPTIONS Opt_list
189dea673e9SRodney W. Grimes 		|
190ca71b908SWill Andrews 	NOOPTION NoOpt_list |
191dea673e9SRodney W. Grimes 	MAKEOPTIONS Mkopt_list
192dea673e9SRodney W. Grimes 		|
19391998fc5SWarner Losh 	NOMAKEOPTION Save_id { rmopt_schedule(&mkopt, $2); } |
19491998fc5SWarner Losh 	IDENT ID { ident = $2; } |
19591998fc5SWarner Losh 	MAXUSERS NUMBER { maxusers = $2; } |
1964edfa908SKyle Evans 	ENV ID { newenvvar($2, true); } |
1974edfa908SKyle Evans 	ENVVAR ENVLINE { newenvvar($2, false); } |
19891998fc5SWarner Losh 	HINTS ID {
19986418d0cSWarner Losh 		struct hint *hint;
20086418d0cSWarner Losh 
20186418d0cSWarner Losh 		hint = (struct hint *)calloc(1, sizeof (struct hint));
20253d55e97SRuslan Ermilov 		if (hint == NULL)
20353d55e97SRuslan Ermilov 			err(EXIT_FAILURE, "calloc");
20486418d0cSWarner Losh 		hint->hint_name = $2;
2056ffdd5efSKyle Evans 		STAILQ_INSERT_HEAD(&hints, hint, hint_next);
206e3937b62SBruce Evans 	        }
207dea673e9SRodney W. Grimes 
208ef354ff7SPeter Wemm System_id:
209993e5c4fSKyle Evans 	Save_id { newopt(&mkopt, ns("KERNEL"), $1, 0, 0); };
210ef354ff7SPeter Wemm 
211ef354ff7SPeter Wemm System_parameter_list:
212ef354ff7SPeter Wemm 	  System_parameter_list ID
213ef354ff7SPeter Wemm 	| ID
214ef354ff7SPeter Wemm 	;
215ef354ff7SPeter Wemm 
216dea673e9SRodney W. Grimes Opt_list:
217dea673e9SRodney W. Grimes 	Opt_list COMMA Option
218dea673e9SRodney W. Grimes 		|
219dea673e9SRodney W. Grimes 	Option
220dea673e9SRodney W. Grimes 		;
221dea673e9SRodney W. Grimes 
222ca71b908SWill Andrews NoOpt_list:
223ca71b908SWill Andrews 	NoOpt_list COMMA NoOption
224ca71b908SWill Andrews 	  	|
225ca71b908SWill Andrews 	NoOption
226ca71b908SWill Andrews 		;
227dea673e9SRodney W. Grimes Option:
22891998fc5SWarner Losh 	Save_id {
229993e5c4fSKyle Evans 		newopt(&opt, $1, NULL, 0, 1);
230347a5ee7SStefan Farfeleder 		if (strchr($1, '=') != NULL)
2315e06480cSDima Dorfman 			errx(1, "%s:%d: The `=' in options should not be "
2325e06480cSDima Dorfman 			    "quoted", yyfile, yyline);
233dea673e9SRodney W. Grimes 	      } |
23491998fc5SWarner Losh 	Save_id EQUALS Opt_value {
235993e5c4fSKyle Evans 		newopt(&opt, $1, $3, 0, 1);
236dea673e9SRodney W. Grimes 	      } ;
237dea673e9SRodney W. Grimes 
238ca71b908SWill Andrews NoOption:
239ca71b908SWill Andrews 	Save_id {
240ca71b908SWill Andrews 		rmopt_schedule(&opt, $1);
241ca71b908SWill Andrews 		};
242ca71b908SWill Andrews 
243e07fcb3eSLuoqi Chen Opt_value:
24491998fc5SWarner Losh 	ID { $$ = $1; } |
24591998fc5SWarner Losh 	NUMBER {
24696217b0fSPeter Wemm 			char buf[80];
247dea673e9SRodney W. Grimes 
24896217b0fSPeter Wemm 			(void) snprintf(buf, sizeof(buf), "%d", $1);
24996217b0fSPeter Wemm 			$$ = ns(buf);
25096217b0fSPeter Wemm 		} ;
251dea673e9SRodney W. Grimes 
252dea673e9SRodney W. Grimes Save_id:
25391998fc5SWarner Losh 	ID { $$ = $1; }
254dea673e9SRodney W. Grimes 	;
255dea673e9SRodney W. Grimes 
256dea673e9SRodney W. Grimes Mkopt_list:
257dea673e9SRodney W. Grimes 	Mkopt_list COMMA Mkoption
258dea673e9SRodney W. Grimes 		|
259dea673e9SRodney W. Grimes 	Mkoption
260dea673e9SRodney W. Grimes 		;
261dea673e9SRodney W. Grimes 
262dea673e9SRodney W. Grimes Mkoption:
263993e5c4fSKyle Evans 	Save_id { newopt(&mkopt, $1, ns(""), 0, 0); } |
264993e5c4fSKyle Evans 	Save_id EQUALS { newopt(&mkopt, $1, ns(""), 0, 0); } |
265993e5c4fSKyle Evans 	Save_id EQUALS Opt_value { newopt(&mkopt, $1, $3, 0, 0); } |
266993e5c4fSKyle Evans 	Save_id PLUSEQUALS Opt_value { newopt(&mkopt, $1, $3, 1, 0); } ;
267dea673e9SRodney W. Grimes 
268dea673e9SRodney W. Grimes Dev:
26991998fc5SWarner Losh 	ID { $$ = $1; }
270dea673e9SRodney W. Grimes 	;
271dea673e9SRodney W. Grimes 
272dea673e9SRodney W. Grimes Device_spec:
27330fdf276SDag-Erling Smørgrav 	DEVICE Dev_list
27430fdf276SDag-Erling Smørgrav 		|
27530fdf276SDag-Erling Smørgrav 	NODEVICE NoDev_list
27630fdf276SDag-Erling Smørgrav 		;
27730fdf276SDag-Erling Smørgrav 
27830fdf276SDag-Erling Smørgrav Dev_list:
27930fdf276SDag-Erling Smørgrav 	Dev_list COMMA Device
28030fdf276SDag-Erling Smørgrav 		|
28130fdf276SDag-Erling Smørgrav 	Device
28230fdf276SDag-Erling Smørgrav 		;
28330fdf276SDag-Erling Smørgrav 
28430fdf276SDag-Erling Smørgrav NoDev_list:
28530fdf276SDag-Erling Smørgrav 	NoDev_list COMMA NoDevice
28630fdf276SDag-Erling Smørgrav 		|
28730fdf276SDag-Erling Smørgrav 	NoDevice
28830fdf276SDag-Erling Smørgrav 		;
28930fdf276SDag-Erling Smørgrav 
29030fdf276SDag-Erling Smørgrav Device:
29191998fc5SWarner Losh 	Dev {
292993e5c4fSKyle Evans 		newopt(&opt, devopt($1), ns("1"), 0, 0);
29310ca19cfSPeter Wemm 		/* and the device part */
29430fdf276SDag-Erling Smørgrav 		newdev($1);
29530fdf276SDag-Erling Smørgrav 		}
29630fdf276SDag-Erling Smørgrav 
29730fdf276SDag-Erling Smørgrav NoDevice:
29891998fc5SWarner Losh 	Dev {
29930fdf276SDag-Erling Smørgrav 		char *s = devopt($1);
30082401849SRuslan Ermilov 
301c1f4dd93SWarner Losh 		rmopt_schedule(&opt, s);
30282401849SRuslan Ermilov 		free(s);
3030b56eafdSRuslan Ermilov 		/* and the device part */
304c1f4dd93SWarner Losh 		rmdev_schedule(&dtab, $1);
305ac0711e1SPeter Wemm 		} ;
306dea673e9SRodney W. Grimes 
307dea673e9SRodney W. Grimes %%
308dea673e9SRodney W. Grimes 
3095dda778dSDapeng Gao int
31068f4fcedSPeter Wemm yyerror(const char *s)
311dea673e9SRodney W. Grimes {
312bc8600f6SPhilippe Charnier 
3135e06480cSDima Dorfman 	errx(1, "%s:%d: %s", yyfile, yyline + 1, s);
314dea673e9SRodney W. Grimes }
315dea673e9SRodney W. Grimes 
316dfdbf9beSJohn Baldwin int
yywrap(void)317dfdbf9beSJohn Baldwin yywrap(void)
318dfdbf9beSJohn Baldwin {
319c1f4dd93SWarner Losh 	if (found_defaults) {
320c1f4dd93SWarner Losh 		if (freopen(PREFIX, "r", stdin) == NULL)
321c1f4dd93SWarner Losh 			err(2, "%s", PREFIX);
322c1f4dd93SWarner Losh 		yyfile = PREFIX;
323dfdbf9beSJohn Baldwin 		yyline = 0;
324c1f4dd93SWarner Losh 		found_defaults = 0;
325dfdbf9beSJohn Baldwin 		return 0;
326dfdbf9beSJohn Baldwin 	}
327dfdbf9beSJohn Baldwin 	return 1;
328dfdbf9beSJohn Baldwin }
329dfdbf9beSJohn Baldwin 
330dea673e9SRodney W. Grimes /*
33143a903c0SOlivier Houchard  * Add a new file to the list of files.
33243a903c0SOlivier Houchard  */
33343a903c0SOlivier Houchard static void
newfile(char * name)33443a903c0SOlivier Houchard newfile(char *name)
33543a903c0SOlivier Houchard {
33643a903c0SOlivier Houchard 	struct files_name *nl;
33743a903c0SOlivier Houchard 
3385f17c1e2SXin LI 	nl = (struct files_name *) calloc(1, sizeof *nl);
33953d55e97SRuslan Ermilov 	if (nl == NULL)
34053d55e97SRuslan Ermilov 		err(EXIT_FAILURE, "calloc");
34143a903c0SOlivier Houchard 	nl->f_name = name;
34243a903c0SOlivier Houchard 	STAILQ_INSERT_TAIL(&fntab, nl, f_next);
34343a903c0SOlivier Houchard }
34443a903c0SOlivier Houchard 
345*9e2b8720SStephen J. Kiernan /*
346*9e2b8720SStephen J. Kiernan  * Add a new options file to the list of options files.
347*9e2b8720SStephen J. Kiernan  */
348*9e2b8720SStephen J. Kiernan static void
newoptionsfile(char * name)349*9e2b8720SStephen J. Kiernan newoptionsfile(char *name)
350*9e2b8720SStephen J. Kiernan {
351*9e2b8720SStephen J. Kiernan 	struct files_name *nl;
352*9e2b8720SStephen J. Kiernan 
353*9e2b8720SStephen J. Kiernan 	nl = (struct files_name *) calloc(1, sizeof *nl);
354*9e2b8720SStephen J. Kiernan 	if (nl == NULL)
355*9e2b8720SStephen J. Kiernan 		err(EXIT_FAILURE, "calloc");
356*9e2b8720SStephen J. Kiernan 	nl->f_name = name;
357*9e2b8720SStephen J. Kiernan 	STAILQ_INSERT_TAIL(&optfntab, nl, f_next);
358*9e2b8720SStephen J. Kiernan }
359*9e2b8720SStephen J. Kiernan 
3604edfa908SKyle Evans static void
newenvvar(char * name,bool is_file)3614edfa908SKyle Evans newenvvar(char *name, bool is_file)
3624edfa908SKyle Evans {
3634edfa908SKyle Evans 	struct envvar *envvar;
3644edfa908SKyle Evans 
3654edfa908SKyle Evans 	envvar = (struct envvar *)calloc(1, sizeof (struct envvar));
3664edfa908SKyle Evans 	if (envvar == NULL)
3674edfa908SKyle Evans 		err(EXIT_FAILURE, "calloc");
3684edfa908SKyle Evans 	envvar->env_str = name;
3694edfa908SKyle Evans 	envvar->env_is_file = is_file;
3706ffdd5efSKyle Evans 	STAILQ_INSERT_HEAD(&envvars, envvar, envvar_next);
3714edfa908SKyle Evans }
3724edfa908SKyle Evans 
37343a903c0SOlivier Houchard /*
3748ee64886SRuslan Ermilov  * Find a device in the list of devices.
3758ee64886SRuslan Ermilov  */
3768ee64886SRuslan Ermilov static struct device *
finddev(struct device_head * dlist,char * name)377744b947eSWojciech A. Koszek finddev(struct device_head *dlist, char *name)
3788ee64886SRuslan Ermilov {
3798ee64886SRuslan Ermilov 	struct device *dp;
3808ee64886SRuslan Ermilov 
381744b947eSWojciech A. Koszek 	STAILQ_FOREACH(dp, dlist, d_next)
3828ee64886SRuslan Ermilov 		if (eq(dp->d_name, name))
3838ee64886SRuslan Ermilov 			return (dp);
3848ee64886SRuslan Ermilov 
3858ee64886SRuslan Ermilov 	return (NULL);
3868ee64886SRuslan Ermilov }
3878ee64886SRuslan Ermilov 
3888ee64886SRuslan Ermilov /*
3898ee64886SRuslan Ermilov  * Add a device to the list of devices.
390dea673e9SRodney W. Grimes  */
391188334f6SPeter Wemm static void
newdev(char * name)392f37a929cSPeter Wemm newdev(char *name)
393dea673e9SRodney W. Grimes {
39491221f54SEmmanuel Vadot 	struct device *np, *dp;
395dea673e9SRodney W. Grimes 
39691221f54SEmmanuel Vadot 	if ((dp = finddev(&dtab, name)) != NULL) {
39791221f54SEmmanuel Vadot 		if (strcmp(dp->yyfile, yyfile) == 0)
3985eb01644SWarner Losh 			fprintf(stderr,
39991221f54SEmmanuel Vadot 			    "WARNING: duplicate device `%s' encountered in %s\n",
40091221f54SEmmanuel Vadot 			    name, yyfile);
4018ee64886SRuslan Ermilov 		return;
4028ee64886SRuslan Ermilov 	}
4038ee64886SRuslan Ermilov 
4045f17c1e2SXin LI 	np = (struct device *) calloc(1, sizeof *np);
40553d55e97SRuslan Ermilov 	if (np == NULL)
40653d55e97SRuslan Ermilov 		err(EXIT_FAILURE, "calloc");
4072db1cff1SPeter Wemm 	np->d_name = name;
40891221f54SEmmanuel Vadot 	np->yyfile = strdup(yyfile);
409292dd8a8SRuslan Ermilov 	STAILQ_INSERT_TAIL(&dtab, np, d_next);
410dea673e9SRodney W. Grimes }
4112db1cff1SPeter Wemm 
4120b56eafdSRuslan Ermilov /*
413744b947eSWojciech A. Koszek  * Schedule a device to removal.
4140b56eafdSRuslan Ermilov  */
4150b56eafdSRuslan Ermilov static void
rmdev_schedule(struct device_head * dh,char * name)416744b947eSWojciech A. Koszek rmdev_schedule(struct device_head *dh, char *name)
4170b56eafdSRuslan Ermilov {
4188ee64886SRuslan Ermilov 	struct device *dp;
4190b56eafdSRuslan Ermilov 
420c1f4dd93SWarner Losh 	dp = finddev(dh, name);
421c1f4dd93SWarner Losh 	if (dp != NULL) {
422c1f4dd93SWarner Losh 		STAILQ_REMOVE(dh, dp, device, d_next);
42391221f54SEmmanuel Vadot 		free(dp->yyfile);
424c1f4dd93SWarner Losh 		free(dp->d_name);
4258ee64886SRuslan Ermilov 		free(dp);
4260b56eafdSRuslan Ermilov 	}
4270b56eafdSRuslan Ermilov }
4280b56eafdSRuslan Ermilov 
4298ee64886SRuslan Ermilov /*
4308ee64886SRuslan Ermilov  * Find an option in the list of options.
4318ee64886SRuslan Ermilov  */
4328ee64886SRuslan Ermilov static struct opt *
findopt(struct opt_head * list,char * name)4338ee64886SRuslan Ermilov findopt(struct opt_head *list, char *name)
4348ee64886SRuslan Ermilov {
4358ee64886SRuslan Ermilov 	struct opt *op;
4368ee64886SRuslan Ermilov 
4378ee64886SRuslan Ermilov 	SLIST_FOREACH(op, list, op_next)
4388ee64886SRuslan Ermilov 		if (eq(op->op_name, name))
4398ee64886SRuslan Ermilov 			return (op);
4408ee64886SRuslan Ermilov 
4418ee64886SRuslan Ermilov 	return (NULL);
4428ee64886SRuslan Ermilov }
4438ee64886SRuslan Ermilov 
4448ee64886SRuslan Ermilov /*
4458ee64886SRuslan Ermilov  * Add an option to the list of options.
4468ee64886SRuslan Ermilov  */
4472db1cff1SPeter Wemm static void
newopt(struct opt_head * list,char * name,char * value,int append,int dupe)448993e5c4fSKyle Evans newopt(struct opt_head *list, char *name, char *value, int append, int dupe)
4492db1cff1SPeter Wemm {
4502880daebSAndrew Thompson 	struct opt *op, *op2;
4512db1cff1SPeter Wemm 
452744b947eSWojciech A. Koszek 	/*
453744b947eSWojciech A. Koszek 	 * Ignore inclusions listed explicitly for configuration files.
454744b947eSWojciech A. Koszek 	 */
455744b947eSWojciech A. Koszek 	if (eq(name, OPT_AUTOGEN)) {
456744b947eSWojciech A. Koszek 		incignore = 1;
457744b947eSWojciech A. Koszek 		return;
458744b947eSWojciech A. Koszek 	}
459744b947eSWojciech A. Koszek 
4602880daebSAndrew Thompson 	op2 = findopt(list, name);
461993e5c4fSKyle Evans 	if (op2 != NULL && !append && !dupe) {
46291221f54SEmmanuel Vadot 		if (strcmp(op2->yyfile, yyfile) == 0)
4635eb01644SWarner Losh 			fprintf(stderr,
4645eb01644SWarner Losh 			    "WARNING: duplicate option `%s' encountered.\n", name);
4658ee64886SRuslan Ermilov 		return;
4668ee64886SRuslan Ermilov 	}
4678ee64886SRuslan Ermilov 
4685f17c1e2SXin LI 	op = (struct opt *)calloc(1, sizeof (struct opt));
46953d55e97SRuslan Ermilov 	if (op == NULL)
47053d55e97SRuslan Ermilov 		err(EXIT_FAILURE, "calloc");
4712db1cff1SPeter Wemm 	op->op_name = name;
4722db1cff1SPeter Wemm 	op->op_ownfile = 0;
4732db1cff1SPeter Wemm 	op->op_value = value;
47491221f54SEmmanuel Vadot 	op->yyfile = strdup(yyfile);
4752880daebSAndrew Thompson 	if (op2 != NULL) {
476993e5c4fSKyle Evans 		if (append) {
4772880daebSAndrew Thompson 			while (SLIST_NEXT(op2, op_append) != NULL)
4782880daebSAndrew Thompson 				op2 = SLIST_NEXT(op2, op_append);
4792880daebSAndrew Thompson 			SLIST_NEXT(op2, op_append) = op;
480993e5c4fSKyle Evans 		} else {
481993e5c4fSKyle Evans 			while (SLIST_NEXT(op2, op_next) != NULL)
482993e5c4fSKyle Evans 				op2 = SLIST_NEXT(op2, op_next);
483993e5c4fSKyle Evans 			SLIST_NEXT(op2, op_next) = op;
484993e5c4fSKyle Evans 		}
4852880daebSAndrew Thompson 	} else
486292dd8a8SRuslan Ermilov 		SLIST_INSERT_HEAD(list, op, op_next);
4872db1cff1SPeter Wemm }
4880b56eafdSRuslan Ermilov 
4898ee64886SRuslan Ermilov /*
4908ee64886SRuslan Ermilov  * Remove an option from the list of options.
4918ee64886SRuslan Ermilov  */
4920b56eafdSRuslan Ermilov static void
rmopt_schedule(struct opt_head * list,char * name)493744b947eSWojciech A. Koszek rmopt_schedule(struct opt_head *list, char *name)
4940b56eafdSRuslan Ermilov {
4958ee64886SRuslan Ermilov 	struct opt *op;
4960b56eafdSRuslan Ermilov 
497ac0a7e2aSKyle Evans 	while ((op = findopt(list, name)) != NULL) {
498c1f4dd93SWarner Losh 		SLIST_REMOVE(list, op, opt, op_next);
49991221f54SEmmanuel Vadot 		free(op->yyfile);
500c1f4dd93SWarner Losh 		free(op->op_name);
5018ee64886SRuslan Ermilov 		free(op);
5020b56eafdSRuslan Ermilov 	}
5030b56eafdSRuslan Ermilov }
504