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