Changed some loglevels and ignore invalid service config rather than exit.
[bpdyndnsd] / src / config.cpp
CommitLineData
5c460c94
BS
1/** @file
2 * @brief Config class implementation. This class represents the actual configuration.
3 *
4 *
5 *
6 * @copyright Intra2net AG
7 * @license GPLv2
8*/
4545a371 9
5c460c94 10#include "config.h"
fc87cdbb 11
089a7152
BS
12#include "service_dhs.h"
13#include "service_ods.h"
14#include "service_dyndns.h"
15#include "service_dyns.h"
16#include "service_easydns.h"
17#include "service_tzo.h"
18#include "service_zoneedit.h"
a78b44b5 19#include "service_gnudip.h"
88a594e8
BS
20
21#include <time.h>
22#include <iostream>
23#include <fstream>
24
25#include <boost/foreach.hpp>
26#include <boost/filesystem.hpp>
27#include <boost/regex.hpp>
4a527a29 28#include <boost/algorithm/string.hpp>
88a594e8 29
e0080b78 30
8bca3c5d
BS
31namespace po = boost::program_options;
32namespace fs = boost::filesystem;
4a527a29 33namespace ba = boost::algorithm;
8bca3c5d 34
92beaba3
BS
35typedef boost::shared_ptr<boost::program_options::options_description> Options_descriptionPtr;
36
8bca3c5d 37using namespace std;
254bbf53 38
31af6a2e 39
5c460c94 40/**
85a0abf9 41 * Default Constructor. Available command line and config file options with their default values are defined here.
5c460c94 42 */
31af6a2e
BS
43Config::Config()
44 : Log(new Logger)
45 , ServiceHolder(new Serviceholder)
46 , DaemonMode(false)
47 , Syslog(false)
48 , EnableIPv6(false)
49 , Loglevel(0)
50 , ConfigPath("/etc/bpdyndnsd")
51 , WebcheckInterval(0)
52 , ProxyPort(0)
53 , ExternalWarningLog("")
54 , ExternalWarningLevel(0)
6b63b758 55 , StartOffline(false)
46fffdd6 56 , WebcheckEnabled(false)
31af6a2e
BS
57{
58 // Available service description config options
59 po::options_description opt_desc_service("Service description options");
60 opt_desc_service.add_options()
61 ("protocol",po::value<string>(),"The service protocol.")
62 ("server",po::value<string>(),"Servername needed for gnudip protocol.")
63 ("host",po::value<string>(),"The hostname to update.")
64 ("login",po::value<string>(),"Login name.")
65 ("password",po::value<string>(),"Corresponding password.")
66 ("update_interval",po::value<int>()->default_value(-1),"Update interval in minutes.")
67 ("max_updates_within_interval",po::value<int>()->default_value(-1),"How many updates can be made in one interval.")
68 ("dns_cache_ttl",po::value<int>()->default_value(-1),"How long a dns record is valid.")
69 ;
70
71 // Available command line only options
72 po::options_description opt_desc_cmd_only("Command line only options");
73 opt_desc_cmd_only.add_options()
74 ("help,?","Show help.")
75 ("version,v","Show version.")
76 ("config,c",po::value<string>()->default_value("/etc/bpdyndnsd"),"Set the config path.")
77 ;
78
79 // Available generic options. Valid on cmd or in config file.
80 po::options_description opt_desc_generic("Generic config options");
81 opt_desc_generic.add_options()
82 ("daemon_mode",po::value<bool>()->default_value(false),"Run as system daemon.")
83 ("loglevel",po::value<int>()->default_value(0),"Loglevel.")
84 ("syslog",po::value<bool>()->default_value(false),"Use syslog facility.")
85 ("enable_ipv6",po::value<bool>()->default_value(false),"Try to use IPv6.")
46fffdd6 86 ("webcheck_enabled",po::value<bool>()->default_value(false),"Use webcheck url to determine actual IP address.")
31af6a2e
BS
87 ("webcheck_url",po::value<string>()->default_value(""),"Use this URL to determine IP.")
88 ("webcheck_url_alt",po::value<string>()->default_value(""),"Use this alternative URL to determine IP.")
89 ("webcheck_interval",po::value<int>()->default_value(10),"The webcheck interval in minutes.")
90 ("http_proxy",po::value<string>(),"Use this proxy for all http requests.")
91 ("http_proxy_port",po::value<int>(),"Port of the proxy.")
92 ("external_warning_log",po::value<string>()->default_value(""),"External programm to pass warning log messages to.")
93 ("external_warning_level",po::value<int>()->default_value(0),"Warning messages of which loglevel should be passed to external programm.")
6b63b758 94 ("start_offline",po::value<bool>()->default_value(false),"Start in offline mode.")
31af6a2e
BS
95 ;
96
97 // Define valid command line parameters
c3c84086 98 OptDescCmd = Options_descriptionPtr(new po::options_description("Command line options"));
31af6a2e
BS
99 OptDescCmd->add(opt_desc_cmd_only);
100 OptDescCmd->add(opt_desc_generic);
101 OptDescCmd->add(opt_desc_service);
102
103 // Define valid config file options
c3c84086 104 OptDescConfMain = Options_descriptionPtr(new po::options_description("Config file options"));
31af6a2e
BS
105 OptDescConfMain->add(opt_desc_generic);
106
107 // Define valid service file options
c3c84086 108 OptDescConfService = Options_descriptionPtr(new po::options_description("Service file options"));
31af6a2e
BS
109 OptDescConfService->add(opt_desc_service);
110}
111
112
113/**
114 * Constructor with Logger and Serviceholder objects. Available command line and config file options with their default values are defined here.
115 */
e0080b78 116Config::Config(Logger::Ptr _log, Serviceholder::Ptr _serviceholder)
9a0aff44
BS
117 : Log(_log)
118 , ServiceHolder(_serviceholder)
119 , DaemonMode(false)
85a0abf9 120 , Syslog(false)
019dc0d9 121 , EnableIPv6(false)
e0080b78
BS
122 , Loglevel(0)
123 , ConfigPath("/etc/bpdyndnsd")
2b0f7c11 124 , WebcheckInterval(0)
891ae3b9 125 , ProxyPort(0)
cbbdeb6c
BS
126 , ExternalWarningLog("")
127 , ExternalWarningLevel(0)
6b63b758 128 , StartOffline(false)
46fffdd6 129 , WebcheckEnabled(false)
4545a371 130{
3434b35f
BS
131 // Available service description config options
132 po::options_description opt_desc_service("Service description options");
133 opt_desc_service.add_options()
134 ("protocol",po::value<string>(),"The service protocol.")
a78b44b5 135 ("server",po::value<string>(),"Servername needed for gnudip protocol.")
3434b35f
BS
136 ("host",po::value<string>(),"The hostname to update.")
137 ("login",po::value<string>(),"Login name.")
138 ("password",po::value<string>(),"Corresponding password.")
3c0cd271
BS
139 ("update_interval",po::value<int>()->default_value(-1),"Update interval in minutes.")
140 ("max_updates_within_interval",po::value<int>()->default_value(-1),"How many updates can be made in one interval.")
c3dea5dc 141 ("dns_cache_ttl",po::value<int>()->default_value(-1),"How long a dns record is valid.")
3434b35f
BS
142 ;
143
144 // Available command line only options
145 po::options_description opt_desc_cmd_only("Command line only options");
146 opt_desc_cmd_only.add_options()
4545a371
BS
147 ("help,?","Show help.")
148 ("version,v","Show version.")
254bbf53 149 ("config,c",po::value<string>()->default_value("/etc/bpdyndnsd"),"Set the config path.")
4545a371
BS
150 ;
151
3434b35f
BS
152 // Available generic options. Valid on cmd or in config file.
153 po::options_description opt_desc_generic("Generic config options");
154 opt_desc_generic.add_options()
155 ("daemon_mode",po::value<bool>()->default_value(false),"Run as system daemon.")
3434b35f
BS
156 ("loglevel",po::value<int>()->default_value(0),"Loglevel.")
157 ("syslog",po::value<bool>()->default_value(false),"Use syslog facility.")
019dc0d9 158 ("enable_ipv6",po::value<bool>()->default_value(false),"Try to use IPv6.")
46fffdd6 159 ("webcheck_enabled",po::value<bool>()->default_value(false),"Use webcheck url to determine actual IP address.")
019dc0d9
BS
160 ("webcheck_url",po::value<string>()->default_value(""),"Use this URL to determine IP.")
161 ("webcheck_url_alt",po::value<string>()->default_value(""),"Use this alternative URL to determine IP.")
2b0f7c11 162 ("webcheck_interval",po::value<int>()->default_value(10),"The webcheck interval in minutes.")
8a00a649
BS
163 ("http_proxy",po::value<string>(),"Use this proxy for all http requests.")
164 ("http_proxy_port",po::value<int>(),"Port of the proxy.")
cbbdeb6c
BS
165 ("external_warning_log",po::value<string>()->default_value(""),"External programm to pass warning log messages to.")
166 ("external_warning_level",po::value<int>()->default_value(0),"Warning messages of which loglevel should be passed to external programm.")
6b63b758 167 ("start_offline",po::value<bool>()->default_value(false),"Start in offline mode.")
fc87cdbb 168 ;
4545a371 169
3434b35f 170 // Define valid command line parameters
c3c84086 171 OptDescCmd = Options_descriptionPtr(new po::options_description("Command line options"));
025abebb
BS
172 OptDescCmd->add(opt_desc_cmd_only);
173 OptDescCmd->add(opt_desc_generic);
174 OptDescCmd->add(opt_desc_service);
3434b35f
BS
175
176 // Define valid config file options
c3c84086 177 OptDescConfMain = Options_descriptionPtr(new po::options_description("Config file options"));
025abebb 178 OptDescConfMain->add(opt_desc_generic);
3434b35f
BS
179
180 // Define valid service file options
c3c84086 181 OptDescConfService = Options_descriptionPtr(new po::options_description("Service file options"));
025abebb 182 OptDescConfService->add(opt_desc_service);
4545a371
BS
183}
184
fc87cdbb 185
5c460c94
BS
186/**
187 * Default Destructor
188 */
4545a371
BS
189Config::~Config()
190{
4545a371
BS
191}
192
fc87cdbb 193
5c460c94
BS
194/**
195 * Parses the command line arguments and does the needed actions.
196 * @param argc Command line argument number given to main.
197 * @param argv[] Pointer to command line argument array given to main.
3404d89f 198 * @return 0 if all is fine, -1 if not.
5c460c94 199 */
e95a6634 200int Config::parse_cmd_line(int argc, char *argv[])
4545a371
BS
201{
202 try
203 {
025abebb
BS
204 po::store(po::parse_command_line(argc, argv, *this->OptDescCmd), VariablesMap);
205 po::notify(VariablesMap);
4545a371 206
025abebb 207 if ( VariablesMap.count("help") )
254bbf53 208 {
025abebb 209 Log->print_usage(OptDescCmd);
3404d89f 210 return -1;
254bbf53 211 }
025abebb 212 else if ( VariablesMap.count("version") )
254bbf53
BS
213 {
214 Log->print_version();
3404d89f 215 return -1;
254bbf53 216 }
4545a371 217
254bbf53 218 // Create a service object if all needed options are set on the command line
025abebb 219 if ( VariablesMap.count("protocol") && VariablesMap.count("host") && VariablesMap.count("login") && VariablesMap.count("password") )
4545a371 220 {
fc87cdbb 221 // Get the cmd parameter values for protocol host login and password
025abebb
BS
222 string protocol = VariablesMap["protocol"].as<string>();
223 string host = VariablesMap["host"].as<string>();
224 string login = VariablesMap["login"].as<string>();
225 string password = VariablesMap["password"].as<string>();
4545a371 226
4a527a29 227 protocol = ba::to_lower_copy(protocol);
4545a371 228
a78b44b5
BS
229 string server;
230 if ( VariablesMap.count("server") )
231 server = VariablesMap["server"].as<string>();
232
3c0cd271
BS
233 int update_interval = 0;
234 if ( VariablesMap.count("update_interval") )
235 update_interval = VariablesMap["update_interval"].as<int>();
236
237 int max_updates_within_interval = 0;
238 if ( VariablesMap.count("max_updates_within_interval") )
239 max_updates_within_interval = VariablesMap["max_updates_within_interval"].as<int>();
240
c3dea5dc
BS
241 int dns_cache_ttl = 0;
242 if ( VariablesMap.count("dns_cache_ttl") )
243 dns_cache_ttl = VariablesMap["dns_cache_ttl"].as<int>();
244
a78b44b5 245 Service::Ptr service = create_service(protocol,server,host,login,password,update_interval,max_updates_within_interval,dns_cache_ttl);
3a3f3566 246 if ( service )
e0080b78
BS
247 {
248 ServiceHolder->add_service(service);
d5a516ba 249 Log->print_service_object("New Service object from command line options:", service->get_protocol(), service->get_hostname(), service->get_login() ,service->get_password(), service->get_update_interval(), service->get_max_updates_within_interval(), service->get_dns_cache_ttl() , service->get_actual_ip(), service->get_last_updates());
e0080b78 250 }
254bbf53 251 else
60657d55
BS
252 {
253 Log->print_invalid_service_config();
254 }
4545a371 255 }
025abebb 256 else if ( VariablesMap.count("protocol") || VariablesMap.count("host") || VariablesMap.count("login") || VariablesMap.count("password") )
4545a371 257 {
254bbf53 258 Log->print_missing_cmd_service_option();
025abebb 259 Log->print_usage(OptDescCmd);
3404d89f 260 return -1;
4545a371 261 }
254bbf53 262
025abebb 263 if ( VariablesMap.count("config") )
254bbf53 264 {
025abebb
BS
265 fs::path full_config_path = fs::system_complete(fs::path(VariablesMap["config"].as<string>()));
266 ConfigPath = full_config_path.string();
254bbf53
BS
267 if ( !fs::exists(full_config_path) || !fs::is_directory(full_config_path) )
268 {
269 // Config path doesn't exist or is not a directory
025abebb 270 Log->print_error_config_path(ConfigPath);
3404d89f 271 return -1;
254bbf53
BS
272 }
273 }
59c8d63c 274
019dc0d9
BS
275 if ( VariablesMap.count("daemon_mode") )
276 DaemonMode = VariablesMap["daemon_mode"].as<bool>();
277
025abebb
BS
278 if ( VariablesMap.count("loglevel") )
279 Loglevel = VariablesMap["loglevel"].as<int>();
59c8d63c 280
025abebb
BS
281 if ( VariablesMap.count("syslog") )
282 Syslog = VariablesMap["syslog"].as<bool>();
59c8d63c 283
019dc0d9
BS
284 if ( VariablesMap.count("enable_ipv6") )
285 EnableIPv6 = VariablesMap["enable_ipv6"].as<bool>();
286
46fffdd6
BS
287 if ( VariablesMap.count("webcheck_enabled") )
288 WebcheckEnabled = VariablesMap["webcheck_enabled"].as<bool>();
289
019dc0d9
BS
290 if ( VariablesMap.count("webcheck_url") )
291 WebcheckIpUrl = VariablesMap["webcheck_url"].as<string>();
292
293 if ( VariablesMap.count("webcheck_url_alt") )
294 WebcheckIpUrlAlt = VariablesMap["webcheck_url_alt"].as<string>();
295
2b0f7c11
BS
296 if ( VariablesMap.count("webcheck_interval") )
297 WebcheckInterval = VariablesMap["webcheck_interval"].as<int>();
298
8a00a649
BS
299 if ( VariablesMap.count("http_proxy") && VariablesMap.count("http_proxy_port") )
300 {
4eb87664 301 Proxy = VariablesMap["http_proxy"].as<string>();
4eb87664 302 ProxyPort = VariablesMap["http_proxy_port"].as<int>();
8a00a649
BS
303 }
304 else if ( VariablesMap.count("http_proxy") || VariablesMap.count("http_proxy_port") )
305 {
306 Log->print_missing_cmd_proxy_option();
307 Log->print_usage(OptDescCmd);
308 return -1;
309 }
310
cbbdeb6c
BS
311 if ( VariablesMap.count("external_warning_log") )
312 ExternalWarningLog = VariablesMap["external_warning_log"].as<string>();
313
314 if ( VariablesMap.count("external_warning_level") )
315 ExternalWarningLevel = VariablesMap["external_warning_level"].as<int>();
4eb87664 316
6b63b758
BS
317 if ( VariablesMap.count("start_offline") )
318 StartOffline = VariablesMap["start_offline"].as<bool>();
319
4545a371 320 }
08a5a621 321 catch( const po::unknown_option& e )
4545a371 322 {
254bbf53 323 Log->print_unknown_cmd_option(e.what());
025abebb 324 Log->print_usage(OptDescCmd);
3404d89f 325 return -1;
4545a371 326 }
08a5a621 327 catch( const po::multiple_occurrences& e )
3c0cd271
BS
328 {
329 Log->print_multiple_cmd_option(e.what());
330 Log->print_usage(OptDescCmd);
331 return -1;
332 }
08a5a621 333 catch( const po::error& e )
c1b8cb79
BS
334 {
335 Log->print_error_parsing_cmd(e.what());
336 Log->print_usage(OptDescCmd);
337 return -1;
338 }
4545a371
BS
339 return 0;
340}
341
fc87cdbb 342
5c460c94 343/**
019dc0d9
BS
344 * Creates a Service object from the given parameters.
345 * @param protocol Protocol to use.
346 * @param host Hostname to update.
347 * @param login Login.
348 * @param password Password.
0680036d
BS
349 * @return A pointer to the created Service object.
350 */
a78b44b5 351Service::Ptr Config::create_service(const string &protocol, const string& server, const string& hostname, const string& login, const string& password, const int update_interval, const int max_updates_within_interval, const int dns_cache_ttl)
0680036d 352{
1a00eac6
BS
353 // Test for valid hostname. Must contain 3 parts minimum.
354 list<string> fqhn_parts;
355 ba::split(fqhn_parts,hostname,boost::is_any_of("."));
356 if ( fqhn_parts.size() < 3 )
357 {
60657d55 358 Log->print_invalid_hostname(hostname);
1a00eac6
BS
359 Service::Ptr service;
360 return service;
361 }
362
0680036d
BS
363 if(protocol == "dhs")
364 {
629d8110 365 Service::Ptr service_dhs(new ServiceDhs(protocol,hostname,login,password,Log,update_interval,max_updates_within_interval,dns_cache_ttl,Proxy,ProxyPort));
85a0abf9 366 return service_dhs;
0680036d
BS
367 }
368 else if(protocol == "ods")
369 {
629d8110 370 Service::Ptr service_ods(new ServiceOds(protocol,hostname,login,password,Log,update_interval,max_updates_within_interval,dns_cache_ttl));
85a0abf9
BS
371 return service_ods;
372 }
b6228761
BS
373 else if(protocol == "dyndns")
374 {
629d8110 375 Service::Ptr service_dyndns(new ServiceDyndns(protocol,hostname,login,password,Log,update_interval,max_updates_within_interval,dns_cache_ttl,Proxy,ProxyPort));
b6228761
BS
376 return service_dyndns;
377 }
b30f392d
BS
378 else if(protocol == "dyns")
379 {
629d8110 380 Service::Ptr service_dyns(new ServiceDyns(protocol,hostname,login,password,Log,update_interval,max_updates_within_interval,dns_cache_ttl,Proxy,ProxyPort));
b30f392d
BS
381 return service_dyns;
382 }
1a00eac6
BS
383 else if(protocol == "easydns")
384 {
629d8110 385 Service::Ptr service_easydns(new ServiceEasydns(protocol,hostname,login,password,Log,update_interval,max_updates_within_interval,dns_cache_ttl,Proxy,ProxyPort));
1a00eac6
BS
386 return service_easydns;
387 }
b17fd691
BS
388 else if(protocol == "tzo")
389 {
629d8110 390 Service::Ptr service_tzo(new ServiceTzo(protocol,hostname,login,password,Log,update_interval,max_updates_within_interval,dns_cache_ttl,Proxy,ProxyPort));
b17fd691
BS
391 return service_tzo;
392 }
3f8b2557
BS
393 else if(protocol == "zoneedit")
394 {
629d8110 395 Service::Ptr service_zoneedit(new ServiceZoneedit(protocol,hostname,login,password,Log,update_interval,max_updates_within_interval,dns_cache_ttl,Proxy,ProxyPort));
3f8b2557
BS
396 return service_zoneedit;
397 }
a78b44b5
BS
398 else if(protocol == "gnudip")
399 {
400 cout << "Server: " << server << endl;
401 if ( !server.empty() )
402 {
403 Service::Ptr service_gnudip(new ServiceGnudip(protocol,server,hostname,login,password,Log,update_interval,max_updates_within_interval,dns_cache_ttl,Proxy,ProxyPort));
404 return service_gnudip;
405 }
406 else
407 {
408 Log->print_gnudip_requires_servername();
409 Service::Ptr service;
410 return service;
411 }
412 }
85a0abf9
BS
413 else
414 {
254bbf53 415 Log->print_unknown_protocol(protocol);
88a594e8 416 Service::Ptr service;
83b60bd6 417 return service;
0680036d 418 }
0680036d
BS
419}
420
421
422/**
1cf4e2b5
BS
423 * Loads a service config file, invoked by load_config_from_files.
424 * @param full_filename Filename of the service config file to load.
3404d89f 425 * @return 0 if all is fine, -1 otherwise.
1cf4e2b5 426 */
e95a6634 427int Config::load_service_config_file(const string& full_filename)
1cf4e2b5 428{
254bbf53
BS
429 Log->print_load_service_conf(full_filename);
430
1cf4e2b5
BS
431 ifstream service_config_file(full_filename.c_str(),ifstream::in);
432 if(service_config_file.is_open())
433 {
434 try
435 {
436 po::variables_map vm;
025abebb 437 po::parsed_options parsed_service_options = po::parse_config_file(service_config_file,*this->OptDescConfService,true);
1cf4e2b5
BS
438 po::store(parsed_service_options,vm);
439 po::notify(vm);
440
3434b35f 441 if(vm.count("protocol") && vm.count("host") && vm.count("login") && vm.count("password"))
1cf4e2b5
BS
442 {
443 // create the corresponding service
3434b35f
BS
444 string protocol = vm["protocol"].as<string>();
445 string host = vm["host"].as<string>();
446 string login = vm["login"].as<string>();
c1b8cb79 447 string password = vm["password"].as<string>();
1cf4e2b5 448
4a527a29 449 protocol = ba::to_lower_copy(protocol);
1cf4e2b5 450
a78b44b5
BS
451 string server;
452 if ( vm.count("server") )
453 server = vm["server"].as<string>();
454
3c0cd271 455 int update_interval = 0;
8a00a649 456 if ( vm.count("update_interval") )
a78b44b5 457 update_interval = vm["update_interval"].as<int>();
3c0cd271
BS
458
459 int max_updates_within_interval = 0;
8a00a649 460 if ( vm.count("max_updates_within_interval") )
a78b44b5 461 max_updates_within_interval = vm["max_updates_within_interval"].as<int>();
3c0cd271 462
c3dea5dc 463 int dns_cache_ttl = 0;
8a00a649 464 if ( vm.count("dns_cache_ttl") )
a78b44b5 465 dns_cache_ttl = vm["dns_cache_ttl"].as<int>();
c3dea5dc 466
a78b44b5 467 Service::Ptr service = create_service(protocol,server,host,login,password,update_interval,max_updates_within_interval,dns_cache_ttl);
3a3f3566 468 if ( service )
1cf4e2b5 469 {
e0080b78 470 ServiceHolder->add_service(service);
d5a516ba 471 Log->print_service_object("New Service object from config:", service->get_protocol(), service->get_hostname(), service->get_login() ,service->get_password(), service->get_update_interval(), service->get_max_updates_within_interval(), service->get_dns_cache_ttl() , service->get_actual_ip(), service->get_last_updates());
1cf4e2b5 472 }
e0080b78 473 else
60657d55
BS
474 {
475 Log->print_invalid_service_config();
476 }
1cf4e2b5 477 }
8a00a649
BS
478 else if ( vm.count("protocol") || vm.count("host") || vm.count("login") || vm.count("password") )
479 {
480 service_config_file.close();
481 Log->print_missing_service_conf_option(full_filename);
482 return -1;
483 }
1cf4e2b5 484 }
08a5a621 485 catch( const po::unknown_option& e )
1cf4e2b5
BS
486 {
487 // unknown option in config file detected
488 service_config_file.close();
8a00a649
BS
489 Log->print_unknown_service_conf_option(full_filename,e.what());
490 return -1;
491 }
08a5a621 492 catch( const po::multiple_occurrences& e )
8a00a649
BS
493 {
494 service_config_file.close();
495 Log->print_multiple_service_conf_option(full_filename,e.what());
3404d89f 496 return -1;
1cf4e2b5 497 }
08a5a621 498 catch( const po::error& e )
c1b8cb79
BS
499 {
500 service_config_file.close();
501 Log->print_error_parsing_config_file(full_filename,e.what());
502 return -1;
503 }
1cf4e2b5
BS
504 service_config_file.close();
505 }
506 else
507 {
254bbf53 508 // error opening service config file for reading
667c672c 509 Log->print_error_opening_r(full_filename);
3404d89f 510 return -1;
1cf4e2b5
BS
511 }
512 return 0;
513}
514
254bbf53 515
1cf4e2b5
BS
516/**
517 * Loads the main config file, invoked by load_config_from_files
518 * @param full_filename The full filename of the main config file to load
3404d89f 519 * @return 0 if all is fine, -1 otherwise
1cf4e2b5 520 */
254bbf53 521int Config::load_main_config_file(const string& full_filename)
1cf4e2b5 522{
254bbf53
BS
523 Log->print_load_main_conf(full_filename);
524
1cf4e2b5
BS
525 ifstream main_config_file(full_filename.c_str(),ifstream::in);
526 if(main_config_file.is_open())
527 {
528 try
529 {
025abebb
BS
530 po::parsed_options parsed_main_options = po::parse_config_file(main_config_file,*this->OptDescConfMain,true);
531 po::store(parsed_main_options,VariablesMap);
532 po::notify(VariablesMap);
1cf4e2b5 533
8a00a649
BS
534 if ( VariablesMap.count("daemon_mode") )
535 DaemonMode = VariablesMap["daemon_mode"].as<bool>();
019dc0d9 536
8a00a649
BS
537 if ( VariablesMap.count("loglevel") )
538 Loglevel = VariablesMap["loglevel"].as<int>();
019dc0d9 539
8a00a649
BS
540 if ( VariablesMap.count("syslog") )
541 Syslog = VariablesMap["syslog"].as<bool>();
019dc0d9 542
8a00a649
BS
543 if ( VariablesMap.count("enable_ipv6") )
544 EnableIPv6 = VariablesMap["enable_ipv6"].as<bool>();
019dc0d9 545
46fffdd6
BS
546 if ( VariablesMap.count("webcheck_enabled") )
547 WebcheckEnabled = VariablesMap["webcheck_enabled"].as<bool>();
548
8a00a649
BS
549 if ( VariablesMap.count("webcheck_url") )
550 WebcheckIpUrl = VariablesMap["webcheck_url"].as<string>();
019dc0d9 551
8a00a649
BS
552 if ( VariablesMap.count("webcheck_url_alt") )
553 WebcheckIpUrlAlt = VariablesMap["webcheck_url_alt"].as<string>();
4eb87664 554
2b0f7c11
BS
555 if ( VariablesMap.count("webcheck_interval") )
556 WebcheckInterval = VariablesMap["webcheck_interval"].as<int>();
557
8a00a649
BS
558 if ( VariablesMap.count("http_proxy") && VariablesMap.count("http_proxy_port") )
559 {
560 Proxy = VariablesMap["http_proxy"].as<string>();
561 ProxyPort = VariablesMap["http_proxy_port"].as<int>();
562 }
563 else if ( VariablesMap.count("http_proxy") || VariablesMap.count("http_proxy_port") )
564 {
565 main_config_file.close();
566 Log->print_missing_conf_proxy_option(full_filename);
567 return -1;
568 }
4eb87664 569
cbbdeb6c
BS
570 if ( VariablesMap.count("external_warning_log") )
571 ExternalWarningLog = VariablesMap["external_warning_log"].as<string>();
572
573 if ( VariablesMap.count("external_warning_level") )
574 ExternalWarningLevel = VariablesMap["external_warning_level"].as<int>();
575
6b63b758
BS
576 if ( VariablesMap.count("start_offline") )
577 StartOffline = VariablesMap["start_offline"].as<bool>();
578
1cf4e2b5 579 }
08a5a621 580 catch( const po::unknown_option& e ) // at the moment 04-08-2009 this exception is never thrown :-(
1cf4e2b5 581 {
254bbf53 582 // unknown option in main config file detected
1cf4e2b5 583 main_config_file.close();
254bbf53 584 Log->print_unknown_main_conf_option(e.what());
3404d89f 585 return -1;
1cf4e2b5 586 }
08a5a621 587 catch( const po::multiple_occurrences& e )
8a00a649
BS
588 {
589 main_config_file.close();
590 Log->print_multiple_main_conf_option(full_filename,e.what());
591 return -1;
592 }
1cf4e2b5
BS
593 main_config_file.close();
594 }
595 else
596 {
254bbf53 597 // error opening main config file for reading
667c672c 598 Log->print_error_opening_r(full_filename);
3404d89f 599 return -1;
1cf4e2b5
BS
600 }
601 return 0;
602}
603
254bbf53 604
1cf4e2b5 605/**
5c460c94
BS
606 * Loads the main and the service config file and does the needed action.
607 * @param config_path The path to the config directory.
3404d89f 608 * @return 0 if all is fine, -1 otherwise
5c460c94 609 */
e95a6634 610int Config::load_config_from_files()
4545a371 611{
025abebb 612 fs::path full_config_path = fs::path(ConfigPath);
7ec77cf1 613
254bbf53
BS
614 fs::directory_iterator end_iter;
615 for ( fs::directory_iterator dir_itr(full_config_path) ; dir_itr != end_iter ; ++dir_itr )
7ec77cf1 616 {
254bbf53 617 if( fs::is_regular_file( dir_itr->status() ) )
7ec77cf1 618 {
254bbf53 619 string actual_file = dir_itr->path().filename();
ba309142 620 boost::regex expr(".*\\.conf?");
254bbf53
BS
621 // If it is the main config file do the following
622 if ( actual_file == "bpdyndnsd.conf" )
7ec77cf1 623 {
254bbf53
BS
624 // Load the main config file
625 string full_filename = dir_itr->path().string();
626 if ( load_main_config_file(full_filename) != 0 )
3404d89f 627 return -1;
254bbf53
BS
628 }
629 // If it is a service definition file *.conf, parse it and generate the corresponding service
630 else if ( boost::regex_search( actual_file,expr ) )
631 {
632 string full_filename = dir_itr->path().string();
e95a6634 633 if ( load_service_config_file(full_filename) != 0 )
3404d89f 634 return -1;
fc87cdbb
BS
635 }
636 }
fc87cdbb 637 }
254bbf53 638 // Config file successfully loaded
025abebb 639 Log->print_conf_loaded(ConfigPath);
b1be615b 640 return 0;
4545a371
BS
641}
642
fc87cdbb 643
5c460c94 644/**
025abebb 645 * Getter method for member OptDescCmd.
254bbf53 646 * @return options_description*.
5c460c94 647 */
92beaba3 648Options_descriptionPtr Config::get_opt_desc_cmd() const
fc87cdbb 649{
025abebb 650 return OptDescCmd;
4545a371
BS
651}
652
fc87cdbb 653
5c460c94 654/**
025abebb 655 * Getter method for member OptDescConfMain.
254bbf53 656 * @return options_description*.
5c460c94 657 */
92beaba3 658Options_descriptionPtr Config::get_opt_desc_conf_main() const
4545a371 659{
025abebb 660 return OptDescConfMain;
4545a371 661}
38060291 662
254bbf53 663
38060291 664/**
025abebb 665 * Getter method for member OptDescConfService.
254bbf53 666 * @return options_description*.
38060291 667 */
92beaba3 668Options_descriptionPtr Config::get_opt_desc_conf_service() const
38060291 669{
025abebb 670 return OptDescConfService;
38060291 671}
3434b35f 672
c5675c01 673
3434b35f
BS
674/**
675 * Getter for member Loglevel.
676 * @return Member Loglevel.
677 */
b38684ce 678int Config::get_loglevel() const
3434b35f
BS
679{
680 return Loglevel;
681}
388f4ab0 682
c5675c01 683
388f4ab0 684/**
025abebb 685 * Getter for member DaemonMode.
388f4ab0
BS
686 * @return TRUE if enabled, FALSE if disabled.
687 */
b38684ce 688bool Config::get_daemon_mode() const
388f4ab0 689{
025abebb 690 return DaemonMode;
388f4ab0 691}
c5675c01
BS
692
693
694/**
8bca3c5d
BS
695 * Deletes the map with the previously parsed options.
696 * This is needed in case we reload the config and don't want the old cmd options to overwrite new config file options.
697 */
698void Config::delete_variables_map()
699{
025abebb 700 VariablesMap.clear();
8bca3c5d
BS
701
702 po::variables_map _variables_map;
025abebb 703 VariablesMap = _variables_map;
8bca3c5d
BS
704}
705
706
707/**
708 * Getter for member Syslog.
709 * @return True if logging through syslog is enabled, false otherwise.
710 */
b38684ce 711bool Config::get_syslog() const
8bca3c5d
BS
712{
713 return Syslog;
714}
019dc0d9
BS
715
716
717/**
718 * Getter for member EnableIPv6
719 * @return Wether IPv6 should be used or not.
720 */
721bool Config::get_enable_ipv6() const
722{
723 return EnableIPv6;
724}
725
726
727/**
46fffdd6
BS
728 * Getter for member WebcheckEnabled
729 * @return Is webcheck enabled by default.
730 */
731bool Config::get_webcheck_enabled() const
732{
733 return WebcheckEnabled;
734}
735
736
737/**
738 * Setter for member WebcheckEnabled
739 * @return Is webcheck enabled by default.
740 */
741void Config::set_webcheck_enabled( bool webcheck_enabled )
742{
743 WebcheckEnabled = webcheck_enabled;
744}
745
746
747/**
019dc0d9
BS
748 * Getter for member WebcheckIpUrl
749 * @return The primary IP Webcheck URL
750 */
751string Config::get_webcheck_ip_url() const
752{
753 return WebcheckIpUrl;
754}
755
756
757/**
758 * Getter for member WebcheckIpUrlAlt
759 * @return The alternative IP Webcheck URL
760 */
761string Config::get_webcheck_ip_url_alt() const
762{
763 return WebcheckIpUrlAlt;
764}
4eb87664
BS
765
766
767/**
2b0f7c11
BS
768 * Get member WebcheckInterval
769 * @return WebcheckInterval
770 */
771int Config::get_webcheck_interval() const
772{
773 return WebcheckInterval;
774}
775
776
777/**
4eb87664
BS
778 * Get member Proxy
779 * @return Proxy
780 */
781string Config::get_proxy() const
782{
783 return Proxy;
784}
785
786
787/**
788 * Get member ProxyPort
789 * @return ProxyPort
790 */
791int Config::get_proxy_port() const
792{
793 return ProxyPort;
794}
cbbdeb6c
BS
795
796
797/**
798 * Get member ExternalWarningLog
799 * @return ExternalWarningLog
800 */
801string Config::get_external_warning_log() const
802{
803 return ExternalWarningLog;
804}
805
806
807/**
808 * Get member ExternalWarningLevel
809 * @return ExternalWaringLevel
810 */
811int Config::get_external_warning_level() const
812{
813 return ExternalWarningLevel;
814}
815
6b63b758
BS
816
817/**
818 * Get member StartOffline
819 * @return StartOffline
820 */
821bool Config::get_start_offline() const
822{
823 return StartOffline;
824}