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_term = false;
37 * Checks if a bpdyndnsd process is already running.
38 * @param updater Shared Pointer to updater, needed for logging.
39 * @return 0 if process not running already or pid of already running process.
41 int check_for_running_process()
43 ifstream pidfile(PIDFILE);
44 if ( pidfile.is_open() )
49 updater->get_logger()->print_pid_found(pid);
53 // check if process still running ret_val==-1 -> not runnig, ret_val==0 -> running
54 if ( kill(pid,0) == 0)
56 updater->get_logger()->print_process_already_running(pid);
67 * Writes the pid into the pidfile.
68 * @param pid The process's pid.
70 int write_pidfile(int pid)
72 ofstream pidfile(PIDFILE);
73 if ( pidfile.is_open() )
75 pidfile << pid << endl;
79 updater->get_logger()->print_error_opening_rw(PIDFILE);
88 * Parent shutdown function
89 * @return 0 if all is fine, -1 otherwise
91 int shutdown_parent(bool remove_pid, int ret_val)
93 // starting shutdown_parent
94 updater->get_logger()->print_starting_shutdown_parent();
96 // remove pidfile if requested
100 // shutdown parent complete
101 updater->get_logger()->print_shutdown_parent_succeeded();
103 // release shared pointer
112 * @return 0 if all is fine, -1 otherwise
119 updater->get_logger()->print_starting_shutdown();
121 // serialize actual service objects
122 if ( updater->get_service_holder()->serialize_services() != 0 )
129 updater->get_logger()->print_shutdown_succeeded();
131 // release shared pointer
139 * Signal SIGTERM caught (exit program)
140 * @param param Parameter from the signal interface.
142 void sigterm_func(int param)
144 caught_sig_term = true;
149 * Signal SIGUSR1 caught (switch to offline mode)
150 * @param param Parameter from the signal interface.
152 void sigusr1_func(int param)
154 caught_sig_usr1 = true;
159 * Signal SIGHUP caught (reload config)
160 * @param param Parameter from the signal interface.
162 void sighup_func(int param)
164 caught_sig_hup = true;
169 * Signal SIGUSR2 caught (switch to online mode)
170 * @param param Parameter from the signal interface.
172 void sigusr2_func(int param)
174 caught_sig_usr2 = true;
179 * Signal SIGRTMIN caught (switch to online mode with webcheck enabled)
180 * @param param Parameter from the signal interface.
182 void sigrtmin_func(int param)
184 caught_sig_rtmin = true;
189 * Initialize the signals we handle.
190 * @return 0 if all is fine, -1 on error.
194 sighandler_t ret_val;
195 ret_val = signal(SIGTERM, sigterm_func);
196 if ( ret_val == SIG_ERR )
198 updater->get_logger()->print_error_setting_signal("SIGTERM");
201 ret_val = signal(SIGUSR1, sigusr1_func);
202 if ( ret_val == SIG_ERR )
204 updater->get_logger()->print_error_setting_signal("SIGUSR1");
207 ret_val = signal(SIGHUP, sighup_func);
208 if ( ret_val == SIG_ERR )
210 updater->get_logger()->print_error_setting_signal("SIGHUP");
213 ret_val = signal(SIGUSR2, sigusr2_func);
214 if ( ret_val == SIG_ERR )
216 updater->get_logger()->print_error_setting_signal("SIGUSR2");
219 ret_val = signal(SIGRTMIN, sigrtmin_func);
220 if ( ret_val == SIG_ERR )
222 updater->get_logger()->print_error_setting_signal("SIGRTMIN");
231 * Try to run in daemon mode if enabled in config.
232 * @param daemon_mode True if process should detach to init (run as daemon), false if not detach to init.
233 * @return 0 if all is fine, -1 on error.
235 int init_daemon_mode(bool daemon_mode)
237 updater->get_logger()->print_daemon_mode(daemon_mode);
238 if ( daemon_mode == true )
244 updater->get_logger()->print_error_fork();
249 // parent continues here
250 if ( write_pidfile(pid) != 0 )
252 if ( kill(pid,SIGTERM) != 0 )
254 updater->get_logger()->print_error_kill_child(pid);
255 shutdown_parent(false,-1); /*lint !e534 */
259 updater->get_logger()->print_child_killed(pid);
260 shutdown_parent(true,-1); /*lint !e534 */
263 updater->get_logger()->print_runnig_as_daemon(pid);
264 shutdown_parent(false,0); /*lint !e534 */
270 if ( write_pidfile(getpid()) != 0 )
272 shutdown(); /*lint !e534 */
280 * @brief The main part.
281 * @param argc Number of arguments
282 * @param argv Command line arguments
283 * @return 0 if all is fine.
285 int main(int argc, char *argv[])
287 // initialize Updater
288 updater = Updater::Ptr(new Updater);
290 // load config and initialize helper classes
291 if ( updater->load_config(argc,argv) != 0 )
294 // open pidfile and check for running process
295 if ( check_for_running_process() != 0)
298 // init signal handling
299 if ( init_signals() != 0)
302 // init daemon_mode if enabled
303 if ( init_daemon_mode(updater->get_config()->get_daemon_mode()) != 0 )
306 // Should we start in offline mode?
307 bool old_online_state = false;
308 bool is_online = !updater->get_config()->get_start_offline();
309 bool webcheck_enabled = updater->get_config()->get_webcheck_enabled();
311 // One shot run if daemon mode is disabled
312 if (updater->get_config()->get_daemon_mode() != 1)
315 // service processing starts here
321 caught_sig_usr1 = false;
322 updater->get_logger()->print_caught_siguser1();
326 } else if (caught_sig_usr2)
328 caught_sig_usr2 = false;
329 updater->get_logger()->print_caught_siguser2();
333 webcheck_enabled = false;
334 } else if (caught_sig_rtmin)
336 caught_sig_rtmin = false;
337 updater->get_logger()->print_caught_sigrtmin();
339 // Go online - with webcheck
341 webcheck_enabled = true;
342 } else if (caught_sig_term)
344 caught_sig_term = false;
345 updater->get_logger()->print_caught_sigterm();
348 } else if (caught_sig_hup)
350 caught_sig_hup = false;
351 updater->get_logger()->print_caught_sighup();
353 if ( updater->reload_config() != 0 )
355 updater->get_logger()->print_conf_reload_failed_exit();
361 if ( is_online == true )
363 // Check if webcheck_enabled differs due to caught singnal then set it in config correspondingly
364 if ( updater->get_config()->get_webcheck_enabled() != webcheck_enabled ) /*lint !e731 */
365 updater->get_config()->set_webcheck_enabled(webcheck_enabled);
367 // update all configured services
368 updater->update_services(is_online != old_online_state);
372 // We are in offline mode, do nothing, expect printing "offline mode".
373 updater->get_logger()->print_offline_mode();
376 // Keep old online state so we can determine
377 // if we switched from offline to online
378 old_online_state = is_online;
380 // Snore, snore... don't hog the cpu if we are in daemon_mode.
382 sleep(10); /*lint !e534 */
383 } while ( !exit_now );
385 // Serialize services to save their actual state.
386 if ( shutdown() != 0 )