xref: /freebsd/usr.bin/iscsictl/parse.y (revision 5381f86246abeb87998d32c9c889a023aa2a5e25)
1009ea47eSEdward Tomasz Napierala %{
2009ea47eSEdward Tomasz Napierala /*-
3009ea47eSEdward Tomasz Napierala  * Copyright (c) 2012 The FreeBSD Foundation
4009ea47eSEdward Tomasz Napierala  * All rights reserved.
5009ea47eSEdward Tomasz Napierala  *
6009ea47eSEdward Tomasz Napierala  * This software was developed by Edward Tomasz Napierala under sponsorship
7009ea47eSEdward Tomasz Napierala  * from the FreeBSD Foundation.
8009ea47eSEdward Tomasz Napierala  *
9009ea47eSEdward Tomasz Napierala  * Redistribution and use in source and binary forms, with or without
10009ea47eSEdward Tomasz Napierala  * modification, are permitted provided that the following conditions
11009ea47eSEdward Tomasz Napierala  * are met:
12009ea47eSEdward Tomasz Napierala  * 1. Redistributions of source code must retain the above copyright
13009ea47eSEdward Tomasz Napierala  *    notice, this list of conditions and the following disclaimer.
14009ea47eSEdward Tomasz Napierala  * 2. Redistributions in binary form must reproduce the above copyright
15009ea47eSEdward Tomasz Napierala  *    notice, this list of conditions and the following disclaimer in the
16009ea47eSEdward Tomasz Napierala  *    documentation and/or other materials provided with the distribution.
17009ea47eSEdward Tomasz Napierala  *
18009ea47eSEdward Tomasz Napierala  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19009ea47eSEdward Tomasz Napierala  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20009ea47eSEdward Tomasz Napierala  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21009ea47eSEdward Tomasz Napierala  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22009ea47eSEdward Tomasz Napierala  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23009ea47eSEdward Tomasz Napierala  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24009ea47eSEdward Tomasz Napierala  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25009ea47eSEdward Tomasz Napierala  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26009ea47eSEdward Tomasz Napierala  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27009ea47eSEdward Tomasz Napierala  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28009ea47eSEdward Tomasz Napierala  * SUCH DAMAGE.
29009ea47eSEdward Tomasz Napierala  *
30009ea47eSEdward Tomasz Napierala  * $FreeBSD$
31009ea47eSEdward Tomasz Napierala  */
32009ea47eSEdward Tomasz Napierala 
33009ea47eSEdward Tomasz Napierala #include <sys/queue.h>
34009ea47eSEdward Tomasz Napierala #include <sys/types.h>
35009ea47eSEdward Tomasz Napierala #include <sys/stat.h>
36009ea47eSEdward Tomasz Napierala #include <assert.h>
37009ea47eSEdward Tomasz Napierala #include <err.h>
38009ea47eSEdward Tomasz Napierala #include <stdio.h>
39009ea47eSEdward Tomasz Napierala #include <stdint.h>
40009ea47eSEdward Tomasz Napierala #include <stdlib.h>
41009ea47eSEdward Tomasz Napierala #include <string.h>
42009ea47eSEdward Tomasz Napierala 
43009ea47eSEdward Tomasz Napierala #include "iscsictl.h"
44009ea47eSEdward Tomasz Napierala 
45009ea47eSEdward Tomasz Napierala extern FILE *yyin;
46009ea47eSEdward Tomasz Napierala extern char *yytext;
47009ea47eSEdward Tomasz Napierala extern int lineno;
48009ea47eSEdward Tomasz Napierala 
49009ea47eSEdward Tomasz Napierala static struct conf *conf;
50009ea47eSEdward Tomasz Napierala static struct target *target;
51009ea47eSEdward Tomasz Napierala 
52009ea47eSEdward Tomasz Napierala extern void	yyerror(const char *);
53009ea47eSEdward Tomasz Napierala extern int	yylex(void);
54009ea47eSEdward Tomasz Napierala extern void	yyrestart(FILE *);
55009ea47eSEdward Tomasz Napierala 
56009ea47eSEdward Tomasz Napierala %}
57009ea47eSEdward Tomasz Napierala 
58009ea47eSEdward Tomasz Napierala %token AUTH_METHOD HEADER_DIGEST DATA_DIGEST TARGET_NAME TARGET_ADDRESS
59009ea47eSEdward Tomasz Napierala %token INITIATOR_NAME INITIATOR_ADDRESS INITIATOR_ALIAS USER SECRET
60009ea47eSEdward Tomasz Napierala %token MUTUAL_USER MUTUAL_SECRET SESSION_TYPE PROTOCOL IGNORED
61009ea47eSEdward Tomasz Napierala %token EQUALS OPENING_BRACKET CLOSING_BRACKET
62009ea47eSEdward Tomasz Napierala 
63009ea47eSEdward Tomasz Napierala %union
64009ea47eSEdward Tomasz Napierala {
65009ea47eSEdward Tomasz Napierala 	char *str;
66009ea47eSEdward Tomasz Napierala }
67009ea47eSEdward Tomasz Napierala 
68009ea47eSEdward Tomasz Napierala %token <str> STR
69009ea47eSEdward Tomasz Napierala 
70009ea47eSEdward Tomasz Napierala %%
71009ea47eSEdward Tomasz Napierala 
72*5381f862SEdward Tomasz Napierala targets:
73009ea47eSEdward Tomasz Napierala 	|
74*5381f862SEdward Tomasz Napierala 	targets target
75009ea47eSEdward Tomasz Napierala 	;
76009ea47eSEdward Tomasz Napierala 
77*5381f862SEdward Tomasz Napierala target:		STR OPENING_BRACKET target_entries CLOSING_BRACKET
78009ea47eSEdward Tomasz Napierala 	{
79009ea47eSEdward Tomasz Napierala 		if (target_find(conf, $1) != NULL)
80009ea47eSEdward Tomasz Napierala 			errx(1, "duplicated target %s", $1);
81009ea47eSEdward Tomasz Napierala 		target->t_nickname = $1;
82009ea47eSEdward Tomasz Napierala 		target = target_new(conf);
83009ea47eSEdward Tomasz Napierala 	}
84009ea47eSEdward Tomasz Napierala 	;
85009ea47eSEdward Tomasz Napierala 
86009ea47eSEdward Tomasz Napierala target_entries:
87009ea47eSEdward Tomasz Napierala 	|
88009ea47eSEdward Tomasz Napierala 	target_entries target_entry
89009ea47eSEdward Tomasz Napierala 	;
90009ea47eSEdward Tomasz Napierala 
91009ea47eSEdward Tomasz Napierala target_entry:
92*5381f862SEdward Tomasz Napierala 	target_name
93009ea47eSEdward Tomasz Napierala 	|
94*5381f862SEdward Tomasz Napierala 	target_address
95009ea47eSEdward Tomasz Napierala 	|
96*5381f862SEdward Tomasz Napierala 	initiator_name
97009ea47eSEdward Tomasz Napierala 	|
98*5381f862SEdward Tomasz Napierala 	initiator_address
99009ea47eSEdward Tomasz Napierala 	|
100*5381f862SEdward Tomasz Napierala 	initiator_alias
101009ea47eSEdward Tomasz Napierala 	|
102*5381f862SEdward Tomasz Napierala 	user
103009ea47eSEdward Tomasz Napierala 	|
104*5381f862SEdward Tomasz Napierala 	secret
105009ea47eSEdward Tomasz Napierala 	|
106*5381f862SEdward Tomasz Napierala 	mutual_user
107009ea47eSEdward Tomasz Napierala 	|
108*5381f862SEdward Tomasz Napierala 	mutual_secret
109009ea47eSEdward Tomasz Napierala 	|
110*5381f862SEdward Tomasz Napierala 	auth_method
111009ea47eSEdward Tomasz Napierala 	|
112*5381f862SEdward Tomasz Napierala 	header_digest
113009ea47eSEdward Tomasz Napierala 	|
114*5381f862SEdward Tomasz Napierala 	data_digest
115009ea47eSEdward Tomasz Napierala 	|
116*5381f862SEdward Tomasz Napierala 	session_type
117009ea47eSEdward Tomasz Napierala 	|
118*5381f862SEdward Tomasz Napierala 	protocol
119009ea47eSEdward Tomasz Napierala 	|
120*5381f862SEdward Tomasz Napierala 	ignored
121009ea47eSEdward Tomasz Napierala 	;
122009ea47eSEdward Tomasz Napierala 
123*5381f862SEdward Tomasz Napierala target_name:	TARGET_NAME EQUALS STR
124009ea47eSEdward Tomasz Napierala 	{
125009ea47eSEdward Tomasz Napierala 		if (target->t_name != NULL)
126009ea47eSEdward Tomasz Napierala 			errx(1, "duplicated TargetName at line %d", lineno + 1);
127009ea47eSEdward Tomasz Napierala 		target->t_name = $3;
128009ea47eSEdward Tomasz Napierala 	}
129009ea47eSEdward Tomasz Napierala 	;
130009ea47eSEdward Tomasz Napierala 
131*5381f862SEdward Tomasz Napierala target_address:	TARGET_ADDRESS EQUALS STR
132009ea47eSEdward Tomasz Napierala 	{
133009ea47eSEdward Tomasz Napierala 		if (target->t_address != NULL)
134009ea47eSEdward Tomasz Napierala 			errx(1, "duplicated TargetAddress at line %d", lineno + 1);
135009ea47eSEdward Tomasz Napierala 		target->t_address = $3;
136009ea47eSEdward Tomasz Napierala 	}
137009ea47eSEdward Tomasz Napierala 	;
138009ea47eSEdward Tomasz Napierala 
139*5381f862SEdward Tomasz Napierala initiator_name:	INITIATOR_NAME EQUALS STR
140009ea47eSEdward Tomasz Napierala 	{
141009ea47eSEdward Tomasz Napierala 		if (target->t_initiator_name != NULL)
142009ea47eSEdward Tomasz Napierala 			errx(1, "duplicated InitiatorName at line %d", lineno + 1);
143009ea47eSEdward Tomasz Napierala 		target->t_initiator_name = $3;
144009ea47eSEdward Tomasz Napierala 	}
145009ea47eSEdward Tomasz Napierala 	;
146009ea47eSEdward Tomasz Napierala 
147*5381f862SEdward Tomasz Napierala initiator_address:	INITIATOR_ADDRESS EQUALS STR
148009ea47eSEdward Tomasz Napierala 	{
149009ea47eSEdward Tomasz Napierala 		if (target->t_initiator_address != NULL)
150009ea47eSEdward Tomasz Napierala 			errx(1, "duplicated InitiatorAddress at line %d", lineno + 1);
151009ea47eSEdward Tomasz Napierala 		target->t_initiator_address = $3;
152009ea47eSEdward Tomasz Napierala 	}
153009ea47eSEdward Tomasz Napierala 	;
154009ea47eSEdward Tomasz Napierala 
155*5381f862SEdward Tomasz Napierala initiator_alias:	INITIATOR_ALIAS EQUALS STR
156009ea47eSEdward Tomasz Napierala 	{
157009ea47eSEdward Tomasz Napierala 		if (target->t_initiator_alias != NULL)
158009ea47eSEdward Tomasz Napierala 			errx(1, "duplicated InitiatorAlias at line %d", lineno + 1);
159009ea47eSEdward Tomasz Napierala 		target->t_initiator_alias = $3;
160009ea47eSEdward Tomasz Napierala 	}
161009ea47eSEdward Tomasz Napierala 	;
162009ea47eSEdward Tomasz Napierala 
163*5381f862SEdward Tomasz Napierala user:		USER EQUALS STR
164009ea47eSEdward Tomasz Napierala 	{
165009ea47eSEdward Tomasz Napierala 		if (target->t_user != NULL)
166009ea47eSEdward Tomasz Napierala 			errx(1, "duplicated chapIName at line %d", lineno + 1);
167009ea47eSEdward Tomasz Napierala 		target->t_user = $3;
168009ea47eSEdward Tomasz Napierala 	}
169009ea47eSEdward Tomasz Napierala 	;
170009ea47eSEdward Tomasz Napierala 
171*5381f862SEdward Tomasz Napierala secret:		SECRET EQUALS STR
172009ea47eSEdward Tomasz Napierala 	{
173009ea47eSEdward Tomasz Napierala 		if (target->t_secret != NULL)
174009ea47eSEdward Tomasz Napierala 			errx(1, "duplicated chapSecret at line %d", lineno + 1);
175009ea47eSEdward Tomasz Napierala 		target->t_secret = $3;
176009ea47eSEdward Tomasz Napierala 	}
177009ea47eSEdward Tomasz Napierala 	;
178009ea47eSEdward Tomasz Napierala 
179*5381f862SEdward Tomasz Napierala mutual_user:	MUTUAL_USER EQUALS STR
180009ea47eSEdward Tomasz Napierala 	{
181009ea47eSEdward Tomasz Napierala 		if (target->t_mutual_user != NULL)
182009ea47eSEdward Tomasz Napierala 			errx(1, "duplicated tgtChapName at line %d", lineno + 1);
183009ea47eSEdward Tomasz Napierala 		target->t_mutual_user = $3;
184009ea47eSEdward Tomasz Napierala 	}
185009ea47eSEdward Tomasz Napierala 	;
186009ea47eSEdward Tomasz Napierala 
187*5381f862SEdward Tomasz Napierala mutual_secret:	MUTUAL_SECRET EQUALS STR
188009ea47eSEdward Tomasz Napierala 	{
189009ea47eSEdward Tomasz Napierala 		if (target->t_mutual_secret != NULL)
190009ea47eSEdward Tomasz Napierala 			errx(1, "duplicated tgtChapSecret at line %d", lineno + 1);
191009ea47eSEdward Tomasz Napierala 		target->t_mutual_secret = $3;
192009ea47eSEdward Tomasz Napierala 	}
193009ea47eSEdward Tomasz Napierala 	;
194009ea47eSEdward Tomasz Napierala 
195*5381f862SEdward Tomasz Napierala auth_method:	AUTH_METHOD EQUALS STR
196009ea47eSEdward Tomasz Napierala 	{
197009ea47eSEdward Tomasz Napierala 		if (target->t_auth_method != AUTH_METHOD_UNSPECIFIED)
198009ea47eSEdward Tomasz Napierala 			errx(1, "duplicated AuthMethod at line %d", lineno + 1);
199009ea47eSEdward Tomasz Napierala 		if (strcasecmp($3, "none") == 0)
200009ea47eSEdward Tomasz Napierala 			target->t_auth_method = AUTH_METHOD_NONE;
201009ea47eSEdward Tomasz Napierala 		else if (strcasecmp($3, "chap") == 0)
202009ea47eSEdward Tomasz Napierala 			target->t_auth_method = AUTH_METHOD_CHAP;
203009ea47eSEdward Tomasz Napierala 		else
204009ea47eSEdward Tomasz Napierala 			errx(1, "invalid AuthMethod at line %d; "
205009ea47eSEdward Tomasz Napierala 			    "must be either \"none\" or \"CHAP\"", lineno + 1);
206009ea47eSEdward Tomasz Napierala 	}
207009ea47eSEdward Tomasz Napierala 	;
208009ea47eSEdward Tomasz Napierala 
209*5381f862SEdward Tomasz Napierala header_digest:	HEADER_DIGEST EQUALS STR
210009ea47eSEdward Tomasz Napierala 	{
211009ea47eSEdward Tomasz Napierala 		if (target->t_header_digest != DIGEST_UNSPECIFIED)
212009ea47eSEdward Tomasz Napierala 			errx(1, "duplicated HeaderDigest at line %d", lineno + 1);
213009ea47eSEdward Tomasz Napierala 		if (strcasecmp($3, "none") == 0)
214009ea47eSEdward Tomasz Napierala 			target->t_header_digest = DIGEST_NONE;
215009ea47eSEdward Tomasz Napierala 		else if (strcasecmp($3, "CRC32C") == 0)
216009ea47eSEdward Tomasz Napierala 			target->t_header_digest = DIGEST_CRC32C;
217009ea47eSEdward Tomasz Napierala 		else
218009ea47eSEdward Tomasz Napierala 			errx(1, "invalid HeaderDigest at line %d; "
219009ea47eSEdward Tomasz Napierala 			    "must be either \"none\" or \"CRC32C\"", lineno + 1);
220009ea47eSEdward Tomasz Napierala 	}
221009ea47eSEdward Tomasz Napierala 	;
222009ea47eSEdward Tomasz Napierala 
223*5381f862SEdward Tomasz Napierala data_digest:	DATA_DIGEST EQUALS STR
224009ea47eSEdward Tomasz Napierala 	{
225009ea47eSEdward Tomasz Napierala 		if (target->t_data_digest != DIGEST_UNSPECIFIED)
226009ea47eSEdward Tomasz Napierala 			errx(1, "duplicated DataDigest at line %d", lineno + 1);
227009ea47eSEdward Tomasz Napierala 		if (strcasecmp($3, "none") == 0)
228009ea47eSEdward Tomasz Napierala 			target->t_data_digest = DIGEST_NONE;
229009ea47eSEdward Tomasz Napierala 		else if (strcasecmp($3, "CRC32C") == 0)
230009ea47eSEdward Tomasz Napierala 			target->t_data_digest = DIGEST_CRC32C;
231009ea47eSEdward Tomasz Napierala 		else
232009ea47eSEdward Tomasz Napierala 			errx(1, "invalid DataDigest at line %d; "
233009ea47eSEdward Tomasz Napierala 			    "must be either \"none\" or \"CRC32C\"", lineno + 1);
234009ea47eSEdward Tomasz Napierala 	}
235009ea47eSEdward Tomasz Napierala 	;
236009ea47eSEdward Tomasz Napierala 
237*5381f862SEdward Tomasz Napierala session_type:	SESSION_TYPE EQUALS STR
238009ea47eSEdward Tomasz Napierala 	{
239009ea47eSEdward Tomasz Napierala 		if (target->t_session_type != SESSION_TYPE_UNSPECIFIED)
240009ea47eSEdward Tomasz Napierala 			errx(1, "duplicated SessionType at line %d", lineno + 1);
241009ea47eSEdward Tomasz Napierala 		if (strcasecmp($3, "normal") == 0)
242009ea47eSEdward Tomasz Napierala 			target->t_session_type = SESSION_TYPE_NORMAL;
243009ea47eSEdward Tomasz Napierala 		else if (strcasecmp($3, "discovery") == 0)
244009ea47eSEdward Tomasz Napierala 			target->t_session_type = SESSION_TYPE_DISCOVERY;
245009ea47eSEdward Tomasz Napierala 		else
246009ea47eSEdward Tomasz Napierala 			errx(1, "invalid SessionType at line %d; "
247009ea47eSEdward Tomasz Napierala 			    "must be either \"normal\" or \"discovery\"", lineno + 1);
248009ea47eSEdward Tomasz Napierala 	}
249009ea47eSEdward Tomasz Napierala 	;
250009ea47eSEdward Tomasz Napierala 
251*5381f862SEdward Tomasz Napierala protocol:	PROTOCOL EQUALS STR
252009ea47eSEdward Tomasz Napierala 	{
253009ea47eSEdward Tomasz Napierala 		if (target->t_protocol != PROTOCOL_UNSPECIFIED)
254009ea47eSEdward Tomasz Napierala 			errx(1, "duplicated protocol at line %d", lineno + 1);
255009ea47eSEdward Tomasz Napierala 		if (strcasecmp($3, "iscsi") == 0)
256009ea47eSEdward Tomasz Napierala 			target->t_protocol = PROTOCOL_ISCSI;
257009ea47eSEdward Tomasz Napierala 		else if (strcasecmp($3, "iser") == 0)
258009ea47eSEdward Tomasz Napierala 			target->t_protocol = PROTOCOL_ISER;
259009ea47eSEdward Tomasz Napierala 		else
260009ea47eSEdward Tomasz Napierala 			errx(1, "invalid protocol at line %d; "
261009ea47eSEdward Tomasz Napierala 			    "must be either \"iscsi\" or \"iser\"", lineno + 1);
262009ea47eSEdward Tomasz Napierala 	}
263009ea47eSEdward Tomasz Napierala 	;
264009ea47eSEdward Tomasz Napierala 
265*5381f862SEdward Tomasz Napierala ignored:	IGNORED EQUALS STR
266009ea47eSEdward Tomasz Napierala 	{
267009ea47eSEdward Tomasz Napierala 		warnx("obsolete statement ignored at line %d", lineno + 1);
268009ea47eSEdward Tomasz Napierala 	}
269009ea47eSEdward Tomasz Napierala 	;
270009ea47eSEdward Tomasz Napierala 
271009ea47eSEdward Tomasz Napierala %%
272009ea47eSEdward Tomasz Napierala 
273009ea47eSEdward Tomasz Napierala void
274009ea47eSEdward Tomasz Napierala yyerror(const char *str)
275009ea47eSEdward Tomasz Napierala {
276009ea47eSEdward Tomasz Napierala 
277009ea47eSEdward Tomasz Napierala 	errx(1, "error in configuration file at line %d near '%s': %s",
278009ea47eSEdward Tomasz Napierala 	    lineno + 1, yytext, str);
279009ea47eSEdward Tomasz Napierala }
280009ea47eSEdward Tomasz Napierala 
281009ea47eSEdward Tomasz Napierala static void
282009ea47eSEdward Tomasz Napierala check_perms(const char *path)
283009ea47eSEdward Tomasz Napierala {
284009ea47eSEdward Tomasz Napierala 	struct stat sb;
285009ea47eSEdward Tomasz Napierala 	int error;
286009ea47eSEdward Tomasz Napierala 
287009ea47eSEdward Tomasz Napierala 	error = stat(path, &sb);
288009ea47eSEdward Tomasz Napierala 	if (error != 0) {
289009ea47eSEdward Tomasz Napierala 		warn("stat");
290009ea47eSEdward Tomasz Napierala 		return;
291009ea47eSEdward Tomasz Napierala 	}
292009ea47eSEdward Tomasz Napierala 	if (sb.st_mode & S_IWOTH) {
293009ea47eSEdward Tomasz Napierala 		warnx("%s is world-writable", path);
294009ea47eSEdward Tomasz Napierala 	} else if (sb.st_mode & S_IROTH) {
295009ea47eSEdward Tomasz Napierala 		warnx("%s is world-readable", path);
296009ea47eSEdward Tomasz Napierala 	} else if (sb.st_mode & S_IXOTH) {
297009ea47eSEdward Tomasz Napierala 		/*
298009ea47eSEdward Tomasz Napierala 		 * Ok, this one doesn't matter, but still do it,
299009ea47eSEdward Tomasz Napierala 		 * just for consistency.
300009ea47eSEdward Tomasz Napierala 		 */
301009ea47eSEdward Tomasz Napierala 		warnx("%s is world-executable", path);
302009ea47eSEdward Tomasz Napierala 	}
303009ea47eSEdward Tomasz Napierala 
304009ea47eSEdward Tomasz Napierala 	/*
305009ea47eSEdward Tomasz Napierala 	 * XXX: Should we also check for owner != 0?
306009ea47eSEdward Tomasz Napierala 	 */
307009ea47eSEdward Tomasz Napierala }
308009ea47eSEdward Tomasz Napierala 
309009ea47eSEdward Tomasz Napierala struct conf *
310009ea47eSEdward Tomasz Napierala conf_new_from_file(const char *path)
311009ea47eSEdward Tomasz Napierala {
312009ea47eSEdward Tomasz Napierala 	int error;
313009ea47eSEdward Tomasz Napierala 
314009ea47eSEdward Tomasz Napierala 	conf = conf_new();
315009ea47eSEdward Tomasz Napierala 	target = target_new(conf);
316009ea47eSEdward Tomasz Napierala 
317009ea47eSEdward Tomasz Napierala 	yyin = fopen(path, "r");
318009ea47eSEdward Tomasz Napierala 	if (yyin == NULL)
319009ea47eSEdward Tomasz Napierala 		err(1, "unable to open configuration file %s", path);
320009ea47eSEdward Tomasz Napierala 	check_perms(path);
321009ea47eSEdward Tomasz Napierala 	lineno = 0;
322009ea47eSEdward Tomasz Napierala 	yyrestart(yyin);
323009ea47eSEdward Tomasz Napierala 	error = yyparse();
324009ea47eSEdward Tomasz Napierala 	assert(error == 0);
325009ea47eSEdward Tomasz Napierala 	fclose(yyin);
326009ea47eSEdward Tomasz Napierala 
327009ea47eSEdward Tomasz Napierala 	assert(target->t_nickname == NULL);
328009ea47eSEdward Tomasz Napierala 	target_delete(target);
329009ea47eSEdward Tomasz Napierala 
330009ea47eSEdward Tomasz Napierala 	conf_verify(conf);
331009ea47eSEdward Tomasz Napierala 
332009ea47eSEdward Tomasz Napierala 	return (conf);
333009ea47eSEdward Tomasz Napierala }
334