]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/dynloader.cc
rec: mention rust compiler in compiling docs
[thirdparty/pdns.git] / pdns / dynloader.cc
1 /*
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 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25 #include <iostream>
26 #include <cstdio>
27 #include <cstring>
28 #include <cstdlib>
29 #include <unistd.h>
30 #include <climits>
31 #include <string>
32 #include <map>
33 #include <sys/mman.h>
34 #include <fcntl.h>
35 #include <sys/types.h>
36
37
38 #include <sys/stat.h>
39 #include "pdnsexception.hh"
40 #include "misc.hh"
41 #include "dynmessenger.hh"
42 #include "arguments.hh"
43 #include "statbag.hh"
44 #include "misc.hh"
45 #include "namespaces.hh"
46
47 ArgvMap &arg()
48 {
49 static ArgvMap arg;
50 return arg;
51 }
52
53 StatBag S;
54
55 int main(int argc, char **argv)
56 {
57 string programname="pdns";
58
59 ::arg().set("config-dir","Location of configuration directory (pdns.conf)")=SYSCONFDIR;
60 ::arg().set("socket-dir",string("Where the controlsocket will live, ")+LOCALSTATEDIR+"/pdns when unset and not chrooted" )="";
61 ::arg().set("remote-address","Remote address to query");
62 ::arg().set("remote-port","Remote port to query")="53000";
63 ::arg().set("secret","Secret needed to connect to remote PowerDNS");
64
65 ::arg().set("config-name","Name of this virtual configuration - will rename the binary image")="";
66 ::arg().setCmd("no-config","Don't parse configuration file");
67 ::arg().set("chroot","")="";
68 ::arg().setCmd("help","Provide a helpful message");
69 ::arg().laxParse(argc,argv);
70
71 if(::arg().mustDo("help")) {
72 cout<<"syntax:"<<endl<<endl;
73 cout<<::arg().helpstring(::arg()["help"])<<endl;
74 cout<<"In addition, 'pdns_control help' can be used to retrieve a list\nof available commands from PowerDNS"<<endl;
75 exit(0);
76 }
77
78 const vector<string>commands=::arg().getCommands();
79
80 if(commands.empty()) {
81 cerr<<"No command passed"<<endl;
82 return 0;
83 }
84
85 if(::arg()["config-name"]!="")
86 programname+="-"+::arg()["config-name"];
87
88 string configname=::arg()["config-dir"]+"/"+programname+".conf";
89 cleanSlashes(configname);
90
91 if(!::arg().mustDo("no-config")) {
92 ::arg().laxFile(configname.c_str());
93 ::arg().laxParse(argc,argv); // reparse so the commandline still wins
94 }
95
96 string socketname=::arg()["socket-dir"];
97 if (::arg()["socket-dir"].empty()) {
98 if (::arg()["chroot"].empty())
99 socketname = std::string(LOCALSTATEDIR) + "/pdns";
100 else
101 socketname = ::arg()["chroot"] + "/";
102 } else if (!::arg()["socket-dir"].empty() && !::arg()["chroot"].empty()) {
103 socketname = ::arg()["chroot"] + ::arg()["socket-dir"];
104 }
105
106 socketname += "/" + programname + ".controlsocket";
107 cleanSlashes(socketname);
108
109 try {
110 string command = commands[0];
111 shared_ptr<DynMessenger> D;
112 if(::arg()["remote-address"].empty())
113 D = std::make_shared<DynMessenger>(socketname);
114 else {
115 uint16_t port;
116 try {
117 pdns::checked_stoi_into(port, ::arg()["remote-port"]);
118 }
119 catch (...) {
120 cerr << "Unable to convert '" << ::arg()["remote-port"] << "' to a port number for connecting to remote PowerDNS\n";
121 exit(99);
122 }
123
124 D = std::make_shared<DynMessenger>(ComboAddress(::arg()["remote-address"], port), ::arg()["secret"]);
125 }
126
127 string message;
128 for(vector<string>::const_iterator i=commands.begin();i!=commands.end();++i) {
129 if(i!=commands.begin())
130 message+=" ";
131 message+=*i;
132 }
133
134 if(command=="show") {
135 message="SHOW ";
136 for(unsigned int n=1;n<commands.size();n++) {
137 message+=commands[n];
138 message+=" ";
139 }
140 }
141 else if(command=="list") {
142 message="SHOW *";
143 command="show";
144 }
145 else if(command=="quit" || command=="QUIT") {
146 message="QUIT";
147 }
148 else if(command=="status" || command=="STATUS") {
149 message="STATUS";
150 }
151 else if(command=="version" || command=="VERSION") {
152 message="VERSION";
153 }
154
155
156 if(D->send(message)<0) {
157 cerr<<"Error sending command"<<endl;
158 return 1;
159 }
160
161 string resp=D->receive();
162 if(resp.compare(0, 7, "Unknown") == 0) {
163 cerr<<resp<<endl;
164 return 1;
165 }
166
167 cout<<resp<<endl;
168 }
169 catch(TimeoutException &ae) {
170 cerr<<"Timeout error: "<<ae.reason<<endl;
171 return 2;
172 }
173 catch(PDNSException &ae) {
174 cerr<<"Fatal error: "<<ae.reason<<endl;
175 return 1;
176 }
177 catch(const std::runtime_error& e) {
178 cerr<<"Runtime error: "<<e.what()<<endl;
179 return 2;
180 }
181 return 0;
182 }