[svn] commit: r908 - /experiments/each-zoneload/master.py
BIND 10 source code commits
bind10-changes at lists.isc.org
Mon Feb 22 05:49:59 UTC 2010
Author: each
Date: Mon Feb 22 05:49:59 2010
New Revision: 908
Log:
add support for $INCLUDE
Modified:
experiments/each-zoneload/master.py
Modified: experiments/each-zoneload/master.py
==============================================================================
--- experiments/each-zoneload/master.py (original)
+++ experiments/each-zoneload/master.py Mon Feb 22 05:49:59 2010
@@ -4,7 +4,7 @@
#########################################################################
# define exceptions
#########################################################################
-class ParseError(Exception):
+class MasterFileError(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
@@ -19,10 +19,10 @@
defclass = 'IN'
#########################################################################
-# cleanup: removes excess content from zone files, including comments
+# cleanup: removes excess content from zone file data, including comments
# and extra whitespace
# input:
-# a line of text
+# line of text
# returns:
# the same line, with comments removed, leading and trailing
# whitespace removed, and all other whitespace compressed to
@@ -149,12 +149,12 @@
# returns:
# int
# throws:
-# ParseError
+# MasterFileError
#########################################################################
def parse_ttl(s):
m = re.match('([0-9]+)(.*)', s)
if not m:
- raise ParseError('Invalid TTL: ' + s)
+ raise MasterFileError('Invalid TTL: ' + s)
ttl, suffix = int(m.group(1)), m.group(2)
if suffix.lower() == 'w':
ttl *= 604800
@@ -167,24 +167,24 @@
return ttl
#########################################################################
-# directive: handle $ORIGIN, $TTL, $INCLUDE and $GENERATE directives
+# directive: handle $ORIGIN, $TTL and $GENERATE directives
# (currently only $ORIGIN and $TTL are implemented)
# input:
# a line from a zone file
# returns:
# a boolean indicating whether a directive was found
# throws:
-# ParseError
+# MasterFileError
#########################################################################
def directive(s):
global origin, defttl, maxttl
- first, xx, more = s.partition(' ')
- second, xx, more = more.partition(' ')
+ first, more = pop(s)
+ second, more = pop(more)
if re.match('\$origin', first, re.I):
if not isname(second):
- raise ParseError('Invalid $ORIGIN')
+ raise MasterFileError('Invalid $ORIGIN')
if more:
- raise ParseError('Invalid $ORIGIN')
+ raise MasterFileError('Invalid $ORIGIN')
if second[-1] == '.':
origin = second
else:
@@ -192,19 +192,36 @@
return True
elif re.match('\$ttl', first, re.I):
if not isttl(second):
- raise ParseError('Invalid $TTL: ' + second)
+ raise MasterFileError('Invalid $TTL: ' + second)
if more:
- raise ParseError('Invalid $TTL statement')
+ raise MasterFileError('Invalid $TTL statement')
defttl = parse_ttl(second)
if defttl > maxttl:
- raise ParseError('TTL too high: ' + second)
- return True
- elif re.match('\$include', first, re.I):
- raise ParseError('$INCLUDE not yet implemented')
+ raise MasterFileError('TTL too high: ' + second)
+ return True
elif re.match('\$generate', first, re.I):
- raise ParseError('$GENERATE not yet implemented')
- else:
- return False
+ raise MasterFileError('$GENERATE not yet implemented')
+ else:
+ return False
+
+#########################################################################
+# include: handle $INCLUDE directives
+# input:
+# a line from a zone file
+# returns:
+# the parsed output of the included file, if any, or an empty array
+# throws:
+# MasterFileError
+#########################################################################
+filename=re.compile('[\"\']*([^\'\"]+)[\"\']*')
+def include(s):
+ global origin, defttl, maxttl
+ first, rest = pop(s)
+ if re.match('\$include', first, re.I):
+ m = filename.match(rest)
+ if m:
+ file = m.group(1)
+ return parse(file)
#########################################################################
# four: try parsing on the assumption that the RR type is specified in
@@ -215,7 +232,7 @@
# returns:
# empty list if parse failed, else name, ttl, class, type, rdata
# throws:
-# ParseError
+# MasterFileError
#########################################################################
def four(record, curname):
ret = ''
@@ -237,7 +254,7 @@
# returns:
# empty list if parse failed, else name, ttl, class, type, rdata
# throws:
-# ParseError
+# MasterFileError
#########################################################################
def three(record, curname):
global defttl, defclass
@@ -259,7 +276,7 @@
ttl = parse_ttl(list[1])
name = curname
else:
- raise ParseError("Cannot parse RR: " + record)
+ raise MasterFileError("Cannot parse RR: " + record)
rrtype = list[2]
rdata = ' '.join(list[3:])
@@ -274,7 +291,7 @@
# returns:
# empty list if parse failed, else name, ttl, class, type, rdata
# throws:
-# ParseError
+# MasterFileError
#########################################################################
def two(record, curname):
global defttl, defclass
@@ -286,7 +303,7 @@
if isname(list[0]):
name = list[0]
else:
- raise ParseError("Cannot parse RR: " + record)
+ raise MasterFileError("Cannot parse RR: " + record)
ttl = defttl
rrclass = defclass
@@ -296,10 +313,10 @@
return ret
#########################################################################
-# parse_zonefile: parse a zone master file and return it as an array of
+# parse: parse a zone master file and return it as an array of
# tuples
#########################################################################
-def parse_zonefile(file):
+def parse(file):
global defttl, defclass
data = open(file).read().splitlines()
zone = []
@@ -309,6 +326,11 @@
if directive(record):
continue;
+ incl = include(record)
+ if incl:
+ zone += incl
+ continue
+
first = record.split()[0]
if first == '@':
name = origin
@@ -328,19 +350,19 @@
result = name, defttl, defclass, first, rdata
if not result:
- raise ParseError("Cannot parse RR: " + record)
+ raise MasterFileError("Cannot parse RR: " + record)
name, ttl, rrclass, rrtype, rdata = result
if name[-1] != '.':
name += '.' + origin
if rrclass.upper() != 'IN':
- raise ParseError("CH and HS zones not supported")
+ raise MasterFileError("CH and HS zones not supported")
# add origin to rdata if necessary
if rrtype.lower() in ('cname', 'dname', 'ns'):
if not isname(rdata):
- raise ParseError("Invalid " + rrtype + ": " + rdata)
+ raise MasterFileError("Invalid " + rrtype + ": " + rdata)
if rdata[-1] != '.':
rdata += '.' + origin
@@ -354,7 +376,7 @@
#########################################################################
def main():
print ('---------------------')
- zone = parse_zonefile('testfile')
+ zone = parse('testfile')
for name, ttl, rrclass, rrtype, rdata in zone:
print ('name: ' + name)
print ('ttl: ' + str(ttl))
More information about the bind10-changes
mailing list