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;
33 * Checks if a bpdyndnsd process is already running.
34 * @param updater Shared Pointer to updater, needed for logging.
35 * @return 0 if process not running already or pid of already running process.
37 int check_for_running_process()
39 ifstream pidfile(PIDFILE);
40 if ( pidfile.is_open() )
45 updater->get_logger()->print_pid_found(pid);
49 // check if process still running ret_val==-1 -> not runnig, ret_val==0 -> running
50 if ( kill(pid,0) == 0)
52 updater->get_logger()->print_process_already_running(pid);
63 * Writes the pid into the pidfile.
64 * @param pid The process's pid.
66 int write_pidfile(int pid)
68 ofstream pidfile(PIDFILE);
69 if ( pidfile.is_open() )
71 pidfile << pid << endl;
75 updater->get_logger()->print_error_opening_rw(PIDFILE);
84 * Parent shutdown function
85 * @return 0 if all is fine, -1 otherwise
87 int shutdown_parent(bool remove_pid, int ret_val)
89 // starting shutdown_parent
90 updater->get_logger()->print_starting_shutdown_parent();
92 // remove pidfile if requested
96 // shutdown parent complete
97 updater->get_logger()->print_shutdown_parent_succeeded();
99 // release shared pointer
108 * @return 0 if all is fine, -1 otherwise
115 updater->get_logger()->print_starting_shutdown();
117 // serialize actual service objects
118 if ( updater->get_service_holder()->serialize_services() != 0 )
125 updater->get_logger()->print_shutdown_succeeded();
127 // release shared pointer
135 * Signal SIGTERM caught, releasing resources and exit.
136 * @param param Parameter from the signal interface.
138 void terminate(int param)
140 updater->get_logger()->print_caught_sigterm();
147 * Signal SIGUSR1 caught, switching to offline mode.
148 * @param param Parameter from the signal interface.
150 void switch_to_offline(int param)
152 updater->get_logger()->print_caught_siguser1();
158 * Signal SIGHUP caught, reloading config.
159 * @param param Parameter from the signal interface.
161 void reload_config(int param)
163 updater->get_logger()->print_caught_sighup();
164 if ( updater->reload_config() != 0 )
170 * Signal SIGUSR2 caught, switching to online mode.
171 * @param param Parameter from the signal interface.
173 void switch_to_online(int param)
175 updater->get_logger()->print_caught_siguser2();
177 webcheck_enabled = false;
182 * Signal SIGRTMIN caught, switching to online mode with webcheck enabled.
183 * @param param Parameter from the signal interface.
185 void switch_to_online_webcheck(int param)
187 updater->get_logger()->print_caught_sigrtmin();
189 webcheck_enabled = true;
194 * Initialize the signals we handle.
195 * @return 0 if all is fine, -1 on error.
199 sighandler_t ret_val;
200 ret_val = signal(SIGTERM,terminate);
201 if ( ret_val == SIG_ERR )
203 updater->get_logger()->print_error_setting_signal("SIGTERM");
206 ret_val = signal(SIGUSR1,switch_to_offline);
207 if ( ret_val == SIG_ERR )
209 updater->get_logger()->print_error_setting_signal("SIGUSR1");
212 ret_val = signal(SIGHUP,reload_config);
213 if ( ret_val == SIG_ERR )
215 updater->get_logger()->print_error_setting_signal("SIGHUP");
218 ret_val = signal(SIGUSR2,switch_to_online);
219 if ( ret_val == SIG_ERR )
221 updater->get_logger()->print_error_setting_signal("SIGUSR2");
224 ret_val = signal(SIGRTMIN,switch_to_online_webcheck);
225 if ( ret_val == SIG_ERR )
227 updater->get_logger()->print_error_setting_signal("SIGRTMIN");
236 * Try to run in daemon mode if enabled in config.
237 * @param daemon_mode True if process should detach to init (run as daemon), false if not detach to init.
238 * @return 0 if all is fine, -1 on error.
240 int init_daemon_mode(bool daemon_mode)
242 updater->get_logger()->print_daemon_mode(daemon_mode);
243 if ( daemon_mode == true )
249 updater->get_logger()->print_error_fork();
254 // parent continues here
255 if ( write_pidfile(pid) != 0 )
257 if ( kill(pid,SIGTERM) != 0 )
259 updater->get_logger()->print_error_kill_child(pid);
260 shutdown_parent(false,-1); /*lint !e534 */
264 updater->get_logger()->print_child_killed(pid);
265 shutdown_parent(true,-1); /*lint !e534 */
268 updater->get_logger()->print_runnig_as_daemon(pid);
269 shutdown_parent(false,0); /*lint !e534 */
275 if ( write_pidfile(getpid()) != 0 )
277 shutdown(); /*lint !e534 */
285 * @brief The main part.
286 * @param argc Number of arguments
287 * @param argv Command line arguments
288 * @return 0 if all is fine.
290 int main(int argc, char *argv[])
292 // initialize Updater
293 updater = Updater::Ptr(new Updater);
295 // load config and initialize helper classes
296 if ( updater->load_config(argc,argv) != 0 )
299 // open pidfile and check for running process
300 if ( check_for_running_process() != 0)
303 // init signal handling
304 if ( init_signals() != 0)
307 // init daemon_mode if enabled
308 if ( init_daemon_mode(updater->get_config()->get_daemon_mode()) != 0 )
311 // Should we start in offline mode?
312 is_online = !updater->get_config()->get_start_offline();
313 webcheck_enabled = updater->get_config()->get_webcheck_enabled();
315 // service processing starts here
318 if ( is_online == true )
320 // Check if webcheck_enabled differs due to caught singnal then set it in config correspondingly
321 if ( updater->get_config()->get_webcheck_enabled() != webcheck_enabled ) /*lint !e731 */
322 updater->get_config()->set_webcheck_enabled(webcheck_enabled);
324 // update all configured services
325 updater->update_services();
329 // We are in offline mode, do nothing, expect printing "offline mode".
330 updater->get_logger()->print_offline_mode();
333 // Snore, snore... don't hug the cpu if we are in daemon_mode.
334 if ( updater->get_config()->get_daemon_mode() == 1 )
335 sleep(10); /*lint !e534 */
337 }while ( updater->get_config()->get_daemon_mode() == 1 );
339 // Serialize services to save their actual state.
340 if ( shutdown() != 0 )