]>
git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/zone2json.cc
2 * This file is part of PowerDNS or dnsdist.
3 * Copyright -- PowerDNS.COM B.V. and its contributors
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * In addition, for the avoidance of any doubt, permission is granted to
10 * link this program with OpenSSL and to (re)distribute the binaries
11 * produced as the result of such linking.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 /* accepts a named.conf or a zone as parameter and outputs heaps of sql */
34 #include "namespaces.hh"
37 #include "arguments.hh"
38 #include "bindparserclasses.hh"
41 #include "dnspacket.hh"
42 #include "zoneparser-tng.hh"
43 #include "dnsrecords.hh"
44 #include <boost/algorithm/string.hpp>
45 #include <sys/types.h>
51 using namespace json11
;
54 static int g_numRecords
;
56 static Json::object
emitRecord(const string
& zoneName
, const DNSName
&DNSqname
, const string
&qtype
, const string
&ocontent
, int ttl
)
61 string
content(ocontent
);
62 if(qtype
== "MX" || qtype
== "SRV") {
63 prio
=pdns_stou(content
);
65 string::size_type pos
= content
.find_first_not_of("0123456789");
66 if(pos
!= string::npos
)
67 boost::erase_head(content
, pos
);
73 dict
["name"] = DNSqname
.toString();
77 dict
["content"] = content
;
82 /* 2 modes of operation, either --named or --zone (the latter needs $ORIGIN)
83 2 further modes: --mysql or --oracle
88 static ArgvMap theArg
;
93 int main(int argc
, char **argv
)
99 std::ios_base::sync_with_stdio(false);
101 ::arg().setSwitch("verbose","Verbose comments on operation")="no";
102 ::arg().setSwitch("on-error-resume-next","Continue after errors")="no";
103 ::arg().set("zone","Zonefile to parse")="";
104 ::arg().set("zone-name","Specify an $ORIGIN in case it is not present")="";
105 ::arg().set("named-conf","Bind 8/9 named.conf to parse")="";
107 ::arg().set("soa-minimum-ttl","Do not change")="0";
108 ::arg().set("soa-refresh-default","Do not change")="0";
109 ::arg().set("soa-retry-default","Do not change")="0";
110 ::arg().set("soa-expire-default","Do not change")="0";
112 ::arg().setCmd("help","Provide a helpful message");
113 ::arg().setCmd("version","Print the version");
115 S
.declare("logmessages");
120 ::arg().parse(argc
, argv
);
122 if(::arg().mustDo("version")){
123 cerr
<<"zone2json "<<VERSION
<<endl
;
127 if(::arg().mustDo("help")) {
128 cout
<<"syntax:"<<endl
<<endl
;
129 cout
<<::arg().helpstring()<<endl
;
134 cerr
<<"syntax:"<<endl
<<endl
;
135 cerr
<<::arg().helpstring()<<endl
;
139 namedfile
=::arg()["named-conf"];
140 zonefile
=::arg()["zone"];
142 int count
=0, num_domainsdone
=0;
144 if(zonefile
.empty()) {
146 BP
.setVerbose(::arg().mustDo("verbose"));
147 BP
.parse(namedfile
.empty() ? "./named.conf" : namedfile
);
149 vector
<BindDomainInfo
> domains
=BP
.getDomains();
151 for(vector
<BindDomainInfo
>::iterator i
=domains
.begin(); i
!=domains
.end(); ++i
) {
152 if(stat(i
->filename
.c_str(), &st
) == 0) {
153 i
->d_dev
= st
.st_dev
;
154 i
->d_ino
= st
.st_ino
;
158 sort(domains
.begin(), domains
.end()); // put stuff in inode order
160 int numdomains
=domains
.size();
161 int tick
=numdomains
/100;
164 for(vector
<BindDomainInfo
>::const_iterator i
=domains
.begin();
168 if(i
->type
!="master" && i
->type
!="slave") {
169 cerr
<<" Warning! Skipping '"<<i
->type
<<"' zone '"<<i
->name
<<"'"<<endl
;
176 ZoneParserTNG
zpt(i
->filename
, i
->name
, BP
.getDirectory());
177 DNSResourceRecord rr
;
178 obj
["name"] = i
->name
.toString();
181 recs
.push_back(emitRecord(i
->name
.toString(), rr
.qname
, rr
.qtype
.getName(), rr
.content
, rr
.ttl
));
182 obj
["records"] = recs
;
185 if(i
+1 < domains
.end()) cout
<<",";
188 catch(std::exception
&ae
) {
189 if(!::arg().mustDo("on-error-resume-next"))
192 cerr
<<endl
<<ae
.what()<<endl
;
194 catch(PDNSException
&ae
) {
195 if(!::arg().mustDo("on-error-resume-next"))
198 cerr
<<ae
.reason
<<endl
;
200 if(!tick
|| !((count
++)%tick
))
201 cerr
<<"\r"<<count
*100/numdomains
<<"% done ("<<i
->filename
<<")\033\133\113";
204 cerr
<<"\r100% done\033\133\113"<<endl
;
207 ZoneParserTNG
zpt(zonefile
, DNSName(::arg()["zone-name"]));
208 DNSResourceRecord rr
;
213 obj
["name"] = ::arg()["zone-name"];
216 records
.push_back(emitRecord(::arg()["zone-name"], rr
.qname
, rr
.qtype
.getName(), rr
.content
, rr
.ttl
));
217 obj
["records"] = records
;
221 cout
<<tmp
.dump()<<endl
;
225 cerr
<<num_domainsdone
<<" domains were fully parsed, containing "<<g_numRecords
<<" records\n";
230 catch(PDNSException
&ae
) {
231 cerr
<<"\nFatal error: "<<ae
.reason
<<endl
;
234 catch(std::exception
&e
) {
235 cerr
<<"\ndied because of STL error: "<<e
.what()<<endl
;
239 cerr
<<"\ndied because of unknown exception"<<endl
;