]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.bin/iscsictl/parse.y
Remove spurious newline
[FreeBSD/FreeBSD.git] / usr.bin / iscsictl / parse.y
1 %{
2 /*-
3  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4  *
5  * Copyright (c) 2012 The FreeBSD Foundation
6  * All rights reserved.
7  *
8  * This software was developed by Edward Tomasz Napierala under sponsorship
9  * from the FreeBSD Foundation.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  * $FreeBSD$
33  */
34
35 #include <sys/queue.h>
36 #include <sys/types.h>
37 #include <sys/stat.h>
38 #include <assert.h>
39 #include <stdio.h>
40 #include <stdint.h>
41 #include <stdlib.h>
42 #include <string.h>
43
44 #include <libxo/xo.h>
45
46 #include "iscsictl.h"
47
48 extern FILE *yyin;
49 extern char *yytext;
50 extern int lineno;
51
52 static struct conf *conf;
53 static struct target *target;
54
55 extern void     yyerror(const char *);
56 extern int      yylex(void);
57 extern void     yyrestart(FILE *);
58
59 %}
60
61 %token AUTH_METHOD ENABLE HEADER_DIGEST DATA_DIGEST TARGET_NAME TARGET_ADDRESS
62 %token INITIATOR_NAME INITIATOR_ADDRESS INITIATOR_ALIAS USER SECRET
63 %token MUTUAL_USER MUTUAL_SECRET SEMICOLON SESSION_TYPE PROTOCOL OFFLOAD
64 %token IGNORED EQUALS OPENING_BRACKET CLOSING_BRACKET
65
66 %union
67 {
68         char *str;
69 }
70
71 %token <str> STR
72
73 %%
74
75 targets:
76         |
77         targets target
78         ;
79
80 target:         STR OPENING_BRACKET target_entries CLOSING_BRACKET
81         {
82                 if (target_find(conf, $1) != NULL)
83                         xo_errx(1, "duplicated target %s", $1);
84                 target->t_nickname = $1;
85                 target = target_new(conf);
86         }
87         ;
88
89 target_entries:
90         |
91         target_entries target_entry
92         |
93         target_entries target_entry SEMICOLON
94         ;
95
96 target_entry:
97         target_name
98         |
99         target_address
100         |
101         initiator_name
102         |
103         initiator_address
104         |
105         initiator_alias
106         |
107         user
108         |
109         secret
110         |
111         mutual_user
112         |
113         mutual_secret
114         |
115         auth_method
116         |
117         header_digest
118         |
119         data_digest
120         |
121         session_type
122         |
123         enable
124         |
125         offload
126         |
127         protocol
128         |
129         ignored
130         ;
131
132 target_name:    TARGET_NAME EQUALS STR
133         {
134                 if (target->t_name != NULL)
135                         xo_errx(1, "duplicated TargetName at line %d", lineno);
136                 target->t_name = $3;
137         }
138         ;
139
140 target_address: TARGET_ADDRESS EQUALS STR
141         {
142                 if (target->t_address != NULL)
143                         xo_errx(1, "duplicated TargetAddress at line %d", lineno);
144                 target->t_address = $3;
145         }
146         ;
147
148 initiator_name: INITIATOR_NAME EQUALS STR
149         {
150                 if (target->t_initiator_name != NULL)
151                         xo_errx(1, "duplicated InitiatorName at line %d", lineno);
152                 target->t_initiator_name = $3;
153         }
154         ;
155
156 initiator_address:      INITIATOR_ADDRESS EQUALS STR
157         {
158                 if (target->t_initiator_address != NULL)
159                         xo_errx(1, "duplicated InitiatorAddress at line %d", lineno);
160                 target->t_initiator_address = $3;
161         }
162         ;
163
164 initiator_alias:        INITIATOR_ALIAS EQUALS STR
165         {
166                 if (target->t_initiator_alias != NULL)
167                         xo_errx(1, "duplicated InitiatorAlias at line %d", lineno);
168                 target->t_initiator_alias = $3;
169         }
170         ;
171
172 user:           USER EQUALS STR
173         {
174                 if (target->t_user != NULL)
175                         xo_errx(1, "duplicated chapIName at line %d", lineno);
176                 target->t_user = $3;
177         }
178         ;
179
180 secret:         SECRET EQUALS STR
181         {
182                 if (target->t_secret != NULL)
183                         xo_errx(1, "duplicated chapSecret at line %d", lineno);
184                 target->t_secret = $3;
185         }
186         ;
187
188 mutual_user:    MUTUAL_USER EQUALS STR
189         {
190                 if (target->t_mutual_user != NULL)
191                         xo_errx(1, "duplicated tgtChapName at line %d", lineno);
192                 target->t_mutual_user = $3;
193         }
194         ;
195
196 mutual_secret:  MUTUAL_SECRET EQUALS STR
197         {
198                 if (target->t_mutual_secret != NULL)
199                         xo_errx(1, "duplicated tgtChapSecret at line %d", lineno);
200                 target->t_mutual_secret = $3;
201         }
202         ;
203
204 auth_method:    AUTH_METHOD EQUALS STR
205         {
206                 if (target->t_auth_method != AUTH_METHOD_UNSPECIFIED)
207                         xo_errx(1, "duplicated AuthMethod at line %d", lineno);
208                 if (strcasecmp($3, "none") == 0)
209                         target->t_auth_method = AUTH_METHOD_NONE;
210                 else if (strcasecmp($3, "chap") == 0)
211                         target->t_auth_method = AUTH_METHOD_CHAP;
212                 else
213                         xo_errx(1, "invalid AuthMethod at line %d; "
214                             "must be either \"none\" or \"CHAP\"", lineno);
215         }
216         ;
217
218 header_digest:  HEADER_DIGEST EQUALS STR
219         {
220                 if (target->t_header_digest != DIGEST_UNSPECIFIED)
221                         xo_errx(1, "duplicated HeaderDigest at line %d", lineno);
222                 if (strcasecmp($3, "none") == 0)
223                         target->t_header_digest = DIGEST_NONE;
224                 else if (strcasecmp($3, "CRC32C") == 0)
225                         target->t_header_digest = DIGEST_CRC32C;
226                 else
227                         xo_errx(1, "invalid HeaderDigest at line %d; "
228                             "must be either \"none\" or \"CRC32C\"", lineno);
229         }
230         ;
231
232 data_digest:    DATA_DIGEST EQUALS STR
233         {
234                 if (target->t_data_digest != DIGEST_UNSPECIFIED)
235                         xo_errx(1, "duplicated DataDigest at line %d", lineno);
236                 if (strcasecmp($3, "none") == 0)
237                         target->t_data_digest = DIGEST_NONE;
238                 else if (strcasecmp($3, "CRC32C") == 0)
239                         target->t_data_digest = DIGEST_CRC32C;
240                 else
241                         xo_errx(1, "invalid DataDigest at line %d; "
242                             "must be either \"none\" or \"CRC32C\"", lineno);
243         }
244         ;
245
246 session_type:   SESSION_TYPE EQUALS STR
247         {
248                 if (target->t_session_type != SESSION_TYPE_UNSPECIFIED)
249                         xo_errx(1, "duplicated SessionType at line %d", lineno);
250                 if (strcasecmp($3, "normal") == 0)
251                         target->t_session_type = SESSION_TYPE_NORMAL;
252                 else if (strcasecmp($3, "discovery") == 0)
253                         target->t_session_type = SESSION_TYPE_DISCOVERY;
254                 else
255                         xo_errx(1, "invalid SessionType at line %d; "
256                             "must be either \"normal\" or \"discovery\"", lineno);
257         }
258         ;
259
260 enable:         ENABLE EQUALS STR
261         {
262                 if (target->t_enable != ENABLE_UNSPECIFIED)
263                         xo_errx(1, "duplicated enable at line %d", lineno);
264                 target->t_enable = parse_enable($3);
265                 if (target->t_enable == ENABLE_UNSPECIFIED)
266                         xo_errx(1, "invalid enable at line %d; "
267                             "must be either \"on\" or \"off\"", lineno);
268         }
269         ;
270
271 offload:        OFFLOAD EQUALS STR
272         {
273                 if (target->t_offload != NULL)
274                         xo_errx(1, "duplicated offload at line %d", lineno);
275                 target->t_offload = $3;
276         }
277         ;
278
279 protocol:       PROTOCOL EQUALS STR
280         {
281                 if (target->t_protocol != PROTOCOL_UNSPECIFIED)
282                         xo_errx(1, "duplicated protocol at line %d", lineno);
283                 if (strcasecmp($3, "iscsi") == 0)
284                         target->t_protocol = PROTOCOL_ISCSI;
285                 else if (strcasecmp($3, "iser") == 0)
286                         target->t_protocol = PROTOCOL_ISER;
287                 else
288                         xo_errx(1, "invalid protocol at line %d; "
289                             "must be either \"iscsi\" or \"iser\"", lineno);
290         }
291         ;
292
293 ignored:        IGNORED EQUALS STR
294         {
295                 xo_warnx("obsolete statement ignored at line %d", lineno);
296         }
297         ;
298
299 %%
300
301 void
302 yyerror(const char *str)
303 {
304
305         xo_errx(1, "error in configuration file at line %d near '%s': %s",
306             lineno, yytext, str);
307 }
308
309 static void
310 check_perms(const char *path)
311 {
312         struct stat sb;
313         int error;
314
315         error = stat(path, &sb);
316         if (error != 0) {
317                 xo_warn("stat");
318                 return;
319         }
320         if (sb.st_mode & S_IWOTH) {
321                 xo_warnx("%s is world-writable", path);
322         } else if (sb.st_mode & S_IROTH) {
323                 xo_warnx("%s is world-readable", path);
324         } else if (sb.st_mode & S_IXOTH) {
325                 /*
326                  * Ok, this one doesn't matter, but still do it,
327                  * just for consistency.
328                  */
329                 xo_warnx("%s is world-executable", path);
330         }
331
332         /*
333          * XXX: Should we also check for owner != 0?
334          */
335 }
336
337 struct conf *
338 conf_new_from_file(const char *path)
339 {
340         int error;
341
342         conf = conf_new();
343         target = target_new(conf);
344
345         yyin = fopen(path, "r");
346         if (yyin == NULL)
347                 xo_err(1, "unable to open configuration file %s", path);
348         check_perms(path);
349         lineno = 1;
350         yyrestart(yyin);
351         error = yyparse();
352         assert(error == 0);
353         fclose(yyin);
354
355         assert(target->t_nickname == NULL);
356         target_delete(target);
357
358         conf_verify(conf);
359
360         return (conf);
361 }