Fixed variable naming to I2N coding style.
[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"
4545a371 38
388f4ab0 39
4545a371
BS
40using namespace std;
41
88a594e8 42Updater::Ptr updater;
98dd88bd 43bool is_online = true;
c5675c01 44
4545a371 45/**
388f4ab0
BS
46 * Checks if a bpdyndnsd process is already running.
47 * @param updater Shared Pointer to updater, needed for logging.
48 * @return 0 if process not running already or pid of already running process.
49 */
c5675c01 50int check_for_running_process()
388f4ab0
BS
51{
52 ifstream pidfile(PIDFILE);
53 if ( pidfile.is_open() )
54 {
55 int pid;
56 pidfile >> pid;
57 if ( pid > 0 )
58 updater->get_logger()->print_pid_found(pid);
59 else
60 return 0;
61
62 // check if process still running ret_val==-1 -> not runnig, ret_val==0 -> running
63 if ( kill(pid,0) == 0)
64 {
65 updater->get_logger()->print_process_already_running(pid);
66 pidfile.close();
67 return pid;
68 }
69 }
70 pidfile.close();
71 return 0;
72}
73
c5675c01
BS
74
75/**
76 * Writes the pid into the pidfile.
77 * @param pid The process's pid.
78 */
388f4ab0
BS
79void write_pidfile(int pid)
80{
81 ofstream pidfile(PIDFILE);
82 if ( pidfile.is_open() )
83 {
84 pidfile << pid << endl;
85 }
86 pidfile.close();
87}
88
c5675c01
BS
89
90/**
91 * Signal SIGTERM caught, releasing resources and exit.
92 * @param param Parameter from the signal interface.
93 */
94void terminate(int param)
95{
96 updater->get_logger()->print_caught_sigterm();
2bc1878a
BS
97
98 // unfortunately we can't call serialize_services in any destructor
99 // cause some singleton are already destroyed !?!
100 updater->get_config()->serialize_services();
c5675c01 101 updater.reset();
39acb828 102 exit(0);
c5675c01
BS
103}
104
105
2bc1878a 106
c5675c01
BS
107/**
108 * Signal SIGUSR1 caught, switching to offline mode.
109 * @param param Parameter from the signal interface.
110 */
111void switch_to_offline(int param)
112{
8bca3c5d 113 updater->get_logger()->print_caught_siguser1();
98dd88bd 114 is_online = false;
c5675c01
BS
115}
116
117
118/**
119 * Signal SIGHUP caught, reloading config and switching to online mode.
39acb828 120 * @param param Parameter from the signal interface.
c5675c01
BS
121 */
122void reload_config(int param)
123{
8bca3c5d 124 updater->get_logger()->print_caught_sighup();
c5675c01 125 updater->reload_config();
98dd88bd 126 is_online = true;
c5675c01
BS
127}
128
129
130/**
131 * Initialize the signals we handle.
132 */
8bca3c5d 133int init_signals()
c5675c01 134{
8bca3c5d
BS
135 sighandler_t ret_val;
136 ret_val = signal(SIGTERM,terminate);
137 if ( ret_val == SIG_ERR )
138 return -1;
139 ret_val = signal(SIGUSR1,switch_to_offline);
140 if ( ret_val == SIG_ERR )
141 return -1;
142 ret_val = signal(SIGHUP,reload_config);
143 if ( ret_val == SIG_ERR )
144 return -1;
5ac72dd8
BS
145
146 return 0;
c5675c01
BS
147}
148
149
388f4ab0 150/**
b1be615b
BS
151 * @brief The main part.
152 * @param argc Number of arguments
153 * @param argv Command line arguments
154 * @return 0 if all is fine.
4545a371
BS
155 */
156int main(int argc, char *argv[])
157{
38060291 158 // initialize Updater
88a594e8 159 Updater::Ptr _updater(new Updater);
c5675c01
BS
160 updater = _updater;
161 _updater.reset();
38060291 162
b011a02a
TJ
163 // TODO: Why do errors return zero exit status?
164
254bbf53 165 // load the cmd options
38060291 166 if ( updater->init_config_from_cmd(argc,argv) != 0 )
1cf4e2b5 167 return 0;
38060291 168
254bbf53 169 // load the config and service files
38060291 170 if ( updater->init_config_from_files() != 0 )
98bd3874 171 return 0;
4545a371 172
388f4ab0 173 // open pidfile and check for running process
c5675c01 174 if ( check_for_running_process() != 0)
388f4ab0 175 return 0;
3434b35f 176
c5675c01 177 // init signal handling
8bca3c5d
BS
178 if ( init_signals() != 0)
179 {
180 updater->get_logger()->print_error_setting_signal();
181 return 0;
182 }
254bbf53
BS
183
184 // initialize daemon mode if configured
59c8d63c
BS
185 updater->get_logger()->print_daemon_mode(updater->get_config()->get_daemon_mode());
186 if ( updater->get_config()->get_daemon_mode() == 1 )
388f4ab0
BS
187 {
188 int pid = fork();
189 if ( pid < 0 )
190 {
191 // error fork
192 updater->get_logger()->print_error_fork();
193 return 0;
194 }
195 else if ( pid > 0 )
196 {
197 // parent
198 write_pidfile(pid);
199 updater->get_logger()->print_runnig_as_daemon(pid);
200 return 0;
201 }
202 // child starts here
203 }
204
205 // service processing starts here
206 do
207 {
98dd88bd 208 if ( is_online == true )
c5675c01
BS
209 {
210 // update all configured services
211 updater->update_services();
212 }
8bca3c5d
BS
213 else
214 {
215 updater->get_logger()->print_offline_mode();
216 }
388f4ab0 217
59c8d63c
BS
218 if ( updater->get_config()->get_daemon_mode() == 1 )
219 sleep(10); // TODO: in a final release, correct the sleep value to something suitable
220
221 }while ( updater->get_config()->get_daemon_mode() == 1 );
4545a371 222
2bc1878a
BS
223
224 // serialize services
225 updater->get_config()->serialize_services();
226
4545a371
BS
227 return 0;
228}