]> granicus.if.org Git - pdns/commitdiff
remove bind1backend, remove old zoneparser, switch rest to zoneparser-tng
authorBert Hubert <bert.hubert@netherlabs.nl>
Sun, 18 Feb 2007 19:49:14 +0000 (19:49 +0000)
committerBert Hubert <bert.hubert@netherlabs.nl>
Sun, 18 Feb 2007 19:49:14 +0000 (19:49 +0000)
git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@959 d19b8d6e-7fed-0310-83ef-9ca221ded41b

pdns/backends/bind/Makefile.am
pdns/backends/bind/bindbackend.cc [deleted file]
pdns/backends/bind/bindbackend.hh [deleted file]
pdns/backends/bind/bindbackend2.cc
pdns/backends/bind/bindbackend2.hh
pdns/backends/bind/bindparser.yy
pdns/backends/bind/zone2ldap.cc
pdns/backends/bind/zone2sql.cc
pdns/backends/bind/zoneparser.hh [deleted file]
pdns/backends/bind/zoneparser2.cc [deleted file]

index 2915908e4f1b8ba2ff671e383892054cde4bd5b2..c54be99797d0a6e9ca26353d2e4a68a81ec2290e 100644 (file)
@@ -1,15 +1,8 @@
 INCLUDES=-I../..
-noinst_LTLIBRARIES = libbindbackend.la libbind2backend.la
-
-libbindbackend_la_SOURCES=bindbackend.cc bindbackend.hh bindparser.yy \
-bindlexer.l zoneparser2.cc ../../misc.cc huffman.cc huffman.hh zoneparser.hh \
-bindparser.hh ../../unix_utility.cc
-
-libbindbackend_la_CXXFLAGS=$(AM_CXXFLAGS)
-libbindbackend_la_CFLAGS=$(AM_CFLAGS)
+noinst_LTLIBRARIES = libbind2backend.la
 
 libbind2backend_la_SOURCES=bindbackend2.cc bindbackend2.hh bindparser.yy \
-bindlexer.l zoneparser2.cc ../../misc.cc huffman.cc huffman.hh zoneparser.hh \
+bindlexer.l ../../zoneparser-tng.cc ../../misc.cc huffman.cc huffman.hh  \
 bindparser.hh ../../unix_utility.cc
 
 libbind2backend_la_CXXFLAGS=$(AM_CXXFLAGS)
@@ -17,14 +10,18 @@ libbind2backend_la_CFLAGS=$(AM_CFLAGS)
 
 bin_PROGRAMS = zone2sql zone2ldap
 
-zone2sql_SOURCES=bindparser.yy bindlexer.l zoneparser2.cc \
+zone2sql_SOURCES=bindparser.yy bindlexer.l \
 ../../arguments.cc ../../logger.cc zone2sql.cc ../../statbag.cc ../../misc.cc \
 ../../unix_utility.cc ../../qtype.cc ../../dnspacket.cc \
-../../sillyrecords.cc
+../../sillyrecords.cc  ../../zoneparser-tng.cc ../../dnsrecords.cc \
+../../dnswriter.cc ../../rcpgenerator.cc ../../dnsparser.cc ../../base64.cc
 
-zone2ldap_SOURCES=bindparser.yy bindlexer.l zoneparser2.cc \
+
+zone2ldap_SOURCES=bindparser.yy bindlexer.l \
 ../../arguments.cc ../../logger.cc zone2ldap.cc ../../statbag.cc ../../misc.cc \
-../../unix_utility.cc ../../qtype.cc
+../../unix_utility.cc ../../qtype.cc  ../../zoneparser-tng.cc ../../dnsrecords.cc \
+../../dnswriter.cc ../../rcpgenerator.cc ../../dnsparser.cc ../../base64.cc
+
 
 
 zone2ldap_LDFLAGS=@THREADFLAGS@
