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