Convert protocol to lower case.
[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 */
667c672c 79int write_pidfile(int pid)
388f4ab0
BS
80{
81 ofstream pidfile(PIDFILE);
82 if ( pidfile.is_open() )
83 {
84 pidfile << pid << endl;
85 }
667c672c
BS
86 else
87 {
88 updater->get_logger()->print_error_opening_rw(PIDFILE);
89 return -1;
90 }
388f4ab0 91 pidfile.close();
667c672c 92 return 0;
388f4ab0
BS
93}
94
c5675c01
BS
95
96/**
97 * Signal SIGTERM caught, releasing resources and exit.
98 * @param param Parameter from the signal interface.
99 */
100void terminate(int param)
101{
102 updater->get_logger()->print_caught_sigterm();
2bc1878a
BS
103
104 // unfortunately we can't call serialize_services in any destructor
105 // cause some singleton are already destroyed !?!
667c672c
BS
106 if ( updater->get_config()->serialize_services() != 0 )
107 {
108 updater.reset();
109 exit(-1);
110 }
c5675c01 111 updater.reset();
39acb828 112 exit(0);
c5675c01
BS
113}
114
115
2bc1878a 116
c5675c01
BS
117/**
118 * Signal SIGUSR1 caught, switching to offline mode.
119 * @param param Parameter from the signal interface.
120 */
121void switch_to_offline(int param)
122{
8bca3c5d 123 updater->get_logger()->print_caught_siguser1();
98dd88bd 124 is_online = false;
c5675c01
BS
125}
126
127
128/**
129 * Signal SIGHUP caught, reloading config and switching to online mode.
39acb828 130 * @param param Parameter from the signal interface.
c5675c01
BS
131 */
132void reload_config(int param)
133{
8bca3c5d 134 updater->get_logger()->print_caught_sighup();
667c672c
BS
135 if ( updater->reload_config() != 0 )
136 exit(-1);
98dd88bd 137 is_online = true;
c5675c01
BS
138}
139
140
141/**
142 * Initialize the signals we handle.
143 */
8bca3c5d 144int init_signals()
c5675c01 145{
8bca3c5d
BS
146 sighandler_t ret_val;
147 ret_val = signal(SIGTERM,terminate);
148 if ( ret_val == SIG_ERR )
667c672c
BS
149 {
150 updater->get_logger()->print_error_setting_signal("SIGTERM");
8bca3c5d 151 return -1;
667c672c 152 }
8bca3c5d
BS
153 ret_val = signal(SIGUSR1,switch_to_offline);
154 if ( ret_val == SIG_ERR )
667c672c
BS
155 {
156 updater->get_logger()->print_error_setting_signal("SIGUSR1");
8bca3c5d 157 return -1;
667c672c 158 }
8bca3c5d
BS
159 ret_val = signal(SIGHUP,reload_config);
160 if ( ret_val == SIG_ERR )
667c672c
BS
161 {
162 updater->get_logger()->print_error_setting_signal("SIGHUP");
8bca3c5d 163 return -1;
667c672c 164 }
5ac72dd8
BS
165
166 return 0;
c5675c01
BS
167}
168
169
388f4ab0 170/**
b1be615b
BS
171 * @brief The main part.
172 * @param argc Number of arguments
173 * @param argv Command line arguments
174 * @return 0 if all is fine.
4545a371
BS
175 */
176int main(int argc, char *argv[])
177{
38060291 178 // initialize Updater
88a594e8 179 Updater::Ptr _updater(new Updater);
c5675c01
BS
180 updater = _updater;
181 _updater.reset();
38060291 182
254bbf53 183 // load the cmd options
38060291 184 if ( updater->init_config_from_cmd(argc,argv) != 0 )
667c672c 185 return -1;
38060291 186
254bbf53 187 // load the config and service files
38060291 188 if ( updater->init_config_from_files() != 0 )
667c672c 189 return -1;
4545a371 190
388f4ab0 191 // open pidfile and check for running process
c5675c01 192 if ( check_for_running_process() != 0)
667c672c 193 return -1;
3434b35f 194
c5675c01 195 // init signal handling
8bca3c5d 196 if ( init_signals() != 0)
667c672c 197 return -1;
254bbf53 198
667c672c 199 // initialize daemon mode if configured TODO: into separate function
59c8d63c
BS
200 updater->get_logger()->print_daemon_mode(updater->get_config()->get_daemon_mode());
201 if ( updater->get_config()->get_daemon_mode() == 1 )
388f4ab0
BS
202 {
203 int pid = fork();
204 if ( pid < 0 )
205 {
206 // error fork
207 updater->get_logger()->print_error_fork();
667c672c 208 return -1;
388f4ab0
BS
209 }
210 else if ( pid > 0 )
211 {
212 // parent
667c672c
BS
213 if ( write_pidfile(pid) != 0 )
214 {
215 if ( kill(pid,SIGTERM) != 0 )
216 updater->get_logger()->print_error_kill_child(pid);
217 return -1;
218 }
388f4ab0
BS
219 updater->get_logger()->print_runnig_as_daemon(pid);
220 return 0;
221 }
222 // child starts here
223 }
224
225 // service processing starts here
226 do
227 {
98dd88bd 228 if ( is_online == true )
c5675c01
BS
229 {
230 // update all configured services
231 updater->update_services();
232 }
8bca3c5d
BS
233 else
234 {
235 updater->get_logger()->print_offline_mode();
236 }
388f4ab0 237
59c8d63c
BS
238 if ( updater->get_config()->get_daemon_mode() == 1 )
239 sleep(10); // TODO: in a final release, correct the sleep value to something suitable
240
241 }while ( updater->get_config()->get_daemon_mode() == 1 );
4545a371 242
2bc1878a 243
667c672c
BS
244 // serialize services to save their actual status
245 if ( updater->get_config()->serialize_services() != 0 )
246 return -1;
2bc1878a 247
4545a371
BS
248 return 0;
249}