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