Changeset 1056

Show
Ignore:
Timestamp:
06/07/07 23:10:21 (1 year ago)
Author:
ahu
Message:

improve line number and filename reporting in errors, dealing with $includes
support $ttl case insensitively
deal with common '$ttl 86400;' syntax
recognize '1D' as a TTL more robustly

Files:

Legend:

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

    r1030 r1056  
    4141  if(!fp) 
    4242    throw runtime_error("Unable to open file '"+fname+"': "+stringerror()); 
    43   d_fps.push(fp); 
     43 
     44  filestate fs(fp, fname); 
     45  d_filestates.push(fs); 
    4446} 
    4547 
    4648ZoneParserTNG::~ZoneParserTNG() 
    4749{ 
    48   while(!d_fps.empty()) { 
    49     fclose(d_fps.top()); 
    50     d_fps.pop(); 
     50  while(!d_filestates.empty()) { 
     51    fclose(d_filestates.top().d_fp); 
     52    d_filestates.pop(); 
    5153  } 
    5254} 
     
    5759} 
    5860 
    59 static unsigned int makeTTLFromZone(const string& str) 
     61static bool isTimeSpec(const string& nextpart) 
     62
     63  if(nextpart.empty()) 
     64    return false; 
     65  for(string::const_iterator iter = nextpart.begin(); iter != nextpart.end(); ++iter) { 
     66    if(isdigit(*iter)) 
     67      continue; 
     68    if(iter+1 != nextpart.end()) 
     69      return false; 
     70    char c=tolower(*iter); 
     71    return (c=='m' || c=='h' || c=='d' || c=='w' || c=='y'); 
     72  } 
     73  return true; 
     74
     75 
     76 
     77unsigned int ZoneParserTNG::makeTTLFromZone(const string& str) 
    6078{ 
    6179  if(str.empty()) 
     
    8199      val*=3600*24*365; 
    82100      break; 
     101 
    83102    default: 
    84       throw ZoneParserTNG::exception("Unable to parse time specification '"+str+"'"); 
     103      throw ZoneParserTNG::exception("Unable to parse time specification '"+str+"' on line "+ 
     104                                     lexical_cast<string>(d_filestates.top().d_lineno)+" of file '"+ 
     105                                     d_filestates.top().d_filename+"'"); 
    85106    } 
    86107  return val; 
     
    199220 
    200221 
     222 
    201223bool ZoneParserTNG::get(DNSResourceRecord& rr)  
    202224{ 
     
    215237  if(d_line[0]=='$') {  
    216238    string command=makeString(d_line, parts[0]); 
    217     if(command=="$TTL" && parts.size() > 1) 
    218       d_defaultttl=makeTTLFromZone(makeString(d_line,parts[1])); 
     239    if(iequals(command,"$TTL") && parts.size() > 1) 
     240      d_defaultttl=makeTTLFromZone(trim_right_copy_if(makeString(d_line, parts[1]), is_any_of(";"))); 
    219241    else if(iequals(command,"$INCLUDE") && parts.size() > 1) { 
    220242      string fname=unquotify(makeString(d_line, parts[1])); 
     
    240262    } 
    241263    else 
    242       throw exception("Can't parse zone line '"+d_line+"'"); 
     264      throw exception("Can't parse zone line '"+d_line+"' on line "+lexical_cast<string>(d_filestates.top().d_lineno)+ 
     265                      " of file '"+d_filestates.top().d_filename); 
    243266    goto retry; 
    244267  } 
     
    285308      continue; 
    286309    } 
    287     if(!haveTTL && !haveQTYPE && all(nextpart, is_digit())) { 
     310    if(!haveTTL && !haveQTYPE && isTimeSpec(nextpart)) { 
    288311      rr.ttl=makeTTLFromZone(nextpart); 
    289312      haveTTL=true; 
     
    301324    } 
    302325    catch(...) { 
    303       throw runtime_error("Parsing zone content line: '"+nextpart+"' doesn't look like a qtype, stopping loop"); 
     326      throw runtime_error("Parsing zone content on line "+ 
     327                          lexical_cast<string>(d_filestates.top().d_lineno)+ 
     328                          " of file '"+d_filestates.top().d_filename+"': '"+nextpart+ 
     329                          "' doesn't look like a qtype, stopping loop"); 
    304330    } 
    305331  } 
     
    365391bool ZoneParserTNG::getLine() 
    366392{ 
    367   while(!d_fps.empty()) { 
     393  while(!d_filestates.empty()) { 
    368394    char buffer[1024]; 
    369     if(fgets(buffer, 1024, d_fps.top())) { 
     395    if(fgets(buffer, 1024, d_filestates.top().d_fp)) { 
     396      d_filestates.top().d_lineno++; 
    370397      d_line=buffer; 
    371398      return true; 
    372399    } 
    373     fclose(d_fps.top()); 
    374     d_fps.pop(); 
     400    fclose(d_filestates.top().d_fp); 
     401    d_filestates.pop(); 
    375402  } 
    376403  return false; 
  • trunk/pdns/pdns/zoneparser-tng.hh

    r953 r1056  
    4040  bool getTemplateLine(); 
    4141  void stackFile(const std::string& fname); 
    42   stack<FILE *> d_fps
     42  unsigned makeTTLFromZone(const std::string& str)
    4343  string d_reldir; 
    4444  string d_line; 
     
    4949  string d_templateline; 
    5050  parts_t d_templateparts; 
     51 
     52  struct filestate { 
     53    filestate(FILE* fp, string filename) : d_fp(fp), d_filename(filename), d_lineno(0){} 
     54    FILE *d_fp; 
     55    string d_filename; 
     56    int d_lineno; 
     57  }; 
     58  stack<filestate> d_filestates; 
    5159}; 
    5260