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