added missing equals() method assignment for ID_ANY identities
[strongswan.git] / src / starter / parser.y
1 %{
2 /* strongSwan config file parser (parser.y)
3  * Copyright (C) 2001 Mathieu Lafon - Arkoon Network Security
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License as published by the
7  * Free Software Foundation; either version 2 of the License, or (at your
8  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13  * for more details.
14  */
15
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19
20 #include <freeswan.h>
21
22 #include "../pluto/constants.h"
23 #include "../pluto/defs.h"
24 #include "../pluto/log.h"
25 #include "parser.h"
26
27 #define YYERROR_VERBOSE
28 #define ERRSTRING_LEN   256
29
30 /**
31  * Bison
32  */
33 static char parser_errstring[ERRSTRING_LEN+1];
34
35 extern void yyerror(const char *s);
36 extern int yylex (void);
37 extern void _parser_y_error(char *b, int size, const char *s);
38
39 /**
40  * Static Globals
41  */
42 static int _save_errors_;
43 static config_parsed_t *_parser_cfg;
44 static kw_list_t **_parser_kw, *_parser_kw_last;
45 static char errbuf[ERRSTRING_LEN+1];
46
47 /**
48  * Gperf
49  */
50 extern kw_entry_t *in_word_set (char *str, unsigned int len);
51
52 %}
53
54 %union { char *s; };
55 %token EQUAL FIRST_SPACES EOL CONFIG SETUP CONN CA INCLUDE FILE_VERSION
56 %token <s> STRING
57
58 %%
59
60 /*
61  * Config file
62  */
63
64 config_file:
65         config_file section_or_include
66         | /* NULL */                
67         ;
68
69 section_or_include:
70         FILE_VERSION STRING EOL
71         {
72                 free($2);
73         }
74         | CONFIG SETUP EOL
75         {
76                 _parser_kw = &(_parser_cfg->config_setup);
77                 _parser_kw_last = NULL;
78         } kw_section
79         | CONN STRING EOL
80         {
81                 section_list_t *section = malloc_thing(section_list_t);
82                 
83                 section->name = clone_str($2);
84                 section->kw = NULL;
85                 section->next = NULL;
86                 _parser_kw = &(section->kw);
87                 if (!_parser_cfg->conn_first)
88                         _parser_cfg->conn_first = section;
89                 if (_parser_cfg->conn_last)
90                         _parser_cfg->conn_last->next = section;
91                 _parser_cfg->conn_last = section;
92                 _parser_kw_last = NULL;
93                 free($2);
94         } kw_section
95         | CA STRING EOL
96         {
97                 section_list_t *section = malloc_thing(section_list_t);
98                 section->name = clone_str($2);
99                 section->kw = NULL;
100                 section->next = NULL;
101                 _parser_kw = &(section->kw);
102                 if (!_parser_cfg->ca_first)
103                         _parser_cfg->ca_first = section;
104                 if (_parser_cfg->ca_last)
105                         _parser_cfg->ca_last->next = section;
106                 _parser_cfg->ca_last = section;
107                 _parser_kw_last = NULL;
108                 free($2);
109         } kw_section
110         | INCLUDE STRING
111         {
112                 extern void _parser_y_include (const char *f);
113                 _parser_y_include($2);
114                 free($2);
115         } EOL
116         | EOL
117         ;
118
119 kw_section:
120         FIRST_SPACES statement_kw EOL kw_section
121         |
122         ;
123
124 statement_kw:
125         STRING EQUAL STRING
126         {
127                 kw_list_t  *new;
128                 kw_entry_t *entry = in_word_set($1, strlen($1));
129
130                 if (entry == NULL)
131                 {
132                         snprintf(errbuf, ERRSTRING_LEN, "unknown keyword '%s'", $1);
133                         yyerror(errbuf);
134                 }
135                 else if (_parser_kw)
136                 {
137                         new = (kw_list_t *)malloc_thing(kw_list_t);
138                         new->entry = entry;
139                         new->value = clone_str($3);
140                         new->next = NULL;
141                         if (_parser_kw_last)
142                                 _parser_kw_last->next = new;
143                         _parser_kw_last = new;
144                         if (!*_parser_kw)
145                                 *_parser_kw = new;
146                 }
147                 free($1);
148                 free($3);
149         }
150         | STRING EQUAL
151           {
152                 free($1);
153           }
154         |
155         ;
156
157 %%
158
159 void
160 yyerror(const char *s)
161 {
162         if (_save_errors_)
163                 _parser_y_error(parser_errstring, ERRSTRING_LEN, s);
164 }
165
166 config_parsed_t *
167 parser_load_conf(const char *file)
168 {
169         config_parsed_t *cfg = NULL;
170         int err = 0;
171         FILE *f;
172
173         extern void _parser_y_init (const char *f);
174         extern FILE *yyin;
175
176         memset(parser_errstring, 0, ERRSTRING_LEN+1);
177
178         cfg = (config_parsed_t *)malloc_thing(config_parsed_t);
179         if (cfg)
180         {
181                 memset(cfg, 0, sizeof(config_parsed_t));
182                 f = fopen(file, "r");
183                 if (f)
184                 {
185                         yyin = f;
186                         _parser_y_init(file);
187                         _save_errors_ = 1;
188                         _parser_cfg = cfg;
189
190                         if (yyparse() !=0 )
191                         {
192                                 if (parser_errstring[0] == '\0')
193                                 {
194                                         snprintf(parser_errstring, ERRSTRING_LEN, "Unknown error...");
195                                 }
196                                 _save_errors_ = 0;
197                                 while (yyparse() != 0);
198                                 err++;
199                         }
200                         else if (parser_errstring[0] != '\0')
201                         {
202                                 err++;
203                         }
204                         else
205                         {
206                                 /**
207                                  * Config valid
208                                  */
209                         }
210
211                         fclose(f);
212                 }
213                 else
214                 {
215                         snprintf(parser_errstring, ERRSTRING_LEN, "can't load file '%s'", file);
216                         err++;
217                 }
218         }
219         else
220         {
221                 snprintf(parser_errstring, ERRSTRING_LEN, "can't allocate memory");
222                 err++;
223         }
224
225         if (err)
226         {
227                 plog("%s", parser_errstring);
228
229                 if (cfg)
230                         parser_free_conf(cfg);
231                 cfg = NULL;
232         }
233
234         return cfg;
235 }
236
237 static void
238 parser_free_kwlist(kw_list_t *list)
239 {
240         kw_list_t *elt;
241
242         while (list)
243         {
244                 elt = list;
245                 list = list->next;
246                 free(elt->value);
247                 free(elt);
248         }
249 }
250
251 void
252 parser_free_conf(config_parsed_t *cfg)
253 {
254         section_list_t *sec;
255         if (cfg)
256         {
257                 parser_free_kwlist(cfg->config_setup);
258                 while (cfg->conn_first)
259                 {
260                         sec = cfg->conn_first;
261                         cfg->conn_first = cfg->conn_first->next;
262                         free(sec->name);
263                         parser_free_kwlist(sec->kw);
264                         free(sec);
265                 }
266                 while (cfg->ca_first)
267                 {
268                         sec = cfg->ca_first;
269                         cfg->ca_first = cfg->ca_first->next;
270                         free(sec->name);
271                         parser_free_kwlist(sec->kw);
272                         free(sec);
273                 }
274                 free(cfg);
275         }
276 }