]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/arguments.cc
lots
[thirdparty/pdns.git] / pdns / arguments.cc
CommitLineData
12c86877
BH
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*/
bd11bd1d 19#include "utility.hh"
12c86877
BH
20#include <fstream>
21#include <iostream>
22#include "logger.hh"
23#include "arguments.hh"
24#include "misc.hh"
25
26#define L theL("pdns")
27extern Logger &theL(const string &prefix);
28
29const ArgvMap::param_t::const_iterator ArgvMap::begin()
30{
31 return params.begin();
32}
33
34const ArgvMap::param_t::const_iterator ArgvMap::end()
35{
36 return params.end();
37}
38
39string & ArgvMap::set(const string &var)
40{
41 return params[var];
42}
43
44bool ArgvMap::mustDo(const string &var)
bd11bd1d 45{
12c86877
BH
46 return ((*this)[var]!="no") && ((*this)[var]!="off");
47}
48
49vector<string>ArgvMap::list()
50{
51 vector<string> ret;
52 for(map<string,string>::const_iterator i=params.begin();i!=params.end();++i)
53 ret.push_back(i->first);
54 return ret;
55}
56
57string ArgvMap::getHelp(const string &item)
58{
59 return helpmap[item];
60}
61
62string & ArgvMap::set(const string &var, const string &help)
63{
64 helpmap[var]=help;
65 d_typeMap[var]="Parameter";
66 return set(var);
67}
68
69void ArgvMap::setCmd(const string &var, const string &help)
70{
71 helpmap[var]=help;
72 d_typeMap[var]="Command";
73 set(var)="no";
74}
75
76string & ArgvMap::setSwitch(const string &var, const string &help)
77{
78 helpmap[var]=help;
79 d_typeMap[var]="Switch";
80 return set(var);
81}
82
83
12c86877
BH
84bool ArgvMap::contains(const string &var, const string &val)
85{
f4137d84
BH
86 vector<string> parts;
87 vector<string>::const_iterator i;
12c86877 88
12c86877 89
f4137d84
BH
90 stringtok( parts, params[var], ", \t" );
91 for( i = parts.begin(); i != parts.end(); i++ )
12c86877 92 {
f4137d84
BH
93 if( *i == val ) {
94 return true;
95 }
12c86877 96 }
f4137d84
BH
97
98 return false;
12c86877
BH
99}
100
101
102string ArgvMap::helpstring(string prefix)
103{
104 if(prefix=="no")
105 prefix="";
106
107 string help;
108
109 for(map<string,string>::const_iterator i=helpmap.begin();
110 i!=helpmap.end();
111 i++)
112 {
113 if(!prefix.empty() && i->first.find(prefix)) // only print items with prefix
114 continue;
115
116 help+=" --";
117 help+=i->first;
118
119 string type=d_typeMap[i->first];
120
121 if(type=="Parameter")
122 help+="=...";
123 else if(type=="Switch")
124 {
125 help+=" | --"+i->first+"=yes";
126 help+=" | --"+i->first+"=no";
127 }
128
129
130 help+="\n\t";
131 help+=i->second;
132 help+="\n";
133
134 }
135 return help;
136}
137
138string ArgvMap::configstring()
139{
140 string help;
141
142 help="# Autogenerated configuration file template\n";
143 for(map<string,string>::const_iterator i=helpmap.begin();
144 i!=helpmap.end();
145 i++)
146 {
147 if(d_typeMap[i->first]=="Command")
148 continue;
149
150 help+="#################################\n";
151 help+="# ";
152 help+=i->first;
153 help+="\t";
154 help+=i->second;
155 help+="\n#\n";
156 help+="# "+i->first+"="+params[i->first]+"\n\n";
157
158 }
159 return help;
160}
161
162
163const string & ArgvMap::operator[](const string &arg)
164{
165 if(!parmIsset(arg))
166 throw ArgException(string("Undefined but needed argument: '")+arg+"'");
167
168
169 return params[arg];
170}
171
172int ArgvMap::asNum(const string &arg)
173{
174 if(!parmIsset(arg))
175 throw ArgException(string("Undefined but needed argument: '")+arg+"'");
176
177 return atoi(params[arg].c_str());
178}
179
180double ArgvMap::asDouble(const string &arg)
181{
182 if(!parmIsset(arg))
183 throw ArgException(string("Undefined but needed argument: '")+arg+"'");
184
185 return atof(params[arg].c_str());
186}
187
188ArgvMap::ArgvMap()
189{
190
191}
192
193bool ArgvMap::parmIsset(const string &var)
194{
195 return (params.find(var)!=params.end());
196}
197
198void ArgvMap::parseOne(const string &arg, const string &parseOnly, bool lax)
199{
200 string var, val;
201 unsigned int pos;
202
203 if(!arg.find("--") &&(pos=arg.find("="))!=string::npos) // this is a --port=25 case
204 {
205 var=arg.substr(2,pos-2);
206 val=arg.substr(pos+1);
207 }
208 else if(!arg.find("--") && (arg.find("=")==string::npos)) // this is a --daemon case
209 {
210 var=arg.substr(2);
211 val="";
212 }
213 else if(arg[0]=='-')
214 {
215 var=arg.substr(1);
216 val="";
217 }
218 else { // command
219 d_cmds.push_back(arg);
220 }
221
222 if(var!="" && (parseOnly.empty() || var==parseOnly)) {
bd11bd1d
BH
223
224 pos=val.find_first_not_of(" \t"); // strip leading whitespace
225 if(pos && pos!=string::npos)
226 val=val.substr(pos);
227
12c86877
BH
228 if(parmIsset(var))
229 params[var]=val;
230 else
231 if(!lax)
232 throw ArgException("Trying to set unexisting parameter '"+var+"'");
233 }
234}
235
236const vector<string>&ArgvMap::getCommands()
237{
238 return d_cmds;
239}
240
241void ArgvMap::parse(int &argc, char **argv, bool lax)
242{
243 for(int n=1;n<argc;n++) {
244 parseOne(argv[n],"",lax);
245 }
246}
247
248void ArgvMap::preParse(int &argc, char **argv, const string &arg)
249{
250 for(int n=1;n<argc;n++) {
251 string varval=argv[n];
252 if(!varval.find("--"+arg))
253 parseOne(argv[n]);
254 }
255}
256
257bool ArgvMap::preParseFile(const char *fname, const string &arg)
258{
259 ifstream f(fname);
260 if(!f)
261 return false;
262
263 string line;
264 string pline;
265 unsigned int pos;
266
267 while(getline(f,pline)) {
268 chomp(pline,"\t\r\n");
269 if(pline[pline.size()-1]=='\\') {
270 line+=pline.substr(0,pline.length()-1);
271 continue;
272 }
273 else
274 line+=pline;
275
276
277 // strip everything after a #
278 if((pos=line.find("#"))!=string::npos)
279 line=line.substr(0,pos);
280
281 // strip trailing spaces
282 chomp(line," ");
283
284 // strip leading spaces
285 if((pos=line.find_first_not_of(" \t\r\n"))!=string::npos)
286 line=line.substr(pos);
287
288 // gpgsql-basic-query=sdfsdfs dfsdfsdf sdfsdfsfd
289
290 parseOne(string("--")+line, arg);
291 line="";
292 }
293
294 return true;
295}
296
297
298bool ArgvMap::file(const char *fname, bool lax)
299{
300 ifstream f(fname);
301 if(!f) {
302 // L<<"Tried file '"<<fname<<"' for configuration"<<endl;
303 return false;
304 }
305 if(!lax)
306 L<<"Opened file '"<<fname<<"' for configuration"<<endl;
307
308 string line;
309 string pline;
310 unsigned int pos;
311 while(getline(f,pline)) {
312 chomp(pline,"\t\r\n");
313
314 if(pline[pline.size()-1]=='\\') {
315 line+=pline.substr(0,pline.length()-1);
316
317 continue;
318 }
319 else
320 line+=pline;
321
322 // strip everything after a #
323 if((pos=line.find("#"))!=string::npos)
324 line=line.substr(0,pos);
325
326 // strip trailing spaces
327 chomp(line," ");
328
329
330 // strip leading spaces
331 if((pos=line.find_first_not_of(" \t\r\n"))!=string::npos)
332 line=line.substr(pos);
333
334
335 parseOne(string("--")+line,"",lax);
336 line="";
337 }
338
339 return true;
340}