]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/zone2json.cc
Merge pull request #5523 from rubenk/fix-typos-in-logmessage
[thirdparty/pdns.git] / pdns / zone2json.cc
CommitLineData
ee681377 1/*
6edbf68a
PL
2 * This file is part of PowerDNS or dnsdist.
3 * Copyright -- PowerDNS.COM B.V. and its contributors
4 *
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.
8 *
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.
12 *
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.
17 *
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.
21 */
22
ee681377
PD
23/* accepts a named.conf or a zone as parameter and outputs heaps of sql */
24
870a0fe4
AT
25#ifdef HAVE_CONFIG_H
26#include "config.h"
27#endif
ee681377
PD
28#include <unistd.h>
29#include <string>
30#include <map>
31
32#include <iostream>
33#include <stdio.h>
34#include "namespaces.hh"
35
36#include "dns.hh"
37#include "arguments.hh"
7c0cb150 38#include "bindparserclasses.hh"
ee681377
PD
39#include "statbag.hh"
40#include "misc.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>
46#include <sys/stat.h>
47#include <unistd.h>
fa8fd4d2 48
bf6dc747 49#include "json11.hpp"
ee681377 50
bf6dc747 51using namespace json11;
ee681377
PD
52
53StatBag S;
ee681377
PD
54static int g_numRecords;
55
bf6dc747 56static Json::object emitRecord(const string& zoneName, const DNSName &DNSqname, const string &qtype, const string &ocontent, int ttl)
ee681377 57{
b9bafae0 58 int prio=0;
ee681377
PD
59 string retval;
60 g_numRecords++;
61 string content(ocontent);
62 if(qtype == "MX" || qtype == "SRV") {
335da0ba 63 prio=pdns_stou(content);
ee681377
PD
64
65 string::size_type pos = content.find_first_not_of("0123456789");
66 if(pos != string::npos)
67 boost::erase_head(content, pos);
68 trim_left(content);
69 }
70
bf6dc747 71 Json::object dict;
ee681377 72
39313d8e 73 dict["name"] = DNSqname.toString();
bf6dc747
AT
74 dict["type"] = qtype;
75 dict["ttl"] = ttl;
76 dict["prio"] = prio;
77 dict["content"] = content;
ee681377 78
bf6dc747 79 return dict;
ee681377
PD
80}
81
82/* 2 modes of operation, either --named or --zone (the latter needs $ORIGIN)
83 2 further modes: --mysql or --oracle
84*/
85
86ArgvMap &arg()
87{
88 static ArgvMap theArg;
89 return theArg;
90}
91
92
93int main(int argc, char **argv)
5761d098 94try
ee681377
PD
95{
96 vector<string> lines;
97
ee681377 98 reportAllTypes();
ee681377
PD
99#if __GNUC__ >= 3
100 std::ios_base::sync_with_stdio(false);
101#endif
102
103 ::arg().setSwitch("verbose","Verbose comments on operation")="no";
104 ::arg().setSwitch("on-error-resume-next","Continue after errors")="no";
105 ::arg().set("zone","Zonefile to parse")="";
106 ::arg().set("zone-name","Specify an $ORIGIN in case it is not present")="";
107 ::arg().set("named-conf","Bind 8/9 named.conf to parse")="";
108
109 ::arg().set("soa-minimum-ttl","Do not change")="0";
110 ::arg().set("soa-refresh-default","Do not change")="0";
111 ::arg().set("soa-retry-default","Do not change")="0";
112 ::arg().set("soa-expire-default","Do not change")="0";
113
114 ::arg().setCmd("help","Provide a helpful message");
a03a8f0a 115 ::arg().setCmd("version","Print the version");
ee681377
PD
116
117 S.declare("logmessages");
118
119 string namedfile="";
120 string zonefile="";
121
122 ::arg().parse(argc, argv);
a03a8f0a
PL
123
124 if(::arg().mustDo("version")){
125 cerr<<"zone2json "<<VERSION<<endl;
126 exit(0);
127 }
128
ff5ba4f9
WA
129 if(::arg().mustDo("help")) {
130 cout<<"syntax:"<<endl<<endl;
131 cout<<::arg().helpstring()<<endl;
132 exit(0);
133 }
134
135 if(argc<2) {
ee681377
PD
136 cerr<<"syntax:"<<endl<<endl;
137 cerr<<::arg().helpstring()<<endl;
138 exit(1);
139 }
140
141 namedfile=::arg()["named-conf"];
142 zonefile=::arg()["zone"];
143
144 int count=0, num_domainsdone=0;
145
146 if(zonefile.empty()) {
147 BindParser BP;
148 BP.setVerbose(::arg().mustDo("verbose"));
149 BP.parse(namedfile.empty() ? "./named.conf" : namedfile);
150
151 vector<BindDomainInfo> domains=BP.getDomains();
152 struct stat st;
153 for(vector<BindDomainInfo>::iterator i=domains.begin(); i!=domains.end(); ++i) {
154 if(stat(i->filename.c_str(), &st) == 0) {
155 i->d_dev = st.st_dev;
156 i->d_ino = st.st_ino;
157 }
158 }
159
160 sort(domains.begin(), domains.end()); // put stuff in inode order
161
162 int numdomains=domains.size();
163 int tick=numdomains/100;
bf6dc747
AT
164 cout << "[";
165
ee681377
PD
166 for(vector<BindDomainInfo>::const_iterator i=domains.begin();
167 i!=domains.end();
168 ++i)
169 {
170 if(i->type!="master" && i->type!="slave") {
39313d8e 171 cerr<<" Warning! Skipping '"<<i->type<<"' zone '"<<i->name<<"'"<<endl;
ee681377
PD
172 continue;
173 }
174 lines.clear();
175 try {
bf6dc747
AT
176 Json::object obj;
177 Json::array recs;
ee681377
PD
178 ZoneParserTNG zpt(i->filename, i->name, BP.getDirectory());
179 DNSResourceRecord rr;
39313d8e 180 obj["name"] = i->name.toString();
bf6dc747 181
ee681377 182 while(zpt.get(rr))
39313d8e 183 recs.push_back(emitRecord(i->name.toString(), rr.qname, rr.qtype.getName(), rr.content, rr.ttl));
bf6dc747
AT
184 obj["records"] = recs;
185 Json tmp = obj;
186 cout<<tmp.dump();
187 if(i+1 < domains.end()) cout<<",";
ee681377 188 num_domainsdone++;
bf6dc747 189 }
ee681377
PD
190 catch(std::exception &ae) {
191 if(!::arg().mustDo("on-error-resume-next"))
192 throw;
193 else
194 cerr<<endl<<ae.what()<<endl;
195 }
3f81d239 196 catch(PDNSException &ae) {
ee681377
PD
197 if(!::arg().mustDo("on-error-resume-next"))
198 throw;
199 else
200 cerr<<ae.reason<<endl;
201 }
202 if(!tick || !((count++)%tick))
203 cerr<<"\r"<<count*100/numdomains<<"% done ("<<i->filename<<")\033\133\113";
204 }
bf6dc747 205 cout << "]" << endl;
ee681377
PD
206 cerr<<"\r100% done\033\133\113"<<endl;
207 }
208 else {
b873e23a 209 ZoneParserTNG zpt(zonefile, DNSName(::arg()["zone-name"]));
ee681377 210 DNSResourceRecord rr;
bf6dc747
AT
211 string zname;
212 Json::object obj;
213 Json::array records;
214
215 obj["name"] = ::arg()["zone-name"];
216
ee681377 217 while(zpt.get(rr))
b873e23a 218 records.push_back(emitRecord(::arg()["zone-name"], rr.qname, rr.qtype.getName(), rr.content, rr.ttl));
bf6dc747
AT
219 obj["records"] = records;
220
221 Json tmp = obj;
222
223 cout<<tmp.dump()<<endl;
224
ee681377
PD
225 num_domainsdone=1;
226 }
227 cerr<<num_domainsdone<<" domains were fully parsed, containing "<<g_numRecords<<" records\n";
5761d098
CH
228
229 return 0;
ee681377 230
5761d098
CH
231}
232catch(PDNSException &ae) {
233 cerr<<"\nFatal error: "<<ae.reason<<endl;
234 return 1;
235}
236catch(std::exception &e) {
237 cerr<<"\ndied because of STL error: "<<e.what()<<endl;
238 return 1;
239}
240catch(...) {
241 cerr<<"\ndied because of unknown exception"<<endl;
ee681377 242 return 1;
ee681377 243}