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