]>
Commit | Line | Data |
---|---|---|
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") | |
27 | extern Logger &theL(const string &prefix); | |
28 | ||
29 | const ArgvMap::param_t::const_iterator ArgvMap::begin() | |
30 | { | |
31 | return params.begin(); | |
32 | } | |
33 | ||
34 | const ArgvMap::param_t::const_iterator ArgvMap::end() | |
35 | { | |
36 | return params.end(); | |
37 | } | |
38 | ||
39 | string & ArgvMap::set(const string &var) | |
40 | { | |
41 | return params[var]; | |
42 | } | |
43 | ||
44 | bool ArgvMap::mustDo(const string &var) | |
bd11bd1d | 45 | { |
12c86877 BH |
46 | return ((*this)[var]!="no") && ((*this)[var]!="off"); |
47 | } | |
48 | ||
49 | vector<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 | ||
57 | string ArgvMap::getHelp(const string &item) | |
58 | { | |
59 | return helpmap[item]; | |
60 | } | |
61 | ||
62 | string & ArgvMap::set(const string &var, const string &help) | |
63 | { | |
64 | helpmap[var]=help; | |
65 | d_typeMap[var]="Parameter"; | |
66 | return set(var); | |
67 | } | |
68 | ||
69 | void ArgvMap::setCmd(const string &var, const string &help) | |
70 | { | |
71 | helpmap[var]=help; | |
72 | d_typeMap[var]="Command"; | |
73 | set(var)="no"; | |
74 | } | |
75 | ||
76 | string & 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 |
84 | bool 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 | ||
102 | string 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 | ||
138 | string 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 | ||
163 | const 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 | ||
172 | int 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 | ||
180 | double 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 | ||
188 | ArgvMap::ArgvMap() | |
189 | { | |
190 | ||
191 | } | |
192 | ||
193 | bool ArgvMap::parmIsset(const string &var) | |
194 | { | |
195 | return (params.find(var)!=params.end()); | |
196 | } | |
197 | ||
198 | void 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 | ||
236 | const vector<string>&ArgvMap::getCommands() | |
237 | { | |
238 | return d_cmds; | |
239 | } | |
240 | ||
241 | void 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 | ||
248 | void 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 | ||
257 | bool 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 | ||
298 | bool 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 | } |