diff --git a/pdns/backends/bind/bindbackend.cc b/pdns/backends/bind/bindbackend.cc
deleted file mode 100644 (file)
index 57908d5..0000000
+++ /dev/null
@@ -1,847 +0,0 @@
-/*
-    PowerDNS Versatile Database Driven Nameserver
-    Copyright (C) 2002  PowerDNS.COM BV
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2 as 
-    published by the Free Software Foundation; 
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-*/
-#include <errno.h>
-#include <string>
-#include <map>
-#include <set>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-using namespace std;
-
-#include "dns.hh"
-#include "dnsbackend.hh"
-#include "bindbackend.hh"
-#include "dnspacket.hh"
-
-#include "zoneparser.hh"
-#include "bindparser.hh"
-#include "logger.hh"
-#include "arguments.hh"
-#include "huffman.hh"
-#include "qtype.hh"
-#include "misc.hh"
-#include "dynlistener.hh"
-#include "lock.hh"
-using namespace std;
-
-
-cmap_t BindBackend::d_qnames;
-map<int,vector<vector<BBResourceRecord>* > > BindBackend::d_zone_id_map;  
-set<string> BindBackend::s_contents;
-HuffmanCodec BindBackend::s_hc;
-
-map<unsigned int,BBDomainInfo> BindBackend::d_bbds;
-
-int BindBackend::s_first=1;
-pthread_mutex_t BindBackend::s_startup_lock=PTHREAD_MUTEX_INITIALIZER;
-
-BBDomainInfo::BBDomainInfo()
-{
-  d_loaded=false;
-  d_last_check=0;
-  d_checknow=false;
-  d_rwlock=new pthread_rwlock_t;
-  d_status="Seen in bind configuration";
-  d_confcount=0;
-  //cout<<"Generated a new bbdomaininfo: "<<(void*)d_rwlock<<"/"<<getpid()<<endl;
-  pthread_rwlock_init(d_rwlock,0);
-}
-
-void BBDomainInfo::setCheckInterval(time_t seconds)
-{
-  d_checkinterval=seconds;
-}
-
-bool BBDomainInfo::current()
-{
-  if(d_checknow)
-    return false;
-
-  if(!d_checknow && !d_checkinterval || (time(0)-d_lastcheck<d_checkinterval) || d_filename.empty())
-    return true;
-
-  return (getCtime()==d_ctime);
-}
-
-time_t BBDomainInfo::getCtime()
-{
-  struct stat buf;
-  
-  if(d_filename.empty() || stat(d_filename.c_str(),&buf)<0)
-    return 0; 
-  d_lastcheck=time(0);
-  return buf.st_ctime;
-}
-
-void BBDomainInfo::setCtime()
-{
-  struct stat buf;
-  if(stat(d_filename.c_str(),&buf)<0)
-    return; 
-  d_ctime=buf.st_ctime;
-}
-
-void BindBackend::setNotified(uint32_t id, uint32_t serial)
-{
-  d_bbds[id].d_lastnotified=serial;
-}
-
-void BindBackend::setFresh(uint32_t domain_id)
-{
-  d_bbds[domain_id].d_last_check=time(0);
-}
-
-bool BindBackend::startTransaction(const string &qname, int id)
-{
-  BBDomainInfo &bbd=d_bbds[d_transaction_id=id];
-  d_transaction_tmpname=bbd.d_filename+"."+itoa(random());
-  d_of=new ofstream(d_transaction_tmpname.c_str());
-  if(!*d_of) {
-    throw DBException("Unable to open temporary zonefile '"+d_transaction_tmpname+"': "+stringerror());
-    unlink(d_transaction_tmpname.c_str());
-    delete d_of;
-    d_of=0;
-  }
-  
-  *d_of<<"; Written by PowerDNS, don't edit!"<<endl;
-  *d_of<<"; Zone '"+bbd.d_name+"' retrieved from master "<<bbd.d_master<<endl<<"; at "<<nowTime()<<endl;
-  bbd.lock();
-  return true;
-}
-
-bool BindBackend::commitTransaction()
-{
-  delete d_of;
-  d_of=0;
-  if(rename(d_transaction_tmpname.c_str(),d_bbds[d_transaction_id].d_filename.c_str())<0)
-    throw DBException("Unable to commit (rename to: '"+d_bbds[d_transaction_id].d_filename+"') AXFRed zone: "+stringerror());
-
-  queueReload(&d_bbds[d_transaction_id]);
-  d_bbds[d_transaction_id].unlock();
-  d_transaction_id=0;
-  return true;
-}
-
-bool BindBackend::abortTransaction()
-{
-  if(d_transaction_id) {
-    d_bbds[d_transaction_id].unlock();
-    delete d_of;
-    d_of=0;
-    unlink(d_transaction_tmpname.c_str());
-    d_transaction_id=0;
-  }
-  return true;
-}
-
-
-
-bool BindBackend::feedRecord(const DNSResourceRecord &r)
-{
-  string qname=r.qname;
-  string domain=d_bbds[d_transaction_id].d_name;
-
-  if(!stripDomainSuffix(&qname,domain)) 
-    throw DBException("out-of-zone data '"+qname+"' during AXFR of zone '"+domain+"'");
-
-  string content=r.content;
-
-  // SOA needs stripping too! XXX FIXME
-  switch(r.qtype.getCode()) {
-  case QType::TXT:
-    *d_of<<qname<<"\t"<<r.ttl<<"\t"<<r.qtype.getName()<<"\t\""<<r.content<<"\""<<endl;
-    break;
-  case QType::MX:
-    if(!stripDomainSuffix(&content,domain))
-      content+=".";
-    *d_of<<qname<<"\t"<<r.ttl<<"\t"<<r.qtype.getName()<<"\t"<<r.priority<<"\t"<<content<<endl;
-    break;
-  case QType::CNAME:
-  case QType::NS:
-    if(!stripDomainSuffix(&content,domain))
-      content+=".";
-    *d_of<<qname<<"\t"<<r.ttl<<"\t"<<r.qtype.getName()<<"\t"<<content<<endl;
-    break;
-  default:
-    *d_of<<qname<<"\t"<<r.ttl<<"\t"<<r.qtype.getName()<<"\t"<<r.content<<endl;
-    break;
-  }
-
-  return true;
-}
-
-void BindBackend::getUpdatedMasters(vector<DomainInfo> *changedDomains)
-{
-  SOAData soadata;
-  for(map<uint32_t,BBDomainInfo>::iterator i=d_bbds.begin();i!=d_bbds.end();++i) {
-    if(!i->second.d_master.empty())
-      continue;
-    soadata.serial=0;
-    try {
-      getSOA(i->second.d_name,soadata); // we might not *have* a SOA yet
-    }
-    catch(...){}
-    DomainInfo di;
-    di.id=i->first;
-    di.serial=soadata.serial;
-    di.zone=i->second.d_name;
-    di.last_check=i->second.d_last_check;
-    di.backend=this;
-    di.kind=DomainInfo::Master;
-    if(!i->second.d_lastnotified)            // don't do notification storm on startup 
-      i->second.d_lastnotified=soadata.serial;
-    else
-      if(soadata.serial!=i->second.d_lastnotified)
-       changedDomains->push_back(di);
-    
-  }
-}
-
-void BindBackend::getUnfreshSlaveInfos(vector<DomainInfo> *unfreshDomains)
-{
-  for(map<uint32_t,BBDomainInfo>::const_iterator i=d_bbds.begin();i!=d_bbds.end();++i) {
-    if(i->second.d_master.empty())
-      continue;
-    DomainInfo sd;
-    sd.id=i->first;
-    sd.zone=i->second.d_name;
-    sd.master=i->second.d_master;
-    sd.last_check=i->second.d_last_check;
-    sd.backend=this;
-    sd.kind=DomainInfo::Slave;
-    SOAData soadata;
-    soadata.serial=0;
-    soadata.refresh=0;
-    soadata.serial=0;
-    soadata.db=(DNSBackend *)-1; // not sure if this is useful, inhibits any caches that might be around
-    try {
-      getSOA(i->second.d_name,soadata); // we might not *have* a SOA yet
-    }
-    catch(...){}
-    sd.serial=soadata.serial;
-    if(sd.last_check+soadata.refresh<(unsigned int)time(0))
-      unfreshDomains->push_back(sd);    
-  }
-}
-
-bool BindBackend::getDomainInfo(const string &domain, DomainInfo &di)
-{
-  for(map<uint32_t,BBDomainInfo>::const_iterator i=d_bbds.begin();i!=d_bbds.end();++i) {
-    if(i->second.d_name==domain) {
-      di.id=i->first;
-      di.zone=domain;
-      di.master=i->second.d_master;
-      di.last_check=i->second.d_last_check;
-      di.backend=this;
-      di.kind=i->second.d_master.empty() ? DomainInfo::Master : DomainInfo::Slave;
-      di.serial=0;
-      try {
-       SOAData sd;
-       sd.serial=0;
-       
-       getSOA(i->second.d_name,sd); // we might not *have* a SOA yet
-       di.serial=sd.serial;
-      }
-      catch(...){}
-
-      return true;
-    }
-  }
-  return false;
-}
-
-
-static string canonic(string ret)
-{
-  string::iterator i;
-
-  for(i=ret.begin();
-      i!=ret.end();
-      ++i)
-    *i=*i; //tolower(*i);
-
-
-  if(*(i-1)=='.')
-    ret.resize(i-ret.begin()-1);
-  return ret;
-}
-
-/** This function adds a record to a domain with a certain id. */
-void BindBackend::insert(int id, const string &qnameu, const string &qtype, const string &content, int ttl=300, int prio=25)
-{
-  static int s_count;
-  static unsigned int len;
-  static unsigned int ulen;
-  DLOG(  
-  if(!((s_count++)%10000))
-    cerr<<"\r"<<s_count-1<<", "<<s_contents.size()<<" different contents, "<<d_qnames.size()<<" different qnames, "<<len/1000000<<"MB, saved: "<<
-      (ulen-len)/1000;
-  );
-  string compressed;
-  s_hc.encode(toLower(canonic(qnameu)),compressed);
-  //  string(compressed).swap(compressed);
-  //  cout<<"saved: "<<qnameu.size()-compressed.size()<<endl;
-
-  vector<BBResourceRecord>::const_iterator i;
-
-  if(d_qnames[compressed].empty()) {  // NEW! NEW! NEW! in de top 40!
-    d_zone_id_map[id].push_back(&d_qnames[compressed]); 
-    i=d_qnames[compressed].end();
-  }
-  else
-    for(i=d_qnames[compressed].begin();i!=d_qnames[compressed].end();++i)
-      if(((i)->qtype==QType::chartocode(qtype.c_str())))
-       if((*(i)->content==canonic(content)))
-         break; 
-  
-  // never saw this specific name/type/content triple before
-  if(i==d_qnames[compressed].end()) {
-    BBResourceRecord v=resourceMaker(id,qtype,canonic(content),ttl,prio);
-    v.qnameptr=&d_qnames.find(compressed)->first;
-    len+=compressed.size();
-    ulen+=qnameu.size();
-    d_qnames[compressed].push_back(v);
-    
-    d_qnames[compressed].reserve(0);
-    //    vector<BBResourceRecord>&tmp=d_qnames[compressed];
-    // vector<BBResourceRecord>(tmp).swap(tmp);
-  }
-  else {
-    s_count--;
-  }
-}
-
-
-/** Helper function that creates a BBResourceRecord and does s_content housekeeping */
-BBResourceRecord BindBackend::resourceMaker(int id, const string &qtype, const string &content, int ttl, int prio)
-{
-  BBResourceRecord make;
-  
-  make.domain_id=id;
-
-  make.qtype=QType::chartocode(qtype.c_str());
-  if(!make.qtype)
-    throw AhuException("Unknown qtype '"+qtype+"'"); // never leaves the BindBackend
-
-  set<string>::const_iterator i=s_contents.find(content);
-  if(i==s_contents.end()) {
-    s_contents.insert(content);
-    i=s_contents.find(content);
-  }
-  make.content=&*i;
-  make.ttl=ttl;
-  make.priority=prio;
-  return make;
-}
-
-static BindBackend *us;
-
-void BindBackend::reload()
-{
-  for(map<uint32_t,BBDomainInfo>::iterator i=us->d_bbds.begin();i!=us->d_bbds.end();++i) 
-    i->second.d_checknow=true;
-}
-
-string BindBackend::DLReloadNowHandler(const vector<string>&parts, Utility::pid_t ppid)
-{
-  ostringstream ret;
-  bool doReload=false;
-  for(map<uint32_t,BBDomainInfo>::iterator j=us->d_bbds.begin();j!=us->d_bbds.end();++j) {
-    doReload=false;
-    if(parts.size()==1)
-      doReload=true;
-    else 
-      for(vector<string>::const_iterator i=parts.begin()+1;i<parts.end();++i)                 // O(N) badness XXX FIXME
-       if(*i==j->second.d_name) {
-         doReload=true;
-         break;
-       }
-    
-    if(doReload) {
-      j->second.lock();
-
-      us->queueReload(&j->second);
-      j->second.unlock();
-      ret<<j->second.d_name<< (j->second.d_loaded ? "": "[rejected]") <<"\t"<<j->second.d_status<<"\n";
-    }
-    doReload=false;
-  }
-       
-  return ret.str();
-}
-
-
-string BindBackend::DLDomStatusHandler(const vector<string>&parts, Utility::pid_t ppid)
-{
-  string ret;
-  bool doPrint=false;
-  for(map<uint32_t,BBDomainInfo>::iterator j=us->d_bbds.begin();j!=us->d_bbds.end();++j) {
-    ostringstream line;
-    doPrint=false;
-    if(parts.size()==1)
-      doPrint=true;
-    else 
-      for(vector<string>::const_iterator i=parts.begin()+1;i<parts.end();++i)                 // O(N) badness XXX FIXME
-       if(*i==j->second.d_name) {
-         doPrint=true;
-         break;
-       }
-    
-    if(doPrint)
-      line<<j->second.d_name<< (j->second.d_loaded ? "": "[rejected]") <<"\t"<<j->second.d_status<<"\n";
-    doPrint=false;
-    ret+=line.str();
-  }
-       
-  return ret;
-}
-
-
-string BindBackend::DLListRejectsHandler(const vector<string>&parts, Utility::pid_t ppid)
-{
-  ostringstream ret;
-  for(map<uint32_t,BBDomainInfo>::iterator j=us->d_bbds.begin();j!=us->d_bbds.end();++j) 
-    if(!j->second.d_loaded)
-      ret<<j->second.d_name<<"\t"<<j->second.d_status<<endl;
-       
-  return ret.str();
-}
-
-static void callback(unsigned int domain_id, const string &domain, const string &qtype, const string &content, int ttl, int prio)
-{
-  us->insert(domain_id,domain,qtype,content,ttl,prio);
-}
-
-BindBackend::BindBackend(const string &suffix)
-{
-  d_logprefix="[bind1"+suffix+"backend]";
-  setArgPrefix("bind1"+suffix);
-  Lock l(&s_startup_lock);
-
-  d_transaction_id=0;
-  if(!s_first) {
-    return;
-  }
-   
-  s_first=0;
-  if(!mustDo("enable-huffman"))
-    s_hc.passthrough(true);
-  
-  if(mustDo("example-zones")) {
-    insert(0,"www.example.com","A","1.2.3.4");
-    insert(0,"example.com","SOA","ns1.example.com hostmaster.example.com");
-    insert(0,"example.com","NS","ns1.example.com",86400);
-    insert(0,"example.com","NS","ns2.example.com",86400);
-    insert(0,"example.com","MX","mail.example.com",3600,25);
-    insert(0,"example.com","MX","mail1.example.com",3600,25);
-    insert(0,"mail.example.com","A","4.3.2.1");
-    insert(0,"mail1.example.com","A","5.4.3.2");
-    insert(0,"ns1.example.com","A","4.3.2.1");
-    insert(0,"ns2.example.com","A","5.4.3.2");
-      
-    for(int i=0;i<1000;i++)
-      insert(0,"host-"+itoa(i)+".example.com","A","2.3.4.5");
-
-    BBDomainInfo bbd;
-    bbd.d_name="example.com";
-    bbd.d_filename="";
-    bbd.d_id=0;
-    d_bbds[0]=bbd; 
-    d_bbds[0].d_loaded=true;
-    d_bbds[0].d_status="parsed into memory at "+nowTime();
-  }
-  
-  loadConfig();
-  
-
-  extern DynListener *dl;
-  us=this;
-  dl->registerFunc("BIND1-RELOAD-NOW", &DLReloadNowHandler);
-  dl->registerFunc("BIND1-DOMAIN-STATUS", &DLDomStatusHandler);
-  dl->registerFunc("BIND1-LIST-REJECTS", &DLListRejectsHandler);
-}
-
-
-void BindBackend::rediscover(string *status)
-{
-  loadConfig(status);
-}
-
-void BindBackend::loadConfig(string* status)
-{
-  static int domain_id=1;
-
-  if(!getArg("config").empty()) {
-    BindParser BP;
-    try {
-      BP.parse(getArg("config"));
-    }
-    catch(AhuException &ae) {
-      L<<Logger::Error<<"Error parsing bind configuration: "<<ae.reason<<endl;
-      throw;
-    }
-    
-    ZoneParser ZP;
-      
-    vector<BindDomainInfo> domains=BP.getDomains();
-    
-    us=this;
-
-    ZP.setDirectory(BP.getDirectory());
-    ZP.setCallback(&callback);  
-    L<<Logger::Warning<<d_logprefix<<" Parsing "<<domains.size()<<" domain(s), will report when done"<<endl;
-    
-    int rejected=0;
-    int newdomains=0;
-
-    map<unsigned int, BBDomainInfo> nbbds;
-
-    for(vector<BindDomainInfo>::const_iterator i=domains.begin();
-       i!=domains.end();
-       ++i)
-      {
-       BBDomainInfo bbd;
-       if(i->type!="master" && i->type!="slave") {
-         L<<Logger::Warning<<d_logprefix<<" Warning! Skipping '"<<i->type<<"' zone '"<<i->name<<"'"<<endl;
-         continue;
-       }
-       map<unsigned int, BBDomainInfo>::const_iterator j=d_bbds.begin();
-       for(;j!=d_bbds.end();++j)
-         if(j->second.d_name==i->name) {
-           bbd=j->second;
-           break;
-         }
-       if(j==d_bbds.end()) { // entirely new
-         bbd.d_id=domain_id++;
-
-         bbd.setCheckInterval(getArgAsNum("check-interval"));
-         bbd.d_lastnotified=0;
-         bbd.d_loaded=false;
-       }
-
-       bbd.d_name=i->name;
-       bbd.d_filename=i->filename;
-       bbd.d_master=i->master;
-       
-       nbbds[bbd.d_id]=bbd; 
-       if(!bbd.d_loaded) {
-         L<<Logger::Info<<d_logprefix<<" parsing '"<<i->name<<"' from file '"<<i->filename<<"'"<<endl;
-         
-         try {
-           ZP.parse(i->filename,i->name,bbd.d_id); // calls callback for us
-           nbbds[bbd.d_id].setCtime();
-           nbbds[bbd.d_id].d_loaded=true;          // does this perform locking for us?
-           nbbds[bbd.d_id].d_status="parsed into memory at "+nowTime();
-           
-         }
-         catch(AhuException &ae) {
-           ostringstream msg;
-           msg<<" error at "+nowTime()+" parsing '"<<i->name<<"' from file '"<<i->filename<<"': "<<ae.reason;
-           if(status)
-             *status+=msg.str();
-           nbbds[bbd.d_id].d_status=msg.str();
-           L<<Logger::Warning<<d_logprefix<<msg.str()<<endl;
-           rejected++;
-         }
-       }
-       
-       vector<vector<BBResourceRecord> *>&tmp=d_zone_id_map[bbd.d_id];  // shrink trick
-       vector<vector<BBResourceRecord> *>(tmp).swap(tmp);
-      }
-
-
-    int remdomains=0;
-    set<string> oldnames, newnames;
-    for(map<unsigned int, BBDomainInfo>::const_iterator j=d_bbds.begin();j!=d_bbds.end();++j) {
-      oldnames.insert(j->second.d_name);
-    }
-    for(map<unsigned int, BBDomainInfo>::const_iterator j=nbbds.begin();j!=nbbds.end();++j) {
-      newnames.insert(j->second.d_name);
-    }
-
-    vector<string> diff;
-    set_difference(oldnames.begin(), oldnames.end(), newnames.begin(), newnames.end(), back_inserter(diff));
-    remdomains=diff.size();
-    for(vector<string>::const_iterator k=diff.begin();k!=diff.end();++k)
-      L<<Logger::Error<<"Removed: "<<*k<<endl;
-
-    for(map<unsigned int, BBDomainInfo>::iterator j=d_bbds.begin();j!=d_bbds.end();++j) { // O(N*M)
-      for(vector<string>::const_iterator k=diff.begin();k!=diff.end();++k)
-       if(j->second.d_name==*k) {
-         L<<Logger::Error<<"Removing records from zone '"<<j->second.d_name<<"' from memory"<<endl;
-         j->second.lock();
-         j->second.d_loaded=false;
-         nukeZoneRecords(&j->second);
-         j->second.unlock(); 
-         break;
-       }
-    }
-
-    vector<string> diff2;
-    set_difference(newnames.begin(), newnames.end(), oldnames.begin(), oldnames.end(), back_inserter(diff2));
-    newdomains=diff2.size();
-
-    d_bbds.swap(nbbds); // commit
-    ostringstream msg;
-    msg<<" Done parsing domains, "<<rejected<<" rejected, "<<newdomains<<" new, "<<remdomains<<" removed"; 
-    if(status)
-      *status=msg.str();
-
-    L<<Logger::Error<<d_logprefix<<msg.str()<<endl;
-    L<<Logger::Info<<d_logprefix<<" Number of hash buckets: "<<d_qnames.bucket_count()<<", number of entries: "<<d_qnames.size()<< endl;
-  }
-}
-
-/** nuke all records from memory, keep bbd intact though. Must be called with bbd lock held already! */
-void BindBackend::nukeZoneRecords(BBDomainInfo *bbd)
-{
-  bbd->d_loaded=0; // block further access
-    
-  // this emtpies all d_qnames vectors belonging to this domain. We find these vectors via d_zone_id_map
-  for(vector<vector<BBResourceRecord> *>::iterator i=d_zone_id_map[bbd->d_id].begin();
-      i!=d_zone_id_map[bbd->d_id].end();++i) {
-    (*i)->clear();
-  }
-  
-  // empty our d_zone_id_map of the references to the now empty vectors (which are not gone from d_qnames, btw)
-  d_zone_id_map[bbd->d_id].clear();
-}
-
-/** Must be called with bbd locked already. Will not be unlocked on return, is your own problem.
-    Does not throw errors or anything, may update d_status however */
-
-
-void BindBackend::queueReload(BBDomainInfo *bbd)
-{
-  // we reload *now* for the time being
-  //cout<<"unlock domain"<<endl;
-  bbd->unlock();
-  //cout<<"lock it again"<<endl;
-
-  bbd->lock();
-  try {
-    nukeZoneRecords(bbd);
-    
-    ZoneParser ZP;
-    us=this;
-    ZP.setCallback(&callback);  
-    ZP.parse(bbd->d_filename,bbd->d_name,bbd->d_id);
-    bbd->setCtime();
-    // and raise d_loaded again!
-    bbd->d_loaded=1;
-    bbd->d_checknow=0;
-    bbd->d_status="parsed into memory at "+nowTime();
-    L<<Logger::Warning<<"Zone '"<<bbd->d_name<<"' ("<<bbd->d_filename<<") reloaded"<<endl;
-  }
-  catch(AhuException &ae) {
-    ostringstream msg;
-    msg<<" error at "+nowTime()+" parsing '"<<bbd->d_name<<"' from file '"<<bbd->d_filename<<"': "<<ae.reason;
-    bbd->d_status=msg.str();
-  }
-}
-
-void BindBackend::lookup(const QType &qtype,const string &qname, DNSPacket *pkt_p, int zoneId )
-{
-  d_handle=new BindBackend::handle;
-  DLOG(L<<"BindBackend constructing handle for search for "<<qtype.getName()<<" for "<<
-       qname<<endl);
-
-  d_handle->qname=qname;
-  d_handle->parent=this;
-  d_handle->qtype=qtype;
-  string compressed;
-  s_hc.encode(toLower(qname),compressed);
-  d_handle->d_records=d_qnames[compressed];
-  d_handle->d_bbd=0;
-  if(!d_handle->d_records.empty()) {
-    BBDomainInfo& bbd=d_bbds[d_handle->d_records.begin()->domain_id];
-    if(!bbd.d_loaded) {
-      delete d_handle;
-      throw DBException("Zone temporarily not available (file missing, or master dead)"); // fuck
-    }
-
-    if(!bbd.tryRLock()) {
-      L<<Logger::Warning<<"Can't get read lock on zone '"<<bbd.d_name<<"'"<<endl;
-      delete d_handle;
-      throw DBException("Temporarily unavailable due to a zone lock"); // fuck
-    }
-      
-
-    if(!bbd.current()) {
-      L<<Logger::Warning<<"Zone '"<<bbd.d_name<<"' ("<<bbd.d_filename<<") needs reloading"<<endl;
-      queueReload(&bbd);
-    }
-    d_handle->d_bbd=&bbd;
-  }
-  else {
-    DLOG(L<<"Query with no results"<<endl);
-  }
-  d_handle->d_iter=d_handle->d_records.begin();
-  d_handle->d_list=false;
-}
-
-BindBackend::handle::handle()
-{
-  d_bbd=0;
-  count=0;
-}
-
-bool  BindBackend::get(DNSResourceRecord &r)
-{
-  if(!d_handle->get(r)) {
-    delete d_handle;
-    d_handle=0;
-    return false;
-  }
-  return true;
-}
-
-bool BindBackend::handle::get(DNSResourceRecord &r)
-{
-  if(d_list)
-    return get_list(r);
-  else
-    return get_normal(r);
-}
-
-bool BindBackend::handle::get_normal(DNSResourceRecord &r)
-{
-  DLOG(L << "BindBackend get() was called for "<<qtype.getName() << " record  for "<<
-       qname<<"- "<<d_records.size()<<" available!"<<endl);
-  
-
-  while(d_iter!=d_records.end() && !(qtype=="ANY" || (d_iter)->qtype==QType(qtype).getCode())) {
-    DLOG(L<<"Skipped "<<qname<<"/"<<QType(d_iter->qtype).getName()<<": '"<<*d_iter->content<<"'"<<endl);
-    d_iter++;
-  }
-  if(d_iter==d_records.end()) { // we've reached the end
-    if(d_bbd) {
-      d_bbd->unlock();
-      d_bbd=0;
-    }
-    return false;
-  }
-
-  DLOG(L << "BindBackend get() returning a rr with a "<<QType(d_iter->qtype).getCode()<<endl);
-
-  r.qname=qname; // fill this in
-  
-  r.content=*(d_iter)->content;
-  r.domain_id=(d_iter)->domain_id;
-  r.qtype=(d_iter)->qtype;
-  r.ttl=(d_iter)->ttl;
-  r.priority=(d_iter)->priority;
-  d_iter++;
-
-  return true;
-}
-
-bool BindBackend::list(const string &target, int id)
-{
-  if(!d_zone_id_map.count(id))
-    return false;
-
-  d_handle=new BindBackend::handle;
-  DLOG(L<<"BindBackend constructing handle for list of "<<id<<endl);
-
-  d_handle->d_qname_iter=d_zone_id_map[id].begin();
-  d_handle->d_qname_end=d_zone_id_map[id].end();   // iter now points to a vector of pointers to vector<BBResourceRecords>
-  d_handle->d_riter=(*(d_handle->d_qname_iter))->begin();
-  d_handle->d_rend=(*(d_handle->d_qname_iter))->end();
-  // rend?
-  d_handle->parent=this;
-  d_handle->id=id;
-  d_handle->d_list=true;
-  return true;
-}
-
-// naam -> naamnummer
-// naamnummer -> vector<BBResourceRecords>, BBResourceRecord bevat ook een pointer naar 
-
-bool BindBackend::handle::get_list(DNSResourceRecord &r)
-{
-  DLOG(L << "BindBackend get_list()"<<endl);
-
-  while(d_riter==d_rend) {
-    DLOG(L<<"Starting new record"<<endl);
-    d_qname_iter++;
-    if(d_qname_iter==d_qname_end) { // we've reached the end of recordsets for this id
-      DLOG(L<<"Really stop!"<<endl);
-      return false;
-    }
-    d_riter=(*(d_qname_iter))->begin();
-    d_rend=(*(d_qname_iter))->end();
-  }
-  // d_riter points to a pointer to BBResourceRecord 
-
-  //  r.qname=qname; // fill this in  HOW?!
-
-  r.qname=parent->s_hc.decode(*d_riter->qnameptr);
-  
-  r.content=*(d_riter)->content;
-  r.domain_id=(d_riter)->domain_id;
-  r.qtype=(d_riter)->qtype;
-  r.ttl=(d_riter)->ttl;
-  r.priority=(d_riter)->priority;
-  d_riter++;
-  return true;
-}
-
-bool BindBackend::isMaster(const string &name, const string &ip)
-{
-  for(map<uint32_t,BBDomainInfo>::iterator j=us->d_bbds.begin();j!=us->d_bbds.end();++j) 
-    if(j->second.d_name==name)
-      return j->second.d_master==ip;
-  return false;
-}
-
-class BindFactory : public BackendFactory
-{
-   public:
-      BindFactory() : BackendFactory("bind1") {}
-
-      void declareArguments(const string &suffix="")
-      {
-         declare(suffix,"config","Location of named.conf","");
-         declare(suffix,"example-zones","Install example zones","no");
-         declare(suffix,"enable-huffman","Enable huffman compression","no");
-         declare(suffix,"check-interval","Interval for zonefile changes","0");
-      }
-
-      DNSBackend *make(const string &suffix="")
-      {
-         return new BindBackend(suffix);
-      }
-};
-
-
-
-
-//! Magic class that is activated when the dynamic library is loaded
-class BindLoader
-{
-public:
-  BindLoader()
-  {
-    BackendMakers().report(new BindFactory);
-    L<<Logger::Notice<<"[BindBackend] This is the bind backend version "VERSION" ("__DATE__", "__TIME__") reporting"<<endl;
-  }
-};
-static BindLoader bindloader;
diff --git a/pdns/backends/bind/bindbackend.hh b/pdns/backends/bind/bindbackend.hh
deleted file mode 100644 (file)
index ed0e7d0..0000000
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
-    PowerDNS Versatile Database Driven Nameserver
-    Copyright (C) 2002  PowerDNS.COM BV
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2
-    as published by the Free Software Foundation
-    
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-*/
-#include <string>
-#include <map>
-#include <set>
-#include <pthread.h>
-#include <time.h>
-#include <fstream>
-
-#include "huffman.hh"
-
-#if __GNUC__ >= 3
-# include <ext/hash_map>
-using namespace __gnu_cxx;
-#else
-# include <hash_map>
-#endif
-
-
-using namespace std;
-
-class BBDomainInfo
-{
-public:
-  BBDomainInfo();
-
-  void setCtime();
-
-  bool current();
-
-  bool d_loaded;
-  string d_status;
-  bool d_checknow;
-  time_t d_ctime;
-  string d_name;
-  string d_filename;
-  unsigned int d_id;
-  time_t d_last_check;
-  string d_master;
-  int d_confcount;
-  uint32_t d_lastnotified;
-
-  bool tryRLock()
-  {
-    //    cout<<"[trylock!] "<<(void*)d_rwlock<<"/"<<getpid()<<endl;
-    return pthread_rwlock_tryrdlock(d_rwlock)!=EBUSY;
-  }
-  
-  void unlock()
-  {
-    //    cout<<"[unlock] "<<(void*)d_rwlock<<"/"<<getpid()<<endl;
-    pthread_rwlock_unlock(d_rwlock);
-  }
-  
-  void lock()
-  {
-    //cout<<"[writelock!] "<<(void*)d_rwlock<<"/"<<getpid()<<endl;
-
-    pthread_rwlock_wrlock(d_rwlock);
-  }
-
-  void setCheckInterval(time_t seconds);
-private:
-  time_t getCtime();
-  time_t d_checkinterval;
-  time_t d_lastcheck;
-  pthread_rwlock_t *d_rwlock;
-};
-      
-
-
-class BBResourceRecord
-{
-public:
-  bool operator==(const BBResourceRecord &o) const
-  {
-    return (o.domain_id==domain_id && o.qtype==qtype && o.content==content && 
-           o.ttl==ttl && o.priority==priority);
-  }
-  
-  const string *qnameptr; // 4
-  unsigned int domain_id;  // 4
-  unsigned short int qtype;             // 2
-  unsigned short int priority;  // 2
-  const string *content;   // 4 
-  unsigned int ttl;        // 4
-
-};
-
-struct compare_string
-{
-  bool operator()(const string& s1, const string& s2) const
-  {
-    return s1 == s2;
-  }
-};
-
-struct hash_string
-{
-  size_t operator()(const string& s) const
-  {
-    return __stl_hash_string(s.c_str());
-  }
-};
-
-typedef hash_map<string,vector<BBResourceRecord>, hash_string, compare_string> cmap_t; 
-
-
-
-/** The BindBackend is a DNSBackend that can answer DNS related questions. It looks up data
-    in a Bind-style zone file 
-
-    How this all works is quite complex and prone to change. There are a number of containers involved which,
-    together, contain everything we need to know about a domain or a record.
-
-    A domain consists of records. So, 'example.com' has 'www.example.com' as a record.
-
-    All record names are stored in the hash_map d_qnames, with their name as index. Attached to that index
-    is a vector of BBResourceRecords ('BindBackend') belonging to that qname. Each record contains a d_domainid,
-    which is the ID of the domain it belongs to.
-
-    Then there is the map called d_bbds which has as its key the Domain ID, and attached a BBDomainInfo object, which
-    tells us domain metadata (place on disk, if it is a master or a slave etc).
-
-    To allow for AXFRs, there is yet another container, the d_zone_id_map, which contains per domain_id a vector
-    of pointers to vectors of BBResourceRecords. When read in sequence, these deliver all records of a domain_id.
-
-    As there is huge repitition in the right hand side of records, many records point to the same thing (IP address, nameserver),
-    a list of these is kept in s_contents, and each BBResourceRecord only contains a pointer to a record in s_contents.
-
-    So, summarizing:
-    
-    class BBResourceRecord:
-    Everything you need to know about a record. In this context we call the name of a BBResourceRecord 'qname'
-
-    class BBDomainInfo:
-    Domain metadata, like location on disk, last time zone was checked
-
-    d_qnames<qname,vector<BBResourceRecord> >:
-    If you know the qname of a record, this gives you all records under that name. 
-
-    set<string>s_contents:
-    Set of all 'contents' of records, the right hand sides. 
-
-    map<int,vector<vector<BBResourceRecord>* > > d_zone_id_map:
-    If you know the zone_id, this has a vector of pointers to vectors in d_qnames, for AXFR
-
-    map<unsigned int, BBDomainInfo>d_bbds:
-    Map of all domains we know about and metadata about them.
-
-    
-*/
-class BindBackend : public DNSBackend
-{
-public:
-  BindBackend(const string &suffix=""); //!< Makes our connection to the database. Calls exit(1) if it fails.
-  void getUnfreshSlaveInfos(vector<DomainInfo> *unfreshDomains);
-  void getUpdatedMasters(vector<DomainInfo> *changedDomains);
-  bool getDomainInfo(const string &domain, DomainInfo &di);
-  time_t getCtime(const string &fname);
-  
-
-  void lookup(const QType &, const string &qdomain, DNSPacket *p=0, int zoneId=-1);
-  bool list(const string &target, int id);
-  bool get(DNSResourceRecord &);
-
-  static DNSBackend *maker();
-  static set<string> s_contents;
-  static pthread_mutex_t s_startup_lock;
-
-  void setFresh(uint32_t domain_id);
-  void setNotified(uint32_t id, uint32_t serial);
-  bool startTransaction(const string &qname, int id);
-  //  bool BindBackend::stopTransaction(const string &qname, int id);
-  bool feedRecord(const DNSResourceRecord &r);
-  bool commitTransaction();
-  bool abortTransaction();
-  void insert(int id, const string &qname, const string &qtype, const string &content, int ttl, int prio);  
-  void rediscover(string *status=0);
-  static HuffmanCodec s_hc;
-
-  bool isMaster(const string &name, const string &ip);
-private:
-  class handle
-  {
-  public:
-    bool get(DNSResourceRecord &);
-    ~handle() {
-      if(d_bbd)
-       d_bbd->unlock();
-    }
-    handle();
-
-    BindBackend *parent;
-
-    vector<BBResourceRecord>d_records;
-    vector<BBResourceRecord>::const_iterator d_iter;
-    
-    vector<BBResourceRecord>::const_iterator d_riter;
-    vector<BBResourceRecord>::const_iterator d_rend;
-    vector<vector<BBResourceRecord> *>::const_iterator d_qname_iter;
-    vector<vector<BBResourceRecord> *>::const_iterator d_qname_end;
-
-    // static map<int,vector<vector<BBResourceRecord>* > > d_zone_id_map;  
-    //                vector<vector<BBResourceRecord>* >   d_zone_id_map[id]
-    // iterator NAAR         vector<BBResourceRecord>*    d_zone_id_map[id].begin()
-
-    bool d_list;
-    int id;
-    BBDomainInfo* d_bbd;
-    string qname;
-    QType qtype;
-  private:
-    int count;
-    
-    bool get_normal(DNSResourceRecord &);
-    bool get_list(DNSResourceRecord &);
-  };
-
-  static cmap_t d_qnames;
-  static map<int,vector<vector<BBResourceRecord>* > > d_zone_id_map;  
-
-  static map<unsigned int, BBDomainInfo>d_bbds;
-  static int s_first;
-
-  string d_logprefix;
-  int d_transaction_id;
-  string d_transaction_tmpname;
-  ofstream *d_of;
-  handle *d_handle;
-  void queueReload(BBDomainInfo *bbd);
-  BBResourceRecord resourceMaker(int id, const string &qtype, const string &content, int ttl, int prio);
-  void reload();
-  static string DLDomStatusHandler(const vector<string>&parts, Utility::pid_t ppid);
-  static string DLListRejectsHandler(const vector<string>&parts, Utility::pid_t ppid);
-  static string DLReloadNowHandler(const vector<string>&parts, Utility::pid_t ppid);
-  void loadConfig(string *status=0);
-  void nukeZoneRecords(BBDomainInfo *bbd);
-};
index 86466123d980052e49b2481d841bb616f129b820..622ee6ce01b67713607ce463762ee3c0ecea9569 100644 (file)
@@ -1,6 +1,6 @@
 /*
     PowerDNS Versatile Database Driven Nameserver
-    Copyright (C) 2002-2006  PowerDNS.COM BV
+    Copyright (C) 2002-2007  PowerDNS.COM BV
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License version 2 as 
@@ -33,8 +33,7 @@ using namespace std;
 #include "dnsbackend.hh"
 #include "bindbackend2.hh"
 #include "dnspacket.hh"
-
-#include "zoneparser.hh"
+#include "zoneparser-tng.hh"
 #include "bindparser.hh"
 #include "logger.hh"
 #include "arguments.hh"
@@ -321,16 +320,11 @@ static string canonic(string ret)
   return ret;
 }
 
-static void InsertionCallback(shared_ptr<Bind2Backend::State> stage, unsigned int domain_id, const string &domain, const string &qtype, const string &content, int ttl, int prio)
-{
-  us->insert(stage, domain_id, domain, qtype, content, ttl, prio);
-}
-
 set<string> contents;
 
 /** This function adds a record to a domain with a certain id. 
     Much of the complication is due to the efforts to benefit from std::string reference counting copy on write semantics */
