2 * @brief The main function.
6 * @copyright Intra2net AG
14 #define PIDFILE "/var/run/bpdyndnsd/bpdyndnsd.pid"
20 #include <boost/foreach.hpp>
21 #include <sys/types.h>
24 #include "updater.hpp"
29 volatile bool exit_now = false;
30 volatile bool caught_sig_hup = false;
31 volatile bool caught_sig_usr1 = false;
32 volatile bool caught_sig_usr2 = false;
33 volatile bool caught_sig_rtmin = false;
34 volatile bool caught_sig_rtmax = false;
35 volatile bool caught_sig_term = false;
38 * Checks if a bpdyndnsd process is already running.
39 * @param updater Shared Pointer to updater, needed for logging.
40 * @return 0 if process not running already or pid of already running process.
42 int check_for_running_process()
44 ifstream pidfile(PIDFILE);
45 if ( pidfile.is_open() )
50 updater->get_logger()->print_pid_found(pid);
54 // check if process still running ret_val==-1 -> not runnig, ret_val==0 -> running
55 if ( kill(pid,0) == 0)
57 updater->get_logger()->print_process_already_running(pid);
68 * Writes the pid into the pidfile.
69 * @param pid The process's pid.
71 int write_pidfile(int pid)
73 ofstream pidfile(PIDFILE);
74 if ( pidfile.is_open() )
76 pidfile << pid << endl;
80 updater->get_logger()->print_error_opening_rw(PIDFILE);
89 * Parent shutdown function
90 * @return 0 if all is fine, -1 otherwise
92 int shutdown_parent(bool remove_pid, int ret_val)
94 // starting shutdown_parent
95 updater->get_logger()->print_starting_shutdown_parent();
97 // remove pidfile if requested
101 // shutdown parent complete
102 updater->get_logger()->print_shutdown_parent_succeeded();
104 // release shared pointer
113 * @return 0 if all is fine, -1 otherwise
120 updater->get_logger()->print_starting_shutdown();
122 // serialize actual service objects
123 if ( updater->get_service_holder()->serialize_services() != 0 )
130 updater->get_logger()->print_shutdown_succeeded();
132 // release shared pointer
140 * Signal SIGTERM caught (exit program)
141 * @param param Parameter from the signal interface.
143 void sigterm_func(int param)
145 caught_sig_term = true;
150 * Signal SIGUSR1 caught (switch to offline mode)
151 * @param param Parameter from the signal interface.
153 void sigusr1_func(int param)
155 caught_sig_usr1 = true;
160 * Signal SIGHUP caught (reload config and reset log level)
161 * @param param Parameter from the signal interface.
163 void sighup_func(int param)
165 caught_sig_hup = true;
170 * Signal SIGUSR2 caught (switch to online mode)
171 * @param param Parameter from the signal interface.
173 void sigusr2_func(int param)
175 caught_sig_usr2 = true;
180 * Signal SIGRTMIN caught (switch to online mode with webcheck enabled)
181 * @param param Parameter from the signal interface.
183 void sigrtmin_func(int param)
185 caught_sig_rtmin = true;
190 * Signal SIGRTMAX caught (increase log level)
191 * @param param Parameter from the signal interface.
193 void sigrtmax_func(int param)
195 caught_sig_rtmax = true;
200 * Initialize the signals we handle.
201 * @return 0 if all is fine, -1 on error.
205 sighandler_t ret_val;
206 ret_val = signal(SIGTERM, sigterm_func);
207 if ( ret_val == SIG_ERR )
209 updater->get_logger()->print_error_setting_signal("SIGTERM");
212 ret_val = signal(SIGUSR1, sigusr1_func);
213 if ( ret_val == SIG_ERR )
215 updater->get_logger()->print_error_setting_signal("SIGUSR1");
218 ret_val = signal(SIGHUP, sighup_func);
219 if ( ret_val == SIG_ERR )
221 updater->get_logger()->print_error_setting_signal("SIGHUP");
224 ret_val = signal(SIGUSR2, sigusr2_func);
225 if ( ret_val == SIG_ERR )
227 updater->get_logger()->print_error_setting_signal("SIGUSR2");
230 ret_val = signal(SIGRTMIN, sigrtmin_func);
231 if ( ret_val == SIG_ERR )
233 updater->get_logger()->print_error_setting_signal("SIGRTMIN");
236 ret_val = signal(SIGRTMAX, sigrtmax_func);
237 if ( ret_val == SIG_ERR )
239 updater->get_logger()->print_error_setting_signal("SIGRTMAX");
248 * Try to run in daemon mode if enabled in config.
249 * @param daemon_mode True if process should detach to init (run as daemon), false if not detach to init.
250 * @return 0 if all is fine, -1 on error.
252 int init_daemon_mode(bool daemon_mode)
254 updater->get_logger()->print_daemon_mode(daemon_mode);
255 if ( daemon_mode == true )
261 updater->get_logger()->print_error_fork();
266 // parent continues here
267 if ( write_pidfile(pid) != 0 )
269 if ( kill(pid,SIGTERM) != 0 )
271 updater->get_logger()->print_error_kill_child(pid);
272 shutdown_parent(false,-1); /*lint !e534 */
276 updater->get_logger()->print_child_killed(pid);
277 shutdown_parent(true,-1); /*lint !e534 */
280 updater->get_logger()->print_runnig_as_daemon(pid);
281 shutdown_parent(false,0); /*lint !e534 */
287 if ( write_pidfile(getpid()) != 0 )
289 shutdown(); /*lint !e534 */
297 * @brief The main part.
298 * @param argc Number of arguments
299 * @param argv Command line arguments
300 * @return 0 if all is fine.
302 int main(int argc, char *argv[])
304 // initialize Updater
305 updater = Updater::Ptr(new Updater);
307 // load config and initialize helper classes
308 if ( updater->load_config(argc,argv) != 0 )
311 // open pidfile and check for running process
312 if ( check_for_running_process() != 0)
315 // init signal handling
316 if ( init_signals() != 0)
319 // init daemon_mode if enabled
320 if ( init_daemon_mode(updater->get_config()->get_daemon_mode()) != 0 )
323 // Should we start in offline mode?
324 bool old_online_state = false;
325 bool is_online = !updater->get_config()->get_start_offline();
326 bool webcheck_enabled = updater->get_config()->get_webcheck_enabled();
328 // One shot run if daemon mode is disabled
329 if (updater->get_config()->get_daemon_mode() != 1)
332 // Tell the world we are running
333 updater->get_logger()->print_started();
335 int original_log_level = updater->get_logger()->get_loglevel();
337 // service processing starts here
343 caught_sig_usr1 = false;
344 updater->get_logger()->print_caught_siguser1();
348 } else if (caught_sig_usr2)
350 caught_sig_usr2 = false;
351 updater->get_logger()->print_caught_siguser2();
355 webcheck_enabled = false;
356 } else if (caught_sig_rtmin)
358 caught_sig_rtmin = false;
359 updater->get_logger()->print_caught_sigrtmin();
361 // Go online - with webcheck
363 webcheck_enabled = true;
364 } else if (caught_sig_rtmax)
366 caught_sig_rtmax = false;
368 // Increase log level
369 int new_loglevel = updater->get_logger()->get_loglevel() + 1;
370 updater->get_logger()->print_caught_sigrtmax(new_loglevel);
371 updater->get_logger()->set_loglevel(new_loglevel);
372 } else if (caught_sig_term)
374 caught_sig_term = false;
375 updater->get_logger()->print_caught_sigterm();
378 } else if (caught_sig_hup)
380 caught_sig_hup = false;
381 updater->get_logger()->print_caught_sighup();
383 if ( updater->reload_config() != 0 )
385 updater->get_logger()->print_conf_reload_failed_exit();
389 // Reset log level to startup log level in case it got elevated by SIGRTMAX
390 updater->get_logger()->set_loglevel(original_log_level);
394 if ( is_online == true )
396 // Check if webcheck_enabled differs due to caught singnal then set it in config correspondingly
397 if ( updater->get_config()->get_webcheck_enabled() != webcheck_enabled ) /*lint !e731 */
398 updater->get_config()->set_webcheck_enabled(webcheck_enabled);
400 // update all configured services
401 updater->update_services(is_online != old_online_state);
405 // We are in offline mode, do nothing, expect printing "offline mode".
406 updater->get_logger()->print_offline_mode();
409 // Keep old online state so we can determine
410 // if we switched from offline to online
411 old_online_state = is_online;
413 // Snore, snore... don't hog the cpu if we are in daemon_mode.
415 sleep(10); /*lint !e534 */
416 } while ( !exit_now );
418 // Serialize services to save their actual state.
419 if ( shutdown() != 0 )