2 * @brief The updater class implementation. This class implements the updater logic.
6 * @copyright Intra2net AG
12 #include "serviceholder.h"
13 #include "service_dhs.h"
14 #include "service_ods.h"
15 #include "service_dyndns.h"
16 #include "service_dyns.h"
17 #include "service_easydns.h"
18 #include "service_tzo.h"
19 #include "service_zoneedit.h"
20 #include "service_gnudip.h"
22 #include <boost/foreach.hpp>
25 // Following boost macros are needed for serialization of derived classes through a base class pointer (Service *).
26 BOOST_CLASS_EXPORT_GUID(ServiceOds, "ServiceOds")
27 BOOST_CLASS_EXPORT_GUID(ServiceDhs, "ServiceDhs")
28 BOOST_CLASS_EXPORT_GUID(ServiceDyns, "ServiceDyns")
29 BOOST_CLASS_EXPORT_GUID(ServiceDyndns, "ServiceDyndns")
30 BOOST_CLASS_EXPORT_GUID(ServiceEasydns, "ServiceEasydns")
31 BOOST_CLASS_EXPORT_GUID(ServiceTzo, "ServiceTzo")
32 BOOST_CLASS_EXPORT_GUID(ServiceZoneedit, "ServiceZoneedit")
33 BOOST_CLASS_EXPORT_GUID(ServiceGnudip, "ServiceGnudip")
36 namespace fs = boost::filesystem;
41 * Default constructor which initializes the member Conf.
44 : IPAddrHelp(new IPAddrHelper)
46 // Initialize program wide Logger, at this point we don't know where to log and with which loglevel.
47 Logger::Ptr _log(new Logger);
50 // initialize Serviceholder
51 Serviceholder::Ptr _serviceholder(new Serviceholder(Log));
52 ServiceHolder.swap(_serviceholder);
55 Config::Ptr _config(new Config(Log,ServiceHolder));
70 * Load config and initialize helper classes.
71 * @param argc Number of arguments in array
72 * @param argv Array with cmd options
74 int Updater::load_config(int argc, char *argv[])
76 // load the cmd options
77 if ( init_config_from_cmd(argc,argv) != 0 )
80 // load the config and service files
81 if ( init_config_from_files() != 0 )
84 // init all helper classes
85 if ( init_helper_classes() != 0 )
93 * Reloading the config. Delete all Service objects and then init new Service objects from config files.
95 int Updater::reload_config()
97 // serialize all service objects
98 if ( ServiceHolder->serialize_services() != 0 )
101 // delete all service objects
102 ServiceHolder->delete_services();
104 // delete the actual Variables_map, perhaps with old cmd options which would overwrite new config file options.
105 Conf->delete_variables_map();
107 // load only config files
108 if ( init_config_from_files() != 0 )
111 // init all helper classes
112 if ( init_helper_classes() != 0 )
120 * Parse the command line arguments and initialize corresponding options.
121 * @param argc Number command line arguments.
122 * @param argv[] Array with arguments.
123 * @return 0 if cmd options successfully parsed, 1 if usage or version.
125 int Updater::init_config_from_cmd(int argc, char *argv[])
127 // Load the command line parameters
128 if( Conf->parse_cmd_line( argc, argv) != 0)
131 // If we have loaded the cmd options we need to init the log facility immediately in case debugging is enabled from cmd.
135 Log->print_cmd_parsed();
141 * Load the main config and the service definition files in config path.
142 * @return 0 if all is fine,
144 int Updater::init_config_from_files()
146 // Load the main and service config files in config path
147 if ( Conf->load_config_from_files() != 0 )
150 // Re-init log facility, perhaps new config file options for logger are set.
151 // These config file options will only overwrite the cmd options if the SIGHUP (reload config) is caught.
154 // Here we are. All Service Objects should be initialized, so it is time to deserialize the old service objects and compare them.
155 if ( ServiceHolder->deserialize_services() != 0 )
159 Log->print_conf_files_parsed();
165 * Init all Helper classes
168 int Updater::init_helper_classes()
170 // Initialize IPHelper
171 if ( init_ip_helper() != 0 )
179 * Init the IPHelp member with needed values.
180 * @return 0 if all is fine, -1 otherwise.
182 int Updater::init_ip_helper()
184 // initialize IPHelper
185 IPAddrHelper::Ptr _ipaddrhelp(new IPAddrHelper(Log,Conf->get_webcheck_ip_url(),Conf->get_webcheck_ip_url_alt(),Conf->get_enable_ipv6(),Conf->get_proxy(),Conf->get_proxy_port()));
186 IPAddrHelp.swap(_ipaddrhelp);
193 * Getter for member Config.
194 * @return Member Config.
196 Config::Ptr Updater::get_config() const
203 * Getter for member Logger.
204 * @return Member Logger.
206 Logger::Ptr Updater::get_logger() const
213 * Initialize the logging facility with loglevel and syslog.
215 void Updater::init_log_facility()
217 Log->set_log_facility(Conf->get_loglevel(),Conf->get_syslog(),Conf->get_external_warning_log(),Conf->get_external_warning_level());
218 Log->print_init_log_facility();
223 * Update all configured services.
225 void Updater::update_services()
227 list<Service::Ptr> services = ServiceHolder->get_services();
229 string ip = IPAddrHelp->get_actual_ip();
233 BOOST_FOREACH(Service::Ptr &service, services )
235 string dns_recheck_ip = ip;
236 int current_time = time(NULL);
239 if ( service->get_last_updates()->size() > 0 )
240 lastupdated = service->get_last_updates()->front();
242 // 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)
243 if ( ((lastupdated != 0) && ((lastupdated + service->get_dns_cache_ttl()) < current_time)) || (lastupdated == 0) )
245 Log->print_recheck_dns_entry(service->get_hostname(),lastupdated,service->get_dns_cache_ttl(),current_time);
246 string _dns_recheck_ip = IPAddrHelp->dns_query(service->get_hostname());
247 Log->print_cached_dns_entry(service->get_hostname(), _dns_recheck_ip, service->get_actual_ip());
248 if (!_dns_recheck_ip.empty())
249 dns_recheck_ip = _dns_recheck_ip;
252 // In case the local hosts IP (ip) differ from the IP set in the last update (actual_ip) or
253 // the IP of the dns record (dns_recheck_ip) differs from the IP of the local host (ip)
254 // then perform an update. This implies that the update is not performed if actual_ip == dns_recheck_ip.
255 // Special case when latupdated == 0 then only perform the update if dns_rechek_ip differs from ip
256 if ( ((service->get_actual_ip() != ip) && (lastupdated != 0)) || (dns_recheck_ip != ip) )
257 service->update(ip,current_time);
258 else if ( (service->get_actual_ip() != ip) && (lastupdated == 0) )
259 service->set_actual_ip(ip);
266 * Getter for member ServiceHolder.
267 * @return ServiceHolder
269 Serviceholder::Ptr Updater::get_service_holder() const
271 return ServiceHolder;