Changeset 952

Show
Ignore:
Timestamp:
02/18/07 14:25:23 (2 years ago)
Author:
ahu
Message:

teach zoneparser-tng about $ORIGIN and $GENERATE, is now feature complete to take over zoneparser in main pdns auth server

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/pdns/pdns/zoneparser-tng.cc

    r951 r952  
    11/* 
    22    PowerDNS Versatile Database Driven Nameserver 
    3     Copyright (C) 2005 - 2006  PowerDNS.COM BV 
     3    Copyright (C) 2005 - 2007  PowerDNS.COM BV 
    44 
    55    This program is free software; you can redistribute it and/or modify 
     
    8686} 
    8787 
     88bool ZoneParserTNG::getTemplateLine() 
     89{ 
     90  if(d_templatecounter > d_templatestop || d_templateparts.empty()) // no template, or done with 
     91    return false; 
     92 
     93  string retline; 
     94  for(parts_t::const_iterator iter = d_templateparts.begin() ; iter != d_templateparts.end(); ++iter) { 
     95    if(iter != d_templateparts.begin()) 
     96      retline+=" "; 
     97 
     98    string part=makeString(d_templateline, *iter); 
     99     
     100    /* a part can contain a 'naked' $, an escaped $ (\$), or ${offset,width,radix}, with width defaulting to 0,  
     101       and radix beging 'd', 'o', 'x' or 'X', defaulting to 'd'.  
     102 
     103       The width is zero-padded, so if the counter is at 1, the offset is 15, with is 3, and the radix is 'x', 
     104       output will be '010', from the input of ${15,3,x} 
     105    */ 
     106 
     107    string outpart; 
     108    outpart.reserve(part.size()+5); 
     109    bool inescape=false; 
     110 
     111    for(string::size_type pos = 0; pos < part.size() ; ++pos) { 
     112      char c=part[pos]; 
     113      if(inescape) { 
     114        outpart.append(1, c); 
     115        inescape=false; 
     116        continue; 
     117      } 
     118         
     119      if(part[pos]=='\\') { 
     120        inescape=true; 
     121        continue; 
     122      } 
     123      if(c=='$') { 
     124        if(pos + 1 == part.size() || part[pos+1]!='{') {  // a trailing $, or not followed by { 
     125          outpart.append(lexical_cast<string>(d_templatecounter)); 
     126          continue; 
     127        } 
     128         
     129        // need to deal with { case  
     130         
     131        pos+=2; 
     132        string::size_type startPos=pos; 
     133        for(; pos < part.size() && part[pos]!='}' ; ++pos) 
     134          ; 
     135         
     136        if(pos == part.size()) // partial spec 
     137          break; 
     138 
     139        // we are on the '}' 
     140 
     141        string spec(part.c_str() + startPos, part.c_str() + pos); 
     142        int offset=0, width=0; 
     143        char radix='d'; 
     144        sscanf(spec.c_str(), "%d,%d,%c", &offset, &width, &radix);  // parse format specifier 
     145 
     146        char format[12]; 
     147        snprintf(format, sizeof(format) - 1, "%%0%d%c", width, radix); // make into printf-style format 
     148 
     149        char tmp[80]; 
     150        snprintf(tmp, sizeof(tmp)-1, format, d_templatecounter + offset); // and do the actual printing 
     151        outpart+=tmp; 
     152      } 
     153      else 
     154        outpart.append(1, c); 
     155    } 
     156    retline+=outpart; 
     157  } 
     158  d_templatecounter+=d_templatestep; 
     159 
     160  d_line = retline; 
     161  return true; 
     162} 
     163 
    88164bool ZoneParserTNG::get(DNSResourceRecord& rr)  
    89165{ 
    90166 retry:; 
    91   if(!getLine()) 
     167  if(!getTemplateLine() && !getLine()) 
    92168    return false; 
    93169 
    94170  chomp(d_line, " \r\n\x1a"); 
    95   deque<pair<string::size_type, string::size_type> > parts; 
     171 
     172  parts_t parts; 
    96173  vstringtok(parts, d_line); 
    97174 
     
    106183      stackFile(unquotify(makeString(d_line, parts[1]))); 
    107184    } 
    108 #if 0 
     185    else if(command=="$ORIGIN" && parts.size() > 1) { 
     186      d_zonename = toCanonic("", makeString(d_line, parts[1])); 
     187    } 
    109188    else if(command=="$GENERATE" && parts.size() > 2) { 
    110189      // $GENERATE 1-127 $ CNAME $.0 
    111190      string range=makeString(d_line, parts[1]); 
    112       int start, stop, step=0; 
    113       int ret=sscanf(range.c_str(),"%d-%d/%d", &start, & stop, &step); 
    114       cerr<<"ret="<<ret<<", start="<<start<<", stop="<<stop<<", step="<<step<<endl; 
    115     } 
    116 #endif 
     191      d_templatestep=1; 
     192      d_templatestop=0; 
     193      sscanf(range.c_str(),"%d-%d/%d", &d_templatecounter, &d_templatestop, &d_templatestep); 
     194      d_templateline=d_line; 
     195      parts.pop_front(); 
     196      parts.pop_front(); 
     197 
     198      d_templateparts=parts; 
     199      goto retry; 
     200    } 
    117201    else 
    118202      throw exception("Can't parse zone line '"+d_line+"'"); 
  • trunk/pdns/pdns/zoneparser-tng.hh

    r951 r952  
    11/* 
    22    PowerDNS Versatile Database Driven Nameserver 
    3     Copyright (C) 2005 - 2006 PowerDNS.COM BV 
     3    Copyright (C) 2005 - 2007 PowerDNS.COM BV 
    44 
    55    This program is free software; you can redistribute it and/or modify 
     
    3535  bool get(DNSResourceRecord& rr); 
    3636  typedef runtime_error exception; 
     37  typedef deque<pair<string::size_type, string::size_type> > parts_t; 
    3738private: 
    3839  bool getLine(); 
     40  bool getTemplateLine(); 
    3941  void stackFile(const std::string& fname); 
    4042  stack<FILE *> d_fps; 
     
    4345  string d_zonename; 
    4446  int d_defaultttl; 
     47  uint32_t d_templatecounter, d_templatestop, d_templatestep; 
     48  string d_templateline; 
     49  parts_t d_templateparts; 
    4550}; 
    4651