2 * @brief The updater class implementation. This class implements the updater logic.
6 * @copyright Intra2net AG
10 #include "updater.hpp"
12 #include "serviceholder.hpp"
15 #include <boost/foreach.hpp>
16 #include <boost/serialization/export.hpp>
23 * Default constructor which initializes the member Conf.
26 : IPAddrHelp(new IPAddrHelper)
28 // Initialize program wide Logger, at this point we don't know where to log and with which loglevel.
29 Log = Logger::Ptr(new Logger);
31 // initialize Serviceholder
32 ServiceHolder = Serviceholder::Ptr(new Serviceholder(Log));
35 Conf = Config::Ptr(new Config(Log,ServiceHolder));
49 * Load config and initialize helper classes.
50 * @param argc Number of arguments in array
51 * @param argv Array with cmd options
53 int Updater::load_config(int argc, char *argv[])
55 // load the cmd options
56 if ( init_config_from_cmd(argc,argv) != 0 )
59 // load the config and service files
60 if ( init_config_from_files() != 0 )
63 // init all helper classes
64 if ( init_helper_classes() != 0 )
72 * Reloading the config. Delete all Service objects and then init new Service objects from config files.
74 int Updater::reload_config()
76 // serialize all service objects
77 if ( ServiceHolder->serialize_services() != 0 )
80 // delete all service objects
81 ServiceHolder->delete_services();
83 // delete the actual Variables_map, perhaps with old cmd options which would overwrite new config file options.
84 Conf->delete_variables_map();
86 // clear the external send messages.
87 Log->clear_external_send_messages();
89 // load only config files
90 if ( init_config_from_files() != 0 )
93 // init all helper classes
94 if ( init_helper_classes() != 0 )
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.
107 int Updater::init_config_from_cmd(int argc, char *argv[]) const
109 // Load the command line parameters
110 if( Conf->parse_cmd_line( argc, argv) != 0)
113 // If we have loaded the cmd options we need to init the log facility immediately in case debugging is enabled from cmd.
117 Log->print_cmd_parsed();
123 * Load the main config and the service definition files in config path.
124 * @return 0 if all is fine,
126 int Updater::init_config_from_files() const
128 // Load the main and service config files in config path
129 if ( Conf->load_config_from_files() != 0 )
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.
136 // Here we are. All Service Objects should be initialized, so it is time to deserialize the old service objects and compare them.
137 if ( ServiceHolder->deserialize_services() != 0 )
141 Log->print_conf_files_parsed();
147 * Init all Helper classes
150 int Updater::init_helper_classes()
152 // Initialize IPHelper
153 if ( init_ip_helper() != 0 )
161 * Init the IPHelp member with needed values.
162 * @return 0 if all is fine, -1 otherwise.
164 int Updater::init_ip_helper()
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 )
170 // Initialize IPHelper
171 IPAddrHelp = IPAddrHelper::Ptr( 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() ) );
175 // IPAddrHelper from ServiceHolder was not declared, so init oen with LastWebcheck 0
176 IPAddrHelp = IPAddrHelper::Ptr( new IPAddrHelper( Log, Conf->get_webcheck_ip_url(), Conf->get_webcheck_ip_url_alt(), Conf->get_webcheck_interval(), (size_t)0, Conf->get_enable_ipv6(), Conf->get_proxy(), Conf->get_proxy_port() ) );
179 // Put the IPAddrHelper into ServiceHolder, so the LastWebcheck state will be serialized too.
180 ServiceHolder->set_ip_addr_helper(IPAddrHelp);
187 * Getter for member Config.
188 * @return Member Config.
190 Config::Ptr Updater::get_config() const
197 * Getter for member Logger.
198 * @return Member Logger.
200 Logger::Ptr Updater::get_logger() const
207 * Initialize the logging facility with loglevel and syslog.
209 void Updater::init_log_facility() const
211 Log->set_log_facility(Conf->get_loglevel(),Conf->get_syslog(),Conf->get_external_warning_log(),Conf->get_external_warning_level(),Conf->get_external_log_only_once());
212 Log->print_init_log_facility();
217 * Update all configured services.
218 * @param changed_to_online True if we just changed to online, false if we were already online
220 void Updater::update_services(bool changed_to_online) const
222 // Get all services from the ServiceHolder.
223 list<Service::Ptr> services = ServiceHolder->get_services();
225 // Get the actual IP of this host.
226 string ip_host = IPAddrHelp->get_actual_ip(Conf->get_webcheck_enabled(), changed_to_online);
227 if ( ip_host.empty() )
229 Log->print_no_wan_ip(changed_to_online);
233 Log->print_external_wan_ip(changed_to_online, ip_host);
236 BOOST_FOREACH(Service::Ptr &service, services )
238 string ip_last_update = service->get_actual_ip();
239 string hostname = service->get_hostname();
240 time_t lastupdated = 0;
241 time_t current_time = time(NULL);
243 // Try to get the lastupdated time of the actual service if there is one.
244 if ( !service->get_last_updates().empty() )
245 lastupdated = service->get_last_updates().front(); /*lint !e1793 */
247 Log->print_check_service_update(hostname, current_time, lastupdated);
249 // Do a DNS Query for the dynamic hostname.
250 string ip_dns_recheck = IPAddrHelp->dns_query(hostname);
252 Log->print_cached_dns_entry(hostname, ip_dns_recheck, ip_last_update, ip_host);
254 // Test if the DNS-Record could not be found.
255 if ( ip_dns_recheck.empty() )
257 Log->print_dns_lookup_failed(changed_to_online, hostname);
261 // Test if the actual DNS-Record differs from the host's IP.
262 if (ip_host == ip_dns_recheck )
264 Log->print_no_update_needed(changed_to_online, hostname, ip_dns_recheck, ip_last_update, ip_host, lastupdated);
269 // Check if the IP set in last update differs from the actual host's ip.
270 if ( ip_last_update != ip_host )
273 Log->print_update_service(hostname, ip_dns_recheck, ip_last_update, ip_host, lastupdated);
274 service->update(ip_host, current_time, changed_to_online);
278 int dns_cache_ttl = service->get_dns_cache_ttl();
279 // Check if DNS Cache TTL is expired, if so, then update the same IP again.
280 if ( (lastupdated + dns_cache_ttl) < current_time )
283 Log->print_update_service_ttl_expired(hostname, ip_dns_recheck, ip_last_update, ip_host, lastupdated, dns_cache_ttl, current_time);
284 service->update(ip_host, current_time, changed_to_online);
288 // DNS cache TTL isn't expired
289 Log->print_update_service_ttl_not_expired(changed_to_online, hostname, ip_dns_recheck, ip_last_update, ip_host, lastupdated, dns_cache_ttl, current_time);
297 * Getter for member ServiceHolder.
298 * @return ServiceHolder
300 Serviceholder::Ptr Updater::get_service_holder() const
302 return ServiceHolder;