1%{
2
3#include <stdio.h>
4#include <string.h>
5#include <stdlib.h>
6#include <string>
7#include <iostream>
8#include <utility>
9#include <errno.h>
10#include "misc.hh"
11#include "pdnsexception.hh"
12#include "namespaces.hh"
13#include "iputils.hh"
14#define YYDEBUG 1
15extern int yydebug;
16#include "bindparserclasses.hh"
17
18#define YYSTYPE char *
19
20extern "C"
21{
22	int yyparse(void);
23	int yylex(void);
24	void yyrestart(FILE *);
25	int yywrap(void);
26	int yywrap(void)
27	{
28		return 1;
29	}
30}
31
32
33extern int yydebug;
34const char *bind_directory;
35extern int linenumber;
36static void yyerror(const char *str)
37{
38  extern char *current_filename;
39  throw PDNSException("Error in bind configuration '"+string(current_filename)+"' on line "+itoa(linenumber)+": "+str);
40}
41
42extern FILE *yyin;
43static BindParser *parent;
44BindDomainInfo s_di;
45
46void BindParser::parse(const string &fname)
47{
48	yydebug=0;
49	yyin=fopen(fname.c_str(),"r");
50	yyrestart(yyin);
51	if(!yyin)
52		throw PDNSException("Unable to open '"+fname+"': "+strerror(errno));
53
54	linenumber=1;
55	parent=this;
56	extern char *current_filename;
57	extern char *original_filename;
58
59	current_filename=original_filename=(char*)fname.c_str();
60
61	yyparse();
62
63//	cerr<<"Need to parse "<<d_zonedomains.size()<<" zone statements"<<endl;
64}
65
66void BindParser::setDirectory(const string &dir)
67{
68	d_dir=dir;
69	if (d_dir.back() == '/') {
70		d_dir.pop_back();
71	}
72	bind_directory=d_dir.c_str();
73}
74
75void BindParser::addAlsoNotify(const string & host)
76{
77	alsoNotify.insert(host);
78}
79
80const string &BindParser::getDirectory()
81{
82	return d_dir;
83}
84
85const vector<BindDomainInfo>& BindParser::getDomains()
86{
87	return d_zonedomains;
88}
89
90void BindParser::setVerbose(bool verbose)
91{
92  d_verbose=verbose;
93}
94
95void BindParser::commit(BindDomainInfo DI)
96{
97  DI.hadFileDirective = (DI.filename != "");
98
99  if(DI.filename[0]!='/')
100    DI.filename=d_dir+"/"+DI.filename;
101
102  if(d_verbose)
103    cerr<<"Domain "<<DI.name.toStringNoDot()<<" lives in file '"<<DI.filename<<"'"<<endl;
104
105  d_zonedomains.push_back(DI);
106}
107
108%}
109
110%token AWORD QUOTEDWORD OBRACE EBRACE SEMICOLON ZONETOK FILETOK OPTIONSTOK
111%token DIRECTORYTOK ACLTOK LOGGINGTOK CLASSTOK TYPETOK MASTERTOK ALSONOTIFYTOK
112
113%%
114
115root_commands:
116	|
117	root_commands root_command SEMICOLON
118  	;
119
120root_command: command | acl_command | global_zone_command | global_options_command
121	;
122
123commands:
124	|
125	commands command SEMICOLON
126	;
127
128command:
129	terms
130	;
131
132global_zone_command:
133	ZONETOK quotedname zone_block
134	{
135		s_di.name=DNSName($2);
136		free($2);
137		parent->commit(s_di);
138		s_di.clear();
139	}
140	|
141	ZONETOK quotedname AWORD zone_block
142	{
143	        s_di.name=DNSName($2);
144		free($2);
145		parent->commit(s_di);
146		s_di.clear();
147	}
148	;
149
150
151global_options_command:
152	OPTIONSTOK OBRACE options_commands EBRACE
153	|
154	LOGGINGTOK OBRACE options_commands EBRACE
155	;
156
157
158acl_command:
159	ACLTOK quotedname acl_block | 	ACLTOK filename acl_block
160	;
161
162acl_block: OBRACE acls EBRACE
163	;
164
165acls:
166	|
167	acl SEMICOLON acls
168	;
169
170acl:
171	AWORD
172	;
173
174options_commands:
175	|
176	options_command SEMICOLON options_commands
177	;
178
179options_command: command | global_options_command
180	;
181
182global_options_command: options_directory_command | also_notify_command
183	;
184
185options_directory_command: DIRECTORYTOK quotedname
186	{
187		parent->setDirectory($2);
188		free($2);
189	}
190	;
191
192also_notify_command: ALSONOTIFYTOK OBRACE also_notify_list EBRACE
193	;
194
195also_notify_list:
196	|
197	also_notify SEMICOLON also_notify_list
198	;
199
200also_notify: AWORD
201 	{
202		parent->addAlsoNotify($1);
203		free($1);
204	}
205	;
206terms: /* empty */
207	|
208	terms term
209	;
210
211term: AWORD | block | quotedname
212	;
213block:
214	OBRACE commands EBRACE
215	;
216
217zone_block:
218	OBRACE zone_commands EBRACE
219	;
220
221zone_commands:
222	|
223	zone_commands zone_command SEMICOLON
224	;
225
226/* commands in zone
227 *   in global scope also_notify_command is used instead of zone_also_notify_command
228 */
229zone_command: command | global_zone_command | zone_also_notify_command
230	;
231
232/* zone commands that also are available at global scope */
233global_zone_command: zone_file_command | zone_type_command | zone_masters_command
234	;
235
236zone_masters_command: MASTERTOK OBRACE masters EBRACE
237	;
238
239zone_also_notify_command: ALSONOTIFYTOK OBRACE zone_also_notify_list EBRACE
240	;
241
242zone_also_notify_list:
243        |
244        zone_also_notify SEMICOLON zone_also_notify_list
245        ;
246
247zone_also_notify: AWORD
248        {
249                s_di.alsoNotify.insert($1);
250                free($1);
251        }
252        ;
253
254masters: /* empty */
255	|
256	masters master SEMICOLON
257	;
258
259master: AWORD
260	{
261		s_di.masters.push_back(ComboAddress($1, 53));
262		free($1);
263	}
264	;
265
266zone_file_command:
267	FILETOK quotedname
268	{
269	  //		printf("Found a filename: '%s'\n",$2);
270		s_di.filename=$2;
271		free($2);
272	}
273	;
274
275zone_type_command:
276TYPETOK AWORD
277	{
278		s_di.type=$2;
279		free($2);
280	}
281	;
282
283
284quotedname:
285	QUOTEDWORD
286	{
287		$$=$1;
288	}
289	;
290
291filename: AWORD
292	;
293