root/trunk/pdns/pdns/backends/bind/zone2sql.cc @ 36

Revision 36, 7.9 KB (checked in by ahu, 10 years ago)

add unknown errors

  • Property svn:eol-style set to native
  • Property svn:keywords set to author date id revision
Line 
1/*
2    PowerDNS Versatile Database Driven Nameserver
3    Copyright (C) 2002  PowerDNS.COM BV
4
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2 of the License, or
8    (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software
17    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18*/
19/* accepts a named.conf as parameter and outputs heaps of sql */
20
21// $Id: zone2sql.cc,v 1.2 2002/11/29 22:50:56 ahu Exp $
22#ifdef WIN32
23# pragma warning ( disable: 4786 )
24# include <unistd.h>
25#endif // WIN32
26
27#include <string>
28#include <map>
29
30#include <iostream>
31#include <stdio.h>
32
33using namespace std;
34
35#include "dns.hh"
36#include "arguments.hh"
37#include "zoneparser.hh"
38#include "bindparser.hh"
39#include "statbag.hh"
40#include "misc.hh"
41
42StatBag S;
43
44string sqlstr(const string &str)
45{
46  if(str.find("\'")!=string::npos)
47    throw 0;
48
49  string ret="\'";
50  ret+=str;
51  ret+="\'";
52  return ret;
53}
54
55static int dirty_hack_num;
56
57enum dbmode_t {MYSQL=0,ORACLE=1,BARE=2,POSTGRES=3};
58dbmode_t mode;
59bool g_intransaction;
60
61static int num_records;
62static string lastsoa_qname;
63static void callback(const string &domain, const string &qtype, const string &content, int ttl, int prio)
64{
65  static int lastsoa_domain_id=-1;
66
67  num_records++;
68
69  if(qtype=="SOA") {
70    if(dirty_hack_num==lastsoa_domain_id && lastsoa_qname!=domain) {
71      dirty_hack_num++;
72      cerr<<"Second SOA in zone, raised domain_id"<<endl;
73      if(mode==POSTGRES || mode==ORACLE) {
74        if(g_intransaction && arg().mustDo("transactions")) {
75          cout<<"COMMIT WORK;"<<endl;
76        }
77        if(arg().mustDo("transactions")) {
78          if(mode==POSTGRES)
79            cout<<"BEGIN TRANSACTION;"<<endl;
80          g_intransaction=1;
81        }
82       
83        if(mode==POSTGRES) {
84          cout<<"insert into domains (name,type) values ("<<sqlstr(domain)<<",'NATIVE');"<<endl;
85        }
86        else if(mode==ORACLE) {
87          cout<<"insert into domains (id,name,type) values (domains_id_sequence.nextval,"<<toLower(sqlstr(domain))<<",'NATIVE');"<<endl;
88        }
89      }
90    }
91    lastsoa_qname=domain;
92  }
93 
94  lastsoa_domain_id=dirty_hack_num;
95
96  if(mode==MYSQL) {
97    cout<<"insert into records (domain_id, name,type,content,ttl,prio) values ("<< dirty_hack_num<<", "<<
98      sqlstr(ZoneParser::canonic(domain))<<", "<<
99      sqlstr(qtype)<<", "<<
100      sqlstr(ZoneParser::canonic(content))<<", "<<ttl<<", "<<prio<<");\n";
101  }
102  if(mode==POSTGRES) {
103    cout<<"insert into records (domain_id, name,type,content,ttl,prio) select id ,"<<
104      sqlstr(toLower(ZoneParser::canonic(domain)))<<", "<<
105      sqlstr(qtype)<<", "<<
106      sqlstr(ZoneParser::canonic(content))<<", "<<ttl<<", "<<prio<< 
107      " from domains where name="<<toLower(sqlstr(lastsoa_qname))<<";\n";
108  }
109  else if(mode==ORACLE) {
110    cout<<"insert into Records (id,ZoneId, name,type,content,TimeToLive,Priority) select RECORDS_ID_SEQUENCE.nextval,id ,"<<
111      sqlstr(toLower(ZoneParser::canonic(domain)))<<", "<<
112      sqlstr(qtype)<<", "<<
113      sqlstr(ZoneParser::canonic(content))<<", "<<ttl<<", "<<prio<< 
114      " from Domains where name="<<toLower(sqlstr(lastsoa_qname))<<";\n";
115  }
116  else if(mode==BARE) {
117    cout<< dirty_hack_num<<"\t"<<
118      sqlstr(ZoneParser::canonic(domain))<<"\t"<<
119      sqlstr(qtype)<<"\t"<<sqlstr(ZoneParser::canonic(content))<<"\t"<<prio<<"\t"<<ttl<<"\n";
120  }
121
122}
123
124
125/* 2 modes of operation, either --named or --zone (the latter needs $ORIGIN)
126   2 further modes: --mysql or --oracle
127   and a parameter: --start-id
128*/
129
130ArgvMap &arg()
131{
132  static ArgvMap theArg;
133  return theArg;
134}
135
136
137int main(int argc, char **argv)
138{
139  try {
140#if __GNUC__ >= 3
141    ios_base::sync_with_stdio(false);
142#endif
143
144    arg().setSwitch("mysql","Output in format suitable for mysqlbackend")="yes";
145    arg().setCmd("gpgsql","Output in format suitable for default gpgsqlbackend");
146    arg().setCmd("gmysql","Output in format suitable for default gmysqlbackend");
147    arg().setCmd("oracle","Output in format suitable for the oraclebackend");
148    arg().setCmd("bare","Output in a bare format, suitable for further parsing");
149    arg().setSwitch("verbose","Verbose comments on operation")="no";
150    arg().setSwitch("slave","Keep BIND slaves as slaves")="no";
151    arg().setSwitch("transactions","If target SQL supports it, use transactions")="no";
152    arg().setSwitch("on-error-resume-next","Continue after errors")="no";
153    arg().set("start-id","Value of first domain-id")="0";
154    arg().set("zone","Zonefile with $ORIGIN to parse")="";
155    arg().set("zone-name","Specify an $ORIGIN in case it is not present")="";
156    arg().set("named-conf","Bind 8 named.conf to parse")="";
157
158    arg().setCmd("help","Provide a helpful message");
159
160    S.declare("logmessages");
161
162    string namedfile="";
163    string zonefile="";
164
165    arg().parse(argc, argv);
166 
167    if(argc<2 || arg().mustDo("help")) {
168      cerr<<"syntax:"<<endl<<endl;
169      cerr<<arg().helpstring()<<endl;
170      exit(1);
171    }
172 
173    if(arg().mustDo("mysql")) 
174      mode=MYSQL;
175    if(arg().mustDo("gpgsql") || arg().mustDo("gmysql"))
176      mode=POSTGRES;
177    if(arg().mustDo("bare"))
178      mode=BARE;
179    if(arg().mustDo("oracle")) {
180      mode=ORACLE;
181      if(!arg().mustDo("transactions"))
182        cout<<"set autocommit on;"<<endl;
183    }
184
185
186    dirty_hack_num=arg().asNum("start-id");
187    namedfile=arg()["named-conf"];
188    zonefile=arg()["zone"];
189
190    int count=0;
191
192    if(zonefile.empty()) {
193      BindParser BP;
194      BP.setVerbose(arg().mustDo("verbose"));
195      BP.parse(namedfile.empty() ? "./named.conf" : namedfile);
196   
197      ZoneParser ZP;
198   
199      const vector<BindDomainInfo> &domains=BP.getDomains();
200
201      int numdomains=domains.size();
202      int tick=numdomains/100;
203      ZP.setDirectory(BP.getDirectory());
204      ZP.setCallback(&callback); 
205   
206      for(vector<BindDomainInfo>::const_iterator i=domains.begin();
207          i!=domains.end();
208          ++i)
209        {
210          try {
211            if(mode==POSTGRES || mode==ORACLE) {
212              if(g_intransaction && arg().mustDo("transactions")) {
213                cout<<"COMMIT WORK;"<<endl;
214              }
215              if(arg().mustDo("transactions")) {
216                if(mode==POSTGRES)
217                  cout<<"BEGIN TRANSACTION;"<<endl;
218                g_intransaction=1;
219              }
220
221              if(mode==POSTGRES) {
222                if(arg().mustDo("slave")) {
223                  if(i->master.empty())
224                    cout<<"insert into domains (name,type) values ("<<sqlstr(i->name)<<",'NATIVE');"<<endl;
225                  else
226                    cout<<"insert into domains (name,type,master) values ("<<sqlstr(i->name)<<",'SLAVE'"<<", '"<<i->master<<"');"<<endl;
227                }
228                else
229                  cout<<"insert into domains (name,type) values ("<<sqlstr(i->name)<<",'NATIVE');"<<endl;
230              }
231              else if(mode==ORACLE) {
232                cout<<"insert into domains (id,name,type) values (domains_id_sequence.nextval,"<<toLower(sqlstr(i->name))<<",'NATIVE');"<<endl;
233              }
234              lastsoa_qname=i->name;
235            }
236            ZP.parse(i->filename,i->name);
237          }
238          catch(AhuException &ae) {
239            if(!arg().mustDo("on-error-resume-next"))
240              throw;
241            else
242              cerr<<ae.reason<<endl;
243          }
244
245          dirty_hack_num++;
246          if(!tick || !((count++)%tick))
247            cerr<<"\r"<<count*100/numdomains<<"% done ("<<i->filename<<")\033\133\113";
248        }
249      cerr<<"\r100% done\033\133\113"<<endl;
250    }
251    else {
252      ZoneParser ZP;
253      ZP.setDirectory(".");
254      ZP.setCallback(&callback); 
255      ZP.parse(zonefile,arg()["zone-name"]);
256      dirty_hack_num++;
257    }
258    cerr<<"Parsed "<<num_records<<" records"<<endl;
259   
260  }
261  catch(AhuException &ae) {
262    cerr<<"Fatal error: "<<ae.reason<<endl;
263    return 0;
264  }
265  catch(...) {
266    cerr<<"An unknown error occured"<<endl;
267    return 0;
268  }
269 
270  if((mode==POSTGRES || mode==ORACLE) && arg().mustDo("transactions") && g_intransaction)
271    cout<<"COMMIT WORK;"<<endl;
272  return 1;
273
274}
Note: See TracBrowser for help on using the browser.