Home | History | Annotate | Line # | Download | only in bind2nsd
      1 #!/usr/bin/env python
      2 # Copyright (c) 2007, Secure64 Software Corporation
      3 # 
      4 # Permission is hereby granted, free of charge, to any person obtaining a copy
      5 # of this software and associated documentation files (the "Software"), to deal
      6 # in the Software without restriction, including without limitation the rights
      7 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      8 # copies of the Software, and to permit persons to whom the Software is
      9 # furnished to do so, subject to the following conditions:
     10 # 
     11 # The above copyright notice and this permission notice shall be included in
     12 # all copies or substantial portions of the Software.
     13 # 
     14 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     17 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     18 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     19 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     20 # THE SOFTWARE.
     21 # 
     22 #
     23 #
     24 #	class to tokenize a named.conf file
     25 #
     26 #
     27 
     28 T_KEYWORD = 0
     29 T_STRING  = 1
     30 T_LBRACE  = 2
     31 T_RBRACE  = 3
     32 T_SEMI    = 4
     33 T_COMMA   = 5
     34 T_QUAD    = 6
     35 T_COMMENT = 7
     36 T_NAME    = 8
     37 T_EOF     = 9
     38 T_LPAREN  = 10
     39 T_RPAREN  = 11
     40 
     41 NAMED_KEYWORDS = [ 'algorithm', 'allow-notify', 'allow-recursion', 
     42                    'allow-transfer', 'also-notify',
     43                    'category', 'channel', 'check-names', 'controls', 
     44 		   'coresize',
     45                    'directory', 'dump-file',
     46 		   'file',
     47 		   'IN', 'in', 'include',
     48 		   'key', 'keys',
     49 		   'logging',
     50 		   'masters',
     51                    'options',
     52 		   'pid-file', 'print-time',
     53 		   'recursive-clients',
     54 		   'secret', 'severity', 'statistics-file', 'syslog',
     55 		   'transfer-format', 'type',
     56 		   'version', 'versions',
     57 		   'zone',
     58 		 ]
     59 
     60 class Tokenizer:
     61 
     62    def __init__(self, fname):
     63       infile = file(fname)
     64       self.data = ''.join(infile.readlines())
     65       self.curpos = 0
     66       self.lastpos = len(self.data)
     67       self.line = 1
     68       return
     69 
     70    def get(self):
     71       tok = ''
     72       done = False
     73       while not done:
     74          if self.curpos >= self.lastpos:
     75 	    return (T_EOF, None, self.line)
     76          c = self.data[self.curpos]
     77 	 if c == '\n':
     78 	    self.line += 1
     79 	 if c.isspace():
     80 	    self.curpos += 1
     81 	    continue
     82 	 elif c == '{':
     83 	    self.curpos += 1
     84 	    return (T_LBRACE, c, self.line)
     85 	 elif c == '}':
     86 	    self.curpos += 1
     87 	    return (T_RBRACE, c, self.line)
     88 	 elif c == '(':
     89 	    self.curpos += 1
     90 	    return (T_LPAREN, c, self.line)
     91 	 elif c == ')':
     92 	    self.curpos += 1
     93 	    return (T_RPAREN, c, self.line)
     94 	 elif c == ';':
     95 	    self.curpos += 1
     96 	    return (T_SEMI, c, self.line)
     97 	 elif c == '#':
     98 	    while c != '\n':
     99 	       tok += c
    100 	       self.curpos += 1
    101 	       c = self.data[self.curpos]
    102             self.curpos += 1
    103 	    if c == '\n':
    104 	       self.line += 1
    105 	    return (T_COMMENT, tok, self.line)
    106 	 elif c == '"':
    107 	    tok += c
    108 	    self.curpos += 1
    109 	    c = self.data[self.curpos]
    110 	    while c != '"':
    111 	       tok += c
    112 	       self.curpos += 1
    113 	       c = self.data[self.curpos]
    114 	    tok += c
    115             self.curpos += 1
    116 	    return (T_STRING, tok, self.line)
    117 	 elif c == '/' and self.data[self.curpos+1] == '/':
    118 	    while c != '\n':
    119 	       tok += c
    120 	       self.curpos += 1
    121 	       c = self.data[self.curpos]
    122 	    if c == '\n':
    123 	       self.line += 1
    124             self.curpos += 1
    125 	    return (T_COMMENT, tok, self.line)
    126 	 elif c == '/' and self.data[self.curpos+1] == '*':
    127 	    cmtDone = False
    128 	    tok += c
    129 	    tok += self.data[self.curpos+1]
    130 	    self.curpos += 2
    131 	    c = self.data[self.curpos]
    132 	    while not cmtDone:
    133 	       if c == '*' and self.data[self.curpos+1] == '/':
    134 		  tok += c
    135 	          tok += self.data[self.curpos+1]
    136 	          self.curpos += 2
    137 	          return (T_COMMENT, tok, self.line)
    138 	       else:
    139 	          tok += c
    140 		  if c == '\n':
    141 		     self.line += 1
    142 		  self.curpos +=1
    143 	          c = self.data[self.curpos]
    144 	    return (T_COMMENT, tok, self.line)
    145 	 elif c.isdigit():
    146 	    tok += c
    147 	    self.curpos += 1
    148 	    c = self.data[self.curpos]
    149 	    while c.isdigit() or c == '.' or c == '/':
    150 	       tok += c
    151 	       self.curpos += 1
    152 	       c = self.data[self.curpos]
    153 	    return (T_QUAD, tok, self.line)
    154 	 else:
    155 	    while c.isalnum() or c == '_' or c == '-' or c == '.':
    156 	       tok += c
    157 	       self.curpos += 1
    158 	       c = self.data[self.curpos]
    159 	    if tok in NAMED_KEYWORDS:
    160 	       return (T_KEYWORD, tok, self.line)
    161 	    else:
    162 	       return (T_NAME, tok, self.line)
    163 
    164       return
    165 
    166    def dump(self):
    167       print 'Tokenizer raw data:'
    168       print 'cur, last: %d, %d' % (self.curpos, self.lastpos)
    169       print self.data
    170       return
    171 
    172