Added cmake search for curl.
[bpdyndnsd] / src / main.cpp
CommitLineData
b1be615b
BS
1/** @file
2 * @brief The main function.
3 *
4 *
5 *
6 * @copyright Intra2net AG
7 * @license GPLv2
8*/
4545a371
BS
9
10#ifdef HAVE_CONFIG_H
11#include <config.h>
12#endif
13
14#define VERSION 0
15#define REVISION 1
16#define RELEASE 0
17
388f4ab0 18#define PIDFILE "/var/run/bpdyndnsd.pid"
27baf279 19#define OBJECT_FILE "/home/bjoern/intranator/bpdyndnsd/objects.ser"
388f4ab0 20
4545a371 21#include <iostream>
88a594e8 22#include <fstream>
4545a371
BS
23#include <list>
24#include <string>
4545a371 25#include <boost/foreach.hpp>
88a594e8
BS
26#include <sys/types.h>
27#include <signal.h>
28
29#include "updater.h"
4545a371 30
4545a371 31#include "config.cpp"
88a594e8 32#include "dhs.cpp"
254bbf53 33#include "logger.cpp"
88a594e8 34#include "ods.cpp"
4545a371 35#include "service.cpp"
27baf279 36#include "serviceholder.cpp"
88a594e8 37#include "updater.cpp"
0665b239 38#include "iphelper.cpp"
4545a371 39
388f4ab0 40
4545a371
BS
41using namespace std;
42
88a594e8 43Updater::Ptr updater;
98dd88bd 44bool is_online = true;
c5675c01 45
4545a371 46/**
388f4ab0
BS
47 * Checks if a bpdyndnsd process is already running.
48 * @param updater Shared Pointer to updater, needed for logging.
49 * @return 0 if process not running already or pid of already running process.
50 */
c5675c01 51int check_for_running_process()
388f4ab0
BS
52{
53 ifstream pidfile(PIDFILE);
54 if ( pidfile.is_open() )
55 {
56 int pid;
57 pidfile >> pid;
58 if ( pid > 0 )
59 updater->get_logger()->print_pid_found(pid);
60 else
61 return 0;
62
63 // check if process still running ret_val==-1 -> not runnig, ret_val==0 -> running
64 if ( kill(pid,0) == 0)
65 {
66 updater->get_logger()->print_process_already_running(pid);
67 pidfile.close();
68 return pid;
69 }
70 }
71 pidfile.close();
72 return 0;
73}
74
c5675c01
BS
75
76/**
77 * Writes the pid into the pidfile.
78 * @param pid The process's pid.
79 */
667c672c 80int write_pidfile(int pid)
388f4ab0
BS
81{
82 ofstream pidfile(PIDFILE);
83 if ( pidfile.is_open() )
84 {
85 pidfile << pid << endl;
86 }
667c672c
BS
87 else
88 {
89 updater->get_logger()->print_error_opening_rw(PIDFILE);
90 return -1;
91 }
388f4ab0 92 pidfile.close();
667c672c 93 return 0;
388f4ab0
BS
94}
95
c5675c01
BS
96
97/**
98 * Signal SIGTERM caught, releasing resources and exit.
99 * @param param Parameter from the signal interface.
100 */
101void terminate(int param)
102{
103 updater->get_logger()->print_caught_sigterm();
2bc1878a
BS
104
105 // unfortunately we can't call serialize_services in any destructor
106 // cause some singleton are already destroyed !?!
667c672c
BS
107 if ( updater->get_config()->serialize_services() != 0 )
108 {
109 updater.reset();
110 exit(-1);
111 }
c5675c01 112 updater.reset();
39acb828 113 exit(0);
c5675c01
BS
114}
115
116
2bc1878a 117
c5675c01
BS
118/**
119 * Signal SIGUSR1 caught, switching to offline mode.
120 * @param param Parameter from the signal interface.
121 */
122void switch_to_offline(int param)
123{
8bca3c5d 124 updater->get_logger()->print_caught_siguser1();
98dd88bd 125 is_online = false;
c5675c01
BS
126}
127
128
129/**
130 * Signal SIGHUP caught, reloading config and switching to online mode.
39acb828 131 * @param param Parameter from the signal interface.
c5675c01
BS
132 */
133void reload_config(int param)
134{
8bca3c5d 135 updater->get_logger()->print_caught_sighup();
667c672c
BS
136 if ( updater->reload_config() != 0 )
137 exit(-1);
98dd88bd 138 is_online = true;
c5675c01
BS
139}
140
141
142/**
143 * Initialize the signals we handle.
144 */
8bca3c5d 145int init_signals()
c5675c01 146{
8bca3c5d
BS
147 sighandler_t ret_val;
148 ret_val = signal(SIGTERM,terminate);
149 if ( ret_val == SIG_ERR )
667c672c
BS
150 {
151 updater->get_logger()->print_error_setting_signal("SIGTERM");
8bca3c5d 152 return -1;
667c672c 153 }
8bca3c5d
BS
154 ret_val = signal(SIGUSR1,switch_to_offline);
155 if ( ret_val == SIG_ERR )
667c672c
BS
156 {
157 updater->get_logger()->print_error_setting_signal("SIGUSR1");
8bca3c5d 158 return -1;
667c672c 159 }
8bca3c5d
BS
160 ret_val = signal(SIGHUP,reload_config);
161 if ( ret_val == SIG_ERR )
667c672c
BS
162 {
163 updater->get_logger()->print_error_setting_signal("SIGHUP");
8bca3c5d 164 return -1;
667c672c 165 }
5ac72dd8
BS
166
167 return 0;
c5675c01
BS
168}
169
170
388f4ab0 171/**
584b9407
BS
172 * Try to run in daemon mode if enabled in config.
173 * @param daemon_mode True if process should detach to init (run as daemon), false if not detach to init.
174 * @return 0 if all is fine, -1 on error.
175 */
176int init_daemon_mode(bool daemon_mode)
177{
178 updater->get_logger()->print_daemon_mode(daemon_mode);
179 if ( daemon_mode == true )
180 {
181 int pid = fork();
182 if ( pid < 0 )
183 {
184 // error fork
185 updater->get_logger()->print_error_fork();
186 return -1;
187 }
188 else if ( pid > 0 )
189 {
190 // parent continues here
191 if ( write_pidfile(pid) != 0 )
192 {
193 if ( kill(pid,SIGTERM) != 0 )
194 updater->get_logger()->print_error_kill_child(pid);
195 else
196 updater->get_logger()->print_child_killed(pid);
197 exit(-1);
198 }
199 updater->get_logger()->print_runnig_as_daemon(pid);
200 exit(0);
201 }
202 // child starts here
203 }
204 return 0;
205}
206
207/**
b1be615b
BS
208 * @brief The main part.
209 * @param argc Number of arguments
210 * @param argv Command line arguments
211 * @return 0 if all is fine.
4545a371
BS
212 */
213int main(int argc, char *argv[])
214{
38060291 215 // initialize Updater
88a594e8 216 Updater::Ptr _updater(new Updater);
c5675c01
BS
217 updater = _updater;
218 _updater.reset();
38060291 219
254bbf53 220 // load the cmd options
38060291 221 if ( updater->init_config_from_cmd(argc,argv) != 0 )
667c672c 222 return -1;
38060291 223
254bbf53 224 // load the config and service files
38060291 225 if ( updater->init_config_from_files() != 0 )
667c672c 226 return -1;
4545a371 227
388f4ab0 228 // open pidfile and check for running process
c5675c01 229 if ( check_for_running_process() != 0)
667c672c 230 return -1;
3434b35f 231
c5675c01 232 // init signal handling
8bca3c5d 233 if ( init_signals() != 0)
667c672c 234 return -1;
254bbf53 235
0665b239
BS
236 // init the ip_helper
237 if ( updater->init_ip_helper() != 0 )
238 return -1;
239
584b9407
BS
240 // init daemon_mode if enabled
241 if ( init_daemon_mode(updater->get_config()->get_daemon_mode()) != 0 )
242 return -1;
388f4ab0
BS
243
244 // service processing starts here
245 do
246 {
98dd88bd 247 if ( is_online == true )
c5675c01
BS
248 {
249 // update all configured services
250 updater->update_services();
251 }
8bca3c5d
BS
252 else
253 {
50d63110 254 // We are in offline mode, do nothing, expect printing "offline mode".
8bca3c5d
BS
255 updater->get_logger()->print_offline_mode();
256 }
388f4ab0 257
50d63110 258 // Snore, snore... don't hug the cpu if we are in daemon_mode.
59c8d63c 259 if ( updater->get_config()->get_daemon_mode() == 1 )
584b9407 260 sleep(5);
59c8d63c
BS
261
262 }while ( updater->get_config()->get_daemon_mode() == 1 );
4545a371 263
2bc1878a 264
50d63110 265 // Serialize services to save their actual state.
667c672c
BS
266 if ( updater->get_config()->serialize_services() != 0 )
267 return -1;
2bc1878a 268
4545a371
BS
269 return 0;
270}