Changeset 1490


Ignore:
Timestamp:
Nov 1, 2008, 4:21:47 AM (16 years ago)
Author:
broder
Message:

Add support for basic quoting in the DNS zone file

Location:
trunk/packages/invirt-dns
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/packages/invirt-dns/debian/changelog

    r1478 r1490  
     1invirt-dns (0.0.6) unstable; urgency=low
     2
     3  * Add support for basic quoting in the zone file
     4
     5 -- Evan Broder <broder@mit.edu>  Sat, 01 Nov 2008 04:01:09 -0400
     6
    17invirt-dns (0.0.5) unstable; urgency=low
    28
  • trunk/packages/invirt-dns/invirt-dns

    r1478 r1490  
    1313import sqlalchemy
    1414import time
     15import re
    1516
    1617class DatabaseAuthority(common.ResolverBase):
     
    114115            return defer.fail(failure.Failure(dns.AuthoritativeDomainError(name)))
    115116
     117class QuotingBindAuthority(authority.BindAuthority):
     118    """
     119    A BindAuthority that (almost) deals with quoting correctly
     120   
     121    This will catch double quotes as marking the start or end of a
     122    quoted phrase, unless the double quote is escaped by a backslash
     123    """
     124    # Grab everything up to the first whitespace character or
     125    # quotation mark not proceeded by a backslash
     126    whitespace_re = re.compile(r'(.*?)([\t\n\x0b\x0c\r ]+|(?<!\\)")')
     127    def collapseContinuations(self, lines):
     128        L = []
     129        state = 0
     130        for line in lines:
     131            if state == 0:
     132                if line.find('(') == -1:
     133                    L.append(line)
     134                else:
     135                    L.append(line[:line.find('(')])
     136                    state = 1
     137            else:
     138                if line.find(')') != -1:
     139                    L[-1] += ' ' + line[:line.find(')')]
     140                    state = 0
     141                else:
     142                    L[-1] += ' ' + line
     143        lines = L
     144        L = []
     145        for line in lines:
     146            in_quote = False
     147            split_line = []
     148            while len(line) > 0:
     149                match = self.whitespace_re.match(line)
     150                if match is None:
     151                    # If there's no match, that means that there's no
     152                    # whitespace in the rest of the line, so it should
     153                    # be treated as a single entity, quoted or not
     154                    #
     155                    # This also means that a closing quote isn't
     156                    # strictly necessary if the line ends the quote
     157                    substr = line
     158                    end = ''
     159                else:
     160                    substr, end = match.groups()
     161               
     162                if in_quote:
     163                    # If we're in the middle of the quote, the string
     164                    # we just grabbed belongs at the end of the
     165                    # previous string
     166                    #
     167                    # Including the whitespace! Unless it's not
     168                    # whitespace and is actually a closequote instead
     169                    split_line[-1] += substr + (end if end != '"' else '')
     170                else:
     171                    # If we're not in the middle of a quote, than this
     172                    # is the next new string
     173                    split_line.append(substr)
     174               
     175                if end == '"':
     176                    in_quote = not in_quote
     177               
     178                # Then strip off what we just processed
     179                line = line[len(substr + end):]
     180            L.append(split_line)
     181        return filter(None, L)
     182
    116183if '__main__' == __name__:
    117184    resolvers = []
    118185    for zone in config.dns.zone_files:
    119186        for origin in config.dns.domains:
    120             r = authority.BindAuthority(zone)
     187            r = QuotingBindAuthority(zone)
    121188            # This sucks, but if I want a generic zone file, I have to
    122189            # reload the information by hand
Note: See TracChangeset for help on using the changeset viewer.