From: Evan Broder Date: Sat, 1 Nov 2008 08:21:47 +0000 (-0400) Subject: Add support for basic quoting in the DNS zone file X-Git-Tag: 0.0.6^0 X-Git-Url: http://xvm.mit.edu/gitweb/invirt/packages/invirt-dns.git/commitdiff_plain/6d00cda627efb7b95b26df3dad629524d416e34a Add support for basic quoting in the DNS zone file svn path=/trunk/packages/invirt-dns/; revision=1490 --- diff --git a/debian/changelog b/debian/changelog index b34b96a..ff67d88 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +invirt-dns (0.0.6) unstable; urgency=low + + * Add support for basic quoting in the zone file + + -- Evan Broder Sat, 01 Nov 2008 04:01:09 -0400 + invirt-dns (0.0.5) unstable; urgency=low * Instead of hacking in support for prod.xvm.mit.edu, support zone files diff --git a/invirt-dns b/invirt-dns index 976a9a7..4193be1 100755 --- a/invirt-dns +++ b/invirt-dns @@ -12,6 +12,7 @@ import invirt.database import psycopg2 import sqlalchemy import time +import re class DatabaseAuthority(common.ResolverBase): """An Authority that is loaded from a file.""" @@ -113,11 +114,77 @@ class DatabaseAuthority(common.ResolverBase): #Doesn't exist return defer.fail(failure.Failure(dns.AuthoritativeDomainError(name))) +class QuotingBindAuthority(authority.BindAuthority): + """ + A BindAuthority that (almost) deals with quoting correctly + + This will catch double quotes as marking the start or end of a + quoted phrase, unless the double quote is escaped by a backslash + """ + # Grab everything up to the first whitespace character or + # quotation mark not proceeded by a backslash + whitespace_re = re.compile(r'(.*?)([\t\n\x0b\x0c\r ]+|(? 0: + match = self.whitespace_re.match(line) + if match is None: + # If there's no match, that means that there's no + # whitespace in the rest of the line, so it should + # be treated as a single entity, quoted or not + # + # This also means that a closing quote isn't + # strictly necessary if the line ends the quote + substr = line + end = '' + else: + substr, end = match.groups() + + if in_quote: + # If we're in the middle of the quote, the string + # we just grabbed belongs at the end of the + # previous string + # + # Including the whitespace! Unless it's not + # whitespace and is actually a closequote instead + split_line[-1] += substr + (end if end != '"' else '') + else: + # If we're not in the middle of a quote, than this + # is the next new string + split_line.append(substr) + + if end == '"': + in_quote = not in_quote + + # Then strip off what we just processed + line = line[len(substr + end):] + L.append(split_line) + return filter(None, L) + if '__main__' == __name__: resolvers = [] for zone in config.dns.zone_files: for origin in config.dns.domains: - r = authority.BindAuthority(zone) + r = QuotingBindAuthority(zone) # This sucks, but if I want a generic zone file, I have to # reload the information by hand r.origin = origin