-void Bind2Backend::insert(shared_ptr<State> stage, int id, const string &qnameu, const string &qtype, const string &content, int ttl=300, int prio=25)
+void Bind2Backend::insert(shared_ptr<State> stage, int id, const string &qnameu, const QType &qtype, const string &content, int ttl=300, int prio=25)
 {
   // XXXX WRONG WRONG WRONG REWRITE
 
@@ -352,7 +346,7 @@ void Bind2Backend::insert(shared_ptr<State> stage, int id, const string &qnameu,
   if(!records.empty() && bdr.qname==(records.end()-1)->qname)
     bdr.qname=(records.end()-1)->qname;
 
-  bdr.qtype=QType(qtype.c_str()).getCode();
+  bdr.qtype=qtype.getCode();
   bdr.content=canonic(content); // I think this is wrong, the zoneparser should not come up with . terminated stuff XXX FIXME
   set<string>::const_iterator i=contents.find(bdr.content);
   if(i!=contents.end())
@@ -480,16 +474,16 @@ void Bind2Backend::loadConfig(string* status)
       throw;
     }
 
-    ZoneParser ZP;
+
       
     vector<BindDomainInfo> domains=BP.getDomains();
     
     us=this;
 
     d_binddirectory=BP.getDirectory();
-    ZP.setDirectory(d_binddirectory);
-    ZoneParser::callback_t func=boost::bind(&InsertionCallback, staging, _1, _2, _3, _4, _5, _6);
-    ZP.setCallback(func);  
+    //    ZP.setDirectory(d_binddirectory);
+    //    ZoneParser::callback_t func=boost::bind(&InsertionCallback, staging, _1, _2, _3, _4, _5, _6);
+
 
     L<<Logger::Warning<<d_logprefix<<" Parsing "<<domains.size()<<" domain(s), will report when done"<<endl;
     
@@ -537,7 +531,13 @@ void Bind2Backend::loadConfig(string* status)
            // we need to allocate a new vector so we don't kill the original, which is still in use!
            bbd->d_records=shared_ptr<vector<Bind2DNSRecord> > (new vector<Bind2DNSRecord>); 
 
-           ZP.parse(i->filename, i->name, bbd->d_id); // calls callback for us
+           ZoneParserTNG zpt(i->filename, i->name, BP.getDirectory());
+           DNSResourceRecord rr;
+           while(zpt.get(rr)) {
+             insert(staging, bbd->d_id, rr.qname, rr.qtype, rr.content, rr.ttl, rr.priority);
+           }
+
+           //      ZP.parse(i->filename, i->name, bbd->d_id); // calls callback for us
            L<<Logger::Info<<d_logprefix<<" sorting '"<<i->name<<"'"<<endl;
 
            sort(staging->id_zone_map[bbd->d_id].d_records->begin(), staging->id_zone_map[bbd->d_id].d_records->end());
@@ -637,18 +637,17 @@ void Bind2Backend::queueReload(BB2DomainInfo *bbd)
   try {
     nukeZoneRecords(bbd); // ? do we need this?
     
-    ZoneParser ZP;
     us=this;
 
-    ZP.setDirectory(d_binddirectory);
-    ZoneParser::callback_t func=boost::bind(&InsertionCallback, staging, _1, _2, _3, _4, _5, _6);
-    ZP.setCallback(func);  
-
     staging->id_zone_map[bbd->d_id]=s_state->id_zone_map[bbd->d_id];
     staging->id_zone_map[bbd->d_id].d_records=shared_ptr<vector<Bind2DNSRecord> > (new vector<Bind2DNSRecord>);  // nuke it
 
-    ZP.parse(bbd->d_filename, bbd->d_name, bbd->d_id);
-    
+    ZoneParserTNG zpt(bbd->d_filename, bbd->d_name, d_binddirectory);
+    DNSResourceRecord rr;
+    while(zpt.get(rr)) {
+      insert(staging, bbd->d_id, rr.qname, rr.qtype, rr.content, rr.ttl, rr.priority);
+    }
+        
     sort(staging->id_zone_map[bbd->d_id].d_records->begin(), staging->id_zone_map[bbd->d_id].d_records->end());
     staging->id_zone_map[bbd->d_id].setCtime();
     
index db3f9b5ce4faf816d512f1d81b4bcc84f8038777..d3d51e11b5dc3a38d3ff4b1d6fa3fc6014328f06 100644 (file)
@@ -120,7 +120,7 @@ public:
     id_zone_map_t id_zone_map;
   };
 
-  void insert(shared_ptr<State> stage, int id, const string &qname, const string &qtype, const string &content, int ttl, int prio);  
+  void insert(shared_ptr<State> stage, int id, const string &qname, const QType &qtype, const string &content, int ttl, int prio);  
   void rediscover(string *status=0);
 
   bool isMaster(const string &name, const string &ip);
index 7474f7bb3d23d3311f68be2413c2bc08f9261caf..43c28b110c38493e8f37292a4f49adebdcf4258e 100644 (file)
@@ -8,7 +8,6 @@
 #include <utility>
 #include <errno.h>
 #include "misc.hh"
-#include "zoneparser.hh"
 #include "ahuexception.hh"
 using namespace std;
 #define YYDEBUG 1
@@ -126,7 +125,7 @@ command:
 zone_command:
        ZONETOK quotedname zone_block
        {
-               s_di.name=ZoneParser::canonic($2);
+               s_di.name=stripDot($2);
                
                parent->commit(s_di);
                s_di.clear();
index f6b5a5978c0c9acf4e660053ebffd45526f58ce3..c92bc8b237810c5b77fae23cd35024f65c8da911 100644 (file)
@@ -1,6 +1,7 @@
 /*
  *  PowerDNS BIND Zone to LDAP converter
  *  Copyright (C) 2003  Norbert Sendetzky
+ *  Copyright (C) 2007  bert hubert
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License version 2
 #include <iostream>
 #include <stdio.h>
 #include "arguments.hh"
-#include "zoneparser.hh"
 #include "bindparser.hh"
 #include "statbag.hh"
+#include <boost/function.hpp>
 #include "misc.hh"
 #include "dns.hh"
-
+#include "zoneparser-tng.hh"
 
 using std::map;
 using std::string;
 using std::vector;
 
-
-
 StatBag S;
 ArgvMap args;
 bool g_dnsttl;
@@ -43,14 +42,12 @@ string g_basedn;
 string g_zonename;
 map<string,bool> g_objects;
 
-
-
 static void callback_simple( unsigned int domain_id, const string &domain, const string &qtype, const string &content, int ttl, int prio )
 {
        string host;
        string::size_type pos;
        vector<string> parts;
-       string domain2 = ZoneParser::canonic( domain );
+       string domain2 = stripDot( domain );
 
 
        if( ( pos = domain2.rfind( g_zonename ) ) == string::npos )
@@ -59,7 +56,7 @@ static void callback_simple( unsigned int domain_id, const string &domain, const
                return;
        }
 
-       host = ZoneParser::canonic( domain2.substr( 0, pos ) );
+       host = stripDot( domain2.substr( 0, pos ) );
 
        cout << "dn: dc=";
        if( !host.empty() ) { cout << host << ",dc="; }
@@ -86,7 +83,7 @@ static void callback_simple( unsigned int domain_id, const string &domain, const
 
        cout << qtype << "Record: ";
        if( prio != 0 ) { cout << prio << " "; }
-       cout << ZoneParser::canonic( content ) << endl << endl;
+       cout << stripDot( content ) << endl << endl;
 }
 
 
@@ -96,7 +93,7 @@ static void callback_tree( unsigned int domain_id, const string &domain, const s
        unsigned int i;
        string dn, net;
        vector<string> parts;
-       string domain2 = ZoneParser::canonic( domain );
+       string domain2 = stripDot( domain );
 
        stringtok( parts, domain2, "." );
        if( parts.empty() ) { return; }
@@ -142,7 +139,7 @@ static void callback_tree( unsigned int domain_id, const string &domain, const s
 
        cout << qtype << "Record: ";
        if( prio != 0 ) { cout << prio << " "; }
-       cout << ZoneParser::canonic( content ) << endl << endl;
+       cout << stripDot( content ) << endl << endl;
 }
 
 
@@ -150,7 +147,6 @@ static void callback_tree( unsigned int domain_id, const string &domain, const s
 int main( int argc, char* argv[] )
 {
        BindParser BP;
-       ZoneParser ZP;
        vector<string> parts;
 
 
@@ -181,18 +177,18 @@ int main( int argc, char* argv[] )
 
                g_basedn = args["basedn"];
                g_dnsttl = args.mustDo( "dnsttl" );
-
-               ZP.setCallback( &callback_simple );
+               typedef boost::function<void(unsigned int, const string &, const string &, const string &, int, int)> callback_t;
+               callback_t callback = callback_simple;
                if( args["layout"] == "tree" )
                {
-                       ZP.setCallback( &callback_tree );
+                       callback=callback_tree;
                }
 
                if( !args["named-conf"].empty() )
                {
                        BP.setVerbose( args.mustDo( "verbose" ) );
                        BP.parse( args["named-conf"] );
-                       ZP.setDirectory( BP.getDirectory() );
+//                     ZP.setDirectory( BP.getDirectory() );
                        const vector<BindDomainInfo> &domains = BP.getDomains();
 
                        for( vector<BindDomainInfo>::const_iterator i = domains.begin(); i != domains.end(); i++ )
@@ -203,7 +199,10 @@ int main( int argc, char* argv[] )
                                        {
                                                cerr << "Parsing file: " << i->filename << ", domain: " << i->name << endl;
                                                g_zonename = i->name;
-                                               ZP.parse( i->filename, i->name, 0 );
+                                               ZoneParserTNG zpt(i->filename, i->name, BP.getDirectory());
+                                               DNSResourceRecord rr;
+                                               while(zpt.get(rr))
+                                                       callback(0, rr.qname, rr.qtype.getName(), rr.content, rr.ttl, rr.priority);
                                        }
                                }
                                catch( AhuException &ae )
@@ -225,8 +224,10 @@ int main( int argc, char* argv[] )
                        }
 
                        g_zonename = args["zone-name"];
-                       ZP.setDirectory( "." );
-                       ZP.parse( args["zone-file"], args["zone-name"], 0 );
+                       ZoneParserTNG zpt(args["zone-file"], args["zone-name"]);
+                       DNSResourceRecord rr;
+                       while(zpt.get(rr))
+                               callback(0, rr.qname, rr.qtype.getName(), rr.content, rr.ttl, rr.priority);
                }
        }
        catch( AhuException &ae )
index 1c61d977f50f76a9192d3763323ee36f2793e59c..51b00d73cae575dea3325a8c8b1e9daafdcdc7ec 100644 (file)
@@ -1,6 +1,6 @@
 /*
     PowerDNS Versatile Database Driven Nameserver
-    Copyright (C) 2002  PowerDNS.COM BV
+    Copyright (C) 2002 - 2007  PowerDNS.COM BV
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License version 2
@@ -34,11 +34,11 @@ using namespace std;
 
 #include "dns.hh"
 #include "arguments.hh"
-#include "zoneparser.hh"
 #include "bindparser.hh"
 #include "statbag.hh"
 #include "misc.hh"
 #include "dnspacket.hh"
+#include "zoneparser-tng.hh"
 
 StatBag S;
 
@@ -75,7 +75,7 @@ static void callback(unsigned int domain_id,const string &domain, const string &
 
   if(qtype=="SOA") {
     //    cerr<<"Juh: "<<dirty_hack_num<<", "<<lastsoa_domain_id<<", "<<lastsoa_qname<<", "<<domain<<endl;
-    if(dirty_hack_num==lastsoa_domain_id && lastsoa_qname!=ZoneParser::canonic(domain)) {
+    if(dirty_hack_num==lastsoa_domain_id && lastsoa_qname!=stripDot(domain)) {
       dirty_hack_num++;
       cerr<<"Second SOA in zone, raised domain_id"<<endl;
       if(mode==POSTGRES || mode==ORACLE) {
@@ -89,7 +89,7 @@ static void callback(unsigned int domain_id,const string &domain, const string &
        }
        
        if(mode==POSTGRES) {
-         cout<<"insert into domains (name,type) values ("<<toLower(sqlstr(ZoneParser::canonic(domain)))<<",'NATIVE');"<<endl;
+         cout<<"insert into domains (name,type) values ("<<toLower(sqlstr(stripDot(domain)))<<",'NATIVE');"<<endl;
        }
        else if(mode==ORACLE) {
          cout<<"insert into domains (id,name,type) values (domains_id_sequence.nextval,"<<toLower(sqlstr(domain))<<",'NATIVE');"<<endl;
@@ -98,40 +98,40 @@ static void callback(unsigned int domain_id,const string &domain, const string &
     }
     SOAData soadata;
     DNSPacket::fillSOAData(content, soadata);
-    soadata.hostmaster=ZoneParser::canonic(soadata.hostmaster);
-    soadata.nameserver=ZoneParser::canonic(soadata.nameserver);
+    soadata.hostmaster=stripDot(soadata.hostmaster);
+    soadata.nameserver=stripDot(soadata.nameserver);
     content=DNSPacket::serializeSOAData(soadata);
 
 
-    lastsoa_qname=ZoneParser::canonic(domain);
+    lastsoa_qname=stripDot(domain);
   }
   
   lastsoa_domain_id=dirty_hack_num;
 
   if(mode==MYSQL) {
     cout<<"insert into records (domain_id, name,type,content,ttl,prio) values ("<< dirty_hack_num<<", "<<
-      sqlstr(ZoneParser::canonic(domain))<<", "<<
+      sqlstr(stripDot(domain))<<", "<<
       sqlstr(qtype)<<", "<<
-      sqlstr(ZoneParser::canonic(content))<<", "<<ttl<<", "<<prio<<");\n";
+      sqlstr(stripDot(content))<<", "<<ttl<<", "<<prio<<");\n";
   }
   if(mode==POSTGRES) {
     cout<<"insert into records (domain_id, name,type,content,ttl,prio) select id ,"<<
-      sqlstr(toLower(ZoneParser::canonic(domain)))<<", "<<
+      sqlstr(toLower(stripDot(domain)))<<", "<<
       sqlstr(qtype)<<", "<<
-      sqlstr(ZoneParser::canonic(content))<<", "<<ttl<<", "<<prio<< 
+      sqlstr(stripDot(content))<<", "<<ttl<<", "<<prio<< 
       " from domains where name="<<toLower(sqlstr(lastsoa_qname))<<";\n";
   }
   else if(mode==ORACLE) {
     cout<<"insert into Records (id,ZoneId, name,type,content,TimeToLive,Priority) select RECORDS_ID_SEQUENCE.nextval,id ,"<<
-      sqlstr(toLower(ZoneParser::canonic(domain)))<<", "<<
+      sqlstr(toLower(stripDot(domain)))<<", "<<
       sqlstr(qtype)<<", "<<
-      sqlstr(ZoneParser::canonic(content))<<", "<<ttl<<", "<<prio<< 
+      sqlstr(stripDot(content))<<", "<<ttl<<", "<<prio<< 
       " from Domains where name="<<toLower(sqlstr(lastsoa_qname))<<";\n";
   }
   else if(mode==BARE) {
     cout<< dirty_hack_num<<"\t"<<
-      sqlstr(ZoneParser::canonic(domain))<<"\t"<<
-      sqlstr(qtype)<<"\t"<<sqlstr(ZoneParser::canonic(content))<<"\t"<<prio<<"\t"<<ttl<<"\n";
+      sqlstr(stripDot(domain))<<"\t"<<
+      sqlstr(qtype)<<"\t"<<sqlstr(stripDot(content))<<"\t"<<prio<<"\t"<<ttl<<"\n";
   }
 
 }
@@ -213,14 +213,11 @@ int main(int argc, char **argv)
       BP.setVerbose(arg().mustDo("verbose"));
       BP.parse(namedfile.empty() ? "./named.conf" : namedfile);
     
-      ZoneParser ZP;
-    
       const vector<BindDomainInfo> &domains=BP.getDomains();
 
       int numdomains=domains.size();
       int tick=numdomains/100;
-      ZP.setDirectory(BP.getDirectory());
-      ZP.setCallback(&callback);  
+      //      ZP.setDirectory(BP.getDirectory());
     
       for(vector<BindDomainInfo>::const_iterator i=domains.begin();
          i!=domains.end();
@@ -252,7 +249,10 @@ int main(int argc, char **argv)
              }
              lastsoa_qname=i->name;
            }
-           ZP.parse(i->filename,i->name,0);
+           ZoneParserTNG zpt(i->filename, i->name, BP.getDirectory());
+           DNSResourceRecord rr;
+           while(zpt.get(rr)) 
+             callback(0, rr.qname, rr.qtype.getName(), rr.content, rr.ttl, rr.priority);
          }
          catch(AhuException &ae) {
            if(!arg().mustDo("on-error-resume-next"))
@@ -268,11 +268,12 @@ int main(int argc, char **argv)
       cerr<<"\r100% done\033\133\113"<<endl;
     }
     else {
+      ZoneParserTNG zpt(zonefile, arg()["zone-name"]);
+      DNSResourceRecord rr;
       dirty_hack_num=-1; // trigger first SOA output
-      ZoneParser ZP;
-      ZP.setDirectory(".");
-      ZP.setCallback(&callback);  
-      ZP.parse(zonefile,arg()["zone-name"],0);
+      while(zpt.get(rr)) 
+       callback(0, rr.qname, rr.qtype.getName(), rr.content, rr.ttl, rr.priority);
+
     }
     cerr<<"Parsed "<<num_records<<" records"<<endl;
     
diff --git a/pdns/backends/bind/zoneparser.hh b/pdns/backends/bind/zoneparser.hh
deleted file mode 100644 (file)
index 52f30c4..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
-    PowerDNS Versatile Database Driven Nameserver
-    Copyright (C) 2002-2006  PowerDNS.COM BV
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2
-    as published by the Free Software Foundation
-    
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-*/
-#ifndef ZONEPARSER_HH
-#define ZONEPARSER_HH
-#include <string>
-#include <map>
-#include <vector>
-#include <time.h>
-#include <boost/function.hpp>
-
-using namespace std;
-
-class ZoneParser
-{
- public:
-  struct Record
-  {
-    string name;
-    string qtype;
-    string content;
-    int ttl;
-    int prio;
-  };
-  ZoneParser() : d_ttl(3600) {}
-  ~ZoneParser();
-  void parse(const string &fname,const string &origin, unsigned int domain_id);
-  void parse(const string &fname,const string &origin, vector<Record>&records);
-  
-  //  typedef void callback_t(unsigned int domain_id, const string &domain, const string &qtype, const string &content, int ttl, int prio);
-  typedef boost::function<void(unsigned int, const string &, const string &, const string &, int, int)> callback_t;
-  void setCallback(callback_t callback);
-  callback_t d_callback;
-  bool parseLine(const vector<string>&words, vector<Record> &);
-  bool eatLine(const string& line, vector<Record>&);
-  void setDirectory(const string &dir);
-  static string canonic(const string& dom);
-    
-private:
-  unsigned int zoneNumber(const string &str);
-  string d_filename;
-  string d_dir;
-  unsigned int d_lineno;
-  void soaCanonic(string &content);
-  bool isNumber(const string &);
-  bool isType(const string &);
-  bool isClass(const string &);
-  string d_origin;
-  time_t d_ttl;
-  void cutOff(string &line, const string &delim);
-  void fillRec(const string &qname, const string &qtype, const string &content, int ttl, int prio, vector<Record>&rec);
-  string expandWord(const string &line, int value);
-};
-
-
-#endif /* BINDPARSER_HH */
diff --git a/pdns/backends/bind/zoneparser2.cc b/pdns/backends/bind/zoneparser2.cc
deleted file mode 100644 (file)
index 5aa0f34..0000000
+++ /dev/null
@@ -1,586 +0,0 @@
-/*
-    PowerDNS Versatile Database Driven Nameserver
-    Copyright (C) 2002 - 2005  PowerDNS.COM BV
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License version 2 as 
-    published by the Free Software Foundation
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-*/
-
-#ifdef WIN32
-# pragma warning ( disable: 4786 )
-#endif // WIN32
-
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-#include <string>
-#include <vector>
-#include <iostream>
-#include <utility>
-#include <ctype.h>
-#include <zlib.h>
-#include <errno.h>
-#include <stack>
-#include "utility.hh"
-#include "misc.hh"
-#include "ahuexception.hh"
-#include "qtype.hh"
-#include <algorithm>
-using namespace std;
-
-#include "zoneparser.hh"
-
-extern const char *bind_directory;
-void ZoneParser::setDirectory(const string &dir)
-{
-  d_dir=dir;
-
-}
-
-void ZoneParser::parse(const string &fname, const string &origin, unsigned int domain_id)
-{      
-  d_filename=fname.c_str();
-  
-  gzFile zonein;
-  if(fname!="-")
-    zonein=gzopen(fname.c_str(),"r");
-  else
-    zonein=gzdopen(STDIN_FILENO,"r");
-
-  if(!zonein)
-    throw AhuException("Unable to open zonefile '"+fname+"': "+stringerror());
-
-  d_origin=origin;
-  
-  char cline[2048];
-  string line;
-  d_lineno=0;
-  vector<Record> rec;
-  stack<gzFile> fds;
-  fds.push(zonein);
-
-
-  while(!fds.empty()) {
-    while(gzgets(fds.top(), cline,sizeof(cline)-1)) {
-      line=cline;
-      chomp(line," \x1a\r\n");
-      cutOff(line,";");
-
-      d_lineno++;
-      if(line.empty())
-       continue;
-
-      if(line[0]=='$' && (!line.find("$INCLUDE ") || !line.find("$include "))) {
-       vector<string> parts;
-       stringtok(parts,line," \t\n"); 
-       if(parts.size()!=2)
-         throw AhuException("Invalid $INCLUDE statement in zonefile '"+fname+"'");
-       
-       string filename=unquotify(parts[1]);
-       if(filename[0]!='/')
-         filename=d_dir+"/"+filename;
-
-
-       gzFile fp=gzopen(filename.c_str(),"r");
-       if(!fp)
-         throw AhuException("Unable to open zonefile '"+filename+"' included from '"+fname+"': "+stringerror());
-       fds.push(fp);
-       continue;
-      }
-      if(eatLine(line,rec))
-       for(vector<Record>::const_iterator i=rec.begin();i!=rec.end();++i)
-         d_callback(domain_id, i->name, i->qtype, i->content, i->ttl, i->prio);
-    }
-
-    //    if(ferror(fds.top())) {
-    //      fclose(fds.top());
-    //      fds.pop();
-    //      throw AhuException("Error reading from file '"+fname+"': "+stringerror());
-    //    }
-    gzclose(fds.top());
-    fds.pop();
-  }
-}
-
-void ZoneParser::parse(const string &fname, const string &origin, vector<Record>&records)
-{      
-  d_filename=fname.c_str();
-
-  gzFile zonein=gzopen(fname.c_str(),"r");
-
-  if(!zonein)
-    throw AhuException("Unable to open zonefile '"+fname+"': "+stringerror());
-
-  d_origin=origin;
-  
-  char cline[2048];
-  string line;
-  d_lineno=0;
-  vector<Record> rec;
-  stack<gzFile>fds;
-  fds.push(zonein);
-
-  while(!fds.empty()) {
-    while(gzgets(fds.top(),cline, sizeof(cline)-1)) {
-      line=cline;
-      chomp(line," \x1a\r\n");
-      cutOff(line,";");
-
-      d_lineno++;
-      if(line.empty())
-       continue;
-
-      if(line[0]=='$' && (!line.find("$INCLUDE ") || !line.find("$include "))) {
-       vector<string> parts;
-       stringtok(parts,line," \t\r\n");
-       if(parts.size()!=2)
-         throw AhuException("Invalid $INCLUDE statement in zonefile '"+fname+"'");
-
-       string filename=unquotify(parts[1]);
-       gzFile fp=gzopen(filename.c_str(),"r");
-       if(!fp)
-         throw AhuException("Unable to open zonefile '"+filename+"' included from '"+fname+"': "+stringerror());
-       fds.push(fp);
-       continue;
-      }
-      if(eatLine(line,rec))
-       for(vector<Record>::const_iterator i=rec.begin();i!=rec.end();++i)
-         records.push_back(*i);
-    }
-
-    //    if(ferror(fds.top())) {
-    //      fclose(fds.top());
-    //      fds.pop();
-    //      throw AhuException("Error reading from file '"+fname+"': "+stringerror());
-    //    }
-    gzclose(fds.top());
-    fds.pop();
-  }
-}
-
-
-void ZoneParser::fillRec(const string &qname, const string &qtype, const string &content, int ttl, int prio, vector<Record>&recs)
-{
-  Record rec;
-  rec.name=qname;
-  rec.qtype=qtype;
-
-  if(!QType::chartocode(qtype.c_str()))
-    throw AhuException("Unknown qtype '"+qtype+"' on line "+itoa(d_lineno)+" of file '"+d_filename+"'");
-  rec.content=content;
-  rec.ttl=ttl;
-  rec.prio=prio;
-
-  //  cerr<<"filled with type: "<<rec.qtype<<", "<<QType::chartocode(qtype.c_str())<<": "<<content<<endl;
-  recs.push_back(rec);
-}
-
-
-void ZoneParser::cutOff(string &line, const string &delim)
-{
-  string::size_type pos=line.find_first_of(delim);
-  if(pos==string::npos)
-    return;
-  line.resize(pos);
-}
-
-bool ZoneParser::eatLine(const string& line, vector<Record> &rec)
-{
-  rec.clear();
-  static string tline;
-  static string lastfirstword;
-  string::size_type pos=string::npos;
-
-  if(tline.empty()) {
-    pos=line.find_first_of("(");
-    if(pos!=string::npos) { // this is a line that continues
-      tline=line.substr(0,pos);
-      return false;
-    }
-    else 
-      tline=line; // complete & boring line
-  }
-  else { // continuation
-    pos=line.find(")");
-    if(pos==string::npos) { // middle part
-      tline.append(line);
-      return false;
-    }
-    else {
-      tline.append(line.substr(0,pos)); // end part, we have a complete line!
-    }
-  }
-  
-  // full & unparenthesised line now in tline!
-  //  cout<<"line: '"<<tline<<"'"<<endl;
-  if(tline.empty() || tline.find_first_not_of(" \t\n")==string::npos) {
-
-    tline="";
-    return false;
-  }
-
-  if(isspace(tline[0]))
-    tline=lastfirstword+"\t"+tline;
-
-  vector<string> parts;
-  stringtok(parts,tline," \t");  // we used to strip " here
-  if(parts[0][0]!='$' && !isspace(parts[0][0]))
-    lastfirstword=parts[0];
-
-  //  for_each(parts.begin(),parts.end(),print);
-  tline="";
-  return parseLine(parts,rec);
-}
-
-ZoneParser::~ZoneParser()
-{
-
-}
-
-void ZoneParser::setCallback(callback_t callback)
-{
-  d_callback=callback;
-}
-
-bool ZoneParser::isNumber(const string &s)
-{
-  for(string::const_iterator i=s.begin();
-      i!=s.end();
-      ++i) {
-    if(i+1==s.end())
-      if(*i=='M' || *i=='D' || *i=='H' || *i=='W' || *i=='m' || *i=='d' || *i=='h' || *i=='w') // last character
-       continue;
-    if(!isdigit(*i))
-      return false;
-  }
-  return true;
-}
-
-bool ZoneParser::isType(const string &s)
-{
-  if(isNumber(s))
-    return false;
-
-  if(isClass(s))
-    return false;
-
-  return true;
-}
-
-bool ZoneParser::isClass(const string &s)
-{
-  return (s.size()==2 && (s=="IN" || s=="CH" || s=="HS" || s=="in" || s=="ch" || s=="hs"));
-}
-
-unsigned int ZoneParser::zoneNumber(const string &str)
-{
-  unsigned int val=atoi(str.c_str());
-  char lc=toupper(str[str.length()-1]);
-  if(!isdigit(lc))
-    switch(lc) {
-    case 'H':
-      val*=3600;
-      break;
-    case 'D':
-      val*=3600*24;
-      break;
-    case 'W':
-      val*=3600*24*7;
-      break;
-    case 'M':
-      val*=3600*24*7*4;
-      break;
-    case 'Y': // ? :-)
-      val*=3600*24*365;
-      break;
-    default:
-      throw AhuException("Unable to parse "+d_origin+" time specification '"+str+"' at line "+itoa(d_lineno));
-    }
-  return val;
-
-}
-
-/** this parser handles 10 cases (sigh)
-    1) qname TTL CLASS QTYPE *
-    2) qname CLASS TTL QTYPE *
-    3) qname CLASS QTYPE *
-    4) qname TTL QTYPE *
-    5) qname QTYPE *
-
-    And then everything again with a space first character, which implies 'same as last name'
-*/
-
-void ZoneParser::soaCanonic(string &content)
-{
-  vector<string>parts;
-  stringtok(parts,content," \t");
-  int pos=0;
-
-  // 'ns.naamserver.net. hostmaster.naamserver.net 2001102501 8H 2H 1W 1D'
-  // FIXME: what about 'ns hostmaster.naamserver.net 2001102501 8H 2H 1W 1D'?
-
-  string newcontent;
-  for(vector<string>::const_iterator i=parts.begin();i!=parts.end();++i,++pos) {
-    if(pos<3) {
-      if(pos)
-       newcontent.append(1,' ');
-      newcontent.append( canonic( *i ) );
-    }
-    else {
-      unsigned int val=zoneNumber(*i);
-
-      newcontent.append(1,' ');
-      newcontent.append(itoa(val));
-    }
-  }
-  content=newcontent;
-}
-
-string ZoneParser::expandWord(const string &line, int value)
-{
-  string newline;
-  bool escape=false;
-  for(string::const_iterator i=line.begin();i!=line.end();++i) {
-    if(*i=='\\')
-      escape=true;
-    else{
-      if(!escape && *i=='$') {
-       if(i+2<line.end() && *(i+1)=='{') { // shit
-         string::const_iterator k=(i+=2);
-         while(k++!=line.end() && *k!='}')
-           ;
-         if(k==line.end())
-           throw AhuException("Malformed $GENERATE statement");
-
-         string spec;
-         
-         //copy(i,k,back_inserter(spec));
-    for ( string::const_iterator a = i; a != k; ++a )
-      spec += *a;
-
-         vector<string> partjes;
-         stringtok(partjes,spec,",");
-         if(partjes.empty())
-           throw AhuException("Malformed $GENERATE statement: '"+spec+"'");
-         
-         value+=atoi(partjes[0].c_str());
-         int width=0;
-         char radix='d';
-         if(partjes.size()>=2)
-           width=atoi(partjes[1].c_str());
-         if(partjes.size()>=3)
-           radix=partjes[2][0];
-
-         char tmp[20];
-         string format;
-         format="%0";
-         format+=itoa(width);
-         format.append(1,radix);
-         
-         snprintf(tmp,19,format.c_str(),value);
-
-         newline.append(tmp);
-         i=k;
-       }
-       else
-         newline.append(itoa(value));
-      }
-      else
-       newline.append(1,*i);
-      escape=false;
-    }
-  }
-  return newline;
-}
-
-string ZoneParser::canonic(const string& dom)
-{
-  if(dom[dom.size()-1]!='.')
-    return dom;
-
-  return dom.substr(0,dom.size()-1);
-
-}
-
-
-bool ZoneParser::parseLine(const vector<string>&words, vector<Record>&rec)
-{
-  int cpos=0;
-  if(!words.size())
-    return false;
-
-  if(words[0][0]=='$')
-    {
-    if(!Utility::strcasecmp(words[0].c_str(),"$ORIGIN") && words.size()>1) {
-       d_origin=canonic(words[1]);
-      }
-      else if(!Utility::strcasecmp(words[0].c_str(),"$TTL") && words.size()>1) {
-       d_ttl=zoneNumber(words[1]);
-      }
-      else if(!Utility::strcasecmp(words[0].c_str(),"$GENERATE") && words.size()>1) {
-       // $GENERATE 1-127 $ CNAME $.0
-       string range=words[1];  // 1-127 means 1...127 (including 127). 1-127/2 is 1..3..5..
-       vector<string>parts;
-       stringtok(parts,range,"-/");
-       if(parts.size()<2 || parts.size()>3)
-         throw AhuException("Malformed $GENERATE on line "+itoa(d_lineno)+" of "+d_filename);
-
-       int start, stop, step=1;
-       start=atoi(parts[0].c_str());
-       stop=atoi(parts[1].c_str());
-       if(parts.size()==3)
-         step=atoi(parts[2].c_str());
-       vector<string>newwords;
-
-       for(int i=start;i<=stop;++i) {
-         newwords.clear();
-         for(unsigned int j=2;j<words.size();++j) {
-           newwords.push_back(expandWord(words[j],i));
-         }
-         parseLine(newwords, rec);
-       }
-       return true;
-      }
-      else {
-       throw AhuException("Unhandled command '"+words[0]+"' on line "+itoa(d_lineno)+" of '"+d_filename+"'");
-      }
-      
-      return false;
-
-    }
-  if(words.size()<3) {
-    if(words.size()==1 && words[0]==";")
-      return false;
-    throw AhuException("Short line "+itoa(d_lineno)+" in '"+d_filename+"': "+itoa(words.size())+ " words. Probably due to repeated record without domainname");
-  }
-
-  string qname=words[0];
-  string qclass="IN";
-  int ttl=d_ttl;
-  string qtype="NONE";
-  if(isNumber(words[1])) // 1 || 4
-    {
-      ttl=zoneNumber(words[1]);
-      if(isClass(words[2])) 
-       {
-//       cout<<1<<endl;
-         qclass=words[2];
-         qtype=words[3];
-         cpos=4;
-         // 1
-       }
-      else
-       {
-//       cout<<4<<endl;
-
-         qtype=words[2];
-         cpos=3;
-         // 4
-       }
-    }
-  else /* 2 || 3 || 5 */
-    {
-      if(!isClass(words[1]))
-       {
-
-         qtype=words[1];
-         cpos=2;
-//       cout<<5<<endl;
-         // 5
-       }
-      else // 2 || 3
-       {
-         qclass=words[1];
-         if(isNumber(words[2])) 
-           {
-             ttl=zoneNumber(words[2]);
-             qtype=words[3];
-//           cout<<2<<endl;
-             cpos=4;
-             // 2
-           }
-         else if(isType(words[2]))
-           {
-             qtype=words[2];
-//           cout<<4<<endl;
-             cpos=3;
-             // 4
-           }
-       }
-      
-    }
-  if(!cpos) {
-    throw AhuException("Funky parse case on line  "+itoa(d_lineno));
-  }
-
-  if(qname=="@")
-    qname=d_origin;
-  else
-    if(qname[qname.size()-1]!='.')
-      qname+="."+d_origin;
-
-
-  //  cerr<<qname<<", "<<qclass<<", "<<qtype<<", "<<ttl<<", rest from field "<<cpos<<endl;
-         
-  int left=words.size()-cpos;
-  string content;
-
-  if((qtype=="MX" && left==2) || (qtype=="SRV" && left==4)){
-    int prio=atoi(words[cpos++].c_str());left--;
-    content=words[cpos++];left--;
-    
-    while(left--)
-      content+=" "+words[cpos++];
-    
-    if(content=="@")
-      content=d_origin;
-    else
-      if(content[content.size()-1]!='.')
-       content+="."+d_origin;
-    
-    fillRec(qname, qtype, content, ttl, prio,rec);
-    return true;
-  }
-  else if(left) {
-    content=words[cpos++];left--;
-    
-    while(left--)
-      content+=" "+words[cpos++];
-    
-    if(qtype=="MX" || qtype=="CNAME" || qtype=="NS") {
-      if(content=="@")
-       content=d_origin;
-      else
-       if(content[content.size()-1]!='.')
-         content+="."+d_origin;
-    }
-    if(qtype=="SOA")
-      soaCanonic(content);
-    if(qtype=="TXT" && content.size() > 2) {  // strip quotes from TXT
-      if(content[0]=='"')
-       content=content.substr(1);
-      if(content[content.size()-1]=='"')
-       content.resize(content.size()-1);
-    }
-      
-    fillRec(qname, qtype, content,ttl, 0, rec);
-    return true;
-  }
-  else {
-    throw AhuException("No content on line  "+itoa(d_lineno));
-  }
-  return false;
-}
-
-