]>
Commit | Line | Data |
---|---|---|
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 | 51 | using namespace json11; |
ee681377 PD |
52 | |
53 | StatBag S; | |
ee681377 PD |
54 | static int g_numRecords; |
55 | ||
bf6dc747 | 56 | static 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 | ||
86 | ArgvMap &arg() | |
87 | { | |
88 | static ArgvMap theArg; | |
89 | return theArg; | |
90 | } | |
91 | ||
92 | ||
93 | int main(int argc, char **argv) | |
5761d098 | 94 | try |
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 | } |
232 | catch(PDNSException &ae) { | |
233 | cerr<<"\nFatal error: "<<ae.reason<<endl; | |
234 | return 1; | |
235 | } | |
236 | catch(std::exception &e) { | |
237 | cerr<<"\ndied because of STL error: "<<e.what()<<endl; | |
238 | return 1; | |
239 | } | |
240 | catch(...) { | |
241 | cerr<<"\ndied because of unknown exception"<<endl; | |
ee681377 | 242 | return 1; |
ee681377 | 243 | } |