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 is_online = false;
30 volatile bool webcheck_enabled = false;
31 volatile bool need_config_reload = false;
32 volatile bool exit_now = false;
35 * Checks if a bpdyndnsd process is already running.
36 * @param updater Shared Pointer to updater, needed for logging.
37 * @return 0 if process not running already or pid of already running process.
39 int check_for_running_process()
41 ifstream pidfile(PIDFILE);
42 if ( pidfile.is_open() )
47 updater->get_logger()->print_pid_found(pid);
51 // check if process still running ret_val==-1 -> not runnig, ret_val==0 -> running
52 if ( kill(pid,0) == 0)
54 updater->get_logger()->print_process_already_running(pid);
65 * Writes the pid into the pidfile.
66 * @param pid The process's pid.
68 int write_pidfile(int pid)
70 ofstream pidfile(PIDFILE);
71 if ( pidfile.is_open() )
73 pidfile << pid << endl;
77 updater->get_logger()->print_error_opening_rw(PIDFILE);
86 * Parent shutdown function
87 * @return 0 if all is fine, -1 otherwise
89 int shutdown_parent(bool remove_pid, int ret_val)
91 // starting shutdown_parent
92 updater->get_logger()->print_starting_shutdown_parent();
94 // remove pidfile if requested
98 // shutdown parent complete
99 updater->get_logger()->print_shutdown_parent_succeeded();
101 // release shared pointer
110 * @return 0 if all is fine, -1 otherwise
117 updater->get_logger()->print_starting_shutdown();
119 // serialize actual service objects
120 if ( updater->get_service_holder()->serialize_services() != 0 )
127 updater->get_logger()->print_shutdown_succeeded();
129 // release shared pointer
137 * Signal SIGTERM caught, releasing resources and exit.
138 * @param param Parameter from the signal interface.
140 void terminate(int param)
142 updater->get_logger()->print_caught_sigterm();
148 * Signal SIGUSR1 caught, switching to offline mode.
149 * @param param Parameter from the signal interface.
151 void switch_to_offline(int param)
153 updater->get_logger()->print_caught_siguser1();
159 * Signal SIGHUP caught, reloading config.
160 * @param param Parameter from the signal interface.
162 void reload_config(int param)
164 need_config_reload = true;
169 * Signal SIGUSR2 caught, switching to online mode.
170 * @param param Parameter from the signal interface.
172 void switch_to_online(int param)
174 updater->get_logger()->print_caught_siguser2();
176 webcheck_enabled = false;
181 * Signal SIGRTMIN caught, switching to online mode with webcheck enabled.
182 * @param param Parameter from the signal interface.
184 void switch_to_online_webcheck(int param)
186 updater->get_logger()->print_caught_sigrtmin();
188 webcheck_enabled = true;
193 * Initialize the signals we handle.
194 * @return 0 if all is fine, -1 on error.
198 sighandler_t ret_val;
199 ret_val = signal(SIGTERM,terminate);
200 if ( ret_val == SIG_ERR )
202 updater->get_logger()->print_error_setting_signal("SIGTERM");
205 ret_val = signal(SIGUSR1,switch_to_offline);
206 if ( ret_val == SIG_ERR )
208 updater->get_logger()->print_error_setting_signal("SIGUSR1");
211 ret_val = signal(SIGHUP,reload_config);
212 if ( ret_val == SIG_ERR )
214 updater->get_logger()->print_error_setting_signal("SIGHUP");
217 ret_val = signal(SIGUSR2,switch_to_online);
218 if ( ret_val == SIG_ERR )
220 updater->get_logger()->print_error_setting_signal("SIGUSR2");
223 ret_val = signal(SIGRTMIN,switch_to_online_webcheck);
224 if ( ret_val == SIG_ERR )
226 updater->get_logger()->print_error_setting_signal("SIGRTMIN");
235 * Try to run in daemon mode if enabled in config.
236 * @param daemon_mode True if process should detach to init (run as daemon), false if not detach to init.
237 * @return 0 if all is fine, -1 on error.
239 int init_daemon_mode(bool daemon_mode)
241 updater->get_logger()->print_daemon_mode(daemon_mode);
242 if ( daemon_mode == true )
248 updater->get_logger()->print_error_fork();
253 // parent continues here
254 if ( write_pidfile(pid) != 0 )
256 if ( kill(pid,SIGTERM) != 0 )
258 updater->get_logger()->print_error_kill_child(pid);
259 shutdown_parent(false,-1); /*lint !e534 */
263 updater->get_logger()->print_child_killed(pid);
264 shutdown_parent(true,-1); /*lint !e534 */
267 updater->get_logger()->print_runnig_as_daemon(pid);
268 shutdown_parent(false,0); /*lint !e534 */
274 if ( write_pidfile(getpid()) != 0 )
276 shutdown(); /*lint !e534 */
284 * @brief The main part.
285 * @param argc Number of arguments
286 * @param argv Command line arguments
287 * @return 0 if all is fine.
289 int main(int argc, char *argv[])
291 // initialize Updater
292 updater = Updater::Ptr(new Updater);
294 // load config and initialize helper classes
295 if ( updater->load_config(argc,argv) != 0 )
298 // open pidfile and check for running process
299 if ( check_for_running_process() != 0)
302 // init signal handling
303 if ( init_signals() != 0)
306 // init daemon_mode if enabled
307 if ( init_daemon_mode(updater->get_config()->get_daemon_mode()) != 0 )
310 // Should we start in offline mode?
311 is_online = !updater->get_config()->get_start_offline();
312 webcheck_enabled = updater->get_config()->get_webcheck_enabled();
314 // One shot run if daemon mode is disabled
315 if (updater->get_config()->get_daemon_mode() != 1)
318 // service processing starts here
321 if ( is_online == true )
323 // Check if webcheck_enabled differs due to caught singnal then set it in config correspondingly
324 if ( updater->get_config()->get_webcheck_enabled() != webcheck_enabled ) /*lint !e731 */
325 updater->get_config()->set_webcheck_enabled(webcheck_enabled);
327 // update all configured services
328 updater->update_services();
332 // We are in offline mode, do nothing, expect printing "offline mode".
333 updater->get_logger()->print_offline_mode();
336 if (need_config_reload)
338 updater->get_logger()->print_caught_sighup();
339 need_config_reload = false;
341 if ( updater->reload_config() != 0 )
343 updater->get_logger()->print_conf_reload_failed_exit();
348 // Snore, snore... don't hog the cpu if we are in daemon_mode.
350 sleep(10); /*lint !e534 */
351 } while ( !exit_now );
353 // Serialize services to save their actual state.
354 if ( shutdown() != 0 )