Removed version information from main.cpp.
[bpdyndnsd] / src / updater.cpp
CommitLineData
b1be615b
BS
1/** @file
2 * @brief The updater class implementation. This class implements the updater logic.
3 *
4 *
5 *
6 * @copyright Intra2net AG
7 * @license GPLv2
8*/
9
4545a371
BS
10#include "updater.h"
11
e0080b78 12#include "serviceholder.h"
e0080b78 13
e0080b78 14
ca5d6889
BS
15#include <boost/foreach.hpp>
16#include <boost/serialization/export.hpp>
b30f392d 17
e0080b78 18
8bca3c5d 19using namespace std;
527536b3 20
ca5d6889 21
b1be615b
BS
22/**
23 * Default constructor which initializes the member Conf.
24 */
4545a371 25Updater::Updater()
ad0e5016 26 : IPAddrHelp(new IPAddrHelper)
4545a371 27{
2e956a36 28 // Initialize program wide Logger, at this point we don't know where to log and with which loglevel.
88a594e8 29 Logger::Ptr _log(new Logger);
4dfdba68 30 Log.swap(_log);
4545a371 31
e0080b78
BS
32 // initialize Serviceholder
33 Serviceholder::Ptr _serviceholder(new Serviceholder(Log));
4dfdba68 34 ServiceHolder.swap(_serviceholder);
e0080b78 35
254bbf53 36 // initialize Config
e0080b78 37 Config::Ptr _config(new Config(Log,ServiceHolder));
4dfdba68 38 Conf.swap(_config);
4545a371
BS
39}
40
527536b3 41
b1be615b
BS
42/**
43 * Default destructor.
44 */
4545a371
BS
45Updater::~Updater()
46{
47}
48
527536b3 49
efbde536
BS
50
51/**
52 * Load config and initialize helper classes.
53 * @param argc Number of arguments in array
54 * @param argv Array with cmd options
55 */
56int Updater::load_config(int argc, char *argv[])
57{
58 // load the cmd options
59 if ( init_config_from_cmd(argc,argv) != 0 )
60 return -1;
61
62 // load the config and service files
63 if ( init_config_from_files() != 0 )
64 return -1;
65
66 // init all helper classes
67 if ( init_helper_classes() != 0 )
68 return -1;
69
70 return 0;
71}
72
73
74/**
75 * Reloading the config. Delete all Service objects and then init new Service objects from config files.
76 */
77int Updater::reload_config()
78{
79 // serialize all service objects
80 if ( ServiceHolder->serialize_services() != 0 )
81 return -1;
82
83 // delete all service objects
84 ServiceHolder->delete_services();
85
86 // delete the actual Variables_map, perhaps with old cmd options which would overwrite new config file options.
87 Conf->delete_variables_map();
88
89 // load only config files
90 if ( init_config_from_files() != 0 )
91 return -1;
92
93 // init all helper classes
94 if ( init_helper_classes() != 0 )
95 return -1;
96
97 return 0;
98}
99
100
b1be615b 101/**
254bbf53
BS
102 * Parse the command line arguments and initialize corresponding options.
103 * @param argc Number command line arguments.
104 * @param argv[] Array with arguments.
105 * @return 0 if cmd options successfully parsed, 1 if usage or version.
38060291 106 */
254bbf53 107int Updater::init_config_from_cmd(int argc, char *argv[])
38060291
BS
108{
109 // Load the command line parameters
e95a6634 110 if( Conf->parse_cmd_line( argc, argv) != 0)
667c672c 111 return -1;
38060291 112
59c8d63c
BS
113 // If we have loaded the cmd options we need to init the log facility immediately in case debugging is enabled from cmd.
114 init_log_facility();
115
254bbf53
BS
116 // successful parsed
117 Log->print_cmd_parsed();
38060291
BS
118 return 0;
119}
120
121
122/**
254bbf53
BS
123 * Load the main config and the service definition files in config path.
124 * @return 0 if all is fine,
b1be615b 125 */
254bbf53 126int Updater::init_config_from_files()
4545a371 127{
254bbf53 128 // Load the main and service config files in config path
e95a6634 129 if ( Conf->load_config_from_files() != 0 )
667c672c 130 return -1;
4545a371 131
59c8d63c
BS
132 // Re-init log facility, perhaps new config file options for logger are set.
133 // These config file options will only overwrite the cmd options if the SIGHUP (reload config) is caught.
134 init_log_facility();
135
27baf279 136 // Here we are. All Service Objects should be initialized, so it is time to deserialize the old service objects and compare them.
e0080b78 137 if ( ServiceHolder->deserialize_services() != 0 )
667c672c 138 return -1;
27baf279 139
254bbf53 140 // successful loaded
667c672c 141 Log->print_conf_files_parsed();
254bbf53 142 return 0;
4545a371
BS
143}
144
527536b3 145
b1be615b 146/**
efbde536
BS
147 * Init all Helper classes
148 * @return
3434b35f 149 */
efbde536 150int Updater::init_helper_classes()
3434b35f 151{
efbde536
BS
152 // Initialize IPHelper
153 if ( init_ip_helper() != 0 )
154 return -1;
3434b35f 155
efbde536 156 return 0;
3434b35f
BS
157}
158
159
160/**
0665b239
BS
161 * Init the IPHelp member with needed values.
162 * @return 0 if all is fine, -1 otherwise.
163 */
164int Updater::init_ip_helper()
165{
20399847
BS
166 // Try to get deserialized IPAddrHelper from ServiceHolder
167 IPAddrHelper::Ptr _ip_addr_help = ServiceHolder->get_ip_addr_helper();
168 if ( _ip_addr_help.use_count() != 0 )
169 {
170 // Initialize IPHelper
171 IPAddrHelper::Ptr ip_addr_help( new IPAddrHelper( Log, Conf->get_webcheck_ip_url(), Conf->get_webcheck_ip_url_alt(), Conf->get_webcheck_interval(), _ip_addr_help->get_last_webcheck(), Conf->get_enable_ipv6(), Conf->get_proxy(), Conf->get_proxy_port() ) );
172 IPAddrHelp.swap(ip_addr_help);
173 }
174 else
175 {
176 // IPAddrHelper from ServiceHolder was not declared, so init oen with LastWebcheck 0
177 IPAddrHelper::Ptr ip_addr_help( new IPAddrHelper( Log, Conf->get_webcheck_ip_url(), Conf->get_webcheck_ip_url_alt(), Conf->get_webcheck_interval(), 0, Conf->get_enable_ipv6(), Conf->get_proxy(), Conf->get_proxy_port() ) );
178 IPAddrHelp.swap(ip_addr_help);
179 }
180
181 // Put the IPAddrHelper into ServiceHolder, so the LastWebcheck state will be serialized too.
182 ServiceHolder->set_ip_addr_helper(IPAddrHelp);
0665b239
BS
183
184 return 0;
185}
186
187
188/**
efbde536
BS
189 * Getter for member Config.
190 * @return Member Config.
191 */
192Config::Ptr Updater::get_config() const
193{
194 return Conf;
195}
667c672c 196
efbde536
BS
197
198/**
199 * Getter for member Logger.
200 * @return Member Logger.
201 */
202Logger::Ptr Updater::get_logger() const
203{
204 return Log;
8bca3c5d
BS
205}
206
207
2bc1878a
BS
208/**
209 * Initialize the logging facility with loglevel and syslog.
210 */
8bca3c5d
BS
211void Updater::init_log_facility()
212{
cbbdeb6c 213 Log->set_log_facility(Conf->get_loglevel(),Conf->get_syslog(),Conf->get_external_warning_log(),Conf->get_external_warning_level());
8bca3c5d 214 Log->print_init_log_facility();
c5675c01
BS
215}
216
217
218/**
b1be615b
BS
219 * Update all configured services.
220 */
4545a371
BS
221void Updater::update_services()
222{
e0080b78 223 list<Service::Ptr> services = ServiceHolder->get_services();
4545a371 224
ad0e5016 225 string ip = IPAddrHelp->get_actual_ip();
4545a371 226
3c0cd271 227 if ( !ip.empty() )
4545a371 228 {
3c0cd271
BS
229 BOOST_FOREACH(Service::Ptr &service, services )
230 {
c3dea5dc
BS
231 string dns_recheck_ip = ip;
232 int current_time = time(NULL);
233
234 int lastupdated = 0;
c1b8cb79
BS
235 if ( service->get_last_updates().size() > 0 )
236 lastupdated = service->get_last_updates().front();
c3dea5dc 237
d5a516ba
BS
238 // If the dns cache ttl is expired or the service is updated for the first time, then get the actual ip of the dns record (this should be the IP in the last update)
239 if ( ((lastupdated != 0) && ((lastupdated + service->get_dns_cache_ttl()) < current_time)) || (lastupdated == 0) )
0541cd71
BS
240 {
241 Log->print_recheck_dns_entry(service->get_hostname(),lastupdated,service->get_dns_cache_ttl(),current_time);
ad0e5016 242 string _dns_recheck_ip = IPAddrHelp->dns_query(service->get_hostname());
0541cd71
BS
243 Log->print_cached_dns_entry(service->get_hostname(), _dns_recheck_ip, service->get_actual_ip());
244 if (!_dns_recheck_ip.empty())
245 dns_recheck_ip = _dns_recheck_ip;
246 }
c3dea5dc 247
4eb87664
BS
248 // In case the local hosts IP (ip) differ from the IP set in the last update (actual_ip) or
249 // the IP of the dns record (dns_recheck_ip) differs from the IP of the local host (ip)
250 // then perform an update. This implies that the update is not performed if actual_ip == dns_recheck_ip.
d5a516ba
BS
251 // Special case when latupdated == 0 then only perform the update if dns_rechek_ip differs from ip
252 if ( ((service->get_actual_ip() != ip) && (lastupdated != 0)) || (dns_recheck_ip != ip) )
c3dea5dc 253 service->update(ip,current_time);
d5a516ba
BS
254 else if ( (service->get_actual_ip() != ip) && (lastupdated == 0) )
255 service->set_actual_ip(ip);
3c0cd271 256 }
4545a371 257 }
b1be615b 258}
e0080b78
BS
259
260
261/**
262 * Getter for member ServiceHolder.
263 * @return ServiceHolder
264 */
265Serviceholder::Ptr Updater::get_service_holder() const
266{
267 return ServiceHolder;
268}